<p><b>duda</b> 2012-02-27 15:33:23 -0700 (Mon, 27 Feb 2012)</p><p>BRANCH COMMIT<br>
<br>
Copy updated Makefile from trunk r1536.<br>
<br>
Also, merge ocean core changes from trunk.<br>
<br>
<br>
M    Makefile<br>
M    src/core_ocean/...<br>
M    namelist.input.ocean<br>
</p><hr noshade><pre><font color="gray">Modified: branches/atmos_physics/Makefile
===================================================================
--- branches/atmos_physics/Makefile        2012-02-27 22:31:30 UTC (rev 1537)
+++ branches/atmos_physics/Makefile        2012-02-27 22:33:23 UTC (rev 1538)
@@ -14,234 +14,185 @@
 
 
 dummy:
-        @( echo &quot;try one of:&quot;; \
-        echo &quot;   make xlf&quot;; \
-        echo &quot;   make pgi&quot;; \
-        echo &quot;   make ifort&quot;; \
-        echo &quot;   make gfortran&quot;; \
-        )
+        ( make error )
 
-xlf-serial:
+xlf:
         ( make all \
-        &quot;FC = xlf90&quot; \
-        &quot;CC = xlc&quot; \
-        &quot;SFC = xlf90&quot; \
-        &quot;SCC = xlc&quot; \
-        &quot;FFLAGS = -qrealsize=8 -g -C &quot; \
-        &quot;CFLAGS = -g&quot; \
-        &quot;LDFLAGS = -g -C&quot; \
+        &quot;FC_PARALLEL = mpxlf90&quot; \
+        &quot;CC_PARALLEL = mpcc&quot; \
+        &quot;FC_SERIAL = xlf90&quot; \
+        &quot;CC_SERIAL = xlc&quot; \
+        &quot;FFLAGS_OPT = -O3 -qrealsize=8&quot; \
+        &quot;CFLAGS_OPT = -O3&quot; \
+        &quot;LDFLAGS_OPT = -O3&quot; \
         &quot;CORE = $(CORE)&quot; \
+        &quot;DEBUG = $(DEBUG)&quot; \
+        &quot;SERIAL = $(SERIAL)&quot; \
+        &quot;USE_PAPI = $(USE_PAPI)&quot; \
         &quot;CPPFLAGS = $(MODEL_FORMULATION) $(FILE_OFFSET) $(ZOLTAN_DEFINE)&quot; )
-
-xlf:
-        ( make all \
-        &quot;FC = mpxlf90&quot; \
-        &quot;CC = mpcc&quot; \
-        &quot;SFC = xlf90&quot; \
-        &quot;SCC = xlc&quot; \
-        &quot;FFLAGS = -O3 -qrealsize=8&quot; \
-        &quot;CFLAGS = -O3&quot; \
-        &quot;LDFLAGS = -O3&quot; \
-        &quot;CORE = $(CORE)&quot; \
-        &quot;CPPFLAGS = $(MODEL_FORMULATION) -D_MPI $(FILE_OFFSET) $(ZOLTAN_DEFINE)&quot; )
  
 ftn:
         ( make all \
-        &quot;FC = ftn&quot; \
-        &quot;CC = cc&quot; \
-        &quot;SFC = ftn&quot; \
-        &quot;SCC = cc&quot; \
-        &quot;FFLAGS = -i4 -r8 -gopt -O2 -Mvect=nosse -Kieee -convert big_endian&quot; \
-        &quot;CFLAGS = -fast&quot; \
-        &quot;LDFLAGS = &quot; \
+        &quot;FC_PARALLEL = ftn&quot; \
+        &quot;CC_PARALLEL = cc&quot; \
+        &quot;FC_SERIAL = ftn&quot; \
+        &quot;CC_SERIAL = cc&quot; \
+        &quot;FFLAGS_OPT = -i4 -r8 -gopt -O2 -Mvect=nosse -Kieee -convert big_endian&quot; \
+        &quot;CFLAGS_OPT = -fast&quot; \
+        &quot;LDFLAGS_OPT = &quot; \
         &quot;CORE = $(CORE)&quot; \
-        &quot;CPPFLAGS = $(MODEL_FORMULATION) -D_MPI -DUNDERSCORE $(FILE_OFFSET) $(ZOLTAN_DEFINE)&quot; )
+        &quot;DEBUG = $(DEBUG)&quot; \
+        &quot;SERIAL = $(SERIAL)&quot; \
+        &quot;USE_PAPI = $(USE_PAPI)&quot; \
+        &quot;CPPFLAGS = $(MODEL_FORMULATION) -DUNDERSCORE $(FILE_OFFSET) $(ZOLTAN_DEFINE)&quot; )
 
 pgi:
         ( make all \
-        &quot;FC = mpif90&quot; \
-        &quot;CC = mpicc&quot; \
-        &quot;SFC = pgf90&quot; \
-        &quot;SCC = pgcc&quot; \
-        &quot;FFLAGS = -r8 -O3 -byteswapio -Mfree&quot; \
-        &quot;CFLAGS = -O3&quot; \
-        &quot;LDFLAGS = -O3&quot; \
+        &quot;FC_PARALLEL = mpif90&quot; \
+        &quot;CC_PARALLEL = mpicc&quot; \
+        &quot;FC_SERIAL = pgf90&quot; \
+        &quot;CC_SERIAL = pgcc&quot; \
+        &quot;FFLAGS_OPT = -r8 -O3 -byteswapio -Mfree&quot; \
+        &quot;CFLAGS_OPT = -O3&quot; \
+        &quot;LDFLAGS_OPT = -O3&quot; \
+        &quot;FFLAGS_DEBUG = -r8 -O0 -g -Mbounds -Mchkptr -byteswapio -Mfree&quot; \
+        &quot;CFLAGS_DEBUG = -O0 -g&quot; \
+        &quot;LDFLAGS_DEBUG = -O0 -g -Mbounds -Mchkptr&quot; \
         &quot;CORE = $(CORE)&quot; \
-        &quot;CPPFLAGS = $(MODEL_FORMULATION) -D_MPI -DUNDERSCORE $(FILE_OFFSET) $(ZOLTAN_DEFINE)&quot; )
+        &quot;DEBUG = $(DEBUG)&quot; \
+        &quot;SERIAL = $(SERIAL)&quot; \
+        &quot;USE_PAPI = $(USE_PAPI)&quot; \
+        &quot;CPPFLAGS = $(MODEL_FORMULATION) -DUNDERSCORE $(FILE_OFFSET) $(ZOLTAN_DEFINE)&quot; )
 
 pgi-nersc:
         ( make all \
-        &quot;FC = ftn&quot; \
-        &quot;CC = cc&quot; \
-        &quot;SFC = ftn&quot; \
-        &quot;SCC = cc&quot; \
-        &quot;FFLAGS = -r8 -O3 -byteswapio -Mfree&quot; \
-        &quot;CFLAGS = -O3&quot; \
-        &quot;LDFLAGS = -O3&quot; \
+        &quot;FC_PARALLEL = ftn&quot; \
+        &quot;CC_PARALLEL = cc&quot; \
+        &quot;FC_SERIAL = ftn&quot; \
+        &quot;CC_SERIAL = cc&quot; \
+        &quot;FFLAGS_OPT = -r8 -O3 -byteswapio -Mfree&quot; \
+        &quot;CFLAGS_OPT = -O3&quot; \
+        &quot;LDFLAGS_OPT = -O3&quot; \
         &quot;CORE = $(CORE)&quot; \
-        &quot;CPPFLAGS = $(MODEL_FORMULATION) -D_MPI -DUNDERSCORE $(FILE_OFFSET) $(ZOLTAN_DEFINE)&quot; )
+        &quot;DEBUG = $(DEBUG)&quot; \
+        &quot;SERIAL = $(SERIAL)&quot; \
+        &quot;USE_PAPI = $(USE_PAPI)&quot; \
+        &quot;CPPFLAGS = $(MODEL_FORMULATION) -DUNDERSCORE $(FILE_OFFSET) $(ZOLTAN_DEFINE)&quot; )
 
 pgi-llnl:
         ( make all \
-        &quot;FC = mpipgf90&quot; \
-        &quot;CC = pgcc&quot; \
-        &quot;SFC = pgf90&quot; \
-        &quot;SCC = pgcc&quot; \
-        &quot;FFLAGS = -i4 -r8 -g -O2 -byteswapio&quot; \
-        &quot;CFLAGS = -fast&quot; \
-        &quot;LDFLAGS = &quot; \
+        &quot;FC_PARALLEL = mpipgf90&quot; \
+        &quot;CC_PARALLEL = pgcc&quot; \
+        &quot;FC_SERIAL = pgf90&quot; \
+        &quot;CC_SERIAL = pgcc&quot; \
+        &quot;FFLAGS_OPT = -i4 -r8 -g -O2 -byteswapio&quot; \
+        &quot;CFLAGS_OPT = -fast&quot; \
+        &quot;LDFLAGS_OPT = &quot; \
         &quot;CORE = $(CORE)&quot; \
-        &quot;CPPFLAGS = $(MODEL_FORMULATION) -D_MPI -DUNDERSCORE $(FILE_OFFSET) $(ZOLTAN_DEFINE)&quot; )
-
-pgi-serial:
-        ( make all \
-        &quot;FC = pgf90&quot; \
-        &quot;CC = pgcc&quot; \
-        &quot;SFC = pgf90&quot; \
-        &quot;SCC = pgcc&quot; \
-        &quot;FFLAGS = -r8 -O0 -g -Mbounds -Mchkptr -byteswapio -Mfree&quot; \
-        &quot;CFLAGS = -O0 -g&quot; \
-        &quot;LDFLAGS = -O0 -g -Mbounds -Mchkptr&quot; \
-        &quot;CORE = $(CORE)&quot; \
+        &quot;DEBUG = $(DEBUG)&quot; \
+        &quot;SERIAL = $(SERIAL)&quot; \
+        &quot;USE_PAPI = $(USE_PAPI)&quot; \
         &quot;CPPFLAGS = $(MODEL_FORMULATION) -DUNDERSCORE $(FILE_OFFSET) $(ZOLTAN_DEFINE)&quot; )
 
-ifort-serial:
+ifort:
         ( make all \
-        &quot;FC = ifort&quot; \
-        &quot;CC = gcc&quot; \
-        &quot;SFC = ifort&quot; \
-        &quot;SCC = gcc&quot; \
-        &quot;FFLAGS = -real-size 64 -O3 -convert big_endian -FR&quot; \
-        &quot;CFLAGS = -O3 -m64&quot; \
-        &quot;LDFLAGS = -O3&quot; \
+        &quot;FC_PARALLEL = mpif90&quot; \
+        &quot;CC_PARALLEL = gcc&quot; \
+        &quot;FC_SERIAL = ifort&quot; \
+        &quot;CC_SERIAL = gcc&quot; \
+        &quot;FFLAGS_OPT = -real-size 64 -O3 -convert big_endian -FR&quot; \
+        &quot;CFLAGS_OPT = -O3 -m64&quot; \
+        &quot;LDFLAGS_OPT = -O3&quot; \
+        &quot;FFLAGS_DEBUG = -real-size 64 -g -convert big_endian -FR -CU -CB -check all&quot; \
+        &quot;CFLAGS_DEBUG = -g -m64&quot; \
+        &quot;LDFLAGS_DEBUG = -g&quot; \
         &quot;CORE = $(CORE)&quot; \
+        &quot;DEBUG = $(DEBUG)&quot; \
+        &quot;SERIAL = $(SERIAL)&quot; \
+        &quot;USE_PAPI = $(USE_PAPI)&quot; \
         &quot;CPPFLAGS = $(MODEL_FORMULATION) -DUNDERSCORE -m64 $(FILE_OFFSET) $(ZOLTAN_DEFINE)&quot; )
 
-ifort-papi:
-        ( make all \
-        &quot;FC = mpif90&quot; \
-        &quot;CC = gcc&quot; \
-        &quot;SFC = ifort&quot; \
-        &quot;SCC = gcc&quot; \
-        &quot;FFLAGS = -real-size 64 -O3 -convert big_endian -FR&quot; \
-        &quot;CFLAGS = -O3 -m64&quot; \
-        &quot;LDFLAGS = -O3&quot; \
-        &quot;CORE = $(CORE)&quot; \
-        &quot;CPPFLAGS = $(MODEL_FORMULATION) -D_PAPI -D_MPI -DUNDERSCORE -m64 $(FILE_OFFSET) $(ZOLTAN_DEFINE)&quot; \
-        &quot;PAPILIBS = -L$(PAPI)/lib -lpapi&quot; )
-
-ifort-papi-serial:
-        ( make all \
-        &quot;FC = ifort&quot; \
-        &quot;CC = gcc&quot; \
-        &quot;SFC = ifort&quot; \
-        &quot;SCC = gcc&quot; \
-        &quot;FFLAGS = -real-size 64 -O3 -convert big_endian -FR&quot; \
-        &quot;CFLAGS = -O3 -m64&quot; \
-        &quot;LDFLAGS = -O3&quot; \
-        &quot;CORE = $(CORE)&quot; \
-        &quot;CPPFLAGS = $(MODEL_FORMULATION) -D_PAPI -DUNDERSCORE -m64 $(FILE_OFFSET) $(ZOLTAN_DEFINE)&quot; \
-        &quot;PAPILIBS = -L$(PAPI)/lib -lpapi&quot; )
-
-ifort:
-        ( make all \
-        &quot;FC = mpif90&quot; \
-        &quot;CC = gcc&quot; \
-        &quot;SFC = ifort&quot; \
-        &quot;SCC = gcc&quot; \
-        &quot;FFLAGS = -real-size 64 -O3 -convert big_endian -FR&quot; \
-        &quot;CFLAGS = -O3 -m64&quot; \
-        &quot;LDFLAGS = -O3&quot; \
-        &quot;CORE = $(CORE)&quot; \
-        &quot;CPPFLAGS = $(MODEL_FORMULATION) -D_MPI -DUNDERSCORE -m64 $(FILE_OFFSET) $(ZOLTAN_DEFINE)&quot; )
-
 gfortran:
         ( make all \
-        &quot;FC = mpif90&quot; \
-        &quot;CC = mpicc&quot; \
-        &quot;SFC = gfortran&quot; \
-        &quot;SCC = gcc&quot; \
-        &quot;FFLAGS = -O3 -m64 -ffree-line-length-none -fdefault-real-8 -fconvert=big-endian -ffree-form&quot; \
-        &quot;CFLAGS = -O3 -m64&quot; \
-        &quot;LDFLAGS = -O3 -m64&quot; \
+        &quot;FC_PARALLEL = mpif90&quot; \
+        &quot;CC_PARALLEL = mpicc&quot; \
+        &quot;FC_SERIAL = gfortran&quot; \
+        &quot;CC_SERIAL = gcc&quot; \
+        &quot;FFLAGS_OPT = -O3 -m64 -ffree-line-length-none -fdefault-real-8 -fconvert=big-endian -ffree-form&quot; \
+        &quot;CFLAGS_OPT = -O3 -m64&quot; \
+        &quot;LDFLAGS_OPT = -O3 -m64&quot; \
+        &quot;FFLAGS_DEBUG = -g -m64 -ffree-line-length-none -fdefault-real-8 -fconvert=big-endian -ffree-form -fbounds-check&quot; \
+        &quot;CFLAGS_DEBUG = -g -m64&quot; \
+        &quot;LDFLAGS_DEBUG = -g -m64&quot; \
         &quot;CORE = $(CORE)&quot; \
-        &quot;CPPFLAGS = $(MODEL_FORMULATION) -D_MPI -DUNDERSCORE -m64 $(FILE_OFFSET) $(ZOLTAN_DEFINE)&quot; )
-
-gfortran-serial:
-        ( make all \
-        &quot;FC = gfortran&quot; \
-        &quot;CC = gcc&quot; \
-        &quot;SFC = gfortran&quot; \
-        &quot;SCC = gcc&quot; \
-        &quot;FFLAGS = -O3 -m64 -ffree-line-length-none -fdefault-real-8 -fconvert=big-endian -ffree-form&quot; \
-        &quot;CFLAGS = -O3 -m64&quot; \
-        &quot;LDFLAGS = -O3 -m64&quot; \
-        &quot;CORE = $(CORE)&quot; \
+        &quot;DEBUG = $(DEBUG)&quot; \
+        &quot;SERIAL = $(SERIAL)&quot; \
+        &quot;USE_PAPI = $(USE_PAPI)&quot; \
         &quot;CPPFLAGS = $(MODEL_FORMULATION) -DUNDERSCORE -m64 $(FILE_OFFSET) $(ZOLTAN_DEFINE)&quot; )
 
 g95:
         ( make all \
-        &quot;FC = mpif90&quot; \
-        &quot;CC = mpicc&quot; \
-        &quot;SFC = g95&quot; \
-        &quot;SCC = gcc&quot; \
-        &quot;FFLAGS = -O3 -ffree-line-length-huge -r8 -fendian=big -ffree-form&quot; \
-        &quot;CFLAGS = -O3 -m32&quot; \
-        &quot;LDFLAGS = -O3&quot; \
+        &quot;FC_PARALLEL = mpif90&quot; \
+        &quot;CC_PARALLEL = mpicc&quot; \
+        &quot;FC_SERIAL = g95&quot; \
+        &quot;CC_SERIAL = gcc&quot; \
+        &quot;FFLAGS_OPT = -O3 -ffree-line-length-huge -r8 -fendian=big&quot; \
+        &quot;CFLAGS_OPT = -O3&quot; \
+        &quot;LDFLAGS_OPT = -O3&quot; \
         &quot;CORE = $(CORE)&quot; \
-        &quot;CPPFLAGS = $(MODEL_FORMULATION) -D_MPI -DDOUBLEUNDERSCORE $(FILE_OFFSET) $(ZOLTAN_DEFINE)&quot; )
+        &quot;DEBUG = $(DEBUG)&quot; \
+        &quot;SERIAL = $(SERIAL)&quot; \
+        &quot;USE_PAPI = $(USE_PAPI)&quot; \
+        &quot;CPPFLAGS = $(MODEL_FORMULATION) -DUNDERSCORE $(FILE_OFFSET) $(ZOLTAN_DEFINE)&quot; )
 
-g95-serial:
-        ( make all \
-        &quot;FC = g95&quot; \
-        &quot;CC = gcc&quot; \
-        &quot;SFC = g95&quot; \
-        &quot;SCC = gcc&quot; \
-        &quot;FFLAGS = -O3 -ffree-line-length-huge -r8 -fendian=big -ffree-form&quot; \
-        &quot;CFLAGS = -O3 -m32&quot; \
-        &quot;LDFLAGS = -O3&quot; \
-        &quot;CORE = $(CORE)&quot; \
-        &quot;CPPFLAGS = $(MODEL_FORMULATION) -DDOUBLEUNDERSCORE $(FILE_OFFSET) $(ZOLTAN_DEFINE)&quot; )
-
 pathscale-nersc:
         ( make all \
-        &quot;FC = ftn&quot; \
-        &quot;CC = cc&quot; \
-        &quot;SFC = ftn&quot; \
-        &quot;SCC = cc&quot; \
-        &quot;FFLAGS = -r8 -O3 -freeform -extend-source&quot; \
-        &quot;CFLAGS = -O3&quot; \
-        &quot;LDFLAGS = -O3&quot; \
+        &quot;FC_PARALLEL = ftn&quot; \
+        &quot;CC_PARALLEL = cc&quot; \
+        &quot;FC_SERIAL = ftn&quot; \
+        &quot;CC_SERIAL = cc&quot; \
+        &quot;FFLAGS_OPT = -r8 -O3 -freeform -extend-source&quot; \
+        &quot;CFLAGS_OPT = -O3&quot; \
+        &quot;LDFLAGS_OPT = -O3&quot; \
         &quot;CORE = $(CORE)&quot; \
-        &quot;CPPFLAGS = $(MODEL_FORMULATION) -D_MPI -DUNDERSCORE $(FILE_OFFSET) $(ZOLTAN_DEFINE)&quot; )
+        &quot;DEBUG = $(DEBUG)&quot; \
+        &quot;SERIAL = $(SERIAL)&quot; \
+        &quot;USE_PAPI = $(USE_PAPI)&quot; \
+        &quot;CPPFLAGS = $(MODEL_FORMULATION) -DUNDERSCORE $(FILE_OFFSET) $(ZOLTAN_DEFINE)&quot; )
 
 cray-nersc:
         ( make all \
-        &quot;FC = ftn&quot; \
-        &quot;CC = cc&quot; \
-        &quot;SFC = ftn&quot; \
-        &quot;SCC = cc&quot; \
-        &quot;FFLAGS = -default64 -O3 -f free&quot; \
-        &quot;CFLAGS = -O3&quot; \
-        &quot;LDFLAGS = -O3&quot; \
+        &quot;FC_PARALLEL = ftn&quot; \
+        &quot;CC_PARALLEL = cc&quot; \
+        &quot;FC_SERIAL = ftn&quot; \
+        &quot;CC_SERIAL = cc&quot; \
+        &quot;FFLAGS_OPT = -default64 -O3 -f free&quot; \
+        &quot;CFLAGS_OPT = -O3&quot; \
+        &quot;LDFLAGS_OPT = -O3&quot; \
         &quot;CORE = $(CORE)&quot; \
-        &quot;CPPFLAGS = $(MODEL_FORMULATION) -D_MPI -DUNDERSCORE $(FILE_OFFSET) $(ZOLTAN_DEFINE)&quot; )
+        &quot;DEBUG = $(DEBUG)&quot; \
+        &quot;SERIAL = $(SERIAL)&quot; \
+        &quot;USE_PAPI = $(USE_PAPI)&quot; \
+        &quot;CPPFLAGS = $(MODEL_FORMULATION) -DUNDERSCORE $(FILE_OFFSET) $(ZOLTAN_DEFINE)&quot; )
 
 intel-nersc:
         ( make all \
-        &quot;FC = ftn&quot; \
-        &quot;CC = cc&quot; \
-        &quot;SFC = ftn&quot; \
-        &quot;SCC = cc&quot; \
-        &quot;FFLAGS = -real-size 64 -O3 -FR&quot; \
-        &quot;CFLAGS = -O3&quot; \
-        &quot;LDFLAGS = -O3&quot; \
+        &quot;FC_PARALLEL = ftn&quot; \
+        &quot;CC_PARALLEL = cc&quot; \
+        &quot;FC_SERIAL = ftn&quot; \
+        &quot;CC_SERIAL = cc&quot; \
+        &quot;FFLAGS_OPT = -real-size 64 -O3 -FR&quot; \
+        &quot;CFLAGS_OPT = -O3&quot; \
+        &quot;LDFLAGS_OPT = -O3&quot; \
         &quot;CORE = $(CORE)&quot; \
-        &quot;CPPFLAGS = $(MODEL_FORMULATION) -D_MPI -DUNDERSCORE $(FILE_OFFSET) $(ZOLTAN_DEFINE)&quot; )
+        &quot;DEBUG = $(DEBUG)&quot; \
+        &quot;SERIAL = $(SERIAL)&quot; \
+        &quot;USE_PAPI = $(USE_PAPI)&quot; \
+        &quot;CPPFLAGS = $(MODEL_FORMULATION) -DUNDERSCORE $(FILE_OFFSET) $(ZOLTAN_DEFINE)&quot; )
 
-CPPINCLUDES = -I../inc -I$(NETCDF)/include -I$(PAPI)/include
-FCINCLUDES = -I../inc -I$(NETCDF)/include -I$(PAPI)/include
-LIBS = -L$(NETCDF)/lib -lnetcdf $(PAPILIBS)
+CPPINCLUDES = -I../inc -I$(NETCDF)/include
+FCINCLUDES = -I../inc -I$(NETCDF)/include
+LIBS = -L$(NETCDF)/lib -lnetcdf
 
 RM = rm -f
 CPP = cpp -C -P -traditional
@@ -268,34 +219,109 @@
 
 ifdef CORE
 
+ifeq &quot;$(DEBUG)&quot; &quot;true&quot;
+
+ifndef FFLAGS_DEBUG
+        FFLAGS=$(FFLAGS_OPT)
+        CFLAGS=$(CFLAGS_OPT)
+        LDFLAGS=$(LDFLAGS_OPT)
+        DEBUG_MESSAGE=&quot;Debug flags are not defined for this compile group. Defaulting to Optimized flags&quot;
+else # FFLAGS_DEBUG IF
+        FFLAGS=$(FFLAGS_DEBUG)
+        CFLAGS=$(CFLAGS_DEBUG)
+        LDFLAGS=$(LDFLAGS_DEBUG)
+        DEBUG_MESSAGE=&quot;Debugging is on.&quot;
+endif # FFLAGS_DEBUG IF
+
+else # DEBUG IF
+        FFLAGS=$(FFLAGS_OPT)
+        CFLAGS=$(CFLAGS_OPT)
+        LDFLAGS=$(LDFLAGS_OPT)
+        DEBUG_MESSAGE=&quot;Debugging is off.&quot;
+endif # DEBUG IF
+
+ifeq &quot;$(SERIAL)&quot; &quot;true&quot;
+        FC=$(FC_SERIAL)
+        CC=$(CC_SERIAL)
+        SFC=$(FC_SERIAL)
+        SCC=$(CC_SERIAL)
+        SERIAL_MESSAGE=&quot;Serial version is on.&quot;
+else # SERIAL IF
+        FC=$(FC_PARALLEL)
+        CC=$(CC_PARALLEL)
+        SFC=$(FC_SERIAL)
+        SCC=$(CC_SERIAL)
+        CPPFLAGS += -D_MPI
+        SERIAL_MESSAGE=&quot;Parallel version is on.&quot;
+endif # SERIAL IF
+
+ifeq &quot;$(USE_PAPI)&quot; &quot;true&quot;
+        CPPINCLUDES += -I$(PAPI)/include -D_PAPI
+        FCINCLUDES += -I$(PAPI)/include
+        LIBS += -L$(PAPI)/lib -lpapi
+        PAPI_MESSAGE=&quot;Papi libraries are on.&quot;
+else # USE_PAPI IF
+        PAPI_MESSAGE=&quot;Papi libraries are off.&quot;
+endif # USE_PAPI IF
+
 all: mpas_main
 
 mpas_main: 
         cd src; make FC=&quot;$(FC)&quot; \
-                     CC=&quot;$(CC)&quot; \
-                     CFLAGS=&quot;$(CFLAGS)&quot; \
-                     FFLAGS=&quot;$(FFLAGS)&quot; \
-                     LDFLAGS=&quot;$(LDFLAGS)&quot; \
-                     RM=&quot;$(RM)&quot; \
-                     CPP=&quot;$(CPP)&quot; \
-                     CPPFLAGS=&quot;$(CPPFLAGS)&quot; \
-                     LIBS=&quot;$(LIBS)&quot; \
-                     CPPINCLUDES=&quot;$(CPPINCLUDES)&quot; \
-                     FCINCLUDES=&quot;$(FCINCLUDES)&quot; \
-                     CORE=&quot;$(CORE)&quot;
+                 CC=&quot;$(CC)&quot; \
+                 SFC=&quot;$(SFC)&quot; \
+                 SCC=&quot;$(SCC)&quot; \
+                 CFLAGS=&quot;$(CFLAGS)&quot; \
+                 FFLAGS=&quot;$(FFLAGS)&quot; \
+                 LDFLAGS=&quot;$(LDFLAGS)&quot; \
+                 RM=&quot;$(RM)&quot; \
+                 CPP=&quot;$(CPP)&quot; \
+                 CPPFLAGS=&quot;$(CPPFLAGS)&quot; \
+                 LIBS=&quot;$(LIBS)&quot; \
+                 CPPINCLUDES=&quot;$(CPPINCLUDES)&quot; \
+                 FCINCLUDES=&quot;$(FCINCLUDES)&quot; \
+                 CORE=&quot;$(CORE)&quot;
         if [ ! -e $(CORE)_model.exe ]; then ln -s src/$(CORE)_model.exe .; fi
-
+        @echo &quot;&quot;
+        @echo $(DEBUG_MESSAGE)
+        @echo $(SERIAL_MESSAGE)
+        @echo $(PAPI_MESSAGE)
 clean:
         cd src; make clean RM=&quot;$(RM)&quot; CORE=&quot;$(CORE)&quot;
         $(RM) $(CORE)_model.exe
+error: errmsg
 
-else
+else # CORE IF
 
-all: errmsg
+all: error
 clean: errmsg
-errmsg:
+error: errmsg
         @echo &quot;************ ERROR ************&quot;
         @echo &quot;No CORE specified. Quitting.&quot;
         @echo &quot;************ ERROR ************&quot;
+        @echo &quot;&quot;
 
-endif
+endif # CORE IF
+
+errmsg:
+        @echo &quot;&quot;
+        @echo &quot;Usage: make target CORE=[core] [options]&quot;
+        @echo &quot;&quot;
+        @echo &quot;Example targets:&quot;
+        @echo &quot;    ifort&quot;
+        @echo &quot;    gfortran&quot;
+        @echo &quot;    xlf&quot;
+        @echo &quot;    pgi&quot;
+        @echo &quot;&quot;
+        @echo &quot;Availabe Cores:&quot;
+        @cd src; ls -d core_* | grep &quot;.*&quot; | sed &quot;s/core_/    /g&quot;
+        @echo &quot;&quot;
+        @echo &quot;Available Options:&quot;
+        @echo &quot;    SERIAL=true - builds serial version. Default is parallel version.&quot;
+        @echo &quot;    DEBUG=true  - builds debug version. Default is optimized version.&quot;
+        @echo &quot;    USE_PAPI=true   - builds version using PAPI for timers and hardware counters. Default is off.&quot;
+        @echo &quot;&quot;
+        @echo &quot;Ensure that NETCDF (and PAPI if USE_PAPI=true) are environment variables&quot;
+        @echo &quot;that point to the absolute paths for the libraries.&quot;
+        @echo &quot;&quot;
+

Modified: branches/atmos_physics/namelist.input.ocean
===================================================================
--- branches/atmos_physics/namelist.input.ocean        2012-02-27 22:31:30 UTC (rev 1537)
+++ branches/atmos_physics/namelist.input.ocean        2012-02-27 22:33:23 UTC (rev 1538)
@@ -1,8 +1,8 @@
 &amp;sw_model
    config_test_case = 0
-   config_time_integration = 'split_explicit'
+   config_time_integration = 'RK4'
    config_rk_filter_btr_mode = .false.
-   config_dt = 10.0
+   config_dt = 100.0
    config_start_time = '0000-01-01_00:00:00'
    config_run_duration = '2000_00:00:00'
    config_stats_interval = 1920
@@ -20,6 +20,7 @@
 /
 &amp;grid
    config_vert_grid_type = 'zlevel'
+   config_pressure_type = 'pressure'
    config_rho0 = 1000
 /
 &amp;split_explicit_ts
@@ -31,12 +32,7 @@
    config_n_btr_cor_iter = 2
    config_u_correction = .true.
    config_filter_btr_mode = .false.
-   config_btr_mom_decay  = .false.
-   config_btr_mom_decay_time =   3600.0
-   config_btr_mom_eddy_visc2 =   0.0
    config_btr_subcycle_loop_factor =  2
-   config_SSH_from =  'avg_flux'
-   config_new_btr_variables_from = 'btr_avg'
    config_btr_gam1_uWt1   = 0.5
    config_btr_gam2_SSHWt1 = 1.0
    config_btr_gam3_uWt2   = 1.0
@@ -46,7 +42,7 @@
    config_h_mom_eddy_visc2 = 1.0e5
    config_h_mom_eddy_visc4 = 0.0
    config_visc_vorticity_term = .true.
-   config_h_tracer_eddy_diff2 = 1.0e4
+   config_h_tracer_eddy_diff2 = 1.0e5
    config_h_tracer_eddy_diff4 = 0.0
 /
 &amp;vmix
@@ -58,11 +54,11 @@
    config_bottom_drag_coeff     = 1.0e-3
 /
 &amp;vmix_const
-   config_vert_visc       = 2.5e-5
-   config_vert_diff       = 2.5e-5 
+   config_vert_visc       = 1.0e-5
+   config_vert_diff       = 1.0e-5 
 /
 &amp;vmix_rich
-   config_bkrd_vert_visc  = 1.0e-4
+   config_bkrd_vert_visc  = 1.0e-5
    config_bkrd_vert_diff  = 1.0e-5
    config_rich_mix        = 0.005
 /

Modified: branches/atmos_physics/src/core_ocean/Registry
===================================================================
--- branches/atmos_physics/src/core_ocean/Registry        2012-02-27 22:31:30 UTC (rev 1537)
+++ branches/atmos_physics/src/core_ocean/Registry        2012-02-27 22:33:23 UTC (rev 1538)
@@ -10,6 +10,7 @@
 namelist character sw_model config_stop_time           none
 namelist character sw_model config_run_duration        none
 namelist integer   sw_model config_stats_interval      100
+namelist logical   sw_model config_initial_stats       false
 namelist character io       config_input_name          grid.nc
 namelist character io       config_output_name         output.nc
 namelist character io       config_restart_name        restart.nc
@@ -19,21 +20,17 @@
 namelist logical   restart  config_do_restart          false
 namelist character restart  config_restart_interval    none
 namelist character grid     config_vert_grid_type      isopycnal
+namelist character grid     config_pressure_type       pressure
 namelist real      grid     config_rho0                1028
 namelist integer   split_explicit_ts config_n_ts_iter     2
-namelist integer   split_explicit_ts config_n_bcl_iter_beg   4
-namelist integer   split_explicit_ts config_n_bcl_iter_mid   4
-namelist integer   split_explicit_ts config_n_bcl_iter_end   4
-namelist integer   split_explicit_ts config_n_btr_subcycles  10
-namelist integer   split_explicit_ts config_n_btr_cor_iter  1
+namelist integer   split_explicit_ts config_n_bcl_iter_beg   2
+namelist integer   split_explicit_ts config_n_bcl_iter_mid   2
+namelist integer   split_explicit_ts config_n_bcl_iter_end   2
+namelist integer   split_explicit_ts config_n_btr_subcycles  20
+namelist integer   split_explicit_ts config_n_btr_cor_iter  2
 namelist logical   split_explicit_ts config_u_correction true
 namelist logical   split_explicit_ts config_filter_btr_mode false
-namelist logical   split_explicit_ts config_btr_mom_decay         false 
-namelist real      split_explicit_ts config_btr_mom_decay_time    3600.0
-namelist real      split_explicit_ts config_btr_mom_eddy_visc2    0.0
 namelist integer   split_explicit_ts config_btr_subcycle_loop_factor  2
-namelist character split_explicit_ts config_SSH_from  avg_flux
-namelist character split_explicit_ts config_new_btr_variables_from  btr_avg
 namelist real      split_explicit_ts config_btr_gam1_uWt1    0.5
 namelist real      split_explicit_ts config_btr_gam2_SSHWt1  1.0
 namelist real      split_explicit_ts config_btr_gam3_uWt2    1.0
@@ -171,24 +168,24 @@
 var persistent integer maxLevelEdgeBot ( nEdges ) 0 - maxLevelEdgeBot mesh - -
 var persistent integer maxLevelVertexTop ( nVertices ) 0 - maxLevelVertexTop mesh - -
 var persistent integer maxLevelVertexBot ( nVertices ) 0 - maxLevelVertexBot mesh - -
+var persistent real referenceBottomDepth ( nVertLevels ) 0 iro referenceBottomDepth mesh - -
+var persistent real referenceBottomDepthTopOfCell ( nVertLevelsP1 ) 0 - referenceBottomDepthTopOfCell mesh - -
 var persistent real hZLevel ( nVertLevels ) 0 iro hZLevel mesh - -
-var persistent real zMidZLevel ( nVertLevels ) 0 - zMidZLevel mesh - -
-var persistent real zTopZLevel ( nVertLevelsP1 ) 0 - zTopZLevel mesh - -
-var persistent real hMeanTopZLevel ( nVertLevels ) 0 - hMeanTopZLevel mesh - -
-var persistent real hRatioZLevelK ( nVertLevels ) 0 - hRatioZLevelK mesh - -
-var persistent real hRatioZLevelKm1 ( nVertLevels ) 0 - hRatioZLevelKm1 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 integer edgeMask ( nVertLevels nEdges ) 0 o edgeMask mesh - -
+var persistent integer vertexMask ( nVertLevels nVertices ) 0 o vertexMask mesh - -
+var persistent integer cellMask ( nVertLevels nCells ) 0 o cellMask mesh - -
 var persistent real    u_src ( nVertLevels nEdges ) 0 ir u_src mesh - -
 var persistent real    temperatureRestore ( nCells ) 0 ir temperatureRestore mesh - -
 var persistent real    salinityRestore ( nCells ) 0 ir salinityRestore mesh - -
 
 % Prognostic variables: read from input, saved in restart, and written to output
 var persistent real    u ( nVertLevels nEdges Time ) 2 ir u state - -
-var persistent real    h ( nVertLevels nCells Time ) 2 ir h state - -
+var persistent real    h ( nVertLevels nCells Time ) 2 iro h state - -
 var persistent real    rho ( nVertLevels nCells Time ) 2 iro rho state - -
 var persistent real    temperature ( nVertLevels nCells Time ) 2 iro temperature state tracers dynamics
 var persistent real    salinity ( nVertLevels nCells Time ) 2 iro salinity state tracers dynamics
@@ -210,12 +207,9 @@
 var persistent real   FBtr ( nEdges Time )         2 -  FBtr state - - 
 var persistent real   GBtrForcing ( nEdges Time )  2 -  GBtrForcing state - -
 var persistent real   uBcl ( nVertLevels nEdges Time )  2 - uBcl state - - 
-var persistent real   circulationBtr ( nVertices Time ) 2 - circulationBtr state - -
-var persistent real   divergenceBtr ( nCells Time ) 2 - divergenceBtr state - -
-var persistent real   vorticityBtr ( nVertices Time ) 2 - vorticityBtr state - -
-var persistent real   u_diffusionBtr ( nEdges Time ) 2 - u_diffusionBtr state - -
 
 % Diagnostic fields: only written to output
+var persistent real    zMid ( nVertLevels nCells Time ) 2 io zMid state - -
 var persistent real    v ( nVertLevels nEdges Time ) 2 - v state - -
 var persistent real    divergence ( nVertLevels nCells Time ) 2 o divergence state - -
 var persistent real    vorticity ( nVertLevels nVertices Time ) 2 o vorticity state - -

Modified: branches/atmos_physics/src/core_ocean/mpas_ocn_advection.F
===================================================================
--- branches/atmos_physics/src/core_ocean/mpas_ocn_advection.F        2012-02-27 22:31:30 UTC (rev 1537)
+++ branches/atmos_physics/src/core_ocean/mpas_ocn_advection.F        2012-02-27 22:33:23 UTC (rev 1538)
@@ -9,7 +9,7 @@
    contains
 
 
-   subroutine ocn_initialize_advection_rk( grid )
+   subroutine ocn_initialize_advection_rk( grid )!{{{
                                       
 !
 ! compute the cell coefficients for the polynomial fit.
@@ -382,7 +382,7 @@
 !      end do
 !      stop
 
-   end subroutine ocn_initialize_advection_rk
+   end subroutine ocn_initialize_advection_rk!}}}
 
 
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -391,7 +391,7 @@
    ! Computes the angle between arcs AB and AC, given points A, B, and C
    ! Equation numbers w.r.t. http://mathworld.wolfram.com/SphericalTrigonometry.html
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   real (kind=RKIND) function sphere_angle(ax, ay, az, bx, by, bz, cx, cy, cz)
+   real (kind=RKIND) function sphere_angle(ax, ay, az, bx, by, bz, cx, cy, cz)!{{{
    
       implicit none
    
@@ -437,7 +437,7 @@
          sphere_angle = -2.0 * asin(max(min(sin_angle,1.0_RKIND),-1.0_RKIND))
       end if
    
-   end function sphere_angle
+   end function sphere_angle!}}}
    
 
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -446,7 +446,7 @@
    ! Computes the angle between vectors AB and AC, given points A, B, and C, and
    !   a vector (u,v,w) normal to the plane.
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   real (kind=RKIND) function plane_angle(ax, ay, az, bx, by, bz, cx, cy, cz, u, v, w)
+   real (kind=RKIND) function plane_angle(ax, ay, az, bx, by, bz, cx, cy, cz, u, v, w)!{{{
    
       implicit none
    
@@ -486,7 +486,7 @@
          plane_angle = -acos(max(min(cos_angle,1.0_RKIND),-1.0_RKIND))
       end if
    
-   end function plane_angle
+   end function plane_angle!}}}
 
 
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -496,7 +496,7 @@
    !    B=(bx, by, bz). It is assumed that both A and B lie on the surface of the
    !    same sphere centered at the origin.
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   real (kind=RKIND) function arc_length(ax, ay, az, bx, by, bz)
+   real (kind=RKIND) function arc_length(ax, ay, az, bx, by, bz)!{{{
    
       implicit none
    
@@ -519,7 +519,7 @@
 !      arc_length = sqrt(r) * 2.0 * asin(c/(2.0*r))
       arc_length = r * 2.0 * asin(c/(2.0*r))
 
-   end function arc_length
+   end function arc_length!}}}
    
    
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -529,7 +529,7 @@
    !   A=(ax, ay, az) to B=(bx, by, bz). It is assumed that A and B lie on the
    !   surface of a sphere centered at the origin.
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   subroutine ocn_arc_bisect(ax, ay, az, bx, by, bz, cx, cy, cz)
+   subroutine ocn_arc_bisect(ax, ay, az, bx, by, bz, cx, cy, cz)!{{{
    
       implicit none
    
@@ -554,10 +554,10 @@
          cz = r * cz / d
       end if
    
-   end subroutine ocn_arc_bisect
+   end subroutine ocn_arc_bisect!}}}
 
 
-   subroutine ocn_poly_fit_2(a_in,b_out,weights_in,m,n,ne)
+   subroutine ocn_poly_fit_2(a_in,b_out,weights_in,m,n,ne)!{{{
 
       implicit none
 
@@ -612,7 +612,7 @@
 !
 !     write(6,*) ' '
 
-   end subroutine ocn_poly_fit_2
+   end subroutine ocn_poly_fit_2!}}}
 
 
 ! Updated 10/24/2001.
@@ -631,119 +631,119 @@
 !                                                                       !
 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 !
-SUBROUTine ocn_migs (A,N,X,INDX)
+subroutine ocn_migs (a,n,x,indx)!{{{
 !
-! Subroutine to invert matrix A(N,N) with the inverse stored
-! in X(N,N) in the output.  Copyright (c) Tao Pang 2001.
+! subroutine to invert matrix a(n,n) with the inverse stored
+! in x(n,n) in the output.  copyright (c) tao pang 2001.
 !
-  IMPLICIT NONE
-  INTEGER, INTENT (IN) :: N
-  INTEGER :: I,J,K
-  INTEGER, INTENT (OUT), DIMENSION (N) :: INDX
-  REAL (kind=RKIND), INTENT (INOUT), DIMENSION (N,N):: A
-  REAL (kind=RKIND), INTENT (OUT), DIMENSION (N,N):: X
-  REAL (kind=RKIND), DIMENSION (N,N) :: B
+  implicit none
+  integer, intent (in) :: n
+  integer :: i,j,k
+  integer, intent (out), dimension (n) :: indx
+  real (kind=RKIND), intent (inout), dimension (n,n):: a
+  real (kind=RKIND), intent (out), dimension (n,n):: x
+  real (kind=RKIND), dimension (n,n) :: b
 !
-  DO I = 1, N
-    DO J = 1, N
-      B(I,J) = 0.0
-    END DO
-  END DO
-  DO I = 1, N
-    B(I,I) = 1.0
-  END DO
+  do i = 1, n
+    do j = 1, n
+      b(i,j) = 0.0
+    end do
+  end do
+  do i = 1, n
+    b(i,i) = 1.0
+  end do
 !
-  call ocn_elgs (A,N,INDX)
+  call ocn_elgs (a,n,indx)
 !
-  DO I = 1, N-1
-    DO J = I+1, N
-      DO K = 1, N
-        B(INDX(J),K) = B(INDX(J),K)-A(INDX(J),I)*B(INDX(I),K)
-      END DO
-    END DO
-  END DO
+  do i = 1, n-1
+    do j = i+1, n
+      do k = 1, n
+        b(indx(j),k) = b(indx(j),k)-a(indx(j),i)*b(indx(i),k)
+      end do
+    end do
+  end do
 !
-  DO I = 1, N
-    X(N,I) = B(INDX(N),I)/A(INDX(N),N)
-    DO J = N-1, 1, -1
-      X(J,I) = B(INDX(J),I)
-      DO K = J+1, N
-        X(J,I) = X(J,I)-A(INDX(J),K)*X(K,I)
-      END DO
-      X(J,I) =  X(J,I)/A(INDX(J),J)
-    END DO
-  END DO
-END SUBROUTine ocn_migs
+  do i = 1, n
+    x(n,i) = b(indx(n),i)/a(indx(n),n)
+    do j = n-1, 1, -1
+      x(j,i) = b(indx(j),i)
+      do k = j+1, n
+        x(j,i) = x(j,i)-a(indx(j),k)*x(k,i)
+      end do
+      x(j,i) =  x(j,i)/a(indx(j),j)
+    end do
+  end do
+end subroutine ocn_migs!}}}
 
 
-SUBROUTine ocn_elgs (A,N,INDX)
+subroutine ocn_elgs (a,n,indx)!{{{
 !
-! Subroutine to perform the partial-pivoting Gaussian elimination.
-! A(N,N) is the original matrix in the input and transformed matrix
+! subroutine to perform the partial-pivoting gaussian elimination.
+! a(n,n) is the original matrix in the input and transformed matrix
 ! plus the pivoting element ratios below the diagonal in the output.
-! INDX(N) records the pivoting order.  Copyright (c) Tao Pang 2001.
+! indx(n) records the pivoting order.  copyright (c) tao pang 2001.
 !
-  IMPLICIT NONE
-  INTEGER, INTENT (IN) :: N
-  INTEGER :: I,J,K,ITMP
-  INTEGER, INTENT (OUT), DIMENSION (N) :: INDX
-  REAL (kind=RKIND) :: C1,PI,PI1,PJ
-  REAL (kind=RKIND), INTENT (INOUT), DIMENSION (N,N) :: A
-  REAL (kind=RKIND), DIMENSION (N) :: C
+  implicit none
+  integer, intent (in) :: n
+  integer :: i,j,k,itmp
+  integer, intent (out), dimension (n) :: indx
+  real (kind=RKIND) :: c1,pi,pi1,pj
+  real (kind=RKIND), intent (inout), dimension (n,n) :: a
+  real (kind=RKIND), dimension (n) :: c
 !
-! Initialize the index
+! initialize the index
 !
-  DO I = 1, N
-    INDX(I) = I
-  END DO
+  do i = 1, n
+    indx(i) = i
+  end do
 !
-! Find the rescaling factors, one from each row
+! find the rescaling factors, one from each row
 !
-  DO I = 1, N
-    C1= 0.0
-    DO J = 1, N
-      C1 = MAX(C1,ABS(A(I,J)))
-    END DO
-    C(I) = C1
-  END DO
+  do i = 1, n
+    c1= 0.0
+    do j = 1, n
+      c1 = max(c1,abs(a(i,j)))
+    end do
+    c(i) = c1
+  end do
 !
-! Search the pivoting (largest) element from each column
+! search the pivoting (largest) element from each column
 !
-  DO J = 1, N-1
-    PI1 = 0.0
-    DO I = J, N
-      PI = ABS(A(INDX(I),J))/C(INDX(I))
-      IF (PI.GT.PI1) THEN
-        PI1 = PI
-        K   = I
-      ENDIF
-    END DO
+  do j = 1, n-1
+    pi1 = 0.0
+    do i = j, n
+      pi = abs(a(indx(i),j))/c(indx(i))
+      if (pi.gt.pi1) then
+        pi1 = pi
+        k   = i
+      endif
+    end do
 !
-! Interchange the rows via INDX(N) to record pivoting order
+! interchange the rows via indx(n) to record pivoting order
 !
-    ITMP    = INDX(J)
-    INDX(J) = INDX(K)
-    INDX(K) = ITMP
-    DO I = J+1, N
-      PJ  = A(INDX(I),J)/A(INDX(J),J)
+    itmp    = indx(j)
+    indx(j) = indx(k)
+    indx(k) = itmp
+    do i = j+1, n
+      pj  = a(indx(i),j)/a(indx(j),j)
 !
-! Record pivoting ratios below the diagonal
+! record pivoting ratios below the diagonal
 !
-      A(INDX(I),J) = PJ
+      a(indx(i),j) = pj
 !
-! Modify other elements accordingly
+! modify other elements accordingly
 !
-      DO K = J+1, N
-        A(INDX(I),K) = A(INDX(I),K)-PJ*A(INDX(J),K)
-      END DO
-    END DO
-  END DO
+      do k = j+1, n
+        a(indx(i),k) = a(indx(i),k)-pj*a(indx(j),k)
+      end do
+    end do
+  end do
 !
-END SUBROUTine ocn_elgs
+end subroutine ocn_elgs!}}}
 
 !-------------------------------------------------------------
 
-   subroutine ocn_initialize_deformation_weights( grid )
+   subroutine ocn_initialize_deformation_weights( grid )!{{{
                                       
 !
 ! compute the cell coefficients for the deformation calculations
@@ -930,6 +930,6 @@
 
       if (debug) write(0,*) ' exiting def weight calc '
 
-   end subroutine ocn_initialize_deformation_weights
+   end subroutine ocn_initialize_deformation_weights!}}}
 
 end module ocn_advection

Modified: branches/atmos_physics/src/core_ocean/mpas_ocn_equation_of_state.F
===================================================================
--- branches/atmos_physics/src/core_ocean/mpas_ocn_equation_of_state.F        2012-02-27 22:31:30 UTC (rev 1537)
+++ branches/atmos_physics/src/core_ocean/mpas_ocn_equation_of_state.F        2012-02-27 22:33:23 UTC (rev 1538)
@@ -16,7 +16,6 @@
 
    use mpas_grid_types
    use mpas_configure
-   use mpas_timer
    use ocn_equation_of_state_linear
    use ocn_equation_of_state_jm
 
@@ -99,8 +98,6 @@
 
       if(.not.eosOn) return
 
-      call mpas_timer_start(&quot;ocn_equation_of_state_rho&quot;)
-
       tracers =&gt; s % tracers % array
       indexT = s % index_temperature
       indexS = s % index_salinity
@@ -122,8 +119,6 @@
 
       endif
 
-      call mpas_timer_stop(&quot;ocn_equation_of_state_rho&quot;)
-
    end subroutine ocn_equation_of_state_rho!}}}
 
 !***********************************************************************
@@ -159,7 +154,7 @@
       linearEos = .false.
       jmEos = .false.
 
-      if(config_vert_grid_type.eq.'zlevel') then
+      if(config_vert_grid_type.ne.'isopycnal') then
           eosON = .true.
 
           if (config_eos_type.eq.'linear') then

Modified: branches/atmos_physics/src/core_ocean/mpas_ocn_equation_of_state_jm.F
===================================================================
--- branches/atmos_physics/src/core_ocean/mpas_ocn_equation_of_state_jm.F        2012-02-27 22:31:30 UTC (rev 1537)
+++ branches/atmos_physics/src/core_ocean/mpas_ocn_equation_of_state_jm.F        2012-02-27 22:33:23 UTC (rev 1538)
@@ -16,7 +16,6 @@
 
    use mpas_grid_types
    use mpas_configure
-   use mpas_timer
 
    implicit none
    private
@@ -96,30 +95,30 @@
 
 
       real (kind=RKIND), dimension(:), pointer :: &amp;
-        zMidZLevel, pRefEOS
+        referenceBottomDepth, pRefEOS
       real (kind=RKIND), dimension(:,:), intent(inout) :: &amp;
         rho
       real (kind=RKIND), dimension(:,:,:), intent(in) :: tracers
 
       integer, dimension(:), pointer :: maxLevelCell
 
-   real (kind=RKIND) :: &amp;
-      TQ,SQ,             &amp;! adjusted T,S
-      BULK_MOD,          &amp;! Bulk modulus
-      RHO_S,             &amp;! density at the surface
-      DRDT0,             &amp;! d(density)/d(temperature), for surface
-      DRDS0,             &amp;! d(density)/d(salinity   ), for surface
-      DKDT,              &amp;! d(bulk modulus)/d(pot. temp.)
-      DKDS,              &amp;! d(bulk modulus)/d(salinity  )
-      SQR,DENOMK,        &amp;! work arrays
-      WORK1, WORK2, WORK3, WORK4, T2, depth
+      real (kind=RKIND) :: &amp;
+         TQ,SQ,             &amp;! adjusted T,S
+         BULK_MOD,          &amp;! Bulk modulus
+         RHO_S,             &amp;! density at the surface
+         DRDT0,             &amp;! d(density)/d(temperature), for surface
+         DRDS0,             &amp;! d(density)/d(salinity   ), for surface
+         DKDT,              &amp;! d(bulk modulus)/d(pot. temp.)
+         DKDS,              &amp;! d(bulk modulus)/d(salinity  )
+         SQR,DENOMK,        &amp;! work arrays
+         WORK1, WORK2, WORK3, WORK4, T2, depth
 
-   real (kind=RKIND) :: &amp; 
-      tmin, tmax,        &amp;! valid temperature range for level k
-      smin, smax          ! valid salinity    range for level k
+      real (kind=RKIND) :: &amp; 
+         tmin, tmax,        &amp;! valid temperature range for level k
+         smin, smax          ! valid salinity    range for level k
 
-   real (kind=RKIND), dimension(:), allocatable :: &amp;
-      p, p2 ! temporary pressure scalars
+      real (kind=RKIND), dimension(:), allocatable :: &amp;
+         p, p2 ! temporary pressure scalars
 
 !-----------------------------------------------------------------------
 !
@@ -127,79 +126,77 @@
 !
 !-----------------------------------------------------------------------
 
-   !*** for density of fresh water (standard UNESCO)
+      !*** for density of fresh water (standard UNESCO)
 
-   real (kind=RKIND), parameter ::              &amp;
-      unt0 =   999.842594,           &amp;
-      unt1 =  6.793952e-2,           &amp;
-      unt2 = -9.095290e-3,           &amp;
-      unt3 =  1.001685e-4,           &amp;
-      unt4 = -1.120083e-6,           &amp;
-      unt5 =  6.536332e-9
+      real (kind=RKIND), parameter ::              &amp;
+         unt0 =   999.842594,           &amp;
+         unt1 =  6.793952e-2,           &amp;
+         unt2 = -9.095290e-3,           &amp;
+         unt3 =  1.001685e-4,           &amp;
+         unt4 = -1.120083e-6,           &amp;
+         unt5 =  6.536332e-9
+   
+      !*** for dependence of surface density on salinity (UNESCO)
 
-   !*** for dependence of surface density on salinity (UNESCO)
-
-   real (kind=RKIND), parameter ::              &amp;
-      uns1t0 =  0.824493 ,           &amp;
-      uns1t1 = -4.0899e-3,           &amp;
-      uns1t2 =  7.6438e-5,           &amp;
-      uns1t3 = -8.2467e-7,           &amp;
-      uns1t4 =  5.3875e-9,           &amp;
-      unsqt0 = -5.72466e-3,          &amp;
-      unsqt1 =  1.0227e-4,           &amp;
-      unsqt2 = -1.6546e-6,           &amp;
-      uns2t0 =  4.8314e-4
-
-   !*** from Table A1 of Jackett and McDougall
-
-   real (kind=RKIND), parameter ::              &amp;
-      bup0s0t0 =  1.965933e+4,       &amp;
-      bup0s0t1 =  1.444304e+2,       &amp;
-      bup0s0t2 = -1.706103   ,       &amp;
-      bup0s0t3 =  9.648704e-3,       &amp;
-      bup0s0t4 = -4.190253e-5
-
-   real (kind=RKIND), parameter ::              &amp;
-      bup0s1t0 =  5.284855e+1,       &amp;
-      bup0s1t1 = -3.101089e-1,       &amp;
-      bup0s1t2 =  6.283263e-3,       &amp;
-      bup0s1t3 = -5.084188e-5
-
-   real (kind=RKIND), parameter ::              &amp;
-      bup0sqt0 =  3.886640e-1,       &amp;
-      bup0sqt1 =  9.085835e-3,       &amp;
-      bup0sqt2 = -4.619924e-4
-
-   real (kind=RKIND), parameter ::              &amp;
-      bup1s0t0 =  3.186519   ,       &amp;
-      bup1s0t1 =  2.212276e-2,       &amp;
-      bup1s0t2 = -2.984642e-4,       &amp;
-      bup1s0t3 =  1.956415e-6 
-
-   real (kind=RKIND), parameter ::              &amp;
-      bup1s1t0 =  6.704388e-3,       &amp;
-      bup1s1t1 = -1.847318e-4,       &amp;
-      bup1s1t2 =  2.059331e-7,       &amp;
-      bup1sqt0 =  1.480266e-4 
-
-   real (kind=RKIND), parameter ::              &amp;
-      bup2s0t0 =  2.102898e-4,       &amp;
-      bup2s0t1 = -1.202016e-5,       &amp;
-      bup2s0t2 =  1.394680e-7,       &amp;
-      bup2s1t0 = -2.040237e-6,       &amp;
-      bup2s1t1 =  6.128773e-8,       &amp;
-      bup2s1t2 =  6.207323e-10
-
-   integer :: k_test, k_ref
-
+      real (kind=RKIND), parameter ::              &amp;
+         uns1t0 =  0.824493 ,           &amp;
+         uns1t1 = -4.0899e-3,           &amp;
+         uns1t2 =  7.6438e-5,           &amp;
+         uns1t3 = -8.2467e-7,           &amp;
+         uns1t4 =  5.3875e-9,           &amp;
+         unsqt0 = -5.72466e-3,          &amp;
+         unsqt1 =  1.0227e-4,           &amp;
+         unsqt2 = -1.6546e-6,           &amp;
+         uns2t0 =  4.8314e-4
+   
+      !*** from Table A1 of Jackett and McDougall
+   
+      real (kind=RKIND), parameter ::              &amp;
+         bup0s0t0 =  1.965933e+4,       &amp;
+         bup0s0t1 =  1.444304e+2,       &amp;
+         bup0s0t2 = -1.706103   ,       &amp;
+         bup0s0t3 =  9.648704e-3,       &amp;
+         bup0s0t4 = -4.190253e-5
+   
+      real (kind=RKIND), parameter ::              &amp;
+         bup0s1t0 =  5.284855e+1,       &amp;
+         bup0s1t1 = -3.101089e-1,       &amp;
+         bup0s1t2 =  6.283263e-3,       &amp;
+         bup0s1t3 = -5.084188e-5
+   
+      real (kind=RKIND), parameter ::              &amp;
+         bup0sqt0 =  3.886640e-1,       &amp;
+         bup0sqt1 =  9.085835e-3,       &amp;
+         bup0sqt2 = -4.619924e-4
+   
+      real (kind=RKIND), parameter ::              &amp;
+         bup1s0t0 =  3.186519   ,       &amp;
+         bup1s0t1 =  2.212276e-2,       &amp;
+         bup1s0t2 = -2.984642e-4,       &amp;
+         bup1s0t3 =  1.956415e-6 
+   
+      real (kind=RKIND), parameter ::              &amp;
+         bup1s1t0 =  6.704388e-3,       &amp;
+         bup1s1t1 = -1.847318e-4,       &amp;
+         bup1s1t2 =  2.059331e-7,       &amp;
+         bup1sqt0 =  1.480266e-4 
+   
+      real (kind=RKIND), parameter ::              &amp;
+         bup2s0t0 =  2.102898e-4,       &amp;
+         bup2s0t1 = -1.202016e-5,       &amp;
+         bup2s0t2 =  1.394680e-7,       &amp;
+         bup2s1t0 = -2.040237e-6,       &amp;
+         bup2s1t1 =  6.128773e-8,       &amp;
+         bup2s1t2 =  6.207323e-10
+   
+      integer :: k_test, k_ref
+   
       err = 0
-
-      call mpas_timer_start(&quot;equation_of_state_jm&quot;)
-
+   
       nCells      = grid % nCells
       maxLevelCell      =&gt; grid % maxLevelCell % array
       nVertLevels = grid % nVertLevels
-      zMidZLevel        =&gt; grid % zMidZLevel % array
+      referenceBottomDepth =&gt; grid % referenceBottomDepth % array
 
 
 !  Jackett and McDougall
@@ -208,109 +205,110 @@
       smin =  0.0  ! valid salinity, in psu   
       smax = 42.0 
 
-      ! This could be put in a startup routine.
-      ! Note I am using zMidZlevel, so pressure on top level does
-      ! not include SSH contribution.  I am not sure if that matters.
-
 !  This function computes pressure in bars from depth in meters
 !  using a mean density derived from depth-dependent global 
 !  average temperatures and salinities from Levitus 1994, and 
 !  integrating using hydrostatic balance.
 
       allocate(pRefEOS(nVertLevels),p(nVertLevels),p2(nVertLevels))
-      do k = 1,nVertLevels
-        depth = -zMidZLevel(k)
-        pRefEOS(k) = 0.059808*(exp(-0.025*depth) - 1.0) &amp;
-            + 0.100766*depth + 2.28405e-7*depth**2
-      enddo
 
-   !  If k_displaced=0, in-situ density is returned (no displacement)
-   !  If k_displaced/=0, potential density is returned
-
-   !  if displacement_type = 'relative', potential density is calculated
-   !     referenced to level k + k_displaced
-   !  if displacement_type = 'absolute', potential density is calculated
-   !     referenced to level k_displaced for all k
-   !  NOTE: k_displaced = 0 or &gt; nVertLevels is incompatible with 'absolute'
-   !     so abort if necessary
-
-   if (displacement_type == 'absolute' .and.   &amp;
-       (k_displaced &lt;= 0 .or. k_displaced &gt; nVertLevels) ) then
-      write(0,*) 'Abort: In equation_of_state_jm', &amp;
-         ' k_displaced must be between 1 and nVertLevels for ', &amp;
-         'displacement_type = absolute'
-      call mpas_dmpar_abort(dminfo)
-   endif
-
-   if (k_displaced == 0) then
-      do k=1,nVertLevels
-         p(k)   = pRefEOS(k)
-         p2(k)  = p(k)*p(k)
+      ! This could be put in the init routine.
+      ! Note I am using referenceBottomDepth, so pressure on top level does
+      ! not include SSH contribution.  I am not sure if that matters, but
+      ! POP does it the same way.
+      depth = 0.5*referenceBottomDepth(1)
+      pRefEOS(1) = 0.059808*(exp(-0.025*depth) - 1.0) &amp;
+          + 0.100766*depth + 2.28405e-7*depth**2
+      do k = 2,nVertLevels
+         depth = 0.5*(referenceBottomDepth(k)+referenceBottomDepth(k-1))
+         pRefEOS(k) = 0.059808*(exp(-0.025*depth) - 1.0) &amp;
+             + 0.100766*depth + 2.28405e-7*depth**2
       enddo
-   else ! k_displaced /= 0
-      do k=1,nVertLevels
-         if (displacement_type == 'relative') then
-            k_test = min(k + k_displaced, nVertLevels)
-            k_ref  = max(k_test, 1)
-         else
-            k_test = min(k_displaced, nVertLevels)
-            k_ref  = max(k_test, 1)
-         endif
-         p(k)   = pRefEOS(k_ref)
-         p2(k)  = p(k)*p(k)
-      enddo
-   endif
 
-  do iCell=1,nCells
-    do k=1,maxLevelCell(iCell)
+      !  If k_displaced=0, in-situ density is returned (no displacement)
+      !  If k_displaced/=0, potential density is returned
 
-      SQ  = max(min(tracers(indexS,k,iCell),smax),smin)
-      TQ  = max(min(tracers(indexT,k,iCell),tmax),tmin)
+      !  if displacement_type = 'relative', potential density is calculated
+      !     referenced to level k + k_displaced
+      !  if displacement_type = 'absolute', potential density is calculated
+      !     referenced to level k_displaced for all k
+      !  NOTE: k_displaced = 0 or &gt; nVertLevels is incompatible with 'absolute'
+      !     so abort if necessary
 
-      SQR = sqrt(SQ)
-      T2  = TQ*TQ
+      if (displacement_type == 'absolute' .and.   &amp;
+         (k_displaced &lt;= 0 .or. k_displaced &gt; nVertLevels) ) then
 
-      !***
-      !*** first calculate surface (p=0) values from UNESCO eqns.
-      !***
+         write(0,*) 'Abort: In equation_of_state_jm', &amp;
+             ' k_displaced must be between 1 and nVertLevels for ', &amp;
+             'displacement_type = absolute'
+         call mpas_dmpar_abort(dminfo)
+      endif
 
-      WORK1 = uns1t0 + uns1t1*TQ + &amp; 
-             (uns1t2 + uns1t3*TQ + uns1t4*T2)*T2
-      WORK2 = SQR*(unsqt0 + unsqt1*TQ + unsqt2*T2)
+      if (k_displaced == 0) then
+         do k=1,nVertLevels
+            p(k)   = pRefEOS(k)
+            p2(k)  = p(k)*p(k)
+         enddo
+      else ! k_displaced /= 0
+         do k=1,nVertLevels
+            if (displacement_type == 'relative') then
+               k_test = min(k + k_displaced, nVertLevels)
+               k_ref  = max(k_test, 1)
+            else
+               k_test = min(k_displaced, nVertLevels)
+               k_ref  = max(k_test, 1)
+            endif
+            p(k)   = pRefEOS(k_ref)
+            p2(k)  = p(k)*p(k)
+         enddo
+      endif
 
-      RHO_S = unt1*TQ + (unt2 + unt3*TQ + (unt4 + unt5*TQ)*T2)*T2 &amp;
-                      + (uns2t0*SQ + WORK1 + WORK2)*SQ
+      do iCell=1,nCells
+         do k=1,maxLevelCell(iCell)
+            SQ  = max(min(tracers(indexS,k,iCell),smax),smin)
+            TQ  = max(min(tracers(indexT,k,iCell),tmax),tmin)
+   
+            SQR = sqrt(SQ)
+            T2  = TQ*TQ
 
-      !***
-      !*** now calculate bulk modulus at pressure p from 
-      !*** Jackett and McDougall formula
-      !***
+            !***
+            !*** first calculate surface (p=0) values from UNESCO eqns.
+            !***
 
-      WORK3 = bup0s1t0 + bup0s1t1*TQ +                    &amp;
-             (bup0s1t2 + bup0s1t3*TQ)*T2 +                &amp;
-              p(k) *(bup1s1t0 + bup1s1t1*TQ + bup1s1t2*T2) + &amp;
-              p2(k)*(bup2s1t0 + bup2s1t1*TQ + bup2s1t2*T2)
-      WORK4 = SQR*(bup0sqt0 + bup0sqt1*TQ + bup0sqt2*T2 + &amp;
-                   bup1sqt0*p(k))
+            WORK1 = uns1t0 + uns1t1*TQ + &amp; 
+                   (uns1t2 + uns1t3*TQ + uns1t4*T2)*T2
+            WORK2 = SQR*(unsqt0 + unsqt1*TQ + unsqt2*T2)
 
-      BULK_MOD  = bup0s0t0 + bup0s0t1*TQ +                    &amp;
-                  (bup0s0t2 + bup0s0t3*TQ + bup0s0t4*T2)*T2 + &amp;
-                  p(k) *(bup1s0t0 + bup1s0t1*TQ +                &amp;
-                     (bup1s0t2 + bup1s0t3*TQ)*T2) +           &amp;
-                  p2(k)*(bup2s0t0 + bup2s0t1*TQ + bup2s0t2*T2) + &amp;
-                  SQ*(WORK3 + WORK4)
+            RHO_S = unt1*TQ + (unt2 + unt3*TQ + (unt4 + unt5*TQ)*T2)*T2 &amp;
+                            + (uns2t0*SQ + WORK1 + WORK2)*SQ
 
-      DENOMK = 1.0/(BULK_MOD - p(k))
+            !***
+            !*** now calculate bulk modulus at pressure p from 
+            !*** Jackett and McDougall formula
+            !***
 
-      rho(k,iCell) = (unt0 + RHO_S)*BULK_MOD*DENOMK
+            WORK3 = bup0s1t0 + bup0s1t1*TQ +                    &amp;
+                    (bup0s1t2 + bup0s1t3*TQ)*T2 +                &amp;
+                    p(k) *(bup1s1t0 + bup1s1t1*TQ + bup1s1t2*T2) + &amp;
+                    p2(k)*(bup2s1t0 + bup2s1t1*TQ + bup2s1t2*T2)
+            WORK4 = SQR*(bup0sqt0 + bup0sqt1*TQ + bup0sqt2*T2 + &amp;
+                         bup1sqt0*p(k))
+   
+            BULK_MOD  = bup0s0t0 + bup0s0t1*TQ +                    &amp;
+                        (bup0s0t2 + bup0s0t3*TQ + bup0s0t4*T2)*T2 + &amp;
+                        p(k) *(bup1s0t0 + bup1s0t1*TQ +                &amp;
+                        (bup1s0t2 + bup1s0t3*TQ)*T2) +           &amp;
+                        p2(k)*(bup2s0t0 + bup2s0t1*TQ + bup2s0t2*T2) + &amp;
+                        SQ*(WORK3 + WORK4)
+  
+            DENOMK = 1.0/(BULK_MOD - p(k))
+   
+            rho(k,iCell) = (unt0 + RHO_S)*BULK_MOD*DENOMK
 
-    end do
-  end do
+         end do
+      end do
 
-   deallocate(pRefEOS,p,p2)
-
-   call mpas_timer_stop(&quot;equation_of_state_jm&quot;)
-
+      deallocate(pRefEOS,p,p2)
    end subroutine ocn_equation_of_state_jm_rho!}}}
 
 !***********************************************************************

Modified: branches/atmos_physics/src/core_ocean/mpas_ocn_equation_of_state_linear.F
===================================================================
--- branches/atmos_physics/src/core_ocean/mpas_ocn_equation_of_state_linear.F        2012-02-27 22:31:30 UTC (rev 1537)
+++ branches/atmos_physics/src/core_ocean/mpas_ocn_equation_of_state_linear.F        2012-02-27 22:33:23 UTC (rev 1538)
@@ -16,7 +16,6 @@
 
    use mpas_grid_types
    use mpas_configure
-   use mpas_timer
 
    implicit none
    private
@@ -87,8 +86,6 @@
       integer :: nCells, iCell, k
       type (dm_info) :: dminfo
 
-      call mpas_timer_start(&quot;ocn_equation_of_state_linear&quot;)
-
       maxLevelCell      =&gt; grid % maxLevelCell % array
       nCells      = grid % nCells
 
@@ -103,8 +100,6 @@
          end do
       end do
 
-      call mpas_timer_stop(&quot;ocn_equation_of_state_linear&quot;)
-
    end subroutine ocn_equation_of_state_linear_rho!}}}
 
 !***********************************************************************

Modified: branches/atmos_physics/src/core_ocean/mpas_ocn_global_diagnostics.F
===================================================================
--- branches/atmos_physics/src/core_ocean/mpas_ocn_global_diagnostics.F        2012-02-27 22:31:30 UTC (rev 1537)
+++ branches/atmos_physics/src/core_ocean/mpas_ocn_global_diagnostics.F        2012-02-27 22:33:23 UTC (rev 1538)
@@ -4,14 +4,17 @@
    use mpas_configure
    use mpas_constants
    use mpas_dmpar
+   use mpas_timer
 
    implicit none
    save
    public
 
+   type (timer_node), pointer :: diagBlockTimer, diagMPITimer
+
    contains
 
-   subroutine ocn_compute_global_diagnostics(dminfo, state, grid, timeIndex, dt)
+   subroutine ocn_compute_global_diagnostics(domain, timeLevel, timeIndex, dt)!{{{
 
       ! Note: this routine assumes that there is only one block per processor. No looping
       ! is preformed over blocks.
@@ -26,197 +29,300 @@
 
       implicit none
 
-      type (dm_info), intent(in) :: dminfo
-      type (state_type), intent(inout) :: state
-      type (mesh_type), intent(in) :: grid
+      type (domain_type), intent(inout) :: domain !&lt; Input/Output: domain information
       integer, intent(in) :: timeIndex
       real (kind=RKIND), intent(in) :: dt
 
+      type (block_type), pointer :: block
+      type (dm_info), pointer :: dminfo
+      type (state_type), pointer :: state
+      type (mesh_type), pointer :: grid
+
       integer :: nVertLevels, nCellsSolve, nEdgesSolve, nVerticesSolve, nCellsGlobal, nEdgesGlobal, nVerticesGlobal, iTracer
+      integer :: elementIndex, variableIndex, nVariables, nSums, nMaxes, nMins
+      integer :: timeLevel,k,i, num_tracers
+      integer :: fileID
+      integer, parameter :: kMaxVariables = 1024 ! this must be a little more than double the number of variables to be reduced
 
-      real (kind=RKIND) ::  areaCellGlobal, areaEdgeGlobal, areaTriangleGlobal
+      real (kind=RKIND) :: volumeCellGlobal, volumeEdgeGlobal, CFLNumberGlobal, localCFL, localSum, areaCellGlobal, areaEdgeGlobal, areaTriangleGlobal
       real (kind=RKIND), dimension(:), pointer ::  areaCell, dcEdge, dvEdge, areaTriangle, areaEdge
       real (kind=RKIND), dimension(:,:), pointer :: h, u, v, h_edge, circulation, vorticity, ke, pv_edge, pv_vertex, &amp;
          pv_cell, gradPVn, gradPVt, pressure, MontPot, wTop, rho, tracerTemp
       real (kind=RKIND), dimension(:,:,:), pointer :: tracers
+      
+      real (kind=RKIND), dimension(kMaxVariables) :: sums, mins, maxes, averages, verticalSumMins, verticalSumMaxes, reductions
+      real (kind=RKIND), dimension(kMaxVariables) :: sums_tmp, mins_tmp, maxes_tmp, averages_tmp, verticalSumMins_tmp, verticalSumMaxes_tmp
 
-      real (kind=RKIND) :: volumeCellGlobal, volumeEdgeGlobal, CFLNumberGlobal
-      real (kind=RKIND) ::  localCFL, localSum
-      integer :: elementIndex, variableIndex, nVariables, nSums, nMaxes, nMins
-      integer :: timeLevel,k,i, num_tracers
+      block =&gt; domain % blocklist
+      dminfo =&gt; domain % dminfo
 
-      integer, parameter :: kMaxVariables = 1024 ! this must be a little more than double the number of variables to be reduced
+      sums = 0.0
+      mins = 0.0
+      maxes = 0.0
+      averages = 0.0
+      verticalSumMins = 0.0
+      verticalSumMaxes = 0.0
+      reductions = 0.0
 
-      real (kind=RKIND), dimension(kMaxVariables) :: sums, mins, maxes, averages, verticalSumMins, verticalSumMaxes, reductions
+      call mpas_timer_start(&quot;diagnostic block loop&quot;, .false., diagBlockTimer)
+      do while (associated(block))
+         state =&gt; block % state % time_levs(timeLevel) % state
+         grid =&gt; block % mesh
+         
+         num_tracers = state % num_tracers
 
-      integer :: fileID
+         nVertLevels = grid % nVertLevels
+         nCellsSolve = grid % nCellsSolve
+         nEdgesSolve = grid % nEdgesSolve
+         nVerticesSolve = grid % nVerticesSolve
 
-      num_tracers = state % num_tracers
+         areaCell =&gt; grid % areaCell % array
+         dcEdge =&gt; grid % dcEdge % array
+         dvEdge =&gt; grid % dvEdge % array
+         areaTriangle =&gt; grid % areaTriangle % array
+         allocate(areaEdge(1:nEdgesSolve))
+         areaEdge = dcEdge(1:nEdgesSolve)*dvEdge(1:nEdgesSolve)
 
-      nVertLevels = grid % nVertLevels
-      nCellsSolve = grid % nCellsSolve
-      nEdgesSolve = grid % nEdgesSolve
-      nVerticesSolve = grid % nVerticesSolve
+         h =&gt; state % h % array
+         u =&gt; state % u % array
+         rho =&gt; state % rho % array
+         tracers =&gt; state % tracers % array
+         v =&gt; state % v % array
+         wTop =&gt; state % wTop % array
+         h_edge =&gt; state % h_edge % array
+         circulation =&gt; state % circulation % array
+         vorticity =&gt; state % vorticity % array
+         ke =&gt; state % ke % array
+         pv_edge =&gt; state % pv_edge % array
+         pv_vertex =&gt; state % pv_vertex % array
+         pv_cell =&gt; state % pv_cell % array
+         gradPVn =&gt; state % gradPVn % array
+         gradPVt =&gt; state % gradPVt % array
+         MontPot =&gt; state % MontPot % array
+         pressure =&gt; state % pressure % array
 
-      areaCell =&gt; grid % areaCell % array
-      dcEdge =&gt; grid % dcEdge % array
-      dvEdge =&gt; grid % dvEdge % array
-      areaTriangle =&gt; grid % areaTriangle % array
-      allocate(areaEdge(1:nEdgesSolve))
-      areaEdge = dcEdge(1:nEdgesSolve)*dvEdge(1:nEdgesSolve)
+         variableIndex = 0
+         ! h
+         variableIndex = variableIndex + 1
+         call ocn_compute_field_area_weighted_local_stats(dminfo, nVertLevels, nCellsSolve, areaCell(1:nCellsSolve), h(:,1:nCellsSolve), &amp;
+            sums_tmp(variableIndex), mins_tmp(variableIndex), maxes_tmp(variableIndex), verticalSumMins_tmp(variableIndex), verticalSumMaxes_tmp(variableIndex))
+         sums(variableIndex) = sums(variableIndex) + sums_tmp(variableIndex)
+         mins(variableIndex) = min(mins(variableIndex), mins_tmp(variableIndex))
+         maxes(variableIndex) = max(maxes(variableIndex), maxes_tmp(variableIndex))
+         verticalSumMins(variableIndex) = min(verticalSumMins(variableIndex), verticalSumMins_tmp(variableIndex))
+         verticalSumMaxes(variableIndex) = max(verticalSumMaxes(variableIndex), verticalSumMaxes_tmp(variableIndex))
 
-      h =&gt; state % h % array
-      u =&gt; state % u % array
-      rho =&gt; state % rho % array
-      tracers =&gt; state % tracers % array
-      v =&gt; state % v % array
-      wTop =&gt; state % wTop % array
-      h_edge =&gt; state % h_edge % array
-      circulation =&gt; state % circulation % array
-      vorticity =&gt; state % vorticity % array
-      ke =&gt; state % ke % array
-      pv_edge =&gt; state % pv_edge % array
-      pv_vertex =&gt; state % pv_vertex % array
-      pv_cell =&gt; state % pv_cell % array
-      gradPVn =&gt; state % gradPVn % array
-      gradPVt =&gt; state % gradPVt % array
-      MontPot =&gt; state % MontPot % array
-      pressure =&gt; state % pressure % array
+         ! u
+         variableIndex = variableIndex + 1
+         call ocn_compute_field_volume_weighted_local_stats(dminfo, nVertLevels, nEdgesSolve, areaEdge(1:nEdgesSolve), h_edge(:,1:nEdgesSolve), &amp;
+            u(:,1:nEdgesSolve), sums_tmp(variableIndex), mins_tmp(variableIndex), maxes_tmp(variableIndex), verticalSumMins_tmp(variableIndex), &amp;
+            verticalSumMaxes_tmp(variableIndex))
+         sums(variableIndex) = sums(variableIndex) + sums_tmp(variableIndex)
+         mins(variableIndex) = min(mins(variableIndex), mins_tmp(variableIndex))
+         maxes(variableIndex) = max(maxes(variableIndex), maxes_tmp(variableIndex))
+         verticalSumMins(variableIndex) = min(verticalSumMins(variableIndex), verticalSumMins_tmp(variableIndex))
+         verticalSumMaxes(variableIndex) = max(verticalSumMaxes(variableIndex), verticalSumMaxes_tmp(variableIndex))
 
-      variableIndex = 0
-      ! h
-      variableIndex = variableIndex + 1
-      call ocn_compute_field_area_weighted_local_stats(dminfo, nVertLevels, nCellsSolve, areaCell(1:nCellsSolve), h(:,1:nCellsSolve), &amp;
-        sums(variableIndex), mins(variableIndex), maxes(variableIndex), verticalSumMins(variableIndex), verticalSumMaxes(variableIndex))
+         ! v
+         variableIndex = variableIndex + 1
+         call ocn_compute_field_volume_weighted_local_stats(dminfo, nVertLevels, nEdgesSolve, areaEdge(1:nEdgesSolve), h_edge(:,1:nEdgesSolve), &amp;
+            v(:,1:nEdgesSolve), sums_tmp(variableIndex), mins_tmp(variableIndex), maxes_tmp(variableIndex), verticalSumMins_tmp(variableIndex), &amp;
+            verticalSumMaxes_tmp(variableIndex))
+         sums(variableIndex) = sums(variableIndex) + sums_tmp(variableIndex)
+         mins(variableIndex) = min(mins(variableIndex), mins_tmp(variableIndex))
+         maxes(variableIndex) = max(maxes(variableIndex), maxes_tmp(variableIndex))
+         verticalSumMins(variableIndex) = min(verticalSumMins(variableIndex), verticalSumMins_tmp(variableIndex))
+         verticalSumMaxes(variableIndex) = max(verticalSumMaxes(variableIndex), verticalSumMaxes_tmp(variableIndex))
 
-      ! u
-      variableIndex = variableIndex + 1
-      call ocn_compute_field_volume_weighted_local_stats(dminfo, nVertLevels, nEdgesSolve, areaEdge(1:nEdgesSolve), h_edge(:,1:nEdgesSolve), &amp;
-        u(:,1:nEdgesSolve), sums(variableIndex), mins(variableIndex), maxes(variableIndex), verticalSumMins(variableIndex), &amp;
-        verticalSumMaxes(variableIndex))
+         ! h_edge
+         variableIndex = variableIndex + 1
+         call ocn_compute_field_area_weighted_local_stats(dminfo, nVertLevels, nEdgesSolve, areaEdge(1:nEdgesSolve), h_edge(:,1:nEdgesSolve), &amp;
+            sums_tmp(variableIndex), mins_tmp(variableIndex), maxes_tmp(variableIndex), verticalSumMins_tmp(variableIndex), verticalSumMaxes_tmp(variableIndex))
+         sums(variableIndex) = sums(variableIndex) + sums_tmp(variableIndex)
+         mins(variableIndex) = min(mins(variableIndex), mins_tmp(variableIndex))
+         maxes(variableIndex) = max(maxes(variableIndex), maxes_tmp(variableIndex))
+         verticalSumMins(variableIndex) = min(verticalSumMins(variableIndex), verticalSumMins_tmp(variableIndex))
+         verticalSumMaxes(variableIndex) = max(verticalSumMaxes(variableIndex), verticalSumMaxes_tmp(variableIndex))
 
-      ! v
-      variableIndex = variableIndex + 1
-      call ocn_compute_field_volume_weighted_local_stats(dminfo, nVertLevels, nEdgesSolve, areaEdge(1:nEdgesSolve), h_edge(:,1:nEdgesSolve), &amp;
-        v(:,1:nEdgesSolve), sums(variableIndex), mins(variableIndex), maxes(variableIndex), verticalSumMins(variableIndex), &amp;
-        verticalSumMaxes(variableIndex))
+         ! circulation
+         variableIndex = variableIndex + 1
+         call ocn_compute_field_local_stats(dminfo, nVertLevels, nVerticesSolve, circulation(:,1:nVerticesSolve), &amp;
+            sums_tmp(variableIndex), mins_tmp(variableIndex), maxes_tmp(variableIndex), verticalSumMins_tmp(variableIndex), verticalSumMaxes_tmp(variableIndex))
+            sums(variableIndex) = sums(variableIndex) + sums_tmp(variableIndex)
+         mins(variableIndex) = min(mins(variableIndex), mins_tmp(variableIndex))
+         maxes(variableIndex) = max(maxes(variableIndex), maxes_tmp(variableIndex))
+         verticalSumMins(variableIndex) = min(verticalSumMins(variableIndex), verticalSumMins_tmp(variableIndex))
+         verticalSumMaxes(variableIndex) = max(verticalSumMaxes(variableIndex), verticalSumMaxes_tmp(variableIndex))
 
-      ! h_edge
-      variableIndex = variableIndex + 1
-      call ocn_compute_field_area_weighted_local_stats(dminfo, nVertLevels, nEdgesSolve, areaEdge(1:nEdgesSolve), h_edge(:,1:nEdgesSolve), &amp;
-        sums(variableIndex), mins(variableIndex), maxes(variableIndex), verticalSumMins(variableIndex), verticalSumMaxes(variableIndex))
+         ! vorticity
+         variableIndex = variableIndex + 1
+         call ocn_compute_field_area_weighted_local_stats(dminfo, nVertLevels, nVerticesSolve, areaTriangle(1:nVerticesSolve), &amp;
+            vorticity(:,1:nVerticesSolve), sums_tmp(variableIndex), mins_tmp(variableIndex), maxes_tmp(variableIndex), &amp;
+            verticalSumMins_tmp(variableIndex), verticalSumMaxes_tmp(variableIndex))
+         sums(variableIndex) = sums(variableIndex) + sums_tmp(variableIndex)
+         mins(variableIndex) = min(mins(variableIndex), mins_tmp(variableIndex))
+         maxes(variableIndex) = max(maxes(variableIndex), maxes_tmp(variableIndex))
+         verticalSumMins(variableIndex) = min(verticalSumMins(variableIndex), verticalSumMins_tmp(variableIndex))
+         verticalSumMaxes(variableIndex) = max(verticalSumMaxes(variableIndex), verticalSumMaxes_tmp(variableIndex))
 
-      ! circulation
-      variableIndex = variableIndex + 1
-      call ocn_compute_field_local_stats(dminfo, nVertLevels, nVerticesSolve, circulation(:,1:nVerticesSolve), &amp;
-        sums(variableIndex), mins(variableIndex), maxes(variableIndex), verticalSumMins(variableIndex), verticalSumMaxes(variableIndex))
+         ! ke
+         variableIndex = variableIndex + 1
+         call ocn_compute_field_volume_weighted_local_stats(dminfo, nVertLevels, nCellsSolve, areaCell(1:nCellsSolve), h(:,1:nCellsSolve), &amp;
+            ke(:,1:nCellsSolve), sums_tmp(variableIndex), mins_tmp(variableIndex), maxes_tmp(variableIndex), verticalSumMins_tmp(variableIndex), &amp;
+            verticalSumMaxes_tmp(variableIndex))
+         sums(variableIndex) = sums(variableIndex) + sums_tmp(variableIndex)
+         mins(variableIndex) = min(mins(variableIndex), mins_tmp(variableIndex))
+         maxes(variableIndex) = max(maxes(variableIndex), maxes_tmp(variableIndex))
+         verticalSumMins(variableIndex) = min(verticalSumMins(variableIndex), verticalSumMins_tmp(variableIndex))
+         verticalSumMaxes(variableIndex) = max(verticalSumMaxes(variableIndex), verticalSumMaxes_tmp(variableIndex))
 
-      ! vorticity
-      variableIndex = variableIndex + 1
-      call ocn_compute_field_area_weighted_local_stats(dminfo, nVertLevels, nVerticesSolve, areaTriangle(1:nVerticesSolve), &amp;
-        vorticity(:,1:nVerticesSolve), sums(variableIndex), mins(variableIndex), maxes(variableIndex), &amp;
-        verticalSumMins(variableIndex), verticalSumMaxes(variableIndex))
+         ! pv_edge
+         variableIndex = variableIndex + 1
+         call ocn_compute_field_volume_weighted_local_stats(dminfo, nVertLevels, nEdgesSolve, areaEdge(1:nEdgesSolve), h_edge(:,1:nEdgesSolve), &amp;
+            pv_edge(:,1:nEdgesSolve), sums_tmp(variableIndex), mins_tmp(variableIndex), maxes_tmp(variableIndex), verticalSumMins_tmp(variableIndex), &amp;
+            verticalSumMaxes_tmp(variableIndex))
+         sums(variableIndex) = sums(variableIndex) + sums_tmp(variableIndex)
+         mins(variableIndex) = min(mins(variableIndex), mins_tmp(variableIndex))
+         maxes(variableIndex) = max(maxes(variableIndex), maxes_tmp(variableIndex))
+         verticalSumMins(variableIndex) = min(verticalSumMins(variableIndex), verticalSumMins_tmp(variableIndex))
+         verticalSumMaxes(variableIndex) = max(verticalSumMaxes(variableIndex), verticalSumMaxes_tmp(variableIndex))
 
-      ! ke
-      variableIndex = variableIndex + 1
-      call ocn_compute_field_volume_weighted_local_stats(dminfo, nVertLevels, nCellsSolve, areaCell(1:nCellsSolve), h(:,1:nCellsSolve), &amp;
-        ke(:,1:nCellsSolve), sums(variableIndex), mins(variableIndex), maxes(variableIndex), verticalSumMins(variableIndex), &amp;
-        verticalSumMaxes(variableIndex))
+         ! pv_vertex
+         variableIndex = variableIndex + 1
+         call ocn_compute_field_area_weighted_local_stats(dminfo, nVertLevels, nVerticesSolve, areaTriangle(1:nVerticesSolve), &amp;
+            pv_vertex(:,1:nVerticesSolve), sums_tmp(variableIndex), mins_tmp(variableIndex), maxes_tmp(variableIndex), &amp;
+            verticalSumMins_tmp(variableIndex), verticalSumMaxes_tmp(variableIndex))
+         sums(variableIndex) = sums(variableIndex) + sums_tmp(variableIndex)
+         mins(variableIndex) = min(mins(variableIndex), mins_tmp(variableIndex))
+         maxes(variableIndex) = max(maxes(variableIndex), maxes_tmp(variableIndex))
+         verticalSumMins(variableIndex) = min(verticalSumMins(variableIndex), verticalSumMins_tmp(variableIndex))
+         verticalSumMaxes(variableIndex) = max(verticalSumMaxes(variableIndex), verticalSumMaxes_tmp(variableIndex))
 
-      ! pv_edge
-      variableIndex = variableIndex + 1
-      call ocn_compute_field_volume_weighted_local_stats(dminfo, nVertLevels, nEdgesSolve, areaEdge(1:nEdgesSolve), h_edge(:,1:nEdgesSolve), &amp;
-        pv_edge(:,1:nEdgesSolve), sums(variableIndex), mins(variableIndex), maxes(variableIndex), verticalSumMins(variableIndex), &amp;
-        verticalSumMaxes(variableIndex))
+         ! pv_cell
+         variableIndex = variableIndex + 1
+         call ocn_compute_field_volume_weighted_local_stats(dminfo, nVertLevels, nCellsSolve, areaCell(1:nCellsSolve), h(:,1:nCellsSolve), &amp;
+            pv_cell(:,1:nCellsSolve), sums_tmp(variableIndex), mins_tmp(variableIndex), maxes_tmp(variableIndex), verticalSumMins_tmp(variableIndex), &amp;
+            verticalSumMaxes_tmp(variableIndex))
+         sums(variableIndex) = sums(variableIndex) + sums_tmp(variableIndex)
+         mins(variableIndex) = min(mins(variableIndex), mins_tmp(variableIndex))
+         maxes(variableIndex) = max(maxes(variableIndex), maxes_tmp(variableIndex))
+         verticalSumMins(variableIndex) = min(verticalSumMins(variableIndex), verticalSumMins_tmp(variableIndex))
+         verticalSumMaxes(variableIndex) = max(verticalSumMaxes(variableIndex), verticalSumMaxes_tmp(variableIndex))
 
-      ! pv_vertex
-      variableIndex = variableIndex + 1
-      call ocn_compute_field_area_weighted_local_stats(dminfo, nVertLevels, nVerticesSolve, areaTriangle(1:nVerticesSolve), &amp;
-        pv_vertex(:,1:nVerticesSolve), sums(variableIndex), mins(variableIndex), maxes(variableIndex), &amp;
-        verticalSumMins(variableIndex), verticalSumMaxes(variableIndex))
+         ! gradPVn
+         variableIndex = variableIndex + 1
+         call ocn_compute_field_volume_weighted_local_stats(dminfo, nVertLevels, nEdgesSolve, areaEdge(1:nEdgesSolve), h_edge(:,1:nEdgesSolve), &amp;
+            gradPVn(:,1:nEdgesSolve), sums_tmp(variableIndex), mins_tmp(variableIndex), maxes_tmp(variableIndex), verticalSumMins_tmp(variableIndex), &amp;
+            verticalSumMaxes_tmp(variableIndex))
+         sums(variableIndex) = sums(variableIndex) + sums_tmp(variableIndex)
+         mins(variableIndex) = min(mins(variableIndex), mins_tmp(variableIndex))
+         maxes(variableIndex) = max(maxes(variableIndex), maxes_tmp(variableIndex))
+         verticalSumMins(variableIndex) = min(verticalSumMins(variableIndex), verticalSumMins_tmp(variableIndex))
+         verticalSumMaxes(variableIndex) = max(verticalSumMaxes(variableIndex), verticalSumMaxes_tmp(variableIndex))
 
-      ! pv_cell
-      variableIndex = variableIndex + 1
-      call ocn_compute_field_volume_weighted_local_stats(dminfo, nVertLevels, nCellsSolve, areaCell(1:nCellsSolve), h(:,1:nCellsSolve), &amp;
-        pv_cell(:,1:nCellsSolve), sums(variableIndex), mins(variableIndex), maxes(variableIndex), verticalSumMins(variableIndex), &amp;
-        verticalSumMaxes(variableIndex))
+         ! gradPVt
+         variableIndex = variableIndex + 1
+         call ocn_compute_field_volume_weighted_local_stats(dminfo, nVertLevels, nEdgesSolve, areaEdge(1:nEdgesSolve), h_edge(:,1:nEdgesSolve), &amp;
+            gradPVt(:,1:nEdgesSolve), sums_tmp(variableIndex), mins_tmp(variableIndex), maxes_tmp(variableIndex), verticalSumMins_tmp(variableIndex), &amp;
+            verticalSumMaxes_tmp(variableIndex))
+         sums(variableIndex) = sums(variableIndex) + sums_tmp(variableIndex)
+         mins(variableIndex) = min(mins(variableIndex), mins_tmp(variableIndex))
+         maxes(variableIndex) = max(maxes(variableIndex), maxes_tmp(variableIndex))
+         verticalSumMins(variableIndex) = min(verticalSumMins(variableIndex), verticalSumMins_tmp(variableIndex))
+         verticalSumMaxes(variableIndex) = max(verticalSumMaxes(variableIndex), verticalSumMaxes_tmp(variableIndex))
 
-      ! gradPVn
-      variableIndex = variableIndex + 1
-      call ocn_compute_field_volume_weighted_local_stats(dminfo, nVertLevels, nEdgesSolve, areaEdge(1:nEdgesSolve), h_edge(:,1:nEdgesSolve), &amp;
-        gradPVn(:,1:nEdgesSolve), sums(variableIndex), mins(variableIndex), maxes(variableIndex), verticalSumMins(variableIndex), &amp;
-        verticalSumMaxes(variableIndex))
+         ! pressure
+         variableIndex = variableIndex + 1
+         call ocn_compute_field_volume_weighted_local_stats(dminfo, nVertLevels, nCellsSolve, areaCell(1:nCellsSolve), h(:,1:nCellsSolve), &amp;
+            pressure(:,1:nCellsSolve), sums_tmp(variableIndex), mins_tmp(variableIndex), maxes_tmp(variableIndex), verticalSumMins_tmp(variableIndex), &amp;
+            verticalSumMaxes_tmp(variableIndex))
+         sums(variableIndex) = sums(variableIndex) + sums_tmp(variableIndex)
+         mins(variableIndex) = min(mins(variableIndex), mins_tmp(variableIndex))
+         maxes(variableIndex) = max(maxes(variableIndex), maxes_tmp(variableIndex))
+         verticalSumMins(variableIndex) = min(verticalSumMins(variableIndex), verticalSumMins_tmp(variableIndex))
+         verticalSumMaxes(variableIndex) = max(verticalSumMaxes(variableIndex), verticalSumMaxes_tmp(variableIndex))
 
-      ! gradPVt
-      variableIndex = variableIndex + 1
-      call ocn_compute_field_volume_weighted_local_stats(dminfo, nVertLevels, nEdgesSolve, areaEdge(1:nEdgesSolve), h_edge(:,1:nEdgesSolve), &amp;
-        gradPVt(:,1:nEdgesSolve), sums(variableIndex), mins(variableIndex), maxes(variableIndex), verticalSumMins(variableIndex), &amp;
-        verticalSumMaxes(variableIndex))
+         ! MontPot
+         variableIndex = variableIndex + 1
+         call ocn_compute_field_volume_weighted_local_stats(dminfo, nVertLevels, nCellsSolve, areaCell(1:nCellsSolve), h(:,1:nCellsSolve), &amp;
+            MontPot(:,1:nCellsSolve), sums_tmp(variableIndex), mins_tmp(variableIndex), maxes_tmp(variableIndex), verticalSumMins_tmp(variableIndex), &amp;
+            verticalSumMaxes_tmp(variableIndex))
+         sums(variableIndex) = sums(variableIndex) + sums_tmp(variableIndex)
+         mins(variableIndex) = min(mins(variableIndex), mins_tmp(variableIndex))
+         maxes(variableIndex) = max(maxes(variableIndex), maxes_tmp(variableIndex))
+         verticalSumMins(variableIndex) = min(verticalSumMins(variableIndex), verticalSumMins_tmp(variableIndex))
+         verticalSumMaxes(variableIndex) = max(verticalSumMaxes(variableIndex), verticalSumMaxes_tmp(variableIndex))
 
-      ! pressure
-      variableIndex = variableIndex + 1
-      call ocn_compute_field_volume_weighted_local_stats(dminfo, nVertLevels, nCellsSolve, areaCell(1:nCellsSolve), h(:,1:nCellsSolve), &amp;
-        pressure(:,1:nCellsSolve), sums(variableIndex), mins(variableIndex), maxes(variableIndex), verticalSumMins(variableIndex), &amp;
-        verticalSumMaxes(variableIndex))
+         ! wTop vertical velocity
+         variableIndex = variableIndex + 1
+         call ocn_compute_field_volume_weighted_local_stats(dminfo, nVertLevels+1, nCellsSolve, areaCell(1:nCellsSolve), h(:,1:nCellsSolve), &amp;
+            wTop(:,1:nCellsSolve), sums_tmp(variableIndex), mins_tmp(variableIndex), maxes_tmp(variableIndex), verticalSumMins_tmp(variableIndex), &amp;
+            verticalSumMaxes_tmp(variableIndex))
+         sums(variableIndex) = sums(variableIndex) + sums_tmp(variableIndex)
+         mins(variableIndex) = min(mins(variableIndex), mins_tmp(variableIndex))
+         maxes(variableIndex) = max(maxes(variableIndex), maxes_tmp(variableIndex))
+         verticalSumMins(variableIndex) = min(verticalSumMins(variableIndex), verticalSumMins_tmp(variableIndex))
+         verticalSumMaxes(variableIndex) = max(verticalSumMaxes(variableIndex), verticalSumMaxes_tmp(variableIndex))
 
-      ! MontPot
-      variableIndex = variableIndex + 1
-      call ocn_compute_field_volume_weighted_local_stats(dminfo, nVertLevels, nCellsSolve, areaCell(1:nCellsSolve), h(:,1:nCellsSolve), &amp;
-        MontPot(:,1:nCellsSolve), sums(variableIndex), mins(variableIndex), maxes(variableIndex), verticalSumMins(variableIndex), &amp;
-        verticalSumMaxes(variableIndex))
+         ! Tracers
+         allocate(tracerTemp(nVertLevels,nCellsSolve))
+         do iTracer=1,num_tracers
+            variableIndex = variableIndex + 1
+            tracerTemp = Tracers(iTracer,:,1:nCellsSolve)
+            call ocn_compute_field_volume_weighted_local_stats(dminfo, nVertLevels, nCellsSolve, areaCell(1:nCellsSolve), h(:,1:nCellsSolve), &amp;
+               tracerTemp, sums_tmp(variableIndex), mins_tmp(variableIndex), maxes_tmp(variableIndex), verticalSumMins_tmp(variableIndex), &amp;
+               verticalSumMaxes_tmp(variableIndex))
+            sums(variableIndex) = sums(variableIndex) + sums_tmp(variableIndex)
+            mins(variableIndex) = min(mins(variableIndex), mins_tmp(variableIndex))
+            maxes(variableIndex) = max(maxes(variableIndex), maxes_tmp(variableIndex))
+            verticalSumMins(variableIndex) = min(verticalSumMins(variableIndex), verticalSumMins_tmp(variableIndex))
+            verticalSumMaxes(variableIndex) = max(verticalSumMaxes(variableIndex), verticalSumMaxes_tmp(variableIndex))
+         enddo
+         deallocate(tracerTemp)
 
-      ! wTop vertical velocity
-      variableIndex = variableIndex + 1
-      call ocn_compute_field_volume_weighted_local_stats(dminfo, nVertLevels+1, nCellsSolve, areaCell(1:nCellsSolve), h(:,1:nCellsSolve), &amp;
-        wTop(:,1:nCellsSolve), sums(variableIndex), mins(variableIndex), maxes(variableIndex), verticalSumMins(variableIndex), &amp;
-        verticalSumMaxes(variableIndex))
+         nVariables = variableIndex
+         nSums = nVariables
+         nMins = nVariables
+         nMaxes = nVariables
 
-      ! Tracers
-      allocate(tracerTemp(nVertLevels,nCellsSolve))
-      do iTracer=1,num_tracers
-        variableIndex = variableIndex + 1
-        tracerTemp = Tracers(iTracer,:,1:nCellsSolve)
-        call ocn_compute_field_volume_weighted_local_stats(dminfo, nVertLevels, nCellsSolve, areaCell(1:nCellsSolve), h(:,1:nCellsSolve), &amp;
-          tracerTemp, sums(variableIndex), mins(variableIndex), maxes(variableIndex), verticalSumMins(variableIndex), &amp;
-          verticalSumMaxes(variableIndex))
-      enddo
-      deallocate(tracerTemp)
+         nSums = nSums + 1
+         sums(nSums) = sums(nSums) + sum(areaCell(1:nCellsSolve))
 
-      nVariables = variableIndex
-      nSums = nVariables
-      nMins = nVariables
-      nMaxes = nVariables
+         nSums = nSums + 1
+         sums(nSums) = sums(nSums) + sum(dcEdge(1:nEdgesSolve)*dvEdge(1:nEdgesSolve))
 
-      nSums = nSums + 1
-      sums(nSums) = sum(areaCell(1:nCellsSolve))
+         nSums = nSums + 1
+         sums(nSums) = sums(nSums) + sum(areaTriangle(1:nVerticesSolve))
 
-      nSums = nSums + 1
-      sums(nSums) = sum(dcEdge(1:nEdgesSolve)*dvEdge(1:nEdgesSolve))
+         nSums = nSums + 1
+         sums(nSums) = sums(nSums) + nCellsSolve
 
-      nSums = nSums + 1
-      sums(nSums) = sum(areaTriangle(1:nVerticesSolve))
+         nSums = nSums + 1
+         sums(nSums) = sums(nSums) + nEdgesSolve
 
-      nSums = nSums + 1
-      sums(nSums) = nCellsSolve
+         nSums = nSums + 1
+         sums(nSums) = sums(nSums) + nVerticesSolve
 
-      nSums = nSums + 1
-      sums(nSums) = nEdgesSolve
+         localCFL = 0.0
+         do elementIndex = 1,nEdgesSolve
+            localCFL = max(localCFL, maxval(dt*u(:,elementIndex)/dcEdge(elementIndex)))
+         end do
+         nMaxes = nMaxes + 1
+         maxes(nMaxes) = localCFL
 
-      nSums = nSums + 1
-      sums(nSums) = nVerticesSolve
+         do i = 1, nVariables
+            mins(nMins+i) = min(mins(nMins+i),verticalSumMins_tmp(i))
+            maxes(nMaxes+i) = max(maxes(nMaxes+i),verticalSumMaxes_tmp(i))
+         end do
 
-      localCFL = 0.0
-      do elementIndex = 1,nEdgesSolve
-         localCFL = max(localCFL, maxval(dt*u(:,elementIndex)/dcEdge(elementIndex)))
+         nMins = nMins + nVariables
+         nMaxes = nMaxes + nVariables
+
+         block =&gt; block % next
       end do
-      nMaxes = nMaxes + 1
-      maxes(nMaxes) = localCFL
+      call mpas_timer_stop(&quot;diagnostic block loop&quot;, diagBlockTimer)
+      call mpas_timer_start(&quot;diagnostics mpi&quot;, .false., diagMPITimer)
 
-      mins(nMins+1:nMins+nVariables) = verticalSumMins(1:nVariables)
-      nMins = nMins + nVariables
-      maxes(nMaxes+1:nMaxes+nVariables) = verticalSumMaxes(1:nVariables)
-      nMaxes = nMaxes + nVariables
-
       ! global reduction of the 5 arrays (packed into 3 to minimize global communication)
       call mpas_dmpar_sum_real_array(dminfo, nSums, sums(1:nSums), reductions(1:nSums))
       sums(1:nVariables) = reductions(1:nVariables)
@@ -306,6 +412,8 @@
         averages(variableIndex) = sums(variableIndex)/volumeCellGlobal
       enddo
 
+      call mpas_timer_stop(&quot;diagnostics mpi&quot;, diagMPITimer)
+
       ! write out the data to files
       if (dminfo % my_proc_id == IO_NODE) then
          fileID = getFreeUnit()
@@ -322,7 +430,7 @@
             write (fileID,'(100es24.14)') averages(1:nVariables)
          close (fileID)
          open(fileID,file='stats_time.txt',ACCESS='append')
-            write (fileID,'(i5,10x,a,100es24.14)') timeIndex, &amp;
+            write (fileID,'(i10,10x,a,100es24.14)') timeIndex, &amp;
                state % xtime % scalar, dt, &amp;
                CFLNumberGlobal
          close (fileID)
@@ -343,9 +451,9 @@
       state % CFLNumberGlobal % scalar = CFLNumberGlobal
       deallocate(areaEdge)
 
-   end subroutine ocn_compute_global_diagnostics
+   end subroutine ocn_compute_global_diagnostics!}}}
 
-   integer function getFreeUnit()
+   integer function getFreeUnit()!{{{
       implicit none
 
       integer :: index
@@ -361,9 +469,9 @@
             end if
          end if
       end do
-   end function getFreeUnit
+   end function getFreeUnit!}}}
 
-   subroutine ocn_compute_field_local_stats(dminfo, nVertLevels, nElements, field, localSum, localMin, localMax, localVertSumMin, &amp;
+   subroutine ocn_compute_field_local_stats(dminfo, nVertLevels, nElements, field, localSum, localMin, localMax, localVertSumMin, &amp;!{{{
       localVertSumMax)
 
       implicit none
@@ -380,9 +488,9 @@
       localVertSumMin = minval(sum(field,1))
       localVertSumMax = maxval(sum(field,1))
 
-   end subroutine ocn_compute_field_local_stats
+   end subroutine ocn_compute_field_local_stats!}}}
 
-   subroutine ocn_compute_field_area_weighted_local_stats(dminfo, nVertLevels, nElements, areas, field, localSum, localMin, &amp;
+   subroutine ocn_compute_field_area_weighted_local_stats(dminfo, nVertLevels, nElements, areas, field, localSum, localMin, &amp;!{{{
       localMax, localVertSumMin, localVertSumMax)
 
       implicit none
@@ -406,9 +514,9 @@
       localVertSumMin = minval(sum(field,1))
       localVertSumMax = maxval(sum(field,1))
 
-   end subroutine ocn_compute_field_area_weighted_local_stats
+   end subroutine ocn_compute_field_area_weighted_local_stats!}}}
 
-   subroutine ocn_compute_field_thickness_weighted_local_stats(dminfo, nVertLevels, nElements, h, field, &amp;
+   subroutine ocn_compute_field_thickness_weighted_local_stats(dminfo, nVertLevels, nElements, h, field, &amp;!{{{
       localSum, localMin, localMax, localVertSumMin, localVertSumMax)
 
       implicit none
@@ -430,9 +538,9 @@
       localVertSumMin = minval(sum(h*field,1))
       localVertSumMax = maxval(sum(h*field,1))
 
-   end subroutine ocn_compute_field_thickness_weighted_local_stats
+   end subroutine ocn_compute_field_thickness_weighted_local_stats!}}}
 
-   subroutine ocn_compute_field_volume_weighted_local_stats(dminfo, nVertLevels, nElements, areas, h, field, &amp;
+   subroutine ocn_compute_field_volume_weighted_local_stats(dminfo, nVertLevels, nElements, areas, h, field, &amp;!{{{
       localSum, localMin, localMax, localVertSumMin, localVertSumMax)
 
       implicit none
@@ -459,11 +567,10 @@
       localVertSumMin = minval(sum(h*field,1))
       localVertSumMax = maxval(sum(h*field,1))
 
-   end subroutine ocn_compute_field_volume_weighted_local_stats
+   end subroutine ocn_compute_field_volume_weighted_local_stats!}}}
 
+   subroutine ocn_compute_global_sum(dminfo, nVertLevels, nElements, field, globalSum)!{{{
 
-   subroutine ocn_compute_global_sum(dminfo, nVertLevels, nElements, field, globalSum)
-
       implicit none
 
       type (dm_info), intent(in) :: dminfo
@@ -476,9 +583,9 @@
       localSum = sum(field)
       call mpas_dmpar_sum_real(dminfo, localSum, globalSum)
 
-   end subroutine ocn_compute_global_sum
+   end subroutine ocn_compute_global_sum!}}}
 
-   subroutine ocn_compute_area_weighted_global_sum(dminfo, nVertLevels, nElements, areas, field, globalSum)
+   subroutine ocn_compute_area_weighted_global_sum(dminfo, nVertLevels, nElements, areas, field, globalSum)!{{{
 
       implicit none
 
@@ -498,9 +605,9 @@
    
       call mpas_dmpar_sum_real(dminfo, localSum, globalSum)
        
-   end subroutine ocn_compute_area_weighted_global_sum
+   end subroutine ocn_compute_area_weighted_global_sum!}}}
 
-   subroutine ocn_compute_volume_weighted_global_sum(dminfo, nVertLevels, nElements, areas, h, field, globalSum)
+   subroutine ocn_compute_volume_weighted_global_sum(dminfo, nVertLevels, nElements, areas, h, field, globalSum)!{{{
 
       implicit none
 
@@ -517,9 +624,9 @@
 
       call ocn_compute_area_weighted_global_sum(dminfo, nVertLevels, nElements, areas, hTimesField, globalSum)
 
-   end subroutine ocn_compute_volume_weighted_global_sum
+   end subroutine ocn_compute_volume_weighted_global_sum!}}}
 
-   subroutine ocn_compute_global_min(dminfo, nVertLevels, nElements, field, globalMin)
+   subroutine ocn_compute_global_min(dminfo, nVertLevels, nElements, field, globalMin)!{{{
 
       implicit none
 
@@ -533,9 +640,9 @@
       localMin = minval(field)
       call mpas_dmpar_min_real(dminfo, localMin, globalMin)
 
-   end subroutine ocn_compute_global_min
+   end subroutine ocn_compute_global_min!}}}
 
-   subroutine ocn_compute_global_max(dminfo, nVertLevels, nElements, field, globalMax)
+   subroutine ocn_compute_global_max(dminfo, nVertLevels, nElements, field, globalMax)!{{{
 
       implicit none
 
@@ -549,9 +656,9 @@
       localMax = maxval(field)
       call mpas_dmpar_max_real(dminfo, localMax, globalMax)
 
-   end subroutine ocn_compute_global_max
+   end subroutine ocn_compute_global_max!}}}
 
-   subroutine ocn_compute_global_vert_sum_horiz_min(dminfo, nVertLevels, nElements, field, globalMin)
+   subroutine ocn_compute_global_vert_sum_horiz_min(dminfo, nVertLevels, nElements, field, globalMin)!{{{
 
       implicit none
 
@@ -565,9 +672,9 @@
       localMin = minval(sum(field,1))
       call mpas_dmpar_min_real(dminfo, localMin, globalMin)
 
-   end subroutine ocn_compute_global_vert_sum_horiz_min
+   end subroutine ocn_compute_global_vert_sum_horiz_min!}}}
 
-   subroutine ocn_compute_global_vert_sum_horiz_max(dminfo, nVertLevels, nElements, field, globalMax)
+   subroutine ocn_compute_global_vert_sum_horiz_max(dminfo, nVertLevels, nElements, field, globalMax)!{{{
 
       implicit none
 
@@ -581,9 +688,9 @@
       localMax = maxval(sum(field,1))
       call mpas_dmpar_max_real(dminfo, localMax, globalMax)
 
-   end subroutine ocn_compute_global_vert_sum_horiz_max
+   end subroutine ocn_compute_global_vert_sum_horiz_max!}}}
 
-   subroutine ocn_compute_global_vert_thickness_weighted_sum_horiz_min(dminfo, nVertLevels, nElements, h, field, globalMin)
+   subroutine ocn_compute_global_vert_thickness_weighted_sum_horiz_min(dminfo, nVertLevels, nElements, h, field, globalMin)!{{{
 
       implicit none
 
@@ -597,9 +704,9 @@
       localMin = minval(sum(h*field,1))
       call mpas_dmpar_min_real(dminfo, localMin, globalMin)
 
-   end subroutine ocn_compute_global_vert_thickness_weighted_sum_horiz_min
+   end subroutine ocn_compute_global_vert_thickness_weighted_sum_horiz_min!}}}
 
-   subroutine ocn_compute_global_vert_thickness_weighted_sum_horiz_max(dminfo, nVertLevels, nElements, h, field, globalMax)
+   subroutine ocn_compute_global_vert_thickness_weighted_sum_horiz_max(dminfo, nVertLevels, nElements, h, field, globalMax)!{{{
 
       implicit none
 
@@ -613,6 +720,6 @@
       localMax = maxval(sum(h*field,1))
       call mpas_dmpar_max_real(dminfo, localMax, globalMax)
 
-   end subroutine ocn_compute_global_vert_thickness_weighted_sum_horiz_max
+   end subroutine ocn_compute_global_vert_thickness_weighted_sum_horiz_max!}}}
 
 end module ocn_global_diagnostics

Modified: branches/atmos_physics/src/core_ocean/mpas_ocn_mpas_core.F
===================================================================
--- branches/atmos_physics/src/core_ocean/mpas_ocn_mpas_core.F        2012-02-27 22:31:30 UTC (rev 1537)
+++ branches/atmos_physics/src/core_ocean/mpas_ocn_mpas_core.F        2012-02-27 22:33:23 UTC (rev 1538)
@@ -1,10 +1,12 @@
 module mpas_core
 
+   use mpas_configure
    use mpas_framework
    use mpas_timekeeping
    use mpas_dmpar
    use mpas_timer
 
+   use ocn_global_diagnostics
    use ocn_test_cases
    use ocn_time_integration
    use ocn_tendency
@@ -35,11 +37,13 @@
    integer, parameter :: restartAlarmID = 2
    integer, parameter :: statsAlarmID = 3
 
+   type (timer_node), pointer :: globalDiagTimer, timeIntTimer
+   type (timer_node), pointer :: initDiagSolveTimer
+
    contains
 
    subroutine mpas_core_init(domain, startTimeStamp)!{{{
 
-      use mpas_configure
       use mpas_grid_types
 
       implicit none
@@ -81,6 +85,9 @@
       call ocn_equation_of_state_init(err_tmp)
       err = ior(err, err_tmp)
 
+      call ocn_tendency_init(err_tmp)
+      err = ior(err,err_tmp)
+
       call mpas_timer_init(domain)
 
       if(err.eq.1) then
@@ -89,58 +96,66 @@
 
       if (.not. config_do_restart) call setup_sw_test_case(domain)
 
-      call compute_maxLevel(domain)
+      call ocn_compute_max_level(domain)
 
-      if (config_vert_grid_type.eq.'isopycnal') then
-         print *, ' Using isopycnal coordinates'
-      elseif (config_vert_grid_type.eq.'zlevel') then
-         print *, ' Using z-level coordinates'
-         call init_ZLevel(domain)
-      else 
-         print *, ' Incorrect choice of config_vert_grid_type:',&amp;
-           config_vert_grid_type
+      call ocn_init_z_level(domain)
+
+      print *, ' Vertical grid type is: ',config_vert_grid_type
+
+      if (config_vert_grid_type.ne.'isopycnal'.and. &amp;
+          config_vert_grid_type.ne.'zlevel'.and. &amp;
+          config_vert_grid_type.ne.'zstar1'.and. &amp;
+          config_vert_grid_type.ne.'zstar'.and. &amp;
+          config_vert_grid_type.ne.'zstarWeights') then
+         print *, ' Incorrect choice of config_vert_grid_type.'
          call mpas_dmpar_abort(dminfo)
       endif
 
-      if (trim(config_new_btr_variables_from) == 'btr_avg' &amp;
-           .and.trim(config_time_integration) == 'unsplit_explicit') then
-         print *, ' unsplit_explicit option must use',&amp;
-           ' config_new_btr_variables_from==last_subcycle'
+      print *, ' Pressure type is: ',config_pressure_type
+      if (config_pressure_type.ne.'pressure'.and. &amp;
+          config_pressure_type.ne.'MontgomeryPotential') then
+         print *, ' Incorrect choice of config_pressure_type.'
          call mpas_dmpar_abort(dminfo)
       endif
 
+      if (config_filter_btr_mode.and. &amp;
+          config_vert_grid_type.ne.'zlevel')then
+         print *, 'filter_btr_mode has only been tested with'// &amp;
+            ' config_vert_grid_type=zlevel.'
+         call mpas_dmpar_abort(dminfo)
+      endif
+
       !
       ! Initialize core
       !
       dt = config_dt
 
-      call simulation_clock_init(domain, dt, startTimeStamp)
+      call ocn_simulation_clock_init(domain, dt, startTimeStamp)
 
       block =&gt; domain % blocklist
       do while (associated(block))
          call mpas_init_block(block, block % mesh, dt)
          block % state % time_levs(1) % state % xtime % scalar = startTimeStamp 
          block =&gt; block % next
-
-         !dwj 110919 This allows the restorings to grab the indices for
-         ! temperature and salinity tracers from state.
       end do
 
    ! mrp 100316 In order for this to work, we need to pass domain % dminfo as an 
    ! input arguement into mpas_init.  Ask about that later.  For now, there will be
    ! no initial statistics write.
    
-   !   call mpas_timer_start(&quot;global diagnostics&quot;)
-   !   call ocn_compute_global_diagnostics(domain % dminfo, block % state % time_levs(1) % state, mesh, 0, dt)
-   !   call mpas_timer_stop(&quot;global diagnostics&quot;)
-   !   call mpas_output_state_init(output_obj, domain, &quot;OUTPUT&quot;)
-   !   call write_output_frame(output_obj, domain)
+      if (config_initial_stats) then
+          call mpas_timer_start(&quot;global diagnostics&quot;, .false., globalDiagTimer)
+          call ocn_compute_global_diagnostics(domain, 1 , 0, dt)
+          call mpas_timer_stop(&quot;global diagnostics&quot;, globalDiagTimer)
+!         call mpas_output_state_init(output_obj, domain, &quot;OUTPUT&quot;)
+!         call ocn_write_output_frame(output_obj, output_frame, domain)
+      endif
 
       current_outfile_frames = 0
 
    end subroutine mpas_core_init!}}}
 
-   subroutine simulation_clock_init(domain, dt, startTimeStamp)!{{{
+   subroutine ocn_simulation_clock_init(domain, dt, startTimeStamp)!{{{
 
       implicit none
 
@@ -196,7 +211,7 @@
 
       call mpas_get_time(curr_time=startTime, dateTimeString=startTimeStamp, ierr=ierr)
 
-   end subroutine simulation_clock_init!}}}
+   end subroutine ocn_simulation_clock_init!}}}
 
    subroutine mpas_init_block(block, mesh, dt)!{{{
    
@@ -213,9 +228,13 @@
    
       call ocn_time_average_init(block % state % time_levs(1) % state)
    
+      call mpas_timer_start(&quot;diagnostic solve&quot;, .false., initDiagSolveTimer)
       call ocn_diagnostic_solve(dt, block % state % time_levs(1) % state, mesh)
+      call mpas_timer_stop(&quot;diagnostic solve&quot;, initDiagSolveTimer)
 
-      call compute_mesh_scaling(mesh)
+      call ocn_wtop(block % state % time_levs(1) % state,block % state % time_levs(1) % state, mesh)
+
+      call ocn_compute_mesh_scaling(mesh)
  
       call mpas_rbf_interp_initialize(mesh)
       call mpas_init_reconstruct(mesh)
@@ -231,6 +250,8 @@
       ! The reconstructed velocity on land will have values not exactly
       ! -1e34 due to the interpolation of reconstruction.
 
+      block % mesh % areaCell % array(block % mesh % nCells+1) = -1.0e34
+
       do iEdge=1,block % mesh % nEdges
          ! mrp 101115 note: in order to include flux boundary conditions, the following
          ! line will need to change.  Right now, set boundary edges between land and 
@@ -253,7 +274,7 @@
 !              :block % mesh % nVertLevels,iCell) =  -1e34
 
 ! mrp 110516, added just to test for conservation of tracers
-!         block % state % time_levs(1) % state % tracers % array(block % state % time_levs(1) % state % index_tracer1,:,iCell) = 1.0
+         block % state % time_levs(1) % state % tracers % array(block % state % time_levs(1) % state % index_tracer1,:,iCell) = 1.0
 
       end do
 
@@ -303,7 +324,7 @@
       call mpas_get_time(curr_time=currTime, dateTimeString=timeStamp, ierr=ierr)
       write(0,*) 'Initial time ', timeStamp
 
-      call write_output_frame(output_obj, output_frame, domain)
+      call ocn_write_output_frame(output_obj, output_frame, domain)
       block_ptr =&gt; domain % blocklist
 
       do while(associated(block_ptr))
@@ -323,9 +344,9 @@
          call mpas_get_time(curr_time=currTime, dateTimeString=timeStamp, ierr=ierr)
          write(0,*) 'Doing timestep ', timeStamp
 
-         call mpas_timer_start(&quot;time integration&quot;)
+         call mpas_timer_start(&quot;time integration&quot;, .false., timeIntTimer)
          call mpas_timestep(domain, itimestep, dt, timeStamp)
-         call mpas_timer_stop(&quot;time integration&quot;)
+         call mpas_timer_stop(&quot;time integration&quot;, timeIntTimer)
    
          ! Move time level 2 fields back into time level 1 for next time step
          call mpas_shift_time_levels_state(domain % blocklist % state)
@@ -343,7 +364,9 @@
                 call ocn_time_average_normalize(block_ptr % state % time_levs(1) % state)
                 block_ptr =&gt; block_ptr % next
             end do
-            call write_output_frame(output_obj, output_frame, domain)
+
+            call ocn_write_output_frame(output_obj, output_frame, domain)
+
             block_ptr =&gt; domain % blocklist
             do while (associated(block_ptr))
                 call ocn_time_average_init(block_ptr % state % time_levs(1) % state)
@@ -364,7 +387,7 @@
 
    end subroutine mpas_core_run!}}}
    
-   subroutine write_output_frame(output_obj, output_frame, domain)!{{{
+   subroutine ocn_write_output_frame(output_obj, output_frame, domain)!{{{
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    ! Compute diagnostic fields for a domain and write model state to output file
    !
@@ -387,7 +410,7 @@
    
       block_ptr =&gt; domain % blocklist
       do while (associated(block_ptr))
-         call compute_output_diagnostics(block_ptr % state % time_levs(1) % state, block_ptr % mesh)
+         call ocn_compute_output_diagnostics(block_ptr % state % time_levs(1) % state, block_ptr % mesh)
          block_ptr =&gt; block_ptr % next
       end do
    
@@ -403,9 +426,9 @@
          end if
       end if
    
-   end subroutine write_output_frame!}}}
+   end subroutine ocn_write_output_frame!}}}
    
-   subroutine compute_output_diagnostics(state, grid)!{{{
+   subroutine ocn_compute_output_diagnostics(state, grid)!{{{
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    ! Compute diagnostic fields for a domain
    !
@@ -425,13 +448,11 @@
       integer :: i, eoe
       integer :: iEdge, k
    
-   end subroutine compute_output_diagnostics!}}}
+   end subroutine ocn_compute_output_diagnostics!}}}
    
    subroutine mpas_timestep(domain, itimestep, dt, timeStamp)!{{{
    
       use mpas_grid_types
-      use mpas_timer
-      use ocn_global_diagnostics
    
       implicit none
    
@@ -447,17 +468,9 @@
 
       if (config_stats_interval &gt; 0) then
           if (mod(itimestep, config_stats_interval) == 0) then
-              block_ptr =&gt; domain % blocklist
-              if (associated(block_ptr % next)) then
-                  write(0,*) 'Error: computeGlobalDiagnostics assumes ',&amp;
-                     'that there is only one block per processor.'
-              end if
-
-          call mpas_timer_start(&quot;global diagnostics&quot;)
-          call ocn_compute_global_diagnostics(domain % dminfo, &amp;
-             block_ptr % state % time_levs(2) % state, block_ptr % mesh, &amp;
-             itimestep, dt)
-          call mpas_timer_stop(&quot;global diagnostics&quot;)
+             call mpas_timer_start(&quot;global diagnostics&quot;, .false., globalDiagTimer)
+             call ocn_compute_global_diagnostics(domain, 2, itimestep, dt);
+             call mpas_timer_stop(&quot;global diagnostics&quot;, globalDiagTimer)
           end if
       end if
 
@@ -480,76 +493,54 @@
 
    end subroutine mpas_timestep!}}}
 
-subroutine init_ZLevel(domain)!{{{
-! Initialize maxLevel and bouncary grid variables.
+   subroutine ocn_init_z_level(domain)!{{{
+   ! Initialize maxLevel and bouncary grid variables.
 
-   use mpas_grid_types
-   use mpas_configure
+      use mpas_grid_types
+      use mpas_configure
 
-   implicit none
+      implicit none
 
-   type (domain_type), intent(inout) :: domain
+      type (domain_type), intent(inout) :: domain
 
-   integer :: i, iCell, iEdge, iVertex, k
-   type (block_type), pointer :: block
+      integer :: i, iCell, iEdge, iVertex, k
+      type (block_type), pointer :: block
 
-   integer :: iTracer, cell, cell1, cell2
-   real (kind=RKIND) :: uhSum, hSum, sshEdge
-   real (kind=RKIND), dimension(:), pointer :: &amp;
-      hZLevel, zMidZLevel, zTopZLevel, &amp;
-      hMeanTopZLevel, hRatioZLevelK, hRatioZLevelKm1
-   real (kind=RKIND), dimension(:,:), pointer :: h
-   integer :: nVertLevels
+      integer :: iTracer, cell, cell1, cell2
+      real (kind=RKIND) :: uhSum, hSum, hEdge1
+      real (kind=RKIND), dimension(:), pointer :: &amp;
+         referenceBottomDepth, referenceBottomDepthTopOfCell
+      real (kind=RKIND), dimension(:,:), pointer :: h
+      integer :: nVertLevels
 
-   ! Initialize z-level grid variables from h, read in from input file.
-   block =&gt; domain % blocklist
-   do while (associated(block))
+      ! Initialize z-level grid variables from h, read in from input file.
+      block =&gt; domain % blocklist
+      do while (associated(block))
 
-      h          =&gt; block % state % time_levs(1) % state % h % array
-      hZLevel    =&gt; block % mesh % hZLevel % array
-      zMidZLevel =&gt; block % mesh % zMidZLevel % array
-      zTopZLevel =&gt; block % mesh % zTopZLevel % array
-      nVertLevels = block % mesh % nVertLevels
-      hMeanTopZLevel    =&gt; block % mesh % hMeanTopZLevel % array
-      hRatioZLevelK    =&gt; block % mesh % hRatioZLevelK % array
-      hRatioZLevelKm1    =&gt; block % mesh % hRatioZLevelKm1 % array
+         h          =&gt; block % state % time_levs(1) % state % h % array
+         referenceBottomDepth =&gt; block % mesh % referenceBottomDepth % array
+         referenceBottomDepthTopOfCell =&gt; block % mesh % referenceBottomDepthTopOfCell % array
+         nVertLevels = block % mesh % nVertLevels
 
-      ! These should eventually be in an input file.  For now
-      ! I just read them in from h(:,1).
-      ! Upon restart, the correct hZLevel should be in restart.nc
-      if (.not. config_do_restart) hZLevel = h(:,1)
+         ! mrp 120208 right now hZLevel is in the grid.nc file.
+         ! We would like to transition to using referenceBottomDepth
+         ! as the defining variable instead, and will transition soon.
+         ! When the transition is done, hZLevel can be removed from
+         ! registry and the following four lines deleted.
+         referenceBottomDepth(1) = block % mesh % hZLevel % array(1)
+         do k = 2,nVertLevels
+            referenceBottomDepth(k) = referenceBottomDepth(k-1) + block % mesh % hZLevel % array(k)
+         end do
 
-      ! hZLevel should be in the grid.nc and restart.nc file, 
-      ! and h for k=1 must be specified there as well.

-      zTopZLevel(1) = 0.0
-      do k = 1,nVertLevels
-         zMidZLevel(k) = zTopZLevel(k)-0.5*hZLevel(k)
-         zTopZLevel(k+1) = zTopZLevel(k)-  hZLevel(k)
-      end do
+         ! TopOfCell needed where zero depth for the very top may be referenced.
+         referenceBottomDepthTopOfCell(1) = 0.0
+         do k = 1,nVertLevels
+            referenceBottomDepthTopOfCell(k+1) = referenceBottomDepth(k)
+         end do
 
-      hMeanTopZLevel(1) = 0.0
-      hRatioZLevelK(1) = 0.0
-      hRatioZLevelKm1(1) = 0.0
-      do k = 2,nVertLevels
-         hMeanTopZLevel(k) = 0.5*(hZLevel(k-1) + hZLevel(k))
-         hRatioZLevelK(k) = 0.5*hZLevel(k)/hMeanTopZLevel(k)
-         hRatioZLevelKm1(k) = 0.5*hZLevel(k-1)/hMeanTopZLevel(k)
-      end do
-
-      ! mrp 110601 For now, h is the variable saved in the restart file
-      ! I am computing SSH here.  In the future, could make smaller 
-      ! restart files for z-Level runs by saving SSH only.
-      do iCell=1,block % mesh % nCells
-
-          block % state % time_levs(1) % state % ssh % array(iCell) &amp; 
-        = block % state % time_levs(1) % state % h % array(1,iCell) &amp; 
-        - block % mesh % hZLevel % array(1)
-      enddo
-
          ! Compute barotropic velocity at first timestep
          ! This is only done upon start-up.
-         if     (trim(config_time_integration) == 'unsplit_explicit') then
+         if (trim(config_time_integration) == 'unsplit_explicit') then
             block % state % time_levs(1) % state % uBtr % array(:) = 0.0
 
               block % state % time_levs(1) % state % uBcl % array(:,:) &amp;
@@ -560,9 +551,7 @@
             if (config_filter_btr_mode) then
                do iCell=1,block % mesh % nCells
                   block % state % time_levs(1) % state % h % array(1,iCell) &amp; 
-                = block % mesh % hZLevel % array(1)

-                  block % state % time_levs(1) % state % ssh % array(iCell) = 0.0
+                = block % mesh % referenceBottomDepth % array(1)
                enddo
             endif 
 
@@ -570,21 +559,30 @@
                cell1 = block % mesh % cellsOnEdge % array(1,iEdge)
                cell2 = block % mesh % cellsOnEdge % array(2,iEdge)
 
-               sshEdge = 0.5*( &amp;
-                   block % state % time_levs(1) % state % ssh % array(cell1) &amp; 
-                 + block % state % time_levs(1) % state % ssh % array(cell2) ) 
-
                ! uBtr = sum(u)/sum(h) on each column
-               uhSum = (sshEdge + block % mesh % hZLevel % array(1)) &amp;
-                  * block % state % time_levs(1) % state % u % array(1,iEdge)
-               hSum = sshEdge + block % mesh % hZLevel % array(1)
+               ! ocn_diagnostic_solve has not yet been called, so compute hEdge 
+               ! just for this edge.
 
+               ! hSum is initialized outside the loop because on land boundaries 
+               ! maxLevelEdgeTop=0, but I want to initialize hSum with a 
+               ! nonzero value to avoid a NaN.
+               hEdge1 = 0.5*( &amp;
+                   block % state % time_levs(1) % state % h % array(1,cell1) &amp; 
+                 + block % state % time_levs(1) % state % h % array(1,cell2) ) 
+               uhSum = hEdge1*block % state % time_levs(1) % state % u % array(1,iEdge)
+               hSum = hEdge1
+
                do k=2,block % mesh % maxLevelEdgeTop % array(iEdge)
+                  ! ocn_diagnostic_solve has not yet been called, so compute hEdge 
+                  ! just for this edge.
+                  hEdge1 = 0.5*( &amp;
+                      block % state % time_levs(1) % state % h % array(k,cell1) &amp; 
+                    + block % state % time_levs(1) % state % h % array(k,cell2) ) 
+
                   uhSum = uhSum &amp;
-                     + block % mesh % hZLevel % array(k) &amp;
-                      *block % state % time_levs(1) % state % u % array(k,iEdge)
-                  hSum = hSum &amp;
-                     + block % mesh % hZLevel % array(k)
+                     + hEdge1*block % state % time_levs(1) % state % u % array(k,iEdge)
+                  hSum = hSum + hEdge1
+
                enddo
                block % state % time_levs(1) % state % uBtr % array(iEdge) = uhSum/hsum
 
@@ -612,39 +610,12 @@
 
          endif
 
-!print *, '11 u ',minval(domain % blocklist % state % time_levs(1) % state % u % array(:,1:domain % blocklist % mesh % nEdgesSolve)), &amp;
-!                maxval(domain % blocklist % state % time_levs(1) % state % u % array(:,1:domain % blocklist % mesh % nEdgesSolve))
-!print *, '11 uBtr ',minval(domain % blocklist % state % time_levs(1) % state % uBtr % array(1:domain % blocklist % mesh % nEdgesSolve)), &amp;
-!                    maxval(domain % blocklist % state % time_levs(1) % state % uBtr % array(1:domain % blocklist % mesh % nEdgesSolve))
-!print *, '11 uBcl ',minval(domain % blocklist % state % time_levs(1) % state % uBcl % array(:,1:domain % blocklist % mesh % nEdgesSolve)), &amp;
-!                    maxval(domain % blocklist % state % time_levs(1) % state % uBcl % array(:,1:domain % blocklist % mesh % nEdgesSolve))
-
-
-! mrp temp testing - is uBcl vert sum zero?
-!            do iEdge=1,block % mesh % nEdges
-!              uhSum = (sshEdge + block % mesh % hZLevel % array(1)) * block % state % time_levs(1) % state % uBcl % array(1,iEdge)
-!              hSum  =  sshEdge + block % mesh % hZLevel % array(1)
-
-!              do k=2,block % mesh % maxLevelEdgeTop % array(iEdge)
-!                 uhSum = uhSum + block % mesh % hZLevel % array(k) *  block % state % time_levs(1) % state % uBcl % array(k,iEdge)
-!                 hSum  =  hSum + block % mesh % hZLevel % array(k)
-!              enddo
-!              block % state % time_levs(1) % state % FBtr % array(iEdge) = uhSum/hSum
-
-!           enddo ! iEdge
-
-!print *, 'uBcl vert sum IC',minval(block % state % time_levs(1) % state % FBtr % array(1:block % mesh % nEdgesSolve)), &amp;
-!                            maxval(block % state % time_levs(1) % state % FBtr % array(1:block % mesh % nEdgesSolve))
-
-! mrp temp testing - is uBcl vert sum zero? end
-
       block =&gt; block % next
+      end do
 
-   end do
+   end subroutine ocn_init_z_level!}}}
 
-end subroutine init_ZLevel!}}}
-
-subroutine compute_maxLevel(domain)!{{{
+subroutine ocn_compute_max_level(domain)!{{{
 ! Initialize maxLevel and bouncary grid variables.
 
    use mpas_grid_types
@@ -669,7 +640,7 @@
       maxLevelVertexTop, maxLevelVertexBot
    integer, dimension(:,:), pointer :: &amp;
       cellsOnEdge, cellsOnVertex, boundaryEdge, boundaryCell, &amp;
-      boundaryVertex, verticesOnEdge
+      boundaryVertex, verticesOnEdge, edgeMask, cellMask, vertexMask
 
    ! Initialize z-level grid variables from h, read in from input file.
    block =&gt; domain % blocklist
@@ -686,6 +657,9 @@
       boundaryEdge   =&gt; block % mesh % boundaryEdge % array
       boundaryCell   =&gt; block % mesh % boundaryCell % array
       boundaryVertex =&gt; block % mesh % boundaryVertex % array
+      edgeMask =&gt; block % mesh % edgeMask % array
+      cellMask =&gt; block % mesh % cellMask % array
+      vertexMask =&gt; block % mesh % vertexMask % array
 
       nCells      = block % mesh % nCells
       nEdges      = block % mesh % nEdges
@@ -739,22 +713,31 @@
       maxLevelVertexTop(nVertices+1) = 0
 
       ! set boundary edge
-      boundaryEdge=1
+      boundaryEdge(:,1:nEdges+1)=1
+      edgeMask(:,1:nEdges+1)=0
       do iEdge=1,nEdges
          boundaryEdge(1:maxLevelEdgeTop(iEdge),iEdge)=0
+         edgeMask(1:maxLevelEdgeTop(iEdge),iEdge)=1
       end do 
 
       !
       ! Find cells and vertices that have an edge on the boundary
       !
-      boundaryCell(:,:) = 0
+      boundaryCell(:,1:nCells+1) = 0
+      cellMask(:,1:nCells+1) = 1
+      boundaryVertex(:,1:nVertices+1) = 0
+      vertexMask(:,1:nVertices+1) = 1
       do iEdge=1,nEdges
          do k=1,nVertLevels
             if (boundaryEdge(k,iEdge).eq.1) then
                boundaryCell(k,cellsOnEdge(1,iEdge)) = 1
                boundaryCell(k,cellsOnEdge(2,iEdge)) = 1
+               cellMask(k,cellsOnEdge(1,iEdge)) = 0
+               cellMask(k,cellsOnEdge(2,iEdge)) = 0
                boundaryVertex(k,verticesOnEdge(1,iEdge)) = 1
                boundaryVertex(k,verticesOnEdge(2,iEdge)) = 1
+               vertexMask(k,verticesOnEdge(1,iEdge)) = 0
+               vertexMask(k,verticesOnEdge(2,iEdge)) = 0
             endif
          end do
       end do
@@ -765,7 +748,7 @@
    ! Note: We do not update halos on maxLevel* variables.  I want the
    ! outside edge of a halo to be zero on each processor.
 
-end subroutine compute_maxLevel!}}}
+end subroutine ocn_compute_max_level!}}}
    
    subroutine mpas_core_finalize(domain)!{{{
    
@@ -780,7 +763,7 @@
 
    end subroutine mpas_core_finalize!}}}
 
-   subroutine compute_mesh_scaling(mesh)!{{{
+   subroutine ocn_compute_mesh_scaling(mesh)!{{{
 
       use mpas_grid_types
       use mpas_configure
@@ -810,7 +793,7 @@
          end do
       end if
 
-   end subroutine compute_mesh_scaling!}}}
+   end subroutine ocn_compute_mesh_scaling!}}}
 
 end module mpas_core
 

Modified: branches/atmos_physics/src/core_ocean/mpas_ocn_restoring.F
===================================================================
--- branches/atmos_physics/src/core_ocean/mpas_ocn_restoring.F        2012-02-27 22:31:30 UTC (rev 1537)
+++ branches/atmos_physics/src/core_ocean/mpas_ocn_restoring.F        2012-02-27 22:33:23 UTC (rev 1538)
@@ -111,6 +111,7 @@
       integer :: iCell, nCellsSolve, k
 
       real (kind=RKIND), dimension(:), pointer :: temperatureRestore, salinityRestore
+      real (kind=RKIND) :: invTemp, invSalinity
 
       err = 0
 
@@ -121,17 +122,14 @@
       temperatureRestore =&gt; grid % temperatureRestore % array
       salinityRestore =&gt; grid % salinityRestore % array
 
+      invTemp = 1.0 / (temperatureTimeScale * 86400.0)
+      invSalinity = 1.0 / (salinityTimeScale * 86400.0)
+
       k = 1  ! restoring only in top layer
       do iCell=1,nCellsSolve
+        tend(indexT, k, iCell) = tend(indexT, k, iCell) - h(k,iCell)*(tracers(indexT, k, iCell) - temperatureRestore(iCell)) * invTemp
+        tend(indexS, k, iCell) = tend(indexS, k, iCell) - h(k,iCell)*(tracers(indexS, k, iCell) - salinityRestore(iCell)) * invSalinity
 
-        tend(indexT, k, iCell) = tend(indexT, k, iCell)  &amp;
-             - h(k,iCell)*(tracers(indexT, k, iCell) - temperatureRestore(iCell)) &amp;
-             / (temperatureTimeScale * 86400.0)
-
-        tend(indexS, k, iCell) = tend(indexS, k, iCell)  &amp;
-             - h(k,iCell)*(tracers(indexS, k, iCell) - salinityRestore(iCell)) &amp;
-             / (salinityTimeScale * 86400.0)
-
 !       write(6,10) iCell, tracers(indexT, k, iCell), &amp;
 !              temperatureRestore(iCell), tracers(indexT, k, iCell), &amp;
 !             (tracers(indexT, k, iCell) - temperatureRestore(iCell)) &amp;

Modified: branches/atmos_physics/src/core_ocean/mpas_ocn_tendency.F
===================================================================
--- branches/atmos_physics/src/core_ocean/mpas_ocn_tendency.F        2012-02-27 22:31:30 UTC (rev 1537)
+++ branches/atmos_physics/src/core_ocean/mpas_ocn_tendency.F        2012-02-27 22:33:23 UTC (rev 1538)
@@ -44,6 +44,11 @@
    private
    save
 
+   type (timer_node), pointer :: diagEOSTimer
+   type (timer_node), pointer :: thickHadvTimer, thickVadvTimer
+   type (timer_node), pointer :: velCorTimer, velVadvTimer, velPgradTimer, velHmixTimer, velForceTimer, velExpVmixTimer
+   type (timer_node), pointer :: tracerHadvTimer, tracerVadvTimer, tracerHmixTimer, tracerExpVmixTimer, tracerRestoringTimer
+
    !--------------------------------------------------------------------
    !
    ! Public parameters
@@ -61,7 +66,8 @@
              ocn_tend_scalar, &amp;
              ocn_diagnostic_solve, &amp;
              ocn_wtop, &amp;
-             ocn_fuperp
+             ocn_fuperp, &amp;
+             ocn_tendency_init
 
    !--------------------------------------------------------------------
    !
@@ -69,7 +75,11 @@
    !
    !--------------------------------------------------------------------
 
+   integer :: hadv2nd, hadv3rd, hadv4th
+   integer :: ke_cell_flag, ke_vertex_flag
+   real (kind=RKIND) ::  coef_3rd_order, fCoef
 
+
 !***********************************************************************
 
 contains
@@ -104,83 +114,18 @@
       type (diagnostics_type), intent(in) :: d
       type (mesh_type), intent(in) :: grid
 
-      integer :: iEdge, iCell, iVertex, k, cell1, cell2, &amp;
-        vertex1, vertex2, eoe, i, j, err
+      real (kind=RKIND), dimension(:,:), pointer :: h_edge, u, wTop, tend_h
 
-! mrp 110512 I just split compute_tend into compute_tend_u and ocn_tend_h.
-!  Most of these variables can be removed, but at a later time.
-      integer :: nCells, nEdges, nVertices, nVertLevels, nEdgesSolve
-      real (kind=RKIND) :: flux, vorticity_abs, h_vertex, workpv, q, &amp;
-        upstream_bias, wTopEdge, rho0Inv, r
-      real (kind=RKIND), dimension(:), pointer :: &amp;
-        h_s, fVertex, fEdge, dvEdge, dcEdge, areaCell, areaTriangle, &amp;
-        zMidZLevel, zTopZLevel 
-      real (kind=RKIND), dimension(:,:), pointer :: &amp;
-        weightsOnEdge, kiteAreasOnVertex, h_edge, h, u, v, pressure, &amp;
-        tend_h, circulation, vorticity, ke, ke_edge, pv_edge, &amp;
-        MontPot, wTop, divergence, vertViscTopOfEdge
-      type (dm_info) :: dminfo
+      integer :: err
 
-      integer, dimension(:), pointer :: nEdgesOnCell, nEdgesOnEdge, &amp;
-        maxLevelCell, maxLevelEdgeTop, maxLevelVertexBot
-      integer, dimension(:,:), pointer :: &amp;
-        cellsOnEdge, cellsOnVertex, verticesOnEdge, edgesOnCell, &amp;
-        edgesOnEdge, edgesOnVertex
-      real (kind=RKIND) :: u_diffusion
-      real (kind=RKIND), dimension(:), allocatable:: fluxVertTop,w_dudzTopEdge
-
-      real (kind=RKIND), allocatable, dimension(:,:) :: delsq_divergence
-      real (kind=RKIND), allocatable, dimension(:,:) :: delsq_u
-      real (kind=RKIND), allocatable, dimension(:,:) :: delsq_circulation, delsq_vorticity
-
       call mpas_timer_start(&quot;ocn_tend_h&quot;)
 
-      h           =&gt; s % h % array
       u           =&gt; s % u % array
-      v           =&gt; s % v % array
       wTop        =&gt; s % wTop % array
       h_edge      =&gt; s % h_edge % array
-      circulation =&gt; s % circulation % array
-      vorticity   =&gt; s % vorticity % array
-      divergence  =&gt; s % divergence % array
-      ke          =&gt; s % ke % array
-      ke_edge     =&gt; s % ke_edge % array
-      pv_edge     =&gt; s % pv_edge % array
-      MontPot     =&gt; s % MontPot % array
-      pressure    =&gt; s % pressure % array
-      vertViscTopOfEdge =&gt; d % vertViscTopOfEdge % array
 
-      weightsOnEdge     =&gt; grid % weightsOnEdge % array
-      kiteAreasOnVertex =&gt; grid % kiteAreasOnVertex % array
-      cellsOnEdge       =&gt; grid % cellsOnEdge % array
-      cellsOnVertex     =&gt; grid % cellsOnVertex % array
-      verticesOnEdge    =&gt; grid % verticesOnEdge % array
-      nEdgesOnCell      =&gt; grid % nEdgesOnCell % array
-      edgesOnCell       =&gt; grid % edgesOnCell % array
-      nEdgesOnEdge      =&gt; grid % nEdgesOnEdge % array
-      edgesOnEdge       =&gt; grid % edgesOnEdge % array
-      edgesOnVertex     =&gt; grid % edgesOnVertex % array
-      dcEdge            =&gt; grid % dcEdge % array
-      dvEdge            =&gt; grid % dvEdge % array
-      areaCell          =&gt; grid % areaCell % array
-      areaTriangle      =&gt; grid % areaTriangle % array
-      h_s               =&gt; grid % h_s % array
-      fVertex           =&gt; grid % fVertex % array
-      fEdge             =&gt; grid % fEdge % array
-      zMidZLevel        =&gt; grid % zMidZLevel % array
-      zTopZLevel        =&gt; grid % zTopZLevel % array
-      maxLevelCell      =&gt; grid % maxLevelCell % array
-      maxLevelEdgeTop      =&gt; grid % maxLevelEdgeTop % array
-      maxLevelVertexBot    =&gt; grid % maxLevelVertexBot % array
-
       tend_h      =&gt; tend % h % array
                   
-      nCells      = grid % nCells
-      nEdges      = grid % nEdges
-      nEdgesSolve = grid % nEdgesSolve
-      nVertices   = grid % nVertices
-      nVertLevels = grid % nVertLevels
-
       !
       ! height tendency: start accumulating tendency terms
       !
@@ -192,23 +137,17 @@
       ! See Ringler et al. (2010) jcp paper, eqn 19, 21, and fig. 3. 
       ! for explanation of divergence operator.
       !
-      ! for z-level, only compute height tendency for top layer.
-
-      call mpas_timer_start(&quot;ocn_tend_h-horiz adv&quot;)
-
+      call mpas_timer_start(&quot;hadv&quot;, .false., thickHadvTimer)
       call ocn_thick_hadv_tend(grid, u, h_edge, tend_h, err)
+      call mpas_timer_stop(&quot;hadv&quot;, thickHadvTimer)
 
-      call mpas_timer_stop(&quot;ocn_tend_h-horiz adv&quot;)
-
       !
       ! height tendency: vertical advection term -d/dz(hw)
       !
-      ! Vertical advection computed for top layer of a z grid only.
-      call mpas_timer_start(&quot;ocn_tend_h-vert adv&quot;)
-
+      call mpas_timer_start(&quot;vadv&quot;, .false., thickVadvTimer)
       call ocn_thick_vadv_tend(grid, wtop, tend_h, err)
+      call mpas_timer_stop(&quot;vadv&quot;, thickVadvTimer)
 
-      call mpas_timer_stop(&quot;ocn_tend_h-vert adv&quot;)
       call mpas_timer_stop(&quot;ocn_tend_h&quot;)
    
    end subroutine ocn_tend_h!}}}
@@ -243,47 +182,22 @@
       type (diagnostics_type), intent(in) :: d
       type (mesh_type), intent(in) :: grid
 
-! mrp 110512 I just split compute_tend into ocn_tend_u and compute_tend_h.
-!  Some of these variables can be removed, but at a later time.
-      integer :: iEdge, iCell, iVertex, k, cell1, cell2, &amp;
-        vertex1, vertex2, eoe, i, j
-
-      integer :: nCells, nEdges, nVertices, nVertLevels, nEdgesSolve, err
-      real (kind=RKIND) :: flux, vorticity_abs, h_vertex, workpv, q, &amp;
-        upstream_bias, wTopEdge, rho0Inv, r, visc_vorticity_coef
-      real (kind=RKIND), dimension(:), pointer :: &amp;
-        h_s, fVertex, fEdge, dvEdge, dcEdge, areaCell, areaTriangle, &amp;
-        zMidZLevel, zTopZLevel, meshScalingDel2, meshScalingDel4
       real (kind=RKIND), dimension(:,:), pointer :: &amp;
-        weightsOnEdge, kiteAreasOnVertex, h_edge, h, u, v, pressure, &amp;
+        h_edge, h, u, rho, zMid, pressure, &amp;
         tend_u, circulation, vorticity, ke, ke_edge, pv_edge, &amp;
         MontPot, wTop, divergence, vertViscTopOfEdge
-      type (dm_info) :: dminfo
 
-      integer, dimension(:), pointer :: nEdgesOnCell, nEdgesOnEdge, &amp;
-        maxLevelCell, maxLevelEdgeTop, maxLevelVertexBot
-      integer, dimension(:,:), pointer :: &amp;
-        cellsOnEdge, cellsOnVertex, verticesOnEdge, edgesOnCell, &amp;
-        edgesOnEdge, edgesOnVertex
-      real (kind=RKIND) :: u_diffusion
-      real (kind=RKIND), dimension(:), allocatable:: fluxVertTop,w_dudzTopEdge
-
-      real (kind=RKIND), allocatable, dimension(:,:) :: delsq_divergence
-      real (kind=RKIND), allocatable, dimension(:,:) :: delsq_u
-      real (kind=RKIND), allocatable, dimension(:,:) :: delsq_circulation, delsq_vorticity
-
-
       real (kind=RKIND), dimension(:,:), pointer :: u_src
-      real (kind=RKIND), parameter :: rho_ref = 1000.0
 
+      integer :: err
+
       call mpas_timer_start(&quot;ocn_tend_u&quot;)
 
-      h           =&gt; s % h % array
       u           =&gt; s % u % array
-      v           =&gt; s % v % array
+      rho         =&gt; s % rho % array
       wTop        =&gt; s % wTop % array
+      zMid        =&gt; s % zMid % array
       h_edge      =&gt; s % h_edge % array
-      circulation =&gt; s % circulation % array
       vorticity   =&gt; s % vorticity % array
       divergence  =&gt; s % divergence % array
       ke          =&gt; s % ke % array
@@ -293,43 +207,10 @@
       pressure    =&gt; s % pressure % array
       vertViscTopOfEdge =&gt; d % vertViscTopOfEdge % array
 
-      weightsOnEdge     =&gt; grid % weightsOnEdge % array
-      kiteAreasOnVertex =&gt; grid % kiteAreasOnVertex % array
-      cellsOnEdge       =&gt; grid % cellsOnEdge % array
-      cellsOnVertex     =&gt; grid % cellsOnVertex % array
-      verticesOnEdge    =&gt; grid % verticesOnEdge % array
-      nEdgesOnCell      =&gt; grid % nEdgesOnCell % array
-      edgesOnCell       =&gt; grid % edgesOnCell % array
-      nEdgesOnEdge      =&gt; grid % nEdgesOnEdge % array
-      edgesOnEdge       =&gt; grid % edgesOnEdge % array
-      edgesOnVertex     =&gt; grid % edgesOnVertex % array
-      dcEdge            =&gt; grid % dcEdge % array
-      dvEdge            =&gt; grid % dvEdge % array
-      areaCell          =&gt; grid % areaCell % array
-      areaTriangle      =&gt; grid % areaTriangle % array
-      h_s               =&gt; grid % h_s % array
-! mrp 110516 cleanup fvertex fedge not used in this subroutine
-      fVertex           =&gt; grid % fVertex % array
-      fEdge             =&gt; grid % fEdge % array
-      zMidZLevel        =&gt; grid % zMidZLevel % array
-      zTopZLevel        =&gt; grid % zTopZLevel % array
-      maxLevelCell      =&gt; grid % maxLevelCell % array
-      maxLevelEdgeTop      =&gt; grid % maxLevelEdgeTop % array
-      maxLevelVertexBot    =&gt; grid % maxLevelVertexBot % array
-
       tend_u      =&gt; tend % u % array
                   
-      nCells      = grid % nCells
-      nEdges      = grid % nEdges
-      nEdgesSolve = grid % nEdgesSolve
-      nVertices   = grid % nVertices
-      nVertLevels = grid % nVertLevels
-
       u_src =&gt; grid % u_src % array
 
-      meshScalingDel2 =&gt; grid % meshScalingDel2 % array
-      meshScalingDel4 =&gt; grid % meshScalingDel4 % array
-
       !
       ! velocity tendency: start accumulating tendency terms
       !
@@ -340,66 +221,54 @@
       ! velocity tendency: nonlinear Coriolis term and grad of kinetic energy
       !
 
-      call mpas_timer_start(&quot;ocn_tend_u-coriolis&quot;)
-
+      call mpas_timer_start(&quot;coriolis&quot;, .false., velCorTimer)
       call ocn_vel_coriolis_tend(grid, pv_edge, h_edge, u, ke, tend_u, err)
+      call mpas_timer_stop(&quot;coriolis&quot;, velCorTimer)
 
-      call mpas_timer_stop(&quot;ocn_tend_u-coriolis&quot;)
-
       !
       ! velocity tendency: vertical advection term -w du/dz
       !
-      call mpas_timer_start(&quot;ocn_tend_u-vert adv&quot;)
+      call mpas_timer_start(&quot;vadv&quot;, .false., velVadvTimer)
+      call ocn_vel_vadv_tend(grid, u, h_edge, wtop, tend_u, err)
+      call mpas_timer_stop(&quot;vadv&quot;, velVadvTimer)
 
-      call ocn_vel_vadv_tend(grid, u, wtop, tend_u, err)
-
-      call mpas_timer_stop(&quot;ocn_tend_u-vert adv&quot;)
-
       !
       ! velocity tendency: pressure gradient
       !
-      call mpas_timer_start(&quot;ocn_tend_u-pressure grad&quot;)
-
-      if (config_vert_grid_type.eq.'isopycnal') then
-          call ocn_vel_pressure_grad_tend(grid, MontPot, tend_u, err)
-      elseif (config_vert_grid_type.eq.'zlevel') then
-          call ocn_vel_pressure_grad_tend(grid, pressure, tend_u, err)
+      call mpas_timer_start(&quot;pressure grad&quot;, .false., velPgradTimer)
+      if (config_pressure_type.eq.'MontgomeryPotential') then
+          call ocn_vel_pressure_grad_tend(grid, MontPot,  zMid, rho, tend_u, err)
+      else
+          call ocn_vel_pressure_grad_tend(grid, pressure, zMid, rho, tend_u, err)
       end if
+      call mpas_timer_stop(&quot;pressure grad&quot;, velPgradTimer)
 
-      call mpas_timer_stop(&quot;ocn_tend_u-pressure grad&quot;)
-
       !
       ! velocity tendency: del2 dissipation, </font>
<font color="black">u_2 </font>
<font color="black">abla^2 u
       !   computed as </font>
<font color="black">u( </font>
<font color="black">abla divergence + k \times </font>
<font color="gray">abla vorticity )
       !   strictly only valid for config_h_mom_eddy_visc2 == constant
       !
-      call mpas_timer_start(&quot;ocn_tend_u-horiz mix&quot;)
-
+      call mpas_timer_start(&quot;hmix&quot;, .false., velHmixTimer)
       call ocn_vel_hmix_tend(grid, divergence, vorticity, tend_u, err)
+      call mpas_timer_stop(&quot;hmix&quot;, velHmixTimer)
 
-      call mpas_timer_stop(&quot;ocn_tend_u-horiz mix&quot;)
-
       !
       ! velocity tendency: forcing and bottom drag
       !
       ! mrp 101115 note: in order to include flux boundary conditions, we will need to 
       ! know the bottom edge with nonzero velocity and place the drag there.
 
-      call mpas_timer_start(&quot;ocn_tend_u-forcings&quot;)
-
+      call mpas_timer_start(&quot;forcings&quot;, .false., velForceTimer)
       call ocn_vel_forcing_tend(grid, u, u_src, ke_edge, h_edge, tend_u, err)
+      call mpas_timer_stop(&quot;forcings&quot;, velForceTimer)
 
-      call mpas_timer_stop(&quot;ocn_tend_u-forcings&quot;)
-
       !
       ! velocity tendency: vertical mixing d/dz( nu_v du/dz))
       !
       if (.not.config_implicit_vertical_mix) then
-          call mpas_timer_start(&quot;ocn_tend_u-explicit vert mix&quot;)
-
+          call mpas_timer_start(&quot;explicit vmix&quot;, .false., velExpVmixTimer)
           call ocn_vel_vmix_tend_explicit(grid, u, h_edge, vertvisctopofedge, tend_u, err)
-
-          call mpas_timer_stop(&quot;ocn_tend_u-explicit vert mix&quot;)
+          call mpas_timer_stop(&quot;explicit vmix&quot;, velExpVmixTimer)
       endif
       call mpas_timer_stop(&quot;ocn_tend_u&quot;)
 
@@ -436,74 +305,24 @@
       type (diagnostics_type), intent(in) :: d
       type (mesh_type), intent(in) :: grid
 
-      integer :: i, k, iCell, iEdge, iTracer, cell1, cell2, upwindCell,&amp;
-        nEdges, nCells, nCellsSolve, nVertLevels, num_tracers, err
-      real (kind=RKIND) :: invAreaCell1, invAreaCell2, tracer_turb_flux
-      real (kind=RKIND) :: flux, tracer_edge, r
-      real (kind=RKIND), dimension(:), pointer :: &amp;
-        h_s, fVertex, fEdge, dvEdge, dcEdge, areaCell, areaTriangle
       real (kind=RKIND), dimension(:,:), pointer :: &amp;
         u,h,wTop, h_edge, vertDiffTopOfCell
       real (kind=RKIND), dimension(:,:,:), pointer :: &amp;
         tracers, tend_tr
-      integer, dimension(:,:), pointer :: boundaryEdge
-      type (dm_info) :: dminfo
 
-      integer, dimension(:), pointer :: nEdgesOnCell, nEdgesOnEdge, &amp;
-        maxLevelCell, maxLevelEdgeTop, maxLevelVertexBot
-      integer, dimension(:,:), pointer :: cellsOnEdge, boundaryCell
-      real (kind=RKIND), dimension(:), pointer :: zTopZLevel,zMidZLevel, &amp;
-         hRatioZLevelK, hRatioZLevelKm1, meshScalingDel2, meshScalingDel4
-      real (kind=RKIND), dimension(:), allocatable:: tracer2ndDer, tracersIn, tracersOut, posZMidZLevel, &amp;
-            posZTopZLevel
-      real (kind=RKIND), dimension(:,:), allocatable:: fluxVertTop, boundaryMask
-      real (kind=RKIND), dimension(:,:,:), allocatable::tr_flux, tr_div, delsq_tracer, tracerTop
+      integer :: err
 
-
-      real (kind=RKIND) :: d2fdx2_cell1, d2fdx2_cell2
-      real (kind=RKIND), dimension(:,:,:), pointer :: deriv_two
-      real (kind=RKIND) :: coef_3rd_order, flux3Coef, cSignWTop
-
-      integer :: index_temperature, index_salinity, rrr
-      real (kind=RKIND), dimension(:), pointer :: temperatureRestore, salinityRestore
-
       call mpas_timer_start(&quot;ocn_tend_scalar&quot;)
 
       u           =&gt; s % u % array
       h           =&gt; s % h % array
-      boundaryCell=&gt; grid % boundaryCell % array
       wTop        =&gt; s % wTop % array
       tracers     =&gt; s % tracers % array
       h_edge      =&gt; s % h_edge % array
       vertDiffTopOfCell =&gt; d % vertDiffTopOfCell % array
 
       tend_tr     =&gt; tend % tracers % array
-                  
-      areaCell          =&gt; grid % areaCell % array
-      cellsOnEdge       =&gt; grid % cellsOnEdge % array
-      dvEdge            =&gt; grid % dvEdge % array
-      dcEdge            =&gt; grid % dcEdge % array
-      zTopZLevel        =&gt; grid % zTopZLevel % array
-      zMidZLevel        =&gt; grid % zMidZLevel % array
-      hRatioZLevelK    =&gt; grid % hRatioZLevelK % array
-      hRatioZLevelKm1    =&gt; grid % hRatioZLevelKm1 % array
-      boundaryEdge      =&gt; grid % boundaryEdge % array
-      maxLevelCell      =&gt; grid % maxLevelCell % array
-      maxLevelEdgeTop      =&gt; grid % maxLevelEdgeTop % array
-      maxLevelVertexBot    =&gt; grid % maxLevelVertexBot % array
 
-      nEdges      = grid % nEdges
-      nCells      = grid % nCells
-      nCellsSolve = grid % nCellsSolve
-      nVertLevels = grid % nVertLevels
-      num_tracers = s % num_tracers
-
-      meshScalingDel2 =&gt; grid % meshScalingDel2 % array
-      meshScalingDel4 =&gt; grid % meshScalingDel4 % array
-
-
-      deriv_two   =&gt; grid % deriv_two % array
-
       !
       ! initialize tracer tendency (RHS of tracer equation) to zero.
       !
@@ -517,32 +336,26 @@
       ! and then change maxLevelEdgeTop to maxLevelEdgeBot in the following section.
       ! tracer_edge at the boundary will also need to be defined for flux boundaries.
 
-      call mpas_timer_start(&quot;ocn_tend_scalar-horiz adv&quot;)
-
+      call mpas_timer_start(&quot;hadv&quot;, .false., tracerHadvTimer)
       call ocn_tracer_hadv_tend(grid, u, h_edge, tracers, tend_tr, err)
+      call mpas_timer_stop(&quot;hadv&quot;, tracerHadvTimer)
 
-      call mpas_timer_stop(&quot;ocn_tend_scalar-horiz adv&quot;)
 
-
       !
       ! tracer tendency: vertical advection term -d/dz( h \phi w)
       !
 
-      call mpas_timer_start(&quot;ocn_tend_scalar-vert adv&quot;)
+      call mpas_timer_start(&quot;vadv&quot;, .false., tracerVadvTimer)
+      call ocn_tracer_vadv_tend(grid, h, wtop, tracers, tend_tr, err)
+      call mpas_timer_stop(&quot;vadv&quot;, tracerVadvTimer)
 
-      call ocn_tracer_vadv_tend(grid, wtop, tracers, tend_tr, err)
-
-      call mpas_timer_stop(&quot;ocn_tend_scalar-vert adv&quot;)
-
       !
       ! tracer tendency: del2 horizontal tracer diffusion, div(h \kappa_2 </font>
<font color="gray">abla \phi)
       !
-      call mpas_timer_start(&quot;ocn_tend_scalar-horiz diff&quot;)
-
+      call mpas_timer_start(&quot;hmix&quot;, .false., tracerHmixTimer)
       call ocn_tracer_hmix_tend(grid, h_edge, tracers, tend_tr, err)
+      call mpas_timer_stop(&quot;hmix&quot;, tracerHmixTimer)
 
-      call mpas_timer_stop(&quot;ocn_tend_scalar-horiz diff&quot;)
-
 ! mrp 110516 printing
 !print *, 'tend_tr 1',minval(tend_tr(3,1,1:nCells)),&amp;
 !                   maxval(tend_tr(3,1,1:nCells))
@@ -554,11 +367,11 @@
       ! tracer tendency: vertical diffusion h d/dz( \kappa_v d\phi/dz)
       !
       if (.not.config_implicit_vertical_mix) then
-         call mpas_timer_start(&quot;ocn_tend_scalar-explicit vert diff&quot;)
+         call mpas_timer_start(&quot;explicit vmix&quot;, .false., tracerExpVmixTimer)
 
          call ocn_tracer_vmix_tend_explicit(grid, h, vertdifftopofcell, tracers, tend_tr, err)
 
-         call mpas_timer_stop(&quot;ocn_tend_scalar-explicit vert diff&quot;)
+         call mpas_timer_stop(&quot;explicit vmix&quot;, tracerExpVmixTimer)
       endif
 
 ! mrp 110516 printing
@@ -569,11 +382,11 @@
       !
       ! add restoring to T and S in top model layer
       !
-      call mpas_timer_start(&quot;ocn_tend_scalar-restoring&quot;)
+      call mpas_timer_start(&quot;restoring&quot;, .false., tracerRestoringTimer)
 
       call ocn_restoring_tend(grid, h, s%index_temperature, s%index_salinity, tracers, tend_tr, err)
 
-      call mpas_timer_stop(&quot;ocn_tend_scalar-restoring&quot;)
+      call mpas_timer_stop(&quot;restoring&quot;, tracerRestoringTimer)
 
  10   format(2i8,10e20.10)
       call mpas_timer_stop(&quot;ocn_tend_scalar&quot;)
@@ -609,42 +422,34 @@
       type (mesh_type), intent(in) :: grid
 
 
-      integer :: iEdge, iCell, iVertex, k, cell1, cell2, vertex1, vertex2, eoe, i, j, cov
-      real (kind=RKIND) :: flux, vorticity_abs, h_vertex, workpv, rho0Inv
+      integer :: iEdge, iCell, iVertex, k, cell1, cell2, vertex1, vertex2, eoe, i, j
+      integer :: boundaryMask, velMask, nCells, nEdges, nVertices, nVertLevels, vertexDegree, err
 
-      integer :: nCells, nEdges, nVertices, nVertLevels, vertexDegree, fCoef, err
+      integer, dimension(:), pointer :: nEdgesOnCell, nEdgesOnEdge, &amp;
+        maxLevelCell, maxLevelEdgeTop, maxLevelEdgeBot, &amp;
+        maxLevelVertexBot
+      integer, dimension(:,:), pointer :: cellsOnEdge, cellsOnVertex, &amp;
+        verticesOnEdge, edgesOnEdge, edgesOnVertex,boundaryCell
 
+      real (kind=RKIND) :: d2fdx2_cell1, d2fdx2_cell2, coef_3rd_order, r_tmp, invAreaCell1, invAreaCell2, invAreaTri1, invAreaTri2, invLength, h_vertex
 
+      real (kind=RKIND), dimension(:), allocatable:: pTop
+
       real (kind=RKIND), dimension(:), pointer :: &amp;
-        h_s, fVertex, fEdge, dvEdge, dcEdge, areaCell, areaTriangle, &amp;
-        hZLevel
+        h_s, fVertex, dvEdge, dcEdge, areaCell, areaTriangle, &amp;
+        referenceBottomDepth, ssh
       real (kind=RKIND), dimension(:,:), pointer :: &amp;
-        weightsOnEdge, kiteAreasOnVertex, h_edge, h, u, v, w, pressure,&amp;
-        circulation, vorticity, ke, ke_edge, MontPot, wTop, &amp;
+        weightsOnEdge, kiteAreasOnVertex, h_edge, h, u, v, pressure,&amp;
+        circulation, vorticity, ke, ke_edge, MontPot, wTop, zMid, &amp;
         pv_edge, pv_vertex, pv_cell, gradPVn, gradPVt, divergence, &amp;
         rho, temperature, salinity, kev, kevc
-      real (kind=RKIND), dimension(:,:,:), pointer :: tracers
-      real (kind=RKIND), dimension(:), allocatable:: pTop
+      real (kind=RKIND), dimension(:,:,:), pointer :: tracers, deriv_two
       real (kind=RKIND), dimension(:,:), allocatable:: div_u
       character :: c1*6
 
-      integer, dimension(:,:), pointer :: cellsOnEdge, cellsOnVertex, &amp;
-        verticesOnEdge, edgesOnCell, edgesOnEdge, edgesOnVertex, &amp;
-        boundaryEdge, boundaryCell
-      integer, dimension(:), pointer :: nEdgesOnCell, nEdgesOnEdge, &amp;
-        maxLevelCell, maxLevelEdgeTop, maxLevelEdgeBot, &amp;
-        maxLevelVertexBot,  maxLevelVertexTop
-      real (kind=RKIND) :: d2fdx2_cell1, d2fdx2_cell2
-      real (kind=RKIND), dimension(:,:,:), pointer :: deriv_two
-      real (kind=RKIND) :: coef_3rd_order
-      real (kind=RKIND) :: r, h1, h2
-
-      call mpas_timer_start(&quot;ocn_diagnostic_solve&quot;)
-
       h           =&gt; s % h % array
       u           =&gt; s % u % array
       v           =&gt; s % v % array
-      wTop        =&gt; s % wTop % array
       h_edge      =&gt; s % h_edge % array
       circulation =&gt; s % circulation % array
       vorticity   =&gt; s % vorticity % array
@@ -659,9 +464,11 @@
       gradPVn     =&gt; s % gradPVn % array
       gradPVt     =&gt; s % gradPVt % array
       rho         =&gt; s % rho % array
-      tracers     =&gt; s % tracers % array
       MontPot     =&gt; s % MontPot % array
       pressure    =&gt; s % pressure % array
+      zMid        =&gt; s % zMid % array
+      ssh         =&gt; s % ssh % array
+      tracers     =&gt; s % tracers % array
 
       weightsOnEdge     =&gt; grid % weightsOnEdge % array
       kiteAreasOnVertex =&gt; grid % kiteAreasOnVertex % array
@@ -669,7 +476,6 @@
       cellsOnVertex     =&gt; grid % cellsOnVertex % array
       verticesOnEdge    =&gt; grid % verticesOnEdge % array
       nEdgesOnCell      =&gt; grid % nEdgesOnCell % array
-      edgesOnCell       =&gt; grid % edgesOnCell % array
       nEdgesOnEdge      =&gt; grid % nEdgesOnEdge % array
       edgesOnEdge       =&gt; grid % edgesOnEdge % array
       edgesOnVertex     =&gt; grid % edgesOnVertex % array
@@ -679,14 +485,12 @@
       areaTriangle      =&gt; grid % areaTriangle % array
       h_s               =&gt; grid % h_s % array
       fVertex           =&gt; grid % fVertex % array
-      fEdge             =&gt; grid % fEdge % array
-      hZLevel           =&gt; grid % hZLevel % array
+      referenceBottomDepth        =&gt; grid % referenceBottomDepth % array
       deriv_two         =&gt; grid % deriv_two % array
       maxLevelCell      =&gt; grid % maxLevelCell % array
       maxLevelEdgeTop   =&gt; grid % maxLevelEdgeTop % array
       maxLevelEdgeBot   =&gt; grid % maxLevelEdgeBot % array
       maxLevelVertexBot =&gt; grid % maxLevelVertexBot % array
-      maxLevelVertexTop =&gt; grid % maxLevelVertexTop % array
                   
       nCells      = grid % nCells
       nEdges      = grid % nEdges
@@ -694,7 +498,6 @@
       nVertLevels = grid % nVertLevels
       vertexDegree = grid % vertexDegree
 
-      boundaryEdge =&gt; grid % boundaryEdge % array
       boundaryCell =&gt; grid % boundaryCell % array
 
       !
@@ -704,205 +507,165 @@
       ! mrp 101115 note: in order to include flux boundary conditions, we will need to 
       ! assign h_edge for maxLevelEdgeTop:maxLevelEdgeBot in the following section
 
-      ! mrp 110516 efficiency note: For z-level, only do this on level 1.  h_edge for all
-      ! lower levels is defined by hZlevel.
+      ! initialize h_edge to avoid divide by zero and NaN problems.
+      h_edge = -1.0e34
 
-      call mpas_timer_start(&quot;ocn_diagnostic_solve-hEdge&quot;)
-
-      coef_3rd_order = 0.
-      if (config_thickness_adv_order == 3) coef_3rd_order = 1.0
-      if (config_thickness_adv_order == 3 .and. config_monotonic) coef_3rd_order = 0.25
-
-      if (config_thickness_adv_order == 2) then
-          call mpas_timer_start(&quot;ocn_diagnostic_solve-hEdge 2&quot;)
-
-         do iEdge=1,nEdges
-            cell1 = cellsOnEdge(1,iEdge)
-            cell2 = cellsOnEdge(2,iEdge)
-            do k=1,maxLevelEdgeTop(iEdge)
-               h_edge(k,iEdge) = 0.5 * (h(k,cell1) + h(k,cell2))
-            end do
+      do iEdge=1,nEdges*hadv2nd
+         cell1 = cellsOnEdge(1,iEdge)
+         cell2 = cellsOnEdge(2,iEdge)
+         do k=1,maxLevelEdgeTop(iEdge)
+            h_edge(k,iEdge) = 0.5 * (h(k,cell1) + h(k,cell2))
          end do
-          call mpas_timer_stop(&quot;ocn_diagnostic_solve-hEdge 2&quot;)
+      end do
 
-      else if (config_thickness_adv_order == 3) then
-          call mpas_timer_start(&quot;ocn_diagnostic_solve-hEdge 3&quot;)
+      do iEdge=1,nEdges*hadv3rd
+         cell1 = cellsOnEdge(1,iEdge)
+         cell2 = cellsOnEdge(2,iEdge)
 
-         do iEdge=1,nEdges
-            cell1 = cellsOnEdge(1,iEdge)
-            cell2 = cellsOnEdge(2,iEdge)
+         do k=1,maxLevelEdgeTop(iEdge)
 
-            do k=1,maxLevelEdgeTop(iEdge)
+            d2fdx2_cell1 = 0.0
+            d2fdx2_cell2 = 0.0
 
-               d2fdx2_cell1 = 0.0
-               d2fdx2_cell2 = 0.0
+            boundaryMask = abs(transfer(.not.(boundaryCell(k,cell1) == 0 .and. boundaryCell(k,cell2) == 0), boundaryMask))
 
-               !-- if not a boundary cell
-               if(boundaryCell(k,cell1).eq.0.and.boundaryCell(k,cell2).eq.0) then
+            d2fdx2_cell1 = deriv_two(1,1,iEdge) * h(k,cell1) * boundaryMask
+            d2fdx2_cell2 = deriv_two(1,2,iEdge) * h(k,cell2) * boundaryMask
 
-                  d2fdx2_cell1 = deriv_two(1,1,iEdge) * h(k,cell1)
-                  d2fdx2_cell2 = deriv_two(1,2,iEdge) * h(k,cell2)
+            !-- all edges of cell 1
+            do i=1, nEdgesOnCell(cell1) * boundaryMask
+               d2fdx2_cell1 = d2fdx2_cell1 + &amp;
+               deriv_two(i+1,1,iEdge) * h(k,grid % CellsOnCell % array (i,cell1))
+            end do
 
-                  !-- all edges of cell 1
-                  do i=1, grid % nEdgesOnCell % array (cell1)
-                          d2fdx2_cell1 = d2fdx2_cell1 + &amp;
-                          deriv_two(i+1,1,iEdge) * h(k,grid % CellsOnCell % array (i,cell1))
-                  end do
+            !-- all edges of cell 2
+            do i=1, nEdgesOnCell(cell2) * boundaryMask
+               d2fdx2_cell2 = d2fdx2_cell2 + &amp;
+               deriv_two(i+1,2,iEdge) * h(k,grid % CellsOnCell % array (i,cell2))
+            end do
 
-                  !-- all edges of cell 2
-                  do i=1, grid % nEdgesOnCell % array (cell2)
-                          d2fdx2_cell2 = d2fdx2_cell2 + &amp;
-                          deriv_two(i+1,2,iEdge) * h(k,grid % CellsOnCell % array (i,cell2))
-                  end do
+            velMask = 2*(abs(transfer(u(k,iEdge) &lt;= 0, velMask))) - 1
 
-               endif
+            h_edge(k,iEdge) = 0.5*(h(k,cell1) + h(k,cell2)) - (dcEdge(iEdge) **2) * (d2fdx2_cell1 + d2fdx2_cell2) / 12.          &amp;
+                            + velMask * (dcEdge(iEdge) **2) * coef_3rd_order*(d2fdx2_cell1 - d2fdx2_cell2) / 12.
 
-               !-- if u &gt; 0:
-               if (u(k,iEdge) &gt; 0) then
-                  h_edge(k,iEdge) =     &amp;
-                       0.5*(h(k,cell1) + h(k,cell2))      &amp;
-                       -(dcEdge(iEdge) **2) * (d2fdx2_cell1 + d2fdx2_cell2) / 12.          &amp;
-                       -(dcEdge(iEdge) **2) * coef_3rd_order*(d2fdx2_cell1 - d2fdx2_cell2) / 12.
-               !-- else u &lt;= 0:
-               else
-                  h_edge(k,iEdge) =     &amp;
-                       0.5*(h(k,cell1) + h(k,cell2))      &amp;
-                       -(dcEdge(iEdge) **2) * (d2fdx2_cell1 + d2fdx2_cell2) / 12.          &amp;
-                       +(dcEdge(iEdge) **2) * coef_3rd_order*(d2fdx2_cell1 - d2fdx2_cell2) / 12.
-               end if
+         end do   ! do k
+      end do         ! do iEdge
 
-            end do   ! do k
-         end do         ! do iEdge
+      do iEdge=1,nEdges*hadv4th
+         cell1 = cellsOnEdge(1,iEdge)
+         cell2 = cellsOnEdge(2,iEdge)
 
-          call mpas_timer_stop(&quot;ocn_diagnostic_solve-hEdge 3&quot;)
-      else  if (config_thickness_adv_order == 4) then
-          call mpas_timer_start(&quot;ocn_diagnostic_solve-hEdge 4&quot;)
+         do k=1,maxLevelEdgeTop(iEdge)
 
-         do iEdge=1,nEdges
-            cell1 = cellsOnEdge(1,iEdge)
-            cell2 = cellsOnEdge(2,iEdge)
+            d2fdx2_cell1 = 0.0
+            d2fdx2_cell2 = 0.0
 
-            do k=1,maxLevelEdgeTop(iEdge)
+            boundaryMask = abs(transfer(.not.(boundaryCell(k,cell1) == 0 .and. boundaryCell(k,cell2) == 0), boundaryMask))
 
-               d2fdx2_cell1 = 0.0
-               d2fdx2_cell2 = 0.0
+            d2fdx2_cell1 = deriv_two(1,1,iEdge) * h(k,cell1) * boundaryMask
+            d2fdx2_cell2 = deriv_two(1,2,iEdge) * h(k,cell2) * boundaryMask
 
-               !-- if not a boundary cell
-               if(boundaryCell(k,cell1).eq.0.and.boundaryCell(k,cell2).eq.0) then
+            !-- all edges of cell 1
+            do i=1, nEdgesOnCell(cell1) * boundaryMask
+               d2fdx2_cell1 = d2fdx2_cell1 + &amp;
+               deriv_two(i+1,1,iEdge) * h(k,grid % CellsOnCell % array (i,cell1))
+            end do
 
-                  d2fdx2_cell1 = deriv_two(1,1,iEdge) * h(k,cell1)
-                  d2fdx2_cell2 = deriv_two(1,2,iEdge) * h(k,cell2)
+            !-- all edges of cell 2
+            do i=1, nEdgesOnCell(cell2) * boundaryMask
+               d2fdx2_cell2 = d2fdx2_cell2 + &amp;
+               deriv_two(i+1,2,iEdge) * h(k,grid % CellsOnCell % array (i,cell2))
+            end do
 
-                  !-- all edges of cell 1
-                  do i=1, grid % nEdgesOnCell % array (cell1)
-                          d2fdx2_cell1 = d2fdx2_cell1 + &amp;
-                          deriv_two(i+1,1,iEdge) * h(k,grid % CellsOnCell % array (i,cell1))
-                  end do
+            h_edge(k,iEdge) =   &amp;
+                 0.5*(h(k,cell1) + h(k,cell2))      &amp;
+                    -(dcEdge(iEdge) **2) * (d2fdx2_cell1 + d2fdx2_cell2) / 12.
 
-                  !-- all edges of cell 2
-                  do i=1, grid % nEdgesOnCell % array (cell2)
-                          d2fdx2_cell2 = d2fdx2_cell2 + &amp;
-                          deriv_two(i+1,2,iEdge) * h(k,grid % CellsOnCell % array (i,cell2))
-                  end do
+         end do   ! do k
+      end do         ! do iEdge
 
-               endif
-
-               h_edge(k,iEdge) =   &amp;
-                    0.5*(h(k,cell1) + h(k,cell2))      &amp;
-                       -(dcEdge(iEdge) **2) * (d2fdx2_cell1 + d2fdx2_cell2) / 12.
-
-            end do   ! do k
-         end do         ! do iEdge
-
-         call mpas_timer_stop(&quot;ocn_diagnostic_solve-hEdge 4&quot;)
-      endif   ! if(config_thickness_adv_order == 2)
-      call mpas_timer_stop(&quot;ocn_diagnostic_solve-hEdge&quot;)
-
       !
       ! set the velocity and height at dummy address
       !    used -1e34 so error clearly occurs if these values are used.
       !
-!mrp 110516 change to zero, change back later:
       u(:,nEdges+1) = -1e34
       h(:,nCells+1) = -1e34
       tracers(s % index_temperature,:,nCells+1) = -1e34
       tracers(s % index_salinity,:,nCells+1) = -1e34
 
-      !
-      ! Compute circulation and relative vorticity at each vertex
-      !
       circulation(:,:) = 0.0
+      vorticity(:,:) = 0.0
+      divergence(:,:) = 0.0
+      ke(:,:) = 0.0
+      v(:,:) = 0.0
       do iEdge=1,nEdges
          vertex1 = verticesOnEdge(1,iEdge)
          vertex2 = verticesOnEdge(2,iEdge)
-         do k=1,maxLevelEdgeBot(iEdge)
-            circulation(k,vertex1) = circulation(k,vertex1) - dcEdge(iEdge) * u(k,iEdge)
-            circulation(k,vertex2) = circulation(k,vertex2) + dcEdge(iEdge) * u(k,iEdge)
-         end do
-      end do
-      do iVertex=1,nVertices
-         do k=1,maxLevelVertexBot(iVertex)
-            vorticity(k,iVertex) = circulation(k,iVertex) / areaTriangle(iVertex)
-         end do
-      end do
 
-      !
-      ! Compute the divergence at each cell center
-      !
-      divergence(:,:) = 0.0
-      do iEdge=1,nEdges
          cell1 = cellsOnEdge(1,iEdge)
          cell2 = cellsOnEdge(2,iEdge)
-         do k=1,maxLevelEdgeBot(iEdge)
-             divergence(k,cell1) = divergence(k,cell1) + u(k,iEdge)*dvEdge(iEdge)
-             divergence(k,cell2) = divergence(k,cell2) - u(k,iEdge)*dvEdge(iEdge)
-         enddo
-      end do
-      do iCell = 1,nCells
-         r = 1.0 / areaCell(iCell)
-         do k = 1,maxLevelCell(iCell)
-            divergence(k,iCell) = divergence(k,iCell) * r
-         enddo
-      enddo
 
-      !
-      ! Compute kinetic energy in each cell
-      !
-      ke(:,:) = 0.0
-      do iEdge=1,nEdges
-         cell1 = cellsOnEdge(1,iEdge)
-         cell2 = cellsOnEdge(2,iEdge)
+         invAreaTri1 = 1.0 / areaTriangle(vertex1)
+         invAreaTri2 = 1.0 / areaTriangle(vertex2)
+
+         invAreaCell1 = 1.0 / areaCell(cell1)
+         invAreaCell2 = 1.0 / areaCell(cell2)
+
          do k=1,maxLevelEdgeBot(iEdge)
-              ke(k,cell1) = ke(k,cell1) + 0.25 * dcEdge(iEdge) * dvEdge(iEdge) * u(k,iEdge)**2.0
-              ke(k,cell2) = ke(k,cell2) + 0.25 * dcEdge(iEdge) * dvEdge(iEdge) * u(k,iEdge)**2.0
-         enddo
+            ! Compute circulation and relative vorticity at each vertex
+            r_tmp = dcEdge(iEdge) * u(k,iEdge)
+            circulation(k,vertex1) = circulation(k,vertex1) - r_tmp
+            circulation(k,vertex2) = circulation(k,vertex2) + r_tmp
+
+            vorticity(k, vertex1) = vorticity(k, vertex1) - r_tmp * invAreaTri1
+            vorticity(k, vertex2) = vorticity(k, vertex2) + r_tmp * invAreaTri2
+
+            ! Compute the divergence at each cell center
+            r_tmp = dvEdge(iEdge) * u(k, iEdge)
+            divergence(k,cell1) = divergence(k,cell1) + r_tmp * invAreaCell1
+            divergence(k,cell2) = divergence(k,cell2) - r_tmp * invAreaCell2
+
+            ! Compute kinetic energy in each cell
+            r_tmp = r_tmp * dcEdge(iEdge) * u(k,iEdge)
+            ke(k,cell1) = ke(k,cell1) + 0.25 * r_tmp * invAreaCell1
+            ke(k,cell2) = ke(k,cell2) + 0.25 * r_tmp * invAreaCell2
+         end do
+
+         ! Compute v (tangential) velocities
+         do i=1,nEdgesOnEdge(iEdge)
+            eoe = edgesOnEdge(i,iEdge)
+            ! mrp 101115 note: in order to include flux boundary conditions,
+            ! the following loop may need to change to maxLevelEdgeBot
+            do k = 1,maxLevelEdgeTop(iEdge) 
+               v(k,iEdge) = v(k,iEdge) + weightsOnEdge(i,iEdge) * u(k, eoe)
+            end do
+         end do
+
       end do
-      do iCell = 1,nCells
-         do k = 1,maxLevelCell(iCell)
-            ke(k,iCell) = ke(k,iCell) / areaCell(iCell)
-         enddo
-      enddo
 
       !
       ! Compute kinetic energy in each vertex
       !
       kev(:,:) = 0.0; kevc(:,:) = 0.0
-      do iEdge=1,nEdges
+      do iEdge=1,nEdges*ke_vertex_flag
          do k=1,nVertLevels
-            kev(k,verticesOnEdge(1,iEdge)) = kev(k,verticesOnEdge(1,iEdge)) + dcEdge(iEdge) * dvEdge(iEdge) * u(k,iEdge)**2
-            kev(k,verticesOnEdge(2,iEdge)) = kev(k,verticesOnEdge(2,iEdge)) + dcEdge(iEdge) * dvEdge(iEdge) * u(k,iEdge)**2
+            r_tmp = dcEdge(iEdge) * dvEdge(iEdge) * u(k, iEdge)**2
+            kev(k,verticesOnEdge(1,iEdge)) = kev(k,verticesOnEdge(1,iEdge)) + r_tmp
+            kev(k,verticesOnEdge(2,iEdge)) = kev(k,verticesOnEdge(2,iEdge)) + r_tmp
          end do
       end do
-      do iVertex = 1,nVertices
+      do iVertex = 1,nVertices*ke_vertex_flag
          do k=1,nVertLevels
-           kev(k,iVertex) = kev(k,iVertex) / areaTriangle(iVertex) / 4.0
+           kev(k,iVertex) = kev(k,iVertex) / areaTriangle(iVertex) * 0.25
          enddo
       enddo
-      do iVertex = 1, nVertices
+      do iVertex = 1, nVertices*ke_vertex_flag
        do i=1,grid % vertexDegree
          iCell = cellsOnVertex(i,iVertex)
+         invAreaCell1 = 1.0 / areaCell(iCell)
          do k=1,nVertLevels
-           kevc(k,iCell) = kevc(k,iCell) + kiteAreasOnVertex(i, iVertex) * kev(k, iVertex) / areaCell(iCell)
+           kevc(k,iCell) = kevc(k,iCell) + kiteAreasOnVertex(i, iVertex) * kev(k, iVertex) * invAreaCell1
          enddo
        enddo
       enddo
@@ -910,35 +673,17 @@
       !
       ! Compute kinetic energy in each cell by blending ke and kevc
       !
-      if(config_include_KE_vertex) then
-      do iCell=1,nCells
+      do iCell=1,nCells*ke_vertex_flag
          do k=1,nVertLevels
             ke(k,iCell) = 5.0/8.0*ke(k,iCell) + 3.0/8.0*kevc(k,iCell)
          end do
       end do
-      endif
 
       !
-      ! Compute v (tangential) velocities
-      !
-      v(:,:) = 0.0
-      do iEdge = 1,nEdges
-         do i=1,nEdgesOnEdge(iEdge)
-            eoe = edgesOnEdge(i,iEdge)
-            ! mrp 101115 note: in order to include flux boundary conditions,
-            ! the following loop may need to change to maxLevelEdgeBot
-            do k = 1,maxLevelEdgeTop(iEdge) 
-               v(k,iEdge) = v(k,iEdge) + weightsOnEdge(i,iEdge) * u(k, eoe)
-            end do
-         end do
-      end do
-
-      !
       ! Compute ke on cell edges at velocity locations for quadratic bottom drag. 
       !
       ! mrp 101025 efficiency note: we could get rid of ke_edge completely by 
       ! using sqrt(u(k,iEdge)**2 + v(k,iEdge)**2) in its place elsewhere.
-      ke_edge = 0.0  !mrp remove 0 for efficiency
       do iEdge=1,nEdges
          cell1 = cellsOnEdge(1,iEdge)
          cell2 = cellsOnEdge(2,iEdge)
@@ -951,83 +696,64 @@
       ! Compute height at vertices, pv at vertices, and average pv to edge locations
       !  ( this computes pv_vertex at all vertices bounding real cells and distance-1 ghost cells )
       !
-      if (trim(config_time_integration) == 'RK4') then
-         ! for RK4, PV is really PV = (eta+f)/h
-         fCoef = 1
-      elseif (trim(config_time_integration) == 'split_explicit' &amp;
-          .or.trim(config_time_integration) == 'unsplit_explicit') then
-         ! for split explicit, PV is eta/h because f is added separately to the momentum forcing.
-! mrp temp, new should be:
-         fCoef = 0
-! old, for testing:
-!         fCoef = 1
-      end if
-
       do iVertex = 1,nVertices
+         invAreaTri1 = 1.0 / areaTriangle(iVertex)
          do k=1,maxLevelVertexBot(iVertex)
             h_vertex = 0.0
             do i=1,vertexDegree
                h_vertex = h_vertex + h(k,cellsOnVertex(i,iVertex)) * kiteAreasOnVertex(i,iVertex)
             end do
-            h_vertex = h_vertex / areaTriangle(iVertex)
+            h_vertex = h_vertex * invAreaTri1
 
             pv_vertex(k,iVertex) = (fCoef*fVertex(iVertex) + vorticity(k,iVertex)) / h_vertex
          end do
       end do
 
-      !
-      ! Compute pv at cell centers
-      !    ( this computes pv_cell for all real cells and distance-1 ghost cells )
-      !
       pv_cell(:,:) = 0.0
+      pv_edge(:,:) = 0.0
       do iVertex = 1,nVertices
          do i=1,vertexDegree
             iCell = cellsOnVertex(i,iVertex)
+            iEdge = edgesOnVertex(i,iVertex)
+
+            invAreaCell1 = 1.0 / areaCell(iCell)
+
+            ! Compute pv at cell centers
+            !    ( this computes pv_cell for all real cells and distance-1 ghost cells )
             do k = 1,maxLevelCell(iCell)
-               pv_cell(k,iCell) = pv_cell(k,iCell)  &amp;
-                  + kiteAreasOnVertex(i, iVertex) * pv_vertex(k, iVertex) &amp;
-                    / areaCell(iCell)
+               pv_cell(k,iCell) = pv_cell(k,iCell) + kiteAreasOnVertex(i, iVertex) * pv_vertex(k, iVertex) * invAreaCell1
             enddo
-         enddo
-      enddo
 
-      !
-      ! Compute pv at the edges
-      !   ( this computes pv_edge at all edges bounding real cells )
-      !
-      pv_edge(:,:) = 0.0
-      do iVertex = 1,nVertices
-         do i=1,vertexDegree
-            iEdge = edgesOnVertex(i,iVertex)
+            ! Compute pv at the edges
+            !   ( this computes pv_edge at all edges bounding real cells )
             do k=1,maxLevelEdgeBot(iEdge)
-               pv_edge(k,iEdge) =  pv_edge(k,iEdge) + 0.5 * pv_vertex(k,iVertex)
+               pv_edge(k,iEdge) = pv_edge(k,iEdge) + 0.5 * pv_vertex(k,iVertex)
             enddo
-        end do
-      end do
+         enddo
+      enddo
 
-      !
-      ! Compute gradient of PV in normal direction
-      !   ( this computes gradPVn for all edges bounding real cells )
-      !
-      gradPVn(:,:) = 0.0
+!     gradPVn(:,:) = 0.0
+!     gradPVt(:,:) = 0.0
       do iEdge = 1,nEdges
+         cell1 = cellsOnEdge(1, iEdge)
+         cell2 = cellsOnEdge(2, iEdge)
+         vertex1 = verticesOnedge(1, iEdge)
+         vertex2 = verticesOnedge(2, iEdge)
+
+         invLength = 1.0 / dcEdge(iEdge)
+         ! Compute gradient of PV in normal direction
+         !   ( this computes gradPVn for all edges bounding real cells )
          do k=1,maxLevelEdgeTop(iEdge)
-            gradPVn(k,iEdge) = (  pv_cell(k,cellsOnEdge(2,iEdge)) &amp;
-                                - pv_cell(k,cellsOnEdge(1,iEdge))) &amp;
-                               / dcEdge(iEdge)
+            gradPVn(k,iEdge) = (pv_cell(k,cell2) - pv_cell(k,cell1)) * invLength
          enddo
-      enddo
 
-      !
-      ! Compute gradient of PV in the tangent direction
-      !   ( this computes gradPVt at all edges bounding real cells and distance-1 ghost cells )
-      !
-      do iEdge = 1,nEdges
+         invLength = 1.0 / dvEdge(iEdge)
+         ! Compute gradient of PV in the tangent direction
+         !   ( this computes gradPVt at all edges bounding real cells and distance-1 ghost cells )
          do k = 1,maxLevelEdgeBot(iEdge)
-           gradPVt(k,iEdge) = (  pv_vertex(k,verticesOnEdge(2,iEdge)) &amp;
-                               - pv_vertex(k,verticesOnEdge(1,iEdge))) &amp;
-                                 /dvEdge(iEdge)
+           gradPVt(k,iEdge) = (pv_vertex(k,vertex2) - pv_vertex(k,vertex1)) * invLength
          enddo
+
       enddo
 
       !
@@ -1046,17 +772,20 @@
       !
       ! For an isopycnal model, density should remain constant.
       ! For zlevel, calculate in-situ density
-      if (config_vert_grid_type.eq.'zlevel') then
+      if (config_vert_grid_type.ne.'isopycnal') then
+         call mpas_timer_start(&quot;equation of state&quot;, .false., diagEOSTimer)
          call ocn_equation_of_state_rho(s, grid, 0, 'relative', err)
       ! mrp 110324 In order to visualize rhoDisplaced, include the following
          call ocn_equation_of_state_rho(s, grid, 1, 'relative', err)
+         call mpas_timer_stop(&quot;equation of state&quot;, diagEOSTimer)
       endif
 
       !
       ! Pressure
       ! This section must be after computing rho
       !
-      if (config_vert_grid_type.eq.'isopycnal') then
+      ! dwj: 10/25/2011 - Need to explore isopycnal vs zlevel flags
+      if (config_pressure_type.eq.'MontgomeryPotential') then
 
         ! For Isopycnal model.
         ! Compute pressure at top of each layer, and then
@@ -1083,34 +812,52 @@
         end do
         deallocate(pTop)
 
-      elseif (config_vert_grid_type.eq.'zlevel') then
+      else
 
-        ! For z-level model.
-        ! Compute pressure at middle of each level.  
-        ! At k=1, where p is pressure at a depth of hZLevel(1)/2, not
-        ! pressure at middle of layer including SSH.
-
         do iCell=1,nCells
-           ! compute pressure for z-level coordinates
+           ! pressure for generalized coordinates
            ! assume atmospheric pressure at the surface is zero for now.
-
            pressure(1,iCell) = rho(1,iCell)*gravity &amp;
-              * (h(1,iCell)-0.5*hZLevel(1)) 
+              * 0.5*h(1,iCell)
 
            do k=2,maxLevelCell(iCell)
               pressure(k,iCell) = pressure(k-1,iCell)  &amp;
-                + 0.5*gravity*(  rho(k-1,iCell)*hZLevel(k-1) &amp;
-                               + rho(k  ,iCell)*hZLevel(k  ))
+                + 0.5*gravity*(  rho(k-1,iCell)*h(k-1,iCell) &amp;
+                               + rho(k  ,iCell)*h(k  ,iCell))
            end do
 
+           ! Compute zMid, the z-coordinate of the middle of the layer.
+           ! This is used for the rho g grad z momentum term.
+           ! Note the negative sign, since referenceBottomDepth is positive
+           ! and z-coordinates are negative below the surface.
+           k = maxLevelCell(iCell)
+           zMid(k:nVertLevels,iCell) = -referenceBottomDepth(k) + 0.5*h(k,iCell)
+
+           do k=maxLevelCell(iCell)-1, 1, -1
+              zMid(k,iCell) = zMid(k+1,iCell)  &amp;
+                + 0.5*(  h(k+1,iCell) &amp;
+                       + h(k  ,iCell))
+           end do
+
         end do
 
       endif
 
-      call ocn_wtop(s,grid)
+      !
+      ! Sea Surface Height
+      !
+      do iCell=1,nCells
+         ! Start at the bottom where we know the depth, and go up.
+         ! The bottom depth for this cell is 
+         ! referenceBottomDepth(maxLevelCell(iCell)).
+         ! Note the negative sign, since referenceBottomDepth is positive
+         ! and z-coordinates are negative below the surface.
 
-      call mpas_timer_stop(&quot;ocn_diagnostic_solve&quot;)
+         ssh(iCell) = -referenceBottomDepth(maxLevelCell(iCell)) &amp;
+           + sum(h(1:maxLevelCell(iCell),iCell))
 
+      end do
+
    end subroutine ocn_diagnostic_solve!}}}
 
 !***********************************************************************
@@ -1126,7 +873,7 @@
 !
 !-----------------------------------------------------------------------
 
-   subroutine ocn_wtop(s, grid)!{{{
+   subroutine ocn_wtop(s1,s2, grid)!{{{
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    ! Compute diagnostic fields used in the tendency computations
    !
@@ -1137,21 +884,22 @@
 
       implicit none
 
-      type (state_type), intent(inout) :: s
+      type (state_type), intent(inout) :: s1
+      type (state_type), intent(inout) :: s2
       type (mesh_type), intent(in) :: grid
 
       ! mrp 110512 could clean this out, remove pointers?
       integer :: iEdge, iCell, iVertex, k, cell1, cell2, vertex1, vertex2, eoe, i, j, cov
-      real (kind=RKIND) :: flux, vorticity_abs, h_vertex, workpv, rho0Inv
+      real (kind=RKIND) :: flux, vorticity_abs, h_vertex, workpv, rho0Inv, hSum
 
       integer :: nCells, nEdges, nVertices, nVertLevels, vertexDegree
 
 
       real (kind=RKIND), dimension(:), pointer :: &amp;
-        h_s, fVertex, fEdge, dvEdge, dcEdge, areaCell, areaTriangle, &amp;
-        hZLevel
-      real (kind=RKIND), dimension(:,:), pointer :: u,wTop
-      real (kind=RKIND), dimension(:,:), allocatable:: div_u
+        h_s, fVertex, fEdge, dvEdge, dcEdge, areaCell, areaTriangle
+      real (kind=RKIND), dimension(:,:), pointer :: u,h,wTop, h_edge
+      real (kind=RKIND), dimension(:,:), allocatable:: div_hu
+      real (kind=RKIND), dimension(:), allocatable:: div_hu_btr, h_tend_col, h_weights
 
       integer, dimension(:,:), pointer :: cellsOnEdge, cellsOnVertex, &amp;
         verticesOnEdge, edgesOnCell, edgesOnEdge, edgesOnVertex, &amp;
@@ -1160,14 +908,13 @@
         maxLevelCell, maxLevelEdgeTop, maxLevelEdgeBot, &amp;
         maxLevelVertexBot,  maxLevelVertexTop
 
-        call mpas_timer_start(&quot;wTop&quot;)
+      h           =&gt; s1 % h % array
+      h_edge      =&gt; s1 % h_edge % array
+      u           =&gt; s2 % u % array
+      wTop        =&gt; s2 % wTop % array
 
-      u           =&gt; s % u % array
-      wTop        =&gt; s % wTop % array
-
       areaCell          =&gt; grid % areaCell % array
       cellsOnEdge       =&gt; grid % cellsOnEdge % array
-      hZLevel           =&gt; grid % hZLevel % array
       maxLevelCell      =&gt; grid % maxLevelCell % array
       maxLevelEdgeBot   =&gt; grid % maxLevelEdgeBot % array
       dvEdge            =&gt; grid % dvEdge % array
@@ -1176,46 +923,128 @@
       nEdges      = grid % nEdges
       nVertLevels = grid % nVertLevels
 
+      allocate(div_hu(nVertLevels,nCells+1), div_hu_btr(nCells+1), &amp;
+          h_tend_col(nVertLevels), h_weights(nVertLevels))
+
       !
+      ! Compute div(h^{edge} u) for each cell
+      ! See Ringler et al. (2010) jcp paper, eqn 19, 21, and fig. 3.
+      !
+      div_hu(:,:) = 0.0
+      do iEdge=1,nEdges
+         cell1 = cellsOnEdge(1,iEdge)
+         cell2 = cellsOnEdge(2,iEdge)
+         do k=1,maxLevelEdgeBot(iEdge)
+            flux = u(k,iEdge) * dvEdge(iEdge) * h_edge(k,iEdge) 
+            div_hu(k,cell1) = div_hu(k,cell1) + flux
+            div_hu(k,cell2) = div_hu(k,cell2) - flux
+         end do 
+      end do 
+
+      do iCell=1,nCells
+         div_hu_btr(iCell) = 0.0
+         do k=1,maxLevelCell(iCell)
+            div_hu(k,iCell) = div_hu(k,iCell) / areaCell(iCell)
+            div_hu_btr(iCell) = div_hu_btr(iCell) + div_hu(k,iCell)
+         end do
+      end do
+
+      !
       ! vertical velocity through layer interface
       !
+      !dwj: 10/25/2011 - Need to explore isopycnal vs zlevel flags
       if (config_vert_grid_type.eq.'isopycnal') then
         ! set vertical velocity to zero in isopycnal case
         wTop=0.0  
 
       elseif (config_vert_grid_type.eq.'zlevel') then
 
-        !
-        ! Compute div(u) for each cell
-        ! See Ringler et al. (2010) jcp paper, eqn 19, 21, and fig. 3.
-        !
-        allocate(div_u(nVertLevels,nCells+1))
-        div_u(:,:) = 0.0
-        do iEdge=1,nEdges
-           cell1 = cellsOnEdge(1,iEdge)
-           cell2 = cellsOnEdge(2,iEdge)
-           do k=2,maxLevelEdgeBot(iEdge)
-              flux = u(k,iEdge) * dvEdge(iEdge) 
-              div_u(k,cell1) = div_u(k,cell1) + flux
-              div_u(k,cell2) = div_u(k,cell2) - flux
-           end do 
-        end do 
+        do iCell=1,nCells
+           ! Vertical velocity through layer interface at top and 
+           ! bottom is zero.
+           wTop(1,iCell) = 0.0
+           wTop(maxLevelCell(iCell)+1,iCell) = 0.0
+           do k=maxLevelCell(iCell),2,-1
+              wTop(k,iCell) = wTop(k+1,iCell) - div_hu(k,iCell)
+           end do
+        end do
 
+      elseif (config_vert_grid_type.eq.'zstar1') then
+
+        ! This is a testing setting.  The computation is similar to zstar,
+        ! but the weights are all in the top layer, so is a bit-for-bit 
+        ! match with zlevel.
+
         do iCell=1,nCells
+
+           h_tend_col = 0.0
+           h_tend_col(1) = - div_hu_btr(iCell)
+
            ! Vertical velocity through layer interface at top and 
            ! bottom is zero.
            wTop(1,iCell) = 0.0
            wTop(maxLevelCell(iCell)+1,iCell) = 0.0
+
            do k=maxLevelCell(iCell),2,-1
-              wTop(k,iCell) = wTop(k+1,iCell) &amp;
-                 - div_u(k,iCell)/areaCell(iCell)*hZLevel(k)
+              wTop(k,iCell) = wTop(k+1,iCell) - div_hu(k,iCell) - h_tend_col(k)
            end do
         end do
-        deallocate(div_u)
 
+      elseif (config_vert_grid_type.eq.'zstar') then
+
+        ! Distribute the change in total column height due to the external
+        ! mode, div_hu_btr, among all the layers.  Distribute in proportion
+        ! to the layer thickness.
+
+        do iCell=1,nCells
+
+           hSum = 0.0
+           do k=1,maxLevelCell(iCell)
+              h_tend_col(k) = - h(k,iCell)*div_hu_btr(iCell)
+              hSum = hSum + h(k,iCell)
+           end do
+           h_tend_col = h_tend_col / hSum
+
+           ! Vertical velocity through layer interface at top and 
+           ! bottom is zero.
+           wTop(1,iCell) = 0.0
+           wTop(maxLevelCell(iCell)+1,iCell) = 0.0
+           do k=maxLevelCell(iCell),2,-1
+              wTop(k,iCell) = wTop(k+1,iCell) - div_hu(k,iCell) - h_tend_col(k)
+           end do
+        end do
+
+      elseif (config_vert_grid_type.eq.'zstarWeights') then
+
+        ! This is a test with other weights, not meant to be permanent.
+
+        h_weights = 0.0
+        h_weights(1:5) = 1.0
+        do k=1,10
+           h_weights(5+k) = 1.0-k*0.1
+        end do
+
+        do iCell=1,nCells
+
+           hSum = 0.0
+           do k=1,maxLevelCell(iCell)
+              h_tend_col(k) = - h_weights(k)*h(k,iCell)*div_hu_btr(iCell)
+              hSum = hSum + h_weights(k)*h(k,iCell)
+           end do
+           h_tend_col = h_tend_col / hSum
+
+           ! Vertical velocity through layer interface at top and 
+           ! bottom is zero.
+           wTop(1,iCell) = 0.0
+           wTop(maxLevelCell(iCell)+1,iCell) = 0.0
+           do k=maxLevelCell(iCell),2,-1
+              wTop(k,iCell) = wTop(k+1,iCell) - div_hu(k,iCell) - h_tend_col(k)
+           end do
+        end do
+
       endif
 
-      call mpas_timer_stop(&quot;wTop&quot;)
+      deallocate(div_hu, div_hu_btr, h_tend_col, h_weights)
 
    end subroutine ocn_wtop!}}}
 
@@ -1249,88 +1078,35 @@
 
 ! mrp 110512 I just split compute_tend into compute_tend_u and compute_tend_h.
 !  Some of these variables can be removed, but at a later time.
-      integer :: iEdge, iCell, iVertex, k, cell1, cell2, &amp;
-        vertex1, vertex2, eoe, i, j
+      integer :: iEdge, cell1, cell2, eoe, i, j, k
 
-      integer :: nCells, nEdges, nVertices, nVertLevels, nEdgesSolve
-      real (kind=RKIND) :: flux, vorticity_abs, h_vertex, workpv, q, &amp;
-        upstream_bias, wTopEdge, rho0Inv, r
-      real (kind=RKIND), dimension(:), pointer :: &amp;
-        h_s, fVertex, fEdge, dvEdge, dcEdge, areaCell, areaTriangle, &amp;
-        zMidZLevel, zTopZLevel 
-      real (kind=RKIND), dimension(:,:), pointer :: &amp;
-        weightsOnEdge, kiteAreasOnVertex, h_edge, h, u, uBcl, v, pressure, &amp;
-        tend_u, circulation, vorticity, ke, ke_edge, pv_edge, &amp;
-        MontPot, wTop, divergence, vertViscTopOfEdge
+      integer :: nEdgesSolve
+      real (kind=RKIND), dimension(:), pointer :: fEdge
+      real (kind=RKIND), dimension(:,:), pointer :: weightsOnEdge, u, uBcl
       type (dm_info) :: dminfo
 
-      integer, dimension(:), pointer :: nEdgesOnCell, nEdgesOnEdge, &amp;
-        maxLevelCell, maxLevelEdgeTop, maxLevelVertexBot
-      integer, dimension(:,:), pointer :: &amp;
-        cellsOnEdge, cellsOnVertex, verticesOnEdge, edgesOnCell, &amp;
-        edgesOnEdge, edgesOnVertex
-      real (kind=RKIND) :: u_diffusion
-      real (kind=RKIND), dimension(:), allocatable:: fluxVertTop,w_dudzTopEdge
+      integer, dimension(:), pointer :: maxLevelEdgeTop, nEdgesOnEdge
+      integer, dimension(:,:), pointer :: cellsOnEdge, edgesOnEdge
 
-      real (kind=RKIND), allocatable, dimension(:,:) :: delsq_divergence
-      real (kind=RKIND), allocatable, dimension(:,:) :: delsq_u
-      real (kind=RKIND), allocatable, dimension(:,:) :: delsq_circulation, delsq_vorticity
-
-
-      real (kind=RKIND), dimension(:,:), pointer :: u_src
-      real (kind=RKIND), parameter :: rho_ref = 1000.0
-
       call mpas_timer_start(&quot;ocn_fuperp&quot;)
 
-      h           =&gt; s % h % array
       u           =&gt; s % u % array
       uBcl        =&gt; s % uBcl % array
-      v           =&gt; s % v % array
-      wTop        =&gt; s % wTop % array
-      h_edge      =&gt; s % h_edge % array
-      circulation =&gt; s % circulation % array
-      vorticity   =&gt; s % vorticity % array
-      divergence  =&gt; s % divergence % array
-      ke          =&gt; s % ke % array
-      ke_edge     =&gt; s % ke_edge % array
-      pv_edge     =&gt; s % pv_edge % array
-      MontPot     =&gt; s % MontPot % array
-      pressure    =&gt; s % pressure % array
-
       weightsOnEdge     =&gt; grid % weightsOnEdge % array
-      kiteAreasOnVertex =&gt; grid % kiteAreasOnVertex % array
+      fEdge             =&gt; grid % fEdge % array
+      maxLevelEdgeTop      =&gt; grid % maxLevelEdgeTop % array
       cellsOnEdge       =&gt; grid % cellsOnEdge % array
-      cellsOnVertex     =&gt; grid % cellsOnVertex % array
-      verticesOnEdge    =&gt; grid % verticesOnEdge % array
-      nEdgesOnCell      =&gt; grid % nEdgesOnCell % array
-      edgesOnCell       =&gt; grid % edgesOnCell % array
       nEdgesOnEdge      =&gt; grid % nEdgesOnEdge % array
       edgesOnEdge       =&gt; grid % edgesOnEdge % array
-      edgesOnVertex     =&gt; grid % edgesOnVertex % array
-      dcEdge            =&gt; grid % dcEdge % array
-      dvEdge            =&gt; grid % dvEdge % array
-      areaCell          =&gt; grid % areaCell % array
-      areaTriangle      =&gt; grid % areaTriangle % array
-      h_s               =&gt; grid % h_s % array
-      fVertex           =&gt; grid % fVertex % array
-      fEdge             =&gt; grid % fEdge % array
-      zMidZLevel        =&gt; grid % zMidZLevel % array
-      zTopZLevel        =&gt; grid % zTopZLevel % array
-      maxLevelCell      =&gt; grid % maxLevelCell % array
-      maxLevelEdgeTop      =&gt; grid % maxLevelEdgeTop % array
-      maxLevelVertexBot    =&gt; grid % maxLevelVertexBot % array
 
-                  
-      nCells      = grid % nCells
-      nEdges      = grid % nEdges
+      fEdge       =&gt; grid % fEdge % array
+
       nEdgesSolve = grid % nEdgesSolve
-      nVertices   = grid % nVertices
-      nVertLevels = grid % nVertLevels
 
       !
       ! Put f*uBcl^{perp} in u as a work variable
       !
-      do iEdge=1,grid % nEdgesSolve
+      do iEdge=1,nEdgesSolve
          cell1 = cellsOnEdge(1,iEdge)
          cell2 = cellsOnEdge(2,iEdge)
 
@@ -1349,7 +1125,71 @@
    end subroutine ocn_fuperp!}}}
 
 !***********************************************************************
+!
+!  routine ocn_tendency_init
+!
+!&gt; \brief   Initializes flags used within tendency routines.
+!&gt; \author  Doug Jacobsen
+!&gt; \date    4 November 2011
+!&gt; \version SVN:$Id$
+!&gt; \details 
+!&gt;  This routine initializes flags related to quantities computed within
+!&gt;  other tendency routines.
+!
+!-----------------------------------------------------------------------
 
+    subroutine ocn_tendency_init(err)!{{{
+        integer, intent(out) :: err
+
+        err = 0
+
+        coef_3rd_order = 0.
+
+        if (config_thickness_adv_order == 2) then
+            hadv2nd = 1
+            hadv3rd = 0
+            hadv4th = 0
+        else if (config_thickness_adv_order == 3) then
+            hadv2nd = 0
+            hadv3rd = 1
+            hadv4th = 0
+
+            if(config_monotonic) then
+                coef_3rd_order = 0.25
+            else
+                coef_3rd_order = 1.0
+            endif
+        else if (config_thickness_adv_order == 4) then
+            hadv2nd = 0
+            hadv3rd = 0
+            hadv4th = 1
+        end if
+
+
+        if(config_include_KE_vertex) then
+            ke_vertex_flag = 1
+            ke_cell_flag = 0
+        else
+            ke_vertex_flag = 0
+            ke_cell_flag = 1
+        endif
+
+        if (trim(config_time_integration) == 'RK4') then
+            ! for RK4, PV is really PV = (eta+f)/h
+            fCoef = 1
+        elseif (trim(config_time_integration) == 'split_explicit' &amp;
+          .or.trim(config_time_integration) == 'unsplit_explicit') then
+            ! for split explicit, PV is eta/h because f is added separately to the momentum forcing.
+            ! mrp temp, new should be:
+            fCoef = 0
+            ! old, for testing:
+            !         fCoef = 1
+        end if
+
+    end subroutine ocn_tendency_init!}}}
+
+!***********************************************************************
+
 end module ocn_tendency
 
 !|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

Modified: branches/atmos_physics/src/core_ocean/mpas_ocn_thick_hadv.F
===================================================================
--- branches/atmos_physics/src/core_ocean/mpas_ocn_thick_hadv.F        2012-02-27 22:31:30 UTC (rev 1537)
+++ branches/atmos_physics/src/core_ocean/mpas_ocn_thick_hadv.F        2012-02-27 22:33:23 UTC (rev 1538)
@@ -104,10 +104,10 @@
       integer :: iEdge, nEdges, cell1, cell2, nVertLevels, k
       integer :: iCell, nCells
 
-      integer, dimension(:), pointer :: maxLevelEdgeTop
+      integer, dimension(:), pointer :: maxLevelEdgeBot, MaxLevelCell
       integer, dimension(:,:), pointer :: cellsOnEdge
 
-      real (kind=RKIND) :: flux
+      real (kind=RKIND) :: flux, invAreaCell1, invAreaCell2
       real (kind=RKIND), dimension(:), pointer :: dvEdge, areaCell
 
       !-----------------------------------------------------------------
@@ -124,46 +124,27 @@
       nCells = grid % nCells
       nVertLevels = grid % nVertLevels
 
-      maxLevelEdgeTop =&gt; grid % maxLevelEdgeTop % array
+      maxLevelCell      =&gt; grid % maxLevelCell % array
+      maxLevelEdgeBot   =&gt; grid % maxLevelEdgeBot % array
       cellsOnEdge =&gt; grid % cellsOnEdge % array
       dvEdge =&gt; grid % dvEdge % array
       areaCell =&gt; grid % areaCell % array
 
-      if (config_vert_grid_type.eq.'isopycnal') then

-         do iEdge=1,nEdges
-            cell1 = cellsOnEdge(1,iEdge)
-            cell2 = cellsOnEdge(2,iEdge)
-            do k=1,nVertLevels
-               flux = u(k,iEdge) * dvEdge(iEdge) * h_edge(k,iEdge)
-               tend(k,cell1) = tend(k,cell1) - flux
-               tend(k,cell2) = tend(k,cell2) + flux
-            end do
+      do iEdge=1,nEdges
+         cell1 = cellsOnEdge(1,iEdge)
+         cell2 = cellsOnEdge(2,iEdge)
+         do k=1,maxLevelEdgeBot(iEdge)
+            flux = u(k,iEdge) * dvEdge(iEdge) * h_edge(k,iEdge)
+            tend(k,cell1) = tend(k,cell1) - flux 
+            tend(k,cell2) = tend(k,cell2) + flux 
          end do
-         do iCell=1,nCells
-            do k=1,nVertLevels
-               tend(k,iCell) = tend(k,iCell) / areaCell(iCell)
-            end do
+      end do
+      do iCell=1,nCells
+         do k=1,maxLevelCell(iCell)
+            tend(k,iCell) = tend(k,iCell) / areaCell(iCell)
          end do
+      end do
 
-      elseif (config_vert_grid_type.eq.'zlevel') then
-
-         do iEdge=1,nEdges
-            cell1 = cellsOnEdge(1,iEdge)
-            cell2 = cellsOnEdge(2,iEdge)
-            do k=1,min(1,maxLevelEdgeTop(iEdge))
-               flux = u(k,iEdge) * dvEdge(iEdge) * h_edge(k,iEdge)
-               tend(k,cell1) = tend(k,cell1) - flux
-               tend(k,cell2) = tend(k,cell2) + flux
-            end do
-         end do
-         do iCell=1,nCells
-           tend(1,iCell) = tend(1,iCell) / areaCell(iCell)
-         end do
-
-      endif ! config_vert_grid_type
-
-
    !--------------------------------------------------------------------
 
    end subroutine ocn_thick_hadv_tend!}}}

Modified: branches/atmos_physics/src/core_ocean/mpas_ocn_thick_vadv.F
===================================================================
--- branches/atmos_physics/src/core_ocean/mpas_ocn_thick_vadv.F        2012-02-27 22:31:30 UTC (rev 1537)
+++ branches/atmos_physics/src/core_ocean/mpas_ocn_thick_vadv.F        2012-02-27 22:33:23 UTC (rev 1538)
@@ -98,7 +98,8 @@
       !
       !-----------------------------------------------------------------
 
-      integer :: iCell, nCells
+      integer :: iCell, nCells, nVertLevels, k
+      integer, dimension(:), pointer :: MaxLevelCell
 
       !-----------------------------------------------------------------
       !
@@ -110,15 +111,17 @@
 
       err = 0
 
+      maxLevelCell      =&gt; grid % maxLevelCell % array
+
       nCells = grid % nCells
+      nVertLevels = grid % nVertLevels
 
-      if (config_vert_grid_type.eq.'zlevel') then
-        do iCell=1,nCells
-           tend(1,iCell) =   tend(1,iCell) + wTop(2,iCell)
-        end do
-      endif ! coordinate type
+      do iCell=1,nCells
+         do k=1,maxLevelCell(iCell)
+            tend(k,iCell) = tend(k,iCell) + wTop(k+1,iCell) - wTop(k,iCell)
+         end do
+      end do
 
-
    !--------------------------------------------------------------------
 
    end subroutine ocn_thick_vadv_tend!}}}

Modified: branches/atmos_physics/src/core_ocean/mpas_ocn_time_integration_rk4.F
===================================================================
--- branches/atmos_physics/src/core_ocean/mpas_ocn_time_integration_rk4.F        2012-02-27 22:31:30 UTC (rev 1537)
+++ branches/atmos_physics/src/core_ocean/mpas_ocn_time_integration_rk4.F        2012-02-27 22:33:23 UTC (rev 1538)
@@ -166,6 +166,10 @@
         call mpas_timer_start(&quot;RK4-tendency computations&quot;)
         block =&gt; domain % blocklist
         do while (associated(block))
+
+           ! mrp 111206 put ocn_wtop call at top for ALE
+           call ocn_wtop(provis, provis, block % mesh)
+
            if (.not.config_implicit_vertical_mix) then
               call ocn_vmix_coefs(block % mesh, provis, block % diagnostics, err)
            end if
@@ -179,7 +183,6 @@
            endif
 
            call ocn_tend_scalar(block % tend, provis, block % diagnostics, block % mesh)
-           call enforce_boundaryEdge(block % tend, block % mesh)
            block =&gt; block % next
         end do
         call mpas_timer_stop(&quot;RK4-tendency computations&quot;)
@@ -296,8 +299,6 @@
 
          if (config_implicit_vertical_mix) then
             call mpas_timer_start(&quot;RK4-implicit vert mix&quot;)
-            allocate(A(nVertLevels),C(nVertLevels),uTemp(nVertLevels), &amp;
-               tracersTemp(num_tracers,nVertLevels))
 
             call ocn_vmix_coefs(block % mesh, block % state % time_levs(2) % state, block % diagnostics, err)
 
@@ -369,8 +370,8 @@
       integer :: nCells, nEdges, nVertices, nVertLevels, nEdgesSolve
       real (kind=RKIND) :: vertSum, uhSum, hSum, sshEdge
       real (kind=RKIND), dimension(:), pointer :: &amp;
-        h_s, fVertex, fEdge, dvEdge, dcEdge, areaCell, areaTriangle, &amp;
-        zMidZLevel, zTopZLevel, meshScalingDel2, meshScalingDel4
+        h_s, dvEdge, dcEdge, areaCell, areaTriangle, &amp;
+        meshScalingDel2, meshScalingDel4
       real (kind=RKIND), dimension(:,:), pointer :: &amp;
         weightsOnEdge, kiteAreasOnVertex, h_edge, h, u, v, pressure, &amp;
         tend_u, circulation, vorticity, ke, ke_edge, pv_edge, &amp;
@@ -425,11 +426,6 @@
       areaCell          =&gt; grid % areaCell % array
       areaTriangle      =&gt; grid % areaTriangle % array
       h_s               =&gt; grid % h_s % array
-! mrp 110516 cleanup fvertex fedge not used in this subroutine
-      fVertex           =&gt; grid % fVertex % array
-      fEdge             =&gt; grid % fEdge % array
-      zMidZLevel        =&gt; grid % zMidZLevel % array
-      zTopZLevel        =&gt; grid % zTopZLevel % array
       maxLevelCell      =&gt; grid % maxLevelCell % array
       maxLevelEdgeTop      =&gt; grid % maxLevelEdgeTop % array
       maxLevelVertexBot    =&gt; grid % maxLevelVertexBot % array
@@ -446,15 +442,12 @@
 
            do iEdge=1,grid % nEdges
 
-              ! I am using hZLevel here.  This assumes that SSH is zero everywhere already,
-              ! which should be the case if the barotropic mode is filtered.
-              ! The more general case is to use sshEdge or h_edge.
-              uhSum = (grid % hZLevel % array(1)) * tend_u(1,iEdge)
-              hSum  =  grid % hZLevel % array(1)
+              uhSum = (h_edge(1,iEdge)) * tend_u(1,iEdge)
+              hSum  =  h_edge(1,iEdge)
 
               do k=2,grid % maxLevelEdgeTop % array(iEdge)
-                 uhSum = uhSum + grid % hZLevel % array(k) * tend_u(k,iEdge)
-                 hSum  =  hSum + grid % hZLevel % array(k)
+                 uhSum = uhSum + h_edge(k,iEdge) * tend_u(k,iEdge)
+                 hSum  =  hSum + h_edge(k,iEdge)
               enddo
 
               vertSum = uhSum/hSum
@@ -492,8 +485,8 @@
       integer :: nCells, nEdges, nVertices, nVertLevels, nEdgesSolve
       real (kind=RKIND) :: vertSum, uhSum, hSum, sshEdge
       real (kind=RKIND), dimension(:), pointer :: &amp;
-        h_s, fVertex, fEdge, dvEdge, dcEdge, areaCell, areaTriangle, &amp;
-        zMidZLevel, zTopZLevel, meshScalingDel2, meshScalingDel4
+        h_s, dvEdge, dcEdge, areaCell, areaTriangle, &amp;
+        meshScalingDel2, meshScalingDel4
       real (kind=RKIND), dimension(:,:), pointer :: &amp;
         weightsOnEdge, kiteAreasOnVertex, h_edge, h, u, v, pressure, &amp;
         tend_u, circulation, vorticity, ke, ke_edge, pv_edge, &amp;
@@ -547,11 +540,6 @@
       areaCell          =&gt; grid % areaCell % array
       areaTriangle      =&gt; grid % areaTriangle % array
       h_s               =&gt; grid % h_s % array
-! mrp 110516 cleanup fvertex fedge not used in this subroutine
-      fVertex           =&gt; grid % fVertex % array
-      fEdge             =&gt; grid % fEdge % array
-      zMidZLevel        =&gt; grid % zMidZLevel % array
-      zTopZLevel        =&gt; grid % zTopZLevel % array
       maxLevelCell      =&gt; grid % maxLevelCell % array
       maxLevelEdgeTop      =&gt; grid % maxLevelEdgeTop % array
       maxLevelVertexBot    =&gt; grid % maxLevelVertexBot % array
@@ -566,15 +554,12 @@
 
            do iEdge=1,grid % nEdges
 
-              ! I am using hZLevel here.  This assumes that SSH is zero everywhere already,
-              ! which should be the case if the barotropic mode is filtered.
-              ! The more general case is to use sshedge or h_edge.
-              uhSum = (grid % hZLevel % array(1)) * u(1,iEdge)
-              hSum  =  grid % hZLevel % array(1)
+              uhSum = (h_edge(1,iEdge)) * u(1,iEdge)
+              hSum  =  h_edge(1,iEdge)
 
               do k=2,grid % maxLevelEdgeTop % array(iEdge)
-                 uhSum = uhSum + grid % hZLevel % array(k) * u(k,iEdge)
-                 hSum  =  hSum + grid % hZLevel % array(k)
+                 uhSum = uhSum + h_edge(k,iEdge) * u(k,iEdge)
+                 hSum  =  hSum + h_edge(k,iEdge)
               enddo
 
               vertSum = uhSum/hSum
@@ -588,51 +573,6 @@
 
    end subroutine filter_btr_mode_u!}}}
 
-   subroutine enforce_boundaryEdge(tend, grid)!{{{
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   ! Enforce any boundary conditions on the normal velocity at each edge
-   !
-   ! Input: grid - grid metadata
-   !
-   ! Output: tend_u set to zero at boundaryEdge == 1 locations
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-
-      implicit none
-
-      type (tend_type), intent(inout) :: tend
-      type (mesh_type), intent(in) :: grid
-
-      integer, dimension(:,:), pointer :: boundaryEdge
-      real (kind=RKIND), dimension(:,:), pointer :: tend_u
-      integer :: nCells, nEdges, nVertices, nVertLevels
-      integer :: iEdge, k
-
-      call mpas_timer_start(&quot;enforce_boundaryEdge&quot;)
-
-      nCells      = grid % nCells
-      nEdges      = grid % nEdges
-      nVertices   = grid % nVertices
-      nVertLevels = grid % nVertLevels
-
-      boundaryEdge         =&gt; grid % boundaryEdge % array
-      tend_u      =&gt; tend % u % array
-
-      if(maxval(boundaryEdge).le.0) return
-
-      do iEdge = 1,nEdges
-        do k = 1,nVertLevels
-
-          if(boundaryEdge(k,iEdge).eq.1) then
-             tend_u(k,iEdge) = 0.0
-          endif
-
-        enddo
-       enddo
-      call mpas_timer_stop(&quot;enforce_boundaryEdge&quot;)
-
-   end subroutine enforce_boundaryEdge!}}}
-
 end module ocn_time_integration_rk4
 
 ! vim: foldmethod=marker

Modified: branches/atmos_physics/src/core_ocean/mpas_ocn_time_integration_split.F
===================================================================
--- branches/atmos_physics/src/core_ocean/mpas_ocn_time_integration_split.F        2012-02-27 22:31:30 UTC (rev 1537)
+++ branches/atmos_physics/src/core_ocean/mpas_ocn_time_integration_split.F        2012-02-27 22:33:23 UTC (rev 1538)
@@ -47,6 +47,10 @@
 
    public :: ocn_time_integrator_split
 
+   type (timer_node), pointer :: timer_main, timer_prep, timer_bcl_vel, timer_btr_vel, timer_diagnostic_update, timer_implicit_vmix, &amp;
+                                 timer_halo_diagnostic, timer_halo_ubtr, timer_halo_ssh, timer_halo_f, timer_halo_h, &amp; 
+                                 timer_halo_tracers, timer_halo_ubcl
+
    contains
 
 !|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
@@ -54,7 +58,7 @@
 !  ocn_time_integration_split
 !
 !&gt; \brief MPAS ocean split explicit time integration scheme
-!&gt; \author Doug Jacobsen
+!&gt; \author Mark Petersen
 !&gt; \date   26 September 2011
 !&gt; \version SVN:$Id:$
 !&gt; \details
@@ -63,16 +67,16 @@
 !
 !-----------------------------------------------------------------------
 
-subroutine ocn_time_integrator_split(domain, dt)!{{{
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   ! Advance model state forward in time by the specified time step using 
-   !   Split_Explicit timestepping scheme
-   !
-   ! Input: domain - current model state in time level 1 (e.g., time_levs(1)state%h(:,:)) 
-   !                 plus grid meta-data
-   ! Output: domain - upon exit, time level 2 (e.g., time_levs(2)%state%h(:,:)) contains 
-   !                  model state advanced forward in time by dt seconds
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+    subroutine ocn_time_integrator_split(domain, dt)!{{{
+    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+    ! Advance model state forward in time by the specified time step using 
+    !   Split_Explicit timestepping scheme
+    !
+    ! Input: domain - current model state in time level 1 (e.g., time_levs(1)state%h(:,:)) 
+    !                 plus grid meta-data
+    ! Output: domain - upon exit, time level 2 (e.g., time_levs(2)%state%h(:,:)) contains 
+    !                  model state advanced forward in time by dt seconds
+    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
       implicit none
 
@@ -81,72 +85,73 @@
 
       type (dm_info) :: dminfo
       integer :: iCell, i,k,j, iEdge, cell1, cell2, split_explicit_step, split, &amp;
-        eoe, oldBtrSubcycleTime, newBtrSubcycleTime, uPerpTime, BtrCorIter, &amp;
-        n_bcl_iter(config_n_ts_iter), &amp;
-        vertex1, vertex2, iVertex
-
+                 eoe, oldBtrSubcycleTime, newBtrSubcycleTime, uPerpTime, BtrCorIter, &amp;
+                 n_bcl_iter(config_n_ts_iter)
       type (block_type), pointer :: block
-      real (kind=RKIND) :: uhSum, hSum, sshEdge, flux, &amp;
-         uPerp, uCorr, tracerTemp, coef, FBtr_coeff, sshCell1, sshCell2
-      real (kind=RKIND), dimension(:), pointer :: sshNew
-
+      real (kind=RKIND) :: uhSum, hSum, flux, sshEdge, &amp;
+                 CoriolisTerm, uCorr, temp, temp_h, coef, FBtr_coeff, sshCell1, sshCell2
       integer :: num_tracers, ucorr_coef, err
       real (kind=RKIND), dimension(:,:), pointer :: &amp;
-        u, h, h_edge, ke_edge, vertViscTopOfEdge, vertDiffTopOfCell
+                 u, h, h_edge, ke_edge, vertViscTopOfEdge, vertDiffTopOfCell
       real (kind=RKIND), dimension(:,:,:), pointer :: tracers
       integer, dimension(:), pointer :: &amp; 
-        maxLevelCell, maxLevelEdgeTop
-      real (kind=RKIND), dimension(:), allocatable:: A,C,uTemp, hNew
+                 maxLevelCell, maxLevelEdgeTop
+      real (kind=RKIND), dimension(:), allocatable:: uTemp
       real (kind=RKIND), dimension(:,:), allocatable:: tracersTemp
 
-      call mpas_timer_start(&quot;split_explicit_timestep&quot;)
+      call mpas_timer_start(&quot;se timestep&quot;, .false., timer_main)
 
       !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
       !
       !  Prep variables before first iteration
       !
       !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+      call mpas_timer_start(&quot;se prep&quot;, .false., timer_prep)
       block =&gt; domain % blocklist
       do while (associated(block))
 
+         ! Initialize * variables that are used to compute baroclinic tendencies below.
          do iEdge=1,block % mesh % nEdges
+            do k=1,block % mesh % nVertLevels !maxLevelEdgeTop % array(iEdge)
 
-            ! The baroclinic velocity needs be recomputed at the beginning of a 
-            ! timestep because the implicit vertical mixing is conducted on the
-            ! total u.  We keep uBtr from the previous timestep.
-              block % state % time_levs(1) % state % uBcl % array(:,iEdge) &amp;
-            = block % state % time_levs(1) % state % u % array(:,iEdge) &amp;
-            - block % state % time_levs(1) % state % uBtr % array(iEdge)
+               ! The baroclinic velocity needs be recomputed at the beginning of a 
+               ! timestep because the implicit vertical mixing is conducted on the
+               ! total u.  We keep uBtr from the previous timestep.
+                 block % state % time_levs(1) % state % uBcl % array(k,iEdge) &amp;
+               = block % state % time_levs(1) % state % u    % array(k,iEdge) &amp;
+               - block % state % time_levs(1) % state % uBtr % array(  iEdge)
 
-              block % state % time_levs(2) % state % u % array(:,iEdge) &amp;
-            = block % state % time_levs(1) % state % u % array(:,iEdge)
+                 block % state % time_levs(2) % state % u % array(k,iEdge) &amp;
+               = block % state % time_levs(1) % state % u % array(k,iEdge)
 
-              block % state % time_levs(2) % state % uBcl % array(:,iEdge) &amp;
-            = block % state % time_levs(1) % state % uBcl % array(:,iEdge)
+                 block % state % time_levs(2) % state % uBcl % array(k,iEdge) &amp;
+               = block % state % time_levs(1) % state % uBcl % array(k,iEdge)
 
-         enddo ! iEdge
+                 block % state % time_levs(2) % state % h_edge % array(k,iEdge) &amp;
+               = block % state % time_levs(1) % state % h_edge % array(k,iEdge)
 
-         ! Initialize * variables that are used compute baroclinic tendencies below.
+            end do 
+         end do 
+
            block % state % time_levs(2) % state % ssh % array(:) &amp;
          = block % state % time_levs(1) % state % ssh % array(:)
 
-           block % state % time_levs(2) % state % h_edge % array(:,:) &amp;
-         = block % state % time_levs(1) % state % h_edge % array(:,:)
+         do iCell=1,block % mesh % nCells  
+            do k=1,block % mesh % maxLevelCell % array(iCell)
 
-         do iCell=1,block % mesh % nCells  ! couple tracers to h
-           ! change to maxLevelCell % array(iCell) ?
-           do k=1,block % mesh % nVertLevels
+                 block % state % time_levs(2) % state % h % array(k,iCell) &amp;
+               = block % state % time_levs(1) % state % h % array(k,iCell)
 
-                block % state % time_levs(2) % state % tracers % array(:,k,iCell) &amp; 
-              = block % state % time_levs(1) % state % tracers % array(:,k,iCell) 
-            end do
+                 block % state % time_levs(2) % state % tracers % array(:,k,iCell) &amp; 
+               = block % state % time_levs(1) % state % tracers % array(:,k,iCell) 
 
+            end do
          end do
 
          block =&gt; block % next
       end do
 
-
+      call mpas_timer_stop(&quot;se prep&quot;, timer_prep)
       !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
       ! BEGIN large iteration loop 
       !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -155,671 +160,484 @@
       n_bcl_iter(config_n_ts_iter) = config_n_bcl_iter_end
 
       do split_explicit_step = 1, config_n_ts_iter
-! ---  update halos for diagnostic variables
+         ! ---  update halos for diagnostic variables
 
-        block =&gt; domain % blocklist
-        do while (associated(block))
-
-           call mpas_dmpar_exch_halo_field2d_real(domain % dminfo, block % state % time_levs(2) % state % pv_edge % array(:,:), &amp;
-                                            block % mesh % nVertLevels, block % mesh % nEdges, &amp;
-                                            block % parinfo % edgesToSend, block % parinfo % edgesToRecv)
-
-           if (config_h_mom_eddy_visc4 &gt; 0.0) then
-              call mpas_dmpar_exch_halo_field2d_real(domain % dminfo, block % state % time_levs(2) % state % divergence % array(:,:), &amp;
-                                               block % mesh % nVertLevels, block % mesh % nCells, &amp;
-                                               block % parinfo % cellsToSend, block % parinfo % cellsToRecv)
-              call mpas_dmpar_exch_halo_field2d_real(domain % dminfo, block % state % time_levs(2) % state % vorticity % array(:,:), &amp;
-                                               block % mesh % nVertLevels, block % mesh % nVertices, &amp;
-                                               block % parinfo % verticesToSend, block % parinfo % verticesToRecv)
-           end if
-
-           block =&gt; block % next
-        end do
-
-      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-      !
-      !  Stage 1: Baroclinic velocity (3D) prediction, explicit with long timestep
-      !
-      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-      ! compute velocity tendencies, T(u*,w*,p*)
-
-      block =&gt; domain % blocklist
-      do while (associated(block))
-         if (.not.config_implicit_vertical_mix) then
-            call ocn_vmix_coefs(block % mesh, block % state % time_levs(2) % state, block % diagnostics, err)
-         end if
-         call ocn_tend_u(block % tend, block % state % time_levs(2) % state , block % diagnostics, block % mesh)
-         call enforce_boundaryEdge(block % tend, block % mesh)
-         block =&gt; block % next
-      end do
-
-      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-      ! BEGIN baroclinic iterations on linear Coriolis term
-      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-      do j=1,n_bcl_iter(split_explicit_step)
-
-         ! Use this G coefficient to avoid an if statement within the iEdge loop.
-         if     (trim(config_time_integration) == 'unsplit_explicit') then
-            split = 0
-         elseif (trim(config_time_integration) == 'split_explicit') then
-            split = 1
-         endif
-
+         call mpas_timer_start(&quot;se halo diag&quot;, .false., timer_halo_diagnostic)
          block =&gt; domain % blocklist
          do while (associated(block))
-           allocate(uTemp(block % mesh % nVertLevels))
 
-           ! Put f*uBcl^{perp} in uNew as a work variable
-           call ocn_fuperp(block % state % time_levs(2) % state , block % mesh)
+            call mpas_dmpar_exch_halo_field2d_real(domain % dminfo, &amp;
+               block % state % time_levs(2) % state % pv_edge % array(:,:), &amp;
+               block % mesh % nVertLevels, block % mesh % nEdges, &amp;
+               block % parinfo % edgesToSend, block % parinfo % edgesToRecv)
 
-           do iEdge=1,block % mesh % nEdges
-              cell1 = block % mesh % cellsOnEdge % array(1,iEdge)
-              cell2 = block % mesh % cellsOnEdge % array(2,iEdge)
+            if (config_h_mom_eddy_visc4 &gt; 0.0) then
+               call mpas_dmpar_exch_halo_field2d_real(domain % dminfo, &amp;
+                  block % state % time_levs(2) % state % divergence % array(:,:), &amp;
+                  block % mesh % nVertLevels, block % mesh % nCells, &amp;
+                  block % parinfo % cellsToSend, block % parinfo % cellsToRecv)
+               call mpas_dmpar_exch_halo_field2d_real(domain % dminfo, &amp;
+                  block % state % time_levs(2) % state % vorticity % array(:,:), &amp;
+                  block % mesh % nVertLevels, block % mesh % nVertices, &amp;
+                  block % parinfo % verticesToSend, block % parinfo % verticesToRecv)
+            end if
 
-              uTemp = 0.0  ! could put this after with uTemp(maxleveledgetop+1:nvertlevels)=0
-              do k=1,block % mesh % maxLevelEdgeTop % array(iEdge)
-
-                 ! uBclNew = uBclOld + dt*(-f*uBclPerp + T(u*,w*,p*) + g*grad(SSH*) )
-                 ! Here uNew is a work variable containing -fEdge(iEdge)*uBclPerp(k,iEdge)
-                 uTemp(k) &amp;
-                 = block % state % time_levs(1) % state % uBcl % array(k,iEdge) &amp;
-                 + dt * (block % tend % u % array (k,iEdge) &amp;
-                      + block % state % time_levs(2) % state % u % array (k,iEdge) &amp;  ! this is f*uBcl^{perp}
-                      + split*gravity &amp;
-                        *(  block % state % time_levs(2) % state % ssh % array(cell2) &amp;
-                          - block % state % time_levs(2) % state % ssh % array(cell1) ) &amp;
-                          /block % mesh % dcEdge % array(iEdge) )
-              enddo
-
-              ! Compute GBtrForcing, the vertically averaged forcing
-              sshEdge = 0.5*( &amp;
-                  block % state % time_levs(1) % state % ssh % array(cell1) &amp; 
-                + block % state % time_levs(1) % state % ssh % array(cell2) ) 
-
-              uhSum = (sshEdge + block % mesh % hZLevel % array(1)) * uTemp(1)
-              hSum  =  sshEdge + block % mesh % hZLevel % array(1)
-
-              do k=2,block % mesh % maxLevelEdgeTop % array(iEdge)
-                 uhSum = uhSum + block % mesh % hZLevel % array(k) * uTemp(k)
-                 hSum  =  hSum + block % mesh % hZLevel % array(k)
-              enddo
-              block % state % time_levs(1) % state % GBtrForcing % array(iEdge) = split*uhSum/hSum/dt
-
-
-              do k=1,block % mesh % maxLevelEdgeTop % array(iEdge)
-                 ! These two steps are together here:
-                 !{\bf u}'_{k,n+1} = {\bf u}'_{k,n} - \Delta t {\overline {\bf G}}
-                 !{\bf u}'_{k,n+1/2} = \frac{1}{2}\left({\bf u}^{'}_{k,n} +{\bf u}'_{k,n+1}\right) 
-                 ! so that uBclNew is at time n+1/2
-                block % state % time_levs(2) % state % uBcl % array(k,iEdge) &amp;
-                  = 0.5*( &amp;
-                  block % state % time_levs(1) % state % uBcl % array(k,iEdge) &amp;
-                  + uTemp(k) - dt * block % state % time_levs(1) % state % GBtrForcing % array(iEdge))
-              enddo
-
-           enddo ! iEdge
-
-           deallocate(uTemp)
-
-           block =&gt; block % next
+            block =&gt; block % next
          end do
+         call mpas_timer_stop(&quot;se halo diag&quot;, timer_halo_diagnostic)
 
-        block =&gt; domain % blocklist
-        do while (associated(block))
-           call mpas_dmpar_exch_halo_field2d_real(domain % dminfo, block % state % time_levs(2) % state % uBcl % array(:,:), &amp;
-                                            block % mesh % nVertLevels, block % mesh % nEdges, &amp;
-                                            block % parinfo % edgesToSend, block % parinfo % edgesToRecv)
+         !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+         !
+         !  Stage 1: Baroclinic velocity (3D) prediction, explicit with long timestep
+         !
+         !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-           block =&gt; block % next
-        end do
+         ! compute velocity tendencies, T(u*,w*,p*)
+         call mpas_timer_start(&quot;se bcl vel&quot;, .false., timer_bcl_vel)
 
-      enddo  ! do j=1,config_n_bcl_iter
-      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-      ! END baroclinic iterations on linear Coriolis term
-      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-
-      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-      !
-      !  Stage 2: Barotropic velocity (2D) prediction, explicitly subcycled
-      !
-      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-      oldBtrSubcycleTime = 1
-      newBtrSubcycleTime = 2
-
-      if (trim(config_time_integration) == 'unsplit_explicit') then
-
          block =&gt; domain % blocklist
          do while (associated(block))
-
-            ! For Split_Explicit unsplit, simply set uBtrNew=0, uBtrSubcycle=0, and uNew=uBclNew
-            block % state % time_levs(2) % state % uBtr % array(:) = 0.0
-
-            block % state % time_levs(newBtrSubcycleTime) % state % uBtrSubcycle % array(:) = 0.0
-
-               block % state % time_levs(2) % state % u    % array(:,:) &amp;
-             = block % state % time_levs(2) % state % uBcl % array(:,:) 
-
+            if (.not.config_implicit_vertical_mix) then
+               call ocn_vmix_coefs(block % mesh, block % state % time_levs(2) % state, block % diagnostics, err)
+            end if
+            call ocn_tend_u(block % tend, block % state % time_levs(2) % state , block % diagnostics, block % mesh)
             block =&gt; block % next
-         end do  ! block
+         end do
 
-      elseif (trim(config_time_integration) == 'split_explicit') then
+         !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+         ! BEGIN baroclinic iterations on linear Coriolis term
+         !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+         do j=1,n_bcl_iter(split_explicit_step)
 
-         ! Initialize variables for barotropic subcycling
-         block =&gt; domain % blocklist
-         do while (associated(block))
+            ! Use this G coefficient to avoid an if statement within the iEdge loop.
+            if (trim(config_time_integration) == 'unsplit_explicit') then
+               split = 0
+            elseif (trim(config_time_integration) == 'split_explicit') then
+               split = 1
+            endif
 
-        if (config_filter_btr_mode) then
-          block % state % time_levs(1) % state % GBtrForcing % array(:) = 0.0
-        endif
-
-            do iCell=1,block % mesh % nCells
-              ! sshSubcycleOld = sshOld  
-                block % state % time_levs(oldBtrSubcycleTime) % state % sshSubcycle % array(iCell) &amp; 
-              = block % state % time_levs(1) % state % ssh % array(iCell)  
-
-              ! sshNew = sshOld  This is the first for the summation
-                block % state % time_levs(2) % state % ssh % array(iCell) &amp; 
-              = block % state % time_levs(1) % state % ssh % array(iCell)  
-            enddo
-
-           do iEdge=1,block % mesh % nEdges
-
-              ! uBtrSubcycleOld = uBtrOld 
-                block % state % time_levs(oldBtrSubcycleTime) % state % uBtrSubcycle % array(iEdge) &amp;
-              = block % state % time_levs(1) % state % uBtr % array(iEdge) 
-
-              ! uBtrNew = BtrOld  This is the first for the summation
-                block % state % time_levs(2) % state % uBtr % array(iEdge) &amp;
-              = block % state % time_levs(1) % state % uBtr % array(iEdge) 
-
-              ! FBtr = 0  
-              block % state % time_levs(1) % state % FBtr % array(iEdge) = 0.0
-            enddo
-
-            block =&gt; block % next
-         end do  ! block
-
-      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-      ! BEGIN Barotropic subcycle loop
-      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-         do j=1,config_n_btr_subcycles*config_btr_subcycle_loop_factor
-
-            !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-            ! Barotropic subcycle: initial solve for velecity
-            !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-          if (config_btr_gam1_uWt1&gt;1.0e-12) then  ! only do this part if it is needed in next SSH solve
-            uPerpTime = oldBtrSubcycleTime
-
             block =&gt; domain % blocklist
             do while (associated(block))
+               allocate(uTemp(block % mesh % nVertLevels))
 
-         do iEdge=1,block % mesh % nEdges
+               ! Put f*uBcl^{perp} in uNew as a work variable
+               call ocn_fuperp(block % state % time_levs(2) % state , block % mesh)
 
-               cell1 = block % mesh % cellsOnEdge % array(1,iEdge)
-               cell2 = block % mesh % cellsOnEdge % array(2,iEdge)
+               do iEdge=1,block % mesh % nEdges
+                  cell1 = block % mesh % cellsOnEdge % array(1,iEdge)
+                  cell2 = block % mesh % cellsOnEdge % array(2,iEdge)
 
-            ! Compute -f*uPerp
-            uPerp = 0.0
-            do i = 1,block % mesh % nEdgesOnEdge % array(iEdge)
-               eoe = block % mesh % edgesOnEdge % array(i,iEdge)
-               uPerp = uPerp + block % mesh % weightsOnEdge % array(i,iEdge) &amp;
-                  * block % state % time_levs(uPerpTime) % state % uBtrSubcycle % array(eoe) &amp;
-                  * block % mesh % fEdge  % array(eoe)
-            end do
+                  uTemp = 0.0  ! could put this after with uTemp(maxleveledgetop+1:nvertlevels)=0
+                  do k=1,block % mesh % maxLevelEdgeTop % array(iEdge)
 
-          ! mrp 110606 efficiency note: could make this a 1D integer factor instead of an if statement.
-          if (block % mesh % boundaryEdge % array(1,iEdge).eq.1) then
-                block % state % time_levs(newBtrSubcycleTime) % state % uBtrSubcycle % array(iEdge) = 0.0
-          else
+                     ! uBclNew = uBclOld + dt*(-f*uBclPerp + T(u*,w*,p*) + g*grad(SSH*) )
+                     ! Here uNew is a work variable containing -fEdge(iEdge)*uBclPerp(k,iEdge)
+                      uTemp(k) = block % state % time_levs(1) % state % uBcl % array(k,iEdge) &amp;
+                         + dt * (block % tend % u % array (k,iEdge) &amp;
+                         + block % state % time_levs(2) % state % u % array (k,iEdge) &amp;  ! this is f*uBcl^{perp}
+                         + split * gravity * (  block % state % time_levs(2) % state % ssh % array(cell2) &amp;
+                         - block % state % time_levs(2) % state % ssh % array(cell1) ) &amp;
+                          /block % mesh % dcEdge % array(iEdge) )
+                  enddo
 
-             ! uBtrNew = uBtrOld + dt*(-f*uBtroldPerp - g*grad(SSH) + G)
-                block % state % time_levs(newBtrSubcycleTime) % state % uBtrSubcycle % array(iEdge) &amp;
-              = block % state % time_levs(oldBtrSubcycleTime) % state % uBtrSubcycle % array(iEdge) &amp;
-              + dt/config_n_btr_subcycles *( &amp;
-                        uPerp &amp;
-                      - gravity &amp;
-                        *(  block % state % time_levs(oldBtrSubcycleTime) % state % sshSubcycle % array(cell2) &amp;
-                          - block % state % time_levs(oldBtrSubcycleTime) % state % sshSubcycle % array(cell1) ) &amp;
-                          /block % mesh % dcEdge % array(iEdge) &amp;
-                      + block % state % time_levs(1) % state % GBtrForcing % array(iEdge) )
+                  ! hSum is initialized outside the loop because on land boundaries 
+                  ! maxLevelEdgeTop=0, but I want to initialize hSum with a 
+                  ! nonzero value to avoid a NaN.
+                  uhSum = block % state % time_levs(2) % state % h_edge % array(1,iEdge) * uTemp(1)
+                  hSum  = block % state % time_levs(2) % state % h_edge % array(1,iEdge)
 
-          endif
+                  do k=2,block % mesh % maxLevelEdgeTop % array(iEdge)
+                     uhSum = uhSum + block % state % time_levs(2) % state % h_edge % array(k,iEdge) * uTemp(k)
+                     hSum  =  hSum + block % state % time_levs(2) % state % h_edge % array(k,iEdge)
+                  enddo
+                  block % state % time_levs(1) % state % GBtrForcing % array(iEdge) = split*uhSum/hSum/dt
 
-         end do
 
-         !  Implicit solve for barotropic momentum decay
-         if ( config_btr_mom_decay) then
-            !
-            !  Add term to RHS of momentum equation: -1/gamma u
-            !
-            !  This changes the solve to:
-            !  u^{n+1} = u_provis^{n+1}/(1+dt/gamma)
-            !
-            coef = 1.0/(1.0 + dt/config_n_btr_subcycles/config_btr_mom_decay_time)
-            do iEdge=1,block % mesh % nEdges
-                block % state % time_levs(newBtrSubcycleTime) % state % uBtrSubcycle % array(iEdge) &amp;
-              = block % state % time_levs(newBtrSubcycleTime) % state % uBtrSubcycle % array(iEdge) &amp;
-              * coef
-            end do
+                  do k=1,block % mesh % maxLevelEdgeTop % array(iEdge)
+                     ! These two steps are together here:
+                     !{\bf u}'_{k,n+1} = {\bf u}'_{k,n} - \Delta t {\overline {\bf G}}
+                     !{\bf u}'_{k,n+1/2} = \frac{1}{2}\left({\bf u}^{'}_{k,n} +{\bf u}'_{k,n+1}\right) 
+                     ! so that uBclNew is at time n+1/2
+                       block % state % time_levs(2) % state % uBcl % array(k,iEdge) &amp;
+                     = 0.5*( &amp;
+                       block % state % time_levs(1) % state % uBcl % array(k,iEdge) &amp;
+                     + uTemp(k) - dt * block % state % time_levs(1) % state % GBtrForcing % array(iEdge))
+                  enddo

+               enddo ! iEdge
 
-          endif
+               deallocate(uTemp)
 
-
                block =&gt; block % next
-            end do  ! block
+            end do
 
-
-            !   boundary update on uBtrNew
+            call mpas_timer_start(&quot;se halo ubcl&quot;, .false., timer_halo_ubcl)
             block =&gt; domain % blocklist
             do while (associated(block))
-
-           call mpas_dmpar_exch_halo_field1d_real(domain % dminfo, &amp;
-              block % state % time_levs(newBtrSubcycleTime) % state % uBtrSubcycle % array(:), &amp;
-              block % mesh % nEdges, &amp;
-              block % parinfo % edgesToSend, block % parinfo % edgesToRecv)
-
+               call mpas_dmpar_exch_halo_field2d_real(domain % dminfo, &amp;
+                  block % state % time_levs(2) % state % uBcl % array(:,:), &amp;
+                  block % mesh % nVertLevels, block % mesh % nEdges, &amp;
+                  block % parinfo % edgesToSend, block % parinfo % edgesToRecv)

                block =&gt; block % next
-            end do  ! block
+            end do
+            call mpas_timer_stop(&quot;se halo ubcl&quot;, timer_halo_ubcl)
 
-          endif ! config_btr_gam1_uWt1&gt;1.0e-12
+         end do  ! do j=1,config_n_bcl_iter
 
+         call mpas_timer_stop(&quot;se bcl vel&quot;, timer_bcl_vel)
+         !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+         ! END baroclinic iterations on linear Coriolis term
+         !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+      
 
-            !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-            ! Barotropic subcycle: Compute thickness flux and new SSH: PREDICTOR
-            !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-            block =&gt; domain % blocklist
-            do while (associated(block))
+         !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+         !
+         !  Stage 2: Barotropic velocity (2D) prediction, explicitly subcycled
+         !
+         !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-           block % tend % ssh % array(:) = 0.0
+         call mpas_timer_start(&quot;se btr vel&quot;, .false., timer_btr_vel)
 
-           if (config_btr_solve_SSH2) then
-             ! If config_btr_solve_SSH2=.true., then do NOT accumulate FBtr in this SSH predictor 
-             ! section, because it will be accumulated in the SSH corrector section.
-             FBtr_coeff = 0.0
-           else
-             ! otherwise, DO accumulate FBtr in this SSH predictor section
-             FBtr_coeff = 1.0
-           endif
+         oldBtrSubcycleTime = 1
+         newBtrSubcycleTime = 2
 
-           ! config_btr_gam1_uWt1 sets the forward weighting of velocity in the SSH computation
-           ! config_btr_gam1_uWt1=  1     flux = uBtrNew*H
-           ! config_btr_gam1_uWt1=0.5     flux = 1/2*(uBtrNew+uBtrOld)*H
-           ! config_btr_gam1_uWt1=  0     flux = uBtrOld*H
-           do iEdge=1,block % mesh % nEdges
-              cell1 = block % mesh % cellsOnEdge % array(1,iEdge)
-              cell2 = block % mesh % cellsOnEdge % array(2,iEdge)
+         if (trim(config_time_integration) == 'unsplit_explicit') then
 
-              sshEdge = 0.5 &amp;
-                 *(  block % state % time_levs(oldBtrSubcycleTime) % state % sshSubcycle % array(cell1) &amp;
-                   + block % state % time_levs(oldBtrSubcycleTime) % state % sshSubcycle % array(cell2) )
-              hSum = sum(block % mesh % hZLevel % array (1:block % mesh % maxLevelEdgeTop % array(iEdge)))
-
-              flux = ((1.0-config_btr_gam1_uWt1) &amp; 
-                        * block % state % time_levs(oldBtrSubcycleTime) % state % uBtrSubcycle % array(iEdge) &amp;
-                       + config_btr_gam1_uWt1 &amp;
-                        * block % state % time_levs(newBtrSubcycleTime) % state % uBtrSubcycle % array(iEdge)) &amp;
-                    * (sshEdge + hSum)
-
-               block % tend % ssh % array(cell1) = block % tend % ssh % array(cell1) &amp;
-                 - flux * block % mesh % dvEdge % array(iEdge) 
-               block % tend % ssh % array(cell2) = block % tend % ssh % array(cell2) &amp;
-                 + flux * block % mesh % dvEdge % array(iEdge) 
-
-               block % state % time_levs(1) % state % FBtr % array(iEdge) &amp;
-             = block % state % time_levs(1) % state % FBtr % array(iEdge) &amp;
-             + FBtr_coeff*flux
-         end do

-         ! SSHnew = SSHold + dt/J*(-div(Flux))
-         do iCell=1,block % mesh % nCells 
-
-                block % state % time_levs(newBtrSubcycleTime) % state % sshSubcycle % array(iCell) &amp; 
-              = block % state % time_levs(oldBtrSubcycleTime) % state % sshSubcycle % array(iCell) &amp; 
-              + dt/config_n_btr_subcycles &amp;
-                * block % tend % ssh % array(iCell) / block % mesh % areaCell % array (iCell)
-
-         end do
-
-               block =&gt; block % next
-            end do  ! block
-
-            !   boundary update on SSHnew
             block =&gt; domain % blocklist
             do while (associated(block))
 
-!              block % state % time_levs(newBtrSubcycleTime) % state % sshSubcycle % array(:), &amp;
+               ! For Split_Explicit unsplit, simply set uBtrNew=0, uBtrSubcycle=0, and uNew=uBclNew
+               block % state % time_levs(2) % state % uBtr % array(:) = 0.0
 
-           call mpas_dmpar_exch_halo_field1d_real(domain % dminfo, &amp;
-              block % state % time_levs(newBtrSubcycleTime) % state % sshSubcycle % array(:), &amp;
-              block % mesh % nCells, &amp;
-              block % parinfo % cellsToSend, block % parinfo % cellsToRecv)
+               block % state % time_levs(2) % state % u % array(:,:)  = block % state % time_levs(2) % state % uBcl % array(:,:) 
 
                block =&gt; block % next
             end do  ! block
 
+         elseif (trim(config_time_integration) == 'split_explicit') then
 
-! mrp 110801 begin
-! This whole section, bounded by 'mrp 110801', may be deleted later if it is found
-! that barotropic del2 is not useful.
-            !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-            ! Barotropic subcycle: compute btr_divergence and btr_vorticity for del2(u_btr) 
-            !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+            ! Initialize variables for barotropic subcycling
             block =&gt; domain % blocklist
             do while (associated(block))
-      block % state % time_levs(1) % state % u_diffusionBtr % array(:) = 0.0
-      if ( config_btr_mom_eddy_visc2 &gt; 0.0 ) then
-      !
-      ! Compute circulation and relative vorticity at each vertex
-      !
-      block % state % time_levs(1) % state % circulationBtr % array(:) = 0.0
-      do iEdge=1,block % mesh % nEdges
-         vertex1 = block % mesh % verticesOnEdge % array(1,iEdge)
-         vertex2 = block % mesh % verticesOnEdge % array(2,iEdge)
-             block % state % time_levs(1) % state % circulationBtr % array(vertex1) &amp;
-           = block % state % time_levs(1) % state % circulationBtr % array(vertex1) &amp;
-           - block % mesh % dcEdge % array (iEdge) &amp;
-            *block % state % time_levs(oldBtrSubcycleTime) % state % uBtrSubcycle % array(iEdge)
 
-             block % state % time_levs(1) % state % circulationBtr % array(vertex2) &amp;
-           = block % state % time_levs(1) % state % circulationBtr % array(vertex2) &amp;
-           + block % mesh % dcEdge % array (iEdge) &amp;
-            *block % state % time_levs(oldBtrSubcycleTime) % state % uBtrSubcycle % array(iEdge)
-      end do 
-      do iVertex=1,block % mesh % nVertices
-            block % state % time_levs(1) % state % vorticityBtr % array(iVertex) &amp;
-          = block % state % time_levs(1) % state % circulationBtr % array(iVertex) / block % mesh % areaTriangle % array (iVertex)
-      end do
+               if (config_filter_btr_mode) then
+                  block % state % time_levs(1) % state % GBtrForcing % array(:) = 0.0
+               endif
 
-      !
-      ! Compute the divergence at each cell center
-      !
-      block % state % time_levs(1) % state % divergenceBtr % array(:) = 0.0
-      do iEdge=1,block % mesh % nEdges
-         cell1 = block % mesh % cellsOnEdge % array(1,iEdge)
-         cell2 = block % mesh % cellsOnEdge % array(2,iEdge)
-             block % state % time_levs(1) % state % divergenceBtr % array (cell1) &amp;
-           = block % state % time_levs(1) % state % divergenceBtr % array (cell1) &amp;
-           + block % state % time_levs(oldBtrSubcycleTime) % state % uBtrSubcycle % array(iEdge) &amp;
-            *block % mesh % dvEdge % array(iEdge)
+               do iCell=1,block % mesh % nCells
+                  ! sshSubcycleOld = sshOld  
+                    block % state % time_levs(oldBtrSubcycleTime) % state % sshSubcycle % array(iCell) &amp;
+                  = block % state % time_levs(1) % state % ssh % array(iCell)  
+               end do
 
-             block % state % time_levs(1) % state % divergenceBtr % array (cell2) &amp;
-           = block % state % time_levs(1) % state % divergenceBtr % array (cell2) &amp;
-           - block % state % time_levs(oldBtrSubcycleTime) % state % uBtrSubcycle % array(iEdge) &amp;
-            *block % mesh % dvEdge % array(iEdge)
-      end do
-      do iCell = 1,block % mesh % nCells
-         block % state % time_levs(1) % state % divergenceBtr % array(iCell) &amp;
-       = block % state % time_levs(1) % state % divergenceBtr % array(iCell) &amp;
-        /block % mesh % areaCell % array(iCell)
-      enddo
+               do iEdge=1,block % mesh % nEdges
 
-      !
-      ! Compute Btr diffusion
-      !
-         do iEdge=1,block % mesh % nEdgesSolve
-            cell1 = block % mesh % cellsOnEdge % array(1,iEdge)
-            cell2 = block % mesh % cellsOnEdge % array(2,iEdge)
-            vertex1 = block % mesh % verticesOnEdge % array(1,iEdge)
-            vertex2 = block % mesh % verticesOnEdge % array(2,iEdge)
+                  ! uBtrSubcycleOld = uBtrOld 
+                    block % state % time_levs(oldBtrSubcycleTime) % state % uBtrSubcycle % array(iEdge) &amp;
+                  = block % state % time_levs(1) % state % uBtr % array(iEdge) 
 
-               ! Here -( vorticityBtr(vertex2) - vorticityBtr(vertex1) ) / dvEdge % array (iEdge)
-               ! is - </font>
<font color="red">abla vorticity pointing from vertex 2 to vertex 1, or equivalently 
-               !    + k \times </font>
<font color="gray">abla vorticity pointing from cell1 to cell2.
+                  ! uBtrNew = BtrOld  This is the first for the summation
+                    block % state % time_levs(2) % state % uBtr % array(iEdge) &amp;
+                  = block % state % time_levs(1) % state % uBtr % array(iEdge) 
 
-               block % state % time_levs(1) % state % u_diffusionBtr % array(iEdge) = block % mesh % meshScalingDel2 % array (iEdge) * config_btr_mom_eddy_visc2 * &amp;
-                   (( block % state % time_levs(1) % state % divergenceBtr % array(cell2)  - block % state % time_levs(1) % state % divergenceBtr % array(cell1) ) / block % mesh % dcEdge % array (iEdge)  &amp;
-                  -( block % state % time_levs(1) % state % vorticityBtr % array(vertex2) - block % state % time_levs(1) % state % vorticityBtr % array(vertex1) ) / block % mesh % dvEdge % array (iEdge))
+                  ! FBtr = 0  
+                  block % state % time_levs(1) % state % FBtr % array(iEdge) = 0.0
+               end do
 
-         end do
-      end if
                block =&gt; block % next
             end do  ! block
-! mrp 110801 end
 
-
             !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-            ! Barotropic subcycle: Final solve for velocity.  Iterate for Coriolis term.
+            ! BEGIN Barotropic subcycle loop
             !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+            do j=1,config_n_btr_subcycles*config_btr_subcycle_loop_factor
 
-       do BtrCorIter=1,config_n_btr_cor_iter
+               !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+               ! Barotropic subcycle: VELOCITY PREDICTOR STEP
+               !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+               if (config_btr_gam1_uWt1&gt;1.0e-12) then  ! only do this part if it is needed in next SSH solve
+                  uPerpTime = oldBtrSubcycleTime
 
-          uPerpTime = newBtrSubcycleTime
+                  block =&gt; domain % blocklist
+                  do while (associated(block))
 
-          block =&gt; domain % blocklist
-          do while (associated(block))
+                     do iEdge=1,block % mesh % nEdges
 
-         do iEdge=1,block % mesh % nEdges 
+                        cell1 = block % mesh % cellsOnEdge % array(1,iEdge)
+                        cell2 = block % mesh % cellsOnEdge % array(2,iEdge)
 
-               cell1 = block % mesh % cellsOnEdge % array(1,iEdge)
-               cell2 = block % mesh % cellsOnEdge % array(2,iEdge)
+                        ! Compute the barotropic Coriolis term, -f*uPerp
+                        CoriolisTerm = 0.0
+                        do i = 1,block % mesh % nEdgesOnEdge % array(iEdge)
+                           eoe = block % mesh % edgesOnEdge % array(i,iEdge)
+                           CoriolisTerm = CoriolisTerm &amp;
+                             + block % mesh % weightsOnEdge % array(i,iEdge) &amp;
+                             * block % state % time_levs(uPerpTime) % state % uBtrSubcycle % array(eoe) &amp;
+                             * block % mesh % fEdge % array(eoe)
+                        end do
+      
+                        ! uBtrNew = uBtrOld + dt/J*(-f*uBtroldPerp - g*grad(SSH) + G)
+                        block % state % time_levs(newBtrSubcycleTime) % state % uBtrSubcycle % array(iEdge) &amp;
+                          = (block % state % time_levs(oldBtrSubcycleTime) % state % uBtrSubcycle % array(iEdge) &amp;
+                          + dt / config_n_btr_subcycles * (CoriolisTerm - gravity &amp;
+                          * (block % state % time_levs(oldBtrSubcycleTime) % state % sshSubcycle % array(cell2) &amp;
+                           - block % state % time_levs(oldBtrSubcycleTime) % state % sshSubcycle % array(cell1) ) &amp;
+                          / block % mesh % dcEdge % array(iEdge) &amp;
+                          + block % state % time_levs(1) % state % GBtrForcing % array(iEdge))) * block % mesh % edgeMask % array(1, iEdge)
+                     end do
 
-            ! Compute -f*uPerp
-            uPerp = 0.0
-            do i = 1,block % mesh % nEdgesOnEdge % array(iEdge)
-               eoe = block % mesh % edgesOnEdge % array(i,iEdge)
-               uPerp = uPerp + block % mesh % weightsOnEdge % array(i,iEdge) &amp;
-                  * block % state % time_levs(uPerpTime) % state % uBtrSubcycle % array(eoe) &amp;
-                  * block % mesh % fEdge  % array(eoe) 
-            end do
+                     block =&gt; block % next
+                  end do  ! block
 
-          ! mrp 110606 efficiency note: could make this a 1D integer factor instead of an if statement.
-          if (block % mesh % boundaryEdge % array(1,iEdge).eq.1) then
-                block % state % time_levs(newBtrSubcycleTime) % state % uBtrSubcycle % array(iEdge) = 0.0
-          else
+                !   boundary update on uBtrNew
+                call mpas_timer_start(&quot;se halo ubtr&quot;, .false., timer_halo_ubtr)
+                block =&gt; domain % blocklist
+                do while (associated(block))
 
-             ! uBtrNew = uBtrOld + dt*(-f*uBtroldPerp - g*grad(SSH) + G)
+                   call mpas_dmpar_exch_halo_field1d_real(domain % dminfo, &amp;
+                       block % state % time_levs(newBtrSubcycleTime) % state % uBtrSubcycle % array(:), &amp;
+                       block % mesh % nEdges, block % parinfo % edgesToSend, block % parinfo % edgesToRecv)
 
-             sshCell1 = &amp;
-               (1-config_btr_gam2_SSHWt1)*block % state % time_levs(oldBtrSubcycleTime) % state % sshSubcycle % array(cell1) &amp;
-                + config_btr_gam2_SSHWt1 *block % state % time_levs(newBtrSubcycleTime) % state % sshSubcycle % array(cell1)
+                   block =&gt; block % next
+                end do  ! block
+                call mpas_timer_stop(&quot;se halo ubtr&quot;, timer_halo_ubtr)
+              endif ! config_btr_gam1_uWt1&gt;1.0e-12
 
-             sshCell2 = &amp;
-               (1-config_btr_gam2_SSHWt1)*block % state % time_levs(oldBtrSubcycleTime) % state % sshSubcycle % array(cell2) &amp;
-                + config_btr_gam2_SSHWt1 *block % state % time_levs(newBtrSubcycleTime) % state % sshSubcycle % array(cell2)
+              !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+              ! Barotropic subcycle: SSH PREDICTOR STEP 
+              !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+              block =&gt; domain % blocklist
+              do while (associated(block))
+      
+                block % tend % ssh % array(:) = 0.0
+      
+                if (config_btr_solve_SSH2) then
+                   ! If config_btr_solve_SSH2=.true., then do NOT accumulate FBtr in this SSH predictor 
+                   ! section, because it will be accumulated in the SSH corrector section.
+                   FBtr_coeff = 0.0
+                else
+                   ! otherwise, DO accumulate FBtr in this SSH predictor section
+                   FBtr_coeff = 1.0
+                endif
+      
+                ! config_btr_gam1_uWt1 sets the forward weighting of velocity in the SSH computation
+                ! config_btr_gam1_uWt1=  1     flux = uBtrNew*H
+                ! config_btr_gam1_uWt1=0.5     flux = 1/2*(uBtrNew+uBtrOld)*H
+                ! config_btr_gam1_uWt1=  0     flux = uBtrOld*H
+                ! mrp 120201 efficiency: could we combine the following edge and cell loops?
+                do iEdge=1,block % mesh % nEdges
+                   cell1 = block % mesh % cellsOnEdge % array(1,iEdge)
+                   cell2 = block % mesh % cellsOnEdge % array(2,iEdge)
+      
+                   sshEdge = 0.5 * (block % state % time_levs(oldBtrSubcycleTime) % state % sshSubcycle % array(cell1) &amp;
+                             + block % state % time_levs(oldBtrSubcycleTime) % state % sshSubcycle % array(cell2) )
+                   hSum = sshEdge + block % mesh % referenceBottomDepthTopOfCell % array (block % mesh % maxLevelEdgeTop % array(iEdge)+1)
+      
+                   flux = ((1.0-config_btr_gam1_uWt1) * block % state % time_levs(oldBtrSubcycleTime) % state % uBtrSubcycle % array(iEdge) &amp;
+                          + config_btr_gam1_uWt1 * block % state % time_levs(newBtrSubcycleTime) % state % uBtrSubcycle % array(iEdge)) &amp;
+                          * hSum 
+      
+                   block % tend % ssh % array(cell1) = block % tend % ssh % array(cell1) - flux * block % mesh % dvEdge % array(iEdge)
+                   block % tend % ssh % array(cell2) = block % tend % ssh % array(cell2) + flux * block % mesh % dvEdge % array(iEdge) 
+      
+                   block % state % time_levs(1) % state % FBtr % array(iEdge) = block % state % time_levs(1) % state % FBtr % array(iEdge) &amp;
+                     + FBtr_coeff*flux
+                end do
+      
+                ! SSHnew = SSHold + dt/J*(-div(Flux))
+                do iCell=1,block % mesh % nCells 
+      
+                   block % state % time_levs(newBtrSubcycleTime) % state % sshSubcycle % array(iCell) &amp; 
+                       = block % state % time_levs(oldBtrSubcycleTime) % state % sshSubcycle % array(iCell) &amp; 
+                       + dt/config_n_btr_subcycles * block % tend % ssh % array(iCell) / block % mesh % areaCell % array (iCell)
+      
+                end do
+      
+                block =&gt; block % next
+              end do  ! block
+      
+              !   boundary update on SSHnew
+              call mpas_timer_start(&quot;se halo ssh&quot;, .false., timer_halo_ssh)
+              block =&gt; domain % blocklist
+              do while (associated(block))
+      
+                call mpas_dmpar_exch_halo_field1d_real(domain % dminfo, &amp;
+                     block % state % time_levs(newBtrSubcycleTime) % state % sshSubcycle % array(:), &amp;
+                     block % mesh % nCells, block % parinfo % cellsToSend, block % parinfo % cellsToRecv)
+      
+                block =&gt; block % next
+              end do  ! block
+              call mpas_timer_stop(&quot;se halo ssh&quot;, timer_halo_ssh)
+      
+              !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+              ! Barotropic subcycle: VELOCITY CORRECTOR STEP
+              !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+              do BtrCorIter=1,config_n_btr_cor_iter
+                uPerpTime = newBtrSubcycleTime
+      
+                block =&gt; domain % blocklist
+                do while (associated(block))
+                   do iEdge=1,block % mesh % nEdges 
+                     cell1 = block % mesh % cellsOnEdge % array(1,iEdge)
+                     cell2 = block % mesh % cellsOnEdge % array(2,iEdge)
+      
+                     ! Compute the barotropic Coriolis term, -f*uPerp
+                     CoriolisTerm = 0.0
+                     do i = 1,block % mesh % nEdgesOnEdge % array(iEdge)
+                         eoe = block % mesh % edgesOnEdge % array(i,iEdge)
+                       CoriolisTerm = CoriolisTerm + block % mesh % weightsOnEdge % array(i,iEdge) &amp;
+                             * block % state % time_levs(uPerpTime) % state % uBtrSubcycle % array(eoe) &amp;
+                             * block % mesh % fEdge  % array(eoe) 
+                     end do
+      
+                     ! In this final solve for velocity, SSH is a linear
+                     ! combination of SSHold and SSHnew.
+                     sshCell1 = (1-config_btr_gam2_SSHWt1)*block % state % time_levs(oldBtrSubcycleTime) % state % sshSubcycle % array(cell1) &amp;
+                               +   config_btr_gam2_SSHWt1 *block % state % time_levs(newBtrSubcycleTime) % state % sshSubcycle % array(cell1)
+                     sshCell2 = (1-config_btr_gam2_SSHWt1)*block % state % time_levs(oldBtrSubcycleTime) % state % sshSubcycle % array(cell2) &amp;
+                               +   config_btr_gam2_SSHWt1 *block % state % time_levs(newBtrSubcycleTime) % state % sshSubcycle % array(cell2)
+    
+                     ! uBtrNew = uBtrOld + dt/J*(-f*uBtroldPerp - g*grad(SSH) + G)
+                     block % state % time_levs(newBtrSubcycleTime) % state % uBtrSubcycle % array(iEdge) &amp; 
+                         = (block % state % time_levs(oldBtrSubcycleTime) % state % uBtrSubcycle % array(iEdge) &amp; 
+                         + dt/config_n_btr_subcycles *(CoriolisTerm - gravity *(sshCell2 - sshCell1) /block % mesh % dcEdge % array(iEdge) &amp;
+                         + block % state % time_levs(1) % state % GBtrForcing % array(iEdge))) * block % mesh % edgeMask % array(1,iEdge)
+                   end do
+      
+                   block =&gt; block % next
+                end do  ! block
+      
+                !   boundary update on uBtrNew
+                call mpas_timer_start(&quot;se halo ubtr&quot;, .false., timer_halo_ubtr)
+                block =&gt; domain % blocklist
+                do while (associated(block))
+                   call mpas_dmpar_exch_halo_field1d_real(domain % dminfo, &amp;
+                       block % state % time_levs(newBtrSubcycleTime) % state % uBtrSubcycle % array(:), &amp;
+                       block % mesh % nEdges, block % parinfo % edgesToSend, block % parinfo % edgesToRecv)
+      
+                   block =&gt; block % next
+                end do  ! block
+                call mpas_timer_stop(&quot;se halo ubtr&quot;, timer_halo_ubtr)
+              end do !do BtrCorIter=1,config_n_btr_cor_iter
+      
+              !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+              ! Barotropic subcycle: SSH CORRECTOR STEP
+              !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+              if (config_btr_solve_SSH2) then
+      
+                block =&gt; domain % blocklist
+                do while (associated(block))
+                   block % tend % ssh % array(:) = 0.0
+      
+                  ! config_btr_gam3_uWt2 sets the forward weighting of velocity in the SSH computation
+                  ! config_btr_gam3_uWt2=  1     flux = uBtrNew*H
+                  ! config_btr_gam3_uWt2=0.5     flux = 1/2*(uBtrNew+uBtrOld)*H
+                  ! config_btr_gam3_uWt2=  0     flux = uBtrOld*H
+                  ! mrp 120201 efficiency: could we combine the following edge and cell loops?
+                  do iEdge=1,block % mesh % nEdges
+                     cell1 = block % mesh % cellsOnEdge % array(1,iEdge)
+                     cell2 = block % mesh % cellsOnEdge % array(2,iEdge)
+      
+                     ! SSH is a linear combination of SSHold and SSHnew.
+                     sshCell1 = (1-config_btr_gam2_SSHWt1)*block % state % time_levs(oldBtrSubcycleTime) % state % sshSubcycle % array(cell1) &amp;
+                               +   config_btr_gam2_SSHWt1 *block % state % time_levs(newBtrSubcycleTime) % state % sshSubcycle % array(cell1)
+                     sshCell2 = (1-config_btr_gam2_SSHWt1)*block % state % time_levs(oldBtrSubcycleTime) % state % sshSubcycle % array(cell2) &amp;
+                               +   config_btr_gam2_SSHWt1 *block % state % time_levs(newBtrSubcycleTime) % state % sshSubcycle % array(cell2)
 
-                block % state % time_levs(newBtrSubcycleTime) % state % uBtrSubcycle % array(iEdge) &amp; 
-              = block % state % time_levs(oldBtrSubcycleTime) % state % uBtrSubcycle % array(iEdge) &amp; 
-              + dt/config_n_btr_subcycles *( &amp;
-                        uPerp &amp;
-                      - gravity &amp;
-                        *(  sshCell2 &amp;
-                          - sshCell1 )&amp;
-                          /block % mesh % dcEdge % array(iEdge) &amp;
-                      + block % state % time_levs(1) % state % GBtrForcing % array(iEdge) &amp;
-                      + block % state % time_levs(1) % state % u_diffusionBtr % array(iEdge))
-                      ! added del2 diffusion to btr solve
-
-          endif
-
-         end do
-
-            !  Implicit solve for barotropic momentum decay
-         if ( config_btr_mom_decay) then
-            !  Add term to RHS of momentum equation: -1/gamma u
-            !
-            !  This changes the solve to:
-            !  u^{n+1} = u_provis^{n+1}/(1+dt/gamma)
-            !
-            coef = 1.0/(1.0 + dt/config_n_btr_subcycles/config_btr_mom_decay_time)
-            do iEdge=1,block % mesh % nEdges 
-                block % state % time_levs(newBtrSubcycleTime) % state % uBtrSubcycle % array(iEdge) &amp; 
-              = block % state % time_levs(newBtrSubcycleTime) % state % uBtrSubcycle % array(iEdge) &amp;
-              * coef
-            end do
-
-         endif
-
-               block =&gt; block % next
-            end do  ! block
-
-
-            !   boundary update on uBtrNew
-            block =&gt; domain % blocklist
-            do while (associated(block))
-
-               call mpas_dmpar_exch_halo_field1d_real(domain % dminfo, &amp;
-                  block % state % time_levs(newBtrSubcycleTime) % state % uBtrSubcycle % array(:), &amp;
-                  block % mesh % nEdges, &amp;
-                  block % parinfo % edgesToSend, block % parinfo % edgesToRecv)
-
-               block =&gt; block % next
-            end do  ! block
-
-       end do !do BtrCorIter=1,config_n_btr_cor_iter
-
+                     sshEdge = 0.5 * (sshCell1 + sshCell2)
+                     hSum = sshEdge + block % mesh % referenceBottomDepthTopOfCell % array (block % mesh % maxLevelEdgeTop % array(iEdge)+1)
+      
+                     flux = ((1.0-config_btr_gam3_uWt2) * block % state % time_levs(oldBtrSubcycleTime) % state % uBtrSubcycle % array(iEdge) &amp;
+                            + config_btr_gam3_uWt2 * block % state % time_levs(newBtrSubcycleTime) % state % uBtrSubcycle % array(iEdge)) &amp;
+                            * hSum
+      
+                     block % tend % ssh % array(cell1) = block % tend % ssh % array(cell1) - flux * block % mesh % dvEdge % array(iEdge) 
+                     block % tend % ssh % array(cell2) = block % tend % ssh % array(cell2) + flux * block % mesh % dvEdge % array(iEdge) 
+      
+                     block % state % time_levs(1) % state % FBtr % array(iEdge) = block % state % time_levs(1) % state % FBtr % array(iEdge) + flux
+                  end do
+      
+                  ! SSHnew = SSHold + dt/J*(-div(Flux))
+                  do iCell=1,block % mesh % nCells 
+                    block % state % time_levs(newBtrSubcycleTime) % state % sshSubcycle % array(iCell) &amp; 
+                          = block % state % time_levs(oldBtrSubcycleTime) % state % sshSubcycle % array(iCell) &amp; 
+                          + dt/config_n_btr_subcycles * block % tend % ssh % array(iCell) / block % mesh % areaCell % array (iCell)
+                  end do
+      
+                  block =&gt; block % next
+                end do  ! block
+      
+                !   boundary update on SSHnew
+                call mpas_timer_start(&quot;se halo ssh&quot;, .false., timer_halo_ssh)
+                block =&gt; domain % blocklist
+                do while (associated(block))
+                  call mpas_dmpar_exch_halo_field1d_real(domain % dminfo, &amp;
+                        block % state % time_levs(newBtrSubcycleTime) % state % sshSubcycle % array(:), &amp;
+                        block % mesh % nCells, block % parinfo % cellsToSend, block % parinfo % cellsToRecv)
+      
+                     block =&gt; block % next
+                  end do  ! block
+                  call mpas_timer_stop(&quot;se halo ssh&quot;, timer_halo_ssh)
+               endif ! config_btr_solve_SSH2
+      
+               !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+               ! Barotropic subcycle: Accumulate running sums, advance timestep pointers
+               !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+      
+               block =&gt; domain % blocklist
+               do while (associated(block))
+      
+                  ! uBtrNew = uBtrNew + uBtrSubcycleNEW
+                  ! This accumulates the sum.
+                  ! If the Barotropic Coriolis iteration is limited to one, this could 
+                  ! be merged with the above code.
+                  do iEdge=1,block % mesh % nEdges 
+      
+                       block % state % time_levs(2) % state % uBtr % array(iEdge) &amp;
+                     = block % state % time_levs(2) % state % uBtr % array(iEdge) &amp; 
+                     + block % state % time_levs(newBtrSubcycleTime) % state % uBtrSubcycle % array(iEdge)  
+      
+                  end do  ! iEdge
+                  block =&gt; block % next
+               end do  ! block
+      
+               ! advance time pointers
+               oldBtrSubcycleTime = mod(oldBtrSubcycleTime,2)+1
+               newBtrSubcycleTime = mod(newBtrSubcycleTime,2)+1
+      
+            end do ! j=1,config_n_btr_subcycles
             !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-            ! Barotropic subcycle: Compute thickness flux and new SSH: CORRECTOR
+            ! END Barotropic subcycle loop
             !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-        if (config_btr_solve_SSH2) then
 
-            block =&gt; domain % blocklist
-            do while (associated(block))
-
-           block % tend % ssh % array(:) = 0.0
-
-           ! config_btr_gam3_uWt2 sets the forward weighting of velocity in the SSH computation
-           ! config_btr_gam3_uWt2=  1     flux = uBtrNew*H
-           ! config_btr_gam3_uWt2=0.5     flux = 1/2*(uBtrNew+uBtrOld)*H
-           ! config_btr_gam3_uWt2=  0     flux = uBtrOld*H
-
-           do iEdge=1,block % mesh % nEdges
-              cell1 = block % mesh % cellsOnEdge % array(1,iEdge)
-              cell2 = block % mesh % cellsOnEdge % array(2,iEdge)
-
-              sshEdge = 0.5 &amp;
-                 *(  block % state % time_levs(oldBtrSubcycleTime) % state % sshSubcycle % array(cell1) &amp;
-                   + block % state % time_levs(oldBtrSubcycleTime) % state % sshSubcycle % array(cell2) )
-              hSum = sum(block % mesh % hZLevel % array (1:block % mesh % maxLevelEdgeTop % array(iEdge)))
-
-              flux = ((1.0-config_btr_gam3_uWt2) &amp; 
-                        * block % state % time_levs(oldBtrSubcycleTime) % state % uBtrSubcycle % array(iEdge) &amp;
-                       + config_btr_gam3_uWt2 &amp;
-                        * block % state % time_levs(newBtrSubcycleTime) % state % uBtrSubcycle % array(iEdge)) &amp;
-                    * (sshEdge + hSum)
-
-               block % tend % ssh % array(cell1) = block % tend % ssh % array(cell1) &amp;
-                 - flux * block % mesh % dvEdge % array(iEdge) 
-               block % tend % ssh % array(cell2) = block % tend % ssh % array(cell2) &amp;
-                 + flux * block % mesh % dvEdge % array(iEdge) 
-
-               block % state % time_levs(1) % state % FBtr % array(iEdge) &amp;
-             = block % state % time_levs(1) % state % FBtr % array(iEdge) &amp;
-             + flux
-
-
-         end do

-         ! SSHnew = SSHold + dt/J*(-div(Flux))
-         do iCell=1,block % mesh % nCells 
-
-                block % state % time_levs(newBtrSubcycleTime) % state % sshSubcycle % array(iCell) &amp; 
-              = block % state % time_levs(oldBtrSubcycleTime) % state % sshSubcycle % array(iCell) &amp; 
-              + dt/config_n_btr_subcycles &amp;
-                * block % tend % ssh % array(iCell) / block % mesh % areaCell % array (iCell)
-
-         end do
-
-               block =&gt; block % next
-            end do  ! block
-
-            !   boundary update on SSHnew
-            block =&gt; domain % blocklist
-            do while (associated(block))
-
-           call mpas_dmpar_exch_halo_field1d_real(domain % dminfo, &amp;
-              block % state % time_levs(newBtrSubcycleTime) % state % sshSubcycle % array(:), &amp;
-              block % mesh % nCells, &amp;
-              block % parinfo % cellsToSend, block % parinfo % cellsToRecv)
-
-               block =&gt; block % next
-            end do  ! block
-
-        endif ! config_btr_solve_SSH2
-
-            !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-            ! Barotropic subcycle: Accumulate running sums, advance timestep pointers
-            !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-            block =&gt; domain % blocklist
-            do while (associated(block))
-
-         ! Accumulate SSH in running sum over the subcycles.
-         do iCell=1,block % mesh % nCells 
-                block % state % time_levs(2) % state % ssh % array(iCell) &amp; 
-              = block % state % time_levs(2) % state % ssh % array(iCell) &amp; 
-              + block % state % time_levs(newBtrSubcycleTime) % state % sshSubcycle % array(iCell)  
-         end do
-
-            ! uBtrNew = uBtrNew + uBtrSubcycleNEW
-            ! This accumulates the sum.
-            ! If the Barotropic Coriolis iteration is limited to one, this could 
-            ! be merged with the above code.
-         do iEdge=1,block % mesh % nEdges 
-
-                block % state % time_levs(2) % state % uBtr % array(iEdge) &amp; 
-              = block % state % time_levs(2) % state % uBtr % array(iEdge) &amp; 
-              + block % state % time_levs(newBtrSubcycleTime) % state % uBtrSubcycle % array(iEdge)  
-
-            end do  ! iEdge
-               block =&gt; block % next
-         end do  ! block
-
-            ! advance time pointers
-            oldBtrSubcycleTime = mod(oldBtrSubcycleTime,2)+1
-            newBtrSubcycleTime = mod(newBtrSubcycleTime,2)+1
-
-         end do ! j=1,config_n_btr_subcycles
-      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-      ! END Barotropic subcycle loop
-      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-
             ! Normalize Barotropic subcycle sums: ssh, uBtr, and F
             block =&gt; domain % blocklist
             do while (associated(block))
-
-         do iEdge=1,block % mesh % nEdges
-               block % state % time_levs(1) % state % FBtr % array(iEdge) &amp;
-             = block % state % time_levs(1) % state % FBtr % array(iEdge) &amp;
-             / (config_n_btr_subcycles*config_btr_subcycle_loop_factor)
-
-                block % state % time_levs(2) % state % uBtr % array(iEdge) &amp; 
-              = block % state % time_levs(2) % state % uBtr % array(iEdge) &amp; 
-             / (config_n_btr_subcycles*config_btr_subcycle_loop_factor + 1)
-         end do
-
-        if (config_SSH_from=='avg_of_SSH_subcycles') then
-         do iCell=1,block % mesh % nCells 
-                block % state % time_levs(2) % state % ssh % array(iCell) &amp; 
-              = block % state % time_levs(2) % state % ssh % array(iCell) &amp; 
-             / (config_n_btr_subcycles*config_btr_subcycle_loop_factor + 1)
-         end do
-        elseif (config_SSH_from=='avg_flux') then
-           ! see below
-        else
-         write(0,*) 'Abort: Unknown config_SSH_from option: '&amp;
-           //trim(config_SSH_from)
-         call mpas_dmpar_abort(dminfo)
-        endif
-
+      
+               do iEdge=1,block % mesh % nEdges
+                  block % state % time_levs(1) % state % FBtr % array(iEdge) = block % state % time_levs(1) % state % FBtr % array(iEdge) &amp;
+                      / (config_n_btr_subcycles*config_btr_subcycle_loop_factor)
+      
+                  block % state % time_levs(2) % state % uBtr % array(iEdge) = block % state % time_levs(2) % state % uBtr % array(iEdge) &amp; 
+                     / (config_n_btr_subcycles*config_btr_subcycle_loop_factor + 1)
+               end do
+      
                block =&gt; block % next
             end do  ! block
-
-
+      
+      
             ! boundary update on F
+            call mpas_timer_start(&quot;se halo F&quot;, .false., timer_halo_f)
             block =&gt; domain % blocklist
             do while (associated(block))
-
-           call mpas_dmpar_exch_halo_field1d_real(domain % dminfo, &amp;
-              block % state % time_levs(1) % state % FBtr % array(:), &amp;
-              block % mesh % nEdges, &amp;
-              block % parinfo % edgesToSend, block % parinfo % edgesToRecv)
-
-               block =&gt; block % next
+              call mpas_dmpar_exch_halo_field1d_real(domain % dminfo, &amp;
+                  block % state % time_levs(1) % state % FBtr % array(:), &amp;
+                  block % mesh % nEdges, block % parinfo % edgesToSend, block % parinfo % edgesToRecv)
+      
+              block =&gt; block % next
             end do  ! block
+            call mpas_timer_stop(&quot;se halo F&quot;, timer_halo_f)
 
 
             ! Check that you can compute SSH using the total sum or the individual increments
@@ -831,363 +649,234 @@
 
                allocate(uTemp(block % mesh % nVertLevels))
 
-        if (config_SSH_from=='avg_flux') then
-           ! Accumulate fluxes in the tend % ssh variable
-           block % tend % ssh % array(:) = 0.0
-           do iEdge=1,block % mesh % nEdges
-              cell1 = block % mesh % cellsOnEdge % array(1,iEdge)
-              cell2 = block % mesh % cellsOnEdge % array(2,iEdge)
+               ! Correction velocity    uCorr = (Flux - Sum(h u*))/H
+               ! or, for the full latex version:
+               !{\bf u}^{corr} = \left( {\overline {\bf F}} 
+               !  - \sum_{k=1}^{N^{edge}} h_{k,*}^{edge}  {\bf u}_k^{avg} \right)
+               ! \left/ \sum_{k=1}^{N^{edge}} h_{k,*}^{edge}   \right. 
 
-                 block % tend % ssh % array(cell1) &amp;
-               = block % tend % ssh % array(cell1) &amp;
-               - block % state % time_levs(1) % state % FBtr % array(iEdge) &amp;
-                    * block % mesh % dvEdge % array(iEdge)
+               if (config_u_correction) then
+                  ucorr_coef = 1
+               else
+                  ucorr_coef = 0
+               endif
 
+               do iEdge=1,block % mesh % nEdges
 
-                 block % tend % ssh % array(cell2) &amp;
-               = block % tend % ssh % array(cell2) &amp;
-               + block % state % time_levs(1) % state % FBtr % array(iEdge) &amp;
-                    * block % mesh % dvEdge % array(iEdge)
+                  ! This is u^{avg}
+                  uTemp(:) = block % state % time_levs(2) % state % uBtr % array(iEdge) &amp;
+                     + block % state % time_levs(2) % state % uBcl % array(:,iEdge) 
 
-          end do
+                  ! hSum is initialized outside the loop because on land boundaries 
+                  ! maxLevelEdgeTop=0, but I want to initialize hSum with a 
+                  ! nonzero value to avoid a NaN.
+                  uhSum = block % state % time_levs(2) % state % h_edge % array(1,iEdge) * uTemp(1)
+                  hSum  = block % state % time_levs(2) % state % h_edge % array(1,iEdge)
 
-         do iCell=1,block % mesh % nCells 

-             ! SSHnew = SSHold + dt*(-div(Flux))
-                block % state % time_levs(2) % state % ssh % array(iCell) &amp; 
-              = block % state % time_levs(1) % state % ssh % array(iCell) &amp; 
-              + dt &amp;
-                * block % tend % ssh % array(iCell) / block % mesh % areaCell % array (iCell)
-         end do
-       endif
+                  do k=2,block % mesh % maxLevelEdgeTop % array(iEdge)
+                     uhSum = uhSum + block % state % time_levs(2) % state % h_edge % array(k,iEdge) * uTemp(k)
+                     hSum  =  hSum + block % state % time_levs(2) % state % h_edge % array(k,iEdge)
+                  enddo
 
-         ! Correction velocity    uCorr = (Flux - Sum(h u*))/H
-         ! or, for the full latex version:
-         !u^{corr} = \left( {\overline {\bf F}} 
-         !  - \sum_{k=1}^{N^{edge}} \left(\zeta_{k,n}^{*\;edge}+\Delta z_k\right)  u_k^* \right)
-         !\left/ \sum_{k=1}^{N^{edge}} \left(\zeta_{k,n}^{*\;edge}+\Delta z_k\right)   \right. 
+                  uCorr =   ucorr_coef*(( block % state % time_levs(1) % state % FBtr % array(iEdge) - uhSum)/hSum)
 
-          if (config_u_correction) then
-             ucorr_coef = 1
-          else
-             ucorr_coef = 0
-          endif
+                  ! put u^{tr}, the velocity for tracer transport, in uNew
+                  ! mrp 060611 not sure if boundary enforcement is needed here.  
+                  if (block % mesh % boundaryEdge % array(1,iEdge).eq.1) then
+                     block % state % time_levs(2) % state % u % array(:,iEdge) = 0.0
+                  else
+                     do k=1,block % mesh % maxLevelEdgeTop % array(iEdge)
+                        block % state % time_levs(2) % state % u % array(k,iEdge) = uTemp(k) + uCorr
+                     enddo
+                     do k=block % mesh % maxLevelEdgeTop % array(iEdge)+1,block % mesh % nVertLevels
+                        block % state % time_levs(2) % state % u % array(k,iEdge) = 0.0
+                     end do
+                  endif
 
-           do iEdge=1,block % mesh % nEdges
-              cell1 = block % mesh % cellsOnEdge % array(1,iEdge)
-              cell2 = block % mesh % cellsOnEdge % array(2,iEdge)
+               end do ! iEdge
 
-              sshEdge = 0.5 &amp;
-                 *(  block % state % time_levs(2) % state % ssh % array(cell1) &amp;
-                   + block % state % time_levs(2) % state % ssh % array(cell2) )
+               deallocate(uTemp)
 
-             ! This is u*
-               uTemp(:) &amp;
-             = block % state % time_levs(2) % state % uBtr % array(iEdge) &amp;
-             + block % state % time_levs(2) % state % uBcl % array(:,iEdge) 
-
-              uhSum = (sshEdge + block % mesh % hZLevel % array(1)) * uTemp(1)
-              hSum  =  sshEdge + block % mesh % hZLevel % array(1)
-
-              do k=2,block % mesh % maxLevelEdgeTop % array(iEdge)
-                 uhSum = uhSum + block % mesh % hZLevel % array(k) * uTemp(k)
-                 hSum  =  hSum + block % mesh % hZLevel % array(k)
-              enddo
-
-            uCorr =   ucorr_coef*(( block % state % time_levs(1) % state % FBtr % array(iEdge) &amp;
-                      - uhSum)/hSum)
-
-              ! put u^{tr}, the velocity for tracer transport, in uNew
-          ! mrp 060611 not sure if boundary enforcement is needed here.  
-          if (block % mesh % boundaryEdge % array(1,iEdge).eq.1) then
-              block % state % time_levs(2) % state % u % array(:,iEdge) = 0.0
-          else
-            do k=1,block % mesh % maxLevelEdgeTop % array(iEdge)
-              block % state % time_levs(2) % state % u % array(k,iEdge) = uTemp(k) + uCorr
-            enddo
-            do k=block % mesh % maxLevelEdgeTop % array(iEdge)+1,block % mesh % nVertLevels
-              block % state % time_levs(2) % state % u % array(k,iEdge) = 0.0
-            enddo
-          endif
-
-         ! Put new sshEdge values in h_edge array, for the OcnTendScalar call below.
-             block % state % time_levs(2) % state % h_edge % array(1,iEdge) &amp;
-           = sshEdge + block % mesh % hZLevel % array(1)
-
-           do k=2,block % mesh % nVertLevels
-             block % state % time_levs(2) % state % h_edge % array(k,iEdge) &amp;
-           = block % mesh % hZLevel % array(k)
-           enddo
-
-          end do ! iEdge
-
-         ! Put new SSH values in h array, for the OcnTendScalar call below.
-         do iCell=1,block % mesh % nCells 
-             block % state % time_levs(2) % state % h % array(1,iCell) &amp;
-           = block % state % time_levs(2) % state % ssh % array(iCell) &amp;
-           + block % mesh % hZLevel % array(1)
-
-           ! mrp 110601 efficiency note: Since h just moves back and forth between pointers,
-           ! this is not necessary once initialized.
-           do k=2,block % mesh % nVertLevels
-             block % state % time_levs(2) % state % h % array(k,iCell) &amp;
-           = block % mesh % hZLevel % array(k)
-           enddo
-         enddo ! iCell
-
-           deallocate(uTemp)
-
                block =&gt; block % next
             end do  ! block
 
+         endif ! split_explicit  
 
-      endif ! split_explicit
+         call mpas_timer_stop(&quot;se btr vel&quot;, timer_btr_vel)
 
-      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-      !
-      !  Stage 3: Tracer, density, pressure, vertical velocity prediction
-      !
-      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+         !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+         !
+         !  Stage 3: Tracer, density, pressure, vertical velocity prediction
+         !
+         !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
+         !TDR: it seems almost trivial to hold off on doing T, S and rho updates until the 
+         !TDR: dycore time step is complete. we might want to take this opportunity to clean-up
+         !TDR: Stage3 in order to faciliate the testing of not doing tracer updates after this code is committed to trunk.
+         !TDR: at this point, I am suggesting just pushing some of this code into subroutines. 
+         !TDR: see comments farther down
+
          block =&gt; domain % blocklist
          do while (associated(block))
+            call ocn_wtop(block % state % time_levs(1) % state,block % state % time_levs(2) % state, block % mesh)
 
-           call ocn_wtop(block % state % time_levs(2) % state, block % mesh)
+            call ocn_tend_h     (block % tend, block % state % time_levs(2) % state , block % diagnostics, block % mesh)
+            call ocn_tend_scalar(block % tend, block % state % time_levs(2) % state , block % diagnostics, block % mesh)
 
-      if (trim(config_time_integration) == 'unsplit_explicit') then
-           call ocn_tend_h(block % tend, block % state % time_levs(2) % state , block % diagnostics, block % mesh)
-      endif
+            block =&gt; block % next
+         end do
 
-           call ocn_tend_scalar(block % tend, block % state % time_levs(2) % state , block % diagnostics, block % mesh)
+         ! update halo for thickness and tracer tendencies
+         call mpas_timer_start(&quot;se halo h&quot;, .false., timer_halo_h)
+         block =&gt; domain % blocklist
+         do while (associated(block))
+            call mpas_dmpar_exch_halo_field2d_real(domain % dminfo, block % tend % h % array(:,:), &amp;
+               block % mesh % nVertLevels, block % mesh % nCells, &amp;
+               block % parinfo % cellsToSend, block % parinfo % cellsToRecv)
 
-           block =&gt; block % next
+            block =&gt; block % next
          end do
+         call mpas_timer_stop(&quot;se halo h&quot;, timer_halo_h)
 
-        ! update halo for thicknes for unsplit only
-        if (trim(config_time_integration) == 'unsplit_explicit') then
-           block =&gt; domain % blocklist
-           do while (associated(block))
-              call mpas_dmpar_exch_halo_field2d_real(domain % dminfo, block % tend % h % array(:,:), &amp;
-                                               block % mesh % nVertLevels, block % mesh % nCells, &amp;
-                                               block % parinfo % cellsToSend, block % parinfo % cellsToRecv)
-              block =&gt; block % next
-           end do
-        endif ! unsplit_explicit
+         block =&gt; domain % blocklist
+         do while (associated(block))
 
+            !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+            !
+            !  If iterating, reset variables for next iteration
+            !
+            !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+            if (split_explicit_step &lt; config_n_ts_iter) then
 
-        block =&gt; domain % blocklist
-        do while (associated(block))
-           allocate(hNew(block % mesh % nVertLevels))
+            !TDR: should we move this code into a subroutine called &quot;compute_intermediate_value_at_midtime&quot;
+            !TDR: this could be within a contains statement in this routine
 
-        if (trim(config_new_btr_variables_from) == 'last_subcycle') then
-           ! This points to the last barotropic SSH subcycle
-           sshNew =&gt; block % state % time_levs(oldBtrSubcycleTime) % state % sshSubcycle % array
-        elseif (trim(config_new_btr_variables_from) == 'btr_avg') then
-           ! This points to the tendency variable SSH*
-           sshNew =&gt; block % state % time_levs(2) % state % ssh % array
-        endif
+               ! Only need T &amp; S for earlier iterations,
+               ! then all the tracers needed the last time through.
+               do iCell=1,block % mesh % nCells
+                  ! sshNew is a pointer, defined above.
+                  do k=1,block % mesh % maxLevelCell % array(iCell)
 
-      if (trim(config_time_integration) == 'unsplit_explicit') then
+                     ! this is h_{n+1}
+                     temp_h &amp;
+                        = block % state % time_levs(1) % state % h % array(k,iCell) &amp;
+                        + dt* block % tend % h % array(k,iCell) 
 
-         do iCell=1,block % mesh % nCells
-           ! this is h_{n+1}
-             block % state % time_levs(2) % state % h % array(:,iCell) &amp;
-           = block % state % time_levs(1) % state % h % array(:,iCell) &amp;
-           + dt* block % tend % h % array(:,iCell) 
+                     ! this is h_{n+1/2}
+                       block % state % time_levs(2) % state % h % array(k,iCell) &amp;
+                     = 0.5*(  &amp;
+                       block % state % time_levs(1) % state % h % array(k,iCell) &amp;
+                       + temp_h)
 
-            ! this is only for the hNew computation below, so there is the correct
-            ! value in the ssh variable for unsplit_explicit case.
-            block % state % time_levs(oldBtrSubcycleTime) % state % sshSubcycle % array(iCell) &amp;
-          = block % state % time_levs(2) % state % h % array(1,iCell) &amp;
-          - block % mesh % hZLevel % array(1)
-           end do ! iCell
+                     do i=1,2
+                        ! This is Phi at n+1
+                        temp = (  &amp;
+                           block % state % time_levs(1) % state % tracers % array(i,k,iCell) &amp;
+                         * block % state % time_levs(1) % state % h % array(k,iCell) &amp;
+                         + dt * block % tend % tracers % array(i,k,iCell)) &amp;
+                              / temp_h
+  
+                        ! This is Phi at n+1/2
+                          block % state % time_levs(2) % state % tracers % array(i,k,iCell) &amp;
+                        = 0.5*( &amp;
+                          block % state % time_levs(1) % state % tracers % array(i,k,iCell) &amp;
+                          + temp )
+                     end do
+                  end do
+               end do ! iCell
 
-      endif ! unsplit_explicit
+               ! uBclNew is u'_{n+1/2}
+               ! uBtrNew is {\bar u}_{avg}
+               ! uNew is u^{tr} 
 
-           ! Only need T &amp; S for earlier iterations,
-           ! then all the tracers needed the last time through.
-         if (split_explicit_step &lt; config_n_ts_iter) then
+               ! mrp 110512  I really only need this to compute h_edge, density, pressure, and SSH
+               ! I can par this down later.
+               call ocn_diagnostic_solve(dt, block % state % time_levs(2) % state, block % mesh)
 
-           hNew(:) = block % mesh % hZLevel % array(:)
-           do iCell=1,block % mesh % nCells
-              ! sshNew is a pointer, defined above.
-              hNew(1) =  sshNew(iCell) + block % mesh % hZLevel % array(1)
-              do k=1,block % mesh % maxLevelCell % array(iCell)
-                 do i=1,2
-                ! This is Phi at n+1
-                tracerTemp &amp;
-                = (  block % state % time_levs(1) % state % tracers % array(i,k,iCell) &amp;
-                   * block % state % time_levs(1) % state % h % array(k,iCell) &amp;
-                 + dt * block % tend % tracers % array(i,k,iCell) &amp;
-                  ) / hNew(k)
+            !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+            !
+            !  If large iteration complete, compute all variables at time n+1
+            !
+            !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+            elseif (split_explicit_step == config_n_ts_iter) then
 
-                ! This is Phi at n+1/2
-                   block % state % time_levs(2) % state % tracers % array(i,k,iCell)  &amp;
-                 = 0.5*( &amp;
-                   block % state % time_levs(1) % state % tracers % array(i,k,iCell) &amp;
-                 + tracerTemp )
-                 enddo
-              end do
-           end do ! iCell
+            !TDR: should we move this code into a subroutine called &quot;compute_final_values_at_nplus1&quot;?
+            !TDR: this could be within a contains statement in this routine
 
+               do iCell=1,block % mesh % nCells
+                  do k=1,block % mesh % maxLevelCell % array(iCell)
 
-          if (trim(config_time_integration) == 'unsplit_explicit') then
+                     ! this is h_{n+1}
+                        block % state % time_levs(2) % state % h % array(k,iCell) &amp;
+                      = block % state % time_levs(1) % state % h % array(k,iCell) &amp;
+                      + dt* block % tend % h % array(k,iCell) 
 
-            ! compute h*, which is h at n+1/2 and put into array hNew
-            ! on last iteration, hNew remains at n+1
-           do iCell=1,block % mesh % nCells
-                 block % state % time_levs(2) % state % h % array(1,iCell) &amp;
-                 = 0.5*( &amp;
-                 block % state % time_levs(2) % state % h % array(1,iCell) &amp;
-               + block % state % time_levs(1) % state % h % array(1,iCell) )
+                     ! This is Phi at n+1
+                     do i=1,block % state % time_levs(1) % state % num_tracers
+                           block % state % time_levs(2) % state % tracers % array(i,k,iCell)  &amp;
+                        = (block % state % time_levs(1) % state % tracers % array(i,k,iCell) &amp;
+                         * block % state % time_levs(1) % state % h % array(k,iCell) &amp;
+                         + dt * block % tend % tracers % array(i,k,iCell)) &amp;
+                         / block % state % time_levs(2) % state % h % array(k,iCell)
 
-           end do ! iCell
-          endif ! unsplit_explicit
+                     enddo
+                  end do
+               end do
 
-          ! compute u*, the velocity for tendency terms.  Put in uNew.
-          ! uBclNew is at time n+1/2 here.
-          ! This overwrites u^{tr}, the tracer transport velocity, which was in uNew.
-          ! The following must occur after  call OcnTendScalar
-           do iEdge=1,block % mesh % nEdges
-               block % state % time_levs(2) % state % u    % array(:,iEdge) &amp;
-             = block % state % time_levs(2) % state % uBtr % array(iEdge) &amp;
-             + block % state % time_levs(2) % state % uBcl % array(:,iEdge) 
-           end do ! iEdge
+               ! Recompute final u to go on to next step.
+               ! u_{n+1} = uBtr_{n+1} + uBcl_{n+1} 
+               ! Right now uBclNew is at time n+1/2, so back compute to get uBcl at time n+1
+               !   using uBcl_{n+1/2} = 1/2*(uBcl_n + u_Bcl_{n+1})
+               ! so the following lines are
+               ! u_{n+1} = uBtr_{n+1} + 2*uBcl_{n+1/2} - uBcl_n
+               ! note that uBcl is recomputed at the beginning of the next timestep due to Imp Vert mixing,
+               ! so uBcl does not have to be recomputed here.
+      
+               do iEdge=1,block % mesh % nEdges
+                  do k=1,block % mesh % maxLevelEdgeTop % array(iEdge)
+                       block % state % time_levs(2) % state % u    % array(k,iEdge) &amp;
+                     = block % state % time_levs(2) % state % uBtr % array(  iEdge) &amp;
+                    +2*block % state % time_levs(2) % state % uBcl % array(k,iEdge) &amp;
+                     - block % state % time_levs(1) % state % uBcl % array(k,iEdge)
+                  end do
+               end do ! iEdges
 
-         elseif (split_explicit_step == config_n_ts_iter) then
+            endif ! split_explicit_step
 
-           hNew(:) = block % mesh % hZLevel % array(:)
-           do iCell=1,block % mesh % nCells
-              ! sshNew is a pointer, defined above.
-              hNew(1) =  sshNew(iCell) + block % mesh % hZLevel % array(1)
-              do k=1,block % mesh % maxLevelCell % array(iCell)
-                 do i=1,block % state % time_levs(1) % state % num_tracers
-                ! This is Phi at n+1
-                   block % state % time_levs(2) % state % tracers % array(i,k,iCell)  &amp;
-                = (  block % state % time_levs(1) % state % tracers % array(i,k,iCell) &amp;
-                   * block % state % time_levs(1) % state % h % array(k,iCell) &amp;
-                 + dt * block % tend % tracers % array(i,k,iCell) &amp;
-                  ) / hNew(k)
+            block =&gt; block % next
+         end do
 
-                 enddo
-              end do
-           end do
-
-         endif ! split_explicit_step
-           deallocate(hNew)
-
-         block =&gt; block % next
-       end do
-
         ! Boundary update on tracers.  This is placed here, rather than 
         ! on tend % tracers as in RK4, because I needed to update 
         ! afterwards for the del4 diffusion operator.
-        block =&gt; domain % blocklist
-        do while (associated(block))
-           call mpas_dmpar_exch_halo_field3d_real(domain % dminfo, block % state % time_levs(2) % state % tracers % array(:,:,:), &amp;
-                                            block % tend % num_tracers, block % mesh % nVertLevels, block % mesh % nCells, &amp;
-                                            block % parinfo % cellsToSend, block % parinfo % cellsToRecv)
-           block =&gt; block % next
-        end do
+         call mpas_timer_start(&quot;se halo tracers&quot;, .false., timer_halo_tracers)
+         block =&gt; domain % blocklist
+         do while (associated(block))
 
+            call mpas_dmpar_exch_halo_field3d_real(domain % dminfo, block % state % time_levs(2) % state % tracers % array(:,:,:), &amp;
+               block % tend % num_tracers, block % mesh % nVertLevels, block % mesh % nCells, block % parinfo % cellsToSend, block % parinfo % cellsToRecv)
 
-         if (split_explicit_step &lt; config_n_ts_iter) then
-            ! mrp 110512  I really only need this to compute h_edge, density, pressure.
-            ! I can par this down later.
-            block =&gt; domain % blocklist
-            do while (associated(block))
+            block =&gt; block % next
+         end do
+         call mpas_timer_stop(&quot;se halo tracers&quot;, timer_halo_tracers)
 
-               call ocn_diagnostic_solve(dt, block % state % time_levs(2) % state, block % mesh)
 
-               block =&gt; block % next
-            end do
-         endif
 
       end do  ! split_explicit_step = 1, config_n_ts_iter
       !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
       ! END large iteration loop 
       !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-      !
-      !  A little clean up at the end: decouple new scalar fields and compute diagnostics for new state
-      !
       block =&gt; domain % blocklist
       do while (associated(block))
 
-        if (trim(config_new_btr_variables_from) == 'last_subcycle') then
-         do iEdge=1,block % mesh % nEdges
-               ! uBtrNew = uBtrSubcycleNew  (old here is because counter already flipped)
-               ! This line is not needed if u is resplit at the beginning of the timestep.
-                block % state % time_levs(2) % state % uBtr % array(iEdge) &amp; 
-              = block % state % time_levs(oldBtrSubcycleTime) % state % uBtrSubcycle % array(iEdge)  
-         enddo ! iEdges
-        elseif (trim(config_new_btr_variables_from) == 'btr_avg') then
-               ! uBtrNew from u*.  this is done above, so u* is already in
-               ! block % state % time_levs(2) % state % uBtr % array(iEdge) 
-        else
-         write(0,*) 'Abort: Unknown config_new_btr_variables_from: '&amp;
-           //trim(config_time_integration)
-         call mpas_dmpar_abort(dminfo)
-       endif
 
-         ! Recompute final u to go on to next step.
-         ! u_{n+1} = uBtr_{n+1} + uBcl_{n+1} 
-         ! Right now uBclNew is at time n+1/2, so back compute to get uBcl at time n+1
-         !   using uBcl_{n+1/2} = 1/2*(uBcl_n + u_Bcl_{n+1})
-         ! so the following lines are
-         ! u_{n+1} = uBtr_{n+1} + 2*uBcl_{n+1/2} - uBcl_n
-         ! note that uBcl is recomputed at the beginning of the next timestep due to Imp Vert mixing,
-         ! so uBcl does not have to be recomputed here.
+         !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+         !
+         !  Implicit vertical mixing, done after timestep is complete
+         !
+         !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-         do iEdge=1,block % mesh % nEdges
-            do k=1,block % mesh % maxLevelEdgeTop % array(iEdge)
-
-               block % state % time_levs(2) % state % u % array(k,iEdge) &amp; 
-            =  block % state % time_levs(2) % state % uBtr % array(iEdge) &amp;
-            +2*block % state % time_levs(2) % state % uBcl % array(k,iEdge) &amp;
-            -  block % state % time_levs(1) % state % uBcl % array(k,iEdge)
-            enddo
-            ! mrp 110607 zero out velocity below land edges. efficiency: this may not be required.
-            do k=block % mesh % maxLevelEdgeTop % array(iEdge) + 1, block % mesh % nVertLevels
-               block % state % time_levs(2) % state % u % array(k,iEdge) = 0.0
-            enddo
-
-         enddo ! iEdges
-
-        if (trim(config_time_integration) == 'split_explicit') then
-
-        if (trim(config_new_btr_variables_from) == 'last_subcycle') then
-         do iCell=1,block % mesh % nCells
-         ! SSH for the next step is from the end of the barotropic subcycle.
-               block % state % time_levs(2) % state % ssh % array(iCell) &amp; 
-            =  block % state % time_levs(oldBtrSubcycleTime) % state % sshSubcycle % array(iCell) 
-         end do ! iCell
-        elseif (trim(config_new_btr_variables_from) == 'btr_avg') then
-               ! sshNew from ssh*.  This is done above, so ssh* is already in
-               ! block % state % time_levs(2) % state % ssh % array(iCell) 
-        endif
-
-         do iCell=1,block % mesh % nCells
-         ! Put new SSH values in h array, for the OcnTendScalar call below.
-             block % state % time_levs(2) % state % h % array(1,iCell) &amp;
-           = block % state % time_levs(2) % state % ssh % array(iCell) &amp;
-           + block % mesh % hZLevel % array(1)
-
-           ! mrp 110601 efficiency note: Since h just moves back and forth between pointers,
-           ! this is not necessary once initialized.
-           do k=2,block % mesh % nVertLevels
-             block % state % time_levs(2) % state % h % array(k,iCell) &amp;
-           = block % mesh % hZLevel % array(k)
-           end do
-         end do ! iCell
-       end if ! split_explicit

-       !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-       !
-       !  Implicit vertical mixing, done after timestep is complete
-       !
-       !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
          u           =&gt; block % state % time_levs(2) % state % u % array
          tracers     =&gt; block % state % time_levs(2) % state % tracers % array
          h           =&gt; block % state % time_levs(2) % state % h % array
@@ -1200,43 +889,34 @@
          maxLevelEdgeTop =&gt; block % mesh % maxLevelEdgeTop % array
 
          if (config_implicit_vertical_mix) then
-            allocate(A(block % mesh % nVertLevels),C(block % mesh % nVertLevels),uTemp(block % mesh % nVertLevels), &amp;
-               tracersTemp(num_tracers,block % mesh % nVertLevels))
-
             call ocn_vmix_coefs(block % mesh, block % state % time_levs(2) % state, block % diagnostics, err)
 
-            !
             !  Implicit vertical solve for momentum
-            !
-
             call ocn_vel_vmix_tend_implicit(block % mesh, dt, ke_edge, vertvisctopofedge, h, h_edge, u, err)
-
-            !
+      
             !  Implicit vertical solve for tracers
-            !
             call ocn_tracer_vmix_tend_implicit(block % mesh, dt, vertdifftopofcell, h, tracers, err)
          end if
 
          if (config_test_case == 1) then    ! For case 1, wind field should be fixed
             block % state % time_levs(2) % state % u % array(:,:) = block % state % time_levs(1) % state % u % array(:,:)
          end if
-
          call ocn_diagnostic_solve(dt, block % state % time_levs(2) % state, block % mesh)
-
          call mpas_reconstruct(block % mesh, block % state % time_levs(2) % state % u % array,          &amp;
-                          block % state % time_levs(2) % state % uReconstructX % array,            &amp;
-                          block % state % time_levs(2) % state % uReconstructY % array,            &amp;
-                          block % state % time_levs(2) % state % uReconstructZ % array,            &amp;
-                          block % state % time_levs(2) % state % uReconstructZonal % array,        &amp;
-                          block % state % time_levs(2) % state % uReconstructMeridional % array    &amp;
-                         )
+            block % state % time_levs(2) % state % uReconstructX % array,            &amp;
+            block % state % time_levs(2) % state % uReconstructY % array,            &amp;
+            block % state % time_levs(2) % state % uReconstructZ % array,            &amp;
+            block % state % time_levs(2) % state % uReconstructZonal % array,        &amp;
+            block % state % time_levs(2) % state % uReconstructMeridional % array)
 
          call ocn_time_average_accumulate(block % state % time_levs(2) % state, block % state % time_levs(1) % state)
 
+
          block =&gt; block % next
       end do
-      call mpas_timer_stop(&quot;split_explicit_timestep&quot;)
+      call mpas_timer_stop(&quot;se timestep&quot;, timer_main)
 
+
    end subroutine ocn_time_integrator_split!}}}
 
    subroutine filter_btr_mode_tend_u(tend, s, d, grid)!{{{
@@ -1256,110 +936,49 @@
       type (diagnostics_type), intent(in) :: d
       type (mesh_type), intent(in) :: grid
 
-! mrp 110512 I just split compute_tend into compute_tend_u and compute_tend_h.
-!  Some of these variables can be removed, but at a later time.
-      integer :: iEdge, iCell, iVertex, k, cell1, cell2, &amp;
-        vertex1, vertex2, eoe, i, j
+      integer :: iEdge, k
 
       integer :: nCells, nEdges, nVertices, nVertLevels, nEdgesSolve
-      real (kind=RKIND) :: vertSum, uhSum, hSum, sshEdge
-      real (kind=RKIND), dimension(:), pointer :: &amp;
-        h_s, fVertex, fEdge, dvEdge, dcEdge, areaCell, areaTriangle, &amp;
-        zMidZLevel, zTopZLevel, meshScalingDel2, meshScalingDel4
+      real (kind=RKIND) :: vertSum, uhSum, hSum
       real (kind=RKIND), dimension(:,:), pointer :: &amp;
-        weightsOnEdge, kiteAreasOnVertex, h_edge, h, u, v, pressure, &amp;
-        tend_u, circulation, vorticity, ke, ke_edge, pv_edge, &amp;
-        MontPot, wTop, divergence, vertViscTopOfEdge
+        h_edge, h, u,tend_u
       type (dm_info) :: dminfo
 
-      integer, dimension(:), pointer :: nEdgesOnCell, nEdgesOnEdge, &amp;
-        maxLevelCell, maxLevelEdgeTop, maxLevelVertexBot
-      integer, dimension(:,:), pointer :: &amp;
-        cellsOnEdge, cellsOnVertex, verticesOnEdge, edgesOnCell, &amp;
-        edgesOnEdge, edgesOnVertex
-      real (kind=RKIND) :: u_diffusion
-      real (kind=RKIND), dimension(:), allocatable:: fluxVertTop,w_dudzTopEdge
+      integer, dimension(:), pointer :: maxLevelEdgeTop
 
-      real (kind=RKIND), allocatable, dimension(:,:) :: delsq_divergence
-      real (kind=RKIND), allocatable, dimension(:,:) :: delsq_u
-      real (kind=RKIND), allocatable, dimension(:,:) :: delsq_circulation, delsq_vorticity
-
-
-      real (kind=RKIND), dimension(:,:), pointer :: u_src
-      real (kind=RKIND), parameter :: rho_ref = 1000.0
-
       call mpas_timer_start(&quot;filter_btr_mode_tend_u&quot;)
 
       h           =&gt; s % h % array
       u           =&gt; s % u % array
-      v           =&gt; s % v % array
-      wTop        =&gt; s % wTop % array
       h_edge      =&gt; s % h_edge % array
-      circulation =&gt; s % circulation % array
-      vorticity   =&gt; s % vorticity % array
-      divergence  =&gt; s % divergence % array
-      ke          =&gt; s % ke % array
-      ke_edge     =&gt; s % ke_edge % array
-      pv_edge     =&gt; s % pv_edge % array
-      MontPot     =&gt; s % MontPot % array
-      pressure    =&gt; s % pressure % array
-      vertViscTopOfEdge =&gt; d % vertViscTopOfEdge % array
 
-      weightsOnEdge     =&gt; grid % weightsOnEdge % array
-      kiteAreasOnVertex =&gt; grid % kiteAreasOnVertex % array
-      cellsOnEdge       =&gt; grid % cellsOnEdge % array
-      cellsOnVertex     =&gt; grid % cellsOnVertex % array
-      verticesOnEdge    =&gt; grid % verticesOnEdge % array
-      nEdgesOnCell      =&gt; grid % nEdgesOnCell % array
-      edgesOnCell       =&gt; grid % edgesOnCell % array
-      nEdgesOnEdge      =&gt; grid % nEdgesOnEdge % array
-      edgesOnEdge       =&gt; grid % edgesOnEdge % array
-      edgesOnVertex     =&gt; grid % edgesOnVertex % array
-      dcEdge            =&gt; grid % dcEdge % array
-      dvEdge            =&gt; grid % dvEdge % array
-      areaCell          =&gt; grid % areaCell % array
-      areaTriangle      =&gt; grid % areaTriangle % array
-      h_s               =&gt; grid % h_s % array
-! mrp 110516 cleanup fvertex fedge not used in this subroutine
-      fVertex           =&gt; grid % fVertex % array
-      fEdge             =&gt; grid % fEdge % array
-      zMidZLevel        =&gt; grid % zMidZLevel % array
-      zTopZLevel        =&gt; grid % zTopZLevel % array
-      maxLevelCell      =&gt; grid % maxLevelCell % array
       maxLevelEdgeTop      =&gt; grid % maxLevelEdgeTop % array
-      maxLevelVertexBot    =&gt; grid % maxLevelVertexBot % array
 
       tend_u      =&gt; tend % u % array
                   
       nCells      = grid % nCells
       nEdges      = grid % nEdges
-      nEdgesSolve = grid % nEdgesSolve
-      nVertices   = grid % nVertices
       nVertLevels = grid % nVertLevels
 
-      u_src =&gt; grid % u_src % array
+      do iEdge=1,nEdges
 
-           do iEdge=1,grid % nEdges
+        ! hSum is initialized outside the loop because on land boundaries 
+        ! maxLevelEdgeTop=0, but I want to initialize hSum with a 
+        ! nonzero value to avoid a NaN.
+        uhSum = h_edge(1,iEdge) * tend_u(1,iEdge)
+        hSum  = h_edge(1,iEdge)
 
-              ! I am using hZLevel here.  This assumes that SSH is zero everywhere already,
-              ! which should be the case if the barotropic mode is filtered.
-              ! The more general case is to use sshEdge or h_edge.
-              uhSum = (grid % hZLevel % array(1)) * tend_u(1,iEdge)
-              hSum  =  grid % hZLevel % array(1)
+        do k=2,maxLevelEdgeTop(iEdge)
+          uhSum = uhSum + h_edge(k,iEdge) * tend_u(k,iEdge)
+          hSum  =  hSum + h_edge(k,iEdge)
+        enddo
 
-              do k=2,grid % maxLevelEdgeTop % array(iEdge)
-                 uhSum = uhSum + grid % hZLevel % array(k) * tend_u(k,iEdge)
-                 hSum  =  hSum + grid % hZLevel % array(k)
-              enddo
+        vertSum = uhSum/hSum
+        do k=1,maxLevelEdgeTop(iEdge)
+          tend_u(k,iEdge) = tend_u(k,iEdge) - vertSum
+        enddo
+      enddo ! iEdge
 
-              vertSum = uhSum/hSum
-
-              do k=1,grid % maxLevelEdgeTop % array(iEdge)
-                 tend_u(k,iEdge) = tend_u(k,iEdge) - vertSum
-              enddo
-
-           enddo ! iEdge
-
       call mpas_timer_stop(&quot;filter_btr_mode_tend_u&quot;)
 
    end subroutine filter_btr_mode_tend_u!}}}
@@ -1379,155 +998,51 @@
       type (state_type), intent(inout) :: s
       type (mesh_type), intent(in) :: grid
 
-! mrp 110512 I just split compute_tend into compute_tend_u and compute_tend_h.
-!  Some of these variables can be removed, but at a later time.
-      integer :: iEdge, iCell, iVertex, k, cell1, cell2, &amp;
-        vertex1, vertex2, eoe, i, j
+      integer :: iEdge, k
 
       integer :: nCells, nEdges, nVertices, nVertLevels, nEdgesSolve
-      real (kind=RKIND) :: vertSum, uhSum, hSum, sshEdge
-      real (kind=RKIND), dimension(:), pointer :: &amp;
-        h_s, fVertex, fEdge, dvEdge, dcEdge, areaCell, areaTriangle, &amp;
-        zMidZLevel, zTopZLevel, meshScalingDel2, meshScalingDel4
+      real (kind=RKIND) :: vertSum, uhSum, hSum
       real (kind=RKIND), dimension(:,:), pointer :: &amp;
-        weightsOnEdge, kiteAreasOnVertex, h_edge, h, u, v, pressure, &amp;
-        tend_u, circulation, vorticity, ke, ke_edge, pv_edge, &amp;
-        MontPot, wTop, divergence, vertViscTopOfEdge
+        h_edge, h, u
       type (dm_info) :: dminfo
 
-      integer, dimension(:), pointer :: nEdgesOnCell, nEdgesOnEdge, &amp;
-        maxLevelCell, maxLevelEdgeTop, maxLevelVertexBot
-      integer, dimension(:,:), pointer :: &amp;
-        cellsOnEdge, cellsOnVertex, verticesOnEdge, edgesOnCell, &amp;
-        edgesOnEdge, edgesOnVertex
-      real (kind=RKIND) :: u_diffusion
-      real (kind=RKIND), dimension(:), allocatable:: fluxVertTop,w_dudzTopEdge
+      integer, dimension(:), pointer :: maxLevelEdgeTop
 
-      real (kind=RKIND), allocatable, dimension(:,:) :: delsq_divergence
-      real (kind=RKIND), allocatable, dimension(:,:) :: delsq_u
-      real (kind=RKIND), allocatable, dimension(:,:) :: delsq_circulation, delsq_vorticity
-
-
-      real (kind=RKIND), dimension(:,:), pointer :: u_src
-      real (kind=RKIND), parameter :: rho_ref = 1000.0
-
       call mpas_timer_start(&quot;filter_btr_mode_u&quot;)
 
       h           =&gt; s % h % array
       u           =&gt; s % u % array
-      v           =&gt; s % v % array
-      wTop        =&gt; s % wTop % array
       h_edge      =&gt; s % h_edge % array
-      circulation =&gt; s % circulation % array
-      vorticity   =&gt; s % vorticity % array
-      divergence  =&gt; s % divergence % array
-      ke          =&gt; s % ke % array
-      ke_edge     =&gt; s % ke_edge % array
-      pv_edge     =&gt; s % pv_edge % array
-      MontPot     =&gt; s % MontPot % array
-      pressure    =&gt; s % pressure % array
 
-      weightsOnEdge     =&gt; grid % weightsOnEdge % array
-      kiteAreasOnVertex =&gt; grid % kiteAreasOnVertex % array
-      cellsOnEdge       =&gt; grid % cellsOnEdge % array
-      cellsOnVertex     =&gt; grid % cellsOnVertex % array
-      verticesOnEdge    =&gt; grid % verticesOnEdge % array
-      nEdgesOnCell      =&gt; grid % nEdgesOnCell % array
-      edgesOnCell       =&gt; grid % edgesOnCell % array
-      nEdgesOnEdge      =&gt; grid % nEdgesOnEdge % array
-      edgesOnEdge       =&gt; grid % edgesOnEdge % array
-      edgesOnVertex     =&gt; grid % edgesOnVertex % array
-      dcEdge            =&gt; grid % dcEdge % array
-      dvEdge            =&gt; grid % dvEdge % array
-      areaCell          =&gt; grid % areaCell % array
-      areaTriangle      =&gt; grid % areaTriangle % array
-      h_s               =&gt; grid % h_s % array
-! mrp 110516 cleanup fvertex fedge not used in this subroutine
-      fVertex           =&gt; grid % fVertex % array
-      fEdge             =&gt; grid % fEdge % array
-      zMidZLevel        =&gt; grid % zMidZLevel % array
-      zTopZLevel        =&gt; grid % zTopZLevel % array
-      maxLevelCell      =&gt; grid % maxLevelCell % array
       maxLevelEdgeTop      =&gt; grid % maxLevelEdgeTop % array
-      maxLevelVertexBot    =&gt; grid % maxLevelVertexBot % array
 
       nCells      = grid % nCells
       nEdges      = grid % nEdges
-      nEdgesSolve = grid % nEdgesSolve
-      nVertices   = grid % nVertices
       nVertLevels = grid % nVertLevels
 
-      u_src =&gt; grid % u_src % array
+      do iEdge=1,nEdges
 
-           do iEdge=1,grid % nEdges
+        ! hSum is initialized outside the loop because on land boundaries 
+        ! maxLevelEdgeTop=0, but I want to initialize hSum with a 
+        ! nonzero value to avoid a NaN.
+        uhSum = h_edge(1,iEdge) * u(1,iEdge)
+        hSum  = h_edge(1,iEdge)
 
-              ! I am using hZLevel here.  This assumes that SSH is zero everywhere already,
-              ! which should be the case if the barotropic mode is filtered.
-              ! The more general case is to use sshedge or h_edge.
-              uhSum = (grid % hZLevel % array(1)) * u(1,iEdge)
-              hSum  =  grid % hZLevel % array(1)
+        do k=2,maxLevelEdgeTop(iEdge)
+          uhSum = uhSum + h_edge(k,iEdge) * u(k,iEdge)
+          hSum  =  hSum + h_edge(k,iEdge)
+        enddo
 
-              do k=2,grid % maxLevelEdgeTop % array(iEdge)
-                 uhSum = uhSum + grid % hZLevel % array(k) * u(k,iEdge)
-                 hSum  =  hSum + grid % hZLevel % array(k)
-              enddo
+        vertSum = uhSum/hSum
+        do k=1,maxLevelEdgeTop(iEdge)
+          u(k,iEdge) = u(k,iEdge) - vertSum
+        enddo
+      enddo ! iEdge
 
-              vertSum = uhSum/hSum
-              do k=1,grid % maxLevelEdgeTop % array(iEdge)
-                 u(k,iEdge) = u(k,iEdge) - vertSum
-              enddo
-
-           enddo ! iEdge
-
       call mpas_timer_stop(&quot;filter_btr_mode_u&quot;)
 
    end subroutine filter_btr_mode_u!}}}
 
-   subroutine enforce_boundaryEdge(tend, grid)!{{{
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-   ! Enforce any boundary conditions on the normal velocity at each edge
-   !
-   ! Input: grid - grid metadata
-   !
-   ! Output: tend_u set to zero at boundaryEdge == 1 locations
-   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-
-      implicit none
-
-      type (tend_type), intent(inout) :: tend
-      type (mesh_type), intent(in) :: grid
-
-      integer, dimension(:,:), pointer :: boundaryEdge
-      real (kind=RKIND), dimension(:,:), pointer :: tend_u
-      integer :: nCells, nEdges, nVertices, nVertLevels
-      integer :: iEdge, k
-
-      call mpas_timer_start(&quot;enforce_boundaryEdge&quot;)
-
-      nCells      = grid % nCells
-      nEdges      = grid % nEdges
-      nVertices   = grid % nVertices
-      nVertLevels = grid % nVertLevels
-
-      boundaryEdge         =&gt; grid % boundaryEdge % array
-      tend_u      =&gt; tend % u % array
-
-      if(maxval(boundaryEdge).le.0) return
-
-      do iEdge = 1,nEdges
-        do k = 1,nVertLevels
-
-          if(boundaryEdge(k,iEdge).eq.1) then
-             tend_u(k,iEdge) = 0.0
-          endif
-
-        enddo
-       enddo
-      call mpas_timer_stop(&quot;enforce_boundaryEdge&quot;)
-
-   end subroutine enforce_boundaryEdge!}}}
-
 end module ocn_time_integration_split
 
 ! vim: foldmethod=marker

Modified: branches/atmos_physics/src/core_ocean/mpas_ocn_tracer_hadv.F
===================================================================
--- branches/atmos_physics/src/core_ocean/mpas_ocn_tracer_hadv.F        2012-02-27 22:31:30 UTC (rev 1537)
+++ branches/atmos_physics/src/core_ocean/mpas_ocn_tracer_hadv.F        2012-02-27 22:33:23 UTC (rev 1538)
@@ -16,6 +16,7 @@
 
    use mpas_grid_types
    use mpas_configure
+   use mpas_timer
 
    use ocn_tracer_hadv2
    use ocn_tracer_hadv3
@@ -46,7 +47,9 @@
    !
    !--------------------------------------------------------------------
 
+   type (timer_node), pointer :: hadv2Timer, hadv3Timer, hadv4Timer
 
+
 !***********************************************************************
 
 contains
@@ -122,9 +125,15 @@
       !
       !-----------------------------------------------------------------
 
+      call mpas_timer_start(&quot;hadv2&quot;, .false., hadv2Timer);
       call ocn_tracer_hadv2_tend(grid, u, h_edge, tracers, tend, err1)
+      call mpas_timer_stop(&quot;hadv2&quot;, hadv2Timer);
+      call mpas_timer_start(&quot;hadv3&quot;, .false., hadv3Timer);
       call ocn_tracer_hadv3_tend(grid, u, h_edge, tracers, tend, err2)
+      call mpas_timer_stop(&quot;hadv3&quot;, hadv3Timer);
+      call mpas_timer_start(&quot;hadv4&quot;, .false., hadv4Timer);
       call ocn_tracer_hadv4_tend(grid, u, h_edge, tracers, tend, err3)
+      call mpas_timer_stop(&quot;hadv4&quot;, hadv4Timer);
 
       err = ior(err1, ior(err2, err3))
 

Modified: branches/atmos_physics/src/core_ocean/mpas_ocn_tracer_hadv2.F
===================================================================
--- branches/atmos_physics/src/core_ocean/mpas_ocn_tracer_hadv2.F        2012-02-27 22:31:30 UTC (rev 1537)
+++ branches/atmos_physics/src/core_ocean/mpas_ocn_tracer_hadv2.F        2012-02-27 22:33:23 UTC (rev 1538)
@@ -16,7 +16,6 @@
 
    use mpas_grid_types
    use mpas_configure
-   use mpas_timer
 
    implicit none
    private
@@ -111,7 +110,7 @@
       integer, dimension(:), pointer :: maxLevelEdgeTop
       integer, dimension(:,:), pointer :: cellsOnEdge
 
-      real (kind=RKIND) :: flux, tracer_edge
+      real (kind=RKIND) :: flux, tracer_edge, invAreaCell1, invAreaCell2, r_tmp
 
       real (kind=RKIND), dimension(:), pointer :: dvEdge, areaCell
 
@@ -127,8 +126,6 @@
 
       if(.not.hadv2On) return
 
-      call mpas_timer_start(&quot;compute_scalar_tend-horiz adv 2&quot;)
-
       nEdges = grid % nEdges
       maxLevelEdgeTop =&gt; grid % maxLevelEdgeTop % array
       cellsOnEdge =&gt; grid % cellsOnEdge % array
@@ -139,17 +136,19 @@
       do iEdge=1,nEdges
          cell1 = cellsOnEdge(1,iEdge)
          cell2 = cellsOnEdge(2,iEdge)
+
+         invAreaCell1 = 1.0 / areaCell(cell1)
+         invAreaCell2 = 1.0 / areaCell(cell2)
          do k=1,maxLevelEdgeTop(iEdge)
+            r_tmp = u(k,iEdge) * dvEdge(iEdge) * h_edge(k,iEdge)
             do iTracer=1,num_tracers
                tracer_edge = 0.5 * (tracers(iTracer,k,cell1) + tracers(iTracer,k,cell2))
-               flux = u(k,iEdge) * dvEdge(iEdge) * h_edge(k,iEdge) * tracer_edge
-               tend(iTracer,k,cell1) = tend(iTracer,k,cell1) - flux/areaCell(cell1)
-               tend(iTracer,k,cell2) = tend(iTracer,k,cell2) + flux/areaCell(cell2)
+               flux = r_tmp * tracer_edge
+               tend(iTracer,k,cell1) = tend(iTracer,k,cell1) - flux * invAreaCell1
+               tend(iTracer,k,cell2) = tend(iTracer,k,cell2) + flux * invAreaCell2
             end do
          end do
       end do
-
-      call mpas_timer_stop(&quot;compute_scalar_tend-horiz adv 2&quot;)
    !--------------------------------------------------------------------
 
    end subroutine ocn_tracer_hadv2_tend!}}}

Modified: branches/atmos_physics/src/core_ocean/mpas_ocn_tracer_hadv3.F
===================================================================
--- branches/atmos_physics/src/core_ocean/mpas_ocn_tracer_hadv3.F        2012-02-27 22:31:30 UTC (rev 1537)
+++ branches/atmos_physics/src/core_ocean/mpas_ocn_tracer_hadv3.F        2012-02-27 22:33:23 UTC (rev 1538)
@@ -16,7 +16,6 @@
 
    use mpas_grid_types
    use mpas_configure
-   use mpas_timer
 
    implicit none
    private
@@ -107,13 +106,15 @@
       !
       !-----------------------------------------------------------------
 
-      integer :: iEdge, nEdges, cell1, cell2, iTracer, num_tracers, i, k
+      integer :: iEdge, nEdges, cell1, cell2, iTracer, num_tracers, i, k, &amp;
+                 boundaryMask, velMask
 
       integer, dimension(:), pointer :: maxLevelEdgeTop, nEdgesOnCell
       integer, dimension(:,:), pointer :: cellsOnEdge, cellsOnCell, &amp;
-                                          boundaryCell
+                                          cellMask, edgeMask
 
-      real (kind=RKIND) :: flux, tracer_edge, d2fdx2_cell1, d2fdx2_cell2
+      real (kind=RKIND) :: flux, tracer_edge, d2fdx2_cell1, d2fdx2_cell2, &amp;
+                           invAreaCell1, invAreaCell2
 
       real (kind=RKIND), dimension(:), pointer :: dvEdge, dcEdge, areaCell
       real (kind=RKIND), dimension(:,:,:), pointer :: deriv_two
@@ -134,7 +135,7 @@
       num_tracers = size(tracers, dim=1)
       maxLevelEdgeTop =&gt; grid % maxLevelEdgeTop % array
       nEdgesOnCell =&gt; grid % nEdgesOnCell % array
-      boundaryCell =&gt; grid % boundaryCell % array
+      cellMask =&gt; grid % cellMask % array
       cellsOnEdge =&gt; grid % cellsOnEdge % array
       cellsOnCell =&gt; grid % cellsOnCell % array
       dvEdge =&gt; grid % dvEdge % array
@@ -142,60 +143,51 @@
       areaCell =&gt; grid % areaCell % array
       deriv_two =&gt; grid % deriv_two % array
 
-      call mpas_timer_start(&quot;compute_scalar_tend-horiz adv 3&quot;)
       do iEdge=1,nEdges
          cell1 = cellsOnEdge(1,iEdge)
          cell2 = cellsOnEdge(2,iEdge)
 
+         invAreaCell1 = 1.0 / areaCell(cell1)
+         invAreaCell2 = 1.0 / areaCell(cell2)
+
          do k=1,maxLevelEdgeTop(iEdge)
 
             d2fdx2_cell1 = 0.0
             d2fdx2_cell2 = 0.0
 
+            boundaryMask = abs(transfer(cellMask(k,cell1)  == 1 .and. cellMask(k,cell2) == 1,boundaryMask))
+
             do iTracer=1,num_tracers
 
                !-- if not a boundary cell
-               if(boundaryCell(k,cell1).eq.0.and.boundaryCell(k,cell2).eq.0) then
+               d2fdx2_cell1 = deriv_two(1,1,iEdge) * tracers(iTracer,k,cell1) * boundaryMask
+               d2fdx2_cell2 = deriv_two(1,2,iEdge) * tracers(iTracer,k,cell2) * boundaryMask
 
-                  d2fdx2_cell1 = deriv_two(1,1,iEdge) * tracers(iTracer,k,cell1)
-                  d2fdx2_cell2 = deriv_two(1,2,iEdge) * tracers(iTracer,k,cell2)
+               !-- all edges of cell 1
+               do i=1,nEdgesOnCell(cell1) * boundaryMask
+                  d2fdx2_cell1 = d2fdx2_cell1 + &amp;
+                  deriv_two(i+1,1,iEdge) * tracers(iTracer,k,cellsOnCell(i,cell1))
+               end do
 
-                  !-- all edges of cell 1
-                  do i=1,nEdgesOnCell(cell1)
-                     d2fdx2_cell1 = d2fdx2_cell1 + &amp;
-                     deriv_two(i+1,1,iEdge) * tracers(iTracer,k,cellsOnCell(i,cell1))
-                  end do
+               !-- all edges of cell 2
+               do i=1,nEdgesOnCell(cell2) * boundaryMask
+                  d2fdx2_cell2 = d2fdx2_cell2 + &amp;
+                  deriv_two(i+1,2,iEdge) * tracers(iTracer,k,cellsOnCell(i,cell2))
+               end do
 
-                  !-- all edges of cell 2
-                  do i=1,nEdgesOnCell(cell2)
-                     d2fdx2_cell2 = d2fdx2_cell2 + &amp;
-                     deriv_two(i+1,2,iEdge) * tracers(iTracer,k,cellsOnCell(i,cell2))
-                  end do
 
-               endif
+               velMask = 2*(abs(transfer(u(k,iEdge) &lt;= 0, velMask))) - 1
+               flux = dvEdge(iEdge) *  u(k,iEdge) * h_edge(k,iEdge) * (          &amp;
+                    0.5*(tracers(iTracer,k,cell1) + tracers(iTracer,k,cell2))      &amp;
+                    -(dcEdge(iEdge) **2) * (d2fdx2_cell1 + d2fdx2_cell2) / 12.          &amp;
+                    +velMask*(dcEdge(iEdge) **2) * coef_3rd_order*(d2fdx2_cell1 - d2fdx2_cell2) / 12. )
 
-               !-- if u &gt; 0:
-               if (u(k,iEdge) &gt; 0) then
-                  flux = dvEdge(iEdge) * u(k,iEdge) * h_edge(k,iEdge) * (          &amp;
-                       0.5*(tracers(iTracer,k,cell1) + tracers(iTracer,k,cell2))      &amp;
-                       -(dcEdge(iEdge) **2) * (d2fdx2_cell1 + d2fdx2_cell2) / 12.          &amp;
-                       -(dcEdge(iEdge) **2) * coef_3rd_order*(d2fdx2_cell1 - d2fdx2_cell2) / 12. )
-               !-- else u &lt;= 0:
-               else
-                  flux = dvEdge(iEdge) *  u(k,iEdge) * h_edge(k,iEdge) * (          &amp;
-                       0.5*(tracers(iTracer,k,cell1) + tracers(iTracer,k,cell2))      &amp;
-                       -(dcEdge(iEdge) **2) * (d2fdx2_cell1 + d2fdx2_cell2) / 12.          &amp;
-                       +(dcEdge(iEdge) **2) * coef_3rd_order*(d2fdx2_cell1 - d2fdx2_cell2) / 12. )
-               end if
-
                !-- update tendency
-               tend(iTracer,k,cell1) = tend(iTracer,k,cell1) - flux/areaCell(cell1)
-               tend(iTracer,k,cell2) = tend(iTracer,k,cell2) + flux/areaCell(cell2)
+               tend(iTracer,k,cell1) = tend(iTracer,k,cell1) - flux*invAreaCell1
+               tend(iTracer,k,cell2) = tend(iTracer,k,cell2) + flux*invAreaCell2
             enddo
          end do
       end do
-      call mpas_timer_stop(&quot;compute_scalar_tend-horiz adv 3&quot;)
-
    !--------------------------------------------------------------------
 
    end subroutine ocn_tracer_hadv3_tend!}}}

Modified: branches/atmos_physics/src/core_ocean/mpas_ocn_tracer_hadv4.F
===================================================================
--- branches/atmos_physics/src/core_ocean/mpas_ocn_tracer_hadv4.F        2012-02-27 22:31:30 UTC (rev 1537)
+++ branches/atmos_physics/src/core_ocean/mpas_ocn_tracer_hadv4.F        2012-02-27 22:33:23 UTC (rev 1538)
@@ -16,7 +16,6 @@
 
    use mpas_grid_types
    use mpas_configure
-   use mpas_timer
 
    implicit none
    private
@@ -106,12 +105,13 @@
       !
       !-----------------------------------------------------------------
 
-      integer :: iEdge, nEdges, cell1, cell2, iTracer, num_tracers, i, k
+      integer :: iEdge, nEdges, cell1, cell2, iTracer, num_tracers, i, k, &amp;
+                 boundaryMask
 
-      integer, dimension(:), pointer :: maxLevelEdgeTop
-      integer, dimension(:,:), pointer :: cellsOnEdge, cellsOnCell, boundaryCell
+      integer, dimension(:), pointer :: maxLevelEdgeTop, nEdgesOnCell
+      integer, dimension(:,:), pointer :: cellsOnEdge, cellsOnCell, cellMask
 
-      real (kind=RKIND) :: flux, tracer_edge, d2fdx2_cell1, d2fdx2_cell2
+      real (kind=RKIND) :: flux, tracer_edge, d2fdx2_cell1, d2fdx2_cell2, invAreaCell1, invAreaCell2
 
       real (kind=RKIND), dimension(:), pointer :: dvEdge, dcEdge, areaCell
       real (kind=RKIND), dimension(:,:,:), pointer :: deriv_two
@@ -131,7 +131,8 @@
       nEdges = grid % nEdges
       num_tracers = size(tracers, dim=1)
       maxLevelEdgeTop =&gt; grid % maxLevelEdgeTop % array
-      boundaryCell =&gt; grid % boundaryCell % array
+      nEdgesOnCell =&gt; grid % nEdgesOnCell % array
+      cellMask =&gt; grid % cellMask % array
       cellsOnEdge =&gt; grid % cellsOnEdge % array
       cellsOnCell =&gt; grid % cellsOnCell % array
       dvEdge =&gt; grid % dvEdge % array
@@ -139,51 +140,46 @@
       areaCell =&gt; grid % areaCell % array
       deriv_two =&gt; grid % deriv_two % array
 
-      call mpas_timer_start(&quot;compute_scalar_tend-horiz adv 4&quot;)
-
       do iEdge=1,nEdges
          cell1 = cellsOnEdge(1,iEdge)
          cell2 = cellsOnEdge(2,iEdge)
 
+         invAreaCell1 = 1.0 / areaCell(cell1)
+         invAreaCell2 = 1.0 / areaCell(cell2)
+
          do k=1,maxLevelEdgeTop(iEdge)
 
             d2fdx2_cell1 = 0.0
             d2fdx2_cell2 = 0.0
 
+            boundaryMask = abs(transfer(cellMask(k,cell1) == 1 .and. cellMask(k, cell2) == 1, boundaryMask))
+
             do iTracer=1,num_tracers
+               d2fdx2_cell1 = deriv_two(1,1,iEdge) * tracers(iTracer,k,cell1) * boundaryMask
+               d2fdx2_cell2 = deriv_two(1,2,iEdge) * tracers(iTracer,k,cell2) * boundaryMask
 
-               !-- if not a boundary cell
-               if(boundaryCell(k,cell1).eq.0.and.boundaryCell(k,cell2).eq.0) then
+               !-- all edges of cell 1
+               do i=1,nEdgesOnCell(cell1) * boundaryMask
+                  d2fdx2_cell1 = d2fdx2_cell1 + &amp;
+                  deriv_two(i+1,1,iEdge) * tracers(iTracer,k,cellsOnCell(i,cell1))
+               end do
 
-                  d2fdx2_cell1 = deriv_two(1,1,iEdge) * tracers(iTracer,k,cell1)
-                  d2fdx2_cell2 = deriv_two(1,2,iEdge) * tracers(iTracer,k,cell2)
+               !-- all edges of cell 2
+               do i=1,nEdgesOnCell(cell2) * boundaryMask
+                   d2fdx2_cell2 = d2fdx2_cell2 + &amp;
+                   deriv_two(i+1,2,iEdge) * tracers(iTracer,k,cellsOnCell(i,cell2))
+               end do
 
-                  !-- all edges of cell 1
-                  do i=1, grid % nEdgesOnCell % array (cell1)
-                     d2fdx2_cell1 = d2fdx2_cell1 + &amp;
-                     deriv_two(i+1,1,iEdge) * tracers(iTracer,k,cellsOnCell(i,cell1))
-                  end do
-
-                  !-- all edges of cell 2
-                  do i=1, grid % nEdgesOnCell % array (cell2)
-                      d2fdx2_cell2 = d2fdx2_cell2 + &amp;
-                      deriv_two(i+1,2,iEdge) * tracers(iTracer,k,cellsOnCell(i,cell2))
-                  end do
-
-               endif
-
                flux = dvEdge(iEdge) *  u(k,iEdge) * h_edge(k,iEdge) * (          &amp;
                     0.5*(tracers(iTracer,k,cell1) + tracers(iTracer,k,cell2))      &amp;
                        -(dcEdge(iEdge) **2) * (d2fdx2_cell1 + d2fdx2_cell2) / 12. )
 
                !-- update tendency
-               tend(iTracer,k,cell1) = tend(iTracer,k,cell1) - flux/areaCell(cell1)
-               tend(iTracer,k,cell2) = tend(iTracer,k,cell2) + flux/areaCell(cell2)
+               tend(iTracer,k,cell1) = tend(iTracer,k,cell1) - flux * invAreaCell1
+               tend(iTracer,k,cell2) = tend(iTracer,k,cell2) + flux * invAreaCell2
             enddo
          end do
       end do
-      call mpas_timer_stop(&quot;compute_scalar_tend-horiz adv 4&quot;)
-
    !--------------------------------------------------------------------
 
    end subroutine ocn_tracer_hadv4_tend!}}}

Modified: branches/atmos_physics/src/core_ocean/mpas_ocn_tracer_hmix.F
===================================================================
--- branches/atmos_physics/src/core_ocean/mpas_ocn_tracer_hmix.F        2012-02-27 22:31:30 UTC (rev 1537)
+++ branches/atmos_physics/src/core_ocean/mpas_ocn_tracer_hmix.F        2012-02-27 22:33:23 UTC (rev 1538)
@@ -18,6 +18,7 @@
 
    use mpas_grid_types
    use mpas_configure
+   use mpas_timer
    use ocn_tracer_hmix_del2
    use ocn_tracer_hmix_del4
 
@@ -46,7 +47,9 @@
    !
    !--------------------------------------------------------------------
 
+   type (timer_node), pointer :: del2Timer, del4Timer
 
+
 !***********************************************************************
 
 contains
@@ -119,8 +122,12 @@
       !
       !-----------------------------------------------------------------
 
+      call mpas_timer_start(&quot;del2&quot;, .false., del2Timer)
       call ocn_tracer_hmix_del2_tend(grid, h_edge, tracers, tend, err1)
+      call mpas_timer_stop(&quot;del2&quot;, del2Timer)
+      call mpas_timer_start(&quot;del4&quot;, .false., del4Timer)
       call ocn_tracer_hmix_del4_tend(grid, h_edge, tracers, tend, err2)
+      call mpas_timer_stop(&quot;del4&quot;, del4Timer)
 
       err = ior(err1, err2)
 

Modified: branches/atmos_physics/src/core_ocean/mpas_ocn_tracer_hmix_del2.F
===================================================================
--- branches/atmos_physics/src/core_ocean/mpas_ocn_tracer_hmix_del2.F        2012-02-27 22:31:30 UTC (rev 1537)
+++ branches/atmos_physics/src/core_ocean/mpas_ocn_tracer_hmix_del2.F        2012-02-27 22:33:23 UTC (rev 1538)
@@ -18,7 +18,6 @@
 
    use mpas_grid_types
    use mpas_configure
-   use mpas_timer
 
    implicit none
    private
@@ -114,10 +113,10 @@
       integer, dimension(:,:), allocatable :: boundaryMask
 
       integer, dimension(:), pointer :: maxLevelEdgeTop
-      integer, dimension(:,:), pointer :: cellsOnEdge, boundaryEdge
+      integer, dimension(:,:), pointer :: cellsOnEdge, edgeMask
 
       real (kind=RKIND) :: invAreaCell1, invAreaCell2
-      real (kind=RKIND) :: tracer_turb_flux, flux
+      real (kind=RKIND) :: tracer_turb_flux, flux, r_tmp
 
       real (kind=RKIND), dimension(:), pointer :: areaCell, dvEdge, dcEdge
       real (kind=RKIND), dimension(:), pointer :: meshScalingDel2
@@ -134,15 +133,13 @@
 
       if (.not.del2On) return
 
-      call mpas_timer_start(&quot;compute_scalar_tend-horiz diff 2&quot;)
-
       nEdges = grid % nEdges
       nVertLevels = grid % nVertLevels
       num_tracers = size(tracers, dim=1)
 
       maxLevelEdgeTop =&gt; grid % maxLevelEdgeTop % array
       cellsOnEdge =&gt; grid % cellsOnEdge % array
-      boundaryEdge =&gt; grid % boundaryEdge % array
+      edgeMask =&gt; grid % edgeMask % array
       areaCell =&gt; grid % areaCell % array
       dvEdge =&gt; grid % dvEdge % array
       dcEdge =&gt; grid % dcEdge % array
@@ -151,36 +148,28 @@
       !
       ! compute a boundary mask to enforce insulating boundary conditions in the horizontal
       !
-      allocate(boundaryMask(nVertLevels, nEdges+1))
-      boundaryMask = 1.0
-      where(boundaryEdge.eq.1) boundaryMask=0.0
-
       do iEdge=1,nEdges
          cell1 = cellsOnEdge(1,iEdge)
          cell2 = cellsOnEdge(2,iEdge)
          invAreaCell1 = 1.0/areaCell(cell1)
          invAreaCell2 = 1.0/areaCell(cell2)
 
+         r_tmp = meshScalingDel2(iEdge) * eddyDiff2 * dvEdge(iEdge) / dcEdge(iEdge)
+
          do k=1,maxLevelEdgeTop(iEdge)
            do iTracer=1,num_tracers
               ! \kappa_2 </font>
<font color="red">abla \phi on edge
-              tracer_turb_flux = meshScalingDel2(iEdge) * eddyDiff2 &amp;
-                 *(  tracers(iTracer,k,cell2) &amp;
-                   - tracers(iTracer,k,cell1))/dcEdge(iEdge)
+              tracer_turb_flux = tracers(iTracer,k,cell2) - tracers(iTracer,k,cell1)
 
               ! div(h \kappa_2 </font>
<font color="gray">abla \phi) at cell center
-              flux = dvEdge (iEdge) * h_edge(k,iEdge) &amp;
-                 * tracer_turb_flux * boundaryMask(k, iEdge)
+              flux = h_edge(k,iEdge) * tracer_turb_flux * edgeMask(k, iEdge) * r_tmp
+
               tend(iTracer,k,cell1) = tend(iTracer,k,cell1) + flux * invAreaCell1
               tend(iTracer,k,cell2) = tend(iTracer,k,cell2) - flux * invAreaCell2
            end do
          end do
 
       end do
-
-      deallocate(boundaryMask)
-      call mpas_timer_stop(&quot;compute_scalar_tend-horiz diff 2&quot;)
-
    !--------------------------------------------------------------------
 
    end subroutine ocn_tracer_hmix_del2_tend!}}}

Modified: branches/atmos_physics/src/core_ocean/mpas_ocn_tracer_hmix_del4.F
===================================================================
--- branches/atmos_physics/src/core_ocean/mpas_ocn_tracer_hmix_del4.F        2012-02-27 22:31:30 UTC (rev 1537)
+++ branches/atmos_physics/src/core_ocean/mpas_ocn_tracer_hmix_del4.F        2012-02-27 22:33:23 UTC (rev 1538)
@@ -18,7 +18,6 @@
 
    use mpas_grid_types
    use mpas_configure
-   use mpas_timer
 
    implicit none
    private
@@ -45,7 +44,7 @@
    !
    !--------------------------------------------------------------------
 
-   logical :: Del4On
+   logical :: del4On
 
    real (kind=RKIND) :: eddyDiff4
 
@@ -111,12 +110,10 @@
       integer :: iEdge, nEdges, num_tracers, nVertLevels, nCells
       integer :: iTracer, k, iCell, cell1, cell2
 
-      integer, dimension(:,:), allocatable :: boundaryMask
-
       integer, dimension(:), pointer :: maxLevelEdgeTop, maxLevelCell
-      integer, dimension(:,:), pointer :: boundaryEdge, cellsOnEdge
+      integer, dimension(:,:), pointer :: edgeMask, cellsOnEdge
 
-      real (kind=RKIND) :: invAreaCell1, invAreaCell2, r, tracer_turb_flux, flux
+      real (kind=RKIND) :: invAreaCell1, invAreaCell2, tracer_turb_flux, flux, invdcEdge, r_tmp1, r_tmp2
 
       real (kind=RKIND), dimension(:,:,:), allocatable :: delsq_tracer
 
@@ -133,10 +130,8 @@
 
       err = 0
 
-      if (.not.Del4On) return
+      if (.not.del4On) return
 
-      call mpas_timer_start(&quot;compute_scalar_tend-horiz diff 4&quot;)
-
       nEdges = grid % nEdges
       nCells = grid % nCells
       num_tracers = size(tracers, dim=1)
@@ -144,7 +139,6 @@
 
       maxLevelEdgeTop =&gt; grid % maxLevelEdgeTop % array
       maxLevelCell =&gt; grid % maxLevelCell % array
-      boundaryEdge =&gt; grid % boundaryEdge % array
       cellsOnEdge =&gt; grid % cellsOnEdge % array
 
       dcEdge =&gt; grid % dcEdge % array
@@ -152,68 +146,61 @@
       areaCell =&gt; grid % areaCell % array
       meshScalingDel4 =&gt; grid % meshScalingDel4 % array
 
-      allocate(boundaryMask(nVertLevels, nEdges+1))
-      boundaryMask = 1.0
-      where(boundaryEdge.eq.1) boundaryMask=0.0
+      edgeMask =&gt; grid % edgeMask % array
 
       allocate(delsq_tracer(num_tracers,nVertLevels, nCells+1))
 
-      delsq_tracer(:,:,:) = 0.
+      delsq_tracer(:,:,:) = 0.0
 
       ! first del2: div(h </font>
<font color="red">abla \phi) at cell center
       do iEdge=1,nEdges
          cell1 = cellsOnEdge(1,iEdge)
          cell2 = cellsOnEdge(2,iEdge)
 
+         invdcEdge = 1.0 / dcEdge(iEdge)
+
+         invAreaCell1 = 1.0 / areaCell(cell1)
+         invAreaCell2 = 1.0 / areaCell(cell2)
+
          do k=1,maxLevelEdgeTop(iEdge)
-           do iTracer=1,num_tracers
-              delsq_tracer(iTracer,k,cell1) = delsq_tracer(iTracer,k,cell1) &amp;
-                 + dvEdge(iEdge)*h_edge(k,iEdge) &amp;
-                   *(tracers(iTracer,k,cell2) - tracers(iTracer,k,cell1)) &amp;
-                   /dcEdge(iEdge) * boundaryMask(k,iEdge)
-              delsq_tracer(iTracer,k,cell2) = delsq_tracer(iTracer,k,cell2) &amp;
-                 - dvEdge(iEdge)*h_edge(k,iEdge) &amp;
-                 *(tracers(iTracer,k,cell2) - tracers(iTracer,k,cell1)) &amp;
-                 /dcEdge(iEdge) * boundaryMask(k,iEdge)
+           do iTracer=1,num_tracers * edgeMask(k, iEdge)
+
+              r_tmp1 = dvEdge(iEdge) * h_edge(k,iEdge) * invdcEdge
+
+              r_tmp2 = r_tmp1 * tracers(iTracer,k,cell2)
+              r_tmp1 = r_tmp1 * tracers(iTracer,k,cell1)
+
+              delsq_tracer(iTracer,k,cell1) = delsq_tracer(iTracer,k,cell1) + (r_tmp2 - r_tmp1) * invAreaCell1
+              delsq_tracer(iTracer,k,cell2) = delsq_tracer(iTracer,k,cell2) - (r_tmp2 - r_tmp1) * invAreaCell2
            end do
          end do
       end do
 
-      do iCell = 1,nCells
-         r = 1.0 / areaCell(iCell)
-         do k=1,maxLevelCell(iCell)
-            do iTracer=1,num_tracers
-               delsq_tracer(iTracer,k,iCell) = delsq_tracer(iTracer,k,iCell) * r
-            end do
-         end do
-      end do
-
       ! second del2: div(h </font>
<font color="gray">abla [delsq_tracer]) at cell center
       do iEdge=1,grid % nEdges
          cell1 = grid % cellsOnEdge % array(1,iEdge)
          cell2 = grid % cellsOnEdge % array(2,iEdge)
+
          invAreaCell1 = 1.0 / areaCell(cell1)
          invAreaCell2 = 1.0 / areaCell(cell2)
 
+         invdcEdge = 1.0 / dcEdge(iEdge)
+
          do k=1,maxLevelEdgeTop(iEdge)
-            do iTracer=1,num_tracers
+            do iTracer=1,num_tracers * edgeMask(k,iEdge)
                tracer_turb_flux = meshScalingDel4(iEdge) * eddyDiff4 &amp;
-                  *(  delsq_tracer(iTracer,k,cell2)  &amp;
-                    - delsq_tracer(iTracer,k,cell1))/dcEdge(iEdge)
+                  * (delsq_tracer(iTracer,k,cell2) - delsq_tracer(iTracer,k,cell1)) &amp;
+                  * invdcEdge
+
                flux = dvEdge (iEdge) * tracer_turb_flux
 
-               tend(iTracer,k,cell1) = tend(iTracer,k,cell1) &amp; 
-                  - flux * invAreaCell1 * boundaryMask(k,iEdge)
-               tend(iTracer,k,cell2) = tend(iTracer,k,cell2) &amp;
-                  + flux * invAreaCell2 * boundaryMask(k,iEdge)
-
+               tend(iTracer,k,cell1) = tend(iTracer,k,cell1) - flux * invAreaCell1
+               tend(iTracer,k,cell2) = tend(iTracer,k,cell2) + flux * invAreaCell2
             enddo
          enddo
       end do
 
       deallocate(delsq_tracer)
-      deallocate(boundaryMask)
-      call mpas_timer_stop(&quot;compute_scalar_tend-horiz diff 4&quot;)
    !--------------------------------------------------------------------
 
    end subroutine ocn_tracer_hmix_del4_tend!}}}
@@ -245,10 +232,10 @@
       integer, intent(out) :: err !&lt; Output: error flag
 
       err = 0
-      Del4on = .false.
+      del4on = .false.
 
       if ( config_h_tracer_eddy_diff4 &gt; 0.0 ) then
-          Del4On = .true.
+          del4On = .true.
           eddyDiff4 = config_h_tracer_eddy_diff4
       endif
 

Modified: branches/atmos_physics/src/core_ocean/mpas_ocn_tracer_vadv.F
===================================================================
--- branches/atmos_physics/src/core_ocean/mpas_ocn_tracer_vadv.F        2012-02-27 22:31:30 UTC (rev 1537)
+++ branches/atmos_physics/src/core_ocean/mpas_ocn_tracer_vadv.F        2012-02-27 22:33:23 UTC (rev 1538)
@@ -70,7 +70,7 @@
 !
 !-----------------------------------------------------------------------
 
-   subroutine ocn_tracer_vadv_tend(grid, wTop, tracers, tend, err)!{{{
+   subroutine ocn_tracer_vadv_tend(grid, h, wTop, tracers, tend, err)!{{{
 
       !-----------------------------------------------------------------
       !
@@ -79,6 +79,7 @@
       !-----------------------------------------------------------------
 
       real (kind=RKIND), dimension(:,:), intent(in) :: &amp;
+         h, &amp;    !&lt; Input: layer thickness
          wTop    !&lt; Input: vertical tracer in top layer
 
       real (kind=RKIND), dimension(:,:,:), intent(in) :: &amp;
@@ -122,10 +123,15 @@
 
       err = 0
 
+      ! mrp 120202 efficiency note:
+      ! The following if statement is not needed, since wTop is set to 
+      ! zero for isopycnal coordinates.  This if statment saves flops
+      ! for isopycnal coordinates.  However, if the loops are pushed
+      ! out, we could get rid of this if statement.
       if(.not.vadvOn) return
 
-      call ocn_tracer_vadv_stencil_tend(grid, wTop, tracers, tend, err1)
-      call ocn_tracer_vadv_spline_tend(grid, wTop, tracers, tend, err2)
+      call ocn_tracer_vadv_stencil_tend(grid, h, wTop, tracers, tend, err1)
+      call ocn_tracer_vadv_spline_tend(grid, h, wTop, tracers, tend, err2)
 
       err = ior(err1, err2)
 
@@ -166,7 +172,7 @@
       err = 0
       vadvOn = .false.
 
-      if (config_vert_grid_type.eq.'zlevel') then
+      if (config_vert_grid_type.ne.'isopycnal') then
           vadvOn = .true.
           call ocn_tracer_vadv_stencil_init(err1)
           call ocn_tracer_vadv_spline_init(err2)

Modified: branches/atmos_physics/src/core_ocean/mpas_ocn_tracer_vadv_spline.F
===================================================================
--- branches/atmos_physics/src/core_ocean/mpas_ocn_tracer_vadv_spline.F        2012-02-27 22:31:30 UTC (rev 1537)
+++ branches/atmos_physics/src/core_ocean/mpas_ocn_tracer_vadv_spline.F        2012-02-27 22:33:23 UTC (rev 1538)
@@ -16,6 +16,7 @@
 
    use mpas_grid_types
    use mpas_configure
+   use mpas_timer
 
    use ocn_tracer_vadv_spline2
    use ocn_tracer_vadv_spline3
@@ -45,6 +46,7 @@
    !
    !--------------------------------------------------------------------
 
+   type (timer_node), pointer :: spline2_timer, spline3_timer
    logical :: splineOn
 
 
@@ -70,7 +72,7 @@
 !
 !-----------------------------------------------------------------------
 
-   subroutine ocn_tracer_vadv_spline_tend(grid, wTop, tracers, tend, err)!{{{
+   subroutine ocn_tracer_vadv_spline_tend(grid, h, wTop, tracers, tend, err)!{{{
 
       !-----------------------------------------------------------------
       !
@@ -79,6 +81,7 @@
       !-----------------------------------------------------------------
 
       real (kind=RKIND), dimension(:,:), intent(in) :: &amp;
+         h, &amp;    !&lt; Input: layer thickness
          wTop    !&lt; Input: vertical tracer in top layer
 
       real (kind=RKIND), dimension(:,:,:), intent(in) :: &amp;
@@ -124,9 +127,14 @@
 
       if(.not.splineOn) return
 
-      call ocn_tracer_vadv_spline2_tend(grid, wTop, tracers, tend, err1)
-      call ocn_tracer_vadv_spline3_tend(grid, wTop, tracers, tend, err2)
+      call mpas_timer_start(&quot;spline 2&quot;, .false., spline2_timer)
+      call ocn_tracer_vadv_spline2_tend(grid, h, wTop, tracers, tend, err1)
+      call mpas_timer_stop(&quot;spline 2&quot;, spline2_timer)
 
+      call mpas_timer_start(&quot;spline 3&quot;, .false., spline3_timer)
+      call ocn_tracer_vadv_spline3_tend(grid, h, wTop, tracers, tend, err2)
+      call mpas_timer_stop(&quot;spline 3&quot;, spline3_timer)
+
       err = ior(err1, err2)
 
    !--------------------------------------------------------------------

Modified: branches/atmos_physics/src/core_ocean/mpas_ocn_tracer_vadv_spline2.F
===================================================================
--- branches/atmos_physics/src/core_ocean/mpas_ocn_tracer_vadv_spline2.F        2012-02-27 22:31:30 UTC (rev 1537)
+++ branches/atmos_physics/src/core_ocean/mpas_ocn_tracer_vadv_spline2.F        2012-02-27 22:33:23 UTC (rev 1538)
@@ -16,7 +16,6 @@
 
    use mpas_grid_types
    use mpas_configure
-   use mpas_timer
 
    implicit none
    private
@@ -64,7 +63,7 @@
 !
 !-----------------------------------------------------------------------
 
-   subroutine ocn_tracer_vadv_spline2_tend(grid, wTop, tracers, tend, err)!{{{
+   subroutine ocn_tracer_vadv_spline2_tend(grid, h, wTop, tracers, tend, err)!{{{
 
       !-----------------------------------------------------------------
       !
@@ -73,6 +72,7 @@
       !-----------------------------------------------------------------
 
       real (kind=RKIND), dimension(:,:), intent(in) :: &amp;
+         h, &amp;    !&lt; Input: layer thickness
          wTop    !&lt; Input: vertical tracer in top layer
 
       real (kind=RKIND), dimension(:,:,:), intent(in) :: &amp;
@@ -108,8 +108,6 @@
 
       integer, dimension(:), pointer :: maxLevelCell
 
-      real (kind=RKIND), dimension(:), pointer :: hRatioZLevelK, hRatioZLevelKm1
-
       real (kind=RKIND), dimension(:,:,:), allocatable :: tracerTop
 
       !-----------------------------------------------------------------
@@ -125,28 +123,24 @@
       if(.not.spline2On) return
       ! Compute tracerTop using linear interpolation.
 
-      call mpas_timer_start(&quot;compute_scalar_tend-vert adv spline 2&quot;)
-
       nCells = grid % nCells
       nCellsSolve = grid % nCellsSolve
       nVertLevels = grid % nVertLevels
       num_tracers = size(tracers, 1)
       maxLevelCell =&gt; grid % maxLevelCell % array
 
-      hRatioZLevelK =&gt; grid % hRatioZLevelK % array
-      hRatioZLevelKm1 =&gt; grid % hRatioZLevelKm1 % array
-
       allocate(tracerTop(num_tracers,nVertLevels+1,nCells))
 
       do iCell=1,nCellsSolve 
          tracerTop(:,1,iCell) = tracers(:,1,iCell) 
          do k=2,maxLevelCell(iCell)
             do iTracer=1,num_tracers
-               ! Note hRatio on the k side is multiplied by tracer at k-1
-               ! and hRatio on the Km1 (k-1) side is mult. by tracer at k.
+               ! Note h on the k side is multiplied by tracer at k-1
+               ! and h on the Km1 (k-1) side is mult. by tracer at k.
                tracerTop(iTracer,k,iCell) = &amp;
-                    hRatioZLevelK(k)  *tracers(iTracer,k-1,iCell) &amp;
-                  + hRatioZLevelKm1(k)*tracers(iTracer,k  ,iCell)
+                  (  h(k  ,iCell)*tracers(iTracer,k-1,iCell) &amp;
+                   + h(k-1,iCell)*tracers(iTracer,k  ,iCell) ) &amp;
+                  / (h(k-1,iCell) + h(k,iCell))   
             end do
          end do
          tracerTop(:,maxLevelCell(iCell)+1,iCell) = tracers(:,maxLevelCell(iCell),iCell)
@@ -163,8 +157,6 @@
       end do
 
       deallocate(tracerTop)
-
-      call mpas_timer_stop(&quot;compute_scalar_tend-vert adv spline 2&quot;)
    !--------------------------------------------------------------------
 
    end subroutine ocn_tracer_vadv_spline2_tend!}}}

Modified: branches/atmos_physics/src/core_ocean/mpas_ocn_tracer_vadv_spline3.F
===================================================================
--- branches/atmos_physics/src/core_ocean/mpas_ocn_tracer_vadv_spline3.F        2012-02-27 22:31:30 UTC (rev 1537)
+++ branches/atmos_physics/src/core_ocean/mpas_ocn_tracer_vadv_spline3.F        2012-02-27 22:33:23 UTC (rev 1538)
@@ -16,7 +16,6 @@
 
    use mpas_grid_types
    use mpas_configure
-   use mpas_timer
    use mpas_spline_interpolation
 
    implicit none
@@ -65,7 +64,7 @@
 !
 !-----------------------------------------------------------------------
 
-   subroutine ocn_tracer_vadv_spline3_tend(grid, wTop, tracers, tend, err)!{{{
+   subroutine ocn_tracer_vadv_spline3_tend(grid, h, wTop, tracers, tend, err)!{{{
 
       !-----------------------------------------------------------------
       !
@@ -74,6 +73,7 @@
       !-----------------------------------------------------------------
 
       real (kind=RKIND), dimension(:,:), intent(in) :: &amp;
+         h, &amp;    !&lt; Input: layer thickness
          wTop    !&lt; Input: vertical tracer in top layer
 
       real (kind=RKIND), dimension(:,:,:), intent(in) :: &amp;
@@ -109,11 +109,8 @@
 
       integer, dimension(:), pointer :: maxLevelCell
 
-      real (kind=RKIND), dimension(:), pointer :: hRatioZLevelK, &amp;
-            hRatioZLevelKm1, zTopZLevel, zMidZLevel
-
       real (kind=RKIND), dimension(:), allocatable :: tracer2ndDer,  &amp;
-            tracersIn, tracersOut, posZMidZLevel, posZTopZLevel
+            tracersIn, tracersOut, depthTop, depthMid
       real (kind=RKIND), dimension(:,:,:), allocatable :: tracerTop
 
       !-----------------------------------------------------------------
@@ -129,34 +126,30 @@
       if(.not.spline3On) return
       ! Compute tracerTop using linear interpolation.
 
-      call mpas_timer_start(&quot;compute_scalar_tend-vert adv spline 3&quot;)
-
       nCells = grid % nCells
       nCellsSolve = grid % nCellsSolve
       nVertLevels = grid % nVertLevels
       num_tracers = size(tracers, 1)
       maxLevelCell =&gt; grid % maxLevelCell % array
 
-      hRatioZLevelK =&gt; grid % hRatioZLevelK % array
-      hRatioZLevelKm1 =&gt; grid % hRatioZLevelKm1 % array
-      zMidZLevel =&gt; grid % zMidZLevel % array
-      zTopZLevel =&gt; grid % zTopZLevel % array
-
       allocate(tracerTop(num_tracers,nVertLevels+1,nCells))
 
       ! Compute tracerTop using cubic spline interpolation.
 
       allocate(tracer2ndDer(nVertLevels))
       allocate(tracersIn(nVertLevels),tracersOut(nVertLevels), &amp;
-            posZMidZLevel(nVertLevels), posZTopZLevel(nVertLevels-1))
+            depthMid(nVertLevels), depthTop(nVertLevels+1))
 
-      ! For the ocean, zlevel coordinates are negative and decreasing, 
-      ! but spline functions assume increasing, so flip to positive.
+      do iCell=1,nCellsSolve 
 
-      posZMidZLevel = -zMidZLevel(1:nVertLevels)
-      posZTopZLevel = -zTopZLevel(2:nVertLevels)
+         ! Here depth considers SSH to be depth=0.  We don't need to 
+         ! have true z-coordinate depths because it is just for interpolation.
+         depthTop(1) = 0.0
+         do k=1,maxLevelCell(iCell)
+            depthMid(k  ) = depthTop(k) + 0.5*h(k,iCell)
+            depthTop(k+1) = depthTop(k) +     h(k,iCell)
+         enddo
 
-      do iCell=1,nCellsSolve 
          ! mrp 110201 efficiency note: push tracer loop down
          ! into spline subroutines to improve efficiency
          do iTracer=1,num_tracers
@@ -165,12 +158,12 @@
             ! subroutine call.  
             tracersIn(1:maxLevelCell(iCell))=tracers(iTracer,1:maxLevelCell(iCell),iCell)
 
-            call mpas_cubic_spline_coefficients(posZMidZLevel, &amp;
+            call mpas_cubic_spline_coefficients(depthMid, &amp;
                tracersIn, maxLevelCell(iCell), tracer2ndDer)
 
             call mpas_interpolate_cubic_spline( &amp;
-               posZMidZLevel, tracersIn, tracer2ndDer, maxLevelCell(iCell), &amp;
-               posZTopZLevel, tracersOut, maxLevelCell(iCell)-1 )
+               depthMid, tracersIn, tracer2ndDer, maxLevelCell(iCell), &amp;
+               depthTop(2:maxLevelCell(iCell)), tracersOut, maxLevelCell(iCell)-1 )
 
             tracerTop(itracer,1,iCell) = tracers(iTracer,1,iCell)
             tracerTop(iTracer,2:maxLevelCell(iCell),iCell) = tracersOut(1:maxLevelCell(iCell)-1)
@@ -189,10 +182,8 @@
       end do
 
       deallocate(tracer2ndDer)
-      deallocate(tracersIn,tracersOut, posZMidZLevel, posZTopZLevel)
+      deallocate(tracersIn,tracersOut, depthMid, depthTop)
       deallocate(tracerTop)
-
-      call mpas_timer_stop(&quot;compute_scalar_tend-vert adv spline 3&quot;)
    !--------------------------------------------------------------------
 
    end subroutine ocn_tracer_vadv_spline3_tend!}}}

Modified: branches/atmos_physics/src/core_ocean/mpas_ocn_tracer_vadv_stencil.F
===================================================================
--- branches/atmos_physics/src/core_ocean/mpas_ocn_tracer_vadv_stencil.F        2012-02-27 22:31:30 UTC (rev 1537)
+++ branches/atmos_physics/src/core_ocean/mpas_ocn_tracer_vadv_stencil.F        2012-02-27 22:33:23 UTC (rev 1538)
@@ -16,6 +16,7 @@
 
    use mpas_grid_types
    use mpas_configure
+   use mpas_timer
 
    use ocn_tracer_vadv_stencil2
    use ocn_tracer_vadv_stencil3
@@ -46,6 +47,8 @@
    !
    !--------------------------------------------------------------------
 
+   type (timer_node), pointer :: stencil2_timer, stencil3_timer, stencil4_timer
+
    logical :: stencilOn
 
 
@@ -71,7 +74,7 @@
 !
 !-----------------------------------------------------------------------
 
-   subroutine ocn_tracer_vadv_stencil_tend(grid, wTop, tracers, tend, err)!{{{
+   subroutine ocn_tracer_vadv_stencil_tend(grid, h, wTop, tracers, tend, err)!{{{
 
       !-----------------------------------------------------------------
       !
@@ -80,6 +83,7 @@
       !-----------------------------------------------------------------
 
       real (kind=RKIND), dimension(:,:), intent(in) :: &amp;
+         h, &amp;    !&lt; Input: layer thickness
          wTop    !&lt; Input: vertical tracer in top layer
 
       real (kind=RKIND), dimension(:,:,:), intent(in) :: &amp;
@@ -125,9 +129,15 @@
 
       if(.not. stencilOn) return
 
+      call mpas_timer_start(&quot;stencil 2&quot;, .false., stencil2_timer)
       call ocn_tracer_vadv_stencil2_tend(grid, wTop, tracers, tend, err1)
-      call ocn_tracer_vadv_stencil3_tend(grid, wTop, tracers, tend, err2)
-      call ocn_tracer_vadv_stencil4_tend(grid, wTop, tracers, tend, err3)
+      call mpas_timer_stop(&quot;stencil 2&quot;, stencil2_timer)
+      call mpas_timer_start(&quot;stencil 3&quot;, .false., stencil3_timer)
+      call ocn_tracer_vadv_stencil3_tend(grid, h, wTop, tracers, tend, err2)
+      call mpas_timer_stop(&quot;stencil 3&quot;, stencil3_timer)
+      call mpas_timer_start(&quot;stencil 4&quot;, .false., stencil4_timer)
+      call ocn_tracer_vadv_stencil4_tend(grid, h, wTop, tracers, tend, err3)
+      call mpas_timer_stop(&quot;stencil 4&quot;, stencil4_timer)
 
       err = ior(err1, ior(err2, err3))
 

Modified: branches/atmos_physics/src/core_ocean/mpas_ocn_tracer_vadv_stencil2.F
===================================================================
--- branches/atmos_physics/src/core_ocean/mpas_ocn_tracer_vadv_stencil2.F        2012-02-27 22:31:30 UTC (rev 1537)
+++ branches/atmos_physics/src/core_ocean/mpas_ocn_tracer_vadv_stencil2.F        2012-02-27 22:33:23 UTC (rev 1538)
@@ -16,7 +16,6 @@
 
    use mpas_grid_types
    use mpas_configure
-   use mpas_timer
 
    implicit none
    private
@@ -122,11 +121,8 @@
 
       err = 0
 
-      if(.not. stencil2On) return
+      if(.not.stencil2On) return
 
-
-      call mpas_timer_start(&quot;compute_scalar_tend-vert adv stencil 2&quot;)
-
       nCells = grid % nCells
       nCellsSolve = grid % nCellsSolve
       num_tracers = size(tracers, 1)
@@ -160,8 +156,6 @@
       end do
 
       deallocate(tracerTop)
-      call mpas_timer_stop(&quot;compute_scalar_tend-vert adv stencil 2&quot;)
-
    !--------------------------------------------------------------------
 
    end subroutine ocn_tracer_vadv_stencil2_tend!}}}

Modified: branches/atmos_physics/src/core_ocean/mpas_ocn_tracer_vadv_stencil3.F
===================================================================
--- branches/atmos_physics/src/core_ocean/mpas_ocn_tracer_vadv_stencil3.F        2012-02-27 22:31:30 UTC (rev 1537)
+++ branches/atmos_physics/src/core_ocean/mpas_ocn_tracer_vadv_stencil3.F        2012-02-27 22:33:23 UTC (rev 1538)
@@ -16,7 +16,6 @@
 
    use mpas_grid_types
    use mpas_configure
-   use mpas_timer
 
    implicit none
    private
@@ -64,7 +63,7 @@
 !
 !-----------------------------------------------------------------------
 
-   subroutine ocn_tracer_vadv_stencil3_tend(grid, wTop, tracers, tend, err)!{{{
+   subroutine ocn_tracer_vadv_stencil3_tend(grid, h, wTop, tracers, tend, err)!{{{
 
       !-----------------------------------------------------------------
       !
@@ -73,6 +72,7 @@
       !-----------------------------------------------------------------
 
       real (kind=RKIND), dimension(:,:), intent(in) :: &amp;
+         h, &amp;    !&lt; Input: layer thickness
          wTop    !&lt; Input: vertical tracer in top layer
 
       real (kind=RKIND), dimension(:,:,:), intent(in) :: &amp;
@@ -110,7 +110,6 @@
       integer, dimension(:), pointer :: maxLevelCell
 
       real (kind=RKIND) :: cSignWTop, flux3Coef
-      real (kind=RKIND), dimension(:), pointer :: hRatioZLevelK, hRatioZLevelKm1
       real (kind=RKIND), dimension(:,:,:), allocatable :: tracerTop
 
 
@@ -124,18 +123,14 @@
 
       err = 0
 
-      if(.not. stencil3On) return
+      if(.not.stencil3On) return
 
       nCells = grid % nCells
       nCellsSolve = grid % nCellsSolve
       num_tracers = size(tracers, 1)
       nVertLevels = grid % nVertLevels
       maxLevelCell =&gt; grid % maxLevelCell % array
-      hRatioZLevelK =&gt; grid % hRatioZLevelK % array
-      hRatioZLevelKm1 =&gt; grid % hRatioZLevelKm1 % array
 
-      call mpas_timer_start(&quot;compute_scalar_tend-vert adv stencil 3&quot;)
-
       allocate(tracerTop(num_tracers,nVertLevels+1,nCells))
 
       ! Compute tracerTop using 3rd order stencil.  This is the same
@@ -148,9 +143,10 @@
          tracerTop(:,1,iCell) = tracers(:,1,iCell)
          k=2
          do iTracer=1,num_tracers
-           tracerTop(iTracer,k,iCell) = &amp;
-                hRatioZLevelK(k)  *tracers(iTracer,k-1,iCell) &amp;
-              + hRatioZLevelKm1(k)*tracers(iTracer,k  ,iCell)
+            tracerTop(iTracer,k,iCell) = &amp;
+               (  h(k,iCell)*tracers(iTracer,k-1,iCell) &amp;
+                + h(k-1,iCell)*tracers(iTracer,k  ,iCell) ) &amp;
+               / (h(k-1,iCell) + h(k,iCell))   
          end do
          do k=3,maxLevelCell(iCell)-1
             cSignWTop = sign(flux3Coef,wTop(k,iCell))
@@ -165,9 +161,10 @@
          end do
          k=maxLevelCell(iCell)
             do iTracer=1,num_tracers
-              tracerTop(iTracer,k,iCell) = &amp;
-                   hRatioZLevelK(k)  *tracers(iTracer,k-1,iCell) &amp;
-                 + hRatioZLevelKm1(k)*tracers(iTracer,k  ,iCell)
+            tracerTop(iTracer,k,iCell) = &amp;
+               (  h(k,iCell)*tracers(iTracer,k-1,iCell) &amp;
+                + h(k-1,iCell)*tracers(iTracer,k  ,iCell) ) &amp;
+               / (h(k-1,iCell) + h(k,iCell))   
             end do
         tracerTop(:,maxLevelCell(iCell)+1,iCell) = tracers(:,maxLevelCell(iCell),iCell)
       end do
@@ -183,8 +180,6 @@
       end do
 
       deallocate(tracerTop)
-      call mpas_timer_stop(&quot;compute_scalar_tend-vert adv stencil 3&quot;)
-
    !--------------------------------------------------------------------
 
    end subroutine ocn_tracer_vadv_stencil3_tend!}}}

Modified: branches/atmos_physics/src/core_ocean/mpas_ocn_tracer_vadv_stencil4.F
===================================================================
--- branches/atmos_physics/src/core_ocean/mpas_ocn_tracer_vadv_stencil4.F        2012-02-27 22:31:30 UTC (rev 1537)
+++ branches/atmos_physics/src/core_ocean/mpas_ocn_tracer_vadv_stencil4.F        2012-02-27 22:33:23 UTC (rev 1538)
@@ -16,7 +16,6 @@
 
    use mpas_grid_types
    use mpas_configure
-   use mpas_timer
 
    implicit none
    private
@@ -64,7 +63,7 @@
 !
 !-----------------------------------------------------------------------
 
-   subroutine ocn_tracer_vadv_stencil4_tend(grid, wTop, tracers, tend, err)!{{{
+   subroutine ocn_tracer_vadv_stencil4_tend(grid, h, wTop, tracers, tend, err)!{{{
 
       !-----------------------------------------------------------------
       !
@@ -73,6 +72,7 @@
       !-----------------------------------------------------------------
 
       real (kind=RKIND), dimension(:,:), intent(in) :: &amp;
+         h, &amp;    !&lt; Input: layer thickness
          wTop    !&lt; Input: vertical tracer in top layer
 
       real (kind=RKIND), dimension(:,:,:), intent(in) :: &amp;
@@ -110,7 +110,6 @@
       integer, dimension(:), pointer :: maxLevelCell
 
       real (kind=RKIND) :: cSingWTop, flux3Coef
-      real (kind=RKIND), dimension(:), pointer :: hRatioZLevelK, hRatioZLevelKm1
       real (kind=RKIND), dimension(:,:,:), allocatable :: tracerTop
 
 
@@ -124,17 +123,13 @@
 
       err = 0
 
-      if(.not. Stencil4On) return
+      if(.not.Stencil4On) return
 
-      call mpas_timer_start(&quot;compute_scalar_tend-vert adv stencil 4&quot;)
-
       nCells = grid % nCells
       nCellsSolve = grid % nCellsSolve
       num_tracers = size(tracers, 1)
       nVertLevels = grid % nVertLevels
       maxLevelCell =&gt; grid % maxLevelCell % array
-      hRatioZLevelK =&gt; grid % hRatioZLevelK % array
-      hRatioZLevelKm1 =&gt; grid % hRatioZLevelKm1 % array
 
       allocate(tracerTop(num_tracers,nVertLevels+1,nCells))
 
@@ -144,9 +139,10 @@
          tracerTop(:,1,iCell) = tracers(:,1,iCell)
          k=2
             do iTracer=1,num_tracers
-              tracerTop(iTracer,k,iCell) = &amp;
-                   hRatioZLevelK(k)  *tracers(iTracer,k-1,iCell) &amp;
-                 + hRatioZLevelKm1(k)*tracers(iTracer,k  ,iCell)
+               tracerTop(iTracer,k,iCell) = &amp;
+                  (  h(k  ,iCell)*tracers(iTracer,k-1,iCell) &amp;
+                   + h(k-1,iCell)*tracers(iTracer,k  ,iCell) ) &amp;
+                  / (h(k-1,iCell) + h(k,iCell))   
             end do
          do k=3,maxLevelCell(iCell)-1
             do iTracer=1,num_tracers
@@ -160,9 +156,10 @@
          end do
          k=maxLevelCell(iCell)
             do iTracer=1,num_tracers
-              tracerTop(iTracer,k,iCell) = &amp;
-                   hRatioZLevelK(k)  *tracers(iTracer,k-1,iCell) &amp;
-                 + hRatioZLevelKm1(k)*tracers(iTracer,k  ,iCell)
+               tracerTop(iTracer,k,iCell) = &amp;
+                  (  h(k  ,iCell)*tracers(iTracer,k-1,iCell) &amp;
+                   + h(k-1,iCell)*tracers(iTracer,k  ,iCell) ) &amp;
+                  / (h(k-1,iCell) + h(k,iCell))   
             end do
         tracerTop(:,maxLevelCell(iCell)+1,iCell) = tracers(:,maxLevelCell(iCell),iCell)
       end do
@@ -178,8 +175,6 @@
       end do
 
       deallocate(tracerTop)
-      call mpas_timer_stop(&quot;compute_scalar_tend-vert adv stencil 4&quot;)
-
    !--------------------------------------------------------------------
 
    end subroutine ocn_tracer_vadv_stencil4_tend!}}}

Modified: branches/atmos_physics/src/core_ocean/mpas_ocn_vel_coriolis.F
===================================================================
--- branches/atmos_physics/src/core_ocean/mpas_ocn_vel_coriolis.F        2012-02-27 22:31:30 UTC (rev 1537)
+++ branches/atmos_physics/src/core_ocean/mpas_ocn_vel_coriolis.F        2012-02-27 22:33:23 UTC (rev 1538)
@@ -106,13 +106,13 @@
       !-----------------------------------------------------------------
 
       integer, dimension(:), pointer :: maxLevelEdgeTop, nEdgesOnEdge
-      integer, dimension(:,:), pointer :: cellsOnEdge, edgesOnEdge
+      integer, dimension(:,:), pointer :: cellsOnEdge, edgesOnEdge, edgeMask
       real (kind=RKIND), dimension(:,:), pointer :: weightsOnEdge
       real (kind=RKIND), dimension(:), pointer :: dcEdge
 
       integer :: j, k
       integer :: cell1, cell2, nEdgesSolve, iEdge, eoe
-      real (kind=RKIND) :: workpv, q
+      real (kind=RKIND) :: workpv, q, invLength
 
       err = 0
 
@@ -123,12 +123,16 @@
       weightsOnEdge =&gt; grid % weightsOnEdge % array
       dcEdge =&gt; grid % dcEdge % array
 
+      edgeMask =&gt; grid % edgeMask % array
+
       nEdgesSolve = grid % nEdgesSolve
 
       do iEdge=1,grid % nEdgesSolve
          cell1 = cellsOnEdge(1,iEdge)
          cell2 = cellsOnEdge(2,iEdge)
 
+         invLength = 1.0 / dcEdge(iEdgE)
+
          do k=1,maxLevelEdgeTop(iEdge)
 
             q = 0.0
@@ -138,9 +142,7 @@
                q = q + weightsOnEdge(j,iEdge) * u(k,eoe) * workpv * h_edge(k,eoe) 
             end do
 
-           tend(k,iEdge) = tend(k,iEdge)     &amp;
-                  + q     &amp;
-                  - (   ke(k,cell2) - ke(k,cell1) ) / dcEdge(iEdge)
+           tend(k,iEdge) = tend(k,iEdge) + edgeMask(k, iEdge) * (q - (   ke(k,cell2) - ke(k,cell1) ) * invLength )
 
          end do
       end do

Modified: branches/atmos_physics/src/core_ocean/mpas_ocn_vel_forcing_bottomdrag.F
===================================================================
--- branches/atmos_physics/src/core_ocean/mpas_ocn_vel_forcing_bottomdrag.F        2012-02-27 22:31:30 UTC (rev 1537)
+++ branches/atmos_physics/src/core_ocean/mpas_ocn_vel_forcing_bottomdrag.F        2012-02-27 22:33:23 UTC (rev 1538)
@@ -109,6 +109,7 @@
 
       integer :: iEdge, nEdgesSolve, k
       integer, dimension(:), pointer :: maxLevelEdgeTop
+      integer, dimension(:,:), pointer :: edgeMask
 
       !-----------------------------------------------------------------
       !
@@ -124,27 +125,18 @@
 
       nEdgesSolve = grid % nEdgesSolve
       maxLevelEdgeTop =&gt; grid % maxLevelEdgeTop % array
+      edgeMask =&gt; grid % edgeMask % array
 
       do iEdge=1,grid % nEdgesSolve
 
-        k = maxLevelEdgeTop(iEdge)
+        k = max(maxLevelEdgeTop(iEdge), 1)
 
-        ! efficiency note: it would be nice to avoid this
-        ! if within a do.  This could be done with
-        ! k =  max(maxLevelEdgeTop(iEdge),1)
-        ! and then tend_u(1,iEdge) is just not used for land cells.
+        ! bottom drag is the same as POP:
+        ! -c |u| u  where c is unitless and 1.0e-3.
+        ! see POP Reference guide, section 3.4.4.
 
-        if (k&gt;0) then
-           ! bottom drag is the same as POP:
-           ! -c |u| u  where c is unitless and 1.0e-3.
-           ! see POP Reference guide, section 3.4.4.
+        tend(k,iEdge) = tend(k,iEdge)-edgeMask(k,iEdge)*(bottomDragCoef*u(k,iEdge)*sqrt(2.0*ke_edge(k,iEdge))/h_edge(k,iEdge))
 
-           tend(k,iEdge) = tend(k,iEdge)  &amp;
-               -bottomDragCoef*u(k,iEdge) &amp;
-               *sqrt(2.0*ke_edge(k,iEdge))/h_edge(k,iEdge)
-
-        endif
-
       enddo
 
 

Modified: branches/atmos_physics/src/core_ocean/mpas_ocn_vel_forcing_windstress.F
===================================================================
--- branches/atmos_physics/src/core_ocean/mpas_ocn_vel_forcing_windstress.F        2012-02-27 22:31:30 UTC (rev 1537)
+++ branches/atmos_physics/src/core_ocean/mpas_ocn_vel_forcing_windstress.F        2012-02-27 22:33:23 UTC (rev 1538)
@@ -106,8 +106,8 @@
 
       integer :: iEdge, nEdgesSolve, k
       integer, dimension(:), pointer :: maxLevelEdgeTop
+      integer, dimension(:,:), pointer :: edgeMask
 
-
       !-----------------------------------------------------------------
       !
       ! call relevant routines for computing tendencies
@@ -122,21 +122,19 @@
 
       nEdgesSolve = grid % nEdgesSolve
       maxLevelEdgeTop =&gt; grid % maxLevelEdgeTop % array
+      edgeMask =&gt; grid % edgeMask % array
 
       do iEdge=1,nEdgesSolve
 
-        k = maxLevelEdgeTop(iEdge)
-
         ! efficiency note: it would be nice to avoid this
         ! if within a do.  This could be done with
         ! k =  max(maxLevelEdgeTop(iEdge),1)
         ! and then tend_u(1,iEdge) is just not used for land cells.
 
-        if (k&gt;0) then
+        do k = 1,min(maxLevelEdgeTop(iEdge),1)
            ! forcing in top layer only
-           tend(1,iEdge) =  tend(1,iEdge) &amp;
-              + u_src(1,iEdge)/rho_ref/h_edge(1,iEdge)
-        endif
+           tend(k,iEdge) =  tend(k,iEdge) + edgeMask(k, iEdge) * (u_src(k,iEdge)/rho_ref/h_edge(k,iEdge))
+        enddo
 
       enddo
 
@@ -171,13 +169,11 @@
 
       integer, intent(out) :: err !&lt; Output: error flag
 
-
       windStressOn = .true.
       rho_ref = 1000.0
 
       err = 0
 
-
    !--------------------------------------------------------------------
 
    end subroutine ocn_vel_forcing_windstress_init!}}}

Modified: branches/atmos_physics/src/core_ocean/mpas_ocn_vel_hmix.F
===================================================================
--- branches/atmos_physics/src/core_ocean/mpas_ocn_vel_hmix.F        2012-02-27 22:31:30 UTC (rev 1537)
+++ branches/atmos_physics/src/core_ocean/mpas_ocn_vel_hmix.F        2012-02-27 22:33:23 UTC (rev 1538)
@@ -18,6 +18,7 @@
 
    use mpas_grid_types
    use mpas_configure
+   use mpas_timer
    use ocn_vel_hmix_del2
    use ocn_vel_hmix_del4
 
@@ -46,7 +47,9 @@
    !
    !--------------------------------------------------------------------
 
+   type (timer_node), pointer :: del2Timer, del4Timer
 
+
 !***********************************************************************
 
 contains
@@ -119,8 +122,12 @@
       !
       !-----------------------------------------------------------------
 
+      call mpas_timer_start(&quot;del2&quot;, .false., del2Timer)
       call ocn_vel_hmix_del2_tend(grid, divergence, vorticity, tend, err1)
+      call mpas_timer_stop(&quot;del2&quot;, del2Timer)
+      call mpas_timer_start(&quot;del4&quot;, .false., del4Timer)
       call ocn_vel_hmix_del4_tend(grid, divergence, vorticity, tend, err2)
+      call mpas_timer_stop(&quot;del4&quot;, del4Timer)
 
       err = ior(err1, err2)
 

Modified: branches/atmos_physics/src/core_ocean/mpas_ocn_vel_hmix_del2.F
===================================================================
--- branches/atmos_physics/src/core_ocean/mpas_ocn_vel_hmix_del2.F        2012-02-27 22:31:30 UTC (rev 1537)
+++ branches/atmos_physics/src/core_ocean/mpas_ocn_vel_hmix_del2.F        2012-02-27 22:33:23 UTC (rev 1538)
@@ -16,7 +16,6 @@
 
    use mpas_grid_types
    use mpas_configure
-   use mpas_timer
 
    implicit none
    private
@@ -43,8 +42,7 @@
    !
    !--------------------------------------------------------------------
 
-   logical :: &amp;
-      hmixDel2On         !&lt; local flag to determine whether del2 chosen
+   logical ::  hmixDel2On  !&lt; integer flag to determine whether del2 chosen
 
    real (kind=RKIND) :: &amp;
       eddyVisc2,        &amp;!&lt; base eddy diffusivity for Laplacian
@@ -116,9 +114,9 @@
       integer :: iEdge, nEdgesSolve, cell1, cell2, vertex1, vertex2
       integer :: k
       integer, dimension(:), pointer :: maxLevelEdgeTop
-      integer, dimension(:,:), pointer :: cellsOnEdge, verticesOnEdge
+      integer, dimension(:,:), pointer :: cellsOnEdge, verticesOnEdge, edgeMask
 
-      real (kind=RKIND) :: u_diffusion
+      real (kind=RKIND) :: u_diffusion, invLength1, invLength2
       real (kind=RKIND), dimension(:), pointer :: meshScalingDel2, &amp;
               dcEdge, dvEdge
 
@@ -132,13 +130,12 @@
 
       if(.not.hmixDel2On) return
 
-      call mpas_timer_start(&quot;compute_tend_u-horiz mix-del2&quot;)
-      
       nEdgesSolve = grid % nEdgesSolve
       maxLevelEdgeTop =&gt; grid % maxLevelEdgeTop % array
       cellsOnEdge =&gt; grid % cellsOnEdge % array
       verticesOnEdge =&gt; grid % verticesOnEdge % array
       meshScalingDel2 =&gt; grid % meshScalingDel2 % array
+      edgeMask =&gt; grid % edgeMask % array
       dcEdge =&gt; grid % dcEdge % array
       dvEdge =&gt; grid % dvEdge % array
 
@@ -148,25 +145,26 @@
          vertex1 = verticesOnEdge(1,iEdge)
          vertex2 = verticesOnEdge(2,iEdge)
 
+         invLength1 = 1.0 / dcEdge(iEdge)
+         invLength2 = 1.0 / dvEdge(iEdge)
+
          do k=1,maxLevelEdgeTop(iEdge)
 
             ! Here -( vorticity(k,vertex2) - vorticity(k,vertex1) ) / dvEdge(iEdge)
             ! is - </font>
<font color="black">abla vorticity pointing from vertex 2 to vertex 1, or equivalently 
             !    + k \times </font>
<font color="gray">abla vorticity pointing from cell1 to cell2.
 
-            u_diffusion = ( divergence(k,cell2)  - divergence(k,cell1) ) / dcEdge(iEdge)  &amp;
+            u_diffusion = ( divergence(k,cell2)  - divergence(k,cell1) ) * invLength1 &amp;
                           -viscVortCoef &amp;
-                          *( vorticity(k,vertex2) - vorticity(k,vertex1) ) / dvEdge(iEdge)
+                          *( vorticity(k,vertex2) - vorticity(k,vertex1) ) * invLength2
 
             u_diffusion = meshScalingDel2(iEdge) * eddyVisc2 * u_diffusion
 
-            tend(k,iEdge) = tend(k,iEdge) + u_diffusion
+            tend(k,iEdge) = tend(k,iEdge) + edgeMask(k, iEdge) * u_diffusion
 
          end do
       end do
 
-      call mpas_timer_stop(&quot;compute_tend_u-horiz mix-del2&quot;)
-
    !--------------------------------------------------------------------
 
    end subroutine ocn_vel_hmix_del2_tend!}}}

Modified: branches/atmos_physics/src/core_ocean/mpas_ocn_vel_hmix_del4.F
===================================================================
--- branches/atmos_physics/src/core_ocean/mpas_ocn_vel_hmix_del4.F        2012-02-27 22:31:30 UTC (rev 1537)
+++ branches/atmos_physics/src/core_ocean/mpas_ocn_vel_hmix_del4.F        2012-02-27 22:33:23 UTC (rev 1538)
@@ -16,7 +16,6 @@
 
    use mpas_grid_types
    use mpas_configure
-   use mpas_timer
 
    implicit none
    private
@@ -43,8 +42,7 @@
    !
    !--------------------------------------------------------------------
 
-   logical :: &amp;
-      hmixDel4On       !&lt; local flag to determine whether del4 chosen
+   logical :: hmixDel4On       !&lt; local flag to determine whether del4 chosen
 
    real (kind=RKIND) :: &amp;
       eddyVisc4,        &amp;!&lt; base eddy diffusivity for biharmonic
@@ -114,30 +112,30 @@
       !
       !-----------------------------------------------------------------
 
-      integer :: iEdge, nEdges, cell1, cell2, vertex1, vertex2, k
+      integer :: iEdge, cell1, cell2, vertex1, vertex2, k
       integer :: iCell, iVertex
-      integer :: nVertices, nVertLevels, nCells
+      integer :: nVertices, nVertLevels, nCells, nEdges, nEdgesSolve
 
       integer, dimension(:), pointer :: maxLevelEdgeTop, maxLevelVertexBot, &amp;
             maxLevelCell
-      integer, dimension(:,:), pointer :: cellsOnEdge, verticesOnEdge
+      integer, dimension(:,:), pointer :: cellsOnEdge, verticesOnEdge, edgeMask
 
 
-      real (kind=RKIND) :: u_diffusion, r
+      real (kind=RKIND) :: u_diffusion, invAreaCell1, invAreaCell2, invAreaTri1, &amp;
+            invAreaTri2, invDcEdge, invDvEdge, r_tmp, delsq_u
       real (kind=RKIND), dimension(:), pointer :: dcEdge, dvEdge, areaTriangle, &amp;
             meshScalingDel4, areaCell
 
       real (kind=RKIND), dimension(:,:), allocatable :: delsq_divergence, &amp;
-            delsq_u, delsq_circulation, delsq_vorticity
+            delsq_circulation, delsq_vorticity
 
       err = 0
 
       if(.not.hmixDel4On) return
 
-      call mpas_timer_start(&quot;compute_tend-horiz mix-del4&quot;)
-
       nCells = grid % nCells
       nEdges = grid % nEdges
+      nEdgesSolve = grid % nEdgessolve
       nVertices = grid % nVertices
       nVertLevels = grid % nVertLevels
       maxLevelEdgeTop =&gt; grid % maxLevelEdgeTop % array
@@ -150,102 +148,70 @@
       areaTriangle =&gt; grid % areaTriangle % array
       areaCell =&gt; grid % areaCell % array
       meshScalingDel4 =&gt; grid % meshScalingDel4 % array
+      edgeMask =&gt; grid % edgeMask % array
 
       allocate(delsq_divergence(nVertLevels, nCells+1))
-      allocate(delsq_u(nVertLevels, nEdges+1))
-      allocate(delsq_circulation(nVertLevels, nVertices+1))
       allocate(delsq_vorticity(nVertLevels, nVertices+1))
 
-      delsq_u(:,:) = 0.0
-      delsq_circulation(:,:) = 0.0
       delsq_vorticity(:,:) = 0.0
       delsq_divergence(:,:) = 0.0
 
-      ! Compute </font>
<font color="black">abla^2 u = </font>
<font color="black">abla divergence + k \times </font>
<font color="red">abla vorticity
-      do iEdge=1,grid % nEdges
+      do iEdge=1,nEdges
          cell1 = cellsOnEdge(1,iEdge)
          cell2 = cellsOnEdge(2,iEdge)
+
          vertex1 = verticesOnEdge(1,iEdge)
          vertex2 = verticesOnEdge(2,iEdge)
 
-         do k=1,maxLevelEdgeTop(iEdge)
+         invAreaTri1 = 1.0 / areaTriangle(vertex1)
+         invAreaTri2 = 1.0 / areaTriangle(vertex2)
 
-            delsq_u(k,iEdge) = &amp; 
-               ( divergence(k,cell2)  - divergence(k,cell1) ) / dcEdge(iEdge)  &amp;
-               -viscVortCoef &amp;
-               *( vorticity(k,vertex2) - vorticity(k,vertex1)) / dvEdge(iEdge)
+         invAreaCell1 = 1.0 / areaCell(cell1)
+         invAreaCell2 = 1.0 / areaCell(cell2)
 
-         end do
-      end do
+         invDcEdge = 1.0 / dcEdge(iEdge)
+         invDvEdge = 1.0 / dvEdge(iEdge)
 
-      ! vorticity using </font>
<font color="red">abla^2 u
-      do iEdge=1,nEdges
-         vertex1 = verticesOnEdge(1,iEdge)
-         vertex2 = verticesOnEdge(2,iEdge)
          do k=1,maxLevelEdgeTop(iEdge)
-            delsq_circulation(k,vertex1) = delsq_circulation(k,vertex1) &amp;
-               - dcEdge(iEdge) * delsq_u(k,iEdge)
-            delsq_circulation(k,vertex2) = delsq_circulation(k,vertex2) &amp;
-               + dcEdge(iEdge) * delsq_u(k,iEdge)
-         end do
-      end do
-      do iVertex=1,nVertices
-         r = 1.0 / areaTriangle(iVertex)
-         do k=1,maxLevelVertexBot(iVertex)
-            delsq_vorticity(k,iVertex) = delsq_circulation(k,iVertex) * r
-         end do
-      end do
+            ! Compute </font>
<font color="black">abla^2 u = </font>
<font color="black">abla divergence + k \times </font>
<font color="red">abla vorticity
+            delsq_u =          ( divergence(k,cell2)  - divergence(k,cell1) ) * invDcEdge  &amp;
+                -viscVortCoef *( vorticity(k,vertex2) - vorticity(k,vertex1)) * invDvEdge 
 
-      ! Divergence using </font>
<font color="red">abla^2 u
-      do iEdge=1,nEdges
-         cell1 = cellsOnEdge(1,iEdge)
-         cell2 = cellsOnEdge(2,iEdge)
-         do k=1,maxLevelEdgeTop(iEdge)
-           delsq_divergence(k,cell1) = delsq_divergence(k,cell1) &amp;
-             + delsq_u(k,iEdge)*dvEdge(iEdge)
-           delsq_divergence(k,cell2) = delsq_divergence(k,cell2) &amp;
-             - delsq_u(k,iEdge)*dvEdge(iEdge)
+            ! vorticity using </font>
<font color="blue">abla^2 u
+            r_tmp = dcEdge(iEdge) * delsq_u
+            delsq_vorticity(k,vertex1) = delsq_vorticity(k,vertex1) - r_tmp * invAreaTri1
+            delsq_vorticity(k,vertex2) = delsq_vorticity(k,vertex2) + r_tmp * invAreaTri2
+
+            ! Divergence using </font>
<font color="red">abla^2 u
+            r_tmp = dvEdge(iEdge) * delsq_u
+            delsq_divergence(k, cell1) = delsq_divergence(k,cell1) + r_tmp * invAreaCell1
+            delsq_divergence(k, cell2) = delsq_divergence(k,cell2) - r_tmp * invAreaCell2
          end do
       end do
-      do iCell = 1,nCells
-         r = 1.0 / areaCell(iCell)
-         do k = 1,maxLevelCell(iCell)
-            delsq_divergence(k,iCell) = delsq_divergence(k,iCell) * r
-         end do
-      end do
 
       ! Compute - \kappa </font>
<font color="black">abla^4 u 
       ! as  </font>
<font color="black">abla div(</font>
<font color="black">abla^2 u) + k \times </font>
<font color="black">abla ( k \cross curl(</font>
<font color="gray">abla^2 u) )
-      do iEdge=1,grid % nEdgesSolve
+      do iEdge=1,nEdgesSolve
          cell1 = cellsOnEdge(1,iEdge)
          cell2 = cellsOnEdge(2,iEdge)
          vertex1 = verticesOnEdge(1,iEdge)
          vertex2 = verticesOnEdge(2,iEdge)
 
+         invDcEdge = 1.0 / dcEdge(iEdge)
+         invDvEdge = 1.0 / dvEdge(iEdge)
+         r_tmp = meshScalingDel4(iEdge) * eddyVisc4
+
          do k=1,maxLevelEdgeTop(iEdge)
-            delsq_u(k,iEdge) = &amp; 
-               ( divergence(k,cell2)  - divergence(k,cell1) ) / dcEdge(iEdge)  &amp;
-              -( vorticity(k,vertex2) - vorticity(k,vertex1)) / dvEdge(iEdge)
+            u_diffusion = (delsq_divergence(k,cell2) - delsq_divergence(k,cell1)) * invDcEdge  &amp;
+                -viscVortCoef * (delsq_vorticity(k,vertex2) - delsq_vorticity(k,vertex1) ) * invDvEdge
 
-            u_diffusion = (  delsq_divergence(k,cell2) &amp;
-                           - delsq_divergence(k,cell1) ) / dcEdge(iEdge)  &amp;
-                         -viscVortCoef &amp;
-                         *(  delsq_vorticity(k,vertex2) &amp;
-                           - delsq_vorticity(k,vertex1) ) / dvEdge(iEdge)
-
-            u_diffusion = meshScalingDel4(iEdge) * eddyVisc4 * u_diffusion
-
-            tend(k,iEdge) = tend(k,iEdge) - u_diffusion
+            tend(k,iEdge) = tend(k,iEdge) - edgeMask(k, iEdge) * u_diffusion * r_tmp
          end do
       end do
 
       deallocate(delsq_divergence)
-      deallocate(delsq_u)
-      deallocate(delsq_circulation)
       deallocate(delsq_vorticity)
 
-      call mpas_timer_stop(&quot;compute_tend-horiz mix-del4&quot;)
-
    !--------------------------------------------------------------------
 
    end subroutine ocn_vel_hmix_del4_tend!}}}

Modified: branches/atmos_physics/src/core_ocean/mpas_ocn_vel_pressure_grad.F
===================================================================
--- branches/atmos_physics/src/core_ocean/mpas_ocn_vel_pressure_grad.F        2012-02-27 22:31:30 UTC (rev 1537)
+++ branches/atmos_physics/src/core_ocean/mpas_ocn_vel_pressure_grad.F        2012-02-27 22:33:23 UTC (rev 1538)
@@ -17,6 +17,7 @@
 
    use mpas_grid_types
    use mpas_configure
+   use mpas_constants
 
    implicit none
    private
@@ -43,7 +44,7 @@
    !
    !--------------------------------------------------------------------
 
-   real (kind=RKIND) :: rho0Inv
+   real (kind=RKIND) :: rho0Inv, grho0Inv
 
 
 !***********************************************************************
@@ -64,7 +65,7 @@
 !
 !-----------------------------------------------------------------------
 
-   subroutine ocn_vel_pressure_grad_tend(grid, pressure, tend, err)!{{{
+   subroutine ocn_vel_pressure_grad_tend(grid, pressure, zMid, rho, tend, err)!{{{
 
       !-----------------------------------------------------------------
       !
@@ -73,7 +74,9 @@
       !-----------------------------------------------------------------
 
       real (kind=RKIND), dimension(:,:), intent(in) :: &amp;
-         pressure !&lt; Input: Pressure field or Mongomery potential
+         pressure, &amp; !&lt; Input: Pressure field or Mongomery potential
+         zMid, &amp;     !&lt; Input: z-coordinate at mid-depth of layer
+         rho         !&lt; Input: density
 
       type (mesh_type), intent(in) :: &amp;
          grid          !&lt; Input: grid information
@@ -103,9 +106,10 @@
 
       integer :: nEdgesSolve, iEdge, k, cell1, cell2
       integer, dimension(:), pointer :: maxLevelEdgeTop
-      integer, dimension(:,:), pointer :: cellsOnEdge
+      integer, dimension(:,:), pointer :: cellsOnEdge, edgeMask
 
       real (kind=RKIND), dimension(:), pointer :: dcEdge
+      real (kind=RKIND) :: invdcEdge
 
       err = 0
 
@@ -113,31 +117,35 @@
       maxLevelEdgeTop =&gt; grid % maxLevelEdgeTop % array
       cellsOnEdge =&gt; grid % cellsOnEdge % array
       dcEdge =&gt; grid % dcEdge % array
+      edgeMask =&gt; grid % edgeMask % array
 
-      if (config_vert_grid_type.eq.'isopycnal') then
-        do iEdge=1,nEdgesSolve
-          cell1 = cellsOnEdge(1,iEdge)
-          cell2 = cellsOnEdge(2,iEdge)
-          do k=1,maxLevelEdgeTop(iEdge)
-             tend(k,iEdge) = tend(k,iEdge)     &amp;
-               - (pressure(k,cell2) - pressure(k,cell1))/dcEdge(iEdge)
-           end do
-        enddo
-      elseif (config_vert_grid_type.eq.'zlevel') then
-        do iEdge=1,nEdgesSolve
-          cell1 = cellsOnEdge(1,iEdge)
-          cell2 = cellsOnEdge(2,iEdge)
-          do k=1,maxLevelEdgeTop(iEdge)
+      ! pressure for generalized coordinates
+      ! -1/rho_0 (grad p_k + rho g grad z_k^{mid})
 
+      ! For pure isopycnal coordinates, we are still using 
+      ! grad(M), the gradient of Montgomery Potential, because
+      ! we have set rho0Inv=1 and grho0Inv=0 in the init routine,
+      ! and pressure is passed in as MontPot.
+
+      do iEdge=1,nEdgesSolve
+         cell1 = cellsOnEdge(1,iEdge)
+         cell2 = cellsOnEdge(2,iEdge)
+         invdcEdge = 1.0 / dcEdge(iEdge)
+
+         do k=1,maxLevelEdgeTop(iEdge)
             tend(k,iEdge) = tend(k,iEdge)     &amp;
-              - rho0Inv*(  pressure(k,cell2) &amp;
-                         - pressure(k,cell1) )/dcEdge(iEdge)
-          end do
+              - edgeMask(k,iEdge) * rho0Inv*(  pressure(k,cell2) &amp;
+                         - pressure(k,cell1) )* invdcEdge &amp;
+              - edgeMask(k,iEdge) * grho0Inv*  0.5*(rho(k,cell1)+rho(k,cell2)) &amp;
+                        *(  zMid(k,cell2) &amp;
+                          - zMid(k,cell1) )* invdcEdge
+                      
+         end do
 
-        enddo
-      endif
+      end do
 
 
+
    !--------------------------------------------------------------------
 
    end subroutine ocn_vel_pressure_grad_tend!}}}
@@ -178,12 +186,16 @@
 
       err = 0
 
-      if (config_vert_grid_type.eq.'isopycnal') then
+      if (config_pressure_type.eq.'MontgomeryPotential') then
         rho0Inv = 1.0
-      elseif (config_vert_grid_type.eq.'zlevel') then
+        grho0Inv = 0.0
+      else 
         rho0Inv = 1.0/config_rho0
+        grho0Inv = gravity/config_rho0
       end if
 
+
+
    !--------------------------------------------------------------------
 
    end subroutine ocn_vel_pressure_grad_init!}}}

Modified: branches/atmos_physics/src/core_ocean/mpas_ocn_vel_vadv.F
===================================================================
--- branches/atmos_physics/src/core_ocean/mpas_ocn_vel_vadv.F        2012-02-27 22:31:30 UTC (rev 1537)
+++ branches/atmos_physics/src/core_ocean/mpas_ocn_vel_vadv.F        2012-02-27 22:33:23 UTC (rev 1538)
@@ -64,7 +64,7 @@
 !
 !-----------------------------------------------------------------------
 
-   subroutine ocn_vel_vadv_tend(grid, u, wTop, tend, err)!{{{
+   subroutine ocn_vel_vadv_tend(grid, u, h_edge, wTop, tend, err)!{{{
 
       !-----------------------------------------------------------------
       !
@@ -75,6 +75,7 @@
       real (kind=RKIND), dimension(:,:), intent(in) :: &amp;
          u     !&lt; Input: Horizontal velocity
       real (kind=RKIND), dimension(:,:), intent(in) :: &amp;
+         h_edge,&amp;!&lt; Input: thickness at edge
          wTop  !&lt; Input: Vertical velocity on top layer
 
       type (mesh_type), intent(in) :: &amp;
@@ -106,12 +107,16 @@
       integer :: iEdge, nEdgesSolve, cell1, cell2, k
       integer :: nVertLevels
       integer, dimension(:), pointer :: maxLevelEdgeTop
-      integer, dimension(:,:), pointer :: cellsOnEdge
+      integer, dimension(:,:), pointer :: cellsOnEdge, edgeMask
 
       real (kind=RKIND) :: wTopEdge
       real (kind=RKIND), dimension(:), allocatable :: w_dudzTopEdge
-      real (kind=RKIND), dimension(:), pointer :: zMidZLevel
 
+      ! mrp 120202 efficiency note:
+      ! The following if statement is not needed, since wTop is set to 
+      ! zero for isopycnal coordinates.  This if statment saves flops
+      ! for isopycnal coordinates.  However, if the loops are pushed
+      ! out, we could get rid of this if statement.
       if(.not.velVadvOn) return
 
       err = 0
@@ -120,7 +125,7 @@
       nEdgesSolve = grid % nEdgesSolve
       maxLevelEdgeTop =&gt; grid % maxLevelEdgeTop % array
       cellsOnEdge =&gt; grid % cellsOnEdge % array
-      zMidZLevel =&gt; grid % zMidZLevel % array
+      edgeMask =&gt; grid % edgeMask % array
 
       allocate(w_dudzTopEdge(nVertLevels+1))
       w_dudzTopEdge = 0.0
@@ -134,14 +139,13 @@
 
           ! compute dudz at vertical interface with first order derivative.
           w_dudzTopEdge(k) = wTopEdge * (u(k-1,iEdge)-u(k,iEdge)) &amp;
-                       / (zMidZLevel(k-1) - zMidZLevel(k))
+                       / (0.5*(h_edge(k-1,iEdge) + h_edge(k,iEdge)))
         end do
         w_dudzTopEdge(maxLevelEdgeTop(iEdge)+1) = 0.0
         ! Average w*du/dz from vertical interface to vertical middle of cell
         do k=1,maxLevelEdgeTop(iEdge)
 
-          tend(k,iEdge) = tend(k,iEdge) &amp;
-             - 0.5 * (w_dudzTopEdge(k) + w_dudzTopEdge(k+1))
+          tend(k,iEdge) = tend(k,iEdge) - edgeMask(k, iEdge) * 0.5 * (w_dudzTopEdge(k) + w_dudzTopEdge(k+1))
         enddo
       enddo
       deallocate(w_dudzTopEdge)
@@ -179,7 +183,7 @@
       err = 0
       velVadvOn = .false.
 
-      if (config_vert_grid_type.eq.'zlevel') then
+      if (config_vert_grid_type.ne.'isopycnal') then
           velVadvOn = .true.
       end if
 

Modified: branches/atmos_physics/src/core_ocean/mpas_ocn_vmix.F
===================================================================
--- branches/atmos_physics/src/core_ocean/mpas_ocn_vmix.F        2012-02-27 22:31:30 UTC (rev 1537)
+++ branches/atmos_physics/src/core_ocean/mpas_ocn_vmix.F        2012-02-27 22:33:23 UTC (rev 1538)
@@ -199,8 +199,6 @@
 
       if(implicitOn) return
 
-      call mpas_timer_start(&quot;compute_tend_u-explicit vert mix&quot;)
-
       nEdgessolve = grid % nEdgesSolve
       nVertLevels = grid % nVertLevels
       maxLevelEdgeTop =&gt; grid % maxLevelEdgeTop % array
@@ -223,9 +221,6 @@
 
       end do
       deallocate(fluxVertTop)
-
-      call mpas_timer_stop(&quot;compute_tend_u-explicit vert mix&quot;)
-
    !--------------------------------------------------------------------
 
    end subroutine ocn_vel_vmix_tend_explicit!}}}
@@ -319,7 +314,6 @@
          ! mrp 110315 efficiency note: for z-level, could precompute
          ! -2.0*dt/(h(k)_h(k+1))/h(k) in setup
          ! h_edge is computed in compute_solve_diag, and is not available yet.
-         ! This could be removed if hZLevel used instead.
          cell1 = cellsOnEdge(1,iEdge)
          cell2 = cellsOnEdge(2,iEdge)
          do k=1,maxLevelEdgeTop(iEdge)
@@ -347,6 +341,8 @@
         end if
       end do
 
+      deallocate(A,C,uTemp)
+
    !--------------------------------------------------------------------
 
    end subroutine ocn_vel_vmix_tend_implicit!}}}
@@ -418,8 +414,6 @@
 
       if(implicitOn) return
 
-      call mpas_timer_start(&quot;compute_scalar_tend-explicit vert diff&quot;)
-
       nCellsSolve = grid % nCellsSolve
       nVertLevels = grid % nVertLevels
       num_tracers = size(tracers, dim=1)
@@ -454,9 +448,6 @@
 !print '(a,50e12.2)', 'tend_tr    ',tend_tr(3,1,1:maxLevelCell(iCell))
       enddo ! iCell loop
       deallocate(fluxVertTop)
-
-      call mpas_timer_stop(&quot;compute_scalar_tend-explicit vert diff&quot;)
-
    !--------------------------------------------------------------------
 
    end subroutine ocn_tracer_vmix_tend_explicit!}}}
@@ -558,9 +549,9 @@
          tracers(:,1:maxLevelCell(iCell),iCell) = tracersTemp(:,1:maxLevelCell(iCell))
          tracers(:,maxLevelCell(iCell)+1:nVertLevels,iCell) = -1e34
       end do
+
       deallocate(A,C,tracersTemp)
 
-
    !--------------------------------------------------------------------
 
    end subroutine ocn_tracer_vmix_tend_implicit!}}}
@@ -602,7 +593,7 @@
 
       if(config_implicit_vertical_mix) then
           explicitOn = .false.
-          implicitOn =.true.
+          implicitOn = .true.
       end if
 
       call ocn_vmix_coefs_const_init(err1)

Modified: branches/atmos_physics/src/core_ocean/mpas_ocn_vmix_coefs_rich.F
===================================================================
--- branches/atmos_physics/src/core_ocean/mpas_ocn_vmix_coefs_rich.F        2012-02-27 22:31:30 UTC (rev 1537)
+++ branches/atmos_physics/src/core_ocean/mpas_ocn_vmix_coefs_rich.F        2012-02-27 22:33:23 UTC (rev 1538)
@@ -26,6 +26,8 @@
    private
    save
 
+   type (timer_node), pointer :: richEOSTimer
+
    !--------------------------------------------------------------------
    !
    ! Public parameters
@@ -139,8 +141,10 @@
       rhoDisplaced =&gt; s % rhoDisplaced % array
       tracers =&gt; s % tracers % array
 
+      call mpas_timer_start(&quot;eos rich&quot;, .false., richEOSTimer)
       call ocn_equation_of_state_rho(s, grid, 0, 'relative', err)
       call ocn_equation_of_state_rho(s, grid, 1, 'relative', err)
+      call mpas_timer_stop(&quot;eos rich&quot;, richEOSTimer)
 
       call ocn_vmix_get_rich_numbers(grid, indexT, indexS, u, h, h_edge, &amp; 
                                   rho, rhoDisplaced, tracers, RiTopOfEdge, RiTopOfCell, err1)
@@ -244,8 +248,6 @@
                else
                   ! for Ri&lt;0 and explicit vertical mix, 
                   ! use maximum diffusion allowed by CFL criterion
-                  ! mrp 110324 efficiency note: for z-level, could use fixed
-                  ! grid array hMeanTopZLevel and compute maxdiff on startup.
                   vertViscTopOfEdge(k,iEdge) = &amp;
                       ((h_edge(k-1,iEdge)+h_edge(k,iEdge))/2.0)**2/config_dt/4.0
                end if
@@ -353,8 +355,6 @@
                else
                   ! for Ri&lt;0 and explicit vertical mix, 
                   ! use maximum diffusion allowed by CFL criterion
-                  ! mrp 110324 efficiency note: for z-level, could use fixed
-                  ! grid array hMeanTopZLevel and compute maxdiff on startup.
                   vertDiffTopOfCell(k,iCell) = &amp;
                      ((h(k-1,iCell)+h(k,iCell))/2.0)**2/config_dt/4.0
                end if
@@ -440,7 +440,7 @@
 
       err = 0
 
-      if(.not.richViscOn .and. .not.richDiffOn) return
+      if((.not.richViscOn) .and. (.not.richDiffOn)) return
 
       nVertLevels = grid % nVertLevels
       nCells = grid % nCells
@@ -455,8 +455,8 @@
       areaCell =&gt; grid % areaCell % array
 
       allocate( &amp;
-         drhoTopOfCell(nVertLevels+1,nCells+1), drhoTopOfEdge(nVertLevels+1,nEdges+1), &amp;
-         du2TopOfCell(nVertLevels+1,nCells+1), du2TopOfEdge(nVertLevels+1,nEdges+1))
+         drhoTopOfCell(nVertLevels+1,nCells+1), drhoTopOfEdge(nVertLevels+1,nEdges), &amp;
+         du2TopOfCell(nVertLevels+1,nCells+1), du2TopOfEdge(nVertLevels+1,nEdges))
 
       ! compute density of parcel displaced to next deeper z-level,
       ! in state % rhoDisplaced

Modified: branches/atmos_physics/src/core_ocean/mpas_ocn_vmix_coefs_tanh.F
===================================================================
--- branches/atmos_physics/src/core_ocean/mpas_ocn_vmix_coefs_tanh.F        2012-02-27 22:31:30 UTC (rev 1537)
+++ branches/atmos_physics/src/core_ocean/mpas_ocn_vmix_coefs_tanh.F        2012-02-27 22:33:23 UTC (rev 1538)
@@ -177,18 +177,22 @@
 
       integer :: k, nVertLevels
 
-      real (kind=RKIND), dimension(:), pointer :: zTopZLevel
+      real (kind=RKIND), dimension(:), pointer :: referenceBottomDepth
 
       err = 0
 
       if(.not.tanhViscOn) return
 
       nVertLevels = grid % nVertLevels
-      zTopZLevel =&gt; grid % zTopZLevel % array
+      referenceBottomDepth =&gt; grid % referenceBottomDepth % array
 
-      do k=1,nVertLevels+1
-          vertViscTopOfEdge(k,:) = -(config_max_visc_tanh-config_min_visc_tanh)/2.0 &amp;
-            *tanh(-(zTopZLevel(k)-config_ZMid_tanh) &amp;
+      ! referenceBottomDepth is used here for simplicity.  Using zMid and h, which 
+      ! vary in time, would give the exact location of the top, but it
+      ! would only change the diffusion value very slightly.
+      vertViscTopOfEdge = 0.0
+      do k=2,nVertLevels
+         vertViscTopOfEdge(k,:) = -(config_max_visc_tanh-config_min_visc_tanh)/2.0 &amp;
+            *tanh((referenceBottomDepth(k-1)+config_ZMid_tanh) &amp;
                   /config_zWidth_tanh) &amp;
             + (config_max_visc_tanh+config_min_visc_tanh)/2
       end do
@@ -246,18 +250,22 @@
 
       integer :: k, nVertLevels
 
-      real (kind=RKIND), dimension(:), pointer :: zTopZLevel
+      real (kind=RKIND), dimension(:), pointer :: referenceBottomDepth
 
       err = 0
 
       if(.not.tanhDiffOn) return
 
       nVertLevels = grid % nVertLevels
-      zTopZLevel =&gt; grid % zTopZLevel % array
+      referenceBottomDepth =&gt; grid % referenceBottomDepth % array
 
-      do k=1,nVertLevels+1
+      ! referenceBottomDepth is used here for simplicity.  Using zMid and h, which 
+      ! vary in time, would give the exact location of the top, but it
+      ! would only change the diffusion value very slightly.
+      vertDiffTopOfCell = 0.0
+      do k=2,nVertLevels
          vertDiffTopOfCell(k,:) = -(config_max_diff_tanh-config_min_diff_tanh)/2.0 &amp;
-            *tanh(-(zTopZLevel(k)-config_ZMid_tanh) &amp;
+            *tanh((referenceBottomDepth(k-1)+config_ZMid_tanh) &amp;
                   /config_zWidth_tanh) &amp;
             + (config_max_diff_tanh+config_min_diff_tanh)/2
       end do
@@ -308,14 +316,6 @@
           tanhDiffOn = .true.
       endif
 
-      if(tanhViscOn .or. tanhDiffOn) then
-         if (config_vert_grid_type.ne.'zlevel') then
-            write(0,*) 'Abort: config_vert_diff_type.eq.tanh may only', &amp;
-                       ' use config_vert_grid_type of zlevel at this time'
-            err = 1
-         endif
-      endif
-
    !--------------------------------------------------------------------
 
    end subroutine ocn_vmix_coefs_tanh_init!}}}

</font>
</pre>