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

Contents of /MITgcm/pkg/diagnostics/diagnostics_calc_phivel.F

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


Revision 1.6 - (show annotations) (download)
Fri Jul 22 19:53:40 2011 UTC (12 years, 10 months ago) by jmc
Branch: MAIN
Changes since 1.5: +17 -16 lines
- fix mask for OBCS (still problems in stream-function with OBCS);
- add specific parameter (default = main code CG2D params) for solver;
- in case of poor convergence, use solution corresponding to lowest residual.

1 C $Header: /u/gcmpack/MITgcm/pkg/diagnostics/diagnostics_calc_phivel.F,v 1.5 2011/07/06 01:47:57 jmc Exp $
2 C $Name: $
3
4 #include "DIAG_OPTIONS.h"
5
6 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
7 CBOP 0
8 C !ROUTINE: DIAGNOSTICS_CALC_PHIVEL
9
10 C !INTERFACE:
11 SUBROUTINE DIAGNOSTICS_CALC_PHIVEL(
12 I listId, md, ndId, ip, im, lm,
13 I NrMax,
14 U qtmp1, qtmp2,
15 I myTime, myIter, myThid )
16
17 C !DESCRIPTION:
18 C Compute Velocity Potential and Velocity Stream-Function
19
20 C !USES:
21 IMPLICIT NONE
22 #include "SIZE.h"
23 #include "EEPARAMS.h"
24 #include "PARAMS.h"
25 #include "GRID.h"
26 #include "DIAGNOSTICS_SIZE.h"
27 #include "DIAGNOSTICS.h"
28 #include "DIAGNOSTICS_CALC.h"
29
30 C !INPUT PARAMETERS:
31 C listId :: Diagnostics list number being written
32 C md :: field number in the list "listId".
33 C ndId :: diagnostics Id number (in available diagnostics list)
34 C ip :: diagnostics pointer to storage array
35 C im :: counter-mate pointer to storage array
36 C lm :: index in the averageCycle
37 C NrMax :: 3rd dimension of input/output arrays
38 C qtmp1 :: horizontal velocity input diag., u-component
39 C qtmp2 :: horizontal velocity input diag., v-component
40 C myTime :: current time of simulation (s)
41 C myIter :: current iteration number
42 C myThid :: my Thread Id number
43 INTEGER listId, md, ndId, ip, im, lm
44 INTEGER NrMax
45 _RL qtmp1(1-OLx:sNx+OLx,1-OLy:sNy+OLy,NrMax,nSx,nSy)
46 _RL qtmp2(1-OLx:sNx+OLx,1-OLy:sNy+OLy,NrMax,nSx,nSy)
47 _RL myTime
48 INTEGER myIter, myThid
49
50 C !OUTPUT PARAMETERS:
51 C qtmp1 :: horizontal-velocity potential
52 C qtmp2 :: horizontal-velocity stream-function
53 CEOP
54
55 C !FUNCTIONS:
56 INTEGER ILNBLNK
57 EXTERNAL ILNBLNK
58
59 C !LOCAL VARIABLES:
60 C bi, bj :: tile indices
61 C i,j,k :: loop indices
62 C uTrans :: horizontal transport, u-component
63 C vTrans :: horizontal transport, u-component
64 C psiVel :: horizontal stream-function
65 C psiLoc :: horizontal stream-function at special location
66 INTEGER bi, bj
67 INTEGER i, j, k
68
69 INTEGER ks
70 INTEGER numIters, nIterMin
71 LOGICAL normaliseMatrice, diagNormaliseRHS
72 _RL residCriter, firstResidual, minResidual, lastResidual
73 _RL a2dMax, a2dNorm
74 _RL rhsMax, rhsNorm
75 _RS aW2d(1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy)
76 _RS aS2d(1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy)
77 _RL b2d (1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy)
78 _RL x2d (1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy)
79 _RL uTrans(1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy)
80 _RL vTrans(1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy)
81 _RL psiVel(1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy)
82 _RL psiLoc(2)
83 INTEGER iL
84 CHARACTER*(MAX_LEN_FNAM) dataFName
85 CHARACTER*(MAX_LEN_MBUF) msgBuf
86
87 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
88
89 DO ks = 1,kdiag(ndId)
90 k = NINT(levs(ks,listId))
91 C-- Solve for velocity potential for each level:
92
93 a2dMax = 0. _d 0
94 rhsMax = 0. _d 0
95 DO bj = myByLo(myThid), myByHi(myThid)
96 DO bi = myBxLo(myThid), myBxHi(myThid)
97 C- Initialise fist guess & RHS
98 DO j = 1-Oly,sNy+Oly
99 DO i = 1-Olx,sNx+Olx
100 b2d(i,j,bi,bj) = 0.
101 x2d(i,j,bi,bj) = 0.
102 ENDDO
103 ENDDO
104 C- calculate cg2d matrix:
105 DO j = 1,sNy+1
106 DO i = 1,sNx+1
107 aW2d(i,j,bi,bj) = dyG(i,j,bi,bj)*recip_dxC(i,j,bi,bj)
108 & *drF(k)*hFacW(i,j,k,bi,bj)
109 & *maskInC(i-1,j,bi,bj)*maskInC(i,j,bi,bj)
110 aS2d(i,j,bi,bj) = dxG(i,j,bi,bj)*recip_dyC(i,j,bi,bj)
111 & *drF(k)*hFacS(i,j,k,bi,bj)
112 & *maskInC(i,j-1,bi,bj)*maskInC(i,j,bi,bj)
113 a2dMax = MAX(a2dMax,aW2d(i,j,bi,bj))
114 a2dMax = MAX(a2dMax,aS2d(i,j,bi,bj))
115 ENDDO
116 ENDDO
117
118 C- calculate RHS = Div(uVel,vVel):
119 DO j = 1,sNy+1
120 DO i = 1,sNx+1
121 uTrans(i,j,bi,bj) = dyG(i,j,bi,bj)*drF(k)
122 & *qtmp1(i,j,ks,bi,bj)*maskInW(i,j,bi,bj)
123 vTrans(i,j,bi,bj) = dxG(i,j,bi,bj)*drF(k)
124 & *qtmp2(i,j,ks,bi,bj)*maskInS(i,j,bi,bj)
125 ENDDO
126 ENDDO
127 DO j = 1,sNy
128 DO i = 1,sNx
129 b2d(i,j,bi,bj) = (
130 & ( uTrans(i+1,j,bi,bj) - uTrans(i,j,bi,bj) )
131 & + ( vTrans(i,j+1,bi,bj) - vTrans(i,j,bi,bj) )
132 & )*maskInC(i,j,bi,bj)
133 rhsMax = MAX(ABS(b2d(I,J,bi,bj)),rhsMax)
134 ENDDO
135 ENDDO
136
137 C- end bi,bj loops
138 ENDDO
139 ENDDO
140
141 C- Normalise Matrice & RHS :
142 diagNormaliseRHS = diagCG_resTarget.GT.0.
143 normaliseMatrice = .TRUE.
144 diagNormaliseRHS = .TRUE.
145 a2dNorm = 1. _d 0
146 rhsNorm = 1. _d 0
147 IF ( normaliseMatrice ) THEN
148 _GLOBAL_MAX_RL( a2dMax, myThid )
149 IF ( a2dMax .GT. 0. _d 0 ) a2dNorm = 1. _d 0/a2dMax
150 ENDIF
151 IF ( diagNormaliseRHS ) THEN
152 _GLOBAL_MAX_RL( rhsMax, myThid )
153 IF ( rhsMax .GT. 0. _d 0 ) rhsNorm = 1. _d 0/(a2dNorm*rhsMax)
154 residCriter = diagCG_resTarget
155 ELSE
156 residCriter = a2dNorm * ABS(diagCG_resTarget)
157 & * globalArea / deltaTmom
158 ENDIF
159 IF ( normaliseMatrice .OR. diagNormaliseRHS ) THEN
160 DO bj = myByLo(myThid), myByHi(myThid)
161 DO bi = myBxLo(myThid), myBxHi(myThid)
162 DO j = 1,sNy+1
163 DO i = 1,sNx+1
164 aW2d(i,j,bi,bj) = aW2d(i,j,bi,bj)*a2dNorm
165 aS2d(i,j,bi,bj) = aS2d(i,j,bi,bj)*a2dNorm
166 b2d(i,j,bi,bj) = b2d(i,j,bi,bj) *a2dNorm*rhsNorm
167 c x2d(i,j,bi,bj) = x2d(i,j,bi,bj) *rhsNorm
168 ENDDO
169 ENDDO
170 ENDDO
171 ENDDO
172 ENDIF
173
174 IF ( debugLevel.GE.debLevA .AND. k.EQ.1 ) THEN
175 _BEGIN_MASTER( myThid )
176 WRITE(standardMessageUnit,'(A,I9,2(A,1P1E13.6),A,1P1E9.2)')
177 & ' diag_cg2d (it=', myIter,') a2dNorm,rhsNorm=', a2dNorm,
178 & ' ,', rhsNorm, ' ; Criter=', residCriter
179 _END_MASTER( myThid )
180 ENDIF
181
182 numIters = diagCG_maxIters
183 CALL DIAG_CG2D(
184 I aW2d, aS2d, b2d,
185 I residCriter,
186 O firstResidual, minResidual, lastResidual,
187 U x2d, numIters,
188 O nIterMin,
189 I diagCG_prtResFrq, myThid )
190
191 IF ( debugLevel.GE.debLevA ) THEN
192 _BEGIN_MASTER( myThid )
193 WRITE(standardMessageUnit,'(A,I4,A,2I6,A,1P3E14.7)')
194 & ' diag_cg2d : k=', k, ' , it=', nIterMin, numIters,
195 & ' ; ini,min,last_Res=',firstResidual,minResidual,lastResidual
196 _END_MASTER( myThid )
197 ENDIF
198
199 _EXCH_XY_RL( x2d, myThid )
200
201 C- Un-normalise the answer
202 IF (diagNormaliseRHS) THEN
203 DO bj = myByLo(myThid), myByHi(myThid)
204 DO bi = myBxLo(myThid), myBxHi(myThid)
205 DO j = 1-Oly,sNy+Oly
206 DO i = 1-Olx,sNx+Olx
207 x2d(i,j,bi,bj) = x2d(i,j,bi,bj) /rhsNorm
208 ENDDO
209 ENDDO
210 ENDDO
211 ENDDO
212 ENDIF
213
214 C- Compte divergence-free transport:
215 DO bj = myByLo(myThid), myByHi(myThid)
216 DO bi = myBxLo(myThid), myBxHi(myThid)
217 DO j = 1,sNy+1
218 DO i = 1,sNx+1
219 uTrans(i,j,bi,bj) = uTrans(i,j,bi,bj)
220 & - ( x2d(i,j,bi,bj) - x2d(i-1,j,bi,bj) )
221 & *recip_dxC(i,j,bi,bj)*dyG(i,j,bi,bj)
222 & *drF(k)*hFacW(i,j,k,bi,bj)
223 & *maskInC(i-1,j,bi,bj)*maskInC(i,j,bi,bj)
224 vTrans(i,j,bi,bj) = vTrans(i,j,bi,bj)
225 & - ( x2d(i,j,bi,bj) - x2d(i,j-1,bi,bj) )
226 & *recip_dyC(i,j,bi,bj)*dxG(i,j,bi,bj)
227 & *drF(k)*hFacS(i,j,k,bi,bj)
228 & *maskInC(i,j-1,bi,bj)*maskInC(i,j,bi,bj)
229 ENDDO
230 ENDDO
231 ENDDO
232 ENDDO
233 CALL DIAG_CALC_PSIVEL(
234 I k, iPsi0, jPsi0, uTrans, vTrans,
235 O psiVel, psiLoc,
236 I myTime, myIter, myThid )
237
238 IF ( useCubedSphereExchange .AND.
239 & diag_mdsio .AND. myProcId.EQ.0 ) THEN
240 C- Missing-corner value are not written in MDS output file
241 C Write separately these 2 values (should be part of DIAGNOSTICS_OUT)
242 _BEGIN_MASTER( myThid)
243 IF ( diagLoc_ioUnit.EQ.0 ) THEN
244 CALL MDSFINDUNIT( diagLoc_ioUnit, myThid )
245 WRITE(dataFName,'(2A,I10.10,A)')
246 & 'diags_CScorners', '.', nIter0, '.txt'
247 OPEN( diagLoc_ioUnit, FILE=dataFName, STATUS='unknown' )
248 iL = ILNBLNK(dataFName)
249 WRITE(msgBuf,'(2A,I6,2A)') 'DIAGNOSTICS_CALC_PHIVEL: ',
250 & 'open unit=',diagLoc_ioUnit, ', file: ',dataFName(1:iL)
251 CALL PRINT_MESSAGE( msgBuf, standardMessageUnit,
252 & SQUEEZE_RIGHT, myThid )
253 ENDIF
254 IF ( diagLoc_ioUnit.GT.0 ) THEN
255 WRITE(diagLoc_ioUnit,'(1P2E18.10,A,2I4,I8,A,2I4,I6,2A)')
256 & psiLoc, ' #', k, lm, myIter,
257 & ' :',listId, md, ndId, ' ', cdiag(ndId)
258 C- check accuracy (f1.SW-corner = f6.NW-corner = f5-NE-corner)
259 c WRITE(0,'(1P2E18.10,A,2I4,I8)')
260 c & psiVel(1,1+sNy,nSx,nSy)- psiVel(1,1,1,1),
261 c & psiVel(1+sNx,1+sNy,nSx-1,nSy)-psiVel(1,1,1,1),
262 c & ' #', k, lm, myIter
263 ENDIF
264 _END_MASTER( myThid)
265 ENDIF
266
267 C- Put the results back in qtmp[1,2]
268 DO bj = myByLo(myThid), myByHi(myThid)
269 DO bi = myBxLo(myThid), myBxHi(myThid)
270 DO j = 1,sNy+1
271 DO i = 1,sNx+1
272 qtmp1(i,j,ks,bi,bj) = x2d(i,j,bi,bj)
273 qtmp2(i,j,ks,bi,bj) = psiVel(i,j,bi,bj)
274 ENDDO
275 ENDDO
276 ENDDO
277 ENDDO
278
279 ENDDO
280
281 RETURN
282 END

  ViewVC Help
Powered by ViewVC 1.1.22