Subversion Repositories lagranto.ecmwf

Rev

Rev 13 | Rev 27 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 13 Rev 19
Line 41... Line 41...
41
 
41
 
42
c     Input and output format for trajectories (see iotra.f)
42
c     Input and output format for trajectories (see iotra.f)
43
      integer   inpmode
43
      integer   inpmode
44
      integer   outmode
44
      integer   outmode
45
 
45
 
46
c     Filename prefix (typically 'P')
46
c     Filename prefix for primary and secondary files (typically 'P' and 'S')
47
      character*1 prefix
47
      character*1 prefix
48
      parameter   (prefix='P')
48
      parameter   (prefix='P')
-
 
49
      character*1 srefix
-
 
50
      parameter   (srefix='S')
-
 
51
 
-
 
52
c     Physical constants - needed to compute potential temperature
-
 
53
      real      rdcp,tzero
-
 
54
      data      rdcp,tzero /0.286,273.15/
49
 
55
 
50
c     --------------------------------------------------------------------
56
c     --------------------------------------------------------------------
51
c     Declaration of variables
57
c     Declaration of variables
52
c     --------------------------------------------------------------------
58
c     --------------------------------------------------------------------
53
 
59
 
Line 64... Line 70...
64
      integer                                deltout         ! Output time interval (in minutes)
70
      integer                                deltout         ! Output time interval (in minutes)
65
      integer                                jflag           ! Jump flag (if =1 ground-touching trajectories reenter atmosphere)
71
      integer                                jflag           ! Jump flag (if =1 ground-touching trajectories reenter atmosphere)
66
      real                                   wfactor         ! Factor for vertical velocity field
72
      real                                   wfactor         ! Factor for vertical velocity field
67
      character*80                           strname         ! File with start positions
73
      character*80                           strname         ! File with start positions
68
      character*80                           timecheck       ! Either 'yes' or 'no'
74
      character*80                           timecheck       ! Either 'yes' or 'no'
-
 
75
      character*80                           isen            ! Isentropic trajectories ('yes' or 'no')
-
 
76
      integer                                thons           ! Isentropic mode: is TH availanle on S
-
 
77
      character*80                           modlev          ! 2D (model level) trajectories ('yes' or 'no')
69
 
78
 
70
c     Trajectories
79
c     Trajectories
71
      integer                                ncol            ! Number of columns for insput trajectories
80
      integer                                ncol            ! Number of columns for insput trajectories
72
      real,allocatable, dimension (:,:,:) :: trainp          ! Input start coordinates (ntra,1,ncol)
81
      real,allocatable, dimension (:,:,:) :: trainp          ! Input start coordinates (ntra,1,ncol)
73
      real,allocatable, dimension (:,:,:) :: traout          ! Output trajectories (ntra,ntim,4)
82
      real,allocatable, dimension (:,:,:) :: traout          ! Output trajectories (ntra,ntim,4)
Line 76... Line 85...
76
      real,allocatable, dimension (:)     :: xx0,yy0,pp0     ! Position of air parcels
85
      real,allocatable, dimension (:)     :: xx0,yy0,pp0     ! Position of air parcels
77
      integer,allocatable, dimension (:)  :: leftflag        ! Flag for domain-leaving
86
      integer,allocatable, dimension (:)  :: leftflag        ! Flag for domain-leaving
78
      real                                   xx1,yy1,pp1     ! Updated position of air parcel
87
      real                                   xx1,yy1,pp1     ! Updated position of air parcel
79
      integer                                leftcount       ! Number of domain leaving trajectories
88
      integer                                leftcount       ! Number of domain leaving trajectories
80
      integer                                ntim            ! Number of output time steps
89
      integer                                ntim            ! Number of output time steps
-
 
90
      real,allocatable, dimension (:)     :: theta           ! Potential temperature for isentropic trajectories
-
 
91
      real,allocatable, dimension (:)     :: zindex          ! Vertical index for model-level (2D) trajectories
81
 
92
 
82
c     Meteorological fields
93
c     Meteorological fields
83
      real,allocatable, dimension (:)     :: spt0,spt1       ! Surface pressure
94
      real,allocatable, dimension (:)     :: spt0,spt1       ! Surface pressure
84
      real,allocatable, dimension (:)     :: uut0,uut1       ! Zonal wind
95
      real,allocatable, dimension (:)     :: uut0,uut1       ! Zonal wind
85
      real,allocatable, dimension (:)     :: vvt0,vvt1       ! Meridional wind
96
      real,allocatable, dimension (:)     :: vvt0,vvt1       ! Meridional wind
86
      real,allocatable, dimension (:)     :: wwt0,wwt1       ! Vertical wind
97
      real,allocatable, dimension (:)     :: wwt0,wwt1       ! Vertical wind
87
      real,allocatable, dimension (:)     :: p3t0,p3t1       ! 3d-pressure 
98
      real,allocatable, dimension (:)     :: p3t0,p3t1       ! 3d-pressure 
-
 
99
      real,allocatable, dimension (:)     :: tht0,tht1       ! 3d potential temperature
-
 
100
      real,allocatable, dimension (:)     :: sth0,sth1       ! Surface potential temperature
88
 
101
 
89
c     Grid description
102
c     Grid description
90
      real                                   pollon,pollat   ! Longitude/latitude of pole
103
      real                                   pollon,pollat   ! Longitude/latitude of pole
91
      real                                   ak(nlevmax)     ! Vertical layers and levels
104
      real                                   ak(nlevmax)     ! Vertical layers and levels
92
      real                                   bk(nlevmax) 
105
      real                                   bk(nlevmax) 
Line 109... Line 122...
109
      integer                                reftmp(6)
122
      integer                                reftmp(6)
110
      character                              ch
123
      character                              ch
111
      real                                   frac,tload
124
      real                                   frac,tload
112
      integer                                itim
125
      integer                                itim
113
      integer                                wstep
126
      integer                                wstep
114
      real                                   x1,y1
127
      real                                   x1,y1,p1
-
 
128
      real                                   thetamin,thetamax
-
 
129
      real                                   zindexmin,zindexmax
115
 
130
 
116
c     Externals
131
c     Externals
117
      real                                   int_index4
132
      real                                   int_index4
118
      external                               int_index4
133
      external                               int_index4
119
 
134
 
Line 191... Line 206...
191
      read(9,*) reftime(6)                  ! time range (in min)
206
      read(9,*) reftime(6)                  ! time range (in min)
192
 
207
 
193
c     Read flag for 'no time check'
208
c     Read flag for 'no time check'
194
      read(9,*) timecheck
209
      read(9,*) timecheck
195
 
210
 
-
 
211
c     Read flag for isentropic trajectories
-
 
212
      read(9,*) isen, thons
-
 
213
 
-
 
214
c     Read flag for model-level trajectories (2D mode)
-
 
215
      read(9,*) modlev
-
 
216
 
196
c     Close the input file
217
c     Close the input file
197
      close(9)
218
      close(9)
198
 
219
 
199
c     Calculate the number of output time steps
220
c     Calculate the number of output time steps
200
      ntim = abs(reftime(6)/deltout) + 1
221
      ntim = abs(reftime(6)/deltout) + 1
Line 227... Line 248...
227
         print*,'  Input format           : ',inpmode
248
         print*,'  Input format           : ',inpmode
228
      endif
249
      endif
229
      print*,'  Output format          : ',outmode
250
      print*,'  Output format          : ',outmode
230
      print*,'  Periodicity            : ',per
251
      print*,'  Periodicity            : ',per
231
      print*,'  Time check             : ',trim(timecheck)
252
      print*,'  Time check             : ',trim(timecheck)
-
 
253
      print*,'  Isentropic trajectories: ',trim(isen),thons
-
 
254
      print*,'  Model-level trajs (2D) : ',trim(modlev)
232
      print*
255
      print*
233
 
256
 
-
 
257
      if ( (isen.eq.'yes').and.(modlev.eq.'yes') ) then
-
 
258
         print*,
-
 
259
     >    '  WARNING: isentropic and 2D mode chosen -> 2D accepted'
-
 
260
         print*
-
 
261
         isen = 'no'
-
 
262
      endif
-
 
263
 
-
 
264
c     Init missing data value
-
 
265
      mdv = -999.
-
 
266
 
234
      print*,'---- FIXED NUMERICAL PARAMETERS -------------------------'
267
      print*,'---- FIXED NUMERICAL PARAMETERS -------------------------'
235
      print*
268
      print*
236
      print*,'  Numerical scheme       : ',imethod
269
      print*,'  Numerical scheme       : ',imethod
237
      print*,'  Number of iterations   : ',numit
270
      print*,'  Number of iterations   : ',numit
238
      print*,'  Filename prefix        : ',prefix
271
      print*,'  Filename prefix        : ',prefix
Line 292... Line 325...
292
      if (stat.ne.0) print*,'*** error allocating array wwt1 ***'
325
      if (stat.ne.0) print*,'*** error allocating array wwt1 ***'
293
      allocate(p3t0(nx*ny*nz),stat=stat)
326
      allocate(p3t0(nx*ny*nz),stat=stat)
294
      if (stat.ne.0) print*,'*** error allocating array p3t0 ***'   ! Pressure
327
      if (stat.ne.0) print*,'*** error allocating array p3t0 ***'   ! Pressure
295
      allocate(p3t1(nx*ny*nz),stat=stat)
328
      allocate(p3t1(nx*ny*nz),stat=stat)
296
      if (stat.ne.0) print*,'*** error allocating array p3t1 ***'
329
      if (stat.ne.0) print*,'*** error allocating array p3t1 ***'
-
 
330
      allocate(tht0(nx*ny*nz),stat=stat)
-
 
331
      if (stat.ne.0) print*,'*** error allocating array tht0 ***'   ! Potential temperature
-
 
332
      allocate(tht1(nx*ny*nz),stat=stat)
-
 
333
      if (stat.ne.0) print*,'*** error allocating array tht1 ***'
-
 
334
      allocate(sth0(nx*ny),stat=stat)
-
 
335
      if (stat.ne.0) print*,'*** error allocating array spt0 ***'   ! Surface potential temperature
-
 
336
      allocate(sth1(nx*ny),stat=stat)
-
 
337
      if (stat.ne.0) print*,'*** error allocating array sth1 ***'
297
 
338
 
298
C     Get memory for trajectory arrays
339
C     Get memory for trajectory arrays
299
      allocate(trainp(ntra,1,ncol),stat=stat)
340
      allocate(trainp(ntra,1,ncol),stat=stat)
300
      if (stat.ne.0) print*,'*** error allocating array trainp   ***' ! Input start coordinates
341
      if (stat.ne.0) print*,'*** error allocating array trainp   ***' ! Input start coordinates
301
      allocate(traout(ntra,ntim,4),stat=stat)
342
      allocate(traout(ntra,ntim,4),stat=stat)
Line 306... Line 347...
306
      if (stat.ne.0) print*,'*** error allocating array yy0      ***' ! Y position (latitude)
347
      if (stat.ne.0) print*,'*** error allocating array yy0      ***' ! Y position (latitude)
307
      allocate(pp0(ntra),stat=stat)
348
      allocate(pp0(ntra),stat=stat)
308
      if (stat.ne.0) print*,'*** error allocating array pp0      ***' ! Pressure
349
      if (stat.ne.0) print*,'*** error allocating array pp0      ***' ! Pressure
309
      allocate(leftflag(ntra),stat=stat)
350
      allocate(leftflag(ntra),stat=stat)
310
      if (stat.ne.0) print*,'*** error allocating array leftflag ***' ! Leaving-domain flag
351
      if (stat.ne.0) print*,'*** error allocating array leftflag ***' ! Leaving-domain flag
-
 
352
      allocate(theta(ntra),stat=stat)
-
 
353
      if (stat.ne.0) print*,'*** error allocating array theta ***'    ! Potential temperature for isentropic trajectories
-
 
354
      allocate(zindex(ntra),stat=stat)
-
 
355
      if (stat.ne.0) print*,'*** error allocating array kind ***'     ! Vertical index for model-level trajectories
311
 
356
 
312
c     Write some status information
357
c     Write some status information
313
      print*,'---- CONSTANT GRID PARAMETERS ---------------------------'
358
      print*,'---- CONSTANT GRID PARAMETERS ---------------------------'
314
      print*
359
      print*
315
      print*,'  xmin,xmax     : ',xmin,xmax
360
      print*,'  xmin,xmax     : ',xmin,xmax
Line 332... Line 377...
332
          enddo
377
          enddo
333
         close(fid)
378
         close(fid)
334
 
379
 
335
c     Read start coordinates from trajectory file - check consistency of ref time
380
c     Read start coordinates from trajectory file - check consistency of ref time
336
      else
381
      else
337
         print*,'Hallo', ntra,ncol
-
 
338
         call ropen_tra(cdfid,strname,ntra,1,ncol,reftmp,vars,inpmode)
382
         call ropen_tra(cdfid,strname,ntra,1,ncol,reftmp,vars,inpmode)
339
         call read_tra (cdfid,trainp,ntra,1,ncol,inpmode)
383
         call read_tra (cdfid,trainp,ntra,1,ncol,inpmode)
340
         do i=1,ntra
384
         do i=1,ntra
341
            time   = trainp(i,1,1)
385
            time   = trainp(i,1,1)
342
            xx0(i) = trainp(i,1,2) 
386
            xx0(i) = trainp(i,1,2) 
Line 392... Line 436...
392
      call hhmm2frac(tst,frac)
436
      call hhmm2frac(tst,frac)
393
      tst = frac
437
      tst = frac
394
      call hhmm2frac(ten,frac)
438
      call hhmm2frac(ten,frac)
395
      ten = frac
439
      ten = frac
396
 
440
 
397
c     Check that all starting positions are above topography
441
c     Get 3D and surface pressure from first data file 
398
      varname = 'P'
-
 
399
      filename = prefix//dat(1)
442
      filename = prefix//dat(1)
400
      call input_open (fid,filename)
443
      call input_open (fid,filename)
-
 
444
      if ( modlev.eq.'no' ) then 
-
 
445
         varname = 'P'
401
      call input_grid
446
         call input_grid
402
     >    (fid,varname,xmin,xmax,ymin,ymax,dx,dy,nx,ny,
447
     >       (fid,varname,xmin,xmax,ymin,ymax,dx,dy,nx,ny,
403
     >     tload,pollon,pollat,p3t1,spt1,nz,ak,bk,stagz,timecheck)
448
     >        tload,pollon,pollat,p3t1,spt1,nz,ak,bk,stagz,timecheck)
-
 
449
      else  
-
 
450
         varname = 'P.ML'
-
 
451
         call input_grid
-
 
452
     >       (fid,varname,xmin,xmax,ymin,ymax,dx,dy,nx,ny,
-
 
453
     >        tload,pollon,pollat,p3t1,spt1,nz,ak,bk,stagz,timecheck)
-
 
454
      endif
404
      call input_close(fid)
455
      call input_close(fid)
-
 
456
      
-
 
457
c     Check that all starting positions are above topography    
405
      do i=1,ntra
458
      do i=1,ntra
406
 
459
 
407
C       Interpolate surface pressure to actual position (from first input file)
460
C       Interpolate surface pressure to actual position (from first input file)
408
        x1 = xx0(i)
461
        x1 = xx0(i)
409
        y1 = yy0(i)
462
        y1 = yy0(i)
Line 420... Line 473...
420
            leftflag(i) = 1
473
            leftflag(i) = 1
421
        endif
474
        endif
422
 
475
 
423
      enddo
476
      enddo
424
 
477
 
-
 
478
c     Special handling for isentropic trajectories - read potential
-
 
479
c     temperature from S file or calculate it based on temperature and
-
 
480
c     pressure from P file; then, calculate for each trajectory its
-
 
481
c     potential temperature - which will stay fixed over time
-
 
482
      if ( isen.eq.'yes' ) then
-
 
483
 
-
 
484
c         Get potential temperature from S file
-
 
485
          if ( thons.eq.1 ) then
-
 
486
              filename = srefix//dat(1)
-
 
487
              print*,' TH <- ',trim(filename)
-
 
488
              call input_open (fid,filename)
-
 
489
              varname='TH'
-
 
490
              call input_wind
-
 
491
     >            (fid,varname,tht1,tload,stagz,mdv,
-
 
492
     >              xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck)
-
 
493
              call input_close(fid)
-
 
494
 
-
 
495
c         Calculate potential temperature from P file
-
 
496
          else
-
 
497
              filename = prefix//dat(1)
-
 
498
              print*,' TH = T * (1000/P)^RDCP <- ',trim(filename)
-
 
499
              call input_open (fid,filename)
-
 
500
              varname='T'
-
 
501
              call input_wind
-
 
502
     >            (fid,varname,tht1,tload,stagz,mdv,
-
 
503
     >              xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck)
-
 
504
              call input_close(fid)
-
 
505
              do i=1,nx*ny*nz
-
 
506
                if (tht1(i).lt.100.) then
-
 
507
                   tht1(i)=(tht1(i)+tzero)*( (1000./p3t1(i))**rdcp )
-
 
508
                else
-
 
509
                   tht1(i)=tht1(i)*( (1000./p3t1(i))**rdcp )
-
 
510
                endif
-
 
511
              enddo
-
 
512
          endif
-
 
513
 
-
 
514
c         Take surface potential temperature from lowest level
-
 
515
          do i=1,nx*ny
-
 
516
            sth1(i) = tht1(i)
-
 
517
          enddo
-
 
518
 
-
 
519
c         Calculate now the potential temperature of all trajectories
-
 
520
          do i=1,ntra
-
 
521
 
-
 
522
             x1 = xx0(i)
-
 
523
             y1 = yy0(i)
-
 
524
             p1 = pp0(i)
-
 
525
             call get_index4 (xind,yind,pind,x1,y1,p1,0.,
-
 
526
     >                 p3t1,p3t1,spt1,spt1,3,
-
 
527
     >                 nx,ny,nz,xmin,ymin,dx,dy,mdv)
-
 
528
             theta(i) =
-
 
529
     >        int_index4(tht1,tht1,nx,ny,nz,xind,yind,pind,0.,mdv)
-
 
530
 
-
 
531
          enddo
-
 
532
 
-
 
533
c         Write info about theta range of starting positions
-
 
534
          thetamin = theta(1)
-
 
535
          thetamax = theta(1)
-
 
536
          do i=2,ntra
-
 
537
            if ( theta(i).gt.thetamax ) thetamax = theta(i)
-
 
538
            if ( theta(i).lt.thetamin ) thetamin = theta(i)
-
 
539
          enddo
-
 
540
 
-
 
541
c         Write some status information
-
 
542
          print*
-
 
543
          print*,
-
 
544
     >     '---- THETA RANGE OF ISENTROPIC TRAJECTORIES -------------'
-
 
545
          print*
-
 
546
          print*,' Theta(min)             :',thetamin
-
 
547
          print*,' Theta(max)             :',thetamax
-
 
548
 
-
 
549
      endif
-
 
550
 
-
 
551
c     Special handling for model-level (2D) trajectories - get the
-
 
552
c     vertical index for each trajectory - which will remain fixed
-
 
553
      if ( modlev.eq.'yes' ) then
-
 
554
          do i=1,ntra
-
 
555
             x1 = xx0(i)
-
 
556
             y1 = yy0(i)
-
 
557
             p1 = pp0(i)
-
 
558
             call get_index4 (xind,yind,pind,x1,y1,p1,0.,
-
 
559
     >                 p3t1,p3t1,spt1,spt1,3,
-
 
560
     >                 nx,ny,nz,xmin,ymin,dx,dy,mdv)
-
 
561
             zindex(i) = pind
-
 
562
          enddo
-
 
563
 
-
 
564
          do i=1,nz
-
 
565
            print*,i,p3t1(189+(141-1)*nx+(i-1)*nx*ny)
-
 
566
          enddo
-
 
567
             print*,x1,y1,p1
-
 
568
             print*,xind,yind,pind
-
 
569
 
-
 
570
c         Write info about zindex range of starting positions
-
 
571
          zindexmin = zindex(1)
-
 
572
          zindexmax = zindex(1)
-
 
573
          do i=2,ntra
-
 
574
            if ( zindex(i).gt.zindexmax ) zindexmax = zindex(i)
-
 
575
            if ( zindex(i).lt.zindexmin ) zindexmin = zindex(i)
-
 
576
          enddo
-
 
577
 
-
 
578
c         Write some status information
-
 
579
          print*
-
 
580
          print*,
-
 
581
     >     '---- INDEX RANGE OF MODEL-LEVEL TRAJECTORIES ------------'
-
 
582
          print*
-
 
583
          print*,' Zindex(min)            :',zindexmin
-
 
584
          print*,' Zindex(max)            :',zindexmax
-
 
585
 
-
 
586
 
-
 
587
      endif
425
 
588
 
426
c     -----------------------------------------------------------------------
589
c     -----------------------------------------------------------------------
427
c     Loop to calculate trajectories
590
c     Loop to calculate trajectories
428
c     -----------------------------------------------------------------------
591
c     -----------------------------------------------------------------------
429
 
592
 
Line 445... Line 608...
445
c     Read wind fields and vertical grid from first file
608
c     Read wind fields and vertical grid from first file
446
      filename = prefix//dat(1)
609
      filename = prefix//dat(1)
447
 
610
 
448
      call frac2hhmm(tstart,tload)
611
      call frac2hhmm(tstart,tload)
449
 
612
 
450
      write(*,'(a16,a20,f7.2)') '  (file,time) : ',
613
      write(*,'(a16,a20,f9.2)') '  (file,time) : ',
451
     >                       trim(filename),tload
614
     >                       trim(filename),tload
452
 
615
 
453
      call input_open (fid,filename)
616
      call input_open (fid,filename)
-
 
617
 
454
      varname='U'                                      ! U
618
      varname='U'                                      ! U
455
      call input_wind 
619
      call input_wind 
456
     >    (fid,varname,uut1,tload,stagz,mdv,
620
     >    (fid,varname,uut1,tload,stagz,mdv,
457
     >     xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck)
621
     >     xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck)
-
 
622
 
458
      varname='V'                                      ! V
623
      varname='V'                                      ! V
459
      call input_wind 
624
      call input_wind 
460
     >    (fid,varname,vvt1,tload,stagz,mdv,
625
     >    (fid,varname,vvt1,tload,stagz,mdv,
461
     >     xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck)
626
     >     xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck)
-
 
627
 
-
 
628
      if ( (modlev.eq.'no').and.(isen.eq.'no') ) then
462
      varname='OMEGA'                                  ! OMEGA
629
         varname='OMEGA'                                  ! OMEGA
463
      call input_wind 
630
         call input_wind
464
     >    (fid,varname,wwt1,tload,stagz,mdv,
631
     >       (fid,varname,wwt1,tload,stagz,mdv,
465
     >     xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck)      
632
     >        xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck)
-
 
633
      endif
-
 
634
 
-
 
635
      if ( modlev.eq.'no' ) then
466
      call input_grid                                  ! GRID
636
         call input_grid                                  ! GRID - AK,BK -> P
467
     >    (fid,varname,xmin,xmax,ymin,ymax,dx,dy,nx,ny,
637
     >       (fid,varname,xmin,xmax,ymin,ymax,dx,dy,nx,ny,
468
     >     tload,pollon,pollat,p3t1,spt1,nz,ak,bk,stagz,timecheck)
638
     >        tload,pollon,pollat,p3t1,spt1,nz,ak,bk,stagz,timecheck)
-
 
639
      else
-
 
640
         varname='P.ML'                                   ! GRID - P,PS
-
 
641
         call input_grid                                  !
-
 
642
     >       (fid,varname,xmin,xmax,ymin,ymax,dx,dy,nx,ny,
-
 
643
     >        tload,pollon,pollat,p3t1,spt1,nz,ak,bk,stagz,timecheck)
-
 
644
      endif
-
 
645
 
469
      call input_close(fid)
646
      call input_close(fid)
470
          
647
 
-
 
648
c     Special handling for isentropic trajectories - read potential
-
 
649
c     temperature from S file or calculate it based on temperature and
-
 
650
c     pressure from P file
-
 
651
      if ( isen.eq.'yes' ) then
-
 
652
 
-
 
653
c         Get potential temperature from S file
-
 
654
          if ( thons.eq.1 ) then
-
 
655
              filename = srefix//dat(1)
-
 
656
              print*,' TH <- ',trim(filename)
-
 
657
              call input_open (fid,filename)
-
 
658
              varname='TH'
-
 
659
              call input_wind
-
 
660
     >            (fid,varname,tht1,tload,stagz,mdv,
-
 
661
     >              xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck)
-
 
662
              call input_close(fid)
-
 
663
 
-
 
664
c         Calculate potential temperature from P file
-
 
665
          else
-
 
666
              filename = prefix//dat(1)
-
 
667
              print*,' TH = T * (1000/P)^RDCP <- ',trim(filename)
-
 
668
              call input_open (fid,filename)
-
 
669
              varname='T'
-
 
670
              call input_wind
-
 
671
     >            (fid,varname,tht1,tload,stagz,mdv,
-
 
672
     >              xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck)
-
 
673
              call input_close(fid)
-
 
674
              do i=1,nx*ny*nz
-
 
675
                if (tht1(i).lt.100.) then
-
 
676
                   tht1(i)=(tht1(i)+tzero)*( (1000./p3t1(i))**rdcp )
-
 
677
                else
-
 
678
                   tht1(i)=tht1(i)*( (1000./p3t1(i))**rdcp )
-
 
679
                endif
-
 
680
              enddo
-
 
681
          endif
-
 
682
 
-
 
683
c         Take surface potential temperature from lowest level
-
 
684
          do i=1,nx*ny
-
 
685
            sth1(i) = tht1(i)
-
 
686
          enddo
-
 
687
      endif
-
 
688
 
471
c     Loop over all input files (time step is <timeinc>)
689
c     Loop over all input files (time step is <timeinc>)
472
      do itm=1,numdat-1
690
      do itm=1,numdat-1
473
 
691
 
474
c       Calculate actual and next time
692
c       Calculate actual and next time
475
        time0 = tstart+real(itm-1)*timeinc*fbflag
693
        time0 = tstart+real(itm-1)*timeinc*fbflag
Line 479... Line 697...
479
        do i=1,nx*ny*nz
697
        do i=1,nx*ny*nz
480
           uut0(i)=uut1(i)
698
           uut0(i)=uut1(i)
481
           vvt0(i)=vvt1(i)
699
           vvt0(i)=vvt1(i)
482
           wwt0(i)=wwt1(i)
700
           wwt0(i)=wwt1(i)
483
           p3t0(i)=p3t1(i)
701
           p3t0(i)=p3t1(i)
-
 
702
           tht0(i)=tht1(i)
484
        enddo
703
        enddo
485
        do i=1,nx*ny
704
        do i=1,nx*ny
486
           spt0(i)=spt1(i)
705
           spt0(i)=spt1(i)
-
 
706
           sth0(i)=sth1(i)
487
        enddo
707
        enddo
488
 
708
 
489
c       Read wind fields and surface pressure at next time
709
c       Read wind fields and surface pressure at next time
490
        filename = prefix//dat(itm+1)
710
        filename = prefix//dat(itm+1)
491
 
711
 
492
        call frac2hhmm(time1,tload)
712
        call frac2hhmm(time1,tload)
493
        write(*,'(a16,a20,f7.2)') '  (file,time) : ',
713
        write(*,'(a16,a20,f9.2)') '  (file,time) : ',
494
     >                          trim(filename),tload
714
     >                          trim(filename),tload
495
 
715
 
496
        call input_open (fid,filename)
716
        call input_open (fid,filename)
-
 
717
 
497
        varname='U'                                     ! U
718
        varname='U'                                     ! U
498
        call input_wind 
719
        call input_wind 
499
     >       (fid,varname,uut1,tload,stagz,mdv,
720
     >       (fid,varname,uut1,tload,stagz,mdv,
500
     >        xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck)
721
     >        xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck)
-
 
722
 
501
        varname='V'                                     ! V
723
        varname='V'                                     ! V
502
        call input_wind 
724
        call input_wind 
503
     >       (fid,varname,vvt1,tload,stagz,mdv,
725
     >       (fid,varname,vvt1,tload,stagz,mdv,
504
     >        xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck)
726
     >        xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck)
-
 
727
 
-
 
728
        if ( (modlev.eq.'no').and.(isen.eq.'no') ) then
505
        varname='OMEGA'                                ! OMEGA
729
           varname='OMEGA'                              ! OMEGA
506
        call input_wind 
730
           call input_wind
507
     >       (fid,varname,wwt1,tload,stagz,mdv,
731
     >          (fid,varname,wwt1,tload,stagz,mdv,
508
     >        xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck)      
732
     >           xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck)
-
 
733
        endif
-
 
734
 
-
 
735
        if ( modlev.eq.'no' ) then
-
 
736
           call input_grid                                  ! GRID - AK,NK -> P
-
 
737
     >          (fid,varname,xmin,xmax,ymin,ymax,dx,dy,nx,ny,
-
 
738
     >           tload,pollon,pollat,p3t1,spt1,nz,ak,bk,stagz,timecheck)
-
 
739
        else
-
 
740
           varname='P.ML'                                   ! GRID - P,PS
509
        call input_grid                                ! GRID
741
           call input_grid                                  !
510
     >       (fid,varname,xmin,xmax,ymin,ymax,dx,dy,nx,ny,
742
     >       (fid,varname,xmin,xmax,ymin,ymax,dx,dy,nx,ny,
511
     >        tload,pollon,pollat,p3t1,spt1,nz,ak,bk,stagz,timecheck)
743
     >        tload,pollon,pollat,p3t1,spt1,nz,ak,bk,stagz,timecheck)
-
 
744
        endif
-
 
745
 
-
 
746
        call input_close(fid)
-
 
747
 
-
 
748
c     Special handling for isentropic trajectories - read potential
-
 
749
c     temperature from S file or calculate it based on temperature and
-
 
750
c     pressure from P file
-
 
751
      if ( isen.eq.'yes' ) then
-
 
752
 
-
 
753
c         Get TH from S file
-
 
754
          if ( thons.eq.1 ) then
-
 
755
              filename = srefix//dat(itm+1)
-
 
756
              print*,' TH <- ',trim(filename)
-
 
757
              call input_open (fid,filename)
-
 
758
              varname='TH'
-
 
759
              call input_wind
-
 
760
     >            (fid,varname,tht1,tload,stagz,mdv,
-
 
761
     >              xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck)
-
 
762
              call input_close(fid)
-
 
763
 
-
 
764
c         Calculate potential temperature from P file
-
 
765
          else
-
 
766
              filename = prefix//dat(itm+1)
-
 
767
              print*,' TH = T * (1000/P)^RDCP <- ',trim(filename)
-
 
768
              call input_open (fid,filename)
-
 
769
              varname='T'
-
 
770
              call input_wind
-
 
771
     >            (fid,varname,tht1,tload,stagz,mdv,
-
 
772
     >              xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck)
512
        call input_close(fid)
773
              call input_close(fid)
-
 
774
              do i=1,nx*ny*nz
-
 
775
                if (tht1(i).lt.100.) then
-
 
776
                   tht1(i)=(tht1(i)+tzero)*( (1000./p3t1(i))**rdcp )
-
 
777
                else
-
 
778
                   tht1(i)=tht1(i)*( (1000./p3t1(i))**rdcp )
-
 
779
                endif
-
 
780
              enddo
-
 
781
          endif
-
 
782
 
-
 
783
c         Take surface potential temperature from lowest level
-
 
784
          do i=1,nx*ny
-
 
785
            sth1(i) = tht1(i)
-
 
786
          enddo
-
 
787
      endif
513
        
788
        
514
C       Determine the first and last loop indices
789
C       Determine the first and last loop indices
515
        if (numdat.eq.2) then
790
        if (numdat.eq.2) then
516
          filo = nint(tst/ts)+1
791
          filo = nint(tst/ts)+1
517
          lalo = nint((timeinc-ten)/ts) 
792
          lalo = nint((timeinc-ten)/ts) 
Line 537... Line 812...
537
          do i=1,ntra
812
          do i=1,ntra
538
 
813
 
539
C           Check if trajectory has already left the data domain
814
C           Check if trajectory has already left the data domain
540
            if (leftflag(i).ne.1) then	
815
            if (leftflag(i).ne.1) then	
541
 
816
 
542
c             Iterative Euler timestep (x0,y0,p0 -> x1,y1,p1)
817
c             3D: Iterative Euler timestep (x0,y0,p0 -> x1,y1,p1)
543
              if (imethod.eq.1) then
818
              if ( (imethod.eq.1   ).and.
-
 
819
     >             (isen   .eq.'no').and.
-
 
820
     >             (modlev .eq.'no') )
-
 
821
     >        then
544
                 call euler(
822
                 call euler_3d(
545
     >               xx1,yy1,pp1,leftflag(i),
823
     >               xx1,yy1,pp1,leftflag(i),
546
     >               xx0(i),yy0(i),pp0(i),reltpos0,reltpos1,
824
     >               xx0(i),yy0(i),pp0(i),reltpos0,reltpos1,
547
     >               ts*3600,numit,jflag,mdv,wfactor,fbflag,
825
     >               ts*3600,numit,jflag,mdv,wfactor,fbflag,
548
     >               spt0,spt1,p3t0,p3t1,uut0,uut1,vvt0,vvt1,wwt0,wwt1,
826
     >               spt0,spt1,p3t0,p3t1,uut0,uut1,vvt0,vvt1,wwt0,wwt1,
549
     >               xmin,ymin,dx,dy,per,hem,nx,ny,nz)
827
     >               xmin,ymin,dx,dy,per,hem,nx,ny,nz)
550
 
828
 
551
c             Runge-Kutta timestep (x0,y0,p0 -> x1,y1,p1)
829
c             3D: Runge-Kutta timestep (x0,y0,p0 -> x1,y1,p1)
552
              else if (imethod.eq.2) then
830
              else if ( (imethod.eq.2   ).and.
-
 
831
     >                  (isen   .eq.'no').and.
-
 
832
     >                  (modlev .eq.'no') )
-
 
833
     >        then
553
                 call runge(
834
                 call runge(
554
     >               xx1,yy1,pp1,leftflag(i),
835
     >               xx1,yy1,pp1,leftflag(i),
555
     >               xx0(i),yy0(i),pp0(i),reltpos0,reltpos1,
836
     >               xx0(i),yy0(i),pp0(i),reltpos0,reltpos1,
556
     >               ts*3600,numit,jflag,mdv,wfactor,fbflag,
837
     >               ts*3600,numit,jflag,mdv,wfactor,fbflag,
557
     >               spt0,spt1,p3t0,p3t1,uut0,uut1,vvt0,vvt1,wwt0,wwt1,
838
     >               spt0,spt1,p3t0,p3t1,uut0,uut1,vvt0,vvt1,wwt0,wwt1,
558
     >               xmin,ymin,dx,dy,per,hem,nx,ny,nz)
839
     >               xmin,ymin,dx,dy,per,hem,nx,ny,nz)
559
 
840
 
-
 
841
c             ISENTROPIC: Iterative Euler timestep (x0,y0,p0 -> x1,y1,p1)
-
 
842
              else if ( (imethod.eq.1    ).and.
-
 
843
     >                  (isen   .eq.'yes').and.
-
 
844
     >                  (modlev .eq.'no' ) )
-
 
845
     >        then
-
 
846
                 call euler_isen(
-
 
847
     >               xx1,yy1,pp1,leftflag(i),
-
 
848
     >               xx0(i),yy0(i),pp0(i),theta(i),reltpos0,reltpos1,
-
 
849
     >               ts*3600,numit,jflag,mdv,wfactor,fbflag,
-
 
850
     >               spt0,spt1,p3t0,p3t1,uut0,uut1,vvt0,vvt1,
-
 
851
     >               sth0,sth1,tht0,tht1,
-
 
852
     >               xmin,ymin,dx,dy,per,hem,nx,ny,nz)
-
 
853
 
-
 
854
c             MODEL-LEVEL (2D): Iterative Euler timestep (x0,y0,p0 -> x1,y1,p1)
-
 
855
              else if ( (imethod.eq.1    ).and.
-
 
856
     >                  (isen   .eq.'no' ).and.
-
 
857
     >                  (modlev .eq.'yes') )
-
 
858
     >        then
-
 
859
                 call euler_2d(
-
 
860
     >               xx1,yy1,pp1,leftflag(i),
-
 
861
     >               xx0(i),yy0(i),pp0(i),zindex(i),reltpos0,reltpos1,
-
 
862
     >               ts*3600,numit,jflag,mdv,wfactor,fbflag,
-
 
863
     >               spt0,spt1,p3t0,p3t1,uut0,uut1,vvt0,vvt1,
-
 
864
     >               xmin,ymin,dx,dy,per,hem,nx,ny,nz)
-
 
865
 
560
              endif
866
              endif
561
 
867
 
562
c             Update trajectory position, or increase number of trajectories leaving domain
868
c             Update trajectory position, or increase number of trajectories leaving domain
563
              if (leftflag(i).eq.1) then
869
              if (leftflag(i).eq.1) then
564
                leftcount=leftcount+1
870
                leftcount=leftcount+1
Line 603... Line 909...
603
 
909
 
604
        enddo
910
        enddo
605
 
911
 
606
      enddo
912
      enddo
607
 
913
 
608
      print*,(traout(1,1,i),i=1,4)
-
 
609
 
-
 
610
c     Write trajectory file
914
c     Write trajectory file
611
      vars(1)  ='time'
915
      vars(1)  ='time'
612
      vars(2)  ='lon'
916
      vars(2)  ='lon'
613
      vars(3)  ='lat'
917
      vars(3)  ='lat'
614
      vars(4)  ='p'
918
      vars(4)  ='p'
Line 656... Line 960...
656
C     numit	 input	number of iterations
960
C     numit	 input	number of iterations
657
C     jump	 input  flag (=1 trajectories don't enter the ground)
961
C     jump	 input  flag (=1 trajectories don't enter the ground)
658
C     left	 output	flag (=1 if trajectory leaves data domain)
962
C     left	 output	flag (=1 if trajectory leaves data domain)
659
 
963
 
660
c     -------------------------------------------------------------------
964
c     -------------------------------------------------------------------
661
c     Iterative Euler time step
965
c     Iterative Euler time step (KINEMATIC 3D TRAJECTORIES)
662
c     -------------------------------------------------------------------
966
c     -------------------------------------------------------------------
663
 
967
 
664
      subroutine euler(x1,y1,p1,left,x0,y0,p0,reltpos0,reltpos1,
968
      subroutine euler_3d(x1,y1,p1,left,x0,y0,p0,reltpos0,reltpos1,
665
     >                 deltat,numit,jump,mdv,wfactor,fbflag,
969
     >                deltat,numit,jump,mdv,wfactor,fbflag,
666
     >		       spt0,spt1,p3d0,p3d1,uut0,uut1,vvt0,vvt1,wwt0,wwt1,
970
     >		          spt0,spt1,p3d0,p3d1,uut0,uut1,vvt0,vvt1,wwt0,wwt1,
667
     >                 xmin,ymin,dx,dy,per,hem,nx,ny,nz)
971
     >                xmin,ymin,dx,dy,per,hem,nx,ny,nz)
668
 
972
 
669
      implicit none
973
      implicit none
Line 786... Line 1090...
786
C       Check if trajectory leaves data domain
1090
C       Check if trajectory leaves data domain
787
        if ( ( (hem.eq.0).and.(x1.lt.xmin)    ).or.
1091
        if ( ( (hem.eq.0).and.(x1.lt.xmin)    ).or.
788
     >       ( (hem.eq.0).and.(x1.gt.xmax-dx) ).or.
1092
     >       ( (hem.eq.0).and.(x1.gt.xmax-dx) ).or.
789
     >         (y1.lt.ymin).or.(y1.gt.ymax).or.(p1.gt.sp) )
1093
     >         (y1.lt.ymin).or.(y1.gt.ymax).or.(p1.gt.sp) )
790
     >  then
1094
     >  then
-
 
1095
          left=1
-
 
1096
          goto 100
-
 
1097
        endif
-
 
1098
 
-
 
1099
      enddo
-
 
1100
 
-
 
1101
c     Exit point for subroutine
-
 
1102
 100  continue
-
 
1103
 
-
 
1104
      return
-
 
1105
 
-
 
1106
      end
-
 
1107
 
-
 
1108
c     -------------------------------------------------------------------
-
 
1109
c     Iterative Euler time step (ISENTROPIC)
-
 
1110
c     -------------------------------------------------------------------
-
 
1111
 
-
 
1112
      subroutine euler_isen(x1,y1,p1,left,x0,y0,p0,theta,
-
 
1113
     >                reltpos0,reltpos1,
-
 
1114
     >                deltat,numit,jump,mdv,wfactor,fbflag,
-
 
1115
     >                spt0,spt1,p3d0,p3d1,uut0,uut1,vvt0,vvt1,
-
 
1116
     >                sth0,sth1,tht0,tht1,
-
 
1117
     >                xmin,ymin,dx,dy,per,hem,nx,ny,nz)
-
 
1118
 
-
 
1119
      implicit none
-
 
1120
 
-
 
1121
c     Declaration of subroutine parameters
-
 
1122
      integer      nx,ny,nz
-
 
1123
      real         x1,y1,p1
-
 
1124
      integer      left
-
 
1125
      real         x0,y0,p0
-
 
1126
      real         reltpos0,reltpos1
-
 
1127
      real         deltat
-
 
1128
      integer      numit
-
 
1129
      integer      jump
-
 
1130
      real         wfactor
-
 
1131
      integer      fbflag
-
 
1132
      real         spt0(nx*ny)   ,spt1(nx*ny)
-
 
1133
      real         sth0(nx*ny)   ,sth1(nx*ny)
-
 
1134
      real         uut0(nx*ny*nz),uut1(nx*ny*nz)
-
 
1135
      real         vvt0(nx*ny*nz),vvt1(nx*ny*nz)
-
 
1136
      real         p3d0(nx*ny*nz),p3d1(nx*ny*nz)
-
 
1137
      real         tht0(nx*ny*nz),tht1(nx*ny*nz)
-
 
1138
      real         xmin,ymin,dx,dy
-
 
1139
      real         per
-
 
1140
      integer      hem
-
 
1141
      real         mdv
-
 
1142
      real         theta
-
 
1143
 
-
 
1144
c     Numerical and physical constants
-
 
1145
      real         deltay
-
 
1146
      parameter    (deltay=1.112E5)  ! Distance in m between 2 lat circles
-
 
1147
      real         pi
-
 
1148
      parameter    (pi=3.1415927)    ! Pi
-
 
1149
 
-
 
1150
c     Auxiliary variables
-
 
1151
      real         xmax,ymax
-
 
1152
      real         xind,yind,pind
-
 
1153
      real         u0,v0,w0,u1,v1,w1,u,v,w,sp
-
 
1154
      integer      icount
-
 
1155
      character    ch
-
 
1156
 
-
 
1157
c     Externals
-
 
1158
      real         int_index4
-
 
1159
      external     int_index4
-
 
1160
 
-
 
1161
c     Reset the flag for domain-leaving
-
 
1162
      left=0
-
 
1163
 
-
 
1164
c     Set the esat-north bounray of the domain
-
 
1165
      xmax = xmin+real(nx-1)*dx
-
 
1166
      ymax = ymin+real(ny-1)*dy
-
 
1167
 
-
 
1168
C     Interpolate wind fields to starting position (x0,y0,p0)
-
 
1169
      call get_index4 (xind,yind,pind,x0,y0,p0,reltpos0,
-
 
1170
     >                 p3d0,p3d1,spt0,spt1,3,
-
 
1171
     >                 nx,ny,nz,xmin,ymin,dx,dy,mdv)
-
 
1172
      u0 = int_index4(uut0,uut1,nx,ny,nz,xind,yind,pind,reltpos0,mdv)
-
 
1173
      v0 = int_index4(vvt0,vvt1,nx,ny,nz,xind,yind,pind,reltpos0,mdv)
-
 
1174
 
-
 
1175
C     For first iteration take ending position equal to starting position
-
 
1176
      x1=x0
-
 
1177
      y1=y0
-
 
1178
      p1=p0
-
 
1179
 
-
 
1180
C     Iterative calculation of new position
-
 
1181
      do icount=1,numit
-
 
1182
 
-
 
1183
C        Calculate new winds for advection
-
 
1184
         call get_index4 (xind,yind,pind,x1,y1,p1,reltpos1,
-
 
1185
     >                    p3d0,p3d1,spt0,spt1,3,
-
 
1186
     >                    nx,ny,nz,xmin,ymin,dx,dy,mdv)
-
 
1187
         u1 = int_index4(uut0,uut1,nx,ny,nz,xind,yind,pind,reltpos1,mdv)
-
 
1188
         v1 = int_index4(vvt0,vvt1,nx,ny,nz,xind,yind,pind,reltpos1,mdv)
-
 
1189
 
-
 
1190
c        Get the new velocity in between
-
 
1191
         u=(u0+u1)/2.
-
 
1192
         v=(v0+v1)/2.
-
 
1193
 
-
 
1194
C        Calculate new positions
-
 
1195
         x1 = x0 + fbflag*u*deltat/(deltay*cos(y0*pi/180.))
-
 
1196
         y1 = y0 + fbflag*v*deltat/deltay
-
 
1197
 
-
 
1198
c        Get the pressure on the isentropic surface at the new position
-
 
1199
         call get_index4 (xind,yind,pind,x1,y1,theta,reltpos1,
-
 
1200
     >                    tht0,tht1,sth0,sth1,1,
-
 
1201
     >                    nx,ny,nz,xmin,ymin,dx,dy,mdv)
-
 
1202
         p1 = int_index4(p3d0,p3d1,nx,ny,nz,xind,yind,pind,reltpos1,mdv)
-
 
1203
 
-
 
1204
c       Handle pole problems (crossing and near pole trajectory)
-
 
1205
        if ((hem.eq.1).and.(y1.gt.90.)) then
-
 
1206
          y1=180.-y1
-
 
1207
          x1=x1+per/2.
-
 
1208
        endif
-
 
1209
        if ((hem.eq.1).and.(y1.lt.-90.)) then
-
 
1210
          y1=-180.-y1
-
 
1211
          x1=x1+per/2.
-
 
1212
        endif
-
 
1213
        if (y1.gt.89.99) then
-
 
1214
           y1=89.99
-
 
1215
        endif
-
 
1216
 
-
 
1217
c       Handle crossings of the dateline
-
 
1218
        if ((hem.eq.1).and.(x1.gt.xmin+per-dx)) then
-
 
1219
           x1=xmin+amod(x1-xmin,per)
-
 
1220
        endif
-
 
1221
        if ((hem.eq.1).and.(x1.lt.xmin)) then
-
 
1222
           x1=xmin+per+amod(x1-xmin,per)
-
 
1223
        endif
-
 
1224
 
-
 
1225
C       Interpolate surface pressure to actual position
-
 
1226
        call get_index4 (xind,yind,pind,x1,y1,1050.,reltpos1,
-
 
1227
     >                   p3d0,p3d1,spt0,spt1,3,
-
 
1228
     >                   nx,ny,nz,xmin,ymin,dx,dy,mdv)
-
 
1229
        sp = int_index4 (spt0,spt1,nx,ny,1,xind,yind,1.,reltpos1,mdv)
-
 
1230
 
-
 
1231
c       Handle trajectories which cross the lower boundary (jump flag)
-
 
1232
        if ((jump.eq.1).and.(p1.gt.sp)) p1=sp-10.
-
 
1233
 
-
 
1234
C       Check if trajectory leaves data domain
-
 
1235
        if ( ( (hem.eq.0).and.(x1.lt.xmin)    ).or.
-
 
1236
     >       ( (hem.eq.0).and.(x1.gt.xmax-dx) ).or.
-
 
1237
     >         (y1.lt.ymin).or.(y1.gt.ymax).or.(p1.gt.sp) )
-
 
1238
     >  then
-
 
1239
          left=1
-
 
1240
          goto 100
-
 
1241
        endif
-
 
1242
 
-
 
1243
      enddo
-
 
1244
 
-
 
1245
c     Exit point for subroutine
-
 
1246
 100  continue
-
 
1247
 
-
 
1248
      return
-
 
1249
 
-
 
1250
      end
-
 
1251
 
-
 
1252
c     -------------------------------------------------------------------
-
 
1253
c     Iterative Euler time step (MODEL-LEVEL, 2D)
-
 
1254
c     -------------------------------------------------------------------
-
 
1255
 
-
 
1256
      subroutine euler_2d(x1,y1,p1,left,x0,y0,p0,zindex,
-
 
1257
     >                reltpos0,reltpos1,
-
 
1258
     >                deltat,numit,jump,mdv,wfactor,fbflag,
-
 
1259
     >                spt0,spt1,p3d0,p3d1,uut0,uut1,vvt0,vvt1,
-
 
1260
     >                xmin,ymin,dx,dy,per,hem,nx,ny,nz)
-
 
1261
 
-
 
1262
      implicit none
-
 
1263
 
-
 
1264
c     Declaration of subroutine parameters
-
 
1265
      integer      nx,ny,nz
-
 
1266
      real         x1,y1,p1
-
 
1267
      integer      left
-
 
1268
      real         x0,y0,p0
-
 
1269
      real         reltpos0,reltpos1
-
 
1270
      real         deltat
-
 
1271
      integer      numit
-
 
1272
      integer      jump
-
 
1273
      real         wfactor
-
 
1274
      integer      fbflag
-
 
1275
      real         spt0(nx*ny)   ,spt1(nx*ny)
-
 
1276
      real         uut0(nx*ny*nz),uut1(nx*ny*nz)
-
 
1277
      real         vvt0(nx*ny*nz),vvt1(nx*ny*nz)
-
 
1278
      real         p3d0(nx*ny*nz),p3d1(nx*ny*nz)
-
 
1279
      real         xmin,ymin,dx,dy
-
 
1280
      real         per
-
 
1281
      integer      hem
-
 
1282
      real         mdv
-
 
1283
      real         zindex
-
 
1284
 
-
 
1285
c     Numerical and physical constants
-
 
1286
      real         deltay
-
 
1287
      parameter    (deltay=1.112E5)  ! Distance in m between 2 lat circles
-
 
1288
      real         pi
-
 
1289
      parameter    (pi=3.1415927)    ! Pi
-
 
1290
      real         eps
-
 
1291
      parameter    (eps=0.001)
-
 
1292
 
-
 
1293
c     Auxiliary variables
-
 
1294
      real         xmax,ymax
-
 
1295
      real         xind,yind,pind
-
 
1296
      real         u0,v0,w0,u1,v1,w1,u,v,w,sp
-
 
1297
      integer      icount
-
 
1298
      character    ch
-
 
1299
 
-
 
1300
c     Externals
-
 
1301
      real         int_index4
-
 
1302
      external     int_index4
-
 
1303
 
-
 
1304
c     Reset the flag for domain-leaving
-
 
1305
      left=0
-
 
1306
 
-
 
1307
c     Set the esat-north bounray of the domain
-
 
1308
      xmax = xmin+real(nx-1)*dx
-
 
1309
      ymax = ymin+real(ny-1)*dy
-
 
1310
 
-
 
1311
C     Interpolate wind fields to starting position (x0,y0,p0)
-
 
1312
      call get_index4 (xind,yind,pind,x0,y0,p0,reltpos0,
-
 
1313
     >                 p3d0,p3d1,spt0,spt1,3,
-
 
1314
     >                 nx,ny,nz,xmin,ymin,dx,dy,mdv)
-
 
1315
      u0 = int_index4(uut0,uut1,nx,ny,nz,xind,yind,zindex,reltpos0,mdv)
-
 
1316
      v0 = int_index4(vvt0,vvt1,nx,ny,nz,xind,yind,zindex,reltpos0,mdv)
-
 
1317
 
-
 
1318
C     For first iteration take ending position equal to starting position
-
 
1319
      x1=x0
-
 
1320
      y1=y0
-
 
1321
      p1=p0
-
 
1322
 
-
 
1323
C     Iterative calculation of new position
-
 
1324
      do icount=1,numit
-
 
1325
 
-
 
1326
C        Calculate new winds for advection
-
 
1327
         call get_index4 (xind,yind,pind,x1,y1,p1,reltpos1,
-
 
1328
     >                    p3d0,p3d1,spt0,spt1,3,
-
 
1329
     >                    nx,ny,nz,xmin,ymin,dx,dy,mdv)
-
 
1330
         u1=int_index4(uut0,uut1,nx,ny,nz,xind,yind,zindex,reltpos1,mdv)
-
 
1331
         v1=int_index4(vvt0,vvt1,nx,ny,nz,xind,yind,zindex,reltpos1,mdv)
-
 
1332
         if ( abs(u1-mdv).lt.eps ) then
-
 
1333
             left = 1
-
 
1334
             goto 100
-
 
1335
         endif
-
 
1336
         if ( abs(v1-mdv).lt.eps ) then
-
 
1337
             left = 1
-
 
1338
             goto 100
-
 
1339
         endif
-
 
1340
 
-
 
1341
c        Get the new velocity in between
-
 
1342
         u=(u0+u1)/2.
-
 
1343
         v=(v0+v1)/2.
-
 
1344
 
-
 
1345
C        Calculate new positions
-
 
1346
         x1 = x0 + fbflag*u*deltat/(deltay*cos(y0*pi/180.))
-
 
1347
         y1 = y0 + fbflag*v*deltat/deltay
-
 
1348
 
-
 
1349
c        Get the pressure on the model surface at the new position
-
 
1350
         xind = (x1 - xmin ) / dx + 1.
-
 
1351
         yind = (y1 - ymin ) / dy + 1.
-
 
1352
         p1 =
-
 
1353
     >     int_index4(p3d0,p3d1,nx,ny,nz,xind,yind,zindex,reltpos1,mdv)
-
 
1354
         if ( abs(p1-mdv).lt.eps ) then
-
 
1355
             left = 1
-
 
1356
             goto 100
-
 
1357
         endif
-
 
1358
 
-
 
1359
c       Handle pole problems (crossing and near pole trajectory)
-
 
1360
        if ((hem.eq.1).and.(y1.gt.90.)) then
-
 
1361
          y1=180.-y1
-
 
1362
          x1=x1+per/2.
-
 
1363
        endif
-
 
1364
        if ((hem.eq.1).and.(y1.lt.-90.)) then
-
 
1365
          y1=-180.-y1
-
 
1366
          x1=x1+per/2.
-
 
1367
        endif
-
 
1368
        if (y1.gt.89.99) then
-
 
1369
           y1=89.99
-
 
1370
        endif
-
 
1371
 
-
 
1372
c       Handle crossings of the dateline
-
 
1373
        if ((hem.eq.1).and.(x1.gt.xmin+per-dx)) then
-
 
1374
           x1=xmin+amod(x1-xmin,per)
-
 
1375
        endif
-
 
1376
        if ((hem.eq.1).and.(x1.lt.xmin)) then
-
 
1377
           x1=xmin+per+amod(x1-xmin,per)
-
 
1378
        endif
-
 
1379
 
-
 
1380
C       Interpolate surface pressure to actual position
-
 
1381
        call get_index4 (xind,yind,pind,x1,y1,1050.,reltpos1,
-
 
1382
     >                   p3d0,p3d1,spt0,spt1,3,
-
 
1383
     >                   nx,ny,nz,xmin,ymin,dx,dy,mdv)
-
 
1384
        sp = int_index4 (spt0,spt1,nx,ny,1,xind,yind,1.,reltpos1,mdv)
-
 
1385
 
-
 
1386
c       Handle trajectories which cross the lower boundary (jump flag)
-
 
1387
        if ((jump.eq.1).and.(p1.gt.sp)) p1=sp-10.
-
 
1388
 
-
 
1389
C       Check if trajectory leaves data domain
-
 
1390
        if ( ( (hem.eq.0).and.(x1.lt.xmin)    ).or.
-
 
1391
     >       ( (hem.eq.0).and.(x1.gt.xmax-dx) ).or.
-
 
1392
     >         (y1.lt.ymin).or.(y1.gt.ymax).or.(p1.gt.sp) )
-
 
1393
     >  then
791
          left=1
1394
          left=1
792
          goto 100
1395
          goto 100
793
        endif
1396
        endif
794
 
1397
 
795
      enddo
1398
      enddo