Subversion Repositories lagranto.wrf

Rev

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

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