File: newisl.F

package info (click to toggle)
emoslib 2%3A4.4.5-2
  • links: PTS
  • area: main
  • in suites: stretch
  • size: 359,232 kB
  • ctags: 13,125
  • sloc: fortran: 93,166; ansic: 27,958; sh: 7,500; f90: 5,209; perl: 604; cpp: 305; makefile: 78; python: 53
file content (304 lines) | stat: -rw-r--r-- 8,335 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
C Copyright 1981-2016 ECMWF.
C
C This software is licensed under the terms of the Apache Licence 
C Version 2.0 which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
C
C In applying this licence, ECMWF does not waive the privileges and immunities 
C granted to it by virtue of its status as an intergovernmental organisation 
C nor does it submit to any jurisdiction.
C

      INTEGER FUNCTION NEWISL(OLDGEO,NEWGEO,OLDLSM,OLDFLD,MASTER,NEWFLD)
C
C---->
C**** NEWISL
C
C     Purpose
C     -------
C
C     Interpolate a field based on an old land-sea mask to a field
C     based on a different land-sea mask.
C
C
C     Interface
C     ---------
C
C     IRET = NEWISL(OLDGEO,NEWGEO,OLDLSM,OLDFLD,MASTER,NEWFLD)
C
C     Input
C     -----
C
C     OLDGEO - GRIB section 2 describing grid of old field.
C     NEWGEO - GRIB section 2 describing grid of new field.
C     OLDLSM - Array of land-sea mask values for old field.
C     OLDFLD - Array of values for old field.
C     MASTER - Array of land-sea mask values for new field.
C
C
C     Output
C     ------
C
C     NEWFLD - Array of values for new field.
C
C     Function returns:
C       - 0 if all is well
C       - 1, otherwise.
C
C
C     Method
C     ------
C
C     Build up field offsets from input geometries.
C     For each point of the new field, find in the old field the four
C     nearest neighbours' positions, values and types.
C     Calculate new value from the neighbours.
C
C
C     Externals
C     ---------
C
C     IGGLAT  - Compute gaussian lines of latitude.
C     JNORSGG - Find gaussian latitudes to north and south of latitude.
C     ISLPROC - Calculate value of new field point.
C     INTLOG  - Log messages
C
C
C     Author
C     ------
C
C     J.D.Chambers     ECMWF     August 2000
C
C----<
C
      IMPLICIT NONE
C
C     Function arguments
C
      INTEGER OLDGEO(*),NEWGEO(*)
      REAL OLDLSM(*),OLDFLD(*),MASTER(*),NEWFLD(*)
C
#include "intisl.h"
#include "parim.h"
C
C     Parameters
C
      INTEGER JPMAXLT, JPGAUSS, JP1000
      PARAMETER (JPMAXLT=721)
      PARAMETER (JPGAUSS=4)
      PARAMETER (JP1000=1000)
C
C     Local variables
C
      INTEGER TOTAL, NEXT, LOOP, NEWOFF(JPMAXLT), OLDOFF(JPMAXLT)
      INTEGER LATIT, LONG, NEWTYPE, IRET, NPTS
      INTEGER LAT(2), LON(4)
      INTEGER PT(4), TYPE(4)
      REAL OLAT(2), OLON(4)
      REAL RLATOLD(JPMAXLT), RLATNEW(JPMAXLT), RLAT, RLON
C
C     Externals
C
      INTEGER IGGLAT, JNORSGG
      REAL ISLPROC
      EXTERNAL IGGLAT, JNORSGG, ISLPROC
C
C     -----------------------------------------------------------------|
C*    Section 1.   Build working values using input geometries.
C     -----------------------------------------------------------------|
C
  100 CONTINUE
C
      NEWISL = 0
C
C     -----------------------------------------------------------------|
C*    Section 2.   Calculate number of points in new field and offset
C                  to start of each latitude in the new grid
C     -----------------------------------------------------------------|
C
  200 CONTINUE
C
      IF( NEWGEO(1).EQ.JPGAUSS ) THEN
C
C       New field is gaussian
C
        CALL INTLOG(JP_DEBUG,'NEWISL: New field is gaussian',JPQUIET)
C
        IF( NEWGEO(17).EQ.0 ) THEN
          CALL INTLOG(JP_DEBUG,'NEWISL: New field is regular',JPQUIET)
          TOTAL = NEWGEO(2)*NEWGEO(3)
          NEWOFF(1) = 0
          DO LOOP = 2, NEWGEO(NJ)
            NEWOFF(LOOP) = NEWOFF(LOOP-1) + NEWGEO(2)
          ENDDO
        ELSE
          CALL INTLOG(JP_DEBUG,'NEWISL: New field is reduced',JPQUIET)
          NEWOFF(1) = 0
          TOTAL = NEWGEO(NPOINTS)
          DO LOOP = 2, NEWGEO(NJ)
            NEWOFF(LOOP) = NEWOFF(LOOP-1) + NEWGEO(NPOINTS-2+LOOP)
            TOTAL = TOTAL + NEWGEO(NPOINTS-1+LOOP)
          ENDDO
        ENDIF
C
C       Get the gaussian latitudes for the new field
C
        IRET = IGGLAT(NEWGEO(NGAUSS)*2,RLATNEW,0,-1)
        IF( IRET.NE.0 ) THEN
          WRITE(*,*) 'NEWISL: Problem call igglat for new grid'
          NEWISL = 1
          RETURN
        ENDIF
C
      ELSE
C
C       New field is lat/long
C
        CALL INTLOG(JP_DEBUG,'NEWISL: New field is lat/long',JPQUIET)
        TOTAL = NEWGEO(2)*NEWGEO(3)
        DO LOOP = 1, NEWGEO(3)
          NEWOFF(LOOP) = NEWGEO(2)*(LOOP-1)
          RLATNEW(LOOP) = 90.0 - (REAL((LOOP-1)*NEWGEO(10))/JP1000)
        ENDDO
C
      ENDIF
C
      CALL INTLOG(JP_DEBUG,'NEWISL: No. of pts in new field = ',TOTAL)
C
C     -----------------------------------------------------------------|
C*    Section 3.   Get the gaussian latitudes for the old field and
C                  setup the offsets to the start of each latitude.
C     -----------------------------------------------------------------|
C
  300 CONTINUE
C
      OLDOFF(1) = 0
      DO LOOP = 2, OLDGEO(NJ)
        OLDOFF(LOOP) = OLDOFF(LOOP-1) + OLDGEO(NPOINTS-2+LOOP)
      ENDDO
C
      IRET = IGGLAT(OLDGEO(NGAUSS)*2,RLATOLD,0,-1)
      IF( IRET.NE.0 ) THEN
        WRITE(*,*) 'NEWISL: Problem call igglat for old grid'
        NEWISL = 1
        RETURN
      ENDIF
C
C     -----------------------------------------------------------------|
C*    Section 4.   Work through the points in the new field.
C     -----------------------------------------------------------------|
C
  400 CONTINUE
C
      DO NEXT = 1, TOTAL
C
C       Calculate lat/long
C
        DO LOOP = 1, NEWGEO(NJ)
          IF( NEWOFF(LOOP).GE.NEXT ) THEN
            LATIT = LOOP - 1
            GOTO 410
          ENDIF
        ENDDO
        LATIT = NEWGEO(NJ)
C
  410   CONTINUE
C
        LONG = NEXT - NEWOFF(LATIT)
C
        RLAT = RLATNEW(LATIT)
        IF( NEWGEO(1).EQ.JPGAUSS ) THEN
          IF( NEWGEO(17).EQ.0 ) THEN
            RLON = REAL((LONG-1)*NEWGEO(9))/JP1000
          ELSE
            RLON = (REAL(LONG-1)*360.0)/REAL(NEWGEO(NPOINTS+LATIT-1))
          ENDIF
        ELSE
          RLON = REAL((LONG-1)*NEWGEO(9))/JP1000
        ENDIF
C
C       Find type of point (land or sea)
C
        IF( MASTER(NEXT).GT.MASTERTHRESHOLD ) THEN
          NEWTYPE = LAND
        ELSE
          NEWTYPE = SEA
        ENDIF
C
C       Find four neighbours in the old field with their types
C       (Find NW neighbour and deduce the others).
C
        LAT(NORTH) = JNORSGG(RLAT,RLATOLD,OLDGEO(NGAUSS),1)
        LAT(SOUTH) = JNORSGG(RLAT,RLATOLD,OLDGEO(NGAUSS),0)
C
        OLAT(NORTH) = RLATOLD(LAT(NORTH))
        OLAT(SOUTH) = RLATOLD(LAT(SOUTH))
C
        NPTS = OLDGEO(NPOINTS-1+LAT(NORTH))
        LON(NWEST) = 1 + INT(RLON/(360.0/REAL(NPTS)))
        LON(NEAST) = LON(NWEST) + 1
        IF( LON(NEAST).GT.NPTS ) LON(NEAST) = 1
C
        OLON(NWEST) = (REAL(LON(NWEST)-1)*360.0)/REAL(NPTS)
        IF( LON(NEAST).EQ.1 ) THEN
          OLON(NEAST) = 360.0
        ELSE
          OLON(NEAST) = (REAL(LON(NEAST)-1)*360.0)/REAL(NPTS)
        ENDIF
C
        NPTS = OLDGEO(NPOINTS-1+LAT(SOUTH))
        LON(SWEST) = 1 + INT(RLON/(360.0/REAL(NPTS)))
        LON(SEAST) = LON(SWEST) + 1
        IF( LON(SEAST).GT.NPTS ) LON(SEAST) = 1
C
        OLON(SWEST) = (REAL(LON(SWEST)-1)*360.0)/REAL(NPTS)
        IF( LON(SEAST).EQ.1 ) THEN
          OLON(SEAST) = 360.0
        ELSE
          OLON(SEAST) = (REAL(LON(SEAST)-1)*360.0)/REAL(NPTS)
        ENDIF
C
        PT(NWEST) = OLDOFF(LAT(NORTH)) + LON(NWEST)
        IF( OLDLSM(PT(NWEST)).GT.OLDLSMTHRESHOLD ) THEN
          TYPE(NWEST) = LAND
        ELSE
          TYPE(NWEST) = SEA
        ENDIF
C
        PT(NEAST) = OLDOFF(LAT(NORTH)) + LON(NEAST)
        IF( OLDLSM(PT(NEAST)).GT.OLDLSMTHRESHOLD ) THEN
          TYPE(NEAST) = LAND
        ELSE
          TYPE(NEAST) = SEA
        ENDIF
C
        PT(SWEST) = OLDOFF(LAT(SOUTH)) + LON(SWEST)
        IF( OLDLSM(PT(SWEST)).GT.OLDLSMTHRESHOLD ) THEN
          TYPE(SWEST) = LAND
        ELSE
          TYPE(SWEST) = SEA
        ENDIF
C
        PT(SEAST) = OLDOFF(LAT(SOUTH)) + LON(SEAST)
        IF( OLDLSM(PT(SEAST)).GT.OLDLSMTHRESHOLD ) THEN
          TYPE(SEAST) = LAND
        ELSE
          TYPE(SEAST) = SEA
        ENDIF
C
C       Interpolate the new value
C
        NEWFLD(NEXT) =
     X    ISLPROC(RLAT,RLON,NEWTYPE,OLAT,OLON,TYPE,PT,OLDFLD)
C
      ENDDO
C
C     -----------------------------------------------------------------|
C*    Section 9.   Return
C     -----------------------------------------------------------------|
C
  900 CONTINUE
C
C
      RETURN
      END