Subversion Repositories pvinversion.ecmwf

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3 michaesp 1
      PROGRAM inv_prep
2
 
3
c     ********************************************************************************
4
c     * CALCULATE REFERENCE PROFILE, CORIOLIS PARAMETER AND GRID PARAMETERS          *
5
c     * Rene Fehlmann 1994 / Code re-organization: Michael Sprenger, 2006            *
6
c     ********************************************************************************
7
 
8
c     --------------------------------------------------------------------------------
9
c     Declaration of variables, parameters, externals and common blocks
10
c     --------------------------------------------------------------------------------
11
 
12
      implicit none
13
 
14
c     Input and output file
15
      character*80   pvsrcfile,referfile
16
      integer        mode
17
      real           radius
18
 
19
c     Grid parameters
20
      integer        nx,ny,nz
21
      real           xmin,ymin,zmin,xmax,ymax,zmax
22
      real           dx,dy,dz
23
      real           mdv
24
 
25
c     Reference state
26
      real,   allocatable,dimension (:) :: nsqref
27
      real,   allocatable,dimension (:) :: thetaref
28
      real,   allocatable,dimension (:) :: rhoref
29
      real,   allocatable,dimension (:) :: pressref
30
      real,   allocatable,dimension (:) :: zref
31
      real    pressn,thetan
32
 
33
c     3d fields for calculation of reference profile
34
      real,allocatable,dimension (:,:,:) :: th,rho,nsq,p,z
35
 
36
c     2d weight for mean
37
      real,allocatable,dimension (:,:) :: weight
38
 
39
c     Auxiliary variables
40
      integer      i,j,k
41
      integer      stat
42
      integer      jj,kk
43
      character*80 varname
44
      integer      istep
45
      real         sum,max,min
46
      integer      cnt,nmd
47
      integer      step
48
      integer      i0,j0
49
      real         lon0,lat0,lon1,lat1,dist
50
      integer      vardim(4),ndim,cdfid,ierr
51
      real         varmin(4),varmax(4),stag(4)
52
      real         mdv
53
      character*80 name
54
 
55
c     Externals
56
      real      sdis
57
      external  sdis
58
 
59
c     --------------------------------------------------------------------------------
60
c     Input
61
c     --------------------------------------------------------------------------------
62
 
63
      print*,'********************************************************'
64
      print*,'* ref_grid                                             *'
65
      print*,'********************************************************'
66
 
67
c     Read parameter file
68
      open(10,file='fort.10')
69
       read(10,*) pvsrcfile
70
       read(10,*) referfile
71
       read(10,*) name,radius
72
       if ( trim(name).ne.'REF_R') stop
73
      close(10) 
74
      print*
75
      print*,trim(pvsrcfile)
76
      print*,trim(referfile)
77
      print*,radius
78
      print*
79
 
80
c     Get lat/lon gid parameters from input file
81
      call read_dim (nx,ny,nz,dx,dy,dz,xmin,ymin,zmin,mdv,
82
     >               pvsrcfile)
83
      print*,'Read_Dim: nx,ny,nz         = ',nx,ny,nz
84
      print*,'          dx,dy,dz         = ',dx,dy,dz
85
      print*,'          xmin,ymin,zmin   = ',xmin,ymin,zmin
86
      print*,'          mdv              = ',mdv
87
      print*
88
      xmax = xmin + real(nx-1) * dx
89
      ymax = ymin + real(ny-1) * dy
90
 
91
c     Count from 0, not from 1: consistent with <inv_cart.f>.
92
      nx=nx-1
93
      ny=ny-1
94
      nz=nz-1
95
 
96
c     Allocate memory for reference profile
97
      allocate(rhoref  (0:2*nz),STAT=stat)
98
      if (stat.ne.0) print*,'error allocating rhoref'
99
      allocate(pressref(0:2*nz),STAT=stat)
100
      if (stat.ne.0) print*,'error allocating pressref'
101
      allocate(thetaref(0:2*nz),STAT=stat)
102
      if (stat.ne.0) print*,'error allocating thetaref'
103
      allocate(nsqref  (0:2*nz),STAT=stat)
104
      if (stat.ne.0) print*,'error allocating nsqref'
105
      allocate(zref    (0:2*nz),STAT=stat)
106
      if (stat.ne.0) print*,'error allocating zref'
107
 
108
c     Allocate memory for calculatation of reference profile
109
      allocate(th (0:nx,0:ny,0:nz),STAT=stat)
110
      if (stat.ne.0) print*,'error allocating th'
111
      allocate(rho(0:nx,0:ny,0:nz),STAT=stat)
112
      if (stat.ne.0) print*,'error allocating rho'
113
      allocate(p  (0:nx,0:ny,0:nz),STAT=stat)
114
      if (stat.ne.0) print*,'error allocating p'
115
      allocate(nsq(0:nx,0:ny,0:nz),STAT=stat)
116
      if (stat.ne.0) print*,'error allocating nsq'
117
      allocate(z(0:nx,0:ny,0:nz),STAT=stat)
118
      if (stat.ne.0) print*,'error allocating z'
119
 
120
c     Allocate memory for weight
121
      allocate(weight(0:nx,0:ny),STAT=stat)
122
      if (stat.ne.0) print*,'error allocating weight'
123
 
124
c     --------------------------------------------------------------------------------
125
c     Calculate the reference profile and put it onto netcdf file
126
c     --------------------------------------------------------------------------------
127
 
128
c     Read data from file
129
      varname='TH'
130
      call read_inp (th,varname,pvsrcfile,
131
     >               nx,ny,nz,dx,dy,dz,xmin,ymin,zmin,mdv)
132
      varname='RHO'
133
      call read_inp (rho,varname,pvsrcfile,
134
     >               nx,ny,nz,dx,dy,dz,xmin,ymin,zmin,mdv)
135
      varname='NSQ'
136
      call read_inp (nsq,varname,pvsrcfile,
137
     >               nx,ny,nz,dx,dy,dz,xmin,ymin,zmin,mdv)
138
      varname='P'
139
      call read_inp (p,varname,pvsrcfile,
140
     >               nx,ny,nz,dx,dy,dz,xmin,ymin,zmin,mdv)
141
 
142
c     Init the height field (not really necessary, but code becomes more symmetrical)
143
      do i=0,nx
144
         do j=0,ny
145
            do k=0,nz
146
               z(i,j,k)=zmin+real(k)*dz
147
            enddo
148
         enddo
149
      enddo
150
 
151
c     Define the weight
152
      if ( radius.lt.0 ) then
153
        do i=0,nx
154
          do j=0,ny
155
              weight(i,j) = 1.
156
          enddo
157
        enddo
158
      else
159
        i0 = nx/2
160
        j0 = ny/2
161
        lon0 = xmin + real(i0-1) * dx
162
        lat0 = ymin + real(j0-1) * dy
163
        weight(i0,j0)=1.
164
        do i=0,nx
165
          do j=0,ny
166
             lon1 = xmin + real(i-1) * dx
167
             lat1 = ymin + real(j-1) * dy
168
             dist = sdis(lon0,lat0,lon1,lat1)
169
             if ( dist.lt.radius ) then
170
                weight(i,j) = 1.
171
             else
172
                weight(i,j) = 0.
173
             endif
174
          enddo
175
        enddo
176
      endif
177
 
178
c     Determine the reference profile (mean over domain, split levels and layers)
179
      call mean(zref,    z,  nx,ny,nz,mdv,weight)
180
      call mean(nsqref,  nsq,nx,ny,nz,mdv,weight)
181
      call mean(rhoref,  rho,nx,ny,nz,mdv,weight)
182
      call mean(thetaref,th, nx,ny,nz,mdv,weight)
183
      call mean(pressref,p,  nx,ny,nz,mdv,weight)
184
 
185
c     Write reference file to netcdf file
186
      call write_ref (nsqref,rhoref,thetaref,pressref,zref,
187
     >                nz,referfile)      
188
 
189
c     Write some info
190
      print*
191
      print*,'Ref:            z         p       rho       nsq     theta'
192
      step=2*nz/10
193
      if (step.lt.1) step=1
194
      do k=0,2*nz,step
195
         write(*,'(8x,f10.1,2f10.2,f10.6,f10.2)')
196
     >         zref(k),pressref(k),rhoref(k),nsqref(k),thetaref(k) 
197
      enddo
198
      print*
199
 
200
c     Write weighht to REF file
201
      call cdfwopn(trim(referfile),cdfid,ierr)
202
      varname='WEIGHT'
203
      vardim(1)=nx+1
204
      vardim(2)=ny+1
205
      vardim(3)=1
206
      vardim(4)=1
207
      varmin(1)=xmin
208
      varmin(2)=ymin
209
      varmin(3)=0.
210
      varmax(1)=xmax
211
      varmax(2)=ymax
212
      varmax(3)=0.
213
      ndim=3
214
      mdv=-999.
215
      call putdef(cdfid,varname,ndim,mdv,vardim,
216
     >            varmin,varmax,stag,ierr)
217
      call putdat(cdfid,varname,0.,1,weight,ierr)
218
 
219
c     --------------------------------------------------------------------------------
220
c     Format specifications
221
c     --------------------------------------------------------------------------------
222
 
223
 111  format (5f20.9)
224
 106  format (2f20.9)
225
 
226
      end
227
 
228
c     --------------------------------------------------------------------------
229
c     Spherical distance between lat/lon points
230
c     --------------------------------------------------------------------------
231
 
232
      real function sdis(xp,yp,xq,yq)
233
c
234
c     calculates spherical distance (in km) between two points given
235
c     by their spherical coordinates (xp,yp) and (xq,yq), respectively.
236
c
237
      real      re
238
      parameter (re=6370.)
239
      real      pi180
240
      parameter (pi180=3.14159/180.)
241
      real      xp,yp,xq,yq,arg
242
 
243
      arg=sin(pi180*yp)*sin(pi180*yq)+
244
     >    cos(pi180*yp)*cos(pi180*yq)*cos(pi180*(xp-xq))
245
      if (arg.lt.-1.) arg=-1.
246
      if (arg.gt.1.) arg=1.
247
 
248
      sdis=re*acos(arg)
249
 
250
      end
251
 
252
c     ********************************************************************************
253
c     * NETCDF INPUT AND OUTPUT                                                      *
254
c     ********************************************************************************
255
 
256
 
257
c     --------------------------------------------------------------------------------
258
c     Write reference file to netcdf
259
c     --------------------------------------------------------------------------------
260
 
261
      SUBROUTINE write_ref (nsqref,rhoref,thetaref,pressref,zref,
262
     >                      nz,pvsrcfile) 
263
 
264
c     Write the reference profile to file
265
c
266
c         thetaref             : Reference potential temperature (K)
267
c         pressref             : Reference pressure (Pa)
268
c         rhoref               : Reference density (kg/m^3)
269
c         nsqref               : Stratification (s^-1)
270
c         zref                 : Reference height (m)
271
c         nz                   : Grid dimension in z direction
272
c         pvsrcfile            : Output file
273
 
274
      implicit   none
275
 
276
c     Declaration of subroutine parameters
277
      integer              nx,ny,nz
278
      real                 nsqref  (0:2*nz)
279
      real                 thetaref(0:2*nz)
280
      real                 rhoref  (0:2*nz)
281
      real                 pressref(0:2*nz)
282
      real                 zref    (0:2*nz)
283
      character*80         pvsrcfile
284
 
285
c     Numerical and physical parameters
286
      real                 eps
287
      parameter            (eps=0.01)
288
 
289
c     Auxiliary variables
290
      integer              cdfid,stat
291
      integer              vardim(4)
292
      real                 misdat
293
      integer              ndimin
294
      real                 varmin(4),varmax(4),stag(4)
295
      integer              i,j,k,nf1
296
      integer              ntimes
297
      real                 time(200)  
298
      character*80         vnam(100),varname
299
      integer              nvars
300
      integer              isok,ierr
301
 
302
c     Get grid description from topography
303
      call cdfopn(pvsrcfile,cdfid,stat)
304
      if (stat.ne.0) goto 997
305
      call getvars(cdfid,nvars,vnam,stat)
306
      if (stat.ne.0) goto 997
307
      isok=0
308
      varname='ORO'
309
      call check_varok(isok,varname,vnam,nvars)
310
      if (isok.eq.0) goto 997
311
      call getdef(cdfid,varname,ndimin,misdat,vardim,
312
     >            varmin,varmax,stag,stat)    
313
      if (stat.ne.0) goto 997
314
      time(1)=0.
315
      call gettimes(cdfid,time,ntimes,stat)  
316
      if (stat.ne.0) goto 997
317
      call clscdf(cdfid,stat)
318
      if (stat.ne.0) goto 997
319
 
320
c     Open output netcdf file
321
      call cdfwopn(pvsrcfile,cdfid,stat)
322
      if (stat.ne.0) goto 997
323
 
324
c     Create the variable if necessary
325
      call getvars(cdfid,nvars,vnam,stat)
326
      if (stat.ne.0) goto 997
327
      isok=0
328
      varname='NSQREF'
329
      call check_varok(isok,varname,vnam,nvars)
330
      if (isok.eq.0) then
331
         vardim(1)=1
332
         vardim(2)=1
333
         vardim(3)=2*nz+1
334
         call putdef(cdfid,varname,ndimin,misdat,vardim,
335
     >               varmin,varmax,stag,stat)
336
         if (stat.ne.0) goto 997
337
      endif
338
      isok=0
339
      varname='RHOREF'
340
      call check_varok(isok,varname,vnam,nvars)
341
      if (isok.eq.0) then
342
         vardim(1)=1
343
         vardim(2)=1
344
         vardim(3)=2*nz+1
345
         call putdef(cdfid,varname,ndimin,misdat,vardim,
346
     >               varmin,varmax,stag,stat)
347
         if (stat.ne.0) goto 997
348
      endif
349
      isok=0
350
      varname='PREREF'
351
      call check_varok(isok,varname,vnam,nvars)
352
      if (isok.eq.0) then
353
         vardim(1)=1
354
         vardim(2)=1
355
         vardim(3)=2*nz+1
356
         call putdef(cdfid,varname,ndimin,misdat,vardim,
357
     >               varmin,varmax,stag,stat)
358
         if (stat.ne.0) goto 997
359
      endif
360
      isok=0
361
      varname='THETAREF'
362
      call check_varok(isok,varname,vnam,nvars)
363
      if (isok.eq.0) then
364
         vardim(1)=1
365
         vardim(2)=1
366
         vardim(3)=2*nz+1
367
         call putdef(cdfid,varname,ndimin,misdat,vardim,
368
     >               varmin,varmax,stag,stat)
369
         if (stat.ne.0) goto 997
370
      endif
371
      isok=0
372
      varname='ZREF'
373
      call check_varok(isok,varname,vnam,nvars)
374
      if (isok.eq.0) then
375
         vardim(1)=1
376
         vardim(2)=1
377
         vardim(3)=2*nz+1
378
         call putdef(cdfid,varname,ndimin,misdat,vardim,
379
     >               varmin,varmax,stag,stat)
380
         if (stat.ne.0) goto 997
381
      endif
382
 
383
c     Write data
384
      varname='NSQREF'
385
      print*,'W NSQREF     ',trim(pvsrcfile)
386
      call putdat(cdfid,varname,time(1),0,nsqref,stat)
387
      if (stat.ne.0) goto 997
388
      varname='RHOREF'
389
      print*,'W RHOREF     ',trim(pvsrcfile)
390
      call putdat(cdfid,varname,time(1),0,rhoref,stat)
391
      if (stat.ne.0) goto 997
392
      varname='THETAREF'
393
      print*,'W THETAREF   ',trim(pvsrcfile)
394
      call putdat(cdfid,varname,time(1),0,thetaref,stat)
395
      if (stat.ne.0) goto 997
396
      varname='PREREF'
397
      print*,'W PREREF     ',trim(pvsrcfile)
398
      call putdat(cdfid,varname,time(1),0,pressref,stat)
399
      if (stat.ne.0) goto 997
400
      varname='ZREF'
401
      print*,'W ZREF       ',trim(pvsrcfile)
402
      call putdat(cdfid,varname,time(1),0,zref,stat)
403
      if (stat.ne.0) goto 997
404
 
405
c     Close output netcdf file
406
      call clscdf(cdfid,stat)
407
      if (stat.ne.0) goto 997
408
 
409
      return
410
 
411
c     Exception handling
412
 997  print*,'Write_Ref: Problem with input netcdf file... Stop'
413
      stop
414
 
415
      end
416
 
417
 
418
c     --------------------------------------------------------------------------------
419
c     Read input fields for reference profile
420
c     --------------------------------------------------------------------------------
421
 
422
      SUBROUTINE read_inp (field,fieldname,pvsrcfile,
423
     >                     nx,ny,nz,dx,dy,dz,xmin,ymin,zmin,mdv)
424
 
425
c     Read <fieldname> from netcdf file <pvsrcfile> into <field>. The grid is specified 
426
c     by <nx,ny,nz,dx,dy,dz,xmin,ymin,zmin>. A check is performed whether the input 
427
c     files are consitent with this grid. The missing data value is set to <mdv>.
428
 
429
      implicit   none
430
 
431
c     Declaration of subroutine parameters
432
      integer              nx,ny,nz
433
      real                 field(0:nx,0:ny,0:nz)
434
      character*80         fieldname
435
      character*80         pvsrcfile
436
      real                 dx,dy,dz,xmin,ymin,zmin
437
      real                 mdv
438
 
439
c     Numerical and physical parameters
440
      real                 eps
441
      parameter            (eps=0.01)
442
 
443
c     Auxiliary variables
444
      integer              cdfid,stat,cdfid99
445
      integer              vardim(4)
446
      real                 misdat
447
      real                 varmin(4),varmax(4),stag(4)
448
      integer              ndimin,outid,i,j,k
449
      real                 max_th
450
      real                 tmp(nx,ny,nz)
451
      integer              ntimes
452
      real                 time(200)       
453
      integer              nvars
454
      character*80         vnam(100),varname
455
      integer              isok
456
 
457
c     Open the input netcdf file
458
      call cdfopn(pvsrcfile,cdfid,stat)
459
      if (stat.ne.0) goto 998
460
 
461
c     Check whether needed variables are on file
462
      call getvars(cdfid,nvars,vnam,stat)
463
      if (stat.ne.0) goto 998
464
      isok=0
465
      varname=trim(fieldname)
466
      call check_varok(isok,varname,vnam,nvars)
467
      if (isok.eq.0) goto 998
468
 
469
c     Get the grid parameters 
470
      call getdef(cdfid,varname,ndimin,misdat,vardim,
471
     >            varmin,varmax,stag,stat)    
472
      if (stat.ne.0) goto 998
473
      time(1)=0.
474
      call gettimes(cdfid,time,ntimes,stat)  
475
      if (stat.ne.0) goto 998
476
 
477
c     Check whether grid parameters are consistent
478
      if ( (vardim(1).ne.(nx+1)).or.
479
     >     (vardim(2).ne.(ny+1)).or.
480
     >     (vardim(3).ne.(nz+1)).or.
481
     >     (abs(varmin(1)-xmin).gt.eps).or.
482
     >     (abs(varmin(2)-ymin).gt.eps).or.
483
     >     (abs(varmin(3)-zmin).gt.eps).or.
484
     >     (abs((varmax(1)-varmin(1))/real(vardim(1)-1)-dx).gt.eps).or.
485
     >     (abs((varmax(2)-varmin(2))/real(vardim(2)-1)-dy).gt.eps).or.
486
     >     (abs((varmax(3)-varmin(3))/real(vardim(3)-1)-dz).gt.eps) ) 
487
     >then
488
         print*,'Input grid inconsitency...'
489
         print*,'  Nx      = ',vardim(1),nx+1
490
         print*,'  Ny      = ',vardim(2),ny+1
491
         print*,'  Nz      = ',vardim(3),nz+1
492
         print*,'  Varminx = ',varmin(1),xmin
493
         print*,'  Varminy = ',varmin(2),ymin
494
         print*,'  Varminz = ',varmin(3),zmin
495
         print*,'  Dx      = ',(varmax(1)-varmin(1))/real(nx-1),dx
496
         print*,'  Dy      = ',(varmax(2)-varmin(2))/real(ny-1),dy
497
         print*,'  Dz      = ',(varmax(3)-varmin(3))/real(nz-1),dz
498
         goto 998
499
      endif
500
 
501
c     Load variables
502
      call getdef(cdfid,varname,ndimin,misdat,vardim,
503
     >            varmin,varmax,stag,stat)
504
      if (stat.ne.0) goto 998
505
      call getdat(cdfid,varname,time(1),0,field,stat)
506
      print*,'R ',trim(varname),' ',trim(pvsrcfile)
507
      if (stat.ne.0) goto 998
508
 
509
c     Close input netcdf file
510
      call clscdf(cdfid,stat)
511
      if (stat.ne.0) goto 998
512
 
513
c     Set missing data value to <mdv>
514
      do i=1,nx
515
         do j=1,ny
516
            do k=1,nz
517
               if (abs(field(i,j,k)-misdat).lt.eps) then
518
                  field(i,j,k)=mdv
519
               endif
520
            enddo
521
         enddo
522
      enddo
523
 
524
      return
525
 
526
c     Exception handling
527
 998  print*,'Read_Inp: Problem with input netcdf file... Stop'
528
      stop
529
 
530
      end
531
 
532
c     --------------------------------------------------------------------------------
533
c     Check whether variable is found on netcdf file
534
c     --------------------------------------------------------------------------------
535
 
536
      subroutine check_varok (isok,varname,varlist,nvars)
537
 
538
c     Check whether the variable <varname> is in the list <varlist(nvars)>. If this is 
539
C     the case, <isok> is incremented by 1. Otherwise <isok> keeps its value.
540
 
541
      implicit none
542
 
543
c     Declaraion of subroutine parameters
544
      integer      isok
545
      integer      nvars
546
      character*80 varname
547
      character*80 varlist(nvars)
548
 
549
c     Auxiliary variables
550
      integer      i
551
 
552
c     Main
553
      do i=1,nvars
554
         if (trim(varname).eq.trim(varlist(i))) isok=isok+1
555
      enddo
556
 
557
      end
558
 
559
c     --------------------------------------------------------------------------------
560
c     Get grid parameters
561
c     --------------------------------------------------------------------------------
562
 
563
      subroutine read_dim (nx,ny,nz,dx,dy,dz,xmin,ymin,zmin,mdv,
564
     >                     pvsrcfile)
565
 
566
c     Get the grid parameters from the variable <TH> on the input file <pvsrcfile>.
567
c     The grid parameters are
568
c        nx,ny,nz                : Number of grid points in x, y and z direction
569
c        xmin,ymin,zmin          : Minimum domain coordinates in x, y and z direction
570
c        xmax,ymax,zmax          : Maximal domain coordinates in x, y and z direction
571
c        dx,dy,dz                : Horizontal and vertical resolution
572
c     Additionally, it is checked whether the vertical grid is equally spaced. If ok,
573
c     the grid paramters are transformed from lon/lat to distance (in meters)
574
 
575
      implicit none
576
 
577
c     Declaration of subroutine parameters
578
      character*80   pvsrcfile
579
      integer        nx,ny,nz
580
      real           dx,dy,dz
581
      real           xmin,ymin,zmin,xmax,ymax,zmax
582
      real           mdv
583
 
584
c     Numerical epsilon and other physical/geoemtrical parameters
585
      real           eps
586
      parameter      (eps=0.01)
587
 
588
c     Auxiliary variables
589
      integer        cdfid,cstid
590
      integer        ierr
591
      character*80   vnam(100),varname
592
      integer        nvars
593
      integer        isok
594
      integer        vardim(4)
595
      real           misdat
596
      real           varmin(4),varmax(4),stag(4)
597
      real           aklev(1000),bklev(1000),aklay(1000),bklay(1000)
598
      real           dh
599
      character*80   csn
600
      integer        ndim
601
      integer        i
602
 
603
c     Get all grid parameters
604
      call cdfopn(pvsrcfile,cdfid,ierr)
605
      if (ierr.ne.0) goto 998
606
      call getvars(cdfid,nvars,vnam,ierr)
607
      if (ierr.ne.0) goto 998
608
      isok=0
609
      varname='T'
610
      call check_varok(isok,varname,vnam,nvars)
611
      if (isok.eq.0) goto 998
612
      call getcfn(cdfid,csn,ierr)
613
      if (ierr.ne.0) goto 998
614
      call cdfopn(csn,cstid,ierr)
615
      if (ierr.ne.0) goto 998
616
      call getdef(cdfid,varname,ndim,misdat,vardim,varmin,varmax,
617
     >            stag,ierr)
618
      if (ierr.ne.0) goto 998
619
      nx=vardim(1)
620
      ny=vardim(2)
621
      nz=vardim(3)
622
      xmin=varmin(1)
623
      ymin=varmin(2)
624
      zmin=varmin(3)
625
      call getlevs(cstid,nz,aklev,bklev,aklay,bklay,ierr)
626
      if (ierr.ne.0) goto 998
627
      call getgrid(cstid,dx,dy,ierr)
628
      if (ierr.ne.0) goto 998
629
      xmax=varmax(1)
630
      ymax=varmax(2)
631
      zmax=varmax(3)
632
      dz=(zmax-zmin)/real(nz-1)
633
      call clscdf(cstid,ierr)
634
      if (ierr.ne.0) goto 998
635
      call clscdf(cdfid,ierr)
636
      if (ierr.ne.0) goto 998
637
 
638
c     Check whether the grid is equallay spaced in the vertical
639
      do i=1,nz-1
640
         dh=aklev(i+1)-aklev(i)
641
         if (abs(dh-dz).gt.eps) then
642
            print*,'Aklev: Vertical grid must be equally spaced... Stop'
643
            print*,(aklev(i),i=1,nz)
644
            stop
645
         endif
646
         dh=aklay(i+1)-aklay(i)
647
         if (abs(dh-dz).gt.eps) then
648
            print*,'Aklay: Vertical grid must be equally spaced... Stop'
649
            print*,(aklay(i),i=1,nz)
650
            stop
651
         endif
652
      enddo
653
 
654
c     Set missing data value
655
      mdv=misdat
656
 
657
      return
658
 
659
c     Exception handling
660
 998  print*,'Read_Dim: Problem with input netcdf file... Stop'
661
      stop
662
 
663
      end
664
 
665
 
666
c     ********************************************************************************
667
c     * DEFINE REFERENCE PROFILE                                                     *
668
c     ********************************************************************************
669
 
670
c     --------------------------------------------------------------------------------
671
c     Calculate area mean
672
c     --------------------------------------------------------------------------------
673
 
674
      SUBROUTINE mean(a,m,nx,ny,nz,mdv,weight)
675
 
676
c     Calculate the area-mean of <m> and save it on <a>.
677
 
678
      implicit none
679
 
680
c     Declaration of subroutine parameters
681
      real       mdv
682
      integer    nx,ny,nz
683
      real       m(0:nx,0:ny,0:nz),a(0:2*nz)
684
      real       weight(0:nx,0:ny)
685
 
686
c     Numerical epsilon
687
      real       eps
688
      parameter  (eps=0.01)
689
 
690
c     Auxiliary varaibles
691
      real       mea(0:nz)
692
      integer    i,j,k,kk
693
      real       counter
694
 
695
c     Determine the mean over all levels (handle missing data)
696
      do k=0,nz
697
         mea(k)=0.
698
         counter=0.
699
         do i=0,nx
700
            do j=0,ny
701
               if (abs(m(i,j,k)-mdv).gt.eps) then
702
                  mea(k)=mea(k)+m(i,j,k)*weight(i,j)
703
                  counter=counter+weight(i,j)
704
               endif
705
 
706
            enddo
707
         enddo
708
         if (counter.gt.0) then
709
            mea(k)=mea(k)/counter
710
         else
711
            mea(k)=mdv
712
         endif
713
      enddo
714
 
715
c     Prepare the output array: split layers and levels
716
      do k=0,nz-1
717
         kk=2*k
718
         a(kk)=mea(k)
719
         a(kk+1)=0.5*(mea(k)+mea(k+1))
720
      enddo
721
      a(2*nz)=mea(nz)
722
 
723
      end