/[MITgcm]/MITgcm/eesupp/src/print.F
ViewVC logotype

Contents of /MITgcm/eesupp/src/print.F

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


Revision 1.4 - (show annotations) (download)
Sun Apr 26 23:41:54 1998 UTC (26 years ago) by cnh
Branch: MAIN
Changes since 1.3: +108 -1 lines
Improvements to I/O and feedback info.

1 C $Header: /u/gcmpack/models/MITgcmUV/eesupp/src/print.F,v 1.3 1998/04/23 20:56:54 cnh Exp $
2
3 #include "CPP_EEOPTIONS.h"
4
5 C-- File printf.F: Routines for performing formatted textual I/O
6 C-- in the MITgcm UV implementation environment.
7 C-- Contents
8 C-- o print_error Does IO with **ERROR** highlighted header
9 C-- o print_list_r8 Prints one-deimensional list of Real*8
10 C-- numbers.
11 C-- o print_mapr4 Formats ABCD... contour map of a Real*4 field
12 C-- Uses print_message for writing
13 C-- o print_mapr8 Formats ABCD... contour map of a Real*8 field
14 C-- Uses print_message for writing
15 C-- o print_message Does IO with unhighlighted header
16
17 CStartOfInterface
18 SUBROUTINE PRINT_ERROR( message , myThid )
19 C /============================================================\
20 C | SUBROUTINE PRINT_ERROR |
21 C | o Write out error message using "standard" format. |
22 C | Notes |
23 C | ===== |
24 C | o Some system's I/O is not "thread-safe". For this reason |
25 C | without the FMTFTN_IO_THREAD_SAFE directive set a |
26 C | critical region is defined around the write here. In some|
27 C | cases BEGIN_CRIT() is approximated by only doing writes |
28 C | for thread number 1 - writes for other threads are |
29 C | ignored! |
30 C | o In a non-parallel form these routines can still be used. |
31 C | to produce pretty printed output! |
32 C \============================================================/
33 C == Global data ==
34 #include "SIZE.h"
35 #include "EEPARAMS.h"
36 #include "EESUPPORT.h"
37 C == Routine arguments ==
38 CHARACTER*(*) message
39 INTEGER myThid
40 CEndOfInterface
41 INTEGER IFNBLNK
42 EXTERNAL IFNBLNK
43 INTEGER ILNBLNK
44 EXTERNAL ILNBLNK
45 C == Local variables ==
46 INTEGER iStart
47 INTEGER iEnd
48 CHARACTER*9 idString
49 C-- Find beginning and end of message
50 iStart = IFNBLNK( message )
51 iEnd = ILNBLNK( message )
52 C-- Test to see if in multi-process ( or multi-threaded ) mode.
53 C If so include process or thread identifier.
54 IF ( numberOfProcs .EQ. 0 .AND. nThreads .EQ. 1 ) THEN
55 C-- Write single process format
56 IF ( message .EQ. ' ' ) THEN
57 WRITE(errorMessageUnit,'(A,1X,A)') ERROR_HEADER, ' '
58 ELSE
59 WRITE(errorMessageUnit,'(A,1X,A)') ERROR_HEADER, message(iStart:iEnd)
60 ENDIF
61 ELSEIF ( pidIO .EQ. myProcId ) THEN
62 C-- Write multi-process format
63 #ifndef FMTFTN_IO_THREAD_SAFE
64 _BEGIN_CRIT(myThid)
65 #endif
66 WRITE(idString,'(I4.4,A,I4.4)') myProcId,'.',myThid
67 #ifndef FMTFTN_IO_THREAD_SAFE
68 _END_CRIT(myThid)
69 #endif
70 IF ( message .EQ. ' ' ) THEN
71 C PRINT_ERROR can be called by several threads simulataneously.
72 C The write statement may need to be marked as a critical section.
73 #ifndef FMTFTN_IO_THREAD_SAFE
74 _BEGIN_CRIT(myThid)
75 #endif
76 WRITE(errorMessageUnit,'(A,A,1X,A,A,A,A,A)')
77 & '(',PROCESS_HEADER,idString,')',ERROR_HEADER,' ',
78 & ' '
79 #ifndef FMTFTN_IO_THREAD_SAFE
80 _END_CRIT(myThid)
81 #endif
82 ELSE
83 #ifndef FMTFTN_IO_THREAD_SAFE
84 _BEGIN_CRIT(myThid)
85 #endif
86 WRITE(errorMessageUnit,'(A,A,1X,A,A,A,A,A)')
87 & '(',PROCESS_HEADER,idString,')',ERROR_HEADER,' ',
88 & message(iStart:iEnd)
89 #ifndef FMTFTN_IO_THREAD_SAFE
90 _END_CRIT(myThid)
91 #endif
92 ENDIF
93 ENDIF
94 C
95 RETURN
96 END
97
98 CStartofinterface
99 SUBROUTINE PRINT_LIST_R8( fld, lFld, index_type, ioUnit )
100 CEndifinterface
101 C /==========================================================\
102 C | o SUBROUTINE PRINT_LIST_R8 |
103 C |==========================================================|
104 C | Routine for producing list of values for a field with |
105 C | duplicate values collected into |
106 C | n @ value |
107 C | record. |
108 C \==========================================================/
109
110 C == Global data ==
111 #include "SIZE.h"
112 #include "EEPARAMS.h"
113
114 C == Routine arguments ==
115 C fld - Data to be printed
116 C lFld - Number of elements to be printed
117 C index_type - Flag indicating which type of index to print
118 C INDEX_K => /* K = nnn */
119 C INDEX_I => /* I = nnn */
120 C INDEX_J => /* J = nnn */
121 C INDEX_NONE =>
122 C ioUnit - Unit number for IO.
123 INTEGER lFld
124 INTEGER index_type
125 Real*8 fld(lFld)
126 INTEGER ioUnit
127
128 C == Local variables ==
129 C iLo - Range index holders for selecting elements with
130 C iHi with the same value
131 C nDup - Number of duplicates
132 C xNew, xOld - Hold current and previous values of field
133 C punc - Field separator
134 C msgBuf - IO buffer
135 C index_lab - Index for labelling elements
136 C K - Loop counter
137 INTEGER iLo
138 INTEGER iHi
139 INTEGER nDup
140 Real*8 xNew, xOld
141 CHARACTER punc
142 CHARACTER(MAX_LEN_MBUF) msgBuf
143 CHARACTER*2 commOpen,commClose
144 CHARACTER*3 index_lab
145 INTEGER K
146
147 IF ( index_type .EQ. INDEX_I ) THEN
148 index_lab = 'I ='
149 ELSEIF ( index_type .EQ. INDEX_J ) THEN
150 index_lab = 'J ='
151 ELSEIF ( index_type .EQ. INDEX_K ) THEN
152 index_lab = 'K ='
153 ELSE
154 index_lab = '?='
155 ENDIF
156 commOpen = '/*'
157 commClose = '*/'
158 iLo = 1
159 iHi = 1
160 punc = ','
161 xOld = fld(1)
162 DO K=2,lFld
163 xNew = fld(K )
164 IF ( xNew .NE. xOld ) THEN
165 nDup = iHi-iLo+1
166 IF ( nDup .EQ. 1 ) THEN
167 WRITE(msgBuf,'(A,1PE23.15,A)') ' ',xOld,punc
168 IF ( index_type .NE. INDEX_NONE )
169 & WRITE(msgBuf(45:),'(A,1X,A,I3,1X,A)') commOpen,index_lab,iLo,commClose
170 ELSE
171 WRITE(msgBuf,'(I,'' '',A,1PE23.15,A)') nDup,'@',xOld,punc
172 IF ( index_type .NE. INDEX_NONE )
173 & WRITE(msgBuf(45:),'(A,1X,A,I3,A,I3,1X,A)')
174 & commOpen,index_lab,iLo,':',iHi,commClose
175 ENDIF
176 CALL PRINT_MESSAGE( msgBuf, standardMessageUnit, SQUEEZE_RIGHT , 1)
177 iLo = K
178 iHi = K
179 xOld = xNew
180 ELSE
181 iHi = K
182 ENDIF
183 ENDDO
184 punc = ' '
185 nDup = iHi-iLo+1
186 IF ( nDup .EQ. 1 ) THEN
187 WRITE(msgBuf,'(A,1PE23.15,A)') ' ',xOld,punc
188 IF ( index_type .NE. INDEX_NONE )
189 & WRITE(msgBuf(45:),'(A,1X,A,I3,1X,A)') commOpen,index_lab,iLo,commClose
190 ELSEIF( nDup .GT. 1 ) THEN
191 WRITE(msgBuf,'(I,'' '',A,1PE23.15,A)') nDup,'@',xOld,punc
192 IF ( index_type .NE. INDEX_NONE )
193 & WRITE(msgBuf(45:),'(A,1X,A,I3,A,I3,1X,A)')
194 & commOpen,index_lab,iLo,':',iHi,commClose
195 ENDIF
196 CALL PRINT_MESSAGE( msgBuf, standardMessageUnit, SQUEEZE_RIGHT , 1)
197
198 RETURN
199 END
200
201 CStartOfInterface
202 SUBROUTINE PRINT_MAPR4 ( fld, fldTitle, plotMode,
203 I iLo, iHi, jLo, jHi, kLo, kHi, nBx, nBy,
204 I iMin, iMax, iStr,
205 I jMin, jMax, jStr,
206 I kMin, kMax, kStr,
207 I bxMin, bxMax, bxStr,
208 I byMin, byMax, byStr )
209 C /==========================================================\
210 C | SUBROUTINE PRINT_MAPR4 |
211 C | o Does textual mapping printing of a field. |
212 C |==========================================================|
213 C | This routine does the actual formatting of the data |
214 C | and printing to a file. It assumes an array using the |
215 C | MITgcm UV indexing scheme and base index variables. |
216 C | User code should call an interface routine like |
217 C | PLOT_FIELD_XYR4( ... ) rather than this code directly. |
218 C | Text plots can be oriented XY, YZ, XZ. An orientation |
219 C | is specficied through the "plotMode" argument. All the |
220 C | plots made by a single call to this routine will use the |
221 C | same contour interval. The plot range (iMin,...,byStr) |
222 C | can be three-dimensional. A separate plot is made for |
223 C | each point in the plot range normal to the orientation. |
224 C | e.g. if the orientation is XY (plotMode = PRINT_MAP_XY). |
225 C | kMin =1, kMax = 5 and kStr = 2 will produce three XY|
226 C | plots - one for K=1, one for K=3 and one for K=5. |
227 C | Each plot would have extents iMin:iMax step iStr |
228 C | and jMin:jMax step jStr. |
229 C \==========================================================/
230
231 C == Global variables ==
232 #include "SIZE.h"
233 #include "EEPARAMS.h"
234 #include "EESUPPORT.h"
235
236 C == Routine arguments ==
237 C fld - Real*4 array holding data to be plotted
238 C fldTitle - Name of field to be plotted
239 C plotMode - Text string indicating plot orientation
240 C ( see - EEPARAMS.h for valid values ).
241 C iLo, iHi, - Dimensions of array fld. fld is assumed to
242 C jLo, jHi be five-dimensional.
243 C kLo, kHi
244 C nBx, nBy
245 C iMin, iMax - Indexing for points to plot. Points from
246 C iStr iMin -> iMax in steps of iStr are plotted
247 C jMin. jMax and similarly for jMin, jMax, jStr and
248 C jStr kMin, kMax, kStr and bxMin, bxMax, bxStr
249 C kMin, kMax byMin, byMax, byStr.
250 C kStr
251 CHARACTER*(*) fldTitle
252 CHARACTER*(*) plotMode
253 INTEGER iLo, iHi
254 INTEGER jLo, jHi
255 INTEGER kLo, kHi
256 INTEGER nBx, nBy
257 Real*4 fld(iLo:iHi,jLo:jHi,kLo:kHi,nBx,nBy)
258 INTEGER iMin, iMax, iStr
259 INTEGER jMin, jMax, jStr
260 INTEGER kMin, kMax, kStr
261 INTEGER bxMin, bxMax, bxStr
262 INTEGER byMin, byMax, byStr
263 CEndOfInterface
264 C == Local variables ==
265 INTEGER IFNBLNK
266 EXTERNAL IFNBLNK
267 INTEGER ILNBLNK
268 EXTERNAL ILNBLNK
269
270 C == Local variables ==
271 C plotBuf - Buffer for building plot record
272 C chList - Character string used for plot
273 C fMin, fMax - Contour min, max and range
274 C fRange
275 C val - Value of element to be "plotted"
276 C small - Lowest range for which contours are plotted
277 C accXXX - Variables used in indexing accross page records.
278 C dwnXXX Variables used in indexing down the page.
279 C pltXXX Variables used in indexing multiple plots ( multiple
280 C plots use same contour range).
281 C Lab - Label
282 C Base - Base number for element indexing
283 C The process bottom, left coordinate in the
284 C global domain.
285 C Step - Block size
286 C Blo - Start block
287 C Bhi - End block
288 C Bstr - Block stride
289 C Min - Start index within block
290 C Max - End index within block
291 C Str - stride within block
292 INTEGER MAX_LEN_PLOTBUF
293 PARAMETER ( MAX_LEN_PLOTBUF = MAX_LEN_MBUF-4 )
294 CHARACTER*(MAX_LEN_PLOTBUF) plotBuf
295 CHARACTER*(MAX_LEN_MBUF) msgBuf
296 INTEGER lChList
297 PARAMETER ( lChList = 28 )
298 CHARACTER*(lChList) chList
299 REAL fMin
300 REAL fMax
301 REAL fRange
302 REAL val
303 REAL small
304 CHARACTER*2 accLab
305 CHARACTER*7 dwnLab
306 CHARACTER*3 pltLab
307 INTEGER accBase, dwnBase, pltBase
308 INTEGER accStep, dwnStep, pltStep
309 INTEGER accBlo, dwnBlo, pltBlo
310 INTEGER accBhi, dwnBhi, pltBhi
311 INTEGER accBstr, dwnBstr, pltBstr
312 INTEGER accMin, dwnMin, pltMin
313 INTEGER accMax, dwnMax, pltMax
314 INTEGER accStr, dwnStr, pltStr
315 INTEGER I, J, K, iStrngLo, iStrngHi, iBuf, iDx
316 INTEGER bi, bj, bk
317 LOGICAL validRange
318
319 chList = '-abcdefghijklmnopqrstuvwxyz+'
320 small = 1. _d -15
321 fMin = 1. _d 32
322 fMax = -1. _d 32
323 validRange = .FALSE.
324
325 C-- Calculate field range
326 DO bj=byMin, byMax, byStr
327 DO bi=bxMin, bxMax, bxStr
328 DO K=kMin, kMax, kStr
329 DO J=jMin, jMax, jStr
330 DO I=iMin, iMax, iStr
331 IF ( fld(I,J,K,bi,bj) .NE. 0. ) THEN
332 IF ( fld(I,J,K,bi,bj) .LT. fMin )
333 & fMin = fld(I,J,K,bi,bj)
334 IF ( fld(I,J,K,bi,bj) .GT. fMax )
335 & fMax = fld(I,J,K,bi,bj)
336 ENDIF
337 ENDDO
338 ENDDO
339 ENDDO
340 ENDDO
341 ENDDO
342 fRange = fMax-fMin
343 IF ( fRange .GT. small ) THEN
344 validRange = .TRUE.
345 ENDIF
346
347 C-- Write field title and statistics
348 msgBuf = '// ======================================================='
349 CALL PRINT_MESSAGE(msgBuf, standardMessageUnit,
350 & SQUEEZE_RIGHT, 1)
351 iStrngLo = IFNBLNK(fldTitle)
352 iStrngHi = ILNBLNK(fldTitle)
353 IF ( iStrngLo .LE. iStrngHi ) THEN
354 WRITE(msgBuf,'(A)') fldTitle(iStrngLo:iStrngHi)
355 ELSE
356 msgBuf = '// UNKNOWN FIELD'
357 ENDIF
358 CALL PRINT_MESSAGE(msgBuf, standardMessageUnit,
359 & SQUEEZE_RIGHT, 1)
360 WRITE(msgBuf,'(A,1PE30.15)')
361 & '// CMIN = ', fMin
362 CALL PRINT_MESSAGE(msgBuf, standardMessageUnit,
363 & SQUEEZE_RIGHT, 1)
364 WRITE(msgBuf,'(A,1PE30.15)')
365 & '// CMAX = ', fMax
366 CALL PRINT_MESSAGE(msgBuf, standardMessageUnit,
367 & SQUEEZE_RIGHT, 1)
368 WRITE(msgBuf,'(A,1PE30.15)')
369 & '// CINT = ', fRange/FLOAT(lChlist-1)
370 CALL PRINT_MESSAGE(msgBuf, standardMessageUnit,
371 & SQUEEZE_RIGHT, 1)
372 WRITE(msgBuf,'(A,1024A1)')
373 & '// SYMBOLS (CMIN->CMAX): ',(chList(I:I),I=1,lChList)
374 CALL PRINT_MESSAGE(msgBuf, standardMessageUnit,
375 & SQUEEZE_RIGHT, 1)
376 WRITE(msgBuf,'(A,1024A1)')
377 & '// 0.0: ','.'
378 CALL PRINT_MESSAGE(msgBuf, standardMessageUnit,
379 & SQUEEZE_RIGHT, 1)
380 WRITE(msgBuf,'(A,3(A,I4),A)')
381 & '// RANGE I (Lo:Hi:Step):',
382 & '(',myXGlobalLo-1+(bxMin-1)*sNx+iMin,
383 & ':',myXGlobalLo-1+(bxMax-1)*sNx+iMax,
384 & ':',iStr,')'
385 CALL PRINT_MESSAGE(msgBuf, standardMessageUnit,
386 & SQUEEZE_RIGHT, 1)
387 WRITE(msgBuf,'(A,3(A,I4),A)')
388 & '// RANGE J (Lo:Hi:Step):',
389 & '(',myYGlobalLo-1+(byMin-1)*sNy+jMin,
390 & ':',myYGlobalLo-1+(byMax-1)*sNy+jMax,
391 & ':',jStr,')'
392 CALL PRINT_MESSAGE(msgBuf, standardMessageUnit,
393 & SQUEEZE_RIGHT, 1)
394 WRITE(msgBuf,'(A,3(A,I4),A)')
395 & '// RANGE K (Lo:Hi:Step):',
396 & '(',kMin,
397 & ':',kMax,
398 & ':',kStr,')'
399 CALL PRINT_MESSAGE(msgBuf, standardMessageUnit,
400 & SQUEEZE_RIGHT, 1)
401 msgBuf = '// ======================================================='
402 CALL PRINT_MESSAGE(msgBuf, standardMessageUnit,
403 & SQUEEZE_RIGHT, 1)
404
405 C-- Write field
406 C Figure out slice type and set plotting parameters appropriately
407 C acc = accross the page
408 C dwn = down the page
409 IF ( plotMode .EQ. PRINT_MAP_XY ) THEN
410 C X across, Y down slice
411 accLab = 'I='
412 accBase = myXGlobalLo
413 accStep = sNx
414 accBlo = bxMin
415 accBhi = bxMax
416 accBStr = bxStr
417 accMin = iMin
418 accMax = iMax
419 accStr = iStr
420 dwnLab = '|--J--|'
421 dwnBase = myYGlobalLo
422 dwnStep = sNy
423 dwnBlo = byMin
424 dwnBhi = byMax
425 dwnBStr = byStr
426 dwnMin = jMin
427 dwnMax = jMax
428 dwnStr = jStr
429 pltBlo = 1
430 pltBhi = 1
431 pltBstr = 1
432 pltMin = kMin
433 pltMax = kMax
434 pltStr = kStr
435 pltBase = 1
436 pltStep = 1
437 pltLab = 'K ='
438 ELSEIF ( plotMode .EQ. PRINT_MAP_YZ ) THEN
439 C Y across, Z down slice
440 accLab = 'J='
441 accBase = myYGlobalLo
442 accStep = sNy
443 accBlo = byMin
444 accBhi = byMax
445 accBStr = byStr
446 accMin = jMin
447 accMax = jMax
448 accStr = jStr
449 dwnLab = '|--K--|'
450 dwnBase = 1
451 dwnStep = 1
452 dwnBlo = 1
453 dwnBhi = 1
454 dwnBStr = 1
455 dwnMin = kMin
456 dwnMax = kMax
457 dwnStr = kStr
458 pltBlo = bxMin
459 pltBhi = bxMax
460 pltBstr = bxStr
461 pltMin = iMin
462 pltMax = iMax
463 pltStr = iStr
464 pltBase = myXGlobalLo
465 pltStep = sNx
466 pltLab = 'I ='
467 ELSEIF ( plotMode .EQ. PRINT_MAP_XZ ) THEN
468 C X across, Z down slice
469 accLab = 'I='
470 accBase = myXGlobalLo
471 accStep = sNx
472 accBlo = bxMin
473 accBhi = bxMax
474 accBStr = bxStr
475 accMin = iMin
476 accMax = iMax
477 accStr = iStr
478 dwnLab = '|--K--|'
479 dwnBase = 1
480 dwnStep = 1
481 dwnBlo = 1
482 dwnBhi = 1
483 dwnBStr = 1
484 dwnMin = kMin
485 dwnMax = kMax
486 dwnStr = kStr
487 pltBlo = byMin
488 pltBhi = byMax
489 pltBstr = byStr
490 pltMin = jMin
491 pltMax = jMax
492 pltStr = jStr
493 pltBase = myYGlobalLo
494 pltStep = sNy
495 pltLab = 'J ='
496 ENDIF
497 IF ( validRange ) THEN
498 C Header
499 C Data
500 DO bk=pltBlo, pltBhi, pltBstr
501 DO K=pltMin,pltMax,pltStr
502 WRITE(plotBuf,'(A,I,I,I,I)') pltLab,
503 & pltBase-1+(bk-1)*pltStep+K
504 CALL PRINT_MESSAGE(plotBuf, standardMessageUnit,
505 & SQUEEZE_RIGHT, 1)
506 plotBuf = ' '
507 iBuf = 6
508 DO bi=accBlo, accBhi, accBstr
509 DO I=accMin, accMax, accStr
510 iDx = accBase-1+(bi-1)*accStep+I
511 iBuf = iBuf + 1
512 IF ( 10*((iBuf-6)/10) .EQ. iBuf-6 ) THEN
513 IF ( iDx. LT. 10 ) THEN
514 WRITE(plotBuf(iBuf:),'(A,I1)') accLab,iDx
515 ELSEIF ( iDx. LT. 100 ) THEN
516 WRITE(plotBuf(iBuf:),'(A,I2)') accLab,iDx
517 ELSEIF ( iDx. LT. 1000 ) THEN
518 WRITE(plotBuf(iBuf:),'(A,I3)') accLab,iDx
519 ELSEIF ( iDx. LT. 10000 ) THEN
520 WRITE(plotBuf(iBuf:),'(A,I4)') accLab,iDx
521 ENDIF
522 ENDIF
523 ENDDO
524 ENDDO
525 WRITE(msgBuf,'(A,A)') '// ',plotBuf
526 CALL PRINT_MESSAGE(msgBuf, standardMessageUnit,
527 & SQUEEZE_RIGHT, 1)
528 plotBuf = dwnLab
529 iBuf = 7
530 DO bi=accBlo, accBhi, accBstr
531 DO I=accMin, accMax, accStr
532 iDx = accBase-1+(bi-1)*accStep+I
533 iBuf = iBuf+1
534 IF ( 10*((iBuf-7)/10) .EQ. iBuf-7 ) THEN
535 WRITE(plotBuf(iBuf:),'(A)') '|'
536 ELSE
537 WRITE(plotBuf(iBuf:iBuf),'(I1)') MOD(iDx,10)
538 ENDIF
539 ENDDO
540 ENDDO
541 WRITE(msgBuf,'(A,A)') '// ',plotBuf
542 CALL PRINT_MESSAGE(msgBuf, standardMessageUnit,
543 & SQUEEZE_RIGHT, 1)
544 DO bj=dwnBlo, dwnBhi, dwnBStr
545 DO J=dwnMin, dwnMax, dwnStr
546 WRITE(plotBuf,'(1X,I5,1X)')
547 & dwnBase-1+(bj-1)*dwnStep+J
548 iBuf = 7
549 DO bi=accBlo,accBhi,accBstr
550 DO I=accMin,accMax,accStr
551 iBuf = iBuf + 1
552 IF ( plotMode .EQ. PRINT_MAP_XY ) THEN
553 val = fld(I,J,K,bi,bj)
554 ELSEIF ( plotMode .EQ. PRINT_MAP_XZ ) THEN
555 val = fld(I,K,J,bi,bk)
556 ELSEIF ( plotMode .EQ. PRINT_MAP_YZ ) THEN
557 val = fld(K,I,J,bk,bi)
558 ENDIF
559 IDX = NINT(
560 & FLOAT( lChList-1 )*( val-fMin ) / (fRange)
561 & )+1
562 IF ( iBuf .LE. MAX_LEN_PLOTBUF )
563 & plotBuf(iBuf:iBuf) = chList(IDX:IDX)
564 IF ( val .EQ. 0. ) THEN
565 IF ( iBuf .LE. MAX_LEN_PLOTBUF )
566 & plotBuf(iBuf:iBuf) = '.'
567 ENDIF
568 ENDDO
569 ENDDO
570 WRITE(msgBuf,'(A,A)') '// ',plotBuf
571 CALL PRINT_MESSAGE(msgBuf, standardMessageUnit,
572 & SQUEEZE_RIGHT, 1)
573 ENDDO
574 ENDDO
575 ENDDO
576 ENDDO
577 ENDIF
578 C-- Write delimiter
579 msgBuf = '// ======================================================='
580 CALL PRINT_MESSAGE(msgBuf, standardMessageUnit,
581 & SQUEEZE_RIGHT, 1)
582 msgBuf = '// END OF FIELD ='
583 CALL PRINT_MESSAGE(msgBuf, standardMessageUnit,
584 & SQUEEZE_RIGHT, 1)
585 msgBuf = '// ======================================================='
586 CALL PRINT_MESSAGE(msgBuf, standardMessageUnit,
587 & SQUEEZE_RIGHT, 1)
588 msgBuf = ' '
589 CALL PRINT_MESSAGE(msgBuf, standardMessageUnit,
590 & SQUEEZE_RIGHT, 1)
591
592 RETURN
593 END
594
595 CStartOfInterface
596 SUBROUTINE PRINT_MAPR8 ( fld, fldTitle, plotMode,
597 I iLo, iHi, jLo, jHi, kLo, kHi, nBx, nBy,
598 I iMin, iMax, iStr,
599 I jMin, jMax, jStr,
600 I kMin, kMax, kStr,
601 I bxMin, bxMax, bxStr,
602 I byMin, byMax, byStr )
603 C /==========================================================\
604 C | SUBROUTINE PRINT_MAPR8 |
605 C | o Does textual mapping printing of a field. |
606 C |==========================================================|
607 C | This routine does the actual formatting of the data |
608 C | and printing to a file. It assumes an array using the |
609 C | MITgcm UV indexing scheme and base index variables. |
610 C | User code should call an interface routine like |
611 C | PLOT_FIELD_XYR8( ... ) rather than this code directly. |
612 C | Text plots can be oriented XY, YZ, XZ. An orientation |
613 C | is specficied through the "plotMode" argument. All the |
614 C | plots made by a single call to this routine will use the |
615 C | same contour interval. The plot range (iMin,...,byStr) |
616 C | can be three-dimensional. A separate plot is made for |
617 C | each point in the plot range normal to the orientation. |
618 C | e.g. if the orientation is XY (plotMode = PRINT_MAP_XY). |
619 C | kMin =1, kMax = 5 and kStr = 2 will produce three XY|
620 C | plots - one for K=1, one for K=3 and one for K=5. |
621 C | Each plot would have extents iMin:iMax step iStr |
622 C | and jMin:jMax step jStr. |
623 C \==========================================================/
624
625 C == Global variables ==
626 #include "SIZE.h"
627 #include "EEPARAMS.h"
628 #include "EESUPPORT.h"
629
630 C == Routine arguments ==
631 C fld - Real*8 array holding data to be plotted
632 C fldTitle - Name of field to be plotted
633 C plotMode - Text string indicating plot orientation
634 C ( see - EEPARAMS.h for valid values ).
635 C iLo, iHi, - Dimensions of array fld. fld is assumed to
636 C jLo, jHi be five-dimensional.
637 C kLo, kHi
638 C nBx, nBy
639 C iMin, iMax - Indexing for points to plot. Points from
640 C iStr iMin -> iMax in steps of iStr are plotted
641 C jMin. jMax and similarly for jMin, jMax, jStr and
642 C jStr kMin, kMax, kStr and bxMin, bxMax, bxStr
643 C kMin, kMax byMin, byMax, byStr.
644 C kStr
645 CHARACTER*(*) fldTitle
646 CHARACTER*(*) plotMode
647 INTEGER iLo, iHi
648 INTEGER jLo, jHi
649 INTEGER kLo, kHi
650 INTEGER nBx, nBy
651 Real*8 fld(iLo:iHi,jLo:jHi,kLo:kHi,nBx,nBy)
652 INTEGER iMin, iMax, iStr
653 INTEGER jMin, jMax, jStr
654 INTEGER kMin, kMax, kStr
655 INTEGER bxMin, bxMax, bxStr
656 INTEGER byMin, byMax, byStr
657 CEndOfInterface
658 C == Local variables ==
659 INTEGER IFNBLNK
660 EXTERNAL IFNBLNK
661 INTEGER ILNBLNK
662 EXTERNAL ILNBLNK
663
664 C == Local variables ==
665 C plotBuf - Buffer for building plot record
666 C chList - Character string used for plot
667 C fMin, fMax - Contour min, max and range
668 C fRange
669 C val - Value of element to be "plotted"
670 C small - Lowest range for which contours are plotted
671 C accXXX - Variables used in indexing accross page records.
672 C dwnXXX Variables used in indexing down the page.
673 C pltXXX Variables used in indexing multiple plots ( multiple
674 C plots use same contour range).
675 C Lab - Label
676 C Base - Base number for element indexing
677 C The process bottom, left coordinate in the
678 C global domain.
679 C Step - Block size
680 C Blo - Start block
681 C Bhi - End block
682 C Bstr - Block stride
683 C Min - Start index within block
684 C Max - End index within block
685 C Str - stride within block
686 INTEGER MAX_LEN_PLOTBUF
687 PARAMETER ( MAX_LEN_PLOTBUF = MAX_LEN_MBUF-4 )
688 CHARACTER*(MAX_LEN_PLOTBUF) plotBuf
689 CHARACTER*(MAX_LEN_MBUF) msgBuf
690 INTEGER lChList
691 PARAMETER ( lChList = 28 )
692 CHARACTER*(lChList) chList
693 REAL fMin
694 REAL fMax
695 REAL fRange
696 REAL val
697 REAL small
698 CHARACTER*2 accLab
699 CHARACTER*7 dwnLab
700 CHARACTER*3 pltLab
701 INTEGER accBase, dwnBase, pltBase
702 INTEGER accStep, dwnStep, pltStep
703 INTEGER accBlo, dwnBlo, pltBlo
704 INTEGER accBhi, dwnBhi, pltBhi
705 INTEGER accBstr, dwnBstr, pltBstr
706 INTEGER accMin, dwnMin, pltMin
707 INTEGER accMax, dwnMax, pltMax
708 INTEGER accStr, dwnStr, pltStr
709 INTEGER I, J, K, iStrngLo, iStrngHi, iBuf, iDx
710 INTEGER bi, bj, bk
711 LOGICAL validRange
712
713 chList = '-abcdefghijklmnopqrstuvwxyz+'
714 small = 1. _d -15
715 fMin = 1. _d 32
716 fMax = -1. _d 32
717 validRange = .FALSE.
718
719 C-- Calculate field range
720 DO bj=byMin, byMax, byStr
721 DO bi=bxMin, bxMax, bxStr
722 DO K=kMin, kMax, kStr
723 DO J=jMin, jMax, jStr
724 DO I=iMin, iMax, iStr
725 C IF ( fld(I,J,K,bi,bj) .NE. 0. ) THEN
726 IF ( fld(I,J,K,bi,bj) .LT. fMin )
727 & fMin = fld(I,J,K,bi,bj)
728 IF ( fld(I,J,K,bi,bj) .GT. fMax )
729 & fMax = fld(I,J,K,bi,bj)
730 C ENDIF
731 ENDDO
732 ENDDO
733 ENDDO
734 ENDDO
735 ENDDO
736 fRange = fMax-fMin
737 IF ( fRange .GT. small ) THEN
738 validRange = .TRUE.
739 ENDIF
740
741 C-- Write field title and statistics
742 msgBuf = '// ======================================================='
743 CALL PRINT_MESSAGE(msgBuf, standardMessageUnit,
744 & SQUEEZE_RIGHT, 1)
745 iStrngLo = IFNBLNK(fldTitle)
746 iStrngHi = ILNBLNK(fldTitle)
747 IF ( iStrngLo .LE. iStrngHi ) THEN
748 WRITE(msgBuf,'(A)') fldTitle(iStrngLo:iStrngHi)
749 ELSE
750 msgBuf = '// UNKNOWN FIELD'
751 ENDIF
752 CALL PRINT_MESSAGE(msgBuf, standardMessageUnit,
753 & SQUEEZE_RIGHT, 1)
754 WRITE(msgBuf,'(A,1PE30.15)')
755 & '// CMIN = ', fMin
756 CALL PRINT_MESSAGE(msgBuf, standardMessageUnit,
757 & SQUEEZE_RIGHT, 1)
758 WRITE(msgBuf,'(A,1PE30.15)')
759 & '// CMAX = ', fMax
760 CALL PRINT_MESSAGE(msgBuf, standardMessageUnit,
761 & SQUEEZE_RIGHT, 1)
762 WRITE(msgBuf,'(A,1PE30.15)')
763 & '// CINT = ', fRange/FLOAT(lChlist-1)
764 CALL PRINT_MESSAGE(msgBuf, standardMessageUnit,
765 & SQUEEZE_RIGHT, 1)
766 WRITE(msgBuf,'(A,1024A1)')
767 & '// SYMBOLS (CMIN->CMAX): ',(chList(I:I),I=1,lChList)
768 CALL PRINT_MESSAGE(msgBuf, standardMessageUnit,
769 & SQUEEZE_RIGHT, 1)
770 WRITE(msgBuf,'(A,1024A1)')
771 & '// 0.0: ','.'
772 CALL PRINT_MESSAGE(msgBuf, standardMessageUnit,
773 & SQUEEZE_RIGHT, 1)
774 WRITE(msgBuf,'(A,3(A,I4),A)')
775 & '// RANGE I (Lo:Hi:Step):',
776 & '(',myXGlobalLo-1+(bxMin-1)*sNx+iMin,
777 & ':',myXGlobalLo-1+(bxMax-1)*sNx+iMax,
778 & ':',iStr,')'
779 CALL PRINT_MESSAGE(msgBuf, standardMessageUnit,
780 & SQUEEZE_RIGHT, 1)
781 WRITE(msgBuf,'(A,3(A,I4),A)')
782 & '// RANGE J (Lo:Hi:Step):',
783 & '(',myYGlobalLo-1+(byMin-1)*sNy+jMin,
784 & ':',myYGlobalLo-1+(byMax-1)*sNy+jMax,
785 & ':',jStr,')'
786 CALL PRINT_MESSAGE(msgBuf, standardMessageUnit,
787 & SQUEEZE_RIGHT, 1)
788 WRITE(msgBuf,'(A,3(A,I4),A)')
789 & '// RANGE K (Lo:Hi:Step):',
790 & '(',kMin,
791 & ':',kMax,
792 & ':',kStr,')'
793 CALL PRINT_MESSAGE(msgBuf, standardMessageUnit,
794 & SQUEEZE_RIGHT, 1)
795 msgBuf = '// ======================================================='
796 CALL PRINT_MESSAGE(msgBuf, standardMessageUnit,
797 & SQUEEZE_RIGHT, 1)
798
799 C-- Write field
800 C Figure out slice type and set plotting parameters appropriately
801 C acc = accross the page
802 C dwn = down the page
803 IF ( plotMode .EQ. PRINT_MAP_XY ) THEN
804 C X across, Y down slice
805 accLab = 'I='
806 accBase = myXGlobalLo
807 accStep = sNx
808 accBlo = bxMin
809 accBhi = bxMax
810 accBStr = bxStr
811 accMin = iMin
812 accMax = iMax
813 accStr = iStr
814 dwnLab = '|--J--|'
815 dwnBase = myYGlobalLo
816 dwnStep = sNy
817 dwnBlo = byMin
818 dwnBhi = byMax
819 dwnBStr = byStr
820 dwnMin = jMin
821 dwnMax = jMax
822 dwnStr = jStr
823 pltBlo = 1
824 pltBhi = 1
825 pltBstr = 1
826 pltMin = kMin
827 pltMax = kMax
828 pltStr = kStr
829 pltBase = 1
830 pltStep = 1
831 pltLab = 'K ='
832 ELSEIF ( plotMode .EQ. PRINT_MAP_YZ ) THEN
833 C Y across, Z down slice
834 accLab = 'J='
835 accBase = myYGlobalLo
836 accStep = sNy
837 accBlo = byMin
838 accBhi = byMax
839 accBStr = byStr
840 accMin = jMin
841 accMax = jMax
842 accStr = jStr
843 dwnLab = '|--K--|'
844 dwnBase = 1
845 dwnStep = 1
846 dwnBlo = 1
847 dwnBhi = 1
848 dwnBStr = 1
849 dwnMin = kMin
850 dwnMax = kMax
851 dwnStr = kStr
852 pltBlo = bxMin
853 pltBhi = bxMax
854 pltBstr = bxStr
855 pltMin = iMin
856 pltMax = iMax
857 pltStr = iStr
858 pltBase = myXGlobalLo
859 pltStep = sNx
860 pltLab = 'I ='
861 ELSEIF ( plotMode .EQ. PRINT_MAP_XZ ) THEN
862 C X across, Z down slice
863 accLab = 'I='
864 accBase = myXGlobalLo
865 accStep = sNx
866 accBlo = bxMin
867 accBhi = bxMax
868 accBStr = bxStr
869 accMin = iMin
870 accMax = iMax
871 accStr = iStr
872 dwnLab = '|--K--|'
873 dwnBase = 1
874 dwnStep = 1
875 dwnBlo = 1
876 dwnBhi = 1
877 dwnBStr = 1
878 dwnMin = kMin
879 dwnMax = kMax
880 dwnStr = kStr
881 pltBlo = byMin
882 pltBhi = byMax
883 pltBstr = byStr
884 pltMin = jMin
885 pltMax = jMax
886 pltStr = jStr
887 pltBase = myYGlobalLo
888 pltStep = sNy
889 pltLab = 'J ='
890 ENDIF
891 IF ( validRange ) THEN
892 C Header
893 C Data
894 DO bk=pltBlo, pltBhi, pltBstr
895 DO K=pltMin,pltMax,pltStr
896 WRITE(plotBuf,'(A,I,I,I,I)') pltLab,
897 & pltBase-1+(bk-1)*pltStep+K
898 CALL PRINT_MESSAGE(plotBuf, standardMessageUnit,
899 & SQUEEZE_RIGHT, 1)
900 plotBuf = ' '
901 iBuf = 6
902 DO bi=accBlo, accBhi, accBstr
903 DO I=accMin, accMax, accStr
904 iDx = accBase-1+(bi-1)*accStep+I
905 iBuf = iBuf + 1
906 IF ( 10*((iBuf-6)/10) .EQ. iBuf-6 ) THEN
907 IF ( iDx. LT. 10 ) THEN
908 WRITE(plotBuf(iBuf:),'(A,I1)') accLab,iDx
909 ELSEIF ( iDx. LT. 100 ) THEN
910 WRITE(plotBuf(iBuf:),'(A,I2)') accLab,iDx
911 ELSEIF ( iDx. LT. 1000 ) THEN
912 WRITE(plotBuf(iBuf:),'(A,I3)') accLab,iDx
913 ELSEIF ( iDx. LT. 10000 ) THEN
914 WRITE(plotBuf(iBuf:),'(A,I4)') accLab,iDx
915 ENDIF
916 ENDIF
917 ENDDO
918 ENDDO
919 CALL PRINT_MESSAGE(plotBuf, standardMessageUnit,
920 & SQUEEZE_RIGHT, 1)
921 plotBuf = dwnLab
922 iBuf = 7
923 DO bi=accBlo, accBhi, accBstr
924 DO I=accMin, accMax, accStr
925 iDx = accBase-1+(bi-1)*accStep+I
926 iBuf = iBuf+1
927 IF ( 10*((iBuf-7)/10) .EQ. iBuf-7 ) THEN
928 WRITE(plotBuf(iBuf:),'(A)') '|'
929 ELSE
930 WRITE(plotBuf(iBuf:iBuf),'(I1)') MOD(iDx,10)
931 ENDIF
932 ENDDO
933 ENDDO
934 CALL PRINT_MESSAGE(plotBuf, standardMessageUnit,
935 & SQUEEZE_RIGHT, 1)
936 DO bj=dwnBlo, dwnBhi, dwnBStr
937 DO J=dwnMin, dwnMax, dwnStr
938 WRITE(plotBuf,'(1X,I5,1X)')
939 & dwnBase-1+(bj-1)*dwnStep+J
940 iBuf = 7
941 DO bi=accBlo,accBhi,accBstr
942 DO I=accMin,accMax,accStr
943 iBuf = iBuf + 1
944 IF ( plotMode .EQ. PRINT_MAP_XY ) THEN
945 val = fld(I,J,K,bi,bj)
946 ELSEIF ( plotMode .EQ. PRINT_MAP_XZ ) THEN
947 val = fld(I,K,J,bi,bk)
948 ELSEIF ( plotMode .EQ. PRINT_MAP_YZ ) THEN
949 val = fld(K,I,J,bk,bi)
950 ENDIF
951 IDX = NINT(
952 & FLOAT( lChList-1 )*( val-fMin ) / (fRange)
953 & )+1
954 IF ( iBuf .LE. MAX_LEN_PLOTBUF )
955 & plotBuf(iBuf:iBuf) = chList(IDX:IDX)
956 IF ( val .EQ. 0. ) THEN
957 IF ( iBuf .LE. MAX_LEN_PLOTBUF )
958 & plotBuf(iBuf:iBuf) = '.'
959 ENDIF
960 ENDDO
961 ENDDO
962 CALL PRINT_MESSAGE(plotBuf, standardMessageUnit,
963 & SQUEEZE_RIGHT, 1)
964 ENDDO
965 ENDDO
966 ENDDO
967 ENDDO
968 ENDIF
969 C-- Write delimiter
970 msgBuf = '// ======================================================='
971 CALL PRINT_MESSAGE(msgBuf, standardMessageUnit,
972 & SQUEEZE_RIGHT, 1)
973 msgBuf = '// END OF FIELD ='
974 CALL PRINT_MESSAGE(msgBuf, standardMessageUnit,
975 & SQUEEZE_RIGHT, 1)
976 msgBuf = '// ======================================================='
977 CALL PRINT_MESSAGE(msgBuf, standardMessageUnit,
978 & SQUEEZE_RIGHT, 1)
979 msgBuf = ' '
980 CALL PRINT_MESSAGE(msgBuf, standardMessageUnit,
981 & SQUEEZE_RIGHT, 1)
982
983 RETURN
984 END
985
986 CStartOfInterface
987 SUBROUTINE PRINT_MESSAGE( message, unit, sq , myThid )
988 C /============================================================\
989 C | SUBROUTINE PRINT_MESSAGE |
990 C | o Write out informational message using "standard" format. |
991 C | Notes |
992 C | ===== |
993 C | o Some system's I/O is not "thread-safe". For this reason |
994 C | without the FMTFTN_IO_THREAD_SAFE directive set a |
995 C | critical region is defined around the write here. In some|
996 C | cases BEGIN_CRIT() is approximated by only doing writes |
997 C | for thread number 1 - writes for other threads are |
998 C | ignored! |
999 C | o In a non-parallel form these routines can still be used. |
1000 C | to produce pretty printed output! |
1001 C \============================================================/
1002 C == Global data ==
1003 #include "SIZE.h"
1004 #include "EEPARAMS.h"
1005 #include "EESUPPORT.h"
1006 C == Routine arguments ==
1007 C message - Message to write
1008 C unit - Unit number to write to
1009 C sq - Justification option
1010 CHARACTER*(*) message
1011 INTEGER unit
1012 CHARACTER*(*) sq
1013 INTEGER myThid
1014 CEndOfInterface
1015 INTEGER IFNBLNK
1016 EXTERNAL IFNBLNK
1017 INTEGER ILNBLNK
1018 EXTERNAL ILNBLNK
1019 C == Local variables ==
1020 INTEGER iStart
1021 INTEGER iEnd
1022 CHARACTER*9 idString
1023 C-- Find beginning and end of message
1024 IF ( sq .EQ. SQUEEZE_BOTH .OR.
1025 & sq .EQ. SQUEEZE_LEFT ) THEN
1026 iStart = IFNBLNK( message )
1027 ELSE
1028 iStart = 1
1029 ENDIF
1030 IF ( sq .EQ. SQUEEZE_BOTH .OR.
1031 & sq .EQ. SQUEEZE_RIGHT ) THEN
1032 iEnd = ILNBLNK( message )
1033 ELSE
1034 iEnd = LEN(message)
1035 ENDIF
1036 C-- Test to see if in multi-process ( or multi-threaded ) mode.
1037 C If so include process or thread identifier.
1038 IF ( numberOfProcs .EQ. 0 .AND. nThreads .EQ. 1 ) THEN
1039 C-- Write single process format
1040 IF ( message .EQ. ' ' ) THEN
1041 WRITE(unit,'(A)') ' '
1042 ELSE
1043 WRITE(unit,'(A)') message(iStart:iEnd)
1044 ENDIF
1045 ELSEIF ( pidIO .EQ. myProcId ) THEN
1046 C-- Write multi-process format
1047 #ifndef FMTFTN_IO_THREAD_SAFE
1048 _BEGIN_CRIT(myThid)
1049 #endif
1050 WRITE(idString,'(I4.4,A,I4.4)') myProcId,'.',myThid
1051 #ifndef FMTFTN_IO_THREAD_SAFE
1052 _END_CRIT(myThid)
1053 #endif
1054 IF ( message .EQ. ' ' ) THEN
1055 C PRINT can be called by several threads simultaneously.
1056 C The write statement may need to ne marked as a critical section.
1057 #ifndef FMTFTN_IO_THREAD_SAFE
1058 _BEGIN_CRIT(myThid)
1059 #endif
1060 WRITE(unit,'(A,A,A,A,A,A)')
1061 & '(',PROCESS_HEADER,' ',idString,')',' '
1062 #ifndef FMTFTN_IO_THREAD_SAFE
1063 _END_CRIT(myThid)
1064 #endif
1065 ELSE
1066 #ifndef FMTFTN_IO_THREAD_SAFE
1067 _BEGIN_CRIT(myThid)
1068 #endif
1069 WRITE(unit,'(A,A,A,A,A,A,A)')
1070 & '(',PROCESS_HEADER,' ',idString(1:ILNBLNK(idString)),')',' ',
1071 & message(iStart:iEnd)
1072 #ifndef FMTFTN_IO_THREAD_SAFE
1073 _END_CRIT(myThid)
1074 #endif
1075 ENDIF
1076 ENDIF
1077 C
1078 RETURN
1079 END

  ViewVC Help
Powered by ViewVC 1.1.22