Subversion Repositories lagranto.ecmwf

Rev

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

Rev 13 Rev 19
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 for primary and secondary files (typically 'P' and 'S')
47
      character*1 prefix
47
      character*1 prefix
48
      parameter   (prefix='P')
48
      parameter   (prefix='P')
-
 
49
      character*1 srefix
-
 
50
      parameter   (srefix='S')
-
 
51
 
-
 
52
c     Physical constants - needed to compute potential temperature
-
 
53
      real      rdcp,tzero
-
 
54
      data      rdcp,tzero /0.286,273.15/
49
 
55
 
50
c     --------------------------------------------------------------------
56
c     --------------------------------------------------------------------
51
c     Declaration of variables
57
c     Declaration of variables
52
c     --------------------------------------------------------------------
58
c     --------------------------------------------------------------------
53
 
59
 
54
c     Input parameters
60
c     Input parameters
55
      integer                                fbflag          ! Flag for forward/backward mode
61
      integer                                fbflag          ! Flag for forward/backward mode
56
      integer                                numdat          ! Number of input files
62
      integer                                numdat          ! Number of input files
57
      character*11                           dat(ndatmax)    ! Dates of input files
63
      character*11                           dat(ndatmax)    ! Dates of input files
58
      real                                   timeinc         ! Time increment between input files
64
      real                                   timeinc         ! Time increment between input files
59
      real                                   per             ! Periodicity (=0 if none)
65
      real                                   per             ! Periodicity (=0 if none)
60
      integer                                ntra            ! Number of trajectories
66
      integer                                ntra            ! Number of trajectories
61
      character*80                           cdfname         ! Name of output files
67
      character*80                           cdfname         ! Name of output files
62
      real                                   ts              ! Time step
68
      real                                   ts              ! Time step
63
      real                                   tst,ten         ! Shift of start and end time relative to first data file
69
      real                                   tst,ten         ! Shift of start and end time relative to first data file
64
      integer                                deltout         ! Output time interval (in minutes)
70
      integer                                deltout         ! Output time interval (in minutes)
65
      integer                                jflag           ! Jump flag (if =1 ground-touching trajectories reenter atmosphere)
71
      integer                                jflag           ! Jump flag (if =1 ground-touching trajectories reenter atmosphere)
66
      real                                   wfactor         ! Factor for vertical velocity field
72
      real                                   wfactor         ! Factor for vertical velocity field
67
      character*80                           strname         ! File with start positions
73
      character*80                           strname         ! File with start positions
68
      character*80                           timecheck       ! Either 'yes' or 'no'
74
      character*80                           timecheck       ! Either 'yes' or 'no'
-
 
75
      character*80                           isen            ! Isentropic trajectories ('yes' or 'no')
-
 
76
      integer                                thons           ! Isentropic mode: is TH availanle on S
-
 
77
      character*80                           modlev          ! 2D (model level) trajectories ('yes' or 'no')
69
 
78
 
70
c     Trajectories
79
c     Trajectories
71
      integer                                ncol            ! Number of columns for insput trajectories
80
      integer                                ncol            ! Number of columns for insput trajectories
72
      real,allocatable, dimension (:,:,:) :: trainp          ! Input start coordinates (ntra,1,ncol)
81
      real,allocatable, dimension (:,:,:) :: trainp          ! Input start coordinates (ntra,1,ncol)
73
      real,allocatable, dimension (:,:,:) :: traout          ! Output trajectories (ntra,ntim,4)
82
      real,allocatable, dimension (:,:,:) :: traout          ! Output trajectories (ntra,ntim,4)
74
      integer                                reftime(6)      ! Reference date
83
      integer                                reftime(6)      ! Reference date
75
      character*80                           vars(200)       ! Field names
84
      character*80                           vars(200)       ! Field names
76
      real,allocatable, dimension (:)     :: xx0,yy0,pp0     ! Position of air parcels
85
      real,allocatable, dimension (:)     :: xx0,yy0,pp0     ! Position of air parcels
77
      integer,allocatable, dimension (:)  :: leftflag        ! Flag for domain-leaving
86
      integer,allocatable, dimension (:)  :: leftflag        ! Flag for domain-leaving
78
      real                                   xx1,yy1,pp1     ! Updated position of air parcel
87
      real                                   xx1,yy1,pp1     ! Updated position of air parcel
79
      integer                                leftcount       ! Number of domain leaving trajectories
88
      integer                                leftcount       ! Number of domain leaving trajectories
80
      integer                                ntim            ! Number of output time steps
89
      integer                                ntim            ! Number of output time steps
-
 
90
      real,allocatable, dimension (:)     :: theta           ! Potential temperature for isentropic trajectories
-
 
91
      real,allocatable, dimension (:)     :: zindex          ! Vertical index for model-level (2D) trajectories
81
 
92
 
82
c     Meteorological fields
93
c     Meteorological fields
83
      real,allocatable, dimension (:)     :: spt0,spt1       ! Surface pressure
94
      real,allocatable, dimension (:)     :: spt0,spt1       ! Surface pressure
84
      real,allocatable, dimension (:)     :: uut0,uut1       ! Zonal wind
95
      real,allocatable, dimension (:)     :: uut0,uut1       ! Zonal wind
85
      real,allocatable, dimension (:)     :: vvt0,vvt1       ! Meridional wind
96
      real,allocatable, dimension (:)     :: vvt0,vvt1       ! Meridional wind
86
      real,allocatable, dimension (:)     :: wwt0,wwt1       ! Vertical wind
97
      real,allocatable, dimension (:)     :: wwt0,wwt1       ! Vertical wind
87
      real,allocatable, dimension (:)     :: p3t0,p3t1       ! 3d-pressure 
98
      real,allocatable, dimension (:)     :: p3t0,p3t1       ! 3d-pressure 
-
 
99
      real,allocatable, dimension (:)     :: tht0,tht1       ! 3d potential temperature
-
 
100
      real,allocatable, dimension (:)     :: sth0,sth1       ! Surface potential temperature
88
 
101
 
89
c     Grid description
102
c     Grid description
90
      real                                   pollon,pollat   ! Longitude/latitude of pole
103
      real                                   pollon,pollat   ! Longitude/latitude of pole
91
      real                                   ak(nlevmax)     ! Vertical layers and levels
104
      real                                   ak(nlevmax)     ! Vertical layers and levels
92
      real                                   bk(nlevmax) 
105
      real                                   bk(nlevmax) 
93
      real                                   xmin,xmax       ! Zonal grid extension
106
      real                                   xmin,xmax       ! Zonal grid extension
94
      real                                   ymin,ymax       ! Meridional grid extension
107
      real                                   ymin,ymax       ! Meridional grid extension
95
      integer                                nx,ny,nz        ! Grid dimensions
108
      integer                                nx,ny,nz        ! Grid dimensions
96
      real                                   dx,dy           ! Horizontal grid resolution
109
      real                                   dx,dy           ! Horizontal grid resolution
97
      integer                                hem             ! Flag for hemispheric domain
110
      integer                                hem             ! Flag for hemispheric domain
98
      real                                   mdv             ! Missing data value
111
      real                                   mdv             ! Missing data value
99
 
112
 
100
c     Auxiliary variables                 
113
c     Auxiliary variables                 
101
      real                                   delta,rd
114
      real                                   delta,rd
102
      integer	                             itm,iloop,i,j,k,filo,lalo
115
      integer	                             itm,iloop,i,j,k,filo,lalo
103
      integer                                ierr,stat
116
      integer                                ierr,stat
104
      integer                                cdfid,fid
117
      integer                                cdfid,fid
105
      real	                                 tstart,time0,time1,time
118
      real	                                 tstart,time0,time1,time
106
      real                                   reltpos0,reltpos1
119
      real                                   reltpos0,reltpos1
107
      real                                   xind,yind,pind,pp,sp,stagz
120
      real                                   xind,yind,pind,pp,sp,stagz
108
      character*80                           filename,varname
121
      character*80                           filename,varname
109
      integer                                reftmp(6)
122
      integer                                reftmp(6)
110
      character                              ch
123
      character                              ch
111
      real                                   frac,tload
124
      real                                   frac,tload
112
      integer                                itim
125
      integer                                itim
113
      integer                                wstep
126
      integer                                wstep
114
      real                                   x1,y1
127
      real                                   x1,y1,p1
-
 
128
      real                                   thetamin,thetamax
-
 
129
      real                                   zindexmin,zindexmax
115
 
130
 
116
c     Externals
131
c     Externals
117
      real                                   int_index4
132
      real                                   int_index4
118
      external                               int_index4
133
      external                               int_index4
119
 
134
 
120
c     --------------------------------------------------------------------
135
c     --------------------------------------------------------------------
121
c     Start of program, Read parameters
136
c     Start of program, Read parameters
122
c     --------------------------------------------------------------------
137
c     --------------------------------------------------------------------
123
 
138
 
124
c     Write start message
139
c     Write start message
125
      print*,'========================================================='
140
      print*,'========================================================='
126
      print*,'              *** START OF PROGRAM CALTRA ***'
141
      print*,'              *** START OF PROGRAM CALTRA ***'
127
      print*
142
      print*
128
 
143
 
129
c     Open the parameter file
144
c     Open the parameter file
130
      open(9,file='caltra.param')
145
      open(9,file='caltra.param')
131
 
146
 
132
c     Read flag for forward/backward mode (fbflag)
147
c     Read flag for forward/backward mode (fbflag)
133
      read(9,*) fbflag
148
      read(9,*) fbflag
134
 
149
 
135
c     Read number of input files (numdat)
150
c     Read number of input files (numdat)
136
      read(9,*) numdat
151
      read(9,*) numdat
137
      if (numdat.gt.ndatmax) then
152
      if (numdat.gt.ndatmax) then
138
        print*,' ERROR: too many input files ',numdat,ndatmax
153
        print*,' ERROR: too many input files ',numdat,ndatmax
139
        goto 993
154
        goto 993
140
      endif
155
      endif
141
 
156
 
142
c     Read list of input dates (dat, sort depending on forward/backward mode)
157
c     Read list of input dates (dat, sort depending on forward/backward mode)
143
      if (fbflag.eq.1) then
158
      if (fbflag.eq.1) then
144
        do itm=1,numdat
159
        do itm=1,numdat
145
          read(9,'(a11)') dat(itm)
160
          read(9,'(a11)') dat(itm)
146
        enddo
161
        enddo
147
      else
162
      else
148
        do itm=numdat,1,-1
163
        do itm=numdat,1,-1
149
          read(9,'(a11)') dat(itm)
164
          read(9,'(a11)') dat(itm)
150
        enddo
165
        enddo
151
      endif
166
      endif
152
 
167
 
153
c     Read time increment between input files (timeinc)
168
c     Read time increment between input files (timeinc)
154
      read(9,*) timeinc
169
      read(9,*) timeinc
155
 
170
 
156
C     Read if data domain is periodic and its periodicity
171
C     Read if data domain is periodic and its periodicity
157
      read(9,*) per
172
      read(9,*) per
158
 
173
 
159
c     Read the number of trajectories and name of position file
174
c     Read the number of trajectories and name of position file
160
      read(9,*) strname
175
      read(9,*) strname
161
      read(9,*) ntra
176
      read(9,*) ntra
162
      read(9,*) ncol 
177
      read(9,*) ncol 
163
      if (ntra.eq.0) goto 991
178
      if (ntra.eq.0) goto 991
164
 
179
 
165
C     Read the name of the output trajectory file and set the constants file
180
C     Read the name of the output trajectory file and set the constants file
166
      read(9,*) cdfname
181
      read(9,*) cdfname
167
 
182
 
168
C     Read the timestep for trajectory calculation (convert from minutes to hours)
183
C     Read the timestep for trajectory calculation (convert from minutes to hours)
169
      read(9,*) ts
184
      read(9,*) ts
170
      ts=ts/60.        
185
      ts=ts/60.        
171
 
186
 
172
C     Read shift of start and end time relative to first data file
187
C     Read shift of start and end time relative to first data file
173
      read(9,*) tst
188
      read(9,*) tst
174
      read(9,*) ten
189
      read(9,*) ten
175
 
190
 
176
C     Read output time interval (in minutes)
191
C     Read output time interval (in minutes)
177
      read(9,*) deltout
192
      read(9,*) deltout
178
 
193
 
179
C     Read jumpflag (if =1 ground-touching trajectories reenter the atmosphere)
194
C     Read jumpflag (if =1 ground-touching trajectories reenter the atmosphere)
180
      read(9,*) jflag
195
      read(9,*) jflag
181
 
196
 
182
C     Read factor for vertical velocity field
197
C     Read factor for vertical velocity field
183
      read(9,*) wfactor
198
      read(9,*) wfactor
184
 
199
 
185
c     Read the reference time and the time range
200
c     Read the reference time and the time range
186
      read(9,*) reftime(1)                  ! year
201
      read(9,*) reftime(1)                  ! year
187
      read(9,*) reftime(2)                  ! month
202
      read(9,*) reftime(2)                  ! month
188
      read(9,*) reftime(3)                  ! day
203
      read(9,*) reftime(3)                  ! day
189
      read(9,*) reftime(4)                  ! hour
204
      read(9,*) reftime(4)                  ! hour
190
      read(9,*) reftime(5)                  ! min
205
      read(9,*) reftime(5)                  ! min
191
      read(9,*) reftime(6)                  ! time range (in min)
206
      read(9,*) reftime(6)                  ! time range (in min)
192
 
207
 
193
c     Read flag for 'no time check'
208
c     Read flag for 'no time check'
194
      read(9,*) timecheck
209
      read(9,*) timecheck
195
 
210
 
-
 
211
c     Read flag for isentropic trajectories
-
 
212
      read(9,*) isen, thons
-
 
213
 
-
 
214
c     Read flag for model-level trajectories (2D mode)
-
 
215
      read(9,*) modlev
-
 
216
 
196
c     Close the input file
217
c     Close the input file
197
      close(9)
218
      close(9)
198
 
219
 
199
c     Calculate the number of output time steps
220
c     Calculate the number of output time steps
200
      ntim = abs(reftime(6)/deltout) + 1
221
      ntim = abs(reftime(6)/deltout) + 1
201
 
222
 
202
c     Set the formats of the input and output files
223
c     Set the formats of the input and output files
203
      call mode_tra(inpmode,strname)
224
      call mode_tra(inpmode,strname)
204
      call mode_tra(outmode,cdfname)
225
      call mode_tra(outmode,cdfname)
205
      if (outmode.eq.-1) outmode=1
226
      if (outmode.eq.-1) outmode=1
206
 
227
 
207
c     Write some status information
228
c     Write some status information
208
      print*,'---- INPUT PARAMETERS -----------------------------------'
229
      print*,'---- INPUT PARAMETERS -----------------------------------'
209
      print* 
230
      print* 
210
      print*,'  Forward/Backward       : ',fbflag
231
      print*,'  Forward/Backward       : ',fbflag
211
      print*,'  #input files           : ',numdat
232
      print*,'  #input files           : ',numdat
212
      print*,'  First/last input file  : ',trim(dat(1)),' ... ',
233
      print*,'  First/last input file  : ',trim(dat(1)),' ... ',
213
     >                                     trim(dat(numdat))
234
     >                                     trim(dat(numdat))
214
      print*,'  time increment         : ',timeinc
235
      print*,'  time increment         : ',timeinc
215
      print*,'  Output file            : ',trim(cdfname)
236
      print*,'  Output file            : ',trim(cdfname)
216
      print*,'  Time step (min)        : ',60.*ts
237
      print*,'  Time step (min)        : ',60.*ts
217
      write(*,'(a27,f7.2,f7.2)') '   Time shift (start,end) : ',tst,ten
238
      write(*,'(a27,f7.2,f7.2)') '   Time shift (start,end) : ',tst,ten
218
      print*,'  Output time interval   : ',deltout
239
      print*,'  Output time interval   : ',deltout
219
      print*,'  Jump flag              : ',jflag
240
      print*,'  Jump flag              : ',jflag
220
      print*,'  Vertical wind (scale)  : ',wfactor
241
      print*,'  Vertical wind (scale)  : ',wfactor
221
      print*,'  Trajectory pos file    : ',trim(strname)
242
      print*,'  Trajectory pos file    : ',trim(strname)
222
      print*,'  # of trajectories      : ',ntra
243
      print*,'  # of trajectories      : ',ntra
223
      print*,'  # of output timesteps  : ',ntim
244
      print*,'  # of output timesteps  : ',ntim
224
      if ( inpmode.eq.-1) then
245
      if ( inpmode.eq.-1) then
225
         print*,'  Input format           : (lon,lat,p)-list'
246
         print*,'  Input format           : (lon,lat,p)-list'
226
      else
247
      else
227
         print*,'  Input format           : ',inpmode
248
         print*,'  Input format           : ',inpmode
228
      endif
249
      endif
229
      print*,'  Output format          : ',outmode
250
      print*,'  Output format          : ',outmode
230
      print*,'  Periodicity            : ',per
251
      print*,'  Periodicity            : ',per
231
      print*,'  Time check             : ',trim(timecheck)
252
      print*,'  Time check             : ',trim(timecheck)
-
 
253
      print*,'  Isentropic trajectories: ',trim(isen),thons
-
 
254
      print*,'  Model-level trajs (2D) : ',trim(modlev)
232
      print*
255
      print*
233
 
256
 
-
 
257
      if ( (isen.eq.'yes').and.(modlev.eq.'yes') ) then
-
 
258
         print*,
-
 
259
     >    '  WARNING: isentropic and 2D mode chosen -> 2D accepted'
-
 
260
         print*
-
 
261
         isen = 'no'
-
 
262
      endif
-
 
263
 
-
 
264
c     Init missing data value
-
 
265
      mdv = -999.
-
 
266
 
234
      print*,'---- FIXED NUMERICAL PARAMETERS -------------------------'
267
      print*,'---- FIXED NUMERICAL PARAMETERS -------------------------'
235
      print*
268
      print*
236
      print*,'  Numerical scheme       : ',imethod
269
      print*,'  Numerical scheme       : ',imethod
237
      print*,'  Number of iterations   : ',numit
270
      print*,'  Number of iterations   : ',numit
238
      print*,'  Filename prefix        : ',prefix
271
      print*,'  Filename prefix        : ',prefix
239
      print*,'  Missing data value     : ',mdv
272
      print*,'  Missing data value     : ',mdv
240
      print*
273
      print*
241
 
274
 
242
c     --------------------------------------------------------------------
275
c     --------------------------------------------------------------------
243
c     Read grid parameters, checks and allocate memory
276
c     Read grid parameters, checks and allocate memory
244
c     --------------------------------------------------------------------
277
c     --------------------------------------------------------------------
245
 
278
 
246
c     Read the constant grid parameters (nx,ny,nz,xmin,xmax,ymin,ymax,pollon,pollat)
279
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  
280
c     The negative <-fid> of the file identifier is used as a flag for parameter retrieval  
248
      filename = prefix//dat(1)
281
      filename = prefix//dat(1)
249
      varname  = 'U'
282
      varname  = 'U'
250
      nx       = 1
283
      nx       = 1
251
      ny       = 1
284
      ny       = 1
252
      nz       = 1
285
      nz       = 1
253
      tload    = -tst
286
      tload    = -tst
254
      call input_open (fid,filename)
287
      call input_open (fid,filename)
255
      call input_grid (-fid,varname,xmin,xmax,ymin,ymax,dx,dy,nx,ny,
288
      call input_grid (-fid,varname,xmin,xmax,ymin,ymax,dx,dy,nx,ny,
256
     >                 tload,pollon,pollat,rd,rd,nz,rd,rd,rd,timecheck)
289
     >                 tload,pollon,pollat,rd,rd,nz,rd,rd,rd,timecheck)
257
      call input_close(fid)
290
      call input_close(fid)
258
 
291
 
259
C     Check if the number of levels is too large
292
C     Check if the number of levels is too large
260
      if (nz.gt.nlevmax) goto 993
293
      if (nz.gt.nlevmax) goto 993
261
 
294
 
262
C     Set logical flag for periodic data set (hemispheric or not)
295
C     Set logical flag for periodic data set (hemispheric or not)
263
      hem = 0
296
      hem = 0
264
      if (per.eq.0.) then
297
      if (per.eq.0.) then
265
         delta=xmax-xmin-360.
298
         delta=xmax-xmin-360.
266
         if (abs(delta+dx).lt.eps) then               ! Program aborts: arrays must be closed
299
         if (abs(delta+dx).lt.eps) then               ! Program aborts: arrays must be closed
267
            goto 992
300
            goto 992
268
        else if (abs(delta).lt.eps) then              ! Periodic and hemispheric
301
        else if (abs(delta).lt.eps) then              ! Periodic and hemispheric
269
           hem=1
302
           hem=1
270
           per=360.
303
           per=360.
271
        endif
304
        endif
272
      else                                            ! Periodic and hemispheric
305
      else                                            ! Periodic and hemispheric
273
         hem=1
306
         hem=1
274
      endif
307
      endif
275
      
308
      
276
C     Allocate memory for some meteorological arrays
309
C     Allocate memory for some meteorological arrays
277
      allocate(spt0(nx*ny),stat=stat)
310
      allocate(spt0(nx*ny),stat=stat)
278
      if (stat.ne.0) print*,'*** error allocating array spt0 ***'   ! Surface pressure
311
      if (stat.ne.0) print*,'*** error allocating array spt0 ***'   ! Surface pressure
279
      allocate(spt1(nx*ny),stat=stat)
312
      allocate(spt1(nx*ny),stat=stat)
280
      if (stat.ne.0) print*,'*** error allocating array spt1 ***'
313
      if (stat.ne.0) print*,'*** error allocating array spt1 ***'
281
      allocate(uut0(nx*ny*nz),stat=stat)
314
      allocate(uut0(nx*ny*nz),stat=stat)
282
      if (stat.ne.0) print*,'*** error allocating array uut0 ***'   ! Zonal wind
315
      if (stat.ne.0) print*,'*** error allocating array uut0 ***'   ! Zonal wind
283
      allocate(uut1(nx*ny*nz),stat=stat)
316
      allocate(uut1(nx*ny*nz),stat=stat)
284
      if (stat.ne.0) print*,'*** error allocating array uut1 ***'
317
      if (stat.ne.0) print*,'*** error allocating array uut1 ***'
285
      allocate(vvt0(nx*ny*nz),stat=stat)
318
      allocate(vvt0(nx*ny*nz),stat=stat)
286
      if (stat.ne.0) print*,'*** error allocating array vvt0 ***'   ! Meridional wind
319
      if (stat.ne.0) print*,'*** error allocating array vvt0 ***'   ! Meridional wind
287
      allocate(vvt1(nx*ny*nz),stat=stat)
320
      allocate(vvt1(nx*ny*nz),stat=stat)
288
      if (stat.ne.0) print*,'*** error allocating array vvt1 ***'
321
      if (stat.ne.0) print*,'*** error allocating array vvt1 ***'
289
      allocate(wwt0(nx*ny*nz),stat=stat)
322
      allocate(wwt0(nx*ny*nz),stat=stat)
290
      if (stat.ne.0) print*,'*** error allocating array wwt0 ***'   ! Vertical wind
323
      if (stat.ne.0) print*,'*** error allocating array wwt0 ***'   ! Vertical wind
291
      allocate(wwt1(nx*ny*nz),stat=stat)
324
      allocate(wwt1(nx*ny*nz),stat=stat)
292
      if (stat.ne.0) print*,'*** error allocating array wwt1 ***'
325
      if (stat.ne.0) print*,'*** error allocating array wwt1 ***'
293
      allocate(p3t0(nx*ny*nz),stat=stat)
326
      allocate(p3t0(nx*ny*nz),stat=stat)
294
      if (stat.ne.0) print*,'*** error allocating array p3t0 ***'   ! Pressure
327
      if (stat.ne.0) print*,'*** error allocating array p3t0 ***'   ! Pressure
295
      allocate(p3t1(nx*ny*nz),stat=stat)
328
      allocate(p3t1(nx*ny*nz),stat=stat)
296
      if (stat.ne.0) print*,'*** error allocating array p3t1 ***'
329
      if (stat.ne.0) print*,'*** error allocating array p3t1 ***'
-
 
330
      allocate(tht0(nx*ny*nz),stat=stat)
-
 
331
      if (stat.ne.0) print*,'*** error allocating array tht0 ***'   ! Potential temperature
-
 
332
      allocate(tht1(nx*ny*nz),stat=stat)
-
 
333
      if (stat.ne.0) print*,'*** error allocating array tht1 ***'
-
 
334
      allocate(sth0(nx*ny),stat=stat)
-
 
335
      if (stat.ne.0) print*,'*** error allocating array spt0 ***'   ! Surface potential temperature
-
 
336
      allocate(sth1(nx*ny),stat=stat)
-
 
337
      if (stat.ne.0) print*,'*** error allocating array sth1 ***'
297
 
338
 
298
C     Get memory for trajectory arrays
339
C     Get memory for trajectory arrays
299
      allocate(trainp(ntra,1,ncol),stat=stat)
340
      allocate(trainp(ntra,1,ncol),stat=stat)
300
      if (stat.ne.0) print*,'*** error allocating array trainp   ***' ! Input start coordinates
341
      if (stat.ne.0) print*,'*** error allocating array trainp   ***' ! Input start coordinates
301
      allocate(traout(ntra,ntim,4),stat=stat)
342
      allocate(traout(ntra,ntim,4),stat=stat)
302
      if (stat.ne.0) print*,'*** error allocating array traout   ***' ! Output trajectories
343
      if (stat.ne.0) print*,'*** error allocating array traout   ***' ! Output trajectories
303
      allocate(xx0(ntra),stat=stat)
344
      allocate(xx0(ntra),stat=stat)
304
      if (stat.ne.0) print*,'*** error allocating array xx0      ***' ! X position (longitude)
345
      if (stat.ne.0) print*,'*** error allocating array xx0      ***' ! X position (longitude)
305
      allocate(yy0(ntra),stat=stat)
346
      allocate(yy0(ntra),stat=stat)
306
      if (stat.ne.0) print*,'*** error allocating array yy0      ***' ! Y position (latitude)
347
      if (stat.ne.0) print*,'*** error allocating array yy0      ***' ! Y position (latitude)
307
      allocate(pp0(ntra),stat=stat)
348
      allocate(pp0(ntra),stat=stat)
308
      if (stat.ne.0) print*,'*** error allocating array pp0      ***' ! Pressure
349
      if (stat.ne.0) print*,'*** error allocating array pp0      ***' ! Pressure
309
      allocate(leftflag(ntra),stat=stat)
350
      allocate(leftflag(ntra),stat=stat)
310
      if (stat.ne.0) print*,'*** error allocating array leftflag ***' ! Leaving-domain flag
351
      if (stat.ne.0) print*,'*** error allocating array leftflag ***' ! Leaving-domain flag
-
 
352
      allocate(theta(ntra),stat=stat)
-
 
353
      if (stat.ne.0) print*,'*** error allocating array theta ***'    ! Potential temperature for isentropic trajectories
-
 
354
      allocate(zindex(ntra),stat=stat)
-
 
355
      if (stat.ne.0) print*,'*** error allocating array kind ***'     ! Vertical index for model-level trajectories
311
 
356
 
312
c     Write some status information
357
c     Write some status information
313
      print*,'---- CONSTANT GRID PARAMETERS ---------------------------'
358
      print*,'---- CONSTANT GRID PARAMETERS ---------------------------'
314
      print*
359
      print*
315
      print*,'  xmin,xmax     : ',xmin,xmax
360
      print*,'  xmin,xmax     : ',xmin,xmax
316
      print*,'  ymin,ymax     : ',ymin,ymax
361
      print*,'  ymin,ymax     : ',ymin,ymax
317
      print*,'  dx,dy         : ',dx,dy
362
      print*,'  dx,dy         : ',dx,dy
318
      print*,'  pollon,pollat : ',pollon,pollat
363
      print*,'  pollon,pollat : ',pollon,pollat
319
      print*,'  nx,ny,nz      : ',nx,ny,nz
364
      print*,'  nx,ny,nz      : ',nx,ny,nz
320
      print*,'  per, hem      : ',per,hem
365
      print*,'  per, hem      : ',per,hem
321
      print*
366
      print*
322
 
367
 
323
c     --------------------------------------------------------------------
368
c     --------------------------------------------------------------------
324
c     Initialize the trajectory calculation
369
c     Initialize the trajectory calculation
325
c     --------------------------------------------------------------------
370
c     --------------------------------------------------------------------
326
 
371
 
327
c     Read start coordinates from file - Format (lon,lat,lev)
372
c     Read start coordinates from file - Format (lon,lat,lev)
328
      if (inpmode.eq.-1) then
373
      if (inpmode.eq.-1) then
329
         open(fid,file=strname)
374
         open(fid,file=strname)
330
          do i=1,ntra
375
          do i=1,ntra
331
             read(fid,*) xx0(i),yy0(i),pp0(i)
376
             read(fid,*) xx0(i),yy0(i),pp0(i)
332
          enddo
377
          enddo
333
         close(fid)
378
         close(fid)
334
 
379
 
335
c     Read start coordinates from trajectory file - check consistency of ref time
380
c     Read start coordinates from trajectory file - check consistency of ref time
336
      else
381
      else
337
         print*,'Hallo', ntra,ncol
-
 
338
         call ropen_tra(cdfid,strname,ntra,1,ncol,reftmp,vars,inpmode)
382
         call ropen_tra(cdfid,strname,ntra,1,ncol,reftmp,vars,inpmode)
339
         call read_tra (cdfid,trainp,ntra,1,ncol,inpmode)
383
         call read_tra (cdfid,trainp,ntra,1,ncol,inpmode)
340
         do i=1,ntra
384
         do i=1,ntra
341
            time   = trainp(i,1,1)
385
            time   = trainp(i,1,1)
342
            xx0(i) = trainp(i,1,2) 
386
            xx0(i) = trainp(i,1,2) 
343
            yy0(i) = trainp(i,1,3) 
387
            yy0(i) = trainp(i,1,3) 
344
            pp0(i) = trainp(i,1,4) 
388
            pp0(i) = trainp(i,1,4) 
345
         enddo
389
         enddo
346
         call close_tra(cdfid,inpmode)
390
         call close_tra(cdfid,inpmode)
347
 
391
 
348
         if ( ( reftime(1).ne.reftmp(1) ).or.
392
         if ( ( reftime(1).ne.reftmp(1) ).or.
349
     >        ( reftime(2).ne.reftmp(2) ).or.
393
     >        ( reftime(2).ne.reftmp(2) ).or.
350
     >        ( reftime(3).ne.reftmp(3) ).or.
394
     >        ( reftime(3).ne.reftmp(3) ).or.
351
     >        ( reftime(4).ne.reftmp(4) ).or.
395
     >        ( reftime(4).ne.reftmp(4) ).or.
352
     >        ( reftime(5).ne.reftmp(5) ) )
396
     >        ( reftime(5).ne.reftmp(5) ) )
353
     >   then
397
     >   then
354
            print*,' WARNING: Inconsistent reference times'
398
            print*,' WARNING: Inconsistent reference times'
355
            write(*,'(5i8)') (reftime(i),i=1,5)
399
            write(*,'(5i8)') (reftime(i),i=1,5)
356
            write(*,'(5i8)') (reftmp (i),i=1,5)
400
            write(*,'(5i8)') (reftmp (i),i=1,5)
357
            print*,'Enter a key to proceed...'
401
            print*,'Enter a key to proceed...'
358
            stop
402
            stop
359
         endif
403
         endif
360
      endif
404
      endif
361
 
405
 
362
c     Set sign of time range
406
c     Set sign of time range
363
      reftime(6) = fbflag * reftime(6)
407
      reftime(6) = fbflag * reftime(6)
364
         
408
         
365
c     Write some status information
409
c     Write some status information
366
      print*,'---- REFERENCE DATE---------- ---------------------------'
410
      print*,'---- REFERENCE DATE---------- ---------------------------'
367
      print*
411
      print*
368
      print*,' Reference time (year)  :',reftime(1)
412
      print*,' Reference time (year)  :',reftime(1)
369
      print*,'                (month) :',reftime(2)
413
      print*,'                (month) :',reftime(2)
370
      print*,'                (day)   :',reftime(3)
414
      print*,'                (day)   :',reftime(3)
371
      print*,'                (hour)  :',reftime(4)
415
      print*,'                (hour)  :',reftime(4)
372
      print*,'                (min)   :',reftime(5)
416
      print*,'                (min)   :',reftime(5)
373
      print*,' Time range             :',reftime(6),' min'
417
      print*,' Time range             :',reftime(6),' min'
374
      print*
418
      print*
375
 
419
 
376
C     Save starting positions 
420
C     Save starting positions 
377
      itim = 1
421
      itim = 1
378
      do i=1,ntra
422
      do i=1,ntra
379
         traout(i,itim,1) = 0.
423
         traout(i,itim,1) = 0.
380
         traout(i,itim,2) = xx0(i)
424
         traout(i,itim,2) = xx0(i)
381
         traout(i,itim,3) = yy0(i)
425
         traout(i,itim,3) = yy0(i)
382
         traout(i,itim,4) = pp0(i)
426
         traout(i,itim,4) = pp0(i)
383
      enddo
427
      enddo
384
 
428
 
385
c     Init the flag and the counter for trajectories leaving the domain
429
c     Init the flag and the counter for trajectories leaving the domain
386
      leftcount=0
430
      leftcount=0
387
      do i=1,ntra
431
      do i=1,ntra
388
         leftflag(i)=0
432
         leftflag(i)=0
389
      enddo
433
      enddo
390
 
434
 
391
C     Convert time shifts <tst,ten> from <hh.mm> into fractional time
435
C     Convert time shifts <tst,ten> from <hh.mm> into fractional time
392
      call hhmm2frac(tst,frac)
436
      call hhmm2frac(tst,frac)
393
      tst = frac
437
      tst = frac
394
      call hhmm2frac(ten,frac)
438
      call hhmm2frac(ten,frac)
395
      ten = frac
439
      ten = frac
396
 
440
 
397
c     Check that all starting positions are above topography
441
c     Get 3D and surface pressure from first data file 
398
      varname = 'P'
-
 
399
      filename = prefix//dat(1)
442
      filename = prefix//dat(1)
400
      call input_open (fid,filename)
443
      call input_open (fid,filename)
-
 
444
      if ( modlev.eq.'no' ) then 
-
 
445
         varname = 'P'
401
      call input_grid
446
         call input_grid
-
 
447
     >       (fid,varname,xmin,xmax,ymin,ymax,dx,dy,nx,ny,
-
 
448
     >        tload,pollon,pollat,p3t1,spt1,nz,ak,bk,stagz,timecheck)
-
 
449
      else  
-
 
450
         varname = 'P.ML'
-
 
451
         call input_grid
402
     >    (fid,varname,xmin,xmax,ymin,ymax,dx,dy,nx,ny,
452
     >       (fid,varname,xmin,xmax,ymin,ymax,dx,dy,nx,ny,
403
     >     tload,pollon,pollat,p3t1,spt1,nz,ak,bk,stagz,timecheck)
453
     >        tload,pollon,pollat,p3t1,spt1,nz,ak,bk,stagz,timecheck)
-
 
454
      endif
404
      call input_close(fid)
455
      call input_close(fid)
-
 
456
      
-
 
457
c     Check that all starting positions are above topography    
405
      do i=1,ntra
458
      do i=1,ntra
406
 
459
 
407
C       Interpolate surface pressure to actual position (from first input file)
460
C       Interpolate surface pressure to actual position (from first input file)
408
        x1 = xx0(i)
461
        x1 = xx0(i)
409
        y1 = yy0(i)
462
        y1 = yy0(i)
410
        call get_index4 (xind,yind,pind,x1,y1,1050.,0.,
463
        call get_index4 (xind,yind,pind,x1,y1,1050.,0.,
411
     >                   p3t1,p3t1,spt1,spt1,3,
464
     >                   p3t1,p3t1,spt1,spt1,3,
412
     >                   nx,ny,nz,xmin,ymin,dx,dy,mdv)
465
     >                   nx,ny,nz,xmin,ymin,dx,dy,mdv)
413
        sp = int_index4 (spt1,spt1,nx,ny,1,xind,yind,1.,0.,mdv)
466
        sp = int_index4 (spt1,spt1,nx,ny,1,xind,yind,1.,0.,mdv)
414
 
467
 
415
c       Decide whether to keep the trajectory
468
c       Decide whether to keep the trajectory
416
        if ( pp0(i).gt.sp ) then
469
        if ( pp0(i).gt.sp ) then
417
            write(*,'(a30,3f10.2)')
470
            write(*,'(a30,3f10.2)')
418
     >               'WARNING: starting point below topography ',
471
     >               'WARNING: starting point below topography ',
419
     >               xx0(i),yy0(i),pp0(i)
472
     >               xx0(i),yy0(i),pp0(i)
420
            leftflag(i) = 1
473
            leftflag(i) = 1
421
        endif
474
        endif
422
 
475
 
423
      enddo
476
      enddo
424
 
477
 
-
 
478
c     Special handling for isentropic trajectories - read potential
-
 
479
c     temperature from S file or calculate it based on temperature and
-
 
480
c     pressure from P file; then, calculate for each trajectory its
-
 
481
c     potential temperature - which will stay fixed over time
-
 
482
      if ( isen.eq.'yes' ) then
-
 
483
 
-
 
484
c         Get potential temperature from S file
-
 
485
          if ( thons.eq.1 ) then
-
 
486
              filename = srefix//dat(1)
-
 
487
              print*,' TH <- ',trim(filename)
-
 
488
              call input_open (fid,filename)
-
 
489
              varname='TH'
-
 
490
              call input_wind
-
 
491
     >            (fid,varname,tht1,tload,stagz,mdv,
-
 
492
     >              xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck)
-
 
493
              call input_close(fid)
-
 
494
 
-
 
495
c         Calculate potential temperature from P file
-
 
496
          else
-
 
497
              filename = prefix//dat(1)
-
 
498
              print*,' TH = T * (1000/P)^RDCP <- ',trim(filename)
-
 
499
              call input_open (fid,filename)
-
 
500
              varname='T'
-
 
501
              call input_wind
-
 
502
     >            (fid,varname,tht1,tload,stagz,mdv,
-
 
503
     >              xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck)
-
 
504
              call input_close(fid)
-
 
505
              do i=1,nx*ny*nz
-
 
506
                if (tht1(i).lt.100.) then
-
 
507
                   tht1(i)=(tht1(i)+tzero)*( (1000./p3t1(i))**rdcp )
-
 
508
                else
-
 
509
                   tht1(i)=tht1(i)*( (1000./p3t1(i))**rdcp )
-
 
510
                endif
-
 
511
              enddo
-
 
512
          endif
-
 
513
 
-
 
514
c         Take surface potential temperature from lowest level
-
 
515
          do i=1,nx*ny
-
 
516
            sth1(i) = tht1(i)
-
 
517
          enddo
-
 
518
 
-
 
519
c         Calculate now the potential temperature of all trajectories
-
 
520
          do i=1,ntra
-
 
521
 
-
 
522
             x1 = xx0(i)
-
 
523
             y1 = yy0(i)
-
 
524
             p1 = pp0(i)
-
 
525
             call get_index4 (xind,yind,pind,x1,y1,p1,0.,
-
 
526
     >                 p3t1,p3t1,spt1,spt1,3,
-
 
527
     >                 nx,ny,nz,xmin,ymin,dx,dy,mdv)
-
 
528
             theta(i) =
-
 
529
     >        int_index4(tht1,tht1,nx,ny,nz,xind,yind,pind,0.,mdv)
-
 
530
 
-
 
531
          enddo
-
 
532
 
-
 
533
c         Write info about theta range of starting positions
-
 
534
          thetamin = theta(1)
-
 
535
          thetamax = theta(1)
-
 
536
          do i=2,ntra
-
 
537
            if ( theta(i).gt.thetamax ) thetamax = theta(i)
-
 
538
            if ( theta(i).lt.thetamin ) thetamin = theta(i)
-
 
539
          enddo
-
 
540
 
-
 
541
c         Write some status information
-
 
542
          print*
-
 
543
          print*,
-
 
544
     >     '---- THETA RANGE OF ISENTROPIC TRAJECTORIES -------------'
-
 
545
          print*
-
 
546
          print*,' Theta(min)             :',thetamin
-
 
547
          print*,' Theta(max)             :',thetamax
-
 
548
 
-
 
549
      endif
-
 
550
 
-
 
551
c     Special handling for model-level (2D) trajectories - get the
-
 
552
c     vertical index for each trajectory - which will remain fixed
-
 
553
      if ( modlev.eq.'yes' ) then
-
 
554
          do i=1,ntra
-
 
555
             x1 = xx0(i)
-
 
556
             y1 = yy0(i)
-
 
557
             p1 = pp0(i)
-
 
558
             call get_index4 (xind,yind,pind,x1,y1,p1,0.,
-
 
559
     >                 p3t1,p3t1,spt1,spt1,3,
-
 
560
     >                 nx,ny,nz,xmin,ymin,dx,dy,mdv)
-
 
561
             zindex(i) = pind
-
 
562
          enddo
-
 
563
 
-
 
564
          do i=1,nz
-
 
565
            print*,i,p3t1(189+(141-1)*nx+(i-1)*nx*ny)
-
 
566
          enddo
-
 
567
             print*,x1,y1,p1
-
 
568
             print*,xind,yind,pind
-
 
569
 
-
 
570
c         Write info about zindex range of starting positions
-
 
571
          zindexmin = zindex(1)
-
 
572
          zindexmax = zindex(1)
-
 
573
          do i=2,ntra
-
 
574
            if ( zindex(i).gt.zindexmax ) zindexmax = zindex(i)
-
 
575
            if ( zindex(i).lt.zindexmin ) zindexmin = zindex(i)
-
 
576
          enddo
-
 
577
 
-
 
578
c         Write some status information
-
 
579
          print*
-
 
580
          print*,
-
 
581
     >     '---- INDEX RANGE OF MODEL-LEVEL TRAJECTORIES ------------'
-
 
582
          print*
-
 
583
          print*,' Zindex(min)            :',zindexmin
-
 
584
          print*,' Zindex(max)            :',zindexmax
-
 
585
 
-
 
586
 
-
 
587
      endif
425
 
588
 
426
c     -----------------------------------------------------------------------
589
c     -----------------------------------------------------------------------
427
c     Loop to calculate trajectories
590
c     Loop to calculate trajectories
428
c     -----------------------------------------------------------------------
591
c     -----------------------------------------------------------------------
429
 
592
 
430
c     Write some status information
593
c     Write some status information
431
      print*
594
      print*
432
      print*,'---- TRAJECTORIES ----------- ---------------------------'
595
      print*,'---- TRAJECTORIES ----------- ---------------------------'
433
      print*    
596
      print*    
434
 
597
 
435
C     Set the time for the first data file (depending on forward/backward mode)
598
C     Set the time for the first data file (depending on forward/backward mode)
436
      if (fbflag.eq.1) then
599
      if (fbflag.eq.1) then
437
        tstart = -tst
600
        tstart = -tst
438
      else
601
      else
439
        tstart = tst
602
        tstart = tst
440
      endif
603
      endif
441
 
604
 
442
c     Set the minute counter for output
605
c     Set the minute counter for output
443
      wstep = 0
606
      wstep = 0
444
 
607
 
445
c     Read wind fields and vertical grid from first file
608
c     Read wind fields and vertical grid from first file
446
      filename = prefix//dat(1)
609
      filename = prefix//dat(1)
447
 
610
 
448
      call frac2hhmm(tstart,tload)
611
      call frac2hhmm(tstart,tload)
449
 
612
 
450
      write(*,'(a16,a20,f7.2)') '  (file,time) : ',
613
      write(*,'(a16,a20,f9.2)') '  (file,time) : ',
451
     >                       trim(filename),tload
614
     >                       trim(filename),tload
452
 
615
 
453
      call input_open (fid,filename)
616
      call input_open (fid,filename)
-
 
617
 
454
      varname='U'                                      ! U
618
      varname='U'                                      ! U
455
      call input_wind 
619
      call input_wind 
456
     >    (fid,varname,uut1,tload,stagz,mdv,
620
     >    (fid,varname,uut1,tload,stagz,mdv,
457
     >     xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck)
621
     >     xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck)
-
 
622
 
458
      varname='V'                                      ! V
623
      varname='V'                                      ! V
459
      call input_wind 
624
      call input_wind 
460
     >    (fid,varname,vvt1,tload,stagz,mdv,
625
     >    (fid,varname,vvt1,tload,stagz,mdv,
461
     >     xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck)
626
     >     xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck)
-
 
627
 
-
 
628
      if ( (modlev.eq.'no').and.(isen.eq.'no') ) then
462
      varname='OMEGA'                                  ! OMEGA
629
         varname='OMEGA'                                  ! OMEGA
463
      call input_wind 
630
         call input_wind
464
     >    (fid,varname,wwt1,tload,stagz,mdv,
631
     >       (fid,varname,wwt1,tload,stagz,mdv,
465
     >     xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck)      
632
     >        xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck)
-
 
633
      endif
-
 
634
 
-
 
635
      if ( modlev.eq.'no' ) then
-
 
636
         call input_grid                                  ! GRID - AK,BK -> P
-
 
637
     >       (fid,varname,xmin,xmax,ymin,ymax,dx,dy,nx,ny,
-
 
638
     >        tload,pollon,pollat,p3t1,spt1,nz,ak,bk,stagz,timecheck)
-
 
639
      else
-
 
640
         varname='P.ML'                                   ! GRID - P,PS
466
      call input_grid                                  ! GRID
641
         call input_grid                                  !
467
     >    (fid,varname,xmin,xmax,ymin,ymax,dx,dy,nx,ny,
642
     >       (fid,varname,xmin,xmax,ymin,ymax,dx,dy,nx,ny,
468
     >     tload,pollon,pollat,p3t1,spt1,nz,ak,bk,stagz,timecheck)
643
     >        tload,pollon,pollat,p3t1,spt1,nz,ak,bk,stagz,timecheck)
-
 
644
      endif
-
 
645
 
469
      call input_close(fid)
646
      call input_close(fid)
-
 
647
 
-
 
648
c     Special handling for isentropic trajectories - read potential
-
 
649
c     temperature from S file or calculate it based on temperature and
-
 
650
c     pressure from P file
-
 
651
      if ( isen.eq.'yes' ) then
-
 
652
 
-
 
653
c         Get potential temperature from S file
-
 
654
          if ( thons.eq.1 ) then
-
 
655
              filename = srefix//dat(1)
-
 
656
              print*,' TH <- ',trim(filename)
-
 
657
              call input_open (fid,filename)
-
 
658
              varname='TH'
-
 
659
              call input_wind
-
 
660
     >            (fid,varname,tht1,tload,stagz,mdv,
-
 
661
     >              xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck)
-
 
662
              call input_close(fid)
-
 
663
 
-
 
664
c         Calculate potential temperature from P file
470
          
665
          else
-
 
666
              filename = prefix//dat(1)
-
 
667
              print*,' TH = T * (1000/P)^RDCP <- ',trim(filename)
-
 
668
              call input_open (fid,filename)
-
 
669
              varname='T'
-
 
670
              call input_wind
-
 
671
     >            (fid,varname,tht1,tload,stagz,mdv,
-
 
672
     >              xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck)
-
 
673
              call input_close(fid)
-
 
674
              do i=1,nx*ny*nz
-
 
675
                if (tht1(i).lt.100.) then
-
 
676
                   tht1(i)=(tht1(i)+tzero)*( (1000./p3t1(i))**rdcp )
-
 
677
                else
-
 
678
                   tht1(i)=tht1(i)*( (1000./p3t1(i))**rdcp )
-
 
679
                endif
-
 
680
              enddo
-
 
681
          endif
-
 
682
 
-
 
683
c         Take surface potential temperature from lowest level
-
 
684
          do i=1,nx*ny
-
 
685
            sth1(i) = tht1(i)
-
 
686
          enddo
-
 
687
      endif
-
 
688
 
471
c     Loop over all input files (time step is <timeinc>)
689
c     Loop over all input files (time step is <timeinc>)
472
      do itm=1,numdat-1
690
      do itm=1,numdat-1
473
 
691
 
474
c       Calculate actual and next time
692
c       Calculate actual and next time
475
        time0 = tstart+real(itm-1)*timeinc*fbflag
693
        time0 = tstart+real(itm-1)*timeinc*fbflag
476
        time1 = time0+timeinc*fbflag
694
        time1 = time0+timeinc*fbflag
477
 
695
 
478
c       Copy old velocities and pressure fields to new ones       
696
c       Copy old velocities and pressure fields to new ones       
479
        do i=1,nx*ny*nz
697
        do i=1,nx*ny*nz
480
           uut0(i)=uut1(i)
698
           uut0(i)=uut1(i)
481
           vvt0(i)=vvt1(i)
699
           vvt0(i)=vvt1(i)
482
           wwt0(i)=wwt1(i)
700
           wwt0(i)=wwt1(i)
483
           p3t0(i)=p3t1(i)
701
           p3t0(i)=p3t1(i)
-
 
702
           tht0(i)=tht1(i)
484
        enddo
703
        enddo
485
        do i=1,nx*ny
704
        do i=1,nx*ny
486
           spt0(i)=spt1(i)
705
           spt0(i)=spt1(i)
-
 
706
           sth0(i)=sth1(i)
487
        enddo
707
        enddo
488
 
708
 
489
c       Read wind fields and surface pressure at next time
709
c       Read wind fields and surface pressure at next time
490
        filename = prefix//dat(itm+1)
710
        filename = prefix//dat(itm+1)
491
 
711
 
492
        call frac2hhmm(time1,tload)
712
        call frac2hhmm(time1,tload)
493
        write(*,'(a16,a20,f7.2)') '  (file,time) : ',
713
        write(*,'(a16,a20,f9.2)') '  (file,time) : ',
494
     >                          trim(filename),tload
714
     >                          trim(filename),tload
495
 
715
 
496
        call input_open (fid,filename)
716
        call input_open (fid,filename)
-
 
717
 
497
        varname='U'                                     ! U
718
        varname='U'                                     ! U
498
        call input_wind 
719
        call input_wind 
499
     >       (fid,varname,uut1,tload,stagz,mdv,
720
     >       (fid,varname,uut1,tload,stagz,mdv,
500
     >        xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck)
721
     >        xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck)
-
 
722
 
501
        varname='V'                                     ! V
723
        varname='V'                                     ! V
502
        call input_wind 
724
        call input_wind 
503
     >       (fid,varname,vvt1,tload,stagz,mdv,
725
     >       (fid,varname,vvt1,tload,stagz,mdv,
504
     >        xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck)
726
     >        xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck)
-
 
727
 
-
 
728
        if ( (modlev.eq.'no').and.(isen.eq.'no') ) then
505
        varname='OMEGA'                                ! OMEGA
729
           varname='OMEGA'                              ! OMEGA
506
        call input_wind 
730
           call input_wind
507
     >       (fid,varname,wwt1,tload,stagz,mdv,
731
     >          (fid,varname,wwt1,tload,stagz,mdv,
508
     >        xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck)      
732
     >           xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck)
-
 
733
        endif
-
 
734
 
-
 
735
        if ( modlev.eq.'no' ) then
-
 
736
           call input_grid                                  ! GRID - AK,NK -> P
-
 
737
     >          (fid,varname,xmin,xmax,ymin,ymax,dx,dy,nx,ny,
-
 
738
     >           tload,pollon,pollat,p3t1,spt1,nz,ak,bk,stagz,timecheck)
-
 
739
        else
-
 
740
           varname='P.ML'                                   ! GRID - P,PS
509
        call input_grid                                ! GRID
741
           call input_grid                                  !
510
     >       (fid,varname,xmin,xmax,ymin,ymax,dx,dy,nx,ny,
742
     >       (fid,varname,xmin,xmax,ymin,ymax,dx,dy,nx,ny,
511
     >        tload,pollon,pollat,p3t1,spt1,nz,ak,bk,stagz,timecheck)
743
     >        tload,pollon,pollat,p3t1,spt1,nz,ak,bk,stagz,timecheck)
-
 
744
        endif
-
 
745
 
512
        call input_close(fid)
746
        call input_close(fid)
-
 
747
 
-
 
748
c     Special handling for isentropic trajectories - read potential
-
 
749
c     temperature from S file or calculate it based on temperature and
-
 
750
c     pressure from P file
-
 
751
      if ( isen.eq.'yes' ) then
-
 
752
 
-
 
753
c         Get TH from S file
-
 
754
          if ( thons.eq.1 ) then
-
 
755
              filename = srefix//dat(itm+1)
-
 
756
              print*,' TH <- ',trim(filename)
-
 
757
              call input_open (fid,filename)
-
 
758
              varname='TH'
-
 
759
              call input_wind
-
 
760
     >            (fid,varname,tht1,tload,stagz,mdv,
-
 
761
     >              xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck)
-
 
762
              call input_close(fid)
-
 
763
 
-
 
764
c         Calculate potential temperature from P file
-
 
765
          else
-
 
766
              filename = prefix//dat(itm+1)
-
 
767
              print*,' TH = T * (1000/P)^RDCP <- ',trim(filename)
-
 
768
              call input_open (fid,filename)
-
 
769
              varname='T'
-
 
770
              call input_wind
-
 
771
     >            (fid,varname,tht1,tload,stagz,mdv,
-
 
772
     >              xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck)
-
 
773
              call input_close(fid)
-
 
774
              do i=1,nx*ny*nz
-
 
775
                if (tht1(i).lt.100.) then
-
 
776
                   tht1(i)=(tht1(i)+tzero)*( (1000./p3t1(i))**rdcp )
-
 
777
                else
-
 
778
                   tht1(i)=tht1(i)*( (1000./p3t1(i))**rdcp )
-
 
779
                endif
-
 
780
              enddo
-
 
781
          endif
-
 
782
 
-
 
783
c         Take surface potential temperature from lowest level
-
 
784
          do i=1,nx*ny
-
 
785
            sth1(i) = tht1(i)
-
 
786
          enddo
-
 
787
      endif
513
        
788
        
514
C       Determine the first and last loop indices
789
C       Determine the first and last loop indices
515
        if (numdat.eq.2) then
790
        if (numdat.eq.2) then
516
          filo = nint(tst/ts)+1
791
          filo = nint(tst/ts)+1
517
          lalo = nint((timeinc-ten)/ts) 
792
          lalo = nint((timeinc-ten)/ts) 
518
        elseif ( itm.eq.1 ) then
793
        elseif ( itm.eq.1 ) then
519
          filo = nint(tst/ts)+1
794
          filo = nint(tst/ts)+1
520
          lalo = nint(timeinc/ts)
795
          lalo = nint(timeinc/ts)
521
        else if (itm.eq.numdat-1) then
796
        else if (itm.eq.numdat-1) then
522
          filo = 1
797
          filo = 1
523
          lalo = nint((timeinc-ten)/ts)
798
          lalo = nint((timeinc-ten)/ts)
524
        else
799
        else
525
          filo = 1
800
          filo = 1
526
          lalo = nint(timeinc/ts)
801
          lalo = nint(timeinc/ts)
527
        endif
802
        endif
528
 
803
 
529
c       Split the interval <timeinc> into computational time steps <ts>
804
c       Split the interval <timeinc> into computational time steps <ts>
530
        do iloop=filo,lalo
805
        do iloop=filo,lalo
531
 
806
 
532
C         Calculate relative time position in the interval timeinc (0=beginning, 1=end)
807
C         Calculate relative time position in the interval timeinc (0=beginning, 1=end)
533
          reltpos0 = ((real(iloop)-1.)*ts)/timeinc
808
          reltpos0 = ((real(iloop)-1.)*ts)/timeinc
534
          reltpos1 = real(iloop)*ts/timeinc
809
          reltpos1 = real(iloop)*ts/timeinc
535
 
810
 
536
c         Timestep for all trajectories
811
c         Timestep for all trajectories
537
          do i=1,ntra
812
          do i=1,ntra
538
 
813
 
539
C           Check if trajectory has already left the data domain
814
C           Check if trajectory has already left the data domain
540
            if (leftflag(i).ne.1) then	
815
            if (leftflag(i).ne.1) then	
541
 
816
 
542
c             Iterative Euler timestep (x0,y0,p0 -> x1,y1,p1)
817
c             3D: Iterative Euler timestep (x0,y0,p0 -> x1,y1,p1)
543
              if (imethod.eq.1) then
818
              if ( (imethod.eq.1   ).and.
-
 
819
     >             (isen   .eq.'no').and.
-
 
820
     >             (modlev .eq.'no') )
-
 
821
     >        then
544
                 call euler(
822
                 call euler_3d(
545
     >               xx1,yy1,pp1,leftflag(i),
823
     >               xx1,yy1,pp1,leftflag(i),
546
     >               xx0(i),yy0(i),pp0(i),reltpos0,reltpos1,
824
     >               xx0(i),yy0(i),pp0(i),reltpos0,reltpos1,
547
     >               ts*3600,numit,jflag,mdv,wfactor,fbflag,
825
     >               ts*3600,numit,jflag,mdv,wfactor,fbflag,
548
     >               spt0,spt1,p3t0,p3t1,uut0,uut1,vvt0,vvt1,wwt0,wwt1,
826
     >               spt0,spt1,p3t0,p3t1,uut0,uut1,vvt0,vvt1,wwt0,wwt1,
549
     >               xmin,ymin,dx,dy,per,hem,nx,ny,nz)
827
     >               xmin,ymin,dx,dy,per,hem,nx,ny,nz)
550
 
828
 
551
c             Runge-Kutta timestep (x0,y0,p0 -> x1,y1,p1)
829
c             3D: Runge-Kutta timestep (x0,y0,p0 -> x1,y1,p1)
552
              else if (imethod.eq.2) then
830
              else if ( (imethod.eq.2   ).and.
-
 
831
     >                  (isen   .eq.'no').and.
-
 
832
     >                  (modlev .eq.'no') )
-
 
833
     >        then
553
                 call runge(
834
                 call runge(
554
     >               xx1,yy1,pp1,leftflag(i),
835
     >               xx1,yy1,pp1,leftflag(i),
555
     >               xx0(i),yy0(i),pp0(i),reltpos0,reltpos1,
836
     >               xx0(i),yy0(i),pp0(i),reltpos0,reltpos1,
556
     >               ts*3600,numit,jflag,mdv,wfactor,fbflag,
837
     >               ts*3600,numit,jflag,mdv,wfactor,fbflag,
557
     >               spt0,spt1,p3t0,p3t1,uut0,uut1,vvt0,vvt1,wwt0,wwt1,
838
     >               spt0,spt1,p3t0,p3t1,uut0,uut1,vvt0,vvt1,wwt0,wwt1,
558
     >               xmin,ymin,dx,dy,per,hem,nx,ny,nz)
839
     >               xmin,ymin,dx,dy,per,hem,nx,ny,nz)
559
 
840
 
-
 
841
c             ISENTROPIC: Iterative Euler timestep (x0,y0,p0 -> x1,y1,p1)
-
 
842
              else if ( (imethod.eq.1    ).and.
-
 
843
     >                  (isen   .eq.'yes').and.
-
 
844
     >                  (modlev .eq.'no' ) )
-
 
845
     >        then
-
 
846
                 call euler_isen(
-
 
847
     >               xx1,yy1,pp1,leftflag(i),
-
 
848
     >               xx0(i),yy0(i),pp0(i),theta(i),reltpos0,reltpos1,
-
 
849
     >               ts*3600,numit,jflag,mdv,wfactor,fbflag,
-
 
850
     >               spt0,spt1,p3t0,p3t1,uut0,uut1,vvt0,vvt1,
-
 
851
     >               sth0,sth1,tht0,tht1,
-
 
852
     >               xmin,ymin,dx,dy,per,hem,nx,ny,nz)
-
 
853
 
-
 
854
c             MODEL-LEVEL (2D): Iterative Euler timestep (x0,y0,p0 -> x1,y1,p1)
-
 
855
              else if ( (imethod.eq.1    ).and.
-
 
856
     >                  (isen   .eq.'no' ).and.
-
 
857
     >                  (modlev .eq.'yes') )
-
 
858
     >        then
-
 
859
                 call euler_2d(
-
 
860
     >               xx1,yy1,pp1,leftflag(i),
-
 
861
     >               xx0(i),yy0(i),pp0(i),zindex(i),reltpos0,reltpos1,
-
 
862
     >               ts*3600,numit,jflag,mdv,wfactor,fbflag,
-
 
863
     >               spt0,spt1,p3t0,p3t1,uut0,uut1,vvt0,vvt1,
-
 
864
     >               xmin,ymin,dx,dy,per,hem,nx,ny,nz)
-
 
865
 
560
              endif
866
              endif
561
 
867
 
562
c             Update trajectory position, or increase number of trajectories leaving domain
868
c             Update trajectory position, or increase number of trajectories leaving domain
563
              if (leftflag(i).eq.1) then
869
              if (leftflag(i).eq.1) then
564
                leftcount=leftcount+1
870
                leftcount=leftcount+1
565
                if ( leftcount.lt.10 ) then
871
                if ( leftcount.lt.10 ) then
566
                   print*,'     -> Trajectory ',i,' leaves domain'
872
                   print*,'     -> Trajectory ',i,' leaves domain'
567
                elseif ( leftcount.eq.10 ) then
873
                elseif ( leftcount.eq.10 ) then
568
                   print*,'     -> N>=10 trajectories leave domain'
874
                   print*,'     -> N>=10 trajectories leave domain'
569
                endif
875
                endif
570
              else
876
              else
571
                xx0(i)=xx1      
877
                xx0(i)=xx1      
572
                yy0(i)=yy1
878
                yy0(i)=yy1
573
                pp0(i)=pp1
879
                pp0(i)=pp1
574
              endif
880
              endif
575
 
881
 
576
c          Trajectory has already left data domain (mark as <mdv>)
882
c          Trajectory has already left data domain (mark as <mdv>)
577
           else
883
           else
578
              xx0(i)=mdv
884
              xx0(i)=mdv
579
              yy0(i)=mdv
885
              yy0(i)=mdv
580
              pp0(i)=mdv
886
              pp0(i)=mdv
581
              
887
              
582
           endif
888
           endif
583
 
889
 
584
          enddo
890
          enddo
585
 
891
 
586
C         Save positions only every deltout minutes
892
C         Save positions only every deltout minutes
587
          delta = aint(iloop*60*ts/deltout)-iloop*60*ts/deltout
893
          delta = aint(iloop*60*ts/deltout)-iloop*60*ts/deltout
588
          if (abs(delta).lt.eps) then
894
          if (abs(delta).lt.eps) then
589
c          wstep = wstep + abs(ts)
895
c          wstep = wstep + abs(ts)
590
c          if ( mod(wstep,deltout).eq.0 ) then
896
c          if ( mod(wstep,deltout).eq.0 ) then
591
            time = time0+reltpos1*timeinc*fbflag
897
            time = time0+reltpos1*timeinc*fbflag
592
            itim = itim + 1
898
            itim = itim + 1
593
            if ( itim.le.ntim ) then
899
            if ( itim.le.ntim ) then
594
              do i=1,ntra
900
              do i=1,ntra
595
                 call frac2hhmm(time,tload)
901
                 call frac2hhmm(time,tload)
596
                 traout(i,itim,1) = tload
902
                 traout(i,itim,1) = tload
597
                 traout(i,itim,2) = xx0(i)
903
                 traout(i,itim,2) = xx0(i)
598
                 traout(i,itim,3) = yy0(i)
904
                 traout(i,itim,3) = yy0(i)
599
                 traout(i,itim,4) = pp0(i)
905
                 traout(i,itim,4) = pp0(i)
600
              enddo
906
              enddo
601
            endif
907
            endif
602
          endif
908
          endif
603
 
909
 
604
        enddo
910
        enddo
605
 
911
 
606
      enddo
912
      enddo
607
 
913
 
608
      print*,(traout(1,1,i),i=1,4)
-
 
609
 
-
 
610
c     Write trajectory file
914
c     Write trajectory file
611
      vars(1)  ='time'
915
      vars(1)  ='time'
612
      vars(2)  ='lon'
916
      vars(2)  ='lon'
613
      vars(3)  ='lat'
917
      vars(3)  ='lat'
614
      vars(4)  ='p'
918
      vars(4)  ='p'
615
      call wopen_tra(cdfid,cdfname,ntra,ntim,4,reftime,vars,outmode)
919
      call wopen_tra(cdfid,cdfname,ntra,ntim,4,reftime,vars,outmode)
616
      call write_tra(cdfid,traout,ntra,ntim,4,outmode)
920
      call write_tra(cdfid,traout,ntra,ntim,4,outmode)
617
      call close_tra(cdfid,outmode)   
921
      call close_tra(cdfid,outmode)   
618
 
922
 
619
c     Write some status information, and end of program message
923
c     Write some status information, and end of program message
620
      print*  
924
      print*  
621
      print*,'---- STATUS INFORMATION --------------------------------'
925
      print*,'---- STATUS INFORMATION --------------------------------'
622
      print*
926
      print*
623
      print*,'  #leaving domain    ', leftcount
927
      print*,'  #leaving domain    ', leftcount
624
      print*,'  #staying in domain ', ntra-leftcount
928
      print*,'  #staying in domain ', ntra-leftcount
625
      print*
929
      print*
626
      print*,'              *** END OF PROGRAM CALTRA ***'
930
      print*,'              *** END OF PROGRAM CALTRA ***'
627
      print*,'========================================================='
931
      print*,'========================================================='
628
 
932
 
629
      stop
933
      stop
630
 
934
 
631
c     ------------------------------------------------------------------
935
c     ------------------------------------------------------------------
632
c     Exception handling
936
c     Exception handling
633
c     ------------------------------------------------------------------
937
c     ------------------------------------------------------------------
634
 
938
 
635
 991  write(*,*) '*** ERROR: all start points outside the data domain'
939
 991  write(*,*) '*** ERROR: all start points outside the data domain'
636
      call exit(1)
940
      call exit(1)
637
      
941
      
638
 992  write(*,*) '*** ERROR: close arrays on files (prog. closear)'
942
 992  write(*,*) '*** ERROR: close arrays on files (prog. closear)'
639
      call exit(1)
943
      call exit(1)
640
 
944
 
641
 993  write(*,*) '*** ERROR: problems with array size'
945
 993  write(*,*) '*** ERROR: problems with array size'
642
      call exit(1)
946
      call exit(1)
643
 
947
 
644
      end 
948
      end 
645
 
949
 
646
 
950
 
647
c     *******************************************************************
951
c     *******************************************************************
648
c     * Time step : either Euler or Runge-Kutta                         *
952
c     * Time step : either Euler or Runge-Kutta                         *
649
c     *******************************************************************
953
c     *******************************************************************
650
 
954
 
651
C     Time-step from (x0,y0,p0) to (x1,y1,p1)
955
C     Time-step from (x0,y0,p0) to (x1,y1,p1)
652
C
956
C
653
C     (x0,y0,p0) input	coordinates (long,lat,p) for starting point
957
C     (x0,y0,p0) input	coordinates (long,lat,p) for starting point
654
C     (x1,y1,p1) output	coordinates (long,lat,p) for end point
958
C     (x1,y1,p1) output	coordinates (long,lat,p) for end point
655
C     deltat	 input	timestep in seconds
959
C     deltat	 input	timestep in seconds
656
C     numit	 input	number of iterations
960
C     numit	 input	number of iterations
657
C     jump	 input  flag (=1 trajectories don't enter the ground)
961
C     jump	 input  flag (=1 trajectories don't enter the ground)
658
C     left	 output	flag (=1 if trajectory leaves data domain)
962
C     left	 output	flag (=1 if trajectory leaves data domain)
659
 
963
 
660
c     -------------------------------------------------------------------
964
c     -------------------------------------------------------------------
661
c     Iterative Euler time step
965
c     Iterative Euler time step (KINEMATIC 3D TRAJECTORIES)
662
c     -------------------------------------------------------------------
966
c     -------------------------------------------------------------------
663
 
967
 
664
      subroutine euler(x1,y1,p1,left,x0,y0,p0,reltpos0,reltpos1,
968
      subroutine euler_3d(x1,y1,p1,left,x0,y0,p0,reltpos0,reltpos1,
665
     >                 deltat,numit,jump,mdv,wfactor,fbflag,
969
     >                deltat,numit,jump,mdv,wfactor,fbflag,
666
     >		       spt0,spt1,p3d0,p3d1,uut0,uut1,vvt0,vvt1,wwt0,wwt1,
970
     >		          spt0,spt1,p3d0,p3d1,uut0,uut1,vvt0,vvt1,wwt0,wwt1,
667
     >                 xmin,ymin,dx,dy,per,hem,nx,ny,nz)
971
     >                xmin,ymin,dx,dy,per,hem,nx,ny,nz)
668
 
972
 
669
      implicit none
973
      implicit none
670
 
974
 
671
c     Declaration of subroutine parameters
975
c     Declaration of subroutine parameters
672
      integer      nx,ny,nz
976
      integer      nx,ny,nz
673
      real         x1,y1,p1
977
      real         x1,y1,p1
674
      integer      left
978
      integer      left
675
      real	   x0,y0,p0
979
      real	   x0,y0,p0
676
      real         reltpos0,reltpos1
980
      real         reltpos0,reltpos1
677
      real   	   deltat
981
      real   	   deltat
678
      integer      numit
982
      integer      numit
679
      integer      jump
983
      integer      jump
680
      real         wfactor
984
      real         wfactor
681
      integer      fbflag
985
      integer      fbflag
682
      real     	   spt0(nx*ny)   ,spt1(nx*ny)
986
      real     	   spt0(nx*ny)   ,spt1(nx*ny)
683
      real         uut0(nx*ny*nz),uut1(nx*ny*nz)
987
      real         uut0(nx*ny*nz),uut1(nx*ny*nz)
684
      real 	   vvt0(nx*ny*nz),vvt1(nx*ny*nz)
988
      real 	   vvt0(nx*ny*nz),vvt1(nx*ny*nz)
685
      real         wwt0(nx*ny*nz),wwt1(nx*ny*nz)
989
      real         wwt0(nx*ny*nz),wwt1(nx*ny*nz)
686
      real         p3d0(nx*ny*nz),p3d1(nx*ny*nz)
990
      real         p3d0(nx*ny*nz),p3d1(nx*ny*nz)
687
      real         xmin,ymin,dx,dy
991
      real         xmin,ymin,dx,dy
688
      real         per
992
      real         per
689
      integer      hem
993
      integer      hem
690
      real         mdv
994
      real         mdv
691
 
995
 
692
c     Numerical and physical constants
996
c     Numerical and physical constants
693
      real         deltay
997
      real         deltay
694
      parameter    (deltay=1.112E5)  ! Distance in m between 2 lat circles
998
      parameter    (deltay=1.112E5)  ! Distance in m between 2 lat circles
695
      real         pi                       
999
      real         pi                       
696
      parameter    (pi=3.1415927)    ! Pi
1000
      parameter    (pi=3.1415927)    ! Pi
697
 
1001
 
698
c     Auxiliary variables
1002
c     Auxiliary variables
699
      real         xmax,ymax
1003
      real         xmax,ymax
700
      real	   xind,yind,pind
1004
      real	   xind,yind,pind
701
      real	   u0,v0,w0,u1,v1,w1,u,v,w,sp
1005
      real	   u0,v0,w0,u1,v1,w1,u,v,w,sp
702
      integer	   icount
1006
      integer	   icount
703
      character    ch
1007
      character    ch
704
 
1008
 
705
c     Externals    
1009
c     Externals    
706
      real         int_index4
1010
      real         int_index4
707
      external     int_index4
1011
      external     int_index4
708
 
1012
 
709
c     Reset the flag for domain-leaving
1013
c     Reset the flag for domain-leaving
710
      left=0
1014
      left=0
711
 
1015
 
712
c     Set the esat-north bounray of the domain
1016
c     Set the esat-north bounray of the domain
713
      xmax = xmin+real(nx-1)*dx
1017
      xmax = xmin+real(nx-1)*dx
714
      ymax = ymin+real(ny-1)*dy
1018
      ymax = ymin+real(ny-1)*dy
715
 
1019
 
716
C     Interpolate wind fields to starting position (x0,y0,p0)
1020
C     Interpolate wind fields to starting position (x0,y0,p0)
717
      call get_index4 (xind,yind,pind,x0,y0,p0,reltpos0,
1021
      call get_index4 (xind,yind,pind,x0,y0,p0,reltpos0,
718
     >                 p3d0,p3d1,spt0,spt1,3,
1022
     >                 p3d0,p3d1,spt0,spt1,3,
719
     >                 nx,ny,nz,xmin,ymin,dx,dy,mdv)
1023
     >                 nx,ny,nz,xmin,ymin,dx,dy,mdv)
720
      u0 = int_index4(uut0,uut1,nx,ny,nz,xind,yind,pind,reltpos0,mdv)
1024
      u0 = int_index4(uut0,uut1,nx,ny,nz,xind,yind,pind,reltpos0,mdv)
721
      v0 = int_index4(vvt0,vvt1,nx,ny,nz,xind,yind,pind,reltpos0,mdv)
1025
      v0 = int_index4(vvt0,vvt1,nx,ny,nz,xind,yind,pind,reltpos0,mdv)
722
      w0 = int_index4(wwt0,wwt1,nx,ny,nz,xind,yind,pind,reltpos0,mdv)
1026
      w0 = int_index4(wwt0,wwt1,nx,ny,nz,xind,yind,pind,reltpos0,mdv)
723
 
1027
 
724
c     Force the near-surface wind to zero
1028
c     Force the near-surface wind to zero
725
      if (pind.lt.1.) w0=w0*pind
1029
      if (pind.lt.1.) w0=w0*pind
726
 
1030
 
727
C     For first iteration take ending position equal to starting position
1031
C     For first iteration take ending position equal to starting position
728
      x1=x0
1032
      x1=x0
729
      y1=y0
1033
      y1=y0
730
      p1=p0
1034
      p1=p0
731
 
1035
 
732
C     Iterative calculation of new position
1036
C     Iterative calculation of new position
733
      do icount=1,numit
1037
      do icount=1,numit
734
 
1038
 
735
C        Calculate new winds for advection
1039
C        Calculate new winds for advection
736
         call get_index4 (xind,yind,pind,x1,y1,p1,reltpos1,
1040
         call get_index4 (xind,yind,pind,x1,y1,p1,reltpos1,
737
     >                    p3d0,p3d1,spt0,spt1,3,
1041
     >                    p3d0,p3d1,spt0,spt1,3,
738
     >                    nx,ny,nz,xmin,ymin,dx,dy,mdv)
1042
     >                    nx,ny,nz,xmin,ymin,dx,dy,mdv)
739
         u1 = int_index4(uut0,uut1,nx,ny,nz,xind,yind,pind,reltpos1,mdv)
1043
         u1 = int_index4(uut0,uut1,nx,ny,nz,xind,yind,pind,reltpos1,mdv)
740
         v1 = int_index4(vvt0,vvt1,nx,ny,nz,xind,yind,pind,reltpos1,mdv)
1044
         v1 = int_index4(vvt0,vvt1,nx,ny,nz,xind,yind,pind,reltpos1,mdv)
741
         w1 = int_index4(wwt0,wwt1,nx,ny,nz,xind,yind,pind,reltpos1,mdv)
1045
         w1 = int_index4(wwt0,wwt1,nx,ny,nz,xind,yind,pind,reltpos1,mdv)
742
 
1046
 
743
c        Force the near-surface wind to zero
1047
c        Force the near-surface wind to zero
744
         if (pind.lt.1.) w1=w1*pind
1048
         if (pind.lt.1.) w1=w1*pind
745
 
1049
 
746
c        Get the new velocity in between
1050
c        Get the new velocity in between
747
         u=(u0+u1)/2.
1051
         u=(u0+u1)/2.
748
         v=(v0+v1)/2.
1052
         v=(v0+v1)/2.
749
         w=(w0+w1)/2.
1053
         w=(w0+w1)/2.
750
         
1054
         
751
C        Calculate new positions
1055
C        Calculate new positions
752
         x1 = x0 + fbflag*u*deltat/(deltay*cos(y0*pi/180.))
1056
         x1 = x0 + fbflag*u*deltat/(deltay*cos(y0*pi/180.))
753
         y1 = y0 + fbflag*v*deltat/deltay
1057
         y1 = y0 + fbflag*v*deltat/deltay
754
         p1 = p0 + fbflag*wfactor*w*deltat/100.
1058
         p1 = p0 + fbflag*wfactor*w*deltat/100.
755
 
1059
 
756
c       Handle pole problems (crossing and near pole trajectory)
1060
c       Handle pole problems (crossing and near pole trajectory)
757
        if ((hem.eq.1).and.(y1.gt.90.)) then
1061
        if ((hem.eq.1).and.(y1.gt.90.)) then
758
          y1=180.-y1
1062
          y1=180.-y1
759
          x1=x1+per/2.
1063
          x1=x1+per/2.
760
        endif
1064
        endif
761
        if ((hem.eq.1).and.(y1.lt.-90.)) then
1065
        if ((hem.eq.1).and.(y1.lt.-90.)) then
762
          y1=-180.-y1
1066
          y1=-180.-y1
763
          x1=x1+per/2.
1067
          x1=x1+per/2.
764
        endif
1068
        endif
765
        if (y1.gt.89.99) then
1069
        if (y1.gt.89.99) then
766
           y1=89.99
1070
           y1=89.99
767
        endif
1071
        endif
768
 
1072
 
769
c       Handle crossings of the dateline
1073
c       Handle crossings of the dateline
770
        if ((hem.eq.1).and.(x1.gt.xmin+per-dx)) then
1074
        if ((hem.eq.1).and.(x1.gt.xmin+per-dx)) then
771
           x1=xmin+amod(x1-xmin,per)
1075
           x1=xmin+amod(x1-xmin,per)
772
        endif
1076
        endif
773
        if ((hem.eq.1).and.(x1.lt.xmin)) then
1077
        if ((hem.eq.1).and.(x1.lt.xmin)) then
774
           x1=xmin+per+amod(x1-xmin,per)
1078
           x1=xmin+per+amod(x1-xmin,per)
775
        endif
1079
        endif
776
 
1080
 
777
C       Interpolate surface pressure to actual position
1081
C       Interpolate surface pressure to actual position
778
        call get_index4 (xind,yind,pind,x1,y1,1050.,reltpos1,
1082
        call get_index4 (xind,yind,pind,x1,y1,1050.,reltpos1,
779
     >                   p3d0,p3d1,spt0,spt1,3,
1083
     >                   p3d0,p3d1,spt0,spt1,3,
780
     >                   nx,ny,nz,xmin,ymin,dx,dy,mdv)
1084
     >                   nx,ny,nz,xmin,ymin,dx,dy,mdv)
781
        sp = int_index4 (spt0,spt1,nx,ny,1,xind,yind,1.,reltpos1,mdv)
1085
        sp = int_index4 (spt0,spt1,nx,ny,1,xind,yind,1.,reltpos1,mdv)
782
 
1086
 
783
c       Handle trajectories which cross the lower boundary (jump flag)
1087
c       Handle trajectories which cross the lower boundary (jump flag)
784
        if ((jump.eq.1).and.(p1.gt.sp)) p1=sp-10.
1088
        if ((jump.eq.1).and.(p1.gt.sp)) p1=sp-10.
785
 
1089
 
786
C       Check if trajectory leaves data domain
1090
C       Check if trajectory leaves data domain
-
 
1091
        if ( ( (hem.eq.0).and.(x1.lt.xmin)    ).or.
-
 
1092
     >       ( (hem.eq.0).and.(x1.gt.xmax-dx) ).or.
-
 
1093
     >         (y1.lt.ymin).or.(y1.gt.ymax).or.(p1.gt.sp) )
-
 
1094
     >  then
-
 
1095
          left=1
-
 
1096
          goto 100
-
 
1097
        endif
-
 
1098
 
-
 
1099
      enddo
-
 
1100
 
-
 
1101
c     Exit point for subroutine
-
 
1102
 100  continue
-
 
1103
 
-
 
1104
      return
-
 
1105
 
-
 
1106
      end
-
 
1107
 
-
 
1108
c     -------------------------------------------------------------------
-
 
1109
c     Iterative Euler time step (ISENTROPIC)
-
 
1110
c     -------------------------------------------------------------------
-
 
1111
 
-
 
1112
      subroutine euler_isen(x1,y1,p1,left,x0,y0,p0,theta,
-
 
1113
     >                reltpos0,reltpos1,
-
 
1114
     >                deltat,numit,jump,mdv,wfactor,fbflag,
-
 
1115
     >                spt0,spt1,p3d0,p3d1,uut0,uut1,vvt0,vvt1,
-
 
1116
     >                sth0,sth1,tht0,tht1,
-
 
1117
     >                xmin,ymin,dx,dy,per,hem,nx,ny,nz)
-
 
1118
 
-
 
1119
      implicit none
-
 
1120
 
-
 
1121
c     Declaration of subroutine parameters
-
 
1122
      integer      nx,ny,nz
-
 
1123
      real         x1,y1,p1
-
 
1124
      integer      left
-
 
1125
      real         x0,y0,p0
-
 
1126
      real         reltpos0,reltpos1
-
 
1127
      real         deltat
-
 
1128
      integer      numit
-
 
1129
      integer      jump
-
 
1130
      real         wfactor
-
 
1131
      integer      fbflag
-
 
1132
      real         spt0(nx*ny)   ,spt1(nx*ny)
-
 
1133
      real         sth0(nx*ny)   ,sth1(nx*ny)
-
 
1134
      real         uut0(nx*ny*nz),uut1(nx*ny*nz)
-
 
1135
      real         vvt0(nx*ny*nz),vvt1(nx*ny*nz)
-
 
1136
      real         p3d0(nx*ny*nz),p3d1(nx*ny*nz)
-
 
1137
      real         tht0(nx*ny*nz),tht1(nx*ny*nz)
-
 
1138
      real         xmin,ymin,dx,dy
-
 
1139
      real         per
-
 
1140
      integer      hem
-
 
1141
      real         mdv
-
 
1142
      real         theta
-
 
1143
 
-
 
1144
c     Numerical and physical constants
-
 
1145
      real         deltay
-
 
1146
      parameter    (deltay=1.112E5)  ! Distance in m between 2 lat circles
-
 
1147
      real         pi
-
 
1148
      parameter    (pi=3.1415927)    ! Pi
-
 
1149
 
-
 
1150
c     Auxiliary variables
-
 
1151
      real         xmax,ymax
-
 
1152
      real         xind,yind,pind
-
 
1153
      real         u0,v0,w0,u1,v1,w1,u,v,w,sp
-
 
1154
      integer      icount
-
 
1155
      character    ch
-
 
1156
 
-
 
1157
c     Externals
-
 
1158
      real         int_index4
-
 
1159
      external     int_index4
-
 
1160
 
-
 
1161
c     Reset the flag for domain-leaving
-
 
1162
      left=0
-
 
1163
 
-
 
1164
c     Set the esat-north bounray of the domain
-
 
1165
      xmax = xmin+real(nx-1)*dx
-
 
1166
      ymax = ymin+real(ny-1)*dy
-
 
1167
 
-
 
1168
C     Interpolate wind fields to starting position (x0,y0,p0)
-
 
1169
      call get_index4 (xind,yind,pind,x0,y0,p0,reltpos0,
-
 
1170
     >                 p3d0,p3d1,spt0,spt1,3,
-
 
1171
     >                 nx,ny,nz,xmin,ymin,dx,dy,mdv)
-
 
1172
      u0 = int_index4(uut0,uut1,nx,ny,nz,xind,yind,pind,reltpos0,mdv)
-
 
1173
      v0 = int_index4(vvt0,vvt1,nx,ny,nz,xind,yind,pind,reltpos0,mdv)
-
 
1174
 
-
 
1175
C     For first iteration take ending position equal to starting position
-
 
1176
      x1=x0
-
 
1177
      y1=y0
-
 
1178
      p1=p0
-
 
1179
 
-
 
1180
C     Iterative calculation of new position
-
 
1181
      do icount=1,numit
-
 
1182
 
-
 
1183
C        Calculate new winds for advection
-
 
1184
         call get_index4 (xind,yind,pind,x1,y1,p1,reltpos1,
-
 
1185
     >                    p3d0,p3d1,spt0,spt1,3,
-
 
1186
     >                    nx,ny,nz,xmin,ymin,dx,dy,mdv)
-
 
1187
         u1 = int_index4(uut0,uut1,nx,ny,nz,xind,yind,pind,reltpos1,mdv)
-
 
1188
         v1 = int_index4(vvt0,vvt1,nx,ny,nz,xind,yind,pind,reltpos1,mdv)
-
 
1189
 
-
 
1190
c        Get the new velocity in between
-
 
1191
         u=(u0+u1)/2.
-
 
1192
         v=(v0+v1)/2.
-
 
1193
 
-
 
1194
C        Calculate new positions
-
 
1195
         x1 = x0 + fbflag*u*deltat/(deltay*cos(y0*pi/180.))
-
 
1196
         y1 = y0 + fbflag*v*deltat/deltay
-
 
1197
 
-
 
1198
c        Get the pressure on the isentropic surface at the new position
-
 
1199
         call get_index4 (xind,yind,pind,x1,y1,theta,reltpos1,
-
 
1200
     >                    tht0,tht1,sth0,sth1,1,
-
 
1201
     >                    nx,ny,nz,xmin,ymin,dx,dy,mdv)
-
 
1202
         p1 = int_index4(p3d0,p3d1,nx,ny,nz,xind,yind,pind,reltpos1,mdv)
-
 
1203
 
-
 
1204
c       Handle pole problems (crossing and near pole trajectory)
-
 
1205
        if ((hem.eq.1).and.(y1.gt.90.)) then
-
 
1206
          y1=180.-y1
-
 
1207
          x1=x1+per/2.
-
 
1208
        endif
-
 
1209
        if ((hem.eq.1).and.(y1.lt.-90.)) then
-
 
1210
          y1=-180.-y1
-
 
1211
          x1=x1+per/2.
-
 
1212
        endif
-
 
1213
        if (y1.gt.89.99) then
-
 
1214
           y1=89.99
-
 
1215
        endif
-
 
1216
 
-
 
1217
c       Handle crossings of the dateline
-
 
1218
        if ((hem.eq.1).and.(x1.gt.xmin+per-dx)) then
-
 
1219
           x1=xmin+amod(x1-xmin,per)
-
 
1220
        endif
-
 
1221
        if ((hem.eq.1).and.(x1.lt.xmin)) then
-
 
1222
           x1=xmin+per+amod(x1-xmin,per)
-
 
1223
        endif
-
 
1224
 
-
 
1225
C       Interpolate surface pressure to actual position
-
 
1226
        call get_index4 (xind,yind,pind,x1,y1,1050.,reltpos1,
-
 
1227
     >                   p3d0,p3d1,spt0,spt1,3,
-
 
1228
     >                   nx,ny,nz,xmin,ymin,dx,dy,mdv)
-
 
1229
        sp = int_index4 (spt0,spt1,nx,ny,1,xind,yind,1.,reltpos1,mdv)
-
 
1230
 
-
 
1231
c       Handle trajectories which cross the lower boundary (jump flag)
-
 
1232
        if ((jump.eq.1).and.(p1.gt.sp)) p1=sp-10.
-
 
1233
 
-
 
1234
C       Check if trajectory leaves data domain
-
 
1235
        if ( ( (hem.eq.0).and.(x1.lt.xmin)    ).or.
-
 
1236
     >       ( (hem.eq.0).and.(x1.gt.xmax-dx) ).or.
-
 
1237
     >         (y1.lt.ymin).or.(y1.gt.ymax).or.(p1.gt.sp) )
-
 
1238
     >  then
-
 
1239
          left=1
-
 
1240
          goto 100
-
 
1241
        endif
-
 
1242
 
-
 
1243
      enddo
-
 
1244
 
-
 
1245
c     Exit point for subroutine
-
 
1246
 100  continue
-
 
1247
 
-
 
1248
      return
-
 
1249
 
-
 
1250
      end
-
 
1251
 
-
 
1252
c     -------------------------------------------------------------------
-
 
1253
c     Iterative Euler time step (MODEL-LEVEL, 2D)
-
 
1254
c     -------------------------------------------------------------------
-
 
1255
 
-
 
1256
      subroutine euler_2d(x1,y1,p1,left,x0,y0,p0,zindex,
-
 
1257
     >                reltpos0,reltpos1,
-
 
1258
     >                deltat,numit,jump,mdv,wfactor,fbflag,
-
 
1259
     >                spt0,spt1,p3d0,p3d1,uut0,uut1,vvt0,vvt1,
-
 
1260
     >                xmin,ymin,dx,dy,per,hem,nx,ny,nz)
-
 
1261
 
-
 
1262
      implicit none
-
 
1263
 
-
 
1264
c     Declaration of subroutine parameters
-
 
1265
      integer      nx,ny,nz
-
 
1266
      real         x1,y1,p1
-
 
1267
      integer      left
-
 
1268
      real         x0,y0,p0
-
 
1269
      real         reltpos0,reltpos1
-
 
1270
      real         deltat
-
 
1271
      integer      numit
-
 
1272
      integer      jump
-
 
1273
      real         wfactor
-
 
1274
      integer      fbflag
-
 
1275
      real         spt0(nx*ny)   ,spt1(nx*ny)
-
 
1276
      real         uut0(nx*ny*nz),uut1(nx*ny*nz)
-
 
1277
      real         vvt0(nx*ny*nz),vvt1(nx*ny*nz)
-
 
1278
      real         p3d0(nx*ny*nz),p3d1(nx*ny*nz)
-
 
1279
      real         xmin,ymin,dx,dy
-
 
1280
      real         per
-
 
1281
      integer      hem
-
 
1282
      real         mdv
-
 
1283
      real         zindex
-
 
1284
 
-
 
1285
c     Numerical and physical constants
-
 
1286
      real         deltay
-
 
1287
      parameter    (deltay=1.112E5)  ! Distance in m between 2 lat circles
-
 
1288
      real         pi
-
 
1289
      parameter    (pi=3.1415927)    ! Pi
-
 
1290
      real         eps
-
 
1291
      parameter    (eps=0.001)
-
 
1292
 
-
 
1293
c     Auxiliary variables
-
 
1294
      real         xmax,ymax
-
 
1295
      real         xind,yind,pind
-
 
1296
      real         u0,v0,w0,u1,v1,w1,u,v,w,sp
-
 
1297
      integer      icount
-
 
1298
      character    ch
-
 
1299
 
-
 
1300
c     Externals
-
 
1301
      real         int_index4
-
 
1302
      external     int_index4
-
 
1303
 
-
 
1304
c     Reset the flag for domain-leaving
-
 
1305
      left=0
-
 
1306
 
-
 
1307
c     Set the esat-north bounray of the domain
-
 
1308
      xmax = xmin+real(nx-1)*dx
-
 
1309
      ymax = ymin+real(ny-1)*dy
-
 
1310
 
-
 
1311
C     Interpolate wind fields to starting position (x0,y0,p0)
-
 
1312
      call get_index4 (xind,yind,pind,x0,y0,p0,reltpos0,
-
 
1313
     >                 p3d0,p3d1,spt0,spt1,3,
-
 
1314
     >                 nx,ny,nz,xmin,ymin,dx,dy,mdv)
-
 
1315
      u0 = int_index4(uut0,uut1,nx,ny,nz,xind,yind,zindex,reltpos0,mdv)
-
 
1316
      v0 = int_index4(vvt0,vvt1,nx,ny,nz,xind,yind,zindex,reltpos0,mdv)
-
 
1317
 
-
 
1318
C     For first iteration take ending position equal to starting position
-
 
1319
      x1=x0
-
 
1320
      y1=y0
-
 
1321
      p1=p0
-
 
1322
 
-
 
1323
C     Iterative calculation of new position
-
 
1324
      do icount=1,numit
-
 
1325
 
-
 
1326
C        Calculate new winds for advection
-
 
1327
         call get_index4 (xind,yind,pind,x1,y1,p1,reltpos1,
-
 
1328
     >                    p3d0,p3d1,spt0,spt1,3,
-
 
1329
     >                    nx,ny,nz,xmin,ymin,dx,dy,mdv)
-
 
1330
         u1=int_index4(uut0,uut1,nx,ny,nz,xind,yind,zindex,reltpos1,mdv)
-
 
1331
         v1=int_index4(vvt0,vvt1,nx,ny,nz,xind,yind,zindex,reltpos1,mdv)
-
 
1332
         if ( abs(u1-mdv).lt.eps ) then
-
 
1333
             left = 1
-
 
1334
             goto 100
-
 
1335
         endif
-
 
1336
         if ( abs(v1-mdv).lt.eps ) then
-
 
1337
             left = 1
-
 
1338
             goto 100
-
 
1339
         endif
-
 
1340
 
-
 
1341
c        Get the new velocity in between
-
 
1342
         u=(u0+u1)/2.
-
 
1343
         v=(v0+v1)/2.
-
 
1344
 
-
 
1345
C        Calculate new positions
-
 
1346
         x1 = x0 + fbflag*u*deltat/(deltay*cos(y0*pi/180.))
-
 
1347
         y1 = y0 + fbflag*v*deltat/deltay
-
 
1348
 
-
 
1349
c        Get the pressure on the model surface at the new position
-
 
1350
         xind = (x1 - xmin ) / dx + 1.
-
 
1351
         yind = (y1 - ymin ) / dy + 1.
-
 
1352
         p1 =
-
 
1353
     >     int_index4(p3d0,p3d1,nx,ny,nz,xind,yind,zindex,reltpos1,mdv)
-
 
1354
         if ( abs(p1-mdv).lt.eps ) then
-
 
1355
             left = 1
-
 
1356
             goto 100
-
 
1357
         endif
-
 
1358
 
-
 
1359
c       Handle pole problems (crossing and near pole trajectory)
-
 
1360
        if ((hem.eq.1).and.(y1.gt.90.)) then
-
 
1361
          y1=180.-y1
-
 
1362
          x1=x1+per/2.
-
 
1363
        endif
-
 
1364
        if ((hem.eq.1).and.(y1.lt.-90.)) then
-
 
1365
          y1=-180.-y1
-
 
1366
          x1=x1+per/2.
-
 
1367
        endif
-
 
1368
        if (y1.gt.89.99) then
-
 
1369
           y1=89.99
-
 
1370
        endif
-
 
1371
 
-
 
1372
c       Handle crossings of the dateline
-
 
1373
        if ((hem.eq.1).and.(x1.gt.xmin+per-dx)) then
-
 
1374
           x1=xmin+amod(x1-xmin,per)
-
 
1375
        endif
-
 
1376
        if ((hem.eq.1).and.(x1.lt.xmin)) then
-
 
1377
           x1=xmin+per+amod(x1-xmin,per)
-
 
1378
        endif
-
 
1379
 
-
 
1380
C       Interpolate surface pressure to actual position
-
 
1381
        call get_index4 (xind,yind,pind,x1,y1,1050.,reltpos1,
-
 
1382
     >                   p3d0,p3d1,spt0,spt1,3,
-
 
1383
     >                   nx,ny,nz,xmin,ymin,dx,dy,mdv)
-
 
1384
        sp = int_index4 (spt0,spt1,nx,ny,1,xind,yind,1.,reltpos1,mdv)
-
 
1385
 
-
 
1386
c       Handle trajectories which cross the lower boundary (jump flag)
-
 
1387
        if ((jump.eq.1).and.(p1.gt.sp)) p1=sp-10.
-
 
1388
 
-
 
1389
C       Check if trajectory leaves data domain
787
        if ( ( (hem.eq.0).and.(x1.lt.xmin)    ).or.
1390
        if ( ( (hem.eq.0).and.(x1.lt.xmin)    ).or.
788
     >       ( (hem.eq.0).and.(x1.gt.xmax-dx) ).or.
1391
     >       ( (hem.eq.0).and.(x1.gt.xmax-dx) ).or.
789
     >         (y1.lt.ymin).or.(y1.gt.ymax).or.(p1.gt.sp) )
1392
     >         (y1.lt.ymin).or.(y1.gt.ymax).or.(p1.gt.sp) )
790
     >  then
1393
     >  then
791
          left=1
1394
          left=1
792
          goto 100
1395
          goto 100
793
        endif
1396
        endif
794
 
1397
 
795
      enddo
1398
      enddo
796
 
1399
 
797
c     Exit point for subroutine
1400
c     Exit point for subroutine
798
 100  continue
1401
 100  continue
799
 
1402
 
800
      return
1403
      return
801
 
1404
 
802
      end
1405
      end
803
 
1406
 
804
c     -------------------------------------------------------------------
1407
c     -------------------------------------------------------------------
805
c     Runge-Kutta (4th order) time-step
1408
c     Runge-Kutta (4th order) time-step
806
c     -------------------------------------------------------------------
1409
c     -------------------------------------------------------------------
807
 
1410
 
808
      subroutine runge(x1,y1,p1,left,x0,y0,p0,reltpos0,reltpos1,
1411
      subroutine runge(x1,y1,p1,left,x0,y0,p0,reltpos0,reltpos1,
809
     >                 deltat,numit,jump,mdv,wfactor,fbflag,
1412
     >                 deltat,numit,jump,mdv,wfactor,fbflag,
810
     >		       spt0,spt1,p3d0,p3d1,uut0,uut1,vvt0,vvt1,wwt0,wwt1,
1413
     >		       spt0,spt1,p3d0,p3d1,uut0,uut1,vvt0,vvt1,wwt0,wwt1,
811
     >                 xmin,ymin,dx,dy,per,hem,nx,ny,nz)
1414
     >                 xmin,ymin,dx,dy,per,hem,nx,ny,nz)
812
 
1415
 
813
      implicit none
1416
      implicit none
814
 
1417
 
815
c     Declaration of subroutine parameters
1418
c     Declaration of subroutine parameters
816
      integer      nx,ny,nz
1419
      integer      nx,ny,nz
817
      real         x1,y1,p1
1420
      real         x1,y1,p1
818
      integer      left
1421
      integer      left
819
      real	   x0,y0,p0
1422
      real	   x0,y0,p0
820
      real         reltpos0,reltpos1
1423
      real         reltpos0,reltpos1
821
      real   	   deltat
1424
      real   	   deltat
822
      integer      numit
1425
      integer      numit
823
      integer      jump
1426
      integer      jump
824
      real         wfactor
1427
      real         wfactor
825
      integer      fbflag
1428
      integer      fbflag
826
      real     	   spt0(nx*ny)   ,spt1(nx*ny)
1429
      real     	   spt0(nx*ny)   ,spt1(nx*ny)
827
      real         uut0(nx*ny*nz),uut1(nx*ny*nz)
1430
      real         uut0(nx*ny*nz),uut1(nx*ny*nz)
828
      real 	   vvt0(nx*ny*nz),vvt1(nx*ny*nz)
1431
      real 	   vvt0(nx*ny*nz),vvt1(nx*ny*nz)
829
      real         wwt0(nx*ny*nz),wwt1(nx*ny*nz)
1432
      real         wwt0(nx*ny*nz),wwt1(nx*ny*nz)
830
      real         p3d0(nx*ny*nz),p3d1(nx*ny*nz)
1433
      real         p3d0(nx*ny*nz),p3d1(nx*ny*nz)
831
      real         xmin,ymin,dx,dy
1434
      real         xmin,ymin,dx,dy
832
      real         per
1435
      real         per
833
      integer      hem
1436
      integer      hem
834
      real         mdv
1437
      real         mdv
835
 
1438
 
836
c     Numerical and physical constants
1439
c     Numerical and physical constants
837
      real         deltay
1440
      real         deltay
838
      parameter    (deltay=1.112E5)  ! Distance in m between 2 lat circles
1441
      parameter    (deltay=1.112E5)  ! Distance in m between 2 lat circles
839
      real         pi                       
1442
      real         pi                       
840
      parameter    (pi=3.1415927)    ! Pi
1443
      parameter    (pi=3.1415927)    ! Pi
841
 
1444
 
842
c     Auxiliary variables
1445
c     Auxiliary variables
843
      real         xmax,ymax
1446
      real         xmax,ymax
844
      real	   xind,yind,pind
1447
      real	   xind,yind,pind
845
      real	   u0,v0,w0,u1,v1,w1,u,v,w,sp
1448
      real	   u0,v0,w0,u1,v1,w1,u,v,w,sp
846
      integer	   icount,n
1449
      integer	   icount,n
847
      real         xs,ys,ps,xk(4),yk(4),pk(4)
1450
      real         xs,ys,ps,xk(4),yk(4),pk(4)
848
      real         reltpos
1451
      real         reltpos
849
 
1452
 
850
c     Externals    
1453
c     Externals    
851
      real         int_index4
1454
      real         int_index4
852
      external     int_index4
1455
      external     int_index4
853
 
1456
 
854
c     Reset the flag for domain-leaving
1457
c     Reset the flag for domain-leaving
855
      left=0
1458
      left=0
856
 
1459
 
857
c     Set the esat-north bounray of the domain
1460
c     Set the esat-north bounray of the domain
858
      xmax = xmin+real(nx-1)*dx
1461
      xmax = xmin+real(nx-1)*dx
859
      ymax = ymin+real(ny-1)*dy
1462
      ymax = ymin+real(ny-1)*dy
860
 
1463
 
861
c     Apply the Runge Kutta scheme
1464
c     Apply the Runge Kutta scheme
862
      do n=1,4
1465
      do n=1,4
863
 
1466
 
864
c       Get intermediate position and relative time
1467
c       Get intermediate position and relative time
865
        if (n.eq.1) then
1468
        if (n.eq.1) then
866
          xs=0.
1469
          xs=0.
867
          ys=0.
1470
          ys=0.
868
          ps=0.
1471
          ps=0.
869
          reltpos=reltpos0
1472
          reltpos=reltpos0
870
        else if (n.eq.4) then
1473
        else if (n.eq.4) then
871
          xs=xk(3)
1474
          xs=xk(3)
872
          ys=yk(3)
1475
          ys=yk(3)
873
          ps=pk(3)
1476
          ps=pk(3)
874
          reltpos=reltpos1
1477
          reltpos=reltpos1
875
        else
1478
        else
876
          xs=xk(n-1)/2.
1479
          xs=xk(n-1)/2.
877
          ys=yk(n-1)/2.
1480
          ys=yk(n-1)/2.
878
          ps=pk(n-1)/2.
1481
          ps=pk(n-1)/2.
879
          reltpos=(reltpos0+reltpos1)/2.
1482
          reltpos=(reltpos0+reltpos1)/2.
880
        endif
1483
        endif
881
        
1484
        
882
C       Calculate new winds for advection
1485
C       Calculate new winds for advection
883
        call get_index4 (xind,yind,pind,x0+xs,y0+ys,p0+ps,reltpos,
1486
        call get_index4 (xind,yind,pind,x0+xs,y0+ys,p0+ps,reltpos,
884
     >                   p3d0,p3d1,spt0,spt1,3,
1487
     >                   p3d0,p3d1,spt0,spt1,3,
885
     >                   nx,ny,nz,xmin,ymin,dx,dy,mdv)
1488
     >                   nx,ny,nz,xmin,ymin,dx,dy,mdv)
886
        u = int_index4 (uut0,uut1,nx,ny,nz,xind,yind,pind,reltpos,mdv)
1489
        u = int_index4 (uut0,uut1,nx,ny,nz,xind,yind,pind,reltpos,mdv)
887
        v = int_index4 (vvt0,vvt1,nx,ny,nz,xind,yind,pind,reltpos,mdv)
1490
        v = int_index4 (vvt0,vvt1,nx,ny,nz,xind,yind,pind,reltpos,mdv)
888
        w = int_index4 (wwt0,wwt1,nx,ny,nz,xind,yind,pind,reltpos,mdv)
1491
        w = int_index4 (wwt0,wwt1,nx,ny,nz,xind,yind,pind,reltpos,mdv)
889
         
1492
         
890
c       Force the near-surface wind to zero
1493
c       Force the near-surface wind to zero
891
        if (pind.lt.1.) w1=w1*pind
1494
        if (pind.lt.1.) w1=w1*pind
892
 
1495
 
893
c       Update position and keep them
1496
c       Update position and keep them
894
        xk(n)=fbflag*u*deltat/(deltay*cos(y0*pi/180.))
1497
        xk(n)=fbflag*u*deltat/(deltay*cos(y0*pi/180.))
895
        yk(n)=fbflag*v*deltat/deltay
1498
        yk(n)=fbflag*v*deltat/deltay
896
        pk(n)=fbflag*w*deltat*wfactor/100.
1499
        pk(n)=fbflag*w*deltat*wfactor/100.
897
 
1500
 
898
      enddo
1501
      enddo
899
 
1502
 
900
C     Calculate new positions
1503
C     Calculate new positions
901
      x1=x0+(1./6.)*(xk(1)+2.*xk(2)+2.*xk(3)+xk(4))
1504
      x1=x0+(1./6.)*(xk(1)+2.*xk(2)+2.*xk(3)+xk(4))
902
      y1=y0+(1./6.)*(yk(1)+2.*yk(2)+2.*yk(3)+yk(4))
1505
      y1=y0+(1./6.)*(yk(1)+2.*yk(2)+2.*yk(3)+yk(4))
903
      p1=p0+(1./6.)*(pk(1)+2.*pk(2)+2.*pk(3)+pk(4))
1506
      p1=p0+(1./6.)*(pk(1)+2.*pk(2)+2.*pk(3)+pk(4))
904
 
1507
 
905
c     Handle pole problems (crossing and near pole trajectory)
1508
c     Handle pole problems (crossing and near pole trajectory)
906
      if ((hem.eq.1).and.(y1.gt.90.)) then
1509
      if ((hem.eq.1).and.(y1.gt.90.)) then
907
         y1=180.-y1
1510
         y1=180.-y1
908
         x1=x1+per/2.
1511
         x1=x1+per/2.
909
      endif
1512
      endif
910
      if ((hem.eq.1).and.(y1.lt.-90.)) then
1513
      if ((hem.eq.1).and.(y1.lt.-90.)) then
911
         y1=-180.-y1
1514
         y1=-180.-y1
912
         x1=x1+per/2.
1515
         x1=x1+per/2.
913
      endif
1516
      endif
914
      if (y1.gt.89.99) then
1517
      if (y1.gt.89.99) then
915
         y1=89.99
1518
         y1=89.99
916
      endif
1519
      endif
917
      
1520
      
918
c     Handle crossings of the dateline
1521
c     Handle crossings of the dateline
919
      if ((hem.eq.1).and.(x1.gt.xmin+per-dx)) then
1522
      if ((hem.eq.1).and.(x1.gt.xmin+per-dx)) then
920
         x1=xmin+amod(x1-xmin,per)
1523
         x1=xmin+amod(x1-xmin,per)
921
      endif
1524
      endif
922
      if ((hem.eq.1).and.(x1.lt.xmin)) then
1525
      if ((hem.eq.1).and.(x1.lt.xmin)) then
923
         x1=xmin+per+amod(x1-xmin,per)
1526
         x1=xmin+per+amod(x1-xmin,per)
924
      endif
1527
      endif
925
      
1528
      
926
C     Interpolate surface pressure to actual position
1529
C     Interpolate surface pressure to actual position
927
      call get_index4 (xind,yind,pind,x1,y1,1050.,reltpos1,
1530
      call get_index4 (xind,yind,pind,x1,y1,1050.,reltpos1,
928
     >                 p3d0,p3d1,spt0,spt1,3,
1531
     >                 p3d0,p3d1,spt0,spt1,3,
929
     >                 nx,ny,nz,xmin,ymin,dx,dy,mdv)
1532
     >                 nx,ny,nz,xmin,ymin,dx,dy,mdv)
930
      sp = int_index4 (spt0,spt1,nx,ny,1,xind,yind,1,reltpos,mdv)
1533
      sp = int_index4 (spt0,spt1,nx,ny,1,xind,yind,1,reltpos,mdv)
931
 
1534
 
932
c     Handle trajectories which cross the lower boundary (jump flag)
1535
c     Handle trajectories which cross the lower boundary (jump flag)
933
      if ((jump.eq.1).and.(p1.gt.sp)) p1=sp-10.
1536
      if ((jump.eq.1).and.(p1.gt.sp)) p1=sp-10.
934
      
1537
      
935
C     Check if trajectory leaves data domain
1538
C     Check if trajectory leaves data domain
936
      if ( ( (hem.eq.0).and.(x1.lt.xmin)    ).or.
1539
      if ( ( (hem.eq.0).and.(x1.lt.xmin)    ).or.
937
     >     ( (hem.eq.0).and.(x1.gt.xmax-dx) ).or.
1540
     >     ( (hem.eq.0).and.(x1.gt.xmax-dx) ).or.
938
     >       (y1.lt.ymin).or.(y1.gt.ymax).or.(p1.gt.sp) )
1541
     >       (y1.lt.ymin).or.(y1.gt.ymax).or.(p1.gt.sp) )
939
     >then
1542
     >then
940
         left=1
1543
         left=1
941
         goto 100
1544
         goto 100
942
      endif
1545
      endif
943
      
1546
      
944
c     Exit point fdor subroutine
1547
c     Exit point fdor subroutine
945
 100  continue
1548
 100  continue
946
 
1549
 
947
      return
1550
      return
948
      end
1551
      end