FrontISTR  6.0.0
Large-scale structural analysis program with finit element method
hecmw_solver_GMRESR.f90
Go to the documentation of this file.
1 !-------------------------------------------------------------------------------
2 ! Copyright (c) 2019 FrontISTR Commons
3 ! This software is released under the MIT License, see LICENSE.txt
4 !-------------------------------------------------------------------------------
5 
6 !C***
7 !C*** module hecmw_solver_GMRESR
8 !C***
9 !
11 
12  public :: hecmw_solve_gmresr
13 
14 contains
15  !C
16  !C*** hecmw_solve_GMRESR
17  !C
18  subroutine hecmw_solve_gmresr( hecMESH, hecMAT, ITER, RESID, error, &
19  & Tset, Tsol, Tcomm )
20  use hecmw_util
22  use m_hecmw_comm_f
27  use hecmw_precond
28  use hecmw_jad_type
30 
31  implicit none
32 
33  type(hecmwst_local_mesh) :: hecmesh
34  type(hecmwst_matrix) :: hecmat
35  integer(kind=kint ), intent(inout):: iter, error
36  real (kind=kreal), intent(inout):: resid, tset, tsol, tcomm
37 
38  integer(kind=kint ) :: n, np, ndof, nndof
39  integer(kind=kint ) :: my_rank
40  integer(kind=kint ) :: iterlog, timelog
41  real(kind=kreal), pointer :: b(:), x(:)
42 
43  integer(kind=kint),dimension(:), allocatable :: idxbfgs
44  real(kind=kreal), dimension(:) , allocatable :: vecr,workpc,tmpvecbfgs,rho,alpha
45  real(kind=kreal), dimension(:,:), allocatable :: u,c,uin,cin,sbfgs,ybfgs
46 
47  integer(kind=kint ) :: maxit, nrest,nbfgs
48 
49  real (kind=kreal) :: tol
50 
51  real (kind=kreal) zero, one
52  parameter( zero = 0.0d+0, one = 1.0d+0 )
53 
54  integer(kind=kint ) :: i,k,kk,iorth,idx,tmpidx,ibfgs
55  real (kind=kreal) :: s_time,e_time,s1_time,e1_time
56  real (kind=kreal) :: bnrm2,dnrm2
57  real (kind=kreal) :: commtime,comptime, coef,coef2
58  integer(kind=kint ) :: estcond
59  real (kind=kreal) :: t_max,t_min,t_avg,t_sd
60 
61 
62  call hecmw_barrier(hecmesh)
63  s_time= hecmw_wtime()
64  !C
65  !C-- INIT.
66  n = hecmat%N
67  np = hecmat%NP
68  ndof = hecmat%NDOF
69  nndof = n * ndof
70  my_rank = hecmesh%my_rank
71  x => hecmat%X
72  b => hecmat%B
73 
74  iterlog = hecmw_mat_get_iterlog( hecmat )
75  timelog = hecmw_mat_get_timelog( hecmat )
76  maxit = hecmw_mat_get_iter( hecmat )
77  tol = hecmw_mat_get_resid( hecmat )
78  nrest = hecmw_mat_get_nrest( hecmat )
79  nbfgs = hecmw_mat_get_nbfgs( hecmat )
80  estcond = hecmw_mat_get_estcond( hecmat )
81 
82  error= 0
83 
84  allocate (vecr(ndof*np))
85  allocate (workpc(ndof*np))
86  allocate (u(ndof*np,nrest))
87  allocate (c(ndof*np,nrest))
88  allocate (uin(ndof*np,nrest))
89  allocate (cin(ndof*np,nrest))
90 
91  if(nbfgs>0)then
92  allocate (tmpvecbfgs(ndof*np))
93  allocate (sbfgs(ndof*np,nbfgs))
94  allocate (ybfgs(ndof*np,nbfgs))
95  allocate (idxbfgs(nbfgs))
96  allocate (rho(nbfgs))
97  allocate (alpha(nbfgs))
98  endif
99 
100  do idx = 1, nbfgs
101  idxbfgs(idx) = idx
102  enddo
103 
104  commtime= 0.d0
105  comptime= 0.d0
106 
107  !C
108  !C-- SCALING
109  call hecmw_solver_scaling_fw(hecmesh, hecmat, tcomm)
110 
111  !C
112  !C-- matrix integration for OpenACC
113  !C
114  !C @note:
115  !C Combine hecMAT%AL, D, and AU into a single matrix for GPU execution.
116  !C This is a no-op for CPU builds.
117  call hecmw_mat_integrate(hecmat)
118 
119  if (hecmw_mat_get_usejad(hecmat).ne.0) then
120  call hecmw_jad_init(hecmat)
121  endif
122  call hecmw_matvec_setup(hecmesh, hecmat)
123 
124  !C===
125  !C +----------------------+
126  !C | SETUP PRECONDITIONER |
127  !C +----------------------+
128  !C===
129  call hecmw_precond_setup(hecmat, hecmesh, 0)
130 
131 
132  call hecmw_innerproduct_r(hecmesh, ndof, b, b, bnrm2, tcomm)
133  if (bnrm2.eq.0.d0) then
134  iter = 0
135  maxit = 0
136  resid = 0.d0
137  x = 0.d0
138  endif
139 
140  e_time= hecmw_wtime()
141  if (timelog.eq.2) then
142  call hecmw_time_statistics(hecmesh, e_time - s_time, &
143  t_max, t_min, t_avg, t_sd)
144  if (hecmesh%my_rank.eq.0) then
145  write(*,*) 'Time solver setup'
146  write(*,*) ' Max :',t_max
147  write(*,*) ' Min :',t_min
148  write(*,*) ' Avg :',t_avg
149  write(*,*) ' Std Dev :',t_sd
150  endif
151  tset = t_max
152  else
153  tset = e_time - s_time
154  endif
155  !C===
156 
157 
158  call hecmw_barrier(hecmesh)
159  s1_time= hecmw_wtime()
160  iter= 0
161  ibfgs=0
162  outer: do
163 
164  call hecmw_matresid(hecmesh, hecmat, x, b, vecr, tcomm)
165  do i = 1, nrest
166  iter= iter + 1
167 
168  !C Solve M*r = uin(:,1)
169  if (ibfgs == 0)then
170  call hecmw_precond_apply(hecmesh, hecmat, vecr, uin(:,1), workpc, tcomm)
171  else
172  call hecmw_copy_r(nndof, vecr, tmpvecbfgs)
173  do k = 1,ibfgs
174  idx = idxbfgs(k)
175  call hecmw_innerproduct_r(hecmesh, ndof, sbfgs(:,idx), ybfgs(:,idx), coef, tcomm)
176  rho(k) = 1.0d0 / coef
177  call hecmw_innerproduct_r(hecmesh, ndof, sbfgs(:,idx), tmpvecbfgs, coef2, tcomm)
178  alpha(k) = rho(k)*coef2
179  call hecmw_axpy_r(nndof, -alpha(k), ybfgs(:,idx), tmpvecbfgs)
180  enddo
181  call hecmw_precond_apply(hecmesh, hecmat, tmpvecbfgs, uin(:,1), workpc, tcomm)
182  do k = ibfgs,1,-1
183  idx = idxbfgs(k)
184  call hecmw_innerproduct_r(hecmesh, ndof, ybfgs(:,idx), uin(:,1), coef, tcomm)
185  coef2 = rho(k) * coef
186  call hecmw_axpy_r(nndof, alpha(k)-coef2, sbfgs(:,idx), uin(:,1))
187  enddo
188  endif
189  !C cin(:,1) = A*uin(:,1)
190  call hecmw_matvec(hecmesh, hecmat, uin(:,1), cin(:,1), tcomm)
191 
192  do iorth = 1, i-1
193  !C c_{i}^T cin_{i}
194  call hecmw_innerproduct_r(hecmesh, ndof, c(:,iorth), cin(:,iorth), coef, tcomm)
195 
196  call hecmw_axpyz_r(nndof, -coef, c(:,iorth), cin(:,iorth), cin(:,iorth+1))
197  call hecmw_axpyz_r(nndof, -coef, u(:,iorth), uin(:,iorth), uin(:,iorth+1))
198  enddo
199  call hecmw_innerproduct_r(hecmesh, ndof, cin(:,i), cin(:,i), coef, tcomm)
200  coef = 1.0d0 / dsqrt(coef)
201  call hecmw_axpby_r(nndof, coef, 0.0d0, cin(:,i), c(:,i))
202  call hecmw_axpby_r(nndof, coef, 0.0d0, uin(:,i), u(:,i))
203 
204  call hecmw_innerproduct_r(hecmesh, ndof, c(:,i), vecr, coef, tcomm)
205  call hecmw_axpy_r(nndof, coef, u(:,i), x)
206  call hecmw_axpy_r(nndof, -coef, c(:,i), vecr)
207 
208  if (nbfgs > 0)then
209  ibfgs = ibfgs + 1
210  if (ibfgs == nbfgs+1)then
211  tmpidx = idxbfgs(1)
212  do kk = 1, nbfgs-1
213  idxbfgs(kk) = idxbfgs(kk+1)
214  enddo
215  idxbfgs(nbfgs) = tmpidx
216  ibfgs = ibfgs - 1
217  endif
218  call hecmw_axpby_r(nndof, coef, 0.0d0, c(:,i), ybfgs(:,idxbfgs(ibfgs)))
219  call hecmw_axpby_r(nndof, coef, 0.0d0, u(:,i), sbfgs(:,idxbfgs(ibfgs)))
220  endif
221 
222 
223  call hecmw_innerproduct_r(hecmesh, ndof, vecr, vecr, dnrm2, tcomm)
224  resid= dsqrt(dnrm2/bnrm2)
225 
226  !C##### ITERATION HISTORY
227  if (my_rank.eq.0.and.iterlog.eq.1) write (*,'(i7, 1pe16.6)') iter, resid
228  !C#####
229 
230  if ( resid.le.tol ) exit outer
231  if ( iter.gt.maxit ) then
233  exit outer
234  end if
235  end do
236 
237  end do outer
238 
239  call hecmw_solver_scaling_bk(hecmat)
240 
241  !C
242  !C-- INTERFACE data EXCHANGE
243  s_time = hecmw_wtime()
244  !call hecmw_update_m_R (hecMESH, X, hecMAT%NP, hecMAT%NDOF)
245  call hecmw_update_r (hecmesh, x, hecmat%NP, hecmat%NDOF)
246 
247  e_time = hecmw_wtime()
248  tcomm = tcomm + e_time - s_time
249 
250  !deallocate (H, WW, SS)
251  deallocate (vecr)
252  deallocate (workpc)
253  deallocate (u )
254  deallocate (c )
255  deallocate (uin)
256  deallocate (cin)
257  call hecmw_precond_clear(hecmat)
258 
259  call hecmw_matvec_teardown(hecmat)
260  if (hecmw_mat_get_usejad(hecmat).ne.0) then
261  call hecmw_jad_finalize(hecmat)
262  endif
263 
264  e1_time= hecmw_wtime()
265  if (timelog.eq.2) then
266  call hecmw_time_statistics(hecmesh, e1_time - s1_time, &
267  t_max, t_min, t_avg, t_sd)
268  if (hecmesh%my_rank.eq.0) then
269  write(*,*) 'Time solver iterations'
270  write(*,*) ' Max :',t_max
271  write(*,*) ' Min :',t_min
272  write(*,*) ' Avg :',t_avg
273  write(*,*) ' Std Dev :',t_sd
274  endif
275  tsol = t_max
276  else
277  tsol = e1_time - s1_time
278  endif
279 
280  end subroutine hecmw_solve_gmresr
281 
282 end module hecmw_solver_gmresr
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.
integer(kind=kint) function, public hecmw_mat_get_nrest(hecMAT)
real(kind=kreal) function, public hecmw_mat_get_resid(hecMAT)
integer(kind=kint) function, public hecmw_mat_get_nbfgs(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_clear(hecMAT)
subroutine, public hecmw_precond_setup(hecMAT, hecMESH, sym)
subroutine, public hecmw_precond_apply(hecMESH, hecMAT, R, Z, ZP, COMMtime)
subroutine, public hecmw_solve_gmresr(hecMESH, hecMAT, ITER, RESID, error, Tset, Tsol, Tcomm)
subroutine, public hecmw_matvec_teardown(hecMAT)
subroutine, public hecmw_matvec_setup(hecMESH, hecMAT)
subroutine, public hecmw_matresid(hecMESH, hecMAT, X, B, R, COMMtime)
subroutine, public hecmw_matvec(hecMESH, hecMAT, X, Y, COMMtime)
subroutine hecmw_axpyz_r(n, alpha, X, Y, Z)
subroutine hecmw_innerproduct_r(hecMESH, ndof, X, Y, sum, COMMtime)
subroutine hecmw_axpby_r(n, alpha, beta, X, Y)
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=4), parameter kreal
real(kind=kreal) function hecmw_wtime()
subroutine hecmw_update_r(hecMESH, val, n, m)
subroutine hecmw_barrier(hecMESH)
integer(kind=kint), parameter hecmw_solver_error_noconv_maxit