NCEPLIBS-ip 4.0.0
neighbor_budget_interp_mod.f90
1module neighbor_budget_interp_mod
2 use gdswzd_mod
3 use polfix_mod
4 use ip_grids_mod
5 implicit none
6
7 private
9
11 module procedure interpolate_neighbor_budget_scalar
12 module procedure interpolate_neighbor_budget_vector
13 end interface interpolate_neighbor_budget
14
15contains
16
17 SUBROUTINE interpolate_neighbor_budget_scalar(IPOPT,grid_in,grid_out, &
18 MI,MO,KM,IBI,LI,GI, &
19 NO,RLAT,RLON,IBO,LO,GO,IRET)
20 !$$$ SUBPROGRAM DOCUMENTATION BLOCK
21 !
22 ! SUBPROGRAM: POLATES6 INTERPOLATE SCALAR FIELDS (BUDGET)
23 ! PRGMMR: IREDELL ORG: W/NMC23 DATE: 96-04-10
24 !
25 ! ABSTRACT: THIS SUBPROGRAM PERFORMS BUDGET INTERPOLATION
26 ! FROM ANY GRID TO ANY GRID FOR SCALAR FIELDS.
27 ! THE ALGORITHM SIMPLY COMPUTES (WEIGHTED) AVERAGES
28 ! OF NEIGHBOR POINTS ARRANGED IN A SQUARE BOX
29 ! CENTERED AROUND EACH OUTPUT GRID POINT AND STRETCHING
30 ! NEARLY HALFWAY TO EACH OF THE NEIGHBORING GRID POINTS.
31 ! OPTIONS ALLOW CHOICES OF NUMBER OF POINTS IN EACH RADIUS
32 ! FROM THE CENTER POINT (IPOPT(1)) WHICH DEFAULTS TO 2
33 ! (IF IPOPT(1)=-1) MEANING THAT 25 POINTS WILL BE AVERAGED;
34 ! FURTHER OPTIONS ARE THE RESPECTIVE WEIGHTS FOR THE RADIUS
35 ! POINTS STARTING AT THE CENTER POINT (IPOPT(2:2+IPOPT(1))
36 ! WHICH DEFAULTS TO ALL 1 (IF IPOPT(1)=-1 OR IPOPT(2)=-1).
37 ! ANOTHER OPTION IS THE MINIMUM PERCENTAGE FOR MASK,
38 ! I.E. PERCENT VALID INPUT DATA REQUIRED TO MAKE OUTPUT DATA,
39 ! (IPOPT(3+IPOPT(1)) WHICH DEFAULTS TO 50 (IF -1).
40 ! ONLY HORIZONTAL INTERPOLATION IS PERFORMED.
41 ! THE CODE RECOGNIZES THE FOLLOWING PROJECTIONS, WHERE
42 ! "IGDTNUMI/O" IS THE GRIB 2 GRID DEFINTION TEMPLATE NUMBER
43 ! FOR THE INPUT AND OUTPUT GRIDS, RESPECTIVELY:
44 ! (IGDTNUMI/O=00) EQUIDISTANT CYLINDRICAL
45 ! (IGDTNUMI/O=01) ROTATED EQUIDISTANT CYLINDRICAL. "E" AND
46 ! NON-"E" STAGGERED
47 ! (IGDTNUMI/O=10) MERCATOR CYLINDRICAL
48 ! (IGDTNUMI/O=20) POLAR STEREOGRAPHIC AZIMUTHAL
49 ! (IGDTNUMI/O=30) LAMBERT CONFORMAL CONICAL
50 ! (IGDTNUMI/O=40) GAUSSIAN CYLINDRICAL
51 ! AS AN ADDED BONUS THE NUMBER OF OUTPUT GRID POINTS
52 ! AND THEIR LATITUDES AND LONGITUDES ARE ALSO RETURNED.
53 ! INPUT BITMAPS WILL BE INTERPOLATED TO OUTPUT BITMAPS.
54 ! OUTPUT BITMAPS WILL ALSO BE CREATED WHEN THE OUTPUT GRID
55 ! EXTENDS OUTSIDE OF THE DOMAIN OF THE INPUT GRID.
56 ! THE OUTPUT FIELD IS SET TO 0 WHERE THE OUTPUT BITMAP IS OFF.
57 !
58 ! PROGRAM HISTORY LOG:
59 ! 96-04-10 IREDELL
60 ! 96-10-04 IREDELL NEIGHBOR POINTS NOT BILINEAR INTERPOLATION
61 ! 1999-04-08 IREDELL SPLIT IJKGDS INTO TWO PIECES
62 ! 2001-06-18 IREDELL INCLUDE MINIMUM MASK PERCENTAGE OPTION
63 ! 2015-01-27 GAYNO REPLACE CALLS TO GDSWIZ WITH NEW MERGED
64 ! VERSION OF GDSWZD.
65 ! 2015-07-13 GAYNO CONVERT TO GRIB 2. REPLACE GRIB 1 KGDS ARRAYS
66 ! WITH GRIB 2 GRID DEFINITION TEMPLATE ARRAYS.
67 !
68 ! USAGE: CALL POLATES6(IPOPT,IGDTNUMI,IGDTMPLI,IGDTLENI, &
69 ! IGDTNUMO,IGDTMPLO,IGDTLENO, &
70 ! MI,MO,KM,IBI,LI,GI, &
71 ! NO,RLAT,RLON,IBO,LO,GO,IRET)
72 !
73 ! INPUT ARGUMENT LIST:
74 ! IPOPT - INTEGER (20) INTERPOLATION OPTIONS
75 ! IPOPT(1) IS NUMBER OF RADIUS POINTS
76 ! (DEFAULTS TO 2 IF IPOPT(1)=-1);
77 ! IPOPT(2:2+IPOPT(1)) ARE RESPECTIVE WEIGHTS
78 ! (DEFAULTS TO ALL 1 IF IPOPT(1)=-1 OR IPOPT(2)=-1).
79 ! IPOPT(3+IPOPT(1)) IS MINIMUM PERCENTAGE FOR MASK
80 ! (DEFAULTS TO 50 IF IPOPT(3+IPOPT(1)=-1)
81 ! IGDTNUMI - INTEGER GRID DEFINITION TEMPLATE NUMBER - INPUT GRID.
82 ! CORRESPONDS TO THE GFLD%IGDTNUM COMPONENT OF THE
83 ! NCEP G2 LIBRARY GRIDMOD DATA STRUCTURE:
84 ! 00 - EQUIDISTANT CYLINDRICAL
85 ! 01 - ROTATED EQUIDISTANT CYLINDRICAL. "E"
86 ! AND NON-"E" STAGGERED
87 ! 10 - MERCATOR CYCLINDRICAL
88 ! 20 - POLAR STEREOGRAPHIC AZIMUTHAL
89 ! 30 - LAMBERT CONFORMAL CONICAL
90 ! 40 - GAUSSIAN EQUIDISTANT CYCLINDRICAL
91 ! IGDTMPLI - INTEGER (IGDTLENI) GRID DEFINITION TEMPLATE ARRAY -
92 ! INPUT GRID. CORRESPONDS TO THE GFLD%IGDTMPL COMPONENT
93 ! OF THE NCEP G2 LIBRARY GRIDMOD DATA STRUCTURE.
94 ! (SECTION 3 INFO). SEE COMMENTS IN ROUTINE
95 ! IPOLATES FOR COMPLETE DEFINITION.
96 ! IGDTLENI - INTEGER NUMBER OF ELEMENTS OF THE GRID DEFINITION
97 ! TEMPLATE ARRAY - INPUT GRID. CORRESPONDS TO THE GFLD%IGDTLEN
98 ! COMPONENT OF THE NCEP G2 LIBRARY GRIDMOD DATA STRUCTURE.
99 ! IGDTNUMO - INTEGER GRID DEFINITION TEMPLATE NUMBER - OUTPUT GRID.
100 ! CORRESPONDS TO THE GFLD%IGDTNUM COMPONENT OF THE
101 ! NCEP G2 LIBRARY GRIDMOD DATA STRUCTURE.
102 ! SAME DEFINITION AS "IGDTNUMI".
103 ! IGDTMPLO - INTEGER (IGDTLENO) GRID DEFINITION TEMPLATE ARRAY -
104 ! OUTPUT GRID. CORRESPONDS TO THE GFLD%IGDTMPL COMPONENT
105 ! OF THE NCEP G2 LIBRARY GRIDMOD DATA STRUCTURE.
106 ! (SECTION 3 INFO). SEE COMMENTS IN ROUTINE
107 ! IPOLATES FOR COMPLETE DEFINITION.
108 ! IGDTLENO - INTEGER NUMBER OF ELEMENTS OF THE GRID DEFINITION
109 ! TEMPLATE ARRAY - OUTPUT GRID. CORRESPONDS TO THE GFLD%IGDTLEN
110 ! COMPONENT OF THE NCEP G2 LIBRARY GRIDMOD DATA STRUCTURE.
111 ! MI - INTEGER SKIP NUMBER BETWEEN INPUT GRID FIELDS IF KM>1
112 ! OR DIMENSION OF INPUT GRID FIELDS IF KM=1
113 ! MO - INTEGER SKIP NUMBER BETWEEN OUTPUT GRID FIELDS IF KM>1
114 ! OR DIMENSION OF OUTPUT GRID FIELDS IF KM=1
115 ! KM - INTEGER NUMBER OF FIELDS TO INTERPOLATE
116 ! IBI - INTEGER (KM) INPUT BITMAP FLAGS
117 ! LI - LOGICAL*1 (MI,KM) INPUT BITMAPS (IF SOME IBI(K)=1)
118 ! GI - REAL (MI,KM) INPUT FIELDS TO INTERPOLATE
119 !
120 ! OUTPUT ARGUMENT LIST:
121 ! NO - INTEGER NUMBER OF OUTPUT POINTS
122 ! RLAT - REAL (MO) OUTPUT LATITUDES IN DEGREES
123 ! RLON - REAL (MO) OUTPUT LONGITUDES IN DEGREES
124 ! IBO - INTEGER (KM) OUTPUT BITMAP FLAGS
125 ! LO - LOGICAL*1 (MO,KM) OUTPUT BITMAPS (ALWAYS OUTPUT)
126 ! GO - REAL (MO,KM) OUTPUT FIELDS INTERPOLATED
127 ! IRET - INTEGER RETURN CODE
128 ! 0 SUCCESSFUL INTERPOLATION
129 ! 2 UNRECOGNIZED INPUT GRID OR NO GRID OVERLAP
130 ! 3 UNRECOGNIZED OUTPUT GRID
131 ! 31 INVALID UNDEFINED OUTPUT GRID
132 ! 32 INVALID BUDGET METHOD PARAMETERS
133 !
134 ! SUBPROGRAMS CALLED:
135 ! GDSWZD GRID DESCRIPTION SECTION WIZARD
136 ! POLFIXS MAKE MULTIPLE POLE SCALAR VALUES CONSISTENT
137 !
138 ! ATTRIBUTES:
139 ! LANGUAGE: FORTRAN 90
140 !
141 !$$$
142
143 class(ip_grid), intent(in) :: grid_in, grid_out
144
145 INTEGER, INTENT(IN ) :: IBI(KM), IPOPT(20), KM, MI, MO
146 INTEGER, INTENT( OUT) :: IBO(KM), IRET, NO
147 !
148 LOGICAL*1, INTENT(IN ) :: LI(MI,KM)
149 LOGICAL*1, INTENT( OUT) :: LO(MO,KM)
150 !
151 REAL, INTENT(IN ) :: GI(MI,KM)
152 REAL, INTENT( OUT) :: GO(MO,KM), RLAT(MO), RLON(MO)
153 !
154 REAL, PARAMETER :: FILL=-9999.
155 !
156 INTEGER :: IB, I1
157 INTEGER :: JB, J1, K, LB, LSW, MP, N
158 INTEGER :: N11(MO), NB, NB1, NB2, NB3, NB4, NV
159 !
160 REAL :: PMP,RLOB(MO),RLAB(MO)
161 REAL :: WB, WO(MO,KM), XI, YI
162 REAL :: XPTB(MO),YPTB(MO),XPTS(MO),YPTS(MO)
163
164 logical :: to_station_points
165
166 select type(grid_out)
167 type is(ip_station_points_grid)
168 to_station_points = .true.
169 class default
170 to_station_points = .false.
171 end select
172
173 ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
174 ! COMPUTE NUMBER OF OUTPUT POINTS AND THEIR LATITUDES AND LONGITUDES.
175 iret=0
176 IF(.not. to_station_points) THEN
177 CALL gdswzd(grid_out, 0,mo,fill,xpts,ypts,rlon,rlat,no)
178 IF(no.EQ.0) iret=3
179 ELSE
180 iret=31
181 ENDIF
182 ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
183 ! SET PARAMETERS
184 nb1=ipopt(1)
185 IF(nb1.EQ.-1) nb1=2
186 IF(iret.EQ.0.AND.nb1.LT.0) iret=32
187 lsw=1
188 IF(ipopt(1).EQ.-1.OR.ipopt(2).EQ.-1) lsw=0
189 IF(iret.EQ.0.AND.lsw.EQ.1.AND.nb1.GT.15) iret=32
190 mp=ipopt(3+ipopt(1))
191 IF(mp.EQ.-1.OR.mp.EQ.0) mp=50
192 IF(mp.LT.0.OR.mp.GT.100) iret=32
193 pmp=mp*0.01
194 IF(iret.EQ.0) THEN
195 nb2=2*nb1+1
196 nb3=nb2*nb2
197 nb4=nb3
198 IF(lsw.EQ.1) THEN
199 nb4=ipopt(2)
200 DO ib=1,nb1
201 nb4=nb4+8*ib*ipopt(2+ib)
202 ENDDO
203 ENDIF
204 ELSE
205 nb2=0
206 nb3=0
207 nb4=0
208 ENDIF
209 DO k=1,km
210 DO n=1,no
211 go(n,k)=0.
212 wo(n,k)=0.
213 ENDDO
214 ENDDO
215 ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
216 ! LOOP OVER SAMPLE POINTS IN OUTPUT GRID BOX
217
218 DO nb=1,nb3
219 ! LOCATE INPUT POINTS AND COMPUTE THEIR WEIGHTS
220 jb=(nb-1)/nb2-nb1
221 ib=nb-(jb+nb1)*nb2-nb1-1
222 lb=max(abs(ib),abs(jb))
223 wb=1
224 IF(lsw.EQ.1) wb=ipopt(2+lb)
225 IF(wb.NE.0) THEN
226 DO n=1,no
227 xptb(n)=xpts(n)+ib/real(nb2)
228 yptb(n)=ypts(n)+jb/real(nb2)
229 ENDDO
230 CALL gdswzd(grid_out, 1,no,fill,xptb,yptb,rlob,rlab,nv)
231 CALL gdswzd(grid_in,-1,no,fill,xptb,yptb,rlob,rlab,nv)
232 IF(iret.EQ.0.AND.nv.EQ.0.AND.lb.EQ.0) iret=2
233 DO n=1,no
234 xi=xptb(n)
235 yi=yptb(n)
236 IF(xi.NE.fill.AND.yi.NE.fill) THEN
237 i1=nint(xi)
238 j1=nint(yi)
239 n11(n)=grid_in%field_pos(i1, j1)
240 ELSE
241 n11(n)=0
242 ENDIF
243 ENDDO
244 ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
245 ! INTERPOLATE WITH OR WITHOUT BITMAPS
246 DO k=1,km
247 DO n=1,no
248 IF(n11(n).GT.0) THEN
249 IF(ibi(k).EQ.0.OR.li(n11(n),k)) THEN
250 go(n,k)=go(n,k)+wb*gi(n11(n),k)
251 wo(n,k)=wo(n,k)+wb
252 ENDIF
253 ENDIF
254 ENDDO
255 ENDDO
256 ENDIF
257 ENDDO
258 ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
259 ! COMPUTE OUTPUT BITMAPS AND FIELDS
260 DO k=1,km
261 ibo(k)=ibi(k)
262 DO n=1,no
263 lo(n,k)=wo(n,k).GE.pmp*nb4
264 IF(lo(n,k)) THEN
265 go(n,k)=go(n,k)/wo(n,k)
266 ELSE
267 ibo(k)=1
268 go(n,k)=0.
269 ENDIF
270 ENDDO
271 ENDDO
272
273 select type(grid_out)
274 type is(ip_equid_cylind_grid)
275 CALL polfixs(no,mo,km,rlat,ibo,lo,go)
276 end select
277
278 END SUBROUTINE interpolate_neighbor_budget_scalar
279
280
281 SUBROUTINE interpolate_neighbor_budget_vector(IPOPT,grid_in,grid_out, &
282 MI,MO,KM,IBI,LI,UI,VI, &
283 NO,RLAT,RLON,CROT,SROT,IBO,LO,UO,VO,IRET)
284 !$$$ SUBPROGRAM DOCUMENTATION BLOCK
285 !
286 ! SUBPROGRAM: POLATEV6 INTERPOLATE VECTOR FIELDS (BUDGET)
287 ! PRGMMR: IREDELL ORG: W/NMC23 DATE: 96-04-10
288 !
289 ! ABSTRACT: THIS SUBPROGRAM PERFORMS BUDGET INTERPOLATION
290 ! FROM ANY GRID TO ANY GRID FOR VECTOR FIELDS.
291 ! THE ALGORITHM SIMPLY COMPUTES (WEIGHTED) AVERAGES
292 ! OF NEIGHBOR POINTS ARRANGED IN A SQUARE BOX
293 ! CENTERED AROUND EACH OUTPUT GRID POINT AND STRETCHING
294 ! NEARLY HALFWAY TO EACH OF THE NEIGHBORING GRID POINTS.
295 ! OPTIONS ALLOW CHOICES OF NUMBER OF POINTS IN EACH RADIUS
296 ! FROM THE CENTER POINT (IPOPT(1)) WHICH DEFAULTS TO 2
297 ! (IF IPOPT(1)=-1) MEANING THAT 25 POINTS WILL BE AVERAGED;
298 ! FURTHER OPTIONS ARE THE RESPECTIVE WEIGHTS FOR THE RADIUS
299 ! POINTS STARTING AT THE CENTER POINT (IPOPT(2:2+IPOPT(1))
300 ! WHICH DEFAULTS TO ALL 1 (IF IPOPT(1)=-1 OR IPOPT(2)=-1).
301 ! ANOTHER OPTION IS THE MINIMUM PERCENTAGE FOR MASK,
302 ! I.E. PERCENT VALID INPUT DATA REQUIRED TO MAKE OUTPUT DATA,
303 ! (IPOPT(3+IPOPT(1)) WHICH DEFAULTS TO 50 (IF -1).
304 ! ONLY HORIZONTAL INTERPOLATION IS PERFORMED.
305 !
306 ! THE INPUT AND OUTPUT GRIDS ARE DEFINED BY THEIR GRIB 2 GRID
307 ! DEFINITION TEMPLATE AS DECODED BY THE NCEP G2 LIBRARY. THE
308 ! CODE RECOGNIZES THE FOLLOWING PROJECTIONS, WHERE
309 ! "IGDTNUMI/O" IS THE GRIB 2 GRID DEFINTION TEMPLATE NUMBER
310 ! FOR THE INPUT AND OUTPUT GRIDS, RESPECTIVELY:
311 ! (IGDTNUMI/O=00) EQUIDISTANT CYLINDRICAL
312 ! (IGDTNUMI/O=01) ROTATED EQUIDISTANT CYLINDRICAL. "E" AND
313 ! NON-"E" STAGGERED
314 ! (IGDTNUMI/O=10) MERCATOR CYLINDRICAL
315 ! (IGDTNUMI/O=20) POLAR STEREOGRAPHIC AZIMUTHAL
316 ! (IGDTNUMI/O=30) LAMBERT CONFORMAL CONICAL
317 ! (IGDTNUMI/O=40) GAUSSIAN CYLINDRICAL
318 !
319 ! THE INPUT AND OUTPUT VECTORS ARE ROTATED SO THAT THEY ARE
320 ! EITHER RESOLVED RELATIVE TO THE DEFINED GRID
321 ! IN THE DIRECTION OF INCREASING X AND Y COORDINATES
322 ! OR RESOLVED RELATIVE TO EASTERLY AND NORTHERLY DIRECTIONS,
323 ! AS DESIGNATED BY THEIR RESPECTIVE GRID DESCRIPTION SECTIONS.
324 !
325 ! AS AN ADDED BONUS THE NUMBER OF OUTPUT GRID POINTS
326 ! AND THEIR LATITUDES AND LONGITUDES ARE ALSO RETURNED
327 ! ALONG WITH THEIR VECTOR ROTATION PARAMETERS.
328 ! INPUT BITMAPS WILL BE INTERPOLATED TO OUTPUT BITMAPS.
329 ! OUTPUT BITMAPS WILL ALSO BE CREATED WHEN THE OUTPUT GRID
330 ! EXTENDS OUTSIDE OF THE DOMAIN OF THE INPUT GRID.
331 ! THE OUTPUT FIELD IS SET TO 0 WHERE THE OUTPUT BITMAP IS OFF.
332 !
333 ! PROGRAM HISTORY LOG:
334 ! 96-04-10 IREDELL
335 ! 1999-04-08 IREDELL SPLIT IJKGDS INTO TWO PIECES
336 ! 2001-06-18 IREDELL INCLUDE MINIMUM MASK PERCENTAGE OPTION
337 ! 2002-01-17 IREDELL SAVE DATA FROM LAST CALL FOR OPTIMIZATION
338 ! 2015-01-27 GAYNO REPLACE CALLS TO GDSWIZ WITH NEW MERGED
339 ! ROUTINE GDSWZD.
340 ! 2015-07-13 GAYNO CONVERT TO GRIB 2. REPLACE GRIB 1 KGDS ARRAYS
341 ! WITH GRIB 2 GRID DEFINITION TEMPLATE ARRAYS.
342 !
343 ! USAGE: CALL POLATEV6(IPOPT,IGDTNUMI,IGDTMPLI,IGDTLENI, &
344 ! IGDTNUMO,IGDTMPLO,IGDTLENO, &
345 ! MI,MO,KM,IBI,LI,UI,VI, &
346 ! NO,RLAT,RLON,CROT,SROT,IBO,LO,UO,VO,IRET)
347 !
348 ! INPUT ARGUMENT LIST:
349 ! IPOPT - INTEGER (20) INTERPOLATION OPTIONS
350 ! IPOPT(1) IS NUMBER OF RADIUS POINTS
351 ! (DEFAULTS TO 2 IF IPOPT(1)=-1);
352 ! IPOPT(2:2+IPOPT(1)) ARE RESPECTIVE WEIGHTS
353 ! (DEFAULTS TO ALL 1 IF IPOPT(1)=-1 OR IPOPT(2)=-1).
354 ! IPOPT(3+IPOPT(1)) IS MINIMUM PERCENTAGE FOR MASK
355 ! (DEFAULTS TO 50 IF IPOPT(3+IPOPT(1)=-1)
356 ! IGDTNUMI - INTEGER GRID DEFINITION TEMPLATE NUMBER - INPUT GRID.
357 ! CORRESPONDS TO THE GFLD%IGDTNUM COMPONENT OF THE
358 ! NCEP G2 LIBRARY GRIDMOD DATA STRUCTURE:
359 ! 00 - EQUIDISTANT CYLINDRICAL
360 ! 01 - ROTATED EQUIDISTANT CYLINDRICAL. "E"
361 ! AND NON-"E" STAGGERED
362 ! 10 - MERCATOR CYCLINDRICAL
363 ! 20 - POLAR STEREOGRAPHIC AZIMUTHAL
364 ! 30 - LAMBERT CONFORMAL CONICAL
365 ! 40 - GAUSSIAN EQUIDISTANT CYCLINDRICAL
366 ! IGDTMPLI - INTEGER (IGDTLENI) GRID DEFINITION TEMPLATE ARRAY -
367 ! INPUT GRID. CORRESPONDS TO THE GFLD%IGDTMPL COMPONENT
368 ! OF THE NCEP G2 LIBRARY GRIDMOD DATA STRUCTURE
369 ! (SECTION 3 INFO). SEE COMMENTS IN ROUTINE
370 ! IPOLATEV FOR COMPLETE DEFINITION.
371 ! IGDTLENI - INTEGER NUMBER OF ELEMENTS OF THE GRID DEFINITION
372 ! TEMPLATE ARRAY - INPUT GRID. CORRESPONDS TO THE GFLD%IGDTLEN
373 ! COMPONENT OF THE NCEP G2 LIBRARY GRIDMOD DATA STRUCTURE.
374 ! IGDTNUMO - INTEGER GRID DEFINITION TEMPLATE NUMBER - OUTPUT GRID.
375 ! CORRESPONDS TO THE GFLD%IGDTNUM COMPONENT OF THE
376 ! NCEP G2 LIBRARY GRIDMOD DATA STRUCTURE.
377 ! SAME DEFINITION AS "IGDTNUMI"
378 ! IGDTMPLO - INTEGER (IGDTLENO) GRID DEFINITION TEMPLATE ARRAY -
379 ! OUTPUT GRID. CORRESPONDS TO THE GFLD%IGDTMPL COMPONENT
380 ! OF THE NCEP G2 LIBRARY GRIDMOD DATA STRUCTURE
381 ! (SECTION 3 INFO). SEE COMMENTS IN ROUTINE
382 ! IPOLATEV FOR COMPLETE DEFINITION.
383 ! IGDTLENO - INTEGER NUMBER OF ELEMENTS OF THE GRID DEFINITION
384 ! TEMPLATE ARRAY - OUTPUT GRID. CORRESPONDS TO THE GFLD%IGDTLEN
385 ! COMPONENT OF THE NCEP G2 LIBRARY GRIDMOD DATA STRUCTURE.
386 ! MI - INTEGER SKIP NUMBER BETWEEN INPUT GRID FIELDS IF KM>1
387 ! OR DIMENSION OF INPUT GRID FIELDS IF KM=1
388 ! MO - INTEGER SKIP NUMBER BETWEEN OUTPUT GRID FIELDS IF KM>1
389 ! OR DIMENSION OF OUTPUT GRID FIELDS IF KM=1
390 ! KM - INTEGER NUMBER OF FIELDS TO INTERPOLATE
391 ! IBI - INTEGER (KM) INPUT BITMAP FLAGS
392 ! LI - LOGICAL*1 (MI,KM) INPUT BITMAPS (IF SOME IBI(K)=1)
393 ! UI - REAL (MI,KM) INPUT U-COMPONENT FIELDS TO INTERPOLATE
394 ! VI - REAL (MI,KM) INPUT V-COMPONENT FIELDS TO INTERPOLATE
395 !
396 ! OUTPUT ARGUMENT LIST:
397 ! NO - INTEGER NUMBER OF OUTPUT POINTS
398 ! RLAT - REAL (MO) OUTPUT LATITUDES IN DEGREES
399 ! RLON - REAL (MO) OUTPUT LONGITUDES IN DEGREES
400 ! CROT - REAL (MO) VECTOR ROTATION COSINES
401 ! SROT - REAL (MO) VECTOR ROTATION SINES
402 ! (UGRID=CROT*UEARTH-SROT*VEARTH;
403 ! VGRID=SROT*UEARTH+CROT*VEARTH)
404 ! IBO - INTEGER (KM) OUTPUT BITMAP FLAGS
405 ! LO - LOGICAL*1 (MO,KM) OUTPUT BITMAPS (ALWAYS OUTPUT)
406 ! UO - REAL (MO,KM) OUTPUT U-COMPONENT FIELDS INTERPOLATED
407 ! VO - REAL (MO,KM) OUTPUT V-COMPONENT FIELDS INTERPOLATED
408 ! IRET - INTEGER RETURN CODE
409 ! 0 SUCCESSFUL INTERPOLATION
410 ! 2 UNRECOGNIZED INPUT GRID OR NO GRID OVERLAP
411 ! 3 UNRECOGNIZED OUTPUT GRID
412 ! 31 INVALID UNDEFINED OUTPUT GRID
413 ! 32 INVALID BUDGET METHOD PARAMETERS
414 !
415 ! SUBPROGRAMS CALLED:
416 ! GDSWZD GRID DESCRIPTION SECTION WIZARD
417 ! MOVECT MOVE A VECTOR ALONG A GREAT CIRCLE
418 ! POLFIXV MAKE MULTIPLE POLE VECTOR VALUES CONSISTENT
419 ! CHECK_GRIDS6V DETERMINE IF INPUT OR OUTPUT GRIDS HAVE CHANGED
420 ! BETWEEN CALLS TO THIS ROUTINE.
421 !
422 ! ATTRIBUTES:
423 ! LANGUAGE: FORTRAN 90
424 !
425 !$$$
426 class(ip_grid), intent(in) :: grid_in, grid_out
427
428 INTEGER, INTENT(IN ) :: IPOPT(20), IBI(KM)
429 INTEGER, INTENT(IN ) :: KM, MI, MO
430 INTEGER, INTENT( OUT) :: IRET, NO, IBO(KM)
431 !
432 LOGICAL*1, INTENT(IN ) :: LI(MI,KM)
433 LOGICAL*1, INTENT( OUT) :: LO(MO,KM)
434 !
435 REAL, INTENT(IN ) :: UI(MI,KM),VI(MI,KM)
436 REAL, INTENT(INOUT) :: RLAT(MO),RLON(MO)
437 REAL, INTENT( OUT) :: UO(MO,KM),VO(MO,KM)
438 REAL, INTENT( OUT) :: CROT(MO),SROT(MO)
439 !
440 REAL, PARAMETER :: FILL=-9999.
441 !
442 INTEGER :: N11(MO)
443 INTEGER :: IB, JB, I1, J1
444 INTEGER :: K, LB, LSW, MP, N, NV
445 INTEGER :: NB, NB1, NB2, NB3, NB4
446 !
447 LOGICAL :: SAME_GRID
448 !
449 REAL :: C11(MO),S11(MO)
450 REAL :: CM11, SM11, PMP
451 REAL :: U11, V11, UROT, VROT
452 REAL :: WB, WO(MO,KM), XI, YI
453 REAL :: RLOB(MO),RLAB(MO)
454 REAL :: XPTS(MO),YPTS(MO)
455 REAL :: XPTB(MO),YPTB(MO)
456
457 logical :: to_station_points
458
459 ! Save coeffecients between runs and only compute if grid has changed
460 INTEGER, SAVE :: MIX=-1
461 REAL, ALLOCATABLE,SAVE :: CROI(:),SROI(:)
462 REAL, ALLOCATABLE,SAVE :: XPTI(:),YPTI(:)
463 REAL, ALLOCATABLE,SAVE :: RLOI(:),RLAI(:)
464 class(ip_grid), allocatable, save :: prev_grid_in
465
466 select type(grid_out)
467 type is(ip_station_points_grid)
468 to_station_points = .true.
469 class default
470 to_station_points = .false.
471 end select
472
473 ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
474 ! COMPUTE NUMBER OF OUTPUT POINTS AND THEIR LATITUDES AND LONGITUDES.
475 iret=0
476 IF(.not. to_station_points) THEN
477 CALL gdswzd(grid_out, 0,mo,fill,xpts,ypts, &
478 rlon,rlat,no,crot,srot)
479 IF(no.EQ.0) iret=3
480 ELSE
481 iret=31
482 ENDIF
483
484 if (.not. allocated(prev_grid_in)) then
485 allocate(prev_grid_in, source = grid_in)
486
487 same_grid = .false.
488 else
489 same_grid = grid_in == prev_grid_in
490
491 if (.not. same_grid) then
492 deallocate(prev_grid_in)
493 allocate(prev_grid_in, source = grid_in)
494 end if
495 end if
496
497 IF(.NOT.same_grid) THEN
498 IF(mix.NE.mi) THEN
499 IF(mix.GE.0) DEALLOCATE(xpti,ypti,rloi,rlai,croi,sroi)
500 ALLOCATE(xpti(mi),ypti(mi),rloi(mi),rlai(mi),croi(mi),sroi(mi))
501 mix=mi
502 ENDIF
503 CALL gdswzd(grid_in,0,mi,fill,xpti,ypti, &
504 rloi,rlai,nv,croi,sroi)
505 ENDIF
506 ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
507 ! SET PARAMETERS
508 nb1=ipopt(1)
509 IF(nb1.EQ.-1) nb1=2
510 IF(iret.EQ.0.AND.nb1.LT.0) iret=32
511 lsw=1
512 IF(ipopt(1).EQ.-1.OR.ipopt(2).EQ.-1) lsw=0
513 IF(iret.EQ.0.AND.lsw.EQ.1.AND.nb1.GT.15) iret=32
514 mp=ipopt(3+ipopt(1))
515 IF(mp.EQ.-1.OR.mp.EQ.0) mp=50
516 IF(mp.LT.0.OR.mp.GT.100) iret=32
517 pmp=mp*0.01
518 IF(iret.EQ.0) THEN
519 nb2=2*nb1+1
520 nb3=nb2*nb2
521 nb4=nb3
522 IF(lsw.EQ.1) THEN
523 nb4=ipopt(2)
524 DO ib=1,nb1
525 nb4=nb4+8*ib*ipopt(2+ib)
526 ENDDO
527 ENDIF
528 ELSE
529 nb2=0
530 nb3=0
531 nb4=0
532 ENDIF
533 DO k=1,km
534 DO n=1,no
535 uo(n,k)=0
536 vo(n,k)=0
537 wo(n,k)=0.
538 ENDDO
539 ENDDO
540 ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
541 ! LOOP OVER SAMPLE POINTS IN OUTPUT GRID BOX
542 DO nb=1,nb3
543 ! LOCATE INPUT POINTS AND COMPUTE THEIR WEIGHTS AND ROTATIONS
544 jb=(nb-1)/nb2-nb1
545 ib=nb-(jb+nb1)*nb2-nb1-1
546 lb=max(abs(ib),abs(jb))
547 wb=1
548 IF(lsw.EQ.1) wb=ipopt(2+lb)
549 IF(wb.NE.0) THEN
550 DO n=1,no
551 xptb(n)=xpts(n)+ib/real(nb2)
552 yptb(n)=ypts(n)+jb/real(nb2)
553 ENDDO
554 CALL gdswzd(grid_out, 1,no,fill,xptb,yptb, &
555 rlob,rlab,nv)
556 CALL gdswzd(grid_in,-1,no,fill,xptb,yptb, &
557 rlob,rlab,nv)
558 IF(iret.EQ.0.AND.nv.EQ.0.AND.lb.EQ.0) iret=2
559 DO n=1,no
560 xi=xptb(n)
561 yi=yptb(n)
562 IF(xi.NE.fill.AND.yi.NE.fill) THEN
563 i1=nint(xi)
564 j1=nint(yi)
565 n11(n)=grid_in%field_pos(i1, j1)
566 IF(n11(n).GT.0) THEN
567 CALL movect(rlai(n11(n)),rloi(n11(n)),rlat(n),rlon(n),cm11,sm11)
568 c11(n)=cm11*croi(n11(n))+sm11*sroi(n11(n))
569 s11(n)=sm11*croi(n11(n))-cm11*sroi(n11(n))
570 ENDIF
571 ELSE
572 n11(n)=0
573 ENDIF
574 ENDDO
575 ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
576 ! INTERPOLATE WITH OR WITHOUT BITMAPS
577 DO k=1,km
578 DO n=1,no
579 IF(n11(n).GT.0) THEN
580 IF(ibi(k).EQ.0.OR.li(n11(n),k)) THEN
581 u11=c11(n)*ui(n11(n),k)-s11(n)*vi(n11(n),k)
582 v11=s11(n)*ui(n11(n),k)+c11(n)*vi(n11(n),k)
583 uo(n,k)=uo(n,k)+wb*u11
584 vo(n,k)=vo(n,k)+wb*v11
585 wo(n,k)=wo(n,k)+wb
586 ENDIF
587 ENDIF
588 ENDDO
589 ENDDO
590 ENDIF
591 ENDDO ! NB LOOP
592 ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
593 ! COMPUTE OUTPUT BITMAPS AND FIELDS
594 DO k=1,km
595 ibo(k)=ibi(k)
596 DO n=1,no
597 lo(n,k)=wo(n,k).GE.pmp*nb4
598 IF(lo(n,k)) THEN
599 uo(n,k)=uo(n,k)/wo(n,k)
600 vo(n,k)=vo(n,k)/wo(n,k)
601 urot=crot(n)*uo(n,k)-srot(n)*vo(n,k)
602 vrot=srot(n)*uo(n,k)+crot(n)*vo(n,k)
603 uo(n,k)=urot
604 vo(n,k)=vrot
605 ELSE
606 ibo(k)=1
607 uo(n,k)=0.
608 vo(n,k)=0.
609 ENDIF
610 ENDDO
611 ENDDO
612
613 select type(grid_out)
614 type is(ip_equid_cylind_grid)
615 CALL polfixv(no,mo,km,rlat,rlon,ibo,lo,uo,vo)
616 end select
617
618 ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
619 END SUBROUTINE interpolate_neighbor_budget_vector
620
621end module neighbor_budget_interp_mod
Driver module for gdswzd routines.
Definition: gdswzd_mod.f90:25