<p><b>mpetersen@lanl.gov</b> 2010-05-03 14:35:52 -0600 (Mon, 03 May 2010)</p><p>Added horizontal and vertical tracer diffusion to zlevel branch.<br>
</p><hr noshade><pre><font color="gray">Modified: branches/ocean_projects/z_level_mrp/mpas/src/core_ocean/module_test_cases.F
===================================================================
--- branches/ocean_projects/z_level_mrp/mpas/src/core_ocean/module_test_cases.F        2010-05-03 20:22:06 UTC (rev 235)
+++ branches/ocean_projects/z_level_mrp/mpas/src/core_ocean/module_test_cases.F        2010-05-03 20:35:52 UTC (rev 236)
@@ -129,17 +129,24 @@
          tracers = 0.0
          do iCell = 1,nCells
            ! for three layer test
-           tracers(index_salinity,1,iCell) = 2.0  ! salinity
-           tracers(index_salinity,2,iCell) = 6.0  ! salinity
-           tracers(index_salinity,3,iCell) = 13.0  ! salinity
+           !tracers(index_salinity,1,iCell) = 2.0  ! salinity
+           !tracers(index_salinity,2,iCell) = 6.0  ! salinity
+           !tracers(index_salinity,3,iCell) = 13.0  ! salinity
            do iLevel = 1,nVertLevels
-             !if (xCell(iCell)&lt;500*1e3) tracers(4,iLevel,iCell) = 1.0
+!             if (xCell(iCell)&lt;500*1e3.and.ycell(iCell)&lt;1000*1e3) then
+!               tracers(index_tracer1,iLevel,iCell) = 1.0
+!               tracers(index_tracer2,iLevel,iCell) = 1.0e4
+!             endif
+!             if (ycell(iCell)&gt;1400*1e3.and.ycell(iCell)&lt;1500*1e3) then
+!               tracers(index_tracer1,iLevel,iCell) = 1.0
+!               tracers(index_tracer2,iLevel,iCell) = 1.0e4
+!             endif
 !            tracers(index_temperature,iLevel,iCell) = 5.0  ! temperature
 !             tracers(index_temperature,iLevel,iCell) = 6.0-iLevel ! temperature
 !             tracers(index_temperature,iLevel,iCell) = 6.0-iLevel+yCell(iCell)/4000.e3 ! temperature
 !             tracers(index_salinity,iLevel,iCell) = 35.0  ! salinity
-
-             ! for three layer test
+             ! for 20 layer test
+             tracers(index_salinity,iLevel,iCell) = 1.4 + iLevel*0.6  ! salinity
              tracers(index_temperature,iLevel,iCell) = 5.0  ! temperature
 
 !             tracers(index_temperature,iLevel,iCell) = &amp;
@@ -149,6 +156,7 @@
              tracers(index_tracer1,iLevel,iCell) = 1.0
              tracers(index_tracer2,iLevel,iCell) = &amp;
                (yCell(iCell)/4000.e3 + xCell(iCell)/2500.e3 )/2.0
+!             tracers(index_tracer1,iLevel,iCell) = mod(ilevel,2)
              rho(iLevel,iCell) = 1000.0*(  1.0 &amp;
                - 2.5e-4*tracers(index_temperature,iLevel,iCell) &amp;
                + 7.6e-4*tracers(index_salinity,iLevel,iCell))

Modified: branches/ocean_projects/z_level_mrp/mpas/src/core_ocean/module_time_integration.F
===================================================================
--- branches/ocean_projects/z_level_mrp/mpas/src/core_ocean/module_time_integration.F        2010-05-03 20:22:06 UTC (rev 235)
+++ branches/ocean_projects/z_level_mrp/mpas/src/core_ocean/module_time_integration.F        2010-05-03 20:35:52 UTC (rev 236)
@@ -534,7 +534,7 @@
            else
               dist = zBotEdge(k-1,iEdge) - zBotEdge(k,iEdge)
            endif
-           tend_u(k,iEdge) = tend_u(k,iEdge) - (fluxVert(k-1) - fluxVert(k))/dist
+           tend_u(k,iEdge) = tend_u(k,iEdge) + (fluxVert(k-1) - fluxVert(k))/dist
          enddo
 
       end do
@@ -587,33 +587,41 @@
 
       integer :: iCell, iEdge, k, iTracer, cell1, cell2, &amp;
         nEdges, nCells, nVertLevels
-      real (kind=RKIND) :: flux, tracer_edge, &amp;
+      real (kind=RKIND) :: flux, tracer_edge, r, &amp;
         Tmid(num_tracers,grid % nVertLevels)
 
+      real (kind=RKIND) :: visc, dist, ah
       real (kind=RKIND), dimension(:), pointer :: &amp;
-        h_s, fVertex, fEdge, dvEdge, dcEdge, areaCell, areaTriangle
+        h_s, fVertex, fEdge, dvEdge, dcEdge, areaCell, areaTriangle, zsurface
       real (kind=RKIND), dimension(:,:), pointer :: &amp;
-        u,h,Fv, h_edge
+        u,h,Fv, h_edge, zmid, zbot
       real (kind=RKIND), dimension(:,:,:), pointer :: &amp;
         tracers, tend_tr
       integer, dimension(:), pointer :: nEdgesOnCell, nEdgesOnEdge
       integer, dimension(:,:), pointer :: cellsOnEdge
+      real (kind=RKIND), dimension(:,:), allocatable:: fluxVert
+      real (kind=RKIND), dimension(:,:,:), allocatable::tr_flux, tr_div
 
       u           =&gt; s % u % array
       h           =&gt; s % h % array
       tracers     =&gt; s % tracers % array
       h_edge      =&gt; s % h_edge % array
       Fv          =&gt; tend % w % array
+      zmid        =&gt; s % zmid % array
+      zbot        =&gt; s % zbot % array
+      zsurface    =&gt; s % zsurface % 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
       nEdges      = grid % nEdges
       nCells      = grid % nCells
       nVertLevels = grid % nVertLevels
 
+      ! Horizontal advection of tracers
       tend_tr(:,:,:) = 0.0
       do iEdge=1,nEdges
          cell1 = cellsOnEdge(1,iEdge)
@@ -632,6 +640,7 @@
          end if
       end do 
 
+
       ! mrp 100409 computation of h tendency was, only had div.(huT) term
       !do iCell=1,grid % nCellsSolve
       !   do k=1,grid % nVertLevelsSolve
@@ -641,6 +650,7 @@
       !   end do
       !end do
       ! mrp 100409 replace with
+      allocate(fluxVert(num_tracers,0:nVertLevels))
       do iCell=1,grid % nCellsSolve
 
          ! Surface tracer Tmid(:,1) is not used
@@ -683,9 +693,97 @@
             end do
          end do
 
-      end do
+         ! vertical mixing
+         fluxVert(:,0) = 0.0
+         fluxVert(:,nVertLevels) = 0.0
+         do k=nVertLevels-1,1,-1
+           do iTracer=1,num_tracers
+             ! compute dphi/dz
+             fluxVert(iTracer,k) = ( tracers(iTracer,k  ,iCell) - tracers(iTracer,k+1,iCell) )&amp;
+                / (zMid(k,iCell) -zMid(k+1,iCell))
+           enddo
+         enddo
+         ! note vertical diffusivity is hardwired as 2.5e-4 here.
+         ! In POP, default vertical tracer diffusion is 0.25cm^2/s=2.5e-5m^2/s
+         fluxVert = 2.5e-4 * fluxVert
+         k=1
+           dist = zSurface(iCell) - zBot(k,iCell)
+           do iTracer=1,num_tracers
+             tend_tr(iTracer,k,iCell) = tend_tr(iTracer,k,iCell) &amp;
+               + (fluxVert(iTracer,k-1) - fluxVert(iTracer,k))/dist
+           enddo
+
+         do k=2,nVertLevels
+           dist = zBot(k-1,iCell) - zBot(k,iCell)
+           do iTracer=1,num_tracers
+             tend_tr(iTracer,k,iCell) = tend_tr(iTracer,k,iCell) &amp;
+               + (fluxVert(iTracer,k-1) - fluxVert(iTracer,k))/dist
+           enddo
+         enddo
+
+      enddo ! iCell loop
+      deallocate(fluxVert)
       ! mrp 100409 end
 
+      ! mrp 100501: Horizontal tracer diffusion 
+      ! first compute kappa*grad(phi) at edges.
+      ! note this could be combined with the above loops for tracer flux.
+      ! leave it separate for now for clarity.
+      ! Hardwire ah as 2e3m^2/s, from 2e7cm^2/s in the POP Users Guide p. 39
+      ah = 2.0e3 ! original
+      allocate(tr_flux(num_tracers,nVertLevels,nEdges))
+!      do iEdge=1,grid % nEdgesSolve 
+      do iEdge=1,nEdges
+         cell1 = cellsOnEdge(1,iEdge)
+         cell2 = cellsOnEdge(2,iEdge)
+         if (cell1 &gt; 0 .and. cell2 &gt; 0) then
+
+         do k=1,nVertLevels
+           do iTracer=1,num_tracers
+             tr_flux(iTracer,k,iEdge) =  ah *    &amp;
+                (Tracers(iTracer,k,cell2) - Tracers(iTracer,k,cell1))/dcEdge(iEdge)
+           enddo
+         enddo
+        endif
+      enddo
+
+      ! Compute the divergence, div(k grad(phi)) at each cell center
+      !
+      allocate(tr_div(num_tracers,nVertLevels,nCells))
+      tr_div(:,:,:) = 0.0
+!      do iEdge=1,grid % nEdgesSolve
+      do iEdge=1,nEdges
+         cell1 = cellsOnEdge(1,iEdge)
+         cell2 = cellsOnEdge(2,iEdge)
+         if (cell1 &gt; 0) then
+            do k=1,nVertLevels
+           do iTracer=1,num_tracers
+              tr_div(iTracer,k,cell1) = tr_div(iTracer,k,cell1) + tr_flux(iTracer,k,iEdge)*dvEdge(iEdge)
+            enddo
+            enddo
+         endif
+         if(cell2 &gt; 0) then
+            do k=1,nVertLevels
+           do iTracer=1,num_tracers
+              tr_div(iTracer,k,cell2) = tr_div(iTracer,k,cell2) - tr_flux(iTracer,k,iEdge)*dvEdge(iEdge)
+            enddo
+            enddo
+         end if
+      end do
+
+      ! The term  div(k grad(phi)) is then added to each cell center below.
+       do iCell = 1,nCells
+        r = 1.0 / areaCell(iCell)
+        do k = 1,nVertLevels
+           do iTracer=1,num_tracers
+              tend_tr(iTracer,k,iCell) = tend_tr(iTracer,k,iCell) &amp;
+                + tr_div(iTracer,k,iCell)*r
+           enddo
+        enddo
+      enddo
+      deallocate(tr_flux, tr_div)
+      ! mrp 100501 end: Horizontal tracer diffusion
+
    end subroutine compute_scalar_tend
 
 
@@ -1017,7 +1115,7 @@
          do k = 1,nVertLevels
            if(uBC(k,iEdge).eq.1) then
              h1 = 0.0
-             h2 = 0.0
+             h2 = 0.0 
              if(cell1.gt.0) h1 = h(k,cell1)
              if(cell2.gt.0) h2 = h(k,cell2)
              pv_edge(k,iEdge) = fEdge(iEdge) / ( max(h1,h2) )

</font>
</pre>