FrontISTR  5.9.0
Large-scale structural analysis program with finit element method
hecmw_solver_GroppCG.f90
Go to the documentation of this file.
1 !C
2 !C*** module hecmw_solver_GroppCG
3 !C
5 
6  public :: hecmw_solve_groppcg
7 
8 contains
9  !C
10  !C*** GroppCG
11  !C
12  subroutine hecmw_solve_groppcg( hecMESH, hecMAT, ITER, RESID, error, &
13  & Tset, Tsol, Tcomm )
14 
15  use hecmw_util
17  use m_hecmw_comm_f
22  use hecmw_precond
23  use hecmw_jad_type
25 
26  implicit none
27 
28  type(hecmwst_local_mesh) :: hecmesh
29  type(hecmwst_matrix) :: hecmat
30  integer(kind=kint), intent(inout) :: iter, error
31  real(kind=kreal), intent(inout) :: resid, tset, tsol, tcomm
32 
33  integer(kind=kint) :: n, np, ndof, nndof
34  integer(kind=kint) :: my_rank
35  integer(kind=kint) :: iterlog, timelog
36  real(kind=kreal), pointer :: b(:), x(:)
37 
38  real(kind=kreal), dimension(:,:), allocatable :: ww
39 
40  integer(kind=kint), parameter :: r = 1
41  integer(kind=kint), parameter :: u = 2
42  integer(kind=kint), parameter :: v = 3
43  integer(kind=kint), parameter :: q = 4
44  integer(kind=kint), parameter :: p = 5
45  integer(kind=kint), parameter :: s = 6
46  integer(kind=kint), parameter :: wk = 7
47 
48  integer(kind=kint) :: maxit
49 
50  real(kind=kreal) :: tol
51  integer(kind=kint) :: i
52  real(kind=kreal) :: s_time, s1_time, e_time, e1_time
53  real(kind=kreal) :: start_time, end_time
54  real(kind=kreal) :: bnrm2, dnrm2
55  real(kind=kreal) :: alpha, alpha1, beta
56  real(kind=kreal) :: gamma, gamma1, delta
57  real(kind=kreal) :: cg(2)
58  real(kind=kreal) :: t_max, t_min, t_avg, t_sd
59  integer(kind=kint) :: estcond
60  real(kind=kreal), allocatable :: d(:), e(:)
61  integer(kind=kint) :: n_indef_precond
62 
63  integer(kind=kint), parameter :: n_iter_recompute_r = 50
64 
65  call hecmw_barrier(hecmesh)
66  s_time = hecmw_wtime()
67 
68  n = hecmat%N
69  np = hecmat%NP
70  ndof = hecmat%NDOF
71  nndof = n * ndof
72  my_rank = hecmesh%my_rank
73  x => hecmat%X
74  b => hecmat%B
75 
76  iterlog = hecmw_mat_get_iterlog(hecmat)
77  timelog = hecmw_mat_get_timelog(hecmat)
78  maxit = hecmw_mat_get_iter(hecmat)
79  tol = hecmw_mat_get_resid(hecmat)
80  estcond = hecmw_mat_get_estcond(hecmat)
81 
82  error = 0
83  iter = 0
84  resid = 0.0d0
85  n_indef_precond = 0
86  alpha1 = 0.0d0
87  beta = 0.0d0
88 
89  allocate(ww(ndof*np, 7))
90  ww = 0.0d0
91 
92  call hecmw_solver_scaling_fw(hecmesh, hecmat, tcomm)
93  call hecmw_mat_integrate(hecmat)
94 
95  if (hecmw_mat_get_usejad(hecmat).ne.0) then
96  call hecmw_jad_init(hecmat)
97  endif
98 
99  if (estcond /= 0 .and. hecmesh%my_rank == 0) then
100  allocate(d(maxit), e(maxit-1))
101  endif
102 
103  call hecmw_precond_setup(hecmat, hecmesh, 1)
104 
105  call hecmw_matresid(hecmesh, hecmat, x, b, ww(:,r), tcomm)
106  call hecmw_innerproduct_r(hecmesh, ndof, b, b, bnrm2, tcomm)
107  if (bnrm2.eq.0.0d0) then
108  maxit = 0
109  x = 0.0d0
110  else
111  call hecmw_precond_apply(hecmesh, hecmat, ww(:,r), ww(:,u), ww(:,wk), tcomm)
112  call hecmw_copy_r(nndof, ww(:,u), ww(:,p))
113  call hecmw_matvec(hecmesh, hecmat, ww(:,p), ww(:,s), tcomm)
114 
115  call hecmw_innerproduct_r_nocomm(hecmesh, ndof, ww(:,r), ww(:,u), cg(1))
116  call hecmw_innerproduct_r_nocomm(hecmesh, ndof, ww(:,r), ww(:,r), cg(2))
117  start_time = hecmw_wtime()
118  call hecmw_allreduce_r(hecmesh, cg, 2, hecmw_sum)
119  end_time = hecmw_wtime()
120  tcomm = tcomm + end_time-start_time
121  gamma = cg(1)
122  dnrm2 = cg(2)
123  resid = dsqrt(dnrm2/bnrm2)
124  if (resid.le.tol) maxit = 0
125  endif
126 
127  e_time = hecmw_wtime()
128  if (timelog.eq.2) then
129  call hecmw_time_statistics(hecmesh, e_time-s_time, t_max, t_min, t_avg, t_sd)
130  if (hecmesh%my_rank.eq.0) then
131  write(*,*) 'Time solver setup'
132  write(*,*) ' Max :', t_max
133  write(*,*) ' Min :', t_min
134  write(*,*) ' Avg :', t_avg
135  write(*,*) ' Std Dev :', t_sd
136  endif
137  tset = t_max
138  else
139  tset = e_time-s_time
140  endif
141 
142  tcomm = 0.0d0
143  call hecmw_barrier(hecmesh)
144  s1_time = hecmw_wtime()
145 
146  do i = 1, maxit
147  if (gamma.eq.0.0d0) then
148  iter = i
150  exit
151  elseif (gamma.ne.gamma) then
152  iter = i
154  exit
155  endif
156 
157  call hecmw_innerproduct_r(hecmesh, ndof, ww(:,p), ww(:,s), delta, tcomm)
158  if (delta.le.0.0d0) then
159  iter = i
161  exit
162  elseif (delta.ne.delta) then
163  iter = i
165  exit
166  endif
167 
168  call hecmw_precond_apply(hecmesh, hecmat, ww(:,s), ww(:,q), ww(:,wk), tcomm)
169 
170  alpha = gamma/delta
171 
172  if (estcond /= 0 .and. hecmesh%my_rank == 0) then
173  if (i.eq.1) then
174  d(1) = 1.0d0/alpha
175  else
176  d(i) = 1.0d0/alpha+beta/alpha1
177  e(i-1) = dsqrt(beta)/alpha1
178  endif
179  if (mod(i,estcond).eq.0) call hecmw_estimate_condition_cg(i, d, e)
180  endif
181 
182  call hecmw_axpy_r(nndof, alpha, ww(:,p), x)
183 
184  if (mod(i,n_iter_recompute_r).eq.0) then
185  call hecmw_matresid(hecmesh, hecmat, x, b, ww(:,r), tcomm)
186  call hecmw_precond_apply(hecmesh, hecmat, ww(:,r), ww(:,u), ww(:,wk), tcomm)
187  else
188  call hecmw_axpy_r(nndof, -alpha, ww(:,s), ww(:,r))
189  call hecmw_axpy_r(nndof, -alpha, ww(:,q), ww(:,u))
190  endif
191 
192  call hecmw_innerproduct_r_nocomm(hecmesh, ndof, ww(:,r), ww(:,u), cg(1))
193  call hecmw_innerproduct_r_nocomm(hecmesh, ndof, ww(:,r), ww(:,r), cg(2))
194  start_time = hecmw_wtime()
195  call hecmw_allreduce_r(hecmesh, cg, 2, hecmw_sum)
196  end_time = hecmw_wtime()
197  tcomm = tcomm + end_time-start_time
198  gamma1 = cg(1)
199  dnrm2 = cg(2)
200  resid = dsqrt(dnrm2/bnrm2)
201  iter = i
202 
203  if (resid.le.tol) then
204  if (mod(i,n_iter_recompute_r).ne.0) then
205  call hecmw_matresid(hecmesh, hecmat, x, b, ww(:,r), tcomm)
206  call hecmw_innerproduct_r(hecmesh, ndof, ww(:,r), ww(:,r), dnrm2, tcomm)
207  resid = dsqrt(dnrm2/bnrm2)
208  endif
209  if (my_rank.eq.0 .and. iterlog.eq.1) write(*,'(i7, 1pe16.6)') iter, resid
210  if (resid.le.tol) exit
211 
212  call hecmw_precond_apply(hecmesh, hecmat, ww(:,r), ww(:,u), ww(:,wk), tcomm)
213  call hecmw_innerproduct_r(hecmesh, ndof, ww(:,r), ww(:,u), gamma1, tcomm)
214  else
215  if (my_rank.eq.0 .and. iterlog.eq.1) write(*,'(i7, 1pe16.6)') iter, resid
216  endif
217 
218  if (i.eq.maxit) then
219  if (mod(i,n_iter_recompute_r).ne.0) then
220  call hecmw_matresid(hecmesh, hecmat, x, b, ww(:,r), tcomm)
221  call hecmw_innerproduct_r(hecmesh, ndof, ww(:,r), ww(:,r), dnrm2, tcomm)
222  resid = dsqrt(dnrm2/bnrm2)
223  endif
224  if (resid.gt.tol) error = hecmw_solver_error_noconv_maxit
225  exit
226  endif
227 
228  if (gamma1.eq.0.0d0) then
230  exit
231  elseif (gamma1.ne.gamma1) then
233  exit
234  elseif (gamma1*gamma.le.0.0d0) then
235  n_indef_precond = n_indef_precond + 1
236  if (n_indef_precond.ge.3) then
238  exit
239  endif
240  endif
241 
242  call hecmw_matvec(hecmesh, hecmat, ww(:,u), ww(:,v), tcomm)
243 
244  beta = gamma1/gamma
245  call hecmw_xpay_r(nndof, beta, ww(:,u), ww(:,p))
246  call hecmw_xpay_r(nndof, beta, ww(:,v), ww(:,s))
247 
248  gamma = gamma1
249  alpha1 = alpha
250  enddo
251 
252  call hecmw_solver_scaling_bk(hecmat)
253 
254  start_time = hecmw_wtime()
255  call hecmw_update_r(hecmesh, x, hecmat%NP, hecmat%NDOF)
256  end_time = hecmw_wtime()
257  tcomm = tcomm + end_time-start_time
258 
259  deallocate(ww)
260 
261  if (hecmw_mat_get_usejad(hecmat).ne.0) then
262  call hecmw_jad_finalize(hecmat)
263  endif
264 
265  if (estcond /= 0 .and. hecmesh%my_rank == 0) then
266  if (error.eq.0 .and. iter.gt.0) call hecmw_estimate_condition_cg(iter, d, e)
267  deallocate(d, e)
268  endif
269 
270  e1_time = hecmw_wtime()
271  if (timelog.eq.2) then
272  call hecmw_time_statistics(hecmesh, e1_time-s1_time, t_max, t_min, t_avg, t_sd)
273  if (hecmesh%my_rank.eq.0) then
274  write(*,*) 'Time solver iterations'
275  write(*,*) ' Max :', t_max
276  write(*,*) ' Min :', t_min
277  write(*,*) ' Avg :', t_avg
278  write(*,*) ' Std Dev :', t_sd
279  endif
280  tsol = t_max
281  else
282  tsol = e1_time-s1_time
283  endif
284 
285  end subroutine hecmw_solve_groppcg
286 
287 end module hecmw_solver_GroppCG
subroutine, public hecmw_estimate_condition_cg(ITER, D, E)
Jagged Diagonal Matrix storage for vector processors. Original code was provided by JAMSTEC.
Definition: hecmw_jadm.f90:8
subroutine, public hecmw_jad_init(hecMAT)
Definition: hecmw_jadm.f90:29
subroutine, public hecmw_jad_finalize(hecMAT)
Definition: hecmw_jadm.f90:42
subroutine, public hecmw_mat_integrate(hecMAT)
Integrate matrix components into a single array for efficient access.
real(kind=kreal) function, public hecmw_mat_get_resid(hecMAT)
integer(kind=kint) function, public hecmw_mat_get_iterlog(hecMAT)
integer(kind=kint) function, public hecmw_mat_get_timelog(hecMAT)
integer(kind=kint) function, public hecmw_mat_get_estcond(hecMAT)
integer(kind=kint) function, public hecmw_mat_get_usejad(hecMAT)
integer(kind=kint) function, public hecmw_mat_get_iter(hecMAT)
subroutine, public hecmw_precond_setup(hecMAT, hecMESH, sym)
subroutine, public hecmw_precond_apply(hecMESH, hecMAT, R, Z, ZP, COMMtime)
subroutine, public hecmw_solve_groppcg(hecMESH, hecMAT, ITER, RESID, error, Tset, Tsol, Tcomm)
subroutine, public hecmw_matresid(hecMESH, hecMAT, X, B, R, COMMtime)
subroutine, public hecmw_matvec(hecMESH, hecMAT, X, Y, COMMtime)
subroutine hecmw_xpay_r(n, alpha, X, Y)
subroutine hecmw_innerproduct_r_nocomm(hecMESH, ndof, X, Y, sum)
subroutine hecmw_innerproduct_r(hecMESH, ndof, X, Y, sum, COMMtime)
subroutine hecmw_axpy_r(n, alpha, X, Y)
subroutine hecmw_copy_r(n, X, Y)
subroutine hecmw_time_statistics(hecMESH, time, t_max, t_min, t_avg, t_sd)
subroutine, public hecmw_solver_scaling_fw(hecMESH, hecMAT, COMMtime)
subroutine, public hecmw_solver_scaling_bk(hecMAT)
I/O and Utility.
Definition: hecmw_util_f.F90:7
integer(kind=kint), parameter hecmw_sum
integer(kind=4), parameter kreal
real(kind=kreal) function hecmw_wtime()
subroutine hecmw_update_r(hecMESH, val, n, m)
subroutine hecmw_allreduce_r(hecMESH, val, n, ntag)
subroutine hecmw_barrier(hecMESH)
integer(kind=kint), parameter hecmw_solver_error_diverge_pc
integer(kind=kint), parameter hecmw_solver_error_diverge_nan
integer(kind=kint), parameter hecmw_solver_error_noconv_maxit
integer(kind=kint), parameter hecmw_solver_error_diverge_mat