xref: /phasta/svLS/CGRAD.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 CGRAD(nFaces, dof, nNo, nnz, mynNo, commu, cS, face,
42*1e99f302SBen Matthews     2   ls, rowPtr, colPtr, D, G, L, R)
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) :: D(dof,nnz), G(dof,nnz), L(nnz)
53*1e99f302SBen Matthews      REAL*8, INTENT(INOUT) :: R(nNo)
54*1e99f302SBen Matthews
55*1e99f302SBen Matthews      INTEGER i
56*1e99f302SBen Matthews      REAL*8 errO, err, alpha, eps, time
57*1e99f302SBen Matthews      REAL*8 CPUT, NORMS, DOTS
58*1e99f302SBen Matthews      REAL*8, ALLOCATABLE :: X(:), P(:), SP(:), DGP(:), GP(:,:),
59*1e99f302SBen Matthews     2   unCondU(:,:)
60*1e99f302SBen Matthews
61*1e99f302SBen Matthews      ALLOCATE(X(nNo), P(nNo), SP(nNo), DGP(nNo), GP(dof,nNo),
62*1e99f302SBen Matthews     2   unCondU(dof,nNo))
63*1e99f302SBen Matthews
64*1e99f302SBen Matthews      time     = CPUT()
65*1e99f302SBen Matthews      ls%suc   = .FALSE.
66*1e99f302SBen Matthews      errO     = NORMS(mynNo, commu, R)
67*1e99f302SBen Matthews      ls%iNorm = errO
68*1e99f302SBen Matthews      eps      = MAX(ls%absTol,ls%relTol*errO)
69*1e99f302SBen Matthews      eps      = eps*eps
70*1e99f302SBen Matthews      X        = 0D0
71*1e99f302SBen Matthews
72*1e99f302SBen Matthews      err      = errO
73*1e99f302SBen Matthews      err      = err*err
74*1e99f302SBen Matthews      P        = R
75*1e99f302SBen Matthews      DO i=1, ls%mItr
76*1e99f302SBen Matthews         IF (err .LT. eps) THEN
77*1e99f302SBen Matthews            ls%suc = .TRUE.
78*1e99f302SBen Matthews            EXIT
79*1e99f302SBen Matthews         END IF
80*1e99f302SBen Matthews         errO = err
81*1e99f302SBen Matthews         CALL SPARMULSV(dof, nNo, nnz, commu, cS, rowPtr, colPtr,
82*1e99f302SBen Matthews     2      G, P, GP)
83*1e99f302SBen Matthews
84*1e99f302SBen Matthews         IF (ANY(face%coupledFlag)) THEN
85*1e99f302SBen Matthews            unCondU = GP
86*1e99f302SBen Matthews            CALL ADDBCMUL(BCOP_TYPE_PRE, nFaces, dof, nNo, mynNo, commu,
87*1e99f302SBen Matthews     2         face, unCondU, GP)
88*1e99f302SBen Matthews         END IF
89*1e99f302SBen Matthews
90*1e99f302SBen Matthews         CALL SPARMULVS(dof, nNo, nnz, commu, cS, rowPtr, colPtr,
91*1e99f302SBen Matthews     2      D, GP, DGP)
92*1e99f302SBen Matthews
93*1e99f302SBen Matthews         CALL SPARMULSS(     nNo, nnz, commu, cS, rowPtr, colPtr,
94*1e99f302SBen Matthews     2      L, P, SP)
95*1e99f302SBen Matthews
96*1e99f302SBen Matthews         SP    = SP - DGP
97*1e99f302SBen Matthews         alpha = errO/DOTS(mynNo, commu, P, SP)
98*1e99f302SBen Matthews         X     = X + alpha*P
99*1e99f302SBen Matthews         R     = R - alpha*SP
100*1e99f302SBen Matthews         err   = NORMS(mynNo, commu, R)
101*1e99f302SBen Matthews         err   = err*err
102*1e99f302SBen Matthews         P     = R + err/errO*P
103*1e99f302SBen Matthews      END DO
104*1e99f302SBen Matthews      R        = X
105*1e99f302SBen Matthews      ls%fNorm = SQRT(err)
106*1e99f302SBen Matthews      ls%callD = CPUT() - time + ls%callD
107*1e99f302SBen Matthews      ls%dB    = 5D0*LOG(err/errO)
108*1e99f302SBen Matthews      ls%itr   = ls%itr + i - 1
109*1e99f302SBen Matthews
110*1e99f302SBen Matthews      DEALLOCATE(X, P, SP, DGP, GP)
111*1e99f302SBen Matthews
112*1e99f302SBen Matthews      RETURN
113*1e99f302SBen Matthews      END SUBROUTINE CGRAD
114*1e99f302SBen Matthews
115*1e99f302SBen Matthews!====================================================================
116*1e99f302SBen Matthews
117*1e99f302SBen Matthews      SUBROUTINE CGRADV(dof, nNo, nnz, mynNo, commu, cS, ls,
118*1e99f302SBen Matthews     2   rowPtr, colPtr, K, R)
119*1e99f302SBen Matthews
120*1e99f302SBen Matthews      INCLUDE "svLS_STD.h"
121*1e99f302SBen Matthews
122*1e99f302SBen Matthews      INTEGER, INTENT(IN) :: dof, nNo, nnz, mynNo
123*1e99f302SBen Matthews      TYPE(svLS_commuType), INTENT(IN) :: commu
124*1e99f302SBen Matthews      TYPE(svLS_cSType), INTENT(IN) :: cS(commu%nTasks)
125*1e99f302SBen Matthews      TYPE(svLS_subLsType), INTENT(INOUT) :: ls
126*1e99f302SBen Matthews      INTEGER, INTENT(IN) :: rowPtr(2,nNo), colPtr(nnz)
127*1e99f302SBen Matthews      REAL*8, INTENT(IN) :: K(dof*dof,nnz)
128*1e99f302SBen Matthews      REAL*8, INTENT(INOUT) :: R(dof,nNo)
129*1e99f302SBen Matthews
130*1e99f302SBen Matthews      INTEGER i
131*1e99f302SBen Matthews      REAL*8 errO, err, alpha, eps
132*1e99f302SBen Matthews      REAL*8 CPUT, NORMV, DOTV
133*1e99f302SBen Matthews      REAL*8, ALLOCATABLE :: P(:,:), KP(:,:), X(:,:)
134*1e99f302SBen Matthews
135*1e99f302SBen Matthews      ALLOCATE(P(dof,nNo), KP(dof,nNo), X(dof,nNo))
136*1e99f302SBen Matthews
137*1e99f302SBen Matthews      ls%callD = CPUT()
138*1e99f302SBen Matthews      ls%suc   = .FALSE.
139*1e99f302SBen Matthews      err      = NORMV(dof, mynNo, commu, R)
140*1e99f302SBen Matthews      ls%iNorm = err
141*1e99f302SBen Matthews      eps      = MAX(ls%absTol,ls%relTol*err)
142*1e99f302SBen Matthews      eps      = eps*eps
143*1e99f302SBen Matthews      err      = err*err
144*1e99f302SBen Matthews      X        = 0D0
145*1e99f302SBen Matthews      P        = R
146*1e99f302SBen Matthews
147*1e99f302SBen Matthews      DO i=1, ls%mItr
148*1e99f302SBen Matthews         IF (err .LT. eps) THEN
149*1e99f302SBen Matthews            ls%suc = .TRUE.
150*1e99f302SBen Matthews            EXIT
151*1e99f302SBen Matthews         END IF
152*1e99f302SBen Matthews         errO = err
153*1e99f302SBen Matthews         CALL SPARMULVV(dof, nNo, nnz, commu, cS, rowPtr, colPtr,
154*1e99f302SBen Matthews     2      K, P, KP)
155*1e99f302SBen Matthews
156*1e99f302SBen Matthews         alpha = errO/DOTV(dof, mynNo, commu, P, KP)
157*1e99f302SBen Matthews         X     = X + alpha*P
158*1e99f302SBen Matthews         R     = R - alpha*KP
159*1e99f302SBen Matthews         err   = NORMV(dof, mynNo, commu, R)
160*1e99f302SBen Matthews         err   = err*err
161*1e99f302SBen Matthews         P = R + err/errO*P
162*1e99f302SBen Matthews      END DO
163*1e99f302SBen Matthews
164*1e99f302SBen Matthews      R        = X
165*1e99f302SBen Matthews      ls%itr   = i - 1
166*1e99f302SBen Matthews      ls%fNorm = SQRT(err)
167*1e99f302SBen Matthews      ls%callD = CPUT() - ls%callD
168*1e99f302SBen Matthews      ls%dB    = 5D0*LOG(err/errO)
169*1e99f302SBen Matthews      IF (i .GT. ls%mItr) ls%itr = ls%mItr
170*1e99f302SBen Matthews
171*1e99f302SBen Matthews      RETURN
172*1e99f302SBen Matthews      END SUBROUTINE CGRADV
173*1e99f302SBen Matthews
174*1e99f302SBen Matthews!====================================================================
175*1e99f302SBen Matthews
176*1e99f302SBen Matthews      SUBROUTINE CGRADS(nNo, nnz, mynNo, commu, cS, ls,
177*1e99f302SBen Matthews     2   rowPtr, colPtr, K, R)
178*1e99f302SBen Matthews
179*1e99f302SBen Matthews      INCLUDE "svLS_STD.h"
180*1e99f302SBen Matthews
181*1e99f302SBen Matthews      INTEGER, INTENT(IN) :: nNo, nnz, mynNo
182*1e99f302SBen Matthews      TYPE(svLS_commuType), INTENT(IN) :: commu
183*1e99f302SBen Matthews      TYPE(svLS_cSType), INTENT(IN) :: cS(commu%nTasks)
184*1e99f302SBen Matthews      TYPE(svLS_subLsType), INTENT(INOUT) :: ls
185*1e99f302SBen Matthews      INTEGER, INTENT(IN) :: rowPtr(2,nNo), colPtr(nnz)
186*1e99f302SBen Matthews      REAL*8, INTENT(IN) :: K(nnz)
187*1e99f302SBen Matthews      REAL*8, INTENT(INOUT) :: R(nNo)
188*1e99f302SBen Matthews
189*1e99f302SBen Matthews      INTEGER i
190*1e99f302SBen Matthews      REAL*8 errO, err, alpha, eps
191*1e99f302SBen Matthews      REAL*8 CPUT, NORMS, DOTS
192*1e99f302SBen Matthews      REAL*8, ALLOCATABLE :: P(:), KP(:), X(:)
193*1e99f302SBen Matthews
194*1e99f302SBen Matthews      ALLOCATE(P(nNo), KP(nNo), X(nNo))
195*1e99f302SBen Matthews
196*1e99f302SBen Matthews      ls%callD = CPUT()
197*1e99f302SBen Matthews      ls%suc   = .FALSE.
198*1e99f302SBen Matthews      err      = NORMS(mynNo, commu, R)
199*1e99f302SBen Matthews      ls%iNorm = err
200*1e99f302SBen Matthews      eps      = MAX(ls%absTol,ls%relTol*err)
201*1e99f302SBen Matthews      eps      = eps*eps
202*1e99f302SBen Matthews      err      = err*err
203*1e99f302SBen Matthews      X        = 0D0
204*1e99f302SBen Matthews      P        = R
205*1e99f302SBen Matthews
206*1e99f302SBen Matthews      DO i=1, ls%mItr
207*1e99f302SBen Matthews         IF (err .LT. eps) THEN
208*1e99f302SBen Matthews            ls%suc = .TRUE.
209*1e99f302SBen Matthews            EXIT
210*1e99f302SBen Matthews         END IF
211*1e99f302SBen Matthews         errO = err
212*1e99f302SBen Matthews         CALL SPARMULSS(nNo, nnz, commu, cS, rowPtr, colPtr, K, P, KP)
213*1e99f302SBen Matthews         alpha = errO/DOTS(mynNo, commu, P, KP)
214*1e99f302SBen Matthews         X     = X + alpha*P
215*1e99f302SBen Matthews         R     = R - alpha*KP
216*1e99f302SBen Matthews         err   = NORMS(mynNo, commu, R)
217*1e99f302SBen Matthews         err   = err*err
218*1e99f302SBen Matthews         P = R + err/errO*P
219*1e99f302SBen Matthews      END DO
220*1e99f302SBen Matthews
221*1e99f302SBen Matthews      R        = X
222*1e99f302SBen Matthews      ls%itr   = i - 1
223*1e99f302SBen Matthews      ls%fNorm = SQRT(err)
224*1e99f302SBen Matthews      ls%callD = CPUT() - ls%callD
225*1e99f302SBen Matthews      ls%dB    = 5D0*LOG(err/errO)
226*1e99f302SBen Matthews      IF (i .GT. ls%mItr) ls%itr = ls%mItr
227*1e99f302SBen Matthews
228*1e99f302SBen Matthews      RETURN
229*1e99f302SBen Matthews      END SUBROUTINE CGRADS
230