/[MITgcm]/MITgcm/pkg/diagnostics/diag_cg2d.F
ViewVC logotype

Annotation of /MITgcm/pkg/diagnostics/diag_cg2d.F

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.4 - (hide annotations) (download)
Wed Aug 24 02:23:41 2011 UTC (12 years, 8 months ago) by jmc
Branch: MAIN
CVS Tags: checkpoint63h, checkpoint63i, checkpoint63j, checkpoint63k, checkpoint63d, checkpoint63e, checkpoint63f, checkpoint63g, checkpoint63b, checkpoint63c
Changes since 1.3: +15 -1 lines
Initialise main diagonal (aC2d) to get valid value in overlap regions
 (in case EXCH call do not fill them all)

1 jmc 1.4 C $Header: /u/gcmpack/MITgcm/pkg/diagnostics/diag_cg2d.F,v 1.3 2011/08/01 20:40:43 jmc Exp $
2 jmc 1.1 C $Name: $
3    
4     #include "DIAG_OPTIONS.h"
5 jmc 1.3 #undef DEBUG_DIAG_CG2D
6 jmc 1.1
7     CBOP
8     C !ROUTINE: DIAG_CG2D
9     C !INTERFACE:
10     SUBROUTINE DIAG_CG2D(
11     I aW2d, aS2d, b2d,
12     I residCriter,
13 jmc 1.2 O firstResidual, minResidual, lastResidual,
14 jmc 1.1 U x2d, numIters,
15 jmc 1.2 O nIterMin,
16     I printResidFrq, myThid )
17 jmc 1.1 C !DESCRIPTION: \bv
18     C *==========================================================*
19     C | SUBROUTINE CG2D
20     C | o Two-dimensional grid problem conjugate-gradient
21     C | inverter (with preconditioner).
22     C *==========================================================*
23     C | Con. grad is an iterative procedure for solving Ax = b.
24     C | It requires the A be symmetric.
25     C | This implementation assumes A is a five-diagonal
26     C | matrix of the form that arises in the discrete
27     C | representation of the del^2 operator in a
28     C | two-dimensional space.
29     C *==========================================================*
30     C \ev
31    
32     C !USES:
33     IMPLICIT NONE
34     C === Global data ===
35     #include "SIZE.h"
36     #include "EEPARAMS.h"
37     #include "PARAMS.h"
38    
39     C !INPUT/OUTPUT PARAMETERS:
40     C === Routine arguments ===
41 jmc 1.2 C b2d :: The source term or "right hand side"
42     C x2d :: The solution
43 jmc 1.1 C firstResidual :: the initial residual before any iterations
44 jmc 1.2 C minResidual :: the lowest residual reached
45 jmc 1.1 C lastResidual :: the actual residual reached
46     C numIters :: Entry: the maximum number of iterations allowed
47     C Exit: the actual number of iterations used
48 jmc 1.2 C nIterMin :: iteration number corresponding to lowest residual
49     C printResidFrq :: Frequency for printing residual in CG iterations
50     C myThid :: my Thread Id number
51 jmc 1.1 _RS aW2d(1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy)
52     _RS aS2d(1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy)
53     _RL b2d (1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy)
54     _RL residCriter
55     _RL firstResidual
56 jmc 1.2 _RL minResidual
57 jmc 1.1 _RL lastResidual
58     _RL x2d (1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy)
59     INTEGER numIters
60 jmc 1.2 INTEGER nIterMin
61     INTEGER printResidFrq
62 jmc 1.1 INTEGER myThid
63    
64     C !LOCAL VARIABLES:
65     C === Local variables ====
66 jmc 1.2 C bi, bj :: tile indices
67 jmc 1.1 C eta_qrN :: Used in computing search directions
68     C eta_qrNM1 suffix N and NM1 denote current and
69     C cgBeta previous iterations respectively.
70     C alpha
71     C sumRHS :: Sum of right-hand-side. Sometimes this is a
72     C useful debuggin/trouble shooting diagnostic.
73     C For neumann problems sumRHS needs to be ~0.
74     C or they converge at a non-zero residual.
75 jmc 1.2 C err :: Measure of current residual of Ax - b, usually the norm.
76 jmc 1.1 C i, j, it2d :: Loop counters ( it2d counts CG iterations )
77     INTEGER bi, bj
78     INTEGER i, j, it2d
79     _RL err, errTile(nSx,nSy)
80     _RL eta_qrN, eta_qrNtile(nSx,nSy)
81     _RL eta_qrNM1
82     _RL cgBeta
83     _RL alpha, alphaTile(nSx,nSy)
84     _RL sumRHS, sumRHStile(nSx,nSy)
85     _RL pW_tmp, pS_tmp
86 jmc 1.3 _RL diagCG_pcOffDFac
87 jmc 1.1 CHARACTER*(MAX_LEN_MBUF) msgBuf
88     LOGICAL printResidual
89     CEOP
90     _RS aC2d(1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy)
91     _RS pW (1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy)
92     _RS pS (1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy)
93     _RS pC (1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy)
94     _RL q2d(1-1:sNx+1,1-1:sNy+1,nSx,nSy)
95 jmc 1.3 #ifdef DEBUG_DIAG_CG2D
96     CHARACTER*(10) sufx
97     _RL r2d(1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy)
98     #else
99 jmc 1.1 _RL r2d(1-1:sNx+1,1-1:sNy+1,nSx,nSy)
100 jmc 1.3 #endif
101 jmc 1.1 _RL s2d(1-1:sNx+1,1-1:sNy+1,nSx,nSy)
102 jmc 1.2 _RL x2dm(1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy)
103 jmc 1.1
104 jmc 1.4 #ifdef ALLOW_DEBUG
105     IF (debugMode) CALL DEBUG_ENTER('DIAG_CG2D',myThid)
106     #endif
107    
108 jmc 1.1 C-- Set matrice main diagnonal:
109     DO bj=myByLo(myThid),myByHi(myThid)
110     DO bi=myBxLo(myThid),myBxHi(myThid)
111 jmc 1.4 C- Initialise overlap regions (in case EXCH call do not fill them all)
112     DO j = 1-Oly,sNy+Oly
113     DO i = 1-Olx,sNx+Olx
114     aC2d(i,j,bi,bj) = 0.
115     ENDDO
116     ENDDO
117 jmc 1.1 DO j=1,sNy
118     DO i=1,sNx
119     aC2d(i,j,bi,bj) = -( ( aW2d(i,j,bi,bj)+aW2d(i+1,j,bi,bj) )
120     & +( aS2d(i,j,bi,bj)+aS2d(i,j+1,bi,bj) )
121     & )
122     ENDDO
123     ENDDO
124     ENDDO
125     ENDDO
126     CALL EXCH_XY_RS(aC2d, myThid)
127    
128     C-- Initialise preconditioner
129 jmc 1.3 diagCG_pcOffDFac = cg2dpcOffDFac
130 jmc 1.1 DO bj=myByLo(myThid),myByHi(myThid)
131     DO bi=myBxLo(myThid),myBxHi(myThid)
132     DO j=1,sNy+1
133     DO i=1,sNx+1
134     IF ( aC2d(i,j,bi,bj) .EQ. 0. ) THEN
135     pC(i,j,bi,bj) = 1. _d 0
136     ELSE
137     pC(i,j,bi,bj) = 1. _d 0 / aC2d(i,j,bi,bj)
138     ENDIF
139     pW_tmp = aC2d(i,j,bi,bj)+aC2d(i-1,j,bi,bj)
140     IF ( pW_tmp .EQ. 0. ) THEN
141     pW(i,j,bi,bj) = 0.
142     ELSE
143     pW(i,j,bi,bj) = -aW2d(i,j,bi,bj)
144 jmc 1.3 & /( (diagCG_pcOffDFac*pW_tmp)**2 )
145 jmc 1.1 ENDIF
146     pS_tmp = aC2d(i,j,bi,bj)+aC2d(i,j-1,bi,bj)
147     IF ( pS_tmp .EQ. 0. ) THEN
148     pS(i,j,bi,bj) = 0.
149     ELSE
150     pS(i,j,bi,bj) = -aS2d(i,j,bi,bj)
151 jmc 1.3 & /( (diagCG_pcOffDFac*pS_tmp)**2 )
152 jmc 1.1 ENDIF
153 jmc 1.3 c pC(i,j,bi,bj) = 1.
154     c pW(i,j,bi,bj) = 0.
155     c pS(i,j,bi,bj) = 0.
156 jmc 1.1 ENDDO
157     ENDDO
158     ENDDO
159     ENDDO
160    
161     C-- Initialise inverter
162     eta_qrNM1 = 1. _d 0
163    
164     CALL EXCH_XY_RL( x2d, myThid )
165    
166     C-- Initial residual calculation
167     DO bj=myByLo(myThid),myByHi(myThid)
168     DO bi=myBxLo(myThid),myBxHi(myThid)
169     DO j=1-1,sNy+1
170     DO i=1-1,sNx+1
171     s2d(i,j,bi,bj) = 0.
172 jmc 1.2 x2dm(i,j,bi,bj) = x2d(i,j,bi,bj)
173 jmc 1.1 ENDDO
174     ENDDO
175     sumRHStile(bi,bj) = 0. _d 0
176     errTile(bi,bj) = 0. _d 0
177     DO j=1,sNy
178     DO i=1,sNx
179     r2d(i,j,bi,bj) = b2d(i,j,bi,bj) -
180     & (aW2d(i ,j ,bi,bj)*x2d(i-1,j ,bi,bj)
181     & +aW2d(i+1,j ,bi,bj)*x2d(i+1,j ,bi,bj)
182     & +aS2d(i ,j ,bi,bj)*x2d(i ,j-1,bi,bj)
183     & +aS2d(i ,j+1,bi,bj)*x2d(i ,j+1,bi,bj)
184     & +aC2d(i ,j ,bi,bj)*x2d(i ,j ,bi,bj)
185     & )
186     errTile(bi,bj) = errTile(bi,bj)
187     & + r2d(i,j,bi,bj)*r2d(i,j,bi,bj)
188     sumRHStile(bi,bj) = sumRHStile(bi,bj) + b2d(i,j,bi,bj)
189     ENDDO
190     ENDDO
191     ENDDO
192     ENDDO
193 jmc 1.3 #ifdef DEBUG_DIAG_CG2D
194     CALL EXCH_XY_RL ( r2d, myThid )
195     #else
196 jmc 1.1 CALL EXCH_S3D_RL( r2d, 1, myThid )
197 jmc 1.3 #endif
198 jmc 1.1 CALL GLOBAL_SUM_TILE_RL( errTile, err, myThid )
199 jmc 1.3 IF ( printResidFrq.GE.1 )
200     & CALL GLOBAL_SUM_TILE_RL( sumRHStile, sumRHS, myThid )
201 jmc 1.1 err = SQRT(err)
202 jmc 1.2 it2d = 0
203     firstResidual = err
204     minResidual = err
205     nIterMin = it2d
206 jmc 1.1
207     printResidual = .FALSE.
208     IF ( debugLevel .GE. debLevZero ) THEN
209     _BEGIN_MASTER( myThid )
210 jmc 1.2 printResidual = printResidFrq.GE.1
211 jmc 1.3 IF ( printResidual ) THEN
212     WRITE(msgBuf,'(2A,I6,A,1PE17.9,A,1PE14.6)')' diag_cg2d:',
213     & ' iter=', it2d, ' ; resid.=', err, ' ; sumRHS=', sumRHS
214     CALL PRINT_MESSAGE( msgBuf, standardMessageUnit,
215     & SQUEEZE_RIGHT, myThid )
216     ENDIF
217 jmc 1.1 _END_MASTER( myThid )
218     ENDIF
219 jmc 1.3 #ifdef DEBUG_DIAG_CG2D
220     IF ( printResidFrq.GE.1 ) THEN
221     WRITE(sufx,'(I10.10)') 0
222     CALL WRITE_FLD_XY_RL( 'r2d.',sufx, r2d, 1, myThid )
223     ENDIF
224     #endif
225 jmc 1.1
226     IF ( err .LT. residCriter ) GOTO 11
227    
228     C >>>>>>>>>>>>>>> BEGIN SOLVER <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
229     DO 10 it2d=1, numIters
230    
231     C-- Solve preconditioning equation and update
232     C-- conjugate direction vector "s".
233     DO bj=myByLo(myThid),myByHi(myThid)
234     DO bi=myBxLo(myThid),myBxHi(myThid)
235     eta_qrNtile(bi,bj) = 0. _d 0
236     DO j=1,sNy
237     DO i=1,sNx
238     q2d(i,j,bi,bj) =
239     & pC(i ,j ,bi,bj)*r2d(i ,j ,bi,bj)
240     & +pW(i ,j ,bi,bj)*r2d(i-1,j ,bi,bj)
241     & +pW(i+1,j ,bi,bj)*r2d(i+1,j ,bi,bj)
242     & +pS(i ,j ,bi,bj)*r2d(i ,j-1,bi,bj)
243     & +pS(i ,j+1,bi,bj)*r2d(i ,j+1,bi,bj)
244     eta_qrNtile(bi,bj) = eta_qrNtile(bi,bj)
245     & +q2d(i,j,bi,bj)*r2d(i,j,bi,bj)
246     ENDDO
247     ENDDO
248     ENDDO
249     ENDDO
250    
251     CALL GLOBAL_SUM_TILE_RL( eta_qrNtile,eta_qrN,myThid )
252     cgBeta = eta_qrN/eta_qrNM1
253     eta_qrNM1 = eta_qrN
254    
255     DO bj=myByLo(myThid),myByHi(myThid)
256     DO bi=myBxLo(myThid),myBxHi(myThid)
257     DO j=1,sNy
258     DO i=1,sNx
259     s2d(i,j,bi,bj) = q2d(i,j,bi,bj)
260     & + cgBeta*s2d(i,j,bi,bj)
261     ENDDO
262     ENDDO
263     ENDDO
264     ENDDO
265    
266     C-- Do exchanges that require messages i.e. between processes.
267     CALL EXCH_S3D_RL( s2d, 1, myThid )
268    
269     C== Evaluate laplace operator on conjugate gradient vector
270     C== q = A.s
271     DO bj=myByLo(myThid),myByHi(myThid)
272     DO bi=myBxLo(myThid),myBxHi(myThid)
273     alphaTile(bi,bj) = 0. _d 0
274     DO j=1,sNy
275     DO i=1,sNx
276     q2d(i,j,bi,bj) =
277     & aW2d(i ,j ,bi,bj)*s2d(i-1,j ,bi,bj)
278     & +aW2d(i+1,j ,bi,bj)*s2d(i+1,j ,bi,bj)
279     & +aS2d(i ,j ,bi,bj)*s2d(i ,j-1,bi,bj)
280     & +aS2d(i ,j+1,bi,bj)*s2d(i ,j+1,bi,bj)
281     & +aC2d(i ,j ,bi,bj)*s2d(i ,j ,bi,bj)
282     alphaTile(bi,bj) = alphaTile(bi,bj)
283     & + s2d(i,j,bi,bj)*q2d(i,j,bi,bj)
284     ENDDO
285     ENDDO
286     ENDDO
287     ENDDO
288     CALL GLOBAL_SUM_TILE_RL( alphaTile, alpha, myThid )
289     alpha = eta_qrN/alpha
290    
291     C== Update solution and residual vectors
292     C Now compute "interior" points.
293     DO bj=myByLo(myThid),myByHi(myThid)
294     DO bi=myBxLo(myThid),myBxHi(myThid)
295     errTile(bi,bj) = 0. _d 0
296     DO j=1,sNy
297     DO i=1,sNx
298     x2d(i,j,bi,bj)=x2d(i,j,bi,bj)+alpha*s2d(i,j,bi,bj)
299     r2d(i,j,bi,bj)=r2d(i,j,bi,bj)-alpha*q2d(i,j,bi,bj)
300     errTile(bi,bj) = errTile(bi,bj)
301     & + r2d(i,j,bi,bj)*r2d(i,j,bi,bj)
302     ENDDO
303     ENDDO
304     ENDDO
305     ENDDO
306    
307     CALL GLOBAL_SUM_TILE_RL( errTile, err, myThid )
308     err = SQRT(err)
309     IF ( printResidual ) THEN
310 jmc 1.2 IF ( MOD( it2d-1, printResidFrq ).EQ.0 ) THEN
311 jmc 1.3 WRITE(msgBuf,'(A,I6,A,1PE17.9)')
312     & ' diag_cg2d: iter=', it2d, ' ; resid.=', err
313 jmc 1.1 CALL PRINT_MESSAGE( msgBuf, standardMessageUnit,
314     & SQUEEZE_RIGHT, myThid )
315     ENDIF
316     ENDIF
317     IF ( err .LT. residCriter ) GOTO 11
318 jmc 1.2 IF ( err .LT. minResidual ) THEN
319     C- Store lowest residual solution
320     minResidual = err
321     nIterMin = it2d
322     DO bj=myByLo(myThid),myByHi(myThid)
323     DO bi=myBxLo(myThid),myBxHi(myThid)
324     DO j=1,sNy
325     DO i=1,sNx
326     x2dm(i,j,bi,bj) = x2d(i,j,bi,bj)
327     ENDDO
328     ENDDO
329     ENDDO
330     ENDDO
331     ENDIF
332 jmc 1.1
333 jmc 1.3 #ifdef DEBUG_DIAG_CG2D
334     CALL EXCH_XY_RL( r2d, myThid )
335     IF ( printResidFrq.GE.1 ) THEN
336     WRITE(sufx,'(I10.10)') it2d
337     CALL WRITE_FLD_XY_RL( 'r2d.',sufx, r2d, 1, myThid )
338     CALL WRITE_FLD_XY_RL( 'x2d.',sufx, x2d, 1, myThid )
339     ENDIF
340     #else
341 jmc 1.1 CALL EXCH_S3D_RL( r2d, 1, myThid )
342 jmc 1.3 #endif
343 jmc 1.1
344     10 CONTINUE
345 jmc 1.2 it2d = numIters
346 jmc 1.1 11 CONTINUE
347    
348 jmc 1.2 C-- Return parameters to caller
349     lastResidual = err
350     numIters = it2d
351    
352     IF ( err .GT. minResidual ) THEN
353     C- use the lowest residual solution (instead of current one <-> last residual)
354     DO bj=myByLo(myThid),myByHi(myThid)
355     DO bi=myBxLo(myThid),myBxHi(myThid)
356     DO j=1,sNy
357     DO i=1,sNx
358     x2d(i,j,bi,bj) = x2dm(i,j,bi,bj)
359     ENDDO
360     ENDDO
361     ENDDO
362     ENDDO
363     ENDIF
364 jmc 1.1 c CALL EXCH_XY_RL( x2d, myThid )
365    
366 jmc 1.4 #ifdef ALLOW_DEBUG
367     IF (debugMode) CALL DEBUG_LEAVE('DIAG_CG2D',myThid)
368     #endif
369    
370 jmc 1.1 RETURN
371     END

  ViewVC Help
Powered by ViewVC 1.1.22