Subversion Repositories lagranto.ecmwf

Rev

Rev 29 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 29 Rev 39
1
      PROGRAM density
1
      PROGRAM density
2
 
2
 
3
      use netcdf
3
      use netcdf
4
 
4
 
5
      implicit none
5
      implicit none
6
 
6
 
7
c     ---------------------------------------------------------------------
7
c     ---------------------------------------------------------------------
8
c     Declaration of variables
8
c     Declaration of variables
9
c     ---------------------------------------------------------------------
9
c     ---------------------------------------------------------------------
10
      
10
      
11
c     Parameter and working arrays
11
c     Parameter and working arrays
12
      real                                    radius
12
      real                                    radius
13
      character*80                            runit
13
      character*80                            runit
14
      integer                                 nx,ny
14
      integer                                 nx,ny
15
      integer                                 nlonlat
15
      integer                                 nlonlat
16
      real                                    dlonlat
16
      real                                    dlonlat
17
      real                                    xmin,ymin,dx,dy
17
      real                                    xmin,ymin,dx,dy
18
      real                                    clon,clat
18
      real                                    clon,clat
19
      integer                                 ntime,nfield,ntra
19
      integer                                 ntime,nfield,ntra
20
      character*80                            inpfile
20
      character*80                            inpfile
21
      character*80                            outfile
21
      character*80                            outfile
22
      character*80                            mode
22
      character*80                            mode
23
      real                                    param
23
      real                                    param
24
      integer                                 opts,npts
24
      integer                                 opts,npts
25
      integer                                 step
25
      integer                                 step
26
      character*80                            gridtype
26
      character*80                            gridtype
27
      character*80                            field
27
      character*80                            field
28
      integer                                 crefile,crevar
28
      integer                                 crefile,crevar
29
      real,allocatable,    dimension (:,:) :: cnt,res,fld,area
29
      real,allocatable,    dimension (:,:) :: cnt,res,fld,area
30
      real,allocatable,    dimension (:)   :: traj
30
      real,allocatable,    dimension (:)   :: traj
31
      real,allocatable,    dimension (:)   :: olon,olat,otim,ofld
31
      real,allocatable,    dimension (:)   :: olon,olat,otim,ofld
32
      real,allocatable,    dimension (:)   :: nlon,nlat,ntim,nfld
32
      real,allocatable,    dimension (:)   :: nlon,nlat,ntim,nfld
33
 
33
 
34
c     Output format
34
c     Output format
35
      character*80                            outformat
35
      character*80                            outformat
36
 
36
 
37
c     Physical and mathematical constants
37
c     Physical and mathematical constants
38
      real                                    pi180
38
      real                                    pi180
39
      parameter                               (pi180=3.14159/180.)
39
      parameter                               (pi180=3.14159/180.)
40
      real                                    deltay
40
      real                                    deltay
41
      parameter                               (deltay=111.)
41
      parameter                               (deltay=111.)
42
      real                                    eps
42
      real                                    eps
43
      parameter                               (eps=0.001)
43
      parameter                               (eps=0.001)
44
 
44
 
45
c     Input trajectories (see iotra.f)
45
c     Input trajectories (see iotra.f)
46
      integer                                 inpmode
46
      integer                                 inpmode
47
      real,allocatable, dimension (:,:,:) ::  trainp     
47
      real,allocatable, dimension (:,:,:) ::  trainp     
48
      integer                                 reftime(6)      
48
      integer                                 reftime(6)      
49
      character*80                            varsinp(100)   
49
      character*80                            varsinp(100)   
50
      integer,allocatable, dimension (:) ::   sel_flag
50
      integer,allocatable, dimension (:) ::   sel_flag
51
      character*80                            sel_file
51
      character*80                            sel_file
52
      character*80                            sel_format
52
      character*80                            sel_format
53
 
53
 
54
c     Auxiliary variables
54
c     Auxiliary variables
55
      character*80                            cdfname,varname
55
      character*80                            cdfname,varname
56
      integer                                 i,j,k
56
      integer                                 i,j,k
57
      integer                                 stat
57
      integer                                 stat
58
      integer,allocatable, dimension (:,:) :: connect0
58
      integer,allocatable, dimension (:,:) :: connect0
59
      integer                                 connectval0
59
      integer                                 connectval0
60
      integer,allocatable, dimension (:,:) :: connect1
60
      integer,allocatable, dimension (:,:) :: connect1
61
      integer                                 connectval1
61
      integer                                 connectval1
62
      integer,allocatable, dimension (:,:) :: connect2
62
      integer,allocatable, dimension (:,:) :: connect2
63
      integer                                 connectval2
63
      integer                                 connectval2
64
      real                                    slat
64
      real                                    slat
65
      integer                                 ipre
65
      integer                                 ipre
66
      real                                    addvalue
66
      real                                    addvalue
67
      real                                    xmax,ymax
67
      real                                    xmax,ymax
68
      real ,allocatable, dimension (:)  ::    odist,ndist
68
      real ,allocatable, dimension (:)  ::    odist,ndist
69
      real                                    dt
69
      real                                    dt
70
      integer                                 fid
70
      integer                                 fid
71
      integer                                 dynamic_grid
71
      integer                                 dynamic_grid
72
      real                                    ycen,xcen
72
      real                                    ycen,xcen
73
      integer                                 indx,indy
73
      integer                                 indx,indy
74
      character*80                            unit
74
      character*80                            unit
75
      real                                    pollon,pollat
75
      real                                    pollon,pollat
76
      real                                    rlon0,rlat0,rlon,rlat
76
      real                                    rlon0,rlat0,rlon,rlat
77
      real                                    lon,lat
77
      real                                    lon,lat
78
      real                                    crot
78
      real                                    crot
79
      integer                                 count
79
      integer                                 count
80
      character*80                            longname, varunit
80
      character*80                            longname, varunit
81
      real                                    time
81
      real                                    time
82
      integer                                 ind
82
      integer                                 ind
83
      integer                                 ifield
83
      integer                                 ifield
84
      real                                    hhmm,frac
84
      real                                    hhmm,frac
85
      integer                                 ierr,ncID
85
      integer                                 ierr,ncID
86
 
86
 
87
c     External functions
87
c     External functions
88
      real         lmstolm,lmtolms
88
      real         lmstolm,lmtolms
89
      real         phstoph,phtophs
89
      real         phstoph,phtophs
90
      external     lmstolm,lmtolms,phstoph,phtophs
90
      external     lmstolm,lmtolms,phstoph,phtophs
91
      
91
      
92
      real         sdis
92
      real         sdis
93
      external     sdis
93
      external     sdis
94
 
94
 
95
c     ---------------------------------------------------------------------
95
c     ---------------------------------------------------------------------
96
c     Preparations
96
c     Preparations
97
c     ---------------------------------------------------------------------
97
c     ---------------------------------------------------------------------
98
 
98
 
99
c     Write start message
99
c     Write start message
100
      print*,'========================================================='
100
      print*,'========================================================='
101
      print*,'              *** START OF PROGRAM DENSITY ***'
101
      print*,'              *** START OF PROGRAM DENSITY ***'
102
      print*
102
      print*
103
 
103
 
104
c     Read input parameters
104
c     Read input parameters
105
      open(10,file='density.param')
105
      open(10,file='density.param')
106
       read(10,*) inpfile
106
       read(10,*) inpfile
107
       read(10,*) outfile
107
       read(10,*) outfile
108
       read(10,*) field
108
       read(10,*) field
109
       read(10,*) ntime,nfield,ntra
109
       read(10,*) ntime,nfield,ntra
110
       read(10,*) gridtype
110
       read(10,*) gridtype
111
       if ( gridtype.eq.'latlon' ) then 
111
       if ( gridtype.eq.'latlon' ) then 
112
          read(10,*) nx,ny,xmin,ymin,dx,dy
112
          read(10,*) nx,ny,xmin,ymin,dx,dy
113
       elseif ( gridtype.eq.'rotated') then
113
       elseif ( gridtype.eq.'rotated') then
114
          read(10,*) clon,clat,nlonlat,dlonlat
114
          read(10,*) clon,clat,nlonlat,dlonlat
115
       else
115
       else
116
          print*,' ERROR: unsupported grid type ',trim(gridtype)
116
          print*,' ERROR: unsupported grid type ',trim(gridtype)
117
          stop
117
          stop
118
       endif
118
       endif
119
       read(10,*) radius,runit
119
       read(10,*) radius,runit
120
       read(10,*) mode
120
       read(10,*) mode
121
       read(10,*) param
121
       read(10,*) param
122
       read(10,*) step
122
       read(10,*) step
123
       read(10,*) sel_file
123
       read(10,*) sel_file
124
       read(10,*) sel_format
124
       read(10,*) sel_format
125
       read(10,*) crefile
125
       read(10,*) crefile
126
       read(10,*) crevar
126
       read(10,*) crevar
127
      close(10)
127
      close(10)
128
 
128
 
129
c     Get the grid parameters if <crefile=0>
129
c     Get the grid parameters if <crefile=0>
130
      if ( crefile.eq.0 ) then
130
      if ( crefile.eq.0 ) then
131
 
131
 
132
           ierr = nf90_open  (trim(outfile), NF90_NOWRITE  , ncID)
132
           ierr = nf90_open  (trim(outfile), NF90_NOWRITE  , ncID)
133
 
133
 
134
           ierr = nf90_get_att(ncID, NF90_GLOBAL, 'grid'   ,gridtype ) 
134
           ierr = nf90_get_att(ncID, NF90_GLOBAL, 'grid'   ,gridtype )
-
 
135
           if ( gridtype.eq.'rotated' ) then
135
           ierr = nf90_get_att(ncID, NF90_GLOBAL, 'clon'   ,clon     )
136
             ierr = nf90_get_att(ncID, NF90_GLOBAL, 'clon'   ,clon     )
136
           ierr = nf90_get_att(ncID, NF90_GLOBAL, 'clat'   ,clat     )
137
             ierr = nf90_get_att(ncID, NF90_GLOBAL, 'clat'   ,clat     )
137
           ierr = nf90_get_att(ncID, NF90_GLOBAL, 'nlonlat',nlonlat  )
138
             ierr = nf90_get_att(ncID, NF90_GLOBAL, 'nlonlat',nlonlat  )
138
           ierr = nf90_get_att(ncID, NF90_GLOBAL, 'dlonlat',dlonlat  )
139
             ierr = nf90_get_att(ncID, NF90_GLOBAL, 'dlonlat',dlonlat  )
-
 
140
           endif
139
           ierr = nf90_get_att(ncID, NF90_GLOBAL, 'nx'     ,nx       )
141
           ierr = nf90_get_att(ncID, NF90_GLOBAL, 'nx'     ,nx       )
140
           ierr = nf90_get_att(ncID, NF90_GLOBAL, 'ny'     ,ny       )
142
           ierr = nf90_get_att(ncID, NF90_GLOBAL, 'ny'     ,ny       )
141
           ierr = nf90_get_att(ncID, NF90_GLOBAL, 'dx'     ,dx       )
143
           ierr = nf90_get_att(ncID, NF90_GLOBAL, 'dx'     ,dx       )
142
           ierr = nf90_get_att(ncID, NF90_GLOBAL, 'dy'     ,dy       )
144
           ierr = nf90_get_att(ncID, NF90_GLOBAL, 'dy'     ,dy       )
143
           ierr = nf90_get_att(ncID, NF90_GLOBAL, 'xmin'   ,xmin     )
145
           ierr = nf90_get_att(ncID, NF90_GLOBAL, 'xmin'   ,xmin     )
144
           ierr = nf90_get_att(ncID, NF90_GLOBAL, 'ymin'   ,ymin     )
146
           ierr = nf90_get_att(ncID, NF90_GLOBAL, 'ymin'   ,ymin     )
145
 
147
 
146
           ierr = nf90_close(ncID)
148
           ierr = nf90_close(ncID)
147
 
149
 
148
           print*,'**** GRID PARAMETERS IMPORTED ',
150
           print*,'**** GRID PARAMETERS IMPORTED ',
149
     >            'FROM NETCDF FILE!!!! ****'
151
     >            'FROM NETCDF FILE!!!! ****'
150
           print*
152
           print*
151
           
153
           
152
      endif
154
      endif
153
 
155
 
154
c     Check for consistency
156
c     Check for consistency
155
      if ( (step.ne.0).and.(mode.ne.'keep') ) then
157
      if ( (step.ne.0).and.(mode.ne.'keep') ) then
156
         print*," ERROR: interpolation is only possible for all",
158
         print*," ERROR: interpolation is only possible for all",
157
     >                   ' time steps... Stop'
159
     >                   ' time steps... Stop'
158
         stop
160
         stop
159
      endif
161
      endif
160
 
162
 
161
c     Set the number of times (just code aesthetics)
163
c     Set the number of times (just code aesthetics)
162
      opts=ntime
164
      opts=ntime
163
 
165
 
164
c     Set grid parameters for rotated grid
166
c     Set grid parameters for rotated grid
165
      if ( gridtype.eq.'rotated' ) then
167
      if ( gridtype.eq.'rotated' ) then
166
         nx   = nlonlat
168
         nx   = nlonlat
167
         ny   = nlonlat
169
         ny   = nlonlat
168
         dx   = dlonlat
170
         dx   = dlonlat
169
         dy   = dlonlat
171
         dy   = dlonlat
170
         xmin = - real(nlonlat-1)/2. * dx
172
         xmin = - real(nlonlat-1)/2. * dx
171
         xmax = + real(nlonlat-1)/2. * dx
173
         xmax = + real(nlonlat-1)/2. * dx
172
         ymin = - real(nlonlat-1)/2. * dy
174
         ymin = - real(nlonlat-1)/2. * dy
173
         ymax = + real(nlonlat-1)/2. * dy
175
         ymax = + real(nlonlat-1)/2. * dy
174
      endif
176
      endif
175
      
177
      
176
c     Set the flag for dynamic grid adjustment
178
c     Set the flag for dynamic grid adjustment
177
      if ( (nx.eq.0).or.(ny.eq.0) ) then
179
      if ( (nx.eq.0).or.(ny.eq.0) ) then
178
         dynamic_grid = 1
180
         dynamic_grid = 1
179
      else
181
      else
180
         dynamic_grid = 0
182
         dynamic_grid = 0
181
      endif
183
      endif
182
 
184
 
183
c     Print status information
185
c     Print status information
184
      print*,'---- INPUT PARAMETERS -----------------------------------'
186
      print*,'---- INPUT PARAMETERS -----------------------------------'
185
      print* 
187
      print* 
186
      print*,'Input                : ',trim(inpfile)
188
      print*,'Input                : ',trim(inpfile)
187
      print*,'Output               : ',trim(outfile)
189
      print*,'Output               : ',trim(outfile)
188
      print*,'Field                : ',trim(field)
190
      print*,'Field                : ',trim(field)
189
      print*,'Trajectory           : ',ntime,nfield,ntra
191
      print*,'Trajectory           : ',ntime,nfield,ntra
190
      print*,'Grid type            : ',trim(gridtype)
192
      print*,'Grid type            : ',trim(gridtype)
191
      if ( dynamic_grid.eq.1 ) then
193
      if ( dynamic_grid.eq.1 ) then
192
         print*,'Grid                 : dynamic (see below)'
194
         print*,'Grid                 : dynamic (see below)'
193
      elseif ( gridtype.eq.'latlon' ) then
195
      elseif ( gridtype.eq.'latlon' ) then
194
         print*,'Grid   nlon,nlat     : ',nx,ny
196
         print*,'Grid   nlon,nlat     : ',nx,ny
195
         print*,'       lonmin,latmin : ',xmin,ymin
197
         print*,'       lonmin,latmin : ',xmin,ymin
196
         print*,'       dlon,dlat     : ',dx,dy
198
         print*,'       dlon,dlat     : ',dx,dy
197
      elseif ( gridtype.eq.'rotated' ) then
199
      elseif ( gridtype.eq.'rotated' ) then
198
         print*,'Grid   clon,clat     : ',clon,clat
200
         print*,'Grid   clon,clat     : ',clon,clat
199
         print*,'       nlonlat       : ',nlonlat
201
         print*,'       nlonlat       : ',nlonlat
200
         print*,'       dlonlat       : ',dlonlat
202
         print*,'       dlonlat       : ',dlonlat
201
      endif
203
      endif
202
      print*,'Filter radius        : ',radius,' ',trim(runit)
204
      print*,'Filter radius        : ',radius,' ',trim(runit)
203
      print*,'Mode                 : ',trim(mode)
205
      print*,'Mode                 : ',trim(mode)
204
      if ( ( mode.eq.'time'  ).or.
206
      if ( ( mode.eq.'time'  ).or.
205
     >     ( mode.eq.'space' ).or.
207
     >     ( mode.eq.'space' ).or.
206
     >     (mode.eq.'grid' ) ) 
208
     >     (mode.eq.'grid' ) ) 
207
     >then
209
     >then
208
         print*,'Parameter            : ',param
210
         print*,'Parameter            : ',param
209
      endif
211
      endif
210
      if ( step.eq.0 ) then
212
      if ( step.eq.0 ) then
211
         print*,'Time step            : all'
213
         print*,'Time step            : all'
212
      elseif (step.gt.0) then
214
      elseif (step.gt.0) then
213
         print*,'Time step            : ',step
215
         print*,'Time step            : ',step
214
      endif
216
      endif
215
      print*,'Selection file       : ',trim(sel_file)
217
      print*,'Selection file       : ',trim(sel_file)
216
      print*,'Selection format     : ',trim(sel_file)
218
      print*,'Selection format     : ',trim(sel_file)
217
      print*,'Flag <crefile>       : ',crefile
219
      print*,'Flag <crefile>       : ',crefile
218
      print*,'Flag <crevar>        : ',crevar
220
      print*,'Flag <crevar>        : ',crevar
219
 
221
 
220
c     Check whether mode is valid
222
c     Check whether mode is valid
221
      if ((mode.ne.'keep'  ).and.
223
      if ((mode.ne.'keep'  ).and.
222
     >    (mode.ne.'time'  ).and.
224
     >    (mode.ne.'time'  ).and.
223
     >    (mode.ne.'space' ).and.
225
     >    (mode.ne.'space' ).and.
224
     >    (mode.ne.'grid'  ))  
226
     >    (mode.ne.'grid'  ))  
225
     >then
227
     >then
226
         print*,' ERROR: Invalid mode ',trim(mode)
228
         print*,' ERROR: Invalid mode ',trim(mode)
227
         stop
229
         stop
228
      endif
230
      endif
229
 
231
 
230
c     Allocate memory for old and new (reparameterised) trajectory
232
c     Allocate memory for old and new (reparameterised) trajectory
231
      allocate(olon(ntime),stat=stat)
233
      allocate(olon(ntime),stat=stat)
232
      if (stat.ne.0) print*,'*** error allocating array olon ***'
234
      if (stat.ne.0) print*,'*** error allocating array olon ***'
233
      allocate(olat(ntime),stat=stat)
235
      allocate(olat(ntime),stat=stat)
234
      if (stat.ne.0) print*,'*** error allocating array olat ***'
236
      if (stat.ne.0) print*,'*** error allocating array olat ***'
235
      allocate(otim(ntime),stat=stat)
237
      allocate(otim(ntime),stat=stat)
236
      if (stat.ne.0) print*,'*** error allocating array otim ***'
238
      if (stat.ne.0) print*,'*** error allocating array otim ***'
237
      allocate(nlon(1000*ntime),stat=stat)
239
      allocate(nlon(1000*ntime),stat=stat)
238
      if (stat.ne.0) print*,'*** error allocating array nlon ***'
240
      if (stat.ne.0) print*,'*** error allocating array nlon ***'
239
      allocate(nlat(1000*ntime),stat=stat)
241
      allocate(nlat(1000*ntime),stat=stat)
240
      if (stat.ne.0) print*,'*** error allocating array nlat ***'
242
      if (stat.ne.0) print*,'*** error allocating array nlat ***'
241
      allocate(ntim(1000*ntime),stat=stat)
243
      allocate(ntim(1000*ntime),stat=stat)
242
      if (stat.ne.0) print*,'*** error allocating array ntim ***'
244
      if (stat.ne.0) print*,'*** error allocating array ntim ***'
243
      allocate(odist(ntime),stat=stat)
245
      allocate(odist(ntime),stat=stat)
244
      if (stat.ne.0) print*,'*** error allocating array odist ***'
246
      if (stat.ne.0) print*,'*** error allocating array odist ***'
245
      allocate(ndist(1000*ntime),stat=stat)
247
      allocate(ndist(1000*ntime),stat=stat)
246
      if (stat.ne.0) print*,'*** error allocating array ndist ***'
248
      if (stat.ne.0) print*,'*** error allocating array ndist ***'
247
      allocate(ofld(ntime),stat=stat)
249
      allocate(ofld(ntime),stat=stat)
248
      if (stat.ne.0) print*,'*** error allocating array ofld ***'
250
      if (stat.ne.0) print*,'*** error allocating array ofld ***'
249
      allocate(nfld(1000*ntime),stat=stat)
251
      allocate(nfld(1000*ntime),stat=stat)
250
      if (stat.ne.0) print*,'*** error allocating array nfld ***'
252
      if (stat.ne.0) print*,'*** error allocating array nfld ***'
251
 
253
 
252
c     Allocate memory for complete trajectory set
254
c     Allocate memory for complete trajectory set
253
      allocate(trainp(ntra,ntime,nfield),stat=stat)
255
      allocate(trainp(ntra,ntime,nfield),stat=stat)
254
      if (stat.ne.0) print*,'*** error allocating array trainp ***'
256
      if (stat.ne.0) print*,'*** error allocating array trainp ***'
255
      allocate(sel_flag(ntra),stat=stat)
257
      allocate(sel_flag(ntra),stat=stat)
256
      if (stat.ne.0) print*,'*** error allocating array sel_flag ***'
258
      if (stat.ne.0) print*,'*** error allocating array sel_flag ***'
257
 
259
 
258
c     Allocate memory for auxiliary fields
260
c     Allocate memory for auxiliary fields
259
      allocate(traj(nfield),stat=stat)
261
      allocate(traj(nfield),stat=stat)
260
      if (stat.ne.0) print*,'*** error allocating array traj ***'
262
      if (stat.ne.0) print*,'*** error allocating array traj ***'
261
 
263
 
262
c     Set the format of the input file
264
c     Set the format of the input file
263
      call mode_tra(inpmode,inpfile)
265
      call mode_tra(inpmode,inpfile)
264
      if (inpmode.eq.-1) inpmode=1
266
      if (inpmode.eq.-1) inpmode=1
265
 
267
 
266
c     Read the input trajectory file
268
c     Read the input trajectory file
267
      call ropen_tra(fid,inpfile,ntra,ntime,nfield,
269
      call ropen_tra(fid,inpfile,ntra,ntime,nfield,
268
     >                   reftime,varsinp,inpmode)
270
     >                   reftime,varsinp,inpmode)
269
      call read_tra (fid,trainp,ntra,ntime,nfield,inpmode)
271
      call read_tra (fid,trainp,ntra,ntime,nfield,inpmode)
270
      call close_tra(fid,inpmode)
272
      call close_tra(fid,inpmode)
271
 
273
 
272
c     Bring trajectories into grid interval
274
c     Bring trajectories into grid interval
273
      print*,xmin,ymin,dx,dy,nx,ny
275
      print*,xmin,ymin,dx,dy,nx,ny
274
      if ( ( abs(xmin+180.).lt.eps).and.
276
      if ( ( abs(xmin+180.).lt.eps).and.
275
     >     ( abs(ymin+90. ).lt.eps).and.
277
     >     ( abs(ymin+90. ).lt.eps).and.
276
     >     ( abs(dx-1.    ).lt.eps).and.
278
     >     ( abs(dx-1.    ).lt.eps).and.
277
     >     ( abs(dy-1.    ).lt.eps).and.
279
     >     ( abs(dy-1.    ).lt.eps).and.
278
     >     ( nx.eq.360    ).and.
280
     >     ( nx.eq.360    ).and.
279
     >     ( ny.eq.180    ) )
281
     >     ( ny.eq.180    ) )
280
     >then
282
     >then
281
        print*,'HALLO'
283
        print*,'HALLO'
282
        do i=1,ntra
284
        do i=1,ntra
283
          do j=1,ntime
285
          do j=1,ntime
284
            if ( trainp(i,j,2).lt.-180. ) then
286
            if ( trainp(i,j,2).lt.-180. ) then
285
                trainp(i,j,2) = trainp(i,j,2) + 360.
287
                trainp(i,j,2) = trainp(i,j,2) + 360.
286
            endif
288
            endif
287
            if ( trainp(i,j,2).gt.180. ) then
289
            if ( trainp(i,j,2).gt.180. ) then
288
                trainp(i,j,2) = trainp(i,j,2) - 360.
290
                trainp(i,j,2) = trainp(i,j,2) - 360.
289
            endif
291
            endif
290
         enddo
292
         enddo
291
        enddo
293
        enddo
292
      endif
294
      endif
293
 
295
 
294
c     Check that first four columns correspond to time,lon,lat,p
296
c     Check that first four columns correspond to time,lon,lat,p
295
      if ( (varsinp(1).ne.'time' ).or.
297
      if ( (varsinp(1).ne.'time' ).or.
296
     >     (varsinp(2).ne.'xpos' ).and.(varsinp(2).ne.'lon' ).or.
298
     >     (varsinp(2).ne.'xpos' ).and.(varsinp(2).ne.'lon' ).or.
297
     >     (varsinp(3).ne.'ypos' ).and.(varsinp(3).ne.'lat' ).or.
299
     >     (varsinp(3).ne.'ypos' ).and.(varsinp(3).ne.'lat' ).or.
298
     >     (varsinp(4).ne.'ppos' ).and.(varsinp(4).ne.'p'   ) )
300
     >     (varsinp(4).ne.'ppos' ).and.(varsinp(4).ne.'p'   ) )
299
     >then
301
     >then
300
         print*,' ERROR: problem with input trajectories ...'
302
         print*,' ERROR: problem with input trajectories ...'
301
         stop
303
         stop
302
      endif
304
      endif
303
      varsinp(1) = 'TIME'
305
      varsinp(1) = 'TIME'
304
      varsinp(2) = 'lon'
306
      varsinp(2) = 'lon'
305
      varsinp(3) = 'lat'
307
      varsinp(3) = 'lat'
306
      varsinp(4) = 'p'
308
      varsinp(4) = 'p'
307
 
309
 
308
c     Get the index of the field (if needed)
310
c     Get the index of the field (if needed)
309
      if ( field.ne.'nil' ) then
311
      if ( field.ne.'nil' ) then
310
         ifield = 0
312
         ifield = 0
311
         do i=1,nfield
313
         do i=1,nfield
312
            if ( varsinp(i).eq.field ) ifield = i
314
            if ( varsinp(i).eq.field ) ifield = i
313
         enddo
315
         enddo
314
         if ( ifield.eq.0 ) then
316
         if ( ifield.eq.0 ) then
315
            print*,' ERROR: field ',trim(field),' not found... Stop'
317
            print*,' ERROR: field ',trim(field),' not found... Stop'
316
            stop
318
            stop
317
         endif
319
         endif
318
      endif
320
      endif
319
 
321
 
320
c     Write some status information of the input trajectories
322
c     Write some status information of the input trajectories
321
      print*
323
      print*
322
      print*,'---- INPUT TRAJECTORIES ---------------------------------'
324
      print*,'---- INPUT TRAJECTORIES ---------------------------------'
323
      print*
325
      print*
324
      print*,' Reference time (year)  : ',reftime(1)
326
      print*,' Reference time (year)  : ',reftime(1)
325
      print*,'                (month) : ',reftime(2)
327
      print*,'                (month) : ',reftime(2)
326
      print*,'                (day)   : ',reftime(3)
328
      print*,'                (day)   : ',reftime(3)
327
      print*,'                (hour)  : ',reftime(4)
329
      print*,'                (hour)  : ',reftime(4)
328
      print*,'                (min)   : ',reftime(5)
330
      print*,'                (min)   : ',reftime(5)
329
      print*,' Time range (min)       : ',reftime(6)
331
      print*,' Time range (min)       : ',reftime(6)
330
      do i=1,nfield
332
      do i=1,nfield
331
         if ( i.ne.ifield ) then
333
         if ( i.ne.ifield ) then
332
            print*,' Var                    :',i,trim(varsinp(i))
334
            print*,' Var                    :',i,trim(varsinp(i))
333
         else
335
         else
334
            print*,' Var                    :',i,trim(varsinp(i)),
336
            print*,' Var                    :',i,trim(varsinp(i)),
335
     >                                        '       [ gridding ]'
337
     >                                        '       [ gridding ]'
336
         endif
338
         endif
337
      enddo
339
      enddo
338
      print*,' List of selected times'
340
      print*,' List of selected times'
339
      do i=1,ntime
341
      do i=1,ntime
340
         if ( (step.eq.0).or.(step.eq.i) ) then
342
         if ( (step.eq.0).or.(step.eq.i) ) then
341
            print*,'     ',i,'  -> ',trainp(1,i,1)
343
            print*,'     ',i,'  -> ',trainp(1,i,1)
342
         endif
344
         endif
343
      enddo
345
      enddo
344
      print*
346
      print*
345
 
347
 
346
c     Select flag: all trajectories are selected
348
c     Select flag: all trajectories are selected
347
      if ( sel_file.eq.'nil' ) then
349
      if ( sel_file.eq.'nil' ) then
348
 
350
 
349
         do i=1,ntra
351
         do i=1,ntra
350
            sel_flag(i) = 1
352
            sel_flag(i) = 1
351
         enddo
353
         enddo
352
 
354
 
353
c     Select flag: index file
355
c     Select flag: index file
354
      elseif ( sel_format.eq.'index' ) then
356
      elseif ( sel_format.eq.'index' ) then
355
 
357
 
356
         do i=1,ntra
358
         do i=1,ntra
357
            sel_flag(i) = 0
359
            sel_flag(i) = 0
358
         enddo
360
         enddo
359
         
361
         
360
         open(10,file=sel_file)
362
         open(10,file=sel_file)
361
 142      read(10,*,end=141) ind
363
 142      read(10,*,end=141) ind
362
          sel_flag(ind) = 1
364
          sel_flag(ind) = 1
363
          goto 142 
365
          goto 142 
364
 141     continue
366
 141     continue
365
         close(10)
367
         close(10)
366
 
368
 
367
c     Select flag: boolean file
369
c     Select flag: boolean file
368
      elseif ( sel_format.eq.'boolean' ) then
370
      elseif ( sel_format.eq.'boolean' ) then
369
       
371
       
370
         open(10,file=sel_file)
372
         open(10,file=sel_file)
371
          do i=1,ntra
373
          do i=1,ntra
372
            read(10,*) ind
374
            read(10,*) ind
373
            if ( ind.eq.1 ) sel_flag(i) = ind
375
            if ( ind.eq.1 ) sel_flag(i) = ind
374
          enddo
376
          enddo
375
         close(10)
377
         close(10)
376
         
378
         
377
      endif
379
      endif
378
 
380
 
379
c     Write status information
381
c     Write status information
380
      if ( sel_file.eq.'nil' ) then
382
      if ( sel_file.eq.'nil' ) then
381
          print*,' Selected trajectories  : all ',ntra          
383
          print*,' Selected trajectories  : all ',ntra          
382
       else
384
       else
383
          count = 0
385
          count = 0
384
          do i=1,ntra
386
          do i=1,ntra
385
             if ( sel_flag(i).eq.1 ) count = count + 1
387
             if ( sel_flag(i).eq.1 ) count = count + 1
386
          enddo
388
          enddo
387
          print*,' #selected trajectories : ',count,
389
          print*,' #selected trajectories : ',count,
388
     >            ' [ ',real(count)/real(ntra) * 100.,' % ] '
390
     >            ' [ ',real(count)/real(ntra) * 100.,' % ] '
389
       endif
391
       endif
390
       print*
392
       print*
391
 
393
 
392
c     ---------------------------------------------------------------------
394
c     ---------------------------------------------------------------------
393
c     Coordinate transformations and grid adjustment
395
c     Coordinate transformations and grid adjustment
394
c     ---------------------------------------------------------------------
396
c     ---------------------------------------------------------------------
395
 
397
 
396
c     Transform from lat/lon to rotated lat/lon, if requested
398
c     Transform from lat/lon to rotated lat/lon, if requested
397
      if ( gridtype.eq.'rotated') then
399
      if ( gridtype.eq.'rotated') then
398
 
400
 
399
         crot = 0.
401
         crot = 0.
400
 
402
 
401
         pollon=clon-180.
403
         pollon=clon-180.
402
         if (pollon.lt.-180.) pollon=pollon+360.
404
         if (pollon.lt.-180.) pollon=pollon+360.
403
         pollat=90.-clat
405
         pollat=90.-clat
404
         do i=1,ntra
406
         do i=1,ntra
405
            do j=1,ntime
407
            do j=1,ntime
406
               
408
               
407
               if ( sel_flag(i).eq.1 ) then
409
               if ( sel_flag(i).eq.1 ) then
408
 
410
 
409
c                Get lat/lon coordinates for trajectory point
411
c                Get lat/lon coordinates for trajectory point
410
                 lon = trainp(i,j,2)
412
                 lon = trainp(i,j,2)
411
                 lat = trainp(i,j,3)
413
                 lat = trainp(i,j,3)
412
 
414
 
413
c                First Rotation
415
c                First Rotation
414
                 pollon=clon-180.
416
                 pollon=clon-180.
415
                 if (pollon.lt.-180.) pollon=pollon+360.
417
                 if (pollon.lt.-180.) pollon=pollon+360.
416
                 pollat=90.-clat
418
                 pollat=90.-clat
417
                 rlon0=lmtolms(lat,lon,pollat,pollon)
419
                 rlon0=lmtolms(lat,lon,pollat,pollon)
418
                 rlat0=phtophs(lat,lon,pollat,pollon)            
420
                 rlat0=phtophs(lat,lon,pollat,pollon)            
419
 
421
 
420
c                Second rotation
422
c                Second rotation
421
                 pollon=-180.
423
                 pollon=-180.
422
                 pollat=90.+crot
424
                 pollat=90.+crot
423
                 rlon=90.+lmtolms(rlat0,rlon0-90.,pollat,pollon)
425
                 rlon=90.+lmtolms(rlat0,rlon0-90.,pollat,pollon)
424
                 rlat=phtophs(rlat0,rlon0-90.,pollat,pollon)   
426
                 rlat=phtophs(rlat0,rlon0-90.,pollat,pollon)   
425
 
427
 
426
c                Get rotated latitude and longitude
428
c                Get rotated latitude and longitude
427
 100             if (rlon.lt.xmin) then
429
 100             if (rlon.lt.xmin) then
428
                  rlon=rlon+360.
430
                  rlon=rlon+360.
429
                  goto 100
431
                  goto 100
430
                 endif
432
                 endif
431
 102             if (rlon.gt.(xmin+real(nx-1)*dx)) then
433
 102             if (rlon.gt.(xmin+real(nx-1)*dx)) then
432
                  rlon=rlon-360.
434
                  rlon=rlon-360.
433
                  goto 102
435
                  goto 102
434
                 endif
436
                 endif
435
 
437
 
436
c                Set the new trajectory coordinates
438
c                Set the new trajectory coordinates
437
                 trainp(i,j,2) = rlon
439
                 trainp(i,j,2) = rlon
438
                 trainp(i,j,3) = rlat
440
                 trainp(i,j,3) = rlat
439
 
441
 
440
              endif
442
              endif
441
 
443
 
442
            enddo
444
            enddo
443
         enddo
445
         enddo
444
            
446
            
445
      endif
447
      endif
446
 
448
 
447
c     Dynamic grid adjustment
449
c     Dynamic grid adjustment
448
      if ( dynamic_grid.eq.1 ) then
450
      if ( dynamic_grid.eq.1 ) then
449
 
451
 
450
c        Get the grid parameters
452
c        Get the grid parameters
451
         xmin =  180.
453
         xmin =  180.
452
         ymin =   90.
454
         ymin =   90.
453
         xmax = -180.
455
         xmax = -180.
454
         ymax =  -90.
456
         ymax =  -90.
455
 
457
 
456
         do i=1,ntra
458
         do i=1,ntra
457
 
459
 
458
            if ( sel_flag(i).eq.1 ) then
460
            if ( sel_flag(i).eq.1 ) then
459
 
461
 
460
              if ( step.eq.0 ) then
462
              if ( step.eq.0 ) then
461
               do j=1,ntime
463
               do j=1,ntime
462
                  if ( trainp(i,j,2).lt.xmin) xmin =  trainp(i,j,2)
464
                  if ( trainp(i,j,2).lt.xmin) xmin =  trainp(i,j,2)
463
                  if ( trainp(i,j,2).gt.xmax) xmax =  trainp(i,j,2)
465
                  if ( trainp(i,j,2).gt.xmax) xmax =  trainp(i,j,2)
464
                  if ( trainp(i,j,3).lt.ymin) ymin =  trainp(i,j,3)
466
                  if ( trainp(i,j,3).lt.ymin) ymin =  trainp(i,j,3)
465
                  if ( trainp(i,j,3).gt.ymax) ymax =  trainp(i,j,3)
467
                  if ( trainp(i,j,3).gt.ymax) ymax =  trainp(i,j,3)
466
               enddo
468
               enddo
467
              else
469
              else
468
                if ( trainp(i,step,2).lt.xmin) xmin =  trainp(i,step,2)
470
                if ( trainp(i,step,2).lt.xmin) xmin =  trainp(i,step,2)
469
                if ( trainp(i,step,2).gt.xmax) xmax =  trainp(i,step,2)
471
                if ( trainp(i,step,2).gt.xmax) xmax =  trainp(i,step,2)
470
                if ( trainp(i,step,3).lt.ymin) ymin =  trainp(i,step,3)
472
                if ( trainp(i,step,3).lt.ymin) ymin =  trainp(i,step,3)
471
                if ( trainp(i,step,3).gt.ymax) ymax =  trainp(i,step,3)
473
                if ( trainp(i,step,3).gt.ymax) ymax =  trainp(i,step,3)
472
              endif
474
              endif
473
            
475
            
474
            endif
476
            endif
475
 
477
 
476
         enddo
478
         enddo
477
 
479
 
478
c        Get first guess for "optimal" grid
480
c        Get first guess for "optimal" grid
479
         nx = 400
481
         nx = 400
480
         ny = 400
482
         ny = 400
481
         dx = (xmax - xmin)/real(nx-1)
483
         dx = (xmax - xmin)/real(nx-1)
482
         dy = (ymax - ymin)/real(ny-1)
484
         dy = (ymax - ymin)/real(ny-1)
483
 
485
 
484
c        Make the grid spacing equal in zonal and meridional direction
486
c        Make the grid spacing equal in zonal and meridional direction
485
         if ( dx.gt.dy ) then
487
         if ( dx.gt.dy ) then
486
            
488
            
487
            dy = dx
489
            dy = dx
488
            ny = (ymax - ymin)/dy + 1
490
            ny = (ymax - ymin)/dy + 1
489
            if (ny.lt.nx/2)              ny = nx / 2
491
            if (ny.lt.nx/2)              ny = nx / 2
490
            if ( real(ny)*dy .ge. 180. ) ny = 180./dy + 1
492
            if ( real(ny)*dy .ge. 180. ) ny = 180./dy + 1
491
            ycen = 0.5* (ymin+ymax)
493
            ycen = 0.5* (ymin+ymax)
492
            ymin = ycen - 0.5 * real(ny/2) * dy
494
            ymin = ycen - 0.5 * real(ny/2) * dy
493
            if (ymin.le.-90.) ymin = -90.
495
            if (ymin.le.-90.) ymin = -90.
494
 
496
 
495
         else
497
         else
496
               
498
               
497
            dx = dy
499
            dx = dy
498
            nx = (xmax - xmin)/dx + 1
500
            nx = (xmax - xmin)/dx + 1
499
            if (nx.lt.ny/2)              nx = ny / 2
501
            if (nx.lt.ny/2)              nx = ny / 2
500
            if ( real(nx)*dx .ge. 360. ) nx = 360./dx + 1
502
            if ( real(nx)*dx .ge. 360. ) nx = 360./dx + 1
501
            xcen = 0.5* (xmin+xmax)
503
            xcen = 0.5* (xmin+xmax)
502
            xmin = xcen - 0.5 * real(nx/2) * dx
504
            xmin = xcen - 0.5 * real(nx/2) * dx
503
            if (xmin.le.-180.) xmin = -180.
505
            if (xmin.le.-180.) xmin = -180.
504
 
506
 
505
         endif
507
         endif
506
            
508
            
507
c        Write information
509
c        Write information
508
         print*
510
         print*
509
         print*,'---- DYNAMIC GRID ADJUSTMENT',
511
         print*,'---- DYNAMIC GRID ADJUSTMENT',
510
     >          ' ----------------------------'  
512
     >          ' ----------------------------'  
511
         print*
513
         print*
512
         print*,'Grid   nlon,nlat     : ',nx,ny
514
         print*,'Grid   nlon,nlat     : ',nx,ny
513
         print*,'       lonmin,latmin : ',xmin,ymin
515
         print*,'       lonmin,latmin : ',xmin,ymin
514
         print*,'       dlon,dlat     : ',dx,dy
516
         print*,'       dlon,dlat     : ',dx,dy
515
         print*
517
         print*
516
 
518
 
517
c     Write grid information for rotated grid (if not already done
519
c     Write grid information for rotated grid (if not already done
518
      elseif ( gridtype.eq.'rotated') then
520
      elseif ( gridtype.eq.'rotated') then
519
         
521
         
520
         print*
522
         print*
521
         print*,'---- GRID PARAMETERS -------',
523
         print*,'---- GRID PARAMETERS -------',
522
     >          ' ----------------------------'  
524
     >          ' ----------------------------'  
523
         print*
525
         print*
524
         print*,'Grid   nlon,nlat     : ',nx,ny
526
         print*,'Grid   nlon,nlat     : ',nx,ny
525
         print*,'       lonmin,latmin : ',xmin,ymin
527
         print*,'       lonmin,latmin : ',xmin,ymin
526
         print*,'       dlon,dlat     : ',dx,dy
528
         print*,'       dlon,dlat     : ',dx,dy
527
         print*
529
         print*
528
       
530
       
529
 
531
 
530
      endif
532
      endif
531
 
533
 
532
c     Set the grid boundaries
534
c     Set the grid boundaries
533
      xmax=xmin+real(nx-1)*dx
535
      xmax=xmin+real(nx-1)*dx
534
      ymax=ymin+real(ny-1)*dy
536
      ymax=ymin+real(ny-1)*dy
535
 
537
 
536
c     Allocate memory for output array and auxiliary gridding array 
538
c     Allocate memory for output array and auxiliary gridding array 
537
      allocate(cnt(nx,ny),stat=stat)
539
      allocate(cnt(nx,ny),stat=stat)
538
      if (stat.ne.0) print*,'*** error allocating array cnt  ***'
540
      if (stat.ne.0) print*,'*** error allocating array cnt  ***'
539
      allocate(res(nx,ny),stat=stat)
541
      allocate(res(nx,ny),stat=stat)
540
      if (stat.ne.0) print*,'*** error allocating array res  ***'
542
      if (stat.ne.0) print*,'*** error allocating array res  ***'
541
      allocate(fld(nx,ny),stat=stat)
543
      allocate(fld(nx,ny),stat=stat)
542
      if (stat.ne.0) print*,'*** error allocating array fld  ***'
544
      if (stat.ne.0) print*,'*** error allocating array fld  ***'
543
      allocate(area(nx,ny),stat=stat)
545
      allocate(area(nx,ny),stat=stat)
544
      if (stat.ne.0) print*,'*** error allocating array area ***'
546
      if (stat.ne.0) print*,'*** error allocating array area ***'
545
 
547
 
546
      allocate(connect0(nx,ny),stat=stat)
548
      allocate(connect0(nx,ny),stat=stat)
547
      if (stat.ne.0) print*,'*** error allocating array connect0 ***'
549
      if (stat.ne.0) print*,'*** error allocating array connect0 ***'
548
      allocate(connect1(nx,ny),stat=stat)
550
      allocate(connect1(nx,ny),stat=stat)
549
      if (stat.ne.0) print*,'*** error allocating array connect1 ***'
551
      if (stat.ne.0) print*,'*** error allocating array connect1 ***'
550
      allocate(connect2(nx,ny),stat=stat)
552
      allocate(connect2(nx,ny),stat=stat)
551
      if (stat.ne.0) print*,'*** error allocating array connect2 ***'
553
      if (stat.ne.0) print*,'*** error allocating array connect2 ***'
552
 
554
 
553
 
555
 
554
c     Init the output array
556
c     Init the output array
555
      do i=1,nx
557
      do i=1,nx
556
         do j=1,ny
558
         do j=1,ny
557
            connect0(i,j) = 0
559
            connect0(i,j) = 0
558
            connect1(i,j) = 0
560
            connect1(i,j) = 0
559
            connect2(i,j) = 0
561
            connect2(i,j) = 0
560
            cnt(i,j)      = 0.
562
            cnt(i,j)      = 0.
561
            res(i,j)      = 0.
563
            res(i,j)      = 0.
562
            fld(i,j)      = 0.
564
            fld(i,j)      = 0.
563
         enddo
565
         enddo
564
      enddo  
566
      enddo  
565
 
567
 
566
c     ---------------------------------------------------------------------
568
c     ---------------------------------------------------------------------
567
c     Gridding
569
c     Gridding
568
c     ---------------------------------------------------------------------
570
c     ---------------------------------------------------------------------
569
 
571
 
570
c     Write some status information 
572
c     Write some status information 
571
      print*,'---- GRIDDING -------------------------------------------'
573
      print*,'---- GRIDDING -------------------------------------------'
572
      print*
574
      print*
573
 
575
 
574
c     Loop over all entries of sampling table
576
c     Loop over all entries of sampling table
575
      connectval0 = 0
577
      connectval0 = 0
576
      connectval1 = 0
578
      connectval1 = 0
577
      connectval2 = 0
579
      connectval2 = 0
578
      count       = 0
580
      count       = 0
579
 
581
 
580
      do i=1,ntra
582
      do i=1,ntra
581
 
583
 
582
         if (mod(i,100).eq.0) print*,i,' of ',ntra
584
         if (mod(i,100).eq.0) print*,i,' of ',ntra
583
 
585
 
584
c        Skip all trajectories which are not selected
586
c        Skip all trajectories which are not selected
585
         if ( sel_flag(i).eq.0 ) goto 300
587
         if ( sel_flag(i).eq.0 ) goto 300
586
 
588
 
587
c        ------- Read a complete trajectory ---------------------------
589
c        ------- Read a complete trajectory ---------------------------
588
         do j=1,ntime
590
         do j=1,ntime
589
            otim(j) = trainp(i,j,1)
591
            otim(j) = trainp(i,j,1)
590
            olon(j) = trainp(i,j,2)
592
            olon(j) = trainp(i,j,2)
591
            olat(j) = trainp(i,j,3)
593
            olat(j) = trainp(i,j,3)
592
            if ( field.ne.'nil' ) then
594
            if ( field.ne.'nil' ) then
593
               ofld(j) =trainp(i,j,ifield)
595
               ofld(j) =trainp(i,j,ifield)
594
            endif
596
            endif
595
         enddo
597
         enddo
596
 
598
 
597
c        -------- Convert hh.m time into fractional time --------------
599
c        -------- Convert hh.m time into fractional time --------------
598
         do j=1,ntime
600
         do j=1,ntime
599
            hhmm    = otim(j)
601
            hhmm    = otim(j)
600
            call hhmm2frac (hhmm,frac)
602
            call hhmm2frac (hhmm,frac)
601
            otim(j) = frac
603
            otim(j) = frac
602
         enddo
604
         enddo
603
 
605
 
604
c        -------- Interpolation ---------------------------------------
606
c        -------- Interpolation ---------------------------------------
605
 
607
 
606
c        Keep the trajectory points as they are
608
c        Keep the trajectory points as they are
607
         if ( ( mode.eq.'keep').and.(step.eq.0) ) then
609
         if ( ( mode.eq.'keep').and.(step.eq.0) ) then
608
            npts=opts
610
            npts=opts
609
            do j=1,opts
611
            do j=1,opts
610
               ntim(j)=otim(j)
612
               ntim(j)=otim(j)
611
               nlon(j)=olon(j)
613
               nlon(j)=olon(j)
612
               nlat(j)=olat(j)
614
               nlat(j)=olat(j)
613
               if ( field.ne.'nil' ) then
615
               if ( field.ne.'nil' ) then
614
                  nfld(j)=ofld(j)
616
                  nfld(j)=ofld(j)
615
               endif
617
               endif
616
            enddo
618
            enddo
617
 
619
 
618
c        Select a single time step
620
c        Select a single time step
619
         elseif ( ( mode.eq.'keep').and.(step.gt.0) ) then
621
         elseif ( ( mode.eq.'keep').and.(step.gt.0) ) then
620
            npts    = 1
622
            npts    = 1
621
            ntim(1) = otim(step)
623
            ntim(1) = otim(step)
622
            nlon(1) = olon(step)
624
            nlon(1) = olon(step)
623
            nlat(1) = olat(step)
625
            nlat(1) = olat(step)
624
            if ( field.ne.'nil' ) then
626
            if ( field.ne.'nil' ) then
625
               nfld(1) = ofld(step)
627
               nfld(1) = ofld(step)
626
            endif
628
            endif
627
 
629
 
628
c        Perform a reparameterisation in time
630
c        Perform a reparameterisation in time
629
         else if ( (mode.eq.'time').and.(step.eq.0) ) then
631
         else if ( (mode.eq.'time').and.(step.eq.0) ) then
630
 
632
 
631
c           Get the new number of trajectory points
633
c           Get the new number of trajectory points
632
            npts=nint(abs(otim(opts)-otim(1))/param)+1
634
            npts=nint(abs(otim(opts)-otim(1))/param)+1
633
 
635
 
634
c           Handle date line problem
636
c           Handle date line problem
635
            do j=2,opts
637
            do j=2,opts
636
               if ( (olon(j-1)-olon(j)).gt.180. ) then
638
               if ( (olon(j-1)-olon(j)).gt.180. ) then
637
                  olon(j) = olon(j) + 360.
639
                  olon(j) = olon(j) + 360.
638
               else if ( (olon(j-1)-olon(j)).lt.-180. ) then
640
               else if ( (olon(j-1)-olon(j)).lt.-180. ) then
639
                  olon(j) = olon(j) - 360.
641
                  olon(j) = olon(j) - 360.
640
               endif
642
               endif
641
            enddo
643
            enddo
642
 
644
 
643
c           Cubic spline fitting
645
c           Cubic spline fitting
644
            call curvefit(otim,olon,opts,ntim,nlon,npts)
646
            call curvefit(otim,olon,opts,ntim,nlon,npts)
645
            call curvefit(otim,olat,opts,ntim,nlat,npts)
647
            call curvefit(otim,olat,opts,ntim,nlat,npts)
646
            if ( field.ne.'nil' ) then
648
            if ( field.ne.'nil' ) then
647
               call curvefit(otim,ofld,opts,ntim,nfld,npts)
649
               call curvefit(otim,ofld,opts,ntim,nfld,npts)
648
            endif
650
            endif
649
 
651
 
650
c           Reverse date line handling
652
c           Reverse date line handling
651
            do j=1,npts
653
            do j=1,npts
652
               if ( nlon(j).gt.xmax ) then
654
               if ( nlon(j).gt.xmax ) then
653
                  nlon(j) = nlon(j) -360.
655
                  nlon(j) = nlon(j) -360.
654
               else if ( nlon(j).lt.xmin ) then
656
               else if ( nlon(j).lt.xmin ) then
655
                  nlon(j) = nlon(j) +360.
657
                  nlon(j) = nlon(j) +360.
656
               endif
658
               endif
657
            enddo
659
            enddo
658
 
660
 
659
c        Perform a reparameterisation with equally spaced gridpoint
661
c        Perform a reparameterisation with equally spaced gridpoint
660
         elseif ( (mode.eq.'space').and.(step.eq.0) ) then
662
         elseif ( (mode.eq.'space').and.(step.eq.0) ) then
661
            
663
            
662
c           Calculate the distance and spacing
664
c           Calculate the distance and spacing
663
            odist(1) = 0.
665
            odist(1) = 0.
664
            unit     = 'km'
666
            unit     = 'km'
665
            do j=2,ntime
667
            do j=2,ntime
666
               odist(j)=odist(j-1) + 
668
               odist(j)=odist(j-1) + 
667
     >                  sdis(olon(j-1),olat(j-1),olon(j),olat(j),unit)
669
     >                  sdis(olon(j-1),olat(j-1),olon(j),olat(j),unit)
668
            enddo
670
            enddo
669
            
671
            
670
c           Determine the new number of trajectory points
672
c           Determine the new number of trajectory points
671
            npts=nint(odist(ntime)/param)+1
673
            npts=nint(odist(ntime)/param)+1
672
            if (npts.eq.0) then
674
            if (npts.eq.0) then
673
               npts=1.
675
               npts=1.
674
            endif
676
            endif
675
        
677
        
676
c           Handle date line problem
678
c           Handle date line problem
677
            do j=2,opts
679
            do j=2,opts
678
               if ( (olon(j-1)-olon(j)).gt.180. ) then
680
               if ( (olon(j-1)-olon(j)).gt.180. ) then
679
                  olon(j) = olon(j) + 360.
681
                  olon(j) = olon(j) + 360.
680
               else if ( (olon(j-1)-olon(j)).lt.-180. ) then
682
               else if ( (olon(j-1)-olon(j)).lt.-180. ) then
681
                  olon(j) = olon(j) - 360.
683
                  olon(j) = olon(j) - 360.
682
               endif
684
               endif
683
            enddo
685
            enddo
684
                  
686
                  
685
c           Cubic spline fitting
687
c           Cubic spline fitting
686
            call curvefit(odist,olon,opts,ndist,nlon,npts)
688
            call curvefit(odist,olon,opts,ndist,nlon,npts)
687
            call curvefit(odist,olat,opts,ndist,nlat,npts)
689
            call curvefit(odist,olat,opts,ndist,nlat,npts)
688
            call curvefit(odist,otim,opts,ndist,ntim,npts)
690
            call curvefit(odist,otim,opts,ndist,ntim,npts)
689
            if ( field.ne.'nil' ) then
691
            if ( field.ne.'nil' ) then
690
               call curvefit(odist,ofld,opts,ndist,nfld,npts)
692
               call curvefit(odist,ofld,opts,ndist,nfld,npts)
691
            endif
693
            endif
692
 
694
 
693
c           Reverse date line handling
695
c           Reverse date line handling
694
            do j=1,npts
696
            do j=1,npts
695
               if ( nlon(j).gt.xmax ) then
697
               if ( nlon(j).gt.xmax ) then
696
                  nlon(j) = nlon(j) -360.
698
                  nlon(j) = nlon(j) -360.
697
               else if ( nlon(j).lt.xmin ) then
699
               else if ( nlon(j).lt.xmin ) then
698
                  nlon(j) = nlon(j) +360.
700
                  nlon(j) = nlon(j) +360.
699
               endif
701
               endif
700
            enddo
702
            enddo
701
 
703
 
702
c        Perform a reparameterisation with equally spaced gridpoint
704
c        Perform a reparameterisation with equally spaced gridpoint
703
         elseif ( (mode.eq.'grid').and.(step.eq.0) ) then
705
         elseif ( (mode.eq.'grid').and.(step.eq.0) ) then
704
            
706
            
705
c           Calculate the distance and spacing
707
c           Calculate the distance and spacing
706
            odist(1) = 0.
708
            odist(1) = 0.
707
            unit     = 'deg'
709
            unit     = 'deg'
708
            do j=2,ntime
710
            do j=2,ntime
709
               odist(j)=odist(j-1) + 
711
               odist(j)=odist(j-1) + 
710
     >                  sdis(olon(j-1),olat(j-1),olon(j),olat(j),unit)
712
     >                  sdis(olon(j-1),olat(j-1),olon(j),olat(j),unit)
711
            enddo
713
            enddo
712
            
714
            
713
c           Determine the new number of trajectory points
715
c           Determine the new number of trajectory points
714
            npts=nint(odist(ntime)/param)+1
716
            npts=nint(odist(ntime)/param)+1
715
            if (npts.eq.0) then
717
            if (npts.eq.0) then
716
               npts=1.
718
               npts=1.
717
            endif
719
            endif
718
        
720
        
719
c           Handle date line problem
721
c           Handle date line problem
720
            do j=2,opts
722
            do j=2,opts
721
               if ( (olon(j-1)-olon(j)).gt.180. ) then
723
               if ( (olon(j-1)-olon(j)).gt.180. ) then
722
                  olon(j) = olon(j) + 360.
724
                  olon(j) = olon(j) + 360.
723
               else if ( (olon(j-1)-olon(j)).lt.-180. ) then
725
               else if ( (olon(j-1)-olon(j)).lt.-180. ) then
724
                  olon(j) = olon(j) - 360.
726
                  olon(j) = olon(j) - 360.
725
               endif
727
               endif
726
            enddo
728
            enddo
727
                  
729
                  
728
c           Cubic spline fitting
730
c           Cubic spline fitting
729
            call curvefit(odist,olon,opts,ndist,nlon,npts)
731
            call curvefit(odist,olon,opts,ndist,nlon,npts)
730
            call curvefit(odist,olat,opts,ndist,nlat,npts)
732
            call curvefit(odist,olat,opts,ndist,nlat,npts)
731
            call curvefit(odist,otim,opts,ndist,ntim,npts)
733
            call curvefit(odist,otim,opts,ndist,ntim,npts)
732
            if ( field.ne.'nil' ) then
734
            if ( field.ne.'nil' ) then
733
               call curvefit(odist,ofld,opts,ndist,nfld,npts)
735
               call curvefit(odist,ofld,opts,ndist,nfld,npts)
734
            endif
736
            endif
735
 
737
 
736
c           Reverse date line handling
738
c           Reverse date line handling
737
            do j=1,npts
739
            do j=1,npts
738
               if ( nlon(j).gt.xmax ) then
740
               if ( nlon(j).gt.xmax ) then
739
                  nlon(j) = nlon(j) -360.
741
                  nlon(j) = nlon(j) -360.
740
               else if ( nlon(j).lt.xmin ) then
742
               else if ( nlon(j).lt.xmin ) then
741
                  nlon(j) = nlon(j) +360.
743
                  nlon(j) = nlon(j) +360.
742
               endif
744
               endif
743
            enddo
745
            enddo
744
 
746
 
745
         endif
747
         endif
746
 
748
 
747
c        -------- Do the gridding -------------------------------------
749
c        -------- Do the gridding -------------------------------------
748
 
750
 
749
c        Gridding of trajectory
751
c        Gridding of trajectory
750
         do j=1,npts
752
         do j=1,npts
751
 
753
 
752
c           Check whether point is in data domain
754
c           Check whether point is in data domain
753
	    if ( (nlon(j).gt.xmin).and.(nlon(j).lt.xmax).and.
755
	    if ( (nlon(j).gt.xmin).and.(nlon(j).lt.xmax).and.
754
     >       (nlat(j).gt.ymin).and.(nlat(j).lt.ymax))
756
     >       (nlat(j).gt.ymin).and.(nlat(j).lt.ymax))
755
     >      then
757
     >      then
756
 
758
 
757
c              Increase counter for gridded points
759
c              Increase counter for gridded points
758
               count = count + 1
760
               count = count + 1
759
 
761
 
760
c              ----------------- Gridding: simple count -----------------
762
c              ----------------- Gridding: simple count -----------------
761
               connectval0 = connectval0+1
763
               connectval0 = connectval0+1
762
               
764
               
763
               addvalue    = 1.
765
               addvalue    = 1.
764
               
766
               
765
               call  gridding1
767
               call  gridding1
766
     >              (nlat(j),nlon(j),addvalue,
768
     >              (nlat(j),nlon(j),addvalue,
767
     >               radius,runit,connect0,connectval0,
769
     >               radius,runit,connect0,connectval0,
768
     >               cnt,nx,ny,xmin,ymin,dx,dy)
770
     >               cnt,nx,ny,xmin,ymin,dx,dy)
769
 
771
 
770
c              ----------------- Gridding: residence time ---------------
772
c              ----------------- Gridding: residence time ---------------
771
               connectval1 = connectval1+1
773
               connectval1 = connectval1+1
772
               
774
               
773
               if ( ntime.eq.1 ) then
775
               if ( ntime.eq.1 ) then
774
                  addvalue = 0.
776
                  addvalue = 0.
775
               elseif ( j.eq.1 )  then
777
               elseif ( j.eq.1 )  then
776
                  addvalue=abs(ntim(2)-ntim(1))
778
                  addvalue=abs(ntim(2)-ntim(1))
777
               else
779
               else
778
                  addvalue=abs(ntim(j)-ntim(j-1))
780
                  addvalue=abs(ntim(j)-ntim(j-1))
779
               endif
781
               endif
780
               
782
               
781
               call  gridding1
783
               call  gridding1
782
     >              (nlat(j),nlon(j),addvalue,
784
     >              (nlat(j),nlon(j),addvalue,
783
     >               radius,runit,connect1,connectval1,
785
     >               radius,runit,connect1,connectval1,
784
     >               res,nx,ny,xmin,ymin,dx,dy)
786
     >               res,nx,ny,xmin,ymin,dx,dy)
785
 
787
 
786
 
788
 
787
c              --------------- Gridding: field -------------------------
789
c              --------------- Gridding: field -------------------------
788
               if ( field.ne.'nil' ) then
790
               if ( field.ne.'nil' ) then
789
 
791
 
790
                   connectval2 = connectval2+1
792
                   connectval2 = connectval2+1
791
               
793
               
792
                   addvalue    = nfld(j)
794
                   addvalue    = nfld(j)
793
               
795
               
794
                   call  gridding1
796
                   call  gridding1
795
     >                  (nlat(j),nlon(j),addvalue,
797
     >                  (nlat(j),nlon(j),addvalue,
796
     >                  radius,runit,connect2,connectval2,
798
     >                  radius,runit,connect2,connectval2,
797
     >                  fld,nx,ny,xmin,ymin,dx,dy)
799
     >                  fld,nx,ny,xmin,ymin,dx,dy)
798
 
800
 
799
               endif
801
               endif
800
 
802
 
801
	    endif
803
	    endif
802
 
804
 
803
         enddo
805
         enddo
804
 
806
 
805
c        Exit point for loop over all trajectories
807
c        Exit point for loop over all trajectories
806
 300     continue
808
 300     continue
807
 
809
 
808
      enddo
810
      enddo
809
 
811
 
810
c     Write status information
812
c     Write status information
811
      print*
813
      print*
812
      print*,' # gridded points       : ',count
814
      print*,' # gridded points       : ',count
813
 
815
 
814
c     ---------------------------------------------------------------------
816
c     ---------------------------------------------------------------------
815
c     Unit conversions and output to netCDF file
817
c     Unit conversions and output to netCDF file
816
c     ---------------------------------------------------------------------
818
c     ---------------------------------------------------------------------
817
 
819
 
818
c     Write some status information 
820
c     Write some status information 
819
      print*
821
      print*
820
      print*,'---- WRITE OUTPUT ---------------------------------------'
822
      print*,'---- WRITE OUTPUT ---------------------------------------'
821
      print*
823
      print*
822
 
824
 
823
c     Area (in km^2)
825
c     Area (in km^2)
824
      do i=1,nx	         
826
      do i=1,nx	         
825
         do j=1,ny	
827
         do j=1,ny	
826
            slat=ymin+real(j-1)*dy
828
            slat=ymin+real(j-1)*dy
827
            if (abs(abs(slat)-90.).gt.eps) then
829
            if (abs(abs(slat)-90.).gt.eps) then
828
               area(i,j) = dy*dx*cos(pi180*slat)*deltay**2
830
               area(i,j) = dy*dx*cos(pi180*slat)*deltay**2
829
            else
831
            else
830
               area(i,j) = 0.
832
               area(i,j) = 0.
831
            endif
833
            endif
832
         enddo
834
         enddo
833
      enddo
835
      enddo
834
 
836
 
835
c     Normalise gridded field
837
c     Normalise gridded field
836
      if ( field.ne.'nil' ) then
838
      if ( field.ne.'nil' ) then
837
         do i=1,nx
839
         do i=1,nx
838
            do j=1,ny
840
            do j=1,ny
839
               if ( cnt(i,j).gt.0. ) then
841
               if ( cnt(i,j).gt.0. ) then
840
                  fld(i,j) = fld(i,j) / cnt(i,j)
842
                  fld(i,j) = fld(i,j) / cnt(i,j)
841
               endif
843
               endif
842
            enddo
844
            enddo
843
         enddo
845
         enddo
844
      endif
846
      endif
845
 
847
 
846
c     Set the time for the output netCDF files - if a composite is
848
c     Set the time for the output netCDF files - if a composite is
847
c     calculatd, then the time is set to 
849
c     calculatd, then the time is set to 
848
      if ( step.eq.0 ) then
850
      if ( step.eq.0 ) then
849
         time = -999.
851
         time = -999.
850
         print*,'   ... COMPOSITE OVER ALL TRAJECTORY TIMES (-999)'
852
         print*,'   ... COMPOSITE OVER ALL TRAJECTORY TIMES (-999)'
851
         print*
853
         print*
852
      else
854
      else
853
         time = trainp(1,step,1)
855
         time = trainp(1,step,1)
854
      endif
856
      endif
855
 
857
 
856
c     Write output to CF netCDF
858
c     Write output to CF netCDF
857
      cdfname  = outfile
859
      cdfname  = outfile
858
      
860
      
859
      varname  = 'COUNT'
861
      varname  = 'COUNT'
860
      longname = 'trajectory counts'
862
      longname = 'trajectory counts'
861
      varunit  = 'counts per grid point'
863
      varunit  = 'counts per grid point'
862
      call  writecdf2D_cf (cdfname,varname,longname,varunit,gridtype,
864
      call  writecdf2D_cf (cdfname,varname,longname,varunit,gridtype,
863
     >       clon,clat,nlonlat,dlonlat,cnt,time,dx,dy,xmin,ymin,nx,
865
     >       clon,clat,nlonlat,dlonlat,cnt,time,dx,dy,xmin,ymin,nx,
864
     >       ny,crefile,crefile,1)
866
     >       ny,crefile,crefile,1)
865
      write(*,'(a8,a10,a5,a10,a10,f7.2,a2)') 
867
      write(*,'(a8,a10,a5,a10,a10,f7.2,a2)') 
866
     >     '    ... ',trim(varname),' -> ',trim(cdfname),
868
     >     '    ... ',trim(varname),' -> ',trim(cdfname),
867
     >     ' [ time = ',time,' ]'    
869
     >     ' [ time = ',time,' ]'    
868
 
870
 
869
      varname  = 'RESIDENCE'
871
      varname  = 'RESIDENCE'
870
      longname = 'residence time'
872
      longname = 'residence time'
871
      varunit  = 'hours per grid point'
873
      varunit  = 'hours per grid point'
872
 
874
 
873
      print*,'crefile = ',crefile
-
 
874
 
-
 
875
      call  writecdf2D_cf (cdfname,varname,longname,varunit,gridtype,
875
      call  writecdf2D_cf (cdfname,varname,longname,varunit,gridtype,
876
     >       clon,clat,nlonlat,dlonlat,res,time,dx,dy,xmin,ymin,nx,
876
     >       clon,clat,nlonlat,dlonlat,res,time,dx,dy,xmin,ymin,nx,
877
     >       ny,0,crefile,1)
877
     >       ny,0,crefile,1)
878
      write(*,'(a8,a10,a5,a10,a10,f7.2,a2)') 
878
      write(*,'(a8,a10,a5,a10,a10,f7.2,a2)') 
879
     >     '    ... ',trim(varname),' -> ',trim(cdfname),
879
     >     '    ... ',trim(varname),' -> ',trim(cdfname),
880
     >     ' [ time = ',time,' ]'    
880
     >     ' [ time = ',time,' ]'    
881
 
881
 
882
      varname  = 'AREA'
882
      varname  = 'AREA'
883
      longname = 'area corresponding to grid points'
883
      longname = 'area corresponding to grid points'
884
      varunit  = 'square kilometers'
884
      varunit  = 'square kilometers'
885
      call  writecdf2D_cf (cdfname,varname,longname,varunit,gridtype,
885
      call  writecdf2D_cf (cdfname,varname,longname,varunit,gridtype,
886
     >       clon,clat,nlonlat,dlonlat,area,time,dx,dy,xmin,ymin,nx,
886
     >       clon,clat,nlonlat,dlonlat,area,time,dx,dy,xmin,ymin,nx,
887
     >       ny,0,crefile,1)
887
     >       ny,0,crefile,1)
888
      write(*,'(a8,a10,a5,a10,a10,f7.2,a2)') 
888
      write(*,'(a8,a10,a5,a10,a10,f7.2,a2)') 
889
     >     '    ... ',trim(varname),' -> ',trim(cdfname),
889
     >     '    ... ',trim(varname),' -> ',trim(cdfname),
890
     >     ' [ time = ',time,' ]'    
890
     >     ' [ time = ',time,' ]'    
891
      
891
      
892
      if ( field.ne.'nil' ) then
892
      if ( field.ne.'nil' ) then
893
         varname  = field
893
         varname  = field
894
         longname = field
894
         longname = field
895
         varunit  = 'as on trajectory file'
895
         varunit  = 'as on trajectory file'
896
         call  writecdf2D_cf (cdfname,varname,longname,varunit,gridtype,
896
         call  writecdf2D_cf (cdfname,varname,longname,varunit,gridtype,
897
     >       clon,clat,nlonlat,dlonlat,fld,time,dx,dy,xmin,ymin,nx,
897
     >       clon,clat,nlonlat,dlonlat,fld,time,dx,dy,xmin,ymin,nx,
898
     >       ny,0,crevar,1)
898
     >       ny,0,crevar,1)
899
 
899
 
900
         write(*,'(a8,a10,a5,a10,a10,f7.2,a2)') 
900
         write(*,'(a8,a10,a5,a10,a10,f7.2,a2)') 
901
     >        '    ... ',trim(varname),' -> ',trim(cdfname),
901
     >        '    ... ',trim(varname),' -> ',trim(cdfname),
902
     >        ' [ time = ',time,' ]'    
902
     >        ' [ time = ',time,' ]'    
903
      endif
903
      endif
904
 
904
 
905
c     Write status information
905
c     Write status information
906
      print*
906
      print*
907
      print*,'              *** END OF PROGRAM DENSITY **'
907
      print*,'              *** END OF PROGRAM DENSITY **'
908
      print*,'========================================================='
908
      print*,'========================================================='
909
 
909
 
910
      end
910
      end
911
 
911
 
912
c     ********************************************************************
912
c     ********************************************************************
913
c     * GRIDDING SUBROUTINES                                             *
913
c     * GRIDDING SUBROUTINES                                             *
914
c     ********************************************************************
914
c     ********************************************************************
915
 
915
 
916
c     ---------------------------------------------------------------------
916
c     ---------------------------------------------------------------------
917
c     Gridding of one single data point (smoothing in km, deg, gridp)
917
c     Gridding of one single data point (smoothing in km, deg, gridp)
918
c     ---------------------------------------------------------------------
918
c     ---------------------------------------------------------------------
919
 
919
 
920
      subroutine gridding1 (lat,lon,addval,radius,unit,
920
      subroutine gridding1 (lat,lon,addval,radius,unit,
921
     >                      connect,connectval,
921
     >                      connect,connectval,
922
     >                      out,nx,ny,xmin,ymin,dx,dy)
922
     >                      out,nx,ny,xmin,ymin,dx,dy)
923
 
923
 
924
      implicit none
924
      implicit none
925
 
925
 
926
c     Declaration of subroutine parameters
926
c     Declaration of subroutine parameters
927
      real         lat,lon
927
      real         lat,lon
928
      integer      nx,ny
928
      integer      nx,ny
929
      real         xmin,ymin,dx,dy
929
      real         xmin,ymin,dx,dy
930
      real         out(nx,ny)
930
      real         out(nx,ny)
931
      real         radius
931
      real         radius
932
      character*80 unit
932
      character*80 unit
933
      integer      connectval
933
      integer      connectval
934
      integer      connect(nx,ny)
934
      integer      connect(nx,ny)
935
      real         addval
935
      real         addval
936
 
936
 
937
c     Auxiliary variables
937
c     Auxiliary variables
938
      integer   i,j,k
938
      integer   i,j,k
939
      integer   mu,md,nr,nl,n,m
939
      integer   mu,md,nr,nl,n,m
940
      integer   stackx(nx*ny),stacky(nx*ny)
940
      integer   stackx(nx*ny),stacky(nx*ny)
941
      integer   tab_x(nx*ny),tab_y(nx*ny)
941
      integer   tab_x(nx*ny),tab_y(nx*ny)
942
      real      tab_r(nx*ny)
942
      real      tab_r(nx*ny)
943
      integer   sp
943
      integer   sp
944
      real      lat2,lon2
944
      real      lat2,lon2
945
      real      dist,sum
945
      real      dist,sum
946
      real      xmax
946
      real      xmax
947
      integer   periodic
947
      integer   periodic
948
      integer   test
948
      integer   test
949
 
949
 
950
c     Numerical epsilon
950
c     Numerical epsilon
951
      real      eps
951
      real      eps
952
      parameter (eps=0.01)
952
      parameter (eps=0.01)
953
 
953
 
954
c     Externals
954
c     Externals
955
      real      sdis,weight
955
      real      sdis,weight
956
      external  sdis,weight
956
      external  sdis,weight
957
 
957
 
958
c     Check whether lat/lon point is valid
958
c     Check whether lat/lon point is valid
959
      xmax=xmin+real(nx-1)*dx
959
      xmax=xmin+real(nx-1)*dx
960
      if (lon.lt.xmin-eps) lon=lon+360.
960
      if (lon.lt.xmin-eps) lon=lon+360.
961
      if (lon.gt.xmax+eps) lon=lon-360.
961
      if (lon.gt.xmax+eps) lon=lon-360.
962
      if (abs(lat-90).lt.eps) lat=90.
962
      if (abs(lat-90).lt.eps) lat=90.
963
      if (abs(lat+90).lt.eps) lat=-90.
963
      if (abs(lat+90).lt.eps) lat=-90.
964
      if ((abs(lat).gt.(90.+eps)).or.
964
      if ((abs(lat).gt.(90.+eps)).or.
965
     >    (lon.lt.xmin-eps).or.(lon.gt.xmax+eps)) then
965
     >    (lon.lt.xmin-eps).or.(lon.gt.xmax+eps)) then
966
         print*,'Invalid lat/lon point ',lat,lon
966
         print*,'Invalid lat/lon point ',lat,lon
967
         return
967
         return
968
      endif
968
      endif
969
 
969
 
970
c     Set flag for periodic domain
970
c     Set flag for periodic domain
971
      if (abs(xmax-xmin-360.).lt.eps) then
971
      if (abs(xmax-xmin-360.).lt.eps) then
972
         periodic=1
972
         periodic=1
973
      else if (abs(xmax-xmin-360+dx).lt.eps) then
973
      else if (abs(xmax-xmin-360+dx).lt.eps) then
974
         periodic=2
974
         periodic=2
975
      else
975
      else
976
         periodic=0
976
         periodic=0
977
      endif
977
      endif
978
 
978
 
979
c     Get indices of one coarse grid point within search radius
979
c     Get indices of one coarse grid point within search radius
980
      i=nint((lon-xmin)/dx)+1
980
      i=nint((lon-xmin)/dx)+1
981
      if ((i.eq.nx).and.(periodic.eq.1)) i=1
981
      if ((i.eq.nx).and.(periodic.eq.1)) i=1
982
      j=nint((lat-ymin)/dy)+1
982
      j=nint((lat-ymin)/dy)+1
983
      lat2=ymin+real(j-1)*dy
983
      lat2=ymin+real(j-1)*dy
984
      lon2=xmin+real(i-1)*dx
984
      lon2=xmin+real(i-1)*dx
985
      dist=sdis(lon,lat,lon2,lat2,unit)
985
      dist=sdis(lon,lat,lon2,lat2,unit)
986
      if (dist.gt.radius) then
986
      if (dist.gt.radius) then
987
         print*,'1: Search radius is too small...'
987
         print*,'1: Search radius is too small...'
988
         stop
988
         stop
989
      endif
989
      endif
990
 
990
 
991
c     Get connected points
991
c     Get connected points
992
      k=0
992
      k=0
993
      stackx(1)=i
993
      stackx(1)=i
994
      stacky(1)=j
994
      stacky(1)=j
995
      sp=1
995
      sp=1
996
      do while (sp.ne.0) 
996
      do while (sp.ne.0) 
997
         
997
         
998
c        Get an element from stack
998
c        Get an element from stack
999
         n=stackx(sp)
999
         n=stackx(sp)
1000
         m=stacky(sp)
1000
         m=stacky(sp)
1001
         sp=sp-1
1001
         sp=sp-1
1002
                  
1002
                  
1003
c        Get distance from reference point
1003
c        Get distance from reference point
1004
         lat2=ymin+real(m-1)*dy
1004
         lat2=ymin+real(m-1)*dy
1005
         lon2=xmin+real(n-1)*dx
1005
         lon2=xmin+real(n-1)*dx
1006
         dist=sdis(lon,lat,lon2,lat2,unit)
1006
         dist=sdis(lon,lat,lon2,lat2,unit)
1007
 
1007
 
1008
c        Check whether distance is smaller than search radius: connected
1008
c        Check whether distance is smaller than search radius: connected
1009
         if (dist.lt.radius) then
1009
         if (dist.lt.radius) then
1010
 
1010
 
1011
c           Make entry in filter mask
1011
c           Make entry in filter mask
1012
            k=k+1
1012
            k=k+1
1013
            tab_x(k)=n
1013
            tab_x(k)=n
1014
            tab_y(k)=m
1014
            tab_y(k)=m
1015
            tab_r(k)=weight(dist,radius)
1015
            tab_r(k)=weight(dist,radius)
1016
 
1016
 
1017
c           Mark this point as visited
1017
c           Mark this point as visited
1018
            connect(n,m)=connectval
1018
            connect(n,m)=connectval
1019
                     
1019
                     
1020
c           Get coordinates of neighbouring points
1020
c           Get coordinates of neighbouring points
1021
            nr=n+1
1021
            nr=n+1
1022
            if ((nr.gt.nx)  .and.(periodic.eq.0)) nr=nx
1022
            if ((nr.gt.nx)  .and.(periodic.eq.0)) nr=nx
1023
            if ((nr.gt.nx-1).and.(periodic.eq.1)) nr=1
1023
            if ((nr.gt.nx-1).and.(periodic.eq.1)) nr=1
1024
            if ((nr.gt.nx)  .and.(periodic.eq.2)) nr=1
1024
            if ((nr.gt.nx)  .and.(periodic.eq.2)) nr=1
1025
            nl=n-1
1025
            nl=n-1
1026
            if ((nl.lt.1).and.(periodic.eq.0)) nl=1
1026
            if ((nl.lt.1).and.(periodic.eq.0)) nl=1
1027
            if ((nl.lt.1).and.(periodic.eq.1)) nl=nx-1
1027
            if ((nl.lt.1).and.(periodic.eq.1)) nl=nx-1
1028
            if ((nl.lt.1).and.(periodic.eq.2)) nl=nx
1028
            if ((nl.lt.1).and.(periodic.eq.2)) nl=nx
1029
            mu=m+1
1029
            mu=m+1
1030
            if (mu.gt.ny) mu=ny
1030
            if (mu.gt.ny) mu=ny
1031
            md=m-1
1031
            md=m-1
1032
            if (md.lt.1) md=1
1032
            if (md.lt.1) md=1
1033
 
1033
 
1034
c           Update stack
1034
c           Update stack
1035
            if (connect(nr,m).ne.connectval) then
1035
            if (connect(nr,m).ne.connectval) then
1036
               connect(nr,m)=connectval
1036
               connect(nr,m)=connectval
1037
               sp=sp+1
1037
               sp=sp+1
1038
               stackx(sp)=nr
1038
               stackx(sp)=nr
1039
               stacky(sp)=m
1039
               stacky(sp)=m
1040
            endif
1040
            endif
1041
            if (connect(nl,m).ne.connectval) then
1041
            if (connect(nl,m).ne.connectval) then
1042
               connect(nl,m)=connectval
1042
               connect(nl,m)=connectval
1043
               sp=sp+1
1043
               sp=sp+1
1044
               stackx(sp)=nl
1044
               stackx(sp)=nl
1045
               stacky(sp)=m
1045
               stacky(sp)=m
1046
            endif
1046
            endif
1047
            if (connect(n,mu).ne.connectval) then
1047
            if (connect(n,mu).ne.connectval) then
1048
               connect(n,mu)=connectval
1048
               connect(n,mu)=connectval
1049
               sp=sp+1
1049
               sp=sp+1
1050
               stackx(sp)=n
1050
               stackx(sp)=n
1051
               stacky(sp)=mu
1051
               stacky(sp)=mu
1052
            endif
1052
            endif
1053
            if (connect(n,md).ne.connectval) then
1053
            if (connect(n,md).ne.connectval) then
1054
               connect(n,md)=connectval
1054
               connect(n,md)=connectval
1055
               sp=sp+1
1055
               sp=sp+1
1056
               stackx(sp)=n
1056
               stackx(sp)=n
1057
               stacky(sp)=md
1057
               stacky(sp)=md
1058
            endif
1058
            endif
1059
         endif
1059
         endif
1060
         
1060
         
1061
      end do
1061
      end do
1062
 
1062
 
1063
      if (k.ge.1) then
1063
      if (k.ge.1) then
1064
         sum=0.
1064
         sum=0.
1065
         do i=1,k
1065
         do i=1,k
1066
            sum=sum+tab_r(i)
1066
            sum=sum+tab_r(i)
1067
         enddo
1067
         enddo
1068
         do i=1,k
1068
         do i=1,k
1069
            out(tab_x(i),tab_y(i))=out(tab_x(i),tab_y(i))+
1069
            out(tab_x(i),tab_y(i))=out(tab_x(i),tab_y(i))+
1070
     >                             addval*tab_r(i)/sum
1070
     >                             addval*tab_r(i)/sum
1071
 
1071
 
1072
            if ((tab_x(i).eq.1).and.(periodic.eq.1)) then
1072
            if ((tab_x(i).eq.1).and.(periodic.eq.1)) then
1073
               out(nx,tab_y(i))=out(nx,tab_y(i))+
1073
               out(nx,tab_y(i))=out(nx,tab_y(i))+
1074
     >                             addval*tab_r(i)/sum
1074
     >                             addval*tab_r(i)/sum
1075
            endif
1075
            endif
1076
         enddo
1076
         enddo
1077
      else
1077
      else
1078
         print*,'2: Search radius is too small...'
1078
         print*,'2: Search radius is too small...'
1079
         stop
1079
         stop
1080
      endif
1080
      endif
1081
 
1081
 
1082
      end
1082
      end
1083
 
1083
 
1084
 
1084
 
1085
c     ----------------------------------------------------------------------
1085
c     ----------------------------------------------------------------------
1086
c     Get spherical distance between lat/lon points
1086
c     Get spherical distance between lat/lon points
1087
c     ----------------------------------------------------------------------
1087
c     ----------------------------------------------------------------------
1088
            
1088
            
1089
      real function sdis(xp,yp,xq,yq,unit)
1089
      real function sdis(xp,yp,xq,yq,unit)
1090
 
1090
 
1091
c     Calculates spherical distance (in km) between two points given
1091
c     Calculates spherical distance (in km) between two points given
1092
c     by their spherical coordinates (xp,yp) and (xq,yq), respectively.
1092
c     by their spherical coordinates (xp,yp) and (xq,yq), respectively.
1093
 
1093
 
1094
      real         re
1094
      real         re
1095
      parameter    (re=6370.)
1095
      parameter    (re=6370.)
1096
      real         xp,yp,xq,yq,arg
1096
      real         xp,yp,xq,yq,arg
1097
      character*80 unit
1097
      character*80 unit
1098
      real         dlon
1098
      real         dlon
1099
 
1099
 
1100
      if ( unit.eq.'km' ) then
1100
      if ( unit.eq.'km' ) then
1101
 
1101
 
1102
         arg=sind(yp)*sind(yq)+cosd(yp)*cosd(yq)*cosd(xp-xq)
1102
         arg=sind(yp)*sind(yq)+cosd(yp)*cosd(yq)*cosd(xp-xq)
1103
         if (arg.lt.-1.) arg=-1.
1103
         if (arg.lt.-1.) arg=-1.
1104
         if (arg.gt.1.) arg=1.
1104
         if (arg.gt.1.) arg=1.
1105
         sdis=re*acos(arg)
1105
         sdis=re*acos(arg)
1106
         
1106
         
1107
      elseif ( unit.eq.'deg' ) then
1107
      elseif ( unit.eq.'deg' ) then
1108
 
1108
 
1109
         dlon = xp-xq
1109
         dlon = xp-xq
1110
         if ( dlon.gt. 180. ) dlon = dlon - 360.
1110
         if ( dlon.gt. 180. ) dlon = dlon - 360.
1111
         if ( dlon.lt.-180. ) dlon = dlon + 360.
1111
         if ( dlon.lt.-180. ) dlon = dlon + 360.
1112
         sdis = sqrt( dlon**2 + (yp-yq)**2 )
1112
         sdis = sqrt( dlon**2 + (yp-yq)**2 )
1113
 
1113
 
1114
      endif
1114
      endif
1115
      
1115
      
1116
 
1116
 
1117
c     Quick and dirty trick to avoid zero distances
1117
c     Quick and dirty trick to avoid zero distances
1118
      if (sdis.eq.0.) sdis=0.1
1118
      if (sdis.eq.0.) sdis=0.1
1119
 
1119
 
1120
      end
1120
      end
1121
 
1121
 
1122
c     ----------------------------------------------------------------------
1122
c     ----------------------------------------------------------------------
1123
c     Weight function for the filter mask
1123
c     Weight function for the filter mask
1124
c     ----------------------------------------------------------------------
1124
c     ----------------------------------------------------------------------
1125
 
1125
 
1126
      real function weight (r,radius)
1126
      real function weight (r,radius)
1127
 
1127
 
1128
c     Attribute to each distanc r its corresponding weight in the filter mask
1128
c     Attribute to each distanc r its corresponding weight in the filter mask
1129
 
1129
 
1130
      implicit none
1130
      implicit none
1131
 
1131
 
1132
c     Declaration of subroutine parameters
1132
c     Declaration of subroutine parameters
1133
      real r
1133
      real r
1134
      real radius
1134
      real radius
1135
 
1135
 
1136
c     Simple 0/1 mask
1136
c     Simple 0/1 mask
1137
      if (r.lt.radius) then
1137
      if (r.lt.radius) then
1138
         weight=exp(-r/radius)
1138
         weight=exp(-r/radius)
1139
      else
1139
      else
1140
         weight=0.
1140
         weight=0.
1141
      endif
1141
      endif
1142
 
1142
 
1143
      end
1143
      end
1144
 
1144
 
1145
 
1145
 
1146
c     ********************************************************************
1146
c     ********************************************************************
1147
c     * REPARAMETERIZATION SUBROUTINES                                   *
1147
c     * REPARAMETERIZATION SUBROUTINES                                   *
1148
c     ********************************************************************
1148
c     ********************************************************************
1149
 
1149
 
1150
c     -------------------------------------------------------------
1150
c     -------------------------------------------------------------
1151
c     Interpolation of the trajectory with a natural cubic spline
1151
c     Interpolation of the trajectory with a natural cubic spline
1152
c     -------------------------------------------------------------
1152
c     -------------------------------------------------------------
1153
 
1153
 
1154
      SUBROUTINE curvefit (time,lon,n,
1154
      SUBROUTINE curvefit (time,lon,n,
1155
     >                     sptime,splon,spn)
1155
     >                     sptime,splon,spn)
1156
 
1156
 
1157
c     Given the curve <time,lon> with <n> data points, fit a
1157
c     Given the curve <time,lon> with <n> data points, fit a
1158
c     cubic spline to this curve. The new curve is returned in 
1158
c     cubic spline to this curve. The new curve is returned in 
1159
c     <sptime,splon,spn> with <spn> data points. The parameter
1159
c     <sptime,splon,spn> with <spn> data points. The parameter
1160
c     <spn> specifies on entry the number of spline interpolated points
1160
c     <spn> specifies on entry the number of spline interpolated points
1161
c     along the curve.
1161
c     along the curve.
1162
      
1162
      
1163
      implicit none
1163
      implicit none
1164
 
1164
 
1165
c     Declaration of subroutine parameters
1165
c     Declaration of subroutine parameters
1166
      integer n
1166
      integer n
1167
      real time(n),lon(n)
1167
      real time(n),lon(n)
1168
      integer spn
1168
      integer spn
1169
      real sptime(spn),splon(spn)
1169
      real sptime(spn),splon(spn)
1170
 
1170
 
1171
c     Auxiliary variables
1171
c     Auxiliary variables
1172
      real y2ax(n)
1172
      real y2ax(n)
1173
      real dt
1173
      real dt
1174
      real s
1174
      real s
1175
      integer i
1175
      integer i
1176
      real order
1176
      real order
1177
 
1177
 
1178
c     Determine whether the input array is ascending or descending
1178
c     Determine whether the input array is ascending or descending
1179
      if (time(1).gt.time(n)) then
1179
      if (time(1).gt.time(n)) then
1180
         order=-1.
1180
         order=-1.
1181
      else
1181
      else
1182
         order= 1.
1182
         order= 1.
1183
      endif
1183
      endif
1184
 
1184
 
1185
c     Bring the time array into ascending order
1185
c     Bring the time array into ascending order
1186
      do i=1,n
1186
      do i=1,n
1187
         time(i)=order*time(i)
1187
         time(i)=order*time(i)
1188
      enddo
1188
      enddo
1189
 
1189
 
1190
c     Prepare the (natural) cubic spline interpolation
1190
c     Prepare the (natural) cubic spline interpolation
1191
      call spline (time,lon,n,1.e30,1.e30,y2ax)
1191
      call spline (time,lon,n,1.e30,1.e30,y2ax)
1192
      dt=(time(n)-time(1))/real(spn-1)
1192
      dt=(time(n)-time(1))/real(spn-1)
1193
      do i=1,spn
1193
      do i=1,spn
1194
         sptime(i)=time(1)+real(i-1)*dt
1194
         sptime(i)=time(1)+real(i-1)*dt
1195
      enddo
1195
      enddo
1196
      
1196
      
1197
c     Do the spline interpolation
1197
c     Do the spline interpolation
1198
      do i=1,spn
1198
      do i=1,spn
1199
         call splint(time,lon,y2ax,n,sptime(i),s)
1199
         call splint(time,lon,y2ax,n,sptime(i),s)
1200
         splon(i)=s
1200
         splon(i)=s
1201
      enddo
1201
      enddo
1202
 
1202
 
1203
c     Change the time arrays back
1203
c     Change the time arrays back
1204
      do i=1,spn
1204
      do i=1,spn
1205
         sptime(i)=order*sptime(i)
1205
         sptime(i)=order*sptime(i)
1206
      enddo
1206
      enddo
1207
      do i=1,n
1207
      do i=1,n
1208
         time(i)=order*time(i)
1208
         time(i)=order*time(i)
1209
      enddo
1209
      enddo
1210
 
1210
 
1211
      return
1211
      return
1212
      end
1212
      end
1213
 
1213
 
1214
c     -------------------------------------------------------------
1214
c     -------------------------------------------------------------
1215
c     Basic routines for spline interpolation (Numerical Recipes)
1215
c     Basic routines for spline interpolation (Numerical Recipes)
1216
c     -------------------------------------------------------------
1216
c     -------------------------------------------------------------
1217
 
1217
 
1218
      SUBROUTINE spline(x,y,n,yp1,ypn,y2)
1218
      SUBROUTINE spline(x,y,n,yp1,ypn,y2)
1219
      INTEGER n,NMAX
1219
      INTEGER n,NMAX
1220
      REAL yp1,ypn,x(n),y(n),y2(n)
1220
      REAL yp1,ypn,x(n),y(n),y2(n)
1221
      PARAMETER (NMAX=500)
1221
      PARAMETER (NMAX=500)
1222
      INTEGER i,k
1222
      INTEGER i,k
1223
      REAL p,qn,sig,un,u(NMAX)
1223
      REAL p,qn,sig,un,u(NMAX)
1224
      if (yp1.gt..99e30) then
1224
      if (yp1.gt..99e30) then
1225
        y2(1)=0.
1225
        y2(1)=0.
1226
        u(1)=0.
1226
        u(1)=0.
1227
      else
1227
      else
1228
        y2(1)=-0.5
1228
        y2(1)=-0.5
1229
        u(1)=(3./(x(2)-x(1)))*((y(2)-y(1))/(x(2)-x(1))-yp1)
1229
        u(1)=(3./(x(2)-x(1)))*((y(2)-y(1))/(x(2)-x(1))-yp1)
1230
      endif
1230
      endif
1231
      do 11 i=2,n-1
1231
      do 11 i=2,n-1
1232
        sig=(x(i)-x(i-1))/(x(i+1)-x(i-1))
1232
        sig=(x(i)-x(i-1))/(x(i+1)-x(i-1))
1233
        p=sig*y2(i-1)+2.
1233
        p=sig*y2(i-1)+2.
1234
        y2(i)=(sig-1.)/p
1234
        y2(i)=(sig-1.)/p
1235
        u(i)=(6.*((y(i+1)-y(i))/(x(i+
1235
        u(i)=(6.*((y(i+1)-y(i))/(x(i+
1236
     *1)-x(i))-(y(i)-y(i-1))/(x(i)-x(i-1)))/(x(i+1)-x(i-1))-sig*
1236
     *1)-x(i))-(y(i)-y(i-1))/(x(i)-x(i-1)))/(x(i+1)-x(i-1))-sig*
1237
     *u(i-1))/p
1237
     *u(i-1))/p
1238
11    continue
1238
11    continue
1239
      if (ypn.gt..99e30) then
1239
      if (ypn.gt..99e30) then
1240
        qn=0.
1240
        qn=0.
1241
        un=0.
1241
        un=0.
1242
      else
1242
      else
1243
        qn=0.5
1243
        qn=0.5
1244
        un=(3./(x(n)-x(n-1)))*(ypn-(y(n)-y(n-1))/(x(n)-x(n-1)))
1244
        un=(3./(x(n)-x(n-1)))*(ypn-(y(n)-y(n-1))/(x(n)-x(n-1)))
1245
      endif
1245
      endif
1246
      y2(n)=(un-qn*u(n-1))/(qn*y2(n-1)+1.)
1246
      y2(n)=(un-qn*u(n-1))/(qn*y2(n-1)+1.)
1247
      do 12 k=n-1,1,-1
1247
      do 12 k=n-1,1,-1
1248
        y2(k)=y2(k)*y2(k+1)+u(k)
1248
        y2(k)=y2(k)*y2(k+1)+u(k)
1249
12    continue
1249
12    continue
1250
      return
1250
      return
1251
      END
1251
      END
1252
 
1252
 
1253
      SUBROUTINE splint(xa,ya,y2a,n,x,y)
1253
      SUBROUTINE splint(xa,ya,y2a,n,x,y)
1254
      INTEGER n
1254
      INTEGER n
1255
      REAL x,y,xa(n),y2a(n),ya(n)
1255
      REAL x,y,xa(n),y2a(n),ya(n)
1256
      INTEGER k,khi,klo
1256
      INTEGER k,khi,klo
1257
      REAL a,b,h
1257
      REAL a,b,h
1258
      klo=1
1258
      klo=1
1259
      khi=n
1259
      khi=n
1260
1     if (khi-klo.gt.1) then
1260
1     if (khi-klo.gt.1) then
1261
        k=(khi+klo)/2
1261
        k=(khi+klo)/2
1262
        if(xa(k).gt.x)then
1262
        if(xa(k).gt.x)then
1263
          khi=k
1263
          khi=k
1264
        else
1264
        else
1265
          klo=k
1265
          klo=k
1266
        endif
1266
        endif
1267
      goto 1
1267
      goto 1
1268
      endif
1268
      endif
1269
      h=xa(khi)-xa(klo)
1269
      h=xa(khi)-xa(klo)
1270
      if (h.eq.0.) then
1270
      if (h.eq.0.) then
1271
         print*,'bad xa input in splint'
1271
         print*,'bad xa input in splint'
1272
         stop
1272
         stop
1273
      endif
1273
      endif
1274
      a=(xa(khi)-x)/h
1274
      a=(xa(khi)-x)/h
1275
      b=(x-xa(klo))/h
1275
      b=(x-xa(klo))/h
1276
      y=a*ya(klo)+b*ya(khi)+((a**3-a)*y2a(klo)+(b**3-b)*y2a(khi))*(h**
1276
      y=a*ya(klo)+b*ya(khi)+((a**3-a)*y2a(klo)+(b**3-b)*y2a(khi))*(h**
1277
     *2)/6.
1277
     *2)/6.
1278
      return
1278
      return
1279
      END
1279
      END
1280
 
1280
 
1281
c     ********************************************************************
1281
c     ********************************************************************
1282
c     * INPUT / OUTPUT SUBROUTINES                                       *
1282
c     * INPUT / OUTPUT SUBROUTINES                                       *
1283
c     ********************************************************************
1283
c     ********************************************************************
1284
 
1284
 
1285
 
1285
 
1286
c     --------------------------------------------------------------------
1286
c     --------------------------------------------------------------------
1287
c     Subroutines to write the CF netcdf output file
1287
c     Subroutines to write the CF netcdf output file
1288
c     --------------------------------------------------------------------
1288
c     --------------------------------------------------------------------
1289
 
1289
 
1290
      subroutine writecdf2D_cf 
1290
      subroutine writecdf2D_cf 
1291
     >          (cdfname,varname,longname,unit,gridtype,clon,clat,
1291
     >          (cdfname,varname,longname,unit,gridtype,clon,clat,
1292
     >           nlonlat,dlonlat,arr,time,dx,dy,xmin,ymin,nx,ny,
1292
     >           nlonlat,dlonlat,arr,time,dx,dy,xmin,ymin,nx,ny,
1293
     >           crefile,crevar,cretime)
1293
     >           crefile,crevar,cretime)
1294
 
1294
 
1295
c     Create and write to the CF netcdf file <cdfname>. The variable
1295
c     Create and write to the CF netcdf file <cdfname>. The variable
1296
c     with name <varname> and with time <time> is written. The data
1296
c     with name <varname> and with time <time> is written. The data
1297
c     are in the two-dimensional array <arr>. The list <dx,dy,xmin,
1297
c     are in the two-dimensional array <arr>. The list <dx,dy,xmin,
1298
c     ymin,nx,ny> specifies the output grid. The flags <crefile> and
1298
c     ymin,nx,ny> specifies the output grid. The flags <crefile> and
1299
c     <crevar> determine whether the file and/or the variable should
1299
c     <crevar> determine whether the file and/or the variable should
1300
c     be created; correspondingly for the unlimited dimension <time>
1300
c     be created; correspondingly for the unlimited dimension <time>
1301
c     with the flag <cretime>.
1301
c     with the flag <cretime>.
1302
 
1302
 
1303
      USE netcdf
1303
      USE netcdf
1304
 
1304
 
1305
      IMPLICIT NONE
1305
      IMPLICIT NONE
1306
 
1306
 
1307
c     Declaration of input parameters
1307
c     Declaration of input parameters
1308
      character*80 cdfname
1308
      character*80 cdfname
1309
      character*80 varname,longname,unit
1309
      character*80 varname,longname,unit
1310
      integer      nx,ny
1310
      integer      nx,ny
1311
      real         arr(nx,ny)
1311
      real         arr(nx,ny)
1312
      real         dx,dy,xmin,ymin
1312
      real         dx,dy,xmin,ymin
1313
      real         time
1313
      real         time
1314
      integer      crefile,crevar,cretime
1314
      integer      crefile,crevar,cretime
1315
      character*80 gridtype
1315
      character*80 gridtype
1316
      real         clon,clat
1316
      real         clon,clat
1317
      integer      nlonlat
1317
      integer      nlonlat
1318
      real         dlonlat
1318
      real         dlonlat
1319
 
1319
 
1320
c     Local variables
1320
c     Local variables
1321
      integer      ierr
1321
      integer      ierr
1322
      integer      ncID
1322
      integer      ncID
1323
      integer      LonDimId,    varLonID
1323
      integer      LonDimId,    varLonID
1324
      integer      LatDimID,    varLatID
1324
      integer      LatDimID,    varLatID
1325
      integer      TimeDimID,   varTimeID
1325
      integer      TimeDimID,   varTimeID
1326
      real         longitude(nx)
1326
      real         longitude(nx)
1327
      real         latitude (ny)
1327
      real         latitude (ny)
1328
      real         timeindex
1328
      real         timeindex
1329
      integer      i
1329
      integer      i
1330
      integer      nvars,varids(100)
1330
      integer      nvars,varids(100)
1331
      integer      ndims,dimids(100)
1331
      integer      ndims,dimids(100)
1332
      real         timelist(1000)
1332
      real         timelist(1000)
1333
      integer      ntimes
1333
      integer      ntimes
1334
      integer      ind
1334
      integer      ind
1335
      integer      varID
1335
      integer      varID
1336
 
1336
 
1337
c     Quick an dirty solution for fieldname conflict
1337
c     Quick an dirty solution for fieldname conflict
1338
      if ( varname.eq.'time' ) varname = 'TIME'
1338
      if ( varname.eq.'time' ) varname = 'TIME'
1339
 
1339
 
1340
c     Initially set error to indicate no errors.
1340
c     Initially set error to indicate no errors.
1341
      ierr = 0
1341
      ierr = 0
1342
 
1342
 
1343
c     ---- Create the netCDF - skip if <crefile=0> ----------------------
1343
c     ---- Create the netCDF - skip if <crefile=0> ----------------------
1344
      if ( crefile.ne.1 ) goto 100
1344
      if ( crefile.ne.1 ) goto 100
1345
 
1345
 
1346
c     Create the file 
1346
c     Create the file 
1347
      ierr = nf90_create(trim(cdfname), NF90_CLOBBER, ncID)
1347
      ierr = nf90_create(trim(cdfname), NF90_CLOBBER, ncID)
1348
      
1348
      
1349
c     Define dimensions 
1349
c     Define dimensions 
1350
      ierr=nf90_def_dim(ncID,'longitude',nx            , LonDimID )
1350
      ierr=nf90_def_dim(ncID,'longitude',nx            , LonDimID )
1351
      ierr=nf90_def_dim(ncID,'latitude' ,ny            , LatDimID )
1351
      ierr=nf90_def_dim(ncID,'latitude' ,ny            , LatDimID )
1352
      ierr=nf90_def_dim(ncID,'time'     ,nf90_unlimited, TimeDimID)
1352
      ierr=nf90_def_dim(ncID,'time'     ,nf90_unlimited, TimeDimID)
1353
      
1353
      
1354
c     Define coordinate Variables 
1354
c     Define coordinate Variables 
1355
      ierr = nf90_def_var(ncID,'longitude',NF90_FLOAT,
1355
      ierr = nf90_def_var(ncID,'longitude',NF90_FLOAT,
1356
     >     (/ LonDimID /),varLonID)
1356
     >     (/ LonDimID /),varLonID)
1357
      ierr = nf90_put_att(ncID, varLonID, "standard_name","longitude")
1357
      ierr = nf90_put_att(ncID, varLonID, "standard_name","longitude")
1358
      ierr = nf90_put_att(ncID, varLonID, "units"      ,"degree_east")
1358
      ierr = nf90_put_att(ncID, varLonID, "units"      ,"degree_east")
1359
      
1359
      
1360
      ierr = nf90_def_var(ncID,'latitude',NF90_FLOAT,
1360
      ierr = nf90_def_var(ncID,'latitude',NF90_FLOAT,
1361
     >     (/ LatDimID /),varLatID)
1361
     >     (/ LatDimID /),varLatID)
1362
      ierr = nf90_put_att(ncID, varLatID, "standard_name", "latitude")
1362
      ierr = nf90_put_att(ncID, varLatID, "standard_name", "latitude")
1363
      ierr = nf90_put_att(ncID, varLatID, "units"    ,"degree_north")
1363
      ierr = nf90_put_att(ncID, varLatID, "units"    ,"degree_north")
1364
      
1364
      
1365
      ierr = nf90_def_var(ncID,'time',NF90_FLOAT, 
1365
      ierr = nf90_def_var(ncID,'time',NF90_FLOAT, 
1366
     >     (/ TimeDimID /), varTimeID)
1366
     >     (/ TimeDimID /), varTimeID)
1367
      ierr = nf90_put_att(ncID, varTimeID, "axis",            "T")
1367
      ierr = nf90_put_att(ncID, varTimeID, "axis",            "T")
1368
      ierr = nf90_put_att(ncID, varTimeID, "calendar", "standard")
1368
      ierr = nf90_put_att(ncID, varTimeID, "calendar", "standard")
1369
      ierr = nf90_put_att(ncID, varTimeID, "long_name",    "time")
1369
      ierr = nf90_put_att(ncID, varTimeID, "long_name",    "time")
1370
      ierr = nf90_put_att(ncID, varTimeID, "units",       "hours")
1370
      ierr = nf90_put_att(ncID, varTimeID, "units",       "hours")
1371
      
1371
      
1372
c     Write global attributes 
1372
c     Write global attributes 
1373
      ierr = nf90_put_att(ncID, NF90_GLOBAL, 'Conventions', 'CF-1.0')
1373
      ierr = nf90_put_att(ncID, NF90_GLOBAL, 'Conventions', 'CF-1.0')
1374
      ierr = nf90_put_att(ncID, NF90_GLOBAL, 'title',  
1374
      ierr = nf90_put_att(ncID, NF90_GLOBAL, 'title',  
1375
     >     'Trajectory Densities')
1375
     >     'Trajectory Densities')
1376
      ierr = nf90_put_att(ncID, NF90_GLOBAL, 'source', 
1376
      ierr = nf90_put_att(ncID, NF90_GLOBAL, 'source', 
1377
     >     'Lagranto Trajectories')
1377
     >     'Lagranto Trajectories')
1378
      ierr = nf90_put_att(ncID, NF90_GLOBAL, 'institution', 
1378
      ierr = nf90_put_att(ncID, NF90_GLOBAL, 'institution', 
1379
     >     'ETH Zurich, IACETH')
1379
     >     'ETH Zurich, IACETH')
1380
      ierr = nf90_put_att(ncID, NF90_GLOBAL, 'grid',trim(gridtype) ) 
1380
      ierr = nf90_put_att(ncID, NF90_GLOBAL, 'grid',trim(gridtype) ) 
-
 
1381
      if ( gridtype.eq.'rotated' ) then
1381
      ierr = nf90_put_att(ncID, NF90_GLOBAL, 'clon',clon )
1382
         ierr = nf90_put_att(ncID, NF90_GLOBAL, 'clon',clon )
1382
      ierr = nf90_put_att(ncID, NF90_GLOBAL, 'clat',clat )
1383
         ierr = nf90_put_att(ncID, NF90_GLOBAL, 'clat',clat )
1383
      ierr = nf90_put_att(ncID, NF90_GLOBAL, 'nlonlat',nlonlat )
1384
         ierr = nf90_put_att(ncID, NF90_GLOBAL, 'nlonlat',nlonlat )
1384
      ierr = nf90_put_att(ncID, NF90_GLOBAL, 'dlonlat',dlonlat )
1385
         ierr = nf90_put_att(ncID, NF90_GLOBAL, 'dlonlat',dlonlat )
-
 
1386
      endif
1385
      ierr = nf90_put_att(ncID, NF90_GLOBAL, 'nx',nx )
1387
      ierr = nf90_put_att(ncID, NF90_GLOBAL, 'nx',nx )
1386
      ierr = nf90_put_att(ncID, NF90_GLOBAL, 'ny',ny )
1388
      ierr = nf90_put_att(ncID, NF90_GLOBAL, 'ny',ny )
1387
      ierr = nf90_put_att(ncID, NF90_GLOBAL, 'dx',dx )
1389
      ierr = nf90_put_att(ncID, NF90_GLOBAL, 'dx',dx )
1388
      ierr = nf90_put_att(ncID, NF90_GLOBAL, 'dy',dy )
1390
      ierr = nf90_put_att(ncID, NF90_GLOBAL, 'dy',dy )
1389
      ierr = nf90_put_att(ncID, NF90_GLOBAL, 'xmin',xmin )
1391
      ierr = nf90_put_att(ncID, NF90_GLOBAL, 'xmin',xmin )
1390
      ierr = nf90_put_att(ncID, NF90_GLOBAL, 'ymin',ymin )
1392
      ierr = nf90_put_att(ncID, NF90_GLOBAL, 'ymin',ymin )
1391
 
-
 
1392
c     Write coordinate data 
-
 
1393
      do i = 1,nx+1
-
 
1394
         longitude(i) = xmin + real(i-1) * dx
-
 
1395
      enddo
-
 
1396
      do i = 1,ny+1
-
 
1397
         latitude(i)  = ymin + real(i-1) * dy
-
 
1398
      enddo
-
 
1399
      
1393
      
1400
c     Check whether the definition was successful
1394
c     Check whether the definition was successful
1401
      ierr = nf90_enddef(ncID)
1395
      ierr = nf90_enddef(ncID)
1402
      if (ierr.gt.0) then
1396
      if (ierr.gt.0) then
1403
         print*, 'An error occurred while attempting to ', 
1397
         print*, 'An error occurred while attempting to ', 
1404
     >        'finish definition mode.'
1398
     >        'finish definition mode.'
1405
         stop
1399
         stop
1406
      endif
1400
      endif
1407
      
1401
      
1408
c     Write coordinate data  
1402
c     Write coordinate data  
-
 
1403
      do i = 1,nx
-
 
1404
         longitude(i) = xmin + real(i-1) * dx
-
 
1405
      enddo
-
 
1406
      do i = 1,ny
-
 
1407
         latitude(i)  = ymin + real(i-1) * dy
-
 
1408
      enddo
1409
      ierr = nf90_put_var(ncID,varLonID ,longitude)
1409
      ierr = nf90_put_var(ncID,varLonID ,longitude)
1410
      ierr = nf90_put_var(ncID,varLatID ,latitude )
1410
      ierr = nf90_put_var(ncID,varLatID ,latitude )
1411
      
1411
      
1412
c     Close netCDF file 
1412
c     Close netCDF file 
1413
      ierr = nf90_close(ncID)
1413
      ierr = nf90_close(ncID)
1414
      
1414
      
1415
 100  continue
1415
 100  continue
1416
 
1416
 
1417
c     ---- Define a new variable - skip if <crevar=0> -----------------------
1417
c     ---- Define a new variable - skip if <crevar=0> -----------------------
1418
 
1418
 
1419
      if ( crevar.ne.1 ) goto 110
1419
      if ( crevar.ne.1 ) goto 110
1420
      
1420
      
1421
c     Open the file for read(write access
1421
c     Open the file for read(write access
1422
      ierr = nf90_open  (trim(cdfname), NF90_WRITE  , ncID)
1422
      ierr = nf90_open  (trim(cdfname), NF90_WRITE  , ncID)
1423
 
1423
 
1424
c     Get the IDs for dimensions
1424
c     Get the IDs for dimensions
1425
      ierr = nf90_inq_dimid(ncID,'longitude', LonDimID )
1425
      ierr = nf90_inq_dimid(ncID,'longitude', LonDimID )
1426
      ierr = nf90_inq_dimid(ncID,'latitude' , LatDimID )
1426
      ierr = nf90_inq_dimid(ncID,'latitude' , LatDimID )
1427
      ierr = nf90_inq_dimid(ncID,'time'     , TimeDimID)
1427
      ierr = nf90_inq_dimid(ncID,'time'     , TimeDimID)
1428
 
1428
 
1429
c     Enter define mode
1429
c     Enter define mode
1430
      ierr = nf90_redef(ncID)
1430
      ierr = nf90_redef(ncID)
1431
 
1431
 
1432
c     Write definition and add attributes
1432
c     Write definition and add attributes
1433
      ierr = nf90_def_var(ncID,varname,NF90_FLOAT,
1433
      ierr = nf90_def_var(ncID,varname,NF90_FLOAT,
1434
     >                   (/ LonDimID, LatDimID, TimeDimID /),varID)
1434
     >                   (/ LonDimID, LatDimID, TimeDimID /),varID)
-
 
1435
     
1435
      ierr = nf90_put_att(ncID, varID, "long_name" , longname )
1436
      ierr = nf90_put_att(ncID, varID, "long_name" , longname )
1436
      ierr = nf90_put_att(ncID, varID, "units"     , unit     ) 
1437
      ierr = nf90_put_att(ncID, varID, "units"     , unit     ) 
1437
      ierr = nf90_put_att(ncID, varID, '_FillValue', -999.99  ) 
1438
      ierr = nf90_put_att(ncID, varID, '_FillValue', -999.99  ) 
1438
 
1439
       
1439
c     Check whether definition was successful
1440
c     Check whether definition was successful
1440
      ierr = nf90_enddef(ncID)
1441
      ierr = nf90_enddef(ncID)
1441
      if (ierr.gt.0) then
1442
      if (ierr.gt.0) then
1442
         print*, 'An error occurred while attempting to ', 
1443
         print*, 'An error occurred while attempting to ', 
1443
     >           'finish definition mode.'
1444
     >           'finish definition mode.'
1444
         stop
1445
         stop
1445
      endif
1446
      endif
1446
      print*,trim(varname),' defined on ',trim(cdfname)
1447
      print*,trim(varname),' defined on ',trim(cdfname)
1447
 
1448
 
1448
c     Close netCDF file 
1449
c     Close netCDF file 
1449
      ierr = nf90_close(ncID)
1450
      ierr = nf90_close(ncID)
1450
 
1451
 
1451
 110  continue
1452
 110  continue
1452
 
1453
 
1453
c     ---- Create a new time (unlimited dimension) - skip if <cretime=0> ------
1454
c     ---- Create a new time (unlimited dimension) - skip if <cretime=0> ------
1454
 
1455
 
1455
      if ( cretime.ne.1 ) goto 120
1456
      if ( cretime.ne.1 ) goto 120
1456
 
1457
 
1457
c     Open the file for read/write access
1458
c     Open the file for read/write access
1458
      ierr = nf90_open  (trim(cdfname), NF90_WRITE, ncID)
1459
      ierr = nf90_open  (trim(cdfname), NF90_WRITE, ncID)
1459
      
1460
      
1460
c     Get the list of times on the netCDF file
1461
c     Get the list of times on the netCDF file
1461
      ierr = nf90_inq_dimid(ncID,'time', TimeDimID)
1462
      ierr = nf90_inq_dimid(ncID,'time', TimeDimID)
1462
      if ( ierr.ne.0 ) then
1463
      if ( ierr.ne.0 ) then
1463
         print*,'Time dimension is not defined on ',trim(cdfname),
1464
         print*,'Time dimension is not defined on ',trim(cdfname),
1464
     >          ' .... Stop'
1465
     >          ' .... Stop'
1465
         stop
1466
         stop
1466
      endif
1467
      endif
1467
      ierr = nf90_inquire_dimension(ncID, TimeDimID, len = ntimes)
1468
      ierr = nf90_inquire_dimension(ncID, TimeDimID, len = ntimes)
1468
      ierr = nf90_inq_varid(ncID,'time', varTimeID)
1469
      ierr = nf90_inq_varid(ncID,'time', varTimeID)
1469
      if ( ierr.ne.0 ) then
1470
      if ( ierr.ne.0 ) then
1470
         print*,'Variable time is not defined on ',trim(cdfname),
1471
         print*,'Variable time is not defined on ',trim(cdfname),
1471
     >          ' ... Stop'
1472
     >          ' ... Stop'
1472
         stop
1473
         stop
1473
      endif
1474
      endif
1474
      ierr = nf90_get_var(ncID,varTimeID,timelist(1:ntimes))
1475
      ierr = nf90_get_var(ncID,varTimeID,timelist(1:ntimes))
1475
 
1476
 
1476
c     Decide whether a new time must be written
1477
c     Decide whether a new time must be written
1477
      ind = 0
1478
      ind = 0
1478
      do i=1,ntimes
1479
      do i=1,ntimes
1479
         if ( time.eq.timelist(i) ) ind = i
1480
         if ( time.eq.timelist(i) ) ind = i
1480
      enddo
1481
      enddo
1481
 
1482
 
1482
c     Extend the time list if required 
1483
c     Extend the time list if required 
1483
      if ( ind.eq.0 ) then
1484
      if ( ind.eq.0 ) then
1484
         ntimes           = ntimes + 1
1485
         ntimes           = ntimes + 1
1485
         timelist(ntimes) = time
1486
         timelist(ntimes) = time
1486
         ierr = nf90_put_var(ncID,varTimeID,timelist(1:ntimes))
1487
         ierr = nf90_put_var(ncID,varTimeID,timelist(1:ntimes))
1487
      endif
1488
      endif
1488
 
1489
 
1489
c     Close netCDF file 
1490
c     Close netCDF file 
1490
      ierr = nf90_close(ncID)
1491
      ierr = nf90_close(ncID)
1491
 
1492
 
1492
 120  continue
1493
 120  continue
1493
 
1494
 
1494
c     ---- Write data --------------------------------------------------
1495
c     ---- Write data --------------------------------------------------
1495
 
1496
 
1496
c     Open the file for read/write access
1497
c     Open the file for read/write access
1497
      ierr = nf90_open  (trim(cdfname), NF90_WRITE , ncID)
1498
      ierr = nf90_open  (trim(cdfname), NF90_WRITE , ncID)
1498
 
1499
 
1499
c     Get the varID
1500
c     Get the varID
1500
      ierr = nf90_inq_varid(ncID,varname, varID )
1501
      ierr = nf90_inq_varid(ncID,varname, varID )
1501
      if (ierr.ne.0) then
1502
      if (ierr.ne.0) then
1502
         print*,'Variable ',trim(varname),' is not defined on ',
1503
         print*,'Variable ',trim(varname),' is not defined on ',
1503
     >          trim(cdfname)
1504
     >          trim(cdfname)
1504
         stop
1505
         stop
1505
      endif
1506
      endif
1506
 
1507
 
1507
c     Get the time index
1508
c     Get the time index
1508
      ierr = nf90_inq_dimid(ncID,'time', TimeDimID)
1509
      ierr = nf90_inq_dimid(ncID,'time', TimeDimID)
1509
      if ( ierr.ne.0 ) then
1510
      if ( ierr.ne.0 ) then
1510
         print*,'Time dimension is not defined on ',trim(cdfname),
1511
         print*,'Time dimension is not defined on ',trim(cdfname),
1511
     >          ' .... Stop'
1512
     >          ' .... Stop'
1512
         stop
1513
         stop
1513
      endif
1514
      endif
1514
      ierr = nf90_inquire_dimension(ncID, TimeDimID, len = ntimes)
1515
      ierr = nf90_inquire_dimension(ncID, TimeDimID, len = ntimes)
1515
      ierr = nf90_inq_varid(ncID,'time', varTimeID)
1516
      ierr = nf90_inq_varid(ncID,'time', varTimeID)
1516
      if ( ierr.ne.0 ) then
1517
      if ( ierr.ne.0 ) then
1517
         print*,'Variable time is not defined on ',trim(cdfname),
1518
         print*,'Variable time is not defined on ',trim(cdfname),
1518
     >          ' ... Stop'
1519
     >          ' ... Stop'
1519
         stop
1520
         stop
1520
      endif
1521
      endif
1521
      ierr = nf90_get_var(ncID,varTimeID,timelist(1:ntimes))
1522
      ierr = nf90_get_var(ncID,varTimeID,timelist(1:ntimes))
1522
      ind = 0
1523
      ind = 0
1523
      do i=1,ntimes
1524
      do i=1,ntimes
1524
         if ( time.eq.timelist(i) ) ind = i
1525
         if ( time.eq.timelist(i) ) ind = i
1525
      enddo
1526
      enddo
1526
      if (ind.eq.0) then
1527
      if (ind.eq.0) then
1527
         print*,'Time',time,' is not defined on the netCDF file',
1528
         print*,'Time',time,' is not defined on the netCDF file',
1528
     >          trim(cdfname),' ... Stop'
1529
     >          trim(cdfname),' ... Stop'
1529
         stop
1530
         stop
1530
      endif
1531
      endif
1531
 
1532
 
1532
c     Write data block      
1533
c     Write data block      
1533
      ierr = nf90_put_var(ncID,varID,arr,
1534
      ierr = nf90_put_var(ncID,varID,arr,
1534
     >                    start = (/ 1, 1, ind /), 
1535
     >                    start = (/ 1, 1, ind /), 
1535
     >                    count = (/ nx, ny, 1 /) )
1536
     >                    count = (/ nx, ny, 1 /) )
1536
 
1537
 
1537
c     Check whether writing was successful 
1538
c     Check whether writing was successful 
1538
      ierr = nf90_close(ncID)
1539
      ierr = nf90_close(ncID)
1539
      if (ierr.ne.0) then
1540
      if (ierr.ne.0) then
1540
         write(*,*) trim(nf90_strerror(ierr))
1541
         write(*,*) trim(nf90_strerror(ierr))
1541
         write(*,*) 'An error occurred while attempting to ', 
1542
         write(*,*) 'An error occurred while attempting to ', 
1542
     >              'close the netcdf file.'
1543
     >              'close the netcdf file.'
1543
         write(*,*) 'in clscdf_CF'
1544
         write(*,*) 'in clscdf_CF'
1544
      endif
1545
      endif
1545
 
1546
 
1546
      end
1547
      end
1547
 
1548
 
1548
 
1549
 
1549
c     ********************************************************************************
1550
c     ********************************************************************************
1550
c     * Transformation routine: LMSTOLM and PHSTOPH from library gm2em               *
1551
c     * Transformation routine: LMSTOLM and PHSTOPH from library gm2em               *
1551
c     ********************************************************************************
1552
c     ********************************************************************************
1552
 
1553
 
1553
      REAL FUNCTION LMSTOLM (PHIS, LAMS, POLPHI, POLLAM)
1554
      REAL FUNCTION LMSTOLM (PHIS, LAMS, POLPHI, POLLAM)
1554
C
1555
C
1555
C**** LMSTOLM  -   FC:BERECHNUNG DER WAHREN GEOGRAPHISCHEN LAENGE FUER
1556
C**** LMSTOLM  -   FC:BERECHNUNG DER WAHREN GEOGRAPHISCHEN LAENGE FUER
1556
C****                 EINEN PUNKT MIT DEN KOORDINATEN (PHIS, LAMS)
1557
C****                 EINEN PUNKT MIT DEN KOORDINATEN (PHIS, LAMS)
1557
C****                 IM ROTIERTEN SYSTEM. DER NORDPOL DES SYSTEMS HAT
1558
C****                 IM ROTIERTEN SYSTEM. DER NORDPOL DES SYSTEMS HAT
1558
C****                 DIE WAHREN KOORDINATEN (POLPHI, POLLAM)
1559
C****                 DIE WAHREN KOORDINATEN (POLPHI, POLLAM)
1559
C**   AUFRUF   :   LAM = LMSTOLM (PHIS, LAMS, POLPHI, POLLAM)
1560
C**   AUFRUF   :   LAM = LMSTOLM (PHIS, LAMS, POLPHI, POLLAM)
1560
C**   ENTRIES  :   KEINE
1561
C**   ENTRIES  :   KEINE
1561
C**   ZWECK    :   BERECHNUNG DER WAHREN GEOGRAPHISCHEN LAENGE FUER
1562
C**   ZWECK    :   BERECHNUNG DER WAHREN GEOGRAPHISCHEN LAENGE FUER
1562
C**                EINEN PUNKT MIT DEN KOORDINATEN (PHIS, LAMS)
1563
C**                EINEN PUNKT MIT DEN KOORDINATEN (PHIS, LAMS)
1563
C**                IM ROTIERTEN SYSTEM. DER NORDPOL DIESES SYSTEMS HAT
1564
C**                IM ROTIERTEN SYSTEM. DER NORDPOL DIESES SYSTEMS HAT
1564
C**                DIE WAHREN KOORDINATEN (POLPHI, POLLAM)
1565
C**                DIE WAHREN KOORDINATEN (POLPHI, POLLAM)
1565
C**   VERSIONS-
1566
C**   VERSIONS-
1566
C**   DATUM    :   03.05.90
1567
C**   DATUM    :   03.05.90
1567
C**
1568
C**
1568
C**   EXTERNALS:   KEINE
1569
C**   EXTERNALS:   KEINE
1569
C**   EINGABE-
1570
C**   EINGABE-
1570
C**   PARAMETER:   PHIS     REAL   GEOGR. BREITE DES PUNKTES IM ROT.SYS.
1571
C**   PARAMETER:   PHIS     REAL   GEOGR. BREITE DES PUNKTES IM ROT.SYS.
1571
C**                LAMS     REAL   GEOGR. LAENGE DES PUNKTES IM ROT.SYS.
1572
C**                LAMS     REAL   GEOGR. LAENGE DES PUNKTES IM ROT.SYS.
1572
C**                POLPHI   REAL   WAHRE GEOGR. BREITE DES NORDPOLS
1573
C**                POLPHI   REAL   WAHRE GEOGR. BREITE DES NORDPOLS
1573
C**                POLLAM   REAL   WAHRE GEOGR. LAENGE DES NORDPOLS
1574
C**                POLLAM   REAL   WAHRE GEOGR. LAENGE DES NORDPOLS
1574
C**   AUSGABE-
1575
C**   AUSGABE-
1575
C**   PARAMETER:   WAHRE GEOGRAPHISCHE LAENGE ALS WERT DER FUNKTION
1576
C**   PARAMETER:   WAHRE GEOGRAPHISCHE LAENGE ALS WERT DER FUNKTION
1576
C**                ALLE WINKEL IN GRAD (NORDEN>0, OSTEN>0)
1577
C**                ALLE WINKEL IN GRAD (NORDEN>0, OSTEN>0)
1577
C**
1578
C**
1578
C**   COMMON-
1579
C**   COMMON-
1579
C**   BLOECKE  :   KEINE
1580
C**   BLOECKE  :   KEINE
1580
C**
1581
C**
1581
C**   FEHLERBE-
1582
C**   FEHLERBE-
1582
C**   HANDLUNG :   KEINE
1583
C**   HANDLUNG :   KEINE
1583
C**   VERFASSER:   D.MAJEWSKI
1584
C**   VERFASSER:   D.MAJEWSKI
1584
 
1585
 
1585
      REAL        LAMS,PHIS,POLPHI,POLLAM
1586
      REAL        LAMS,PHIS,POLPHI,POLLAM
1586
 
1587
 
1587
      DATA        ZRPI18 , ZPIR18  / 57.2957795 , 0.0174532925 /
1588
      DATA        ZRPI18 , ZPIR18  / 57.2957795 , 0.0174532925 /
1588
 
1589
 
1589
      ZSINPOL = SIN(ZPIR18*POLPHI)
1590
      ZSINPOL = SIN(ZPIR18*POLPHI)
1590
      ZCOSPOL = COS(ZPIR18*POLPHI)
1591
      ZCOSPOL = COS(ZPIR18*POLPHI)
1591
      ZLAMPOL = ZPIR18*POLLAM
1592
      ZLAMPOL = ZPIR18*POLLAM
1592
      ZPHIS   = ZPIR18*PHIS
1593
      ZPHIS   = ZPIR18*PHIS
1593
      ZLAMS   = LAMS
1594
      ZLAMS   = LAMS
1594
      IF(ZLAMS.GT.180.0) ZLAMS = ZLAMS - 360.0
1595
      IF(ZLAMS.GT.180.0) ZLAMS = ZLAMS - 360.0
1595
      ZLAMS   = ZPIR18*ZLAMS
1596
      ZLAMS   = ZPIR18*ZLAMS
1596
 
1597
 
1597
      ZARG1   = SIN(ZLAMPOL)*(- ZSINPOL*COS(ZLAMS)*COS(ZPHIS)  +
1598
      ZARG1   = SIN(ZLAMPOL)*(- ZSINPOL*COS(ZLAMS)*COS(ZPHIS)  +
1598
     1                          ZCOSPOL*           SIN(ZPHIS)) -
1599
     1                          ZCOSPOL*           SIN(ZPHIS)) -
1599
     2          COS(ZLAMPOL)*           SIN(ZLAMS)*COS(ZPHIS)
1600
     2          COS(ZLAMPOL)*           SIN(ZLAMS)*COS(ZPHIS)
1600
      ZARG2   = COS(ZLAMPOL)*(- ZSINPOL*COS(ZLAMS)*COS(ZPHIS)  +
1601
      ZARG2   = COS(ZLAMPOL)*(- ZSINPOL*COS(ZLAMS)*COS(ZPHIS)  +
1601
     1                          ZCOSPOL*           SIN(ZPHIS)) +
1602
     1                          ZCOSPOL*           SIN(ZPHIS)) +
1602
     2          SIN(ZLAMPOL)*           SIN(ZLAMS)*COS(ZPHIS)
1603
     2          SIN(ZLAMPOL)*           SIN(ZLAMS)*COS(ZPHIS)
1603
      IF (ABS(ZARG2).LT.1.E-30) THEN
1604
      IF (ABS(ZARG2).LT.1.E-30) THEN
1604
        IF (ABS(ZARG1).LT.1.E-30) THEN
1605
        IF (ABS(ZARG1).LT.1.E-30) THEN
1605
          LMSTOLM =   0.0
1606
          LMSTOLM =   0.0
1606
        ELSEIF (ZARG1.GT.0.) THEN
1607
        ELSEIF (ZARG1.GT.0.) THEN
1607
              LMSTOLAM =  90.0
1608
              LMSTOLAM =  90.0
1608
            ELSE
1609
            ELSE
1609
              LMSTOLAM = -90.0
1610
              LMSTOLAM = -90.0
1610
            ENDIF
1611
            ENDIF
1611
      ELSE
1612
      ELSE
1612
        LMSTOLM = ZRPI18*ATAN2(ZARG1,ZARG2)
1613
        LMSTOLM = ZRPI18*ATAN2(ZARG1,ZARG2)
1613
      ENDIF
1614
      ENDIF
1614
 
1615
 
1615
      RETURN
1616
      RETURN
1616
      END
1617
      END
1617
 
1618
 
1618
 
1619
 
1619
      REAL FUNCTION PHSTOPH (PHIS, LAMS, POLPHI, POLLAM)
1620
      REAL FUNCTION PHSTOPH (PHIS, LAMS, POLPHI, POLLAM)
1620
C
1621
C
1621
C**** PHSTOPH  -   FC:BERECHNUNG DER WAHREN GEOGRAPHISCHEN BREITE FUER
1622
C**** PHSTOPH  -   FC:BERECHNUNG DER WAHREN GEOGRAPHISCHEN BREITE FUER
1622
C****                 EINEN PUNKT MIT DEN KOORDINATEN (PHIS, LAMS) IM
1623
C****                 EINEN PUNKT MIT DEN KOORDINATEN (PHIS, LAMS) IM
1623
C****                 ROTIERTEN SYSTEM. DER NORDPOL DIESES SYSTEMS HAT
1624
C****                 ROTIERTEN SYSTEM. DER NORDPOL DIESES SYSTEMS HAT
1624
C****                 DIE WAHREN KOORDINATEN (POLPHI, POLLAM)
1625
C****                 DIE WAHREN KOORDINATEN (POLPHI, POLLAM)
1625
C**   AUFRUF   :   PHI = PHSTOPH (PHIS, LAMS, POLPHI, POLLAM)
1626
C**   AUFRUF   :   PHI = PHSTOPH (PHIS, LAMS, POLPHI, POLLAM)
1626
C**   ENTRIES  :   KEINE
1627
C**   ENTRIES  :   KEINE
1627
C**   ZWECK    :   BERECHNUNG DER WAHREN GEOGRAPHISCHEN BREITE FUER
1628
C**   ZWECK    :   BERECHNUNG DER WAHREN GEOGRAPHISCHEN BREITE FUER
1628
C**                EINEN PUNKT MIT DEN KOORDINATEN (PHIS, LAMS) IM
1629
C**                EINEN PUNKT MIT DEN KOORDINATEN (PHIS, LAMS) IM
1629
C**                ROTIERTEN SYSTEM. DER NORDPOL DIESES SYSTEMS HAT
1630
C**                ROTIERTEN SYSTEM. DER NORDPOL DIESES SYSTEMS HAT
1630
C**                DIE WAHREN KOORDINATEN (POLPHI, POLLAM)
1631
C**                DIE WAHREN KOORDINATEN (POLPHI, POLLAM)
1631
C**   VERSIONS-
1632
C**   VERSIONS-
1632
C**   DATUM    :   03.05.90
1633
C**   DATUM    :   03.05.90
1633
C**
1634
C**
1634
C**   EXTERNALS:   KEINE
1635
C**   EXTERNALS:   KEINE
1635
C**   EINGABE-
1636
C**   EINGABE-
1636
C**   PARAMETER:   PHIS     REAL   GEOGR. BREITE DES PUNKTES IM ROT.SYS.
1637
C**   PARAMETER:   PHIS     REAL   GEOGR. BREITE DES PUNKTES IM ROT.SYS.
1637
C**                LAMS     REAL   GEOGR. LAENGE DES PUNKTES IM ROT.SYS.
1638
C**                LAMS     REAL   GEOGR. LAENGE DES PUNKTES IM ROT.SYS.
1638
C**                POLPHI   REAL   WAHRE GEOGR. BREITE DES NORDPOLS
1639
C**                POLPHI   REAL   WAHRE GEOGR. BREITE DES NORDPOLS
1639
C**                POLLAM   REAL   WAHRE GEOGR. LAENGE DES NORDPOLS
1640
C**                POLLAM   REAL   WAHRE GEOGR. LAENGE DES NORDPOLS
1640
C**   AUSGABE-
1641
C**   AUSGABE-
1641
C**   PARAMETER:   WAHRE GEOGRAPHISCHE BREITE ALS WERT DER FUNKTION
1642
C**   PARAMETER:   WAHRE GEOGRAPHISCHE BREITE ALS WERT DER FUNKTION
1642
C**                ALLE WINKEL IN GRAD (NORDEN>0, OSTEN>0)
1643
C**                ALLE WINKEL IN GRAD (NORDEN>0, OSTEN>0)
1643
C**
1644
C**
1644
C**   COMMON-
1645
C**   COMMON-
1645
C**   BLOECKE  :   KEINE
1646
C**   BLOECKE  :   KEINE
1646
C**
1647
C**
1647
C**   FEHLERBE-
1648
C**   FEHLERBE-
1648
C**   HANDLUNG :   KEINE
1649
C**   HANDLUNG :   KEINE
1649
C**   VERFASSER:   D.MAJEWSKI
1650
C**   VERFASSER:   D.MAJEWSKI
1650
 
1651
 
1651
      REAL        LAMS,PHIS,POLPHI,POLLAM
1652
      REAL        LAMS,PHIS,POLPHI,POLLAM
1652
 
1653
 
1653
      DATA        ZRPI18 , ZPIR18  / 57.2957795 , 0.0174532925 /
1654
      DATA        ZRPI18 , ZPIR18  / 57.2957795 , 0.0174532925 /
1654
 
1655
 
1655
      SINPOL = SIN(ZPIR18*POLPHI)
1656
      SINPOL = SIN(ZPIR18*POLPHI)
1656
      COSPOL = COS(ZPIR18*POLPHI)
1657
      COSPOL = COS(ZPIR18*POLPHI)
1657
      ZPHIS  = ZPIR18*PHIS
1658
      ZPHIS  = ZPIR18*PHIS
1658
      ZLAMS  = LAMS
1659
      ZLAMS  = LAMS
1659
      IF(ZLAMS.GT.180.0) ZLAMS = ZLAMS - 360.0
1660
      IF(ZLAMS.GT.180.0) ZLAMS = ZLAMS - 360.0
1660
      ZLAMS  = ZPIR18*ZLAMS
1661
      ZLAMS  = ZPIR18*ZLAMS
1661
      ARG     = COSPOL*COS(ZPHIS)*COS(ZLAMS) + SINPOL*SIN(ZPHIS)
1662
      ARG     = COSPOL*COS(ZPHIS)*COS(ZLAMS) + SINPOL*SIN(ZPHIS)
1662
 
1663
 
1663
      PHSTOPH = ZRPI18*ASIN(ARG)
1664
      PHSTOPH = ZRPI18*ASIN(ARG)
1664
 
1665
 
1665
      RETURN
1666
      RETURN
1666
      END
1667
      END
1667
 
1668
 
1668
 
1669
 
1669
      REAL FUNCTION LMTOLMS (PHI, LAM, POLPHI, POLLAM)
1670
      REAL FUNCTION LMTOLMS (PHI, LAM, POLPHI, POLLAM)
1670
C
1671
C
1671
C%Z% Modul %M%, V%I% vom %G%, extrahiert am %H%
1672
C%Z% Modul %M%, V%I% vom %G%, extrahiert am %H%
1672
C
1673
C
1673
C**** LMTOLMS  -   FC:UMRECHNUNG DER WAHREN GEOGRAPHISCHEN LAENGE LAM
1674
C**** LMTOLMS  -   FC:UMRECHNUNG DER WAHREN GEOGRAPHISCHEN LAENGE LAM
1674
C****                 AUF EINEM PUNKT MIT DEN KOORDINATEN (PHIS, LAMS)
1675
C****                 AUF EINEM PUNKT MIT DEN KOORDINATEN (PHIS, LAMS)
1675
C****                 IM ROTIERTEN SYSTEM. DER NORDPOL DES SYSTEMS HAT
1676
C****                 IM ROTIERTEN SYSTEM. DER NORDPOL DES SYSTEMS HAT
1676
C****                 DIE WAHREN KOORDINATEN (POLPHI, POLLAM)
1677
C****                 DIE WAHREN KOORDINATEN (POLPHI, POLLAM)
1677
C**   AUFRUF   :   LAM = LMTOLMS (PHI, LAM, POLPHI, POLLAM)
1678
C**   AUFRUF   :   LAM = LMTOLMS (PHI, LAM, POLPHI, POLLAM)
1678
C**   ENTRIES  :   KEINE
1679
C**   ENTRIES  :   KEINE
1679
C**   ZWECK    :   UMRECHNUNG DER WAHREN GEOGRAPHISCHEN LAENGE LAM AUF
1680
C**   ZWECK    :   UMRECHNUNG DER WAHREN GEOGRAPHISCHEN LAENGE LAM AUF
1680
C**                EINEM PUNKT MIT DEN KOORDINATEN (PHIS, LAMS) IM
1681
C**                EINEM PUNKT MIT DEN KOORDINATEN (PHIS, LAMS) IM
1681
C**                ROTIERTEN SYSTEM. DER NORDPOL DIESES SYSTEMS HAT
1682
C**                ROTIERTEN SYSTEM. DER NORDPOL DIESES SYSTEMS HAT
1682
C**                DIE WAHREN KOORDINATEN (POLPHI, POLLAM)
1683
C**                DIE WAHREN KOORDINATEN (POLPHI, POLLAM)
1683
C**   VERSIONS-
1684
C**   VERSIONS-
1684
C**   DATUM    :   03.05.90
1685
C**   DATUM    :   03.05.90
1685
C**
1686
C**
1686
C**   EXTERNALS:   KEINE
1687
C**   EXTERNALS:   KEINE
1687
C**   EINGABE-
1688
C**   EINGABE-
1688
C**   PARAMETER:   PHI    REAL BREITE DES PUNKTES IM GEOGR. SYSTEM
1689
C**   PARAMETER:   PHI    REAL BREITE DES PUNKTES IM GEOGR. SYSTEM
1689
C**                LAM    REAL LAENGE DES PUNKTES IM GEOGR. SYSTEM
1690
C**                LAM    REAL LAENGE DES PUNKTES IM GEOGR. SYSTEM
1690
C**                POLPHI REAL GEOGR.BREITE DES N-POLS DES ROT. SYSTEMS
1691
C**                POLPHI REAL GEOGR.BREITE DES N-POLS DES ROT. SYSTEMS
1691
C**                POLLAM REAL GEOGR.LAENGE DES N-POLS DES ROT. SYSTEMS
1692
C**                POLLAM REAL GEOGR.LAENGE DES N-POLS DES ROT. SYSTEMS
1692
C**   AUSGABE-
1693
C**   AUSGABE-
1693
C**   PARAMETER:   WAHRE GEOGRAPHISCHE LAENGE ALS WERT DER FUNKTION
1694
C**   PARAMETER:   WAHRE GEOGRAPHISCHE LAENGE ALS WERT DER FUNKTION
1694
C**                ALLE WINKEL IN GRAD (NORDEN>0, OSTEN>0)
1695
C**                ALLE WINKEL IN GRAD (NORDEN>0, OSTEN>0)
1695
C**
1696
C**
1696
C**   COMMON-
1697
C**   COMMON-
1697
C**   BLOECKE  :   KEINE
1698
C**   BLOECKE  :   KEINE
1698
C**
1699
C**
1699
C**   FEHLERBE-
1700
C**   FEHLERBE-
1700
C**   HANDLUNG :   KEINE
1701
C**   HANDLUNG :   KEINE
1701
C**   VERFASSER:   G. DE MORSIER
1702
C**   VERFASSER:   G. DE MORSIER
1702
 
1703
 
1703
      REAL        LAM,PHI,POLPHI,POLLAM
1704
      REAL        LAM,PHI,POLPHI,POLLAM
1704
 
1705
 
1705
      DATA        ZRPI18 , ZPIR18  / 57.2957795 , 0.0174532925 /
1706
      DATA        ZRPI18 , ZPIR18  / 57.2957795 , 0.0174532925 /
1706
 
1707
 
1707
      ZSINPOL = SIN(ZPIR18*POLPHI)
1708
      ZSINPOL = SIN(ZPIR18*POLPHI)
1708
      ZCOSPOL = COS(ZPIR18*POLPHI)
1709
      ZCOSPOL = COS(ZPIR18*POLPHI)
1709
      ZLAMPOL =     ZPIR18*POLLAM
1710
      ZLAMPOL =     ZPIR18*POLLAM
1710
      ZPHI    =     ZPIR18*PHI
1711
      ZPHI    =     ZPIR18*PHI
1711
      ZLAM    = LAM
1712
      ZLAM    = LAM
1712
      IF(ZLAM.GT.180.0) ZLAM = ZLAM - 360.0
1713
      IF(ZLAM.GT.180.0) ZLAM = ZLAM - 360.0
1713
      ZLAM    = ZPIR18*ZLAM
1714
      ZLAM    = ZPIR18*ZLAM
1714
 
1715
 
1715
      ZARG1   = - SIN(ZLAM-ZLAMPOL)*COS(ZPHI)
1716
      ZARG1   = - SIN(ZLAM-ZLAMPOL)*COS(ZPHI)
1716
      ZARG2   = - ZSINPOL*COS(ZPHI)*COS(ZLAM-ZLAMPOL)+ZCOSPOL*SIN(ZPHI)
1717
      ZARG2   = - ZSINPOL*COS(ZPHI)*COS(ZLAM-ZLAMPOL)+ZCOSPOL*SIN(ZPHI)
1717
      IF (ABS(ZARG2).LT.1.E-30) THEN
1718
      IF (ABS(ZARG2).LT.1.E-30) THEN
1718
        IF (ABS(ZARG1).LT.1.E-30) THEN
1719
        IF (ABS(ZARG1).LT.1.E-30) THEN
1719
          LMTOLMS =   0.0
1720
          LMTOLMS =   0.0
1720
        ELSEIF (ZARG1.GT.0.) THEN
1721
        ELSEIF (ZARG1.GT.0.) THEN
1721
              LMTOLMS =  90.0
1722
              LMTOLMS =  90.0
1722
            ELSE
1723
            ELSE
1723
              LMTOLMS = -90.0
1724
              LMTOLMS = -90.0
1724
            ENDIF
1725
            ENDIF
1725
      ELSE
1726
      ELSE
1726
        LMTOLMS = ZRPI18*ATAN2(ZARG1,ZARG2)
1727
        LMTOLMS = ZRPI18*ATAN2(ZARG1,ZARG2)
1727
      ENDIF
1728
      ENDIF
1728
 
1729
 
1729
      RETURN
1730
      RETURN
1730
      END
1731
      END
1731
 
1732
 
1732
 
1733
 
1733
      REAL FUNCTION PHTOPHS (PHI, LAM, POLPHI, POLLAM)
1734
      REAL FUNCTION PHTOPHS (PHI, LAM, POLPHI, POLLAM)
1734
C
1735
C
1735
C%Z% Modul %M%, V%I% vom %G%, extrahiert am %H%
1736
C%Z% Modul %M%, V%I% vom %G%, extrahiert am %H%
1736
C
1737
C
1737
C**** PHTOPHS  -   FC:UMRECHNUNG DER WAHREN GEOGRAPHISCHEN BREITE PHI
1738
C**** PHTOPHS  -   FC:UMRECHNUNG DER WAHREN GEOGRAPHISCHEN BREITE PHI
1738
C****                 AUF EINEM PUNKT MIT DEN KOORDINATEN (PHIS, LAMS)
1739
C****                 AUF EINEM PUNKT MIT DEN KOORDINATEN (PHIS, LAMS)
1739
C****                 IM ROTIERTEN SYSTEM. DER NORDPOL DES SYSTEMS HAT
1740
C****                 IM ROTIERTEN SYSTEM. DER NORDPOL DES SYSTEMS HAT
1740
C****                 DIE WAHREN KOORDINATEN (POLPHI, POLLAM)
1741
C****                 DIE WAHREN KOORDINATEN (POLPHI, POLLAM)
1741
C**   AUFRUF   :   PHI = PHTOPHS (PHI, LAM, POLPHI, POLLAM)
1742
C**   AUFRUF   :   PHI = PHTOPHS (PHI, LAM, POLPHI, POLLAM)
1742
C**   ENTRIES  :   KEINE
1743
C**   ENTRIES  :   KEINE
1743
C**   ZWECK    :   UMRECHNUNG DER WAHREN GEOGRAPHISCHEN BREITE PHI AUF
1744
C**   ZWECK    :   UMRECHNUNG DER WAHREN GEOGRAPHISCHEN BREITE PHI AUF
1744
C**                EINEM PUNKT MIT DEN KOORDINATEN (PHIS, LAMS) IM
1745
C**                EINEM PUNKT MIT DEN KOORDINATEN (PHIS, LAMS) IM
1745
C**                ROTIERTEN SYSTEM. DER NORDPOL DIESES SYSTEMS HAT
1746
C**                ROTIERTEN SYSTEM. DER NORDPOL DIESES SYSTEMS HAT
1746
C**                DIE WAHREN KOORDINATEN (POLPHI, POLLAM)
1747
C**                DIE WAHREN KOORDINATEN (POLPHI, POLLAM)
1747
C**   VERSIONS-
1748
C**   VERSIONS-
1748
C**   DATUM    :   03.05.90
1749
C**   DATUM    :   03.05.90
1749
C**
1750
C**
1750
C**   EXTERNALS:   KEINE
1751
C**   EXTERNALS:   KEINE
1751
C**   EINGABE-
1752
C**   EINGABE-
1752
C**   PARAMETER:   PHI    REAL BREITE DES PUNKTES IM GEOGR. SYSTEM
1753
C**   PARAMETER:   PHI    REAL BREITE DES PUNKTES IM GEOGR. SYSTEM
1753
C**                LAM    REAL LAENGE DES PUNKTES IM GEOGR. SYSTEM
1754
C**                LAM    REAL LAENGE DES PUNKTES IM GEOGR. SYSTEM
1754
C**                POLPHI REAL GEOGR.BREITE DES N-POLS DES ROT. SYSTEMS
1755
C**                POLPHI REAL GEOGR.BREITE DES N-POLS DES ROT. SYSTEMS
1755
C**                POLLAM REAL GEOGR.LAENGE DES N-POLS DES ROT. SYSTEMS
1756
C**                POLLAM REAL GEOGR.LAENGE DES N-POLS DES ROT. SYSTEMS
1756
C**   AUSGABE-
1757
C**   AUSGABE-
1757
C**   PARAMETER:   ROTIERTE BREITE PHIS ALS WERT DER FUNKTION
1758
C**   PARAMETER:   ROTIERTE BREITE PHIS ALS WERT DER FUNKTION
1758
C**                ALLE WINKEL IN GRAD (NORDEN>0, OSTEN>0)
1759
C**                ALLE WINKEL IN GRAD (NORDEN>0, OSTEN>0)
1759
C**
1760
C**
1760
C**   COMMON-
1761
C**   COMMON-
1761
C**   BLOECKE  :   KEINE
1762
C**   BLOECKE  :   KEINE
1762
C**
1763
C**
1763
C**   FEHLERBE-
1764
C**   FEHLERBE-
1764
C**   HANDLUNG :   KEINE
1765
C**   HANDLUNG :   KEINE
1765
C**   VERFASSER:   G. DE MORSIER
1766
C**   VERFASSER:   G. DE MORSIER
1766
 
1767
 
1767
      REAL        LAM,PHI,POLPHI,POLLAM
1768
      REAL        LAM,PHI,POLPHI,POLLAM
1768
 
1769
 
1769
      DATA        ZRPI18 , ZPIR18  / 57.2957795 , 0.0174532925 /
1770
      DATA        ZRPI18 , ZPIR18  / 57.2957795 , 0.0174532925 /
1770
 
1771
 
1771
      ZSINPOL = SIN(ZPIR18*POLPHI)
1772
      ZSINPOL = SIN(ZPIR18*POLPHI)
1772
      ZCOSPOL = COS(ZPIR18*POLPHI)
1773
      ZCOSPOL = COS(ZPIR18*POLPHI)
1773
      ZLAMPOL = ZPIR18*POLLAM
1774
      ZLAMPOL = ZPIR18*POLLAM
1774
      ZPHI    = ZPIR18*PHI
1775
      ZPHI    = ZPIR18*PHI
1775
      ZLAM    = LAM
1776
      ZLAM    = LAM
1776
      IF(ZLAM.GT.180.0) ZLAM = ZLAM - 360.0
1777
      IF(ZLAM.GT.180.0) ZLAM = ZLAM - 360.0
1777
      ZLAM    = ZPIR18*ZLAM
1778
      ZLAM    = ZPIR18*ZLAM
1778
      ZARG    = ZCOSPOL*COS(ZPHI)*COS(ZLAM-ZLAMPOL) + ZSINPOL*SIN(ZPHI)
1779
      ZARG    = ZCOSPOL*COS(ZPHI)*COS(ZLAM-ZLAMPOL) + ZSINPOL*SIN(ZPHI)
1779
 
1780
 
1780
      PHTOPHS = ZRPI18*ASIN(ZARG)
1781
      PHTOPHS = ZRPI18*ASIN(ZARG)
1781
 
1782
 
1782
      RETURN
1783
      RETURN
1783
      END
1784
      END
1784
 
1785
 
1785
c     ------------------------------------------------------------------
1786
c     ------------------------------------------------------------------
1786
c     Compute Cos/Sin of an argument in Degree instead of Radian
1787
c     Compute Cos/Sin of an argument in Degree instead of Radian
1787
c     ------------------------------------------------------------------
1788
c     ------------------------------------------------------------------
1788
 
1789
 
1789
      real function cosd(arg)
1790
      real function cosd(arg)
1790
 
1791
 
1791
      real,intent(IN) :: arg
1792
      real,intent(IN) :: arg
1792
      real,parameter :: grad2rad=3.1415926/180.
1793
      real,parameter :: grad2rad=3.1415926/180.
1793
      cosd=cos(arg*grad2rad)
1794
      cosd=cos(arg*grad2rad)
1794
      return
1795
      return
1795
      end
1796
      end
1796
 
1797
 
1797
      real function sind(arg)
1798
      real function sind(arg)
1798
 
1799
 
1799
      real,intent(IN) :: arg
1800
      real,intent(IN) :: arg
1800
      real,parameter :: grad2rad=3.1415926/180.
1801
      real,parameter :: grad2rad=3.1415926/180.
1801
      sind=sin(arg*grad2rad)
1802
      sind=sin(arg*grad2rad)
1802
      return
1803
      return
1803
      end
1804
      end
1804
 
1805
 
1805
 
1806