Bilinear interpolation package:
GRID2INDX, PNTS2INDX, and INDXMULT

Fortran version:

"Generic" Fortran-90 routines GRID2INDX, PNTS2INDX with optional SPHER1, SPHER2 spheroid arguments for computing bilinear interpolation indices and coefficients; single-layer and multi-layer OpenMP parallel bilinear-matrix multiplication routine INDXMULT:
    SUBROUTINE GRID2INDX( GDTYP1, P_ALP1, P_BET1, P_GAM1, XCENT1, YCENT1,   &
                          GDTYP2, P_ALP2, P_BET2, P_GAM2, XCENT2, YCENT2,   &
                          NCOLS1, NROWS1, XORIG1, YORIG1, XCELL1, YCELL1,   &
                          NCOLS2, NROWS2, XORIG2, YORIG2, XCELL2, YCELL2,   &
                          IX2, PX2, PY2 )
    SUBROUTINE GRID2INDX( GDTYP1, P_ALP1, P_BET1, P_GAM1, XCENT1, YCENT1, SPHER1,  &
                          GDTYP2, P_ALP2, P_BET2, P_GAM2, XCENT2, YCENT2, SPHER2,  &
                          NCOLS1, NROWS1, XORIG1, YORIG1, XCELL1, YCELL1,          &
                          NCOLS2, NROWS2, XORIG2, YORIG2, XCELL2, YCELL2,          &
                          IX2, PX2, PY2 )
        INTEGER, INTENT(IN   ) :: GDTYP1, GDTYP2
        INTEGER, INTENT(IN   ) :: NCOLS2, NROWS2
        REAL*8 , INTENT(IN   ) :: SPHER1, SPHER2        !!  input, output spheres
        REAL*8 , INTENT(IN   ) :: P_ALP1, P_BET1, P_GAM1, XCENT1, YCENT1
        REAL*8 , INTENT(IN   ) :: P_ALP2, P_BET2, P_GAM2, XCENT2, YCENT2
        REAL*8 , INTENT(IN   ) :: XORIG2, YORIG2, XCELL2, YCELL2
        INTEGER, INTENT(  OUT) :: IX2( NPNTS2 )
        REAL   , INTENT(  OUT) :: PX2( NPNTS2 )
        REAL   , INTENT(  OUT) :: PY2( NPNTS2 )

    SUBROUTINE PNTS2INDX( GDTYP1, P_ALP1, P_BET1, P_GAM1, XCENT1, YCENT1,      &
                          GDTYP2, P_ALP2, P_BET2, P_GAM2, XCENT2, YCENT2,      &
                          NCOLS1, NROWS1, XORIG1, YORIG1, XCELL1, YCELL1,      &
                          NPNTS2, XPNTS2, YPNTS2,                              &
                          IX2, PX2, PY2 )
    SUBROUTINE PNTS2INDX( GDTYP1, P_ALP1, P_BET1, P_GAM1, XCENT1, YCENT1, SPHER1,  &
                          GDTYP2, P_ALP2, P_BET2, P_GAM2, XCENT2, YCENT2, SPHER2,  &
                          NCOLS1, NROWS1, XORIG1, YORIG1, XCELL1, YCELL1,          &
                          NPNTS2, XPNTS2, YPNTS2,                                  &
                          IX2, PX2, PY2 )
        INTEGER, INTENT(IN   ) :: GDTYP1, GDTYP2
        INTEGER, INTENT(IN   ) :: NCOLS1, NROWS1, NPNTS2
        REAL*8 , INTENT(IN   ) :: SPHER1, SPHER2        !!  input, output spheres
        REAL*8 , INTENT(IN   ) :: P_ALP1, P_BET1, P_GAM1, XCENT1, YCENT1
        REAL*8 , INTENT(IN   ) :: P_ALP2, P_BET2, P_GAM2, XCENT2, YCENT2
        REAL*8 , INTENT(IN   ) :: XORIG1, YORIG1, XCELL1, YCELL1
        REAL*8 , INTENT(IN   ) :: XPNTS2( NPNTS2 ),  YPNTS2( NPNTS2 ) YCENT2
        REAL*8 , INTENT(IN   ) :: XORIG2, YORIG2, XCELL2, YCELL2
        INTEGER, INTENT(  OUT) :: IX2( NPNTS2 )
        REAL   , INTENT(  OUT) :: PX2( NPNTS2 )
        REAL   , INTENT(  OUT) :: PY2( NPNTS2 )

    SUBROUTINE INDXMULT( NSIZE1, NCOLS2, NROWS2,    &
                         IX1, PX1, PY1, GR1, GR2 )
    SUBROUTINE INDXMULT( NSIZE1, NLAYS, NCOLS2, NROWS2,    &
                         IX1, PX1, PY1, GR3, GR4 )
    SUBROUTINE INDXMULT( NCOLS1, NROWS1, NLAYS, NCOLS2, NROWS2,    &
                         IX5, PX5, PY5, GR5, GR6 )
        INTEGER, INTENT(IN   ) :: NSIZE1
        INTEGER, INTENT(IN   ) :: NLAYS
        INTEGER, INTENT(IN   ) :: NCOLS2, NROWS2
        INTEGER, INTENT(IN   ) :: IX1( NSIZE1 )
        REAL   , INTENT(IN   ) :: PX1( NSIZE1 )
        REAL   , INTENT(IN   ) :: PY1( NSIZE1 )
        INTEGER, INTENT(IN   ) :: IX5( NCOLS1*NROWS1 )
        REAL   , INTENT(IN   ) :: PX5( NCOLS1*NROWS1 )
        REAL   , INTENT(IN   ) :: PY5( NCOLS1*NROWS1 )
        REAL   , INTENT(  OUT) :: GR1( NSIZE1 )                 !!  single-indexed 1-D or 2-D
        REAL   , INTENT(IN   ) :: GR2( NCOLS2*NROWS2 )
        REAL   , INTENT(  OUT) :: GR3( NSIZE1,NLAYS )
        REAL   , INTENT(IN   ) :: GR4( NCOLS2*NROWS2,NLAYS )    !!  single-indexed layered
        REAL   , INTENT(  OUT) :: GR5( NCOLS1,NROWS1,NLAYS )
        REAL   , INTENT(IN   ) :: GR6( NCOLS2,NROWS2,NLAYS )    !!  double-indexed 3-D layered

Compute single-indexed, single-indexed-layered, double-indexed-layered (3-D-gridded) array subscript IX and bilinear interpolation fractions PX, PY for GRID2 nodes or array of point-locations relative to GRID1 using USGS GCTP-package routine GTPZ0(), and use them for bilinear interpolation.

Whenever the requested points lie outside the data-grid, the interpolation will use the nearest boundary cell of the data-grid to determine the output value (i.e., the interpolation uses "extend-by-constant" outside GRID1.

Use routine INITSPHERES() (controlled by environment variable IOAPI_ISPH) to determine the spheroid used by the map projections,

NOTE: The GRID1-vs-GRID2 issue for GRID2INDX() and PNTS2INDX() is "backward" to the naive intuition: to interpolate data-grids from GRID1 to GRID2, one needs to compute the locations of GRID2-nodes relative to the GRID1 coordinate-and-grid system—a coordinate transformation in the reverse of the direction of the data-interpolation.

Summary:

For I/O API Version 3.2 or later, only: module-routines contained in MODULE MODGCTP..

Preconditions

USE MODGCTGP

CALL INITSPHERES() or CALL SETSPHERE() before using.

Fortran Usage:

Interpolate and from GRID2 to GRID1, as indicated below, or see m3tools program mcple for a full-program example.
    ...
    INTEGER     GDTYP1      !!  parameters for output coordinate system
    REAL*8      P_ALP1
    REAL*8      P_BET1
    REAL*8      P_GAM1
    REAL*8      XCENT1
    REAL*8      YCENT1
    INTEGER     NCOLS1
    INTEGER     NROWS1
    INTEGER     NLAYS1
    INTEGER     GDTYP2      !!  parameters for input grid and coord system
    INTEGER     NCOLS2
    INTEGER     NROWS2
    INTEGER     NTHIK2
    REAL*8      P_ALP2
    REAL*8      P_BET2
    REAL*8      P_GAM2
    REAL*8      XCENT2
    REAL*8      YCENT2
    REAL*8      XORIG2
    REAL*8      YORIG2
    REAL*8      XCELL2
    REAL*8      YCELL2
    ...
    INTEGER     IX2( NCOLS2*NROWS2 )
    REAL*8      PX2( NCOLS2*NROWS2 )
    REAL*8      PY2( NCOLS2*NROWS2 )
    ...
    REAL*8      TVALS1( NCOLS1*NROWS1 )
    REAL*8      TVALS2( NCOLS2*NROWS2 )
    REAL*8      ZVALS1( NCOLS1,NROWS1,NLAYS1 )
    REAL*8      ZVALS2( NCOLS2,NROWS2,NLAYS1 )
    ...
    CALL GRID2INDX( GDTYP1, P_ALP1, P_BET1, P_GAM1, XCENT1, YCENT1,      &
                    GDTYP2, P_ALP2, P_BET2, P_GAM2, XCENT2, YCENT2,      &
                    NCOLS1, NROWS1, XORIG1, YORIG1, XCELL1, YCELL1,      &
                    NCOLS2, NROWS2, XORIG2, YORIG2, XCELL2, YCELL2,      &
                    IX2, PX2, PY2 )
    ...
    CALL INDXMULT( NCOLS1*NROWS1, NCOLS2, NROWS2, IX1, PX1, PY1, TVALS1, TVALS2 )
    ...
    CALL INDXMULT( NCOLS1, NROWS1, NLAYS1, NCOLS2, NROWS2, IX1, PX1, PY1, ZVALS1, ZVALS2 )
    ...
    

See also:


Up: MODULE MODGCTP

Up: Coordinate and Grid Related Routines

To: Models-3/EDSS I/O API: The Help Pages