Subversion Repositories lagranto.20cr

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4 michaesp 1
c     ************************************************************
2
c     * This package provides input routines to read the wind    *
3
c     * and other fields from IVE necdf files. The routines are  *
4
c     *                                                          *
5
c     * 1) input_open  : to open a data file                     *
6
c     * 2) input_grid  : to read the grid information, including *
7
c     *                  the vertical levels                     *
8
c     * 3) input_wind  : to read the wind components             *
9
c     * 4) input_close : to close an input file                  *
10
c     *                                                          *
11
c     * The file is characterised by an filename <filename> and  *
12
c     * a file identifier <fid>. The horizontal grid is given by *
13
c     * <xmin,xmax,ymin,ymax,dx,dy,nx,ny> where the pole of the  *
14
c     * rotated grid is given by <pollon,pollat>. The vertical   *
15
c     * grid is characterised by the surface pressure <ps> and   *
16
c     * the pressure at staggered <slev> and unstaggered <ulev>  *
17
c     * levels. The number of levels is given by <nz>. Finally,  *
18
c     * the retrieval of the wind <field> with name <fieldname>  *
19
c     * is characterised by a <time> and a missing data value    *
20
c     * <mdv>.                                                   *
21
c     *                                                          *
22
c     * Author: Michael Sprenger, Autumn 2008                    *
23
c     ************************************************************
24
 
25
c     ------------------------------------------------------------
26
c     Open input file
27
c     ------------------------------------------------------------
28
 
29
      subroutine input_open (fid,filename)
30
 
31
c     Open the input file with filename <filename> and return the
32
c     file identifier <fid> for further reference. 
33
 
34
      use netcdf
35
 
36
      implicit none
37
 
38
c     Declaration of subroutine parameters
39
      integer      fid              ! File identifier
40
      character*80 filename         ! Filename
41
 
42
c     Declaration of auxiliary variables
43
      integer      ierr
44
 
45
      ierr = NF90_OPEN(TRIM(filename),nf90_nowrite, fid)
46
      IF ( ierr /= nf90_NoErr ) PRINT *,NF90_STRERROR(ierr)
47
 
48
      end
49
 
50
 
51
c     ------------------------------------------------------------
52
c     Read information about the grid
53
c     ------------------------------------------------------------
54
 
55
      subroutine input_grid 
56
     >                   (fid,fieldname,xmin,xmax,ymin,ymax,dx,dy,nx,ny,
57
     >                    time,pollon,pollat,p3,ps,nz,ak,bk,stagz,
58
     >                    timecheck)
59
 
60
      use netcdf
61
 
62
c     Read grid information at <time> from file with identifier <fid>. 
63
c     The horizontal grid is characterized by <xmin,xmax,ymin,ymax,dx,dy>
64
c     with pole position at <pollon,pollat> and grid dimension <nx,ny>.
65
c     The 3d arrays <p3(nx,ny,nz)> gives the vertical coordinates, either
66
c     on the staggered or unstaggered grid (with <stagz> as the flag).
67
c     The surface pressure is given in <ps(nx,ny)>. If <fid> is negative, 
68
c     only the grid dimensions and grid parameters (xmin...pollat,nz) are 
69
c     determined and returned (this is needed for dynamical allocation of 
70
c     memory).
71
 
72
      implicit none
73
 
74
c     Declaration of subroutine parameters 
75
      integer      fid                 ! File identifier
76
      real         xmin,xmax,ymin,ymax ! Domain size
77
      real         dx,dy               ! Horizontal resolution
78
      integer      nx,ny,nz            ! Grid dimensions
79
      real         pollon,pollat       ! Longitude and latitude of pole
80
      real         p3(nx,ny,nz)        ! Staggered levels
81
      real         ps(nx,ny)           ! Surface pressure
82
      real         time                ! Time of the grid information
83
      real         ak(nz),bk(nz)       ! Ak and Bk for layers or levels
84
      real         stagz               ! Vertical staggering (0 or -0.5)
85
      character*80 fieldname           ! Variable from which to take grid info
86
      character*80 timecheck           ! Either 'yes' or 'no'
87
 
88
c     Numerical epsilon
89
      real         eps
90
      parameter    (eps=0.0001)
91
 
92
c     Auxiliary varaibles
93
      integer      ierr       
94
      integer      i,j,k
95
      character*80 varname
96
      character*80 newname
97
      real         lon(1000),lat(1000),lev(1000),lev2(1000)
98
      integer      varid,lonid,latid,levid
99
      integer      nz2
100
      real         tmp(nx-1,ny)
101
      integer      indx
102
      real         lon1
103
      integer      itmp
104
 
105
c     Inquire dimensions and grid constants if <fid> is negative
106
      if (fid.lt.0) then
107
 
108
c       Longitude
109
        ierr = nf90_inq_dimid(-fid,'lon', lonid)
110
        IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
111
        ierr = nf90_inquire_dimension(-fid, lonid, len = nx)
112
        IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
113
        ierr = NF90_INQ_VARID(-fid,'lon',varid)
114
        IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
115
        ierr = NF90_GET_VAR(-fid,varid,lon(1:nx))
116
        IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
117
 
118
c       Latitude
119
        ierr = nf90_inq_dimid(-fid,'lat', latid)
120
        IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
121
        ierr = nf90_inquire_dimension(-fid, latid, len = ny)
122
        IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
123
        ierr = NF90_INQ_VARID(-fid,'lat',varid)
124
        IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
125
        ierr = NF90_GET_VAR(-fid,varid,lat(1:ny))
126
        IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
127
 
128
c       Set grid parameters and compare to expected setting
129
        xmin   = lon(1)
130
        xmax   = lon(nx)
131
        ymin   = lat(ny)
132
        ymax   = lat(1)
133
        dx     = (xmax-xmin)/real(nx-1)
134
        dy     = (ymax-ymin)/real(ny-1)
135
        if (
136
     >       ( nx              .ne.180 ).or.
137
     >       ( ny              .ne.91  ).or.
138
     >       ( abs(xmin -   0.).gt.eps ).or.
139
     >       ( abs(xmax - 358.).gt.eps ).or.
140
     >       ( abs(ymin +  90.).gt.eps ).or.
141
     >       ( abs(ymax -  90.).gt.eps ).or.
142
     >       ( abs(dx   -   2.).gt.eps ).or.
143
     >       ( abs(dy   -   2.).gt.eps ) )
144
     >  then
145
          print*,' ERROR: grid does not agree with expectation.. Stop'
146
          stop
147
        endif
148
 
149
c       Vertical levels
150
        ierr = nf90_inq_dimid(-fid,'level', levid)
151
        IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
152
        ierr = nf90_inquire_dimension(-fid, levid, len = nz)
153
        IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
154
        ierr = NF90_INQ_VARID(-fid,'level',varid)
155
        IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
156
        ierr = NF90_GET_VAR(-fid,varid,lev(1:nz))
157
        IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
158
 
159
c       Get vertical levels for omega and check consistence
160
        ierr = nf90_inq_dimid(-fid,'level_2', levid)
161
        IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
162
        ierr = nf90_inquire_dimension(-fid, levid, len = nz2)
163
        IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
164
        ierr = NF90_INQ_VARID(-fid,'level_2',varid)
165
        IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
166
        ierr = NF90_GET_VAR(-fid,varid,lev2(1:nz2))
167
        IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
168
 
169
        if (nz.gt.nz2 ) then
170
            itmp = nz
171
            nz   = nz2
172
            nz2  = itmp
173
        endif
174
 
175
        if ( ( nz.ne.19 ).or.(nz2.ne.24) ) then
176
          print*,' ERROR: grid inconsitence... level vs level_2'
177
          print*,'nz,nz2 ',nz,nz2
178
          stop
179
        endif
180
        do i=1,nz
181
            if ( abs( lev2(i)-lev(i) ).gt.eps ) then
182
                print*,' ERROR: grid inconsitence... level vs level_2'
183
                print*,i,lev2(i),lev(i)
184
                stop
185
            endif
186
        enddo
187
 
188
c       Set the final (expected) parameters, including closing and shifting
189
        nx     = 181
190
        ny     = 91
191
        nz     = 19
192
        xmin   = -180.
193
        xmax   = 180.
194
        ymin   = -90.
195
        ymax   = 90.
196
        dx     = 2.
197
        dy     = 2.
198
        pollon = 0.
199
        pollat = 90.
200
        stagz  = 0.
201
 
202
c     Get non-constant grid parameters (surface pressure and vertical grid)
203
      else
204
 
205
c       Set 3D pressure
206
        ierr = NF90_INQ_VARID(fid,'level_2',varid)
207
        IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
208
        ierr = NF90_GET_VAR(fid,varid,lev(1:nz))
209
        IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
210
 
211
        do i=1,nx
212
          do j=1,ny
213
            do k=1,nz
214
              p3(i,j,k) = lev(k)
215
            enddo
216
          enddo
217
        enddo
218
 
219
c       Set ak, bk
220
        do k=1,nz
221
           ak(k) = lev(k)
222
           bk(k) = 0.
223
        enddo
224
 
225
c       Read surface pressure (close and shift/swap domain; unit conversion)
226
        varname = 'pres'
227
        ierr = NF90_INQ_VARID(fid,varname,varid)
228
        IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
229
        ierr = NF90_GET_VAR(fid,varid,tmp(1:(nx-1),1:ny))
230
        IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
231
 
232
        do i=1,nx-1
233
            lon1 = xmin + real(i-1)*dx
234
            if ( lon1.lt.-eps ) lon1 = lon1 + 360.
235
            indx = nint( lon1 / dx + 1. )
236
            do j=1,ny
237
                ps(i,j) = 0.01 * tmp(indx,ny-j+1)
238
            enddo
239
        enddo
240
        do j=1,ny
241
            ps(nx,j) = ps(1,j)
242
        enddo
243
 
244
      endif
245
 
246
      end
247
 
248
c     ------------------------------------------------------------
249
c     Read wind and other met field
250
c     ------------------------------------------------------------
251
 
252
      subroutine input_wind (fid,fieldname,field,time,stagz,mdv,
253
     >                       xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,
254
     >                       timecheck)
255
 
256
      use netcdf
257
 
258
c     Read the wind component <fieldname> from the file with identifier
259
c     <fid> and save it in the 3d array <field>. The vertical staggering 
260
c     information is provided in <stagz> and gives the reference to either
261
c     the layer or level field from <input_grid>. A consistency check is
262
c     performed to have an agreement with the grid specified by <xmin,xmax,
263
c     ymin,ymax,dx,dy,nx,ny,nz>.
264
 
265
      implicit none
266
 
267
c     Declaration of variables and parameters
268
      integer      fid                 ! File identifier
269
      character*80 fieldname           ! Name of the wind field
270
      integer      nx,ny,nz            ! Dimension of fields
271
      real         field(nx,ny,nz)     ! 3d wind field
272
      real         stagz               ! Staggering in the z direction
273
      real         mdv                 ! Missing data flag
274
      real         xmin,xmax,ymin,ymax ! Domain size
275
      real         dx,dy               ! Horizontal resolution
276
      real         time                ! Time
277
      character*80 timecheck           ! Either 'yes' or 'no'
278
 
279
c     Netcdf variables
280
      integer      ierr
281
      character*80 varname
282
      character*80 newname
283
 
284
c     Numerical epsilon
285
      real         eps
286
      parameter    (eps=0.0001)
287
 
288
c     Auxiliary variables
289
      integer      i,j,k
290
      real         lev(1000)
291
      integer      varid
292
      real         tmp(nx-1,ny,nz)
293
      real         lon(nx-1)
294
      integer      indx
295
      real         lon1
296
      integer      is2d
297
 
298
c     Set the correct fieldname
299
      newname = fieldname
300
      if ( fieldname.eq.'PLEV'  ) newname='P'
301
      if ( fieldname.eq.'PLAY'  ) newname='P'
302
      if ( fieldname.eq.'P'     ) newname='P'
303
      if ( fieldname.eq.'OMEGA' ) newname='omega'
304
      if ( fieldname.eq.'PS'    ) newname='pres'
305
      if ( fieldname.eq.'U'     ) newname='uwnd'
306
      if ( fieldname.eq.'V'     ) newname='vwnd'
307
 
308
c     Get flag for 2D field
309
      is2d = 0
310
      if ( fieldname.eq.'pres' ) is2d = 1
311
 
312
c     Get 3D pressure
313
      if ( fieldname.eq.'P' ) then
314
 
315
        varname = 'level'
316
        ierr = NF90_INQ_VARID(fid,varname,varid)
317
        IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
318
        ierr = NF90_GET_VAR(fid,varid,lev(1:nz))
319
        IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
320
 
321
        do i=1,nx
322
          do j=1,ny
323
            do k=1,nz
324
              field(i,j,k) = lev(k)
325
            enddo
326
          enddo
327
        enddo
328
 
329
        mdv  = -9.96921e+36
330
 
331
c     Get 3D field (close and shift/swap domain)
332
      elseif ( is2d.eq.0 ) then
333
 
334
        varname = newname
335
        ierr = NF90_INQ_VARID(fid,varname,varid)
336
        IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
337
        ierr = NF90_GET_VAR(fid,varid,tmp(1:(nx-1),1:ny,1:nz))
338
        IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
339
        ierr  = nf90_get_att(fid, varid, "_FillValue", mdv)
340
        IF (ierr /= nf90_NoErr) THEN
341
            mdv  = -9.96921e+36
342
            ierr = nf90_NoErr
343
        ENDIF
344
 
345
        do i=1,nx-1
346
          lon1 = xmin + real(i-1)*dx
347
          if ( lon1.lt.-eps ) lon1 = lon1 + 360.
348
          indx = nint( lon1 / dx + 1. )
349
          do k=1,nz
350
            do j=1,ny
351
              field(i,j,k) = tmp(indx,ny-j+1,k)
352
            enddo
353
            field(nx,j,k) = field(1,j,k)
354
          enddo
355
        enddo
356
 
357
c     Get 2D field (close and shift/swap domain)
358
      elseif ( is2d.eq.1 ) then
359
 
360
        varname = newname
361
        ierr = NF90_INQ_VARID(fid,varname,varid)
362
        IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
363
        ierr = NF90_GET_VAR(fid,varid,tmp(1:(nx-1),1:ny,1:1))
364
        IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
365
        ierr  = nf90_get_att(fid, varid, "_FillValue", mdv)
366
        IF (ierr /= nf90_NoErr) THEN
367
            mdv  = -9.96921e+36
368
            ierr = nf90_NoErr
369
        ENDIF
370
 
371
        do i=1,nx-1
372
          lon1 = xmin + real(i-1)*dx
373
          if ( lon1.lt.-eps ) lon1 = lon1 + 360.
374
          indx = nint( lon1 / dx + 1. )
375
          do j=1,ny
376
            field(i,j,1) = tmp(indx,ny-j+1,1)
377
            do k=2,nz
378
              field(i,j,k) = field(i,j,k-1)
379
            enddo
380
            field(nx,j,k) = field(1,j,k)
381
          enddo
382
        enddo
383
 
384
      endif
385
 
386
      end
387
 
388
c     ------------------------------------------------------------
389
c     Close input file
390
c     ------------------------------------------------------------
391
 
392
      subroutine input_close(fid)
393
 
394
c     Close the input file with file identifier <fid>.
395
 
396
      use netcdf
397
 
398
      implicit none
399
 
400
c     Declaration of subroutine parameters
401
      integer fid
402
 
403
c     Auxiliary variables
404
      integer ierr
405
 
406
      ierr = NF90_CLOSE(fid)
407
      IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
408
 
409
 
410
 
411
      end