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

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

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


Revision 1.26 - (show annotations) (download)
Sat Aug 16 17:28:29 2008 UTC (15 years, 8 months ago) by jmc
Branch: MAIN
CVS Tags: checkpoint61d, checkpoint61e, checkpoint61c
Changes since 1.25: +158 -105 lines
add short function to hide big common blocs "DIAGNOSTICS.h"

1 C $Header: /u/gcmpack/MITgcm/pkg/diagnostics/diagnostics_utils.F,v 1.25 2008/02/05 15:31:19 jmc Exp $
2 C $Name: $
3
4 #include "DIAG_OPTIONS.h"
5
6 C-- File diagnostics_utils.F: General purpose support routines
7 C-- Contents:
8 C-- o GETDIAG
9 C-- o DIAGNOSTICS_COUNT
10 C-- o DIAGNOSTICS_GET_POINTERS
11 C-- o DIAGS_GET_PARMS_I (Function)
12 C-- o DIAGS_MK_UNITS (Function)
13 C-- o DIAGS_MK_TITLE (Function)
14
15 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
16 CBOP 0
17 C !ROUTINE: GETDIAG
18
19 C !INTERFACE:
20 SUBROUTINE GETDIAG(
21 I levreal, undef,
22 O qtmp,
23 I ndId, mate, ip, im, bi, bj, myThid )
24
25 C !DESCRIPTION:
26 C Retrieve averaged model diagnostic
27
28 C !USES:
29 IMPLICIT NONE
30 #include "EEPARAMS.h"
31 #include "SIZE.h"
32 #include "DIAGNOSTICS_SIZE.h"
33 #include "DIAGNOSTICS.h"
34
35 C !INPUT PARAMETERS:
36 C levreal :: Diagnostic LEVEL
37 C undef :: UNDEFINED VALUE
38 C ndId :: DIAGNOSTIC NUMBER FROM MENU
39 C mate :: counter DIAGNOSTIC NUMBER if any ; 0 otherwise
40 C ip :: pointer to storage array location for diag.
41 C im :: pointer to storage array location for mate
42 C bi :: X-direction tile number
43 C bj :: Y-direction tile number
44 C myThid :: my thread Id number
45 _RL levreal
46 _RL undef
47 INTEGER ndId, mate, ip, im
48 INTEGER bi,bj, myThid
49
50 C !OUTPUT PARAMETERS:
51 C qtmp ..... AVERAGED DIAGNOSTIC QUANTITY
52 _RL qtmp(1-OLx:sNx+OLx,1-OLy:sNy+OLy)
53 CEOP
54
55 C !LOCAL VARIABLES:
56 _RL factor
57 INTEGER i, j, ipnt,ipCt
58 INTEGER lev, levCt, klev
59
60 IF (ndId.GE.1) THEN
61 lev = NINT(levreal)
62 klev = kdiag(ndId)
63 IF (lev.LE.klev) THEN
64
65 IF ( mate.EQ.0 ) THEN
66 C- No counter diagnostics => average = Sum / ndiag :
67
68 ipnt = ip + lev - 1
69 factor = FLOAT(ndiag(ip,bi,bj))
70 IF (ndiag(ip,bi,bj).NE.0) factor = 1. _d 0 / factor
71
72 DO j = 1,sNy+1
73 DO i = 1,sNx+1
74 IF ( qdiag(i,j,ipnt,bi,bj) .LE. undef ) THEN
75 qtmp(i,j) = qdiag(i,j,ipnt,bi,bj)*factor
76 ELSE
77 qtmp(i,j) = undef
78 ENDIF
79 ENDDO
80 ENDDO
81
82 ELSE
83 C- With counter diagnostics => average = Sum / counter:
84
85 ipnt = ip + lev - 1
86 levCt= MIN(lev,kdiag(mate))
87 ipCt = im + levCt - 1
88 DO j = 1,sNy+1
89 DO i = 1,sNx+1
90 IF ( qdiag(i,j,ipCt,bi,bj) .NE. 0. ) THEN
91 qtmp(i,j) = qdiag(i,j,ipnt,bi,bj)
92 & / qdiag(i,j,ipCt,bi,bj)
93 ELSE
94 qtmp(i,j) = undef
95 ENDIF
96 ENDDO
97 ENDDO
98
99 ENDIF
100 ENDIF
101 ENDIF
102
103 RETURN
104 END
105
106 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
107
108 CBOP 0
109 C !ROUTINE: DIAGNOSTICS_COUNT
110 C !INTERFACE:
111 SUBROUTINE DIAGNOSTICS_COUNT (chardiag,
112 I biArg, bjArg, myThid)
113
114 C !DESCRIPTION:
115 C***********************************************************************
116 C routine to increment the diagnostic counter only
117 C***********************************************************************
118 C !USES:
119 IMPLICIT NONE
120
121 C == Global variables ===
122 #include "EEPARAMS.h"
123 #include "SIZE.h"
124 #include "DIAGNOSTICS_SIZE.h"
125 #include "DIAGNOSTICS.h"
126
127 C !INPUT PARAMETERS:
128 C***********************************************************************
129 C Arguments Description
130 C ----------------------
131 C chardiag :: Character expression for diag to increment the counter
132 C biArg :: X-direction tile number, or 0 if called outside bi,bj loops
133 C bjArg :: Y-direction tile number, or 0 if called outside bi,bj loops
134 C myThid :: my thread Id number
135 C***********************************************************************
136 CHARACTER*8 chardiag
137 INTEGER biArg, bjArg
138 INTEGER myThid
139 CEOP
140
141 C !LOCAL VARIABLES:
142 C ===============
143 INTEGER m, n
144 INTEGER bi, bj
145 INTEGER ipt
146 c CHARACTER*(MAX_LEN_MBUF) msgBuf
147
148 C-- Run through list of active diagnostics to find which counter
149 C to increment (needs to be a valid & active diagnostic-counter)
150 DO n=1,nlists
151 DO m=1,nActive(n)
152 IF ( chardiag.EQ.flds(m,n) .AND. idiag(m,n).GT.0 ) THEN
153 ipt = idiag(m,n)
154 IF (ndiag(ipt,1,1).GE.0) THEN
155 C- Increment the counter for the diagnostic
156 IF ( biArg.EQ.0 .AND. bjArg.EQ.0 ) THEN
157 DO bj=myByLo(myThid), myByHi(myThid)
158 DO bi=myBxLo(myThid), myBxHi(myThid)
159 ndiag(ipt,bi,bj) = ndiag(ipt,bi,bj) + 1
160 ENDDO
161 ENDDO
162 ELSE
163 bi = MIN(biArg,nSx)
164 bj = MIN(bjArg,nSy)
165 ndiag(ipt,bi,bj) = ndiag(ipt,bi,bj) + 1
166 ENDIF
167 C- Increment is done
168 ENDIF
169 ENDIF
170 ENDDO
171 ENDDO
172
173 RETURN
174 END
175
176 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
177
178 CBOP 0
179 C !ROUTINE: DIAGNOSTICS_GET_POINTERS
180 C !INTERFACE:
181 SUBROUTINE DIAGNOSTICS_GET_POINTERS(
182 I diagName, listId,
183 O ndId, ip,
184 I myThid )
185
186 C !DESCRIPTION:
187 C *================================================================*
188 C | o Returns the diagnostic Id number and diagnostic
189 C | pointer to storage array for a specified diagnostic.
190 C *================================================================*
191 C | Note: A diagnostics field can be stored multiple times
192 C | (for different output frequency,phase, ...).
193 C | operates in 2 ways:
194 C | o listId =0 => find 1 diagnostics Id & pointer which name matches.
195 C | o listId >0 => find the unique diagnostic Id & pointer with
196 C | the right name and same output time as "listId" output-list
197 C | o return ip=0 if did not find the right diagnostic;
198 C | (ndId <>0 if diagnostic exist but output time does not match)
199 C *================================================================*
200
201 C !USES:
202 IMPLICIT NONE
203 #include "EEPARAMS.h"
204 #include "SIZE.h"
205 #include "DIAGNOSTICS_SIZE.h"
206 #include "DIAGNOSTICS.h"
207
208 C !INPUT PARAMETERS:
209 C diagName :: diagnostic identificator name (8 characters long)
210 C listId :: list number that specify the output frequency
211 C myThid :: my Thread Id number
212 C !OUTPUT PARAMETERS:
213 C ndId :: diagnostics Id number (in available diagnostics list)
214 C ip :: diagnostics pointer to storage array
215
216
217 CHARACTER*8 diagName
218 INTEGER listId
219 INTEGER ndId, ip
220 INTEGER myThid
221 CEOP
222
223 C !LOCAL VARIABLES:
224 INTEGER n,m
225
226 ip = 0
227 ndId = 0
228
229 IF ( listId.LE.0 ) THEN
230 C-- select the 1rst one which name matches:
231
232 C- search for this diag. in the active 2D/3D diagnostics list
233 DO n=1,nlists
234 DO m=1,nActive(n)
235 IF ( ip.EQ.0 .AND. diagName.EQ.flds(m,n)
236 & .AND. idiag(m,n).NE.0 ) THEN
237 ip = ABS(idiag(m,n))
238 ndId = jdiag(m,n)
239 ENDIF
240 ENDDO
241 ENDDO
242
243 ELSEIF ( listId.LE.nlists ) THEN
244 C-- select the unique diagnostic with output-time identical to listId
245
246 C- search for this diag. in the active 2D/3D diagnostics list
247 DO n=1,nlists
248 IF ( ip.EQ.0
249 & .AND. freq(n) .EQ. freq(listId)
250 & .AND. phase(n).EQ.phase(listId)
251 & .AND. averageFreq(n) .EQ.averageFreq(listId)
252 & .AND. averagePhase(n).EQ.averagePhase(listId)
253 & .AND. averageCycle(n).EQ.averageCycle(listId)
254 & ) THEN
255 DO m=1,nActive(n)
256 IF ( ip.EQ.0 .AND. diagName.EQ.flds(m,n)
257 & .AND. idiag(m,n).NE.0 ) THEN
258 ip = ABS(idiag(m,n))
259 ndId = jdiag(m,n)
260 ENDIF
261 ENDDO
262 ELSEIF ( ip.EQ.0 ) THEN
263 DO m=1,nActive(n)
264 IF ( ip.EQ.0 .AND. diagName.EQ.flds(m,n)
265 & .AND. idiag(m,n).NE.0 ) THEN
266 ndId = jdiag(m,n)
267 ENDIF
268 ENDDO
269 ENDIF
270 ENDDO
271
272 ELSE
273 STOP 'DIAGNOSTICS_GET_POINTERS: invalid listId number'
274 ENDIF
275
276 RETURN
277 END
278
279 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
280
281 CBOP 0
282 C !ROUTINE: DIAGS_GET_PARMS_I
283
284 C !INTERFACE:
285 INTEGER FUNCTION DIAGS_GET_PARMS_I(
286 I parName, myThid )
287
288 C !DESCRIPTION:
289 C *==========================================================*
290 C | FUNCTION DIAGS_GET_PARMS_I
291 C | o Return the value of integer parameter
292 C | from one of the DIAGNOSTICS.h common blocs
293 C *==========================================================*
294
295 C !USES:
296 IMPLICIT NONE
297 #include "EEPARAMS.h"
298 #include "SIZE.h"
299 #include "DIAGNOSTICS_SIZE.h"
300 #include "DIAGNOSTICS.h"
301
302 C !INPUT PARAMETERS:
303 C parName :: string used to identify which parameter to get
304 C myThid :: my Thread Id number
305 CHARACTER*(*) parName
306 INTEGER myThid
307 CEOP
308
309 C !LOCAL VARIABLES:
310 CHARACTER*(MAX_LEN_MBUF) msgBuf
311 INTEGER n
312
313 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
314
315 n = LEN(parName)
316 c write(0,'(3A,I4)')
317 c & 'DIAGS_GET_PARMS_I: parName="',parName,'" , length=',n
318
319 IF ( parName.EQ.'LAST_DIAG_ID' ) THEN
320 DIAGS_GET_PARMS_I = ndiagt
321 ELSE
322 WRITE(msgBuf,'(4A)') 'DIAGS_GET_PARMS_I: ',
323 & ' parName="', parName, '" not known.'
324 CALL PRINT_ERROR( msgBuf, myThid )
325 STOP 'ABNORMAL END: S/R DIAGS_GET_PARMS_I'
326 ENDIF
327
328 RETURN
329 END
330
331 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
332
333 CBOP 0
334 C !ROUTINE: DIAGS_MK_UNITS
335
336 C !INTERFACE:
337 CHARACTER*16 FUNCTION DIAGS_MK_UNITS(
338 I diagUnitsInPieces, myThid )
339
340 C !DESCRIPTION:
341 C *==========================================================*
342 C | FUNCTION DIAGS_MK_UNITS
343 C | o Return the diagnostic units string (16c) removing
344 C | blanks from the input string
345 C *==========================================================*
346
347 C !USES:
348 IMPLICIT NONE
349 #include "EEPARAMS.h"
350
351 C !INPUT PARAMETERS:
352 C diagUnitsInPieces :: string for diagnostic units: in several
353 C pieces, with blanks in between
354 C myThid :: my thread Id number
355 CHARACTER*(*) diagUnitsInPieces
356 INTEGER myThid
357 CEOP
358
359 C !LOCAL VARIABLES:
360 CHARACTER*(MAX_LEN_MBUF) msgBuf
361 INTEGER i,j,n
362
363 DIAGS_MK_UNITS = ' '
364 n = LEN(diagUnitsInPieces)
365
366 j = 0
367 DO i=1,n
368 IF (diagUnitsInPieces(i:i) .NE. ' ' ) THEN
369 j = j+1
370 IF ( j.LE.16 ) DIAGS_MK_UNITS(j:j) = diagUnitsInPieces(i:i)
371 ENDIF
372 ENDDO
373
374 IF ( j.GT.16 ) THEN
375 WRITE(msgBuf,'(2A,I4,A)') '**WARNING** ',
376 & 'DIAGS_MK_UNITS: too long (',j,' >16) input string'
377 CALL PRINT_MESSAGE( msgBuf, errorMessageUnit,
378 & SQUEEZE_RIGHT , myThid)
379 WRITE(msgBuf,'(3A)') '**WARNING** ',
380 & 'DIAGS_MK_UNITS: input=', diagUnitsInPieces
381 CALL PRINT_MESSAGE( msgBuf, errorMessageUnit,
382 & SQUEEZE_RIGHT , myThid)
383 ENDIF
384
385 RETURN
386 END
387
388 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
389
390 CBOP 0
391 C !ROUTINE: DIAGS_MK_TITLE
392
393 C !INTERFACE:
394 CHARACTER*80 FUNCTION DIAGS_MK_TITLE(
395 I diagTitleInPieces, myThid )
396
397 C !DESCRIPTION:
398 C *==========================================================*
399 C | FUNCTION DIAGS_MK_TITLE
400 C | o Return the diagnostic title string (80c) removing
401 C | consecutive blanks from the input string
402 C *==========================================================*
403
404 C !USES:
405 IMPLICIT NONE
406 #include "EEPARAMS.h"
407
408 C !INPUT PARAMETERS:
409 C diagTitleInPieces :: string for diagnostic units: in several
410 C pieces, with blanks in between
411 C myThid :: my Thread Id number
412 CHARACTER*(*) diagTitleInPieces
413 INTEGER myThid
414 CEOP
415
416 C !LOCAL VARIABLES:
417 CHARACTER*(MAX_LEN_MBUF) msgBuf
418 LOGICAL flag
419 INTEGER i,j,n
420
421 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
422
423 DIAGS_MK_TITLE = ' '
424 & //' '
425 n = LEN(diagTitleInPieces)
426
427 j = 0
428 flag = .FALSE.
429 DO i=1,n
430 IF (diagTitleInPieces(i:i) .NE. ' ' ) THEN
431 IF ( flag ) THEN
432 j = j+1
433 IF (j.LE.80) DIAGS_MK_TITLE(j:j) = ' '
434 ENDIF
435 j = j+1
436 IF ( j.LE.80 ) DIAGS_MK_TITLE(j:j) = diagTitleInPieces(i:i)
437 flag = .FALSE.
438 ELSE
439 flag = j.GE.1
440 ENDIF
441 ENDDO
442
443 IF ( j.GT.80 ) THEN
444 WRITE(msgBuf,'(2A,I4,A)') '**WARNING** ',
445 & 'DIAGS_MK_TITLE: too long (',j,' >80) input string'
446 CALL PRINT_MESSAGE( msgBuf, errorMessageUnit,
447 & SQUEEZE_RIGHT , myThid)
448 WRITE(msgBuf,'(3A)') '**WARNING** ',
449 & 'DIAGS_MK_TITLE: input=', diagTitleInPieces
450 CALL PRINT_MESSAGE( msgBuf, errorMessageUnit,
451 & SQUEEZE_RIGHT , myThid)
452 ENDIF
453
454 RETURN
455 END

  ViewVC Help
Powered by ViewVC 1.1.22