Subversion Repositories lagranto.wrf

Rev

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

Rev 11 Rev 15
1
      PROGRAM wrfmap
1
      PROGRAM wrfmap
2
 
2
 
3
c     **********************************************************************
3
c     **********************************************************************
4
c     * Transform between lon/lat and x/y coordinates                      *
4
c     * Transform between lon/lat and x/y coordinates                      *
5
c     * Michael Sprenger / Spring 2013                                     *
5
c     * Michael Sprenger / Spring 2013                                     *
6
c     **********************************************************************
6
c     **********************************************************************
7
 
7
 
8
      implicit none
8
      implicit none
9
     
9
     
10
c     ------------------------------------------------------------
10
c     ------------------------------------------------------------
11
c     Declaration of parameters and variables
11
c     Declaration of parameters and variables
12
c     ------------------------------------------------------------
12
c     ------------------------------------------------------------
13
 
13
 
14
c     Input parameters
14
c     Input parameters
15
      character*80 mode
15
      character*80 mode
16
      character*80 inpfile
16
      character*80 inpfile
17
      character*80 outfile
17
      character*80 outfile
18
      integer      ntra,ntim,ncol
18
      integer      ntra,ntim,ncol
19
      character*80 anglemode
19
      character*80 anglemode
20
 
20
 
21
c     Fixed parameters
21
c     Fixed parameters
22
      character*80 mapfile                          ! netCDF file with map transformation
22
      character*80 mapfile                          ! netCDF file with map transformation
23
      parameter    (mapfile ='wrfmap.nc')
23
      parameter    (mapfile ='wrfmap.nc')
24
      real         mdv                              ! missing data value
24
      real         mdv                              ! missing data value
25
      parameter    (mdv=-999.)
25
      parameter    (mdv=-999.)
26
 
26
 
27
c     Numerical grid
27
c     Numerical grid
28
      real         xmin,xmax,ymin,ymax              ! Domain size
28
      real         xmin,xmax,ymin,ymax              ! Domain size
29
      real         dx,dy                            ! Horizontal resolution
29
      real         dx,dy                            ! Horizontal resolution
30
      integer      nx,ny,nz                         ! Grid dimensions
30
      integer      nx,ny,nz                         ! Grid dimensions
31
      real,allocatable,dimension (:,:)  :: lon,lat  ! lon/lat on numerical grid
31
      real,allocatable,dimension (:,:)  :: lon,lat  ! lon/lat on numerical grid
32
      real,allocatable,dimension (:,:)  :: mpx,mpy  ! map scale factors in x/y direction
32
      real,allocatable,dimension (:,:)  :: mpx,mpy  ! map scale factors in x/y direction
33
 
33
 
34
 
34
 
35
c     Geographical grid
35
c     Geographical grid
36
      real         latmin,latmax,lonmin,lonmax      ! Geographical domain
36
      real         latmin,latmax,lonmin,lonmax      ! Geographical domain
37
      real         dlon,dlat                        ! Minimum spacing in geographical space
37
      real         dlon,dlat                        ! Minimum spacing in geographical space
38
      integer      nlon,nlat,nlev                        ! Geographical grid dimension
38
      integer      nlon,nlat,nlev                        ! Geographical grid dimension
39
      real,allocatable,dimension (:,:)   :: x,y      ! x/y on geographical grid
39
      real,allocatable,dimension (:,:)   :: x,y      ! x/y on geographical grid
40
 
40
 
41
c     Vertical grid
41
c     Vertical grid
42
      real,allocatable,dimension (:,:,:)   :: p3    ! 3D pressure
42
      real,allocatable,dimension (:,:,:)   :: p3    ! 3D pressure
43
      real,allocatable,dimension (:,:)     :: ps    ! surface pressure
43
      real,allocatable,dimension (:,:)     :: ps    ! surface pressure
44
      real,allocatable,dimension (:,:,:)   :: z3    ! 3D geopotential height
44
      real,allocatable,dimension (:,:,:)   :: z3    ! 3D geopotential height
45
      real,allocatable,dimension (:,:)     :: zb    ! surface geopotential height
45
      real,allocatable,dimension (:,:)     :: zb    ! surface geopotential height
46
 
46
 
47
c     Transformation between numerical and geographical grid
47
c     Transformation between numerical and geographical grid
48
      real,allocatable,dimension (:,:)  :: connect1 
48
      integer,allocatable,dimension (:,:)  :: connect1 
49
      integer      connectval1 
49
      integer      connectval1 
50
      real,allocatable,dimension (:,:)  :: connect2 
50
      integer,allocatable,dimension (:,:)  :: connect2 
51
      integer      connectval2
51
      integer      connectval2
52
      real,allocatable,dimension (:,:)  :: xc,yc
52
      real,allocatable,dimension (:,:)  :: xc,yc
53
      real         radius
53
      real         radius
54
      real         xval,yval
54
      real         xval,yval
55
 
55
 
56
c     Trajectories
56
c     Trajectories
57
      real,allocatable, dimension (:,:,:) :: tra             ! Input start coordinates (ntra,ntim,ncol)
57
      real,allocatable, dimension (:,:,:) :: tra             ! Input start coordinates (ntra,ntim,ncol)
58
      integer                                refdate(6)      ! Reference date
58
      integer                                refdate(6)      ! Reference date
59
      character*80                           vars(200)       ! Field names
59
      character*80                           vars(200)       ! Field names
60
      real,allocatable, dimension (:)     :: xx0,yy0,zz0     ! Position of air parcels
60
      real,allocatable, dimension (:)     :: xx0,yy0,zz0     ! Position of air parcels
61
      integer                                inpmode
61
      integer                                inpmode
62
      integer                                outmode
62
      integer                                outmode
63
      integer                                npoints
63
      integer                                npoints
64
 
64
 
65
c     Auxiliary variables
65
c     Auxiliary variables
66
      integer      fid
66
      integer      fid
67
      integer      stat
67
      integer      stat
68
      character*80 varname,cdfname
68
      character*80 varname,cdfname
69
      integer      i,j
69
      integer      i,j
70
      character*80 radunit
70
      character*80 radunit
71
      real         rdummy
71
      real         rdummy
72
      real         rid,rjd,rkd
72
      real         rid,rjd,rkd
73
      real         xpos,ypos,zpos,ppos,lonpos,latpos
73
      real         xpos,ypos,zpos,ppos,lonpos,latpos
74
      real         lon1,lat1,lon2,lat2
74
      real         lon1,lat1,lon2,lat2
75
      integer      nfilter
75
      integer      nfilter
76
 
76
 
77
c     Externals
77
c     Externals
78
      real         int_index3
78
      real         int_index3
79
      external     int_index3
79
      external     int_index3
80
      real         sdis
80
      real         sdis
81
      external     sdis
81
      external     sdis
82
 
82
 
83
c     ------------------------------------------------------------
83
c     ------------------------------------------------------------
84
c     Preparations
84
c     Preparations
85
c     ------------------------------------------------------------
85
c     ------------------------------------------------------------
86
 
86
 
87
c     Read parameters
87
c     Read parameters
88
      open(10,file='wrfmap.param')
88
      open(10,file='wrfmap.param')
89
 
89
 
90
       read(10,*) mode
90
       read(10,*) mode
91
 
91
 
92
       if ( mode.eq.'-create' ) then         ! create mapping file
92
       if ( mode.eq.'-create' ) then         ! create mapping file
93
          read(10,*) inpfile
93
          read(10,*) inpfile
94
          read(10,*) anglemode
94
          read(10,*) anglemode
95
       endif
95
       endif
96
 
96
 
97
       if ( mode.eq.'-ll2xy'  ) then         ! convert lon/lat -> x/y
97
       if ( mode.eq.'-ll2xy'  ) then         ! convert lon/lat -> x/y
98
          read(10,*) inpfile
98
          read(10,*) inpfile
99
          read(10,*) outfile
99
          read(10,*) outfile
100
          read(10,*) ntra,ntim,ncol
100
          read(10,*) ntra,ntim,ncol
101
       endif
101
       endif
102
 
102
 
103
       if ( mode.eq.'-ll2xy.single'  ) then   ! convert single lon/lat -> x/y
103
       if ( mode.eq.'-ll2xy.single'  ) then   ! convert single lon/lat -> x/y
104
          read(10,*) lonpos,latpos
104
          read(10,*) lonpos,latpos
105
       endif
105
       endif
106
 
106
 
107
       if ( mode.eq.'-xy2ll'  ) then         ! convert x/y -> lon/lat
107
       if ( mode.eq.'-xy2ll'  ) then         ! convert x/y -> lon/lat
108
          read(10,*) inpfile
108
          read(10,*) inpfile
109
          read(10,*) outfile
109
          read(10,*) outfile
110
          read(10,*) ntra,ntim,ncol
110
          read(10,*) ntra,ntim,ncol
111
       endif
111
       endif
112
 
112
 
113
       if ( mode.eq.'-xy2ll.single'  ) then   ! convert single x/y -> lon/lat
113
       if ( mode.eq.'-xy2ll.single'  ) then   ! convert single x/y -> lon/lat
114
          read(10,*) xpos,ypos
114
          read(10,*) xpos,ypos
115
       endif
115
       endif
116
 
116
 
117
       if ( mode.eq.'-p2z'  ) then            ! convert x/y/p -> x/y/z
117
       if ( mode.eq.'-p2z'  ) then            ! convert x/y/p -> x/y/z
118
          read(10,*) inpfile
118
          read(10,*) inpfile
119
          read(10,*) outfile
119
          read(10,*) outfile
120
          read(10,*) ntra,ntim,ncol
120
          read(10,*) ntra,ntim,ncol
121
       endif
121
       endif
122
 
122
 
123
       if ( mode.eq.'-p2z.single'  ) then     ! convert single x/y/p -> x/y/z
123
       if ( mode.eq.'-p2z.single'  ) then     ! convert single x/y/p -> x/y/z
124
          read(10,*) xpos,ypos,ppos
124
          read(10,*) xpos,ypos,ppos
125
       endif
125
       endif
126
 
126
 
127
       if ( mode.eq.'-z2p'  ) then            ! convert x/y/z -> x/y/p
127
       if ( mode.eq.'-z2p'  ) then            ! convert x/y/z -> x/y/p
128
          read(10,*) inpfile
128
          read(10,*) inpfile
129
          read(10,*) outfile
129
          read(10,*) outfile
130
          read(10,*) ntra,ntim,ncol
130
          read(10,*) ntra,ntim,ncol
131
       endif
131
       endif
132
 
132
 
133
       if ( mode.eq.'-z2p.single'  ) then     ! convert single x/y/z -> x/y/p
133
       if ( mode.eq.'-z2p.single'  ) then     ! convert single x/y/z -> x/y/p
134
          read(10,*) xpos,ypos,zpos
134
          read(10,*) xpos,ypos,zpos
135
       endif
135
       endif
136
 
136
 
137
       if ( mode.eq.'-mapscale'  ) then       ! calculate mapping scale factors
137
       if ( mode.eq.'-mapscale'  ) then       ! calculate mapping scale factors
138
          read(10,*) nfilter
138
          read(10,*) nfilter
139
       endif
139
       endif
140
 
140
 
141
      close(10)
141
      close(10)
142
 
142
 
143
c     Read the mapping file - except for mode '-create'
143
c     Read the mapping file - except for mode '-create'
144
      if ( mode.ne.'-create' ) then
144
      if ( mode.ne.'-create' ) then
145
 
145
 
146
c        Get dimensions 
146
c        Get dimensions 
147
         cdfname = mapfile
147
         cdfname = mapfile
148
         varname = 'Z'
148
         varname = 'Z'
149
         nx      = 1
149
         nx      = 1
150
         ny      = 1
150
         ny      = 1
151
         nz      = 1
151
         nz      = 1
152
         call readcdf2D(cdfname,varname,rdummy,0.,
152
         call readcdf2D(cdfname,varname,rdummy,0.,
153
     >                  dx,dy,xmin,ymin,nx,ny,nz)
153
     >                  dx,dy,xmin,ymin,nx,ny,nz)
154
 
154
 
155
         cdfname = mapfile
155
         cdfname = mapfile
156
         varname = 'X'
156
         varname = 'X'
157
         nlon    = 1
157
         nlon    = 1
158
         nlat    = 1
158
         nlat    = 1
159
         nlev    = 1
159
         nlev    = 1
160
         call readcdf2D(cdfname,varname,rdummy,0.,
160
         call readcdf2D(cdfname,varname,rdummy,0.,
161
     >                  dlon,dlat,lonmin,latmin,nlon,nlat,nlev)
161
     >                  dlon,dlat,lonmin,latmin,nlon,nlat,nlev)
162
 
162
 
163
c        Allocate memory
163
c        Allocate memory
164
         allocate(lon(nx,ny),stat=stat)
164
         allocate(lon(nx,ny),stat=stat)
165
         if (stat.ne.0) print*,'*** error allocating array lon ***'
165
         if (stat.ne.0) print*,'*** error allocating array lon ***'
166
         allocate(lat(nx,ny),stat=stat)
166
         allocate(lat(nx,ny),stat=stat)
167
         if (stat.ne.0) print*,'*** error allocating array lat ***'
167
         if (stat.ne.0) print*,'*** error allocating array lat ***'
168
         allocate(x(nlon,nlat),stat=stat)
168
         allocate(x(nlon,nlat),stat=stat)
169
         if (stat.ne.0) print*,'*** error allocating array x   ***'
169
         if (stat.ne.0) print*,'*** error allocating array x   ***'
170
         allocate(y(nlon,nlat),stat=stat)
170
         allocate(y(nlon,nlat),stat=stat)
171
         if (stat.ne.0) print*,'*** error allocating array y   ***'
171
         if (stat.ne.0) print*,'*** error allocating array y   ***'
172
         allocate(p3(nx,ny,nz),stat=stat)
172
         allocate(p3(nx,ny,nz),stat=stat)
173
         if (stat.ne.0) print*,'*** error allocating array p3  ***'
173
         if (stat.ne.0) print*,'*** error allocating array p3  ***'
174
         allocate(z3(nx,ny,nz),stat=stat)
174
         allocate(z3(nx,ny,nz),stat=stat)
175
         if (stat.ne.0) print*,'*** error allocating array z3  ***'
175
         if (stat.ne.0) print*,'*** error allocating array z3  ***'
176
         allocate(zb(nx,ny),stat=stat)
176
         allocate(zb(nx,ny),stat=stat)
177
         if (stat.ne.0) print*,'*** error allocating array zb  ***'
177
         if (stat.ne.0) print*,'*** error allocating array zb  ***'
178
         allocate(ps(nx,ny),stat=stat)
178
         allocate(ps(nx,ny),stat=stat)
179
         if (stat.ne.0) print*,'*** error allocating array ps  ***'
179
         if (stat.ne.0) print*,'*** error allocating array ps  ***'
180
 
180
 
181
c        Read data
181
c        Read data
182
         cdfname = mapfile
182
         cdfname = mapfile
183
         varname = 'LON'
183
         varname = 'LON'
184
         call readcdf2D(cdfname,varname,lon,0.,
184
         call readcdf2D(cdfname,varname,lon,0.,
185
     >                  dx,dy,xmin,ymin,nx,ny,1)
185
     >                  dx,dy,xmin,ymin,nx,ny,1)
186
         cdfname = mapfile
186
         cdfname = mapfile
187
         varname = 'LAT'
187
         varname = 'LAT'
188
         call readcdf2D(cdfname,varname,lat,0.,
188
         call readcdf2D(cdfname,varname,lat,0.,
189
     >                  dx,dy,xmin,ymin,nx,ny,1)
189
     >                  dx,dy,xmin,ymin,nx,ny,1)
190
         cdfname = mapfile
190
         cdfname = mapfile
191
         varname = 'X'
191
         varname = 'X'
192
         call readcdf2D(cdfname,varname,x,0.,
192
         call readcdf2D(cdfname,varname,x,0.,
193
     >                  dlon,dlat,lonmin,latmin,nlon,nlat,1)
193
     >                  dlon,dlat,lonmin,latmin,nlon,nlat,1)
194
         cdfname = mapfile
194
         cdfname = mapfile
195
         varname = 'Y'
195
         varname = 'Y'
196
         call readcdf2D(cdfname,varname,y,0.,
196
         call readcdf2D(cdfname,varname,y,0.,
197
     >                  dlon,dlat,lonmin,latmin,nlon,nlat,1)
197
     >                  dlon,dlat,lonmin,latmin,nlon,nlat,1)
198
         cdfname = mapfile
198
         cdfname = mapfile
199
         varname = 'Z'
199
         varname = 'Z'
200
         call readcdf2D(cdfname,varname,z3,0.,
200
         call readcdf2D(cdfname,varname,z3,0.,
201
     >                  dx,dy,xmin,ymin,nx,ny,nz)
201
     >                  dx,dy,xmin,ymin,nx,ny,nz)
202
         cdfname = mapfile
202
         cdfname = mapfile
203
         varname = 'P'
203
         varname = 'P'
204
         call readcdf2D(cdfname,varname,p3,0.,
204
         call readcdf2D(cdfname,varname,p3,0.,
205
     >                  dx,dy,xmin,ymin,nx,ny,nz)
205
     >                  dx,dy,xmin,ymin,nx,ny,nz)
206
         cdfname = mapfile
206
         cdfname = mapfile
207
         varname = 'TOPO'
207
         varname = 'TOPO'
208
         call readcdf2D(cdfname,varname,zb,0.,
208
         call readcdf2D(cdfname,varname,zb,0.,
209
     >                  dx,dy,xmin,ymin,nx,ny,1)
209
     >                  dx,dy,xmin,ymin,nx,ny,1)
210
 
210
 
211
c	     Set surface prtessure to lowest 3d pressure level
211
c	     Set surface prtessure to lowest 3d pressure level
212
         do i=1,nx
212
         do i=1,nx
213
            do j=1,ny
213
            do j=1,ny
214
               ps(i,j) = p3(i,j,1)
214
               ps(i,j) = p3(i,j,1)
215
            enddo
215
            enddo
216
         enddo
216
         enddo
217
 
217
 
218
      endif
218
      endif
219
 
219
 
220
c     ------------------------------------------------------------
220
c     ------------------------------------------------------------
221
c     Create mapping file
221
c     Create mapping file
222
c     ------------------------------------------------------------
222
c     ------------------------------------------------------------
223
 
223
 
224
      if ( mode.eq.'-create' ) then
224
      if ( mode.eq.'-create' ) then
225
 
225
 
226
c     Open mapping file
226
c     Open mapping file
227
      call input_open(fid,inpfile)
227
      call input_open(fid,inpfile)
228
 
228
 
229
c     Get grid description
229
c     Get grid description
230
      call input_grid_wrf(fid,
230
      call input_grid_wrf(fid,
231
     >		          xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz)
231
     >		          xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz)
232
 
232
 
233
c     Write grid information to screen
233
c     Write grid information to screen
234
      print*,' xmin,xmax  = ',xmin,xmax
234
      print*,' xmin,xmax  = ',xmin,xmax
235
      print*,' ymin,ymax  = ',ymin,ymax
235
      print*,' ymin,ymax  = ',ymin,ymax
236
      print*,' dx,dy      = ',dx,dy
236
      print*,' dx,dy      = ',dx,dy
237
      print*,' nx,ny,nz   = ',nx,ny,nz 
237
      print*,' nx,ny,nz   = ',nx,ny,nz 
-
 
238
      print*,' anglemode  = ',trim(anglemode)
238
 
239
 
239
c     Transform grid specifier into grid coordinates
240
c     Transform grid specifier into grid coordinates
240
      xmin = 1.
241
      xmin = 1.
241
      ymin = 1.
242
      ymin = 1.
242
      dx   = 1.
243
      dx   = 1.
243
      dy   = 1.
244
      dy   = 1.
244
 
245
 
245
c     Allocate memory for lon/lat on numerical grid
246
c     Allocate memory for lon/lat on numerical grid
246
      allocate(lon(nx,ny),stat=stat)
247
      allocate(lon(nx,ny),stat=stat)
247
      if (stat.ne.0) print*,'*** error allocating array lon ***'
248
      if (stat.ne.0) print*,'*** error allocating array lon ***'
248
      allocate(lat(nx,ny),stat=stat)
249
      allocate(lat(nx,ny),stat=stat)
249
      if (stat.ne.0) print*,'*** error allocating array lat ***'
250
      if (stat.ne.0) print*,'*** error allocating array lat ***'
250
      allocate(p3(nx,ny,nz),stat=stat)
251
      allocate(p3(nx,ny,nz),stat=stat)
251
      if (stat.ne.0) print*,'*** error allocating array p3  ***'
252
      if (stat.ne.0) print*,'*** error allocating array p3  ***'
252
      allocate(z3(nx,ny,nz),stat=stat)
253
      allocate(z3(nx,ny,nz),stat=stat)
253
      if (stat.ne.0) print*,'*** error allocating array z3  ***'
254
      if (stat.ne.0) print*,'*** error allocating array z3  ***'
254
      allocate(zb(nx,ny),stat=stat)
255
      allocate(zb(nx,ny),stat=stat)
255
      if (stat.ne.0) print*,'*** error allocating array zb  ***'
256
      if (stat.ne.0) print*,'*** error allocating array zb  ***'
256
 
257
 
257
c     Read lon/lat on the model grid
258
c     Read lon/lat on the model grid
258
      varname='XLONG'
259
      varname='XLONG'
259
      call input_var_wrf(fid,varname,lon,nx,ny,1)
260
      call input_var_wrf(fid,varname,lon,nx,ny,1)
260
      varname='XLAT'
261
      varname='XLAT'
261
      call input_var_wrf(fid,varname,lat,nx,ny,1)
262
      call input_var_wrf(fid,varname,lat,nx,ny,1)
262
      varname='pressure'
263
      varname='pressure'
263
      call input_var_wrf(fid,varname,p3 ,nx,ny,nz)
264
      call input_var_wrf(fid,varname,p3 ,nx,ny,nz)
264
      varname='geopot'
265
      varname='geopot'
265
      call input_var_wrf(fid,varname,z3 ,nx,ny,nz)
266
      call input_var_wrf(fid,varname,z3 ,nx,ny,nz)
266
      varname='geopots'
267
      varname='geopots'
267
      call input_var_wrf(fid,varname,zb ,nx,ny,1)
268
      call input_var_wrf(fid,varname,zb ,nx,ny,1)
268
 
269
 
269
c     Transform longitude depending on <anglemode>
270
c     Transform longitude depending on <anglemode>
270
      if ( anglemode.eq.'greenwich' ) then
271
      if ( anglemode.eq.'greenwich' ) then
271
         do i=1,nx
272
         do i=1,nx
272
           do j=1,ny
273
           do j=1,ny
273
              if ( lon(i,j).lt.0. ) lon(i,j) = lon(i,j) + 360.
274
              if ( lon(i,j).lt.0. ) lon(i,j) = lon(i,j) + 360.
274
            enddo
275
            enddo
275
         enddo
276
         enddo
276
      elseif ( anglemode.eq.'dateline' ) then
277
      elseif ( anglemode.eq.'dateline' ) then
277
         do i=1,nx
278
         do i=1,nx
278
            do j=1,ny
279
            do j=1,ny
279
               if ( lon(i,j).gt.180. ) lon(i,j) = lon(i,j) - 360.
280
               if ( lon(i,j).gt.180. ) lon(i,j) = lon(i,j) - 360.
280
            enddo
281
            enddo
281
         enddo
282
         enddo
282
      else
283
      else
283
         print*,' ERROR: unsupported angle mode... Stop'
284
         print*,' ERROR: unsupported angle mode... Stop'
284
         stop
285
         stop
285
      endif
286
      endif
286
 
287
 
287
c     Close input file file
288
c     Close input file file
288
      call input_close(fid)
289
      call input_close(fid)
289
 
290
 
290
c     Check for 'date line' and for pole
291
c     Check for 'date line' and for pole
291
      do i=2,nx
292
      do i=2,nx
292
      do j=1,ny
293
      do j=1,ny
293
        if ( abs( lat(i,j) ).gt.90. ) then
294
        if ( abs( lat(i,j) ).gt.90. ) then
294
           print*,' ERROR: mapping over pole not supported... Stop'
295
           print*,' ERROR: mapping over pole not supported... Stop'
295
           stop
296
           stop
296
        endif
297
        endif
297
        if ( abs( lon(i,j)-lon(i-1,j) ).gt.180. ) then
298
        if ( abs( lon(i,j)-lon(i-1,j) ).gt.180. ) then
298
           print*,' ERROR: mapping over date line not supported... Stop'
299
           print*,' ERROR: mapping over date line not supported... Stop'
299
           stop
300
           stop
300
        endif
301
        endif
301
      enddo
302
      enddo
302
      enddo
303
      enddo
303
 
304
 
304
c     Determine the extreme coordinates
305
c     Determine the extreme coordinates
305
      latmin  = lat(1,1)
306
      latmin  = lat(1,1)
306
      latmax  = lat(1,1)
307
      latmax  = lat(1,1)
307
      lonmin  = lon(1,1)
308
      lonmin  = lon(1,1)
308
      lonmax  = lon(1,1)
309
      lonmax  = lon(1,1)
309
      do i=1,nx
310
      do i=1,nx
310
	    do j=1,ny
311
	    do j=1,ny
311
          if ( lat(i,j).lt.latmin ) latmin = lat(i,j)
312
          if ( lat(i,j).lt.latmin ) latmin = lat(i,j)
312
          if ( lat(i,j).gt.latmax ) latmax = lat(i,j)
313
          if ( lat(i,j).gt.latmax ) latmax = lat(i,j)
313
          if ( lon(i,j).lt.lonmin ) lonmin = lon(i,j)
314
          if ( lon(i,j).lt.lonmin ) lonmin = lon(i,j)
314
          if ( lon(i,j).gt.lonmax ) lonmax = lon(i,j)
315
          if ( lon(i,j).gt.lonmax ) lonmax = lon(i,j)
315
        enddo
316
        enddo
316
      enddo
317
      enddo
317
 
318
 
318
      print*,' lonmin,max = ',lonmin,lonmax
319
      print*,' lonmin,max = ',lonmin,lonmax
319
      print*,' latmin,max = ',latmin,latmax
320
      print*,' latmin,max = ',latmin,latmax
320
 
321
 
321
c     Determine the extreme dlon/dlat spacing
322
c     Determine the extreme dlon/dlat spacing
322
      dlon = abs( lon(2,1)-lon(1,1) )
323
      dlon = abs( lon(2,1)-lon(1,1) )
323
      do i=2,nx
324
      do i=2,nx
324
	    do j=1,ny
325
	    do j=1,ny
325
           if ( abs( lon(i,j)-lon(i-1,j) ).lt.dlon ) then
326
           if ( abs( lon(i,j)-lon(i-1,j) ).lt.dlon ) then
326
              dlon = abs( lon(i,j)-lon(i-1,j) )
327
              dlon = abs( lon(i,j)-lon(i-1,j) )
327
           endif
328
           endif
328
         enddo
329
         enddo
329
      enddo
330
      enddo
330
      dlat = abs( lat(1,2)-lat(1,1) )
331
      dlat = abs( lat(1,2)-lat(1,1) )
331
      do i=1,nx
332
      do i=1,nx
332
	    do j=2,ny
333
	    do j=2,ny
333
           if ( abs( lat(i,j)-lat(i,j-1) ).lt.dlat ) then
334
           if ( abs( lat(i,j)-lat(i,j-1) ).lt.dlat ) then
334
              dlat = abs( lat(i,j)-lat(i,j-1) )
335
              dlat = abs( lat(i,j)-lat(i,j-1) )
335
           endif
336
           endif
336
         enddo
337
         enddo
337
      enddo
338
      enddo
338
 
339
 
339
c     Set dimension of geographical grid 
340
c     Set dimension of geographical grid 
340
      nlon   = ceiling( (lonmax-lonmin) / dlon + 1. )
341
      nlon   = ceiling( (lonmax-lonmin) / dlon + 1. )
341
      nlat   = ceiling( (latmax-latmin) / dlat + 1. )
342
      nlat   = ceiling( (latmax-latmin) / dlat + 1. )
342
      lonmax = lonmin + real(nlon-1) * dlon
343
      lonmax = lonmin + real(nlon-1) * dlon
343
      latmax = latmin + real(nlat-1) * dlat
344
      latmax = latmin + real(nlat-1) * dlat
344
 
345
 
345
      print*,' dlon,dlat  = ',dlon,dlat
346
      print*,' dlon,dlat  = ',dlon,dlat
346
      print*,' nlon,nlat  = ',nlon,nlat
347
      print*,' nlon,nlat  = ',nlon,nlat
347
 
348
 
348
c     Allocate memory for x/y on geographical grid
349
c     Allocate memory for x/y on geographical grid
349
      allocate(x(nlon,nlat),stat=stat)
350
      allocate(x(nlon,nlat),stat=stat)
350
      if (stat.ne.0) print*,'*** error allocating array x       ***'
351
      if (stat.ne.0) print*,'*** error allocating array x       ***'
351
      allocate(y(nlon,nlat),stat=stat)
352
      allocate(y(nlon,nlat),stat=stat)
352
      if (stat.ne.0) print*,'*** error allocating array y       ***'
353
      if (stat.ne.0) print*,'*** error allocating array y       ***'
353
      allocate(connect1(nlon,nlat),stat=stat)
354
      allocate(connect1(nlon,nlat),stat=stat)
354
      if (stat.ne.0) print*,'*** error allocating array connect1***'
355
      if (stat.ne.0) print*,'*** error allocating array connect1***'
355
      allocate(connect2(nlon,nlat),stat=stat)
356
      allocate(connect2(nlon,nlat),stat=stat)
356
      if (stat.ne.0) print*,'*** error allocating array connect2***'
357
      if (stat.ne.0) print*,'*** error allocating array connect2***'
357
      allocate(xc(nlon,nlat),stat=stat)
358
      allocate(xc(nlon,nlat),stat=stat)
358
      if (stat.ne.0) print*,'*** error allocating array xc      ***'
359
      if (stat.ne.0) print*,'*** error allocating array xc      ***'
359
      allocate(yc(nlon,nlat),stat=stat)
360
      allocate(yc(nlon,nlat),stat=stat)
360
      if (stat.ne.0) print*,'*** error allocating array yc      ***'
361
      if (stat.ne.0) print*,'*** error allocating array yc      ***'
361
 
362
 
362
c     Init the mapping arrays
363
c     Init the mapping arrays
363
      connectval1 = 0
364
      connectval1 = 0
364
      connectval2 = 0
365
      connectval2 = 0
365
      do i=1,nlon
366
      do i=1,nlon
366
	do j=1,nlat
367
	do j=1,nlat
367
           x(i,j)        = 0.
368
           x(i,j)        = 0.
368
           y(i,j)        = 0.
369
           y(i,j)        = 0.
369
           xc(i,j)       = 0.
370
           xc(i,j)       = 0.
370
           yc(i,j)       = 0.
371
           yc(i,j)       = 0.
371
           connect1(i,j) = 1
372
           connect1(i,j) = 1
372
           connect2(i,j) = 1
373
           connect2(i,j) = 1
373
        enddo
374
        enddo
374
      enddo
375
      enddo
375
 
376
 
376
c     Get the good radius for gridding - avoiding gaps
377
c     Get the good radius for gridding - avoiding gaps
377
      radunit = 'deg'
378
      radunit = 'deg'
378
      radius  = 0.
379
      radius  = 0.
379
      do i=2,nx
380
      do i=2,nx
380
        do j=2,ny
381
        do j=2,ny
381
           if ( abs( lat(i,j)-lat(i,j-1) ).gt.radius ) then
382
           if ( abs( lat(i,j)-lat(i,j-1) ).gt.radius ) then
382
              radius = abs( lat(i,j)-lat(i,j-1) )
383
              radius = abs( lat(i,j)-lat(i,j-1) )
383
           endif
384
           endif
384
           if ( abs( lon(i,j)-lon(i-1,j) ).gt.radius ) then
385
           if ( abs( lon(i,j)-lon(i-1,j) ).gt.radius ) then
385
              radius = abs( lon(i,j)-lon(i-1,j) )
386
              radius = abs( lon(i,j)-lon(i-1,j) )
386
           endif
387
           endif
387
        enddo
388
        enddo
388
      enddo
389
      enddo
389
      radius = 3. * radius 
390
      radius = 3. * radius 
390
 
391
 
391
c     Do the mapping
392
c     Do the mapping
392
      do i=1,nx
393
      do i=1,nx
393
	do j=1,ny
394
	do j=1,ny
394
 
395
 
395
          connectval1 = connectval1 + 1
396
          connectval1 = connectval1 + 1
396
          call gridding1(lat(i,j),lon(i,j),real(i),radius,radunit,
397
          call gridding1(lat(i,j),lon(i,j),real(i),radius,radunit,
397
     >                   connect1,connectval1,
398
     >                   connect1,connectval1,
398
     >                   x,xc,nlon,nlat,lonmin,latmin,dlon,dlat)
399
     >                   x,xc,nlon,nlat,lonmin,latmin,dlon,dlat)
399
 
400
 
400
          connectval2 = connectval2 + 1
401
          connectval2 = connectval2 + 1
401
          call gridding1(lat(i,j),lon(i,j),real(j),radius,radunit,
402
          call gridding1(lat(i,j),lon(i,j),real(j),radius,radunit,
402
     >                   connect2,connectval2,
403
     >                   connect2,connectval2,
403
     >                   y,yc,nlon,nlat,lonmin,latmin,dlon,dlat)
404
     >                   y,yc,nlon,nlat,lonmin,latmin,dlon,dlat)
404
 
405
 
405
 
406
 
406
	enddo
407
	enddo
407
      enddo
408
      enddo
408
 
409
 
409
c     Normalize output and set miising data flag
410
c     Normalize output and set miising data flag
410
      do i=1,nlon
411
      do i=1,nlon
411
         do j=1,nlat
412
         do j=1,nlat
412
            if ( xc(i,j).gt.0. ) then
413
            if ( xc(i,j).gt.0. ) then
413
               x(i,j) = x(i,j)/xc(i,j)
414
               x(i,j) = x(i,j)/xc(i,j)
414
            else
415
            else
415
               x(i,j) = mdv
416
               x(i,j) = mdv
416
            endif
417
            endif
417
            if ( yc(i,j).gt.0. ) then
418
            if ( yc(i,j).gt.0. ) then
418
               y(i,j) = y(i,j)/yc(i,j)
419
               y(i,j) = y(i,j)/yc(i,j)
419
            else
420
            else
420
               y(i,j) = mdv
421
               y(i,j) = mdv
421
            endif
422
            endif
422
         enddo
423
         enddo
423
      enddo
424
      enddo
424
 
425
 
425
c     Write data to netCDF
426
c     Write data to netCDF
426
      cdfname = mapfile
427
      cdfname = mapfile
427
      varname = 'X'
428
      varname = 'X'
428
      call writecdf2D(cdfname,varname,x,0.,
429
      call writecdf2D(cdfname,varname,x,0.,
429
     >                dlon,dlat,lonmin,latmin,nlon,nlat,1,1,1)
430
     >                dlon,dlat,lonmin,latmin,nlon,nlat,1,1,1)
430
 
431
 
431
      cdfname = mapfile
432
      cdfname = mapfile
432
      varname = 'Y'
433
      varname = 'Y'
433
      call writecdf2D(cdfname,varname,y,0.,
434
      call writecdf2D(cdfname,varname,y,0.,
434
     >                dlon,dlat,lonmin,latmin,nlon,nlat,1,0,1)
435
     >                dlon,dlat,lonmin,latmin,nlon,nlat,1,0,1)
435
 
436
 
436
      cdfname = mapfile
437
      cdfname = mapfile
437
      varname = 'LON'
438
      varname = 'LON'
438
      call writecdf2D(cdfname,varname,lon,0.,
439
      call writecdf2D(cdfname,varname,lon,0.,
439
     >                dx,dy,xmin,ymin,nx,ny,1,0,1)
440
     >                dx,dy,xmin,ymin,nx,ny,1,0,1)
440
 
441
 
441
      cdfname = mapfile
442
      cdfname = mapfile
442
      varname = 'LAT'
443
      varname = 'LAT'
443
      call writecdf2D(cdfname,varname,lat,0.,
444
      call writecdf2D(cdfname,varname,lat,0.,
444
     >                dx,dy,xmin,ymin,nx,ny,1,0,1)
445
     >                dx,dy,xmin,ymin,nx,ny,1,0,1)
445
 
446
 
446
      cdfname = mapfile
447
      cdfname = mapfile
447
      varname = 'Z'
448
      varname = 'Z'
448
      call writecdf2D(cdfname,varname,z3,0.,
449
      call writecdf2D(cdfname,varname,z3,0.,
449
     >                dx,dy,xmin,ymin,nx,ny,nz,0,1)
450
     >                dx,dy,xmin,ymin,nx,ny,nz,0,1)
450
 
451
 
451
      cdfname = mapfile
452
      cdfname = mapfile
452
      varname = 'P'
453
      varname = 'P'
453
      call writecdf2D(cdfname,varname,p3,0.,
454
      call writecdf2D(cdfname,varname,p3,0.,
454
     >                dx,dy,xmin,ymin,nx,ny,nz,0,1)
455
     >                dx,dy,xmin,ymin,nx,ny,nz,0,1)
455
 
-
 
456
      cdfname = mapfile
456
      cdfname = mapfile
457
      varname = 'TOPO'
457
      varname = 'TOPO'
458
      call writecdf2D(cdfname,varname,zb,0.,
458
      call writecdf2D(cdfname,varname,zb,0.,
459
     >                dx,dy,xmin,ymin,nx,ny,1,0,1)
459
     >                dx,dy,xmin,ymin,nx,ny,1,0,1)
460
 
460
 
461
 
461
 
462
      endif
462
      endif
463
 
463
 
464
 
464
 
465
c     ------------------------------------------------------------
465
c     ------------------------------------------------------------
466
c     Convert a lat/lon/z list to a x/y/z list
466
c     Convert a lat/lon/z list to a x/y/z list
467
c     ------------------------------------------------------------
467
c     ------------------------------------------------------------
468
 
468
 
469
      if ( mode.eq.'-ll2xy' ) then
469
      if ( mode.eq.'-ll2xy' ) then
470
 
470
 
471
c     Allocate memory for input and output lists
471
c     Allocate memory for input and output lists
472
      allocate(tra(ntra,ntim,ncol),stat=stat)
472
      allocate(tra(ntra,ntim,ncol),stat=stat)
473
      if (stat.ne.0) print*,'*** error allocating array tra         ***'
473
      if (stat.ne.0) print*,'*** error allocating array tra         ***'
474
      allocate(xx0(ntra*ntim),stat=stat)
474
      allocate(xx0(ntra*ntim),stat=stat)
475
      if (stat.ne.0) print*,'*** error allocating array xx0         ***'
475
      if (stat.ne.0) print*,'*** error allocating array xx0         ***'
476
      allocate(yy0(ntra*ntim),stat=stat)
476
      allocate(yy0(ntra*ntim),stat=stat)
477
      if (stat.ne.0) print*,'*** error allocating array yy0         ***'
477
      if (stat.ne.0) print*,'*** error allocating array yy0         ***'
478
      allocate(zz0(ntra*ntim),stat=stat)
478
      allocate(zz0(ntra*ntim),stat=stat)
479
      if (stat.ne.0) print*,'*** error allocating array zz0         ***'
479
      if (stat.ne.0) print*,'*** error allocating array zz0         ***'
480
 
480
 
481
c     Get format of input and output file
481
c     Get format of input and output file
482
      call mode_tra(inpmode,inpfile)
482
      call mode_tra(inpmode,inpfile)
483
      call mode_tra(outmode,outfile)
483
      call mode_tra(outmode,outfile)
484
      if ( outmode.eq.-1 ) outmode = inpmode
484
      if ( outmode.eq.-1 ) outmode = inpmode
485
 
485
 
486
c     Read coordinates from file - Format (lon,lat,lev)
486
c     Read coordinates from file - Format (lon,lat,lev)
487
      if (inpmode.eq.-1) then
487
      if (inpmode.eq.-1) then
488
         fid = 10
488
         fid = 10
489
         npoints = 0
489
         npoints = 0
490
         open(fid,file=inpfile)
490
         open(fid,file=inpfile)
491
          do i=1,ntra
491
          do i=1,ntra
492
             npoints = npoints + 1
492
             npoints = npoints + 1
493
             read(fid,*) xx0(npoints),yy0(npoints),zz0(npoints)
493
             read(fid,*) xx0(npoints),yy0(npoints),zz0(npoints)
494
          enddo
494
          enddo
495
         close(fid)
495
         close(fid)
496
 
496
 
497
c     Read coordinates from trajectory file 
497
c     Read coordinates from trajectory file 
498
      else
498
      else
499
         call ropen_tra(fid,inpfile,ntra,ntim,ncol,refdate,vars,inpmode)
499
         call ropen_tra(fid,inpfile,ntra,ntim,ncol,refdate,vars,inpmode)
500
         call read_tra (fid,tra,ntra,ntim,ncol,inpmode)
500
         call read_tra (fid,tra,ntra,ntim,ncol,inpmode)
501
         call close_tra(fid,inpmode)
501
         call close_tra(fid,inpmode)
502
 
502
 
503
         if ( (vars(2).ne.'lon').and.(vars(3).ne.'lat') ) then
503
         if ( (vars(2).ne.'lon').and.(vars(3).ne.'lat') ) then
504
            print*,' ERROR: input must be in lon/lat format... Stop'       
504
            print*,' ERROR: input must be in lon/lat format... Stop'       
505
            stop
505
            stop
506
         endif
506
         endif
507
 
507
 
508
         npoints = 0
508
         npoints = 0
509
         do i=1,ntra
509
         do i=1,ntra
510
            do j=1,ntim
510
            do j=1,ntim
511
               npoints = npoints + 1
511
               npoints = npoints + 1
512
               xx0(npoints) = tra(i,j,2) 
512
               xx0(npoints) = tra(i,j,2) 
513
               yy0(npoints) = tra(i,j,3) 
513
               yy0(npoints) = tra(i,j,3) 
514
               zz0(npoints) = tra(i,j,4) 
514
               zz0(npoints) = tra(i,j,4) 
515
            enddo
515
            enddo
516
         enddo
516
         enddo
517
      endif 
517
      endif 
518
 
518
 
519
c     Transform coordinates
519
c     Transform coordinates
520
      do i=1,npoints
520
      do i=1,npoints
521
 
521
 
522
          rid=(xx0(i)-lonmin)/dlon+1.
522
          rid=(xx0(i)-lonmin)/dlon+1.
523
          rjd=(yy0(i)-latmin)/dlat+1.
523
          rjd=(yy0(i)-latmin)/dlat+1.
524
 
524
 
525
          xx0(i) = int_index3(x,nlon,nlat,1,rid,rjd,1.,mdv)
525
          xx0(i) = int_index3(x,nlon,nlat,1,rid,rjd,1.,mdv)
526
          yy0(i) = int_index3(y,nlon,nlat,1,rid,rjd,1.,mdv)
526
          yy0(i) = int_index3(y,nlon,nlat,1,rid,rjd,1.,mdv)
527
 
527
 
528
      enddo
528
      enddo
529
 
529
 
530
c     Write output to list
530
c     Write output to list
531
      if ( outmode.eq.-1 ) then
531
      if ( outmode.eq.-1 ) then
532
         fid = 10
532
         fid = 10
533
         open(fid,file=outfile)
533
         open(fid,file=outfile)
534
         do i=1,ntra
534
         do i=1,ntra
535
            write(fid,'(f9.2,f8.2,i6)') xx0(i),yy0(i),nint(zz0(i))
535
            write(fid,'(f9.2,f8.2,i6)') xx0(i),yy0(i),nint(zz0(i))
536
         enddo
536
         enddo
537
         close(fid)
537
         close(fid)
538
 
538
 
539
c     Write output to trajectory
539
c     Write output to trajectory
540
      else         
540
      else         
541
         npoints = 0
541
         npoints = 0
542
         do i=1,ntra
542
         do i=1,ntra
543
            do j=1,ntim
543
            do j=1,ntim
544
               npoints = npoints + 1
544
               npoints = npoints + 1
545
               tra(i,j,2) = xx0(npoints)
545
               tra(i,j,2) = xx0(npoints)
546
               tra(i,j,3) = yy0(npoints)
546
               tra(i,j,3) = yy0(npoints)
547
               tra(i,j,4) = zz0(npoints)
547
               tra(i,j,4) = zz0(npoints)
548
            enddo
548
            enddo
549
         enddo
549
         enddo
550
         if ( ncol.eq.3 ) ncol = 4
550
         if ( ncol.eq.3 ) ncol = 4
551
         vars(1) = 'time'
551
         vars(1) = 'time'
552
         vars(2) = 'x'
552
         vars(2) = 'x'
553
         vars(3) = 'y'
553
         vars(3) = 'y'
554
         vars(4) = 'z'
554
         vars(4) = 'z'
555
         call wopen_tra(fid,outfile,ntra,ntim,ncol,refdate,vars,outmode)
555
         call wopen_tra(fid,outfile,ntra,ntim,ncol,refdate,vars,outmode)
556
         call write_tra(fid,tra,ntra,ntim,ncol,outmode)
556
         call write_tra(fid,tra,ntra,ntim,ncol,outmode)
557
         call close_tra(fid,outmode)
557
         call close_tra(fid,outmode)
558
      endif
558
      endif
559
 
559
 
560
      endif
560
      endif
561
 
561
 
562
c     ------------------------------------------------------------
562
c     ------------------------------------------------------------
563
c     Convert a x/y/z list to a lon/lat/z list
563
c     Convert a x/y/z list to a lon/lat/z list
564
c     ------------------------------------------------------------
564
c     ------------------------------------------------------------
565
 
565
 
566
      if ( mode.eq.'-xy2ll' ) then
566
      if ( mode.eq.'-xy2ll' ) then
567
 
567
 
568
c     Allocate memory for input and output lists
568
c     Allocate memory for input and output lists
569
      allocate(tra(ntra,ntim,ncol),stat=stat)
569
      allocate(tra(ntra,ntim,ncol),stat=stat)
570
      if (stat.ne.0) print*,'*** error allocating array tra         ***'
570
      if (stat.ne.0) print*,'*** error allocating array tra         ***'
571
      allocate(xx0(ntra*ntim),stat=stat)
571
      allocate(xx0(ntra*ntim),stat=stat)
572
      if (stat.ne.0) print*,'*** error allocating array xx0         ***'
572
      if (stat.ne.0) print*,'*** error allocating array xx0         ***'
573
      allocate(yy0(ntra*ntim),stat=stat)
573
      allocate(yy0(ntra*ntim),stat=stat)
574
      if (stat.ne.0) print*,'*** error allocating array yy0         ***'
574
      if (stat.ne.0) print*,'*** error allocating array yy0         ***'
575
      allocate(zz0(ntra*ntim),stat=stat)
575
      allocate(zz0(ntra*ntim),stat=stat)
576
      if (stat.ne.0) print*,'*** error allocating array zz0         ***'
576
      if (stat.ne.0) print*,'*** error allocating array zz0         ***'
577
 
577
 
578
c     Get format of input and output file
578
c     Get format of input and output file
579
      call mode_tra(inpmode,inpfile)
579
      call mode_tra(inpmode,inpfile)
580
      call mode_tra(outmode,outfile)
580
      call mode_tra(outmode,outfile)
581
      if ( outmode.eq.-1) outmode=inpmode
581
      if ( outmode.eq.-1) outmode=inpmode
582
 
582
 
583
c     Read coordinates from file - Format (x,y,lev)
583
c     Read coordinates from file - Format (x,y,lev)
584
      if (inpmode.eq.-1) then
584
      if (inpmode.eq.-1) then
585
         fid = 10
585
         fid = 10
586
         npoints = 0
586
         npoints = 0
587
         open(fid,file=inpfile)
587
         open(fid,file=inpfile)
588
          do i=1,ntra
588
          do i=1,ntra
589
             npoints = npoints + 1
589
             npoints = npoints + 1
590
             read(fid,*) xx0(npoints),yy0(npoints),zz0(npoints)
590
             read(fid,*) xx0(npoints),yy0(npoints),zz0(npoints)
591
          enddo
591
          enddo
592
         close(fid)
592
         close(fid)
593
 
593
 
594
c     Read coordinates from trajectory file 
594
c     Read coordinates from trajectory file 
595
      else
595
      else
596
         call ropen_tra(fid,inpfile,ntra,ntim,ncol,refdate,vars,inpmode)
596
         call ropen_tra(fid,inpfile,ntra,ntim,ncol,refdate,vars,inpmode)
597
         call read_tra (fid,tra,ntra,ntim,ncol,inpmode)
597
         call read_tra (fid,tra,ntra,ntim,ncol,inpmode)
598
         call close_tra(fid,inpmode)
598
         call close_tra(fid,inpmode)
599
 
599
 
600
         if ( (vars(2).ne.'x').and.(vars(3).ne.'y') ) then
600
         if ( (vars(2).ne.'x').and.(vars(3).ne.'y') ) then
601
            print*,' ERROR: input must be in x/y format... Stop'       
601
            print*,' ERROR: input must be in x/y format... Stop'       
602
            stop
602
            stop
603
         endif
603
         endif
604
 
604
 
605
         npoints = 0
605
         npoints = 0
606
         do i=1,ntra
606
         do i=1,ntra
607
            do j=1,ntim
607
            do j=1,ntim
608
               npoints = npoints + 1
608
               npoints = npoints + 1
609
               xx0(npoints) = tra(i,j,2) 
609
               xx0(npoints) = tra(i,j,2) 
610
               yy0(npoints) = tra(i,j,3) 
610
               yy0(npoints) = tra(i,j,3) 
611
               zz0(npoints) = tra(i,j,4) 
611
               zz0(npoints) = tra(i,j,4) 
612
            enddo
612
            enddo
613
         enddo
613
         enddo
614
      endif 
614
      endif 
615
 
615
 
616
c     Transform coordinates
616
c     Transform coordinates
617
      do i=1,npoints
617
      do i=1,npoints
618
 
618
 
619
          rid=(xx0(i)-xmin)/dx+1.
619
          rid=(xx0(i)-xmin)/dx+1.
620
          rjd=(yy0(i)-ymin)/dy+1.
620
          rjd=(yy0(i)-ymin)/dy+1.
621
 
621
 
622
          xx0(i) = int_index3(lon,nx,ny,1,rid,rjd,1.,mdv)
622
          xx0(i) = int_index3(lon,nx,ny,1,rid,rjd,1.,mdv)
623
          yy0(i) = int_index3(lat,nx,ny,1,rid,rjd,1.,mdv)
623
          yy0(i) = int_index3(lat,nx,ny,1,rid,rjd,1.,mdv)
624
 
624
 
625
      enddo
625
      enddo
626
 
626
 
627
c     Write output to list
627
c     Write output to list
628
      if ( outmode.eq.-1 ) then
628
      if ( outmode.eq.-1 ) then
629
         fid = 10
629
         fid = 10
630
         open(fid,file=outfile)
630
         open(fid,file=outfile)
631
         do i=1,ntra
631
         do i=1,ntra
632
            write(fid,'(f9.2,f8.2,i6)') xx0(i),yy0(i),nint(zz0(i))
632
            write(fid,'(f9.2,f8.2,i6)') xx0(i),yy0(i),nint(zz0(i))
633
         enddo
633
         enddo
634
         close(fid)
634
         close(fid)
635
 
635
 
636
c     Write output to trajectory
636
c     Write output to trajectory
637
      else         
637
      else         
638
         npoints = 0
638
         npoints = 0
639
         do i=1,ntra
639
         do i=1,ntra
640
            do j=1,ntim
640
            do j=1,ntim
641
               npoints = npoints + 1
641
               npoints = npoints + 1
642
               tra(i,j,2) = xx0(npoints)
642
               tra(i,j,2) = xx0(npoints)
643
               tra(i,j,3) = yy0(npoints)
643
               tra(i,j,3) = yy0(npoints)
644
               tra(i,j,4) = zz0(npoints)
644
               tra(i,j,4) = zz0(npoints)
645
            enddo
645
            enddo
646
         enddo
646
         enddo
647
         if ( ncol.eq.3 ) ncol = 4
647
         if ( ncol.eq.3 ) ncol = 4
648
         vars(1) = 'time'
648
         vars(1) = 'time'
649
         vars(2) = 'lon'
649
         vars(2) = 'lon'
650
         vars(3) = 'lat'
650
         vars(3) = 'lat'
651
         vars(4) = 'z'
651
         vars(4) = 'z'
652
         call wopen_tra(fid,outfile,ntra,ntim,ncol,refdate,vars,outmode)
652
         call wopen_tra(fid,outfile,ntra,ntim,ncol,refdate,vars,outmode)
653
         call write_tra(fid,tra,ntra,ntim,ncol,outmode)
653
         call write_tra(fid,tra,ntra,ntim,ncol,outmode)
654
         call close_tra(fid,outmode)
654
         call close_tra(fid,outmode)
655
      endif
655
      endif
656
 
656
 
657
      endif
657
      endif
658
 
658
 
659
c     ------------------------------------------------------------
659
c     ------------------------------------------------------------
660
c     Convert a single lat/lon/z list to a x/y/z list
660
c     Convert a single lat/lon/z list to a x/y/z list
661
c     ------------------------------------------------------------
661
c     ------------------------------------------------------------
662
 
662
 
663
      if ( mode.eq.'-ll2xy.single' ) then
663
      if ( mode.eq.'-ll2xy.single' ) then
664
 
664
 
665
c     Transform coordinates
665
c     Transform coordinates
666
      rid  = (lonpos-lonmin)/dlon+1.
666
      rid  = (lonpos-lonmin)/dlon+1.
667
      rjd  = (latpos-latmin)/dlat+1.
667
      rjd  = (latpos-latmin)/dlat+1.
668
      xpos = int_index3(x,nlon,nlat,1,rid,rjd,1.,mdv)
668
      xpos = int_index3(x,nlon,nlat,1,rid,rjd,1.,mdv)
669
      ypos = int_index3(y,nlon,nlat,1,rid,rjd,1.,mdv)
669
      ypos = int_index3(y,nlon,nlat,1,rid,rjd,1.,mdv)
670
 
670
 
671
c	  Write result to screen
671
c	  Write result to screen
672
      print*,xpos,ypos
672
      print*,xpos,ypos
673
 
673
 
674
      endif
674
      endif
675
 
675
 
676
c     ------------------------------------------------------------
676
c     ------------------------------------------------------------
677
c     Convert a single x/y/z list to a lon/lat/z list
677
c     Convert a single x/y/z list to a lon/lat/z list
678
c     ------------------------------------------------------------
678
c     ------------------------------------------------------------
679
 
679
 
680
      if ( mode.eq.'-xy2ll.single' ) then
680
      if ( mode.eq.'-xy2ll.single' ) then
681
 
681
 
682
c     Transform coordinates
682
c     Transform coordinates
683
      rid    = (xpos-xmin)/dx+1.
683
      rid    = (xpos-xmin)/dx+1.
684
      rjd    = (ypos-ymin)/dy+1.
684
      rjd    = (ypos-ymin)/dy+1.
685
      lonpos = int_index3(lon,nx,ny,1,rid,rjd,1.,mdv)
685
      lonpos = int_index3(lon,nx,ny,1,rid,rjd,1.,mdv)
686
      latpos = int_index3(lat,nx,ny,1,rid,rjd,1.,mdv)
686
      latpos = int_index3(lat,nx,ny,1,rid,rjd,1.,mdv)
687
 
687
 
688
c	  Write result to screen
688
c	  Write result to screen
689
      print*,lonpos,latpos
689
      print*,lonpos,latpos
690
 
690
 
691
      endif
691
      endif
692
 
692
 
693
c     ------------------------------------------------------------
693
c     ------------------------------------------------------------
694
c     Calculate numerically the maps scale factor
694
c     Calculate numerically the maps scale factor
695
c     ------------------------------------------------------------
695
c     ------------------------------------------------------------
696
 
696
 
697
      if ( mode.eq.'-mapscale' ) then
697
      if ( mode.eq.'-mapscale' ) then
698
 
698
 
699
c	  Allocate memory for map scale factors
699
c	  Allocate memory for map scale factors
700
      allocate(mpx(nx,ny),stat=stat)
700
      allocate(mpx(nx,ny),stat=stat)
701
      if (stat.ne.0) print*,'*** error allocating array mpx       ***'
701
      if (stat.ne.0) print*,'*** error allocating array mpx       ***'
702
      allocate(mpy(nx,ny),stat=stat)
702
      allocate(mpy(nx,ny),stat=stat)
703
      if (stat.ne.0) print*,'*** error allocating array mpy       ***'
703
      if (stat.ne.0) print*,'*** error allocating array mpy       ***'
704
 
704
 
705
c     Get map scale for interior points
705
c     Get map scale for interior points
706
      do i=2,nx-1
706
      do i=2,nx-1
707
         do j=2,ny-1
707
         do j=2,ny-1
708
 
708
 
709
c           Map scale in x direction
709
c           Map scale in x direction
710
            lon1     = lon(i-1,j)
710
            lon1     = lon(i-1,j)
711
            lat1     = lat(i-1,j)
711
            lat1     = lat(i-1,j)
712
            lon2     = lon(i+1,j)
712
            lon2     = lon(i+1,j)
713
            lat2     = lat(i+1,j)
713
            lat2     = lat(i+1,j)
714
            radunit  = 'km.haversine'
714
            radunit  = 'km.haversine'
715
            mpx(i,j) = 0.5 * 1000. * sdis(lon1,lat1,lon2,lat2,radunit)
715
            mpx(i,j) = 0.5 * 1000. * sdis(lon1,lat1,lon2,lat2,radunit)
716
 
716
 
717
c           Map scale in y direction
717
c           Map scale in y direction
718
            lon1     = lon(i,j-1)
718
            lon1     = lon(i,j-1)
719
            lat1     = lat(i,j-1)
719
            lat1     = lat(i,j-1)
720
            lon2     = lon(i,j+1)
720
            lon2     = lon(i,j+1)
721
            lat2     = lat(i,j+1)
721
            lat2     = lat(i,j+1)
722
            radunit  = 'km.haversine'
722
            radunit  = 'km.haversine'
723
            mpy(i,j) = 0.5 * 1000. * sdis(lon1,lat1,lon2,lat2,radunit)
723
            mpy(i,j) = 0.5 * 1000. * sdis(lon1,lat1,lon2,lat2,radunit)
724
 
724
 
725
         enddo
725
         enddo
726
      enddo
726
      enddo
727
 
727
 
728
c     Copy map scale for boundary line points
728
c     Copy map scale for boundary line points
729
      do i=2,nx-1
729
      do i=2,nx-1
730
        mpx(i, 1) = mpx(i,   2)
730
        mpx(i, 1) = mpx(i,   2)
731
        mpx(i,ny) = mpx(i,ny-1)
731
        mpx(i,ny) = mpx(i,ny-1)
732
        mpy(i, 1) = mpy(i,   2)
732
        mpy(i, 1) = mpy(i,   2)
733
        mpy(i,ny) = mpy(i,ny-1)
733
        mpy(i,ny) = mpy(i,ny-1)
734
      enddo
734
      enddo
735
      do j=2,ny-1
735
      do j=2,ny-1
736
        mpx(1, j) = mpx(2,   j)
736
        mpx(1, j) = mpx(2,   j)
737
        mpx(nx,j) = mpx(nx-1,j)
737
        mpx(nx,j) = mpx(nx-1,j)
738
        mpy(1, j) = mpy(2,   j)
738
        mpy(1, j) = mpy(2,   j)
739
        mpy(nx,j) = mpy(nx-1,j)
739
        mpy(nx,j) = mpy(nx-1,j)
740
      enddo
740
      enddo
741
 
741
 
742
c     Copy map scale factor for boundary corner points
742
c     Copy map scale factor for boundary corner points
743
      mpx( 1, 1) = mpx(   2,   2)
743
      mpx( 1, 1) = mpx(   2,   2)
744
      mpy( 1, 1) = mpy(   2,   2)
744
      mpy( 1, 1) = mpy(   2,   2)
745
      mpx(nx, 1) = mpx(nx-1,   2)
745
      mpx(nx, 1) = mpx(nx-1,   2)
746
      mpy(nx, 1) = mpy(nx-1,   2)
746
      mpy(nx, 1) = mpy(nx-1,   2)
747
      mpx(nx,ny) = mpx(nx-1,ny-1)
747
      mpx(nx,ny) = mpx(nx-1,ny-1)
748
      mpy(nx,ny) = mpy(nx-1,ny-1)
748
      mpy(nx,ny) = mpy(nx-1,ny-1)
749
      mpx( 1,ny) = mpx(   2,ny-1)
749
      mpx( 1,ny) = mpx(   2,ny-1)
750
      mpy( 1,ny) = mpy(   2,ny-1)
750
      mpy( 1,ny) = mpy(   2,ny-1)
751
 
751
 
752
c     Apply a diffuive filter
752
c     Apply a diffuive filter
753
      do i=1,nfilter
753
      do i=1,nfilter
754
         call filt2d (mpx,mpx,nx,ny,1.0,-999.,0,0,0,0)
754
         call filt2d (mpx,mpx,nx,ny,1.0,-999.,0,0,0,0)
755
         call filt2d (mpy,mpy,nx,ny,1.0,-999.,0,0,0,0)
755
         call filt2d (mpy,mpy,nx,ny,1.0,-999.,0,0,0,0)
756
      enddo
756
      enddo
757
 
757
 
758
c     Write map factors to mapping file
758
c     Write map factors to mapping file
759
      cdfname = mapfile
759
      cdfname = mapfile
760
      varname = 'MAPSCALE_X'
760
      varname = 'MAPSCALE_X'
761
      call writecdf2D(cdfname,varname,mpx,0.,
761
      call writecdf2D(cdfname,varname,mpx,0.,
762
     >                dx,dy,xmin,ymin,nx,ny,1,0,1)
762
     >                dx,dy,xmin,ymin,nx,ny,1,0,1)
763
      cdfname = mapfile
763
      cdfname = mapfile
764
      varname = 'MAPSCALE_Y'
764
      varname = 'MAPSCALE_Y'
765
      call writecdf2D(cdfname,varname,mpy,0.,
765
      call writecdf2D(cdfname,varname,mpy,0.,
766
     >                dx,dy,xmin,ymin,nx,ny,1,0,1)
766
     >                dx,dy,xmin,ymin,nx,ny,1,0,1)
767
 
767
 
768
 
768
 
769
      endif
769
      endif
770
 
770
 
771
c     ------------------------------------------------------------
771
c     ------------------------------------------------------------
772
c     Convert from pressure to height
772
c     Convert from pressure to height
773
c     ------------------------------------------------------------
773
c     ------------------------------------------------------------
774
 
774
 
775
      if ( mode.eq.'-p2z' ) then
775
      if ( mode.eq.'-p2z' ) then
776
 
776
 
777
c     Allocate memory for input and output lists
777
c     Allocate memory for input and output lists
778
      allocate(tra(ntra,ntim,ncol),stat=stat)
778
      allocate(tra(ntra,ntim,ncol),stat=stat)
779
      if (stat.ne.0) print*,'*** error allocating array tra         ***'
779
      if (stat.ne.0) print*,'*** error allocating array tra         ***'
780
      allocate(xx0(ntra*ntim),stat=stat)
780
      allocate(xx0(ntra*ntim),stat=stat)
781
      if (stat.ne.0) print*,'*** error allocating array xx0         ***'
781
      if (stat.ne.0) print*,'*** error allocating array xx0         ***'
782
      allocate(yy0(ntra*ntim),stat=stat)
782
      allocate(yy0(ntra*ntim),stat=stat)
783
      if (stat.ne.0) print*,'*** error allocating array yy0         ***'
783
      if (stat.ne.0) print*,'*** error allocating array yy0         ***'
784
      allocate(zz0(ntra*ntim),stat=stat)
784
      allocate(zz0(ntra*ntim),stat=stat)
785
      if (stat.ne.0) print*,'*** error allocating array zz0         ***'
785
      if (stat.ne.0) print*,'*** error allocating array zz0         ***'
786
 
786
 
787
c     Get format of input and output file
787
c     Get format of input and output file
788
      call mode_tra(inpmode,inpfile)
788
      call mode_tra(inpmode,inpfile)
789
      call mode_tra(outmode,outfile)
789
      call mode_tra(outmode,outfile)
790
      if ( outmode.eq.-1) outmode=inpmode
790
      if ( outmode.eq.-1) outmode=inpmode
791
 
791
 
792
c     Read coordinates from file - Format (x,y,lev)
792
c     Read coordinates from file - Format (x,y,lev)
793
      if (inpmode.eq.-1) then
793
      if (inpmode.eq.-1) then
794
         fid = 10
794
         fid = 10
795
         npoints = 0
795
         npoints = 0
796
         open(fid,file=inpfile)
796
         open(fid,file=inpfile)
797
          do i=1,ntra
797
          do i=1,ntra
798
             npoints = npoints + 1
798
             npoints = npoints + 1
799
             read(fid,*) xx0(npoints),yy0(npoints),zz0(npoints)
799
             read(fid,*) xx0(npoints),yy0(npoints),zz0(npoints)
800
          enddo
800
          enddo
801
         close(fid)
801
         close(fid)
802
 
802
 
803
c     Read coordinates from trajectory file
803
c     Read coordinates from trajectory file
804
      else
804
      else
805
         call ropen_tra(fid,inpfile,ntra,ntim,ncol,refdate,vars,inpmode)
805
         call ropen_tra(fid,inpfile,ntra,ntim,ncol,refdate,vars,inpmode)
806
         call read_tra (fid,tra,ntra,ntim,ncol,inpmode)
806
         call read_tra (fid,tra,ntra,ntim,ncol,inpmode)
807
         call close_tra(fid,inpmode)
807
         call close_tra(fid,inpmode)
808
 
808
 
809
         if ( (vars(2).ne.'x').and.(vars(3).ne.'y') ) then
809
         if ( (vars(2).ne.'x').and.(vars(3).ne.'y') ) then
810
            print*,' ERROR: input must be in x/y format... Stop'
810
            print*,' ERROR: input must be in x/y format... Stop'
811
            stop
811
            stop
812
         endif
812
         endif
813
 
813
 
814
         npoints = 0
814
         npoints = 0
815
         do i=1,ntra
815
         do i=1,ntra
816
            do j=1,ntim
816
            do j=1,ntim
817
               npoints = npoints + 1
817
               npoints = npoints + 1
818
               xx0(npoints) = tra(i,j,2)
818
               xx0(npoints) = tra(i,j,2)
819
               yy0(npoints) = tra(i,j,3)
819
               yy0(npoints) = tra(i,j,3)
820
               zz0(npoints) = tra(i,j,4)
820
               zz0(npoints) = tra(i,j,4)
821
            enddo
821
            enddo
822
         enddo
822
         enddo
823
      endif
823
      endif
824
 
824
 
825
c     Transform coordinates
825
c     Transform coordinates
826
      do i=1,npoints
826
      do i=1,npoints
827
 
827
 
828
          call get_index3 (rid,rjd,rkd,xx0(i),yy0(i),-zz0(i),1,
828
          call get_index3 (rid,rjd,rkd,xx0(i),yy0(i),-zz0(i),1,
829
     >                     -p3,-ps,nx,ny,nz,xmin,ymin,dx,dy)
829
     >                     -p3,-ps,nx,ny,nz,xmin,ymin,dx,dy)
830
 
830
 
831
          zz0(i) = int_index3(z3,nx,ny,nz,rid,rjd,rkd,mdv)
831
          zz0(i) = int_index3(z3,nx,ny,nz,rid,rjd,rkd,mdv)
832
 
832
 
833
      enddo
833
      enddo
834
 
834
 
835
c     Write output to list
835
c     Write output to list
836
      if ( outmode.eq.-1 ) then
836
      if ( outmode.eq.-1 ) then
837
         fid = 10
837
         fid = 10
838
         open(fid,file=outfile)
838
         open(fid,file=outfile)
839
         do i=1,ntra
839
         do i=1,ntra
840
            write(fid,'(f9.2,f8.2,i6)') xx0(i),yy0(i),nint(zz0(i))
840
            write(fid,'(f9.2,f8.2,i6)') xx0(i),yy0(i),nint(zz0(i))
841
         enddo
841
         enddo
842
         close(fid)
842
         close(fid)
843
 
843
 
844
c     Write output to trajectory
844
c     Write output to trajectory
845
      else
845
      else
846
         npoints = 0
846
         npoints = 0
847
         do i=1,ntra
847
         do i=1,ntra
848
            do j=1,ntim
848
            do j=1,ntim
849
               npoints = npoints + 1
849
               npoints = npoints + 1
850
               tra(i,j,2) = xx0(npoints)
850
               tra(i,j,2) = xx0(npoints)
851
               tra(i,j,3) = yy0(npoints)
851
               tra(i,j,3) = yy0(npoints)
852
               tra(i,j,4) = zz0(npoints)
852
               tra(i,j,4) = zz0(npoints)
853
            enddo
853
            enddo
854
         enddo
854
         enddo
855
         if ( ncol.eq.3 ) ncol = 4
855
         if ( ncol.eq.3 ) ncol = 4
856
         vars(1) = 'time'
856
         vars(1) = 'time'
857
         vars(2) = 'x'
857
         vars(2) = 'x'
858
         vars(3) = 'y'
858
         vars(3) = 'y'
859
         vars(4) = 'z'
859
         vars(4) = 'z'
860
         call wopen_tra(fid,outfile,ntra,ntim,ncol,refdate,vars,outmode)
860
         call wopen_tra(fid,outfile,ntra,ntim,ncol,refdate,vars,outmode)
861
         call write_tra(fid,tra,ntra,ntim,ncol,outmode)
861
         call write_tra(fid,tra,ntra,ntim,ncol,outmode)
862
         call close_tra(fid,outmode)
862
         call close_tra(fid,outmode)
863
      endif
863
      endif
864
 
864
 
865
      endif
865
      endif
866
 
866
 
867
c     ------------------------------------------------------------
867
c     ------------------------------------------------------------
868
c     Convert single x/y/p to x/y/z
868
c     Convert single x/y/p to x/y/z
869
c     ------------------------------------------------------------
869
c     ------------------------------------------------------------
870
 
870
 
871
      if ( mode.eq.'-p2z.single' ) then
871
      if ( mode.eq.'-p2z.single' ) then
872
 
872
 
873
c     Transform coordinates - change from descending to ascending (minus sign)
873
c     Transform coordinates - change from descending to ascending (minus sign)
874
      call get_index3 (rid,rjd,rkd,xpos,ypos,-ppos,1,
874
      call get_index3 (rid,rjd,rkd,xpos,ypos,-ppos,1,
875
     >                 -p3,-ps,nx,ny,nz,xmin,ymin,dx,dy)
875
     >                 -p3,-ps,nx,ny,nz,xmin,ymin,dx,dy)
876
 
876
 
877
      zpos = int_index3(z3,nx,ny,nz,rid,rjd,rkd,mdv)
877
      zpos = int_index3(z3,nx,ny,nz,rid,rjd,rkd,mdv)
878
 
878
 
879
c	  Write result to screen
879
c	  Write result to screen
880
      print*,xpos,ypos,zpos
880
      print*,xpos,ypos,zpos
881
 
881
 
882
      endif
882
      endif
883
 
883
 
884
c     ------------------------------------------------------------
884
c     ------------------------------------------------------------
885
c     Convert from height to pressure
885
c     Convert from height to pressure
886
c     ------------------------------------------------------------
886
c     ------------------------------------------------------------
887
 
887
 
888
      if ( mode.eq.'-z2p' ) then
888
      if ( mode.eq.'-z2p' ) then
889
 
889
 
890
c     Allocate memory for input and output lists
890
c     Allocate memory for input and output lists
891
      allocate(tra(ntra,ntim,ncol),stat=stat)
891
      allocate(tra(ntra,ntim,ncol),stat=stat)
892
      if (stat.ne.0) print*,'*** error allocating array tra         ***'
892
      if (stat.ne.0) print*,'*** error allocating array tra         ***'
893
      allocate(xx0(ntra*ntim),stat=stat)
893
      allocate(xx0(ntra*ntim),stat=stat)
894
      if (stat.ne.0) print*,'*** error allocating array xx0         ***'
894
      if (stat.ne.0) print*,'*** error allocating array xx0         ***'
895
      allocate(yy0(ntra*ntim),stat=stat)
895
      allocate(yy0(ntra*ntim),stat=stat)
896
      if (stat.ne.0) print*,'*** error allocating array yy0         ***'
896
      if (stat.ne.0) print*,'*** error allocating array yy0         ***'
897
      allocate(zz0(ntra*ntim),stat=stat)
897
      allocate(zz0(ntra*ntim),stat=stat)
898
      if (stat.ne.0) print*,'*** error allocating array zz0         ***'
898
      if (stat.ne.0) print*,'*** error allocating array zz0         ***'
899
 
899
 
900
c     Get format of input and output file
900
c     Get format of input and output file
901
      call mode_tra(inpmode,inpfile)
901
      call mode_tra(inpmode,inpfile)
902
      call mode_tra(outmode,outfile)
902
      call mode_tra(outmode,outfile)
903
      if ( outmode.eq.-1) outmode=inpmode
903
      if ( outmode.eq.-1) outmode=inpmode
904
 
904
 
905
c     Read coordinates from file - Format (x,y,lev)
905
c     Read coordinates from file - Format (x,y,lev)
906
      if (inpmode.eq.-1) then
906
      if (inpmode.eq.-1) then
907
         fid = 10
907
         fid = 10
908
         npoints = 0
908
         npoints = 0
909
         open(fid,file=inpfile)
909
         open(fid,file=inpfile)
910
          do i=1,ntra
910
          do i=1,ntra
911
             npoints = npoints + 1
911
             npoints = npoints + 1
912
             read(fid,*) xx0(npoints),yy0(npoints),zz0(npoints)
912
             read(fid,*) xx0(npoints),yy0(npoints),zz0(npoints)
913
          enddo
913
          enddo
914
         close(fid)
914
         close(fid)
915
 
915
 
916
c     Read coordinates from trajectory file
916
c     Read coordinates from trajectory file
917
      else
917
      else
918
         call ropen_tra(fid,inpfile,ntra,ntim,ncol,refdate,vars,inpmode)
918
         call ropen_tra(fid,inpfile,ntra,ntim,ncol,refdate,vars,inpmode)
919
         call read_tra (fid,tra,ntra,ntim,ncol,inpmode)
919
         call read_tra (fid,tra,ntra,ntim,ncol,inpmode)
920
         call close_tra(fid,inpmode)
920
         call close_tra(fid,inpmode)
921
 
921
 
922
         if ( (vars(2).ne.'x').and.(vars(3).ne.'y') ) then
922
         if ( (vars(2).ne.'x').and.(vars(3).ne.'y') ) then
923
            print*,' ERROR: input must be in x/y format... Stop'
923
            print*,' ERROR: input must be in x/y format... Stop'
924
            stop
924
            stop
925
         endif
925
         endif
926
 
926
 
927
         npoints = 0
927
         npoints = 0
928
         do i=1,ntra
928
         do i=1,ntra
929
            do j=1,ntim
929
            do j=1,ntim
930
               npoints = npoints + 1
930
               npoints = npoints + 1
931
               xx0(npoints) = tra(i,j,2)
931
               xx0(npoints) = tra(i,j,2)
932
               yy0(npoints) = tra(i,j,3)
932
               yy0(npoints) = tra(i,j,3)
933
               zz0(npoints) = tra(i,j,4)
933
               zz0(npoints) = tra(i,j,4)
934
            enddo
934
            enddo
935
         enddo
935
         enddo
936
      endif
936
      endif
937
 
937
 
938
c     Transform coordinates
938
c     Transform coordinates
939
      do i=1,npoints
939
      do i=1,npoints
940
 
940
 
941
          call get_index3 (rid,rjd,rkd,xx0(i),yy0(i),zz0(i),1,
941
          call get_index3 (rid,rjd,rkd,xx0(i),yy0(i),zz0(i),1,
942
     >                     z3,zb,nx,ny,nz,xmin,ymin,dx,dy)
942
     >                     z3,zb,nx,ny,nz,xmin,ymin,dx,dy)
943
 
943
 
944
          zz0(i) = int_index3(p3,nx,ny,nz,rid,rjd,rkd,mdv)
944
          zz0(i) = int_index3(p3,nx,ny,nz,rid,rjd,rkd,mdv)
945
 
945
 
946
      enddo
946
      enddo
947
 
947
 
948
c     Write output to list
948
c     Write output to list
949
      if ( outmode.eq.-1 ) then
949
      if ( outmode.eq.-1 ) then
950
         fid = 10
950
         fid = 10
951
         open(fid,file=outfile)
951
         open(fid,file=outfile)
952
         do i=1,ntra
952
         do i=1,ntra
953
            write(fid,'(f9.2,f8.2,i6)') xx0(i),yy0(i),nint(zz0(i))
953
            write(fid,'(f9.2,f8.2,i6)') xx0(i),yy0(i),nint(zz0(i))
954
         enddo
954
         enddo
955
         close(fid)
955
         close(fid)
956
 
956
 
957
c     Write output to trajectory
957
c     Write output to trajectory
958
      else
958
      else
959
         npoints = 0
959
         npoints = 0
960
         do i=1,ntra
960
         do i=1,ntra
961
            do j=1,ntim
961
            do j=1,ntim
962
               npoints = npoints + 1
962
               npoints = npoints + 1
963
               tra(i,j,2) = xx0(npoints)
963
               tra(i,j,2) = xx0(npoints)
964
               tra(i,j,3) = yy0(npoints)
964
               tra(i,j,3) = yy0(npoints)
965
               tra(i,j,4) = zz0(npoints)
965
               tra(i,j,4) = zz0(npoints)
966
            enddo
966
            enddo
967
         enddo
967
         enddo
968
         if ( ncol.eq.3 ) ncol = 4
968
         if ( ncol.eq.3 ) ncol = 4
969
         vars(1) = 'time'
969
         vars(1) = 'time'
970
         vars(2) = 'x'
970
         vars(2) = 'x'
971
         vars(3) = 'y'
971
         vars(3) = 'y'
972
         vars(4) = 'p'
972
         vars(4) = 'p'
973
         call wopen_tra(fid,outfile,ntra,ntim,ncol,refdate,vars,outmode)
973
         call wopen_tra(fid,outfile,ntra,ntim,ncol,refdate,vars,outmode)
974
         call write_tra(fid,tra,ntra,ntim,ncol,outmode)
974
         call write_tra(fid,tra,ntra,ntim,ncol,outmode)
975
         call close_tra(fid,outmode)
975
         call close_tra(fid,outmode)
976
      endif
976
      endif
977
 
977
 
978
      endif
978
      endif
979
 
979
 
980
c     ------------------------------------------------------------
980
c     ------------------------------------------------------------
981
c     Convert single x/y/z to x/y/p
981
c     Convert single x/y/z to x/y/p
982
c     ------------------------------------------------------------
982
c     ------------------------------------------------------------
983
 
983
 
984
      if ( mode.eq.'-z2p.single' ) then
984
      if ( mode.eq.'-z2p.single' ) then
985
 
985
 
986
c     Transform coordinates - change from descending to ascending (minus sign)
986
c     Transform coordinates - change from descending to ascending (minus sign)
987
      call get_index3 (rid,rjd,rkd,xpos,ypos,zpos,1,
987
      call get_index3 (rid,rjd,rkd,xpos,ypos,zpos,1,
988
     >                 z3,zb,nx,ny,nz,xmin,ymin,dx,dy)
988
     >                 z3,zb,nx,ny,nz,xmin,ymin,dx,dy)
989
 
989
 
990
      ppos = int_index3(p3,nx,ny,nz,rid,rjd,rkd,mdv)
990
      ppos = int_index3(p3,nx,ny,nz,rid,rjd,rkd,mdv)
991
 
991
 
992
c	  Write result to screen
992
c	  Write result to screen
993
      print*,xpos,ypos,ppos
993
      print*,xpos,ypos,ppos
994
 
994
 
995
      endif
995
      endif
996
 
996
 
997
      end
997
      end
998
 
998
 
999
 
999
 
1000
c     ********************************************************************
1000
c     ********************************************************************
1001
c     * GRIDDING SUBROUTINES                                             *
1001
c     * GRIDDING SUBROUTINES                                             *
1002
c     ********************************************************************
1002
c     ********************************************************************
1003
 
1003
 
1004
c     ---------------------------------------------------------------------
1004
c     ---------------------------------------------------------------------
1005
c     Gridding of one single data point (smoothing in km, deg, gridp)
1005
c     Gridding of one single data point (smoothing in km, deg, gridp)
1006
c     ---------------------------------------------------------------------
1006
c     ---------------------------------------------------------------------
1007
 
1007
 
1008
      subroutine gridding1 (lat,lon,addval,radius,unit,
1008
      subroutine gridding1 (lat,lon,addval,radius,unit,
1009
     >                      connect,connectval,
1009
     >                      connect,connectval,
1010
     >                      out,outc,nx,ny,xmin,ymin,dx,dy)
1010
     >                      out,outc,nx,ny,xmin,ymin,dx,dy)
1011
 
1011
 
1012
      implicit none
1012
      implicit none
1013
 
1013
 
1014
c     Declaration of subroutine parameters
1014
c     Declaration of subroutine parameters
1015
      real         lat,lon
1015
      real         lat,lon
1016
      integer      nx,ny
1016
      integer      nx,ny
1017
      real         xmin,ymin,dx,dy
1017
      real         xmin,ymin,dx,dy
1018
      real         out(nx,ny),outc(nx,ny)
1018
      real         out(nx,ny),outc(nx,ny)
1019
      real         radius
1019
      real         radius
1020
      character*80 unit
1020
      character*80 unit
1021
      integer      connectval
1021
      integer      connectval
1022
      integer      connect(nx,ny)
1022
      integer      connect(nx,ny)
1023
      real         addval
1023
      real         addval
1024
 
1024
 
1025
c     Auxiliary variables
1025
c     Auxiliary variables
1026
      integer   i,j,k
1026
      integer   i,j,k
1027
      integer   mu,md,nr,nl,n,m
1027
      integer   mu,md,nr,nl,n,m
1028
      integer   stackx(nx*ny),stacky(nx*ny)
1028
      integer   stackx(nx*ny),stacky(nx*ny)
1029
      integer   tab_x(nx*ny),tab_y(nx*ny)
1029
      integer   tab_x(nx*ny),tab_y(nx*ny)
1030
      real      tab_r(nx*ny)
1030
      real      tab_r(nx*ny)
1031
      integer   sp
1031
      integer   sp
1032
      real      lat2,lon2
1032
      real      lat2,lon2
1033
      real      dist,sum
1033
      real      dist,sum
1034
      real      xmax
1034
      real      xmax
1035
      integer   periodic
1035
      integer   periodic
1036
      integer   test
1036
      integer   test
1037
      character ch
1037
      character ch
1038
 
1038
 
1039
c     Numerical epsilon
1039
c     Numerical epsilon
1040
      real      eps
1040
      real      eps
1041
      parameter (eps=0.01)
1041
      parameter (eps=0.01)
1042
 
1042
 
1043
c     Externals
1043
c     Externals
1044
      real      sdis,weight
1044
      real      sdis,weight
1045
      external  sdis,weight
1045
      external  sdis,weight
1046
 
1046
 
1047
c     Check whether lat/lon point is valid
1047
c     Check whether lat/lon point is valid
1048
      xmax=xmin+real(nx-1)*dx
1048
      xmax=xmin+real(nx-1)*dx
1049
      if (lon.lt.xmin-eps) lon=lon+360.
1049
      if (lon.lt.xmin-eps) lon=lon+360.
1050
      if (lon.gt.xmax+eps) lon=lon-360.
1050
      if (lon.gt.xmax+eps) lon=lon-360.
1051
      if (abs(lat-90).lt.eps) lat=90.
1051
      if (abs(lat-90).lt.eps) lat=90.
1052
      if (abs(lat+90).lt.eps) lat=-90.
1052
      if (abs(lat+90).lt.eps) lat=-90.
1053
      if ((abs(lat).gt.(90.+eps)).or.
1053
      if ((abs(lat).gt.(90.+eps)).or.
1054
     >    (lon.lt.xmin-eps).or.(lon.gt.xmax+eps)) then
1054
     >    (lon.lt.xmin-eps).or.(lon.gt.xmax+eps)) then
1055
         print*,'Invalid lat/lon point ',lat,lon
1055
         print*,'Invalid lat/lon point ',lat,lon
1056
         return
1056
         return
1057
      endif
1057
      endif
1058
 
1058
 
1059
c     Set flag for periodic domain
1059
c     Set flag for periodic domain
1060
      if (abs(xmax-xmin-360.).lt.eps) then
1060
      if (abs(xmax-xmin-360.).lt.eps) then
1061
         periodic=1
1061
         periodic=1
1062
      else if (abs(xmax-xmin-360+dx).lt.eps) then
1062
      else if (abs(xmax-xmin-360+dx).lt.eps) then
1063
         periodic=2
1063
         periodic=2
1064
      else
1064
      else
1065
         periodic=0
1065
         periodic=0
1066
      endif
1066
      endif
1067
 
1067
 
1068
c     Get indices of one coarse grid point within search radius
1068
c     Get indices of one coarse grid point within search radius
1069
      i=nint((lon-xmin)/dx)+1
1069
      i=nint((lon-xmin)/dx)+1
1070
      if ((i.eq.nx).and.(periodic.eq.1)) i=1
1070
      if ((i.eq.nx).and.(periodic.eq.1)) i=1
1071
      j=nint((lat-ymin)/dy)+1
1071
      j=nint((lat-ymin)/dy)+1
1072
      lat2=ymin+real(j-1)*dy
1072
      lat2=ymin+real(j-1)*dy
1073
      lon2=xmin+real(i-1)*dx
1073
      lon2=xmin+real(i-1)*dx
1074
      dist=sdis(lon,lat,lon2,lat2,unit)
1074
      dist=sdis(lon,lat,lon2,lat2,unit)
1075
      if (dist.gt.radius) then
1075
      if (dist.gt.radius) then
1076
         print*,'1: Search radius is too small...'
1076
         print*,'1: Search radius is too small...'
1077
         stop
1077
         stop
1078
      endif
1078
      endif
1079
 
1079
 
1080
c     Get connected points
1080
c     Get connected points
1081
      k=0
1081
      k=0
1082
      stackx(1)=i
1082
      stackx(1)=i
1083
      stacky(1)=j
1083
      stacky(1)=j
1084
      sp    = 1
1084
      sp    = 1
1085
      do while (sp.ne.0) 
1085
      do while (sp.ne.0) 
1086
         
1086
         
1087
c        Get an element from stack
1087
c        Get an element from stack
1088
         n=stackx(sp)
1088
         n=stackx(sp)
1089
         m=stacky(sp)
1089
         m=stacky(sp)
1090
         sp=sp-1
1090
         sp=sp-1
1091
                  
1091
                  
1092
c        Get distance from reference point
1092
c        Get distance from reference point
1093
         lat2=ymin+real(m-1)*dy
1093
         lat2=ymin+real(m-1)*dy
1094
         lon2=xmin+real(n-1)*dx
1094
         lon2=xmin+real(n-1)*dx
1095
         dist=sdis(lon,lat,lon2,lat2,unit)
1095
         dist=sdis(lon,lat,lon2,lat2,unit)
1096
 
1096
 
1097
c        Check whether distance is smaller than search radius: connected
1097
c        Check whether distance is smaller than search radius: connected
1098
         if (dist.lt.radius) then
1098
         if (dist.lt.radius) then
1099
 
1099
 
1100
c           Make entry in filter mask
1100
c           Make entry in filter mask
1101
            k=k+1
1101
            k=k+1
1102
            tab_x(k)=n
1102
            tab_x(k)=n
1103
            tab_y(k)=m
1103
            tab_y(k)=m
1104
            tab_r(k)=weight(dist,radius)
1104
            tab_r(k)=weight(dist,radius)
1105
 
1105
 
1106
c           Mark this point as visited
1106
c           Mark this point as visited
1107
            connect(n,m)=connectval
1107
            connect(n,m)=connectval
1108
                     
1108
                     
1109
c           Get coordinates of neighbouring points
1109
c           Get coordinates of neighbouring points
1110
            nr=n+1
1110
            nr=n+1
1111
            if ((nr.gt.nx)  .and.(periodic.eq.0)) nr=nx
1111
            if ((nr.gt.nx)  .and.(periodic.eq.0)) nr=nx
1112
            if ((nr.gt.nx-1).and.(periodic.eq.1)) nr=1
1112
            if ((nr.gt.nx-1).and.(periodic.eq.1)) nr=1
1113
            if ((nr.gt.nx)  .and.(periodic.eq.2)) nr=1
1113
            if ((nr.gt.nx)  .and.(periodic.eq.2)) nr=1
1114
            nl=n-1
1114
            nl=n-1
1115
            if ((nl.lt.1).and.(periodic.eq.0)) nl=1
1115
            if ((nl.lt.1).and.(periodic.eq.0)) nl=1
1116
            if ((nl.lt.1).and.(periodic.eq.1)) nl=nx-1
1116
            if ((nl.lt.1).and.(periodic.eq.1)) nl=nx-1
1117
            if ((nl.lt.1).and.(periodic.eq.2)) nl=nx
1117
            if ((nl.lt.1).and.(periodic.eq.2)) nl=nx
1118
            mu=m+1
1118
            mu=m+1
1119
            if (mu.gt.ny) mu=ny
1119
            if (mu.gt.ny) mu=ny
1120
            md=m-1
1120
            md=m-1
1121
            if (md.lt.1) md=1
1121
            if (md.lt.1) md=1
1122
 
1122
 
1123
c           Update stack
1123
c           Update stack
1124
            if (connect(nr,m).ne.connectval) then
1124
            if (connect(nr,m).ne.connectval) then
1125
               connect(nr,m)=connectval
1125
               connect(nr,m)=connectval
1126
               sp=sp+1
1126
               sp=sp+1
1127
               stackx(sp)=nr
1127
               stackx(sp)=nr
1128
               stacky(sp)=m
1128
               stacky(sp)=m
1129
            endif
1129
            endif
1130
            if (connect(nl,m).ne.connectval) then
1130
            if (connect(nl,m).ne.connectval) then
1131
               connect(nl,m)=connectval
1131
               connect(nl,m)=connectval
1132
               sp=sp+1
1132
               sp=sp+1
1133
               stackx(sp)=nl
1133
               stackx(sp)=nl
1134
               stacky(sp)=m
1134
               stacky(sp)=m
1135
            endif
1135
            endif
1136
            if (connect(n,mu).ne.connectval) then
1136
            if (connect(n,mu).ne.connectval) then
1137
               connect(n,mu)=connectval
1137
               connect(n,mu)=connectval
1138
               sp=sp+1
1138
               sp=sp+1
1139
               stackx(sp)=n
1139
               stackx(sp)=n
1140
               stacky(sp)=mu
1140
               stacky(sp)=mu
1141
            endif
1141
            endif
1142
            if (connect(n,md).ne.connectval) then
1142
            if (connect(n,md).ne.connectval) then
1143
               connect(n,md)=connectval
1143
               connect(n,md)=connectval
1144
               sp=sp+1
1144
               sp=sp+1
1145
               stackx(sp)=n
1145
               stackx(sp)=n
1146
               stacky(sp)=md
1146
               stacky(sp)=md
1147
            endif
1147
            endif
1148
         endif     
1148
         endif     
1149
 
1149
 
1150
      end do
1150
      end do
1151
 
1151
 
1152
      if (k.ge.1) then
1152
      if (k.ge.1) then
1153
         sum=0.
1153
         sum=0.
1154
         do i=1,k
1154
         do i=1,k
1155
            sum=sum+tab_r(i)
1155
            sum=sum+tab_r(i)
1156
         enddo
1156
         enddo
1157
         do i=1,k
1157
         do i=1,k
1158
            out (tab_x(i),tab_y(i))=out(tab_x(i),tab_y(i))+
1158
            out (tab_x(i),tab_y(i))=out(tab_x(i),tab_y(i))+
1159
     >                             addval*tab_r(i)/sum
1159
     >                             addval*tab_r(i)/sum
1160
            outc(tab_x(i),tab_y(i))=outc(tab_x(i),tab_y(i))+
1160
            outc(tab_x(i),tab_y(i))=outc(tab_x(i),tab_y(i))+
1161
     >                             1.*tab_r(i)/sum
1161
     >                             1.*tab_r(i)/sum
1162
 
1162
 
1163
            if ((tab_x(i).eq.1).and.(periodic.eq.1)) then
1163
            if ((tab_x(i).eq.1).and.(periodic.eq.1)) then
1164
               out(nx,tab_y(i))=out(nx,tab_y(i))+
1164
               out(nx,tab_y(i))=out(nx,tab_y(i))+
1165
     >                             addval*tab_r(i)/sum
1165
     >                             addval*tab_r(i)/sum
1166
               outc(nx,tab_y(i))=outc(nx,tab_y(i))+
1166
               outc(nx,tab_y(i))=outc(nx,tab_y(i))+
1167
     >                             1.*tab_r(i)/sum
1167
     >                             1.*tab_r(i)/sum
1168
 
1168
 
1169
            endif
1169
            endif
1170
         enddo
1170
         enddo
1171
      else
1171
      else
1172
         print*,'2: Search radius is too small...'
1172
         print*,'2: Search radius is too small...'
1173
         stop
1173
         stop
1174
      endif
1174
      endif
1175
 
1175
 
1176
      end
1176
      end
1177
 
1177
 
1178
 
1178
 
1179
c     ----------------------------------------------------------------------
1179
c     ----------------------------------------------------------------------
1180
c     Get spherical distance between lat/lon points
1180
c     Get spherical distance between lat/lon points
1181
c     ----------------------------------------------------------------------
1181
c     ----------------------------------------------------------------------
1182
            
1182
        
1183
      real function sdis(xp,yp,xq,yq,unit)
1183
      real function sdis(xp,yp,xq,yq,unit)
1184
 
1184
 
1185
c     Calculates spherical distance (in km) between two points given
1185
c     Calculates spherical distance (in km) between two points given
1186
c     by their spherical coordinates (xp,yp) and (xq,yq), respectively.
1186
c     by their spherical coordinates (xp,yp) and (xq,yq), respectively.
1187
 
1187
 
1188
      real,parameter ::       re=6371.229
1188
      real,parameter ::       re=6371.229
1189
      real,parameter ::       rad2deg=180./3.14159265
1189
      real,parameter ::       rad2deg=180./3.14159265
1190
      real,parameter ::       deg2rad=3.141592654/180.
1190
      real,parameter ::       deg2rad=3.141592654/180.
1191
 
1191
 
1192
      real         xp,yp,xq,yq,arg
1192
      real         xp,yp,xq,yq,arg
1193
      character*80 unit
1193
      character*80 unit
1194
      real         dlon,dlat,alpha,rlat1,ralt2
1194
      real         dlon,dlat,alpha,rlat1,ralt2
1195
 
1195
 
1196
      if ( unit.eq.'km' ) then
1196
      if ( unit.eq.'km' ) then
1197
 
1197
 
1198
         arg=sind(yp)*sind(yq)+cosd(yp)*cosd(yq)*cosd(xp-xq)
1198
         arg=sin(yp*deg2rad)*sin(yq*deg2rad)+
-
 
1199
     >           cos(yp*deg2rad)*cos(yq*deg2rad)*cos((xp-xq)*deg2rad)
1199
         if (arg.lt.-1.) arg=-1.
1200
         if (arg.lt.-1.) arg=-1.
1200
         if (arg.gt.1.) arg=1.
1201
         if (arg.gt.1.) arg=1.
1201
         sdis=re*acos(arg)
1202
         sdis=re*acos(arg)
1202
         
1203
         
1203
      elseif ( unit.eq.'deg' ) then
1204
      elseif ( unit.eq.'deg' ) then
1204
 
1205
 
1205
         dlon = xp-xq
1206
         dlon = xp-xq
1206
         if ( dlon.gt. 180. ) dlon = dlon - 360.
1207
         if ( dlon.gt. 180. ) dlon = dlon - 360.
1207
         if ( dlon.lt.-180. ) dlon = dlon + 360.
1208
         if ( dlon.lt.-180. ) dlon = dlon + 360.
1208
         sdis = sqrt( dlon**2 + (yp-yq)**2 )
1209
         sdis = sqrt( dlon**2 + (yp-yq)**2 )
1209
 
1210
 
1210
      elseif ( unit.eq.'km.haversine' ) then
1211
      elseif ( unit.eq.'km.haversine' ) then
1211
 
1212
 
1212
        dlat   =  (yp - yq)*deg2rad
1213
        dlat   =  (yp - yq)*deg2rad
1213
        dlon   =  (xp - xq)*deg2rad
1214
        dlon   =  (xp - xq)*deg2rad
1214
        rlat1   =  yp*deg2rad
1215
        rlat1   =  yp*deg2rad
1215
        rlat2   =  yq*deg2rad
1216
        rlat2   =  yq*deg2rad
1216
 
1217
 
1217
        alpha  = ( sin(0.5*dlat)**2 ) +
1218
        alpha  = ( sin(0.5*dlat)**2 ) +
1218
     >           ( sin(0.5*dlon)**2 )*cos(rlat1)*cos(rlat2)
1219
     >           ( sin(0.5*dlon)**2 )*cos(rlat1)*cos(rlat2)
1219
 
1220
 
1220
        sdis = 4. * re * atan2( sqrt(alpha),1. + sqrt( 1. - alpha ) )
1221
        sdis = 4. * re * atan2( sqrt(alpha),1. + sqrt( 1. - alpha ) )
1221
 
1222
 
1222
      endif  
1223
      endif  
1223
 
1224
 
1224
      end
1225
      end
1225
 
1226
 
1226
c     ----------------------------------------------------------------------
1227
c     ----------------------------------------------------------------------
1227
c     Weight function for the filter mask
1228
c     Weight function for the filter mask
1228
c     ----------------------------------------------------------------------
1229
c     ----------------------------------------------------------------------
1229
 
1230
 
1230
      real function weight (r,radius)
1231
      real function weight (r,radius)
1231
 
1232
 
1232
c     Attribute to each distanc r its corresponding weight in the filter mask
1233
c     Attribute to each distanc r its corresponding weight in the filter mask
1233
 
1234
 
1234
      implicit none
1235
      implicit none
1235
 
1236
 
1236
c     Declaration of subroutine parameters
1237
c     Declaration of subroutine parameters
1237
      real r
1238
      real r
1238
      real radius
1239
      real radius
1239
 
1240
 
1240
c     Simple 0/1 mask
1241
c     Simple 0/1 mask
1241
      if (r.lt.radius) then
1242
      if (r.lt.radius) then
1242
          weight=1.-0.65*r/radius 
1243
          weight=1.-0.65*r/radius 
1243
      else
1244
      else
1244
          weight=0.
1245
          weight=0.
1245
      endif
1246
      endif
1246
 
1247
 
1247
      end
1248
      end
1248
 
1249
 
1249
 
1250
 
1250
c     ********************************************************************
1251
c     ********************************************************************
1251
c     * INPUT / OUTPUT SUBROUTINES                                       *
1252
c     * INPUT / OUTPUT SUBROUTINES                                       *
1252
c     ********************************************************************
1253
c     ********************************************************************
1253
 
1254
 
1254
c     --------------------------------------------------------------------
1255
c     --------------------------------------------------------------------
1255
c     Subroutines to write the netcdf output file
1256
c     Subroutines to write the netcdf output file
1256
c     --------------------------------------------------------------------
1257
c     --------------------------------------------------------------------
1257
 
1258
 
1258
      subroutine writecdf2D(cdfname,
1259
      subroutine writecdf2D(cdfname,
1259
     >                      varname,arr,time,
1260
     >                      varname,arr,time,
1260
     >                      dx,dy,xmin,ymin,nx,ny,nz,
1261
     >                      dx,dy,xmin,ymin,nx,ny,nz,
1261
     >                      crefile,crevar)
1262
     >                      crefile,crevar)
1262
 
1263
 
1263
      IMPLICIT NONE
1264
      IMPLICIT NONE
1264
 
1265
 
1265
c     Declaration of input parameters
1266
c     Declaration of input parameters
1266
      character*80 cdfname,varname
1267
      character*80 cdfname,varname
1267
      integer nx,ny,nz
1268
      integer nx,ny,nz
1268
      real arr(nx,ny,nz)
1269
      real arr(nx,ny,nz)
1269
      real dx,dy,xmin,ymin
1270
      real dx,dy,xmin,ymin
1270
      real time
1271
      real time
1271
      integer crefile,crevar
1272
      integer crefile,crevar
1272
 
1273
 
1273
c     Further variables
1274
c     Further variables
1274
      real varmin(4),varmax(4),stag(4)
1275
      real varmin(4),varmax(4),stag(4)
1275
      integer ierr,cdfid,ndim,vardim(4)
1276
      integer ierr,cdfid,ndim,vardim(4)
1276
      character*80 cstname
1277
      character*80 cstname
1277
      real mdv
1278
      real mdv
1278
      integer i
1279
      integer i
1279
      integer nvars
1280
      integer nvars
1280
      character*80 vars(300)
1281
      character*80 vars(300)
1281
 
1282
 
1282
C     Definitions
1283
C     Definitions
1283
      varmin(1)=xmin
1284
      varmin(1)=xmin
1284
      varmin(2)=ymin
1285
      varmin(2)=ymin
1285
      varmin(3)=1050.
1286
      varmin(3)=1050.
1286
      varmax(1)=xmin+real(nx-1)*dx
1287
      varmax(1)=xmin+real(nx-1)*dx
1287
      varmax(2)=ymin+real(ny-1)*dy
1288
      varmax(2)=ymin+real(ny-1)*dy
1288
      varmax(3)=1050.
1289
      varmax(3)=1050.
1289
      cstname='no_constants_file'
1290
      cstname='no_constants_file'
1290
      ndim=4
1291
      ndim=4
1291
      vardim(1)=nx
1292
      vardim(1)=nx
1292
      vardim(2)=ny
1293
      vardim(2)=ny
1293
      vardim(3)=nz
1294
      vardim(3)=nz
1294
      stag(1)=0.
1295
      stag(1)=0.
1295
      stag(2)=0.
1296
      stag(2)=0.
1296
      stag(3)=0.
1297
      stag(3)=0.
1297
      mdv=-999.98999
1298
      mdv=-999.98999
1298
 
1299
 
1299
C     Create the file
1300
C     Create the file
1300
      if (crefile.eq.0) then
1301
      if (crefile.eq.0) then
1301
         call cdfwopn(cdfname,cdfid,ierr)
1302
         call cdfwopn(cdfname,cdfid,ierr)
1302
         if (ierr.ne.0) goto 906
1303
         if (ierr.ne.0) goto 906
1303
      else if (crefile.eq.1) then
1304
      else if (crefile.eq.1) then
1304
         call crecdf(cdfname,cdfid,
1305
         call crecdf(cdfname,cdfid,
1305
     >        varmin,varmax,ndim,cstname,ierr)
1306
     >        varmin,varmax,ndim,cstname,ierr)
1306
         if (ierr.ne.0) goto 903
1307
         if (ierr.ne.0) goto 903
1307
      endif
1308
      endif
1308
 
1309
 
1309
c     Check whether the variable is already on the file
1310
c     Check whether the variable is already on the file
1310
      call getvars(cdfid,nvars,vars,ierr)
1311
      call getvars(cdfid,nvars,vars,ierr)
1311
      if (ierr.ne.0) goto 906
1312
      if (ierr.ne.0) goto 906
1312
      do i=1,nvars
1313
      do i=1,nvars
1313
         if ( vars(i).eq.varname ) crevar = 0
1314
         if ( vars(i).eq.varname ) crevar = 0
1314
      enddo
1315
      enddo
1315
 
1316
 
1316
c     Write the data to the netcdf file, and close the file
1317
c     Write the data to the netcdf file, and close the file
1317
      if (crevar.eq.1) then
1318
      if (crevar.eq.1) then
1318
         call putdef(cdfid,varname,ndim,mdv,
1319
         call putdef(cdfid,varname,ndim,mdv,
1319
     >        vardim,varmin,varmax,stag,ierr)
1320
     >        vardim,varmin,varmax,stag,ierr)
1320
         if (ierr.ne.0) goto 904
1321
         if (ierr.ne.0) goto 904
1321
      endif
1322
      endif
1322
      call putdat(cdfid,varname,time,0,arr,ierr)
1323
      call putdat(cdfid,varname,time,0,arr,ierr)
1323
      if (ierr.ne.0) goto 905
1324
      if (ierr.ne.0) goto 905
1324
      call clscdf(cdfid,ierr)
1325
      call clscdf(cdfid,ierr)
1325
 
1326
 
1326
      return
1327
      return
1327
 
1328
 
1328
c     Error handling
1329
c     Error handling
1329
 903  print*,'*** Problem to create netcdf file ***'
1330
 903  print*,'*** Problem to create netcdf file ***'
1330
      stop
1331
      stop
1331
 904  print*,'*** Problem to write definition ***'
1332
 904  print*,'*** Problem to write definition ***'
1332
      stop
1333
      stop
1333
 905  print*,'*** Problem to write data ***'
1334
 905  print*,'*** Problem to write data ***'
1334
      stop
1335
      stop
1335
 906  print*,'*** Problem to open netcdf file ***'
1336
 906  print*,'*** Problem to open netcdf file ***'
1336
      stop
1337
      stop
1337
 
1338
 
1338
      end
1339
      end
1339
 
1340
 
1340
 
1341
 
1341
c     -----------------------------------------------
1342
c     -----------------------------------------------
1342
c     Subroutine to read a netcdf output file
1343
c     Subroutine to read a netcdf output file
1343
c     -----------------------------------------------
1344
c     -----------------------------------------------
1344
 
1345
 
1345
      subroutine readcdf2D(cdfname,varname,arr,time,
1346
      subroutine readcdf2D(cdfname,varname,arr,time,
1346
     >                     dx,dy,xmin,ymin,nx,ny,nz)
1347
     >                     dx,dy,xmin,ymin,nx,ny,nz)
1347
 
1348
 
1348
      implicit none
1349
      implicit none
1349
 
1350
 
1350
c     Declaration of input parameters
1351
c     Declaration of input parameters
1351
      character*80 cdfname,varname
1352
      character*80 cdfname,varname
1352
      integer      nx,ny,nz
1353
      integer      nx,ny,nz
1353
      real         arr(nx,ny,nz)
1354
      real         arr(nx,ny,nz)
1354
      real         dx,dy,xmin,ymin
1355
      real         dx,dy,xmin,ymin
1355
      real         time
1356
      real         time
1356
 
1357
 
1357
c     Internal variables for the netcdf file
1358
c     Internal variables for the netcdf file
1358
      real         varmin(4),varmax(4),stag(4)
1359
      real         varmin(4),varmax(4),stag(4)
1359
      integer      ierr,cdfid,ndim,vardim(4)
1360
      integer      ierr,cdfid,ndim,vardim(4)
1360
      real         mdv
1361
      real         mdv
1361
      real         delx,dely
1362
      real         delx,dely
1362
      real         times(500)
1363
      real         times(500)
1363
      integer      ntimes,flag
1364
      integer      ntimes,flag
1364
 
1365
 
1365
c     Numerical epsilon
1366
c     Numerical epsilon
1366
      real         eps
1367
      real         eps
1367
      parameter    (eps=0.01)
1368
      parameter    (eps=0.01)
1368
 
1369
 
1369
c     Auxiliary variables
1370
c     Auxiliary variables
1370
      integer      i,j,k
1371
      integer      i,j,k
1371
 
1372
 
1372
c     Initialize the ouput array
1373
c     Initialize the ouput array
1373
      do i=1,nx
1374
      do i=1,nx
1374
         do j=1,ny
1375
         do j=1,ny
1375
            do k=1,nz
1376
            do k=1,nz
1376
               arr(i,j,k)=0.
1377
               arr(i,j,k)=0.
1377
            enddo
1378
            enddo
1378
         enddo
1379
         enddo
1379
      enddo
1380
      enddo
1380
 
1381
 
1381
c     Try to open the netcdf file and to read the variable
1382
c     Try to open the netcdf file and to read the variable
1382
      call cdfopn(cdfname,cdfid,ierr)
1383
      call cdfopn(cdfname,cdfid,ierr)
1383
      if (ierr.ne.0) goto 801
1384
      if (ierr.ne.0) goto 801
1384
 
1385
 
1385
c     Check whether the specifieed time is available
1386
c     Check whether the specifieed time is available
1386
      call gettimes(cdfid,times,ntimes,ierr)
1387
      call gettimes(cdfid,times,ntimes,ierr)
1387
      if (ierr.ne.0) goto 801
1388
      if (ierr.ne.0) goto 801
1388
      flag=0
1389
      flag=0
1389
      do i=1,ntimes
1390
      do i=1,ntimes
1390
          if (abs(times(i)-time).lt.eps) flag=1
1391
          if (abs(times(i)-time).lt.eps) flag=1
1391
      enddo
1392
      enddo
1392
      if (flag.eq.0) then
1393
      if (flag.eq.0) then
1393
         print*,'No such time on cdf',time
1394
         print*,'No such time on cdf',time
1394
         stop
1395
         stop
1395
      endif
1396
      endif
1396
 
1397
 
1397
c     Get the variable definition, and the grid
1398
c     Get the variable definition, and the grid
1398
      call getdef(cdfid,varname,ndim,mdv,vardim,varmin,varmax,
1399
      call getdef(cdfid,varname,ndim,mdv,vardim,varmin,varmax,
1399
     >     stag,ierr)
1400
     >     stag,ierr)
1400
      if (ierr.ne.0) goto 801
1401
      if (ierr.ne.0) goto 801
1401
 
1402
 
1402
c     Set parameters or read parameters - depending on nx,ny
1403
c     Set parameters or read parameters - depending on nx,ny
1403
      if ( (nx.eq.1).and.(ny.eq.1) ) then
1404
      if ( (nx.eq.1).and.(ny.eq.1) ) then
1404
         dx   = (varmax(1)-varmin(1))/real(vardim(1)-1)
1405
         dx   = (varmax(1)-varmin(1))/real(vardim(1)-1)
1405
         dy   = (varmax(2)-varmin(2))/real(vardim(2)-1)
1406
         dy   = (varmax(2)-varmin(2))/real(vardim(2)-1)
1406
         nx   = vardim(1)
1407
         nx   = vardim(1)
1407
         ny   = vardim(2)
1408
         ny   = vardim(2)
1408
         nz   = vardim(3)
1409
         nz   = vardim(3)
1409
         xmin = varmin(1)
1410
         xmin = varmin(1)
1410
         ymin = varmin(2)
1411
         ymin = varmin(2)
1411
      else
1412
      else
1412
         call getdat(cdfid,varname,time,0,arr,ierr)
1413
         call getdat(cdfid,varname,time,0,arr,ierr)
1413
         if (ierr.ne.0) goto 801
1414
         if (ierr.ne.0) goto 801
1414
      endif
1415
      endif
1415
 
1416
 
1416
c     Close data file
1417
c     Close data file
1417
      call clscdf(cdfid,ierr)
1418
      call clscdf(cdfid,ierr)
1418
 
1419
 
1419
      return
1420
      return
1420
      
1421
      
1421
c     Exception handling
1422
c     Exception handling
1422
 801  print*,'Problems in reading netcdf file'
1423
 801  print*,'Problems in reading netcdf file'
1423
      stop
1424
      stop
1424
      
1425
      
1425
      end
1426
      end
1426
 
1427
 
1427
 
1428
 
1428
c     -----------------------------------------------
1429
c     -----------------------------------------------
1429
c     Diffusive filter
1430
c     Diffusive filter
1430
c     -----------------------------------------------
1431
c     -----------------------------------------------
1431
 
1432
 
1432
      subroutine filt2d (a,af,nx,ny,fil,misdat,
1433
      subroutine filt2d (a,af,nx,ny,fil,misdat,
1433
     &                   iperx,ipery,ispol,inpol)
1434
     &                   iperx,ipery,ispol,inpol)
1434
 
1435
 
1435
c     Apply a conservative diffusion operator onto the 2d field a,
1436
c     Apply a conservative diffusion operator onto the 2d field a,
1436
c     with full missing data checking.
1437
c     with full missing data checking.
1437
c
1438
c
1438
c     a     real   inp  array to be filtered, dimensioned (nx,ny)
1439
c     a     real   inp  array to be filtered, dimensioned (nx,ny)
1439
c     af    real   out  filtered array, dimensioned (nx,ny), can be
1440
c     af    real   out  filtered array, dimensioned (nx,ny), can be
1440
c                       equivalenced with array a in the calling routine
1441
c                       equivalenced with array a in the calling routine
1441
c     f1    real        workarray, dimensioned (nx+1,ny)
1442
c     f1    real        workarray, dimensioned (nx+1,ny)
1442
c     f2    real        workarray, dimensioned (nx,ny+1)
1443
c     f2    real        workarray, dimensioned (nx,ny+1)
1443
c     fil   real   inp  filter-coeff., 0<afil<=1. Maximum filtering with afil=1
1444
c     fil   real   inp  filter-coeff., 0<afil<=1. Maximum filtering with afil=1
1444
c                       corresponds to one application of the linear filter.
1445
c                       corresponds to one application of the linear filter.
1445
c     misdat real  inp  missing-data value, a(i,j)=misdat indicates that
1446
c     misdat real  inp  missing-data value, a(i,j)=misdat indicates that
1446
c                       the corresponding value is not available. The
1447
c                       the corresponding value is not available. The
1447
c                       misdat-checking can be switched off with with misdat=0.
1448
c                       misdat-checking can be switched off with with misdat=0.
1448
c     iperx int    inp  periodic boundaries in the x-direction (1=yes,0=no)
1449
c     iperx int    inp  periodic boundaries in the x-direction (1=yes,0=no)
1449
c     ipery int    inp  periodic boundaries in the y-direction (1=yes,0=no)
1450
c     ipery int    inp  periodic boundaries in the y-direction (1=yes,0=no)
1450
c     inpol int    inp  northpole at j=ny  (1=yes,0=no)
1451
c     inpol int    inp  northpole at j=ny  (1=yes,0=no)
1451
c     ispol int    inp  southpole at j=1   (1=yes,0=no)
1452
c     ispol int    inp  southpole at j=1   (1=yes,0=no)
1452
c
1453
c
1453
c     Christoph Schaer, 1993
1454
c     Christoph Schaer, 1993
1454
 
1455
 
1455
c     argument declaration
1456
c     argument declaration
1456
      integer     nx,ny
1457
      integer     nx,ny
1457
      real        a(nx,ny),af(nx,ny),fil,misdat
1458
      real        a(nx,ny),af(nx,ny),fil,misdat
1458
      integer     iperx,ipery,inpol,ispol
1459
      integer     iperx,ipery,inpol,ispol
1459
 
1460
 
1460
c     local variable declaration
1461
c     local variable declaration
1461
      integer     i,j,is
1462
      integer     i,j,is
1462
      real        fh
1463
      real        fh
1463
      real        f1(nx+1,ny),f2(nx,ny+1)
1464
      real        f1(nx+1,ny),f2(nx,ny+1)
1464
 
1465
 
1465
c     compute constant fh
1466
c     compute constant fh
1466
      fh=0.125*fil
1467
      fh=0.125*fil
1467
 
1468
 
1468
c     compute fluxes in x-direction
1469
c     compute fluxes in x-direction
1469
      if (misdat.eq.0.) then
1470
      if (misdat.eq.0.) then
1470
        do j=1,ny
1471
        do j=1,ny
1471
        do i=2,nx
1472
        do i=2,nx
1472
          f1(i,j)=a(i-1,j)-a(i,j)
1473
          f1(i,j)=a(i-1,j)-a(i,j)
1473
        enddo
1474
        enddo
1474
        enddo
1475
        enddo
1475
      else
1476
      else
1476
        do j=1,ny
1477
        do j=1,ny
1477
        do i=2,nx
1478
        do i=2,nx
1478
          if ((a(i,j).eq.misdat).or.(a(i-1,j).eq.misdat)) then
1479
          if ((a(i,j).eq.misdat).or.(a(i-1,j).eq.misdat)) then
1479
            f1(i,j)=0.
1480
            f1(i,j)=0.
1480
          else
1481
          else
1481
            f1(i,j)=a(i-1,j)-a(i,j)
1482
            f1(i,j)=a(i-1,j)-a(i,j)
1482
          endif
1483
          endif
1483
        enddo
1484
        enddo
1484
        enddo
1485
        enddo
1485
      endif
1486
      endif
1486
      if (iperx.eq.1) then
1487
      if (iperx.eq.1) then
1487
c       do periodic boundaries in the x-direction
1488
c       do periodic boundaries in the x-direction
1488
        do j=1,ny
1489
        do j=1,ny
1489
          f1(1,j)=f1(nx,j)
1490
          f1(1,j)=f1(nx,j)
1490
          f1(nx+1,j)=f1(2,j)
1491
          f1(nx+1,j)=f1(2,j)
1491
        enddo
1492
        enddo
1492
      else
1493
      else
1493
c       set boundary-fluxes to zero
1494
c       set boundary-fluxes to zero
1494
        do j=1,ny
1495
        do j=1,ny
1495
          f1(1,j)=0.
1496
          f1(1,j)=0.
1496
          f1(nx+1,j)=0.
1497
          f1(nx+1,j)=0.
1497
        enddo
1498
        enddo
1498
      endif
1499
      endif
1499
 
1500
 
1500
c     compute fluxes in y-direction
1501
c     compute fluxes in y-direction
1501
      if (misdat.eq.0.) then
1502
      if (misdat.eq.0.) then
1502
        do j=2,ny
1503
        do j=2,ny
1503
        do i=1,nx
1504
        do i=1,nx
1504
          f2(i,j)=a(i,j-1)-a(i,j)
1505
          f2(i,j)=a(i,j-1)-a(i,j)
1505
        enddo
1506
        enddo
1506
        enddo
1507
        enddo
1507
      else
1508
      else
1508
        do j=2,ny
1509
        do j=2,ny
1509
        do i=1,nx
1510
        do i=1,nx
1510
          if ((a(i,j).eq.misdat).or.(a(i,j-1).eq.misdat)) then
1511
          if ((a(i,j).eq.misdat).or.(a(i,j-1).eq.misdat)) then
1511
            f2(i,j)=0.
1512
            f2(i,j)=0.
1512
          else
1513
          else
1513
            f2(i,j)=a(i,j-1)-a(i,j)
1514
            f2(i,j)=a(i,j-1)-a(i,j)
1514
          endif
1515
          endif
1515
        enddo
1516
        enddo
1516
        enddo
1517
        enddo
1517
      endif
1518
      endif
1518
c     set boundary-fluxes to zero
1519
c     set boundary-fluxes to zero
1519
      do i=1,nx
1520
      do i=1,nx
1520
        f2(i,1)=0.
1521
        f2(i,1)=0.
1521
        f2(i,ny+1)=0.
1522
        f2(i,ny+1)=0.
1522
      enddo
1523
      enddo
1523
      if (ipery.eq.1) then
1524
      if (ipery.eq.1) then
1524
c       do periodic boundaries in the x-direction
1525
c       do periodic boundaries in the x-direction
1525
        do i=1,nx
1526
        do i=1,nx
1526
          f2(i,1)=f2(i,ny)
1527
          f2(i,1)=f2(i,ny)
1527
          f2(i,ny+1)=f2(i,2)
1528
          f2(i,ny+1)=f2(i,2)
1528
        enddo
1529
        enddo
1529
      endif
1530
      endif
1530
      if (iperx.eq.1) then
1531
      if (iperx.eq.1) then
1531
        if (ispol.eq.1) then
1532
        if (ispol.eq.1) then
1532
c         do south-pole
1533
c         do south-pole
1533
          is=(nx-1)/2
1534
          is=(nx-1)/2
1534
          do i=1,nx
1535
          do i=1,nx
1535
            f2(i,1)=-f2(mod(i-1+is,nx)+1,2)
1536
            f2(i,1)=-f2(mod(i-1+is,nx)+1,2)
1536
          enddo
1537
          enddo
1537
        endif
1538
        endif
1538
        if (inpol.eq.1) then
1539
        if (inpol.eq.1) then
1539
c         do north-pole
1540
c         do north-pole
1540
          is=(nx-1)/2
1541
          is=(nx-1)/2
1541
          do i=1,nx
1542
          do i=1,nx
1542
            f2(i,ny+1)=-f2(mod(i-1+is,nx)+1,ny)
1543
            f2(i,ny+1)=-f2(mod(i-1+is,nx)+1,ny)
1543
          enddo
1544
          enddo
1544
        endif
1545
        endif
1545
      endif
1546
      endif
1546
 
1547
 
1547
c     compute flux-convergence -> filter
1548
c     compute flux-convergence -> filter
1548
      if (misdat.eq.0.) then
1549
      if (misdat.eq.0.) then
1549
        do j=1,ny
1550
        do j=1,ny
1550
        do i=1,nx
1551
        do i=1,nx
1551
            af(i,j)=a(i,j)+fh*(f1(i,j)-f1(i+1,j)+f2(i,j)-f2(i,j+1))
1552
            af(i,j)=a(i,j)+fh*(f1(i,j)-f1(i+1,j)+f2(i,j)-f2(i,j+1))
1552
        enddo
1553
        enddo
1553
        enddo
1554
        enddo
1554
      else
1555
      else
1555
        do j=1,ny
1556
        do j=1,ny
1556
        do i=1,nx
1557
        do i=1,nx
1557
          if (a(i,j).eq.misdat) then
1558
          if (a(i,j).eq.misdat) then
1558
            af(i,j)=misdat
1559
            af(i,j)=misdat
1559
          else
1560
          else
1560
            af(i,j)=a(i,j)+fh*(f1(i,j)-f1(i+1,j)+f2(i,j)-f2(i,j+1))
1561
            af(i,j)=a(i,j)+fh*(f1(i,j)-f1(i+1,j)+f2(i,j)-f2(i,j+1))
1561
          endif
1562
          endif
1562
        enddo
1563
        enddo
1563
        enddo
1564
        enddo
1564
      endif
1565
      endif
1565
      end
1566
      end
1566
 
1567
 
1567
 
1568
 
1568
 
1569
 
1569
 
1570
 
1570
 
1571
 
1571
 
1572
 
1572
 
1573
 
1573
 
1574
 
1574
 
1575
 
1575
 
1576
 
1576
 
1577
 
1577
 
1578
 
1578
 
1579
 
1579
 
1580
 
1580
 
1581
 
1581
 
1582
 
1582
 
1583
 
1583
 
1584
 
1584
 
1585
 
1585
 
1586
 
1586
 
1587
 
1587
 
1588
 
1588
 
1589
 
1589
 
1590
 
1590
 
1591
 
1591
 
1592