<p><b>dwj07@fsu.edu</b> 2011-08-29 16:03:13 -0600 (Mon, 29 Aug 2011)</p><p><br>
        Separating out thickness tendency and velocity forcing tendencies into modules, and applying array masking.<br>
<br>
        changing a lot of divisions from module_time_integration to multiplications, to help performance.<br>
</p><hr noshade><pre><font color="gray">Modified: branches/ocean_projects/performance/mpas/src/core_ocean/Makefile
===================================================================
--- branches/ocean_projects/performance/mpas/src/core_ocean/Makefile        2011-08-29 16:48:20 UTC (rev 958)
+++ branches/ocean_projects/performance/mpas/src/core_ocean/Makefile        2011-08-29 22:03:13 UTC (rev 959)
@@ -13,6 +13,8 @@
        module_OcnVmixTracerConst.o \
        module_OcnVmixTracerTanh.o \
        module_OcnCoriolis.o \
+           module_OcnThickness.o \
+           module_OcnVelocityForcing.o \
        module_time_integration.o \
        module_global_diagnostics.o
 
@@ -23,6 +25,10 @@
 
 module_test_cases.o:
 
+module_OcnVelocityForcing.o:
+
+module_OcnThickness.o:
+
 module_advection.o:
 
 module_OcnCoriolis.o:
@@ -49,7 +55,7 @@
 
 module_global_diagnostics.o: 
 
-module_mpas_core.o: module_advection.o module_global_diagnostics.o module_test_cases.o module_OcnCoriolis.o module_OcnVmixTracer.o module_OcnVmixTracerConst.o module_OcnVmixTracerTanh.o module_OcnHmixTracer.o module_OcnHmixTracerDel2.o module_OcnHmixTracerDel4.o module_OcnHmixVel.o module_OcnHmixVelDel2.o module_OcnHmixVelDel4.o module_time_integration.o
+module_mpas_core.o: module_advection.o module_global_diagnostics.o module_test_cases.o module_OcnVelocityForcing.o module_OcnThickness.o module_OcnCoriolis.o module_OcnVmixTracer.o module_OcnVmixTracerConst.o module_OcnVmixTracerTanh.o module_OcnHmixTracer.o module_OcnHmixTracerDel2.o module_OcnHmixTracerDel4.o module_OcnHmixVel.o module_OcnHmixVelDel2.o module_OcnHmixVelDel4.o module_time_integration.o
 
 clean:
         $(RM) *.o *.mod *.f90 libdycore.a

Added: branches/ocean_projects/performance/mpas/src/core_ocean/module_OcnThickness.F
===================================================================
--- branches/ocean_projects/performance/mpas/src/core_ocean/module_OcnThickness.F                                (rev 0)
+++ branches/ocean_projects/performance/mpas/src/core_ocean/module_OcnThickness.F        2011-08-29 22:03:13 UTC (rev 959)
@@ -0,0 +1,168 @@
+!|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+!
+!  OcnThickness
+!
+!&gt; \brief MPAS ocean thickness tendency
+!&gt; \author Doug Jacobsen
+!&gt; \date   29 July 2011
+!&gt; \version SVN:$Id:$
+!&gt; \details
+!&gt;  This module contains the main driver routine for computing 
+!&gt;  the thickness tendencices
+!
+!-----------------------------------------------------------------------
+
+module OcnThickness
+
+   use grid_types
+   use configure
+
+   implicit none
+   private
+   save
+
+   !--------------------------------------------------------------------
+   !
+   ! Public parameters
+   !
+   !--------------------------------------------------------------------
+
+   !--------------------------------------------------------------------
+   !
+   ! Public member functions
+   !
+   !--------------------------------------------------------------------
+
+   public :: OcnThicknessTend
+
+   !--------------------------------------------------------------------
+   !
+   ! Private module variables
+   !
+   !--------------------------------------------------------------------
+
+
+!***********************************************************************
+
+contains
+
+!***********************************************************************
+!
+!  routine OcnThicknessTend
+!
+!&gt; \brief   Computes tendency term for horizontal tracer mixing
+!&gt; \author  Doug Jacobsen
+!&gt; \date    26 July 2011
+!&gt; \version SVN:$Id$
+!&gt; \details 
+!&gt;  This routine computes the thickness tendency based on current state.
+!
+!-----------------------------------------------------------------------
+
+   subroutine OcnThicknessTend(tend, hEdge, u, wTop, grid)
+
+      !-----------------------------------------------------------------
+      !
+      ! input variables
+      !
+      !-----------------------------------------------------------------
+
+      real (kind=RKIND), dimension(:,:), intent(in) :: &amp;
+         u, wTop, hEdge
+
+
+      type (mesh_type), intent(in) :: &amp;
+         grid       !&lt; Input: grid information
+
+      !-----------------------------------------------------------------
+      !
+      ! input/output variables
+      !
+      !-----------------------------------------------------------------
+
+      real (kind=RKIND), dimension(:,:), intent(inout) :: &amp;
+         tend                          !&lt; Input/Output: velocity tendency
+
+      !-----------------------------------------------------------------
+      !
+      ! output variables
+      !
+      !-----------------------------------------------------------------
+
+      !-----------------------------------------------------------------
+      !
+      ! local variables
+      !
+      !-----------------------------------------------------------------
+
+      integer :: iEdge, nEdges, k, cell1, cell2, iCell, nCells, nVertLevels
+      real (kind=RKIND) :: invAreaCell1, invAreaCell2, flux
+
+      integer, dimension(:,:), pointer :: cellsOnEdge
+      integer, dimension(:), pointer :: maxLevelEdgeTop
+
+      real (kind=RKIND), dimension(:), pointer :: dvEdge, areaCell
+
+      cellsOnEdge =&gt; grid % cellsOnEdge % array
+      areaCell =&gt; grid % areaCell % array
+      dvEdge =&gt; grid % dvEdge % array
+      maxLevelEdgeTop =&gt; grid % maxLevelEdgeTop % array
+
+      nEdges = grid % nEdges
+      nCells = grid % nCells
+      nVertLevels = grid % nVertLevels
+
+      !
+      ! height tendency: horizontal advection term -</font>
<font color="gray">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)
+
+            invAreaCell1 = 1.0/areaCell(cell1)
+            invAreaCell2 = 1.0/areaCell(cell2)
+            do k=1,nVertLevels
+               flux = u(k,iEdge) * dvEdge(iEdge) * hEdge(k,iEdge)
+               tend(k,cell1) = tend(k,cell1) - flux * invAreaCell1
+               tend(k,cell2) = tend(k,cell2) + flux * invAreaCell2
+            end do
+         end do
+
+      elseif (config_vert_grid_type.eq.'zlevel') then
+
+         do iEdge=1,nEdges
+            cell1 = cellsOnEdge(1,iEdge)
+            cell2 = cellsOnEdge(2,iEdge)
+            invAreaCell1 = 1.0/areaCell(cell1)
+            invAreaCell2 = 1.0/areaCell(cell2)
+            do k=1,min(1,maxLevelEdgeTop(iEdge))
+               flux = u(k,iEdge) * dvEdge(iEdge) * hEdge(k,iEdge)
+               tend(k,cell1) = tend(k,cell1) - flux * invAreaCell1
+               tend(k,cell2) = tend(k,cell2) + flux * invAreaCell2
+            end do
+         end do
+         ! height tendency: vertical advection term -d/dz(hw)
+         !
+         ! Vertical advection computed for top layer of a z grid only.
+         do iCell=1,nCells
+            tend(1,iCell) = tend(1,iCell) + wTop(2,iCell)
+         end do
+      endif ! coordinate type
+
+
+   !--------------------------------------------------------------------
+
+   end subroutine OcnThicknessTend
+
+!***********************************************************************
+
+end module OcnThickness
+
+!|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

Added: branches/ocean_projects/performance/mpas/src/core_ocean/module_OcnVelocityForcing.F
===================================================================
--- branches/ocean_projects/performance/mpas/src/core_ocean/module_OcnVelocityForcing.F                                (rev 0)
+++ branches/ocean_projects/performance/mpas/src/core_ocean/module_OcnVelocityForcing.F        2011-08-29 22:03:13 UTC (rev 959)
@@ -0,0 +1,152 @@
+!|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+!
+!  OcnVelocityForcing
+!
+!&gt; \brief MPAS ocean velocity forcing
+!&gt; \author Doug Jacobsen
+!&gt; \date   29 July 2011
+!&gt; \version SVN:$Id:$
+!&gt; \details
+!&gt;  This module contains the routine for computing 
+!&gt;  velocity tendencies from forcings. Including bottom drag and
+!&gt;  wind stress.
+!&gt;
+!
+!-----------------------------------------------------------------------
+
+module OcnVelocityForcing
+
+   use grid_types
+   use configure
+
+   implicit none
+   private
+   save
+
+   !--------------------------------------------------------------------
+   !
+   ! Public parameters
+   !
+   !--------------------------------------------------------------------
+
+   !--------------------------------------------------------------------
+   !
+   ! Public member functions
+   !
+   !--------------------------------------------------------------------
+
+   public :: OcnVelocityForcingTend
+
+   !--------------------------------------------------------------------
+   !
+   ! Private module variables
+   !
+   !--------------------------------------------------------------------
+
+
+!***********************************************************************
+
+contains
+
+!***********************************************************************
+!
+!  routine OcnVelocityForcingTend
+!
+!&gt; \brief   Computes tendency term velocity based on forcings
+!&gt; \author  Doug Jacobsen
+!&gt; \date    26 July 2011
+!&gt; \version SVN:$Id$
+!&gt; \details 
+!&gt;  This routine computes the tendency for velocity
+!&gt;  based on current state, and forcings that are based on wind stress
+!&gt;  (from an initial condition), or bottom drag.
+!
+!-----------------------------------------------------------------------
+
+   subroutine OcnVelocityForcingTend(tend, keEdge, hEdge, u, grid)
+
+      !-----------------------------------------------------------------
+      !
+      ! input variables
+      !
+      !-----------------------------------------------------------------
+
+      real (kind=RKIND), dimension(:,:), intent(in) :: &amp;
+         hEdge, u, keEdge
+
+      type (mesh_type), intent(in) :: &amp;
+         grid       !&lt; Input: grid information
+
+      !-----------------------------------------------------------------
+      !
+      ! input/output variables
+      !
+      !-----------------------------------------------------------------
+
+      real (kind=RKIND), dimension(:,:), intent(inout) :: &amp;
+         tend                          !&lt; Input/Output: velocity tendency
+
+      !-----------------------------------------------------------------
+      !
+      ! output variables
+      !
+      !-----------------------------------------------------------------
+
+      !-----------------------------------------------------------------
+      !
+      ! local variables
+      !
+      !-----------------------------------------------------------------
+
+      integer :: iEdge, k
+      integer, dimension(:), pointer :: maxLevelEdgeTop
+
+      real (kind=RKIND), dimension(:,:), pointer :: u_src
+
+      real (kind=RKIND), parameter :: rho_ref = 1000.0
+
+      maxLevelEdgeTop =&gt; grid % maxLevelEdgeTop % array
+      u_src =&gt; grid % u_src % array
+
+      !
+      ! 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(1,iEdge) =  tend(1,iEdge) &amp;
+              + u_src(1,iEdge)/rho_ref/hEdge(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.
+
+           tend(k,iEdge) = tend(k,iEdge)  &amp;
+             - 1.0e-3*u(k,iEdge) &amp;
+               *sqrt(2.0*keEdge(k,iEdge))/hEdge(k,iEdge)
+
+        endif
+
+      enddo
+
+   !--------------------------------------------------------------------
+
+   end subroutine OcnVelocityForcingTend
+
+!***********************************************************************
+
+end module OcnVelocityForcing
+
+!|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

Modified: branches/ocean_projects/performance/mpas/src/core_ocean/module_time_integration.F
===================================================================
--- branches/ocean_projects/performance/mpas/src/core_ocean/module_time_integration.F        2011-08-29 16:48:20 UTC (rev 958)
+++ branches/ocean_projects/performance/mpas/src/core_ocean/module_time_integration.F        2011-08-29 22:03:13 UTC (rev 959)
@@ -9,10 +9,12 @@
    use vector_reconstruction
    use spline_interpolation
    use timer
-   use OcnHmixVel
    use OcnHmixTracer
+   use OcnHmixVel
    use OcnVmixTracer
    use OcnCoriolis
+   use OcnThickness
+   use OcnVelocityForcing
 
    contains
 
@@ -299,6 +301,9 @@
       real (kind=RKIND), allocatable, dimension(:,:) :: delsq_u
       real (kind=RKIND), allocatable, dimension(:,:) :: delsq_circulation, delsq_vorticity
 
+      real (kind=RKIND) :: invAreaCell1, invAreaCell2
+      real (kind=RKIND) :: invAreaTri1, invAreaTri2
+      real (kind=RKIND) :: invDCEdge, invDVEdge
 
       real (kind=RKIND), dimension(:,:), pointer :: u_src
       real (kind=RKIND), parameter :: rho_ref = 1000.0
@@ -357,45 +362,9 @@
       !
       tend_h = 0.0
 
-      !
-      ! height tendency: horizontal advection term -</font>
<font color="gray">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.
+      call OcnThicknessTend(tend_h, h_edge, u, wTop, grid)
 
-      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 / areaCell(cell1)
-               tend_h(k,cell2) = tend_h(k,cell2) + flux / areaCell(cell2)
-            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 / areaCell(cell1)
-               tend_h(k,cell2) = tend_h(k,cell2) + flux / areaCell(cell2)
-            end do
-         end do
-         ! height tendency: vertical advection term -d/dz(hw)
-         !
-         ! Vertical advection computed for top layer of a z grid only.
-         do iCell=1,nCells
-            tend_h(1,iCell) = tend_h(1,iCell) + wTop(2,iCell)
-         end do
-      endif ! coordinate type
-
       call timer_stop(&quot;height&quot;)
       call timer_start(&quot;velocity&quot;)
       !
@@ -442,29 +411,35 @@
         do iEdge=1,grid % nEdgesSolve
           cell1 = cellsOnEdge(1,iEdge)
           cell2 = cellsOnEdge(2,iEdge)
+
+          invDCEdge = 1.0 / dcEdge(iEdge)
+
           do k=1,maxLevelEdgeTop(iEdge)
              tend_u(k,iEdge) = tend_u(k,iEdge)     &amp;
-               - (MontPot(k,cell2) - MontPot(k,cell1))/dcEdge(iEdge)
+               - (MontPot(k,cell2) - MontPot(k,cell1))*invDCEdge
            end do
         enddo
       elseif (config_vert_grid_type.eq.'zlevel') then
         do iEdge=1,grid % nEdgesSolve
           cell1 = cellsOnEdge(1,iEdge)
           cell2 = cellsOnEdge(2,iEdge)
+
+          invDCEdge = 1.0 / dcEdge(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)
+                          - pressure(k,cell1) )*invDCEdge
           end do
         enddo
       endif
 
       call timer_stop(&quot;press grad&quot;)
-
       call timer_start(&quot;vel dissipation&quot;)
+
       call OcnHmixVelTend(tend_u, divergence, vorticity, grid)
-      call timer_stop(&quot;vel dissipation&quot;)
 
+      call timer_stop(&quot;vel dissipation&quot;)
       !
       ! velocity tendency: nonlinear Coriolis term and grad of kinetic energy
       !
@@ -474,39 +449,9 @@
 
       call timer_stop(&quot;coriolis&quot;)
       call timer_start(&quot;vel forcing&quot;)
-      !
-      ! 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
+      call OcnVelocityForcingTend(tend_u, ke_edge, h_edge, u, grid)
 
-        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.
-
-           tend_u(k,iEdge) = tend_u(k,iEdge)  &amp;
-             - 1.0e-3*u(k,iEdge) &amp;
-               *sqrt(2.0*ke_edge(k,iEdge))/h_edge(k,iEdge)
-
-        endif
-
-      enddo
-
       call timer_stop(&quot;vel forcing&quot;)
       call timer_start(&quot;vel vmix&quot;)
       !
@@ -667,12 +612,16 @@
          do iEdge=1,nEdges
             cell1 = cellsOnEdge(1,iEdge)
             cell2 = cellsOnEdge(2,iEdge)
+
+            invAreaCell1 = 1.0/areaCell(cell1)
+            invAreaCell2 = 1.0/areaCell(cell2)
+
             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)
+                  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
@@ -683,6 +632,9 @@
             cell1 = cellsOnEdge(1,iEdge)
             cell2 = cellsOnEdge(2,iEdge)
 
+            invAreaCell1 = 1.0 / areaCell(cell1)
+            invAreaCell2 = 1.0 / areaCell(cell2)
+
             do k=1,maxLevelEdgeTop(iEdge)
 
                d2fdx2_cell1 = 0.0
@@ -725,8 +677,8 @@
                   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)
+                  tend_tr(iTracer,k,cell1) = tend_tr(iTracer,k,cell1) - flux*invAreaCell1
+                  tend_tr(iTracer,k,cell2) = tend_tr(iTracer,k,cell2) + flux*invAreaCell2
                enddo
             end do
          end do
@@ -737,6 +689,9 @@
             cell1 = cellsOnEdge(1,iEdge)
             cell2 = cellsOnEdge(2,iEdge)
 
+            invAreaCell1 = 1.0 / areaCell(cell1)
+            invAreaCell2 = 1.0 / areaCell(cell2)
+
             do k=1,maxLevelEdgeTop(iEdge)
 
                d2fdx2_cell1 = 0.0
@@ -769,8 +724,8 @@
                           -(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)
+                  tend_tr(iTracer,k,cell1) = tend_tr(iTracer,k,cell1) - flux*invAreaCell1
+                  tend_tr(iTracer,k,cell2) = tend_tr(iTracer,k,cell2) + flux*invAreaCell2
                enddo
             end do
          end do
@@ -1043,6 +998,9 @@
       real (kind=RKIND) :: coef_3rd_order
       real (kind=RKIND) :: r, h1, h2
 
+      real (kind=RKIND) :: invAreaCell1, invAreaCell2
+      real (kind=RKIND) :: invAreaTri1, invAreaTri2
+      real (kind=RKIND) :: invDCEdge, invDVEdge
 
       h           =&gt; s % h % array
       u           =&gt; s % u % array
@@ -1229,8 +1187,11 @@
          end do
       end do
       do iVertex=1,nVertices
+
+         invAreaTri1 = 1.0 / areaTriangle(iVertex)
+
          do k=1,maxLevelVertexBot(iVertex)
-            vorticity(k,iVertex) = circulation(k,iVertex) / areaTriangle(iVertex)
+            vorticity(k,iVertex) = circulation(k,iVertex) * invAreaTri1
          end do
       end do
 
@@ -1241,17 +1202,15 @@
       do iEdge=1,nEdges
          cell1 = cellsOnEdge(1,iEdge)
          cell2 = cellsOnEdge(2,iEdge)
+
+         invAreaCell1 = 1.0/areaCell(cell1)
+         invAreaCell2 = 1.0/areaCell(cell2)
+
          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)
+             divergence(k,cell1) = divergence(k,cell1) + u(k,iEdge)*dvEdge(iEdge)*invAreaCell1
+             divergence(k,cell2) = divergence(k,cell2) - u(k,iEdge)*dvEdge(iEdge)*invAreaCell2
          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
@@ -1260,16 +1219,15 @@
       do iEdge=1,nEdges
          cell1 = cellsOnEdge(1,iEdge)
          cell2 = cellsOnEdge(2,iEdge)
+
+         invAreaCell1 = 1.0/areaCell(cell1)
+         invAreaCell2 = 1.0/areaCell(cell2)
+
          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
+              ke(k,cell1) = ke(k,cell1) + 0.25 * dcEdge(iEdge) * dvEdge(iEdge) * u(k,iEdge)**2.0 * invAreaCell1
+              ke(k,cell2) = ke(k,cell2) + 0.25 * dcEdge(iEdge) * dvEdge(iEdge) * u(k,iEdge)**2.0 * invAreaCell2
          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
@@ -1305,12 +1263,14 @@
       !  ( this computes pv_vertex at all vertices bounding real cells and distance-1 ghost cells )
       !
       do iVertex = 1,nVertices
+
+         invAreaTri1 = 1.0 / areaTriangle(iVertex)
          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)
+            h_vertex = h_vertex * invAreaTri1
 
             pv_vertex(k,iVertex) = (fVertex(iVertex) + vorticity(k,iVertex)) / h_vertex
          end do
@@ -1324,10 +1284,12 @@
       do iVertex = 1,nVertices
          do i=1,vertexDegree
             iCell = cellsOnVertex(i,iVertex)
+
+            invAreaCell1 = 1.0/areaCell(iCell)
             do k = 1,maxLevelCell(iCell)
                pv_cell(k,iCell) = pv_cell(k,iCell)  &amp;
                   + kiteAreasOnVertex(i, iVertex) * pv_vertex(k, iVertex) &amp;
-                    / areaCell(iCell)
+                    * invAreaCell1
             enddo
          enddo
       enddo
@@ -1352,10 +1314,13 @@
       !
       gradPVn(:,:) = 0.0
       do iEdge = 1,nEdges
+
+         invDCEdge = 1.0 / dcEdge(iEdge)
+
          do k=1,maxLevelEdgeTop(iEdge)
             gradPVn(k,iEdge) = (  pv_cell(k,cellsOnEdge(2,iEdge)) &amp;
                                 - pv_cell(k,cellsOnEdge(1,iEdge))) &amp;
-                               / dcEdge(iEdge)
+                               * invDCEdge
          enddo
       enddo
 
@@ -1364,10 +1329,12 @@
       !   ( this computes gradPVt at all edges bounding real cells and distance-1 ghost cells )
       !
       do iEdge = 1,nEdges
+
+         invDVEdge = 1.0 / dvEdge(iEdge)
          do k = 1,maxLevelEdgeBot(iEdge)
            gradPVt(k,iEdge) = (  pv_vertex(k,verticesOnEdge(2,iEdge)) &amp;
                                - pv_vertex(k,verticesOnEdge(1,iEdge))) &amp;
-                                 /dvEdge(iEdge)
+                                 * invDVEdge
          enddo
       enddo
 
@@ -1475,9 +1442,12 @@
            ! bottom is zero.
            wTop(1,iCell) = 0.0
            wTop(maxLevelCell(iCell)+1,iCell) = 0.0
+
+           invAreaCell1 = 1.0/areaCell(iCell)
+
            do k=maxLevelCell(iCell),2,-1
               wTop(k,iCell) = wTop(k+1,iCell) &amp;
-                 - div_u(k,iCell)/areaCell(iCell)*h(k,iCell)
+                 - div_u(k,iCell)*h(k,iCell) * invAreaCell1
            end do
         end do
         deallocate(div_u)

</font>
</pre>