source: CPL/oasis3/trunk/src/lib/psmile/src/mod_prism_grids_writing.F90 @ 1677

Last change on this file since 1677 was 1677, checked in by aclsce, 12 years ago

Imported oasis3 (tag ipslcm5a) from cvs server to svn server (igcmg project).

File size: 37.2 KB
Line 
1#define __VERBOSE
2!-----------------------------------------------------------------------
3! BOP
4!
5! !MODULE:  mod_prism_grids_writing
6! !REMARKS:
7! !REVISION HISTORY:
8! 2003.07.07 Veronika Gayler initial version
9!
10! !PUBLIC MEMBER FUNCTIONS:
11!
12!      subroutine prism_start_grids_writing(iwrite)
13!             This subroutine initializes grids writing by receiving a
14!             starting command from OASIS.
15!
16!      subroutine prism_write_grid(cgrid, nx, ny, lon, lat)
17!             This subroutine writes longitudes and latitudes for a model
18!             grid.
19!
20!      subroutine prism_write_corner(cgrid, nx, ny, nc, clon, clat)
21!             This subroutine writes the longitudes and latitudes of the
22!             grid cell corners.
23!
24!      subroutine prism_write_mask(cgrid, nx, ny, mask)
25!             This subroutine writes the mask for a model grid
26!
27!      subroutine prism_write_area(cgrid, nx, ny, area)
28!             This subroutine writes the grid cell areas for a model grid.
29!
30!      subroutine prism_terminate_grids_writing()
31!             This subroutine terminates grids writing by sending a flag
32!             to OASIS, stating the all needed grid information was written.
33!       
34
35MODULE mod_prism_grids_writing
36
37! !USES:
38  USE mod_kinds_model
39  USE mod_comprism_proto
40 
41  IMPLICIT NONE
42#include <mpif.h>
43 
44  INTEGER(kind=ip_intwp_p), PARAMETER :: itagcol=9876
45  INTEGER(kind=ip_intwp_p)  :: tag          ! MPI message tag
46  INTEGER(kind=ip_intwp_p)  :: len          ! MPI message length
47  INTEGER(kind=ip_intwp_p)  :: type         ! MPI message type
48  LOGICAL        :: gridswrite      ! grid writing is needed
49  LOGICAL        :: netcdf          ! grids file format is netCDF
50  CHARACTER*5    :: cgrdnam         ! grids file name
51  CHARACTER*5    :: cmsknam         ! masks file name
52  CHARACTER*5    :: csurnam         ! areas file name
53  CHARACTER*4    :: cglonsuf        ! suffix for longitudes
54  CHARACTER*4    :: cglatsuf        ! suffix for latitudes
55  CHARACTER*4    :: crnlonsuf       ! suffix for longitudes
56  CHARACTER*4    :: crnlatsuf       ! suffix for latitudes
57  CHARACTER*4    :: cmsksuf         ! suffix for masks
58  CHARACTER*4    :: csursuf         ! suffix for areas
59!---------------------------------------------------------------------------
60
61CONTAINS
62
63!--------------------------------------------------------------------------
64!
65  SUBROUTINE prism_start_grids_writing(iwrite)
66!--------------------------------------------------------------------------
67! Routine to start the grids writing. To syncronize access to the
68! grids file all component models have to wait for the starting
69! message from OASIS (via MPI; see prism_init_comp_proto)
70!--------------------------------------------------------------------------
71    IMPLICIT NONE
72 
73    INTEGER(kind=ip_intwp_p), INTENT (OUT) :: iwrite ! flag to state whether
74                                            ! grids file needs to be written
75    INTEGER(kind=ip_intwp_p) :: source   ! rank of the sending process
76    INTEGER(kind=ip_intwp_p), DIMENSION(MPI_STATUS_SIZE) :: status
77
78!--------------------------------------------------------------------------
79
80#ifdef __VERBOSE
81    write(nulprt,*) ' '
82    write(nulprt,*) 'Start - - prism_start_grids_writing'
83    CALL FLUSH(nulprt)
84#endif
85!
86!-- Initialisation
87!
88    netcdf = .true.
89    gridswrite = .false.
90    iwrite = 0
91    cgrdnam = '-----'
92    cmsknam = '-----'
93    csurnam = '-----'
94    cglonsuf = '----'
95    cglatsuf = '----'
96    crnlonsuf = '----'
97    crnlatsuf = '----'
98    cmsksuf = '----'
99    csursuf = '----'
100    source = 0            ! OASIS: process 0 of global communicator
101
102    IF (grids_start == 1) THEN
103       gridswrite = .true.
104!
105!--    receive grid file name
106!
107       WRITE (nulprt,FMT='(A)') 'Recv - cgrdnam'
108       len = 5
109       type = MPI_CHARACTER
110       tag = itagcol+4
111       CALL MPI_Recv (cgrdnam, len, type, source, tag, mpi_comm, status,mpi_err)
112       IF (mpi_err == MPI_SUCCESS) THEN
113          WRITE(nulprt,FMT='(A,I2,A,I6,A,I2,A,I3,A,I5,A,A5)') &
114               'Recv - <from:',source,'> <comm:',mpi_comm,'> <len:',len,  &
115               '> <type:',type,'> <tag:',tag,'> ::  ',cgrdnam
116          CALL FLUSH(nulprt)
117       ELSE
118          WRITE (nulprt,*) ' '
119          WRITE (nulprt,*) 'start_grids_writing: error receiving cgrdnam'
120          WRITE (nulprt,*) 'start_grids_writing: err= ', mpi_err 
121          WRITE (nulprt,*) 'start_grids_writing: STOP'
122          STOP
123       ENDIF
124!
125!--    receive masks file name
126!
127       WRITE (nulprt,FMT='(A)') 'Recv - cmsknam'
128       len = 5
129       type = MPI_CHARACTER
130       tag = itagcol+5
131       CALL MPI_Recv (cmsknam, len, type, source, tag, mpi_comm, status,mpi_err)
132       IF (mpi_err == MPI_SUCCESS) THEN
133          WRITE(nulprt,FMT='(A,I2,A,I6,A,I2,A,I3,A,I5,A,A5)') &
134               'Recv - <from:',source,'> <comm:',mpi_comm,'> <len:',len,  &
135               '> <type:',type,'> <tag:',tag,'> ::  ',cmsknam
136          CALL FLUSH(nulprt)
137       ELSE
138          WRITE (nulprt,*) ' '
139          WRITE (nulprt,*) 'start_grids_writing: error receiving cmsknam'
140          WRITE (nulprt,*) 'start_grids_writing: err= ', mpi_err 
141          WRITE (nulprt,*) 'start_grids_writing: STOP'
142          STOP
143       ENDIF
144!
145!--    receive areas file name
146!
147       WRITE (nulprt,FMT='(A)') 'Recv - csurnam'
148       len = 5
149       type = MPI_CHARACTER
150       tag = itagcol+6
151       CALL MPI_Recv (csurnam, len, type, source, tag, mpi_comm, status,mpi_err)
152       IF (mpi_err == MPI_SUCCESS) THEN
153          WRITE(nulprt,FMT='(A,I2,A,I6,A,I2,A,I3,A,I5,A,A5)') &
154               'Recv - <from:',source,'> <comm:',mpi_comm,'> <len:',len, &
155               '> <type:',type,'> <tag:',tag,'> ::  ',csurnam
156          CALL FLUSH(nulprt)
157       ELSE
158          WRITE (nulprt,*) ' '
159          WRITE (nulprt,*) 'start_grids_writing: error receiving csurnam'
160          WRITE (nulprt,*) 'start_grids_writing: err= ', mpi_err 
161          WRITE (nulprt,*) 'start_grids_writing: STOP'
162          STOP
163       ENDIF
164!
165!--    receive suffix for longitudes
166!
167       WRITE (nulprt,FMT='(A)') 'Recv - cglonsuf'
168       len = 4
169       type = MPI_CHARACTER
170       tag = itagcol+7
171       CALL MPI_Recv (cglonsuf, len, type, source, tag, mpi_comm,status,mpi_err)
172       IF (mpi_err == MPI_SUCCESS) THEN
173          WRITE(nulprt,FMT='(A,I2,A,I6,A,I2,A,I3,A,I5,A,A4)') &
174               'Recv - <from:',source,'> <comm:',mpi_comm,'> <len:',len, &
175               '> <type:',type,'> <tag:',tag,'> ::  ',cglonsuf
176          CALL FLUSH(nulprt)
177       ELSE
178          WRITE (nulprt,*) ' '
179          WRITE (nulprt,*) 'start_grids_writing: error receiving cglonsuf'
180          WRITE (nulprt,*) 'start_grids_writing: err= ', mpi_err 
181          WRITE (nulprt,*) 'start_grids_writing: STOP'
182          STOP
183       ENDIF
184!
185!--    receive suffix for latitudes
186!
187       WRITE (nulprt,FMT='(A)') 'Recv - cglatsuf'
188       len = 4
189       type = MPI_CHARACTER
190       tag = itagcol+8
191       CALL MPI_Recv (cglatsuf, len, type, source, tag, mpi_comm,status,mpi_err)
192       IF (mpi_err == MPI_SUCCESS) THEN
193          WRITE(nulprt,FMT='(A,I2,A,I6,A,I2,A,I3,A,I5,A,A4)') &
194               'Recv - <from:',source,'> <comm:',mpi_comm,'> <len:',len, &
195               '> <type:',type,'> <tag:',tag,'> ::  ',cglatsuf
196          CALL FLUSH(nulprt)
197       ELSE
198          WRITE (nulprt,*) ' '
199          WRITE (nulprt,*) 'start_grids_writing: error receiving cglatsuf'
200          WRITE (nulprt,*) 'start_grids_writing: err= ', mpi_err 
201          WRITE (nulprt,*) 'start_grids_writing: STOP'
202          STOP
203       ENDIF
204!
205!--    receive suffix for longitudes of grid cell corners
206!
207       WRITE (nulprt,FMT='(A)') 'Recv - crnlonsuf'
208       len = 4
209       type = MPI_CHARACTER
210       tag = itagcol+9
211       CALL MPI_Recv (crnlonsuf, len, type, source, tag, mpi_comm,status,mpi_err)
212       IF (mpi_err == MPI_SUCCESS) THEN
213          WRITE(nulprt,FMT='(A,I2,A,I6,A,I2,A,I3,A,I5,A,A4)') &
214               'Recv - <from:',source,'> <comm:',mpi_comm,'> <len:',len, &
215               '> <type:',type,'> <tag:',tag,'> ::  ',crnlonsuf
216          CALL FLUSH(nulprt)
217       ELSE
218          WRITE (nulprt,*) ' '
219          WRITE (nulprt,*) 'start_grids_writing: error receiving crnlonsuf'
220          WRITE (nulprt,*) 'start_grids_writing: err= ', mpi_err
221          WRITE (nulprt,*) 'start_grids_writing: STOP'
222          STOP
223       ENDIF
224!
225!--    receive suffix for latitudes
226!
227       WRITE (nulprt,FMT='(A)') 'Recv - crnlatsuf'
228       len = 4
229       type = MPI_CHARACTER
230       tag = itagcol+10
231       CALL MPI_Recv (crnlatsuf, len, type, source, tag, mpi_comm,status,mpi_err)
232       IF (mpi_err == MPI_SUCCESS) THEN
233          WRITE(nulprt,FMT='(A,I2,A,I6,A,I2,A,I3,A,I5,A,A4)') &
234               'Recv - <from:',source,'> <comm:',mpi_comm,'> <len:',len, &
235               '> <type:',type,'> <tag:',tag,'> ::  ',crnlatsuf
236          CALL FLUSH(nulprt)
237       ELSE
238          WRITE (nulprt,*) ' '
239          WRITE (nulprt,*) 'start_grids_writing: error receiving crnlatsuf'
240          WRITE (nulprt,*) 'start_grids_writing: err= ', mpi_err 
241          WRITE (nulprt,*) 'start_grids_writing: STOP'
242          STOP
243       ENDIF
244!
245!--    receive suffix for masks
246!
247       WRITE (nulprt,FMT='(A)') 'Recv - cmsksuf'
248       len = 4
249       type = MPI_CHARACTER
250       tag = itagcol+11
251       CALL MPI_Recv (cmsksuf, len, type, source, tag, mpi_comm, status,mpi_err)
252       IF (mpi_err == MPI_SUCCESS) THEN
253          WRITE(nulprt,FMT='(A,I2,A,I6,A,I2,A,I3,A,I5,A,A4)') &
254               'Recv - <from:',source,'> <comm:',mpi_comm,'> <len:',len, &
255               '> <type:',type,'> <tag:',tag,'> ::  ',cmsksuf
256          CALL FLUSH(nulprt)
257       ELSE
258          WRITE (nulprt,*) ' '
259          WRITE (nulprt,*) 'start_grids_writing: error receiving cmsksuf'
260          WRITE (nulprt,*) 'start_grids_writing: err= ', mpi_err 
261          WRITE (nulprt,*) 'start_grids_writing: STOP'
262          STOP
263       ENDIF
264!
265!--    receive suffix for areas
266!
267       WRITE (nulprt,FMT='(A)') 'Recv - csursuf'
268       len = 4
269       type = MPI_CHARACTER
270       tag = itagcol+12
271       CALL MPI_Recv (csursuf, len, type, source, tag, mpi_comm, status,mpi_err)
272       IF (mpi_err == MPI_SUCCESS) THEN
273          WRITE(nulprt,FMT='(A,I2,A,I6,A,I2,A,I3,A,I5,A,A4)') &
274               'Recv - <from:',source,'> <comm:',mpi_comm,'> <len:',len, &
275               '> <type:',type,'> <tag:',tag,'> ::  ',csursuf
276          CALL FLUSH(nulprt)
277       ELSE
278          WRITE (nulprt,*) ' '
279          WRITE (nulprt,*) 'start_grids_writing: error receiving csursuf'
280          WRITE (nulprt,*) 'start_grids_writing: err= ', mpi_err 
281          WRITE (nulprt,*) 'start_grids_writing: STOP'
282          STOP
283       ENDIF
284
285#ifdef __VERBOSE
286       WRITE (nulprt,*) ' '
287       WRITE (nulprt,*) '  grids file name:              ', cgrdnam
288       WRITE (nulprt,*) '  masks file name:              ', cmsknam
289       WRITE (nulprt,*) '  areas file name:              ', csurnam
290       WRITE (nulprt,*) '  suffix for longitudes:        ', cglonsuf
291       WRITE (nulprt,*) '  suffix for latitudes:         ', cglatsuf
292       WRITE (nulprt,*) '  suffix for corner longitudes: ', crnlonsuf
293       WRITE (nulprt,*) '  suffix for corner latitudes:  ', crnlatsuf
294       WRITE (nulprt,*) '  suffix for masks:             ', cmsksuf
295       WRITE (nulprt,*) '  suffix for areas:             ', csursuf
296       CALL FLUSH(nulprt)
297#endif
298
299   ELSE IF (grids_start == 0) THEN
300!
301!--     grids file already exists, no writing needed
302!
303#ifdef __VERBOSE
304       WRITE (nulprt,*) '  grids file exists, no writing needed'
305       CALL FLUSH(nulprt)
306#endif
307       gridswrite = .false.
308    ELSE
309       WRITE (nulprt,*) ' '
310       WRITE (nulprt,*) 'start_grids_writing: no valid flag received'
311       WRITE (nulprt,*) 'start_grids_writing: grids_start= ', grids_start 
312       WRITE (nulprt,*) 'start_grids_writing: STOP'
313       STOP         
314    ENDIF
315
316    IF (gridswrite) THEN
317       iwrite = 1
318    ENDIF
319
320#ifdef __VERBOSE
321    write(nulprt,*) 'End - - prism_start_grids_writing'
322    write(nulprt,*) ''
323    CALL FLUSH(nulprt)
324#endif
325    RETURN
326
327  END SUBROUTINE prism_start_grids_writing
328
329!--------------------------------------------------------------------------
330!
331  SUBROUTINE prism_write_grid(cgrid, nx, ny, lon, lat)
332!--------------------------------------------------------------------------
333! Routine to create a new grids file or to add a grid description to an
334! existing grids file.
335!--------------------------------------------------------------------------
336    IMPLICIT NONE
337
338    INCLUDE 'netcdf.inc'
339
340    CHARACTER*4,              INTENT (IN) :: cgrid      ! grid acronym
341    INTEGER(kind=ip_intwp_p), INTENT (IN) :: nx         ! number of longitudes
342    INTEGER(kind=ip_intwp_p), INTENT (IN) :: ny         ! number of latitudes
343    REAL(kind=ip_realwp_p),   INTENT (IN) :: lon(nx,ny) ! longitudes
344    REAL(kind=ip_realwp_p),   INTENT (IN) :: lat(nx,ny) ! latitudes
345
346    INTEGER(kind=ip_intwp_p) :: iost         ! i/o status
347    INTEGER(kind=ip_intwp_p) :: nulgrd       ! logical unit of grids file
348    INTEGER(kind=ip_intwp_p) :: stat         ! netcdf status
349    INTEGER(kind=ip_intwp_p) :: ncid         ! netcdf file id
350    INTEGER(kind=ip_intwp_p) :: idx, idy     ! netcdf dimension ids
351    INTEGER(kind=ip_intwp_p) :: idlon, idlat ! netcdf variable ids
352    INTEGER(kind=ip_intwp_p) :: dims(2)      ! netcdf variable dimensions
353
354    LOGICAL :: existent    !true if grids file is already existing
355    LOGICAL :: grdopen     !true if grids file is opened
356
357    CHARACTER*8 :: clon    !locator sring (binary) / variable name (netcdf)
358    CHARACTER*8 :: clat    !locator sring (binary) / variable name (netcdf)
359   
360!--------------------------------------------------------------------------
361
362#ifdef __VERBOSE
363    write(nulprt,*) ' '
364    write(nulprt,*) 'Start - - prism_write_grid'
365    write(nulprt,*) '  grid acronym: ', cgrid
366    CALL FLUSH(nulprt)
367#endif
368!
369!-- Return, if grids files already exists
370!
371    IF (.NOT. gridswrite) THEN
372       write(nulprt,*) ' '
373       write(nulprt,*) 'No grid writing needed'
374       RETURN
375    ENDIF
376
377    IF (netcdf) THEN
378!      -------------
379!--    netCDF format
380!      -------------
381!
382!      open grids file
383!      ---------------
384       stat = NF_OPEN(cgrdnam//'.nc', NF_WRITE, ncid)
385       IF (stat /= NF_NOERR) THEN
386           stat = NF_CREATE(cgrdnam//'.nc', NF_CLOBBER, ncid)
387          IF (stat /= NF_NOERR) THEN
388             WRITE (nulprt,*) 'prism_write_grid: error opening grids file.'
389             WRITE (nulprt,*) 'prism_write_grid: STOP'
390             STOP
391          ENDIF
392       ENDIF
393!
394!--   define dimensions
395!     -----------------
396      stat = NF_REDEF(ncid)
397      stat = NF_INQ_DIMID(ncid, 'x_'//cgrid, idx)
398      IF (stat .NE. NF_NOERR) THEN
399          stat = NF_DEF_DIM(ncid, 'x_'//cgrid, nx, idx)
400          IF (stat /= NF_NOERR) THEN
401              WRITE (nulprt,*) 'ERROR defining dimension x_',cgrid
402          ENDIF
403      ELSE
404          WRITE(nulprt,*)'Grid already defined: ', cgrid
405          RETURN
406      ENDIF
407      stat = NF_DEF_DIM(ncid, 'y_'//cgrid, ny, idy)
408      IF (stat /= NF_NOERR) THEN
409          WRITE (nulprt,*) 'ERROR defining dimension y_',cgrid
410      ENDIF
411
412      dims(1) = idx
413      dims(2) = idy
414!
415!--   define longitudes
416!     -----------------
417      clon=cgrid//cglonsuf
418      stat = NF_DEF_VAR (ncid, clon , NF_DOUBLE, 2, dims, idlon)
419      IF (stat /= NF_NOERR) THEN
420          WRITE (nulprt,*) 'ERROR defining variable ', clon
421      ENDIF
422      stat = NF_PUT_ATT_TEXT(ncid,idlon,'long_name',18,'Longitudes of '//cgrid)
423      IF (stat /= NF_NOERR) THEN
424          WRITE (nulprt,*) 'ERROR creating att. for longitudes of ', cgrid
425      ENDIF
426      stat = NF_PUT_ATT_TEXT(ncid, idlon, 'units', 8, 'degree_E')
427      IF (stat /= NF_NOERR) THEN
428          WRITE (nulprt,*) 'ERROR creating att. for longitudes of ', cgrid
429      ENDIF
430!
431!--   define latitudes
432!     ----------------
433      clat=cgrid//cglatsuf
434      stat = NF_DEF_VAR (ncid, clat , NF_DOUBLE, 2, dims, idlat)
435      IF (stat /= NF_NOERR) THEN
436         WRITE (nulprt,*) 'ERROR defining variable ', clat
437      ENDIF
438      stat = NF_PUT_ATT_TEXT(ncid, idlat,'long_name',17,'Latitudes of '//cgrid)
439      IF (stat /= NF_NOERR) THEN
440         WRITE (nulprt,*) 'ERROR creating att. for latitudes of ', cgrid
441      ENDIF
442      stat = NF_PUT_ATT_TEXT(ncid, idlat, 'units', 8, 'degree_N')
443      IF (stat /= NF_NOERR) THEN
444         WRITE (nulprt,*) 'ERROR creating att. for latitudes of ', cgrid
445      ENDIF
446!
447!--   switch to data mode
448!     -------------------
449      stat = NF_ENDDEF(ncid)
450      IF (stat /= NF_NOERR) THEN
451         WRITE (nulprt,*) 'ERROR: file ', ncid, ' still in define mode'
452      ENDIF
453!
454!--   write longitudes
455!     ----------------
456      stat = NF_PUT_VAR_DOUBLE (ncid, idlon, lon(:,:))
457      IF (stat /= NF_NOERR) THEN
458         WRITE (nulprt,*) 'ERROR writing lonitudes of ', cgrid
459      ENDIF
460!
461!--   write latitudes
462!     ---------------
463      stat = NF_PUT_VAR_DOUBLE (ncid, idlat, lat(:,:))
464      IF (stat /= NF_NOERR) THEN
465         WRITE (nulprt,*) 'ERROR writing latitudes of ', cgrid
466      ENDIF
467!
468!--   close grids file
469!     ----------------
470      stat = NF_CLOSE(ncid)
471      IF (stat /= NF_NOERR) THEN
472         WRITE (nulprt,*) 'ERROR closing file', cgrdnam
473      ENDIF
474     
475    ELSE
476!      -------------
477!--    binary format
478!      -------------
479!
480!      open grids file
481!      ---------------
482       INQUIRE (FILE = cgrdnam, EXIST = existent, OPENED = grdopen)
483       IF (existent .AND. grdopen) THEN
484          WRITE (nulprt,*) ' '
485          WRITE (nulprt,*) 'prism_write_grid: grids file already opened'
486          WRITE (nulprt,*) 'prism_write_grid: STOP'
487          STOP     
488       ENDIF
489       iost = 0
490       nulgrd = 7
491       INQUIRE (nulgrd,OPENED = grdopen)
492       DO WHILE (grdopen)
493          nulgrd = nulgrd + 1 
494          INQUIRE (nulgrd,OPENED = grdopen)
495       END DO
496
497       OPEN (UNIT=nulgrd, FILE=cgrdnam, STATUS='UNKNOWN',                 &
498             ACCESS='SEQUENTIAL', FORM='UNFORMATTED', POSITION='APPEND',  &
499             ACTION='WRITE', IOSTAT=iost, ERR=110)
500
501110    CONTINUE
502       IF (iost /= 0) THEN
503          WRITE (nulprt,*) ' '
504          WRITE (nulprt,*) 'prism_write_grid: Error opening grids file'
505          WRITE (nulprt,*) 'prism_write_grid: STOP'
506          STOP
507       ENDIF
508
509!      write longitudes
510!      ----------------
511       clon=cgrid//cglonsuf
512       WRITE (UNIT = nulgrd) clon
513       WRITE (UNIT = nulgrd) lon(:,:)
514                           
515!      write latitudes     
516!      ----------------   
517       clat=cgrid//cglatsuf
518       WRITE (UNIT = nulgrd) clat
519       WRITE (UNIT = nulgrd) lat(:,:)
520
521!      close grids file
522!      ----------------
523       CLOSE (nulgrd)
524
525    ENDIF
526
527#ifdef __VERBOSE
528    write(nulprt,*) 'End - - prism_write_grid'
529    CALL FLUSH(nulprt)
530#endif
531
532    RETURN
533
534  END SUBROUTINE prism_write_grid
535!--------------------------------------------------------------------------
536!
537  SUBROUTINE prism_write_corner(cgrid, nx, ny, nc, clon, clat)
538!--------------------------------------------------------------------------
539! Routine to add longitudes and latitudes of grid cell corners to an
540! existing grids file.
541!--------------------------------------------------------------------------
542    IMPLICIT NONE
543
544    INCLUDE 'netcdf.inc'
545
546    CHARACTER*4,              INTENT (IN) :: cgrid  ! grid acronym
547    INTEGER(kind=ip_intwp_p), INTENT (IN) :: nx     ! number of longitudes
548    INTEGER(kind=ip_intwp_p), INTENT (IN) :: ny     ! number of latitudes
549    INTEGER(kind=ip_intwp_p), INTENT (IN) :: nc     ! number of corners per cell
550    REAL(kind=ip_realwp_p),   INTENT (IN) :: clon(nx,ny,nc) ! longitudes
551    REAL(kind=ip_realwp_p),   INTENT (IN) :: clat(nx,ny,nc) ! latitudes
552
553    INTEGER(kind=ip_intwp_p) :: stat           ! netcdf status
554    INTEGER(kind=ip_intwp_p) :: ncid           ! netcdf file id
555    INTEGER(kind=ip_intwp_p) :: idx, idy, idc  ! netcdf dimension ids
556    INTEGER(kind=ip_intwp_p) :: idclon, idclat ! netcdf variable ids
557    INTEGER(kind=ip_intwp_p) :: dims(3)        ! netcdf variable dimensions
558
559    CHARACTER*8 :: crnlon    !locator sring (binary) / variable name (netcdf)
560    CHARACTER*8 :: crnlat    !locator sring (binary) / variable name (netcdf)
561   
562!--------------------------------------------------------------------------
563
564#ifdef __VERBOSE
565    write(nulprt,*) ' '
566    write(nulprt,*) 'Start - - prism_write_corner'
567    write(nulprt,*) '  grid acronym: ', cgrid
568    CALL FLUSH(nulprt)
569#endif
570
571!
572!-- Return, if grids files was written in a former run
573!
574    IF (.NOT. gridswrite) THEN
575       write(nulprt,*) ' '
576       write(nulprt,*) 'No grid writing needed'
577       RETURN
578    ENDIF
579
580    IF (netcdf) THEN
581!      -------------
582!--    netCDF format
583!      -------------
584!
585!      open grids file
586!      ---------------
587       stat = NF_OPEN(cgrdnam//'.nc', NF_WRITE, ncid)
588       IF (stat /= NF_NOERR) THEN
589          WRITE (nulprt,*) ' '
590          WRITE (nulprt,*) 'prism_write_corner: ERROR'
591          WRITE (nulprt,*) 'prism_write_corner:   grids.nc file does not exist!'
592          WRITE (nulprt,*) 'prism_write_corner:   call prism_write_grid first!'
593          WRITE (nulprt,*) 'prism_write_corner:   STOP'
594          STOP
595       ENDIF
596!
597!--   define corner dimensions
598!     ------------------------
599      stat = NF_REDEF(ncid)
600      stat = NF_INQ_DIMID(ncid, 'x_'//cgrid, idx)
601      IF (stat /= NF_NOERR) THEN
602         WRITE (nulprt,*) 'ERROR finding out dimension id of x_',cgrid
603      ENDIF
604      stat = NF_INQ_DIMID(ncid, 'y_'//cgrid, idy)
605      IF (stat /= NF_NOERR) THEN
606         WRITE (nulprt,*) 'ERROR finding out dimension id of y_',cgrid
607      ENDIF
608      stat = NF_DEF_DIM(ncid, 'crn_'//cgrid, nc, idc)
609      IF (stat /= NF_NOERR) THEN
610         WRITE (nulprt,*) 'ERROR defining dimension crn_',cgrid
611      ENDIF
612
613      dims(1) = idx
614      dims(2) = idy
615      dims(3) = idc
616      ig_noc = nc
617!
618!--   define corner longitudes
619!     ------------------------
620      crnlon=cgrid//crnlonsuf
621      stat = NF_INQ_VARID (ncid, crnlon, idclon)
622      IF (stat .NE. NF_NOERR) THEN
623          stat = NF_DEF_VAR (ncid, crnlon , NF_DOUBLE, 3, dims, idclon)
624          IF (stat /= NF_NOERR) THEN
625              WRITE (nulprt,*) 'ERROR defining variable ', crnlon
626          ENDIF
627          stat = NF_PUT_ATT_TEXT   &
628             (ncid,idclon,'long_name',39,'Longitudes of grid cell corners of '//cgrid)
629          IF (stat /= NF_NOERR) THEN
630              WRITE (nulprt,*) 'ERROR creating att. for corner longitudes of ', cgrid
631          ENDIF
632          stat = NF_PUT_ATT_TEXT(ncid, idclon, 'units', 8, 'degree_E')
633          IF (stat /= NF_NOERR) THEN
634              WRITE (nulprt,*) 'ERROR creating att. for corner longitudes of ', cgrid
635          ENDIF
636      ELSE
637          WRITE(nulprt,*)'Corners already defined: ', cgrid
638          RETURN
639      ENDIF
640!
641!--   define corner latitudes
642!     -----------------------
643      crnlat=cgrid//crnlatsuf
644      stat = NF_DEF_VAR (ncid, crnlat , NF_DOUBLE, 3, dims, idclat)
645      IF (stat /= NF_NOERR) THEN
646         WRITE (nulprt,*) 'ERROR defining variable ', crnlat
647      ENDIF
648      stat = NF_PUT_ATT_TEXT   &
649         (ncid, idclat,'long_name',38,'Latitudes of grid cell corners of '//cgrid)
650      IF (stat /= NF_NOERR) THEN
651         WRITE (nulprt,*) 'ERROR creating att. for corner latitudes of ', cgrid
652      ENDIF
653      stat = NF_PUT_ATT_TEXT(ncid, idclat, 'units', 8, 'degree_N')
654      IF (stat /= NF_NOERR) THEN
655         WRITE (nulprt,*) 'ERROR creating att. for corner latitudes of ', cgrid
656      ENDIF
657!
658!--   switch to data mode
659!     -------------------
660      stat = NF_ENDDEF(ncid)
661      IF (stat /= NF_NOERR) THEN
662         WRITE (nulprt,*) 'ERROR: file ', ncid, ' still in define mode'
663      ENDIF
664!
665!--   write longitudes
666!     ----------------
667      stat = NF_PUT_VAR_DOUBLE (ncid, idclon, clon(:,:,:))
668      IF (stat /= NF_NOERR) THEN
669         WRITE (nulprt,*) 'ERROR writing corner lonitudes of ', cgrid
670      ENDIF
671!
672!--   write latitudes
673!     ---------------
674      stat = NF_PUT_VAR_DOUBLE (ncid, idclat, clat(:,:,:))
675      IF (stat /= NF_NOERR) THEN
676         WRITE (nulprt,*) 'ERROR writing corner latitudes of ', cgrid
677      ENDIF
678!
679!--   close grids file
680!     ----------------
681      stat = NF_CLOSE(ncid)
682      IF (stat /= NF_NOERR) THEN
683         WRITE (nulprt,*) 'ERROR closing file', cgrdnam
684      ENDIF
685     
686    ELSE
687!      -------------
688!--    binary format
689!      -------------
690          WRITE (nulprt,*) ' '
691          WRITE (nulprt,*) 'prisn_write_corner: WARNING: '
692          WRITE (nulprt,*) 'prism_write_corner:   Binary format not supported'
693          WRITE (nulprt,*) 'prism_write_corner:   No corners added'
694    ENDIF
695
696#ifdef __VERBOSE
697    write(nulprt,*) 'End - - prism_write_corner'
698    CALL FLUSH(nulprt)
699#endif
700
701    RETURN
702
703  END SUBROUTINE prism_write_corner
704!--------------------------------------------------------------------------
705!
706  SUBROUTINE prism_write_mask(cgrid, nx, ny, mask)
707!--------------------------------------------------------------------------
708! Routine to create a new masks file or to add a land see mask to an
709! existing masks file.
710!--------------------------------------------------------------------------
711    IMPLICIT NONE
712
713    INCLUDE 'netcdf.inc'
714
715    CHARACTER*4,              INTENT (IN) :: cgrid       ! grid acronym
716    INTEGER(kind=ip_intwp_p), INTENT (IN) :: nx          ! number of longitudes
717    INTEGER(kind=ip_intwp_p), INTENT (IN) :: ny          ! number of latitudes
718    INTEGER(kind=ip_intwp_p), INTENT (IN) :: mask(nx,ny) ! mask
719
720    INTEGER(kind=ip_intwp_p) :: iost         ! i/o status
721    INTEGER(kind=ip_intwp_p) :: nulmsk       ! logical unit of masks file
722    INTEGER(kind=ip_intwp_p) :: stat         ! netcdf status
723    INTEGER(kind=ip_intwp_p) :: ncid         ! netcdf file id
724    INTEGER(kind=ip_intwp_p) :: idx, idy     ! netcdf dimension ids
725    INTEGER(kind=ip_intwp_p) :: idmsk        ! netcdf variable id
726    INTEGER(kind=ip_intwp_p) :: dims(2)      ! netcdf variable dimensions
727
728    LOGICAL :: existent    !true if masks file is already existing
729    LOGICAL :: mskopen     !true if masks file is opened
730
731    CHARACTER*8 :: cmsk    !locator sring (binary) / variable name (netcdf)
732   
733!--------------------------------------------------------------------------
734
735#ifdef __VERBOSE
736    write(nulprt,*) ' '
737    write(nulprt,*) 'Start - - prism_write_mask'
738    write(nulprt,*) '  grid acronym: ', cgrid
739    CALL FLUSH(nulprt)
740#endif
741
742!
743!-- Return, if masks files already exists
744!
745    IF (.NOT. gridswrite) THEN
746       write(nulprt,*) ' '
747       write(nulprt,*) 'No mask writing needed'
748       RETURN
749    ENDIF
750
751    IF (netcdf) THEN
752!      -------------
753!--    netCDF format
754!      -------------
755!
756!      open masks file
757!      ---------------
758       stat = NF_OPEN(cmsknam//'.nc', NF_WRITE, ncid)
759       IF (stat /= NF_NOERR) THEN
760           stat = NF_CREATE(cmsknam//'.nc', NF_CLOBBER, ncid)
761          IF (stat /= NF_NOERR) THEN
762             WRITE (nulprt,*) 'prism_write_mask: error opening masks file.'
763             WRITE (nulprt,*) 'prism_write_mask: STOP'
764             STOP
765          ENDIF
766      ENDIF
767!
768!--   define dimensions
769!     -----------------
770      stat = NF_REDEF(ncid)
771      stat = NF_INQ_DIMID(ncid, 'x_'//cgrid, idx)
772      IF (stat .NE. NF_NOERR) THEN
773          stat = NF_DEF_DIM(ncid, 'x_'//cgrid, nx, idx)
774          IF (stat /= NF_NOERR) THEN
775              WRITE (nulprt,*) 'ERROR defining dimension x_',cgrid
776          ENDIF
777      ELSE
778          WRITE(nulprt,*)'Mask already defined: ', cgrid
779          RETURN
780      ENDIF
781      stat = NF_DEF_DIM(ncid, 'y_'//cgrid, ny, idy)
782      IF (stat /= NF_NOERR) THEN
783         WRITE (nulprt,*) 'ERROR defining dimension y_',cgrid
784      ENDIF
785
786      dims(1) = idx
787      dims(2) = idy
788!
789!--   define mask
790!     -----------
791      cmsk=cgrid//cmsksuf
792      stat = NF_DEF_VAR (ncid, cmsk , NF_INT, 2, dims, idmsk)
793      IF (stat /= NF_NOERR) THEN
794         WRITE (nulprt,*) 'ERROR defining variable ', cmsk
795      ENDIF
796      stat = NF_PUT_ATT_TEXT(ncid,idmsk,'long_name',12,'Mask of '//cgrid)
797      IF (stat /= NF_NOERR) THEN
798         WRITE (nulprt,*) 'ERROR creating att. for mask of ', cgrid
799      ENDIF
800      stat = NF_PUT_ATT_TEXT(ncid, idmsk, 'units', 1, '1')
801      IF (stat /= NF_NOERR) THEN
802         WRITE (nulprt,*) 'ERROR creating att. for mask of ', cgrid
803      ENDIF
804!
805!--   switch to data mode
806!     -------------------
807      stat = NF_ENDDEF(ncid)
808      IF (stat /= NF_NOERR) THEN
809         WRITE (nulprt,*) 'ERROR: file ', ncid, ' still in define mode'
810      ENDIF
811!
812!--   write mask
813!     ----------
814      stat = NF_PUT_VAR_INT (ncid, idmsk, mask(:,:))
815      IF (stat /= NF_NOERR) THEN
816         WRITE (nulprt,*) 'ERROR writing mask of ', cgrid
817      ENDIF
818!
819!--   close masks file
820!     ----------------
821      stat = NF_CLOSE(ncid)
822      IF (stat /= NF_NOERR) THEN
823         WRITE (nulprt,*) 'ERROR closing file', cmsknam
824      ENDIF
825     
826    ELSE
827!      -------------
828!--    binary format
829!      -------------
830!
831!      open masks file
832!      ---------------
833       INQUIRE (FILE = cmsknam, EXIST = existent, OPENED = mskopen)
834       IF (existent .AND. mskopen) THEN
835          WRITE (nulprt,*) ' '
836          WRITE (nulprt,*) 'prism_write_mask: masks file already opened'
837          WRITE (nulprt,*) 'prism_write_mask: STOP'
838          STOP     
839       ENDIF
840       iost = 0
841       nulmsk = 7
842       INQUIRE (nulmsk,OPENED = mskopen)
843       DO WHILE (mskopen)
844          nulmsk = nulmsk + 1 
845          INQUIRE (nulmsk,OPENED = mskopen)
846       END DO
847
848       OPEN (UNIT=nulmsk, FILE=cmsknam, STATUS='UNKNOWN',                 &
849             ACCESS='SEQUENTIAL', FORM='UNFORMATTED', POSITION='APPEND',  &
850             ACTION='WRITE', IOSTAT=iost, ERR=110)
851
852110    CONTINUE
853       IF (iost /= 0) THEN
854          WRITE (nulprt,*) ' '
855          WRITE (nulprt,*) 'prism_write_mask: Error opening masks file'
856          WRITE (nulprt,*) 'prism_write_mask: STOP'
857          STOP
858       ENDIF
859
860!      write maks
861!      ----------
862       cmsk=cgrid//cmsksuf
863       WRITE (UNIT = nulmsk) cmsk
864       WRITE (UNIT = nulmsk) mask(:,:)
865                           
866!      close grids file
867!      ----------------
868       CLOSE (nulmsk)
869
870    ENDIF
871
872#ifdef __VERBOSE
873    write(nulprt,*) 'End - - prism_write_mask'
874    CALL FLUSH(nulprt)
875#endif
876
877    RETURN
878
879  END SUBROUTINE prism_write_mask
880!--------------------------------------------------------------------------
881!
882  SUBROUTINE prism_write_area(cgrid, nx, ny, area)
883!--------------------------------------------------------------------------
884! Routine to create a new areas file or to add areas of a grid to an
885! existing areas file.
886!--------------------------------------------------------------------------
887    IMPLICIT NONE
888
889    INCLUDE 'netcdf.inc'
890
891    CHARACTER*4,              INTENT (IN) :: cgrid       ! grid acronym
892    INTEGER(kind=ip_intwp_p), INTENT (IN) :: nx          ! number of longitudes
893    INTEGER(kind=ip_intwp_p), INTENT (IN) :: ny          ! number of latitudes
894    REAL(kind=ip_realwp_p),   INTENT (IN) :: area(nx,ny) ! areas
895
896    INTEGER(kind=ip_intwp_p) :: iost         ! i/o status
897    INTEGER(kind=ip_intwp_p) :: nulsrf       ! logical unit of areas file
898    INTEGER(kind=ip_intwp_p) :: stat         ! netcdf status
899    INTEGER(kind=ip_intwp_p) :: ncid         ! netcdf file id
900    INTEGER(kind=ip_intwp_p) :: idx, idy     ! netcdf dimension ids
901    INTEGER(kind=ip_intwp_p) :: idsrf        ! netcdf variable id
902    INTEGER(kind=ip_intwp_p) :: dims(2)      ! netcdf variable dimensions
903
904    LOGICAL :: existent    !true if areas file is already existing
905    LOGICAL :: srfopen     !true if areas file is opened
906
907    CHARACTER*8 :: csrf    !locator sring (binary) / variable name (netcdf)
908   
909!--------------------------------------------------------------------------
910
911#ifdef __VERBOSE
912    write(nulprt,*) ' '
913    write(nulprt,*) 'Start - - prism_write_area'
914    write(nulprt,*) '  grid acronym: ', cgrid
915    CALL FLUSH(nulprt)
916#endif
917
918!
919!-- Return, if areas files already exists
920!
921    IF (.NOT. gridswrite) THEN
922       write(nulprt,*) ' '
923       write(nulprt,*) 'No areas writing needed'
924       RETURN
925    ENDIF
926
927    IF (netcdf) THEN
928!      -------------
929!--    netCDF format
930!      -------------
931!
932!      open areas file
933!      ---------------
934       stat = NF_OPEN(csurnam//'.nc', NF_WRITE, ncid)
935       IF (stat /= NF_NOERR) THEN
936           stat = NF_CREATE(csurnam//'.nc', NF_CLOBBER, ncid)
937          IF (stat /= NF_NOERR) THEN
938             WRITE (nulprt,*) 'prism_write_area: error opening areas file.'
939             WRITE (nulprt,*) 'prism_write_area: STOP'
940             STOP
941          ENDIF
942       ENDIF
943!
944!--   define dimensions
945!     -----------------
946      stat = NF_REDEF(ncid)
947      stat = NF_INQ_DIMID(ncid, 'x_'//cgrid, idx)
948      IF (stat .NE. NF_NOERR) THEN
949          stat = NF_DEF_DIM(ncid, 'x_'//cgrid, nx, idx)
950          IF (stat /= NF_NOERR) THEN
951              WRITE (nulprt,*) 'ERROR defining dimension x_',cgrid
952          ENDIF
953      ELSE
954          WRITE(nulprt,*)'Areas already defined: ', cgrid
955          RETURN
956      ENDIF
957      stat = NF_DEF_DIM(ncid, 'y_'//cgrid, ny, idy)
958      IF (stat /= NF_NOERR) THEN
959         WRITE (nulprt,*) 'ERROR defining dimension y_',cgrid
960      ENDIF
961
962      dims(1) = idx
963      dims(2) = idy
964!
965!--   define areas
966!     ------------
967      csrf=cgrid//csursuf
968      stat = NF_DEF_VAR (ncid, csrf , NF_DOUBLE, 2, dims, idsrf)
969      IF (stat /= NF_NOERR) THEN
970         WRITE (nulprt,*) 'ERROR defining variable ', csrf
971      ENDIF
972      stat = NF_PUT_ATT_TEXT(ncid,idsrf,'long_name',13,'Areas of '//cgrid)
973      IF (stat /= NF_NOERR) THEN
974         WRITE (nulprt,*) 'ERROR creating att. for areas of ', cgrid
975      ENDIF
976      stat = NF_PUT_ATT_TEXT(ncid, idsrf, 'units', 2, 'm2')
977      IF (stat /= NF_NOERR) THEN
978         WRITE (nulprt,*) 'ERROR creating att. for areas of ', cgrid
979      ENDIF
980!
981!--   switch to data mode
982!     -------------------
983      stat = NF_ENDDEF(ncid)
984      IF (stat /= NF_NOERR) THEN
985         WRITE (nulprt,*) 'ERROR: file ', ncid, ' still in define mode'
986      ENDIF
987!
988!--   write areas
989!     -----------
990      stat = NF_PUT_VAR_DOUBLE (ncid, idsrf, area(:,:))
991      IF (stat /= NF_NOERR) THEN
992         WRITE (nulprt,*) 'ERROR writing area of ', cgrid
993      ENDIF
994!
995!--   close areas file
996!     ----------------
997      stat = NF_CLOSE(ncid)
998      IF (stat /= NF_NOERR) THEN
999         WRITE (nulprt,*) 'ERROR closing file', csurnam
1000      ENDIF
1001     
1002    ELSE
1003!      -------------
1004!--    binary format
1005!      -------------
1006!
1007!      open areas file
1008!      ---------------
1009       INQUIRE (FILE = csurnam, EXIST = existent, OPENED = srfopen)
1010       IF (existent .AND. srfopen) THEN
1011          WRITE (nulprt,*) ' '
1012          WRITE (nulprt,*) 'prism_write_area: areas file already opened'
1013          WRITE (nulprt,*) 'prism_write_area: STOP'
1014          STOP     
1015       ENDIF
1016       iost = 0
1017       nulsrf = 7
1018       INQUIRE (nulsrf,OPENED = srfopen)
1019       DO WHILE (srfopen)
1020          nulsrf = nulsrf + 1 
1021          INQUIRE (nulsrf,OPENED = srfopen)
1022       END DO
1023
1024       OPEN (UNIT=nulsrf, FILE=csurnam, STATUS='UNKNOWN',                 &
1025             ACCESS='SEQUENTIAL', FORM='UNFORMATTED', POSITION='APPEND',  &
1026             ACTION='WRITE', IOSTAT=iost, ERR=110)
1027
1028110    CONTINUE
1029       IF (iost /= 0) THEN
1030          WRITE (nulprt,*) ' '
1031          WRITE (nulprt,*) 'prism_write_area: Error opening areas file'
1032          WRITE (nulprt,*) 'prism_write_area: STOP'
1033          STOP
1034       ENDIF
1035
1036!      write areas
1037!      -----------
1038       csrf=cgrid//csursuf
1039       WRITE (UNIT = nulsrf) csrf
1040       WRITE (UNIT = nulsrf) area(:,:)
1041                           
1042!      close areas file
1043!      ----------------
1044       CLOSE (nulsrf)
1045
1046    ENDIF
1047
1048#ifdef __VERBOSE
1049    write(nulprt,*) 'End - - prism_write_area'
1050    CALL FLUSH(nulprt)
1051#endif
1052
1053    RETURN
1054
1055  END SUBROUTINE prism_write_area
1056
1057!--------------------------------------------------------------------------
1058!
1059  SUBROUTINE prism_terminate_grids_writing
1060!--------------------------------------------------------------------------
1061! Routine to terminate the grids writing. Sent a message to OASIS
1062! saying that the model has written all grids and that
1063! the next model can start editing the grids file.
1064!--------------------------------------------------------------------------
1065    IMPLICIT NONE
1066
1067    INTEGER(kind=ip_intwp_p) :: grids_done ! flag to state  that grids
1068                                           ! writing is done
1069    INTEGER(kind=ip_intwp_p) :: dest       ! rank of the receiving process
1070
1071!--------------------------------------------------------------------------
1072#ifdef __VERBOSE
1073    write(nulprt,*) ' '
1074    write(nulprt,*) 'Start - - prism_terminate_grids_writing'
1075    CALL FLUSH(nulprt)
1076#endif
1077
1078    IF (.NOT. gridswrite) THEN
1079       write(nulprt,*) ' '
1080       write(nulprt,*) 'call to routine not needed'
1081       RETURN
1082    ENDIF
1083
1084    grids_done = 1
1085    dest = 0                   ! OASIS: process 0 of global communicator
1086
1087    WRITE (nulprt,FMT='(A)') 'Send - grids_done'
1088    len = 1
1089    type = MPI_INTEGER
1090    tag = itagcol+13
1091    CALL MPI_Send (grids_done, len, type, dest, tag, mpi_comm, mpi_err)
1092    IF (mpi_err == MPI_SUCCESS) THEN
1093       WRITE(nulprt,FMT='(A,I2,A,I6,A,I2,A,I3,A,I5,A,I1)') &
1094            'Send - <dest:',dest,'> <comm:',mpi_comm,'> <len:',len,  &
1095            '> <type:',type,'> <tag:',tag,'> ::  ',grids_done
1096       CALL FLUSH(nulprt)
1097    ELSE
1098       WRITE (nulprt,*) ' '
1099       WRITE (nulprt,*) 'terminate_grids_writing: an error occured'
1100       WRITE (nulprt,*) 'terminate_grids_writing: err= ', mpi_err 
1101       WRITE (nulprt,*) 'terminate_grids_writing: STOP'
1102       STOP
1103    ENDIF
1104
1105#ifdef __VERBOSE
1106    write(nulprt,*) 'End - - prism_terminate_grids_writing'
1107    write(nulprt,*) ' '
1108    CALL FLUSH(nulprt)
1109#endif
1110
1111    RETURN
1112  END SUBROUTINE prism_terminate_grids_writing
1113!--------------------------------------------------------------------------
1114
1115END MODULE mod_prism_grids_writing
1116!--------------------------------------------------------------------------
1117
1118
1119     
Note: See TracBrowser for help on using the repository browser.