Subversion Repositories lagranto.ecmwf

Rev

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

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