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

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

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


Revision 1.26 - (hide annotations) (download)
Sat Aug 16 17:28:29 2008 UTC (15 years, 9 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 jmc 1.26 C $Header: /u/gcmpack/MITgcm/pkg/diagnostics/diagnostics_utils.F,v 1.25 2008/02/05 15:31:19 jmc Exp $
2 edhill 1.8 C $Name: $
3    
4 edhill 1.9 #include "DIAG_OPTIONS.h"
5    
6 jmc 1.25 C-- File diagnostics_utils.F: General purpose support routines
7     C-- Contents:
8     C-- o GETDIAG
9     C-- o DIAGNOSTICS_COUNT
10 jmc 1.26 C-- o DIAGNOSTICS_GET_POINTERS
11     C-- o DIAGS_GET_PARMS_I (Function)
12 jmc 1.25 C-- o DIAGS_MK_UNITS (Function)
13     C-- o DIAGS_MK_TITLE (Function)
14    
15 edhill 1.12 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
16     CBOP 0
17     C !ROUTINE: GETDIAG
18    
19     C !INTERFACE:
20 jmc 1.18 SUBROUTINE GETDIAG(
21     I levreal, undef,
22     O qtmp,
23 jmc 1.21 I ndId, mate, ip, im, bi, bj, myThid )
24 edhill 1.12
25     C !DESCRIPTION:
26 edhill 1.13 C Retrieve averaged model diagnostic
27 jmc 1.15
28 edhill 1.12 C !USES:
29 jmc 1.18 IMPLICIT NONE
30 molod 1.3 #include "EEPARAMS.h"
31 molod 1.1 #include "SIZE.h"
32 jmc 1.15 #include "DIAGNOSTICS_SIZE.h"
33     #include "DIAGNOSTICS.h"
34 molod 1.3
35 jmc 1.18 C !INPUT PARAMETERS:
36 jmc 1.21 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 jmc 1.15 _RL levreal
46 molod 1.3 _RL undef
47 jmc 1.21 INTEGER ndId, mate, ip, im
48 jmc 1.18 INTEGER bi,bj, myThid
49 jmc 1.15
50 jmc 1.18 C !OUTPUT PARAMETERS:
51 edhill 1.12 C qtmp ..... AVERAGED DIAGNOSTIC QUANTITY
52 jmc 1.18 _RL qtmp(1-OLx:sNx+OLx,1-OLy:sNy+OLy)
53     CEOP
54 molod 1.11
55 jmc 1.18 C !LOCAL VARIABLES:
56 molod 1.3 _RL factor
57 jmc 1.18 INTEGER i, j, ipnt,ipCt
58     INTEGER lev, levCt, klev
59 molod 1.11
60 jmc 1.21 IF (ndId.GE.1) THEN
61 jmc 1.15 lev = NINT(levreal)
62 jmc 1.21 klev = kdiag(ndId)
63 jmc 1.18 IF (lev.LE.klev) THEN
64 jmc 1.15
65 jmc 1.18 IF ( mate.EQ.0 ) THEN
66     C- No counter diagnostics => average = Sum / ndiag :
67 jmc 1.15
68 jmc 1.21 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 jmc 1.18
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 jmc 1.21 ipnt = ip + lev - 1
86 jmc 1.18 levCt= MIN(lev,kdiag(mate))
87 jmc 1.21 ipCt = im + levCt - 1
88 jmc 1.18 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 molod 1.1
99 jmc 1.18 ENDIF
100     ENDIF
101     ENDIF
102 molod 1.3
103 jmc 1.15 RETURN
104     END
105 edhill 1.12
106     C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
107    
108 jmc 1.15 CBOP 0
109 jmc 1.19 C !ROUTINE: DIAGNOSTICS_COUNT
110     C !INTERFACE:
111 jmc 1.21 SUBROUTINE DIAGNOSTICS_COUNT (chardiag,
112     I biArg, bjArg, myThid)
113 jmc 1.19
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 jmc 1.21 INTEGER m, n
144     INTEGER bi, bj
145     INTEGER ipt
146 jmc 1.19 c CHARACTER*(MAX_LEN_MBUF) msgBuf
147    
148 jmc 1.21 C-- Run through list of active diagnostics to find which counter
149     C to increment (needs to be a valid & active diagnostic-counter)
150 jmc 1.19 DO n=1,nlists
151     DO m=1,nActive(n)
152 jmc 1.21 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 jmc 1.19 ENDIF
170     ENDDO
171     ENDDO
172    
173 jmc 1.21 RETURN
174 jmc 1.19 END
175    
176     C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
177    
178     CBOP 0
179 jmc 1.26 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 jmc 1.17 C !ROUTINE: DIAGS_MK_UNITS
335    
336     C !INTERFACE:
337 jmc 1.21 CHARACTER*16 FUNCTION DIAGS_MK_UNITS(
338 jmc 1.17 I diagUnitsInPieces, myThid )
339    
340     C !DESCRIPTION:
341     C *==========================================================*
342     C | FUNCTION DIAGS_MK_UNITS
343 jmc 1.21 C | o Return the diagnostic units string (16c) removing
344 jmc 1.17 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 jmc 1.21 C diagUnitsInPieces :: string for diagnostic units: in several
353 jmc 1.17 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 jmc 1.21 DIAGS_MK_UNITS = ' '
364 jmc 1.17 n = LEN(diagUnitsInPieces)
365 jmc 1.21
366 jmc 1.17 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 jmc 1.23
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 molod 1.22 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
422 jmc 1.23
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