1module spectral_interp_mod
12 module procedure interpolate_spectral_scalar
13 module procedure interpolate_spectral_vector
17 module procedure polates4_grib1
18 module procedure polates4_grib2
22 module procedure polatev4_grib1
23 module procedure polatev4_grib2
28 subroutine interpolate_spectral_scalar(IPOPT,grid_in,grid_out, &
30 NO,RLAT,RLON,IBO,LO,GO,IRET)
31 INTEGER,
INTENT(IN ) :: IPOPT(20)
32 class(ip_grid),
intent(in) :: grid_in, grid_out
33 INTEGER,
INTENT(IN ) :: MI, MO
34 INTEGER,
INTENT(IN ) :: IBI(KM), KM
35 INTEGER,
INTENT( OUT) :: IBO(KM), IRET, NO
37 LOGICAL*1,
INTENT( OUT) :: LO(MO,KM)
39 REAL,
INTENT(IN ) :: GI(MI,KM)
40 REAL,
INTENT(INOUT) :: RLAT(MO),RLON(MO)
41 REAL,
INTENT( OUT) :: GO(MO,KM)
44 select type(desc_in => grid_in%descriptor)
46 select type(desc_out => grid_out%descriptor)
48 CALL polates4(ipopt,desc_in%gds,desc_out%gds,mi,mo,km,ibi,gi,no,rlat,rlon,ibo,lo,go,iret)
52 select type(desc_out => grid_out%descriptor)
54 CALL polates4(ipopt,desc_in%gdt_num,desc_in%gdt_tmpl,desc_in%gdt_len, &
55 desc_out%gdt_num,desc_out%gdt_tmpl,desc_out%gdt_len, &
56 mi,mo,km,ibi,gi,no,rlat,rlon,ibo,lo,go,iret)
61 end subroutine interpolate_spectral_scalar
64 subroutine interpolate_spectral_vector(IPOPT,grid_in,grid_out, &
66 NO,RLAT,RLON,CROT,SROT,IBO,LO,UO,VO,IRET)
67 class(ip_grid),
intent(in) :: grid_in, grid_out
68 INTEGER,
INTENT(IN ) :: IPOPT(20), IBI(KM)
69 INTEGER,
INTENT(IN ) :: KM, MI, MO
70 INTEGER,
INTENT( OUT) :: IRET, IBO(KM), NO
72 LOGICAL*1,
INTENT( OUT) :: LO(MO,KM)
74 REAL,
INTENT(IN ) :: UI(MI,KM),VI(MI,KM)
75 REAL,
INTENT( OUT) :: UO(MO,KM),VO(MO,KM)
76 REAL,
INTENT(INOUT) :: RLAT(MO),RLON(MO)
77 REAL,
INTENT( OUT) :: CROT(MO),SROT(MO)
80 select type(desc_in => grid_in%descriptor)
82 select type(desc_out => grid_out%descriptor)
84 CALL polatev4_grib1(ipopt,desc_in%gds,desc_out%gds,mi,mo,km,ibi,ui,vi,&
85 no,rlat,rlon,crot,srot,ibo,lo,uo,vo,iret)
89 select type(desc_out => grid_out%descriptor)
91 CALL polatev4(ipopt,desc_in%gdt_num,desc_in%gdt_tmpl,desc_in%gdt_len, &
92 desc_out%gdt_num,desc_out%gdt_tmpl,desc_out%gdt_len, &
94 no,rlat,rlon,crot,srot,ibo,lo,uo,vo,iret)
99 end subroutine interpolate_spectral_vector
102 SUBROUTINE polates4_grib2(IPOPT,IGDTNUMI,IGDTMPLI,IGDTLENI, &
103 IGDTNUMO,IGDTMPLO,IGDTLENO, &
105 NO,RLAT,RLON,IBO,LO,GO,IRET)
226 INTEGER,
INTENT(IN ) :: IGDTNUMI, IGDTLENI
227 INTEGER,
INTENT(IN ) :: IGDTMPLI(IGDTLENI)
228 INTEGER,
INTENT(IN ) :: IGDTNUMO, IGDTLENO
229 INTEGER,
INTENT(IN ) :: IGDTMPLO(IGDTLENO)
230 INTEGER,
INTENT(IN ) :: IPOPT(20)
231 INTEGER,
INTENT(IN ) :: MI, MO
232 INTEGER,
INTENT(IN ) :: IBI(KM), KM
233 INTEGER,
INTENT( OUT) :: IBO(KM), IRET, NO
235 LOGICAL*1,
INTENT( OUT) :: LO(MO,KM)
237 REAL,
INTENT(IN ) :: GI(MI,KM)
238 REAL,
INTENT(INOUT) :: RLAT(MO),RLON(MO)
239 REAL,
INTENT( OUT) :: GO(MO,KM)
241 REAL,
PARAMETER :: FILL=-9999.
242 REAL,
PARAMETER :: PI=3.14159265358979
243 REAL,
PARAMETER :: DPR=180./pi
245 INTEGER :: IDRTI, IDRTO, IG, JG, IM, JM
246 INTEGER :: IGO, JGO, IMO, JMO
247 INTEGER :: ISCAN, JSCAN, NSCAN
248 INTEGER :: ISCANO, JSCANO, NSCANO
249 INTEGER :: ISKIPI, JSKIPI, ISCALE
250 INTEGER :: IMAXI, JMAXI, ISPEC
251 INTEGER :: IP, IPRIME, IPROJ, IROMB, K
252 INTEGER :: MAXWV, N, NI, NJ, NPS
255 REAL :: DLAT, DLON, DLATO, DLONO
256 REAL :: GO2(MO,KM), H, HI, HJ
257 REAL :: ORIENT, SLAT, RERTH, E2
258 REAL :: RLAT1, RLON1, RLAT2, RLON2, RLATI
259 REAL :: XMESH, XP, YP
260 REAL :: XPTS(MO), YPTS(MO)
262 type(grib2_descriptor) :: desc_in, desc_out
263 class(ip_grid),
allocatable :: grid_in, grid_out
273 IF(igdtnumo.GE.0)
THEN
275 CALL gdswzd(grid_out, 0,mo,fill,xpts,ypts,rlon,rlat,no)
285 IF(idrti==40) idrti=4
286 IF(idrti==0.OR.idrti==4)
THEN
289 iscale=igdtmpli(10)*igdtmpli(11)
290 IF(iscale==0) iscale=10**6
291 rlon1=float(igdtmpli(13))/float(iscale)
292 rlon2=float(igdtmpli(16))/float(iscale)
293 iscan=mod(igdtmpli(19)/128,2)
294 jscan=mod(igdtmpli(19)/64,2)
295 nscan=mod(igdtmpli(19)/32,2)
300 IF(ibi(k).NE.0) iret=41
304 dlon=(mod(rlon2-rlon1-1+3600,360.)+1)/(im-1)
306 dlon=-(mod(rlon1-rlon2-1+3600,360.)+1)/(im-1)
308 ig=nint(360/abs(dlon))
309 iprime=1+mod(-nint(rlon1/dlon)+ig,ig)
312 IF(mod(ig,2).NE.0.OR.im.LT.ig) iret=41
314 IF(iret.EQ.0.AND.idrti.EQ.0)
THEN
315 iscale=igdtmpli(10)*igdtmpli(11)
316 IF(iscale==0) iscale=10**6
317 rlat1=float(igdtmpli(12))/float(iscale)
318 rlat2=float(igdtmpli(15))/float(iscale)
319 dlat=(rlat2-rlat1)/(jm-1)
320 jg=nint(180/abs(dlat))
321 IF(jm.EQ.jg) idrti=256
322 IF(jm.NE.jg.AND.jm.NE.jg+1) iret=41
323 ELSEIF(iret.EQ.0.AND.idrti.EQ.4)
THEN
333 IF(iromb.EQ.0.AND.idrti.EQ.4) maxwv=(jmaxi-1)
334 IF(iromb.EQ.1.AND.idrti.EQ.4) maxwv=(jmaxi-1)/2
335 IF(iromb.EQ.0.AND.idrti.EQ.0) maxwv=(jmaxi-3)/2
336 IF(iromb.EQ.1.AND.idrti.EQ.0) maxwv=(jmaxi-3)/4
337 IF(iromb.EQ.0.AND.idrti.EQ.256) maxwv=(jmaxi-1)/2
338 IF(iromb.EQ.1.AND.idrti.EQ.256) maxwv=(jmaxi-1)/4
340 IF((iromb.NE.0.AND.iromb.NE.1).OR.maxwv.LT.0) iret=42
352 IF(iscan.EQ.1) iskipi=-iskipi
353 IF(jscan.EQ.0) jskipi=-jskipi
356 IF((igdtnumo.EQ.0.OR.igdtnumo.EQ.40).AND. &
357 mod(igdtmplo(8),2).EQ.0.AND.igdtmplo(13).EQ.0.AND.igdtmplo(19).EQ.0)
THEN
362 iscale=igdtmplo(10)*igdtmplo(11)
363 IF(iscale==0) iscale=10**6
364 rlon2=float(igdtmplo(16))/float(iscale)
365 dlono=(mod(rlon2-1+3600,360.)+1)/(imo-1)
366 igo=nint(360/abs(dlono))
367 IF(imo.EQ.igo.AND.idrto.EQ.0)
THEN
368 rlat1=float(igdtmplo(12))/float(iscale)
369 rlat2=float(igdtmplo(15))/float(iscale)
370 dlat=(rlat2-rlat1)/(jmo-1)
371 jgo=nint(180/abs(dlat))
372 IF(jmo.EQ.jgo) idrto=256
373 IF(jmo.EQ.jgo.OR.jmo.EQ.jgo+1) ispec=1
374 ELSEIF(imo.EQ.igo.AND.idrto.EQ.4)
THEN
376 IF(jmo.EQ.jgo) ispec=1
379 CALL sptrun(iromb,maxwv,idrti,imaxi,jmaxi,idrto,imo,jmo, &
380 km,iprime,iskipi,jskipi,mi,0,0,mo,0,gi,go)
383 ELSEIF(igdtnumo.EQ.20.AND. &
384 igdtmplo(8).EQ.igdtmplo(9).AND.mod(igdtmplo(8),2).EQ.1.AND. &
385 igdtmplo(15).EQ.igdtmplo(16).AND.igdtmplo(18).EQ.64)
THEN
387 rlat1=float(igdtmplo(10))*1.e-6
388 rlon1=float(igdtmplo(11))*1.e-6
389 orient=float(igdtmplo(14))*1.e-6
390 xmesh=float(igdtmplo(15))*1.e-3
391 iproj=mod(igdtmplo(17)/128,2)
394 slat=float(abs(igdtmplo(13)))*1.e-6
395 CALL earth_radius(igdtmplo,igdtleno,rerth,e2)
396 de=(1.+sin(slat/dpr))*rerth
397 dr=de*cos(rlat1/dpr)/(1+h*sin(rlat1/dpr))
398 xp=1-h*sin((rlon1-orient)/dpr)*dr/xmesh
399 yp=1+cos((rlon1-orient)/dpr)*dr/xmesh
400 IF(nint(xp).EQ.ip.AND.nint(yp).EQ.ip)
THEN
402 CALL sptruns(iromb,maxwv,idrti,imaxi,jmaxi,km,nps, &
403 iprime,iskipi,jskipi,mi,mo,0,0,0, &
404 slat,xmesh,orient,gi,go,go2)
406 CALL sptruns(iromb,maxwv,idrti,imaxi,jmaxi,km,nps, &
407 iprime,iskipi,jskipi,mi,mo,0,0,0, &
408 slat,xmesh,orient,gi,go2,go)
413 ELSEIF(igdtnumo.EQ.10)
THEN
416 rlat1=float(igdtmplo(10))*1.0e-6
417 rlon1=float(igdtmplo(11))*1.0e-6
418 rlon2=float(igdtmplo(15))*1.0e-6
419 rlati=float(igdtmplo(13))*1.0e-6
420 iscano=mod(igdtmplo(16)/128,2)
421 jscano=mod(igdtmplo(16)/64,2)
422 nscano=mod(igdtmplo(16)/32,2)
423 dy=float(igdtmplo(19))*1.0e-3
426 CALL earth_radius(igdtmplo,igdtleno,rerth,e2)
427 dlono=hi*(mod(hi*(rlon2-rlon1)-1+3600,360.)+1)/(ni-1)
428 dlato=hj*dy/(rerth*cos(rlati/dpr))*dpr
430 CALL sptrunm(iromb,maxwv,idrti,imaxi,jmaxi,km,ni,nj, &
431 iprime,iskipi,jskipi,mi,mo,0,0,0, &
432 rlat1,rlon1,dlato,dlono,gi,go)
438 CALL sptrung(iromb,maxwv,idrti,imaxi,jmaxi,km,no, &
439 iprime,iskipi,jskipi,mi,mo,0,0,0,rlat,rlon,gi,go)
457 END SUBROUTINE polates4_grib2
536 SUBROUTINE polates4_grib1(IPOPT,KGDSI,KGDSO,MI,MO,KM,IBI,GI, &
537 NO,RLAT,RLON,IBO,LO,GO,IRET)
538 INTEGER,
INTENT(IN ) :: IPOPT(20), KGDSI(200)
539 INTEGER,
INTENT(IN ) :: KGDSO(200), MI, MO
540 INTEGER,
INTENT(IN ) :: IBI(KM), KM
541 INTEGER,
INTENT( OUT) :: IBO(KM), IRET
543 LOGICAL*1,
INTENT( OUT) :: LO(MO,KM)
545 REAL,
INTENT(IN ) :: GI(MI,KM)
546 REAL,
INTENT(INOUT) :: RLAT(MO),RLON(MO)
547 REAL,
INTENT( OUT) :: GO(MO,KM)
549 REAL,
PARAMETER :: FILL=-9999.
550 REAL,
PARAMETER :: RERTH=6.3712e6
551 REAL,
PARAMETER :: PI=3.14159265358979
552 REAL,
PARAMETER :: DPR=180./pi
554 INTEGER :: IDRTI, IDRTO, IG, JG, IM, JM
555 INTEGER :: IGO, JGO, IMO, JMO
556 INTEGER :: ISCAN, JSCAN, NSCAN
557 INTEGER :: ISCANO, JSCANO, NSCANO
558 INTEGER :: ISKIPI, JSKIPI
559 INTEGER :: IMAXI, JMAXI, ISPEC
560 INTEGER :: IP, IPRIME, IPROJ, IROMB, K
561 INTEGER :: MAXWV, N, NI, NJ, NPS, NO
564 REAL :: DLAT, DLON, DLATO, DLONO
565 REAL :: GO2(MO,KM), H, HI, HJ
567 REAL :: RLAT1, RLON1, RLAT2, RLON2, RLATI
568 REAL :: XMESH, XP, YP
569 REAL :: XPTS(MO), YPTS(MO)
572 class(
ip_grid),
allocatable :: grid_in, grid_out
583 IF(kgdso(1).GE.0)
THEN
584 CALL gdswzd(grid_out, 0,mo,fill,xpts,ypts,rlon,rlat,no)
598 iscan=mod(kgdsi(11)/128,2)
599 jscan=mod(kgdsi(11)/64,2)
600 nscan=mod(kgdsi(11)/32,2)
601 IF(idrti.NE.0.AND.idrti.NE.4) iret=41
603 IF(ibi(k).NE.0) iret=41
607 dlon=(mod(rlon2-rlon1-1+3600,360.)+1)/(im-1)
609 dlon=-(mod(rlon1-rlon2-1+3600,360.)+1)/(im-1)
611 ig=nint(360/abs(dlon))
612 iprime=1+mod(-nint(rlon1/dlon)+ig,ig)
615 IF(mod(ig,2).NE.0.OR.im.LT.ig) iret=41
617 IF(iret.EQ.0.AND.idrti.EQ.0)
THEN
620 dlat=(rlat2-rlat1)/(jm-1)
621 jg=nint(180/abs(dlat))
622 IF(jm.EQ.jg) idrti=256
623 IF(jm.NE.jg.AND.jm.NE.jg+1) iret=41
624 ELSEIF(iret.EQ.0.AND.idrti.EQ.4)
THEN
634 IF(iromb.EQ.0.AND.idrti.EQ.4) maxwv=(jmaxi-1)
635 IF(iromb.EQ.1.AND.idrti.EQ.4) maxwv=(jmaxi-1)/2
636 IF(iromb.EQ.0.AND.idrti.EQ.0) maxwv=(jmaxi-3)/2
637 IF(iromb.EQ.1.AND.idrti.EQ.0) maxwv=(jmaxi-3)/4
638 IF(iromb.EQ.0.AND.idrti.EQ.256) maxwv=(jmaxi-1)/2
639 IF(iromb.EQ.1.AND.idrti.EQ.256) maxwv=(jmaxi-1)/4
641 IF((iromb.NE.0.AND.iromb.NE.1).OR.maxwv.LT.0) iret=42
653 IF(iscan.EQ.1) iskipi=-iskipi
654 IF(jscan.EQ.0) jskipi=-jskipi
657 IF((kgdso(1).EQ.0.OR.kgdso(1).EQ.4).AND. &
658 mod(kgdso(2),2).EQ.0.AND.kgdso(5).EQ.0.AND.kgdso(11).EQ.0)
THEN
663 dlono=(mod(rlon2-1+3600,360.)+1)/(imo-1)
664 igo=nint(360/abs(dlono))
665 IF(imo.EQ.igo.AND.idrto.EQ.0)
THEN
668 dlat=(rlat2-rlat1)/(jmo-1)
669 jgo=nint(180/abs(dlat))
670 IF(jmo.EQ.jgo) idrto=256
671 IF(jmo.EQ.jgo.OR.jmo.EQ.jgo+1) ispec=1
672 ELSEIF(imo.EQ.igo.AND.idrto.EQ.4)
THEN
674 IF(jmo.EQ.jgo) ispec=1
677 CALL sptrun(iromb,maxwv,idrti,imaxi,jmaxi,idrto,imo,jmo, &
678 km,iprime,iskipi,jskipi,mi,0,0,mo,0,gi,go)
681 ELSEIF(kgdso(1).EQ.5.AND. &
682 kgdso(2).EQ.kgdso(3).AND.mod(kgdso(2),2).EQ.1.AND. &
683 kgdso(8).EQ.kgdso(9).AND.kgdso(11).EQ.64)
THEN
687 orient=kgdso(7)*1.e-3
689 iproj=mod(kgdso(10)/128,2)
692 de=(1.+sin(60./dpr))*rerth
693 dr=de*cos(rlat1/dpr)/(1+h*sin(rlat1/dpr))
694 xp=1-h*sin((rlon1-orient)/dpr)*dr/xmesh
695 yp=1+cos((rlon1-orient)/dpr)*dr/xmesh
696 IF(nint(xp).EQ.ip.AND.nint(yp).EQ.ip)
THEN
698 CALL sptruns(iromb,maxwv,idrti,imaxi,jmaxi,km,nps, &
699 iprime,iskipi,jskipi,mi,mo,0,0,0, &
700 60.,xmesh,orient,gi,go,go2)
702 CALL sptruns(iromb,maxwv,idrti,imaxi,jmaxi,km,nps, &
703 iprime,iskipi,jskipi,mi,mo,0,0,0, &
704 60.,xmesh,orient,gi,go2,go)
709 ELSEIF(kgdso(1).EQ.1)
THEN
716 iscano=mod(kgdso(11)/128,2)
717 jscano=mod(kgdso(11)/64,2)
718 nscano=mod(kgdso(11)/32,2)
722 dlono=hi*(mod(hi*(rlon2-rlon1)-1+3600,360.)+1)/(ni-1)
723 dlato=hj*dy/(rerth*cos(rlati/dpr))*dpr
725 CALL sptrunm(iromb,maxwv,idrti,imaxi,jmaxi,km,ni,nj, &
726 iprime,iskipi,jskipi,mi,mo,0,0,0, &
727 rlat1,rlon1,dlato,dlono,gi,go)
733 CALL sptrung(iromb,maxwv,idrti,imaxi,jmaxi,km,no, &
734 iprime,iskipi,jskipi,mi,mo,0,0,0,rlat,rlon,gi,go)
752 END SUBROUTINE polates4_grib1
755 SUBROUTINE polatev4_grib2(IPOPT,IGDTNUMI,IGDTMPLI,IGDTLENI, &
756 IGDTNUMO,IGDTMPLO,IGDTLENO, &
757 MI,MO,KM,IBI,UI,VI, &
758 NO,RLAT,RLON,CROT,SROT,IBO,LO,UO,VO,IRET)
904 INTEGER,
INTENT(IN ) :: IPOPT(20), IBI(KM)
905 INTEGER,
INTENT(IN ) :: KM, MI, MO
906 INTEGER,
INTENT( OUT) :: IRET, IBO(KM), NO
907 INTEGER,
INTENT(IN ) :: IGDTNUMI, IGDTLENI
908 INTEGER,
INTENT(IN ) :: IGDTMPLI(IGDTLENI)
909 INTEGER,
INTENT(IN ) :: IGDTNUMO, IGDTLENO
910 INTEGER,
INTENT(IN ) :: IGDTMPLO(IGDTLENO)
912 LOGICAL*1,
INTENT( OUT) :: LO(MO,KM)
914 REAL,
INTENT(IN ) :: UI(MI,KM),VI(MI,KM)
915 REAL,
INTENT( OUT) :: UO(MO,KM),VO(MO,KM)
916 REAL,
INTENT(INOUT) :: RLAT(MO),RLON(MO)
917 REAL,
INTENT( OUT) :: CROT(MO),SROT(MO)
919 REAL,
PARAMETER :: FILL=-9999.
920 REAL,
PARAMETER :: PI=3.14159265358979
921 REAL,
PARAMETER :: DPR=180./pi
923 INTEGER :: IDRTO, IROMB, ISKIPI, ISPEC
924 INTEGER :: IDRTI, IMAXI, JMAXI, IM, JM
925 INTEGER :: IPRIME, IG, IMO, JMO, IGO, JGO
926 INTEGER :: ISCAN, JSCAN, NSCAN
927 INTEGER :: ISCANO, JSCANO, NSCANO
928 INTEGER :: ISCALE, IP, IPROJ, JSKIPI, JG
929 INTEGER :: K, MAXWV, N, NI, NJ, NPS
931 REAL :: DLAT, DLON, DLATO, DLONO, DE, DR, DY
932 REAL :: DUM, E2, H, HI, HJ
933 REAL :: ORIENT, RERTH, SLAT
934 REAL :: RLAT1, RLON1, RLAT2, RLON2, RLATI
935 REAL :: UROT, VROT, UO2(MO,KM),VO2(MO,KM)
936 REAL :: XMESH, X, XP, YP, XPTS(MO),YPTS(MO)
939 class(
ip_grid),
allocatable :: grid_in, grid_out
950 IF(igdtnumo.GE.0)
THEN
951 CALL gdswzd(grid_out, 0,mo,fill,xpts,ypts, &
952 rlon,rlat,no,crot,srot)
962 IF(idrti==40) idrti=4
963 IF(idrti==0.OR.idrti==4)
THEN
966 iscale=igdtmpli(10)*igdtmpli(11)
967 IF(iscale==0) iscale=10**6
968 rlon1=float(igdtmpli(13))/float(iscale)
969 rlon2=float(igdtmpli(16))/float(iscale)
970 iscan=mod(igdtmpli(19)/128,2)
971 jscan=mod(igdtmpli(19)/64,2)
972 nscan=mod(igdtmpli(19)/32,2)
977 IF(ibi(k).NE.0) iret=41
981 dlon=(mod(rlon2-rlon1-1+3600,360.)+1)/(im-1)
983 dlon=-(mod(rlon1-rlon2-1+3600,360.)+1)/(im-1)
985 ig=nint(360/abs(dlon))
986 iprime=1+mod(-nint(rlon1/dlon)+ig,ig)
989 IF(mod(ig,2).NE.0.OR.im.LT.ig) iret=41
991 IF(iret.EQ.0.AND.idrti.EQ.0)
THEN
992 iscale=igdtmpli(10)*igdtmpli(11)
993 IF(iscale==0) iscale=10**6
994 rlat1=float(igdtmpli(12))/float(iscale)
995 rlat2=float(igdtmpli(15))/float(iscale)
996 dlat=(rlat2-rlat1)/(jm-1)
997 jg=nint(180/abs(dlat))
998 IF(jm.EQ.jg) idrti=256
999 IF(jm.NE.jg.AND.jm.NE.jg+1) iret=41
1000 ELSEIF(iret.EQ.0.AND.idrti.EQ.4)
THEN
1002 IF(jm.NE.jg) iret=41
1009 IF(maxwv.EQ.-1)
THEN
1010 IF(iromb.EQ.0.AND.idrti.EQ.4) maxwv=(jmaxi-1)
1011 IF(iromb.EQ.1.AND.idrti.EQ.4) maxwv=(jmaxi-1)/2
1012 IF(iromb.EQ.0.AND.idrti.EQ.0) maxwv=(jmaxi-3)/2
1013 IF(iromb.EQ.1.AND.idrti.EQ.0) maxwv=(jmaxi-3)/4
1014 IF(iromb.EQ.0.AND.idrti.EQ.256) maxwv=(jmaxi-1)/2
1015 IF(iromb.EQ.1.AND.idrti.EQ.256) maxwv=(jmaxi-1)/4
1017 IF((iromb.NE.0.AND.iromb.NE.1).OR.maxwv.LT.0) iret=42
1029 IF(iscan.EQ.1) iskipi=-iskipi
1030 IF(jscan.EQ.0) jskipi=-jskipi
1033 IF((igdtnumo.EQ.0.OR.igdtnumo.EQ.40).AND. &
1034 mod(igdtmplo(8),2).EQ.0.AND.igdtmplo(13).EQ.0.AND. &
1035 igdtmplo(19).EQ.0)
THEN
1037 IF(idrto==40)idrto=4
1040 iscale=igdtmplo(10)*igdtmplo(11)
1041 IF(iscale==0) iscale=10**6
1042 rlon2=float(igdtmplo(16))/float(iscale)
1043 dlono=(mod(rlon2-1+3600,360.)+1)/(imo-1)
1044 igo=nint(360/abs(dlono))
1045 IF(imo.EQ.igo.AND.idrto.EQ.0)
THEN
1046 rlat1=float(igdtmplo(12))/float(iscale)
1047 rlat2=float(igdtmplo(15))/float(iscale)
1048 dlat=(rlat2-rlat1)/(jmo-1)
1049 jgo=nint(180/abs(dlat))
1050 IF(jmo.EQ.jgo) idrto=256
1051 IF(jmo.EQ.jgo.OR.jmo.EQ.jgo+1) ispec=1
1052 ELSEIF(imo.EQ.igo.AND.idrto.EQ.4)
THEN
1054 IF(jmo.EQ.jgo) ispec=1
1057 CALL sptrunv(iromb,maxwv,idrti,imaxi,jmaxi,idrto,imo,jmo, &
1058 km,iprime,iskipi,jskipi,mi,0,0,mo,0,ui,vi, &
1059 .true.,uo,vo,.false.,dum,dum,.false.,dum,dum)
1062 ELSEIF(igdtnumo.EQ.20.AND. &
1063 igdtmplo(8).EQ.igdtmplo(9).AND.mod(igdtmplo(8),2).EQ.1.AND. &
1064 igdtmplo(15).EQ.igdtmplo(16).AND.igdtmplo(18).EQ.64.AND. &
1065 mod(igdtmplo(12)/8,2).EQ.1)
THEN
1067 rlat1=float(igdtmplo(10))*1.e-6
1068 rlon1=float(igdtmplo(11))*1.e-6
1069 orient=float(igdtmplo(14))*1.e-6
1070 xmesh=float(igdtmplo(15))*1.e-3
1071 iproj=mod(igdtmplo(17)/128,2)
1074 slat=float(abs(igdtmplo(13)))*1.e-6
1075 CALL earth_radius(igdtmplo,igdtleno,rerth,e2)
1076 de=(1.+sin(slat/dpr))*rerth
1077 dr=de*cos(rlat1/dpr)/(1+h*sin(rlat1/dpr))
1078 xp=1-h*sin((rlon1-orient)/dpr)*dr/xmesh
1079 yp=1+cos((rlon1-orient)/dpr)*dr/xmesh
1080 IF(nint(xp).EQ.ip.AND.nint(yp).EQ.ip)
THEN
1082 CALL sptrunsv(iromb,maxwv,idrti,imaxi,jmaxi,km,nps, &
1083 iprime,iskipi,jskipi,mi,mo,0,0,0, &
1084 slat,xmesh,orient,ui,vi,.true.,uo,vo,uo2,vo2, &
1085 .false.,dum,dum,dum,dum, &
1086 .false.,dum,dum,dum,dum)
1088 CALL sptrunsv(iromb,maxwv,idrti,imaxi,jmaxi,km,nps, &
1089 iprime,iskipi,jskipi,mi,mo,0,0,0, &
1090 slat,xmesh,orient,ui,vi,.true.,uo2,vo2,uo,vo, &
1091 .false.,dum,dum,dum,dum, &
1092 .false.,dum,dum,dum,dum)
1097 ELSEIF(igdtnumo.EQ.10)
THEN
1100 rlat1=float(igdtmplo(10))*1.0e-6
1101 rlon1=float(igdtmplo(11))*1.0e-6
1102 rlon2=float(igdtmplo(15))*1.0e-6
1103 rlati=float(igdtmplo(13))*1.0e-6
1104 iscano=mod(igdtmplo(16)/128,2)
1105 jscano=mod(igdtmplo(16)/64,2)
1106 nscano=mod(igdtmplo(16)/32,2)
1107 dy=float(igdtmplo(19))*1.0e-3
1109 hj=(-1.)**(1-jscano)
1110 CALL earth_radius(igdtmplo,igdtleno,rerth,e2)
1111 dlono=hi*(mod(hi*(rlon2-rlon1)-1+3600,360.)+1)/(ni-1)
1112 dlato=hj*dy/(rerth*cos(rlati/dpr))*dpr
1113 IF(nscano.EQ.0)
THEN
1114 CALL sptrunmv(iromb,maxwv,idrti,imaxi,jmaxi,km,ni,nj, &
1115 iprime,iskipi,jskipi,mi,mo,0,0,0, &
1116 rlat1,rlon1,dlato,dlono,ui,vi, &
1117 .true.,uo,vo,.false.,dum,dum,.false.,dum,dum)
1123 CALL sptrungv(iromb,maxwv,idrti,imaxi,jmaxi,km,no, &
1124 iprime,iskipi,jskipi,mi,mo,0,0,0,rlat,rlon, &
1125 ui,vi,.true.,uo,vo,.false.,x,x,.false.,x,x)
1130 urot=crot(n)*uo(n,k)-srot(n)*vo(n,k)
1131 vrot=srot(n)*uo(n,k)+crot(n)*vo(n,k)
1148 END SUBROUTINE polatev4_grib2
1241 SUBROUTINE polatev4_grib1(IPOPT,KGDSI,KGDSO,MI,MO,KM,IBI,UI,VI, &
1242 NO,RLAT,RLON,CROT,SROT,IBO,LO,UO,VO,IRET)
1243 INTEGER,
INTENT(IN ) :: IPOPT(20), IBI(KM)
1244 INTEGER,
INTENT(IN ) :: KM, MI, MO
1245 INTEGER,
INTENT( OUT) :: IRET, IBO(KM)
1246 INTEGER,
INTENT(IN) :: KGDSI(200),KGDSO(200)
1248 LOGICAL*1,
INTENT( OUT) :: LO(MO,KM)
1250 REAL,
INTENT(IN ) :: UI(MI,KM),VI(MI,KM)
1251 REAL,
INTENT( OUT) :: UO(MO,KM),VO(MO,KM)
1252 REAL,
INTENT(INOUT) :: RLAT(MO),RLON(MO)
1253 REAL,
INTENT( OUT) :: CROT(MO),SROT(MO)
1255 REAL,
PARAMETER :: FILL=-9999.
1256 REAL,
PARAMETER :: RERTH=6.3712e6
1257 REAL,
PARAMETER :: PI=3.14159265358979
1258 REAL,
PARAMETER :: DPR=180./pi
1260 INTEGER :: IDRTO, IROMB, ISKIPI, ISPEC
1261 INTEGER :: IDRTI, IMAXI, JMAXI, IM, JM
1262 INTEGER :: IPRIME, IG, IMO, JMO, IGO, JGO
1263 INTEGER :: ISCAN, JSCAN, NSCAN
1264 INTEGER :: ISCANO, JSCANO, NSCANO
1265 INTEGER :: IP, IPROJ, JSKIPI, JG
1266 INTEGER :: K, MAXWV, N, NI, NJ, NO, NPS
1268 REAL :: DLAT, DLON, DLATO, DLONO, DE, DR, DY
1269 REAL :: DUM, H, HI, HJ
1271 REAL :: RLAT1, RLON1, RLAT2, RLON2, RLATI
1272 REAL :: UROT, VROT, UO2(MO,KM),VO2(MO,KM)
1273 REAL :: XMESH, X, XP, YP, XPTS(MO),YPTS(MO)
1276 class(
ip_grid),
allocatable :: grid_in, grid_out
1286 IF(kgdso(1).GE.0)
THEN
1287 CALL gdswzd(grid_out, 0,mo,fill,xpts,ypts,rlon,rlat,no,crot,srot)
1299 rlon1=kgdsi(5)*1.e-3
1300 rlon2=kgdsi(8)*1.e-3
1301 iscan=mod(kgdsi(11)/128,2)
1302 jscan=mod(kgdsi(11)/64,2)
1303 nscan=mod(kgdsi(11)/32,2)
1304 IF(idrti.NE.0.AND.idrti.NE.4) iret=41
1306 IF(ibi(k).NE.0) iret=41
1310 dlon=(mod(rlon2-rlon1-1+3600,360.)+1)/(im-1)
1312 dlon=-(mod(rlon1-rlon2-1+3600,360.)+1)/(im-1)
1314 ig=nint(360/abs(dlon))
1315 iprime=1+mod(-nint(rlon1/dlon)+ig,ig)
1318 IF(mod(ig,2).NE.0.OR.im.LT.ig) iret=41
1320 IF(iret.EQ.0.AND.idrti.EQ.0)
THEN
1321 rlat1=kgdsi(4)*1.e-3
1322 rlat2=kgdsi(7)*1.e-3
1323 dlat=(rlat2-rlat1)/(jm-1)
1324 jg=nint(180/abs(dlat))
1325 IF(jm.EQ.jg) idrti=256
1326 IF(jm.NE.jg.AND.jm.NE.jg+1) iret=41
1327 ELSEIF(iret.EQ.0.AND.idrti.EQ.4)
THEN
1329 IF(jm.NE.jg) iret=41
1336 IF(maxwv.EQ.-1)
THEN
1337 IF(iromb.EQ.0.AND.idrti.EQ.4) maxwv=(jmaxi-1)
1338 IF(iromb.EQ.1.AND.idrti.EQ.4) maxwv=(jmaxi-1)/2
1339 IF(iromb.EQ.0.AND.idrti.EQ.0) maxwv=(jmaxi-3)/2
1340 IF(iromb.EQ.1.AND.idrti.EQ.0) maxwv=(jmaxi-3)/4
1341 IF(iromb.EQ.0.AND.idrti.EQ.256) maxwv=(jmaxi-1)/2
1342 IF(iromb.EQ.1.AND.idrti.EQ.256) maxwv=(jmaxi-1)/4
1344 IF((iromb.NE.0.AND.iromb.NE.1).OR.maxwv.LT.0) iret=42
1356 IF(iscan.EQ.1) iskipi=-iskipi
1357 IF(jscan.EQ.0) jskipi=-jskipi
1360 IF((kgdso(1).EQ.0.OR.kgdso(1).EQ.4).AND. &
1361 mod(kgdso(2),2).EQ.0.AND.kgdso(5).EQ.0.AND. &
1362 kgdso(11).EQ.0)
THEN
1366 rlon2=kgdso(8)*1.e-3
1367 dlono=(mod(rlon2-1+3600,360.)+1)/(imo-1)
1368 igo=nint(360/abs(dlono))
1369 IF(imo.EQ.igo.AND.idrto.EQ.0)
THEN
1370 rlat1=kgdso(4)*1.e-3
1371 rlat2=kgdso(7)*1.e-3
1372 dlat=(rlat2-rlat1)/(jmo-1)
1373 jgo=nint(180/abs(dlat))
1374 IF(jmo.EQ.jgo) idrto=256
1375 IF(jmo.EQ.jgo.OR.jmo.EQ.jgo+1) ispec=1
1376 ELSEIF(imo.EQ.igo.AND.idrto.EQ.4)
THEN
1378 IF(jmo.EQ.jgo) ispec=1
1381 CALL sptrunv(iromb,maxwv,idrti,imaxi,jmaxi,idrto,imo,jmo, &
1382 km,iprime,iskipi,jskipi,mi,0,0,mo,0,ui,vi, &
1383 .true.,uo,vo,.false.,dum,dum,.false.,dum,dum)
1386 ELSEIF(kgdso(1).EQ.5.AND. &
1387 kgdso(2).EQ.kgdso(3).AND.mod(kgdso(2),2).EQ.1.AND. &
1388 kgdso(8).EQ.kgdso(9).AND.kgdso(11).EQ.64.AND. &
1389 mod(kgdso(6)/8,2).EQ.1)
THEN
1391 rlat1=kgdso(4)*1.e-3
1392 rlon1=kgdso(5)*1.e-3
1393 orient=kgdso(7)*1.e-3
1395 iproj=mod(kgdso(10)/128,2)
1398 de=(1.+sin(60./dpr))*rerth
1399 dr=de*cos(rlat1/dpr)/(1+h*sin(rlat1/dpr))
1400 xp=1-h*sin((rlon1-orient)/dpr)*dr/xmesh
1401 yp=1+cos((rlon1-orient)/dpr)*dr/xmesh
1402 IF(nint(xp).EQ.ip.AND.nint(yp).EQ.ip)
THEN
1404 CALL sptrunsv(iromb,maxwv,idrti,imaxi,jmaxi,km,nps, &
1405 iprime,iskipi,jskipi,mi,mo,0,0,0, &
1406 60.,xmesh,orient,ui,vi,.true.,uo,vo,uo2,vo2, &
1407 .false.,dum,dum,dum,dum, &
1408 .false.,dum,dum,dum,dum)
1410 CALL sptrunsv(iromb,maxwv,idrti,imaxi,jmaxi,km,nps, &
1411 iprime,iskipi,jskipi,mi,mo,0,0,0, &
1412 60.,xmesh,orient,ui,vi,.true.,uo2,vo2,uo,vo, &
1413 .false.,dum,dum,dum,dum, &
1414 .false.,dum,dum,dum,dum)
1419 ELSEIF(kgdso(1).EQ.1)
THEN
1422 rlat1=kgdso(4)*1.e-3
1423 rlon1=kgdso(5)*1.e-3
1424 rlon2=kgdso(8)*1.e-3
1425 rlati=kgdso(9)*1.e-3
1426 iscano=mod(kgdso(11)/128,2)
1427 jscano=mod(kgdso(11)/64,2)
1428 nscano=mod(kgdso(11)/32,2)
1431 hj=(-1.)**(1-jscano)
1432 dlono=hi*(mod(hi*(rlon2-rlon1)-1+3600,360.)+1)/(ni-1)
1433 dlato=hj*dy/(rerth*cos(rlati/dpr))*dpr
1434 IF(nscano.EQ.0)
THEN
1435 CALL sptrunmv(iromb,maxwv,idrti,imaxi,jmaxi,km,ni,nj, &
1436 iprime,iskipi,jskipi,mi,mo,0,0,0, &
1437 rlat1,rlon1,dlato,dlono,ui,vi, &
1438 .true.,uo,vo,.false.,dum,dum,.false.,dum,dum)
1444 CALL sptrungv(iromb,maxwv,idrti,imaxi,jmaxi,km,no, &
1445 iprime,iskipi,jskipi,mi,mo,0,0,0,rlat,rlon, &
1446 ui,vi,.true.,uo,vo,.false.,x,x,.false.,x,x)
1451 urot=crot(n)*uo(n,k)-srot(n)*vo(n,k)
1452 vrot=srot(n)*uo(n,k)+crot(n)*vo(n,k)
1469 END SUBROUTINE polatev4_grib1
1473end module spectral_interp_mod
Driver module for gdswzd routines.
Uses derived type grid descriptor objects to abstract away the raw Grib-1 and Grib-2 grid definitions...
Routines for creating an ip_grid given a Grib descriptor.
Descriptor representing a grib1 grib descriptor section (GDS) with an integer array.
Grib-2 descriptor containing a grib2 GDT represented by an integer array.
Abstract grid that holds fields and methods common to all grids.