/[MITgcm]/MITgcm_contrib/heimbach/OpenAD/code_shallow_openad/cg2d.F
ViewVC logotype

Annotation of /MITgcm_contrib/heimbach/OpenAD/code_shallow_openad/cg2d.F

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


Revision 1.3 - (hide annotations) (download)
Thu Jan 11 15:19:59 2007 UTC (19 years, 10 months ago) by utke
Branch: MAIN
Changes since 1.2: +49 -49 lines
partial resync with regular version

1 utke 1.3 C $Header: /u/gcmpack/MITgcm_contrib/heimbach/OpenAD/code_shallow_openad/cg2d.F,v 1.2 2006/01/24 02:46:07 utke Exp $
2 utke 1.1 C $Name: $
3    
4     #include "CPP_OPTIONS.h"
5    
6     CBOP
7     C !ROUTINE: CG2D
8     C !INTERFACE:
9 utke 1.3 SUBROUTINE CG2D(
10 utke 1.1 I cg2d_b,
11     U cg2d_x,
12     O firstResidual,
13     O lastResidual,
14     U numIters,
15     I myThid )
16     C !DESCRIPTION: \bv
17     C *==========================================================*
18 utke 1.3 C | SUBROUTINE CG2D
19     C | o Two-dimensional grid problem conjugate-gradient
20     C | inverter (with preconditioner).
21 utke 1.1 C *==========================================================*
22 utke 1.3 C | Con. grad is an iterative procedure for solving Ax = b.
23     C | It requires the A be symmetric.
24     C | This implementation assumes A is a five-diagonal
25     C | matrix of the form that arises in the discrete
26     C | representation of the del^2 operator in a
27     C | two-dimensional space.
28     C | Notes:
29     C | ======
30     C | This implementation can support shared-memory
31     C | multi-threaded execution. In order to do this COMMON
32     C | blocks are used for many of the arrays - even ones that
33     C | are only used for intermedaite results. This design is
34     C | OK if you want to all the threads to collaborate on
35     C | solving the same problem. On the other hand if you want
36     C | the threads to solve several different problems
37     C | concurrently this implementation will not work.
38 utke 1.1 C *==========================================================*
39     C \ev
40    
41     C !USES:
42     IMPLICIT NONE
43     C === Global data ===
44     #include "SIZE.h"
45     #include "EEPARAMS.h"
46     #include "PARAMS.h"
47     #include "GRID.h"
48     #include "CG2D.h"
49     #include "SURFACE.h"
50    
51     C !INPUT/OUTPUT PARAMETERS:
52     C === Routine arguments ===
53 utke 1.3 C myThid :: Thread on which I am working.
54     C cg2d_b :: The source term or "right hand side"
55     C cg2d_x :: The solution
56     C firstResidual :: the initial residual before any iterations
57     C lastResidual :: the actual residual reached
58     C numIters :: Entry: the maximum number of iterations allowed
59     C Exit: the actual number of iterations used
60 utke 1.1 _RL cg2d_b(1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy)
61     _RL cg2d_x(1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy)
62     _RL firstResidual
63     _RL lastResidual
64     INTEGER numIters
65     INTEGER myThid
66    
67     C !LOCAL VARIABLES:
68     C === Local variables ====
69 utke 1.3 C actualIts :: Number of iterations taken
70     C actualResidual :: residual
71     C bi, bj :: Block index in X and Y.
72     C eta_qrN :: Used in computing search directions
73 utke 1.1 C eta_qrNM1 suffix N and NM1 denote current and
74     C cgBeta previous iterations respectively.
75 utke 1.3 C alpha
76     C sumRHS :: Sum of right-hand-side. Sometimes this is a
77 utke 1.1 C useful debuggin/trouble shooting diagnostic.
78     C For neumann problems sumRHS needs to be ~0.
79     C or they converge at a non-zero residual.
80 utke 1.3 C err :: Measure of residual of Ax - b, usually the norm.
81     C I, J, it2d :: Loop counters ( it2d counts CG iterations )
82 utke 1.1 INTEGER actualIts
83     _RL actualResidual
84 utke 1.3 INTEGER bi, bj
85 utke 1.1 INTEGER I, J, it2d
86 utke 1.3 c INTEGER ks
87 utke 1.1 _RL err,errTile
88     _RL eta_qrN,eta_qrNtile
89     _RL eta_qrNM1
90     _RL cgBeta
91     _RL alpha,alphaTile
92     _RL sumRHS,sumRHStile
93     _RL rhsMax
94     _RL rhsNorm
95     CEOP
96    
97    
98     CcnhDebugStarts
99     C CHARACTER*(MAX_LEN_FNAM) suff
100     CcnhDebugEnds
101    
102    
103     C-- Initialise inverter
104     eta_qrNM1 = 1. _d 0
105    
106     CcnhDebugStarts
107     C _EXCH_XY_R8( cg2d_b, myThid )
108     C CALL PLOT_FIELD_XYRL( cg2d_b, 'CG2D.0 CG2D_B' , 1, myThid )
109     C suff = 'unnormalised'
110     C CALL WRITE_FLD_XY_RL ( 'cg2d_b.',suff, cg2d_b, 1, myThid)
111     C STOP
112     CcnhDebugEnds
113    
114     C-- Normalise RHS
115     rhsMax = 0. _d 0
116     DO bj=myByLo(myThid),myByHi(myThid)
117     DO bi=myBxLo(myThid),myBxHi(myThid)
118     DO J=1,sNy
119     DO I=1,sNx
120     cg2d_b(I,J,bi,bj) = cg2d_b(I,J,bi,bj)*cg2dNorm
121     rhsMax = MAX(ABS(cg2d_b(I,J,bi,bj)),rhsMax)
122     ENDDO
123     ENDDO
124     ENDDO
125     ENDDO
126    
127     IF (cg2dNormaliseRHS) THEN
128     C- Normalise RHS :
129     #ifdef LETS_MAKE_JAM
130     C _GLOBAL_MAX_R8( rhsMax, myThid )
131     rhsMax=1.
132     #else
133     _GLOBAL_MAX_R8( rhsMax, myThid )
134     #endif
135     rhsNorm = 1. _d 0
136     IF ( rhsMax .NE. 0. ) rhsNorm = 1. _d 0 / rhsMax
137     DO bj=myByLo(myThid),myByHi(myThid)
138     DO bi=myBxLo(myThid),myBxHi(myThid)
139     DO J=1,sNy
140     DO I=1,sNx
141     cg2d_b(I,J,bi,bj) = cg2d_b(I,J,bi,bj)*rhsNorm
142     cg2d_x(I,J,bi,bj) = cg2d_x(I,J,bi,bj)*rhsNorm
143     ENDDO
144     ENDDO
145     ENDDO
146     ENDDO
147     C- end Normalise RHS
148     ENDIF
149    
150     C-- Update overlaps
151     _EXCH_XY_R8( cg2d_b, myThid )
152     _EXCH_XY_R8( cg2d_x, myThid )
153     CcnhDebugStarts
154     C CALL PLOT_FIELD_XYRL( cg2d_b, 'CG2D.1 CG2D_B' , 1, myThid )
155     C suff = 'normalised'
156     C CALL WRITE_FLD_XY_RL ( 'cg2d_b.',suff, cg2d_b, 1, myThid)
157     CcnhDebugEnds
158    
159     C-- Initial residual calculation
160     err = 0. _d 0
161     sumRHS = 0. _d 0
162     DO bj=myByLo(myThid),myByHi(myThid)
163     DO bi=myBxLo(myThid),myBxHi(myThid)
164     sumRHStile = 0. _d 0
165     errTile = 0. _d 0
166     DO J=1,sNy
167     DO I=1,sNx
168 utke 1.3 c ks = ksurfC(I,J,bi,bj)
169 utke 1.1 cg2d_s(I,J,bi,bj) = 0.
170     cg2d_r(I,J,bi,bj) = cg2d_b(I,J,bi,bj) -
171     & (aW2d(I ,J ,bi,bj)*cg2d_x(I-1,J ,bi,bj)
172     & +aW2d(I+1,J ,bi,bj)*cg2d_x(I+1,J ,bi,bj)
173     & +aS2d(I ,J ,bi,bj)*cg2d_x(I ,J-1,bi,bj)
174     & +aS2d(I ,J+1,bi,bj)*cg2d_x(I ,J+1,bi,bj)
175     & -aW2d(I ,J ,bi,bj)*cg2d_x(I ,J ,bi,bj)
176     & -aW2d(I+1,J ,bi,bj)*cg2d_x(I ,J ,bi,bj)
177     & -aS2d(I ,J ,bi,bj)*cg2d_x(I ,J ,bi,bj)
178     & -aS2d(I ,J+1,bi,bj)*cg2d_x(I ,J ,bi,bj)
179     & -freeSurfFac*_rA(i,j,bi,bj)*recip_Bo(i,j,bi,bj)*
180     & cg2d_x(I ,J ,bi,bj)/deltaTMom/deltaTfreesurf*cg2dNorm
181     & )
182     errTile = errTile +
183     & cg2d_r(I,J,bi,bj)*cg2d_r(I,J,bi,bj)
184     sumRHStile = sumRHStile +
185     & cg2d_b(I,J,bi,bj)
186     ENDDO
187     ENDDO
188     sumRHS = sumRHS + sumRHStile
189     err = err + errTile
190     ENDDO
191     ENDDO
192     C _EXCH_XY_R8( cg2d_r, myThid )
193     #ifdef LETS_MAKE_JAM
194     CALL EXCH_XY_O1_R8_JAM( cg2d_r )
195     #else
196     CALL EXCH_XY_RL( cg2d_r, myThid )
197     #endif
198     C _EXCH_XY_R8( cg2d_s, myThid )
199     #ifdef LETS_MAKE_JAM
200     CALL EXCH_XY_O1_R8_JAM( cg2d_s )
201     #else
202     CALL EXCH_XY_RL( cg2d_s, myThid )
203     #endif
204     _GLOBAL_SUM_R8( sumRHS, myThid )
205     _GLOBAL_SUM_R8( err , myThid )
206     err = SQRT(err)
207     actualIts = 0
208     actualResidual = err
209    
210     IF ( debugLevel .GE. debLevZero ) THEN
211     _BEGIN_MASTER( myThid )
212 utke 1.3 WRITE(standardmessageunit,'(A,1P2E22.14)')
213     & ' cg2d: Sum(rhs),rhsMax = ', sumRHS,rhsMax
214 utke 1.1 _END_MASTER( myThid )
215     ENDIF
216     C _BARRIER
217     c _BEGIN_MASTER( myThid )
218 utke 1.3 c WRITE(standardmessageunit,'(A,I6,1PE30.14)')
219     c & ' CG2D iters, err = ',
220 utke 1.1 c & actualIts, actualResidual
221     c _END_MASTER( myThid )
222     firstResidual=actualResidual
223    
224     IF ( err .ge. cg2dTolerance ) then
225    
226     C >>>>>>>>>>>>>>> BEGIN SOLVER <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
227     it2d=1
228    
229 utke 1.2 DO while ((it2d .le. numIters .and. err .ge. cg2dTolerance))
230 utke 1.1
231     CcnhDebugStarts
232     C WRITE(*,*) ' CG2D: Iteration ',it2d-1,' residual = ',
233     C & actualResidual
234     CcnhDebugEnds
235     C-- Solve preconditioning equation and update
236     C-- conjugate direction vector "s".
237     eta_qrN = 0. _d 0
238     DO bj=myByLo(myThid),myByHi(myThid)
239     DO bi=myBxLo(myThid),myBxHi(myThid)
240     eta_qrNtile = 0. _d 0
241     DO J=1,sNy
242     DO I=1,sNx
243 utke 1.3 cg2d_q(I,J,bi,bj) =
244 utke 1.1 & pC(I ,J ,bi,bj)*cg2d_r(I ,J ,bi,bj)
245     & +pW(I ,J ,bi,bj)*cg2d_r(I-1,J ,bi,bj)
246     & +pW(I+1,J ,bi,bj)*cg2d_r(I+1,J ,bi,bj)
247     & +pS(I ,J ,bi,bj)*cg2d_r(I ,J-1,bi,bj)
248     & +pS(I ,J+1,bi,bj)*cg2d_r(I ,J+1,bi,bj)
249     CcnhDebugStarts
250     C cg2d_q(I,J,bi,bj) = cg2d_r(I ,J ,bi,bj)
251     CcnhDebugEnds
252     eta_qrNtile = eta_qrNtile
253     & +cg2d_q(I,J,bi,bj)*cg2d_r(I,J,bi,bj)
254     ENDDO
255     ENDDO
256     eta_qrN = eta_qrN + eta_qrNtile
257     ENDDO
258     ENDDO
259    
260     _GLOBAL_SUM_R8(eta_qrN, myThid)
261     CcnhDebugStarts
262     C WRITE(*,*) ' CG2D: Iteration ',it2d-1,' eta_qrN = ',eta_qrN
263     CcnhDebugEnds
264     cgBeta = eta_qrN/eta_qrNM1
265     CcnhDebugStarts
266     C WRITE(*,*) ' CG2D: Iteration ',it2d-1,' beta = ',cgBeta
267     CcnhDebugEnds
268     eta_qrNM1 = eta_qrN
269    
270     DO bj=myByLo(myThid),myByHi(myThid)
271     DO bi=myBxLo(myThid),myBxHi(myThid)
272     DO J=1,sNy
273     DO I=1,sNx
274     cg2d_s(I,J,bi,bj) = cg2d_q(I,J,bi,bj)
275     & + cgBeta*cg2d_s(I,J,bi,bj)
276     ENDDO
277     ENDDO
278     ENDDO
279     ENDDO
280    
281     C-- Do exchanges that require messages i.e. between
282     C-- processes.
283     C _EXCH_XY_R8( cg2d_s, myThid )
284     #ifdef LETS_MAKE_JAM
285     CALL EXCH_XY_O1_R8_JAM( cg2d_s )
286     #else
287     CALL EXCH_XY_RL( cg2d_s, myThid )
288     #endif
289    
290     C== Evaluate laplace operator on conjugate gradient vector
291     C== q = A.s
292     alpha = 0. _d 0
293     DO bj=myByLo(myThid),myByHi(myThid)
294     DO bi=myBxLo(myThid),myBxHi(myThid)
295     alphaTile = 0. _d 0
296     DO J=1,sNy
297     DO I=1,sNx
298 utke 1.3 c ks = ksurfC(I,J,bi,bj)
299     cg2d_q(I,J,bi,bj) =
300 utke 1.1 & aW2d(I ,J ,bi,bj)*cg2d_s(I-1,J ,bi,bj)
301     & +aW2d(I+1,J ,bi,bj)*cg2d_s(I+1,J ,bi,bj)
302     & +aS2d(I ,J ,bi,bj)*cg2d_s(I ,J-1,bi,bj)
303     & +aS2d(I ,J+1,bi,bj)*cg2d_s(I ,J+1,bi,bj)
304     & -aW2d(I ,J ,bi,bj)*cg2d_s(I ,J ,bi,bj)
305     & -aW2d(I+1,J ,bi,bj)*cg2d_s(I ,J ,bi,bj)
306     & -aS2d(I ,J ,bi,bj)*cg2d_s(I ,J ,bi,bj)
307     & -aS2d(I ,J+1,bi,bj)*cg2d_s(I ,J ,bi,bj)
308     & -freeSurfFac*_rA(i,j,bi,bj)*recip_Bo(i,j,bi,bj)*
309     & cg2d_s(I ,J ,bi,bj)/deltaTMom/deltaTfreesurf*cg2dNorm
310     alphaTile = alphaTile+cg2d_s(I,J,bi,bj)*cg2d_q(I,J,bi,bj)
311     ENDDO
312     ENDDO
313     alpha = alpha + alphaTile
314     ENDDO
315     ENDDO
316     _GLOBAL_SUM_R8(alpha,myThid)
317     CcnhDebugStarts
318     C WRITE(*,*) ' CG2D: Iteration ',it2d-1,' SUM(s*q)= ',alpha
319     CcnhDebugEnds
320     alpha = eta_qrN/alpha
321     CcnhDebugStarts
322     C WRITE(*,*) ' CG2D: Iteration ',it2d-1,' alpha= ',alpha
323     CcnhDebugEnds
324 utke 1.3
325 utke 1.1 C== Update solution and residual vectors
326     C Now compute "interior" points.
327     err = 0. _d 0
328     DO bj=myByLo(myThid),myByHi(myThid)
329     DO bi=myBxLo(myThid),myBxHi(myThid)
330     errTile = 0. _d 0
331     DO J=1,sNy
332     DO I=1,sNx
333     cg2d_x(I,J,bi,bj)=cg2d_x(I,J,bi,bj)+alpha*cg2d_s(I,J,bi,bj)
334     cg2d_r(I,J,bi,bj)=cg2d_r(I,J,bi,bj)-alpha*cg2d_q(I,J,bi,bj)
335     errTile = errTile+cg2d_r(I,J,bi,bj)*cg2d_r(I,J,bi,bj)
336     ENDDO
337     ENDDO
338     err = err + errTile
339     ENDDO
340     ENDDO
341    
342     _GLOBAL_SUM_R8( err , myThid )
343     err = SQRT(err)
344     actualIts = it2d
345     actualResidual = err
346     C _EXCH_XY_R8(cg2d_r, myThid )
347     #ifdef LETS_MAKE_JAM
348     CALL EXCH_XY_O1_R8_JAM( cg2d_r )
349     #else
350     CALL EXCH_XY_RL( cg2d_r, myThid )
351     #endif
352 utke 1.2 it2d=it2d+1
353 utke 1.1
354     end do
355     end if
356    
357     IF (cg2dNormaliseRHS) THEN
358     C-- Un-normalise the answer
359     DO bj=myByLo(myThid),myByHi(myThid)
360     DO bi=myBxLo(myThid),myBxHi(myThid)
361     DO J=1,sNy
362     DO I=1,sNx
363     cg2d_x(I ,J ,bi,bj) = cg2d_x(I ,J ,bi,bj)/rhsNorm
364     ENDDO
365     ENDDO
366     ENDDO
367     ENDDO
368     ENDIF
369    
370     C The following exchange was moved up to solve_for_pressure
371     C for compatibility with TAMC.
372     C _EXCH_XY_R8(cg2d_x, myThid )
373     c _BEGIN_MASTER( myThid )
374 utke 1.3 c WRITE(*,'(A,I6,1PE30.14)') ' CG2D iters, err = ',
375 utke 1.1 c & actualIts, actualResidual
376     c _END_MASTER( myThid )
377    
378     C-- Return parameters to caller
379     lastResidual=actualResidual
380     numIters=actualIts
381    
382     CcnhDebugStarts
383     C CALL PLOT_FIELD_XYRL( cg2d_x, 'CALC_MOM_RHS CG2D_X' , 1, myThid )
384     C err = 0. _d 0
385     C DO bj=myByLo(myThid),myByHi(myThid)
386     C DO bi=myBxLo(myThid),myBxHi(myThid)
387     C DO J=1,sNy
388     C DO I=1,sNx
389     C cg2d_r(I,J,bi,bj) = cg2d_b(I,J,bi,bj) -
390     C & (aW2d(I ,J ,bi,bj)*cg2d_x(I-1,J ,bi,bj)
391     C & +aW2d(I+1,J ,bi,bj)*cg2d_x(I+1,J ,bi,bj)
392     C & +aS2d(I ,J ,bi,bj)*cg2d_x(I ,J-1,bi,bj)
393     C & +aS2d(I ,J+1,bi,bj)*cg2d_x(I ,J+1,bi,bj)
394     C & -aW2d(I ,J ,bi,bj)*cg2d_x(I ,J ,bi,bj)
395     C & -aW2d(I+1,J ,bi,bj)*cg2d_x(I ,J ,bi,bj)
396     C & -aS2d(I ,J ,bi,bj)*cg2d_x(I ,J ,bi,bj)
397     C & -aS2d(I ,J+1,bi,bj)*cg2d_x(I ,J ,bi,bj))
398 utke 1.3 C err = err +
399 utke 1.1 C & cg2d_r(I,J,bi,bj)*cg2d_r(I,J,bi,bj)
400     C ENDDO
401     C ENDDO
402     C ENDDO
403     C ENDDO
404     C _GLOBAL_SUM_R8( err , myThid )
405     C write(*,*) 'cg2d: Ax - b = ',SQRT(err)
406     CcnhDebugEnds
407    
408     RETURN
409     END

  ViewVC Help
Powered by ViewVC 1.1.22