xref: /phasta/svLS/GMRES.f (revision 712d3df0b59ebebaaeaea358162c8d2c043c6e08)
1*1e99f302SBen Matthews!     This software is Copyright (c) 2012-2015 The Regents of the
2*1e99f302SBen Matthews!     University of California. All Rights Reserved.
3*1e99f302SBen Matthews!
4*1e99f302SBen Matthews!     Permission to copy and modify this software and its documentation
5*1e99f302SBen Matthews!     for educational, research and non-profit purposes, without fee,
6*1e99f302SBen Matthews!     and without a written agreement is hereby granted, provided that
7*1e99f302SBen Matthews!     the above copyright notice, this paragraph and the following three
8*1e99f302SBen Matthews!     paragraphs appear in all copies.
9*1e99f302SBen Matthews!
10*1e99f302SBen Matthews!     Permission to make commercial use of this software may be obtained
11*1e99f302SBen Matthews!     by contacting:
12*1e99f302SBen Matthews!
13*1e99f302SBen Matthews!     Technology Transfer Office
14*1e99f302SBen Matthews!     9500 Gilman Drive, Mail Code 0910
15*1e99f302SBen Matthews!     University of California
16*1e99f302SBen Matthews!     La Jolla, CA 92093-0910
17*1e99f302SBen Matthews!     (858) 534-5815
18*1e99f302SBen Matthews!     invent@ucsd.edu
19*1e99f302SBen Matthews!
20*1e99f302SBen Matthews!     This software program and documentation are copyrighted by The
21*1e99f302SBen Matthews!     Regents of the University of California. The software program and
22*1e99f302SBen Matthews!     documentation are supplied "as is", without any accompanying
23*1e99f302SBen Matthews!     services from The Regents. The Regents does not warrant that the
24*1e99f302SBen Matthews!     operation of the program will be uninterrupted or error-free. The
25*1e99f302SBen Matthews!     end-user understands that the program was developed for research
26*1e99f302SBen Matthews!     purposes and is advised not to rely exclusively on the program for
27*1e99f302SBen Matthews!     any reason.
28*1e99f302SBen Matthews!
29*1e99f302SBen Matthews!     IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY
30*1e99f302SBen Matthews!     PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
31*1e99f302SBen Matthews!     DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS
32*1e99f302SBen Matthews!     SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
33*1e99f302SBen Matthews!     CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34*1e99f302SBen Matthews!     THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY
35*1e99f302SBen Matthews!     WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
36*1e99f302SBen Matthews!     OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
37*1e99f302SBen Matthews!     SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE
38*1e99f302SBen Matthews!     UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE
39*1e99f302SBen Matthews!     MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
40*1e99f302SBen Matthews
41*1e99f302SBen Matthews      SUBROUTINE GMRES(nFaces, dof, nNo, nnz, mynNo, commu, cS, face,
42*1e99f302SBen Matthews     2   ls, rowPtr, colPtr, Val, R, X)
43*1e99f302SBen Matthews
44*1e99f302SBen Matthews      INCLUDE "svLS_STD.h"
45*1e99f302SBen Matthews
46*1e99f302SBen Matthews      INTEGER, INTENT(IN) :: nFaces, dof, nNo, nnz, mynNo
47*1e99f302SBen Matthews      TYPE(svLS_commuType), INTENT(IN) :: commu
48*1e99f302SBen Matthews      TYPE(svLS_cSType), INTENT(IN) :: cS(commu%nTasks)
49*1e99f302SBen Matthews      TYPE(svLS_faceType), INTENT(IN) :: face(nFaces)
50*1e99f302SBen Matthews      TYPE(svLS_subLsType), INTENT(INOUT) :: ls
51*1e99f302SBen Matthews      INTEGER, INTENT(IN) :: rowPtr(2,nNo), colPtr(nnz)
52*1e99f302SBen Matthews      REAL*8, INTENT(IN) :: Val(dof*dof,nnz), R(dof,nNo)
53*1e99f302SBen Matthews      REAL*8, INTENT(OUT) :: X(dof,nNo)
54*1e99f302SBen Matthews
55*1e99f302SBen Matthews      INTEGER i, j, k, l
56*1e99f302SBen Matthews      REAL*8 CPUT, NORMV, DOTV
57*1e99f302SBen Matthews      REAL*8 eps, tmp, time
58*1e99f302SBen Matthews      REAL*8, ALLOCATABLE :: u(:,:,:), h(:,:), unCondU(:,:), y(:), c(:),
59*1e99f302SBen Matthews     2   s(:), err(:)
60*1e99f302SBen Matthews
61*1e99f302SBen Matthews      ALLOCATE(h(ls%sD+1,ls%sD), u(dof,nNo,ls%sD+1), unCondU(dof,nNo),
62*1e99f302SBen Matthews     2   y(ls%sD), c(ls%sD), s(ls%sD), err(ls%sD+1))
63*1e99f302SBen Matthews
64*1e99f302SBen Matthews      time   = CPUT()
65*1e99f302SBen Matthews      ls%suc = .FALSE.
66*1e99f302SBen Matthews
67*1e99f302SBen Matthews      X = 0D0
68*1e99f302SBen Matthews      DO l=1, ls%mItr
69*1e99f302SBen Matthews         IF (l .EQ. 1) THEN
70*1e99f302SBen Matthews            u(:,:,1) = R
71*1e99f302SBen Matthews         ELSE
72*1e99f302SBen Matthews            ls%itr = ls%itr + 1
73*1e99f302SBen Matthews            CALL SPARMULVV(dof, nNo, nnz, commu, cS, rowPtr, colPtr,
74*1e99f302SBen Matthews     2         Val, X, u(:,:,1))
75*1e99f302SBen Matthews
76*1e99f302SBen Matthews            CALL ADDBCMUL(BCOP_TYPE_ADD, nFaces, dof, nNo, mynNo, commu,
77*1e99f302SBen Matthews     2         face, X, u(:,:,1))
78*1e99f302SBen Matthews
79*1e99f302SBen Matthews            u(:,:,1) = R - u(:,:,1)
80*1e99f302SBen Matthews         END IF
81*1e99f302SBen Matthews         IF (ANY(face%coupledFlag)) THEN
82*1e99f302SBen Matthews            unCondU = u(:,:,1)
83*1e99f302SBen Matthews            CALL ADDBCMUL(BCOP_TYPE_PRE, nFaces, dof, nNo, mynNo, commu,
84*1e99f302SBen Matthews     2         face, unCondU, u(:,:,1))
85*1e99f302SBen Matthews         END IF
86*1e99f302SBen Matthews
87*1e99f302SBen Matthews         err(1)   = NORMV(dof, mynNo, commu, u(:,:,1))
88*1e99f302SBen Matthews         IF (l .EQ. 1) THEN
89*1e99f302SBen Matthews            eps       = err(1)
90*1e99f302SBen Matthews            IF (eps .LE. ls%absTol) THEN
91*1e99f302SBen Matthews               ls%callD = 0D0
92*1e99f302SBen Matthews               ls%dB    = 0D0
93*1e99f302SBen Matthews               RETURN
94*1e99f302SBen Matthews            END IF
95*1e99f302SBen Matthews            ls%iNorm  = eps
96*1e99f302SBen Matthews            ls%fNorm  = eps
97*1e99f302SBen Matthews            eps       = MAX(ls%absTol,ls%relTol*eps)
98*1e99f302SBen Matthews         END IF
99*1e99f302SBen Matthews         ls%dB = ls%fNorm
100*1e99f302SBen Matthews         u(:,:,1) = u(:,:,1)/err(1)
101*1e99f302SBen Matthews         DO i=1, ls%sD
102*1e99f302SBen Matthews            ls%itr = ls%itr + 1
103*1e99f302SBen Matthews            CALL SPARMULVV(dof, nNo, nnz, commu, cS, rowPtr, colPtr,
104*1e99f302SBen Matthews     2         Val, u(:,:,i), u(:,:,i+1))
105*1e99f302SBen Matthews
106*1e99f302SBen Matthews            CALL ADDBCMUL(BCOP_TYPE_ADD, nFaces, dof, nNo, mynNo, commu,
107*1e99f302SBen Matthews     2         face, u(:,:,i), u(:,:,i+1))
108*1e99f302SBen Matthews
109*1e99f302SBen Matthews            IF (ANY(face%coupledFlag)) THEN
110*1e99f302SBen Matthews               unCondU = u(:,:,i+1)
111*1e99f302SBen Matthews               CALL ADDBCMUL(BCOP_TYPE_PRE, nFaces, dof, nNo, mynNo,
112*1e99f302SBen Matthews     2            commu, face, unCondU, u(:,:,i+1))
113*1e99f302SBen Matthews            END IF
114*1e99f302SBen Matthews            DO j=1, i
115*1e99f302SBen Matthews               h(j,i) = DOTV(dof, mynNo, commu, u(:,:,i+1), u(:,:,j))
116*1e99f302SBen Matthews               u(:,:,i+1) = u(:,:,i+1) - h(j,i)*u(:,:,j)
117*1e99f302SBen Matthews            END DO
118*1e99f302SBen Matthews            h(i+1,i)   = NORMV(dof, mynNo, commu, u(:,:,i+1))
119*1e99f302SBen Matthews
120*1e99f302SBen Matthews            u(:,:,i+1) = u(:,:,i+1)/h(i+1,i)
121*1e99f302SBen Matthews            DO j=1, i-1
122*1e99f302SBen Matthews               tmp      =  c(j)*h(j,i) + s(j)*h(j+1,i)
123*1e99f302SBen Matthews               h(j+1,i) = -s(j)*h(j,i) + c(j)*h(j+1,i)
124*1e99f302SBen Matthews               h(j,i)   =  tmp
125*1e99f302SBen Matthews            END DO
126*1e99f302SBen Matthews            tmp      = SQRT(h(i,i)*h(i,i) + h(i+1,i)*h(i+1,i))
127*1e99f302SBen Matthews            c(i)     = h(i,i)/tmp
128*1e99f302SBen Matthews            s(i)     = h(i+1,i)/tmp
129*1e99f302SBen Matthews            h(i,i)   = tmp
130*1e99f302SBen Matthews            h(i+1,i) = 0D0
131*1e99f302SBen Matthews            err(i+1) = -s(i)*err(i)
132*1e99f302SBen Matthews            err(i)   =  c(i)*err(i)
133*1e99f302SBen Matthews            IF (ABS(err(i+1)) .LT. eps) THEN
134*1e99f302SBen Matthews               ls%suc = .TRUE.
135*1e99f302SBen Matthews               EXIT
136*1e99f302SBen Matthews            END IF
137*1e99f302SBen Matthews         END DO
138*1e99f302SBen Matthews         IF (i .GT. ls%sD) i = ls%sD
139*1e99f302SBen Matthews
140*1e99f302SBen Matthews         y = err(1:i)
141*1e99f302SBen Matthews         DO j=i, 1, -1
142*1e99f302SBen Matthews            DO k=j+1, i
143*1e99f302SBen Matthews               y(j) = y(j) - h(j,k)*y(k)
144*1e99f302SBen Matthews            END DO
145*1e99f302SBen Matthews            y(j) = y(j)/h(j,j)
146*1e99f302SBen Matthews         END DO
147*1e99f302SBen Matthews
148*1e99f302SBen Matthews         DO j=1, i
149*1e99f302SBen Matthews            X = X + u(:,:,j)*y(j)
150*1e99f302SBen Matthews         END DO
151*1e99f302SBen Matthews         ls%fNorm = ABS(err(i+1))
152*1e99f302SBen Matthews         IF (ls%suc) EXIT
153*1e99f302SBen Matthews      END DO
154*1e99f302SBen Matthews
155*1e99f302SBen Matthews      ls%callD = CPUT() - time + ls%callD
156*1e99f302SBen Matthews      ls%dB    = 1D1*LOG(ls%fNorm/ls%dB)
157*1e99f302SBen Matthews
158*1e99f302SBen Matthews      RETURN
159*1e99f302SBen Matthews      END SUBROUTINE GMRES
160*1e99f302SBen Matthews
161*1e99f302SBen Matthews!====================================================================
162*1e99f302SBen Matthews
163*1e99f302SBen Matthews      SUBROUTINE GMRESV(nFaces, dof, nNo, nnz, mynNo, commu, cS, face,
164*1e99f302SBen Matthews     2   ls, rowPtr, colPtr, Val, R)
165*1e99f302SBen Matthews
166*1e99f302SBen Matthews      INCLUDE "svLS_STD.h"
167*1e99f302SBen Matthews
168*1e99f302SBen Matthews      INTEGER, INTENT(IN) :: nFaces, dof, nNo, nnz, mynNo
169*1e99f302SBen Matthews      TYPE(svLS_commuType), INTENT(IN) :: commu
170*1e99f302SBen Matthews      TYPE(svLS_cSType), INTENT(IN) :: cS(commu%nTasks)
171*1e99f302SBen Matthews      TYPE(svLS_faceType), INTENT(IN) :: face(nFaces)
172*1e99f302SBen Matthews      TYPE(svLS_subLsType), INTENT(INOUT) :: ls
173*1e99f302SBen Matthews      INTEGER, INTENT(IN) :: rowPtr(2,nNo), colPtr(nnz)
174*1e99f302SBen Matthews      REAL*8, INTENT(IN) :: Val(dof*dof,nnz)
175*1e99f302SBen Matthews      REAL*8, INTENT(INOUT) :: R(dof,nNo)
176*1e99f302SBen Matthews
177*1e99f302SBen Matthews      INTEGER i, j, k, l
178*1e99f302SBen Matthews      REAL*8 CPUT, NORMV, DOTV
179*1e99f302SBen Matthews      REAL*8 eps, tmp
180*1e99f302SBen Matthews      REAL*8, ALLOCATABLE :: u(:,:,:), h(:,:), X(:,:), y(:), c(:), s(:),
181*1e99f302SBen Matthews     2   err(:)
182*1e99f302SBen Matthews
183*1e99f302SBen Matthews      ALLOCATE(h(ls%sD+1,ls%sD), u(dof,nNo,ls%sD+1), X(dof,nNo),
184*1e99f302SBen Matthews     2   y(ls%sD), c(ls%sD), s(ls%sD), err(ls%sD+1))
185*1e99f302SBen Matthews
186*1e99f302SBen Matthews      ls%callD  = CPUT()
187*1e99f302SBen Matthews      ls%suc    = .FALSE.
188*1e99f302SBen Matthews      eps       = NORMV(dof, mynNo, commu, R)
189*1e99f302SBen Matthews      ls%iNorm  = eps
190*1e99f302SBen Matthews      ls%fNorm  = eps
191*1e99f302SBen Matthews      eps       = MAX(ls%absTol,ls%relTol*eps)
192*1e99f302SBen Matthews      ls%itr    = 0
193*1e99f302SBen Matthews      X         = 0D0
194*1e99f302SBen Matthews
195*1e99f302SBen Matthews      IF (ls%iNorm .LE. ls%absTol) THEN
196*1e99f302SBen Matthews         ls%callD = 0D0
197*1e99f302SBen Matthews         ls%dB    = 0D0
198*1e99f302SBen Matthews         RETURN
199*1e99f302SBen Matthews      END IF
200*1e99f302SBen Matthews      DO l=1, ls%mItr
201*1e99f302SBen Matthews         ls%dB = ls%fNorm
202*1e99f302SBen Matthews         ls%itr = ls%itr + 1
203*1e99f302SBen Matthews         CALL SPARMULVV(dof, nNo, nnz, commu, cS, rowPtr, colPtr,
204*1e99f302SBen Matthews     2      Val, X, u(:,:,1))
205*1e99f302SBen Matthews         CALL ADDBCMUL(BCOP_TYPE_ADD, nFaces, dof, nNo, mynNo, commu,
206*1e99f302SBen Matthews     2      face, X, u(:,:,1))
207*1e99f302SBen Matthews
208*1e99f302SBen Matthews         u(:,:,1) = R - u(:,:,1)
209*1e99f302SBen Matthews         err(1)   = NORMV(dof, mynNo, commu, u(:,:,1))
210*1e99f302SBen Matthews         u(:,:,1) = u(:,:,1)/err(1)
211*1e99f302SBen Matthews         DO i=1, ls%sD
212*1e99f302SBen Matthews            ls%itr = ls%itr + 1
213*1e99f302SBen Matthews            CALL SPARMULVV(dof, nNo, nnz, commu, cS, rowPtr, colPtr,
214*1e99f302SBen Matthews     2         Val, u(:,:,i), u(:,:,i+1))
215*1e99f302SBen Matthews            CALL ADDBCMUL(BCOP_TYPE_ADD, nFaces, dof, nNo, mynNo, commu,
216*1e99f302SBen Matthews     2         face, u(:,:,i), u(:,:,i+1))
217*1e99f302SBen Matthews
218*1e99f302SBen Matthews            DO j=1, i
219*1e99f302SBen Matthews               h(j,i) = DOTV(dof, mynNo, commu, u(:,:,i+1), u(:,:,j))
220*1e99f302SBen Matthews               u(:,:,i+1) = u(:,:,i+1) - h(j,i)*u(:,:,j)
221*1e99f302SBen Matthews            END DO
222*1e99f302SBen Matthews            h(i+1,i)   = NORMV(dof, mynNo, commu, u(:,:,i+1))
223*1e99f302SBen Matthews            u(:,:,i+1) = u(:,:,i+1)/h(i+1,i)
224*1e99f302SBen Matthews            DO j=1, i-1
225*1e99f302SBen Matthews               tmp      =  c(j)*h(j,i) + s(j)*h(j+1,i)
226*1e99f302SBen Matthews               h(j+1,i) = -s(j)*h(j,i) + c(j)*h(j+1,i)
227*1e99f302SBen Matthews               h(j,i)   =  tmp
228*1e99f302SBen Matthews            END DO
229*1e99f302SBen Matthews            tmp      = SQRT(h(i,i)*h(i,i) + h(i+1,i)*h(i+1,i))
230*1e99f302SBen Matthews            c(i)     = h(i,i)/tmp
231*1e99f302SBen Matthews            s(i)     = h(i+1,i)/tmp
232*1e99f302SBen Matthews            h(i,i)   = tmp
233*1e99f302SBen Matthews            h(i+1,i) = 0D0
234*1e99f302SBen Matthews            err(i+1) = -s(i)*err(i)
235*1e99f302SBen Matthews            err(i)   =  c(i)*err(i)
236*1e99f302SBen Matthews            IF (ABS(err(i+1)) .LT. eps) THEN
237*1e99f302SBen Matthews               ls%suc = .TRUE.
238*1e99f302SBen Matthews               EXIT
239*1e99f302SBen Matthews            END IF
240*1e99f302SBen Matthews         END DO
241*1e99f302SBen Matthews         IF (i .GT. ls%sD) i = ls%sD
242*1e99f302SBen Matthews
243*1e99f302SBen Matthews         y = err(1:i)
244*1e99f302SBen Matthews         DO j=i, 1, -1
245*1e99f302SBen Matthews            DO k=j+1, i
246*1e99f302SBen Matthews               y(j) = y(j) - h(j,k)*y(k)
247*1e99f302SBen Matthews            END DO
248*1e99f302SBen Matthews            y(j) = y(j)/h(j,j)
249*1e99f302SBen Matthews         END DO
250*1e99f302SBen Matthews
251*1e99f302SBen Matthews         DO j=1, i
252*1e99f302SBen Matthews            X = X + u(:,:,j)*y(j)
253*1e99f302SBen Matthews         END DO
254*1e99f302SBen Matthews         ls%fNorm = ABS(err(i+1))
255*1e99f302SBen Matthews         IF (ls%suc) EXIT
256*1e99f302SBen Matthews      END DO
257*1e99f302SBen Matthews      R = X
258*1e99f302SBen Matthews      ls%callD = CPUT() - ls%callD
259*1e99f302SBen Matthews      ls%dB    = 1D1*LOG(ls%fNorm/ls%dB)
260*1e99f302SBen Matthews
261*1e99f302SBen Matthews      RETURN
262*1e99f302SBen Matthews      END SUBROUTINE GMRESV
263*1e99f302SBen Matthews
264