Subversion Repositories lagranto.ecmwf

Rev

Rev 3 | Rev 19 | Go to most recent revision | Details | Compare with Previous | 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
9 michaesp 117
      integer      plev
3 michaesp 118
 
119
c     Init the flag for 2D variables - assume a 3D field
120
      is2d = 0
121
 
9 michaesp 122
c     Init the flag for pressure levels (PS is not needed)
123
      plev = 0
124
 
3 michaesp 125
c     Inquire dimensions and grid constants if <fid> is negative
126
      if (fid.lt.0) then
127
 
128
c        Get grid info for the selected variable
129
         if ( fieldname.eq.'PLEV' ) then
130
            varname = 'PS'
131
            stagz   = 0.
132
            call getdef(-fid,varname,ndim,mdv,vardim,
133
     >                  varmin,varmax,stag,ierr)
134
            if (ierr.ne.0) goto 900
135
            call getcfn(-fid,cstfile,ierr)
136
            if (ierr.ne.0) goto 903
137
            call cdfopn(cstfile,cstid,ierr)
138
            if (ierr.ne.0) goto 903
139
            call getlevs(cstid,vardim(3),tmp,tmp,tmp,tmp,ierr)
140
            if (ierr.ne.0) goto 903
141
            call clscdf(cstid,ierr)
142
            if (ierr.ne.0) goto 903
143
 
144
         elseif ( ( fieldname.eq.'PLAY' ).or.( fieldname.eq.'P' ) ) then       
145
            varname = 'PS'
146
            stagz   = -0.5
147
            call getdef(-fid,varname,ndim,mdv,vardim,
148
     >                  varmin,varmax,stag,ierr)
149
            if (ierr.ne.0) goto 900
150
            call getcfn(-fid,cstfile,ierr)
151
            if (ierr.ne.0) goto 903
152
            call cdfopn(cstfile,cstid,ierr)
153
            if (ierr.ne.0) goto 903
154
            call getlevs(cstid,vardim(3),tmp,tmp,tmp,tmp,ierr)
155
            if (ierr.ne.0) goto 903
156
            call clscdf(cstid,ierr)
157
            if (ierr.ne.0) goto 903
158
 
159
         else
160
            varname = fieldname
161
            call getdef(-fid,varname,ndim,mdv,vardim,
162
     >                  varmin,varmax,stag,ierr)
163
            if (ierr.ne.0) goto 900
164
 
165
         endif
166
 
167
c        Set the grid dimensions and constants - vardim(3) is taken from constants file
168
         nx   = vardim(1)
169
         ny   = vardim(2)
170
         nz   = vardim(3)
171
         xmin = varmin(1)
172
         ymin = varmin(2)
173
         xmax = varmax(1)
174
         ymax = varmax(2)
175
         dx   = (xmax-xmin)/real(nx-1)
176
         dy   = (ymax-ymin)/real(ny-1)
177
 
178
c        Get pole position - if no constants file available, set default pole
179
         call getcfn(-fid,cstfile,ierr)
180
         if (ierr.eq.0) then  
181
            call cdfopn(cstfile,cstid,ierr)
182
            if (ierr.ne.0) goto 903
183
            call getpole(cstid,pollon,pollat,ierr)
184
            if (ierr.ne.0) goto 903
185
            call clscdf(cstid,ierr)
186
            if (ierr.ne.0) goto 903
187
         else
188
            pollon = 0.
189
            pollat = 90.
190
         endif
191
 
192
c     Get non-constant grid parameters (surface pressure and vertical grid)
193
      else
194
 
195
c        Get full grid info - in particular staggering flag; set flag for 2D tracing
196
         if ( fieldname.eq.'PLEV' ) then
197
            varname = 'PS'
198
            stagz   = 0.
199
            call getdef(fid,varname,ndim,mdv,vardim,
200
     >                  varmin,varmax,stag,ierr)
201
            if (ierr.ne.0) goto 900
202
            call getcfn(fid,cstfile,ierr)
203
            if (ierr.ne.0) goto 903
204
            call cdfopn(cstfile,cstid,ierr)
205
            if (ierr.ne.0) goto 903
206
            call getlevs(cstid,vardim(3),tmp,tmp,tmp,tmp,ierr)
207
            if (ierr.ne.0) goto 903
208
            call clscdf(cstid,ierr)
209
            if (ierr.ne.0) goto 903
210
 
211
         elseif ( ( fieldname.eq.'PLAY' ).or.( fieldname.eq.'P' ) ) then       
212
            varname = 'PS'
213
            stagz   = -0.5
214
            call getdef(fid,varname,ndim,mdv,vardim,
215
     >                  varmin,varmax,stag,ierr)
216
            if (ierr.ne.0) goto 900
217
            call getcfn(fid,cstfile,ierr)
218
            if (ierr.ne.0) goto 903
219
            call cdfopn(cstfile,cstid,ierr)
220
            if (ierr.ne.0) goto 903
221
            call getlevs(cstid,vardim(3),tmp,tmp,tmp,tmp,ierr)
222
            if (ierr.ne.0) goto 903
223
            call clscdf(cstid,ierr)
224
            if (ierr.ne.0) goto 903
225
 
226
         else
227
            varname=fieldname
228
            call getdef(fid,varname,ndim,mdv,vardim,
229
     >                  varmin,varmax,stag,ierr)
230
            if (ierr.ne.0) goto 900
231
            if (vardim(3).eq.1) is2d = 1
232
         endif
233
 
234
c        Get time information (check if time is correct)
235
         call gettimes(fid,times,ntimes,ierr)
236
         if (ierr.ne.0) goto 901
237
         isok=0
238
         do i=1,ntimes
239
            if (abs(time-times(i)).lt.eps) then
240
               isok = 1
241
               rtime = times(i)
242
            elseif (timecheck.eq.'no') then
243
               isok = 1
244
               rtime = times(1)
245
            endif
246
         enddo
247
         if ( isok.eq.0) goto 905
248
 
249
c        If 2D tracing requested: take dummay values for PS, AKLEV,BKLEV,AKLAY,BKLAY
250
         if ( is2d.eq.1 ) then
251
 
252
            do i=1,nx
253
               do j=1,ny
254
                  ps(i,j) = 1050.
255
               enddo
256
            enddo
257
 
258
            do k=1,nz
259
               aklev(k) = 0.
260
               bklev(k) = real(nz-k)/real(nz-1) 
261
               aklay(k) = 0.
262
               bklay(k) = real(nz-k)/real(nz-1) 
263
            enddo
264
 
265
c        3D tracing - read PS, AKLEV,BKLEV,AKLAY;BKLAY
266
         else
267
 
268
c           Read the level coefficients from the constants file
269
            call getcfn(fid,cstfile,ierr)
270
            if (ierr.ne.0) goto 903
271
            call cdfopn(cstfile,cstid,ierr)
272
            if (ierr.ne.0) goto 903
273
            call getlevs(cstid,vardim(3),aklev,bklev,aklay,bklay,ierr)
274
            if (ierr.ne.0) goto 903
275
            call clscdf(cstid,ierr)
276
            if (ierr.ne.0) goto 903
277
 
9 michaesp 278
c           Check whether PS is needed to get the 3d pressure field
279
            plev = 1
280
            do i=1,nz
281
              if ( (abs(stagz).lt.eps).and.(abs(bklev(i)).gt.eps) ) then
282
                plev = 0
283
              endif
284
              if ( (abs(stagz).gt.eps).and.(abs(bklay(i)).gt.eps) ) then
285
                plev = 0
286
              endif
287
            enddo
3 michaesp 288
 
9 michaesp 289
c           Read surface pressure if needed
290
            if ( plev.ne.1 ) then
291
              varname='PS'
292
              call getdat(fid,varname,rtime,0,ps,ierr)
293
              if (ierr.ne.0) goto 904
294
            else
295
              do i=1,nx
296
                do j=1,ny
297
                    ps(i,j) = 1000.
298
                enddo
299
              enddo
300
            endif
301
 
3 michaesp 302
         endif
303
 
304
c        Calculate layer and level pressures
305
         do i=1,nx
306
            do j=1,ny
307
               do k=1,nz
308
                  if ( abs(stagz).lt.eps ) then
309
                     p3(i,j,k)=aklev(k)+bklev(k)*ps(i,j)
310
                  else
311
                     p3(i,j,k)=aklay(k)+bklay(k)*ps(i,j)
312
                  endif
313
               enddo
314
            enddo
315
         enddo
316
 
317
c        Set the ak and bk for the vertical grid
318
         do k=1,nz
319
            if ( abs(stagz).lt.eps ) then
320
               ak(k)=aklev(k)
321
               bk(k)=bklev(k)
322
            else
323
               ak(k)=aklay(k)
324
               bk(k)=bklay(k)
325
            endif
326
         enddo
327
 
328
      endif
329
 
330
c     Exit point for subroutine
331
 800  continue
332
      return
333
 
334
c     Exception handling
335
 900  print*,'Cannot retrieve grid dimension from ',fid
336
      stop
337
 901  print*,'Cannot retrieve grid parameters from ',fid
338
      stop
339
 902  print*,'Grid inconsistency detected for ',fid
340
      stop
341
 903  print*,'Problem with level coefficients from ',trim(cstfile)
342
      stop
343
 904  print*,'Cannot read surface pressure from ',trim(cstfile)
344
      stop
345
 905  print*,'Cannot find time ',time,' on ',fid
346
      stop
347
 906  print*,'Unable to get grid info ',fid
348
      stop
349
 
350
      end
351
 
352
c     ------------------------------------------------------------
353
c     Read wind information
354
c     ------------------------------------------------------------
355
 
356
      subroutine input_wind (fid,fieldname,field,time,stagz,mdv,
357
     >                       xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,
358
     >                       timecheck)
359
 
360
c     Read the wind component <fieldname> from the file with identifier
361
c     <fid> and save it in the 3d array <field>. The vertical staggering 
362
c     information is provided in <stagz> and gives the reference to either
363
c     the layer or level field from <input_grid>. A consistency check is
364
c     performed to have an agreement with the grid specified by <xmin,xmax,
365
c     ymin,ymax,dx,dy,nx,ny,nz>.
366
 
367
      implicit none
368
 
369
c     Declaration of variables and parameters
370
      integer      fid                 ! File identifier
371
      character*80 fieldname           ! Name of the wind field
372
      integer      nx,ny,nz            ! Dimension of fields
373
      real         field(nx,ny,nz)     ! 3d wind field
374
      real         stagz               ! Staggering in the z direction
375
      real         mdv                 ! Missing data flag
376
      real         xmin,xmax,ymin,ymax ! Domain size
377
      real         dx,dy               ! Horizontal resolution
378
      real         time                ! Time
379
      character*80 timecheck           ! Either 'yes' or 'no'
380
 
381
c     Numerical and physical parameters
382
      real        eps                 ! Numerical epsilon
383
      parameter  (eps=0.001)
384
      real        notimecheck         ! 'Flag' for no time check
385
      parameter  (notimecheck=7.26537)
386
 
387
c     Netcdf variables
388
      integer      ierr
389
      character*80 varname
390
      integer      vardim(4)
391
      real         varmin(4),varmax(4)
392
      real         stag(4)
393
      integer      ndim
394
      real         times(10)
395
      integer      ntimes
396
      character*80 cstfile
397
      integer      cstid
398
      real         aklay(200),bklay(200),aklev(200),bklev(200)
399
      real         ps(nx,ny)
400
 
401
c     Auxiliary variables
402
      integer      isok
403
      integer      i,j,k
404
      integer      nz1
405
      real         rtime
406
 
407
c     Read variable definition - for P, PLEV and PLAY: load also ak,bk
408
      if ( ( fieldname.eq.'PLEV' ).or.
409
     >     ( fieldname.eq.'PLAY' ).or.
410
     >     ( fieldname.eq.'P'    ) )
411
     >then
412
         call getcfn(fid,cstfile,ierr)
413
         if (ierr.ne.0) goto 905
414
         call cdfopn(cstfile,cstid,ierr)
415
         if (ierr.ne.0) goto 905
416
         call getlevs(cstid,nz1,aklev,bklev,aklay,bklay,ierr)
417
         if (ierr.ne.0) goto 905
418
         call clscdf(cstid,ierr)
419
         if (ierr.ne.0) goto 905
420
         varname = 'PS'
421
         call getdef(fid,varname,ndim,mdv,vardim,
422
     >               varmin,varmax,stag,ierr)
423
         vardim(3) = nz1
424
         if (ierr.ne.0) goto 900
425
      else
426
         varname = fieldname
427
         call getdef(fid,varname,ndim,mdv,vardim,
428
     >               varmin,varmax,stag,ierr)
429
         if (ierr.ne.0) goto 900
430
         stagz=stag(3)
431
      endif
432
 
433
c     Get time information (set time to first one in the file)
434
      call gettimes(fid,times,ntimes,ierr)
435
      if (ierr.ne.0) goto 902
436
      isok=0
437
      do i=1,ntimes
438
         if (abs(time-times(i)).lt.eps) then
439
            isok = 1
440
            rtime = times(i)
441
         elseif (timecheck.eq.'no') then
442
            isok = 1
443
            rtime = times(1)
444
         endif
445
      enddo
446
      if ( isok.eq.0 ) goto 904
447
 
448
c     Read  field
449
      if ( ( fieldname.eq.'P' ).or.(fieldname.eq.'PLAY') )  then       ! P, PLAY
450
         stagz   = -0.5
451
         varname = 'PS'
452
         call getdat(fid,varname,rtime,0,ps,ierr)
453
         if (ierr.ne.0) goto 903
454
         do i=1,nx
455
            do j=1,ny
456
               do k=1,nz
457
                  field(i,j,k)=aklay(k)+bklay(k)*ps(i,j)
458
               enddo
459
            enddo
460
         enddo
461
 
462
      elseif ( fieldname.eq.'PLEV' )  then                             ! PLEV
463
         stagz   = 0.
464
         varname = 'PS'
465
         call getdat(fid,varname,rtime,0,ps,ierr)
466
         if (ierr.ne.0) goto 903
467
         do i=1,nx
468
            do j=1,ny
469
               do k=1,nz
470
                  field(i,j,k)=aklev(k)+bklev(k)*ps(i,j)
471
               enddo
472
            enddo
473
         enddo
474
 
475
      else                                                             ! Other fields
476
         varname=fieldname
477
         call getdat(fid,varname,rtime,0,field,ierr)
478
         if (ierr.ne.0) goto 903
479
 
480
      endif
481
 
482
c     If the field is 2D, expand it to 3D - simple handling of 2D tracing
483
      if ( vardim(3).eq.1 ) then
484
         do i=1,nx
485
            do j=1,ny
486
               do k=1,nz
487
                  field(i,j,k) = field(i,j,1)
488
               enddo
489
            enddo
490
         enddo
491
      endif
492
 
493
 
494
 
495
c     Exception handling
496
      return
497
 
498
 900  print*,'Cannot retrieve definition for ',trim(varname),'  ',fid
499
      stop
500
 901  print*,'Grid inconsistency detected for ',trim(varname),'  ',fid
501
      stop
502
 902  print*,'Cannot retrieve time for ',trim(varname),'  ',fid
503
      stop
504
 903  print*,'Cannot load wind component ',trim(varname),'  ',fid
505
      stop
506
 904  print*,'Cannot load time ',time,' for ',trim(varname),'  ',fid
507
      stop
508
 905  print*,'Cannot load time vertical grid AK, BK from file  ',fid
509
      stop
510
 
511
      end
512
 
513
c     ------------------------------------------------------------
514
c     Close input file
515
c     ------------------------------------------------------------
516
 
517
      subroutine input_close(fid)
518
 
519
c     Close the input file with file identifier <fid>.
520
 
521
      implicit none
522
 
523
c     Declaration of subroutine parameters
524
      integer fid
525
 
526
c     Auxiliary variables
527
      integer ierr
528
 
529
c     Close file
530
      call clscdf(fid,ierr)
531
 
532
      end