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

source: trunk/NEMO/OFF_SRC/IOM/iom_rstdimg.F90 @ 719

Last change on this file since 719 was 719, checked in by ctlod, 17 years ago

get back to the nemo_v2_3 version for trunk

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