Subversion Repositories lagranto.ecmwf

Rev

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

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