Subversion Repositories lagranto.ecmwf

Rev

Rev 9 | Rev 21 | 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
 
19 michaesp 195
c        Special handling for fieldname 'P.ML' -> in this case the fields
196
c        P and PS are available on the data file and can be read in. There
197
c        is no need to reconstruct it from PS,AK and BK. This mode is
198
c        used for model-level (2D) trajectories
199
         if ( fieldname.eq.'P.ML' ) then
200
 
201
c           Get the right time to read
202
            call gettimes(fid,times,ntimes,ierr)
203
            if (ierr.ne.0) goto 901
204
            isok=0
205
            do i=1,ntimes
206
               if (abs(time-times(i)).lt.eps) then
207
                  isok = 1
208
                  rtime = times(i)
209
               elseif (timecheck.eq.'no') then
210
                  isok = 1
211
                  rtime = times(1)
212
               endif
213
            enddo
214
 
215
c           Read surface pressure and 3D pressure
216
            varname='PS'
217
            call getdat(fid,varname,rtime,0,ps,ierr)
218
            if (ierr.ne.0) goto 904
219
            varname='P'
220
            call getdat(fid,varname,rtime,0,p3,ierr)
221
            if (ierr.ne.0) goto 904
222
 
223
c           Set MDV to 1050. - otherwise interpolation routines don't work
224
            do i=1,nx
225
              do j=1,ny
226
                do k=1,nz
227
                   if ( p3(i,j,k).lt.0. ) p3(i,j,k) = 1050.
228
                enddo
229
              enddo
230
            enddo
231
 
232
c           Don't care about other stuff - finish subroutine
233
            goto 800
234
 
235
         endif
236
 
3 michaesp 237
c        Get full grid info - in particular staggering flag; set flag for 2D tracing
238
         if ( fieldname.eq.'PLEV' ) then
239
            varname = 'PS'
240
            stagz   = 0.
241
            call getdef(fid,varname,ndim,mdv,vardim,
242
     >                  varmin,varmax,stag,ierr)
243
            if (ierr.ne.0) goto 900
244
            call getcfn(fid,cstfile,ierr)
245
            if (ierr.ne.0) goto 903
246
            call cdfopn(cstfile,cstid,ierr)
247
            if (ierr.ne.0) goto 903
248
            call getlevs(cstid,vardim(3),tmp,tmp,tmp,tmp,ierr)
249
            if (ierr.ne.0) goto 903
250
            call clscdf(cstid,ierr)
251
            if (ierr.ne.0) goto 903
252
 
253
         elseif ( ( fieldname.eq.'PLAY' ).or.( fieldname.eq.'P' ) ) then       
254
            varname = 'PS'
255
            stagz   = -0.5
256
            call getdef(fid,varname,ndim,mdv,vardim,
257
     >                  varmin,varmax,stag,ierr)
258
            if (ierr.ne.0) goto 900
259
            call getcfn(fid,cstfile,ierr)
260
            if (ierr.ne.0) goto 903
261
            call cdfopn(cstfile,cstid,ierr)
262
            if (ierr.ne.0) goto 903
263
            call getlevs(cstid,vardim(3),tmp,tmp,tmp,tmp,ierr)
264
            if (ierr.ne.0) goto 903
265
            call clscdf(cstid,ierr)
266
            if (ierr.ne.0) goto 903
267
 
268
         else
269
            varname=fieldname
270
            call getdef(fid,varname,ndim,mdv,vardim,
271
     >                  varmin,varmax,stag,ierr)
272
            if (ierr.ne.0) goto 900
273
            if (vardim(3).eq.1) is2d = 1
274
         endif
275
 
276
c        Get time information (check if time is correct)
277
         call gettimes(fid,times,ntimes,ierr)
278
         if (ierr.ne.0) goto 901
279
         isok=0
280
         do i=1,ntimes
281
            if (abs(time-times(i)).lt.eps) then
282
               isok = 1
283
               rtime = times(i)
284
            elseif (timecheck.eq.'no') then
285
               isok = 1
286
               rtime = times(1)
287
            endif
288
         enddo
289
         if ( isok.eq.0) goto 905
290
 
291
c        If 2D tracing requested: take dummay values for PS, AKLEV,BKLEV,AKLAY,BKLAY
292
         if ( is2d.eq.1 ) then
293
 
294
            do i=1,nx
295
               do j=1,ny
296
                  ps(i,j) = 1050.
297
               enddo
298
            enddo
299
 
300
            do k=1,nz
301
               aklev(k) = 0.
302
               bklev(k) = real(nz-k)/real(nz-1) 
303
               aklay(k) = 0.
304
               bklay(k) = real(nz-k)/real(nz-1) 
305
            enddo
306
 
307
c        3D tracing - read PS, AKLEV,BKLEV,AKLAY;BKLAY
308
         else
309
 
310
c           Read the level coefficients from the constants file
311
            call getcfn(fid,cstfile,ierr)
312
            if (ierr.ne.0) goto 903
313
            call cdfopn(cstfile,cstid,ierr)
314
            if (ierr.ne.0) goto 903
315
            call getlevs(cstid,vardim(3),aklev,bklev,aklay,bklay,ierr)
316
            if (ierr.ne.0) goto 903
317
            call clscdf(cstid,ierr)
318
            if (ierr.ne.0) goto 903
319
 
9 michaesp 320
c           Check whether PS is needed to get the 3d pressure field
321
            plev = 1
322
            do i=1,nz
323
              if ( (abs(stagz).lt.eps).and.(abs(bklev(i)).gt.eps) ) then
324
                plev = 0
325
              endif
326
              if ( (abs(stagz).gt.eps).and.(abs(bklay(i)).gt.eps) ) then
327
                plev = 0
328
              endif
329
            enddo
3 michaesp 330
 
9 michaesp 331
c           Read surface pressure if needed
332
            if ( plev.ne.1 ) then
333
              varname='PS'
334
              call getdat(fid,varname,rtime,0,ps,ierr)
335
              if (ierr.ne.0) goto 904
336
            else
337
              do i=1,nx
338
                do j=1,ny
339
                    ps(i,j) = 1000.
340
                enddo
341
              enddo
342
            endif
343
 
3 michaesp 344
         endif
345
 
346
c        Calculate layer and level pressures
347
         do i=1,nx
348
            do j=1,ny
349
               do k=1,nz
350
                  if ( abs(stagz).lt.eps ) then
351
                     p3(i,j,k)=aklev(k)+bklev(k)*ps(i,j)
352
                  else
353
                     p3(i,j,k)=aklay(k)+bklay(k)*ps(i,j)
354
                  endif
355
               enddo
356
            enddo
357
         enddo
358
 
359
c        Set the ak and bk for the vertical grid
360
         do k=1,nz
361
            if ( abs(stagz).lt.eps ) then
362
               ak(k)=aklev(k)
363
               bk(k)=bklev(k)
364
            else
365
               ak(k)=aklay(k)
366
               bk(k)=bklay(k)
367
            endif
368
         enddo
369
 
370
      endif
371
 
372
c     Exit point for subroutine
373
 800  continue
374
      return
375
 
376
c     Exception handling
377
 900  print*,'Cannot retrieve grid dimension from ',fid
378
      stop
379
 901  print*,'Cannot retrieve grid parameters from ',fid
380
      stop
381
 902  print*,'Grid inconsistency detected for ',fid
382
      stop
383
 903  print*,'Problem with level coefficients from ',trim(cstfile)
384
      stop
385
 904  print*,'Cannot read surface pressure from ',trim(cstfile)
386
      stop
387
 905  print*,'Cannot find time ',time,' on ',fid
388
      stop
389
 906  print*,'Unable to get grid info ',fid
390
      stop
391
 
392
      end
393
 
394
c     ------------------------------------------------------------
395
c     Read wind information
396
c     ------------------------------------------------------------
397
 
398
      subroutine input_wind (fid,fieldname,field,time,stagz,mdv,
399
     >                       xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,
400
     >                       timecheck)
401
 
402
c     Read the wind component <fieldname> from the file with identifier
403
c     <fid> and save it in the 3d array <field>. The vertical staggering 
404
c     information is provided in <stagz> and gives the reference to either
405
c     the layer or level field from <input_grid>. A consistency check is
406
c     performed to have an agreement with the grid specified by <xmin,xmax,
407
c     ymin,ymax,dx,dy,nx,ny,nz>.
408
 
409
      implicit none
410
 
411
c     Declaration of variables and parameters
412
      integer      fid                 ! File identifier
413
      character*80 fieldname           ! Name of the wind field
414
      integer      nx,ny,nz            ! Dimension of fields
415
      real         field(nx,ny,nz)     ! 3d wind field
416
      real         stagz               ! Staggering in the z direction
417
      real         mdv                 ! Missing data flag
418
      real         xmin,xmax,ymin,ymax ! Domain size
419
      real         dx,dy               ! Horizontal resolution
420
      real         time                ! Time
421
      character*80 timecheck           ! Either 'yes' or 'no'
422
 
423
c     Numerical and physical parameters
424
      real        eps                 ! Numerical epsilon
425
      parameter  (eps=0.001)
426
      real        notimecheck         ! 'Flag' for no time check
427
      parameter  (notimecheck=7.26537)
428
 
429
c     Netcdf variables
430
      integer      ierr
431
      character*80 varname
432
      integer      vardim(4)
433
      real         varmin(4),varmax(4)
434
      real         stag(4)
435
      integer      ndim
436
      real         times(10)
437
      integer      ntimes
438
      character*80 cstfile
439
      integer      cstid
440
      real         aklay(200),bklay(200),aklev(200),bklev(200)
441
      real         ps(nx,ny)
442
 
443
c     Auxiliary variables
444
      integer      isok
445
      integer      i,j,k
446
      integer      nz1
447
      real         rtime
448
 
449
c     Read variable definition - for P, PLEV and PLAY: load also ak,bk
450
      if ( ( fieldname.eq.'PLEV' ).or.
451
     >     ( fieldname.eq.'PLAY' ).or.
452
     >     ( fieldname.eq.'P'    ) )
453
     >then
454
         call getcfn(fid,cstfile,ierr)
455
         if (ierr.ne.0) goto 905
456
         call cdfopn(cstfile,cstid,ierr)
457
         if (ierr.ne.0) goto 905
458
         call getlevs(cstid,nz1,aklev,bklev,aklay,bklay,ierr)
459
         if (ierr.ne.0) goto 905
460
         call clscdf(cstid,ierr)
461
         if (ierr.ne.0) goto 905
462
         varname = 'PS'
463
         call getdef(fid,varname,ndim,mdv,vardim,
464
     >               varmin,varmax,stag,ierr)
465
         vardim(3) = nz1
466
         if (ierr.ne.0) goto 900
19 michaesp 467
 
3 michaesp 468
      else
469
         varname = fieldname
470
         call getdef(fid,varname,ndim,mdv,vardim,
471
     >               varmin,varmax,stag,ierr)
472
         if (ierr.ne.0) goto 900
473
         stagz=stag(3)
474
      endif
475
 
476
c     Get time information (set time to first one in the file)
477
      call gettimes(fid,times,ntimes,ierr)
478
      if (ierr.ne.0) goto 902
479
      isok=0
480
      do i=1,ntimes
481
         if (abs(time-times(i)).lt.eps) then
482
            isok = 1
483
            rtime = times(i)
484
         elseif (timecheck.eq.'no') then
485
            isok = 1
486
            rtime = times(1)
487
         endif
488
      enddo
489
      if ( isok.eq.0 ) goto 904
490
 
491
c     Read  field
492
      if ( ( fieldname.eq.'P' ).or.(fieldname.eq.'PLAY') )  then       ! P, PLAY
493
         stagz   = -0.5
494
         varname = 'PS'
495
         call getdat(fid,varname,rtime,0,ps,ierr)
496
         if (ierr.ne.0) goto 903
497
         do i=1,nx
498
            do j=1,ny
499
               do k=1,nz
500
                  field(i,j,k)=aklay(k)+bklay(k)*ps(i,j)
501
               enddo
502
            enddo
503
         enddo
504
 
505
      elseif ( fieldname.eq.'PLEV' )  then                             ! PLEV
506
         stagz   = 0.
507
         varname = 'PS'
508
         call getdat(fid,varname,rtime,0,ps,ierr)
509
         if (ierr.ne.0) goto 903
510
         do i=1,nx
511
            do j=1,ny
512
               do k=1,nz
513
                  field(i,j,k)=aklev(k)+bklev(k)*ps(i,j)
514
               enddo
515
            enddo
516
         enddo
517
 
518
      else                                                             ! Other fields
519
         varname=fieldname
520
         call getdat(fid,varname,rtime,0,field,ierr)
521
         if (ierr.ne.0) goto 903
522
 
523
      endif
524
 
525
c     If the field is 2D, expand it to 3D - simple handling of 2D tracing
526
      if ( vardim(3).eq.1 ) then
527
         do i=1,nx
528
            do j=1,ny
529
               do k=1,nz
530
                  field(i,j,k) = field(i,j,1)
531
               enddo
532
            enddo
533
         enddo
534
      endif
535
 
536
 
537
 
538
c     Exception handling
539
      return
540
 
541
 900  print*,'Cannot retrieve definition for ',trim(varname),'  ',fid
542
      stop
543
 901  print*,'Grid inconsistency detected for ',trim(varname),'  ',fid
544
      stop
545
 902  print*,'Cannot retrieve time for ',trim(varname),'  ',fid
546
      stop
547
 903  print*,'Cannot load wind component ',trim(varname),'  ',fid
548
      stop
549
 904  print*,'Cannot load time ',time,' for ',trim(varname),'  ',fid
550
      stop
551
 905  print*,'Cannot load time vertical grid AK, BK from file  ',fid
552
      stop
553
 
554
      end
555
 
556
c     ------------------------------------------------------------
557
c     Close input file
558
c     ------------------------------------------------------------
559
 
560
      subroutine input_close(fid)
561
 
562
c     Close the input file with file identifier <fid>.
563
 
564
      implicit none
565
 
566
c     Declaration of subroutine parameters
567
      integer fid
568
 
569
c     Auxiliary variables
570
      integer ierr
571
 
572
c     Close file
573
      call clscdf(fid,ierr)
574
 
575
      end