/[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.5 - (show annotations) (download)
Wed Jul 6 01:47:57 2011 UTC (12 years, 10 months ago) by jmc
Branch: MAIN
CVS Tags: checkpoint63
Changes since 1.4: +4 -14 lines
fix test rshMax > 0 for rshNorm ;
implement selection of grid-point location where PsiVEL == 0

1 C $Header: /u/gcmpack/MITgcm/pkg/diagnostics/diagnostics_calc_phivel.F,v 1.4 2011/07/01 18:50:00 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
71 LOGICAL normaliseMatrice, diagNormaliseRHS
72 _RL residCriter, firstResidual, 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 & *maskInW(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 & *maskInS(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 = cg2dTargetResWunit.LE.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 = cg2dTargetResidual
155 ELSE
156 residCriter = a2dNorm * cg2dTargetResWunit
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 = cg2dMaxIters
183 CALL DIAG_CG2D(
184 I aW2d, aS2d, b2d,
185 I residCriter,
186 O firstResidual, lastResidual,
187 U x2d, numIters,
188 I myThid )
189
190 IF ( debugLevel.GE.debLevA ) THEN
191 _BEGIN_MASTER( myThid )
192 WRITE(standardMessageUnit,'(A,I4,A,I6,A,1P2E17.9)')
193 & ' diag_cg2d : k=', k, ' , iters=', numIters,
194 & ' ; ini,last_Res=', firstResidual, lastResidual
195 _END_MASTER( myThid )
196 ENDIF
197
198 _EXCH_XY_RL( x2d, myThid )
199
200 C- Un-normalise the answer
201 IF (diagNormaliseRHS) THEN
202 DO bj = myByLo(myThid), myByHi(myThid)
203 DO bi = myBxLo(myThid), myBxHi(myThid)
204 DO j = 1-Oly,sNy+Oly
205 DO i = 1-Olx,sNx+Olx
206 x2d(i,j,bi,bj) = x2d(i,j,bi,bj) /rhsNorm
207 ENDDO
208 ENDDO
209 ENDDO
210 ENDDO
211 ENDIF
212
213 C- Compte divergence-free transport:
214 DO bj = myByLo(myThid), myByHi(myThid)
215 DO bi = myBxLo(myThid), myBxHi(myThid)
216 DO j = 1,sNy+1
217 DO i = 1,sNx+1
218 uTrans(i,j,bi,bj) = uTrans(i,j,bi,bj)
219 & - ( x2d(i,j,bi,bj) - x2d(i-1,j,bi,bj) )
220 & *recip_dxC(i,j,bi,bj)*dyG(i,j,bi,bj)
221 & *drF(k)*hFacW(i,j,k,bi,bj)
222 & *maskInW(i,j,bi,bj)
223 vTrans(i,j,bi,bj) = vTrans(i,j,bi,bj)
224 & - ( x2d(i,j,bi,bj) - x2d(i,j-1,bi,bj) )
225 & *recip_dyC(i,j,bi,bj)*dxG(i,j,bi,bj)
226 & *drF(k)*hFacS(i,j,k,bi,bj)
227 & *maskInS(i,j,bi,bj)
228 ENDDO
229 ENDDO
230 ENDDO
231 ENDDO
232 CALL DIAG_CALC_PSIVEL(
233 I k, iPsi0, jPsi0, uTrans, vTrans,
234 O psiVel, psiLoc,
235 I myTime, myIter, myThid )
236
237 IF ( useCubedSphereExchange .AND.
238 & diag_mdsio .AND. myProcId.EQ.0 ) THEN
239 C- Missing-corner value are not written in MDS output file
240 C Write separately these 2 values (should be part of DIAGNOSTICS_OUT)
241 _BEGIN_MASTER( myThid)
242 IF ( diagLoc_ioUnit.EQ.0 ) THEN
243 CALL MDSFINDUNIT( diagLoc_ioUnit, myThid )
244 WRITE(dataFName,'(2A,I10.10,A)')
245 & 'diags_CScorners', '.', nIter0, '.txt'
246 OPEN( diagLoc_ioUnit, FILE=dataFName, STATUS='unknown' )
247 iL = ILNBLNK(dataFName)
248 WRITE(msgBuf,'(2A,I6,2A)') 'DIAGNOSTICS_CALC_PHIVEL: ',
249 & 'open unit=',diagLoc_ioUnit, ', file: ',dataFName(1:iL)
250 CALL PRINT_MESSAGE( msgBuf, standardMessageUnit,
251 & SQUEEZE_RIGHT, myThid )
252 ENDIF
253 IF ( diagLoc_ioUnit.GT.0 ) THEN
254 WRITE(diagLoc_ioUnit,'(1P2E18.10,A,2I4,I8,A,2I4,I6,2A)')
255 & psiLoc, ' #', k, lm, myIter,
256 & ' :',listId, md, ndId, ' ', cdiag(ndId)
257 C- check accuracy (f1.SW-corner = f6.NW-corner = f5-NE-corner)
258 c WRITE(0,'(1P2E18.10,A,2I4,I8)')
259 c & psiVel(1,1+sNy,nSx,nSy)- psiVel(1,1,1,1),
260 c & psiVel(1+sNx,1+sNy,nSx-1,nSy)-psiVel(1,1,1,1),
261 c & ' #', k, lm, myIter
262 ENDIF
263 _END_MASTER( myThid)
264 ENDIF
265
266 C- Put the results back in qtmp[1,2]
267 DO bj = myByLo(myThid), myByHi(myThid)
268 DO bi = myBxLo(myThid), myBxHi(myThid)
269 DO j = 1,sNy+1
270 DO i = 1,sNx+1
271 qtmp1(i,j,ks,bi,bj) = x2d(i,j,bi,bj)
272 qtmp2(i,j,ks,bi,bj) = psiVel(i,j,bi,bj)
273 ENDDO
274 ENDDO
275 ENDDO
276 ENDDO
277
278 ENDDO
279
280 RETURN
281 END

  ViewVC Help
Powered by ViewVC 1.1.22