MODULE module_interp_info 4
     INTEGER , PARAMETER :: NOT_DEFINED_YET    = 0
     INTEGER , PARAMETER :: BILINEAR           = 1
     INTEGER , PARAMETER :: SINT               = 2
     INTEGER , PARAMETER :: NEAREST_NEIGHBOR   = 3
     INTEGER , PARAMETER :: QUADRATIC          = 4
     INTEGER , PARAMETER :: SPLINE             = 5
     INTEGER , PARAMETER :: SINT_NEW           = 12

     INTEGER             :: interp_method_type = 0
CONTAINS

   SUBROUTINE interp_info_init 1
#if (EM_CORE == 1)
     CALL nl_get_interp_method_type ( 1 , interp_method_type )
#else
     interp_method_type = 2
#endif
   END SUBROUTINE interp_info_init
END MODULE module_interp_info

!WRF:MEDIATION_LAYER:INTERPOLATIONFUNCTION
!
!

!=========================================================================


   SUBROUTINE interp_init 1,2
      USE module_interp_info
      CALL interp_info_init
   END SUBROUTINE interp_init

!=========================================================================

#if ! defined(NMM_CORE) || NMM_CORE!=1

   SUBROUTINE interp_fcn    ( cfld,                                 &  ! CD field 2,6
                              cids, cide, ckds, ckde, cjds, cjde,   &
                              cims, cime, ckms, ckme, cjms, cjme,   &
                              cits, cite, ckts, ckte, cjts, cjte,   &
                              nfld,                                 &  ! ND field
                              nids, nide, nkds, nkde, njds, njde,   &
                              nims, nime, nkms, nkme, njms, njme,   &
                              nits, nite, nkts, nkte, njts, njte,   &
                              shw,                                  &  ! stencil half width for interp
                              imask,                                &  ! interpolation mask
                              xstag, ystag,                         &  ! staggering of field
                              ipos, jpos,                           &  ! Position of lower left of nest in CD
                              nri, nrj                              )  ! Nest ratio, i- and j-directions

     USE module_interp_info      

     IMPLICIT NONE

     INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
                            cims, cime, ckms, ckme, cjms, cjme,   &
                            cits, cite, ckts, ckte, cjts, cjte,   &
                            nids, nide, nkds, nkde, njds, njde,   &
                            nims, nime, nkms, nkme, njms, njme,   &
                            nits, nite, nkts, nkte, njts, njte,   &
                            shw,                                  &
                            ipos, jpos,                           &
                            nri, nrj
     LOGICAL, INTENT(IN) :: xstag, ystag

     REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ) :: cfld
     REAL, DIMENSION ( nims:nime, nkms:nkme, njms:njme ) :: nfld
     INTEGER, DIMENSION ( nims:nime, njms:njme ) :: imask

     IF      ( interp_method_type .EQ. NOT_DEFINED_YET  ) THEN
        interp_method_type = SINT
     END IF

     IF      ( interp_method_type .EQ. BILINEAR         ) THEN
       CALL interp_fcn_blint ( cfld,                                 &  ! CD field
                               cids, cide, ckds, ckde, cjds, cjde,   &
                               cims, cime, ckms, ckme, cjms, cjme,   &
                               cits, cite, ckts, ckte, cjts, cjte,   &
                               nfld,                                 &  ! ND field
                               nids, nide, nkds, nkde, njds, njde,   &
                               nims, nime, nkms, nkme, njms, njme,   &
                               nits, nite, nkts, nkte, njts, njte,   &
                               shw,                                  &  ! stencil half width for interp
                               imask,                                &  ! interpolation mask
                               xstag, ystag,                         &  ! staggering of field
                               ipos, jpos,                           &  ! Position of lower left of nest in CD
                               nri, nrj)                                ! Nest ratio, i- and j-directions
     ELSE IF ( MOD(interp_method_type,10) .EQ. SINT             ) THEN
       CALL interp_fcn_sint  ( cfld,                                 &  ! CD field
                               cids, cide, ckds, ckde, cjds, cjde,   &
                               cims, cime, ckms, ckme, cjms, cjme,   &
                               cits, cite, ckts, ckte, cjts, cjte,   &
                               nfld,                                 &  ! ND field
                               nids, nide, nkds, nkde, njds, njde,   &
                               nims, nime, nkms, nkme, njms, njme,   &
                               nits, nite, nkts, nkte, njts, njte,   &
                               shw,                                  &  ! stencil half width for interp
                               imask,                                &  ! interpolation mask
                               xstag, ystag,                         &  ! staggering of field
                               ipos, jpos,                           &  ! Position of lower left of nest in CD
                               nri, nrj)                                ! Nest ratio, i- and j-directions
     ELSE IF ( interp_method_type .EQ. NEAREST_NEIGHBOR ) THEN
       CALL interp_fcn_nn    ( cfld,                                 &  ! CD field
                               cids, cide, ckds, ckde, cjds, cjde,   &
                               cims, cime, ckms, ckme, cjms, cjme,   &
                               cits, cite, ckts, ckte, cjts, cjte,   &
                               nfld,                                 &  ! ND field
                               nids, nide, nkds, nkde, njds, njde,   &
                               nims, nime, nkms, nkme, njms, njme,   &
                               nits, nite, nkts, nkte, njts, njte,   &
                               shw,                                  &  ! stencil half width for interp
                               imask,                                &  ! interpolation mask
                               xstag, ystag,                         &  ! staggering of field
                               ipos, jpos,                           &  ! Position of lower left of nest in CD
                               nri, nrj)                                ! Nest ratio, i- and j-directions
     ELSE IF ( interp_method_type .EQ. QUADRATIC        ) THEN
       CALL interp_fcn_lagr  ( cfld,                                 &  ! CD field
                               cids, cide, ckds, ckde, cjds, cjde,   &
                               cims, cime, ckms, ckme, cjms, cjme,   &
                               cits, cite, ckts, ckte, cjts, cjte,   &
                               nfld,                                 &  ! ND field
                               nids, nide, nkds, nkde, njds, njde,   &
                               nims, nime, nkms, nkme, njms, njme,   &
                               nits, nite, nkts, nkte, njts, njte,   &
                               shw,                                  &  ! stencil half width for interp
                               imask,                                &  ! interpolation mask
                               xstag, ystag,                         &  ! staggering of field
                               ipos, jpos,                           &  ! Position of lower left of nest in CD
                               nri, nrj)                                ! Nest ratio, i- and j-directions
     ELSE
        CALL wrf_error_fatal ('Hold on there cowboy, we need to know which interpolation option you want')
     END IF

   END SUBROUTINE interp_fcn

!=========================================================================

! Overlapping linear horizontal iterpolation for mass, u, and v staggerings.


   SUBROUTINE interp_fcn_blint    ( cfld,                                 &  ! CD field 1
                              cids, cide, ckds, ckde, cjds, cjde,   &
                              cims, cime, ckms, ckme, cjms, cjme,   &
                              cits, cite, ckts, ckte, cjts, cjte,   &
                              nfld,                                 &  ! ND field
                              nids, nide, nkds, nkde, njds, njde,   &
                              nims, nime, nkms, nkme, njms, njme,   &
                              nits, nite, nkts, nkte, njts, njte,   &
                              shw,                                  &  ! stencil half width for interp
                              imask,                                &  ! interpolation mask
                              xstag, ystag,                         &  ! staggering of field
                              ipos, jpos,                           &  ! Position of lower left of nest in CD
                              nri, nrj)                                ! Nest ratio, i- and j-directions

     IMPLICIT NONE

     INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
                            cims, cime, ckms, ckme, cjms, cjme,   &
                            cits, cite, ckts, ckte, cjts, cjte,   &
                            nids, nide, nkds, nkde, njds, njde,   &
                            nims, nime, nkms, nkme, njms, njme,   &
                            nits, nite, nkts, nkte, njts, njte,   &
                            shw,                                  &
                            ipos, jpos,                           &
                            nri, nrj
     LOGICAL, INTENT(IN) :: xstag, ystag

     REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ) :: cfld
     REAL, DIMENSION ( nims:nime, nkms:nkme, njms:njme ) :: nfld
     INTEGER, DIMENSION ( nims:nime, njms:njme ) :: imask

     ! Local

     INTEGER ci, cj, ck, ni, nj, nk, istag, jstag, ioff, joff, i, j, k
     REAL :: wx, wy, cfld_ll, cfld_lr, cfld_ul, cfld_ur
     REAL :: cxp0, cxp1, nx, cyp0, cyp1, ny

     !  Fortran functions.  Yes, yes, I know, probably pretty slow.

     REAL, EXTERNAL :: nest_loc_of_cg
     INTEGER, EXTERNAL :: compute_CGLL

     !  This stag stuff is to keep us away from the outer most row
     !  and column for the unstaggered directions.  We are going to 
     !  consider "U" an xstag variable and "V" a ystag variable.  The
     !  vertical staggering is handled in the actual arguments.  The
     !  ckte and nkte are the ending vertical dimensions for computations
     !  for this particular variable.

     IF ( xstag ) THEN
        istag = 0 
        ioff  = 1
     ELSE
        istag = 1
        ioff  = 0
     END IF

     IF ( ystag ) THEN
        jstag = 0 
        joff  = 1
     ELSE
        jstag = 1
        joff  = 0
     END IF

     !  Loop over each j-index on this tile for the nested domain.

     j_loop : DO nj = njts, MIN(njde-jstag,njte)

        !  This is the lower-left j-index of the CG.

        !  Example is 3:1 ratio, mass-point staggering.  We have listed six CG values
        !  as an example: A, B, C, D, E, F.  For a 3:1 ratio, each of these CG cells has
        !  nine associated FG points.
        !  |=========|=========|=========|
        !  | -  -  - | -  -  - | -  -  - |
        !  |         |         |         |
        !  | -  D  - | -  E  - | -  F  - |
        !  |         |         |         |
        !  | 1  2  3 | 4  5  6 | 7  8  9 |
        !  |=========|=========|=========|
        !  | -  -  - | -  -  - | -  -  - |
        !  |         |         |         |
        !  | -  A  - | -  B  - | -  C  - |
        !  |         |         |         |
        !  | -  -  - | -  -  - | -  -  - |
        !  |=========|=========|=========|
        !  To interpolate to FG point 4, we will use CG points: A, B, D, E.  It is adequate to
        !  find the lower left point.  The lower left (LL) point for "4" is "A".  Below
        !  are a few more points.
        !  2 => A
        !  3 => A
        !  4 => A
        !  5 => B
        !  6 => B
        !  7 => B

        cj = compute_CGLL ( nj , jpos , nrj , jstag )
        ny = REAL(nj)
        cyp0 = nest_loc_of_cg ( cj   , jpos , nrj , joff ) 
        cyp1 = nest_loc_of_cg ( cj+1 , jpos , nrj , joff ) 

        !  What is the weighting for this CG point to the FG point, j-weight only.

        wy = ( cyp1 - ny ) / ( cyp1 - cyp0 )

        !  Vertical dim of the nest domain.

        k_loop : DO nk = nkts, nkte

          !  Loop over each i-index on this tile for the nested domain.

           i_loop : DO ni = nits, MIN(nide-istag,nite)

              IF ( imask ( ni, nj ) .EQ. 1 ) THEN
 
                 !  The coarse grid location that is to the lower left of the FG point.
   
                 ci = compute_CGLL ( ni , ipos , nri , istag )
                 nx = REAL(ni)
                 cxp0 = nest_loc_of_cg ( ci   , ipos , nri , ioff ) 
                 cxp1 = nest_loc_of_cg ( ci+1 , ipos , nri , ioff ) 
   
                 wx = ( cxp1 - nx ) / ( cxp1 - cxp0 )
   
                 !  The four surrounding CG values.
   
                 cfld_ll = cfld(ci  ,nk,cj  )
                 cfld_lr = cfld(ci+1,nk,cj  )
                 cfld_ul = cfld(ci  ,nk,cj+1)
                 cfld_ur = cfld(ci+1,nk,cj+1)

                 !  Bilinear interpolation in horizontal.

                 nfld( ni , nk , nj ) =     wy  * ( cfld_ll * wx + cfld_lr * (1.-wx) ) + &
                                        (1.-wy) * ( cfld_ul * wx + cfld_ur * (1.-wx) )

              END IF
           END DO i_loop
        END DO    k_loop
     END DO       j_loop

   END SUBROUTINE interp_fcn_blint

!=========================================================================

! Overlapping linear horizontal iterpolation for longitude


   SUBROUTINE interp_fcn_blint_ll    ( cfld_inp,                                 &  ! CD field,1
                              cids, cide, ckds, ckde, cjds, cjde,   &
                              cims, cime, ckms, ckme, cjms, cjme,   &
                              cits, cite, ckts, ckte, cjts, cjte,   &
                              nfld,                                 &  ! ND field
                              nids, nide, nkds, nkde, njds, njde,   &
                              nims, nime, nkms, nkme, njms, njme,   &
                              nits, nite, nkts, nkte, njts, njte,   &
                              shw,                                  &  ! stencil half width for interp
                              imask,                                &  ! interpolation mask
                              xstag, ystag,                         &  ! staggering of field
                              ipos, jpos,                           &  ! Position of lower left of nest in CD
                              nri, nrj,                             &  ! Nest ratio, i- and j-directions
                              clat_in, nlat_in,                     & ! CG, FG latitude
                              cinput_from_file, ninput_from_file )    ! CG, FG T/F input from file

     IMPLICIT NONE

     INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
                            cims, cime, ckms, ckme, cjms, cjme,   &
                            cits, cite, ckts, ckte, cjts, cjte,   &
                            nids, nide, nkds, nkde, njds, njde,   &
                            nims, nime, nkms, nkme, njms, njme,   &
                            nits, nite, nkts, nkte, njts, njte,   &
                            shw,                                  &
                            ipos, jpos,                           &
                            nri, nrj
     LOGICAL, INTENT(IN) :: xstag, ystag

     REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ) :: cfld_inp, cfld
     REAL, DIMENSION ( nims:nime, nkms:nkme, njms:njme ) :: nfld
     REAL, DIMENSION ( cims:cime,            cjms:cjme ) :: clat_in
     REAL, DIMENSION ( nims:nime,            njms:njme ) :: nlat_in
     INTEGER, DIMENSION ( nims:nime, njms:njme ) :: imask
     LOGICAL :: cinput_from_file, ninput_from_file

     ! Local

     INTEGER ci, cj, ck, ni, nj, nk, istag, jstag, ioff, joff, i, j, k
     REAL :: wx, wy, cfld_ll, cfld_lr, cfld_ul, cfld_ur
     REAL :: cxp0, cxp1, nx, cyp0, cyp1, ny
     LOGICAL :: probably_by_dateline
     REAL :: max_lon, min_lon
     LOGICAL :: probably_by_pole
     REAL :: max_lat, min_lat

     !  Fortran functions.  Yes, yes, I know, probably pretty slow.

     REAL, EXTERNAL :: nest_loc_of_cg
     INTEGER, EXTERNAL :: compute_CGLL

     !  This stag stuff is to keep us away from the outer most row
     !  and column for the unstaggered directions.  We are going to 
     !  consider "U" an xstag variable and "V" a ystag variable.  The
     !  vertical staggering is handled in the actual arguments.  The
     !  ckte and nkte are the ending vertical dimensions for computations
     !  for this particular variable.

     IF ( xstag ) THEN
        istag = 0 
        ioff  = 1
     ELSE
        istag = 1
        ioff  = 0
     END IF

     IF ( ystag ) THEN
        jstag = 0 
        joff  = 1
     ELSE
        jstag = 1
        joff  = 0
     END IF

     !  If this is a projection where the nest is over the pole, and
     !  we are using the parent to interpolate the longitudes, then 
     !  we are going to have longitude troubles.  If this is the case,
     !  stop the model right away.

     probably_by_pole = .FALSE.
     max_lat = -90
     min_lat = +90
     DO nj = njts, MIN(njde-jstag,njte)
        DO ni = nits, MIN(nide-istag,nite)
           max_lat = MAX ( nlat_in(ni,nj) , max_lat )       
           min_lat = MIN ( nlat_in(ni,nj) , min_lat )       
        END DO
     END DO

     IF ( ( max_lat .GT. 85 ) .OR. ( ABS(min_lat) .GT. 85 ) ) THEN
        probably_by_pole = .TRUE.
     END IF

     IF ( ( probably_by_pole ) .AND. ( .NOT. ninput_from_file ) ) THEN
        CALL wrf_error_fatal ( 'Nest over the pole, single input domain, longitudes will be wrong' )
     END IF

     !  Initialize to NOT being by dateline.

     probably_by_dateline = .FALSE.
     max_lon = -180
     min_lon = +180
     DO nj = njts, MIN(njde-jstag,njte)
        cj = compute_CGLL ( nj , jpos , nrj , jstag )
        DO ni = nits, MIN(nide-istag,nite)
           ci = compute_CGLL ( ni , ipos , nri , istag )
           max_lon = MAX ( cfld_inp(ci,1,cj) , max_lon )       
           min_lon = MIN ( cfld_inp(ci,1,cj) , min_lon )       
        END DO
     END DO

     IF ( max_lon - min_lon .GT. 300 ) THEN
        probably_by_dateline = .TRUE.
     END IF

     !  Load "continuous" longitude across the date line

     DO cj = MIN(cjts-1,cjms), MAX(cjte+1,cjme)
       DO ci = MIN(cits-1,cims), MAX(cite+1,cime)
         IF ( ( cfld_inp(ci,ckts,cj) .LT. 0 ) .AND. ( probably_by_dateline ) ) THEN
           cfld(ci,ckts,cj) = 360 + cfld_inp(ci,ckts,cj)
         ELSE
           cfld(ci,ckts,cj) =       cfld_inp(ci,ckts,cj)
         END IF
       END DO
     END DO

     !  Loop over each j-index on this tile for the nested domain.

     j_loop : DO nj = njts, MIN(njde-jstag,njte)

        !  This is the lower-left j-index of the CG.

        !  Example is 3:1 ratio, mass-point staggering.  We have listed six CG values
        !  as an example: A, B, C, D, E, F.  For a 3:1 ratio, each of these CG cells has
        !  nine associated FG points.
        !  |=========|=========|=========|
        !  | -  -  - | -  -  - | -  -  - |
        !  |         |         |         |
        !  | -  D  - | -  E  - | -  F  - |
        !  |         |         |         |
        !  | 1  2  3 | 4  5  6 | 7  8  9 |
        !  |=========|=========|=========|
        !  | -  -  - | -  -  - | -  -  - |
        !  |         |         |         |
        !  | -  A  - | -  B  - | -  C  - |
        !  |         |         |         |
        !  | -  -  - | -  -  - | -  -  - |
        !  |=========|=========|=========|
        !  To interpolate to FG point 4, we will use CG points: A, B, D, E.  It is adequate to
        !  find the lower left point.  The lower left (LL) point for "4" is "A".  Below
        !  are a few more points.
        !  2 => A
        !  3 => A
        !  4 => A
        !  5 => B
        !  6 => B
        !  7 => B

        cj = compute_CGLL ( nj , jpos , nrj , jstag )
        ny = REAL(nj)
        cyp0 = nest_loc_of_cg ( cj   , jpos , nrj , joff ) 
        cyp1 = nest_loc_of_cg ( cj+1 , jpos , nrj , joff ) 

        !  What is the weighting for this CG point to the FG point, j-weight only.

        wy = ( cyp1 - ny ) / ( cyp1 - cyp0 )

        !  Vertical dim of the nest domain.

        k_loop : DO nk = nkts, nkte

          !  Loop over each i-index on this tile for the nested domain.

           i_loop : DO ni = nits, MIN(nide-istag,nite)

              IF ( imask ( ni, nj ) .EQ. 1 ) THEN
 
                 !  The coarse grid location that is to the lower left of the FG point.
   
                 ci = compute_CGLL ( ni , ipos , nri , istag )
                 nx = REAL(ni)
                 cxp0 = nest_loc_of_cg ( ci   , ipos , nri , ioff ) 
                 cxp1 = nest_loc_of_cg ( ci+1 , ipos , nri , ioff ) 
   
                 wx = ( cxp1 - nx ) / ( cxp1 - cxp0 )
   
                 !  The four surrounding CG values.
   
                 cfld_ll = cfld(ci  ,nk,cj  )
                 cfld_lr = cfld(ci+1,nk,cj  )
                 cfld_ul = cfld(ci  ,nk,cj+1)
                 cfld_ur = cfld(ci+1,nk,cj+1)

                 !  Bilinear interpolation in horizontal.

                 nfld( ni , nk , nj ) =     wy  * ( cfld_ll * wx + cfld_lr * (1.-wx) ) + &
                                        (1.-wy) * ( cfld_ul * wx + cfld_ur * (1.-wx) )

              END IF
           END DO i_loop
        END DO    k_loop
     END DO       j_loop

     !  Put nested longitude back into the -180 to 180 range.

     DO nj = njts, MIN(njde-jstag,njte)
        DO ni = nits, MIN(nide-istag,nite)
           IF ( nfld(ni,nkts,nj) .GT. 180 ) THEN
              nfld(ni,nkts,nj) = -360 + nfld(ni,nkts,nj)
           END IF
        END DO
    END DO

   END SUBROUTINE interp_fcn_blint_ll

!=========================================================================

! Lagrange interpolating polynomials, set up as a quadratic, with an average of
! the overlap.


   SUBROUTINE interp_fcn_lagr ( cfld,                                 &  ! CD field 1
                                cids, cide, ckds, ckde, cjds, cjde,   &
                                cims, cime, ckms, ckme, cjms, cjme,   &
                                cits, cite, ckts, ckte, cjts, cjte,   &
                                nfld,                                 &  ! ND field
                                nids, nide, nkds, nkde, njds, njde,   &
                                nims, nime, nkms, nkme, njms, njme,   &
                                nits, nite, nkts, nkte, njts, njte,   &
                                shw,                                  &  ! stencil half width for interp
                                imask,                                &  ! interpolation mask
                                xstag, ystag,                         &  ! staggering of field
                                ipos, jpos,                           &  ! Position of lower left of nest in CD
                                nri, nrj)                                ! Nest ratio, i- and j-directions

     IMPLICIT NONE

     INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
                            cims, cime, ckms, ckme, cjms, cjme,   &
                            cits, cite, ckts, ckte, cjts, cjte,   &
                            nids, nide, nkds, nkde, njds, njde,   &
                            nims, nime, nkms, nkme, njms, njme,   &
                            nits, nite, nkts, nkte, njts, njte,   &
                            shw,                                  &
                            ipos, jpos,                           &
                            nri, nrj
     LOGICAL, INTENT(IN) :: xstag, ystag

     REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ) :: cfld
     REAL, DIMENSION ( nims:nime, nkms:nkme, njms:njme ) :: nfld
     INTEGER, DIMENSION ( nims:nime, njms:njme ) :: imask

     ! Local

     INTEGER ci, cj, ck, ni, nj, nk, istag, jstag, i, j, k
     REAL :: nx, x0, x1, x2, x3, x
     REAL :: ny, y0, y1, y2, y3
     REAL :: cxm1, cxp0, cxp1, cxp2, nfld_m1, nfld_p0, nfld_p1, nfld_p2
     REAL :: cym1, cyp0, cyp1, cyp2
     INTEGER :: ioff, joff

     !  Fortran functions.

     REAL, EXTERNAL :: lagrange_quad_avg
     REAL, EXTERNAL :: nest_loc_of_cg
     INTEGER, EXTERNAL :: compute_CGLL

     !  This stag stuff is to keep us away from the outer most row
     !  and column for the unstaggered directions.  We are going to 
     !  consider "U" an xstag variable and "V" a ystag variable.  The
     !  vertical staggering is handled in the actual arguments.  The
     !  ckte and nkte are the ending vertical dimensions for computations
     !  for this particular variable.

     !  The ioff and joff are offsets due to the staggering.  It is a lot
     !  simpler with ioff and joff if 
     !  u var => ioff=1
     !  v var => joff=1
     !  otherwise zero.
     !  Note that is OPPOSITE of the istag, jstag vars.  The stag variables are
     !  used for the domain dimensions, the offset guys are used in the 
     !  determination of grid points between the CG and FG

     IF ( xstag ) THEN
        istag = 0 
        ioff  = 1
     ELSE
        istag = 1
        ioff  = 0
     END IF

     IF ( ystag ) THEN
        jstag = 0 
        joff  = 1
     ELSE
        jstag = 1
        joff  = 0
     END IF

     !  Loop over each j-index on this tile for the nested domain.

     j_loop : DO nj = njts, MIN(njde-jstag,njte)

        !  This is the lower-left j-index of the CG.

        !  Example is 3:1 ratio, mass-point staggering.  We have listed sixteen CG values
        !  as an example: A through P.  For a 3:1 ratio, each of these CG cells has
        !  nine associated FG points.

        !  |=========|=========|=========|=========|
        !  | -  -  - | -  -  - | -  -  - | -  -  - |
        !  |         |         |         |         |
        !  | -  M  - | -  N  d | -  O  - | -  P  - |
        !  |         |         |         |         |
        !  | -  -  - | -  -  - | -  -  - | -  -  - |
        !  |=========|=========|=========|=========|
        !  | -  -  - | -  -  - | -  -  - | -  -  - |
        !  |         |         |         |         |
        !  | -  I  - | -  J  c | -  K  - | -  L  - |
        !  |         |         |         |         |
        !  | -  -  - | -  -  - | -  -  - | -  -  - |
        !  |=========|=========|=========|=========|
        !  | -  1  2 | 3  4  5 | 6  7  8 | -  -  - |
        !  |         |         |         |         |
        !  | -  E  - | -  F  b | -  G  - | -  H  - |
        !  |         |         |         |         |
        !  | -  -  - | -  -  - | -  -  - | -  -  - |
        !  |=========|=========|=========|=========|
        !  | -  -  - | -  -  - | -  -  - | -  -  - |
        !  |         |         |         |         |
        !  | -  A  - | -  B  a | -  C  - | -  D  - |
        !  |         |         |         |         |
        !  | -  -  - | -  -  - | -  -  - | -  -  - |
        !  |=========|=========|=========|=========|

        !  To interpolate to FG point 4, 5, or 6 we will use CG points: A through P.  It is
        !  sufficient to find the lower left corner of a 4-point interpolation, and then extend 
        !  each side by one unit.

        !  Here are the lower left hand corners of the following FG points:
        !  1 => E
        !  2 => E
        !  3 => E
        !  4 => F
        !  5 => F
        !  6 => F
        !  7 => G
        !  8 => G

        cj = compute_CGLL ( nj , jpos , nrj , jstag )

        !  Vertical dim of the nest domain.

        k_loop : DO nk = nkts, nkte

          !  Loop over each i-index on this tile for the nested domain.

           i_loop : DO ni = nits, MIN(nide-istag,nite)
 
              !  The coarse grid location that is to the lower left of the FG point.

              ci = compute_CGLL ( ni , ipos , nri , istag )

              !  To interpolate to point "*" (look in grid cell "F"):
              !  1. Use ABC to get a quadratic valid at "a"
              !     Use BCD to get a quadratic valid at "a"
              !     Average these to get the final value for "a"
              !  2. Use EFG to get a quadratic valid at "b"
              !     Use FGH to get a quadratic valid at "b"
              !     Average these to get the final value for "b"
              !  3. Use IJK to get a quadratic valid at "c"
              !     Use JKL to get a quadratic valid at "c"
              !     Average these to get the final value for "c"
              !  4. Use MNO to get a quadratic valid at "d"
              !     Use NOP to get a quadratic valid at "d"
              !     Average these to get the final value for "d"
              !  5. Use abc to get a quadratic valid at "*"
              !     Use bcd to get a quadratic valid at "*"
              !     Average these to get the final value for "*"

              !  |=========|=========|=========|=========|
              !  | -  -  - | -  -  - | -  -  - | -  -  - |
              !  |         |         |         |         |
              !  | -  M  - | -  N  d | -  O  - | -  P  - |
              !  |         |         |         |         |
              !  | -  -  - | -  -  - | -  -  - | -  -  - |
              !  |=========|=========|=========|=========|
              !  | -  -  - | -  -  - | -  -  - | -  -  - |
              !  |         |         |         |         |
              !  | -  I  - | -  J  c | -  K  - | -  L  - |
              !  |         |         |         |         |
              !  | -  -  - | -  -  - | -  -  - | -  -  - |
              !  |=========|=========|=========|=========|
              !  | -  -  - | -  -  * | -  -  - | -  -  - |
              !  |         |         |         |         |
              !  | -  E  - | -  F  b | -  G  - | -  H  - |
              !  |         |         |         |         |
              !  | -  -  - | -  -  - | -  -  - | -  -  - |
              !  |=========|=========|=========|=========|
              !  | -  -  - | -  -  - | -  -  - | -  -  - |
              !  |         |         |         |         |
              !  | -  A  - | -  B  a | -  C  - | -  D  - |
              !  |         |         |         |         |
              !  | -  -  - | -  -  - | -  -  - | -  -  - |
              !  |=========|=========|=========|=========|

              !  Overlapping quadratic interpolation.

              IF ( imask ( ni, nj ) .EQ. 1 ) THEN

                 !  I-direction location of "*"

                 nx = REAL(ni)

                 !  I-direction location of "A", "E", "I", "M"

                 cxm1 = nest_loc_of_cg ( ci-1 , ipos , nri , ioff ) 

                 !  I-direction location of "B", "F", "J", "N"

                 cxp0 = nest_loc_of_cg ( ci   , ipos , nri , ioff ) 

                 !  I-direction location of "C", "G", "K", "O"

                 cxp1 = nest_loc_of_cg ( ci+1 , ipos , nri , ioff ) 

                 !  I-direction location of "D", "H", "L", "P"

                 cxp2 = nest_loc_of_cg ( ci+2 , ipos , nri , ioff ) 

                 !  Value at "a"

                 nfld_m1 = lagrange_quad_avg ( nx, cxm1, cxp0, cxp1, cxp2, cfld(ci-1,nk,cj-1), cfld(ci+0,nk,cj-1), cfld(ci+1,nk,cj-1), cfld(ci+2,nk,cj-1) )

                 !  Value at "b"

                 nfld_p0 = lagrange_quad_avg ( nx, cxm1, cxp0, cxp1, cxp2, cfld(ci-1,nk,cj+0), cfld(ci+0,nk,cj+0), cfld(ci+1,nk,cj+0), cfld(ci+2,nk,cj+0) )

                 !  Value at "c"

                 nfld_p1 = lagrange_quad_avg ( nx, cxm1, cxp0, cxp1, cxp2, cfld(ci-1,nk,cj+1), cfld(ci+0,nk,cj+1), cfld(ci+1,nk,cj+1), cfld(ci+2,nk,cj+1) )

                 !  Value at "d"

                 nfld_p2 = lagrange_quad_avg ( nx, cxm1, cxp0, cxp1, cxp2, cfld(ci-1,nk,cj+2), cfld(ci+0,nk,cj+2), cfld(ci+1,nk,cj+2), cfld(ci+2,nk,cj+2) )

                 !  J-direction location of "*"

                 ny = REAL(nj)

                 !  J-direction location of "A", "B", "C", "D"

                 cym1 = nest_loc_of_cg ( cj-1 , jpos , nrj , joff ) 

                 !  J-direction location of "E", "F", "G", "H" 

                 cyp0 = nest_loc_of_cg ( cj   , jpos , nrj , joff ) 

                 !  J-direction location of "I", "J", "K", "L"

                 cyp1 = nest_loc_of_cg ( cj+1 , jpos , nrj , joff ) 

                 !  J-direction location of "M", "N", "O", "P"

                 cyp2 = nest_loc_of_cg ( cj+2 , jpos , nrj , joff ) 

                 !  Value at "*"

                 nfld(ni,nk,nj) = lagrange_quad_avg ( ny, cym1, cyp0, cyp1,    &
                                                      cyp2, nfld_m1, nfld_p0, nfld_p1, nfld_p2 )

              END IF

           END DO i_loop
        END DO    k_loop
     END DO       j_loop

   END SUBROUTINE interp_fcn_lagr

!=================================================================================


   REAL FUNCTION lagrange_quad ( x , x0, x1, x2, y0, y1, y2 )

     IMPLICIT NONE 

     REAL :: x , x0, x1, x2, y0, y1, y2

     !  Lagrange = sum     prod    ( x  - xj )
     !             i=0,n ( j=0,n    ---------  * yi )
     !                     j<>i    ( xi - xj ) 
     
     !  For a quadratic, in the above equation, we are setting n=2. Three points
     !  required for a quadratic, points x0, x1, x2 (hence n=2).

     lagrange_quad = &
            (x-x1)*(x-x2)*y0 / ( (x0-x1)*(x0-x2) ) + &
            (x-x0)*(x-x2)*y1 / ( (x1-x0)*(x1-x2) ) + &
            (x-x0)*(x-x1)*y2 / ( (x2-x0)*(x2-x1) ) 

   END FUNCTION lagrange_quad

!=================================================================================


   REAL FUNCTION lagrange_quad_avg ( x , x0, x1, x2, x3, y0, y1, y2, y3 )

     IMPLICIT NONE

     REAL, EXTERNAL :: lagrange_quad
     REAL :: x , x0, x1, x2, x3, y0, y1, y2, y3

     !  Since there are three points required for a quadratic, we compute it twice 
     !  (once with x0, x1, x2 and once with x1, x2, x3), and then average those values.  This will 
     !  reduce overshoot.  The "x" point is where we are interpolating TO.
    
     !         x0         x1    x    x2
     !                    x1    x    x2         x3

     lagrange_quad_avg = & 
!      ( lagrange_quad ( x , x0, x1, x2,     y0, y1, y2     )               + &
!        lagrange_quad ( x ,     x1, x2, x3,     y1, y2, y3 )               ) / &
!        2.
       ( lagrange_quad ( x , x0, x1, x2,     y0, y1, y2     ) * ( x2 - x  ) + &
         lagrange_quad ( x ,     x1, x2, x3,     y1, y2, y3 ) * ( x  - x1 ) ) / &
         ( x2 - x1 )

   END FUNCTION lagrange_quad_avg

!=================================================================================


   REAL FUNCTION nest_loc_of_cg ( ci , ipos , nri , ioff )

     !  I and J direction equations for mass and momentum values for even
     !  and odd ratios: Given that the starting value of the nest in the
     !  CG grid cell is defined as (1,1), what is the location of the CG
     !  location in FG index units.  Example, for a 2:1 ratio, the location 
     !  of the mass point T is 1.5 (3:1 ratio = 2, 4:1 ratio = 2.5, etc).
     !  Note that for momentum points, the CG U point is defined as "1", the
     !  same as the I-direction of the (1,1) location of the FG U point.
     !  Same for V, but in the J-direction.

     IMPLICIT NONE 

     INTEGER :: ci , ipos , nri , ioff

     nest_loc_of_cg = & 
       ( ci - ipos ) * nri + ( 1 - ioff ) * REAL ( nri + 1 ) / 2. + ioff

   END FUNCTION nest_loc_of_cg

!=================================================================================


   FUNCTION compute_CGLL ( ni , ipos , nri , istag ) RESULT ( CGLL_loc ),1

      IMPLICIT NONE

      INTEGER , INTENT(IN ) :: ni , ipos , nri , istag
      INTEGER :: CGLL_loc

      !  Local vars

      INTEGER :: starting_position , increments_of_CG_cells
      INTEGER :: location_of_LL_wrt_this_CG
      INTEGER :: ioff
      INTEGER , PARAMETER :: MOMENTUM_STAG   = 0
      INTEGER , PARAMETER :: MASS_POINT_STAG = 1

      starting_position = ipos
      increments_of_CG_cells = ( ni - 1 ) / nri
      ioff = MOD ( nri , 2 )

      IF      ( istag .EQ. MOMENTUM_STAG   ) THEN
         location_of_LL_wrt_this_CG =   MOD ( ( ni - 1 ) , nri )          /   ( nri + ioff )       - istag ! zero
      ELSE IF ( istag .EQ. MASS_POINT_STAG ) THEN
         location_of_LL_wrt_this_CG = ( MOD ( ( ni - 1 ) , nri ) + ioff ) / ( ( nri + ioff ) / 2 ) - istag
      ELSE
         CALL wrf_error_fatal ( 'Hold on there pard, there are only two staggerings I accept.' )
      END IF

      CGLL_loc = starting_position + increments_of_CG_cells + location_of_LL_wrt_this_CG
!      WRITE ( 6 , '(a,i4, i4, i4, i4)') 'ni   ipos nri  stag', ni, ipos, nri, istag
!      WRITE ( 6 , '(a,i4, i4, i4, i4)') 'strt inc  loc  CGLL', starting_position , increments_of_CG_cells , location_of_LL_wrt_this_CG , CGLL_loc
!      print *,' '

   END FUNCTION compute_CGLL

!=================================================================================

! Smolarkiewicz positive definite, monotonic transport.


   SUBROUTINE interp_fcn_sint ( cfld,                                 &  ! CD field 1,2
                           cids, cide, ckds, ckde, cjds, cjde,   &
                           cims, cime, ckms, ckme, cjms, cjme,   &
                           cits, cite, ckts, ckte, cjts, cjte,   &
                           nfld,                                 &  ! ND field
                           nids, nide, nkds, nkde, njds, njde,   &
                           nims, nime, nkms, nkme, njms, njme,   &
                           nits, nite, nkts, nkte, njts, njte,   &
                           shw,                                  &  ! stencil half width for interp
                           imask,                                &  ! interpolation mask
                           xstag, ystag,                         &  ! staggering of field
                           ipos, jpos,                           &  ! Position of lower left of nest in CD
                           nri, nrj                             )   ! nest ratios
     USE module_configure

     IMPLICIT NONE

     INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
                            cims, cime, ckms, ckme, cjms, cjme,   &
                            cits, cite, ckts, ckte, cjts, cjte,   &
                            nids, nide, nkds, nkde, njds, njde,   &
                            nims, nime, nkms, nkme, njms, njme,   &
                            nits, nite, nkts, nkte, njts, njte,   &
                            shw,                                  &
                            ipos, jpos,                           &
                            nri, nrj
     LOGICAL, INTENT(IN) :: xstag, ystag

     REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ) :: cfld
     REAL, DIMENSION ( nims:nime, nkms:nkme, njms:njme ) :: nfld
     INTEGER, DIMENSION ( nims:nime, njms:njme ) :: imask

     ! Local

     INTEGER ci, cj, ck, ni, nj, nk, ip, jp, ioff, joff, nioff, njoff
     INTEGER nfx, ior
     PARAMETER (ior=2)
     INTEGER nf
     REAL psca(cims:cime,cjms:cjme,nri*nrj)
     LOGICAL icmask( cims:cime, cjms:cjme )
     INTEGER i,j,k
     INTEGER nrio2, nrjo2

     ! Iterate over the ND tile and compute the values
     ! from the CD tile. 

     ioff  = 0 ; joff  = 0
     nioff = 0 ; njoff = 0
     IF ( xstag ) THEN 
       ioff = (nri-1)/2
       nioff = nri 
     ENDIF
     IF ( ystag ) THEN
       joff = (nrj-1)/2
       njoff = nrj
     ENDIF

     nrio2 = nri/2
     nrjo2 = nrj/2

     nfx = nri * nrj
   !$OMP PARALLEL DO   &
   !$OMP PRIVATE ( i,j,k,ni,nj,ci,cj,ip,jp,nk,ck,nf,icmask,psca )
     DO k = ckts, ckte
        icmask = .FALSE.
        DO nf = 1,nfx
           DO j = cjms,cjme
              nj = (j-jpos) * nrj + ( nrjo2 + 1 )  ! j point on nest
              DO i = cims,cime
                ni = (i-ipos) * nri + ( nrio2 + 1 )    ! i point on nest
                if ( ni .ge. nits-nioff-nrio2 .and. &
                     ni .le. nite+nioff+nrio2 .and. &
                     nj .ge. njts-njoff-nrjo2 .and. &
                     nj .le. njte+njoff+nrjo2 ) then
                  if ( ni.ge.nims.and.ni.le.nime.and.nj.ge.njms.and.nj.le.njme) then
                    if ( imask(ni,nj) .eq. 1 ) then
                      icmask( i, j ) = .TRUE.
                    endif
                  endif
                  if ( ni-nioff.ge.nims.and.ni.le.nime.and.nj-njoff.ge.njms.and.nj.le.njme) then
                    if (ni .ge. nits-nioff .and. nj .ge. njts-njoff ) then
                      if ( imask(ni-nioff,nj-njoff) .eq. 1) then
                        icmask( i, j ) = .TRUE.
                      endif
                    endif
                  endif
                endif
                psca(i,j,nf) = cfld(i,k,j)
              ENDDO           ! i
           ENDDO              ! j
        ENDDO                 ! nf

! tile dims in this call to sint are 1-over to account for the fact
! that the number of cells on the nest local subdomain is not 
! necessarily a multiple of the nest ratio in a given dim.
! this could be a little less ham-handed.

        CALL sint( psca,                     &
                   cims, cime, cjms, cjme, icmask,   &
                   cits-1, cite+1, cjts-1, cjte+1, nrj*nri, xstag, ystag )

        DO nj = njts, njte+joff
           cj = jpos + (nj-1) / nrj ! j coord of CD point 
           jp = mod ( nj-1 , nrj )  ! coord of ND w/i CD point
           nk = k
           ck = nk
           DO ni = nits, nite+ioff
               ci = ipos + (ni-1) / nri      ! i coord of CD point 
               ip = mod ( ni-1 , nri )  ! coord of ND w/i CD point
               if ( ( ni-ioff .ge. nits ) .and. ( nj-joff .ge. njts ) ) then
                  if ( imask ( ni, nj ) .eq. 1 .or. imask ( ni-ioff, nj-joff ) .eq. 1  ) then
                    nfld( ni-ioff, nk, nj-joff ) = psca( ci , cj, ip+1 + (jp)*nri )
                  endif
               endif
           ENDDO
        ENDDO
     ENDDO
   !$OMP END PARALLEL DO

   END SUBROUTINE interp_fcn_sint

!=========================================================================

!  Nearest neighbor interpolation.


   SUBROUTINE interp_fcn_nn ( cfld,                                 &  ! CD field 1
                           cids, cide, ckds, ckde, cjds, cjde,   &
                           cims, cime, ckms, ckme, cjms, cjme,   &
                           cits, cite, ckts, ckte, cjts, cjte,   &
                           nfld,                                 &  ! ND field
                           nids, nide, nkds, nkde, njds, njde,   &
                           nims, nime, nkms, nkme, njms, njme,   &
                           nits, nite, nkts, nkte, njts, njte,   &
                           shw,                                  &  ! stencil half width for interp
                           imask,                                &  ! interpolation mask
                           xstag, ystag,                         &  ! staggering of field
                           ipos, jpos,                           &  ! Position of lower left of nest in CD
                           nri, nrj                             )   ! nest ratios
     IMPLICIT NONE

     INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
                            cims, cime, ckms, ckme, cjms, cjme,   &
                            cits, cite, ckts, ckte, cjts, cjte,   &
                            nids, nide, nkds, nkde, njds, njde,   &
                            nims, nime, nkms, nkme, njms, njme,   &
                            nits, nite, nkts, nkte, njts, njte,   &
                            shw,                                  &
                            ipos, jpos,                           &
                            nri, nrj
     LOGICAL, INTENT(IN) :: xstag, ystag

     REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ) :: cfld
     REAL, DIMENSION ( nims:nime, nkms:nkme, njms:njme ) :: nfld
     INTEGER, DIMENSION ( nims:nime, njms:njme ) :: imask

     INTEGER ci, cj, ck, ni, nj, nk

     ! Iterate over the ND tile and assign the values
     ! from the CD tile.  This is a trivial implementation 
     ! of the interp_fcn; just copies the values from the CD into the ND

     DO nj = njts, njte
        cj = jpos + (nj-1) / nrj     ! j coord of CD point 
        DO nk = nkts, nkte
           ck = nk
           DO ni = nits, nite
              if ( imask ( ni, nj ) .eq. 1 ) then
                ci = ipos + (ni-1) / nri      ! i coord of CD point 
                nfld( ni, nk, nj ) = cfld( ci , ck , cj )
              endif
           ENDDO
        ENDDO
     ENDDO

   END SUBROUTINE interp_fcn_nn

!=========================================================================


   SUBROUTINE interp_fcn_bl ( cfld,                                 &  ! CD field 2,2
                              cids, cide, ckds, ckde, cjds, cjde,   &
                              cims, cime, ckms, ckme, cjms, cjme,   &
                              cits, cite, ckts, ckte, cjts, cjte,   &
                              nfld,                                 &  ! ND field
                              nids, nide, nkds, nkde, njds, njde,   &
                              nims, nime, nkms, nkme, njms, njme,   &
                              nits, nite, nkts, nkte, njts, njte,   &
                              shw,                                  &  ! stencil half width for interp
                              imask,                                &  ! interpolation mask
                              xstag, ystag,                         &  ! staggering of field
                              ipos, jpos,                           &  ! Position of lower left of nest in CD
                              nri, nrj,                             &  ! Nest ratio, i- and j-directions
                              cht, nht,                             &  ! topography for CG and FG
                              ct_max_p,nt_max_p,                    &  ! temperature (K) at max press, want CG value
                              cght_max_p,nght_max_p,                &  ! height (m) at max press, want CG value
                              cmax_p,nmax_p,                        &  ! max pressure (Pa) in column, want CG value
                              ct_min_p,nt_min_p,                    &  ! temperature (K) at min press, want CG value
                              cght_min_p,nght_min_p,                &  ! height (m) at min press, want CG value
                              cmin_p,nmin_p,                        &  ! min pressure (Pa) in column, want CG value
                              zn, p_top                             )  ! eta levels
     USE module_timing
!    USE module_configure
     USE module_model_constants , ONLY : g , r_d, cp, p1000mb, t0

     IMPLICIT NONE


     INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
                            cims, cime, ckms, ckme, cjms, cjme,   &
                            cits, cite, ckts, ckte, cjts, cjte,   &
                            nids, nide, nkds, nkde, njds, njde,   &
                            nims, nime, nkms, nkme, njms, njme,   &
                            nits, nite, nkts, nkte, njts, njte,   &
                            shw,                                  &
                            ipos, jpos,                           &
                            nri, nrj
     LOGICAL, INTENT(IN) :: xstag, ystag

     REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ) :: cfld
     REAL, DIMENSION ( nims:nime, nkms:nkme, njms:njme ) :: nfld
     INTEGER, DIMENSION ( nims:nime, njms:njme ) :: imask
     REAL, DIMENSION ( cims:cime, cjms:cjme ) :: cht, ct_max_p, cght_max_p, cmax_p, ct_min_p, cght_min_p, cmin_p
     REAL, DIMENSION ( nims:nime, njms:njme ) :: nht, nt_max_p, nght_max_p, nmax_p, nt_min_p, nght_min_p, nmin_p
     REAL, DIMENSION ( ckms:ckme ) :: zn
     REAL :: p_top
     REAL, EXTERNAL :: v_interp_col

     ! Local

     INTEGER ci, cj, ni, nj, nk, istag, jstag, i, j, k
     REAL :: wx, wy, nprs, cfld_ll, cfld_lr, cfld_ul, cfld_ur
     REAL , DIMENSION(ckms:ckme) :: cprs
     REAL    :: p00 , t00 , a , tiso , p_surf

     !  Yes, memory sized to allow "outside the tile" indexing for horiz interpolation.  This
     !  is really an intermediate domain that has quite a bit of usable real estate surrounding
     !  the tile dimensions.

     REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ) :: cpb
  
     !  A bit larger than tile sized to allow horizontal interpolation on the CG.

     REAL, DIMENSION ( cits-2:cite+2, cjts-2:cjte+2 ) :: cfld_max_p, cfld_min_p

     !  The usual tile size for the FG local array.

     REAL, DIMENSION ( nits:nite, nkts:nkte, njts:njte ) :: npb

     !  Get base state constants

     CALL nl_get_base_pres  ( 1 , p00 )
     CALL nl_get_base_temp  ( 1 , t00 )
     CALL nl_get_base_lapse ( 1 , a   )
     CALL nl_get_iso_temp   ( 1 , tiso )

     !  This stag stuff is to keep us away from the outer most row
     !  and column for the unstaggered directions.  We are going to 
     !  consider "U" an xstag variable and "V" a ystag variable.  The
     !  vertical staggering is handled in the actual arguments.  The
     !  ckte and nkte are the ending vertical dimensions for computations
     !  for this particular variable.

     IF ( xstag ) THEN
        istag = 0 
     ELSE
        istag = 1
     END IF

     IF ( ystag ) THEN
        jstag = 0 
     ELSE
        jstag = 1
     END IF

     !  Compute the reference pressure for the CG, function only of constants and elevation.
     !  We extend the i,j range to allow us to do horizontal interpolation.  We only need
     !  one extra grid cell surrounding the nest, and the intermediate domain has plenty of
     !  room with the halos set up for higher-order interpolations.  For intermediate domains,
     !  it turns out that the "domain" size actually fits within the "tile" size.  Yeppers,
     !  that is backwards from what usually happens.  That intermediate domain size is a couple
     !  grid points larger than necessary, and the tile is a couple of grid cells larger still.
     !  For our low-order interpolation, we can use the tile size for the CG, and we will have
     !  plenty of data on our boundaries.

     DO j = cjts-2 , cjte+2
        DO i = cits-2 , cite+2
           p_surf = p00 * EXP ( -t00/a + ( (t00/a)**2 - 2.*g*cht(i,j)/a/r_d ) **0.5 )
           DO k = ckts , ckte
              cpb(i,k,j) = zn(k)*(p_surf - p_top) + p_top  
           END DO
           IF ( ckte .EQ. ckme ) THEN
              cfld_max_p(i,j) = cght_max_p(i,j) * g
              cfld_min_p(i,j) = cght_min_p(i,j) * g
           ELSE
              cfld_max_p(i,j) = ct_max_p(i,j) * (p1000mb/cmax_p(i,j))**(r_d/cp) - t0
              cfld_min_p(i,j) = ct_min_p(i,j) * (p1000mb/cmin_p(i,j))**(r_d/cp) - t0
           END IF
        END DO
     END DO

     !  Compute the reference pressure for the FG. This is actually the size of the entire
     !  domain, not some chopped down piece of intermediate domain, as in the parent
     !  grid.  We do the traditional MAX(dom end -1,tile end), since we know a priori that the
     !  pressure is a mass point field (because the topo elevation is a mass point field).

     DO j = njts , MIN(njde-1,njte)
        DO i = nits , MIN(nide-1,nite)
           p_surf = p00 * EXP ( -t00/a + ( (t00/a)**2 - 2.*g*nht(i,j)/a/r_d ) **0.5 )
           DO k = nkts , nkte
              npb(i,k,j) = zn(k)*(p_surf - p_top) + p_top  
           END DO
        END DO
     END DO

     !  Loop over each j-index on this tile for the nested domain.

     j_loop : DO nj = njts, MIN(njde-jstag,njte)

        !  This is the lower-left j-index of the CG.

        !  Example is 3:1 ratio, mass-point staggering.  We have listed six CG values
        !  as an example: A, B, C, D, E, F.  For a 3:1 ratio, each of these CG cells has
        !  nine associated FG points.
        !  |=========|=========|=========|
        !  | -  -  - | -  -  - | -  -  - |
        !  |         |         |         |
        !  | -  D  - | -  E  - | -  F  - |
        !  |         |         |         |
        !  | 1  2  3 | 4  5  6 | 7  8  9 |
        !  |=========|=========|=========|
        !  | -  -  - | -  -  - | -  -  - |
        !  |         |         |         |
        !  | -  A  - | -  B  - | -  C  - |
        !  |         |         |         |
        !  | -  -  - | -  -  - | -  -  - |
        !  |=========|=========|=========|
        !  To interpolate to FG point 4, we will use CG points: A, B, D, E.  It is adequate to
        !  find the lower left point.  The lower left (LL) point for "4" is "A".  Below
        !  are a few more points.
        !  2 => A
        !  3 => A
        !  4 => A
        !  5 => B
        !  6 => B
        !  7 => B
        !  We want an equation that returns the CG LL:
        !  CG LL =   ipos                          (the starting point of the nest in the CG) 
        !          + (ni-1)/nri                    (gives us the CG cell, based on the nri-groups of FG cells
        !          - istag                         (a correction term, this is either zero for u in the x-dir, 
        !                                           since we are doing an "i" example, or 1 for anything else)
        !          + (MOD(ni-1,nri)+1 + nri/2)/nri (gives us specifically related CG point for each of the nri
        !                                           FG points, for example, we want points "1", "4", and "7" all
        !                                           to point to the CG at the left for the LL point)
        !  For grid points 4, 5, 6, we want the CG LL (sans the first two terms) to be -1, 0, 0 (which
        !  means that the CG point for "4" is to the left, and the CG LL point for "5" and "6"
        !  is in the current CG index.  

        cj = jpos + (nj-1)/nrj - jstag + (MOD(nj-1,nrj)+1 + nrj/2)/nrj


        !  What is the weighting for this CG point to the FG point, j-weight only.

        IF ( ystag ) THEN
           wy = 1. - ( REAL(MOD(nj+(nrj-1)/2,nrj)) / REAL(nrj) +  1. / REAL (2 * nrj) )
        ELSE
           wy = 1. - ( REAL(MOD(nj+(nrj-1)/2,nrj)) / REAL(nrj)                        )
        END IF

        !  Vertical dim of the nest domain.

        k_loop : DO nk = nkts, nkte

          !  Loop over each i-index on this tile for the nested domain.

           i_loop : DO ni = nits, MIN(nide-istag,nite)
 
              !  The coarse grid location that is to the lower left of the FG point.

              ci = ipos + (ni-1)/nri - istag + (MOD(ni-1,nri)+1 + nri/2)/nri

              !  Weights in the x-direction.

              IF ( xstag ) THEN
                 wx = 1. - ( REAL(MOD(ni+(nri-1)/2,nri)) / REAL(nri) +  1. / REAL (2 * nri) )
              ELSE
                 wx = 1. - ( REAL(MOD(ni+(nri-1)/2,nri)) / REAL(nri)                        )
              END IF

              !  The pressure of the FG point.

              IF      ( ( .NOT. xstag ) .AND. ( .NOT. ystag ) ) THEN
                 nprs =   npb(  ni  , nk , nj  ) 
              ELSE IF ( xstag ) THEN
                 nprs = ( npb(  ni-1, nk , nj  ) + npb(  ni  , nk , nj  ) ) * 0.5
              ELSE IF ( ystag ) THEN
                 nprs = ( npb(  ni  , nk , nj-1) + npb(  ni  , nk , nj  ) ) * 0.5
              END IF

              !  The four surrounding CG values.

              IF      ( ( .NOT. xstag ) .AND. ( .NOT. ystag ) ) THEN
                 cprs(:) =   cpb(ci  ,:,cj  )
                 cfld_ll = v_interp_col ( cfld(ci  ,:,cj  ) , cprs(:) , ckms , ckme , ckte, nprs, ni, nj, nk, ci  , cj  , &
                                          cfld_max_p(ci  ,cj  ) , cmax_p(ci  ,cj  ) , cfld_min_p(ci  ,cj  ) , cmin_p(ci  ,cj  ) )
                 cprs(:) =   cpb(ci+1,:,cj  )
                 cfld_lr = v_interp_col ( cfld(ci+1,:,cj  ) , cprs(:) , ckms , ckme , ckte, nprs, ni, nj, nk, ci+1, cj  , &
                                          cfld_max_p(ci+1,cj  ) , cmax_p(ci+1,cj  ) , cfld_min_p(ci+1,cj  ) , cmin_p(ci+1,cj  ) )
                 cprs(:) =   cpb(ci  ,:,cj+1)
                 cfld_ul = v_interp_col ( cfld(ci  ,:,cj+1) , cprs(:) , ckms , ckme , ckte, nprs, ni, nj, nk, ci  , cj+1, &
                                          cfld_max_p(ci  ,cj+1) , cmax_p(ci  ,cj+1) , cfld_min_p(ci  ,cj+1) , cmin_p(ci  ,cj+1) )
                 cprs(:) =   cpb(ci+1,:,cj+1)
                 cfld_ur = v_interp_col ( cfld(ci+1,:,cj+1) , cprs(:) , ckms , ckme , ckte, nprs, ni, nj, nk, ci+1, cj+1, &
                                          cfld_max_p(ci+1,cj+1) , cmax_p(ci+1,cj+1) , cfld_min_p(ci+1,cj+1) , cmin_p(ci+1,cj+1) )

              ELSE IF ( xstag ) THEN
                 cprs(:) = ( cpb(ci  ,:,cj  ) + cpb(ci-1,:,cj  ) )*0.5 
                 cfld_ll = v_interp_col ( cfld(ci  ,:,cj  ) , cprs(:) , ckms , ckme , ckte, nprs, ni, nj, nk, ci  , cj  , &
                                          cfld_max_p(ci  ,cj  ) , cmax_p(ci  ,cj  ) , cfld_min_p(ci  ,cj  ) , cmin_p(ci  ,cj  ) )
                 cprs(:) = ( cpb(ci+1,:,cj  ) + cpb(ci  ,:,cj  ) )*0.5
                 cfld_lr = v_interp_col ( cfld(ci+1,:,cj  ) , cprs(:) , ckms , ckme , ckte, nprs, ni, nj, nk, ci+1, cj  , &
                                          cfld_max_p(ci+1,cj  ) , cmax_p(ci+1,cj  ) , cfld_min_p(ci+1,cj  ) , cmin_p(ci+1,cj  ) )
                 cprs(:) = ( cpb(ci  ,:,cj+1) + cpb(ci-1,:,cj+1) )*0.5
                 cfld_ul = v_interp_col ( cfld(ci  ,:,cj+1) , cprs(:) , ckms , ckme , ckte, nprs, ni, nj, nk, ci  , cj+1, &
                                          cfld_max_p(ci  ,cj+1) , cmax_p(ci  ,cj+1) , cfld_min_p(ci  ,cj+1) , cmin_p(ci  ,cj+1) )
                 cprs(:) = ( cpb(ci+1,:,cj+1) + cpb(ci  ,:,cj+1) )*0.5
                 cfld_ur = v_interp_col ( cfld(ci+1,:,cj+1) , cprs(:) , ckms , ckme , ckte, nprs, ni, nj, nk, ci+1, cj+1, &
                                          cfld_max_p(ci+1,cj+1) , cmax_p(ci+1,cj+1) , cfld_min_p(ci+1,cj+1) , cmin_p(ci+1,cj+1) )
              ELSE IF ( ystag ) THEN
                 cprs(:) = ( cpb(ci  ,:,cj  ) + cpb(ci  ,:,cj-1) )*0.5
                 cfld_ll = v_interp_col ( cfld(ci  ,:,cj  ) , cprs(:) , ckms , ckme , ckte, nprs, ni, nj, nk, ci  , cj  , &
                                          cfld_max_p(ci  ,cj  ) , cmax_p(ci  ,cj  ) , cfld_min_p(ci  ,cj  ) , cmin_p(ci  ,cj  ) )
                 cprs(:) = ( cpb(ci+1,:,cj  ) + cpb(ci+1,:,cj-1) )*0.5
                 cfld_lr = v_interp_col ( cfld(ci+1,:,cj  ) , cprs(:) , ckms , ckme , ckte, nprs, ni, nj, nk, ci+1, cj  , &
                                          cfld_max_p(ci+1,cj  ) , cmax_p(ci+1,cj  ) , cfld_min_p(ci+1,cj  ) , cmin_p(ci+1,cj  ) )
                 cprs(:) = ( cpb(ci  ,:,cj+1) + cpb(ci  ,:,cj  ) )*0.5
                 cfld_ul = v_interp_col ( cfld(ci  ,:,cj+1) , cprs(:) , ckms , ckme , ckte, nprs, ni, nj, nk, ci  , cj+1, &
                                          cfld_max_p(ci  ,cj+1) , cmax_p(ci  ,cj+1) , cfld_min_p(ci  ,cj+1) , cmin_p(ci  ,cj+1) )
                 cprs(:) = ( cpb(ci+1,:,cj+1) + cpb(ci+1,:,cj  ) )*0.5
                 cfld_ur = v_interp_col ( cfld(ci+1,:,cj+1) , cprs(:) , ckms , ckme , ckte, nprs, ni, nj, nk, ci+1, cj+1, &
                                          cfld_max_p(ci+1,cj+1) , cmax_p(ci+1,cj+1) , cfld_min_p(ci+1,cj+1) , cmin_p(ci+1,cj+1) )
              END IF

              !  Bilinear interpolation in horizontal with vertically corrected CG field values.

              nfld( ni , nk , nj ) =     wy  * ( cfld_ll * wx + cfld_lr * (1.-wx) ) + &
                                     (1.-wy) * ( cfld_ul * wx + cfld_ur * (1.-wx) )

           END DO i_loop
        END DO    k_loop
     END DO       j_loop

     !  If this is ph_2, make the values at k=1 all zero

     IF ( ckme .EQ. ckte ) THEN
        DO nj = njts,njte
           DO ni = nits, nite
              nfld(ni,nkts,nj) = 0.0
           END DO
        END DO
     END IF

   END SUBROUTINE interp_fcn_bl

!==================================


   FUNCTION v_interp_col ( cfld_orig , cprs_orig , ckms , ckme , ckte , nprs, ni, nj, nk, ci, cj, &,1
                           cfld_max_p , cmax_p , cfld_min_p , cmin_p ) RESULT ( cfld_interp )

      IMPLICIT NONE

      INTEGER , INTENT(IN) ::  ni, nj, nk, ci, cj
      INTEGER , INTENT(IN) :: ckms , ckme , ckte
      REAL , DIMENSION(ckms:ckme) , INTENT(IN) :: cfld_orig , cprs_orig
      REAL , INTENT(IN) :: cfld_max_p , cmax_p , cfld_min_p , cmin_p
      REAL , INTENT(IN) :: nprs
      REAL :: cfld_interp

      !  Local

      INTEGER :: ck
      LOGICAL :: found
      CHARACTER(LEN=256) :: joe_mess
      REAL , DIMENSION(ckms:ckme+1+1) :: cfld , cprs

      !  Fill input arrays

      cfld(1) = cfld_max_p
      cprs(1) = cmax_p

      cfld(ckte+2) = cfld_min_p
      cprs(ckte+2) = cmin_p

      DO ck = ckms , ckte
         cfld(ck+1) = cfld_orig(ck)
         cprs(ck+1) = cprs_orig(ck)
      END DO

      found = .FALSE.

      IF      ( cprs(ckms) .LT. nprs ) THEN
         cfld_interp = cfld(ckms)
         RETURN
      ELSE IF ( cprs(ckte+2) .GE. nprs ) THEN
         cfld_interp = cfld(ckte+2)
         RETURN
      END IF

      DO ck = ckms , ckte+1
         IF ( ( cprs(ck  ) .GE. nprs ) .AND. &
              ( cprs(ck+1) .LT. nprs ) ) THEN
            cfld_interp = ( cfld(ck  ) * ( nprs     - cprs(ck+1) ) + &
                            cfld(ck+1) * ( cprs(ck) - nprs       ) ) / &
                                         ( cprs(ck) - cprs(ck+1) )
            RETURN
         END IF
      END DO

      CALL wrf_error_fatal ( 'ERROR -- vertical interpolation for nest interp cannot find trapping pressures' )
   
   END FUNCTION v_interp_col

!==================================
! this is the default function used in feedback.


   SUBROUTINE copy_fcn ( cfld,                                 &  ! CD field,1
                           cids, cide, ckds, ckde, cjds, cjde,   &
                           cims, cime, ckms, ckme, cjms, cjme,   &
                           cits, cite, ckts, ckte, cjts, cjte,   &
                           nfld,                                 &  ! ND field
                           nids, nide, nkds, nkde, njds, njde,   &
                           nims, nime, nkms, nkme, njms, njme,   &
                           nits, nite, nkts, nkte, njts, njte,   &
                           shw,                                  &  ! stencil half width for interp
                           imask,                                &  ! interpolation mask
                           xstag, ystag,                         &  ! staggering of field
                           ipos, jpos,                           &  ! Position of lower left of nest in CD
                           nri, nrj                             )   ! nest ratios
     USE module_configure
     IMPLICIT NONE


     INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
                            cims, cime, ckms, ckme, cjms, cjme,   &
                            cits, cite, ckts, ckte, cjts, cjte,   &
                            nids, nide, nkds, nkde, njds, njde,   &
                            nims, nime, nkms, nkme, njms, njme,   &
                            nits, nite, nkts, nkte, njts, njte,   &
                            shw,                                  &
                            ipos, jpos,                           &
                            nri, nrj
     LOGICAL, INTENT(IN) :: xstag, ystag

     REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ), INTENT(OUT) :: cfld
     REAL, DIMENSION ( nims:nime, nkms:nkme, njms:njme ),INTENT(IN)  :: nfld
     INTEGER, DIMENSION ( nims:nime, njms:njme ),INTENT(IN)  :: imask

     ! Local

     INTEGER ci, cj, ck, ni, nj, nk, ip, jp, ioff, joff, ioffa, joffa
     INTEGER :: icmin,icmax,jcmin,jcmax
     INTEGER :: istag,jstag, ipoints,jpoints,ijpoints
     INTEGER , PARAMETER :: passes = 2
     INTEGER spec_zone

     !  Loop over the coarse grid in the area of the fine mesh.  Do not
     !  process the coarse grid values that are along the lateral BC
     !  provided to the fine grid.  Since that is in the specified zone
     !  for the fine grid, it should not be used in any feedback to the
     !  coarse grid as it should not have changed.

     !  Due to peculiarities of staggering, it is simpler to handle the feedback
     !  for the staggerings based upon whether it is a even ratio (2::1, 4::1, etc.) or
     !  an odd staggering ratio (3::1, 5::1, etc.). 

     !  Though there are separate grid ratios for the i and j directions, this code
     !  is not general enough to handle aspect ratios .NE. 1 for the fine grid cell.
 
     !  These are local integer increments in the looping.  Basically, istag=1 means
     !  that we will assume one less point in the i direction.  Note that ci and cj
     !  have a maximum value that is decreased by istag and jstag, respectively.  

     !  Horizontal momentum feedback is along the face, not within the cell.  For a
     !  3::1 ratio, temperature would use 9 pts for feedback, while u and v use
     !  only 3 points for feedback from the nest to the parent.

     CALL nl_get_spec_zone( 1 , spec_zone )
     istag = 1 ; jstag = 1
     IF ( xstag ) istag = 0
     IF ( ystag ) jstag = 0

     IF( MOD(nrj,2) .NE. 0) THEN  ! odd refinement ratio

        IF      ( ( .NOT. xstag ) .AND. ( .NOT. ystag ) ) THEN
           DO cj = MAX(jpos+spec_zone,cjts),MIN(jpos+(njde-njds)/nrj-jstag-spec_zone,cjte)
              nj = (cj-jpos)*nrj + jstag + 1
              DO ck = ckts, ckte
                 nk = ck
                 DO ci = MAX(ipos+spec_zone,cits),MIN(ipos+(nide-nids)/nri-istag-spec_zone,cite)
                    ni = (ci-ipos)*nri + istag + 1
                    cfld( ci, ck, cj ) = 0.
                    DO ijpoints = 1 , nri * nrj
                       ipoints = MOD((ijpoints-1),nri) + 1 - nri/2 - 1
                       jpoints = (ijpoints-1)/nri + 1 - nrj/2 - 1
                       cfld( ci, ck, cj ) =  cfld( ci, ck, cj ) + &
                                             1./REAL(nri*nrj) * nfld( ni+ipoints , nk , nj+jpoints )
                    END DO
!                   cfld( ci, ck, cj ) =  1./9. * &
!                                         ( nfld( ni-1, nk , nj-1) + &
!                                           nfld( ni  , nk , nj-1) + &
!                                           nfld( ni+1, nk , nj-1) + &
!                                           nfld( ni-1, nk , nj  ) + &
!                                           nfld( ni  , nk , nj  ) + &
!                                           nfld( ni+1, nk , nj  ) + &
!                                           nfld( ni-1, nk , nj+1) + &
!                                           nfld( ni  , nk , nj+1) + &
!                                           nfld( ni+1, nk , nj+1) )
                 ENDDO
              ENDDO
           ENDDO

        ELSE IF ( (       xstag ) .AND. ( .NOT. ystag ) ) THEN
           DO cj = MAX(jpos+spec_zone,cjts),MIN(jpos+(njde-njds)/nrj-jstag-spec_zone,cjte)
              nj = (cj-jpos)*nrj + jstag + 1
              DO ck = ckts, ckte
                 nk = ck
                 DO ci = MAX(ipos+spec_zone,cits),MIN(ipos+(nide-nids)/nri-istag-spec_zone,cite)
                    ni = (ci-ipos)*nri + istag + 1
                    cfld( ci, ck, cj ) = 0.
                    DO ijpoints = (nri+1)/2 , (nri+1)/2 + nri*(nri-1) , nri
                       ipoints = MOD((ijpoints-1),nri) + 1 - nri/2 - 1
                       jpoints = (ijpoints-1)/nri + 1 - nrj/2 - 1
                       cfld( ci, ck, cj ) =  cfld( ci, ck, cj ) + &
                                             1./REAL(nri    ) * nfld( ni+ipoints , nk , nj+jpoints )
                    END DO
!                   cfld( ci, ck, cj ) =  1./3. * &
!                                         ( nfld( ni  , nk , nj-1) + &
!                                           nfld( ni  , nk , nj  ) + &
!                                           nfld( ni  , nk , nj+1) )
                 ENDDO
              ENDDO
           ENDDO

        ELSE IF ( ( .NOT. xstag ) .AND. (       ystag ) ) THEN
           DO cj = MAX(jpos+spec_zone,cjts),MIN(jpos+(njde-njds)/nrj-jstag-spec_zone,cjte)
              nj = (cj-jpos)*nrj + jstag + 1
              DO ck = ckts, ckte
                 nk = ck
                 DO ci = MAX(ipos+spec_zone,cits),MIN(ipos+(nide-nids)/nri-istag-spec_zone,cite)
                    ni = (ci-ipos)*nri + istag + 1
                    cfld( ci, ck, cj ) = 0.
                    DO ijpoints = ( nrj*nrj +1 )/2 - nrj/2 , ( nrj*nrj +1 )/2 - nrj/2 + nrj-1
                       ipoints = MOD((ijpoints-1),nri) + 1 - nri/2 - 1
                       jpoints = (ijpoints-1)/nri + 1 - nrj/2 - 1
                       cfld( ci, ck, cj ) =  cfld( ci, ck, cj ) + &
                                             1./REAL(    nrj) * nfld( ni+ipoints , nk , nj+jpoints )
                    END DO
!                   cfld( ci, ck, cj ) =  1./3. * &
!                                         ( nfld( ni-1, nk , nj  ) + &
!                                           nfld( ni  , nk , nj  ) + &
!                                           nfld( ni+1, nk , nj  ) )
                 ENDDO
              ENDDO
           ENDDO

        END IF

     !  Even refinement ratio

     ELSE IF ( MOD(nrj,2) .EQ. 0) THEN
        IF ( ( .NOT. xstag ) .AND. ( .NOT. ystag ) ) THEN

        !  This is a simple schematic of the feedback indexing used in the even
        !  ratio nests.  For simplicity, a 2::1 ratio is depicted.  Only the 
        !  mass variable staggering is shown. 
        !                                                                  Each of
        !  the boxes with a "T" and four small "t" represents a coarse grid (CG)
        !  cell, that is composed of four (2::1 ratio) fine grid (FG) cells.
   
        !  Shown below is the area of the CG that is in the area of the FG.   The
        !  first grid point of the depicted CG is the starting location of the nest
        !  in the parent domain (ipos,jpos - i_parent_start and j_parent_start from
        !  the namelist).  
   
        !  For each of the CG points, the feedback loop is over each of the FG points
        !  within the CG cell.  For a 2::1 ratio, there are four total points (this is 
        !  the ijpoints loop).  The feedback value to the CG is the arithmetic mean of 
        !  all of the FG values within each CG cell.

!              |-------------||-------------|                          |-------------||-------------|
!              |  t      t   ||  t      t   |                          |  t      t   ||  t      t   |
! jpos+        |             ||             |                          |             ||             |
! (njde-njds)- |      T      ||      T      |                          |      T      ||      T      |
! jstag        |             ||             |                          |             ||             |
!              |  t      t   ||  t      t   |                          |  t      t   ||  t      t   |
!              |-------------||-------------|                          |-------------||-------------|
!              |-------------||-------------|                          |-------------||-------------|
!              |  t      t   ||  t      t   |                          |  t      t   ||  t      t   |
!              |             ||             |                          |             ||             |
!              |      T      ||      T      |                          |      T      ||      T      |
!              |             ||             |                          |             ||             |
!              |  t      t   ||  t      t   |                          |  t      t   ||  t      t   |
!              |-------------||-------------|                          |-------------||-------------|
!
!                   ...
!                   ...
!                   ...
!                   ...
!                   ...

!              |-------------||-------------|                          |-------------||-------------|
! jpoints = 1  |  t      t   ||  t      t   |                          |  t      t   ||  t      t   |
!              |             ||             |                          |             ||             |
!              |      T      ||      T      |                          |      T      ||      T      |
!              |             ||             |                          |             ||             |
! jpoints = 0, |  t      t   ||  t      t   |                          |  t      t   ||  t      t   |
!  nj=3        |-------------||-------------|                          |-------------||-------------|
!              |-------------||-------------|                          |-------------||-------------|
! jpoints = 1  |  t      t   ||  t      t   |                          |  t      t   ||  t      t   |
!              |             ||             |                          |             ||             |
!    jpos      |      T      ||      T      |          ...             |      T      ||      T      |
!              |             ||             |          ...             |             ||             |
! jpoints = 0, |  t      t   ||  t      t   |          ...             |  t      t   ||  t      t   |
!  nj=1        |-------------||-------------|                          |-------------||-------------|
!                     ^                                                                      ^
!                     |                                                                      |
!                     |                                                                      |
!                   ipos                                                                   ipos+
!     ni =        1              3                                                         (nide-nids)/nri
! ipoints=        0      1       0      1                                                  -istag
!

           !  For performance benefits, users can comment out the inner most loop (and cfld=0) and
           !  hardcode the loop feedback.  For example, it is set up to run a 2::1 ratio
           !  if uncommented.  This lacks generality, but is likely to gain timing benefits
           !  with compilers unable to unroll inner loops that do not have parameterized sizes.
   
           !  The extra +1 ---------/ and the extra -1 ----\  (both for ci and cj) 
           !                       /                        \   keeps the feedback out of the 
           !                      /                          \  outer row/col, since that CG data
           !                     /                            \ specified the nest boundary originally
           !                    /                              \   This
           !                   /                                \    is just
           !                  /                                  \   a sentence to not end a line
           !                 /                                    \   with a stupid backslash
           DO cj = MAX(jpos+spec_zone,cjts),MIN(jpos+(njde-njds)/nrj-jstag-spec_zone,cjte)
              nj = (cj-jpos)*nrj + jstag
              DO ck = ckts, ckte
                 nk = ck
                 DO ci = MAX(ipos+spec_zone,cits),MIN(ipos+(nide-nids)/nri-istag-spec_zone,cite)
                    ni = (ci-ipos)*nri + istag
                    cfld( ci, ck, cj ) = 0.
                    DO ijpoints = 1 , nri * nrj
                       ipoints = MOD((ijpoints-1),nri)
                       jpoints = (ijpoints-1)/nri
                       cfld( ci, ck, cj ) =  cfld( ci, ck, cj ) + &
                                             1./REAL(nri*nrj) * nfld( ni+ipoints , nk , nj+jpoints )
                    END DO
!                   cfld( ci, ck, cj ) =  1./4. * &
!                                         ( nfld( ni  , nk , nj  ) + &
!                                           nfld( ni+1, nk , nj  ) + &
!                                           nfld( ni  , nk , nj+1) + &
!                                           nfld( ni+1, nk , nj+1) )
                 END DO
              END DO
           END DO

        !  U

        ELSE IF ( (       xstag ) .AND. ( .NOT. ystag ) ) THEN
!              |---------------|
!              |               |
! jpoints = 1  u       u       |
!              |               |
!              U               |
!              |               |
! jpoints = 0, u       u       |
!  nj=3        |               |
!              |---------------|
!              |---------------|
!              |               |
! jpoints = 1  u       u       |
!              |               |
!    jpos      U               |
!              |               |
! jpoints = 0, u       u       |
! nj=1         |               |
!              |---------------|
! 
!              ^               
!              |              
!              |             
!            ipos           
!     ni =     1               3
! ipoints=     0       1       0 
!

           DO cj = MAX(jpos+spec_zone,cjts),MIN(jpos+(njde-njds)/nrj-jstag-spec_zone,cjte)
              nj = (cj-jpos)*nrj + 1
              DO ck = ckts, ckte
                 nk = ck
                 DO ci = MAX(ipos+spec_zone,cits),MIN(ipos+(nide-nids)/nri-istag-spec_zone,cite)
                    ni = (ci-ipos)*nri + 1
                    cfld( ci, ck, cj ) = 0.
                    DO ijpoints = 1 , nri*nrj , nri
                       ipoints = MOD((ijpoints-1),nri)
                       jpoints = (ijpoints-1)/nri
                       cfld( ci, ck, cj ) =  cfld( ci, ck, cj ) + &
                                             1./REAL(nri    ) * nfld( ni+ipoints , nk , nj+jpoints )
                    END DO
!                cfld( ci, ck, cj ) =  1./2. * &
!                                      ( nfld( ni  , nk , nj  ) + &
!                                        nfld( ni  , nk , nj+1) )
                 ENDDO
              ENDDO
           ENDDO

        !  V 

        ELSE IF ( ( .NOT. xstag ) .AND. (       ystag ) ) THEN
           DO cj = MAX(jpos+spec_zone,cjts),MIN(jpos+(njde-njds)/nrj-jstag-spec_zone,cjte)
              nj = (cj-jpos)*nrj + 1
              DO ck = ckts, ckte
                 nk = ck
                 DO ci = MAX(ipos+spec_zone,cits),MIN(ipos+(nide-nids)/nri-istag-spec_zone,cite)
                    ni = (ci-ipos)*nri + 1
                    cfld( ci, ck, cj ) = 0.
                    DO ijpoints = 1 , nri
                       ipoints = MOD((ijpoints-1),nri)
                       jpoints = (ijpoints-1)/nri
                       cfld( ci, ck, cj ) =  cfld( ci, ck, cj ) + &
                                             1./REAL(nri    ) * nfld( ni+ipoints , nk , nj+jpoints )
                    END DO
!                cfld( ci, ck, cj ) =  1./2. * &
!                                      ( nfld( ni  , nk , nj  ) + &
!                                        nfld( ni+1, nk , nj  ) )
                 ENDDO
              ENDDO
           ENDDO
        END IF
     END IF

     RETURN

   END SUBROUTINE copy_fcn

!==================================
! this is the 1pt function used in feedback.


   SUBROUTINE copy_fcnm (  cfld,                                 &  ! CD field,2
                           cids, cide, ckds, ckde, cjds, cjde,   &
                           cims, cime, ckms, ckme, cjms, cjme,   &
                           cits, cite, ckts, ckte, cjts, cjte,   &
                           nfld,                                 &  ! ND field
                           nids, nide, nkds, nkde, njds, njde,   &
                           nims, nime, nkms, nkme, njms, njme,   &
                           nits, nite, nkts, nkte, njts, njte,   &
                           shw,                                  &  ! stencil half width for interp
                           imask,                                &  ! interpolation mask
                           xstag, ystag,                         &  ! staggering of field
                           ipos, jpos,                           &  ! Position of lower left of nest in CD
                           nri, nrj                             )   ! nest ratios
     USE module_configure
     USE module_wrf_error
     IMPLICIT NONE


     INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
                            cims, cime, ckms, ckme, cjms, cjme,   &
                            cits, cite, ckts, ckte, cjts, cjte,   &
                            nids, nide, nkds, nkde, njds, njde,   &
                            nims, nime, nkms, nkme, njms, njme,   &
                            nits, nite, nkts, nkte, njts, njte,   &
                            shw,                                  &
                            ipos, jpos,                           &
                            nri, nrj
     LOGICAL, INTENT(IN) :: xstag, ystag

     REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ), INTENT(OUT) :: cfld
     REAL, DIMENSION ( nims:nime, nkms:nkme, njms:njme ), INTENT(IN) :: nfld
     INTEGER, DIMENSION ( nims:nime, njms:njme ), INTENT(IN) :: imask

     ! Local

     INTEGER ci, cj, ck, ni, nj, nk, ip, jp, ioff, joff, ioffa, joffa
     INTEGER :: icmin,icmax,jcmin,jcmax
     INTEGER :: istag,jstag, ipoints,jpoints,ijpoints
     INTEGER , PARAMETER :: passes = 2
     INTEGER spec_zone

     CALL nl_get_spec_zone( 1, spec_zone ) 
     istag = 1 ; jstag = 1
     IF ( xstag ) istag = 0
     IF ( ystag ) jstag = 0

     IF( MOD(nrj,2) .NE. 0) THEN  ! odd refinement ratio

        DO cj = MAX(jpos+spec_zone,cjts),MIN(jpos+(njde-njds)/nrj-jstag-spec_zone,cjte)
           nj = (cj-jpos)*nrj + jstag + 1
           DO ck = ckts, ckte
              nk = ck
              DO ci = MAX(ipos+spec_zone,cits),MIN(ipos+(nide-nids)/nri-istag-spec_zone,cite)
                 ni = (ci-ipos)*nri + istag + 1
                 cfld( ci, ck, cj ) =  nfld( ni  , nk , nj  )
              ENDDO
           ENDDO
        ENDDO

     ELSE  ! even refinement ratio, pick nearest neighbor on SW corner
        DO cj = MAX(jpos+spec_zone,cjts),MIN(jpos+(njde-njds)/nrj-jstag-spec_zone,cjte)
           nj = (cj-jpos)*nrj + 1
           DO ck = ckts, ckte
              nk = ck
              DO ci = MAX(ipos+spec_zone,cits),MIN(ipos+(nide-nids)/nri-istag-spec_zone,cite)
                 ni = (ci-ipos)*nri + 1
                 ipoints = nri/2 -1
                 jpoints = nrj/2 -1
                 cfld( ci, ck, cj ) =  nfld( ni+ipoints , nk , nj+jpoints )
              END DO
           END DO
        END DO

     END IF

     RETURN

   END SUBROUTINE copy_fcnm

!==================================
! this is the 1pt function used in feedback for integers


   SUBROUTINE copy_fcni ( cfld,                                 &  ! CD field,2
                           cids, cide, ckds, ckde, cjds, cjde,   &
                           cims, cime, ckms, ckme, cjms, cjme,   &
                           cits, cite, ckts, ckte, cjts, cjte,   &
                           nfld,                                 &  ! ND field
                           nids, nide, nkds, nkde, njds, njde,   &
                           nims, nime, nkms, nkme, njms, njme,   &
                           nits, nite, nkts, nkte, njts, njte,   &
                           shw,                                  &  ! stencil half width for interp
                           imask,                                &  ! interpolation mask
                           xstag, ystag,                         &  ! staggering of field
                           ipos, jpos,                           &  ! Position of lower left of nest in CD
                           nri, nrj                             )   ! nest ratios
     USE module_configure
     USE module_wrf_error
     IMPLICIT NONE


     INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
                            cims, cime, ckms, ckme, cjms, cjme,   &
                            cits, cite, ckts, ckte, cjts, cjte,   &
                            nids, nide, nkds, nkde, njds, njde,   &
                            nims, nime, nkms, nkme, njms, njme,   &
                            nits, nite, nkts, nkte, njts, njte,   &
                            shw,                                  &
                            ipos, jpos,                           &
                            nri, nrj
     LOGICAL, INTENT(IN) :: xstag, ystag

     INTEGER, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ), INTENT(OUT) :: cfld
     INTEGER, DIMENSION ( nims:nime, nkms:nkme, njms:njme ), INTENT(IN) :: nfld
     INTEGER, DIMENSION ( nims:nime, njms:njme ), INTENT(IN)  :: imask

     ! Local

     INTEGER ci, cj, ck, ni, nj, nk, ip, jp, ioff, joff, ioffa, joffa
     INTEGER :: icmin,icmax,jcmin,jcmax
     INTEGER :: istag,jstag, ipoints,jpoints,ijpoints
     INTEGER , PARAMETER :: passes = 2
     INTEGER spec_zone

     CALL nl_get_spec_zone( 1, spec_zone ) 
     istag = 1 ; jstag = 1
     IF ( xstag ) istag = 0
     IF ( ystag ) jstag = 0

     IF( MOD(nrj,2) .NE. 0) THEN  ! odd refinement ratio

        DO cj = MAX(jpos+spec_zone,cjts),MIN(jpos+(njde-njds)/nrj-jstag-spec_zone,cjte)
           nj = (cj-jpos)*nrj + jstag + 1
           DO ck = ckts, ckte
              nk = ck
              DO ci = MAX(ipos+spec_zone,cits),MIN(ipos+(nide-nids)/nri-istag-spec_zone,cite)
                 ni = (ci-ipos)*nri + istag + 1
                 cfld( ci, ck, cj ) =  nfld( ni  , nk , nj  )
              ENDDO
           ENDDO
        ENDDO

     ELSE  ! even refinement ratio
        DO cj = MAX(jpos+spec_zone,cjts),MIN(jpos+(njde-njds)/nrj-jstag-spec_zone,cjte)
           nj = (cj-jpos)*nrj + 1
           DO ck = ckts, ckte
              nk = ck
              DO ci = MAX(ipos+spec_zone,cits),MIN(ipos+(nide-nids)/nri-istag-spec_zone,cite)
                 ni = (ci-ipos)*nri + 1
                 ipoints = nri/2 -1
                 jpoints = nrj/2 -1
                 cfld( ci, ck, cj ) =  nfld( ni+ipoints , nk , nj+jpoints )
              END DO
           END DO
        END DO

     END IF

     RETURN

   END SUBROUTINE copy_fcni

!==================================


   SUBROUTINE vert_interp_vert_nesting ( cfld,                                 &  ! CD field 1,1
                                         ids, ide, kds, kde, jds, jde,         & 
                                         ims, ime, kms, kme, jms, jme,         &
                                         its, ite, kts, kte, jts, jte,         &   
                                         pgrid_s_vert, pgrid_e_vert,           &  ! vertical dimensions of parent grid
					 cf1_c, cf2_c, cf3_c, cfn_c, cfn1_c,   &  ! coarse grid extrapolation constants
                                         alt_u_c, alt_u_n)

!KAL vertical interpolation for u, v, and mass points (w is below in a different subroutine) for vertical nesting 

   IMPLICIT NONE
   REAL, DIMENSION ( ims:ime, kms:kme, jms:jme ), INTENT(INOUT) :: cfld   
   INTEGER, INTENT(IN) :: ids, ide, kds, kde, jds, jde,   &
                          ims, ime, kms, kme, jms, jme,   &
                          its, ite, kts, kte, jts, jte
   INTEGER, INTENT(IN) :: pgrid_s_vert, pgrid_e_vert                ! vertical dimensions of the parent grid			  
   REAL, INTENT(IN)    :: cf1_c, cf2_c, cf3_c, cfn_c, cfn1_c
   REAL, DIMENSION(pgrid_s_vert:pgrid_e_vert+1), INTENT(IN) :: alt_u_c
   REAL, DIMENSION(kde+1), INTENT(IN) :: alt_u_n

   
   !local
   
   INTEGER :: i,j,k
   REAL, DIMENSION(pgrid_s_vert:pgrid_e_vert+1) :: pro_u_c           ! variable in 1D on the coarse grid
   REAL, DIMENSION(kde+1) :: pro_u_n
   
   DO j = jms,jme
   DO i = ims,ime
   
      ! pro_u_c is u on the 1D coarse grid 
    
      do k = pgrid_s_vert,pgrid_e_vert-1
      pro_u_c(k+1) = cfld(i,k,j)
      enddo 
      
      !KAL fill in the surface value and the top value using extrapolation

      pro_u_c(1      ) = cf1_c*cfld(i,1,j) &
                       + cf2_c*cfld(i,2,j) &
                       + cf3_c*cfld(i,3,j)
   
      pro_u_c(pgrid_e_vert+1) = cfn_c *cfld(i,pgrid_e_vert-1,j) &
                              + cfn1_c*cfld(i,pgrid_e_vert-2,j)  
		       
      call inter_wrf_copy(pro_u_c, alt_u_c, pgrid_e_vert+1, pro_u_n, alt_u_n, kde+1)
      
      do k = 1,kde-1
         cfld(i,k,j) = pro_u_n(k+1)
      enddo	
            
   ENDDO
   ENDDO
  
   
   END SUBROUTINE vert_interp_vert_nesting
   
 !==================================


   SUBROUTINE vert_interp_vert_nesting_w ( cfld,                                 &  ! CD field,1
                                           ids, ide, kds, kde, jds, jde,         & 
                                           ims, ime, kms, kme, jms, jme,         &
                                           its, ite, kts, kte, jts, jte,         &   
                                           pgrid_s_vert, pgrid_e_vert,           &  ! vertical dimensions of parent grid
                                           alt_w_c, alt_w_n)

!KAL vertical interpolation at w points for vertical nesting

   IMPLICIT NONE
   REAL, DIMENSION ( ims:ime, kms:kme, jms:jme ), INTENT(INOUT) :: cfld   
   INTEGER, INTENT(IN) :: ids, ide, kds, kde, jds, jde,   &
                          ims, ime, kms, kme, jms, jme,   &
                          its, ite, kts, kte, jts, jte
   INTEGER, INTENT(IN) :: pgrid_s_vert, pgrid_e_vert                ! vertical dimensions of the parent grid			  
   REAL, DIMENSION(pgrid_s_vert:pgrid_e_vert), INTENT(IN) :: alt_w_c
   REAL, DIMENSION(kde), INTENT(IN) :: alt_w_n

   
   !local
   
   INTEGER :: i,j,k
   REAL, DIMENSION(pgrid_s_vert:pgrid_e_vert) :: pro_w_c           ! variable in 1D on the coarse grid
   REAL, DIMENSION(kde) :: pro_w_n
   
   DO j = jms,jme
   DO i = ims,ime
   
      ! pro_w_c is w on the 1D coarse grid 
    
      do k = pgrid_s_vert,pgrid_e_vert
      pro_w_c(k) = cfld(i,k,j)
      enddo 
	       
      call inter_wrf_copy(pro_w_c, alt_w_c, pgrid_e_vert, pro_w_n, alt_w_n, kde)
      
      do k = 1,kde
         cfld(i,k,j) = pro_w_n(k)
      enddo	
            
   ENDDO
   ENDDO
  
   
   END SUBROUTINE vert_interp_vert_nesting_w

!-----------------------------------------------------------------------------------------   


   SUBROUTINE vert_interp_vert_nesting_1d ( cfld,                                 &  ! CD field 5,1
                                            ids, ide, kds, kde, jds, jde,         & 
                                            ims, ime, kms, kme, jms, jme,         &
                                            its, ite, kts, kte, jts, jte,         &   
                                            pgrid_s_vert, pgrid_e_vert,           &  ! vertical dimensions of parent grid
					    cf1_c, cf2_c, cf3_c, cfn_c, cfn1_c,   &  ! coarse grid extrapolation constants
                                            alt_u_c, alt_u_n)

!KAL vertical interpolation for u, v, and mass points (w is below in a different subroutine) for vertical nesting 

   IMPLICIT NONE
   REAL, DIMENSION (kms:kme),INTENT(INOUT) :: cfld   
   INTEGER, INTENT(IN) :: ids, ide, kds, kde, jds, jde,   &
                          ims, ime, kms, kme, jms, jme,   &
                          its, ite, kts, kte, jts, jte
   INTEGER, INTENT(IN) :: pgrid_s_vert, pgrid_e_vert                ! vertical dimensions of the parent grid			  
   REAL, INTENT(IN)    :: cf1_c, cf2_c, cf3_c, cfn_c, cfn1_c
   REAL, DIMENSION(pgrid_s_vert:pgrid_e_vert+1), INTENT(IN) :: alt_u_c
   REAL, DIMENSION(kde+1), INTENT(IN) :: alt_u_n

   
   !local
   
   INTEGER :: i,j,k
   REAL, DIMENSION(pgrid_s_vert:pgrid_e_vert+1) :: pro_u_c           ! variable in 1D on the coarse grid
   REAL, DIMENSION(kde+1) :: pro_u_n
   

      ! pro_u_c is u on the 1D coarse grid 
    
      do k = pgrid_s_vert,pgrid_e_vert-1
      pro_u_c(k+1) = cfld(k)
      enddo 
      
      !KAL fill in the surface value and the top value using extrapolation

      pro_u_c(1      ) = cf1_c*cfld(1) &
                       + cf2_c*cfld(2) &
                       + cf3_c*cfld(3)
   
      pro_u_c(pgrid_e_vert+1) = cfn_c *cfld(pgrid_e_vert-1) &
                              + cfn1_c*cfld(pgrid_e_vert-2)  
		       
      call inter_wrf_copy(pro_u_c, alt_u_c, pgrid_e_vert+1, pro_u_n, alt_u_n, kde+1)
      
      do k = 1,kde-1
         cfld(k) = pro_u_n(k+1)
      enddo	
            
   
   END SUBROUTINE vert_interp_vert_nesting_1d   
   
     
 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!KAL this is a direct copy of a subroutine from ndown, but a dependency on ndown will not work because it is not always compiled (for ideal cases), and most likely not compliled in the order needed.


  SUBROUTINE inter_wrf_copy(pro_c,alt_c,kde_c,pro_n,alt_n,kde_n) 3,1
  
!KAL this routine has been added for vertical nesting  

   IMPLICIT NONE
   INTEGER , INTENT(IN) :: kde_c,kde_n
   REAL , DIMENSION(kde_c) , INTENT(IN ) :: pro_c,alt_c
   REAL , DIMENSION(kde_n) , INTENT(IN ) :: alt_n
   REAL , DIMENSION(kde_n) , INTENT(OUT) :: pro_n

      real ,dimension(kde_c) :: a,b,c,d
      real :: p
      integer :: i,j


      call coeff_mon_wrf_copy(alt_c,pro_c,a,b,c,d,kde_c)

       do i = 1,kde_n-1

          do j=1,kde_c-1

               if ( (alt_n(i) .ge. alt_c(j)).and.(alt_n(i) .lt. alt_c(j+1)) ) then
                p =  alt_n(i)-alt_c(j)
                pro_n(i) = p*( p*(a(j)*p+b(j))+c(j)) + d(j)
                goto 20
               endif
           enddo
20             continue
       enddo

       pro_n(kde_n) = pro_c(kde_c)


   END SUBROUTINE inter_wrf_copy

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!11
!KAL this is a direct copy of a subroutine from ndown, but a dependency on ndown will not work because it is not always compiled (for ideal cases), and most likely not compliled in the order needed.


     subroutine  coeff_mon_wrf_copy(x,y,a,b,c,d,n) 1
     
!KAL this routine has been added for vertical nesting     

      implicit none

      integer :: n
      real ,dimension(n) :: x,y,a,b,c,d
      real ,dimension(n) :: h,s,p,yp

       integer :: i


      do i=1,n-1
      h(i) = (x(i+1)-x(i))
      s(i) = (y(i+1)-y(i)) / h(i)
      enddo

      do i=2,n-1
      p(i) = (s(i-1)*h(i)+s(i)*h(i-1)) / (h(i-1)+h(i))
      enddo

      p(1) = s(1)
      p(n) = s(n-1)

      do i=1,n
      yp(i) = p(i)
      enddo
!!!!!!!!!!!!!!!!!!!!!

      do i=2,n-1
      yp(i) = (sign(1.,s(i-1))+sign(1.,s(i)))* min( abs(s(i-1)),abs(s(i)),0.5*abs(p(i)))
      enddo

      do i = 1,n-1
      a(i) = (yp(i)+yp(i+1)-2.*s(i))/(h(i)*h(i))
      b(i) = (3.*s(i)-2.*yp(i)-yp(i+1))/h(i)
      c(i) = yp(i)
      d(i) = y(i)
      enddo

      end  subroutine  coeff_mon_wrf_copy
      
  !-----------------------------------------------------------------------------------------
  

!================================== 


   SUBROUTINE p2c ( cfld,                                 &  ! CD field 36,2
                    cids, cide, ckds, ckde, cjds, cjde,   &
                    cims, cime, ckms, ckme, cjms, cjme,   &
                    cits, cite, ckts, ckte, cjts, cjte,   &
                    nfld,                                 &  ! ND field
                    nids, nide, nkds, nkde, njds, njde,   &
                    nims, nime, nkms, nkme, njms, njme,   &
                    nits, nite, nkts, nkte, njts, njte,   &
                    shw,                                  &  ! stencil half width
                    imask,                                &  ! interpolation mask
                    xstag, ystag,                         &  ! staggering of field
                    ipos, jpos,                           &  ! Position of lower left of nest in CD
                    nri, nrj                              &  ! nest ratios
                    )   
     USE module_configure
     IMPLICIT NONE

     INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
                            cims, cime, ckms, ckme, cjms, cjme,   &
                            cits, cite, ckts, ckte, cjts, cjte,   &
                            nids, nide, nkds, nkde, njds, njde,   &
                            nims, nime, nkms, nkme, njms, njme,   &
                            nits, nite, nkts, nkte, njts, njte,   &
                            shw,                                  &
                            ipos, jpos,                           &
                            nri, nrj

     LOGICAL, INTENT(IN) :: xstag, ystag

     REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ) :: cfld
     REAL, DIMENSION ( nims:nime, nkms:nkme, njms:njme ) :: nfld
     INTEGER, DIMENSION ( nims:nime, njms:njme ) :: imask

     CALL  interp_fcn  (cfld,                             &  ! CD field
                        cids, cide, ckds, ckde, cjds, cjde,   &
                        cims, cime, ckms, ckme, cjms, cjme,   &
                        cits, cite, ckts, ckte, cjts, cjte,   &
                        nfld,                             &  ! ND field
                        nids, nide, nkds, nkde, njds, njde,   &
                        nims, nime, nkms, nkme, njms, njme,   &
                        nits, nite, nkts, nkte, njts, njte,   &
                        shw,                                  &  ! stencil half width for interp
                        imask,                                &  ! interpolation mask
                        xstag, ystag,                         &  ! staggering of field
                        ipos, jpos,                           &  ! Position of lower left of nest in CD
                        nri, nrj                             )   ! nest ratios

   END SUBROUTINE p2c

!==================================


   SUBROUTINE c2f_interp ( cfld,                                 &  ! CD field,1
                           cids, cide, ckds, ckde, cjds, cjde,   &
                           cims, cime, ckms, ckme, cjms, cjme,   &
                           cits, cite, ckts, ckte, cjts, cjte,   &
                           nfld,                                 &  ! ND field
                           nids, nide, nkds, nkde, njds, njde,   &
                           nims, nime, nkms, nkme, njms, njme,   &  
                           nits, nite, nkts, nkte, njts, njte,   &
                           shw,                                  &  ! stencil half width
                           imask,                                &  ! interpolation mask
                           xstag, ystag,                         &  ! staggering of field
                           ipos, jpos,                           &  ! Position of lower left of nest in CD
                           nri, nrj,                             &  ! nest ratios
!                          cbdy_xs, nbdy_xs,                           &
!                          cbdy_xe, nbdy_xe,                           &
!                          cbdy_ys, nbdy_ys,                           &
!                          cbdy_ye, nbdy_ye,                           &
!                          cbdy_txs, nbdy_txs,                       &
!                          cbdy_txe, nbdy_txe,                       &
!                          cbdy_tys, nbdy_tys,                       &
!                          cbdy_tye, nbdy_tye,                       &
                           parent_id,nest_id                        &!cyl    
                           )   ! boundary arrays
     USE module_configure
     IMPLICIT NONE

!------------------------------------------------------------
! Subroutine c2f_interp interpolate field from coarse resolution domain
! to its nested domain. It is written by Dave Gill in NCAR for the purpose 
! running phys/module_sf_oml.F-DPWP in only d01 and d02 
!                                       Chiaying Lee RSMAS/UM
!------------------------------------------------------------
                            
     INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
                            cims, cime, ckms, ckme, cjms, cjme,   &
                            cits, cite, ckts, ckte, cjts, cjte,   &
                            nids, nide, nkds, nkde, njds, njde,   &
                            nims, nime, nkms, nkme, njms, njme,   &
                            nits, nite, nkts, nkte, njts, njte,   &
                            shw,                                  &
                            ipos, jpos,                           &
                            nri, nrj,parent_id,nest_id            !cyl

     LOGICAL, INTENT(IN) :: xstag, ystag
     
     REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ) :: cfld
     REAL, DIMENSION ( nims:nime, nkms:nkme, njms:njme ) :: nfld
     INTEGER, DIMENSION ( nims:nime, njms:njme ) :: imask
!    REAL,  DIMENSION( * ), INTENT(INOUT) :: cbdy_xs, cbdy_txs, nbdy_xs, nbdy_txs
!    REAL,  DIMENSION( * ), INTENT(INOUT) :: cbdy_xe, cbdy_txe, nbdy_xe, nbdy_txe
!    REAL,  DIMENSION( * ), INTENT(INOUT) :: cbdy_ys, cbdy_tys, nbdy_ys, nbdy_tys
!    REAL,  DIMENSION( * ), INTENT(INOUT) :: cbdy_ye, cbdy_tye, nbdy_ye, nbdy_tye
     REAL cdt, ndt
     
     ! Local

     INTEGER ci, cj, ck, ni, nj, nk, ip, jp

     ! Iterate over the ND tile and compute the values
     ! from the CD tile. 

!write(0,'("mask cits:cite, ckts:ckte, cjts:cjte ",6i4)')cits,cite, ckts,ckte, cjts,cjte
!write(0,'("mask nits:nite, nkts:nkte, njts:njte ",6i4)')nits,nite, nkts,nkte, njts,njte
!     write(0,*)'cyl parentid',parent_id
!     write(0,*)'cyl nestid',nest_id
!     If ( nest_id .le. 2 .and. (1.0/rdx .ge. 3000.0 .and. 1.0/rdy .ge. 3000.0)  ) then ! cyl: only run it in the nest domain with dx, dy < 3 km
     If ( nest_id .eq. 3 ) then 
     DO nj = njts, njte
     
        cj = jpos + (nj-1) / nrj     ! j coord of CD point 
        jp = mod ( nj , nrj )  ! coord of ND w/i CD point
        DO nk = nkts, nkte
           ck = nk
           DO ni = nits, nite
              ci = ipos + (ni-1) / nri      ! j coord of CD point 
              ip = mod ( ni , nri )  ! coord of ND w/i CD point
              ! This is a trivial implementation of the interp_fcn; just copies
              ! the values from the CD into the ND
              nfld( ni, nk, nj ) = cfld( ci , ck , cj )
           ENDDO
        ENDDO
     ENDDO
     ENDIF  ! cyl
     RETURN

   END SUBROUTINE c2f_interp

!==================================


   SUBROUTINE bdy_interp ( cfld,                                 &  ! CD field,4
                           cids, cide, ckds, ckde, cjds, cjde,   &
                           cims, cime, ckms, ckme, cjms, cjme,   &
                           cits, cite, ckts, ckte, cjts, cjte,   &
                           nfld,                                 &  ! ND field
                           nids, nide, nkds, nkde, njds, njde,   &
                           nims, nime, nkms, nkme, njms, njme,   &
                           nits, nite, nkts, nkte, njts, njte,   &
                           shw,                                  &  ! stencil half width
                           imask,                                &  ! interpolation mask
                           xstag, ystag,                         &  ! staggering of field
                           ipos, jpos,                           &  ! Position of lower left of nest in CD
                           nri, nrj,                             &  ! nest ratios
                           cbdy_xs, nbdy_xs,                     &  ! Boundary components, for the CG and FG,
                           cbdy_xe, nbdy_xe,                     &  ! for each of the four sides (x start, e end, y start, y end)
                           cbdy_ys, nbdy_ys,                     &  ! and also for the two components of the LBC:
                           cbdy_ye, nbdy_ye,                     &  ! the "starting" value and the tendency
                           cbdy_txs, nbdy_txs,                   &
                           cbdy_txe, nbdy_txe,                   &  ! The CG is at a parent time step ahead of the FG
                           cbdy_tys, nbdy_tys,                   &
                           cbdy_tye, nbdy_tye,                   &
                           cdt, ndt                              )  ! Time step size for CG and FG

     USE module_interp_info

     IMPLICIT NONE

     INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
                            cims, cime, ckms, ckme, cjms, cjme,   &
                            cits, cite, ckts, ckte, cjts, cjte,   &
                            nids, nide, nkds, nkde, njds, njde,   &
                            nims, nime, nkms, nkme, njms, njme,   &
                            nits, nite, nkts, nkte, njts, njte,   &
                            shw,                                  &
                            ipos, jpos,                           &
                            nri, nrj

     LOGICAL, INTENT(IN) :: xstag, ystag

     REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ) :: cfld
     REAL, DIMENSION ( nims:nime, nkms:nkme, njms:njme ) :: nfld
     INTEGER, DIMENSION ( nims:nime, njms:njme ) :: imask
     REAL,  DIMENSION( * ), INTENT(INOUT) :: cbdy_xs, cbdy_txs, nbdy_xs, nbdy_txs
     REAL,  DIMENSION( * ), INTENT(INOUT) :: cbdy_xe, cbdy_txe, nbdy_xe, nbdy_txe
     REAL,  DIMENSION( * ), INTENT(INOUT) :: cbdy_ys, cbdy_tys, nbdy_ys, nbdy_tys
     REAL,  DIMENSION( * ), INTENT(INOUT) :: cbdy_ye, cbdy_tye, nbdy_ye, nbdy_tye
     REAL cdt, ndt

     ! Local

     INTEGER nijds, nijde, spec_bdy_width

     nijds = min(nids, njds)
     nijde = max(nide, njde)
     CALL nl_get_spec_bdy_width( 1, spec_bdy_width )

     IF      ( interp_method_type .EQ. NOT_DEFINED_YET  ) THEN
        interp_method_type = SINT
     END IF

     IF      ( interp_method_type .EQ. SINT      ) THEN
         CALL bdy_interp1( cfld,                                 &  ! CD field
                           cids, cide, ckds, ckde, cjds, cjde,   &
                           cims, cime, ckms, ckme, cjms, cjme,   &
                           cits, cite, ckts, ckte, cjts, cjte,   &
                           nfld,                                 &  ! ND field
                           nijds, nijde ,                        &  ! start and end of nest LBC size in the LONG direction
                           spec_bdy_width ,                      &  ! width of the LBC, the SHORT direction
                           nids, nide, nkds, nkde, njds, njde,   &
                           nims, nime, nkms, nkme, njms, njme,   &
                           nits, nite, nkts, nkte, njts, njte,   &
                           shw, imask,                           &
                           xstag, ystag,                         &  ! staggering of field
                           ipos, jpos,                           &  ! Position of lower left of nest in CD
                           nri, nrj,                             &
                           cbdy_xs, nbdy_xs,                     &  ! Boundary components, for the CG and FG,
                           cbdy_xe, nbdy_xe,                     &  ! for each of the four sides (x start, e end, y start, y end)
                           cbdy_ys, nbdy_ys,                     &  ! and also for the two components of the LBC:
                           cbdy_ye, nbdy_ye,                     &  ! the "starting" value and the tendency
                           cbdy_txs, nbdy_txs,                   &
                           cbdy_txe, nbdy_txe,                   &  ! The CG is at a parent time step ahead of the FG
                           cbdy_tys, nbdy_tys,                   &
                           cbdy_tye, nbdy_tye,                   &
                           cdt, ndt                              &  ! Time step size for CG and FG
                                                                 )

     ELSE IF      ( ( interp_method_type .EQ. BILINEAR         ) .OR. &
                    ( interp_method_type .EQ. NEAREST_NEIGHBOR ) .OR. &
                    ( interp_method_type .EQ. QUADRATIC        ) .OR. &
                    ( interp_method_type .EQ. SPLINE           ) .OR. &
                    ( interp_method_type .EQ. SINT_NEW         ) ) THEN 
         CALL bdy_interp2( cfld,                                 &  ! CD field
                           cids, cide, ckds, ckde, cjds, cjde,   &
                           cims, cime, ckms, ckme, cjms, cjme,   &
                           cits, cite, ckts, ckte, cjts, cjte,   &
                           nfld,                                 &  ! ND field
                           nijds, nijde ,                        &  ! start and end of nest LBC size in the LONG direction
                           spec_bdy_width ,                      &  ! width of the LBC, the SHORT direction
                           nids, nide, nkds, nkde, njds, njde,   &
                           nims, nime, nkms, nkme, njms, njme,   &
                           nits, nite, nkts, nkte, njts, njte,   &
                           shw, imask,                           &
                           xstag, ystag,                         &  ! staggering of field
                           ipos, jpos,                           &  ! Position of lower left of nest in CD
                           nri, nrj,                             &
                           cbdy_xs, nbdy_xs,                     &  ! Boundary components, for the CG and FG,
                           cbdy_xe, nbdy_xe,                     &  ! for each of the four sides (x start, e end, y start, y end)
                           cbdy_ys, nbdy_ys,                     &  ! and also for the two components of the LBC:
                           cbdy_ye, nbdy_ye,                     &  ! the "starting" value and the tendency
                           cbdy_txs, nbdy_txs,                   &
                           cbdy_txe, nbdy_txe,                   &  ! The CG is at a parent time step ahead of the FG
                           cbdy_tys, nbdy_tys,                   &
                           cbdy_tye, nbdy_tye,                   &
                           cdt, ndt                              &  ! Time step size for CG and FG
                                                                 )

     ELSE
        CALL wrf_error_fatal ('Hold on there cowboy #2, we need to know which nested lateral boundary interpolation option you want')
     END IF

   END SUBROUTINE bdy_interp

!==================================


   SUBROUTINE bdy_interp1( cfld,                                 &  ! CD field 1,5
                           cids, cide, ckds, ckde, cjds, cjde,   &
                           cims, cime, ckms, ckme, cjms, cjme,   &
                           cits, cite, ckts, ckte, cjts, cjte,   &
                           nfld,                                 &  ! ND field
                           nijds, nijde, spec_bdy_width ,          &
                           nids, nide, nkds, nkde, njds, njde,   &
                           nims, nime, nkms, nkme, njms, njme,   &
                           nits, nite, nkts, nkte, njts, njte,   &
                           shw1,                                 &
                           imask,                                &  ! interpolation mask
                           xstag, ystag,                         &  ! staggering of field
                           ipos, jpos,                           &  ! Position of lower left of nest in CD
                           nri, nrj,                             &
                           cbdy_xs, bdy_xs,                           &
                           cbdy_xe, bdy_xe,                           &
                           cbdy_ys, bdy_ys,                           &
                           cbdy_ye, bdy_ye,                           &
                           cbdy_txs, bdy_txs,                       &
                           cbdy_txe, bdy_txe,                       &
                           cbdy_tys, bdy_tys,                       &
                           cbdy_tye, bdy_tye,                       &
                           cdt, ndt                              &
                                        )

!    USE module_configure , ONLY : nl_get_spec_zone, nl_get_relax_zone
     USE module_state_description

     IMPLICIT NONE

     INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
                            cims, cime, ckms, ckme, cjms, cjme,   &
                            cits, cite, ckts, ckte, cjts, cjte,   &
                            nids, nide, nkds, nkde, njds, njde,   &
                            nims, nime, nkms, nkme, njms, njme,   &
                            nits, nite, nkts, nkte, njts, njte,   &
                            shw1,                                 &  ! ignore
                            ipos, jpos,                           &
                            nri, nrj
     INTEGER, INTENT(IN) :: nijds, nijde, spec_bdy_width
     LOGICAL, INTENT(IN) :: xstag, ystag

     REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ), INTENT(INOUT) :: cfld
     REAL, DIMENSION ( nims:nime, nkms:nkme, njms:njme ), INTENT(INOUT) :: nfld
     INTEGER, DIMENSION ( nims:nime, njms:njme ) :: imask
     REAL, DIMENSION ( * ), INTENT(INOUT) :: cbdy_xs, cbdy_txs   ! not used
     REAL, DIMENSION ( * ), INTENT(INOUT) :: cbdy_xe, cbdy_txe   ! not used
     REAL, DIMENSION ( * ), INTENT(INOUT) :: cbdy_ys, cbdy_tys   ! not used
     REAL, DIMENSION ( * ), INTENT(INOUT) :: cbdy_ye, cbdy_tye   ! not used
     REAL                                 :: cdt, ndt
     REAL, DIMENSION ( njms:njme, nkms:nkme, spec_bdy_width ), INTENT(INOUT) :: bdy_xs, bdy_txs
     REAL, DIMENSION ( njms:njme, nkms:nkme, spec_bdy_width ), INTENT(INOUT) :: bdy_xe, bdy_txe
     REAL, DIMENSION ( nims:nime, nkms:nkme, spec_bdy_width ), INTENT(INOUT) :: bdy_ys, bdy_tys
     REAL, DIMENSION ( nims:nime, nkms:nkme, spec_bdy_width ), INTENT(INOUT) :: bdy_ye, bdy_tye

     ! Local

     REAL*8 rdt
     INTEGER ci, cj, ck, ni, nj, nk, ni1, nj1, nk1, ip, jp, ioff, joff
     INTEGER nfx, ior
     PARAMETER (ior=2)
     INTEGER nf
     REAL psca1(cims:cime,cjms:cjme,nri*nrj)
     REAL psca(cims:cime,cjms:cjme,nri*nrj)
     LOGICAL icmask( cims:cime, cjms:cjme )
     INTEGER i,j,k
     INTEGER shw
     INTEGER spec_zone 
     INTEGER relax_zone
     INTEGER sz
     INTEGER n2ci,n
     INTEGER n2cj

! statement functions for converting a nest index to coarse
     n2ci(n) = (n+ipos*nri-1)/nri
     n2cj(n) = (n+jpos*nrj-1)/nrj

     rdt = 1.D0/cdt

     shw = 0

     ioff  = 0 ; joff  = 0
     IF ( xstag ) THEN 
       ioff = MAX((nri-1)/2,1)
     ENDIF
     IF ( ystag ) THEN
       joff = MAX((nrj-1)/2,1)
     ENDIF

     ! Iterate over the ND tile and compute the values
     ! from the CD tile. 

     CALL nl_get_spec_zone( 1, spec_zone )
     CALL nl_get_relax_zone( 1, relax_zone )
     sz = MIN(MAX( spec_zone, relax_zone + 1 ),spec_bdy_width)

     nfx = nri * nrj

   !$OMP PARALLEL DO   &
   !$OMP PRIVATE ( i,j,k,ni,nj,ni1,nj1,ci,cj,ip,jp,nk,ck,nf,icmask,psca,psca1 )
     DO k = ckts, ckte

        DO nf = 1,nfx
           DO j = cjms,cjme
              nj = (j-jpos) * nrj + ( nrj / 2 + 1 )  ! j point on nest
              DO i = cims,cime
                ni = (i-ipos) * nri + ( nri / 2 + 1 )   ! i point on nest
                psca1(i,j,nf) = cfld(i,k,j)
              ENDDO
           ENDDO
        ENDDO
! hopefully less ham handed but still correct and more efficient
! sintb ignores icmask so it does not matter that icmask is not set
!
! SOUTH BDY
               IF   ( njts .ge. njds .and. njts .le. njds + sz + joff  ) THEN
        CALL sintb( psca1, psca,                     &
          cims, cime, cjms, cjme, icmask,  &
          n2ci(nits)-1, n2ci(nite)+1, n2cj(MAX(njts,njds)), n2cj(MIN(njte,njds+sz+joff)), nrj*nri, xstag, ystag )
               ENDIF
! NORTH BDY
               IF   ( njte .le. njde .and. njte .ge. njde - sz - joff ) THEN
        CALL sintb( psca1, psca,                     &
          cims, cime, cjms, cjme, icmask,  &
          n2ci(nits)-1, n2ci(nite)+1, n2cj(MAX(njts,njde-sz-joff)), n2cj(MIN(njte,njde-1+joff)), nrj*nri, xstag, ystag )
               ENDIF
! WEST BDY
               IF   ( nits .ge. nids .and. nits .le. nids + sz + ioff  ) THEN
        CALL sintb( psca1, psca,                     &
          cims, cime, cjms, cjme, icmask,  &
          n2ci(MAX(nits,nids)), n2ci(MIN(nite,nids+sz+ioff)), n2cj(njts)-1, n2cj(njte)+1, nrj*nri, xstag, ystag )
               ENDIF
! EAST BDY
               IF   ( nite .le. nide .and. nite .ge. nide - sz - ioff ) THEN
        CALL sintb( psca1, psca,                     &
          cims, cime, cjms, cjme, icmask,  &
          n2ci(MAX(nits,nide-sz-ioff)), n2ci(MIN(nite,nide-1+ioff)), n2cj(njts)-1, n2cj(njte)+1, nrj*nri, xstag, ystag )
               ENDIF

        DO nj1 = MAX(njds,njts-1), MIN(njde+joff,njte+joff+1) 
           cj = jpos + (nj1-1) / nrj     ! j coord of CD point 
           jp = mod ( nj1-1 , nrj )  ! coord of ND w/i CD point
           nk = k
           ck = nk
           DO ni1 = MAX(nids,nits-1), MIN(nide+ioff,nite+ioff+1)
               ci = ipos + (ni1-1) / nri      ! j coord of CD point 
               ip = mod ( ni1-1 , nri )  ! coord of ND w/i CD point

               ni = ni1-ioff
               nj = nj1-joff

               IF ( ( ni.LT.nids) .OR. (nj.LT.njds) ) THEN
                  CYCLE
               END IF

!bdy contains the value at t-dt. psca contains the value at t
!compute dv/dt and store in bdy_t
!afterwards store the new value of v at t into bdy
        ! WEST
               IF   ( ni .ge. nids .and. ni .lt. nids + sz ) THEN
                 bdy_txs( nj,k,ni ) = rdt*(psca(ci+shw,cj+shw,ip+1+(jp)*nri)-nfld(ni,k,nj))
                 bdy_xs( nj,k,ni ) = nfld(ni,k,nj)
               ENDIF

        ! SOUTH
               IF   ( nj .ge. njds .and. nj .lt. njds + sz ) THEN
                 bdy_tys( ni,k,nj ) = rdt*(psca(ci+shw,cj+shw,ip+1+(jp)*nri)-nfld(ni,k,nj))
                 bdy_ys( ni,k,nj ) = nfld(ni,k,nj)
               ENDIF

        ! EAST
               IF ( xstag ) THEN
                 IF   ( ni .ge. nide - sz + 1 .AND. ni .le. nide ) THEN
                   bdy_txe( nj,k,nide-ni+1 ) = rdt*(psca(ci+shw,cj+shw,ip+1+(jp)*nri)-nfld(ni,k,nj))
                   bdy_xe( nj,k,nide-ni+1 ) = nfld(ni,k,nj)
                 ENDIF
               ELSE
                 IF   ( ni .ge. nide - sz .AND. ni .le. nide-1 ) THEN
                   bdy_txe( nj,k,nide-ni ) = rdt*(psca(ci+shw,cj+shw,ip+1+(jp)*nri)-nfld(ni,k,nj))
                   bdy_xe( nj,k,nide-ni ) = nfld(ni,k,nj)
                 ENDIF
               ENDIF

        ! NORTH
               IF ( ystag ) THEN
                 IF   ( nj .ge. njde - sz + 1 .AND. nj .le. njde  ) THEN
                   bdy_tye( ni,k,njde-nj+1 ) = rdt*(psca(ci+shw,cj+shw,ip+1+(jp)*nri)-nfld(ni,k,nj))
                   bdy_ye( ni,k,njde-nj+1 ) = nfld(ni,k,nj)
                 ENDIF
               ELSE
                 IF   (  nj .ge. njde - sz .AND. nj .le. njde-1 ) THEN
                   bdy_tye(ni,k,njde-nj ) = rdt*(psca(ci+shw,cj+shw,ip+1+(jp)*nri)-nfld(ni,k,nj))
                   bdy_ye( ni,k,njde-nj ) = nfld(ni,k,nj)
                 ENDIF
               ENDIF

           ENDDO
        ENDDO
     ENDDO
   !$OMP END PARALLEL DO
                  
     RETURN

   END SUBROUTINE bdy_interp1

!==================================


   SUBROUTINE bdy_interp2( cfld,                                 &  ! CD field 1,2
                           cids, cide, ckds, ckde, cjds, cjde,   &
                           cims, cime, ckms, ckme, cjms, cjme,   &
                           cits, cite, ckts, ckte, cjts, cjte,   &
                           nfld,                                 &  ! ND field
                           nijds, nijde, spec_bdy_width ,        &
                           nids, nide, nkds, nkde, njds, njde,   &
                           nims, nime, nkms, nkme, njms, njme,   &
                           nits, nite, nkts, nkte, njts, njte,   &
                           shw1,                                 &
                           imask,                                &  ! interpolation mask
                           xstag, ystag,                         &  ! staggering of field
                           ipos, jpos,                           &  ! Position of lower left of nest in CD
                           nri, nrj,                             &
                           cbdy_xs, bdy_xs,                      &
                           cbdy_xe, bdy_xe,                      &
                           cbdy_ys, bdy_ys,                      &
                           cbdy_ye, bdy_ye,                      &
                           cbdy_txs, bdy_txs,                    &
                           cbdy_txe, bdy_txe,                    &
                           cbdy_tys, bdy_tys,                    &
                           cbdy_tye, bdy_tye,                    &
                           cdt, ndt                              &
                                                                 )

!    USE module_configure , ONLY : nl_get_spec_zone, nl_get_relax_zone
!    USE module_state_description
     USE module_interp_info

     IMPLICIT NONE

     INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
                            cims, cime, ckms, ckme, cjms, cjme,   &
                            cits, cite, ckts, ckte, cjts, cjte,   &
                            nids, nide, nkds, nkde, njds, njde,   &
                            nims, nime, nkms, nkme, njms, njme,   &
                            nits, nite, nkts, nkte, njts, njte,   &
                            shw1,                                 &  ! ignore
                            ipos, jpos,                           &
                            nri, nrj
     INTEGER, INTENT(IN) :: nijds, nijde, spec_bdy_width
     LOGICAL, INTENT(IN) :: xstag, ystag

     REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ), INTENT(INOUT) :: cfld
     REAL, DIMENSION ( nims:nime, nkms:nkme, njms:njme ), INTENT(INOUT) :: nfld
     INTEGER, DIMENSION ( nims:nime, njms:njme ) :: imask
     REAL, DIMENSION ( * ), INTENT(INOUT) :: cbdy_xs, cbdy_txs   ! not used
     REAL, DIMENSION ( * ), INTENT(INOUT) :: cbdy_xe, cbdy_txe   ! not used
     REAL, DIMENSION ( * ), INTENT(INOUT) :: cbdy_ys, cbdy_tys   ! not used
     REAL, DIMENSION ( * ), INTENT(INOUT) :: cbdy_ye, cbdy_tye   ! not used
     REAL                                 :: cdt, ndt
     REAL, DIMENSION ( njms:njme, nkms:nkme, spec_bdy_width ), INTENT(INOUT) :: bdy_xs, bdy_txs
     REAL, DIMENSION ( njms:njme, nkms:nkme, spec_bdy_width ), INTENT(INOUT) :: bdy_xe, bdy_txe
     REAL, DIMENSION ( nims:nime, nkms:nkme, spec_bdy_width ), INTENT(INOUT) :: bdy_ys, bdy_tys
     REAL, DIMENSION ( nims:nime, nkms:nkme, spec_bdy_width ), INTENT(INOUT) :: bdy_ye, bdy_tye

     ! Local

     REAL, DIMENSION ( nims:nime, nkms:nkme, njms:njme ) :: nfld_horiz_interp ! mem dimensioned on purpose
                                                                              ! to allow interpolating routine
                                                                              ! to assume this is a mem
                                                                              ! sized array
     INTEGER ni, nj, nk, istag, jstag
     INTEGER shw
     INTEGER spec_zone 
     INTEGER relax_zone
     INTEGER sz
     REAL*8 rdt

     shw = 0  ! dummy, not used, but needed for the calling interface

     !  Horizontally interpolate the CG to the FG, store in nfld_horiz_interp

     CALL interp_fcn ( cfld,                                 &  ! CD field
                       cids, cide, ckds, ckde, cjds, cjde,   &
                       cims, cime, ckms, ckme, cjms, cjme,   &
                       cits, cite, ckts, ckte, cjts, cjte,   &
                       nfld_horiz_interp,                    &  ! ND field
                       nids, nide, nkds, nkde, njds, njde,   &
                       nims, nime, nkms, nkme, njms, njme,   &
                       MAX(nits-nri,nids),MIN(nite+nri,nide),&
                       nkts, nkte,                           &
                       MAX(njts-nrj,njds),MIN(njte+nrj,njde),&
                       shw,                                  &  ! stencil half width for interp
                       imask,                                &  ! interpolation mask
                       xstag, ystag,                         &  ! staggering of field
                       ipos, jpos,                           &  ! Position of lower left of nest in CD
!                      ipos-1, jpos-1,                       &  ! Position of lower left of nest in CD
                       nri, nrj                              )  ! Nest ratio, i- and j-directions

     !  Staggering, to determine loop indexes

     IF ( xstag ) THEN 
        istag = 0
     ELSE
        istag = 1
     END IF
     IF ( ystag ) THEN
        jstag = 0
     ELSE 
        jstag = 1
     END IF

     !  CG time step reciprocal, for computing tendencies.

     rdt = 1.D0/cdt

     CALL nl_get_spec_zone( 1, spec_zone )
     CALL nl_get_relax_zone( 1, relax_zone )

     !  Belt and suspenders ... sz is just spec_bdy_width.

     sz = MIN(MAX( spec_zone, relax_zone + 1 ),spec_bdy_width)

   !$OMP PARALLEL DO   &
   !$OMP PRIVATE ( ni,nj,nk )
     
     DO nj = MAX ( njts-nrj, njds ) , MIN ( njte+nrj, njde-jstag )
        DO nk = nkts, nkte
           DO ni = MAX( nits-nri, nids ) , MIN ( nite+nri, nide-istag )

              !  WEST boundary

              IF ( ni .LT. nids + sz ) THEN
                  bdy_txs(nj,nk,ni) = rdt*(nfld_horiz_interp(ni,nk,nj)-nfld(ni,nk,nj))
                  bdy_xs (nj,nk,ni) =      nfld(ni,nk,nj)
              END IF

               !  SOUTH boundary

               IF ( nj .LT. njds + sz ) THEN
                  bdy_tys(ni,nk,nj) = rdt*(nfld_horiz_interp(ni,nk,nj)-nfld(ni,nk,nj))
                  bdy_ys (ni,nk,nj) =      nfld(ni,nk,nj)
               END IF

               !  EAST boundary

               IF ( xstag ) THEN
                  IF ( ( ni .GE. nide - sz + 1 ) .AND. ( ni .LE. nide ) ) THEN
                     bdy_txe(nj,nk,nide-ni+1) = rdt*(nfld_horiz_interp(ni,nk,nj)-nfld(ni,nk,nj))
                     bdy_xe (nj,nk,nide-ni+1) =      nfld(ni,nk,nj)
                  END IF
               ELSE
                  IF ( ( ni .GE. nide - sz ) .AND. ( ni .LE. nide-1 ) ) THEN
                     bdy_txe(nj,nk,nide-ni  ) = rdt*(nfld_horiz_interp(ni,nk,nj)-nfld(ni,nk,nj))
                     bdy_xe (nj,nk,nide-ni  ) =      nfld(ni,nk,nj)
                  END IF
               END IF

               !  NORTH boundary

               IF ( ystag ) THEN
                  IF ( ( nj .GE. njde - sz + 1 ) .AND. ( nj .LE. njde  ) ) THEN
                     bdy_tye(ni,nk,njde-nj+1) = rdt*(nfld_horiz_interp(ni,nk,nj)-nfld(ni,nk,nj))
                     bdy_ye (ni,nk,njde-nj+1) =      nfld(ni,nk,nj)
                  END IF
               ELSE
                  IF ( (  nj .GE. njde - sz ) .AND. ( nj .LE. njde-1 ) ) THEN
                     bdy_tye(ni,nk,njde-nj  ) = rdt*(nfld_horiz_interp(ni,nk,nj)-nfld(ni,nk,nj))
                     bdy_ye (ni,nk,njde-nj  ) =      nfld(ni,nk,nj)
                  END IF
               END IF

           END DO      ! nest i
        END DO         ! nest k
     END DO            ! nest j

   !$OMP END PARALLEL DO

   END SUBROUTINE bdy_interp2

!==================================


   SUBROUTINE interp_fcni( cfld,                                 &  ! CD field,1
                           cids, cide, ckds, ckde, cjds, cjde,   &
                           cims, cime, ckms, ckme, cjms, cjme,   &
                           cits, cite, ckts, ckte, cjts, cjte,   &
                           nfld,                                 &  ! ND field
                           nids, nide, nkds, nkde, njds, njde,   &
                           nims, nime, nkms, nkme, njms, njme,   &
                           nits, nite, nkts, nkte, njts, njte,   &
                           shw,                                  &  ! stencil half width
                           imask,                                &  ! interpolation mask
                           xstag, ystag,                         &  ! staggering of field
                           ipos, jpos,                           &  ! Position of lower left of nest in CD
                           nri, nrj                             )   ! nest ratios
     USE module_configure
     IMPLICIT NONE


     INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
                            cims, cime, ckms, ckme, cjms, cjme,   &
                            cits, cite, ckts, ckte, cjts, cjte,   &
                            nids, nide, nkds, nkde, njds, njde,   &
                            nims, nime, nkms, nkme, njms, njme,   &
                            nits, nite, nkts, nkte, njts, njte,   &
                            shw,                                  &
                            ipos, jpos,                           &
                            nri, nrj
     LOGICAL, INTENT(IN) :: xstag, ystag

     INTEGER, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ) :: cfld
     INTEGER, DIMENSION ( nims:nime, nkms:nkme, njms:njme ) :: nfld
     INTEGER, DIMENSION ( nims:nime, njms:njme ) :: imask

     ! Local

     INTEGER ci, cj, ck, ni, nj, nk, ip, jp

     ! Iterate over the ND tile and compute the values
     ! from the CD tile. 

!write(0,'("cits:cite, ckts:ckte, cjts:cjte ",6i4)')cits,cite, ckts,ckte, cjts,cjte
!write(0,'("nits:nite, nkts:nkte, njts:njte ",6i4)')nits,nite, nkts,nkte, njts,njte

     DO nj = njts, njte
        cj = jpos + (nj-1) / nrj     ! j coord of CD point 
        jp = mod ( nj , nrj )  ! coord of ND w/i CD point
        DO nk = nkts, nkte
           ck = nk
           DO ni = nits, nite
              if ( imask(ni,nj) .NE. 1 ) cycle
              ci = ipos + (ni-1) / nri      ! j coord of CD point 
              ip = mod ( ni , nri )  ! coord of ND w/i CD point
              ! This is a trivial implementation of the interp_fcn; just copies
              ! the values from the CD into the ND
              nfld( ni, nk, nj ) = cfld( ci , ck , cj )
           ENDDO
        ENDDO
     ENDDO

     RETURN

   END SUBROUTINE interp_fcni


   SUBROUTINE interp_fcnm( cfld,                                 &  ! CD field,1
                           cids, cide, ckds, ckde, cjds, cjde,   &
                           cims, cime, ckms, ckme, cjms, cjme,   &
                           cits, cite, ckts, ckte, cjts, cjte,   &
                           nfld,                                 &  ! ND field
                           nids, nide, nkds, nkde, njds, njde,   &
                           nims, nime, nkms, nkme, njms, njme,   &
                           nits, nite, nkts, nkte, njts, njte,   &
                           shw,                                  &  ! stencil half width
                           imask,                                &  ! interpolation mask
                           xstag, ystag,                         &  ! staggering of field
                           ipos, jpos,                           &  ! Position of lower left of nest in CD
                           nri, nrj                             )   ! nest ratios
     USE module_configure
     IMPLICIT NONE


     INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
                            cims, cime, ckms, ckme, cjms, cjme,   &
                            cits, cite, ckts, ckte, cjts, cjte,   &
                            nids, nide, nkds, nkde, njds, njde,   &
                            nims, nime, nkms, nkme, njms, njme,   &
                            nits, nite, nkts, nkte, njts, njte,   &
                            shw,                                  &
                            ipos, jpos,                           &
                            nri, nrj
     LOGICAL, INTENT(IN) :: xstag, ystag

     REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ) :: cfld
     REAL, DIMENSION ( nims:nime, nkms:nkme, njms:njme ) :: nfld
     INTEGER, DIMENSION ( nims:nime, njms:njme ) :: imask

     ! Local

     INTEGER ci, cj, ck, ni, nj, nk, ip, jp

     ! Iterate over the ND tile and compute the values
     ! from the CD tile. 

!write(0,'("mask cits:cite, ckts:ckte, cjts:cjte ",6i4)')cits,cite, ckts,ckte, cjts,cjte
!write(0,'("mask nits:nite, nkts:nkte, njts:njte ",6i4)')nits,nite, nkts,nkte, njts,njte

     DO nj = njts, njte
        cj = jpos + (nj-1) / nrj     ! j coord of CD point 
        jp = mod ( nj , nrj )  ! coord of ND w/i CD point
        DO nk = nkts, nkte
           ck = nk
           DO ni = nits, nite
              ci = ipos + (ni-1) / nri      ! j coord of CD point 
              ip = mod ( ni , nri )  ! coord of ND w/i CD point
              ! This is a trivial implementation of the interp_fcn; just copies
              ! the values from the CD into the ND
              nfld( ni, nk, nj ) = cfld( ci , ck , cj )
           ENDDO
        ENDDO
     ENDDO

     RETURN

   END SUBROUTINE interp_fcnm


   SUBROUTINE interp_fcnm_lu( cfld,                              &  ! CD field,6
                           cids, cide, ckds, ckde, cjds, cjde,   &
                           cims, cime, ckms, ckme, cjms, cjme,   &
                           cits, cite, ckts, ckte, cjts, cjte,   &
                           nfld,                                 &  ! ND field
                           nids, nide, nkds, nkde, njds, njde,   &
                           nims, nime, nkms, nkme, njms, njme,   &
                           nits, nite, nkts, nkte, njts, njte,   &
                           shw,                                  &  ! stencil half width
                           imask,                                &  ! interpolation mask
                           xstag, ystag,                         &  ! staggering of field
                           ipos, jpos,                           &  ! Position of lower left of nest in CD
                           nri, nrj,                             &  ! nest ratios
                           cxlat,    nxlat,                      &
                           cxlong,   nxlong,                     &
                           cdx, ndx,                             &
                           cid, nid                            ) 
     USE module_configure

     IMPLICIT NONE


     INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
                            cims, cime, ckms, ckme, cjms, cjme,   &
                            cits, cite, ckts, ckte, cjts, cjte,   &
                            nids, nide, nkds, nkde, njds, njde,   &
                            nims, nime, nkms, nkme, njms, njme,   &
                            nits, nite, nkts, nkte, njts, njte,   &
                            shw,                                  &
                            ipos, jpos,                           &
                            nri, nrj,                             &
                            cid, nid
     LOGICAL, INTENT(IN) :: xstag, ystag 

     REAL,    INTENT(IN) :: cdx, ndx

     REAL,    INTENT(IN),  DIMENSION ( cims:cime, cjms:cjme ) :: cxlat, cxlong
     REAL,    INTENT(IN),  DIMENSION ( nims:nime, njms:njme ) :: nxlat, nxlong


     REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ) :: cfld
     REAL, DIMENSION ( nims:nime, nkms:nkme, njms:njme ) :: nfld
     INTEGER, DIMENSION ( nims:nime, njms:njme ) :: imask

     ! Local

     INTEGER i, ci, cj, ck, ni, nj, nk, ip, jp, ierr

#ifdef TERRAIN_AND_LANDUSE
     INTEGER, DIMENSION(256) :: ipath  ! array for integer coded ascii for passing path down to get_landuse

     REAL , ALLOCATABLE, DIMENSION(:,:) :: xlat_g, xlon_g, landuse_g
     CHARACTER*256 :: message 
     CHARACTER*256 :: rsmas_data_path

     LOGICAL :: input_from_hires, input_from_file

     INTEGER, EXTERNAL :: get_landuse
     LOGICAL, EXTERNAL :: wrf_dm_on_monitor

     CALL nl_get_input_from_hires( nid , input_from_hires)
     CALL nl_get_input_from_file ( nid , input_from_file )

     IF ( input_from_file .AND. input_from_hires ) THEN
       Write(message, '(a,i3,a)') & 
          "Warning : input_from_file turned on for domain ", nid, ", input_from_hires disabled"
       CALL wrf_message(message)
     END IF

     IF ( .NOT. input_from_file .AND. input_from_hires ) THEN

       allocate(xlat_g(nids:nide,njds:njde))
       allocate(xlon_g(nids:nide,njds:njde))
       allocate(landuse_g(nids:nide,njds:njde))

       CALL nl_get_rsmas_data_path(1,rsmas_data_path)

       DO i = 1, LEN(TRIM(rsmas_data_path))
          ipath(i) = ICHAR(rsmas_data_path(i:i))
       ENDDO

#if ( defined( DM_PARALLEL ) && ( ! defined( STUBMPI ) ) )
       CALL wrf_patch_to_global_real ( nxlat, xlat_g , nid, ' ' , 'xy' ,   &
                                       nids, nide-1 , njds , njde-1 , 1 , 1 ,             &
                                       nims, nime   , njms , njme   , 1 , 1 ,             &
                                       nits, nite   , njts , njte   , 1 , 1   )
       CALL wrf_patch_to_global_real ( nxlong, xlon_g, nid, ' ' , 'xy' ,   &
                                       nids, nide-1 , njds , njde-1 , 1 , 1 ,             &
                                       nims, nime   , njms , njme   , 1 , 1 ,             &
                                       nits, nite   , njts , njte   , 1 , 1   )
       IF ( wrf_dm_on_monitor() ) THEN
         ierr = get_landuse ( ndx/1000., xlat_g, xlon_g, &
                              landuse_g,                                        &
                              nide-nids+1,njde-njds+1,nide-nids+1,njde-njds+1,  &
                              ipath, LEN(TRIM(rsmas_data_path)) )
         IF ( ierr == 1 ) THEN
            WRITE(message,fmt='(a)') 'get_landuse : aborted!'
            CALL wrf_error_fatal(TRIM(message))
         ENDIF
       ENDIF

       CALL wrf_global_to_patch_real ( landuse_g , nfld(:,1,:), nid, ' ' , 'xy' ,  &
                                      nids, nide-1 , njds , njde-1 , 1 , 1 ,    &
                                      nims, nime   , njms , njme   , 1 , 1 ,    &
                                      nits, nite   , njts , njte   , 1 , 1   )

#else
       ierr = get_landuse ( ndx/1000., nxlat(nids:nide,njds:njde), nxlong(nids:nide,njds:njde),  &
                            nfld(nids:nide,1,njds:njde),                                         &
                            nide-nids+1,njde-njds+1,nide-nids+1,njde-njds+1,                     &
                            ipath, LEN(TRIM(rsmas_data_path)) )
#endif
       deallocate(xlat_g)
       deallocate(xlon_g)
       deallocate(landuse_g)
     ELSE
#endif
   ! Iterate over the ND tile and compute the values
   ! from the CD tile.
     DO nj = njts, njte
        cj = jpos + (nj-1) / nrj     ! j coord of CD point
        jp = mod ( nj , nrj )  ! coord of ND w/i CD point
        DO nk = nkts, nkte
           ck = nk
           DO ni = nits, nite
              ci = ipos + (ni-1) / nri      ! j coord of CD point
              ip = mod ( ni , nri )  ! coord of ND w/i CD point
              ! This is a trivial implementation of the interp_fcn; just copies
              ! the values from the CD into the ND
              if ( imask(ni,nj) .eq. 1 ) then
               nfld( ni, nk, nj ) = cfld( ci , ck , cj )
              endif
           ENDDO
        ENDDO
     ENDDO
#ifdef TERRAIN_AND_LANDUSE
     END IF
#endif
     RETURN

   END SUBROUTINE interp_fcnm_lu



   SUBROUTINE interp_fcnm_imask( cfld,                           &  ! CD field,1
                           cids, cide, ckds, ckde, cjds, cjde,   &
                           cims, cime, ckms, ckme, cjms, cjme,   &
                           cits, cite, ckts, ckte, cjts, cjte,   &
                           nfld,                                 &  ! ND field
                           nids, nide, nkds, nkde, njds, njde,   &
                           nims, nime, nkms, nkme, njms, njme,   &
                           nits, nite, nkts, nkte, njts, njte,   &
                           shw,                                  &  ! stencil half width
                           imask,                                &  ! interpolation mask
                           xstag, ystag,                         &  ! staggering of field
                           ipos, jpos,                           &  ! Position of lower left of nest in CD
                           nri, nrj                             )   ! nest ratios
     USE module_configure
     IMPLICIT NONE


     INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
                            cims, cime, ckms, ckme, cjms, cjme,   &
                            cits, cite, ckts, ckte, cjts, cjte,   &
                            nids, nide, nkds, nkde, njds, njde,   &
                            nims, nime, nkms, nkme, njms, njme,   &
                            nits, nite, nkts, nkte, njts, njte,   &
                            shw,                                  &
                            ipos, jpos,                           &
                            nri, nrj
     LOGICAL, INTENT(IN) :: xstag, ystag

     REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ) :: cfld
     REAL, DIMENSION ( nims:nime, nkms:nkme, njms:njme ) :: nfld
     INTEGER, DIMENSION ( nims:nime, njms:njme ) :: imask

     ! Local

     INTEGER ci, cj, ck, ni, nj, nk, ip, jp

     ! Iterate over the ND tile and compute the values
     ! from the CD tile. 

!write(0,'("mask cits:cite, ckts:ckte, cjts:cjte ",6i4)')cits,cite, ckts,ckte,cjts,cjte
!write(0,'("mask nits:nite, nkts:nkte, njts:njte ",6i4)')nits,nite, nkts,nkte,njts,njte

     DO nj = njts, njte
        cj = jpos + (nj-1) / nrj     ! j coord of CD point 
        jp = mod ( nj , nrj )  ! coord of ND w/i CD point
        DO nk = nkts, nkte
           ck = nk
           DO ni = nits, nite
              ci = ipos + (ni-1) / nri      ! j coord of CD point 
              ip = mod ( ni , nri )  ! coord of ND w/i CD point
              ! This is a trivial implementation of the interp_fcn; just copies
              ! the values from the CD into the ND
              if ( imask(ni,nj) .eq. 1 ) then
               nfld( ni, nk, nj ) = cfld( ci , ck , cj )
              endif
           ENDDO
        ENDDO
     ENDDO

     RETURN

   END SUBROUTINE interp_fcnm_imask
#endif
! end of first block of ARW-only routines

! NMM: We still allow interp_mask_land_field because it is needed, but no
! equivalent exists.  Use of this in WRF-NMM is an error and will have
! unintended consequences.

   SUBROUTINE interp_mask_land_field ( enable,                   &  ! says whether to allow interpolation or just the bcasts,7
                                       cfld,                     &  ! CD field
                           cids, cide, ckds, ckde, cjds, cjde,   &
                           cims, cime, ckms, ckme, cjms, cjme,   &
                           cits, cite, ckts, ckte, cjts, cjte,   &
                           nfld,                                 &  ! ND field
                           nids, nide, nkds, nkde, njds, njde,   &
                           nims, nime, nkms, nkme, njms, njme,   &
                           nits, nite, nkts, nkte, njts, njte,   &
                           shw,                                  &  ! stencil half width
                           imask,                                &  ! interpolation mask
                           xstag, ystag,                         &  ! staggering of field
                           ipos, jpos,                           &  ! Position of lower left of nest in CD
                           nri, nrj,                             &  ! nest ratios
                           clu, nlu                              )

      USE module_configure
      USE module_wrf_error
      USE module_dm, only : wrf_dm_sum_reals, wrf_dm_sum_integers

      IMPLICIT NONE
   
   
      LOGICAL, INTENT(IN) :: enable
      INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
                             cims, cime, ckms, ckme, cjms, cjme,   &
                             cits, cite, ckts, ckte, cjts, cjte,   &
                             nids, nide, nkds, nkde, njds, njde,   &
                             nims, nime, nkms, nkme, njms, njme,   &
                             nits, nite, nkts, nkte, njts, njte,   &
                             shw,                                  &
                             ipos, jpos,                           &
                             nri, nrj
      LOGICAL, INTENT(IN) :: xstag, ystag
   
      REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ) :: cfld
      REAL, DIMENSION ( nims:nime, nkms:nkme, njms:njme ) :: nfld
     INTEGER, DIMENSION ( nims:nime, njms:njme ) :: imask
   
      REAL, DIMENSION ( cims:cime, cjms:cjme ) :: clu
      REAL, DIMENSION ( nims:nime, njms:njme ) :: nlu
   
      ! Local
   
      INTEGER ci, cj, ck, ni, nj, nk, ip, jp
      INTEGER :: icount , ii , jj , ist , ien , jst , jen , iswater, ierr
      REAL :: avg , sum , dx , dy
      INTEGER , PARAMETER :: max_search = 5
      CHARACTER(LEN=255) :: message
      INTEGER :: icount_n(nkts:nkte), idummy(nkts:nkte)
      REAL :: avg_n(nkts:nkte), sum_n(nkts:nkte), dummy(nkts:nkte)
   
      !  Find out what the water value is.
   
      CALL nl_get_iswater(1,iswater)

      !  Right now, only mass point locations permitted.
   
      IF ( ( .NOT. xstag) .AND. ( .NOT. ystag ) ) THEN

         !  Loop over each i,k,j in the nested domain.

       IF ( enable ) THEN

         DO nj = njts, njte
            IF ( MOD ( nrj , 2 ) .EQ. 0 ) THEN
               cj = ( nj + (nrj/2)-1 ) / nrj + jpos -1 ! first coarse position equal to or below nest point
            ELSE
               cj = ( nj + (nrj-1)/2 ) / nrj + jpos -1 ! first coarse position equal to or below nest point
            END IF
            DO nk = nkts, nkte
               ck = nk
               DO ni = nits, nite
                  IF ( imask(ni, nj) .NE. 1 ) cycle
                  IF ( MOD ( nri , 2 ) .EQ. 0 ) THEN
                     ci = ( ni + (nri/2)-1 ) / nri + ipos -1 ! first coarse position equal to or to the left of nest point
                  ELSE
                     ci = ( ni + (nri-1)/2 ) / nri + ipos -1 ! first coarse position equal to or to the left of nest point
                  END IF
   



                  !
                  !                    (ci,cj+1)     (ci+1,cj+1)
                  !               -        -------------
                  !         1-dy  |        |           |
                  !               |        |           |
                  !               -        |  *        |
                  !          dy   |        | (ni,nj)   |
                  !               |        |           |
                  !               -        -------------
                  !                    (ci,cj)       (ci+1,cj)  
                  !
                  !                        |--|--------|
                  !                         dx  1-dx         


                  !  For odd ratios, at (nri+1)/2, we are on the coarse grid point, so dx = 0

                  IF ( MOD ( nri , 2 ) .EQ. 0 ) THEN
                     dx = ( REAL ( MOD ( ni+(nri-1)/2 , nri ) ) + 0.5 ) / REAL ( nri ) 
                  ELSE 
                     dx =   REAL ( MOD ( ni+(nri-1)/2 , nri ) )         / REAL ( nri ) 
                  END IF
                  IF ( MOD ( nrj , 2 ) .EQ. 0 ) THEN
                     dy = ( REAL ( MOD ( nj+(nrj-1)/2 , nrj ) ) + 0.5 ) / REAL ( nrj ) 
                  ELSE 
                     dy =   REAL ( MOD ( nj+(nrj-1)/2 , nrj ) )         / REAL ( nrj ) 
                  END IF
   
                  !  This is a "land only" field.  If this is a water point, no operations required.

                  IF      ( ( NINT(nlu(ni  ,nj  )) .EQ. iswater ) ) THEN
                     nfld(ni,nk,nj) =  cfld(ci  ,ck,cj  )

                  !  If this is a nested land point, and the surrounding coarse values are all land points,
                  !  then this is a simple 4-pt interpolation.

                  ELSE IF ( ( NINT(nlu(ni  ,nj  )) .NE. iswater ) .AND. &
                            ( NINT(clu(ci  ,cj  )) .NE. iswater ) .AND. &
                            ( NINT(clu(ci+1,cj  )) .NE. iswater ) .AND. &
                            ( NINT(clu(ci  ,cj+1)) .NE. iswater ) .AND. &
                            ( NINT(clu(ci+1,cj+1)) .NE. iswater ) ) THEN
                     nfld(ni,nk,nj) = ( 1. - dx ) * ( ( 1. - dy ) * cfld(ci  ,ck,cj  )   + &
                                                             dy   * cfld(ci  ,ck,cj+1) ) + &
                                             dx   * ( ( 1. - dy ) * cfld(ci+1,ck,cj  )   + &
                                                             dy   * cfld(ci+1,ck,cj+1) )

                  !  If this is a nested land point and there are NO coarse land values surrounding,
                  !  we temporarily punt.

                  ELSE IF ( ( NINT(nlu(ni  ,nj  )) .NE. iswater ) .AND. &
                            ( NINT(clu(ci  ,cj  )) .EQ. iswater ) .AND. &
                            ( NINT(clu(ci+1,cj  )) .EQ. iswater ) .AND. &
                            ( NINT(clu(ci  ,cj+1)) .EQ. iswater ) .AND. &
                            ( NINT(clu(ci+1,cj+1)) .EQ. iswater ) ) THEN
                     nfld(ni,nk,nj) = -1

                  !  If there are some water points and some land points, take an average. 
                  
                  ELSE IF ( NINT(nlu(ni  ,nj  )) .NE. iswater ) THEN
                     icount = 0
                     sum = 0
                     IF ( NINT(clu(ci  ,cj  )) .NE. iswater ) THEN
                        icount = icount + 1
                        sum = sum + cfld(ci  ,ck,cj  )
                     END IF
                     IF ( NINT(clu(ci+1,cj  )) .NE. iswater ) THEN
                        icount = icount + 1
                        sum = sum + cfld(ci+1,ck,cj  )
                     END IF
                     IF ( NINT(clu(ci  ,cj+1)) .NE. iswater ) THEN
                        icount = icount + 1
                        sum = sum + cfld(ci  ,ck,cj+1)
                     END IF
                     IF ( NINT(clu(ci+1,cj+1)) .NE. iswater ) THEN
                        icount = icount + 1
                        sum = sum + cfld(ci+1,ck,cj+1)
                     END IF
                     nfld(ni,nk,nj) = sum / REAL ( icount ) 
                  END IF
               END DO
            END DO
         END DO


         !  Get an average of the whole domain for problem locations.

         sum_n     = 0
         icount_n  = 0
         DO nj = njts, njte
            DO nk = nkts, nkte
               DO ni = nits, nite
                  IF ( nfld(ni,nk,nj) .NE. -1 ) THEN
                     IF ( NINT(nlu(ni,nj)) .NE. iswater ) THEN
                       icount_n(nk)  = icount_n(nk) + 1
                       sum_n(nk) = sum_n(nk) + nfld(ni,nk,nj)
                     END IF
                  END IF
               END DO
            END DO
         END DO

         CALL wrf_dm_sum_reals(      sum_n(nkts:nkte),  dummy(nkts:nkte))
         sum_n    = dummy
         CALL wrf_dm_sum_integers(icount_n(nkts:nkte), idummy(nkts:nkte))
         icount_n = idummy
         DO nk = nkts, nkte
            IF ( icount_n(nk) .GT. 0 )  &
              avg_n(nk)  = sum_n(nk) / icount_n(nk)
         END DO
       ENDIF

       IF ( enable ) THEN
         IF ( ANY(nfld .EQ. -1) ) THEN

         !  OK, if there were any of those island situations, we try to search a bit broader
         !  of an area in the coarse grid.

           DO nj = njts, njte
              DO nk = nkts, nkte
                 DO ni = nits, nite
                    IF ( imask(ni, nj) .NE. 1 ) cycle
                    IF ( nfld(ni,nk,nj) .EQ. -1 ) THEN
                       IF ( MOD ( nrj , 2 ) .EQ. 0 ) THEN
                          cj = ( nj + (nrj/2)-1 ) / nrj + jpos -1 ! first coarse position equal to or below nest point
                       ELSE
                          cj = ( nj + (nrj-1)/2 ) / nrj + jpos -1 ! first coarse position equal to or below nest point
                       END IF
                       IF ( MOD ( nri , 2 ) .EQ. 0 ) THEN
                          ci = ( ni + (nri/2)-1 ) / nri + ipos -1 ! first coarse position equal to or to the left of nest point
                       ELSE
                          ci = ( ni + (nri-1)/2 ) / nri + ipos -1 ! first coarse position equal to or to the left of nest point
                       END IF
                       ist = MAX (ci-max_search,cits)
                       ien = MIN (ci+max_search,cite,cide-1)
                       jst = MAX (cj-max_search,cjts)
                       jen = MIN (cj+max_search,cjte,cjde-1)
                       icount = 0 
                       sum = 0
                       DO jj = jst,jen
                          DO ii = ist,ien
                             IF ( NINT(clu(ii,jj)) .NE. iswater ) THEN
                                icount = icount + 1
                                sum = sum + cfld(ii,nk,jj)
                             END IF
                          END DO
                       END DO
                       IF ( icount .GT. 0 ) THEN
                          nfld(ni,nk,nj) = sum / REAL ( icount ) 
                       ELSE
                          Write(message,fmt='(a,i4,a,i4,a,f10.4)') &
                            'horizontal interp error - island (', ni, ',', nj, '), using average ', avg_n(nk)
                          CALL wrf_message ( message )
                          nfld(ni,nk,nj) = avg_n(nk)
                       END IF        
                    END IF
                 END DO
              END DO
           END DO
         ENDIF
       ENDIF
      ELSE
         CALL wrf_error_fatal ( "only unstaggered fields right now" )
      END IF

   END SUBROUTINE interp_mask_land_field


   SUBROUTINE interp_mask_water_field ( enable,                  &  ! says whether to allow interpolation or just the bcasts,7
                                        cfld,                    &  ! CD field
                           cids, cide, ckds, ckde, cjds, cjde,   &
                           cims, cime, ckms, ckme, cjms, cjme,   &
                           cits, cite, ckts, ckte, cjts, cjte,   &
                           nfld,                                 &  ! ND field
                           nids, nide, nkds, nkde, njds, njde,   &
                           nims, nime, nkms, nkme, njms, njme,   &
                           nits, nite, nkts, nkte, njts, njte,   &
                           shw,                                  &  ! stencil half width
                           imask,                                &  ! interpolation mask
                           xstag, ystag,                         &  ! staggering of field
                           ipos, jpos,                           &  ! Position of lower left of nest in CD
                           nri, nrj,                             &  ! nest ratios
                           clu, nlu, cflag, nflag                )

      USE module_configure
      USE module_wrf_error
      USE module_dm, only : wrf_dm_sum_reals, wrf_dm_sum_integers

      IMPLICIT NONE
   
   
      LOGICAL, INTENT(IN) :: enable
      INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
                             cims, cime, ckms, ckme, cjms, cjme,   &
                             cits, cite, ckts, ckte, cjts, cjte,   &
                             nids, nide, nkds, nkde, njds, njde,   &
                             nims, nime, nkms, nkme, njms, njme,   &
                             nits, nite, nkts, nkte, njts, njte,   &
                             shw,                                  &
                             ipos, jpos,                           &
                             nri, nrj, cflag, nflag
      LOGICAL, INTENT(IN) :: xstag, ystag
   
      REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ) :: cfld
      REAL, DIMENSION ( nims:nime, nkms:nkme, njms:njme ) :: nfld
     INTEGER, DIMENSION ( nims:nime, njms:njme ) :: imask
   
      REAL, DIMENSION ( cims:cime, cjms:cjme ) :: clu
      REAL, DIMENSION ( nims:nime, njms:njme ) :: nlu
   
      ! Local
   
      INTEGER ci, cj, ck, ni, nj, nk, ip, jp
      INTEGER :: icount , ii , jj , ist , ien , jst , jen, ierr
      REAL :: avg , sum , dx , dy
      INTEGER , PARAMETER :: max_search = 5
      INTEGER :: icount_n(nkts:nkte), idummy(nkts:nkte)
      REAL :: avg_n(nkts:nkte), sum_n(nkts:nkte), dummy(nkts:nkte)
      CHARACTER(LEN=255) :: message

      !  Right now, only mass point locations permitted.
   
      IF ( ( .NOT. xstag) .AND. ( .NOT. ystag ) ) THEN

       IF ( enable ) THEN
         !  Loop over each i,k,j in the nested domain.

         DO nj = njts, njte
            IF ( MOD ( nrj , 2 ) .EQ. 0 ) THEN
               cj = ( nj + (nrj/2)-1 ) / nrj + jpos -1 ! first coarse position equal to or below nest point
            ELSE
               cj = ( nj + (nrj-1)/2 ) / nrj + jpos -1 ! first coarse position equal to or below nest point
            END IF
            DO nk = nkts, nkte
               ck = nk
               DO ni = nits, nite
!dave             IF ( imask(ni, nj) .NE. 1 ) cycle
                  IF ( MOD ( nri , 2 ) .EQ. 0 ) THEN
                     ci = ( ni + (nri/2)-1 ) / nri + ipos -1 ! first coarse position equal to or to the left of nest point
                  ELSE
                     ci = ( ni + (nri-1)/2 ) / nri + ipos -1 ! first coarse position equal to or to the left of nest point
                  END IF
   



                  !
                  !                    (ci,cj+1)     (ci+1,cj+1)
                  !               -        -------------
                  !         1-dy  |        |           |
                  !               |        |           |
                  !               -        |  *        |
                  !          dy   |        | (ni,nj)   |
                  !               |        |           |
                  !               -        -------------
                  !                    (ci,cj)       (ci+1,cj)  
                  !
                  !                        |--|--------|
                  !                         dx  1-dx         


                  !  At ni=2, we are on the coarse grid point, so dx = 0

                  IF ( MOD ( nri , 2 ) .EQ. 0 ) THEN
                     dx = ( REAL ( MOD ( ni+(nri-1)/2 , nri ) ) + 0.5 ) / REAL ( nri ) 
                  ELSE 
                     dx =   REAL ( MOD ( ni+(nri-1)/2 , nri ) )         / REAL ( nri ) 
                  END IF
                  IF ( MOD ( nrj , 2 ) .EQ. 0 ) THEN
                     dy = ( REAL ( MOD ( nj+(nrj-1)/2 , nrj ) ) + 0.5 ) / REAL ( nrj ) 
                  ELSE 
                     dy =   REAL ( MOD ( nj+(nrj-1)/2 , nrj ) )         / REAL ( nrj ) 
                  END IF
   
                  !  This is a "water only" field.  If this is a land point, no operations required.

                  IF      ( ( NINT(nlu(ni  ,nj  )) .NE. nflag ) ) THEN
                     nfld(ni,nk,nj) = cfld(ci  ,ck,cj  )

                  !  If this is a nested water point, and the surrounding coarse values are all water points,
                  !  then this is a simple 4-pt interpolation.

                  ELSE IF ( ( NINT(nlu(ni  ,nj  )) .EQ. nflag ) .AND. &
                            ( NINT(clu(ci  ,cj  )) .EQ. nflag ) .AND. &
                            ( NINT(clu(ci+1,cj  )) .EQ. nflag ) .AND. &
                            ( NINT(clu(ci  ,cj+1)) .EQ. nflag ) .AND. &
                            ( NINT(clu(ci+1,cj+1)) .EQ. nflag ) ) THEN
                     nfld(ni,nk,nj) = ( 1. - dx ) * ( ( 1. - dy ) * cfld(ci  ,ck,cj  )   + &
                                                             dy   * cfld(ci  ,ck,cj+1) ) + &
                                             dx   * ( ( 1. - dy ) * cfld(ci+1,ck,cj  )   + &
                                                             dy   * cfld(ci+1,ck,cj+1) )

                  !  If this is a nested water point and there are NO coarse water values surrounding,
                  !  we temporarily punt.

                  ELSE IF ( ( NINT(nlu(ni  ,nj  )) .EQ. nflag ) .AND. &
                            ( NINT(clu(ci  ,cj  )) .NE. nflag ) .AND. &
                            ( NINT(clu(ci+1,cj  )) .NE. nflag ) .AND. &
                            ( NINT(clu(ci  ,cj+1)) .NE. nflag ) .AND. &
                            ( NINT(clu(ci+1,cj+1)) .NE. nflag ) ) THEN
                     nfld(ni,nk,nj) = -4

                  !  If there are some land points and some water points, take an average. 
                  
                  ELSE IF ( NINT(nlu(ni  ,nj  )) .EQ. nflag ) THEN
                     icount = 0
                     sum = 0
                     IF ( NINT(clu(ci  ,cj  )) .EQ. nflag ) THEN
                        icount = icount + 1
                        sum = sum + cfld(ci  ,ck,cj  )
                     END IF
                     IF ( NINT(clu(ci+1,cj  )) .EQ. nflag ) THEN
                        icount = icount + 1
                        sum = sum + cfld(ci+1,ck,cj  )
                     END IF
                     IF ( NINT(clu(ci  ,cj+1)) .EQ. nflag ) THEN
                        icount = icount + 1
                        sum = sum + cfld(ci  ,ck,cj+1)
                     END IF
                     IF ( NINT(clu(ci+1,cj+1)) .EQ. nflag ) THEN
                        icount = icount + 1
                        sum = sum + cfld(ci+1,ck,cj+1)
                     END IF
                     nfld(ni,nk,nj) = sum / REAL ( icount ) 
                  END IF
               END DO
            END DO
         END DO

         !  Get an average of the whole domain for problem locations.

         sum_n     = 0
         icount_n  = 0
         DO nj = njts, njte
            DO nk = nkts, nkte
               DO ni = nits, nite
                  IF ( nfld(ni,nk,nj) .NE. -1 ) THEN
                     IF ( NINT(nlu(ni,nj)) .EQ. nflag ) THEN
                       icount_n(nk)  = icount_n(nk) + 1
                       sum_n(nk) = sum_n(nk) + nfld(ni,nk,nj)
                     END IF
                  END IF
               END DO
            END DO
         END DO

         CALL wrf_dm_sum_reals(      sum_n(nkts:nkte),  dummy(nkts:nkte))
         sum_n    = dummy
         CALL wrf_dm_sum_integers(icount_n(nkts:nkte), idummy(nkts:nkte))
         icount_n = idummy
         DO nk = nkts, nkte
            IF ( icount_n(nk) .GT. 0 )  &
              avg_n(nk)  = sum_n(nk) / icount_n(nk)
         END DO
       ENDIF

       IF ( enable ) THEN
         IF ( ANY(nfld .EQ. -4) ) THEN

           !  OK, if there were any of those lake situations, we try to search a bit broader
           !  of an area in the coarse grid.

           DO nj = njts, njte
              DO nk = nkts, nkte
                 DO ni = nits, nite
!dave               IF ( imask(ni, nj) .NE. 1 ) cycle
                    IF ( nfld(ni,nk,nj) .EQ. -4 ) THEN
                       IF ( MOD ( nrj , 2 ) .EQ. 0 ) THEN
                          cj = ( nj + (nrj/2)-1 ) / nrj + jpos -1 ! first coarse position equal to or below nest point
                       ELSE
                          cj = ( nj + (nrj-1)/2 ) / nrj + jpos -1 ! first coarse position equal to or below nest point
                       END IF
                       IF ( MOD ( nri , 2 ) .EQ. 0 ) THEN
                          ci = ( ni + (nri/2)-1 ) / nri + ipos -1 ! first coarse position equal to or to the left of nest point
                       ELSE
                          ci = ( ni + (nri-1)/2 ) / nri + ipos -1 ! first coarse position equal to or to the left of nest point
                       END IF
                       ist = MAX (ci-max_search,cits)
                       ien = MIN (ci+max_search,cite,cide-1)
                       jst = MAX (cj-max_search,cjts)
                       jen = MIN (cj+max_search,cjte,cjde-1)
                       icount = 0 
                       sum = 0
                       DO jj = jst,jen
                          DO ii = ist,ien
                             IF ( NINT(clu(ii,jj)) .EQ. nflag ) THEN
                                icount = icount + 1
                                sum = sum + cfld(ii,nk,jj)
                             END IF
                          END DO
                       END DO
                       IF ( icount .GT. 0 ) THEN
                          nfld(ni,nk,nj) = sum / REAL ( icount ) 
                       ELSE
                         Write(message,fmt='(a,i4,a,i4,a,f10.4)') &
                            'horizontal interp error - lake (', ni, ',', nj, '), using average ', avg_n(nk)
                         CALL wrf_message ( message )                         
                          nfld(ni,nk,nj) = avg_n(nk)
                       END IF        
                    END IF
                 END DO
              END DO
           END DO
         ENDIF
       ENDIF
      ELSE
         CALL wrf_error_fatal ( "only unstaggered fields right now" )
      END IF

   END SUBROUTINE interp_mask_water_field

! Begin second block of ARW-only routines
#if ! defined(NMM_CORE) || NMM_CORE!=1

   SUBROUTINE p2c_mask (   cfld,                                 &  ! CD field,3
                           cids, cide, ckds, ckde, cjds, cjde,   &
                           cims, cime, ckms, ckme, cjms, cjme,   &
                           cits, cite, ckts, ckte, cjts, cjte,   &
                           nfld,                                 &  ! ND field
                           nids, nide, nkds, nkde, njds, njde,   &
                           nims, nime, nkms, nkme, njms, njme,   &
                           nits, nite, nkts, nkte, njts, njte,   &
                           shw,                                  &  ! stencil half width
                           imask,                                &  ! interpolation mask
                           xstag, ystag,                         &  ! staggering of field
                           ipos, jpos,                           &  ! Position of lower left of nest in CD
                           nri, nrj,                             &  ! nest ratios
                           clu, nlu,                             &  ! land use categories
                           ctslb,ntslb,                          &  ! soil temps
                           cnum_soil_layers,nnum_soil_layers,    &  ! number of soil layers for tslb
                           ciswater, niswater                    )  ! iswater category

      USE module_configure
      USE module_wrf_error

      IMPLICIT NONE
   
      INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
                             cims, cime, ckms, ckme, cjms, cjme,   &
                             cits, cite, ckts, ckte, cjts, cjte,   &
                             nids, nide, nkds, nkde, njds, njde,   &
                             nims, nime, nkms, nkme, njms, njme,   &
                             nits, nite, nkts, nkte, njts, njte,   &
                             shw,                                  &
                             ipos, jpos,                           &
                             nri, nrj,                             &
                             cnum_soil_layers, nnum_soil_layers,   &
                             ciswater, niswater 

      LOGICAL, INTENT(IN) :: xstag, ystag
   
      REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ) :: cfld
      REAL, DIMENSION ( nims:nime, nkms:nkme, njms:njme ) :: nfld
      INTEGER, DIMENSION ( nims:nime, njms:njme ) :: imask
   
      REAL, DIMENSION ( cims:cime, cjms:cjme ) :: clu
      REAL, DIMENSION ( nims:nime, njms:njme ) :: nlu

      REAL, DIMENSION ( cims:cime, 1:cnum_soil_layers, cjms:cjme ) :: ctslb
      REAL, DIMENSION ( nims:nime, 1:nnum_soil_layers, njms:njme ) :: ntslb

      ! Local
   
      INTEGER ci, cj, ck, ni, nj, nk
      INTEGER :: icount 
      REAL :: sum , dx , dy

      !  Right now, only mass point locations permitted.
   
      IF ( ( .NOT. xstag) .AND. ( .NOT. ystag ) ) THEN

         !  Loop over each i,k,j in the nested domain.

         DO nj = njts, MIN(njde-1,njte)
            IF ( MOD ( nrj , 2 ) .EQ. 0 ) THEN
               cj = ( nj + (nrj/2)-1 ) / nrj + jpos -1 ! first coarse position equal to or below nest point
            ELSE
               cj = ( nj + (nrj-1)/2 ) / nrj + jpos -1 ! first coarse position equal to or below nest point
            END IF
            DO nk = nkts, nkte
               ck = nk
               DO ni = nits, MIN(nide-1,nite)
                  IF ( MOD ( nri , 2 ) .EQ. 0 ) THEN
                     ci = ( ni + (nri/2)-1 ) / nri + ipos -1 ! first coarse position equal to or to the left of nest point
                  ELSE
                     ci = ( ni + (nri-1)/2 ) / nri + ipos -1 ! first coarse position equal to or to the left of nest point
                  END IF

                  !
                  !                    (ci,cj+1)     (ci+1,cj+1)
                  !               -        -------------
                  !         1-dy  |        |           |
                  !               |        |           |
                  !               -        |  *        |
                  !          dy   |        | (ni,nj)   |
                  !               |        |           |
                  !               -        -------------
                  !                    (ci,cj)       (ci+1,cj)  
                  !
                  !                        |--|--------|
                  !                         dx  1-dx         


                  !  At ni=2, we are on the coarse grid point, so dx = 0

                  IF ( MOD ( nri , 2 ) .EQ. 0 ) THEN
                     dx = ( REAL ( MOD ( ni+(nri-1)/2 , nri ) ) + 0.5 ) / REAL ( nri ) 
                  ELSE 
                     dx =   REAL ( MOD ( ni+(nri-1)/2 , nri ) )         / REAL ( nri ) 
                  END IF
                  IF ( MOD ( nrj , 2 ) .EQ. 0 ) THEN
                     dy = ( REAL ( MOD ( nj+(nrj-1)/2 , nrj ) ) + 0.5 ) / REAL ( nrj ) 
                  ELSE 
                     dy =   REAL ( MOD ( nj+(nrj-1)/2 , nrj ) )         / REAL ( nrj ) 
                  END IF
   
                  !  This is a "water only" field.  If this is a land point, no operations required.

                  IF      ( ( NINT(nlu(ni  ,nj  )) .NE. niswater ) ) THEN
                     nfld(ni,nk,nj) = 273.18

                  !  If this is a nested water point, and the surrounding coarse values are all water points,
                  !  then this is a simple 4-pt interpolation.

                  ELSE IF ( ( NINT(nlu(ni  ,nj  )) .EQ. niswater ) .AND. &
                            ( NINT(clu(ci  ,cj  )) .EQ. niswater ) .AND. &
                            ( NINT(clu(ci+1,cj  )) .EQ. niswater ) .AND. &
                            ( NINT(clu(ci  ,cj+1)) .EQ. niswater ) .AND. &
                            ( NINT(clu(ci+1,cj+1)) .EQ. niswater ) ) THEN
                     nfld(ni,nk,nj) = ( 1. - dx ) * ( ( 1. - dy ) * cfld(ci  ,ck,cj  )   + &
                                                             dy   * cfld(ci  ,ck,cj+1) ) + &
                                             dx   * ( ( 1. - dy ) * cfld(ci+1,ck,cj  )   + &
                                                             dy   * cfld(ci+1,ck,cj+1) )

                  !  If this is a nested water point and there are NO coarse water values surrounding,
                  !  we manufacture something from the deepest CG soil temp.

                  ELSE IF ( ( NINT(nlu(ni  ,nj  )) .EQ. niswater ) .AND. &
                            ( NINT(clu(ci  ,cj  )) .NE. niswater ) .AND. &
                            ( NINT(clu(ci+1,cj  )) .NE. niswater ) .AND. &
                            ( NINT(clu(ci  ,cj+1)) .NE. niswater ) .AND. &
                            ( NINT(clu(ci+1,cj+1)) .NE. niswater ) ) THEN
                     nfld(ni,nk,nj) = ( 1. - dx ) * ( ( 1. - dy ) * ctslb(ci  ,cnum_soil_layers,cj  )   + &
                                                             dy   * ctslb(ci  ,cnum_soil_layers,cj+1) ) + &
                                             dx   * ( ( 1. - dy ) * ctslb(ci+1,cnum_soil_layers,cj  )   + &
                                                             dy   * ctslb(ci+1,cnum_soil_layers,cj+1) )

                  !  If there are some land points and some water points, take an average of the water points.
                  
                  ELSE IF ( NINT(nlu(ni  ,nj  )) .EQ. niswater ) THEN
                     icount = 0
                     sum = 0
                     IF ( NINT(clu(ci  ,cj  )) .EQ. niswater ) THEN
                        icount = icount + 1
                        sum = sum + cfld(ci  ,ck,cj  )
                     END IF
                     IF ( NINT(clu(ci+1,cj  )) .EQ. niswater ) THEN
                        icount = icount + 1
                        sum = sum + cfld(ci+1,ck,cj  )
                     END IF
                     IF ( NINT(clu(ci  ,cj+1)) .EQ. niswater ) THEN
                        icount = icount + 1
                        sum = sum + cfld(ci  ,ck,cj+1)
                     END IF
                     IF ( NINT(clu(ci+1,cj+1)) .EQ. niswater ) THEN
                        icount = icount + 1
                        sum = sum + cfld(ci+1,ck,cj+1)
                     END IF
                     nfld(ni,nk,nj) = sum / REAL ( icount ) 
                  END IF
               END DO
            END DO
         END DO

      ELSE
         CALL wrf_error_fatal ( "only unstaggered fields right now" )
      END IF

   END SUBROUTINE p2c_mask


   SUBROUTINE none
   END SUBROUTINE none


   SUBROUTINE smoother ( cfld , &,3
                      cids, cide, ckds, ckde, cjds, cjde,   &
                      cims, cime, ckms, ckme, cjms, cjme,   &
                      cits, cite, ckts, ckte, cjts, cjte,   &
                      nids, nide, nkds, nkde, njds, njde,   &
                      nims, nime, nkms, nkme, njms, njme,   &
                      nits, nite, nkts, nkte, njts, njte,   &
                      xstag, ystag,                         &  ! staggering of field
                      ipos, jpos,                           &  ! Position of lower left of nest in
                      nri, nrj                              &
                      )
 
      USE module_configure
      IMPLICIT NONE
   
      INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
                             cims, cime, ckms, ckme, cjms, cjme,   &
                             cits, cite, ckts, ckte, cjts, cjte,   &
                             nids, nide, nkds, nkde, njds, njde,   &
                             nims, nime, nkms, nkme, njms, njme,   &
                             nits, nite, nkts, nkte, njts, njte,   &
                             nri, nrj,                             &  
                             ipos, jpos
      LOGICAL, INTENT(IN) :: xstag, ystag
      INTEGER             :: smooth_option, feedback , spec_zone
   
      REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ) :: cfld

      !  If there is no feedback, there can be no smoothing.

      CALL nl_get_feedback       ( 1, feedback  )
      IF ( feedback == 0 ) RETURN
      CALL nl_get_spec_zone ( 1, spec_zone )

      !  These are the 2d smoothers used on the fedback data.  These filters
      !  are run on the coarse grid data (after the nested info has been
      !  fedback).  Only the area of the nest in the coarse grid is filtered.

      CALL nl_get_smooth_option  ( 1, smooth_option  )

      IF      ( smooth_option == 0 ) THEN
! no op
      ELSE IF ( smooth_option == 1 ) THEN
         CALL sm121 ( cfld , &
                      cids, cide, ckds, ckde, cjds, cjde,   &
                      cims, cime, ckms, ckme, cjms, cjme,   &
                      cits, cite, ckts, ckte, cjts, cjte,   &
                      xstag, ystag,                         &  ! staggering of field
                      nids, nide, nkds, nkde, njds, njde,   &
                      nims, nime, nkms, nkme, njms, njme,   &
                      nits, nite, nkts, nkte, njts, njte,   &
                      nri, nrj,                             &  
                      ipos, jpos                            &  ! Position of lower left of nest in 
                      )
      ELSE IF ( smooth_option == 2 ) THEN
         CALL smdsm ( cfld , &
                      cids, cide, ckds, ckde, cjds, cjde,   &
                      cims, cime, ckms, ckme, cjms, cjme,   &
                      cits, cite, ckts, ckte, cjts, cjte,   &
                      xstag, ystag,                         &  ! staggering of field
                      nids, nide, nkds, nkde, njds, njde,   &
                      nims, nime, nkms, nkme, njms, njme,   &
                      nits, nite, nkts, nkte, njts, njte,   &
                      nri, nrj,                             &  
                      ipos, jpos                            &  ! Position of lower left of nest in 
                      )
      END IF

   END SUBROUTINE smoother 


   SUBROUTINE sm121 ( cfld , & 1,1
                      cids, cide, ckds, ckde, cjds, cjde,   &
                      cims, cime, ckms, ckme, cjms, cjme,   &
                      cits, cite, ckts, ckte, cjts, cjte,   &
                      xstag, ystag,                         &  ! staggering of field
                      nids, nide, nkds, nkde, njds, njde,   &
                      nims, nime, nkms, nkme, njms, njme,   &
                      nits, nite, nkts, nkte, njts, njte,   &
                      nri, nrj,                             &  
                      ipos, jpos                            &  ! Position of lower left of nest in 
                      )
   
      USE module_configure
      IMPLICIT NONE
   
      INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
                             cims, cime, ckms, ckme, cjms, cjme,   &
                             cits, cite, ckts, ckte, cjts, cjte,   &
                             nids, nide, nkds, nkde, njds, njde,   &
                             nims, nime, nkms, nkme, njms, njme,   &
                             nits, nite, nkts, nkte, njts, njte,   &
                             nri, nrj,                             &  
                             ipos, jpos
      LOGICAL, INTENT(IN) :: xstag, ystag
   
      REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ) :: cfld
      REAL, DIMENSION ( cims:cime,            cjms:cjme ) :: cfldnew
   
      INTEGER                        :: i , j , k , loop
      INTEGER :: istag,jstag

      INTEGER, PARAMETER  :: smooth_passes = 1 ! More passes requires a larger stencil (currently 48 pt)

      istag = 1 ; jstag = 1
      IF ( xstag ) istag = 0
      IF ( ystag ) jstag = 0
   
      !  Simple 1-2-1 smoother.
   
      smoothing_passes : DO loop = 1 , smooth_passes
   
         DO k = ckts , ckte
   
            !  Initialize dummy cfldnew

            DO i = MAX(ipos,cits-3) , MIN(ipos+(nide-nids)/nri,cite+3)
               DO j = MAX(jpos,cjts-3) , MIN(jpos+(njde-njds)/nrj,cjte+3)
                  cfldnew(i,j) = cfld(i,k,j) 
               END DO
            END DO

            !  1-2-1 smoothing in the j direction first, 
   
            DO i = MAX(ipos+2,cits-2) , MIN(ipos+(nide-nids)/nri-2-istag,cite+2)
            DO j = MAX(jpos+2,cjts-2) , MIN(jpos+(njde-njds)/nrj-2-jstag,cjte+2)
                  cfldnew(i,j) = 0.25 * ( cfld(i,k,j+1) + 2.*cfld(i,k,j) + cfld(i,k,j-1) )
               END DO
            END DO

            !  then 1-2-1 smoothing in the i direction last
       
            DO j = MAX(jpos+2,cjts-2) , MIN(jpos+(njde-njds)/nrj-2-jstag,cjte+2)
            DO i = MAX(ipos+2,cits-2) , MIN(ipos+(nide-nids)/nri-2-istag,cite+2)
                  cfld(i,k,j) =  0.25 * ( cfldnew(i+1,j) + 2.*cfldnew(i,j) + cfldnew(i-1,j) )
               END DO
            END DO
       
         END DO
    
      END DO smoothing_passes
   
   END SUBROUTINE sm121


   SUBROUTINE smdsm ( cfld , & 1,1
                      cids, cide, ckds, ckde, cjds, cjde,   &
                      cims, cime, ckms, ckme, cjms, cjme,   &
                      cits, cite, ckts, ckte, cjts, cjte,   &
                      xstag, ystag,                         &  ! staggering of field
                      nids, nide, nkds, nkde, njds, njde,   &
                      nims, nime, nkms, nkme, njms, njme,   &
                      nits, nite, nkts, nkte, njts, njte,   &
                      nri, nrj,                             &  
                      ipos, jpos                            &  ! Position of lower left of nest in 
                      )
   
      USE module_configure
      IMPLICIT NONE
   
      INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
                             cims, cime, ckms, ckme, cjms, cjme,   &
                             cits, cite, ckts, ckte, cjts, cjte,   &
                             nids, nide, nkds, nkde, njds, njde,   &
                             nims, nime, nkms, nkme, njms, njme,   &
                             nits, nite, nkts, nkte, njts, njte,   &
                             nri, nrj,                             &  
                             ipos, jpos
      LOGICAL, INTENT(IN) :: xstag, ystag
   
      REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ) :: cfld
      REAL, DIMENSION ( cims:cime,            cjms:cjme ) :: cfldnew
   
      REAL , DIMENSION ( 2 )         :: xnu
      INTEGER                        :: i , j , k , loop , n 
      INTEGER :: istag,jstag

      INTEGER, PARAMETER  :: smooth_passes = 1 ! More passes requires a larger stencil (currently 48 pt)

      xnu  =  (/ 0.50 , -0.52 /)
    
      istag = 1 ; jstag = 1
      IF ( xstag ) istag = 0
      IF ( ystag ) jstag = 0
   
      !  The odd number passes of this are the "smoother", the even
      !  number passes are the "de-smoother" (note the different signs on xnu).
   
      smoothing_passes : DO loop = 1 , smooth_passes * 2
   
         n  =  2 - MOD ( loop , 2 )
    
         DO k = ckts , ckte
   
            DO i = MAX(ipos+2,cits-2) , MIN(ipos+(nide-nids)/nri-2-istag,cite+2)
               DO j = MAX(jpos+2,cjts-2) , MIN(jpos+(njde-njds)/nrj-2-jstag,cjte+2)
                  cfldnew(i,j) = cfld(i,k,j) + xnu(n) * ((cfld(i,k,j+1) + cfld(i,k,j-1)) * 0.5-cfld(i,k,j))
               END DO
            END DO
       
            DO i = MAX(ipos+2,cits-2) , MIN(ipos+(nide-nids)/nri-2-istag,cite+2)
               DO j = MAX(jpos+2,cjts-2) , MIN(jpos+(njde-njds)/nrj-2-jstag,cjte+2)
                  cfld(i,k,j) = cfldnew(i,j)
               END DO
            END DO
       
            DO j = MAX(jpos+2,cjts-2) , MIN(jpos+(njde-njds)/nrj-2-jstag,cjte+2)
               DO i = MAX(ipos+2,cits-2) , MIN(ipos+(nide-nids)/nri-2-istag,cite+2)
                  cfldnew(i,j) = cfld(i,k,j) + xnu(n) * ((cfld(i+1,k,j) + cfld(i-1,k,j)) * 0.5-cfld(i,k,j))
               END DO
            END DO
       
            DO j = MAX(jpos+2,cjts-2) , MIN(jpos+(njde-njds)/nrj-2-jstag,cjte+2)
               DO i = MAX(ipos+2,cits-2) , MIN(ipos+(nide-nids)/nri-2-istag,cite+2)
                  cfld(i,k,j) = cfldnew(i,j)
               END DO
            END DO
   
         END DO
    
      END DO smoothing_passes
   
   END SUBROUTINE smdsm

!==================================
! this is used to modify a field over the nest so we can see where the nest is


   SUBROUTINE mark_domain (  cfld,                                 &  ! CD field,2
                           cids, cide, ckds, ckde, cjds, cjde,   &
                           cims, cime, ckms, ckme, cjms, cjme,   &
                           cits, cite, ckts, ckte, cjts, cjte,   &
                           nfld,                                 &  ! ND field
                           nids, nide, nkds, nkde, njds, njde,   &
                           nims, nime, nkms, nkme, njms, njme,   &
                           nits, nite, nkts, nkte, njts, njte,   &
                           shw,                                  &  ! stencil half width for interp
                           imask,                                &  ! interpolation mask
                           xstag, ystag,                         &  ! staggering of field
                           ipos, jpos,                           &  ! Position of lower left of nest in CD
                           nri, nrj                             )   ! nest ratios
     USE module_configure
     USE module_wrf_error
     IMPLICIT NONE


     INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
                            cims, cime, ckms, ckme, cjms, cjme,   &
                            cits, cite, ckts, ckte, cjts, cjte,   &
                            nids, nide, nkds, nkde, njds, njde,   &
                            nims, nime, nkms, nkme, njms, njme,   &
                            nits, nite, nkts, nkte, njts, njte,   &
                            shw,                                  &
                            ipos, jpos,                           &
                            nri, nrj
     LOGICAL, INTENT(IN) :: xstag, ystag

     REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ), INTENT(OUT) :: cfld
     REAL, DIMENSION ( nims:nime, nkms:nkme, njms:njme ), INTENT(IN) :: nfld
     INTEGER, DIMENSION ( nims:nime, njms:njme ), INTENT(IN) :: imask

     ! Local

     INTEGER ci, cj, ck, ni, nj, nk, ip, jp, ioff, joff, ioffa, joffa
     INTEGER :: icmin,icmax,jcmin,jcmax
     INTEGER :: istag,jstag, ipoints,jpoints,ijpoints

     istag = 1 ; jstag = 1
     IF ( xstag ) istag = 0
     IF ( ystag ) jstag = 0

     DO cj = MAX(jpos+1,cjts),MIN(jpos+(njde-njds)/nrj-jstag-1,cjte)
        nj = (cj-jpos)*nrj + jstag + 1
        DO ck = ckts, ckte
           nk = ck
           DO ci = MAX(ipos+1,cits),MIN(ipos+(nide-nids)/nri-istag-1,cite)
              ni = (ci-ipos)*nri + istag + 1
              cfld( ci, ck, cj ) =  9021000.  !magic number: Beverly Hills * 100.
           ENDDO
        ENDDO
     ENDDO

   END SUBROUTINE mark_domain
#endif 
! end of second block of WRF-ARW-specific interpolation schemes

#if ( NMM_CORE == 1 )
!=======================================================================================
!  Old circa 2007 interpolation schemes that are still in use
!  This is gopal's doing
!=======================================================================================

  SUBROUTINE force_sst_nmm    (cfld,                                 &  ! CD field,2
                               cids, cide, ckds, ckde, cjds, cjde,   &
                               cims, cime, ckms, ckme, cjms, cjme,   &
                               cits, cite, ckts, ckte, cjts, cjte,   &
                               nfld,                                 &  ! ND field
                               nids, nide, nkds, nkde, njds, njde,   &
                               nims, nime, nkms, nkme, njms, njme,   &
                               nits, nite, nkts, nkte, njts, njte,   &
                               shw,                                  &  ! stencil half width for interp
                               imask,                                &  ! interpolation mask
                               xstag, ystag,                         &  ! staggering of field
                               ipos, jpos,                           &  ! Position of lower left of nest in CD
                               nri, nrj,                             &  ! nest ratios                         
                               CII, IIH, CJJ, JJH, CBWGT1, HBWGT1,   &  ! south-western grid locs and weights 
                               CBWGT2, HBWGT2, CBWGT3, HBWGT3,       &  ! note that "C"ourse grid ones are
                               CBWGT4, HBWGT4, CCSST, CSST           )  ! just dummys
     USE module_timing
     IMPLICIT NONE

     INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
                            cims, cime, ckms, ckme, cjms, cjme,   &
                            cits, cite, ckts, ckte, cjts, cjte,   &
                            nids, nide, nkds, nkde, njds, njde,   &
                            nims, nime, nkms, nkme, njms, njme,   &
                            nits, nite, nkts, nkte, njts, njte,   &
                            shw,                                  &
                            ipos, jpos,                           &
                            nri, nrj
     LOGICAL, INTENT(IN) :: xstag, ystag

     REAL, DIMENSION ( cims:cime, cjms:cjme ) :: cfld
     REAL, DIMENSION ( nims:nime, njms:njme ) :: nfld
     REAL,    DIMENSION ( cims:cime, cjms:cjme ), INTENT(IN) :: CBWGT1,CBWGT2,CBWGT3,CBWGT4    ! dummy
     REAL,    DIMENSION ( nims:nime, njms:njme ), INTENT(IN) :: HBWGT1,HBWGT2,HBWGT3,HBWGT4
     INTEGER, DIMENSION ( cims:cime, cjms:cjme ), INTENT(IN) :: CII,CJJ                        ! dummy
     INTEGER, DIMENSION ( nims:nime, njms:njme ), INTENT(IN) :: IIH,JJH
     INTEGER, DIMENSION ( nims:nime, njms:njme ) :: imask
     INTEGER , INTENT(IN) :: csst(*), ccsst(*)
!    local

     LOGICAL  FLIP
     INTEGER  i,j,k,n
     REAL     SUM,AMAXVAL
     REAL,    DIMENSION (4, nims:nime, njms:njme ) :: NBWGT

     if(csst(1) /= 1) return

!
!*** INDEX CONVENTIONS
!***                     NBWGT4=0
!***                      4
!***
!***
!***
!***                   h
!***             1                 2
!***            NBWGT1=1           NBWGT2=0
!***
!***
!***                      3
!***                     NBWGT3=0

     DO J=NJTS,MIN(NJTE,NJDE-1)
      DO I=NITS,MIN(NITE,NIDE-1)
            NBWGT(1,I,J)=HBWGT1(I,J)
            NBWGT(2,I,J)=HBWGT2(I,J)
            NBWGT(3,I,J)=HBWGT3(I,J)
            NBWGT(4,I,J)=HBWGT4(I,J)
      ENDDO
     ENDDO

     DO J=NJTS,MIN(NJTE,NJDE-1)
      DO I=NITS,MIN(NITE,NIDE-1)
          AMAXVAL=0.
          DO N=1,4
            AMAXVAL=amax1(NBWGT(N,I,J),AMAXVAL)
          ENDDO

          FLIP=.TRUE.
          SUM=0.0
          DO N=1,4
             IF(AMAXVAL .EQ. NBWGT(N,I,J) .AND. FLIP)THEN
               NBWGT(N,I,J)=1.0
               FLIP=.FALSE.
             ELSE
               NBWGT(N,I,J)=0.0
             ENDIF
             SUM=SUM+NBWGT(N,I,J)
             IF(SUM .GT. 1.0)CALL wrf_error_fatal ( "horizontal interp error - interp_hnear_nmm" )
          ENDDO
      ENDDO
     ENDDO

       DO J=NJTS,MIN(NJTE,NJDE-1)
        DO I=NITS,MIN(NITE,NIDE-1)
            IF(MOD(JJH(I,J),2) .NE. 0)THEN    ! 1,3,5,7 
                NFLD(I,J) = NBWGT(1,I,J)*CFLD(IIH(I,J),  JJH(I,J)  ) &
                          + NBWGT(2,I,J)*CFLD(IIH(I,J)+1,JJH(I,J)  ) &
                          + NBWGT(3,I,J)*CFLD(IIH(I,J),  JJH(I,J)-1) &
                          + NBWGT(4,I,J)*CFLD(IIH(I,J),  JJH(I,J)+1)
            ELSE
                NFLD(I,J) = NBWGT(1,I,J)*CFLD(IIH(I,J),  JJH(I,J)  ) &
                          + NBWGT(2,I,J)*CFLD(IIH(I,J)+1,JJH(I,J)  ) &
                          + NBWGT(3,I,J)*CFLD(IIH(I,J)+1,JJH(I,J)-1) &
                          + NBWGT(4,I,J)*CFLD(IIH(I,J)+1,JJH(I,J)+1)
            ENDIF
        ENDDO
       ENDDO


     END SUBROUTINE force_sst_nmm


   SUBROUTINE nmm_smoother_ikj ( cfld , &,2
                             cids, cide, ckds, ckde, cjds, cjde,   &
                             cims, cime, ckms, ckme, cjms, cjme,   &
                             cits, cite, ckts, ckte, cjts, cjte,   &
                             nids, nide, nkds, nkde, njds, njde,   &
                             nims, nime, nkms, nkme, njms, njme,   &
                             nits, nite, nkts, nkte, njts, njte,   &
                             xstag, ystag,                         &
                             ipos, jpos,                           &
                             nri, nrj                              &
                             )

      USE module_configure
      IMPLICIT NONE

      INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
                             cims, cime, ckms, ckme, cjms, cjme,   &
                             cits, cite, ckts, ckte, cjts, cjte,   &
                             nids, nide, nkds, nkde, njds, njde,   &
                             nims, nime, nkms, nkme, njms, njme,   &
                             nits, nite, nkts, nkte, njts, njte,   &
                             nri, nrj,                             &
                             ipos, jpos
      REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ), INTENT(INOUT) :: cfld
      LOGICAL, INTENT(IN) :: xstag, ystag


      ! Local

      INTEGER             :: feedback
      INTEGER, PARAMETER  :: smooth_passes = 5

      REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ) :: cfldnew
      INTEGER :: ci, cj, ck
      INTEGER :: is, npass
      REAL    :: AVGH
      CHARACTER (LEN=256) :: a_message

      RETURN
      !  If there is no feedback, there can be no smoothing.

      CALL nl_get_feedback       ( 1, feedback  )
      IF ( feedback == 0 ) RETURN

      WRITE(a_message,*)'SIMPLE SMOOTHER IS SWITCHED ON FOR HEIGHT'
      CALL wrf_message ( a_message )                       

      DO npass = 1, smooth_passes

      DO cj = MAX(jpos+1,cjts),MIN(jpos+(njde-njds)/nrj-1,cjte)  ! exclude top and bottom BCs
       if(mod(cj,2) .eq. 0)THEN
        is=0 ! even rows for mass points (2,4,6,8)
       else
        is=1 ! odd rows for mass points  (1,3,5,7)
       endif
       DO ck = ckts, ckte
        DO ci = MAX(ipos+is,cits),MIN(ipos+(nide-nids)/nri-1,cite) ! excludes LBCs
            IF(IS==0)THEN    ! (2,4,6,8)
             AVGH = CFLD(CI,CK,CJ+1) + CFLD(CI,CK,CJ-1) + CFLD(CI+1,CK,CJ+1) + CFLD(CI+1,CK,CJ-1)
            ELSE
             AVGH = CFLD(CI,CK,CJ+1) + CFLD(CI,CK,CJ-1) + CFLD(CI-1,CK,CJ+1) + CFLD(CI-1,CK,CJ-1)
            ENDIF
            CFLDNEW(CI,CK,CJ) = (AVGH + 4*CFLD(CI,CK,CJ)) / 8.0
        ENDDO
       ENDDO
      ENDDO

      DO cj = MAX(jpos+1,cjts),MIN(jpos+(njde-njds)/nrj-1,cjte)  ! exclude top and bottom BCs
       if(mod(cj,2) .eq. 0)THEN
        is=0 ! even rows for mass points (2,4,6,8)
       else
        is=1 ! odd rows for mass points  (1,3,5,7)
       endif
       DO ck = ckts, ckte
        DO ci = MAX(ipos+is,cits),MIN(ipos+(nide-nids)/nri-1,cite) ! excludes LBCs
           CFLD(CI,CK,CJ) = CFLDNEW(CI,CK,CJ)
        ENDDO
       ENDDO
      ENDDO

      ENDDO   ! do npass

   END SUBROUTINE nmm_smoother_ikj



   SUBROUTINE nmm_smoother_ijk ( cfld , &,2
                             cids, cide, ckds, ckde, cjds, cjde,   &
                             cims, cime, ckms, ckme, cjms, cjme,   &
                             cits, cite, ckts, ckte, cjts, cjte,   &
                             nids, nide, nkds, nkde, njds, njde,   &
                             nims, nime, nkms, nkme, njms, njme,   &
                             nits, nite, nkts, nkte, njts, njte,   &
                             xstag, ystag,                         &
                             ipos, jpos,                           &
                             nri, nrj                              &
                             )

      USE module_configure
      IMPLICIT NONE

      INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
                             cims, cime, ckms, ckme, cjms, cjme,   &
                             cits, cite, ckts, ckte, cjts, cjte,   &
                             nids, nide, nkds, nkde, njds, njde,   &
                             nims, nime, nkms, nkme, njms, njme,   &
                             nits, nite, nkts, nkte, njts, njte,   &
                             nri, nrj,                             &
                             ipos, jpos
      REAL, DIMENSION ( cims:cime, cjms:cjme, ckms:ckme ), INTENT(INOUT) :: cfld
      LOGICAL, INTENT(IN) :: xstag, ystag


      ! Local

      INTEGER             :: feedback
      INTEGER, PARAMETER  :: smooth_passes = 5

      REAL, DIMENSION ( cims:cime, cjms:cjme, ckms:ckme ) :: cfldnew
      INTEGER :: ci, cj, ck
      INTEGER :: is, npass
      REAL    :: AVGH
      CHARACTER (LEN=256) :: a_message

      RETURN
      !  If there is no feedback, there can be no smoothing.

      CALL nl_get_feedback       ( 1, feedback  )
      IF ( feedback == 0 ) RETURN

      WRITE(a_message,*)'SIMPLE SMOOTHER IS SWITCHED ON FOR HEIGHT'
      CALL wrf_message ( a_message )                       

      DO npass = 1, smooth_passes

      DO ck = ckts, ckte
       DO cj = MAX(jpos+1,cjts),MIN(jpos+(njde-njds)/nrj-1,cjte)  ! exclude top and bottom BCs
        if(mod(cj,2) .eq. 0)THEN
         is=0 ! even rows for mass points (2,4,6,8)
        else
         is=1 ! odd rows for mass points  (1,3,5,7)
        endif
        DO ci = MAX(ipos+is,cits),MIN(ipos+(nide-nids)/nri-1,cite) ! excludes LBCs
            IF(IS==0)THEN    ! (2,4,6,8)
             AVGH = CFLD(CI,CJ+1,CK) + CFLD(CI,CJ-1,CK) + CFLD(CI+1,CJ+1,CK) + CFLD(CI+1,CJ-1,CK)
            ELSE
             AVGH = CFLD(CI,CJ+1,CK) + CFLD(CI,CJ-1,CK) + CFLD(CI-1,CJ+1,CK) + CFLD(CI-1,CJ-1,CK)
            ENDIF
            CFLDNEW(CI,CJ,CK) = (AVGH + 4*CFLD(CI,CJ,CK)) / 8.0
        ENDDO
       ENDDO
      ENDDO

      DO ck = ckts, ckte
       DO cj = MAX(jpos+1,cjts),MIN(jpos+(njde-njds)/nrj-1,cjte)  ! exclude top and bottom BCs
        if(mod(cj,2) .eq. 0)THEN
         is=0 ! even rows for mass points (2,4,6,8)
        else
         is=1 ! odd rows for mass points  (1,3,5,7)
        endif
        DO ci = MAX(ipos+is,cits),MIN(ipos+(nide-nids)/nri-1,cite) ! excludes LBCs
           CFLD(CI,CJ,CK) = CFLDNEW(CI,CJ,CK)
        ENDDO
       ENDDO
      ENDDO

      ENDDO   ! do npass

   END SUBROUTINE nmm_smoother_ijk



   SUBROUTINE nmm_vsmoother_ikj ( cfld , &,2
                             cids, cide, ckds, ckde, cjds, cjde,   &
                             cims, cime, ckms, ckme, cjms, cjme,   &
                             cits, cite, ckts, ckte, cjts, cjte,   &
                             nids, nide, nkds, nkde, njds, njde,   &
                             nims, nime, nkms, nkme, njms, njme,   &
                             nits, nite, nkts, nkte, njts, njte,   &
                             xstag, ystag,                         &
                             ipos, jpos,                           &
                             nri, nrj                              &
                             )

      USE module_configure
      IMPLICIT NONE

      INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
                             cims, cime, ckms, ckme, cjms, cjme,   &
                             cits, cite, ckts, ckte, cjts, cjte,   &
                             nids, nide, nkds, nkde, njds, njde,   &
                             nims, nime, nkms, nkme, njms, njme,   &
                             nits, nite, nkts, nkte, njts, njte,   &
                             nri, nrj,                             &
                             ipos, jpos
      REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ), INTENT(INOUT) :: cfld
      LOGICAL, INTENT(IN) :: xstag, ystag


      ! Local

      INTEGER             :: feedback
      INTEGER, PARAMETER  :: smooth_passes = 5

      REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ) :: cfldnew
      INTEGER :: ci, cj, ck
      INTEGER :: is, npass
      REAL    :: AVGV
      CHARACTER (LEN=256) :: a_message

      RETURN
      !  If there is no feedback, there can be no smoothing.

      CALL nl_get_feedback       ( 1, feedback  )
      IF ( feedback == 0 ) RETURN

      WRITE(a_message,*)'SIMPLE SMOOTHER IS SWITCHED ON FOR VELOCITY'
      CALL wrf_message ( a_message )                       

      DO npass = 1, smooth_passes

      DO cj = MAX(jpos+1,cjts),MIN(jpos+(njde-njds)/nrj-1,cjte)  ! exclude top and bottom BCs
       if(mod(cj,2) .eq. 0)THEN
        is=1 ! even rows for mass points (2,4,6,8)
       else
        is=0 ! odd rows for mass points  (1,3,5,7)
       endif
       DO ck = ckts, ckte
        DO ci = MAX(ipos+is,cits),MIN(ipos+(nide-nids)/nri-1,cite) ! excludes LBCs
            IF(IS==0)THEN    ! (2,4,6,8)
             AVGV = CFLD(CI,CK,CJ+1) + CFLD(CI,CK,CJ-1) + CFLD(CI+1,CK,CJ+1) + CFLD(CI+1,CK,CJ-1)
            ELSE
             AVGV = CFLD(CI,CK,CJ+1) + CFLD(CI,CK,CJ-1) + CFLD(CI-1,CK,CJ+1) + CFLD(CI-1,CK,CJ-1)
            ENDIF
            CFLDNEW(CI,CK,CJ) = (AVGV + 4*CFLD(CI,CK,CJ)) / 8.0
        ENDDO
       ENDDO
      ENDDO

      DO cj = MAX(jpos+1,cjts),MIN(jpos+(njde-njds)/nrj-1,cjte)  ! exclude top and bottom BCs
       if(mod(cj,2) .eq. 0)THEN
        is=1 ! even rows for mass points (2,4,6,8)
       else
        is=0 ! odd rows for mass points  (1,3,5,7)
       endif
       DO ck = ckts, ckte
        DO ci = MAX(ipos+is,cits),MIN(ipos+(nide-nids)/nri-1,cite) ! excludes LBCs
           CFLD(CI,CK,CJ) = CFLDNEW(CI,CK,CJ)
        ENDDO
       ENDDO
      ENDDO

      ENDDO

   END SUBROUTINE nmm_vsmoother_ikj
!======================================================================================
!   End of gopal's doing
!======================================================================================
!======================================================================================
!   New NMM Interpolation Routines; wrappers around module_interp_nmm (Sam's doing)
!======================================================================================

!--------------------------------------------------------------------------------------
   

   subroutine NoInterpMany(cfld,                                 &  ! CD field
        cids, cide, ckds, ckde, cjds, cjde,   &
        cims, cime, ckms, ckme, cjms, cjme,   &
        cits, cite, ckts, ckte, cjts, cjte,   &
        nfld,                                 &  ! ND field
        nids, nide, nkds, nkde, njds, njde,   &
        nims, nime, nkms, nkme, njms, njme,   &
        nits, nite, nkts, nkte, njts, njte,   &
        shw,                                  &  ! stencil half width for interp
        imask,                                &  ! interpolation mask
        xstag, ystag,                         &  ! staggering of field
        ipos, jpos,                           &  ! Position of lower left of nest in CD
        nri, nrj,                             &  ! nest ratios                         
        cpint,npint, cpd,npd, cq,nq, ct,nt,   &
        cfis,nfis)
     LOGICAL,INTENT(IN) :: xstag, ystag
     INTEGER,INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
          cims, cime, ckms, ckme, cjms, cjme,   &
          cits, cite, ckts, ckte, cjts, cjte,   &
          nids, nide, nkds, nkde, njds, njde,   &
          nims, nime, nkms, nkme, njms, njme,   &
          nits, nite, nkts, nkte, njts, njte,   &
          shw,ipos,jpos,nri,nrj

     INTEGER,DIMENSION(nims:nime,njms:njme),          INTENT(IN)           :: IMASK

     !  parent domain

     REAL,DIMENSION(cims:cime,cjms:cjme,ckms:ckme),   INTENT(IN)           :: CFLD,cpint,ct,cq
     REAL,DIMENSION(cims:cime,cjms:cjme),             INTENT(IN)           :: cpd,cfis

     !  nested domain

     REAL,DIMENSION(nims:nime,njms:njme),             INTENT(IN)           :: nFIS,npd
     REAL,DIMENSION(nims:nime,njms:njme,nkms:nkme),   INTENT(IN)           :: NFLD,npint,nt,nq

   end subroutine NoInterpMany


   subroutine DownAged2D(junk,                &,3
        cids, cide, ckds, ckde, cjds, cjde,   &
        cims, cime, ckms, ckme, cjms, cjme,   &
        cits, cite, ckts, ckte, cjts, cjte,   &
        nfld,                                 &  ! ND field
        nids, nide, nkds, nkde, njds, njde,   &
        nims, nime, nkms, nkme, njms, njme,   &
        nits, nite, nkts, nkte, njts, njte,   &
        shw,                                  &  ! stencil half width for interp
        imask,                                &  ! interpolation mask
        xstag, ystag,                         &  ! staggering of field
        ipos, jpos,                           &  ! Position of lower left of nest in CD
        nri, nrj, &
        c_age,n_age, cfld)

     use module_interp_nmm, only: c2n_copy2d_nomask
     use module_interp_store
     implicit none
     LOGICAL,INTENT(IN) :: xstag, ystag
     INTEGER,INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
          cims, cime, ckms, ckme, cjms, cjme,   &
          cits, cite, ckts, ckte, cjts, cjte,   &
          nids, nide, nkds, nkde, njds, njde,   &
          nims, nime, nkms, nkme, njms, njme,   &
          nits, nite, nkts, nkte, njts, njte,   &
          shw,ipos,jpos,nri,nrj

     integer, intent(in) :: c_age
     integer, intent(inout) :: n_age

     INTEGER,DIMENSION(nims:nime,njms:njme),          INTENT(IN)           :: IMASK
     REAL,DIMENSION(cims:cime,cjms:cjme),   INTENT(IN)           :: CFLD,junk
     REAL,DIMENSION(nims:nime,njms:njme),   INTENT(INOUT)        :: nfld

     logical bad
     integer i,j
     ! Skip if the nest is up-to-date with the parent.  Special age
     ! of 0 means the values are invalid (parent just moved, nest
     ! just moved or one was initialized).
     if(n_age==c_age .and. n_age/=0 .and. c_age/=0) then
        !write(0,*) 'Grid ',grid_id,' not storing pdyn in DownAged2D'
        !write(0,*) '  reason: n_age=',n_age,' c_age=',c_age
        return
     end if
     n_age=c_age
     !write(0,*) 'Storing grid ',parent_grid_id,' pdyn_smooth in grid ',grid_id,' pdyn_parent'

     call c2n_copy2d_nomask(IIH,JJH,HBWGT1,HBWGT2,HBWGT3,HBWGT4,  &
          cfld,nfld,                &
          cims, cime, cjms, cjme,   &
          nids, nide, njds, njde,   &
          nims, nime, njms, njme,   &
          nits, nite, njts, njte, .true.)

   end subroutine DownAged2D


   subroutine ForceNearSST   (cfld,                                 &  ! CD field,3
        cids, cide, ckds, ckde, cjds, cjde,   &
        cims, cime, ckms, ckme, cjms, cjme,   &
        cits, cite, ckts, ckte, cjts, cjte,   &
        nfld,                                 &  ! ND field
        nids, nide, nkds, nkde, njds, njde,   &
        nims, nime, nkms, nkme, njms, njme,   &
        nits, nite, nkts, nkte, njts, njte,   &
        shw,                                  &  ! stencil half width for interp
        imask,                                &  ! interpolation mask
        xstag, ystag,                         &  ! staggering of field
        ipos, jpos,                           &  ! Position of lower left of nest in CD
        nri, nrj, &
        cactivate, nactivate)
     use module_interp_nmm, only: c2n_sst
     use module_interp_store
     implicit none
     LOGICAL,INTENT(IN) :: xstag, ystag
     INTEGER,INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
          cims, cime, ckms, ckme, cjms, cjme,   &
          cits, cite, ckts, ckte, cjts, cjte,   &
          nids, nide, nkds, nkde, njds, njde,   &
          nims, nime, nkms, nkme, njms, njme,   &
          nits, nite, nkts, nkte, njts, njte,   &
          shw,ipos,jpos,nri,nrj

     integer, intent(In), dimension(*) :: cactivate, nactivate

     INTEGER,DIMENSION(nims:nime,njms:njme),          INTENT(IN)           :: IMASK
     REAL,DIMENSION(cims:cime,cjms:cjme),   INTENT(IN)           :: CFLD
     REAL,DIMENSION(nims:nime,njms:njme),   INTENT(INOUT)        :: nfld

     if(nactivate(1)/=1) return

     call c2n_sst(hnear_i,hnear_j,          &
          cfld,nfld,                &
          cims, cime, cjms, cjme,   &
          nids, nide, njds, njde,   &
          nims, nime, njms, njme,   &
          nits, nite, njts, njte)
   end subroutine ForceNearSST


   subroutine DownNear      (cfld,                                 &  ! CD field,4
        cids, cide, ckds, ckde, cjds, cjde,   &
        cims, cime, ckms, ckme, cjms, cjme,   &
        cits, cite, ckts, ckte, cjts, cjte,   &
        nfld,                                 &  ! ND field
        nids, nide, nkds, nkde, njds, njde,   &
        nims, nime, nkms, nkme, njms, njme,   &
        nits, nite, nkts, nkte, njts, njte,   &
        shw,                                  &  ! stencil half width for interp
        imask,                                &  ! interpolation mask
        xstag, ystag,                         &  ! staggering of field
        ipos, jpos,                           &  ! Position of lower left of nest in CD
        nri, nrj)                                ! nest ratios         
     use module_interp_nmm, only: c2n_near2d, c2n_near3d
     use module_interp_store
     implicit none
     LOGICAL,INTENT(IN) :: xstag, ystag
     INTEGER,INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
          cims, cime, ckms, ckme, cjms, cjme,   &
          cits, cite, ckts, ckte, cjts, cjte,   &
          nids, nide, nkds, nkde, njds, njde,   &
          nims, nime, nkms, nkme, njms, njme,   &
          nits, nite, nkts, nkte, njts, njte,   &
          shw,ipos,jpos,nri,nrj

     INTEGER,DIMENSION(nims:nime,njms:njme),          INTENT(IN)           :: IMASK
     REAL,DIMENSION(cims:cime,cjms:cjme),   INTENT(IN)           :: CFLD
     REAL,DIMENSION(nims:nime,njms:njme),   INTENT(INOUT)          :: nfld

     if(nkts==nkte) then
        call c2n_near2d(hnear_i,hnear_j,   &
             cfld,nfld,imask,                       &
             cims, cime, cjms, cjme,   &
             nids, nide, njds, njde,   &
             nims, nime, njms, njme,   &
             nits, nite, njts, njte)
     else
        call c2n_near3d(hnear_i,hnear_j,   &
             cfld,nfld,imask,                       &
             cims, cime, cjms, cjme, ckms, ckme,   &
             nids, nide, njds, njde, nkds, nkde,   &
             nims, nime, njms, njme, nkms, nkme,   &
             nits, nite, njts, njte, nkts, nkte)
     endif
   end subroutine DownNear


   subroutine DownNearIKJ   (cfld,                                 &  ! CD field,4
        cids, cide, ckds, ckde, cjds, cjde,   &
        cims, cime, ckms, ckme, cjms, cjme,   &
        cits, cite, ckts, ckte, cjts, cjte,   &
        nfld,                                 &  ! ND field
        nids, nide, nkds, nkde, njds, njde,   &
        nims, nime, nkms, nkme, njms, njme,   &
        nits, nite, nkts, nkte, njts, njte,   &
        shw,                                  &  ! stencil half width for interp
        imask,                                &  ! interpolation mask
        xstag, ystag,                         &  ! staggering of field
        ipos, jpos,                           &  ! Position of lower left of nest in CD
        nri, nrj)                                ! nest ratios         
     use module_interp_nmm, only: c2n_near3dikj
     use module_interp_store
     implicit none
     LOGICAL,INTENT(IN) :: xstag, ystag
     INTEGER,INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
          cims, cime, ckms, ckme, cjms, cjme,   &
          cits, cite, ckts, ckte, cjts, cjte,   &
          nids, nide, nkds, nkde, njds, njde,   &
          nims, nime, nkms, nkme, njms, njme,   &
          nits, nite, nkts, nkte, njts, njte,   &
          shw,ipos,jpos,nri,nrj

     INTEGER,DIMENSION(nims:nime,njms:njme),          INTENT(IN)           :: IMASK
     REAL,DIMENSION(cims:cime,ckms:ckme,cjms:cjme),   INTENT(IN)           :: CFLD
     REAL,DIMENSION(nims:nime,nkms:nkme,njms:njme),   INTENT(INOUT)          :: nfld
     
     if(nkts==nkte) &
          call wrf_error_fatal('IJ interpolation of an IKJ variable is not supported and makes no sense anyway.  Use DownNear instead.')

     call c2n_near3dikj(hnear_i,hnear_j,   &
          cfld,nfld,imask,                       &
          cims, cime, cjms, cjme, ckms, ckme,  &
          nids, nide, njds, njde, nkds, nkde,  &
          nims, nime, njms, njme, nkms, nkme,  &
          nits, nite, njts, njte, nkts, nkte)
   end subroutine DownNearIKJ


   subroutine UpNear(cfld,                    &  ! CD field,4
        cids, cide, ckds, ckde, cjds, cjde,   &
        cims, cime, ckms, ckme, cjms, cjme,   &
        cits, cite, ckts, ckte, cjts, cjte,   &
        nfld,                                 &  ! ND field
        nids, nide, nkds, nkde, njds, njde,   &
        nims, nime, nkms, nkme, njms, njme,   &
        nits, nite, nkts, nkte, njts, njte,   &
        shw,                                  &  ! stencil half width for interp
        imask,                                &  ! interpolation mask
        xstag, ystag,                         &  ! staggering of field
        ipos, jpos,                           &  ! Position of lower left of nest in CD
        nri, nrj)                                ! nest ratios                         
     use module_interp_store
     use module_interp_nmm, only: n2c_near2d
     implicit none
     LOGICAL,INTENT(IN) :: xstag, ystag
     INTEGER,INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
          cims, cime, ckms, ckme, cjms, cjme,   &
          cits, cite, ckts, ckte, cjts, cjte,   &
          nids, nide, nkds, nkde, njds, njde,   &
          nims, nime, nkms, nkme, njms, njme,   &
          nits, nite, nkts, nkte, njts, njte,   &
          shw,ipos,jpos,nri,nrj

     INTEGER,DIMENSION(nims:nime,njms:njme),          INTENT(IN)           :: IMASK
     REAL,DIMENSION(cims:cime,cjms:cjme),   INTENT(OUT)           :: CFLD
     REAL,DIMENSION(nims:nime,njms:njme),   INTENT(IN)          :: nfld

     if(nkts/=nkte) &
          call wrf_error_fatal('Up nearest neighbor interpolation is not implemented.')

     call n2c_near2d( cfld,nfld,ipos,jpos,                  &
          cids, cide, cjds, cjde,   &
          cims, cime, cjms, cjme,   &
          cits, cite, cjts, cjte,   &
          nids, nide, njds, njde,   &
          nims, nime, njms, njme,   &
          nits, nite, njts, njte)
   end subroutine UpNear


   subroutine DownINear      (cfld,                                 &  ! CD field,4
        cids, cide, ckds, ckde, cjds, cjde,   &
        cims, cime, ckms, ckme, cjms, cjme,   &
        cits, cite, ckts, ckte, cjts, cjte,   &
        nfld,                                 &  ! ND field
        nids, nide, nkds, nkde, njds, njde,   &
        nims, nime, nkms, nkme, njms, njme,   &
        nits, nite, nkts, nkte, njts, njte,   &
        shw,                                  &  ! stencil half width for interp
        imask,                                &  ! interpolation mask
        xstag, ystag,                         &  ! staggering of field
        ipos, jpos,                           &  ! Position of lower left of nest in CD
        nri, nrj)                                ! nest ratios         
     use module_interp_nmm, only: c2n_inear2d
     use module_interp_store
     implicit none
     LOGICAL,INTENT(IN) :: xstag, ystag
     INTEGER,INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
          cims, cime, ckms, ckme, cjms, cjme,   &
          cits, cite, ckts, ckte, cjts, cjte,   &
          nids, nide, nkds, nkde, njds, njde,   &
          nims, nime, nkms, nkme, njms, njme,   &
          nits, nite, nkts, nkte, njts, njte,   &
          shw,ipos,jpos,nri,nrj

     INTEGER,DIMENSION(nims:nime,njms:njme),          INTENT(IN)           :: IMASK
     INTEGER,DIMENSION(cims:cime,cjms:cjme),   INTENT(IN)           :: CFLD
     INTEGER,DIMENSION(nims:nime,njms:njme),   INTENT(INOUT)          :: nfld

     if(nkts/=nkte) &
          call wrf_error_fatal('3D integer nearest neighbor interpolation is not implemented.')

     call c2n_inear2d(hnear_i,hnear_j,   &
          cfld,nfld,imask,                       &
          cims, cime, cjms, cjme,   &
          nids, nide, njds, njde,   &
          nims, nime, njms, njme,   &
          nits, nite, njts, njte)
   end subroutine DownINear


   subroutine UpINear        (cfld,                                 &  ! CD field,4
        cids, cide, ckds, ckde, cjds, cjde,   &
        cims, cime, ckms, ckme, cjms, cjme,   &
        cits, cite, ckts, ckte, cjts, cjte,   &
        nfld,                                 &  ! ND field
        nids, nide, nkds, nkde, njds, njde,   &
        nims, nime, nkms, nkme, njms, njme,   &
        nits, nite, nkts, nkte, njts, njte,   &
        shw,                                  &  ! stencil half width for interp
        imask,                                &  ! interpolation mask
        xstag, ystag,                         &  ! staggering of field
        ipos, jpos,                           &  ! Position of lower left of nest in CD
        nri, nrj)                                ! nest ratios                         
     use module_interp_store
     use module_interp_nmm, only: n2c_inear2d
     implicit none
     LOGICAL,INTENT(IN) :: xstag, ystag
     INTEGER,INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
          cims, cime, ckms, ckme, cjms, cjme,   &
          cits, cite, ckts, ckte, cjts, cjte,   &
          nids, nide, nkds, nkde, njds, njde,   &
          nims, nime, nkms, nkme, njms, njme,   &
          nits, nite, nkts, nkte, njts, njte,   &
          shw,ipos,jpos,nri,nrj

     INTEGER,DIMENSION(nims:nime,njms:njme),          INTENT(IN)           :: IMASK
     INTEGER,DIMENSION(cims:cime,cjms:cjme),   INTENT(OUT)           :: CFLD
     INTEGER,DIMENSION(nims:nime,njms:njme),   INTENT(IN)          :: nfld

     if(nkts/=nkte) &
          call wrf_error_fatal('3D integer nearest neighbor interpolation is not implemented.')

     call n2c_inear2d( cfld,nfld,ipos,jpos,                  &
          cids, cide, cjds, cjde,   &
          cims, cime, cjms, cjme,   &
          cits, cite, cjts, cjte,   &
          nids, nide, njds, njde,   &
          nims, nime, njms, njme,   &
          nits, nite, njts, njte)
   end subroutine UpINear


   subroutine DownMass      (cfld,                                 &  ! CD field,4
        cids, cide, ckds, ckde, cjds, cjde,   &
        cims, cime, ckms, ckme, cjms, cjme,   &
        cits, cite, ckts, ckte, cjts, cjte,   &
        nfld,                                 &  ! ND field
        nids, nide, nkds, nkde, njds, njde,   &
        nims, nime, nkms, nkme, njms, njme,   &
        nits, nite, nkts, nkte, njts, njte,   &
        shw,                                  &  ! stencil half width for interp
        imask,                                &  ! interpolation mask
        xstag, ystag,                         &  ! staggering of field
        ipos, jpos,                           &  ! Position of lower left of nest in CD
        nri, nrj,                             &  ! nest ratios
        emethod, evalue)                         ! extrapolation method
     use module_interp_nmm, only: c2n_mass, c2n_copy2d
     use module_interp_store
     implicit none
     LOGICAL,INTENT(IN) :: xstag, ystag
     INTEGER,INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
          cims, cime, ckms, ckme, cjms, cjme,   &
          cits, cite, ckts, ckte, cjts, cjte,   &
          nids, nide, nkds, nkde, njds, njde,   &
          nims, nime, nkms, nkme, njms, njme,   &
          nits, nite, nkts, nkte, njts, njte,   &
          shw,ipos,jpos,nri,nrj, emethod
     real, intent(in) :: evalue

     INTEGER,DIMENSION(nims:nime,njms:njme),          INTENT(IN)           :: IMASK
     REAL,DIMENSION(cims:cime,cjms:cjme,ckms:ckme),   INTENT(IN)           :: CFLD
     REAL,DIMENSION(nims:nime,njms:njme,nkms:nkme),   INTENT(INOUT)          :: nfld

     if(nkts==nkte) then
        call c2n_copy2d(IIH,JJH,HBWGT1,HBWGT2,HBWGT3,HBWGT4,  &
             cfld,nfld,imask,                &
             cims, cime, cjms, cjme,   &
             nids, nide, njds, njde,   &
             nims, nime, njms, njme,   &
             nits, nite, njts, njte, .true.)
     else
        call c2n_mass(IIH,JJH,HBWGT1,HBWGT2,HBWGT3,HBWGT4,   &
             cfld,nfld,iinfo,winfo,imask,          &
             emethod,evalue,                       &
             cims, cime, cjms, cjme, ckms, ckme,   &
             nids, nide, njds, njde, nkds, nkde,   &
             nims, nime, njms, njme, nkms, nkme,   &
             nits, nite, njts, njte, nkts, nkte)
     endif
   end subroutine DownMass


   subroutine DownMassIKJ   (cfld,                                 &  ! CD field,4
        cids, cide, ckds, ckde, cjds, cjde,   &
        cims, cime, ckms, ckme, cjms, cjme,   &
        cits, cite, ckts, ckte, cjts, cjte,   &
        nfld,                                 &  ! ND field
        nids, nide, nkds, nkde, njds, njde,   &
        nims, nime, nkms, nkme, njms, njme,   &
        nits, nite, nkts, nkte, njts, njte,   &
        shw,                                  &  ! stencil half width for interp
        imask,                                &  ! interpolation mask
        xstag, ystag,                         &  ! staggering of field
        ipos, jpos,                           &  ! Position of lower left of nest in CD
        nri, nrj,                             &  ! nest ratios
        emethod, evalue)                         ! extrapolation method
     use module_interp_nmm, only: c2n_massikj
     use module_interp_store
     implicit none
     LOGICAL,INTENT(IN) :: xstag, ystag
     INTEGER,INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
          cims, cime, ckms, ckme, cjms, cjme,   &
          cits, cite, ckts, ckte, cjts, cjte,   &
          nids, nide, nkds, nkde, njds, njde,   &
          nims, nime, nkms, nkme, njms, njme,   &
          nits, nite, nkts, nkte, njts, njte,   &
          shw,ipos,jpos,nri,nrj,emethod
     real, intent(in) :: evalue

     INTEGER,DIMENSION(nims:nime,njms:njme),          INTENT(IN)           :: IMASK
     REAL,DIMENSION(cims:cime,ckms:ckme,cjms:cjme),   INTENT(IN)           :: CFLD
     REAL,DIMENSION(nims:nime,nkms:nkme,njms:njme),   INTENT(INOUT)          :: nfld

     if(nkts==nkte) &
          call wrf_error_fatal('IKJ 2D interpolation of an IJ array is not implemented (and makes no sense anyway).  Use DownCopy instead.')
     call c2n_massikj(IIH,JJH,HBWGT1,HBWGT2,HBWGT3,HBWGT4,   &
          cfld,nfld,iinfo,winfo,imask,          &
          emethod, evalue,                      &
          cims, cime, cjms, cjme, ckms, ckme,   &
          nids, nide, njds, njde, nkds, nkde,   &
          nims, nime, njms, njme, nkms, nkme,   &
          nits, nite, njts, njte, nkts, nkte)
   end subroutine DownMassIKJ


   subroutine UpMassIKJ     (cfld,                                 &  ! CD field,4
        cids, cide, ckds, ckde, cjds, cjde,   &
        cims, cime, ckms, ckme, cjms, cjme,   &
        cits, cite, ckts, ckte, cjts, cjte,   &
        nfld,                                 &  ! ND field
        nids, nide, nkds, nkde, njds, njde,   &
        nims, nime, nkms, nkme, njms, njme,   &
        nits, nite, nkts, nkte, njts, njte,   &
        shw,                                  &  ! stencil half width for interp
        imask,                                &  ! interpolation mask
        xstag, ystag,                         &  ! staggering of field
        ipos, jpos,                           &  ! Position of lower left of nest in CD
        nri, nrj,                             &  ! nest ratios                         
        emethod, evalue)                         ! extrapolation method
     use module_interp_store
     use module_interp_nmm, only: n2c_massikj, n2c_copy2d
     implicit none
     LOGICAL,INTENT(IN) :: xstag, ystag
     INTEGER,INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
          cims, cime, ckms, ckme, cjms, cjme,   &
          cits, cite, ckts, ckte, cjts, cjte,   &
          nids, nide, nkds, nkde, njds, njde,   &
          nims, nime, nkms, nkme, njms, njme,   &
          nits, nite, nkts, nkte, njts, njte,   &
          shw,ipos,jpos,nri,nrj, emethod
     real, intent(in) :: evalue

     INTEGER,DIMENSION(nims:nime,njms:njme),          INTENT(IN)           :: IMASK
     REAL,DIMENSION(cims:cime,ckms:ckme,cjms:cjme),   INTENT(OUT)           :: CFLD
     REAL,DIMENSION(nims:nime,nkms:nkme,njms:njme),   INTENT(IN)          :: nfld

     if(nkts==nkte) then
        call n2c_copy2d(&
             cfld,nfld,ipos,jpos,                   &
             cids, cide, cjds, cjde,   &
             cims, cime, cjms, cjme,   &
             cits, cite, cjts, cjte,   &
             nids, nide, njds, njde,   &
             nims, nime, njms, njme,   &
             nits, nite, njts, njte, .true.)
     else
        call n2c_massikj(&
             cfld,nfld,parent_iinfo,parent_winfo,  &
             ipos,jpos,emethod, evalue,            &
             cids, cide, cjds, cjde, ckds, ckde,   &
             cims, cime, cjms, cjme, ckms, ckme,   &
             cits, cite, cjts, cjte, ckts, ckte,   &
             nids, nide, njds, njde, nkds, nkde,   &
             nims, nime, njms, njme, nkms, nkme,   &
             nits, nite, njts, njte, nkts, nkte)
     endif
   end subroutine UpMassIKJ


   subroutine UpMass        (cfld,                                 &  ! CD field,4
        cids, cide, ckds, ckde, cjds, cjde,   &
        cims, cime, ckms, ckme, cjms, cjme,   &
        cits, cite, ckts, ckte, cjts, cjte,   &
        nfld,                                 &  ! ND field
        nids, nide, nkds, nkde, njds, njde,   &
        nims, nime, nkms, nkme, njms, njme,   &
        nits, nite, nkts, nkte, njts, njte,   &
        shw,                                  &  ! stencil half width for interp
        imask,                                &  ! interpolation mask
        xstag, ystag,                         &  ! staggering of field
        ipos, jpos,                           &  ! Position of lower left of nest in CD
        nri, nrj,                             &  ! nest ratios                         
        emethod, evalue)                         ! extrapolation method
     use module_interp_store
     use module_interp_nmm, only: n2c_mass, n2c_copy2d
     implicit none
     LOGICAL,INTENT(IN) :: xstag, ystag
     INTEGER,INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
          cims, cime, ckms, ckme, cjms, cjme,   &
          cits, cite, ckts, ckte, cjts, cjte,   &
          nids, nide, nkds, nkde, njds, njde,   &
          nims, nime, nkms, nkme, njms, njme,   &
          nits, nite, nkts, nkte, njts, njte,   &
          shw,ipos,jpos,nri,nrj, emethod
     real, intent(in) :: evalue

     INTEGER,DIMENSION(nims:nime,njms:njme),          INTENT(IN)           :: IMASK
     REAL,DIMENSION(cims:cime,cjms:cjme,ckms:ckme),   INTENT(OUT)           :: CFLD
     REAL,DIMENSION(nims:nime,njms:njme,nkms:nkme),   INTENT(IN)          :: nfld

     if(nkts==nkte) then
        call n2c_copy2d(&
             cfld,nfld,ipos,jpos,                   &
             cids, cide, cjds, cjde,   &
             cims, cime, cjms, cjme,   &
             cits, cite, cjts, cjte,   &
             nids, nide, njds, njde,   &
             nims, nime, njms, njme,   &
             nits, nite, njts, njte, .true.)
     else
        call n2c_mass(&
             cfld,nfld,parent_iinfo,parent_winfo,  &
             ipos,jpos,emethod, evalue,            &
             cids, cide, cjds, cjde, ckds, ckde,   &
             cims, cime, cjms, cjme, ckms, ckme,   &
             cits, cite, cjts, cjte, ckts, ckte,   &
             nids, nide, njds, njde, nkds, nkde,   &
             nims, nime, njms, njme, nkms, nkme,   &
             nits, nite, njts, njte, nkts, nkte)
     endif
   end subroutine UpMass


   subroutine UpCopy         (cfld,                                 &  ! CD field,3
        cids, cide, ckds, ckde, cjds, cjde,   &
        cims, cime, ckms, ckme, cjms, cjme,   &
        cits, cite, ckts, ckte, cjts, cjte,   &
        nfld,                                 &  ! ND field
        nids, nide, nkds, nkde, njds, njde,   &
        nims, nime, nkms, nkme, njms, njme,   &
        nits, nite, nkts, nkte, njts, njte,   &
        shw,                                  &  ! stencil half width for interp
        imask,                                &  ! interpolation mask
        xstag, ystag,                         &  ! staggering of field
        ipos, jpos,                           &  ! Position of lower left of nest in CD
        nri, nrj)                                ! nest ratios                         

     use module_interp_nmm, only: n2c_copy3d, n2c_copy2d
     implicit none
     LOGICAL,INTENT(IN) :: xstag, ystag
     INTEGER,INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
          cims, cime, ckms, ckme, cjms, cjme,   &
          cits, cite, ckts, ckte, cjts, cjte,   &
          nids, nide, nkds, nkde, njds, njde,   &
          nims, nime, nkms, nkme, njms, njme,   &
          nits, nite, nkts, nkte, njts, njte,   &
          shw,ipos,jpos,nri,nrj

     INTEGER,DIMENSION(nims:nime,njms:njme),          INTENT(IN)           :: IMASK
     REAL,DIMENSION(cims:cime,cjms:cjme,ckms:ckme),   INTENT(OUT)           :: CFLD
     REAL,DIMENSION(nims:nime,njms:njme,nkms:nkme),   INTENT(IN)          :: nfld

     if(nkts==nkte) then
        call n2c_copy2d(&
             cfld,nfld,ipos,jpos,                   &
             cids, cide, cjds, cjde,   &
             cims, cime, cjms, cjme,   &
             cits, cite, cjts, cjte,   &
             nids, nide, njds, njde,   &
             nims, nime, njms, njme,   &
             nits, nite, njts, njte, .true.)
     else
        call n2c_copy3d(&
             cfld,nfld,ipos,jpos,                   &
             cids, cide, cjds, cjde, ckds, ckde,   &
             cims, cime, cjms, cjme, ckms, ckme,   &
             cits, cite, cjts, cjte, ckts, ckte,   &
             nids, nide, njds, njde, nkds, nkde,   &
             nims, nime, njms, njme, nkms, nkme,   &
             nits, nite, njts, njte, nkts, nkte, .true.)
     endif
   end subroutine UpCopy


   subroutine UpMax          (cfld,                                 &  ! CD field,3
        cids, cide, ckds, ckde, cjds, cjde,   &
        cims, cime, ckms, ckme, cjms, cjme,   &
        cits, cite, ckts, ckte, cjts, cjte,   &
        nfld,                                 &  ! ND field
        nids, nide, nkds, nkde, njds, njde,   &
        nims, nime, nkms, nkme, njms, njme,   &
        nits, nite, nkts, nkte, njts, njte,   &
        shw,                                  &  ! stencil half width for interp
        imask,                                &  ! interpolation mask
        xstag, ystag,                         &  ! staggering of field
        ipos, jpos,                           &  ! Position of lower left of nest in CD
        nri, nrj)                                ! nest ratios                         

     use module_interp_nmm, only: n2c_max3d, n2c_max2d
     implicit none
     LOGICAL,INTENT(IN) :: xstag, ystag
     INTEGER,INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
          cims, cime, ckms, ckme, cjms, cjme,   &
          cits, cite, ckts, ckte, cjts, cjte,   &
          nids, nide, nkds, nkde, njds, njde,   &
          nims, nime, nkms, nkme, njms, njme,   &
          nits, nite, nkts, nkte, njts, njte,   &
          shw,ipos,jpos,nri,nrj

     INTEGER,DIMENSION(nims:nime,njms:njme),          INTENT(IN)           :: IMASK
     REAL,DIMENSION(cims:cime,cjms:cjme,ckms:ckme),   INTENT(OUT)           :: CFLD
     REAL,DIMENSION(nims:nime,njms:njme,nkms:nkme),   INTENT(IN)          :: nfld

     if(nkts==nkte) then
        call n2c_max2d(&
             cfld,nfld,ipos,jpos,                   &
             cids, cide, cjds, cjde,   &
             cims, cime, cjms, cjme,   &
             cits, cite, cjts, cjte,   &
             nids, nide, njds, njde,   &
             nims, nime, njms, njme,   &
             nits, nite, njts, njte, .true.)
     else
        call n2c_max3d(&
             cfld,nfld,ipos,jpos,                   &
             cids, cide, cjds, cjde, ckds, ckde,   &
             cims, cime, cjms, cjme, ckms, ckme,   &
             cits, cite, cjts, cjte, ckts, ckte,   &
             nids, nide, njds, njde, nkds, nkde,   &
             nims, nime, njms, njme, nkms, nkme,   &
             nits, nite, njts, njte, nkts, nkte, .true.)
     endif
   end subroutine UpMax


   subroutine DownCopy      (cfld,                                 &  ! CD field,4
        cids, cide, ckds, ckde, cjds, cjde,   &
        cims, cime, ckms, ckme, cjms, cjme,   &
        cits, cite, ckts, ckte, cjts, cjte,   &
        nfld,                                 &  ! ND field
        nids, nide, nkds, nkde, njds, njde,   &
        nims, nime, nkms, nkme, njms, njme,   &
        nits, nite, nkts, nkte, njts, njte,   &
        shw,                                  &  ! stencil half width for interp
        imask,                                &  ! interpolation mask
        xstag, ystag,                         &  ! staggering of field
        ipos, jpos,                           &  ! Position of lower left of nest in CD
        nri, nrj)                                ! nest ratios                         
     use module_interp_store
     use module_interp_nmm, only: c2n_copy3d, c2n_copy2d
     implicit none
     LOGICAL,INTENT(IN) :: xstag, ystag
     INTEGER,INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
          cims, cime, ckms, ckme, cjms, cjme,   &
          cits, cite, ckts, ckte, cjts, cjte,   &
          nids, nide, nkds, nkde, njds, njde,   &
          nims, nime, nkms, nkme, njms, njme,   &
          nits, nite, nkts, nkte, njts, njte,   &
          shw,ipos,jpos,nri,nrj

     INTEGER,DIMENSION(nims:nime,njms:njme),          INTENT(IN)           :: IMASK
     REAL,DIMENSION(cims:cime,cjms:cjme,ckms:ckme),   INTENT(IN)           :: CFLD
     REAL,DIMENSION(nims:nime,njms:njme,nkms:nkme),   INTENT(INOUT)          :: nfld

     if(nkts==nkte) then
        call c2n_copy2d(IIH,JJH,HBWGT1,HBWGT2,HBWGT3,HBWGT4,  &
             cfld,nfld,imask,                &
             cims, cime, cjms, cjme,   &
             nids, nide, njds, njde,   &
             nims, nime, njms, njme,   &
             nits, nite, njts, njte, .true.)
     else
        call c2n_copy3d(IIH,JJH,HBWGT1,HBWGT2,HBWGT3,HBWGT4,  &
             cfld,nfld,imask,                &
             cims, cime, cjms, cjme, ckms, ckme,   &
             nids, nide, njds, njde, nkds, nkde,   &
             nims, nime, njms, njme, nkms, nkme,   &
             nits, nite, njts, njte, nkts, nkte, .true.)
     endif
   end subroutine DownCopy


   subroutine UpVel   (cfld,                                 &  ! CD field,3
        cids, cide, ckds, ckde, cjds, cjde,   &
        cims, cime, ckms, ckme, cjms, cjme,   &
        cits, cite, ckts, ckte, cjts, cjte,   &
        nfld,                                 &  ! ND field
        nids, nide, nkds, nkde, njds, njde,   &
        nims, nime, nkms, nkme, njms, njme,   &
        nits, nite, nkts, nkte, njts, njte,   &
        shw,                                  &  ! stencil half width for interp
        imask,                                &  ! interpolation mask
        xstag, ystag,                         &  ! staggering of field
        ipos, jpos,                           &  ! Position of lower left of nest in CD
        nri, nrj)                                ! nest ratios                         

     use module_interp_nmm, only: n2c_copy3d, n2c_copy2d
     implicit none
     LOGICAL,INTENT(IN) :: xstag, ystag
     INTEGER,INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
          cims, cime, ckms, ckme, cjms, cjme,   &
          cits, cite, ckts, ckte, cjts, cjte,   &
          nids, nide, nkds, nkde, njds, njde,   &
          nims, nime, nkms, nkme, njms, njme,   &
          nits, nite, nkts, nkte, njts, njte,   &
          shw,ipos,jpos,nri,nrj

     INTEGER,DIMENSION(nims:nime,njms:njme),          INTENT(IN)           :: IMASK
     REAL,DIMENSION(cims:cime,cjms:cjme,ckms:ckme),   INTENT(OUT)           :: CFLD
     REAL,DIMENSION(nims:nime,njms:njme,nkms:nkme),   INTENT(IN)          :: nfld

     if(nkts==nkte) then
        call n2c_copy2d( cfld,nfld,ipos,jpos,             &
             cids, cide, cjds, cjde,   &
             cims, cime, cjms, cjme,   &
             cits, cite, cjts, cjte,   &
             nids, nide, njds, njde,   &
             nims, nime, njms, njme,   &
             nits, nite, njts, njte, .false.)
     else
        call n2c_copy3d(&
             cfld,nfld,ipos,jpos,                   &
             cids, cide, cjds, cjde, ckds, ckde,   &
             cims, cime, cjms, cjme, ckms, ckme,   &
             cits, cite, cjts, cjte, ckts, ckte,   &
             nids, nide, njds, njde, nkds, nkde,   &
             nims, nime, njms, njme, nkms, nkme,   &
             nits, nite, njts, njte, nkts, nkte, .false.)
     endif
   end subroutine UpVel


   subroutine DownVel      (cfld,                                 &  ! CD field,4
        cids, cide, ckds, ckde, cjds, cjde,   &
        cims, cime, ckms, ckme, cjms, cjme,   &
        cits, cite, ckts, ckte, cjts, cjte,   &
        nfld,                                 &  ! ND field
        nids, nide, nkds, nkde, njds, njde,   &
        nims, nime, nkms, nkme, njms, njme,   &
        nits, nite, nkts, nkte, njts, njte,   &
        shw,                                  &  ! stencil half width for interp
        imask,                                &  ! interpolation mask
        xstag, ystag,                         &  ! staggering of field
        ipos, jpos,                           &  ! Position of lower left of nest in CD
        nri, nrj)                                ! nest ratios                         
     use module_interp_store
     use module_interp_nmm, only: c2n_copy3d, c2n_copy2d
     implicit none
     LOGICAL,INTENT(IN) :: xstag, ystag
     INTEGER,INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
          cims, cime, ckms, ckme, cjms, cjme,   &
          cits, cite, ckts, ckte, cjts, cjte,   &
          nids, nide, nkds, nkde, njds, njde,   &
          nims, nime, nkms, nkme, njms, njme,   &
          nits, nite, nkts, nkte, njts, njte,   &
          shw,ipos,jpos,nri,nrj

     INTEGER,DIMENSION(nims:nime,njms:njme),          INTENT(IN)           :: IMASK
     REAL,DIMENSION(cims:cime,cjms:cjme,ckms:ckme),   INTENT(IN)           :: CFLD
     REAL,DIMENSION(nims:nime,njms:njme,nkms:nkme),   INTENT(INOUT)          :: nfld

     if(nkts==nkte) then
        call c2n_copy2d(IIV,JJV,VBWGT1,VBWGT2,VBWGT3,VBWGT4,  &
             cfld,nfld,imask,                &
             cims, cime, cjms, cjme,   &
             nids, nide, njds, njde,   &
             nims, nime, njms, njme,   &
             nits, nite, njts, njte, .false.)
     else
        call c2n_copy3d(IIV,JJV,VBWGT1,VBWGT2,VBWGT3,VBWGT4,  &
             cfld,nfld,imask,                &
             cims, cime, cjms, cjme, ckms, ckme,   &
             nids, nide, njds, njde, nkds, nkde,   &
             nims, nime, njms, njme, nkms, nkme,   &
             nits, nite, njts, njte, nkts, nkte, .false.)
     endif
   end subroutine DownVel


   SUBROUTINE BdyMass (cfld,                                 &  ! CD field,6
        cids, cide, ckds, ckde, cjds, cjde,   &
        cims, cime, ckms, ckme, cjms, cjme,   &
        cits, cite, ckts, ckte, cjts, cjte,   &
        nfld,                                 &  ! ND field
        nids, nide, nkds, nkde, njds, njde,   &
        nims, nime, nkms, nkme, njms, njme,   &
        nits, nite, nkts, nkte, njts, njte,   &
        shw,                                  &  ! stencil half width
        imask,                                &  ! interpolation mask
        xstag, ystag,                         &  ! staggering of field
        ipos, jpos,                           &  ! Position of lower left of nest in CD
        nri, nrj,                             &  ! nest ratios
        c_bxs,n_bxs,                          &
        c_bxe,n_bxe,                          &
        c_bys,n_bys,                          &
        c_bye,n_bye,                          &
        c_btxs,n_btxs,                        &
        c_btxe,n_btxe,                        &
        c_btys,n_btys,                        &
        c_btye,n_btye,                        &
        emethod,evalue)                          ! Extrapolation information

     !     use module_state_description
     USE module_configure
     USE module_wrf_error
     use module_interp_store
     use module_interp_nmm, only: c2b_mass, c2b_copy2d

     IMPLICIT NONE
     integer, parameter :: bdyw = 1

     INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
          cims, cime, ckms, ckme, cjms, cjme,   &
          cits, cite, ckts, ckte, cjts, cjte,   &
          nids, nide, nkds, nkde, njds, njde,   &
          nims, nime, nkms, nkme, njms, njme,   &
          nits, nite, nkts, nkte, njts, njte,   &
          shw,                                  &
          ipos, jpos,                           &
          nri, nrj, emethod
     real, intent(in) :: evalue

     LOGICAL, INTENT(IN) :: xstag, ystag

     REAL, DIMENSION ( cims:cime, cjms:cjme, ckms:ckme ) :: cfld,ccwm
     REAL, DIMENSION ( nims:nime, njms:njme, nkms:nkme ) :: nfld,ncwm
     !
     INTEGER, DIMENSION ( nims:nime, njms:njme ) :: imask

     ! Output field boundary info:
     real,dimension(nims:nime,nkms:nkme,bdyw) :: n_bys,n_bye
     real,dimension(njms:njme,nkms:nkme,bdyw) :: n_bxs,n_bxe

     ! Unused parameters:
     REAL,  DIMENSION( * ), INTENT(INOUT) :: c_bxs,c_bxe,c_bys,c_bye
     REAL,  DIMENSION( * ), INTENT(INOUT) :: c_btxs,n_btxs,c_btxe,n_btxe,c_btys,n_btys,c_btye,n_btye

     if(nkts==nkte) then
        call c2b_copy2d(iih,jjh,                   &
             hbwgt1,hbwgt2,hbwgt3,hbwgt4,          &
             cfld,                                 &
             n_bxs, n_bxe, n_bys, n_bye,           &
             cims, cime, cjms, cjme,   &
             nids, nide, njds, njde,   &
             nims, nime, njms, njme,   &
             nits, nite, njts, njte,   &
             .true.)
     else
        call c2b_mass(iih,jjh,                     &
             hbwgt1,hbwgt2,hbwgt3,hbwgt4,          &
             cfld,                                 &
             iinfo_bxs,iinfo_bxe,iinfo_bys,iinfo_bye,          &
             winfo_bxs,winfo_bxe,winfo_bys,winfo_bye,          &
             n_bxs, n_bxe, n_bys, n_bye,           &
             emethod, evalue,                      &
             cims, cime, cjms, cjme, ckms, ckme,   &
             nids, nide, njds, njde, nkds, nkde,   &
             nims, nime, njms, njme, nkms, nkme,   &
             nits, nite, njts, njte, nkts, nkte)
     endif
   END SUBROUTINE BdyMass

   !
   !--------------------------------------------------------------------------------------
   !

   SUBROUTINE BdyCopy  (cfld,                                 &  ! CD field,6
        cids, cide, ckds, ckde, cjds, cjde,   &
        cims, cime, ckms, ckme, cjms, cjme,   &
        cits, cite, ckts, ckte, cjts, cjte,   &
        nfld,                                 &  ! ND field
        nids, nide, nkds, nkde, njds, njde,   &
        nims, nime, nkms, nkme, njms, njme,   &
        nits, nite, nkts, nkte, njts, njte,   &
        shw,                                  &  ! stencil half width
        imask,                                &  ! interpolation mask
        xstag, ystag,                         &  ! staggering of field
        ipos, jpos,                           &  ! Position of lower left of nest in CD
        nri, nrj,                             &  ! nest ratios
        c_bxs,n_bxs,                          &
        c_bxe,n_bxe,                          &
        c_bys,n_bys,                          &
        c_bye,n_bye,                          &
        c_btxs,n_btxs,                        &
        c_btxe,n_btxe,                        &
        c_btys,n_btys,                        &
        c_btye,n_btye)

     !     use module_state_description
     USE module_configure
     USE module_wrf_error
     use module_interp_nmm, only: c2b_copy3d, c2b_copy2d
     use module_interp_store

     IMPLICIT NONE
     integer, parameter :: bdyw = 1

     INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
          cims, cime, ckms, ckme, cjms, cjme,   &
          cits, cite, ckts, ckte, cjts, cjte,   &
          nids, nide, nkds, nkde, njds, njde,   &
          nims, nime, nkms, nkme, njms, njme,   &
          nits, nite, nkts, nkte, njts, njte,   &
          shw,                                  &
          ipos, jpos,                           &
          nri, nrj

     LOGICAL, INTENT(IN) :: xstag, ystag

     REAL, DIMENSION ( cims:cime, cjms:cjme, ckms:ckme ) :: cfld
     REAL, DIMENSION ( nims:nime, njms:njme, nkms:nkme ) :: nfld
     !
     INTEGER, DIMENSION ( nims:nime, njms:njme ) :: imask

     ! Output field boundary info:
     real,dimension(nims:nime,nkms:nkme,bdyw) :: n_bys,n_bye
     real,dimension(njms:njme,nkms:nkme,bdyw) :: n_bxs,n_bxe

     ! Nest-parent horizontal interpolation information:
     ! Unused parameters:
     REAL,  DIMENSION( * ), INTENT(INOUT) :: c_bxs,c_bxe,c_bys,c_bye
     REAL,  DIMENSION( * ), INTENT(INOUT) :: c_btxs,n_btxs,c_btxe,n_btxe,c_btys,n_btys,c_btye,n_btye

     if(nkts==nkte) then
        call c2b_copy2d(iiv,jjv,                   &
             vbwgt1,vbwgt2,vbwgt3,vbwgt4,          &
             cfld,                                 &
             n_bxs, n_bxe, n_bys, n_bye,           &
             cims, cime, cjms, cjme,   &
             nids, nide, njds, njde,   &
             nims, nime, njms, njme,   &
             nits, nite, njts, njte, .false.)
     else
        call c2b_copy3d(iih,jjh,                     &
             hbwgt1,hbwgt2,hbwgt3,hbwgt4,          &
             cfld,                                 &
             n_bxs, n_bxe, n_bys, n_bye,           &
             cims, cime, cjms, cjme, ckms, ckme,   &
             nids, nide, njds, njde, nkds, nkde,   &
             nims, nime, njms, njme, nkms, nkme,   &
             nits, nite, njts, njte, nkts, nkte, .false.)
     endif

   END SUBROUTINE BdyCopy
   !
   !--------------------------------------------------------------------------------------
   !

   subroutine NoInterp()
   end subroutine NoInterp
   !
   !--------------------------------------------------------------------------------------
   !

   SUBROUTINE BdyVel  (cfld,                                 &  ! CD field,6
        cids, cide, ckds, ckde, cjds, cjde,   &
        cims, cime, ckms, ckme, cjms, cjme,   &
        cits, cite, ckts, ckte, cjts, cjte,   &
        nfld,                                 &  ! ND field
        nids, nide, nkds, nkde, njds, njde,   &
        nims, nime, nkms, nkme, njms, njme,   &
        nits, nite, nkts, nkte, njts, njte,   &
        shw,                                  &  ! stencil half width
        imask,                                &  ! interpolation mask
        xstag, ystag,                         &  ! staggering of field
        ipos, jpos,                           &  ! Position of lower left of nest in CD
        nri, nrj,                             &  ! nest ratios
        c_bxs,n_bxs,                          &
        c_bxe,n_bxe,                          &
        c_bys,n_bys,                          &
        c_bye,n_bye,                          &
        c_btxs,n_btxs,                        &
        c_btxe,n_btxe,                        &
        c_btys,n_btys,                        &
        c_btye,n_btye)

     !     use module_state_description
     USE module_configure
     USE module_wrf_error
     use module_interp_nmm, only: c2b_copy3d, c2b_copy2d
     use module_interp_store

     IMPLICIT NONE
     integer, parameter :: bdyw = 1

     INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
          cims, cime, ckms, ckme, cjms, cjme,   &
          cits, cite, ckts, ckte, cjts, cjte,   &
          nids, nide, nkds, nkde, njds, njde,   &
          nims, nime, nkms, nkme, njms, njme,   &
          nits, nite, nkts, nkte, njts, njte,   &
          shw,                                  &
          ipos, jpos,                           &
          nri, nrj

     LOGICAL, INTENT(IN) :: xstag, ystag

     REAL, DIMENSION ( cims:cime, cjms:cjme, ckms:ckme ) :: cfld
     REAL, DIMENSION ( nims:nime, njms:njme, nkms:nkme ) :: nfld
     !
     INTEGER, DIMENSION ( nims:nime, njms:njme ) :: imask

     ! Output field boundary info:
     real,dimension(nims:nime,nkms:nkme,bdyw) :: n_bys,n_bye
     real,dimension(njms:njme,nkms:nkme,bdyw) :: n_bxs,n_bxe

     ! Nest-parent horizontal interpolation information:
     ! Unused parameters:
     REAL,  DIMENSION( * ), INTENT(INOUT) :: c_bxs,c_bxe,c_bys,c_bye
     REAL,  DIMENSION( * ), INTENT(INOUT) :: c_btxs,n_btxs,c_btxe,n_btxe,c_btys,n_btys,c_btye,n_btye

     if(nkts==nkte) then
        call c2b_copy2d(iiv,jjv,                     &
             vbwgt1,vbwgt2,vbwgt3,vbwgt4,          &
             cfld,                                 &
             n_bxs, n_bxe, n_bys, n_bye,           &
             cims, cime, cjms, cjme,   &
             nids, nide, njds, njde,   &
             nims, nime, njms, njme,   &
             nits, nite, njts, njte, .false.)
     else
        call c2b_copy3d(iiv,jjv,                     &
             vbwgt1,vbwgt2,vbwgt3,vbwgt4,          &
             cfld,                                 &
             n_bxs, n_bxe, n_bys, n_bye,           &
             cims, cime, cjms, cjme, ckms, ckme,   &
             nids, nide, njds, njde, nkds, nkde,   &
             nims, nime, njms, njme, nkms, nkme,   &
             nits, nite, njts, njte, nkts, nkte, .false.)
     endif
   END SUBROUTINE BdyVel
   !
   !--------------------------------------------------------------------------------------
   !

   SUBROUTINE BdyNear (cfld,                                 &  ! CD field,6
        cids, cide, ckds, ckde, cjds, cjde,   &
        cims, cime, ckms, ckme, cjms, cjme,   &
        cits, cite, ckts, ckte, cjts, cjte,   &
        nfld,                                 &  ! ND field
        nids, nide, nkds, nkde, njds, njde,   &
        nims, nime, nkms, nkme, njms, njme,   &
        nits, nite, nkts, nkte, njts, njte,   &
        shw,                                  &  ! stencil half width
        imask,                                &  ! interpolation mask
        xstag, ystag,                         &  ! staggering of field
        ipos, jpos,                           &  ! Position of lower left of nest in CD
        nri, nrj,                             &  ! nest ratios
        c_bxs,n_bxs,                          &
        c_bxe,n_bxe,                          &
        c_bys,n_bys,                          &
        c_bye,n_bye,                          &
        c_btxs,n_btxs,                        &
        c_btxe,n_btxe,                        &
        c_btys,n_btys,                        &
        c_btye,n_btye)

     !     use module_state_description
     USE module_configure
     USE module_wrf_error
     use module_interp_nmm, only: c2b_near2d
     use module_interp_store

     IMPLICIT NONE
     integer, parameter :: bdyw = 1

     INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
          cims, cime, ckms, ckme, cjms, cjme,   &
          cits, cite, ckts, ckte, cjts, cjte,   &
          nids, nide, nkds, nkde, njds, njde,   &
          nims, nime, nkms, nkme, njms, njme,   &
          nits, nite, nkts, nkte, njts, njte,   &
          shw,                                  &
          ipos, jpos,                           &
          nri, nrj

     LOGICAL, INTENT(IN) :: xstag, ystag

     REAL, DIMENSION ( cims:cime, cjms:cjme ) :: cfld
     REAL, DIMENSION ( nims:nime, njms:njme ) :: nfld

     INTEGER, DIMENSION ( nims:nime, njms:njme ) :: imask

     ! Output field boundary info:
     real,dimension(nims:nime,1,bdyw) :: n_bys,n_bye
     real,dimension(njms:njme,1,bdyw) :: n_bxs,n_bxe

     ! Unused parameters:
     REAL,  DIMENSION( * ), INTENT(INOUT) :: c_bxs,c_bxe,c_bys,c_bye
     REAL,  DIMENSION( * ), INTENT(INOUT) :: c_btxs,n_btxs,c_btxe,n_btxe,c_btys,n_btys,c_btye,n_btye

     if(nkts/=nkte) &
          call wrf_error_fatal('3D boundary nearest neighbor interpolation is not implemented.')
     call c2b_near2d(hnear_i,hnear_j,cfld,      &
          n_bxs, n_bxe, n_bys, n_bye,           &
          cims, cime, cjms, cjme,   &
          nids, nide, njds, njde,   &
          nims, nime, njms, njme,   &
          nits, nite, njts, njte)

   END SUBROUTINE BdyNear


   SUBROUTINE BdyINear (cfld,                                 &  ! CD field,6
        cids, cide, ckds, ckde, cjds, cjde,   &
        cims, cime, ckms, ckme, cjms, cjme,   &
        cits, cite, ckts, ckte, cjts, cjte,   &
        nfld,                                 &  ! ND field
        nids, nide, nkds, nkde, njds, njde,   &
        nims, nime, nkms, nkme, njms, njme,   &
        nits, nite, nkts, nkte, njts, njte,   &
        shw,                                  &  ! stencil half width
        imask,                                &  ! interpolation mask
        xstag, ystag,                         &  ! staggering of field
        ipos, jpos,                           &  ! Position of lower left of nest in CD
        nri, nrj,                             &  ! nest ratios
        c_bxs,n_bxs,                          &
        c_bxe,n_bxe,                          &
        c_bys,n_bys,                          &
        c_bye,n_bye,                          &
        c_btxs,n_btxs,                        &
        c_btxe,n_btxe,                        &
        c_btys,n_btys,                        &
        c_btye,n_btye)

     !     use module_state_description
     USE module_configure
     USE module_wrf_error
     use module_interp_nmm, only: c2b_inear2d
     use module_interp_store

     IMPLICIT NONE
     integer, parameter :: bdyw = 1

     INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
          cims, cime, ckms, ckme, cjms, cjme,   &
          cits, cite, ckts, ckte, cjts, cjte,   &
          nids, nide, nkds, nkde, njds, njde,   &
          nims, nime, nkms, nkme, njms, njme,   &
          nits, nite, nkts, nkte, njts, njte,   &
          shw,                                  &
          ipos, jpos,                           &
          nri, nrj

     LOGICAL, INTENT(IN) :: xstag, ystag

     INTEGER, DIMENSION ( cims:cime, cjms:cjme ) :: cfld
     INTEGER, DIMENSION ( nims:nime, njms:njme ) :: nfld

     INTEGER, DIMENSION ( nims:nime, njms:njme ) :: imask

     ! Output field boundary info:
     integer,dimension(nims:nime,1,bdyw) :: n_bys,n_bye
     integer,dimension(njms:njme,1,bdyw) :: n_bxs,n_bxe

     ! Unused parameters:
     integer,  DIMENSION( * ), INTENT(INOUT) :: c_bxs,c_bxe,c_bys,c_bye
     integer,  DIMENSION( * ), INTENT(INOUT) :: c_btxs,n_btxs,c_btxe,n_btxe,c_btys,n_btys,c_btye,n_btye

     if(nkts/=nkte) &
          call wrf_error_fatal('3D boundary nearest neighbor interpolation is not implemented.')
     call c2b_inear2d(hnear_i,hnear_j,cfld,      &
          n_bxs, n_bxe, n_bys, n_bye,           &
          cims, cime, cjms, cjme,   &
          nids, nide, njds, njde,   &
          nims, nime, njms, njme,   &
          nits, nite, njts, njte)

   END SUBROUTINE BdyINear

!--------------------------------------------------------------------------------------
! End of Sam's doing
!--------------------------------------------------------------------------------------

#endif

! Third block of ARW-specific routines
#if ! defined(NMM_CORE) || NMM_CORE!=1


   SUBROUTINE interp_mask_field ( enable,                  &  ! says whether to allow interpolation or just the bcasts,4
                                       cfld,                     &  ! CD field
                           cids, cide, ckds, ckde, cjds, cjde,   &
                           cims, cime, ckms, ckme, cjms, cjme,   &
                           cits, cite, ckts, ckte, cjts, cjte,   &
                           nfld,                                 &  ! ND field
                           nids, nide, nkds, nkde, njds, njde,   &
                           nims, nime, nkms, nkme, njms, njme,   &
                           nits, nite, nkts, nkte, njts, njte,   &
                           shw,                                  &  ! stencil half width
                           imask,                                &  ! interpolation mask
                           xstag, ystag,                         &  ! staggering of field
                           ipos, jpos,                           &  ! Position of lower left of nest in CD
                           nri, nrj,                             &  ! nest ratios
                           clu, nlu, cflag, nflag ) 

      USE module_configure
      USE module_wrf_error
      USE module_dm , only :  wrf_dm_sum_reals, wrf_dm_sum_integers

      IMPLICIT NONE


      LOGICAL, INTENT(IN) :: enable
      INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
                             cims, cime, ckms, ckme, cjms, cjme,   &
                             cits, cite, ckts, ckte, cjts, cjte,   &
                             nids, nide, nkds, nkde, njds, njde,   &
                             nims, nime, nkms, nkme, njms, njme,   &
                             nits, nite, nkts, nkte, njts, njte,   &
                             shw,                                  &  ! stencil half width
                             ipos, jpos,                           &
                             nri, nrj, cflag, nflag
      LOGICAL, INTENT(IN) :: xstag, ystag

      REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ) :: cfld
      REAL, DIMENSION ( nims:nime, nkms:nkme, njms:njme ) :: nfld
      INTEGER, DIMENSION ( nims:nime, njms:njme ) :: imask

      REAL, DIMENSION ( cims:cime, cjms:cjme ) :: clu
      REAL, DIMENSION ( nims:nime, njms:njme ) :: nlu

      ! Local

      INTEGER ci, cj, ck, ni, nj, nk, ip, jp
      INTEGER :: icount, ii , jj , ist , ien , jst , jen , iswater, ierr
      REAL :: avg, sum, dx , dy
      INTEGER :: icount_water(nkts:nkte), icount_land(nkts:nkte), idummy(nkts:nkte)
      REAL :: avg_water(nkts:nkte), avg_land(nkts:nkte), sum_water(nkts:nkte), sum_land(nkts:nkte), dummy(nkts:nkte)
      CHARACTER (len=256) :: message
      CHARACTER (len=256) :: a_mess

      !  Find out what the water value is.

      !CALL nl_get_iswater(1,iswater)
      iswater = nflag

      !  Right now, only mass point locations permitted.

      IF ( ( .NOT. xstag) .AND. ( .NOT. ystag ) ) THEN

        !  Loop over each i,k,j in the nested domain.

        IF ( enable ) THEN
          DO nj = njts, njte
            ! first coarse position equal to or below nest point
            IF ( MOD ( nrj , 2 ) .EQ. 0 ) THEN
               cj = ( nj + (nrj/2)-1 ) / nrj + jpos -1
            ELSE
               cj = ( nj + (nrj-1)/2 ) / nrj + jpos -1
            END IF
            DO nk = nkts, nkte
               ck = nk
               DO ni = nits, nite
                  IF ( imask(ni, nj) .NE. 1 ) cycle
                  ! first coarse position equal to or to the left of nest point
                  IF ( MOD ( nri , 2 ) .EQ. 0 ) THEN
                     ci = ( ni + (nri/2)-1 ) / nri + ipos -1
                  ELSE
                     ci = ( ni + (nri-1)/2 ) / nri + ipos -1
                  END IF

                  !
                  !                    (ci,cj+1)     (ci+1,cj+1)
                  !               -        -------------
                  !         1-dy  |        |           |
                  !               |        |           |
                  !               -        |  *        |
                  !          dy   |        | (ni,nj)   |
                  !               |        |           |
                  !               -        -------------
                  !                    (ci,cj)       (ci+1,cj)
                  !
                  !                        |--|--------|
                  !                         dx  1-dx

                  !  For odd ratios, at (nri+1)/2, we are on the coarse grid point, so dx = 0

                  IF ( MOD ( nri , 2 ) .EQ. 0 ) THEN
                     dx = ( REAL ( MOD ( ni+(nri-1)/2 , nri ) ) + 0.5 ) / REAL ( nri )
                  ELSE
                     dx =   REAL ( MOD ( ni+(nri-1)/2 , nri ) )         / REAL ( nri )
                  END IF
                  IF ( MOD ( nrj , 2 ) .EQ. 0 ) THEN
                     dy = ( REAL ( MOD ( nj+(nrj-1)/2 , nrj ) ) + 0.5 ) / REAL ( nrj )
                  ELSE
                     dy =   REAL ( MOD ( nj+(nrj-1)/2 , nrj ) )         / REAL ( nrj )
                  END IF

                  ! Nested cell is a water cell.
                  IF ( ( NINT(nlu(ni, nj)) .EQ. iswater ) ) THEN

                     ! If the surrounding coarse values are all WATER points,
                     ! i.e. open water, this is a simple 4-pt interpolation. 
                     ! If the surrounding coarse values are all LAND points,
                     ! i.e. this is a 1-cell lake, we have no better way to 
                     ! come up with the value than to do a simple 4-pt interpolation.

                     IF ( ALL( clu(ci:ci+1,cj:cj+1) == iswater ) .OR. &
                          ALL( clu(ci:ci+1,cj:cj+1) /= iswater ) ) THEN

                       nfld(ni,nk,nj) = ( 1. - dx ) * ( ( 1. - dy ) * cfld(ci  ,ck,cj  )   + &
                                                               dy   * cfld(ci  ,ck,cj+1) ) + &
                                               dx   * ( ( 1. - dy ) * cfld(ci+1,ck,cj  )   + &
                                                               dy   * cfld(ci+1,ck,cj+1) )

                     !  If there are some land points and some water points, take an average.
                     ELSE
                       icount = 0
                       sum = 0
                       IF ( NINT(clu(ci  ,cj  )) .EQ. iswater ) THEN
                          icount = icount + 1
                          sum = sum + cfld(ci  ,ck,cj  )
                       END IF
                       IF ( NINT(clu(ci+1,cj  )) .EQ. iswater ) THEN
                          icount = icount + 1
                          sum = sum + cfld(ci+1,ck,cj  )
                       END IF
                       IF ( NINT(clu(ci  ,cj+1)) .EQ. iswater ) THEN
                          icount = icount + 1
                          sum = sum + cfld(ci  ,ck,cj+1)
                       END IF
                       IF ( NINT(clu(ci+1,cj+1)) .EQ. iswater ) THEN
                          icount = icount + 1
                          sum = sum + cfld(ci+1,ck,cj+1)
                       END IF
                       nfld(ni,nk,nj) = sum / REAL ( icount )
                     END IF

                  ! Nested cell is a land cell.
                   ELSE IF ( ( NINT(nlu(ni, nj)) .NE. iswater ) ) THEN

                     ! If the surrounding coarse values are all LAND points,
                     ! this is a simple 4-pt interpolation. 
                     ! If the surrounding coarse values are all WATER points,
                     ! i.e. this is a 1-cell island, we have no better way to 
                     ! come up with the value than to do a simple 4-pt interpolation.

                     IF ( ALL( clu(ci:ci+1,cj:cj+1) == iswater ) .OR. &
                          ALL( clu(ci:ci+1,cj:cj+1) /= iswater ) ) THEN

                       nfld(ni,nk,nj) = ( 1. - dx ) * ( ( 1. - dy ) * cfld(ci  ,ck,cj  )   + &
                                                               dy   * cfld(ci  ,ck,cj+1) ) + &
                                               dx   * ( ( 1. - dy ) * cfld(ci+1,ck,cj  )   + &
                                                               dy   * cfld(ci+1,ck,cj+1) )

                    !  If there are some water points and some land points, take an average.                  
                    ELSE
                      icount = 0
                      sum = 0
                      IF ( NINT(clu(ci  ,cj  )) .NE. iswater ) THEN
                         icount = icount + 1
                         sum = sum + cfld(ci  ,ck,cj  )
                      END IF
                      IF ( NINT(clu(ci+1,cj  )) .NE. iswater ) THEN
                         icount = icount + 1
                         sum = sum + cfld(ci+1,ck,cj  )
                      END IF
                      IF ( NINT(clu(ci  ,cj+1)) .NE. iswater ) THEN
                         icount = icount + 1
                         sum = sum + cfld(ci  ,ck,cj+1)
                      END IF
                      IF ( NINT(clu(ci+1,cj+1)) .NE. iswater ) THEN
                         icount = icount + 1
                         sum = sum + cfld(ci+1,ck,cj+1)
                      END IF
                      nfld(ni,nk,nj) = sum / REAL ( icount )

                    END IF
                  END IF

               END DO
            END DO
          END DO

        END IF
      ELSE
         CALL wrf_error_fatal ( "only unstaggered fields right now" )
      END IF

   END SUBROUTINE interp_mask_field



   SUBROUTINE interp_mask_soil ( enable,                  &  ! says whether to allow interpolation or just the bcasts,4
                                       cfld,                     &  ! CD field
                           cids, cide, ckds, ckde, cjds, cjde,   &
                           cims, cime, ckms, ckme, cjms, cjme,   &
                           cits, cite, ckts, ckte, cjts, cjte,   &
                           nfld,                                 &  ! ND field
                           nids, nide, nkds, nkde, njds, njde,   &
                           nims, nime, nkms, nkme, njms, njme,   &
                           nits, nite, nkts, nkte, njts, njte,   &
                           shw,                                  &  ! stencil half width
                           imask,                                &  ! interpolation mask
                           xstag, ystag,                         &  ! staggering of field
                           ipos, jpos,                           &  ! Position of lower left of nest in CD
                           nri, nrj,                             &  ! nest ratios
                           clu, nlu )

      USE module_configure
      USE module_wrf_error
      USE module_dm , only : wrf_dm_sum_real, wrf_dm_sum_integer

      IMPLICIT NONE


      LOGICAL, INTENT(IN) :: enable
      INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
                             cims, cime, ckms, ckme, cjms, cjme,   &
                             cits, cite, ckts, ckte, cjts, cjte,   &
                             nids, nide, nkds, nkde, njds, njde,   &
                             nims, nime, nkms, nkme, njms, njme,   &
                             nits, nite, nkts, nkte, njts, njte,   &
                             shw,                                  &  ! stencil half width
                             ipos, jpos,                           &
                             nri, nrj
      LOGICAL, INTENT(IN) :: xstag, ystag

      INTEGER, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ) :: cfld
      INTEGER, DIMENSION ( nims:nime, nkms:nkme, njms:njme ) :: nfld
      INTEGER, DIMENSION ( nims:nime, njms:njme ) :: imask

      REAL, DIMENSION ( cims:cime, cjms:cjme ) :: clu
      REAL, DIMENSION ( nims:nime, njms:njme ) :: nlu

      ! Local

      INTEGER ci, cj, ck, ni, nj, nk, ip, jp
      INTEGER :: icount, ii , jj , ist , ien , jst , jen , iswater, num_soil_cat, ierr
      REAL :: avg, sum, dx , dy
      INTEGER , ALLOCATABLE :: icount_water(:,: ), icount_land(:,:)
      INTEGER , PARAMETER :: max_search = 5
      CHARACTER*120 message
      INTEGER, PARAMETER :: isoilwater = 14

      CALL nl_get_iswater(1,iswater)
      CALL nl_get_num_soil_cat(1,num_soil_cat)

      allocate (icount_water(nkms:nkme,1:num_soil_cat))
      allocate ( icount_land(nkms:nkme,1:num_soil_cat))

      !  Right now, only mass point locations permitted.

      IF ( ( .NOT. xstag) .AND. ( .NOT. ystag ) ) THEN

        !  Loop over each i,k,j in the nested domain.

        IF ( enable ) THEN

          DO nj = njts, njte
             cj = jpos + (nj-1) / nrj     ! j coord of CD point 
            DO nk = nkts, nkte
               ck = nk
               DO ni = nits, nite
                  ci = ipos + (ni-1) / nri      ! j coord of CD point 

                  IF ( imask(ni, nj) .NE. 1 ) cycle

                  IF ( ( NINT(nlu(ni, nj)) .EQ. iswater ) ) then

                     IF ( ( NINT(clu(ci  ,cj  )) .EQ. iswater ) ) then 
                       nfld(ni,nk,nj) = cfld(ci,ck,cj)
                     ELSE 
                       nfld(ni,nk,nj) = -1
                     ENDIF

                  ELSE IF ( ( NINT(nlu(ni, nj)) .NE. iswater ) ) THEN

                      IF ( ( NINT(clu(ci  ,cj  )) .NE. iswater ) ) THEN 
                         nfld(ni,nk,nj) = cfld(ci,ck,cj)
                      ELSE 
                         nfld(ni,nk,nj) = -1
                      ENDIF

                  END IF
               END DO
            END DO
          END DO

          DO nj = njts, njte
             DO nk = nkts, nkte
                DO ni = nits, nite
                  IF ( imask(ni, nj) .NE. 1 ) cycle
                  IF ( nfld(ni,nk,nj) .EQ. -1 ) THEN
                     IF ( NINT(nlu(ni,nj)) .EQ. iswater ) THEN 
                        nfld(ni,nk,nj) = isoilwater
                     END IF
                  END IF
               END DO
             END DO
          END DO
#if 0
          IF ( ANY(nfld .EQ. -1) ) THEN

            !  Get an average of the whole domain for problem locations.

            sum_water    = 0
            icount_water = 0
            sum_land     = 0
            icount_land  = 0
            avg_water    = 0
            avg_land     = 0
           
            DO nj = njts, njte
               cj = jpos + (nj-1) / nrj     ! j coord of CD point 
               DO nk = nkts, nkte
                  DO ni = nits, nite
                     ci = ipos + (ni-1) / nri      ! j coord of CD point 
                     IF ( imask(ni, nj) .NE. 1 ) cycle
                     IF ( nfld(ni,nk,nj) .EQ. -1 ) THEN
                        ist = MAX (ci-max_search,cits)
                        ien = MIN (ci+max_search,cite,cide-1)
                        jst = MAX (cj-max_search,cjts)
                        jen = MIN (cj+max_search,cjte,cjde-1)
                        DO jj = jst,jen
                           DO ii = ist,ien
                              IF ( NINT(clu(ii,jj)) .NE. iswater ) THEN
                                 icount_land(nk,cfld(ii,nk,jj)) = icount_land(nk,cfld(ii,nk,jj)) +1
                              END IF
                           END DO
                        END DO
                        IF ( maxval(icount_land(nk,:)) .GT. 0 .and. maxloc(icount_land(nk,:)) .ne. isoilwater ) then
                            nfld(ni,nk,nj) = maxloc(icount_land(nk,:))
                        END IF
                     END IF
                  END DO
               END DO
            END DO

          END IF ! nfld = -1


          IF ( ANY(nfld .EQ. -1) ) THEN
            sum_water    = 0
            icount_water = 0
            sum_land     = 0
            icount_land  = 0
            avg_water    = 0
            avg_land     = 0

            DO nj = njts, njte
               DO nk = nkts, nkte
                  DO ni = nits, nite
                     IF ( nlu(ni,nj ) .NE. iswater ) THEN
                        icount_land(nk,nfld(ni,nk,nj)) = icount_land(nk,nfld(ni,nk,nj)) +1
                     END IF
                  ENDDO
               ENDDO
            ENDDO

            DO nj = njts, njte
               DO nk = nkts, nkte
                  DO ni = nits, nite
                     IF ( imask(ni, nj) .NE. 1 ) cycle
                     IF ( nfld(ni,nk,nj) .EQ. -1 .and. maxloc(icount_land(nk,:)) .ne. isoilwater) THEN
                        nfld(ni,nk,nj) = MAXLOC(icount_land(nk,:))
                     END IF
                  ENDDO
               ENDDO
            ENDDO
          END IF ! nfld = -1
#endif

          IF ( ANY(nfld .EQ. -1) ) THEN
            DO nj = njts, njte
               DO nk = nkts, nkte
                  DO ni = nits, nite
                     IF ( imask(ni, nj) .NE. 1 ) cycle
                     IF ( nfld(ni,nk,nj) .EQ. -1 ) THEN
                        nfld(ni,nk,nj) = 8
                     END IF
                  ENDDO
               ENDDO
            ENDDO
          END IF ! nfld = -1

        END IF  ! enable
      ELSE
         CALL wrf_error_fatal ( "only unstaggered fields right now" )
      END IF


      deallocate (icount_water)
      deallocate (icount_land)

   END SUBROUTINE interp_mask_soil
 
!=========================================================================

! Lagrange interpolating polynomials, set up as a quadratic, with an average of
! the overlap.  Specifically for longitude near the date line.


   SUBROUTINE interp_fcn_lagr_ll ( cfld_inp,                          &  ! CD field,1
                                cids, cide, ckds, ckde, cjds, cjde,   &
                                cims, cime, ckms, ckme, cjms, cjme,   &
                                cits, cite, ckts, ckte, cjts, cjte,   &
                                nfld,                                 &  ! ND field
                                nids, nide, nkds, nkde, njds, njde,   &
                                nims, nime, nkms, nkme, njms, njme,   &
                                nits, nite, nkts, nkte, njts, njte,   &
                                shw,                                  &  !  stencil half width for interp
                                imask,                                &  !  interpolation mask
                                xstag, ystag,                         &  !  staggering of field
                                ipos, jpos,                           &  !  Position of lower left of nest in CD
                                nri, nrj,                             & ! Nest ratio, i- and j-directions
                                clat_in, nlat_in,                     & ! CG, FG latitude
                                cinput_from_file, ninput_from_file )    ! CG, FG T/F input from file

     IMPLICIT NONE

     INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde,   &
                            cims, cime, ckms, ckme, cjms, cjme,   &
                            cits, cite, ckts, ckte, cjts, cjte,   &
                            nids, nide, nkds, nkde, njds, njde,   &
                            nims, nime, nkms, nkme, njms, njme,   &
                            nits, nite, nkts, nkte, njts, njte,   &
                            shw,                                  &
                            ipos, jpos,                           &
                            nri, nrj
     LOGICAL, INTENT(IN) :: xstag, ystag

     REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ) :: cfld_inp, cfld
     REAL, DIMENSION ( nims:nime, nkms:nkme, njms:njme ) :: nfld
     REAL, DIMENSION ( cims:cime,            cjms:cjme ) :: clat_in
     REAL, DIMENSION ( nims:nime,            njms:njme ) :: nlat_in
     INTEGER, DIMENSION ( nims:nime, njms:njme ) :: imask
     LOGICAL :: cinput_from_file, ninput_from_file

     ! Local

     INTEGER ci, cj, ck, ni, nj, nk, istag, jstag, i, j, k
     REAL :: nx, x0, x1, x2, x3, x
     REAL :: ny, y0, y1, y2, y3
     REAL :: cxm1, cxp0, cxp1, cxp2, nfld_m1, nfld_p0, nfld_p1, nfld_p2
     REAL :: cym1, cyp0, cyp1, cyp2
     INTEGER :: ioff, joff
     LOGICAL :: probably_by_dateline
     REAL :: max_lon, min_lon
     LOGICAL :: probably_by_pole
     REAL :: max_lat, min_lat

     !  Fortran functions.

     REAL, EXTERNAL :: lagrange_quad_avg
     REAL, EXTERNAL :: nest_loc_of_cg
     INTEGER, EXTERNAL :: compute_CGLL

     !  This stag stuff is to keep us away from the outer most row
     !  and column for the unstaggered directions.  We are going to 
     !  consider "U" an xstag variable and "V" a ystag variable.  The
     !  vertical staggering is handled in the actual arguments.  The
     !  ckte and nkte are the ending vertical dimensions for computations
     !  for this particular variable.

     !  The ioff and joff are offsets due to the staggering.  It is a lot
     !  simpler with ioff and joff if 
     !  u var => ioff=1
     !  v var => joff=1
     !  otherwise zero.
     !  Note that is OPPOSITE of the istag, jstag vars.  The stag variables are
     !  used for the domain dimensions, the offset guys are used in the 
     !  determination of grid points between the CG and FG

     IF ( xstag ) THEN
        istag = 0 
        ioff  = 1
     ELSE
        istag = 1
        ioff  = 0
     END IF

     IF ( ystag ) THEN
        jstag = 0 
        joff  = 1
     ELSE
        jstag = 1
        joff  = 0
     END IF

     !  If this is a projection where the nest is over the pole, and
     !  we are using the parent to interpolate the longitudes, then 
     !  we are going to have longitude troubles.  If this is the case,
     !  stop the model right away.

     probably_by_pole = .FALSE.
     max_lat = -90
     min_lat = +90
     DO nj = njts, MIN(njde-jstag,njte)
        DO ni = nits, MIN(nide-istag,nite)
           max_lat = MAX ( nlat_in(ni,nj) , max_lat )       
           min_lat = MIN ( nlat_in(ni,nj) , min_lat )       
        END DO
     END DO

     IF ( ( max_lat .GT. 85 ) .OR. ( ABS(min_lat) .GT. 85 ) ) THEN
        probably_by_pole = .TRUE.
     END IF

     IF ( ( probably_by_pole ) .AND. ( .NOT. ninput_from_file ) ) THEN
        CALL wrf_error_fatal ( 'Nest over the pole, single input domain, longitudes will be wrong' )
     END IF

     !  Initialize to NOT being by dateline.

     probably_by_dateline = .FALSE.
     max_lon = -180
     min_lon = +180
     DO nj = njts, MIN(njde-jstag,njte)
        cj = compute_CGLL ( nj , jpos , nrj , jstag )
        DO ni = nits, MIN(nide-istag,nite)
           ci = compute_CGLL ( ni , ipos , nri , istag )
           max_lon = MAX ( cfld_inp(ci,1,cj) , max_lon )       
           min_lon = MIN ( cfld_inp(ci,1,cj) , min_lon )       
        END DO
     END DO

     IF ( max_lon - min_lon .GT. 300 ) THEN
        probably_by_dateline = .TRUE.
     END IF

     !  Load "continuous" longitude across the date line

     DO cj = MIN(cjts-1,cjms), MAX(cjte+1,cjme)
       DO ci = MIN(cits-1,cims), MAX(cite+1,cime)
         IF ( ( cfld_inp(ci,ckts,cj) .LT. 0 ) .AND. ( probably_by_dateline ) ) THEN
           cfld(ci,ckts,cj) = 360 + cfld_inp(ci,ckts,cj)
         ELSE
           cfld(ci,ckts,cj) =       cfld_inp(ci,ckts,cj)
         END IF
       END DO
     END DO

     !  Loop over each j-index on this tile for the nested domain.

     j_loop : DO nj = njts, MIN(njde-jstag,njte)

        !  This is the lower-left j-index of the CG.

        !  Example is 3:1 ratio, mass-point staggering.  We have listed sixteen CG values
        !  as an example: A through P.  For a 3:1 ratio, each of these CG cells has
        !  nine associated FG points.

        !  |=========|=========|=========|=========|
        !  | -  -  - | -  -  - | -  -  - | -  -  - |
        !  |         |         |         |         |
        !  | -  M  - | -  N  d | -  O  - | -  P  - |
        !  |         |         |         |         |
        !  | -  -  - | -  -  - | -  -  - | -  -  - |
        !  |=========|=========|=========|=========|
        !  | -  -  - | -  -  - | -  -  - | -  -  - |
        !  |         |         |         |         |
        !  | -  I  - | -  J  c | -  K  - | -  L  - |
        !  |         |         |         |         |
        !  | -  -  - | -  -  - | -  -  - | -  -  - |
        !  |=========|=========|=========|=========|
        !  | -  1  2 | 3  4  5 | 6  7  8 | -  -  - |
        !  |         |         |         |         |
        !  | -  E  - | -  F  b | -  G  - | -  H  - |
        !  |         |         |         |         |
        !  | -  -  - | -  -  - | -  -  - | -  -  - |
        !  |=========|=========|=========|=========|
        !  | -  -  - | -  -  - | -  -  - | -  -  - |
        !  |         |         |         |         |
        !  | -  A  - | -  B  a | -  C  - | -  D  - |
        !  |         |         |         |         |
        !  | -  -  - | -  -  - | -  -  - | -  -  - |
        !  |=========|=========|=========|=========|

        !  To interpolate to FG point 4, 5, or 6 we will use CG points: A through P.  It is
        !  sufficient to find the lower left corner of a 4-point interpolation, and then extend 
        !  each side by one unit.

        !  Here are the lower left hand corners of the following FG points:
        !  1 => E
        !  2 => E
        !  3 => E
        !  4 => F
        !  5 => F
        !  6 => F
        !  7 => G
        !  8 => G

        cj = compute_CGLL ( nj , jpos , nrj , jstag )

        !  Vertical dim of the nest domain.

        k_loop : DO nk = nkts, nkte

          !  Loop over each i-index on this tile for the nested domain.

           i_loop : DO ni = nits, MIN(nide-istag,nite)
 
              !  The coarse grid location that is to the lower left of the FG point.

              ci = compute_CGLL ( ni , ipos , nri , istag )

              !  To interpolate to point "*" (look in grid cell "F"):
              !  1. Use ABC to get a quadratic valid at "a"
              !     Use BCD to get a quadratic valid at "a"
              !     Average these to get the final value for "a"
              !  2. Use EFG to get a quadratic valid at "b"
              !     Use FGH to get a quadratic valid at "b"
              !     Average these to get the final value for "b"
              !  3. Use IJK to get a quadratic valid at "c"
              !     Use JKL to get a quadratic valid at "c"
              !     Average these to get the final value for "c"
              !  4. Use MNO to get a quadratic valid at "d"
              !     Use NOP to get a quadratic valid at "d"
              !     Average these to get the final value for "d"
              !  5. Use abc to get a quadratic valid at "*"
              !     Use bcd to get a quadratic valid at "*"
              !     Average these to get the final value for "*"

              !  |=========|=========|=========|=========|
              !  | -  -  - | -  -  - | -  -  - | -  -  - |
              !  |         |         |         |         |
              !  | -  M  - | -  N  d | -  O  - | -  P  - |
              !  |         |         |         |         |
              !  | -  -  - | -  -  - | -  -  - | -  -  - |
              !  |=========|=========|=========|=========|
              !  | -  -  - | -  -  - | -  -  - | -  -  - |
              !  |         |         |         |         |
              !  | -  I  - | -  J  c | -  K  - | -  L  - |
              !  |         |         |         |         |
              !  | -  -  - | -  -  - | -  -  - | -  -  - |
              !  |=========|=========|=========|=========|
              !  | -  -  - | -  -  * | -  -  - | -  -  - |
              !  |         |         |         |         |
              !  | -  E  - | -  F  b | -  G  - | -  H  - |
              !  |         |         |         |         |
              !  | -  -  - | -  -  - | -  -  - | -  -  - |
              !  |=========|=========|=========|=========|
              !  | -  -  - | -  -  - | -  -  - | -  -  - |
              !  |         |         |         |         |
              !  | -  A  - | -  B  a | -  C  - | -  D  - |
              !  |         |         |         |         |
              !  | -  -  - | -  -  - | -  -  - | -  -  - |
              !  |=========|=========|=========|=========|

              !  Overlapping quadratic interpolation.

              IF ( imask ( ni, nj ) .EQ. 1 ) THEN

                 !  I-direction location of "*"

                 nx = REAL(ni)

                 !  I-direction location of "A", "E", "I", "M"

                 cxm1 = nest_loc_of_cg ( ci-1 , ipos , nri , ioff ) 

                 !  I-direction location of "B", "F", "J", "N"

                 cxp0 = nest_loc_of_cg ( ci   , ipos , nri , ioff ) 

                 !  I-direction location of "C", "G", "K", "O"

                 cxp1 = nest_loc_of_cg ( ci+1 , ipos , nri , ioff ) 

                 !  I-direction location of "D", "H", "L", "P"

                 cxp2 = nest_loc_of_cg ( ci+2 , ipos , nri , ioff ) 

                 !  Value at "a"

                 nfld_m1 = lagrange_quad_avg ( nx, cxm1, cxp0, cxp1, cxp2, &
                                               cfld(ci-1,nk,cj-1), cfld(ci+0,nk,cj-1), &
                                               cfld(ci+1,nk,cj-1), cfld(ci+2,nk,cj-1) )

                 !  Value at "b"

                 nfld_p0 = lagrange_quad_avg ( nx, cxm1, cxp0, cxp1, cxp2,  &
                                               cfld(ci-1,nk,cj+0), cfld(ci+0,nk,cj+0), &
                                               cfld(ci+1,nk,cj+0), cfld(ci+2,nk,cj+0) )

                 !  Value at "c"

                 nfld_p1 = lagrange_quad_avg ( nx, cxm1, cxp0, cxp1, cxp2,  &
                                               cfld(ci-1,nk,cj+1), cfld(ci+0,nk,cj+1), &
                                               cfld(ci+1,nk,cj+1), cfld(ci+2,nk,cj+1) )

                 !  Value at "d"

                 nfld_p2 = lagrange_quad_avg ( nx, cxm1, cxp0, cxp1, cxp2,  &
                                               cfld(ci-1,nk,cj+2), cfld(ci+0,nk,cj+2), &
                                               cfld(ci+1,nk,cj+2), cfld(ci+2,nk,cj+2) )

                 !  J-direction location of "*"

                ny = REAL(nj)

                 !  J-direction location of "A", "B", "C", "D"

                 cym1 = nest_loc_of_cg ( cj-1 , jpos , nrj , joff ) 

                 !  J-direction location of "E", "F", "G", "H" 

                 cyp0 = nest_loc_of_cg ( cj   , jpos , nrj , joff ) 

                 !  J-direction location of "I", "J", "K", "L"

                cyp1 = nest_loc_of_cg ( cj+1 , jpos , nrj , joff ) 

                 !  J-direction location of "M", "N", "O", "P"

                 cyp2 = nest_loc_of_cg ( cj+2 , jpos , nrj , joff ) 

                 !  Value at "*"

                 nfld(ni,nk,nj) = lagrange_quad_avg ( ny, cym1, cyp0, cyp1,  &
                                                      cyp2, nfld_m1, nfld_p0, nfld_p1, nfld_p2 )

             END IF

           END DO i_loop
        END DO    k_loop
     END DO       j_loop

     !  Put nested longitude back into the -180 to 180 range.

     DO nj = njts, MIN(njde-jstag,njte)
        DO ni = nits, MIN(nide-istag,nite)
           IF ( nfld(ni,nkts,nj) .GT. 180 ) THEN
              nfld(ni,nkts,nj) = -360 + nfld(ni,nkts,nj)
           END IF
        END DO
    END DO

   END SUBROUTINE interp_fcn_lagr_ll
#endif 
! End of third block of ARW-only routines