Subversion Repositories lagranto.wrf

Rev

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

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