/[MITgcm]/MITgcm/pkg/mdsio/mdsio_read_field.F
ViewVC logotype

Contents of /MITgcm/pkg/mdsio/mdsio_read_field.F

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


Revision 1.2 - (show annotations) (download)
Mon Mar 19 02:30:49 2007 UTC (17 years, 3 months ago) by jmc
Branch: MAIN
CVS Tags: checkpoint58x_post, checkpoint59e, checkpoint59d, checkpoint59g, checkpoint59f, checkpoint59a, checkpoint59c, checkpoint59b, checkpoint59i, checkpoint59h, checkpoint59j, checkpoint59, checkpoint58y_post
Changes since 1.1: +84 -59 lines
to read/write compact global files: add parameter for mapping tile to global file.

1 C $Header: /u/gcmpack/MITgcm/pkg/mdsio/mdsio_read_field.F,v 1.1 2006/12/29 05:25:15 jmc Exp $
2 C $Name: $
3
4 #include "MDSIO_OPTIONS.h"
5
6 CBOP
7 C !ROUTINE: MDS_READ_FIELD
8 C !INTERFACE:
9 SUBROUTINE MDS_READ_FIELD(
10 I fName,
11 I filePrec,
12 I useCurrentDir,
13 I arrType,
14 I zSize, nNz,
15 O arr,
16 I irecord,
17 I myThid )
18
19 C !DESCRIPTION:
20 C Arguments:
21 C
22 C fName (string) :: base name for file to read
23 C filePrec (integer) :: number of bits per word in file (32 or 64)
24 C useCurrentDir(logic):: always read from the current directory (even if
25 C "mdsioLocalDir" is set)
26 C arrType (char(2)) :: declaration of "arr": either "RS" or "RL"
27 C zSize (integer) :: size of third dimension: normally either 1 or Nr
28 C nNz (integer) :: number of vertical levels to read
29 C arr ( RS/RL ) :: array to read into, arr(:,:,zSize,:,:)
30 C irecord (integer) :: record number to read
31 C myIter (integer) :: time step number
32 C myThid (integer) :: thread identifier
33 C
34 C MDS_READ_FIELD first checks to see IF the file "fName" exists, then
35 C IF the file "fName.data" exists and finally the tiled files of the
36 C form "fName.xxx.yyy.data" exist. Currently, the meta-files are not
37 C read because it is difficult to parse files in fortran.
38 C The precision of the file is decsribed by filePrec, set either
39 C to floatPrec32 or floatPrec64. The precision or declaration of
40 C the array argument must be consistently described by the char*(2)
41 C string arrType, either "RS" or "RL". nNz allows for both 2-D and
42 C 3-D arrays to be handled. nNz=1 implies a 2-D model field and
43 C nNz=Nr implies a 3-D model field. irecord is the record number
44 C to be read and must be >= 1. The file data is stored in
45 C arr *but* the overlaps are *not* updated. ie. An exchange must
46 C be called. This is because the routine is sometimes called from
47 C within a MASTER_THID region.
48 C
49 C Created: 03/16/99 adcroft@mit.edu
50 CEOP
51
52 C !USES:
53 IMPLICIT NONE
54 C Global variables / common blocks
55 #include "SIZE.h"
56 #include "EEPARAMS.h"
57 #include "PARAMS.h"
58 #include "EESUPPORT.h"
59 #ifdef ALLOW_EXCH2
60 #include "W2_EXCH2_TOPOLOGY.h"
61 #include "W2_EXCH2_PARAMS.h"
62 #endif /* ALLOW_EXCH2 */
63 #include "MDSIO_SCPU.h"
64
65 C !INPUT PARAMETERS:
66 CHARACTER*(*) fName
67 INTEGER filePrec
68 LOGICAL useCurrentDir
69 CHARACTER*(2) arrType
70 INTEGER zSize
71 INTEGER nNz
72 INTEGER irecord
73 INTEGER myThid
74 C !OUTPUT PARAMETERS:
75 Real arr(*)
76
77 C !FUNCTIONS
78 INTEGER ILNBLNK
79 INTEGER MDS_RECLEN
80 LOGICAL MASTER_CPU_IO
81 EXTERNAL ILNBLNK
82 EXTERNAL MDS_RECLEN
83 EXTERNAL MASTER_CPU_IO
84
85 C !LOCAL VARIABLES:
86 CHARACTER*(MAX_LEN_FNAM) dataFName,pfName
87 CHARACTER*(MAX_LEN_MBUF) msgBuf
88 LOGICAL exst
89 LOGICAL globalFile, fileIsOpen
90 LOGICAL iAmDoingIO
91 INTEGER iG,jG,irec,bi,bj,i,j,k,dUnit,IL,pIL
92 INTEGER x_size,y_size,length_of_rec
93 #if defined(ALLOW_EXCH2) && !defined(MISSING_TILE_IO)
94 INTEGER iG_IO,jG_IO,npe, loc_xGlobalLo, loc_yGlobalLo
95 PARAMETER ( x_size = exch2_domain_nxt * sNx )
96 PARAMETER ( y_size = exch2_domain_nyt * sNy )
97 #else
98 PARAMETER ( x_size = Nx )
99 PARAMETER ( y_size = Ny )
100 #endif
101 Real*4 xy_buffer_r4(x_size,y_size)
102 Real*4 r4seg(sNx)
103 Real*8 r8seg(sNx)
104 Real*8 xy_buffer_r8(x_size,y_size)
105 Real*8 globalBuf(Nx,Ny)
106 #ifdef ALLOW_EXCH2
107 INTEGER iGjLoc, jGjLoc
108 c INTEGER tGy,tGx,tNy,tNx,tN
109 INTEGER tGy,tGx, tNx,tN
110 #endif /* ALLOW_EXCH2 */
111 INTEGER tNy
112
113
114 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
115
116 C Assume nothing
117 globalFile = .FALSE.
118 fileIsOpen = .FALSE.
119 IL = ILNBLNK( fName )
120 pIL = ILNBLNK( mdsioLocalDir )
121
122 C Only do I/O if I am the master thread (and mpi process 0 IF useSingleCpuIO):
123 iAmDoingIO = MASTER_CPU_IO(myThid)
124
125 C Only do I/O if I am the master thread
126 IF ( iAmDoingIO ) THEN
127
128 C Record number must be >= 1
129 IF (irecord .LT. 1) THEN
130 WRITE(msgBuf,'(A,I9.8)')
131 & ' MDS_READ_FIELD: argument irecord = ',irecord
132 CALL PRINT_MESSAGE( msgBuf, standardMessageUnit,
133 & SQUEEZE_RIGHT , myThid)
134 WRITE(msgBuf,'(A)')
135 & ' MDS_READ_FIELD: Invalid value for irecord'
136 CALL PRINT_ERROR( msgBuf, myThid )
137 STOP 'ABNORMAL END: S/R MDS_READ_FIELD'
138 ENDIF
139
140 C Assign special directory
141 IF ( useCurrentDir .OR. pIL.EQ.0 ) THEN
142 pfName= fName
143 ELSE
144 WRITE(pfName,'(2a)') mdsioLocalDir(1:pIL), fName(1:IL)
145 ENDIF
146 pIL=ILNBLNK( pfName )
147
148 C Assign a free unit number as the I/O channel for this routine
149 CALL MDSFINDUNIT( dUnit, myThid )
150
151 C Check first for global file with simple name (ie. fName)
152 dataFName = fName
153 INQUIRE( file=dataFName, exist=exst )
154 IF (exst) THEN
155 IF ( debugLevel .GE. debLevA ) THEN
156 WRITE(msgBuf,'(A,A)')
157 & ' MDS_READ_FIELD: opening global file: ',dataFName(1:IL)
158 #ifndef ALLOW_ECCO
159 CALL PRINT_MESSAGE( msgBuf, standardMessageUnit,
160 & SQUEEZE_RIGHT , myThid)
161 #endif
162 ENDIF
163 globalFile = .TRUE.
164 ENDIF
165
166 C If negative check for global file with MDS name (ie. fName.data)
167 IF (.NOT. globalFile) THEN
168 WRITE(dataFName,'(2a)') fName(1:IL),'.data'
169 INQUIRE( file=dataFName, exist=exst )
170 IF (exst) THEN
171 IF ( debugLevel .GE. debLevA ) THEN
172 WRITE(msgBuf,'(A,A)')
173 & ' MDS_READ_FIELD: opening global file: ',dataFName(1:IL+5)
174 #ifndef ALLOW_ECCO
175 CALL PRINT_MESSAGE( msgBuf, standardMessageUnit,
176 & SQUEEZE_RIGHT , myThid)
177 #endif
178 ENDIF
179 globalFile = .TRUE.
180 ENDIF
181 ENDIF
182
183 C- endif iAmDoingIO
184 ENDIF
185
186 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
187
188 IF ( useSingleCPUIO ) THEN
189
190 C master thread of process 0, only, opens a global file
191 IF ( iAmDoingIO ) THEN
192 C If global file is visible to process 0, then open it here.
193 C Otherwise stop program.
194 IF ( globalFile) THEN
195 length_of_rec=MDS_RECLEN( filePrec, x_size*y_size, myThid )
196 OPEN( dUnit, file=dataFName, status='old',
197 & access='direct', recl=length_of_rec )
198 ELSE
199 WRITE(msgBuf,'(2A)')
200 & ' MDS_READ_FIELD: filename: ', dataFName(1:IL+5)
201 CALL PRINT_MESSAGE( msgBuf, standardMessageUnit,
202 & SQUEEZE_RIGHT , myThid)
203 CALL PRINT_ERROR( msgBuf, myThid )
204 WRITE(msgBuf,'(A)')
205 & ' MDS_READ_FIELD: File does not exist'
206 CALL PRINT_MESSAGE( msgBuf, standardMessageUnit,
207 & SQUEEZE_RIGHT , myThid)
208 CALL PRINT_ERROR( msgBuf, myThid )
209 STOP 'ABNORMAL END: S/R MDS_READ_FIELD'
210 ENDIF
211 C- endif iAmDoingIO
212 ENDIF
213
214 DO k=1,nNz
215
216 C master thread of process 0, only, read from file
217 IF ( iAmDoingIO ) THEN
218 irec = k+nNz*(irecord-1)
219 IF (filePrec .EQ. precFloat32) THEN
220 READ(dUnit,rec=irec) xy_buffer_r4
221 #ifdef _BYTESWAPIO
222 CALL MDS_BYTESWAPR4( x_size*y_size, xy_buffer_r4 )
223 #endif
224 ELSEIF (filePrec .EQ. precFloat64) THEN
225 READ(dUnit,rec=irec) xy_buffer_r8
226 #ifdef _BYTESWAPIO
227 CALL MDS_BYTESWAPR8( x_size*y_size, xy_buffer_r8 )
228 #endif
229 ELSE
230 WRITE(msgBuf,'(A)')
231 & ' MDS_READ_FIELD: illegal value for filePrec'
232 CALL PRINT_ERROR( msgBuf, myThid )
233 STOP 'ABNORMAL END: S/R MDS_READ_FIELD'
234 ENDIF
235
236 #if defined(ALLOW_EXCH2) && !defined(MISSING_TILE_IO)
237 bj=1
238 DO npe=1,nPx*nPy
239 DO bi=1,nSx
240 #ifdef ALLOW_USE_MPI
241 loc_xGlobalLo = mpi_myXGlobalLo(npe)
242 loc_yGlobalLo = mpi_myYGlobalLo(npe)
243 #else /* ALLOW_USE_MPI */
244 loc_xGlobalLo = myXGlobalLo
245 loc_yGlobalLo = myYGlobalLo
246 #endif /* ALLOW_USE_MPI */
247 tN = W2_mpi_myTileList(npe,bi)
248 IF ( exch2_mydNx(tN) .GT. x_size ) THEN
249 C- face x-size larger than glob-size : fold it
250 iGjLoc = 0
251 jGjLoc = exch2_mydNx(tN) / x_size
252 ELSEIF ( exch2_tNy(tN) .GT. y_size ) THEN
253 C- tile y-size larger than glob-size : make a long line
254 iGjLoc = exch2_mydNx(tN)
255 jGjLoc = 0
256 ELSE
257 C- default (face fit into global-IO-array)
258 iGjLoc = 0
259 jGjLoc = 1
260 ENDIF
261
262 IF (filePrec .EQ. precFloat32) THEN
263 DO J=1,sNy
264 DO I=1,sNx
265 iG = loc_xGlobalLo-1+(bi-1)*sNx+i
266 jG = loc_yGlobalLo-1+(bj-1)*sNy+j
267 iG_IO=exch2_txGlobalo(tN)+iGjLoc*(j-1)+i-1
268 jG_IO=exch2_tyGlobalo(tN)+jGjLoc*(j-1)
269 globalBuf(iG,jG) = xy_buffer_r4(iG_IO,jG_IO)
270 ENDDO
271 ENDDO
272 ELSEIF (filePrec .EQ. precFloat64) THEN
273 DO J=1,sNy
274 DO I=1,sNx
275 iG = loc_xGlobalLo-1+(bi-1)*sNx+i
276 jG = loc_yGlobalLo-1+(bj-1)*sNy+j
277 iG_IO=exch2_txGlobalo(tN)+iGjLoc*(j-1)+i-1
278 jG_IO=exch2_tyGlobalo(tN)+jGjLoc*(j-1)
279 globalBuf(iG,jG) = xy_buffer_r8(iG_IO,jG_IO)
280 ENDDO
281 ENDDO
282 ENDIF
283
284 C-- end of npe & bi loops
285 ENDDO
286 ENDDO
287 #else /* defined(ALLOW_EXCH2) && !defined(MISSING_TILE_IO) */
288 IF (filePrec .EQ. precFloat32) THEN
289 DO J=1,Ny
290 DO I=1,Nx
291 globalBuf(I,J) = xy_buffer_r4(I,J)
292 ENDDO
293 ENDDO
294 ELSEIF (filePrec .EQ. precFloat64) THEN
295 DO J=1,Ny
296 DO I=1,Nx
297 globalBuf(I,J) = xy_buffer_r8(I,J)
298 ENDDO
299 ENDDO
300 ENDIF
301 #endif /* defined(ALLOW_EXCH2) && !defined(MISSING_TILE_IO) */
302 C- endif iAmDoingIO
303 ENDIF
304 CALL SCATTER_2D(globalBuf,sharedLocalBuf,myThid)
305 IF (arrType .EQ. 'RS') THEN
306 CALL MDS_PASStoRS( sharedLocalBuf,arr,k,zSize,.TRUE.,myThid )
307 ELSEIF (arrType .EQ. 'RL') THEN
308 CALL MDS_PASStoRL( sharedLocalBuf,arr,k,zSize,.TRUE.,myThid )
309 ELSE
310 WRITE(msgBuf,'(A)')
311 & ' MDS_READ_FIELD: illegal value for arrType'
312 CALL PRINT_ERROR( msgBuf, myThid )
313 STOP 'ABNORMAL END: S/R MDS_READ_FIELD'
314 ENDIF
315
316 ENDDO
317 c ENDDO k=1,nNz
318
319 IF ( iAmDoingIO ) THEN
320 CLOSE( dUnit )
321 ENDIF
322
323 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
324 C--- else .NOT.useSingleCpuIO
325 ELSE
326
327 C Only do I/O if I am the master thread
328 IF ( iAmDoingIO ) THEN
329
330 C If we are reading from a global file then we open it here
331 IF (globalFile) THEN
332 length_of_rec=MDS_RECLEN( filePrec, sNx, myThid )
333 OPEN( dUnit, file=dataFName, status='old',
334 & access='direct', recl=length_of_rec )
335 fileIsOpen=.TRUE.
336 ENDIF
337
338 C Loop over all tiles
339 DO bj=1,nSy
340 DO bi=1,nSx
341 C If we are reading from a tiled MDS file then we open each one here
342 IF (.NOT. globalFile) THEN
343 iG=bi+(myXGlobalLo-1)/sNx ! Kludge until unstructered tiles
344 jG=bj+(myYGlobalLo-1)/sNy ! Kludge until unstructered tiles
345 WRITE(dataFName,'(2A,I3.3,A,I3.3,A)')
346 & pfName(1:pIL),'.',iG,'.',jG,'.data'
347 INQUIRE( file=dataFName, exist=exst )
348 C Of course, we only open the file if the tile is "active"
349 C (This is a place-holder for the active/passive mechanism
350 IF (exst) THEN
351 IF ( debugLevel .GE. debLevA ) THEN
352 WRITE(msgBuf,'(A,A)')
353 & ' MDS_READ_FIELD: opening file: ',dataFName(1:pIL+13)
354 CALL PRINT_MESSAGE( msgBuf, standardMessageUnit,
355 & SQUEEZE_RIGHT , myThid)
356 ENDIF
357 length_of_rec=MDS_RECLEN( filePrec, sNx, myThid )
358 OPEN( dUnit, file=dataFName, status='old',
359 & access='direct', recl=length_of_rec )
360 fileIsOpen=.TRUE.
361 ELSE
362 fileIsOpen=.FALSE.
363 WRITE(msgBuf,'(4A)') ' MDS_READ_FIELD: filename: ',
364 & fName(1:IL),' , ', dataFName(1:pIL+13)
365 CALL PRINT_MESSAGE( msgBuf, standardMessageUnit,
366 & SQUEEZE_RIGHT , myThid)
367 CALL PRINT_ERROR( msgBuf, myThid )
368 WRITE(msgBuf,'(A)')
369 & ' MDS_READ_FIELD: Files DO not exist'
370 CALL PRINT_MESSAGE( msgBuf, standardMessageUnit,
371 & SQUEEZE_RIGHT , myThid)
372 CALL PRINT_ERROR( msgBuf, myThid )
373 STOP 'ABNORMAL END: S/R MDS_READ_FIELD'
374 ENDIF
375 ENDIF
376
377 IF (fileIsOpen) THEN
378 tNy = sNy
379 #ifdef ALLOW_EXCH2
380 tN = W2_myTileList(bi)
381 tGy = exch2_tyGlobalo(tN)
382 tGx = exch2_txGlobalo(tN)
383 tNy = exch2_tNy(tN)
384 tNx = exch2_tNx(tN)
385 IF ( exch2_mydNx(tN) .GT. x_size ) THEN
386 C- face x-size larger than glob-size : fold it
387 iGjLoc = 0
388 jGjLoc = exch2_mydNx(tN) / x_size
389 ELSEIF ( exch2_tNy(tN) .GT. y_size ) THEN
390 C- tile y-size larger than glob-size : make a long line
391 iGjLoc = exch2_mydNx(tN)
392 jGjLoc = 0
393 ELSE
394 C- default (face fit into global-IO-array)
395 iGjLoc = 0
396 jGjLoc = 1
397 ENDIF
398 #endif /* ALLOW_EXCH2 */
399 DO k=1,nNz
400 DO j=1,tNy
401 IF (globalFile) THEN
402 #ifdef ALLOW_EXCH2
403 irec = 1 + ( tGx-1 + (j-1)*iGjLoc )/tNx
404 & + ( tGy-1 + (j-1)*jGjLoc )*exch2_domain_nxt
405 & + ( k-1 + (irecord-1)*nNz
406 & )*y_size*exch2_domain_nxt
407 #else /* ALLOW_EXCH2 */
408 iG = myXGlobalLo-1 + (bi-1)*sNx
409 jG = myYGlobalLo-1 + (bj-1)*sNy
410 irec= 1 + INT(iG/sNx) + nSx*nPx*(jG+j-1)
411 & + nSx*nPx*Ny*(k-1)
412 & + nSx*nPx*Ny*nNz*(irecord-1)
413 #endif /* ALLOW_EXCH2 */
414 ELSE
415 irec=j + sNy*(k-1) + sNy*nNz*(irecord-1)
416 ENDIF
417 IF (filePrec .EQ. precFloat32) THEN
418 READ(dUnit,rec=irec) r4seg
419 #ifdef _BYTESWAPIO
420 CALL MDS_BYTESWAPR4( sNx, r4seg )
421 #endif
422 IF (arrType .EQ. 'RS') THEN
423 CALL MDS_SEG4toRS( j,bi,bj,k,zSize, r4seg, .TRUE., arr )
424 ELSEIF (arrType .EQ. 'RL') THEN
425 CALL MDS_SEG4toRL( j,bi,bj,k,zSize, r4seg, .TRUE., arr )
426 ELSE
427 WRITE(msgBuf,'(A)')
428 & ' MDS_READ_FIELD: illegal value for arrType'
429 CALL PRINT_ERROR( msgBuf, myThid )
430 STOP 'ABNORMAL END: S/R MDS_READ_FIELD'
431 ENDIF
432 ELSEIF (filePrec .EQ. precFloat64) THEN
433 READ(dUnit,rec=irec) r8seg
434 #ifdef _BYTESWAPIO
435 CALL MDS_BYTESWAPR8( sNx, r8seg )
436 #endif
437 IF (arrType .EQ. 'RS') THEN
438 CALL MDS_SEG8toRS( j,bi,bj,k,zSize, r8seg, .TRUE., arr )
439 ELSEIF (arrType .EQ. 'RL') THEN
440 CALL MDS_SEG8toRL( j,bi,bj,k,zSize, r8seg, .TRUE., arr )
441 ELSE
442 WRITE(msgBuf,'(A)')
443 & ' MDS_READ_FIELD: illegal value for arrType'
444 CALL PRINT_ERROR( msgBuf, myThid )
445 STOP 'ABNORMAL END: S/R MDS_READ_FIELD'
446 ENDIF
447 ELSE
448 WRITE(msgBuf,'(A)')
449 & ' MDS_READ_FIELD: illegal value for filePrec'
450 CALL PRINT_ERROR( msgBuf, myThid )
451 STOP 'ABNORMAL END: S/R MDS_READ_FIELD'
452 ENDIF
453 C End of j loop
454 ENDDO
455 C End of k loop
456 ENDDO
457 C end if fileIsOpen
458 ENDIF
459 IF (fileIsOpen .AND. (.NOT. globalFile)) THEN
460 CLOSE( dUnit )
461 fileIsOpen = .FALSE.
462 ENDIF
463 C End of bi,bj loops
464 ENDDO
465 ENDDO
466
467 C If global file was opened then close it
468 IF (fileIsOpen .AND. globalFile) THEN
469 CLOSE( dUnit )
470 fileIsOpen = .FALSE.
471 ENDIF
472
473 C- endif iAmDoingIO
474 ENDIF
475
476 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
477 C if useSingleCpuIO / else / end
478 ENDIF
479
480 RETURN
481 END

  ViewVC Help
Powered by ViewVC 1.1.22