<p><b>akt@lanl.gov</b> 2013-04-19 12:44:55 -0600 (Fri, 19 Apr 2013)</p><p>Initial versions of velocity solver. Divergence of stress calculated with both weak integral formulation and variational discretization on both triangles and arbitary polygons<br>
</p><hr noshade><pre><font color="gray">Modified: branches/cice_projects/initial_cice_core/src/core_cice/Makefile
===================================================================
--- branches/cice_projects/initial_cice_core/src/core_cice/Makefile        2013-04-19 17:49:14 UTC (rev 2779)
+++ branches/cice_projects/initial_cice_core/src/core_cice/Makefile        2013-04-19 18:44:55 UTC (rev 2780)
@@ -1,35 +1,29 @@
 .SUFFIXES: .F .o
 
-OBJS =        mpas_cice_kinds_mod.o \
-        mpas_cice_constants.o \
-        mpas_cice_domain_size.o \
-        mpas_cice_state.o \
-        mpas_cice_test.o \
-        mpas_cice_init.o \
-        mpas_cice_timestep.o \
-        mpas_cice_mpas_core.o 
+OBJS =         mpas_cice_mpas_core.o \
+        mpas_cice_time_integration.o \
+        mpas_cice_dynamics_evp_tri.o \
+        mpas_cice_dynamics_evp_hex.o \
+        mpas_cice_dynamics_shared.o \
+        mpas_cice_testing.o
 
 all: core_cice
 
 core_cice: $(OBJS)
         ar -ru libdycore.a $(OBJS)
 
-mpas_cice_kinds_mod.o:
+mpas_cice_testing.o:
 
-mpas_cice_constants.o: mpas_cice_kinds_mod.o
+mpas_cice_dynamics_shared.o: mpas_cice_testing.o
 
-mpas_cice_domain_size.o: mpas_cice_kinds_mod.o
+mpas_cice_dynamics_evp_tri.o: mpas_cice_testing.o mpas_cice_dynamics_shared.o
 
-mpas_cice_state.o: mpas_cice_kinds_mod.o mpas_cice_domain_size.o
+mpas_cice_dynamics_evp_hex.o: mpas_cice_testing.o mpas_cice_dynamics_shared.o
 
-mpas_cice_init.o: mpas_cice_state.o
+mpas_cice_time_integration.o:
 
-mpas_cice_test.o: mpas_cice_kinds_mod.o mpas_cice_constants.o
+mpas_cice_mpas_core.o: mpas_cice_dynamics_evp_hex.o mpas_cice_dynamics_evp_tri.o mpas_cice_time_integration.o
 
-mpas_cice_timestep.o: mpas_cice_kinds_mod.o mpas_cice_test.o 
-
-mpas_cice_mpas_core.o: mpas_cice_test.o mpas_cice_init.o mpas_cice_timestep.o
-
 clean:
         $(RM) *.o *.mod *.f90 libdycore.a
 

Modified: branches/cice_projects/initial_cice_core/src/core_cice/Registry
===================================================================
--- branches/cice_projects/initial_cice_core/src/core_cice/Registry        2013-04-19 17:49:14 UTC (rev 2779)
+++ branches/cice_projects/initial_cice_core/src/core_cice/Registry        2013-04-19 18:44:55 UTC (rev 2780)
@@ -36,14 +36,12 @@
 dim vertexDegree vertexDegree
 dim nVertLevels nVertLevels
 dim nTracers nTracers
-dim nCategories nCategories
-dim nIceLayers nIceLayers
-dim nSnowLayers nSnowLayers
 
 %
 % var persistence type  name_in_file  ( dims )  time_levs iro-  name_in_code struct super-array array_class
 %
 var persistent text    xtime ( Time ) 2 ro xtime state - -
+var persistent integer somevar ( TWO ) 2 - somevar state - -
 
 var persistent real    latCell ( nCells ) 0 iro latCell mesh - -
 var persistent real    lonCell ( nCells ) 0 iro lonCell mesh - -
@@ -96,6 +94,7 @@
 var persistent real    fEdge ( nEdges ) 0 iro fEdge mesh - -
 var persistent real    fVertex ( nVertices ) 0 iro fVertex mesh - -
 var persistent real    fCell ( nCells ) 0 iro fCell mesh - -
+var persistent real    h_s ( nCells ) 0 iro h_s mesh - -
 
 % Space needed for advection
 var persistent real    deriv_two ( FIFTEEN TWO nEdges ) 0 o deriv_two mesh - -
@@ -104,37 +103,148 @@
 % !! NOTE: the following arrays are needed to allow the use
 % !! of the module_advection.F w/o alteration
 % Space needed for deformation calculation weights
-%var persistent real    defc_a ( maxEdges nCells ) 0 - defc_a mesh - -
-%var persistent real    defc_b ( maxEdges nCells ) 0 - defc_b mesh - -
-%var persistent real    kdiff ( nVertLevels nCells Time ) 0 - kdiff mesh - -
+var persistent real    defc_a ( maxEdges nCells ) 0 - defc_a mesh - -
+var persistent real    defc_b ( maxEdges nCells ) 0 - defc_b mesh - -
+var persistent real    kdiff ( nVertLevels nCells Time ) 0 - kdiff mesh - -
 
 % Arrays required for reconstruction of velocity field
 var persistent real    coeffs_reconstruct ( R3 maxEdges nCells ) 0 - coeffs_reconstruct mesh - -
 
 % Boundary conditions: read from input, saved in restart and written to output
-%var persistent integer boundaryEdge ( nVertLevels nEdges ) 0 iro boundaryEdge mesh - -
-%var persistent integer boundaryVertex ( nVertLevels nVertices ) 0 iro boundaryVertex mesh - -
-%var persistent integer boundaryCell ( nVertLevels nCells ) 0 iro boundaryCell mesh - -
-%var persistent real    u_src ( nVertLevels nEdges ) 0 iro u_src mesh - -
+var persistent integer boundaryEdge ( nVertLevels nEdges ) 0 iro boundaryEdge mesh - -
+var persistent integer boundaryVertex ( nVertLevels nVertices ) 0 iro boundaryVertex mesh - -
+var persistent integer boundaryCell ( nVertLevels nCells ) 0 iro boundaryCell mesh - -
+var persistent real    u_src ( nVertLevels nEdges ) 0 iro u_src mesh - -
 
-%--------------------------------------------------------------------------------------
+%-------------------------------------------------------------------
+% ice state
+var persistent real    iceAreaCell ( nCells ) 0 - iceAreaCell icestate - -
+var persistent real    iceAreaVertex ( nVertices ) 0 - iceAreaVertex icestate - -
+var persistent real    iceVolumeCell ( nCells ) 0 - iceVolumeCell icestate - -
+var persistent real    totalMassCell ( nCells ) 0 - totalMassCell icestate - -
+var persistent real    totalMassVertex ( nVertices ) 0 - totalMassVertex icestate - -
 
-% state
-var persistent real    iceAreaCell ( nCells ) 0 - iceAreaCell states - -
-var persistent real    iceVolumeCell ( nCells ) 0 - iceVolumeCell states - -
-var persistent real    snowVolumeCell ( nCells ) 0 - snowVolumeCell states - -
-var persistent real    iceAreaCategory ( nCells nCategories ) 0 - iceAreaCategory states - -
-var persistent real    iceVolumeCategory ( nCells nCategories ) 0 - iceVolumeCategory states - -
-var persistent real    snowVolumeCategory ( nCells nCategories ) 0 - snowVolumeCategory states - -
+% ice dynamics
+var persistent real    uVelocity ( nCells ) 0 - uVelocity dynamics - -
+var persistent real    vVelocity ( nCells ) 0 - vVelocity dynamics - -
+var persistent real    icePressure ( nCells ) 0 - icePressure dynamics - -
+var persistent real    stress1 ( vertexDegree nVertices ) 0 - stress1 dynamics - -
+var persistent real    stress2 ( vertexDegree nVertices ) 0 - stress2 dynamics - -
+var persistent real    stress12 ( vertexDegree nVertices ) 0 - stress12 dynamics - -
+var persistent real    stressDivergenceU ( nCells ) 0 - stressDivergenceU dynamics - -
+var persistent real    stressDivergenceV ( nCells ) 0 - stressDivergenceV dynamics - -
+var persistent real    airStressU ( nCells ) 0 - airStressU dynamics - -
+var persistent real    airStressV ( nCells ) 0 - airStressV dynamics - -
+var persistent real    oceanStressU ( nCells ) 0 - oceanStressU dynamics - -
+var persistent real    oceanStressV ( nCells ) 0 - oceanStressV dynamics - -
+var persistent real    oceanStressCoeff ( nCells ) 0 - oceanStressCoeff dynamics - -
+var persistent real    surfaceTiltForceU ( nCells ) 0 - surfaceTiltForceU dynamics - -
+var persistent real    surfaceTiltForceV ( nCells ) 0 - surfaceTiltForceV dynamics - -
 
-% tracers
-var persistent real    iceEnthalpy ( nIceLayers nCategories nCells ) 0 - iceEnthalpy tracer iceVolumeLayerTracers tracers
-var persistent real    iceSalinity ( nIceLayers nCategories nCells ) 0 - iceSalinity tracer iceVolumeLayerTracers tracers
-var persistent real    snowEnthalpy ( nSnowLayers nCategories nCells ) 0 - snowEnthalpy tracer snowVolumeLayerTracers wibble
-var persistent real    snowSalinity ( nSnowLayers nCategories nCells ) 0 - snowSalinity tracer snowVolumeLayerTracers wibble
+% basis
+var persistent real    basisGradientU ( vertexDegree nVertices ) 0 - basisGradientU basis - -
+var persistent real    basisGradientV ( vertexDegree nVertices ) 0 - basisGradientV basis - -
+var persistent real    basisIntegrals ( vertexDegree nVertices ) 0 - basisIntegrals basis - -
+var persistent integer triangleCornerAtCellCenter ( maxEdges nCells ) 0 - triangleCornerAtCellCenter basis - -
+var persistent integer edgeOppositeTriangleCorner ( vertexDegree nVertices ) 0 - edgeOppositeTriangleCorner basis - -
 
-% flux
-var persistent real    seaSurfaceTemperature ( nCells ) 0 - seaSurfaceTemperature flux - -
-var persistent real    seaFreezingTemperature ( nCells ) 0 - seaFreezingTemperature flux - -
-var persistent real    iceLateralMeltFraction ( nCells ) 0 - iceLateralMeltFraction flux - -
-var persistent real    seaFreezeMeltPotential ( nCells ) 0 - seaFreezeMeltPotential flux - -
+% forcing
+var persistent real    uAirVelocity ( nCells ) 0 - uAirVelocity forcing - -
+var persistent real    vAirVelocity ( nCells ) 0 - vAirVelocity forcing - -
+var persistent real    uOceanVelocity ( nCells ) 0 - uOceanVelocity forcing - -
+var persistent real    vOceanVelocity ( nCells ) 0 - vOceanVelocity forcing - -
+
+% boundary
+var persistent integer boundaryCell ( nCells ) 0 - boundaryCell boundary - -
+var persistent integer boundaryCell2 ( nCells ) 0 - boundaryCell2 boundary - -
+var persistent integer boundaryEdge ( nEdges ) 0 - boundaryEdge boundary - -
+var persistent integer boundaryVertex ( nVertices ) 0 - boundaryVertex boundary - -
+var persistent integer boundaryVertex2 ( nVertices ) 0 - boundaryVertex2 boundary - -
+var persistent integer interiorVertex ( nVertices ) 0 - interiorVertex boundary - -
+var persistent integer interiorVertex2 ( nVertices ) 0 - interiorVertex2 boundary - -
+
+%-------------------------------------------------------------------
+% hex basis
+%var persistent real    xLocal ( maxEdges nCells ) 0 - xLocal hexbas - -
+%var persistent real    yLocal ( maxEdges nCells ) 0 - yLocal hexbas - -
+%var persistent real    wachspressA ( maxEdges nCells ) 0 - wachspressA hexbas - -
+%var persistent real    wachspressB ( maxEdges nCells ) 0 - wachspressB hexbas - -
+%var persistent real    wachspressKappa ( maxEdges maxEdges nCells ) 0 - wachspressKappa hexbas - -
+%var persistent real    basisIntegralsU ( maxEdges maxEdges nCells ) 0 - basisIntegralsU hexbas - -
+%var persistent real    basisIntegralsV ( maxEdges maxEdges nCells ) 0 - basisIntegralsV hexbas - -
+%var persistent real    basisGradientU ( maxEdges maxEdges nCells ) 0 - basisGradientU hexbas - -
+%var persistent real    basisGradientV ( maxEdges maxEdges nCells ) 0 - basisGradientV hexbas - -
+%var persistent integer cellVerticesAtVertex ( vertexDegree nVertices ) 0 - cellVerticesAtVertex hexbas - -
+
+var persistent real    xLocal ( vertexDegree nVertices ) 0 - xLocal hexbas - -
+var persistent real    yLocal ( vertexDegree nVertices ) 0 - yLocal hexbas - -
+var persistent real    wachspressA ( vertexDegree nVertices ) 0 - wachspressA hexbas - -
+var persistent real    wachspressB ( vertexDegree nVertices ) 0 - wachspressB hexbas - -
+var persistent real    wachspressKappa ( vertexDegree vertexDegree nVertices ) 0 - wachspressKappa hexbas - -
+var persistent real    basisIntegralsU ( vertexDegree vertexDegree nVertices ) 0 - basisIntegralsU hexbas - -
+var persistent real    basisIntegralsV ( vertexDegree vertexDegree nVertices ) 0 - basisIntegralsV hexbas - -
+var persistent real    basisGradientU ( vertexDegree vertexDegree nVertices ) 0 - basisGradientU hexbas - -
+var persistent real    basisGradientV ( vertexDegree vertexDegree nVertices ) 0 - basisGradientV hexbas - -
+var persistent integer cellVerticesAtVertex ( maxEdges nCells ) 0 - cellVerticesAtVertex hexbas - -
+
+
+% hex dynamics
+var persistent real    uVelocity ( nVertices ) 0 - uVelocity hexdyn - -
+var persistent real    vVelocity ( nVertices ) 0 - vVelocity hexdyn - -
+var persistent real    icePressure ( nCells ) 0 - icePressure hexdyn - -
+%var persistent real    stress1 ( maxEdges nCells ) 0 - stress1 hexdyn - -
+%var persistent real    stress2 ( maxEdges nCells ) 0 - stress2 hexdyn - -
+%var persistent real    stress12 ( maxEdges nCells ) 0 - stress12 hexdyn - -
+%var persistent real    stressDivergenceU ( nVertices ) 0 - stressDivergenceU hexdyn - -
+%var persistent real    stressDivergenceV ( nVertices ) 0 - stressDivergenceV hexdyn - -
+var persistent real    airStressU ( nVertices ) 0 - airStressU hexdyn - -
+var persistent real    airStressV ( nVertices ) 0 - airStressV hexdyn - -
+var persistent real    oceanStressU ( nVertices ) 0 - oceanStressU hexdyn - -
+var persistent real    oceanStressV ( nVertices ) 0 - oceanStressV hexdyn - -
+var persistent real    oceanStressCoeff ( nVertices ) 0 - oceanStressCoeff hexdyn - -
+var persistent real    surfaceTiltForceU ( nVertices ) 0 - surfaceTiltForceU hexdyn - -
+var persistent real    surfaceTiltForceV ( nVertices ) 0 - surfaceTiltForceV hexdyn - -
+
+var persistent real    stress1 ( vertexDegree nVertices ) 0 - stress1 hexdyn - -
+var persistent real    stress2 ( vertexDegree nVertices ) 0 - stress2 hexdyn - -
+var persistent real    stress12 ( vertexDegree nVertices ) 0 - stress12 hexdyn - -
+var persistent real    stressDivergenceU ( nCells ) 0 - stressDivergenceU hexdyn - -
+var persistent real    stressDivergenceV ( nCells ) 0 - stressDivergenceV hexdyn - -
+
+% hex forcing
+var persistent real    uAirVelocity ( nVertices ) 0 - uAirVelocity hexfor - -
+var persistent real    vAirVelocity ( nVertices ) 0 - vAirVelocity hexfor - -
+var persistent real    uOceanVelocity ( nVertices ) 0 - uOceanVelocity hexfor - -
+var persistent real    vOceanVelocity ( nVertices ) 0 - vOceanVelocity hexfor - -
+
+%-------------------------------------------------------------------
+% weak integral formulation
+var persistent real    uVelocity ( nVertices ) 0 - uVelocity weak - -
+var persistent real    vVelocity ( nVertices ) 0 - vVelocity weak - -
+var persistent real    icePressure ( nCells ) 0 - icePressure weak - -
+var persistent real    strain11 ( nCells ) 0 - strain11 weak - -
+var persistent real    strain22 ( nCells ) 0 - strain22 weak - -
+var persistent real    strain12 ( nCells ) 0 - strain12 weak - -
+var persistent real    stress11 ( nCells ) 0 - stress11 weak - -
+var persistent real    stress22 ( nCells ) 0 - stress22 weak - -
+var persistent real    stress12 ( nCells ) 0 - stress12 weak - -
+var persistent real    principalStress1 ( nCells ) 0 - principalStress1 weak - -
+var persistent real    principalStress2 ( nCells ) 0 - principalStress2 weak - -
+var persistent real    stressDivergenceU ( nVertices ) 0 - stressDivergenceU weak - -
+var persistent real    stressDivergenceV ( nVertices ) 0 - stressDivergenceV weak - -
+var persistent real    normalVectorPolygon ( TWO maxEdges nCells ) 0 - normalVectorPolygon weak - -
+var persistent real    normalVectorTriangle ( TWO vertexDegree nVertices ) 0 - normalVectorTriangle weak - -
+
+
+var persistent real    airStressU ( nVertices ) 0 - airStressU weak - -
+var persistent real    airStressV ( nVertices ) 0 - airStressV weak - -
+var persistent real    oceanStressU ( nVertices ) 0 - oceanStressU weak - -
+var persistent real    oceanStressV ( nVertices ) 0 - oceanStressV weak - -
+var persistent real    oceanStressCoeff ( nVertices ) 0 - oceanStressCoeff weak - -
+var persistent real    surfaceTiltForceU ( nVertices ) 0 - surfaceTiltForceU weak - -
+var persistent real    surfaceTiltForceV ( nVertices ) 0 - surfaceTiltForceV weak - -
+
+var persistent real    uAirVelocity ( nVertices ) 0 - uAirVelocity weak - -
+var persistent real    vAirVelocity ( nVertices ) 0 - vAirVelocity weak - -
+var persistent real    uOceanVelocity ( nVertices ) 0 - uOceanVelocity weak - -
+var persistent real    vOceanVelocity ( nVertices ) 0 - vOceanVelocity weak - -

Deleted: branches/cice_projects/initial_cice_core/src/core_cice/mpas_cice_constants.F
===================================================================
--- branches/cice_projects/initial_cice_core/src/core_cice/mpas_cice_constants.F        2013-04-19 17:49:14 UTC (rev 2779)
+++ branches/cice_projects/initial_cice_core/src/core_cice/mpas_cice_constants.F        2013-04-19 18:44:55 UTC (rev 2780)
@@ -1,242 +0,0 @@
-!=======================================================================
-!BOP
-!
-! !MODULE: ice_constants - sets physical constants
-!
-! !DESCRIPTION:
-!
-! This module defines a variety of physical and numerical constants
-! used throughout the ice model \\
-!
-! Code originally based on constants.F in POP
-!
-! !REVISION HISTORY:
-!  SVN:$Id: ice_constants.F90 567 2013-01-07 02:57:36Z eclare $
-!
-! author Elizabeth C. Hunke, LANL
-!
-! !INTERFACE:
-
-      module cice_constants
-!
-! !USES:
-!
-      use cice_kinds_mod
-!
-!EOP
-!
-      implicit none
-      !save
-
-      !-----------------------------------------------------------------
-      ! physical constants
-      !-----------------------------------------------------------------
-
-#ifdef AOMIP
-      real (kind=dbl_kind), parameter :: &amp;
-         rhos      = 300.0_dbl_kind   ,&amp;! density of snow (kg/m^3)
-         rhoi      = 900.0_dbl_kind   ,&amp;! density of ice (kg/m^3)
-         rhow      = 1025.0_dbl_kind  ,&amp;! density of seawater (kg/m^3)
-         cp_air    = 1004.0_dbl_kind  ,&amp;! specific heat of air (J/kg/K)
-         emissivity= 0.98_dbl_kind    ,&amp;! emissivity of snow and ice
-         cp_ice    = 2090._dbl_kind   ,&amp;! specific heat of fresh ice (J/kg/K)
-         cp_brine  = 4650._dbl_kind   ,&amp;! specific heat of brine (J/kg/K) 
-                                        ! from Taylor and Feltham (2004)
-         cp_ocn    = 4190._dbl_kind   ,&amp;! specific heat of ocn    (J/kg/K)
-         depressT  = 0.0575_dbl_kind  ,&amp;! Tf:brine salinity ratio (C/ppt)
-         dragio    = 0.0055_dbl_kind  ,&amp;! ice-ocn drag coefficient
-         albocn    = 0.10_dbl_kind      ! ocean albedo
-#else
-! CICE default parameters
-      real (kind=dbl_kind), parameter :: &amp;
-         rhos      = 330.0_dbl_kind   ,&amp;! density of snow (kg/m^3)
-         rhoi      = 917.0_dbl_kind   ,&amp;! density of ice (kg/m^3)
-         rhow      = 1026.0_dbl_kind  ,&amp;! density of seawater (kg/m^3)
-         cp_air    = 1005.0_dbl_kind  ,&amp;! specific heat of air (J/kg/K)
-         ! (Briegleb JGR 97 11475-11485  July 1992)
-         emissivity= 0.95_dbl_kind    ,&amp;! emissivity of snow and ice
-         cp_ice    = 2106._dbl_kind   ,&amp;! specific heat of fresh ice (J/kg/K)
-         cp_ocn    = 4218._dbl_kind   ,&amp;! specific heat of ocn    (J/kg/K)
-                                        ! freshwater value needed for enthalpy
-         depressT  = 0.054_dbl_kind   ,&amp;! Tf:brine salinity ratio (C/ppt)
-         dragio    = 0.00536_dbl_kind ,&amp;! ice-ocn drag coefficient
-         albocn    = 0.06_dbl_kind      ! ocean albedo
-#endif
-
-! UNESCO melting temperature parameters
-      real (kind=dbl_kind), parameter :: &amp;
-         mlt_a     = 0.0575_dbl_kind       ,&amp; !nonlinear melting T coefficient (oC/ppt)
-         mlt_b     = 1.710523e-3_dbl_kind  ,&amp; !(oC/ppt^(3/2))
-         mlt_c     = 2.154996e-4_dbl_kind     !(oC/ppt^2)
-          
-
-      real (kind=dbl_kind), parameter :: &amp;
-         gravit    = 9.80616_dbl_kind    ,&amp;! gravitational acceleration (m/s^2)
-         omega     = 7.292e-5_dbl_kind   ,&amp;! angular velocity of earth (rad/sec)
-         radius    = 6.37e6_dbl_kind       ! earth radius (m)
-
-      real (kind=dbl_kind), parameter :: &amp;
-         pi = 3.14159265358979323846_dbl_kind,&amp;! pi
-         secday    = 86400.0_dbl_kind ,&amp;! seconds in calendar day
-         Tocnfrz   = -1.8_dbl_kind    ,&amp;! freezing temp of seawater (C),
-                                        ! used as Tsfcn for open water
-         rhofresh  = 1000.0_dbl_kind  ,&amp;! density of fresh water (kg/m^3)
-         zvir      = 0.606_dbl_kind   ,&amp;! rh2o/rair - 1.0
-         vonkar    = 0.4_dbl_kind     ,&amp;! von Karman constant
-         cp_wv     = 1.81e3_dbl_kind  ,&amp;! specific heat of water vapor (J/kg/K)
-         stefan_boltzmann = 567.0e-10_dbl_kind,&amp;!  W/m^2/K^4
-         Tffresh   = 273.15_dbl_kind  ,&amp;! freezing temp of fresh ice (K)
-         Lsub      = 2.835e6_dbl_kind ,&amp;! latent heat, sublimation freshwater (J/kg)
-         Lvap      = 2.501e6_dbl_kind ,&amp;! latent heat, vaporization freshwater (J/kg)
-         Lfresh    = Lsub-Lvap        ,&amp;! latent heat of melting of fresh ice (J/kg)
-         Timelt    = 0.0_dbl_kind     ,&amp;! melting temperature, ice top surface  (C)
-         Tsmelt    = 0.0_dbl_kind     ,&amp;! melting temperature, snow top surface (C)
-         ice_ref_salinity = 4._dbl_kind ,&amp;! (ppt)
-!        ocn_ref_salinity = 34.7_dbl_kind,&amp;! (ppt)
-!        rho_air   = 1.2_dbl_kind     ,&amp;! ambient air density (kg/m^3)
-         spval_dbl = 1.0e30_dbl_kind    ! special value (double precision)
-
-      real (kind=real_kind), parameter :: &amp;
-         spval     = 1.0e30_real_kind   ! special value for netCDF output
-
-      real (kind=dbl_kind), parameter :: &amp;
-         iceruf   = 0.0005_dbl_kind   ,&amp;! ice surface roughness (m)
-
-         ! (Ebert, Schramm and Curry JGR 100 15965-15975 Aug 1995)
-         kappav = 1.4_dbl_kind ,&amp;! vis extnctn coef in ice, wvlngth&lt;700nm (1/m)
-         kappan = 17.6_dbl_kind,&amp;! vis extnctn coef in ice, wvlngth&lt;700nm (1/m)
-
-         kice   = 2.03_dbl_kind  ,&amp;! thermal conductivity of fresh ice(W/m/deg)
-         kseaice= 2.00_dbl_kind  ,&amp;! thermal conductivity of sea ice (W/m/deg)
-                                   ! (used in zero layer thermodynamics option)
-         ksno   = 0.30_dbl_kind  ,&amp;! thermal conductivity of snow  (W/m/deg)
-         zref   = 10._dbl_kind   ,&amp;! reference height for stability (m)
-         hsmin  = 0.0001_dbl_kind,&amp;! minimum allowed snow depth (m) for DE
-         snowpatch = 0.02_dbl_kind,&amp;! parameter for fractional snow area (m)
-         salt_loss = 0.65_dbl_kind ! zbgc fraction of available salt retained (1.0 = no loss)
-                    
-      ! weights for albedos 
-! 4 Jan 2007 BPB  Following are appropriate for complete cloud
-! in a summer polar atmosphere with 1.5m bare sea ice surface:
-! .636/.364 vis/nir with only 0.5% direct for each band.
-      real (kind=dbl_kind), parameter :: &amp;           ! currently used only
-         awtvdr = 0.00318_dbl_kind, &amp;! visible, direct  ! for history and
-         awtidr = 0.00182_dbl_kind, &amp;! near IR, direct  ! diagnostics
-         awtvdf = 0.63282_dbl_kind, &amp;! visible, diffuse
-         awtidf = 0.36218_dbl_kind   ! near IR, diffuse
-
-      real (kind=dbl_kind), parameter :: &amp;
-         qqqice  = 11637800._dbl_kind   ,&amp;! for qsat over ice
-         TTTice  = 5897.8_dbl_kind      ,&amp;! for qsat over ice
-         qqqocn  = 627572.4_dbl_kind    ,&amp;! for qsat over ocn
-         TTTocn  = 5107.4_dbl_kind        ! for qsat over ocn
-
-      ! these are currently set so as to have no effect on the decomposition
-      real (kind=dbl_kind), parameter :: &amp;
-         shlat  =  30.0_dbl_kind   ,&amp;! artificial masking edge (deg)
-         nhlat  = -30.0_dbl_kind     ! artificial masking edge (deg)
-   
-      !-----------------------------------------------------------------
-      ! numbers
-      !-----------------------------------------------------------------
-
-      real (kind=dbl_kind), parameter :: &amp;
-        c0   = 0.0_dbl_kind, &amp;
-        c1   = 1.0_dbl_kind, &amp;
-        c1p5 = 1.5_dbl_kind, &amp;
-        c2   = 2.0_dbl_kind, &amp;
-        c3   = 3.0_dbl_kind, &amp;
-        c4   = 4.0_dbl_kind, &amp;
-        c5   = 5.0_dbl_kind, &amp;
-        c6   = 6.0_dbl_kind, &amp;
-        c8   = 8.0_dbl_kind, &amp;
-        c9   = 9.0_dbl_kind, &amp;
-        c10  = 10.0_dbl_kind, &amp;
-        c12  = 12.0_dbl_kind, &amp;
-        c15  = 15.0_dbl_kind, &amp;
-        c16  = 16.0_dbl_kind, &amp;
-        c20  = 20.0_dbl_kind, &amp;
-        c25  = 25.0_dbl_kind, &amp;
-        c30  = 30.0_dbl_kind, &amp;
-        c100 = 100.0_dbl_kind, &amp;
-        c180 = 180.0_dbl_kind, &amp;
-        c360 = 360.0_dbl_kind, &amp;
-        c365 = 365.0_dbl_kind, &amp;
-        c400 = 400.0_dbl_kind, &amp;
-        c3600= 3600.0_dbl_kind, &amp;
-        c1000= 1000.0_dbl_kind, &amp;
-        p001 = 0.001_dbl_kind, &amp;
-        p01  = 0.01_dbl_kind, &amp;
-        p025 = 0.025_dbl_kind, &amp;
-        p1   = 0.1_dbl_kind, &amp;
-        p2   = 0.2_dbl_kind, &amp;
-        p4   = 0.4_dbl_kind, &amp;
-        p5   = 0.5_dbl_kind, &amp;
-        p6   = 0.6_dbl_kind, &amp;
-        p05  = 0.05_dbl_kind, &amp;
-        p15  = 0.15_dbl_kind, &amp;
-        p25  = 0.25_dbl_kind, &amp;
-        p75  = 0.75_dbl_kind, &amp;
-        p166 = c1/c6, &amp;
-        p333 = c1/c3, &amp;
-        p666 = c2/c3, &amp;
-        p111 = c1/c9, &amp;
-        p055 = p111*p5, &amp;
-        p027 = p055*p5, &amp;
-        p222 = c2/c9, &amp;
-        eps11  = 1.0e-11_dbl_kind, &amp;
-        eps13  = 1.0e-13_dbl_kind, &amp;
-        eps16  = 1.0e-16_dbl_kind, &amp;
-        puny   = eps11, &amp;
-        bignum = 1.0e+30_dbl_kind, &amp;
-        pih    = p5*pi, &amp;
-        piq    = p5*pih, &amp;
-        pi2    = c2*pi, &amp;
-        days_per_4c = 146097.0_dbl_kind, &amp;
-        days_per_c  = 36524.0_dbl_kind,  &amp;
-        days_per_4y = 1461.0_dbl_kind,   &amp;
-        days_per_y  = 365.0_dbl_kind
-
-      !-----------------------------------------------------------------
-      ! location of fields for staggered grids
-      !-----------------------------------------------------------------
-
-      integer (int_kind), parameter :: &amp;   
-        field_loc_unknown  =  0, &amp; 
-        field_loc_noupdate = -1, &amp; 
-        field_loc_center   =  1, &amp; 
-        field_loc_NEcorner =  2, &amp; 
-        field_loc_Nface    =  3, &amp; 
-        field_loc_Eface    =  4, &amp;
-        field_loc_Wface    =  5
-
-
-      !-----------------------------------------------------------------
-      ! field type attribute - necessary for handling
-      ! changes of direction across tripole boundary
-      !-----------------------------------------------------------------
-
-      integer (int_kind), parameter :: &amp;   
-        field_type_unknown  =  0, &amp; 
-        field_type_noupdate = -1, &amp; 
-        field_type_scalar   =  1, &amp; 
-        field_type_vector   =  2, &amp; 
-        field_type_angle    =  3
-
-      !-----------------------------------------------------------------
-      ! conversion factors
-      !-----------------------------------------------------------------
-
-      real (kind=dbl_kind), parameter :: &amp;
-        cm_to_m       = 0.01_dbl_kind   ,&amp;! cm to meters
-        m_to_cm       = 100._dbl_kind   ,&amp;! meters to cm
-        m2_to_km2     = 1.e-6_dbl_kind  ,&amp;! m^2 to km^2
-        kg_to_g       = 1000._dbl_kind  ,&amp;! kilograms to grams
-        mps_to_cmpdy  = 8.64e6_dbl_kind ,&amp;! m per s to cm per day
-        rad_to_deg    = 180._dbl_kind/pi  ! degree-radian conversion
-
-!=======================================================================
-
-      end module cice_constants
-
-!=======================================================================

Deleted: branches/cice_projects/initial_cice_core/src/core_cice/mpas_cice_domain_size.F
===================================================================
--- branches/cice_projects/initial_cice_core/src/core_cice/mpas_cice_domain_size.F        2013-04-19 17:49:14 UTC (rev 2779)
+++ branches/cice_projects/initial_cice_core/src/core_cice/mpas_cice_domain_size.F        2013-04-19 18:44:55 UTC (rev 2780)
@@ -1,102 +0,0 @@
-!=======================================================================
-!BOP
-!
-! !MODULE: ice_domain_size
-!
-! !DESCRIPTION:
-!
-! Defines the global domain size and number of categories and layers.
-! Code originally based on domain_size.F in POP
-!
-! !REVISION HISTORY:
-!  SVN:$Id: ice_domain_size.F90 574 2013-01-13 16:20:47Z eclare $
-!
-! author Elizabeth C. Hunke, LANL
-! 2004: Block structure and snow parameters added by William Lipscomb
-!       Renamed (used to be ice_model_size)
-! 2006: Converted to free source form (F90) by Elizabeth Hunke
-!       Removed hardwired sizes (NX...can now be set in compile scripts)
-!
-! !INTERFACE:
-!
-      module cice_domain_size
-!
-! !USES:
-!
-      use cice_kinds_mod
-!
-!EOP
-!=======================================================================
-
-      implicit none
-      save
-
-      ! added instead of preprocessor
-      integer (kind=int_kind), parameter :: &amp;
-           NXGLOB  = 1 , &amp; 
-           NYGLOB  = 1 , &amp; 
-           NICECAT = 1 , &amp; 
-           NICELYR = 4 , &amp; 
-           NSNWLYR = 1 , &amp; 
-           NTRAERO = 0 , &amp; 
-           NBGCLYR = 1 , &amp; 
-           TRAGE   = 0 , &amp; 
-           TRFY    = 0 , &amp; 
-           TRLVL   = 0 , &amp; 
-           TRPND   = 0 , &amp; 
-           TRBRI   = 0 , &amp; 
-           BLCKX   = 1 , &amp; 
-           BLCKY   = 1 , &amp; 
-           MXBLCKS = 1
-
-      integer (kind=int_kind), parameter :: &amp;
-        nx_global = NXGLOB    , &amp; ! i-axis size
-        ny_global = NYGLOB    , &amp; ! j-axis size
-        ncat      = NICECAT   , &amp; ! number of categories
-        nilyr     = NICELYR   , &amp; ! number of ice layers per category
-        nslyr     = NSNWLYR   , &amp; ! number of snow layers per category
-        max_aero  =   6       , &amp; ! maximum number of aerosols 
-        n_aero    = NTRAERO   , &amp; ! number of aerosols in use
-
-        nblyr     = NBGCLYR   , &amp; ! number of biology layers per category
-        nblyr_hist = nblyr+2  , &amp; ! number of ice layer plus boundary points
-        nltrcr    = 6         , &amp; ! number of layer bgc tracers  
-                                  ! number of biology layer tracers      
-        nbltrcr   = 1         , &amp; ! 4 basic bio;  1 nitrate only 
-
-                                  ! number of tracers (defined in ice_init)
-        max_ntrcr =   1         &amp; ! 1 = surface temperature              
-                  + nilyr       &amp; ! ice salinity
-                  + nilyr       &amp; ! ice enthalpy
-                  + nslyr       &amp; ! snow enthalpy
-                              !!!!! optional tracers:
-                  + TRAGE       &amp; ! age
-                  + TRFY        &amp; ! first-year area
-                  + TRLVL*2     &amp; ! level/deformed ice
-                  + TRPND*3     &amp; ! ponds
-                  + n_aero*4    &amp; ! number of aerosols * 4 aero layers
-                  + TRBRI       &amp; ! brine height
-                  + TRBRI*nltrcr*nblyr,&amp;! zbgc (off if TRBRI=0)
-        max_nstrm =   5           ! max number of history output streams
-
-      integer (kind=int_kind), parameter :: &amp;
-        block_size_x = BLCKX  , &amp; ! size of block in first horiz dimension
-        block_size_y = BLCKY      ! size of block in second horiz dimension
-
-   !*** The model will inform the user of the correct
-   !*** values for the parameter below.  A value higher than
-   !*** necessary will not cause the code to fail, but will
-   !*** allocate more memory than is necessary.  A value that
-   !*** is too low will cause the code to exit.  
-   !*** A good initial guess is found using
-   !*** max_blocks = (nx_global/block_size_x)*(ny_global/block_size_y)/
-   !***               num_procs

-      integer (kind=int_kind), parameter :: &amp;
-        max_blocks = MXBLCKS      ! max number of blocks per processor
-
-!=======================================================================
-
-      end module cice_domain_size
-
-!=======================================================================

Added: branches/cice_projects/initial_cice_core/src/core_cice/mpas_cice_dynamics_evp_hex.F
===================================================================
--- branches/cice_projects/initial_cice_core/src/core_cice/mpas_cice_dynamics_evp_hex.F                                (rev 0)
+++ branches/cice_projects/initial_cice_core/src/core_cice/mpas_cice_dynamics_evp_hex.F        2013-04-19 18:44:55 UTC (rev 2780)
@@ -0,0 +1,1430 @@
+module cice_dynamics_evp_hex
+
+  use mpas_grid_types
+
+  implicit none
+
+  private
+  public :: init_hexagonal_basis, &amp;
+            test_divergence_stress_tensor
+
+contains
+
+  !-------------------------------------------------------------
+
+  subroutine init_hexagonal_basis(mesh, hexbas, boundary)
+
+    use cice_testing, only: writeout_edgecell, writeout_edgeedgecell
+
+    use cice_dynamics_shared, only: boundary_cells, boundary_vertices
+
+    type(mesh_type), intent(in) :: mesh
+
+    type(hexbas_type),   pointer :: hexbas
+    type(boundary_type), pointer :: boundary
+
+    integer :: iCell, iVertex, jVertex
+
+    real(kind=RKIND) :: &amp;
+         integration
+
+    call calc_local_coords(mesh, &amp;
+         hexbas % xLocal % array, &amp;
+         hexbas % yLocal % array)
+
+    call calc_wachspress_coefficients(mesh, &amp;
+         hexbas % wachspressKappa % array, &amp;
+         hexbas % wachspressA % array, &amp;
+         hexbas % wachspressB % array, &amp;
+         hexbas % xLocal % array, &amp;
+         hexbas % yLocal % array)
+
+    call calculate_wachspress_derivatives(mesh, &amp;
+         hexbas % basisGradientU % array,  &amp;
+         hexbas % basisGradientV % array,  &amp;
+         hexbas % wachspressA % array,     &amp; 
+         hexbas % wachspressB % array,     &amp;
+         hexbas % wachspressKappa % array)
+
+    !call writeout_edgeedgecell(mesh, hexbas % wachspressKappa % array, &quot;wachspressKappa.txt&quot;)
+    !call writeout_edgecell(mesh, hexbas % wachspressA % array, &quot;wachspressA.txt&quot;)
+    !call writeout_edgecell(mesh, hexbas % wachspressB % array, &quot;wachspressB.txt&quot;)
+
+    call integrate_wachspress(mesh, hexbas)
+
+    !call writeout_edgeedgecell(mesh, hexbas % basisIntegralsU % array, &quot;integralsu.txt&quot;)
+    !call writeout_edgeedgecell(mesh, hexbas % basisIntegralsV % array, &quot;integralsv.txt&quot;)
+
+    call calc_cell_vertices_at_vertex(mesh, &amp;
+         hexbas % cellVerticesAtVertex % array)
+
+    !call boundary_cells(mesh, &amp;
+    !     boundary % boundaryCell % array, &amp;
+    !     boundary % boundaryCell2 % array) 
+
+    !call boundary_vertices(mesh, &amp;
+    !     boundary % boundaryVertex % array, &amp;
+    !     boundary % interiorVertex % array, &amp;
+    !     boundary % interiorVertex2 % array, &amp;
+    !     boundary % boundaryCell % array)
+
+  end subroutine init_hexagonal_basis
+  
+  !-------------------------------------------------------------
+
+  subroutine calc_local_coords(mesh, xLocal, yLocal)
+
+    type(mesh_type), intent(in) :: mesh
+
+    real(kind=RKIND), dimension(:,:), intent(out) :: &amp;
+         xLocal, &amp;
+         yLocal
+
+    integer :: &amp;
+         iCell, &amp;
+         iVertex, &amp;
+         iVertexOnCell
+
+    do iCell = 1, mesh % nCells
+
+       do iVertex = 1, mesh % nEdgesOnCell % array(iCell)
+
+          iVertexOnCell = mesh % verticesOnCell % array(iVertex, iCell)
+
+          xLocal(iVertex,iCell) = mesh % xVertex % array(iVertexOnCell) - mesh % xCell % array(iCell)
+          yLocal(iVertex,iCell) = mesh % yVertex % array(iVertexOnCell) - mesh % yCell % array(iCell)
+
+       enddo ! iVertex
+
+    enddo ! iCell
+
+  end subroutine calc_local_coords
+
+  !-------------------------------------------------------------
+
+  subroutine calc_wachspress_coefficients(mesh, wachspressKappa, wachspressA, wachspressB, xLocal, yLocal)
+    
+    type(mesh_type), intent(in) :: mesh
+
+    real(kind=RKIND), dimension(:,:,:), intent(out) :: &amp;
+         wachspressKappa
+
+    real(kind=RKIND), dimension(:,:), intent(out) :: &amp;
+         wachspressA, &amp;
+         wachspressB
+
+    real(kind=RKIND), dimension(:,:), intent(in) :: &amp;
+         xLocal, &amp;
+         yLocal
+
+    integer :: &amp;
+         iCell, &amp;
+         iVertex, &amp;
+         i0, &amp;
+         i1, &amp;
+         i2, &amp;
+         jVertex, &amp;
+         nEdgesOnCell
+
+    ! loop over cells
+    do iCell = 1, mesh % nCells
+
+       ! number of edges
+       nEdgesOnCell = mesh % nEdgesOnCell % array(iCell)
+       
+       ! loop over vertices
+       do iVertex = 1, nEdgesOnCell
+          
+          ! end points of line segment
+          i1 = iVertex - 1
+          i2 = iVertex
+          if (i1 &lt; 1) i1 = i1 + nEdgesOnCell
+          
+          ! solve for the line segment equation
+          wachspressA(iVertex, iCell) = (yLocal(i2,iCell) - yLocal(i1,iCell)) / (xLocal(i1,iCell) * yLocal(i2,iCell) - xLocal(i2,iCell) * yLocal(i1,iCell))
+          wachspressB(iVertex, iCell) = (xLocal(i1,iCell) - xLocal(i2,iCell)) / (xLocal(i1,iCell) * yLocal(i2,iCell) - xLocal(i2,iCell) * yLocal(i1,iCell))
+
+          write(*,*) iCell, iVertex, i1, i2, wachspressA(iVertex, iCell), wachspressB(iVertex, iCell)
+
+       enddo ! iVertex
+
+       ! loop over vertices
+       do iVertex = 1, nEdgesOnCell
+
+          ! determine kappa
+          wachspressKappa(1,iVertex,iCell) = 1.0_RKIND
+
+          do jVertex = 2, nEdgesOnCell
+             
+             ! previous, this and next vertex
+             i0 = jVertex - 1
+             i1 = jVertex
+             i2 = jVertex + 1
+             if (i2 &gt; nEdgesOnCell) i2 = i2 - nEdgesOnCell
+             
+             wachspressKappa(jVertex,iVertex,iCell) = wachspressKappa(jVertex-1,iVertex,iCell) * &amp;
+                  (wachspressA(i2,iCell) * (xLocal(i0,iCell) - xLocal(i1,iCell)) + wachspressB(i2,iCell) * (yLocal(i0,iCell) - yLocal(i1,iCell))) / &amp;
+                  (wachspressA(i0,iCell) * (xLocal(i1,iCell) - xLocal(i0,iCell)) + wachspressB(i0,iCell) * (yLocal(i1,iCell) - yLocal(i0,iCell)))
+
+          enddo ! jVertex
+          
+       enddo ! iVertex
+       
+    enddo ! iCell
+
+  end subroutine calc_wachspress_coefficients
+
+  !-------------------------------------------------------------
+
+  function wachspress_basis_function(nEdgesOnCell, iVertex, x, y, wachspressKappa, wachspressA, wachspressB) result(wachpress)
+
+    integer, intent(in) :: &amp;
+         nEdgesOnCell, &amp;
+         iVertex
+
+    real(kind=RKIND), intent(in) :: &amp;
+         x, &amp;
+         y
+    
+    real(kind=RKIND), dimension(:,:), intent(in) :: &amp;
+         wachspressKappa
+
+    real(kind=RKIND), dimension(:), intent(in) :: &amp;
+         wachspressA, &amp;
+         wachspressB
+
+    real(kind=RKIND) :: &amp;
+         wachpress
+
+    real(kind=RKIND) :: &amp;
+         numerator, &amp;
+         denominator, &amp;
+         numerator_ivertex
+
+    integer :: &amp;
+         jVertex
+
+    ! sum over numerators to get denominator
+    denominator = 0.0_RKIND
+
+    do jVertex = 1, nEdgesOnCell
+
+       numerator = wachspress_numerator(nEdgesOnCell, jVertex, iVertex, x, y, wachspressKappa, wachspressA, wachspressB)
+
+       denominator = denominator + numerator
+
+       if (jvertex == iVertex) then
+          numerator_ivertex = numerator
+       endif
+
+    enddo ! jVertex
+
+    wachpress = numerator_ivertex / denominator
+
+  end function wachspress_basis_function
+
+  !-------------------------------------------------------------
+
+  function wachspress_basis_derivative(nEdgesOnCell, iVertex, x, y, wachspressKappa, wachspressA, wachspressB, iDerivativeType) result(wachspress)
+
+    integer, intent(in) :: &amp;
+         nEdgesOnCell, &amp;
+         iVertex, &amp;
+         iDerivativeType
+
+    real(kind=RKIND), intent(in) :: &amp;
+         x, &amp;
+         y
+    
+    real(kind=RKIND), dimension(:,:), intent(in) :: &amp;
+         wachspressKappa
+
+    real(kind=RKIND), dimension(:), intent(in) :: &amp;
+         wachspressA, &amp;
+         wachspressB
+
+    real(kind=RKIND) :: &amp;
+         wachspress
+
+    real(kind=RKIND) :: &amp;
+         numerator, &amp;
+         derivative, &amp;
+         denominator, &amp;
+         sum_of_derivatives, &amp;
+         numerator_ivertex, &amp;
+         derivative_ivertex
+
+    integer :: &amp;
+         jVertex
+
+    ! sum over numerators to get denominator
+    denominator = 0.0_RKIND
+    sum_of_derivatives = 0.0_RKIND
+
+    do jVertex = 1, nEdgesOnCell
+
+       numerator  = wachspress_numerator(nEdgesOnCell, jVertex, iVertex, x, y, wachspressKappa, wachspressA, wachspressB)
+       derivative = wachspress_numerator_derivative(nEdgesOnCell, jVertex, iVertex, x, y, wachspressKappa, wachspressA, wachspressB, iDerivativeType)
+
+       denominator        = denominator        + numerator
+       sum_of_derivatives = sum_of_derivatives + derivative
+
+       if (jvertex == iVertex) then
+          numerator_ivertex  = numerator
+          derivative_ivertex = derivative
+       endif
+
+    enddo ! jVertex
+
+    wachspress = derivative_ivertex / denominator - (numerator_ivertex / denominator**2) * sum_of_derivatives
+
+  end function wachspress_basis_derivative
+
+  !-------------------------------------------------------------
+
+  function wachspress_numerator(nEdgesOnCell, jVertex, iVertex, x, y, wachspressKappa, wachspressA, wachspressB) result(numerator)
+
+    integer, intent(in) :: &amp;
+         nEdgesOnCell, &amp;
+         jVertex, &amp;
+         iVertex
+
+    real(kind=RKIND), intent(in) :: &amp;
+         x, &amp;
+         y
+    
+    real(kind=RKIND), dimension(:,:), intent(in) :: &amp;
+         wachspressKappa
+
+    real(kind=RKIND), dimension(:), intent(in) :: &amp;
+         wachspressA, &amp;
+         wachspressB
+
+    real(kind=RKIND) :: numerator
+
+    integer :: &amp;
+         kVertex, &amp;
+         i1, &amp;
+         i2
+    
+    i1 = jVertex 
+    i2 = jVertex + 1
+    if (i2 &gt; nEdgesOnCell) i2 = i2 - nEdgesOnCell
+
+    numerator = 1.0_RKIND
+
+    do kVertex = 1, nEdgesOnCell
+
+       if (kVertex /= i1 .and. kVertex /= i2) then
+          numerator = numerator * wachspress_edge_equation(kVertex, x, y, wachspressA, wachspressB)
+       endif
+
+    enddo ! jVertex
+
+    numerator = numerator * wachspressKappa(jVertex,iVertex)
+
+  end function wachspress_numerator
+
+  !-------------------------------------------------------------
+
+  function wachspress_numerator_derivative(nEdgesOnCell, jVertex, iVertex, x, y, wachspressKappa, wachspressA, wachspressB, iDerivativeType) result(derivative)
+
+    integer, intent(in) :: &amp;
+         nEdgesOnCell, &amp;
+         jVertex, &amp;
+         iVertex, &amp;
+         iDerivativeType
+
+    real(kind=RKIND), intent(in) :: &amp;
+         x, &amp;
+         y
+    
+    real(kind=RKIND), dimension(:,:), intent(in) :: &amp;
+         wachspressKappa
+
+    real(kind=RKIND), dimension(:), intent(in) :: &amp;
+         wachspressA, &amp;
+         wachspressB
+
+    real(kind=RKIND) :: &amp;
+         derivative
+
+    real(kind=RKIND) :: &amp;
+         sum_of_products, &amp;
+         product
+
+    integer :: &amp;
+         kVertex, &amp;
+         lVertex, &amp;
+         i1, &amp;
+         i2
+
+    i1 = jVertex 
+    i2 = jVertex + 1
+    if (i2 &gt; nEdgesOnCell) i2 = i2 - nEdgesOnCell
+
+    sum_of_products = 0.0_RKIND
+
+    do kVertex = 1, nEdgesOnCell
+
+       if (kVertex /= i1 .and. kVertex /= i2) then
+          
+          product = 1.0_RKIND
+
+          do lVertex = 1, nEdgesOnCell
+             
+             if (lVertex /= i1 .and. lVertex /= i2) then
+                
+                if (lVertex == kVertex) then
+
+                   product = product * wachspress_edge_equation_derivative(lVertex, wachspressA, wachspressB, iDerivativeType)
+                
+                else
+
+                   product = product * wachspress_edge_equation(lVertex, x, y, wachspressA, wachspressB)
+
+                endif
+
+             endif
+             
+          enddo ! jVertex
+
+          sum_of_products = sum_of_products + product
+          
+       endif
+
+    enddo ! jVertex
+
+    derivative = sum_of_products * wachspressKappa(jVertex,iVertex)
+
+  end function wachspress_numerator_derivative
+
+  !-------------------------------------------------------------
+
+  function wachspress_edge_equation(iVertex, x, y, wachspressA, wachspressB) result(edge_equation)
+
+    integer, intent(in) :: &amp;
+         iVertex
+
+    real(kind=RKIND), intent(in) :: &amp;
+         x, &amp;
+         y
+
+    real(kind=RKIND), dimension(:), intent(in) :: &amp;
+         wachspressA, &amp;
+         wachspressB
+
+    real(kind=RKIND) :: edge_equation
+
+    edge_equation = 1.0_RKIND - wachspressA(iVertex) * x - wachspressB(iVertex) * y
+
+  end function wachspress_edge_equation
+
+  !-------------------------------------------------------------
+
+  function wachspress_edge_equation_derivative(iVertex, wachspressA, wachspressB, iDerivativeType) result(derivative)
+
+    integer, intent(in) :: &amp;
+         iVertex, &amp;
+         iDerivativeType
+
+    real(kind=RKIND), dimension(:), intent(in) :: &amp;
+         wachspressA, &amp;
+         wachspressB
+
+    real(kind=RKIND) :: derivative
+
+    if (iDerivativeType == 1) then
+
+       derivative = -wachspressA(iVertex)
+
+    else if (iDerivativeType == 2) then
+
+       derivative = -wachspressB(iVertex)
+
+    endif
+
+  end function wachspress_edge_equation_derivative
+
+  !-------------------------------------------------------------
+
+  subroutine calculate_wachspress_derivatives(mesh, &amp;
+                                              basisGradientU, basisGradientV, &amp;
+                                              wachspressA,      wachspressB,      &amp;
+                                              wachspressKappa)
+
+    ! basisGradientUV(jVertexOnCell,iVertexOnCell,iCell)
+    ! iCell         : The cell the gradients are based in
+    ! iVertexOnCell : The vertex basis function the gradient is calculated from
+    ! jVertexOnCell : The vertex location the gradients are calculated at
+    
+    type(mesh_type), intent(in) :: mesh
+
+    real(kind=RKIND), dimension(:,:,:), intent(out) :: &amp;
+         basisGradientU, &amp;
+         basisGradientV
+
+    real(kind=RKIND), dimension(:,:), intent(in) :: &amp;    
+         wachspressA, &amp;
+         wachspressB
+
+    real(kind=RKIND), dimension(:,:,:), intent(in) :: &amp;  
+         wachspressKappa
+
+    integer :: &amp;
+         nEdgesOnCell
+
+    integer :: &amp;
+         iCell, &amp;
+         iVertexOnCell, &amp;
+         jVertexOnCell, &amp;
+         jVertex
+
+    ! loop over cells
+    do iCell = 1, mesh % nCells
+
+       nEdgesOnCell = mesh % nEdgesOnCell % array(iCell)
+
+       ! loop over vertices - basis function
+       do iVertexOnCell = 1, nEdgesOnCell
+
+          ! loop over vertices again - derivative position
+          do jVertexOnCell = 1, nEdgesOnCell
+
+             jVertex = mesh % verticesOnCell % array(jVertexOnCell,iCell)
+          
+             basisGradientU(jVertexOnCell,iVertexOnCell,iCell) = &amp;
+                  wachspress_basis_derivative(nEdgesOnCell, &amp;
+                                              iVertexOnCell, &amp;
+                                              mesh % xVertex % array(jVertex), &amp;
+                                              mesh % yVertex % array(jVertex), &amp;
+                                              wachspressKappa(:,:,iCell), &amp;
+                                              wachspressA(:,iCell), &amp;
+                                              wachspressB(:,iCell), &amp;
+                                              1)
+
+             basisGradientV(jVertexOnCell,iVertexOnCell,iCell) = &amp;
+                  wachspress_basis_derivative(nEdgesOnCell, &amp;
+                                              iVertexOnCell, &amp;
+                                              mesh % xVertex % array(jVertex), &amp;
+                                              mesh % yVertex % array(jVertex), &amp;
+                                              wachspressKappa(:,:,iCell), &amp;
+                                              wachspressA(:,iCell), &amp;
+                                              wachspressB(:,iCell), &amp;
+                                              2)
+
+           enddo ! jVertexOnCell
+
+       enddo ! iVertexOnCell
+
+    enddo ! iCell
+
+  end subroutine calculate_wachspress_derivatives
+
+  !-------------------------------------------------------------
+
+  subroutine get_triangle_mapping(mapping, x1, y1, x2, y2, u1, v1, u2, v2)
+
+    real(kind=RKIND), dimension(2,2), intent(out) :: &amp;
+         mapping
+
+    real(kind=RKIND), intent(in) :: &amp;
+         x1, &amp; ! input
+         y1, &amp;
+         x2, &amp; 
+         y2, &amp;
+         u1, &amp; ! output
+         v1, &amp;
+         u2, &amp;
+         v2
+
+    mapping(1,1) = (u2*y1 - u1*y2) / (x2*y1 - x1*y2)
+    mapping(1,2) = (u1*x2 - u2*x1) / (y1*x2 - y2*x1)
+
+    mapping(2,1) = (v2*y1 - v1*y2) / (x2*y1 - x1*y2)
+    mapping(2,2) = (v1*x2 - v2*x1) / (y1*x2 - y2*x1)
+
+  end subroutine get_triangle_mapping
+
+  !-------------------------------------------------------------
+
+  subroutine use_triangle_mapping(u, v, x, y, mapping)
+
+    real(kind=RKIND), intent(out) :: &amp;
+         u, v
+
+    real(kind=RKIND), intent(in) :: &amp;
+         x, y
+
+    real(kind=RKIND), dimension(2,2), intent(in) :: &amp;
+         mapping
+
+    u = mapping(1,1) * x + mapping(1,2) * y
+    v = mapping(2,1) * x + mapping(2,2) * y
+
+  end subroutine use_triangle_mapping
+
+  !-------------------------------------------------------------
+
+  subroutine integrate_wachspress(mesh, hexbas)
+
+    ! basisIntegralsUV (iVertexOnCell,jVertexOnCell,iCell)
+    ! iCell         : cell integrals are performed on
+    ! iVertexOnCell : vertex number of Wachspress function 
+    ! jVertexOnCell : vertex number of Wachspress derivative function 
+    ! Sij
+
+    type(mesh_type), intent(in) :: mesh
+
+    type(hexbas_type), pointer :: hexbas
+
+    real(kind=RKIND) :: &amp;
+         integration
+
+    integer :: &amp;
+         iCell, &amp;
+         iVertexOnCell, &amp;
+         jVertexOnCell, &amp;
+         iDerivativeType, &amp;
+         nEdgesOnCell
+
+    do iCell = 1, mesh % nCells
+
+       nEdgesOnCell = mesh % nEdgesOnCell % array(iCell)
+
+       do iVertexOnCell = 1, nEdgesOnCell
+
+          do jVertexOnCell = 1, nEdgesOnCell
+
+             do iDerivativeType = 1, 2
+
+                call integrate_wachspress_polygon(&amp;
+                     integration, nEdgesOnCell, iVertexOnCell, jvertexOnCell, &amp;
+                     hexbas % xLocal % array(:,iCell), &amp;
+                     hexbas % yLocal % array(:,iCell), &amp;
+                     hexbas % wachspressKappa % array(:,:,iCell), &amp;
+                     hexbas % wachspressA % array(:,iCell), &amp;
+                     hexbas % wachspressB % array(:,iCell), &amp;
+                     iDerivativeType)
+
+                if (iDerivativeType == 1) then
+
+                   hexbas % basisIntegralsU % array(iVertexOnCell,jVertexOnCell,iCell) = &amp;
+                        integration
+
+                else if (iDerivativeType == 2) then
+
+                   hexbas % basisIntegralsV % array(iVertexOnCell,jVertexOnCell,iCell) = &amp;
+                        integration
+
+                endif
+
+             enddo ! iDerivativeType
+
+          enddo ! jVertex
+
+       enddo ! iVertex
+
+    enddo ! iCell
+
+  end subroutine integrate_wachspress
+
+  !-------------------------------------------------------------
+
+  subroutine integrate_wachspress_polygon(integration, nEdgesOnCell, iVertexOnCell, jvertexOnCell, xLocal, yLocal, &amp;
+                                          wachspressKappa, wachspressA, wachspressB, iDerivativeType)
+
+    integer, intent(in) :: &amp;
+         nEdgesOnCell, &amp;
+         iVertexOnCell, &amp;
+         jvertexOnCell, &amp;
+         iDerivativeType
+
+    real(kind=RKIND), dimension(:), intent(in) :: &amp;
+         xLocal, &amp;
+         yLocal
+
+    real(kind=RKIND), dimension(:,:), intent(in) :: &amp;
+         wachspressKappa
+
+    real(kind=RKIND), dimension(:), intent(in) :: &amp;
+         wachspressA, &amp;
+         wachspressB
+
+    real(kind=RKIND) :: &amp;
+         integration, &amp;
+         integration_subtriangle
+
+    real(kind=RKIND), dimension(2,2) :: &amp;
+         mapping
+
+    integer :: &amp;
+         iSubTriangle, &amp;
+         i1, &amp;
+         i2
+
+    integration = 0.0_RKIND
+
+    do iSubTriangle = 1, nEdgesOnCell
+
+       i1 = iSubTriangle
+       i2 = iSubTriangle + 1
+       if (i2 &gt; nEdgesOnCell) i2 = i2 - nEdgesOnCell
+
+       call get_triangle_mapping(mapping, &amp;
+                                 1.0_RKIND, 0.0_RKIND, &amp;
+                                 0.0_RKIND, 1.0_RKIND, &amp;
+                                 xLocal(i1), yLocal(i1), &amp;
+                                 xLocal(i2), yLocal(i2))
+
+       call integrate_wachspress_subtriangle(integration_subtriangle, nEdgesOnCell, iVertexOnCell, jvertexOnCell, &amp;
+                                             wachspressKappa(:,:), wachspressA(:), wachspressB(:), iDerivativeType, mapping)
+
+       integration = integration + integration_subtriangle
+
+    enddo ! iSubTriangle
+
+  end subroutine integrate_wachspress_polygon
+
+  !-------------------------------------------------------------
+
+  subroutine integrate_wachspress_subtriangle(integration,nEdgesOnCell, iVertexOnCell, jvertexOnCell, &amp;
+       wachspressKappa, wachspressA, wachspressB, iDerivativeType, mapping)
+
+    real(kind=RKIND), intent(out) :: &amp;
+         integration
+
+    integer, intent(in) :: &amp;
+         nEdgesOnCell, &amp;
+         iVertexOnCell, &amp;
+         jvertexOnCell, &amp;
+         iDerivativeType
+
+    real(kind=RKIND), dimension(:,:), intent(in) :: &amp;
+         wachspressKappa
+
+    real(kind=RKIND), dimension(:), intent(in) :: &amp;
+         wachspressA, &amp;
+         wachspressB
+
+    real(kind=RKIND), dimension(2,2), intent(in) :: &amp;
+         mapping
+
+    real(kind=RKIND) :: &amp;
+         jacobian
+
+    real(kind=RKIND) :: &amp;
+         scaling, &amp;
+         x, &amp;
+         y, &amp;
+         u, &amp;
+         v
+
+
+    integer :: &amp;
+         i, j, k
+
+    integer, parameter :: n = 10
+
+    integration = 0.0_RKIND
+
+    do i = 0, n
+       do j = 0, n
+
+          if (i&lt;=n-j) then
+
+             if (i==n .or. j==n .or. (i==0 .and. j==0)) then
+
+                scaling = 1.0_RKIND
+
+             else if ((j==0 .and. i/=0 .and. i/=n) .or. (i==0 .and. j/=0 .and. j/=n) .or. (i==n-j .and. i/=0 .and. j/=0)) then
+
+                scaling = 3.0_RKIND
+
+             else
+
+                scaling = 6.0_RKIND 
+
+             endif
+
+             u = real(i,RKIND) / real(n,RKIND)
+             v = real(j,RKIND) / real(n,RKIND)
+             
+             call use_triangle_mapping(x, y, u, v, mapping)
+             
+             jacobian = mapping(1,1) * mapping(2,2) - mapping(1,2) * mapping(2,1)
+             
+             ! area test
+             !integration = integration + scaling * jacobian
+             
+             ! actual integration
+             integration = integration + scaling * jacobian * &amp;
+                  wachspress_basis_function(nEdgesOnCell, iVertexOnCell, x, y, wachspressKappa, wachspressA, wachspressB) * &amp;
+                  wachspress_basis_derivative(nEdgesOnCell, jVertexOnCell, x, y, wachspressKappa, wachspressA, wachspressB, iDerivativeType)
+
+          endif
+
+       enddo ! i
+    enddo ! j
+
+    integration = integration / (6.0_RKIND * real(n,RKIND)**2)
+
+  end subroutine integrate_wachspress_subtriangle
+
+  !-------------------------------------------------------------
+
+   subroutine calc_cell_vertices_at_vertex(mesh, cellVerticesAtVertex)
+
+    type(mesh_type), intent(in) :: mesh
+
+    integer, dimension(:,:), intent(out) :: &amp;
+         cellVerticesAtVertex
+
+    integer :: &amp;
+         iVertex, &amp;
+         iVertexDegree, &amp;
+         iCell, &amp;
+         iVertexOnCell, &amp;
+         jVertex
+
+    do iVertex = 1, mesh % nVertices
+
+       do iVertexDegree = 1, mesh % vertexDegree
+
+          cellVerticesAtVertex(iVertexDegree,iVertex) = 0
+
+          iCell = mesh % cellsOnVertex % array(iVertexDegree, iVertex)
+
+          do iVertexOnCell = 1, mesh % nEdgesOnCell % array(iCell)
+
+             jVertex = mesh % verticesOnCell % array(iVertexOnCell,iCell)
+
+             if (iVertex == jVertex) then
+
+                cellVerticesAtVertex(iVertexDegree,iVertex) = iVertexOnCell
+
+             endif
+
+          enddo ! iVertexOnCell
+
+       enddo ! iVertexDegree
+
+    enddo ! iVertex
+
+   end subroutine calc_cell_vertices_at_vertex
+
+  !-------------------------------------------------------------
+  ! time step
+  !-------------------------------------------------------------
+  
+  subroutine run_dynamics_evp(mesh, icestate, hexbas, hexdyn, hexfor, boundary)
+
+    use cice_dynamics_shared, only: ice_strength, air_stress, ocean_stress, surface_tilt, solve_velocity
+
+    type(mesh_type), intent(in) :: mesh
+
+    type(icestate_type), pointer :: icestate
+    type(hexdyn_type),   pointer :: hexdyn
+    type(hexbas_type),   pointer :: hexbas
+    type(hexfor_type),   pointer :: hexfor
+    type(boundary_type), pointer :: boundary
+
+    real(kind=RKIND) :: timeStep, elasticTimeStep
+
+    call ice_strength(mesh, &amp;     
+         hexdyn % icePressure % array,    &amp;
+         icestate % iceAreaCell % array,  &amp;
+         icestate % iceVolumeCell % array)
+    
+    call stress_tensor(mesh, &amp;
+         hexdyn % stress1 % array,        &amp;
+         hexdyn % stress2 % array,        &amp;
+         hexdyn % stress12 % array,       &amp;
+         hexdyn % icePressure % array,    &amp;
+         hexdyn % uVelocity % array,      &amp;
+         hexdyn % vVelocity % array,      &amp;
+         hexbas % basisGradientU % array, &amp;
+         hexbas % basisGradientV % array, &amp;
+         timeStep, elasticTimeStep)
+    
+    call divergence_stress_tensor(mesh, &amp;
+         hexdyn % stressDivergenceU % array,    &amp;
+         hexdyn % stressDivergenceV % array,    &amp;
+         hexdyn % stress1 % array,              &amp;
+         hexdyn % stress2 % array,              &amp;
+         hexdyn % stress12 % array,             &amp;
+         hexbas % basisIntegralsU % array,      &amp;
+         hexbas % basisIntegralsV % array,      &amp;
+         hexbas % cellVerticesAtVertex % array, &amp;
+         boundary % interiorVertex % array)
+
+    call air_stress(&amp;
+         hexdyn % airStressU % array,   &amp;
+         hexdyn % airStressV % array,   &amp;
+         hexfor % uAirVelocity % array, &amp; 
+         hexfor % vAirVelocity % array, &amp;
+         icestate % iceAreaVertex % array)
+    
+    !call ocean_stress(&amp; 
+    !     hexdyn % oceanStressU % array,     &amp;
+    !     hexdyn % oceanStressV % array,     &amp;
+    !     hexdyn % oceanStressCoeff % array, &amp;
+    !     hexfor % uOceanVelocity % array,   &amp; 
+    !     hexfor % vOceanVelocity % array,   &amp;
+    !     hexdyn % uVelocity % array,        &amp;   
+    !     hexdyn % vVelocity % array,        &amp;
+    !     icestate % iceAreaCell % array)
+    
+    call surface_tilt(&amp;
+         hexdyn % surfaceTiltForceU % array, &amp;
+         hexdyn % surfaceTiltForceV % array)
+    
+    call solve_velocity(mesh % nCells, &amp;
+         boundary % interiorVertex % array,  &amp;
+         hexdyn % uVelocity % array,         &amp;   
+         hexdyn % vVelocity % array,         &amp;
+         iceState % totalMassCell % array,   &amp; 
+         mesh % fCell % array,               &amp;
+         hexdyn % stressDivergenceU % array, &amp; 
+         hexdyn % stressDivergenceV % array, &amp;
+         hexdyn % airStressU % array,        &amp;
+         hexdyn % airStressV % array,        &amp;
+         hexdyn % surfaceTiltForceU % array, &amp;
+         hexdyn % surfaceTiltForceV % array, &amp;
+         hexdyn % oceanStressU % array,      &amp;
+         hexdyn % oceanStressV % array,      &amp;
+         hexdyn % oceanStressCoeff % array,  &amp;
+         timeStep)
+
+  end subroutine run_dynamics_evp
+
+  !-------------------------------------------------------------
+  
+  subroutine stress_tensor(mesh, &amp;
+                           stress1,        stress2,        &amp;
+                           stress12,       icePressure,    &amp;
+                           uVelocity,      vVelocity,      &amp;
+                           basisGradientU, basisGradientV, &amp;
+                           timeStep,       elasticTimeStep)
+
+    use cice_dynamics_shared, only: evp_constitutive_relation, linear_constitutive_relation
+
+    type(mesh_type), intent(in) :: mesh
+
+    real(kind=RKIND), dimension(:,:), intent(out) :: &amp;
+         stress1, &amp;
+         stress2, &amp;
+         stress12
+    
+    real(kind=RKIND), dimension(:), intent(in) :: &amp;
+         icePressure, &amp;
+         uVelocity, &amp;
+         vVelocity
+
+    real(kind=RKIND), dimension(:,:,:), intent(in) :: &amp;
+         basisGradientU, &amp;
+         basisGradientV
+
+    real(kind=RKIND), intent(in) :: &amp;
+         timeStep,  &amp;
+         elasticTimeStep
+
+    real(kind=RKIND) :: &amp;
+         strainDivergence, &amp;
+         strainTension, &amp;
+         strainShearing
+
+    integer :: &amp;
+         iCell, &amp;
+         jVertexOnCell, &amp;
+         iVertexOnCell, &amp;
+         iVertex
+
+    ! loop over cells
+    do iCell = 1, mesh % nCells
+
+       ! loop over velocity points surrounding cell - location of stress and derivative
+       do jVertexOnCell = 1, mesh % nEdgesOnCell % array(iCell)
+
+          strainDivergence = 0.0_RKIND
+          strainTension    = 0.0_RKIND
+          strainShearing   = 0.0_RKIND
+
+          ! loop over basis functions
+          do iVertexOnCell = 1, mesh % nEdgesOnCell % array(iCell)
+
+             iVertex = mesh % verticesOnCell % array(iVertexOnCell,iCell)
+
+             strainDivergence = strainDivergence + &amp;
+                  uVelocity(iVertex) * basisGradientU(jVertexOnCell,iVertexOnCell,iCell) + &amp;
+                  vVelocity(iVertex) * basisGradientV(jVertexOnCell,iVertexOnCell,iCell)
+
+             strainTension = strainTension + &amp;
+                  uVelocity(iVertex) * basisGradientU(jVertexOnCell,iVertexOnCell,iCell) - &amp;
+                  vVelocity(iVertex) * basisGradientV(jVertexOnCell,iVertexOnCell,iCell)
+
+             strainShearing = strainShearing + &amp;
+                  uVelocity(iVertex) * basisGradientV(jVertexOnCell,iVertexOnCell,iCell) + &amp;
+                  vVelocity(iVertex) * basisGradientU(jVertexOnCell,iVertexOnCell,iCell)
+
+          enddo ! iVertexOnCell             
+
+          !call evp_constitutive_relation(stress1(jVertexOnCell,iCell),                    &amp;
+          !                               stress2(jVertexOnCell,iCell),                    &amp;
+          !                               stress12(jVertexOnCell,iCell),                   &amp;
+          !                               strainDivergence, strainTension, strainShearing, &amp;
+          !                               icePressure(iCell),                              &amp;
+          !                               timeStep, elasticTimeStep)
+
+          call linear_constitutive_relation(stress1(jVertexOnCell,iCell),                    &amp;
+                                            stress2(jVertexOnCell,iCell),                    &amp;
+                                            stress12(jVertexOnCell,iCell),                   &amp;
+                                            strainDivergence, strainTension, strainShearing)
+
+
+       enddo ! jVertexOnCell
+
+    enddo ! iCell
+
+  end subroutine stress_tensor
+  
+  !-------------------------------------------------------------
+
+  subroutine divergence_stress_tensor(mesh, &amp;
+                                      stressDivergenceU, stressDivergenceV, &amp;
+                                      stress1,            stress2,          &amp;
+                                      stress12,                             &amp;
+                                      basisIntegralsU, basisIntegralsV,     &amp;
+                                      cellVerticesAtVertex, interiorVertex)
+
+    type(mesh_type), intent(in) :: mesh
+
+    real(kind=RKIND), dimension(:), intent(out) :: &amp;
+         stressDivergenceU, &amp;
+         stressDivergenceV
+
+    real(kind=RKIND), dimension(:,:), intent(in) :: &amp;    
+         stress1, &amp;
+         stress2, &amp;
+         stress12
+
+    real(kind=RKIND), dimension(:,:,:), intent(in) :: &amp;   
+         basisIntegralsU, &amp;
+         basisIntegralsV
+
+    integer, dimension(:,:), intent(in) :: &amp;
+         cellVerticesAtVertex
+
+    integer, dimension(:), intent(in) :: &amp;
+         interiorVertex
+
+    real(kind=RKIND) :: &amp;
+         stressDivergenceUCell, &amp;
+         stressDivergenceVCell
+
+    real(kind=RKIND) :: &amp;
+         stress1contribU, &amp;
+         stress2contribU, &amp;
+         stress12contribU, &amp;
+         stress1contribV, &amp;
+         stress2contribV, &amp;
+         stress12contribV
+
+    integer :: &amp;
+         iVertex, &amp;
+         iCellOnVertex, &amp;
+         iCell, &amp;
+         iVertexOnCell, &amp;
+         jVertexOnCell
+
+    ! loop over velocity positions
+    do iVertex = 1, mesh % nVertices
+
+       stressDivergenceU(iVertex) = 0.0_RKIND
+       stressDivergenceV(iVertex) = 0.0_RKIND
+
+       !if (interiorVertex(iVertex) == 1) then
+
+          stress1contribU = 0.0_RKIND
+          stress2contribU = 0.0_RKIND
+          stress12contribU = 0.0_RKIND
+          
+          stress1contribV = 0.0_RKIND
+          stress2contribV = 0.0_RKIND
+          stress12contribV = 0.0_RKIND
+
+          ! loop over surrounding cells
+          do iCellOnVertex = 1, mesh % vertexDegree
+             
+             ! get the cell number of this cell
+             iCell = mesh % cellsOnVertex % array(iCellOnVertex, iVertex)
+             
+             ! get the vertexOnCell number of the iVertex velocity point from cell iCell
+             jVertexOnCell = cellVerticesAtVertex(iCellOnVertex,iVertex)
+
+             stressDivergenceUCell = 0.0_RKIND
+             stressDivergenceVCell = 0.0_RKIND
+
+             ! loop over the vertices of the surrounding cell
+             do iVertexOnCell = 1, mesh % nEdgesOnCell % array(iCell)
+
+                
+                stress1contribU = stress1contribU   + stress1(iVertexOnCell,iCell)  * basisIntegralsU(iVertexOnCell,jVertexOnCell,iCell)
+                stress2contribU = 0.0_RKIND
+                stress12contribU = stress12contribU + stress12(iVertexOnCell,iCell) * basisIntegralsV(iVertexOnCell,jVertexOnCell,iCell)
+
+                stress1contribV = 0.0_RKIND
+                stress2contribV = stress2contribV   + stress2(iVertexOnCell,iCell)  * basisIntegralsV(iVertexOnCell,jVertexOnCell,iCell)
+                stress12contribV = stress12contribV + stress12(iVertexOnCell,iCell) * basisIntegralsU(iVertexOnCell,jVertexOnCell,iCell)
+
+
+                stressDivergenceUCell = stressDivergenceUCell + &amp;
+                     stress1(iVertexOnCell,iCell)  * basisIntegralsU(iVertexOnCell,jVertexOnCell,iCell) * 0.5_RKIND + &amp;
+                     stress2(iVertexOnCell,iCell)  * basisIntegralsU(iVertexOnCell,jVertexOnCell,iCell) * 0.5_RKIND + &amp;
+                     stress12(iVertexOnCell,iCell) * basisIntegralsV(iVertexOnCell,jVertexOnCell,iCell)
+                
+                stressDivergenceVCell = stressDivergenceVCell + &amp;
+                     stress1(iVertexOnCell,iCell)  * basisIntegralsV(iVertexOnCell,jVertexOnCell,iCell) * 0.5_RKIND - &amp;
+                     stress2(iVertexOnCell,iCell)  * basisIntegralsV(iVertexOnCell,jVertexOnCell,iCell) * 0.5_RKIND + &amp;
+                     stress12(iVertexOnCell,iCell) * basisIntegralsU(iVertexOnCell,jVertexOnCell,iCell)
+                
+                !write(*,*) iVertex, iCellOnVertex, iVertexOnCell, stressDivergenceU(iVertex), stress1(iVertexOnCell,iCell), basisIntegralsU(iVertexOnCell,jVertexOnCell,iCell)
+                
+             enddo ! jVertex
+
+
+
+             stressDivergenceU(iVertex) = stressDivergenceU(iVertex) + stressDivergenceUCell / mesh % areaCell % array(iCell)
+             stressDivergenceV(iVertex) = stressDivergenceV(iVertex) + stressDivergenceVCell / mesh % areaCell % array(iCell)
+             
+             !write(*,*) iVertex, iVertexOnCell, stressDivergenceUCell / mesh % areaCell % array(iCell), stressDivergenceVCell / mesh % areaCell % array(iCell)
+            
+
+          enddo ! iCellOnVertex
+
+          !write(*,*) iVertex, stressDivergenceU(iVertex), stressDivergenceV(iVertex)
+          
+
+          stress1contribU = stress1contribU   / mesh % areaCell % array(iCell)
+          stress2contribU = stress2contribU   / mesh % areaCell % array(iCell)
+          stress12contribU = stress12contribU / mesh % areaCell % array(iCell)
+          
+          stress1contribV = stress1contribV   / mesh % areaCell % array(iCell)
+          stress2contribV = stress2contribV   / mesh % areaCell % array(iCell)
+          stress12contribV = stress12contribV / mesh % areaCell % array(iCell)
+
+          write(*,*) iVertex, iCellOnVertex, stress1contribU, stress12contribU, &amp;
+               stress2contribV, stress12contribV, &amp;
+               stress1contribU+stress2contribU+stress12contribU,stress1contribV+stress2contribV+stress12contribV
+
+
+       !endif ! interiorVertex
+
+    enddo ! iVertex
+    
+    write(*,*) &quot;divergence&quot;
+
+  end subroutine divergence_stress_tensor
+
+  !-------------------------------------------------------------
+
+  subroutine test_divergence_stress_tensor(mesh, hexbas, hexdyn, boundary)
+
+    use cice_testing, only: divergence_stress_test_velocity_set, writeout_on_vertex_real, &amp;
+         writeout_on_vertex_on_cell_real, gnuplot_triangle, divergence_stress_test_stress_set_hex, gnuplot_cell
+
+    type(mesh_type), intent(in) :: mesh
+
+    type(hexbas_type),   pointer :: hexbas
+    type(hexdyn_type),   pointer :: hexdyn
+    type(boundary_type), pointer :: boundary
+
+    !call gnuplot_cell(mesh, mesh % xCell % array, &quot;cells.txt&quot;, .false., .false.) 
+
+    ! set the velocity field
+    !call divergence_stress_test_velocity_set(hexdyn % uVelocity % array, &amp;
+    !                                         hexdyn % vVelocity % array, &amp;
+    !                                         mesh % xVertex % array,     &amp;
+    !                                         mesh % yVertex % array,     &amp;
+    !                                         &quot;div1&quot;)
+
+    !call writeout_on_vertex_real(mesh, hexdyn % uVelocity % array, &quot;u.txt&quot;)
+    !call writeout_on_vertex_real(mesh, hexdyn % vVelocity % array, &quot;v.txt&quot;)
+
+    ! set the stress field from the velocity field with a linear constitutive relation
+    !call stress_tensor(mesh, &amp;
+    !                   hexdyn % stress1 % array,        hexdyn % stress2 % array,        &amp;
+    !                   hexdyn % stress12 % array,       hexdyn % icePressure % array,    &amp;
+    !                   hexdyn % uVelocity % array,      hexdyn % vVelocity % array,      &amp;
+    !                   hexbas % basisGradientU % array, hexbas % basisGradientV % array, &amp;
+    !                   0.0_RKIND, 0.0_RKIND)
+
+    call divergence_stress_test_stress_set_hex(mesh, &amp;
+                                               hexdyn % stress1 % array, &amp;
+                                               hexdyn % stress2 % array, &amp;
+                                               hexdyn % stress12 % array)
+
+    !call writeout_on_vertex_on_cell_real(mesh, hexdyn % stress1 % array, &quot;stress1.txt&quot;)
+    !call writeout_on_vertex_on_cell_real(mesh, hexdyn % stress2 % array, &quot;stress2.txt&quot;)
+    !call writeout_on_vertex_on_cell_real(mesh, hexdyn % stress12 % array, &quot;stress12.txt&quot;)
+
+    ! set the divergence of the stress
+    write(*,*) &quot;divergence test&quot;
+    call divergence_stress_tensor(mesh, &amp;
+                                  hexdyn % stressDivergenceU % array,    hexdyn % stressDivergenceV % array, &amp;
+                                  hexdyn % stress1 % array,              hexdyn % stress2 % array,           &amp;
+                                  hexdyn % stress12 % array,                                                 &amp;
+                                  hexbas % basisIntegralsU % array,      hexbas % basisIntegralsV % array,   &amp;
+                                  hexbas % cellVerticesAtVertex % array, boundary % interiorVertex % array)
+
+    ! writeout the divergence
+    !call writeout_on_vertex_real(mesh, hexdyn % stressDivergenceU % array, &quot;divu.txt&quot;)
+    !call writeout_on_vertex_real(mesh, hexdyn % stressDivergenceV % array, &quot;divv.txt&quot;)
+
+    !call gnuplot_triangle(mesh, hexdyn % stressDivergenceU % array, &quot;divugnu.txt&quot;)
+
+    stop
+
+  end subroutine test_divergence_stress_tensor
+
+  !-------------------------------------------------------------
+  ! Hex specific plotting stuff
+  !-------------------------------------------------------------
+
+  subroutine plot_wachpress(mesh, iCell, nEdgesOnCell, iVertex, wachspressKappa, wachspressA, wachspressB, xLocal, yLocal)
+    
+    type(mesh_type), intent(in) :: mesh
+
+    integer, intent(in) :: &amp;
+         iCell, &amp;
+         nEdgesOnCell, &amp;
+         iVertex
+
+    real(kind=RKIND), dimension(:,:), intent(out) :: &amp;
+         wachspressKappa
+
+    real(kind=RKIND), dimension(:), intent(out) :: &amp;
+         wachspressA, &amp;
+         wachspressB
+
+    real(kind=RKIND), dimension(:), intent(in) :: &amp;
+         xLocal, &amp;
+         yLocal
+
+    real(kind=RKIND) :: &amp;
+         xmin, xmax, ymin, ymax
+    
+    real(kind=RKIND), dimension(2,2) :: &amp;
+         mapping
+
+    integer :: &amp;
+         iSubTriangle, &amp;
+         i1, &amp;
+         i2, &amp;
+         iVertexOnCell, &amp;
+         iVertex2
+
+    xmin =  1e30
+    xmax = -1e30
+    ymin =  1e30
+    ymax = -1e30
+
+    do iVertexOnCell = 1, nEdgesOnCell
+
+       iVertex2 = mesh % verticesOnCell % array(iVertexOnCell,iCell)
+
+       xmin = min(xmin,mesh % xVertex % array(iVertex2)) - 1000.0_RKIND
+       xmax = max(xmax,mesh % xVertex % array(iVertex2)) + 1000.0_RKIND
+       ymin = min(ymin,mesh % yVertex % array(iVertex2)) - 1000.0_RKIND
+       ymax = max(ymax,mesh % yVertex % array(iVertex2)) + 1000.0_RKIND
+       
+       open(55,file='test.txt')
+       if (iVertexOnCell == iVertex) then
+          write(55,*) mesh % xVertex % array(iVertex2), mesh % yVertex % array(iVertex2)
+       endif
+       close(55)
+
+    enddo ! iVertex
+
+    open(55,file=&quot;wachspress.txt&quot;)
+
+    !write(55,fmt='(a,f10.2,a,f10.2,a)') &quot;set xrange [&quot;,xmin,&quot;:&quot;,xmax,&quot;]&quot;
+    !write(55,fmt='(a,f10.2,a,f10.2,a)') &quot;set yrange [&quot;,ymin,&quot;:&quot;,ymax,&quot;]&quot;
+
+    ! loop over subtriangles
+    do iSubTriangle = 1, nEdgesOnCell
+
+       i1 = iSubTriangle
+       i2 = iSubTriangle + 1
+       if (i2 &gt; nEdgesOnCell) i2 = i2 - nEdgesOnCell
+
+       ! get the triangle mapping
+       call get_triangle_mapping(mapping, &amp;
+                                 1.0_RKIND,0.0_RKIND,&amp;
+                                 0.0_RKIND,1.0_RKIND,&amp;
+                                 xLocal(i1),yLocal(i1),&amp;
+                                 xLocal(i2),yLocal(i2))    
+       
+       ! plot from subtriangle
+       call plot_subtriangle(nEdgesOnCell, iSubTriangle, iVertex, &amp;
+                             wachspressKappa, wachspressA, wachspressB, &amp;
+                             mapping, mesh % xCell % array(iCell), mesh % yCell % array(iCell))
+
+    enddo ! iSubTriangle
+
+    close(55)
+stop
+  end subroutine plot_wachpress
+
+  !-------------------------------------------------------------
+  
+  subroutine plot_subtriangle(nEdgesOnCell, iSubTriangle, iVertex, wachspressKappa, wachspressA, wachspressB, mapping, x0, y0)
+
+    use cice_testing, only: matlab_jet
+
+    integer, intent(in) :: &amp;
+         nEdgesOnCell, &amp;
+         iSubTriangle, &amp;
+         iVertex
+
+    real(kind=RKIND), dimension(:,:), intent(in) :: &amp;
+         wachspressKappa
+
+    real(kind=RKIND), dimension(:), intent(in) :: &amp;
+         wachspressA, &amp;
+         wachspressB
+
+    real(kind=RKIND), dimension(2,2), intent(in) :: &amp;
+         mapping
+
+    real(kind=RKIND), intent(in) :: &amp;
+         x0, y0
+
+
+    real(kind=RKIND) :: &amp;
+         u, v, &amp;
+         x, y, &amp;
+         wachspress, &amp;
+         wachspress1
+
+    integer :: &amp;
+         i, j, iObject
+
+    real(kind=RKIND) :: &amp;
+         x1, x2, x3, x4, x5, &amp;
+         y1, y2, y3, y4, y5, &amp;
+         d, minf, maxf, fValue, &amp;
+         dx, dy
+    
+    real(kind=RKIND), parameter :: &amp;
+         fMin = -1.7759450831950581E-004_RKIND, &amp;
+         fMax = 5.5313696223098112E-005_RKIND
+
+    integer, parameter :: n = 50
+
+    character(len=7) :: &amp;
+         color
+
+    logical, parameter :: &amp;
+         lfinitedifference = .true.
+
+    iObject = ((iSubTriangle - 1) * (n+1) * (n+2)) / 2
+
+    d = 1.0_RKIND / real(n, RKIND)

+    minf = 1e30
+    maxf = -1e30
+
+    do i = 0, n
+       do j = 0, n
+
+          if (i&lt;=n-j-1) then
+
+             iObject = iObject + 1  
+
+             u = real(i,RKIND) / real(n,RKIND)
+             v = real(j,RKIND) / real(n,RKIND)
+
+             call use_triangle_mapping(x, y, u, v, mapping)
+
+             if (lfinitedifference) then
+                wachspress = &amp;
+                     wachspress_basis_function(nEdgesOnCell, iVertex, x, y, wachspressKappa, wachspressA, wachspressB)
+                
+                dx = 0.0_RKIND
+                dy = 100.0_RKIND
+                
+                x1 = x + dx
+                y1 = y + dy
+                
+                wachspress1 = &amp;
+                     wachspress_basis_function(nEdgesOnCell, iVertex, x1, y1, wachspressKappa, wachspressA, wachspressB)             
+                
+                wachspress = (wachspress1 - wachspress) / dy
+                
+             else
+
+                wachspress = &amp;
+                     wachspress_basis_derivative(nEdgesOnCell, iVertex, x, y, wachspressKappa, wachspressA, wachspressB, 2)
+
+             endif
+
+             fValue = (wachspress - fMin) / (fMax - fMin)
+                
+             minf = min(minf,wachspress)
+             maxf = max(maxf,wachspress)
+
+             if (i&lt;n-j-1) then
+                
+                call use_triangle_mapping(x1, y1, u,   v,   mapping)
+                call use_triangle_mapping(x2, y2, u,   v+d, mapping)
+                call use_triangle_mapping(x3, y3, u+d, v+d, mapping)
+                call use_triangle_mapping(x4, y4, u+d, v,   mapping)
+                x5 = x1
+                y5 = y1
+                
+                x1 = x1 + x0 ; y1 = y1 + y0
+                x2 = x2 + x0 ; y2 = y2 + y0
+                x3 = x3 + x0 ; y3 = y3 + y0
+                x4 = x4 + x0 ; y4 = y4 + y0
+                x5 = x5 + x0 ; y5 = y5 + y0
+                
+                !write(55,fmt='(a,i5,a,f10.2,a,f10.2,a,f10.2,a,f10.2,a,f10.2,a,f10.2,a,f10.2,a,f10.2,a,f10.2,a,f10.2)') &quot;set object &quot;,iObject,&quot; polygon from &quot;,&amp;
+                !     x1,&quot;,&quot;,y1,&quot; to &quot;,x2,&quot;,&quot;,y2,&quot; to &quot;,x3,&quot;,&quot;,y3,&quot; to &quot;,x4,&quot;,&quot;,y4,&quot; to &quot;,x5,&quot;,&quot;,y5     
+
+                color = matlab_jet(max(min(fValue,1.0_RKIND),0.0_RKIND))
+                !write(55,fmt='(a,i5,a,a,a)') &quot;set object &quot;,iObject,' fc rgb &quot;', color, '&quot; fillstyle solid'  
+
+             else
+
+                call use_triangle_mapping(x1, y1, u,   v,   mapping)
+                call use_triangle_mapping(x2, y2, u,   v+d, mapping)
+                call use_triangle_mapping(x4, y4, u+d, v,   mapping)
+                x5 = x1
+                y5 = y1
+
+                x1 = x1 + x0 ; y1 = y1 + y0
+                x2 = x2 + x0 ; y2 = y2 + y0
+                x4 = x4 + x0 ; y4 = y4 + y0
+                x5 = x5 + x0 ; y5 = y5 + y0
+                
+                !write(55,fmt='(a,i5,a,f10.2,a,f10.2,a,f10.2,a,f10.2,a,f10.2,a,f10.2,a,f10.2,a,f10.2,a,f10.2,a,f10.2)') &quot;set object &quot;,iObject,&quot; polygon from &quot;,&amp;
+                !     x1,&quot;,&quot;,y1,&quot; to &quot;,x2,&quot;,&quot;,y2,&quot; to &quot;,x4,&quot;,&quot;,y4,&quot; to &quot;,x5,&quot;,&quot;,y5    
+
+                color = matlab_jet(max(min(fValue,1.0_RKIND),0.0_RKIND))
+                !write(55,fmt='(a,i5,a,a,a)') &quot;set object &quot;,iObject,' fc rgb &quot;', color, '&quot; fillstyle solid'   
+
+             endif
+
+          endif
+
+       enddo ! j
+    enddo ! i
+
+    !write(0,*) minf, maxf
+
+  end subroutine plot_subtriangle
+
+  !-------------------------------------------------------------
+
+end module cice_dynamics_evp_hex

Added: branches/cice_projects/initial_cice_core/src/core_cice/mpas_cice_dynamics_evp_tri.F
===================================================================
--- branches/cice_projects/initial_cice_core/src/core_cice/mpas_cice_dynamics_evp_tri.F                                (rev 0)
+++ branches/cice_projects/initial_cice_core/src/core_cice/mpas_cice_dynamics_evp_tri.F        2013-04-19 18:44:55 UTC (rev 2780)
@@ -0,0 +1,1064 @@
+module cice_dynamics_evp_tri
+
+  use mpas_grid_types
+
+  implicit none
+
+  private
+  public :: init_dynamics_evp, &amp;
+            test_tri_divergence_stress_tensor
+
+contains
+
+
+
+  !-------------------------------------------------------------
+  ! Initialization
+  !-------------------------------------------------------------
+
+  subroutine init_dynamics_evp(mesh, basis, boundary)
+
+    use cice_testing, only: gnuplot_cell, gnuplot_triangle, plot_boundary_triangles, &amp;
+                            boundary_locations, labels_verticesOnCell, labels_verticesDegreeOnVertex, &amp;
+                            writeout_minmax
+    
+    use cice_dynamics_shared, only: boundary_cells, boundary_vertices, boundary_edges
+
+    type(mesh_type), intent(in) :: mesh
+
+    type(basis_type),    pointer :: basis
+    type(boundary_type), pointer :: boundary
+
+    integer :: iCell, iVertex
+   
+    call boundary_cells(mesh, &amp;
+         boundary % boundaryCell % array, &amp;
+         boundary % boundaryCell2 % array) 
+
+    call boundary_vertices(mesh, &amp;
+         boundary % boundaryVertex % array, &amp;
+         boundary % interiorVertex % array, &amp;
+         boundary % interiorVertex2 % array, &amp;
+         boundary % boundaryCell % array)
+
+    call boundary_edges(mesh, &amp;
+         boundary % boundaryEdge % array)
+
+    !call gnuplot_cell(mesh, mesh % xCell % array, &quot;cells.txt&quot;, .false., .true.)
+    call gnuplot_triangle(mesh, mesh % xVertex % array+mesh % yVertex % array, &quot;triangles.txt&quot;, .false., .true.)
+
+    call writeout_minmax()
+
+    !call labels_verticesOnCell(mesh, mesh % verticesOnCell % array, &quot;cell_vertices.txt&quot;) 
+    !call labels_verticesDegreeOnVertex(mesh, mesh % cellsOnVertex % array, boundary % interiorVertex % array, &quot;triangle_corners.txt&quot;) 
+
+    call calc_triangle_corner_at_cell_center(mesh, basis % triangleCornerAtCellCenter % array)
+    call calc_edge_opposite_triangle_corner(mesh, basis % edgeOppositeTriangleCorner % array, boundary % interiorVertex % array)
+
+    !call labels_verticesOnCell(mesh, basis % triangleCornerAtCellCenter % array, &quot;triangleCornerAtCellCenter.txt&quot;) 
+    !call labels_verticesDegreeOnVertex(mesh, basis % edgeOppositeTriangleCorner % array, boundary % interiorVertex % array, &quot;edgeOppositeTriangleCorner.txt&quot;) 
+
+
+    !stop
+
+
+    call basis_gradients_planar(mesh, &amp;
+         basis % basisGradientU % array, &amp;
+         basis % basisGradientV % array, &amp;
+         boundary % interiorVertex % array)
+
+    call basis_integrals(mesh, &amp;
+         basis % basisIntegrals % array, &amp;
+         basis % edgeOppositeTriangleCorner % array)
+
+    ! plotting stuff
+    !call gnuplot_cell(mesh, mesh % xCell % array, &quot;xCell.txt&quot;)
+    !call gnuplot_triangle(mesh, mesh % xVertex % array, &quot;xVertex.txt&quot;)
+
+    !call boundary_locations(mesh, &amp;
+    !     boundary % boundaryCell % array, &amp;
+    !     boundary % boundaryVertex % array, &amp;
+    !     boundary % interiorVertex % array, &amp;
+    !     boundary % boundaryEdge % array)
+
+    !call plot_boundary_triangles(mesh, &amp;
+    !     boundary % boundaryVertex % array, &amp;
+    !     boundary % interiorVertex % array, &amp;
+    !     boundary % boundaryEdge % array)
+
+  end subroutine init_dynamics_evp
+
+  !-------------------------------------------------------------
+
+  subroutine calc_triangle_corner_at_cell_center(mesh, triangleCornerAtCellCenter)
+
+    ! this finds the triangle corner number of a cell centre for an adjacent triangle
+
+
+    type(mesh_type), intent(in) :: mesh
+
+    integer, dimension(:,:), intent(out) :: &amp;
+         triangleCornerAtCellCenter
+
+    integer :: &amp;
+         iCell,            &amp; !
+         iVertexOnCell,    &amp; !
+         iVertex,          &amp; !
+         iVertexDegree,    &amp; !
+         iCellVertexDegree   !
+
+    ! loop over velocity positions
+    do iCell = 1, mesh % nCells
+
+       ! loop over triangles surrounding velocity position
+       do iVertexOnCell = 1, mesh % nEdgesOnCell % array(iCell)
+
+          ! get the vertex number associated with this cell vertex
+          iVertex = mesh % verticesOnCell % array(iVertexOnCell, iCell)
+
+          ! loop over triangle corners of this triangle
+          do iVertexDegree = 1, mesh % vertexDegree
+
+             ! get the cell number associated with this triangle corner
+             iCellVertexDegree = mesh % cellsOnVertex % array(iVertexDegree, iVertex)
+
+             ! test to see if it is the cell number of interest
+             if (iCellVertexDegree == iCell) then
+
+                triangleCornerAtCellCenter(iVertexOnCell,iCell) = iVertexDegree
+                exit
+
+             endif
+
+          enddo ! iVertexDegree
+
+       enddo ! iVertexOnCell
+
+    enddo ! iCell
+
+  end subroutine calc_triangle_corner_at_cell_center
+
+  !-------------------------------------------------------------
+
+  subroutine calc_edge_opposite_triangle_corner(mesh, edgeOppositeTriangleCorner, interiorVertex)
+
+    type(mesh_type), intent(in) :: mesh
+    
+    integer, dimension(:,:), intent(out) :: &amp;
+         edgeOppositeTriangleCorner
+
+    integer, dimension(:), intent(in) :: &amp;
+         interiorVertex
+
+    integer :: &amp;
+         iVertex, &amp;
+         iVertexDegree, &amp;
+         iCell, &amp;
+         jVertexDegree, &amp;
+         jEdge, &amp;
+         jEdgeOnCell
+
+    integer, dimension(3) :: &amp;
+         edgeMatched, &amp;
+         jEdgeVertexDegree
+
+    ! loop over all triangles
+    do iVertex = 1, mesh % nVertices
+
+       edgeOppositeTriangleCorner(:,iVertex) = 0
+
+       ! check are at an interior triangle
+       if (interiorVertex(iVertex) == 1) then
+
+          ! find opposite edge for each corner of triangle
+          do iVertexDegree = 1, mesh % vertexDegree
+
+             ! get cell number of this triangle corner
+             iCell = mesh % cellsOnVertex % array(iVertexDegree,iVertex)
+
+             ! initialize the matched array to none
+             edgeMatched = 0
+
+             ! check each triangle corner to see if NOT on iCell
+             do jVertexDegree = 1, mesh % vertexDegree
+
+                ! edge of this triangle corner
+                jEdgeVertexDegree(jVertexDegree) = mesh % edgesOnVertex % array(jVertexDegree, iVertex)
+
+                ! loop over edges on this cell see whether match with 
+                do jEdge = 1, mesh % nEdgesOnCell % array(iCell)
+
+                   ! edge number of this edge on the cell
+                   jEdgeOnCell = mesh % edgesOnCell % array(jEdge,iCell)
+
+                   ! see if edges are the same
+                   if (jEdgeVertexDegree(jVertexDegree) == jEdgeOnCell) then
+
+                      ! matched the vertex edge so this ISNT the right edge
+                      edgeMatched(jVertexDegree) = 1
+
+                   endif
+
+                enddo ! iEdgeOnCell
+
+             enddo ! jVertexDegree
+
+             ! check have matched right number
+             if (sum(edgeMatched) /= 2) then
+                write(*,*) &quot;calc_edge_opposite_triangle_corner: matched failed&quot;
+                stop
+             endif
+
+             ! find the right nonmatched edge
+             do jVertexDegree = 1, mesh % vertexDegree
+
+                if (edgeMatched(jVertexDegree) == 0) then
+                   edgeOppositeTriangleCorner(iVertexDegree,iVertex) = jEdgeVertexDegree(jVertexDegree)
+                endif
+
+             enddo ! jVertexDegree
+
+          enddo ! iVertexDegree
+
+       endif ! interiorVertex
+
+    enddo ! iVertex
+
+  end subroutine calc_edge_opposite_triangle_corner
+
+  !-------------------------------------------------------------
+
+  subroutine basis_gradients_planar(mesh, basisGradientU, basisGradientV, interiorVertex)
+
+    type(mesh_type), intent(in) :: mesh
+
+    real(kind=RKIND), dimension(:,:), intent(out) :: &amp;
+         basisGradientU, &amp;
+         basisGradientV
+
+    integer, dimension(:), intent(in) :: &amp;
+         interiorVertex
+
+    integer :: &amp;
+         iVertex,       &amp;
+         iVertexDegree
+
+    integer, dimension(3) :: &amp;
+         iCells
+
+    write(*,*) &quot;basis_gradients_planar&quot;
+
+    ! loop over the triangles
+    do iVertex = 1, mesh % nVertices
+
+       if (interiorVertex(iVertex) == 1) then
+
+          ! loop over corners of triangle
+          do iVertexDegree = 1, mesh % vertexDegree
+             
+             iCells(iVertexDegree) = mesh % cellsOnVertex % array(iVertexDegree, iVertex)
+             
+          enddo ! iVertexDegree
+          
+          call basis_gradients_planar_single(&amp;
+               basisGradientU(:,iVertex), &amp;
+               basisGradientV(:,iVertex), &amp;
+               mesh % xVertex % array(iVertex), mesh % yVertex % array(iVertex), &amp;
+               mesh % xCell % array(iCells(1)), mesh % yCell % array(iCells(1)), &amp;
+               mesh % xCell % array(iCells(2)), mesh % yCell % array(iCells(2)), &amp;
+               mesh % xCell % array(iCells(3)), mesh % yCell % array(iCells(3)))
+          
+       endif ! iVertex
+
+    enddo
+
+  end subroutine basis_gradients_planar
+
+  !-------------------------------------------------------------
+
+  subroutine basis_gradients_planar_single(basisGradientU, basisGradientV, &amp;
+       x0, y0, x1, y1, x2, y2, x3, y3)
+
+    use cice_dynamics_shared, only: solve_linear_basis_system
+
+    real(kind=RKIND), dimension(:), intent(out) :: &amp;
+         basisGradientU, &amp;
+         basisGradientV
+
+    real(kind=RKIND), intent(in) :: &amp;
+         x0, y0, &amp;
+         x1, y1, &amp;
+         x2, y2, &amp;
+         x3, y3
+
+    real(kind=RKIND), dimension(3,3) :: &amp;
+         leftMatrix
+
+    real(kind=RKIND), dimension(3) :: &amp;
+         rightHandSide, &amp;
+         solutionVector
+
+    integer :: &amp;
+         iTriangleCorner
+
+    leftMatrix(1,1) = x1 - x0
+    leftMatrix(1,2) = y1 - y0
+    leftMatrix(1,3) = 1.0_RKIND
+
+    leftMatrix(2,1) = x2 - x0
+    leftMatrix(2,2) = y2 - y0
+    leftMatrix(2,3) = 1.0_RKIND
+
+    leftMatrix(3,1) = x3 - x0
+    leftMatrix(3,2) = y3 - y0
+    leftMatrix(3,3) = 1.0_RKIND
+       
+    ! loop over corners of triangle
+    do iTriangleCorner = 1, 3
+
+       rightHandSide(:)               = 0.0_RKIND
+       rightHandSide(iTriangleCorner) = 1.0_RKIND
+
+       call solve_linear_basis_system(leftMatrix, rightHandSide, solutionVector)
+
+       basisGradientU(iTriangleCorner) = solutionVector(1)
+       basisGradientV(iTriangleCorner) = solutionVector(2)
+
+    enddo ! iVertexDegree
+
+  end subroutine basis_gradients_planar_single
+
+  !-------------------------------------------------------------
+
+  subroutine basis_integrals(mesh, basisIntegral, edgeOppositeTriangleCorner)
+
+    type(mesh_type), intent(in) :: mesh
+
+    real(kind=RKIND), dimension(:,:), intent(out) :: &amp;
+         basisIntegral
+
+    integer, dimension(:,:), intent(in) :: &amp;
+         edgeOppositeTriangleCorner
+
+    integer :: &amp;
+         iVertex, &amp;
+         iVertexDegree, &amp;
+         iEdge
+
+    real(kind=RKIND) :: &amp;
+         a, b, c
+
+    write(*,*) &quot;basis_integrals&quot;
+    
+    ! loop over triangles
+    do iVertex = 1, mesh % nVertices
+
+       do iVertexDegree = 1, mesh % vertexDegree       
+
+          iEdge = edgeOppositeTriangleCorner(modulo(iVertexDegree-1,3)+1, iVertex)
+          c = mesh % dcEdge % array(iEdge)
+          
+          iEdge = edgeOppositeTriangleCorner(modulo(iVertexDegree,3)+1, iVertex)
+          a = mesh % dcEdge % array(iEdge)
+
+          iEdge = edgeOppositeTriangleCorner(modulo(iVertexDegree-2,3)+1, iVertex)
+          b = mesh % dcEdge % array(iEdge)          
+
+          basisIntegral(iVertexDegree,iVertex) = &amp;
+               basis_integral(a, b, c, mesh % areaTriangle % array(iVertex))
+
+          !write(*,*) iVertex, iVertexDegree, basisIntegral(iVertexDegree,iVertex)
+
+       enddo ! iVertexDegree
+
+    enddo ! iVertex
+
+  end subroutine basis_integrals
+
+  !-------------------------------------------------------------
+
+  function basis_integral(a, b, c, areaTriangle) result(integral)
+
+    real(kind=RKIND), intent(in) :: &amp;
+         a, &amp;
+         b, &amp;
+         c, &amp;
+         areaTriangle
+
+    real(kind=RKIND) :: &amp;
+         integral
+
+    real(kind=RKIND) :: &amp;
+         d, &amp;
+         cosGamma
+
+    cosGamma = (a**2 + b**2 - c**2) / (2.0_RKIND * a * b)
+    
+    d = ((a*b) / c) * sqrt(1.0_RKIND - cosGamma**2)
+
+    !integral = (c*d) / (6.0_RKIND * areaTriangle)
+    integral = (c*d) / 6.0_RKIND
+
+    !write(*,*) a, b, c, d, areaTriangle, integral
+
+  end function basis_integral
+
+  !-------------------------------------------------------------
+
+  function greatCircleLength(x1,y1,z1,x2,y2,z2) result(length)
+
+    real(kind=RKIND), intent(in) :: &amp;
+         x1, y1, z1, &amp;
+         x2, y2, z2
+
+    real(kind=RKIND) :: length
+
+    real(kind=RKIND), dimension(3) :: &amp;
+         crossProduct
+
+    real(kind=RKIND) :: &amp;
+         dotProduct, &amp;
+         absCrossProduct
+
+    !http://en.wikipedia.org/wiki/Great-circle_distance#Vector_version
+
+    dotProduct = x1 * x2 + y1 * y2 + z1 * z2
+
+    crossProduct(1) = y1 * z2 - z1 * y2
+    crossProduct(2) = z1 * x2 - x1 * z2
+    crossProduct(3) = x1 * y2 - y1 * x2
+
+    absCrossProduct = sqrt(crossProduct(1)**2 + crossProduct(2)**2 + crossProduct(3)**2)
+
+    length = atan(absCrossProduct / dotProduct) ! atan or atan2?
+
+  end function greatCircleLength
+
+  !-------------------------------------------------------------
+
+  function planarLength(x1,y1,z1,x2,y2,z2) result(length)
+
+    real(kind=RKIND), intent(in) :: &amp;
+         x1, y1, z1, &amp;
+         x2, y2, z2
+
+    real(kind=RKIND) :: length
+
+    length = sqrt((x2-x1)**2 + (y2-y1)**2 + (z2-z1)**2)
+
+  end function planarLength
+
+  !-------------------------------------------------------------
+
+  function sphericalTriangleArea(radius,a,b,c) result(area)
+
+    use mpas_constants, only: pii
+
+    real(kind=RKIND), intent(in) :: &amp;
+         radius, a, b, c
+    
+    real(kind=RKIND) :: area
+
+    real(kind=RKIND) :: &amp;
+         sphericalExcess, &amp;
+         s
+
+    s = 0.5_RKIND * (a + b + c)
+    
+    sphericalExcess = 4.0_RKIND * atan(sqrt(tan(s/2.0_RKIND)*tan((s-a)/2.0_RKIND)*tan((s-b)/2.0_RKIND)*tan((s-c)/2.0_RKIND)))
+
+    area = (pii * radius**2 * sphericalExcess) / 180.0_RKIND 
+
+  end function sphericalTriangleArea
+
+  !-------------------------------------------------------------
+  
+  function planarTriangleArea(radius,a,b,c) result(area)
+
+    real(kind=RKIND), intent(in) :: &amp;
+         radius, a, b, c
+
+    real(kind=RKIND) :: area
+
+    !http://en.wikipedia.org/wiki/Triangle#Using_Heron.27s_formula
+    
+    real(kind=RKIND) :: &amp;
+         s
+
+    s = 0.5_RKIND * (a + b + c)
+
+    area = sqrt(s * (s-a) * (s-b) * (s-c))
+
+  end function planarTriangleArea
+
+  !-------------------------------------------------------------
+  ! time step
+  !-------------------------------------------------------------
+  
+  subroutine run_dynamics_evp(mesh, icestate, dynamics, basis, forcing, boundary)
+
+    use cice_dynamics_shared, only: ice_strength, air_stress, ocean_stress, surface_tilt, solve_velocity
+
+    type(mesh_type), intent(in) :: mesh
+
+    type(icestate_type), pointer :: icestate
+    type(dynamics_type), pointer :: dynamics
+    type(basis_type),    pointer :: basis
+    type(forcing_type),  pointer :: forcing
+    type(boundary_type), pointer :: boundary
+
+    real(kind=RKIND) :: timeStep, elasticTimeStep
+
+    call ice_strength(mesh, &amp;     
+         dynamics % icePressure % array, &amp;
+         icestate % iceAreaCell % array, &amp;
+         icestate % iceVolumeCell % array)
+    
+    call stress_tensor(mesh, &amp;
+         dynamics % stress1 % array,         &amp;
+         dynamics % stress2 % array,         &amp;
+         dynamics % stress12 % array,        &amp;
+         dynamics % icePressure % array,     &amp;
+         dynamics % uVelocity % array,       &amp;
+         dynamics % vVelocity % array,       &amp;
+         basis % basisGradientU % array,     &amp;
+         basis % basisGradientV % array,     &amp;
+         boundary % interiorVertex2 % array, &amp;
+         timeStep, elasticTimeStep)
+    
+    call divergence_stress_tensor(mesh, &amp;
+         dynamics % stressDivergenceU % array,       &amp;
+         dynamics % stressDivergenceV % array,       &amp;
+         dynamics % stress1 % array,                 &amp;
+         dynamics % stress2 % array,                 &amp;
+         dynamics % stress12 % array,                &amp;
+         basis % basisGradientU % array,             &amp;   
+         basis % basisGradientV % array,             &amp;
+         basis % basisIntegrals % array,             &amp;
+         basis % triangleCornerAtCellCenter % array, &amp;
+         boundary % boundaryCell % array,            &amp;
+         boundary % interiorVertex2 % array)
+
+    call air_stress(&amp;
+         dynamics % airStressU % array,  &amp;
+         dynamics % airStressV % array,  &amp;
+         forcing % uAirVelocity % array, &amp; 
+         forcing % vAirVelocity % array, &amp;
+         icestate % iceAreaVertex % array)
+    
+    !call ocean_stress(&amp; 
+    !     dynamics % oceanStressU % array,     &amp;
+    !     dynamics % oceanStressV % array,     &amp;
+    !     dynamics % oceanStressCoeff % array, &amp;
+    !     forcing % uOceanVelocity % array,    &amp; 
+    !     forcing % vOceanVelocity % array,    &amp;
+    !     dynamics % uVelocity % array,        &amp;   
+    !     dynamics % vVelocity % array,        &amp;
+    !     icestate % iceAreaCell % array)
+    
+    call surface_tilt(&amp;
+         dynamics % surfaceTiltForceU % array, &amp;
+         dynamics % surfaceTiltForceV % array)
+    
+    call solve_velocity(mesh % nCells,         &amp;
+         boundary % interiorVertex % array,    &amp;
+         dynamics % uVelocity % array,         &amp;   
+         dynamics % vVelocity % array,         &amp;
+         iceState % totalMassCell % array,     &amp; 
+         mesh % fCell % array,                 &amp;
+         dynamics % stressDivergenceU % array, &amp; 
+         dynamics % stressDivergenceV % array, &amp;
+         dynamics % airStressU % array,        &amp;
+         dynamics % airStressV % array,        &amp;
+         dynamics % surfaceTiltForceU % array, &amp;
+         dynamics % surfaceTiltForceV % array, &amp;
+         dynamics % oceanStressU % array,      &amp;
+         dynamics % oceanStressV % array,      &amp;
+         dynamics % oceanStressCoeff % array,  &amp;
+         timeStep)
+
+  end subroutine run_dynamics_evp
+
+  !-------------------------------------------------------------
+  
+  subroutine stress_tensor(mesh, &amp;
+                           stress1,        stress2,        &amp;
+                           stress12,                       &amp;
+                           icePressure,                    &amp;
+                           uVelocity,      vVelocity,      &amp;
+                           basisGradientU, basisGradientV, &amp;
+                           interiorVertex,                 &amp;
+                           timeStep,       elasticTimeStep)
+
+    use cice_dynamics_shared, only: evp_constitutive_relation
+
+    type(mesh_type), intent(in) :: mesh
+
+    real(kind=RKIND), dimension(:,:), intent(out) :: &amp;
+         stress1, &amp;
+         stress2, &amp;
+         stress12
+
+    real(kind=RKIND), dimension(:), intent(in) :: &amp;
+         uVelocity, &amp;
+         vVelocity
+
+    real(kind=RKIND), dimension(:,:), intent(in) :: &amp;
+         basisGradientU, &amp;
+         basisGradientV
+
+    real(kind=RKIND), dimension(:), intent(in) :: &amp;
+         icePressure
+
+    integer, dimension(:), intent(in) :: &amp;
+         interiorVertex
+
+    real(kind=RKIND), intent(in) :: &amp;
+         timeStep,  &amp;
+         elasticTimeStep
+
+    real(kind=RKIND) :: &amp;
+         strainDivergence, &amp; ! divergence of the strain rate tensor
+         strainTension,    &amp; ! horizontal tension of the strain rate tensor
+         strainShearing      ! horizontal shearing of the strain rate tensor
+
+    integer :: &amp;
+         iVertex,       &amp;
+         iVertexDegree, &amp;
+         iCell
+
+    ! loop over the triangles
+    do iVertex = 1, mesh % nVertices
+
+       if (interiorVertex(iVertex) == 1) then
+          
+          strainDivergence = 0.0_RKIND
+          strainTension    = 0.0_RKIND
+          strainShearing   = 0.0_RKIND
+          
+          ! loop over corners of triangle
+          do iVertexDegree = 1, mesh % vertexDegree
+             
+             iCell = mesh % cellsOnVertex % array(iVertexDegree, iVertex)
+             
+             ! divergence of the strain rate tensor
+             strainDivergence = strainDivergence + &amp;
+                  uVelocity(iCell) * basisGradientU(iVertexDegree,iVertex) + &amp;
+                  vVelocity(iCell) * basisGradientV(iVertexDegree,iVertex)
+             
+             ! horizontal tension of the strain rate tensor
+             strainTension = strainTension + &amp;
+                  uVelocity(iCell) * basisGradientU(iVertexDegree,iVertex) - &amp;
+                  vVelocity(iCell) * basisGradientV(iVertexDegree,iVertex)
+             
+             ! horizontal shearing of the strain rate tensor
+             strainShearing = strainShearing + &amp;
+                  uVelocity(iCell) * basisGradientV(iVertexDegree,iVertex) + &amp;
+                  vVelocity(iCell) * basisGradientU(iVertexDegree,iVertex)
+             
+          enddo ! iVertexDegree
+          
+          ! loop over corners of triangle
+          do iVertexDegree = 1, mesh % vertexDegree
+             
+             iCell = mesh % cellsOnVertex % array(iVertexDegree, iVertex)
+             
+             !call evp_constitutive_relation(stress1(iVertexDegree,iVertex),                     &amp;
+             !                               stress2(iVertexDegree,iVertex),                     &amp;
+             !                               stress12(iVertexDegree,iVertex),                    &amp;
+             !                               strainDivergence, strainTension, strainShearing,    &amp;
+             !                               icePressure(iCell), mesh % areaCell % array(iCell), &amp;
+             !                               timeStep, elasticTimeStep)
+  
+          enddo ! iVertexDegree
+
+       endif ! interiorVertex
+
+    enddo ! iVertex
+
+  end subroutine stress_tensor
+
+  !-------------------------------------------------------------
+
+  subroutine divergence_stress_tensor(mesh, &amp;
+                                      divergenceStressU, divergenceStressV, &amp;
+                                      stress1,            stress2,          &amp;
+                                      stress12,                             &amp;
+                                      basisGradientU,     basisGradientV,   &amp;
+                                      basisIntegrals,                       &amp;
+                                      triangleCornerAtCellCenter,           &amp;
+                                      boundaryCell,       interiorVertex2)
+
+    type(mesh_type), intent(in) :: mesh
+
+    real(kind=RKIND), dimension(:), intent(out) :: &amp;
+         divergenceStressU, &amp;
+         divergenceStressV
+
+    real(kind=RKIND), dimension(:,:), intent(in) :: &amp;
+         stress1,        &amp;
+         stress2,        &amp;
+         stress12,       &amp;
+         basisGradientU, &amp;
+         basisGradientV, &amp;
+         basisIntegrals
+
+    integer, dimension(:,:), intent(in) :: &amp;
+         triangleCornerAtCellCenter
+
+    integer, dimension(:), intent(in) :: &amp;
+         boundaryCell, &amp;
+         interiorVertex2
+
+    integer :: &amp;
+         iCell,         &amp;
+         iVertexOnCell, &amp;
+         iVertex,       &amp;
+         iVertexDegree, &amp;
+         jVertexDegree
+
+
+    real(kind=RKIND) :: &amp;
+         stress1contribU, &amp;
+         stress2contribU, &amp;
+         stress12contribU, &amp;
+         stress1contribV, &amp;
+         stress2contribV, &amp;
+         stress12contribV
+
+    write(*,*) &quot;divergence start&quot;, mesh % nCells
+
+    ! loop over velocity positions
+    do iCell = 1, mesh % nCells
+
+       ! only cells interior to our smaller domain
+       if (boundaryCell(iCell) == 0) then
+
+          divergenceStressU(iCell) = 0.0_RKIND
+          divergenceStressV(iCell) = 0.0_RKIND   
+          
+          ! loop over triangles surrounding velocity position
+          do iVertexOnCell = 1, mesh % nEdgesOnCell % array(iCell)
+             
+             ! vertex index of the current triangle
+             iVertex = mesh % verticesOnCell % array(iVertexOnCell, iCell)
+
+             stress1contribU  = 0.0_RKIND
+             stress2contribU  = 0.0_RKIND
+             stress12contribU = 0.0_RKIND
+             
+             stress1contribV  = 0.0_RKIND
+             stress2contribV  = 0.0_RKIND
+             stress12contribV = 0.0_RKIND
+             
+             ! only internal triangles at the mo
+             !if (interiorVertex2(iVertex) == 1) then
+             
+                ! vertex number of vertex triangle from this cell
+                jVertexDegree = triangleCornerAtCellCenter(iVertexOnCell, iCell)
+                
+                do iVertexDegree = 1, mesh % vertexDegree
+
+                   stress1contribU  = stress1contribU  + stress1(iVertexDegree,iVertex)  * basisGradientU(iVertexDegree,iVertex) * basisIntegrals(iVertexDegree,iVertex)
+                   stress2contribU  = 0.0_RKIND
+                   stress12contribU = stress12contribU + stress12(iVertexDegree,iVertex) * basisGradientV(iVertexDegree,iVertex) * basisIntegrals(iVertexDegree,iVertex)
+                   
+                   stress1contribV  = 0.0_RKIND
+                   stress2contribV  = stress2contribV  + stress2(iVertexDegree,iVertex)  * basisGradientV(jVertexDegree,iVertex) * basisIntegrals(iVertexDegree,iVertex)
+                   stress12contribV = stress12contribV + stress12(iVertexDegree,iVertex) * basisGradientU(jVertexDegree,iVertex) * basisIntegrals(iVertexDegree,iVertex)
+                
+                   ! divergence of the stress tensor in u direction
+                   !divergenceStressU(iCell) = divergenceStressU(iCell) + &amp;
+                   !     stress1(iVertexDegree,iVertex)  * basisGradientU(iVertexDegree,iVertex) * basisIntegrals(iVertexDegree,iVertex) * 0.5_RKIND + &amp;
+                   !     stress2(iVertexDegree,iVertex)  * basisGradientU(iVertexDegree,iVertex) * basisIntegrals(iVertexDegree,iVertex) * 0.5_RKIND + &amp;
+                   !     stress12(iVertexDegree,iVertex) * basisGradientV(iVertexDegree,iVertex) * basisIntegrals(iVertexDegree,iVertex)
+                   
+                   ! divergence of the stress tensor in v direction
+                   !divergenceStressV(iCell) = divergenceStressV(iCell) + &amp;
+                   !     stress1(iVertexDegree,iVertex)  * basisGradientV(jVertexDegree,iVertex) * basisIntegrals(iVertexDegree,iVertex) * 0.5_RKIND + &amp;
+                   !     stress2(iVertexDegree,iVertex)  * basisGradientV(jVertexDegree,iVertex) * basisIntegrals(iVertexDegree,iVertex) * 0.5_RKIND + &amp;
+                   !     stress12(iVertexDegree,iVertex) * basisGradientU(jVertexDegree,iVertex) * basisIntegrals(iVertexDegree,iVertex)
+
+                   write(*,*) iCell, iVertexOnCell, iVertexDegree, stress1(iVertexDegree,iVertex), basisGradientU(iVertexDegree,iVertex), basisIntegrals(iVertexDegree,iVertex)
+                   
+                enddo ! iVertexDegree
+                
+             !endif ! interiorVertex2
+
+             divergenceStressU(iCell) = divergenceStressU(iCell) + &amp;
+                  (stress1contribU + stress12contribU) / mesh % areaTriangle % array(iVertex)
+
+             divergenceStressV(iCell) = divergenceStressV(iCell) + &amp;
+                  (stress2contribU + stress12contribU) / mesh % areaTriangle % array(iVertex)
+
+          enddo ! iVertexOnCell
+
+          write(*,*) iCell, divergenceStressU(iCell), divergenceStressV(iCell)
+
+       endif ! boundaryCell
+
+    enddo ! iCell
+
+    write(*,*) &quot;divergence&quot;
+
+  end subroutine divergence_stress_tensor
+
+  !-------------------------------------------------------------
+
+  subroutine test_tri_divergence_stress_tensor(mesh, dynamics, basis, boundary)
+
+    use cice_testing, only: divergence_stress_test_stress_set_tri
+
+    type(mesh_type), intent(in) :: mesh
+    type(dynamics_type), pointer :: dynamics
+    type(basis_type),    pointer :: basis
+    type(boundary_type), pointer :: boundary
+
+    write(*,*) &quot;divergence test&quot;
+
+    call divergence_stress_test_stress_set_tri(mesh, &amp;
+                                               dynamics % stress1 % array, &amp;
+                                               dynamics % stress2 % array, &amp;
+                                               dynamics % stress12 % array)
+
+    call divergence_stress_tensor(mesh, &amp;
+         dynamics % stressDivergenceU % array,       &amp;
+         dynamics % stressDivergenceV % array,       &amp;
+         dynamics % stress1 % array,                 &amp;
+         dynamics % stress2 % array,                 &amp;
+         dynamics % stress12 % array,                &amp;
+         basis % basisGradientU % array,             &amp;
+         basis % basisGradientV % array,             &amp;
+         basis % basisIntegrals % array,             &amp;
+         basis % triangleCornerAtCellCenter % array, &amp;
+         boundary % boundaryCell % array,            &amp;
+         boundary % interiorVertex % array)
+
+    stop
+
+  end subroutine test_tri_divergence_stress_tensor
+
+  !-------------------------------------------------------------
+  ! boundary
+  !-------------------------------------------------------------
+
+  subroutine divergence_stress_tensor_boundary(mesh, &amp;
+                                               divergenceStressU, divergenceStressV, &amp;
+                                               uVelocity,         vVelocity,         &amp;
+                                               icePressure,       basisIntegrals,    &amp;
+                                               basisGradientU,    basisGradientV,    &amp;
+                                               boundaryCell,      boundaryCell2,     &amp;
+                                               boundaryVertex2,                      &amp;
+                                               timeStep,          elasticTimeStep)
+
+    use cice_dynamics_shared, only: evp_constitutive_relation
+
+    type(mesh_type), intent(in) :: mesh
+
+    real(kind=RKIND), dimension(:), intent(inout) :: &amp;
+         divergenceStressU, &amp;
+         divergenceStressV
+
+    real(kind=RKIND), dimension(:), intent(in) :: &amp;
+         uVelocity, &amp;
+         vVelocity, &amp;
+         icePressure
+
+    real(kind=RKIND), dimension(:,:), intent(in) :: &amp;
+         basisIntegrals, &amp;
+         basisGradientU, &amp;
+         basisGradientV
+
+    integer, dimension(:), intent(in) :: &amp;
+          boundaryCell,    &amp;
+          boundaryCell2,   &amp;
+          boundaryVertex2
+
+    real(kind=RKIND), intent(in) :: &amp;
+         timeStep,  &amp;
+         elasticTimeStep
+
+    real(kind=RKIND) :: &amp;
+         strainDivergence, &amp;
+         strainTension, &amp;
+         strainShearing, &amp;
+         stress1, &amp;
+         stress2, &amp;
+         stress12, &amp;
+         divergenceStressUBoundary, &amp;
+         divergenceStressVBoundary, &amp;
+         areaCorrection
+
+    integer :: &amp;
+         iCell, &amp;
+         iVertexOnCell, &amp;
+         iVertex, &amp;
+         iVertexDegree, &amp;
+         iCellTriangleCorner, &amp;
+         jVertexDegree
+
+    ! loop over all velocity points
+    do iCell = 1, mesh % nCells
+
+       ! interior boundary velocity points
+       if (boundaryCell2(iCell) == 1) then
+
+          ! find the triangles we still need to sum
+          do iVertexOnCell = 1, mesh % nEdgesOnCell % array(iCell) 
+
+             iVertex = mesh % verticesOnCell % array(iVertexOnCell,iCell)
+
+             if (boundaryVertex2(iVertex) == 1) then
+
+                strainDivergence = 0.0_RKIND
+                strainTension    = 0.0_RKIND
+                strainShearing   = 0.0_RKIND
+
+                areaCorrection = 0.0_RKIND
+
+                ! loop over triangle vertices
+                do iVertexDegree = 1, mesh % vertexDegree
+
+                   iCellTriangleCorner = mesh % cellsOnVertex % array(iVertexDegree,iVertex)
+
+                   if (boundaryCell(iCellTriangleCorner) == 0) then
+                      ! interior triangle corner
+                      areaCorrection = areaCorrection + mesh % kiteAreasOnVertex % array(iVertexDegree,iVertex)
+
+                      ! divergence of the strain rate tensor
+                      strainDivergence = strainDivergence + &amp;
+                           uVelocity(iCellTriangleCorner) * basisGradientU(iVertexDegree,iVertex) + &amp;
+                           vVelocity(iCellTriangleCorner) * basisGradientV(iVertexDegree,iVertex)
+                      
+                      ! horizontal tension of the strain rate tensor
+                      strainTension = strainTension + &amp;
+                           uVelocity(iCellTriangleCorner) * basisGradientU(iVertexDegree,iVertex) - &amp;
+                           vVelocity(iCellTriangleCorner) * basisGradientV(iVertexDegree,iVertex)
+                      
+                      ! horizontal shearing of the strain rate tensor
+                      strainShearing = strainShearing + &amp;
+                           uVelocity(iCellTriangleCorner) * basisGradientV(iVertexDegree,iVertex) + &amp;
+                           vVelocity(iCellTriangleCorner) * basisGradientU(iVertexDegree,iVertex)
+
+                   else
+                      ! exterior triangle corner
+
+                      ! divergence of the strain rate tensor
+                      strainDivergence = strainDivergence - &amp;
+                           uVelocity(iCell) * basisGradientU(iVertexDegree,iVertex) - &amp;
+                           vVelocity(iCell) * basisGradientV(iVertexDegree,iVertex)
+                      
+                      ! horizontal tension of the strain rate tensor
+                      strainTension = strainTension - &amp;
+                           uVelocity(iCell) * basisGradientU(iVertexDegree,iVertex) + &amp;
+                           vVelocity(iCell) * basisGradientV(iVertexDegree,iVertex)
+                      
+                      ! horizontal shearing of the strain rate tensor
+                      strainShearing = strainShearing - &amp;
+                           uVelocity(iCell) * basisGradientV(iVertexDegree,iVertex) - &amp;
+                           vVelocity(iCell) * basisGradientU(iVertexDegree,iVertex)
+
+                   endif ! boundaryCell
+                   
+                enddo ! iVertexDegree
+
+                areaCorrection = areaCorrection / mesh % areaCell % array(iCell)
+                
+                ! calculate stress assuming all ice strength equal that at iCell
+                !call evp_constitutive_relation(stress1,          stress2,       stress12,          &amp;
+                !                               strainDivergence, strainTension, strainShearing,    &amp;
+                !                               icePressure(iCell), mesh % areaCell % array(iCell), &amp;
+                !                               timeStep, elasticTimeStep)
+
+                ! vertex number of vertex triangle from this cell
+                !jVertexDegree = triangleCornerAtCellCenter(iVertexOnCell, iCell) ????
+                
+                divergenceStressUBoundary = 0.0_RKIND
+                divergenceStressVBoundary = 0.0_RKIND
+
+                do iVertexDegree = 1, mesh % vertexDegree
+                   
+                   ! divergence of the stress tensor in u direction
+                   divergenceStressUBoundary = divergenceStressUBoundary + &amp;
+                        stress1  * basisGradientU(iVertexDegree,iVertex) * basisIntegrals(iVertexDegree,iVertex) * 0.5_RKIND + &amp;
+                        stress2  * basisGradientU(iVertexDegree,iVertex) * basisIntegrals(iVertexDegree,iVertex) * 0.5_RKIND + &amp;
+                        stress12 * basisGradientV(iVertexDegree,iVertex) * basisIntegrals(iVertexDegree,iVertex)
+                   
+                   ! divergence of the stress tensor in v direction
+                   divergenceStressVBoundary = divergenceStressVBoundary + &amp;
+                        stress1  * basisGradientV(jVertexDegree,iVertex) * basisIntegrals(iVertexDegree,iVertex) * 0.5_RKIND + &amp;
+                        stress2  * basisGradientV(jVertexDegree,iVertex) * basisIntegrals(iVertexDegree,iVertex) * 0.5_RKIND + &amp;
+                        stress12 * basisGradientU(jVertexDegree,iVertex) * basisIntegrals(iVertexDegree,iVertex)
+                   
+                enddo ! iVertexDegree
+
+                divergenceStressU(iCell) = divergenceStressU(iCell) + divergenceStressUBoundary * areaCorrection
+                divergenceStressV(iCell) = divergenceStressV(iCell) + divergenceStressVBoundary * areaCorrection
+
+             endif ! boundaryVertex2
+
+          enddo ! iVertexOnCell
+
+       endif ! boundaryCell2
+       
+    enddo ! iCell
+
+  end subroutine divergence_stress_tensor_boundary
+
+  !------------------------------------------------------------- 
+
+  subroutine set_boundary_velocity(mesh, &amp;
+                                   uVelocityBoundary, vVelocityBoundary, &amp;
+                                   uVelocity,         vVelocity,         &amp;
+                                   boundaryCell)
+
+    type(mesh_type), intent(in) :: mesh
+
+    real(kind=RKIND), dimension(:,:), intent(out) :: &amp;
+         uVelocityBoundary, &amp;
+         vVelocityBoundary
+
+    real(kind=RKIND), dimension(:), intent(in) :: &amp;    
+         uVelocity, &amp;
+         vVelocity
+
+    integer, dimension(:), intent(in) :: &amp;
+         boundaryCell
+
+    integer :: &amp;
+         iCell, &amp;
+         iEdgeOnCell, &amp;
+         iCellNeighbour
+
+    ! loop over all possible velocity points
+    do iCell = 1, mesh % nCells
+
+       ! only boundary velocity points
+       if (boundaryCell(iCell) == 1) then
+
+          ! loop over surrounding cells
+          do iEdgeOnCell = 1, mesh % nEdgesOnCell % array(iCell)
+
+             ! cell number of neighbouring cell
+             iCellNeighbour = mesh % cellsOnCell % array(iEdgeOnCell,iCell)
+
+             ! check if this is interior cell
+             if (boundaryCell(iCellNeighbour) == 0) then
+
+                uVelocityBoundary(iEdgeOnCell,iCell) = -uVelocity(iCellNeighbour)
+                vVelocityBoundary(iEdgeOnCell,iCell) = -vVelocity(iCellNeighbour)
+
+             endif ! boundaryCell
+
+          enddo ! iEdgeOnCell
+
+       endif ! boundaryCell
+
+    enddo ! iCell
+
+  end subroutine set_boundary_velocity
+
+  !-------------------------------------------------------------
+
+end module cice_dynamics_evp_tri
+

Added: branches/cice_projects/initial_cice_core/src/core_cice/mpas_cice_dynamics_shared.F
===================================================================
--- branches/cice_projects/initial_cice_core/src/core_cice/mpas_cice_dynamics_shared.F                                (rev 0)
+++ branches/cice_projects/initial_cice_core/src/core_cice/mpas_cice_dynamics_shared.F        2013-04-19 18:44:55 UTC (rev 2780)
@@ -0,0 +1,1448 @@
+module cice_dynamics_shared
+
+  use mpas_grid_types
+
+  implicit none
+
+
+  private
+
+  ! Weak formulation
+  public :: init_weak_dynamics, &amp;
+            run_dynamics, &amp;
+            test_stress_divergence
+
+  ! Legacy
+  public :: boundary_cells, &amp;
+            boundary_vertices, &amp;
+            boundary_edges, &amp;
+            ice_strength, &amp;
+            evp_constitutive_relation, &amp;
+            linear_constitutive_relation, &amp;
+            air_stress, &amp;
+            ocean_stress, &amp;
+            solve_velocity, &amp;
+            surface_tilt, &amp;
+            solve_linear_basis_system
+
+  real(kind=RKIND), parameter, public :: &amp;
+       sinOceanTurningAngle = 0.0_RKIND, &amp;
+       cosOceanTurningAngle = 1.0_RKIND
+
+  
+  real(kind=RKIND), parameter :: &amp;
+       Pstar = 2.75e4_RKIND, &amp; ! constant in Hibler strength formula 
+       Cstar = 20.0_RKIND  , &amp; ! constant in Hibler strength formula 
+       eccentricity = 2.0_RKIND, &amp;
+       dampingTimescaleParameter = 0.36_RKIND, &amp;
+       puny = 1.0e-11_RKIND
+
+  real(kind=RKIND) :: &amp;
+       dtDynamics, &amp;
+       dtElastic, &amp;
+       dampingTimescale, &amp;
+       elapsedTime
+
+  integer, parameter :: &amp;
+       nElasticSubcycle = 120 ! will be from namelist
+
+contains
+
+  !-------------------------------------------------------------
+  ! Initialization
+  !-------------------------------------------------------------
+  
+  subroutine init_weak_dynamics(mesh, weak, boundary, dt)
+
+    type(mesh_type), intent(inout) :: mesh
+
+    type(weak_type),     pointer :: weak
+    type(boundary_type), pointer :: boundary
+
+    real(kind=RKIND), intent(in) :: dt
+
+    call boundary_vertices_weak(mesh, &amp;
+         boundary % interiorVertex % array)
+
+    call normal_vectors_planar(mesh, &amp;
+         weak % normalVectorPolygon % array, &amp;
+         weak % normalVectorTriangle % array, &amp;
+         boundary % interiorVertex % array)
+
+    call init_evp(dt)
+
+    mesh % fVertex % array = 0.0_RKIND
+
+  end subroutine init_weak_dynamics
+
+  !-------------------------------------------------------------
+
+  subroutine boundary_vertices_weak(mesh, interiorVertex)
+
+    type(mesh_type), intent(in) :: mesh
+
+    integer, dimension(:), intent(out) :: &amp;
+         interiorVertex
+
+    integer :: &amp;
+         nInteriorAdjacentCells
+
+    integer :: &amp;
+         iVertex, &amp;
+         iVertexDegree, &amp;
+         iCell
+
+    ! boundary vertices
+    do iVertex = 1, mesh % nVertices
+
+       interiorVertex(iVertex) = 0
+       
+       nInteriorAdjacentCells = 0
+
+       do iVertexDegree = 1, mesh % vertexDegree
+
+          iCell = mesh % cellsOnVertex % array(iVertexDegree, iVertex)
+          
+          if (iCell &gt;= 1 .and. iCell &lt;= mesh % nCells) then
+             
+             nInteriorAdjacentCells = nInteriorAdjacentCells + 1
+             
+          endif
+          
+       enddo ! iVertexDegree
+
+       ! vertex points we directly calculate on
+       if (nInteriorAdjacentCells == 3) then
+
+          interiorVertex(iVertex) = 1
+          
+       endif
+       
+    enddo ! iVertex
+
+  end subroutine boundary_vertices_weak
+
+  !-------------------------------------------------------------
+
+  subroutine normal_vectors_planar(mesh, normalVectorPolygon, normalVectorTriangle, interiorVertex)
+
+    type(mesh_type), intent(in) :: mesh
+
+    real(kind=RKIND), dimension(:,:,:), intent(out) :: &amp;
+         normalVectorPolygon, &amp;
+         normalVectorTriangle
+
+    integer, dimension(:), intent(in) :: &amp;
+         interiorVertex
+
+    call normal_vectors_planar_polygon(mesh, normalVectorPolygon)
+
+    call normal_vectors_planar_triangle(mesh, normalVectorTriangle, interiorVertex)
+
+  end subroutine normal_vectors_planar
+
+  !-------------------------------------------------------------
+
+  subroutine normal_vectors_planar_polygon(mesh, normalVectorPolygon)
+
+    type(mesh_type), intent(in) :: mesh
+
+    real(kind=RKIND), dimension(:,:,:), intent(out) :: &amp;
+         normalVectorPolygon
+
+    integer :: &amp;
+         iCell, &amp;
+         iEdgeOnCell, &amp;
+         iEdge
+
+    real(kind=RKIND) :: &amp;
+         dx, dy
+
+    do iCell = 1, mesh % nCells
+
+       do iEdgeOnCell = 1, mesh % nEdgesOnCell % array(iCell)
+          
+          iEdge = mesh % edgesOnCell % array(iEdgeOnCell,iCell)
+
+          dx = mesh % xEdge % array(iEdge) - mesh % xCell % array(iCell)
+          dy = mesh % yEdge % array(iEdge) - mesh % yCell % array(iCell)
+
+          normalVectorPolygon(1,iEdgeOnCell,iCell) = dx / sqrt(dx**2 + dy**2)
+          normalVectorPolygon(2,iEdgeOnCell,iCell) = dy / sqrt(dx**2 + dy**2)
+
+       enddo ! iEdgeOnCell
+
+    enddo ! iCell
+
+  end subroutine normal_vectors_planar_polygon
+
+  !-------------------------------------------------------------
+
+  subroutine normal_vectors_planar_triangle(mesh, normalVectorTriangle, interiorVertex)
+
+    type(mesh_type), intent(in) :: mesh
+
+    real(kind=RKIND), dimension(:,:,:), intent(out) :: &amp;
+         normalVectorTriangle
+
+    integer, dimension(:), intent(in) :: &amp;
+         interiorVertex
+
+    integer :: &amp;
+         iVertex, &amp;
+         iVertexDegree, &amp;
+         iEdge
+
+    real(kind=RKIND) :: &amp;
+         dx, dy
+
+    do iVertex = 1, mesh % nVertices
+
+       normalVectorTriangle(:,:,iVertex) = 0.0_RKIND
+
+       if (interiorVertex(iVertex) == 1) then
+
+          do iVertexDegree = 1, mesh % vertexDegree
+             
+             iEdge = mesh % edgesOnVertex % array(iVertexDegree,iVertex)
+             
+             dx = mesh % xEdge % array(iEdge) - mesh % xVertex % array(iVertex)
+             dy = mesh % yEdge % array(iEdge) - mesh % yVertex % array(iVertex)
+             
+             normalVectorTriangle(1,iVertexDegree,iVertex) = dx / sqrt(dx**2 + dy**2)
+             normalVectorTriangle(2,iVertexDegree,iVertex) = dy / sqrt(dx**2 + dy**2)
+             
+          enddo ! iVertexDegree
+
+       endif ! interiorVertex
+
+    enddo ! iVertex
+
+  end subroutine normal_vectors_planar_triangle
+
+  !-------------------------------------------------------------
+
+  subroutine init_evp(dt)
+
+    real(kind=RKIND), intent(in) :: dt
+
+    dtDynamics = dt
+
+    dtElastic = dtDynamics / real(nElasticSubcycle,RKIND)
+
+    dampingTimescale = dampingTimescaleParameter * dtDynamics
+
+    elapsedTime = 0.0_RKIND
+
+  end subroutine init_evp
+
+  !-------------------------------------------------------------
+  ! Time stepping
+  !-------------------------------------------------------------
+
+  subroutine run_dynamics(mesh, icestate, weak, boundary, dt)
+
+    use cice_testing, only: gnuplot_triangle, gnuplot_cell, writeout_minmax
+
+    type(mesh_type), intent(in) :: mesh
+
+    type(icestate_type), pointer :: icestate
+    type(weak_type),     pointer :: weak
+    type(boundary_type), pointer :: boundary
+
+    real(kind=RKIND), intent(in) :: &amp;
+         dt
+
+    call ice_strength(mesh, &amp;     
+         weak % icePressure % array,    &amp;
+         icestate % iceAreaCell % array,  &amp;
+         icestate % iceVolumeCell % array)
+
+    call interpolate_cell_to_vertex(mesh, &amp;
+         icestate % iceAreaVertex % array, &amp;
+         icestate % iceAreaCell % array)
+
+    call air_stress(&amp;
+         weak % airStressU % array,   &amp;
+         weak % airStressV % array,   &amp;
+         weak % uAirVelocity % array, &amp; 
+         weak % vAirVelocity % array, &amp;
+         icestate % iceAreaVertex % array)
+    
+    call ocean_stress(&amp; 
+         weak % oceanStressU % array,     &amp;
+         weak % oceanStressV % array,     &amp;
+         weak % uOceanVelocity % array,   &amp; 
+         weak % vOceanVelocity % array)
+    
+    !call surface_tilt(&amp;
+    !     weak % surfaceTiltForceU % array, &amp;
+    !     weak % surfaceTiltForceV % array)
+
+    call subcycle_dynamics(mesh, icestate, weak, boundary, &amp;
+                           dtDynamics, dtElastic)
+
+    call principal_stresses(mesh, &amp;
+         weak % principalStress1 % array, &amp;
+         weak % principalStress2 % array, &amp;
+         weak % stress11 % array,         &amp;
+         weak % stress22 % array,         &amp;
+         weak % stress12 % array,         &amp;
+         weak % icePressure % array)
+    
+
+    call gnuplot_triangle(mesh, weak % stressDivergenceU % array, &quot;test.txt&quot;)
+    !call gnuplot_cell(mesh, weak % uVelocity % array, &quot;test.txt&quot;)
+    write(*,*) minval(weak % uVelocity % array), maxval(weak % uVelocity % array)
+    call writeout_minmax()
+    stop
+
+    elapsedTime = elapsedTime + dt
+
+  end subroutine run_dynamics
+
+  !-------------------------------------------------------------
+
+  subroutine subcycle_dynamics(mesh, icestate, weak, boundary, &amp;
+                               dtDynamics, dtElastic)
+
+    use cice_testing, only: gnuplot_triangle, gnuplot_cell, writeout_minmax, gnuplot_vertexvector
+
+    type(mesh_type), intent(in) :: mesh
+
+    type(icestate_type), pointer :: icestate
+    type(weak_type),     pointer :: weak
+    type(boundary_type), pointer :: boundary
+
+    real(kind=RKIND), intent(in) :: &amp;
+         dtDynamics, &amp;
+         dtElastic
+
+    integer :: &amp;
+         iElasticSubcycle
+
+    do iElasticSubcycle = 1, nElasticSubcycle
+
+       write(*,*) &quot;subcycle: &quot;, iElasticSubcycle
+       call single_subcycle_dynamics(mesh, icestate, weak, boundary, &amp;
+                                     dtDynamics, dtElastic)
+
+    enddo
+
+    call gnuplot_triangle(mesh, weak % stressDivergenceU % array, &quot;test.txt&quot;)
+    !call gnuplot_triangle(mesh, weak % uVelocity % array, &quot;test.txt&quot;)
+    !call gnuplot_cell(mesh, weak % stress11 % array, &quot;test.txt&quot;)
+    stop
+
+  end subroutine subcycle_dynamics
+
+  !-------------------------------------------------------------
+
+  subroutine single_subcycle_dynamics(mesh, icestate, weak, boundary, &amp;
+                                      dtDynamics, dtElastic)
+
+    use cice_testing, only: gnuplot_triangle, gnuplot_cell, writeout_minmax, gnuplot_vertexvector
+
+    type(mesh_type), intent(in) :: mesh
+
+    type(icestate_type), pointer :: icestate
+    type(weak_type),     pointer :: weak
+    type(boundary_type), pointer :: boundary
+
+    real(kind=RKIND), intent(in) :: &amp;
+         dtDynamics, &amp;
+         dtElastic
+
+    !weak % uVelocity % array = mesh % xVertex % array
+    !weak % vVelocity % array = 0.0_RKIND
+
+    call strain_tensor(mesh, &amp;
+         weak % strain11 % array,           &amp;
+         weak % strain22 % array,           &amp;
+         weak % strain12 % array,           &amp;
+         weak % uVelocity % array,          &amp;
+         weak % vVelocity % array,          &amp;
+         weak % normalVectorPolygon % array)
+
+    call stress_tensor(mesh, &amp;
+         weak % stress11 % array,    &amp;
+         weak % stress22 % array,    &amp;
+         weak % stress12 % array,    &amp;
+         weak % strain11 % array,    &amp;
+         weak % strain22 % array,    &amp;
+         weak % strain12 % array,    &amp;
+         weak % icePressure % array, &amp;
+         dtDynamics,                 &amp;
+         dtElastic)
+    
+    call stress_divergence(mesh, &amp;
+         weak % stressDivergenceU % array,    &amp;
+         weak % stressDivergenceV % array,    &amp;
+         weak % stress11 % array,             &amp;
+         weak % stress22 % array,             &amp;
+         weak % stress12 % array,             &amp;
+         weak % normalVectorTriangle % array, &amp;
+         boundary % interiorVertex % array)
+    
+    call interpolate_cell_to_vertex(mesh, &amp;
+         icestate % totalMassVertex % array, &amp;
+         icestate % totalMassCell % array)
+
+    call ocean_stress_coefficient(&amp; 
+         weak % oceanStressCoeff % array, &amp;
+         weak % uOceanVelocity % array,   &amp; 
+         weak % vOceanVelocity % array,   &amp;
+         weak % uVelocity % array,        &amp;   
+         weak % vVelocity % array,        &amp;
+         icestate % iceAreaVertex % array)
+
+    call solve_velocity(mesh % nVertices, &amp;
+         boundary % interiorVertex % array,  &amp;
+         weak % uVelocity % array,           &amp;   
+         weak % vVelocity % array,           &amp;
+         icestate % totalMassVertex % array, &amp; 
+         mesh % fVertex % array,             &amp;
+         weak % stressDivergenceU % array,   &amp; 
+         weak % stressDivergenceV % array,   &amp;
+         weak % airStressU % array,          &amp; 
+         weak % airStressV % array,          &amp;
+         weak % surfaceTiltForceU % array,   &amp;
+         weak % surfaceTiltForceV % array,   &amp;
+         weak % oceanStressU % array,        &amp;
+         weak % oceanStressV % array,        &amp;
+         weak % oceanStressCoeff % array,    &amp;
+         dtElastic)
+
+  end subroutine single_subcycle_dynamics
+
+  !-------------------------------------------------------------
+
+  subroutine ice_strength(mesh,        icePressure,   &amp;
+                          iceAreaCell, iceVolumeCell)
+
+    type(mesh_type), intent(in) :: mesh
+
+    real(kind=RKIND), dimension(:), intent(out) :: &amp;
+         icePressure
+
+    real(kind=RKIND), dimension(:), intent(in) :: &amp;
+         iceAreaCell, &amp;
+         iceVolumeCell
+
+    integer :: &amp;
+         iCell
+
+    do iCell = 1, mesh % nCells
+
+       icePressure(iCell) = Pstar * iceVolumeCell(iCell) * exp(-Cstar*(1.0_RKIND-iceAreaCell(iCell)))
+
+    enddo ! iCell
+
+  end subroutine ice_strength
+
+  !-------------------------------------------------------------
+
+  subroutine interpolate_cell_to_vertex(mesh, variableVertex, variableCell)
+
+    type(mesh_type), intent(in) :: mesh
+
+    real(kind=RKIND), dimension(:), intent(out) :: &amp;
+         variableVertex
+
+    real(kind=RKIND), dimension(:), intent(in) :: &amp;
+         variableCell
+
+    real(kind=RKIND) :: &amp;
+         totalArea
+
+    integer :: &amp;
+         iVertex, &amp;
+         iVertexDegree, &amp;
+         iCell
+
+    do iVertex = 1, mesh % nVertices
+    
+       variableVertex(iVertex) = 0.0_RKIND
+       totalArea = 0.0_RKIND
+
+       do iVertexDegree = 1, mesh % vertexDegree
+
+          iCell = mesh % cellsOnVertex % array(iVertexDegree,iVertex) 
+
+          variableVertex(iVertex) = variableVertex(iVertex) + mesh % areaCell % array(iCell) * variableCell(iCell)
+
+          totalArea = totalArea + mesh % areaCell % array(iCell)
+
+       enddo ! iVertexDegree
+
+       variableVertex(iVertex) = variableVertex(iVertex) / totalArea
+
+    enddo ! iVertex    
+
+  end subroutine interpolate_cell_to_vertex
+
+  !-------------------------------------------------------------
+
+  subroutine evp_constitutive_relation(stress1,          stress2,       stress12,       &amp;
+                                       strainDivergence, strainTension, strainShearing, &amp;
+                                       icePressure,      areaCell,                      &amp;
+                                       dtDynamics,       dtElastic,iCell)
+
+    real(kind=RKIND), intent(inout) :: &amp;
+         stress1, &amp;
+         stress2, &amp;
+         stress12
+
+    real(kind=RKIND), intent(inout) :: &amp;
+         strainDivergence, &amp;
+         strainTension,    &amp;
+         strainShearing
+
+    real(kind=RKIND), intent(in) :: &amp;
+         icePressure,      &amp; 
+         areaCell,         &amp;
+         dtDynamics,       &amp;
+         dtElastic
+
+    real(kind=RKIND) :: &amp;
+         Delta, &amp;
+         pressureCoefficient, stress10
+
+    integer :: iCell
+
+    !write(*,*) stress1
+
+    !strainDivergence = 1.0_RKIND
+    !strainTension = 1.0_RKIND
+    !strainShearing = 0.0_RKIND
+
+    !stress1 = 0.0_RKIND
+    !stress2 = 0.0_RKIND
+    !stress12 = 0.0_RKIND
+
+    Delta = sqrt(strainDivergence**2 + &amp;
+         (strainTension**2 + strainShearing**2) / eccentricity**2)
+
+    pressureCoefficient = (icePressure * dtElastic) / (2.0_RKIND * dampingTimescale * max(Delta,puny))
+!stress10 = stress1
+    stress1  = (stress1  + pressureCoefficient * (strainDivergence - Delta)) / &amp;
+               (1.0_RKIND + (0.5_RKIND * dtElastic) / dampingTimescale)
+
+    stress2  = (stress2  + pressureCoefficient * strainTension) / &amp;
+               (1.0_RKIND + (0.5_RKIND * dtElastic * eccentricity**2) / dampingTimescale)
+
+    stress12 = (stress12 + pressureCoefficient * strainShearing * 0.5_RKIND) / &amp;
+               (1.0_RKIND + (0.5_RKIND * dtElastic * eccentricity**2) / dampingTimescale)
+
+    !write(*,*) stress1, icePressure / max(Delta,puny), icePressure
+    !write(*,*) (1.0_RKIND + (0.5_RKIND * dtElastic) / dampingTimescale), dampingTimescale, (0.5_RKIND * dtElastic) / dampingTimescale
+    !stop
+
+    !write(*,*) stress10, stress1, strainDivergence, Delta, icePressure / max(Delta,areaCell * puny), (1.0_RKIND + (0.5_RKIND * dtElastic) / dampingTimescale), (0.5_RKIND * dtElastic) / dampingTimescale
+
+  end subroutine evp_constitutive_relation
+
+  !-------------------------------------------------------------
+
+  subroutine strain_tensor(mesh, strain11, strain22, strain12, uVelocity, vVelocity, normalVectorPolygon)
+
+    type(mesh_type), intent(in) :: mesh
+
+    real(kind=RKIND), dimension(:), intent(out) :: &amp;
+         strain11, &amp;
+         strain22, &amp;
+         strain12
+
+    real(kind=RKIND), dimension(:), intent(in) :: &amp;
+         uVelocity, &amp;
+         vVelocity
+
+    real(kind=RKIND), dimension(:,:,:), intent(in) :: &amp;
+         normalVectorPolygon
+
+
+    integer :: &amp;
+         iCell, &amp;
+         iEdgeOnCell, &amp;
+         iEdge, &amp;
+         iVertexOnEdge, &amp;
+         iVertex
+    
+    real(kind=RKIND) :: &amp;
+         uVelocityEdge, &amp;
+         vVelocityEdge
+    
+    do iCell = 1, mesh % nCells
+
+       strain11(iCell) = 0.0_RKIND
+       strain22(iCell) = 0.0_RKIND
+       strain12(iCell) = 0.0_RKIND
+
+       do iEdgeOnCell = 1, mesh % nEdgesOnCell % array(iCell)
+
+          iEdge = mesh % edgesOnCell % array(iEdgeOnCell,iCell)
+
+          uVelocityEdge = 0.0_RKIND
+          vVelocityEdge = 0.0_RKIND
+
+          do iVertexOnEdge = 1, 2
+
+             iVertex = mesh % verticesOnEdge % array(iVertexOnEdge,iEdge)
+
+             uVelocityEdge = uVelocityEdge + uVelocity(iVertex)
+             vVelocityEdge = vVelocityEdge + vVelocity(iVertex)
+
+          enddo ! iVertexOnEdge
+
+          uVelocityEdge = uVelocityEdge / 2.0_RKIND
+          vVelocityEdge = vVelocityEdge / 2.0_RKIND
+
+          strain11(iCell) = strain11(iCell) + uVelocityEdge * normalVectorPolygon(1,iEdgeOnCell,iCell) * mesh % dvEdge % array(iEdge)
+          strain22(iCell) = strain22(iCell) + vVelocityEdge * normalVectorPolygon(2,iEdgeOnCell,iCell) * mesh % dvEdge % array(iEdge)
+          strain12(iCell) = strain12(iCell) + 0.5_RKIND * ( &amp;
+                                              uVelocityEdge * normalVectorPolygon(2,iEdgeOnCell,iCell) + &amp;
+                                              vVelocityEdge * normalVectorPolygon(1,iEdgeOnCell,iCell) ) * mesh % dvEdge % array(iEdge)
+               
+          !write(*,*) iCell, uVelocityEdge, normalVectorPolygon(1,iEdgeOnCell,iCell), mesh % dvEdge % array(iEdge), &amp;
+          !     uVelocityEdge * normalVectorPolygon(1,iEdgeOnCell,iCell) * mesh % dvEdge % array(iEdge)
+
+
+       enddo ! iEdgeOnCell
+
+       !write(*,*) iCell, strain11(iCell), mesh % areaCell % array(iCell), strain11(iCell) / mesh % areaCell % array(iCell)
+
+       strain11(iCell) = strain11(iCell) / mesh % areaCell % array(iCell)
+       strain22(iCell) = strain22(iCell) / mesh % areaCell % array(iCell)
+       strain12(iCell) = strain12(iCell) / mesh % areaCell % array(iCell)
+
+
+
+    enddo ! iCell
+
+  end subroutine strain_tensor
+
+  !-------------------------------------------------------------
+
+  subroutine stress_tensor(mesh, stress11, stress22, stress12, strain11, strain22, strain12, icePressure, dtDynamics, dtElastic)
+
+    use cice_testing, only: find_nearest_cell
+
+    type(mesh_type), intent(in) :: mesh
+
+    real(kind=RKIND), dimension(:), intent(out) :: &amp;
+         stress11, &amp;
+         stress22, &amp;
+         stress12
+
+    real(kind=RKIND), dimension(:), intent(in) :: &amp;
+         strain11, &amp;
+         strain22, &amp;
+         strain12, &amp;
+         icePressure
+
+    real(kind=RKIND), intent(in) :: &amp;
+         dtDynamics, &amp;
+         dtElastic
+
+    real(kind=RKIND) :: &amp;
+         strainDivergence, &amp;
+         strainTension, &amp;
+         strainShearing, &amp;
+         stress1, &amp;
+         stress2
+         
+    integer :: iCell
+
+    ! start testing!
+    integer :: iCellEx
+    real(kind=RKIND), parameter :: x0 = 1.2e6_RKIND
+    real(kind=RKIND), parameter :: y0 = 6.0e5_RKIND
+
+    ! stop testing!
+
+    do iCell = 1, mesh % nCells
+
+       strainDivergence = strain11(iCell) + strain22(iCell)
+       strainTension    = strain11(iCell) - strain22(iCell)
+       strainShearing   = strain12(iCell) * 2.0_RKIND
+
+       stress1 = stress11(iCell) + stress22(iCell)
+       stress2 = stress11(iCell) - stress22(iCell)
+
+       call evp_constitutive_relation(stress1,          stress2,       stress12(iCell),   &amp;
+                                      strainDivergence, strainTension, strainShearing,    &amp;
+                                      icePressure(iCell), mesh % areaCell % array(iCell), &amp;
+                                      dtDynamics, dtElastic,iCell)
+
+       !call linear_constitutive_relation(stress1,          stress2,       stress12(iCell), &amp;
+       !                                  strainDivergence, strainTension, strainShearing)
+
+       stress11(iCell) = 0.5_RKIND * (stress1 + stress2)
+       stress22(iCell) = 0.5_RKIND * (stress1 - stress2)
+
+       ! start testing!
+       !write(*,*) iCell, strain11(iCell), strain22(iCell), strain12(iCell), stress11(iCell), stress22(iCell), stress12(iCell)
+
+       !stress11(iCell) = strain11(iCell)
+       !stress22(iCell) = strain22(iCell)
+       !stress12(iCell) = strain12(iCell)
+       ! stop testing!
+
+    end do ! iCell
+
+    ! start testing!
+    !iCellEx = find_nearest_cell(mesh,x0,y0)
+    !write(53,*) &quot;stress:&quot;, iCellEx, stress11(iCellEx), stress22(iCellEx), stress12(iCellEx), strain11(iCellEx), strain22(iCellEx), strain12(iCellEx)
+    ! stop testing!
+
+  end subroutine stress_tensor
+
+  !-------------------------------------------------------------
+
+  subroutine stress_divergence(mesh, stressDivergenceU, stressDivergenceV, stress11, stress22, stress12, normalVectorTriangle, interiorVertex)
+
+    type(mesh_type), intent(in) :: mesh
+
+    real(kind=RKIND), dimension(:), intent(out) :: &amp;
+         stressDivergenceU, &amp;
+         stressDivergenceV
+
+    real(kind=RKIND), dimension(:), intent(in) :: &amp;
+         stress11, &amp;
+         stress22, &amp;
+         stress12
+
+    real(kind=RKIND), dimension(:,:,:), intent(in) :: &amp;
+         normalVectorTriangle
+
+    integer, dimension(:), intent(in) :: &amp;
+         interiorVertex
+
+    real(kind=RKIND) :: &amp;
+         stress11Edge, &amp;
+         stress22Edge, &amp;
+         stress12Edge
+
+    integer :: &amp;
+         iVertex, &amp;
+         iVertexDegree, &amp;
+         iEdge, &amp;
+         iCellOnEdge, &amp;
+         iCell
+
+    do iVertex = 1, mesh % nVertices
+
+       if (interiorVertex(iVertex) == 1) then
+
+          stressDivergenceU(iVertex) = 0.0_RKIND
+          stressDivergenceV(iVertex) = 0.0_RKIND
+          
+          do iVertexDegree = 1, mesh % vertexDegree
+             
+             iEdge = mesh % edgesOnVertex % array(iVertexDegree,iVertex)
+             
+             stress11Edge = 0.0_RKIND
+             stress22Edge = 0.0_RKIND
+             stress12Edge = 0.0_RKIND
+             
+             do iCellOnEdge = 1, 2
+                
+                iCell = mesh % cellsOnEdge % array(iCellOnEdge,iEdge)
+                
+                stress11Edge = stress11Edge + stress11(iCell)
+                stress22Edge = stress22Edge + stress22(iCell)
+                stress12Edge = stress12Edge + stress12(iCell)
+
+                !write(*,*) stress11(iCell), stress22(iCell), stress12(iCell)
+                
+             enddo ! iCellOnEdge
+             
+             stress11Edge = stress11Edge / 2.0_RKIND
+             stress22Edge = stress22Edge / 2.0_RKIND
+             stress12Edge = stress12Edge / 2.0_RKIND
+             
+             stressDivergenceU(iVertex) = stressDivergenceU(iVertex) + &amp;
+                  (stress11Edge * normalVectorTriangle(1,iVertexDegree,iVertex) + &amp;
+                  stress12Edge * normalVectorTriangle(2,iVertexDegree,iVertex)) * mesh % dcEdge % array(iEdge)
+             
+             stressDivergenceV(iVertex) = stressDivergenceV(iVertex) + &amp;
+                  (stress22Edge * normalVectorTriangle(2,iVertexDegree,iVertex) + &amp;
+                  stress12Edge * normalVectorTriangle(1,iVertexDegree,iVertex)) * mesh % dcEdge % array(iEdge)
+
+          enddo ! iVertexDegree
+          
+          stressDivergenceU(iVertex) = stressDivergenceU(iVertex) / mesh % areaTriangle % array(iVertex)
+          stressDivergenceV(iVertex) = stressDivergenceV(iVertex) / mesh % areaTriangle % array(iVertex)
+
+          !write(*,*) iVertex, stressDivergenceU(iVertex), stressDivergenceV(iVertex)
+
+       endif ! interiorVertex
+
+    enddo ! iVertex
+
+  end subroutine stress_divergence
+
+  !-------------------------------------------------------------
+
+  subroutine solve_velocity(nPoints,           solvePoints,       &amp;
+                            uVelocity,         vVelocity,         &amp;
+                            mass,              coriolisParameter, &amp;
+                            stressDivergenceU, stressDivergenceV, &amp;
+                            airStressU,        airStressV,        &amp;
+                            surfaceTiltForceU, surfaceTiltForceV, &amp;
+                            oceanStressU,      oceanStressV,      &amp;
+                            oceanStressCoeff,  dtElastic)
+
+    integer, intent(in) :: &amp;
+         nPoints
+
+    integer, dimension(:), intent(in) :: &amp;
+         solvePoints
+
+    real(kind=RKIND), dimension(:), intent(out) :: &amp;
+         uVelocity, &amp;
+         vVelocity
+
+    real(kind=RKIND), dimension(:), intent(in) :: &amp;
+         mass,              &amp;
+         coriolisParameter, &amp;
+         stressDivergenceU, &amp;
+         stressDivergenceV, &amp;
+         airStressU,        &amp;
+         airStressV,        &amp;
+         surfaceTiltForceU, &amp;
+         surfaceTiltForceV, &amp;
+         oceanStressU,      &amp;
+         oceanStressV,      &amp;
+         oceanStressCoeff
+
+    real(kind=RKIND), intent(in) :: &amp;
+         dtElastic
+
+    real(kind=RKIND), dimension(2) :: &amp;
+         rightHandSide
+
+    real(kind=RKIND), dimension(2,2) :: &amp;
+         leftMatrix
+
+    real(kind=RKIND) :: &amp;
+         solutionDenominator
+
+    integer :: &amp;
+         iPoint
+
+    do iPoint = 1, nPoints
+
+       if (solvePoints(iPoint) == 1) then
+
+          ! U equation
+          leftMatrix(1,1) =  mass(iPoint) / dtElastic                 + oceanStressCoeff(iPoint) * cosOceanTurningAngle
+          leftMatrix(1,2) = -mass(iPoint) * coriolisParameter(iPoint) - oceanStressCoeff(iPoint) * sinOceanTurningAngle
+
+          ! V equation
+          leftMatrix(2,1) =  mass(iPoint) * coriolisParameter(iPoint) + oceanStressCoeff(iPoint) * sinOceanTurningAngle
+          leftMatrix(2,2) =  mass(iPoint) / dtElastic                 + oceanStressCoeff(iPoint) * cosOceanTurningAngle
+
+          ! right hand side of matrix solve
+          rightHandSide(1) = stressDivergenceU(iPoint) + airStressU(iPoint) + surfaceTiltForceU(iPoint) + &amp;
+               oceanStressCoeff(iPoint) * oceanStressU(iPoint) + (mass(iPoint) * uVelocity(iPoint)) / dtElastic
+
+          rightHandSide(2) = stressDivergenceV(iPoint) + airStressV(iPoint) + surfaceTiltForceV(iPoint) + &amp;
+               oceanStressCoeff(iPoint) * oceanStressV(iPoint) + (mass(iPoint) * vVelocity(iPoint)) / dtElastic
+
+          ! solve the equation
+          solutionDenominator = leftMatrix(1,1) * leftMatrix(2,2) - leftMatrix(1,2) * leftMatrix(2,1)
+
+          uVelocity(iPoint) = (leftMatrix(2,2) * rightHandSide(1) - leftMatrix(1,2) * rightHandSide(2)) / solutionDenominator
+          vVelocity(iPoint) = (leftMatrix(1,1) * rightHandSide(2) - leftMatrix(2,1) * rightHandSide(1)) / solutionDenominator
+
+          !write(*,*) iPoint, leftMatrix(1,1), leftMatrix(1,2), leftMatrix(2,1), leftMatrix(2,2), rightHandSide(1), rightHandSide(2), uVelocity(iPoint), vVelocity(iPoint) 
+          !write(*,*) stressDivergenceU(iPoint), airStressU(iPoint), surfaceTiltForceU(iPoint), &amp;
+          !     oceanStressCoeff(iPoint) * oceanStressU(iPoint), mass(iPoint), uVelocity(iPoint), dtElastic
+          !write(*,*) iPoint, uVelocity(iPoint), stressDivergenceU(iPoint), airStressU(iPoint), mass(iPoint) / dtElastic
+
+          !write(*,*) iPoint, mass(iPoint), dtElastic
+
+
+       endif ! solvePoints
+
+    enddo ! iCell
+
+    !stop
+
+  end subroutine solve_velocity
+
+  !-------------------------------------------------------------
+
+  subroutine air_stress(airStressU, airStressV, uAirVelocity, vAirVelocity, iceAreaVertex)
+
+    real(kind=RKIND), dimension(:), intent(out) :: &amp;
+         airStressU, &amp;
+         airStressV
+
+    real(kind=RKIND), dimension(:), intent(in) :: &amp;
+         uAirVelocity, &amp;
+         vAirVelocity, &amp;
+         iceAreaVertex
+
+    real(kind=RKIND) :: &amp;
+         windSpeed
+
+    integer :: &amp;
+         nPoints, &amp;
+         iPoint
+
+    real(kind=RKIND), parameter :: &amp;
+         airStressCoeff = 0.0012_RKIND, &amp;
+         densityAir     = 1.3_RKIND 
+    
+    nPoints = size(airStressU,1)
+
+    do iPoint = 1, nPoints
+
+       windSpeed = sqrt(uAirVelocity(iPoint)**2 + vAirVelocity(iPoint)**2)
+
+       airStressU(iPoint) = densityAir * windSpeed * airStressCoeff * uAirVelocity(iPoint) * iceAreaVertex(iPoint)
+       airStressV(iPoint) = densityAir * windSpeed * airStressCoeff * vAirVelocity(iPoint) * iceAreaVertex(iPoint)
+
+    enddo ! iPoint
+    
+  end subroutine air_stress
+
+  !-------------------------------------------------------------
+
+  subroutine ocean_stress(oceanStressU, oceanStressV, &amp;
+                          uOceanVelocity, vOceanVelocity)
+
+    real(kind=RKIND), dimension(:), intent(out) :: &amp;
+         oceanStressU, &amp;
+         oceanStressV
+
+    real(kind=RKIND), dimension(:), intent(in) :: &amp;
+         uOceanVelocity, &amp;
+         vOceanVelocity
+
+    integer :: &amp;
+         nPoints, &amp;
+         iPoint
+
+    nPoints = size(oceanStressU,1)
+
+    do iPoint = 1, nPoints
+
+       oceanStressU(iPoint) = uOceanVelocity(iPoint) * cosOceanTurningAngle - vOceanVelocity(iPoint) * sinOceanTurningAngle
+       oceanStressV(iPoint) = uOceanVelocity(iPoint) * sinOceanTurningAngle + vOceanVelocity(iPoint) * cosOceanTurningAngle
+
+    enddo ! iPoint
+
+  end subroutine ocean_stress
+
+  !-------------------------------------------------------------
+
+  subroutine ocean_stress_coefficient(oceanStressCoeff, &amp;
+                                      uOceanVelocity, vOceanVelocity, &amp;
+                                      uVelocity, vVelocity, &amp;
+                                      iceArea) 
+
+    real(kind=RKIND), dimension(:), intent(out) :: &amp;
+         oceanStressCoeff
+
+    real(kind=RKIND), dimension(:), intent(in) :: &amp;
+         uOceanVelocity, &amp;
+         vOceanVelocity, &amp;
+         uVelocity, &amp;
+         vVelocity, &amp;
+         iceArea
+
+    real(kind=RKIND), parameter :: &amp;
+         densityWater      = 1026.0_RKIND, &amp;
+         iceOceanDragCoeff = 0.00536_RKIND
+
+    integer :: &amp;
+         nPoints, &amp;
+         iPoint
+
+    nPoints = size(oceanStressCoeff,1)
+
+    do iPoint = 1, nPoints
+
+       oceanStressCoeff(iPoint) = iceOceanDragCoeff * densityWater * iceArea(iPoint) * &amp;
+                                  sqrt((uOceanVelocity(iPoint) - uVelocity(iPoint))**2 + &amp;
+                                       (vOceanVelocity(iPoint) - vVelocity(iPoint))**2)
+
+    enddo ! iPoint
+
+  end subroutine ocean_stress_coefficient
+  
+  !-------------------------------------------------------------
+
+  subroutine surface_tilt(surfaceTiltForceU, surfaceTiltForceV)
+
+    real(kind=RKIND), dimension(:), intent(out) :: &amp;
+         surfaceTiltForceU, &amp;
+         surfaceTiltForceV
+
+    integer :: &amp;
+         nPoints, &amp;
+         iPoint
+
+    nPoints = size(surfaceTiltForceU,1)
+
+    do iPoint = 1, nPoints
+
+       surfaceTiltForceU(iPoint) = 0.0_RKIND
+       surfaceTiltForceV(iPoint) = 0.0_RKIND
+
+    enddo ! iPoint
+
+  end subroutine surface_tilt
+
+  !-------------------------------------------------------------
+
+  subroutine principal_stresses(mesh, principalStress1, principalStress2, stress11, stress22, stress12, icePressure)
+
+    type(mesh_type), intent(in) :: mesh
+
+    real(kind=RKIND), dimension(:), intent(out) :: &amp;
+         principalStress1, &amp;
+         principalStress2
+
+    real(kind=RKIND), dimension(:), intent(in) :: &amp;
+         stress11, &amp;
+         stress22, &amp;
+         stress12, &amp;
+         icePressure
+
+    real(kind=RKIND) :: &amp;
+         sqrtContents
+
+    integer :: &amp;
+         iCell
+
+    open(55,file='principal_stresses.txt')
+
+    do iCell = 1, mesh % nCells
+
+       sqrtContents = (stress11(iCell) + stress22(iCell))**2 - &amp;
+                      4.0_RKIND * stress11(iCell) * stress22(iCell) + &amp;
+                      4.0_RKIND * stress12(iCell)**2
+
+       principalStress1(iCell) = 0.5_RKIND * (stress11(iCell) + stress22(iCell)) + 0.5_RKIND * sqrt(sqrtContents)
+       principalStress2(iCell) = 0.5_RKIND * (stress11(iCell) + stress22(iCell)) - 0.5_RKIND * sqrt(sqrtContents)
+
+       write(55,*) principalStress1(iCell) / icePressure(iCell), principalStress2(iCell) / icePressure(iCell)
+
+    enddo ! iCell
+
+    close(55)
+
+  end subroutine principal_stresses
+
+  !-------------------------------------------------------------
+  ! Testing
+  !-------------------------------------------------------------
+
+  subroutine linear_constitutive_relation(stress1,          stress2,       stress12,       &amp;
+                                          strainDivergence, strainTension, strainShearing)
+
+    use cice_testing, only: lambda
+
+    real(kind=RKIND), intent(out) :: &amp;
+         stress1, &amp;
+         stress2, &amp;
+         stress12
+
+    real(kind=RKIND), intent(in) :: &amp;
+         strainDivergence, &amp;
+         strainTension,    &amp;
+         strainShearing
+
+    stress1  = lambda * strainDivergence
+    stress2  = lambda * strainTension
+    stress12 = lambda * strainShearing * 0.5_RKIND
+
+  end subroutine linear_constitutive_relation
+
+  !-------------------------------------------------------------
+
+  subroutine test_stress_divergence(mesh, icestate, weak, boundary)
+
+    use cice_testing, only: divergence_stress_test_stress_set_weak, divergence_stress_test_velocity_set
+
+    type(mesh_type), intent(in) :: mesh
+
+    type(icestate_type), pointer :: icestate
+    type(weak_type),     pointer :: weak
+    type(boundary_type), pointer :: boundary
+
+    real(kind=RKIND) :: &amp;
+         dtDynamics, dtElastic
+
+    call divergence_stress_test_velocity_set(&amp;
+         weak % uVelocity % array, &amp;
+         weak % vVelocity % array, &amp;
+         mesh % xVertex % array,   &amp;
+         mesh % yVertex % array,   &amp;
+         &quot;div1&quot;)
+
+    write(*,*) &quot;strain test&quot;
+    call strain_tensor(mesh, &amp;
+         weak % strain11 % array,  &amp;
+         weak % strain22 % array,  &amp;
+         weak % strain12 % array,  &amp;
+         weak % uVelocity % array, &amp;
+         weak % vVelocity % array, &amp;
+         weak % normalVectorPolygon % array)
+
+    call stress_tensor(mesh, &amp;
+         weak % stress11 % array, &amp;
+         weak % stress22 % array, &amp;
+         weak % stress12 % array, &amp;
+         weak % strain11 % array, &amp;
+         weak % strain22 % array, &amp;
+         weak % strain12 % array, &amp;
+         weak % icePressure % array, &amp;
+         dtDynamics, dtElastic)
+
+    write(*,*) &quot;divergence test&quot;
+    !call divergence_stress_test_stress_set_weak(mesh, &amp;
+    !     weak % stress11 % array, &amp;
+    !     weak % stress22 % array, &amp;
+    !     weak % stress12 % array)
+
+    call stress_divergence(mesh, &amp;
+         weak % stressDivergenceU % array,    &amp;
+         weak % stressDivergenceV % array,    &amp;
+         weak % stress11 % array,             &amp;
+         weak % stress22 % array,             &amp;
+         weak % stress12 % array,             &amp;
+         weak % normalVectorTriangle % array, &amp;
+         boundary % interiorVertex % array)
+
+  end subroutine test_stress_divergence
+
+  !-------------------------------------------------------------
+  ! Legacy
+  !-------------------------------------------------------------
+
+  subroutine boundary_cells(mesh, boundaryCell, boundaryCell2) 
+
+    type(mesh_type), intent(in) :: mesh
+
+    integer, dimension(:), intent(out) :: &amp;
+         boundaryCell, &amp;
+         boundaryCell2
+         
+    integer :: &amp;
+         iCell, &amp;
+         iCellOnCell, &amp;
+         iAdjacentCell
+
+    do iCell = 1, mesh % nCells
+
+       boundaryCell(iCell) = 0
+
+       do iCellOnCell = 1, mesh % nEdgesOnCell % array(iCell)
+
+          iAdjacentCell = mesh % cellsOnCell % array(iCellOnCell,iCell)
+
+          if (iAdjacentCell &gt; mesh % nCells) then
+
+             boundaryCell(iCell) = 1
+             exit
+
+          endif
+
+       enddo ! iCellOnCell
+
+    enddo ! iCell
+
+    do iCell = 1, mesh % nCells
+
+       boundaryCell2(iCell) = 0
+
+       if (boundaryCell(iCell) == 0) then
+
+          do iCellOnCell = 1, mesh % nEdgesOnCell % array(iCell)
+
+             iAdjacentCell = mesh % cellsOnCell % array(iCellOnCell,iCell)
+
+             if (boundaryCell(iAdjacentCell) == 1) then
+
+                boundaryCell2(iCell) = 1
+
+             endif
+
+          enddo ! iCellOnCell
+
+       endif
+
+    enddo ! iCell
+
+  end subroutine boundary_cells
+
+  !-------------------------------------------------------------
+
+  subroutine boundary_vertices(mesh, boundaryVertex, interiorVertex, interiorVertex2, boundaryCell)
+
+    type(mesh_type), intent(in) :: mesh
+
+    integer, dimension(:), intent(out) :: &amp;
+         boundaryVertex, &amp; ! boundary vertices of boundary vertex triangles
+         interiorVertex, &amp; ! all normal shaped interior vertices
+         interiorVertex2
+
+    integer, dimension(:), intent(in) :: &amp;
+         boundaryCell
+
+    integer :: &amp;
+         nInteriorAdjacentCells
+
+    integer :: &amp;
+         iVertex, &amp;
+         iVertexDegree, &amp;
+         iCell
+
+    logical :: &amp;
+         linterior
+
+    ! boundary vertices
+    do iVertex = 1, mesh % nVertices
+
+       boundaryVertex(iVertex) = 0
+       interiorVertex(iVertex) = 0
+       
+       nInteriorAdjacentCells = 0
+
+       do iVertexDegree = 1, mesh % vertexDegree
+
+          iCell = mesh % cellsOnVertex % array(iVertexDegree, iVertex)
+          
+          if (iCell &gt;= 1 .and. iCell &lt;= mesh % nCells) then
+             
+             nInteriorAdjacentCells = nInteriorAdjacentCells + 1
+             
+          endif
+          
+       enddo ! iVertexDegree
+
+       ! boundary vertices that have triangles
+       if (nInteriorAdjacentCells == 2) then
+
+          boundaryVertex(iVertex) = 1
+          
+       endif
+
+       ! vertex points we directly calculate on
+       if (nInteriorAdjacentCells == 3) then
+
+          interiorVertex(iVertex) = 1
+          
+       endif
+       
+    enddo ! iVertex
+
+
+    ! second interior vertices
+    do iVertex = 1, mesh % nVertices
+
+       interiorVertex2(iVertex) = 0
+
+       linterior = .true.
+
+       do iVertexDegree = 1, mesh % vertexDegree
+
+          iCell = mesh % cellsOnVertex % array(iVertexDegree, iVertex)
+          
+          if (boundaryCell(iCell) == 1) then
+             
+             linterior = .false.
+             
+          endif
+          
+       enddo ! iVertexDegree
+
+       if (linterior) interiorVertex2(iVertex) = 1
+
+    enddo ! iVertex
+
+  end subroutine boundary_vertices
+
+  !-------------------------------------------------------------
+
+  subroutine boundary_edges(mesh, boundaryEdge)
+
+    type(mesh_type), intent(in) :: mesh
+
+    integer, dimension(:), intent(out) :: &amp;
+         boundaryEdge
+
+    integer :: &amp;
+         nInteriorAdjacentCells
+
+    integer :: &amp;
+         iCell, &amp;
+         iEdge, &amp;
+         iCellsOnEdge
+    
+    ! boundary edges
+    do iEdge = 1, mesh % nEdges
+       
+       do iCellsOnEdge = 1, 2
+          
+          iCell = mesh % cellsOnEdge % array(iCellsOnEdge,iEdge)
+          
+          if (iCell &gt; mesh % nCells) then
+             boundaryEdge(iEdge) = 1
+          else
+             boundaryEdge(iEdge) = 0
+          endif
+          
+       enddo ! iCellsOnEdge
+
+    enddo ! iEdge
+    
+  end subroutine boundary_edges
+
+  !-------------------------------------------------------------
+  ! LU decomposition
+  !-------------------------------------------------------------
+
+  subroutine solve_linear_basis_system(leftMatrix, rightHandSide, solutionVector)
+
+    real(kind=RKIND), dimension(3,3), intent(in) :: &amp;
+         leftMatrix
+    real(kind=RKIND), dimension(3), intent(in) :: &amp;
+         rightHandSide
+    real(kind=RKIND), dimension(3), intent(out) :: &amp;
+         solutionVector
+
+    real(kind=RKIND), dimension(3,3) :: a
+    real(kind=RKIND), dimension(3) :: b
+    integer, dimension(3) :: indx
+    real(kind=RKIND) :: d
+
+    a(:,:) = leftMatrix(:,:)
+    b(:) = rightHandSide(:)
+
+    call ludcmp(a,indx,d)
+
+    call lubksb(a,indx,b)
+
+    solutionVector(:) = b(:)
+
+  end subroutine solve_linear_basis_system
+
+  !-------------------------------------------------------------
+
+  SUBROUTINE ludcmp(a,indx,d)
+
+    IMPLICIT NONE
+    REAL(kind=RKIND), DIMENSION(:,:), INTENT(INOUT) :: a
+    INTEGER, DIMENSION(:), INTENT(OUT) :: indx
+    REAL(kind=RKIND), INTENT(OUT) :: d
+    REAL(kind=RKIND), DIMENSION(size(a,1)) :: vv
+    REAL(kind=RKIND), PARAMETER :: TINY=1.0e-20_RKIND
+    INTEGER :: j,n,imax
+    n=assert_eq(size(a,1),size(a,2),size(indx),'ludcmp')
+    d=1.0
+    vv=maxval(abs(a),dim=2)
+    if (any(vv == 0.0)) call nrerror('singular matrix in ludcmp')
+    vv=1.0_RKIND/vv
+    do j=1,n
+       imax=(j-1)+imaxloc(vv(j:n)*abs(a(j:n,j)))
+       if (j /= imax) then
+          call swap(a(imax,:),a(j,:))
+          d=-d
+          vv(imax)=vv(j)
+       end if
+       indx(j)=imax
+       if (a(j,j) == 0.0) a(j,j)=TINY
+       a(j+1:n,j)=a(j+1:n,j)/a(j,j)
+       a(j+1:n,j+1:n)=a(j+1:n,j+1:n)-outerprod(a(j+1:n,j),a(j,j+1:n))
+    end do
+  END SUBROUTINE ludcmp
+
+  !-------------------------------------------------------------
+
+  SUBROUTINE lubksb(a,indx,b)
+
+    IMPLICIT NONE
+    REAL(kind=RKIND), DIMENSION(:,:), INTENT(IN) :: a
+    INTEGER, DIMENSION(:), INTENT(IN) :: indx
+    REAL(kind=RKIND), DIMENSION(:), INTENT(INOUT) :: b
+    INTEGER :: i,n,ii,ll
+    REAL(kind=RKIND) :: summ
+    n=assert_eq(size(a,1),size(a,2),size(indx),'lubksb')
+    ii=0
+    do i=1,n
+       ll=indx(i)
+       summ=b(ll)
+       b(ll)=b(i)
+       if (ii /= 0) then
+          summ=summ-dot_product(a(i,ii:i-1),b(ii:i-1))
+       else if (summ /= 0.0) then
+          ii=i
+       end if
+       b(i)=summ
+    end do
+    do i=n,1,-1
+       b(i) = (b(i)-dot_product(a(i,i+1:n),b(i+1:n)))/a(i,i)
+    end do
+  END SUBROUTINE lubksb
+
+  !-------------------------------------------------------------
+
+  FUNCTION assert_eq(n1,n2,n3,string)
+    CHARACTER(LEN=*), INTENT(IN) :: string
+    INTEGER, INTENT(IN) :: n1,n2,n3
+    INTEGER :: assert_eq
+    if (n1 == n2 .and. n2 == n3) then
+       assert_eq=n1
+    else
+       write (*,*) 'nrerror: an assert_eq failed with this tag:', &amp;
+            string
+       STOP 'program terminated by assert_eq3'
+    end if
+  END FUNCTION assert_eq
+
+  !-------------------------------------------------------------
+
+  FUNCTION imaxloc(arr)
+    REAL(kind=RKIND), DIMENSION(:), INTENT(IN) :: arr
+    INTEGER :: imaxloc
+    INTEGER, DIMENSION(1) :: imax
+    imax=maxloc(arr(:))
+    imaxloc=imax(1)
+  END FUNCTION imaxloc
+
+  !-------------------------------------------------------------
+
+  SUBROUTINE nrerror(string)
+    CHARACTER(LEN=*), INTENT(IN) :: string
+    write (*,*) 'nrerror: ',string
+    STOP 'program terminated by nrerror'
+  END SUBROUTINE nrerror
+
+  !-------------------------------------------------------------
+
+  FUNCTION outerprod(a,b)
+    REAL(kind=RKIND), DIMENSION(:), INTENT(IN) :: a,b
+    REAL(kind=RKIND), DIMENSION(size(a),size(b)) :: outerprod
+    outerprod = spread(a,dim=2,ncopies=size(b)) * &amp;
+         spread(b,dim=1,ncopies=size(a))
+  END FUNCTION outerprod
+
+  !-------------------------------------------------------------
+
+  SUBROUTINE swap(a,b)
+    REAL(kind=RKIND), DIMENSION(:), INTENT(INOUT) :: a,b
+    REAL(kind=RKIND), DIMENSION(SIZE(a)) :: dum
+    dum=a
+    a=b
+    b=dum
+  END SUBROUTINE swap
+
+  !-------------------------------------------------------------
+
+end module cice_dynamics_shared

Deleted: branches/cice_projects/initial_cice_core/src/core_cice/mpas_cice_init.F
===================================================================
--- branches/cice_projects/initial_cice_core/src/core_cice/mpas_cice_init.F        2013-04-19 17:49:14 UTC (rev 2779)
+++ branches/cice_projects/initial_cice_core/src/core_cice/mpas_cice_init.F        2013-04-19 18:44:55 UTC (rev 2780)
@@ -1,20 +0,0 @@
-module cice_init
-
-  implicit none
-
-
-contains
-
-  !-------------------------------------------------------------------------
-  
-  subroutine init_data()
-
-    use cice_state
-
-    call init_cice_state()
-
-  end subroutine init_data
-
-  !-------------------------------------------------------------------------
-
-end module cice_init

Deleted: branches/cice_projects/initial_cice_core/src/core_cice/mpas_cice_kinds_mod.F
===================================================================
--- branches/cice_projects/initial_cice_core/src/core_cice/mpas_cice_kinds_mod.F        2013-04-19 17:49:14 UTC (rev 2779)
+++ branches/cice_projects/initial_cice_core/src/core_cice/mpas_cice_kinds_mod.F        2013-04-19 18:44:55 UTC (rev 2780)
@@ -1,42 +0,0 @@
-!=======================================================================
-!BOP
-!
-! !MODULE: ice_kinds_mod - defines variable precision
-!
-! !DESCRIPTION:
-!
-! Defines variable precision for all common data types \\
-! Code originally based on kinds_mod.F in POP
-!
-! !REVISION HISTORY:
-!  SVN:$Id: ice_kinds_mod.F90 140 2008-07-25 20:15:53Z eclare $
-!
-! author: Elizabeth C. Hunke and William H. Lipscomb, LANL
-! 2006: ECH converted to free source form (F90)
-!
-! !INTERFACE:
-!
-      module cice_kinds_mod
-!
-! !USES:
-!
-!EOP
-!=======================================================================
-
-      use mpas_kind_types
-
-      implicit none
-
-      integer, parameter :: char_len  = 80, &amp;
-                            char_len_long  = 256, &amp;
-                            log_kind  = kind(.true.), &amp;
-                            int_kind  = kind(1), &amp;
-                            real_kind = RKIND, &amp;
-                            dbl_kind  = RKIND, &amp;
-                            r16_kind  = selected_real_kind(26)
-
-!=======================================================================
-
-      end module cice_kinds_mod
-
-!=======================================================================

Modified: branches/cice_projects/initial_cice_core/src/core_cice/mpas_cice_mpas_core.F
===================================================================
--- branches/cice_projects/initial_cice_core/src/core_cice/mpas_cice_mpas_core.F        2013-04-19 17:49:14 UTC (rev 2779)
+++ branches/cice_projects/initial_cice_core/src/core_cice/mpas_cice_mpas_core.F        2013-04-19 18:44:55 UTC (rev 2780)
@@ -14,14 +14,13 @@
 
    contains
 
-   !-------------------------------------------------------------------------
+!--------------------------------------------------------------------------
 
    subroutine mpas_core_init(domain, startTimeStamp)
    
       use mpas_configure
       use mpas_grid_types
-      use cice_init
-
+   
       implicit none
    
       type (domain_type), intent(inout) :: domain
@@ -46,12 +45,9 @@
 
       current_outfile_frames = 0
 
-      ! CICE init
-      call init_data()
-
    end subroutine mpas_core_init
 
-   !-------------------------------------------------------------------------
+!--------------------------------------------------------------------------
 
    subroutine simulation_clock_init(domain, dt, startTimeStamp)
 
@@ -102,35 +98,39 @@
 
    end subroutine simulation_clock_init
 
-   !-------------------------------------------------------------------------
+!--------------------------------------------------------------------------
 
    subroutine mpas_init_block(block, mesh, dt)
    
       use mpas_grid_types
       use mpas_rbf_interpolation
       use mpas_vector_reconstruction
-   
+
+      use cice_dynamics_shared, only: init_weak_dynamics, &amp;
+                                      test_stress_divergence
+
+      use cice_testing, only: init_square_test_case_weak
+
       implicit none
-   
+
       type (block_type), intent(inout) :: block
       type (mesh_type), intent(inout) :: mesh
       real (kind=RKIND), intent(in) :: dt
-   
-      call compute_mesh_scaling(mesh) 
 
+      integer :: iCell
+
       call mpas_rbf_interp_initialize(mesh)
       call mpas_init_reconstruct(mesh)
-      !call mpas_reconstruct(mesh, block % state % time_levs(1) % state % u % array,                  &amp;
-      !                 block % state % time_levs(1) % state % uReconstructX % array,            &amp;
-      !                 block % state % time_levs(1) % state % uReconstructY % array,            &amp;
-      !                 block % state % time_levs(1) % state % uReconstructZ % array,            &amp;
-      !                 block % state % time_levs(1) % state % uReconstructZonal % array,        &amp;
-      !                 block % state % time_levs(1) % state % uReconstructMeridional % array    &amp;
-      !                )
 
+      ! dynamics
+      call init_weak_dynamics(mesh, block % weak, block % boundary, dt)
+      
+      ! test case
+      call init_square_test_case_weak(mesh, block % icestate, block % weak)
+
    end subroutine mpas_init_block
    
-   !-------------------------------------------------------------------------
+!--------------------------------------------------------------------------
    
    subroutine mpas_core_run(domain, output_obj, output_frame)
    
@@ -138,7 +138,6 @@
       use mpas_kind_types
       use mpas_io_output
       use mpas_timer
-      use cice_timestep
    
       implicit none
    
@@ -211,8 +210,8 @@
 
    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
@@ -254,7 +253,7 @@
 
    end subroutine write_output_frame
    
-   !-------------------------------------------------------------------------
+!--------------------------------------------------------------------------
    
    subroutine compute_output_diagnostics(state, grid)
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -277,9 +276,36 @@
       integer :: iEdge, k
    
    end subroutine compute_output_diagnostics
+   
+!--------------------------------------------------------------------------
+   
+   subroutine mpas_timestep(domain, itimestep, dt, timeStamp)
+   
+      use mpas_grid_types
+      use cice_time_integration
+      use mpas_timer
+   
+      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
+
+      write(*,*) trim(timeStamp)
+
+      block =&gt; domain % blocklist
+      do while (associated(block))
+         call cice_timestep(block, dt)
+         block =&gt; block % next
+      end do
+
+   end subroutine mpas_timestep
    
+!--------------------------------------------------------------------------   
+
    subroutine mpas_core_finalize(domain)
    
       use mpas_grid_types
@@ -293,39 +319,6 @@
 
    end subroutine mpas_core_finalize
 
-   !-------------------------------------------------------------------------
+!--------------------------------------------------------------------------
 
-   subroutine compute_mesh_scaling(mesh)
-
-      use mpas_grid_types
-
-      implicit none
-
-      type (mesh_type), intent(inout) :: mesh
-
-      integer :: iEdge, cell1, cell2
-      real (kind=RKIND), dimension(:), pointer :: meshDensity, meshScalingDel2, meshScalingDel4
-
-      meshDensity =&gt; mesh % meshDensity % array
-      meshScalingDel2 =&gt; mesh % meshScalingDel2 % array
-      meshScalingDel4 =&gt; mesh % meshScalingDel4 % array
-
-      !
-      ! Compute the scaling factors to be used in the del2 and del4 dissipation
-      !
-      !meshScalingDel2(:) = 1.0
-      !meshScalingDel4(:) = 1.0
-      !if (config_h_ScaleWithMesh) then
-      !   do iEdge=1,mesh%nEdges
-      !      cell1 = mesh % cellsOnEdge % array(1,iEdge)
-      !      cell2 = mesh % cellsOnEdge % array(2,iEdge)
-      !      meshScalingDel2(iEdge) = 1.0 / ( (meshDensity(cell1) + meshDensity(cell2) )/2.0)**(5.0/12.0)
-      !      meshScalingDel4(iEdge) = 1.0 / ( (meshDensity(cell1) + meshDensity(cell2) )/2.0)**(5.0/6.0)
-      !   end do
-      !end if
-
-   end subroutine compute_mesh_scaling
-
-   !-------------------------------------------------------------------------
-
 end module mpas_core

Deleted: branches/cice_projects/initial_cice_core/src/core_cice/mpas_cice_state.F
===================================================================
--- branches/cice_projects/initial_cice_core/src/core_cice/mpas_cice_state.F        2013-04-19 17:49:14 UTC (rev 2779)
+++ branches/cice_projects/initial_cice_core/src/core_cice/mpas_cice_state.F        2013-04-19 18:44:55 UTC (rev 2780)
@@ -1,263 +0,0 @@
-!=======================================================================
-!BOP
-!
-! !MODULE: ice_state - primary state variables
-!
-! !DESCRIPTION:
-!
-! Primary state variables in various configurations
-! Note: other state variables are at the end of this...
-! The primary state variable names are:
-!-------------------------------------------------------------------
-! for each category   aggregated over     units
-!                       categories
-!-------------------------------------------------------------------
-! aicen(i,j,n)         aice(i,j)           ---
-! vicen(i,j,n)         vice(i,j)           m
-! vsnon(i,j,n)         vsno(i,j)           m
-! trcrn(i,j,it,n)      trcr(i,j,it)        
-!
-! Area is dimensionless because aice is the fractional area
-! (normalized so that the sum over all categories, including open
-! water, is 1.0).  That is why vice/vsno have units of m instead of m^3.
-!
-! Variable names follow these rules:
-!
-! (1) For 3D variables (indices i,j,n), write 'ice' or 'sno' or
-!     'sfc' and put an 'n' at the end.
-! (2) For 2D variables (indices i,j) aggregated over all categories,
-!     write 'ice' or 'sno' or 'sfc' without the 'n'.
-! (3) For 2D variables (indices i,j) associated with an individual
-!     category, write 'i' or 's' instead of 'ice' or 'sno' and put an 'n'
-!     at the end: e.g. hin, hsn.  These are not declared here
-!     but in individual modules (e.g., ice_therm_vertical).
-!
-! !REVISION HISTORY:
-!  SVN:$Id: ice_state.F90 567 2013-01-07 02:57:36Z eclare $
-!
-! authors C. M. Bitz, UW
-!         Elizabeth C. Hunke and William H. Lipscomb, LANL
-!
-! 2004: Block structure added by William Lipscomb
-! 2006: Converted to free form source (F90) by Elizabeth Hunke
-!
-! !INTERFACE:
-!
-      module cice_state
-!
-! !USES:
-!
-      use cice_kinds_mod
-      use cice_domain_size
-      !use ice_blocks
-!
-!EOP
-!
-      implicit none
-      save
-
-      !-----------------------------------------------------------------
-      ! state of the ice aggregated over all categories
-      !-----------------------------------------------------------------
-
-      !real (kind=dbl_kind), dimension(nx_block,ny_block,max_blocks) :: &amp;
-      !   aice  , &amp; ! concentration of ice
-      !   vice  , &amp; ! volume per unit area of ice          (m)
-      !   vsno      ! volume per unit area of snow         (m)
-
-      !real (kind=dbl_kind), &amp;
-      !   dimension(nx_block,ny_block,max_ntrcr,max_blocks) :: &amp;
-      !   trcr      ! ice tracers
-                   ! 1: surface temperature of ice/snow (C)
-
-      !-----------------------------------------------------------------
-      ! state of the ice for each category
-      !-----------------------------------------------------------------
-
-      !real (kind=dbl_kind), dimension (nx_block,ny_block,max_blocks):: &amp;
-      !   aice0     ! concentration of open water
-
-      !real (kind=dbl_kind), &amp;
-      !   dimension (nx_block,ny_block,ncat,max_blocks) :: &amp;
-      !   aicen , &amp; ! concentration of ice
-      !   vicen , &amp; ! volume per unit area of ice          (m)
-      !   vsnon     ! volume per unit area of snow         (m)
-
-      !real (kind=dbl_kind), &amp;
-      !   dimension (nx_block,ny_block,max_ntrcr,ncat,max_blocks) :: &amp;
-      !   trcrn     ! tracers
-                   ! 1: surface temperature of ice/snow (C)
-
-      !integer (kind=int_kind), dimension (max_ntrcr) :: &amp;
-      !   trcr_depend   ! = 0 for ice area tracers
-                       ! = 1 for ice volume tracers
-                       ! = 2 for snow volume tracers
-
-      integer (kind=int_kind) :: &amp;
-         ntrcr     ! number of tracers in use
-
-      !-----------------------------------------------------------------
-      ! indices and flags for tracers
-      !-----------------------------------------------------------------
-
-      integer (kind=int_kind) ::                      &amp;
-         ntraceb     , &amp;    ! number of bio layer tracers in use                   &amp;
-         ntrace_start       ! index of first bio tracer
-      
-      integer (kind=int_kind) :: &amp;
-         nt_Tsfc  , &amp; ! ice/snow temperature
-         nt_qice  , &amp; ! volume-weighted ice enthalpy (in layers)
-         nt_qsno  , &amp; ! volume-weighted snow enthalpy (in layers)
-         nt_sice  , &amp; ! volume-weighted ice bulk salinity (CICE grid layers)
-         nt_fbri  , &amp; ! volume fraction of ice with dynamic salt (hinS/vicen*aicen)
-         nt_iage  , &amp; ! volume-weighted ice age
-         nt_FY    , &amp; ! area-weighted first-year ice area
-         nt_alvl  , &amp; ! level ice area fraction
-         nt_vlvl  , &amp; ! level ice volume fraction
-         nt_apnd  , &amp; ! melt pond area fraction
-         nt_hpnd  , &amp; ! melt pond depth
-         nt_ipnd  , &amp; ! melt pond refrozen lid thickness
-         nt_aero  , &amp; ! starting index for aerosols in ice
-         nt_bgc_N_sk,   &amp; ! algae (skeletal layer)
-         nt_bgc_C_sk,   &amp; ! 
-         nt_bgc_chl_sk, &amp; ! 
-         nt_bgc_Nit_sk, &amp; ! nutrients (skeletal layer) 
-         nt_bgc_Am_sk,  &amp; ! 
-         nt_bgc_Sil_sk, &amp; !
-         nt_bgc_DMSPp_sk, &amp; ! trace gases (skeletal layer)
-         nt_bgc_DMSPd_sk, &amp; ! 
-         nt_bgc_DMS_sk, &amp; ! 
-         nt_bgc_Nit_ml, &amp; ! nutrients (ocean mixed layer) 
-         nt_bgc_Am_ml,  &amp; ! 
-         nt_bgc_Sil_ml, &amp; !
-         nt_bgc_DMSP_ml, &amp; ! trace gases (ocean mixed layer)
-         nt_bgc_DMS_ml, &amp; !  
-         nt_bgc_N,   &amp; ! algae: bulk quantities are tracers (volume preserved)
-         nt_bgc_C,   &amp; ! 
-         nt_bgc_chl, &amp; ! 
-         nt_bgc_NO,  &amp; ! nutrients  
-         nt_bgc_NH,  &amp; ! 
-         nt_bgc_Sil, &amp; !
-         nt_bgc_DMSPp, &amp; ! trace gases (skeletal layer)
-         nt_bgc_DMSPd, &amp; ! 
-         nt_bgc_DMS, &amp; ! 
-         nt_bgc_PON, &amp; ! zooplankton and detritus  
-         nt_bgc_S      ! Bulk salinity in fraction ice with dynamic salinity (Bio grid) 
-
-      logical (kind=log_kind) :: &amp;
-         tr_iage,   &amp; ! if .true., use age tracer
-         tr_FY,     &amp; ! if .true., use first-year area tracer
-         tr_lvl,    &amp; ! if .true., use level ice tracer
-         tr_pond,   &amp; ! if .true., use melt pond tracer
-         tr_pond_cesm,&amp; ! if .true., use cesm pond tracer
-         tr_pond_lvl, &amp; ! if .true., use level-ice pond tracer
-         tr_pond_topo,&amp; ! if .true., use explicit topography-based ponds
-         tr_aero      ! if .true., use aerosol tracers
-
-      !-----------------------------------------------------------------
-      ! dynamic variables closely related to the state of the ice
-      !-----------------------------------------------------------------
-
-      !real (kind=dbl_kind), dimension(nx_block,ny_block,max_blocks) :: &amp;
-      !   uvel     , &amp; ! x-component of velocity (m/s)
-      !   vvel     , &amp; ! y-component of velocity (m/s)
-      !   divu     , &amp; ! strain rate I component, velocity divergence (1/s)
-      !   shear    , &amp; ! strain rate II component (1/s)
-      !   strength     ! ice strength (N/m)
-
-      !-----------------------------------------------------------------
-      ! ice state at start of time step, saved for later in the step 
-      !-----------------------------------------------------------------
-
-      !real (kind=dbl_kind), dimension(nx_block,ny_block,max_blocks) :: &amp;
-      !   aice_init       ! initial concentration of ice, for diagnostics
-
-      !real (kind=dbl_kind), &amp;
-      !   dimension(nx_block,ny_block,ncat,max_blocks) :: &amp;
-      !   aicen_init  , &amp; ! initial ice concentration, for linear ITD
-      !   vicen_init      ! initial ice volume (m), for linear ITD
-
-      ! logical (kind=log_kind) :: &amp;
-      !   hbrine          ! if .true., brine height differs from ice thickness
-
-!=======================================================================
-
-      contains
-
-!=======================================================================
-
-        subroutine init_cice_state()
-
-         tr_iage = .false.
-         tr_FY = .false.
-         tr_lvl = .false.
-         tr_pond = .false.
-         tr_pond_cesm = .false.
-         tr_pond_lvl = .false.
-         tr_pond_topo = .false.
-         tr_aero = .false.
-
-         nt_Tsfc = 1           ! index tracers, starting with Tsfc = 1
-         ntrcr = 1             ! count tracers, starting with Tsfc = 1
-
-         nt_qice = ntrcr + 1
-         ntrcr = ntrcr + nilyr ! qice in nilyr layers
-
-         nt_qsno = ntrcr + 1
-         ntrcr = ntrcr + nslyr ! qsno in nslyr layers
-
-         nt_sice = ntrcr + 1
-         ntrcr = ntrcr + nilyr ! sice in nilyr layers
-
-         nt_iage = 0
-         if (tr_iage) then
-             nt_iage = ntrcr + 1   ! chronological ice age
-             ntrcr = ntrcr + 1
-         endif
-
-         nt_FY = 0
-         if (tr_FY) then
-             nt_FY = ntrcr + 1     ! area of first year ice
-             ntrcr = ntrcr + 1
-         endif
-
-         nt_alvl = 0
-         nt_vlvl = 0
-         if (tr_lvl) then
-             nt_alvl = ntrcr + 1
-             ntrcr = ntrcr + 1
-             nt_vlvl = ntrcr + 1
-             ntrcr = ntrcr + 1
-         endif
-
-         nt_apnd = 0
-         nt_hpnd = 0
-         nt_ipnd = 0
-         if (tr_pond) then            ! all explicit melt pond schemes
-             nt_apnd = ntrcr + 1
-             ntrcr = ntrcr + 1
-             nt_hpnd = ntrcr + 1
-             ntrcr = ntrcr + 1
-             if (tr_pond_lvl) then
-                 nt_ipnd = ntrcr + 1  ! refrozen pond ice lid thickness
-                 ntrcr = ntrcr + 1    ! on level-ice ponds (if frzpnd='hlid')
-             endif
-             if (tr_pond_topo) then
-                 nt_ipnd = ntrcr + 1  ! refrozen pond ice lid thickness
-                 ntrcr = ntrcr + 1    ! 
-             endif
-         endif
-
-         nt_aero = 0
-         if (tr_aero) then
-             nt_aero = ntrcr + 1
-             ntrcr = ntrcr + 4*n_aero ! 4 dEdd layers, n_aero species
-         endif
-
-        end subroutine init_cice_state
-
-!=======================================================================
-
-      end module cice_state
-
-!=======================================================================

Deleted: branches/cice_projects/initial_cice_core/src/core_cice/mpas_cice_test.F
===================================================================
--- branches/cice_projects/initial_cice_core/src/core_cice/mpas_cice_test.F        2013-04-19 17:49:14 UTC (rev 2779)
+++ branches/cice_projects/initial_cice_core/src/core_cice/mpas_cice_test.F        2013-04-19 18:44:55 UTC (rev 2780)
@@ -1,262 +0,0 @@
-module cice_test
-
-  use cice_kinds_mod
-  use cice_domain_size
-  use cice_constants
-
-contains
-
-!=======================================================================
-!BOP
-!
-! !ROUTINE: frzmlt_bottom_lateral - bottom and lateral heat fluxes
-!
-! !DESCRIPTION:
-!
-! Adjust frzmlt to account for changes in fhocn since from_coupler.
-! Compute heat flux to bottom surface.
-! Compute fraction of ice that melts laterally.
-!
-! !REVISION HISTORY:
-!
-! authors C. M. Bitz, UW
-!         William H. Lipscomb, LANL
-!         Elizabeth C. Hunke, LANL
-!
-! !INTERFACE:
-!
-      subroutine frzmlt_bottom_lateral (nx_block, ny_block, &amp;
-                                        ilo, ihi, jlo, jhi, &amp;
-                                        ntrcr,    dt,       &amp;
-                                        aice,     frzmlt,   &amp;
-                                        vicen,    vsnon,    &amp;
-                                        trcrn,              &amp;
-                                        sst,      Tf,       &amp;
-                                        strocnxT, strocnyT, &amp;
-                                        Tbot,     fbot,     &amp;
-                                        rside)
-!
-! !USES:
-!
-! !INPUT/OUTPUT PARAMETERS:
-
-      integer (kind=int_kind), intent(in) :: &amp;
-         nx_block, ny_block, &amp; ! block dimensions
-         ilo,ihi,jlo,jhi   , &amp; ! beginning and end of physical domain
-         ntrcr                 ! number of tracers
-
-      real (kind=dbl_kind), intent(in) :: &amp;
-         dt                  ! time step
-
-      real (kind=dbl_kind), dimension(nx_block,ny_block), intent(in) :: &amp;
-         aice    , &amp; ! ice concentration
-         frzmlt  , &amp; ! freezing/melting potential (W/m^2)
-         sst     , &amp; ! sea surface temperature (C)
-         Tf      , &amp; ! freezing temperature (C)
-         strocnxT, &amp; ! ice-ocean stress, x-direction
-         strocnyT    ! ice-ocean stress, y-direction
-
-      real (kind=dbl_kind), dimension(nx_block,ny_block,ncat), &amp;
-         intent(in) :: &amp;
-         vicen   , &amp; ! ice volume (m)
-         vsnon       ! snow volume (m)
-
-      real (kind=dbl_kind), dimension(nx_block,ny_block,ntrcr,ncat), &amp;
-         intent(in) :: &amp;
-         trcrn       ! tracer array
-
-      real (kind=dbl_kind), dimension(nx_block,ny_block), &amp;
-         intent(out) :: &amp;
-         Tbot    , &amp; ! ice bottom surface temperature (deg C)
-         fbot    , &amp; ! heat flux to ice bottom  (W/m^2)
-         rside       ! fraction of ice that melts laterally
-!
-!EOP
-!
-      integer (kind=int_kind) :: &amp;
-         i, j           , &amp; ! horizontal indices
-         n              , &amp; ! thickness category index
-         k              , &amp; ! layer index
-         ij             , &amp; ! horizontal index, combines i and j loops
-         imelt              ! number of cells with ice melting
-
-      integer (kind=int_kind), dimension (nx_block*ny_block) :: &amp;
-         indxi, indxj     ! compressed indices for cells with ice melting
-
-      real (kind=dbl_kind), dimension (:), allocatable :: &amp;
-         etot    , &amp; ! total energy in column
-         fside       ! lateral heat flux (W/m^2)
-
-      real (kind=dbl_kind) :: &amp;
-         deltaT    , &amp; ! SST - Tbot &gt;= 0
-         ustar     , &amp; ! skin friction velocity for fbot (m/s)
-         wlat      , &amp; ! lateral melt rate (m/s)
-         xtmp          ! temporary variable
-
-      ! Parameters for bottom melting
-
-      ! 0.006 = unitless param for basal heat flx ala McPhee and Maykut
-
-      real (kind=dbl_kind), parameter :: &amp;
-         cpchr = -cp_ocn*rhow*0.006_dbl_kind
-
-
-      ! Parameters for lateral melting
-
-      real (kind=dbl_kind), parameter :: &amp;
-         floediam = 300.0_dbl_kind, &amp; ! effective floe diameter (m)
-         alpha    = 0.66_dbl_kind , &amp; ! constant from Steele (unitless)
-         m1 = 1.6e-6_dbl_kind     , &amp; ! constant from Maykut &amp; Perovich
-                                      ! (m/s/deg^(-m2))
-         m2 = 1.36_dbl_kind           ! constant from Maykut &amp; Perovich
-                                      ! (unitless)
-
-      do j = 1, ny_block
-      do i = 1, nx_block
-         rside(i,j) = c0
-         Tbot (i,j) = Tf(i,j)
-         fbot (i,j) = c0
-      enddo
-      enddo
-
-      !-----------------------------------------------------------------
-      ! Identify grid cells where ice can melt.
-      !-----------------------------------------------------------------
-
-      imelt = 0
-      do j = jlo, jhi
-      do i = ilo, ihi
-#if (defined notz_experiment || defined notz_fieldwork)
-         if (aice(i,j) &gt; puny) then
-#else
-         if (aice(i,j) &gt; puny .and. frzmlt(i,j) &lt; c0) then ! ice can melt
-#endif
-            imelt = imelt + 1
-            indxi(imelt) = i
-            indxj(imelt) = j
-         endif
-      enddo                     ! i
-      enddo                     ! j
-
-      allocate(etot (imelt))
-      allocate(fside(imelt))
-
-      do ij = 1, imelt  ! cells where ice can melt
-         i = indxi(ij)
-         j = indxj(ij)
-
-         fside(ij) = c0
-
-      !-----------------------------------------------------------------
-      ! Use boundary layer theory for fbot.
-      ! See Maykut and McPhee (1995): JGR, 100, 24,691-24,703.
-      !-----------------------------------------------------------------
-
-         deltaT = max((sst(i,j)-Tbot(i,j)),c0)
-
-         ! strocnx has units N/m^2 so strocnx/rho has units m^2/s^2
-         ustar = sqrt (sqrt(strocnxT(i,j)**2+strocnyT(i,j)**2)/rhow)
-         ustar = max (ustar,ustar_min)
-
-#if defined notz_experiment
-         fbot(i,j) = c0
-!#elif (defined pond_barrow || defined snowice_maksym)
-!         fbot(i,j) = c0
-#elif defined notz_fieldwork
-         fbot(i,j) = cpchr * deltaT * ustar ! &lt; 0
-#else
-         fbot(i,j) = cpchr * deltaT * ustar ! &lt; 0
-         fbot(i,j) = max (fbot(i,j), frzmlt(i,j)) ! frzmlt &lt; fbot &lt; 0
-#endif
-
-!!! uncomment to use all frzmlt for standalone runs
-   !     fbot(i,j) = min (c0, frzmlt(i,j))
-
-      !-----------------------------------------------------------------
-      ! Compute rside.  See these references:
-      !    Maykut and Perovich (1987): JGR, 92, 7032-7044
-      !    Steele (1992): JGR, 97, 17,729-17,738
-      !-----------------------------------------------------------------
-
-         wlat = m1 * deltaT**m2 ! Maykut &amp; Perovich
-         rside(i,j) = wlat*dt*pi/(alpha*floediam) ! Steele
-         rside(i,j) = max(c0,min(rside(i,j),c1))
-
-      enddo                     ! ij
-
-      !-----------------------------------------------------------------
-      ! Compute heat flux associated with this value of rside.
-      !-----------------------------------------------------------------
-
-      do n = 1, ncat
-
-         do ij = 1, imelt
-            etot(ij) = c0
-         enddo
-
-         ! melting energy/unit area in each column, etot &lt; 0
-
-         do k = 1, nslyr
-!DIR$ CONCURRENT !Cray
-!cdir nodep      !NEC
-!ocl novrec      !Fujitsu
-            do ij = 1, imelt
-               i = indxi(ij)
-               j = indxj(ij)
-               etot(ij) = etot(ij) + trcrn(i,j,nt_qsno+k-1,n) &amp;
-                                   * vsnon(i,j,n)/real(nslyr,kind=dbl_kind)
-            enddo               ! ij
-         enddo
-
-         do k = 1, nilyr
-!DIR$ CONCURRENT !Cray
-!cdir nodep      !NEC
-!ocl novrec      !Fujitsu
-            do ij = 1, imelt
-               i = indxi(ij)
-               j = indxj(ij)
-               etot(ij) = etot(ij) + trcrn(i,j,nt_qice+k-1,n) &amp;
-                                   * vicen(i,j,n)/real(nilyr,kind=dbl_kind)
-            enddo               ! ij
-         enddo                  ! nilyr
-
-!DIR$ CONCURRENT !Cray
-!cdir nodep      !NEC
-!ocl novrec      !Fujitsu
-         do ij = 1, imelt
-            i = indxi(ij)
-            j = indxj(ij)
-            ! lateral heat flux
-            fside(ij) = fside(ij) + rside(i,j)*etot(ij)/dt ! fside &lt; 0
-         enddo                  ! ij
-
-      enddo                     ! n
-
-      !-----------------------------------------------------------------
-      ! Limit bottom and lateral heat fluxes if necessary.
-      !-----------------------------------------------------------------
-
-!DIR$ CONCURRENT !Cray
-!cdir nodep      !NEC
-!ocl novrec      !Fujitsu
-      do ij = 1, imelt
-         i = indxi(ij)
-         j = indxj(ij)
-
-         xtmp = frzmlt(i,j)/(fbot(i,j) + fside(ij) + puny) 
-         xtmp = min(xtmp, c1)
-#if !(defined notz_experiment || defined notz_fieldwork || defined snowice_maksym || defined pond_barrow)
-         fbot(i,j)  = fbot(i,j)  * xtmp
-#endif
-         rside(i,j) = rside(i,j) * xtmp
-      enddo                     ! ij
-
-      deallocate(etot)
-      deallocate(fside)
-
-      end subroutine frzmlt_bottom_lateral
-
-!=======================================================================
-
-end module cice_test
-

Added: branches/cice_projects/initial_cice_core/src/core_cice/mpas_cice_testing.F
===================================================================
--- branches/cice_projects/initial_cice_core/src/core_cice/mpas_cice_testing.F                                (rev 0)
+++ branches/cice_projects/initial_cice_core/src/core_cice/mpas_cice_testing.F        2013-04-19 18:44:55 UTC (rev 2780)
@@ -0,0 +1,1876 @@
+module cice_testing
+
+  use mpas_grid_types
+
+  implicit none
+
+  private
+  public :: divergence_stress_test_velocity_set, &amp;
+            divergence_stress_test_stress_set_hex, &amp;
+            divergence_stress_test_stress_set_tri, &amp;
+            divergence_stress_test_stress_set_weak, &amp;
+            gnuplot_cell, &amp;
+            gnuplot_triangle, &amp;
+            matlab_jet, &amp;
+            plot_boundary_triangles, &amp;
+            boundary_locations, &amp;
+            labels_verticesOnCell, &amp;
+            labels_verticesDegreeOnVertex, &amp;
+            writeout_minmax, &amp;
+            writeout_on_cell_real, &amp;
+            writeout_on_vertex_real, &amp;
+            writeout_on_vertex_on_cell_real, &amp;
+            writeout_array, &amp;
+            writeout_edgecell, &amp;
+            writeout_edgeedgecell, &amp;
+            rotate_ninety, &amp;
+            reverse_grids, &amp;
+            init_square_test_case_weak, &amp;
+            gnuplot_vertexvector, &amp;
+            find_nearest_cell
+
+  integer :: &amp;
+       iObject = 1, &amp;
+       iLabel  = 1, &amp;
+       iArrow  = 1
+
+  real(kind=RKIND) :: &amp;
+       xmin =  1.0e30_RKIND, &amp;
+       xmax = -1.0e30_RKIND, &amp;
+       ymin =  1.0e30_RKIND, &amp;
+       ymax = -1.0e30_RKIND
+
+  ! parameter in constant stress strain relation
+  real(kind=RKIND), parameter, public :: lambda = 1.0e9_RKIND
+
+contains
+
+  !-------------------------------------------------------------
+  ! Square test case
+  !-------------------------------------------------------------
+
+  subroutine init_square_test_case_weak(mesh, icestate, weak)
+
+    type(mesh_type), intent(in) :: mesh
+
+    type(icestate_type), pointer :: icestate
+    type(weak_type),     pointer :: weak
+
+    call init_atmos_velocity(weak % uAirVelocity % array, &amp;
+                             weak % vAirVelocity % array, &amp;
+                             mesh % xVertex % array,        &amp;
+                             mesh % yVertex % array,        &amp;
+                             0.0_RKIND)
+
+    call init_ocean_velocity(weak % uOceanVelocity % array, &amp;
+                             weak % vOceanVelocity % array, &amp;
+                             mesh % xVertex % array,          &amp;
+                             mesh % yVertex % array)
+
+    call init_ice_state(mesh, icestate, weak)
+
+  end subroutine init_square_test_case_weak
+
+  !-------------------------------------------------------------
+
+  subroutine init_square_test_case_tri(mesh, icestate, forcing)
+
+    type(mesh_type), intent(in) :: mesh
+
+    type(icestate_type), pointer :: icestate
+    type(forcing_type),  pointer :: forcing
+
+    call init_atmos_velocity(forcing % uAirVelocity % array, &amp;
+                             forcing % vAirVelocity % array, &amp;
+                             mesh % xCell % array,           &amp;
+                             mesh % yCell % array,           &amp;
+                             0.0_RKIND)
+
+    call init_ocean_velocity(forcing % uOceanVelocity % array, &amp;
+                             forcing % vOceanVelocity % array, &amp;
+                             mesh % xCell % array,             &amp;
+                             mesh % yCell % array)
+
+    !call init_ice_state(mesh, icestate)
+
+  end subroutine init_square_test_case_tri
+
+  !-------------------------------------------------------------
+
+  subroutine init_square_test_case_hex(mesh, icestate, hexfor)
+
+    type(mesh_type), intent(in) :: mesh
+
+    type(icestate_type), pointer :: icestate
+    type(hexfor_type),   pointer :: hexfor
+
+    call init_atmos_velocity(hexfor % uAirVelocity % array, &amp;
+                             hexfor % vAirVelocity % array, &amp;
+                             mesh % xVertex % array,        &amp;
+                             mesh % yVertex % array,        &amp;
+                             0.0_RKIND)
+
+    call init_ocean_velocity(hexfor % uOceanVelocity % array, &amp;
+                             hexfor % vOceanVelocity % array, &amp;
+                             mesh % xVertex % array,          &amp;
+                             mesh % yVertex % array)
+
+    !call init_ice_state(mesh, icestate)
+
+  end subroutine init_square_test_case_hex
+
+  !-------------------------------------------------------------
+
+  subroutine init_ocean_velocity(uOceanVelocity, vOceanVelocity, x, y)
+
+    real(kind=RKIND), dimension(:), intent(out) :: &amp;
+         uOceanVelocity, &amp;
+         vOceanVelocity
+
+    real(kind=RKIND), dimension(:), intent(in) :: &amp;
+         x, y
+
+    real(kind=RKIND), parameter :: a = 0.1_RKIND  
+   
+    real(kind=RKIND), parameter :: &amp;
+         Lx = 1.28e6_RKIND, &amp;
+         Ly = 1.28e6_RKIND
+
+    integer :: iPoint, nPoints
+
+    nPoints = size(uOceanVelocity,1)
+
+    do iPoint = 1, nPoints
+       
+       uOceanVelocity(iPoint) =  a * ((2.0_RKIND * y(iPoint) - Ly) / Ly)
+
+       vOceanVelocity(iPoint) = -a * ((2.0_RKIND * x(iPoint) - Lx) / Lx)
+       
+    enddo ! iCell
+
+  end subroutine init_ocean_velocity
+
+  !-------------------------------------------------------------
+
+  subroutine init_atmos_velocity(uAirVelocity, vAirVelocity, xin, yin, time)
+
+    real(kind=RKIND), dimension(:), intent(out) :: &amp;
+         uAirVelocity, &amp;
+         vAirVelocity
+
+    real(kind=RKIND), dimension(:), intent(in) :: &amp;
+         xin, yin
+
+    real(kind=RKIND), intent(in) :: &amp;
+         time
+
+    real(kind=RKIND), parameter :: pi = &amp;
+         3.142_RKIND
+
+    real(kind=RKIND), parameter :: a = 5.0_RKIND
+    real(kind=RKIND), parameter :: b = 3.0_RKIND
+
+    real(kind=RKIND), parameter :: theta = 4.0_RKIND * 24.0_RKIND * 3600.0_RKIND
+
+    real(kind=RKIND), parameter :: &amp;
+         Lx = 1.28e6_RKIND, &amp;
+         Ly = 1.28e6_RKIND
+
+    real(kind=RKIND) :: &amp;
+         x, y, &amp;
+         xmin, xmax, ymin, ymax
+
+    integer :: iPoint, nPoints
+
+    xmin = minval(xin)
+    xmax = maxval(xin)
+    ymin = minval(yin)
+    ymax = maxval(yin)
+
+    nPoints = size(uAirVelocity,1)
+
+    do iPoint = 1, nPoints
+
+       !x = ((xin(iPoint) - xmin) / (xmax - xmin)) * Lx
+       !y = ((yin(iPoint) - ymin) / (ymax - ymin)) * Ly
+
+       x = xin(iPoint)
+       y = yin(iPoint)
+
+       uAirVelocity(iPoint) = &amp;!a * (y / Ly)
+            a + (sin((2.0_RKIND * pi * time) / theta) - b) * sin(2.0_RKIND * pi * (x / Lx)) * sin(pi * (y / Ly))
+       vAirVelocity(iPoint) = &amp;!0.0_RKIND!&amp;
+            a + (sin((2.0_RKIND * pi * time) / theta) - b) * sin(2.0_RKIND * pi * (y / Ly)) * sin(pi * (x / Lx))
+
+       !uAirVelocity(iPoint) = a
+       !vAirVelocity(iPoint) = a
+
+    enddo ! iPoint
+
+  end subroutine init_atmos_velocity
+
+  !-------------------------------------------------------------
+
+  subroutine init_ice_state(mesh, icestate, weak)
+
+    type(mesh_type), intent(in) :: mesh
+
+    type(icestate_type), pointer :: icestate
+    type(weak_type),     pointer :: weak
+
+    real(kind=RKIND) :: iceThickness
+
+    real(kind=RKIND) :: x    
+
+    real(kind=RKIND), parameter :: &amp;
+         Lx = 1.28e6_RKIND, &amp;
+         rhoi = 917.0_RKIND
+
+    integer :: iCell
+
+    iceThickness = 2.0_RKIND
+
+    do iCell = 1, mesh % nCells
+
+       x = mesh % xCell % array(iCell)
+
+       icestate % iceAreaCell % array(iCell) = &amp;!0.95_RKIND!&amp;
+            max(min(x / Lx, 1.0_RKIND), 0.0_RKIND)
+
+       icestate % iceVolumeCell % array(iCell) = &amp;
+            iceThickness * icestate % iceAreaCell % array(iCell)
+
+       icestate % totalMassCell % array(iCell) = icestate % iceVolumeCell % array(iCell) * rhoi
+
+       weak % uVelocity % array = weak % uOceanVelocity % array
+       weak % vVelocity % array = weak % vOceanVelocity % array
+
+    enddo ! iCell
+
+  end subroutine init_ice_state
+
+  !-------------------------------------------------------------
+  ! stress divergence operator test velocities
+  !-------------------------------------------------------------
+
+  subroutine divergence_stress_test_velocity_set(uVelocity, vVelocity, x, y, type)
+    
+    real(kind=RKIND), dimension(:), intent(out) :: &amp;
+         uVelocity, &amp;
+         vVelocity
+
+    real(kind=RKIND), dimension(:), intent(in) :: &amp;
+         x, y
+    
+    character(len=*), intent(in) :: &amp;
+         type
+
+    integer :: iPoint, nPoints
+
+    real(kind=RKIND), parameter :: &amp;
+         velocityConstantU = 112.87654_RKIND, &amp;
+         velocityConstantV = -34.5678_RKIND, &amp;
+         velocityScale = 1.0_RKIND
+
+    nPoints = size(uVelocity,1)
+
+    select case (type)
+    case (&quot;zero&quot;)
+       write(*,*) &quot;zero velocities&quot;
+
+       ! zero velocities
+       do iPoint = 1, nPoints
+          uVelocity(iPoint) = 0.0_RKIND
+          vVelocity(iPoint) = 0.0_RKIND
+       enddo ! iPoint
+
+    case (&quot;constant&quot;)
+       write(*,*) &quot;constant velocities&quot;
+
+       ! constant velocities
+       do iPoint = 1, nPoints
+          uVelocity(iPoint) = velocityConstantU
+          vVelocity(iPoint) = velocityConstantV
+       enddo ! iPoint
+
+    case (&quot;linearx&quot;)
+       write(*,*) &quot;linearx velocities&quot;
+
+       ! constant velocities
+       do iPoint = 1, nPoints
+          uVelocity(iPoint) = x(iPoint)
+          vVelocity(iPoint) = 0.0_RKIND
+       enddo ! iPoint
+
+    case (&quot;lineary&quot;)
+       write(*,*) &quot;lineary velocities&quot;
+
+       ! constant velocities
+       do iPoint = 1, nPoints
+          uVelocity(iPoint) = 0.0_RKIND
+          vVelocity(iPoint) = y(iPoint)
+       enddo ! iPoint
+
+    case (&quot;constantsig12&quot;)
+       write(*,*) &quot;constant sigma_12&quot;
+
+       ! constant velocities
+       do iPoint = 1, nPoints
+          uVelocity(iPoint) = y(iPoint)
+          vVelocity(iPoint) = x(iPoint)
+       enddo ! iPoint
+
+    case (&quot;div1&quot;)
+       write(*,*) &quot;div1 velocities&quot;
+
+       ! velocity field that gives constant divergence
+       do iPoint = 1, nPoints
+          uVelocity(iPoint) = x(iPoint)**2 / (4.0_RKIND * lambda) + (x(iPoint) * y(iPoint)) / lambda
+          vVelocity(iPoint) = y(iPoint)**2 / (4.0_RKIND * lambda) + (x(iPoint) * y(iPoint)) / lambda
+          uVelocity(iPoint) = uVelocity(iPoint) * velocityScale
+          vVelocity(iPoint) = vVelocity(iPoint) * velocityScale
+       enddo ! iPoint
+
+    end select
+
+  end subroutine divergence_stress_test_velocity_set
+
+  !-------------------------------------------------------------
+
+  subroutine divergence_stress_test_stress_set_hex(mesh, stress1, stress2, stress12)
+
+    type(mesh_type), intent(in) :: mesh
+
+    real(kind=RKIND), dimension(:,:), intent(inout) :: &amp;
+         stress1, &amp;
+         stress2, &amp;
+         stress12
+
+    real(kind=RKIND) :: &amp;
+         xpy, &amp;
+         x, y
+
+    integer :: &amp;
+         iCell, &amp;
+         iVertexOnCell, &amp;
+         iVertex
+
+    do iCell = 1, mesh % nCells
+
+       do iVertexOnCell = 1, mesh % nEdgesOnCell % array(iCell)
+
+          iVertex = mesh % verticesOnCell % array(iVertexOnCell,iCell)
+
+          x = mesh % xVertex % array(iVertex)
+          y = mesh % yVertex % array(iVertex)
+
+          xpy = x + y
+
+          ! divu = 1 ; divv = 1
+          stress1(iVertexOnCell,iCell)  =  1.5_RKIND * xpy
+          stress2(iVertexOnCell,iCell)  = -0.5_RKIND * xpy
+          stress12(iVertexOnCell,iCell) =  0.5_RKIND * xpy
+
+          ! divu = 1 ; divv = 0
+          !stress1(iVertexOnCell,iCell)  =  0.5_RKIND * x
+          !stress2(iVertexOnCell,iCell)  =  0.5_RKIND * x
+          !stress12(iVertexOnCell,iCell) =  0.5_RKIND * y
+
+          ! divu = 0 ; divv = 1
+          !stress1(iVertexOnCell,iCell)  =  0.5_RKIND * y
+          !stress2(iVertexOnCell,iCell)  = -0.5_RKIND * y
+          !stress12(iVertexOnCell,iCell) =  0.5_RKIND * x
+
+          ! others
+          !stress1(iVertexOnCell,iCell)  =  0.5_RKIND * x
+          !stress2(iVertexOnCell,iCell)  =  0.5_RKIND * x
+          !stress12(iVertexOnCell,iCell) =  0.0_RKIND
+
+          !stress1(iVertexOnCell,iCell)  =  0.0_RKIND
+          !stress2(iVertexOnCell,iCell)  =  0.0_RKIND
+          !stress12(iVertexOnCell,iCell) =  xpy
+
+          !stress1(iVertexOnCell,iCell)  =  y
+          !stress2(iVertexOnCell,iCell)  =  -y
+          !stress12(iVertexOnCell,iCell) =  0.0_RKIND
+
+          stress1(iVertexOnCell,iCell)  =  0.5_RKIND * x + y
+          stress2(iVertexOnCell,iCell)  =  0.5_RKIND * y + x
+          stress12(iVertexOnCell,iCell) =  0.5_RKIND * (x + y)
+
+          stress1(iVertexOnCell,iCell)  =  x
+          stress2(iVertexOnCell,iCell)  =  0.0_RKIND
+          stress12(iVertexOnCell,iCell) =  0.0_RKIND
+
+
+       enddo ! iVertexOnCell
+
+    enddo ! iCell
+
+  end subroutine divergence_stress_test_stress_set_hex
+
+  !-------------------------------------------------------------
+
+  subroutine divergence_stress_test_stress_set_tri(mesh, stress1, stress2, stress12)
+
+    type(mesh_type), intent(in) :: mesh
+
+    real(kind=RKIND), dimension(:,:), intent(inout) :: &amp;
+         stress1, &amp;
+         stress2, &amp;
+         stress12
+
+    real(kind=RKIND) :: &amp;
+         xpy, &amp;
+         x, y
+
+    integer :: &amp;
+         iVertex, &amp;
+         iVertexDegree, &amp;
+         iCell
+
+    do iVertex = 1, mesh % nVertices
+
+       do iVertexDegree = 1, mesh % vertexDegree
+
+          iCell = mesh % cellsOnVertex % array(iVertexDegree,iVertex)
+
+          x = mesh % xCell % array(iCell)
+          y = mesh % yCell % array(iCell)
+
+          xpy = x + y
+
+          ! divu = 1 ; divv = 1
+          !stress1(iVertexDegree,iVertex)  =  1.5_RKIND * xpy
+          !stress2(iVertexDegree,iVertex)  = -0.5_RKIND * xpy
+          !stress12(iVertexDegree,iVertex) =  0.5_RKIND * xpy
+
+          ! divu = 1 ; divv = 0
+          !stress1(iVertexDegree,iVertex)  =  0.5_RKIND * x
+          !stress2(iVertexDegree,iVertex)  =  0.5_RKIND * x
+          !stress12(iVertexDegree,iVertex) =  0.5_RKIND * y
+
+          ! divu = 0 ; divv = 1
+          !stress1(iVertexDegree,iVertex)  =  0.5_RKIND * y
+          !stress2(iVertexDegree,iVertex)  = -0.5_RKIND * y
+          !stress12(iVertexDegree,iVertex) =  0.5_RKIND * x
+
+          ! others
+          !stress1(iVertexDegree,iVertex)  =  0.5_RKIND * x
+          !stress2(iVertexDegree,iVertex)  =  0.5_RKIND * x
+          !stress12(iVertexDegree,iVertex) =  0.0_RKIND
+
+          !stress1(iVertexDegree,iVertex)  =  0.0_RKIND
+          !stress2(iVertexDegree,iVertex)  =  0.0_RKIND
+          !stress12(iVertexDegree,iVertex) =  xpy
+
+          !stress1(iVertexDegree,iVertex)  =  y
+          !stress2(iVertexDegree,iVertex)  =  -y
+          !stress12(iVertexDegree,iVertex) =  0.0_RKIND
+
+          !stress1(iVertexDegree,iVertex)  =  0.5_RKIND * x + y
+          !stress2(iVertexDegree,iVertex)  =  0.5_RKIND * y + x
+          !stress12(iVertexDegree,iVertex) =  0.5_RKIND * (x + y)
+
+          stress1(iVertexDegree,iVertex)  =  x
+          stress2(iVertexDegree,iVertex)  =  0.0_RKIND
+          stress12(iVertexDegree,iVertex) =  0.0_RKIND
+
+
+       enddo ! iVertexOnCell
+
+    enddo ! iCell
+
+  end subroutine divergence_stress_test_stress_set_tri
+
+  !-------------------------------------------------------------
+
+  subroutine divergence_stress_test_stress_set_weak(mesh, stress11, stress22, stress12)
+
+    type(mesh_type), intent(in) :: mesh
+
+    real(kind=RKIND), dimension(:), intent(inout) :: &amp;
+         stress11, &amp;
+         stress22, &amp;
+         stress12
+
+    real(kind=RKIND) :: &amp;
+         xpy, &amp;
+         x, y
+
+    integer :: &amp;
+         iCell
+
+    do iCell = 1, mesh % nCells
+
+       x = mesh % xCell % array(iCell)
+       y = mesh % yCell % array(iCell)
+
+       xpy = x + y
+
+       ! divu = 1 ; divv = 0
+       !stress11(iCell) =  x
+       !stress22(iCell) =  0.0_RKIND
+       !stress12(iCell) =  0.0_RKIND
+
+       ! divu = 0 ; divv = 1
+       !stress11(iCell) =  0.0_RKIND
+       !stress22(iCell) =  y
+       !stress12(iCell) =  0.0_RKIND
+
+       ! divu = 1 ; divv = 1
+       !stress11(iCell) =  x
+       !stress22(iCell) =  y
+       !stress12(iCell) =  0.0_RKIND
+
+       ! divu = 1 ; divv = 1
+       !stress11(iCell) =  0.5_RKIND * xpy
+       !stress22(iCell) =  0.5_RKIND * xpy
+       !stress12(iCell) =  0.5_RKIND * xpy
+
+       ! divu = 1 ; divv = 1
+       stress11(iCell) =  100.0_RKIND
+       stress22(iCell) =  -1000.0_RKIND
+       stress12(iCell) =  1.0_RKIND * xpy
+
+    enddo ! iCell
+
+  end subroutine divergence_stress_test_stress_set_weak
+
+  !-------------------------------------------------------------
+  ! general plotting
+  !-------------------------------------------------------------
+  
+  subroutine gnuplot_cell(mesh, cellArray, filename, append, nofill) 
+    
+    type(mesh_type), intent(in) :: mesh
+    
+    real(kind=RKIND), dimension(:), intent(in) :: &amp;
+         cellArray
+    
+    character(len=*), intent(in) :: &amp;
+         filename
+    
+    logical, optional, intent(in) :: &amp;
+         append, &amp;
+         nofill
+
+    real(kind=RKIND) :: &amp;
+         x, y, x0, y0, xc, yc
+
+    real(kind=RKIND) :: &amp;
+         fMin, fMax, &amp;
+         fValue
+
+    integer :: &amp;
+         iCell, &amp;
+         iVertexOnCell, &amp;
+         iVertex
+
+    character(len=400) :: &amp;
+         stroutvertex, &amp;
+         strout, &amp;
+         stroutlabel, &amp;
+         stroutint
+
+    integer :: &amp;
+         red, &amp;
+         green, &amp;
+         blue
+
+    character(len=7) :: &amp;
+         color
+
+    ! optional arguments 
+    logical :: &amp;
+         lappend, &amp;
+         lnofill
+
+    ! optional arguments
+    lappend = .false.
+    if (present(append)) lappend = append
+
+    lnofill = .false.
+    if (present(nofill)) lnofill = nofill
+
+    fMin = minval(cellArray(1:mesh % nCells))
+    fMax = maxval(cellArray(1:mesh % nCells))
+    !fMin = 1
+    !fMax = mesh % nCells
+
+    if (lappend) then
+       open(55,file=filename,action=&quot;write&quot;,position=&quot;append&quot;)
+    else
+       open(55,file=filename,action=&quot;write&quot;)
+    end if
+
+    open(56,file=&quot;border.txt&quot;,action=&quot;write&quot;)
+
+    write(56,*) minval(mesh % cellsOnCell % array), maxval(mesh % cellsOnCell % array)
+    write(56,*) minloc(mesh % cellsOnCell % array), maxloc(mesh % cellsOnCell % array)
+    write(56,*) size(mesh % cellsOnCell % array,1), size(mesh % cellsOnCell % array,2)
+
+    do iCell = 1, mesh % nCells
+
+       xc = mesh % xCell % array(iCell)
+       yc = mesh % yCell % array(iCell)
+
+       xmin = min(xmin,xc) ; xmax = max(xmax,xc)
+       ymin = min(ymin,yc) ; ymax = max(ymax,yc)
+
+       !write(stroutint,fmt='(i5)') iCell
+       !write(stroutlabel,fmt='(a,i5,a,a,a,f14.2,a,f14.2,a)') &quot;set label &quot;,iLabel,' &quot;',trim(adjustl(stroutint)),'&quot; at ',xc, &quot;,&quot;,yc, &quot; center&quot;
+       !iLabel = iLabel + 1
+       !write(55,*) trim(stroutlabel)
+
+       fValue = (cellArray(iCell) - fMin) / (fMax - fMin) 
+       !fValue = (real(iCell,RKIND) - fMin) / (fMax - fMin) 
+
+       write(strout,fmt='(a,i5,a)') &quot;set object &quot;,iObject,&quot; polygon from &quot;
+
+       do iVertexOnCell = 1, mesh % nEdgesOnCell % array(iCell)
+
+          !write(*,*) iCell, iVertexOnCell
+
+          write(56,*) iCell, mesh % nCells, iVertexOnCell, mesh % cellsOnCell % array(iVertexOnCell, iCell)
+
+          iVertex = mesh % verticesOnCell % array(iVertexOnCell, iCell)
+
+          x = mesh % xVertex % array(iVertex)
+          y = mesh % yVertex % array(iVertex)
+
+          xmin = min(xmin,x) ; xmax = max(xmax,x)
+          ymin = min(ymin,y) ; ymax = max(ymax,y)
+
+          if (iVertexOnCell == 1) then
+             x0 = x
+             y0 = y
+          endif
+
+          write(stroutvertex,fmt='(f14.2,a,f14.2,a)') x, &quot;,&quot;, y, &quot; to &quot;
+
+          strout = trim(strout)//trim(stroutvertex)
+
+       enddo ! iVertex
+
+       write(stroutvertex,fmt='(f14.2,a,f14.2)') x0, &quot;,&quot;, y0
+
+       strout = trim(strout)//trim(stroutvertex)
+
+       write(55,*) trim(strout)
+
+       color = matlab_jet(fValue)
+       !if (iCell == 3272) color = &quot;#000000&quot;
+
+       if (lnofill) then
+          write(strout,fmt='(a,i5,a,a,a)') &quot;set object &quot;,iObject,' fillstyle empty border lt -1'
+       else
+          write(strout,fmt='(a,i5,a,a,a)') &quot;set object &quot;,iObject,' fc rgb &quot;', color, '&quot; fillstyle solid'
+       endif
+
+       write(55,*) trim(strout)
+
+       iObject = iObject + 1
+
+    enddo ! iCell
+
+    write(stroutint,fmt='(e20.8)') fMax
+    write(stroutlabel,fmt='(a,i5,a,a,a)') &quot;set label &quot;,iLabel,' &quot;',trim(adjustl(stroutint)),'&quot; at graph 1.02, 0.9'
+    iLabel = iLabel + 1
+    write(55,*) trim(stroutlabel)
+
+
+    write(stroutint,fmt='(e20.8)') fMin
+    write(stroutlabel,fmt='(a,i5,a,a,a)') &quot;set label &quot;,iLabel,' &quot;',trim(adjustl(stroutint)),'&quot; at graph 1.02, 0.8'
+    iLabel = iLabel + 1
+    write(55,*) trim(stroutlabel)
+
+    close(55)
+    close(56)
+
+    !call gnuplot_triangle(mesh, mesh % xVertex % array, filename, .true., mesh % nCells, .true.)
+!stop
+  end subroutine gnuplot_cell
+
+  !-------------------------------------------------------------
+
+  subroutine gnuplot_triangle(mesh, vertexArray, filename, append, nofill)
+
+    type(mesh_type), intent(in) :: mesh
+
+    real(kind=RKIND), dimension(:), intent(in) :: &amp;
+         vertexArray
+
+    character(len=*), intent(in) :: &amp;
+         filename
+
+    logical, optional, intent(in) :: &amp;
+         append, &amp;
+         nofill
+
+    real(kind=RKIND) :: &amp;
+         x, y, x0, y0, xv, yv
+
+    real(kind=RKIND) :: &amp;
+         fMin, fMax, &amp;
+         fValue
+
+    integer :: &amp;
+         iVertex, &amp;
+         iVertexDegree, &amp;
+         iCell
+
+    character(len=400) :: &amp;
+         stroutvertex, &amp;
+         strout, &amp;
+         stroutlabel, &amp;
+         stroutint
+
+    integer :: &amp;
+         red, &amp;
+         green, &amp;
+         blue
+
+    character(len=7) :: &amp;
+         color
+
+    logical :: atBoundary
+
+    ! optional arguments 
+    logical :: &amp;
+         lappend, &amp;
+         lnofill
+
+    ! optional arguments
+    lappend = .false.
+    if (present(append)) lappend = append
+
+    lnofill = .false.
+    if (present(nofill)) lnofill = nofill
+
+    ! min/maxes
+    fMin = 1e30
+    fMax = -1e30
+
+    ! loop over triangles
+    do iVertex = 1, mesh % nVertices
+       atBoundary = .false.
+
+       ! loop over triangle vertices
+       do iVertexDegree = 1, mesh % vertexDegree
+
+          iCell = mesh % cellsOnVertex % array(iVertexDegree,iVertex)
+
+          if (iCell &gt; mesh % nCells) then
+             atBoundary = .true.
+          end if
+       enddo ! iVertexDegree
+
+       if (.not. atBoundary) then
+          fMin = min(fMin,vertexArray(iVertex))
+          fMax = max(fMax,vertexArray(iVertex))
+       endif
+    
+    enddo ! iVertex
+    !fMin = minval(vertexArray)
+    !fMax = maxval(vertexArray)
+    !fMin = 1
+    !fMax = mesh % nVertices
+
+    if (lappend) then
+       open(55,file=filename,action=&quot;write&quot;,position=&quot;append&quot;)
+    else
+       open(55,file=filename,action=&quot;write&quot;)
+    end if
+
+    ! loop over triangles
+    do iVertex = 1, mesh % nVertices
+
+       xv = mesh % xVertex % array(iVertex)
+       yv = mesh % yVertex % array(iVertex)
+
+       xmin = min(xmin,xv) ; xmax = max(xmax,xv)
+       ymin = min(ymin,yv) ; ymax = max(ymax,yv)
+
+       !write(stroutint,fmt='(i5)') iVertex
+       !write(stroutlabel,fmt='(a,i5,a,a,a,f14.2,a,f14.2,a)') &quot;set label &quot;,iLabel,' &quot;',trim(adjustl(stroutint)),'&quot; at ',xv, &quot;,&quot;,yv, &quot; center&quot;
+       !iLabel = iLabel + 1
+       !write(55,*) trim(stroutlabel)
+
+       atBoundary = .false.
+
+       fValue = (vertexArray(iVertex) - fMin) / (fMax - fMin) 
+       !fValue = (real(iVertex,RKIND) - fMin) / (fMax - fMin) 
+       !write(*,*) iVertex, vertexArray(iVertex), fMin, fMax
+
+       write(strout,fmt='(a,i5,a)') &quot;set object &quot;,iObject,&quot; polygon from &quot;
+
+       ! loop over triangle vertices
+       do iVertexDegree = 1, mesh % vertexDegree
+
+          iCell = mesh % cellsOnVertex % array(iVertexDegree,iVertex)
+
+          if (iCell &gt; mesh % nCells) then
+             atBoundary = .true.
+          end if
+
+          x = mesh % xCell % array(iCell)
+          y = mesh % yCell % array(iCell)
+
+          if (.not. atBoundary) then
+             xmin = min(xmin,x) ; xmax = max(xmax,x)
+             ymin = min(ymin,y) ; ymax = max(ymax,y)
+          endif
+
+          if (iVertexDegree == 1) then
+             x0 = x
+             y0 = y
+          endif
+
+          write(stroutvertex,fmt='(f14.2,a,f14.2,a)') x, &quot;,&quot;, y, &quot; to &quot;
+
+          strout = trim(strout)//trim(stroutvertex)
+
+       enddo ! iVertexDegree
+
+       write(stroutvertex,fmt='(f14.2,a,f14.2)') x0, &quot;,&quot;, y0
+
+       strout = trim(strout)//trim(stroutvertex)
+
+       if (.not. atBoundary) write(55,*) trim(strout)
+
+       color = matlab_jet(fValue)
+
+       if (lnofill) then
+          write(strout,fmt='(a,i5,a,a,a)') &quot;set object &quot;,iObject,' fillstyle empty border lt -1'
+       else
+          write(strout,fmt='(a,i5,a,a,a)') &quot;set object &quot;,iObject,' fc rgb &quot;', color, '&quot; fillstyle solid'
+       endif
+
+       if (.not. atBoundary) iObject = iObject + 1
+
+       if (.not. atBoundary) write(55,*) trim(strout)
+
+    enddo ! iVertex
+
+    write(stroutint,fmt='(e20.8)') fMax
+    write(stroutlabel,fmt='(a,i5,a,a,a)') &quot;set label &quot;,iLabel,' &quot;',trim(adjustl(stroutint)),'&quot; at graph 1.02, 0.9'
+    iLabel = iLabel + 1
+    write(55,*) trim(stroutlabel)
+
+
+    write(stroutint,fmt='(e20.8)') fMin
+    write(stroutlabel,fmt='(a,i5,a,a,a)') &quot;set label &quot;,iLabel,' &quot;',trim(adjustl(stroutint)),'&quot; at graph 1.02, 0.8'
+    iLabel = iLabel + 1
+    write(55,*) trim(stroutlabel)
+
+    close(55)
+
+  end subroutine gnuplot_triangle
+
+  !-------------------------------------------------------------
+
+  subroutine gnuplot_vertexvector(mesh, vertexArrayU, vertexArrayV, filename)
+
+    type(mesh_type), intent(in) :: mesh
+
+    real(kind=RKIND), dimension(:), intent(in) :: &amp;
+         vertexArrayU, &amp;
+         vertexArrayV
+
+    character(len=*), intent(in) :: &amp;
+         filename
+
+    integer, parameter :: plot_every = 10
+
+    real(kind=RKIND), parameter :: &amp;
+         plotLength = 100000.0_RKIND
+
+    character(len=200) :: strout
+
+    real(kind=RKIND) :: &amp;
+         x1, x2, y1, y2, &amp;
+         n1, n2, &amp;
+         arrowLength, &amp;
+         arrowLengthMax, &amp;
+         arrowLengthPlot, &amp;
+         random
+
+    integer :: iVertex
+
+    ! find maximum vector
+    arrowLengthMax = -1e30
+
+    do iVertex = 1, mesh % nVertices
+
+       n1 = vertexArrayU(iVertex)
+       n2 = vertexArrayV(iVertex)
+       arrowLength = sqrt(n1**2 + n2**2)
+
+       arrowLengthMax = Max(arrowLengthMax,arrowLength)
+
+    enddo ! iVertex
+
+    write(*,*) arrowLengthMax
+
+
+    open(55,file=filename)
+
+    do iVertex = 1, mesh % nVertices
+    
+       random = rand()
+
+       if (random &lt;= 1.0_RKIND / real(plot_every,RKIND)) then
+
+
+          n1 = vertexArrayU(iVertex)
+          n2 = vertexArrayV(iVertex)
+          arrowLength = sqrt(n1**2 + n2**2)
+          n1 = n1 / arrowLength
+          n2 = n2 / arrowLength
+
+          arrowLengthPlot = (arrowLength / arrowLengthMax) * plotLength
+
+          x1 = mesh % xVertex % array(iVertex)
+          y1 = mesh % yVertex % array(iVertex)
+
+          x2 = x1 + n1 * arrowLengthPlot
+          y2 = y1 + n2 * arrowLengthPlot
+
+          write(*,*) arrowLengthPlot, n1, n2, x1, y1, x2, y2
+
+          write(strout,fmt='(a,i5,a,f14.2,a,f14.2,a,f14.2,a,f14.2)') &quot;set arrow &quot;,iArrow,&quot; from &quot;,x1,&quot;,&quot;,y1,&quot; to &quot;,x2,&quot;,&quot;,y2
+          iArrow = iArrow + 1
+
+          write(55,*) trim(strout)
+
+       endif
+
+    enddo ! iVertex
+
+    close(55)
+
+  end subroutine gnuplot_vertexvector
+
+  !-------------------------------------------------------------
+
+  function hexstring(red,green,blue) result(hex)
+
+    integer, intent(in) :: red,green,blue
+    character(len=7) :: hex
+
+    integer :: hex1, hex2
+
+    hex = &quot;#&quot;//dectohex(red)//dectohex(green)//dectohex(blue)
+
+  end function hexstring
+
+  !-------------------------------------------------------------
+
+  function dectohex(dec) result(hex)
+
+    integer, intent(in) :: dec
+    character(len=2) :: hex
+
+    integer :: hex1, hex2
+
+    character(len=1), dimension(16), parameter :: hexchars = &amp;
+         (/'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'/)
+
+    hex1 = floor(real(dec, RKIND) / 16.0_RKIND)
+    hex2 = dec - hex1 * 16
+
+    hex = hexchars(hex1+1)//hexchars(hex2+1)
+
+  end function dectohex
+
+  !-------------------------------------------------------------
+
+  function matlab_jet(f) result(color)
+
+    real(kind=RKIND), intent(in) :: f
+    character(len=7) :: color
+
+    real(kind=RKIND) :: r_red, r_green, r_blue
+    integer :: red, green, blue
+
+    r_blue  = max(min(min(4.0_RKIND * f + 0.5_RKIND, -4.0_RKIND * f + 2.5_RKIND),1.0_RKIND),0.0_RKIND)
+
+    r_green = max(min(min(4.0_RKIND * f - 0.5_RKIND, -4.0_RKIND * f + 3.5_RKIND),1.0_RKIND),0.0_RKIND)
+
+    r_red   = max(min(min(4.0_RKIND * f - 1.5_RKIND, -4.0_RKIND * f + 4.5_RKIND),1.0_RKIND),0.0_RKIND)
+
+    red   = nint(r_red   * 255)
+    green = nint(r_green * 255)
+    blue  = nint(r_blue  * 255)
+
+    color = hexstring(red,green,blue)
+
+  end function matlab_jet
+
+  !-------------------------------------------------------------
+
+  subroutine boundary_locations(mesh, boundaryCell, boundaryVertex, interiorVertex, boundaryEdge)
+
+    type(mesh_type), intent(in) :: mesh
+
+    integer, dimension(:), intent(in) :: &amp;
+         boundaryCell, &amp;
+         boundaryVertex, &amp;
+         interiorVertex, &amp;
+         boundaryEdge
+
+    integer :: &amp;
+         iCell, &amp;
+         iVertex, &amp;
+         iEdge
+
+    ! identify border cells
+    open(55,file=&quot;border_cell.txt&quot;,action=&quot;write&quot;)
+
+    do iCell = 1, mesh % nCells
+
+       if (boundaryCell(iCell) == 1) then
+
+          write(55,*) mesh % xCell % array(iCell), mesh % yCell % array(iCell)
+
+       endif
+
+    enddo ! iCell
+
+    close(55)
+
+    ! identify border vertices
+    open(55,file=&quot;border_vertex.txt&quot;,action=&quot;write&quot;)
+
+    do iVertex = 1, mesh % nVertices
+
+       if (boundaryVertex(iVertex) == 1) then
+
+          write(55,*) mesh % xVertex % array(iVertex), mesh % yVertex % array(iVertex)
+
+       endif
+
+    enddo ! iVertex
+
+    close(55)
+
+    ! identify interior vertices
+    open(55,file=&quot;interior_vertex.txt&quot;,action=&quot;write&quot;)
+
+    do iVertex = 1, mesh % nVertices
+
+       if (interiorVertex(iVertex) == 1) then
+
+          write(55,*) mesh % xVertex % array(iVertex), mesh % yVertex % array(iVertex)
+
+       endif
+
+    enddo ! iVertex
+
+    close(55)
+
+    ! identify border edges
+    open(55,file=&quot;border_edge.txt&quot;,action=&quot;write&quot;)
+
+    do iEdge = 1, mesh % nEdges
+
+       if (boundaryEdge(iEdge) == 1) then
+
+          write(55,*) mesh % xEdge % array(iEdge), mesh % yEdge % array(iEdge)
+
+       endif
+
+    enddo ! iVertex
+
+    close(55)
+
+  end subroutine boundary_locations
+
+  !-------------------------------------------------------------
+
+  subroutine plot_boundary_triangles(mesh, boundaryVertex, interiorVertex, boundaryEdge)
+
+    type(mesh_type), intent(in) :: mesh
+
+    integer, dimension(:), intent(in) :: &amp;
+         boundaryVertex, &amp;
+         interiorVertex, &amp;
+         boundaryEdge
+
+    real(kind=RKIND) :: &amp;
+         x, y, &amp;
+         x0, y0
+
+    character(len=200) :: &amp;
+         stroutvertex, &amp;
+         strout
+
+    integer :: &amp;
+         iEdgeBoundary, &amp;
+         iEdge, &amp;
+         iCellOnEdge, &amp;
+         iCell, &amp;
+         iVertexOnEdge, &amp;
+         iVertex, &amp;
+         iVertexDegree
+
+    integer :: start_index
+
+    start_index = mesh % nCells + mesh % nVertices + 10
+
+    open(55,file=&quot;boundary_triangles_edge.txt&quot;,action=&quot;write&quot;)
+
+    ! edge triangles
+    iEdgeBoundary = 0
+
+    do iEdge = 1, mesh % nEdges
+
+       write(0,*) iEdge, boundaryEdge(iEdge)
+
+       if (boundaryEdge(iEdge) == 1) then
+          ! am on boundary
+          iEdgeBoundary = iEdgeBoundary + 1
+
+          write(strout,fmt='(a,i5,a)') &quot;set object &quot;,iEdgeBoundary+start_index,&quot; polygon from &quot;
+
+          ! find the interior cell
+          do iCellOnEdge = 1, 2
+
+             iCell = mesh % cellsOnEdge %array(iCellOnEdge,iEdge)
+
+             if (iCell &gt;= 1 .and. iCell &lt;= mesh % nCells) then
+
+                ! this cell is interior to domain
+                x = mesh % xCell % array(iCell)
+                y = mesh % yCell % array(iCell)               
+                x0 = x
+                y0 = y
+
+                write(stroutvertex,fmt='(f10.2,a,f10.2,a)') x, &quot;,&quot;, y, &quot; to &quot;
+
+                strout = trim(strout)//trim(stroutvertex)
+
+             endif
+
+          enddo ! iCellOnEdge
+
+          ! find the adjacent vertices
+          do iVertexOnEdge = 1, 2
+
+             iVertex = mesh % verticesOnEdge % array(iVertexOnEdge,iEdge)
+
+             x = mesh % xVertex % array(iVertex)
+             y = mesh % yVertex % array(iVertex)
+
+             write(stroutvertex,fmt='(f10.2,a,f10.2,a)') x, &quot;,&quot;, y, &quot; to &quot;
+
+             strout = trim(strout)//trim(stroutvertex)
+
+          enddo ! iVertexOnEdge
+
+          write(stroutvertex,fmt='(f10.2,a,f10.2)') x0, &quot;,&quot;, y0
+
+          strout = trim(strout)//trim(stroutvertex)
+
+          write(55,*) trim(strout)
+
+          write(strout,fmt='(a,i5,a,a,a)') &quot;set object &quot;,iEdgeBoundary+start_index,' fillstyle empty border lt -1'
+
+          write(55,*) trim(strout)
+
+       endif
+
+    enddo ! iEdge
+
+    close(55)
+
+    open(55,file=&quot;boundary_triangles_vertex.txt&quot;,action=&quot;write&quot;)
+
+    ! loop over vertices
+    do iVertex = 1, mesh % nVertices
+
+       ! boundary vertex adjacent to two interior cells
+       if (boundaryVertex(iVertex) == 1) then
+
+          iEdgeBoundary = iEdgeBoundary + 1
+
+          write(strout,fmt='(a,i5,a)') &quot;set object &quot;,iEdgeBoundary+start_index,&quot; polygon from &quot;
+
+          ! starting vertex point
+          x = mesh % xVertex % array(iVertex)
+          y = mesh % yVertex % array(iVertex)
+          x0 = x
+          y0 = y
+
+          write(stroutvertex,fmt='(f10.2,a,f10.2,a)') x, &quot;,&quot;, y, &quot; to &quot;
+
+          strout = trim(strout)//trim(stroutvertex)
+
+          ! the two interior cells
+          do iVertexDegree = 1, mesh % vertexDegree
+
+             ! adjacent cell
+             iCell = mesh % cellsOnVertex % array(iVertexDegree, iVertex)
+
+             if (iCell &gt;= 1 .and. iCell &lt;= mesh % nCells) then
+                ! interior adjacent cell
+
+                x = mesh % xCell % array(iCell)
+                y = mesh % yCell % array(iCell)
+
+                write(stroutvertex,fmt='(f10.2,a,f10.2,a)') x, &quot;,&quot;, y, &quot; to &quot;
+
+                strout = trim(strout)//trim(stroutvertex)
+
+             endif
+
+          enddo ! iVertexDegree
+
+          write(stroutvertex,fmt='(f10.2,a,f10.2)') x0, &quot;,&quot;, y0
+
+          strout = trim(strout)//trim(stroutvertex)
+
+          write(55,*) trim(strout)
+
+          write(strout,fmt='(a,i5,a,a,a)') &quot;set object &quot;,iEdgeBoundary+start_index,' fillstyle empty border lt -1'
+
+          write(55,*) trim(strout)
+
+       endif
+
+    enddo ! iVertex
+
+    close(55)
+
+  end subroutine plot_boundary_triangles
+
+  !-------------------------------------------------------------
+
+  subroutine labels_verticesOnCell(mesh, verticesOnCell, filename) 
+
+    type(mesh_type), intent(in) :: mesh
+
+    integer, dimension(:,:), intent(in) :: &amp;
+         verticesOnCell
+
+    character(len=*), intent(in) :: &amp;
+         filename
+
+    integer :: &amp;
+         iCell
+
+    do iCell = 1, mesh % nCells
+
+       call label_verticesOnCell(mesh, iCell, verticesOnCell(:,iCell), filename, .true.) 
+
+    enddo ! iCell
+
+  end subroutine labels_verticesOnCell
+
+  !-------------------------------------------------------------
+
+  subroutine label_verticesOnCell(mesh, iCell, verticesOnCell, filename, append) 
+
+    type(mesh_type), intent(in) :: mesh
+
+    integer, intent(in) :: &amp;
+         iCell
+
+    integer, dimension(:), intent(in) :: &amp;
+         verticesOnCell
+
+    character(len=*), intent(in) :: &amp;
+         filename
+
+    logical, intent(in), optional :: &amp;
+         append
+
+    real(kind=RKIND) :: &amp;
+         x, y, x0, y0, xc, yc, xl, yl
+
+    real(kind=RKIND) :: &amp;
+         fMin, fMax
+
+    character(len=200) :: &amp;
+         stroutvertex, &amp;
+         strout, &amp;
+         stroutlabel, &amp;
+         stroutint
+
+    integer :: &amp;
+         iVertexOnCell, &amp;
+         iVertex
+
+    logical :: &amp;
+         lappend
+
+    lappend = .false.
+    if (present(append)) lappend = .true.
+
+    if (lappend) then
+       open(55,file=filename,position=&quot;append&quot;)
+    else
+       open(55,file=filename)
+    endif
+
+    write(strout,fmt='(a,i5,a)') &quot;set object &quot;,iObject,&quot; polygon from &quot;
+
+    xc = mesh % xCell % array(iCell)
+    yc = mesh % yCell % array(iCell)
+
+    ! draw cell
+    do iVertexOnCell = 1, mesh % nEdgesOnCell % array(iCell)
+
+       iVertex = mesh % verticesOnCell % array(iVertexOnCell,iCell)
+
+       x = mesh % xVertex % array(iVertex)
+       y = mesh % yVertex % array(iVertex)
+
+       if (iVertexOnCell == 1) then
+          x0 = x
+          y0 = y
+       endif
+
+       write(stroutvertex,fmt='(f10.2,a,f10.2,a)') x, &quot;,&quot;, y, &quot; to &quot;
+
+       strout = trim(strout)//trim(stroutvertex)
+
+       xl = 0.3_RKIND * xc + 0.7_RKIND * x
+       yl = 0.3_RKIND * yc + 0.7_RKIND * y
+
+       !write(stroutint,fmt='(i5)') iVertexOnCell
+       write(stroutint,fmt='(i5)') verticesOnCell(iVertexOnCell)
+       write(stroutlabel,fmt='(a,i5,a,a,a,f10.2,a,f10.2,a)') &quot;set label &quot;,iLabel,' &quot;',trim(adjustl(stroutint)),'&quot; at ',xl, &quot;,&quot;,yl, ' center font &quot;Helvetica,8&quot;'
+
+       write(55,*) trim(stroutlabel)
+
+       iLabel = iLabel + 1
+
+    enddo ! iVertexOnCell
+
+    write(stroutvertex,fmt='(f10.2,a,f10.2)') x0, &quot;,&quot;, y0
+
+    strout = trim(strout)//trim(stroutvertex)
+
+    write(55,*) trim(strout)
+
+    write(strout,fmt='(a,i5,a,a,a)') &quot;set object &quot;,iObject,' fillstyle empty border lt -1'
+
+    write(55,*) trim(strout)
+
+    iObject = iObject + 1
+
+    close(55)
+
+  end subroutine label_verticesOnCell
+
+  !-------------------------------------------------------------
+
+  subroutine labels_verticesDegreeOnVertex(mesh, verticesDegreeOnVertex, interiorVertex, filename) 
+
+    type(mesh_type), intent(in) :: mesh
+
+    integer, dimension(:,:), intent(in) :: &amp;
+         verticesDegreeOnVertex
+
+    integer, dimension(:), intent(in) :: &amp;
+         interiorVertex
+
+    character(len=*), intent(in) :: &amp;
+         filename
+
+    integer :: &amp;
+         iVertex
+
+    do iVertex = 1, mesh % nVertices
+
+       if (interiorVertex(iVertex) == 1) then
+
+          call label_verticesDegreeOnVertex(mesh, iVertex, verticesDegreeOnVertex(:,iVertex), filename, .true.) 
+
+       endif
+
+    enddo ! iVertex
+
+  end subroutine labels_verticesDegreeOnVertex
+
+  !-------------------------------------------------------------
+
+  subroutine label_verticesDegreeOnVertex(mesh, iVertex, verticesDegreeOnVertex, filename, append) 
+
+    type(mesh_type), intent(in) :: mesh
+
+    integer, intent(in) :: &amp;
+         iVertex
+
+    integer, dimension(:), intent(in) :: &amp;
+         verticesDegreeOnVertex
+
+    character(len=*), intent(in) :: &amp;
+         filename
+
+    logical, intent(in), optional :: &amp;
+         append
+
+    real(kind=RKIND) :: &amp;
+         x, y, x0, y0, xv, yv, xl, yl
+
+    real(kind=RKIND) :: &amp;
+         fMin, fMax
+
+    character(len=200) :: &amp;
+         stroutvertex, &amp;
+         strout, &amp;
+         stroutlabel, &amp;
+         stroutint
+
+    integer :: &amp;
+         iVertexDegree, &amp;
+         iCell
+
+    logical :: &amp;
+         lappend
+
+    lappend = .false.
+    if (present(append)) lappend = .true.
+
+    if (lappend) then
+       open(55,file=filename,position=&quot;append&quot;)
+    else
+       open(55,file=filename)
+    endif
+
+    write(strout,fmt='(a,i5,a)') &quot;set object &quot;,iObject,&quot; polygon from &quot;
+
+    xv = mesh % xVertex % array(iVertex)
+    yv = mesh % yVertex % array(iVertex)
+
+    ! draw cell
+    do iVertexDegree = 1, mesh % vertexDegree
+
+       iCell = mesh % cellsOnVertex % array(iVertexDegree,iVertex)
+
+       x = mesh % xCell % array(iCell)
+       y = mesh % yCell % array(iCell)
+
+       if (iVertexDegree == 1) then
+          x0 = x
+          y0 = y
+       endif
+
+       write(stroutvertex,fmt='(f10.2,a,f10.2,a)') x, &quot;,&quot;, y, &quot; to &quot;
+
+       strout = trim(strout)//trim(stroutvertex)
+
+       xl = 0.3_RKIND * xv + 0.7_RKIND * x
+       yl = 0.3_RKIND * yv + 0.7_RKIND * y
+
+       !write(stroutint,fmt='(i5)') iVertexDegree
+       write(stroutint,fmt='(i5)') verticesDegreeOnVertex(iVertexDegree)
+       write(stroutlabel,fmt='(a,i5,a,a,a,f10.2,a,f10.2,a)') &quot;set label &quot;,iLabel,' &quot;',trim(adjustl(stroutint)),'&quot; at ',xl, &quot;,&quot;,yl, ' center font &quot;Helvetica,8&quot;'
+       iLabel = iLabel + 1
+
+       write(55,*) trim(stroutlabel)
+
+    enddo ! iVertexOnCell
+
+    write(stroutvertex,fmt='(f10.2,a,f10.2)') x0, &quot;,&quot;, y0
+
+    strout = trim(strout)//trim(stroutvertex)
+
+    write(55,*) trim(strout)
+
+    write(strout,fmt='(a,i5,a,a,a)') &quot;set object &quot;,iObject,' fillstyle empty border lt -1'
+
+    write(55,*) trim(strout)
+
+    iObject = iObject + 1
+
+    close(55)
+
+  end subroutine label_verticesDegreeOnVertex
+
+  !-------------------------------------------------------------
+
+  subroutine writeout_minmax()
+
+    character(len=200) :: strout
+    real(kind=RKIND), parameter :: border = 7000.0_RKIND
+
+    real(kind=RKIND) :: xming, xmaxg, yming, ymaxg
+
+    xming = min(xmin,ymin)-border ; yming = xming
+    xmaxg = max(xmax,ymax)+border ; ymaxg = xmaxg
+
+    write(strout,fmt='(a,f10.2,a,f10.2,a,f10.2,a,f10.2,a)') &amp;
+         &quot;set size square ; set xrange [&quot;, xming, &quot;:&quot;, xmaxg, &quot;] ; set yrange [&quot;, yming, &quot;:&quot;, ymaxg, &quot;]&quot;
+    write(*,*) trim(strout)
+
+  end subroutine writeout_minmax
+
+  !-------------------------------------------------------------
+  ! write out variables routines
+  !-------------------------------------------------------------
+
+  subroutine writeout_on_cell_real(mesh, arrayOnCell, filename)
+
+    type(mesh_type), intent(in) :: mesh
+
+    real(kind=RKIND), dimension(:), intent(in) :: &amp;
+         arrayOnCell
+    
+    character(len=*), intent(in) :: &amp;
+         filename
+
+    integer :: iCell
+
+    open(55,file=filename)
+
+    do iCell = 1, mesh % nCells
+
+       write(55,*) iCell, arrayOnCell(iCell), &amp;
+            mesh % xCell % array(iCell), mesh % yCell % array(iCell)
+
+    enddo ! iCell
+
+    close(55)
+
+  end subroutine writeout_on_cell_real
+
+  !-------------------------------------------------------------
+
+  subroutine writeout_on_vertex_real(mesh, arrayOnVertex, filename)
+
+    type(mesh_type), intent(in) :: mesh
+
+    real(kind=RKIND), dimension(:), intent(in) :: &amp;
+         arrayOnVertex
+    
+    character(len=*), intent(in) :: &amp;
+         filename
+
+    integer :: iVertex
+
+    open(55,file=filename)
+
+    do iVertex = 1, mesh % nVertices
+
+       write(55,*) iVertex, arrayOnVertex(iVertex), &amp;
+            mesh % xVertex % array(iVertex), mesh % yVertex % array(iVertex)
+
+    enddo ! iVertex
+
+    close(55)
+
+  end subroutine writeout_on_vertex_real
+
+  !-------------------------------------------------------------
+
+  subroutine writeout_on_vertex_on_cell_real(mesh, arrayVertexOnCell, filename)
+
+    type(mesh_type), intent(in) :: mesh
+
+    real(kind=RKIND), dimension(:,:), intent(in) :: &amp;
+         arrayVertexOnCell
+    
+    character(len=*), intent(in) :: &amp;
+         filename
+
+    integer :: &amp;
+         iCell, &amp;
+         iVertexOnCell, &amp;
+         iVertex
+
+    open(55,file=filename)
+
+    do iCell = 1, mesh % nCells
+
+       do iVertexOnCell = 1, mesh % nEdgesOnCell % array(iCell)
+
+          iVertex = mesh % verticesOnCell % array(iVertexOnCell,iCell)
+
+          write(55,*) iCell, iVertexOnCell, arrayVertexOnCell(iVertexOnCell,iCell), &amp;
+               mesh % xVertex % array(iVertex), mesh % yVertex % array(iVertex), &amp;
+               arrayVertexOnCell(iVertexOnCell,iCell) / (mesh % xVertex % array(iVertex) + mesh % yVertex % array(iVertex))
+
+       enddo ! iVertexOnCell
+
+    enddo ! iCell
+
+    close(55)
+
+  end subroutine writeout_on_vertex_on_cell_real
+
+  !-------------------------------------------------------------
+
+  subroutine writeout_array(n, arr, filename)
+
+    integer, intent(in) :: n
+
+    real(kind=RKIND), dimension(n), intent(in) :: &amp;
+         arr
+
+    character(len=*), intent(in) :: &amp;
+         filename
+
+    integer :: i
+
+    open(55,file=filename)
+
+    do i = 1, n
+
+       write(55,*) i, arr(i)
+
+    enddo ! i
+
+    close(55)
+
+  end subroutine writeout_array
+
+  !-------------------------------------------------------------
+    
+  subroutine writeout_edgecell(mesh, arrayEdgeCell, filename)
+
+    type(mesh_type), intent(in) :: mesh
+
+    real(kind=RKIND), dimension(:,:), intent(in) :: &amp;
+         arrayEdgeCell
+    
+    character(len=*), intent(in) :: &amp;
+         filename
+
+    integer :: &amp;
+         iCell, &amp;
+         iEdge
+
+    open(55,file=filename)
+
+    do iCell = 1, mesh % nCells
+       
+       do iEdge = 1, mesh % nEdgesOnCell % array(iCell)
+
+          write(55,*) iCell, iEdge, arrayEdgeCell(iEdge,iCell)
+
+       enddo ! iEdge
+
+    enddo ! iCell
+
+    close(55)
+
+  end subroutine writeout_edgecell
+
+  !-------------------------------------------------------------
+
+  subroutine writeout_edgeedgecell(mesh, arrayEdgeEdgeCell, filename)
+
+    type(mesh_type), intent(in) :: mesh
+
+    real(kind=RKIND), dimension(:,:,:), intent(in) :: &amp;
+         arrayEdgeEdgeCell
+    
+    character(len=*), intent(in) :: &amp;
+         filename
+
+    integer :: &amp;
+         iCell, &amp;
+         iEdge, &amp;
+         jEdge
+
+    open(55,file=filename)
+
+    do iCell = 1, mesh % nCells
+       
+       do iEdge = 1, mesh % nEdgesOnCell % array(iCell)
+
+          do jEdge = 1, mesh % nEdgesOnCell % array(iCell) 
+
+             write(55,*) iCell, iEdge, jEdge, arrayEdgeEdgeCell(jEdge,iEdge,iCell)
+
+          enddo ! jEdge
+
+       enddo ! iEdge
+
+    enddo ! iCell
+
+    close(55)
+
+  end subroutine writeout_edgeedgecell
+
+  !-------------------------------------------------------------
+
+  function find_nearest_cell(mesh,x,y) result(iNear)
+
+    type(mesh_type), intent(in) :: mesh
+
+    real(kind=RKIND), intent(in) :: &amp;
+         x, y
+
+    integer :: iNear
+
+    real(kind=RKIND) :: &amp;
+         distance, &amp;
+         min_distance
+
+    integer :: &amp;
+         iCell
+
+    iNear = -1
+    min_distance = 1e30_RKIND
+
+    do iCell = 1, mesh % nCells
+
+       distance = sqrt((x - mesh % xCell % array(iCell))**2 + (y - mesh % yCell % array(iCell))**2)
+
+       if (distance &lt; min_distance) then
+
+          min_distance = distance
+
+          iNear = iCell
+
+       endif
+
+    enddo ! iCell    
+
+  end function find_nearest_cell
+
+  !-------------------------------------------------------------
+
+  subroutine rotate_ninety(mesh)
+
+    type(mesh_type), intent(in) :: mesh
+
+    integer :: &amp;
+         iCell, &amp;
+         iVertex, &amp;
+         iEdge
+
+    real(kind=RKIND) :: x, y
+
+    do iCell = 1, mesh % nCells
+
+       x = mesh % xCell % array(iCell)
+       y = mesh % yCell % array(iCell)
+
+       mesh % xCell % array(iCell) = y
+       mesh % yCell % array(iCell) = -x
+
+    enddo ! iCell
+
+    do iVertex = 1, mesh % nVertices
+
+       x = mesh % xVertex % array(iVertex)
+       y = mesh % yVertex % array(iVertex)
+
+       mesh % xVertex % array(iVertex) = y
+       mesh % yVertex % array(iVertex) = -x
+
+    enddo ! iVertex
+
+    do iEdge = 1, mesh % nEdges
+
+       x = mesh % xEdge % array(iEdge)
+       y = mesh % yEdge % array(iEdge)
+
+       mesh % xEdge % array(iEdge) = y
+       mesh % yEdge % array(iEdge) = -x
+
+    enddo ! iVertex
+
+  end subroutine rotate_ninety
+
+  !-------------------------------------------------------------
+  
+  subroutine reverse_grids(mesh)
+
+    type(mesh_type), intent(inout) :: mesh
+
+    real(kind=RKIND), dimension(:), allocatable :: tmp_ncells, tmp_nvertices
+    integer, dimension(:,:), allocatable :: tmp_maxedgesncells, tmp_vertexdegreenvertices
+
+
+    integer :: nCells0, nVertices0, vertexDegree0, maxEdges0
+
+    !write(*,*) lbound(mesh % xCell % array), ubound(mesh % xCell % array), size(mesh % xCell % array,1), mesh % nCells
+    !stop
+
+
+    nCells0 = mesh % nCells
+    nVertices0 = mesh % nVertices
+    vertexDegree0 = mesh % vertexDegree
+    maxEdges0 = mesh % maxEdges
+
+    allocate(tmp_ncells(1:mesh % nCells+1))
+    allocate(tmp_nvertices(1:mesh % nVertices+1))
+    allocate(tmp_maxedgesncells(1:mesh % maxEdges,1:mesh % nCells+1))
+    allocate(tmp_vertexdegreenvertices(1:mesh % vertexDegree,1:mesh % nVertices+1))
+
+    ! x position
+    tmp_ncells    = mesh % xCell % array
+    tmp_nvertices = mesh % xVertex % array
+    deallocate(mesh % xCell % array)
+    deallocate(mesh % xVertex % array)
+    allocate(mesh % xCell % array(1:nVertices0+1))
+    allocate(mesh % xVertex % array(1:nCells0+1))
+    mesh % xCell % array = tmp_nvertices
+    mesh % xVertex % array = tmp_ncells
+
+    ! x position
+    tmp_ncells    = mesh % yCell % array
+    tmp_nvertices = mesh % yVertex % array
+    deallocate(mesh % yCell % array)
+    deallocate(mesh % yVertex % array)
+    allocate(mesh % yCell % array(1:nVertices0+1))
+    allocate(mesh % yVertex % array(1:nCells0+1))
+    mesh % yCell % array = tmp_nvertices
+    mesh % yVertex % array = tmp_ncells
+
+    ! z position
+    tmp_ncells    = mesh % zCell % array
+    tmp_nvertices = mesh % zVertex % array
+    deallocate(mesh % zCell % array)
+    deallocate(mesh % zVertex % array)
+    allocate(mesh % zCell % array(1:nVertices0+1))
+    allocate(mesh % zVertex % array(1:nCells0+1))
+    mesh % zCell % array = tmp_nvertices
+    mesh % zVertex % array = tmp_ncells
+
+    ! nEdgesOnCell
+    deallocate(mesh % nEdgesOnCell % array)
+    allocate(mesh % nEdgesOnCell % array(nVertices0+1))
+    mesh % nEdgesOnCell % array = 3
+
+
+    ! verticesOnCell / cellsOnVertex
+    tmp_maxedgesncells = mesh % verticesOnCell % array
+    tmp_vertexdegreenvertices = mesh % cellsOnVertex % array
+    deallocate(mesh % verticesOnCell % array)
+    deallocate(mesh % cellsOnVertex % array)
+    allocate(mesh % verticesOnCell % array(vertexDegree0,nVertices0+1))
+    allocate(mesh % cellsOnVertex % array(maxEdges0,nCells0+1))
+    mesh % verticesOnCell % array = tmp_vertexdegreenvertices
+    mesh % cellsOnVertex % array = tmp_maxedgesncells
+
+    ! area
+    deallocate(mesh % areaCell % array)
+    allocate(mesh % areaCell % array(nVertices0+1))
+    mesh % areaCell % array = mesh % areaTriangle % array
+    
+    ! sizes
+    mesh % nCells = nVertices0
+    mesh % nVertices = nCells0
+    mesh % vertexDegree = maxEdges0
+    mesh % maxEdges = vertexDegree0
+
+    deallocate(tmp_ncells)
+    deallocate(tmp_nvertices)
+    deallocate(tmp_maxedgesncells)
+    deallocate(tmp_vertexdegreenvertices)
+
+    !stop
+  end subroutine reverse_grids
+
+  !-------------------------------------------------------------
+
+end module cice_testing
+

Added: branches/cice_projects/initial_cice_core/src/core_cice/mpas_cice_time_integration.F
===================================================================
--- branches/cice_projects/initial_cice_core/src/core_cice/mpas_cice_time_integration.F                                (rev 0)
+++ branches/cice_projects/initial_cice_core/src/core_cice/mpas_cice_time_integration.F        2013-04-19 18:44:55 UTC (rev 2780)
@@ -0,0 +1,24 @@
+module cice_time_integration
+
+  use mpas_grid_types
+
+contains
+
+  !--------------------------------------------------------------------------
+
+  subroutine cice_timestep(block, dt)
+
+    use cice_dynamics_shared, only: run_dynamics
+
+    implicit none
+
+    type(block_type), intent(inout) :: block
+    real(kind=RKIND), intent(in) :: dt
+
+    call run_dynamics(block % mesh, block % icestate, block % weak, block % boundary, dt)
+
+  end subroutine cice_timestep
+
+  !--------------------------------------------------------------------------
+
+end module cice_time_integration

Deleted: branches/cice_projects/initial_cice_core/src/core_cice/mpas_cice_timestep.F
===================================================================
--- branches/cice_projects/initial_cice_core/src/core_cice/mpas_cice_timestep.F        2013-04-19 17:49:14 UTC (rev 2779)
+++ branches/cice_projects/initial_cice_core/src/core_cice/mpas_cice_timestep.F        2013-04-19 18:44:55 UTC (rev 2780)
@@ -1,139 +0,0 @@
-module cice_timestep
-
-  use mpas_grid_types
-
-  implicit none
-
-
-contains
-
-  !-------------------------------------------------------------------------
-
-  subroutine mpas_timestep(domain, itimestep, dt, timeStamp)
-
-    type (domain_type), intent(inout) :: domain 
-    integer, intent(in) :: itimestep
-    real (kind=RKIND), intent(in) :: dt
-    character(len=*), intent(in) :: timeStamp
-
-    call step_therm1(domain, dt)
-
-
-
-  end subroutine mpas_timestep
-
-  !-------------------------------------------------------------------------
-
-  subroutine step_therm1(domain, dt)
-
-    use cice_test
-    use cice_state, only: ntrcr, nilyr, nt_qice, nt_qsno
-
-    type (domain_type), intent(inout) :: domain 
-    real (kind=RKIND), intent(in) :: dt
-    integer :: nCells, nCategories
-    integer :: iCell
-
-    type (block_type),  pointer :: block
-    type (states_type), pointer :: states
-    type (tracer_type), pointer :: tracer
-    type (flux_type),   pointer :: flux
-
-    ! original non-local variables
-    real(kind=RKIND), dimension(1,1,1) :: &amp;
-         aice     , &amp;
-         sst      , &amp;
-         Tf       , &amp;
-         strocnxT , &amp;
-         strocnyT , &amp;
-         rside    , &amp;
-         frzmlt
-
-    real(kind=RKIND), dimension(:,:,:,:), allocatable :: &amp;
-         vicen , &amp;
-         vsnon
-
-    real(kind=RKIND), dimension(:,:,:,:,:), allocatable :: &amp;
-         trcrn
-
-    ! original step_therm1 variables
-    real(kind=RKIND), dimension(1,1) :: &amp;
-         Tbot, &amp;
-         fbot
-
-    ! allocate local cice variables
-    allocate(vicen(1,1,nCategories,1))
-    allocate(vsnon(1,1,nCategories,1))
-    allocate(trcrn(1,1,ntrcr,nCategories,1))
-
-    ! loop over blocks
-    block =&gt; domain % blocklist
-    do while (associated(block))
-
-       ! loop over all cells
-       do iCell = 1, nCells
-
-          ! structure pointers
-          states =&gt; block % states
-          tracer =&gt; block % tracer
-          flux   =&gt; block % flux
-
-          ! state variable conversion
-          aice(1,1,1)    = states % iceAreaCell % array(iCell)
-          vicen(1,1,:,1) = states % iceVolumeCategory % array(iCell,:)
-          vsnon(1,1,:,1) = states % snowVolumeCategory % array(iCell,:)
-          
-          ! flux variable conversion
-          sst(1,1,1)    = flux % seaSurfaceTemperature % array(iCell)
-          Tf(1,1,1)     = flux % seaFreezingTemperature % array(iCell)
-          rside(1,1,1)  = flux % iceLateralMeltFraction % array(iCell)
-          frzmlt(1,1,1) = flux % seaFreezeMeltPotential % array(iCell)
-          
-          strocnxT(1,1,1) = 0.0_RKIND
-          strocnyT(1,1,1) = 0.0_RKIND
-          
-          ! tracer conversion
-          trcrn(1,1,nt_qice:nt_qice+nilyr-1,:,1) = &amp;
-               tracer % iceVolumeLayerTracers % array(tracer % index_iceEnthalpy,:,iCell,:)
-          trcrn(1,1,nt_qsno:nt_qsno+nilyr-1,:,1) = &amp;
-               tracer % snowVolumeLayerTracers % array(tracer % index_snowEnthalpy,:,iCell,:)
-          
-!!! BEGIN ORIGINAL CICE CALL
-          call frzmlt_bottom_lateral(1, 1,                                 &amp;
-                                     1, 1, 1, 1,                           &amp;
-                                     ntrcr,             dt,                &amp;
-                                     aice    (:,:,:),   frzmlt  (:,:,:),   &amp;
-                                     vicen   (:,:,:,1), vsnon   (:,:,:,:), &amp;
-                                     trcrn   (:,:,1:ntrcr,:,:),            &amp;
-                                     sst     (:,:,:),   Tf      (:,:,:),   &amp;
-                                     strocnxT(:,:,:),   strocnyT(:,:,:),   &amp;
-                                     Tbot,              fbot,              &amp;
-                                     rside   (:,:,:))
-!!! END ORIGINAL CICE CALL
-          
-          ! state variable back conversion
-          states % iceAreaCell % array(iCell)      = aice(1,1,1)
-          states % iceVolumeCategory % array(iCell,:)  = vicen(1,1,:,1)
-          states % snowVolumeCategory % array(iCell,:) = vsnon(1,1,:,1)
-          
-          ! tracer back conversion
-          tracer % iceVolumeLayerTracers % array(tracer % index_iceEnthalpy,:,iCell,:)   = &amp;
-               trcrn(1,1,nt_qice:nt_qice+nilyr-1,:,1)
-          tracer % snowVolumeLayerTracers % array(tracer % index_snowEnthalpy,:,iCell,:) = &amp;
-               trcrn(1,1,nt_qsno:nt_qsno+nilyr-1,:,1)
-          
-       enddo ! iCell
-       
-       block =&gt; block % next
-    end do ! blocks
-    
-    ! clean up original variables
-    deallocate(vicen)
-    deallocate(vsnon)
-    deallocate(trcrn)
-
-  end subroutine step_therm1
-
-  !-------------------------------------------------------------------------
-
-end module cice_timestep

</font>
</pre>