New URL for NEMO forge!   http://forge.nemo-ocean.eu

Since March 2022 along with NEMO 4.2 release, the code development moved to a self-hosted GitLab.
This present forge is now archived and remained online for history.
iom_rstdimg.F90 in trunk/NEMO/OPA_SRC/IOM – NEMO

source: trunk/NEMO/OPA_SRC/IOM/iom_rstdimg.F90 @ 548

Last change on this file since 548 was 547, checked in by opalod, 18 years ago

nemo_v1_update_078:RB: finalization of IOM (2)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 25.4 KB
Line 
1MODULE iom_rstdimg
2   !!=====================================================================
3   !!                    ***  MODULE  iom_rstdimg ***
4   !! Input/Output manager :  Library to read input rstdimg files
5   !!====================================================================
6   !! History :  9.0  ! 06 09  (S. Masson) Original code
7   !!--------------------------------------------------------------------
8
9   !!--------------------------------------------------------------------
10   !!   iom_open       : open a file read only
11   !!   iom_close      : close a file or all files opened by iom
12   !!   iom_get        : read a field (interfaced to several routines)
13   !!   iom_gettime    : read the time axis kvid in the file
14   !!   iom_varid      : get the id of a variable in a file
15   !!   iom_rstput     : write a field in a restart file (interfaced to several routines)
16   !!--------------------------------------------------------------------
17   USE in_out_manager  ! I/O manager
18   USE dom_oce         ! ocean space and time domain
19   USE lbclnk          ! lateal boundary condition / mpp exchanges
20
21   USE iom_def         !
22
23   IMPLICIT NONE
24   PRIVATE
25
26   PUBLIC iom_rstdimg_open, iom_rstdimg_close, iom_rstdimg_get, iom_rstdimg_rstput
27
28   INTERFACE iom_rstdimg_get
29      MODULE PROCEDURE iom_rstdimg_get_0d, iom_rstdimg_get_123d
30   END INTERFACE
31   INTERFACE iom_rstdimg_rstput
32      MODULE PROCEDURE iom_rstdimg_rstput_0d, iom_rstdimg_rstput_123d
33   END INTERFACE
34   !!----------------------------------------------------------------------
35   !!  OPA 9.0 , LOCEAN-IPSL (2006)
36   !! $Header$
37   !! Software governed by the CeCILL licence (modipsl/doc/NEMO_CeCILL.txt)
38   !!----------------------------------------------------------------------
39
40CONTAINS
41
42   SUBROUTINE iom_rstdimg_open( cdname, kiomid, ldwrt, ldok, kdompar )
43      !!---------------------------------------------------------------------
44      !!                   ***  SUBROUTINE  iom_open  ***
45      !!
46      !! ** Purpose :  open an input file read only (return 0 if not found)
47      !!---------------------------------------------------------------------
48      CHARACTER(len=*)       , INTENT(inout) ::   cdname   ! File name
49      INTEGER                , INTENT(  out) ::   kiomid   ! iom identifier of the opened file
50      LOGICAL                , INTENT(in   ) ::   ldwrt    ! read or write the file?
51      LOGICAL                , INTENT(in   ) ::   ldok     ! check the existence
52      INTEGER, DIMENSION(2,5), INTENT(in   ) ::   kdompar  ! domain parameters:
53
54      CHARACTER(LEN=100)                      ::   clinfo                     ! info character
55      CHARACTER(LEN=100)                      ::   cltmp                      ! temporary character
56      INTEGER                                 ::   jv                         ! loop counter
57      INTEGER                                 ::   istop                      ! temporary storage of nstop
58      INTEGER                                 ::   idrst                      ! logical unit of the restart file
59      INTEGER                                 ::   iln                        ! lengths of character
60      INTEGER                                 ::   irecl8                     ! record length
61      INTEGER                                 ::   ios                        ! IO status
62      INTEGER                                 ::   ivnum                      ! number of variables
63      INTEGER                                 ::   inx, iny, inz              ! x,y,z dimension of the variable
64      INTEGER                                 ::   in0d, in2d, in3d           ! number of 0/2/3D variables
65      INTEGER                                 ::   ipni, ipnj, ipnij, iarea   ! domain decomposition
66      CHARACTER(LEN=8), DIMENSION(jpmax_vars) ::   clna0d, clna2d, clna3d     ! name of 0/2/3D variables
67      REAL(wp),         DIMENSION(jpmax_vars) ::   zval0d, zval2d, zval3d     ! value of 0d variables or
68      !                                                                       ! record position for 2/3D variables
69      !---------------------------------------------------------------------
70
71      clinfo = '                    iom_rstdimg_open ~~~  '
72      istop = nstop      ! store the actual value of nstop
73      ios = 0            ! default definition
74      kiomid = 0         ! default definition
75      ! get a free unit
76      idrst = getunit()  ! get a free logical unit for the restart file
77!!$#if defined key_agrif
78!!$      idrst = Agrif_Get_Unit()     
79!!$#endif
80      ! Open the file...
81      ! =============
82      IF( ldok ) THEN      ! Open existing file...
83         ! find the record length
84         OPEN( idrst, FILE = TRIM(cdname), FORM = 'unformatted', ACCESS = 'direct'   &
85               &          , RECL = 8, STATUS = 'old', ACTION = 'read', IOSTAT = ios, ERR = 987 )
86         READ( idrst, REC = 1, IOSTAT = ios, ERR = 987 ) irecl8
87         CLOSE( idrst )
88         ! Open the file with the appropriate record length and parameters
89         IF( ldwrt ) THEN  ! ... in readwrite mode
90            IF(lwp) WRITE(numout,*) TRIM(clinfo)//' open existing file: '//TRIM(cdname)//' in READWRITE mode'
91            OPEN( idrst, FILE = TRIM(cdname), FORM = 'unformatted', ACCESS = 'direct'   &
92                  &          , RECL = irecl8, STATUS = 'old', ACTION = 'readwrite', IOSTAT = ios, ERR = 987 )
93         ELSE              ! ... in read mode
94            IF(lwp) WRITE(numout,*) TRIM(clinfo)//' open existing file: '//TRIM(cdname)//' in READ mode'
95            OPEN( idrst, FILE = TRIM(cdname), FORM = 'unformatted', ACCESS = 'direct'   &
96                  &          , RECL = irecl8, STATUS = 'old', ACTION = 'read'     , IOSTAT = ios, ERR = 987 )
97         ENDIF
98      ELSE                 ! the file does not exist
99         iln = INDEX( cdname, '.dimg' )
100         IF( ldwrt ) THEN  ! the file should be open in readwrite mode so we create it...
101            irecl8= kdompar(1,1) * kdompar(2,1) * wp
102            WRITE(cltmp,'(a,a,i4.4,a)') cdname(1:iln-1), '_', narea-1, '.dimg'
103            cdname = TRIM(cltmp)
104            IF(lwp) WRITE(numout,*) TRIM(clinfo)//' create new file: '//TRIM(cdname)//' in READWRITE mode'
105            OPEN( idrst, FILE = TRIM(cdname), FORM = 'UNFORMATTED', ACCESS = 'DIRECT'   &
106                  &          , RECL = irecl8, STATUS = 'new', ACTION = 'readwrite', IOSTAT = ios, ERR = 987 )
107         ELSE              ! the file should be open for read mode so it must exist...
108            CALL ctl_stop( TRIM(clinfo), 'File '//cdname(1:iln-1)//'* not found' )
109         ENDIF
110      ENDIF
111      ! Performs checks on the file
112      ! =============
113      IF( ldok ) THEN      ! old file
114         READ( idrst, REC = 1, IOSTAT = ios, ERR = 987 ) irecl8, inx, iny, inz, in0d, in2d, in3d
115         READ( idrst, REC = 1, IOSTAT = ios, ERR = 987 ) irecl8, inx, iny, inz, in0d, in2d, in3d,   &
116               &   clna0d(1:in0d), zval0d(1:in0d), clna2d(1:in2d), zval2d(1:in2d), clna3d(1:in3d), zval3d(1:in3d),   &
117               &   ipni, ipnj, ipnij, iarea 
118         clinfo = TRIM(clinfo)//' file '//TRIM(cdname)
119         IF( inx   /= kdompar(1,1) )   CALL ctl_stop( TRIM(clinfo), 'Mismatch in domain size in i direction' )
120         IF( iny   /= kdompar(2,1) )   CALL ctl_stop( TRIM(clinfo), 'Mismatch in domain size in j direction' )
121         IF( inz   /= jpk          )   CALL ctl_stop( TRIM(clinfo), 'Mismatch in domain size in k direction' )
122         IF( ipni  /= jpni         )   CALL ctl_stop( TRIM(clinfo), 'Processor splitting changed along I' )
123         IF( ipnj  /= jpnj         )   CALL ctl_stop( TRIM(clinfo), 'Processor splitting changed along J' )
124         IF( ipnij /= jpnij        )   CALL ctl_stop( TRIM(clinfo), 'Total number of processors changed' )
125         IF( iarea /= narea        )   CALL ctl_stop( TRIM(clinfo), 'Mismatch in area numbering ...' )
126      ENDIF
127      ! fill file informations
128      ! =============
129      IF( istop == nstop ) THEN   ! no error within this routine
130         kiomid = MINLOC(iom_file(:)%nfid, dim = 1)
131         iom_file(kiomid)%name    = TRIM(cdname)
132         iom_file(kiomid)%nfid    = idrst
133         iom_file(kiomid)%iolib   = jprstdimg
134         iom_file(kiomid)%iduld   = -1
135         IF( ldok ) THEN      ! old file
136            ! read variables informations from the file header
137            ivnum = in0d + in2d + in3d
138            iom_file(kiomid)%nvars            = ivnum
139            iom_file(kiomid)%irec             = 2 + in2d + inz * in3d
140            iom_file(kiomid)%luld(   1:ivnum) = .FALSE.
141            iom_file(kiomid)%scf(    1:ivnum) = 1.
142            ! scalar variable
143            DO jv = 1, in0d
144               iom_file(kiomid)%cn_var(jv) = TRIM(clna0d(jv))
145               iom_file(kiomid)%nvid(  jv) = 1
146               iom_file(kiomid)%ndims( jv) = 0
147               iom_file(kiomid)%ofs(   jv) = zval0d(jv)   ! warning: trick... we use ofs to store the value
148            END DO
149            ! 2d variable
150            DO jv = 1, in2d
151               iom_file(kiomid)%cn_var(    in0d + jv) = TRIM(clna2d(jv))
152               iom_file(kiomid)%nvid(      in0d + jv) = zval2d(jv)
153               iom_file(kiomid)%ndims(     in0d + jv) = 2
154               iom_file(kiomid)%dimsz(1:2, in0d + jv) = (/ inx, iny /)
155               iom_file(kiomid)%ofs(       in0d + jv) = 0.
156            END DO
157            ! 3d variable
158            DO jv = 1, in3d
159               iom_file(kiomid)%cn_var(    in0d + in2d + jv) = TRIM(clna3d(jv))
160               iom_file(kiomid)%nvid(      in0d + in2d + jv) = zval3d(jv)
161               iom_file(kiomid)%ndims(     in0d + in2d + jv) = 3
162               iom_file(kiomid)%dimsz(1:3, in0d + in2d + jv) = (/ inx, iny, jpk /)
163               iom_file(kiomid)%ofs(       in0d + in2d + jv) = 0.
164            END DO
165         ELSE                 ! new file
166            iom_file(kiomid)%nvars = 0
167            iom_file(kiomid)%irec  = 2
168            ! store file informations
169            WRITE( idrst, REC = 1, IOSTAT = ios, ERR = 987 ) irecl8, kdompar(:,1), jpk   ! store domain size
170         ENDIF
171      ENDIF
172987   CONTINUE
173      IF( ios /= 0 )   CALL ctl_stop( TRIM(clinfo), 'error in opening file '//TRIM(cdname) )
174      !
175   END SUBROUTINE iom_rstdimg_open
176
177
178   SUBROUTINE iom_rstdimg_close( kiomid )
179      !!--------------------------------------------------------------------
180      !!                   ***  SUBROUTINE  iom_rstdimg_close  ***
181      !!
182      !! ** Purpose : close an input file
183      !!--------------------------------------------------------------------
184      INTEGER, INTENT(in) ::   kiomid   ! iom identifier of the file to be closed
185      !
186      CHARACTER(LEN=100)                      ::   clinfo                     ! info character
187      INTEGER                                 ::   jv                         ! loop counter
188      INTEGER                                 ::   irecl8                     ! record length
189      INTEGER                                 ::   ios                        ! IO status
190      INTEGER                                 ::   ivnum                      ! number of variables
191      INTEGER                                 ::   idrst                      ! file logical unit
192      INTEGER                                 ::   inx, iny, inz              ! x,y,z dimension of the variable
193      INTEGER                                 ::   in0d, in2d, in3d           ! number of 0/2/3D variables
194      CHARACTER(LEN=8), DIMENSION(jpmax_vars) ::   clna0d, clna2d, clna3d     ! name of 0/2/3D variables
195      REAL(wp),         DIMENSION(jpmax_vars) ::   zval0d, zval2d, zval3d     ! value of 0d variables or
196      !                                                                       ! record position for 2/3D variables
197      !---------------------------------------------------------------------
198      !
199      clinfo = '                    iom_rstdimg_close ~~~  '
200      idrst = iom_file(kiomid)%nfid   ! get back the logical unit of the restart file
201      ! test if we can write in the file (test with INQUIRE gives alsways YES even with read only files...)
202      READ(  idrst, REC = 1, IOSTAT = ios, ERR = 987 ) irecl8, inx, iny, inz   
203      WRITE( idrst, REC = 1, IOSTAT = ios            ) irecl8, inx, iny, inz   
204      ! We can write in the file => we update its header before closing
205      IF( ios == 0 ) THEN
206         READ( idrst, REC = 1, IOSTAT = ios, ERR = 987 ) irecl8, inx, iny, inz   ! get back domain size
207         ivnum = iom_file(kiomid)%nvars
208         in0d = 0   ;   in2d = 0   ;   in3d = 0
209         DO jv = 1, ivnum   ! loop on each variable to get its name and value/record position
210            SELECT CASE (iom_file(kiomid)%ndims(jv))
211            CASE (0)   ! scalar variable
212               in0d = in0d + 1
213               clna0d(in0d) = TRIM(iom_file(kiomid)%cn_var(jv))
214               zval0d(in0d) = iom_file(kiomid)%ofs(jv)   ! warning: trick... we use ofs to store the value
215            CASE (2)   ! 2d variable
216               in2d = in2d + 1
217               clna2d(in2d) = TRIM(iom_file(kiomid)%cn_var(jv))
218               zval2d(in2d) = iom_file(kiomid)%nvid(jv)
219            CASE (3)   ! 3d variable
220               in3d = in3d + 1
221               clna3d(in3d) = TRIM(iom_file(kiomid)%cn_var(jv))
222               zval3d(in3d) = iom_file(kiomid)%nvid(jv)
223            END SELECT
224         END DO
225         ! update teh file header before closing it
226         WRITE( idrst, REC = 1, IOSTAT = ios, ERR = 987 ) irecl8, inx, iny, inz, in0d, in2d, in3d,   &
227               &   clna0d(1:in0d), zval0d(1:in0d), clna2d(1:in2d), zval2d(1:in2d), clna3d(1:in3d), zval3d(1:in3d),   &
228               &   jpni, jpnj, jpnij, narea, jpiglo, jpjglo,   &
229               &   nlcit, nlcjt, nldit, nldjt, nleit, nlejt, nimppt, njmppt
230      ELSE
231         ios = 0   ! we cannot write in the file
232      ENDIF
233      !
234      CLOSE( idrst, IOSTAT = ios, ERR = 987 )
235987   CONTINUE
236      IF( ios /= 0 )   CALL ctl_stop( TRIM(clinfo), 'error when updating the header of '//TRIM(iom_file(kiomid)%name) )
237      !   
238   END SUBROUTINE iom_rstdimg_close
239
240
241   SUBROUTINE iom_rstdimg_get_0d( kiomid, kvid, pvar )
242      !!-----------------------------------------------------------------------
243      !!                  ***  ROUTINE  iom_rstdimg_get_0d  ***
244      !!
245      !! ** Purpose : read a scalar with RSTDIMG
246      !!-----------------------------------------------------------------------
247      INTEGER,  INTENT(in   ) ::   kiomid    ! Identifier of the file
248      INTEGER,  INTENT(in   ) ::   kvid      ! variable id
249      REAL(wp), INTENT(  out) ::   pvar      ! read field
250      !---------------------------------------------------------------------
251      !
252      pvar = iom_file(kiomid)%ofs(kvid)   ! warning: trick... we use ofs to store the value
253      !
254   END SUBROUTINE iom_rstdimg_get_0d
255
256
257   SUBROUTINE iom_rstdimg_rstput_0d( kiomid, cdvar, pv_r0d )
258      !!--------------------------------------------------------------------
259      !!                   ***  SUBROUTINE  iom_rstdimg_rstput  ***
260      !!
261      !! ** Purpose : write a scalar with RSTDIMG
262      !!--------------------------------------------------------------------
263      INTEGER                   , INTENT(in) ::   kiomid   ! Identifier of the file
264      CHARACTER(len=*)          , INTENT(in) ::   cdvar    ! time axis name
265      REAL(wp)                  , INTENT(in) ::   pv_r0d   ! read field
266      !
267      CHARACTER(LEN=100) ::   clinfo     ! info character
268      INTEGER            ::   idvar      ! variable id
269      !---------------------------------------------------------------------
270     
271      clinfo = '                    iom_rstdimg_rstput_0d ~~~  '
272      idvar = iom_file(kiomid)%nvars + 1
273      IF( idvar <= jpmax_vars ) THEN
274         iom_file(kiomid)%nvars = idvar
275         iom_file(kiomid)%cn_var(idvar) = TRIM(cdvar)
276         iom_file(kiomid)%nvid(   idvar) = 1   ! useless, Od variables a strored in record 1
277         iom_file(kiomid)%ndims(  idvar) = 0
278         iom_file(kiomid)%luld(   idvar) = .FALSE.
279         iom_file(kiomid)%scf(    idvar) = 1.
280         iom_file(kiomid)%ofs(    idvar) = pv_r0d   ! warning: trick... we use ofs to store the value
281      ELSE
282         CALL ctl_stop( TRIM(clinfo), 'increase the value of jpmax_vars' )
283      ENDIF
284   END SUBROUTINE iom_rstdimg_rstput_0d
285
286
287   SUBROUTINE iom_rstdimg_get_123d( kiomid, kdom  , kvid  , kstart, kcount,    &
288         &                           pv_r1d, pv_r2d, pv_r3d )
289      !!-----------------------------------------------------------------------
290      !!                  ***  ROUTINE  iom_rstdimg_get_123d  ***
291      !!
292      !! ** Purpose : read a 1D/2D/3D variable with RSTDIMG
293      !!
294      !! ** Method : read ONE record at each CALL
295      !!-----------------------------------------------------------------------
296      INTEGER                    , INTENT(in   )           ::   kiomid     ! iom identifier of the file
297      INTEGER                    , INTENT(in   )           ::   kdom       ! Type of domain to be read
298      INTEGER                    , INTENT(in   )           ::   kvid       ! variable id
299      INTEGER , DIMENSION(:)     , INTENT(in   )           ::   kstart     ! start position of the reading in each axis
300      INTEGER , DIMENSION(:)     , INTENT(in   )           ::   kcount     ! number of points to be read in each axis
301      REAL(wp), DIMENSION(:)     , INTENT(  out), OPTIONAL ::   pv_r1d     ! read field (1D case)
302      REAL(wp), DIMENSION(:,:)   , INTENT(  out), OPTIONAL ::   pv_r2d     ! read field (2D case)
303      REAL(wp), DIMENSION(:,:,:) , INTENT(  out), OPTIONAL ::   pv_r3d     ! read field (3D case)
304
305      CHARACTER(LEN=100) ::   clinfo               ! info character
306      INTEGER            ::   ios                  ! IO status
307      INTEGER            ::   jk                   ! loop counter
308      INTEGER            ::   idrst                ! logical unit of the restart file
309      INTEGER            ::   istop                ! temporary storage of nstop
310      INTEGER            ::   ix1, ix2, iy1, iy2   ! subdomain indexes
311      !---------------------------------------------------------------------
312      clinfo = '                    iom_rstdimg_get_123d ~~~  '
313      !
314      istop = nstop                   ! store the actual value of nstop
315      idrst = iom_file(kiomid)%nfid   ! get back the logical unit of the restart file
316      IF( kdom == jpdom_data .OR. kdom == jpdom_global )   &
317            &   CALL ctl_stop( TRIM(clinfo), TRIM(iom_file(kiomid)%cn_var(kvid))//': case not coded for rstdimg files' )
318      !
319      IF( istop == nstop .AND. kvid > 0 ) THEN
320         IF( .NOT. PRESENT(pv_r1d) ) THEN
321            SELECT CASE (kdom)   ! find the right index of the array to be read
322            CASE (jpdom_local_full)      ;   ix1 = nldi   ;   ix2 = nlei   ;   iy1 = nldj   ;   iy2 = nlej
323            CASE (jpdom_local_noextra)   ;   ix1 = 1      ;   ix2 = nlci   ;   iy1 = 1      ;   iy2 = nlcj
324            CASE (jpdom_local_noovlap)   ;   ix1 = nldi   ;   ix2 = nlei   ;   iy1 = nldj   ;   iy2 = nlej
325            CASE DEFAULT                 ;   CALL ctl_stop( clinfo, 'we should not be there...' )
326            END SELECT
327         ENDIF
328         IF(     PRESENT(pv_r1d) ) THEN   ! read 1D variables
329            READ( idrst, REC = iom_file(kiomid)%nvid(kvid), IOSTAT = ios, ERR = 987 )   pv_r1d(:)
330         ELSEIF( PRESENT(pv_r2d) ) THEN   ! read 2D variables
331            READ( idrst, REC = iom_file(kiomid)%nvid(kvid), IOSTAT = ios, ERR = 987 )   pv_r2d(ix1:ix2, iy1:iy2 )
332            SELECT CASE (kdom)
333            CASE (jpdom_local_noextra)   !--- Fill extra hallows (mpp)       
334               pv_r2d(nlci+1:jpi,      :   ) = 1.   
335               pv_r2d(      :   ,nlcj+1:jpj) = 1.           
336            CASE (jpdom_local_noovlap)   !--- Fill the overlap areas and extra hallows (mpp)
337               CALL lbc_lnk (pv_r2d,'Z',-999.,'no0')
338            CASE DEFAULT
339            END SELECT
340         ELSEIF( PRESENT(pv_r3d) ) THEN   ! read 3D variables
341            DO jk = 1, iom_file(kiomid)%dimsz(3,kvid)   ! do loop on each level
342               READ( idrst, REC = iom_file(kiomid)%nvid(kvid) + jk - 1, IOSTAT = ios, ERR = 987 )   &
343                     &       pv_r3d( ix1:ix2, iy1:iy2, jk )
344            END DO
345            SELECT CASE (kdom)
346            CASE (jpdom_local_noextra)   !--- Fill extra hallows (mpp)       
347               pv_r3d(nlci+1:jpi,      :   ,:) = 1.   
348               pv_r3d(      :   ,nlcj+1:jpj,:) = 1.           
349            CASE (jpdom_local_noovlap)   !--- Fill the overlap areas and extra hallows (mpp)
350               ! this if could be simplified with the new lbc_lnk that works with any size of the 3rd dimension
351               IF( kcount(3) == jpk ) THEN
352                  CALL lbc_lnk( pv_r3d,'Z',-999.,'no0' )
353               ELSE
354                  pv_r3d(nlei+1:jpi,      :   ,:) = 1.           
355                  pv_r3d(      :   ,nlej+1:jpj,:) = 1.           
356               ENDIF
357            CASE DEFAULT
358            END SELECT
359         ENDIF
360      ENDIF
361987   CONTINUE
362      IF( ios /= 0 )   CALL ctl_stop( TRIM(clinfo) )
363      !
364   END SUBROUTINE iom_rstdimg_get_123d
365
366
367   SUBROUTINE iom_rstdimg_rstput_123d( kiomid, cdvar, pv_r1d, pv_r2d, pv_r3d )
368      !!--------------------------------------------------------------------
369      !!                   ***  SUBROUTINE  iom_rstdimg_rstput  ***
370      !!
371      !! ** Purpose : write a 2D/3D variable with RSTDIMG
372      !!--------------------------------------------------------------------
373      INTEGER                         , INTENT(in)           ::   kiomid   ! Identifier of the file
374      CHARACTER(len=*)                , INTENT(in)           ::   cdvar    ! time axis name
375      REAL(wp), DIMENSION(        jpk), INTENT(in), OPTIONAL ::   pv_r1d   ! read field
376      REAL(wp), DIMENSION(jpi,jpj    ), INTENT(in), OPTIONAL ::   pv_r2d   ! read field
377      REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(in), OPTIONAL ::   pv_r3d   ! read field
378      !
379      CHARACTER(LEN=100)    ::   clinfo               ! info character
380      INTEGER               ::   irecl8               ! reacord length
381      INTEGER               ::   ios                  ! IO status
382      INTEGER               ::   idrst                ! reacord length
383      INTEGER               ::   inx, iny, inz        ! x,y,z dimension of the variable
384      INTEGER               ::   idvar                ! variable id
385      INTEGER               ::   istop                ! temporary storage of nstop
386      INTEGER               ::   irec                 ! record number
387      INTEGER               ::   ix1, ix2, iy1, iy2   ! subdomain indexes
388      INTEGER               ::   jk                   ! loop counter
389      !---------------------------------------------------------------------
390      !
391      clinfo = '          iom_rstdimg_rstput_123d, file: '//TRIM(iom_file(kiomid)%name)//', var: '//TRIM(cdvar)
392      istop = nstop                   ! store the actual value of nstop
393      irec = iom_file(kiomid)%irec    ! get back the record number of the variable
394      idrst = iom_file(kiomid)%nfid   ! get back the logical unit of the restart file
395      idvar = iom_file(kiomid)%nvars + 1
396      IF( idvar > jpmax_vars )   CALL ctl_stop( TRIM(clinfo), 'increase the value of jpmax_vars' )
397      IF( .NOT. PRESENT(pv_r1d) ) THEN
398         ! find which part of data must be written
399         READ( idrst, REC = 1, IOSTAT = ios, ERR = 987 ) irecl8, inx, iny, inz
400         IF(     inx == (nlei - nldi + 1) .AND. iny == (nlej - nldj + 1) ) THEN
401            ix1 = nldi   ;   ix2 = nlei   ;   iy1 = nldj   ;   iy2 = nlej
402         ELSEIF( inx == nlci              .AND. iny == nlcj              ) THEN
403            ix1 = 1      ;   ix2 = nlci   ;   iy1 = 1      ;   iy2 = nlcj
404         ELSEIF( inx == jpi               .AND. iny == jpj               ) THEN
405            ix1 = 1      ;   ix2 = jpi    ;   iy1 = 1      ;   iy2 = jpj
406         ELSE
407            CALL ctl_stop( clinfo, 'should have been an impossible case...' )
408         ENDIF
409      ENDIF
410      IF( istop == nstop ) THEN
411         ! write the data
412         IF(     PRESENT(pv_r1d) ) THEN   ! 1D variable
413            WRITE( idrst, REC = irec            , IOSTAT = ios, ERR = 987 ) pv_r1d(:)
414         ELSEIF( PRESENT(pv_r2d) ) THEN   ! 2D variable
415            WRITE( idrst, REC = irec            , IOSTAT = ios, ERR = 987 ) pv_r2d(ix1:ix2, iy1:iy2    )
416         ELSEIF( PRESENT(pv_r3d) ) THEN   ! 3D variable
417            DO jk = 1, jpk   ! do loop on each level
418               WRITE( idrst, REC = irec + jk - 1, IOSTAT = ios, ERR = 987 ) pv_r3d(ix1:ix2, iy1:iy2, jk)
419            END DO
420         ENDIF
421         ! fill the file informations
422         iom_file(kiomid)%nvars = idvar
423         IF(     PRESENT(pv_r1d) ) THEN
424            iom_file(kiomid)%irec              = irec + 1
425            iom_file(kiomid)%ndims(     idvar) = 1
426            iom_file(kiomid)%dimsz(1:2, idvar) = inz
427         ELSEIF( PRESENT(pv_r2d) ) THEN
428            iom_file(kiomid)%irec              = irec + 1
429            iom_file(kiomid)%ndims(     idvar) = 2
430            iom_file(kiomid)%dimsz(1:2, idvar) = (/ inx, iny /)
431         ELSEIF( PRESENT(pv_r3d) ) THEN
432            iom_file(kiomid)%irec              = irec + inz
433            iom_file(kiomid)%ndims(     idvar) = 3
434            iom_file(kiomid)%dimsz(1:3, idvar) = (/ inx, iny, inz /)
435         ENDIF
436         iom_file(kiomid)%cn_var(idvar) = TRIM(cdvar)
437         iom_file(kiomid)%nvid(  idvar) = irec
438         iom_file(kiomid)%luld(  idvar) = .FALSE.
439         iom_file(kiomid)%scf(   idvar) = 1.
440         iom_file(kiomid)%ofs(   idvar) = 0.
441      ENDIF
442987   CONTINUE
443      IF( ios /= 0 ) THEN   ;   CALL ctl_stop( TRIM(clinfo) )
444      ELSE                  ;   IF(lwp) WRITE(numout,*) TRIM(clinfo)//' written ok'
445      ENDIF
446      !     
447   END SUBROUTINE iom_rstdimg_rstput_123d
448
449
450   !!======================================================================
451END MODULE iom_rstdimg
Note: See TracBrowser for help on using the repository browser.