ESMF_XGridCreateFromSparseMat Function

public function ESMF_XGridCreateFromSparseMat(keywordEnforcer, sideAGrid, sideAMesh, sideBGrid, sideBMesh, sideAGridPriority, sideAMeshPriority, sideBGridPriority, sideBMeshPriority, sparseMatA2X, sparseMatX2A, sparseMatB2X, sparseMatX2B, area, centroid, name, rc)

Arguments

Type IntentOptional Attributes Name
type(ESMF_KeywordEnforcer), optional :: keywordEnforcer
type(ESMF_Grid), intent(in), optional :: sideAGrid(:)
type(ESMF_Mesh), intent(in), optional :: sideAMesh(:)
type(ESMF_Grid), intent(in), optional :: sideBGrid(:)
type(ESMF_Mesh), intent(in), optional :: sideBMesh(:)
integer, intent(in), optional :: sideAGridPriority(:)
integer, intent(in), optional :: sideAMeshPriority(:)
integer, intent(in), optional :: sideBGridPriority(:)
integer, intent(in), optional :: sideBMeshPriority(:)
type(ESMF_XGridSpec), intent(in), optional :: sparseMatA2X(:)
type(ESMF_XGridSpec), intent(in), optional :: sparseMatX2A(:)
type(ESMF_XGridSpec), intent(in), optional :: sparseMatB2X(:)
type(ESMF_XGridSpec), intent(in), optional :: sparseMatX2B(:)
real(kind=ESMF_KIND_R8), intent(in), optional :: area(:)
real(kind=ESMF_KIND_R8), intent(in), optional :: centroid(:,:)
character(len=*), intent(in), optional :: name
integer, intent(out), optional :: rc

Return Value type(ESMF_XGrid)


Source Code

function ESMF_XGridCreateFromSparseMat(keywordEnforcer, &
    sideAGrid,              sideAMesh, &
    sideBGrid,              sideBMesh, &
    sideAGridPriority,      sideAMeshPriority, &
    sideBGridPriority,      sideBMeshPriority, &
    sparseMatA2X, sparseMatX2A, sparseMatB2X, sparseMatX2B, &
    area, centroid, &
    name, &
    rc) 

!
! !RETURN VALUE:
    type(ESMF_XGrid) :: ESMF_XGridCreateFromSparseMat
!
! !ARGUMENTS:
type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below
type(ESMF_Grid),      intent(in), optional :: sideAGrid(:)
type(ESMF_Mesh),      intent(in), optional :: sideAMesh(:)
type(ESMF_Grid),      intent(in), optional :: sideBGrid(:)
type(ESMF_Mesh),      intent(in), optional :: sideBMesh(:)
integer,              intent(in), optional :: sideAGridPriority(:)
integer,              intent(in), optional :: sideAMeshPriority(:)
integer,              intent(in), optional :: sideBGridPriority(:)
integer,              intent(in), optional :: sideBMeshPriority(:)
type(ESMF_XGridSpec), intent(in), optional :: sparseMatA2X(:)
type(ESMF_XGridSpec), intent(in), optional :: sparseMatX2A(:)
type(ESMF_XGridSpec), intent(in), optional :: sparseMatB2X(:)
type(ESMF_XGridSpec), intent(in), optional :: sparseMatX2B(:)
real(ESMF_KIND_R8),   intent(in), optional :: area(:)
real(ESMF_KIND_R8),   intent(in), optional :: centroid(:,:)
character (len=*),    intent(in), optional :: name
integer,              intent(out),optional :: rc 

!
! !DESCRIPTION:
!      Create an XGrid directly from user supplied sparse matrix parameters. User
!      is responsible to supply all information necessary for communication calculation. 
!      For an example and associated documentation using this method see section 
!      \ref{sec:xgrid:usage:xgrid_createfromsparsemat}
!
!     The arguments are:
!     \begin{description}
!     \item [{[sideAGrid]}]
!           Parametric 2D Grids on side A, for example, 
!           these Grids can be either Cartesian 2D or Spherical.
!     \item [{[sideAMesh]}]
!           Parametric 2D Meshes on side A, for example, 
!           these Meshes can be either Cartesian 2D or Spherical.
!     \item [{[sideBGrid]}]
!           Parametric 2D Grids on side B, for example, 
!           these Grids can be either Cartesian 2D or Spherical.
!     \item [{[sideBMesh]}]
!           Parametric 2D Meshes on side B, for example, 
!           these Meshes can be either Cartesian 2D or Spherical.
!     \item [{[sideAGridPriority]}]
!           Priority array of Grids on sideA during overlay generation.
!           The {\tt sideAGridPriority} array should be the same size as the {\tt sideAGrid} array. The values
!           in the array should range from 1 to size(sideAGrid)+size(sideAMesh). A Grid whose corresponding
!           value in this array is lower than another side A Grid or Mesh, will take precedence over that Grid or Mesh
!           during side A merging. In other words, if both have parts in the same region, then the object with the lower value will win, and
!           the other Grid or Mesh part will be clipped away.
!     \item [{[sideAMeshPriority]}]
!           Priority array of Meshes on sideA during overlay generation.
!           The {\tt sideAMeshPriority} array should be the same size as the {\tt sideAMesh} array. The values
!           in the array should range from 1 to size(sideAGrid)+size(sideAMesh). A Mesh whose corresponding
!           value in this array is lower than another side A Grid or Mesh, will take precedence over that Grid or Mesh
!           during side A merging. In other words, if both have parts in the same region, then the object with the lower value will win, and
!           the other Grid or Mesh part will be clipped away.
!     \item [{[sideBGridPriority]}]
!           Priority array of Grids on sideB during overlay generation.
!           The {\tt sideBGridPriority} array should be the same size as the {\tt sideBGrid} array. The values
!           in the array should range from 1 to size(sideBGrid)+size(sideBMesh). A Grid whose corresponding
!           value in this array is lower than another side B Grid or Mesh, will take precedence over that Grid or Mesh
!           during side B merging. In other words, if both have parts in the same region, then the object with the lower value will win, and
!           the other Grid or Mesh part will be clipped away.
!     \item [{[sideBMeshPriority]}]
!           Priority array of Meshes on sideB during overlay generation.
!           The {\tt sideBMeshPriority} array should be the same size as the {\tt sideBMesh} array. The values
!           in the array should range from 1 to size(sideBGrid)+size(sideBMesh). A Mesh whose corresponding
!           value in this array is lower than another side B Grid or Mesh, will take precedence over that Grid or Mesh
!           during side B merging. In other words, if both have parts in the same region, then the object with the lower value will win, and
!           the other Grid or Mesh part will be clipped away.
!     \item [{[sparseMatA2X]}]
!           indexlist from a Grid index space on side A to xgrid index space;
!           indexFactorlist from a Grid index space on side A to xgrid index space.
!     \item [{[sparseMatX2A]}]
!           indexlist from xgrid index space to a Grid index space on side A;
!           indexFactorlist from xgrid index space to a Grid index space on side A.
!     \item [{[sparseMatB2X]}]
!           indexlist from a Grid index space on side B to xgrid index space;
!           indexFactorlist from a Grid index space on side B to xgrid index space.
!     \item [{[sparseMatX2B]}]
!           indexlist from xgrid index space to a Grid index space on side B;
!           indexFactorlist from xgrid index space to a Grid index space on side B.
!     \item [{[area]}]
!           area of the xgrid cells.
!     \item [{[centroid]}]
!           coordinates at the area weighted center of the xgrid cells.
!     \item [{[name]}]
!           name of the xgrid object.
!     \item [{[rc]}]
!           Return code; equals {\tt ESMF\_SUCCESS} only if the {\tt ESMF\_XGrid} 
!           is created.
!     \end{description}
!
!EOP

    integer :: localrc, ngrid_a, ngrid_b
    integer :: i, j, ncells, ndim
    type(ESMF_XGridType), pointer :: xgtype

    ! Initialize
    localrc = ESMF_RC_NOT_IMPL

    ! Initialize return code   
    if(present(rc)) rc = ESMF_RC_NOT_IMPL

    ! check there are enough input to create the XGrid
    if(.not. present(sideAGrid) .and. .not. present(sideAMesh)) then
      call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & 
         msg="- Either Grid or Mesh must be provided on sideA", &
         ESMF_CONTEXT, rcToReturn=rc) 
      return
    endif
    if(.not. present(sideBGrid) .and. .not. present(sideBMesh)) then
      call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & 
         msg="- Either Grid or Mesh must be provided on sideB", &
         ESMF_CONTEXT, rcToReturn=rc) 
      return
    endif

    if(present(sideAGrid) .and. present(sideAMesh)) then
      if(size(sideAGrid, 1)+size(sideAMesh, 1) .le. 0) then
        call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & 
           msg="- Either Grid or Mesh must be provided on sideA", &
           ESMF_CONTEXT, rcToReturn=rc) 
        return
      endif
    endif

    if(present(sideBGrid) .and. present(sideBMesh)) then
      if(size(sideBGrid, 1)+size(sideBMesh, 1) .le. 0) then
        call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & 
           msg="- Either Grid or Mesh must be provided on sideB", &
           ESMF_CONTEXT, rcToReturn=rc) 
        return
      endif
    endif

    ! check init status of input Grids
    if(present(sideAGrid)) then
      ngrid_a = size(sideAGrid, 1)
      do i = 1, ngrid_a
          ESMF_INIT_CHECK_DEEP(ESMF_GridGetInit,sideAGrid(i),rc)
      enddo

      ! No need to check grid for offline xgrid creation, assume user know what they are doing!
      !do i = 1, ngrid_a
      !  call checkGrid(sideAGrid(i), ESMF_STAGGERLOC_CORNER, rc=localrc)
      !  if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
      !      ESMF_CONTEXT, rcToReturn=rc)) return
      !enddo

      if(present(sideAGridPriority)) then
        if(size(sideAGridPriority, 1) /= ngrid_a) then
          call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & 
             msg="- Size of sideAGridPriority does not match size of sideAGrid", &
             ESMF_CONTEXT, rcToReturn=rc) 
          return
        endif
      endif
    endif

    if(present(sideBGrid)) then
      ngrid_b = size(sideBGrid, 1)
      do i = 1, ngrid_b
          ESMF_INIT_CHECK_DEEP(ESMF_GridGetInit,sideBGrid(i),rc)
      enddo
      ! No need to check grid for offline xgrid creation, assume user know what they are doing!
      !do i = 1, ngrid_b
      !  call checkGrid(sideBGrid(i), ESMF_STAGGERLOC_CORNER, rc=localrc)
      !  if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
      !      ESMF_CONTEXT, rcToReturn=rc)) return
      !enddo
      if(present(sideBGridPriority)) then
        if(size(sideBGridPriority, 1) /= ngrid_a) then
          call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & 
             msg="- Size of sideBGridPriority does not match size of sideBGrid", &
             ESMF_CONTEXT, rcToReturn=rc) 
          return
        endif
      endif
    endif

    !TODO: need to check Meshes too.
    if(present(sideAMesh)) then
      ngrid_a = size(sideAMesh, 1)
      if(present(sideAMeshPriority)) then
        if(size(sideAMeshPriority, 1) /= ngrid_a) then
          call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & 
             msg="- Size of sideAMeshPriority does not match size of sideAMesh", &
             ESMF_CONTEXT, rcToReturn=rc) 
          return
        endif
      endif
    endif
    if(present(sideBMesh)) then
      ngrid_b = size(sideBMesh, 1)
      if(present(sideBMeshPriority)) then
        if(size(sideBMeshPriority, 1) /= ngrid_b) then
          call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & 
             msg="- Size of sideBMeshPriority does not match size of sideBMesh", &
             ESMF_CONTEXT, rcToReturn=rc) 
          return
        endif
      endif
    endif

    ! Priority for Grid and Mesh must all be present simultaneously
    if( (present(sideAGridPriority) .and. .not. present(sideAGrid)) .or. &
         present(sideAMeshPriority) .and. .not. present(sideAMesh)  .or. &
         present(sideBGridPriority) .and. .not. present(sideBGrid)  .or. &
         present(sideBMeshPriority) .and. .not. present(sideBMesh)) then

      call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & 
         msg="- Cannot specify Grid or Mesh Priority without actual list of Grids or Meshes", &
         ESMF_CONTEXT, rcToReturn=rc) 
      return
    endif

    ! Make sure that the input objects have a consisent coordSys
    call error_check_coordsys(sideAGrid, sideAMesh, sideBGrid, sideBMesh, rc=localrc)
    if (ESMF_LogFoundError(localrc, &
         ESMF_ERR_PASSTHRU, &
         ESMF_CONTEXT, rcToReturn=rc)) return


    ! At this point the inputs are consistently sized.
    ! Take care of ordering
    ngrid_a = 0
    if(present(sideAGrid)) ngrid_a = size(sideAGrid, 1)
    if(present(sideAMesh)) ngrid_a = ngrid_a + size(sideAMesh, 1)
    ngrid_b = 0
    if(present(sideBGrid)) ngrid_b = size(sideBGrid, 1)
    if(present(sideBMesh)) ngrid_b = ngrid_b + size(sideBMesh, 1)

    ! do some range checking on priority lists
    if(present(sideAGridPriority) .and. present(sideAMeshPriority)) then
      do i = 1, size(sideAGridPriority, 1)
        if(sideAGridPriority(i) .le. 0 .or. sideAGridPriority(i) .gt. ngrid_a) then
          call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & 
             msg="- sideAGridPriority value out of range", &
             ESMF_CONTEXT, rcToReturn=rc) 
          return
        endif
      enddo
      do i = 1, size(sideAMeshPriority, 1)
        if(sideAMeshPriority(i) .le. 0 .or. sideAMeshPriority(i) .gt. ngrid_a) then
          call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & 
             msg="- sideAMeshPriority value out of range", &
             ESMF_CONTEXT, rcToReturn=rc) 
          return
        endif
      enddo

      do i = 1, size(sideAGridPriority, 1)
        do j = 1, size(sideAMeshPriority, 1)
          if(sideAGridPriority(i) == sideAMeshPriority(j)) then
            call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & 
               msg="- sideAGridPriority and sideAMeshPriority cannot have duplicate entry", &
               ESMF_CONTEXT, rcToReturn=rc) 
            return
          endif
        enddo
      enddo
    endif

    if(present(sideBGridPriority) .and. present(sideBMeshPriority)) then
      do i = 1, size(sideBGridPriority, 1)
        if(sideBGridPriority(i) .le. 0 .or. sideBGridPriority(i) .gt. ngrid_b) then
          call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & 
             msg="- sideBGridPriority value out of range", &
             ESMF_CONTEXT, rcToReturn=rc) 
          return
        endif
      enddo
      do i = 1, size(sideBMeshPriority, 1)
        if(sideBMeshPriority(i) .le. 0 .or. sideBMeshPriority(i) .gt. ngrid_b) then
          call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & 
             msg="- sideBMeshPriority value out of range", &
             ESMF_CONTEXT, rcToReturn=rc) 
          return
        endif
      enddo

      do i = 1, size(sideBGridPriority, 1)
        do j = 1, size(sideBMeshPriority, 1)
          if(sideBGridPriority(i) == sideBMeshPriority(j)) then
            call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & 
               msg="- sideBGridPriority and sideBMeshPriority cannot have duplicate entry", &
               ESMF_CONTEXT, rcToReturn=rc) 
            return
          endif
        enddo
      enddo
    endif

    if(.not. present(sparseMatA2X) .and. &
      (.not. present(sparseMatX2A)).and. &
      (.not. present(sparseMatB2X)).and. &
      (.not. present(sparseMatX2B))) then
        call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & 
           msg="- One of the sparseMat must be set to generate an XGrid", &
           ESMF_CONTEXT, rcToReturn=rc) 
        return
    endif

    ! initialize XGridType object and its base object
    nullify(xgtype)
    nullify(ESMF_XGridCreateFromSparseMat%xgtypep)
    call ESMF_XGridConstructBaseObj(xgtype, name, localrc)
    if (ESMF_LogFoundAllocError(localrc, &
      msg="Constructing xgtype base object ", &
      ESMF_CONTEXT, rcToReturn=rc)) return

    ! Choose a default coordSys for XGrid
    ! TODO: eventually also allow a user to pass one in
    call choose_default_coordsys(sideAGrid, sideAMesh, sideBGrid, sideBMesh, xgtype%coordSys, rc=localrc)
    if (ESMF_LogFoundError(localrc, &
         ESMF_ERR_PASSTHRU, &
         ESMF_CONTEXT, rcToReturn=rc)) return

    allocate(xgtype%sideA(ngrid_a), xgtype%sideB(ngrid_b), stat=localrc)
    if (ESMF_LogFoundAllocError(localrc, &
        msg="- Allocating xgtype%sideA or xgtype%sideB ", &
        ESMF_CONTEXT, rcToReturn=rc)) return

    ! Need to initialize xgtype%sideA based on sideAGrid and/or sideAMesh
    if(present(sideAGrid)) then
      if(present(sideAGridPriority)) then
        do i = 1, size(sideAGrid, 1)
          xgtype%sideA(sideAGridPriority(i)) = ESMF_XGridGeomBaseCreate(sideAGrid(i), &
            ESMF_STAGGERLOC_CENTER, rc=localrc)
          if (ESMF_LogFoundError(localrc, &
              ESMF_ERR_PASSTHRU, &
              ESMF_CONTEXT, rcToReturn=rc)) return
        enddo
      else
        do i = 1, size(sideAGrid, 1)
          xgtype%sideA(i) = ESMF_XGridGeomBaseCreate(sideAGrid(i), &
            ESMF_STAGGERLOC_CENTER, rc=localrc)
          if (ESMF_LogFoundError(localrc, &
              ESMF_ERR_PASSTHRU, &
              ESMF_CONTEXT, rcToReturn=rc)) return
        enddo
      endif

      if(present(sideAMesh)) then
        if(present(sideAMeshPriority)) then
          do i = 1, size(sideAMesh, 1)
            xgtype%sideA(sideAMeshPriority(i)) = ESMF_XGridGeomBaseCreate(sideAMesh(i), &
              ESMF_MESHLOC_ELEMENT, rc=localrc)
            if (ESMF_LogFoundError(localrc, &
                ESMF_ERR_PASSTHRU, &
                ESMF_CONTEXT, rcToReturn=rc)) return
          enddo
        else
          do i = 1, size(sideAMesh, 1)
            xgtype%sideA(i+size(sideAGrid, 1)) = ESMF_XGridGeomBaseCreate(sideAMesh(i), &
              ESMF_MESHLOC_ELEMENT, rc=localrc)
            if (ESMF_LogFoundError(localrc, &
                ESMF_ERR_PASSTHRU, &
                ESMF_CONTEXT, rcToReturn=rc)) return
          enddo
        endif
      endif
    else ! .not. present(sideAGrid)
      if(present(sideAMesh)) then
        if(present(sideAMeshPriority)) then
          do i = 1, size(sideAMesh, 1)
            xgtype%sideA(sideAMeshPriority(i)) = ESMF_XGridGeomBaseCreate(sideAMesh(i), &
              ESMF_MESHLOC_ELEMENT, rc=localrc)
            if (ESMF_LogFoundError(localrc, &
                ESMF_ERR_PASSTHRU, &
                ESMF_CONTEXT, rcToReturn=rc)) return
          enddo
        else
          do i = 1, size(sideAMesh, 1)
            xgtype%sideA(i) = ESMF_XGridGeomBaseCreate(sideAMesh(i), &
              ESMF_MESHLOC_ELEMENT, rc=localrc)
            if (ESMF_LogFoundError(localrc, &
                ESMF_ERR_PASSTHRU, &
                ESMF_CONTEXT, rcToReturn=rc)) return
          enddo
        endif
      endif
    endif

    ! Need to initialize xgtype%sideB based on sideBGrid and/or sideBMesh
    if(present(sideBGrid)) then
      if(present(sideBGridPriority)) then
        do i = 1, size(sideBGrid, 1)
          xgtype%sideB(sideBGridPriority(i)) = ESMF_XGridGeomBaseCreate(sideBGrid(i), &
            ESMF_STAGGERLOC_CENTER, rc=localrc)
          if (ESMF_LogFoundError(localrc, &
              ESMF_ERR_PASSTHRU, &
              ESMF_CONTEXT, rcToReturn=rc)) return
        enddo
      else
        do i = 1, size(sideBGrid, 1)
          xgtype%sideB(i) = ESMF_XGridGeomBaseCreate(sideBGrid(i), &
            ESMF_STAGGERLOC_CENTER, rc=localrc)
          if (ESMF_LogFoundError(localrc, &
              ESMF_ERR_PASSTHRU, &
              ESMF_CONTEXT, rcToReturn=rc)) return
        enddo
      endif

      if(present(sideBMesh)) then
        if(present(sideBMeshPriority)) then
          do i = 1, size(sideBMesh, 1)
            xgtype%sideB(sideBMeshPriority(i)) = ESMF_XGridGeomBaseCreate(sideBMesh(i), &
              ESMF_MESHLOC_ELEMENT, rc=localrc)
            if (ESMF_LogFoundError(localrc, &
                ESMF_ERR_PASSTHRU, &
                ESMF_CONTEXT, rcToReturn=rc)) return
          enddo
        else
          do i = 1, size(sideBMesh, 1)
            xgtype%sideB(i+size(sideBGrid, 1)) = ESMF_XGridGeomBaseCreate(sideBMesh(i), &
              ESMF_MESHLOC_ELEMENT, rc=localrc)
            if (ESMF_LogFoundError(localrc, &
                ESMF_ERR_PASSTHRU, &
                ESMF_CONTEXT, rcToReturn=rc)) return
          enddo
        endif
      endif
    else ! .not. present(sideBGrid)
      if(present(sideBMesh)) then
        if(present(sideBMeshPriority)) then
          do i = 1, size(sideBMesh, 1)
            xgtype%sideB(sideBMeshPriority(i)) = ESMF_XGridGeomBaseCreate(sideBMesh(i), &
              ESMF_MESHLOC_ELEMENT, rc=localrc)
            if (ESMF_LogFoundError(localrc, &
                ESMF_ERR_PASSTHRU, &
                ESMF_CONTEXT, rcToReturn=rc)) return
          enddo
        else
          do i = 1, size(sideBMesh, 1)
            xgtype%sideB(i) = ESMF_XGridGeomBaseCreate(sideBMesh(i), &
              ESMF_MESHLOC_ELEMENT, rc=localrc)
            if (ESMF_LogFoundError(localrc, &
                ESMF_ERR_PASSTHRU, &
                ESMF_CONTEXT, rcToReturn=rc)) return
          enddo
        endif
      endif
    endif

    if(present(area)) then
      ncells = size(area, 1)
      allocate(xgtype%area(ncells), stat=localrc)
      if (ESMF_LogFoundAllocError(localrc, &
          msg="- Allocating xgtype%area ", &
          ESMF_CONTEXT, rcToReturn=rc)) return
      xgtype%area = area
    endif

    if(present(centroid)) then
        ncells = size(centroid, 1)
        ndim = size(centroid, 2)
        allocate(xgtype%centroid(ncells, ndim), stat=localrc)
        if (ESMF_LogFoundAllocError(localrc, &
            msg="- Allocating xgtype%centroid ", &
            ESMF_CONTEXT, rcToReturn=rc)) return
        xgtype%centroid = centroid
    endif

    call ESMF_XGridConstruct(xgtype, xgtype%sideA, xgtype%sideB, &
      sparseMatA2X=sparseMatA2X, sparseMatX2A=sparseMatX2A, &
      sparseMatB2X=sparseMatB2X, sparseMatX2B=sparseMatX2B, offline=.true., rc=localrc)
    if (ESMF_LogFoundAllocError(localrc, &
      msg="Constructing xgtype object ", &
      ESMF_CONTEXT, rcToReturn=rc)) return

    ! Finalize XGrid Creation
    xgtype%online = 0
    xgtype%status = ESMF_STATUS_READY
    ESMF_XGridCreateFromSparseMat%xgtypep => xgtype 
    ESMF_INIT_SET_CREATED(ESMF_XGridCreateFromSparseMat)

    call ESMF_XGridValidate(ESMF_XGridCreateFromSparseMat, rc=localrc)
    if (ESMF_LogFoundError(localrc, &
        ESMF_ERR_PASSTHRU, &
        ESMF_CONTEXT, rcToReturn=rc)) return

    if(present(rc)) rc = ESMF_SUCCESS

end function ESMF_XGridCreateFromSparseMat