<p><b>dwj07@fsu.edu</b> 2012-05-31 13:28:35 -0600 (Thu, 31 May 2012)</p><p><br>
        -- BRANCH COMMIT --<br>
<br>
        General code clean up and commenting in block_creator. Added doxygen comments to each routine, and a header comment for the module. Minimal inline comments added as well.<br>
<br>
        Code reorganization in mpas_io_input.<br>
<br>
        Bug fix in mpas_dmpar.<br>
</p><hr noshade><pre><font color="gray">Modified: branches/omp_blocks/multiple_blocks/src/framework/mpas_block_creator.F
===================================================================
--- branches/omp_blocks/multiple_blocks/src/framework/mpas_block_creator.F        2012-05-30 21:41:48 UTC (rev 1950)
+++ branches/omp_blocks/multiple_blocks/src/framework/mpas_block_creator.F        2012-05-31 19:28:35 UTC (rev 1951)
@@ -1,3 +1,19 @@
+!***********************************************************************
+!
+!  mpas_block_creator
+!
+!&gt; \brief   This module is responsible for the intial creation and setup of the block data structures.
+!&gt; \author  Doug Jacobsen
+!&gt; \date    05/31/12
+!&gt; \version SVN:$Id$
+!&gt; \details 
+!&gt; This module provides routines for the creation of blocks, with both an
+!&gt; arbitrary number of blocks per processor and an arbitrary number of halos for
+!&gt; each block. The provided routines also setup the exchange lists for each
+!&gt; block.
+!
+!-----------------------------------------------------------------------
+
 module mpas_block_creator
 
    use mpas_dmpar
@@ -10,15 +26,29 @@
 
    contains
 
-   subroutine mpas_block_creator_setup_blocks_and_0halo_cells(domain, indexToCellIDField, cellList, blockID, blockStart, blockCount)!{{{
+!***********************************************************************
+!
+!  routine mpas_block_creator_setup_blocks_and_0halo_cells
+!
+!&gt; \brief   Initializes the list of blocks, and determines 0 halo cell indices.
+!&gt; \author  Doug Jacobsen
+!&gt; \date    05/31/12
+!&gt; \version SVN:$Id$
+!&gt; \details 
+!&gt;  This routine sets up the linked list of blocks, and creates the
+!&gt;  indexToCellID field for the 0 halo. The information required to setup these
+!&gt;  structures is provided as input in cellList, blockID, blockStart, and
+!&gt;  blockCount.
+!
+!-----------------------------------------------------------------------
 
-     type (domain_type), pointer :: domain
-     type (block_type), pointer :: block
-     type (field1dInteger), pointer :: indexToCellIDField
-     integer, dimension(:), intent(in) :: cellList
-     integer, dimension(:), intent(in) :: blockID
-     integer, dimension(:), intent(in) :: blockStart
-     integer, dimension(:), intent(in) :: blockCount
+   subroutine mpas_block_creator_setup_blocks_and_0halo_cells(domain, indexToCellID, cellList, blockID, blockStart, blockCount)!{{{
+     type (domain_type), pointer :: domain !&lt; Input: Domain information
+     type (field1dInteger), pointer :: indexToCellID !&lt; Input/Output: indexToCellID field
+     integer, dimension(:), intent(in) :: cellList !&lt; Input: List of cell indices owned by this processor
+     integer, dimension(:), intent(in) :: blockID !&lt; Input: List of block indices owned by this processor
+     integer, dimension(:), intent(in) :: blockStart !&lt; Input: Indices of starting cell id in cellList for each block
+     integer, dimension(:), intent(in) :: blockCount !&lt; Input: Number of cells from cellList owned by each block.
  
      integer :: nHalos
      type (block_type), pointer :: blockCursor
@@ -30,47 +60,77 @@
      nBlocks = size(blockID)
      nHalos = config_num_halos
 
-     allocate(domain % blocklist)
-     block =&gt; domain % blocklist
-     nullify(block % prev)
-     nullify(block % next)

-     allocate(indexToCellIDField)
-     nullify(indexToCellIDField % next)
+     if(nBlocks &gt; 0) then
+       ! Setup first block
+       allocate(domain % blocklist)
+!      block =&gt; domain % blocklist
+       nullify(domain % blocklist % prev)
+       nullify(domain % blocklist % next)
+   
+       ! Setup first block field
+       allocate(indexToCellID)
+       nullify(indexToCellID % next)
+  
+       ! Loop over blocks
+       blockCursor =&gt; domain % blocklist
+       fieldCursor =&gt; indexToCellID
+       do i = 1, nBlocks
+         ! Initialize block information
+         blockCursor % blockID = blockID(i)
+         blockCursor % localBlockID = i - 1
+         blockCursor % domain =&gt; domain
+   
+         ! Link to block, and setup array size
+         fieldCursor % block =&gt; blockCursor
+         fieldCursor % dimSizes(1) = blockCount(i)
+         nullify(fieldCursor % ioinfo)
+  
+         ! Initialize exchange lists
+         call mpas_dmpar_init_mulithalo_exchange_list(fieldCursor % sendList, nHalos)
+         call mpas_dmpar_init_mulithalo_exchange_list(fieldCursor % recvList, nHalos)
+         call mpas_dmpar_init_mulithalo_exchange_list(fieldCursor % copyList, nHalos)
+  
+         ! Allocate array, and copy indices into array
+         allocate(fieldCursor % array(fieldCursor % dimSizes(1)))
+         fieldCursor % array(1:fieldCursor % dimSizes(1)) = cellList(blockStart(i)+1:blockStart(i)+blockCount(i))
+   
+         ! Advance cursors, and create new blocks as needed
+         if(i &lt; nBlocks) then
+           allocate(blockCursor % next)
+           allocate(fieldCursor % next)
+  
+           blockCursor % next % prev =&gt; blockCursor
+   
+           blockCursor =&gt; blockCursor % next
+           fieldCursor =&gt; fieldCursor % next
+         end if
+  
+         ! Nullify next pointers
+         nullify(blockCursor % next)
+         nullify(fieldCursor % next)
+       end do
+     else
+       ! If no blocks, nullify block and field pointers
+       nullify(domain % blocklist)
+       nullify(indexToCellID)
+     end if
+   end subroutine mpas_block_creator_setup_blocks_and_0halo_cells!}}}
 
-     blockCursor =&gt; block
-     fieldCursor =&gt; indexToCellIDField
-     do i = 1, nBlocks
-       blockCursor % blockID = blockID(i)
-       blockCursor % localBlockID = i - 1
-       blockCursor % domain =&gt; domain

-       fieldCursor % block =&gt; blockCursor
-       fieldCursor % dimSizes(1) = blockCount(i)
-       nullify(fieldCursor % ioinfo)
+!***********************************************************************
+!
+!  routine mpas_block_creator_build_0halo_cell_fields
+!
+!&gt; \brief   Initializes 0 halo cell based fields requried to work out halos
+!&gt; \author  Doug Jacobsen
+!&gt; \date    05/31/12
+!&gt; \version SVN:$Id$
+!&gt; \details 
+!&gt;  This routine uses the previously setup 0 halo cell field, and the blocks of
+!&gt;  data read in by other routhers to determine all of the connectivity for the 0
+!&gt;  halo cell fields on all blocks on a processor.
+!
+!-----------------------------------------------------------------------
 
-       call mpas_dmpar_init_mulithalo_exchange_list(fieldCursor % sendList, nHalos)
-       call mpas_dmpar_init_mulithalo_exchange_list(fieldCursor % recvList, nHalos)
-       call mpas_dmpar_init_mulithalo_exchange_list(fieldCursor % copyList, nHalos)
-
-       allocate(fieldCursor % array(fieldCursor % dimSizes(1)))
-       fieldCursor % array(1:fieldCursor % dimSizes(1)) = cellList(blockStart(i)+1:blockStart(i)+blockCount(i))

-       if(i &lt; nBlocks) then
-         allocate(blockCursor % next)
-         allocate(fieldCursor % next)
-
-         blockCursor % next % prev =&gt; blockCursor

-         blockCursor =&gt; blockCursor % next
-         fieldCursor =&gt; fieldCursor % next
-       end if
-
-       nullify(blockCursor % next)
-       nullify(fieldCursor % next)
-     end do
-   end subroutine mpas_block_creator_setup_blocks_and_0halo_cells!}}}
-
    subroutine mpas_block_creator_build_0halo_cell_fields(indexToCellIDBlock, nEdgesOnCellBlock, cellsOnCellBlock, verticesOnCellBlock, edgesOnCellBlock, indexToCellID_0Halo, nEdgesOnCell_0Halo, cellsOnCell_0Halo, verticesOnCell_0Halo, edgesOnCell_0Halo)!{{{
      type(field1dInteger), pointer :: indexToCellIDBlock !&lt; Input: Block of read in indexToCellID field
      type(field1dInteger), pointer :: nEdgesOnCellBlock !&lt; Input: Block of read in nEdgesOnCell field
@@ -92,27 +152,39 @@
      integer :: nCellsInBlock, maxEdges, nHalos
      integer :: i, iHalo
 
-     nHalos = size(indexToCellID_0Halo % sendList % halos)
+     nHalos = config_num_halos
 
+     ! Only sending from halo layer 1 for setup
      allocate(sendingHaloLayers(1))
      sendingHaloLayers(1) = 1
 
      maxEdges = cellsOnCellBlock % dimSizes(1)
 
+     ! Build exchange list from the block of read in data to each block's index fields.
      call mpas_dmpar_get_exch_list(1, indexToCellIDBlock, indexToCellID_0Halo)
 
-     allocate(nEdgesOnCell_0Halo)
-     nullify(nEdgesOncell_0Halo % next)
+     ! Setup header fields if at least 1 block exists
+     if(associated(indexToCellID_0Halo)) then
+       allocate(nEdgesOnCell_0Halo)
+       nullify(nEdgesOncell_0Halo % next)
 
-     allocate(cellsOnCell_0Halo)
-     nullify(cellsOnCell_0Halo % next)
+       allocate(cellsOnCell_0Halo)
+       nullify(cellsOnCell_0Halo % next)
+  
+       allocate(verticesOnCell_0Halo)
+       nullify(verticesOnCell_0Halo % next)
+  
+       allocate(edgesOnCell_0Halo)
+       nullify(edgesOnCell_0Halo % next)
+     else
+       nullify(nEdgesOnCell_0Halo)
+       nullify(cellsOnCell_0Halo)
+       nullify(verticesOnCell_0Halo)
+       nullify(edgesOnCell_0Halo)
+     end if
 
-     allocate(verticesOnCell_0Halo)
-     nullify(verticesOnCell_0Halo % next)
 
-     allocate(edgesOnCell_0Halo)
-     nullify(edgesOnCell_0Halo % next)
-
+     ! Loop over blocks
      indexCursor =&gt; indexToCellID_0Halo
      nEdgesCursor =&gt; nEdgesOnCell_0Halo
      cellsOnCellCursor =&gt; cellsOnCell_0Halo
@@ -121,16 +193,19 @@
      do while(associated(indexCursor))
        nCellsInBlock = indexCursor % dimSizes(1)
 
+       ! Link to block structure
        nEdgesCursor % block =&gt; indexCursor % block
        cellsOnCellCursor % block =&gt; indexCursor % block
        verticesOnCellCursor % block =&gt; indexCursor % block
        edgesOnCellCursor % block =&gt; indexCursor % block
 
+       ! Nullify ioinfo, since this data is not read in
        nullify(nEdgesCursor % ioinfo)
        nullify(cellsOnCellCursor % ioinfo)
        nullify(verticesOnCellCursor % ioinfo)
        nullify(edgesOnCellCursor % ioinfo)
 
+       ! Setup array sizes
        nEdgesCursor % dimSizes(1) = nCellsInBlock
        cellsOnCellCursor % dimSizes(1) = maxEdges
        cellsOnCellCursor % dimSizes(2) = nCellsInBlock
@@ -139,6 +214,7 @@
        edgesOnCellCursor % dimSizes(1) = maxEdges
        edgesOnCellCursor % dimSizes(2) = nCellsInBlock
 
+       ! Link exchange lists
        nEdgesCursor % sendList =&gt; indexCursor % sendList
        nEdgesCursor % recvList =&gt; indexCursor % recvList
        nEdgesCursor % copyList =&gt; indexCursor % copyList
@@ -152,11 +228,13 @@
        edgesOnCellCursor % recvList =&gt; indexCursor % recvList
        edgesOnCellCursor % copyList =&gt; indexCursor % copyList
 
+       ! Allocate arrays
        allocate(nEdgesCursor % array(nEdgesCursor % dimSizes(1)))
        allocate(cellsOnCellCursor % array(cellsOnCellCursor % dimSizes(1), cellsOnCellCursor % dimSizes(2)))
        allocate(verticesOnCellCursor % array(verticesOnCellCursor % dimSizes(1), verticesOnCellCursor % dimSizes(2)))
        allocate(edgesOnCellCursor % array(edgesOnCellCursor % dimSizes(1), edgesOnCellCursor % dimSizes(2)))
        
+       ! Create new blocks and advance cursors as needed
        indexCursor =&gt; indexCursor % next
        if(associated(indexCursor)) then
          allocate(nEdgesCursor % next)
@@ -171,18 +249,36 @@
 
        end if
 
+       ! Nullify next pointers
        nullify(nEdgesCursor % next)
        nullify(cellsOnCellCursor % next)
        nullify(verticesOnCellCursor % next)
        nullify(edgesOnCellCursor % next)
-     end do
+     end do ! indexCursor loop over blocks
 
+     ! Communicate data from read in blocks to each block's fields
      call mpas_dmpar_alltoall_field(nEdgesOnCellBlock, nEdgesOnCell_0Halo, sendingHaloLayers)
      call mpas_dmpar_alltoall_field(cellsOnCellBlock, cellsOnCell_0Halo, sendingHaloLayers)
      call mpas_dmpar_alltoall_field(verticesOnCellBlock, verticesOnCell_0Halo, sendingHaloLayers)
      call mpas_dmpar_alltoall_field(edgesOnCellBlock, edgesOnCell_0Halo, sendingHaloLayers)
    end subroutine mpas_block_creator_build_0halo_cell_fields!}}}
 
+!***********************************************************************
+!
+!  routine mpas_block_creator_build_0_and_1halo_vertex_fields
+!
+!&gt; \brief   Initializes 0 and 1 halo vertex based fields requried to work out halos
+!&gt; \author  Doug Jacobsen
+!&gt; \date    05/31/12
+!&gt; \version SVN:$Id$
+!&gt; \details 
+!&gt;  This routine uses the previously setup 0 halo cell fields, and the blocks of
+!&gt;  data read in by other routhers to determine which vertices are in a blocks
+!&gt;  0 and 1 halo for all blocks on a processor.
+!&gt;  NOTE: This routine can be used on either vertices or edges
+!
+!-----------------------------------------------------------------------
+
    subroutine mpas_block_creator_build_0_and_1halo_vertex_fields(indexToVertexIDBlock, cellsOnVertexBlock, indexToCellID_0Halo, nEdgesOnCell_0Halo, verticesOnCell_0Halo, indexToVertexID_0Halo, cellsOnVertex_0Halo, nVerticesSolve)!{{{
      type (field1dInteger), pointer :: indexToVertexIDBlock !&lt; Input: indexToVertexID read in field
      type (field2dInteger), pointer :: cellsOnVertexBlock !&lt; Input: cellsOnVertex read in field
@@ -208,51 +304,71 @@
      integer :: haloStart
      integer :: iBlock, i, j, k
 
+     ! Setup sendingHaloLayers
      allocate(sendingHaloLayers(1))
      sendingHaloLayers(1) = 1
 
+     ! Get dimension information
      maxEdges = verticesOnCell_0Halo % dimSizes(1)
      vertexDegree = cellsOnVertexBlock % dimSizes(1)
      nHalos = config_num_halos
 
-     allocate(cellsOnVertex_0Halo)
-     allocate(indexToVertexID_0Halo)
+     ! Setup initial block for each field
+     if(associated(indexToCellCursor)) then
+       allocate(cellsOnVertex_0Halo)
+       allocate(indexToVertexID_0Halo)
 
+       nullify(cellsOnVertex_0Halo % next)
+       nullify(indexToVertexID_0Halo % next)
+     else
+       nullify(cellsOnVertex_0Halo)
+       nullify(indexToVertexID_0Halo)
+     end if
+
+     ! Loop over blocks
      indexToCellCursor =&gt; indexToCellID_0Halo
      verticesOnCellCursor =&gt; verticesOnCell_0Halo
      nEdgesCursor =&gt; nEdgesOnCell_0Halo
      indexToVertexCursor =&gt; indexToVertexID_0Halo
      cellsOnVertexCursor =&gt; cellsOnVertex_0Halo
      do while(associated(indexToCellCursor))
+       ! Determine number of cells in block
        nCellsInBlock = indexToCellCursor % dimSizes(1)
 
+       ! Determine all vertices in block
        call mpas_block_decomp_all_edges_in_block(maxEdges, nCellsInBlock, nEdgesCursor % array, verticesOnCellCursor % array, nVerticesLocal, localVertexList)
 
+       ! Setup indexToVertex block
        indexToVertexCursor % block =&gt; indexToCellCursor % block
        nullify(indexToVertexCursor % ioinfo)
        indexToVertexCursor % dimSizes(1) = nVerticesLocal
        allocate(indexToVertexCursor % array(indexToVertexCursor % dimSizes(1)))
        indexToVertexCursor % array(:) = localVertexList(:)
 
+       ! Setup cellsOnVertex block
        cellsOnVertexCursor % block =&gt; indexToCellCursor % block
        nullify(cellsOnVertexCursor % ioinfo)
        cellsOnVertexCursor % dimSizes(1) = vertexDegree
        cellsOnVertexCursor % dimSizes(2) = nVerticesLocal
        allocate(cellsOnVertexCursor % array(cellsOnVertexCursor % dimSizes(1), cellsOnVertexCursor % dimSizes(2)))
 
+       ! Setup exchange lists
        call mpas_dmpar_init_mulithalo_exchange_list(indexToVertexCursor % sendList, nHalos+1)
        call mpas_dmpar_init_mulithalo_exchange_list(indexToVertexCursor % recvList, nHalos+1)
        call mpas_dmpar_init_mulithalo_exchange_list(indexToVertexCursor % copyList, nHalos+1)
 
+       ! Link exchange lists
        cellsOnVertexCursor % sendList =&gt; indexToVertexCursor % sendList
        cellsOnVertexCursor % recvList =&gt; indexToVertexCursor % recvList
        cellsOnVertexCursor % copyList =&gt; indexToVertexCursor % copyList
        
+       ! Remove localVertexList array
        deallocate(localVertexList)
+
+       ! Advance cursors, and create new blocks if needed
        indexToCellCursor =&gt; indexToCellCursor % next
        verticesOnCellCursor =&gt; verticesOnCellCursor % next
        nEdgescursor =&gt; nEdgesCursor % next
-
        if(associated(indexToCellCursor)) then
          allocate(indexToVertexCursor % next)
          indexToVertexCursor =&gt; indexToVertexCursor % next
@@ -260,85 +376,32 @@
          allocate(cellsOnVertexCursor % next)
          cellsOnVertexCursor =&gt; cellsOnVertexCursor % next
        end if
+
+       ! Nullify next pointers
        nullify(indexToVertexCursor % next)
        nullify(cellsOnVertexCursor % next)
-     end do
+     end do ! indexToCursor loop over blocks
 
+     ! Build exchangel ists from read in blocks to owned blocks.
      call mpas_dmpar_get_exch_list(1, indexToVertexIDBlock, indexToVertexID_0Halo)
 
-!    write(6,*) 'CELLSONVERTEXBLOCK'
-!    indexToVertexCursor =&gt; indexToVertexIDBlock
-!    do while(associated(indexToVertexCursor))
-!      write(6,*) 'sendLists on block',indexToVertexCursor % block % blockID
-!      exchListPtr =&gt; indexToVertexCursor % sendList % halos(1) % exchList
-!      do while(associated(exchListPtr))
-!        write(6,*) 'to', exchListPtr % endPointID
-!        do i = 1, exchListPtr % nList
-!          write(6,*) i, exchListPtr % srcList(i), exchListPtr % destList(i)
-!        end do
-!        exchListPtr =&gt; exchListPtr % next
-!      end do
-!      write(6,*) 'recvLists on block',indexToVertexCursor % block % blockID
-!      exchListPtr =&gt; indexToVertexCursor % recvList % halos(1) % exchList
-!      do while(associated(exchListPtr))
-!        write(6,*) 'from', exchListPtr % endPointID
-!        do i = 1, exchListPtr % nList
-!          write(6,*) i, exchListPtr % srcList(i), exchListPtr % destList(i)
-!        end do
-!        exchListPtr =&gt; exchListPtr % next
-!      end do
-!      write(6,*) 'copyLists on block',indexToVertexCursor % block % blockID
-!      exchListPtr =&gt; indexToVertexCursor % copyList % halos(1) % exchList
-!      do while(associated(exchListPtr))
-!        write(6,*) 'to', exchListPtr % endPointID
-!        do i = 1, exchListPtr % nList
-!          write(6,*) i, exchListPtr % srcList(i), exchListPtr % destList(i)
-!        end do
-!        exchListPtr =&gt; exchListPtr % next
-!      end do
-!      indexToVertexCursor =&gt; indexToVertexCursor % next
-!    end do
-
-!    write(6,*) 'CELLSONVERTEX_0HALO'
-!    cellsOnVertexCursor =&gt; cellsOnVertex_0Halo
-!    do while(associated(cellsOnVertexCursor))
-!      write(6,*) 'sendLists on block',cellsOnVertexCursor % block % blockID
-!      exchListPtr =&gt; cellsOnVertexCursor % sendList % halos(1) % exchList
-!      do while(associated(exchListPtr))
-!        write(6,*) 'to', exchListPtr % endPointID
-!        do i = 1, exchListPtr % nList
-!          write(6,*) i, exchListPtr % srcList(i), exchListPtr % destList(i)
-!        end do
-!        exchListPtr =&gt; exchListPtr % next
-!      end do
-!      write(6,*) 'recvLists on block',cellsOnVertexCursor % block % blockID
-!      exchListPtr =&gt; cellsOnVertexCursor % recvList % halos(1) % exchList
-!      do while(associated(exchListPtr))
-!        write(6,*) 'from', exchListPtr % endPointID
-!        do i = 1, exchListPtr % nList
-!          write(6,*) i, exchListPtr % srcList(i), exchListPtr % destList(i)
-!        end do
-!        exchListPtr =&gt; exchListPtr % next
-!      end do
-!      write(6,*) 'copyLists on block',cellsOnVertexCursor % block % blockID
-!      exchListPtr =&gt; cellsOnVertexCursor % copyList % halos(1) % exchList
-!      do while(associated(exchListPtr))
-!        write(6,*) 'to', exchListPtr % endPointID
-!        do i = 1, exchListPtr % nList
-!          write(6,*) i, exchListPtr % srcList(i), exchListPtr % destList(i)
-!        end do
-!        exchListPtr =&gt; exchListPtr % next
-!      end do
-!      cellsOnVertexCursor =&gt; cellsOnVertexCursor % next
-!    end do
-
+     ! Perform all to all to get owned block data
      call mpas_dmpar_alltoall_field(cellsOnVertexBlock, cellsOnVertex_0Halo, sendingHaloLayers)
 
-     allocate(haloIndices)
-     allocate(offSetField)
-     allocate(vertexLimitField)
-     allocate(nVerticesSolve)
+     ! Setup first block's fields if there is at least 1 block.
+     if(associated(indexToVertexID_0Halo)) then
+       allocate(haloIndices)
+       allocate(offSetField)
+       allocate(vertexLimitField)
+       allocate(nVerticesSolve)
+     else
+       nullify(haloIndices)
+       nullify(offSetField)
+       nullify(vertexLimitField)
+       nullify(nVerticesSolve)
+     end if
 
+     ! Loop over blocks
      indexToVertexCursor =&gt; indexToVertexID_0Halo
      cellsOnVertexCursor =&gt; cellsOnVertex_0Halo
      indexToCellCursor =&gt; indexToCellID_0Halo
@@ -347,37 +410,45 @@
      vertexLimitCursor =&gt; vertexLimitField
      nVerticesSolveCursor =&gt; nVerticesSolve
      do while(associated(indexToVertexCursor))
+       ! Determine 0 and 1 halo vertices
        call mpas_block_decomp_partitioned_edge_list(indexToCellCursor % dimSizes(1), indexToCellCursor % array, &amp;
                                                     vertexDegree, indexToVertexCursor % dimSizes(1), cellsOnVertexCursor % array, &amp;
                                                     indexToVertexCursor % array, haloStart)
 
+       ! Link blocks                                                
        haloCursor % block =&gt; indexToVertexCursor % block
        offSetCursor % block =&gt; indexToVertexCursor % block
        vertexLimitCursor % block =&gt; indexToVertexCursor % block
        nVerticesSolveCursor % block =&gt; indexToVertexCursor % block
 
+       ! Nullify io info
        nullify(haloCursor % ioinfo)
        nullify(offSetCursor % ioinfo)
        nullify(vertexLimitCursor % ioinfo)
        nullify(nVerticesSolveCursor % ioinfo)
 
+       ! Setup haloIndices
        haloCursor % dimSizes(1) = indexToVertexCursor % dimSizes(1) - (haloStart-1)
        allocate(haloCursor % array(haloCursor % dimSizes(1)))
        haloCursor % array(:) = indexToVertexCursor % array(haloStart:indexToVertexCursor % dimSizes(1))
 
+       ! Link exchange lists
        haloCursor % sendList =&gt; indexToVertexCursor % sendList
        haloCursor % recvList =&gt; indexToVertexCursor % recvList
        haloCursor % copyList =&gt; indexToVertexCursor % copyList
 
+       ! Determine offSet and limit on 0 halo vertices for exchange list creation
        offSetCursor % scalar = haloStart - 1
        vertexLimitCursor % scalar = haloStart - 1
 
-       nVerticesSolveCursor % dimSizes(1) = nHalos+2 ! 1 for 0 halo, 1 for nHalo+1
+       ! Setup nVerticesSolve
+       nVerticesSolveCursor % dimSizes(1) = nHalos+2 
        allocate(nVerticesSolveCursor % array(nVerticesSolve % dimSizes(1)))
        nVerticesSolveCursor % array = -1
        nVerticesSolveCursor % array(1) = haloStart - 1
        nVerticesSolveCursor % array(2) = indexToVertexCursor % dimSizes(1)
 
+       ! Advance cursors, and create new blocks if needed
        indexToVertexCursor =&gt; indexToVertexCursor % next
        cellsOnVertexCursor =&gt; cellsOnVertexCursor % next
        indexToCellCursor =&gt; indexToCellCursor % next
@@ -394,14 +465,18 @@
          allocate(nVerticesSolveCursor % next)
          nVerticesSolveCursor =&gt; nVerticesSolveCursor % next
        end if
+
+       ! Nullify next pointers
        nullify(haloCursor % next)
        nullify(offSetCursor % next)
        nullify(vertexLimitCursor % next)
        nullify(nVerticesSolveCursor % next)
      end do
 
+     ! Create exchange lists from 0 halo to 1 halo vertices
      call mpas_dmpar_get_exch_list(1, indexToVertexID_0Halo, haloIndices, offSetField, vertexLimitField)
 
+     ! Deallocate fields that are not needed anymore.
      call mpas_deallocate_field(haloIndices)
      call mpas_deallocate_field(offSetField)
      call mpas_deallocate_field(vertexLimitCursor)
@@ -409,6 +484,22 @@
 
    end subroutine mpas_block_creator_build_0_and_1halo_vertex_fields!}}}
 
+!***********************************************************************
+!
+!  routine mpas_block_creator_build_cell_halos
+!
+!&gt; \brief   Builds cell halos
+!&gt; \author  Doug Jacobsen
+!&gt; \date    05/31/12
+!&gt; \version SVN:$Id$
+!&gt; \details 
+!&gt;  This routine uses the previously setup 0 halo cell fields to determine
+!&gt;  which cells fall in each halo layer for a block. During this process, each
+!&gt;  halo's exchange lists are created. This process is performed for all blocks on
+!&gt;  a processor.
+!
+!-----------------------------------------------------------------------
+
    subroutine mpas_block_creator_build_cell_halos(indexToCellID, nEdgesOnCell, cellsOnCell, verticesOnCell, edgesOnCell, nCellsSolve)!{{{
      type (field1dInteger), pointer :: indexToCellID !&lt; Input/Output: indexToCellID field for all halos
      type (field1dInteger), pointer :: nEdgesOnCell !&lt; Input/Output: nEdgesOnCell field for all halos
@@ -442,29 +533,46 @@
      nHalos = config_num_halos
      dminfo =&gt; indexToCellID % block % domain % dminfo
      allocate(sendingHaloLayers(1))
-     allocate(nCellsSolve)
 
-     allocate(cellLimitField)
-     allocate(offSetField)
+     ! Setup header fields
+     if(associated(indexToCellID)) then
+       allocate(nCellsSolve)
+       allocate(cellLimitField)
+       allocate(offSetField)
+
+       nullify(nCellsSolve % next)
+       nullify(cellLimitField % next)
+       nullify(offSetField % next)
+     else
+       nullify(nCellsSolve)
+       nullify(cellLimitField)
+       nullify(offSetField)
+     end if
+
+     ! Loop over blocks
      offSetCursor =&gt; offsetField
      cellLimitCursor =&gt; cellLimitField
      indexCursor =&gt; indexToCellID
      nCellsSolveCursor =&gt; nCellsSolve
      do while (associated(indexCursor))
+       ! Setup offset
        offSetCursor % scalar = indexCursor % dimSizes(1)
        offSetCursor % block =&gt; indexCursor % block
        nullify(offSetCursor % ioinfo)
 
+       ! Setup nCellsSolve
        nCellsSolveCursor % dimSizes(1) = nHalos+1
        allocate(nCellsSolveCursor % array(nCellsSolveCursor % dimSizes(1)))
        nCellsSolveCursor % array(1) = indexCursor % dimSizes(1)
        nCellsSolveCursor % block =&gt; indexCursor % block
        nullify(nCellsSolveCursor % ioinfo)
 
+       ! Setup owned cellLimit
        cellLimitCursor % scalar = indexCursor % dimSizes(1)
        cellLimitCursor % block =&gt; indexCursor % block
        nullify(cellLimitCursor % ioinfo)
 
+       ! Advance cursors and create new blocks if needed
        indexCursor =&gt; indexCursor % next
        if(associated(indexCursor)) then
          allocate(offSetCursor % next)
@@ -476,16 +584,26 @@
          allocate(cellLimitCursor % next)
          cellLimitCursor =&gt; cellLimitCursor % next
        end if
+
+       ! Nullify next pointers
        nullify(offSetCursor % next)
        nullify(nCellssolveCursor % next)
        nullify(cellLimitCursor % next)
      end do
 
+     ! Loop over halos
      do iHalo = 1, nHalos
+       ! Sending halo layer is the current halo
        sendingHaloLayers(1) = iHalo
 
-       allocate(haloIndices)
+       if(associated(indexToCellID)) then
+         allocate(haloIndices)
+         nullify(haloIndices % next)
+       else
+         nullify(haloIndices)
+       end if
 
+       ! Loop over blocks
        indexCursor =&gt; indexToCellID
        nEdgesCursor =&gt; nEdgesOnCell
        cellsOnCellCursor =&gt; cellsOnCell
@@ -494,11 +612,14 @@
        haloCursor =&gt; haloIndices
        offSetCursor =&gt; offSetField
        do while(associated(indexCursor))
+         ! Determine block dimensions
          nCellsInBlock = indexCursor % dimSizes(1)
          maxEdges = cellsOnCellCursor % dimSizes(1)
 
+         ! Setup offSet
          offSetCursor % scalar = nCellsInBlock 
 
+         ! Setup block graphs
          allocate(blockGraphWithHalo)
          allocate(blockGraph)
          allocate(blockGraph % vertexID(nCellsInBlock))
@@ -510,14 +631,14 @@
          blockGraph % maxDegree = maxEdges
          blockGraph % ghostStart = nCellsInBlock + 1
 
-!write(6,*) 'max nedges on block', indexCursor % block % blockid, maxval(nEdgescursor % array)
-
          blockGraph % vertexID(:) = indexCursor % array(:)
          blockGraph % nAdjacent(:) = nEdgesCursor % array(:)
          blockGraph % adjacencyList(:,:) = cellsOnCellCursor % array(:,:)
 
+         ! Determine all cell id's with the next halo added
          call mpas_block_decomp_add_halo(dminfo, blockGraph, blockGraphWithHalo)
 
+         ! Setup haloIndices
          haloCursor % dimSizes(1) = blockGraphWithHalo % nVerticesTotal - blockGraphWithHalo % nVertices
          allocate(haloCursor % array(haloCursor % dimSizes(1)))
          haloCursor % array(:) = -1
@@ -528,6 +649,7 @@
          haloCursor % block =&gt; indexCursor % block
          nullify(haloCursor % ioinfo)
 
+         ! Deallocate block graphs
          deallocate(blockGraphWithHalo % vertexID)
          deallocate(blockGraphWithHalo % nAdjacent)
          deallocate(blockGraphWithHalo % adjacencyList)
@@ -538,6 +660,7 @@
          deallocate(blockGraph % adjacencyList)
          deallocate(blockGraph)
 
+         ! Advance cursors and create new block if needed
          indexCursor =&gt; indexCursor % next
          nEdgesCursor =&gt; nEdgesCursor % next
          cellsOnCellCursor =&gt; cellsOnCellCursor % next
@@ -548,55 +671,14 @@
            allocate(haloCursor % next)
            haloCursor =&gt; haloCursor % next
          end if
+         ! Nullify next pointer
          nullify(haloCursor % next)
        end do ! indexCursor loop over blocks
 
+       ! Create exchange lists for current halo layer
        call mpas_dmpar_get_exch_list(iHalo, indexToCellID, haloIndices, offSetField, cellLimitField)
 
-       ! dwj: 05/24/12 debugging
-!      write(6,*) 'new send lists'
-!      indexCursor =&gt; indexToCellID
-!      do while(associated(indexCursor))
-!        exchListPtr =&gt; indexCursor % sendList % halos(iHalo) % exchList
-!        do while(associated(exchListPtr))
-!        write(6,*) 'send list from block ', indexCursor % block % localBlockID, ' to proc ', exchListPtr % endPointID
-!          do i = 1, exchListPtr % nList
-!            write(6,*) exchListPtr % srcList(i), exchListPtr % destList(i)!, indexCursor % array(exchListPtr % srcList(i))
-!          end do
-!          exchListPtr =&gt; exchListPtr % next
-!        end do
-!        indexCursor =&gt; indexCursor % next
-!      end do
-
-!      write(6,*) 'new recv lists'
-!      indexCursor =&gt; indexToCellID
-!      do while(associated(indexCursor))
-!        exchListPtr =&gt; indexCursor % recvList % halos(iHalo) % exchList
-!        do while(associated(exchListPtr))
-!        write(6,*) 'recv list to block ', indexCursor % block % localBlockID, ' from proc ', exchListPtr % endPointID
-!          do i = 1, exchListPtr % nList
-!            write(6,*) exchListPtr % srcList(i), exchListPtr % destList(i), indexCursor % array(exchListPtr % srcList(i))
-!          end do
-!          exchListPtr =&gt; exchListPtr % next
-!        end do
-!        indexCursor =&gt; indexCursor % next
-!      end do
-
-
-!      write(6,*) 'new copy lists'
-!      indexCursor =&gt; indexToCellID
-!      do while(associated(indexCursor))
-!        exchListPtr =&gt; indexCursor % copyList % halos(iHalo) % exchList
-!        do while(associated(exchListPtr))
-!        write(6,*) 'copy list from block ', indexCursor % block % localBlockID, ' to ', exchListPtr % endPointID
-!          do i = 1, exchListPtr % nList
-!            write(6,*) exchListPtr % srcList(i), exchListPtr % destList(i), indexCursor % array(exchListPtr % srcList(i))
-!          end do
-!          exchListPtr =&gt; exchListPtr % next
-!        end do
-!        indexCursor =&gt; indexCursor % next
-!      end do
-
+       ! Loop over blocks
        indexCursor =&gt; indexToCellID
        nEdgesCursor =&gt; nEdgesOnCell
        cellsOnCellCursor =&gt; cellsOnCell
@@ -605,11 +687,14 @@
        haloCursor =&gt; haloIndices
        nCellsSolveCursor =&gt; nCellsSolve
        do while(associated(indexCursor))
+         ! Determine block dimensions
          nCellsInBlock = indexCursor % dimSizes(1)
          nCellsInHalo = haloCursor % dimSizes(1) 
 
+         ! Setup new layer's nCellsSolve
          nCellsSolveCursor % array(iHalo+1) = nCellsInBlock + nCellsInHalo
 
+         ! Copy cell indices into indexToCellID field
          field1dArrayHolder =&gt; indexCursor % array
          indexCursor % dimSizes(1) = nCellsSolveCursor % array(iHalo+1)
          allocate(indexCursor % array(indexCursor % dimSizes(1)))
@@ -618,6 +703,7 @@
          indexCursor % array(nCellsInBlock+1:nCellsSolveCursor % array(iHalo+1)) = haloCursor % array(1:nCellsInHalo)
          deallocate(field1dArrayHolder)
 
+         ! Allocate space in nEdgesOnCell
          field1dArrayHolder =&gt; nEdgesCursor % array
          nEdgesCursor % dimSizes(1) = nCellsSolveCursor % array(iHalo+1)
          allocate(nEdgesCursor % array(nEdgesCursor % dimSizes(1)))
@@ -625,6 +711,7 @@
          nEdgesCursor % array(1:nCellsInBlock) = field1dArrayHolder(:)
          deallocate(field1dArrayHolder)
 
+         ! Allocate space in cellsOnCell
          field2dArrayHolder =&gt; cellsOnCellCursor % array
          cellsOnCellCursor  % dimSizes(2) = nCellsSolveCursor % array(iHalo+1)
          allocate(cellsOnCellCursor % array(cellsOnCellCursor % dimSizes(1), cellsOnCellCursor % dimSizes(2)))
@@ -632,6 +719,7 @@
          cellsOnCellCursor % array(:,1:nCellsInBlock) = field2dArrayHolder(:,:)
          deallocate(field2dArrayHolder)
 
+         ! Allocate space in verticesOnCell
          field2dArrayHolder =&gt; verticesOnCellCursor % array
          verticesOnCellCursor  % dimSizes(2) = nCellsSolveCursor % array(iHalo+1)
          allocate(verticesOnCellCursor % array(verticesOnCellCursor % dimSizes(1), verticesOnCellCursor % dimSizes(2)))
@@ -639,6 +727,7 @@
          verticesOnCellCursor % array(:,1:nCellsInBlock) = field2dArrayHolder(:,:)
          deallocate(field2dArrayHolder)
 
+         ! Allocate space in edgesOnCell
          field2dArrayHolder =&gt; edgesOnCellCursor % array
          edgesOnCellCursor  % dimSizes(2) = nCellsSolveCursor % array(iHalo+1)
          allocate(edgesOnCellCursor % array(edgesOnCellCursor % dimSizes(1), edgesOnCellCursor % dimSizes(2)))
@@ -655,49 +744,40 @@
          nCellsSolveCursor =&gt; nCellsSolveCursor % next
        end do
 
+       ! Perform allToAll communications
        call mpas_dmpar_alltoall_field(indexToCellID, indexToCellID, sendingHaloLayers)
        call mpas_dmpar_alltoall_field(nEdgesOnCell, nEdgesOncell, sendingHaloLayers)
        call mpas_dmpar_alltoall_field(cellsOnCell, cellsOnCell, sendingHaloLayers)
        call mpas_dmpar_alltoall_field(verticesOnCell, verticesOnCell, sendingHaloLayers)
        call mpas_dmpar_alltoall_field(edgesOnCell, edgesOnCell, sendingHaloLayers)
 
-       ! dwj: 05/24/12 debugging
-!       indexCursor =&gt; indexToCellID
-!       do while(associated(indexCursor))
-!write(6,*) 'indexToCellID with HALO', iHalo,' on block ', indexCursor % block % blockID
-!         do i = 1, indexcursor % dimSizes(1)
-!           write(6,*) i, indexCursor % array(i)
-!         end do
-!         indexCursor =&gt; indexCursor % next
-!       end do
-!
-!       nEdgesCursor =&gt; nEdgesOnCell
-!       do while(associated(nEdgesCursor))
-!write(6,*) 'nEdgesOnCell with HALO', iHalo, ' on block', nEdgescursor % block % blockID
-!         do i = 1, nEdgesCursor % dimSizes(1)
-!           write(6,*) i, nEdgesCursor % array(i) 
-!         end do
-!         nEdgesCursor =&gt; nEdgesCursor % next
-!       end do
-!
-!       cellsOnCellCursor =&gt; cellsOnCell
-!       do while(associated(cellsOnCellCursor))
-!write(6,*) 'cellsOnCell with HALO', iHalo,' on block ', cellsOnCellCursor % block % blockID
-!         do i = 1, cellsOnCellCursor % dimSizes(2)
-!           write(6,*) i, cellsOnCellCursor % array(:,i)
-!         end do
-!         cellsOnCellCursor =&gt; cellsOnCellCursor % next
-!       end do
-
-
+       ! Deallocate haloindices field
        call mpas_deallocate_field(haloIndices)
      end do ! iHalo loop over nHalos
 
+     ! Deallocate array and field.
      deallocate(sendingHaloLayers)
      call mpas_deallocate_field(offSetField)
 
    end subroutine mpas_block_creator_build_cell_halos!}}}
 
+!***********************************************************************
+!
+!  routine mpas_block_creator_build_vertex_halos
+!
+!&gt; \brief   Builds vertex halos
+!&gt; \author  Doug Jacobsen
+!&gt; \date    05/31/12
+!&gt; \version SVN:$Id$
+!&gt; \details 
+!&gt;  This routine uses the previously setup 0 and 1 vertex fields and 0 halo cell fields to determine
+!&gt;  which vertices fall in each halo layer for a block. During this process, each
+!&gt;  halo's exchange lists are created. This process is performed for all blocks on
+!&gt;  a processor. 
+!&gt;  NOTE: This routine can be used on either vertices or edges
+!
+!-----------------------------------------------------------------------
+
    subroutine mpas_block_creator_build_vertex_halos(indexToCellID, nEdgesOnCell, nCellsSolve, verticesOnCell, indexToVertexID, cellsOnVertex, nVerticesSolve)!{{{
      type (field1dInteger), pointer :: indexToCellID !&lt; Input: indexToCellID field for all halos
      type (field1dInteger), pointer :: nEdgesOnCell !&lt; Input: nEdgesOnCell field for all halos
@@ -731,11 +811,22 @@
 
      ! Allocate some needed arrays and fields
      allocate(sendingHaloLayers(1))
-     allocate(haloIndices)
-     allocate(offSetField)
-     allocate(vertexLimitField)
+     if(associated(indexToVertexID)) then
+       allocate(haloIndices)
+       allocate(offSetField)
+       allocate(vertexLimitField)
 
+       nullify(haloIndices % next)
+       nullify(offSetField % next)
+       nullify(vertexLimitField % next)
+     else
+       nullify(haloIndices)
+       nullify(offSetField)
+       nullify(vertexLimitField)
+     end if
+
      ! Determine number of blocks, and setup field lists
+     ! Loop over blocks
      nBlocks = 0
      indexToVertexCursor =&gt; indexToVertexID
      haloCursor =&gt; haloIndices
@@ -745,21 +836,26 @@
      do while(associated(indexToVertexCursor))
        nBlocks = nBlocks + 1
 
+       ! Setup vertexLimit and offSet
        vertexLimitCursor % scalar = nVerticesSolveCursor % array(1)
        offSetCursor % scalar = nVerticesSolveCursor % array(2)
 
+       ! Link blocks
        vertexLimitCursor % block =&gt; indexToVertexCursor % block
        offSetCursor % block =&gt; indexToVertexCursor % block
        haloCursor % block =&gt; indexToVertexCursor % block
 
+       ! Nullify ioinfo
        nullify(vertexLimitCursor % ioinfo)
        nullify(offSetCursor % ioinfo)
        nullify(haloCursor % ioinfo)
 
+       ! Link exchange lists
        haloCursor % sendList =&gt; indexToVertexCursor % sendList
        haloCursor % recvList =&gt; indexToVertexCursor % recvList
        haloCursor % copyList =&gt; indexToVertexCursor % copyList
 
+       ! Advance cursors and create new blocks if needed
        indexToVertexCursor =&gt; indexToVertexCursor % next
        nVerticesSolveCursor =&gt; nVerticesSolveCursor % next
        if(associated(indexToVertexCursor)) then
@@ -772,6 +868,8 @@
          allocate(vertexLimitCursor % next)
          vertexLimitCursor =&gt;vertexLimitCursor % next
        end if
+
+       ! Nullify next pointers
        nullify(haloCursor % next)
        nullify(offSetCursor % next)
        nullify(vertexLimitCursor % next)
@@ -800,6 +898,8 @@
      ! Append new unique vertex id's to indexToVertexID field.
      do iHalo = 3, nHalos+2
        sendingHaloLayers(1) = iHalo-1
+
+       ! Loop over blocks
        indexToVertexCursor =&gt; indexToVertexID
        nEdgesCursor =&gt; nEdgesOnCell
        nCellsSolveCursor =&gt; nCellsSolve
@@ -812,7 +912,7 @@
          nCellsInBlock = nCellsSolveCursor % array(iHalo-1)
          offSetCursor % scalar = nVerticesSolveCursor % array(iHalo-1)
   
-!        call mpas_block_decomp_all_edges_in_block(maxEdges, nCellsInBlock, nEdgesCursor % array(1:nCellsInBlock), verticesOnCellCursor % array(:,1:nCellsInBlock), nVerticesLocal, localVertexList)
+         ! Determine all vertices in block
          call mpas_block_decomp_all_edges_in_block(maxEdges, nCellsInBlock, nEdgesCursor % array, verticesOnCellCursor % array, nVerticesLocal, localVertexList)
 
          nVerticesSolveCursor % array(iHalo) = nVerticesLocal
@@ -821,6 +921,7 @@
 
          allocate(haloCursor % array(haloCursor % dimSizes(1)))
 
+         ! Add all vertices into block, and figure out which are new vertices meaning they belong to the new halo layer
          j = 1
          do i = 1, nVerticesLocal
            if(.not. mpas_hash_search(vertexList(iBlock), localVertexList(i))) then
@@ -832,6 +933,7 @@
 
          deallocate(localVertexList)
 
+         ! Advance Cursors
          indexToVertexCursor =&gt; indexToVertexCursor % next
          nEdgesCursor =&gt; nEdgesCursor % next
          nCellsSolveCursor =&gt; nCellsSolveCursor % next
@@ -841,13 +943,16 @@
          offSetCursor =&gt; offSetCursor % next
        end do
 
+       ! Build current layers exchange list
        call mpas_dmpar_get_exch_list(iHalo-1, indexToVertexID, haloIndices, offSetField, vertexLimitField)
 
+       ! Loop over blocks
        indexToVertexCursor =&gt; indexToVertexID
        cellsOnVertexCursor =&gt; cellsOnVertex
        nVerticesSolveCursor =&gt; nVerticesSolve
        haloCursor =&gt; haloIndices
        do while(associated(indexToVertexCursor))
+         ! Copy in new halo indices
          array1dHolder =&gt; indexToVertexCursor % array
          indexToVertexCursor % dimSizes(1) = nVerticesSolveCursor % array(iHalo)
          allocate(indexToVertexCursor % array(indexToVertexCursor % dimSizes(1)))
@@ -855,20 +960,24 @@
          indexToVertexCursor % array(nVerticesSolveCursor % array(iHalo-1)+1:nVerticesSolveCursor % array(iHalo)) = haloCursor % array(:)
          deallocate(array1dHolder)
 
+         ! Allocate space in cellsOnVertex
          array2dHolder =&gt; cellsOnVertexCursor % array
          cellsOnVertexCursor % dimSizes(2) = nVerticesSolveCursor % array(iHalo)
          allocate(cellsOnVertexCursor % array(cellsOnVertexCursor % dimSizes(1), cellsOnVertexCursor % dimSizes(2)))
          cellsOnVertexCursor % array(:,1:nVerticesSolveCursor % array(iHalo-1)) = array2dHolder(:,:)
          deallocate(array2dHolder)
 
+         ! Deallocate haloCursor array
          deallocate(haloCursor % array)
 
+         ! Advance cursors
          indexToVertexCursor =&gt; indexToVertexCursor % next
          cellsOnVertexCursor =&gt; cellsOnVertexCursor % next
          nVerticesSolveCursor =&gt; nVerticesSolveCursor % next
          haloCursor =&gt; haloCursor % next
        end do
 
+       ! Performe allToAll communication
        call mpas_dmpar_alltoall_field(cellsOnVertex, cellsOnVertex, sendingHaloLayers)
      end do
 
@@ -885,47 +994,272 @@
 
    end subroutine mpas_block_creator_build_vertex_halos!}}}
 
-
 !***********************************************************************
 !
-!  routine mpas_get_halo_cells_and_exchange_lists
+!  routine mpas_block_creator_finalize_block_init
 !
-!&gt; \brief   Determines cell indices for each halo layer, and builds exchange lists
+!&gt; \brief   Finalize block creation
 !&gt; \author  Doug Jacobsen
-!&gt; \date    04/30/12
+!&gt; \date    05/31/12
 !&gt; \version SVN:$Id$
 !&gt; \details 
-!&gt;  This routine builds the field indexToCellID_nHalos, which is an array of nHalos linked lists.
-!&gt;  Each index in indexToCellID_nHalos represnts a linked list of cells in a given halo.
-!&gt;  It creates the exchange lists for cells, and places them in the block structure.
-!&gt;  In order to call this routine, there are some assumptions made.
-!&gt;  The first assumption is that the 1 index of each array is setup correctly, 
-!&gt;      ie block pointers are valid, dimSizes are valid, next pointers are valid, ets
-!&gt;  The second assumption is that the arrays in each field are allocated and full with their appropriate information.
-!&gt;  These assumptions lead to the conclusion that the 0 halo has to be properly setup prior to calling this routine.
+!&gt;  This routine finalizes the block initialization processor. It calls
+!&gt;  mpas_block_allocate to allocate space for all fields in a block. Then the 0
+!&gt;  halo indices for each element and the exchange lists are copied into the
+!&gt;  appropriate block. A halo update is required after this routien is called
+!&gt;  to make sure all data in a block is valid.
 !
 !-----------------------------------------------------------------------
 
+   subroutine mpas_block_creator_finalize_block_init(blocklist, maxEdges, maxEdges2, vertexDegree, nVertLevels, nCellsSolve, nEdgesSolve, nVerticesSolve, indexToCellID, indexToEdgeID, indexToVertexID)!{{{
+     type (block_type), pointer :: blocklist !&lt; Input/Output: Linked List of blocks
+     integer :: maxEdges !&lt; Input: maxEdges dimension
+     integer :: maxEdges2 !&lt; Input: maxEdges2 dimension
+     integer :: vertexDegree !&lt; Input: vertexDegree dimension
+     integer :: nVertLevels !&lt; Input: nVertLEvels dimension
+     type (field1dInteger), pointer :: nCellsSolve !&lt; Input: nCellsSolve field information
+     type (field1dInteger), pointer :: nEdgesSolve !&lt; Input: nEdgesSolve field information
+     type (field1dInteger), pointer :: nVerticesSolve !&lt; Input: nVerticesSolve field information
+     type (field1dInteger), pointer :: indexToCellID !&lt; Input: indexToCellID field information
+     type (field1dInteger), pointer :: indexToEdgeID !&lt; Input: indexToEdgeID field information
+     type (field1dInteger), pointer :: indexToVertexID !&lt; Input: indexToVertexID field information
+
+     type (domain_type), pointer :: domain
+
+     type (block_type), pointer :: block_ptr
+     type (field1dInteger), pointer :: nCellsCursor, nEdgesCursor, nVerticesCursor
+     type (field1dInteger), pointer :: indexToCellCursor, indexToEdgeCursor, indexToVertexCursor
+
+     integer :: nCells, nVertices, nEdges, nHalos
+     integer :: nCellsSolve_0Halo, nVerticesSolve_0Halo, nEdgesSolve_0Halo
+     integer :: blockID, localBlockID
+
+     nHalos = config_num_halos
+     domain =&gt; blocklist % domain
+
+     ! Loop over blocks
+     block_ptr =&gt; blocklist
+     nCellsCursor =&gt; nCellsSolve
+     nEdgesCursor =&gt; nEdgesSolve
+     nVerticesCursor =&gt; nVerticesSolve
+     indexToCellCursor =&gt; indexToCellID
+     indexToEdgeCursor =&gt; indexToEdgeID
+     indexToVertexCursor =&gt; indexToVertexID
+     do while(associated(block_ptr))
+       ! Determine block dimensions
+       nCells = nCellsCursor % array(nHalos+1)
+       nEdges = nEdgesCursor % array(nHalos+2)
+       nVertices = nVerticesCursor % array(nHalos+2)
+
+       nCellsSolve_0Halo = nCellsCursor % array(1)
+       nEdgesSolve_0Halo = nEdgesCursor % array(1)
+       nVerticesSolve_0Halo = nVerticesCursor % array(1)
+
+       ! Determine block IDs
+       blockID = block_ptr % blockID
+       localBlockID = block_ptr % localBlockID
+
+       ! Allocate fields in block
+       call mpas_allocate_block(nHalos, block_ptr, domain, blockID, &amp;
+#include &quot;dim_dummy_args.inc&quot;
+                               )
+
+       ! Set block's local id
+       block_ptr % localBlockID = localBlockID
+
+       ! Set block's *Solve dimensions
+       block_ptr % mesh % nCellsSolve = nCellsSolve_0Halo
+       block_ptr % mesh % nEdgesSolve = nEdgesSolve_0Halo
+       block_ptr % mesh % nVerticesSolve = nVerticesSolve_0Halo
+
+       ! Set block's 0 halo indices
+       block_ptr % mesh % indexToCellID % array(1:nCellsSolve_0Halo) = indexToCellCursor % array(1:nCellsSolve_0Halo)
+       block_ptr % mesh % indexToEdgeID % array(1:nEdgesSolve_0Halo) = indexToEdgeCursor % array(1:nEdgesSolve_0Halo)
+       block_ptr % mesh % indexToVertexID % array(1:nVerticesSolve_0Halo) = indexToVertexCursor % array(1:nVerticesSolve_0Halo)
+
+       ! Set block's exchange lists and nullify unneeded exchange lists
+       block_ptr % parinfo % cellsToSend =&gt; indexToCellCursor % sendList
+       block_ptr % parinfo % cellsToRecv =&gt; indexToCellCursor % recvList
+       block_ptr % parinfo % cellsToCopy =&gt; indexToCellCursor % copyList
+       nullify(indexToCellCursor % sendList)
+       nullify(indexToCellCursor % recvList)
+       nullify(indexToCellCursor % copyList)
+
+       block_ptr % parinfo % edgesToSend =&gt; indexToEdgeCursor % sendList
+       block_ptr % parinfo % edgesToRecv =&gt; indexToEdgeCursor % recvList
+       block_ptr % parinfo % edgesToCopy =&gt; indexToEdgeCursor % copyList
+       nullify(indexToEdgeCursor % sendList)
+       nullify(indexToEdgeCursor % recvList)
+       nullify(indexToEdgeCursor % copyList)
+
+       block_ptr % parinfo % verticesToSend =&gt; indexToVertexCursor % sendList
+       block_ptr % parinfo % verticesToRecv =&gt; indexToVertexCursor % recvList
+       block_ptr % parinfo % verticesToCopy =&gt; indexToVertexCursor % copyList
+       nullify(indexToVertexCursor % sendList)
+       nullify(indexToVertexCursor % recvList)
+       nullify(indexToVertexCursor % copyList)
+
+       ! Advance cursors
+       block_ptr =&gt; block_ptr % next
+       nCellsCursor =&gt; nCellsCursor % next
+       nEdgesCursor =&gt; nEdgesCursor % next
+       nVerticesCursor =&gt; nVerticesCursor % next
+       indexToCellCursor =&gt; indexToCellCursor % next
+       indexToEdgeCursor =&gt; indexToEdgeCursor % next
+       indexToVertexCursor =&gt; indextoVertexcursor % next
+     end do
+
+     ! Link fields between blocks
+     block_ptr =&gt; blocklist
+     do while(associated(block_ptr))
+       call mpas_create_field_links(block_ptr)
+
+       block_ptr =&gt; block_ptr % next
+     end do
+   end subroutine mpas_block_creator_finalize_block_init!}}}
+
 !***********************************************************************
 !
-!  routine mpas_get_vertex_ids_and_exchange_lists
+!  routine mpas_block_creator_reindex_block_fields
 !
-!&gt; \brief   Determines vertex indices for each halo layer, and builds exchange lists
+!&gt; \brief   Reindex mesh connectivity arrays
 !&gt; \author  Doug Jacobsen
-!&gt; \date    05/01/12
+!&gt; \date    05/31/12
 !&gt; \version SVN:$Id$
 !&gt; \details 
-!&gt;  This routine fills in the arrays for the indexToVertexID_0Halo, and indexToVertexID_nHalos
-!&gt;  indexToVertexID_0Halo represents all vertices in the 0 halo, while indexToVertexID_nHalos represnts
-!&gt;  the vertex id's for all vertices in all other halos. It is an array of linked lists where each
-!&gt;  index represents the linked list of vertex ids at that halo layer.
-!&gt;  It creates the exchange lists for vertices, and places them in the block structure.
-!&gt;  In order to call this routine, there are some assumptions made.
-!&gt;  The first assumption is that the 1 index of each array is setup correctly, 
-!&gt;      ie block pointers are valid, dimSizes are valid, next pointers are valid, ets
-!&gt;  The second assumption is that the arrays in each field are allocated and full with their appropriate information.
-!&gt;  These assumptions lead to the conclusion that the 0 halo has to be properly setup prior to calling this routine.
+!&gt;  This routine re-indexes the connectivity arrays for the mesh data
+!&gt;  structure. Prior to this routine, all indices are given as global index (which
+!&gt;  can later be found in the indexTo* arrays). After this routine is called,
+!&gt;  indices are provided as local indices now (1:nCells+1 ... etc).
 !
 !-----------------------------------------------------------------------
 
+   subroutine mpas_block_creator_reindex_block_fields(blocklist)!{{{
+       type (block_type), pointer :: blocklist !&lt; Input/Output: Linked list of blocks
+
+     type (block_type), pointer :: block_ptr
+
+     integer :: i, j, k
+     integer, dimension(:,:), pointer :: cellIDSorted, edgeIDSorted, vertexIDSorted
+
+     ! Loop over blocks
+     block_ptr =&gt; blocklist
+     do while(associated(block_ptr))
+       !
+       ! Rename vertices in cellsOnCell, edgesOnCell, etc. to local indices
+       !
+       allocate(cellIDSorted(2, block_ptr % mesh % nCells))
+       allocate(edgeIDSorted(2, block_ptr % mesh % nEdges))
+       allocate(vertexIDSorted(2, block_ptr % mesh % nVertices))

+       do i=1,block_ptr % mesh % nCells
+         cellIDSorted(1,i) = block_ptr % mesh % indexToCellID % array(i)
+         cellIDSorted(2,i) = i
+       end do
+       call quicksort(block_ptr % mesh % nCells, cellIDSorted)

+       do i=1,block_ptr % mesh % nEdges
+         edgeIDSorted(1,i) = block_ptr % mesh % indexToEdgeID % array(i)
+         edgeIDSorted(2,i) = i
+       end do
+       call quicksort(block_ptr % mesh % nEdges, edgeIDSorted)

+       do i=1,block_ptr % mesh % nVertices
+         vertexIDSorted(1,i) = block_ptr % mesh % indexToVertexID % array(i)
+         vertexIDSorted(2,i) = i
+       end do
+       call quicksort(block_ptr % mesh % nVertices, vertexIDSorted)


+       do i=1,block_ptr % mesh % nCells
+         do j=1,block_ptr % mesh % nEdgesOnCell % array(i)
+           k = mpas_binary_search(cellIDSorted, 2, 1, block_ptr % mesh % nCells, &amp;
+                                  block_ptr % mesh % cellsOnCell % array(j,i))
+           if (k &lt;= block_ptr % mesh % nCells) then
+             block_ptr % mesh % cellsOnCell % array(j,i) = cellIDSorted(2,k)
+           else
+             block_ptr % mesh % cellsOnCell % array(j,i) = block_ptr % mesh % nCells + 1
+           end if

+           k = mpas_binary_search(edgeIDSorted, 2, 1, block_ptr % mesh % nEdges, &amp;
+                                  block_ptr % mesh % edgesOnCell % array(j,i))
+           if (k &lt;= block_ptr % mesh % nEdges) then
+             block_ptr % mesh % edgesOnCell % array(j,i) = edgeIDSorted(2,k)
+           else
+             block_ptr % mesh % edgesOnCell % array(j,i) = block_ptr % mesh % nEdges + 1
+           end if
+  
+           k = mpas_binary_search(vertexIDSorted, 2, 1, block_ptr % mesh % nVertices, &amp;
+                                  block_ptr % mesh % verticesOnCell % array(j,i))
+           if (k &lt;= block_ptr % mesh % nVertices) then
+             block_ptr % mesh % verticesOnCell % array(j,i) = vertexIDSorted(2,k)
+           else
+             block_ptr % mesh % verticesOnCell % array(j,i) = block_ptr % mesh % nVertices + 1
+           end if
+         end do
+       end do
+  
+       do i=1,block_ptr % mesh % nEdges
+         do j=1,2
+  
+           k = mpas_binary_search(cellIDSorted, 2, 1, block_ptr % mesh % nCells, &amp;
+                                  block_ptr % mesh % cellsOnEdge % array(j,i))
+           if (k &lt;= block_ptr % mesh % nCells) then
+             block_ptr % mesh % cellsOnEdge % array(j,i) = cellIDSorted(2,k)
+           else
+             block_ptr % mesh % cellsOnEdge % array(j,i) = block_ptr % mesh % nCells + 1
+           end if
+  
+           k = mpas_binary_search(vertexIDSorted, 2, 1, block_ptr % mesh % nVertices, &amp;
+                                  block_ptr % mesh % verticesOnEdge % array(j,i))
+           if (k &lt;= block_ptr % mesh % nVertices) then
+             block_ptr % mesh % verticesOnEdge % array(j,i) = vertexIDSorted(2,k)
+           else
+             block_ptr % mesh % verticesOnEdge % array(j,i) = block_ptr % mesh % nVertices + 1
+           end if
+  
+         end do
+  
+         do j=1,block_ptr % mesh % nEdgesOnEdge % array(i)
+  
+           k = mpas_binary_search(edgeIDSorted, 2, 1, block_ptr % mesh % nEdges, &amp;
+                                  block_ptr % mesh % edgesOnEdge % array(j,i))
+           if (k &lt;= block_ptr % mesh % nEdges) then
+             block_ptr % mesh % edgesOnEdge % array(j,i) = edgeIDSorted(2,k)
+           else
+             block_ptr % mesh % edgesOnEdge % array(j,i) = block_ptr % mesh % nEdges + 1
+           end if
+         end do
+       end do
+  
+       do i=1,block_ptr % mesh % nVertices
+         do j=1,block_ptr % mesh % vertexDegree
+  
+           k = mpas_binary_search(cellIDSorted, 2, 1, block_ptr % mesh % nCells, &amp;
+                                  block_ptr % mesh % cellsOnVertex % array(j,i))
+           if (k &lt;= block_ptr % mesh % nCells) then
+             block_ptr % mesh % cellsOnVertex % array(j,i) = cellIDSorted(2,k)
+           else
+             block_ptr % mesh % cellsOnVertex % array(j,i) = block_ptr % mesh % nCells + 1
+           end if
+  
+           k = mpas_binary_search(edgeIDSorted, 2, 1, block_ptr % mesh % nEdges, &amp;
+                             block_ptr % mesh % edgesOnVertex % array(j,i))
+           if (k &lt;= block_ptr % mesh % nEdges) then
+             block_ptr % mesh % edgesOnVertex % array(j,i) = edgeIDSorted(2,k)
+           else
+             block_ptr % mesh % edgesOnVertex % array(j,i) = block_ptr % mesh % nEdges + 1
+           end if
+         end do
+       end do
+  
+       deallocate(cellIDSorted)
+       deallocate(edgeIDSorted)
+       deallocate(vertexIDSorted)
+
+       block_ptr =&gt; block_ptr % next
+     end do
+
+   end subroutine mpas_block_creator_reindex_block_fields!}}}
+
 end module mpas_block_creator

Modified: branches/omp_blocks/multiple_blocks/src/framework/mpas_dmpar.F
===================================================================
--- branches/omp_blocks/multiple_blocks/src/framework/mpas_dmpar.F        2012-05-30 21:41:48 UTC (rev 1950)
+++ branches/omp_blocks/multiple_blocks/src/framework/mpas_dmpar.F        2012-05-31 19:28:35 UTC (rev 1951)
@@ -4222,6 +4222,8 @@
      integer :: nHalos
      integer :: i
 
+     nHalos = size(exchList % halos)
+
      do i = 1, nHalos
        call mpas_dmpar_destroy_exchange_list(exchList % halos(i) % exchList)
      end do

Modified: branches/omp_blocks/multiple_blocks/src/framework/mpas_io_input.F
===================================================================
--- branches/omp_blocks/multiple_blocks/src/framework/mpas_io_input.F        2012-05-30 21:41:48 UTC (rev 1950)
+++ branches/omp_blocks/multiple_blocks/src/framework/mpas_io_input.F        2012-05-31 19:28:35 UTC (rev 1951)
@@ -72,13 +72,13 @@
       type (field2dInteger), pointer :: cellsOnEdgeField
       type (field2dInteger), pointer :: cellsOnVertexField
 
-#ifdef HAVE_ZOLTAN
-#ifdef _MPI 
+!#ifdef HAVE_ZOLTAN
+!#ifdef _MPI 
       type (field1dReal), pointer :: xCellField,   yCellField,   zCellField
       type (field1dReal), pointer :: xEdgeField,   yEdgeField,   zEdgeField
       type (field1dReal), pointer :: xVertexField, yVertexField, zVertexField
-#endif
-#endif
+!#endif
+!#endif
 
       type (field1DChar) :: xtime
 
@@ -122,13 +122,13 @@
 
       type (field1DInteger), pointer :: indexToEdgeID_tList
 
-#ifdef HAVE_ZOLTAN
-#ifdef _MPI 
+!#ifdef HAVE_ZOLTAN
+!#ifdef _MPI 
       type (field1DReal), pointer :: xCell, yCell, zCell
       type (field1DReal), pointer :: xEdge, yEdge, zEdge
       type (field1DReal), pointer :: xVertex, yVertex, zVertex
-#endif
-#endif
+!#endif
+!#endif
    
       integer, dimension(:,:), pointer :: cellIDSorted, vertexIDSorted, edgeIDSorted
       integer, dimension(:), pointer :: local_cell_list, local_edge_list, local_vertex_list
@@ -170,35 +170,32 @@
 
       nHalos = config_num_halos
 
-
       if (config_do_restart) then
+        ! this get followed by set is to ensure that the time is in standard format
+        call mpas_set_time(curr_time=startTime, dateTimeString=config_start_time)
+        call mpas_get_time(curr_time=startTime, dateTimeString=timeStamp)
 
-         ! this get followed by set is to ensure that the time is in standard format
-         call mpas_set_time(curr_time=startTime, dateTimeString=config_start_time)
-         call mpas_get_time(curr_time=startTime, dateTimeString=timeStamp)
+        call mpas_insert_string_suffix(trim(config_restart_name), timeStamp, filename)
 
-         call mpas_insert_string_suffix(trim(config_restart_name), timeStamp, filename)
-
-         input_obj % filename = trim(filename)
-         input_obj % stream = STREAM_RESTART
+        input_obj % filename = trim(filename)
+        input_obj % stream = STREAM_RESTART
       else
-         input_obj % filename = trim(config_input_name)
-         input_obj % stream = STREAM_INPUT
+        input_obj % filename = trim(config_input_name)
+        input_obj % stream = STREAM_INPUT
       end if
       inputHandle = MPAS_io_open(trim(input_obj % filename), MPAS_IO_READ, MPAS_IO_PNETCDF, ierr)
       if (ierr /= MPAS_IO_NOERR) then
-         write(0,*) ' '
-         if (input_obj % stream == STREAM_RESTART) then
-            write(0,*) 'Error opening restart file ''', trim(input_obj % filename), ''''
-         else if (input_obj % stream == STREAM_INPUT) then
-            write(0,*) 'Error opening input file ''', trim(input_obj % filename), ''''
-         else if (input_obj % stream == STREAM_SFC) then
-            write(0,*) 'Error opening sfc file ''', trim(input_obj % filename), ''''
-         end if
-         write(0,*) ' '
-         call mpas_dmpar_abort(domain % dminfo)
+        write(0,*) ' '
+        if (input_obj % stream == STREAM_RESTART) then
+          write(0,*) 'Error opening restart file ''', trim(input_obj % filename), ''''
+        else if (input_obj % stream == STREAM_INPUT) then
+          write(0,*) 'Error opening input file ''', trim(input_obj % filename), ''''
+        else if (input_obj % stream == STREAM_SFC) then
+          write(0,*) 'Error opening sfc file ''', trim(input_obj % filename), ''''
+        end if
+        write(0,*) ' '
+        call mpas_dmpar_abort(domain % dminfo)
       end if
-   
 
       !
       ! Read global number of cells/edges/vertices
@@ -226,413 +223,19 @@
       readingBlock % domain =&gt; domain
       readingBlock % blockID = domain % dminfo % my_proc_id
       readingBlock % localBlockID = 0
-   
-   
+
       !
       ! Allocate and read fields that we will need in order to ultimately work out
       !   which cells/edges/vertices are owned by each block, and which are ghost
       !
 
-      ! Global cell indices
-      allocate(indexToCellIDField)
-      allocate(indexToCellIDField % ioinfo)
-      indexToCellIDField % ioinfo % fieldName = 'indexToCellID'
-      indexToCellIDField % ioinfo % start(1) = readCellStart
-      indexToCellIDField % ioinfo % count(1) = nReadCells
-      allocate(indexToCellIDField % array(nReadCells))
-      allocate(readIndices(nReadCells))
-      do i=1,nReadCells
-         readIndices(i) = i + readCellStart - 1
-      end do
-      call MPAS_io_inq_var(inputHandle, 'indexToCellID', ierr=ierr)
-      call MPAS_io_set_var_indices(inputHandle, 'indexToCellID', readIndices, ierr=ierr)
-      call mpas_io_get_var(inputHandle, 'indexToCellID', indexToCellIDField % array, ierr)
-      indexToCellIDField % dimSizes(1) = nReadCells
-      indexToCellIDField % block =&gt; readingBlock
-!     call mpas_dmpar_init_multihalo_exchange_list(indexToCellIDField % sendList, nHalos)
-!     call mpas_dmpar_init_mulithalo_exchange_list(indexToCellIDField % recvList, nHalos)
-!     call mpas_dmpar_init_multihalo_exchange_list(indexToCellIDField % copyList, nHalos)
-      allocate(indexToCellIDField % sendList)
-      allocate(indexToCellIDField % recvList)
-      allocate(indexToCellIDField % copyList)
-      allocate(indexToCellIDField % sendList % halos(nHalos))
-      allocate(indexToCellIDField % recvList % halos(nHalos))
-      allocate(indexToCellIDField % copyList % halos(nHalos))
-      do i = 1, nHalos
-        nullify(indexToCellIDField % sendList % halos(i) % exchList)
-        nullify(indexToCellIDField % recvList % halos(i) % exchList)
-        nullify(indexToCellIDField % copyList % halos(i) % exchList)
-      end do
-      nullify(indexToCellIDField % next)
-   
-#ifdef HAVE_ZOLTAN
-#ifdef _MPI 
-      ! Cell x-coordinates (in 3d Cartesian space)
-      allocate(xCellField)
-      allocate(xCellField % ioinfo)
-      xCellField % ioinfo % fieldName = 'xCell'
-      xCellField % ioinfo % start(1) = readCellStart
-      xCellField % ioinfo % count(1) = nReadCells
-      allocate(xCellField % array(nReadCells))
-      call MPAS_io_inq_var(inputHandle, 'xCell', ierr=ierr)
-      call MPAS_io_set_var_indices(inputHandle, 'xCell', readIndices, ierr=ierr)
-      call mpas_io_get_var(inputHandle, 'xCell', xCellField % array, ierr)
-      xCellField % dimSizes(1) = nReadCells
-      xCellField % block =&gt; readingBlock
-      xCellField % sendList =&gt; indexToCellIDField % sendList
-      xCellField % recvList =&gt; indexToCellIDField % recvList
-      xCellField % copyList =&gt; indexToCellIDField % copyList
-      nullify(xCellField % next)
+      call mpas_io_setup_cell_block_fields(inputHandle, nreadCells, readCellStart, readingBlock, maxEdges, indexTocellIDField, xCellField, &amp;
+                                           yCellField, zCellField, nEdgesOnCellField, cellsOnCellField, edgesOnCellField, verticesOnCellField)
 
-      ! Cell y-coordinates (in 3d Cartesian space)
-      allocate(yCellField)
-      allocate(yCellField % ioinfo)
-      yCellField % ioinfo % fieldName = 'yCell'
-      yCellField % ioinfo % start(1) = readCellStart
-      yCellField % ioinfo % count(1) = nReadCells
-      allocate(yCellField % array(nReadCells))
-      call MPAS_io_inq_var(inputHandle, 'yCell', ierr=ierr)
-      call MPAS_io_set_var_indices(inputHandle, 'yCell', readIndices, ierr=ierr)
-      call mpas_io_get_var(inputHandle, 'yCell', yCellField % array, ierr)
-      yCellField % sendList =&gt; indexToCellIDField % sendList
-      yCellField % recvList =&gt; indexToCellIDField % recvList
-      yCellField % copyList =&gt; indexToCellIDField % copyList
-      yCellField % dimSizes(1) = nReadCells
-      yCellField % block =&gt; readingBlock
-      nullify(yCellField % next)
+      call mpas_io_setup_edge_block_fields(inputHandle, nReadEdges, readEdgeStart, readingBlock, indexToEdgeIDField, xEdgeField, yEdgeField, zEdgeField, cellsOnEdgeField)
 
-      ! Cell z-coordinates (in 3d Cartesian space)
-      allocate(zCellField)
-      allocate(zCellField % ioinfo)
-      zCellField % ioinfo % fieldName = 'zCell'
-      zCellField % ioinfo % start(1) = readCellStart
-      zCellField % ioinfo % count(1) = nReadCells
-      allocate(zCellField % array(nReadCells))
-      call MPAS_io_inq_var(inputHandle, 'zCell', ierr=ierr)
-      call MPAS_io_set_var_indices(inputHandle, 'zCell', readIndices, ierr=ierr)
-      call mpas_io_get_var(inputHandle, 'zCell', zCellField % array, ierr)
-      zCellField % dimSizes(1) = nReadCells
-      zCellField % block =&gt; readingBlock
-      zCellField % sendList =&gt; indexToCellIDField % sendList
-      zCellField % recvList =&gt; indexToCellIDField % recvList
-      zCellField % copyList =&gt; indexToCellIDField % copyList
-      nullify(zCellField % next)
-#endif
-#endif
-      deallocate(readIndices)
-
-
-      ! Global edge indices
-      allocate(indexToEdgeIDField)
-      allocate(indexToEdgeIDField % ioinfo)
-      indexToEdgeIDField % ioinfo % fieldName = 'indexToEdgeID'
-      indexToEdgeIDField % ioinfo % start(1) = readEdgeStart
-      indexToEdgeIDField % ioinfo % count(1) = nReadEdges
-      allocate(indexToEdgeIDField % array(nReadEdges))
-      allocate(indexToEdgeIDField % array(nReadEdges))
-      allocate(readIndices(nReadEdges))
-      do i=1,nReadEdges
-         readIndices(i) = i + readEdgeStart - 1
-      end do
-      call MPAS_io_inq_var(inputHandle, 'indexToEdgeID', ierr=ierr)
-      call MPAS_io_set_var_indices(inputHandle, 'indexToEdgeID', readIndices, ierr=ierr)
-      call mpas_io_get_var(inputHandle, 'indexToEdgeID', indexToEdgeIDField % array, ierr)
-      indexToEdgeIDField % dimSizes(1) = nREadEdges
-      indexToEdgeIDField % block =&gt; readingBlock
-      allocate(indexToEdgeIDField % sendList)
-      allocate(indexToEdgeIDField % recvList)
-      allocate(indexToEdgeIDField % copyList)
-      allocate(indexToEdgeIDField % sendList % halos(nHalos))
-      allocate(indexToEdgeIDField % recvList % halos(nHalos))
-      allocate(indexToEdgeIDField % copyList % halos(nHalos))
-      do i = 1, nHalos
-        nullify(indexToEdgeIDField % sendList % halos(i) % exchList)
-        nullify(indexToEdgeIDField % recvList % halos(i) % exchList)
-        nullify(indexToEdgeIDField % copyList % halos(i) % exchList)
-      end do
-      nullify(indexToEdgeIDField % next)
-   
-#ifdef HAVE_ZOLTAN
-#ifdef _MPI 
-      ! Edge x-coordinates (in 3d Cartesian space)
-      allocate(xEdgeField)
-      allocate(xEdgeField % ioinfo)
-      xEdgeField % ioinfo % fieldName = 'xEdge'
-      xEdgeField % ioinfo % start(1) = readEdgeStart
-      xEdgeField % ioinfo % count(1) = nReadEdges
-      allocate(xEdgeField % array(nReadEdges))
-      call MPAS_io_inq_var(inputHandle, 'xEdge', ierr=ierr)
-      call MPAS_io_set_var_indices(inputHandle, 'xEdge', readIndices, ierr=ierr)
-      call mpas_io_get_var(inputHandle, 'xEdge', xEdgeField % array, ierr)
-      xEdgeField % dimSizes(1) = nReadEdges
-      xEdgeField % block =&gt; readingBlock
-      xEdgeField % sendList =&gt; indexToEdgeIDField % sendList
-      xEdgeField % recvList =&gt; indexToEdgeIDField % recvList
-      xEdgeField % copyList =&gt; indexToEdgeIDField % copyList
-      nullify(xEdgeField % next)
-
-      ! Edge y-coordinates (in 3d Cartesian space)
-      allocate(yEdgeField)
-      allocate(yEdgeField % ioinfo)
-      yEdgeField % ioinfo % fieldName = 'yEdge'
-      yEdgeField % ioinfo % start(1) = readEdgeStart
-      yEdgeField % ioinfo % count(1) = nReadEdges
-      allocate(yEdgeField % array(nReadEdges))
-      call MPAS_io_inq_var(inputHandle, 'yEdge', ierr=ierr)
-      call MPAS_io_set_var_indices(inputHandle, 'yEdge', readIndices, ierr=ierr)
-      call mpas_io_get_var(inputHandle, 'yEdge', yEdgeField % array, ierr)
-      yEdgeField % dimSizes(1) = nReadEdges
-      yEdgeField % block =&gt; readingBlock
-      yEdgeField % sendList =&gt; indexToEdgeIDField % sendList
-      yEdgeField % recvList =&gt; indexToEdgeIDField % recvList
-      yEdgeField % copyList =&gt; indexToEdgeIDField % copyList
-      nullify(yEdgeField % next)
-
-      ! Edge z-coordinates (in 3d Cartesian space)
-      allocate(zEdgeField)
-      allocate(zEdgeField % ioinfo)
-      zEdgeField % ioinfo % fieldName = 'zEdge'
-      zEdgeField % ioinfo % start(1) = readEdgeStart
-      zEdgeField % ioinfo % count(1) = nReadEdges
-      allocate(zEdgeField % array(nReadEdges))
-      call MPAS_io_inq_var(inputHandle, 'zEdge', ierr=ierr)
-      call MPAS_io_set_var_indices(inputHandle, 'zEdge', readIndices, ierr=ierr)
-      call mpas_io_get_var(inputHandle, 'zEdge', zEdgeField % array, ierr)
-      zEdgeField % dimSizes(1) = nReadEdges
-      zEdgeField % block =&gt; readingBlock
-      zEdgeField % sendList =&gt; indexToEdgeIDField % sendList
-      zEdgeField % recvList =&gt; indexToEdgeIDField % recvList
-      zEdgeField % copyList =&gt; indexToEdgeIDField % copyList
-      nullify(zEdgeField % next)
-#endif
-#endif
-      deallocate(readIndices)
-
-
-      ! Global vertex indices
-      allocate(indexToVertexIDField)
-      allocate(indexToVertexIDField % ioinfo)
-      indexToVertexIDField % ioinfo % fieldName = 'indexToVertexID'
-      indexToVertexIDField % ioinfo % start(1) = readVertexStart
-      indexToVertexIDField % ioinfo % count(1) = nReadVertices
-      allocate(indexToVertexIDField % array(nReadVertices))
-      allocate(readIndices(nReadVertices))
-      do i=1,nReadVertices
-         readIndices(i) = i + readVertexStart - 1
-      end do
-      call MPAS_io_inq_var(inputHandle, 'indexToVertexID', ierr=ierr)
-      call MPAS_io_set_var_indices(inputHandle, 'indexToVertexID', readIndices, ierr=ierr)
-      call mpas_io_get_var(inputHandle, 'indexToVertexID', indexToVertexIDField % array, ierr)
-      indexToVertexIDField % dimSizes(1) = nReadVertices
-      indexToVertexIDField % block =&gt; readingBlock
-      allocate(indexToVertexIDField % sendList)
-      allocate(indexToVertexIDField % recvList)
-      allocate(indexToVertexIDField % copyList)
-      allocate(indexToVertexIDField % sendList % halos(nHalos))
-      allocate(indexToVertexIDField % recvList % halos(nHalos))
-      allocate(indexToVertexIDField % copyList % halos(nHalos))
-      do i = 1, nHalos
-        nullify(indexToVertexIDField % sendList % halos(i) % exchList) 
-        nullify(indexToVertexIDField % recvList % halos(i) % exchList)
-        nullify(indexToVertexIDField % copyList % halos(i) % exchList)
-      end do
-      nullify(indexToVertexIDField % next)
-   
-#ifdef HAVE_ZOLTAN
-#ifdef _MPI
-      ! Vertex x-coordinates (in 3d Cartesian space)
-      allocate(xVertexField)
-      allocate(xVertexField % ioinfo)
-      xVertexField % ioinfo % fieldName = 'xVertex'
-      xVertexField % ioinfo % start(1) = readVertexStart
-      xVertexField % ioinfo % count(1) = nReadVertices
-      allocate(xVertexField % array(nReadVertices))
-      call MPAS_io_inq_var(inputHandle, 'xVertex', ierr=ierr)
-      call MPAS_io_set_var_indices(inputHandle, 'xVertex', readIndices, ierr=ierr)
-      call mpas_io_get_var(inputHandle, 'xVertex', xVertexField % array, ierr)
-      xVertexField % dimSizes(1) = nReadVertices
-      xVertexField % block =&gt; readingBlock
-      xVertexField % sendList =&gt; indexToVertexIDField % sendList
-      xVertexField % recvList =&gt; indexToVertexIDField % recvList
-      xVertexField % copyList =&gt; indexToVertexIDField % copyList
-      nullify(xVertexField % next)
-
-      ! Vertex y-coordinates (in 3d Cartesian space)
-      allocate(yVertexField)
-      allocate(yVertexField % ioinfo)
-      yVertexField % ioinfo % fieldName = 'yVertex'
-      yVertexField % ioinfo % start(1) = readVertexStart
-      yVertexField % ioinfo % count(1) = nReadVertices
-      allocate(yVertexField % array(nReadVertices))
-      call MPAS_io_inq_var(inputHandle, 'yVertex', ierr=ierr)
-      call MPAS_io_set_var_indices(inputHandle, 'yVertex', readIndices, ierr=ierr)
-      call mpas_io_get_var(inputHandle, 'yVertex', yVertexField % array, ierr)
-      yVertexField % dimSizes(1) = nReadVertices
-      yVertexField % block =&gt; readingBlock
-      yVertexField % sendList =&gt; indexToVertexIDField % sendList
-      yVertexField % recvList =&gt; indexToVertexIDField % recvList
-      yVertexField % copyList =&gt; indexToVertexIDField % copyList
-      nullify(yVertexField % next)
-
-      ! Vertex z-coordinates (in 3d Cartesian space)
-      allocate(zVertexField)
-      allocate(zVertexField % ioinfo)
-      zVertexField % ioinfo % fieldName = 'zVertex'
-      zVertexField % ioinfo % start(1) = readVertexStart
-      zVertexField % ioinfo % count(1) = nReadVertices
-      allocate(zVertexField % array(nReadVertices))
-      call MPAS_io_inq_var(inputHandle, 'zVertex', ierr=ierr)
-      call MPAS_io_set_var_indices(inputHandle, 'zVertex', readIndices, ierr=ierr)
-      call mpas_io_get_var(inputHandle, 'zVertex', zVertexField % array, ierr)
-      zVertexField % dimSizes(1) = nReadVertices
-      zVertexField % block =&gt; readingBlock
-      zVertexField % sendList =&gt; indexToVertexIDField % sendList
-      zVertexField % recvList =&gt; indexToVertexIDField % recvList
-      zVertexField % copyList =&gt; indexToVertexIDField % copyList
-      nullify(zVertexField % next)
-#endif
-#endif
-      deallocate(readIndices)
-
-      ! Number of cell/edges/vertices adjacent to each cell
-      allocate(nEdgesOnCellField)
-      allocate(nEdgesOnCellField % ioinfo)
-      nEdgesOnCellField % ioinfo % fieldName = 'nEdgesOnCell'
-      nEdgesOnCellField % ioinfo % start(1) = readCellStart
-      nEdgesOnCellField % ioinfo % count(1) = nReadCells
-      allocate(nEdgesOnCellField % array(nReadCells))
-      allocate(readIndices(nReadCells))
-      do i=1,nReadCells
-         readIndices(i) = i + readCellStart - 1
-      end do
-      call MPAS_io_inq_var(inputHandle, 'nEdgesOnCell', ierr=ierr)
-      call MPAS_io_set_var_indices(inputHandle, 'nEdgesOnCell', readIndices, ierr=ierr)
-      call mpas_io_get_var(inputHandle, 'nEdgesOnCell', nEdgesOnCellField % array, ierr)
-      nEdgesOnCellField % dimSizes(1) = nReadCells
-      nEdgesOnCellField % block =&gt; readingBlock
-      nEdgesOnCellField % sendList =&gt; indexToCellIDField % sendList
-      nEdgesOnCellField % recvList =&gt; indexToCellIDField % recvList
-      nEdgesOnCellField % copyList =&gt; indexToCellIDField % copyList
-      nullify(nEdgesOnCellField % next)
-   
-      ! Global indices of cells adjacent to each cell
-      allocate(cellsOnCellField)
-      allocate(cellsOnCellField % ioinfo)
-      cellsOnCellField % ioinfo % fieldName = 'cellsOnCell'
-      cellsOnCellField % ioinfo % start(1) = 1
-      cellsOnCellField % ioinfo % start(2) = readCellStart
-      cellsOnCellField % ioinfo % count(1) = maxEdges
-      cellsOnCellField % ioinfo % count(2) = nReadCells
-      allocate(cellsOnCellField % array(maxEdges,nReadCells))
-      call MPAS_io_inq_var(inputHandle, 'cellsOnCell', ierr=ierr)
-      call MPAS_io_set_var_indices(inputHandle, 'cellsOnCell', readIndices, ierr=ierr)
-      call mpas_io_get_var(inputHandle, 'cellsOnCell', cellsOnCellField % array, ierr)
-      cellsOnCellField % dimSizes(1) = maxEdges
-      cellsOnCellField % dimSizes(2) = nReadCells
-      cellsOnCellField % block =&gt; readingBlock
-      cellsOnCellField % sendList =&gt; indexToCellIDField % sendList
-      cellsOnCellField % recvList =&gt; indexToCellIDField % recvList
-      cellsOnCellField % copyList =&gt; indexToCellIDField % copyList
-      nullify(cellsOnCellField % next)
-   
-      ! Global indices of edges adjacent to each cell
-      allocate(edgesOnCellField)
-      allocate(edgesOnCellField % ioinfo)
-      edgesOnCellField % ioinfo % fieldName = 'edgesOnCell'
-      edgesOnCellField % ioinfo % start(1) = 1
-      edgesOnCellField % ioinfo % start(2) = readCellStart
-      edgesOnCellField % ioinfo % count(1) = maxEdges
-      edgesOnCellField % ioinfo % count(2) = nReadCells
-      allocate(edgesOnCellField % array(maxEdges,nReadCells))
-      call MPAS_io_inq_var(inputHandle, 'edgesOnCell', ierr=ierr)
-      call MPAS_io_set_var_indices(inputHandle, 'edgesOnCell', readIndices, ierr=ierr)
-      call mpas_io_get_var(inputHandle, 'edgesOnCell', edgesOnCellField % array, ierr)
-      edgesOnCellField % dimSizes(1) = maxEdges
-      edgesOnCellField % dimSizes(2) = nReadCells
-      edgesOnCellField % block =&gt; readingBlock
-      edgesOnCellField % sendList =&gt; indexToCellIDField % sendList
-      edgesOnCellField % recvList =&gt; indexToCellIDField % recvList
-      edgesOnCellField % copyList =&gt; indexToCellIDField % copyList
-      nullify(edgesOnCellField % next)
-   
-      ! Global indices of vertices adjacent to each cell
-      allocate(verticesOnCellField)
-      allocate(verticesOnCellField % ioinfo)
-      verticesOnCellField % ioinfo % fieldName = 'verticesOnCell'
-      verticesOnCellField % ioinfo % start(1) = 1
-      verticesOnCellField % ioinfo % start(2) = readCellStart
-      verticesOnCellField % ioinfo % count(1) = maxEdges
-      verticesOnCellField % ioinfo % count(2) = nReadCells
-      allocate(verticesOnCellField % array(maxEdges,nReadCells))
-      call MPAS_io_inq_var(inputHandle, 'verticesOnCell', ierr=ierr)
-      call MPAS_io_set_var_indices(inputHandle, 'verticesOnCell', readIndices, ierr=ierr)
-      call mpas_io_get_var(inputHandle, 'verticesOnCell', verticesOnCellField % array, ierr)
-      deallocate(readIndices)
-      verticesOnCellField % dimSizes(1) = maxEdges
-      verticesOnCellField % dimSizes(2) = nReadCells
-      verticesOnCellField % block =&gt; readingBlock
-      verticesOnCellField % sendList =&gt; indexToCellIDField % sendList
-      verticesOnCellField % recvList =&gt; indexToCellIDField % recvList
-      verticesOnCellField % copyList =&gt; indexToCellIDField % copyList
-      nullify(verticesOnCellField % next)
-
-
-   
-      ! Global indices of cells adjacent to each edge
-      !    used for determining which edges are owned by a block, where 
-      !    iEdge is owned iff cellsOnEdge(1,iEdge) is an owned cell
-      allocate(cellsOnEdgeField)
-      allocate(cellsOnEdgeField % ioinfo)
-      cellsOnEdgeField % ioinfo % fieldName = 'cellsOnEdge'
-      cellsOnEdgeField % ioinfo % start(1) = 1
-      cellsOnEdgeField % ioinfo % start(2) = readEdgeStart
-      cellsOnEdgeField % ioinfo % count(1) = 2
-      cellsOnEdgeField % ioinfo % count(2) = nReadEdges
-      allocate(cellsOnEdgeField % array(2,nReadEdges))
-      allocate(readIndices(nReadEdges))
-      do i=1,nReadEdges
-         readIndices(i) = i + readEdgeStart - 1
-      end do
-      call MPAS_io_inq_var(inputHandle, 'cellsOnEdge', ierr=ierr)
-      call MPAS_io_set_var_indices(inputHandle, 'cellsOnEdge', readIndices, ierr=ierr)
-      call mpas_io_get_var(inputHandle, 'cellsOnEdge', cellsOnEdgeField % array, ierr)
-      deallocate(readIndices)
-      cellsOnEdgeField % dimSizes(1) = 2
-      cellsOnEdgeField % dimSizes(2) = nReadEdges
-      cellsOnEdgeField % block =&gt; readingBlock
-      cellsOnEdgeField % sendList =&gt; indexToEdgeIDField % sendList
-      cellsOnEdgeField % recvList =&gt; indexToEdgeIDField % recvList
-      cellsOnEdgeField % copyList =&gt; indexToEdgeIDField % copyList
-      nullify(cellsOnEdgeField % next)
-
-   
-      ! Global indices of cells adjacent to each vertex
-      !    used for determining which vertices are owned by a block, where 
-      !    iVtx is owned iff cellsOnVertex(1,iVtx) is an owned cell
-      allocate(cellsOnVertexField)
-      allocate(cellsOnVertexField % ioinfo)
-      cellsOnVertexField % ioinfo % fieldName = 'cellsOnVertex'
-      cellsOnVertexField % ioinfo % start(1) = 1
-      cellsOnVertexField % ioinfo % start(2) = readVertexStart
-      cellsOnVertexField % ioinfo % count(1) = vertexDegree
-      cellsOnVertexField % ioinfo % count(2) = nReadVertices
-      allocate(cellsOnVertexField % array(vertexDegree,nReadVertices))
-      allocate(readIndices(nReadVertices))
-      do i=1,nReadVertices
-         readIndices(i) = i + readVertexStart - 1
-      end do
-      call MPAS_io_inq_var(inputHandle, 'cellsOnVertex', ierr=ierr)
-      call MPAS_io_set_var_indices(inputHandle, 'cellsOnVertex', readIndices, ierr=ierr)
-      call mpas_io_get_var(inputHandle, 'cellsOnVertex', cellsOnVertexField % array, ierr)
-      cellsOnVertexField % dimSizes(1) = vertexDegree
-      cellsOnVertexField % dimSizes(2) = nReadVertices
-      cellsOnVertexField % block =&gt; readingBlock
-      cellsOnVertexField % sendList =&gt; indexToVertexIDField % sendList
-      cellsOnVertexField % recvList =&gt; indexToVertexIDField % recvList
-      cellsOnVertexField % copyList =&gt; indexToVertexIDField % copyList
-      nullify(cellsOnVertexField % next)
-      deallocate(readIndices)
-
+      call mpas_io_setup_vertex_block_fields(inputHandle, nReadVertices, readVertexStart, readingBlock, vertexDegree, indexToVertexIDField, &amp;
+                                             xVertexField, yVertexField, zVertexField, cellsOnVertexField)
       !
       ! Set up a graph derived data type describing the connectivity for the cells 
       !   that were read by this process
@@ -651,7 +254,6 @@
       partial_global_graph_info % vertexID(:) = indexToCellIDField % array(:)
       partial_global_graph_info % nAdjacent(:) = nEdgesOnCellField % array(:)
       partial_global_graph_info % adjacencyList(:,:) = cellsOnCellField % array(:,:)
-      
    
       ! TODO: Ensure (by renaming or exchanging) that initial cell range on each proc is contiguous
       !       This situation may occur when reading a restart file with cells/edges/vertices written
@@ -689,6 +291,7 @@
       write(6,*) 'Building vertex halos', nHalos
       call mpas_block_creator_build_vertex_halos(indexToCellID_0Halo, nEdgesOnCell_0Halo, nCellsSolveField, edgesOnCell_0Halo, indexToEdgeID_0Halo, cellsOnEdge_0Halo, nEdgesSolveField)
 
+      ! DWJ DEBUGGING
 !     int1d_ptr =&gt; nCellsSolveField
 !     do while(associated(int1d_ptr))
 !       write(6,*) 'nCellsSolve on block', int1d_ptr % block % localBlockID
@@ -719,65 +322,17 @@
 !       int1d_ptr =&gt; int1d_ptr % next
 !     end do
 
-      ! Allocate blocks, and copy indexTo arrays into blocks
-      write(6,*) 'Allocate blocks, and copy indexTo arrays into blocks'
+     ! Allocate blocks, and copy indexTo arrays into blocks
+     write(6,*) 'Allocate blocks, and copy indexTo arrays into blocks'
+     call mpas_block_creator_finalize_block_init(domain % blocklist, maxEdges, maxEdges2, vertexDegree, nVertLevels, nCellsSolveField, nEdgesSolveField, nVerticesSolveField, indexToCellID_0Halo, indexToEdgeID_0Halo, indexToVertexID_0Halo)
+
+      write(6,*) 'initializing input object'
       block_ptr =&gt; domain % blocklist
-      int1d_ptr =&gt; nCellsSolveField
-      int1d_ptr2 =&gt; nVerticesSolveField
-      int1d_ptr3 =&gt; nEdgesSolveField
-      indexToCellCursor =&gt; indexToCellID_0Halo
-      indexToVertexCursor =&gt; indexToVertexID_0Halo
-      indexToEdgeCursor =&gt; indexToEdgeID_0Halo
       do while(associated(block_ptr))
-        nCells = int1d_ptr % array(nHalos+1)
-        nVertices = int1d_ptr2 % array(nHalos+2)
-        nEdges = int1d_ptr3 % array(nHalos+2)
-
-        call mpas_allocate_block(nHalos, block_ptr, domain , block_ptr % blockID, &amp;
-#include &quot;dim_dummy_args.inc&quot;
-                                )
-
-        block_ptr % mesh % indexToCellID % array(1:int1d_ptr % array(1)) = indexToCellCursor % array(1:int1d_ptr % array(1))
-        block_ptr % mesh % indexToVertexID % array(1:int1d_ptr2 % array(1)) = indexToVertexCursor % array(1:int1d_ptr2 % array(1))
-        block_ptr % mesh % indexToEdgeID % array(1:int1d_ptr3 % array(1)) = indexToEdgeCursor % array(1:int1d_ptr3 % array(1))
-
-        block_ptr % parinfo % cellsToSend =&gt; indexToCellCursor % sendList
-        block_ptr % parinfo % cellsToRecv =&gt; indexToCellCursor % recvList
-        block_ptr % parinfo % cellsToCopy =&gt; indexToCellCursor % copyList
-        nullify(indexToCellCursor % sendList)
-        nullify(indexToCellCursor % recvList)
-        nullify(indexToCellCursor % copyList)
-
-        block_ptr % parinfo % verticesToSend =&gt; indexToVertexCursor % sendList
-        block_ptr % parinfo % verticesToRecv =&gt; indexToVertexCursor % recvList
-        block_ptr % parinfo % verticesToCopy =&gt; indexToVertexCursor % copyList
-        nullify(indexToVertexCursor % sendList)
-        nullify(indexToVertexCursor % recvList)
-        nullify(indexToVertexCursor % copyList)
-        
-        block_ptr % parinfo % edgesToSend =&gt; indexToEdgeCursor % sendList
-        block_ptr % parinfo % edgesToRecv =&gt; indexToEdgeCursor % recvList
-        block_ptr % parinfo % edgesToCopy =&gt; indexToEdgeCursor % copyList
-        nullify(indexToEdgeCursor % sendList)
-        nullify(indexToEdgeCursor % recvList)
-        nullify(indexToEdgeCursor % copyList)
-
-        block_ptr % mesh % nCellsSolve = int1d_ptr % array(1)
-        block_ptr % mesh % nVerticesSolve = int1d_ptr2 % array(1)
-        block_ptr % mesh % nEdgesSolve = int1d_ptr3 % array(1)
-
+        call mpas_io_input_init(input_obj, block_ptr, domain % dminfo)
         block_ptr =&gt; block_ptr % next
-        int1d_ptr =&gt; int1d_ptr % next
-        int1d_ptr2 =&gt; int1d_ptr2 % next
-        int1d_ptr3 =&gt; int1d_ptr3 % next
-        indexToCellCursor =&gt; indexToCellCursor % next
-        indexToVertexCursor =&gt; indexToVertexCursor % next
-        indexToEdgeCursor =&gt; indexToEdgeCursor % next
       end do
 
-      write(6,*) 'initializing input object'
-      call mpas_io_input_init(input_obj, domain % blocklist, domain % dminfo)
-
       write(6,*) 'getting file attributes'
       call MPAS_readStreamAtt(input_obj % io_stream, 'sphere_radius', r_sphere_radius, ierr)
       if (ierr /= MPAS_STREAM_NOERR) then
@@ -832,6 +387,23 @@
         write(0,*) 'Restarting model from time ', timeStamp
       end if
 
+      !DWJ DEBUGGING
+      write(6,*) 'BLOCK LOOP 1'
+      block_ptr =&gt; domain % blocklist
+      do while(associated(block_ptr))
+        write(6,*) 'nEdges', block_ptr % mesh % nEdges
+        write(6,*) 'nEdgesSolve', block_ptr % mesh % nEdgesSolve
+        write(6,*) 'indexToCellID on block', block_ptr % blockID
+        do i = 1, block_ptr % mesh % nCells
+          write(6,*) i, block_ptr % mesh % indexToCellID % array(i)
+        end do
+        write(6,*) 'edgesOnCell on block', block_ptr % blockID
+        do i = 1, block_ptr % mesh % nCells
+          write(6,*) i, block_ptr % mesh % edgesOnCell % array(:, i)
+        end do
+        block_ptr =&gt; block_ptr % next
+      end do
+
       !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
       ! Do the actual work of reading all fields in from the input or restart file
       ! For each field:
@@ -850,16 +422,19 @@
       call MPAS_io_close(inputHandle, ierr)
 
       !DWJ DEBUGGING
-!     write(6,*) 'nEdges', domain % blockList % mesh % nEdges
-!     write(6,*) 'nEdgesSolve', domain % blockList % mesh % nEdgesSolve
-!     write(6,*) 'indexToCellID 1'
-!     do i = 1, domain % blockList % mesh % nCells
-!       write(6,*) i, domain % blocklist % mesh % indexToCellID % array(i)
-!     end do
-!     write(6,*) 'edgesOnCell 1'
-!     do i = 1, domain % blockList % mesh % nCells
-!       write(6,*) i, domain % blocklist % mesh % edgesOnCell % array(:, i)
-!     end do
+      write(6,*) 'BLOCK LOOP 2'
+      block_ptr =&gt; domain % blocklist
+      do while(associated(block_ptr))
+        write(6,*) 'indexToCellID on block', block_ptr % blockID
+        do i = 1, block_ptr % mesh % nCells
+          write(6,*) i, block_ptr % mesh % indexToCellID % array(i)
+        end do
+        write(6,*) 'edgesOnCell on block', block_ptr % blockID
+        do i = 1, block_ptr % mesh % nCells
+          write(6,*) i, block_ptr % mesh % edgesOnCell % array(:, i)
+        end do
+        block_ptr =&gt; block_ptr % next
+      end do
 
       !
       ! Exchange halos for all of the fields that were read from the input file
@@ -868,143 +443,45 @@
       call mpas_exch_input_field_halos(domain, input_obj)
 
       !DWJ DEBUGGING
-!     write(6,*) 'indexToCellID 2'
-!     do i = 1, domain % blockList % mesh % nCells
-!       write(6,*) i, domain % blocklist % mesh % indexToCellID % array(i)
-!     end do
-!     write(6,*) 'edgesOnCell 2'
-!     do i = 1, domain % blockList % mesh % nCells
-!       write(6,*) i, domain % blocklist % mesh % edgesOnCell % array(:, i)
-!     end do
-
-      write(6,*) 're-index fields'
+      write(6,*) 'BLOCK LOOP 3'
       block_ptr =&gt; domain % blocklist
       do while(associated(block_ptr))
-        !
-        ! Rename vertices in cellsOnCell, edgesOnCell, etc. to local indices
-        !
-        allocate(cellIDSorted(2, block_ptr % mesh % nCells))
-        allocate(edgeIDSorted(2, block_ptr % mesh % nEdges))
-        allocate(vertexIDSorted(2, block_ptr % mesh % nVertices))
-  
-        do i=1,block_ptr % mesh % nCells
-           cellIDSorted(1,i) = block_ptr % mesh % indexToCellID % array(i)
-           cellIDSorted(2,i) = i
+        write(6,*) 'indexToCellID on block', block_ptr % blockID
+        do i = 1, block_ptr % mesh % nCells
+          write(6,*) i, block_ptr % mesh % indexToCellID % array(i)
         end do
-        call quicksort(block_ptr % mesh % nCells, cellIDSorted)
-  
-        do i=1,block_ptr % mesh % nEdges
-           edgeIDSorted(1,i) = block_ptr % mesh % indexToEdgeID % array(i)
-           edgeIDSorted(2,i) = i
+        write(6,*) 'edgesOnCell on block', block_ptr % blockID
+        do i = 1, block_ptr % mesh % nCells
+          write(6,*) i, block_ptr % mesh % edgesOnCell % array(:, i)
         end do
-        call quicksort(block_ptr % mesh % nEdges, edgeIDSorted)
-  
-        do i=1,block_ptr % mesh % nVertices
-           vertexIDSorted(1,i) = block_ptr % mesh % indexToVertexID % array(i)
-           vertexIDSorted(2,i) = i
-        end do
-        call quicksort(block_ptr % mesh % nVertices, vertexIDSorted)
-  
-  
-        do i=1,block_ptr % mesh % nCells
-           do j=1,block_ptr % mesh % nEdgesOnCell % array(i)
-              k = mpas_binary_search(cellIDSorted, 2, 1, block_ptr % mesh % nCells, &amp;
-                                block_ptr % mesh % cellsOnCell % array(j,i))
-              if (k &lt;= block_ptr % mesh % nCells) then
-                 block_ptr % mesh % cellsOnCell % array(j,i) = cellIDSorted(2,k)
-              else
-                 block_ptr % mesh % cellsOnCell % array(j,i) = block_ptr % mesh % nCells + 1
-              end if
-  
-!             write(6,*) 'searching for edge', block_ptr % mesh % edgesOnCell % array(j,i)
-              k = mpas_binary_search(edgeIDSorted, 2, 1, block_ptr % mesh % nEdges, &amp;
-                                block_ptr % mesh % edgesOnCell % array(j,i))
-              if (k &lt;= block_ptr % mesh % nEdges) then
-                 block_ptr % mesh % edgesOnCell % array(j,i) = edgeIDSorted(2,k)
-              else
-!                write(6,*) 'Setting',block_ptr % mesh % edgesOnCell % array(j,i),'to',block_ptr % mesh % nEdges + 1
-                 block_ptr % mesh % edgesOnCell % array(j,i) = block_ptr % mesh % nEdges + 1
-              end if
-  
-              k = mpas_binary_search(vertexIDSorted, 2, 1, block_ptr % mesh % nVertices, &amp;
-                                block_ptr % mesh % verticesOnCell % array(j,i))
-              if (k &lt;= block_ptr % mesh % nVertices) then
-                 block_ptr % mesh % verticesOnCell % array(j,i) = vertexIDSorted(2,k)
-              else
-                 block_ptr % mesh % verticesOnCell % array(j,i) = block_ptr % mesh % nVertices + 1
-              end if
-           end do
-        end do
-  
-        do i=1,block_ptr % mesh % nEdges
-           do j=1,2
-  
-              k = mpas_binary_search(cellIDSorted, 2, 1, block_ptr % mesh % nCells, &amp;
-                                block_ptr % mesh % cellsOnEdge % array(j,i))
-              if (k &lt;= block_ptr % mesh % nCells) then
-                 block_ptr % mesh % cellsOnEdge % array(j,i) = cellIDSorted(2,k)
-              else
-                 block_ptr % mesh % cellsOnEdge % array(j,i) = block_ptr % mesh % nCells + 1
-              end if
-  
-              k = mpas_binary_search(vertexIDSorted, 2, 1, block_ptr % mesh % nVertices, &amp;
-                                block_ptr % mesh % verticesOnEdge % array(j,i))
-              if (k &lt;= block_ptr % mesh % nVertices) then
-                 block_ptr % mesh % verticesOnEdge % array(j,i) = vertexIDSorted(2,k)
-              else
-                 block_ptr % mesh % verticesOnEdge % array(j,i) = block_ptr % mesh % nVertices + 1
-              end if
-  
-           end do
-  
-           do j=1,block_ptr % mesh % nEdgesOnEdge % array(i)
-  
-              k = mpas_binary_search(edgeIDSorted, 2, 1, block_ptr % mesh % nEdges, &amp;
-                                block_ptr % mesh % edgesOnEdge % array(j,i))
-              if (k &lt;= block_ptr % mesh % nEdges) then
-                 block_ptr % mesh % edgesOnEdge % array(j,i) = edgeIDSorted(2,k)
-              else
-                 block_ptr % mesh % edgesOnEdge % array(j,i) = block_ptr % mesh % nEdges + 1
-              end if
-  
-           end do
-        end do
-  
-        do i=1,block_ptr % mesh % nVertices
-           do j=1,vertexDegree
-  
-              k = mpas_binary_search(cellIDSorted, 2, 1, block_ptr % mesh % nCells, &amp;
-                                block_ptr % mesh % cellsOnVertex % array(j,i))
-              if (k &lt;= block_ptr % mesh % nCells) then
-                 block_ptr % mesh % cellsOnVertex % array(j,i) = cellIDSorted(2,k)
-              else
-                 block_ptr % mesh % cellsOnVertex % array(j,i) = block_ptr % mesh % nCells + 1
-              end if
-  
-              k = mpas_binary_search(edgeIDSorted, 2, 1, block_ptr % mesh % nEdges, &amp;
-                                block_ptr % mesh % edgesOnVertex % array(j,i))
-              if (k &lt;= block_ptr % mesh % nEdges) then
-                 block_ptr % mesh % edgesOnVertex % array(j,i) = edgeIDSorted(2,k)
-              else
-                 block_ptr % mesh % edgesOnVertex % array(j,i) = block_ptr % mesh % nEdges + 1
-              end if
-  
-           end do
-        end do
-  
-        deallocate(cellIDSorted)
-        deallocate(edgeIDSorted)
-        deallocate(vertexIDSorted)
-
         block_ptr =&gt; block_ptr % next
       end do
 
+      call mpas_block_creator_reindex_block_fields(domain % blocklist)
+
       !DWJ DEBUGGING
-!     write(6,*) 'edgesOnCell 3'
-!     do i = 1, domain % blockList % mesh % nCells
-!       write(6,*) i, domain % blocklist % mesh % edgesOnCell % array(:, i)
-!     end do
+      write(6,*) 'BLOCK LOOP 4'
+      block_ptr =&gt; domain % blocklist
+      do while(associated(block_ptr))
+        write(6,*) 'edgesOnCell on block', block_ptr % blockID
+        do i = 1, block_ptr % mesh % nCells
+          write(6,*) i, block_ptr % mesh % edgesOnCell % array(:, i)
+        end do
+        block_ptr =&gt; block_ptr % next
+      end do
 
+      call mpas_dmpar_destroy_mulithalo_exchange_list(indexToCellIDField % sendList)
+      call mpas_dmpar_destroy_mulithalo_exchange_list(indexToCellIDField % recvList)
+      call mpas_dmpar_destroy_mulithalo_exchange_list(indexToCellIDField % copyList)
+
+      call mpas_dmpar_destroy_mulithalo_exchange_list(indexToEdgeIDField % sendList)
+      call mpas_dmpar_destroy_mulithalo_exchange_list(indexToEdgeIDField % recvList)
+      call mpas_dmpar_destroy_mulithalo_exchange_list(indexToEdgeIDField % copyList)
+
+      call mpas_dmpar_destroy_mulithalo_exchange_list(indexToVertexIDField % sendList)
+      call mpas_dmpar_destroy_mulithalo_exchange_list(indexToVertexIDField % recvList)
+      call mpas_dmpar_destroy_mulithalo_exchange_list(indexToVertexIDField % copyList)
+
       call mpas_deallocate_field(indexToCellIDField)
       call mpas_deallocate_field(indexToEdgeIDField)
       call mpas_deallocate_field(indexToVertexIDField)
@@ -1034,9 +511,6 @@
       deallocate(block_start)
       deallocate(block_count)
 
-!     write(6,*) 'Stopping'
-!     stop
-
 #ifdef HAVE_ZOLTAN
 #ifdef _MPI 
 !     allocate(xCell(size(local_cell_list)))
@@ -1293,5 +767,434 @@
       call MPAS_closeStream(input_obj % io_stream, nferr)
  
    end subroutine mpas_io_input_finalize!}}}
+
+   subroutine mpas_io_setup_cell_block_fields(inputHandle, nReadCells, readCellStart, readingBlock, maxEdges, indexToCellID, xCell, yCell, zCell, nEdgesOnCell, cellsOnCell, edgesOnCell, verticesOnCell)!{{{
+     type (MPAS_IO_Handle_type) :: inputHandle
+     integer, intent(in) :: nReadCells
+     integer, intent(in) :: readCellStart
+     integer, intent(in) :: maxEdges
+     type (block_type), pointer :: readingBlock
+     type (field1dInteger), pointer :: indexToCellID
+     type (field1dReal), pointer :: xCell
+     type (field1dReal), pointer :: yCell
+     type (field1dReal), pointer :: zCell
+     type (field1dInteger), pointer :: nEdgesOnCell
+     type (field2dInteger), pointer :: cellsOnCell
+     type (field2dInteger), pointer :: edgesOnCell
+     type (field2dInteger), pointer :: verticesOnCell
+
+     integer :: i, nHalos
+     integer, dimension(:), pointer :: readIndices
+
+     nHalos = config_num_halos
+  
+     !
+     ! Allocate and read fields that we will need in order to ultimately work out
+     !   which cells/edges/vertices are owned by each block, and which are ghost
+     !
+
+     ! Global cell indices
+     allocate(indexToCellID)
+     allocate(indexToCellID % ioinfo)
+     indexToCellID % ioinfo % fieldName = 'indexToCellID'
+     indexToCellID % ioinfo % start(1) = readCellStart
+     indexToCellID % ioinfo % count(1) = nReadCells
+     allocate(indexToCellID % array(nReadCells))
+     allocate(readIndices(nReadCells))
+     do i=1,nReadCells
+        readIndices(i) = i + readCellStart - 1
+     end do
+     call MPAS_io_inq_var(inputHandle, 'indexToCellID', ierr=ierr)
+     call MPAS_io_set_var_indices(inputHandle, 'indexToCellID', readIndices, ierr=ierr)
+     call mpas_io_get_var(inputHandle, 'indexToCellID', indexToCellID % array, ierr)
+     indexToCellID % dimSizes(1) = nReadCells
+     indexToCellID % block =&gt; readingBlock
+     call mpas_dmpar_init_mulithalo_exchange_list(indexToCellID % sendList, nHalos)
+     call mpas_dmpar_init_mulithalo_exchange_list(indexToCellID % recvList, nHalos)
+     call mpas_dmpar_init_mulithalo_exchange_list(indexToCellID % copyList, nHalos)
+     nullify(indexToCellID % next)
+   
+#ifdef HAVE_ZOLTAN
+#ifdef _MPI 
+     ! Cell x-coordinates (in 3d Cartesian space)
+     allocate(xCell)
+     allocate(xCell % ioinfo)
+     xCell % ioinfo % fieldName = 'xCell'
+     xCell % ioinfo % start(1) = readCellStart
+     xCell % ioinfo % count(1) = nReadCells
+     allocate(xCell % array(nReadCells))
+     call MPAS_io_inq_var(inputHandle, 'xCell', ierr=ierr)
+     call MPAS_io_set_var_indices(inputHandle, 'xCell', readIndices, ierr=ierr)
+     call mpas_io_get_var(inputHandle, 'xCell', xCell % array, ierr)
+     xCell % dimSizes(1) = nReadCells
+     xCell % block =&gt; readingBlock
+     xCell % sendList =&gt; indexToCellID % sendList
+     xCell % recvList =&gt; indexToCellID % recvList
+     xCell % copyList =&gt; indexToCellID % copyList
+     nullify(xCell % next)
+
+     ! Cell y-coordinates (in 3d Cartesian space)
+     allocate(yCell)
+     allocate(yCell % ioinfo)
+     yCell % ioinfo % fieldName = 'yCell'
+     yCell % ioinfo % start(1) = readCellStart
+     yCell % ioinfo % count(1) = nReadCells
+     allocate(yCell % array(nReadCells))
+     call MPAS_io_inq_var(inputHandle, 'yCell', ierr=ierr)
+     call MPAS_io_set_var_indices(inputHandle, 'yCell', readIndices, ierr=ierr)
+     call mpas_io_get_var(inputHandle, 'yCell', yCell % array, ierr)
+     yCell % sendList =&gt; indexToCellID % sendList
+     yCell % recvList =&gt; indexToCellID % recvList
+     yCell % copyList =&gt; indexToCellID % copyList
+     yCell % dimSizes(1) = nReadCells
+     yCell % block =&gt; readingBlock
+     nullify(yCell % next)
+
+     ! Cell z-coordinates (in 3d Cartesian space)
+     allocate(zCell)
+     allocate(zCell % ioinfo)
+     zCell % ioinfo % fieldName = 'zCell'
+     zCell % ioinfo % start(1) = readCellStart
+     zCell % ioinfo % count(1) = nReadCells
+     allocate(zCell % array(nReadCells))
+     call MPAS_io_inq_var(inputHandle, 'zCell', ierr=ierr)
+     call MPAS_io_set_var_indices(inputHandle, 'zCell', readIndices, ierr=ierr)
+     call mpas_io_get_var(inputHandle, 'zCell', zCell % array, ierr)
+     zCell % dimSizes(1) = nReadCells
+     zCell % block =&gt; readingBlock
+     zCell % sendList =&gt; indexToCellID % sendList
+     zCell % recvList =&gt; indexToCellID % recvList
+     zCell % copyList =&gt; indexToCellID % copyList
+     nullify(zCell % next)
+#endif
+#endif
+
+     ! Number of cell/edges/vertices adjacent to each cell
+     allocate(nEdgesOnCell)
+     allocate(nEdgesOnCell % ioinfo)
+     nEdgesOnCell % ioinfo % fieldName = 'nEdgesOnCell'
+     nEdgesOnCell % ioinfo % start(1) = readCellStart
+     nEdgesOnCell % ioinfo % count(1) = nReadCells
+     allocate(nEdgesOnCell % array(nReadCells))
+     call MPAS_io_inq_var(inputHandle, 'nEdgesOnCell', ierr=ierr)
+     call MPAS_io_set_var_indices(inputHandle, 'nEdgesOnCell', readIndices, ierr=ierr)
+     call mpas_io_get_var(inputHandle, 'nEdgesOnCell', nEdgesOnCell % array, ierr)
+     nEdgesOnCell % dimSizes(1) = nReadCells
+     nEdgesOnCell % block =&gt; readingBlock
+     nEdgesOnCell % sendList =&gt; indexToCellID % sendList
+     nEdgesOnCell % recvList =&gt; indexToCellID % recvList
+     nEdgesOnCell % copyList =&gt; indexToCellID % copyList
+     nullify(nEdgesOnCell % next)
+   
+     ! Global indices of cells adjacent to each cell
+     allocate(cellsOnCell)
+     allocate(cellsOnCell % ioinfo)
+     cellsOnCell % ioinfo % fieldName = 'cellsOnCell'
+     cellsOnCell % ioinfo % start(1) = 1
+     cellsOnCell % ioinfo % start(2) = readCellStart
+     cellsOnCell % ioinfo % count(1) = maxEdges
+     cellsOnCell % ioinfo % count(2) = nReadCells
+     allocate(cellsOnCell % array(maxEdges,nReadCells))
+     call MPAS_io_inq_var(inputHandle, 'cellsOnCell', ierr=ierr)
+     call MPAS_io_set_var_indices(inputHandle, 'cellsOnCell', readIndices, ierr=ierr)
+     call mpas_io_get_var(inputHandle, 'cellsOnCell', cellsOnCell % array, ierr)
+     cellsOnCell % dimSizes(1) = maxEdges
+     cellsOnCell % dimSizes(2) = nReadCells
+     cellsOnCell % block =&gt; readingBlock
+     cellsOnCell % sendList =&gt; indexToCellID % sendList
+     cellsOnCell % recvList =&gt; indexToCellID % recvList
+     cellsOnCell % copyList =&gt; indexToCellID % copyList
+     nullify(cellsOnCell % next)
+   
+     ! Global indices of edges adjacent to each cell
+     allocate(edgesOnCell)
+     allocate(edgesOnCell % ioinfo)
+     edgesOnCell % ioinfo % fieldName = 'edgesOnCell'
+     edgesOnCell % ioinfo % start(1) = 1
+     edgesOnCell % ioinfo % start(2) = readCellStart
+     edgesOnCell % ioinfo % count(1) = maxEdges
+     edgesOnCell % ioinfo % count(2) = nReadCells
+     allocate(edgesOnCell % array(maxEdges,nReadCells))
+     call MPAS_io_inq_var(inputHandle, 'edgesOnCell', ierr=ierr)
+     call MPAS_io_set_var_indices(inputHandle, 'edgesOnCell', readIndices, ierr=ierr)
+     call mpas_io_get_var(inputHandle, 'edgesOnCell', edgesOnCell % array, ierr)
+     edgesOnCell % dimSizes(1) = maxEdges
+     edgesOnCell % dimSizes(2) = nReadCells
+     edgesOnCell % block =&gt; readingBlock
+     edgesOnCell % sendList =&gt; indexToCellID % sendList
+     edgesOnCell % recvList =&gt; indexToCellID % recvList
+     edgesOnCell % copyList =&gt; indexToCellID % copyList
+     nullify(edgesOnCell % next)
+   
+     ! Global indices of vertices adjacent to each cell
+     allocate(verticesOnCell)
+     allocate(verticesOnCell % ioinfo)
+     verticesOnCell % ioinfo % fieldName = 'verticesOnCell'
+     verticesOnCell % ioinfo % start(1) = 1
+     verticesOnCell % ioinfo % start(2) = readCellStart
+     verticesOnCell % ioinfo % count(1) = maxEdges
+     verticesOnCell % ioinfo % count(2) = nReadCells
+     allocate(verticesOnCell % array(maxEdges,nReadCells))
+     call MPAS_io_inq_var(inputHandle, 'verticesOnCell', ierr=ierr)
+     call MPAS_io_set_var_indices(inputHandle, 'verticesOnCell', readIndices, ierr=ierr)
+     call mpas_io_get_var(inputHandle, 'verticesOnCell', verticesOnCell % array, ierr)
+     verticesOnCell % dimSizes(1) = maxEdges
+     verticesOnCell % dimSizes(2) = nReadCells
+     verticesOnCell % block =&gt; readingBlock
+     verticesOnCell % sendList =&gt; indexToCellID % sendList
+     verticesOnCell % recvList =&gt; indexToCellID % recvList
+     verticesOnCell % copyList =&gt; indexToCellID % copyList
+     nullify(verticesOnCell % next)
+
+     deallocate(readIndices)
+   
+   end subroutine mpas_io_setup_cell_block_fields!}}}
+
+   subroutine mpas_io_setup_edge_block_fields(inputHandle, nReadEdges, readEdgeStart, readingBlock, indexToEdgeID, xEdge, yEdge, zEdge, cellsOnEdge)!{{{
+     type (MPAS_IO_Handle_type) :: inputHandle
+     integer, intent(in) :: nReadEdges
+     integer, intent(in) :: readEdgeStart
+     type (block_type), pointer :: readingBlock
+     type (field1dInteger), pointer :: indexToEdgeID
+     type (field1dReal), pointer :: xEdge
+     type (field1dReal), pointer :: yEdge
+     type (field1dReal), pointer :: zEdge
+     type (field2dInteger), pointer :: cellsOnEdge
+
+     integer :: i, nHalos
+     integer, dimension(:), pointer :: readIndices
+
+     nHalos = config_num_halos
+  
+     !
+     ! Allocate and read fields that we will need in order to ultimately work out
+     !   which cells/edges/vertices are owned by each block, and which are ghost
+     !
+
+     allocate(readIndices(nReadEdges))
+
+     ! Global edge indices
+     allocate(indexToEdgeID)
+     allocate(indexToEdgeID % ioinfo)
+     indexToEdgeID % ioinfo % fieldName = 'indexToEdgeID'
+     indexToEdgeID % ioinfo % start(1) = readEdgeStart
+     indexToEdgeID % ioinfo % count(1) = nReadEdges
+     allocate(indexToEdgeID % array(nReadEdges))
+     allocate(indexToEdgeID % array(nReadEdges))
+     do i=1,nReadEdges
+        readIndices(i) = i + readEdgeStart - 1
+     end do
+     call MPAS_io_inq_var(inputHandle, 'indexToEdgeID', ierr=ierr)
+     call MPAS_io_set_var_indices(inputHandle, 'indexToEdgeID', readIndices, ierr=ierr)
+     call mpas_io_get_var(inputHandle, 'indexToEdgeID', indexToEdgeID % array, ierr)
+     indexToEdgeID % dimSizes(1) = nREadEdges
+     indexToEdgeID % block =&gt; readingBlock
+     call mpas_dmpar_init_mulithalo_exchange_list(indexToEdgeID % sendList, nHalos+1)
+     call mpas_dmpar_init_mulithalo_exchange_list(indexToEdgeID % recvList, nHalos+1)
+     call mpas_dmpar_init_mulithalo_exchange_list(indexToEdgeID % copyList, nHalos+1)
+     nullify(indexToEdgeID % next)
+   
+#ifdef HAVE_ZOLTAN
+#ifdef _MPI 
+     ! Edge x-coordinates (in 3d Cartesian space)
+     allocate(xEdge)
+     allocate(xEdge % ioinfo)
+     xEdge % ioinfo % fieldName = 'xEdge'
+     xEdge % ioinfo % start(1) = readEdgeStart
+     xEdge % ioinfo % count(1) = nReadEdges
+     allocate(xEdge % array(nReadEdges))
+     call MPAS_io_inq_var(inputHandle, 'xEdge', ierr=ierr)
+     call MPAS_io_set_var_indices(inputHandle, 'xEdge', readIndices, ierr=ierr)
+     call mpas_io_get_var(inputHandle, 'xEdge', xEdge % array, ierr)
+     xEdge % dimSizes(1) = nReadEdges
+     xEdge % block =&gt; readingBlock
+     xEdge % sendList =&gt; indexToEdgeID % sendList
+     xEdge % recvList =&gt; indexToEdgeID % recvList
+     xEdge % copyList =&gt; indexToEdgeID % copyList
+     nullify(xEdge % next)
+
+     ! Edge y-coordinates (in 3d Cartesian space)
+     allocate(yEdge)
+     allocate(yEdge % ioinfo)
+     yEdge % ioinfo % fieldName = 'yEdge'
+     yEdge % ioinfo % start(1) = readEdgeStart
+     yEdge % ioinfo % count(1) = nReadEdges
+     allocate(yEdge % array(nReadEdges))
+     call MPAS_io_inq_var(inputHandle, 'yEdge', ierr=ierr)
+     call MPAS_io_set_var_indices(inputHandle, 'yEdge', readIndices, ierr=ierr)
+     call mpas_io_get_var(inputHandle, 'yEdge', yEdge % array, ierr)
+     yEdge % dimSizes(1) = nReadEdges
+     yEdge % block =&gt; readingBlock
+     yEdge % sendList =&gt; indexToEdgeID % sendList
+     yEdge % recvList =&gt; indexToEdgeID % recvList
+     yEdge % copyList =&gt; indexToEdgeID % copyList
+     nullify(yEdge % next)
+
+     ! Edge z-coordinates (in 3d Cartesian space)
+     allocate(zEdge)
+     allocate(zEdge % ioinfo)
+     zEdge % ioinfo % fieldName = 'zEdge'
+     zEdge % ioinfo % start(1) = readEdgeStart
+     zEdge % ioinfo % count(1) = nReadEdges
+     allocate(zEdge % array(nReadEdges))
+     call MPAS_io_inq_var(inputHandle, 'zEdge', ierr=ierr)
+     call MPAS_io_set_var_indices(inputHandle, 'zEdge', readIndices, ierr=ierr)
+     call mpas_io_get_var(inputHandle, 'zEdge', zEdge % array, ierr)
+     zEdge % dimSizes(1) = nReadEdges
+     zEdge % block =&gt; readingBlock
+     zEdge % sendList =&gt; indexToEdgeID % sendList
+     zEdge % recvList =&gt; indexToEdgeID % recvList
+     zEdge % copyList =&gt; indexToEdgeID % copyList
+     nullify(zEdge % next)
+#endif
+#endif
+
+   
+     ! Global indices of cells adjacent to each edge
+     !    used for determining which edges are owned by a block, where 
+     !    iEdge is owned iff cellsOnEdge(1,iEdge) is an owned cell
+     allocate(cellsOnEdge)
+     allocate(cellsOnEdge % ioinfo)
+     cellsOnEdge % ioinfo % fieldName = 'cellsOnEdge'
+     cellsOnEdge % ioinfo % start(1) = 1
+     cellsOnEdge % ioinfo % start(2) = readEdgeStart
+     cellsOnEdge % ioinfo % count(1) = 2
+     cellsOnEdge % ioinfo % count(2) = nReadEdges
+     allocate(cellsOnEdge % array(2,nReadEdges))
+     call MPAS_io_inq_var(inputHandle, 'cellsOnEdge', ierr=ierr)
+     call MPAS_io_set_var_indices(inputHandle, 'cellsOnEdge', readIndices, ierr=ierr)
+     call mpas_io_get_var(inputHandle, 'cellsOnEdge', cellsOnEdge % array, ierr)
+     cellsOnEdge % dimSizes(1) = 2
+     cellsOnEdge % dimSizes(2) = nReadEdges
+     cellsOnEdge % block =&gt; readingBlock
+     cellsOnEdge % sendList =&gt; indexToEdgeID % sendList
+     cellsOnEdge % recvList =&gt; indexToEdgeID % recvList
+     cellsOnEdge % copyList =&gt; indexToEdgeID % copyList
+     nullify(cellsOnEdge % next)
+
+     deallocate(readIndices)
+   
+   end subroutine mpas_io_setup_edge_block_fields!}}}
+
+   subroutine mpas_io_setup_vertex_block_fields(inputHandle, nReadVertices, readVertexStart, readingBlock, vertexDegree, indexToVertexID, xVertex, yVertex, zVertex, cellsOnVertex)!{{{
+     type (MPAS_IO_Handle_type) :: inputHandle
+     integer, intent(in) :: nReadVertices
+     integer, intent(in) :: readVertexStart
+     integer, intent(in) :: vertexDegree
+     type (block_type), pointer :: readingBlock
+     type (field1dInteger), pointer :: indexToVertexID
+     type (field1dReal), pointer :: xVertex
+     type (field1dReal), pointer :: yVertex
+     type (field1dReal), pointer :: zVertex
+     type (field2dInteger), pointer :: cellsOnVertex
+
+     integer :: i, nHalos
+     integer, dimension(:), pointer :: readIndices
+
+     nHalos = config_num_halos
+  
+     ! Global vertex indices
+     allocate(indexToVertexID)
+     allocate(indexToVertexID % ioinfo)
+     indexToVertexID % ioinfo % fieldName = 'indexToVertexID'
+     indexToVertexID % ioinfo % start(1) = readVertexStart
+     indexToVertexID % ioinfo % count(1) = nReadVertices
+     allocate(indexToVertexID % array(nReadVertices))
+     allocate(readIndices(nReadVertices))
+     do i=1,nReadVertices
+        readIndices(i) = i + readVertexStart - 1
+     end do
+     call MPAS_io_inq_var(inputHandle, 'indexToVertexID', ierr=ierr)
+     call MPAS_io_set_var_indices(inputHandle, 'indexToVertexID', readIndices, ierr=ierr)
+     call mpas_io_get_var(inputHandle, 'indexToVertexID', indexToVertexID % array, ierr)
+     indexToVertexID % dimSizes(1) = nReadVertices
+     indexToVertexID % block =&gt; readingBlock
+     call mpas_dmpar_init_mulithalo_exchange_list(indexToVertexID % sendList, nHalos+1)
+     call mpas_dmpar_init_mulithalo_exchange_list(indexToVertexID % recvList, nHalos+1)
+     call mpas_dmpar_init_mulithalo_exchange_list(indexToVertexID % copyList, nHalos+1)
+     nullify(indexToVertexID % next)
+   
+#ifdef HAVE_ZOLTAN
+#ifdef _MPI
+     ! Vertex x-coordinates (in 3d Cartesian space)
+     allocate(xVertex)
+     allocate(xVertex % ioinfo)
+     xVertex % ioinfo % fieldName = 'xVertex'
+     xVertex % ioinfo % start(1) = readVertexStart
+     xVertex % ioinfo % count(1) = nReadVertices
+     allocate(xVertex % array(nReadVertices))
+     call MPAS_io_inq_var(inputHandle, 'xVertex', ierr=ierr)
+     call MPAS_io_set_var_indices(inputHandle, 'xVertex', readIndices, ierr=ierr)
+     call mpas_io_get_var(inputHandle, 'xVertex', xVertex % array, ierr)
+     xVertex % dimSizes(1) = nReadVertices
+     xVertex % block =&gt; readingBlock
+     xVertex % sendList =&gt; indexToVertexID % sendList
+     xVertex % recvList =&gt; indexToVertexID % recvList
+     xVertex % copyList =&gt; indexToVertexID % copyList
+     nullify(xVertex % next)
+
+     ! Vertex y-coordinates (in 3d Cartesian space)
+     allocate(yVertex)
+     allocate(yVertex % ioinfo)
+     yVertex % ioinfo % fieldName = 'yVertex'
+     yVertex % ioinfo % start(1) = readVertexStart
+     yVertex % ioinfo % count(1) = nReadVertices
+     allocate(yVertex % array(nReadVertices))
+     call MPAS_io_inq_var(inputHandle, 'yVertex', ierr=ierr)
+     call MPAS_io_set_var_indices(inputHandle, 'yVertex', readIndices, ierr=ierr)
+     call mpas_io_get_var(inputHandle, 'yVertex', yVertex % array, ierr)
+     yVertex % dimSizes(1) = nReadVertices
+     yVertex % block =&gt; readingBlock
+     yVertex % sendList =&gt; indexToVertexID % sendList
+     yVertex % recvList =&gt; indexToVertexID % recvList
+     yVertex % copyList =&gt; indexToVertexID % copyList
+     nullify(yVertex % next)
+
+     ! Vertex z-coordinates (in 3d Cartesian space)
+     allocate(zVertex)
+     allocate(zVertex % ioinfo)
+     zVertex % ioinfo % fieldName = 'zVertex'
+     zVertex % ioinfo % start(1) = readVertexStart
+     zVertex % ioinfo % count(1) = nReadVertices
+     allocate(zVertex % array(nReadVertices))
+     call MPAS_io_inq_var(inputHandle, 'zVertex', ierr=ierr)
+     call MPAS_io_set_var_indices(inputHandle, 'zVertex', readIndices, ierr=ierr)
+     call mpas_io_get_var(inputHandle, 'zVertex', zVertex % array, ierr)
+     zVertex % dimSizes(1) = nReadVertices
+     zVertex % block =&gt; readingBlock
+     zVertex % sendList =&gt; indexToVertexID % sendList
+     zVertex % recvList =&gt; indexToVertexID % recvList
+     zVertex % copyList =&gt; indexToVertexID % copyList
+     nullify(zVertex % next)
+#endif
+#endif
+
+   
+     ! Global indices of cells adjacent to each vertex
+     !    used for determining which vertices are owned by a block, where 
+     !    iVtx is owned iff cellsOnVertex(1,iVtx) is an owned cell
+     allocate(cellsOnVertex)
+     allocate(cellsOnVertex % ioinfo)
+     cellsOnVertex % ioinfo % fieldName = 'cellsOnVertex'
+     cellsOnVertex % ioinfo % start(1) = 1
+     cellsOnVertex % ioinfo % start(2) = readVertexStart
+     cellsOnVertex % ioinfo % count(1) = vertexDegree
+     cellsOnVertex % ioinfo % count(2) = nReadVertices
+     allocate(cellsOnVertex % array(vertexDegree,nReadVertices))
+     call MPAS_io_inq_var(inputHandle, 'cellsOnVertex', ierr=ierr)
+     call MPAS_io_set_var_indices(inputHandle, 'cellsOnVertex', readIndices, ierr=ierr)
+     call mpas_io_get_var(inputHandle, 'cellsOnVertex', cellsOnVertex % array, ierr)
+     cellsOnVertex % dimSizes(1) = vertexDegree
+     cellsOnVertex % dimSizes(2) = nReadVertices
+     cellsOnVertex % block =&gt; readingBlock
+     cellsOnVertex % sendList =&gt; indexToVertexID % sendList
+     cellsOnVertex % recvList =&gt; indexToVertexID % recvList
+     cellsOnVertex % copyList =&gt; indexToVertexID % copyList
+     nullify(cellsOnVertex % next)
+
+     deallocate(readIndices)
+
+   end subroutine mpas_io_setup_vertex_block_fields!}}}
+
  
 end module mpas_io_input

</font>
</pre>