1C Copyright 1981-2016 ECMWF.
2C
3C This software is licensed under the terms of the Apache Licence
4C Version 2.0 which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
5C
6C In applying this licence, ECMWF does not waive the privileges and immunities
7C granted to it by virtue of its status as an intergovernmental organisation
8C nor does it submit to any jurisdiction.
9C
10
11      INTEGER FUNCTION IGLSIZE(KSTRIDE, KAREA, KNWE, KNNS, KLN,
12     1   OWEGLOBE, ONPOLE, OSPOLE, KPR, KERR)
13C
14C---->
15C**** *IGLSIZE*
16C
17C     PURPOSE
18C     _______
19C
20C     Evaluate the array sizes for a regular latitude/longitude grid
21C     and area.
22C
23C     INTERFACE
24C     _________
25C
26C     IERR = IGLSIZE(KSTRIDE, KAREA, KNWE, KNNS, KLN, OWEGLOBE,
27C    1   ONPOLE, OSPOLE, KPR, KERR)
28C
29C     Input parameters
30C     ________________
31C
32C     KSTRIDE    - The field grid definition (WE, NS).
33C
34C     KAREA      - The field area definition (N, W, S, E) provided by
35C                  the calling routine.
36C
37C     KNWE       - The number of points in the West-East direction in
38C                  the field. This will be zero for an output field.
39C
40C     KNNS       - The number of points in the North-South direction
41C                  in the field. This will be zero for an output field.
42C
43C     KPR        - The debug print switch.
44C                  0  , No debugging output.
45C                  1  , Produce debugging output.
46C
47C     KERR       - The error control flag.
48C                  -ve, No error message. Return error code.
49C                  0  , Hard failure with error message.
50C                  +ve, Print error message. Return error code.
51C
52C     Output parameters
53C     ________________
54C
55C     KNWE       - The number of points in the West-East direction in
56C                  the field.
57C
58C     KNNS       - The number of points in the North-South direction
59C                  in the field.
60C
61C     KLN        - The line number of the Northern latitude. This
62C                  value is used during land sea mask processing to
63C                  evaluate offsets in the "standard" files.
64C
65C     OWEGLOBE   - This variable will be true if the array of
66C                  longitudes spans the globe.
67C
68C     ONPOLE     - This variable will be true if the North polar line
69C                  of latitude is included in the grid.
70C
71C     OSPOLE     - This variable will be true if the South polar line
72C                  of latitude is included in the grid.
73C
74C     Return value
75C     ____________
76C
77C     The error indicator (INTEGER).
78C
79C     Error and Warning Return Values
80C     _______________________________
81C
82C     -1    The West-East range does not match the stride and number
83C           of points.
84C     -2    The North-South range does not match the stride and
85C           number of points.
86C
87C     The two problems above could be caused by known deficiencies
88C     in the GRIB representation of ranges and strides. They will be
89C     treated as WARNING values.
90C
91C     25101 A global field is requested with an inappropriate
92C           West-East stride.
93C     25102 A global field is requested with an inappropriate
94C           North-South stride.
95C
96C     Common block usage
97C     __________________
98C
99C     None
100C
101C     EXTERNALS
102C     _________
103C
104C     INTLOG(R)    - Logs messages.
105C
106C     METHOD
107C     ______
108C
109C     If all elements of array KAREA are zero then limits for the
110C     appropriate global grid are generated.
111C
112C     Otherwise it is assumed that all the limits in KAREA have been
113C     validated and the sizes of the arrays required are calculated.
114C
115C     REFERENCE
116C     _________
117C
118C     None
119C
120C     COMMENTS
121C     ________
122C
123C     Program contains sections 0 to 4 and 9
124C
125C     AUTHOR
126C     ______
127C
128C     K. Fielding      *ECMWF*      Oct 1993
129C
130C     MODIFICATIONS
131C     _____________
132C
133C     J.D.Chambers   ECMWF   March 1999
134C     Use tolerance when testing E-W and N-S global span.
135C
136C----<
137C     _______________________________________________________
138C
139C     Section 0. Definition of variables.
140C     _______________________________________________________
141C
142      IMPLICIT NONE
143C
144#include "parim.h"
145C
146C     Function arguments
147C
148      LOGICAL OWEGLOBE, ONPOLE, OSPOLE
149      INTEGER KNWE, KNNS, KLN, KPR, KERR
150      INTEGER KSTRIDE(2), KAREA(4)
151C
152C     Parameters
153C
154      INTEGER JPROUTINE, JPEPSI
155      PARAMETER (JPROUTINE = 25100)
156      PARAMETER (JPEPSI = 50)
157C                          `---> represents 0.5 millidegree to allow for
158C                                grid step being off by upto 0.5 millidgrees
159C
160C
161C     Local variables
162C
163      INTEGER IEAST, IWEST, IREACH, INORTH, ISOUTH
164C
165C     _______________________________________________________
166C
167C     Section 1. Initialisation
168C     _______________________________________________________
169C
170  100 CONTINUE
171C
172      IF( KPR.GE.1 ) CALL INTLOG(JP_DEBUG,'IGLSIZE: Section 1.',JPQUIET)
173C
174      IGLSIZE = 0
175C
176      IF( KPR.GE.1 ) THEN
177        CALL INTLOG(JP_DEBUG,'IGLSIZE: Input parameters.',JPQUIET)
178         IF( KNWE.NE.0 ) CALL INTLOG(JP_DEBUG,
179     X     'IGLSIZE: No.long pts = ',KNWE)
180         IF( KNNS.NE.0 ) CALL INTLOG(JP_DEBUG,
181     X     'IGLSIZE: No.lat. pts = ',KNNS)
182        CALL INTLOG(JP_DEBUG,'IGLSIZE: Grid WE stride = ',KSTRIDE(1))
183        CALL INTLOG(JP_DEBUG,'IGLSIZE: Grid NS stride = ',KSTRIDE(2))
184        CALL INTLOG(JP_DEBUG,'IGLSIZE: Area North = ', KAREA(1))
185        CALL INTLOG(JP_DEBUG,'IGLSIZE: Area West  = ', KAREA(2))
186        CALL INTLOG(JP_DEBUG,'IGLSIZE: Area South = ', KAREA(3))
187        CALL INTLOG(JP_DEBUG,'IGLSIZE: Area East  = ', KAREA(4))
188      ENDIF
189C
190C     _______________________________________________________
191C
192C     Section 2. Generate global limits if no limits set
193C     _______________________________________________________
194C
195  200 CONTINUE
196C
197      IF( KPR.GE.1 ) CALL INTLOG(JP_DEBUG,'IGLSIZE: Section 2.',JPQUIET)
198C
199      IF( (KAREA(JPEAST).EQ.0 )  .AND.
200     X    (KAREA(JPWEST).EQ.0 )  .AND.
201     X    (KAREA(JPNORTH).EQ.0 ) .AND.
202     X    (KAREA(JPSOUTH).EQ.0 ) ) THEN
203C
204        IF( MOD(JP360,KSTRIDE(JPWESTEP)).NE.0 ) THEN
205          IGLSIZE = JPROUTINE + 1
206          IF( KERR.GE.0 ) THEN
207            CALL INTLOGR(JP_ERROR,
208     X        'IGLSIZE: West-East stride for global grid = ',
209     X        REAL(KSTRIDE(JPWESTEP))/PPMULT)
210            CALL INTLOGR(JP_ERROR,
211     X        'IGLSIZE: This is not a factor of ',
212     X        REAL(JP360)/PPMULT)
213          ENDIF
214C
215          IF( KERR.EQ.0 ) CALL INTLOG(JP_FATAL,
216     X      'IGLSIZE: Interpolation failed.',IGLSIZE)
217C
218          GO TO 900
219        ENDIF
220C
221        IF( MOD(JP180,KSTRIDE(JPNSSTEP)).NE.0 ) THEN
222          IGLSIZE = JPROUTINE + 2
223          IF( KERR.GE.0 ) THEN
224            CALL INTLOGR(JP_ERROR,
225     X        'IGLSIZE: North-South stride for global grid = ',
226     X        REAL(KSTRIDE(JPNSSTEP))/PPMULT)
227            CALL INTLOGR(JP_ERROR,
228     X        'IGLSIZE: This is not a factor of ',
229     X        REAL(JP180)/PPMULT)
230          ENDIF
231C
232          IF( KERR.EQ.0 ) CALL INTLOG(JP_FATAL,
233     X      'IGLSIZE: Interpolation failed.',IGLSIZE)
234C
235          GO TO 900
236        ENDIF
237C
238        KAREA(JPNORTH) = JP90
239        KAREA(JPWEST) = 0
240        KAREA(JPSOUTH) = - JP90
241        KAREA(JPEAST) = JP360 - KSTRIDE(JPWESTEP)
242C
243      ENDIF
244C
245C     _______________________________________________________
246C
247C     Section 3. Standardise West-East limits and check for
248C                West-East global fields
249C     _______________________________________________________
250C
251  300 CONTINUE
252C
253      IF( KPR.GE.1 ) CALL INTLOG(JP_DEBUG,'IGLSIZE: Section 3.',JPQUIET)
254C
255C     Force both KAREA(JPWEST) and KAREA(JPEAST) into standard
256C     range (0 to JP360)
257C
258      IF( KAREA(JPWEST).LT.0 ) KAREA(JPWEST) = KAREA(JPWEST) + JP360
259C
260      IF( KAREA(JPEAST).LT.0 ) KAREA(JPEAST) = KAREA(JPEAST) + JP360
261C
262C     Standardise range so that EAST > WEST
263C
264      IEAST = KAREA(JPEAST)
265      IWEST = KAREA(JPWEST)
266C
267      IF( IEAST.LT.IWEST ) THEN
268C
269        IF( IEAST.LT.0 ) THEN
270          IEAST = IEAST + JP360
271          KAREA(JPEAST) = IEAST
272        ELSE
273          IWEST = IWEST - JP360
274          KAREA(JPWEST) = IWEST
275        ENDIF
276C
277      ENDIF
278C
279      IF( KNWE.EQ.0 ) THEN
280C
281C       Is it a global grid ?
282C
283        IREACH = IEAST - IWEST + KSTRIDE(JPWESTEP)
284C
285        OWEGLOBE = IREACH.GE.JP360
286C
287C       Number of points along line is
288C
289        KNWE = NINT( FLOAT(IREACH) / FLOAT(KSTRIDE(JPWESTEP)) )
290C
291      ELSE
292C
293C       Number of points is set (input field)
294C
295        IF( ABS(IWEST+(KNWE-1)*KSTRIDE(JPWESTEP)-IEAST).GT.
296     X      ((KNWE-1)*JPEPSI) ) THEN
297C
298C         WARNING of possible mismatch
299C
300          IGLSIZE = - 1
301          CALL INTLOGR(JP_WARN,
302     X      'IGLSIZE: West-East range = ',REAL(KAREA(JPWEST))/PPMULT)
303          CALL INTLOGR(JP_WARN,
304     X      'IGLSIZE: to = ',REAL(KAREA(JPEAST))/PPMULT)
305          CALL INTLOG(JP_WARN,
306     X      'IGLSIZE: Does not match no. of pts = ',KNWE)
307          CALL INTLOGR(JP_WARN,
308     X      'IGLSIZE: and stride = ',REAL(KSTRIDE(JPWESTEP))/PPMULT)
309C
310        ENDIF
311C
312        OWEGLOBE = ABS((KNWE * KSTRIDE(JPWESTEP))-JP360).LT.
313     X             (KNWE*JPEPSI)
314C
315      ENDIF
316C
317C     _______________________________________________________
318C
319C     Section 4. Generate points along a line of meridian
320C     _______________________________________________________
321C
322  400 CONTINUE
323C
324      IF( KPR.GE.1 ) CALL INTLOG(JP_DEBUG,'IGLSIZE: Section 4.',JPQUIET)
325C
326      INORTH = KAREA(JPNORTH)
327      ISOUTH = KAREA(JPSOUTH)
328      IF( INORTH.LT.ISOUTH ) THEN
329        INORTH = KAREA(JPSOUTH)
330        ISOUTH = KAREA(JPNORTH)
331      ENDIF
332C
333      IF( KNNS.EQ.0 ) THEN
334C
335C     Number of lines not set (output field)
336C
337        IREACH = INORTH - ISOUTH + KSTRIDE(JPNSSTEP)
338C
339        KNNS = NINT( FLOAT(IREACH) / FLOAT(KSTRIDE(JPNSSTEP)) )
340C
341      ELSE
342C
343C       Number of lines is set (input field)
344C
345        IF(
346     X    ABS(INORTH-(KNNS-1)*KSTRIDE(JPNSSTEP)-ISOUTH)
347     X    .GT.((KNNS-1)*JPEPSI) ) THEN
348C
349C     WARNING of possible mismatch
350C
351          IGLSIZE = - 2
352          CALL INTLOGR(JP_WARN,
353     X      'IGLSIZE: North-South range = ',REAL(INORTH)/PPMULT)
354          CALL INTLOGR(JP_WARN,
355     X      'IGLSIZE: to = ',REAL(ISOUTH)/PPMULT)
356          CALL INTLOG(JP_WARN,
357     X      'IGLSIZE: Does not match no. of pts = ',KNNS)
358          CALL INTLOGR(JP_WARN,
359     X      'IGLSIZE: and stride = ',REAL(KSTRIDE(JPNSSTEP))/PPMULT)
360C
361         ENDIF
362C
363      ENDIF
364C
365      KLN = (JP90 - INORTH ) / KSTRIDE(JPNSSTEP) + 1
366C
367C     Check if North and South poles within grid
368C
369      ONPOLE = INORTH.EQ.JP90
370      OSPOLE = ISOUTH.EQ.(- JP90)
371C
372      IF( KPR.GE.1 ) THEN
373        CALL INTLOG(JP_DEBUG,'IGLSIZE: Output parameters.',JPQUIET)
374        IF( KNWE.NE.0 ) CALL INTLOG(JP_DEBUG,
375     X    'IGLSIZE: No.long pts = ',KNWE)
376        IF( KNNS.NE.0 ) CALL INTLOG(JP_DEBUG,
377     X    'IGLSIZE: No.lat. pts = ',KNNS)
378        CALL INTLOG(JP_DEBUG,'IGLSIZE: Northern line no. =',KLN)
379C
380        IF( OWEGLOBE ) THEN
381          CALL INTLOG(JP_DEBUG,'IGLSIZE: W-E fld is global',JPQUIET)
382        ELSE
383          CALL INTLOG(JP_DEBUG,'IGLSIZE: W-E fld is NOT global',JPQUIET)
384        ENDIF
385C
386        IF( ONPOLE ) THEN
387          CALL INTLOG(JP_DEBUG,'IGLSIZE: N pole is in fld.',JPQUIET)
388        ELSE
389          CALL INTLOG(JP_DEBUG,'IGLSIZE: N pole is NOT in fld.',JPQUIET)
390        ENDIF
391C
392        IF( OSPOLE ) THEN
393          CALL INTLOG(JP_DEBUG,'IGLSIZE: S pole is in fld.',JPQUIET)
394        ELSE
395          CALL INTLOG(JP_DEBUG,'IGLSIZE: S pole is NOT in fld.',JPQUIET)
396        ENDIF
397C
398      ENDIF
399C
400C     _______________________________________________________
401C
402C     Section 9. Return to calling routine. Format statements
403C     _______________________________________________________
404C
405  900 CONTINUE
406C
407      IF( KPR.GE.1 ) CALL INTLOG(JP_DEBUG,'IGLSIZE: Section 9.',JPQUIET)
408C
409      RETURN
410      END
411