FrontISTR  5.9.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 ) :: nrk,i,k,kk,jj,info,ik,iorth,idx,tmpidx,ibfgs
55  integer(kind=kint ) :: irow
56  real (kind=kreal) :: s_time,e_time,s1_time,e1_time
57  real (kind=kreal) :: ldh,ldw,bnrm2,dnrm2,rnorm
58  real (kind=kreal) :: commtime,comptime, coef,coef2,val,vcs,vsn,dtemp,aa,bb,r0,scale,rr
59  integer(kind=kint ) :: estcond
60  real (kind=kreal) :: t_max,t_min,t_avg,t_sd
61 
62 
63  call hecmw_barrier(hecmesh)
64  s_time= hecmw_wtime()
65  !C
66  !C-- INIT.
67  n = hecmat%N
68  np = hecmat%NP
69  ndof = hecmat%NDOF
70  nndof = n * ndof
71  my_rank = hecmesh%my_rank
72  x => hecmat%X
73  b => hecmat%B
74 
75  iterlog = hecmw_mat_get_iterlog( hecmat )
76  timelog = hecmw_mat_get_timelog( hecmat )
77  maxit = hecmw_mat_get_iter( hecmat )
78  tol = hecmw_mat_get_resid( hecmat )
79  nrest = hecmw_mat_get_nrest( hecmat )
80  nbfgs = hecmw_mat_get_nbfgs( hecmat )
81  estcond = hecmw_mat_get_estcond( hecmat )
82 
83  error= 0
84 
85  allocate (vecr(ndof*np))
86  allocate (workpc(ndof*np))
87  allocate (u(ndof*np,nrest))
88  allocate (c(ndof*np,nrest))
89  allocate (uin(ndof*np,nrest))
90  allocate (cin(ndof*np,nrest))
91 
92  if(nbfgs>0)then
93  allocate (tmpvecbfgs(ndof*np))
94  allocate (sbfgs(ndof*np,nbfgs))
95  allocate (ybfgs(ndof*np,nbfgs))
96  allocate (idxbfgs(nbfgs))
97  allocate (rho(nbfgs))
98  allocate (alpha(nbfgs))
99  endif
100 
101  do idx = 1, nbfgs
102  idxbfgs(idx) = idx
103  enddo
104 
105  commtime= 0.d0
106  comptime= 0.d0
107 
108  !C
109  !C-- SCALING
110  call hecmw_solver_scaling_fw(hecmesh, hecmat, tcomm)
111 
112  !C
113  !C-- matrix integration for OpenACC
114  !C
115  !C @note:
116  !C Combine hecMAT%AL, D, and AU into a single matrix for GPU execution.
117  !C This is a no-op for CPU builds.
118  call hecmw_mat_integrate(hecmat)
119 
120  if (hecmw_mat_get_usejad(hecmat).ne.0) then
121  call hecmw_jad_init(hecmat)
122  endif
123  call hecmw_matvec_setup(hecmesh, hecmat)
124 
125  !C===
126  !C +----------------------+
127  !C | SETUP PRECONDITIONER |
128  !C +----------------------+
129  !C===
130  call hecmw_precond_setup(hecmat, hecmesh, 0)
131 
132 
133  call hecmw_innerproduct_r(hecmesh, ndof, b, b, bnrm2, tcomm)
134  if (bnrm2.eq.0.d0) then
135  iter = 0
136  maxit = 0
137  resid = 0.d0
138  x = 0.d0
139  endif
140 
141  e_time= hecmw_wtime()
142  if (timelog.eq.2) then
143  call hecmw_time_statistics(hecmesh, e_time - s_time, &
144  t_max, t_min, t_avg, t_sd)
145  if (hecmesh%my_rank.eq.0) then
146  write(*,*) 'Time solver setup'
147  write(*,*) ' Max :',t_max
148  write(*,*) ' Min :',t_min
149  write(*,*) ' Avg :',t_avg
150  write(*,*) ' Std Dev :',t_sd
151  endif
152  tset = t_max
153  else
154  tset = e_time - s_time
155  endif
156  !C===
157 
158 
159  call hecmw_barrier(hecmesh)
160  s1_time= hecmw_wtime()
161  iter= 0
162  ibfgs=0
163  outer: do
164 
165  call hecmw_matresid(hecmesh, hecmat, x, b, vecr, tcomm)
166  do i = 1, nrest
167  iter= iter + 1
168 
169  !C Solve M*r = uin(:,1)
170  if (ibfgs == 0)then
171  call hecmw_precond_apply(hecmesh, hecmat, vecr, uin(:,1), workpc, tcomm)
172  else
173  call hecmw_copy_r(nndof, vecr, tmpvecbfgs)
174  do k = 1,ibfgs
175  idx = idxbfgs(k)
176  call hecmw_innerproduct_r(hecmesh, ndof, sbfgs(:,idx), ybfgs(:,idx), coef, tcomm)
177  rho(k) = 1.0d0 / coef
178  call hecmw_innerproduct_r(hecmesh, ndof, sbfgs(:,idx), tmpvecbfgs, coef2, tcomm)
179  alpha(k) = rho(k)*coef2
180  call hecmw_axpy_r(nndof, -alpha(k), ybfgs(:,idx), tmpvecbfgs)
181  enddo
182  call hecmw_precond_apply(hecmesh, hecmat, tmpvecbfgs, uin(:,1), workpc, tcomm)
183  do k = ibfgs,1,-1
184  idx = idxbfgs(k)
185  call hecmw_innerproduct_r(hecmesh, ndof, ybfgs(:,idx), uin(:,1), coef, tcomm)
186  coef2 = rho(k) * coef
187  call hecmw_axpy_r(nndof, alpha(k)-coef2, sbfgs(:,idx), uin(:,1))
188  enddo
189  endif
190  !C cin(:,1) = A*uin(:,1)
191  call hecmw_matvec(hecmesh, hecmat, uin(:,1), cin(:,1), tcomm)
192 
193  do iorth = 1, i-1
194  !C c_{i}^T cin_{i}
195  call hecmw_innerproduct_r(hecmesh, ndof, c(:,iorth), cin(:,iorth), coef, tcomm)
196 
197  call hecmw_axpyz_r(nndof, -coef, c(:,iorth), cin(:,iorth), cin(:,iorth+1))
198  call hecmw_axpyz_r(nndof, -coef, u(:,iorth), uin(:,iorth), uin(:,iorth+1))
199  enddo
200  call hecmw_innerproduct_r(hecmesh, ndof, cin(:,i), cin(:,i), coef, tcomm)
201  coef = 1.0d0 / dsqrt(coef)
202  call hecmw_axpby_r(nndof, coef, 0.0d0, cin(:,i), c(:,i))
203  call hecmw_axpby_r(nndof, coef, 0.0d0, uin(:,i), u(:,i))
204 
205  call hecmw_innerproduct_r(hecmesh, ndof, c(:,i), vecr, coef, tcomm)
206  call hecmw_axpy_r(nndof, coef, u(:,i), x)
207  call hecmw_axpy_r(nndof, -coef, c(:,i), vecr)
208 
209  if (nbfgs > 0)then
210  ibfgs = ibfgs + 1
211  if (ibfgs == nbfgs+1)then
212  tmpidx = idxbfgs(1)
213  do kk = 1, nbfgs-1
214  idxbfgs(kk) = idxbfgs(kk+1)
215  enddo
216  idxbfgs(nbfgs) = tmpidx
217  ibfgs = ibfgs - 1
218  endif
219  call hecmw_axpby_r(nndof, coef, 0.0d0, c(:,i), ybfgs(:,idxbfgs(ibfgs)))
220  call hecmw_axpby_r(nndof, coef, 0.0d0, u(:,i), sbfgs(:,idxbfgs(ibfgs)))
221  endif
222 
223 
224  call hecmw_innerproduct_r(hecmesh, ndof, vecr, vecr, dnrm2, tcomm)
225  resid= dsqrt(dnrm2/bnrm2)
226 
227  !C##### ITERATION HISTORY
228  if (my_rank.eq.0.and.iterlog.eq.1) write (*,'(i7, 1pe16.6)') iter, resid
229  !C#####
230 
231  if ( resid.le.tol ) exit outer
232  if ( iter.gt.maxit ) then
234  exit outer
235  end if
236  end do
237 
238  end do outer
239 
240  call hecmw_solver_scaling_bk(hecmat)
241 
242  !C
243  !C-- INTERFACE data EXCHANGE
244  s_time = hecmw_wtime()
245  !call hecmw_update_m_R (hecMESH, X, hecMAT%NP, hecMAT%NDOF)
246  call hecmw_update_r (hecmesh, x, hecmat%NP, hecmat%NDOF)
247 
248  e_time = hecmw_wtime()
249  tcomm = tcomm + e_time - s_time
250 
251  !deallocate (H, WW, SS)
252  deallocate (vecr)
253  deallocate (workpc)
254  deallocate (u )
255  deallocate (c )
256  deallocate (uin)
257  deallocate (cin)
258  call hecmw_precond_clear(hecmat)
259 
260  call hecmw_matvec_teardown(hecmat)
261  if (hecmw_mat_get_usejad(hecmat).ne.0) then
262  call hecmw_jad_finalize(hecmat)
263  endif
264 
265  e1_time= hecmw_wtime()
266  if (timelog.eq.2) then
267  call hecmw_time_statistics(hecmesh, e1_time - s1_time, &
268  t_max, t_min, t_avg, t_sd)
269  if (hecmesh%my_rank.eq.0) then
270  write(*,*) 'Time solver iterations'
271  write(*,*) ' Max :',t_max
272  write(*,*) ' Min :',t_min
273  write(*,*) ' Avg :',t_avg
274  write(*,*) ' Std Dev :',t_sd
275  endif
276  tsol = t_max
277  else
278  tsol = e1_time - s1_time
279  endif
280 
281  end subroutine hecmw_solve_gmresr
282 
283 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