Subversion Repositories lagranto.arpege

Rev

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