Subversion Repositories lagranto.ecmwf

Rev

Rev 23 | Rev 27 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
3 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
 
21 michaesp 34
      use netcdf
35
 
3 michaesp 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
 
21 michaesp 45
c     Open netcdf file
46
      ierr = NF90_OPEN(TRIM(filename),nf90_nowrite, fid)
47
      IF ( ierr /= nf90_NoErr ) PRINT *,NF90_STRERROR(ierr)
48
 
3 michaesp 49
c     Exception handling
50
      return
51
 
52
      end
21 michaesp 53
 
3 michaesp 54
c     ------------------------------------------------------------
55
c     Read information about the grid
56
c     ------------------------------------------------------------
57
 
58
      subroutine input_grid 
59
     >                   (fid,fieldname,xmin,xmax,ymin,ymax,dx,dy,nx,ny,
60
     >                    time,pollon,pollat,p3,ps,nz,ak,bk,stagz,
61
     >                    timecheck)
62
 
63
c     Read grid information at <time> from file with identifier <fid>. 
64
c     The horizontal grid is characterized by <xmin,xmax,ymin,ymax,dx,dy>
65
c     with pole position at <pollon,pollat> and grid dimension <nx,ny>.
66
c     The 3d arrays <p3(nx,ny,nz)> gives the vertical coordinates, either
67
c     on the staggered or unstaggered grid (with <stagz> as the flag).
68
c     The surface pressure is given in <ps(nx,ny)>. If <fid> is negative, 
69
c     only the grid dimensions and grid parameters (xmin...pollat,nz) are 
70
c     determined and returned (this is needed for dynamical allocation of 
71
c     memory).
72
 
21 michaesp 73
      use netcdf
74
 
3 michaesp 75
      implicit none
76
 
77
c     Declaration of subroutine parameters 
78
      integer      fid                 ! File identifier
79
      real         xmin,xmax,ymin,ymax ! Domain size
80
      real         dx,dy               ! Horizontal resolution
81
      integer      nx,ny,nz            ! Grid dimensions
82
      real         pollon,pollat       ! Longitude and latitude of pole
83
      real         p3(nx,ny,nz)        ! Staggered levels
84
      real         ps(nx,ny)           ! Surface pressure
85
      real         time                ! Time of the grid information
86
      real         ak(nz),bk(nz)       ! Ak and Bk for layers or levels
87
      real         stagz               ! Vertical staggering (0 or -0.5)
88
      character*80 fieldname           ! Variable from which to take grid info
89
      character*80 timecheck           ! Either 'yes' or 'no'
90
 
91
c     Numerical and physical parameters
92
      real          eps                 ! Numerical epsilon
93
      parameter    (eps=0.001)
94
 
95
c     Netcdf variables
96
      integer      vardim(4)
97
      real         varmin(4),varmax(4)
98
      real         mdv
99
      real         stag(4)
100
      integer      ndim
101
      character*80 cstfile
102
      integer      cstid
103
      integer      nvars
104
      character*80 vars(100)
25 michaesp 105
      integer        dimids (nf90_max_var_dims),dimid
21 michaesp 106
      character*80   dimname(nf90_max_var_dims)
25 michaesp 107
      character*80   stdname
21 michaesp 108
      real,allocatable, dimension (:)     :: lon,lat,lev
109
      real,allocatable, dimension (:)     :: times
110
      real,allocatable, dimension (:,:)   :: tmp2
111
      real,allocatable, dimension (:,:,:) :: tmp3
23 michaesp 112
      real,allocatable, dimension (:)     :: aktmp,bktmp
21 michaesp 113
      character*80  units
25 michaesp 114
      character*80  leveltype
115
      integer       nakbktmp
116
      integer       vertical_swap
3 michaesp 117
 
21 michaesp 118
c     Auxiliary variables
3 michaesp 119
      integer      ierr       
120
      integer      i,j,k
121
      integer      isok
122
      real         tmp(200)
123
      character*80 varname
124
      real         rtime
21 michaesp 125
      integer      varid
126
      integer      cdfid
127
      integer      stat
128
      real         delta
129
      integer      closear
130
      real         maxps,minps
3 michaesp 131
 
25 michaesp 132
c     ---- Read data from netCDF file as they are ---------------------
133
 
134
c     Set file identifier
3 michaesp 135
      if (fid.lt.0) then
21 michaesp 136
        cdfid = -fid
137
      else 
138
        cdfid = fid
139
      endif
3 michaesp 140
 
21 michaesp 141
c     Special handling if 3D pressure is
142
      if ( fieldname.eq.'P' ) then
143
         fieldname = 'U'
144
      endif
3 michaesp 145
 
21 michaesp 146
c     Get number of dimensions of variable -> ndim
147
      ierr = NF90_INQ_VARID(cdfid,fieldname,varid)
148
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
149
      ierr = nf90_inquire_variable(cdfid, varid, ndims  = ndim)
150
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
151
      if ( ndim.ne.4 ) then
152
          print*,' ERROR: netCDF variables need to be 4D'
153
          print*,'      ',trim(fieldname)
154
          stop
155
      endif
3 michaesp 156
 
21 michaesp 157
c     Get dimensions -> vardim(1:ndim),dimname(1:ndim)
158
      ierr = NF90_INQ_VARID(cdfid,fieldname,varid)
159
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
160
      ierr = nf90_inquire_variable(cdfid, varid, 
161
     >                                   dimids = dimids(1:ndim))
162
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
163
      do i=1,ndim
164
           ierr = nf90_inquire_dimension(cdfid, dimids(i), 
165
     >                               name = dimname(i) )
166
           IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
167
           ierr = nf90_inquire_dimension(cdfid, dimids(i),len=vardim(i))
168
           IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
169
      enddo
3 michaesp 170
 
25 michaesp 171
c     Get dimension of AK,BK
172
      varname = 'nhym'
173
      ierr = NF90_INQ_DIMID(cdfid,varname,dimid)
174
      ierr = nf90_inquire_dimension(cdfid, dimid,len=nakbktmp)
175
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
176
 
21 michaesp 177
c     Check whether the list of dimensions is OK
178
      if ( ( dimname(1).ne.'lon'  ).or.
179
     >     ( dimname(2).ne.'lat'  ).or. 
180
     >     ( dimname(3).ne.'lev'  ).and.( dimname(3).ne.'lev_2'  ).or.
181
     >     ( dimname(4).ne.'time' ) )
182
     >then
183
        print*,' ERROR: the dimensions of the variable are not correct'
184
        print*,'        expected -> lon / lat / lev / time'
185
        print*, ( trim(dimname(i))//' / ',i=1,ndim )
186
        stop
187
      endif
3 michaesp 188
 
25 michaesp 189
c     Check about the type of vertical levels
190
      varname=dimname(3)
191
      ierr = NF90_INQ_VARID(cdfid,varname,varid)
192
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
193
      ierr = nf90_get_att(cdfid, varid, "standard_name", leveltype)
194
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
195
      if ( (leveltype.ne.'hybrid_sigma_pressure').and.
196
     >     (leveltype.ne.'air_pressure'         ) )
197
     >then
198
         print*,' ERROR: input netCDF data must be on hybrid-sigma'
199
         print*,'        or air pressure levels!',trim(leveltype)
200
         stop
201
      endif
202
 
203
c     Check that vardim(3)==#AK,BK for hybrid-sigmal levels
204
      if ( (leveltype.eq.'hybrid_sigma_pressure').and.
205
     >     (dimname(3).eq.'lev') )
206
     >then
207
        if ( nakbktmp.ne.vardim(3) ) then
208
           print*,' ERROR: for hybrid-sigma pressure levels, #AK,BK'
209
           print*,'        must agree with number of vertical levels'
210
           print*,'        ',vardim(3),nakbktmp
211
           stop
212
        endif
213
      endif
214
 
21 michaesp 215
c     Allocate memory for reading arrays
216
      allocate(tmp2(vardim(1),vardim(2)),stat=stat)
217
      if (stat.ne.0) print*,'*** error allocating array tmp2     ***'
218
      allocate(tmp3(vardim(1),vardim(2),vardim(3)),stat=stat)
219
      if (stat.ne.0) print*,'*** error allocating array tmp3     ***'
220
      allocate(lon(vardim(1)),stat=stat)
221
      if (stat.ne.0) print*,'*** error allocating array lon     ***' 
222
      allocate(lat(vardim(2)),stat=stat)
223
      if (stat.ne.0) print*,'*** error allocating array lat     ***' 
25 michaesp 224
      allocate(lev(vardim(3)),stat=stat)
225
      if (stat.ne.0) print*,'*** error allocating array lev     ***'
21 michaesp 226
      allocate(times(vardim(4)),stat=stat)
227
      if (stat.ne.0) print*,'*** error allocating array times   ***'
25 michaesp 228
      allocate(aktmp(nakbktmp),stat=stat)
23 michaesp 229
      if (stat.ne.0) print*,'*** error allocating array aktmp   ***'
25 michaesp 230
      allocate(bktmp(nakbktmp),stat=stat)
23 michaesp 231
      if (stat.ne.0) print*,'*** error allocating array bktmp   ***'
19 michaesp 232
 
25 michaesp 233
c     Get domain longitudes, latitudes and levels
21 michaesp 234
      varname = dimname(1)
235
      ierr = NF90_INQ_VARID(cdfid,varname,varid)
236
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
237
      ierr = nf90_get_var(cdfid,varid,lon)
238
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
239
      varname = dimname(2)
240
      ierr = NF90_INQ_VARID(cdfid,varname,varid)
241
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
242
      ierr = nf90_get_var(cdfid,varid,lat)
243
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
25 michaesp 244
      varname = dimname(3)
245
      ierr = NF90_INQ_VARID(cdfid,varname,varid)
246
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
247
      ierr = nf90_get_var(cdfid,varid,lev)
248
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
21 michaesp 249
 
250
c     Get ak and bk
251
      varname='hyam'
252
      ierr = NF90_INQ_VARID(cdfid,varname,varid)
253
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
23 michaesp 254
      ierr = nf90_get_var(cdfid,varid,aktmp)
21 michaesp 255
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
256
      varname='hybm'
257
      ierr = NF90_INQ_VARID(cdfid,varname,varid)
258
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
23 michaesp 259
      ierr = nf90_get_var(cdfid,varid,bktmp)
21 michaesp 260
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
19 michaesp 261
 
21 michaesp 262
c     Check that unit of ak is in hPa - if necessary correct it
263
      varname='hyam'
264
      ierr = NF90_INQ_VARID(cdfid,varname,varid)
265
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
266
      ierr = nf90_get_att(cdfid, varid, "units", units)
267
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
268
      if ( units.eq.'Pa' ) then
25 michaesp 269
         do k=1,nakbktmp
23 michaesp 270
            aktmp(k) = 0.01 * aktmp(k)
21 michaesp 271
         enddo
272
      endif
19 michaesp 273
 
25 michaesp 274
c     Check that unit of lev is in hPa - if necessary correct it
275
      if ( leveltype.eq.'air_pressure' ) then
276
         varname='lev'
277
         ierr = NF90_INQ_VARID(cdfid,varname,varid)
278
         IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
279
         ierr = nf90_get_att(cdfid, varid, "units", units)
280
         IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
281
         if ( units.eq.'Pa' ) then
282
            do k=1,vardim(3)
283
               lev(k) = 0.01 * lev(k)
284
            enddo
285
         endif
286
      endif
287
 
288
c     Decide whether to swap vertical levels
289
      vertical_swap = 1
290
      if ( leveltype.eq.'hybrid_sigma_pressure') then
291
        if ( (aktmp(1) + bktmp(1) * 1000.).gt.
292
     >       (aktmp(2) + bktmp(2) * 1000.) )
293
     >  then
294
          vertical_swap = 0
295
        endif
296
      elseif ( leveltype.eq.'air_pressure') then
297
        if ( lev(1).gt.lev(2) ) then
298
          vertical_swap = 0
299
        endif
300
      endif
301
c      print*,' Vertical SWAP P -> ', vertical_swap
302
 
21 michaesp 303
c     Get time information (check if time is correct)
304
      varname = 'time'
305
      ierr = NF90_INQ_VARID(cdfid,varname,varid)
306
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
307
      ierr = nf90_get_var(cdfid,varid,times)
308
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
309
      isok=0
310
      do i=1,vardim(4)
311
        if (abs(time-times(i)).lt.eps) then
3 michaesp 312
               isok = 1
313
               rtime = times(i)
21 michaesp 314
        elseif (timecheck.eq.'no') then
3 michaesp 315
               isok = 1
316
               rtime = times(1)
21 michaesp 317
        endif
318
      enddo
319
      if ( isok.eq.0 ) then
320
         print*,' ERROR: time ',rtime,' not found on netCDF file' 
321
         stop
322
      endif
3 michaesp 323
 
21 michaesp 324
c     Read surface pressure
325
      varname='PS'
326
      ierr = NF90_INQ_VARID(cdfid,varname,varid)
327
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
328
      ierr = nf90_get_var(cdfid,varid,tmp2)
329
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
330
 
331
c     Check that surface pressure is in hPa
25 michaesp 332
      maxps = -1.e19
333
      minps =  1.e19
21 michaesp 334
      do i=1,vardim(1)
335
        do j=1,vardim(2)
336
             if (tmp2(i,j).gt.maxps) maxps = tmp2(i,j)
337
             if (tmp2(i,j).lt.minps) minps = tmp2(i,j)
338
        enddo
339
      enddo
340
      if ( (maxps.gt.1500.).or.(minps.lt.300.) ) then
341
         print*,' ERROR: surface pressre PS must be in hPa'
342
         print*,'       ',maxps,minps
343
         stop
344
      endif
345
 
25 michaesp 346
c     ---- Define output of subroutine --------------------------------
3 michaesp 347
 
21 michaesp 348
c     Set the grid dimensions and constants
349
      nx      = vardim(1)
350
      ny      = vardim(2)
351
      nz      = vardim(3)
352
      xmin    = lon(1)
353
      ymin    = lat(1)
354
      xmax    = lon(nx)
355
      ymax    = lat(ny)
356
      dx      = (xmax-xmin)/real(nx-1)
357
      dy      = (ymax-ymin)/real(ny-1)
358
      pollon  = 0.
359
      pollat  = 90.
360
      stagz   = 0.
361
      delta   = xmax-xmin-360.
362
      if (abs(delta+dx).lt.eps) then
363
          xmax    = xmax + dx
364
          nx      = nx + 1
365
          closear = 1
366
      else
367
          closear = 0
368
      endif
3 michaesp 369
 
21 michaesp 370
c     Save the output arrays (if fid>0) - close arrays on request
371
      if ( fid.gt.0 ) then
3 michaesp 372
 
25 michaesp 373
c        Calculate layer pressures
374
         if (leveltype.eq.'hybrid_sigma_pressure' ) then
375
            do i=1,vardim(1)
376
              do j=1,vardim(2)
377
                 do k=1,vardim(3)
378
                  tmp3(i,j,k)=aktmp(k)+bktmp(k)*tmp2(i,j)
379
                 enddo
380
              enddo
381
           enddo
382
         elseif (leveltype.eq.'air_pressure' ) then
383
           do i=1,vardim(1)
384
              do j=1,vardim(2)
385
                 do k=1,vardim(3)
386
                  tmp3(i,j,k)=lev(k)
387
                 enddo
388
              enddo
389
           enddo
390
         endif
391
 
392
c        Get PS - close array on demand
21 michaesp 393
         do j=1,vardim(2)
394
           do i=1,vardim(1)
395
             ps(i,j) = tmp2(i,j)
396
           enddo
397
           if (closear.eq.1) ps(vardim(1)+1,j) = ps(1,j)
3 michaesp 398
         enddo
399
 
25 michaesp 400
c        Get P3 - close array on demand + vertical swap
21 michaesp 401
         do j=1,vardim(2)
402
           do k=1,vardim(3)
403
             do i=1,vardim(1)
25 michaesp 404
               if ( vertical_swap.eq.1 ) then
405
                  p3(i,j,k) = tmp3(i,j,vardim(3)-k+1)
406
               else
407
                  p3(i,j,k) = tmp3(i,j,k)
408
               endif
21 michaesp 409
             enddo
410
             if (closear.eq.1) p3(vardim(1)+1,j,k) = p3(1,j,k)
411
           enddo
3 michaesp 412
         enddo
23 michaesp 413
 
25 michaesp 414
c        Get AK,BK - vertical swap on demand
415
         if ( leveltype.eq.'hybrid_sigma_pressure' ) then
416
           do k=1,vardim(3)
417
              if ( vertical_swap.eq.1 ) then
418
                 ak(k) = aktmp(vardim(3)-k+1)
419
                 bk(k) = bktmp(vardim(3)-k+1)
420
              endif
421
           enddo
422
         elseif (leveltype.eq.'air_pressure' ) then
423
           do k=1,vardim(3)
424
              if ( vertical_swap.eq.1 ) then
425
                 ak(k) = lev(vardim(3)-k+1)
426
                 bk(k) = 0.
427
              else
428
                ak(k) = lev(k)
429
                bk(k) = 0.
430
              endif
431
           enddo
432
         endif
23 michaesp 433
 
21 michaesp 434
      endif
3 michaesp 435
 
25 michaesp 436
 
3 michaesp 437
      return
438
 
439
      end
440
 
441
c     ------------------------------------------------------------
442
c     Read wind information
443
c     ------------------------------------------------------------
444
 
445
      subroutine input_wind (fid,fieldname,field,time,stagz,mdv,
446
     >                       xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,
447
     >                       timecheck)
448
 
449
c     Read the wind component <fieldname> from the file with identifier
450
c     <fid> and save it in the 3d array <field>. The vertical staggering 
451
c     information is provided in <stagz> and gives the reference to either
452
c     the layer or level field from <input_grid>. A consistency check is
453
c     performed to have an agreement with the grid specified by <xmin,xmax,
454
c     ymin,ymax,dx,dy,nx,ny,nz>.
455
 
21 michaesp 456
      use netcdf
457
 
3 michaesp 458
      implicit none
459
 
460
c     Declaration of variables and parameters
461
      integer      fid                 ! File identifier
462
      character*80 fieldname           ! Name of the wind field
463
      integer      nx,ny,nz            ! Dimension of fields
464
      real         field(nx,ny,nz)     ! 3d wind field
465
      real         stagz               ! Staggering in the z direction
466
      real         mdv                 ! Missing data flag
467
      real         xmin,xmax,ymin,ymax ! Domain size
468
      real         dx,dy               ! Horizontal resolution
469
      real         time                ! Time
470
      character*80 timecheck           ! Either 'yes' or 'no'
471
 
472
c     Numerical and physical parameters
473
      real        eps                 ! Numerical epsilon
474
      parameter  (eps=0.001)
475
      real        notimecheck         ! 'Flag' for no time check
476
      parameter  (notimecheck=7.26537)
477
 
478
c     Netcdf variables
479
      integer      ierr
480
      character*80 varname
481
      integer      vardim(4)
482
      real         varmin(4),varmax(4)
483
      real         stag(4)
484
      integer      ndim
485
      real         times(10)
486
      integer      ntimes
487
      character*80 cstfile
488
      integer      cstid
489
      real         aklay(200),bklay(200),aklev(200),bklev(200)
490
      real         ps(nx,ny)
21 michaesp 491
      integer      dimids (nf90_max_var_dims)
492
      character*80 dimname(nf90_max_var_dims)
493
      integer      varid
494
      integer      cdfid
25 michaesp 495
      real,allocatable, dimension (:)     :: lon,lat,lev
21 michaesp 496
      real,allocatable, dimension (:,:)   :: tmp2
497
      real,allocatable, dimension (:,:,:) :: tmp3
25 michaesp 498
      real,allocatable, dimension (:)     :: aktmp,bktmp
499
      character*80  leveltype
500
      integer       vertical_swap
501
      character*80  units
502
      integer       nakbktmp
503
      integer       dimid
3 michaesp 504
 
505
c     Auxiliary variables
506
      integer      isok
507
      integer      i,j,k
508
      integer      nz1
509
      real         rtime
21 michaesp 510
      integer      closear
511
      integer      stat
512
      real         delta
3 michaesp 513
 
21 michaesp 514
c     Get the number of dimensions -> ndim
515
      ierr = NF90_INQ_VARID(fid,fieldname,varid)
516
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
517
      ierr = nf90_inquire_variable(fid, varid, ndims  = ndim)
518
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
19 michaesp 519
 
21 michaesp 520
c     Get the dimensions of the arrays -> varid(1:ndim)
521
      ierr = NF90_INQ_VARID(fid,fieldname,varid)
522
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
523
      ierr = nf90_inquire_variable(fid, varid, 
524
     >                                   dimids = dimids(1:ndim))
525
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
526
      do i=1,ndim
527
           ierr = nf90_inquire_dimension(fid, dimids(i), 
528
     >                               name = dimname(i) )
529
           IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
530
           ierr = nf90_inquire_dimension(fid, dimids(i),len=vardim(i))
531
           IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
3 michaesp 532
      enddo
533
 
21 michaesp 534
c     Check whether the list of dimensions is OK
535
      if ( ( dimname(1).ne.'lon'  ).or.
536
     >     ( dimname(2).ne.'lat'  ).or.
537
     >     ( dimname(3).ne.'lev'  ).and.( dimname(3).ne.'lev_2'  ).or.
538
     >     ( dimname(4).ne.'time' ) )
539
     >then
540
        print*,' ERROR: the dimensions of the variable are not correct'
541
        print*,'        expected -> lon / lat / lev / time'
542
        print*, ( trim(dimname(i))//' / ',i=1,ndim )
543
        stop
544
      endif
3 michaesp 545
 
25 michaesp 546
c     Get dimension of AK,BK
547
      varname = 'nhym'
548
      ierr = NF90_INQ_DIMID(fid,varname,dimid)
549
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
550
      ierr = nf90_inquire_dimension(fid, dimid,len=nakbktmp)
551
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
552
 
553
c     Check about the type of vertical levels
554
      varname=dimname(3)
555
      ierr = NF90_INQ_VARID(fid,varname,varid)
556
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
557
      ierr = nf90_get_att(fid, varid, "standard_name", leveltype)
558
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
559
      if ( (leveltype.ne.'hybrid_sigma_pressure').and.
560
     >     (leveltype.ne.'air_pressure'         ) )
561
     >then
562
         print*,' ERROR: input netCDF data must be on hybrid-sigma'
563
         print*,'        or air pressure levels!',trim(leveltype)
564
         stop
565
      endif
566
 
567
c     Check that vardim(3)==#AK,BK for hybrid-sigmal levels
568
      if ( (leveltype.eq.'hybrid_sigma_pressure').and.
569
     >     (dimname(3).eq.'lev') )
570
     >then
571
        if ( nakbktmp.ne.vardim(3) ) then
572
           print*,' ERROR: for hybrid-sigma pressure levels, #AK,BK'
573
           print*,'        must agree with number of vertical levels'
574
           print*,'        ',vardim(3),nakbktmp
575
           stop
576
        endif
577
      endif
578
 
21 michaesp 579
c     Allocate memory for reading arrays - depending on <closear>
580
      allocate(tmp2(vardim(1),vardim(2)),stat=stat)
581
      if (stat.ne.0) print*,'*** error allocating array tmp2     ***'
582
      allocate(tmp3(vardim(1),vardim(2),vardim(3)),stat=stat)
583
      if (stat.ne.0) print*,'*** error allocating array tmp3     ***'
584
      allocate(lon(vardim(1)),stat=stat)
585
      if (stat.ne.0) print*,'*** error allocating array lon     ***'
586
      allocate(lat(vardim(2)),stat=stat)
587
      if (stat.ne.0) print*,'*** error allocating array lat     ***'
25 michaesp 588
      allocate(lev(vardim(3)),stat=stat)
589
      if (stat.ne.0) print*,'*** error allocating array lev     ***'
590
      allocate(aktmp(nakbktmp),stat=stat)
591
      if (stat.ne.0) print*,'*** error allocating array aktmp   ***'
592
      allocate(bktmp(nakbktmp),stat=stat)
593
      if (stat.ne.0) print*,'*** error allocating array bktmp   ***'
3 michaesp 594
 
25 michaesp 595
c     Get domain boundaries - longitude, latitude, levels
21 michaesp 596
      varname = dimname(1)
597
      ierr = NF90_INQ_VARID(fid,varname,varid)
598
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
599
      ierr = nf90_get_var(fid,varid,lon)
600
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
601
      varname = dimname(2)
602
      ierr = NF90_INQ_VARID(fid,varname,varid)
603
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
604
      ierr = nf90_get_var(fid,varid,lat)
605
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
25 michaesp 606
      varname = dimname(3)
607
      ierr = NF90_INQ_VARID(fid,varname,varid)
608
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
609
      ierr = nf90_get_var(fid,varid,lev)
610
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
3 michaesp 611
 
25 michaesp 612
c     Get ak and bk
613
      varname='hyam'
614
      ierr = NF90_INQ_VARID(fid,varname,varid)
615
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
616
      ierr = nf90_get_var(fid,varid,aktmp)
617
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
618
      varname='hybm'
619
      ierr = NF90_INQ_VARID(fid,varname,varid)
620
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
621
      ierr = nf90_get_var(fid,varid,bktmp)
622
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
623
 
624
c     Check that unit of ak is in hPa - if necessary correct it
625
      varname='hyam'
626
      ierr = NF90_INQ_VARID(fid,varname,varid)
627
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
628
      ierr = nf90_get_att(fid, varid, "units", units)
629
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
630
      if ( units.eq.'Pa' ) then
631
         do k=1,nakbktmp
632
            aktmp(k) = 0.01 * aktmp(k)
633
         enddo
634
      endif
635
 
636
c     Check that unit of lev is in hPa - if necessary correct it
637
      if ( leveltype.eq.'air_pressure' ) then
638
         varname='lev'
639
         ierr = NF90_INQ_VARID(fid,varname,varid)
640
         IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
641
         ierr = nf90_get_att(fid, varid, "units", units)
642
         IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
643
         if ( units.eq.'Pa' ) then
644
            do k=1,vardim(3)
645
               lev(k) = 0.01 * lev(k)
646
            enddo
647
         endif
648
      endif
649
 
650
c     Decide whether to swap vertical levels
651
      vertical_swap = 1
652
      if ( leveltype.eq.'hybrid_sigma_pressure') then
653
        if ( (aktmp(1) + bktmp(1) * 1000.).gt.
654
     >       (aktmp(2) + bktmp(2) * 1000.) )
655
     >  then
656
          vertical_swap = 0
657
        endif
658
      elseif ( leveltype.eq.'air_pressure') then
659
        if ( lev(1).gt.lev(2) ) then
660
          vertical_swap = 0
661
        endif
662
      endif
663
c      print*,' Vertical SWAP ',trim(fieldname),' -> ', vertical_swap
664
 
21 michaesp 665
c     Read data 
666
      ierr = NF90_INQ_VARID(fid,fieldname,varid)
667
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
668
      ierr = nf90_get_var(fid,varid,tmp3)
669
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
670
 
3 michaesp 671
c     If the field is 2D, expand it to 3D - simple handling of 2D tracing
672
      if ( vardim(3).eq.1 ) then
21 michaesp 673
         do i=1,vardim(1)
674
            do j=1,vardim(2)
675
               do k=1,vardim(3)
676
                  tmp3(i,j,k) = tmp3(i,j,1)
3 michaesp 677
               enddo
678
            enddo
679
         enddo
680
      endif
681
 
25 michaesp 682
c     Decide whether to close arrays
21 michaesp 683
      delta = varmax(1)-varmin(1)-360.
684
      if (abs(delta+dx).lt.eps) then
685
          closear = 1
686
      else
687
          closear = 0
688
      endif
3 michaesp 689
 
25 michaesp 690
c     Save output array - close array and swap on demand
21 michaesp 691
      do j=1,vardim(2)
692
        do k=1,vardim(3)
693
          do i=1,vardim(1)
25 michaesp 694
             if ( vertical_swap.eq.1 ) then
695
                 field(i,j,k) = tmp3(i,j,vardim(3)-k+1)
696
             else
697
                 field(i,j,k) = tmp3(i,j,k)
698
             endif
21 michaesp 699
          enddo
700
          if (closear.eq.1) field(vardim(1)+1,j,k) = field(1,j,k)
701
        enddo
702
      enddo
703
 
704
c     Exit point
3 michaesp 705
      return
21 michaesp 706
 
3 michaesp 707
      end
708
 
709
c     ------------------------------------------------------------
710
c     Close input file
711
c     ------------------------------------------------------------
712
 
713
      subroutine input_close(fid)
714
 
715
c     Close the input file with file identifier <fid>.
716
 
21 michaesp 717
      use netcdf
718
 
3 michaesp 719
      implicit none
720
 
721
c     Declaration of subroutine parameters
722
      integer fid
723
 
724
c     Auxiliary variables
725
      integer ierr
726
 
727
c     Close file
21 michaesp 728
      ierr = NF90_CLOSE(fid)
729
      IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
730
 
731
      end
732
 
733
c     ------------------------------------------------------------
734
c     Get a list of variables on netCDF file
735
c     ------------------------------------------------------------
736
 
737
      subroutine input_getvars(fid,vnam,nvars)
738
 
739
c     List of variables on netCDF file
740
 
741
      use netcdf
742
 
743
      implicit none
744
 
745
c     Declaration of subroutine parameters
746
      integer      fid
747
      integer      nvars
748
      character*80 vnam(200)
749
 
750
c     Auxiliary variables
751
      integer ierr
752
      integer i
753
      integer nDims,nGlobalAtts,unlimdimid
754
 
755
      ierr = nf90_inquire(fid, nDims, nVars, nGlobalAtts, unlimdimid)
756
      IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
757
 
758
      do i=1,nVars
759
         ierr = nf90_inquire_variable(fid, i, name = vnam(i))
760
      enddo
3 michaesp 761
 
762
      end