Subversion Repositories lagranto.ocean

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3 michaesp 1
      PROGRAM caltra
2
 
3
C     ********************************************************************
4
C     *                                                                  *
5
C     * Calculates trajectories                                          *
6
C     *                                                                  *
7
C     *	Heini Wernli	   first version:	April 1993               *
8
C     * Michael Sprenger   major upgrade:       2008-2009                *
9
C     *                                                                  *
10
C     ********************************************************************
11
 
12
      implicit none
13
 
14
c     --------------------------------------------------------------------
15
c     Declaration of parameters
16
c     --------------------------------------------------------------------
17
 
18
c     Maximum number of levels for input files
19
      integer   nlevmax
20
      parameter	(nlevmax=100)
21
 
22
c     Maximum number of input files (dates, length of trajectories)
23
      integer   ndatmax
24
      parameter	(ndatmax=500)
25
 
26
c     Numerical epsilon (for float comparison)
27
      real      eps
28
      parameter (eps=0.001)
29
 
30
c     Distance in m between 2 lat circles
31
      real	deltay
32
      parameter	(deltay=1.112E5)
33
 
34
c     Numerical method for the integration (0=iterative Euler, 1=Runge-Kutta)
35
      integer   imethod
36
      parameter (imethod=1)
37
 
38
c     Number of iterations for iterative Euler scheme
39
      integer   numit
40
      parameter (numit=3)
41
 
42
c     Input and output format for trajectories (see iotra.f)
43
      integer   inpmode
44
      integer   outmode
45
 
46
c     Filename prefix (typically 'P')
47
      character*1 prefix
48
      parameter   (prefix='P')
49
 
50
c     --------------------------------------------------------------------
51
c     Declaration of variables
52
c     --------------------------------------------------------------------
53
 
54
c     Input parameters
55
      integer                                fbflag          ! Flag for forward/backward mode
56
      integer                                numdat          ! Number of input files
57
      character*11                           dat(ndatmax)    ! Dates of input files
58
      real                                   timeinc         ! Time increment between input files
59
      real                                   per             ! Periodicity (=0 if none)
60
      integer                                ntra            ! Number of trajectories
61
      character*80                           cdfname         ! Name of output files
62
      real                                   ts              ! Time step
63
      real                                   tst,ten         ! Shift of start and end time relative to first data file
64
      integer                                deltout         ! Output time interval (in minutes)
65
      integer                                jflag           ! Jump flag (if =1 ground-touching trajectories reenter atmosphere)
66
      real                                   wfactor         ! Factor for vertical velocity field
67
      character*80                           strname         ! File with start positions
68
      character*80                           timecheck       ! Either 'yes' or 'no'
69
 
70
c     Trajectories
71
      integer                                ncol            ! Number of columns for insput trajectories
72
      real,allocatable, dimension (:,:,:) :: trainp          ! Input start coordinates (ntra,1,ncol)
73
      real,allocatable, dimension (:,:,:) :: traout          ! Output trajectories (ntra,ntim,4)
74
      integer                                reftime(6)      ! Reference date
75
      character*80                           vars(200)       ! Field names
76
      real,allocatable, dimension (:)     :: xx0,yy0,zz0     ! Position of air parcels
77
      integer,allocatable, dimension (:)  :: leftflag        ! Flag for domain-leaving
78
      real                                   xx1,yy1,zz1     ! Updated position of air parcel
79
      integer                                leftcount       ! Number of domain leaving trajectories
80
      integer                                ntim            ! Number of output time steps
81
 
82
c     Meteorological fields
83
      real,allocatable, dimension (:)     :: spt0,spt1       ! Surface pressure
84
      real,allocatable, dimension (:)     :: uut0,uut1       ! Zonal current
85
      real,allocatable, dimension (:)     :: vvt0,vvt1       ! Meridional current
86
      real,allocatable, dimension (:)     :: wwt0,wwt1       ! Vertical current
87
      real,allocatable, dimension (:)     :: topo            ! Bathymetrie
88
      real,allocatable, dimension (:)     :: z,zb            ! 3d / surface height
89
      real,allocatable, dimension (:)     :: dummy2    ! 2d dummy array
90
 
91
 
92
 
93
c     Grid description
94
      real                                   pollon,pollat   ! Longitude/latitude of pole
95
      real                                   xmin,xmax       ! Zonal grid extension
96
      real                                   ymin,ymax       ! Meridional grid extension
97
      integer                                nx,ny,nz        ! Grid dimensions
98
      real                                   dx,dy           ! Horizontal grid resolution
99
      integer                                hem             ! Flag for hemispheric domain
100
      real                                   mdv             ! Missing data value
101
 
102
c     Auxiliary variables
103
      real                                   delta,rd
104
      integer	                             itm,iloop,i,j,k,filo,lalo
105
      integer                                ierr,stat
106
      integer                                cdfid,fid,bid
107
      real	                                 tstart,time0,time1,time
108
      real                                   reltpos0,reltpos1
109
      real                                   xind,yind,zind,pp,sp,stagz
110
      character*80                           filename,varname
111
      integer                                reftmp(6)
112
      character                              ch
113
      real                                   frac,tload
114
      integer                                itim
115
      integer                                wstep
116
      real                                   x1,y1,z1
117
      real                                   tmp1,tmp2
118
 
119
c     Index variables
120
      integer                                c100,c010,c001
121
      integer                                c200,c002,ii
122
      logical                                uflag,vflag
123
 
124
c     Externals
125
      real                                   int_index4
126
      external                               int_index4
127
      real                                   int_index3
128
      external                               int_index3
129
 
130
c     --------------------------------------------------------------------
131
c     Start of program, Read parameters
132
c     --------------------------------------------------------------------
133
 
134
c     Write start message
135
      print*,'========================================================='
136
      print*,'              *** START OF PROGRAM CALTRA ***'
137
      print*
138
 
139
c     Open the parameter file
140
      open(9,file='caltra.param')
141
 
142
c     Read flag for forward/backward mode (fbflag)
143
      read(9,*) fbflag
144
 
145
c     Read number of input files (numdat)
146
      read(9,*) numdat
147
      if (numdat.gt.ndatmax) then
148
        print*,' ERROR: too many input files ',numdat,ndatmax
149
        goto 993
150
      endif
151
 
152
c     Read list of input dates (dat, sort depending on forward/backward mode)
153
      if (fbflag.eq.1) then
154
        do itm=1,numdat
155
          read(9,'(a11)') dat(itm)
156
        enddo
157
      else
158
        do itm=numdat,1,-1
159
          read(9,'(a11)') dat(itm)
160
        enddo
161
      endif
162
 
163
c     Read time increment between input files (timeinc)
164
      read(9,*) timeinc
165
 
166
C     Read if data domain is periodic and its periodicity
167
      read(9,*) per
168
 
169
c     Read the number of trajectories and name of position file
170
      read(9,*) strname
171
      read(9,*) ntra
172
      read(9,*) ncol
173
      if (ntra.eq.0) goto 991
174
 
175
C     Read the name of the output trajectory file and set the constants file
176
      read(9,*) cdfname
177
 
178
C     Read the timestep for trajectory calculation (convert from minutes to hours)
179
      read(9,*) ts
180
      ts=ts/60.
181
 
182
C     Read shift of start and end time relative to first data file
183
      read(9,*) tst
184
      read(9,*) ten
185
 
186
C     Read output time interval (in minutes)
187
      read(9,*) deltout
188
 
189
C     Read jumpflag (if =1 ground-touching trajectories reenter the atmosphere)
190
      read(9,*) jflag
191
 
192
C     Read factor for vertical velocity field
193
      read(9,*) wfactor
194
 
195
c     Read the reference time and the time range
196
      read(9,*) reftime(1)                  ! year
197
      read(9,*) reftime(2)                  ! month
198
      read(9,*) reftime(3)                  ! day
199
      read(9,*) reftime(4)                  ! hour
200
      read(9,*) reftime(5)                  ! min
201
      read(9,*) reftime(6)                  ! time range (in min)
202
 
203
c     Read flag for 'no time check'
204
      read(9,*) timecheck
205
 
206
c     Close the input file
207
      close(9)
208
 
209
c     Calculate the number of output time steps
210
      ntim = abs(reftime(6)/deltout) + 1
211
 
212
c     Set the formats of the input and output files
213
      call mode_tra(inpmode,strname)
214
      call mode_tra(outmode,cdfname)
215
      if (outmode.eq.-1) outmode=1
216
 
217
c     Write some status information
218
      print*,'---- INPUT PARAMETERS -----------------------------------'
219
      print*
220
      print*,'  Forward/Backward       : ',fbflag
221
      print*,'  #input files           : ',numdat
222
      print*,'  First/last input file  : ',trim(dat(1)),' ... ',
223
     >                                     trim(dat(numdat))
224
      print*,'  time increment         : ',timeinc
225
      print*,'  Output file            : ',trim(cdfname)
226
      print*,'  Time step (min)        : ',60.*ts
227
      write(*,'(a27,f7.2,f7.2)') '   Time shift (start,end) : ',tst,ten
228
      print*,'  Output time interval   : ',deltout
229
      print*,'  Jump flag              : ',jflag
230
      print*,'  Vertical current (scale)  : ',wfactor
231
      print*,'  Trajectory pos file    : ',trim(strname)
232
      print*,'  # of trajectories      : ',ntra
233
      print*,'  # of output timesteps  : ',ntim
234
      if ( inpmode.eq.-1) then
235
         print*,'  Input format           : (lon,lat,height)-list'
236
      else
237
         print*,'  Input format           : ',inpmode
238
      endif
239
      print*,'  Output format          : ',outmode
240
      print*,'  Periodicity            : ',per
241
      print*,'  Time check             : ',trim(timecheck)
242
      print*
243
 
244
      print*,'---- FIXED NUMERICAL PARAMETERS -------------------------'
245
      print*
246
      print*,'  Numerical scheme       : ',imethod
247
      print*,'  Number of iterations   : ',numit
248
      print*,'  Filename prefix        : ',prefix
249
      print*,'  Missing data value     : ',mdv
250
      print*
251
 
252
c     --------------------------------------------------------------------
253
c     Read grid parameters, checks and allocate memory
254
c     --------------------------------------------------------------------
255
 
256
c     Read the constant grid parameters (nx,ny,nz,xmin,xmax,ymin,ymax,pollon,pollat)
257
c     The negative <-fid> of the file identifier is used as a flag for parameter retrieval
258
      filename = prefix//dat(1)
259
      varname  = 'U'
260
      nx       = 1
261
      ny       = 1
262
      nz       = 1
263
      tload    = -tst
264
      call input_open (fid,filename)
265
      call input_grid (-fid,varname,xmin,xmax,ymin,ymax,dx,dy,nx,ny,
266
     >                 tload,pollon,pollat,rd,rd,nz,rd,timecheck)
267
      call input_close(fid)
268
 
269
C     Check if the number of levels is too large
270
      if (nz.gt.nlevmax) goto 993
271
 
272
C     Set logical flag for periodic data set (hemispheric or not)
273
      hem = 0
274
      if (per.eq.0.) then
275
         delta=xmax-xmin-360.
276
         if (abs(delta+dx).lt.eps) then               ! Program aborts: arrays must be closed
277
            goto 992
278
        else if (abs(delta).lt.eps) then              ! Periodic and hemispheric
279
           hem=1
280
           per=360.
281
        endif
282
      else                                            ! Periodic and hemispheric
283
         hem=1
284
      endif
285
 
286
C     Allocate memory for some meteorological arrays
287
      allocate(zb(nx*ny),stat=stat)
288
      if (stat.ne.0) print*,'*** error allocating array spt0 ***'   ! Surface height
289
      allocate(uut0(nx*ny*nz),stat=stat)
290
      if (stat.ne.0) print*,'*** error allocating array uut0 ***'   ! Zonal current
291
      allocate(uut1(nx*ny*nz),stat=stat)
292
      if (stat.ne.0) print*,'*** error allocating array uut1 ***'
293
      allocate(vvt0(nx*ny*nz),stat=stat)
294
      if (stat.ne.0) print*,'*** error allocating array vvt0 ***'   ! Meridional current
295
      allocate(vvt1(nx*ny*nz),stat=stat)
296
      if (stat.ne.0) print*,'*** error allocating array vvt1 ***'
297
      allocate(wwt0(nx*ny*nz),stat=stat)
298
      if (stat.ne.0) print*,'*** error allocating array wwt0 ***'   ! Vertical current
299
      allocate(wwt1(nx*ny*nz),stat=stat)
300
      if (stat.ne.0) print*,'*** error allocating array wwt1 ***'
301
      allocate(topo(nx*ny*nz),stat=stat)                             ! Bathymetrie
302
      if (stat.ne.0) print*,'*** error allocating array p3t1 ***'
303
      allocate(z(nx*ny*nz),stat=stat)                                ! 3d height
304
      if (stat.ne.0) print*,'*** error allocating array p3t1 ***'
305
 
306
c     Auxillary
307
      allocate(dummy2(nx*ny),stat=stat)
308
      if (stat.ne.0) print*,'*** error allocating array dummy2 ***'
309
 
310
C     Get memory for trajectory arrays
311
      allocate(trainp(ntra,1,ncol),stat=stat)
312
      if (stat.ne.0) print*,'*** error allocating array trainp   ***' ! Input start coordinates
313
      allocate(traout(ntra,ntim,4),stat=stat)
314
      if (stat.ne.0) print*,'*** error allocating array traout   ***' ! Output trajectories
315
      allocate(xx0(ntra),stat=stat)
316
      if (stat.ne.0) print*,'*** error allocating array xx0      ***' ! X position (longitude)
317
      allocate(yy0(ntra),stat=stat)
318
      if (stat.ne.0) print*,'*** error allocating array yy0      ***' ! Y position (latitude)
319
      allocate(zz0(ntra),stat=stat)
320
      if (stat.ne.0) print*,'*** error allocating array zz0      ***' ! Pressure
321
      allocate(leftflag(ntra),stat=stat)
322
      if (stat.ne.0) print*,'*** error allocating array leftflag ***' ! Leaving-domain flag
323
 
324
c     Write some status information
325
      print*,'---- CONSTANT GRID PARAMETERS ---------------------------'
326
      print*
327
      print*,'  xmin,xmax     : ',xmin,xmax
328
      print*,'  ymin,ymax     : ',ymin,ymax
329
      print*,'  dx,dy         : ',dx,dy
330
      print*,'  pollon,pollat : ',pollon,pollat
331
      print*,'  nx,ny,nz      : ',nx,ny,nz
332
      print*,'  per, hem      : ',per,hem
333
      print*
334
 
335
c     --------------------------------------------------------------------
336
c     Initialize the trajectory calculation
337
c     --------------------------------------------------------------------
338
 
339
c     Read start coordinates from file - Format (lon,lat,lev)
340
      if (inpmode.eq.-1) then
341
         open(fid,file=strname)
342
          do i=1,ntra
343
             read(fid,*) xx0(i),yy0(i),zz0(i)
344
          enddo
345
         close(fid)
346
c     Read start coordinates from trajectory file - check consistency of ref time
347
      else
348
         print*,'Hallo', ntra,ncol
349
         call ropen_tra(cdfid,strname,ntra,1,ncol,reftmp,vars,inpmode)
350
         call read_tra (cdfid,trainp,ntra,1,ncol,inpmode)
351
         do i=1,ntra
352
            time   = trainp(i,1,1)
353
            xx0(i) = trainp(i,1,2)
354
            yy0(i) = trainp(i,1,3)
355
            zz0(i) = trainp(i,1,4)
356
         enddo
357
         call close_tra(cdfid,inpmode)
358
 
359
         if ( ( reftime(1).ne.reftmp(1) ).or.
360
     >        ( reftime(2).ne.reftmp(2) ).or.
361
     >        ( reftime(3).ne.reftmp(3) ).or.
362
     >        ( reftime(4).ne.reftmp(4) ).or.
363
     >        ( reftime(5).ne.reftmp(5) ) )
364
     >   then
365
            print*,' WARNING: Inconsistent reference times'
366
            write(*,'(5i8)') (reftime(i),i=1,5)
367
            write(*,'(5i8)') (reftmp (i),i=1,5)
368
            print*,'Enter a key to proceed...'
369
            stop
370
         endif
371
      endif
372
 
373
c     Set sign of time range
374
      reftime(6) = fbflag * reftime(6)
375
 
376
c     Write some status information
377
      print*,'---- REFERENCE DATE---------- ---------------------------'
378
      print*
379
      print*,' Reference time (year)  :',reftime(1)
380
      print*,'                (month) :',reftime(2)
381
      print*,'                (day)   :',reftime(3)
382
      print*,'                (hour)  :',reftime(4)
383
      print*,'                (min)   :',reftime(5)
384
      print*,' Time range             :',reftime(6),' min'
385
      print*
386
 
387
C     Save starting positions
388
      itim = 1
389
      do i=1,ntra
390
         traout(i,itim,1) = 0.
391
         traout(i,itim,2) = xx0(i)
392
         traout(i,itim,3) = yy0(i)
393
         traout(i,itim,4) = zz0(i)
394
      enddo
395
 
396
c     Init the flag and the counter for trajectories leaving the domain
397
      leftcount=0
398
      do i=1,ntra
399
         leftflag(i)=0
400
      enddo
401
 
402
C     Convert time shifts <tst,ten> from <hh.mm> into fractional time
403
      call hhmm2frac(tst,frac)
404
      tst = frac
405
      call hhmm2frac(ten,frac)
406
      ten = frac
407
 
408
 
409
c     ------- Bathymetrie ---------------------------------------------
410
 
411
      filename='bath'
412
      call input_open(bid,filename)
413
 
414
c     //repeat is a gfortran work around because input assumes len=80
415
      print*," Read bathymetrie: BATH"
416
      varname='BATH'
417
      call input_grid
418
     >     (bid,varname,xmin,xmax,ymin,ymax,dx,dy,nx,ny,
419
     >      0.,pollon,pollat,topo,dummy2,nz,stagz,timecheck)
420
      call input_close(bid)
421
 
422
c     ------- Height----------------------------------------------------
423
 
424
      print*," Read depth: lev"
425
      filename = prefix//dat(1)
426
      call input_open (fid,filename)
427
      varname = 'lev'
428
      call input_grid
429
     >        (fid,varname,xmin,xmax,ymin,ymax,dx,dy,nx,ny,
430
     >        0,pollon,pollat,z,zb,nz,stagz,timecheck)
431
      call input_close(fid)
432
      print*,' zmin,zmax     : ',zb(1),z(nx*ny*nz)
433
 
434
c    -------------------------------------------------------------------
435
 
436
c     Check that all starting positions are above topography
437
c      varname = 'P'
438
c      filename = prefix//dat(1)
439
c      call input_open (fid,filename)
440
c      call input_grid
441
c     >    (fid,varname,xmin,xmax,ymin,ymax,dx,dy,nx,ny,
442
c     >     tload,pollon,pollat,p3t1,spt1,nz,ak,bk,stagz,timecheck)
443
c      call input_close(fid)
444
 
445
 
446
      do i=1,ntra
447
 
448
C       Interpolate heigt to actual position (from first input file)
449
        x1 = xx0(i)
450
        y1 = yy0(i)
451
        z1 = zz0(i)
452
 
453
c        call get_index4 (xind,yind,pind,x1,y1,1050.,0.,
454
c     >                   p3t1,p3t1,spt1,spt1,3,
455
c     >                   nx,ny,nz,xmin,ymin,dx,dy,mdv)
456
c        sp = int_index4 (spt1,spt1,nx,ny,1,xind,yind,1.,0.,mdv)
457
 
458
        call get_index3(xind,yind,zind,x1,y1,z1,3,
459
     >                  z,zb,nx,ny,nz,xmin,ymin,dx,dy)
460
 
461
        tmp1 = int_index3 (topo,nx,ny,nz,xind,yind,zind,mdv)
462
 
463
c       Decide whether to keep the trajectory (vertical check)
464
c        if ( zz0(i).gt.sp ) then
465
         if ( abs(tmp1-1.).lt.eps ) then
466
 
467
            write(*,'(a30,3f10.2)')
468
     >               'WARNING: starting point inside topography ',
469
     >               xx0(i),yy0(i),zz0(i)
470
            leftflag(i) = 1
471
        endif
472
 
473
      enddo
474
 
475
 
476
c     -----------------------------------------------------------------------
477
c     Loop to calculate trajectories
478
c     -----------------------------------------------------------------------
479
 
480
c     Write some status information
481
      print*
482
      print*,'---- TRAJECTORIES ----------- ---------------------------'
483
      print*
484
 
485
C     Set the time for the first data file (depending on forward/backward mode)
486
      if (fbflag.eq.1) then
487
        tstart = -tst
488
      else
489
        tstart = tst
490
      endif
491
 
492
c     Set the minute counter for output
493
      wstep = 0
494
 
495
c     Read current fields and vertical grid from first file
496
      filename = prefix//dat(1)
497
 
498
      call frac2hhmm(tstart,tload)
499
 
500
      write(*,'(a16,a20,f10.2)') '  (file,time) : ',
501
     >                       trim(filename),tload
502
 
503
      call input_open (fid,filename)
504
      varname='U'                                      ! U
505
      call input_wind
506
     >    (fid,varname,uut1,tload,stagz,mdv,
507
     >     xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck)
508
      varname='V'                                      ! V
509
      call input_wind
510
     >    (fid,varname,vvt1,tload,stagz,mdv,
511
     >     xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck)
512
      varname='W'                                      ! W
513
      call input_wind
514
     >    (fid,varname,wwt1,tload,stagz,mdv,
515
     >     xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck)
516
      wwt1=-1.*wwt1                                     ! depth is reversed on file
517
c      call input_grid                                  ! GRID
518
c     >    (fid,varname,xmin,xmax,ymin,ymax,dx,dy,nx,ny,
519
c     >     tload,pollon,pollat,p3t1,spt1,nz,ak,bk,stagz,timecheck)
520
      call input_close(fid)
521
 
522
 
523
 
524
c     ------------------------------------------------------------------
525
c     Boundary conditions
526
c     ------------------------------------------------------------------
527
      print*,' '
528
      print*,'------------ Boundary conditions ---------------------'
529
      print*,'Using no-normal boundary conditions: Un/Vn/Wn set to zero'
530
      print*,'Using no-slip boundary conditions '
531
      print*,'Trajectories leaving the domain are set to: ',mdv
532
 
533
c     -------------------- no-normal flow ----------------------------
534
 
535
       do i=2,nx-1
536
        do j=2,ny-1
537
         do k=2,nz-1
538
 
539
 
540
c         central point
541
          c010=i+(j-1)*nx+(k-1)*nx*ny
542
 
543
c         --- set U to zero if neighbour is land point
544
c         - start with 1 neighbour up to 20 -
545
 
546
 
547
c         U  neighbour U(i+1,j,k)
548
          c001=i-1+(j-1)*nx+(k-1)*nx*ny
549
c         U  neighbour U(i-1,j,k)
550
          c100=i+1+(j-1)*nx+(k-1)*nx*ny
551
 
552
c         if left or right boundary is land (1) set u to zero
553
          if ((topo(c001).gt.0.5).or.(topo(c100).gt.0.5)) then
554
           uut1(c010)=0
555
          end if
556
c         --- set V to zero if neighbour is land point
557
 
558
c         V  neighbour
559
          c001=i+(j-1-ii)*nx+(k-1)*nx*ny
560
 
561
c         V  neighbour
562
          c100=i+(j-1+ii)*nx+(k-1)*nx*ny
563
 
564
          if ((topo(c001).gt.0.5).or.(topo(c100).gt.0.5)) then
565
            vvt1(c010)=0
566
          end if
567
 
568
 
569
c         --- set W to zero if neighbour is land point
570
 
571
c         W  neighbour
572
          c001=i+(j-1)*nx+(k-1-1)*nx*ny
573
 
574
c         W  neighbour
575
          c100=i+(j-1)*nx+(k-1+1)*nx*ny
576
 
577
          if ((topo(c001).gt.0.5).or.(topo(c100).gt.0.5)) wwt1(c010)=0
578
 
579
c     ---------- Set no-slip conditions (zero at land) -----------------
580
c        ghost points are first boundary points
581
c        ghost points are set to negative of u
582
C        this yields zero velocity in between the two points at the wall
583
 
584
c         first bounday points in U direction
585
          c001=i-1+(j-1)*nx+(k-1)*nx*ny
586
          c100=i+1+(j-1)*nx+(k-1)*nx*ny
587
 
588
          if ((topo(c010).gt.0.5).and.((topo(c001).lt.0.5))) then
589
           uut1(c010)=-uut1(c001)
590
          elseif ((topo(c010).gt.0.5).and.((topo(c100).lt.0.5))) then
591
           uut1(c010)=-uut1(c100)
592
          end if
593
 
594
c         first bounday points in V direction
595
          c001=i+(j-1-1)*nx+(k-1)*nx*ny
596
          c100=i+(j-1+1)*nx+(k-1)*nx*ny
597
 
598
          if ((topo(c010).gt.0.5).and.((topo(c001).lt.0.5))) then
599
           vvt1(c010)=-vvt1(c001)
600
          elseif ((topo(c010).gt.0.5).and.((topo(c100).lt.0.5))) then
601
           vvt1(c010)=-vvt1(c100)
602
          end if
603
 
604
c         first bounday points in W direction
605
          c001=i+(j-1)*nx+(k-1-1)*nx*ny
606
          c100=i+(j-1)*nx+(k-1+1)*nx*ny
607
 
608
          if ((topo(c010).gt.0.5).and.((topo(c001).lt.0.5))) then
609
           wwt1(c010)=-wwt1(c001)
610
          elseif ((topo(c010).gt.0.5).and.((topo(c100).lt.0.5))) then
611
           wwt1(c010)=-wwt1(c100)
612
          end if
613
 
614
         end do
615
        end do
616
       end do
617
 
618
c     ------------------------------------------------------------------
619
 
620
 
621
c     Loop over all input files (time step is <timeinc>)
622
      do itm=1,numdat-1
623
 
624
c       Calculate actual and next time
625
        time0 = tstart+real(itm-1)*timeinc*fbflag
626
        time1 = time0+timeinc*fbflag
627
 
628
c       Copy old velocities to new ones
629
        do i=1,nx*ny*nz
630
           uut0(i)=uut1(i)
631
           vvt0(i)=vvt1(i)
632
           wwt0(i)=wwt1(i)
633
        enddo
634
 
635
 
636
c       Read current fields at next time
637
        filename = prefix//dat(itm+1)
638
 
639
        call frac2hhmm(time1,tload)
640
        write(*,'(a16,a20,f10.2)') '  (file,time) : ',
641
     >                          trim(filename),tload
642
 
643
        call input_open (fid,filename)
644
        varname='U'                                     ! U
645
        call input_wind
646
     >       (fid,varname,uut1,tload,stagz,mdv,
647
     >        xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck)
648
        varname='V'                                     ! V
649
        call input_wind
650
     >       (fid,varname,vvt1,tload,stagz,mdv,
651
     >        xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck)
652
        varname='W'                                     ! W
653
        call input_wind
654
     >       (fid,varname,wwt1,tload,stagz,mdv,
655
     >        xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck)
656
        wwt1=-1.*wwt1                                   ! depth is reversed on file
657
c        call input_grid                                ! GRID
658
c     >       (fid,varname,xmin,xmax,ymin,ymax,dx,dy,nx,ny,
659
c     >        tload,pollon,pollat,p3t1,spt1,nz,ak,bk,stagz,timecheck)
660
        call input_close(fid)
661
 
662
c     ------------------------------------------------------------------
663
c     Boundary conditions
664
c     ------------------------------------------------------------------
665
 
666
       do i=2,nx-1
667
        do j=2,ny-1
668
         do k=2,nz-1
669
 
670
 
671
c     ---------- Set component normal to land to zero ------------------
672
 
673
c         central point
674
          c010=i+(j-1)*nx+(k-1)*nx*ny
675
 
676
c         U  neighbour U(i+1,j,k)
677
          c001=i-1+(j-1)*nx+(k-1)*nx*ny
678
c         U  neighbour U(i-1,j,k)
679
          c100=i+1+(j-1)*nx+(k-1)*nx*ny
680
 
681
c         if left or right boundary is land (1) set u to zero
682
          if ((topo(c001).gt.0.5).or.(topo(c100).gt.0.5)) then
683
           uut1(c010)=0
684
          end if
685
c         --- set V to zero if neighbour is land point
686
 
687
c         V  neighbour
688
          c001=i+(j-1-1)*nx+(k-1)*nx*ny
689
 
690
c         V  neighbour
691
          c100=i+(j-1+1)*nx+(k-1)*nx*ny
692
 
693
          if ((topo(c001).gt.0.5).or.(topo(c100).gt.0.5)) then
694
            vvt1(c010)=0
695
          end if
696
 
697
 
698
c         --- set W to zero if neighbour is land point
699
 
700
c         W  neighbour
701
          c001=i+(j-1)*nx+(k-1-1)*nx*ny
702
 
703
c         W  neighbour
704
          c100=i+(j-1)*nx+(k-1+1)*nx*ny
705
 
706
          if ((topo(c001).gt.0.5).or.(topo(c100).gt.0.5)) wwt1(c010)=0
707
 
708
c     ---------- Set no-slip conditions (zero at land) -----------------
709
c        ghost points are first boundary points
710
c        ghost points are set to negative of u
711
c        this yields zero velocity in between the two points at the wall
712
 
713
c         first bounday point in U direction
714
          c001=i-1+(j-1)*nx+(k-1)*nx*ny
715
          c100=i+1+(j-1)*nx+(k-1)*nx*ny
716
 
717
          if ((topo(c010).gt.0.5).and.((topo(c001).lt.0.5))) then
718
           uut1(c010)=-uut1(c001)
719
          elseif ((topo(c010).gt.0.5).and.((topo(c100).lt.0.5))) then
720
           uut1(c010)=-uut1(c100)
721
          end if
722
 
723
c         first bounday point in V direction
724
          c001=i+(j-1-1)*nx+(k-1)*nx*ny
725
          c100=i+(j-1+1)*nx+(k-1)*nx*ny
726
 
727
          if ((topo(c010).gt.0.5).and.((topo(c001).lt.0.5))) then
728
           vvt1(c010)=-vvt1(c001)
729
          elseif ((topo(c010).gt.0.5).and.((topo(c100).lt.0.5))) then
730
           vvt1(c010)=-vvt1(c100)
731
          end if
732
 
733
c         first bounday point in W direction
734
          c001=i+(j-1)*nx+(k-1-1)*nx*ny
735
          c100=i+(j-1)*nx+(k-1+1)*nx*ny
736
 
737
          if ((topo(c010).gt.0.5).and.((topo(c001).lt.0.5))) then
738
           wwt1(c010)=-wwt1(c001)
739
          elseif ((topo(c010).gt.0.5).and.((topo(c100).lt.0.5))) then
740
           wwt1(c010)=-wwt1(c100)
741
          end if
742
 
743
 
744
         end do
745
        end do
746
       end do
747
 
748
 
749
c     ------------------------------------------------------------------
750
 
751
 
752
C       Determine the first and last loop indices
753
        if (numdat.eq.2) then
754
          filo = nint(tst/ts)+1
755
          lalo = nint((timeinc-ten)/ts)
756
        elseif ( itm.eq.1 ) then
757
          filo = nint(tst/ts)+1
758
          lalo = nint(timeinc/ts)
759
        else if (itm.eq.numdat-1) then
760
          filo = 1
761
          lalo = nint((timeinc-ten)/ts)
762
        else
763
          filo = 1
764
          lalo = nint(timeinc/ts)
765
        endif
766
 
767
c       Split the interval <timeinc> into computational time steps <ts>
768
        do iloop=filo,lalo
769
 
770
C         Calculate relative time position in the interval timeinc (0=beginning, 1=end)
771
          reltpos0 = ((real(iloop)-1.)*ts)/timeinc
772
          reltpos1 = real(iloop)*ts/timeinc
773
 
774
c         Timestep for all trajectories
775
          do i=1,ntra
776
 
777
C           Check if trajectory has already left the data domain
778
            if (leftflag(i).ne.1) then
779
 
780
c             Iterative Euler timestep (x0,y0,p0 -> x1,y1,p1)
781
              if (imethod.eq.1) then
782
                 call euler(
783
     >               xx1,yy1,zz1,leftflag(i),
784
     >               xx0(i),yy0(i),zz0(i),reltpos0,reltpos1,
785
     >               ts*3600,numit,jflag,mdv,wfactor,fbflag,
786
     >               zb,zb,z,z,uut0,uut1,vvt0,vvt1,wwt0,wwt1,
787
     >               xmin,ymin,dx,dy,per,hem,nx,ny,nz,topo)
788
 
789
c             Runge-Kutta timestep (x0,y0,p0 -> x1,y1,p1)
790
              else if (imethod.eq.2) then
791
                 call runge(
792
     >               xx1,yy1,zz1,leftflag(i),
793
     >               xx0(i),yy0(i),zz0(i),reltpos0,reltpos1,
794
     >               ts*3600,numit,jflag,mdv,wfactor,fbflag,
795
     >               zb,zb,z,z,uut0,uut1,vvt0,vvt1,wwt0,wwt1,
796
     >               xmin,ymin,dx,dy,per,hem,nx,ny,nz)
797
 
798
              endif
799
 
800
 
801
c             Update trajectory position, or increase number of trajectories leaving domain
802
              if (leftflag(i).eq.1) then
803
                leftcount=leftcount+1
804
                if ( leftcount.lt.10 ) then
805
                   print*,'     -> Trajectory ',i,' leaves domain at:'
806
                   print*,' ',xx1,', ',yy1,', ',zz1
807
 
808
                elseif ( leftcount.eq.10 ) then
809
                   print*,'     -> N>=10 trajectories leave domain'
810
                endif
811
              else
812
                xx0(i)=xx1
813
                yy0(i)=yy1
814
                zz0(i)=zz1
815
              endif
816
 
817
c          Trajectory has already left data domain (mark as <mdv>)
818
           else
819
              xx0(i)=mdv
820
              yy0(i)=mdv
821
              zz0(i)=mdv
822
 
823
           endif
824
 
825
          enddo
826
 
827
C         Save positions only every deltout minutes
828
          delta = aint(iloop*60*ts/deltout)-iloop*60*ts/deltout
829
          if (abs(delta).lt.eps) then
830
c          wstep = wstep + abs(ts)
831
c          if ( mod(wstep,deltout).eq.0 ) then
832
            time = time0+reltpos1*timeinc*fbflag
833
            itim = itim + 1
834
            if ( itim.le.ntim ) then
835
              do i=1,ntra
836
                 call frac2hhmm(time,tload)
837
                 traout(i,itim,1) = tload
838
                 traout(i,itim,2) = xx0(i)
839
                 traout(i,itim,3) = yy0(i)
840
                 traout(i,itim,4) = zz0(i)
841
              enddo
842
            endif
843
          endif
844
 
845
        enddo
846
 
847
      enddo
848
 
849
      print*,(traout(1,1,i),i=1,4)
850
 
851
c     Write trajectory file
852
      vars(1)  ='time'
853
      vars(2)  ='lon'
854
      vars(3)  ='lat'
855
      vars(4)  ='depth'
856
      call wopen_tra(cdfid,cdfname,ntra,ntim,4,reftime,vars,outmode)
857
      call write_tra(cdfid,traout,ntra,ntim,4,outmode)
858
      call close_tra(cdfid,outmode)
859
 
860
c     Write some status information, and end of program message
861
      print*
862
      print*,'---- STATUS INFORMATION --------------------------------'
863
      print*
864
      print*,'  #leaving domain    ', leftcount
865
      print*,'  #staying in domain ', ntra-leftcount
866
      print*
867
      print*,'              *** END OF PROGRAM CALTRA ***'
868
      print*,'========================================================='
869
 
870
      stop
871
 
872
c     ------------------------------------------------------------------
873
c     Exception handling
874
c     ------------------------------------------------------------------
875
 
876
 991  write(*,*) '*** ERROR: all start points outside the data domain'
877
      call exit(1)
878
 
879
 992  write(*,*) '*** ERROR: close arrays on files (prog. closear)'
880
      call exit(1)
881
 
882
 993  write(*,*) '*** ERROR: problems with array size'
883
      call exit(1)
884
 
885
      end
886
 
887
 
888
c     *******************************************************************
889
c     * Time step : either Euler or Runge-Kutta                         *
890
c     *******************************************************************
891
 
892
C     Time-step from (x0,y0,z0) to (x1,y1,z1)
893
C
894
C     (x0,y0,z0) input	coordinates (long,lat,z) for starting point
895
C     (x1,y1,z1) output	coordinates (long,lat,z) for end point
896
C     deltat	 input	timestep in seconds
897
C     numit	 input	number of iterations
898
C     jump	 input  flag (=1 trajectories don't enter the ground)
899
C     left	 output	flag (=1 if trajectory leaves data domain)
900
 
901
c     -------------------------------------------------------------------
902
c     Iterative Euler time step
903
c     -------------------------------------------------------------------
904
 
905
      subroutine euler(x1,y1,z1,left,x0,y0,z0,reltpos0,reltpos1,
906
     >                 deltat,numit,jump,mdv,wfactor,fbflag,
907
     >		       zbt0,zbt1,zt0,zt1,uut0,uut1,vvt0,vvt1,wwt0,wwt1,
908
     >                 xmin,ymin,dx,dy,per,hem,nx,ny,nz,topo)
909
 
910
      implicit none
911
 
912
c     Declaration of subroutine parameters
913
      integer      nx,ny,nz
914
      real         x1,y1,z1
915
      integer      left
916
      real	       x0,y0,z0
917
      real         reltpos0,reltpos1
918
      real   	   deltat
919
      integer      numit
920
      integer      jump
921
      real         wfactor
922
      integer      fbflag
923
      real     	   zbt0(nx*ny)   ,zbt1(nx*ny)
924
      real         uut0(nx*ny*nz),uut1(nx*ny*nz)
925
      real 	       vvt0(nx*ny*nz),vvt1(nx*ny*nz)
926
      real         wwt0(nx*ny*nz),wwt1(nx*ny*nz)
927
      real         zt0(nx*ny*nz),zt1(nx*ny*nz)
928
      real         topo(nx*ny*nz)
929
      real         xmin,ymin,dx,dy
930
      real         per
931
      integer      hem
932
      real         mdv
933
      real         tmp1
934
 
935
c     Numerical and physical constants
936
      real         deltay
937
      parameter    (deltay=1.112E5)  ! Distance in m between 2 lat circles
938
      real         pi
939
      parameter    (pi=3.1415927)    ! Pi
940
 
941
c     Auxiliary variables
942
      real         xmax,ymax
943
      real	       xind,yind,zind
944
      real	       u0,v0,w0,u1,v1,w1,u,v,w,sp
945
      integer	   icount
946
      character    ch
947
 
948
c     Externals
949
      real         int_index4
950
      external     int_index4
951
      real         int_index3
952
      external     int_index3
953
 
954
c     Reset the flag for domain-leaving
955
      left=0
956
 
957
c     Set the esat-north bounray of the domain
958
      xmax = xmin+real(nx-1)*dx
959
      ymax = ymin+real(ny-1)*dy
960
 
961
C     Interpolate current fields to starting position (x0,y0,z0)
962
      call get_index4 (xind,yind,zind,x0,y0,z0,reltpos0,
963
     >                 zt0,zt1,zbt0,zbt1,3,
964
     >                 nx,ny,nz,xmin,ymin,dx,dy,mdv)
965
      u0 = int_index4(uut0,uut1,nx,ny,nz,xind,yind,zind,reltpos0,mdv)
966
      v0 = int_index4(vvt0,vvt1,nx,ny,nz,xind,yind,zind,reltpos0,mdv)
967
C     w is reversed to fit depth coordinate, hence mdv is reversed here
968
      w0 = int_index4(wwt0,wwt1,nx,ny,nz,xind,yind,zind,reltpos0,-1*mdv)
969
 
970
c     Force the near-surface current to no slip conditions
971
      if (zind.lt.1.) w0=w0*((zind-0.5)/0.5)
972
 
973
C     For first iteration take ending position equal to starting position
974
      x1=x0
975
      y1=y0
976
      z1=z0
977
 
978
C     Iterative calculation of new position
979
      do icount=1,numit
980
 
981
C        Calculate new currents for advection
982
         call get_index4 (xind,yind,zind,x1,y1,z1,reltpos1,
983
     >                    zt0,zt1,zbt0,zbt1,3,
984
     >                    nx,ny,nz,xmin,ymin,dx,dy,mdv)
985
       u1= int_index4(uut0,uut1,nx,ny,nz,xind,yind,zind,reltpos1,mdv)
986
       v1= int_index4(vvt0,vvt1,nx,ny,nz,xind,yind,zind,reltpos1,mdv)
987
       w1= int_index4(wwt0,wwt1,nx,ny,nz,xind,yind,zind,reltpos1,-1*mdv)
988
 
989
 
990
c        Force the near-surface current to no-slip condition
991
         if (zind.lt.1.) w1=w1*((zind-0.5)/0.5)
992
 
993
 
994
c        Get the new velocity in between
995
         u=(u0+u1)/2.
996
         v=(v0+v1)/2.
997
         w=(w0+w1)/2.
998
 
999
C        Calculate new positions
1000
         x1 = x0 + fbflag*u*deltat/(deltay*cos(y0*pi/180.))
1001
         y1 = y0 + fbflag*v*deltat/deltay
1002
         z1 = z0 + fbflag*wfactor*w*deltat
1003
 
1004
c       Handle pole problems (crossing and near pole trajectory)
1005
        if ((hem.eq.1).and.(y1.gt.90.)) then
1006
          y1=180.-y1
1007
          x1=x1+per/2.
1008
        endif
1009
        if ((hem.eq.1).and.(y1.lt.-90.)) then
1010
          y1=-180.-y1
1011
          x1=x1+per/2.
1012
        endif
1013
        if (y1.gt.89.99) then
1014
           y1=89.99
1015
        endif
1016
 
1017
c       Handle crossings of the dateline
1018
        if ((hem.eq.1).and.(x1.gt.xmin+per-dx)) then
1019
           x1=xmin+amod(x1-xmin,per)
1020
        endif
1021
        if ((hem.eq.1).and.(x1.lt.xmin)) then
1022
           x1=xmin+per+amod(x1-xmin,per)
1023
        endif
1024
 
1025
C       Interpolate surface height to actual position
1026
        call get_index4 (xind,yind,zind,x1,y1,0.,reltpos1,
1027
     >                   zt0,zt1,zbt0,zbt1,3,
1028
     >                   nx,ny,nz,xmin,ymin,dx,dy,mdv)
1029
        sp = int_index4 (zbt0,zbt1,nx,ny,1,xind,yind,1.,reltpos1,mdv)
1030
 
1031
c       Handle trajectories which cross the lower boundary (jump flag +0.1m)
1032
        if ((jump.eq.1).and.(z1.lt.sp)) z1=sp+0.1
1033
 
1034
C       Check if trajectory leaves data domain
1035
        if ( ( (hem.eq.0).and.(x1.lt.xmin)    ).or.
1036
     >       ( (hem.eq.0).and.(x1.gt.xmax-dx) ).or.
1037
     >         (y1.lt.ymin).or.(y1.gt.ymax).or.(z1.lt.sp) )
1038
     >  then
1039
          left=1
1040
          goto 100
1041
        endif
1042
 
1043
c       Check if trajectory hits topograpy (1=land/0=ocean)
1044
        if ( left/=1 ) then
1045
         call get_index3(xind,yind,zind,x1,y1,
1046
     >            z1,3,zt0,zbt0,nx,ny,nz,xmin,ymin,dx,dy)
1047
 
1048
         tmp1 = int_index3 (topo,nx,ny,nz,xind,yind,zind,mdv)
1049
 
1050
         if ( tmp1.gt.0.5 ) then
1051
            left=1
1052
            goto 100
1053
         endif
1054
 
1055
        endif
1056
 
1057
      enddo
1058
 
1059
c     Exit point for subroutine
1060
 100  continue
1061
 
1062
      return
1063
 
1064
      end
1065
 
1066
c     -------------------------------------------------------------------
1067
c     Runge-Kutta (4th order) time-step
1068
c     -------------------------------------------------------------------
1069
 
1070
      subroutine runge(x1,y1,p1,left,x0,y0,p0,reltpos0,reltpos1,
1071
     >                 deltat,numit,jump,mdv,wfactor,fbflag,
1072
     >		       spt0,spt1,p3d0,p3d1,uut0,uut1,vvt0,vvt1,wwt0,wwt1,
1073
     >                 xmin,ymin,dx,dy,per,hem,nx,ny,nz)
1074
 
1075
      implicit none
1076
 
1077
c     Declaration of subroutine parameters
1078
      integer      nx,ny,nz
1079
      real         x1,y1,p1
1080
      integer      left
1081
      real	   x0,y0,p0
1082
      real         reltpos0,reltpos1
1083
      real   	   deltat
1084
      integer      numit
1085
      integer      jump
1086
      real         wfactor
1087
      integer      fbflag
1088
      real     	   spt0(nx*ny)   ,spt1(nx*ny)
1089
      real         uut0(nx*ny*nz),uut1(nx*ny*nz)
1090
      real 	   vvt0(nx*ny*nz),vvt1(nx*ny*nz)
1091
      real         wwt0(nx*ny*nz),wwt1(nx*ny*nz)
1092
      real         p3d0(nx*ny*nz),p3d1(nx*ny*nz)
1093
      real         xmin,ymin,dx,dy
1094
      real         per
1095
      integer      hem
1096
      real         mdv
1097
 
1098
c     Numerical and physical constants
1099
      real         deltay
1100
      parameter    (deltay=1.112E5)  ! Distance in m between 2 lat circles
1101
      real         pi
1102
      parameter    (pi=3.1415927)    ! Pi
1103
 
1104
c     Auxiliary variables
1105
      real         xmax,ymax
1106
      real	   xind,yind,zind
1107
      real	   u0,v0,w0,u1,v1,w1,u,v,w,sp
1108
      integer	   icount,n
1109
      real         xs,ys,ps,xk(4),yk(4),pk(4)
1110
      real         reltpos
1111
 
1112
c     Externals
1113
      real         int_index4
1114
      external     int_index4
1115
 
1116
c     Reset the flag for domain-leaving
1117
      left=0
1118
 
1119
c     Set the esat-north bounray of the domain
1120
      xmax = xmin+real(nx-1)*dx
1121
      ymax = ymin+real(ny-1)*dy
1122
 
1123
c     Apply the Runge Kutta scheme
1124
      do n=1,4
1125
 
1126
c       Get intermediate position and relative time
1127
        if (n.eq.1) then
1128
          xs=0.
1129
          ys=0.
1130
          ps=0.
1131
          reltpos=reltpos0
1132
        else if (n.eq.4) then
1133
          xs=xk(3)
1134
          ys=yk(3)
1135
          ps=pk(3)
1136
          reltpos=reltpos1
1137
        else
1138
          xs=xk(n-1)/2.
1139
          ys=yk(n-1)/2.
1140
          ps=pk(n-1)/2.
1141
          reltpos=(reltpos0+reltpos1)/2.
1142
        endif
1143
 
1144
C       Calculate new currents for advection
1145
        call get_index4 (xind,yind,zind,x0+xs,y0+ys,p0+ps,reltpos,
1146
     >                   p3d0,p3d1,spt0,spt1,3,
1147
     >                   nx,ny,nz,xmin,ymin,dx,dy,mdv)
1148
        u = int_index4 (uut0,uut1,nx,ny,nz,xind,yind,zind,reltpos,mdv)
1149
        v = int_index4 (vvt0,vvt1,nx,ny,nz,xind,yind,zind,reltpos,mdv)
1150
        w = int_index4 (wwt0,wwt1,nx,ny,nz,xind,yind,zind,reltpos,mdv)
1151
 
1152
c       Force the near-surface current to zero
1153
        if (zind.lt.1.) w1=w1*zind
1154
 
1155
c       Update position and keep them
1156
        xk(n)=fbflag*u*deltat/(deltay*cos(y0*pi/180.))
1157
        yk(n)=fbflag*v*deltat/deltay
1158
        pk(n)=fbflag*w*deltat*wfactor/100.
1159
 
1160
      enddo
1161
 
1162
C     Calculate new positions
1163
      x1=x0+(1./6.)*(xk(1)+2.*xk(2)+2.*xk(3)+xk(4))
1164
      y1=y0+(1./6.)*(yk(1)+2.*yk(2)+2.*yk(3)+yk(4))
1165
      p1=p0+(1./6.)*(pk(1)+2.*pk(2)+2.*pk(3)+pk(4))
1166
 
1167
c     Handle pole problems (crossing and near pole trajectory)
1168
      if ((hem.eq.1).and.(y1.gt.90.)) then
1169
         y1=180.-y1
1170
         x1=x1+per/2.
1171
      endif
1172
      if ((hem.eq.1).and.(y1.lt.-90.)) then
1173
         y1=-180.-y1
1174
         x1=x1+per/2.
1175
      endif
1176
      if (y1.gt.89.99) then
1177
         y1=89.99
1178
      endif
1179
 
1180
c     Handle crossings of the dateline
1181
      if ((hem.eq.1).and.(x1.gt.xmin+per-dx)) then
1182
         x1=xmin+amod(x1-xmin,per)
1183
      endif
1184
      if ((hem.eq.1).and.(x1.lt.xmin)) then
1185
         x1=xmin+per+amod(x1-xmin,per)
1186
      endif
1187
 
1188
cC     Interpolate surface pressure to actual position
1189
      call get_index4 (xind,yind,zind,x1,y1,1050.,reltpos1,
1190
     >                 p3d0,p3d1,spt0,spt1,3,
1191
     >                 nx,ny,nz,xmin,ymin,dx,dy,mdv)
1192
      sp = int_index4 (spt0,spt1,nx,ny,1,xind,yind,1,reltpos,mdv)
1193
 
1194
c     Handle trajectories which cross the lower boundary (jump flag)
1195
      if ((jump.eq.1).and.(p1.gt.sp)) p1=sp-10.
1196
 
1197
C     Check if trajectory leaves data domain
1198
      if ( ( (hem.eq.0).and.(x1.lt.xmin)    ).or.
1199
     >     ( (hem.eq.0).and.(x1.gt.xmax-dx) ).or.
1200
     >       (y1.lt.ymin).or.(y1.gt.ymax).or.(p1.gt.sp) )
1201
     >then
1202
         left=1
1203
         goto 100
1204
      endif
1205
 
1206
c     Exit point fdor subroutine
1207
 100  continue
1208
 
1209
      return
1210
      end