Subversion Repositories lagranto.wrf

Rev

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

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