Subversion Repositories lagranto.arpege

Rev

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