Subversion Repositories lagranto.ecmwf

Rev

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

Rev 29 Rev 31
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
              else
-
 
422
                 ak(k) = aktmp(k)
-
 
423
                 bk(k) = bktmp(k)
421
              endif
424
              endif
422
           enddo
425
           enddo
423
         elseif (leveltype.eq.'air_pressure' ) then
426
         elseif (leveltype.eq.'air_pressure' ) then
424
           do k=1,vardim(3)
427
           do k=1,vardim(3)
425
              if ( vertical_swap.eq.1 ) then
428
              if ( vertical_swap.eq.1 ) then
426
                 ak(k) = lev(vardim(3)-k+1)
429
                 ak(k) = lev(vardim(3)-k+1)
427
                 bk(k) = 0.
430
                 bk(k) = 0.
428
              else
431
              else
429
                ak(k) = lev(k)
432
                ak(k) = lev(k)
430
                bk(k) = 0.
433
                bk(k) = 0.
431
              endif
434
              endif
432
           enddo
435
           enddo
433
         endif
436
         endif
434
 
437
 
435
      endif
438
      endif
436
 
439
 
437
 
440
 
438
      return
441
      return
439
      
442
      
440
      end
443
      end
441
 
444
 
442
c     ------------------------------------------------------------
445
c     ------------------------------------------------------------
443
c     Read wind information
446
c     Read wind information
444
c     ------------------------------------------------------------
447
c     ------------------------------------------------------------
445
 
448
 
446
      subroutine input_wind (fid,fieldname,field,time,stagz,mdv,
449
      subroutine input_wind (fid,fieldname,field,time,stagz,mdv,
447
     >                       xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,
450
     >                       xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,
448
     >                       timecheck)
451
     >                       timecheck)
449
 
452
 
450
c     Read the wind component <fieldname> from the file with identifier
453
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 
454
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
455
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
456
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,
457
c     performed to have an agreement with the grid specified by <xmin,xmax,
455
c     ymin,ymax,dx,dy,nx,ny,nz>.
458
c     ymin,ymax,dx,dy,nx,ny,nz>.
456
 
459
 
457
      use netcdf
460
      use netcdf
458
 
461
 
459
      implicit none
462
      implicit none
460
 
463
 
461
c     Declaration of variables and parameters
464
c     Declaration of variables and parameters
462
      integer      fid                 ! File identifier
465
      integer      fid                 ! File identifier
463
      character*80 fieldname           ! Name of the wind field
466
      character*80 fieldname           ! Name of the wind field
464
      integer      nx,ny,nz            ! Dimension of fields
467
      integer      nx,ny,nz            ! Dimension of fields
465
      real         field(nx,ny,nz)     ! 3d wind field
468
      real         field(nx,ny,nz)     ! 3d wind field
466
      real         stagz               ! Staggering in the z direction
469
      real         stagz               ! Staggering in the z direction
467
      real         mdv                 ! Missing data flag
470
      real         mdv                 ! Missing data flag
468
      real         xmin,xmax,ymin,ymax ! Domain size
471
      real         xmin,xmax,ymin,ymax ! Domain size
469
      real         dx,dy               ! Horizontal resolution
472
      real         dx,dy               ! Horizontal resolution
470
      real         time                ! Time
473
      real         time                ! Time
471
      character*80 timecheck           ! Either 'yes' or 'no'
474
      character*80 timecheck           ! Either 'yes' or 'no'
472
 
475
 
473
c     Numerical and physical parameters
476
c     Numerical and physical parameters
474
      real        eps                 ! Numerical epsilon
477
      real        eps                 ! Numerical epsilon
475
      parameter  (eps=0.001)
478
      parameter  (eps=0.001)
476
      real        notimecheck         ! 'Flag' for no time check
479
      real        notimecheck         ! 'Flag' for no time check
477
      parameter  (notimecheck=7.26537)
480
      parameter  (notimecheck=7.26537)
478
 
481
 
479
c     Netcdf variables
482
c     Netcdf variables
480
      integer      ierr
483
      integer      ierr
481
      character*80 varname
484
      character*80 varname
482
      integer      vardim(4)
485
      integer      vardim(4)
483
      real         varmin(4),varmax(4)
486
      real         varmin(4),varmax(4)
484
      real         stag(4)
487
      real         stag(4)
485
      integer      ndim
488
      integer      ndim
486
      real         times(10)
489
      real         times(10)
487
      integer      ntimes
490
      integer      ntimes
488
      character*80 cstfile
491
      character*80 cstfile
489
      integer      cstid
492
      integer      cstid
490
      real         aklay(200),bklay(200),aklev(200),bklev(200)
493
      real         aklay(200),bklay(200),aklev(200),bklev(200)
491
      real         ps(nx,ny)
494
      real         ps(nx,ny)
492
      integer      dimids (nf90_max_var_dims)
495
      integer      dimids (nf90_max_var_dims)
493
      character*80 dimname(nf90_max_var_dims)
496
      character*80 dimname(nf90_max_var_dims)
494
      integer      varid
497
      integer      varid
495
      integer      cdfid
498
      integer      cdfid
496
      real,allocatable, dimension (:)     :: lon,lat,lev
499
      real,allocatable, dimension (:)     :: lon,lat,lev
497
      real,allocatable, dimension (:,:)   :: tmp2
500
      real,allocatable, dimension (:,:)   :: tmp2
498
      real,allocatable, dimension (:,:,:) :: tmp3
501
      real,allocatable, dimension (:,:,:) :: tmp3
499
      real,allocatable, dimension (:)     :: aktmp,bktmp
502
      real,allocatable, dimension (:)     :: aktmp,bktmp
500
      character*80  leveltype
503
      character*80  leveltype
501
      integer       vertical_swap
504
      integer       vertical_swap
502
      character*80  units
505
      character*80  units
503
      integer       nakbktmp
506
      integer       nakbktmp
504
      integer       dimid
507
      integer       dimid
505
 
508
 
506
c     Auxiliary variables
509
c     Auxiliary variables
507
      integer      isok
510
      integer      isok
508
      integer      i,j,k
511
      integer      i,j,k
509
      integer      nz1
512
      integer      nz1
510
      real         rtime
513
      real         rtime
511
      integer      closear
514
      integer      closear
512
      integer      stat
515
      integer      stat
513
      real         delta
516
      real         delta
514
 
517
 
515
c     Init mdv
518
c     Init mdv
516
      mdv = -999.
519
      mdv = -999.
517
 
520
 
518
c     Get the number of dimensions -> ndim
521
c     Get the number of dimensions -> ndim
519
      ierr = NF90_INQ_VARID(fid,fieldname,varid)
522
      ierr = NF90_INQ_VARID(fid,fieldname,varid)
520
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
523
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
521
      ierr = nf90_inquire_variable(fid, varid, ndims  = ndim)
524
      ierr = nf90_inquire_variable(fid, varid, ndims  = ndim)
522
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
525
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
523
 
526
 
524
c     Get the dimensions of the arrays -> varid(1:ndim)
527
c     Get the dimensions of the arrays -> varid(1:ndim)
525
      ierr = NF90_INQ_VARID(fid,fieldname,varid)
528
      ierr = NF90_INQ_VARID(fid,fieldname,varid)
526
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
529
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
527
      ierr = nf90_inquire_variable(fid, varid, 
530
      ierr = nf90_inquire_variable(fid, varid, 
528
     >                                   dimids = dimids(1:ndim))
531
     >                                   dimids = dimids(1:ndim))
529
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
532
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
530
      do i=1,ndim
533
      do i=1,ndim
531
           ierr = nf90_inquire_dimension(fid, dimids(i), 
534
           ierr = nf90_inquire_dimension(fid, dimids(i), 
532
     >                               name = dimname(i) )
535
     >                               name = dimname(i) )
533
           IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
536
           IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
534
           ierr = nf90_inquire_dimension(fid, dimids(i),len=vardim(i))
537
           ierr = nf90_inquire_dimension(fid, dimids(i),len=vardim(i))
535
           IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
538
           IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
536
      enddo
539
      enddo
537
 
540
 
538
c     Check whether the list of dimensions is OK
541
c     Check whether the list of dimensions is OK
539
      if ( ( dimname(1).ne.'lon'  ).or.
542
      if ( ( dimname(1).ne.'lon'  ).or.
540
     >     ( dimname(2).ne.'lat'  ).or.
543
     >     ( dimname(2).ne.'lat'  ).or.
541
     >     ( dimname(3).ne.'lev'  ).and.( dimname(3).ne.'lev_2'  ).or.
544
     >     ( dimname(3).ne.'lev'  ).and.( dimname(3).ne.'lev_2'  ).or.
542
     >     ( dimname(4).ne.'time' ) )
545
     >     ( dimname(4).ne.'time' ) )
543
     >then
546
     >then
544
        print*,' ERROR: the dimensions of the variable are not correct'
547
        print*,' ERROR: the dimensions of the variable are not correct'
545
        print*,'        expected -> lon / lat / lev / time'
548
        print*,'        expected -> lon / lat / lev / time'
546
        print*, ( trim(dimname(i))//' / ',i=1,ndim )
549
        print*, ( trim(dimname(i))//' / ',i=1,ndim )
547
        stop
550
        stop
548
      endif
551
      endif
549
 
552
 
550
c     Get dimension of AK,BK
553
c     Get dimension of AK,BK
551
      varname = 'nhym'
554
      varname = 'nhym'
552
      ierr = NF90_INQ_DIMID(fid,varname,dimid)
555
      ierr = NF90_INQ_DIMID(fid,varname,dimid)
553
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
556
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
554
      ierr = nf90_inquire_dimension(fid, dimid,len=nakbktmp)
557
      ierr = nf90_inquire_dimension(fid, dimid,len=nakbktmp)
555
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
558
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
556
 
559
 
557
c     Check about the type of vertical levels
560
c     Check about the type of vertical levels
558
      varname=dimname(3)
561
      varname=dimname(3)
559
      ierr = NF90_INQ_VARID(fid,varname,varid)
562
      ierr = NF90_INQ_VARID(fid,varname,varid)
560
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
563
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
561
      ierr = nf90_get_att(fid, varid, "standard_name", leveltype)
564
      ierr = nf90_get_att(fid, varid, "standard_name", leveltype)
562
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
565
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
563
      if ( (leveltype.ne.'hybrid_sigma_pressure').and.
566
      if ( (leveltype.ne.'hybrid_sigma_pressure').and.
564
     >     (leveltype.ne.'air_pressure'         ) )
567
     >     (leveltype.ne.'air_pressure'         ) )
565
     >then
568
     >then
566
         print*,' ERROR: input netCDF data must be on hybrid-sigma'
569
         print*,' ERROR: input netCDF data must be on hybrid-sigma'
567
         print*,'        or air pressure levels!',trim(leveltype)
570
         print*,'        or air pressure levels!',trim(leveltype)
568
         stop
571
         stop
569
      endif
572
      endif
570
 
573
 
571
c     Allocate memory for reading arrays - depending on <closear>
574
c     Allocate memory for reading arrays - depending on <closear>
572
      allocate(tmp2(vardim(1),vardim(2)),stat=stat)
575
      allocate(tmp2(vardim(1),vardim(2)),stat=stat)
573
      if (stat.ne.0) print*,'*** error allocating array tmp2     ***'
576
      if (stat.ne.0) print*,'*** error allocating array tmp2     ***'
574
      allocate(tmp3(vardim(1),vardim(2),vardim(3)),stat=stat)
577
      allocate(tmp3(vardim(1),vardim(2),vardim(3)),stat=stat)
575
      if (stat.ne.0) print*,'*** error allocating array tmp3     ***'
578
      if (stat.ne.0) print*,'*** error allocating array tmp3     ***'
576
      allocate(lon(vardim(1)),stat=stat)
579
      allocate(lon(vardim(1)),stat=stat)
577
      if (stat.ne.0) print*,'*** error allocating array lon     ***'
580
      if (stat.ne.0) print*,'*** error allocating array lon     ***'
578
      allocate(lat(vardim(2)),stat=stat)
581
      allocate(lat(vardim(2)),stat=stat)
579
      if (stat.ne.0) print*,'*** error allocating array lat     ***'
582
      if (stat.ne.0) print*,'*** error allocating array lat     ***'
580
      allocate(lev(vardim(3)),stat=stat)
583
      allocate(lev(vardim(3)),stat=stat)
581
      if (stat.ne.0) print*,'*** error allocating array lev     ***'
584
      if (stat.ne.0) print*,'*** error allocating array lev     ***'
582
      allocate(aktmp(nakbktmp),stat=stat)
585
      allocate(aktmp(nakbktmp),stat=stat)
583
      if (stat.ne.0) print*,'*** error allocating array aktmp   ***'
586
      if (stat.ne.0) print*,'*** error allocating array aktmp   ***'
584
      allocate(bktmp(nakbktmp),stat=stat)
587
      allocate(bktmp(nakbktmp),stat=stat)
585
      if (stat.ne.0) print*,'*** error allocating array bktmp   ***'
588
      if (stat.ne.0) print*,'*** error allocating array bktmp   ***'
586
 
589
 
587
c     Get domain boundaries - longitude, latitude, levels
590
c     Get domain boundaries - longitude, latitude, levels
588
      varname = dimname(1)
591
      varname = dimname(1)
589
      ierr = NF90_INQ_VARID(fid,varname,varid)
592
      ierr = NF90_INQ_VARID(fid,varname,varid)
590
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
593
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
591
      ierr = nf90_get_var(fid,varid,lon)
594
      ierr = nf90_get_var(fid,varid,lon)
592
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
595
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
593
      varname = dimname(2)
596
      varname = dimname(2)
594
      ierr = NF90_INQ_VARID(fid,varname,varid)
597
      ierr = NF90_INQ_VARID(fid,varname,varid)
595
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
598
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
596
      ierr = nf90_get_var(fid,varid,lat)
599
      ierr = nf90_get_var(fid,varid,lat)
597
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
600
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
598
      varname = dimname(3)
601
      varname = dimname(3)
599
      ierr = NF90_INQ_VARID(fid,varname,varid)
602
      ierr = NF90_INQ_VARID(fid,varname,varid)
600
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
603
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
601
      ierr = nf90_get_var(fid,varid,lev)
604
      ierr = nf90_get_var(fid,varid,lev)
602
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
605
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
-
 
606
      varmin(1) = lon(1)
-
 
607
      varmax(1) = lon( vardim(1) )
-
 
608
      varmin(2) = lat(1)
-
 
609
      varmax(2) = lat( vardim(2) )
603
 
610
 
604
c     Get ak and bk
611
c     Get ak and bk
605
      varname='hyam'
612
      varname='hyam'
606
      ierr = NF90_INQ_VARID(fid,varname,varid)
613
      ierr = NF90_INQ_VARID(fid,varname,varid)
607
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
614
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
608
      ierr = nf90_get_var(fid,varid,aktmp)
615
      ierr = nf90_get_var(fid,varid,aktmp)
609
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
616
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
610
      varname='hybm'
617
      varname='hybm'
611
      ierr = NF90_INQ_VARID(fid,varname,varid)
618
      ierr = NF90_INQ_VARID(fid,varname,varid)
612
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
619
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
613
      ierr = nf90_get_var(fid,varid,bktmp)
620
      ierr = nf90_get_var(fid,varid,bktmp)
614
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
621
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
615
 
622
 
616
c     Check that unit of ak is in hPa - if necessary correct it
623
c     Check that unit of ak is in hPa - if necessary correct it
617
      varname='hyam'
624
      varname='hyam'
618
      ierr = NF90_INQ_VARID(fid,varname,varid)
625
      ierr = NF90_INQ_VARID(fid,varname,varid)
619
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
626
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
620
      ierr = nf90_get_att(fid, varid, "units", units)
627
      ierr = nf90_get_att(fid, varid, "units", units)
621
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
628
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
622
      if ( units.eq.'Pa' ) then
629
      if ( units.eq.'Pa' ) then
623
         do k=1,nakbktmp
630
         do k=1,nakbktmp
624
            aktmp(k) = 0.01 * aktmp(k)
631
            aktmp(k) = 0.01 * aktmp(k)
625
         enddo
632
         enddo
626
      endif
633
      endif
627
 
634
 
628
c     Check that unit of lev is in hPa - if necessary correct it
635
c     Check that unit of lev is in hPa - if necessary correct it
629
      if ( leveltype.eq.'air_pressure' ) then
636
      if ( leveltype.eq.'air_pressure' ) then
630
         varname='lev'
637
         varname='lev'
631
         ierr = NF90_INQ_VARID(fid,varname,varid)
638
         ierr = NF90_INQ_VARID(fid,varname,varid)
632
         IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
639
         IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
633
         ierr = nf90_get_att(fid, varid, "units", units)
640
         ierr = nf90_get_att(fid, varid, "units", units)
634
         IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
641
         IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
635
         if ( units.eq.'Pa' ) then
642
         if ( units.eq.'Pa' ) then
636
            do k=1,vardim(3)
643
            do k=1,vardim(3)
637
               lev(k) = 0.01 * lev(k)
644
               lev(k) = 0.01 * lev(k)
638
            enddo
645
            enddo
639
         endif
646
         endif
640
      endif
647
      endif
641
 
648
 
642
c     Decide whether to swap vertical levels
649
c     Decide whether to swap vertical levels
643
      vertical_swap = 1
650
      vertical_swap = 1
644
      if ( leveltype.eq.'hybrid_sigma_pressure') then
651
      if ( leveltype.eq.'hybrid_sigma_pressure') then
645
        if ( (aktmp(1) + bktmp(1) * 1000.).gt.
652
        if ( (aktmp(1) + bktmp(1) * 1000.).gt.
646
     >       (aktmp(2) + bktmp(2) * 1000.) )
653
     >       (aktmp(2) + bktmp(2) * 1000.) )
647
     >  then
654
     >  then
648
          vertical_swap = 0
655
          vertical_swap = 0
649
        endif
656
        endif
650
      elseif ( leveltype.eq.'air_pressure') then
657
      elseif ( leveltype.eq.'air_pressure') then
651
        if ( lev(1).gt.lev(2) ) then
658
        if ( lev(1).gt.lev(2) ) then
652
          vertical_swap = 0
659
          vertical_swap = 0
653
        endif
660
        endif
654
      endif
661
      endif
655
 
662
 
656
c     Read data 
663
c     Read data 
657
      ierr = NF90_INQ_VARID(fid,fieldname,varid)
664
      ierr = NF90_INQ_VARID(fid,fieldname,varid)
658
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
665
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
659
      ierr = nf90_get_var(fid,varid,tmp3)
666
      ierr = nf90_get_var(fid,varid,tmp3)
660
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
667
      IF(ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
661
  
668
  
662
c     If the field is 2D, expand it to 3D - simple handling of 2D tracing
669
c     If the field is 2D, expand it to 3D - simple handling of 2D tracing
663
      if ( vardim(3).eq.1 ) then
670
      if ( vardim(3).eq.1 ) then
664
         do i=1,vardim(1)
671
         do i=1,vardim(1)
665
            do j=1,vardim(2)
672
            do j=1,vardim(2)
666
               do k=1,vardim(3)
673
               do k=1,vardim(3)
667
                  tmp3(i,j,k) = tmp3(i,j,1)
674
                  tmp3(i,j,k) = tmp3(i,j,1)
668
               enddo
675
               enddo
669
            enddo
676
            enddo
670
         enddo
677
         enddo
671
      endif
678
      endif
672
 
679
 
673
c     Decide whether to close arrays
680
c     Decide whether to close arrays
674
      delta = varmax(1)-varmin(1)-360.
681
      delta = varmax(1)-varmin(1)-360.
675
      if (abs(delta+dx).lt.eps) then
682
      if (abs(delta+dx).lt.eps) then
676
          closear = 1
683
          closear = 1
677
      else
684
      else
678
          closear = 0
685
          closear = 0
679
      endif
686
      endif
680
 
687
 
681
c     Save output array - close array and swap on demand
688
c     Save output array - close array and swap on demand
682
      do j=1,vardim(2)
689
      do j=1,vardim(2)
683
        do k=1,vardim(3)
690
        do k=1,vardim(3)
684
          do i=1,vardim(1)
691
          do i=1,vardim(1)
685
             if ( vertical_swap.eq.1 ) then
692
             if ( vertical_swap.eq.1 ) then
686
                 field(i,j,k) = tmp3(i,j,vardim(3)-k+1)
693
                 field(i,j,k) = tmp3(i,j,vardim(3)-k+1)
687
             else
694
             else
688
                 field(i,j,k) = tmp3(i,j,k)
695
                 field(i,j,k) = tmp3(i,j,k)
689
             endif
696
             endif
690
          enddo
697
          enddo
691
          if (closear.eq.1) field(vardim(1)+1,j,k) = field(1,j,k)
698
          if (closear.eq.1) field(vardim(1)+1,j,k) = field(1,j,k)
692
        enddo
699
        enddo
693
      enddo
700
      enddo
694
         
701
         
695
c     Exit point
702
c     Exit point
696
      return
703
      return
697
 
704
 
698
      end
705
      end
699
 
706
 
700
c     ------------------------------------------------------------
707
c     ------------------------------------------------------------
701
c     Close input file
708
c     Close input file
702
c     ------------------------------------------------------------
709
c     ------------------------------------------------------------
703
 
710
 
704
      subroutine input_close(fid)
711
      subroutine input_close(fid)
705
 
712
 
706
c     Close the input file with file identifier <fid>.
713
c     Close the input file with file identifier <fid>.
707
 
714
 
708
      use netcdf
715
      use netcdf
709
 
716
 
710
      implicit none
717
      implicit none
711
 
718
 
712
c     Declaration of subroutine parameters
719
c     Declaration of subroutine parameters
713
      integer fid
720
      integer fid
714
 
721
 
715
c     Auxiliary variables
722
c     Auxiliary variables
716
      integer ierr
723
      integer ierr
717
 
724
 
718
c     Close file
725
c     Close file
719
      ierr = NF90_CLOSE(fid)
726
      ierr = NF90_CLOSE(fid)
720
      IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
727
      IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
721
      
728
      
722
      end
729
      end
723
      
730
      
724
c     ------------------------------------------------------------
731
c     ------------------------------------------------------------
725
c     Get a list of variables on netCDF file
732
c     Get a list of variables on netCDF file
726
c     ------------------------------------------------------------
733
c     ------------------------------------------------------------
727
 
734
 
728
      subroutine input_getvars(fid,vnam,nvars)
735
      subroutine input_getvars(fid,vnam,nvars)
729
 
736
 
730
c     List of variables on netCDF file
737
c     List of variables on netCDF file
731
 
738
 
732
      use netcdf
739
      use netcdf
733
 
740
 
734
      implicit none
741
      implicit none
735
 
742
 
736
c     Declaration of subroutine parameters
743
c     Declaration of subroutine parameters
737
      integer      fid
744
      integer      fid
738
      integer      nvars
745
      integer      nvars
739
      character*80 vnam(200)
746
      character*80 vnam(200)
740
 
747
 
741
c     Auxiliary variables
748
c     Auxiliary variables
742
      integer ierr
749
      integer ierr
743
      integer i
750
      integer i
744
      integer nDims,nGlobalAtts,unlimdimid
751
      integer nDims,nGlobalAtts,unlimdimid
745
 
752
 
746
      ierr = nf90_inquire(fid, nDims, nVars, nGlobalAtts, unlimdimid)
753
      ierr = nf90_inquire(fid, nDims, nVars, nGlobalAtts, unlimdimid)
747
      IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
754
      IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr)
748
      
755
      
749
      do i=1,nVars
756
      do i=1,nVars
750
         ierr = nf90_inquire_variable(fid, i, name = vnam(i))
757
         ierr = nf90_inquire_variable(fid, i, name = vnam(i))
751
      enddo
758
      enddo
752
 
759
 
753
      end
760
      end