<p><b>mhoffman@lanl.gov</b> 2012-04-18 15:32:11 -0600 (Wed, 18 Apr 2012)</p><p>BRANCH COMMIT<br>
Resolved instability in the thickness advection with the Forward Euler time stepper by (properly) using velocity from previous time step to calculate thickness tendency.  Reorganized the Forward Euler time integration subroutine to clearly reflect the proper use of the two time levels.  Modified the calls to the velocity solvers to make the velocity variable that is solved to be independent of the state used to calculate velocity.<br>
</p><hr noshade><pre><font color="gray">Modified: branches/land_ice_projects/implement_core/src/core_land_ice/mpas_land_ice_lifev.F
===================================================================
--- branches/land_ice_projects/implement_core/src/core_land_ice/mpas_land_ice_lifev.F        2012-04-18 19:45:23 UTC (rev 1793)
+++ branches/land_ice_projects/implement_core/src/core_land_ice/mpas_land_ice_lifev.F        2012-04-18 21:32:11 UTC (rev 1794)
@@ -289,7 +289,7 @@
 
 !***********************************************************************
 
-   subroutine land_ice_lifev_solve(mesh, state, err)
+   subroutine land_ice_lifev_solve(mesh, state, normalVelocity, err)
 
       !-----------------------------------------------------------------
       !
@@ -300,14 +300,19 @@
       type (mesh_type), intent(in) :: &amp;
          mesh          !&lt; Input: mesh information
 
+      type (state_type), intent(in) :: &amp;
+         state          !&lt; Input: state information
+      ! Note: This state is meant to be unmodified (input only).
+
       !-----------------------------------------------------------------
       !
       ! input/output variables
       !
       !-----------------------------------------------------------------
 
-      type (state_type), intent(in) :: &amp;
-         state          !&lt; Input/Output: state information
+      real (kind=RKIND), intent(inout), dimension(:,:) :: &amp;
+         normalVelocity !&lt; Input/Output: the result of the velocity solve
+         ! Note: this velocity should be used for both input or output - it may be different than the velocity included in state, and the velocity included in state should not be touched.  If land_ice_vel_solve() returns anything else besides normalVelocity, those variables should also be treated in this way.  This allow the time integration scheme to decide how to treat multiple time levels.
 
       !-----------------------------------------------------------------
       !
@@ -324,8 +329,6 @@
       !-----------------------------------------------------------------
       real (kind=RKIND), dimension(:), pointer :: &amp;
          thickness, lowerSurface, beta
-      real (kind=RKIND), dimension(:,:), pointer :: &amp;
-         normalVelocity
       real (kind=RKIND), dimension(:,:,:), pointer :: &amp;
          tracers
 
@@ -337,7 +340,6 @@
       lowerSurface =&gt; state % lowerSurface % array
       beta =&gt; state % beta % array
       tracers =&gt; state % tracers % array
-      normalVelocity =&gt; state % normalVelocity % array
 
       index_temperature = state % index_temperature
 

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-04-18 19:45:23 UTC (rev 1793)
+++ branches/land_ice_projects/implement_core/src/core_land_ice/mpas_land_ice_sia.F        2012-04-18 21:32:11 UTC (rev 1794)
@@ -261,7 +261,7 @@
 
 !***********************************************************************
 
-   subroutine land_ice_sia_solve(mesh, state, err)
+   subroutine land_ice_sia_solve(mesh, state, normalVelocity, err)
       use mpas_constants, only: gravity
 
       !-----------------------------------------------------------------
@@ -273,14 +273,19 @@
       type (mesh_type), intent(in) :: &amp;
          mesh          !&lt; Input: mesh information
 
+      type (state_type), intent(in) :: &amp;
+         state          !&lt; Input: state information
+      ! Note: This state is meant to be unmodified (input only).
+
       !-----------------------------------------------------------------
       !
       ! input/output variables
       !
       !-----------------------------------------------------------------
 
-      type (state_type), intent(in) :: &amp;
-         state          !&lt; Input/Output: state information
+      real (kind=RKIND), intent(inout), dimension(:,:) :: &amp;
+         normalVelocity !&lt; Input/Output: the result of the velocity solve
+         ! Note: this velocity should be used for both input or output - it may be different than the velocity included in state, and the velocity included in state should not be touched.  If land_ice_vel_solve() returns anything else besides normalVelocity, those variables should also be treated in this way.  This allow the time integration scheme to decide how to treat multiple time levels.
 
       !-----------------------------------------------------------------
       !
@@ -300,7 +305,6 @@
       real (kind=RKIND), dimension(:), pointer :: dcEdge
       real (kind=RKIND), dimension(:,:), pointer :: layerThickness
       integer, dimension(:,:), pointer :: cellsOnEdge
-      real (kind=RKIND), dimension(:,:), pointer :: normalVelocity
       real (kind=RKIND), dimension(mesh%nVertLevels) :: layerFractionAboveBed
       integer :: nVertLevels, nCells, nEdges, iCell, iLevel, iEdge
       real (kind=RKIND) :: ratefactor, basalVelocity, slopeOnEdge, thicknessOnEdge
@@ -320,7 +324,6 @@
 
       thickness =&gt; state % thickness % array
       layerThickness =&gt; state % layerThickness % array
-      normalVelocity =&gt; state % normalVelocity % array
 
       rhoi = config_ice_density
 
@@ -385,6 +388,7 @@
      cell1 = cellsOnEdge(1,iEdge)
      cell2 = cellsOnEdge(2,iEdge)
      ! Check if an edge has at least one adjacent cell with ice
+     ! (to turn off advancing margins with FO thickness advection, replace the .or. with .and.
      if ( (thickness(cell1).gt.0.0) .or. (thickness(cell2).gt.0.0) ) then
          edgeIsIce = .true.
      else

Modified: branches/land_ice_projects/implement_core/src/core_land_ice/mpas_land_ice_time_integration.F
===================================================================
--- branches/land_ice_projects/implement_core/src/core_land_ice/mpas_land_ice_time_integration.F        2012-04-18 19:45:23 UTC (rev 1793)
+++ branches/land_ice_projects/implement_core/src/core_land_ice/mpas_land_ice_time_integration.F        2012-04-18 21:32:11 UTC (rev 1794)
@@ -19,7 +19,7 @@
    use mpas_configure
    use mpas_constants
    use mpas_dmpar
-   use land_ice_time_integration_ForwardEuler
+   use land_ice_time_integration_forwardeuler
 
    contains
 
@@ -51,7 +51,7 @@
       write(*,*) 'Using ', trim(config_time_integration), ' time integration.'
       select case (config_time_integration)
       case ('ForwardEuler')
-         call land_ice_time_integrator_ForwardEuler(domain, dt)
+         call land_ice_time_integrator_forwardeuler(domain, dt)
       case ('RK4')
          write(*,*) trim(config_time_integration), ' is not currently supported.'
          !call mpas_dmpar_abort(dminfo)
@@ -62,7 +62,7 @@
 
       block =&gt; domain % blocklist
       do while (associated(block))
-         ! Assign the time stamp
+         ! Assign the time stamp for this time step
          block % state % time_levs(2) % state % xtime % scalar = timeStamp
 
 !         ! Abort the simulation if NaNs occur in the velocity field

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-04-18 19:45:23 UTC (rev 1793)
+++ branches/land_ice_projects/implement_core/src/core_land_ice/mpas_land_ice_time_integration_ForwardEuler.F        2012-04-18 21:32:11 UTC (rev 1794)
@@ -1,6 +1,6 @@
 !|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 !
-!  land_ice_time_integration_ForwardEuler
+!  land_ice_time_integration_forwardeuler
 !
 !&gt; \brief MPAS land ice Forward Euler time integration schem
 !&gt; \author Matt Hoffman
@@ -12,7 +12,7 @@
 !-----------------------------------------------------------------------
 
 
-module land_ice_time_integration_ForwardEuler
+module land_ice_time_integration_forwardeuler
 
    use mpas_vector_reconstruction
    use mpas_grid_types
@@ -24,7 +24,7 @@
 
    contains
 
-   subroutine land_ice_time_integrator_ForwardEuler(domain, dt)
+   subroutine land_ice_time_integrator_forwardeuler(domain, dt)
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
    ! Advance model state forward in time by the specified time step using
    !    Forward Euler method
@@ -41,11 +41,11 @@
       real (kind=RKIND), intent(in) :: dt
 
       type (block_type), pointer :: block
-      type (state_type), pointer :: state
+      type (state_type), pointer :: stateOld, stateNew
       type (mesh_type), pointer :: mesh
 
-      real (kind=RKIND), dimension(:), pointer :: thickness, thickness_tend, layerThicknessFractions
-      real (kind=RKIND), dimension(:,:), pointer :: normalVelocity, layerThickness !, layerThickness_tend
+      real (kind=RKIND), dimension(:), pointer :: thicknessOld, thicknessNew, thickness_tend, layerThicknessFractions
+      real (kind=RKIND), dimension(:,:), pointer :: normalVelocityOld, normalVelocityNew, layerThicknessOld, layerThicknessNew !, layerThickness_tend
       real (kind=RKIND), dimension(:,:), pointer :: uReconstructX, uReconstructY, uReconstructZ,  &amp;
          uReconstructZonal, uReconstructMeridional
 
@@ -55,72 +55,105 @@
 
       integer :: err
       
+      ! 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(...)
+      ! (time level 1 should not be modified.)
 
       block =&gt; domain % blocklist
       do while (associated(block))
+! === Initialize pointers ========================
+         ! Mesh information
          mesh =&gt; block % mesh
          nVertLevels =  mesh % nVertLevels
          layerThicknessFractions =&gt; mesh % layerThicknessFractions % array
 
-         state =&gt; block % state % time_levs(2) % state
-         thickness =&gt; state % thickness % array
-         layerThickness =&gt; state % layerThickness % array
-         normalVelocity =&gt; state % normalVelocity % array
+         ! State at time n
+         stateOld =&gt; block % state % time_levs(1) % state
+         thicknessOld =&gt; stateOld % thickness % array
+         layerThicknessOld =&gt; stateOld % layerThickness % array
+         normalVelocityOld =&gt; stateOld % normalVelocity % array
 
-         uReconstructX =&gt; state % uReconstructX % array
-         uReconstructY =&gt; state % uReconstructY % array
-         uReconstructZ =&gt; state % uReconstructZ % array
-         uReconstructZonal =&gt; state % uReconstructZonal % array
-         uReconstructMeridional =&gt; state % uReconstructMeridional % array
+         ! State at time n+1 (advanced by dt by Forward Euler)
+         stateNew =&gt; block % state % time_levs(2) % state
+         thicknessNew =&gt; stateNew % thickness % array
+         layerThicknessNew =&gt; stateNew % layerThickness % array
+         normalVelocityNew =&gt; stateNew % normalVelocity % array
+         uReconstructX =&gt; stateNew % uReconstructX % array
+         uReconstructY =&gt; stateNew % uReconstructY % array
+         uReconstructZ =&gt; stateNew % uReconstructZ % array
+         uReconstructZonal =&gt; stateNew % uReconstructZonal % array
+         uReconstructMeridional =&gt; stateNew % uReconstructMeridional % array
 
+         ! Tendencies
          !layerThickness_tend =&gt; block % tend % layerThickness % array
          thickness_tend =&gt; block % tend % thickness % array
 
-         k = size(thickness)
-         allocate(mask(k))
 
+         allocate(mask(mesh%nCells + 1))
 
-         ! Solve the velocity
-         call land_ice_vel_solve(mesh, block % state % time_levs(1) % state, err)
-         block % state % time_levs(2) % state % normalVelocity % array = block % state % time_levs(1) % state % normalVelocity % array
-         !state % xtime % scalar = timeStamp 

-         ! Update the thickness and tracers  (move to another module eventually)
-         call lice_tend_h(mesh, normalVelocity, layerThickness, thickness, thickness_tend, dt, err)
-         thickness = thickness + thickness_tend * dt / SecondsInYear
 
-         ! Commented lines below calculate the thickness tendency per layer instead of for the whole column
+! === Calculate Tendencies ========================
+         ! Calculate thickness tendency using state at time n
+         call lice_tend_h(mesh, normalVelocityOld, layerThicknessOld, thicknessOld, thickness_tend, dt, err)
+
+         ! update halos on thickness tend
+         !call ()
+
+         ! (Calculate tracer tendencies)
+         !call ()
+
+
+         ! Commented lines below calculate the thickness tendency per layer instead of for the whole column  (last 2 lines should be moved to following 'section' of code)
          !call lice_tend_h_layers(mesh, normalVelocity, layerThickness, layerThickness_tend, dt, err)       
          !layerThickness = layerThickness + layerThickness_tend * dt / SecondsInYear
          !thickness = sum(layerThickness, 1)
 
-         ! Remap layer thicknesses
-         do k = 1, nVertLevels
-            layerThickness(k, :) = thickness * layerThicknessFractions(k)
-         end do
 
+! === Compute new state for prognostic variables ==================================
+
+         ! Update thickness (and tracers eventually)
+         thicknessNew = thicknessOld + thickness_tend * dt / SecondsInYear        
+
          !Optionally print some information about the new state
-         print *, 'thickness maxval:', maxval(thickness)
+         print *, 'thickness maxval:', maxval(thicknessNew)
          mask = 0
-         where (thickness .lt. 0.0)
+         where (thicknessNew .lt. 0.0)
             mask = 1
-            thickness = 0.0
+            thicknessNew = 0.0
          end where
-         print *,'Cells with negative thickness (set to 0):',sum(mask)
+         if (sum(mask) .gt. 0) then
+                 print *,'Cells with negative thickness (set to 0):',sum(mask)
+         endif
 
          mask = 0
-         where (thickness .gt. 0.0)
+         where (thicknessNew .gt. 0.0)
             mask = 1
          end where
          print *,'Cells with nonzero thickness:', sum(mask)
 
+         ! Solve the velocity (using old state)
+         call land_ice_vel_solve(mesh, stateOld, normalVelocityNew, err)
+         ! update halos on velocity
+         ! call ()
+
+! === Calculate diagnostic variables for new state =====================
+         ! Remap layer thicknesses (could be moved to diagnostic solve)
+         do k = 1, nVertLevels
+            layerThicknessNew(k, :) = thicknessNew * layerThicknessFractions(k)
+         end do
+
          ! call land_ice_diagnostic_solve()
 
-         ! Reconstruct velocities for this time step
-         call mpas_reconstruct(mesh, normalVelocity, &amp;
+         ! Reconstruct velocities for this time step (could be moved to diagnostic solve)
+         call mpas_reconstruct(mesh, normalVelocityNew, &amp;
                 uReconstructX, uReconstructY, uReconstructZ,  &amp;
                 uReconstructZonal, uReconstructMeridional)
 
+! === Cleanup &amp; Misc. =============================
+
+
+! ================================
+
          block =&gt; block % next
       end do
 
@@ -130,6 +163,6 @@
 
 
 
-end module land_ice_time_integration_ForwardEuler
+end module land_ice_time_integration_forwardeuler
 
 

Modified: branches/land_ice_projects/implement_core/src/core_land_ice/mpas_land_ice_vel.F
===================================================================
--- branches/land_ice_projects/implement_core/src/core_land_ice/mpas_land_ice_vel.F        2012-04-18 19:45:23 UTC (rev 1793)
+++ branches/land_ice_projects/implement_core/src/core_land_ice/mpas_land_ice_vel.F        2012-04-18 21:32:11 UTC (rev 1794)
@@ -238,7 +238,7 @@
 
 !***********************************************************************
 
-   subroutine land_ice_vel_solve(mesh, state, err)
+   subroutine land_ice_vel_solve(mesh, state, normalVelocity, err)
 
       use land_ice_SIA
 
@@ -251,14 +251,19 @@
       type (mesh_type), intent(in) :: &amp;
          mesh          !&lt; Input: mesh information
 
+      type (state_type), intent(in) :: &amp;
+         state          !&lt; Input: state information 
+      ! Note: This state is meant to be unmodified (input only).
+
       !-----------------------------------------------------------------
       !
       ! input/output variables
       !
       !-----------------------------------------------------------------
 
-      type (state_type), intent(in) :: &amp;
-         state          !&lt; Input/Output: state information
+      real (kind=RKIND), intent(inout), dimension(:,:) :: &amp;
+         normalVelocity !&lt; Input/Output: the result of the velocity solve
+         ! Note: this velocity should be used for both input or output - it may be different than the velocity included in state, and the velocity included in state should not be touched.  If land_ice_vel_solve() returns anything else besides normalVelocity, those variables should also be treated in this way.  This allow the time integration scheme to decide how to treat multiple time levels.
 
       !-----------------------------------------------------------------
       !
@@ -278,9 +283,9 @@
 
       select case (config_dycore)
       case ('L1L2')
-          call land_ice_lifev_solve(mesh, state, err)
+          call land_ice_lifev_solve(mesh, state, normalVelocity, err)
       case ('SIA')
-          call land_ice_sia_solve(mesh, state, err)
+          call land_ice_sia_solve(mesh, state, normalVelocity, err)
       case default
           write(*,*) trim(config_dycore), ' is not a valid land ice dycore option.'
           err = 1

</font>
</pre>