Subversion Repositories lagranto.ecmwf

Rev

Rev 9 | Rev 19 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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