<p><b>mhoffman@lanl.gov</b> 2012-05-21 15:14:18 -0600 (Mon, 21 May 2012)</p><p>BRANCH COMMIT -- land ice<br>
<br>
Updated shallow ice velocity solver to use correct vertical indexing convention.<br>
Also cleaned up various implementations of thickness on edges:<br>
  SIA velocity is hardcoded to use 2nd order h_edge.<br>
  FO-Upwind thickness advection is hardcoded to use 1st order h_edge.<br>
  Diagnostic h_edge (needed for tracer advection) is determined by choice of thickness advection scheme.<br>
Also fixed a bug in the Makefile.<br>
</p><hr noshade><pre><font color="gray">Modified: branches/land_ice_projects/implement_core/src/core_land_ice/Makefile
===================================================================
--- branches/land_ice_projects/implement_core/src/core_land_ice/Makefile        2012-05-21 20:07:29 UTC (rev 1924)
+++ branches/land_ice_projects/implement_core/src/core_land_ice/Makefile        2012-05-21 21:14:18 UTC (rev 1925)
@@ -34,13 +34,13 @@
 
 mpas_land_ice_time_integration.o: mpas_land_ice_time_integration_forwardeuler.o
 
-mpas_land_ice_time_integration_forwardeuler.o: mpas_land_ice_vel.o mpas_land_ice_tendency.o mpas_ocn_tracer_advection.o
+mpas_land_ice_time_integration_forwardeuler.o: mpas_land_ice_vel.o mpas_land_ice_tendency.o 
 
 mpas_land_ice_mask.o:
 
 mpas_land_ice_vel.o: mpas_land_ice_lifev.o mpas_land_ice_sia.o
 
-mpas_land_ice_tendency.o: mpas_land_ice_mask.o
+mpas_land_ice_tendency.o: mpas_land_ice_mask.o mpas_ocn_tracer_advection.o
 
 mpas_land_ice_lifev.o:
 

Modified: branches/land_ice_projects/implement_core/src/core_land_ice/Registry
===================================================================
--- branches/land_ice_projects/implement_core/src/core_land_ice/Registry        2012-05-21 20:07:29 UTC (rev 1924)
+++ branches/land_ice_projects/implement_core/src/core_land_ice/Registry        2012-05-21 21:14:18 UTC (rev 1925)
@@ -18,7 +18,7 @@
 % valid dycores are SIA, L1L2, FO, Stokes. All but SIA require compiling with LifeV libraries.
 namelist character   land_ice_model  config_time_integration      ForwardEuler
 % valid time integration is ForwardEuler
-namelist character   land_ice_model  config_advection             FO-Upwind
+namelist character   land_ice_model  config_thickness_advection   FO-Upwind
 % valid advection is FO-Upwind, None (FCT coming soon)
 namelist character   land_ice_model  config_tracer_advection      FCT
 % valid options for tracer_advection are FCT (flux-corrected transport), None
@@ -175,8 +175,8 @@
 % Mesh variables specific to land ice core
 % Sigma coordinate: read from input, saved in restart and written to output
 var persistent real    layerThicknessFractions ( nVertLevels ) 0 iro layerThicknessFractions mesh - -
-var persistent real    layerCenterSigma ( nVertLevels ) 0 - layerCenterSigma mesh - -
-var persistent real    layerInterfaceSigma ( nVertLevelsPlus1 ) 0 - layerInterfaceSigma mesh - -
+var persistent real    layerCenterSigma ( nVertLevels ) 0 o layerCenterSigma mesh - -
+var persistent real    layerInterfaceSigma ( nVertLevelsPlus1 ) 0 o layerInterfaceSigma mesh - -
 
 % Boundary Conditions (defined as mesh variables because they are read in once and held constant for the simulation - at least for now)
 %
@@ -199,7 +199,6 @@
 
 % Tendency variables
 var persistent real    tend_layerThickness ( nVertLevels nCells Time ) 1 o layerThickness tend - -
-var persistent real    tend_thickness ( nCells Time ) 1 o thickness tend - -
 var persistent real    tend_temperature ( nVertLevels nCells Time ) 1 o temperature tend tracers dynamics
 %var persistent real    tend_sup_thickness ( nVertLevels nCells Time ) 1 o sup_thickness tend sup_thickness bob
 

Modified: branches/land_ice_projects/implement_core/src/core_land_ice/mpas_land_ice_global_diagnostics.F
===================================================================
--- branches/land_ice_projects/implement_core/src/core_land_ice/mpas_land_ice_global_diagnostics.F        2012-05-21 20:07:29 UTC (rev 1924)
+++ branches/land_ice_projects/implement_core/src/core_land_ice/mpas_land_ice_global_diagnostics.F        2012-05-21 21:14:18 UTC (rev 1925)
@@ -50,7 +50,7 @@
       real (kind=RKIND), dimension(:), pointer ::  areaCell, dcEdge, dvEdge, areaTriangle
 !!!      real (kind=RKIND), dimension(:), pointer ::  h_s, fCell, fEdge
 !!!      real (kind=RKIND), dimension(:,:), pointer :: h, u, v, layerThicknessEdge, &amp;
-      real (kind=RKIND), dimension(:,:), pointer :: layerThickness, normalVelocity, layerThicknessEdge, &amp;
+      real (kind=RKIND), dimension(:,:), pointer :: layerThickness, normalVelocity, &amp;
 !!!                                                    pv_edge, pv_vertex, pv_cell,  &amp;
                                                     layerThicknessVertex, weightsOnEdge
 
@@ -110,7 +110,7 @@
       normalVelocity =&gt; state % normalVelocity % array
 !!!      v =&gt; state % v % array
       tracers =&gt; state % tracers % array
-      layerThicknessEdge =&gt; state % layerThicknessEdge % array
+!      layerThicknessEdge =&gt; state % layerThicknessEdge % array
       layerThicknessVertex =&gt; state % layerThicknessVertex % array
 !!!      pv_edge =&gt; state % pv_edge % array
 !!!      pv_vertex =&gt; state % pv_vertex % array

Modified: branches/land_ice_projects/implement_core/src/core_land_ice/mpas_land_ice_sia.F
===================================================================
--- branches/land_ice_projects/implement_core/src/core_land_ice/mpas_land_ice_sia.F        2012-05-21 20:07:29 UTC (rev 1924)
+++ branches/land_ice_projects/implement_core/src/core_land_ice/mpas_land_ice_sia.F        2012-05-21 21:14:18 UTC (rev 1925)
@@ -215,7 +215,19 @@
    end subroutine land_ice_sia_block_init
 
 !***********************************************************************
-
+!
+!  subroutine land_ice_sia_solve
+!
+!&gt; \brief   Computes velocity using Shallow Ice Appoximation
+!&gt; \author  Matt Hoffman
+!&gt; \date    21 May 2012
+!&gt; \version SVN:$Id$
+!&gt; \details 
+!&gt;  This routine computes the normal velocity on edges for each layer 
+!&gt;  using the Shallow Ice Approximation.  It calculates ice thickness on 
+!&gt;  on an edge using the average of the two neighoring cells (2nd order).
+!
+!-----------------------------------------------------------------------
    subroutine land_ice_sia_solve(mesh, state, err)
       use mpas_constants, only: gravity
 
@@ -251,63 +263,57 @@
       !
       !-----------------------------------------------------------------
 
-      real (kind=RKIND), dimension(:), pointer :: thickness, layerThicknessFractions
-      real (kind=RKIND), dimension(:), pointer :: dcEdge
-      real (kind=RKIND), dimension(:,:), pointer :: layerThickness, normalVelocity
+      real (kind=RKIND), dimension(:), pointer :: thickness, layerCenterSigma, dcEdge
+      real (kind=RKIND), dimension(:,:), pointer :: normalVelocity
       integer, dimension(:,:), pointer :: cellsOnEdge
       integer, dimension(:), pointer :: edgeMask
-      real (kind=RKIND), dimension(mesh%nVertLevels) :: layerFractionAboveBed
-      integer :: nVertLevels, nCells, nEdges, iCell, iLevel, iEdge
-      real (kind=RKIND) :: ratefactor, basalVelocity, slopeOnEdge, thicknessOnEdge
-      real rhoi  !!!! THIS SHOULD BE A PHYSICAL PARAMETER ELSEWHERE
+      integer :: nVertLevels, nEdges, iLevel, iEdge, cell1, cell2
+      real (kind=RKIND) :: ratefactor, basalVelocity, slopeOnEdge, &amp;
+               layerCenterHeightOnEdge, thicknessEdge
+      real rhoi
 
       err = 0
 
       ! Set needed variables and pointers
-      nCells = mesh % nCells
       nEdges = mesh % nEdges
       nVertLevels = mesh % nVertLevels
 
       dcEdge =&gt; mesh % dcEdge % array
       cellsOnEdge =&gt; mesh % cellsOnEdge % array
-      layerThicknessFractions =&gt; mesh % layerThicknessFractions % array
+      layerCenterSigma =&gt; mesh % layerCenterSigma % array
 
       normalVelocity =&gt; state % normalVelocity % array
       thickness =&gt; state % thickness % array
-      layerThickness =&gt; state % layerThickness % array
       edgeMask =&gt; state % edgeMask % array
 
+
       rhoi = config_ice_density
 
       basalVelocity = 0.0  ! Assume no sliding
 
+      ! Calculate ratefactor (A) at edge - This should be calculated external to this subroutine and as a function of temperature 
       ratefactor = 1.0e-16
 
-      ! Determine the height of each layer above the bed
-      layerFractionAboveBed(1) = 0.5 * layerThicknessFractions(1)
-      do iLevel = 2, nVertLevels
-          layerFractionAboveBed(iLevel) = layerFractionAboveBed(iLevel - 1) + &amp;
-              0.5 * layerThicknessFractions(iLevel - 1) + 0.5 * layerThicknessFractions(iLevel)
-      end do
-
       ! Loop over edges
       do iEdge = 1, nEdges
          ! Only calculate velocity for edges that are part of the ice sheet.
          ! Also, the velocity calculation should be valid for non-ice edges (i.e. returns 0).
          if ( MASK_IS_ICE(edgeMask(iEdge)) ) then
-             ! Calculate slope, thickness at edge
-             ! These could/should be calculated externally to this subroutine
-             slopeOnEdge = (thickness(cellsOnEdge(1,iEdge)) - thickness(cellsOnEdge(2,iEdge)) ) &amp;
-                 / dcEdge(iEdge) 
-             thicknessOnEdge = 0.5 * (thickness(cellsOnEdge(1,iEdge)) + thickness(cellsOnEdge(2,iEdge))) 
+             cell1 = cellsOnEdge(1,iEdge)
+             cell2 = cellsOnEdge(2,iEdge)
+             ! Calculate slope at edge
+             ! This could/should be calculated externally to this subroutine
+             slopeOnEdge = (thickness(cell1) - thickness(cell2) ) / dcEdge(iEdge) 
+             ! Calculate thickness on edge - 2nd order
+             thicknessEdge = (thickness(cell1) + thickness(cell2) ) * 0.5
              ! Loop over layers
              do iLevel = 1, nVertLevels
-                ! Calculate ratefactor (A) at edge - This should be calculated here as a function of temperature 
-                ! ratefactor = f(T)
+                ! Determine the height of each layer above the bed
+                layerCenterHeightOnEdge = thicknessEdge * (1.0 - layerCenterSigma(iLevel) )
                 ! Calculate SIA velocity
                 normalVelocity(iLevel,iEdge) = basalVelocity + &amp;
                     0.5 * ratefactor * (rhoi * gravity)**3 * slopeOnEdge**3 * &amp;
-                    (thicknessOnEdge**4 - (thicknessOnEdge - thicknessOnEdge * layerFractionAboveBed(iLevel))**4)
+                    (thicknessEdge**4 - (thicknessEdge - layerCenterHeightOnEdge)**4)
              end do  ! Levels
          endif
       end do  ! edges  

Modified: branches/land_ice_projects/implement_core/src/core_land_ice/mpas_land_ice_tendency.F
===================================================================
--- branches/land_ice_projects/implement_core/src/core_land_ice/mpas_land_ice_tendency.F        2012-05-21 20:07:29 UTC (rev 1924)
+++ branches/land_ice_projects/implement_core/src/core_land_ice/mpas_land_ice_tendency.F        2012-05-21 21:14:18 UTC (rev 1925)
@@ -113,7 +113,7 @@
      ! 0 tendency
      layerThickness_tend = 0.0
 
-     select case (config_advection)
+     select case (config_thickness_advection)
      case ('FO-Upwind')  !===================================================
         !print *,'Using FO Upwind for thickness advection'
 
@@ -122,7 +122,7 @@
         !   state % layerThickness % array, state % thickness % array, thickness_tend, dt, err)
 
         call land_ice_tend_h_layers_fo_upwind(mesh, state % normalVelocity % array, &amp;
-             state % layerThicknessEdge % array, layerThickness_tend, dt, err)       
+             state % layerThickness % array, layerThickness_tend, dt, err)       
 
      !case ('FCT')  !===================================================
         ! MJH TEMP TRYING IT WITH THICKNESS
@@ -142,7 +142,7 @@
      case ('None')  !===================================================
         ! Do nothing
      case default  !===================================================
-        write(0,*) trim(config_advection), ' is not a valid thickness advection option.'
+        write(0,*) trim(config_thickness_advection), ' is not a valid thickness advection option.'
         call mpas_dmpar_abort(dminfo)
      end select  !===================================================
 
@@ -246,6 +246,7 @@
          end where
 
          ! FCT code needs u*h on edges - this could be calculated elsewhere and saved, potentially (e.g. it's already calculated locally in the FO upwind thickness routine)
+         ! layerThicknessEdge and normalVelocity should match those used in thickness advection!
          do iEdge = 1, mesh % nEdges
            do k = 1, mesh % nVertLevels
                uh(k, iEdge) = normalVelocity(k, iEdge) * layerThicknessEdge(k, iEdge)
@@ -332,7 +333,7 @@
       !-----------------------------------------------------------------
       integer :: iCell, iLevel, nCells, nVertLevels, nVertices
       real (kind=RKIND), dimension(:), pointer :: thickness, upperSurface, &amp;
-        lowerSurface, bedTopography, layerThicknessFractions
+        lowerSurface, bedTopography, layerThicknessFractions, thicknessEdge
       real (kind=RKIND), dimension(:,:), pointer :: layerThickness, layerThicknessEdge
       integer, dimension(:), pointer :: vertexMask
       integer, dimension(:,:), pointer :: cellsOnVertex, cellsOnEdge
@@ -370,29 +371,31 @@
          end do
       end do
 
-
-      ! \todo Calculate h_edge that can be used by SIA solve and FO advection scheme.  
-      ! ocn_diagnostic_solve in mpas_ocn_tendency.F has 2, 3, &amp; 4th order calculations for h_edge that can be used.  
-      ! Right now I am using 2nd order h_edge in SIA solve and 1st order h_edge in FO advection. 
+      ! Calculate h_edge.  This is used by both thickness and tracer advection.  
+      ! Note: FO-Upwind thickness advection does not explicitly use h_edge but a FO h_edge is implied.
+      ! Note: SIA velocity solver uses its own local calculation of h_edge that is always 2nd order.
+      ! Note: ocn_diagnostic_solve in mpas_ocn_tendency.F has 2, 3, &amp; 4th order calculations for h_edge that can be used.  
       ! NOTE: This calculates FO upwind h edge
 
       ! Both thickness and layerThickness should be updated by this time.
-      do iEdge=1,nEdges
-         cell1 = cellsOnEdge(1,iEdge)
-         cell2 = cellsOnEdge(2,iEdge)
-         do k=1, nVertLevels
-            ! Calculate h on edges using first order
-            layerThicknessEdge(k,iEdge) = max(layerThickness(k, cell1), layerThickness(k, cell2))
+      if (config_thickness_advection .eq. 'FO-Upwind') then
+         ! If using FO-Upwind then h_edge must be FO.
+         do iEdge=1,nEdges
+            cell1 = cellsOnEdge(1,iEdge)
+            cell2 = cellsOnEdge(2,iEdge)
+            do k=1, nVertLevels
+               ! Calculate h on edges using first order
+               layerThicknessEdge(k,iEdge) = max(layerThickness(k, cell1), layerThickness(k, cell2))
+            end do
+            ! thickness_edge is not currently in registry and not currenly needed.  If it is, uncomment the next line
+            !h_edge = max(thickness(cell1), thickness(cell2))
+            !!!h_edge = (thickness(k) + thickness(k) ) / 2.0  ! 2nd order 
          end do
-         ! thickness_edge is not currently in registry and not currenly needed.  If it is, uncomment the next line
-         !h_edge = max(thickness(cell1), thickness(cell2))
-         !!!h_edge = (thickness(k) + thickness(k) ) / 2.0  ! 2nd order 
-      end do
+      else
+          print *,'layerThicknessEdge not calculated!'
+      endif
 
-
-
       ! Calculate masks
-
       call land_ice_calculate_mask(mesh, state, err)
 
 
@@ -538,7 +541,7 @@
 !&gt;  results.  
 !
 !-----------------------------------------------------------------------
-   subroutine land_ice_tend_h_layers_fo_upwind(grid, normalVelocity, layerThicknessEdge, tend, dt, err)!{{{
+   subroutine land_ice_tend_h_layers_fo_upwind(grid, normalVelocity, layerThickness, tend, dt, err)!{{{
 
       !-----------------------------------------------------------------
       !
@@ -550,7 +553,7 @@
          normalVelocity    !&lt; Input: velocity
 
       real (kind=RKIND), dimension(:,:), intent(in) :: &amp;
-         layerThicknessEdge    !&lt; Input: thickness of each layer at edge
+         layerThickness    !&lt; Input: thickness of each layer
 
       type (mesh_type), intent(in) :: &amp;
          grid          !&lt; Input: grid information
@@ -580,11 +583,11 @@
       !
       !-----------------------------------------------------------------
 
-      integer :: iEdge, nEdges, cell1, cell2, nVertLevels, k
+      integer :: iEdge, nEdges, cell1, cell2, nVertLevels, k, CellDownwind, CellUpwind
 
       integer, dimension(:,:), pointer :: cellsOnEdge
 
-      real (kind=RKIND) :: flux
+      real (kind=RKIND) :: flux, VelSign
       real (kind=RKIND), dimension(:), pointer :: dvEdge, areaCell, dcEdge
 
       err = 0
@@ -600,14 +603,24 @@
       do iEdge=1,nEdges
          cell1 = cellsOnEdge(1,iEdge)
          cell2 = cellsOnEdge(2,iEdge)
-         do k=1, nVertLevels
-            if ( (abs(normalVelocity(k, iEdge)) * dt/SecondsInYear) .gt. (0.5 * dcEdge(iEdge))) then
-              print *, 'CFL violation at level, edge', k, iEdge
-            endif
-            flux = normalVelocity(k,iEdge) * dvEdge(iEdge) * layerThicknessEdge(k,iEdge)
-            tend(k,cell1) = tend(k,cell1) - flux / areaCell(cell1)
-            tend(k,cell2) = tend(k,cell2) + flux / areaCell(cell2)
-         end do
+         VelSign = sign(1.0, normalVelocity(1, iEdge))
+         if (VelSign .gt. 0.0) then
+            CellUpwind = cell1
+            CellDownwind = cell2
+         else
+            CellUpwind = cell2
+            CellDownwind = cell1
+         endif
+         if (layerThickness(1,cellUpwind) .gt. 0.0) then  ! Don't calculate for non-ice cells - would result in divide by 0 (just need to check one layer)
+            do k=1, nVertLevels
+               if ( (abs(normalVelocity(k, iEdge)) * dt/SecondsInYear) .gt. (0.5 * dcEdge(iEdge))) then
+                  print *, 'CFL violation at level, edge', k, iEdge
+               endif
+               flux = normalVelocity(k,iEdge) * dvEdge(iEdge) * layerThickness(k,cellUpwind)
+               tend(k,cell1) = tend(k,cell1) - flux / areaCell(cell1)
+               tend(k,cell2) = tend(k,cell2) + flux / areaCell(cell2)
+            end do
+         end if
       end do
 
    !--------------------------------------------------------------------

Modified: branches/land_ice_projects/implement_core/src/core_land_ice/mpas_land_ice_time_integration_forwardeuler.F
===================================================================
--- branches/land_ice_projects/implement_core/src/core_land_ice/mpas_land_ice_time_integration_forwardeuler.F        2012-05-21 20:07:29 UTC (rev 1924)
+++ branches/land_ice_projects/implement_core/src/core_land_ice/mpas_land_ice_time_integration_forwardeuler.F        2012-05-21 21:14:18 UTC (rev 1925)
@@ -45,7 +45,7 @@
       type (state_type), pointer :: stateOld, stateNew
       type (mesh_type), pointer :: mesh
 
-      real (kind=RKIND), dimension(:), pointer :: thicknessOld, thicknessNew, thickness_tend, layerThicknessFractions
+      real (kind=RKIND), dimension(:), pointer :: thicknessOld, thicknessNew, layerThicknessFractions
       real (kind=RKIND), dimension(:,:), pointer :: normalVelocityOld, normalVelocityNew, layerThicknessOld, layerThicknessNew, layerThickness_tend
       real (kind=RKIND), dimension(:,:,:), pointer :: tracer_tendency, tracersNew, tracersOld
 
@@ -90,7 +90,6 @@
 
          ! Tendencies
          layerThickness_tend =&gt; block % tend % layerThickness % array
-         thickness_tend =&gt; block % tend % thickness % array
          tracer_tendency =&gt; block % tend % tracers % array
 
 

</font>
</pre>