/[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.4 - (show annotations) (download)
Fri Jul 1 18:50:00 2011 UTC (13 years, 2 months ago) by jmc
Branch: MAIN
Changes since 1.3: +108 -22 lines
add S/R to compute velocity stream-function (called after velocity-potential
 calculation) from divergence free transport.

1 C $Header: /u/gcmpack/MITgcm/pkg/diagnostics/diagnostics_calc_phivel.F,v 1.3 2011/06/24 22:15:48 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 c#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 C i,jPsi0 :: indices of grid-point location where Psi == 0
67 INTEGER bi, bj
68 INTEGER i, j, k
69
70 INTEGER ks
71 INTEGER numIters
72 LOGICAL normaliseMatrice, diagNormaliseRHS
73 _RL residCriter, firstResidual, lastResidual
74 _RL a2dMax, a2dNorm
75 _RL rhsMax, rhsNorm
76 _RS aW2d(1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy)
77 _RS aS2d(1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy)
78 _RL b2d (1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy)
79 _RL x2d (1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy)
80 _RL uTrans(1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy)
81 _RL vTrans(1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy)
82 _RL psiVel(1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy)
83 _RL psiLoc(2)
84 INTEGER iPsi0(nSx,nSy)
85 INTEGER jPsi0(nSx,nSy)
86 INTEGER iL
87 CHARACTER*(MAX_LEN_FNAM) dataFName
88 CHARACTER*(MAX_LEN_MBUF) msgBuf
89
90 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
91
92 DO bj=myByLo(myThid),myByHi(myThid)
93 DO bi=myBxLo(myThid),myBxHi(myThid)
94 iPsi0(bi,bj) = -1
95 jPsi0(bi,bj) = 0
96 ENDDO
97 ENDDO
98
99 DO ks = 1,kdiag(ndId)
100 k = NINT(levs(ks,listId))
101 C-- Solve for velocity potential for each level:
102
103 a2dMax = 0. _d 0
104 rhsMax = 0. _d 0
105 DO bj = myByLo(myThid), myByHi(myThid)
106 DO bi = myBxLo(myThid), myBxHi(myThid)
107 C- Initialise fist guess & RHS
108 DO j = 1-Oly,sNy+Oly
109 DO i = 1-Olx,sNx+Olx
110 b2d(i,j,bi,bj) = 0.
111 x2d(i,j,bi,bj) = 0.
112 ENDDO
113 ENDDO
114 C- calculate cg2d matrix:
115 DO j = 1,sNy+1
116 DO i = 1,sNx+1
117 aW2d(i,j,bi,bj) = dyG(i,j,bi,bj)*recip_dxC(i,j,bi,bj)
118 & *drF(k)*hFacW(i,j,k,bi,bj)
119 & *maskInW(i,j,bi,bj)
120 aS2d(i,j,bi,bj) = dxG(i,j,bi,bj)*recip_dyC(i,j,bi,bj)
121 & *drF(k)*hFacS(i,j,k,bi,bj)
122 & *maskInS(i,j,bi,bj)
123 a2dMax = MAX(a2dMax,aW2d(i,j,bi,bj))
124 a2dMax = MAX(a2dMax,aS2d(i,j,bi,bj))
125 ENDDO
126 ENDDO
127
128 C- calculate RHS = Div(uVel,vVel):
129 DO j = 1,sNy+1
130 DO i = 1,sNx+1
131 uTrans(i,j,bi,bj) = dyG(i,j,bi,bj)*drF(k)
132 & *qtmp1(i,j,ks,bi,bj)*maskInW(i,j,bi,bj)
133 vTrans(i,j,bi,bj) = dxG(i,j,bi,bj)*drF(k)
134 & *qtmp2(i,j,ks,bi,bj)*maskInS(i,j,bi,bj)
135 ENDDO
136 ENDDO
137 DO j = 1,sNy
138 DO i = 1,sNx
139 b2d(i,j,bi,bj) = (
140 & ( uTrans(i+1,j,bi,bj) - uTrans(i,j,bi,bj) )
141 & + ( vTrans(i,j+1,bi,bj) - vTrans(i,j,bi,bj) )
142 & )*maskInC(i,j,bi,bj)
143 rhsMax = MAX(ABS(b2d(I,J,bi,bj)),rhsMax)
144 ENDDO
145 ENDDO
146
147 C- end bi,bj loops
148 ENDDO
149 ENDDO
150
151 C- Normalise Matrice & RHS :
152 diagNormaliseRHS = cg2dTargetResWunit.LE.0.
153 normaliseMatrice = .TRUE.
154 diagNormaliseRHS = .TRUE.
155 a2dNorm = 1. _d 0
156 rhsNorm = 1. _d 0
157 IF ( normaliseMatrice ) THEN
158 _GLOBAL_MAX_RL( a2dMax, myThid )
159 IF ( a2dMax .GE. 0. _d 0 ) a2dNorm = 1. _d 0/a2dMax
160 ENDIF
161 IF ( diagNormaliseRHS ) THEN
162 _GLOBAL_MAX_RL( rhsMax, myThid )
163 IF ( rhsMax .GE. 0. _d 0 ) rhsNorm = 1. _d 0/(a2dNorm*rhsMax)
164 residCriter = cg2dTargetResidual
165 ELSE
166 residCriter = a2dNorm * cg2dTargetResWunit
167 & * globalArea / deltaTmom
168 ENDIF
169 IF ( normaliseMatrice .OR. diagNormaliseRHS ) THEN
170 DO bj = myByLo(myThid), myByHi(myThid)
171 DO bi = myBxLo(myThid), myBxHi(myThid)
172 DO j = 1,sNy+1
173 DO i = 1,sNx+1
174 aW2d(i,j,bi,bj) = aW2d(i,j,bi,bj)*a2dNorm
175 aS2d(i,j,bi,bj) = aS2d(i,j,bi,bj)*a2dNorm
176 b2d(i,j,bi,bj) = b2d(i,j,bi,bj) *a2dNorm*rhsNorm
177 c x2d(i,j,bi,bj) = x2d(i,j,bi,bj) *rhsNorm
178 ENDDO
179 ENDDO
180 ENDDO
181 ENDDO
182 ENDIF
183
184 IF ( debugLevel.GE.debLevA .AND. k.EQ.1 ) THEN
185 _BEGIN_MASTER( myThid )
186 WRITE(standardMessageUnit,'(A,I9,2(A,1P1E13.6),A,1P1E9.2)')
187 & ' diag_cg2d (it=', myIter,') a2dNorm,rhsNorm=', a2dNorm,
188 & ' ,', rhsNorm, ' ; Criter=', residCriter
189 _END_MASTER( myThid )
190 ENDIF
191
192 numIters = cg2dMaxIters
193 CALL DIAG_CG2D(
194 I aW2d, aS2d, b2d,
195 I residCriter,
196 O firstResidual, lastResidual,
197 U x2d, numIters,
198 I myThid )
199
200 IF ( debugLevel.GE.debLevA ) THEN
201 _BEGIN_MASTER( myThid )
202 WRITE(standardMessageUnit,'(A,I4,A,I6,A,1P2E17.9)')
203 & ' diag_cg2d : k=', k, ' , iters=', numIters,
204 & ' ; ini,last_Res=', firstResidual, lastResidual
205 _END_MASTER( myThid )
206 ENDIF
207
208 _EXCH_XY_RL( x2d, myThid )
209
210 C- Un-normalise the answer
211 IF (diagNormaliseRHS) THEN
212 DO bj = myByLo(myThid), myByHi(myThid)
213 DO bi = myBxLo(myThid), myBxHi(myThid)
214 DO j = 1-Oly,sNy+Oly
215 DO i = 1-Olx,sNx+Olx
216 x2d(i,j,bi,bj) = x2d(i,j,bi,bj) /rhsNorm
217 ENDDO
218 ENDDO
219 ENDDO
220 ENDDO
221 ENDIF
222
223 C- Compte divergence-free transport:
224 DO bj = myByLo(myThid), myByHi(myThid)
225 DO bi = myBxLo(myThid), myBxHi(myThid)
226 DO j = 1,sNy+1
227 DO i = 1,sNx+1
228 uTrans(i,j,bi,bj) = uTrans(i,j,bi,bj)
229 & - ( x2d(i,j,bi,bj) - x2d(i-1,j,bi,bj) )
230 & *recip_dxC(i,j,bi,bj)*dyG(i,j,bi,bj)
231 & *drF(k)*hFacW(i,j,k,bi,bj)
232 & *maskInW(i,j,bi,bj)
233 vTrans(i,j,bi,bj) = vTrans(i,j,bi,bj)
234 & - ( x2d(i,j,bi,bj) - x2d(i,j-1,bi,bj) )
235 & *recip_dyC(i,j,bi,bj)*dxG(i,j,bi,bj)
236 & *drF(k)*hFacS(i,j,k,bi,bj)
237 & *maskInS(i,j,bi,bj)
238 ENDDO
239 ENDDO
240 ENDDO
241 ENDDO
242 CALL DIAG_CALC_PSIVEL(
243 I k, iPsi0, jPsi0, uTrans, vTrans,
244 O psiVel, psiLoc,
245 I myTime, myIter, myThid )
246
247 IF ( useCubedSphereExchange .AND.
248 & diag_mdsio .AND. myProcId.EQ.0 ) THEN
249 C- Missing-corner value are not written in MDS output file
250 C Write separately these 2 values (should be part of DIAGNOSTICS_OUT)
251 _BEGIN_MASTER( myThid)
252 IF ( diagLoc_ioUnit.EQ.0 ) THEN
253 CALL MDSFINDUNIT( diagLoc_ioUnit, myThid )
254 WRITE(dataFName,'(2A,I10.10,A)')
255 & 'diags_CScorners', '.', nIter0, '.txt'
256 OPEN( diagLoc_ioUnit, FILE=dataFName, STATUS='unknown' )
257 iL = ILNBLNK(dataFName)
258 WRITE(msgBuf,'(2A,I6,2A)') 'DIAGNOSTICS_CALC_PHIVEL: ',
259 & 'open unit=',diagLoc_ioUnit, ', file: ',dataFName(1:iL)
260 CALL PRINT_MESSAGE( msgBuf, standardMessageUnit,
261 & SQUEEZE_RIGHT, myThid )
262 ENDIF
263 IF ( diagLoc_ioUnit.GT.0 ) THEN
264 WRITE(diagLoc_ioUnit,'(1P2E18.10,A,2I4,I8,A,2I4,I6,2A)')
265 & psiLoc, ' #', k, lm, myIter,
266 & ' :',listId, md, ndId, ' ', cdiag(ndId)
267 C- check accuracy (f1.SW-corner = f6.NW-corner = f5-NE-corner)
268 c WRITE(0,'(1P2E18.10,A,2I4,I8)')
269 c & psiVel(1,1+sNy,nSx,nSy)- psiVel(1,1,1,1),
270 c & psiVel(1+sNx,1+sNy,nSx-1,nSy)-psiVel(1,1,1,1),
271 c & ' #', k, lm, myIter
272 ENDIF
273 _END_MASTER( myThid)
274 ENDIF
275
276 C- Put the results back in qtmp[1,2]
277 DO bj = myByLo(myThid), myByHi(myThid)
278 DO bi = myBxLo(myThid), myBxHi(myThid)
279 DO j = 1,sNy+1
280 DO i = 1,sNx+1
281 qtmp1(i,j,ks,bi,bj) = x2d(i,j,bi,bj)
282 qtmp2(i,j,ks,bi,bj) = psiVel(i,j,bi,bj)
283 ENDDO
284 ENDDO
285 ENDDO
286 ENDDO
287
288 ENDDO
289
290 RETURN
291 END

  ViewVC Help
Powered by ViewVC 1.1.22