Subversion Repositories lagranto.ecmwf

Rev

Rev 9 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3 michaesp 1
c     ************************************************************
2
c     * This package provides input routines to read the wind    *
3
c     * and other fields from IVE necdf files. The routines are  *
4
c     *                                                          *
5
c     * 1) input_open  : to open a data file                     *
6
c     * 2) input_grid  : to read the grid information, including *
7
c     *                  the vertical levels                     *
8
c     * 3) input_wind  : to read the wind components             *
9
c     * 4) input_close : to close an input file                  *
10
c     *                                                          *
11
c     * The file is characterised by an filename <filename> and  *
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  *
14
c     * rotated grid is given by <pollon,pollat>. The vertical   *
15
c     * grid is characterised by the surface pressure <ps> and   *
16
c     * the pressure at staggered <slev> and unstaggered <ulev>  *
17
c     * levels. The number of levels is given by <nz>. Finally,  *
18
c     * the retrieval of the wind <field> with name <fieldname>  *
19
c     * is characterised by a <time> and a missing data value    *
20
c     * <mdv>.                                                   *
21
c     *                                                          *
22
c     * Author: Michael Sprenger, Autumn 2008                    *
23
c     ************************************************************
24
 
25
c     ------------------------------------------------------------
26
c     Open input file
27
c     ------------------------------------------------------------
28
 
29
      subroutine input_open (fid,filename)
30
 
31
c     Open the input file with filename <filename> and return the
32
c     file identifier <fid> for further reference. 
33
 
34
      implicit none
35
 
36
c     Declaration of subroutine parameters
37
      integer      fid              ! File identifier
38
      character*80 filename         ! Filename
39
 
40
c     Declaration of auxiliary variables
41
      integer      ierr
42
 
43
c     Open IVE netcdf file
44
      call cdfopn(filename,fid,ierr)
45
      if (ierr.ne.0) goto 900
46
 
47
c     Exception handling
48
      return
49
 
50
 900  print*,'Cannot open input file ',trim(filename)
51
      stop
52
 
53
      end
54
 
55
 
56
c     ------------------------------------------------------------
57
c     Read information about the grid
58
c     ------------------------------------------------------------
59
 
60
      subroutine input_grid 
61
     >                   (fid,fieldname,xmin,xmax,ymin,ymax,dx,dy,nx,ny,
62
     >                    time,pollon,pollat,p3,ps,nz,ak,bk,stagz,
63
     >                    timecheck)
64
 
65
c     Read grid information at <time> from file with identifier <fid>. 
66
c     The horizontal grid is characterized by <xmin,xmax,ymin,ymax,dx,dy>
67
c     with pole position at <pollon,pollat> and grid dimension <nx,ny>.
68
c     The 3d arrays <p3(nx,ny,nz)> gives the vertical coordinates, either
69
c     on the staggered or unstaggered grid (with <stagz> as the flag).
70
c     The surface pressure is given in <ps(nx,ny)>. If <fid> is negative, 
71
c     only the grid dimensions and grid parameters (xmin...pollat,nz) are 
72
c     determined and returned (this is needed for dynamical allocation of 
73
c     memory).
74
 
75
      implicit none
76
 
77
c     Declaration of subroutine parameters 
78
      integer      fid                 ! File identifier
79
      real         xmin,xmax,ymin,ymax ! Domain size
80
      real         dx,dy               ! Horizontal resolution
81
      integer      nx,ny,nz            ! Grid dimensions
82
      real         pollon,pollat       ! Longitude and latitude of pole
83
      real         p3(nx,ny,nz)        ! Staggered levels
84
      real         ps(nx,ny)           ! Surface pressure
85
      real         time                ! Time of the grid information
86
      real         ak(nz),bk(nz)       ! Ak and Bk for layers or levels
87
      real         stagz               ! Vertical staggering (0 or -0.5)
88
      character*80 fieldname           ! Variable from which to take grid info
89
      character*80 timecheck           ! Either 'yes' or 'no'
90
 
91
c     Numerical and physical parameters
92
      real          eps                 ! Numerical epsilon
93
      parameter    (eps=0.001)
94
 
95
c     Netcdf variables
96
      integer      vardim(4)
97
      real         varmin(4),varmax(4)
98
      real         mdv
99
      real         stag(4)
100
      integer      ndim
101
      character*80 cstfile
102
      integer      cstid
103
      real         times(10)
104
      integer      ntimes
105
      real         aklay(nz),bklay(nz),aklev(nz),bklev(nz)
106
      integer      nvars
107
      character*80 vars(100)
108
 
109
c     Auxiliary varaibles
110
      integer      ierr       
111
      integer      i,j,k
112
      integer      isok
113
      real         tmp(200)
114
      character*80 varname
115
      real         rtime
116
      integer      is2d
117
 
118
c     Init the flag for 2D variables - assume a 3D field
119
      is2d = 0
120
 
121
c     Inquire dimensions and grid constants if <fid> is negative
122
      if (fid.lt.0) then
123
 
124
c        Get grid info for the selected variable
125
         if ( fieldname.eq.'PLEV' ) then
126
            varname = 'PS'
127
            stagz   = 0.
128
            call getdef(-fid,varname,ndim,mdv,vardim,
129
     >                  varmin,varmax,stag,ierr)
130
            if (ierr.ne.0) goto 900
131
            call getcfn(-fid,cstfile,ierr)
132
            if (ierr.ne.0) goto 903
133
            call cdfopn(cstfile,cstid,ierr)
134
            if (ierr.ne.0) goto 903
135
            call getlevs(cstid,vardim(3),tmp,tmp,tmp,tmp,ierr)
136
            if (ierr.ne.0) goto 903
137
            call clscdf(cstid,ierr)
138
            if (ierr.ne.0) goto 903
139
 
140
         elseif ( ( fieldname.eq.'PLAY' ).or.( fieldname.eq.'P' ) ) then       
141
            varname = 'PS'
142
            stagz   = -0.5
143
            call getdef(-fid,varname,ndim,mdv,vardim,
144
     >                  varmin,varmax,stag,ierr)
145
            if (ierr.ne.0) goto 900
146
            call getcfn(-fid,cstfile,ierr)
147
            if (ierr.ne.0) goto 903
148
            call cdfopn(cstfile,cstid,ierr)
149
            if (ierr.ne.0) goto 903
150
            call getlevs(cstid,vardim(3),tmp,tmp,tmp,tmp,ierr)
151
            if (ierr.ne.0) goto 903
152
            call clscdf(cstid,ierr)
153
            if (ierr.ne.0) goto 903
154
 
155
         else
156
            varname = fieldname
157
            call getdef(-fid,varname,ndim,mdv,vardim,
158
     >                  varmin,varmax,stag,ierr)
159
            if (ierr.ne.0) goto 900
160
 
161
         endif
162
 
163
c        Set the grid dimensions and constants - vardim(3) is taken from constants file
164
         nx   = vardim(1)
165
         ny   = vardim(2)
166
         nz   = vardim(3)
167
         xmin = varmin(1)
168
         ymin = varmin(2)
169
         xmax = varmax(1)
170
         ymax = varmax(2)
171
         dx   = (xmax-xmin)/real(nx-1)
172
         dy   = (ymax-ymin)/real(ny-1)
173
 
174
c        Get pole position - if no constants file available, set default pole
175
         call getcfn(-fid,cstfile,ierr)
176
         if (ierr.eq.0) then  
177
            call cdfopn(cstfile,cstid,ierr)
178
            if (ierr.ne.0) goto 903
179
            call getpole(cstid,pollon,pollat,ierr)
180
            if (ierr.ne.0) goto 903
181
            call clscdf(cstid,ierr)
182
            if (ierr.ne.0) goto 903
183
         else
184
            pollon = 0.
185
            pollat = 90.
186
         endif
187
 
188
c     Get non-constant grid parameters (surface pressure and vertical grid)
189
      else
190
 
191
c        Get full grid info - in particular staggering flag; set flag for 2D tracing
192
         if ( fieldname.eq.'PLEV' ) then
193
            varname = 'PS'
194
            stagz   = 0.
195
            call getdef(fid,varname,ndim,mdv,vardim,
196
     >                  varmin,varmax,stag,ierr)
197
            if (ierr.ne.0) goto 900
198
            call getcfn(fid,cstfile,ierr)
199
            if (ierr.ne.0) goto 903
200
            call cdfopn(cstfile,cstid,ierr)
201
            if (ierr.ne.0) goto 903
202
            call getlevs(cstid,vardim(3),tmp,tmp,tmp,tmp,ierr)
203
            if (ierr.ne.0) goto 903
204
            call clscdf(cstid,ierr)
205
            if (ierr.ne.0) goto 903
206
 
207
         elseif ( ( fieldname.eq.'PLAY' ).or.( fieldname.eq.'P' ) ) then       
208
            varname = 'PS'
209
            stagz   = -0.5
210
            call getdef(fid,varname,ndim,mdv,vardim,
211
     >                  varmin,varmax,stag,ierr)
212
            if (ierr.ne.0) goto 900
213
            call getcfn(fid,cstfile,ierr)
214
            if (ierr.ne.0) goto 903
215
            call cdfopn(cstfile,cstid,ierr)
216
            if (ierr.ne.0) goto 903
217
            call getlevs(cstid,vardim(3),tmp,tmp,tmp,tmp,ierr)
218
            if (ierr.ne.0) goto 903
219
            call clscdf(cstid,ierr)
220
            if (ierr.ne.0) goto 903
221
 
222
         else
223
            varname=fieldname
224
            call getdef(fid,varname,ndim,mdv,vardim,
225
     >                  varmin,varmax,stag,ierr)
226
            if (ierr.ne.0) goto 900
227
            if (vardim(3).eq.1) is2d = 1
228
         endif
229
 
230
c        Get time information (check if time is correct)
231
         call gettimes(fid,times,ntimes,ierr)
232
         if (ierr.ne.0) goto 901
233
         isok=0
234
         do i=1,ntimes
235
            if (abs(time-times(i)).lt.eps) then
236
               isok = 1
237
               rtime = times(i)
238
            elseif (timecheck.eq.'no') then
239
               isok = 1
240
               rtime = times(1)
241
            endif
242
         enddo
243
         if ( isok.eq.0) goto 905
244
 
245
c        If 2D tracing requested: take dummay values for PS, AKLEV,BKLEV,AKLAY,BKLAY
246
         if ( is2d.eq.1 ) then
247
 
248
            do i=1,nx
249
               do j=1,ny
250
                  ps(i,j) = 1050.
251
               enddo
252
            enddo
253
 
254
            do k=1,nz
255
               aklev(k) = 0.
256
               bklev(k) = real(nz-k)/real(nz-1) 
257
               aklay(k) = 0.
258
               bklay(k) = real(nz-k)/real(nz-1) 
259
            enddo
260
 
261
c        3D tracing - read PS, AKLEV,BKLEV,AKLAY;BKLAY
262
         else
263
 
264
c           Read the level coefficients from the constants file
265
            call getcfn(fid,cstfile,ierr)
266
            if (ierr.ne.0) goto 903
267
            call cdfopn(cstfile,cstid,ierr)
268
            if (ierr.ne.0) goto 903
269
            call getlevs(cstid,vardim(3),aklev,bklev,aklay,bklay,ierr)
270
            if (ierr.ne.0) goto 903
271
            call clscdf(cstid,ierr)
272
            if (ierr.ne.0) goto 903
273
 
274
c           Read surface pressure
275
            varname='PS'
276
            call getdat(fid,varname,rtime,0,ps,ierr)
277
            if (ierr.ne.0) goto 904
278
 
279
         endif
280
 
281
c        Calculate layer and level pressures
282
         do i=1,nx
283
            do j=1,ny
284
               do k=1,nz
285
                  if ( abs(stagz).lt.eps ) then
286
                     p3(i,j,k)=aklev(k)+bklev(k)*ps(i,j)
287
                  else
288
                     p3(i,j,k)=aklay(k)+bklay(k)*ps(i,j)
289
                  endif
290
               enddo
291
            enddo
292
         enddo
293
 
294
c        Set the ak and bk for the vertical grid
295
         do k=1,nz
296
            if ( abs(stagz).lt.eps ) then
297
               ak(k)=aklev(k)
298
               bk(k)=bklev(k)
299
            else
300
               ak(k)=aklay(k)
301
               bk(k)=bklay(k)
302
            endif
303
         enddo
304
 
305
      endif
306
 
307
c     Exit point for subroutine
308
 800  continue
309
      return
310
 
311
c     Exception handling
312
 900  print*,'Cannot retrieve grid dimension from ',fid
313
      stop
314
 901  print*,'Cannot retrieve grid parameters from ',fid
315
      stop
316
 902  print*,'Grid inconsistency detected for ',fid
317
      stop
318
 903  print*,'Problem with level coefficients from ',trim(cstfile)
319
      stop
320
 904  print*,'Cannot read surface pressure from ',trim(cstfile)
321
      stop
322
 905  print*,'Cannot find time ',time,' on ',fid
323
      stop
324
 906  print*,'Unable to get grid info ',fid
325
      stop
326
 
327
      end
328
 
329
c     ------------------------------------------------------------
330
c     Read wind information
331
c     ------------------------------------------------------------
332
 
333
      subroutine input_wind (fid,fieldname,field,time,stagz,mdv,
334
     >                       xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,
335
     >                       timecheck)
336
 
337
c     Read the wind component <fieldname> from the file with identifier
338
c     <fid> and save it in the 3d array <field>. The vertical staggering 
339
c     information is provided in <stagz> and gives the reference to either
340
c     the layer or level field from <input_grid>. A consistency check is
341
c     performed to have an agreement with the grid specified by <xmin,xmax,
342
c     ymin,ymax,dx,dy,nx,ny,nz>.
343
 
344
      implicit none
345
 
346
c     Declaration of variables and parameters
347
      integer      fid                 ! File identifier
348
      character*80 fieldname           ! Name of the wind field
349
      integer      nx,ny,nz            ! Dimension of fields
350
      real         field(nx,ny,nz)     ! 3d wind field
351
      real         stagz               ! Staggering in the z direction
352
      real         mdv                 ! Missing data flag
353
      real         xmin,xmax,ymin,ymax ! Domain size
354
      real         dx,dy               ! Horizontal resolution
355
      real         time                ! Time
356
      character*80 timecheck           ! Either 'yes' or 'no'
357
 
358
c     Numerical and physical parameters
359
      real        eps                 ! Numerical epsilon
360
      parameter  (eps=0.001)
361
      real        notimecheck         ! 'Flag' for no time check
362
      parameter  (notimecheck=7.26537)
363
 
364
c     Netcdf variables
365
      integer      ierr
366
      character*80 varname
367
      integer      vardim(4)
368
      real         varmin(4),varmax(4)
369
      real         stag(4)
370
      integer      ndim
371
      real         times(10)
372
      integer      ntimes
373
      character*80 cstfile
374
      integer      cstid
375
      real         aklay(200),bklay(200),aklev(200),bklev(200)
376
      real         ps(nx,ny)
377
 
378
c     Auxiliary variables
379
      integer      isok
380
      integer      i,j,k
381
      integer      nz1
382
      real         rtime
383
 
384
c     Read variable definition - for P, PLEV and PLAY: load also ak,bk
385
      if ( ( fieldname.eq.'PLEV' ).or.
386
     >     ( fieldname.eq.'PLAY' ).or.
387
     >     ( fieldname.eq.'P'    ) )
388
     >then
389
         call getcfn(fid,cstfile,ierr)
390
         if (ierr.ne.0) goto 905
391
         call cdfopn(cstfile,cstid,ierr)
392
         if (ierr.ne.0) goto 905
393
         call getlevs(cstid,nz1,aklev,bklev,aklay,bklay,ierr)
394
         if (ierr.ne.0) goto 905
395
         call clscdf(cstid,ierr)
396
         if (ierr.ne.0) goto 905
397
         varname = 'PS'
398
         call getdef(fid,varname,ndim,mdv,vardim,
399
     >               varmin,varmax,stag,ierr)
400
         vardim(3) = nz1
401
         if (ierr.ne.0) goto 900
402
      else
403
         varname = fieldname
404
         call getdef(fid,varname,ndim,mdv,vardim,
405
     >               varmin,varmax,stag,ierr)
406
         if (ierr.ne.0) goto 900
407
         stagz=stag(3)
408
      endif
409
 
410
c     Get time information (set time to first one in the file)
411
      call gettimes(fid,times,ntimes,ierr)
412
      if (ierr.ne.0) goto 902
413
      isok=0
414
      do i=1,ntimes
415
         if (abs(time-times(i)).lt.eps) then
416
            isok = 1
417
            rtime = times(i)
418
         elseif (timecheck.eq.'no') then
419
            isok = 1
420
            rtime = times(1)
421
         endif
422
      enddo
423
      if ( isok.eq.0 ) goto 904
424
 
425
c     Read  field
426
      if ( ( fieldname.eq.'P' ).or.(fieldname.eq.'PLAY') )  then       ! P, PLAY
427
         stagz   = -0.5
428
         varname = 'PS'
429
         call getdat(fid,varname,rtime,0,ps,ierr)
430
         if (ierr.ne.0) goto 903
431
         do i=1,nx
432
            do j=1,ny
433
               do k=1,nz
434
                  field(i,j,k)=aklay(k)+bklay(k)*ps(i,j)
435
               enddo
436
            enddo
437
         enddo
438
 
439
      elseif ( fieldname.eq.'PLEV' )  then                             ! PLEV
440
         stagz   = 0.
441
         varname = 'PS'
442
         call getdat(fid,varname,rtime,0,ps,ierr)
443
         if (ierr.ne.0) goto 903
444
         do i=1,nx
445
            do j=1,ny
446
               do k=1,nz
447
                  field(i,j,k)=aklev(k)+bklev(k)*ps(i,j)
448
               enddo
449
            enddo
450
         enddo
451
 
452
      else                                                             ! Other fields
453
         varname=fieldname
454
         call getdat(fid,varname,rtime,0,field,ierr)
455
         if (ierr.ne.0) goto 903
456
 
457
      endif
458
 
459
c     If the field is 2D, expand it to 3D - simple handling of 2D tracing
460
      if ( vardim(3).eq.1 ) then
461
         do i=1,nx
462
            do j=1,ny
463
               do k=1,nz
464
                  field(i,j,k) = field(i,j,1)
465
               enddo
466
            enddo
467
         enddo
468
      endif
469
 
470
 
471
 
472
c     Exception handling
473
      return
474
 
475
 900  print*,'Cannot retrieve definition for ',trim(varname),'  ',fid
476
      stop
477
 901  print*,'Grid inconsistency detected for ',trim(varname),'  ',fid
478
      stop
479
 902  print*,'Cannot retrieve time for ',trim(varname),'  ',fid
480
      stop
481
 903  print*,'Cannot load wind component ',trim(varname),'  ',fid
482
      stop
483
 904  print*,'Cannot load time ',time,' for ',trim(varname),'  ',fid
484
      stop
485
 905  print*,'Cannot load time vertical grid AK, BK from file  ',fid
486
      stop
487
 
488
      end
489
 
490
c     ------------------------------------------------------------
491
c     Close input file
492
c     ------------------------------------------------------------
493
 
494
      subroutine input_close(fid)
495
 
496
c     Close the input file with file identifier <fid>.
497
 
498
      implicit none
499
 
500
c     Declaration of subroutine parameters
501
      integer fid
502
 
503
c     Auxiliary variables
504
      integer ierr
505
 
506
c     Close file
507
      call clscdf(fid,ierr)
508
 
509
      end