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 branches/dev_001_GM/NEMO/OFF_SRC/IOM – NEMO

source: branches/dev_001_GM/NEMO/OFF_SRC/IOM/iom_rstdimg.F90 @ 951

Last change on this file since 951 was 951, checked in by cetlod, 16 years ago

phasing the OFFLINE module to the new version of NEMO, see ticket 146

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