Subversion Repositories lagranto.ecmwf

Rev

Rev 27 | Rev 31 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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