<p><b>dwj07@fsu.edu</b> 2011-09-30 12:20:19 -0600 (Fri, 30 Sep 2011)</p><p><br>
Removing left over modules from the old naming scheme. <br>
These have already been replaced with new modules in the previous commit, so they are now obsolete.<br>
</p><hr noshade><pre><font color="gray">Deleted: trunk/mpas/src/core_ocean/module_advection.F
===================================================================
--- trunk/mpas/src/core_ocean/module_advection.F        2011-09-30 18:04:47 UTC (rev 1046)
+++ trunk/mpas/src/core_ocean/module_advection.F        2011-09-30 18:20:19 UTC (rev 1047)
@@ -1,934 +0,0 @@
-module advection
-
-   use grid_types
-   use configure
-   use constants
-
-
-   contains
-
-
-   subroutine initialize_advection_rk( grid )
-                                      
-!
-! compute the cell coefficients for the polynomial fit.
-! this is performed during setup for model integration.
-! WCS, 31 August 2009
-!
-      implicit none
-
-      type (mesh_type), intent(in) :: grid
-
-      real (kind=RKIND), dimension(:,:,:), pointer :: deriv_two
-      integer, dimension(:,:), pointer :: advCells
-
-!  local variables
-
-      real (kind=RKIND), dimension(2, grid % nEdges) :: thetae
-      real (kind=RKIND), dimension(grid % nEdges) :: xe, ye
-      real (kind=RKIND), dimension(grid % nCells) :: theta_abs
-
-      real (kind=RKIND), dimension(25) :: xc, yc, zc ! cell center coordinates
-      real (kind=RKIND), dimension(25) :: thetav, thetat, dl_sphere
-      real (kind=RKIND) :: xm, ym, zm, dl, xec, yec, zec
-      real (kind=RKIND) :: thetae_tmp, xe_tmp, ye_tmp
-      real (kind=RKIND) :: xv1, xv2, yv1, yv2, zv1, zv2
-      integer :: i, j, k, ip1, ip2, m, n, ip1a, ii
-      integer :: iCell, iEdge
-      real (kind=RKIND) :: pii
-      real (kind=RKIND) :: x0, y0, x1, y1, x2, y2, x3, y3, x4, y4, x5, y5
-      real (kind=RKIND) :: pdx1, pdx2, pdx3, pdy1, pdy2, pdy3, dx1, dx2, dy1, dy2
-      real (kind=RKIND) :: angv1, angv2, dl1, dl2
-      real (kind=RKIND), dimension(25) :: dxe, dye, x2v, y2v, xp, yp
-      
-      real (kind=RKIND) :: amatrix(25,25), bmatrix(25,25), wmatrix(25,25)
-      real (kind=RKIND) :: length_scale
-      integer :: ma,na, cell_add, mw, nn
-      integer, dimension(25) :: cell_list
-
-
-      integer :: cell1, cell2
-      integer, parameter :: polynomial_order = 2
-!      logical, parameter :: debug = .true.
-      logical, parameter :: debug = .false.
-!      logical, parameter :: least_squares = .false.
-      logical, parameter :: least_squares = .true.
-      logical :: add_the_cell, do_the_cell
-
-      logical, parameter :: reset_poly = .true.
-
-      real (kind=RKIND) :: rcell, cos2t, costsint, sin2t
-      real (kind=RKIND), dimension(grid%maxEdges) :: angle_2d
-
-!---
-
-      pii = 2.*asin(1.0)
-
-      advCells =&gt; grid % advCells % array
-      deriv_two =&gt; grid % deriv_two % array
-      deriv_two(:,:,:) = 0.
-
-      do iCell = 1, grid % nCells !  is this correct? - we need first halo cell also...
-
-         cell_list(1) = iCell
-         do i=2, grid % nEdgesOnCell % array(iCell)+1
-            cell_list(i) = grid % CellsOnCell % array(i-1,iCell)
-         end do
-         n = grid % nEdgesOnCell % array(iCell) + 1
-
-         if ( polynomial_order &gt; 2 ) then
-            do i=2,grid % nEdgesOnCell % array(iCell) + 1
-               do j=1,grid % nEdgesOnCell % array ( cell_list(i) )
-                  cell_add = grid % CellsOnCell % array (j,cell_list(i))
-                  add_the_cell = .true.
-                  do k=1,n
-                     if ( cell_add == cell_list(k) ) add_the_cell = .false.
-                  end do
-                  if (add_the_cell) then
-                     n = n+1
-                     cell_list(n) = cell_add
-                  end if
-               end do
-            end do
-         end if

-         advCells(1,iCell) = n
-
-!  check to see if we are reaching outside the halo
-
-         do_the_cell = .true.
-         do i=1,n
-            if (cell_list(i) &gt; grid % nCells) do_the_cell = .false.
-         end do
-
-
-         if ( .not. do_the_cell ) cycle
-
-
-!  compute poynomial fit for this cell if all needed neighbors exist
-         if ( grid % on_a_sphere ) then
-
-            do i=1,n
-               advCells(i+1,iCell) = cell_list(i)
-               xc(i) = grid % xCell % array(advCells(i+1,iCell))/a
-               yc(i) = grid % yCell % array(advCells(i+1,iCell))/a
-               zc(i) = grid % zCell % array(advCells(i+1,iCell))/a
-            end do
-
-            theta_abs(iCell) =  pii/2. - sphere_angle( xc(1), yc(1), zc(1),  &amp;
-                                                       xc(2), yc(2), zc(2),  &amp;
-                                                       0.,    0.,    1.      ) 
-
-! angles from cell center to neighbor centers (thetav)
-
-            do i=1,n-1
-   
-               ip2 = i+2
-               if (ip2 &gt; n) ip2 = 2
-    
-               thetav(i) = sphere_angle( xc(1),   yc(1),   zc(1),    &amp;
-                                         xc(i+1), yc(i+1), zc(i+1),  &amp;
-                                         xc(ip2), yc(ip2), zc(ip2)   )
-
-               dl_sphere(i) = a*arc_length( xc(1),   yc(1),   zc(1),  &amp;
-                                            xc(i+1), yc(i+1), zc(i+1) )
-            end do
-
-            length_scale = 1.
-            do i=1,n-1
-               dl_sphere(i) = dl_sphere(i)/length_scale
-            end do
-
-!            thetat(1) = 0.  !  this defines the x direction, cell center 1 -&gt; 
-            thetat(1) = theta_abs(iCell)  !  this defines the x direction, longitude line
-            do i=2,n-1
-               thetat(i) = thetat(i-1) + thetav(i-1)
-            end do
-   
-            do i=1,n-1
-               xp(i) = cos(thetat(i)) * dl_sphere(i)
-               yp(i) = sin(thetat(i)) * dl_sphere(i)
-            end do
-
-         else     ! On an x-y plane
-
-            do i=1,n-1
-
-               angle_2d(i) = grid%angleEdge%array(grid % EdgesOnCell % array(i,iCell))
-               iEdge = grid % EdgesOnCell % array(i,iCell)
-               if ( iCell .ne. grid % CellsOnEdge % array(1,iEdge)) &amp;
-                  angle_2d(i) = angle_2d(i) - pii
-
-!               xp(i) = grid % xCell % array(cell_list(i)) - grid % xCell % array(iCell)
-!               yp(i) = grid % yCell % array(cell_list(i)) - grid % yCell % array(iCell)
-
-               xp(i) = grid % dcEdge % array(grid % EdgesOnCell % array(i,iCell)) * cos(angle_2d(i))
-               yp(i) = grid % dcEdge % array(grid % EdgesOnCell % array(i,iCell)) * sin(angle_2d(i))
-
-            end do
-
-         end if
-
-
-         ma = n-1
-         mw = grid % nEdgesOnCell % array (iCell)
-
-         bmatrix = 0.
-         amatrix = 0.
-         wmatrix = 0.
-
-         if (polynomial_order == 2) then
-            na = 6
-            ma = ma+1
-  
-            amatrix(1,1) = 1.
-            wmatrix(1,1) = 1.
-            do i=2,ma
-               amatrix(i,1) = 1.
-               amatrix(i,2) = xp(i-1)
-               amatrix(i,3) = yp(i-1)
-               amatrix(i,4) = xp(i-1)**2
-               amatrix(i,5) = xp(i-1) * yp(i-1)
-               amatrix(i,6) = yp(i-1)**2
-   
-               wmatrix(i,i) = 1.
-            end do

-         else if (polynomial_order == 3) then
-            na = 10
-            ma = ma+1
-  
-            amatrix(1,1) = 1.
-            wmatrix(1,1) = 1.
-            do i=2,ma
-               amatrix(i,1) = 1.
-               amatrix(i,2) = xp(i-1)
-               amatrix(i,3) = yp(i-1)
-   
-               amatrix(i,4) = xp(i-1)**2
-               amatrix(i,5) = xp(i-1) * yp(i-1)
-               amatrix(i,6) = yp(i-1)**2
-   
-               amatrix(i,7) = xp(i-1)**3
-               amatrix(i,8) = yp(i-1) * (xp(i-1)**2)
-               amatrix(i,9) = xp(i-1) * (yp(i-1)**2)
-               amatrix(i,10) = yp(i-1)**3
-   
-               wmatrix(i,i) = 1.

-            end do
-
-         else
-            na = 15
-            ma = ma+1
-  
-            amatrix(1,1) = 1.
-            wmatrix(1,1) = 1.
-            do i=2,ma
-               amatrix(i,1) = 1.
-               amatrix(i,2) = xp(i-1)
-               amatrix(i,3) = yp(i-1)
-   
-               amatrix(i,4) = xp(i-1)**2
-               amatrix(i,5) = xp(i-1) * yp(i-1)
-               amatrix(i,6) = yp(i-1)**2
-   
-               amatrix(i,7) = xp(i-1)**3
-               amatrix(i,8) = yp(i-1) * (xp(i-1)**2)
-               amatrix(i,9) = xp(i-1) * (yp(i-1)**2)
-               amatrix(i,10) = yp(i-1)**3
-   
-               amatrix(i,11) = xp(i-1)**4
-               amatrix(i,12) = yp(i-1) * (xp(i-1)**3)
-               amatrix(i,13) = (xp(i-1)**2)*(yp(i-1)**2)
-               amatrix(i,14) = xp(i-1) * (yp(i-1)**3)
-               amatrix(i,15) = yp(i-1)**4
-   
-               wmatrix(i,i) = 1.
-  
-            end do

-            do i=1,mw
-               wmatrix(i,i) = 1.
-            end do

-         end if

-         call poly_fit_2( amatrix, bmatrix, wmatrix, ma, na, 25 )
-
-         do i=1,grid % nEdgesOnCell % array (iCell)
-            ip1 = i+1
-            if (ip1 &gt; n-1) ip1 = 1
-  
-            iEdge = grid % EdgesOnCell % array (i,iCell)
-            xv1 = grid % xVertex % array(grid % verticesOnEdge % array (1,iedge))/a
-            yv1 = grid % yVertex % array(grid % verticesOnEdge % array (1,iedge))/a
-            zv1 = grid % zVertex % array(grid % verticesOnEdge % array (1,iedge))/a
-            xv2 = grid % xVertex % array(grid % verticesOnEdge % array (2,iedge))/a
-            yv2 = grid % yVertex % array(grid % verticesOnEdge % array (2,iedge))/a
-            zv2 = grid % zVertex % array(grid % verticesOnEdge % array (2,iedge))/a
-  
-            if ( grid % on_a_sphere ) then
-               call arc_bisect( xv1, yv1, zv1,  &amp;
-                                xv2, yv2, zv2,  &amp;
-                                xec, yec, zec   )
-  
-               thetae_tmp = sphere_angle( xc(1),   yc(1),   zc(1),    &amp;
-                                          xc(i+1), yc(i+1), zc(i+1),  &amp;
-                                          xec,     yec,     zec       )
-               thetae_tmp = thetae_tmp + thetat(i)
-               if (iCell == grid % cellsOnEdge % array(1,iEdge)) then
-                  thetae(1,grid % EdgesOnCell % array (i,iCell)) = thetae_tmp
-               else
-                  thetae(2,grid % EdgesOnCell % array (i,iCell)) = thetae_tmp
-               end if
-!            else
-!
-!               xe(grid % EdgesOnCell % array (i,iCell)) = 0.5 * (xv1 + xv2)
-!               ye(grid % EdgesOnCell % array (i,iCell)) = 0.5 * (yv1 + yv2)
-
-            end if
-  
-         end do
-
-!  fill second derivative stencil for rk advection 
-
-         do i=1, grid % nEdgesOnCell % array (iCell)
-            iEdge = grid % EdgesOnCell % array (i,iCell)
-  
-  
-            if ( grid % on_a_sphere ) then
-               if (iCell == grid % cellsOnEdge % array(1,iEdge)) then
-  
-                  cos2t = cos(thetae(1,grid % EdgesOnCell % array (i,iCell)))
-                  sin2t = sin(thetae(1,grid % EdgesOnCell % array (i,iCell)))
-                  costsint = cos2t*sin2t
-                  cos2t = cos2t**2
-                  sin2t = sin2t**2
-   
-                  do j=1,n
-                     deriv_two(j,1,iEdge) =   2.*cos2t*bmatrix(4,j)  &amp;
-                                            + 2.*costsint*bmatrix(5,j)  &amp;
-                                            + 2.*sin2t*bmatrix(6,j)
-                  end do
-               else
-     
-                  cos2t = cos(thetae(2,grid % EdgesOnCell % array (i,iCell)))
-                  sin2t = sin(thetae(2,grid % EdgesOnCell % array (i,iCell)))
-                  costsint = cos2t*sin2t
-                  cos2t = cos2t**2
-                  sin2t = sin2t**2
-      
-                  do j=1,n
-                     deriv_two(j,2,iEdge) =   2.*cos2t*bmatrix(4,j)  &amp;
-                                            + 2.*costsint*bmatrix(5,j)  &amp;
-                                            + 2.*sin2t*bmatrix(6,j)
-                  end do
-               end if
-
-            else
-
-               cos2t = cos(angle_2d(i))
-               sin2t = sin(angle_2d(i))
-               costsint = cos2t*sin2t
-               cos2t = cos2t**2
-               sin2t = sin2t**2
-
-!               do j=1,n
-!
-!                  deriv_two(j,1,iEdge) =   2.*xe(iEdge)*xe(iEdge)*bmatrix(4,j)  &amp;
-!                                         + 2.*xe(iEdge)*ye(iEdge)*bmatrix(5,j)  &amp;
-!                                         + 2.*ye(iEdge)*ye(iEdge)*bmatrix(6,j)
-!               end do
-
-               if (iCell == grid % cellsOnEdge % array(1,iEdge)) then
-                  do j=1,n
-                     deriv_two(j,1,iEdge) =   2.*cos2t*bmatrix(4,j)  &amp;
-                                            + 2.*costsint*bmatrix(5,j)  &amp;
-                                            + 2.*sin2t*bmatrix(6,j)
-                  end do
-               else
-                  do j=1,n
-                     deriv_two(j,2,iEdge) =   2.*cos2t*bmatrix(4,j)  &amp;
-                                            + 2.*costsint*bmatrix(5,j)  &amp;
-                                            + 2.*sin2t*bmatrix(6,j)
-                  end do
-               end if
-
-            end if
-         end do

-      end do ! end of loop over cells
-
-      if (debug) stop
-
-
-!      write(0,*) ' check for deriv2 coefficients, iEdge 4 '
-!
-!      iEdge = 4
-!      j = 1
-!      iCell = grid % cellsOnEdge % array(1,iEdge)
-!      write(0,*) ' j, icell, coef ',j,iCell,deriv_two(j,1,iEdge)
-!      do j=2,7
-!         write(0,*) ' j, icell, coef ',j,grid % CellsOnCell % array(j-1,iCell),deriv_two(j,1,iEdge)
-!      end do
-!
-!      j = 1
-!      iCell = grid % cellsOnEdge % array(2,iEdge)
-!      write(0,*) ' j, icell, coef ',j,iCell,deriv_two(j,2,iEdge)
-!      do j=2,7
-!         write(0,*) ' j, icell, coef ',j,grid % CellsOnCell % array(j-1,iCell),deriv_two(j,2,iEdge)
-!      end do
-!      stop
-
-   end subroutine initialize_advection_rk
-
-
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   ! FUNCTION SPHERE_ANGLE
-   !
-   ! Computes the angle between arcs AB and AC, given points A, B, and C
-   ! Equation numbers w.r.t. http://mathworld.wolfram.com/SphericalTrigonometry.html
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   real function sphere_angle(ax, ay, az, bx, by, bz, cx, cy, cz)
-   
-      implicit none
-   
-      real (kind=RKIND), intent(in) :: ax, ay, az, bx, by, bz, cx, cy, cz
-   
-      real (kind=RKIND) :: a, b, c          ! Side lengths of spherical triangle ABC
-   
-      real (kind=RKIND) :: ABx, ABy, ABz    ! The components of the vector AB
-      real (kind=RKIND) :: mAB              ! The magnitude of AB
-      real (kind=RKIND) :: ACx, ACy, ACz    ! The components of the vector AC
-      real (kind=RKIND) :: mAC              ! The magnitude of AC
-   
-      real (kind=RKIND) :: Dx               ! The i-components of the cross product AB x AC
-      real (kind=RKIND) :: Dy               ! The j-components of the cross product AB x AC
-      real (kind=RKIND) :: Dz               ! The k-components of the cross product AB x AC
-   
-      real (kind=RKIND) :: s                ! Semiperimeter of the triangle
-      real (kind=RKIND) :: sin_angle
-   
-      a = acos(max(min(bx*cx + by*cy + bz*cz,1.0),-1.0))      ! Eqn. (3)
-      b = acos(max(min(ax*cx + ay*cy + az*cz,1.0),-1.0))      ! Eqn. (2)
-      c = acos(max(min(ax*bx + ay*by + az*bz,1.0),-1.0))      ! Eqn. (1)
-   
-      ABx = bx - ax
-      ABy = by - ay
-      ABz = bz - az
-   
-      ACx = cx - ax
-      ACy = cy - ay
-      ACz = cz - az
-   
-      Dx =   (ABy * ACz) - (ABz * ACy)
-      Dy = -((ABx * ACz) - (ABz * ACx))
-      Dz =   (ABx * ACy) - (ABy * ACx)
-   
-      s = 0.5*(a + b + c)
-!      sin_angle = sqrt((sin(s-b)*sin(s-c))/(sin(b)*sin(c)))   ! Eqn. (28)
-      sin_angle = sqrt(min(1.,max(0.,(sin(s-b)*sin(s-c))/(sin(b)*sin(c)))))   ! Eqn. (28)
-   
-      if ((Dx*ax + Dy*ay + Dz*az) &gt;= 0.0) then
-         sphere_angle =  2.0 * asin(max(min(sin_angle,1.0),-1.0))
-      else
-         sphere_angle = -2.0 * asin(max(min(sin_angle,1.0),-1.0))
-      end if
-   
-   end function sphere_angle
-   
-
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   ! FUNCTION PLANE_ANGLE
-   !
-   ! Computes the angle between vectors AB and AC, given points A, B, and C, and
-   !   a vector (u,v,w) normal to the plane.
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   real function plane_angle(ax, ay, az, bx, by, bz, cx, cy, cz, u, v, w)
-   
-      implicit none
-   
-      real (kind=RKIND), intent(in) :: ax, ay, az, bx, by, bz, cx, cy, cz, u, v, w
-   
-      real (kind=RKIND) :: ABx, ABy, ABz    ! The components of the vector AB
-      real (kind=RKIND) :: mAB              ! The magnitude of AB
-      real (kind=RKIND) :: ACx, ACy, ACz    ! The components of the vector AC
-      real (kind=RKIND) :: mAC              ! The magnitude of AC
-   
-      real (kind=RKIND) :: Dx               ! The i-components of the cross product AB x AC
-      real (kind=RKIND) :: Dy               ! The j-components of the cross product AB x AC
-      real (kind=RKIND) :: Dz               ! The k-components of the cross product AB x AC
-   
-      real (kind=RKIND) :: cos_angle
-   
-      ABx = bx - ax
-      ABy = by - ay
-      ABz = bz - az
-      mAB = sqrt(ABx**2.0 + ABy**2.0 + ABz**2.0)
-   
-      ACx = cx - ax
-      ACy = cy - ay
-      ACz = cz - az
-      mAC = sqrt(ACx**2.0 + ACy**2.0 + ACz**2.0)
-   
-   
-      Dx =   (ABy * ACz) - (ABz * ACy)
-      Dy = -((ABx * ACz) - (ABz * ACx))
-      Dz =   (ABx * ACy) - (ABy * ACx)
-   
-      cos_angle = (ABx*ACx + ABy*ACy + ABz*ACz) / (mAB * mAC)
-   
-      if ((Dx*u + Dy*v + Dz*w) &gt;= 0.0) then
-         plane_angle =  acos(max(min(cos_angle,1.0),-1.0))
-      else
-         plane_angle = -acos(max(min(cos_angle,1.0),-1.0))
-      end if
-   
-   end function plane_angle
-
-
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   ! FUNCTION ARC_LENGTH
-   !
-   ! Returns the length of the great circle arc from A=(ax, ay, az) to 
-   !    B=(bx, by, bz). It is assumed that both A and B lie on the surface of the
-   !    same sphere centered at the origin.
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   real function arc_length(ax, ay, az, bx, by, bz)
-   
-      implicit none
-   
-      real (kind=RKIND), intent(in) :: ax, ay, az, bx, by, bz
-   
-      real (kind=RKIND) :: r, c
-      real (kind=RKIND) :: cx, cy, cz
-   
-      cx = bx - ax
-      cy = by - ay
-      cz = bz - az
-
-!      r = ax*ax + ay*ay + az*az
-!      c = cx*cx + cy*cy + cz*cz
-!
-!      arc_length = sqrt(r) * acos(1.0 - c/(2.0*r))
-
-      r = sqrt(ax*ax + ay*ay + az*az)
-      c = sqrt(cx*cx + cy*cy + cz*cz)
-!      arc_length = sqrt(r) * 2.0 * asin(c/(2.0*r))
-      arc_length = r * 2.0 * asin(c/(2.0*r))
-
-   end function arc_length
-   
-   
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   ! SUBROUTINE ARC_BISECT
-   !
-   ! Returns the point C=(cx, cy, cz) that bisects the great circle arc from
-   !   A=(ax, ay, az) to B=(bx, by, bz). It is assumed that A and B lie on the
-   !   surface of a sphere centered at the origin.
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   subroutine arc_bisect(ax, ay, az, bx, by, bz, cx, cy, cz)
-   
-      implicit none
-   
-      real (kind=RKIND), intent(in) :: ax, ay, az, bx, by, bz
-      real (kind=RKIND), intent(out) :: cx, cy, cz
-   
-      real (kind=RKIND) :: r           ! Radius of the sphere
-      real (kind=RKIND) :: d           
-   
-      r = sqrt(ax*ax + ay*ay + az*az)
-   
-      cx = 0.5*(ax + bx)
-      cy = 0.5*(ay + by)
-      cz = 0.5*(az + bz)
-   
-      if (cx == 0. .and. cy == 0. .and. cz == 0.) then
-         write(0,*) 'Error: arc_bisect: A and B are diametrically opposite'
-      else
-         d = sqrt(cx*cx + cy*cy + cz*cz)
-         cx = r * cx / d
-         cy = r * cy / d
-         cz = r * cz / d
-      end if
-   
-   end subroutine arc_bisect
-
-
-   subroutine poly_fit_2(a_in,b_out,weights_in,m,n,ne)
-
-      implicit none
-
-      integer, intent(in) :: m,n,ne
-      real (kind=RKIND), dimension(ne,ne), intent(in) :: a_in, weights_in
-      real (kind=RKIND), dimension(ne,ne), intent(out) :: b_out
-   
-      ! local storage
-   
-      real (kind=RKIND), dimension(m,n)  :: a
-      real (kind=RKIND), dimension(n,m)  :: b
-      real (kind=RKIND), dimension(m,m)  :: w,wt,h
-      real (kind=RKIND), dimension(n,m)  :: at, ath
-      real (kind=RKIND), dimension(n,n)  :: ata, ata_inv, atha, atha_inv
-      integer, dimension(n) :: indx
-      integer :: i,j
-   
-      if ( (ne&lt;n) .or. (ne&lt;m) ) then
-         write(6,*) ' error in poly_fit_2 inversion ',m,n,ne
-         stop
-      end if
-   
-!      a(1:m,1:n) = a_in(1:n,1:m) 
-      a(1:m,1:n) = a_in(1:m,1:n)
-      w(1:m,1:m) = weights_in(1:m,1:m) 
-      b_out(:,:) = 0.   
-
-      wt = transpose(w)
-      h = matmul(wt,w)
-      at = transpose(a)
-      ath = matmul(at,h)
-      atha = matmul(ath,a)
-      
-      ata = matmul(at,a)
-
-!      if (m == n) then
-!         call migs(a,n,b,indx)
-!      else
-
-         call migs(atha,n,atha_inv,indx)
-
-         b = matmul(atha_inv,ath)
-
-!         call migs(ata,n,ata_inv,indx)
-!         b = matmul(ata_inv,at)
-!      end if
-      b_out(1:n,1:m) = b(1:n,1:m)
-
-!     do i=1,n
-!        write(6,*) ' i, indx ',i,indx(i)
-!     end do
-!
-!     write(6,*) ' '
-
-   end subroutine poly_fit_2
-
-
-! Updated 10/24/2001.
-!
-!!!!!!!!!!!!!!!!!!!!!!!!!!!   Program 4.4   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-!
-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-!                                                                       !
-! Please Note:                                                          !
-!                                                                       !
-! (1) This computer program is written by Tao Pang in conjunction with  !
-!     his book, &quot;An Introduction to Computational Physics,&quot; published   !
-!     by Cambridge University Press in 1997.                            !
-!                                                                       !
-! (2) No warranties, express or implied, are made for this program.     !
-!                                                                       !
-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-!
-SUBROUTINE MIGS (A,N,X,INDX)
-!
-! Subroutine to invert matrix A(N,N) with the inverse stored
-! in X(N,N) in the output.  Copyright (c) Tao Pang 2001.
-!
-  IMPLICIT NONE
-  INTEGER, INTENT (IN) :: N
-  INTEGER :: I,J,K
-  INTEGER, INTENT (OUT), DIMENSION (N) :: INDX
-  REAL (kind=RKIND), INTENT (INOUT), DIMENSION (N,N):: A
-  REAL (kind=RKIND), INTENT (OUT), DIMENSION (N,N):: X
-  REAL (kind=RKIND), DIMENSION (N,N) :: B
-!
-  DO I = 1, N
-    DO J = 1, N
-      B(I,J) = 0.0
-    END DO
-  END DO
-  DO I = 1, N
-    B(I,I) = 1.0
-  END DO
-!
-  CALL ELGS (A,N,INDX)
-!
-  DO I = 1, N-1
-    DO J = I+1, N
-      DO K = 1, N
-        B(INDX(J),K) = B(INDX(J),K)-A(INDX(J),I)*B(INDX(I),K)
-      END DO
-    END DO
-  END DO
-!
-  DO I = 1, N
-    X(N,I) = B(INDX(N),I)/A(INDX(N),N)
-    DO J = N-1, 1, -1
-      X(J,I) = B(INDX(J),I)
-      DO K = J+1, N
-        X(J,I) = X(J,I)-A(INDX(J),K)*X(K,I)
-      END DO
-      X(J,I) =  X(J,I)/A(INDX(J),J)
-    END DO
-  END DO
-END SUBROUTINE MIGS
-
-
-SUBROUTINE ELGS (A,N,INDX)
-!
-! Subroutine to perform the partial-pivoting Gaussian elimination.
-! A(N,N) is the original matrix in the input and transformed matrix
-! plus the pivoting element ratios below the diagonal in the output.
-! INDX(N) records the pivoting order.  Copyright (c) Tao Pang 2001.
-!
-  IMPLICIT NONE
-  INTEGER, INTENT (IN) :: N
-  INTEGER :: I,J,K,ITMP
-  INTEGER, INTENT (OUT), DIMENSION (N) :: INDX
-  REAL (kind=RKIND) :: C1,PI,PI1,PJ
-  REAL (kind=RKIND), INTENT (INOUT), DIMENSION (N,N) :: A
-  REAL (kind=RKIND), DIMENSION (N) :: C
-!
-! Initialize the index
-!
-  DO I = 1, N
-    INDX(I) = I
-  END DO
-!
-! Find the rescaling factors, one from each row
-!
-  DO I = 1, N
-    C1= 0.0
-    DO J = 1, N
-      C1 = MAX(C1,ABS(A(I,J)))
-    END DO
-    C(I) = C1
-  END DO
-!
-! Search the pivoting (largest) element from each column
-!
-  DO J = 1, N-1
-    PI1 = 0.0
-    DO I = J, N
-      PI = ABS(A(INDX(I),J))/C(INDX(I))
-      IF (PI.GT.PI1) THEN
-        PI1 = PI
-        K   = I
-      ENDIF
-    END DO
-!
-! Interchange the rows via INDX(N) to record pivoting order
-!
-    ITMP    = INDX(J)
-    INDX(J) = INDX(K)
-    INDX(K) = ITMP
-    DO I = J+1, N
-      PJ  = A(INDX(I),J)/A(INDX(J),J)
-!
-! Record pivoting ratios below the diagonal
-!
-      A(INDX(I),J) = PJ
-!
-! Modify other elements accordingly
-!
-      DO K = J+1, N
-        A(INDX(I),K) = A(INDX(I),K)-PJ*A(INDX(J),K)
-      END DO
-    END DO
-  END DO
-!
-END SUBROUTINE ELGS
-
-!-------------------------------------------------------------
-
-   subroutine initialize_deformation_weights( grid )
-                                      
-!
-! compute the cell coefficients for the deformation calculations
-! WCS, 13 July 2010
-!
-      implicit none
-
-      type (mesh_type), intent(in) :: grid
-!      type (grid_meta), intent(in) :: grid
-
-      real (kind=RKIND), dimension(:,:), pointer :: defc_a, defc_b
-      integer, dimension(:,:), pointer :: cellsOnEdge, edgesOnCell
-
-!  local variables
-
-      real (kind=RKIND), dimension(2, grid % nEdges) :: thetae
-      real (kind=RKIND), dimension(grid % nEdges) :: xe, ye
-      real (kind=RKIND), dimension(grid % nCells) :: theta_abs
-
-      real (kind=RKIND), dimension(25) :: xc, yc, zc ! cell center coordinates
-      real (kind=RKIND), dimension(25) :: thetav, thetat, dl_sphere
-      real (kind=RKIND) :: xm, ym, zm, dl, xec, yec, zec
-      real (kind=RKIND) :: thetae_tmp, xe_tmp, ye_tmp
-      real (kind=RKIND) :: xv1, xv2, yv1, yv2, zv1, zv2
-      integer :: i, j, k, ip1, ip2, m, n, ip1a, ii
-      integer :: iCell, iEdge
-      real (kind=RKIND) :: pii
-      real (kind=RKIND) :: x0, y0, x1, y1, x2, y2, x3, y3, x4, y4, x5, y5
-      real (kind=RKIND) :: pdx1, pdx2, pdx3, pdy1, pdy2, pdy3, dx1, dx2, dy1, dy2
-      real (kind=RKIND) :: angv1, angv2, dl1, dl2
-      real (kind=RKIND), dimension(25) :: dxe, dye, x2v, y2v, xp, yp, xpt, ypt
-      
-      real (kind=RKIND) :: length_scale
-      integer :: ma,na, cell_add, mw, nn
-      integer, dimension(25) :: cell_list
-
-      integer :: cell1, cell2, iv
-      logical :: do_the_cell
-      real (kind=RKIND) :: area_cell, sint2, cost2, sint_cost, sumw1, sumw2, xptt, area_cellt
-
-      logical, parameter :: debug = .false.
-
-      if (debug) write(0,*) ' in def weight calc '
-
-      defc_a =&gt; grid % defc_a % array
-      defc_b =&gt; grid % defc_b % array
-      cellsOnEdge =&gt; grid % cellsOnEdge % array
-      edgesOnCell =&gt; grid % edgesOnCell % array
-
-      defc_a(:,:) = 0.
-      defc_b(:,:) = 0.
-
-      pii = 2.*asin(1.0)
-
-      if (debug) write(0,*) ' beginning cell loop '
-
-      do iCell = 1, grid % nCells
-
-         if (debug) write(0,*) ' cell loop ', iCell
-
-         cell_list(1) = iCell
-         do i=2, grid % nEdgesOnCell % array(iCell)+1
-            cell_list(i) = grid % CellsOnCell % array(i-1,iCell)
-         end do
-         n = grid % nEdgesOnCell % array(iCell) + 1
-
-!  check to see if we are reaching outside the halo
-
-         if (debug) write(0,*) ' points ', n
-
-         do_the_cell = .true.
-         do i=1,n
-            if (cell_list(i) &gt; grid % nCells) do_the_cell = .false.
-         end do
-
-
-         if (.not. do_the_cell) cycle
-
-
-!  compute poynomial fit for this cell if all needed neighbors exist
-         if (grid % on_a_sphere) then
-
-            xc(1) = grid % xCell % array(iCell)/a
-            yc(1) = grid % yCell % array(iCell)/a
-            zc(1) = grid % zCell % array(iCell)/a
-
-
-            do i=2,n
-               iv = grid % verticesOnCell % array(i-1,iCell)
-               xc(i) = grid % xVertex % array(iv)/a
-               yc(i) = grid % yVertex % array(iv)/a
-               zc(i) = grid % zVertex % array(iv)/a
-            end do
-
-            theta_abs(iCell) =  pii/2. - sphere_angle( xc(1), yc(1), zc(1),  &amp;
-                                                       xc(2), yc(2), zc(2),  &amp;
-                                                       0.,    0.,    1.      ) 
-
-! angles from cell center to neighbor centers (thetav)
-
-            do i=1,n-1
-   
-               ip2 = i+2
-               if (ip2 &gt; n) ip2 = 2
-    
-               thetav(i) = sphere_angle( xc(1),   yc(1),   zc(1),    &amp;
-                                         xc(i+1), yc(i+1), zc(i+1),  &amp;
-                                         xc(ip2), yc(ip2), zc(ip2)   )
-
-               dl_sphere(i) = a*arc_length( xc(1),   yc(1),   zc(1),  &amp;
-                                            xc(i+1), yc(i+1), zc(i+1) )
-            end do
-
-            length_scale = 1.
-            do i=1,n-1
-               dl_sphere(i) = dl_sphere(i)/length_scale
-            end do
-
-            thetat(1) = 0.  !  this defines the x direction, cell center 1 -&gt; 
-!            thetat(1) = theta_abs(iCell)  !  this defines the x direction, longitude line
-            do i=2,n-1
-               thetat(i) = thetat(i-1) + thetav(i-1)
-            end do
-   
-            do i=1,n-1
-               xp(i) = cos(thetat(i)) * dl_sphere(i)
-               yp(i) = sin(thetat(i)) * dl_sphere(i)
-            end do
-
-         else     ! On an x-y plane
-
-            xp(1) = grid % xCell % array(iCell)
-            yp(1) = grid % yCell % array(iCell)
-
-
-            do i=2,n
-               iv = grid % verticesOnCell % array(i-1,iCell)
-               xp(i) = grid % xVertex % array(iv)
-               yp(i) = grid % yVertex % array(iv)
-            end do
-
-         end if
-
-!         thetat(1) = 0.
-         thetat(1) = theta_abs(iCell)
-         do i=2,n-1
-            ip1 = i+1
-            if (ip1 == n) ip1 = 1
-            thetat(i) = plane_angle( 0.,0.,0.,  &amp;
-                                     xp(i)-xp(i-1), yp(i)-yp(i-1), 0.,  &amp;
-                                     xp(ip1)-xp(i), yp(ip1)-yp(i), 0.,  &amp;
-                                     0., 0., 1.)
-            thetat(i) = thetat(i) + thetat(i-1)
-         end do
-
-         area_cell = 0.
-         area_cellt = 0.
-         do i=1,n-1
-            ip1 = i+1
-            if (ip1 == n) ip1 = 1
-            dl = sqrt((xp(ip1)-xp(i))**2 + (yp(ip1)-yp(i))**2)
-            area_cell = area_cell + 0.25*(xp(i)+xp(ip1))*(yp(ip1)-yp(i)) - 0.25*(yp(i)+yp(ip1))*(xp(ip1)-xp(i))
-            area_cellt = area_cellt + (0.25*(xp(i)+xp(ip1))*cos(thetat(i)) + 0.25*(yp(i)+yp(ip1))*sin(thetat(i)))*dl
-         end do
-         if (debug) write(0,*) ' area_cell, area_cellt ',area_cell, area_cellt,area_cell-area_cellt
-
-         do i=1,n-1
-            ip1 = i+1
-            if (ip1 == n) ip1 = 1
-            dl = sqrt((xp(ip1)-xp(i))**2 + (yp(ip1)-yp(i))**2)
-            sint2 = (sin(thetat(i)))**2
-            cost2 = (cos(thetat(i)))**2
-            sint_cost = sin(thetat(i))*cos(thetat(i))
-            defc_a(i,iCell) = dl*(cost2 - sint2)/area_cell
-            defc_b(i,iCell) = dl*2.*sint_cost/area_cell
-            if (cellsOnEdge(1,EdgesOnCell(i,iCell)) /= iCell) then
-               defc_a(i,iCell) = - defc_a(i,iCell)
-               defc_b(i,iCell) = - defc_b(i,iCell)
-            end if

-         end do
-
-      end do
-
-      if (debug) write(0,*) ' exiting def weight calc '
-
-   end subroutine initialize_deformation_weights
-
-end module advection

Deleted: trunk/mpas/src/core_ocean/module_global_diagnostics.F
===================================================================
--- trunk/mpas/src/core_ocean/module_global_diagnostics.F        2011-09-30 18:04:47 UTC (rev 1046)
+++ trunk/mpas/src/core_ocean/module_global_diagnostics.F        2011-09-30 18:20:19 UTC (rev 1047)
@@ -1,618 +0,0 @@
-module global_diagnostics
-
-   use grid_types
-   use configure
-   use constants
-   use dmpar
-
-   implicit none
-   save
-   public
-
-   contains
-
-   subroutine computeGlobalDiagnostics(dminfo, state, grid, timeIndex, dt)
-
-      ! Note: this routine assumes that there is only one block per processor. No looping
-      ! is preformed over blocks.
-      ! dminfo is the domain info needed for global communication
-      ! state contains the state variables needed to compute global diagnostics
-      ! grid conains the meta data about the grid
-      ! timeIndex is the current time step counter
-      ! dt is the duration of each time step
-
-      ! Sums of variables at vertices are not weighted by thickness (since h is not known at
-      !    vertices as it is at cell centers and at edges).
-
-      implicit none
-
-      type (dm_info), intent(in) :: dminfo
-      type (state_type), intent(inout) :: state
-      type (mesh_type), intent(in) :: grid
-      integer, intent(in) :: timeIndex
-      real (kind=RKIND), intent(in) :: dt
-
-      integer :: nVertLevels, nCellsSolve, nEdgesSolve, nVerticesSolve, nCellsGlobal, nEdgesGlobal, nVerticesGlobal, iTracer
-
-      real (kind=RKIND) ::  areaCellGlobal, areaEdgeGlobal, areaTriangleGlobal
-      real (kind=RKIND), dimension(:), pointer ::  areaCell, dcEdge, dvEdge, areaTriangle, areaEdge
-      real (kind=RKIND), dimension(:,:), pointer :: h, u, v, h_edge, circulation, vorticity, ke, pv_edge, pv_vertex, &amp;
-         pv_cell, gradPVn, gradPVt, pressure, MontPot, wTop, rho, tracerTemp
-      real (kind=RKIND), dimension(:,:,:), pointer :: tracers
-
-      real (kind=RKIND) :: volumeCellGlobal, volumeEdgeGlobal, CFLNumberGlobal
-      real (kind=RKIND) ::  localCFL, localSum
-      integer :: elementIndex, variableIndex, nVariables, nSums, nMaxes, nMins
-      integer :: timeLevel,k,i, num_tracers
-
-      integer, parameter :: kMaxVariables = 1024 ! this must be a little more than double the number of variables to be reduced
-
-      real (kind=RKIND), dimension(kMaxVariables) :: sums, mins, maxes, averages, verticalSumMins, verticalSumMaxes, reductions
-
-      integer :: fileID
-
-      num_tracers = state % num_tracers
-
-      nVertLevels = grid % nVertLevels
-      nCellsSolve = grid % nCellsSolve
-      nEdgesSolve = grid % nEdgesSolve
-      nVerticesSolve = grid % nVerticesSolve
-
-      areaCell =&gt; grid % areaCell % array
-      dcEdge =&gt; grid % dcEdge % array
-      dvEdge =&gt; grid % dvEdge % array
-      areaTriangle =&gt; grid % areaTriangle % array
-      allocate(areaEdge(1:nEdgesSolve))
-      areaEdge = dcEdge(1:nEdgesSolve)*dvEdge(1:nEdgesSolve)
-
-      h =&gt; state % h % array
-      u =&gt; state % u % array
-      rho =&gt; state % rho % array
-      tracers =&gt; state % tracers % array
-      v =&gt; state % v % array
-      wTop =&gt; state % wTop % array
-      h_edge =&gt; state % h_edge % array
-      circulation =&gt; state % circulation % array
-      vorticity =&gt; state % vorticity % array
-      ke =&gt; state % ke % array
-      pv_edge =&gt; state % pv_edge % array
-      pv_vertex =&gt; state % pv_vertex % array
-      pv_cell =&gt; state % pv_cell % array
-      gradPVn =&gt; state % gradPVn % array
-      gradPVt =&gt; state % gradPVt % array
-      MontPot =&gt; state % MontPot % array
-      pressure =&gt; state % pressure % array
-
-      variableIndex = 0
-      ! h
-      variableIndex = variableIndex + 1
-      call computeFieldAreaWeightedLocalStats(dminfo, nVertLevels, nCellsSolve, areaCell(1:nCellsSolve), h(:,1:nCellsSolve), &amp;
-        sums(variableIndex), mins(variableIndex), maxes(variableIndex), verticalSumMins(variableIndex), verticalSumMaxes(variableIndex))
-
-      ! u
-      variableIndex = variableIndex + 1
-      call computeFieldVolumeWeightedLocalStats(dminfo, nVertLevels, nEdgesSolve, areaEdge(1:nEdgesSolve), h_edge(:,1:nEdgesSolve), &amp;
-        u(:,1:nEdgesSolve), sums(variableIndex), mins(variableIndex), maxes(variableIndex), verticalSumMins(variableIndex), &amp;
-        verticalSumMaxes(variableIndex))
-
-      ! v
-      variableIndex = variableIndex + 1
-      call computeFieldVolumeWeightedLocalStats(dminfo, nVertLevels, nEdgesSolve, areaEdge(1:nEdgesSolve), h_edge(:,1:nEdgesSolve), &amp;
-        v(:,1:nEdgesSolve), sums(variableIndex), mins(variableIndex), maxes(variableIndex), verticalSumMins(variableIndex), &amp;
-        verticalSumMaxes(variableIndex))
-
-      ! h_edge
-      variableIndex = variableIndex + 1
-      call computeFieldAreaWeightedLocalStats(dminfo, nVertLevels, nEdgesSolve, areaEdge(1:nEdgesSolve), h_edge(:,1:nEdgesSolve), &amp;
-        sums(variableIndex), mins(variableIndex), maxes(variableIndex), verticalSumMins(variableIndex), verticalSumMaxes(variableIndex))
-
-      ! circulation
-      variableIndex = variableIndex + 1
-      call computeFieldLocalStats(dminfo, nVertLevels, nVerticesSolve, circulation(:,1:nVerticesSolve), &amp;
-        sums(variableIndex), mins(variableIndex), maxes(variableIndex), verticalSumMins(variableIndex), verticalSumMaxes(variableIndex))
-
-      ! vorticity
-      variableIndex = variableIndex + 1
-      call computeFieldAreaWeightedLocalStats(dminfo, nVertLevels, nVerticesSolve, areaTriangle(1:nVerticesSolve), &amp;
-        vorticity(:,1:nVerticesSolve), sums(variableIndex), mins(variableIndex), maxes(variableIndex), &amp;
-        verticalSumMins(variableIndex), verticalSumMaxes(variableIndex))
-
-      ! ke
-      variableIndex = variableIndex + 1
-      call computeFieldVolumeWeightedLocalStats(dminfo, nVertLevels, nCellsSolve, areaCell(1:nCellsSolve), h(:,1:nCellsSolve), &amp;
-        ke(:,1:nCellsSolve), sums(variableIndex), mins(variableIndex), maxes(variableIndex), verticalSumMins(variableIndex), &amp;
-        verticalSumMaxes(variableIndex))
-
-      ! pv_edge
-      variableIndex = variableIndex + 1
-      call computeFieldVolumeWeightedLocalStats(dminfo, nVertLevels, nEdgesSolve, areaEdge(1:nEdgesSolve), h_edge(:,1:nEdgesSolve), &amp;
-        pv_edge(:,1:nEdgesSolve), sums(variableIndex), mins(variableIndex), maxes(variableIndex), verticalSumMins(variableIndex), &amp;
-        verticalSumMaxes(variableIndex))
-
-      ! pv_vertex
-      variableIndex = variableIndex + 1
-      call computeFieldAreaWeightedLocalStats(dminfo, nVertLevels, nVerticesSolve, areaTriangle(1:nVerticesSolve), &amp;
-        pv_vertex(:,1:nVerticesSolve), sums(variableIndex), mins(variableIndex), maxes(variableIndex), &amp;
-        verticalSumMins(variableIndex), verticalSumMaxes(variableIndex))
-
-      ! pv_cell
-      variableIndex = variableIndex + 1
-      call computeFieldVolumeWeightedLocalStats(dminfo, nVertLevels, nCellsSolve, areaCell(1:nCellsSolve), h(:,1:nCellsSolve), &amp;
-        pv_cell(:,1:nCellsSolve), sums(variableIndex), mins(variableIndex), maxes(variableIndex), verticalSumMins(variableIndex), &amp;
-        verticalSumMaxes(variableIndex))
-
-      ! gradPVn
-      variableIndex = variableIndex + 1
-      call computeFieldVolumeWeightedLocalStats(dminfo, nVertLevels, nEdgesSolve, areaEdge(1:nEdgesSolve), h_edge(:,1:nEdgesSolve), &amp;
-        gradPVn(:,1:nEdgesSolve), sums(variableIndex), mins(variableIndex), maxes(variableIndex), verticalSumMins(variableIndex), &amp;
-        verticalSumMaxes(variableIndex))
-
-      ! gradPVt
-      variableIndex = variableIndex + 1
-      call computeFieldVolumeWeightedLocalStats(dminfo, nVertLevels, nEdgesSolve, areaEdge(1:nEdgesSolve), h_edge(:,1:nEdgesSolve), &amp;
-        gradPVt(:,1:nEdgesSolve), sums(variableIndex), mins(variableIndex), maxes(variableIndex), verticalSumMins(variableIndex), &amp;
-        verticalSumMaxes(variableIndex))
-
-      ! pressure
-      variableIndex = variableIndex + 1
-      call computeFieldVolumeWeightedLocalStats(dminfo, nVertLevels, nCellsSolve, areaCell(1:nCellsSolve), h(:,1:nCellsSolve), &amp;
-        pressure(:,1:nCellsSolve), sums(variableIndex), mins(variableIndex), maxes(variableIndex), verticalSumMins(variableIndex), &amp;
-        verticalSumMaxes(variableIndex))
-
-      ! MontPot
-      variableIndex = variableIndex + 1
-      call computeFieldVolumeWeightedLocalStats(dminfo, nVertLevels, nCellsSolve, areaCell(1:nCellsSolve), h(:,1:nCellsSolve), &amp;
-        MontPot(:,1:nCellsSolve), sums(variableIndex), mins(variableIndex), maxes(variableIndex), verticalSumMins(variableIndex), &amp;
-        verticalSumMaxes(variableIndex))
-
-      ! wTop vertical velocity
-      variableIndex = variableIndex + 1
-      call computeFieldVolumeWeightedLocalStats(dminfo, nVertLevels+1, nCellsSolve, areaCell(1:nCellsSolve), h(:,1:nCellsSolve), &amp;
-        wTop(:,1:nCellsSolve), sums(variableIndex), mins(variableIndex), maxes(variableIndex), verticalSumMins(variableIndex), &amp;
-        verticalSumMaxes(variableIndex))
-
-      ! Tracers
-      allocate(tracerTemp(nVertLevels,nCellsSolve))
-      do iTracer=1,num_tracers
-        variableIndex = variableIndex + 1
-        tracerTemp = Tracers(iTracer,:,1:nCellsSolve)
-        call computeFieldVolumeWeightedLocalStats(dminfo, nVertLevels, nCellsSolve, areaCell(1:nCellsSolve), h(:,1:nCellsSolve), &amp;
-          tracerTemp, sums(variableIndex), mins(variableIndex), maxes(variableIndex), verticalSumMins(variableIndex), &amp;
-          verticalSumMaxes(variableIndex))
-      enddo
-      deallocate(tracerTemp)
-
-      nVariables = variableIndex
-      nSums = nVariables
-      nMins = nVariables
-      nMaxes = nVariables
-
-      nSums = nSums + 1
-      sums(nSums) = sum(areaCell(1:nCellsSolve))
-
-      nSums = nSums + 1
-      sums(nSums) = sum(dcEdge(1:nEdgesSolve)*dvEdge(1:nEdgesSolve))
-
-      nSums = nSums + 1
-      sums(nSums) = sum(areaTriangle(1:nVerticesSolve))
-
-      nSums = nSums + 1
-      sums(nSums) = nCellsSolve
-
-      nSums = nSums + 1
-      sums(nSums) = nEdgesSolve
-
-      nSums = nSums + 1
-      sums(nSums) = nVerticesSolve
-
-      localCFL = 0.0
-      do elementIndex = 1,nEdgesSolve
-         localCFL = max(localCFL, maxval(dt*u(:,elementIndex)/dcEdge(elementIndex)))
-      end do
-      nMaxes = nMaxes + 1
-      maxes(nMaxes) = localCFL
-
-      mins(nMins+1:nMins+nVariables) = verticalSumMins(1:nVariables)
-      nMins = nMins + nVariables
-      maxes(nMaxes+1:nMaxes+nVariables) = verticalSumMaxes(1:nVariables)
-      nMaxes = nMaxes + nVariables
-
-      ! global reduction of the 5 arrays (packed into 3 to minimize global communication)
-      call dmpar_sum_real_array(dminfo, nSums, sums(1:nSums), reductions(1:nSums))
-      sums(1:nVariables) = reductions(1:nVariables)
-      areaCellGlobal = reductions(nVariables+1)
-      areaEdgeGlobal = reductions(nVariables+2)
-      areaTriangleGlobal = reductions(nVariables+3)
-      nCellsGlobal = int(reductions(nVariables+4))
-      nEdgesGlobal = int(reductions(nVariables+5))
-      nVerticesGlobal = int(reductions(nVariables+6))
-
-      call dmpar_min_real_array(dminfo, nMins, mins(1:nMins), reductions(1:nMins))
-      mins(1:nVariables) = reductions(1:nVariables)
-      verticalSumMins(1:nVariables) = reductions(nMins-nVariables+1:nMins)
-
-      call dmpar_max_real_array(dminfo, nMaxes, maxes(1:nMaxes), reductions(1:nMaxes))
-      maxes(1:nVariables) = reductions(1:nVariables)
-      CFLNumberGlobal = reductions(nVariables+1)
-      verticalSumMaxes(1:nVariables) = reductions(nMaxes-nVariables+1:nMaxes)
-
-      volumeCellGlobal = sums(1)
-      volumeEdgeGlobal = sums(4)
-      ! compute the averages (slightly different depending on how the sum was computed)
-      variableIndex = 0
-      ! h
-      variableIndex = variableIndex + 1
-      averages(variableIndex) = sums(variableIndex)/(areaCellGlobal*nVertLevels)
-
-      ! u
-      variableIndex = variableIndex + 1
-      averages(variableIndex) = sums(variableIndex)/volumeEdgeGlobal
-
-      ! v
-      variableIndex = variableIndex + 1
-      averages(variableIndex) = sums(variableIndex)/volumeEdgeGlobal
-
-      ! h_edge
-      variableIndex = variableIndex + 1
-      averages(variableIndex) = sums(variableIndex)/(areaEdgeGlobal*nVertLevels)
-
-      ! circulation
-      variableIndex = variableIndex + 1
-      averages(variableIndex) = sums(variableIndex)/(nVerticesGlobal*nVertLevels)
-
-      ! vorticity
-      variableIndex = variableIndex + 1
-      averages(variableIndex) = sums(variableIndex)/(areaTriangleGlobal*nVertLevels)
-
-      ! ke
-      variableIndex = variableIndex + 1
-      averages(variableIndex) = sums(variableIndex)/volumeCellGlobal
-
-      ! pv_edge
-      variableIndex = variableIndex + 1
-      averages(variableIndex) = sums(variableIndex)/volumeEdgeGlobal
-
-      ! pv_vertex
-      variableIndex = variableIndex + 1
-      averages(variableIndex) = sums(variableIndex)/(areaTriangleGlobal*nVertLevels)
-
-      ! pv_cell
-      variableIndex = variableIndex + 1
-      averages(variableIndex) = sums(variableIndex)/volumeCellGlobal
-
-      ! gradPVn
-      variableIndex = variableIndex + 1
-      averages(variableIndex) = sums(variableIndex)/volumeEdgeGlobal
-
-      ! gradPVt
-      variableIndex = variableIndex + 1
-      averages(variableIndex) = sums(variableIndex)/volumeEdgeGlobal
-
-      ! pressure
-      variableIndex = variableIndex + 1
-      averages(variableIndex) = sums(variableIndex)/volumeCellGlobal
-
-      ! MontPot
-      variableIndex = variableIndex + 1
-      averages(variableIndex) = sums(variableIndex)/volumeCellGlobal
-
-      ! wTop vertical velocity
-      variableIndex = variableIndex + 1
-      averages(variableIndex) = sums(variableIndex)/volumeCellGlobal
-
-      ! Tracers
-      do iTracer=1,num_tracers
-        variableIndex = variableIndex + 1
-        averages(variableIndex) = sums(variableIndex)/volumeCellGlobal
-      enddo
-
-      ! write out the data to files
-      if (dminfo % my_proc_id == IO_NODE) then
-         fileID = getFreeUnit()
-         open(fileID,file='stats_min.txt',ACCESS='append')
-            write (fileID,'(100es24.16)') mins(1:nVariables)
-         close (fileID)
-         open(fileID,file='stats_max.txt',ACCESS='append')
-            write (fileID,'(100es24.16)') maxes(1:nVariables)
-         close (fileID)
-         open(fileID,file='stats_sum.txt',ACCESS='append')
-            write (fileID,'(100es24.16)') sums(1:nVariables)
-         close (fileID)
-         open(fileID,file='stats_avg.txt',ACCESS='append')
-            write (fileID,'(100es24.16)') averages(1:nVariables)
-         close (fileID)
-         open(fileID,file='stats_time.txt',ACCESS='append')
-            write (fileID,'(i5,10x,a,100es24.16)') timeIndex, &amp;
-               state % xtime % scalar, dt, &amp;
-               CFLNumberGlobal
-         close (fileID)
-         open(fileID,file='stats_colmin.txt',ACCESS='append')
-            write (fileID,'(100es24.16)') verticalSumMins(1:nVariables)
-         close (fileID)
-         open(fileID,file='stats_colmax.txt',ACCESS='append')
-            write (fileID,'(100es24.16)') verticalSumMaxes(1:nVariables)
-         close (fileID)
-      end if
-
-      state % areaCellGlobal % scalar = areaCellGlobal
-      state % areaEdgeGlobal % scalar = areaEdgeGlobal
-      state % areaTriangleGlobal % scalar = areaTriangleGlobal
-
-      state % volumeCellGlobal % scalar = volumeCellGlobal
-      state % volumeEdgeGlobal % scalar = volumeEdgeGlobal
-      state % CFLNumberGlobal % scalar = CFLNumberGlobal
-      deallocate(areaEdge)
-
-   end subroutine computeGlobalDiagnostics
-
-   integer function getFreeUnit()
-      implicit none
-
-      integer :: index
-      logical :: isOpened
-
-      getFreeUnit = 0
-      do index = 1,99
-         if((index /= 5) .and. (index /= 6)) then
-            inquire(unit = index, opened = isOpened)
-            if( .not. isOpened) then
-               getFreeUnit = index
-               return
-            end if
-         end if
-      end do
-   end function getFreeUnit
-
-   subroutine computeFieldLocalStats(dminfo, nVertLevels, nElements, field, localSum, localMin, localMax, localVertSumMin, &amp;
-      localVertSumMax)
-
-      implicit none
-
-      type (dm_info), intent(in) :: dminfo
-      integer, intent(in) :: nVertLevels, nElements
-      real (kind=RKIND), dimension(nVertLevels, nElements), intent(in) :: field
-      real (kind=RKIND), intent(out) :: localSum, localMin, localMax, localVertSumMin, &amp;
-      localVertSumMax
-
-      localSum = sum(field)
-      localMin = minval(field)
-      localMax = maxval(field)
-      localVertSumMin = minval(sum(field,1))
-      localVertSumMax = maxval(sum(field,1))
-
-   end subroutine computeFieldLocalStats
-
-   subroutine computeFieldAreaWeightedLocalStats(dminfo, nVertLevels, nElements, areas, field, localSum, localMin, &amp;
-      localMax, localVertSumMin, localVertSumMax)
-
-      implicit none
-
-      type (dm_info), intent(in) :: dminfo
-      integer, intent(in) :: nVertLevels, nElements
-      real (kind=RKIND), dimension(nElements), intent(in) :: areas
-      real (kind=RKIND), dimension(nVertLevels, nElements), intent(in) :: field
-      real (kind=RKIND), intent(out) :: localSum, localMin, localMax, localVertSumMin, &amp;
-      localVertSumMax
-
-      integer :: elementIndex
-
-      localSum = 0.0
-      do elementIndex = 1, nElements
-        localSum = localSum + areas(elementIndex) * sum(field(:,elementIndex))
-      end do
-
-      localMin = minval(field)
-      localMax = maxval(field)
-      localVertSumMin = minval(sum(field,1))
-      localVertSumMax = maxval(sum(field,1))
-
-   end subroutine computeFieldAreaWeightedLocalStats
-
-   subroutine computeFieldThicknessWeightedLocalStats(dminfo, nVertLevels, nElements, h, field, &amp;
-      localSum, localMin, localMax, localVertSumMin, localVertSumMax)
-
-      implicit none
-
-      type (dm_info), intent(in) :: dminfo
-      integer, intent(in) :: nVertLevels, nElements
-      real (kind=RKIND), dimension(nVertLevels, nElements), intent(in) :: h
-      real (kind=RKIND), dimension(nVertLevels, nElements), intent(in) :: field
-      real (kind=RKIND), intent(out) :: localSum, localMin, localMax, localVertSumMin, &amp;
-      localVertSumMax
-
-      real (kind=RKIND), dimension(nVertLevels, nElements) :: hTimesField
-
-      integer :: elementIndex
-
-      localSum = sum(h*field)
-      localMin = minval(field)
-      localMax = maxval(field)
-      localVertSumMin = minval(sum(h*field,1))
-      localVertSumMax = maxval(sum(h*field,1))
-
-   end subroutine computeFieldThicknessWeightedLocalStats
-
-   subroutine computeFieldVolumeWeightedLocalStats(dminfo, nVertLevels, nElements, areas, h, field, &amp;
-      localSum, localMin, localMax, localVertSumMin, localVertSumMax)
-
-      implicit none
-
-      type (dm_info), intent(in) :: dminfo
-      integer, intent(in) :: nVertLevels, nElements
-      real (kind=RKIND), dimension(nElements), intent(in) :: areas
-      real (kind=RKIND), dimension(nVertLevels, nElements), intent(in) :: h
-      real (kind=RKIND), dimension(nVertLevels, nElements), intent(in) :: field
-      real (kind=RKIND), intent(out) :: localSum, localMin, localMax, localVertSumMin, &amp;
-      localVertSumMax
-
-      real (kind=RKIND), dimension(nVertLevels, nElements) :: hTimesField
-
-      integer :: elementIndex
-
-      localSum = 0.0
-      do elementIndex = 1, nElements
-        localSum = localSum + areas(elementIndex) * sum(h(:,elementIndex)*field(:,elementIndex))
-      end do
-
-      localMin = minval(field)
-      localMax = maxval(field)
-      localVertSumMin = minval(sum(h*field,1))
-      localVertSumMax = maxval(sum(h*field,1))
-
-   end subroutine computeFieldVolumeWeightedLocalStats
-
-
-   subroutine computeGlobalSum(dminfo, nVertLevels, nElements, field, globalSum)
-
-      implicit none
-
-      type (dm_info), intent(in) :: dminfo
-      integer, intent(in) :: nVertLevels, nElements
-      real (kind=RKIND), dimension(nVertLevels, nElements), intent(in) :: field
-      real (kind=RKIND), intent(out) :: globalSum
-
-      real (kind=RKIND) :: localSum
-
-      localSum = sum(field)
-      call dmpar_sum_real(dminfo, localSum, globalSum)
-
-   end subroutine computeGlobalSum
-
-   subroutine computeAreaWeightedGlobalSum(dminfo, nVertLevels, nElements, areas, field, globalSum)
-
-      implicit none
-
-      type (dm_info), intent(in) :: dminfo
-      integer, intent(in) :: nVertLevels, nElements
-      real (kind=RKIND), dimension(nElements), intent(in) :: areas
-      real (kind=RKIND), dimension(nVertLevels, nElements), intent(in) :: field
-      real (kind=RKIND), intent(out) :: globalSum
-      
-      integer :: elementIndex
-      real (kind=RKIND) :: localSum
-
-      localSum = 0.
-      do elementIndex = 1, nElements
-        localSum = localSum + areas(elementIndex) * sum(field(:,elementIndex))
-      end do
-   
-      call dmpar_sum_real(dminfo, localSum, globalSum)
-       
-   end subroutine computeAreaWeightedGlobalSum
-
-   subroutine computeVolumeWeightedGlobalSum(dminfo, nVertLevels, nElements, areas, h, field, globalSum)
-
-      implicit none
-
-      type (dm_info), intent(in) :: dminfo
-      integer, intent(in) :: nVertLevels, nElements
-      real (kind=RKIND), dimension(nElements), intent(in) :: areas
-      real (kind=RKIND), dimension(nVertLevels, nElements), intent(in) :: h
-      real (kind=RKIND), dimension(nVertLevels, nElements), intent(in) :: field
-      real (kind=RKIND), intent(out) :: globalSum
-
-      real (kind=RKIND), dimension(nVertLevels, nElements) :: hTimesField
-
-      hTimesField = h*field
-
-      call computeAreaWeightedGlobalSum(dminfo, nVertLevels, nElements, areas, hTimesField, globalSum)
-
-   end subroutine computeVolumeWeightedGlobalSum
-
-   subroutine computeGlobalMin(dminfo, nVertLevels, nElements, field, globalMin)
-
-      implicit none
-
-      type (dm_info), intent(in) :: dminfo
-      integer, intent(in) :: nVertLevels, nElements
-      real (kind=RKIND), dimension(nVertLevels, nElements), intent(in) :: field
-      real (kind=RKIND), intent(out) :: globalMin
-
-      real (kind=RKIND) :: localMin
-
-      localMin = minval(field)
-      call dmpar_min_real(dminfo, localMin, globalMin)
-
-   end subroutine computeGlobalMin
-
-   subroutine computeGlobalMax(dminfo, nVertLevels, nElements, field, globalMax)
-
-      implicit none
-
-      type (dm_info), intent(in) :: dminfo
-      integer, intent(in) :: nVertLevels, nElements
-      real (kind=RKIND), dimension(nVertLevels, nElements), intent(in) :: field
-      real (kind=RKIND), intent(out) :: globalMax
-
-      real (kind=RKIND) :: localMax
-
-      localMax = maxval(field)
-      call dmpar_max_real(dminfo, localMax, globalMax)
-
-   end subroutine computeGlobalMax
-
-   subroutine computeGlobalVertSumHorizMin(dminfo, nVertLevels, nElements, field, globalMin)
-
-      implicit none
-
-      type (dm_info), intent(in) :: dminfo
-      integer, intent(in) :: nVertLevels, nElements
-      real (kind=RKIND), dimension(nVertLevels, nElements), intent(in) :: field
-      real (kind=RKIND), intent(out) :: globalMin
-
-      real (kind=RKIND) :: localMin
-
-      localMin = minval(sum(field,1))
-      call dmpar_min_real(dminfo, localMin, globalMin)
-
-   end subroutine computeGlobalVertSumHorizMin
-
-   subroutine computeGlobalVertSumHorizMax(dminfo, nVertLevels, nElements, field, globalMax)
-
-      implicit none
-
-      type (dm_info), intent(in) :: dminfo
-      integer, intent(in) :: nVertLevels, nElements
-      real (kind=RKIND), dimension(nVertLevels, nElements), intent(in) :: field
-      real (kind=RKIND), intent(out) :: globalMax
-
-      real (kind=RKIND) :: localMax
-
-      localMax = maxval(sum(field,1))
-      call dmpar_max_real(dminfo, localMax, globalMax)
-
-   end subroutine computeGlobalVertSumHorizMax
-
-   subroutine computeGlobalVertThicknessWeightedSumHorizMin(dminfo, nVertLevels, nElements, h, field, globalMin)
-
-      implicit none
-
-      type (dm_info), intent(in) :: dminfo
-      integer, intent(in) :: nVertLevels, nElements
-      real (kind=RKIND), dimension(nVertLevels, nElements), intent(in) :: h, field
-      real (kind=RKIND), intent(out) :: globalMin
-
-      real (kind=RKIND) :: localMin
-
-      localMin = minval(sum(h*field,1))
-      call dmpar_min_real(dminfo, localMin, globalMin)
-
-   end subroutine computeGlobalVertThicknessWeightedSumHorizMin
-
-   subroutine computeGlobalVertThicknessWeightedSumHorizMax(dminfo, nVertLevels, nElements, h, field, globalMax)
-
-      implicit none
-
-      type (dm_info), intent(in) :: dminfo
-      integer, intent(in) :: nVertLevels, nElements
-      real (kind=RKIND), dimension(nVertLevels, nElements), intent(in) :: h, field
-      real (kind=RKIND), intent(out) :: globalMax
-
-      real (kind=RKIND) :: localMax
-
-      localMax = maxval(sum(h*field,1))
-      call dmpar_max_real(dminfo, localMax, globalMax)
-
-   end subroutine computeGlobalVertThicknessWeightedSumHorizMax
-
-end module global_diagnostics

Deleted: trunk/mpas/src/core_ocean/module_mpas_core.F
===================================================================
--- trunk/mpas/src/core_ocean/module_mpas_core.F        2011-09-30 18:04:47 UTC (rev 1046)
+++ trunk/mpas/src/core_ocean/module_mpas_core.F        2011-09-30 18:20:19 UTC (rev 1047)
@@ -1,582 +0,0 @@
-module mpas_core
-
-   use mpas_framework
-   use mpas_timekeeping
-   use dmpar
-   use test_cases
-
-   type (io_output_object) :: restart_obj
-   integer :: restart_frame
-
-   integer :: current_outfile_frames
-
-   type (MPAS_Clock_type) :: clock
-
-   integer, parameter :: outputAlarmID = 1
-   integer, parameter :: restartAlarmID = 2
-   integer, parameter :: statsAlarmID = 3
-
-   contains
-
-   subroutine mpas_core_init(domain, startTimeStamp)
-
-      use configure
-      use grid_types
-
-      implicit none
-
-      type (domain_type), intent(inout) :: domain
-      character(len=*), intent(out) :: startTimeStamp
-
-      real (kind=RKIND) :: dt
-      type (block_type), pointer :: block
-      type (dm_info) :: dminfo
-
-      if (.not. config_do_restart) call setup_sw_test_case(domain)
-
-      if (config_vert_grid_type.eq.'isopycnal') then
-         print *, ' Using isopycnal coordinates'
-      elseif (config_vert_grid_type.eq.'zlevel') then
-         print *, ' Using z-level coordinates'
-         call init_ZLevel(domain)
-      else 
-         print *, ' Incorrect choice of config_vert_grid_type:',&amp;
-           config_vert_grid_type
-         call dmpar_abort(dminfo)
-      endif
-
-      call compute_maxLevel(domain)
-
-      !
-      ! Initialize core
-      !
-      dt = config_dt
-
-      call simulation_clock_init(domain, dt, startTimeStamp)
-
-      block =&gt; domain % blocklist
-      do while (associated(block))
-         call mpas_init_block(block, block % mesh, dt)
-         block % state % time_levs(1) % state % xtime % scalar = startTimeStamp 
-         block =&gt; block % next
-      end do
-
-   ! mrp 100316 In order for this to work, we need to pass domain % dminfo as an 
-   ! input arguement into mpas_init.  Ask about that later.  For now, there will be
-   ! no initial statistics write.
-   
-   !   call timer_start(&quot;global diagnostics&quot;)
-   !   call computeGlobalDiagnostics(domain % dminfo, block % state % time_levs(1) % state, mesh, 0, dt)
-   !   call timer_stop(&quot;global diagnostics&quot;)
-   !   call output_state_init(output_obj, domain, &quot;OUTPUT&quot;)
-   !   call write_output_frame(output_obj, domain)
-
-      restart_frame = 1
-      current_outfile_frames = 0
-
-   end subroutine mpas_core_init
-
-
-   subroutine simulation_clock_init(domain, dt, startTimeStamp)
-
-      implicit none
-
-      type (domain_type), intent(inout) :: domain
-      real (kind=RKIND), intent(in) :: dt
-      character(len=*), intent(out) :: startTimeStamp
-
-      type (MPAS_Time_Type) :: startTime, stopTime, alarmStartTime
-      type (MPAS_TimeInterval_type) :: runDuration, timeStep, alarmTimeStep
-      integer :: ierr
-
-      call MPAS_setTime(curr_time=startTime, dateTimeString=config_start_time, ierr=ierr)
-      call MPAS_setTimeInterval(timeStep, dt=dt, ierr=ierr)
-
-      if (trim(config_run_duration) /= &quot;none&quot;) then
-         call MPAS_setTimeInterval(runDuration, timeString=config_run_duration, ierr=ierr)
-         call MPAS_createClock(clock, startTime=startTime, timeStep=timeStep, runDuration=runDuration, ierr=ierr)
-
-         if (trim(config_stop_time) /= &quot;none&quot;) then
-            call MPAS_setTime(curr_time=stopTime, dateTimeString=config_stop_time, ierr=ierr)
-            if(startTime + runduration /= stopTime) then
-               write(0,*) 'Warning: config_run_duration and config_stop_time are inconsitent: using config_run_duration.'
-            end if
-         end if
-      else if (trim(config_stop_time) /= &quot;none&quot;) then
-         call MPAS_setTime(curr_time=stopTime, dateTimeString=config_stop_time, ierr=ierr)
-         call MPAS_createClock(clock, startTime=startTime, timeStep=timeStep, stopTime=stopTime, ierr=ierr)
-      else
-          write(0,*) 'Error: Neither config_run_duration nor config_stop_time were specified.'
-          call dmpar_finalize(domain % dminfo)
-      end if
-
-      ! set output alarm
-      call MPAS_setTimeInterval(alarmTimeStep, timeString=config_output_interval, ierr=ierr)
-      alarmStartTime = startTime + alarmTimeStep
-      call MPAS_addClockAlarm(clock, outputAlarmID, alarmStartTime, alarmTimeStep, ierr=ierr)
-
-      ! set restart alarm, if necessary
-      if (trim(config_restart_interval) /= &quot;none&quot;) then
-         call MPAS_setTimeInterval(alarmTimeStep, timeString=config_restart_interval, ierr=ierr)
-         alarmStartTime = startTime + alarmTimeStep
-         call MPAS_addClockAlarm(clock, restartAlarmID, alarmStartTime, alarmTimeStep, ierr=ierr)
-      end if
-
-      !TODO: use this code if we desire to convert config_stats_interval to alarms 
-      !(must also change config_stats_interval type to character) 
-      ! set stats alarm, if necessary
-      !if (trim(config_stats_interval) /= &quot;none&quot;) then      
-      !   call MPAS_setTimeInterval(alarmTimeStep, timeString=config_stats_interval, ierr=ierr)
-      !   alarmStartTime = startTime + alarmTimeStep
-      !   call MPAS_addClockAlarm(clock, statsAlarmID, alarmStartTime, alarmTimeStep, ierr=ierr)
-      !end if
-
-      call MPAS_getTime(curr_time=startTime, dateTimeString=startTimeStamp, ierr=ierr)
-
-   end subroutine simulation_clock_init
-
-
-   subroutine mpas_init_block(block, mesh, dt)
-   
-      use grid_types
-      use time_integration
-      use RBF_interpolation
-      use vector_reconstruction
-   
-      implicit none
-   
-      type (block_type), intent(inout) :: block
-      type (mesh_type), intent(inout) :: mesh
-      real (kind=RKIND), intent(in) :: dt
-      integer :: i, iEdge, iCell, k
-   
-   
-      call compute_solve_diagnostics(dt, block % state % time_levs(1) % state, mesh)

-      call rbfInterp_initialize(mesh)
-      call init_reconstruct(mesh)
-      call reconstruct(block % state % time_levs(1) % state, mesh)
-
-      ! initialize velocities and tracers on land to be -1e34
-      ! The reconstructed velocity on land will have values not exactly
-      ! -1e34 due to the interpolation of reconstruction.
-
-      do iEdge=1,block % mesh % nEdges
-         ! mrp 101115 note: in order to include flux boundary conditions, the following
-         ! line will need to change.  Right now, set boundary edges between land and 
-         ! water to have zero velocity.
-         block % state % time_levs(1) % state % u % array( &amp;
-             block % mesh % maxLevelEdgeTop % array(iEdge)+1 &amp;
-            :block % mesh % maxLevelEdgeBot % array(iEdge), iEdge) = 0.0
-
-         block % state % time_levs(1) % state % u % array( &amp;
-             block % mesh % maxLevelEdgeBot % array(iEdge)+1: &amp;
-             block % mesh % nVertLevels,iEdge) = -1e34
-      end do
-      do iCell=1,block % mesh % nCells
-         block % state % time_levs(1) % state % tracers % array( &amp;
-            :, block % mesh % maxLevelCell % array(iCell)+1 &amp;
-              :block % mesh % nVertLevels,iCell) =  -1e34
-      end do
-   
-      if (config_do_restart) then 
-          do i=2,nTimeLevs
-             call copy_state(block % state % time_levs(i) % state, &amp;
-                             block % state % time_levs(1) % state)
-          end do
-      endif
-   
-   end subroutine mpas_init_block
-   
-   
-   subroutine mpas_core_run(domain, output_obj, output_frame)
-   
-      use grid_types
-      use io_output
-      use timer
-   
-      implicit none
-   
-      type (domain_type), intent(inout) :: domain
-      type (io_output_object), intent(inout) :: output_obj
-      integer, intent(inout) :: output_frame
-   
-      integer :: itimestep
-      real (kind=RKIND) :: dt
-      type (block_type), pointer :: block_ptr
-
-      type (MPAS_Time_Type) :: currTime
-      character(len=32) :: timeStamp
-      integer :: ierr
-   
-      ! Eventually, dt should be domain specific
-      dt = config_dt
-
-      currTime = MPAS_getClockTime(clock, MPAS_NOW, ierr)
-      call MPAS_getTime(curr_time=currTime, dateTimeString=timeStamp, ierr=ierr)
-      write(0,*) 'Initial time ', timeStamp
-
-      call write_output_frame(output_obj, output_frame, domain)
-   
-      ! During integration, time level 1 stores the model state at the beginning of the
-      !   time step, and time level 2 stores the state advanced dt in time by timestep(...)
-      itimestep = 0
-      do while (.not. MPAS_isClockStopTime(clock))
-
-         itimestep = itimestep + 1
-         call MPAS_advanceClock(clock)
-
-         currTime = MPAS_getClockTime(clock, MPAS_NOW, ierr)
-         call MPAS_getTime(curr_time=currTime, dateTimeString=timeStamp, ierr=ierr)
-         write(0,*) 'Doing timestep ', timeStamp
-
-         call timer_start(&quot;time integration&quot;)
-         call mpas_timestep(domain, itimestep, dt, timeStamp)
-         call timer_stop(&quot;time integration&quot;)
-   
-         ! Move time level 2 fields back into time level 1 for next time step
-         call shift_time_levels_state(domain % blocklist % state)
-      
-         if (MPAS_isAlarmRinging(clock, outputAlarmID, ierr=ierr)) then
-            call MPAS_resetClockAlarm(clock, outputAlarmID, ierr=ierr)
-            if(output_frame == 1) call output_state_init(output_obj, domain, &quot;OUTPUT&quot;, trim(timeStamp)) ! output_frame will always be &gt; 1 here unless it is reset after the output file is finalized
-            call write_output_frame(output_obj, output_frame, domain)
-         end if
-
-         if (MPAS_isAlarmRinging(clock, restartAlarmID, ierr=ierr)) then
-            call MPAS_resetClockAlarm(clock, restartAlarmID, ierr=ierr)
-            if (restart_frame == 1) call output_state_init(restart_obj, domain, &quot;RESTART&quot;)
-            call output_state_for_domain(restart_obj, domain, restart_frame)
-            restart_frame = restart_frame + 1
-         end if
-
-      end do
-
-   end subroutine mpas_core_run
-   
-   
-   subroutine write_output_frame(output_obj, output_frame, domain)
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   ! Compute diagnostic fields for a domain and write model state to output file
-   !
-   ! Input/Output: domain - contains model state; diagnostic field are computed
-   !                        before returning
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   
-      use grid_types
-      use io_output
-   
-      implicit none
-   
-      integer, intent(inout) :: output_frame
-      type (domain_type), intent(inout) :: domain
-      type (io_output_object), intent(inout) :: output_obj
-   
-      integer :: i, j, k
-      integer :: eoe
-      type (block_type), pointer :: block_ptr
-   
-      block_ptr =&gt; domain % blocklist
-      do while (associated(block_ptr))
-         call compute_output_diagnostics(block_ptr % state % time_levs(1) % state, block_ptr % mesh)
-         block_ptr =&gt; block_ptr % next
-      end do
-   
-      call output_state_for_domain(output_obj, domain, output_frame)
-      output_frame = output_frame + 1
-
-      ! if the maximum number of frames per outfile has been reached, finalize outfile and reset frame
-      if (config_frames_per_outfile &gt; 0) then
-         current_outfile_frames = current_outfile_frames + 1            
-         if(current_outfile_frames &gt;= config_frames_per_outfile) then
-            current_outfile_frames = 0
-            call output_state_finalize(output_obj, domain % dminfo)
-            output_frame = 1
-         end if
-      end if
-   
-   end subroutine write_output_frame
-   
-   
-   subroutine compute_output_diagnostics(state, grid)
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   ! Compute diagnostic fields for a domain
-   !
-   ! Input: state - contains model prognostic fields
-   !        grid  - contains grid metadata
-   !
-   ! Output: state - upon returning, diagnostic fields will have be computed
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   
-      use grid_types
-   
-      implicit none
-   
-      type (state_type), intent(inout) :: state
-      type (mesh_type), intent(in) :: grid
-   
-      integer :: i, eoe
-      integer :: iEdge, k
-   
-   end subroutine compute_output_diagnostics
-   
-   
-   subroutine mpas_timestep(domain, itimestep, dt, timeStamp)
-   
-      use grid_types
-      use time_integration
-      use timer
-      use global_diagnostics
-   
-      implicit none
-   
-      type (domain_type), intent(inout) :: domain 
-      integer, intent(in) :: itimestep
-      real (kind=RKIND), intent(in) :: dt
-      character(len=*), intent(in) :: timeStamp
-
-      type (block_type), pointer :: block_ptr
-      integer :: ierr
-   
-      call timestep(domain, dt, timeStamp)
-
-      if (config_stats_interval &gt; 0) then
-          if (mod(itimestep, config_stats_interval) == 0) then
-              block_ptr =&gt; domain % blocklist
-              if (associated(block_ptr % next)) then
-                  write(0,*) 'Error: computeGlobalDiagnostics assumes ',&amp;
-                     'that there is only one block per processor.'
-              end if
-
-          call timer_start(&quot;global diagnostics&quot;)
-          call computeGlobalDiagnostics(domain % dminfo, &amp;
-             block_ptr % state % time_levs(2) % state, block_ptr % mesh, &amp;
-             itimestep, dt)
-          call timer_stop(&quot;global diagnostics&quot;)
-          end if
-      end if
-
-      !TODO: replace the above code block with this if we desire to convert config_stats_interval to use alarms
-      !if (MPAS_isAlarmRinging(clock, statsAlarmID, ierr=ierr)) then
-      !   call MPAS_resetClockAlarm(clock, statsAlarmID, ierr=ierr)
-
-      !   block_ptr =&gt; domain % blocklist
-      !   if (associated(block_ptr % next)) then
-      !      write(0,*) 'Error: computeGlobalDiagnostics assumes ',&amp;
-      !                 'that there is only one block per processor.'
-      !   end if
-   
-      !   call timer_start(&quot;global diagnostics&quot;)
-      !   call computeGlobalDiagnostics(domain % dminfo, &amp;
-      !            block_ptr % state % time_levs(2) % state, block_ptr % mesh, &amp;
-      !            timeStamp, dt)
-      !   call timer_stop(&quot;global diagnostics&quot;)
-      !end if
-
-   end subroutine mpas_timestep
-
-
-subroutine init_ZLevel(domain)
-! Initialize maxLevel and bouncary grid variables.
-
-   use grid_types
-   use configure
-
-   implicit none
-
-   type (domain_type), intent(inout) :: domain
-
-   integer :: i, iCell, iEdge, iVertex, k
-   type (block_type), pointer :: block
-
-   integer :: iTracer, cell
-   real (kind=RKIND), dimension(:), pointer :: &amp;
-      hZLevel, zMidZLevel, zTopZLevel, &amp;
-      hMeanTopZLevel, hRatioZLevelK, hRatioZLevelKm1
-   real (kind=RKIND), dimension(:,:), pointer :: h
-   integer :: nVertLevels
-
-   ! Initialize z-level grid variables from h, read in from input file.
-   block =&gt; domain % blocklist
-   do while (associated(block))
-
-      h          =&gt; block % state % time_levs(1) % state % h % array
-      hZLevel    =&gt; block % mesh % hZLevel % array
-      zMidZLevel =&gt; block % mesh % zMidZLevel % array
-      zTopZLevel =&gt; block % mesh % zTopZLevel % array
-      nVertLevels = block % mesh % nVertLevels
-      hMeanTopZLevel    =&gt; block % mesh % hMeanTopZLevel % array
-      hRatioZLevelK    =&gt; block % mesh % hRatioZLevelK % array
-      hRatioZLevelKm1    =&gt; block % mesh % hRatioZLevelKm1 % array
-
-      ! These should eventually be in an input file.  For now
-      ! I just read them in from h(:,1).
-      ! Upon restart, the correct hZLevel should be in restart.nc
-      if (.not. config_do_restart) hZLevel = h(:,1)
-
-      ! hZLevel should be in the grid.nc and restart.nc file, 
-      ! and h for k=1 must be specified there as well.

-      zTopZLevel(1) = 0.0
-      do k = 1,nVertLevels
-         zMidZLevel(k) = zTopZLevel(k)-0.5*hZLevel(k)
-         zTopZLevel(k+1) = zTopZLevel(k)-  hZLevel(k)
-      end do
-
-      hMeanTopZLevel(1) = 0.0
-      hRatioZLevelK(1) = 0.0
-      hRatioZLevelKm1(1) = 0.0
-      do k = 2,nVertLevels
-         hMeanTopZLevel(k) = 0.5*(hZLevel(k-1) + hZLevel(k))
-         hRatioZLevelK(k) = 0.5*hZLevel(k)/hMeanTopZLevel(k)
-         hRatioZLevelKm1(k) = 0.5*hZLevel(k-1)/hMeanTopZLevel(k)
-      end do
-
-      block =&gt; block % next
-
-   end do
-
-end subroutine init_ZLevel
-
-
-subroutine compute_maxLevel(domain)
-! Initialize maxLevel and bouncary grid variables.
-
-   use grid_types
-   use configure
-   use constants
-
-   implicit none
-
-   type (domain_type), intent(inout) :: domain
-
-   integer :: i, iCell, iEdge, iVertex, k
-   type (block_type), pointer :: block
-
-   real (kind=RKIND), dimension(:,:), pointer :: h, u, u_src, rho
-   real (kind=RKIND), dimension(:,:,:), pointer :: tracers
-   real (kind=RKIND) :: delta_rho, pi, latCenter, lonCenter, dist
-   real (kind=RKIND) :: centerx, centery
-   integer :: nCells, nEdges, nVertices, nVertLevels, vertexDegree
-
-   integer, dimension(:), pointer :: &amp;
-      maxLevelCell, maxLevelEdgeTop, maxLevelEdgeBot, &amp;
-      maxLevelVertexTop, maxLevelVertexBot
-   integer, dimension(:,:), pointer :: &amp;
-      cellsOnEdge, cellsOnVertex, boundaryEdge, boundaryCell, &amp;
-      boundaryVertex, verticesOnEdge
-
-   ! Initialize z-level grid variables from h, read in from input file.
-   block =&gt; domain % blocklist
-   do while (associated(block))
-
-      maxLevelCell =&gt; block % mesh % maxLevelCell % array
-      maxLevelEdgeTop =&gt; block % mesh % maxLevelEdgeTop % array
-      maxLevelEdgeBot =&gt; block % mesh % maxLevelEdgeBot % array
-      maxLevelVertexTop =&gt; block % mesh % maxLevelVertexTop % array
-      maxLevelVertexBot =&gt; block % mesh % maxLevelVertexBot % array
-      cellsOnEdge    =&gt; block % mesh % cellsOnEdge % array
-      cellsOnVertex  =&gt; block % mesh % cellsOnVertex % array
-      verticesOnEdge =&gt; block % mesh % verticesOnEdge % array
-      boundaryEdge   =&gt; block % mesh % boundaryEdge % array
-      boundaryCell   =&gt; block % mesh % boundaryCell % array
-      boundaryVertex =&gt; block % mesh % boundaryVertex % array
-
-      nCells      = block % mesh % nCells
-      nEdges      = block % mesh % nEdges
-      nVertices   = block % mesh % nVertices
-      nVertLevels = block % mesh % nVertLevels
-      vertexDegree = block % mesh % vertexDegree
-
-      ! for z-grids, maxLevelCell should be in input state
-      ! Isopycnal grid uses all vertical cells
-      if (config_vert_grid_type.eq.'isopycnal') then
-         maxLevelCell(1:nCells) = nVertLevels
-      endif
-      maxLevelCell(nCells+1) = 0
-
-      ! maxLevelEdgeTop is the minimum (shallowest) of the surrounding cells
-      do iEdge=1,nEdges
-         maxLevelEdgeTop(iEdge) = &amp;
-            min( maxLevelCell(cellsOnEdge(1,iEdge)), &amp;
-                 maxLevelCell(cellsOnEdge(2,iEdge)) )
-      end do 
-      maxLevelEdgeTop(nEdges+1) = 0
-
-      ! maxLevelEdgeBot is the maximum (deepest) of the surrounding cells
-      do iEdge=1,nEdges
-         maxLevelEdgeBot(iEdge) = &amp;
-            max( maxLevelCell(cellsOnEdge(1,iEdge)), &amp;
-                 maxLevelCell(cellsOnEdge(2,iEdge)) )
-      end do 
-      maxLevelEdgeBot(nEdges+1) = 0
-
-      ! maxLevelVertexBot is the maximum (deepest) of the surrounding cells
-      do iVertex = 1,nVertices
-         maxLevelVertexBot(iVertex) = maxLevelCell(cellsOnVertex(1,iVertex))
-         do i=2,vertexDegree
-            maxLevelVertexBot(iVertex) = &amp;
-               max( maxLevelVertexBot(iVertex), &amp;
-                    maxLevelCell(cellsOnVertex(i,iVertex)))
-         end do
-      end do 
-      maxLevelVertexBot(nVertices+1) = 0
-
-      ! maxLevelVertexTop is the minimum (shallowest) of the surrounding cells
-      do iVertex = 1,nVertices
-         maxLevelVertexTop(iVertex) = maxLevelCell(cellsOnVertex(1,iVertex))
-         do i=2,vertexDegree
-            maxLevelVertexTop(iVertex) = &amp;
-               min( maxLevelVertexTop(iVertex), &amp;
-                    maxLevelCell(cellsOnVertex(i,iVertex)))
-         end do
-      end do 
-      maxLevelVertexTop(nVertices+1) = 0
-
-      ! set boundary edge
-      boundaryEdge=1
-      do iEdge=1,nEdges
-         boundaryEdge(1:maxLevelEdgeTop(iEdge),iEdge)=0
-      end do 
-
-      !
-      ! Find cells and vertices that have an edge on the boundary
-      !
-      boundaryCell(:,:) = 0
-      do iEdge=1,nEdges
-         do k=1,nVertLevels
-            if (boundaryEdge(k,iEdge).eq.1) then
-               boundaryCell(k,cellsOnEdge(1,iEdge)) = 1
-               boundaryCell(k,cellsOnEdge(2,iEdge)) = 1
-               boundaryVertex(k,verticesOnEdge(1,iEdge)) = 1
-               boundaryVertex(k,verticesOnEdge(2,iEdge)) = 1
-            endif
-         end do
-      end do
-
-      block =&gt; block % next
-   end do
-
-   ! Note: We do not update halos on maxLevel* variables.  I want the
-   ! outside edge of a halo to be zero on each processor.
-
-end subroutine compute_maxLevel
-   
-   
-   subroutine mpas_core_finalize(domain)
-   
-      use grid_types
-   
-      implicit none
-
-      integer :: ierr
-
-      type (domain_type), intent(inout) :: domain 
-
-      if (restart_frame &gt; 1) call output_state_finalize(restart_obj, domain % dminfo)
-
-      call MPAS_destroyClock(clock, ierr)
-
-   end subroutine mpas_core_finalize
-
-end module mpas_core

Deleted: trunk/mpas/src/core_ocean/module_test_cases.F
===================================================================
--- trunk/mpas/src/core_ocean/module_test_cases.F        2011-09-30 18:04:47 UTC (rev 1046)
+++ trunk/mpas/src/core_ocean/module_test_cases.F        2011-09-30 18:20:19 UTC (rev 1047)
@@ -1,526 +0,0 @@
- module test_cases
-
-   use grid_types
-   use configure
-   use constants
-
-
-   contains
-
-
-   subroutine setup_sw_test_case(domain)
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   ! Configure grid metadata and model state for the shallow water test case 
-   !   specified in the namelist
-   !
-   ! Output: block - a subset (not necessarily proper) of the model domain to be
-   !                 initialized
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-      implicit none
-
-      type (domain_type), intent(inout) :: domain
-
-      integer :: i, iCell, iEdge, iVtx, iLevel
-      type (block_type), pointer :: block_ptr
-      type (dm_info) :: dminfo
-
-      if (config_test_case == 0) then
-         write(0,*) 'Using initial conditions supplied in input file'
-
-      else if (config_test_case == 1) then
-         write(0,*) ' Setting up shallow water test case 1:'
-         write(0,*) ' Advection of Cosine Bell over the Pole'
-
-         block_ptr =&gt; domain % blocklist
-         do while (associated(block_ptr))
-            call sw_test_case_1(block_ptr % mesh, block_ptr % state % time_levs(1) % state)
-            block_ptr =&gt; block_ptr % next
-         end do
-
-      else if (config_test_case == 2) then
-         write(0,*) ' Setup shallow water test case 2: '// &amp;
-           'Global Steady State Nonlinear Zonal Geostrophic Flow'
-
-         block_ptr =&gt; domain % blocklist
-         do while (associated(block_ptr))
-            call sw_test_case_2(block_ptr % mesh, block_ptr % state % time_levs(1) % state)
-            block_ptr =&gt; block_ptr % next
-         end do
-
-      else if (config_test_case == 5) then
-         write(0,*) ' Setup shallow water test case 5:'// &amp;
-           ' Zonal Flow over an Isolated Mountain'
-
-         block_ptr =&gt; domain % blocklist
-         do while (associated(block_ptr))
-            call sw_test_case_5(block_ptr % mesh, block_ptr % state % time_levs(1) % state)
-            block_ptr =&gt; block_ptr % next
-         end do
-
-      else if (config_test_case == 6) then
-         write(0,*) ' Set up shallow water test case 6:'
-         write(0,*) ' Rossby-Haurwitz Wave'
-
-         block_ptr =&gt; domain % blocklist
-         do while (associated(block_ptr))
-            call sw_test_case_6(block_ptr % mesh, block_ptr % state % time_levs(1) % state)
-            block_ptr =&gt; block_ptr % next
-         end do
-
-      else
-         write(0,*) 'Abort: config_test_case=',config_test_case
-         write(0,*) 'Only test case 1, 2, 5, and 6 ', &amp;
-           'are currently supported.  '
-           call dmpar_abort(dminfo)
-      end if
-
-      block_ptr =&gt; domain % blocklist
-      do while (associated(block_ptr))
-
-        do i=2,nTimeLevs
-           call copy_state(block_ptr % state % time_levs(i) % state, &amp;
-                           block_ptr % state % time_levs(1) % state)
-        end do
-
-        block_ptr =&gt; block_ptr % next
-      end do
-
-   end subroutine setup_sw_test_case
-
-
-   subroutine sw_test_case_1(grid, state)
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   ! Setup shallow water test case 1: Advection of Cosine Bell over the Pole
-   !
-   ! Reference: Williamson, D.L., et al., &quot;A Standard Test Set for Numerical 
-   !            Approximations to the Shallow Water Equations in Spherical 
-   !            Geometry&quot; J. of Comp. Phys., 102, pp. 211--224
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-      implicit none
-
-      type (mesh_type), intent(inout) :: grid
-      type (state_type), intent(inout) :: state
-
-      real (kind=RKIND), parameter :: u0 = 2.0 * pii * a / (12.0 * 86400.0)
-      real (kind=RKIND), parameter :: h0 = 1000.0
-      real (kind=RKIND), parameter :: theta_c = 0.0
-      real (kind=RKIND), parameter :: lambda_c = 3.0*pii/2.0
-      real (kind=RKIND), parameter :: alpha = pii/4.0
-
-      integer :: iCell, iEdge, iVtx
-      real (kind=RKIND) :: r, u, v
-      real (kind=RKIND), allocatable, dimension(:) :: psiVertex
-
-      !
-      ! Scale all distances and areas from a unit sphere to one with radius a
-      !
-      grid % xCell % array = grid % xCell % array * a
-      grid % yCell % array = grid % yCell % array * a
-      grid % zCell % array = grid % zCell % array * a
-      grid % xVertex % array = grid % xVertex % array * a
-      grid % yVertex % array = grid % yVertex % array * a
-      grid % zVertex % array = grid % zVertex % array * a
-      grid % xEdge % array = grid % xEdge % array * a
-      grid % yEdge % array = grid % yEdge % array * a
-      grid % zEdge % array = grid % zEdge % array * a
-      grid % dvEdge % array = grid % dvEdge % array * a
-      grid % dcEdge % array = grid % dcEdge % array * a
-      grid % areaCell % array = grid % areaCell % array * a**2.0
-      grid % areaTriangle % array = grid % areaTriangle % array * a**2.0
-      grid % kiteAreasOnVertex % array = grid % kiteAreasOnVertex % array * a**2.0
-
-      !
-      ! Initialize wind field
-      !
-      allocate(psiVertex(grid % nVertices))
-      do iVtx=1,grid % nVertices
-         psiVertex(iVtx) = -a * u0 * ( &amp;
-                                       sin(grid%latVertex%array(iVtx)) * cos(alpha) - &amp;
-                                       cos(grid%lonVertex%array(iVtx)) * cos(grid%latVertex%array(iVtx)) * sin(alpha) &amp;
-                                     )
-      end do
-      do iEdge=1,grid % nEdges
-         state % u % array(1,iEdge) = -1.0 * ( &amp;
-                                               psiVertex(grid%verticesOnEdge%array(2,iEdge)) - &amp;
-                                               psiVertex(grid%verticesOnEdge%array(1,iEdge)) &amp;
-                                             ) / grid%dvEdge%array(iEdge)
-      end do
-      deallocate(psiVertex)
-
-      !
-      ! Initialize cosine bell at (theta_c, lambda_c)
-      !
-      do iCell=1,grid % nCells
-         r = sphere_distance(theta_c, lambda_c, grid % latCell % array(iCell), grid % lonCell % array(iCell), a) 
-         if (r &lt; a/3.0) then
-            state % h % array(1,iCell) = (h0 / 2.0) * (1.0 + cos(pii*r*3.0/a))
-         else
-            state % h % array(1,iCell) = 0.0
-         end if
-      end do
-
-   end subroutine sw_test_case_1
-
-
-   subroutine sw_test_case_2(grid, state)
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   ! Setup shallow water test case 2: Global Steady State Nonlinear Zonal 
-   !                                  Geostrophic Flow
-   !
-   ! Reference: Williamson, D.L., et al., &quot;A Standard Test Set for Numerical 
-   !            Approximations to the Shallow Water Equations in Spherical 
-   !            Geometry&quot; J. of Comp. Phys., 102, pp. 211--224
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-      implicit none
-
-      type (mesh_type), intent(inout) :: grid
-      type (state_type), intent(inout) :: state
-
-      real (kind=RKIND), parameter :: u0 = 2.0 * pii * a / (12.0 * 86400.0)
-      real (kind=RKIND), parameter :: gh0 = 29400.0
-      real (kind=RKIND), parameter :: alpha = 0.0
-
-      integer :: iCell, iEdge, iVtx
-      real (kind=RKIND) :: u, v
-      real (kind=RKIND), allocatable, dimension(:) :: psiVertex
-
-
-      !
-      ! Scale all distances and areas from a unit sphere to one with radius a
-      !
-      grid % xCell % array = grid % xCell % array * a
-      grid % yCell % array = grid % yCell % array * a
-      grid % zCell % array = grid % zCell % array * a
-      grid % xVertex % array = grid % xVertex % array * a
-      grid % yVertex % array = grid % yVertex % array * a
-      grid % zVertex % array = grid % zVertex % array * a
-      grid % xEdge % array = grid % xEdge % array * a
-      grid % yEdge % array = grid % yEdge % array * a
-      grid % zEdge % array = grid % zEdge % array * a
-      grid % dvEdge % array = grid % dvEdge % array * a
-      grid % dcEdge % array = grid % dcEdge % array * a
-      grid % areaCell % array = grid % areaCell % array * a**2.0
-      grid % areaTriangle % array = grid % areaTriangle % array * a**2.0
-      grid % kiteAreasOnVertex % array = grid % kiteAreasOnVertex % array * a**2.0
-      
-
-      !
-      ! Initialize wind field
-      !
-      allocate(psiVertex(grid % nVertices))
-      do iVtx=1,grid % nVertices
-         psiVertex(iVtx) = -a * u0 * ( &amp;
-                                       sin(grid%latVertex%array(iVtx)) * cos(alpha) - &amp;
-                                       cos(grid%lonVertex%array(iVtx)) * cos(grid%latVertex%array(iVtx)) * sin(alpha) &amp;
-                                     )
-      end do
-      do iEdge=1,grid % nEdges
-         state % u % array(1,iEdge) = -1.0 * ( &amp;
-                                               psiVertex(grid%verticesOnEdge%array(2,iEdge)) - &amp;
-                                               psiVertex(grid%verticesOnEdge%array(1,iEdge)) &amp;
-                                             ) / grid%dvEdge%array(iEdge)
-      end do
-      deallocate(psiVertex)
-
-      !
-      ! Generate rotated Coriolis field
-      !
-      do iEdge=1,grid % nEdges
-         grid % fEdge % array(iEdge) = 2.0 * omega * &amp;
-                                       ( -cos(grid%lonEdge%array(iEdge)) * cos(grid%latEdge%array(iEdge)) * sin(alpha) + &amp;
-                                         sin(grid%latEdge%array(iEdge)) * cos(alpha) &amp;
-                                       )
-      end do
-      do iVtx=1,grid % nVertices
-         grid % fVertex % array(iVtx) = 2.0 * omega * &amp;
-                                         (-cos(grid%lonVertex%array(iVtx)) * cos(grid%latVertex%array(iVtx)) * sin(alpha) + &amp;
-                                          sin(grid%latVertex%array(iVtx)) * cos(alpha) &amp;
-                                         )
-      end do
-
-      !
-      ! Initialize height field (actually, fluid thickness field)
-      !
-      do iCell=1,grid % nCells
-         state % h % array(1,iCell) = (gh0 - (a * omega * u0 + 0.5 * u0**2.0) * &amp;
-                                             (-cos(grid%lonCell%array(iCell)) * cos(grid%latCell%array(iCell)) * sin(alpha) + &amp;
-                                              sin(grid%latCell%array(iCell)) * cos(alpha) &amp;
-                                             )**2.0 &amp;
-                                      ) / &amp;
-                                      gravity
-      end do
-
-   end subroutine sw_test_case_2
-
-
-   subroutine sw_test_case_5(grid, state)
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   ! Setup shallow water test case 5: Zonal Flow over an Isolated Mountain
-   !
-   ! Reference: Williamson, D.L., et al., &quot;A Standard Test Set for Numerical 
-   !            Approximations to the Shallow Water Equations in Spherical 
-   !            Geometry&quot; J. of Comp. Phys., 102, pp. 211--224
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-      implicit none
-
-      type (mesh_type), intent(inout) :: grid
-      type (state_type), intent(inout) :: state
-
-      real (kind=RKIND), parameter :: u0 = 20.
-      real (kind=RKIND), parameter :: gh0 = 5960.0*gravity
-!      real (kind=RKIND), parameter :: hs0 = 2000. original
-      real (kind=RKIND), parameter :: hs0 = 250.  !mrp 100204
-      real (kind=RKIND), parameter :: theta_c = pii/6.0
-      real (kind=RKIND), parameter :: lambda_c = 3.0*pii/2.0
-      real (kind=RKIND), parameter :: rr = pii/9.0
-      real (kind=RKIND), parameter :: alpha = 0.0
-
-      integer :: iCell, iEdge, iVtx
-      real (kind=RKIND) :: r, u, v
-      real (kind=RKIND), allocatable, dimension(:) :: psiVertex
-
-
-      !
-      ! Scale all distances and areas from a unit sphere to one with radius a
-      !
-      grid % xCell % array = grid % xCell % array * a
-      grid % yCell % array = grid % yCell % array * a
-      grid % zCell % array = grid % zCell % array * a
-      grid % xVertex % array = grid % xVertex % array * a
-      grid % yVertex % array = grid % yVertex % array * a
-      grid % zVertex % array = grid % zVertex % array * a
-      grid % xEdge % array = grid % xEdge % array * a
-      grid % yEdge % array = grid % yEdge % array * a
-      grid % zEdge % array = grid % zEdge % array * a
-      grid % dvEdge % array = grid % dvEdge % array * a
-      grid % dcEdge % array = grid % dcEdge % array * a
-      grid % areaCell % array = grid % areaCell % array * a**2.0
-      grid % areaTriangle % array = grid % areaTriangle % array * a**2.0
-      grid % kiteAreasOnVertex % array = grid % kiteAreasOnVertex % array * a**2.0
-
-      !
-      ! Initialize wind field
-      !
-      allocate(psiVertex(grid % nVertices))
-      do iVtx=1,grid % nVertices
-         psiVertex(iVtx) = -a * u0 * ( &amp;
-                                       sin(grid%latVertex%array(iVtx)) * cos(alpha) - &amp;
-                                       cos(grid%lonVertex%array(iVtx)) * cos(grid%latVertex%array(iVtx)) * sin(alpha) &amp;
-                                     )
-      end do
-      do iEdge=1,grid % nEdges
-         state % u % array(1,iEdge) = -1.0 * ( &amp;
-                                               psiVertex(grid%verticesOnEdge%array(2,iEdge)) - &amp;
-                                               psiVertex(grid%verticesOnEdge%array(1,iEdge)) &amp;
-                                             ) / grid%dvEdge%array(iEdge)
-      end do
-      deallocate(psiVertex)
-
-      !
-      ! Generate rotated Coriolis field
-      !
-      do iEdge=1,grid % nEdges
-         grid % fEdge % array(iEdge) = 2.0 * omega * &amp;
-                                        (-cos(grid%lonEdge%array(iEdge)) * cos(grid%latEdge%array(iEdge)) * sin(alpha) + &amp;
-                                         sin(grid%latEdge%array(iEdge)) * cos(alpha) &amp;
-                                        )
-      end do
-      do iVtx=1,grid % nVertices
-         grid % fVertex % array(iVtx) = 2.0 * omega * &amp;
-                                         (-cos(grid%lonVertex%array(iVtx)) * cos(grid%latVertex%array(iVtx)) * sin(alpha) + &amp;
-                                          sin(grid%latVertex%array(iVtx)) * cos(alpha) &amp;
-                                         )
-      end do
-
-      !
-      ! Initialize mountain
-      !
-      do iCell=1,grid % nCells
-         if (grid % lonCell % array(iCell) &lt; 0.0) grid % lonCell % array(iCell) = grid % lonCell % array(iCell) + 2.0 * pii
-         r = sqrt(min(rr**2.0, (grid % lonCell % array(iCell) - lambda_c)**2.0 + (grid % latCell % array(iCell) - theta_c)**2.0))
-         grid % h_s % array(iCell) = hs0 * (1.0 - r/rr)
-      end do
-! output about mountain
-print *, 'h_s',minval(grid % h_s % array),sum(grid % h_s % array)/grid % nCells, maxval(grid % h_s % array)
-
-      !
-      ! Initialize tracer fields
-      !
-      do iCell=1,grid % nCells
-         r = sqrt(min(rr**2.0, (grid % lonCell % array(iCell) - lambda_c)**2.0 + (grid % latCell % array(iCell) - theta_c)**2.0))
-         state % tracers % array(1,1,iCell) = 1.0 - r/rr
-      end do
-      do iCell=1,grid % nCells
-         r = sqrt(min(rr**2.0, (grid % lonCell % array(iCell) - lambda_c)**2.0 + &amp;
-                      (grid % latCell % array(iCell) - theta_c - pii/6.0)**2.0 &amp;
-                     ) &amp;
-                 )
-         state % tracers % array(2,1,iCell) = 1.0 - r/rr
-      end do
-
-      !
-      ! Initialize height field (actually, fluid thickness field)
-      !
-      do iCell=1,grid % nCells
-         state % h % array(1,iCell) = (gh0 - (a * omega * u0 + 0.5 * u0**2.0) * &amp;
-                                         (-cos(grid%lonCell%array(iCell)) * cos(grid%latCell%array(iCell)) * sin(alpha) + &amp;
-                                          sin(grid%latCell%array(iCell)) * cos(alpha) &amp;
-                                         )**2.0 &amp;
-                                      ) / &amp;
-                                      gravity
-         state % h % array(1,iCell) = state % h % array(1,iCell) - grid % h_s % array(iCell)
-      end do
-
-   end subroutine sw_test_case_5
-
-
-   subroutine sw_test_case_6(grid, state)
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   ! Setup shallow water test case 6: Rossby-Haurwitz Wave
-   !
-   ! Reference: Williamson, D.L., et al., &quot;A Standard Test Set for Numerical 
-   !            Approximations to the Shallow Water Equations in Spherical 
-   !            Geometry&quot; J. of Comp. Phys., 102, pp. 211--224
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-      implicit none
-
-      type (mesh_type), intent(inout) :: grid
-      type (state_type), intent(inout) :: state
-
-      real (kind=RKIND), parameter :: h0 = 8000.0
-      real (kind=RKIND), parameter :: w = 7.848e-6
-      real (kind=RKIND), parameter :: K = 7.848e-6
-      real (kind=RKIND), parameter :: R = 4.0
-
-      integer :: iCell, iEdge, iVtx
-      real (kind=RKIND) :: u, v
-      real (kind=RKIND), allocatable, dimension(:) :: psiVertex
-
-
-      !
-      ! Scale all distances and areas from a unit sphere to one with radius a
-      !
-      grid % xCell % array = grid % xCell % array * a
-      grid % yCell % array = grid % yCell % array * a
-      grid % zCell % array = grid % zCell % array * a
-      grid % xVertex % array = grid % xVertex % array * a
-      grid % yVertex % array = grid % yVertex % array * a
-      grid % zVertex % array = grid % zVertex % array * a
-      grid % xEdge % array = grid % xEdge % array * a
-      grid % yEdge % array = grid % yEdge % array * a
-      grid % zEdge % array = grid % zEdge % array * a
-      grid % dvEdge % array = grid % dvEdge % array * a
-      grid % dcEdge % array = grid % dcEdge % array * a
-      grid % areaCell % array = grid % areaCell % array * a**2.0
-      grid % areaTriangle % array = grid % areaTriangle % array * a**2.0
-      grid % kiteAreasOnVertex % array = grid % kiteAreasOnVertex % array * a**2.0
-
-      !
-      ! Initialize wind field
-      !
-      allocate(psiVertex(grid % nVertices))
-      do iVtx=1,grid % nVertices
-         psiVertex(iVtx) = -a * a * w * sin(grid%latVertex%array(iVtx)) + &amp;
-                            a *a * K * (cos(grid%latVertex%array(iVtx))**R) * &amp;
-                            sin(grid%latVertex%array(iVtx)) * cos(R * grid%lonVertex%array(iVtx))
-      end do
-      do iEdge=1,grid % nEdges
-         state % u % array(1,iEdge) = -1.0 * ( &amp;
-                                               psiVertex(grid%verticesOnEdge%array(2,iEdge)) - &amp;
-                                               psiVertex(grid%verticesOnEdge%array(1,iEdge)) &amp;
-                                             ) / grid%dvEdge%array(iEdge)
-      end do
-      deallocate(psiVertex)
-
-      !
-      ! Initialize height field (actually, fluid thickness field)
-      !
-      do iCell=1,grid % nCells
-         state % h % array(1,iCell) = (gravity * h0 + a*a*AA(grid%latCell%array(iCell)) + &amp;
-                                                      a*a*BB(grid%latCell%array(iCell)) * cos(R*grid%lonCell%array(iCell)) + &amp;
-                                                      a*a*CC(grid%latCell%array(iCell)) * cos(2.0*R*grid%lonCell%array(iCell)) &amp;
-                                      ) / gravity
-      end do
-
-   end subroutine sw_test_case_6
-
-
-   real function sphere_distance(lat1, lon1, lat2, lon2, radius)
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   ! Compute the great-circle distance between (lat1, lon1) and (lat2, lon2) on a
-   !   sphere with given radius.
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-      implicit none
-
-      real (kind=RKIND), intent(in) :: lat1, lon1, lat2, lon2, radius
-
-      real (kind=RKIND) :: arg1
-
-      arg1 = sqrt( sin(0.5*(lat2-lat1))**2 +  &amp;
-                   cos(lat1)*cos(lat2)*sin(0.5*(lon2-lon1))**2 )
-      sphere_distance = 2.*radius*asin(arg1)
-
-   end function sphere_distance
-
-
-   real function AA(theta)
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   ! A, used in height field computation for Rossby-Haurwitz wave
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-      implicit none
-
-      real (kind=RKIND), parameter :: w = 7.848e-6
-      real (kind=RKIND), parameter :: K = 7.848e-6
-      real (kind=RKIND), parameter :: R = 4.0
-
-      real (kind=RKIND), intent(in) :: theta
-
-      AA = 0.5 * w * (2.0 * omega + w) * cos(theta)**2.0 + &amp;
-          0.25 * K**2.0 * cos(theta)**(2.0*R) * ((R+1.0)*cos(theta)**2.0 + 2.0*R**2.0 - R - 2.0 - 2.0*R**2*cos(theta)**-2.0)
-
-   end function AA
-
-   
-   real function BB(theta)
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   ! B, used in height field computation for Rossby-Haurwitz wave
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-      implicit none
-
-      real (kind=RKIND), parameter :: w = 7.848e-6
-      real (kind=RKIND), parameter :: K = 7.848e-6
-      real (kind=RKIND), parameter :: R = 4.0
-
-      real (kind=RKIND), intent(in) :: theta
-
-      BB = (2.0*(omega + w)*K / ((R+1.0)*(R+2.0))) * cos(theta)**R * ((R**2.0 + 2.0*R + 2.0) - ((R+1.0)*cos(theta))**2.0)
-
-   end function BB
-
-
-   real function CC(theta)
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   ! C, used in height field computation for Rossby-Haurwitz wave
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-      implicit none
-
-      real (kind=RKIND), parameter :: w = 7.848e-6
-      real (kind=RKIND), parameter :: K = 7.848e-6
-      real (kind=RKIND), parameter :: R = 4.0
-
-      real (kind=RKIND), intent(in) :: theta
-
-      CC = 0.25 * K**2.0 * cos(theta)**(2.0*R) * ((R+1.0)*cos(theta)**2.0 - R - 2.0)
-
-   end function CC
-
-end module test_cases

Deleted: trunk/mpas/src/core_ocean/module_time_integration.F
===================================================================
--- trunk/mpas/src/core_ocean/module_time_integration.F        2011-09-30 18:04:47 UTC (rev 1046)
+++ trunk/mpas/src/core_ocean/module_time_integration.F        2011-09-30 18:20:19 UTC (rev 1047)
@@ -1,2586 +0,0 @@
-module time_integration
-
-   use grid_types
-   use configure
-   use constants
-   use dmpar
-   use vector_reconstruction
-   use spline_interpolation
-
-   contains
-
-   subroutine timestep(domain, dt, timeStamp)
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   ! Advance model state forward in time by the specified time step
-   !
-   ! Input: domain - current model state in time level 1 (e.g., time_levs(1)state%h(:,:)) 
-   !                 plus grid meta-data
-   ! Output: domain - upon exit, time level 2 (e.g., time_levs(2)%state%h(:,:)) contains 
-   !                  model state advanced forward in time by dt seconds
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-      implicit none
-
-      type (domain_type), intent(inout) :: domain
-      real (kind=RKIND), intent(in) :: dt
-      character(len=*), intent(in) :: timeStamp
-
-      type (dm_info) :: dminfo
-      type (block_type), pointer :: block
-
-      if (trim(config_time_integration) == 'RK4') then
-         call rk4(domain, dt)
-      else
-         write(0,*) 'Abort: Unknown time integration option '&amp;
-           //trim(config_time_integration)
-         write(0,*) 'Currently, only ''RK4'' is supported.'
-         call dmpar_abort(dminfo)
-      end if
-
-      block =&gt; domain % blocklist
-      do while (associated(block))
-         block % state % time_levs(2) % state % xtime % scalar = timeStamp
-
-         if (isNaN(sum(block % state % time_levs(2) % state % u % array))) then
-            write(0,*) 'Abort: NaN detected'
-            call dmpar_abort(dminfo)
-         endif
-
-         block =&gt; block % next
-      end do
-
-   end subroutine timestep
-
-
-   subroutine rk4(domain, dt)
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   ! Advance model state forward in time by the specified time step using 
-   !   4th order Runge-Kutta
-   !
-   ! Input: domain - current model state in time level 1 (e.g., time_levs(1)state%h(:,:)) 
-   !                 plus grid meta-data
-   ! Output: domain - upon exit, time level 2 (e.g., time_levs(2)%state%h(:,:)) contains 
-   !                  model state advanced forward in time by dt seconds
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-      implicit none
-
-      type (domain_type), intent(inout) :: domain
-      real (kind=RKIND), intent(in) :: dt
-
-      integer :: iCell, k, i
-      type (block_type), pointer :: block
-      type (state_type) :: provis
-
-      integer :: rk_step, iEdge, cell1, cell2
-
-      real (kind=RKIND), dimension(4) :: rk_weights, rk_substep_weights
-
-      integer :: nCells, nEdges, nVertLevels, num_tracers
-      real (kind=RKIND), dimension(:,:), pointer :: &amp;
-        u, h, h_edge, vertViscTopOfEdge, vertDiffTopOfCell, ke_edge
-      real (kind=RKIND), dimension(:,:,:), pointer :: tracers
-      integer, dimension(:), pointer :: &amp; 
-        maxLevelCell, maxLevelEdgeTop
-      real (kind=RKIND), dimension(:), allocatable:: A,C,uTemp
-      real (kind=RKIND), dimension(:,:), allocatable:: tracersTemp
-
-
-      block =&gt; domain % blocklist
-      call allocate_state(provis, &amp;
-                          block % mesh % nCells, block % mesh % nEdges, block % mesh % maxEdges, block % mesh % maxEdges2, &amp;
-                          block % mesh % nVertices, block % mesh % vertexDegree, block % mesh % nVertLevels )
-
-      !
-      ! Initialize time_levs(2) with state at current time
-      ! Initialize first RK state
-      ! Couple tracers time_levs(2) with h in time-levels
-      ! Initialize RK weights
-      !
-      block =&gt; domain % blocklist
-      do while (associated(block))
-
-         block % state % time_levs(2) % state % u % array(:,:) = block % state % time_levs(1) % state % u % array(:,:)
-         block % state % time_levs(2) % state % h % array(:,:) = block % state % time_levs(1) % state % h % array(:,:)
-         do iCell=1,block % mesh % nCells  ! couple tracers to h
-           do k=1,block % mesh % maxLevelCell % array(iCell)
-             block % state % time_levs(2) % state % tracers % array(:,k,iCell) = block % state % time_levs(1) % state % tracers % array(:,k,iCell) &amp;
-                                                                       * block % state % time_levs(1) % state % h % array(k,iCell)
-            end do
-         end do
-
-         call copy_state(provis, block % state % time_levs(1) % state)
-
-         block =&gt; block % next
-      end do
-
-      rk_weights(1) = dt/6.
-      rk_weights(2) = dt/3.
-      rk_weights(3) = dt/3.
-      rk_weights(4) = dt/6.
-
-      rk_substep_weights(1) = dt/2.
-      rk_substep_weights(2) = dt/2.
-      rk_substep_weights(3) = dt
-      rk_substep_weights(4) = 0.
-
-
-      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-      ! BEGIN RK loop 
-      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-      do rk_step = 1, 4
-! ---  update halos for diagnostic variables
-
-        block =&gt; domain % blocklist
-        do while (associated(block))
-           call dmpar_exch_halo_field2dReal(domain % dminfo, provis % pv_edge % array(:,:), &amp;
-                                            block % mesh % nVertLevels, block % mesh % nEdges, &amp;
-                                            block % parinfo % edgesToSend, block % parinfo % edgesToRecv)
-
-           if (config_h_mom_eddy_visc4 &gt; 0.0) then
-              call dmpar_exch_halo_field2dReal(domain % dminfo, block % state % time_levs(2) % state % divergence % array(:,:), &amp;
-                                               block % mesh % nVertLevels, block % mesh % nCells, &amp;
-                                               block % parinfo % cellsToSend, block % parinfo % cellsToRecv)
-              call dmpar_exch_halo_field2dReal(domain % dminfo, block % state % time_levs(2) % state % vorticity % array(:,:), &amp;
-                                               block % mesh % nVertLevels, block % mesh % nVertices, &amp;
-                                               block % parinfo % verticesToSend, block % parinfo % verticesToRecv)
-           end if
-
-           block =&gt; block % next
-        end do
-
-! ---  compute tendencies
-
-        block =&gt; domain % blocklist
-        do while (associated(block))
-           if (.not.config_implicit_vertical_mix) then
-              call compute_vertical_mix_coefficients(provis, block % diagnostics, block % mesh)
-           end if
-           call compute_tend(block % tend, provis, block % diagnostics, block % mesh)
-           call compute_scalar_tend(block % tend, provis, block % diagnostics, block % mesh)
-           call enforce_boundaryEdge(block % tend, block % mesh)
-           block =&gt; block % next
-        end do
-
-! ---  update halos for prognostic variables
-
-        block =&gt; domain % blocklist
-        do while (associated(block))
-           call dmpar_exch_halo_field2dReal(domain % dminfo, block % tend % u % array(:,:), &amp;
-                                            block % mesh % nVertLevels, block % mesh % nEdges, &amp;
-                                            block % parinfo % edgesToSend, block % parinfo % edgesToRecv)
-           call dmpar_exch_halo_field2dReal(domain % dminfo, block % tend % h % array(:,:), &amp;
-                                            block % mesh % nVertLevels, block % mesh % nCells, &amp;
-                                            block % parinfo % cellsToSend, block % parinfo % cellsToRecv)
-           call dmpar_exch_halo_field3dReal(domain % dminfo, block % tend % tracers % array(:,:,:), &amp;
-                                            block % tend % num_tracers, block % mesh % nVertLevels, block % mesh % nCells, &amp;
-                                            block % parinfo % cellsToSend, block % parinfo % cellsToRecv)
-           block =&gt; block % next
-        end do
-
-! ---  compute next substep state
-
-        if (rk_step &lt; 4) then
-           block =&gt; domain % blocklist
-           do while (associated(block))
-
-              provis % u % array(:,:)       = block % state % time_levs(1) % state % u % array(:,:)  &amp;
-                                         + rk_substep_weights(rk_step) * block % tend % u % array(:,:)
-              provis % h % array(:,:)       = block % state % time_levs(1) % state % h % array(:,:)  &amp;
-                                         + rk_substep_weights(rk_step) * block % tend % h % array(:,:)
-              do iCell=1,block % mesh % nCells
-                 do k=1,block % mesh % maxLevelCell % array(iCell)
-                    provis % tracers % array(:,k,iCell) = ( &amp;
-                                                                      block % state % time_levs(1) % state % h % array(k,iCell) * &amp;
-                                                                      block % state % time_levs(1) % state % tracers % array(:,k,iCell)  &amp;
-                                      + rk_substep_weights(rk_step) * block % tend % tracers % array(:,k,iCell) &amp;
-                                                                     ) / provis % h % array(k,iCell)
-                 end do
-
-              end do
-              if (config_test_case == 1) then    ! For case 1, wind field should be fixed
-                 provis % u % array(:,:) = block % state % time_levs(1) % state % u % array(:,:)
-              end if
-              call compute_solve_diagnostics(dt, provis, block % mesh)
-
-              block =&gt; block % next
-           end do
-        end if
-
-
-
-!--- accumulate update (for RK4)
-
-        block =&gt; domain % blocklist
-        do while (associated(block))
-           block % state % time_levs(2) % state % u % array(:,:) = block % state % time_levs(2) % state % u % array(:,:) &amp;
-                                   + rk_weights(rk_step) * block % tend % u % array(:,:) 
-           block % state % time_levs(2) % state % h % array(:,:) = block % state % time_levs(2) % state % h % array(:,:) &amp;
-                                   + rk_weights(rk_step) * block % tend % h % array(:,:) 
-
-           do iCell=1,block % mesh % nCells
-              do k=1,block % mesh % maxLevelCell % array(iCell)
-                 block % state % time_levs(2) % state % tracers % array(:,k,iCell) =  &amp;
-                                                                       block % state % time_levs(2) % state % tracers % array(:,k,iCell) &amp;
-                                               + rk_weights(rk_step) * block % tend % tracers % array(:,k,iCell)
-              end do
-           end do
-
-           block =&gt; block % next
-        end do
-
-      end do
-      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-      ! END RK loop 
-      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-      !
-      !  A little clean up at the end: decouple new scalar fields and compute diagnostics for new state
-      !
-      block =&gt; domain % blocklist
-      do while (associated(block))
-
-         u           =&gt; block % state % time_levs(2) % state % u % array
-         tracers     =&gt; block % state % time_levs(2) % state % tracers % array
-         h           =&gt; block % state % time_levs(2) % state % h % array
-         h_edge      =&gt; block % state % time_levs(2) % state % h_edge % array
-         ke_edge     =&gt; block % state % time_levs(2) % state % ke_edge % array
-         num_tracers = block % state % time_levs(2) % state % num_tracers
-         vertViscTopOfEdge =&gt; block % diagnostics % vertViscTopOfEdge % array
-         vertDiffTopOfCell =&gt; block % diagnostics % vertDiffTopOfCell % array
-         maxLevelCell    =&gt; block % mesh % maxLevelCell % array
-         maxLevelEdgeTop =&gt; block % mesh % maxLevelEdgeTop % array
-                  
-         nCells      = block % mesh % nCells
-         nEdges      = block % mesh % nEdges
-         nVertLevels = block % mesh % nVertLevels
-
-         do iCell=1,nCells
-            do k=1,maxLevelCell(iCell)
-               tracers(:,k,iCell) = tracers(:,k,iCell) / h(k,iCell)
-            end do
-         end do
-
-         if (config_implicit_vertical_mix) then
-            allocate(A(nVertLevels),C(nVertLevels),uTemp(nVertLevels), &amp;
-               tracersTemp(num_tracers,nVertLevels))
-
-            call compute_vertical_mix_coefficients(block % state % time_levs(2) % state, block % diagnostics, block % mesh)
-
-            !
-            !  Implicit vertical solve for momentum
-            !
-            do iEdge=1,nEdges
-              if (maxLevelEdgeTop(iEdge).gt.0) then
-
-               ! Compute A(k), C(k) for momentum
-               ! mrp 110315 efficiency note: for z-level, could precompute
-               ! -2.0*dt/(h(k)_h(k+1))/h(k) in setup
-               ! h_edge is computed in compute_solve_diag, and is not available yet.
-               ! This could be removed if hZLevel used instead.
-               cell1 = block % mesh % cellsOnEdge % array(1,iEdge)
-               cell2 = block % mesh % cellsOnEdge % array(2,iEdge)
-               do k=1,maxLevelEdgeTop(iEdge)
-                  h_edge(k,iEdge) = 0.5 * (h(k,cell1) + h(k,cell2))
-               end do
-
-               do k=1,maxLevelEdgeTop(iEdge)-1
-                  A(k) = -2.0*dt*vertViscTopOfEdge(k+1,iEdge) &amp;
-                     / (h_edge(k,iEdge) + h_edge(k+1,iEdge)) &amp;
-                     / h_edge(k,iEdge)
-               enddo
-               A(maxLevelEdgeTop(iEdge)) = -dt*config_bottom_drag_coeff  &amp;
-                  *sqrt(2.0*ke_edge(k,iEdge))/h_edge(k,iEdge)
-
-               C(1) = 1 - A(1)
-               do k=2,maxLevelEdgeTop(iEdge)
-                  C(k) = 1 - A(k) - A(k-1)
-               enddo
-
-               call tridiagonal_solve(A,C,A,u(:,iEdge),uTemp,maxLevelEdgeTop(iEdge))
-
-               u(1:maxLevelEdgeTop(iEdge),iEdge) = uTemp(1:maxLevelEdgeTop(iEdge))
-               u(maxLevelEdgeTop(iEdge)+1:nVertLevels,iEdge) = 0.0
-
-              end if
-            end do
-
-            !
-            !  Implicit vertical solve for tracers
-            !
-            do iCell=1,nCells
-               ! Compute A(k), C(k) for tracers
-               ! mrp 110315 efficiency note: for z-level, could precompute
-               ! -2.0*dt/(h(k)_h(k+1))/h(k) in setup
-               do k=1,maxLevelCell(iCell)-1
-                  A(k) = -2.0*dt*vertDiffTopOfCell(k+1,iCell) &amp;
-                     / (h(k,iCell) + h(k+1,iCell)) &amp;
-                     / h(k,iCell)
-               enddo
-
-               A(maxLevelCell(iCell)) = 0.0
-
-               C(1) = 1 - A(1)
-               do k=2,maxLevelCell(iCell)
-                  C(k) = 1 - A(k) - A(k-1)
-               enddo
-
-               call tridiagonal_solve_mult(A,C,A,tracers(:,:,iCell), &amp;
-                  tracersTemp, maxLevelCell(iCell), &amp;
-                  nVertLevels,num_tracers)
-
-               tracers(:,1:maxLevelCell(iCell),iCell) = tracersTemp(:,1:maxLevelCell(iCell))
-               tracers(:,maxLevelCell(iCell)+1:nVertLevels,iCell) = -1e34
-            end do
-            deallocate(A,C,uTemp,tracersTemp)
-         end if
-
-         if (config_test_case == 1) then    ! For case 1, wind field should be fixed
-            block % state % time_levs(2) % state % u % array(:,:) = block % state % time_levs(1) % state % u % array(:,:)
-         end if
-
-         call compute_solve_diagnostics(dt, block % state % time_levs(2) % state, block % mesh)
-
-         call reconstruct(block % state % time_levs(2) % state, block % mesh)
-
-         block =&gt; block % next
-      end do
-
-      call deallocate_state(provis)
-
-   end subroutine rk4
-
-
-   subroutine compute_tend(tend, s, d, grid)
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   ! Compute height and normal wind tendencies, as well as diagnostic variables
-   !
-   ! Input: s - current model state
-   !        grid - grid metadata
-   !
-   ! Output: tend - computed tendencies for prognostic variables
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-      implicit none
-
-      type (tend_type), intent(inout) :: tend
-      type (state_type), intent(in) :: s
-      type (diagnostics_type), intent(in) :: d
-      type (mesh_type), intent(in) :: grid
-
-      integer :: iEdge, iCell, iVertex, k, cell1, cell2, &amp;
-        vertex1, vertex2, eoe, i, j
-
-      integer :: nCells, nEdges, nVertices, nVertLevels, nEdgesSolve
-      real (kind=RKIND) :: flux, vorticity_abs, h_vertex, workpv, q, &amp;
-        upstream_bias, wTopEdge, rho0Inv, r
-      real (kind=RKIND), dimension(:), pointer :: &amp;
-        h_s, fVertex, fEdge, dvEdge, dcEdge, areaCell, areaTriangle, &amp;
-        zMidZLevel, zTopZLevel 
-      real (kind=RKIND), dimension(:,:), pointer :: &amp;
-        weightsOnEdge, kiteAreasOnVertex, h_edge, h, u, v, pressure, &amp;
-        tend_h, tend_u, circulation, vorticity, ke, ke_edge, pv_edge, &amp;
-        MontPot, wTop, divergence, vertViscTopOfEdge
-      type (dm_info) :: dminfo
-
-      integer, dimension(:), pointer :: nEdgesOnCell, nEdgesOnEdge, &amp;
-        maxLevelCell, maxLevelEdgeTop, maxLevelVertexBot
-      integer, dimension(:,:), pointer :: &amp;
-        cellsOnEdge, cellsOnVertex, verticesOnEdge, edgesOnCell, &amp;
-        edgesOnEdge, edgesOnVertex
-      real (kind=RKIND) :: u_diffusion
-      real (kind=RKIND), dimension(:), allocatable:: fluxVertTop,w_dudzTopEdge
-
-      real (kind=RKIND), allocatable, dimension(:,:) :: delsq_divergence
-      real (kind=RKIND), allocatable, dimension(:,:) :: delsq_u
-      real (kind=RKIND), allocatable, dimension(:,:) :: delsq_circulation, delsq_vorticity
-
-
-      real (kind=RKIND), dimension(:,:), pointer :: u_src
-      real (kind=RKIND), parameter :: rho_ref = 1000.0
-
-      h           =&gt; s % h % array
-      u           =&gt; s % u % array
-      v           =&gt; s % v % array
-      wTop        =&gt; s % wTop % array
-      h_edge      =&gt; s % h_edge % array
-      circulation =&gt; s % circulation % array
-      vorticity   =&gt; s % vorticity % array
-      divergence  =&gt; s % divergence % array
-      ke          =&gt; s % ke % array
-      ke_edge     =&gt; s % ke_edge % array
-      pv_edge     =&gt; s % pv_edge % array
-      MontPot     =&gt; s % MontPot % array
-      pressure    =&gt; s % pressure % array
-      vertViscTopOfEdge =&gt; d % vertViscTopOfEdge % array
-
-      weightsOnEdge     =&gt; grid % weightsOnEdge % array
-      kiteAreasOnVertex =&gt; grid % kiteAreasOnVertex % array
-      cellsOnEdge       =&gt; grid % cellsOnEdge % array
-      cellsOnVertex     =&gt; grid % cellsOnVertex % array
-      verticesOnEdge    =&gt; grid % verticesOnEdge % array
-      nEdgesOnCell      =&gt; grid % nEdgesOnCell % array
-      edgesOnCell       =&gt; grid % edgesOnCell % array
-      nEdgesOnEdge      =&gt; grid % nEdgesOnEdge % array
-      edgesOnEdge       =&gt; grid % edgesOnEdge % array
-      edgesOnVertex     =&gt; grid % edgesOnVertex % array
-      dcEdge            =&gt; grid % dcEdge % array
-      dvEdge            =&gt; grid % dvEdge % array
-      areaCell          =&gt; grid % areaCell % array
-      areaTriangle      =&gt; grid % areaTriangle % array
-      h_s               =&gt; grid % h_s % array
-      fVertex           =&gt; grid % fVertex % array
-      fEdge             =&gt; grid % fEdge % array
-      zMidZLevel        =&gt; grid % zMidZLevel % array
-      zTopZLevel        =&gt; grid % zTopZLevel % array
-      maxLevelCell      =&gt; grid % maxLevelCell % array
-      maxLevelEdgeTop      =&gt; grid % maxLevelEdgeTop % array
-      maxLevelVertexBot    =&gt; grid % maxLevelVertexBot % array
-
-      tend_h      =&gt; tend % h % array
-      tend_u      =&gt; tend % u % array
-                  
-      nCells      = grid % nCells
-      nEdges      = grid % nEdges
-      nEdgesSolve = grid % nEdgesSolve
-      nVertices   = grid % nVertices
-      nVertLevels = grid % nVertLevels
-
-      u_src =&gt; grid % u_src % array
-
-      !
-      ! height tendency: start accumulating tendency terms
-      !
-      tend_h = 0.0
-
-      !
-      ! height tendency: horizontal advection term -</font>
<font color="red">abla\cdot ( hu)
-      !
-      ! See Ringler et al. (2010) jcp paper, eqn 19, 21, and fig. 3. 
-      ! for explanation of divergence operator.
-      !
-      ! for z-level, only compute height tendency for top layer.
-
-      if (config_vert_grid_type.eq.'isopycnal') then

-         do iEdge=1,nEdges
-            cell1 = cellsOnEdge(1,iEdge)
-            cell2 = cellsOnEdge(2,iEdge)
-            do k=1,nVertLevels
-               flux = u(k,iEdge) * dvEdge(iEdge) * h_edge(k,iEdge)
-               tend_h(k,cell1) = tend_h(k,cell1) - flux
-               tend_h(k,cell2) = tend_h(k,cell2) + flux
-            end do
-         end do
-         do iCell=1,nCells
-            do k=1,nVertLevels
-               tend_h(k,iCell) = tend_h(k,iCell) / areaCell(iCell)
-            end do
-         end do
-
-      elseif (config_vert_grid_type.eq.'zlevel') then
-
-         do iEdge=1,nEdges
-            cell1 = cellsOnEdge(1,iEdge)
-            cell2 = cellsOnEdge(2,iEdge)
-            do k=1,min(1,maxLevelEdgeTop(iEdge))
-               flux = u(k,iEdge) * dvEdge(iEdge) * h_edge(k,iEdge)
-               tend_h(k,cell1) = tend_h(k,cell1) - flux
-               tend_h(k,cell2) = tend_h(k,cell2) + flux
-            end do
-         end do
-         do iCell=1,nCells
-            tend_h(1,iCell) = tend_h(1,iCell) / areaCell(iCell)
-         end do
-
-      endif ! config_vert_grid_type
-
-      !
-      ! height tendency: vertical advection term -d/dz(hw)
-      !
-      ! Vertical advection computed for top layer of a z grid only.
-      if (config_vert_grid_type.eq.'zlevel') then
-        do iCell=1,nCells
-           tend_h(1,iCell) =   tend_h(1,iCell) + wTop(2,iCell)
-        end do
-      endif ! coordinate type
-
-      !
-      ! velocity tendency: start accumulating tendency terms
-      !
-      tend_u(:,:) = 0.0
-
-      !
-      ! velocity tendency: vertical advection term -w du/dz
-      !
-      if (config_vert_grid_type.eq.'zlevel') then
-        allocate(w_dudzTopEdge(nVertLevels+1))
-        w_dudzTopEdge(1) = 0.0
-        do iEdge=1,grid % nEdgesSolve
-          cell1 = cellsOnEdge(1,iEdge)
-          cell2 = cellsOnEdge(2,iEdge)
-
-          do k=2,maxLevelEdgeTop(iEdge)
-            ! Average w from cell center to edge
-            wTopEdge = 0.5*(wTop(k,cell1)+wTop(k,cell2))
-
-            ! compute dudz at vertical interface with first order derivative.
-            w_dudzTopEdge(k) = wTopEdge * (u(k-1,iEdge)-u(k,iEdge)) &amp;
-                         / (zMidZLevel(k-1) - zMidZLevel(k))
-          end do
-          w_dudzTopEdge(maxLevelEdgeTop(iEdge)+1) = 0.0
-
-          ! Average w*du/dz from vertical interface to vertical middle of cell
-          do k=1,maxLevelEdgeTop(iEdge)
-             tend_u(k,iEdge) = - 0.5 * (w_dudzTopEdge(k) + w_dudzTopEdge(k+1))
-          enddo
-        enddo
-        deallocate(w_dudzTopEdge)
-      endif
-
-      !
-      ! velocity tendency: pressure gradient
-      !
-      rho0Inv = 1.0/config_rho0
-      if (config_vert_grid_type.eq.'isopycnal') then
-        do iEdge=1,grid % nEdgesSolve
-          cell1 = cellsOnEdge(1,iEdge)
-          cell2 = cellsOnEdge(2,iEdge)
-          do k=1,maxLevelEdgeTop(iEdge)
-             tend_u(k,iEdge) = tend_u(k,iEdge)     &amp;
-               - (MontPot(k,cell2) - MontPot(k,cell1))/dcEdge(iEdge)
-           end do
-        enddo
-      elseif (config_vert_grid_type.eq.'zlevel') then
-        do iEdge=1,grid % nEdgesSolve
-          cell1 = cellsOnEdge(1,iEdge)
-          cell2 = cellsOnEdge(2,iEdge)
-          do k=1,maxLevelEdgeTop(iEdge)
-             tend_u(k,iEdge) = tend_u(k,iEdge)     &amp;
-               - rho0Inv*(  pressure(k,cell2) &amp;
-                          - pressure(k,cell1) )/dcEdge(iEdge)
-          end do
-        enddo
-      endif
-
-      !
-      ! velocity tendency: del2 dissipation, </font>
<font color="black">u_2 </font>
<font color="red">abla^2 u
-      !   computed as </font>
<font color="black">u( </font>
<font color="black">abla divergence + k \times </font>
<font color="red">abla vorticity )
-      !   strictly only valid for config_h_mom_eddy_visc2 == constant
-      !
-      if ( config_h_mom_eddy_visc2 &gt; 0.0 ) then
-         do iEdge=1,grid % nEdgesSolve
-            cell1 = cellsOnEdge(1,iEdge)
-            cell2 = cellsOnEdge(2,iEdge)
-            vertex1 = verticesOnEdge(1,iEdge)
-            vertex2 = verticesOnEdge(2,iEdge)
-
-            do k=1,maxLevelEdgeTop(iEdge)
-
-               ! Here -( vorticity(k,vertex2) - vorticity(k,vertex1) ) / dvEdge(iEdge)
-               ! is - </font>
<font color="red">abla vorticity pointing from vertex 2 to vertex 1, or equivalently 
-               !    + k \times </font>
<font color="red">abla vorticity pointing from cell1 to cell2.
-
-               u_diffusion = ( divergence(k,cell2)  - divergence(k,cell1) ) / dcEdge(iEdge)  &amp;
-                            -( vorticity(k,vertex2) - vorticity(k,vertex1) ) / dvEdge(iEdge)
-               u_diffusion = config_h_mom_eddy_visc2 * u_diffusion
-
-               tend_u(k,iEdge) = tend_u(k,iEdge) + u_diffusion
-
-            end do
-         end do
-      end if
-
-      !
-      ! velocity tendency: del4 dissipation, -</font>
<font color="black">u_4 </font>
<font color="red">abla^4 u
-      !   computed as </font>
<font color="black">abla^2 u = </font>
<font color="black">abla divergence + k \times </font>
<font color="red">abla vorticity
-      !   applied recursively.
-      !   strictly only valid for config_h_mom_eddy_visc4 == constant
-      !
-      if ( config_h_mom_eddy_visc4 &gt; 0.0 ) then
-
-         allocate(delsq_divergence(nVertLevels, nCells+1))
-         allocate(delsq_u(nVertLevels, nEdges+1))
-         allocate(delsq_circulation(nVertLevels, nVertices+1))
-         allocate(delsq_vorticity(nVertLevels, nVertices+1))
-
-         delsq_u(:,:) = 0.0
-
-         ! Compute </font>
<font color="black">abla^2 u = </font>
<font color="black">abla divergence + k \times </font>
<font color="red">abla vorticity
-         do iEdge=1,grid % nEdges
-            cell1 = cellsOnEdge(1,iEdge)
-            cell2 = cellsOnEdge(2,iEdge)
-            vertex1 = verticesOnEdge(1,iEdge)
-            vertex2 = verticesOnEdge(2,iEdge)
-
-            do k=1,maxLevelEdgeTop(iEdge)
-
-               delsq_u(k,iEdge) = &amp; 
-                  ( divergence(k,cell2)  - divergence(k,cell1) ) / dcEdge(iEdge)  &amp;
-                 -( vorticity(k,vertex2) - vorticity(k,vertex1)) / dvEdge(iEdge)
-
-            end do
-         end do
-
-         ! vorticity using </font>
<font color="red">abla^2 u
-         delsq_circulation(:,:) = 0.0
-         do iEdge=1,nEdges
-            vertex1 = verticesOnEdge(1,iEdge)
-            vertex2 = verticesOnEdge(2,iEdge)
-            do k=1,maxLevelEdgeTop(iEdge)
-               delsq_circulation(k,vertex1) = delsq_circulation(k,vertex1) &amp;
-                  - dcEdge(iEdge) * delsq_u(k,iEdge)
-               delsq_circulation(k,vertex2) = delsq_circulation(k,vertex2) &amp;
-                  + dcEdge(iEdge) * delsq_u(k,iEdge)
-            end do
-         end do
-         do iVertex=1,nVertices
-            r = 1.0 / areaTriangle(iVertex)
-            do k=1,maxLevelVertexBot(iVertex)
-               delsq_vorticity(k,iVertex) = delsq_circulation(k,iVertex) * r
-            end do
-         end do
-
-         ! Divergence using </font>
<font color="red">abla^2 u
-         delsq_divergence(:,:) = 0.0
-         do iEdge=1,nEdges
-            cell1 = cellsOnEdge(1,iEdge)
-            cell2 = cellsOnEdge(2,iEdge)
-            do k=1,maxLevelEdgeTop(iEdge)
-              delsq_divergence(k,cell1) = delsq_divergence(k,cell1) &amp;
-                + delsq_u(k,iEdge)*dvEdge(iEdge)
-              delsq_divergence(k,cell2) = delsq_divergence(k,cell2) &amp;
-                - delsq_u(k,iEdge)*dvEdge(iEdge)
-            end do
-         end do
-         do iCell = 1,nCells
-            r = 1.0 / areaCell(iCell)
-            do k = 1,maxLevelCell(iCell)
-               delsq_divergence(k,iCell) = delsq_divergence(k,iCell) * r
-            end do
-         end do
-
-         ! Compute - \kappa </font>
<font color="red">abla^4 u 
-         ! as  </font>
<font color="black">abla div(</font>
<font color="black">abla^2 u) + k \times </font>
<font color="black">abla ( k \cross curl(</font>
<font color="red">abla^2 u) )
-         do iEdge=1,grid % nEdgesSolve
-            cell1 = cellsOnEdge(1,iEdge)
-            cell2 = cellsOnEdge(2,iEdge)
-            vertex1 = verticesOnEdge(1,iEdge)
-            vertex2 = verticesOnEdge(2,iEdge)
-
-            do k=1,maxLevelEdgeTop(iEdge)
-
-               u_diffusion = (  delsq_divergence(k,cell2) &amp;
-                              - delsq_divergence(k,cell1) ) / dcEdge(iEdge)  &amp;
-                            -(  delsq_vorticity(k,vertex2) &amp;
-                              - delsq_vorticity(k,vertex1) ) / dvEdge(iEdge)

-               tend_u(k,iEdge) = tend_u(k,iEdge) - config_h_mom_eddy_visc4 * u_diffusion
-            end do
-         end do
-
-         deallocate(delsq_divergence)
-         deallocate(delsq_u)
-         deallocate(delsq_circulation)
-         deallocate(delsq_vorticity)
-
-      end if
-
-      !
-      ! velocity tendency: nonlinear Coriolis term and grad of kinetic energy
-      !
-      do iEdge=1,grid % nEdgesSolve
-         cell1 = cellsOnEdge(1,iEdge)
-         cell2 = cellsOnEdge(2,iEdge)
-
-         do k=1,maxLevelEdgeTop(iEdge)
-
-            q = 0.0
-            do j = 1,nEdgesOnEdge(iEdge)
-               eoe = edgesOnEdge(j,iEdge)
-               workpv = 0.5 * (pv_edge(k,iEdge) + pv_edge(k,eoe))
-               q = q + weightsOnEdge(j,iEdge) * u(k,eoe) * workpv * h_edge(k,eoe) 
-            end do
-            tend_u(k,iEdge) = tend_u(k,iEdge)     &amp;
-                   + q     &amp;
-                   - (   ke(k,cell2) - ke(k,cell1) ) / dcEdge(iEdge)
-
-         end do
-      end do
-
-      !
-      ! velocity tendency: forcing and bottom drag
-      !
-      ! mrp 101115 note: in order to include flux boundary conditions, we will need to 
-      ! know the bottom edge with nonzero velocity and place the drag there.
-
-      do iEdge=1,grid % nEdgesSolve
-
-        k = maxLevelEdgeTop(iEdge)
-
-        ! efficiency note: it would be nice to avoid this
-        ! if within a do.  This could be done with
-        ! k =  max(maxLevelEdgeTop(iEdge),1)
-        ! and then tend_u(1,iEdge) is just not used for land cells.
-
-        if (k&gt;0) then
-
-           ! forcing in top layer only
-           tend_u(1,iEdge) =  tend_u(1,iEdge) &amp;
-              + u_src(1,iEdge)/rho_ref/h_edge(1,iEdge)
-
-           ! bottom drag is the same as POP:
-           ! -c |u| u  where c is unitless and 1.0e-3.
-           ! see POP Reference guide, section 3.4.4.
-
-           if (.not.config_implicit_vertical_mix) then
-              tend_u(k,iEdge) = tend_u(k,iEdge)  &amp;
-                - config_bottom_drag_coeff*u(k,iEdge) &amp;
-                  *sqrt(2.0*ke_edge(k,iEdge))/h_edge(k,iEdge)
-           end if
-
-        endif
-
-      enddo
-
-      !
-      ! velocity tendency: vertical mixing d/dz( nu_v du/dz))
-      !
-      if (.not.config_implicit_vertical_mix) then
-         allocate(fluxVertTop(nVertLevels+1))
-         fluxVertTop(1) = 0.0
-         do iEdge=1,grid % nEdgesSolve
-         
-            do k=2,maxLevelEdgeTop(iEdge)
-              fluxVertTop(k) = vertViscTopOfEdge(k,iEdge) &amp;
-                 * ( u(k-1,iEdge) - u(k,iEdge) ) &amp;
-                 * 2 / (h_edge(k-1,iEdge) + h_edge(k,iEdge))
-            enddo
-            fluxVertTop(maxLevelEdgeTop(iEdge)+1) = 0.0
-
-            do k=1,maxLevelEdgeTop(iEdge)
-              tend_u(k,iEdge) = tend_u(k,iEdge) &amp;
-                + (fluxVertTop(k) - fluxVertTop(k+1)) &amp;
-                / h_edge(k,iEdge)
-            enddo
-
-         end do
-         deallocate(fluxVertTop)
-      endif
-
-   end subroutine compute_tend
-
-
-   subroutine compute_scalar_tend(tend, s, d, grid)
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   !
-   ! Input: s - current model state
-   !        grid - grid metadata
-   !
-   ! Output: tend - computed scalar tendencies
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-      implicit none
-
-      type (tend_type), intent(inout) :: tend
-      type (state_type), intent(in) :: s
-      type (diagnostics_type), intent(in) :: d
-      type (mesh_type), intent(in) :: grid
-
-      integer :: i, k, iCell, iEdge, iTracer, cell1, cell2, upwindCell,&amp;
-        nEdges, nCells, nCellsSolve, nVertLevels, num_tracers
-      real (kind=RKIND) :: invAreaCell1, invAreaCell2, tracer_turb_flux
-      real (kind=RKIND) :: flux, tracer_edge, r
-      real (kind=RKIND), dimension(:), pointer :: &amp;
-        h_s, fVertex, fEdge, dvEdge, dcEdge, areaCell, areaTriangle
-      real (kind=RKIND), dimension(:,:), pointer :: &amp;
-        u,h,wTop, h_edge, vertDiffTopOfCell
-      real (kind=RKIND), dimension(:,:,:), pointer :: &amp;
-        tracers, tend_tr
-      integer, dimension(:,:), pointer :: boundaryEdge
-      type (dm_info) :: dminfo
-
-      integer, dimension(:), pointer :: nEdgesOnCell, nEdgesOnEdge, &amp;
-        maxLevelCell, maxLevelEdgeTop, maxLevelVertexBot
-      integer, dimension(:,:), pointer :: cellsOnEdge, boundaryCell
-      real (kind=RKIND), dimension(:), pointer :: zTopZLevel,zMidZLevel, &amp;
-         hRatioZLevelK, hRatioZLevelKm1
-      real (kind=RKIND), dimension(:), allocatable:: tracer2ndDer, tracersIn, tracersOut, posZMidZLevel, &amp;
-            posZTopZLevel
-      real (kind=RKIND), dimension(:,:), allocatable:: fluxVertTop, boundaryMask
-      real (kind=RKIND), dimension(:,:,:), allocatable::tr_flux, tr_div, delsq_tracer, tracerTop
-
-
-      real (kind=RKIND) :: d2fdx2_cell1, d2fdx2_cell2
-      real (kind=RKIND), dimension(:,:,:), pointer :: deriv_two
-      real (kind=RKIND) :: coef_3rd_order, flux3Coef, cSignWTop
-
-      integer :: index_temperature, index_salinity, rrr
-      real (kind=RKIND), dimension(:), pointer :: temperatureRestore, salinityRestore
-
-      u           =&gt; s % u % array
-      h           =&gt; s % h % array
-      boundaryCell=&gt; grid % boundaryCell % array
-      wTop        =&gt; s % wTop % array
-      tracers     =&gt; s % tracers % array
-      h_edge      =&gt; s % h_edge % array
-      vertDiffTopOfCell =&gt; d % vertDiffTopOfCell % array
-
-      tend_tr     =&gt; tend % tracers % array
-                  
-      areaCell          =&gt; grid % areaCell % array
-      cellsOnEdge       =&gt; grid % cellsOnEdge % array
-      dvEdge            =&gt; grid % dvEdge % array
-      dcEdge            =&gt; grid % dcEdge % array
-      zTopZLevel        =&gt; grid % zTopZLevel % array
-      zMidZLevel        =&gt; grid % zMidZLevel % array
-      hRatioZLevelK    =&gt; grid % hRatioZLevelK % array
-      hRatioZLevelKm1    =&gt; grid % hRatioZLevelKm1 % array
-      boundaryEdge      =&gt; grid % boundaryEdge % array
-      maxLevelCell      =&gt; grid % maxLevelCell % array
-      maxLevelEdgeTop      =&gt; grid % maxLevelEdgeTop % array
-      maxLevelVertexBot    =&gt; grid % maxLevelVertexBot % array
-
-      nEdges      = grid % nEdges
-      nCells      = grid % nCells
-      nCellsSolve = grid % nCellsSolve
-      nVertLevels = grid % nVertLevels
-      num_tracers = s % num_tracers
-
-      deriv_two   =&gt; grid % deriv_two % array
-
-      if(config_restoreTS) then
-        index_temperature = s % index_temperature
-        index_salinity = s % index_salinity
-        temperatureRestore =&gt; grid % temperatureRestore % array
-        salinityRestore =&gt; grid % salinityRestore % array
-      endif
-
-      !
-      ! initialize tracer tendency (RHS of tracer equation) to zero.
-      !
-      tend_tr(:,:,:) = 0.0
-
-      !
-      ! tracer tendency: horizontal advection term -div( h \phi u)
-      !
-      ! mrp 101115 note: in order to include flux boundary conditions, we will need to 
-      ! assign h_edge for maxLevelEdgeTop:maxLevelEdgeBot in the compute_solve_diagnostics
-      ! and then change maxLevelEdgeTop to maxLevelEdgeBot in the following section.
-      ! tracer_edge at the boundary will also need to be defined for flux boundaries.
-
-      coef_3rd_order = 0.
-      if (config_tracer_adv_order == 3) coef_3rd_order = 1.0
-      if (config_tracer_adv_order == 3 .and. config_monotonic) coef_3rd_order = 0.25
-
-      if (config_tracer_adv_order == 2) then
-
-         do iEdge=1,nEdges
-            cell1 = cellsOnEdge(1,iEdge)
-            cell2 = cellsOnEdge(2,iEdge)
-            do k=1,maxLevelEdgeTop(iEdge)
-               do iTracer=1,num_tracers
-                  tracer_edge = 0.5 * (tracers(iTracer,k,cell1) + tracers(iTracer,k,cell2))
-                  flux = u(k,iEdge) * dvEdge(iEdge) * h_edge(k,iEdge) * tracer_edge
-                  tend_tr(iTracer,k,cell1) = tend_tr(iTracer,k,cell1) - flux/areaCell(cell1)
-                  tend_tr(iTracer,k,cell2) = tend_tr(iTracer,k,cell2) + flux/areaCell(cell2)
-               end do
-            end do
-         end do
-
-      else if (config_tracer_adv_order == 3) then
-
-         do iEdge=1,nEdges
-            cell1 = cellsOnEdge(1,iEdge)
-            cell2 = cellsOnEdge(2,iEdge)
-
-            do k=1,maxLevelEdgeTop(iEdge)
-
-               d2fdx2_cell1 = 0.0
-               d2fdx2_cell2 = 0.0
-
-               do iTracer=1,num_tracers
-
-                  !-- if not a boundary cell
-                  if(boundaryCell(k,cell1).eq.0.and.boundaryCell(k,cell2).eq.0) then
-
-                     d2fdx2_cell1 = deriv_two(1,1,iEdge) * tracers(iTracer,k,cell1)
-                     d2fdx2_cell2 = deriv_two(1,2,iEdge) * tracers(iTracer,k,cell2)
-
-                     !-- all edges of cell 1
-                     do i=1, grid % nEdgesOnCell % array (cell1)
-                        d2fdx2_cell1 = d2fdx2_cell1 + &amp;
-                        deriv_two(i+1,1,iEdge) * tracers(iTracer,k,grid % CellsOnCell % array (i,cell1))
-                     end do
-
-                     !-- all edges of cell 2
-                     do i=1, grid % nEdgesOnCell % array (cell2)
-                        d2fdx2_cell2 = d2fdx2_cell2 + &amp;
-                        deriv_two(i+1,2,iEdge) * tracers(iTracer,k,grid % CellsOnCell % array (i,cell2))
-                     end do
-
-                  endif
-
-                  !-- if u &gt; 0:
-                  if (u(k,iEdge) &gt; 0) then
-                     flux = dvEdge(iEdge) * u(k,iEdge) * h_edge(k,iEdge) * (          &amp;
-                          0.5*(tracers(iTracer,k,cell1) + tracers(iTracer,k,cell2))      &amp;
-                          -(dcEdge(iEdge) **2) * (d2fdx2_cell1 + d2fdx2_cell2) / 12.          &amp;
-                          -(dcEdge(iEdge) **2) * coef_3rd_order*(d2fdx2_cell1 - d2fdx2_cell2) / 12. )
-                  !-- else u &lt;= 0:
-                  else
-                     flux = dvEdge(iEdge) *  u(k,iEdge) * h_edge(k,iEdge) * (          &amp;
-                          0.5*(tracers(iTracer,k,cell1) + tracers(iTracer,k,cell2))      &amp;
-                          -(dcEdge(iEdge) **2) * (d2fdx2_cell1 + d2fdx2_cell2) / 12.          &amp;
-                          +(dcEdge(iEdge) **2) * coef_3rd_order*(d2fdx2_cell1 - d2fdx2_cell2) / 12. )
-                  end if
-
-                  !-- update tendency
-                  tend_tr(iTracer,k,cell1) = tend_tr(iTracer,k,cell1) - flux/areaCell(cell1)
-                  tend_tr(iTracer,k,cell2) = tend_tr(iTracer,k,cell2) + flux/areaCell(cell2)
-               enddo
-            end do
-         end do
-
-      else if (config_tracer_adv_order == 4) then
-
-         do iEdge=1,nEdges
-            cell1 = cellsOnEdge(1,iEdge)
-            cell2 = cellsOnEdge(2,iEdge)
-
-            do k=1,maxLevelEdgeTop(iEdge)
-
-               d2fdx2_cell1 = 0.0
-               d2fdx2_cell2 = 0.0
-
-               do iTracer=1,num_tracers
-
-                  !-- if not a boundary cell
-                  if(boundaryCell(k,cell1).eq.0.and.boundaryCell(k,cell2).eq.0) then
-
-                     d2fdx2_cell1 = deriv_two(1,1,iEdge) * tracers(iTracer,k,cell1)
-                     d2fdx2_cell2 = deriv_two(1,2,iEdge) * tracers(iTracer,k,cell2)
-
-                     !-- all edges of cell 1
-                     do i=1, grid % nEdgesOnCell % array (cell1)
-                        d2fdx2_cell1 = d2fdx2_cell1 + &amp;
-                        deriv_two(i+1,1,iEdge) * tracers(iTracer,k,grid % CellsOnCell % array (i,cell1))
-                     end do
-
-                     !-- all edges of cell 2
-                     do i=1, grid % nEdgesOnCell % array (cell2)
-                         d2fdx2_cell2 = d2fdx2_cell2 + &amp;
-                         deriv_two(i+1,2,iEdge) * tracers(iTracer,k,grid % CellsOnCell % array (i,cell2))
-                     end do
-
-                  endif
-
-                  flux = dvEdge(iEdge) *  u(k,iEdge) * h_edge(k,iEdge) * (          &amp;
-                       0.5*(tracers(iTracer,k,cell1) + tracers(iTracer,k,cell2))      &amp;
-                          -(dcEdge(iEdge) **2) * (d2fdx2_cell1 + d2fdx2_cell2) / 12. )
-
-                  !-- update tendency
-                  tend_tr(iTracer,k,cell1) = tend_tr(iTracer,k,cell1) - flux/areaCell(cell1)
-                  tend_tr(iTracer,k,cell2) = tend_tr(iTracer,k,cell2) + flux/areaCell(cell2)
-               enddo
-            end do
-         end do
-
-      endif   ! if (config_tracer_adv_order == 2 )
-
-
-      !
-      ! tracer tendency: vertical advection term -d/dz( h \phi w)
-      !
-
-      if (config_vert_grid_type.eq.'zlevel') then
-
-         allocate(tracerTop(num_tracers,nVertLevels+1,nCells))
-
-         ! Tracers at the top and bottom boundary are assigned nearest 
-         ! cell-centered value, regardless of tracer interpolation method.
-         ! wTop=0 at top and bottom sets the boundary condition.
-         do iCell=1,nCellsSolve 
-            do iTracer=1,num_tracers
-               tracerTop(iTracer,1,iCell) = tracers(iTracer,1,iCell)
-               tracerTop(iTracer,maxLevelCell(iCell)+1,iCell) = &amp;
-               tracers(iTracer,maxLevelCell(iCell),iCell)
-            end do
-         end do
-
-         if (config_vert_tracer_adv.eq.'stencil'.and. &amp;
-             config_vert_tracer_adv_order.eq.2) then
-
-            ! Compute tracerTop using centered stencil, a simple average.
-
-            do iCell=1,nCellsSolve 
-               do k=2,maxLevelCell(iCell)
-                  do iTracer=1,num_tracers
-                     tracerTop(iTracer,k,iCell) = &amp;
-                        ( tracers(iTracer,k-1,iCell) &amp;
-                         +tracers(iTracer,k  ,iCell))/2.0
-                  end do
-               end do
-            end do
-         
-         elseif (config_vert_tracer_adv.eq.'stencil'.and. &amp;
-             config_vert_tracer_adv_order.eq.3) then
-
-            ! Compute tracerTop using 3rd order stencil.  This is the same
-            ! as 4th order, but includes upwinding.
-
-            ! Hardwire flux3Coeff at 1.0 for now.  Could add this to the 
-            ! namelist, if desired.
-            flux3Coef = 1.0
-            do iCell=1,nCellsSolve 
-               k=2
-               do iTracer=1,num_tracers
-                 tracerTop(iTracer,k,iCell) = &amp;
-                      hRatioZLevelK(k)  *tracers(iTracer,k-1,iCell) &amp;
-                    + hRatioZLevelKm1(k)*tracers(iTracer,k  ,iCell)
-               end do
-               do k=3,maxLevelCell(iCell)-1
-                  cSignWTop = sign(flux3Coef,wTop(k,iCell))
-                  do iTracer=1,num_tracers
-                     tracerTop(iTracer,k,iCell) = &amp;
-                        ( (-1.+   cSignWTop)*tracers(iTracer,k-2,iCell) &amp;
-                         +( 7.-3.*cSignWTop)*tracers(iTracer,k-1,iCell) &amp;
-                         +( 7.+3.*cSignWTop)*tracers(iTracer,k  ,iCell) &amp;
-                         +(-1.-   cSignWTop)*tracers(iTracer,k+1,iCell) &amp;
-                        )/12.
-                  end do
-               end do
-               k=maxLevelCell(iCell)
-                  do iTracer=1,num_tracers
-                    tracerTop(iTracer,k,iCell) = &amp;
-                         hRatioZLevelK(k)  *tracers(iTracer,k-1,iCell) &amp;
-                       + hRatioZLevelKm1(k)*tracers(iTracer,k  ,iCell)
-                  end do
-            end do
-
-         elseif (config_vert_tracer_adv.eq.'stencil'.and. &amp;
-             config_vert_tracer_adv_order.eq.4) then
-
-            ! Compute tracerTop using 4rd order stencil [-1 7 7 -1]
-
-            do iCell=1,nCellsSolve 
-               k=2
-                  do iTracer=1,num_tracers
-                    tracerTop(iTracer,k,iCell) = &amp;
-                         hRatioZLevelK(k)  *tracers(iTracer,k-1,iCell) &amp;
-                       + hRatioZLevelKm1(k)*tracers(iTracer,k  ,iCell)
-                  end do
-               do k=3,maxLevelCell(iCell)-1
-                  do iTracer=1,num_tracers
-                     tracerTop(iTracer,k,iCell) = &amp;
-                        (-   tracers(iTracer,k-2,iCell) &amp;
-                         +7.*tracers(iTracer,k-1,iCell) &amp;
-                         +7.*tracers(iTracer,k  ,iCell) &amp;
-                         -   tracers(iTracer,k+1,iCell) &amp;
-                        )/12.
-                  end do
-               end do
-               k=maxLevelCell(iCell)
-                  do iTracer=1,num_tracers
-                    tracerTop(iTracer,k,iCell) = &amp;
-                         hRatioZLevelK(k)  *tracers(iTracer,k-1,iCell) &amp;
-                       + hRatioZLevelKm1(k)*tracers(iTracer,k  ,iCell)
-                  end do
-            end do
-
-         elseif (config_vert_tracer_adv.eq.'spline'.and. &amp;
-             config_vert_tracer_adv_order.eq.2) then
-
-            ! Compute tracerTop using linear interpolation.
-
-            do iCell=1,nCellsSolve 
-               do k=2,maxLevelCell(iCell)
-                  do iTracer=1,num_tracers
-                     ! Note hRatio on the k side is multiplied by tracer at k-1
-                     ! and hRatio on the Km1 (k-1) side is mult. by tracer at k.
-                     tracerTop(iTracer,k,iCell) = &amp;
-                          hRatioZLevelK(k)  *tracers(iTracer,k-1,iCell) &amp;
-                        + hRatioZLevelKm1(k)*tracers(iTracer,k  ,iCell)
-                  end do
-               end do
-            end do
-         
-         elseif (config_vert_tracer_adv.eq.'spline'.and. &amp;
-             config_vert_tracer_adv_order.eq.3) then
-
-            ! Compute tracerTop using cubic spline interpolation.
-
-            allocate(tracer2ndDer(nVertLevels))
-            allocate(tracersIn(nVertLevels),tracersOut(nVertLevels), &amp;
-               posZMidZLevel(nVertLevels), posZTopZLevel(nVertLevels-1))
-
-            ! For the ocean, zlevel coordinates are negative and decreasing, 
-            ! but spline functions assume increasing, so flip to positive.
-
-            posZMidZLevel = -zMidZLevel(1:nVertLevels)
-            posZTopZLevel = -zTopZLevel(2:nVertLevels)
-
-            do iCell=1,nCellsSolve 
-               ! mrp 110201 efficiency note: push tracer loop down
-               ! into spline subroutines to improve efficiency
-               do iTracer=1,num_tracers
-
-                  ! Place data in arrays to avoid creating new temporary arrays for every 
-                  ! subroutine call.  
-                  tracersIn(1:maxLevelCell(iCell))=tracers(iTracer,1:maxLevelCell(iCell),iCell)
-
-                  call CubicSplineCoefficients(posZMidZLevel, &amp;
-                     tracersIn, maxLevelCell(iCell), tracer2ndDer)
-
-                  call InterpolateCubicSpline( &amp;
-                     posZMidZLevel, tracersIn, tracer2ndDer, maxLevelCell(iCell), &amp;
-                     posZTopZLevel, tracersOut, maxLevelCell(iCell)-1 )
-
-                  tracerTop(iTracer,2:maxLevelCell(iCell),iCell) = tracersOut(1:maxLevelCell(iCell)-1)
-
-               end do
-            end do
-
-            deallocate(tracer2ndDer)
-            deallocate(tracersIn,tracersOut, posZMidZLevel, posZTopZLevel)
-
-        else
-
-            print *, 'Abort: Incorrect combination of ', &amp;
-              'config_vert_tracer_adv and config_vert_tracer_adv_order.'
-            print *, 'Use:'
-            print *, 'config_vert_tracer_adv=''stencil'' and config_vert_tracer_adv_order=2,3,4 or'
-            print *, 'config_vert_tracer_adv=''spline''  and config_vert_tracer_adv_order=2,3'
-            call dmpar_abort(dminfo)
-
-         endif ! vertical tracer advection method
-
-         do iCell=1,nCellsSolve 
-            do k=1,maxLevelCell(iCell)  
-               do iTracer=1,num_tracers
-                  tend_tr(iTracer,k,iCell) = tend_tr(iTracer,k,iCell) &amp;
-                     - (   wTop(k  ,iCell)*tracerTop(iTracer,k  ,iCell) &amp;
-                         - wTop(k+1,iCell)*tracerTop(iTracer,k+1,iCell))
-               end do
-            end do
-         end do
-
-         deallocate(tracerTop)
-
-      endif ! ZLevel
-
-      !
-      ! tracer tendency: del2 horizontal tracer diffusion, div(h \kappa_2 </font>
<font color="red">abla \phi)
-      !
-      if ( config_h_tracer_eddy_diff2 &gt; 0.0 ) then
-
-         !
-         ! compute a boundary mask to enforce insulating boundary conditions in the horizontal
-         !
-         allocate(boundaryMask(nVertLevels, nEdges+1))
-         boundaryMask = 1.0
-         where(boundaryEdge.eq.1) boundaryMask=0.0
-
-         do iEdge=1,grid % nEdges
-            cell1 = grid % cellsOnEdge % array(1,iEdge)
-            cell2 = grid % cellsOnEdge % array(2,iEdge)
-            invAreaCell1 = 1.0/areaCell(cell1)
-            invAreaCell2 = 1.0/areaCell(cell2)
-
-            do k=1,maxLevelEdgeTop(iEdge)
-              do iTracer=1,num_tracers
-                 ! \kappa_2 </font>
<font color="red">abla \phi on edge
-                 tracer_turb_flux = config_h_tracer_eddy_diff2 &amp;
-                    *(  tracers(iTracer,k,cell2) &amp;
-                      - tracers(iTracer,k,cell1))/dcEdge(iEdge)
-
-                 ! div(h \kappa_2 </font>
<font color="red">abla \phi) at cell center
-                 flux = dvEdge (iEdge) * h_edge(k,iEdge) &amp;
-                    * tracer_turb_flux * boundaryMask(k, iEdge)
-                 tend_tr(iTracer,k,cell1) = tend_tr(iTracer,k,cell1) + flux * invAreaCell1
-                 tend_tr(iTracer,k,cell2) = tend_tr(iTracer,k,cell2) - flux * invAreaCell2
-              end do
-            end do
-
-         end do
-
-        deallocate(boundaryMask)
-
-      end if
-
-      !
-      ! tracer tendency: del4 horizontal tracer diffusion, &amp;
-      !    div(h \kappa_4 </font>
<font color="black">abla [div(h </font>
<font color="red">abla \phi)])
-      !
-      if ( config_h_tracer_eddy_diff4 &gt; 0.0 ) then
-
-         !
-         ! compute a boundary mask to enforce insulating boundary conditions in the horizontal
-         !
-         allocate(boundaryMask(nVertLevels, nEdges+1))
-         boundaryMask = 1.0
-         where(boundaryEdge.eq.1) boundaryMask=0.0
-
-         allocate(delsq_tracer(num_tracers,nVertLevels, nCells+1))
-
-         delsq_tracer(:,:,:) = 0.
-
-         ! first del2: div(h </font>
<font color="red">abla \phi) at cell center
-         do iEdge=1,grid % nEdges
-            cell1 = grid % cellsOnEdge % array(1,iEdge)
-            cell2 = grid % cellsOnEdge % array(2,iEdge)
-
-            do k=1,maxLevelEdgeTop(iEdge)
-              do iTracer=1,num_tracers
-                 delsq_tracer(iTracer,k,cell1) = delsq_tracer(iTracer,k,cell1) &amp;
-                    + dvEdge(iEdge)*h_edge(k,iEdge) &amp;
-                      *(tracers(iTracer,k,cell2) - tracers(iTracer,k,cell1)) &amp;
-                      /dcEdge(iEdge) * boundaryMask(k,iEdge)
-                 delsq_tracer(iTracer,k,cell2) = delsq_tracer(iTracer,k,cell2) &amp;
-                    - dvEdge(iEdge)*h_edge(k,iEdge) &amp;
-                    *(tracers(iTracer,k,cell2) - tracers(iTracer,k,cell1)) &amp;
-                    /dcEdge(iEdge) * boundaryMask(k,iEdge)
-              end do
-            end do
-
-         end do
-
-         do iCell = 1,nCells
-            r = 1.0 / areaCell(iCell)
-            do k=1,maxLevelCell(iCell)
-            do iTracer=1,num_tracers
-               delsq_tracer(iTracer,k,iCell) = delsq_tracer(iTracer,k,iCell) * r
-            end do
-            end do
-         end do
-
-         ! second del2: div(h </font>
<font color="red">abla [delsq_tracer]) at cell center
-         do iEdge=1,grid % nEdges
-            cell1 = grid % cellsOnEdge % array(1,iEdge)
-            cell2 = grid % cellsOnEdge % array(2,iEdge)
-            invAreaCell1 = 1.0 / areaCell(cell1)
-            invAreaCell2 = 1.0 / areaCell(cell2)
-
-            do k=1,maxLevelEdgeTop(iEdge)
-               do iTracer=1,num_tracers
-                  tracer_turb_flux = config_h_tracer_eddy_diff4 &amp;
-                     *(  delsq_tracer(iTracer,k,cell2)  &amp;
-                       - delsq_tracer(iTracer,k,cell1))/dcEdge(iEdge)
-                  flux = dvEdge (iEdge) * tracer_turb_flux
-
-                  tend_tr(iTracer,k,cell1) = tend_tr(iTracer,k,cell1) &amp; 
-                     - flux * invAreaCell1 * boundaryMask(k,iEdge)
-                  tend_tr(iTracer,k,cell2) = tend_tr(iTracer,k,cell2) &amp;
-                     + flux * invAreaCell2 * boundaryMask(k,iEdge)
-
-               enddo
-            enddo
-         end do
-
-         deallocate(delsq_tracer)
-
-      end if
-
-      !
-      ! tracer tendency: vertical diffusion h d/dz( \kappa_v d\phi/dz)
-      !
-      if (.not.config_implicit_vertical_mix) then
-         allocate(fluxVertTop(num_tracers,nVertLevels+1))
-         fluxVertTop(:,1) = 0.0
-         do iCell=1,nCellsSolve 
-
-            do k=2,maxLevelCell(iCell)
-              do iTracer=1,num_tracers
-                ! compute \kappa_v d\phi/dz
-                fluxVertTop(iTracer,k) = vertDiffTopOfCell(k,iCell) &amp;
-                   * (tracers(iTracer,k-1,iCell) - tracers(iTracer,k,iCell) )&amp;
-                   * 2 / (h(k-1,iCell) + h(k,iCell))
-              enddo
-            enddo
-            fluxVertTop(:,maxLevelCell(iCell)+1) = 0.0
-
-            do k=1,maxLevelCell(iCell)
-              do iTracer=1,num_tracers
-                ! This is h d/dz( fluxVertTop) but h and dz cancel, so 
-                ! reduces to delta( fluxVertTop)
-                tend_tr(iTracer,k,iCell) = tend_tr(iTracer,k,iCell) &amp;
-                  + fluxVertTop(iTracer,k) - fluxVertTop(iTracer,k+1)
-              enddo
-            enddo
-
-         enddo ! iCell loop
-         deallocate(fluxVertTop)
-      endif
-
-      !
-      ! add restoring to T and S in top model layer
-      !
-      if(config_restoreTS) then
-         k = 1  ! restoring only in top layer
-         do iCell=1,nCellsSolve
-
-           tend_tr(index_temperature, k, iCell) = tend_tr(index_temperature, k, iCell)  &amp;
-                - h(k,iCell)*(tracers(index_temperature, k, iCell) - temperatureRestore(iCell)) &amp;
-                / (config_restoreT_timescale * 86400.0)
-
-           tend_tr(index_salinity, k, iCell) = tend_tr(index_salinity, k, iCell)  &amp;
-                - h(k,iCell)*(tracers(index_salinity, k, iCell) - salinityRestore(iCell)) &amp;
-                / (config_restoreS_timescale * 86400.0)
-
-   !       write(6,10) iCell, tracers(index_temperature, k, iCell), &amp;
-   !              temperatureRestore(iCell), tracers(index_temperature, k, iCell), &amp;
-   !             (tracers(index_temperature, k, iCell) - temperatureRestore(iCell)) &amp;
-   !             / (config_restoreT_timescale * 86400.0)
-
-         enddo
-
-      endif
- 10   format(2i8,10e20.10)
-
-
-          ! print some diagnostics - for debugging
-!         print *, 'after vertical mixing',&amp;
-! 'iTracer,k, minval(tend_tr(itracer,k,:)), maxval(tend_tr(itracer,k,:))'
-!         do iTracer=1,num_tracers
-!         do k = 1,nVertLevels
-!            print '(2i5,20es12.4)', iTracer,k, &amp;
-!              minval(tend_tr(itracer,k,:)), maxval(tend_tr(itracer,k,:))
-!         enddo
-!         enddo
-
-
-   end subroutine compute_scalar_tend
-
-
-   subroutine compute_solve_diagnostics(dt, s, grid)
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   ! Compute diagnostic fields used in the tendency computations
-   !
-   ! Input: grid - grid metadata
-   !
-   ! Output: s - computed diagnostics
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-      implicit none
-
-      real (kind=RKIND), intent(in) :: dt
-      type (state_type), intent(inout) :: s
-      type (mesh_type), intent(in) :: grid
-
-
-      integer :: iEdge, iCell, iVertex, k, cell1, cell2, vertex1, vertex2, eoe, i, j, cov
-      real (kind=RKIND) :: flux, vorticity_abs, h_vertex, workpv, rho0Inv
-
-      integer :: nCells, nEdges, nVertices, nVertLevels, vertexDegree
-
-
-      real (kind=RKIND), dimension(:), pointer :: &amp;
-        h_s, fVertex, fEdge, dvEdge, dcEdge, areaCell, areaTriangle, &amp;
-        hZLevel
-      real (kind=RKIND), dimension(:,:), pointer :: &amp;
-        weightsOnEdge, kiteAreasOnVertex, h_edge, h, u, v, w, pressure,&amp;
-        circulation, vorticity, ke, ke_edge, MontPot, wTop, &amp;
-        pv_edge, pv_vertex, pv_cell, gradPVn, gradPVt, divergence, &amp;
-        rho, temperature, salinity
-      real (kind=RKIND), dimension(:,:,:), pointer :: tracers
-      real (kind=RKIND), dimension(:), allocatable:: pTop
-      real (kind=RKIND), dimension(:,:), allocatable:: div_u
-      character :: c1*6
-
-      integer, dimension(:,:), pointer :: cellsOnEdge, cellsOnVertex, &amp;
-        verticesOnEdge, edgesOnCell, edgesOnEdge, edgesOnVertex, &amp;
-        boundaryEdge, boundaryCell
-      integer, dimension(:), pointer :: nEdgesOnCell, nEdgesOnEdge, &amp;
-        maxLevelCell, maxLevelEdgeTop, maxLevelEdgeBot, &amp;
-        maxLevelVertexBot,  maxLevelVertexTop
-      real (kind=RKIND) :: d2fdx2_cell1, d2fdx2_cell2
-      real (kind=RKIND), dimension(:,:,:), pointer :: deriv_two
-      real (kind=RKIND) :: coef_3rd_order
-      real (kind=RKIND) :: r, h1, h2
-
-      h           =&gt; s % h % array
-      u           =&gt; s % u % array
-      v           =&gt; s % v % array
-      wTop        =&gt; s % wTop % array
-      h_edge      =&gt; s % h_edge % array
-      circulation =&gt; s % circulation % array
-      vorticity   =&gt; s % vorticity % array
-      divergence  =&gt; s % divergence % array
-      ke          =&gt; s % ke % array
-      ke_edge     =&gt; s % ke_edge % array
-      pv_edge     =&gt; s % pv_edge % array
-      pv_vertex   =&gt; s % pv_vertex % array
-      pv_cell     =&gt; s % pv_cell % array
-      gradPVn     =&gt; s % gradPVn % array
-      gradPVt     =&gt; s % gradPVt % array
-      rho         =&gt; s % rho % array
-      tracers     =&gt; s % tracers % array
-      MontPot     =&gt; s % MontPot % array
-      pressure    =&gt; s % pressure % array
-
-      weightsOnEdge     =&gt; grid % weightsOnEdge % array
-      kiteAreasOnVertex =&gt; grid % kiteAreasOnVertex % array
-      cellsOnEdge       =&gt; grid % cellsOnEdge % array
-      cellsOnVertex     =&gt; grid % cellsOnVertex % array
-      verticesOnEdge    =&gt; grid % verticesOnEdge % array
-      nEdgesOnCell      =&gt; grid % nEdgesOnCell % array
-      edgesOnCell       =&gt; grid % edgesOnCell % array
-      nEdgesOnEdge      =&gt; grid % nEdgesOnEdge % array
-      edgesOnEdge       =&gt; grid % edgesOnEdge % array
-      edgesOnVertex     =&gt; grid % edgesOnVertex % array
-      dcEdge            =&gt; grid % dcEdge % array
-      dvEdge            =&gt; grid % dvEdge % array
-      areaCell          =&gt; grid % areaCell % array
-      areaTriangle      =&gt; grid % areaTriangle % array
-      h_s               =&gt; grid % h_s % array
-      fVertex           =&gt; grid % fVertex % array
-      fEdge             =&gt; grid % fEdge % array
-      hZLevel           =&gt; grid % hZLevel % array
-      deriv_two         =&gt; grid % deriv_two % array
-      maxLevelCell      =&gt; grid % maxLevelCell % array
-      maxLevelEdgeTop   =&gt; grid % maxLevelEdgeTop % array
-      maxLevelEdgeBot   =&gt; grid % maxLevelEdgeBot % array
-      maxLevelVertexBot =&gt; grid % maxLevelVertexBot % array
-      maxLevelVertexTop =&gt; grid % maxLevelVertexTop % array
-                  
-      nCells      = grid % nCells
-      nEdges      = grid % nEdges
-      nVertices   = grid % nVertices
-      nVertLevels = grid % nVertLevels
-      vertexDegree = grid % vertexDegree
-
-      boundaryEdge =&gt; grid % boundaryEdge % array
-      boundaryCell =&gt; grid % boundaryCell % array
-
-      !
-      ! Compute height on cell edges at velocity locations
-      !   Namelist options control the order of accuracy of the reconstructed h_edge value
-      !
-      ! mrp 101115 note: in order to include flux boundary conditions, we will need to 
-      ! assign h_edge for maxLevelEdgeTop:maxLevelEdgeBot in the following section
-
-      coef_3rd_order = 0.
-      if (config_thickness_adv_order == 3) coef_3rd_order = 1.0
-      if (config_thickness_adv_order == 3 .and. config_monotonic) coef_3rd_order = 0.25
-
-      if (config_thickness_adv_order == 2) then
-
-         do iEdge=1,nEdges
-            cell1 = cellsOnEdge(1,iEdge)
-            cell2 = cellsOnEdge(2,iEdge)
-            do k=1,maxLevelEdgeTop(iEdge)
-               h_edge(k,iEdge) = 0.5 * (h(k,cell1) + h(k,cell2))
-            end do
-         end do
-
-      else if (config_thickness_adv_order == 3) then
-
-         do iEdge=1,nEdges
-            cell1 = cellsOnEdge(1,iEdge)
-            cell2 = cellsOnEdge(2,iEdge)
-
-            do k=1,maxLevelEdgeTop(iEdge)
-
-               d2fdx2_cell1 = 0.0
-               d2fdx2_cell2 = 0.0
-
-               !-- if not a boundary cell
-               if(boundaryCell(k,cell1).eq.0.and.boundaryCell(k,cell2).eq.0) then
-
-                  d2fdx2_cell1 = deriv_two(1,1,iEdge) * h(k,cell1)
-                  d2fdx2_cell2 = deriv_two(1,2,iEdge) * h(k,cell2)
-
-                  !-- all edges of cell 1
-                  do i=1, grid % nEdgesOnCell % array (cell1)
-                          d2fdx2_cell1 = d2fdx2_cell1 + &amp;
-                          deriv_two(i+1,1,iEdge) * h(k,grid % CellsOnCell % array (i,cell1))
-                  end do
-
-                  !-- all edges of cell 2
-                  do i=1, grid % nEdgesOnCell % array (cell2)
-                          d2fdx2_cell2 = d2fdx2_cell2 + &amp;
-                          deriv_two(i+1,2,iEdge) * h(k,grid % CellsOnCell % array (i,cell2))
-                  end do
-
-               endif
-
-               !-- if u &gt; 0:
-               if (u(k,iEdge) &gt; 0) then
-                  h_edge(k,iEdge) =     &amp;
-                       0.5*(h(k,cell1) + h(k,cell2))      &amp;
-                       -(dcEdge(iEdge) **2) * (d2fdx2_cell1 + d2fdx2_cell2) / 12.          &amp;
-                       -(dcEdge(iEdge) **2) * coef_3rd_order*(d2fdx2_cell1 - d2fdx2_cell2) / 12.
-               !-- else u &lt;= 0:
-               else
-                  h_edge(k,iEdge) =     &amp;
-                       0.5*(h(k,cell1) + h(k,cell2))      &amp;
-                       -(dcEdge(iEdge) **2) * (d2fdx2_cell1 + d2fdx2_cell2) / 12.          &amp;
-                       +(dcEdge(iEdge) **2) * coef_3rd_order*(d2fdx2_cell1 - d2fdx2_cell2) / 12.
-               end if
-
-            end do   ! do k
-         end do         ! do iEdge
-
-      else  if (config_thickness_adv_order == 4) then
-
-         do iEdge=1,nEdges
-            cell1 = cellsOnEdge(1,iEdge)
-            cell2 = cellsOnEdge(2,iEdge)
-
-            do k=1,maxLevelEdgeTop(iEdge)
-
-               d2fdx2_cell1 = 0.0
-               d2fdx2_cell2 = 0.0
-
-               !-- if not a boundary cell
-               if(boundaryCell(k,cell1).eq.0.and.boundaryCell(k,cell2).eq.0) then
-
-                  d2fdx2_cell1 = deriv_two(1,1,iEdge) * h(k,cell1)
-                  d2fdx2_cell2 = deriv_two(1,2,iEdge) * h(k,cell2)
-
-                  !-- all edges of cell 1
-                  do i=1, grid % nEdgesOnCell % array (cell1)
-                          d2fdx2_cell1 = d2fdx2_cell1 + &amp;
-                          deriv_two(i+1,1,iEdge) * h(k,grid % CellsOnCell % array (i,cell1))
-                  end do
-
-                  !-- all edges of cell 2
-                  do i=1, grid % nEdgesOnCell % array (cell2)
-                          d2fdx2_cell2 = d2fdx2_cell2 + &amp;
-                          deriv_two(i+1,2,iEdge) * h(k,grid % CellsOnCell % array (i,cell2))
-                  end do
-
-               endif
-
-               h_edge(k,iEdge) =   &amp;
-                    0.5*(h(k,cell1) + h(k,cell2))      &amp;
-                       -(dcEdge(iEdge) **2) * (d2fdx2_cell1 + d2fdx2_cell2) / 12.
-
-            end do   ! do k
-         end do         ! do iEdge
-
-      endif   ! if(config_thickness_adv_order == 2)
-
-      !
-      ! set the velocity and height at dummy address
-      !    used -1e34 so error clearly occurs if these values are used.
-      !
-      u(:,nEdges+1) = -1e34
-      h(:,nCells+1) = -1e34
-      tracers(s % index_temperature,:,nCells+1) = -1e34
-      tracers(s % index_salinity,:,nCells+1) = -1e34
-
-      !
-      ! Compute circulation and relative vorticity at each vertex
-      !
-      circulation(:,:) = 0.0
-      do iEdge=1,nEdges
-         vertex1 = verticesOnEdge(1,iEdge)
-         vertex2 = verticesOnEdge(2,iEdge)
-         do k=1,maxLevelEdgeBot(iEdge)
-            circulation(k,vertex1) = circulation(k,vertex1) - dcEdge(iEdge) * u(k,iEdge)
-            circulation(k,vertex2) = circulation(k,vertex2) + dcEdge(iEdge) * u(k,iEdge)
-         end do
-      end do
-      do iVertex=1,nVertices
-         do k=1,maxLevelVertexBot(iVertex)
-            vorticity(k,iVertex) = circulation(k,iVertex) / areaTriangle(iVertex)
-         end do
-      end do
-
-      !
-      ! Compute the divergence at each cell center
-      !
-      divergence(:,:) = 0.0
-      do iEdge=1,nEdges
-         cell1 = cellsOnEdge(1,iEdge)
-         cell2 = cellsOnEdge(2,iEdge)
-         do k=1,maxLevelEdgeBot(iEdge)
-             divergence(k,cell1) = divergence(k,cell1) + u(k,iEdge)*dvEdge(iEdge)
-             divergence(k,cell2) = divergence(k,cell2) - u(k,iEdge)*dvEdge(iEdge)
-         enddo
-      end do
-      do iCell = 1,nCells
-         r = 1.0 / areaCell(iCell)
-         do k = 1,maxLevelCell(iCell)
-            divergence(k,iCell) = divergence(k,iCell) * r
-         enddo
-      enddo
-
-      !
-      ! Compute kinetic energy in each cell
-      !
-      ke(:,:) = 0.0
-      do iEdge=1,nEdges
-         cell1 = cellsOnEdge(1,iEdge)
-         cell2 = cellsOnEdge(2,iEdge)
-         do k=1,maxLevelEdgeBot(iEdge)
-              ke(k,cell1) = ke(k,cell1) + 0.25 * dcEdge(iEdge) * dvEdge(iEdge) * u(k,iEdge)**2.0
-              ke(k,cell2) = ke(k,cell2) + 0.25 * dcEdge(iEdge) * dvEdge(iEdge) * u(k,iEdge)**2.0
-         enddo
-      end do
-      do iCell = 1,nCells
-         do k = 1,maxLevelCell(iCell)
-            ke(k,iCell) = ke(k,iCell) / areaCell(iCell)
-         enddo
-      enddo
-
-      !
-      ! Compute v (tangential) velocities
-      !
-      v(:,:) = 0.0
-      do iEdge = 1,nEdges
-         do i=1,nEdgesOnEdge(iEdge)
-            eoe = edgesOnEdge(i,iEdge)
-            ! mrp 101115 note: in order to include flux boundary conditions,
-            ! the following loop may need to change to maxLevelEdgeBot
-            do k = 1,maxLevelEdgeTop(iEdge) 
-               v(k,iEdge) = v(k,iEdge) + weightsOnEdge(i,iEdge) * u(k, eoe)
-            end do
-         end do
-      end do
-
-      !
-      ! Compute ke on cell edges at velocity locations for quadratic bottom drag. 
-      !
-      ! mrp 101025 efficiency note: we could get rid of ke_edge completely by 
-      ! using sqrt(u(k,iEdge)**2 + v(k,iEdge)**2) in its place elsewhere.
-      ke_edge = 0.0  !mrp remove 0 for efficiency
-      do iEdge=1,nEdges
-         cell1 = cellsOnEdge(1,iEdge)
-         cell2 = cellsOnEdge(2,iEdge)
-         do k=1,maxLevelEdgeTop(iEdge)
-            ke_edge(k,iEdge) = 0.5 * (ke(k,cell1) + ke(k,cell2))
-         end do
-      end do
-
-      !
-      ! Compute height at vertices, pv at vertices, and average pv to edge locations
-      !  ( this computes pv_vertex at all vertices bounding real cells and distance-1 ghost cells )
-      !
-      do iVertex = 1,nVertices
-         do k=1,maxLevelVertexBot(iVertex)
-            h_vertex = 0.0
-            do i=1,vertexDegree
-               h_vertex = h_vertex + h(k,cellsOnVertex(i,iVertex)) * kiteAreasOnVertex(i,iVertex)
-            end do
-            h_vertex = h_vertex / areaTriangle(iVertex)
-
-            pv_vertex(k,iVertex) = (fVertex(iVertex) + vorticity(k,iVertex)) / h_vertex
-         end do
-      end do
-
-      !
-      ! Compute pv at cell centers
-      !    ( this computes pv_cell for all real cells and distance-1 ghost cells )
-      !
-      pv_cell(:,:) = 0.0
-      do iVertex = 1,nVertices
-         do i=1,vertexDegree
-            iCell = cellsOnVertex(i,iVertex)
-            do k = 1,maxLevelCell(iCell)
-               pv_cell(k,iCell) = pv_cell(k,iCell)  &amp;
-                  + kiteAreasOnVertex(i, iVertex) * pv_vertex(k, iVertex) &amp;
-                    / areaCell(iCell)
-            enddo
-         enddo
-      enddo
-
-      !
-      ! Compute pv at the edges
-      !   ( this computes pv_edge at all edges bounding real cells )
-      !
-      pv_edge(:,:) = 0.0
-      do iVertex = 1,nVertices
-         do i=1,vertexDegree
-            iEdge = edgesOnVertex(i,iVertex)
-            do k=1,maxLevelEdgeBot(iEdge)
-               pv_edge(k,iEdge) =  pv_edge(k,iEdge) + 0.5 * pv_vertex(k,iVertex)
-            enddo
-        end do
-      end do
-
-      !
-      ! Compute gradient of PV in normal direction
-      !   ( this computes gradPVn for all edges bounding real cells )
-      !
-      gradPVn(:,:) = 0.0
-      do iEdge = 1,nEdges
-         do k=1,maxLevelEdgeTop(iEdge)
-            gradPVn(k,iEdge) = (  pv_cell(k,cellsOnEdge(2,iEdge)) &amp;
-                                - pv_cell(k,cellsOnEdge(1,iEdge))) &amp;
-                               / dcEdge(iEdge)
-         enddo
-      enddo
-
-      !
-      ! Compute gradient of PV in the tangent direction
-      !   ( this computes gradPVt at all edges bounding real cells and distance-1 ghost cells )
-      !
-      do iEdge = 1,nEdges
-         do k = 1,maxLevelEdgeBot(iEdge)
-           gradPVt(k,iEdge) = (  pv_vertex(k,verticesOnEdge(2,iEdge)) &amp;
-                               - pv_vertex(k,verticesOnEdge(1,iEdge))) &amp;
-                                 /dvEdge(iEdge)
-         enddo
-      enddo
-
-      !
-      ! Modify PV edge with upstream bias.
-      !
-      do iEdge = 1,nEdges
-         do k = 1,maxLevelEdgeBot(iEdge)
-           pv_edge(k,iEdge) = pv_edge(k,iEdge) &amp;
-             - 0.5 * dt* (  u(k,iEdge) * gradPVn(k,iEdge) &amp;
-                          + v(k,iEdge) * gradPVt(k,iEdge) )
-         enddo
-      enddo
-
-      !
-      ! equation of state
-      !
-      ! For an isopycnal model, density should remain constant.
-      ! For zlevel, calculate in-istu density
-      if (config_vert_grid_type.eq.'zlevel') then
-         call equation_of_state(s,grid,0,'relative')
-      ! mrp 110324 In order to visualize rhoDisplaced, include the following
-         call equation_of_state(s, grid, 1,'relative')
-      endif
-
-      !
-      ! Pressure
-      ! This section must be after computing rho
-      !
-      if (config_vert_grid_type.eq.'isopycnal') then
-
-        ! For Isopycnal model.
-        ! Compute pressure at top of each layer, and then
-        ! Montgomery Potential.
-        allocate(pTop(nVertLevels))
-        do iCell=1,nCells
-
-           ! assume atmospheric pressure at the surface is zero for now.
-           pTop(1) = 0.0
-           ! For isopycnal mode, p is the Montgomery Potential.
-           ! At top layer it is g*SSH, where SSH may be off by a 
-           ! constant (ie, h_s can be relative to top or bottom)
-           MontPot(1,iCell) = gravity &amp;
-              * (h_s(iCell) + sum(h(1:nVertLevels,iCell)))
-
-           do k=2,nVertLevels
-              pTop(k) = pTop(k-1) + rho(k-1,iCell)*gravity* h(k-1,iCell)
-
-              ! from delta M = p delta / rho
-              MontPot(k,iCell) = MontPot(k-1,iCell) &amp;
-                 + pTop(k)*(1.0/rho(k,iCell) - 1.0/rho(k-1,iCell)) 
-           end do
-
-        end do
-        deallocate(pTop)
-
-      elseif (config_vert_grid_type.eq.'zlevel') then
-
-        ! For z-level model.
-        ! Compute pressure at middle of each level.  
-        ! At k=1, where p is pressure at a depth of hZLevel(1)/2, not
-        ! pressure at middle of layer including SSH.
-
-        do iCell=1,nCells
-           ! compute pressure for z-level coordinates
-           ! assume atmospheric pressure at the surface is zero for now.
-
-           pressure(1,iCell) = rho(1,iCell)*gravity &amp;
-              * (h(1,iCell)-0.5*hZLevel(1)) 
-
-           do k=2,maxLevelCell(iCell)
-              pressure(k,iCell) = pressure(k-1,iCell)  &amp;
-                + 0.5*gravity*(  rho(k-1,iCell)*hZLevel(k-1) &amp;
-                               + rho(k  ,iCell)*hZLevel(k  ))
-           end do
-
-        end do
-
-      endif
-
-      !
-      ! vertical velocity through layer interface
-      !
-      if (config_vert_grid_type.eq.'isopycnal') then
-        ! set vertical velocity to zero in isopycnal case
-        wTop=0.0  
-
-      elseif (config_vert_grid_type.eq.'zlevel') then
-
-        !
-        ! Compute div(u) for each cell
-        ! See Ringler et al. (2010) jcp paper, eqn 19, 21, and fig. 3.
-        !
-        allocate(div_u(nVertLevels,nCells+1))
-        div_u(:,:) = 0.0
-        do iEdge=1,nEdges
-           cell1 = cellsOnEdge(1,iEdge)
-           cell2 = cellsOnEdge(2,iEdge)
-           do k=2,maxLevelEdgeBot(iEdge)
-              flux = u(k,iEdge) * dvEdge(iEdge) 
-              div_u(k,cell1) = div_u(k,cell1) + flux
-              div_u(k,cell2) = div_u(k,cell2) - flux
-           end do 
-        end do 
-
-        do iCell=1,nCells
-           ! Vertical velocity through layer interface at top and 
-           ! bottom is zero.
-           wTop(1,iCell) = 0.0
-           wTop(maxLevelCell(iCell)+1,iCell) = 0.0
-           do k=maxLevelCell(iCell),2,-1
-              wTop(k,iCell) = wTop(k+1,iCell) &amp;
-                 - div_u(k,iCell)/areaCell(iCell)*h(k,iCell)
-           end do
-        end do
-        deallocate(div_u)
-
-      endif
-
-   end subroutine compute_solve_diagnostics
-
-   subroutine compute_vertical_mix_coefficients(s, d, grid)
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   ! Compute diagnostic fields used in the tendency computations
-   !
-   ! Input: grid - grid metadata
-   !
-   ! Output: s - computed diagnostics
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-      implicit none
-
-      type (state_type), intent(inout) :: s
-      type (diagnostics_type), intent(inout) :: d
-      type (mesh_type), intent(in) :: grid
-
-      type (dm_info) :: dminfo
-
-      integer :: iEdge, iCell, iVertex, k, cell1, cell2, i, j
-      integer :: nCells, nEdges, nVertices, nVertLevels
-
-      real (kind=RKIND), dimension(:,:), allocatable:: &amp;
-        drhoTopOfCell, drhoTopOfEdge, &amp;
-        du2TopOfCell, du2TopOfEdge
-      real (kind=RKIND) :: coef
-      real (kind=RKIND), dimension(:,:), pointer :: &amp;
-        vertViscTopOfEdge, vertDiffTopOfCell, &amp;
-        RiTopOfEdge, RiTopOfCell, rhoDisplaced, rho, &amp;
-        kiteAreasOnVertex, h_edge, h, u
-
-      real (kind=RKIND), dimension(:), pointer :: &amp;
-        h_s, fVertex, fEdge, dvEdge, dcEdge, areaCell, areaTriangle, &amp;
-        hZLevel, zTopZLevel  
-      character :: c1*6
-
-      integer, dimension(:), pointer :: nEdgesOnCell, nEdgesOnEdge, &amp;
-        maxLevelCell, maxLevelEdgeTop, maxLevelEdgeBot, &amp;
-        maxLevelVertexBot,  maxLevelVertexTop
-      integer, dimension(:,:), pointer :: &amp;
-        cellsOnEdge
-      real (kind=RKIND) :: d2fdx2_cell1, d2fdx2_cell2
-      real (kind=RKIND), dimension(:,:,:), pointer :: deriv_two
-      real (kind=RKIND) :: coef_3rd_order
-      real (kind=RKIND) :: r, h1, h2
-
-      rho =&gt; s % rho % array
-      rhoDisplaced =&gt; s % rhoDisplaced % array
-      u           =&gt; s % u % array
-      h           =&gt; s % h % array
-      h_edge      =&gt; s % h_edge % array
-
-      vertViscTopOfEdge =&gt; d % vertViscTopOfEdge % array
-      vertDiffTopOfCell =&gt; d % vertDiffTopOfCell % array
-      RiTopOfEdge =&gt; d % RiTopOfEdge % array
-      RiTopOfCell =&gt; d % RiTopOfCell % array
-
-      zTopZLevel        =&gt; grid % zTopZLevel % array
-      maxLevelCell      =&gt; grid % maxLevelCell % array
-      maxLevelEdgeTop   =&gt; grid % maxLevelEdgeTop % array
-      maxLevelEdgeBot   =&gt; grid % maxLevelEdgeBot % array
-      cellsOnEdge       =&gt; grid % cellsOnEdge % array
-      dcEdge            =&gt; grid % dcEdge % array
-      dvEdge            =&gt; grid % dvEdge % array
-      areaCell          =&gt; grid % areaCell % array
-
-      nCells      = grid % nCells
-      nEdges      = grid % nEdges
-      nVertices   = grid % nVertices
-      nVertLevels = grid % nVertLevels
-
-   !
-   !  Compute Richardson Number
-   !
-   if (config_vert_visc_type.eq.'rich'.or. &amp;
-       config_vert_diff_type.eq.'rich') then
-      allocate( &amp;
-         drhoTopOfCell(nVertLevels+1,nCells+1), drhoTopOfEdge(nVertLevels+1,nEdges+1), &amp;
-         du2TopOfCell(nVertLevels+1,nCells+1), du2TopOfEdge(nVertLevels+1,nEdges+1))
-
-      ! compute density of parcel displaced to next deeper z-level,
-      ! in state % rhoDisplaced
-!maltrud make sure rho is current--check this for redundancy
-      call equation_of_state(s, grid, 0, 'relative')
-      call equation_of_state(s, grid, 1, 'relative')
-
-      ! drhoTopOfCell(k) = $\rho^*_{k-1}-\rho^*_k$
-      drhoTopOfCell = 0.0
-      do iCell=1,nCells
-         do k=2,maxLevelCell(iCell)
-            drhoTopOfCell(k,iCell) = rho(k-1,iCell) - rhoDisplaced(k-1,iCell)
-          end do
-      end do
-
-      ! interpolate drhoTopOfCell to drhoTopOfEdge
-      do iEdge=1,nEdges
-         cell1 = cellsOnEdge(1,iEdge)
-         cell2 = cellsOnEdge(2,iEdge)
-         do k=2,maxLevelEdgeTop(iEdge)
-            drhoTopOfEdge(k,iEdge) = &amp;
-               (drhoTopOfCell(k,cell1) + &amp;
-                drhoTopOfCell(k,cell2))/2  
-         end do
-       end do
-
-      ! du2TopOfEdge(k) = $u_{k-1}-u_k$
-      du2TopOfEdge=0.0
-      do iEdge=1,nEdges
-         do k=2,maxLevelEdgeTop(iEdge)
-            du2TopOfEdge(k,iEdge) = (u(k-1,iEdge) - u(k,iEdge))**2
-         end do
-      end do
-
-      ! interpolate du2TopOfEdge to du2TopOfCell
-      du2TopOfCell(:,:) = 0.0
-      do iEdge=1,nEdges
-         cell1 = cellsOnEdge(1,iEdge)
-         cell2 = cellsOnEdge(2,iEdge)
-         do k=2,maxLevelEdgeBot(iEdge)
-            du2TopOfCell(k,cell1) = du2TopOfCell(k,cell1) &amp;
-               + 0.5 * dcEdge(iEdge) * dvEdge(iEdge) * du2TopOfEdge(k,iEdge)
-            du2TopOfCell(k,cell2) = du2TopOfCell(k,cell2) &amp;
-               + 0.5 * dcEdge(iEdge) * dvEdge(iEdge) * du2TopOfEdge(k,iEdge)
-         end do
-      end do
-      do iCell = 1,nCells
-         do k = 2,maxLevelCell(iCell)
-            du2TopOfCell(k,iCell) = du2TopOfCell(k,iCell) / areaCell(iCell)
-         end do
-      end do
-
-      ! compute RiTopOfEdge using drhoTopOfEdge and du2TopOfEdge
-      ! coef = -g/rho_0/2
-      RiTopOfEdge = 0.0
-      coef = -gravity/1000.0/2.0
-      do iEdge = 1,nEdges
-         do k = 2,maxLevelEdgeTop(iEdge)
-            RiTopOfEdge(k,iEdge) = coef*drhoTopOfEdge(k,iEdge) &amp;
-               *(h_edge(k-1,iEdge)+h_edge(k,iEdge)) &amp;
-               / (du2TopOfEdge(k,iEdge) + 1e-20)
-         end do
-      end do
-
-      ! compute RiTopOfCell using drhoTopOfCell and du2TopOfCell
-      ! coef = -g/rho_0/2
-      RiTopOfCell = 0.0
-      coef = -gravity/1000.0/2.0
-      do iCell = 1,nCells
-         do k = 2,maxLevelCell(iCell)
-            RiTopOfCell(k,iCell) = coef*drhoTopOfCell(k,iCell) &amp;
-               *(h(k-1,iCell)+h(k,iCell)) &amp;
-               / (du2TopOfCell(k,iCell) + 1e-20)
-         end do
-      end do
-
-      deallocate(drhoTopOfCell, drhoTopOfEdge, &amp;
-        du2TopOfCell, du2TopOfEdge)
-   endif
-
-   !
-   !  Compute vertical viscosity
-   !
-   if (config_vert_visc_type.eq.'const') then
-
-      vertViscTopOfEdge = config_vert_visc
-
-   elseif (config_vert_visc_type.eq.'tanh') then
-
-      if (config_vert_grid_type.ne.'zlevel') then
-         write(0,*) 'Abort: config_vert_visc_type.eq.tanh may only', &amp;
-            ' use config_vert_grid_type of zlevel at this time'
-         call dmpar_abort(dminfo)
-      endif
-  
-      do k=1,nVertLevels+1
-          vertViscTopOfEdge(k,:) = -(config_max_visc_tanh-config_min_visc_tanh)/2.0 &amp;
-            *tanh(-(zTopZLevel(k)-config_ZMid_tanh) &amp;
-                  /config_zWidth_tanh) &amp;
-            + (config_max_visc_tanh+config_min_visc_tanh)/2
-      end do
-
-   elseif (config_vert_visc_type.eq.'rich') then
-
-      vertViscTopOfEdge = 0.0
-      do iEdge = 1,nEdges
-         do k = 2,maxLevelEdgeTop(iEdge)
-            ! mrp 110324 efficiency note: this if is inside iEdge and k loops.
-            ! Perhaps there is a more efficient way to do this.
-            if (RiTopOfEdge(k,iEdge)&gt;0.0) then
-               vertViscTopOfEdge(k,iEdge) = config_bkrd_vert_visc &amp;
-                  + config_rich_mix / (1.0 + 5.0*RiTopOfEdge(k,iEdge))**2
-            ! maltrud do limiting of coefficient--should not be necessary
-            ! also probably better logic could be found
-               if (vertViscTopOfEdge(k,iEdge) &gt; config_convective_visc) then
-                   if( config_implicit_vertical_mix) then
-                      vertViscTopOfEdge(k,iEdge) = config_convective_visc
-                   else
-                      vertViscTopOfEdge(k,iEdge) = &amp;
-                      ((h_edge(k-1,iEdge)+h_edge(k,iEdge))/2.0)**2/config_dt/4.0
-                   end if
-               end if
-            else
-               ! mrp 110324 efficiency note: this if is inside iCell and k loops.
-               if (config_implicit_vertical_mix) then
-                  ! for Ri&lt;0 and implicit mix, use convective diffusion
-                  vertViscTopOfEdge(k,iEdge) = config_convective_visc
-               else
-                  ! for Ri&lt;0 and explicit vertical mix, 
-                  ! use maximum diffusion allowed by CFL criterion
-                  ! mrp 110324 efficiency note: for z-level, could use fixed
-                  ! grid array hMeanTopZLevel and compute maxdiff on startup.
-                  vertViscTopOfEdge(k,iEdge) = &amp;
-                      ((h_edge(k-1,iEdge)+h_edge(k,iEdge))/2.0)**2/config_dt/4.0
-               end if
-            end if
-         end do
-      end do
-
-   else
-
-      write(0,*) 'Abort: unrecognized config_vert_visc_type'
-      call dmpar_abort(dminfo)
-
-   endif
-
-   !
-   !  Compute vertical tracer diffusion
-   !
-   if (config_vert_diff_type.eq.'const') then
-
-      vertDiffTopOfCell = config_vert_diff
-
-   elseif (config_vert_diff_type.eq.'tanh') then
-
-      if (config_vert_grid_type.ne.'zlevel') then
-         write(0,*) 'Abort: config_vert_diff_type.eq.tanh may only', &amp;
-            ' use config_vert_grid_type of zlevel at this time'
-         call dmpar_abort(dminfo)
-      endif
-
-      do k=1,nVertLevels+1
-         vertDiffTopOfCell(k,:) = -(config_max_diff_tanh-config_min_diff_tanh)/2.0 &amp;
-            *tanh(-(zTopZLevel(k)-config_ZMid_tanh) &amp;
-                  /config_zWidth_tanh) &amp;
-            + (config_max_diff_tanh+config_min_diff_tanh)/2
-      end do
-
-   elseif (config_vert_diff_type.eq.'rich') then
-
-      vertDiffTopOfCell = 0.0
-      coef = -gravity/1000.0/2.0
-      do iCell = 1,nCells
-         do k = 2,maxLevelCell(iCell)
-            ! mrp 110324 efficiency note: this if is inside iCell and k loops.
-            ! Perhaps there is a more efficient way to do this.
-            if (RiTopOfCell(k,iCell)&gt;0.0) then
-               vertDiffTopOfCell(k,iCell) = config_bkrd_vert_diff &amp;
-                  + (config_bkrd_vert_visc &amp; 
-                     + config_rich_mix / (1.0 + 5.0*RiTopOfCell(k,iCell))**2) &amp;
-                  / (1.0 + 5.0*RiTopOfCell(k,iCell))
-            ! maltrud do limiting of coefficient--should not be necessary
-            ! also probably better logic could be found
-               if (vertDiffTopOfCell(k,iCell) &gt; config_convective_diff) then
-                  if (config_implicit_vertical_mix) then
-                     vertDiffTopOfCell(k,iCell) = config_convective_diff
-                  else
-                     vertDiffTopOfCell(k,iCell) = &amp;
-                        ((h(k-1,iCell)+h(k,iCell))/2.0)**2/config_dt/4.0
-                  end if
-               end if
-             else
-               ! mrp 110324 efficiency note: this if is inside iCell and k loops.
-               if (config_implicit_vertical_mix) then
-                  ! for Ri&lt;0 and implicit mix, use convective diffusion
-                  vertDiffTopOfCell(k,iCell) = config_convective_diff
-               else
-                  ! for Ri&lt;0 and explicit vertical mix, 
-                  ! use maximum diffusion allowed by CFL criterion
-                  ! mrp 110324 efficiency note: for z-level, could use fixed
-                  ! grid array hMeanTopZLevel and compute maxdiff on startup.
-                  vertDiffTopOfCell(k,iCell) = &amp;
-                     ((h(k-1,iCell)+h(k,iCell))/2.0)**2/config_dt/4.0
-               end if
-            end if
-         end do
-      end do
-
-   else
-
-      write(0,*) 'Abort: unrecognized config_vert_diff_type'
-      call dmpar_abort(dminfo)
-
-   endif
-
-   end subroutine compute_vertical_mix_coefficients
-
-
-   subroutine enforce_boundaryEdge(tend, grid)
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   ! Enforce any boundary conditions on the normal velocity at each edge
-   !
-   ! Input: grid - grid metadata
-   !
-   ! Output: tend_u set to zero at boundaryEdge == 1 locations
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-
-      implicit none
-
-      type (tend_type), intent(inout) :: tend
-      type (mesh_type), intent(in) :: grid
-
-      integer, dimension(:,:), pointer :: boundaryEdge
-      real (kind=RKIND), dimension(:,:), pointer :: tend_u
-      integer :: nCells, nEdges, nVertices, nVertLevels
-      integer :: iEdge, k
-
-      nCells      = grid % nCells
-      nEdges      = grid % nEdges
-      nVertices   = grid % nVertices
-      nVertLevels = grid % nVertLevels
-
-      boundaryEdge         =&gt; grid % boundaryEdge % array
-      tend_u      =&gt; tend % u % array
-
-      if(maxval(boundaryEdge).le.0) return
-
-      do iEdge = 1,nEdges
-        do k = 1,nVertLevels
-
-          if(boundaryEdge(k,iEdge).eq.1) then
-             tend_u(k,iEdge) = 0.0
-          endif
-
-        enddo
-       enddo
-
-   end subroutine enforce_boundaryEdge
-
-
-   subroutine equation_of_state(s, grid, k_displaced, displacement_type)
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   !  This module contains routines necessary for computing the density
-   !  from model temperature and salinity using an equation of state.
-   !
-   ! Input: grid - grid metadata
-   !        s - state: tracers
-   !        k_displaced 
-   !  If k_displaced&lt;=0, state % rho is returned with no displaced
-   !  If k_displaced&gt;0,the state % rhoDisplaced is returned, and is for
-   !  a parcel adiabatically displaced from its original level to level 
-   !  k_displaced.  This does not effect the linear EOS.
-   !
-   ! Output: s - state: computed density
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-      implicit none
-
-      type (state_type), intent(inout) :: s
-      type (mesh_type), intent(in) :: grid
-      integer :: k_displaced
-      character(len=8), intent(in) :: displacement_type
-
-      integer, dimension(:), pointer :: maxLevelCell
-      real (kind=RKIND), dimension(:,:), pointer :: rho
-      real (kind=RKIND), dimension(:,:,:), pointer :: tracers
-      integer :: nCells, iCell, k
-      type (dm_info) :: dminfo
-
-      if (config_eos_type.eq.'linear') then
-
-         rho         =&gt; s % rho % array
-         tracers     =&gt; s % tracers % array
-         maxLevelCell      =&gt; grid % maxLevelCell % array
-         nCells      = grid % nCells
-
-         do iCell=1,nCells
-            do k=1,maxLevelCell(iCell)
-               ! Linear equation of state
-               rho(k,iCell) = 1000.0*(  1.0 &amp;
-                  - 2.5e-4*tracers(s % index_temperature,k,iCell) &amp;
-                  + 7.6e-4*tracers(s % index_salinity,k,iCell))
-            end do
-         end do
-
-      elseif (config_eos_type.eq.'jm') then
-
-         call equation_of_state_jm(s, grid, k_displaced, displacement_type)
-
-      else 
-         print *, ' Incorrect choice of config_eos_type:',&amp;
-            config_eos_type
-         call dmpar_abort(dminfo)
-      endif
-
-   end subroutine equation_of_state
-
-
-   subroutine equation_of_state_jm(s, grid, k_displaced, displacement_type)
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   !  This module contains routines necessary for computing the density
-   !  from model temperature and salinity using an equation of state.
-   !
-   !  The UNESCO equation of state computed using the
-   !  potential-temperature-based bulk modulus from Jackett and
-   !  McDougall, JTECH, Vol.12, pp 381-389, April, 1995.
-   !
-   ! Input: grid - grid metadata
-   !        s - state: tracers
-   !        k_displaced 
-
-   !  If k_displaced&lt;=0, density is returned with no displaced
-   !  If k_displaced&gt;0,the density returned is that for a parcel
-   !  adiabatically displaced from its original level to level 
-   !  k_displaced.
-
-   !
-   ! Output: s - state: computed density
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-      implicit none
-
-      type (state_type), intent(in) :: s
-      type (mesh_type), intent(in) :: grid
-      integer :: k_displaced
-      character(len=8), intent(in) :: displacement_type
-
-      type (dm_info) :: dminfo
-      integer :: iEdge, iCell, iVertex, k
-
-      integer :: nCells, nEdges, nVertices, nVertLevels
-
-
-      real (kind=RKIND), dimension(:), pointer :: &amp;
-        zMidZLevel, pRefEOS
-      real (kind=RKIND), dimension(:,:), pointer :: &amp;
-        rhoPointer
-      real (kind=RKIND), dimension(:,:,:), pointer :: tracers
-
-      integer, dimension(:), pointer :: maxLevelCell
-
-   real (kind=RKIND) :: &amp;
-      TQ,SQ,             &amp;! adjusted T,S
-      BULK_MOD,          &amp;! Bulk modulus
-      RHO_S,             &amp;! density at the surface
-      DRDT0,             &amp;! d(density)/d(temperature), for surface
-      DRDS0,             &amp;! d(density)/d(salinity   ), for surface
-      DKDT,              &amp;! d(bulk modulus)/d(pot. temp.)
-      DKDS,              &amp;! d(bulk modulus)/d(salinity  )
-      SQR,DENOMK,        &amp;! work arrays
-      WORK1, WORK2, WORK3, WORK4, T2, depth
-
-   real (kind=RKIND) :: &amp; 
-      tmin, tmax,        &amp;! valid temperature range for level k
-      smin, smax          ! valid salinity    range for level k
-
-   real (kind=RKIND), dimension(:), allocatable :: &amp;
-      p, p2 ! temporary pressure scalars
-
-!-----------------------------------------------------------------------
-!
-!  UNESCO EOS constants and JMcD bulk modulus constants
-!
-!-----------------------------------------------------------------------
-
-   !*** for density of fresh water (standard UNESCO)
-
-   real (kind=RKIND), parameter ::              &amp;
-      unt0 =   999.842594,           &amp;
-      unt1 =  6.793952e-2,           &amp;
-      unt2 = -9.095290e-3,           &amp;
-      unt3 =  1.001685e-4,           &amp;
-      unt4 = -1.120083e-6,           &amp;
-      unt5 =  6.536332e-9
-
-   !*** for dependence of surface density on salinity (UNESCO)
-
-   real (kind=RKIND), parameter ::              &amp;
-      uns1t0 =  0.824493 ,           &amp;
-      uns1t1 = -4.0899e-3,           &amp;
-      uns1t2 =  7.6438e-5,           &amp;
-      uns1t3 = -8.2467e-7,           &amp;
-      uns1t4 =  5.3875e-9,           &amp;
-      unsqt0 = -5.72466e-3,          &amp;
-      unsqt1 =  1.0227e-4,           &amp;
-      unsqt2 = -1.6546e-6,           &amp;
-      uns2t0 =  4.8314e-4
-
-   !*** from Table A1 of Jackett and McDougall
-
-   real (kind=RKIND), parameter ::              &amp;
-      bup0s0t0 =  1.965933e+4,       &amp;
-      bup0s0t1 =  1.444304e+2,       &amp;
-      bup0s0t2 = -1.706103   ,       &amp;
-      bup0s0t3 =  9.648704e-3,       &amp;
-      bup0s0t4 = -4.190253e-5
-
-   real (kind=RKIND), parameter ::              &amp;
-      bup0s1t0 =  5.284855e+1,       &amp;
-      bup0s1t1 = -3.101089e-1,       &amp;
-      bup0s1t2 =  6.283263e-3,       &amp;
-      bup0s1t3 = -5.084188e-5
-
-   real (kind=RKIND), parameter ::              &amp;
-      bup0sqt0 =  3.886640e-1,       &amp;
-      bup0sqt1 =  9.085835e-3,       &amp;
-      bup0sqt2 = -4.619924e-4
-
-   real (kind=RKIND), parameter ::              &amp;
-      bup1s0t0 =  3.186519   ,       &amp;
-      bup1s0t1 =  2.212276e-2,       &amp;
-      bup1s0t2 = -2.984642e-4,       &amp;
-      bup1s0t3 =  1.956415e-6 
-
-   real (kind=RKIND), parameter ::              &amp;
-      bup1s1t0 =  6.704388e-3,       &amp;
-      bup1s1t1 = -1.847318e-4,       &amp;
-      bup1s1t2 =  2.059331e-7,       &amp;
-      bup1sqt0 =  1.480266e-4 
-
-   real (kind=RKIND), parameter ::              &amp;
-      bup2s0t0 =  2.102898e-4,       &amp;
-      bup2s0t1 = -1.202016e-5,       &amp;
-      bup2s0t2 =  1.394680e-7,       &amp;
-      bup2s1t0 = -2.040237e-6,       &amp;
-      bup2s1t1 =  6.128773e-8,       &amp;
-      bup2s1t2 =  6.207323e-10
-
-   integer :: k_test, k_ref
-
-      tracers     =&gt; s % tracers % array
-
-      nCells      = grid % nCells
-      maxLevelCell      =&gt; grid % maxLevelCell % array
-      nVertLevels = grid % nVertLevels
-      zMidZLevel        =&gt; grid % zMidZLevel % array
-
-
-!  Jackett and McDougall
-      tmin = -2.0  ! valid pot. temp. range
-      tmax = 40.0 
-      smin =  0.0  ! valid salinity, in psu   
-      smax = 42.0 
-
-      ! This could be put in a startup routine.
-      ! Note I am using zMidZlevel, so pressure on top level does
-      ! not include SSH contribution.  I am not sure if that matters.
-
-!  This function computes pressure in bars from depth in meters
-!  using a mean density derived from depth-dependent global 
-!  average temperatures and salinities from Levitus 1994, and 
-!  integrating using hydrostatic balance.
-
-      allocate(pRefEOS(nVertLevels),p(nVertLevels),p2(nVertLevels))
-      do k = 1,nVertLevels
-        depth = -zMidZLevel(k)
-        pRefEOS(k) = 0.059808*(exp(-0.025*depth) - 1.0) &amp;
-            + 0.100766*depth + 2.28405e-7*depth**2
-      enddo
-
-   !  If k_displaced=0, in-situ density is returned (no displacement)
-   !  If k_displaced/=0, potential density is returned
-
-   !  if displacement_type = 'relative', potential density is calculated
-   !     referenced to level k + k_displaced
-   !  if displacement_type = 'absolute', potential density is calculated
-   !     referenced to level k_displaced for all k
-   !  NOTE: k_displaced = 0 or &gt; nVertLevels is incompatible with 'absolute'
-   !     so abort if necessary
-
-   if (displacement_type == 'absolute' .and.   &amp;
-       (k_displaced &lt;= 0 .or. k_displaced &gt; nVertLevels) ) then
-      write(0,*) 'Abort: In equation_of_state_jm', &amp;
-         ' k_displaced must be between 1 and nVertLevels for displacement_type = absolute'
-      call dmpar_abort(dminfo)
-   endif
-
-   if (k_displaced == 0) then
-      rhoPointer =&gt; s % rho % array
-      do k=1,nVertLevels
-         p(k)   = pRefEOS(k)
-         p2(k)  = p(k)*p(k)
-      enddo
-   else ! k_displaced /= 0
-      rhoPointer =&gt; s % rhoDisplaced % array
-      do k=1,nVertLevels
-         if (displacement_type == 'relative') then
-            k_test = min(k + k_displaced, nVertLevels)
-            k_ref  = max(k_test, 1)
-         else
-            k_test = min(k_displaced, nVertLevels)
-            k_ref  = max(k_test, 1)
-         endif
-         p(k)   = pRefEOS(k_ref)
-         p2(k)  = p(k)*p(k)
-      enddo
-   endif
-
-  do iCell=1,nCells
-    do k=1,maxLevelCell(iCell)
-
-      SQ  = max(min(tracers(s%index_salinity,k,iCell),smax),smin)
-      TQ  = max(min(tracers(s%index_temperature,k,iCell),tmax),tmin)
-
-      SQR = sqrt(SQ)
-      T2  = TQ*TQ
-
-      !***
-      !*** first calculate surface (p=0) values from UNESCO eqns.
-      !***
-
-      WORK1 = uns1t0 + uns1t1*TQ + &amp; 
-             (uns1t2 + uns1t3*TQ + uns1t4*T2)*T2
-      WORK2 = SQR*(unsqt0 + unsqt1*TQ + unsqt2*T2)
-
-      RHO_S = unt1*TQ + (unt2 + unt3*TQ + (unt4 + unt5*TQ)*T2)*T2 &amp;
-                      + (uns2t0*SQ + WORK1 + WORK2)*SQ
-
-      !***
-      !*** now calculate bulk modulus at pressure p from 
-      !*** Jackett and McDougall formula
-      !***
-
-      WORK3 = bup0s1t0 + bup0s1t1*TQ +                    &amp;
-             (bup0s1t2 + bup0s1t3*TQ)*T2 +                &amp;
-              p(k) *(bup1s1t0 + bup1s1t1*TQ + bup1s1t2*T2) + &amp;
-              p2(k)*(bup2s1t0 + bup2s1t1*TQ + bup2s1t2*T2)
-      WORK4 = SQR*(bup0sqt0 + bup0sqt1*TQ + bup0sqt2*T2 + &amp;
-                   bup1sqt0*p(k))
-
-      BULK_MOD  = bup0s0t0 + bup0s0t1*TQ +                    &amp;
-                  (bup0s0t2 + bup0s0t3*TQ + bup0s0t4*T2)*T2 + &amp;
-                  p(k) *(bup1s0t0 + bup1s0t1*TQ +                &amp;
-                     (bup1s0t2 + bup1s0t3*TQ)*T2) +           &amp;
-                  p2(k)*(bup2s0t0 + bup2s0t1*TQ + bup2s0t2*T2) + &amp;
-                  SQ*(WORK3 + WORK4)
-
-      DENOMK = 1.0/(BULK_MOD - p(k))
-
-      rhoPointer(k,iCell) = (unt0 + RHO_S)*BULK_MOD*DENOMK
-
-    end do
-  end do
-
-   deallocate(pRefEOS,p,p2)
-
-   end subroutine equation_of_state_jm
-
-
-subroutine tridiagonal_solve(a,b,c,r,x,n)
-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-! Solve the matrix equation Ax=r for x, where A is tridiagonal.
-! A is an nxn matrix, with:
-!   a sub-diagonal, filled from 1:n-1 (a(1) appears on row 2)
-!   b diagonal, filled from 1:n
-!   c sup-diagonal, filled from 1:n-1  (c(1) apears on row 1)
-!
-! Input: a,b,c,r,n
-!
-! Output: x
-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

-   implicit none
-
-   integer,intent(in) :: n
-   real (KIND=RKIND), dimension(n), intent(in) :: a,b,c,r
-   real (KIND=RKIND), dimension(n), intent(out) :: x
-   real (KIND=RKIND), dimension(n) :: bTemp,rTemp
-   real (KIND=RKIND) :: m
-   integer i

-   ! Use work variables for b and r
-   bTemp(1) = b(1)
-   rTemp(1) = r(1)

-   ! First pass: set the coefficients
-   do i = 2,n
-      m = a(i-1)/bTemp(i-1)
-      bTemp(i) = b(i) - m*c(i-1)
-      rTemp(i) = r(i) - m*rTemp(i-1)
-   end do 

-   x(n) = rTemp(n)/bTemp(n)
-   ! Second pass: back-substition
-   do i = n-1, 1, -1
-      x(i) = (rTemp(i) - c(i)*x(i+1))/bTemp(i)
-   end do

-end subroutine tridiagonal_solve
-
-
-subroutine tridiagonal_solve_mult(a,b,c,r,x,n,nDim,nSystems)
-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-! Solve the matrix equation Ax=r for x, where A is tridiagonal.
-! A is an nxn matrix, with:
-!   a sub-diagonal, filled from 1:n-1 (a(1) appears on row 2)
-!   b diagonal, filled from 1:n
-!   c sup-diagonal, filled from 1:n-1  (c(1) apears on row 1)
-!
-! Input: a,b,c,r,n
-!
-! Output: x
-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

-   implicit none
-
-   integer,intent(in) :: n, nDim, nSystems
-   real (KIND=RKIND), dimension(n), intent(in) :: a,b,c
-   real (KIND=RKIND), dimension(nSystems,nDim), intent(in) :: r
-   real (KIND=RKIND), dimension(nSystems,nDim), intent(out) :: x
-   real (KIND=RKIND), dimension(n) :: bTemp
-   real (KIND=RKIND), dimension(nSystems,n) :: rTemp
-   real (KIND=RKIND) :: m
-   integer i,j

-   ! Use work variables for b and r
-   bTemp(1) = b(1)
-   do j = 1,nSystems
-      rTemp(j,1) = r(j,1)
-   end do

-   ! First pass: set the coefficients
-   do i = 2,n
-      m = a(i-1)/bTemp(i-1)
-      bTemp(i) = b(i) - m*c(i-1)
-      do j = 1,nSystems
-         rTemp(j,i) = r(j,i) - m*rTemp(j,i-1)
-      end do 
-   end do 

-   do j = 1,nSystems
-      x(j,n) = rTemp(j,n)/bTemp(n)
-   end do
-   ! Second pass: back-substition
-   do i = n-1, 1, -1
-      do j = 1,nSystems
-         x(j,i) = (rTemp(j,i) - c(i)*x(j,i+1))/bTemp(i)
-      end do
-   end do

-end subroutine tridiagonal_solve_mult
-
-
-end module time_integration

</font>
</pre>