Index: sm/trunk/CMakeLists.txt
===================================================================
--- /issm/trunk/CMakeLists.txt	(revision 17805)
+++ 	(revision )
@@ -1,57 +1,0 @@
-# CMake version check. Version 2.6 is considered standard.
-cmake_minimum_required (VERSION 2.6) 
-
-# Project Information {{{
-# Project Name
-project(ISSM) 
-set(ISSM_VERSION_MAJOR 4)
-set(ISSM_VERSION_MINOR 1)
-# }}}
-# Contact Information {{{
-set(ISSM_EMAIL "issm@jpl.nasa.gov")
-set(ISSM_WEBSITE "http://issm.jpl.nasa.gov")
-# }}}
-
-# CMake Modules {{{
-include(CheckLanguage)
-include(./m4/issm_options.cmake)
-# }}}
-
-# Language Checks {{{
-
-# 'C' language check.
-include(CheckLanguage)
-
-check_language(C)
-if(CMAKE_C_COMPILER)
-   enable_language(C)
-else(CMAKE_C_COMPILER)
-   message(FATAL_ERROR "No C support found!")
-endif(CMAKE_C_COMPILER)
-
-# 'C++' language check.
-check_language(CXX)
-if(CMAKE_CXX_COMPILER)
-   enable_language(CXX)
-else(CMAKE_CXX_COMPILER)
-   message(FATA_ERROR "No C++ support found!")
-endif(CMAKE_CXX_COMPILER)
-
-# 'Fortran' language check.
-#check_language(Fortran)
-#if(CMAKE_Fortran_COMPILER)
-#   enable_language(Fortran)
-#else(CMAKE_Fortran_COMPILER)
-#   message(FATA_ERROR "No Fortran support")
-#endif(CMAKE_Fortran_COMPILER)
-# }}}
-
-# Subdirectories {{{
-add_subdirectory(src) 
-# }}}
-
-# Options {{{
-option(SHARED_LIBS "Set whether to produce shared libraries, or not. Default is no."
-       OFF)
-# Questionable whether all options should be contained within this file or included from some other file.
-# }}}
Index: /issm/trunk/configs/config-linux64-acenet.sh
===================================================================
--- /issm/trunk/configs/config-linux64-acenet.sh	(revision 17806)
+++ /issm/trunk/configs/config-linux64-acenet.sh	(revision 17806)
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+./configure \
+ --prefix=/home/klemorza/issm/trunk-jpl \
+ --with-metis-dir=$ISSM_DIR/externalpackages/metis/install \
+ --with-metis-dir=$ISSM_DIR/externalpackages/petsc/install
+ --with-petsc-dir=$ISSM_DIR/externalpackages/petsc/install \
+ --with-mpi-include=$OPENMPI/include  \
+ --with-mpi-libflags="-L$OPENMPI/lib -lmpi" \
+ --with-blas-lapack-dir=$ISSM_DIR/externalpackages/petsc/install \
+ --with-scalapack-dir=$ISSM_DIR/externalpackages/petsc/install/ \
+ --with-mumps-dir=$ISSM_DIR/externalpackages/petsc/install/ \
+ --with-cxxoptflags="-O2" \
+ --with-numthreads=32 \
+ --with-serial=no \
+ --with-modules=no \
+ --enable-debugging CC=mpicc CXX=mpiCC F77=mpif77
Index: /issm/trunk/configs/config-linux64-pleiades-ampi-gcc.sh
===================================================================
--- /issm/trunk/configs/config-linux64-pleiades-ampi-gcc.sh	(revision 17805)
+++ /issm/trunk/configs/config-linux64-pleiades-ampi-gcc.sh	(revision 17806)
@@ -5,15 +5,18 @@
 	--with-wrappers=no \
 	--with-triangle-dir="$ISSM_DIR/externalpackages/triangle/install" \
-	--with-mpi-include="/nasa/mvapich2/1.6.sles11/gcc/include" \
-	--with-mpi-libflags="-L/nasa/mvapich2/1.6.sles11/gcc/lib -llmpe -lmpe -lmpich" \
+	--with-mpi-include=$ISSM_DIR/externalpackages/mpich/install/include  \
+	--with-mpi-libflags="-L$ISSM_DIR/externalpackages/mpich/install/lib/ -lmpich -lmpl " \
 	--with-adolc-dir="$ISSM_DIR/externalpackages/adolc/install"\
 	--with-ampi-dir="$ISSM_DIR/externalpackages/adjoinablempi/install"\
+	--with-metis-dir="$ISSM_DIR/externalpackages/petsc/install" \
 	--with-blas-lapack-dir="$ISSM_DIR/externalpackages/petsc/install" \
 	--with-gsl-dir="$ISSM_DIR/externalpackages/gsl/install" \
-	--with-metis-dir="$ISSM_DIR/externalpackages/petsc/install" \
 	--with-mumps-dir="$ISSM_DIR/externalpackages/petsc/install" \
 	--with-scalapack-dir="$ISSM_DIR/externalpackages/petsc/install" \
 	--with-hypre-dir="$ISSM_DIR/externalpackages/petsc/install" \
 	--with-graphics-lib="/usr/lib64/libX11.so" \
-	--with-cxxoptflags="-g -O2" \
-	--with-vendor="intel-pleiades-gcc"
+	--with-cxxoptflags=" -O3 -march=corei7-avx" \
+	--with-vendor="intel-pleiades-gcc"  \
+	CFLAGS="-O3 -march=corei7-avx" \
+	CXXFLAGS="-O3 -march=corei7-avx" \
+	FFLAGS="-O3 -march=corei7-avx" 
Index: /issm/trunk/configs/config-linux64-pleiades-intel2012.0.032-mpt.2.06rp16.sh
===================================================================
--- /issm/trunk/configs/config-linux64-pleiades-intel2012.0.032-mpt.2.06rp16.sh	(revision 17806)
+++ /issm/trunk/configs/config-linux64-pleiades-intel2012.0.032-mpt.2.06rp16.sh	(revision 17806)
@@ -0,0 +1,18 @@
+#!/bin/csh
+./configure \
+	--prefix=$ISSM_DIR \
+	--without-kriging \
+	--with-matlab-dir="$ISSM_DIR/externalpackages/matlab/install" \
+	--with-petsc-dir="$ISSM_DIR/externalpackages/petsc/install" \
+	--with-petsc-arch=$ISSM_ARCH \
+	--with-triangle-dir="$ISSM_DIR/externalpackages/triangle/install" \
+	--with-mpi-include="/nasa/sgi/mpt/2.06rp16/include" \
+	--with-mpi-libflags="-L/nasa/sgi/mpt/2.06rp16/ -lmpi" \
+	--with-mkl-dir="/nasa/intel/Compiler/2012.0.032/composer_xe_2011_sp1/mkl/lib/intel64"\
+	--with-metis-dir="$ISSM_DIR/externalpackages/petsc/install" \
+	--with-mumps-dir="$ISSM_DIR/externalpackages/petsc/install" \
+	--with-scalapack-dir="$ISSM_DIR/externalpackages/petsc/install" \
+	--with-hypre-dir="$ISSM_DIR/externalpackages/petsc/install" \
+	--with-graphics-lib="/usr/lib64/libX11.so" \
+	--with-cxxoptflags="-g -O2" \
+	--with-vendor="intel-pleiades"
Index: /issm/trunk/configs/config-linux64-skylla.sh
===================================================================
--- /issm/trunk/configs/config-linux64-skylla.sh	(revision 17805)
+++ /issm/trunk/configs/config-linux64-skylla.sh	(revision 17806)
@@ -15,4 +15,5 @@
  --with-petsc-arch=$ISSM_ARCH \
  --with-blas-lapack-dir=$ISSM_DIR/externalpackages/petsc/install \
+ --with-tao-dir=$ISSM_DIR/externalpackages/tao/install/ \
  --with-scalapack-dir=$ISSM_DIR/externalpackages/petsc/install/ \
  --with-mumps-dir=$ISSM_DIR/externalpackages/petsc/install/ \
Index: /issm/trunk/configure.ac
===================================================================
--- /issm/trunk/configure.ac	(revision 17805)
+++ /issm/trunk/configure.ac	(revision 17806)
@@ -2,5 +2,5 @@
 
 #AUTOCONF
-AC_INIT([Ice Sheet System Model (ISSM)],[4.5],[issm@jpl.nasa.gov],[issm],[http://issm.jpl.nasa.gov]) #Initializing configure
+AC_INIT([Ice Sheet System Model (ISSM)],[4.6],[issm@jpl.nasa.gov],[issm],[http://issm.jpl.nasa.gov]) #Initializing configure
 AC_CONFIG_AUX_DIR([./aux-config])         #Put config files in aux-config
 AC_CONFIG_MACRO_DIR([m4])                 #m4 macros are located in m4
Index: /issm/trunk/etc/environment.csh
===================================================================
--- /issm/trunk/etc/environment.csh	(revision 17805)
+++ /issm/trunk/etc/environment.csh	(revision 17806)
@@ -13,5 +13,5 @@
 
 #MPI
-set MPI_DIR="$ISSM_DIR/externalpackages/mpich2/install"
+set MPI_DIR="$ISSM_DIR/externalpackages/mpich/install"
 if (-d $MPI_DIR) then
 	setenv MPI_DIR {$MPI_DIR}
@@ -96,2 +96,8 @@
 	setenv PATH {$PATH}:{$YAMS_DIR}/bin
 endif
+
+#SHELL2JUNIT
+set SHELL2JUNIT_DIR="$ISSM_DIR/externalpackages/shell2junit"
+if (-d $SHELL2JUNIT_DIR) then
+	setenv PATH {$PATH}:{$SHELL2JUNIT_DIR}/install
+endif
Index: /issm/trunk/etc/environment.sh
===================================================================
--- /issm/trunk/etc/environment.sh	(revision 17805)
+++ /issm/trunk/etc/environment.sh	(revision 17806)
@@ -3,10 +3,20 @@
 pathprepend(){ #{{{
 	if [ -d "$1" ] && [[ ":$PATH:" != *":$1:"* ]]; then
-		export PATH="$1:$PATH"
+		name=$1
+		if [[ "$ISSM_ARCH" == "cygwin-intel" ]]; then
+			#export path using the cygwin convention
+			name=`cygpath -u $1`
+		fi
+		export PATH="$name:$PATH"
 	fi
 } #}}}
 pathappend(){ #{{{
 	if [ -d "$1" ] && [[ ":$PATH:" != *":$1:"* ]]; then
-		export PATH="$PATH:$1"
+		name=$1
+		if [[ "$ISSM_ARCH" == "cygwin-intel" ]]; then
+			#export path in cygwin convention
+			name=`cygpath -u $1`
+		fi
+		export PATH="$PATH:$name"
 	fi
 } #}}}
@@ -116,5 +126,6 @@
 
 PROJ4_DIR="$ISSM_DIR/externalpackages/proj.4/install"
-libpathappend "$PROJ4_DIR/lib"
+dylibpathprepend "$PROJ4_DIR/lib"
+libpathprepend "$PROJ4_DIR/lib"
 
 MERCURIAL_DIR="$ISSM_DIR/externalpackages/mercurial/install"
@@ -287,2 +298,9 @@
 #INISHELL
 pathappend   "$ISSM_DIR/externalpackages/inishell/install"
+
+#SHELL2JUNIT
+pathappend   "$ISSM_DIR/externalpackages/shell2junit/install"
+
+#EXPAT
+libpathprepend   "$ISSM_DIR/externalpackages/expat/install"
+dylibpathprepend   "$ISSM_DIR/externalpackages/expat/install"
Index: /issm/trunk/examples/Jakobshavn/Jks.par
===================================================================
--- /issm/trunk/examples/Jakobshavn/Jks.par	(revision 17805)
+++ /issm/trunk/examples/Jakobshavn/Jks.par	(revision 17806)
@@ -22,8 +22,8 @@
 
 disp('   Interpolating bedrock topography');
-md.geometry.bed=InterpFromGridToMesh(x1,y1,topg,md.mesh.x,md.mesh.y,0);
+md.geometry.base = InterpFromGridToMesh(x1,y1,topg,md.mesh.x,md.mesh.y,0);
 
 disp('   Constructing surface elevation');
-md.geometry.surface=md.geometry.thickness+md.geometry.bed;
+md.geometry.surface=md.geometry.thickness+md.geometry.base;
 
 disp('   Interpolating velocities');
@@ -51,4 +51,5 @@
 md.materials.rheology_n=3*ones(md.mesh.numberofelements,1);
 md.materials.rheology_B=paterson(md.initialization.temperature);
+md.damage.D=zeros(md.mesh.numberofvertices,1);
 %Reduce viscosity along the shear margins
 weakb=ContourToMesh(md.mesh.elements,md.mesh.x,md.mesh.y,'WeakB.exp','node',2);
Index: /issm/trunk/examples/Jakobshavn/runme.m
===================================================================
--- /issm/trunk/examples/Jakobshavn/runme.m	(revision 17805)
+++ /issm/trunk/examples/Jakobshavn/runme.m	(revision 17806)
@@ -1,3 +1,3 @@
-steps=[1];
+steps=[1:3];
 
 if any(steps==1)
@@ -52,5 +52,5 @@
 
 	%Cost functions
-	md.inversion.cost_functions=[101*ones(md.inversion.nsteps,1) 103*ones(md.inversion.nsteps,1)];
+	md.inversion.cost_functions=[101 103];
 	md.inversion.cost_functions_coefficients=ones(md.mesh.numberofvertices,2);
 	md.inversion.cost_functions_coefficients(:,1)=40;
Index: /issm/trunk/examples/SquareIceShelf/Square.par
===================================================================
--- /issm/trunk/examples/SquareIceShelf/Square.par	(revision 17805)
+++ /issm/trunk/examples/SquareIceShelf/Square.par	(revision 17806)
@@ -6,7 +6,7 @@
 ymin=min(md.mesh.y);
 ymax=max(md.mesh.y);
-md.geometry.thickness=hmax+(hmin-hmax)*(md.mesh.y-ymin)/(ymax-ymin);
-md.geometry.bed=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness;
-md.geometry.surface=md.geometry.bed+md.geometry.thickness;
+md.geometry.thickness = hmax+(hmin-hmax)*(md.mesh.y-ymin)/(ymax-ymin);
+md.geometry.base      = -md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness;
+md.geometry.surface   = md.geometry.base+md.geometry.thickness;
 
 disp('      creating drag');
@@ -25,4 +25,5 @@
 md.materials.rheology_B=paterson((273-20)*ones(md.mesh.numberofvertices,1));
 md.materials.rheology_n=3*ones(md.mesh.numberofelements,1);
+md.damage.D=zeros(md.mesh.numberofvertices,1);
 
 disp('      creating boundary conditions');
Index: /issm/trunk/externalpackages/adjoinablempi/install-pleaides-gcc.sh
===================================================================
--- /issm/trunk/externalpackages/adjoinablempi/install-pleaides-gcc.sh	(revision 17806)
+++ /issm/trunk/externalpackages/adjoinablempi/install-pleaides-gcc.sh	(revision 17806)
@@ -0,0 +1,27 @@
+#!/bin/bash
+set -eu
+
+#Some cleanup
+rm -rf src  install
+
+#Mercurial cloning: 
+hg clone http://mercurial.mcs.anl.gov//ad/AdjoinableMPI src
+
+#Configure adjoinablempi
+cd src
+autoreconf -fi
+
+./configure \
+	--prefix="$ISSM_DIR/externalpackages/adjoinablempi/install" \
+	--libdir="$ISSM_DIR/externalpackages/adjoinablempi/install/lib" \
+	--with-mpi-root="$ISSM_DIR/externalpackages/mpich/install" \
+	--enable-requestOnTrace CFLAGS="-g -O0"
+
+#Compile adjoinablempi 
+make clean
+if [ $# -eq 0 ]; then
+	make 
+else
+	make -j $1
+fi
+make install
Index: /issm/trunk/externalpackages/adolc/install-withampi-macosx64.sh
===================================================================
--- /issm/trunk/externalpackages/adolc/install-withampi-macosx64.sh	(revision 17805)
+++ /issm/trunk/externalpackages/adolc/install-withampi-macosx64.sh	(revision 17806)
@@ -20,4 +20,5 @@
 	--enable-ampi \
 	--with-ampi=$ISSM_DIR/externalpackages/adjoinablempi/install \
+        --with-soname=adolc \
 	--disable-tapedoc-values
 
Index: /issm/trunk/externalpackages/adolc/install-withampi-pleiades-gcc.sh
===================================================================
--- /issm/trunk/externalpackages/adolc/install-withampi-pleiades-gcc.sh	(revision 17805)
+++ /issm/trunk/externalpackages/adolc/install-withampi-pleiades-gcc.sh	(revision 17806)
@@ -14,7 +14,8 @@
 ./configure --prefix=$ISSM_DIR/externalpackages/adolc/install  \
 	--libdir=$ISSM_DIR/externalpackages/adolc/install/lib \
-	--with-mpi-root="/nasa/mvapich2/1.6.sles11/gcc" \
+	--with-mpi-root=$ISSM_DIR/externalpackages/mpich/install \
 	--enable-ampi \
 	--with-ampi=$ISSM_DIR/externalpackages/adjoinablempi/install \
+        --with-soname=adolc \
 	--disable-tapedoc-values
 
Index: /issm/trunk/externalpackages/adolc/install-withampi-pleiades.sh
===================================================================
--- /issm/trunk/externalpackages/adolc/install-withampi-pleiades.sh	(revision 17805)
+++ /issm/trunk/externalpackages/adolc/install-withampi-pleiades.sh	(revision 17806)
@@ -17,4 +17,5 @@
 	--enable-ampi \
 	--with-ampi=$ISSM_DIR/externalpackages/adjoinablempi/install \
+        --with-soname=adolc \
 	--disable-tapedoc-values
 
Index: /issm/trunk/externalpackages/adolc/install-withampi.sh
===================================================================
--- /issm/trunk/externalpackages/adolc/install-withampi.sh	(revision 17805)
+++ /issm/trunk/externalpackages/adolc/install-withampi.sh	(revision 17806)
@@ -1,5 +1,5 @@
 #!/bin/bash
 set -eu
-
+ 
 #Some cleanup
 rm -rf install src
@@ -17,4 +17,5 @@
 	--enable-ampi \
 	--with-ampi=$ISSM_DIR/externalpackages/adjoinablempi/install \
+	--with-soname=adolc \
 	--disable-tapedoc-values
 
Index: /issm/trunk/externalpackages/cccl/install-win7.sh
===================================================================
--- /issm/trunk/externalpackages/cccl/install-win7.sh	(revision 17805)
+++ /issm/trunk/externalpackages/cccl/install-win7.sh	(revision 17806)
@@ -9,2 +9,3 @@
 #Move cccl into install directory
 cp issm/cccl install/bin
+chmod 755 install/bin/cccl
Index: /issm/trunk/externalpackages/cython/install-18.sh
===================================================================
--- /issm/trunk/externalpackages/cython/install-18.sh	(revision 17806)
+++ /issm/trunk/externalpackages/cython/install-18.sh	(revision 17806)
@@ -0,0 +1,13 @@
+#!/bin/bash
+set -eu
+
+#clean up
+rm -rf Cython-0.18
+
+#download numpy first
+$ISSM_DIR/scripts/DownloadExternalPackage.py 'http://issm.jpl.nasa.gov/files/externalpackages/Cython-0.18.tar.gz' 'cython.tar.gz'
+
+#install numpy
+tar -zxvf cython.tar.gz
+cd Cython-0.18
+python setup.py install
Index: /issm/trunk/externalpackages/cython/install-19.2.sh
===================================================================
--- /issm/trunk/externalpackages/cython/install-19.2.sh	(revision 17806)
+++ /issm/trunk/externalpackages/cython/install-19.2.sh	(revision 17806)
@@ -0,0 +1,13 @@
+#!/bin/bash
+set -eu
+
+#clean up
+rm -rf Cython-0.19.2
+
+#download numpy first
+$ISSM_DIR/scripts/DownloadExternalPackage.py 'http://issm.jpl.nasa.gov/files/externalpackages/Cython-0.19.2.tar.gz' 'cython.tar.gz'
+
+#install numpy
+tar -zxvf cython.tar.gz
+cd Cython-0.19.2
+python setup.py install
Index: /issm/trunk/externalpackages/cython/install.sh
===================================================================
--- /issm/trunk/externalpackages/cython/install.sh	(revision 17805)
+++ /issm/trunk/externalpackages/cython/install.sh	(revision 17806)
@@ -3,11 +3,10 @@
 
 #clean up
-rm -rf Cython-0.18
+rm -rf cython
 
-#download numpy first
-$ISSM_DIR/scripts/DownloadExternalPackage.py 'http://issm.jpl.nasa.gov/files/externalpackages/Cython-0.18.tar.gz' 'cython.tar.gz'
+#download cython first
+git clone https://github.com/cython/cython.git
 
-#install numpy
-tar -zxvf cython.tar.gz
-cd Cython-0.18
+#install cython
+cd cython
 python setup.py install
Index: /issm/trunk/externalpackages/fti/Makefile
===================================================================
--- /issm/trunk/externalpackages/fti/Makefile	(revision 17806)
+++ /issm/trunk/externalpackages/fti/Makefile	(revision 17806)
@@ -0,0 +1,90 @@
+## * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+##* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+##=======================================================================
+##Copyright (C) 2010-2013 Leonardo A. BAUTISTA GOMEZ
+##This program is free software; you can redistribute it and/or modify
+##it under the terms of the GNU General Public License (GPL) as published
+##of the License, or (at your option) any later version.
+##
+##This program is distributed in the hope that it will be useful,
+##but WITHOUT ANY WARRANTY; without even the implied warranty of
+##MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+##GNU General Public License for more details.
+##
+##To read the license please visit http://www.gnu.org/copyleft/gpl.html
+##=======================================================================
+
+##=======================================================================
+##   PLEASE SET THESE VARIABLES BEFORE COMPILING
+##=======================================================================
+
+FTIPATH		= $(ISSM_DIR)/externalpackages/fti/install
+MPIPATH		= $(ISSM_DIR)/externalpackages/mpich/install
+
+##=======================================================================
+##   DIRECTORY TREE
+##=======================================================================
+
+LIB 		= lib
+OBJ		= obj
+SRC		= src
+DOC		= doc
+INC		= include
+
+##=======================================================================
+##   COMPILERS
+##=======================================================================
+
+CC 		= gcc
+MPICC 		= mpicc
+
+##=======================================================================
+##   FLAGS
+##=======================================================================
+
+FTIFLAGS	= -fPIC -g -Iinclude/ -c
+MPIFLAGS	= -I$(MPIPATH)/include -L$(MPIPATH)/lib -lmpich -lpmpich
+
+##=======================================================================
+##   TARGETS
+##=======================================================================
+
+
+OBJS		= $(OBJ)/galois.o $(OBJ)/jerasure.o $(OBJ)/dictionary.o $(OBJ)/iniparser.o \
+		$(OBJ)/recover.o $(OBJ)/tools.o $(OBJ)/checkpoint.o $(OBJ)/topo.o \
+		$(OBJ)/api.o
+
+SHARED		= libfti.so
+STATIC		= libfti.a
+
+all: 		$(SHARED) $(STATIC)
+
+doc:
+		doxygen $(DOC)/Doxyfile
+
+$(OBJ)/%.o:	$(SRC)/%.c
+		$(MPICC) $(FTIFLAGS) $< -o $@
+
+$(SHARED):	$(OBJS)
+		$(CC) $(MPIFLAGS) -shared -o $(LIB)/$(SHARED) $(OBJS) -lc
+
+$(STATIC):	$(OBJS)
+		$(AR) -cvq $(LIB)/$(STATIC) $(OBJS)
+install:
+		if [ ! -d "$(FTIPATH)/FTI" ]; then mkdir $(FTIPATH)/FTI; fi
+		if [ ! -d "$(FTIPATH)/FTI/$(LIB)" ]; then mkdir $(FTIPATH)/FTI/$(LIB); fi
+		if [ ! -d "$(FTIPATH)/FTI/$(INC)" ]; then mkdir $(FTIPATH)/FTI/$(INC); fi
+		rm -f $(FTIPATH)/FTI/$(LIB)/* $(FTIPATH)/FTI/$(INC)/*
+		cp $(INC)/* $(FTIPATH)/FTI/$(INC)/
+		cp $(LIB)/* $(FTIPATH)/FTI/$(LIB)/
+
+uninstall:
+		rm -f $(FTIPATH)/FTI/$(LIB)/* $(FTIPATH)/FTI/$(INC)/*
+		if [ -d "$(FTIPATH)/FTI/$(LIB)" ]; then rmdir $(FTIPATH)/FTI/$(LIB); fi
+		if [ -d "$(FTIPATH)/FTI/$(INC)" ]; then rmdir $(FTIPATH)/FTI/$(INC); fi
+		if [ -d "$(FTIPATH)/FTI" ]; then rmdir $(FTIPATH)/FTI; fi
+
+clean:
+		rm -f $(OBJ)/* $(LIB)/*
+
+.PHONY:		$(SHARED) $(STATIC) doc install uninstall clean
Index: /issm/trunk/externalpackages/fti/install.sh
===================================================================
--- /issm/trunk/externalpackages/fti/install.sh	(revision 17806)
+++ /issm/trunk/externalpackages/fti/install.sh	(revision 17806)
@@ -0,0 +1,24 @@
+#!/bin/bash
+set -eu
+
+#Some cleanup
+rm -rf install fti-0.9.2
+mkdir install
+
+#Download from ISSM server
+$ISSM_DIR/scripts/DownloadExternalPackage.py 'http://issm.jpl.nasa.gov/files/externalpackages/fti-0.9.2.tgz' 'fti-0.9.2.tgz'
+
+#Untar 
+tar -zxvf  fti-0.9.2.tgz
+
+#Move mpich into src directory
+mv fti/* install
+rm -rf fti
+
+#Configure mpich
+cd install
+cp ../Makefile .
+
+#Compile mpich (this new version supports parallel make)
+make
+make install 
Index: /issm/trunk/externalpackages/gdal/install-1.10-macosx64.sh
===================================================================
--- /issm/trunk/externalpackages/gdal/install-1.10-macosx64.sh	(revision 17805)
+++ /issm/trunk/externalpackages/gdal/install-1.10-macosx64.sh	(revision 17806)
@@ -25,5 +25,6 @@
 	--with-netcdf=no \
 	--with-libiconv-prefix="/usr/lib/" \
-	--without-hdf5
+	--without-hdf5 \
+	--with-expat=$ISSM_DIR/externalpackages/expat/install
 #Note:
 # look for libiconv in /usr/lib/ because there seemed to be a conflict with port's library
Index: /issm/trunk/externalpackages/gdal/install-1.6-macosx64.sh
===================================================================
--- /issm/trunk/externalpackages/gdal/install-1.6-macosx64.sh	(revision 17805)
+++ /issm/trunk/externalpackages/gdal/install-1.6-macosx64.sh	(revision 17806)
@@ -27,6 +27,7 @@
 	--with-jasper=no \
 	--without-ld-shared \
+	--without-hdf5 \
 	--with-unix-stdio-64=no \
-	--with-expat-lib=/usr/lib64/libexpat.so
+	--with-expat=$ISSM_DIR/externalpackages/expat/install
 
 #Compile and install gdal
Index: /issm/trunk/externalpackages/git/install.sh
===================================================================
--- /issm/trunk/externalpackages/git/install.sh	(revision 17805)
+++ /issm/trunk/externalpackages/git/install.sh	(revision 17806)
@@ -18,5 +18,5 @@
 #install
 cd src 
-./configure  --prefix="$ISSM_DIR/externalpackages/git/install"
+./configure  --prefix="$ISSM_DIR/externalpackages/git/install" 
 #--with-python="$ISSM_DIR/externalpackages/python/install/bin/python" #Do we really need this line?
 	
Index: /issm/trunk/externalpackages/gmsh/install.sh
===================================================================
--- /issm/trunk/externalpackages/gmsh/install.sh	(revision 17806)
+++ /issm/trunk/externalpackages/gmsh/install.sh	(revision 17806)
@@ -0,0 +1,21 @@
+#!/bin/bash
+set -eu
+
+#Some cleanup
+rm -rf install src
+mkdir install
+
+#Download latest version
+svn --username gmsh --password gmsh co https://geuz.org/svn/gmsh/trunk src
+
+#Configure
+cd install
+cmake ../src -DCMAKE_INSTALL_PREFIX="$ISSM_DIR/externalpackages/gmsh/install"
+
+#Compile and install
+if [ $# -eq 0 ]; then
+	make
+else
+	make -j $1
+fi
+make install
Index: /issm/trunk/externalpackages/modules/install-macosx64.sh
===================================================================
--- /issm/trunk/externalpackages/modules/install-macosx64.sh	(revision 17805)
+++ /issm/trunk/externalpackages/modules/install-macosx64.sh	(revision 17806)
@@ -4,36 +4,36 @@
 #Some cleanup
 rm -rf install
-rm -rf modules-3.2.9
+rm -rf modules-3.2.10
 mkdir install
 
 #Download from ISSM server
-$ISSM_DIR/scripts/DownloadExternalPackage.py 'http://issm.jpl.nasa.gov/files/externalpackages/modules-3.2.9.tar.gz' 'modules-3.2.9.tar.gz'
+$ISSM_DIR/scripts/DownloadExternalPackage.py 'http://issm.jpl.nasa.gov/files/externalpackages/modules-3.2.10.tar.gz' 'modules-3.2.10.tar.gz'
 
 #Untar 
-tar -zxvf  modules-3.2.9.tar.gz
+tar -zxvf  modules-3.2.10.tar.gz
 
 #Move modules into src directory
 
 #Configure modules
-cd modules-3.2.9
-./configure \
-	--prefix=$ISSM_DIR/externalpackages/modules/install\
-	--with-module-path=$ISSM_DIR/externalpackages/modules/install/modules/files\
-	--with-version-path=$ISSM_DIR/externalpackages/modules/install/modules/versions\
+cd modules-3.2.10
+sudo ./configure \
+	--prefix=/usr/local/modules \
 	--with-tcl-lib=$ISSM_DIR/externalpackages/tcl/install/Library/Frameworks/Tcl.framework/Versions/8.5\
 	--with-tcl-inc=$ISSM_DIR/externalpackages/tcl/install/Library/Frameworks/Tcl.framework/Versions/8.5/Headers\
-	--with-tcl-ver=8.5\
+	--with-tcl-ver=8.5 \
 	--with-tclx-lib=$ISSM_DIR/externalpackages/tclx/install/lib/tclx8.4\
     --with-tclx-inc=$ISSM_DIR/externalpackages/tclx/install/include\
-	--with-tclx-ver=8.4\
-	--with-etc-path=$ISSM_DIR/externalpackages/modules/install/modules/etc\
-	--with-skel-path=$ISSM_DIR/externalpackages/modules/install/modules/etc/skel\
+	--with-tclx-ver=8.4 \
+	--with-version-path=/usr/local/modules/versions \
+	--with-skel-path=/usr/local/modules/etc/skel \
+	--with-etc-path=/usr/local/modules/etc \
+	--with-module-path=/usr/local/modules/files \
 	--disable-dependency-tracking
 
 #Compile and install modules
 if [ $# -eq 0 ]; then
-	make
+	sudo make
 else
-	make -j $1
+	sudo make -j $1
 fi
-make install
+sudo make install
Index: /issm/trunk/externalpackages/mpich/install-2_1.5-linux64.sh
===================================================================
--- /issm/trunk/externalpackages/mpich/install-2_1.5-linux64.sh	(revision 17805)
+++ /issm/trunk/externalpackages/mpich/install-2_1.5-linux64.sh	(revision 17806)
@@ -22,5 +22,5 @@
 	--enable-shared \
 	--enable-sharedlibs=gcc \
-	--enable-f91=gfortran 
+	--enable-f91=gfortran  CC=gcc FC=gfortran
 
 #Compile mpich2 (this new version supports parallel make)
Index: /issm/trunk/externalpackages/mpich/install-3.0-macosx64.sh
===================================================================
--- /issm/trunk/externalpackages/mpich/install-3.0-macosx64.sh	(revision 17805)
+++ /issm/trunk/externalpackages/mpich/install-3.0-macosx64.sh	(revision 17806)
@@ -20,8 +20,7 @@
 ./configure \
 	--prefix="$ISSM_DIR/externalpackages/mpich/install" \
-	--enable-shared \
-	CC=llvm-gcc \
-	FC=gfortran \
-	F77=gfortran 
+	--enable-shared
+
+	#CC=llvm-gcc \
 
 #Compile mpich (this new version supports parallel make)
Index: /issm/trunk/externalpackages/nose/install-linux64-python2.sh
===================================================================
--- /issm/trunk/externalpackages/nose/install-linux64-python2.sh	(revision 17805)
+++ /issm/trunk/externalpackages/nose/install-linux64-python2.sh	(revision 17806)
@@ -2,5 +2,5 @@
 #Install Python nose module
 
-rm -rf src 
+rm -rf src  install
 
 #Download from ISSM server
@@ -13,2 +13,8 @@
 python ./setup.py build
 python ./setup.py install
+
+#to be flagged by jenkins, we create an empty install dir: 
+cd ../
+mkdir install
+touch install/emptyfile
+
Index: /issm/trunk/externalpackages/nose/install-linux64-python3.sh
===================================================================
--- /issm/trunk/externalpackages/nose/install-linux64-python3.sh	(revision 17805)
+++ /issm/trunk/externalpackages/nose/install-linux64-python3.sh	(revision 17806)
@@ -2,5 +2,5 @@
 #Install Python nose module
 
-rm -rf src 
+rm -rf src  install
 
 svn checkout http://python-nose.googlecode.com/svn/branches/py3k
@@ -10,2 +10,7 @@
 python ./setup.py build
 python ./setup.py install
+
+#to be flagged by jenkins, we create an empty install dir: 
+cd ../
+mkdir install
+touch install/emptyfile
Index: /issm/trunk/externalpackages/nose/install-macosx64-python2.sh
===================================================================
--- /issm/trunk/externalpackages/nose/install-macosx64-python2.sh	(revision 17805)
+++ /issm/trunk/externalpackages/nose/install-macosx64-python2.sh	(revision 17806)
@@ -2,5 +2,5 @@
 #Install Python nose module
 
-rm -rf src 
+rm -rf src  install
 
 #Download from ISSM server
@@ -13,2 +13,7 @@
 python ./setup.py build
 python ./setup.py install
+
+#to be flagged by jenkins, we create an empty install dir: 
+cd ../
+mkdir install
+touch install/emptyfile
Index: /issm/trunk/externalpackages/nose/install-macosx64-python3.sh
===================================================================
--- /issm/trunk/externalpackages/nose/install-macosx64-python3.sh	(revision 17805)
+++ /issm/trunk/externalpackages/nose/install-macosx64-python3.sh	(revision 17806)
@@ -2,5 +2,5 @@
 #Install Python nose module
 
-rm -rf src 
+rm -rf src  install
 
 svn checkout http://python-nose.googlecode.com/svn/branches/py3k
@@ -10,2 +10,7 @@
 python ./setup.py build
 python ./setup.py install
+
+#to be flagged by jenkins, we create an empty install dir: 
+cd ../
+mkdir install
+touch install/emptyfile
Index: /issm/trunk/externalpackages/numpy/install-linux64.sh
===================================================================
--- /issm/trunk/externalpackages/numpy/install-linux64.sh	(revision 17805)
+++ /issm/trunk/externalpackages/numpy/install-linux64.sh	(revision 17806)
@@ -1,4 +1,6 @@
 #!/bin/bash
 set -eu
+
+rm -rf install
 
 export CC="gcc -fPIC"
@@ -25,2 +27,7 @@
 python -c "import numpy; print 'Installed NumPy', numpy.__version__"
 python -c "import numpy; numpy.test()"
+
+#to be flagged by jenkins, we create an empty install dir: 
+mkdir install
+touch install/emptyfile
+
Index: /issm/trunk/externalpackages/numpy/install-macosx-lion.sh
===================================================================
--- /issm/trunk/externalpackages/numpy/install-macosx-lion.sh	(revision 17805)
+++ /issm/trunk/externalpackages/numpy/install-macosx-lion.sh	(revision 17806)
@@ -1,4 +1,6 @@
 #!/bin/bash
 set -eu
+
+rm -rf install
 
 export CC=gcc
@@ -23,2 +25,7 @@
 python -c "import numpy; print 'Installed NumPy', numpy.__version__"
 python -c "import numpy; numpy.test()"
+
+#to be flagged by jenkins, we create an empty install dir: 
+mkdir install
+touch install/emptyfile
+
Index: /issm/trunk/externalpackages/numpy/install-macosx-mlion.sh
===================================================================
--- /issm/trunk/externalpackages/numpy/install-macosx-mlion.sh	(revision 17805)
+++ /issm/trunk/externalpackages/numpy/install-macosx-mlion.sh	(revision 17806)
@@ -1,4 +1,6 @@
 #!/bin/bash
 set -eu
+
+rm -rf install
 
 export CC=gcc
@@ -23,2 +25,7 @@
 python -c "import numpy; print 'Installed NumPy', numpy.__version__"
 python -c "import numpy; numpy.test()"
+
+#to be flagged by jenkins, we create an empty install dir: 
+mkdir install
+touch install/emptyfile
+
Index: /issm/trunk/externalpackages/numpy/install-macosx-snowleopard.sh
===================================================================
--- /issm/trunk/externalpackages/numpy/install-macosx-snowleopard.sh	(revision 17805)
+++ /issm/trunk/externalpackages/numpy/install-macosx-snowleopard.sh	(revision 17806)
@@ -1,4 +1,6 @@
 #!/bin/bash
 set -eu
+
+rm -rf install
 
 # On OSX 10.6, gfortran gets installed in /usr/local/gfortran 
@@ -16,2 +18,7 @@
 python -c "import numpy; print 'Installed NumPy', numpy.__version__"
 python -c "import numpy; numpy.test()"
+
+#to be flagged by jenkins, we create an empty install dir: 
+mkdir install
+touch install/emptyfile
+
Index: /issm/trunk/externalpackages/petsc/install-3.1-win7.sh
===================================================================
--- /issm/trunk/externalpackages/petsc/install-3.1-win7.sh	(revision 17805)
+++ /issm/trunk/externalpackages/petsc/install-3.1-win7.sh	(revision 17806)
@@ -14,11 +14,14 @@
 rm -rf petsc-3.1-p7
 
+export PETSC_DIR=`cygpath -u "$ISSM_DIR/externalpackages/petsc/src"`
+export PREFIX_DIR=`cygpath -u "$ISSM_DIR/externalpackages/petsc/install"`
+
 #configure
 cd src
 ./config/configure.py  \
 	--with-parallel-no \
-	--prefix="$ISSM_DIR/externalpackages/petsc/install" \
+	--prefix=$PREFIX_DIR \
 	--PETSC_ARCH=cygwin-intel \
-	--PETSC_DIR="$ISSM_DIR/externalpackages/petsc/src" \
+	--PETSC_DIR=$PETSC_DIR \
 	--with-debugging=0 \
 	--with-mpi=0 \
Index: /issm/trunk/externalpackages/petsc/install-3.4-acenet.sh
===================================================================
--- /issm/trunk/externalpackages/petsc/install-3.4-acenet.sh	(revision 17806)
+++ /issm/trunk/externalpackages/petsc/install-3.4-acenet.sh	(revision 17806)
@@ -0,0 +1,33 @@
+#!/bin/bash
+set -eu
+
+#Some cleanup
+rm -rf install petsc-3.4.3 src
+mkdir install src
+
+#Download from ISSM server
+$ISSM_DIR/scripts/DownloadExternalPackage.py 'http://issm.jpl.nasa.gov/files/externalpackages/petsc-lite-3.4.3.tar.gz' 'petsc-3.4.3.tar.gz'
+
+#Untar and move petsc to install directory
+tar -zxvf  petsc-3.4.3.tar.gz
+mv petsc-3.4.3/* src/
+rm -rf petsc-3.4.3
+
+#configure
+cd src
+./config/configure.py \
+ --prefix="$ISSM_DIR/externalpackages/petsc/install" \
+ --PETSC_ARCH="linux-gnu-amd64" \
+ --PETSC_DIR="$ISSM_DIR/externalpackages/petsc/src" \
+ --with-debugging=0 \
+ --with-shared-libraries=1 \
+ --known-mpi-shared-libraries=1 \
+ --with-mpi-dir=$OPENMPI \
+ --with-blas-lapack-dir=/usr/local/intel/composer_xe_2011_sp1.13.367/mkl/ \
+ --download-scalapack=yes \
+ --download-mumps=yes \
+ --download-metis=yes \
+ --download-parmetis=yes 
+
+make
+make install
Index: /issm/trunk/externalpackages/petsc/install-3.4-pleiades-intel2012.0.032-mpt.2.06rp16
===================================================================
--- /issm/trunk/externalpackages/petsc/install-3.4-pleiades-intel2012.0.032-mpt.2.06rp16	(revision 17806)
+++ /issm/trunk/externalpackages/petsc/install-3.4-pleiades-intel2012.0.032-mpt.2.06rp16	(revision 17806)
@@ -0,0 +1,61 @@
+#!/bin/bash
+
+#Some cleanup
+rm -rf install petsc-3.4.2 src
+mkdir install src
+
+#Download from ISSM server
+$ISSM_DIR/scripts/DownloadExternalPackage.py 'http://issm.jpl.nasa.gov/files/externalpackages/petsc-lite-3.4.2.tar.gz' 'petsc-3.4.2.tar.gz'
+
+#Untar and move petsc to install directory
+tar -zxvf  petsc-3.4.2.tar.gz
+mv petsc-3.4.2/* src/
+rm -rf petsc-3.4.2
+
+#configure
+cd src
+./config/configure.py \
+ --prefix="$ISSM_DIR/externalpackages/petsc/install" \
+ --PETSC_ARCH="$ISSM_ARCH" \
+ --PETSC_DIR="$ISSM_DIR/externalpackages/petsc/src" \
+ --with-batch=1  \
+ --with-debugging=0 \
+ --with-shared-libraries=1 \
+ --known-mpi-shared-libraries=1 \
+ --with-mpi=1 \
+ --with-mpi-lib="/nasa/sgi/mpt/2.06rp16/lib/libmpi.so" \
+ --with-mpi-include="/nasa/sgi/mpt/2.06rp16/include" \
+ --with-blas-lapack-dir="/nasa/intel/Compiler/2012.0.032/composer_xe_2011_sp1/mkl/lib/intel64" \
+ --download-scalapack=yes \
+ --download-blacs=yes \
+ --download-mumps=yes \
+ --download-metis=yes \
+ --download-parmetis=yes \
+ --download-trilinos=yes \
+ --download-euclid=yes \
+ --download-hypre=yes \
+ --COPTFLAGS="-lmpi -O3" \
+ --FOPTFLAGS="-lmpi -O3" \
+ --CXXOPTFLAGS="-lmpi -O3"
+
+#prepare script to reconfigure petsc
+cat > script.queue << EOF
+#PBS -S /bin/bash
+#PBS -l select=1:ncpus=1:model=wes 
+#PBS -l walltime=200 
+#PBS -W group_list=s1010
+#PBS -m e 
+
+. /usr/share/modules/init/bash 
+module load comp-intel/2012.0.032
+module load mpi-sgi/mpt.2.06rp16
+
+export PATH="$PATH:." 
+export MPI_GROUP_MAX=64 
+mpiexec -np 1 ./conftest-linux-gnu-ia64-intel.py
+EOF
+
+#print instructions
+echo "== Now: cd src/ "
+echo "== qsub -q devel script.queue "
+echo "== Then run reconfigure script generated by PETSc and follow instructions"
Index: /issm/trunk/externalpackages/petsc/install-3.4-pleiades-mpich2.sh
===================================================================
--- /issm/trunk/externalpackages/petsc/install-3.4-pleiades-mpich2.sh	(revision 17806)
+++ /issm/trunk/externalpackages/petsc/install-3.4-pleiades-mpich2.sh	(revision 17806)
@@ -0,0 +1,68 @@
+#!/bin/bash
+
+#Some cleanup
+rm -rf install petsc-3.4.2 src
+mkdir install src
+
+export cc=gcc
+alias cc='gcc'
+
+#Download from ISSM server
+$ISSM_DIR/scripts/DownloadExternalPackage.py 'http://issm.jpl.nasa.gov/files/externalpackages/petsc-lite-3.4.2.tar.gz' 'petsc-3.4.2.tar.gz'
+
+#Untar and move petsc to install directory
+tar -zxvf  petsc-3.4.2.tar.gz
+mv petsc-3.4.2/* src/
+rm -rf petsc-3.4.2
+
+#configure
+cd src
+./config/configure.py \
+ --prefix="$ISSM_DIR/externalpackages/petsc/install" \
+ --PETSC_ARCH="$ISSM_ARCH" \
+ --PETSC_DIR="$ISSM_DIR/externalpackages/petsc/src" \
+ --with-batch=1  \
+ --with-debugging=0 \
+ --with-shared-libraries=1 \
+ --with-mpi=1 \
+ --with-mpi-lib="$ISSM_DIR/externalpackages/mpich/install/lib/libmpich.so"\
+ --with-mpi-include="$ISSM_DIR/externalpackages/mpich/install/include" \
+  --known-mpi-shared-libraries=1 \
+  --download-f-blas-lapack=yes \
+ --download-scalapack=yes \
+ --download-metis=yes \
+ --download-parmetis=yes \
+ --download-blacs=yes \
+ --download-mumps=yes \
+  --download-trilinos=yes \
+ --download-euclid=yes \
+ --download-hypre=yes  \
+ --COPTFLAGS=" -O3 -march=corei7-avx" \
+ --FOPTFLAGS=" -O3 -march=corei7-avx" \
+ --CXXOPTFLAGS=" -O3 -march=corei7-avx" 
+
+#--with-mpi-lib="/nasa/mvapich2/1.4.1/gcc.sles11/lib/libmpich.a" \
+# --with-mpi-include="/nasa/mvapich2/1.4.1/gcc.sles11/include" \
+
+
+#prepare script to reconfigure petsc
+cat > script.queue << EOF
+#PBS -S /bin/bash
+#PBS -l select=1:ncpus=1:model=wes 
+#PBS -l walltime=200 
+#PBS -W group_list=s1010
+#PBS -m e 
+
+. /usr/share/modules/init/bash 
+module load mpi-mvapich2/1.6/gcc
+module load gcc/4.7.0
+
+export PATH="$PATH:." 
+export MPI_GROUP_MAX=64 
+mpiexec -np 1 ./conftest-linux-gnu-ia64-intel.py
+EOF
+
+#print instructions
+echo "== Now: cd src/ "
+echo "== qsub -q devel script.queue "
+echo "== Then run reconfigure script generated by PETSc and follow instructions"
Index: /issm/trunk/externalpackages/petsc/install-3.4-pleiades2.sh
===================================================================
--- /issm/trunk/externalpackages/petsc/install-3.4-pleiades2.sh	(revision 17806)
+++ /issm/trunk/externalpackages/petsc/install-3.4-pleiades2.sh	(revision 17806)
@@ -0,0 +1,61 @@
+#!/bin/bash
+
+#Some cleanup
+rm -rf install petsc-3.4.3 src
+mkdir install src
+
+#Download from ISSM server
+$ISSM_DIR/scripts/DownloadExternalPackage.py 'http://issm.jpl.nasa.gov/files/externalpackages/petsc-lite-3.4.3.tar.gz' 'petsc-3.4.3.tar.gz'
+
+#Untar and move petsc to install directory
+tar -zxvf  petsc-3.4.3.tar.gz
+mv petsc-3.4.3/* src/
+rm -rf petsc-3.4.3
+
+#configure
+cd src
+./config/configure.py \
+ --prefix="$ISSM_DIR/externalpackages/petsc/install" \
+ --PETSC_ARCH="$ISSM_ARCH" \
+ --PETSC_DIR="$ISSM_DIR/externalpackages/petsc/src" \
+ --with-batch=1  \
+ --with-debugging=0 \
+ --with-shared-libraries=1 \
+ --known-mpi-shared-libraries=1 \
+ --with-mpi=1 \
+ --with-mpi-lib="/nasa/sgi/mpt/2.06rp16/lib/libmpi.so" \
+ --with-mpi-include="/nasa/sgi/mpt/2.06rp16/include" \
+ --with-blas-lapack-dir="/nasa/intel/Compiler/2013.1.117/composer_xe_2013.1.117/mkl/lib/intel64" \
+ --download-scalapack=yes \
+ --download-blacs=yes \
+ --download-mumps=yes \
+ --download-metis=yes \
+ --download-parmetis=yes \
+ --download-trilinos=yes \
+ --download-euclid=yes \
+ --download-hypre=yes \
+ --COPTFLAGS="-lmpi -O3" \
+ --FOPTFLAGS="-lmpi -O3" \
+ --CXXOPTFLAGS="-lmpi -O3"
+
+#prepare script to reconfigure petsc
+cat > script.queue << EOF
+#PBS -S /bin/bash
+#PBS -l select=1:ncpus=1:model=wes 
+#PBS -l walltime=200 
+#PBS -W group_list=s1010
+#PBS -m e 
+
+. /usr/share/modules/init/bash 
+module load comp-intel/2013.1.117
+module load mpi-sgi/mpt.2.06rp16
+
+export PATH="$PATH:." 
+export MPI_GROUP_MAX=64 
+mpiexec -np 1 ./conftest-linux-gnu-ia64-intel.py
+EOF
+
+#print instructions
+echo "== Now: cd src/ "
+echo "== qsub -q devel script.queue "
+echo "== Then run reconfigure script generated by PETSc and follow instructions"
Index: /issm/trunk/externalpackages/scipy/install-linux64.sh
===================================================================
--- /issm/trunk/externalpackages/scipy/install-linux64.sh	(revision 17805)
+++ /issm/trunk/externalpackages/scipy/install-linux64.sh	(revision 17806)
@@ -10,5 +10,4 @@
 #clean up
 rm -rf scipy
-
 #download scipy
 export GIT_SSL_NO_VERIFY=true 
Index: /issm/trunk/externalpackages/shell2junit/README
===================================================================
--- /issm/trunk/externalpackages/shell2junit/README	(revision 17806)
+++ /issm/trunk/externalpackages/shell2junit/README	(revision 17806)
@@ -0,0 +1,9 @@
+http://code.google.com/p/shell2junit/
+
+Shell2junit
+
+Shell2junit is a simple utility which facilitates to generate junit reports for batch processes executed in shell scripts. 
+
+The reports can be easily parsed in Hudson and other CI software in order to monitor and generate trends and alerts. 
+
+This page teaches how to do it in Hudson. 
Index: /issm/trunk/externalpackages/shell2junit/install.sh
===================================================================
--- /issm/trunk/externalpackages/shell2junit/install.sh	(revision 17806)
+++ /issm/trunk/externalpackages/shell2junit/install.sh	(revision 17806)
@@ -0,0 +1,9 @@
+#!/bin/bash
+set -eu
+
+
+#Some cleanup
+rm -rf install 
+mkdir install 
+
+cp patch/sh2ju.sh install/
Index: /issm/trunk/externalpackages/shell2junit/install.sh.old
===================================================================
--- /issm/trunk/externalpackages/shell2junit/install.sh.old	(revision 17806)
+++ /issm/trunk/externalpackages/shell2junit/install.sh.old	(revision 17806)
@@ -0,0 +1,20 @@
+#!/bin/bash
+set -eu
+
+#Some cleanup
+rm -rf install src
+rm -rf shell2junit
+mkdir install src
+
+#Download from ISSM server
+$ISSM_DIR/scripts/DownloadExternalPackage.py 'http://issm.jpl.nasa.gov/files/externalpackages/shell2junit-1.0.0.zip' 'shell2junit-1.0.0.zip'
+
+#Untar 
+unzip shell2junit-1.0.0.zip
+
+#Move shell2junit into install directory
+mv shell2junit/* src
+rm -rf shell2junit
+
+#Copy executable: 
+cp src/sh2ju.sh install
Index: /issm/trunk/externalpackages/shell2junit/patch/sh2ju.sh
===================================================================
--- /issm/trunk/externalpackages/shell2junit/patch/sh2ju.sh	(revision 17806)
+++ /issm/trunk/externalpackages/shell2junit/patch/sh2ju.sh	(revision 17806)
@@ -0,0 +1,131 @@
+#!/bin/sh
+### Copyright 2010 Manuel Carrasco Moñino. (manolo at apache.org) 
+###
+### Licensed under the Apache License, Version 2.0.
+### You may obtain a copy of it at
+### http://www.apache.org/licenses/LICENSE-2.0
+
+###
+### A library for shell scripts which creates reports in jUnit format.
+### These reports can be used in Hudson, or any other CI.
+###
+### Usage: 
+###     - Include this file in your shell script
+###     - Use juLog to call your command any time you want to produce a new report
+###        Usage:   juLog <options> command arguments
+###           options:
+###             -name="TestName" : the test name which will be shown in the junit report
+###             -error="RegExp"  : a regexp which sets the test as failure when the output matches it
+###             -ierror="RegExp" : same as -error but case insensitive
+###     - Junit reports are left in the folder 'result' under the directory where the script is executed.
+###     - Configure hudson to parse junit files from the generated folder
+###
+
+asserts=00; errors=0; total=0; content=""
+
+# create output folder
+juDIR=`pwd`/results
+mkdir -p $juDIR || exit
+
+# The name of the suite is calculated based in your script name
+suite=`basename $0 | sed -e 's/.sh$//' | tr "." "_"`
+
+# A wrapper for the eval method witch allows catching seg-faults and use tee
+errfile=/tmp/evErr.$$.log
+eVal() {
+  eval "$1"
+  echo $? | tr -d "\n" >$errfile
+}
+
+# Method to clean old tests
+juLogClean() {
+  echo "+++ Removing old junit reports from: $juDIR "
+  rm -f $juDIR/TEST-*	
+}
+
+# Execute a command and record its results 
+juLog() {
+  
+  # parse arguments
+  ya=""; icase=""; testname="";
+  while [ -z "$ya" ]; do  
+    case "$1" in
+  	  -name=*)   name=$asserts-`echo "$1" | sed -e 's/-name=//'`;   shift;;
+      -ierror=*) ereg=`echo "$1" | sed -e 's/-ierror=//'`; icase="-i"; shift;;
+      -error=*)  ereg=`echo "$1" | sed -e 's/-error=//'`;  shift;;
+      -test=*)  testname=`echo "$1" | sed -e 's/-test=//'`;  shift;;
+      *)         ya=1;;
+    esac
+  done  
+
+  # use first arg as name if it was not given 
+  if [ -z "$name" ]; then
+    name="$asserts-$1" 
+    shift
+  fi
+
+  # calculate command to eval
+  [ -z "$1" ] && return
+  cmd="$1"; shift
+  while [ -n "$1" ]
+  do
+     cmd="$cmd \"$1\""
+     shift
+  done
+
+  # eval the command sending output to a file
+  outf=/var/tmp/ju$$.txt
+  >$outf
+  echo ""                         | tee -a $outf
+  echo "+++ Running case: $testname " | tee -a $outf
+  echo "+++ working dir: "`pwd`           | tee -a $outf
+  #echo "+++ command: $cmd"            | tee -a $outf
+  ini=`date +%s`
+  eVal "$cmd" 2>&1                | tee -a $outf
+  evErr=`cat $errfile`
+  rm -f $errfile
+  end=`date +%s`
+  echo "+++ exit code: $evErr"        | tee -a $outf
+  
+  # set the appropriate error, based in the exit code and the regex  
+  [ $evErr != 0 ] && err=1 || err=0
+  out=`cat $outf | sed -e 's/^\([^+]\)/| \1/g'`
+  if [ $err = 0 -a -n "$ereg" ]; then
+      H=`echo "$out" | egrep $icase "$ereg"`
+      [ -n "$H" ] && err=1
+  fi
+  echo "+++ error: $err"         | tee -a $outf
+  rm -f $outf
+
+  # calculate vars
+  asserts=`expr $asserts + 1`
+  asserts=`printf "%.2d" $asserts`
+  errors=`expr $errors + $err`
+  time=`expr $end - $ini`
+  total=`expr $total + $time`
+
+  # write the junit xml report
+  ## failure tag
+  [ $err = 0 ] && failure="" || failure="
+      <failure type=\"ScriptError\" message=\"Script Error\"></failure>
+  "
+  ## testcase tag
+  content="$content
+    <testcase assertions=\"1\" name=\"$testname $ereg\" time=\"$time\">
+    $failure
+    <system-out>
+<![CDATA[
+$out
+]]>
+    </system-out>
+    </testcase>
+  "
+  ## testsuite block
+  cat <<EOF >$juDIR/TEST-$suite.xml
+  <testsuite failures="0" assertions="$assertions" name="ISSM Test Suite" tests="1" errors="$errors" time="$total">
+    $content
+  </testsuite>
+EOF
+
+}
+
Index: /issm/trunk/externalpackages/tao/install-2.2.sh
===================================================================
--- /issm/trunk/externalpackages/tao/install-2.2.sh	(revision 17805)
+++ /issm/trunk/externalpackages/tao/install-2.2.sh	(revision 17806)
@@ -1,21 +1,21 @@
 #!/bin/bash
 set -eu
-#http://www.mcs.anl.gov/research/projects/tao/download/tao-2.2-pre1.tar.gz
+#http://www.mcs.anl.gov/research/projects/tao/download/tao-2.2.2.tar.gz
 
 #compatible with PETSc 3.4
 
 #Some cleanup
-rm -rf install tao-2.2-pre1
+rm -rf install tao-2.2.2
 mkdir install
 
 #Download from ISSM server
-$ISSM_DIR/scripts/DownloadExternalPackage.py 'http://issm.jpl.nasa.gov/files/externalpackages/tao-2.2-pre1.tar.gz' 'tao-2.2-pre1.tar.gz'
+$ISSM_DIR/scripts/DownloadExternalPackage.py 'http://issm.jpl.nasa.gov/files/externalpackages/tao-2.2.2.tar.gz' 'tao-2.2.2.tar.gz'
 
 #Untar 
-tar -zxvf  tao-2.2-pre1.tar.gz
+tar -zxvf  tao-2.2.2.tar.gz
 
 #move into place
-mv tao-2.2-pre1/* install/
-rm -rf tao-2.2-pre1
+mv tao-2.2.2/* install/
+rm -rf tao-2.2.2
 
 #compile
Index: /issm/trunk/externalpackages/vim/addons/vim/syntax/c.vim
===================================================================
--- /issm/trunk/externalpackages/vim/addons/vim/syntax/c.vim	(revision 17805)
+++ /issm/trunk/externalpackages/vim/addons/vim/syntax/c.vim	(revision 17806)
@@ -412,4 +412,5 @@
 syn keyword cType BoolInput
 syn keyword cType BoolParam
+syn keyword cType classes
 syn keyword cType Constraint
 syn keyword cType Constraints
@@ -417,6 +418,6 @@
 syn keyword cType Contours
 syn keyword cType ControlInput
+syn keyword cType DatasetInput
 syn keyword cType DataSetParam
-syn keyword cType DatasetInput
 syn keyword cType Definition
 syn keyword cType DependentObject
@@ -431,6 +432,6 @@
 syn keyword cType ElementHook
 syn keyword cType ElementMatrix
+syn keyword cType Elements
 syn keyword cType ElementVector
-syn keyword cType Elements
 syn keyword cType ExponentialVariogram
 syn keyword cType ExternalResult
@@ -438,8 +439,11 @@
 syn keyword cType FileParam
 syn keyword cType Friction
+syn keyword cType Gauss
+syn keyword cType GaussianVariogram
+syn keyword cType gaussobjects
 syn keyword cType GaussPenta
 syn keyword cType GaussSeg
+syn keyword cType GaussTetra
 syn keyword cType GaussTria
-syn keyword cType GaussianVariogram
 syn keyword cType GenericExternalResult
 syn keyword cType GenericOption
@@ -455,4 +459,5 @@
 syn keyword cType IntVecParam
 syn keyword cType IoModel
+syn keyword cType krigingobjects
 syn keyword cType Load
 syn keyword cType Loads
@@ -462,5 +467,7 @@
 syn keyword cType Matice
 syn keyword cType Matpar
+syn keyword cType matrixobjects
 syn keyword cType MatrixParam
+syn keyword cType Misfit
 syn keyword cType Node
 syn keyword cType Nodes
@@ -469,6 +476,6 @@
 syn keyword cType Observations
 syn keyword cType Option
+syn keyword cType Options
 syn keyword cType OptionUtilities
-syn keyword cType Options
 syn keyword cType Param
 syn keyword cType Parameters
@@ -482,10 +489,10 @@
 syn keyword cType Quadtree
 syn keyword cType Results
+syn keyword cType Riftfront
 syn keyword cType RiftStruct
-syn keyword cType Riftfront
 syn keyword cType Seg
 syn keyword cType SegInput
+syn keyword cType Segment
 syn keyword cType SegRef
-syn keyword cType Segment
 syn keyword cType SpcDynamic
 syn keyword cType SpcStatic
@@ -494,4 +501,7 @@
 syn keyword cType StringArrayParam
 syn keyword cType StringParam
+syn keyword cType Tetra
+syn keyword cType TetraInput
+syn keyword cType TetraRef
 syn keyword cType TransientInput
 syn keyword cType TransientParam
@@ -504,8 +514,4 @@
 syn keyword cType Vertex
 syn keyword cType Vertices
-syn keyword cType classes
-syn keyword cType gaussobjects
-syn keyword cType krigingobjects
-syn keyword cType matrixobjects
 syn keyword cType AdjointBalancethicknessAnalysis
 syn keyword cType AdjointHorizAnalysis
@@ -515,6 +521,8 @@
 syn keyword cType BalancevelocityAnalysis
 syn keyword cType DamageEvolutionAnalysis
+syn keyword cType DepthAverageAnalysis
 syn keyword cType EnthalpyAnalysis
 syn keyword cType EnumToAnalysis
+syn keyword cType ExtrapolationAnalysis
 syn keyword cType ExtrudeFromBaseAnalysis
 syn keyword cType ExtrudeFromTopAnalysis
@@ -526,4 +534,7 @@
 syn keyword cType HydrologyShreveAnalysis
 syn keyword cType L2ProjectionBaseAnalysis
+syn keyword cType L2ProjectionEPLAnalysis
+syn keyword cType LevelsetAnalysis
+syn keyword cType LsfReinitializationAnalysis
 syn keyword cType MasstransportAnalysis
 syn keyword cType MeltingAnalysis
@@ -569,6 +580,6 @@
 syn keyword cConstant BasalforcingsMeltingRateCorrectionEnum
 syn keyword cConstant BasalforcingsMeltingRateEnum
-syn keyword cConstant BathymetryEnum
 syn keyword cConstant BedEnum
+syn keyword cConstant BaseEnum
 syn keyword cConstant ConstantsGEnum
 syn keyword cConstant ConstantsReferencetemperatureEnum
@@ -628,4 +639,7 @@
 syn keyword cConstant EplHeadEnum
 syn keyword cConstant EplHeadOldEnum
+syn keyword cConstant EplHeadSlopeXEnum
+syn keyword cConstant EplHeadSlopeYEnum
+syn keyword cConstant HydrologydcMaxIterEnum
 syn keyword cConstant HydrologydcRelTolEnum
 syn keyword cConstant HydrologydcSpcsedimentHeadEnum
@@ -636,9 +650,12 @@
 syn keyword cConstant HydrologydcWaterCompressibilityEnum
 syn keyword cConstant HydrologydcSpceplHeadEnum
-syn keyword cConstant HydrologydcMaskEplactiveEnum
+syn keyword cConstant HydrologydcMaskEplactiveNodeEnum
+syn keyword cConstant HydrologydcMaskEplactiveEltEnum
 syn keyword cConstant HydrologydcEplCompressibilityEnum
 syn keyword cConstant HydrologydcEplPorosityEnum
+syn keyword cConstant HydrologydcEplInitialThicknessEnum
 syn keyword cConstant HydrologydcEplThicknessEnum
-syn keyword cConstant HydrologydcEplTransmitivityEnum
+syn keyword cConstant HydrologydcEplThicknessOldEnum
+syn keyword cConstant HydrologydcEplConductivityEnum
 syn keyword cConstant HydrologydcIsefficientlayerEnum
 syn keyword cConstant HydrologydcSedimentlimitFlagEnum
@@ -647,9 +664,10 @@
 syn keyword cConstant HydrologydcLeakageFactorEnum
 syn keyword cConstant HydrologydcPenaltyFactorEnum
+syn keyword cConstant HydrologydcPenaltyLockEnum
+syn keyword cConstant HydrologydcBasalMoulinInputEnum
 syn keyword cConstant HydrologyLayerEnum
 syn keyword cConstant HydrologySedimentEnum
 syn keyword cConstant HydrologyEfficientEnum
 syn keyword cConstant HydrologySedimentKmaxEnum
-syn keyword cConstant WaterTransferEnum
 syn keyword cConstant IndependentObjectEnum
 syn keyword cConstant InversionControlParametersEnum
@@ -684,4 +702,5 @@
 syn keyword cConstant MaterialsRheologyNEnum
 syn keyword cConstant DamageDEnum
+syn keyword cConstant DamageFEnum
 syn keyword cConstant QmuDamageDEnum
 syn keyword cConstant DamageDbarEnum
@@ -700,4 +719,7 @@
 syn keyword cConstant DamageSpcdamageEnum
 syn keyword cConstant DamageMaxDamageEnum
+syn keyword cConstant DamageEquivStressEnum
+syn keyword cConstant DamageEvolutionNumRequestedOutputsEnum
+syn keyword cConstant DamageEvolutionRequestedOutputsEnum
 syn keyword cConstant MaterialsRhoIceEnum
 syn keyword cConstant MaterialsRhoWaterEnum
@@ -706,4 +728,5 @@
 syn keyword cConstant MaterialsThermalExchangeVelocityEnum
 syn keyword cConstant MaterialsThermalconductivityEnum
+syn keyword cConstant MaterialsTemperateiceconductivityEnum
 syn keyword cConstant MaterialsLithosphereShearModulusEnum
 syn keyword cConstant MaterialsLithosphereDensityEnum
@@ -711,5 +734,5 @@
 syn keyword cConstant MaterialsMantleDensityEnum
 syn keyword cConstant MeshAverageVertexConnectivityEnum
-syn keyword cConstant MeshElementonbedEnum
+syn keyword cConstant MeshElementonbaseEnum
 syn keyword cConstant MeshElementonsurfaceEnum
 syn keyword cConstant MeshElements2dEnum
@@ -722,13 +745,15 @@
 syn keyword cConstant MeshNumberofverticesEnum
 syn keyword cConstant MeshUpperelementsEnum
-syn keyword cConstant MeshVertexonbedEnum
+syn keyword cConstant MeshVertexonbaseEnum
 syn keyword cConstant MeshVertexonsurfaceEnum
 syn keyword cConstant MeshXEnum
 syn keyword cConstant MeshYEnum
 syn keyword cConstant MeshZEnum
-syn keyword cConstant MeshTypeEnum
-syn keyword cConstant Mesh2DhorizontalEnum
-syn keyword cConstant Mesh2DverticalEnum
-syn keyword cConstant Mesh3DEnum
+syn keyword cConstant MeshElementtypeEnum
+syn keyword cConstant DomainTypeEnum
+syn keyword cConstant DomainDimensionEnum
+syn keyword cConstant Domain2DhorizontalEnum
+syn keyword cConstant Domain2DverticalEnum
+syn keyword cConstant Domain3DEnum
 syn keyword cConstant MiscellaneousNameEnum
 syn keyword cConstant MasstransportHydrostaticAdjustmentEnum
@@ -737,4 +762,5 @@
 syn keyword cConstant MasstransportPenaltyFactorEnum
 syn keyword cConstant MasstransportSpcthicknessEnum
+syn keyword cConstant MasstransportCalvingrateEnum
 syn keyword cConstant MasstransportStabilizationEnum
 syn keyword cConstant MasstransportVertexPairingEnum
@@ -753,14 +779,9 @@
 syn keyword cConstant RiftsNumriftsEnum
 syn keyword cConstant RiftsRiftstructEnum
+syn keyword cConstant SettingsResultsOnNodesEnum
 syn keyword cConstant SettingsIoGatherEnum
 syn keyword cConstant SettingsLowmemEnum
 syn keyword cConstant SettingsOutputFrequencyEnum
 syn keyword cConstant SettingsWaitonlockEnum
-syn keyword cConstant SurfaceforcingsDelta18oEnum
-syn keyword cConstant SurfaceforcingsDelta18oSurfaceEnum
-syn keyword cConstant SurfaceforcingsIsdelta18oEnum
-syn keyword cConstant SurfaceforcingsPrecipitationsPresentdayEnum
-syn keyword cConstant SurfaceforcingsTemperaturesPresentdayEnum
-syn keyword cConstant SurfaceforcingsTemperaturesLgmEnum
 syn keyword cConstant DebugProfilingEnum
 syn keyword cConstant ProfilingCurrentMemEnum
@@ -773,15 +794,4 @@
 syn keyword cConstant SteadystateRequestedOutputsEnum
 syn keyword cConstant SurfaceEnum
-syn keyword cConstant SurfaceforcingsPrecipitationEnum
-syn keyword cConstant SurfaceforcingsMassBalanceEnum
-syn keyword cConstant SurfaceforcingsIspddEnum
-syn keyword cConstant SurfaceforcingsDesfacEnum
-syn keyword cConstant SurfaceforcingsS0pEnum
-syn keyword cConstant SurfaceforcingsIssmbgradientsEnum
-syn keyword cConstant SurfaceforcingsMonthlytemperaturesEnum
-syn keyword cConstant SurfaceforcingsHrefEnum
-syn keyword cConstant SurfaceforcingsSmbrefEnum
-syn keyword cConstant SurfaceforcingsBPosEnum
-syn keyword cConstant SurfaceforcingsBNegEnum
 syn keyword cConstant ThermalIsenthalpyEnum
 syn keyword cConstant ThermalIsdynamicbasalspcEnum
@@ -807,7 +817,29 @@
 syn keyword cConstant TransientIsthermalEnum
 syn keyword cConstant TransientIsgiaEnum
-syn keyword cConstant TransientIsdamageEnum
+syn keyword cConstant TransientIsdamageevolutionEnum
 syn keyword cConstant TransientNumRequestedOutputsEnum
 syn keyword cConstant TransientRequestedOutputsEnum
+syn keyword cConstant SurfaceforcingsEnum
+syn keyword cConstant SMBEnum
+syn keyword cConstant SurfaceforcingsMassBalanceEnum
+syn keyword cConstant SMBpddEnum
+syn keyword cConstant SurfaceforcingsDelta18oEnum
+syn keyword cConstant SurfaceforcingsDelta18oSurfaceEnum
+syn keyword cConstant SurfaceforcingsIsdelta18oEnum
+syn keyword cConstant SurfaceforcingsPrecipitationsPresentdayEnum
+syn keyword cConstant SurfaceforcingsTemperaturesPresentdayEnum
+syn keyword cConstant SurfaceforcingsTemperaturesLgmEnum
+syn keyword cConstant SurfaceforcingsPrecipitationEnum
+syn keyword cConstant SurfaceforcingsDesfacEnum
+syn keyword cConstant SurfaceforcingsS0pEnum
+syn keyword cConstant SMBgradientsEnum
+syn keyword cConstant SurfaceforcingsMonthlytemperaturesEnum
+syn keyword cConstant SurfaceforcingsHrefEnum
+syn keyword cConstant SurfaceforcingsSmbrefEnum
+syn keyword cConstant SurfaceforcingsBPosEnum
+syn keyword cConstant SurfaceforcingsBNegEnum
+syn keyword cConstant SMBhenningEnum
+syn keyword cConstant SurfaceforcingsIspddEnum
+syn keyword cConstant SurfaceforcingsIssmbgradientsEnum
 syn keyword cConstant SolutionTypeEnum
 syn keyword cConstant AnalysisTypeEnum
@@ -823,4 +855,5 @@
 syn keyword cConstant BalancevelocityAnalysisEnum
 syn keyword cConstant BalancevelocitySolutionEnum
+syn keyword cConstant L2ProjectionEPLAnalysisEnum
 syn keyword cConstant L2ProjectionBaseAnalysisEnum
 syn keyword cConstant BedSlopeSolutionEnum
@@ -843,8 +876,9 @@
 syn keyword cConstant FreeSurfaceBaseAnalysisEnum
 syn keyword cConstant FreeSurfaceTopAnalysisEnum
+syn keyword cConstant SurfaceNormalVelocityEnum
 syn keyword cConstant ExtrudeFromBaseAnalysisEnum
 syn keyword cConstant ExtrudeFromTopAnalysisEnum
+syn keyword cConstant DepthAverageAnalysisEnum
 syn keyword cConstant SteadystateSolutionEnum
-syn keyword cConstant L2ProjectionTopAnalysisEnum
 syn keyword cConstant SurfaceSlopeSolutionEnum
 syn keyword cConstant SmoothedSurfaceSlopeXAnalysisEnum
@@ -857,4 +891,7 @@
 syn keyword cConstant MeshdeformationSolutionEnum
 syn keyword cConstant MeshdeformationAnalysisEnum
+syn keyword cConstant LevelsetAnalysisEnum
+syn keyword cConstant ExtrapolationAnalysisEnum
+syn keyword cConstant LsfReinitializationAnalysisEnum
 syn keyword cConstant ApproximationEnum
 syn keyword cConstant NoneApproximationEnum
@@ -897,4 +934,5 @@
 syn keyword cConstant InputToExtrudeEnum
 syn keyword cConstant InputToL2ProjectEnum
+syn keyword cConstant InputToDepthaverageEnum
 syn keyword cConstant IntParamEnum
 syn keyword cConstant IntVecParamEnum
@@ -908,6 +946,4 @@
 syn keyword cConstant PengridEnum
 syn keyword cConstant PenpairEnum
-syn keyword cConstant PentaEnum
-syn keyword cConstant PentaInputEnum
 syn keyword cConstant ProfilerEnum
 syn keyword cConstant MatrixParamEnum
@@ -927,4 +963,8 @@
 syn keyword cConstant TriaEnum
 syn keyword cConstant TriaInputEnum
+syn keyword cConstant TetraEnum
+syn keyword cConstant TetraInputEnum
+syn keyword cConstant PentaEnum
+syn keyword cConstant PentaInputEnum
 syn keyword cConstant VertexEnum
 syn keyword cConstant VertexPIdEnum
@@ -961,5 +1001,5 @@
 syn keyword cConstant QmuVzEnum
 syn keyword cConstant QmuThicknessEnum
-syn keyword cConstant QmuBedEnum
+syn keyword cConstant QmuBaseEnum
 syn keyword cConstant QmuSurfaceEnum
 syn keyword cConstant QmuMeltingEnum
@@ -1020,4 +1060,19 @@
 syn keyword cConstant StressTensoryzEnum
 syn keyword cConstant StressTensorzzEnum
+syn keyword cConstant DeviatoricStressEnum
+syn keyword cConstant DeviatoricStressxxEnum
+syn keyword cConstant DeviatoricStressxyEnum
+syn keyword cConstant DeviatoricStressxzEnum
+syn keyword cConstant DeviatoricStressyyEnum
+syn keyword cConstant DeviatoricStressyzEnum
+syn keyword cConstant DeviatoricStresszzEnum
+syn keyword cConstant StrainRateEnum
+syn keyword cConstant StrainRatexxEnum
+syn keyword cConstant StrainRatexyEnum
+syn keyword cConstant StrainRatexzEnum
+syn keyword cConstant StrainRateyyEnum
+syn keyword cConstant StrainRateyzEnum
+syn keyword cConstant StrainRatezzEnum
+syn keyword cConstant DivergenceEnum
 syn keyword cConstant GiaCrossSectionShapeEnum
 syn keyword cConstant GiadWdtEnum
@@ -1031,4 +1086,6 @@
 syn keyword cConstant P2xP1Enum
 syn keyword cConstant P1xP2Enum
+syn keyword cConstant P1xP3Enum
+syn keyword cConstant P2xP4Enum
 syn keyword cConstant P1P1Enum
 syn keyword cConstant P1P1GLSEnum
@@ -1036,4 +1093,6 @@
 syn keyword cConstant MINIcondensedEnum
 syn keyword cConstant TaylorHoodEnum
+syn keyword cConstant XTaylorHoodEnum
+syn keyword cConstant OneLayerP4zEnum
 syn keyword cConstant SaveResultsEnum
 syn keyword cConstant BoolExternalResultEnum
@@ -1051,4 +1110,13 @@
 syn keyword cConstant MassfluxatgateNameEnum
 syn keyword cConstant MassfluxatgateSegmentsEnum
+syn keyword cConstant MisfitNameEnum
+syn keyword cConstant MisfitModelEnumEnum
+syn keyword cConstant MisfitObservationEnum
+syn keyword cConstant MisfitObservationEnumEnum
+syn keyword cConstant MisfitTimeinterpolationEnum
+syn keyword cConstant MisfitWeightsEnum
+syn keyword cConstant MisfitWeightsEnumEnum
+syn keyword cConstant SurfaceObservationEnum
+syn keyword cConstant WeightsSurfaceObservationEnum
 syn keyword cConstant MinVelEnum
 syn keyword cConstant MaxVelEnum
@@ -1067,11 +1135,18 @@
 syn keyword cConstant AbsoluteEnum
 syn keyword cConstant IncrementalEnum
+syn keyword cConstant AugmentedLagrangianREnum
+syn keyword cConstant AugmentedLagrangianThetaEnum
+syn keyword cConstant NoneEnum
 syn keyword cConstant AgressiveMigrationEnum
-syn keyword cConstant NoneEnum
 syn keyword cConstant SoftMigrationEnum
 syn keyword cConstant SubelementMigrationEnum
 syn keyword cConstant SubelementMigration2Enum
+syn keyword cConstant ContactEnum
 syn keyword cConstant MaskGroundediceLevelsetEnum
 syn keyword cConstant QmuMaskGroundediceLevelsetEnum
+syn keyword cConstant GaussSegEnum
+syn keyword cConstant GaussTriaEnum
+syn keyword cConstant GaussTetraEnum
+syn keyword cConstant GaussPentaEnum
 syn keyword cConstant FSSolverEnum
 syn keyword cConstant AdjointEnum
@@ -1119,7 +1194,14 @@
 syn keyword cConstant OptionCellEnum
 syn keyword cConstant OptionStructEnum
+syn keyword cConstant CuffeyEnum
 syn keyword cConstant PatersonEnum
 syn keyword cConstant ArrheniusEnum
 syn keyword cConstant LliboutryDuvalEnum
+syn keyword cConstant TransientIslevelsetEnum
+syn keyword cConstant ExtrapolationVariableEnum
+syn keyword cConstant IceMaskNodeActivationEnum
+syn keyword cConstant LevelsetfunctionSlopeXEnum
+syn keyword cConstant LevelsetfunctionSlopeYEnum
+syn keyword cConstant LevelsetfunctionPicardEnum
 "ISSM's Enums end
 """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
Index: /issm/trunk/jenkins/execute_shell
===================================================================
--- /issm/trunk/jenkins/execute_shell	(revision 17806)
+++ /issm/trunk/jenkins/execute_shell	(revision 17806)
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+#some exports required
+export ISSM_DIR="$WORKSPACE"
+
+#which configuration are we using?
+case $Platform in
+	master )
+		configfile=linux64_murdo ;;
+	imac-012301-gil )
+		configfile=imac-012301-gil ;;
+	larsen )
+		configfile=linux64_larsen ;;
+	windows )
+		configfile=windows
+		export PATH=/cygdrive/c/Cygwin/usr/bin:/cygdrive/c/Cygwin/bin:$PATH ;;
+
+esac
+
+#run
+cd "$WORKSPACE"
+source $ISSM_DIR/jenkins/jenkins.sh $ISSM_DIR/jenkins/$configfile
Index: /issm/trunk/jenkins/execute_shell_ad
===================================================================
--- /issm/trunk/jenkins/execute_shell_ad	(revision 17806)
+++ /issm/trunk/jenkins/execute_shell_ad	(revision 17806)
@@ -0,0 +1,16 @@
+#!/bin/bash
+
+#some exports required
+export ISSM_DIR="$WORKSPACE"
+
+#which configuration are we using? 
+case $AMPI in 
+	ampion ) 
+		configfile=linux64_murdo_ampi ;;
+	ampioff )
+		configfile=linux64_murdo_ad ;;
+esac 
+
+#run
+cd "$WORKSPACE"
+source $ISSM_DIR/jenkins/jenkins.sh $ISSM_DIR/jenkins/$configfile
Index: /issm/trunk/jenkins/imac-012301-gil
===================================================================
--- /issm/trunk/jenkins/imac-012301-gil	(revision 17806)
+++ /issm/trunk/jenkins/imac-012301-gil	(revision 17806)
@@ -0,0 +1,110 @@
+#
+########### Configuration file for Eric Larour's Jenkins run on MaxOSX ############
+
+#-------------------------------#
+# 1: ISSM general configuration #
+#-------------------------------#
+
+#Nightly run name
+NAME="ISSM matlab tests on MacOSX"
+
+#ISSM Architecture
+ISSM_ARCH="macosx-gnu"
+
+#ISSM CONFIGURATION 
+ISSM_CONFIG='--prefix=$ISSM_DIR \
+	--with-matlab-dir=$MATLAB_DIR \
+	--with-triangle-dir=$ISSM_DIR/externalpackages/triangle/install \
+	--with-metis-dir=$ISSM_DIR/externalpackages/metis/install \
+	--with-mpi-include=$ISSM_DIR/externalpackages/mpich/install/include  \
+	--with-mpi-libflags=" $ISSM_DIR/externalpackages/mpich/install/lib/libpmpich.a $ISSM_DIR/externalpackages/mpich/install/lib/libmpich.a $ISSM_DIR/externalpackages/mpich/install/lib/libmpl.a " \
+	--with-fortran-lib="/usr/local/gfortran/lib/libgfortran.a" \
+	--with-math-lib="/usr/lib/libm.dylib" \
+	--with-graphics-lib="/usr/X11/lib/libX11.dylib" \
+	--with-cxxoptflags=" -fno-common -no-cpp-precomp -fexceptions -arch x86_64 -mmacosx-version-min=10.5  -O3 -DNDEBUG -w "\
+	--with-numthreads=8 \
+	--with-petsc-dir=$ISSM_DIR/externalpackages/petsc/install  \
+	--with-petsc-arch=$ISSM_ARCH \
+	--with-blas-lapack-dir=$ISSM_DIR/externalpackages/petsc/install \
+	--with-scalapack-dir=$ISSM_DIR/externalpackages/petsc/install/ \
+	--with-mumps-dir=$ISSM_DIR/externalpackages/petsc/install \
+	--with-tao-dir=$ISSM_DIR/externalpackages/tao/install \
+	--enable-development'
+
+#MATLAB path
+MATLAB_PATH="/Applications/MATLAB_R2011b.app/"
+
+#PYTHON and MATLAB testing
+MATLAB_TEST=1
+PYTHON_TEST=0
+
+#execution path used for parallel runs
+EXECUTION_PATH=$ISSM_DIR/execution
+
+#repo:
+REPOSITORY="https://issm.ess.uci.edu/svn/issm/issm/trunk-jpl"
+
+#-----------------------------------#
+# 3: External packages installation #
+#-----------------------------------#
+
+#ISSM_EXTERNALPACKAGES can have 3 values:
+# - "install" install all external packages listed below
+# - "copy"    copy existing directories (EXTERNALPACKAGESDIR)
+# - "none"    leave external packages as is
+#             ->skip to section 4
+ISSM_EXTERNALPACKAGES="install"
+EXTERNALPACKAGESDIR=$ISSM_DIR/externalpackages
+
+#List of external pakages to be installed and their installation scripts
+EXTERNALPACKAGES="autotools install.sh                
+						matlab    install.sh                
+						mpich     install-3.0-macosx64.sh    
+						cmake     install.sh                
+						petsc     install-3.4-macosx64.sh    
+						tao       install-2.2.sh
+						triangle  install-macosx64.sh 
+						shell2junit  install.sh "
+
+
+#---------------------#
+# 4: ISSM Compilation #
+#---------------------#
+
+#ISSM_COMPILATION can have 2 values:
+# - "yes" compile ISSM
+# - "no"  do not compile ISSM
+ISSM_COMPILATION="yes"
+
+#----------------------#
+# 5: Mail notification #
+#----------------------#
+
+#Mail delivery. If SKIPMAIL="no", the html nightly run report will be
+#sent to the adresses present in $ISSM_DIR/cron/mailinglist.
+SKIPMAIL="no"
+
+#Sender email address
+EMAIL_ADRESS="eric.larour@jpl.nasa.gov"
+
+#Mailing list
+MAILINGLIST="eric.larour@jpl.nasa.gov"
+
+#------------------------#
+# 6: Nightly run options #
+#------------------------#
+
+#number of cpus used in ISSM installation and compilation (one is usually
+#safer as some packages are very sensitive to parallel compilation)
+NUMCPUS_INSTALL=8
+
+#number of cpus used in the nightly runs.
+NUMCPUS_RUN=1
+
+#Nightly run options. The matlab routine runme.m will be called
+#as follows: runme($MATLAB_NROPTIONS). The options must be understandable
+#by Matlab and runme.m
+#ex: "'id',[101 102 103]"
+##                                                                   bamg mesh   FS                     
+MATLAB_NROPTIONS="'exclude',[218 234 235 412 413 414 417 418 420 514 701 702 703 422 404 421 503 507 510]"
+PYTHON_NROPTIONS=""
Index: /issm/trunk/jenkins/jenkins.sh
===================================================================
--- /issm/trunk/jenkins/jenkins.sh	(revision 17806)
+++ /issm/trunk/jenkins/jenkins.sh	(revision 17806)
@@ -0,0 +1,382 @@
+#!/bin/bash
+#This bash script calls the nightlyrun.m matlab file to run our nightly test decks. 
+#It then processes the results and sends an email to the Ice developpers.
+
+#some functions
+function timer() #{{{
+{
+	if [[ $# -eq 0 ]]; then
+		echo $(date '+%s')
+	else
+		local  stime=$1
+		etime=$(date '+%s')
+
+		if [[ -z "$stime" ]]; then stime=$etime; fi
+
+		dt=$((etime - stime))
+		ds=$((dt % 60))
+		dm=$(((dt / 60) % 60))
+		dh=$((dt / 3600))
+		printf '%d:%02d:%02d' $dh $dm $ds
+	fi
+} #}}}
+function todaydate() #{{{
+{
+	suffix=`date | awk '{printf("%s-%s-%s  %s",$2,$3,$6,$4);}'`			 
+	echo $suffix;			 
+} #}}}
+function host_name() #{{{
+{
+	#return host name depending on the OS
+	if [ "$1" = "win7" ] 
+	then
+		HOST_NAME=`hostname | sed 's/-//g'`;
+	else
+		HOST_NAME=`hostname -s | sed 's/-//g'`;
+	fi
+	echo $HOST_NAME;
+} #}}}
+function pause() #{{{
+{
+pid=`ps aux -W | grep $1 | awk '{printf("%s\n",$1);}'`
+
+while [ -n "$pid" ]
+do
+	pid=`ps aux -W | grep $1 | awk '{printf("%s\n",$1);}'`
+done
+}
+#}}}
+
+#Get configuration
+#Source config file{{{
+if [ $# -ne 1 ];
+then
+	#no config file specified: exit
+	echo "no config file specified. Exiting..." >&2 # Error message to stderr.
+	exit 1
+fi
+if [ ! -f "$1" ]
+then
+	echo "File $1 not found!" >&2   # Error message to stderr.
+	exit 1
+fi 
+source $1;
+#}}}
+#Initialize variables {{{
+TODAY=$(todaydate);
+OS=$(uname -s)
+if [[ $OS == "CYGWIN_NT-6.1-WOW64" ]]; then 
+	OS="win7";
+fi
+HOST_NAME=$(host_name $OS);
+START_TIME=$(timer);
+ISSM_RELEASE=$(basename $(echo $REPOSITORY));
+USER=$(whoami);
+INIT_PATH=$(pwd);
+#}}}
+
+#Installation ISSM
+#create matlab's installation sript {{{
+cat << END > $ISSM_DIR/externalpackages/matlab/install.sh
+#!/bin/bash
+rm -rf install
+ln -s $MATLAB_PATH install
+END
+#}}}
+#install/copy/none external packages    (ISSM_EXTERNALPACKAGES){{{
+if [ "$ISSM_EXTERNALPACKAGES" == "install" ]
+then
+	
+	cd $ISSM_DIR/externalpackages
+
+	#number of packages: 
+	NUMPACKAGES=$(($(echo $EXTERNALPACKAGES | wc -w )/2))
+
+	for ((i=1;i<=$NUMPACKAGES;i++))
+	do
+		NUM1=$((2*$i-1))
+		NUM2=$((2*$i))
+		PACKAGENAME=$(echo $EXTERNALPACKAGES | cut -d " " -f $NUM1-$NUM1)
+		PACKAGEINST=$(echo $EXTERNALPACKAGES | cut -d " " -f $NUM2-$NUM2)
+
+		cd $PACKAGENAME
+
+		#tricky part here. We do not want to reinstall this package if it's already installed
+		#and the svn file which does the install has not be modified! To keep track of 
+		#this, we check the current svn version against the "last changed" revision number.  If they 
+		#are the same, we reinstall the package. 
+		current_version=`svnversion`
+		last_changed_version=`svn info $PACKAGEINST | grep "Last Changed Rev" | awk '{printf("%s\n",$4);}'`
+
+		if [[ $current_version == $last_changed_version ]]; then 
+			#go ahead and reinstall. 
+			echo "For $PACKAGENAME: svn current_version  is $current_version and last changed version is $last_changed_version"
+			echo "Triggering new install of $PACKAGENAME"
+			install_test=1
+		else
+			#ok, we want to skip, unless the package is not installed: 
+			if [ -d install ]; then 
+				#could be empty, signaling a failed previous install: 
+				if [ "$(ls -A install)" ];then
+					echo "For $PACKAGENAME: svn current_version  is $current_version and last changed version is $last_changed_version"
+					echo "and install directory exists, so skipping install of $PACKAGENAME"
+					install_test=0;
+				else
+					echo "For $PACKAGENAME: svn current_version  is $current_version and last changed version is $last_changed_version"
+					echo "and install directory exists, however, it is empty, so triggering install of $PACKAGENAME"
+					install_test=1;
+				fi
+			else
+				echo "For $PACKAGENAME: svn current_version  is $current_version and last changed version is $last_changed_version"
+				echo "However, install directory does not exist, so triggering install of $PACKAGENAME"
+				install_test=1;
+			fi
+		fi
+
+		if [[ $install_test == 1 ]]; then 
+			echo "======================================================";
+			echo "       Installing $PACKAGENAME                        ";
+			echo "======================================================";
+			./$PACKAGEINST |  tee compil.log
+			if [ $? -ne 0 ]; then
+				echo "======================================================";
+				echo "    ERROR: installation of $PACKAGENAME failed        ";
+				echo "======================================================";
+				#erase install directory, so that next time, we still try and compile this!
+				rm -rf install
+			fi
+			source $ISSM_DIR/etc/environment.sh
+		else
+			echo "======================================================";
+			echo "       Skipping install of $PACKAGENAME                        ";
+			echo "======================================================";
+			source $ISSM_DIR/etc/environment.sh #for good measure :)
+		fi
+		cd ..
+	done
+
+elif [ "$ISSM_EXTERNALPACKAGES" == "copy" ]
+then
+	cd $ISSM_DIR
+	rm -rf externalpackages
+	cp -Rf $EXTERNALPACKAGESDIR ./
+elif [ "$ISSM_EXTERNALPACKAGES" == "link" ]
+then
+	cd $ISSM_DIR
+	rm -rf externalpackages
+	ln -s  $EXTERNALPACKAGESDIR  .
+elif [ "$ISSM_EXTERNALPACKAGES" == "none" ]
+then
+	echo "Skipping external packages installation"
+else
+	echo "ISSM_EXTERNALPACKAGES supported values are: install, copy and none. Exiting..." >&2 # Error message to stderr.
+	exit 1
+fi
+source $ISSM_DIR/etc/environment.sh
+#}}}
+#ISSM compilation yes/no                (ISSM_COMPILATION) {{{
+if [ "$ISSM_COMPILATION" == "yes" ]
+then
+	cd $ISSM_DIR
+	make uninstall
+	make clean
+	make distclean
+	./scripts/automakererun.sh
+	cat > configure.sh << EOF
+./configure $ISSM_CONFIG
+EOF
+	chmod 700 configure.sh
+	./configure.sh
+
+	#4: compile and install ISSM
+	if [ $NUMCPUS_INSTALL -gt 1 ]
+	then
+		echo "Making with " $NUMCPUS_INSTALL " cpus"
+		make -j $NUMCPUS_INSTALL install
+	else
+		make install
+	fi
+	if [ $? -ne 0 ]; then 
+		echo "ISSM_COMPILATION failed!"
+		exit 1
+	fi
+elif [ "$ISSM_COMPILATION" == "no" ]
+then
+	echo "Skipping ISSM compilation"
+else
+	echo "ISSM_COMPILATION supported values are: yes and no. Exiting..." >&2 # Error message to stderr.
+	exit 1
+fi
+#}}}
+echo "Cleaning up execution directory"
+rm -rf $ISSM_DIR/execution/*
+
+#Prepare info.log
+#{{{
+rm -rf $ISSM_DIR/nightlylog
+mkdir  $ISSM_DIR/nightlylog
+INSTALL_TIME=$(timer)
+ELAPSED=$(timer $START_TIME)
+VERSION=$(svnversion $ISSM_DIR)
+cat << END > $ISSM_DIR/nightlylog/info.log
+name:      $(echo $NAME)
+today:     $(echo $TODAY)
+user:      $(echo $USER)
+host:      $(echo $HOST_NAME)
+OS:        $(echo $OS)
+release:   $(echo $ISSM_RELEASE)
+init_path: $(echo $INIT_PATH)
+is_matlab: $(echo $MATLAB_TEST)
+is_python: $(echo $PYTHON_TEST)
+elapsed_install: $(echo $ELAPSED)
+version: $(echo $VERSION)
+END
+#}}}
+
+#matlab tests
+if [ $MATLAB_TEST -eq 1 ]; then
+#Launch all tests on different cpus {{{
+MATLAB_START_TIME=$(timer);
+for (( i=1;i<=$NUMCPUS_RUN;i++ ))
+do
+	#Launch matlab and the nightly run script
+	cat > $ISSM_DIR/nightlylog/matlab_run$i.m << EOF
+	warning off %necessary to avoid a info.log of several Go for parallel runs
+	try,
+	$(if [ "$MATLAB_NROPTIONS" = ""  ]
+	then
+		echo "runme('output','nightly','rank',$i,'numprocs',$NUMCPUS_RUN);"
+	else
+		echo "runme($MATLAB_NROPTIONS,'output','nightly','rank',$i,'numprocs',$NUMCPUS_RUN);"
+	fi
+	)
+	catch me,
+		%An error occured, get report and exit
+		message=getReport(me)
+		directory=strsplit(pwd,'/');
+		fid=fopen([issmdir '/nightlylog/matlaberror.log'], 'at');
+		fprintf(fid,'\nMatlab error occured in: %s\n\n',directory{end});
+		fprintf(fid,'%s',message);
+		fclose(fid);
+	end
+	disp('MATLABEXITEDCORRECTLY');
+	exit
+EOF
+	cd $ISSM_DIR/test/NightlyRun
+	matlab -nojvm -nosplash -r "addpath $ISSM_DIR/src/m/dev; devpath; addpath $ISSM_DIR/nightlylog/; matlab_run$i" -logfile $ISSM_DIR/nightlylog/matlab_log$i.log &
+done
+
+#wait until matlab closes
+if [ "$OS" = "win7" ]; then
+	pause MATLAB
+else
+	wait
+fi
+
+#concatenate reports
+cd $ISSM_DIR/nightlylog/
+rm matlab_log.log
+for (( i=1;i<=$NUMCPUS_RUN;i++ ))
+do
+	cat matlab_log$i.log >> matlab_log.log
+done
+
+#filter out windows characters: 
+cat matlab_log.log | tr -cd '\11\12\40-\176' > matlab_log.log2 && mv matlab_log.log2 matlab_log.log
+
+#}}}
+#Complete info.log {{{
+if [ $(cat matlab_log.log | grep "MATLABEXITEDCORRECTLY" | wc -l) -eq $NUMCPUS_RUN ]
+then
+	MATLABCRASH=0
+else
+	MATLABCRASH=1
+fi
+ELAPSED=$(timer $MATLAB_START_TIME)
+cat << END >>  $ISSM_DIR/nightlylog/info.log
+elapsed_matlab: $(echo $ELAPSED)
+matlab_crash:   $(echo $MATLABCRASH)
+END
+#}}}
+fi
+
+#python tests
+if [ $PYTHON_TEST -eq 1 ]; then
+#Launch all tests on different cpus {{{
+PYTHON_START_TIME=$(timer);
+export PYTHONSTARTUP=$ISSM_DIR/src/m/dev/devpath.py
+for (( i=1;i<=$NUMCPUS_RUN;i++ ))
+do
+	cd $ISSM_DIR/test/NightlyRun
+	./runme.py --output=nightly --rank=$i --numprocs=$NUMCPUS_RUN $PYTHON_NROPTIONS 2>&1 > $ISSM_DIR/nightlylog/python_log$i.log &
+done
+
+#wait until python closes
+if [ "$OS" = "win7" ]; then
+	pause MATLAB
+else
+	wait
+fi
+
+#concatenate reports
+cd $ISSM_DIR/nightlylog/
+rm python_log.log
+for (( i=1;i<=$NUMCPUS_RUN;i++ ))
+do
+	cat python_log$i.log >> python_log.log
+done
+#}}}
+#Complete info.log {{{
+if [ $(cat python_log.log | grep "PYTHONEXITEDCORRECTLY" | wc -l) -eq $NUMCPUS_RUN ]
+then
+	PYTHONCRASH=0
+else
+	PYTHONCRASH=1
+fi
+ELAPSED=$(timer $PYTHON_START_TIME)
+cat << END >>  $ISSM_DIR/nightlylog/info.log
+elapsed_python: $(echo $ELAPSED)
+python_crash:   $(echo $PYTHONCRASH)
+END
+#}}}
+fi
+
+#complete info.log
+#{{{
+ELAPSED=$(timer $START_TIME)
+cat << END >>  $ISSM_DIR/nightlylog/info.log
+elapsed_total:  $(echo $ELAPSED)
+END
+#}}}
+
+#process logs to be junit compatible
+#{{{
+cd $ISSM_DIR/nightlylog/
+source $ISSM_DIR/externalpackages/shell2junit/install/sh2ju.sh
+juLogClean
+
+if [ $MATLAB_TEST -eq 1 ]; then
+	#number tests:
+	numtests=`cat matlab_log.log  | grep "\-\-\-\-\-\-\-\-starting" | wc -l`
+	testlist=`cat matlab_log.log  | grep "\-\-\-\-\-\-\-\-starting" | sed 's/----------------starting://g'  | sed 's/-//g'`
+
+	#look through numtests:
+	for i in `echo $testlist`
+	do
+		juLog  -test=MATLAB-$i -name=Error -error=ERROR awk "/starting:$i/{flag=1;next}/finished/{flag=0} flag{print}" matlab_log.log
+		juLog  -test=MATLAB-$i -name=Failure -error=FAILURE awk "/starting:$i/{flag=1;next}/finished/{flag=0} flag{print}" matlab_log.log
+	done
+fi
+if [ $PYTHON_TEST -eq 1 ]; then
+	#number tests:
+	numtests=`cat python_log.log  | grep "\-\-\-\-\-\-\-\-starting" | wc -l`
+	testlist=`cat python_log.log  | grep "\-\-\-\-\-\-\-\-starting" | sed 's/----------------starting://g'  | sed 's/-//g'`
+
+	#look through numtests:
+	for i in `echo $testlist`
+	do
+		juLog  -test=PYTHON-$i -name=Error -error=ERROR awk "/starting:$i/{flag=1;next}/finished/{flag=0} flag{print}" python_log.log
+		juLog  -test=PYTHON-$i -name=Failure -error=FAILURE awk "/starting:$i/{flag=1;next}/finished/{flag=0} flag{print}" python_log.log
+	done
+fi
+#}}}
Index: /issm/trunk/jenkins/linux64_larsen
===================================================================
--- /issm/trunk/jenkins/linux64_larsen	(revision 17806)
+++ /issm/trunk/jenkins/linux64_larsen	(revision 17806)
@@ -0,0 +1,112 @@
+#
+########### Configuration file for Eric Larour's Jenkins run on Murdo ############
+
+#-------------------------------#
+# 1: ISSM general configuration #
+#-------------------------------#
+
+#Nightly run name
+NAME="ISSM matlab tests on Linux64 (murdo)"
+
+#ISSM Architecture
+ISSM_ARCH="linux-gnu-amd64"
+
+#ISSM CONFIGURATION 
+ISSM_CONFIG='--prefix=$ISSM_DIR\
+	--with-matlab-dir=$MATLAB_DIR \
+	--with-triangle-dir=$ISSM_DIR/externalpackages/triangle/install \
+	--with-metis-dir=$ISSM_DIR/externalpackages/metis/install \
+	--with-mpi-include=$ISSM_DIR/externalpackages/mpich/install/include  \
+	--with-mpi-libflags="-L$ISSM_DIR/externalpackages/mpich/install/lib/ -lmpich" \
+	--with-petsc-dir=$ISSM_DIR/externalpackages/petsc/install \
+	--with-petsc-arch=$ISSM_ARCH \
+	--with-mumps-dir=$ISSM_DIR/externalpackages/petsc/install/ \
+	--with-dakota-dir=$ISSM_DIR/externalpackages/dakota/install \
+	--with-boost-dir=$ISSM_DIR/externalpackages/boost/install/ \
+	--with-blas-lapack-dir=$ISSM_DIR/externalpackages/petsc/install \
+	--with-chaco-dir="$ISSM_DIR/externalpackages/chaco/install" \
+	--with-numthreads=18 \
+	--with-cxxoptflags="-mtune=barcelona -ffast-math -O3 -msse4.2 -Wno-write-strings "\
+	--with-graphics-lib="/usr/lib/x86_64-linux-gnu/libX11.so" \
+	--with-tao-dir=$ISSM_DIR/externalpackages/tao/install \
+	--enable-development \
+	--enable-debugging '
+
+#MATLAB path
+MATLAB_PATH="/usr/local/matlab80/"
+
+#PYTHON and MATLAB testing
+MATLAB_TEST=1
+PYTHON_TEST=0
+
+#execution path used for parallel runs
+EXECUTION_PATH=$ISSM_DIR/execution
+
+#repo:
+REPOSITORY="https://issm.ess.uci.edu/svn/issm/issm/trunk-jpl"
+
+#-----------------------------------#
+# 3: External packages installation #
+#-----------------------------------#
+
+#ISSM_EXTERNALPACKAGES can have 3 values:
+# - "install" install all external packages listed below
+# - "copy"    copy existing directories (EXTERNALPACKAGESDIR)
+# - "none"    leave external packages as is
+#             ->skip to section 4
+ISSM_EXTERNALPACKAGES="install"
+EXTERNALPACKAGESDIR=$ISSM_DIR/externalpackages
+
+#List of external pakages to be installed and their installation scripts
+EXTERNALPACKAGES="autotools install.sh                
+						matlab    install.sh                
+						mpich     install-3.0-linux64.sh    
+						cmake     install.sh                
+						petsc     install-3.4-linux64.sh    
+						triangle  install-linux64.sh        
+						boost     install.sh                
+						dakota    install-5.3.1-linux64.sh  
+						tao       install-2.2.sh
+						chaco     install.sh 
+						shell2junit install.sh"
+
+#---------------------#
+# 4: ISSM Compilation #
+#---------------------#
+
+#ISSM_COMPILATION can have 2 values:
+# - "yes" compile ISSM
+# - "no"  do not compile ISSM
+ISSM_COMPILATION="yes"
+
+#----------------------#
+# 5: Mail notification #
+#----------------------#
+
+#Mail delivery. If SKIPMAIL="no", the html nightly run report will be
+#sent to the adresses present in $ISSM_DIR/cron/mailinglist.
+SKIPMAIL="no"
+
+#Sender email address
+EMAIL_ADRESS="eric.larour@jpl.nasa.gov"
+
+#Mailing list
+MAILINGLIST="eric.larour@jpl.nasa.gov"
+
+#------------------------#
+# 6: Nightly run options #
+#------------------------#
+
+#number of cpus used in ISSM installation and compilation (one is usually
+#safer as some packages are very sensitive to parallel compilation)
+NUMCPUS_INSTALL=8
+
+#number of cpus used in the nightly runs.
+NUMCPUS_RUN=8
+
+#Nightly run options. The matlab routine runme.m will be called
+#as follows: runme($MATLAB_NROPTIONS). The options must be understandable
+#by Matlab and runme.m
+#ex: "'id',[101 102 103]"
+MATLAB_NROPTIONS=""
+PYTHON_NROPTIONS=""
Index: /issm/trunk/jenkins/linux64_murdo
===================================================================
--- /issm/trunk/jenkins/linux64_murdo	(revision 17806)
+++ /issm/trunk/jenkins/linux64_murdo	(revision 17806)
@@ -0,0 +1,125 @@
+#
+########### Configuration file for Eric Larour's Jenkins run on Murdo ############
+
+#-------------------------------#
+# 1: ISSM general configuration #
+#-------------------------------#
+
+#Nightly run name
+NAME="ISSM matlab tests on Linux64 (murdo)"
+
+#ISSM Architecture
+ISSM_ARCH="linux-gnu-amd64"
+
+#ISSM CONFIGURATION 
+ISSM_CONFIG='--prefix=$ISSM_DIR\
+	--with-matlab-dir=$MATLAB_DIR \
+	--with-triangle-dir=$ISSM_DIR/externalpackages/triangle/install \
+	--with-metis-dir=$ISSM_DIR/externalpackages/metis/install \
+	--with-mpi-include=$ISSM_DIR/externalpackages/mpich/install/include  \
+	--with-mpi-libflags="-L$ISSM_DIR/externalpackages/mpich/install/lib/ -lmpich" \
+	--with-petsc-dir=$ISSM_DIR/externalpackages/petsc/install \
+	--with-petsc-arch=$ISSM_ARCH \
+	--with-python-dir=$ISSM_DIR/externalpackages/python/install\
+	--with-python-numpy-dir=$ISSM_DIR/externalpackages/python/install/lib/python2.7/site-packages/numpy/core/include/numpy\
+	--with-mumps-dir=$ISSM_DIR/externalpackages/petsc/install/ \
+	--with-blas-lapack-dir=$ISSM_DIR/externalpackages/petsc/install \
+	--with-chaco-dir="$ISSM_DIR/externalpackages/chaco/install" \
+	--with-numthreads=18 \
+	--with-cxxoptflags="-mtune=barcelona -ffast-math -O3 -msse4.2 -Wno-write-strings "\
+	--with-graphics-lib="/usr/lib/x86_64-linux-gnu/libX11.so" \
+	--with-dakota-dir=$ISSM_DIR/externalpackages/dakota/install \
+	--with-boost-dir=$ISSM_DIR/externalpackages/boost/install/ \
+	--with-tao-dir=$ISSM_DIR/externalpackages/tao/install \
+	--enable-development \
+	--enable-debugging '
+
+#MATLAB path
+MATLAB_PATH="/usr/local/matlab80/"
+
+#PYTHON and MATLAB testing
+MATLAB_TEST=1
+PYTHON_TEST=1
+
+#execution path used for parallel runs
+EXECUTION_PATH=$ISSM_DIR/execution
+
+#repo:
+REPOSITORY="https://issm.ess.uci.edu/svn/issm/issm/trunk-jpl"
+
+#-----------------------------------#
+# 3: External packages installation #
+#-----------------------------------#
+
+#ISSM_EXTERNALPACKAGES can have 3 values:
+# - "install" install all external packages listed below
+# - "copy"    copy existing directories (EXTERNALPACKAGESDIR)
+# - "none"    leave external packages as is
+#             ->skip to section 4
+ISSM_EXTERNALPACKAGES="install"
+EXTERNALPACKAGESDIR=$ISSM_DIR/externalpackages
+
+#List of external pakages to be installed and their installation scripts
+EXTERNALPACKAGES="autotools install.sh                
+						matlab    install.sh                
+						mpich     install-3.0-linux64.sh    
+						cmake     install.sh                
+						petsc     install-3.4-linux64.sh    
+						triangle  install-linux64.sh        
+						boost     install.sh                
+						dakota    install-5.3.1-linux64.sh  
+						tao       install-2.2.sh
+						chaco     install.sh 
+						python        install-2.7.3-linux64.sh    
+						nose          install-linux64-python2.sh  
+						blas          install-linux64.sh          
+						lapack        install-linux64.sh          
+						git           install.sh                  
+						numpy         install-linux64.sh          
+						scipy         install-linux64.sh          
+						hdf5          install.sh                  
+						netcdf        install.sh                  
+						netcdf-python install.sh
+						shell2junit install.sh"
+
+
+#---------------------#
+# 4: ISSM Compilation #
+#---------------------#
+
+#ISSM_COMPILATION can have 2 values:
+# - "yes" compile ISSM
+# - "no"  do not compile ISSM
+ISSM_COMPILATION="yes"
+
+#----------------------#
+# 5: Mail notification #
+#----------------------#
+
+#Mail delivery. If SKIPMAIL="no", the html nightly run report will be
+#sent to the adresses present in $ISSM_DIR/cron/mailinglist.
+SKIPMAIL="no"
+
+#Sender email address
+EMAIL_ADRESS="eric.larour@jpl.nasa.gov"
+
+#Mailing list
+MAILINGLIST="eric.larour@jpl.nasa.gov"
+
+#------------------------#
+# 6: Nightly run options #
+#------------------------#
+
+#number of cpus used in ISSM installation and compilation (one is usually
+#safer as some packages are very sensitive to parallel compilation)
+NUMCPUS_INSTALL=8
+
+#number of cpus used in the nightly runs.
+NUMCPUS_RUN=8
+
+#Nightly run options. The matlab routine runme.m will be called
+#as follows: runme($MATLAB_NROPTIONS). The options must be understandable
+#by Matlab and runme.m
+#ex: "'id',[101 102 103]"
+MATLAB_NROPTIONS="'exclude',[119,514,701,702,435]"
+PYTHON_NROPTIONS="--exclude 119 514 701 702 435"
Index: /issm/trunk/jenkins/linux64_murdo_ad
===================================================================
--- /issm/trunk/jenkins/linux64_murdo_ad	(revision 17806)
+++ /issm/trunk/jenkins/linux64_murdo_ad	(revision 17806)
@@ -0,0 +1,99 @@
+########### Configuration file for Eric Larour's Jenkins runs on Linux. Automatic differentiation ############
+
+#-------------------------------#
+# 1: ISSM general configuration #
+#-------------------------------#
+
+#Nightly run name
+NAME="ISSM tests on Linux64 (murdo). Automatic differentiation validation tests"
+
+#ISSM Architecture
+ISSM_ARCH="linux-gnu-amd64"
+
+#ISSM CONFIGURATION 
+ISSM_CONFIG='--prefix=$ISSM_DIR\
+				--prefix=$ISSM_DIR \
+				--without-kriging \
+				--without-kml \
+				--with-gsl-dir=$ISSM_DIR/externalpackages/gsl/install \
+				--with-adolc-dir=$ISSM_DIR/externalpackages/adolc/install \
+				--with-matlab-dir=$MATLAB_DIR \
+				--with-triangle-dir=$ISSM_DIR/externalpackages/triangle/install '
+#MATLAB path
+MATLAB_PATH="/usr/local/matlab80/"
+
+#PYTHON and MATLAB testing
+MATLAB_TEST=1
+PYTHON_TEST=0
+
+#execution path used for parallel runs
+EXECUTION_PATH=$ISSM_DIR/execution
+
+#repo:
+REPOSITORY="https://issm.ess.uci.edu/svn/issm/issm/trunk-jpl"
+
+#-----------------------------------#
+# 3: External packages installation #
+#-----------------------------------#
+
+#ISSM_EXTERNALPACKAGES can have 3 values:
+# - "install" install all external packages listed below
+# - "copy"    copy existing directories (EXTERNALPACKAGESDIR)
+# - "none"    leave external packages as is
+#             ->skip to section 4
+ISSM_EXTERNALPACKAGES="install"
+EXTERNALPACKAGESDIR=$ISSM_DIR/externalpackages
+
+#List of external pakages to be installed and their installation scripts
+EXTERNALPACKAGES="autotools install.sh                
+					 git install.sh 
+					 cmake install.sh 
+					 matlab install.sh 
+					 mpich install-3.0-linux64.sh
+					 petsc install-3.4-linux64.sh
+					 metis install-5.0.1-linux64.sh
+					 triangle install-linux64.sh 
+					 gsl install-linux64.sh 
+					 adolc install.sh
+					 shell2junit install.sh"
+
+#---------------------#
+# 4: ISSM Compilation #
+#---------------------#
+
+#ISSM_COMPILATION can have 2 values:
+# - "yes" compile ISSM
+# - "no"  do not compile ISSM
+ISSM_COMPILATION="yes"
+
+#----------------------#
+# 5: Mail notification #
+#----------------------#
+
+#Mail delivery. If SKIPMAIL="no", the html nightly run report will be
+#sent to the adresses present in $ISSM_DIR/cron/mailinglist.
+SKIPMAIL="no"
+
+#Sender email address
+EMAIL_ADRESS="eric.larour@jpl.nasa.gov"
+
+#Mailing list
+MAILINGLIST="eric.larour@jpl.nasa.gov"
+
+#------------------------#
+# 6: Nightly run options #
+#------------------------#
+
+#number of cpus used in ISSM installation and compilation (one is usually
+#safer as some packages are very sensitive to parallel compilation)
+NUMCPUS_INSTALL=8
+
+#number of cpus used in the nightly runs.
+NUMCPUS_RUN=8
+
+#Nightly run options. The matlab routine runme.m will be called
+#as follows: runme($MATLAB_NROPTIONS). The options must be understandable
+#by Matlab and runme.m
+#ex: "'id',[101 102 103]"
+MATLAB_NROPTIONS="'benchmark','adolc','id',[3001:3019]"
+PYTHON_NROPTIONS=""
Index: /issm/trunk/jenkins/linux64_murdo_ampi
===================================================================
--- /issm/trunk/jenkins/linux64_murdo_ampi	(revision 17806)
+++ /issm/trunk/jenkins/linux64_murdo_ampi	(revision 17806)
@@ -0,0 +1,112 @@
+#
+########### Configuration file for Eric Larour's Jenkins run on Murdo ############
+
+#-------------------------------#
+# 1: ISSM general configuration #
+#-------------------------------#
+
+#Nightly run name
+NAME="ISSM tests on Linux64 (murdo). Automatic differentiation validation tests with ampi"
+
+#ISSM Architecture
+ISSM_ARCH="linux-gnu-amd64"
+
+#ISSM CONFIGURATION 
+ISSM_CONFIG='--prefix=$ISSM_DIR\
+				  --without-kriging \
+				  --without-kml \
+				  --with-gsl-dir=$ISSM_DIR/externalpackages/gsl/install \
+				  --with-adolc-dir=$ISSM_DIR/externalpackages/adolc/install \
+				  --with-ampi-dir=$ISSM_DIR/externalpackages/adjoinablempi/install \
+				  --with-matlab-dir=$MATLAB_DIR \
+				  --with-metis-dir=$ISSM_DIR/externalpackages/petsc/install \
+				  --with-mpi-include=$ISSM_DIR/externalpackages/mpich/install/include  \
+				  --with-mpi-libflags="-L$ISSM_DIR/externalpackages/mpich/install/lib/ -lmpich" \
+				  --with-graphics-lib="/usr/lib/x86_64-linux-gnu/libX11.so" \
+				  --with-mumps-dir=$ISSM_DIR/externalpackages/petsc/install/ \
+				  --with-blas-lapack-dir=$ISSM_DIR/externalpackages/petsc/install \
+				  --with-numthreads=18  \
+				  --with-scalapack-dir=$ISSM_DIR/externalpackages/petsc/install/ \
+				  --with-triangle-dir=$ISSM_DIR/externalpackages/triangle/install \
+				  --enable-development \
+				  --enable-debugging CXXFLAGS="-g -O0" '
+#MATLAB path
+MATLAB_PATH="/usr/local/matlab80/"
+
+#PYTHON and MATLAB testing
+MATLAB_TEST=1
+PYTHON_TEST=0
+
+#execution path used for parallel runs
+EXECUTION_PATH=$ISSM_DIR/execution
+
+#repo:
+REPOSITORY="https://issm.ess.uci.edu/svn/issm/issm/trunk-jpl"
+
+#-----------------------------------#
+# 3: External packages installation #
+#-----------------------------------#
+
+#ISSM_EXTERNALPACKAGES can have 3 values:
+# - "install" install all external packages listed below
+# - "copy"    copy existing directories (EXTERNALPACKAGESDIR)
+# - "none"    leave external packages as is
+#             ->skip to section 4
+ISSM_EXTERNALPACKAGES="install"
+EXTERNALPACKAGESDIR=$ISSM_DIR/externalpackages
+
+#List of external pakages to be installed and their installation scripts
+EXTERNALPACKAGES="autotools install.sh 
+					 git install.sh 
+					 cmake install.sh 
+					 matlab install.sh 
+					 mpich install-3.0-linux64.sh
+					 petsc install-3.4-linux64.sh
+					 metis install-5.0.1-linux64.sh
+					 triangle install-linux64.sh 
+					 gsl install-linux64.sh 
+					 mercurial install.sh
+					 adjoinablempi install.sh
+					 adolc install-withampi.sh
+					 shell2junit install.sh"
+
+#---------------------#
+# 4: ISSM Compilation #
+#---------------------#
+
+#ISSM_COMPILATION can have 2 values:
+# - "yes" compile ISSM
+# - "no"  do not compile ISSM
+ISSM_COMPILATION="yes"
+
+#----------------------#
+# 5: Mail notification #
+#----------------------#
+
+#Mail delivery. If SKIPMAIL="no", the html nightly run report will be
+#sent to the adresses present in $ISSM_DIR/cron/mailinglist.
+SKIPMAIL="no"
+
+#Sender email address
+EMAIL_ADRESS="eric.larour@jpl.nasa.gov"
+
+#Mailing list
+MAILINGLIST="eric.larour@jpl.nasa.gov"
+
+#------------------------#
+# 6: Nightly run options #
+#------------------------#
+
+#number of cpus used in ISSM installation and compilation (one is usually
+#safer as some packages are very sensitive to parallel compilation)
+NUMCPUS_INSTALL=8
+
+#number of cpus used in the nightly runs.
+NUMCPUS_RUN=8
+
+#Nightly run options. The matlab routine runme.m will be called
+#as follows: runme($MATLAB_NROPTIONS). The options must be understandable
+#by Matlab and runme.m
+#ex: "'id',[101 102 103]"
+MATLAB_NROPTIONS="'benchmark','adolc','id',[3001, 3002, 3003, 3004, 3005, 3006, 3007, 3008, 3009, 3010, 3101, 3102, 3103, 3104, 3105, 3106, 3107, 3108, 3109, 3119]"
+PYTHON_NROPTIONS=""
Index: /issm/trunk/jenkins/parsing_rules
===================================================================
--- /issm/trunk/jenkins/parsing_rules	(revision 17806)
+++ /issm/trunk/jenkins/parsing_rules	(revision 17806)
@@ -0,0 +1,15 @@
+ok /not really/
+
+# match line starting with 'error ', case-insensitive
+error /.*\\berror:\\b.*/
+
+# list of warnings here...
+warning /[Ww]arning/
+warning /WARNING/
+
+# create a quick access link to lines in the report containing 'INFO'
+info /INFO/
+
+# each line containing 'BUILD' represents the start of a section for grouping errors and warnings found after the line.
+# also creates a quick access link.
+start /BUILD/
Index: /issm/trunk/jenkins/windows
===================================================================
--- /issm/trunk/jenkins/windows	(revision 17806)
+++ /issm/trunk/jenkins/windows	(revision 17806)
@@ -0,0 +1,105 @@
+#
+########### Configuration file for Eric Larour's Jenkins run on Windows ############
+
+#-------------------------------#
+# 1: ISSM general configuration #
+#-------------------------------#
+
+#Nightly run name
+NAME="ISSM matlab tests on Windows"
+
+#ISSM Architecture
+ISSM_ARCH="cygwin-intel"
+
+#ISSM CONFIGURATION 
+ISSM_CONFIG='--prefix=$ISSM_DIR \
+   --disable-static \
+	--with-vendor=intel-win7-64  \
+	--with-matlab-dir=""$ISSM_DIR/externalpackages/matlab/install"" \
+	--with-triangle-dir="$ISSM_DIR/externalpackages/triangle/install" \
+	--with-metis-dir="$ISSM_DIR/externalpackages/metis/install" \
+	--with-petsc-dir="$ISSM_DIR/externalpackages/petsc/install" \
+	--with-petsc-arch=$ISSM_ARCH  \
+	--with-blas-lapack-dir=$ISSM_DIR/externalpackages/petsc/install/lib/  \
+	--with-mpi-libdir="$ISSM_DIR/externalpackages/petsc/install/lib" \
+	--with-mpi-libflags="-Wl,libpetsc.lib" \
+	--with-mpi-include="$ISSM_DIR/externalpackages/petsc/install/include/mpiuni" \
+	--enable-development'
+
+#MATLAB path
+MATLAB_PATH="C:/MATLAB/R2013a/"
+
+#PYTHON and MATLAB testing
+MATLAB_TEST=1
+PYTHON_TEST=0
+
+#execution path used for parallel runs
+EXECUTION_PATH=$ISSM_DIR/execution
+
+#repo:
+REPOSITORY="https://issm.ess.uci.edu/svn/issm/issm/trunk-jpl"
+
+#-----------------------------------#
+# 3: External packages installation #
+#-----------------------------------#
+
+#ISSM_EXTERNALPACKAGES can have 3 values:
+# - "install" install all external packages listed below
+# - "copy"    copy existing directories (EXTERNALPACKAGESDIR)
+# - "none"    leave external packages as is
+#             ->skip to section 4
+ISSM_EXTERNALPACKAGES="install"
+EXTERNALPACKAGESDIR=$ISSM_DIR/externalpackages
+
+#List of external pakages to be installed and their installation scripts
+EXTERNALPACKAGES=" cccl install-win7.sh
+						petsc     install-3.1-win7.sh
+						triangle  install-win7.sh        
+						matlab install.sh
+						metis install-4.0-win7.sh
+						shell2junit install.sh"
+
+#---------------------#
+# 4: ISSM Compilation #
+#---------------------#
+
+#ISSM_COMPILATION can have 2 values:
+# - "yes" compile ISSM
+# - "no"  do not compile ISSM
+ISSM_COMPILATION="yes"
+
+#----------------------#
+# 5: Mail notification #
+#----------------------#
+
+#Mail delivery. If SKIPMAIL="no", the html nightly run report will be
+#sent to the adresses present in $ISSM_DIR/cron/mailinglist.
+SKIPMAIL="no"
+
+#Sender email address
+EMAIL_ADRESS="eric.larour@jpl.nasa.gov"
+
+#Mailing list
+MAILINGLIST="eric.larour@jpl.nasa.gov"
+
+#------------------------#
+# 6: Nightly run options #
+#------------------------#
+
+#number of cpus used in ISSM installation and compilation (one is usually
+#safer as some packages are very sensitive to parallel compilation)
+NUMCPUS_INSTALL=8
+
+#number of cpus used in the nightly runs.
+NUMCPUS_RUN=1
+
+#Nightly run options. The matlab routine runme.m will be called
+#as follows: runme($MATLAB_NROPTIONS). The options must be understandable
+#by Matlab and runme.m
+#ex: "'id',[101 102 103]"
+
+#In Windows, we don't yet have MUMPS, can't do full stokes, so exclude all FS runs. Also exclude all runs with Dakota. And exclude higher order runs that have penalties.
+MATLAB_NROPTIONS="'exclude',[104, 124, 204, 211, 215, 220, 221, 285, 290, 308, 322, 404, 421, 422, 503, 507, 510, 511, 701, 702, 703, 218, 234, 235, 412, 413, 414, 417, 418, 420, 205, 274, 331, 405, 409, 455, 612, 514, 435]"
+PYTHON_NROPTIONS=""
+
+
Index: /issm/trunk/m4/analyses.m4
===================================================================
--- /issm/trunk/m4/analyses.m4	(revision 17806)
+++ /issm/trunk/m4/analyses.m4	(revision 17806)
@@ -0,0 +1,433 @@
+
+dnl   WARNING: DO NOT MODIFY THIS FILE
+dnl            this file has been automatically generated by Synchronize.sh
+dnl            Please read README for more information
+
+# AX_ANALYSES_SELECTION
+# -----------------
+# Check for analyses compilation
+AC_DEFUN([AX_ANALYSES_SELECTION],
+[
+
+dnl with-AdjointBalancethickness{{{
+AC_ARG_WITH([AdjointBalancethickness],
+	AS_HELP_STRING([--with-AdjointBalancethickness = YES], [compile with AdjointBalancethickness capabilities (default is yes)]),
+	[ADJOINTBALANCETHICKNESS=$withval],[ADJOINTBALANCETHICKNESS=yes])
+AC_MSG_CHECKING(for AdjointBalancethickness capability compilation)
+
+HAVE_ADJOINTBALANCETHICKNESS=no 
+if test "x$ADJOINTBALANCETHICKNESS" = "xyes"; then
+	HAVE_ADJOINTBALANCETHICKNESS=yes
+	AC_DEFINE([_HAVE_ADJOINTBALANCETHICKNESS_],[1],[with AdjointBalancethicknesscapability])
+fi
+AM_CONDITIONAL([ADJOINTBALANCETHICKNESS], [test x$HAVE_ADJOINTBALANCETHICKNESS = xyes])
+AC_MSG_RESULT($HAVE_ADJOINTBALANCETHICKNESS)
+dnl }}}
+dnl with-AdjointHoriz{{{
+AC_ARG_WITH([AdjointHoriz],
+	AS_HELP_STRING([--with-AdjointHoriz = YES], [compile with AdjointHoriz capabilities (default is yes)]),
+	[ADJOINTHORIZ=$withval],[ADJOINTHORIZ=yes])
+AC_MSG_CHECKING(for AdjointHoriz capability compilation)
+
+HAVE_ADJOINTHORIZ=no 
+if test "x$ADJOINTHORIZ" = "xyes"; then
+	HAVE_ADJOINTHORIZ=yes
+	AC_DEFINE([_HAVE_ADJOINTHORIZ_],[1],[with AdjointHorizcapability])
+fi
+AM_CONDITIONAL([ADJOINTHORIZ], [test x$HAVE_ADJOINTHORIZ = xyes])
+AC_MSG_RESULT($HAVE_ADJOINTHORIZ)
+dnl }}}
+dnl with-Balancethickness{{{
+AC_ARG_WITH([Balancethickness],
+	AS_HELP_STRING([--with-Balancethickness = YES], [compile with Balancethickness capabilities (default is yes)]),
+	[BALANCETHICKNESS=$withval],[BALANCETHICKNESS=yes])
+AC_MSG_CHECKING(for Balancethickness capability compilation)
+
+HAVE_BALANCETHICKNESS=no 
+if test "x$BALANCETHICKNESS" = "xyes"; then
+	HAVE_BALANCETHICKNESS=yes
+	AC_DEFINE([_HAVE_BALANCETHICKNESS_],[1],[with Balancethicknesscapability])
+fi
+AM_CONDITIONAL([BALANCETHICKNESS], [test x$HAVE_BALANCETHICKNESS = xyes])
+AC_MSG_RESULT($HAVE_BALANCETHICKNESS)
+dnl }}}
+dnl with-BalancethicknessSoft{{{
+AC_ARG_WITH([BalancethicknessSoft],
+	AS_HELP_STRING([--with-BalancethicknessSoft = YES], [compile with BalancethicknessSoft capabilities (default is yes)]),
+	[BALANCETHICKNESSSOFT=$withval],[BALANCETHICKNESSSOFT=yes])
+AC_MSG_CHECKING(for BalancethicknessSoft capability compilation)
+
+HAVE_BALANCETHICKNESSSOFT=no 
+if test "x$BALANCETHICKNESSSOFT" = "xyes"; then
+	HAVE_BALANCETHICKNESSSOFT=yes
+	AC_DEFINE([_HAVE_BALANCETHICKNESSSOFT_],[1],[with BalancethicknessSoftcapability])
+fi
+AM_CONDITIONAL([BALANCETHICKNESSSOFT], [test x$HAVE_BALANCETHICKNESSSOFT = xyes])
+AC_MSG_RESULT($HAVE_BALANCETHICKNESSSOFT)
+dnl }}}
+dnl with-Balancevelocity{{{
+AC_ARG_WITH([Balancevelocity],
+	AS_HELP_STRING([--with-Balancevelocity = YES], [compile with Balancevelocity capabilities (default is yes)]),
+	[BALANCEVELOCITY=$withval],[BALANCEVELOCITY=yes])
+AC_MSG_CHECKING(for Balancevelocity capability compilation)
+
+HAVE_BALANCEVELOCITY=no 
+if test "x$BALANCEVELOCITY" = "xyes"; then
+	HAVE_BALANCEVELOCITY=yes
+	AC_DEFINE([_HAVE_BALANCEVELOCITY_],[1],[with Balancevelocitycapability])
+fi
+AM_CONDITIONAL([BALANCEVELOCITY], [test x$HAVE_BALANCEVELOCITY = xyes])
+AC_MSG_RESULT($HAVE_BALANCEVELOCITY)
+dnl }}}
+dnl with-L2ProjectionEPL{{{
+AC_ARG_WITH([L2ProjectionEPL],
+	AS_HELP_STRING([--with-L2ProjectionEPL = YES], [compile with L2ProjectionEPL capabilities (default is yes)]),
+	[L2PROJECTIONEPL=$withval],[L2PROJECTIONEPL=yes])
+AC_MSG_CHECKING(for L2ProjectionEPL capability compilation)
+
+HAVE_L2PROJECTIONEPL=no 
+if test "x$L2PROJECTIONEPL" = "xyes"; then
+	HAVE_L2PROJECTIONEPL=yes
+	AC_DEFINE([_HAVE_L2PROJECTIONEPL_],[1],[with L2ProjectionEPLcapability])
+fi
+AM_CONDITIONAL([L2PROJECTIONEPL], [test x$HAVE_L2PROJECTIONEPL = xyes])
+AC_MSG_RESULT($HAVE_L2PROJECTIONEPL)
+dnl }}}
+dnl with-L2ProjectionBase{{{
+AC_ARG_WITH([L2ProjectionBase],
+	AS_HELP_STRING([--with-L2ProjectionBase = YES], [compile with L2ProjectionBase capabilities (default is yes)]),
+	[L2PROJECTIONBASE=$withval],[L2PROJECTIONBASE=yes])
+AC_MSG_CHECKING(for L2ProjectionBase capability compilation)
+
+HAVE_L2PROJECTIONBASE=no 
+if test "x$L2PROJECTIONBASE" = "xyes"; then
+	HAVE_L2PROJECTIONBASE=yes
+	AC_DEFINE([_HAVE_L2PROJECTIONBASE_],[1],[with L2ProjectionBasecapability])
+fi
+AM_CONDITIONAL([L2PROJECTIONBASE], [test x$HAVE_L2PROJECTIONBASE = xyes])
+AC_MSG_RESULT($HAVE_L2PROJECTIONBASE)
+dnl }}}
+dnl with-DamageEvolution{{{
+AC_ARG_WITH([DamageEvolution],
+	AS_HELP_STRING([--with-DamageEvolution = YES], [compile with DamageEvolution capabilities (default is yes)]),
+	[DAMAGEEVOLUTION=$withval],[DAMAGEEVOLUTION=yes])
+AC_MSG_CHECKING(for DamageEvolution capability compilation)
+
+HAVE_DAMAGEEVOLUTION=no 
+if test "x$DAMAGEEVOLUTION" = "xyes"; then
+	HAVE_DAMAGEEVOLUTION=yes
+	AC_DEFINE([_HAVE_DAMAGEEVOLUTION_],[1],[with DamageEvolutioncapability])
+fi
+AM_CONDITIONAL([DAMAGEEVOLUTION], [test x$HAVE_DAMAGEEVOLUTION = xyes])
+AC_MSG_RESULT($HAVE_DAMAGEEVOLUTION)
+dnl }}}
+dnl with-Stressbalance{{{
+AC_ARG_WITH([Stressbalance],
+	AS_HELP_STRING([--with-Stressbalance = YES], [compile with Stressbalance capabilities (default is yes)]),
+	[STRESSBALANCE=$withval],[STRESSBALANCE=yes])
+AC_MSG_CHECKING(for Stressbalance capability compilation)
+
+HAVE_STRESSBALANCE=no 
+if test "x$STRESSBALANCE" = "xyes"; then
+	HAVE_STRESSBALANCE=yes
+	AC_DEFINE([_HAVE_STRESSBALANCE_],[1],[with Stressbalancecapability])
+fi
+AM_CONDITIONAL([STRESSBALANCE], [test x$HAVE_STRESSBALANCE = xyes])
+AC_MSG_RESULT($HAVE_STRESSBALANCE)
+dnl }}}
+dnl with-StressbalanceSIA{{{
+AC_ARG_WITH([StressbalanceSIA],
+	AS_HELP_STRING([--with-StressbalanceSIA = YES], [compile with StressbalanceSIA capabilities (default is yes)]),
+	[STRESSBALANCESIA=$withval],[STRESSBALANCESIA=yes])
+AC_MSG_CHECKING(for StressbalanceSIA capability compilation)
+
+HAVE_STRESSBALANCESIA=no 
+if test "x$STRESSBALANCESIA" = "xyes"; then
+	HAVE_STRESSBALANCESIA=yes
+	AC_DEFINE([_HAVE_STRESSBALANCESIA_],[1],[with StressbalanceSIAcapability])
+fi
+AM_CONDITIONAL([STRESSBALANCESIA], [test x$HAVE_STRESSBALANCESIA = xyes])
+AC_MSG_RESULT($HAVE_STRESSBALANCESIA)
+dnl }}}
+dnl with-StressbalanceVertical{{{
+AC_ARG_WITH([StressbalanceVertical],
+	AS_HELP_STRING([--with-StressbalanceVertical = YES], [compile with StressbalanceVertical capabilities (default is yes)]),
+	[STRESSBALANCEVERTICAL=$withval],[STRESSBALANCEVERTICAL=yes])
+AC_MSG_CHECKING(for StressbalanceVertical capability compilation)
+
+HAVE_STRESSBALANCEVERTICAL=no 
+if test "x$STRESSBALANCEVERTICAL" = "xyes"; then
+	HAVE_STRESSBALANCEVERTICAL=yes
+	AC_DEFINE([_HAVE_STRESSBALANCEVERTICAL_],[1],[with StressbalanceVerticalcapability])
+fi
+AM_CONDITIONAL([STRESSBALANCEVERTICAL], [test x$HAVE_STRESSBALANCEVERTICAL = xyes])
+AC_MSG_RESULT($HAVE_STRESSBALANCEVERTICAL)
+dnl }}}
+dnl with-Enthalpy{{{
+AC_ARG_WITH([Enthalpy],
+	AS_HELP_STRING([--with-Enthalpy = YES], [compile with Enthalpy capabilities (default is yes)]),
+	[ENTHALPY=$withval],[ENTHALPY=yes])
+AC_MSG_CHECKING(for Enthalpy capability compilation)
+
+HAVE_ENTHALPY=no 
+if test "x$ENTHALPY" = "xyes"; then
+	HAVE_ENTHALPY=yes
+	AC_DEFINE([_HAVE_ENTHALPY_],[1],[with Enthalpycapability])
+fi
+AM_CONDITIONAL([ENTHALPY], [test x$HAVE_ENTHALPY = xyes])
+AC_MSG_RESULT($HAVE_ENTHALPY)
+dnl }}}
+dnl with-HydrologyShreve{{{
+AC_ARG_WITH([HydrologyShreve],
+	AS_HELP_STRING([--with-HydrologyShreve = YES], [compile with HydrologyShreve capabilities (default is yes)]),
+	[HYDROLOGYSHREVE=$withval],[HYDROLOGYSHREVE=yes])
+AC_MSG_CHECKING(for HydrologyShreve capability compilation)
+
+HAVE_HYDROLOGYSHREVE=no 
+if test "x$HYDROLOGYSHREVE" = "xyes"; then
+	HAVE_HYDROLOGYSHREVE=yes
+	AC_DEFINE([_HAVE_HYDROLOGYSHREVE_],[1],[with HydrologyShrevecapability])
+fi
+AM_CONDITIONAL([HYDROLOGYSHREVE], [test x$HAVE_HYDROLOGYSHREVE = xyes])
+AC_MSG_RESULT($HAVE_HYDROLOGYSHREVE)
+dnl }}}
+dnl with-HydrologyDCInefficient{{{
+AC_ARG_WITH([HydrologyDCInefficient],
+	AS_HELP_STRING([--with-HydrologyDCInefficient = YES], [compile with HydrologyDCInefficient capabilities (default is yes)]),
+	[HYDROLOGYDCINEFFICIENT=$withval],[HYDROLOGYDCINEFFICIENT=yes])
+AC_MSG_CHECKING(for HydrologyDCInefficient capability compilation)
+
+HAVE_HYDROLOGYDCINEFFICIENT=no 
+if test "x$HYDROLOGYDCINEFFICIENT" = "xyes"; then
+	HAVE_HYDROLOGYDCINEFFICIENT=yes
+	AC_DEFINE([_HAVE_HYDROLOGYDCINEFFICIENT_],[1],[with HydrologyDCInefficientcapability])
+fi
+AM_CONDITIONAL([HYDROLOGYDCINEFFICIENT], [test x$HAVE_HYDROLOGYDCINEFFICIENT = xyes])
+AC_MSG_RESULT($HAVE_HYDROLOGYDCINEFFICIENT)
+dnl }}}
+dnl with-HydrologyDCEfficient{{{
+AC_ARG_WITH([HydrologyDCEfficient],
+	AS_HELP_STRING([--with-HydrologyDCEfficient = YES], [compile with HydrologyDCEfficient capabilities (default is yes)]),
+	[HYDROLOGYDCEFFICIENT=$withval],[HYDROLOGYDCEFFICIENT=yes])
+AC_MSG_CHECKING(for HydrologyDCEfficient capability compilation)
+
+HAVE_HYDROLOGYDCEFFICIENT=no 
+if test "x$HYDROLOGYDCEFFICIENT" = "xyes"; then
+	HAVE_HYDROLOGYDCEFFICIENT=yes
+	AC_DEFINE([_HAVE_HYDROLOGYDCEFFICIENT_],[1],[with HydrologyDCEfficientcapability])
+fi
+AM_CONDITIONAL([HYDROLOGYDCEFFICIENT], [test x$HAVE_HYDROLOGYDCEFFICIENT = xyes])
+AC_MSG_RESULT($HAVE_HYDROLOGYDCEFFICIENT)
+dnl }}}
+dnl with-Melting{{{
+AC_ARG_WITH([Melting],
+	AS_HELP_STRING([--with-Melting = YES], [compile with Melting capabilities (default is yes)]),
+	[MELTING=$withval],[MELTING=yes])
+AC_MSG_CHECKING(for Melting capability compilation)
+
+HAVE_MELTING=no 
+if test "x$MELTING" = "xyes"; then
+	HAVE_MELTING=yes
+	AC_DEFINE([_HAVE_MELTING_],[1],[with Meltingcapability])
+fi
+AM_CONDITIONAL([MELTING], [test x$HAVE_MELTING = xyes])
+AC_MSG_RESULT($HAVE_MELTING)
+dnl }}}
+dnl with-Masstransport{{{
+AC_ARG_WITH([Masstransport],
+	AS_HELP_STRING([--with-Masstransport = YES], [compile with Masstransport capabilities (default is yes)]),
+	[MASSTRANSPORT=$withval],[MASSTRANSPORT=yes])
+AC_MSG_CHECKING(for Masstransport capability compilation)
+
+HAVE_MASSTRANSPORT=no 
+if test "x$MASSTRANSPORT" = "xyes"; then
+	HAVE_MASSTRANSPORT=yes
+	AC_DEFINE([_HAVE_MASSTRANSPORT_],[1],[with Masstransportcapability])
+fi
+AM_CONDITIONAL([MASSTRANSPORT], [test x$HAVE_MASSTRANSPORT = xyes])
+AC_MSG_RESULT($HAVE_MASSTRANSPORT)
+dnl }}}
+dnl with-FreeSurfaceBase{{{
+AC_ARG_WITH([FreeSurfaceBase],
+	AS_HELP_STRING([--with-FreeSurfaceBase = YES], [compile with FreeSurfaceBase capabilities (default is yes)]),
+	[FREESURFACEBASE=$withval],[FREESURFACEBASE=yes])
+AC_MSG_CHECKING(for FreeSurfaceBase capability compilation)
+
+HAVE_FREESURFACEBASE=no 
+if test "x$FREESURFACEBASE" = "xyes"; then
+	HAVE_FREESURFACEBASE=yes
+	AC_DEFINE([_HAVE_FREESURFACEBASE_],[1],[with FreeSurfaceBasecapability])
+fi
+AM_CONDITIONAL([FREESURFACEBASE], [test x$HAVE_FREESURFACEBASE = xyes])
+AC_MSG_RESULT($HAVE_FREESURFACEBASE)
+dnl }}}
+dnl with-FreeSurfaceTop{{{
+AC_ARG_WITH([FreeSurfaceTop],
+	AS_HELP_STRING([--with-FreeSurfaceTop = YES], [compile with FreeSurfaceTop capabilities (default is yes)]),
+	[FREESURFACETOP=$withval],[FREESURFACETOP=yes])
+AC_MSG_CHECKING(for FreeSurfaceTop capability compilation)
+
+HAVE_FREESURFACETOP=no 
+if test "x$FREESURFACETOP" = "xyes"; then
+	HAVE_FREESURFACETOP=yes
+	AC_DEFINE([_HAVE_FREESURFACETOP_],[1],[with FreeSurfaceTopcapability])
+fi
+AM_CONDITIONAL([FREESURFACETOP], [test x$HAVE_FREESURFACETOP = xyes])
+AC_MSG_RESULT($HAVE_FREESURFACETOP)
+dnl }}}
+dnl with-ExtrudeFromBase{{{
+AC_ARG_WITH([ExtrudeFromBase],
+	AS_HELP_STRING([--with-ExtrudeFromBase = YES], [compile with ExtrudeFromBase capabilities (default is yes)]),
+	[EXTRUDEFROMBASE=$withval],[EXTRUDEFROMBASE=yes])
+AC_MSG_CHECKING(for ExtrudeFromBase capability compilation)
+
+HAVE_EXTRUDEFROMBASE=no 
+if test "x$EXTRUDEFROMBASE" = "xyes"; then
+	HAVE_EXTRUDEFROMBASE=yes
+	AC_DEFINE([_HAVE_EXTRUDEFROMBASE_],[1],[with ExtrudeFromBasecapability])
+fi
+AM_CONDITIONAL([EXTRUDEFROMBASE], [test x$HAVE_EXTRUDEFROMBASE = xyes])
+AC_MSG_RESULT($HAVE_EXTRUDEFROMBASE)
+dnl }}}
+dnl with-ExtrudeFromTop{{{
+AC_ARG_WITH([ExtrudeFromTop],
+	AS_HELP_STRING([--with-ExtrudeFromTop = YES], [compile with ExtrudeFromTop capabilities (default is yes)]),
+	[EXTRUDEFROMTOP=$withval],[EXTRUDEFROMTOP=yes])
+AC_MSG_CHECKING(for ExtrudeFromTop capability compilation)
+
+HAVE_EXTRUDEFROMTOP=no 
+if test "x$EXTRUDEFROMTOP" = "xyes"; then
+	HAVE_EXTRUDEFROMTOP=yes
+	AC_DEFINE([_HAVE_EXTRUDEFROMTOP_],[1],[with ExtrudeFromTopcapability])
+fi
+AM_CONDITIONAL([EXTRUDEFROMTOP], [test x$HAVE_EXTRUDEFROMTOP = xyes])
+AC_MSG_RESULT($HAVE_EXTRUDEFROMTOP)
+dnl }}}
+dnl with-DepthAverage{{{
+AC_ARG_WITH([DepthAverage],
+	AS_HELP_STRING([--with-DepthAverage = YES], [compile with DepthAverage capabilities (default is yes)]),
+	[DEPTHAVERAGE=$withval],[DEPTHAVERAGE=yes])
+AC_MSG_CHECKING(for DepthAverage capability compilation)
+
+HAVE_DEPTHAVERAGE=no 
+if test "x$DEPTHAVERAGE" = "xyes"; then
+	HAVE_DEPTHAVERAGE=yes
+	AC_DEFINE([_HAVE_DEPTHAVERAGE_],[1],[with DepthAveragecapability])
+fi
+AM_CONDITIONAL([DEPTHAVERAGE], [test x$HAVE_DEPTHAVERAGE = xyes])
+AC_MSG_RESULT($HAVE_DEPTHAVERAGE)
+dnl }}}
+dnl with-SmoothedSurfaceSlopeX{{{
+AC_ARG_WITH([SmoothedSurfaceSlopeX],
+	AS_HELP_STRING([--with-SmoothedSurfaceSlopeX = YES], [compile with SmoothedSurfaceSlopeX capabilities (default is yes)]),
+	[SMOOTHEDSURFACESLOPEX=$withval],[SMOOTHEDSURFACESLOPEX=yes])
+AC_MSG_CHECKING(for SmoothedSurfaceSlopeX capability compilation)
+
+HAVE_SMOOTHEDSURFACESLOPEX=no 
+if test "x$SMOOTHEDSURFACESLOPEX" = "xyes"; then
+	HAVE_SMOOTHEDSURFACESLOPEX=yes
+	AC_DEFINE([_HAVE_SMOOTHEDSURFACESLOPEX_],[1],[with SmoothedSurfaceSlopeXcapability])
+fi
+AM_CONDITIONAL([SMOOTHEDSURFACESLOPEX], [test x$HAVE_SMOOTHEDSURFACESLOPEX = xyes])
+AC_MSG_RESULT($HAVE_SMOOTHEDSURFACESLOPEX)
+dnl }}}
+dnl with-SmoothedSurfaceSlopeY{{{
+AC_ARG_WITH([SmoothedSurfaceSlopeY],
+	AS_HELP_STRING([--with-SmoothedSurfaceSlopeY = YES], [compile with SmoothedSurfaceSlopeY capabilities (default is yes)]),
+	[SMOOTHEDSURFACESLOPEY=$withval],[SMOOTHEDSURFACESLOPEY=yes])
+AC_MSG_CHECKING(for SmoothedSurfaceSlopeY capability compilation)
+
+HAVE_SMOOTHEDSURFACESLOPEY=no 
+if test "x$SMOOTHEDSURFACESLOPEY" = "xyes"; then
+	HAVE_SMOOTHEDSURFACESLOPEY=yes
+	AC_DEFINE([_HAVE_SMOOTHEDSURFACESLOPEY_],[1],[with SmoothedSurfaceSlopeYcapability])
+fi
+AM_CONDITIONAL([SMOOTHEDSURFACESLOPEY], [test x$HAVE_SMOOTHEDSURFACESLOPEY = xyes])
+AC_MSG_RESULT($HAVE_SMOOTHEDSURFACESLOPEY)
+dnl }}}
+dnl with-Thermal{{{
+AC_ARG_WITH([Thermal],
+	AS_HELP_STRING([--with-Thermal = YES], [compile with Thermal capabilities (default is yes)]),
+	[THERMAL=$withval],[THERMAL=yes])
+AC_MSG_CHECKING(for Thermal capability compilation)
+
+HAVE_THERMAL=no 
+if test "x$THERMAL" = "xyes"; then
+	HAVE_THERMAL=yes
+	AC_DEFINE([_HAVE_THERMAL_],[1],[with Thermalcapability])
+fi
+AM_CONDITIONAL([THERMAL], [test x$HAVE_THERMAL = xyes])
+AC_MSG_RESULT($HAVE_THERMAL)
+dnl }}}
+dnl with-Gia{{{
+AC_ARG_WITH([Gia],
+	AS_HELP_STRING([--with-Gia = YES], [compile with Gia capabilities (default is yes)]),
+	[GIA=$withval],[GIA=yes])
+AC_MSG_CHECKING(for Gia capability compilation)
+
+HAVE_GIA=no 
+if test "x$GIA" = "xyes"; then
+	HAVE_GIA=yes
+	AC_DEFINE([_HAVE_GIA_],[1],[with Giacapability])
+fi
+AM_CONDITIONAL([GIA], [test x$HAVE_GIA = xyes])
+AC_MSG_RESULT($HAVE_GIA)
+dnl }}}
+dnl with-Meshdeformation{{{
+AC_ARG_WITH([Meshdeformation],
+	AS_HELP_STRING([--with-Meshdeformation = YES], [compile with Meshdeformation capabilities (default is yes)]),
+	[MESHDEFORMATION=$withval],[MESHDEFORMATION=yes])
+AC_MSG_CHECKING(for Meshdeformation capability compilation)
+
+HAVE_MESHDEFORMATION=no 
+if test "x$MESHDEFORMATION" = "xyes"; then
+	HAVE_MESHDEFORMATION=yes
+	AC_DEFINE([_HAVE_MESHDEFORMATION_],[1],[with Meshdeformationcapability])
+fi
+AM_CONDITIONAL([MESHDEFORMATION], [test x$HAVE_MESHDEFORMATION = xyes])
+AC_MSG_RESULT($HAVE_MESHDEFORMATION)
+dnl }}}
+dnl with-Levelset{{{
+AC_ARG_WITH([Levelset],
+	AS_HELP_STRING([--with-Levelset = YES], [compile with Levelset capabilities (default is yes)]),
+	[LEVELSET=$withval],[LEVELSET=yes])
+AC_MSG_CHECKING(for Levelset capability compilation)
+
+HAVE_LEVELSET=no 
+if test "x$LEVELSET" = "xyes"; then
+	HAVE_LEVELSET=yes
+	AC_DEFINE([_HAVE_LEVELSET_],[1],[with Levelsetcapability])
+fi
+AM_CONDITIONAL([LEVELSET], [test x$HAVE_LEVELSET = xyes])
+AC_MSG_RESULT($HAVE_LEVELSET)
+dnl }}}
+dnl with-Extrapolation{{{
+AC_ARG_WITH([Extrapolation],
+	AS_HELP_STRING([--with-Extrapolation = YES], [compile with Extrapolation capabilities (default is yes)]),
+	[EXTRAPOLATION=$withval],[EXTRAPOLATION=yes])
+AC_MSG_CHECKING(for Extrapolation capability compilation)
+
+HAVE_EXTRAPOLATION=no 
+if test "x$EXTRAPOLATION" = "xyes"; then
+	HAVE_EXTRAPOLATION=yes
+	AC_DEFINE([_HAVE_EXTRAPOLATION_],[1],[with Extrapolationcapability])
+fi
+AM_CONDITIONAL([EXTRAPOLATION], [test x$HAVE_EXTRAPOLATION = xyes])
+AC_MSG_RESULT($HAVE_EXTRAPOLATION)
+dnl }}}
+dnl with-LsfReinitialization{{{
+AC_ARG_WITH([LsfReinitialization],
+	AS_HELP_STRING([--with-LsfReinitialization = YES], [compile with LsfReinitialization capabilities (default is yes)]),
+	[LSFREINITIALIZATION=$withval],[LSFREINITIALIZATION=yes])
+AC_MSG_CHECKING(for LsfReinitialization capability compilation)
+
+HAVE_LSFREINITIALIZATION=no 
+if test "x$LSFREINITIALIZATION" = "xyes"; then
+	HAVE_LSFREINITIALIZATION=yes
+	AC_DEFINE([_HAVE_LSFREINITIALIZATION_],[1],[with LsfReinitializationcapability])
+fi
+AM_CONDITIONAL([LSFREINITIALIZATION], [test x$HAVE_LSFREINITIALIZATION = xyes])
+AC_MSG_RESULT($HAVE_LSFREINITIALIZATION)
+dnl }}}
+
+])
Index: sm/trunk/m4/issm_options.cmake
===================================================================
--- /issm/trunk/m4/issm_options.cmake	(revision 17805)
+++ 	(revision )
@@ -1,37 +1,0 @@
-# ISSM Options {{{
-option(DAKOTA "DAKOTA" OFF)
-option(PETSC "PETSC" OFF)
-option(MUMPS "MUMPS" OFF)
-#option(GSL "GSL" OFF)
-option(TRANSIENT "TRANSIENT" ON)
-option(STEADYSTATE "STEADYSTATE" ON)
-option(PROGNOSTIC "PROGNOSTIC" ON)
-option(THERMAL "THERMAL" ON)
-option(GIA "GIA" OFF)
-option(CONTROL "CONTROL" ON)
-option(HYDROLOGY "HYDROLOGY" ON)
-option(DIAGNOSTIC "DIAGNOSTIC" ON)
-option(BALANCED "BALANCED" ON)
-option(SLOPE "SLOPE" ON)
-option(GROUNDINGLINE "GROUNDINGLINE" ON)
-option(RIFTS "RIFTS" ON)
-option(ANDROID "ANDROID" OFF)
-option(THREED "THREED" ON)
-option(MPI "MPI" OFF)
-option(METIS "METIS" OFF)
-option(KRIGING "KRIGING" OFF)
-# }}}
-
-if(NOT GSL_DIR)
-    message(FATAL_ERROR "Non GSL build not supported")
-else(NOT GSL_DIR)
-    find_path(GSL lib ${GSL_DIR})
-
-    if(GSL)
-        message("Found GSL: ${GSL_DIR}")
-        set(GSL_INC_DIR ${GSL_DIR}/include)
-        set(GSL_LIB_DIR ${GSL_DIR}/lib)
-    else(GSL)
-        message(FATAL_ERROR "GSL installation directory not found!")
-    endif(GSL)
-endif(NOT GSL_DIR)
Index: /issm/trunk/m4/issm_options.m4
===================================================================
--- /issm/trunk/m4/issm_options.m4	(revision 17805)
+++ /issm/trunk/m4/issm_options.m4	(revision 17806)
@@ -15,5 +15,5 @@
 		PACKAGE_DATE=`date`
 	else
-		PACKAGE_DATE="unknown date"
+		PACKAGE_DATE="unknown"
 	fi
 	AC_DEFINE_UNQUOTED(PACKAGE_BUILD_DATE,"$PACKAGE_DATE", Build date)
@@ -39,4 +39,7 @@
 
 	AC_MSG_CHECKING(for development support)
+	if test "x$enable_development" = xyes; then
+		AC_DEFINE([_DEVELOPMENT_],[1],[Macro to enable development version in ISSM])
+	fi
 	AM_CONDITIONAL([DEVELOPMENT], [test x$enable_development = xyes])
 	AC_MSG_RESULT($enable_development)
@@ -118,9 +121,14 @@
 			export CXXFLAGS=" -O3 -D_INTEL_LINUX_ "
 			export CFLAGS=" -O3 -D_INTEL_LINUX_ "
+		elif test $VENDOR = intel-acenet; then
+			export CC=icc
+			export CXX=icpc
+			export CXXFLAGS=" -D_INTEL_LINUX_ "
+			export CFLAGS=" -D_INTEL_LINUX_ "
 		elif test $VENDOR = intel-pleiades-gcc; then
 			export CC=gcc
 			export CXX=g++
-			export CXXFLAGS=" -g -O2 "
-			export CFLAGS=" -g -O2 "
+			export CXXFLAGS="-O3 -march=corei7-avx"
+			export CFLAGS="-O3 -march=corei7-avx"
         else
 		AC_MSG_ERROR([unknown compiler vendor!])
@@ -173,9 +181,13 @@
   			;;
 		   *)
-		      MEXLINK=$(mex -v 2>&1 < /dev/null | grep LDFLAGS     | sed -e "s/         LDFLAGS            = //g")
-	         MEXLIB=$( mex -v 2>&1 < /dev/null | grep CXXLIBS     | sed -e "s/         CXXLIBS            = //g")
-		      MEXEXT=$( mex -v 2>&1 < /dev/null | grep LDEXTENSION | sed -e "s/         LDEXTENSION        = //g")
+		      MEXLINK=$($MATLAB_ROOT/bin/mex -v 2>&1 < /dev/null | grep LDFLAGS     | sed -e "s/         LDFLAGS            = //g")
+	         MEXLIB=$( $MATLAB_ROOT/bin/mex -v 2>&1 < /dev/null | grep CXXLIBS     | sed -e "s/         CXXLIBS            = //g")
+		      MEXEXT=$( $MATLAB_ROOT/bin/mex -v 2>&1 < /dev/null | grep LDEXTENSION | sed -e "s/         LDEXTENSION        = //g")
   			;;
       esac
+	   if test "x$MEXEXT" = "x" ; then
+			AC_MSG_ERROR([Couldn't find mex... check your installation of matlab])
+	   fi
+
 		AC_SUBST([MATLABINCL])
 		AC_SUBST([MEX])
@@ -1071,4 +1083,6 @@
 		if test x$VENDOR = xintel-pleiades; then
 			MKLLIB=-L"$MKL_ROOT -lmkl_intel_lp64 -lmkl_intel_thread -lmkl_core -liomp5 -lpthread"
+		elif test x$VENDOR = xintel-acenet; then
+			MKLLIB=-L"$MKL_ROOT -lmkl_intel_lp64 -lmkl_sequential -lmkl_core -lpthread -lm"
 		else
 			MKLLIB=-L"$MKL_ROOT -lmkl -lmkl_lapack -lmkl_scalapack_ilp64 -lmkl_blacs_sgimpt_ilp64 -lguide -lpthread"
@@ -1549,9 +1563,8 @@
 	AC_MSG_CHECKING(for kml capability compilation)
 
+	HAVE_KML=no
 	if test "x$KML" = "xyes"; then
 		HAVE_KML=yes
 		AC_DEFINE([_HAVE_KML_],[1],[with kml capability])
-	else
-		HAVE_KML=no
 	fi
 	AM_CONDITIONAL([KML], [test x$HAVE_KML = xyes])
@@ -1564,288 +1577,33 @@
 	AC_MSG_CHECKING(for kriging capability compilation)
 
+	HAVE_KRIGING=no
 	if test "x$KRIGING" = "xyes"; then
 		HAVE_KRIGING=yes
 		AC_DEFINE([_HAVE_KRIGING_],[1],[with kriging capability])
-	else
-		HAVE_KRIGING=no
 	fi
 	AM_CONDITIONAL([KRIGING], [test x$HAVE_KRIGING = xyes])
 	AC_MSG_RESULT($HAVE_KRIGING)
 	dnl }}}
-	dnl with-steadystate{{{
-	AC_ARG_WITH([steadystate],
-		AS_HELP_STRING([--with-steadystate = YES],[compile with steadystate capabilities (default is yes)]),
-		[STEADYSTATE=$withval],[STEADYSTATE=yes]) 
-	AC_MSG_CHECKING(for steadystate capability compilation)
-
-	if test "x$STEADYSTATE" = "xyes"; then
-
-		dnl defaults
-		HAVE_STEADYSTATE=yes
-
-		AC_DEFINE([_HAVE_STEADYSTATE_],[1],[with steadystate capability])
-	else
-		HAVE_STEADYSTATE=no
-	fi
-	AM_CONDITIONAL([STEADYSTATE], [test x$HAVE_STEADYSTATE = xyes])
-	AC_MSG_RESULT($HAVE_STEADYSTATE)
-	dnl }}}
-	dnl with-transient{{{
-	AC_ARG_WITH([transient],
-		AS_HELP_STRING([--with-transient = YES], [compile with transient capabilities (default is yes)]),
-		[TRANSIENT=$withval],[TRANSIENT=yes]) 
-	AC_MSG_CHECKING(for transient capability compilation)
-
-	if test "x$TRANSIENT" = "xyes"; then
-
-		dnl defaults
-		HAVE_TRANSIENT=yes
-
-		AC_DEFINE([_HAVE_TRANSIENT_],[1],[with transient capability])
-	else
-		HAVE_TRANSIENT=no
-	fi
-	AM_CONDITIONAL([TRANSIENT], [test x$HAVE_TRANSIENT = xyes])
-	AC_MSG_RESULT($HAVE_TRANSIENT)
-	dnl }}}
-	dnl with-thermal{{{
-	AC_ARG_WITH([thermal],
-		AS_HELP_STRING([--with-thermal = YES], [compile with thermal capabilities (default is yes)]),
-		[THERMAL=$withval],[THERMAL=yes]) 
-	AC_MSG_CHECKING(for thermal capability compilation)
-
-	if test "x$THERMAL" = "xyes"; then
-
-		dnl defaults
-		HAVE_THERMAL=yes
-
-		AC_DEFINE([_HAVE_THERMAL_],[1],[with thermal capability])
-	else
-		HAVE_THERMAL=no
-	fi
-	AM_CONDITIONAL([THERMAL], [test x$HAVE_THERMAL = xyes])
-	AC_MSG_RESULT($HAVE_THERMAL)
-	dnl }}}
-	dnl with-masstransport{{{
-	AC_ARG_WITH([masstransport],
-		AS_HELP_STRING([--with-masstransport = YES], [compile with masstransport capabilities (default is yes)]),
-		[MASSTRANSPORT=$withval],[MASSTRANSPORT=yes]) 
-	AC_MSG_CHECKING(for masstransport capability compilation)
-
-	if test "x$MASSTRANSPORT" = "xyes"; then
-
-		dnl defaults
-		HAVE_MASSTRANSPORT=yes
-
-		AC_DEFINE([_HAVE_MASSTRANSPORT_],[1],[with masstransport capability])
-	else
-		HAVE_MASSTRANSPORT=no
-	fi
-	AM_CONDITIONAL([MASSTRANSPORT], [test x$HAVE_MASSTRANSPORT = xyes])
-	AC_MSG_RESULT($HAVE_MASSTRANSPORT)
-	dnl }}}
-	dnl with-control{{{
-	AC_ARG_WITH([control],
-		AS_HELP_STRING([--with-control = YES], [compile with control capabilities (default is yes)]),
-		[CONTROL=$withval],[CONTROL=yes]) 
-	AC_MSG_CHECKING(for control capability compilation)
-
-	if test "x$CONTROL" = "xyes"; then
-
-		dnl defaults
-		HAVE_CONTROL=yes
-
-		AC_DEFINE([_HAVE_CONTROL_],[1],[with control capability])
-	else
-		HAVE_CONTROL=no
-	fi
-	AM_CONDITIONAL([CONTROL], [test x$HAVE_CONTROL = xyes])
-	AC_MSG_RESULT($HAVE_CONTROL)
-	dnl }}}
-	dnl with-hydrology{{{
-	AC_ARG_WITH([hydrology],
-		AS_HELP_STRING([--with-hydrology = YES], [compile with hydrology capabilities (default is yes)]),
-		[HYDROLOGY=$withval],[HYDROLOGY=yes]) 
-	AC_MSG_CHECKING(for hydrology capability compilation)
-
-	if test "x$HYDROLOGY" = "xyes"; then
-
-		dnl defaults
-		HAVE_HYDROLOGY=yes
-
-		AC_DEFINE([_HAVE_HYDROLOGY_],[1],[with hydrology capability])
-	else
-		HAVE_HYDROLOGY=no
-	fi
-	AM_CONDITIONAL([HYDROLOGY], [test x$HAVE_HYDROLOGY = xyes])
-	AC_MSG_RESULT($HAVE_HYDROLOGY)
-	dnl }}}
-	dnl with-stressbalance{{{
-	AC_ARG_WITH([stressbalance],
-		AS_HELP_STRING([--with-stressbalance = YES], [compile with stressbalance capabilities (default is yes)]),
-		[STRESSBALANCE=$withval],[STRESSBALANCE=yes]) 
-	AC_MSG_CHECKING(for stressbalance capability compilation)
-
-	if test "x$STRESSBALANCE" = "xyes"; then
-
-		dnl defaults
-		HAVE_STRESSBALANCE=yes
-
-		AC_DEFINE([_HAVE_STRESSBALANCE_],[1],[with stressbalance capability])
-	else
-		HAVE_STRESSBALANCE=no
-	fi
-	AM_CONDITIONAL([STRESSBALANCE], [test x$HAVE_STRESSBALANCE = xyes])
-	AC_MSG_RESULT($HAVE_STRESSBALANCE)
-	dnl }}}
-	dnl with-balanced{{{
-	AC_ARG_WITH([balanced],
-		AS_HELP_STRING([--with-balanced = YES], [compile with balanced capabilities (default is yes)]),
-		[BALANCED=$withval],[BALANCED=yes]) 
-	AC_MSG_CHECKING(for balanced capability compilation)
-
-	if test "x$BALANCED" = "xyes"; then
-
-		dnl defaults
-		HAVE_BALANCED=yes
-
-		AC_DEFINE([_HAVE_BALANCED_],[1],[with balanced capability])
-	else
-		HAVE_BALANCED=no
-	fi
-	AM_CONDITIONAL([BALANCED], [test x$HAVE_BALANCED = xyes])
-	AC_MSG_RESULT($HAVE_BALANCED)
-	dnl }}}
-	dnl with-damage{{{
-	AC_ARG_WITH([damage],
-		AS_HELP_STRING([--with-damage = YES], [compile with damage capabilities (default is yes)]),
-		[DAMAGE=$withval],[DAMAGE=yes]) 
-	AC_MSG_CHECKING(for damage capability compilation)
-
-	if test "x$DAMAGE" = "xyes"; then
-
-		dnl defaults
-		HAVE_DAMAGE=yes
-
-		AC_DEFINE([_HAVE_DAMAGE_],[1],[with damage capability])
-	else
-		HAVE_DAMAGE=no
-	fi
-	AM_CONDITIONAL([DAMAGE], [test x$HAVE_DAMAGE = xyes])
-	AC_MSG_RESULT($HAVE_DAMAGE)
-	dnl }}}
-	dnl with-responses{{{
-	AC_ARG_WITH([responses],
-		AS_HELP_STRING([--with-responses = YES], [compile with responses capabilities (default is yes)]),
-		[RESPONSES=$withval],[RESPONSES=yes]) 
-	AC_MSG_CHECKING(for responses capability compilation)
-
-	if test "x$RESPONSES" = "xyes"; then
-
-		dnl defaults
-		HAVE_RESPONSES=yes
-
-		AC_DEFINE([_HAVE_RESPONSES_],[1],[with responses capability])
-	else
-		HAVE_RESPONSES=no
-	fi
-	AM_CONDITIONAL([RESPONSES], [test x$HAVE_RESPONSES = xyes])
-	AC_MSG_RESULT($HAVE_RESPONSES)
-	dnl }}}
-	dnl with-slope{{{
-	AC_ARG_WITH([slope],
-		AS_HELP_STRING([--with-slope = YES], [compile with slope capabilities (default is yes)]),
-		[SLOPE=$withval],[SLOPE=yes]) 
-	AC_MSG_CHECKING(for slope capability compilation)
-
-	if test "x$SLOPE" = "xyes"; then
-
-		dnl defaults
-		HAVE_SLOPE=yes
-
-		AC_DEFINE([_HAVE_SLOPE_],[1],[with slope capability])
-	else
-		HAVE_SLOPE=no
-	fi
-	AM_CONDITIONAL([SLOPE], [test x$HAVE_SLOPE = xyes])
-	AC_MSG_RESULT($HAVE_SLOPE)
-	dnl }}}
-	dnl with-meshdeformation{{{
-		AC_ARG_WITH([meshdeformation],
-					AS_HELP_STRING([--with-meshdeformation = YES], [compile with meshdeformation capabilities (default is yes)]),
-					[MESHDEFORMATION=$withval],[MESHDEFORMATION=yes]) 
-		  AC_MSG_CHECKING(for meshdeformation capability compilation)
-
-		  if test "x$MESHDEFORMATION" = "xyes"; then
-
-			dnl defaults
-			  HAVE_MESHDEFORMATION=yes
-
-			  AC_DEFINE([_HAVE_MESHDEFORMATION_],[1],[with meshdeformation capability])
-		  else
-				HAVE_MESHDEFORMATION=no
-		  fi
-	  AM_CONDITIONAL([MESHDEFORMATION], [test x$HAVE_MESHDEFORMATION = xyes])
-	  AC_MSG_RESULT($HAVE_MESHDEFORMATION)
-	  dnl }}}
-	dnl with-groundingline{{{
-	AC_ARG_WITH([groundingline],
-		AS_HELP_STRING([--with-groundingline = YES], [compile with groundingline capabilities (default is yes)]),
-		[GROUNDINGLINE=$withval],[GROUNDINGLINE=yes]) 
-	AC_MSG_CHECKING(for groundingline capability compilation)
-
-	if test "x$GROUNDINGLINE" = "xyes"; then
-
-		dnl defaults
-		HAVE_GROUNDINGLINE=yes
-
-		AC_DEFINE([_HAVE_GROUNDINGLINE_],[1],[with groundingline capability])
-	else
-		HAVE_GROUNDINGLINE=no
-	fi
-	AM_CONDITIONAL([GROUNDINGLINE], [test x$HAVE_GROUNDINGLINE = xyes])
-	AC_MSG_RESULT($HAVE_GROUNDINGLINE)
-	dnl }}}
-	dnl with-rifts{{{
-	AC_ARG_WITH([rifts],
-		AS_HELP_STRING([--with-rifts = YES], [compile with rifts capabilities (default is yes)]),
-		[RIFTS=$withval],[RIFTS=yes]) 
-	AC_MSG_CHECKING(for rifts capability compilation)
-
-	if test "x$RIFTS" = "xyes"; then
-
-		dnl defaults
-		HAVE_RIFTS=yes
-
-		AC_DEFINE([_HAVE_RIFTS_],[1],[with rifts capability])
-	else
-		HAVE_RIFTS=no
-	fi
-	AM_CONDITIONAL([RIFTS], [test x$HAVE_RIFTS = xyes])
-	AC_MSG_RESULT($HAVE_RIFTS)
-	dnl }}}
 	dnl with-gia{{{
-	AC_ARG_WITH([gia],
-		AS_HELP_STRING([--with-gia = YES], [compile with gia capabilities (default is yes)]),
+		AC_ARG_WITH([gia],
+		AS_HELP_STRING([--with-gia = YES], [compile with gia capabilities (default is no)]),
 		[GIA=$withval],[GIA=no]) 
-	AC_MSG_CHECKING(for gia capability compilation)
-
-	if test "x$GIA" = "xyes"; then
-	  
-	  if test "x$HAVE_MATH77" = "xno"; then
-		  HAVE_GIA=no
-		  AC_MSG_ERROR([gia requires compilation of math77 library! Reconfigure with --with-math77 option on]);
-	  else
-		dnl defaults
-		HAVE_GIA=yes
-		AC_DEFINE([_HAVE_GIA_],[1],[with gia capability])
-	  fi
-
-	else
+	   AC_MSG_CHECKING(for gia capability compilation)
+
 		HAVE_GIA=no
-	fi
-	AM_CONDITIONAL([GIA], [test x$HAVE_GIA = xyes])
-	AC_MSG_RESULT($HAVE_GIA)
-	dnl }}}
+		if test "x$GIA" = "xyes"; then
+			if test "x$HAVE_MATH77" = "xno"; then
+				 AC_MSG_ERROR([gia requires compilation of math77 library! Reconfigure with --with-math77 option on]);
+			else
+				HAVE_GIA=yes
+				AC_DEFINE([_HAVE_GIA_],[1],[with gia capability])
+		   fi
+		fi
+		AM_CONDITIONAL([GIA], [test x$HAVE_GIA = xyes])
+		AC_MSG_RESULT($HAVE_GIA)
+		dnl }}}
+	AX_ANALYSES_SELECTION
+
+	dnl Platform specifics
 	dnl with-ios{{{
 	AC_ARG_WITH([ios],
@@ -1911,22 +1669,4 @@
 	fi
 	AC_MSG_RESULT($HAVE_ANDROID_NDK)
-	dnl }}}
-	dnl with-3d{{{
-	AC_ARG_WITH([3d],
-		AS_HELP_STRING([--with-3d = YES], [compile with 3d capabilities (default is yes)]),
-		[THREED=$withval],[THREED=yes]) 
-	AC_MSG_CHECKING(for 3d capability compilation)
-
-	if test "x$THREED" = "xyes"; then
-
-		dnl defaults
-		HAVE_3D=yes
-
-		AC_DEFINE([_HAVE_3D_],[1],[with 3d capability])
-	else
-		HAVE_3D=no
-	fi
-	AM_CONDITIONAL([THREED], [test x$HAVE_3D = xyes])
-	AC_MSG_RESULT($HAVE_3D)
 	dnl }}}
 
@@ -1990,38 +1730,33 @@
 		  dnl check that if petsc is requested , mpi should be specified
 		  if test "$HAVE_PETSC" = "yes" ; then
-			if test "$HAVE_MPI" = "NO";  then
-			 AC_MSG_ERROR([petsc requires mpi!]);
-		fi
+				if test "$HAVE_MPI" = "NO";  then
+					 AC_MSG_ERROR([petsc requires mpi!]);
+				fi
 		  fi
 
 		  dnl check that we have either python or matlab support if we compile the modules
 		  if test "$MODULES_VALUE" = "yes"  && test "$HAVE_MATLAB" = "no" && test "$HAVE_PYTHON" = "no"; then
-			AC_MSG_ERROR([need at least python or matlab support to compile modules (or use --with-modules=no)]);
-		fi
+				AC_MSG_ERROR([need at least python or matlab support to compile modules (or use --with-modules=no)]);
+		  fi
 
 		  dnl check that if we have MPI, we have metis
 		  if test "$HAVE_METIS" = "yes"  && test "$HAVE_MPI" = "no" ; then
-			AC_MSG_ERROR([need mpi if using the metis partitioner!]);
-		fi
+				AC_MSG_ERROR([need mpi if using the metis partitioner!]);
+		  fi
 		
 		dnl check that if we run adolc, we don't compile krigging.exe
-		  if test "$HAVE_ADOLC" = "yes"  && test "$HAVE_KRIGING" = "yes" ; then
+		if test "$HAVE_ADOLC" = "yes"  && test "$HAVE_KRIGING" = "yes" ; then
 			AC_MSG_ERROR([cannot compile kriging.exe under adolc conditions!]);
 		fi
 		dnl check that if we run meteoio, we have snowpack also
-		  if test "$HAVE_METEOIO" = "yes"  && test "$HAVE_SNOWPACK" = "no" ; then
+		if test "$HAVE_METEOIO" = "yes"  && test "$HAVE_SNOWPACK" = "no" ; then
 			AC_MSG_ERROR([cannot compile MeteoIO package without Snowpack!]);
 		fi
 		dnl check that if we run snowpack, we have meteoio also
-		  if test "$HAVE_METEOIO" = "no"  && test "$HAVE_SNOWPACK" = "yes" ; then
+		if test "$HAVE_METEOIO" = "no"  && test "$HAVE_SNOWPACK" = "yes" ; then
 			AC_MSG_ERROR([cannot compile Snowpack package without MeteoIO!]);
 		fi
 
-
-
-
-
-
-		  AC_MSG_RESULT(done)
-		  dnl }}}
+		AC_MSG_RESULT(done)
+		dnl }}}
 ])
Index: /issm/trunk/packagers/win7/package32.sh
===================================================================
--- /issm/trunk/packagers/win7/package32.sh	(revision 17805)
+++ /issm/trunk/packagers/win7/package32.sh	(revision 17806)
@@ -16,5 +16,5 @@
 END
 
-ls $ISSM_DIR_WIN/scripts/*.bat startup.m $ISSM_DIR_WIN/bin/*.h | awk '{printf("AddFile APPDIR %s\n",$1);}' | sed 's/\//\\/g' >> ISSM.aic
+ls $ISSM_DIR_WIN/scripts/*.bat startup.m  | awk '{printf("AddFile APPDIR %s\n",$1);}' | sed 's/\//\\/g' >> ISSM.aic
 
 cat << END >> ISSM.aic
@@ -33,5 +33,5 @@
 
 #Run installer: 
-"C:/Program Files (x86)/Caphyon/Advanced Installer 10.1/bin/x86/AdvancedInstaller.com" /execute  ./ISSM.aip ./ISSM.aic
+"C:/Program Files (x86)/Caphyon/Advanced Installer 10.8/bin/x86/AdvancedInstaller.com" /execute  ./ISSM.aip ./ISSM.aic
 
 #Get rid of temporary files: 
Index: /issm/trunk/packagers/win7/package64.sh
===================================================================
--- /issm/trunk/packagers/win7/package64.sh	(revision 17805)
+++ /issm/trunk/packagers/win7/package64.sh	(revision 17806)
@@ -19,5 +19,5 @@
 END
 
-ls $ISSM_DIR_WIN/scripts/*.bat startup.m $ISSM_DIR_WIN/bin/*.h | awk '{printf("AddFile APPDIR %s\n",$1);}' | sed 's/\//\\/g' >> ISSM.aic
+ls $ISSM_DIR_WIN/scripts/*.bat startup.m | awk '{printf("AddFile APPDIR %s\n",$1);}' | sed 's/\//\\/g' >> ISSM.aic
 
 cat << END >> ISSM.aic
@@ -38,5 +38,5 @@
 
 #Run installer: 
-"C:/Program Files (x86)/Caphyon/Advanced Installer 10.1/bin/x86/AdvancedInstaller.com" /execute  ./ISSM.aip ./ISSM.aic
+"C:/Program Files (x86)/Caphyon/Advanced Installer 10.8/bin/x86/AdvancedInstaller.com" /execute  ./ISSM.aip ./ISSM.aic
 
 #Get rid of temporary files: 
@@ -44,5 +44,4 @@
 rm -rf ISSM.aip ISSM-SetupFiles ISSM.aic
 
-#Upload?: 
+#To upload to website: 
 #scp ISSM.msi websites:/home/larour/files/ISSM64.msi
-#cp  ISSM.msi /cygrdive/z/Desktop/ISSM64.msi
Index: /issm/trunk/packagers/win7/startup.m
===================================================================
--- /issm/trunk/packagers/win7/startup.m	(revision 17805)
+++ /issm/trunk/packagers/win7/startup.m	(revision 17806)
@@ -25,4 +25,5 @@
 addpath(pwd); %add current path first
 addpath([pwd '\bin']);
+addpath([pwd '\lib']);
 
 %Check on any warning messages that might indicate that the paths were not correct. 
Index: /issm/trunk/scripts/vie
===================================================================
--- /issm/trunk/scripts/vie	(revision 17805)
+++ /issm/trunk/scripts/vie	(revision 17806)
@@ -3,5 +3,5 @@
 if [ -z "$EXECUTION_DIR" ];
 then
-	EXECUTION_DIR=$ISSM_DIR/execution
+	EXECUTION_DIR="$ISSM_DIR/execution"
 fi
 
Index: /issm/trunk/scripts/vil
===================================================================
--- /issm/trunk/scripts/vil	(revision 17805)
+++ /issm/trunk/scripts/vil	(revision 17806)
@@ -2,5 +2,5 @@
 if [ -z $EXECUTION_DIR ];
 then
-	EXECUTION_DIR=$ISSM_DIR/execution
+	EXECUTION_DIR="$ISSM_DIR/execution"
 fi
 
Index: sm/trunk/src/CMakeLists.txt
===================================================================
--- /issm/trunk/src/CMakeLists.txt	(revision 17805)
+++ 	(revision )
@@ -1,8 +1,0 @@
-# Subdirectories {{{
-add_subdirectory(c)
-#add_subdirectory(m)
-#add_subdirectory(wrappers)
-#Android Dir {{{
-# add_subdirectory(android)
-#}}}
-# }}}
Index: sm/trunk/src/c/CMakeLists.txt
===================================================================
--- /issm/trunk/src/c/CMakeLists.txt	(revision 17805)
+++ 	(revision )
@@ -1,728 +1,0 @@
-# config.h {{{
-set(CPP_FLAGS -DHAVE_CONFIG_H)
-# }}}
-# Include Directory {{{
-include_directories(AFTER $ENV{ISSM_DIR}/ 
-                          $ENV{ISSM_DIR}/src/c 
-                          $ENV{ISSM_DIR}/src/c/main 
-                          $ENV{ISSM_DIR}/src/c/datastructure 
-                          $ENV{ISSM_DIR}/src/c/classes 
-                          $ENV{ISSM_DIR}/src/c/classes/Options 
-                          $ENV{ISSM_DIR}/src/c/classes/ExternalResults 
-                          $ENV{ISSM_DIR}/src/c/classes/Elements 
-                          $ENV{ISSM_DIR}/src/c/classes/Inputs 
-                          $ENV{ISSM_DIR}/src/c/classes/Materials 
-                          $ENV{ISSM_DIR}/src/c/classes/Constraints 
-                          $ENV{ISSM_DIR}/src/c/classes/Loads 
-                          $ENV{ISSM_DIR}/src/c/classes/matrix 
-                          $ENV{ISSM_DIR}/src/c/classes/Params 
-                          $ENV{ISSM_DIR}/src/c/classes/Params 
-                          $ENV{ISSM_DIR}/src/c/shared 
-                          $ENV{ISSM_DIR}/src/c/shared/MemOps 
-                          $ENV{ISSM_DIR}/src/c/shared/Matrix 
-                          $ENV{ISSM_DIR}/src/c/shared/io 
-                          $ENV{ISSM_DIR}/src/c/shared/io/Disk 
-                          $ENV{ISSM_DIR}/src/c/shared/io/Print 
-                          $ENV{ISSM_DIR}/src/c/shared/io/Comm 
-                          $ENV{ISSM_DIR}/src/c/shared/LatLong 
-                          $ENV{ISSM_DIR}/src/c/shared/Enum 
-                          $ENV{ISSM_DIR}/src/c/shared/Numerics 
-                          $ENV{ISSM_DIR}/src/c/shared/Exceptions 
-                          $ENV{ISSM_DIR}/src/c/shared/Sorting 
-                          $ENV{ISSM_DIR}/src/c/shared/Elements 
-                          $ENV{ISSM_DIR}/src/c/shared/String 
-                          $ENV{ISSM_DIR}/src/c/toolkits 
-                          $ENV{ISSM_DIR}/src/c/toolkits/metis 
-                          $ENV{ISSM_DIR}/src/c/toolkits/issm 
-                          $ENV{ISSM_DIR}/src/c/toolkits/adolc 
-                          $ENV{ISSM_DIR}/src/c/toolkits/triangle 
-                          $ENV{ISSM_DIR}/src/c/toolkits/objects 
-                          $ENV{ISSM_DIR}/src/c/modules 
-                          $ENV{ISSM_DIR}/src/c/modules/ModelProcessorx 
-                          $ENV{ISSM_DIR}/src/c/modules/ParseToolkitsOptionsx 
-                          $ENV{ISSM_DIR}/src/c/modules/NodesDofx 
-                          $ENV{ISSM_DIR}/src/c/modules/NodalValuex 
-                          $ENV{ISSM_DIR}/src/c/modules/VerticesDofx 
-                          $ENV{ISSM_DIR}/src/c/modules/VertexCoordinatesx 
-                          $ENV{ISSM_DIR}/src/c/modules/OutputResultsx 
-                          $ENV{ISSM_DIR}/src/c/modules/InputDuplicatex 
-                          $ENV{ISSM_DIR}/src/c/modules/InputScalex 
-                          $ENV{ISSM_DIR}/src/c/modules/SurfaceAreax 
-                          $ENV{ISSM_DIR}/src/c/modules/CreateNodalConstraintsx 
-                          $ENV{ISSM_DIR}/src/c/modules/UpdateDynamicConstraintsx 
-                          $ENV{ISSM_DIR}/src/c/modules/IoModelToConstraintsx 
-                          $ENV{ISSM_DIR}/src/c/modules/InputUpdateFromConstantx 
-                          $ENV{ISSM_DIR}/src/c/modules/GetSolutionFromInputsx 
-                          $ENV{ISSM_DIR}/src/c/modules/GetVectorFromInputsx 
-                          $ENV{ISSM_DIR}/src/c/modules/InputUpdateFromVectorx 
-                          $ENV{ISSM_DIR}/src/c/modules/ConfigureObjectsx 
-                          $ENV{ISSM_DIR}/src/c/modules/ComputeBasalStressx 
-                          $ENV{ISSM_DIR}/src/c/modules/ComputeStrainRatex 
-                          $ENV{ISSM_DIR}/src/c/modules/SpcNodesx 
-                          $ENV{ISSM_DIR}/src/c/modules/PositiveDegreeDayx 
-                          $ENV{ISSM_DIR}/src/c/modules/Delta18oParameterizationx 
-                          $ENV{ISSM_DIR}/src/c/modules/SmbGradientsx 
-                          $ENV{ISSM_DIR}/src/c/modules/MeshPartitionx 
-                          $ENV{ISSM_DIR}/src/c/modules/Reducevectorgtofx 
-                          $ENV{ISSM_DIR}/src/c/modules/Reduceloadx 
-                          $ENV{ISSM_DIR}/src/c/modules/ConstraintsStatex 
-                          $ENV{ISSM_DIR}/src/c/modules/ResetConstraintsx 
-                          $ENV{ISSM_DIR}/src/c/modules/ResetCoordinateSystemx 
-                          $ENV{ISSM_DIR}/src/c/modules/Solverx 
-                          $ENV{ISSM_DIR}/src/c/modules/VecMergex 
-                          $ENV{ISSM_DIR}/src/c/modules/Mergesolutionfromftogx 
-                          $ENV{ISSM_DIR}/src/c/cores 
-                          $ENV{ISSM_DIR}/src/c/solutionsequences 
-                          $ENV{ISSM_DIR}/src/c/solutionsequences)
-# }}}
-
-# Core Sources {{{
-set(core_sources   	./datastructures/DataSet.cpp
-					./classes/gauss/GaussTria.cpp
-					./classes/FemModel.cpp
-					./classes/Loads/Friction.cpp
-					./classes/Inputs/TransientInput.cpp
-					./classes/Constraints/SpcTransient.cpp
-					./classes/IndependentObject.cpp
-					./classes/DependentObject.cpp
-					./classes/DofIndexing.cpp
-					./classes/IoModel.cpp
-					./classes/Contours.cpp
-					./classes/Nodes.cpp
-					./classes/Vertices.cpp
-					./classes/Node.cpp
-					./classes/Vertex.cpp
-					./classes/Hook.cpp
-					./classes/ExternalResults/Results.cpp
-					./classes/Elements/Elements.cpp
-					./classes/Elements/ElementHook.cpp
-					./classes/Elements/Tria.cpp
-					./classes/Elements/TriaRef.cpp
-					./classes/Inputs/Inputs.cpp
-					./classes/Inputs/TriaInput.cpp
-					./classes/Inputs/BoolInput.cpp
-					./classes/Inputs/IntInput.cpp
-					./classes/Inputs/DoubleInput.cpp
-					./classes/Inputs/DatasetInput.cpp
-					./classes/Materials/Materials.cpp
-					./classes/Materials/Matice.cpp
-					./classes/Materials/Matdamageice.cpp
-					./classes/Materials/Matpar.cpp
-					./classes/Constraints/Constraints.cpp
-					./classes/Constraints/SpcStatic.cpp
-					./classes/Constraints/SpcDynamic.cpp
-					./classes/Loads/Loads.cpp
-					./classes/Loads/Penpair.cpp
-					./classes/Loads/Pengrid.cpp
-					./classes/Loads/Icefront.cpp
-					./classes/Loads/Numericalflux.cpp
-					./classes/matrix/ElementMatrix.cpp
-					./classes/matrix/ElementVector.cpp
-					./classes/Params/Parameters.cpp
-					./classes/Params/BoolParam.cpp
-					./classes/Params/IntParam.cpp
-					./classes/Params/IntVecParam.cpp
-					./classes/Params/IntMatParam.cpp
-					./classes/Params/DoubleParam.cpp
-					./classes/Params/FileParam.cpp
-					./classes/Params/StringArrayParam.cpp
-					./classes/Params/DoubleMatParam.cpp
-					./classes/Params/DoubleTransientMatParam.cpp
-					./classes/Params/DoubleMatArrayParam.cpp
-					./classes/Params/DoubleVecParam.cpp
-					./classes/Params/StringParam.cpp
-					./classes/Params/MatrixParam.cpp
-					./classes/Params/VectorParam.cpp
-					./classes/Params/TransientParam.cpp
-					./classes/Params/DataSetParam.cpp
-					./classes/Profiler.cpp
-					./shared/Matrix/MatrixUtils.cpp
-					./shared/io/Disk/pfopen.cpp
-					./shared/io/Disk/pfclose.cpp
-					./shared/io/Disk/WriteLockFile.cpp
-					./shared/io/Print/PrintfFunction.cpp
-					./shared/io/Comm/IssmComm.cpp
-					./shared/LatLong/Ll2xyx.cpp
-					./shared/LatLong/Xy2llx.cpp
-					./shared/Enum/EnumToStringx.cpp
-					./shared/Enum/StringToEnumx.cpp
-					./shared/Numerics/Verbosity.cpp
-					./shared/Numerics/GaussPoints.cpp
-					./shared/Numerics/cross.cpp
-					./shared/Numerics/isnan.cpp
-					./shared/Numerics/cubic.cpp
-					./shared/Numerics/extrema.cpp
-					./shared/Numerics/XZvectorsToCoordinateSystem.cpp
-					./shared/Exceptions/Exceptions.cpp
-					./shared/Exceptions/exprintf.cpp
-					./shared/Sorting/binary_search.cpp
-					./shared/Elements/Paterson.cpp
-					./shared/Elements/Arrhenius.cpp
-					./shared/Elements/PrintArrays.cpp
-					./shared/Elements/PddSurfaceMassBalance.cpp
-					./shared/Elements/ComputeDelta18oTemperaturePrecipitation.cpp
-					./shared/String/DescriptorIndex.cpp
-					./toolkits/issm/IssmToolkitUtils.cpp
-					./toolkits/issm/IssmSolver.cpp
-					./toolkits/ToolkitOptions.cpp
-					./modules/ModelProcessorx/ModelProcessorx.cpp
-					./modules/ModelProcessorx/ElementsAndVerticesPartitioning.cpp
-					./modules/ModelProcessorx/NodesPartitioning.cpp
-					./modules/ModelProcessorx/EdgesPartitioning.cpp
-					./modules/ModelProcessorx/SortDataSets.cpp
-					./modules/ModelProcessorx/UpdateCounters.cpp
-					./modules/ModelProcessorx/CreateDataSets.cpp
-					./modules/ModelProcessorx/CreateParameters.cpp
-					./modules/ModelProcessorx/Autodiff/CreateParametersAutodiff.cpp
-					./modules/ModelProcessorx/CreateEdges.cpp
-					./modules/ModelProcessorx/CreateElementToEdgeConnectivity.cpp
-					./modules/ModelProcessorx/CreateSingleNodeToElementConnectivity.cpp
-					./modules/ModelProcessorx/CreateNumberNodeToElementConnectivity.cpp
-					./modules/ModelProcessorx/CreateElementsVerticesAndMaterials.cpp
-					./modules/ModelProcessorx/CreateNodes.cpp
-					./modules/ParseToolkitsOptionsx/ParseToolkitsOptionsx.cpp
-					./modules/NodesDofx/NodesDofx.cpp
-					./modules/NodalValuex/NodalValuex.cpp
-					./modules/VerticesDofx/VerticesDofx.cpp
-					./modules/VertexCoordinatesx/VertexCoordinatesx.cpp
-					./modules/OutputResultsx/OutputResultsx.cpp
-					./modules/InputDuplicatex/InputDuplicatex.cpp
-					./modules/InputScalex/InputScalex.cpp
-					./modules/SurfaceAreax/SurfaceAreax.cpp
-					./modules/CreateNodalConstraintsx/CreateNodalConstraintsx.cpp
-					./modules/UpdateDynamicConstraintsx/UpdateDynamicConstraintsx.cpp
-					./modules/IoModelToConstraintsx/IoModelToConstraintsx.cpp
-					./modules/InputUpdateFromConstantx/InputUpdateFromConstantx.cpp
-					./modules/InputUpdateFromSolutionx/InputUpdateFromSolutionx.cpp
-					./modules/GetSolutionFromInputsx/GetSolutionFromInputsx.cpp
-					./modules/GetVectorFromInputsx/GetVectorFromInputsx.cpp
-					./modules/InputUpdateFromVectorx/InputUpdateFromVectorx.cpp
-					./modules/ConfigureObjectsx/ConfigureObjectsx.cpp
-					./modules/ComputeBasalStressx/ComputeBasalStressx.cpp
-					./modules/ComputeStrainRatex/ComputeStrainRatex.cpp
-					./modules/SpcNodesx/SpcNodesx.cpp
-					./modules/PositiveDegreeDayx/PositiveDegreeDayx.cpp
-					./modules/Delta18oParameterizationx/Delta18oParameterizationx.cpp
-					./modules/SmbGradientsx/SmbGradientsx.cpp
-					./modules/Reducevectorgtofx/Reducevectorgtofx.cpp
-					./modules/Reduceloadx/Reduceloadx.cpp
-					./modules/ConstraintsStatex/ConstraintsStatex.cpp
-					./modules/ResetConstraintsx/ResetConstraintsx.cpp
-					./modules/ResetCoordinateSystemx/ResetCoordinateSystemx.cpp
-					./modules/Solverx/Solverx.cpp
-					./modules/VecMergex/VecMergex.cpp
-					./modules/Mergesolutionfromftogx/Mergesolutionfromftogx.cpp
-					./cores/ProcessArguments.cpp
-					./cores/ResetBoundaryConditions.cpp
-					./cores/AnalysisConfiguration.cpp
-					./cores/WrapperCorePointerFromSolutionEnum.cpp
-					./cores/CorePointerFromSolutionEnum.cpp
-					./cores/EnvironmentInit.cpp
-					./cores/EnvironmentFinalize.cpp
-					./cores/ad_core.cpp
-					./solutionsequences/solutionsequence_linear.cpp
-					./solutionsequences/solutionsequence_nonlinear.cpp
-					./solutionsequences/solutionsequence_newton.cpp
-					./solutionsequences/convergence.cpp
-					./classes/Options/Options.cpp
-					./classes/Options/OptionUtilities.cpp
-					./classes/RiftStruct.cpp)
-set(issm_sources ${core_sources})
-# }}}
-
-# DAKOTA sources  {{{
-set(dakota_sources 				  ./modules/InputUpdateFromDakotax/InputUpdateFromDakotax.cpp
-					  				  ./modules/InputUpdateFromVectorDakotax/InputUpdateFromVectorDakotax.cpp
-					  				  ./modules/InputUpdateFromMatrixDakotax/InputUpdateFromMatrixDakotax.cpp
-					  ./modules/AverageOntoPartitionx/AverageOntoPartitionx.cpp
-					  				  ./modules/ModelProcessorx/Dakota/CreateParametersDakota.cpp
-					  ./cores/dakota_core.cpp
-					  				  ./cores/DakotaSpawnCore.cpp)
-#}}}
-#Transient sources  {{{
-set(transient_sources ./modules/ModelProcessorx/Transient/UpdateElementsTransient.cpp 
-							./cores/transient_core.cpp)
-#}}}
-#Steadystate sources  {{{
-set(steadystate_sources ./cores/steadystate_core.cpp)
-#}}}
-#Prognostic sources  {{{
-set(prognostic_sources ./modules/ModelProcessorx/Prognostic/UpdateElementsPrognostic.cpp
-					      ./modules/ModelProcessorx/Prognostic/CreateNodesPrognostic.cpp
-					      ./modules/ModelProcessorx/Prognostic/CreateConstraintsPrognostic.cpp
-					      ./modules/ModelProcessorx/Prognostic/CreateLoadsPrognostic.cpp
-							./cores/prognostic_core.cpp)
-#}}}
-#Thermal sources  {{{
-set(thermal_sources ./modules/ModelProcessorx/Thermal/UpdateElementsThermal.cpp
-					   ./modules/ModelProcessorx/Thermal/CreateNodesThermal.cpp
-					   ./modules/ModelProcessorx/Thermal/CreateConstraintsThermal.cpp
-					   ./modules/ModelProcessorx/Thermal/CreateLoadsThermal.cpp
-					   ./modules/ModelProcessorx/Enthalpy/UpdateElementsEnthalpy.cpp
-					   ./modules/ModelProcessorx/Enthalpy/CreateNodesEnthalpy.cpp
-					   ./modules/ModelProcessorx/Enthalpy/CreateConstraintsEnthalpy.cpp
-					   ./modules/ModelProcessorx/Enthalpy/CreateLoadsEnthalpy.cpp
-					   ./modules/ModelProcessorx/Melting/UpdateElementsMelting.cpp
-					   ./modules/ModelProcessorx/Melting/CreateNodesMelting.cpp
-					   ./modules/ModelProcessorx/Melting/CreateConstraintsMelting.cpp
-					   ./modules/ModelProcessorx/Melting/CreateLoadsMelting.cpp
-					   ./modules/ConstraintsStatex/ThermalConstraintsState.cpp
-					   ./modules/ConstraintsStatex/ThermalIsPresent.cpp
-					   ./modules/ResetConstraintsx/ThermalConstraintsReset.cpp 
-					   ./cores/thermal_core.cpp
-					   ./solutionsequences/solutionsequence_thermal_nonlinear.cpp)
-#}}}
-#Control sources  {{{
-set(control_sources ./modules/ControlInputGetGradientx/ControlInputGetGradientx.cpp
-					  				  ./modules/ControlInputSetGradientx/ControlInputSetGradientx.cpp
-					  				  ./modules/ControlInputScaleGradientx/ControlInputScaleGradientx.cpp
-					  				  ./modules/GetVectorFromControlInputsx/GetVectorFromControlInputsx.cpp
-					  				  ./modules/SetControlInputsFromVectorx/SetControlInputsFromVectorx.cpp
-					  				  ./modules/ModelProcessorx/Control/CreateParametersControl.cpp
-					  ./modules/ModelProcessorx/Control/UpdateElementsAndMaterialsControl.cpp
-					  				  ./modules/InputControlUpdatex/InputControlUpdatex.cpp
-					  				  ./modules/SurfaceAbsVelMisfitx/SurfaceAbsVelMisfitx.cpp
-					  				  ./modules/SurfaceRelVelMisfitx/SurfaceRelVelMisfitx.cpp
-					  				  ./modules/SurfaceLogVelMisfitx/SurfaceLogVelMisfitx.cpp
-					  				  ./modules/SurfaceLogVxVyMisfitx/SurfaceLogVxVyMisfitx.cpp
-					  				  ./modules/SurfaceAverageVelMisfitx/SurfaceAverageVelMisfitx.cpp
-					  				  ./modules/ThicknessAbsMisfitx/ThicknessAbsMisfitx.cpp
-					  				  ./modules/Orthx/Orthx.cpp
-					  				  ./modules/Gradjx/Gradjx.cpp
-					  ./modules/DragCoefficientAbsGradientx/DragCoefficientAbsGradientx.cpp
-					  				  ./modules/ThicknessAlongGradientx/ThicknessAlongGradientx.cpp
-					  				  ./modules/ThicknessAcrossGradientx/ThicknessAcrossGradientx.cpp
-					  				  ./modules/RheologyBbarAbsGradientx/RheologyBbarAbsGradientx.cpp
-					  				  				  ./classes/Inputs/ControlInput.cpp
-					  ./shared/Numerics/BrentSearch.cpp
-					  ./shared/Numerics/OptimalSearch.cpp 
-					  ./cores/control_core.cpp
-					  ./cores/controltao_core.cpp
-					  ./cores/objectivefunction.cpp
-					  ./cores/gradient_core.cpp
-					  ./cores/adjointdiagnostic_core.cpp
-					  ./cores/adjointbalancethickness_core.cpp
-					  ./cores/AdjointCorePointerFromSolutionEnum.cpp
-					  ./solutionsequences/solutionsequence_adjoint_linear.cpp)
-#}}}
-#Hydrology sources  {{{
-set(hydrology_sources  ./modules/ModelProcessorx/HydrologyShreve/UpdateElementsHydrologyShreve.cpp
-					      ./modules/ModelProcessorx/HydrologyShreve/CreateNodesHydrologyShreve.cpp
-					      ./modules/ModelProcessorx/HydrologyShreve/CreateConstraintsHydrologyShreve.cpp
-					      ./modules/ModelProcessorx/HydrologyShreve/CreateLoadsHydrologyShreve.cpp 
-							./modules/ModelProcessorx/HydrologyShreve/CreateParametersHydrologyShreve.cpp 
-							./modules/ModelProcessorx/HydrologyDCInefficient/UpdateElementsHydrologyDCInefficient.cpp
-							./modules/ModelProcessorx/HydrologyDCInefficient/CreateNodesHydrologyDCInefficient.cpp
-							./modules/ModelProcessorx/HydrologyDCInefficient/CreateConstraintsHydrologyDCInefficient.cpp
-							./modules/ModelProcessorx/HydrologyDCInefficient/CreateLoadsHydrologyDCInefficient.cpp 
-							./modules/ModelProcessorx/HydrologyDCInefficient/CreateParametersHydrologyDCInefficient.cpp 
-							./modules/ModelProcessorx/HydrologyDCEfficient/UpdateElementsHydrologyDCEfficient.cpp
-							./modules/ModelProcessorx/HydrologyDCEfficient/CreateNodesHydrologyDCEfficient.cpp
-							./modules/ModelProcessorx/HydrologyDCEfficient/CreateConstraintsHydrologyDCEfficient.cpp
-							./modules/ModelProcessorx/HydrologyDCEfficient/CreateLoadsHydrologyDCEfficient.cpp 
-							./modules/ModelProcessorx/HydrologyDCEfficient/CreateParametersHydrologyDCEfficient.cpp 
-							./cores/hydrology_core.cpp
-							./solutionsequences/solutionsequence_hydro_nonlinear.cpp)
-#}}}
-#Diagnostic sources  {{{
-set(diagnostic_sources ./modules/ModelProcessorx/DiagnosticHoriz/UpdateElementsDiagnosticHoriz.cpp
-					      ./modules/ModelProcessorx/DiagnosticHoriz/CreateNodesDiagnosticHoriz.cpp 
-					      ./modules/ModelProcessorx/DiagnosticHoriz/CreateConstraintsDiagnosticHoriz.cpp 
-					      ./modules/ModelProcessorx/DiagnosticHoriz/CreateLoadsDiagnosticHoriz.cpp
-					      ./modules/ModelProcessorx/DiagnosticVert/UpdateElementsDiagnosticVert.cpp
-					      ./modules/ModelProcessorx/DiagnosticVert/CreateNodesDiagnosticVert.cpp 
-					      ./modules/ModelProcessorx/DiagnosticVert/CreateConstraintsDiagnosticVert.cpp 
-					      ./modules/ModelProcessorx/DiagnosticVert/CreateLoadsDiagnosticVert.cpp
-					      ./modules/ModelProcessorx/DiagnosticHutter/UpdateElementsDiagnosticHutter.cpp
-					      ./modules/ModelProcessorx/DiagnosticHutter/CreateNodesDiagnosticHutter.cpp 
-					      ./modules/ModelProcessorx/DiagnosticHutter/CreateConstraintsDiagnosticHutter.cpp 
-							./modules/ModelProcessorx/DiagnosticHutter/CreateLoadsDiagnosticHutter.cpp 
-							./cores/diagnostic_core.cpp
-							./solutionsequences/solutionsequence_stokescoupling_nonlinear.cpp)
-#}}}
-#Balanced sources  {{{
-set(balanced_sources ./modules/ModelProcessorx/Balancethickness/UpdateElementsBalancethickness.cpp
-					    ./modules/ModelProcessorx/Balancethickness/CreateNodesBalancethickness.cpp
-					    ./modules/ModelProcessorx/Balancethickness/CreateConstraintsBalancethickness.cpp
-						 ./modules/ModelProcessorx/Balancethickness/CreateLoadsBalancethickness.cpp
-						 ./cores/balancethickness_core.cpp 
-						 ./cores/dummy_core.cpp)
-#}}}
-#Slope sources  {{{
-set(slope_sources  ./modules/ModelProcessorx/BedSlope/UpdateElementsBedSlope.cpp
-					  ./modules/ModelProcessorx/BedSlope/CreateNodesBedSlope.cpp 
-					  ./modules/ModelProcessorx/BedSlope/CreateConstraintsBedSlope.cpp
-					  ./modules/ModelProcessorx/BedSlope/CreateLoadsBedSlope.cpp
-					  ./modules/ModelProcessorx/SurfaceSlope/UpdateElementsSurfaceSlope.cpp
-					  ./modules/ModelProcessorx/SurfaceSlope/CreateNodesSurfaceSlope.cpp 
-					  ./modules/ModelProcessorx/SurfaceSlope/CreateConstraintsSurfaceSlope.cpp
-					  ./modules/ModelProcessorx/SurfaceSlope/CreateLoadsSurfaceSlope.cpp
-					  ./cores/surfaceslope_core.cpp
-					  ./cores/bedslope_core.cpp)
-#}}}
-#Gia sources  {{{
-set(gia_sources  ./cores/gia_core.cpp
-					./modules/ModelProcessorx/Gia/UpdateElementsGia.cpp
-					./modules/ModelProcessorx/Gia/CreateNodesGia.cpp 
-					./modules/ModelProcessorx/Gia/CreateConstraintsGia.cpp
-					./modules/ModelProcessorx/Gia/CreateLoadsGia.cpp
-					./modules/GiaDeflectionCorex/GiaDeflectionCorex.cpp
-									./modules/GiaDeflectionCorex/distme.f
-					./modules/GiaDeflectionCorex/freed.f
-					./modules/GiaDeflectionCorex/ojrule.f
-					./modules/GiaDeflectionCorex/pwise.f
-					./modules/GiaDeflectionCorex/qwise.f
-					./modules/GiaDeflectionCorex/stot.f
-					./modules/GiaDeflectionCorex/what0.f
-					)
-#}}}
-#Groundingline sources  {{{
-set(groundingline_sources ./modules/GroundinglineMigrationx/GroundinglineMigrationx.cpp
-					        )
-#}}}
-#Rifts sources  {{{
-set(rifts_sources ./classes/Loads/Riftfront.cpp
-				    			    ./modules/ConstraintsStatex/RiftConstraintsState.cpp)
-#}}}
-#Android sources  {{{
-set(android_sources )
-#}}}
-#3D sources  {{{
-set(threed_sources 			     ./classes/gauss/GaussPenta.cpp
-				     			     ./classes/Inputs/PentaInput.cpp
-				     			     ./classes/Elements/Penta.cpp
-				     			     ./classes/Elements/PentaRef.cpp)
-#}}}
-#Bamg sources  {{{
-set(bamg_sources  						./bamg/BamgGeom.cpp
-							./bamg/BamgMesh.cpp
-							./bamg/BamgOpts.cpp
-							./bamg/CrackedEdge.cpp
-							./bamg/Curve.cpp
-							./bamg/Direction.cpp
-										./bamg/Edge.cpp
-							./bamg/GeomEdge.cpp
-							./bamg/GeomSubDomain.cpp
-							./bamg/GeomVertex.cpp
-				./bamg/Geometry.cpp
-							./bamg/ListofIntersectionTriangles.cpp
-							./bamg/EigenMetric.cpp
-				./bamg/Metric.cpp
-							./bamg/BamgQuadtree.cpp
-										./bamg/SetOfE4.cpp
-										./bamg/SubDomain.cpp
-							./bamg/AdjacentTriangle.cpp
-				./bamg/Triangle.cpp
-				./bamg/det.h 
-							./bamg/BamgVertex.cpp
-										./bamg/VertexOnEdge.cpp
-							./bamg/VertexOnGeom.cpp
-							./bamg/VertexOnVertex.cpp
-				./bamg/Mesh.cpp
-							./shared/Bamg/Abs.h 
-							./shared/Bamg/BigPrimeNumber.cpp
-				./shared/Bamg/BinaryRand.h 
-				./shared/Bamg/Exchange.h 
-				./shared/Bamg/extrema.h 
-				./shared/Bamg/HeapSort.h 
-				./shared/Bamg/OppositeAngle.h 
-				./modules/Bamgx/Bamgx.cpp
-							./modules/BamgConvertMeshx/BamgConvertMeshx.cpp
-							./modules/BamgTriangulatex/BamgTriangulatex.cpp
-				)
-#}}}
-#Kriging sources  {{{
-set(kriging_sources 					./classes/kriging/Observations.cpp
-						./classes/kriging/Variogram.h 
-											./classes/kriging/GaussianVariogram.cpp
-											./classes/kriging/ExponentialVariogram.cpp
-											./classes/kriging/SphericalVariogram.cpp
-											./classes/kriging/PowerVariogram.cpp
-											./classes/kriging/Quadtree.cpp
-											./classes/kriging/Observation.cpp
-						./modules/Krigingx/Krigingx.cpp
-						./modules/Krigingx/Kriging
-#For parallel kriging, only difference is ./modules/Krigingx/pKrigingx.cpp with no multithreading
-set(pkriging_sources 					./classes/kriging/Observations.cpp
-						./classes/kriging/Variogram.h 
-											./classes/kriging/GaussianVariogram.cpp
-											./classes/kriging/ExponentialVariogram.cpp
-											./classes/kriging/SphericalVariogram.cpp
-											./classes/kriging/PowerVariogram.cpp
-											./classes/kriging/Quadtree.cpp
-											./classes/kriging/Observation.cpp
-						./modules/Krigingx/pKrigingx.cpp
-						)
-#}}}
-#Kml sources  {{{
-set(kml_sources 		     ./modules/Exp2Kmlx/Exp2Kmlx.cpp
-			     		     ./modules/Kml2Expx/Kml2Expx.cpp
-			     		     ./modules/Shp2Expx/Shp2Expx.cpp
-			     		     ./modules/Shp2Kmlx/Shp2Kmlx.cpp
-			     		     ./modules/KMLFileReadx/KMLFileReadx.cpp
-			     		     ./modules/KMLMeshWritex/KMLMeshWritex.cpp
-			     		     ./modules/KMLOverlayx/KMLOverlayx.cpp
-			     		     ./kml/KML_Attribute.cpp
-			     		     ./kml/KML_Comment.cpp
-			     		     ./kml/KML_ColorStyle.cpp
-			     		     ./kml/KML_Container.cpp
-			     		     ./kml/KML_Document.cpp
-			     		     ./kml/KML_Feature.cpp
-			     		     ./kml/KML_File.cpp
-			     		     ./kml/KML_Folder.cpp
-			     		     ./kml/KML_Geometry.cpp
-			     		     ./kml/KML_GroundOverlay.cpp
-			     		     ./kml/KML_Icon.cpp
-			     		     ./kml/KML_LatLonBox.cpp
-		  	     		     ./kml/KML_LinearRing.cpp
-			     		     ./kml/KML_LineString.cpp
-			     		     ./kml/KML_LineStyle.cpp
-			     		     ./kml/KML_MultiGeometry.cpp
-			     		     ./kml/KML_Object.cpp
-			     		     ./kml/KML_Overlay.cpp
-			     		     ./kml/KML_Point.cpp
-			     		     ./kml/KML_Placemark.cpp
-			     		     ./kml/KML_Polygon.cpp
-			     		     ./kml/KML_PolyStyle.cpp
-			     		     ./kml/KML_Style.cpp
-			     		     ./kml/KML_StyleSelector.cpp
-			     		     ./kml/KML_SubStyle.cpp
-			     		     ./kml/KML_Unknown.cpp
-			     		     ./kml/KMLFileReadUtils.cpp
-			     )
-#}}}
-#Petsc sources  {{{
-petsc_sources= ./toolkits/petsc
-					./toolkits/petsc/patches
-													./toolkits/petsc/patches/VecToMPISerial.cpp
-					./toolkits/petsc/patches/MatToSerial.cpp
-					./toolkits/petsc/patches/VecMerge.cpp
-					./toolkits/petsc/patches/NewVec.cpp
-					./toolkits/petsc/patches/PetscOptionsDetermineSolverType.cpp
-					./toolkits/petsc/patches/PetscOptionsInsertMultipleString.cpp
-					./toolkits/petsc/patches/NewMat.cpp
-					./toolkits/petsc/patches/VecFree.cpp
-					./toolkits/petsc/patches/KSPFree.cpp
-					./toolkits/petsc/patches/MatFree.cpp
-					./toolkits/petsc/patches/MatMultPatch.cpp
-					./toolkits/petsc/patches/ISSMToPetscMatrixType.cpp
-					./toolkits/petsc/patches/ISSMToPetscInsertMode.cpp
-					./toolkits/petsc/patches/ISSMToPetscNormMode.cpp
-													./toolkits/petsc/objects/PetscMat.cpp
-									./toolkits/petsc/objects/PetscVec.cpp
-					./toolkits/petsc/objects/PetscSolver.cpp
-									)
-#}}}
-#Mumps sources  {{{
-set(mumps_sources      ./toolkits/mumps
-									./toolkits/mumps/MpiDenseMumpsSolve.cpp)
-#}}}
-#Gsl sources  {{{
-set(gsl_sources   ./toolkits/gsl/DenseGslSolve.cpp)
-#}}}
-#Mpi sources  {{{
-set(mpi_sources 						./toolkits/mpi/patches/DetermineLocalSize.cpp
-				./toolkits/mpi/patches/DetermineGlobalSize.cpp
-				./toolkits/mpi/patches/DetermineRowRankFromLocalSize.cpp
-				./toolkits/mpi/patches/GetOwnershipBoundariesFromRange.cpp
-							)
-#}}}
-#Metis sources  {{{
-set(metis_sources 				./toolkits/metis/patches/METIS_PartMeshNodalPatch.cpp)
-#}}}
-
-# API Print {{{
-if(NOT PYTHON AND NOT MATLAB)
-    add_library(ISSMOverload STATIC ./shared/String/ApiPrintf.cpp)
-    list(APPEND issm_deps ISSMOverload)
-else(NOT PYTHON AND NOT MATLAB)
-    message(FATAL_ERROR "Python and Matlab are not supported yet.")
-endif(NOT PYTHON AND NOT MATLAB)
-# }}}
-
-# Modules Sources {{{
-set(modules_sources ./shared/Threads/LaunchThread.cpp
-			./shared/Threads/PartitionRange.cpp
-			./shared/Exp/exp.cpp
-			./shared/TriMesh/AssociateSegmentToElement.cpp
-			./shared/TriMesh/GridInsideHole.cpp
-			./shared/TriMesh/OrderSegments.cpp
-			./shared/TriMesh/SplitMeshForRifts.cpp
-			./shared/TriMesh/TriMeshUtils.cpp
-			./modules/Chacox/Chacox.cpp
-			./modules/Chacox/input_parse.cpp
-			./modules/Chacox/chaco_seconds.cpp
-			./modules/Chacox/user_params.cpp
-			./modules/TriaSearchx/TriaSearchx.cpp
-			./modules/TriMeshx/TriMeshx.cpp
-			./modules/TriMeshProcessRiftsx/TriMeshProcessRiftsx.cpp
-			./modules/PointCloudFindNeighborsx/PointCloudFindNeighborsx.cpp
-			./modules/PointCloudFindNeighborsx/PointCloudFindNeighborsxt.cpp
-			./modules/InterpFromGridToMeshx/InterpFromGridToMeshx.cpp
-			./modules/InterpFromMesh2dx/InterpFromMesh2dx.cpp
-			./modules/InterpFromMesh2dx/InterpFromMesh2dxt.cpp
-			./modules/InterpFromMeshToMesh2dx/InterpFromMeshToMesh2dx.cpp
-			./modules/InterpFromMeshToMesh3dx/InterpFromMeshToMesh3dx.cpp
-			./modules/InterpFromMeshToGridx/InterpFromMeshToGridx.cpp
-			./modules/HoleFillerx/HoleFillerx.cpp
-			./modules/EdgeDetectionx/EdgeDetectionx.cpp
-			./modules/AverageFilterx/AverageFilterx.cpp
-			./modules/MeshProfileIntersectionx/MeshProfileIntersectionx.cpp
-			./modules/ContourToMeshx/ContourToMeshx.cpp
-			./modules/ContourToMeshx/ContourToMeshxt.cpp
-			./modules/ContourToNodesx/ContourToNodesx.cpp
-			./modules/Reducevectorgtosx/Reducevectorgtosx.cpp
-			./modules/NodeConnectivityx/NodeConnectivityx.cpp
-			./modules/ElementConnectivityx/ElementConnectivityx.cpp
-			./modules/Scotchx/Scotchx.cpp
-			./modules/PropagateFlagsFromConnectivityx/PropagateFlagsFromConnectivityx.cpp)
-# }}}
-
-#{{{ Conditional build-up of sources
-#ISSM sources are a combination of core sources and sources related to specific capabilities.
-
-if(DAKOTA)
-list(APPEND CPP_FLAGS '-D_HAVE_DAKOTA_')
-list(APPEND issm_sources ${dakota_sources})
-endif(DAKOTA)
-
-if(PETSC)
-list(APPEND CPP_FLAGS '-D_HAVE_PETSC_')
-list(APPEND issm_sources ${petsc_sources})
-endif(PETSC)
-
-if(MUMPS)
-list(APPEND CPP_FLAGS '-D_HAVE_MUMPS_')
-list(APPEND issm_sources ${mumps_sources})
-endif(MUMPS)
-
-if(GSL)
-list(APPEND CPP_FLAGS '-D_HAVE_GSL_')
-list(APPEND issm_sources ${gsl_sources})
-list(APPEND issm_deps gsl gslcblas)
-list(APPEND issm_lib_paths ${GSL_LIB_DIR})
-include_directories(AFTER ${GSL_INC_DIR})
-message("GSL_INC: ${GSL_INC_DIR}")
-message("GSL_LIB: ${GSL_LIB_DIR}")
-endif(GSL)
-
-if(TRANSIENT)
-list(APPEND CPP_FLAGS '-D_HAVE_TRANSIENT_')
-list(APPEND issm_sources ${transient_sources})
-endif(TRANSIENT)
-
-if(STEADYSTATE)
-list(APPEND CPP_FLAGS '-D_HAVE_STEADYSTATE_')
-list(APPEND issm_sources ${steadystate_sources})
-endif(STEADYSTATE)
-
-if(PROGNOSTIC)
-list(APPEND CPP_FLAGS '-D_HAVE_PROGNOSTIC_')
-list(APPEND issm_sources ${prognostic_sources})
-endif(PROGNOSTIC)
-
-if(THERMAL)
-list(APPEND CPP_FLAGS '-D_HAVE_THERMAL_')
-list(APPEND issm_sources ${thermal_sources})
-endif(THERMAL)
-
-if(GIA)
-list(APPEND CPP_FLAGS '-D_HAVE_GIA_')
-list(APPEND issm_sources ${gia_sources})
-endif(GIA)
-
-if(CONTROL)
-list(APPEND CPP_FLAGS '-D_HAVE_CONTROL_')
-list(APPEND issm_sources ${control_sources})
-endif(CONTROL)
-
-if(HYDROLOGY)
-list(APPEND CPP_FLAGS '-D_HAVE_HYDROLOGY_')
-list(APPEND issm_sources ${hydrology_sources})
-endif(HYDROLOGY)
-
-if(DIAGNOSTIC)
-list(APPEND CPP_FLAGS '-D_HAVE_DIAGNOSTIC_')
-list(APPEND issm_sources ${diagnostic_sources})
-endif(DIAGNOSTIC)
-
-if(BALANCED)
-list(APPEND CPP_FLAGS '-D_HAVE_BALANCED_')
-list(APPEND issm_sources ${balanced_sources})
-endif(BALANCED)
-
-if(SLOPE)
-list(APPEND CPP_FLAGS '-D_HAVE_SLOPE_')
-list(APPEND issm_sources ${slope_sources})
-endif(SLOPE)
-
-if(GROUNDINGLINE)
-list(APPEND CPP_FLAGS '-D_HAVE_GROUNDINGLINE_')
-list(APPEND issm_sources ${groundingline_sources})
-endif(GROUNDINGLINE)
-
-if(RIFTS)
-list(APPEND CPP_FLAGS '-D_HAVE_RIFTS_')
-list(APPEND issm_sources ${rifts_sources})
-endif(RIFTS)
-
-if(ANDROID)
-list(APPEND CPP_FLAGS '-D_HAVE_ANDROID_')
-list(APPEND issm_sources ${android_sources})
-endif(ANDROID)
-
-if(THREED)
-list(APPEND CPP_FLAGS '-D_HAVE_THREED_')
-list(APPEND issm_sources ${threed_sources})
-endif(THREED)
-
-if(MPI)
-list(APPEND CPP_FLAGS '-D_HAVE_MPI_')
-list(APPEND issm_sources ${mpi_sources})
-endif(MPI)
-
-if(METIS)
-list(APPEND CPP_FLAGS '-D_HAVE_METIS_')
-list(APPEND issm_sources ${metis_sources})
-endif(METIS)
-
-if(KRIGING)
-list(APPEND CPP_FLAGS '-D_HAVE_KRIGING_')
-list(APPEND issm_sources ${pkriging_sources})
-endif(KRIGING)
-#}}}
-
-add_library(ISSMCore STATIC ${issm_sources})
-add_library(ISSMModules STATIC ${modules_sources})
-
-list(INSERT issm_deps 0 ISSMCore ISSMModules)
-add_executable(issm ./main/issm.cpp)
-
-# Definitions {{{
-add_definitions(${CPP_FLAGS})
-# }}}
-# Compilation Flags {{{
-# }}}
-# Linking Flags {{{
-link_directories($ENV{ISSM_DIR}/src/c )
-target_link_libraries(issm ${issm_deps})
-message("ISSM_DEPS: ${issm_deps}")
-# }}}
-
-# Install Targets {{{
-# Install 'issm.exe'
-install(TARGETS issm RUNTIME DESTINATION $ENV{ISSM_DIR}/bin)
-
-# Install 'libISSMCore.a' and 'libISSMOverload.a'
-install(TARGETS ISSMCore
-                ISSMModules
-                ISSMOverload
-        ARCHIVE DESTINATION $ENV{ISSM_DIR}/lib)
-# }}}
-# Optional Install {{{
-#if(${SHARED_LIBS} IS ON)
-#   install(TARGETS ISSMCore
-#                   ISSMOverload
-#           LIBRARY)
-#endif(${SHARED_LIBS} IS ON)
-# }}}
Index: /issm/trunk/src/c/Makefile.am
===================================================================
--- /issm/trunk/src/c/Makefile.am	(revision 17805)
+++ /issm/trunk/src/c/Makefile.am	(revision 17806)
@@ -18,17 +18,21 @@
 #}}}
 
-#sources
+#Core sources
 #Core sources{{{
-core_sources = ./datastructures/DataSet.h\
+issm_sources = ./datastructures/DataSet.h\
 					./datastructures/DataSet.cpp\
 					./datastructures/Object.h\
 					./datastructures/datastructures.h\
 					./classes/classes.h\
+					./classes/gauss/Gauss.h\
 					./classes/gauss/GaussSeg.h\
 					./classes/gauss/GaussSeg.cpp\
 					./classes/gauss/GaussTria.h\
 					./classes/gauss/GaussTria.cpp\
+					./classes/gauss/GaussTetra.h\
+					./classes/gauss/GaussTetra.cpp\
+					./classes/gauss/GaussPenta.h\
+					./classes/gauss/GaussPenta.cpp\
 					./classes/Update.h\
-					./classes/Element.h\
 					./classes/FemModel.h\
 					./classes/FemModel.cpp\
@@ -67,4 +71,6 @@
 					./classes/ExternalResults/ExternalResult.h\
 					./classes/ExternalResults/GenericExternalResult.h\
+					./classes/Elements/Element.h\
+					./classes/Elements/Element.cpp\
 					./classes/Elements/Elements.h\
 					./classes/Elements/Elements.cpp\
@@ -79,4 +85,12 @@
 					./classes/Elements/TriaRef.h\
 					./classes/Elements/TriaRef.cpp\
+					./classes/Elements/Tetra.h\
+					./classes/Elements/Tetra.cpp\
+					./classes/Elements/TetraRef.h\
+					./classes/Elements/TetraRef.cpp\
+					./classes/Elements/Penta.h\
+					./classes/Elements/Penta.cpp\
+					./classes/Elements/PentaRef.h\
+					./classes/Elements/PentaRef.cpp\
 					./classes/Inputs/Inputs.h\
 					./classes/Inputs/Inputs.cpp\
@@ -175,4 +189,6 @@
 					./shared/LatLong/Ll2xyx.cpp\
 					./shared/LatLong/Xy2llx.cpp\
+					./shared/FSanalyticals/fsanalyticals.h\
+					./shared/FSanalyticals/fsanalyticals.cpp\
 					./shared/Enum/Enum.h\
 					./shared/Enum/EnumDefinitions.h\
@@ -190,4 +206,5 @@
 					./shared/Numerics/isnan.cpp\
 					./shared/Numerics/cubic.cpp\
+					./shared/Numerics/NewtonSolveDnorm.cpp\
 					./shared/Numerics/extrema.cpp\
 					./shared/Numerics/XZvectorsToCoordinateSystem.cpp\
@@ -199,4 +216,5 @@
 					./shared/Sorting/sorting.h\
 					./shared/Elements/elements.h\
+					./shared/Elements/Cuffey.cpp\
 					./shared/Elements/Paterson.cpp\
 					./shared/Elements/Arrhenius.cpp\
@@ -284,4 +302,6 @@
 					./modules/IoModelToConstraintsx/IoModelToConstraintsx.h\
 					./modules/IoModelToConstraintsx/IoModelToConstraintsx.cpp\
+					./modules/SetActiveNodesLSMx/SetActiveNodesLSMx.h\
+					./modules/SetActiveNodesLSMx/SetActiveNodesLSMx.cpp\
 					./modules/InputUpdateFromConstantx/InputUpdateFromConstantx.h\
 					./modules/InputUpdateFromConstantx/InputUpdateFromConstantx.cpp\
@@ -302,10 +322,6 @@
 					./modules/SpcNodesx/SpcNodesx.h\
 					./modules/SpcNodesx/SpcNodesx.cpp\
-					./modules/PositiveDegreeDayx/PositiveDegreeDayx.h\
-					./modules/PositiveDegreeDayx/PositiveDegreeDayx.cpp\
-					./modules/Delta18oParameterizationx/Delta18oParameterizationx.h\
-					./modules/Delta18oParameterizationx/Delta18oParameterizationx.cpp\
-					./modules/SmbGradientsx/SmbGradientsx.h\
-					./modules/SmbGradientsx/SmbGradientsx.cpp\
+					./modules/SurfaceMassBalancex/SurfaceMassBalancex.h\
+					./modules/SurfaceMassBalancex/SurfaceMassBalancex.cpp\
 					./modules/MeshPartitionx/MeshPartitionx.h\
 					./modules/Reducevectorgtofx/Reducevectorgtofx.cpp\
@@ -318,6 +334,6 @@
 					./modules/ResetConstraintsx/ResetConstraintsx.h\
 					./modules/ResetConstraintsx/ResetConstraintsx.cpp\
-					./modules/ResetCoordinateSystemx/ResetCoordinateSystemx.h\
-					./modules/ResetCoordinateSystemx/ResetCoordinateSystemx.cpp\
+					./modules/ResetFSBasalBoundaryConditionx/ResetFSBasalBoundaryConditionx.h\
+					./modules/ResetFSBasalBoundaryConditionx/ResetFSBasalBoundaryConditionx.cpp\
 					./modules/Solverx/Solverx.cpp\
 					./modules/Solverx/Solverx.h\
@@ -340,4 +356,5 @@
 					./solutionsequences/solutionsequence_nonlinear.cpp\
 					./solutionsequences/solutionsequence_newton.cpp\
+					./solutionsequences/solutionsequence_la_theta.cpp\
 					./solutionsequences/convergence.cpp\
 					./classes/Options/Options.h\
@@ -348,8 +365,93 @@
 					./classes/Options/OptionUtilities.h\
 					./classes/RiftStruct.cpp\
-					./classes/RiftStruct.h
-#}}}
+					./classes/RiftStruct.h\
+					./modules/ModelProcessorx/Transient/UpdateElementsTransient.cpp \
+					./cores/transient_core.cpp\
+					./cores/steadystate_core.cpp\
+					./cores/masstransport_core.cpp\
+					./cores/depthaverage_core.cpp\
+					./cores/extrudefrombase_core.cpp\
+					./cores/extrudefromtop_core.cpp\
+					./cores/thermal_core.cpp\
+					./solutionsequences/solutionsequence_thermal_nonlinear.cpp\
+					./modules/ControlInputGetGradientx/ControlInputGetGradientx.cpp\
+					./modules/ControlInputGetGradientx/ControlInputGetGradientx.h\
+					./modules/ControlInputSetGradientx/ControlInputSetGradientx.cpp\
+					./modules/ControlInputSetGradientx/ControlInputSetGradientx.h\
+					./modules/ControlInputScaleGradientx/ControlInputScaleGradientx.cpp\
+					./modules/ControlInputScaleGradientx/ControlInputScaleGradientx.h\
+					./modules/GetVectorFromControlInputsx/GetVectorFromControlInputsx.cpp\
+					./modules/GetVectorFromControlInputsx/GetVectorFromControlInputsx.h\
+					./modules/SetControlInputsFromVectorx/SetControlInputsFromVectorx.cpp\
+					./modules/SetControlInputsFromVectorx/SetControlInputsFromVectorx.h\
+					./modules/ModelProcessorx/Control/CreateParametersControl.cpp\
+					./modules/ModelProcessorx/Control/UpdateElementsAndMaterialsControl.cpp\
+					./modules/InputControlUpdatex/InputControlUpdatex.h\
+					./modules/InputControlUpdatex/InputControlUpdatex.cpp\
+					./modules/SurfaceAbsVelMisfitx/SurfaceAbsVelMisfitx.h\
+					./modules/SurfaceAbsVelMisfitx/SurfaceAbsVelMisfitx.cpp\
+					./modules/SurfaceRelVelMisfitx/SurfaceRelVelMisfitx.h\
+					./modules/SurfaceRelVelMisfitx/SurfaceRelVelMisfitx.cpp\
+					./modules/SurfaceLogVelMisfitx/SurfaceLogVelMisfitx.h\
+					./modules/SurfaceLogVelMisfitx/SurfaceLogVelMisfitx.cpp\
+					./modules/SurfaceLogVxVyMisfitx/SurfaceLogVxVyMisfitx.h\
+					./modules/SurfaceLogVxVyMisfitx/SurfaceLogVxVyMisfitx.cpp\
+					./modules/SurfaceAverageVelMisfitx/SurfaceAverageVelMisfitx.h\
+					./modules/SurfaceAverageVelMisfitx/SurfaceAverageVelMisfitx.cpp\
+					./modules/ThicknessAbsMisfitx/ThicknessAbsMisfitx.h\
+					./modules/ThicknessAbsMisfitx/ThicknessAbsMisfitx.cpp\
+					./modules/Orthx/Orthx.h\
+					./modules/Orthx/Orthx.cpp\
+					./modules/Gradjx/Gradjx.h\
+					./modules/Gradjx/Gradjx.cpp\
+					./modules/DragCoefficientAbsGradientx/DragCoefficientAbsGradientx.cpp\
+					./modules/DragCoefficientAbsGradientx/DragCoefficientAbsGradientx.h\
+					./modules/ThicknessAlongGradientx/ThicknessAlongGradientx.cpp\
+					./modules/ThicknessAlongGradientx/ThicknessAlongGradientx.h\
+					./modules/ThicknessAcrossGradientx/ThicknessAcrossGradientx.cpp\
+					./modules/ThicknessAcrossGradientx/ThicknessAcrossGradientx.h\
+					./modules/RheologyBbarAbsGradientx/RheologyBbarAbsGradientx.cpp\
+					./modules/RheologyBbarAbsGradientx/RheologyBbarAbsGradientx.h\
+					./classes/Inputs/ControlInput.h\
+					./classes/Inputs/ControlInput.cpp\
+					./shared/Numerics/BrentSearch.cpp\
+					./shared/Numerics/OptimalSearch.cpp \
+					./cores/control_core.cpp\
+					./cores/controltao_core.cpp\
+					./cores/objectivefunction.cpp\
+					./cores/gradient_core.cpp\
+					./cores/adjointstressbalance_core.cpp\
+					./cores/adjointbalancethickness_core.cpp\
+					./cores/AdjointCorePointerFromSolutionEnum.cpp\
+					./solutionsequences/solutionsequence_adjoint_linear.cpp\
+					./cores/hydrology_core.cpp\
+					./solutionsequences/solutionsequence_hydro_nonlinear.cpp\
+					./cores/stressbalance_core.cpp\
+					./solutionsequences/solutionsequence_stokescoupling_nonlinear.cpp\
+					./cores/balancethickness_core.cpp \
+					./cores/balancevelocity_core.cpp \
+					./cores/dummy_core.cpp\
+					./cores/surfaceslope_core.cpp\
+					./cores/bedslope_core.cpp\
+					./cores/meshdeformation_core.cpp\
+					./cores/damage_core.cpp\
+					./cores/levelsetfunctionslope_core.cpp\
+					./analyses/DamageEvolutionAnalysis.cpp\
+					./modules/GroundinglineMigrationx/GroundinglineMigrationx.cpp\
+					./classes/Loads/Riftfront.cpp\
+					./modules/ConstraintsStatex/RiftConstraintsState.cpp\
+					./classes/Massfluxatgate.h \
+					./classes/Misfit.h \
+					./modules/ModelProcessorx/CreateOutputDefinitions.cpp\
+					./modules/OutputDefinitionsResponsex/OutputDefinitionsResponsex.h\
+					./modules/OutputDefinitionsResponsex/OutputDefinitionsResponsex.cpp\
+					./classes/Inputs/PentaInput.h\
+					./classes/Inputs/PentaInput.cpp\
+					./classes/Inputs/TetraInput.h\
+					./classes/Inputs/TetraInput.cpp\
+					#}}}
 #DAKOTA sources  {{{
-dakota_sources = ./modules/InputUpdateFromDakotax/InputUpdateFromDakotax.h\
+if DAKOTA
+issm_sources +=  ./modules/InputUpdateFromDakotax/InputUpdateFromDakotax.h\
 					  ./modules/InputUpdateFromDakotax/InputUpdateFromDakotax.cpp\
 					  ./modules/InputUpdateFromVectorDakotax/InputUpdateFromVectorDakotax.h\
@@ -364,371 +466,9 @@
 					  ./cores/DakotaSpawnCore.h\
 					  ./cores/DakotaSpawnCore.cpp
-#}}}
-#Transient sources  {{{
-transient_sources  = ./modules/ModelProcessorx/Transient/UpdateElementsTransient.cpp \
-							./cores/transient_core.cpp
-#}}}
-#Steadystate sources  {{{
-steadystate_sources = ./cores/steadystate_core.cpp
-#}}}
-#Masstransport sources  {{{
-masstransport_sources = ./analyses/ExtrudeFromBaseAnalysis.h\
-								./analyses/ExtrudeFromBaseAnalysis.cpp\
-								./analyses/ExtrudeFromTopAnalysis.h\
-								./analyses/ExtrudeFromTopAnalysis.cpp\
-								./analyses/MasstransportAnalysis.h\
-								./analyses/MasstransportAnalysis.cpp\
-								./analyses/FreeSurfaceBaseAnalysis.h\
-								./analyses/FreeSurfaceBaseAnalysis.cpp\
-								./analyses/FreeSurfaceTopAnalysis.h\
-								./analyses/FreeSurfaceTopAnalysis.cpp\
-								./cores/masstransport_core.cpp\
-								./cores/extrudefrombase_core.cpp\
-								./cores/extrudefromtop_core.cpp
-
-#}}}
-#Thermal sources  {{{
-thermal_sources = ./modules/PostprocessingEnthalpyx/PostprocessingEnthalpyx.h\
-					   ./modules/PostprocessingEnthalpyx/PostprocessingEnthalpyx.cpp\
-						./analyses/ThermalAnalysis.h\
-						./analyses/ThermalAnalysis.cpp\
-						./analyses/EnthalpyAnalysis.h\
-						./analyses/EnthalpyAnalysis.cpp\
-						./analyses/MeltingAnalysis.h\
-						./analyses/MeltingAnalysis.cpp\
-					   ./cores/thermal_core.cpp\
-					   ./solutionsequences/solutionsequence_thermal_nonlinear.cpp
-#}}}
-#Control sources  {{{
-control_sources= ./modules/ControlInputGetGradientx/ControlInputGetGradientx.cpp\
-					  ./modules/ControlInputGetGradientx/ControlInputGetGradientx.h\
-					  ./modules/ControlInputSetGradientx/ControlInputSetGradientx.cpp\
-					  ./modules/ControlInputSetGradientx/ControlInputSetGradientx.h\
-					  ./modules/ControlInputScaleGradientx/ControlInputScaleGradientx.cpp\
-					  ./modules/ControlInputScaleGradientx/ControlInputScaleGradientx.h\
-					  ./modules/GetVectorFromControlInputsx/GetVectorFromControlInputsx.cpp\
-					  ./modules/GetVectorFromControlInputsx/GetVectorFromControlInputsx.h\
-					  ./modules/SetControlInputsFromVectorx/SetControlInputsFromVectorx.cpp\
-					  ./modules/SetControlInputsFromVectorx/SetControlInputsFromVectorx.h\
-					  ./modules/ModelProcessorx/Control/CreateParametersControl.cpp\
-					  ./modules/ModelProcessorx/Control/UpdateElementsAndMaterialsControl.cpp\
-					  ./modules/InputControlUpdatex/InputControlUpdatex.h\
-					  ./modules/InputControlUpdatex/InputControlUpdatex.cpp\
-					  ./modules/SurfaceAbsVelMisfitx/SurfaceAbsVelMisfitx.h\
-					  ./modules/SurfaceAbsVelMisfitx/SurfaceAbsVelMisfitx.cpp\
-					  ./modules/SurfaceRelVelMisfitx/SurfaceRelVelMisfitx.h\
-					  ./modules/SurfaceRelVelMisfitx/SurfaceRelVelMisfitx.cpp\
-					  ./modules/SurfaceLogVelMisfitx/SurfaceLogVelMisfitx.h\
-					  ./modules/SurfaceLogVelMisfitx/SurfaceLogVelMisfitx.cpp\
-					  ./modules/SurfaceLogVxVyMisfitx/SurfaceLogVxVyMisfitx.h\
-					  ./modules/SurfaceLogVxVyMisfitx/SurfaceLogVxVyMisfitx.cpp\
-					  ./modules/SurfaceAverageVelMisfitx/SurfaceAverageVelMisfitx.h\
-					  ./modules/SurfaceAverageVelMisfitx/SurfaceAverageVelMisfitx.cpp\
-					  ./modules/ThicknessAbsMisfitx/ThicknessAbsMisfitx.h\
-					  ./modules/ThicknessAbsMisfitx/ThicknessAbsMisfitx.cpp\
-					  ./modules/Orthx/Orthx.h\
-					  ./modules/Orthx/Orthx.cpp\
-					  ./modules/Gradjx/Gradjx.h\
-					  ./modules/Gradjx/Gradjx.cpp\
-					  ./modules/DragCoefficientAbsGradientx/DragCoefficientAbsGradientx.cpp\
-					  ./modules/DragCoefficientAbsGradientx/DragCoefficientAbsGradientx.h\
-					  ./modules/ThicknessAlongGradientx/ThicknessAlongGradientx.cpp\
-					  ./modules/ThicknessAlongGradientx/ThicknessAlongGradientx.h\
-					  ./modules/ThicknessAcrossGradientx/ThicknessAcrossGradientx.cpp\
-					  ./modules/ThicknessAcrossGradientx/ThicknessAcrossGradientx.h\
-					  ./modules/RheologyBbarAbsGradientx/RheologyBbarAbsGradientx.cpp\
-					  ./modules/RheologyBbarAbsGradientx/RheologyBbarAbsGradientx.h\
-					  ./classes/Inputs/ControlInput.h\
-					  ./classes/Inputs/ControlInput.cpp\
-					  ./shared/Numerics/BrentSearch.cpp\
-					  ./shared/Numerics/OptimalSearch.cpp \
-					  ./cores/control_core.cpp\
-					  ./cores/controltao_core.cpp\
-					  ./cores/objectivefunction.cpp\
-					  ./cores/gradient_core.cpp\
-					  ./cores/adjointstressbalance_core.cpp\
-					  ./cores/adjointbalancethickness_core.cpp\
-					  ./cores/AdjointCorePointerFromSolutionEnum.cpp\
-					  ./analyses/AdjointBalancethicknessAnalysis.h\
-					  ./analyses/AdjointBalancethicknessAnalysis.cpp\
-					  ./analyses/AdjointHorizAnalysis.h\
-					  ./analyses/AdjointHorizAnalysis.cpp\
-					  ./solutionsequences/solutionsequence_adjoint_linear.cpp
-
-#}}}
-#Hydrology sources  {{{
-hydrology_sources  = ./analyses/HydrologyDCEfficientAnalysis.h\
-							./analyses/HydrologyDCEfficientAnalysis.cpp\
-							./analyses/HydrologyDCInefficientAnalysis.h\
-							./analyses/HydrologyDCInefficientAnalysis.cpp\
-							./analyses/HydrologyShreveAnalysis.h\
-							./analyses/HydrologyShreveAnalysis.cpp\
-							./cores/hydrology_core.cpp\
-							./solutionsequences/solutionsequence_hydro_nonlinear.cpp
-#}}}
-#Stressbalance sources  {{{
-stressbalance_sources = ./analyses/StressbalanceAnalysis.h\
-							./analyses/StressbalanceAnalysis.cpp\
-							./analyses/StressbalanceSIAAnalysis.h\
-							./analyses/StressbalanceSIAAnalysis.cpp\
-							./analyses/StressbalanceVerticalAnalysis.h\
-							./analyses/StressbalanceVerticalAnalysis.cpp\
-							./cores/stressbalance_core.cpp\
-							./solutionsequences/solutionsequence_stokescoupling_nonlinear.cpp
-#}}}
-#Balanced sources  {{{
-balanced_sources = ./analyses/BalancevelocityAnalysis.h\
-						 ./analyses/BalancevelocityAnalysis.cpp\
-						 ./analyses/SmoothedSurfaceSlopeXAnalysis.h\
-						 ./analyses/SmoothedSurfaceSlopeXAnalysis.cpp\
-						 ./analyses/SmoothedSurfaceSlopeYAnalysis.h\
-						 ./analyses/SmoothedSurfaceSlopeYAnalysis.cpp\
-						 ./analyses/BalancethicknessAnalysis.h\
-						 ./analyses/BalancethicknessAnalysis.cpp\
-						 ./analyses/BalancethicknessSoftAnalysis.h\
-						 ./analyses/BalancethicknessSoftAnalysis.cpp\
-						 ./cores/balancethickness_core.cpp \
-						 ./cores/balancevelocity_core.cpp \
-						 ./cores/dummy_core.cpp
-#}}}
-#Slope sources  {{{
-slope_sources =  ./analyses/L2ProjectionBaseAnalysis.h\
-					  ./analyses/L2ProjectionBaseAnalysis.cpp\
-					  ./cores/surfaceslope_core.cpp\
-					  ./cores/bedslope_core.cpp
-#}}}
-#MeshDeformation sources  {{{
-meshdeformation_sources = ./analyses/MeshdeformationAnalysis.h\
-					  ./analyses/MeshdeformationAnalysis.cpp\
-					  ./cores/meshdeformation_core.cpp
-#}}}
-#Gia sources  {{{
-gia_sources =  ./cores/gia_core.cpp\
-					./analyses/GiaAnalysis.h\
-					./analyses/GiaAnalysis.cpp\
-					./modules/GiaDeflectionCorex/GiaDeflectionCorex.cpp\
-					./modules/GiaDeflectionCorex/GiaDeflectionCorex.h\
-					./modules/GiaDeflectionCorex/distme.f\
-					./modules/GiaDeflectionCorex/freed.f\
-					./modules/GiaDeflectionCorex/ojrule.f\
-					./modules/GiaDeflectionCorex/pwise.f\
-					./modules/GiaDeflectionCorex/qwise.f\
-					./modules/GiaDeflectionCorex/stot.f\
-					./modules/GiaDeflectionCorex/what0.f\
-					./classes/GiaDeflectionCoreArgs.h
-
-#}}}
-#Damage sources  {{{
-damage_sources =  ./cores/damage_core.cpp\
-						./analyses/DamageEvolutionAnalysis.h\
-						./analyses/DamageEvolutionAnalysis.cpp\
-						./solutionsequences/solutionsequence_damage_nonlinear.cpp
-
-#}}}
-#Groundingline sources  {{{
-groundingline_sources= ./modules/GroundinglineMigrationx/GroundinglineMigrationx.cpp\
-					        ./modules/GroundinglineMigrationx/GroundinglineMigrationx.h
-#}}}
-#Rifts sources  {{{
-rifts_sources = ./classes/Loads/Riftfront.cpp\
-				    ./classes/Loads/Riftfront.h\
-				    ./modules/ConstraintsStatex/RiftConstraintsState.cpp
-#}}}
-#Responses sources  {{{
-responses_sources= ./classes/Massfluxatgate.h \
-				   ./modules/ModelProcessorx/CreateOutputDefinitions.cpp\
-				   ./modules/OutputDefinitionsResponsex/OutputDefinitionsResponsex.h\
-				   ./modules/OutputDefinitionsResponsex/OutputDefinitionsResponsex.cpp
-#}}}
-#Android sources  {{{
-android_sources = 
-#}}}
-#3D sources  {{{
-threed_sources = ./classes/gauss/GaussPenta.h\
-				     ./classes/gauss/GaussPenta.cpp\
-				     ./classes/Inputs/PentaInput.h\
-				     ./classes/Inputs/PentaInput.cpp\
-				     ./classes/Elements/Penta.h\
-				     ./classes/Elements/Penta.cpp\
-				     ./classes/Elements/PentaRef.h\
-				     ./classes/Elements/PentaRef.cpp
-#}}}
-#Bamg sources  {{{
-bamg_sources =  ./bamg/bamgobjects.h\
-				./bamg/BamgGeom.h\
-				./bamg/BamgGeom.cpp\
-				./bamg/BamgMesh.h\
-				./bamg/BamgMesh.cpp\
-				./bamg/BamgOpts.h\
-				./bamg/BamgOpts.cpp\
-				./bamg/CrackedEdge.h\
-				./bamg/CrackedEdge.cpp\
-				./bamg/Curve.h\
-				./bamg/Curve.cpp\
-				./bamg/Direction.h\
-				./bamg/Direction.cpp\
-				./bamg/DoubleAndInt.h\
-				./bamg/Edge.h\
-				./bamg/Edge.cpp\
-				./bamg/GeomEdge.h\
-				./bamg/GeomEdge.cpp\
-				./bamg/GeomSubDomain.h\
-				./bamg/GeomSubDomain.cpp\
-				./bamg/GeomVertex.h\
-				./bamg/GeomVertex.cpp\
-				./bamg/Geometry.cpp\
-				./bamg/Geometry.h\
-				./bamg/ListofIntersectionTriangles.cpp\
-				./bamg/ListofIntersectionTriangles.h\
-				./bamg/EigenMetric.cpp\
-				./bamg/Metric.cpp\
-				./bamg/Metric.h\
-				./bamg/BamgQuadtree.cpp\
-				./bamg/BamgQuadtree.h\
-				./bamg/R2.h\
-				./bamg/SetOfE4.cpp\
-				./bamg/SetOfE4.h\
-				./bamg/SubDomain.h\
-				./bamg/SubDomain.cpp\
-				./bamg/AdjacentTriangle.h\
-				./bamg/AdjacentTriangle.cpp\
-				./bamg/Triangle.cpp\
-				./bamg/det.h \
-				./bamg/Triangle.h\
-				./bamg/BamgVertex.cpp\
-				./bamg/BamgVertex.h\
-				./bamg/VertexOnEdge.h\
-				./bamg/VertexOnEdge.cpp\
-				./bamg/VertexOnGeom.h\
-				./bamg/VertexOnGeom.cpp\
-				./bamg/VertexOnVertex.h\
-				./bamg/VertexOnVertex.cpp\
-				./bamg/Mesh.cpp\
-				./bamg/Mesh.h\
-				./shared/Bamg/Abs.h \
-				./shared/Bamg/BigPrimeNumber.h\
-				./shared/Bamg/BigPrimeNumber.cpp\
-				./shared/Bamg/BinaryRand.h \
-				./shared/Bamg/Exchange.h \
-				./shared/Bamg/extrema.h \
-				./shared/Bamg/HeapSort.h \
-				./shared/Bamg/OppositeAngle.h \
-				./modules/Bamgx/Bamgx.cpp\
-				./modules/Bamgx/Bamgx.h\
-				./modules/BamgConvertMeshx/BamgConvertMeshx.cpp\
-				./modules/BamgConvertMeshx/BamgConvertMeshx.h\
-				./modules/BamgTriangulatex/BamgTriangulatex.cpp\
-				./modules/BamgTriangulatex/BamgTriangulatex.h
-#}}}
-#Kriging sources  {{{
-kriging_sources = ./classes/kriging/Observations.h\
-						./classes/kriging/Observations.cpp\
-						./classes/kriging/Variogram.h \
-						./classes/kriging/GaussianVariogram.h\
-						./classes/kriging/GaussianVariogram.cpp\
-						./classes/kriging/ExponentialVariogram.h\
-						./classes/kriging/ExponentialVariogram.cpp\
-						./classes/kriging/SphericalVariogram.h\
-						./classes/kriging/SphericalVariogram.cpp\
-						./classes/kriging/PowerVariogram.h\
-						./classes/kriging/PowerVariogram.cpp\
-						./classes/kriging/Quadtree.h\
-						./classes/kriging/Quadtree.cpp\
-						./classes/kriging/Observation.h\
-						./classes/kriging/Observation.cpp\
-						./modules/Krigingx/Krigingx.cpp\
-						./modules/Krigingx/Krigingx.h
-
-#For parallel kriging, only difference is ./modules/Krigingx/pKrigingx.cpp with no multithreading
-pkriging_sources = ./classes/kriging/Observations.h\
-						./classes/kriging/Observations.cpp\
-						./classes/kriging/Variogram.h \
-						./classes/kriging/GaussianVariogram.h\
-						./classes/kriging/GaussianVariogram.cpp\
-						./classes/kriging/ExponentialVariogram.h\
-						./classes/kriging/ExponentialVariogram.cpp\
-						./classes/kriging/SphericalVariogram.h\
-						./classes/kriging/SphericalVariogram.cpp\
-						./classes/kriging/PowerVariogram.h\
-						./classes/kriging/PowerVariogram.cpp\
-						./classes/kriging/Quadtree.h\
-						./classes/kriging/Quadtree.cpp\
-						./classes/kriging/Observation.h\
-						./classes/kriging/Observation.cpp\
-						./modules/Krigingx/pKrigingx.cpp\
-						./modules/Krigingx/Krigingx.h
-
-#}}}
-#Kml sources  {{{
-kml_sources = ./modules/Exp2Kmlx/Exp2Kmlx.h\
-			     ./modules/Exp2Kmlx/Exp2Kmlx.cpp\
-			     ./modules/Kml2Expx/Kml2Expx.h\
-			     ./modules/Kml2Expx/Kml2Expx.cpp\
-			     ./modules/Shp2Kmlx/Shp2Kmlx.h\
-			     ./modules/Shp2Kmlx/Shp2Kmlx.cpp\
-			     ./modules/KMLFileReadx/KMLFileReadx.h\
-			     ./modules/KMLFileReadx/KMLFileReadx.cpp\
-			     ./modules/KMLMeshWritex/KMLMeshWritex.h\
-			     ./modules/KMLMeshWritex/KMLMeshWritex.cpp\
-			     ./modules/KMLOverlayx/KMLOverlayx.h\
-			     ./modules/KMLOverlayx/KMLOverlayx.cpp\
-			     ./kml/kmlobjects.h\
-			     ./kml/KML_Attribute.cpp\
-			     ./kml/KML_Attribute.h\
-			     ./kml/KML_Comment.cpp\
-			     ./kml/KML_Comment.h\
-			     ./kml/KML_ColorStyle.cpp\
-			     ./kml/KML_ColorStyle.h\
-			     ./kml/KML_Container.cpp\
-			     ./kml/KML_Container.h\
-			     ./kml/KML_Document.cpp\
-			     ./kml/KML_Document.h\
-			     ./kml/KML_Feature.cpp\
-			     ./kml/KML_Feature.h\
-			     ./kml/KML_File.cpp\
-			     ./kml/KML_File.h\
-			     ./kml/KML_Folder.cpp\
-			     ./kml/KML_Folder.h\
-			     ./kml/KML_Geometry.cpp\
-			     ./kml/KML_Geometry.h\
-			     ./kml/KML_GroundOverlay.cpp\
-			     ./kml/KML_GroundOverlay.h\
-			     ./kml/KML_Icon.cpp\
-			     ./kml/KML_Icon.h\
-			     ./kml/KML_LatLonBox.cpp\
-		  	     ./kml/KML_LatLonBox.h\
-			     ./kml/KML_LinearRing.cpp\
-			     ./kml/KML_LinearRing.h\
-			     ./kml/KML_LineString.cpp\
-			     ./kml/KML_LineString.h\
-			     ./kml/KML_LineStyle.cpp\
-			     ./kml/KML_LineStyle.h\
-			     ./kml/KML_MultiGeometry.cpp\
-			     ./kml/KML_MultiGeometry.h\
-			     ./kml/KML_Object.cpp\
-			     ./kml/KML_Object.h\
-			     ./kml/KML_Overlay.cpp\
-			     ./kml/KML_Overlay.h\
-			     ./kml/KML_Point.cpp\
-			     ./kml/KML_Point.h\
-			     ./kml/KML_Placemark.cpp\
-			     ./kml/KML_Placemark.h\
-			     ./kml/KML_Polygon.cpp\
-			     ./kml/KML_Polygon.h\
-			     ./kml/KML_PolyStyle.cpp\
-			     ./kml/KML_PolyStyle.h\
-			     ./kml/KML_Style.cpp\
-			     ./kml/KML_Style.h\
-			     ./kml/KML_StyleSelector.cpp\
-			     ./kml/KML_StyleSelector.h\
-			     ./kml/KML_SubStyle.cpp\
-			     ./kml/KML_SubStyle.h\
-			     ./kml/KML_Unknown.cpp\
-			     ./kml/KML_Unknown.h\
-			     ./kml/KMLFileReadUtils.cpp\
-			     ./kml/KMLFileReadUtils.h
+endif
 #}}}
 #Petsc sources  {{{
-petsc_sources= ./toolkits/petsc\
+if PETSC
+issm_sources += ./toolkits/petsc\
 					./toolkits/petsc/patches\
 					./toolkits/petsc/patches/SolverEnum.h\
@@ -756,23 +496,295 @@
 					./toolkits/petsc/objects/PetscSolver.h\
 					./toolkits/petsc/petscincludes.h
-
+endif
 #}}}
 #Mumps sources  {{{
-mumps_sources=      ./toolkits/mumps\
+if MUMPS
+issm_sources += ./toolkits/mumps\
 					./toolkits/mumps/mumpsincludes.h\
 					./toolkits/mumps/MumpsSolve.cpp
+endif
 #}}}
 #Gsl sources  {{{
-gsl_sources=      ./toolkits/gsl\
+if GSL
+issm_sources += ./toolkits/gsl\
 					./toolkits/gsl/gslincludes.h\
 					./toolkits/gsl/DenseGslSolve.cpp
+endif
+#}}}
+#Analyses{{{
+if ADJOINTBALANCETHICKNESS
+issm_sources += ./analyses/AdjointBalancethicknessAnalysis.cpp
+endif
+if ADJOINTHORIZ
+issm_sources += ./analyses/AdjointHorizAnalysis.cpp
+endif
+if BALANCETHICKNESS
+issm_sources += ./analyses/BalancethicknessAnalysis.cpp
+endif
+if BALANCETHICKNESSSOFT
+issm_sources += ./analyses/BalancethicknessSoftAnalysis.cpp
+endif
+if BALANCEVELOCITY
+issm_sources += ./analyses/BalancevelocityAnalysis.cpp
+endif
+if L2PROJECTIONBASE
+issm_sources += ./analyses/L2ProjectionBaseAnalysis.cpp
+endif
+if DAMAGEEVOLUTION
+issm_sources += ./analyses/DamageEvolutionAnalysis.cpp
+endif
+if STRESSBALANCE
+issm_sources += ./analyses/StressbalanceAnalysis.cpp
+endif
+if STRESSBALANCESIA
+issm_sources += ./analyses/StressbalanceSIAAnalysis.cpp
+endif
+if STRESSBALANCEVERTICAL
+issm_sources += ./analyses/StressbalanceVerticalAnalysis.cpp
+endif
+if ENTHALPY
+issm_sources += ./analyses/EnthalpyAnalysis.cpp
+endif
+if HYDROLOGYSHREVE
+issm_sources += ./analyses/HydrologyShreveAnalysis.cpp
+endif
+if HYDROLOGYDCINEFFICIENT
+issm_sources += ./analyses/HydrologyDCInefficientAnalysis.cpp
+endif
+if HYDROLOGYDCEFFICIENT
+issm_sources += ./analyses/HydrologyDCEfficientAnalysis.cpp
+endif
+if L2PROJECTIONEPL
+issm_sources += ./analyses/L2ProjectionEPLAnalysis.cpp
+endif
+if MELTING
+issm_sources += ./analyses/MeltingAnalysis.cpp
+endif
+if MASSTRANSPORT
+issm_sources += ./analyses/MasstransportAnalysis.cpp
+endif
+if FREESURFACEBASE
+issm_sources += ./analyses/FreeSurfaceBaseAnalysis.cpp
+endif
+if FREESURFACETOP
+issm_sources += ./analyses/FreeSurfaceTopAnalysis.cpp
+endif
+if EXTRUDEFROMBASE
+issm_sources += ./analyses/ExtrudeFromBaseAnalysis.cpp
+endif
+if EXTRUDEFROMTOP
+issm_sources += ./analyses/ExtrudeFromTopAnalysis.cpp
+endif
+if DEPTHAVERAGE
+issm_sources += ./analyses/DepthAverageAnalysis.cpp
+endif
+if THERMAL
+issm_sources += ./analyses/ThermalAnalysis.cpp
+endif
+if SMOOTHEDSURFACESLOPEX
+issm_sources += ./analyses/SmoothedSurfaceSlopeXAnalysis.cpp
+endif
+if SMOOTHEDSURFACESLOPEY
+issm_sources += ./analyses/SmoothedSurfaceSlopeYAnalysis.cpp
+endif
+if MESHDEFORMATION
+issm_sources += ./analyses/MeshdeformationAnalysis.cpp
+endif
+if LEVELSET
+issm_sources += ./analyses/LevelsetAnalysis.cpp
+endif
+if EXTRAPOLATION
+issm_sources += ./analyses/ExtrapolationAnalysis.cpp
+endif
+if LSFREINITIALIZATION
+issm_sources += ./analyses/LsfReinitializationAnalysis.cpp
+endif
+#}}}
+#Gia sources  {{{
+if GIA
+issm_sources +=  ./cores/gia_core.cpp\
+					./analyses/GiaAnalysis.cpp\
+					./modules/GiaDeflectionCorex/GiaDeflectionCorex.cpp\
+					./modules/GiaDeflectionCorex/distme.f\
+					./modules/GiaDeflectionCorex/freed.f\
+					./modules/GiaDeflectionCorex/ojrule.f\
+					./modules/GiaDeflectionCorex/pwise.f\
+					./modules/GiaDeflectionCorex/qwise.f\
+					./modules/GiaDeflectionCorex/stot.f\
+					./modules/GiaDeflectionCorex/what0.f
+endif
 #}}}
 #Mpi sources  {{{
-mpi_sources= ./toolkits/issm/IssmMpiDenseMat.h\
-				./toolkits/issm/IssmMpiVec.h
+if MPI
+issm_sources += ./toolkits/issm/IssmMpiDenseMat.h\
+					 ./toolkits/issm/IssmMpiVec.h
+endif
 #}}}
 #Metis sources  {{{
-metis_sources= ./toolkits/metis/patches/metispatches.h\
+if METIS
+issm_sources += ./toolkits/metis/patches/metispatches.h\
 					./toolkits/metis/patches/METIS_PartMeshNodalPatch.cpp
+endif
+#}}}
+
+#Wrapper sources
+#Bamg sources  {{{
+bamg_sources =  ./bamg/bamgobjects.h\
+					 ./bamg/BamgGeom.h\
+					 ./bamg/BamgGeom.cpp\
+					 ./bamg/BamgMesh.h\
+					 ./bamg/BamgMesh.cpp\
+					 ./bamg/BamgOpts.h\
+					 ./bamg/BamgOpts.cpp\
+					 ./bamg/CrackedEdge.h\
+					 ./bamg/CrackedEdge.cpp\
+					 ./bamg/Curve.h\
+					 ./bamg/Curve.cpp\
+					 ./bamg/Direction.h\
+					 ./bamg/Direction.cpp\
+					 ./bamg/DoubleAndInt.h\
+					 ./bamg/Edge.h\
+					 ./bamg/Edge.cpp\
+					 ./bamg/GeomEdge.h\
+					 ./bamg/GeomEdge.cpp\
+					 ./bamg/GeomSubDomain.h\
+					 ./bamg/GeomSubDomain.cpp\
+					 ./bamg/GeomVertex.h\
+					 ./bamg/GeomVertex.cpp\
+					 ./bamg/Geometry.cpp\
+					 ./bamg/Geometry.h\
+					 ./bamg/ListofIntersectionTriangles.cpp\
+					 ./bamg/ListofIntersectionTriangles.h\
+					 ./bamg/EigenMetric.cpp\
+					 ./bamg/Metric.cpp\
+					 ./bamg/Metric.h\
+					 ./bamg/BamgQuadtree.cpp\
+					 ./bamg/BamgQuadtree.h\
+					 ./bamg/R2.h\
+					 ./bamg/SetOfE4.cpp\
+					 ./bamg/SetOfE4.h\
+					 ./bamg/SubDomain.h\
+					 ./bamg/SubDomain.cpp\
+					 ./bamg/AdjacentTriangle.h\
+					 ./bamg/AdjacentTriangle.cpp\
+					 ./bamg/Triangle.cpp\
+					 ./bamg/det.h \
+					 ./bamg/Triangle.h\
+					 ./bamg/BamgVertex.cpp\
+					 ./bamg/BamgVertex.h\
+					 ./bamg/VertexOnEdge.h\
+					 ./bamg/VertexOnEdge.cpp\
+					 ./bamg/VertexOnGeom.h\
+					 ./bamg/VertexOnGeom.cpp\
+					 ./bamg/VertexOnVertex.h\
+					 ./bamg/VertexOnVertex.cpp\
+					 ./bamg/Mesh.cpp\
+					 ./bamg/Mesh.h\
+					 ./shared/Bamg/Abs.h \
+					 ./shared/Bamg/BigPrimeNumber.h\
+					 ./shared/Bamg/BigPrimeNumber.cpp\
+					 ./shared/Bamg/BinaryRand.h \
+					 ./shared/Bamg/Exchange.h \
+					 ./shared/Bamg/extrema.h \
+					 ./shared/Bamg/HeapSort.h \
+					 ./shared/Bamg/OppositeAngle.h \
+					 ./modules/Bamgx/Bamgx.cpp\
+					 ./modules/Bamgx/Bamgx.h\
+					 ./modules/BamgConvertMeshx/BamgConvertMeshx.cpp\
+					 ./modules/BamgConvertMeshx/BamgConvertMeshx.h\
+					 ./modules/BamgTriangulatex/BamgTriangulatex.cpp\
+					 ./modules/BamgTriangulatex/BamgTriangulatex.h
+#}}}
+#Kriging sources  {{{
+if KRIGING
+kriging_sources = ./classes/kriging/Observations.h\
+					./classes/kriging/Observations.cpp\
+					./classes/kriging/Variogram.h \
+					./classes/kriging/GaussianVariogram.h\
+					./classes/kriging/GaussianVariogram.cpp\
+					./classes/kriging/ExponentialVariogram.h\
+					./classes/kriging/ExponentialVariogram.cpp\
+					./classes/kriging/SphericalVariogram.h\
+					./classes/kriging/SphericalVariogram.cpp\
+					./classes/kriging/PowerVariogram.h\
+					./classes/kriging/PowerVariogram.cpp\
+					./classes/kriging/Quadtree.h\
+					./classes/kriging/Quadtree.cpp\
+					./classes/kriging/Observation.h\
+					./classes/kriging/Observation.cpp\
+					./modules/Krigingx/Krigingx.cpp\
+					./modules/Krigingx/Krigingx.h
+issm_sources +=$(kriging_sources)
+issm_sources +=./modules/Krigingx/pKrigingx.cpp
+endif
+#}}}
+#Kml sources  {{{
+kml_sources = ./modules/Exp2Kmlx/Exp2Kmlx.h\
+				  ./modules/Exp2Kmlx/Exp2Kmlx.cpp\
+				  ./modules/Kml2Expx/Kml2Expx.h\
+				  ./modules/Kml2Expx/Kml2Expx.cpp\
+				  ./modules/Shp2Kmlx/Shp2Kmlx.h\
+				  ./modules/Shp2Kmlx/Shp2Kmlx.cpp\
+				  ./modules/KMLFileReadx/KMLFileReadx.h\
+				  ./modules/KMLFileReadx/KMLFileReadx.cpp\
+				  ./modules/KMLMeshWritex/KMLMeshWritex.h\
+				  ./modules/KMLMeshWritex/KMLMeshWritex.cpp\
+				  ./modules/KMLOverlayx/KMLOverlayx.h\
+				  ./modules/KMLOverlayx/KMLOverlayx.cpp\
+				  ./kml/kmlobjects.h\
+				  ./kml/KML_Attribute.cpp\
+				  ./kml/KML_Attribute.h\
+				  ./kml/KML_Comment.cpp\
+				  ./kml/KML_Comment.h\
+				  ./kml/KML_ColorStyle.cpp\
+				  ./kml/KML_ColorStyle.h\
+				  ./kml/KML_Container.cpp\
+				  ./kml/KML_Container.h\
+				  ./kml/KML_Document.cpp\
+				  ./kml/KML_Document.h\
+				  ./kml/KML_Feature.cpp\
+				  ./kml/KML_Feature.h\
+				  ./kml/KML_File.cpp\
+				  ./kml/KML_File.h\
+				  ./kml/KML_Folder.cpp\
+				  ./kml/KML_Folder.h\
+				  ./kml/KML_Geometry.cpp\
+				  ./kml/KML_Geometry.h\
+				  ./kml/KML_GroundOverlay.cpp\
+				  ./kml/KML_GroundOverlay.h\
+				  ./kml/KML_Icon.cpp\
+				  ./kml/KML_Icon.h\
+				  ./kml/KML_LatLonBox.cpp\
+				  ./kml/KML_LatLonBox.h\
+				  ./kml/KML_LinearRing.cpp\
+				  ./kml/KML_LinearRing.h\
+				  ./kml/KML_LineString.cpp\
+				  ./kml/KML_LineString.h\
+				  ./kml/KML_LineStyle.cpp\
+				  ./kml/KML_LineStyle.h\
+				  ./kml/KML_MultiGeometry.cpp\
+				  ./kml/KML_MultiGeometry.h\
+				  ./kml/KML_Object.cpp\
+				  ./kml/KML_Object.h\
+				  ./kml/KML_Overlay.cpp\
+				  ./kml/KML_Overlay.h\
+				  ./kml/KML_Point.cpp\
+				  ./kml/KML_Point.h\
+				  ./kml/KML_Placemark.cpp\
+				  ./kml/KML_Placemark.h\
+				  ./kml/KML_Polygon.cpp\
+				  ./kml/KML_Polygon.h\
+				  ./kml/KML_PolyStyle.cpp\
+				  ./kml/KML_PolyStyle.h\
+				  ./kml/KML_Style.cpp\
+				  ./kml/KML_Style.h\
+				  ./kml/KML_StyleSelector.cpp\
+				  ./kml/KML_StyleSelector.h\
+				  ./kml/KML_SubStyle.cpp\
+				  ./kml/KML_SubStyle.h\
+				  ./kml/KML_Unknown.cpp\
+				  ./kml/KML_Unknown.h\
+				  ./kml/KMLFileReadUtils.cpp\
+				  ./kml/KMLFileReadUtils.h
 #}}}
 #Modules sources{{{
@@ -841,108 +853,4 @@
 endif
 #}}}
-
-#{{{ Conditional build-up of sources
-#ISSM sources are a combination of core sources and sources related to specific capabilities (which can 
-#be activated by autotools conditionals 
-
-#First the core
-issm_sources  =  $(core_sources)
-
-#Now the optional source
-if DAKOTA
-issm_sources  +=  $(dakota_sources)
-endif
-
-if PETSC
-issm_sources  +=  $(petsc_sources)
-endif
-
-if MUMPS
-issm_sources  +=  $(mumps_sources)
-endif
-
-if GSL
-issm_sources  +=  $(gsl_sources)
-endif
-
-if TRANSIENT
-issm_sources  +=  $(transient_sources)
-endif
-
-if STEADYSTATE
-issm_sources  +=  $(steadystate_sources)
-endif
-
-if MASSTRANSPORT
-issm_sources  +=  $(masstransport_sources)
-endif
-
-if THERMAL
-issm_sources  +=  $(thermal_sources)
-endif
-
-if GIA
-issm_sources  +=  $(gia_sources)
-endif
-
-if CONTROL
-issm_sources  +=  $(control_sources)
-endif
-
-if HYDROLOGY
-issm_sources  +=  $(hydrology_sources)
-endif
-
-if STRESSBALANCE
-issm_sources  +=  $(stressbalance_sources)
-endif
-
-if BALANCED
-issm_sources  +=  $(balanced_sources)
-endif
-
-if SLOPE
-issm_sources  +=  $(slope_sources)
-endif
-
-if MESHDEFORMATION
-issm_sources  +=  $(meshdeformation_sources)
-endif
-
-if GROUNDINGLINE
-issm_sources +=  $(groundingline_sources)
-endif
-
-if RIFTS
-issm_sources +=  $(rifts_sources)
-endif
-
-if RESPONSES
-issm_sources +=  $(responses_sources)
-endif
-
-if ANDROID
-issm_sources +=  $(android_sources)
-endif
-
-if THREED
-issm_sources +=  $(threed_sources)
-endif
-
-if MPI
-issm_sources +=  $(mpi_sources)
-endif
-
-if METIS
-issm_sources +=  $(metis_sources)
-endif
-
-if KRIGING
-issm_sources +=  $(pkriging_sources)
-endif
-
-if DAMAGE
-issm_sources +=  $(damage_sources)
-endif
 #}}}
 #Library flags and sources {{{
@@ -1020,5 +928,5 @@
 endif
 #}}}
-#Automatic differentiation: append this fold to the end of the src/c/Makefile.am to get this Makefile.am {{{
+#Automatic differentiation (must be done at the end) {{{
 if ADIC2 
 lib_LIBRARIES += libAD.a libISSMRose.a
@@ -1028,5 +936,4 @@
 libAD_a_SOURCES = 
 libAD_a_CFLAGS = -fPIC -D_C_ $(COPTFLAGS)
-
 
 #test rose preprocessing 
@@ -1036,11 +943,7 @@
 libISSMRose_a_CXXFLAGS= -fPIC -D_C_ $(CXXOPTFLAGS)
 
-
-
 #Automatic differentiation rules: 
 %.ad.c: %.c
 	adic2 -mforward  $< --nary
-
-
 
 #Executable
Index: /issm/trunk/src/c/analyses/AdjointBalancethicknessAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/AdjointBalancethicknessAnalysis.cpp	(revision 17805)
+++ /issm/trunk/src/c/analyses/AdjointBalancethicknessAnalysis.cpp	(revision 17806)
@@ -6,5 +6,5 @@
 
 /*Model processor*/
-int  AdjointBalancethicknessAnalysis::DofsPerNode(int** doflist,int meshtype,int approximation){/*{{{*/
+int  AdjointBalancethicknessAnalysis::DofsPerNode(int** doflist,int domaintype,int approximation){/*{{{*/
 	return 1;
 }/*}}}*/
@@ -24,2 +24,146 @@
 	_error_("not implemented yet");
 }/*}}}*/
+
+/*Finite Element Analysis*/
+void           AdjointBalancethicknessAnalysis::Core(FemModel* femmodel){/*{{{*/
+	_error_("not implemented");
+}/*}}}*/
+ElementVector* AdjointBalancethicknessAnalysis::CreateDVector(Element* element){/*{{{*/
+	/*Default, return NULL*/
+	return NULL;
+}/*}}}*/
+ElementMatrix* AdjointBalancethicknessAnalysis::CreateJacobianMatrix(Element* element){/*{{{*/
+_error_("Not implemented");
+}/*}}}*/
+ElementMatrix* AdjointBalancethicknessAnalysis::CreateKMatrix(Element* element){/*{{{*/
+
+	BalancethicknessAnalysis* analysis = new BalancethicknessAnalysis();
+	ElementMatrix* Ke = analysis->CreateKMatrix(element);
+	delete analysis;
+
+	/*Transpose and return Ke*/
+	Ke->Transpose();
+	return Ke;
+}/*}}}*/
+ElementVector* AdjointBalancethicknessAnalysis::CreatePVector(Element* element){/*{{{*/
+
+	/*Intermediaries*/
+	int      domaintype;
+	Element* basalelement;
+
+	/*Get basal element*/
+	element->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DhorizontalEnum:
+			basalelement = element;
+			break;
+		case Domain3DEnum:
+			if(!element->IsOnBase()) return NULL;
+			basalelement = element->SpawnBasalElement();
+			break;
+		default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
+	}
+
+	/*Intermediaries */
+	int         num_responses,i;
+	IssmDouble  dH[2];
+	IssmDouble  vx,vy,vel,Jdet;
+	IssmDouble  thickness,thicknessobs,weight;
+	int        *responses = NULL;
+	IssmDouble *xyz_list  = NULL;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = basalelement->GetNumberOfNodes();
+
+	/*Initialize Element vector and vectors*/
+	ElementVector* pe     = basalelement->NewElementVector(SSAApproximationEnum);
+	IssmDouble*    basis  = xNew<IssmDouble>(numnodes);
+	IssmDouble*    dbasis = xNew<IssmDouble>(2*numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	basalelement->GetVerticesCoordinates(&xyz_list);
+	basalelement->FindParam(&num_responses,InversionNumCostFunctionsEnum);
+	basalelement->FindParam(&responses,NULL,InversionCostFunctionsEnum);
+	Input* thickness_input    = basalelement->GetInput(ThicknessEnum);                          _assert_(thickness_input);
+	Input* thicknessobs_input = basalelement->GetInput(InversionThicknessObsEnum);              _assert_(thicknessobs_input);
+	Input* weights_input      = basalelement->GetInput(InversionCostFunctionsCoefficientsEnum); _assert_(weights_input);
+	Input* vx_input           = basalelement->GetInput(VxEnum);                                 _assert_(vx_input);
+	Input* vy_input           = basalelement->GetInput(VyEnum);                                 _assert_(vy_input);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=basalelement->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		basalelement->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		basalelement->NodalFunctions(basis,gauss);
+		basalelement->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+
+		thickness_input->GetInputValue(&thickness, gauss);
+		thickness_input->GetInputDerivativeValue(&dH[0],xyz_list,gauss);
+		thicknessobs_input->GetInputValue(&thicknessobs, gauss);
+
+		/*Loop over all requested responses*/
+		for(int resp=0;resp<num_responses;resp++){
+			weights_input->GetInputValue(&weight,gauss,responses[resp]);
+
+			switch(responses[resp]){
+				case ThicknessAbsMisfitEnum:
+					for(i=0;i<numnodes;i++) pe->values[i]+=(thicknessobs-thickness)*weight*Jdet*gauss->weight*basis[i];
+					break;
+				case ThicknessAbsGradientEnum:
+					for(i=0;i<numnodes;i++) pe->values[i]+= - weight*dH[0]*dbasis[0*numnodes+i]*Jdet*gauss->weight;
+					for(i=0;i<numnodes;i++) pe->values[i]+= - weight*dH[1]*dbasis[1*numnodes+i]*Jdet*gauss->weight;
+					break;
+				case ThicknessAlongGradientEnum:
+					vx_input->GetInputValue(&vx,gauss);
+					vy_input->GetInputValue(&vy,gauss);
+					vel = sqrt(vx*vx+vy*vy);
+					vx  = vx/(vel+1.e-9);
+					vy  = vy/(vel+1.e-9);
+					for(i=0;i<numnodes;i++) pe->values[i]+= - weight*(dH[0]*vx+dH[1]*vy)*(dbasis[0*numnodes+i]*vx+dbasis[1*numnodes+i]*vy)*Jdet*gauss->weight;
+					break;
+				case ThicknessAcrossGradientEnum:
+					vx_input->GetInputValue(&vx,gauss);
+					vy_input->GetInputValue(&vy,gauss);
+					vel = sqrt(vx*vx+vy*vy);
+					vx  = vx/(vel+1.e-9);
+					vy  = vy/(vel+1.e-9);
+					for(i=0;i<numnodes;i++) pe->values[i]+= - weight*(dH[0]*(-vy)+dH[1]*vx)*(dbasis[0*numnodes+i]*(-vy)+dbasis[1*numnodes+i]*vx)*Jdet*gauss->weight;
+					break;
+				default:
+					_error_("response " << EnumToStringx(responses[resp]) << " not supported yet");
+			}
+		}
+	}
+
+	/*Clean up and return*/
+	xDelete<int>(responses);
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(basis);
+	xDelete<IssmDouble>(dbasis);
+	if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;};
+	delete gauss;
+	return pe;
+}/*}}}*/
+void AdjointBalancethicknessAnalysis::GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element){/*{{{*/
+	_error_("not implemented yet");
+}/*}}}*/
+void AdjointBalancethicknessAnalysis::InputUpdateFromSolution(IssmDouble* solution,Element* element){/*{{{*/
+
+	int domaintype;
+	element->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DhorizontalEnum:
+			element->InputUpdateFromSolutionOneDof(solution,AdjointEnum);
+			break;
+		case Domain3DEnum:
+			element->InputUpdateFromSolutionOneDofCollapsed(solution,AdjointEnum);
+			break;
+		default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
+	}
+}/*}}}*/
+void AdjointBalancethicknessAnalysis::UpdateConstraints(FemModel* femmodel){/*{{{*/
+	/*Default, do nothing*/
+	return;
+}/*}}}*/
Index: /issm/trunk/src/c/analyses/AdjointBalancethicknessAnalysis.h
===================================================================
--- /issm/trunk/src/c/analyses/AdjointBalancethicknessAnalysis.h	(revision 17805)
+++ /issm/trunk/src/c/analyses/AdjointBalancethicknessAnalysis.h	(revision 17806)
@@ -12,5 +12,6 @@
 
 	public:
-		int  DofsPerNode(int** doflist,int meshtype,int approximation);
+		/*Model processing*/
+		int  DofsPerNode(int** doflist,int domaintype,int approximation);
 		void UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum);
 		void UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);
@@ -18,4 +19,14 @@
 		void CreateConstraints(Constraints* constraints,IoModel* iomodel);
 		void CreateLoads(Loads* loads, IoModel* iomodel);
+
+		/*Finite element Analysis*/
+		void           Core(FemModel* femmodel);
+		ElementVector* CreateDVector(Element* element);
+		ElementMatrix* CreateJacobianMatrix(Element* element);
+		ElementMatrix* CreateKMatrix(Element* element);
+		ElementVector* CreatePVector(Element* element);
+		void GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element);
+		void InputUpdateFromSolution(IssmDouble* solution,Element* element);
+		void UpdateConstraints(FemModel* femmodel);
 };
 #endif
Index: /issm/trunk/src/c/analyses/AdjointHorizAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/AdjointHorizAnalysis.cpp	(revision 17805)
+++ /issm/trunk/src/c/analyses/AdjointHorizAnalysis.cpp	(revision 17806)
@@ -6,5 +6,5 @@
 
 /*Model processing*/
-int  AdjointHorizAnalysis::DofsPerNode(int** doflist,int meshtype,int approximation){/*{{{*/
+int  AdjointHorizAnalysis::DofsPerNode(int** doflist,int domaintype,int approximation){/*{{{*/
 	_error_("not implemented");
 }/*}}}*/
@@ -24,2 +24,973 @@
 	   _error_("not implemented yet");
 }/*}}}*/
+
+/*Finite Element Analysis*/
+void           AdjointHorizAnalysis::Core(FemModel* femmodel){/*{{{*/
+	_error_("not implemented");
+}/*}}}*/
+ElementVector* AdjointHorizAnalysis::CreateDVector(Element* element){/*{{{*/
+	/*Default, return NULL*/
+	return NULL;
+}/*}}}*/
+ElementMatrix* AdjointHorizAnalysis::CreateJacobianMatrix(Element* element){/*{{{*/
+_error_("Not implemented");
+}/*}}}*/
+ElementMatrix* AdjointHorizAnalysis::CreateKMatrix(Element* element){/*{{{*/
+	int approximation;
+	element->GetInputValue(&approximation,ApproximationEnum);
+	switch(approximation){
+		case SSAApproximationEnum: 
+			return CreateKMatrixSSA(element);
+		case HOApproximationEnum: 
+			return CreateKMatrixHO(element);
+		case FSApproximationEnum: 
+			return CreateKMatrixFS(element);
+		case NoneApproximationEnum:
+			return NULL;
+		default:
+			_error_("Approximation "<<EnumToStringx(approximation)<<" not supported");
+	}
+}/*}}}*/
+ElementMatrix* AdjointHorizAnalysis::CreateKMatrixSSA(Element* element){/*{{{*/
+
+	/*Intermediaries*/
+	int      domaintype;
+	Element* basalelement;
+
+	/*Get basal element*/
+	element->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DhorizontalEnum:
+			basalelement = element;
+			break;
+		case Domain3DEnum:
+			if(!element->IsOnBase()) return NULL;
+			basalelement = element->SpawnBasalElement();
+			break;
+		default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
+	}
+
+	/*Intermediaries */
+	bool        incomplete_adjoint;
+	IssmDouble  Jdet,thickness,mu_prime;
+	IssmDouble  eps1dotdphii,eps1dotdphij,eps2dotdphii,eps2dotdphij;
+	IssmDouble  eps1[2],eps2[2],epsilon[3];
+	IssmDouble *xyz_list = NULL;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = basalelement->GetNumberOfNodes();
+
+	/*Initialize Jacobian with regular SSA (first part of the Gateau derivative)*/
+	basalelement->FindParam(&incomplete_adjoint,InversionIncompleteAdjointEnum);
+	StressbalanceAnalysis* analysis = new StressbalanceAnalysis();
+	ElementMatrix* Ke=analysis->CreateKMatrix(element);
+	delete analysis;
+	if(incomplete_adjoint){
+		if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;};
+		return Ke;
+	}
+
+	/*Retrieve all inputs and parameters*/
+	basalelement->GetVerticesCoordinates(&xyz_list);
+	Input* vx_input        = basalelement->GetInput(VxEnum);       _assert_(vx_input);
+	Input* vy_input        = basalelement->GetInput(VyEnum);       _assert_(vy_input);
+	Input* thickness_input = basalelement->GetInput(ThicknessEnum); _assert_(thickness_input);
+
+	/*Allocate dbasis*/
+	IssmDouble* dbasis = xNew<IssmDouble>(2*numnodes);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=basalelement->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		basalelement->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		basalelement->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+
+		thickness_input->GetInputValue(&thickness, gauss);
+		basalelement->StrainRateSSA(&epsilon[0],xyz_list,gauss,vx_input,vy_input);
+		basalelement->ViscositySSADerivativeEpsSquare(&mu_prime,&epsilon[0]);
+		eps1[0]=2.*epsilon[0]+epsilon[1]; eps2[0]=epsilon[2];
+		eps1[1]=epsilon[2];               eps2[1]=epsilon[0]+2*epsilon[1];
+
+		for(int i=0;i<numnodes;i++){
+			for(int j=0;j<numnodes;j++){
+				eps1dotdphii=eps1[0]*dbasis[0*numnodes+i]+eps1[1]*dbasis[1*numnodes+i];
+				eps1dotdphij=eps1[0]*dbasis[0*numnodes+j]+eps1[1]*dbasis[1*numnodes+j];
+				eps2dotdphii=eps2[0]*dbasis[0*numnodes+i]+eps2[1]*dbasis[1*numnodes+i];
+				eps2dotdphij=eps2[0]*dbasis[0*numnodes+j]+eps2[1]*dbasis[1*numnodes+j];
+
+				Ke->values[2*numnodes*(2*i+0)+2*j+0]+=gauss->weight*Jdet*2*mu_prime*thickness*eps1dotdphij*eps1dotdphii;
+				Ke->values[2*numnodes*(2*i+0)+2*j+1]+=gauss->weight*Jdet*2*mu_prime*thickness*eps2dotdphij*eps1dotdphii;
+				Ke->values[2*numnodes*(2*i+1)+2*j+0]+=gauss->weight*Jdet*2*mu_prime*thickness*eps1dotdphij*eps2dotdphii;
+				Ke->values[2*numnodes*(2*i+1)+2*j+1]+=gauss->weight*Jdet*2*mu_prime*thickness*eps2dotdphij*eps2dotdphii;
+			}
+		}
+	}
+
+	/*Transform Coordinate System*/
+	basalelement->TransformStiffnessMatrixCoord(Ke,XYEnum);
+
+	/*Clean up and return*/
+	delete gauss;
+	xDelete<IssmDouble>(dbasis);
+	xDelete<IssmDouble>(xyz_list);
+	if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;};
+	return Ke;
+}/*}}}*/
+ElementMatrix* AdjointHorizAnalysis::CreateKMatrixHO(Element* element){/*{{{*/
+
+	/*Intermediaries */
+	bool        incomplete_adjoint;
+	IssmDouble  Jdet,mu_prime;
+	IssmDouble  eps1dotdphii,eps1dotdphij,eps2dotdphii,eps2dotdphij;
+	IssmDouble  eps1[3],eps2[3],epsilon[5];/* epsilon=[exx,eyy,exy,exz,eyz];*/
+	IssmDouble *xyz_list = NULL;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Initialize Jacobian with regular HO (first part of the Gateau derivative)*/
+	element->FindParam(&incomplete_adjoint,InversionIncompleteAdjointEnum);
+	StressbalanceAnalysis* analysis = new StressbalanceAnalysis();
+	ElementMatrix* Ke=analysis->CreateKMatrix(element);
+	delete analysis;
+	if(incomplete_adjoint) return Ke;
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+	Input* vx_input = element->GetInput(VxEnum); _assert_(vx_input);
+	Input* vy_input = element->GetInput(VyEnum); _assert_(vy_input);
+
+	/*Allocate dbasis*/
+	IssmDouble* dbasis = xNew<IssmDouble>(3*numnodes);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGauss(5);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		element->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+
+		element->StrainRateHO(&epsilon[0],xyz_list,gauss,vx_input,vy_input);
+		element->ViscosityHODerivativeEpsSquare(&mu_prime,&epsilon[0]);
+		eps1[0]=2.*epsilon[0]+epsilon[1];   eps2[0]=epsilon[2];
+		eps1[1]=epsilon[2];                 eps2[1]=epsilon[0]+2.*epsilon[1];
+		eps1[2]=epsilon[3];                 eps2[2]=epsilon[4];
+
+		for(int i=0;i<numnodes;i++){
+			for(int j=0;j<numnodes;j++){
+				eps1dotdphii=eps1[0]*dbasis[0*numnodes+i]+eps1[1]*dbasis[1*numnodes+i]+eps1[2]*dbasis[2*numnodes+i];
+				eps1dotdphij=eps1[0]*dbasis[0*numnodes+j]+eps1[1]*dbasis[1*numnodes+j]+eps1[2]*dbasis[2*numnodes+j];
+				eps2dotdphii=eps2[0]*dbasis[0*numnodes+i]+eps2[1]*dbasis[1*numnodes+i]+eps2[2]*dbasis[2*numnodes+i];
+				eps2dotdphij=eps2[0]*dbasis[0*numnodes+j]+eps2[1]*dbasis[1*numnodes+j]+eps2[2]*dbasis[2*numnodes+j];
+
+				Ke->values[2*numnodes*(2*i+0)+2*j+0]+=gauss->weight*Jdet*2*mu_prime*eps1dotdphij*eps1dotdphii;
+				Ke->values[2*numnodes*(2*i+0)+2*j+1]+=gauss->weight*Jdet*2*mu_prime*eps2dotdphij*eps1dotdphii;
+				Ke->values[2*numnodes*(2*i+1)+2*j+0]+=gauss->weight*Jdet*2*mu_prime*eps1dotdphij*eps2dotdphii;
+				Ke->values[2*numnodes*(2*i+1)+2*j+1]+=gauss->weight*Jdet*2*mu_prime*eps2dotdphij*eps2dotdphii;
+			}
+		}
+	}
+
+	/*Transform Coordinate System*/
+	element->TransformStiffnessMatrixCoord(Ke,XYEnum);
+
+	/*Clean up and return*/
+	delete gauss;
+	xDelete<IssmDouble>(dbasis);
+	xDelete<IssmDouble>(xyz_list);
+	return Ke;
+}/*}}}*/
+ElementMatrix* AdjointHorizAnalysis::CreateKMatrixFS(Element* element){/*{{{*/
+
+	/*Intermediaries */
+	bool        incomplete_adjoint;
+	IssmDouble  Jdet,mu_prime;
+	IssmDouble  eps1dotdphii,eps1dotdphij,eps2dotdphii,eps2dotdphij,eps3dotdphii,eps3dotdphij;
+	IssmDouble  eps1[3],eps2[3],eps3[3],epsilon[5];/* epsilon=[exx,eyy,exy,exz,eyz];*/
+	IssmDouble *xyz_list = NULL;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int vnumnodes = element->NumberofNodesVelocity();
+	int pnumnodes = element->NumberofNodesPressure();
+	int numdof    = vnumnodes*3 + pnumnodes;
+
+	/*Initialize Jacobian with regular FS (first part of the Gateau derivative)*/
+	element->FindParam(&incomplete_adjoint,InversionIncompleteAdjointEnum);
+	StressbalanceAnalysis* analysis = new StressbalanceAnalysis();
+	ElementMatrix* Ke=analysis->CreateKMatrix(element);
+	delete analysis;
+	if(incomplete_adjoint) return Ke;
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+	Input* vx_input = element->GetInput(VxEnum);_assert_(vx_input);
+	Input* vy_input = element->GetInput(VyEnum);_assert_(vy_input);
+	Input* vz_input = element->GetInput(VzEnum);_assert_(vz_input);
+
+	/*Allocate dbasis*/
+	IssmDouble* dbasis = xNew<IssmDouble>(3*vnumnodes);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGauss(5);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		element->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+
+		element->StrainRateHO(&epsilon[0],xyz_list,gauss,vx_input,vy_input);
+		element->ViscosityFSDerivativeEpsSquare(&mu_prime,&epsilon[0]);
+		eps1[0]=epsilon[0];   eps2[0]=epsilon[2];   eps3[0]=epsilon[3];
+		eps1[1]=epsilon[2];   eps2[1]=epsilon[1];   eps3[1]=epsilon[4];
+		eps1[2]=epsilon[3];   eps2[2]=epsilon[4];   eps3[2]= -epsilon[0] -epsilon[1];
+
+		for(int i=0;i<vnumnodes;i++){
+			for(int j=0;j<vnumnodes;j++){
+				eps1dotdphii=eps1[0]*dbasis[0*vnumnodes+i]+eps1[1]*dbasis[1*vnumnodes+i]+eps1[2]*dbasis[2*vnumnodes+i];
+				eps1dotdphij=eps1[0]*dbasis[0*vnumnodes+j]+eps1[1]*dbasis[1*vnumnodes+j]+eps1[2]*dbasis[2*vnumnodes+j];
+				eps2dotdphii=eps2[0]*dbasis[0*vnumnodes+i]+eps2[1]*dbasis[1*vnumnodes+i]+eps2[2]*dbasis[2*vnumnodes+i];
+				eps2dotdphij=eps2[0]*dbasis[0*vnumnodes+j]+eps2[1]*dbasis[1*vnumnodes+j]+eps2[2]*dbasis[2*vnumnodes+j];
+				eps3dotdphii=eps3[0]*dbasis[0*vnumnodes+i]+eps3[1]*dbasis[1*vnumnodes+i]+eps3[2]*dbasis[2*vnumnodes+i];
+				eps3dotdphij=eps3[0]*dbasis[0*vnumnodes+j]+eps3[1]*dbasis[1*vnumnodes+j]+eps3[2]*dbasis[2*vnumnodes+j];
+
+				Ke->values[numdof*(4*i+0)+4*j+0]+=gauss->weight*Jdet*2*mu_prime*eps1dotdphij*eps1dotdphii;
+				Ke->values[numdof*(4*i+0)+4*j+1]+=gauss->weight*Jdet*2*mu_prime*eps2dotdphij*eps1dotdphii;
+				Ke->values[numdof*(4*i+0)+4*j+2]+=gauss->weight*Jdet*2*mu_prime*eps3dotdphij*eps1dotdphii;
+
+				Ke->values[numdof*(4*i+1)+4*j+0]+=gauss->weight*Jdet*2*mu_prime*eps1dotdphij*eps2dotdphii;
+				Ke->values[numdof*(4*i+1)+4*j+1]+=gauss->weight*Jdet*2*mu_prime*eps2dotdphij*eps2dotdphii;
+				Ke->values[numdof*(4*i+1)+4*j+2]+=gauss->weight*Jdet*2*mu_prime*eps3dotdphij*eps2dotdphii;
+
+				Ke->values[numdof*(4*i+2)+4*j+0]+=gauss->weight*Jdet*2*mu_prime*eps1dotdphij*eps3dotdphii;
+				Ke->values[numdof*(4*i+2)+4*j+1]+=gauss->weight*Jdet*2*mu_prime*eps2dotdphij*eps3dotdphii;
+				Ke->values[numdof*(4*i+2)+4*j+2]+=gauss->weight*Jdet*2*mu_prime*eps3dotdphij*eps3dotdphii;
+			}
+		}
+	}
+
+	/*Transform Coordinate System*/
+	element->TransformStiffnessMatrixCoord(Ke,XYZEnum);
+
+	/*Clean up and return*/
+	delete gauss;
+	xDelete<IssmDouble>(dbasis);
+	xDelete<IssmDouble>(xyz_list);
+	return Ke;
+}/*}}}*/
+ElementVector* AdjointHorizAnalysis::CreatePVector(Element* element){/*{{{*/
+
+	int approximation;
+	element->GetInputValue(&approximation,ApproximationEnum);
+	switch(approximation){
+		case SSAApproximationEnum: 
+			return CreatePVectorSSA(element);
+		case HOApproximationEnum: 
+			return CreatePVectorHO(element);
+		case FSApproximationEnum: 
+			return CreatePVectorFS(element);
+		case NoneApproximationEnum:
+			return NULL;
+		default:
+			_error_("Approximation "<<EnumToStringx(approximation)<<" not supported");
+	}
+}/*}}}*/
+ElementVector* AdjointHorizAnalysis::CreatePVectorFS(Element* element){/*{{{*/
+
+	/*Nothing to be done if not on surface*/
+	if(!element->IsOnSurface()) return NULL;
+
+	/*Intermediaries */
+	int        num_responses,i,dim;
+	IssmDouble Jdet,obs_velocity_mag,velocity_mag;
+	IssmDouble vx,vy,vxobs,vyobs,dux,duy,weight;
+	IssmDouble scalex,scaley,scale,S;
+	int        *responses    = NULL;
+	IssmDouble *xyz_list_top = NULL;
+
+	/*Get problem dimension*/
+	element->FindParam(&dim,DomainDimensionEnum);
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int vnumnodes = element->NumberofNodesVelocity();
+	int pnumnodes = element->NumberofNodesPressure();
+
+	/*Prepare coordinate system list*/
+	int* cs_list = xNew<int>(vnumnodes+pnumnodes);
+	for(i=0;i<vnumnodes;i++) cs_list[i]           = XYZEnum;
+	for(i=0;i<pnumnodes;i++) cs_list[vnumnodes+i] = PressureEnum;
+
+	/*Initialize Element vector and vectors*/
+	ElementVector* pe     = element->NewElementVector(FSApproximationEnum);
+	IssmDouble*    vbasis = xNew<IssmDouble>(vnumnodes);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinatesTop(&xyz_list_top);
+	element->FindParam(&num_responses,InversionNumCostFunctionsEnum);
+	element->FindParam(&responses,NULL,InversionCostFunctionsEnum);
+	Input* weights_input = element->GetInput(InversionCostFunctionsCoefficientsEnum); _assert_(weights_input);
+	Input* vx_input      = element->GetInput(VxEnum);                                 _assert_(vx_input);
+	Input* vy_input      = element->GetInput(VyEnum);                                 _assert_(vy_input);
+	Input* vxobs_input   = element->GetInput(InversionVxObsEnum);                     _assert_(vxobs_input);
+	Input* vyobs_input   = element->GetInput(InversionVyObsEnum);                     _assert_(vyobs_input);
+	IssmDouble epsvel  = 2.220446049250313e-16;
+	IssmDouble meanvel = 3.170979198376458e-05; /*1000 m/yr*/
+
+	/*Get Surface if required by one response*/
+	for(int resp=0;resp<num_responses;resp++){
+		if(responses[resp]==SurfaceAverageVelMisfitEnum){
+			element->GetInputValue(&S,SurfaceAreaEnum); break;
+		}
+	}
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGaussTop(4);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminantTop(&Jdet,xyz_list_top,gauss);
+		element->NodalFunctionsVelocity(vbasis,gauss);
+
+		vx_input->GetInputValue(&vx,gauss);
+		vy_input->GetInputValue(&vy,gauss);
+		vxobs_input->GetInputValue(&vxobs,gauss);
+		vyobs_input->GetInputValue(&vyobs,gauss);
+
+		/*Loop over all requested responses*/
+		for(int resp=0;resp<num_responses;resp++){
+			weights_input->GetInputValue(&weight,gauss,responses[resp]);
+
+			switch(responses[resp]){
+				case SurfaceAbsVelMisfitEnum:
+					/*
+					 *      1  [           2              2 ]
+					 * J = --- | (u - u   )  +  (v - v   )  |
+					 *      2  [       obs            obs   ]
+					 *
+					 *        dJ
+					 * DU = - -- = (u   - u )
+					 *        du     obs
+					 */
+					for(i=0;i<vnumnodes;i++){
+						dux=vxobs-vx;
+						duy=vyobs-vy;
+						pe->values[i*dim+0]+=dux*weight*Jdet*gauss->weight*vbasis[i]; 
+						pe->values[i*dim+1]+=duy*weight*Jdet*gauss->weight*vbasis[i]; 
+					}
+					break;
+				case SurfaceRelVelMisfitEnum:
+					/*
+					 *      1  [     \bar{v}^2             2   \bar{v}^2              2 ]
+					 * J = --- | -------------  (u - u   ) + -------------  (v - v   )  |
+					 *      2  [  (u   + eps)^2       obs    (v   + eps)^2       obs    ]
+					 *              obs                        obs                      
+					 *
+					 *        dJ     \bar{v}^2
+					 * DU = - -- = ------------- (u   - u )
+					 *        du   (u   + eps)^2    obs
+					 *               obs
+					 */
+					for(i=0;i<vnumnodes;i++){
+						scalex=pow(meanvel/(vxobs+epsvel),2); if(vxobs==0)scalex=0;
+						scaley=pow(meanvel/(vyobs+epsvel),2); if(vyobs==0)scaley=0;
+						dux=scalex*(vxobs-vx);
+						duy=scaley*(vyobs-vy);
+						pe->values[i*dim+0]+=dux*weight*Jdet*gauss->weight*vbasis[i]; 
+						pe->values[i*dim+1]+=duy*weight*Jdet*gauss->weight*vbasis[i]; 
+					}
+					break;
+				case SurfaceLogVelMisfitEnum:
+					/*
+					 *                 [        vel + eps     ] 2
+					 * J = 4 \bar{v}^2 | log ( -----------  ) |  
+					 *                 [       vel   + eps    ]
+					 *                            obs
+					 *
+					 *        dJ                 2 * log(...)
+					 * DU = - -- = - 4 \bar{v}^2 -------------  u
+					 *        du                 vel^2 + eps
+					 *            
+					 */
+					for(i=0;i<vnumnodes;i++){
+						velocity_mag    =sqrt(pow(vx,   2)+pow(vy,   2))+epsvel;
+						obs_velocity_mag=sqrt(pow(vxobs,2)+pow(vyobs,2))+epsvel;
+						scale=-8*pow(meanvel,2)/pow(velocity_mag,2)*log(velocity_mag/obs_velocity_mag);
+						dux=scale*vx;
+						duy=scale*vy;
+						pe->values[i*dim+0]+=dux*weight*Jdet*gauss->weight*vbasis[i]; 
+						pe->values[i*dim+1]+=duy*weight*Jdet*gauss->weight*vbasis[i]; 
+					}
+					break;
+				case SurfaceAverageVelMisfitEnum:
+					/*
+					 *      1                    2              2
+					 * J = ---  sqrt(  (u - u   )  +  (v - v   )  )
+					 *      S                obs            obs
+					 *
+					 *        dJ      1       1 
+					 * DU = - -- = - --- ----------- * 2 (u - u   )
+					 *        du      S  2 sqrt(...)           obs
+					 */
+					for(i=0;i<vnumnodes;i++){
+						scale=1./(S*2*sqrt(pow(vx-vxobs,2)+pow(vy-vyobs,2))+epsvel);
+						dux=scale*(vxobs-vx);
+						duy=scale*(vyobs-vy);
+						pe->values[i*dim+0]+=dux*weight*Jdet*gauss->weight*vbasis[i]; 
+						pe->values[i*dim+1]+=duy*weight*Jdet*gauss->weight*vbasis[i]; 
+					}
+					break;
+				case SurfaceLogVxVyMisfitEnum:
+					/*
+					 *      1            [        |u| + eps     2          |v| + eps     2  ]
+					 * J = --- \bar{v}^2 | log ( -----------  )   +  log ( -----------  )   |  
+					 *      2            [       |u    |+ eps              |v    |+ eps     ]
+					 *                              obs                       obs
+					 *        dJ                              1      u                             1
+					 * DU = - -- = - \bar{v}^2 log(u...) --------- ----  ~ - \bar{v}^2 log(u...) ------
+					 *        du                         |u| + eps  |u|                           u + eps
+					 */
+					for(i=0;i<vnumnodes;i++){
+						dux = - meanvel*meanvel * log((fabs(vx)+epsvel)/(fabs(vxobs)+epsvel)) / (vx+epsvel);
+						duy = - meanvel*meanvel * log((fabs(vy)+epsvel)/(fabs(vyobs)+epsvel)) / (vy+epsvel);
+						pe->values[i*dim+0]+=dux*weight*Jdet*gauss->weight*vbasis[i]; 
+						pe->values[i*dim+1]+=duy*weight*Jdet*gauss->weight*vbasis[i]; 
+					}
+					break;
+				case DragCoefficientAbsGradientEnum:
+					/*Nothing in P vector*/
+					break;
+				case ThicknessAbsGradientEnum:
+					/*Nothing in P vector*/
+					break;
+				case ThicknessAlongGradientEnum:
+					/*Nothing in P vector*/
+					break;
+				case ThicknessAcrossGradientEnum:
+					/*Nothing in P vector*/
+					break;
+				case RheologyBbarAbsGradientEnum:
+					/*Nothing in P vector*/
+					break;
+				default:
+					_error_("response " << EnumToStringx(responses[resp]) << " not supported yet");
+			}
+		}
+	}
+
+	/*Transform coordinate system*/
+	element->TransformLoadVectorCoord(pe,cs_list);
+
+	/*Clean up and return*/
+	xDelete<int>(cs_list);
+	xDelete<int>(responses);
+	xDelete<IssmDouble>(xyz_list_top);
+	xDelete<IssmDouble>(vbasis);
+	delete gauss;
+	return pe;
+	_error_("S");
+}/*}}}*/
+ElementVector* AdjointHorizAnalysis::CreatePVectorHO(Element* element){/*{{{*/
+
+	/*Nothing to be done if not on surface*/
+	if(!element->IsOnSurface()) return NULL;
+
+	/*Intermediaries */
+	int        num_responses,i;
+	IssmDouble Jdet,obs_velocity_mag,velocity_mag;
+	IssmDouble vx,vy,vxobs,vyobs,dux,duy,weight;
+	IssmDouble scalex,scaley,scale,S;
+	int        *responses    = NULL;
+	IssmDouble *xyz_list_top = NULL;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Initialize Element vector and vectors*/
+	ElementVector* pe    = element->NewElementVector(HOApproximationEnum);
+	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinatesTop(&xyz_list_top);
+	element->FindParam(&num_responses,InversionNumCostFunctionsEnum);
+	element->FindParam(&responses,NULL,InversionCostFunctionsEnum);
+	Input* weights_input = element->GetInput(InversionCostFunctionsCoefficientsEnum); _assert_(weights_input);
+	Input* vx_input      = element->GetInput(VxEnum);                                 _assert_(vx_input);
+	Input* vy_input      = element->GetInput(VyEnum);                                 _assert_(vy_input);
+	Input* vxobs_input   = element->GetInput(InversionVxObsEnum);                     _assert_(vxobs_input);
+	Input* vyobs_input   = element->GetInput(InversionVyObsEnum);                     _assert_(vyobs_input);
+	IssmDouble epsvel  = 2.220446049250313e-16;
+	IssmDouble meanvel = 3.170979198376458e-05; /*1000 m/yr*/
+
+	/*Get Surface if required by one response*/
+	for(int resp=0;resp<num_responses;resp++){
+		if(responses[resp]==SurfaceAverageVelMisfitEnum){
+			element->GetInputValue(&S,SurfaceAreaEnum); break;
+		}
+	}
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGaussTop(4);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminantTop(&Jdet,xyz_list_top,gauss);
+		element->NodalFunctions(basis, gauss);
+
+		vx_input->GetInputValue(&vx,gauss);
+		vy_input->GetInputValue(&vy,gauss);
+		vxobs_input->GetInputValue(&vxobs,gauss);
+		vyobs_input->GetInputValue(&vyobs,gauss);
+
+		/*Loop over all requested responses*/
+		for(int resp=0;resp<num_responses;resp++){
+			weights_input->GetInputValue(&weight,gauss,responses[resp]);
+
+			switch(responses[resp]){
+				case SurfaceAbsVelMisfitEnum:
+					/*
+					 *      1  [           2              2 ]
+					 * J = --- | (u - u   )  +  (v - v   )  |
+					 *      2  [       obs            obs   ]
+					 *
+					 *        dJ
+					 * DU = - -- = (u   - u )
+					 *        du     obs
+					 */
+					for(i=0;i<numnodes;i++){
+						dux=vxobs-vx;
+						duy=vyobs-vy;
+						pe->values[i*2+0]+=dux*weight*Jdet*gauss->weight*basis[i]; 
+						pe->values[i*2+1]+=duy*weight*Jdet*gauss->weight*basis[i]; 
+					}
+					break;
+				case SurfaceRelVelMisfitEnum:
+					/*
+					 *      1  [     \bar{v}^2             2   \bar{v}^2              2 ]
+					 * J = --- | -------------  (u - u   ) + -------------  (v - v   )  |
+					 *      2  [  (u   + eps)^2       obs    (v   + eps)^2       obs    ]
+					 *              obs                        obs                      
+					 *
+					 *        dJ     \bar{v}^2
+					 * DU = - -- = ------------- (u   - u )
+					 *        du   (u   + eps)^2    obs
+					 *               obs
+					 */
+					for(i=0;i<numnodes;i++){
+						scalex=pow(meanvel/(vxobs+epsvel),2); if(vxobs==0)scalex=0;
+						scaley=pow(meanvel/(vyobs+epsvel),2); if(vyobs==0)scaley=0;
+						dux=scalex*(vxobs-vx);
+						duy=scaley*(vyobs-vy);
+						pe->values[i*2+0]+=dux*weight*Jdet*gauss->weight*basis[i]; 
+						pe->values[i*2+1]+=duy*weight*Jdet*gauss->weight*basis[i]; 
+					}
+					break;
+				case SurfaceLogVelMisfitEnum:
+					/*
+					 *                 [        vel + eps     ] 2
+					 * J = 4 \bar{v}^2 | log ( -----------  ) |  
+					 *                 [       vel   + eps    ]
+					 *                            obs
+					 *
+					 *        dJ                 2 * log(...)
+					 * DU = - -- = - 4 \bar{v}^2 -------------  u
+					 *        du                 vel^2 + eps
+					 *            
+					 */
+					for(i=0;i<numnodes;i++){
+						velocity_mag    =sqrt(pow(vx,   2)+pow(vy,   2))+epsvel;
+						obs_velocity_mag=sqrt(pow(vxobs,2)+pow(vyobs,2))+epsvel;
+						scale=-8*pow(meanvel,2)/pow(velocity_mag,2)*log(velocity_mag/obs_velocity_mag);
+						dux=scale*vx;
+						duy=scale*vy;
+						pe->values[i*2+0]+=dux*weight*Jdet*gauss->weight*basis[i]; 
+						pe->values[i*2+1]+=duy*weight*Jdet*gauss->weight*basis[i]; 
+					}
+					break;
+				case SurfaceAverageVelMisfitEnum:
+					/*
+					 *      1                    2              2
+					 * J = ---  sqrt(  (u - u   )  +  (v - v   )  )
+					 *      S                obs            obs
+					 *
+					 *        dJ      1       1 
+					 * DU = - -- = - --- ----------- * 2 (u - u   )
+					 *        du      S  2 sqrt(...)           obs
+					 */
+					for(i=0;i<numnodes;i++){
+						scale=1./(S*2*sqrt(pow(vx-vxobs,2)+pow(vy-vyobs,2))+epsvel);
+						dux=scale*(vxobs-vx);
+						duy=scale*(vyobs-vy);
+						pe->values[i*2+0]+=dux*weight*Jdet*gauss->weight*basis[i]; 
+						pe->values[i*2+1]+=duy*weight*Jdet*gauss->weight*basis[i]; 
+					}
+					break;
+				case SurfaceLogVxVyMisfitEnum:
+					/*
+					 *      1            [        |u| + eps     2          |v| + eps     2  ]
+					 * J = --- \bar{v}^2 | log ( -----------  )   +  log ( -----------  )   |  
+					 *      2            [       |u    |+ eps              |v    |+ eps     ]
+					 *                              obs                       obs
+					 *        dJ                              1      u                             1
+					 * DU = - -- = - \bar{v}^2 log(u...) --------- ----  ~ - \bar{v}^2 log(u...) ------
+					 *        du                         |u| + eps  |u|                           u + eps
+					 */
+					for(i=0;i<numnodes;i++){
+						dux = - meanvel*meanvel * log((fabs(vx)+epsvel)/(fabs(vxobs)+epsvel)) / (vx+epsvel);
+						duy = - meanvel*meanvel * log((fabs(vy)+epsvel)/(fabs(vyobs)+epsvel)) / (vy+epsvel);
+						pe->values[i*2+0]+=dux*weight*Jdet*gauss->weight*basis[i]; 
+						pe->values[i*2+1]+=duy*weight*Jdet*gauss->weight*basis[i]; 
+					}
+					break;
+				case DragCoefficientAbsGradientEnum:
+					/*Nothing in P vector*/
+					break;
+				case ThicknessAbsGradientEnum:
+					/*Nothing in P vector*/
+					break;
+				case ThicknessAlongGradientEnum:
+					/*Nothing in P vector*/
+					break;
+				case ThicknessAcrossGradientEnum:
+					/*Nothing in P vector*/
+					break;
+				case RheologyBbarAbsGradientEnum:
+					/*Nothing in P vector*/
+					break;
+				default:
+					_error_("response " << EnumToStringx(responses[resp]) << " not supported yet");
+			}
+		}
+	}
+
+	/*Transform coordinate system*/
+	element->TransformLoadVectorCoord(pe,XYEnum);
+
+	/*Clean up and return*/
+	xDelete<int>(responses);
+	xDelete<IssmDouble>(xyz_list_top);
+	xDelete<IssmDouble>(basis);
+	delete gauss;
+	return pe;
+
+}/*}}}*/
+ElementVector* AdjointHorizAnalysis::CreatePVectorSSA(Element* element){/*{{{*/
+
+	/*Intermediaries*/
+	int      domaintype;
+	Element* basalelement;
+
+	/*Get basal element*/
+	element->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DhorizontalEnum:
+			basalelement = element;
+			break;
+		case Domain3DEnum:
+			if(!element->IsOnBase()) return NULL;
+			basalelement = element->SpawnBasalElement();
+			break;
+		default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
+	}
+
+	/*Intermediaries */
+	int         num_responses,i;
+	IssmDouble  Jdet,obs_velocity_mag,velocity_mag;
+	IssmDouble  vx,vy,vxobs,vyobs,dux,duy,weight;
+	IssmDouble scalex,scaley,scale,S;
+	int        *responses = NULL;
+	IssmDouble *xyz_list  = NULL;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = basalelement->GetNumberOfNodes();
+
+	/*Initialize Element vector and vectors*/
+	ElementVector* pe    = basalelement->NewElementVector(SSAApproximationEnum);
+	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	basalelement->GetVerticesCoordinates(&xyz_list);
+	basalelement->FindParam(&num_responses,InversionNumCostFunctionsEnum);
+	basalelement->FindParam(&responses,NULL,InversionCostFunctionsEnum);
+	Input* weights_input = basalelement->GetInput(InversionCostFunctionsCoefficientsEnum); _assert_(weights_input);
+	Input* vx_input      = basalelement->GetInput(VxEnum);                                 _assert_(vx_input);
+	Input* vy_input      = basalelement->GetInput(VyEnum);                                 _assert_(vy_input);
+	Input* vxobs_input   = basalelement->GetInput(InversionVxObsEnum);                     _assert_(vxobs_input);
+	Input* vyobs_input   = basalelement->GetInput(InversionVyObsEnum);                     _assert_(vyobs_input);
+	IssmDouble epsvel  = 2.220446049250313e-16;
+	IssmDouble meanvel = 3.170979198376458e-05; /*1000 m/yr*/
+
+	/*Get Surface if required by one response*/
+	for(int resp=0;resp<num_responses;resp++){
+		if(responses[resp]==SurfaceAverageVelMisfitEnum){
+			basalelement->GetInputValue(&S,SurfaceAreaEnum); break;
+		}
+	}
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=basalelement->NewGauss(4);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		basalelement->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		basalelement->NodalFunctions(basis, gauss);
+
+		vx_input->GetInputValue(&vx,gauss);
+		vy_input->GetInputValue(&vy,gauss);
+		vxobs_input->GetInputValue(&vxobs,gauss);
+		vyobs_input->GetInputValue(&vyobs,gauss);
+
+		/*Loop over all requested responses*/
+		for(int resp=0;resp<num_responses;resp++){
+			weights_input->GetInputValue(&weight,gauss,responses[resp]);
+
+			switch(responses[resp]){
+				case SurfaceAbsVelMisfitEnum:
+					/*
+					 *      1  [           2              2 ]
+					 * J = --- | (u - u   )  +  (v - v   )  |
+					 *      2  [       obs            obs   ]
+					 *
+					 *        dJ
+					 * DU = - -- = (u   - u )
+					 *        du     obs
+					 */
+					for(i=0;i<numnodes;i++){
+						dux=vxobs-vx;
+						duy=vyobs-vy;
+						pe->values[i*2+0]+=dux*weight*Jdet*gauss->weight*basis[i]; 
+						pe->values[i*2+1]+=duy*weight*Jdet*gauss->weight*basis[i]; 
+					}
+					break;
+				case SurfaceRelVelMisfitEnum:
+					/*
+					 *      1  [     \bar{v}^2             2   \bar{v}^2              2 ]
+					 * J = --- | -------------  (u - u   ) + -------------  (v - v   )  |
+					 *      2  [  (u   + eps)^2       obs    (v   + eps)^2       obs    ]
+					 *              obs                        obs                      
+					 *
+					 *        dJ     \bar{v}^2
+					 * DU = - -- = ------------- (u   - u )
+					 *        du   (u   + eps)^2    obs
+					 *               obs
+					 */
+					for(i=0;i<numnodes;i++){
+						scalex=pow(meanvel/(vxobs+epsvel),2); if(vxobs==0)scalex=0;
+						scaley=pow(meanvel/(vyobs+epsvel),2); if(vyobs==0)scaley=0;
+						dux=scalex*(vxobs-vx);
+						duy=scaley*(vyobs-vy);
+						pe->values[i*2+0]+=dux*weight*Jdet*gauss->weight*basis[i]; 
+						pe->values[i*2+1]+=duy*weight*Jdet*gauss->weight*basis[i]; 
+					}
+					break;
+				case SurfaceLogVelMisfitEnum:
+					/*
+					 *                 [        vel + eps     ] 2
+					 * J = 4 \bar{v}^2 | log ( -----------  ) |  
+					 *                 [       vel   + eps    ]
+					 *                            obs
+					 *
+					 *        dJ                 2 * log(...)
+					 * DU = - -- = - 4 \bar{v}^2 -------------  u
+					 *        du                 vel^2 + eps
+					 *            
+					 */
+					for(i=0;i<numnodes;i++){
+						velocity_mag    =sqrt(pow(vx,   2)+pow(vy,   2))+epsvel;
+						obs_velocity_mag=sqrt(pow(vxobs,2)+pow(vyobs,2))+epsvel;
+						scale=-8*pow(meanvel,2)/pow(velocity_mag,2)*log(velocity_mag/obs_velocity_mag);
+						dux=scale*vx;
+						duy=scale*vy;
+						pe->values[i*2+0]+=dux*weight*Jdet*gauss->weight*basis[i]; 
+						pe->values[i*2+1]+=duy*weight*Jdet*gauss->weight*basis[i]; 
+					}
+					break;
+				case SurfaceAverageVelMisfitEnum:
+					/*
+					 *      1                    2              2
+					 * J = ---  sqrt(  (u - u   )  +  (v - v   )  )
+					 *      S                obs            obs
+					 *
+					 *        dJ      1       1 
+					 * DU = - -- = - --- ----------- * 2 (u - u   )
+					 *        du      S  2 sqrt(...)           obs
+					 */
+					for(i=0;i<numnodes;i++){
+						scale=1./(S*2*sqrt(pow(vx-vxobs,2)+pow(vy-vyobs,2))+epsvel);
+						dux=scale*(vxobs-vx);
+						duy=scale*(vyobs-vy);
+						pe->values[i*2+0]+=dux*weight*Jdet*gauss->weight*basis[i]; 
+						pe->values[i*2+1]+=duy*weight*Jdet*gauss->weight*basis[i]; 
+					}
+					break;
+				case SurfaceLogVxVyMisfitEnum:
+					/*
+					 *      1            [        |u| + eps     2          |v| + eps     2  ]
+					 * J = --- \bar{v}^2 | log ( -----------  )   +  log ( -----------  )   |  
+					 *      2            [       |u    |+ eps              |v    |+ eps     ]
+					 *                              obs                       obs
+					 *        dJ                              1      u                             1
+					 * DU = - -- = - \bar{v}^2 log(u...) --------- ----  ~ - \bar{v}^2 log(u...) ------
+					 *        du                         |u| + eps  |u|                           u + eps
+					 */
+					for(i=0;i<numnodes;i++){
+						dux = - meanvel*meanvel * log((fabs(vx)+epsvel)/(fabs(vxobs)+epsvel)) / (vx+epsvel);
+						duy = - meanvel*meanvel * log((fabs(vy)+epsvel)/(fabs(vyobs)+epsvel)) / (vy+epsvel);
+						pe->values[i*2+0]+=dux*weight*Jdet*gauss->weight*basis[i]; 
+						pe->values[i*2+1]+=duy*weight*Jdet*gauss->weight*basis[i]; 
+					}
+					break;
+				case DragCoefficientAbsGradientEnum:
+					/*Nothing in P vector*/
+					break;
+				case ThicknessAbsGradientEnum:
+					/*Nothing in P vector*/
+					break;
+				case ThicknessAlongGradientEnum:
+					/*Nothing in P vector*/
+					break;
+				case ThicknessAcrossGradientEnum:
+					/*Nothing in P vector*/
+					break;
+				case RheologyBbarAbsGradientEnum:
+					/*Nothing in P vector*/
+					break;
+				default:
+					_error_("response " << EnumToStringx(responses[resp]) << " not supported yet");
+			}
+		}
+	}
+
+	/*Transform coordinate system*/
+	basalelement->TransformLoadVectorCoord(pe,XYEnum);
+
+	/*Clean up and return*/
+	xDelete<int>(responses);
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(basis);
+	if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;};
+	delete gauss;
+	return pe;
+}/*}}}*/
+void AdjointHorizAnalysis::GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element){/*{{{*/
+	   _error_("not implemented yet");
+}/*}}}*/
+void AdjointHorizAnalysis::InputUpdateFromSolution(IssmDouble* solution,Element* element){/*{{{*/
+	int approximation;
+	element->GetInputValue(&approximation,ApproximationEnum);
+	if(approximation==FSApproximationEnum || approximation==NoneApproximationEnum){
+		InputUpdateFromSolutionFS(solution,element);
+	}
+	else{
+		InputUpdateFromSolutionHoriz(solution,element);
+	}
+}/*}}}*/
+void AdjointHorizAnalysis::InputUpdateFromSolutionHoriz(IssmDouble* solution,Element* element){/*{{{*/
+	int  i;
+	int* doflist=NULL;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+	int numdof   = numnodes*2;
+
+	/*Fetch dof list and allocate solution vectors*/
+	element->GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
+	IssmDouble* values  = xNew<IssmDouble>(numdof);
+	IssmDouble* lambdax = xNew<IssmDouble>(numnodes);
+	IssmDouble* lambday = xNew<IssmDouble>(numnodes);
+
+	/*Use the dof list to index into the solution vector: */
+	for(i=0;i<numdof;i++) values[i]=solution[doflist[i]];
+
+	/*Transform solution in Cartesian Space*/
+	element->TransformSolutionCoord(&values[0],XYEnum);
+
+	/*Ok, we have vx and vy in values, fill in vx and vy arrays: */
+	for(i=0;i<numnodes;i++){
+		lambdax[i]=values[i*NDOF2+0];
+		lambday[i]=values[i*NDOF2+1];
+
+		/*Check solution*/
+		if(xIsNan<IssmDouble>(lambdax[i])) _error_("NaN found in solution vector");
+		if(xIsNan<IssmDouble>(lambday[i])) _error_("NaN found in solution vector");
+	}
+
+	/*Add vx and vy as inputs to the tria element: */
+	element->AddInput(AdjointxEnum,lambdax,element->GetElementType());
+	element->AddInput(AdjointyEnum,lambday,element->GetElementType());
+
+	/*Free ressources:*/
+	xDelete<IssmDouble>(values);
+	xDelete<IssmDouble>(lambdax);
+	xDelete<IssmDouble>(lambday);
+	xDelete<int>(doflist);
+}/*}}}*/
+void AdjointHorizAnalysis::InputUpdateFromSolutionFS(IssmDouble* solution,Element* element){/*{{{*/
+	int          i;
+	int*         vdoflist=NULL;
+	int*         pdoflist=NULL;
+	IssmDouble   FSreconditioning;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int vnumnodes = element->NumberofNodesVelocity();
+	int pnumnodes = element->NumberofNodesPressure();
+	int vnumdof   = vnumnodes*3;
+	int pnumdof   = pnumnodes*1;
+
+	/*Initialize values*/
+	IssmDouble* values  = xNew<IssmDouble>(vnumdof+pnumdof);
+	IssmDouble* lambdax = xNew<IssmDouble>(vnumnodes);
+	IssmDouble* lambday = xNew<IssmDouble>(vnumnodes);
+	IssmDouble* lambdaz = xNew<IssmDouble>(vnumnodes);
+	IssmDouble* lambdap = xNew<IssmDouble>(pnumnodes);
+
+	int* cs_list = xNew<int>(vnumnodes+pnumnodes);
+	for(i=0;i<vnumnodes;i++) cs_list[i] = XYZEnum;
+	for(i=0;i<pnumnodes;i++) cs_list[vnumnodes+i] = PressureEnum;
+
+	/*Get dof list: */
+	element->GetDofListVelocity(&vdoflist,GsetEnum);
+	element->GetDofListPressure(&pdoflist,GsetEnum);
+
+	/*Use the dof list to index into the solution vector: */
+	for(i=0;i<vnumdof;i++) values[i]        =solution[vdoflist[i]];
+	for(i=0;i<pnumdof;i++) values[vnumdof+i]=solution[pdoflist[i]];
+
+	/*Transform solution in Cartesian Space*/
+	element->TransformSolutionCoord(values,cs_list);
+
+	/*fill in all arrays: */
+	for(i=0;i<vnumnodes;i++){
+		lambdax[i] = values[i*NDOF3+0]; if(xIsNan<IssmDouble>(lambdax[i])) _error_("NaN found in solution vector");
+		lambday[i] = values[i*NDOF3+1]; if(xIsNan<IssmDouble>(lambday[i])) _error_("NaN found in solution vector");
+		lambdaz[i] = values[i*NDOF3+2]; if(xIsNan<IssmDouble>(lambdaz[i])) _error_("NaN found in solution vector");
+	}
+	for(i=0;i<pnumnodes;i++){
+		lambdap[i] = values[vnumdof+i]; if(xIsNan<IssmDouble>(lambdap[i])) _error_("NaN found in solution vector");
+	}
+
+	/*Recondition pressure and compute vel: */
+	element->FindParam(&FSreconditioning,StressbalanceFSreconditioningEnum);
+	for(i=0;i<pnumnodes;i++) lambdap[i]=lambdap[i]*FSreconditioning;
+
+	/*Add vx and vy as inputs to the tria element: */
+	element->AddInput(AdjointxEnum,lambdax,element->VelocityInterpolation());
+	element->AddInput(AdjointyEnum,lambday,element->VelocityInterpolation());
+	element->AddInput(AdjointzEnum,lambdaz,element->VelocityInterpolation());
+	element->AddInput(AdjointpEnum,lambdap,element->PressureInterpolation());
+
+	/*Free ressources:*/
+	xDelete<int>(vdoflist);
+	xDelete<int>(pdoflist);
+	xDelete<int>(cs_list);
+	xDelete<IssmDouble>(lambdap);
+	xDelete<IssmDouble>(lambdaz);
+	xDelete<IssmDouble>(lambday);
+	xDelete<IssmDouble>(lambdax);
+	xDelete<IssmDouble>(values);
+}/*}}}*/
+void AdjointHorizAnalysis::UpdateConstraints(FemModel* femmodel){/*{{{*/
+	/*Default, do nothing*/
+	return;
+}/*}}}*/
Index: /issm/trunk/src/c/analyses/AdjointHorizAnalysis.h
===================================================================
--- /issm/trunk/src/c/analyses/AdjointHorizAnalysis.h	(revision 17805)
+++ /issm/trunk/src/c/analyses/AdjointHorizAnalysis.h	(revision 17806)
@@ -12,5 +12,6 @@
 
 	public:
-		int  DofsPerNode(int** doflist,int meshtype,int approximation);
+		/*Model processing*/
+		int  DofsPerNode(int** doflist,int domaintype,int approximation);
 		void UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum);
 		void UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);
@@ -18,4 +19,22 @@
 		void CreateConstraints(Constraints* constraints,IoModel* iomodel);
 		void CreateLoads(Loads* loads, IoModel* iomodel);
+
+		/*Finite element Analysis*/
+		void           Core(FemModel* femmodel);
+		ElementVector* CreateDVector(Element* element);
+		ElementMatrix* CreateJacobianMatrix(Element* element);
+		ElementMatrix* CreateKMatrix(Element* element);
+		ElementMatrix* CreateKMatrixSSA(Element* element);
+		ElementMatrix* CreateKMatrixHO(Element* element);
+		ElementMatrix* CreateKMatrixFS(Element* element);
+		ElementVector* CreatePVector(Element* element);
+		ElementVector* CreatePVectorSSA(Element* element);
+		ElementVector* CreatePVectorHO(Element* element);
+		ElementVector* CreatePVectorFS(Element* element);
+		void GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element);
+		void InputUpdateFromSolution(IssmDouble* solution,Element* element);
+		void UpdateConstraints(FemModel* femmodel);
+		void InputUpdateFromSolutionHoriz(IssmDouble* solution,Element* element);
+		void InputUpdateFromSolutionFS(IssmDouble* solution,Element* element);
 };
 #endif
Index: /issm/trunk/src/c/analyses/Analysis.h
===================================================================
--- /issm/trunk/src/c/analyses/Analysis.h	(revision 17805)
+++ /issm/trunk/src/c/analyses/Analysis.h	(revision 17806)
@@ -6,4 +6,5 @@
 #define _ANALYSIS_H_
 
+#include "../toolkits/objects/toolkitobjects.h"
 class Parameters;
 class IoModel;
@@ -12,11 +13,17 @@
 class Constraints;
 class Loads;
+class Element;
+class ElementVector;
+class ElementMatrix;
+class Gauss;
 
 class Analysis{
 
 	public: 
+		/*Constructor/Destructor*/
+		virtual      ~Analysis(){};
 
-		virtual      ~Analysis(){};
-		virtual int  DofsPerNode(int** doflist,int meshtype,int approximation)=0;
+		/*Model processing*/
+		virtual int  DofsPerNode(int** doflist,int domaintype,int approximation)=0;
 		virtual void UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum)=0;
 		virtual void UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type)=0;
@@ -24,4 +31,14 @@
 		virtual void CreateConstraints(Constraints* constraints,IoModel* iomodel)=0;
 		virtual void CreateLoads(Loads* loads, IoModel* iomodel)=0;
+
+		/*Finite element Analysis*/
+		virtual void           Core(FemModel* femmodel)=0;
+		virtual ElementVector* CreateDVector(Element* element)=0;
+		virtual ElementMatrix* CreateJacobianMatrix(Element* element)=0;
+		virtual ElementMatrix* CreateKMatrix(Element* element)=0;
+		virtual ElementVector* CreatePVector(Element* element)=0;
+		virtual void GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element)=0;
+		virtual void InputUpdateFromSolution(IssmDouble* solution,Element* element)=0;
+		virtual void UpdateConstraints(FemModel* femmodel)=0;
 };
 #endif
Index: /issm/trunk/src/c/analyses/BalancethicknessAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/BalancethicknessAnalysis.cpp	(revision 17805)
+++ /issm/trunk/src/c/analyses/BalancethicknessAnalysis.cpp	(revision 17806)
@@ -6,5 +6,5 @@
 
 /*Model processing*/
-int  BalancethicknessAnalysis::DofsPerNode(int** doflist,int meshtype,int approximation){/*{{{*/
+int  BalancethicknessAnalysis::DofsPerNode(int** doflist,int domaintype,int approximation){/*{{{*/
 	return 1;
 }/*}}}*/
@@ -36,5 +36,5 @@
 	iomodel->FetchDataToInput(elements,ThicknessEnum);
 	iomodel->FetchDataToInput(elements,SurfaceEnum);
-	iomodel->FetchDataToInput(elements,BedEnum);
+	iomodel->FetchDataToInput(elements,BaseEnum);
 	iomodel->FetchDataToInput(elements,MaskIceLevelsetEnum);
 	iomodel->FetchDataToInput(elements,VxEnum);
@@ -44,6 +44,6 @@
 	iomodel->FetchDataToInput(elements,BalancethicknessThickeningRateEnum);
 
-	if(iomodel->meshtype==Mesh3DEnum){
-		iomodel->FetchDataToInput(elements,MeshElementonbedEnum);
+	if(iomodel->domaintype==Domain3DEnum){
+		iomodel->FetchDataToInput(elements,MeshElementonbaseEnum);
 		iomodel->FetchDataToInput(elements,MeshElementonsurfaceEnum);
 	}
@@ -55,8 +55,8 @@
 
 	/*Check in 3d*/
-	if(stabilization==3 && iomodel->meshtype==Mesh3DEnum) _error_("DG 3d not implemented yet");
+	if(stabilization==3 && iomodel->domaintype==Domain3DEnum) _error_("DG 3d not implemented yet");
 
 	/*First fetch data: */
-	if(iomodel->meshtype==Mesh3DEnum) iomodel->FetchData(2,MeshVertexonbedEnum,MeshVertexonsurfaceEnum);
+	if(iomodel->domaintype==Domain3DEnum) iomodel->FetchData(2,MeshVertexonbaseEnum,MeshVertexonsurfaceEnum);
 	if(stabilization!=3){
 		::CreateNodes(nodes,iomodel,BalancethicknessAnalysisEnum,P1Enum);
@@ -65,5 +65,5 @@
 		::CreateNodes(nodes,iomodel,BalancethicknessAnalysisEnum,P1DGEnum);
 	}
-	iomodel->DeleteData(2,MeshVertexonbedEnum,MeshVertexonsurfaceEnum);
+	iomodel->DeleteData(2,MeshVertexonbaseEnum,MeshVertexonsurfaceEnum);
 }/*}}}*/
 void BalancethicknessAnalysis::CreateConstraints(Constraints* constraints,IoModel* iomodel){/*{{{*/
@@ -112,2 +112,386 @@
 	}
 }/*}}}*/
+
+/*Finite Element Analysis*/
+void           BalancethicknessAnalysis::Core(FemModel* femmodel){/*{{{*/
+	_error_("not implemented");
+}/*}}}*/
+ElementVector* BalancethicknessAnalysis::CreateDVector(Element* element){/*{{{*/
+	/*Default, return NULL*/
+	return NULL;
+}/*}}}*/
+ElementMatrix* BalancethicknessAnalysis::CreateJacobianMatrix(Element* element){/*{{{*/
+_error_("Not implemented");
+}/*}}}*/
+ElementMatrix* BalancethicknessAnalysis::CreateKMatrix(Element* element){/*{{{*/
+
+	if(!element->IsOnBase()) return NULL;
+	Element* basalelement = element->SpawnBasalElement();
+
+	ElementMatrix* Ke = NULL;
+	switch(element->FiniteElement()){
+		case P1Enum: case P2Enum:
+			Ke = CreateKMatrixCG(basalelement);
+			break;
+		case P1DGEnum:
+			Ke = CreateKMatrixDG(basalelement);
+			break;
+		default:
+			_error_("Element type " << EnumToStringx(element->FiniteElement()) << " not supported yet");
+	}
+
+	int domaintype;
+	element->FindParam(&domaintype,DomainTypeEnum);
+	if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;};
+	return Ke;
+}/*}}}*/
+ElementMatrix* BalancethicknessAnalysis::CreateKMatrixCG(Element* element){/*{{{*/
+
+	/*Intermediaries */
+	int        stabilization;
+	int        domaintype;
+	IssmDouble Jdet,D_scalar,h;
+	IssmDouble vel,vx,vy,dvxdx,dvydy;
+	IssmDouble dvx[2],dvy[2];
+	IssmDouble* xyz_list = NULL;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Initialize Element vector and other vectors*/
+	ElementMatrix* Ke     = element->NewElementMatrix();
+	IssmDouble*    B      = xNew<IssmDouble>(2*numnodes);
+	IssmDouble*    Bprime = xNew<IssmDouble>(2*numnodes);
+	IssmDouble     D[2][2];
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+	element->FindParam(&domaintype,DomainTypeEnum);
+	element->FindParam(&stabilization,BalancethicknessStabilizationEnum);
+	Input* vxaverage_input=NULL;
+	Input* vyaverage_input=NULL;
+	if(domaintype==Domain2DhorizontalEnum){
+		vxaverage_input=element->GetInput(VxEnum); _assert_(vxaverage_input);
+		vyaverage_input=element->GetInput(VyEnum); _assert_(vyaverage_input);
+	}
+	else{
+		vxaverage_input=element->GetInput(VxAverageEnum); _assert_(vxaverage_input);
+		vyaverage_input=element->GetInput(VyAverageEnum); _assert_(vyaverage_input);
+	}
+	h = element->CharacteristicLength();
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		GetB(B,element,xyz_list,gauss);
+		GetBprime(Bprime,element,xyz_list,gauss);
+
+		vxaverage_input->GetInputValue(&vx,gauss);
+		vyaverage_input->GetInputValue(&vy,gauss);
+		vxaverage_input->GetInputDerivativeValue(&dvx[0],xyz_list,gauss);
+		vyaverage_input->GetInputDerivativeValue(&dvy[0],xyz_list,gauss);
+		dvxdx=dvx[0];
+		dvydy=dvy[1];
+		D_scalar=gauss->weight*Jdet;
+
+		D[0][0]=D_scalar*dvxdx;
+		D[0][1]=0.;
+		D[1][0]=0.;
+		D[1][1]=D_scalar*dvydy;
+		TripleMultiply(B,2,numnodes,1,
+					&D[0][0],2,2,0,
+					B,2,numnodes,0,
+					&Ke->values[0],1);
+
+		D[0][0]=D_scalar*vx;
+		D[1][1]=D_scalar*vy;
+		TripleMultiply(B,2,numnodes,1,
+					&D[0][0],2,2,0,
+					Bprime,2,numnodes,0,
+					&Ke->values[0],1);
+
+		if(stabilization==1){
+			/*Streamline upwinding*/
+			vel=sqrt(vx*vx+vy*vy);
+			D[0][0]=h/(2*vel)*vx*vx;
+			D[1][0]=h/(2*vel)*vy*vx;
+			D[0][1]=h/(2*vel)*vx*vy;
+			D[1][1]=h/(2*vel)*vy*vy;
+		}
+		else if(stabilization==2){
+			/*SSA*/
+			vxaverage_input->GetInputAverage(&vx);
+			vyaverage_input->GetInputAverage(&vy);
+			D[0][0]=h/2.0*fabs(vx);
+			D[0][1]=0.;
+			D[1][0]=0.;
+			D[1][1]=h/2.0*fabs(vy);
+		}
+		if(stabilization==1 || stabilization==2){
+			D[0][0]=D_scalar*D[0][0];
+			D[1][0]=D_scalar*D[1][0];
+			D[0][1]=D_scalar*D[0][1];
+			D[1][1]=D_scalar*D[1][1];
+			TripleMultiply(Bprime,2,numnodes,1,
+						&D[0][0],2,2,0,
+						Bprime,2,numnodes,0,
+						&Ke->values[0],1);
+		}
+	}
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(B);
+	xDelete<IssmDouble>(Bprime);
+	delete gauss;
+	return Ke;
+}/*}}}*/
+ElementMatrix* BalancethicknessAnalysis::CreateKMatrixDG(Element* element){/*{{{*/
+
+	/*Intermediaries */
+	int        domaintype;
+	IssmDouble Jdet,D_scalar,vx,vy,dvxdx,dvydy,vel;
+	IssmDouble dvx[2],dvy[2];
+	IssmDouble* xyz_list = NULL;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Initialize Element vector and other vectors*/
+	ElementMatrix* Ke     = element->NewElementMatrix();
+	IssmDouble*    B      = xNew<IssmDouble>(2*numnodes);
+	IssmDouble*    Bprime = xNew<IssmDouble>(2*numnodes);
+	IssmDouble     D[2][2];
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+	element->FindParam(&domaintype,DomainTypeEnum);
+	Input* vxaverage_input=NULL;
+	Input* vyaverage_input=NULL;
+	if(domaintype==Domain2DhorizontalEnum){
+		vxaverage_input=element->GetInput(VxEnum); _assert_(vxaverage_input);
+		vyaverage_input=element->GetInput(VyEnum); _assert_(vyaverage_input);
+	}
+	else{
+		vxaverage_input=element->GetInput(VxAverageEnum); _assert_(vxaverage_input);
+		vyaverage_input=element->GetInput(VyAverageEnum); _assert_(vyaverage_input);
+	}
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		vxaverage_input->GetInputValue(&vx,gauss);
+		vyaverage_input->GetInputValue(&vy,gauss);
+		vxaverage_input->GetInputDerivativeValue(&dvx[0],xyz_list,gauss);
+		vyaverage_input->GetInputDerivativeValue(&dvy[0],xyz_list,gauss);
+		D_scalar=gauss->weight*Jdet;
+
+		/*WARNING: B and Bprime are inverted compared to CG*/
+		GetB(Bprime,element,xyz_list,gauss);
+		GetBprime(B,element,xyz_list,gauss);
+
+		D_scalar = - gauss->weight*Jdet;
+		D[0][0]  = D_scalar*vx;
+		D[0][1]  = 0.;
+		D[1][0]  = 0.;
+		D[1][1]  = D_scalar*vy;
+		TripleMultiply(B,2,numnodes,1,
+					&D[0][0],2,2,0,
+					Bprime,2,numnodes,0,
+					&Ke->values[0],1);
+
+	}
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(B);
+	xDelete<IssmDouble>(Bprime);
+	delete gauss;
+	return Ke;
+}/*}}}*/
+ElementVector* BalancethicknessAnalysis::CreatePVector(Element* element){/*{{{*/
+
+	if(!element->IsOnBase()) return NULL;
+	Element* basalelement = element->SpawnBasalElement();
+
+	ElementVector* pe = NULL;
+	switch(element->FiniteElement()){
+		case P1Enum: case P2Enum:
+			pe = CreatePVectorCG(basalelement);
+			break;
+		case P1DGEnum:
+			pe = CreatePVectorDG(basalelement);
+			break;
+		default:
+			_error_("Element type " << EnumToStringx(element->FiniteElement()) << " not supported yet");
+	}
+
+	int domaintype;
+	element->FindParam(&domaintype,DomainTypeEnum);
+	if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;};
+	return pe;
+}/*}}}*/
+ElementVector* BalancethicknessAnalysis::CreatePVectorCG(Element* element){/*{{{*/
+
+	/*Intermediaries */
+	IssmDouble  dhdt,mb,ms,Jdet;
+	IssmDouble* xyz_list = NULL;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Initialize Element vector and other vectors*/
+	ElementVector* pe    = element->NewElementVector();
+	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+	Input* mb_input   = element->GetInput(BasalforcingsMeltingRateEnum);       _assert_(mb_input);
+	Input* ms_input   = element->GetInput(SurfaceforcingsMassBalanceEnum);     _assert_(ms_input);
+	Input* dhdt_input = element->GetInput(BalancethicknessThickeningRateEnum); _assert_(dhdt_input);
+
+	/*Initialize mb_correction to 0, do not forget!:*/
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		element->NodalFunctions(basis,gauss);
+
+		ms_input->GetInputValue(&ms,gauss);
+		mb_input->GetInputValue(&mb,gauss);
+		dhdt_input->GetInputValue(&dhdt,gauss);
+
+		for(int i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*(ms-mb-dhdt)*basis[i];
+	}
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(basis);
+	delete gauss;
+	return pe;
+}/*}}}*/
+ElementVector* BalancethicknessAnalysis::CreatePVectorDG(Element* element){/*{{{*/
+
+	/*Intermediaries */
+	IssmDouble  dhdt,mb,ms,Jdet;
+	IssmDouble* xyz_list = NULL;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Initialize Element vector and other vectors*/
+	ElementVector* pe    = element->NewElementVector();
+	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+	Input* mb_input   = element->GetInput(BasalforcingsMeltingRateEnum);       _assert_(mb_input);
+	Input* ms_input   = element->GetInput(SurfaceforcingsMassBalanceEnum);     _assert_(ms_input);
+	Input* dhdt_input = element->GetInput(BalancethicknessThickeningRateEnum); _assert_(dhdt_input);
+
+	/*Initialize mb_correction to 0, do not forget!:*/
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		element->NodalFunctions(basis,gauss);
+
+		ms_input->GetInputValue(&ms,gauss);
+		mb_input->GetInputValue(&mb,gauss);
+		dhdt_input->GetInputValue(&dhdt,gauss);
+
+		for(int i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*(ms-mb-dhdt)*basis[i];
+	}
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(basis);
+	delete gauss;
+	return pe;
+}/*}}}*/
+void BalancethicknessAnalysis::GetB(IssmDouble* B,Element* element,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
+	/*Compute B  matrix. B=[B1 B2 B3] where Bi is of size 3*NDOF2. 
+	 * For node i, Bi can be expressed in the actual coordinate system
+	 * by: 
+	 *       Bi=[ N ]
+	 *          [ N ]
+	 * where N is the finiteelement function for node i.
+	 *
+	 * We assume B_prog has been allocated already, of size: 2x(NDOF1*numnodes)
+	 */
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Get nodal functions*/
+	IssmDouble* basis=xNew<IssmDouble>(numnodes);
+	element->NodalFunctions(basis,gauss);
+
+	/*Build B: */
+	for(int i=0;i<numnodes;i++){
+		B[numnodes*0+i] = basis[i];
+		B[numnodes*1+i] = basis[i];
+	}
+
+	/*Clean-up*/
+	xDelete<IssmDouble>(basis);
+}/*}}}*/
+void BalancethicknessAnalysis::GetBprime(IssmDouble* Bprime,Element* element,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
+	/*Compute B'  matrix. B'=[B1' B2' B3'] where Bi' is of size 3*NDOF2. 
+	 * For node i, Bi' can be expressed in the actual coordinate system
+	 * by: 
+	 *       Bi_prime=[ dN/dx ]
+	 *                [ dN/dy ]
+	 * where N is the finiteelement function for node i.
+	 *
+	 * We assume B' has been allocated already, of size: 3x(NDOF2*numnodes)
+	 */
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Get nodal functions derivatives*/
+	IssmDouble* dbasis=xNew<IssmDouble>(2*numnodes);
+	element->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+
+	/*Build B': */
+	for(int i=0;i<numnodes;i++){
+		Bprime[numnodes*0+i] = dbasis[0*numnodes+i];
+		Bprime[numnodes*1+i] = dbasis[1*numnodes+i];
+	}
+
+	/*Clean-up*/
+	xDelete<IssmDouble>(dbasis);
+
+}/*}}}*/
+void BalancethicknessAnalysis::GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element){/*{{{*/
+	   _error_("not implemented yet");
+}/*}}}*/
+void BalancethicknessAnalysis::InputUpdateFromSolution(IssmDouble* solution,Element* element){/*{{{*/
+
+	int domaintype;
+	element->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DhorizontalEnum:
+			element->InputUpdateFromSolutionOneDof(solution,ThicknessEnum);
+			break;
+		case Domain3DEnum:
+			element->InputUpdateFromSolutionOneDofCollapsed(solution,ThicknessEnum);
+			break;
+		default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
+	}
+}/*}}}*/
+void BalancethicknessAnalysis::UpdateConstraints(FemModel* femmodel){/*{{{*/
+	/*Default, do nothing*/
+	return;
+}/*}}}*/
Index: /issm/trunk/src/c/analyses/BalancethicknessAnalysis.h
===================================================================
--- /issm/trunk/src/c/analyses/BalancethicknessAnalysis.h	(revision 17805)
+++ /issm/trunk/src/c/analyses/BalancethicknessAnalysis.h	(revision 17806)
@@ -12,5 +12,6 @@
 
 	public:
-		int  DofsPerNode(int** doflist,int meshtype,int approximation);
+		/*Model processing*/
+		int  DofsPerNode(int** doflist,int domaintype,int approximation);
 		void UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum);
 		void UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);
@@ -18,4 +19,20 @@
 		void CreateConstraints(Constraints* constraints,IoModel* iomodel);
 		void CreateLoads(Loads* loads, IoModel* iomodel);
+
+		/*Finite element Analysis*/
+		void           Core(FemModel* femmodel);
+		ElementVector* CreateDVector(Element* element);
+		ElementMatrix* CreateJacobianMatrix(Element* element);
+		ElementMatrix* CreateKMatrix(Element* element);
+		ElementMatrix* CreateKMatrixCG(Element* element);
+		ElementMatrix* CreateKMatrixDG(Element* element);
+		ElementVector* CreatePVector(Element* element);
+		ElementVector* CreatePVectorCG(Element* element);
+		ElementVector* CreatePVectorDG(Element* element);
+		void GetB(IssmDouble* B,Element* element,IssmDouble* xyz_list,Gauss* gauss);
+		void GetBprime(IssmDouble* B,Element* element,IssmDouble* xyz_list,Gauss* gauss);
+		void GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element);
+		void InputUpdateFromSolution(IssmDouble* solution,Element* element);
+		void UpdateConstraints(FemModel* femmodel);
 };
 #endif
Index: /issm/trunk/src/c/analyses/BalancethicknessSoftAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/BalancethicknessSoftAnalysis.cpp	(revision 17805)
+++ /issm/trunk/src/c/analyses/BalancethicknessSoftAnalysis.cpp	(revision 17806)
@@ -6,5 +6,5 @@
 
 /*Model processing*/
-int  BalancethicknessSoftAnalysis::DofsPerNode(int** doflist,int meshtype,int approximation){/*{{{*/
+int  BalancethicknessSoftAnalysis::DofsPerNode(int** doflist,int domaintype,int approximation){/*{{{*/
 	_error_("not implemented");
 }/*}}}*/
@@ -24,2 +24,30 @@
 	   _error_("not implemented yet");
 }/*}}}*/
+
+/*Finite Element Analysis*/
+void           BalancethicknessSoftAnalysis::Core(FemModel* femmodel){/*{{{*/
+	_error_("not implemented");
+}/*}}}*/
+ElementVector* BalancethicknessSoftAnalysis::CreateDVector(Element* element){/*{{{*/
+	/*Default, return NULL*/
+	return NULL;
+}/*}}}*/
+ElementMatrix* BalancethicknessSoftAnalysis::CreateJacobianMatrix(Element* element){/*{{{*/
+_error_("Not implemented");
+}/*}}}*/
+ElementMatrix* BalancethicknessSoftAnalysis::CreateKMatrix(Element* element){/*{{{*/
+	_error_("not implemented yet");
+}/*}}}*/
+ElementVector* BalancethicknessSoftAnalysis::CreatePVector(Element* element){/*{{{*/
+_error_("not implemented yet");
+}/*}}}*/
+void BalancethicknessSoftAnalysis::GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element){/*{{{*/
+	   _error_("not implemented yet");
+}/*}}}*/
+void BalancethicknessSoftAnalysis::InputUpdateFromSolution(IssmDouble* solution,Element* element){/*{{{*/
+	_error_("not implemented yet");
+}/*}}}*/
+void BalancethicknessSoftAnalysis::UpdateConstraints(FemModel* femmodel){/*{{{*/
+	/*Default, do nothing*/
+	return;
+}/*}}}*/
Index: /issm/trunk/src/c/analyses/BalancethicknessSoftAnalysis.h
===================================================================
--- /issm/trunk/src/c/analyses/BalancethicknessSoftAnalysis.h	(revision 17805)
+++ /issm/trunk/src/c/analyses/BalancethicknessSoftAnalysis.h	(revision 17806)
@@ -12,5 +12,6 @@
 
 	public:
-		int  DofsPerNode(int** doflist,int meshtype,int approximation);
+		/*Model processing*/
+		int  DofsPerNode(int** doflist,int domaintype,int approximation);
 		void UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum);
 		void UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);
@@ -18,4 +19,14 @@
 		void CreateConstraints(Constraints* constraints,IoModel* iomodel);
 		void CreateLoads(Loads* loads, IoModel* iomodel);
+
+		/*Finite element Analysis*/
+		void           Core(FemModel* femmodel);
+		ElementVector* CreateDVector(Element* element);
+		ElementMatrix* CreateJacobianMatrix(Element* element);
+		ElementMatrix* CreateKMatrix(Element* element);
+		ElementVector* CreatePVector(Element* element);
+		void GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element);
+		void InputUpdateFromSolution(IssmDouble* solution,Element* element);
+		void UpdateConstraints(FemModel* femmodel);
 };
 #endif
Index: /issm/trunk/src/c/analyses/BalancevelocityAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/BalancevelocityAnalysis.cpp	(revision 17805)
+++ /issm/trunk/src/c/analyses/BalancevelocityAnalysis.cpp	(revision 17806)
@@ -6,5 +6,5 @@
 
 /*Model processing*/
-int  BalancevelocityAnalysis::DofsPerNode(int** doflist,int meshtype,int approximation){/*{{{*/
+int  BalancevelocityAnalysis::DofsPerNode(int** doflist,int domaintype,int approximation){/*{{{*/
 	return 1;
 }/*}}}*/
@@ -25,5 +25,5 @@
 	iomodel->FetchDataToInput(elements,ThicknessEnum);
 	iomodel->FetchDataToInput(elements,SurfaceEnum);
-	iomodel->FetchDataToInput(elements,BedEnum);
+	iomodel->FetchDataToInput(elements,BaseEnum);
 	iomodel->FetchDataToInput(elements,MaskIceLevelsetEnum);
 	iomodel->FetchDataToInput(elements,VxEnum);
@@ -33,6 +33,6 @@
 	iomodel->FetchDataToInput(elements,BalancethicknessThickeningRateEnum);
 
-	if(iomodel->meshtype==Mesh3DEnum){
-		iomodel->FetchDataToInput(elements,MeshElementonbedEnum);
+	if(iomodel->domaintype==Domain3DEnum){
+		iomodel->FetchDataToInput(elements,MeshElementonbaseEnum);
 		iomodel->FetchDataToInput(elements,MeshElementonsurfaceEnum);
 	}
@@ -41,10 +41,8 @@
 
 	/*Check in 3d*/
-	if(iomodel->meshtype==Mesh3DEnum) _error_("DG 3d not implemented yet");
+	if(iomodel->domaintype==Domain3DEnum) _error_("DG 3d not implemented yet");
 
 	/*First fetch data: */
-	iomodel->FetchData(3,MeshVertexonbedEnum,MeshVertexonsurfaceEnum,FlowequationVertexEquationEnum);
 	::CreateNodes(nodes,iomodel,BalancevelocityAnalysisEnum,P1Enum);
-	iomodel->DeleteData(3,MeshVertexonbedEnum,MeshVertexonsurfaceEnum,FlowequationVertexEquationEnum);
 }/*}}}*/
 void BalancevelocityAnalysis::CreateConstraints(Constraints* constraints,IoModel* iomodel){/*{{{*/
@@ -57,2 +55,206 @@
 	/*No loads*/
 }/*}}}*/
+
+/*Finite Element Analysis*/
+void           BalancevelocityAnalysis::Core(FemModel* femmodel){/*{{{*/
+	_error_("not implemented");
+}/*}}}*/
+ElementVector* BalancevelocityAnalysis::CreateDVector(Element* element){/*{{{*/
+	/*Default, return NULL*/
+	return NULL;
+}/*}}}*/
+ElementMatrix* BalancevelocityAnalysis::CreateJacobianMatrix(Element* element){/*{{{*/
+_error_("Not implemented");
+}/*}}}*/
+ElementMatrix* BalancevelocityAnalysis::CreateKMatrix(Element* element){/*{{{*/
+
+	/*Intermediaries */
+	IssmDouble  dhdt,mb,ms,Jdet;
+	IssmDouble  h,gamma,thickness;
+	IssmDouble  hnx,hny,dhnx[2],dhny[2];
+	IssmDouble *xyz_list = NULL;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Initialize Element matrix and vectors*/
+	ElementMatrix* Ke     = element->NewElementMatrix();
+	IssmDouble*    B      = xNew<IssmDouble>(2*numnodes);
+	IssmDouble*    basis  = xNew<IssmDouble>(numnodes);
+	IssmDouble*    dbasis = xNew<IssmDouble>(2*numnodes);
+	IssmDouble*    HNx    = xNew<IssmDouble>(numnodes);
+	IssmDouble*    HNy    = xNew<IssmDouble>(numnodes);
+	IssmDouble*    H      = xNew<IssmDouble>(numnodes);
+	IssmDouble*    Nx     = xNew<IssmDouble>(numnodes);
+	IssmDouble*    Ny     = xNew<IssmDouble>(numnodes);
+
+	/*Retrieve all Inputs and parameters: */
+	element->GetVerticesCoordinates(&xyz_list);
+	Input* H_input = element->GetInput(ThicknessEnum); _assert_(H_input);
+	h = element->CharacteristicLength();
+
+	/*Get vector N for all nodes and build HNx and HNy*/
+	element->GetInputListOnNodes(Nx,SurfaceSlopeXEnum);
+	element->GetInputListOnNodes(Ny,SurfaceSlopeYEnum);
+	element->GetInputListOnNodes(H,ThicknessEnum);
+	for(int i=0;i<numnodes;i++){
+		IssmDouble norm=sqrt(Nx[i]*Nx[i]+Ny[i]*Ny[i]+1.e-10);
+		HNx[i] = -H[i]*Nx[i]/norm;
+		HNy[i] = -H[i]*Ny[i]/norm;
+	}
+
+	/*Start looping on the number of gaussian points:*/
+	Gauss* gauss=element->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		H_input->GetInputValue(&thickness,gauss);
+		if(thickness<50.) thickness=50.;
+		element->ValueP1DerivativesOnGauss(&dhnx[0],HNx,xyz_list,gauss);
+		element->ValueP1DerivativesOnGauss(&dhny[0],HNy,xyz_list,gauss);
+		element->ValueP1OnGauss(&hnx,HNx,gauss);
+		element->ValueP1OnGauss(&hny,HNy,gauss);
+
+		gamma=h/(2.*thickness+1.e-10);
+
+		element->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		element->NodalFunctions(basis,gauss);
+		element->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+
+		for(int i=0;i<numnodes;i++){
+			for(int j=0;j<numnodes;j++){
+				Ke->values[i*numnodes+j] += gauss->weight*Jdet*(
+							(basis[i]+gamma*(basis[i]*(dhnx[0]+dhny[1]) + dbasis[0*numnodes+i]*hnx + dbasis[1*numnodes+i]*hny))*
+							(basis[j]*(dhnx[0]+dhny[1])  + dbasis[0*numnodes+j]*hnx + dbasis[1*numnodes+j]*hny)
+							);
+			}
+		}
+	}
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(basis);
+	xDelete<IssmDouble>(dbasis);
+	xDelete<IssmDouble>(H);
+	xDelete<IssmDouble>(Nx);
+	xDelete<IssmDouble>(Ny);
+	xDelete<IssmDouble>(HNx);
+	xDelete<IssmDouble>(HNy);
+	xDelete<IssmDouble>(B);
+	delete gauss;
+	return Ke;
+}/*}}}*/
+ElementVector* BalancevelocityAnalysis::CreatePVector(Element* element){/*{{{*/
+
+	/*Intermediaries*/
+	int      domaintype;
+	Element* basalelement;
+
+	/*Get basal element*/
+	element->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DhorizontalEnum:
+			basalelement = element;
+			break;
+		case Domain3DEnum:
+			if(!element->IsOnBase()) return NULL;
+			basalelement = element->SpawnBasalElement();
+			break;
+		default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
+	}
+
+	/*Intermediaries */
+	IssmDouble dhdt,mb,ms,Jdet;
+	IssmDouble gamma,thickness;
+	IssmDouble hnx,hny,dhnx[2],dhny[2];
+	IssmDouble *xyz_list  = NULL;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = basalelement->GetNumberOfNodes();
+
+	/*Initialize Element vector*/
+	ElementVector* pe    = basalelement->NewElementVector();
+	IssmDouble*    basis  = xNew<IssmDouble>(numnodes);
+	IssmDouble*    dbasis = xNew<IssmDouble>(numnodes*2);
+	IssmDouble*    H      = xNew<IssmDouble>(numnodes);
+	IssmDouble*    Nx     = xNew<IssmDouble>(numnodes);
+	IssmDouble*    Ny     = xNew<IssmDouble>(numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	basalelement->GetVerticesCoordinates(&xyz_list);
+	Input* ms_input   = basalelement->GetInput(SurfaceforcingsMassBalanceEnum);     _assert_(ms_input);
+	Input* mb_input   = basalelement->GetInput(BasalforcingsMeltingRateEnum);       _assert_(mb_input);
+	Input* dhdt_input = basalelement->GetInput(BalancethicknessThickeningRateEnum); _assert_(dhdt_input);
+	Input* H_input    = basalelement->GetInput(ThicknessEnum);                      _assert_(H_input);
+	IssmDouble h = basalelement->CharacteristicLength();
+
+	/*Get vector N for all nodes*/
+	basalelement->GetInputListOnNodes(Nx,SurfaceSlopeXEnum);
+	basalelement->GetInputListOnNodes(Ny,SurfaceSlopeYEnum);
+	basalelement->GetInputListOnNodes(H,ThicknessEnum);
+	for(int i=0;i<numnodes;i++){
+		IssmDouble norm=sqrt(Nx[i]*Nx[i]+Ny[i]*Ny[i]+1.e-10);
+		Nx[i] = -H[i]*Nx[i]/norm;
+		Ny[i] = -H[i]*Ny[i]/norm;
+	}
+
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=basalelement->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		basalelement->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		basalelement->NodalFunctions(basis,gauss);
+		basalelement->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+
+		element->ValueP1DerivativesOnGauss(&dhnx[0],Nx,xyz_list,gauss);
+		element->ValueP1DerivativesOnGauss(&dhny[0],Ny,xyz_list,gauss);
+		element->ValueP1OnGauss(&hnx,Nx,gauss);
+		element->ValueP1OnGauss(&hny,Ny,gauss);
+
+		ms_input->GetInputValue(&ms,gauss);
+		mb_input->GetInputValue(&mb,gauss);
+		dhdt_input->GetInputValue(&dhdt,gauss);
+		H_input->GetInputValue(&thickness,gauss);
+		if(thickness<50.) thickness=50.;
+
+		gamma=h/(2.*thickness+1.e-10);
+
+		for(int i=0;i<numnodes;i++){
+			pe->values[i]+=Jdet*gauss->weight*(ms-mb-dhdt)*( basis[i] + gamma*(basis[i]*(dhnx[0]+dhny[1])+hnx*dbasis[0*numnodes+i] + hny*dbasis[1*numnodes+i]));
+		}
+	}
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(basis);
+	xDelete<IssmDouble>(dbasis);
+	xDelete<IssmDouble>(H);
+	xDelete<IssmDouble>(Nx);
+	xDelete<IssmDouble>(Ny);
+	delete gauss;
+	if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;};
+	return pe;
+}/*}}}*/
+void BalancevelocityAnalysis::GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element){/*{{{*/
+	   _error_("not implemented yet");
+}/*}}}*/
+void BalancevelocityAnalysis::InputUpdateFromSolution(IssmDouble* solution,Element* element){/*{{{*/
+
+	int domaintype;
+	element->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DhorizontalEnum:
+			element->InputUpdateFromSolutionOneDof(solution,VelEnum);
+			break;
+		case Domain3DEnum:
+			element->InputUpdateFromSolutionOneDofCollapsed(solution,VelEnum);
+			break;
+		default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
+	}
+}/*}}}*/
+void BalancevelocityAnalysis::UpdateConstraints(FemModel* femmodel){/*{{{*/
+	/*Default, do nothing*/
+	return;
+}/*}}}*/
Index: /issm/trunk/src/c/analyses/BalancevelocityAnalysis.h
===================================================================
--- /issm/trunk/src/c/analyses/BalancevelocityAnalysis.h	(revision 17805)
+++ /issm/trunk/src/c/analyses/BalancevelocityAnalysis.h	(revision 17806)
@@ -12,5 +12,6 @@
 
 	public:
-		int  DofsPerNode(int** doflist,int meshtype,int approximation);
+		/*Model processing*/
+		int  DofsPerNode(int** doflist,int domaintype,int approximation);
 		void UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum);
 		void UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);
@@ -18,4 +19,14 @@
 		void CreateConstraints(Constraints* constraints,IoModel* iomodel);
 		void CreateLoads(Loads* loads, IoModel* iomodel);
+
+		/*Finite element Analysis*/
+		void           Core(FemModel* femmodel);
+		ElementVector* CreateDVector(Element* element);
+		ElementMatrix* CreateJacobianMatrix(Element* element);
+		ElementMatrix* CreateKMatrix(Element* element);
+		ElementVector* CreatePVector(Element* element);
+		void GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element);
+		void InputUpdateFromSolution(IssmDouble* solution,Element* element);
+		void UpdateConstraints(FemModel* femmodel);
 };
 #endif
Index: /issm/trunk/src/c/analyses/DamageEvolutionAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/DamageEvolutionAnalysis.cpp	(revision 17805)
+++ /issm/trunk/src/c/analyses/DamageEvolutionAnalysis.cpp	(revision 17806)
@@ -6,13 +6,16 @@
 
 /*Model processing*/
-int  DamageEvolutionAnalysis::DofsPerNode(int** doflist,int meshtype,int approximation){/*{{{*/
+int  DamageEvolutionAnalysis::DofsPerNode(int** doflist,int domaintype,int approximation){/*{{{*/
 	return 1;
 }/*}}}*/
 void DamageEvolutionAnalysis::UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum){/*{{{*/
+
+	/*Intermediaries*/
+	int         numoutputs;
+	char**      requestedoutputs = NULL;
 
 	/*retrieve some parameters: */
 	parameters->AddObject(iomodel->CopyConstantObject(DamageLawEnum));
 	parameters->AddObject(iomodel->CopyConstantObject(DamageStabilizationEnum));
-
 	parameters->AddObject(iomodel->CopyConstantObject(DamagePenaltyThresholdEnum));
 	parameters->AddObject(iomodel->CopyConstantObject(DamagePenaltyLockEnum));
@@ -20,4 +23,10 @@
 	parameters->AddObject(iomodel->CopyConstantObject(DamageMaxiterEnum));
 	parameters->AddObject(iomodel->CopyConstantObject(DamageMaxDamageEnum));
+
+	/*Requested outputs*/
+	iomodel->FetchData(&requestedoutputs,&numoutputs,DamageEvolutionRequestedOutputsEnum);
+	parameters->AddObject(new IntParam(DamageEvolutionNumRequestedOutputsEnum,numoutputs));
+	if(numoutputs)parameters->AddObject(new StringArrayParam(DamageEvolutionRequestedOutputsEnum,requestedoutputs,numoutputs));
+	iomodel->DeleteData(&requestedoutputs,numoutputs,DamageEvolutionRequestedOutputsEnum);
 
 	/*Retrieve law dependent parameters: */
@@ -31,4 +40,5 @@
 		parameters->AddObject(iomodel->CopyConstantObject(DamageStressThresholdEnum));
 		parameters->AddObject(iomodel->CopyConstantObject(DamageHealingEnum));
+		parameters->AddObject(iomodel->CopyConstantObject(DamageEquivStressEnum));
 	}
 	xDelete<char>(law);
@@ -36,4 +46,6 @@
 }/*}}}*/
 void DamageEvolutionAnalysis::UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type){/*{{{*/
+
+	int finiteelement = P1Enum;
 
 	/*Update elements: */
@@ -42,5 +54,5 @@
 		if(iomodel->my_elements[i]){
 			Element* element=(Element*)elements->GetObjectByOffset(counter);
-			element->Update(i,iomodel,analysis_counter,analysis_type,P1Enum);
+			element->Update(i,iomodel,analysis_counter,analysis_type,finiteelement);
 			counter++;
 		}
@@ -50,5 +62,5 @@
 	iomodel->FetchDataToInput(elements,VxEnum);
 	iomodel->FetchDataToInput(elements,VyEnum);
-	iomodel->FetchDataToInput(elements,VzEnum);
+	if(iomodel->domaintype==Domain3DEnum) iomodel->FetchDataToInput(elements,VzEnum);
 	iomodel->FetchDataToInput(elements,DamageDEnum);
 	iomodel->FetchDataToInput(elements,MaskIceLevelsetEnum);
@@ -63,32 +75,442 @@
 void DamageEvolutionAnalysis::CreateNodes(Nodes* nodes,IoModel* iomodel){/*{{{*/
 
-	iomodel->FetchData(1,MeshVertexonbedEnum);
-	::CreateNodes(nodes,iomodel,DamageEvolutionAnalysisEnum,P1Enum);
-	iomodel->DeleteData(1,MeshVertexonbedEnum);
+	int finiteelement = P1Enum;
+
+	if(iomodel->domaintype!=Domain2DhorizontalEnum) iomodel->FetchData(1,MeshVertexonbaseEnum);
+	::CreateNodes(nodes,iomodel,DamageEvolutionAnalysisEnum,finiteelement);
+	iomodel->DeleteData(1,MeshVertexonbaseEnum);
 }/*}}}*/
 void DamageEvolutionAnalysis::CreateConstraints(Constraints* constraints,IoModel* iomodel){/*{{{*/
 
 	int stabilization;
+	int finiteelement = P1Enum;
 	iomodel->Constant(&stabilization,DamageStabilizationEnum);
 
-	IoModelToConstraintsx(constraints,iomodel,DamageSpcdamageEnum,DamageEvolutionAnalysisEnum,P1Enum);
+	IoModelToConstraintsx(constraints,iomodel,DamageSpcdamageEnum,DamageEvolutionAnalysisEnum,finiteelement);
 
 }/*}}}*/
 void DamageEvolutionAnalysis::CreateLoads(Loads* loads, IoModel* iomodel){/*{{{*/
 
-	/*create penalties for nodes: no node can have a damage > 1*/
-	iomodel->FetchData(1,DamageSpcdamageEnum);
-	CreateSingleNodeToElementConnectivity(iomodel);
-
-	for(int i=0;i<iomodel->numberofvertices;i++){
-
-		/*keep only this partition's nodes:*/
-		if(iomodel->my_vertices[i]){
-			if (xIsNan<IssmDouble>(iomodel->Data(DamageSpcdamageEnum)[i])){ //No penalty applied on spc nodes!
-				loads->AddObject(new Pengrid(iomodel->loadcounter+i+1,i,iomodel,DamageEvolutionAnalysisEnum));
+	/*Nothing for now*/
+
+}/*}}}*/
+
+/*Finite Element Analysis*/
+void           DamageEvolutionAnalysis::Core(FemModel* femmodel){/*{{{*/
+	_error_("not implemented");
+}/*}}}*/
+ElementVector* DamageEvolutionAnalysis::CreateDVector(Element* element){/*{{{*/
+	/*Default, return NULL*/
+	return NULL;
+}/*}}}*/
+ElementMatrix* DamageEvolutionAnalysis::CreateJacobianMatrix(Element* element){/*{{{*/
+_error_("Not implemented");
+}/*}}}*/
+ElementMatrix* DamageEvolutionAnalysis::CreateKMatrix(Element* element){/*{{{*/
+
+	/* Check if ice in element */
+	if(!element->IsIceInElement()) return NULL;
+
+	/*Intermediaries*/
+	Element*    basalelement;
+	int         domaintype,dim;
+	int         stabilization;
+	IssmDouble  Jdet,dt,D_scalar,h;
+	IssmDouble  vel,vx,vy,dvxdx,dvydy,dvx[2],dvy[2];
+	IssmDouble *xyz_list  = NULL;
+
+	/*Get problem dimension and basal element*/
+	element->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DhorizontalEnum:
+			basalelement = element;
+			dim = 2;
+			break;
+		case Domain3DEnum:
+			if(!element->IsOnBase()) return NULL;
+			basalelement = element->SpawnBasalElement();
+			dim = 2;
+			break;
+		default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
+	}
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = basalelement->GetNumberOfNodes();
+
+	/*Initialize Element vector*/
+	ElementMatrix* Ke     = basalelement->NewElementMatrix();
+	IssmDouble*    basis  = xNew<IssmDouble>(numnodes);
+	IssmDouble*    B      = xNew<IssmDouble>(dim*numnodes);
+	IssmDouble*    Bprime = xNew<IssmDouble>(dim*numnodes);
+	IssmDouble*    D      = xNewZeroInit<IssmDouble>(dim*dim);
+
+	/*Retrieve all inputs and parameters*/
+	basalelement->GetVerticesCoordinates(&xyz_list);
+	basalelement->FindParam(&dt,TimesteppingTimeStepEnum);
+	basalelement->FindParam(&stabilization,DamageStabilizationEnum);
+	Input* vxaverage_input=NULL;
+	Input* vyaverage_input=NULL;
+	if(domaintype==Domain2DhorizontalEnum){
+		vxaverage_input=basalelement->GetInput(VxEnum); _assert_(vxaverage_input);
+		vyaverage_input=basalelement->GetInput(VyEnum); _assert_(vyaverage_input);
+	}
+	else{
+		if(dim==1){
+			vxaverage_input=element->GetInput(VxEnum); _assert_(vxaverage_input);
+		}
+		if(dim==2){
+			vxaverage_input=element->GetInput(VxAverageEnum); _assert_(vxaverage_input);
+			vyaverage_input=element->GetInput(VyAverageEnum); _assert_(vyaverage_input);
+		}
+	}
+	h=basalelement->CharacteristicLength();
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=basalelement->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		basalelement->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		basalelement->NodalFunctions(basis,gauss);
+		
+		vxaverage_input->GetInputValue(&vx,gauss);
+		vxaverage_input->GetInputDerivativeValue(&dvx[0],xyz_list,gauss);
+		if(dim==2){
+			vyaverage_input->GetInputValue(&vy,gauss);
+			vyaverage_input->GetInputDerivativeValue(&dvy[0],xyz_list,gauss);
+		}
+
+		D_scalar=gauss->weight*Jdet;
+		TripleMultiply(basis,1,numnodes,1,
+					&D_scalar,1,1,0,
+					basis,1,numnodes,0,
+					&Ke->values[0],1);
+
+		GetB(B,basalelement,dim,xyz_list,gauss);
+		GetBprime(Bprime,basalelement,dim,xyz_list,gauss);
+
+		dvxdx=dvx[0];
+		if(dim==2) dvydy=dvy[1];
+		D_scalar=dt*gauss->weight*Jdet;
+
+		D[0*dim+0]=D_scalar*dvxdx;
+		if(dim==2) D[1*dim+1]=D_scalar*dvydy;
+
+		TripleMultiply(B,dim,numnodes,1,
+					D,dim,dim,0,
+					B,dim,numnodes,0,
+					&Ke->values[0],1);
+
+		D[0*dim+0]=D_scalar*vx;
+		if(dim==2) D[1*dim+1]=D_scalar*vy;
+
+		TripleMultiply(B,dim,numnodes,1,
+					D,dim,dim,0,
+					Bprime,dim,numnodes,0,
+					&Ke->values[0],1);
+
+		if(stabilization==2){
+			if(dim==1){
+				vel=fabs(vx)+1.e-8;
+				D[0]=h/(2.0*vel)*vx*vx;
 			}
-		}
-	}
-	iomodel->DeleteData(1,DamageSpcdamageEnum);
-
-}/*}}}*/
+			else{
+				/*Streamline upwinding*/
+				vel=sqrt(vx*vx+vy*vy)+1.e-8;
+				D[0*dim+0]=h/(2.0*vel)*vx*vx;
+				D[1*dim+0]=h/(2.0*vel)*vy*vx;
+				D[0*dim+1]=h/(2.0*vel)*vx*vy;
+				D[1*dim+1]=h/(2.0*vel)*vy*vy;
+			}
+		}
+		else if(stabilization==1){
+			vxaverage_input->GetInputAverage(&vx);
+			if(dim==2) vyaverage_input->GetInputAverage(&vy);
+			D[0*dim+0]=h/2.0*fabs(vx);
+			if(dim==2) D[1*dim+1]=h/2.0*fabs(vy);
+		}
+		if(stabilization==1 || stabilization==2){
+			if(dim==1) D[0]=D_scalar*D[0];
+			else{
+				D[0*dim+0]=D_scalar*D[0*dim+0];
+				D[1*dim+0]=D_scalar*D[1*dim+0];
+				D[0*dim+1]=D_scalar*D[0*dim+1];
+				D[1*dim+1]=D_scalar*D[1*dim+1];
+			}
+
+			TripleMultiply(Bprime,dim,numnodes,1,
+						D,dim,dim,0,
+						Bprime,dim,numnodes,0,
+						&Ke->values[0],1);
+		}
+
+	}
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(basis);
+	xDelete<IssmDouble>(B);
+	xDelete<IssmDouble>(Bprime);
+	xDelete<IssmDouble>(D);
+	delete gauss;
+	if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;};
+	return Ke;
+}/*}}}*/
+ElementVector* DamageEvolutionAnalysis::CreatePVector(Element* element){/*{{{*/
+
+	/* Check if ice in element */
+	if(!element->IsIceInElement()) return NULL;
+
+	/*Intermediaries*/
+	int      domaintype;
+	Element* basalelement;
+	IssmDouble  Jdet,dt;
+	IssmDouble  f,damage;
+	IssmDouble* xyz_list = NULL;
+
+	/*Get basal element*/
+	element->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DhorizontalEnum:
+			basalelement = element;
+			break;
+		case Domain3DEnum:
+			if(!element->IsOnBase()) return NULL;
+			basalelement = element->SpawnBasalElement();
+			break;
+		default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
+	}
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = basalelement->GetNumberOfNodes();
+
+	/*Initialize Element vector and other vectors*/
+	ElementVector* pe    = basalelement->NewElementVector();
+	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	basalelement->GetVerticesCoordinates(&xyz_list);
+	basalelement->FindParam(&dt,TimesteppingTimeStepEnum);
+	this->CreateDamageFInput(basalelement);
+	Input* damaged_input = basalelement->GetInput(DamageDEnum); _assert_(damaged_input);
+	Input* damagef_input = basalelement->GetInput(DamageFEnum); _assert_(damagef_input);
+
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=basalelement->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		basalelement->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		basalelement->NodalFunctions(basis,gauss);
+
+		damaged_input->GetInputValue(&damage,gauss);
+		damagef_input->GetInputValue(&f,gauss);
+
+		for(int i=0;i<numnodes;i++){
+			pe->values[i]+=Jdet*gauss->weight*(damage+dt*f)*basis[i];
+		}
+	}
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(basis);
+	if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;};
+	delete gauss;
+	return pe;
+}/*}}}*/
+void DamageEvolutionAnalysis::GetB(IssmDouble* B,Element* element,int dim,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
+	/*Compute B  matrix. B=[B1 B2 B3] where Bi is of size 3*NDOF2. 
+	 * For node i, Bi can be expressed in the actual coordinate system
+	 * by: 
+	 *       Bi=[ N ]
+	 *          [ N ]
+	 * where N is the finiteelement function for node i.
+	 *
+	 * We assume B_prog has been allocated already, of size: 2x(NDOF1*numnodes)
+	 */
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Get nodal functions*/
+	IssmDouble* basis=xNew<IssmDouble>(numnodes);
+	element->NodalFunctions(basis,gauss);
+
+	/*Build B: */
+	for(int i=0;i<numnodes;i++){
+		for(int j=0;j<dim;j++){
+			B[numnodes*j+i] = basis[i];
+		}
+	}
+
+	/*Clean-up*/
+	xDelete<IssmDouble>(basis);
+}/*}}}*/
+void DamageEvolutionAnalysis::GetBprime(IssmDouble* Bprime,Element* element,int dim,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
+	/*Compute B'  matrix. B'=[B1' B2' B3'] where Bi' is of size 3*NDOF2. 
+	 * For node i, Bi' can be expressed in the actual coordinate system
+	 * by: 
+	 *       Bi_prime=[ dN/dx ]
+	 *                [ dN/dy ]
+	 * where N is the finiteelement function for node i.
+	 *
+	 * We assume B' has been allocated already, of size: 3x(NDOF2*numnodes)
+	 */
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Get nodal functions derivatives*/
+	IssmDouble* dbasis=xNew<IssmDouble>(dim*numnodes);
+	element->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+
+	/*Build B': */
+	for(int i=0;i<numnodes;i++){
+		for(int j=0;j<dim;j++){
+			Bprime[numnodes*j+i] = dbasis[j*numnodes+i];
+		}
+	}
+
+	/*Clean-up*/
+	xDelete<IssmDouble>(dbasis);
+
+}/*}}}*/
+void DamageEvolutionAnalysis::GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element){/*{{{*/
+	   _error_("not implemented yet");
+}/*}}}*/
+void DamageEvolutionAnalysis::InputUpdateFromSolution(IssmDouble* solution,Element* element){/*{{{*/
+
+	int domaintype;
+	IssmDouble  max_damage;
+	int			*doflist = NULL;
+	Element*   basalelement=NULL;
+
+	element->FindParam(&domaintype,DomainTypeEnum);
+	if(domaintype!=Domain2DhorizontalEnum){
+		if(!element->IsOnBase()) return;
+		basalelement=element->SpawnBasalElement();
+	}
+	else{
+		basalelement = element;
+	}
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = basalelement->GetNumberOfNodes();
+
+	/*Fetch dof list and allocate solution vector*/
+	basalelement->GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
+	IssmDouble* newdamage = xNew<IssmDouble>(numnodes);
+
+	/*Get user-supplied max_damage: */
+	basalelement->FindParam(&max_damage,DamageMaxDamageEnum);
+
+	/*Use the dof list to index into the solution vector: */
+	for(int i=0;i<numnodes;i++){
+		newdamage[i]=solution[doflist[i]];
+		/*Check solution*/
+		if(xIsNan<IssmDouble>(newdamage[i])) _error_("NaN found in solution vector");
+		/*Enforce D < max_damage and D > 0 */
+		if(newdamage[i]>max_damage) newdamage[i]=max_damage;
+		else if(newdamage[i]<0.)    newdamage[i]=0.;
+	}
+
+	/*Get all inputs and parameters*/
+	if(domaintype==Domain2DhorizontalEnum){
+		basalelement->AddInput(DamageDbarEnum,newdamage,element->GetElementType());
+	}
+	else{
+		basalelement->AddBasalInput(DamageDEnum,newdamage,element->GetElementType());
+	}
+
+	/*Free ressources:*/
+	xDelete<IssmDouble>(newdamage);
+	xDelete<int>(doflist);
+	if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;};
+}/*}}}*/
+void DamageEvolutionAnalysis::UpdateConstraints(FemModel* femmodel){/*{{{*/
+	/*Default, do nothing*/
+	return;
+}/*}}}*/
+
+/*Intermediaries*/
+void DamageEvolutionAnalysis::CreateDamageFInput(Element* element){/*{{{*/
+
+	/*Intermediaries */
+	IssmDouble c1,c2,c3,healing,stress_threshold;
+	IssmDouble s_xx,s_xy,s_yy,s1,s2,stmp;
+	IssmDouble J2s,Chi,Psi,PosPsi,NegPsi;
+	IssmDouble damage,tau_xx,tau_xy,tau_yy;
+	int equivstress,domaintype;
+
+	/*Fetch number of vertices and allocate output*/
+	int numvertices = element->GetNumberOfVertices();
+	IssmDouble* f   = xNew<IssmDouble>(numvertices);
+
+	/*retrieve parameters:*/
+	element->FindParam(&c1,DamageC1Enum);
+	element->FindParam(&c2,DamageC2Enum);
+	element->FindParam(&c3,DamageC3Enum);
+	element->FindParam(&healing,DamageHealingEnum);
+	element->FindParam(&stress_threshold,DamageStressThresholdEnum);
+	element->FindParam(&domaintype,DomainTypeEnum);
+
+	/*Compute stress tensor: */
+	element->ComputeDeviatoricStressTensor();
+
+	/*retrieve what we need: */
+	Input* tau_xx_input  = element->GetInput(DeviatoricStressxxEnum);     _assert_(tau_xx_input);
+	Input* tau_xy_input  = element->GetInput(DeviatoricStressxyEnum);     _assert_(tau_xy_input);
+	Input* tau_yy_input  = element->GetInput(DeviatoricStressyyEnum);     _assert_(tau_yy_input);
+	Input* damage_input = NULL;
+	if(domaintype==Domain2DhorizontalEnum){
+		damage_input = element->GetInput(DamageDbarEnum); 	_assert_(damage_input);
+	}
+	else{
+		damage_input = element->GetInput(DamageDEnum);   _assert_(damage_input);
+	}
+
+
+
+	/*retrieve the desired type of equivalent stress*/
+	element->FindParam(&equivstress,DamageEquivStressEnum);
+
+	/*Calculate damage evolution source term: */
+	Gauss* gauss=element->NewGauss();
+	for (int iv=0;iv<numvertices;iv++){
+		gauss->GaussVertex(iv);
+		
+		damage_input->GetInputValue(&damage,gauss);
+		tau_xx_input->GetInputValue(&tau_xx,gauss);
+		tau_xy_input->GetInputValue(&tau_xy,gauss);
+		tau_yy_input->GetInputValue(&tau_yy,gauss);
+	
+		/*Calculate effective stress components*/
+		s_xx=tau_xx/(1.-damage);
+		s_xy=tau_xy/(1.-damage);
+		s_yy=tau_yy/(1.-damage);
+
+		/*Calculate principal effective stresses*/
+		s1=(s_xx+s_yy)/2.+sqrt(pow((s_xx-s_yy)/2.,2)+pow(s_xy,2));
+		s2=(s_xx+s_yy)/2.-sqrt(pow((s_xx-s_yy)/2.,2)+pow(s_xy,2));
+		if(fabs(s2)>fabs(s1)){stmp=s2; s2=s1; s1=stmp;}
+
+		if(equivstress==0){ /* von Mises */
+			Chi=sqrt(s1*s1-s1*s2+s2*s2);
+		}
+		else if(equivstress==1){ /* max principal stress */
+			Chi=s1;
+		}
+		Psi=Chi-stress_threshold;
+		PosPsi=max(Psi,0.);
+		NegPsi=max(-Chi,0.); /* healing only for compressive stresses */
+
+		f[iv]= c1*(pow(PosPsi,c2) - healing*pow(NegPsi,c2))*pow((1.-damage),-c3);
+	}
+
+	/*Add input*/
+	element->AddInput(DamageFEnum,f,P1Enum);
+	
+	/*Clean up and return*/
+	xDelete<IssmDouble>(f);
+	delete gauss;
+}/*}}}*/
Index: /issm/trunk/src/c/analyses/DamageEvolutionAnalysis.h
===================================================================
--- /issm/trunk/src/c/analyses/DamageEvolutionAnalysis.h	(revision 17805)
+++ /issm/trunk/src/c/analyses/DamageEvolutionAnalysis.h	(revision 17806)
@@ -12,5 +12,6 @@
 
 	public:
-		int  DofsPerNode(int** doflist,int meshtype,int approximation);
+		/*Model processing*/
+		int  DofsPerNode(int** doflist,int domaintype,int approximation);
 		void UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum);
 		void UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);
@@ -18,4 +19,19 @@
 		void CreateConstraints(Constraints* constraints,IoModel* iomodel);
 		void CreateLoads(Loads* loads, IoModel* iomodel);
+
+		/*Finite element Analysis*/
+		void           Core(FemModel* femmodel);
+		ElementVector* CreateDVector(Element* element);
+		ElementMatrix* CreateJacobianMatrix(Element* element);
+		ElementMatrix* CreateKMatrix(Element* element);
+		ElementVector* CreatePVector(Element* element);
+		void GetB(IssmDouble* B,Element* element,int dim,IssmDouble* xyz_list,Gauss* gauss);
+		void GetBprime(IssmDouble* B,Element* element,int dim,IssmDouble* xyz_list,Gauss* gauss);
+		void GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element);
+		void InputUpdateFromSolution(IssmDouble* solution,Element* element);
+		void UpdateConstraints(FemModel* femmodel);
+
+		/*Intermediaries*/
+		void CreateDamageFInput(Element* element);
 };
 #endif
Index: /issm/trunk/src/c/analyses/DepthAverageAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/DepthAverageAnalysis.cpp	(revision 17806)
+++ /issm/trunk/src/c/analyses/DepthAverageAnalysis.cpp	(revision 17806)
@@ -0,0 +1,171 @@
+#include "./DepthAverageAnalysis.h"
+#include "../toolkits/toolkits.h"
+#include "../classes/classes.h"
+#include "../shared/shared.h"
+#include "../modules/modules.h"
+
+/*Model processing*/
+int  DepthAverageAnalysis::DofsPerNode(int** doflist,int domaintype,int approximation){/*{{{*/
+	return 1;
+}/*}}}*/
+void DepthAverageAnalysis::UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum){/*{{{*/
+}/*}}}*/
+void DepthAverageAnalysis::UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type){/*{{{*/
+
+	int counter=0;
+	for(int i=0;i<iomodel->numberofelements;i++){
+		if(iomodel->my_elements[i]){
+			Element* element=(Element*)elements->GetObjectByOffset(counter);
+			element->Update(i,iomodel,analysis_counter,analysis_type,P1Enum);
+			counter++;
+		}
+	}
+
+	if(iomodel->domaintype==Domain2DverticalEnum){
+		iomodel->FetchDataToInput(elements,MeshVertexonbaseEnum);
+	}
+}/*}}}*/
+void DepthAverageAnalysis::CreateNodes(Nodes* nodes,IoModel* iomodel){/*{{{*/
+
+	::CreateNodes(nodes,iomodel,DepthAverageAnalysisEnum,P1Enum);
+
+}/*}}}*/
+void DepthAverageAnalysis::CreateConstraints(Constraints* constraints,IoModel* iomodel){/*{{{*/
+}/*}}}*/
+void DepthAverageAnalysis::CreateLoads(Loads* loads, IoModel* iomodel){/*{{{*/
+}/*}}}*/
+
+/*Finite Element Analysis*/
+void           DepthAverageAnalysis::Core(FemModel* femmodel){/*{{{*/
+	_error_("not implemented");
+}/*}}}*/
+ElementVector* DepthAverageAnalysis::CreateDVector(Element* element){/*{{{*/
+	/*Default, return NULL*/
+	return NULL;
+}/*}}}*/
+ElementMatrix* DepthAverageAnalysis::CreateJacobianMatrix(Element* element){/*{{{*/
+_error_("Not implemented");
+}/*}}}*/
+ElementMatrix* DepthAverageAnalysis::CreateKMatrix(Element* element){/*{{{*/
+
+	/*Intermediaries */
+	int         dim;
+	IssmDouble  Jdet,D,dt=1.e+9;
+	IssmDouble *xyz_list = NULL;
+
+	/*Get dimension*/
+	element->FindParam(&dim,DomainDimensionEnum);
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Initialize Element vector and other vectors*/
+	ElementMatrix* Ke     = element->NewElementMatrix();
+	IssmDouble*    B      = xNew<IssmDouble>(numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		GetB(B,element,dim,xyz_list,gauss);
+		D=gauss->weight*Jdet*dt;
+
+		/*vertical diffusion*/
+		TripleMultiply(B,1,numnodes,1,
+					&D,1,1,0,
+					B,1,numnodes,0,
+					&Ke->values[0],1);
+
+		/*Next value*/
+		D=gauss->weight*Jdet;
+		element->NodalFunctions(B,gauss);
+		TripleMultiply(B,numnodes,1,0,
+					&D,1,1,0,
+					B,1,numnodes,0,
+					&Ke->values[0],1);
+	} 
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(B);
+	delete gauss;
+	return Ke;
+}/*}}}*/
+ElementVector* DepthAverageAnalysis::CreatePVector(Element* element){/*{{{*/
+
+	/*Intermediaries*/
+	int         input_enum;
+	IssmDouble  Jdet,scalar,value;
+	IssmDouble* xyz_list = NULL;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Initialize Element vector*/
+	ElementVector* pe     = element->NewElementVector();
+	IssmDouble*    basis  = xNew<IssmDouble>(numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+	element->FindParam(&input_enum,InputToDepthaverageEnum);
+	Input* input = element->GetInput(input_enum); _assert_(input);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGauss(3);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		element->NodalFunctions(basis,gauss);
+
+		/* Build transient now */
+		input->GetInputValue(&value, gauss);
+		scalar=value*Jdet*gauss->weight;
+		for(int i=0;i<numnodes;i++) pe->values[i]+=scalar*basis[i];
+
+	}
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(basis);
+	xDelete<IssmDouble>(xyz_list);
+	delete gauss;
+	return pe;
+}/*}}}*/
+void DepthAverageAnalysis::GetB(IssmDouble* B,Element* element,int dim,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
+	/*	Compute B  matrix. B=[dh1/dz dh2/dz dh3/dz dh4/dz dh5/dz dh6/dz];
+		where hi is the interpolation function for node i.*/
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Get nodal functions derivatives*/
+	IssmDouble* dbasis=xNew<IssmDouble>(dim*numnodes);
+	element->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+
+	/*Build B: */
+	for(int i=0;i<numnodes;i++){
+		B[i] = dbasis[(dim-1)*numnodes+i];
+	}
+
+	/*Clean-up*/
+	xDelete<IssmDouble>(dbasis);
+}
+/*}}}*/
+void DepthAverageAnalysis::GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element){/*{{{*/
+	   _error_("not implemented yet");
+}/*}}}*/
+void DepthAverageAnalysis::InputUpdateFromSolution(IssmDouble* solution,Element* element){/*{{{*/
+
+	int inputenum;
+	element->FindParam(&inputenum,InputToDepthaverageEnum);
+	element->InputUpdateFromSolutionOneDof(solution,inputenum);
+}/*}}}*/
+void DepthAverageAnalysis::UpdateConstraints(FemModel* femmodel){/*{{{*/
+	/*Default, do nothing*/
+	return;
+}/*}}}*/
Index: /issm/trunk/src/c/analyses/DepthAverageAnalysis.h
===================================================================
--- /issm/trunk/src/c/analyses/DepthAverageAnalysis.h	(revision 17806)
+++ /issm/trunk/src/c/analyses/DepthAverageAnalysis.h	(revision 17806)
@@ -0,0 +1,33 @@
+/*! \file DepthAverageAnalysis.h 
+ *  \brief: header file for generic external result object
+ */
+
+#ifndef _DepthAverageAnalysis_
+#define _DepthAverageAnalysis_
+
+/*Headers*/
+#include "./Analysis.h"
+
+class DepthAverageAnalysis: public Analysis{
+
+	public:
+		/*Model processing*/
+		int  DofsPerNode(int** doflist,int domaintype,int approximation);
+		void UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum);
+		void UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);
+		void CreateNodes(Nodes* nodes,IoModel* iomodel);
+		void CreateConstraints(Constraints* constraints,IoModel* iomodel);
+		void CreateLoads(Loads* loads, IoModel* iomodel);
+
+		/*Finite element Analysis*/
+		void           Core(FemModel* femmodel);
+		ElementVector* CreateDVector(Element* element);
+		ElementMatrix* CreateJacobianMatrix(Element* element);
+		ElementMatrix* CreateKMatrix(Element* element);
+		ElementVector* CreatePVector(Element* element);
+		void GetB(IssmDouble* B,Element* element,int dim,IssmDouble* xyz_list,Gauss* gauss);
+		void GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element);
+		void InputUpdateFromSolution(IssmDouble* solution,Element* element);
+		void UpdateConstraints(FemModel* femmodel);
+};
+#endif
Index: /issm/trunk/src/c/analyses/EnthalpyAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/EnthalpyAnalysis.cpp	(revision 17805)
+++ /issm/trunk/src/c/analyses/EnthalpyAnalysis.cpp	(revision 17806)
@@ -6,16 +6,28 @@
 
 /*Model processing*/
-int  EnthalpyAnalysis::DofsPerNode(int** doflist,int meshtype,int approximation){/*{{{*/
+int  EnthalpyAnalysis::DofsPerNode(int** doflist,int domaintype,int approximation){/*{{{*/
 	return 1;
 }/*}}}*/
 void EnthalpyAnalysis::UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum){/*{{{*/
+
+	int     numoutputs;
+	char**  requestedoutputs = NULL;
+
+	parameters->AddObject(iomodel->CopyConstantObject(ThermalStabilizationEnum));
+	parameters->AddObject(iomodel->CopyConstantObject(ThermalIsenthalpyEnum));
+	parameters->AddObject(iomodel->CopyConstantObject(ThermalIsdynamicbasalspcEnum));
+
+	iomodel->FetchData(&requestedoutputs,&numoutputs,ThermalRequestedOutputsEnum);
+	parameters->AddObject(new IntParam(ThermalNumRequestedOutputsEnum,numoutputs));
+	if(numoutputs)parameters->AddObject(new StringArrayParam(ThermalRequestedOutputsEnum,requestedoutputs,numoutputs));
+	iomodel->DeleteData(&requestedoutputs,numoutputs,ThermalRequestedOutputsEnum);
 }/*}}}*/
 void EnthalpyAnalysis::UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type){/*{{{*/
 
-	bool dakota_analysis;
+	bool dakota_analysis, islevelset;
 	bool isenthalpy;
 
 	/*Now, is the model 3d? otherwise, do nothing: */
-	if(iomodel->meshtype==Mesh2DhorizontalEnum)return;
+	if(iomodel->domaintype==Domain2DhorizontalEnum)return;
 
 	/*Is enthalpy requested?*/
@@ -37,8 +49,9 @@
 
 	iomodel->Constant(&dakota_analysis,QmuIsdakotaEnum);
+	iomodel->Constant(&islevelset,TransientIslevelsetEnum);
 
 	iomodel->FetchDataToInput(elements,ThicknessEnum);
 	iomodel->FetchDataToInput(elements,SurfaceEnum);
-	iomodel->FetchDataToInput(elements,BedEnum);
+	iomodel->FetchDataToInput(elements,BaseEnum);
 	iomodel->FetchDataToInput(elements,FrictionCoefficientEnum);
 	iomodel->FetchDataToInput(elements,FrictionPEnum);
@@ -46,5 +59,5 @@
 	iomodel->FetchDataToInput(elements,MaskIceLevelsetEnum);
 	iomodel->FetchDataToInput(elements,MaskGroundediceLevelsetEnum);
-	iomodel->FetchDataToInput(elements,MeshElementonbedEnum);
+	iomodel->FetchDataToInput(elements,MeshElementonbaseEnum);
 	iomodel->FetchDataToInput(elements,MeshElementonsurfaceEnum);
 	iomodel->FetchDataToInput(elements,FlowequationElementEquationEnum);
@@ -71,4 +84,8 @@
 		elements->InputDuplicate(VxMeshEnum,QmuVzMeshEnum);
 	}
+	if(islevelset){
+		iomodel->FetchDataToInput(elements,IceMaskNodeActivationEnum);
+		iomodel->FetchDataToInput(elements,MeshVertexonbaseEnum); // required for updating active nodes
+	}
 
 	/*Free data: */
@@ -77,7 +94,7 @@
 void EnthalpyAnalysis::CreateNodes(Nodes* nodes,IoModel* iomodel){/*{{{*/
 
-	if(iomodel->meshtype==Mesh3DEnum) iomodel->FetchData(2,MeshVertexonbedEnum,MeshVertexonsurfaceEnum);
+	if(iomodel->domaintype==Domain3DEnum) iomodel->FetchData(2,MeshVertexonbaseEnum,MeshVertexonsurfaceEnum);
 	::CreateNodes(nodes,iomodel,EnthalpyAnalysisEnum,P1Enum);
-	iomodel->DeleteData(2,MeshVertexonbedEnum,MeshVertexonsurfaceEnum);
+	iomodel->DeleteData(2,MeshVertexonbaseEnum,MeshVertexonsurfaceEnum);
 }/*}}}*/
 void EnthalpyAnalysis::CreateConstraints(Constraints* constraints,IoModel* iomodel){/*{{{*/
@@ -100,5 +117,5 @@
 
 	/*return if 2d mesh*/
-	if(iomodel->meshtype==Mesh2DhorizontalEnum) return;
+	if(iomodel->domaintype==Domain2DhorizontalEnum) return;
 
 	/*Fetch data: */
@@ -117,5 +134,5 @@
 				if (!xIsNan<IssmDouble>(spcvector[i])){
 
-					constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,1,heatcapacity*(spcvector[i]-referencetemperature),EnthalpyAnalysisEnum));
+					constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,0,heatcapacity*(spcvector[i]-referencetemperature),EnthalpyAnalysisEnum));
 					count++;
 
@@ -150,5 +167,5 @@
 
 				if(spcpresent){
-					constraints->AddObject(new SpcTransient(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,1,N,times,values,EnthalpyAnalysisEnum));
+					constraints->AddObject(new SpcTransient(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,0,N,times,values,EnthalpyAnalysisEnum));
 					count++;
 				}
@@ -170,2 +187,1113 @@
 	/*No loads */
 }/*}}}*/
+
+/*Finite Element Analysis*/
+void EnthalpyAnalysis::Core(FemModel* femmodel){/*{{{*/
+	_error_("not implemented");
+}/*}}}*/
+ElementVector* EnthalpyAnalysis::CreateDVector(Element* element){/*{{{*/
+	/*Default, return NULL*/
+	return NULL;
+}/*}}}*/
+ElementMatrix* EnthalpyAnalysis::CreateJacobianMatrix(Element* element){/*{{{*/
+_error_("Not implemented");
+}/*}}}*/
+ElementMatrix* EnthalpyAnalysis::CreateKMatrix(Element* element){/*{{{*/
+
+	/* Check if ice in element */
+	if(!element->IsIceInElement()) return NULL;
+
+	/*compute all stiffness matrices for this element*/
+	ElementMatrix* Ke1=CreateKMatrixVolume(element);
+	ElementMatrix* Ke2=CreateKMatrixShelf(element);
+	ElementMatrix* Ke =new ElementMatrix(Ke1,Ke2);
+
+	/*clean-up and return*/
+	delete Ke1;
+	delete Ke2;
+	return Ke;
+}/*}}}*/
+ElementMatrix* EnthalpyAnalysis::CreateKMatrixVolume(Element* element){/*{{{*/
+
+	/* Check if ice in element */
+	if(!element->IsIceInElement()) return NULL;
+
+	/*Intermediaries */
+	int         stabilization;
+	IssmDouble  Jdet,dt,u,v,w,um,vm,wm,vel;
+	IssmDouble  h,hx,hy,hz,vx,vy,vz;
+	IssmDouble  tau_parameter,diameter;
+	IssmDouble  D_scalar;
+	IssmDouble* xyz_list = NULL;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes    = element->GetNumberOfNodes();
+
+	/*Initialize Element vector and other vectors*/
+	ElementMatrix* Ke       = element->NewElementMatrix();
+	IssmDouble*    basis    = xNew<IssmDouble>(numnodes);
+	IssmDouble*    dbasis   = xNew<IssmDouble>(3*numnodes);
+	IssmDouble*    B        = xNew<IssmDouble>(3*numnodes);
+	IssmDouble*    Bprime   = xNew<IssmDouble>(3*numnodes);
+	IssmDouble     D[3][3]  = {0.};
+	IssmDouble     K[3][3];
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+	element->FindParam(&dt,TimesteppingTimeStepEnum);
+	element->FindParam(&stabilization,ThermalStabilizationEnum);
+	IssmDouble  rho_water           = element->GetMaterialParameter(MaterialsRhoWaterEnum);
+	IssmDouble  rho_ice             = element->GetMaterialParameter(MaterialsRhoIceEnum);
+	IssmDouble  gravity             = element->GetMaterialParameter(ConstantsGEnum);
+	IssmDouble  heatcapacity        = element->GetMaterialParameter(MaterialsHeatcapacityEnum);
+	IssmDouble  thermalconductivity = element->GetMaterialParameter(MaterialsThermalconductivityEnum);
+	Input* vx_input  = element->GetInput(VxEnum);     _assert_(vx_input);
+	Input* vy_input  = element->GetInput(VyEnum);     _assert_(vy_input);
+	Input* vz_input  = element->GetInput(VzEnum);     _assert_(vz_input);
+	Input* vxm_input = element->GetInput(VxMeshEnum); _assert_(vxm_input);
+	Input* vym_input = element->GetInput(VyMeshEnum); _assert_(vym_input);
+	Input* vzm_input = element->GetInput(VzMeshEnum); _assert_(vzm_input);
+	if(stabilization==2) diameter=element->MinEdgeLength(xyz_list);
+
+	/*Enthalpy diffusion parameter*/
+	IssmDouble kappa=this->EnthalpyDiffusionParameterVolume(element,EnthalpyPicardEnum); _assert_(kappa>=0.);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		D_scalar=gauss->weight*Jdet;
+		if(dt!=0.) D_scalar=D_scalar*dt;
+
+		/*Conduction: */
+		GetBConduct(B,element,xyz_list,gauss); 
+		D[0][0]=D_scalar*kappa/rho_ice;
+		D[1][1]=D_scalar*kappa/rho_ice;
+		D[2][2]=D_scalar*kappa/rho_ice;
+		TripleMultiply(B,3,numnodes,1,
+					&D[0][0],3,3,0,
+					B,3,numnodes,0,
+					&Ke->values[0],1);
+
+		/*Advection: */
+		GetBAdvec(B,element,xyz_list,gauss); 
+		GetBAdvecprime(Bprime,element,xyz_list,gauss); 
+		vx_input->GetInputValue(&u,gauss); vxm_input->GetInputValue(&um,gauss); vx=u-um;
+		vy_input->GetInputValue(&v,gauss); vym_input->GetInputValue(&vm,gauss); vy=v-vm;
+		vz_input->GetInputValue(&w,gauss); vzm_input->GetInputValue(&wm,gauss); vz=w-wm;
+		D[0][0]=D_scalar*vx;
+		D[1][1]=D_scalar*vy;
+		D[2][2]=D_scalar*vz;
+		TripleMultiply(B,3,numnodes,1,
+					&D[0][0],3,3,0,
+					Bprime,3,numnodes,0,
+					&Ke->values[0],1);
+
+		/*Transient: */
+		if(dt!=0.){
+			D_scalar=gauss->weight*Jdet;
+			element->NodalFunctions(basis,gauss);
+			TripleMultiply(basis,numnodes,1,0,
+						&D_scalar,1,1,0,
+						basis,1,numnodes,0,
+						&Ke->values[0],1);
+			D_scalar=D_scalar*dt;
+		}
+
+		/*Artifficial diffusivity*/
+		if(stabilization==1){
+			element->ElementSizes(&hx,&hy,&hz);
+			vel=sqrt(vx*vx + vy*vy + vz*vz)+1.e-14;
+			h=sqrt( pow(hx*vx/vel,2) + pow(hy*vy/vel,2) + pow(hz*vz/vel,2));
+			K[0][0]=h/(2.*vel)*vx*vx;  K[0][1]=h/(2.*vel)*vx*vy; K[0][2]=h/(2.*vel)*vx*vz;
+			K[1][0]=h/(2.*vel)*vy*vx;  K[1][1]=h/(2.*vel)*vy*vy; K[1][2]=h/(2.*vel)*vy*vz;
+			K[2][0]=h/(2.*vel)*vz*vx;  K[2][1]=h/(2.*vel)*vz*vy; K[2][2]=h/(2.*vel)*vz*vz;
+			for(int i=0;i<3;i++) for(int j=0;j<3;j++) K[i][j] = D_scalar*K[i][j];
+
+			GetBAdvecprime(Bprime,element,xyz_list,gauss); 
+			TripleMultiply(Bprime,3,numnodes,1,
+						&K[0][0],3,3,0,
+						Bprime,3,numnodes,0,
+						&Ke->values[0],1);
+		}
+		else if(stabilization==2){
+			element->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+			tau_parameter=element->StabilizationParameter(u-um,v-vm,w-wm,diameter,kappa/rho_ice);
+			for(int i=0;i<numnodes;i++){
+				for(int j=0;j<numnodes;j++){
+					Ke->values[i*numnodes+j]+=tau_parameter*D_scalar*
+					  ((u-um)*dbasis[0*numnodes+i]+(v-vm)*dbasis[1*numnodes+i]+(w-wm)*dbasis[2*numnodes+i])*((u-um)*dbasis[0*numnodes+j]+(v-vm)*dbasis[1*numnodes+j]+(w-wm)*dbasis[2*numnodes+j]);
+				}
+			}
+			if(dt!=0.){
+				D_scalar=gauss->weight*Jdet;
+				for(int i=0;i<numnodes;i++){
+					for(int j=0;j<numnodes;j++){
+						Ke->values[i*numnodes+j]+=tau_parameter*D_scalar*basis[j]*((u-um)*dbasis[0*numnodes+i]+(v-vm)*dbasis[1*numnodes+i]+(w-wm)*dbasis[2*numnodes+i]);
+					}
+				}
+			}
+		}
+	}
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(basis);
+	xDelete<IssmDouble>(dbasis);
+	xDelete<IssmDouble>(B);
+	xDelete<IssmDouble>(Bprime);
+	delete gauss;
+	return Ke;
+}/*}}}*/
+ElementMatrix* EnthalpyAnalysis::CreateKMatrixShelf(Element* element){/*{{{*/
+
+	/* Check if ice in element */
+	if(!element->IsIceInElement()) return NULL;
+
+	/*Initialize Element matrix and return if necessary*/
+	if(!element->IsOnBase() || !element->IsFloating()) return NULL;
+
+	/*Intermediaries*/
+	IssmDouble  dt,Jdet,D;
+	IssmDouble *xyz_list_base = NULL;
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Initialize vectors*/
+	ElementMatrix* Ke    = element->NewElementMatrix();
+	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinatesBase(&xyz_list_base);
+	element->FindParam(&dt,TimesteppingTimeStepEnum);
+	IssmDouble  gravity             = element->GetMaterialParameter(ConstantsGEnum);
+	IssmDouble  rho_water           = element->GetMaterialParameter(MaterialsRhoWaterEnum);
+	IssmDouble  rho_ice             = element->GetMaterialParameter(MaterialsRhoIceEnum);
+	IssmDouble  heatcapacity        = element->GetMaterialParameter(MaterialsHeatcapacityEnum);
+	IssmDouble  mixed_layer_capacity= element->GetMaterialParameter(MaterialsMixedLayerCapacityEnum);
+	IssmDouble  thermal_exchange_vel= element->GetMaterialParameter(MaterialsThermalExchangeVelocityEnum);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGaussBase(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminantBase(&Jdet,xyz_list_base,gauss);
+		element->NodalFunctions(basis,gauss);
+
+		D=gauss->weight*Jdet*rho_water*mixed_layer_capacity*thermal_exchange_vel/(heatcapacity*rho_ice);
+		if(reCast<bool,IssmDouble>(dt)) D=dt*D;
+		TripleMultiply(basis,numnodes,1,0,
+					&D,1,1,0,
+					basis,1,numnodes,0,
+					&Ke->values[0],1);
+
+	}
+
+	/*Clean up and return*/
+	delete gauss;
+	xDelete<IssmDouble>(basis);
+	xDelete<IssmDouble>(xyz_list_base);
+	return Ke;
+}/*}}}*/
+ElementVector* EnthalpyAnalysis::CreatePVector(Element* element){/*{{{*/
+
+	/* Check if ice in element */
+	if(!element->IsIceInElement()) return NULL;
+
+	/*compute all load vectors for this element*/
+	ElementVector* pe1=CreatePVectorVolume(element);
+	ElementVector* pe2=CreatePVectorSheet(element);
+	ElementVector* pe3=CreatePVectorShelf(element);
+	ElementVector* pe =new ElementVector(pe1,pe2,pe3);
+
+	/*clean-up and return*/
+	delete pe1;
+	delete pe2;
+	delete pe3;
+	return pe;
+}/*}}}*/
+ElementVector* EnthalpyAnalysis::CreatePVectorVolume(Element* element){/*{{{*/
+
+	/* Check if ice in element */
+	if(!element->IsIceInElement()) return NULL;
+
+	/*Intermediaries*/
+	int         i, stabilization;
+	IssmDouble  Jdet,phi,dt;
+	IssmDouble  enthalpy, Hpmp;
+	IssmDouble  enthalpypicard, d1enthalpypicard[3];
+	IssmDouble  pressure, d1pressure[3], d2pressure;
+	IssmDouble  waterfractionpicard;
+	IssmDouble  kappa,tau_parameter,diameter,kappa_w;
+	IssmDouble  u,v,w;
+	IssmDouble  scalar_def, scalar_sens ,scalar_transient;
+	IssmDouble* xyz_list = NULL;
+	IssmDouble  d1H_d1P, d1P2;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes    = element->GetNumberOfNodes();
+	int numvertices = element->GetNumberOfVertices();
+
+	/*Initialize Element vector*/
+	ElementVector* pe             = element->NewElementVector();
+	IssmDouble*    basis          = xNew<IssmDouble>(numnodes);
+	IssmDouble*    dbasis         = xNew<IssmDouble>(3*numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+	IssmDouble  rho_ice             = element->GetMaterialParameter(MaterialsRhoIceEnum);
+	IssmDouble  heatcapacity        = element->GetMaterialParameter(MaterialsHeatcapacityEnum);
+	IssmDouble  thermalconductivity = element->GetMaterialParameter(MaterialsThermalconductivityEnum);
+	IssmDouble  temperateiceconductivity = element->GetMaterialParameter(MaterialsTemperateiceconductivityEnum);
+	IssmDouble  beta                = element->GetMaterialParameter(MaterialsBetaEnum);
+	IssmDouble  latentheat          = element->GetMaterialParameter(MaterialsLatentheatEnum);
+	element->FindParam(&dt,TimesteppingTimeStepEnum);
+	element->FindParam(&stabilization,ThermalStabilizationEnum);
+	Input* vx_input=element->GetInput(VxEnum); _assert_(vx_input);
+	Input* vy_input=element->GetInput(VyEnum); _assert_(vy_input);
+	Input* vz_input=element->GetInput(VzEnum); _assert_(vz_input);
+	Input* enthalpypicard_input=element->GetInput(EnthalpyPicardEnum); _assert_(enthalpypicard_input);
+	Input* pressure_input=element->GetInput(PressureEnum); _assert_(pressure_input);
+	Input* enthalpy_input=NULL;
+	if(reCast<bool,IssmDouble>(dt)){enthalpy_input = element->GetInput(EnthalpyEnum); _assert_(enthalpy_input);}
+	if(stabilization==2){
+		diameter=element->MinEdgeLength(xyz_list);
+		kappa=this->EnthalpyDiffusionParameterVolume(element,EnthalpyPicardEnum); _assert_(kappa>=0.);
+	}
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGauss(3);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		element->NodalFunctions(basis,gauss);
+		
+		/*viscous dissipation*/
+		element->ViscousHeating(&phi,xyz_list,gauss,vx_input,vy_input,vz_input);
+
+		scalar_def=phi/rho_ice*Jdet*gauss->weight;
+		if(dt!=0.) scalar_def=scalar_def*dt;
+
+		for(i=0;i<numnodes;i++) pe->values[i]+=scalar_def*basis[i];
+
+		/*sensible heat flux in temperate ice*/
+		enthalpypicard_input->GetInputValue(&enthalpypicard,gauss);
+		pressure_input->GetInputValue(&pressure,gauss);
+		Hpmp=this->PureIceEnthalpy(element, pressure);
+
+		if(enthalpypicard>=Hpmp){
+			enthalpypicard_input->GetInputDerivativeValue(&d1enthalpypicard[0],xyz_list,gauss);
+			pressure_input->GetInputDerivativeValue(&d1pressure[0],xyz_list,gauss);
+			d2pressure=0.; // for linear elements, 2nd derivative is zero
+			
+			d1H_d1P=0.;
+			for(i=0;i<3;i++) d1H_d1P+=d1enthalpypicard[i]*d1pressure[i];
+			d1P2=0.;
+			for(i=0;i<3;i++) d1P2+=pow(d1pressure[i],2.);
+
+			scalar_sens=-beta*((temperateiceconductivity - thermalconductivity)/latentheat*(d1H_d1P + beta*heatcapacity*d1P2))/rho_ice;
+			if(dt!=0.) scalar_sens=scalar_sens*dt;
+			for(i=0;i<numnodes;i++) pe->values[i]+=scalar_sens*basis[i];
+		}		
+
+		/* Build transient now */
+		if(reCast<bool,IssmDouble>(dt)){
+			enthalpy_input->GetInputValue(&enthalpy, gauss);
+			scalar_transient=enthalpy*Jdet*gauss->weight;
+			for(i=0;i<numnodes;i++) pe->values[i]+=scalar_transient*basis[i];
+		}
+
+		if(stabilization==2){
+			element->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+
+			vx_input->GetInputValue(&u,gauss);
+			vy_input->GetInputValue(&v,gauss);
+			vz_input->GetInputValue(&w,gauss);
+			tau_parameter=element->StabilizationParameter(u,v,w,diameter,kappa/rho_ice);
+
+			for(i=0;i<numnodes;i++) pe->values[i]+=tau_parameter*scalar_def*(u*dbasis[0*numnodes+i]+v*dbasis[1*numnodes+i]+w*dbasis[2*numnodes+i]);
+
+			if(dt!=0.){
+				for(i=0;i<numnodes;i++) pe->values[i]+=tau_parameter*scalar_transient*(u*dbasis[0*numnodes+i]+v*dbasis[1*numnodes+i]+w*dbasis[2*numnodes+i]);
+			}
+		}
+	}
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(basis);
+	xDelete<IssmDouble>(dbasis);
+	xDelete<IssmDouble>(xyz_list);
+	delete gauss;
+	return pe;
+
+}/*}}}*/
+ElementVector* EnthalpyAnalysis::CreatePVectorSheet(Element* element){/*{{{*/
+
+	/* Check if ice in element */
+	if(!element->IsIceInElement()) return NULL;
+
+	/* implementation of the basal condition decision chart of Aschwanden 2012, Fig.5 */
+	if(!element->IsOnBase() || element->IsFloating()) return NULL;
+
+	IssmDouble  dt,Jdet,enthalpy,pressure,watercolumn,geothermalflux,vx,vy,vz;
+	IssmDouble  enthalpyup,pressureup,alpha2,scalar,basalfriction,heatflux;
+	IssmDouble *xyz_list_base = NULL;
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Initialize vectors*/
+	ElementVector* pe    = element->NewElementVector();
+	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinatesBase(&xyz_list_base);
+	element->FindParam(&dt,TimesteppingTimeStepEnum);
+	Input* vx_input             = element->GetInput(VxEnum);                          _assert_(vx_input);
+	Input* vy_input             = element->GetInput(VyEnum);                          _assert_(vy_input);
+	Input* vz_input             = element->GetInput(VzEnum);                          _assert_(vz_input);
+	Input* enthalpy_input       = element->GetInput(EnthalpyPicardEnum);              _assert_(enthalpy_input);
+	Input* pressure_input       = element->GetInput(PressureEnum);                    _assert_(pressure_input);
+	Input* geothermalflux_input = element->GetInput(BasalforcingsGeothermalfluxEnum); _assert_(geothermalflux_input);
+	Input* watercolumn_input    = element->GetInput(WatercolumnEnum);                 _assert_(watercolumn_input);
+	IssmDouble  rho_ice             = element->GetMaterialParameter(MaterialsRhoIceEnum);
+	IssmDouble  heatcapacity        = element->GetMaterialParameter(MaterialsHeatcapacityEnum);
+
+	/*Build friction element, needed later: */
+	Friction* friction=new Friction(element,3);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss   = element->NewGaussBase(2);
+	Gauss* gaussup = element->NewGaussTop(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminantBase(&Jdet,xyz_list_base,gauss);
+		element->NodalFunctions(basis,gauss);
+
+		enthalpy_input->GetInputValue(&enthalpy,gauss);
+		pressure_input->GetInputValue(&pressure,gauss);
+		watercolumn_input->GetInputValue(&watercolumn,gauss);
+
+		if((watercolumn<=0.) && (enthalpy<PureIceEnthalpy(element,pressure))){
+			/* the above check is equivalent to 
+			 NOT [(watercolumn>0.) AND (enthalpy<PIE)] AND (enthalpy<PIE)*/
+			geothermalflux_input->GetInputValue(&geothermalflux,gauss);
+
+			friction->GetAlpha2(&alpha2,gauss,vx_input,vy_input,vz_input);
+			vx_input->GetInputValue(&vx,gauss);
+			vy_input->GetInputValue(&vy,gauss);
+			vz_input->GetInputValue(&vz,gauss);
+			basalfriction = alpha2*(vx*vx + vy*vy + vz*vz);
+			heatflux      = (basalfriction+geothermalflux)/(rho_ice);
+
+			scalar = gauss->weight*Jdet*heatflux;
+			if(dt!=0.) scalar=dt*scalar;
+
+			for(int i=0;i<numnodes;i++) pe->values[i]+=scalar*basis[i];
+		}
+		else if(enthalpy >= PureIceEnthalpy(element,pressure)){
+			/* check positive thickness of temperate basal ice layer */
+			enthalpy_input->GetInputValue(&enthalpyup,gaussup);
+			pressure_input->GetInputValue(&pressureup,gaussup);
+			if(enthalpyup >= PureIceEnthalpy(element,pressureup)){
+				// do nothing, set grad enthalpy*n=0.
+			}
+			else{
+				// only base temperate, set Dirichlet BCs in Penta::UpdateBasalConstraintsEnthalpy()
+			}
+		}
+		else{
+			// base cold, but watercolumn positive. Set base to pressure melting point enthalpy
+		}
+	}
+
+	/*Clean up and return*/
+	delete gauss;
+	delete gaussup;
+	delete friction;
+	xDelete<IssmDouble>(basis);
+	xDelete<IssmDouble>(xyz_list_base);
+	return pe;
+
+}/*}}}*/
+ElementVector* EnthalpyAnalysis::CreatePVectorShelf(Element* element){/*{{{*/
+
+	/* Check if ice in element */
+	if(!element->IsIceInElement()) return NULL;
+
+	/*Get basal element*/
+	if(!element->IsOnBase() || !element->IsFloating()) return NULL;
+
+	IssmDouble  h_pmp,dt,Jdet,scalar_ocean,pressure;
+	IssmDouble *xyz_list_base = NULL;
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Initialize vectors*/
+	ElementVector* pe    = element->NewElementVector();
+	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinatesBase(&xyz_list_base);
+	element->FindParam(&dt,TimesteppingTimeStepEnum);
+	Input*      pressure_input=element->GetInput(PressureEnum); _assert_(pressure_input);
+	IssmDouble  gravity             = element->GetMaterialParameter(ConstantsGEnum);
+	IssmDouble  rho_water           = element->GetMaterialParameter(MaterialsRhoWaterEnum);
+	IssmDouble  rho_ice             = element->GetMaterialParameter(MaterialsRhoIceEnum);
+	IssmDouble  heatcapacity        = element->GetMaterialParameter(MaterialsHeatcapacityEnum);
+	IssmDouble  mixed_layer_capacity= element->GetMaterialParameter(MaterialsMixedLayerCapacityEnum);
+	IssmDouble  thermal_exchange_vel= element->GetMaterialParameter(MaterialsThermalExchangeVelocityEnum);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGaussBase(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminantBase(&Jdet,xyz_list_base,gauss);
+		element->NodalFunctions(basis,gauss);
+
+		pressure_input->GetInputValue(&pressure,gauss);
+		h_pmp=element->PureIceEnthalpy(pressure);
+
+		scalar_ocean=gauss->weight*Jdet*rho_water*mixed_layer_capacity*thermal_exchange_vel*h_pmp/(heatcapacity*rho_ice);
+		if(reCast<bool,IssmDouble>(dt)) scalar_ocean=dt*scalar_ocean;
+
+		for(int i=0;i<numnodes;i++) pe->values[i]+=scalar_ocean*basis[i];
+	}
+
+	/*Clean up and return*/
+	delete gauss;
+	xDelete<IssmDouble>(basis);
+	xDelete<IssmDouble>(xyz_list_base);
+	return pe;
+}/*}}}*/
+void EnthalpyAnalysis::GetBConduct(IssmDouble* B,Element* element,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
+	/*Compute B  matrix. B=[B1 B2 B3 B4 B5 B6] where Bi is of size 5*NDOF1. 
+	 * For node i, Bi' can be expressed in the actual coordinate system
+	 * by: 
+	 *       Bi_conduct=[ dh/dx ]
+	 *                  [ dh/dy ]
+	 *                  [ dh/dz ]
+	 * where h is the interpolation function for node i.
+	 *
+	 * We assume B has been allocated already, of size: 3x(NDOF1*numnodes)
+	 */
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Get nodal functions derivatives*/
+	IssmDouble* dbasis=xNew<IssmDouble>(3*numnodes);
+	element->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+
+	/*Build B: */
+	for(int i=0;i<numnodes;i++){
+		B[numnodes*0+i] = dbasis[0*numnodes+i];
+		B[numnodes*1+i] = dbasis[1*numnodes+i];
+		B[numnodes*2+i] = dbasis[2*numnodes+i];
+	}
+
+	/*Clean-up*/
+	xDelete<IssmDouble>(dbasis);
+}/*}}}*/
+void EnthalpyAnalysis::GetBAdvec(IssmDouble* B,Element* element,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
+	/*Compute B  matrix. B=[B1 B2 B3 B4 B5 B6] where Bi is of size 5*NDOF1. 
+	 * For node i, Bi' can be expressed in the actual coordinate system
+	 * by: 
+	 *       Bi_advec =[ h ]
+	 *                 [ h ]
+	 *                 [ h ]
+	 * where h is the interpolation function for node i.
+	 *
+	 * We assume B has been allocated already, of size: 3x(NDOF1*NUMNODESP1)
+	 */
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Get nodal functions*/
+	IssmDouble* basis=xNew<IssmDouble>(numnodes);
+	element->NodalFunctions(basis,gauss);
+
+	/*Build B: */
+	for(int i=0;i<numnodes;i++){
+		B[numnodes*0+i] = basis[i];
+		B[numnodes*1+i] = basis[i];
+		B[numnodes*2+i] = basis[i];
+	}
+
+	/*Clean-up*/
+	xDelete<IssmDouble>(basis);
+}/*}}}*/
+void EnthalpyAnalysis::GetBAdvecprime(IssmDouble* B,Element* element,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
+	/*Compute B  matrix. B=[B1 B2 B3 B4 B5 B6] where Bi is of size 5*NDOF1. 
+	 * For node i, Bi' can be expressed in the actual coordinate system
+	 * by: 
+	 *       Biprime_advec=[ dh/dx ]
+	 *                     [ dh/dy ]
+	 *                     [ dh/dz ]
+	 * where h is the interpolation function for node i.
+	 *
+	 * We assume B has been allocated already, of size: 3x(NDOF1*numnodes)
+	 */
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Get nodal functions derivatives*/
+	IssmDouble* dbasis=xNew<IssmDouble>(3*numnodes);
+	element->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+
+	/*Build B: */
+	for(int i=0;i<numnodes;i++){
+		B[numnodes*0+i] = dbasis[0*numnodes+i];
+		B[numnodes*1+i] = dbasis[1*numnodes+i];
+		B[numnodes*2+i] = dbasis[2*numnodes+i];
+	}
+
+	/*Clean-up*/
+	xDelete<IssmDouble>(dbasis);
+}/*}}}*/
+void EnthalpyAnalysis::GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element){/*{{{*/
+	element->GetSolutionFromInputsOneDof(solution,EnthalpyEnum);
+}/*}}}*/
+void EnthalpyAnalysis::InputUpdateFromSolution(IssmDouble* solution,Element* element){/*{{{*/
+
+	bool        converged;
+	int         i,rheology_law;
+	IssmDouble  B_average,s_average,T_average=0.,P_average=0.;
+	int        *doflist   = NULL;
+	IssmDouble *xyz_list  = NULL;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes    = element->GetNumberOfNodes();
+
+	/*Fetch dof list and allocate solution vector*/
+	element->GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
+	IssmDouble* values        = xNew<IssmDouble>(numnodes);
+	IssmDouble* pressure      = xNew<IssmDouble>(numnodes);
+	IssmDouble* surface       = xNew<IssmDouble>(numnodes);
+	IssmDouble* B             = xNew<IssmDouble>(numnodes);
+	IssmDouble* temperature   = xNew<IssmDouble>(numnodes);
+	IssmDouble* waterfraction = xNew<IssmDouble>(numnodes);
+
+	/*Use the dof list to index into the solution vector: */
+	for(i=0;i<numnodes;i++){
+		values[i]=solution[doflist[i]];
+
+		/*Check solution*/
+		if(xIsNan<IssmDouble>(values[i])) _error_("NaN found in solution vector");
+	}
+
+	/*Get all inputs and parameters*/
+	element->GetInputValue(&converged,ConvergedEnum);
+	element->GetInputListOnNodes(&pressure[0],PressureEnum);
+	if(converged){
+		for(i=0;i<numnodes;i++){
+			element->EnthalpyToThermal(&temperature[i],&waterfraction[i],values[i],pressure[i]);
+			if(waterfraction[i]<0.) _error_("Negative water fraction found in solution vector");
+			//if(waterfraction[i]>1.) _error_("Water fraction >1 found in solution vector");
+		}
+		element->AddInput(EnthalpyEnum,values,element->GetElementType());
+		element->AddInput(WaterfractionEnum,waterfraction,element->GetElementType());
+		element->AddInput(TemperatureEnum,temperature,element->GetElementType());
+
+		/*Update Rheology only if converged (we must make sure that the temperature is below melting point
+		 * otherwise the rheology could be negative*/
+		element->FindParam(&rheology_law,MaterialsRheologyLawEnum);
+		element->GetInputListOnNodes(&surface[0],SurfaceEnum);
+		switch(rheology_law){
+			case NoneEnum:
+				/*Do nothing: B is not temperature dependent*/
+				break;
+			case CuffeyEnum:
+				for(i=0;i<numnodes;i++) B[i]=Cuffey(temperature[i]);
+				element->AddInput(MaterialsRheologyBEnum,&B[0],element->GetElementType());
+				break;
+			case PatersonEnum:
+				for(i=0;i<numnodes;i++) B[i]=Paterson(temperature[i]);
+				element->AddInput(MaterialsRheologyBEnum,&B[0],element->GetElementType());
+				break;
+			case ArrheniusEnum:
+				element->GetVerticesCoordinates(&xyz_list);
+				for(i=0;i<numnodes;i++) B[i]=Arrhenius(temperature[i],surface[i]-xyz_list[i*3+2],element->GetMaterialParameter(MaterialsRheologyNEnum));
+				element->AddInput(MaterialsRheologyBEnum,&B[0],element->GetElementType());
+				break;
+			case LliboutryDuvalEnum:
+				for(i=0;i<numnodes;i++) B[i]=LliboutryDuval(values[i],pressure[i],element->GetMaterialParameter(MaterialsRheologyNEnum),element->GetMaterialParameter(MaterialsBetaEnum),element->GetMaterialParameter(ConstantsReferencetemperatureEnum),element->GetMaterialParameter(MaterialsHeatcapacityEnum),element->GetMaterialParameter(MaterialsLatentheatEnum)); 
+				element->AddInput(MaterialsRheologyBEnum,&B[0],element->GetElementType()); 
+				break; 
+			default: _error_("Rheology law " << EnumToStringx(rheology_law) << " not supported yet");
+		}
+	}
+	else{
+		element->AddInput(EnthalpyPicardEnum,values,element->GetElementType());
+	}
+
+	/*Free ressources:*/
+	xDelete<IssmDouble>(values);
+	xDelete<IssmDouble>(pressure);
+	xDelete<IssmDouble>(surface);
+	xDelete<IssmDouble>(B);
+	xDelete<IssmDouble>(temperature);
+	xDelete<IssmDouble>(waterfraction);
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<int>(doflist);
+}/*}}}*/
+void EnthalpyAnalysis::UpdateConstraints(FemModel* femmodel){/*{{{*/
+
+	bool islevelset;
+	femmodel->parameters->FindParam(&islevelset,TransientIslevelsetEnum);
+	if(islevelset){
+		SetActiveNodesLSMx(femmodel);
+	}
+	return;
+}/*}}}*/
+
+/*Modules*/
+void EnthalpyAnalysis::PostProcessing(FemModel* femmodel){/*{{{*/
+
+	/*Intermediaries*/
+	int solution_type, i;
+	bool computebasalmeltingrates=true;
+	bool isdrainage=true;
+	bool updatebasalconstraints=true;
+
+	if(isdrainage){
+		/*Drain excess water fraction in ice column: */
+		for(i=0;i<femmodel->elements->Size();i++){
+			Element* element=dynamic_cast<Element*>(femmodel->elements->GetObjectByOffset(i));
+			DrainWaterfractionIcecolumn(element);
+		}
+	}
+
+	if(computebasalmeltingrates){
+		/*Compute basal melting rates: */
+		for(i=0;i<femmodel->elements->Size();i++){
+			Element* element=dynamic_cast<Element*>(femmodel->elements->GetObjectByOffset(i));
+			ComputeBasalMeltingrate(element);
+		}
+	}
+
+	if(updatebasalconstraints){
+		/*Update basal dirichlet BCs for enthalpy in transient runs: */
+		femmodel->parameters->FindParam(&solution_type,SolutionTypeEnum);
+		if(solution_type==TransientSolutionEnum){
+			for(i=0;i<femmodel->elements->Size();i++){
+				Element* element=dynamic_cast<Element*>(femmodel->elements->GetObjectByOffset(i));
+				UpdateBasalConstraints(element);
+			}
+		}
+	}
+}/*}}}*/
+void EnthalpyAnalysis::ComputeBasalMeltingrate(Element* element){/*{{{*/
+	/*Calculate the basal melt rates of the enthalpy model after Aschwanden 2012*/
+	/* melting rate is positive when melting, negative when refreezing*/
+
+	/* Check if ice in element */
+	if(!element->IsIceInElement()) return;
+
+	/* Only compute melt rates at the base of grounded ice*/
+	if(!element->IsOnBase() || element->IsFloating()) return;
+
+	/* Intermediaries */
+	const int   dim=3;
+	int         i,is,vertexdown,vertexup,numvertices,numsegments;
+	IssmDouble  heatflux;
+	IssmDouble  vec_heatflux[dim],normal_base[dim],d1enthalpy[dim];
+	IssmDouble  temperature, waterfraction;
+	IssmDouble  basalfriction,alpha2;
+	IssmDouble  dt,yts;
+	IssmDouble  melting_overshoot,lambda;
+	IssmDouble  geothermalflux;
+	IssmDouble  vx,vy,vz;
+	IssmDouble *xyz_list      = NULL;
+	IssmDouble *xyz_list_base = NULL;
+	int        *pairindices   = NULL;
+
+	/*Fetch parameters and inputs */
+	element->GetVerticesCoordinates(&xyz_list);
+	element->GetVerticesCoordinatesBase(&xyz_list_base);
+	IssmDouble latentheat = element->GetMaterialParameter(MaterialsLatentheatEnum);
+	IssmDouble rho_ice    = element->GetMaterialParameter(MaterialsRhoIceEnum);
+	IssmDouble rho_water  = element->GetMaterialParameter(MaterialsRhoWaterEnum);
+	Input* enthalpy_input         = element->GetInput(EnthalpyEnum);                    _assert_(enthalpy_input);
+	Input* geothermalflux_input   = element->GetInput(BasalforcingsGeothermalfluxEnum); _assert_(geothermalflux_input);
+	Input* vx_input               = element->GetInput(VxEnum);                          _assert_(vx_input);
+	Input* vy_input               = element->GetInput(VyEnum);                          _assert_(vy_input);
+	Input* vz_input               = element->GetInput(VzEnum);                          _assert_(vz_input);
+	IssmDouble kappa=EnthalpyDiffusionParameterVolume(element,EnthalpyEnum);     _assert_(kappa>=0.);
+	element->NormalBase(&normal_base[0],xyz_list_base);
+	element->VerticalSegmentIndices(&pairindices,&numsegments);
+	IssmDouble* meltingrate_enthalpy = xNew<IssmDouble>(numsegments);
+	IssmDouble* heating = xNew<IssmDouble>(numsegments);	
+
+	/*Build friction element, needed later: */
+	Friction* friction=new Friction(element,dim);
+
+	/******** MELTING RATES  ************************************/
+	numvertices=element->GetNumberOfVertices();
+	IssmDouble* enthalpy = xNew<IssmDouble>(numvertices);
+	IssmDouble* pressure = xNew<IssmDouble>(numvertices);
+	IssmDouble* watercolumn = xNew<IssmDouble>(numvertices);
+	IssmDouble* basalmeltingrate = xNew<IssmDouble>(numvertices);
+	element->GetInputListOnVertices(enthalpy,EnthalpyEnum);
+	element->GetInputListOnVertices(pressure,PressureEnum);
+	element->GetInputListOnVertices(watercolumn,WatercolumnEnum);
+	element->GetInputListOnVertices(basalmeltingrate,BasalforcingsMeltingRateEnum);
+
+	Gauss* gauss=element->NewGauss();
+	
+	for(int is=0;is<numsegments;is++){
+		vertexdown = pairindices[is*2+0];
+		vertexup   = pairindices[is*2+1];
+		gauss->GaussVertex(vertexdown);
+		
+		bool checkpositivethickness=true;
+		_assert_(watercolumn[vertexdown]>=0.);
+
+		/*Calculate basal meltingrate after Fig.5 of A.Aschwanden 2012*/
+		meltingrate_enthalpy[is]=0.;
+		heating[is]=0.;
+		if((watercolumn[vertexdown]>0.) && (enthalpy[vertexdown]<PureIceEnthalpy(element,pressure[vertexdown]))){
+			/*ensure that no ice is at T<Tm(p), if water layer present*/
+			enthalpy[vertexdown]=element->PureIceEnthalpy(pressure[vertexdown]); 
+		}
+		else if(enthalpy[vertexdown]<element->PureIceEnthalpy(pressure[vertexdown])){
+			/*cold base: set q*n=q_geo*n+frictionheating as Neumann BC in Penta::CreatePVectorEnthalpySheet*/
+			checkpositivethickness=false; // cold base, skip next test
+		}
+		else{/*we have a temperate base, go to next test*/}
+
+		if(checkpositivethickness){
+			/*From here on all basal ice is temperate. Check for positive thickness of layer of temperate ice. */
+			bool istemperatelayer=false;
+			if(enthalpy[vertexup]>=element->PureIceEnthalpy(pressure[vertexup])) istemperatelayer=true;
+			if(istemperatelayer) for(i=0;i<dim;i++) vec_heatflux[i]=0.; // TODO: add -k*nabla T_pmp
+			else{
+				enthalpy_input->GetInputDerivativeValue(&d1enthalpy[0],xyz_list,gauss);
+				for(i=0;i<3;i++) vec_heatflux[i]=-kappa*d1enthalpy[i];
+			}
+
+			/*heat flux along normal*/
+			heatflux=0.;
+			for(i=0;i<3;i++) heatflux+=(vec_heatflux[i])*normal_base[i];
+
+			/*basal friction*/
+			friction->GetAlpha2(&alpha2,gauss,vx_input,vy_input,vz_input);
+			vx_input->GetInputValue(&vx,gauss);
+			vy_input->GetInputValue(&vy,gauss);
+			vz_input->GetInputValue(&vz,gauss);
+			basalfriction=alpha2*(vx*vx + vy*vy + vz*vz);
+
+			element->EnthalpyToThermal(&temperature,&waterfraction,enthalpy[vertexdown],pressure[vertexdown]);
+			geothermalflux_input->GetInputValue(&geothermalflux,gauss);
+			/* -Mb= Fb-(q-q_geo)/((1-w)*L), cf Aschwanden 2012, eq.66*/
+			heating[is]=(heatflux+basalfriction+geothermalflux);
+			meltingrate_enthalpy[is]=heating[is]/((1-waterfraction)*latentheat*rho_water); // m/s water equivalent
+		}
+	}
+	/******** UPDATE MELTINGRATES AND WATERCOLUMN **************/
+	element->FindParam(&dt,TimesteppingTimeStepEnum);
+	for(is=0;is<numsegments;is++){
+		vertexdown = pairindices[is*2+0];
+		vertexup   = pairindices[is*2+1];
+		if(dt!=0.){
+			if(watercolumn[vertexdown]+meltingrate_enthalpy[is]*dt<0.){	// prevent too much freeze on			
+				lambda = -watercolumn[vertexdown]/(dt*meltingrate_enthalpy[is]); _assert_(lambda>=0.); _assert_(lambda<1.);
+				watercolumn[vertexdown]=0.;
+				basalmeltingrate[vertexdown]=lambda*meltingrate_enthalpy[is]; // restrict freeze on only to size of watercolumn
+				enthalpy[vertexdown]+=(1.-lambda)*meltingrate_enthalpy[is]*dt*latentheat; // use rest of energy to cool down base
+			}
+			else{
+				basalmeltingrate[vertexdown]=meltingrate_enthalpy[is];
+				watercolumn[vertexdown]+=dt*meltingrate_enthalpy[is]; 
+			}
+		}
+		else{
+			basalmeltingrate[vertexdown]=meltingrate_enthalpy[is];
+			watercolumn[vertexdown]+=meltingrate_enthalpy[is];
+		}	
+		basalmeltingrate[vertexdown]*=rho_water/rho_ice; // convert meltingrate from water to ice equivalent
+		_assert_(watercolumn[vertexdown]>=0.);
+	}
+
+	/*feed updated variables back into model*/
+	element->AddInput(EnthalpyEnum,enthalpy,P1Enum);
+	element->AddInput(WatercolumnEnum,watercolumn,P1Enum);
+	element->AddInput(BasalforcingsMeltingRateEnum,basalmeltingrate,P1Enum);
+
+	/*Clean up and return*/
+	delete gauss;
+	delete friction;
+	xDelete<IssmDouble>(enthalpy);
+	xDelete<IssmDouble>(pressure);
+	xDelete<IssmDouble>(watercolumn);
+	xDelete<IssmDouble>(basalmeltingrate);
+	xDelete<IssmDouble>(meltingrate_enthalpy);
+	xDelete<IssmDouble>(heating);
+	xDelete<IssmDouble>(xyz_list);
+}/*}}}*/
+void EnthalpyAnalysis::DrainWaterfractionIcecolumn(Element* element){/*{{{*/
+
+	/* Check if ice in element */
+	if(!element->IsIceInElement()) return;
+
+	/* Only drain waterfraction of ice column from element at base*/
+	if(!element->IsOnBase()) return; //FIXME: allow freeze on for floating elements
+
+	/* Intermediaries*/
+	int is, numvertices, numsegments;
+	int *pairindices   = NULL;
+
+	numvertices=element->GetNumberOfVertices();
+	element->VerticalSegmentIndices(&pairindices,&numsegments);
+
+	IssmDouble* watercolumn = xNew<IssmDouble>(numvertices);
+	IssmDouble* drainrate_column  = xNew<IssmDouble>(numsegments);
+	IssmDouble* drainrate_element = xNew<IssmDouble>(numsegments);
+
+	element->GetInputListOnVertices(watercolumn,WatercolumnEnum);
+
+	for(is=0;is<numsegments;is++)	drainrate_column[is]=0.;
+	Element* elementi = element;
+	for(;;){
+		for(is=0;is<numsegments;is++)	drainrate_element[is]=0.;
+		DrainWaterfraction(elementi,drainrate_element); // TODO: make sure every vertex is only drained once
+		for(is=0;is<numsegments;is++)	drainrate_column[is]+=drainrate_element[is];
+
+		if(elementi->IsOnSurface()) break;
+		elementi=elementi->GetUpperElement();			
+	}
+	/* add drained water to water column*/
+	for(is=0;is<numsegments;is++) watercolumn[is]+=drainrate_column[is];
+	/* Feed updated water column back into model */
+	element->AddInput(WatercolumnEnum,watercolumn,P1Enum);
+
+	xDelete<int>(pairindices);
+	xDelete<IssmDouble>(drainrate_column);
+	xDelete<IssmDouble>(drainrate_element);
+	xDelete<IssmDouble>(watercolumn);
+}/*}}}*/
+void EnthalpyAnalysis::DrainWaterfraction(Element* element, IssmDouble* pdrainrate_element){/*{{{*/
+
+	/* Check if ice in element */
+	if(!element->IsIceInElement()) return;
+
+	/*Intermediaries*/
+	int iv,is,vertexdown,vertexup,numsegments;	
+	IssmDouble dt, height_element;
+	IssmDouble rho_water, rho_ice;
+	int numvertices = element->GetNumberOfVertices();
+
+	IssmDouble* xyz_list = NULL;
+	IssmDouble* enthalpies = xNew<IssmDouble>(numvertices);
+	IssmDouble* pressures = xNew<IssmDouble>(numvertices);
+	IssmDouble* temperatures = xNew<IssmDouble>(numvertices);
+	IssmDouble* waterfractions = xNew<IssmDouble>(numvertices);
+	IssmDouble* deltawaterfractions = xNew<IssmDouble>(numvertices);
+	int        *pairindices   = NULL;
+	
+	rho_ice=element->GetMaterialParameter(MaterialsRhoIceEnum);
+	rho_water=element->GetMaterialParameter(MaterialsRhoWaterEnum);
+
+	element->GetVerticesCoordinates(&xyz_list);
+	element->GetInputListOnVertices(enthalpies,EnthalpyEnum);
+	element->GetInputListOnVertices(pressures,PressureEnum);
+
+	element->FindParam(&dt,TimesteppingTimeStepEnum);
+	for(iv=0;iv<numvertices;iv++){ 
+		element->EnthalpyToThermal(&temperatures[iv],&waterfractions[iv], enthalpies[iv],pressures[iv]); 
+		deltawaterfractions[iv]=DrainageFunctionWaterfraction(waterfractions[iv], dt);
+	}
+	
+	/*drain waterfraction, feed updated variables back into model*/
+	for(iv=0;iv<numvertices;iv++){
+		if(reCast<bool,IssmDouble>(dt))
+			waterfractions[iv]-=deltawaterfractions[iv]*dt;
+		else
+			waterfractions[iv]-=deltawaterfractions[iv];
+		element->ThermalToEnthalpy(&enthalpies[iv], temperatures[iv], waterfractions[iv], pressures[iv]);
+	}
+	element->AddInput(EnthalpyEnum,enthalpies,P1Enum);
+  	element->AddInput(WaterfractionEnum,waterfractions,P1Enum);
+
+	/*return meltwater column equivalent to drained water*/
+	element->VerticalSegmentIndices(&pairindices,&numsegments);
+	for(is=0;is<numsegments;is++){
+		vertexdown = pairindices[is*2+0];
+		vertexup   = pairindices[is*2+1];
+		height_element=fabs(xyz_list[vertexup*3+2]-xyz_list[vertexdown*3+2]);
+		pdrainrate_element[is]=(deltawaterfractions[vertexdown]+deltawaterfractions[vertexup])/2.*height_element; // return water equivalent of drainage
+		_assert_(pdrainrate_element[is]>=0.);
+	}
+
+	/*Clean up and return*/
+	xDelete<int>(pairindices);
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(enthalpies);
+	xDelete<IssmDouble>(pressures);
+	xDelete<IssmDouble>(temperatures);
+	xDelete<IssmDouble>(waterfractions);
+	xDelete<IssmDouble>(deltawaterfractions);
+}/*}}}*/
+void EnthalpyAnalysis::UpdateBasalConstraints(Element* element){/*{{{*/
+
+	/* Check if ice in element */
+	if(!element->IsIceInElement()) return;
+
+	/* Only update Constraints at the base of grounded ice*/
+	if(!(element->IsOnBase()) || element->IsFloating()) return;
+
+	/*Intermediary*/
+	bool        isdynamicbasalspc,setspc;
+	int         numindices, numindicesup;
+	IssmDouble  pressure, pressureup;
+	IssmDouble  h_pmp, enthalpy, enthalpyup;
+	IssmDouble  watercolumn;
+	int        *indices = NULL, *indicesup = NULL;
+	Node*       node = NULL;
+
+	/*Check wether dynamic basal boundary conditions are activated */
+	element->FindParam(&isdynamicbasalspc,ThermalIsdynamicbasalspcEnum);
+	if(!isdynamicbasalspc) return;
+
+	/*Fetch indices of basal & surface nodes for this finite element*/
+	Penta *penta =  (Penta *) element; // TODO: add Basal-/SurfaceNodeIndices to element.h, and change this to Element*
+	penta->BasalNodeIndices(&numindices,&indices,element->GetElementType());
+	penta->SurfaceNodeIndices(&numindicesup,&indicesup,element->GetElementType());
+	_assert_(numindices==numindicesup);
+
+	/*Get parameters and inputs: */
+	Input* pressure_input=element->GetInput(PressureEnum); _assert_(pressure_input);
+	Input* enthalpy_input=element->GetInput(EnthalpyEnum); _assert_(enthalpy_input);
+	Input* watercolumn_input=element->GetInput(WatercolumnEnum); _assert_(watercolumn_input);
+
+	/*if there is a temperate layer of zero thickness, set spc enthalpy=h_pmp at that node*/
+	GaussPenta* gauss=new GaussPenta();
+	GaussPenta* gaussup=new GaussPenta();
+	for(int i=0;i<numindices;i++){
+		gauss->GaussNode(element->GetElementType(),indices[i]);
+		gaussup->GaussNode(element->GetElementType(),indicesup[i]);
+
+		/*Check wether there is a temperate layer at the base or not */
+		/*check if node is temperate, else continue*/
+		enthalpy_input->GetInputValue(&enthalpy, gauss);
+		pressure_input->GetInputValue(&pressure, gauss);
+		watercolumn_input->GetInputValue(&watercolumn,gauss);
+		h_pmp=PureIceEnthalpy(element,pressure);
+		if (enthalpy>=h_pmp){
+			/*check if upper node is temperate, too.
+				if yes, then we have a temperate layer of positive thickness and reset the spc.
+				if not, apply dirichlet BC.*/
+			enthalpy_input->GetInputValue(&enthalpyup, gaussup);
+			pressure_input->GetInputValue(&pressureup, gaussup);
+			setspc=((enthalpyup<PureIceEnthalpy(element,pressureup)) && (watercolumn>=0.))?true:false;
+		}
+		else
+			setspc = false;
+
+		node=element->GetNode(indices[i]);
+		if(setspc) 
+			node->ApplyConstraint(0,h_pmp); /*apply spc*/ 
+		else			
+			node->DofInFSet(0); /*remove spc*/ 
+	}
+
+	/*Free ressources:*/
+	xDelete<int>(indices);
+	xDelete<int>(indicesup);
+	delete gauss;
+	delete gaussup;
+}/*}}}*/
+
+/*Intermediaries*/
+IssmDouble EnthalpyAnalysis::EnthalpyDiffusionParameter(Element* element,IssmDouble enthalpy,IssmDouble pressure){/*{{{*/
+
+	IssmDouble heatcapacity             = element->GetMaterialParameter(MaterialsHeatcapacityEnum);
+	IssmDouble temperateiceconductivity = element->GetMaterialParameter(MaterialsTemperateiceconductivityEnum);
+	IssmDouble thermalconductivity      = element->GetMaterialParameter(MaterialsThermalconductivityEnum);
+
+	if(enthalpy < PureIceEnthalpy(element,pressure)){
+		return thermalconductivity/heatcapacity;
+	}
+	else{
+		return temperateiceconductivity/heatcapacity;
+	}
+}/*}}}*/
+IssmDouble EnthalpyAnalysis::EnthalpyDiffusionParameterVolume(Element* element,int enthalpy_enum){/*{{{*/
+
+	int         iv;
+	IssmDouble  lambda;                   /* fraction of cold ice    */
+	IssmDouble  kappa,kappa_c,kappa_t; /* enthalpy conductivities */
+	IssmDouble  Hc,Ht;
+
+	/*Get pressures and enthalpies on vertices*/
+	int         numvertices = element->GetNumberOfVertices();
+	IssmDouble* pressures   = xNew<IssmDouble>(numvertices);
+	IssmDouble* enthalpies  = xNew<IssmDouble>(numvertices);
+	IssmDouble* PIE         = xNew<IssmDouble>(numvertices);
+	IssmDouble* dHpmp       = xNew<IssmDouble>(numvertices);
+	element->GetInputListOnVertices(pressures,PressureEnum);
+	element->GetInputListOnVertices(enthalpies,enthalpy_enum);
+	for(iv=0;iv<numvertices;iv++){
+		PIE[iv]   = PureIceEnthalpy(element,pressures[iv]);
+		dHpmp[iv] = enthalpies[iv]-PIE[iv];
+	}
+
+	bool allequalsign = true;
+	if(dHpmp[0]<0.){
+		for(iv=1; iv<numvertices;iv++) allequalsign=(allequalsign && (dHpmp[iv]<0.));
+	}
+	else{
+		for(iv=1; iv<numvertices;iv++) allequalsign=(allequalsign && (dHpmp[iv]>=0.));
+	}
+
+	if(allequalsign){
+		kappa = EnthalpyDiffusionParameter(element,enthalpies[0],pressures[0]);
+	}
+	else{
+		/* return harmonic mean of thermal conductivities, weighted by fraction of cold/temperate ice,
+			cf Patankar 1980, pp44 */
+		kappa_c = EnthalpyDiffusionParameter(element,PureIceEnthalpy(element,0.)-1.,0.);
+		kappa_t = EnthalpyDiffusionParameter(element,PureIceEnthalpy(element,0.)+1.,0.);
+		Hc=0.; Ht=0.;
+		for(iv=0; iv<numvertices;iv++){
+			if(enthalpies[iv]<PIE[iv])
+			 Hc+=(PIE[iv]-enthalpies[iv]);
+			else
+			 Ht+=(enthalpies[iv]-PIE[iv]);
+		}
+		_assert_((Hc+Ht)>0.);
+		lambda = Hc/(Hc+Ht);
+		kappa  = kappa_c*kappa_t/(lambda*kappa_t+(1.-lambda)*kappa_c); // ==(lambda/kappa_c + (1.-lambda)/kappa_t)^-1
+	}	
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(PIE);
+	xDelete<IssmDouble>(dHpmp);
+	xDelete<IssmDouble>(pressures);
+	xDelete<IssmDouble>(enthalpies);
+	return kappa;
+}/*}}}*/
+IssmDouble EnthalpyAnalysis::PureIceEnthalpy(Element* element,IssmDouble pressure){/*{{{*/
+
+	IssmDouble heatcapacity         = element->GetMaterialParameter(MaterialsHeatcapacityEnum);
+	IssmDouble referencetemperature = element->GetMaterialParameter(ConstantsReferencetemperatureEnum);
+
+	return heatcapacity*(TMeltingPoint(element,pressure)-referencetemperature);
+}/*}}}*/
+IssmDouble EnthalpyAnalysis::TMeltingPoint(Element* element,IssmDouble pressure){/*{{{*/
+
+	IssmDouble meltingpoint = element->GetMaterialParameter(MaterialsMeltingpointEnum);
+	IssmDouble beta         = element->GetMaterialParameter(MaterialsBetaEnum);
+
+	return meltingpoint-beta*pressure;
+}/*}}}*/
Index: /issm/trunk/src/c/analyses/EnthalpyAnalysis.h
===================================================================
--- /issm/trunk/src/c/analyses/EnthalpyAnalysis.h	(revision 17805)
+++ /issm/trunk/src/c/analyses/EnthalpyAnalysis.h	(revision 17806)
@@ -12,5 +12,6 @@
 
 	public:
-		int  DofsPerNode(int** doflist,int meshtype,int approximation);
+		/*Model processing*/
+		int  DofsPerNode(int** doflist,int domaintype,int approximation);
 		void UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum);
 		void UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);
@@ -18,4 +19,35 @@
 		void CreateConstraints(Constraints* constraints,IoModel* iomodel);
 		void CreateLoads(Loads* loads, IoModel* iomodel);
+
+		/*Finite element Analysis*/
+		void           Core(FemModel* femmodel);
+		ElementVector* CreateDVector(Element* element);
+		ElementMatrix* CreateJacobianMatrix(Element* element);
+		ElementMatrix* CreateKMatrix(Element* element);
+		ElementMatrix* CreateKMatrixVolume(Element* element);
+		ElementMatrix* CreateKMatrixShelf(Element* element);
+		ElementVector* CreatePVector(Element* element);
+		ElementVector* CreatePVectorVolume(Element* element);
+		ElementVector* CreatePVectorSheet(Element* element);
+		ElementVector* CreatePVectorShelf(Element* element);
+		void GetBConduct(IssmDouble* B,Element* element,IssmDouble* xyz_list,Gauss* gauss);
+		void GetBAdvec(IssmDouble* B,Element* element,IssmDouble* xyz_list,Gauss* gauss);
+		void GetBAdvecprime(IssmDouble* B,Element* element,IssmDouble* xyz_list,Gauss* gauss);
+		void GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element);
+		void InputUpdateFromSolution(IssmDouble* solution,Element* element);
+		void UpdateConstraints(FemModel* femmodel);
+
+		/*Modules*/
+		static void PostProcessing(FemModel* femmodel);
+		static void ComputeBasalMeltingrate(Element* element);
+		static void DrainWaterfractionIcecolumn(Element* element);
+		static void DrainWaterfraction(Element* element, IssmDouble* pdrainrate_element);
+		static void UpdateBasalConstraints(Element* element);
+
+		/*Intermediaries*/
+		static IssmDouble EnthalpyDiffusionParameter(Element* element,IssmDouble enthalpy,IssmDouble pressure);
+		static IssmDouble EnthalpyDiffusionParameterVolume(Element* element,int enthalpy_enum);
+		static IssmDouble PureIceEnthalpy(Element* element,IssmDouble pressure);
+		static IssmDouble TMeltingPoint(Element* element,IssmDouble pressure);
 };
 #endif
Index: /issm/trunk/src/c/analyses/EnumToAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/EnumToAnalysis.cpp	(revision 17805)
+++ /issm/trunk/src/c/analyses/EnumToAnalysis.cpp	(revision 17806)
@@ -14,25 +14,79 @@
 
 	switch(analysis_enum){
+		#ifdef _HAVE_ADJOINTBALANCETHICKNESS_
 		case AdjointBalancethicknessAnalysisEnum : return new AdjointBalancethicknessAnalysis();
+		#endif
+		#ifdef _HAVE_ADJOINTHORIZ_
 		case AdjointHorizAnalysisEnum : return new AdjointHorizAnalysis();
+		#endif
+		#ifdef _HAVE_BALANCETHICKNESS_
 		case BalancethicknessAnalysisEnum : return new BalancethicknessAnalysis();
+		#endif
+		#ifdef _HAVE_BALANCETHICKNESSSOFT_
 		case BalancethicknessSoftAnalysisEnum : return new BalancethicknessSoftAnalysis();
+		#endif
+		#ifdef _HAVE_BALANCEVELOCITY_
 		case BalancevelocityAnalysisEnum : return new BalancevelocityAnalysis();
+		#endif
+		#ifdef _HAVE_L2PROJECTIONEPL_
+		case L2ProjectionEPLAnalysisEnum : return new L2ProjectionEPLAnalysis();
+		#endif
+		#ifdef _HAVE_L2PROJECTIONBASE_
 		case L2ProjectionBaseAnalysisEnum : return new L2ProjectionBaseAnalysis();
+		#endif
+		#ifdef _HAVE_DAMAGEEVOLUTION_
 		case DamageEvolutionAnalysisEnum : return new DamageEvolutionAnalysis();
+		#endif
+		#ifdef _HAVE_STRESSBALANCE_
 		case StressbalanceAnalysisEnum : return new StressbalanceAnalysis();
+		#endif
+		#ifdef _HAVE_STRESSBALANCESIA_
 		case StressbalanceSIAAnalysisEnum : return new StressbalanceSIAAnalysis();
+		#endif
+		#ifdef _HAVE_STRESSBALANCEVERTICAL_
 		case StressbalanceVerticalAnalysisEnum : return new StressbalanceVerticalAnalysis();
+		#endif
+		#ifdef _HAVE_ENTHALPY_
 		case EnthalpyAnalysisEnum : return new EnthalpyAnalysis();
+		#endif
+		#ifdef _HAVE_HYDROLOGYSHREVE_
 		case HydrologyShreveAnalysisEnum : return new HydrologyShreveAnalysis();
+		#endif
+		#ifdef _HAVE_HYDROLOGYDCINEFFICIENT_
 		case HydrologyDCInefficientAnalysisEnum : return new HydrologyDCInefficientAnalysis();
+		#endif
+		#ifdef _HAVE_HYDROLOGYDCEFFICIENT_
 		case HydrologyDCEfficientAnalysisEnum : return new HydrologyDCEfficientAnalysis();
+		#endif
+		#ifdef _HAVE_MELTING_
 		case MeltingAnalysisEnum : return new MeltingAnalysis();
+		#endif
+		#ifdef _HAVE_MASSTRANSPORT_
 		case MasstransportAnalysisEnum : return new MasstransportAnalysis();
+		#endif
+		#ifdef _HAVE_FREESURFACEBASE_
 		case FreeSurfaceBaseAnalysisEnum : return new FreeSurfaceBaseAnalysis();
+		#endif
+		#ifdef _HAVE_FREESURFACETOP_
 		case FreeSurfaceTopAnalysisEnum : return new FreeSurfaceTopAnalysis();
+		#endif
+		#ifdef _HAVE_EXTRUDEFROMBASE_
 		case ExtrudeFromBaseAnalysisEnum : return new ExtrudeFromBaseAnalysis();
+		#endif
+		#ifdef _HAVE_EXTRUDEFROMTOP_
 		case ExtrudeFromTopAnalysisEnum : return new ExtrudeFromTopAnalysis();
+		#endif
+		#ifdef _HAVE_DEPTHAVERAGE_
+		case DepthAverageAnalysisEnum : return new DepthAverageAnalysis();
+		#endif
+		#ifdef _HAVE_SMOOTHEDSURFACESLOPEX_
+		case SmoothedSurfaceSlopeXAnalysisEnum : return new SmoothedSurfaceSlopeXAnalysis();
+		#endif
+		#ifdef _HAVE_SMOOTHEDSURFACESLOPEY_
+		case SmoothedSurfaceSlopeYAnalysisEnum : return new SmoothedSurfaceSlopeYAnalysis();
+		#endif
+		#ifdef _HAVE_THERMAL_
 		case ThermalAnalysisEnum : return new ThermalAnalysis();
+		#endif
 		#ifdef _HAVE_GIA_
 		case GiaAnalysisEnum : return new GiaAnalysis();
@@ -41,6 +95,13 @@
 		case MeshdeformationAnalysisEnum : return new MeshdeformationAnalysis();
 		#endif
-		case SmoothedSurfaceSlopeXAnalysisEnum: return new SmoothedSurfaceSlopeXAnalysis();
-		case SmoothedSurfaceSlopeYAnalysisEnum: return new SmoothedSurfaceSlopeYAnalysis();
+		#ifdef _HAVE_LEVELSET_
+		case LevelsetAnalysisEnum : return new LevelsetAnalysis();
+		#endif
+		#ifdef _HAVE_EXTRAPOLATION_
+		case ExtrapolationAnalysisEnum : return new ExtrapolationAnalysis();
+		#endif
+		#ifdef _HAVE_LSFREINITIALIZATION_
+		case LsfReinitializationAnalysisEnum : return new LsfReinitializationAnalysis();
+		#endif
 		default : _error_("enum provided not supported ("<<EnumToStringx(analysis_enum)<<")");
 	}
Index: /issm/trunk/src/c/analyses/EnumToAnalysis.h
===================================================================
--- /issm/trunk/src/c/analyses/EnumToAnalysis.h	(revision 17805)
+++ /issm/trunk/src/c/analyses/EnumToAnalysis.h	(revision 17806)
@@ -7,5 +7,6 @@
 
 #endif
-		int  DofsPerNode(int** doflist,int meshtype,int approximation);
+		/*Model processing*/
+		int  DofsPerNode(int** doflist,int domaintype,int approximation);
 		void UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum);
 		void UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);
@@ -13,2 +14,12 @@
 		void CreateConstraints(Constraints* constraints,IoModel* iomodel);
 		void CreateLoads(Loads* loads, IoModel* iomodel);
+
+		/*Finite element Analysis*/
+		void           Core(FemModel* femmodel);
+		ElementVector* CreateDVector(Element* element);
+		ElementMatrix* CreateJacobianMatrix(Element* element);
+		ElementMatrix* CreateKMatrix(Element* element);
+		ElementVector* CreatePVector(Element* element);
+		void GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element);
+		void InputUpdateFromSolution(IssmDouble* solution,Element* element);
+		void UpdateConstraints(FemModel* femmodel);
Index: /issm/trunk/src/c/analyses/ExtrapolationAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/ExtrapolationAnalysis.cpp	(revision 17806)
+++ /issm/trunk/src/c/analyses/ExtrapolationAnalysis.cpp	(revision 17806)
@@ -0,0 +1,352 @@
+#include "./ExtrapolationAnalysis.h"
+#include "../toolkits/toolkits.h"
+#include "../classes/classes.h"
+#include "../shared/shared.h"
+#include "../modules/modules.h"
+#include "../solutionsequences/solutionsequences.h"
+
+int ExtrapolationAnalysis::DofsPerNode(int** doflist,int domaintype,int approximation){/*{{{*/
+	return 1;
+}
+/*}}}*/
+void ExtrapolationAnalysis::UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum){/*{{{*/
+	//do nothing for now
+	return;
+}
+/*}}}*/
+void ExtrapolationAnalysis::UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type){/*{{{*/
+	int    finiteelement;
+
+	/*Finite element type*/
+	finiteelement = P1Enum;
+
+	/*Update elements: */
+	int counter=0;
+	for(int i=0;i<iomodel->numberofelements;i++){
+		if(iomodel->my_elements[i]){
+			Element* element=(Element*)elements->GetObjectByOffset(counter);
+			element->Update(i,iomodel,analysis_counter,analysis_type,finiteelement);
+			counter++;
+		}
+	}
+	if(iomodel->domaintype==Domain3DEnum){
+		iomodel->FetchDataToInput(elements,MeshElementonbaseEnum);
+		iomodel->FetchDataToInput(elements,MeshElementonsurfaceEnum);
+	}
+}
+/*}}}*/
+void ExtrapolationAnalysis::CreateNodes(Nodes* nodes,IoModel* iomodel){/*{{{*/
+	int finiteelement=P1Enum;
+	if(iomodel->domaintype!=Domain2DhorizontalEnum) iomodel->FetchData(2,MeshVertexonbaseEnum,MeshVertexonsurfaceEnum);
+	::CreateNodes(nodes,iomodel,ExtrapolationAnalysisEnum,finiteelement);
+	iomodel->DeleteData(2,MeshVertexonbaseEnum,MeshVertexonsurfaceEnum);
+}
+/*}}}*/
+void ExtrapolationAnalysis::CreateConstraints(Constraints* constraints,IoModel* iomodel){/*{{{*/
+	// do nothing for now
+	return;
+}
+/*}}}*/
+void ExtrapolationAnalysis::CreateLoads(Loads* loads, IoModel* iomodel){/*{{{*/
+	//	do nothing for now
+	return;
+}/*}}}*/
+
+/*Finite element Analysis*/
+void ExtrapolationAnalysis::Core(FemModel* femmodel){/*{{{*/
+
+	/* Intermediaries */
+	bool save_results;
+	int extvar_enum; 
+   femmodel->parameters->FindParam(&extvar_enum, ExtrapolationVariableEnum);
+
+	/*activate formulation: */
+	femmodel->SetCurrentConfiguration(ExtrapolationAnalysisEnum);
+
+	if(VerboseSolution()) _printf0_("extrapolation of " << EnumToStringx(extvar_enum) << ": call computational core:\n");
+	solutionsequence_linear(femmodel);
+
+	save_results=true;
+	if(save_results){
+		if(VerboseSolution()) _printf0_("   saving results\n");
+		int outputs[2] = {VxEnum,VyEnum};
+		femmodel->RequestedOutputsx(&femmodel->results,&outputs[0],2);
+	}
+}/*}}}*/
+ElementVector* ExtrapolationAnalysis::CreateDVector(Element* element){/*{{{*/
+	/*Default, return NULL*/
+	return NULL;
+}/*}}}*/
+ElementMatrix* ExtrapolationAnalysis::CreateJacobianMatrix(Element* element){/*{{{*/
+	/* Jacobian required for the Newton solver */
+	_error_("not implemented yet");
+}/*}}}*/
+ElementMatrix* ExtrapolationAnalysis::CreateKMatrix(Element* element){/*{{{*/
+
+	if(!element->IsOnBase()) return NULL;
+	Element* basalelement = element->SpawnBasalElement();
+
+	/*Intermediaries */
+	int		   domaintype,dim;
+	int        i,row,col,stabilization;
+	bool	   extrapolatebydiffusion = true;
+	IssmDouble Jdet,D_scalar,h;
+	IssmDouble norm_dlsf;
+	IssmDouble hx,hy,hz,kappa;
+	IssmDouble* xyz_list = NULL;
+
+	/*Get problem dimension*/
+	basalelement->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DverticalEnum:   dim = 1; break;
+		case Domain2DhorizontalEnum: dim = 2; break;
+		case Domain3DEnum:           dim = 2; break;
+		default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
+	}
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = basalelement->GetNumberOfNodes();
+
+	/*Initialize Element vector and other vectors*/
+	ElementMatrix* Ke     = basalelement->NewElementMatrix();
+	IssmDouble*    B      = xNew<IssmDouble>(dim*numnodes);
+	IssmDouble*    Bprime = xNew<IssmDouble>(dim*numnodes);
+	IssmDouble*		D	  = xNew<IssmDouble>(dim*dim);
+	IssmDouble*		dlsf  = xNew<IssmDouble>(dim);
+	IssmDouble*		normal= xNew<IssmDouble>(dim);
+
+	/*Retrieve all inputs and parameters*/
+	Input* lsf_slopex_input=basalelement->GetInput(LevelsetfunctionSlopeXEnum); _assert_(lsf_slopex_input);
+	Input* lsf_slopey_input=basalelement->GetInput(LevelsetfunctionSlopeYEnum); _assert_(lsf_slopey_input);
+	basalelement->GetVerticesCoordinates(&xyz_list);
+	h = basalelement->CharacteristicLength();
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=basalelement->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){/*{{{*/
+		gauss->GaussPoint(ig);
+
+		basalelement->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		GetB(B,basalelement,xyz_list,gauss);
+		GetBprime(Bprime,basalelement,xyz_list,gauss);
+		
+		D_scalar=gauss->weight*Jdet;
+
+		if(extrapolatebydiffusion){
+			/* diffuse values outward */
+			for(row=0;row<dim;row++)
+				for(col=0;col<dim;col++)
+					if(row==col)
+						D[row*dim+col] = D_scalar;
+					else
+						D[row*dim+col] = 0.;
+
+			TripleMultiply(Bprime,dim,numnodes,1,
+					D,dim,dim,0,
+					Bprime,dim,numnodes,0,
+					&Ke->values[0],1);
+		}
+		else{
+			/* extrapolate values along normal */
+			/* Get normal on ice boundary */
+			lsf_slopex_input->GetInputValue(&dlsf[0],gauss);
+			lsf_slopey_input->GetInputValue(&dlsf[1],gauss);
+			norm_dlsf=0.;
+			for(i=0;i<dim;i++)	norm_dlsf+=dlsf[i]*dlsf[i]; 
+			norm_dlsf=sqrt(norm_dlsf); _assert_(norm_dlsf>0.);
+
+			if(norm_dlsf>0.)
+				for(i=0;i<dim;i++)	normal[i]=dlsf[i]/norm_dlsf;
+			else
+				for(i=0;i<dim;i++)	normal[i]=0.;
+			
+			for(row=0;row<dim;row++)
+				for(col=0;col<dim;col++)
+					if(row==col)
+						D[row*dim+col]=D_scalar*normal[row];
+					else
+						D[row*dim+col]=0.;
+			TripleMultiply(B,dim,numnodes,1,
+						D,dim,dim,0,
+						Bprime,dim,numnodes,0,
+						&Ke->values[0],1);
+
+			/* Stabilization *//*{{{*/
+			stabilization=1;
+			if (stabilization==0){/* no stabilization, do nothing*/}
+			else if(stabilization==1){
+				/* Artificial Diffusion */
+				basalelement->ElementSizes(&hx,&hy,&hz);
+				h=sqrt( pow(hx*normal[0],2) + pow(hy*normal[1],2));
+				kappa=h/2.+1.e-14; 
+				for(row=0;row<dim;row++)
+					for(col=0;col<dim;col++)
+						if(row==col)
+							D[row*dim+col]=D_scalar*kappa;
+						else
+							D[row*dim+col]=0.;
+				TripleMultiply(Bprime,dim,numnodes,1,
+							D,dim,dim,0,
+							Bprime,dim,numnodes,0,
+							&Ke->values[0],1);
+			}
+			else if(stabilization==2){
+				/*Streamline upwinding - do not use this for extrapolation: yields oscillating results due to smoothing along normal, not across */
+				for(row=0;row<dim;row++)
+					for(col=0;col<dim;col++)
+						D[row*dim+col]=h/(2.*1.)*normal[row]*normal[col];
+
+				TripleMultiply(Bprime,dim,numnodes,1,
+							D,dim,dim,0,
+							Bprime,dim,numnodes,0,
+							&Ke->values[0],1);
+			}/*}}}*/
+		}
+	}/*}}}*/
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(B);
+	xDelete<IssmDouble>(Bprime);
+	xDelete<IssmDouble>(D);
+	xDelete<IssmDouble>(dlsf);
+	xDelete<IssmDouble>(normal);
+	delete gauss;
+	if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;};
+	return Ke;
+
+}/*}}}*/
+ElementVector* ExtrapolationAnalysis::CreatePVector(Element* element){/*{{{*/
+
+	if(!element->IsOnBase()) return NULL;
+	Element* basalelement = element->SpawnBasalElement();
+
+	/*Intermediaries */
+	int i, domaintype;
+	
+	/*Fetch number of nodes */
+	int numnodes = basalelement->GetNumberOfNodes();
+
+	/*Initialize Element vector*/
+	ElementVector* pe = basalelement->NewElementVector();
+	for(i=0;i<numnodes;i++) 
+		pe->values[i]=0.; 
+
+	basalelement->FindParam(&domaintype,DomainTypeEnum);
+	if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;};
+	return pe;
+}/*}}}*/
+void ExtrapolationAnalysis::GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element){/*{{{*/
+	_error_("not implemented yet");
+}/*}}}*/
+void ExtrapolationAnalysis::InputUpdateFromSolution(IssmDouble* solution,Element* element){/*{{{*/
+
+	int domaintype, extrapolationvariable;
+	element->FindParam(&domaintype,DomainTypeEnum);
+	element->FindParam(&extrapolationvariable, ExtrapolationVariableEnum);
+	switch(domaintype){
+		case Domain2DhorizontalEnum:
+			element->InputUpdateFromSolutionOneDof(solution,extrapolationvariable);
+			break;
+		case Domain3DEnum:
+			element->InputUpdateFromSolutionOneDofCollapsed(solution,extrapolationvariable);
+			break;
+		default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
+	}
+}/*}}}*/
+void ExtrapolationAnalysis::GetB(IssmDouble* B,Element* element,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
+	/*Compute B  matrix. B=[B1 B2 B3] where Bi is of size 3*NDOF2. 
+	 * For node i, Bi can be expressed in the actual coordinate system
+	 * by: 
+	 *       Bi=[ N ]
+	 *          [ N ]
+	 * where N is the finiteelement function for node i.
+	 *
+	 * We assume B_prog has been allocated already, of size: 2x(NDOF1*numnodes)
+	 */
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Get nodal functions*/
+	IssmDouble* basis=xNew<IssmDouble>(numnodes);
+	element->NodalFunctions(basis,gauss);
+
+	/*Build B: */
+	for(int i=0;i<numnodes;i++){
+		B[numnodes*0+i] = basis[i];
+		B[numnodes*1+i] = basis[i];
+	}
+
+	/*Clean-up*/
+	xDelete<IssmDouble>(basis);
+}/*}}}*/
+void ExtrapolationAnalysis::GetBprime(IssmDouble* Bprime,Element* element,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
+	/*Compute B'  matrix. B'=[B1' B2' B3'] where Bi' is of size 3*NDOF2. 
+	 * For node i, Bi' can be expressed in the actual coordinate system
+	 * by: 
+	 *       Bi_prime=[ dN/dx ]
+	 *                [ dN/dy ]
+	 * where N is the finiteelement function for node i.
+	 *
+	 * We assume B' has been allocated already, of size: 3x(NDOF2*numnodes)
+	 */
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Get nodal functions derivatives*/
+	IssmDouble* dbasis=xNew<IssmDouble>(2*numnodes);
+	element->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+
+	/*Build B': */
+	for(int i=0;i<numnodes;i++){
+		Bprime[numnodes*0+i] = dbasis[0*numnodes+i];
+		Bprime[numnodes*1+i] = dbasis[1*numnodes+i];
+	}
+
+	/*Clean-up*/
+	xDelete<IssmDouble>(dbasis);
+
+}/*}}}*/
+void ExtrapolationAnalysis::SetConstraintsOnIce(Element* element){/*{{{*/
+
+	int numnodes=element->GetNumberOfNodes();	
+
+	/* Intermediaries */
+	int extvar_enum;
+	IssmDouble phi,value;
+	Node* node = NULL;
+
+	/* Get parameters */
+	element->FindParam(&extvar_enum, ExtrapolationVariableEnum);
+	
+	Input* levelset_input=element->GetInput(MaskIceLevelsetEnum); _assert_(levelset_input);
+	Input* extvar_input=element->GetInput(extvar_enum); _assert_(extvar_input);
+
+	Gauss* gauss=element->NewGauss();
+	for(int in=0;in<numnodes;in++){
+		gauss->GaussNode(element->GetElementType(),in);
+		node=element->GetNode(in);
+		levelset_input->GetInputValue(&phi,gauss);
+		if(node->IsActive()){
+			if(phi<=0.){
+				/* if ice, set dirichlet BC */
+				extvar_input->GetInputValue(&value,gauss);
+				node->ApplyConstraint(0,value);
+			}
+			else {
+				/* no ice, set no spc */
+				node->DofInFSet(0); 
+			}
+		}
+	}
+	delete gauss;
+}/*}}}*/
+void ExtrapolationAnalysis::UpdateConstraints(FemModel* femmodel){/*{{{*/
+
+	for(int i=0;i<femmodel->elements->Size();i++){
+		Element* element=dynamic_cast<Element*>(femmodel->elements->GetObjectByOffset(i));
+		this->SetConstraintsOnIce(element);
+	}
+}/*}}}*/
Index: /issm/trunk/src/c/analyses/ExtrapolationAnalysis.h
===================================================================
--- /issm/trunk/src/c/analyses/ExtrapolationAnalysis.h	(revision 17806)
+++ /issm/trunk/src/c/analyses/ExtrapolationAnalysis.h	(revision 17806)
@@ -0,0 +1,35 @@
+/*! \file ExtrapolationAnalysis.h 
+ *  \brief: header file for generic external result object
+ */
+
+#ifndef _ExtrapolationAnalysis_
+#define _ExtrapolationAnalysis_
+
+/*Headers*/
+#include "./Analysis.h"
+
+class ExtrapolationAnalysis: public Analysis{
+	
+ public:
+	/*Model processing*/
+	int  DofsPerNode(int** doflist,int domaintype,int approximation);
+	void UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum);
+	void UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);
+	void CreateNodes(Nodes* nodes,IoModel* iomodel);
+	void CreateConstraints(Constraints* constraints,IoModel* iomodel);
+	void CreateLoads(Loads* loads, IoModel* iomodel);
+
+	/*Finite element Analysis*/
+	void           Core(FemModel* femmodel);
+	ElementVector* CreateDVector(Element* element);
+	ElementMatrix* CreateJacobianMatrix(Element* element);
+	ElementMatrix* CreateKMatrix(Element* element);
+	ElementVector* CreatePVector(Element* element);
+	void GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element);
+	void InputUpdateFromSolution(IssmDouble* solution,Element* element);
+	void UpdateConstraints(FemModel* femmodel);
+	void GetB(IssmDouble* B,Element* element,IssmDouble* xyz_list,Gauss* gauss);
+	void GetBprime(IssmDouble* Bprime,Element* element,IssmDouble* xyz_list,Gauss* gauss);
+	void SetConstraintsOnIce(Element* element);
+};
+#endif
Index: /issm/trunk/src/c/analyses/ExtrudeFromBaseAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/ExtrudeFromBaseAnalysis.cpp	(revision 17805)
+++ /issm/trunk/src/c/analyses/ExtrudeFromBaseAnalysis.cpp	(revision 17806)
@@ -6,5 +6,5 @@
 
 /*Model processing*/
-int  ExtrudeFromBaseAnalysis::DofsPerNode(int** doflist,int meshtype,int approximation){/*{{{*/
+int  ExtrudeFromBaseAnalysis::DofsPerNode(int** doflist,int domaintype,int approximation){/*{{{*/
 	return 1;
 }/*}}}*/
@@ -22,6 +22,6 @@
 	}
 
-	if(iomodel->meshtype==Mesh2DverticalEnum){
-		iomodel->FetchDataToInput(elements,MeshVertexonbedEnum);
+	if(iomodel->domaintype==Domain2DverticalEnum){
+		iomodel->FetchDataToInput(elements,MeshVertexonbaseEnum);
 	}
 }/*}}}*/
@@ -35,2 +35,199 @@
 void ExtrudeFromBaseAnalysis::CreateLoads(Loads* loads, IoModel* iomodel){/*{{{*/
 }/*}}}*/
+
+/*Finite Element Analysis*/
+void           ExtrudeFromBaseAnalysis::Core(FemModel* femmodel){/*{{{*/
+	_error_("not implemented");
+}/*}}}*/
+ElementVector* ExtrudeFromBaseAnalysis::CreateDVector(Element* element){/*{{{*/
+	/*Default, return NULL*/
+	return NULL;
+}/*}}}*/
+ElementMatrix* ExtrudeFromBaseAnalysis::CreateJacobianMatrix(Element* element){/*{{{*/
+_error_("Not implemented");
+}/*}}}*/
+ElementMatrix* ExtrudeFromBaseAnalysis::CreateKMatrix(Element* element){/*{{{*/
+
+	/*compute all stiffness matrices for this element*/
+	ElementMatrix* Ke1=CreateKMatrixVolume(element);
+	ElementMatrix* Ke2=CreateKMatrixSurface(element);
+	ElementMatrix* Ke3=CreateKMatrixBed(element);
+	ElementMatrix* Ke =new ElementMatrix(Ke1,Ke2,Ke3);
+
+	/*clean-up and return*/
+	delete Ke1;
+	delete Ke2;
+	delete Ke3;
+	return Ke;
+}/*}}}*/
+ElementMatrix* ExtrudeFromBaseAnalysis::CreateKMatrixVolume(Element* element){/*{{{*/
+
+	/*Intermediaries */
+	IssmDouble  Jdet,D;
+	IssmDouble *xyz_list = NULL;
+
+	/*Get dimension*/
+	int dim;
+	element->FindParam(&dim,DomainDimensionEnum);
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Initialize Element vector and other vectors*/
+	ElementMatrix* Ke     = element->NewElementMatrix();
+	IssmDouble*    B      = xNew<IssmDouble>(numnodes);
+	IssmDouble*    Bprime = xNew<IssmDouble>(numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		element->NodalFunctions(Bprime,gauss);
+		GetB(B,element,dim,xyz_list,gauss);
+		D=gauss->weight*Jdet;
+
+		TripleMultiply(B,1,numnodes,1,
+					&D,1,1,0,
+					Bprime,1,numnodes,0,
+					&Ke->values[0],1);
+	} 
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(B);
+	xDelete<IssmDouble>(Bprime);
+	delete gauss;
+	return Ke;
+}
+/*}}}*/
+ElementMatrix* ExtrudeFromBaseAnalysis::CreateKMatrixSurface(Element* element){/*{{{*/
+
+	if(!element->IsOnSurface()) return NULL;
+
+	/*Intermediaries */
+	int         dim;
+	IssmDouble  Jdet,D,normal[3];
+	IssmDouble *xyz_list_top = NULL;
+
+	/*Get dimension*/
+	element->FindParam(&dim,DomainDimensionEnum);
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Initialize Element vector and other vectors*/
+	ElementMatrix* Ke    = element->NewElementMatrix();
+	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinatesTop(&xyz_list_top);
+	element->NormalTop(&normal[0],xyz_list_top);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGaussTop(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminantTop(&Jdet,xyz_list_top,gauss);
+		element->NodalFunctions(basis,gauss);
+		D = - gauss->weight*Jdet*normal[dim-1]; 
+
+		TripleMultiply(basis,1,numnodes,1,
+					&D,1,1,0,
+					basis,1,numnodes,0,
+					&Ke->values[0],1);
+	}
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(xyz_list_top);
+	xDelete<IssmDouble>(basis);
+	delete gauss;
+	return Ke;
+}
+/*}}}*/
+ElementMatrix* ExtrudeFromBaseAnalysis::CreateKMatrixBed(Element* element){/*{{{*/
+
+	if(!element->IsOnBase()) return NULL;
+
+	/*Intermediaries */
+	int         dim;
+	IssmDouble  Jdet,D,normal[3];
+	IssmDouble *xyz_list_base = NULL;
+
+	/*Get dimension*/
+	element->FindParam(&dim,DomainDimensionEnum);
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Initialize Element vector and other vectors*/
+	ElementMatrix* Ke    = element->NewElementMatrix();
+	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinatesBase(&xyz_list_base);
+	element->NormalBase(&normal[0],xyz_list_base);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGaussBase(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminantBase(&Jdet,xyz_list_base,gauss);
+		element->NodalFunctions(basis,gauss);
+		D = - gauss->weight*Jdet*normal[dim-1]; 
+
+		TripleMultiply(basis,1,numnodes,1,
+					&D,1,1,0,
+					basis,1,numnodes,0,
+					&Ke->values[0],1);
+	}
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(xyz_list_base);
+	xDelete<IssmDouble>(basis);
+	delete gauss;
+	return Ke;
+}
+/*}}}*/
+ElementVector* ExtrudeFromBaseAnalysis::CreatePVector(Element* element){/*{{{*/
+	return NULL;
+}/*}}}*/
+void ExtrudeFromBaseAnalysis::GetB(IssmDouble* B,Element* element,int dim,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
+	/*	Compute B  matrix. B=[dh1/dz dh2/dz dh3/dz dh4/dz dh5/dz dh6/dz];
+		where hi is the interpolation function for node i.*/
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Get nodal functions derivatives*/
+	IssmDouble* dbasis=xNew<IssmDouble>(dim*numnodes);
+	element->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+
+	/*Build B: */
+	for(int i=0;i<numnodes;i++){
+		B[i] = dbasis[(dim-1)*numnodes+i];
+	}
+
+	/*Clean-up*/
+	xDelete<IssmDouble>(dbasis);
+}
+/*}}}*/
+void ExtrudeFromBaseAnalysis::GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element){/*{{{*/
+	   _error_("not implemented yet");
+}/*}}}*/
+void ExtrudeFromBaseAnalysis::InputUpdateFromSolution(IssmDouble* solution,Element* element){/*{{{*/
+
+	int inputenum;
+	element->FindParam(&inputenum,InputToExtrudeEnum);
+	element->InputUpdateFromSolutionOneDof(solution,inputenum);
+}/*}}}*/
+void ExtrudeFromBaseAnalysis::UpdateConstraints(FemModel* femmodel){/*{{{*/
+	/*Default, do nothing*/
+	return;
+}/*}}}*/
Index: /issm/trunk/src/c/analyses/ExtrudeFromBaseAnalysis.h
===================================================================
--- /issm/trunk/src/c/analyses/ExtrudeFromBaseAnalysis.h	(revision 17805)
+++ /issm/trunk/src/c/analyses/ExtrudeFromBaseAnalysis.h	(revision 17806)
@@ -12,5 +12,6 @@
 
 	public:
-		int  DofsPerNode(int** doflist,int meshtype,int approximation);
+		/*Model processing*/
+		int  DofsPerNode(int** doflist,int domaintype,int approximation);
 		void UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum);
 		void UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);
@@ -18,4 +19,18 @@
 		void CreateConstraints(Constraints* constraints,IoModel* iomodel);
 		void CreateLoads(Loads* loads, IoModel* iomodel);
+
+		/*Finite element Analysis*/
+		void           Core(FemModel* femmodel);
+		ElementVector* CreateDVector(Element* element);
+		ElementMatrix* CreateJacobianMatrix(Element* element);
+		ElementMatrix* CreateKMatrix(Element* element);
+		ElementMatrix* CreateKMatrixVolume(Element* element);
+		ElementMatrix* CreateKMatrixSurface(Element* element);
+		ElementMatrix* CreateKMatrixBed(Element* element);
+		ElementVector* CreatePVector(Element* element);
+		void GetB(IssmDouble* B,Element* element,int dim,IssmDouble* xyz_list,Gauss* gauss);
+		void GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element);
+		void InputUpdateFromSolution(IssmDouble* solution,Element* element);
+		void UpdateConstraints(FemModel* femmodel);
 };
 #endif
Index: /issm/trunk/src/c/analyses/ExtrudeFromTopAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/ExtrudeFromTopAnalysis.cpp	(revision 17805)
+++ /issm/trunk/src/c/analyses/ExtrudeFromTopAnalysis.cpp	(revision 17806)
@@ -6,5 +6,5 @@
 
 /*Model processing*/
-int  ExtrudeFromTopAnalysis::DofsPerNode(int** doflist,int meshtype,int approximation){/*{{{*/
+int  ExtrudeFromTopAnalysis::DofsPerNode(int** doflist,int domaintype,int approximation){/*{{{*/
 	return 1;
 }/*}}}*/
@@ -22,11 +22,11 @@
 	}
 
-	if(iomodel->meshtype==Mesh2DverticalEnum){
-		iomodel->FetchDataToInput(elements,MeshVertexonbedEnum);
+	if(iomodel->domaintype==Domain2DverticalEnum){
+		iomodel->FetchDataToInput(elements,MeshVertexonbaseEnum);
 	}
 }/*}}}*/
 void ExtrudeFromTopAnalysis::CreateNodes(Nodes* nodes,IoModel* iomodel){/*{{{*/
 
-	::CreateNodes(nodes,iomodel,ExtrudeFromBaseAnalysisEnum,P1Enum);
+	::CreateNodes(nodes,iomodel,ExtrudeFromTopAnalysisEnum,P1Enum);
 
 }/*}}}*/
@@ -35,2 +35,199 @@
 void ExtrudeFromTopAnalysis::CreateLoads(Loads* loads, IoModel* iomodel){/*{{{*/
 }/*}}}*/
+
+/*Finite Element Analysis*/
+void           ExtrudeFromTopAnalysis::Core(FemModel* femmodel){/*{{{*/
+	_error_("not implemented");
+}/*}}}*/
+ElementVector* ExtrudeFromTopAnalysis::CreateDVector(Element* element){/*{{{*/
+	/*Default, return NULL*/
+	return NULL;
+}/*}}}*/
+ElementMatrix* ExtrudeFromTopAnalysis::CreateJacobianMatrix(Element* element){/*{{{*/
+_error_("Not implemented");
+}/*}}}*/
+ElementMatrix* ExtrudeFromTopAnalysis::CreateKMatrix(Element* element){/*{{{*/
+
+	/*compute all stiffness matrices for this element*/
+	ElementMatrix* Ke1=CreateKMatrixVolume(element);
+	ElementMatrix* Ke2=CreateKMatrixSurface(element);
+	ElementMatrix* Ke3=CreateKMatrixBed(element);
+	ElementMatrix* Ke =new ElementMatrix(Ke1,Ke2,Ke3);
+
+	/*clean-up and return*/
+	delete Ke1;
+	delete Ke2;
+	delete Ke3;
+	return Ke;
+}/*}}}*/
+ElementMatrix* ExtrudeFromTopAnalysis::CreateKMatrixVolume(Element* element){/*{{{*/
+
+	/*Intermediaries */
+	int         dim;
+	IssmDouble  Jdet,D;
+	IssmDouble *xyz_list = NULL;
+
+	/*Get dimension*/
+	element->FindParam(&dim,DomainDimensionEnum);
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Initialize Element vector and other vectors*/
+	ElementMatrix* Ke     = element->NewElementMatrix();
+	IssmDouble*    B      = xNew<IssmDouble>(numnodes);
+	IssmDouble*    Bprime = xNew<IssmDouble>(numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		element->NodalFunctions(Bprime,gauss);
+		GetB(B,element,dim,xyz_list,gauss);
+		D=gauss->weight*Jdet;
+
+		TripleMultiply(B,1,numnodes,1,
+					&D,1,1,0,
+					Bprime,1,numnodes,0,
+					&Ke->values[0],1);
+	} 
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(B);
+	xDelete<IssmDouble>(Bprime);
+	delete gauss;
+	return Ke;
+}
+/*}}}*/
+ElementMatrix* ExtrudeFromTopAnalysis::CreateKMatrixSurface(Element* element){/*{{{*/
+
+	if(!element->IsOnSurface()) return NULL;
+
+	/*Intermediaries */
+	int         dim;
+	IssmDouble  Jdet,D,normal[2];
+	IssmDouble *xyz_list_top = NULL;
+
+	/*Get dimension*/
+	element->FindParam(&dim,DomainDimensionEnum);
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Initialize Element vector and other vectors*/
+	ElementMatrix* Ke    = element->NewElementMatrix();
+	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinatesTop(&xyz_list_top);
+	element->NormalTop(&normal[0],xyz_list_top);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGaussTop(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminantTop(&Jdet,xyz_list_top,gauss);
+		element->NodalFunctions(basis,gauss);
+		D = - gauss->weight*Jdet*normal[dim-1]; 
+
+		TripleMultiply(basis,1,numnodes,1,
+					&D,1,1,0,
+					basis,1,numnodes,0,
+					&Ke->values[0],1);
+	}
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(xyz_list_top);
+	xDelete<IssmDouble>(basis);
+	delete gauss;
+	return Ke;
+}
+/*}}}*/
+ElementMatrix* ExtrudeFromTopAnalysis::CreateKMatrixBed(Element* element){/*{{{*/
+
+	if(!element->IsOnBase()) return NULL;
+
+	/*Intermediaries */
+	int         dim;
+	IssmDouble  Jdet,D,normal[3];
+	IssmDouble *xyz_list_base = NULL;
+
+	/*Get dimension*/
+	element->FindParam(&dim,DomainDimensionEnum);
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Initialize Element vector and other vectors*/
+	ElementMatrix* Ke    = element->NewElementMatrix();
+	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinatesBase(&xyz_list_base);
+	element->NormalBase(&normal[0],xyz_list_base);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGaussBase(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminantBase(&Jdet,xyz_list_base,gauss);
+		element->NodalFunctions(basis,gauss);
+		D = - gauss->weight*Jdet*normal[dim-1]; 
+
+		TripleMultiply(basis,1,numnodes,1,
+					&D,1,1,0,
+					basis,1,numnodes,0,
+					&Ke->values[0],1);
+	}
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(xyz_list_base);
+	xDelete<IssmDouble>(basis);
+	delete gauss;
+	return Ke;
+}
+/*}}}*/
+ElementVector* ExtrudeFromTopAnalysis::CreatePVector(Element* element){/*{{{*/
+	return NULL;
+}/*}}}*/
+void ExtrudeFromTopAnalysis::GetB(IssmDouble* B,Element* element,int dim,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
+	/*	Compute B  matrix. B=[dh1/dz dh2/dz dh3/dz dh4/dz dh5/dz dh6/dz];
+		where hi is the interpolation function for node i.*/
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Get nodal functions derivatives*/
+	IssmDouble* dbasis=xNew<IssmDouble>(dim*numnodes);
+	element->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+
+	/*Build B: */
+	for(int i=0;i<numnodes;i++){
+		B[i] = dbasis[(dim-1)*numnodes+i];
+	}
+
+	/*Clean-up*/
+	xDelete<IssmDouble>(dbasis);
+}
+/*}}}*/
+void ExtrudeFromTopAnalysis::GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element){/*{{{*/
+	   _error_("not implemented yet");
+}/*}}}*/
+void ExtrudeFromTopAnalysis::InputUpdateFromSolution(IssmDouble* solution,Element* element){/*{{{*/
+
+	int inputenum;
+	element->FindParam(&inputenum,InputToExtrudeEnum);
+	element->InputUpdateFromSolutionOneDof(solution,inputenum);
+}/*}}}*/
+void ExtrudeFromTopAnalysis::UpdateConstraints(FemModel* femmodel){/*{{{*/
+	/*Default, do nothing*/
+	return;
+}/*}}}*/
Index: /issm/trunk/src/c/analyses/ExtrudeFromTopAnalysis.h
===================================================================
--- /issm/trunk/src/c/analyses/ExtrudeFromTopAnalysis.h	(revision 17805)
+++ /issm/trunk/src/c/analyses/ExtrudeFromTopAnalysis.h	(revision 17806)
@@ -12,5 +12,6 @@
 
 	public:
-		int  DofsPerNode(int** doflist,int meshtype,int approximation);
+		/*Model processing*/
+		int  DofsPerNode(int** doflist,int domaintype,int approximation);
 		void UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum);
 		void UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);
@@ -18,4 +19,18 @@
 		void CreateConstraints(Constraints* constraints,IoModel* iomodel);
 		void CreateLoads(Loads* loads, IoModel* iomodel);
+
+		/*Finite element Analysis*/
+		void           Core(FemModel* femmodel);
+		ElementVector* CreateDVector(Element* element);
+		ElementMatrix* CreateJacobianMatrix(Element* element);
+		ElementMatrix* CreateKMatrix(Element* element);
+		ElementMatrix* CreateKMatrixVolume(Element* element);
+		ElementMatrix* CreateKMatrixSurface(Element* element);
+		ElementMatrix* CreateKMatrixBed(Element* element);
+		ElementVector* CreatePVector(Element* element);
+		void GetB(IssmDouble* B,Element* element,int dim,IssmDouble* xyz_list,Gauss* gauss);
+		void GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element);
+		void InputUpdateFromSolution(IssmDouble* solution,Element* element);
+		void UpdateConstraints(FemModel* femmodel);
 };
 #endif
Index: /issm/trunk/src/c/analyses/FreeSurfaceBaseAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/FreeSurfaceBaseAnalysis.cpp	(revision 17805)
+++ /issm/trunk/src/c/analyses/FreeSurfaceBaseAnalysis.cpp	(revision 17806)
@@ -6,5 +6,5 @@
 
 /*Model processing*/
-int  FreeSurfaceBaseAnalysis::DofsPerNode(int** doflist,int meshtype,int approximation){/*{{{*/
+int  FreeSurfaceBaseAnalysis::DofsPerNode(int** doflist,int domaintype,int approximation){/*{{{*/
 	return 1;
 }/*}}}*/
@@ -14,5 +14,5 @@
 
 	/*Now, is the model 3d? otherwise, do nothing: */
-	if (iomodel->meshtype==Mesh2DhorizontalEnum)return;
+	if (iomodel->domaintype==Domain2DhorizontalEnum)return;
 
 	/*Finite element type*/
@@ -35,7 +35,7 @@
 	iomodel->FetchDataToInput(elements,VxEnum);
 	iomodel->FetchDataToInput(elements,VyEnum);
-	if(iomodel->meshtype==Mesh3DEnum){
+	if(iomodel->domaintype==Domain3DEnum){
 		iomodel->FetchDataToInput(elements,VzEnum);
-		iomodel->FetchDataToInput(elements,MeshElementonbedEnum);
+		iomodel->FetchDataToInput(elements,MeshElementonbaseEnum);
 		iomodel->FetchDataToInput(elements,MeshElementonsurfaceEnum);
 	}
@@ -43,7 +43,7 @@
 void FreeSurfaceBaseAnalysis::CreateNodes(Nodes* nodes,IoModel* iomodel){/*{{{*/
 
-	if(iomodel->meshtype!=Mesh2DhorizontalEnum) iomodel->FetchData(2,MeshVertexonbedEnum,MeshVertexonsurfaceEnum);
+	if(iomodel->domaintype!=Domain2DhorizontalEnum) iomodel->FetchData(2,MeshVertexonbaseEnum,MeshVertexonsurfaceEnum);
 	::CreateNodes(nodes,iomodel,FreeSurfaceBaseAnalysisEnum,P1Enum);
-	iomodel->DeleteData(2,MeshVertexonbedEnum,MeshVertexonsurfaceEnum);
+	iomodel->DeleteData(2,MeshVertexonbaseEnum,MeshVertexonsurfaceEnum);
 }/*}}}*/
 void FreeSurfaceBaseAnalysis::CreateConstraints(Constraints* constraints,IoModel* iomodel){/*{{{*/
@@ -58,7 +58,7 @@
 	/*Create Penpair for vertex_pairing: */
 	IssmDouble *vertex_pairing=NULL;
-	IssmDouble *nodeonbed=NULL;
+	IssmDouble *nodeonbase=NULL;
 	iomodel->FetchData(&vertex_pairing,&numvertex_pairing,NULL,MasstransportVertexPairingEnum);
-	iomodel->FetchData(&nodeonbed,NULL,NULL,MeshVertexonbedEnum);
+	if(iomodel->domaintype!=Domain2DhorizontalEnum) iomodel->FetchData(&nodeonbase,NULL,NULL,MeshVertexonbaseEnum);
 	for(int i=0;i<numvertex_pairing;i++){
 
@@ -69,5 +69,7 @@
 
 			/*Skip if one of the two is not on the bed*/
-			if(!(reCast<bool>(nodeonbed[reCast<int>(vertex_pairing[2*i+0])-1])) || !(reCast<bool>(nodeonbed[reCast<int>(vertex_pairing[2*i+1])-1]))) continue;
+			if(iomodel->domaintype!=Domain2DhorizontalEnum){
+				if(!(reCast<bool>(nodeonbase[reCast<int>(vertex_pairing[2*i+0])-1])) || !(reCast<bool>(nodeonbase[reCast<int>(vertex_pairing[2*i+1])-1]))) continue;
+			}
 
 			/*Get node ids*/
@@ -86,4 +88,312 @@
 	/*free ressources: */
 	iomodel->DeleteData(vertex_pairing,MasstransportVertexPairingEnum);
-	iomodel->DeleteData(nodeonbed,MeshVertexonbedEnum);
-}/*}}}*/
+	iomodel->DeleteData(nodeonbase,MeshVertexonbaseEnum);
+}/*}}}*/
+
+/*Finite Element Analysis*/
+void           FreeSurfaceBaseAnalysis::Core(FemModel* femmodel){/*{{{*/
+	_error_("not implemented");
+}/*}}}*/
+ElementVector* FreeSurfaceBaseAnalysis::CreateDVector(Element* element){/*{{{*/
+	/*Default, return NULL*/
+	return NULL;
+}/*}}}*/
+ElementMatrix* FreeSurfaceBaseAnalysis::CreateJacobianMatrix(Element* element){/*{{{*/
+_error_("Not implemented");
+}/*}}}*/
+ElementMatrix* FreeSurfaceBaseAnalysis::CreateKMatrix(Element* element){/*{{{*/
+
+	/*Intermediaries*/
+	int         domaintype,dim,stabilization;
+	Element*    basalelement = NULL;
+	IssmDouble *xyz_list  = NULL;
+	IssmDouble  Jdet,D_scalar,dt,h;
+	IssmDouble  vel,vx,vy;
+
+	/*Get basal element*/
+	element->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DhorizontalEnum:
+			basalelement = element;
+			dim = 2;
+			break;
+		case Domain2DverticalEnum:
+			if(!element->IsOnBase()) return NULL;
+			basalelement = element->SpawnBasalElement();
+			dim = 1;
+			break;
+		case Domain3DEnum:
+			if(!element->IsOnBase()) return NULL;
+			basalelement = element->SpawnBasalElement();
+			dim = 2;
+			break;
+		default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
+	}
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = basalelement->GetNumberOfNodes();
+
+	/*Initialize Element vector*/
+	ElementMatrix* Ke     = basalelement->NewElementMatrix(NoneApproximationEnum);
+	IssmDouble*    basis  = xNew<IssmDouble>(numnodes);
+	IssmDouble*    B      = xNew<IssmDouble>(dim*numnodes);
+	IssmDouble*    Bprime = xNew<IssmDouble>(dim*numnodes);
+	IssmDouble*    D      = xNew<IssmDouble>(dim*dim);
+
+	/*Retrieve all inputs and parameters*/
+	basalelement->GetVerticesCoordinates(&xyz_list);
+	basalelement->FindParam(&dt,TimesteppingTimeStepEnum);
+	basalelement->FindParam(&stabilization,MasstransportStabilizationEnum);
+	Input* vx_input=basalelement->GetInput(VxEnum); _assert_(vx_input);
+	Input* vy_input=NULL;
+	if(dim>1){vy_input = basalelement->GetInput(VyEnum); _assert_(vy_input);}
+	h = basalelement->CharacteristicLength();
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=basalelement->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		basalelement->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		basalelement->NodalFunctions(basis,gauss);
+
+		vx_input->GetInputValue(&vx,gauss);
+		if(dim==2) vy_input->GetInputValue(&vy,gauss);
+
+		D_scalar=gauss->weight*Jdet;
+		TripleMultiply(basis,1,numnodes,1,
+					&D_scalar,1,1,0,
+					basis,1,numnodes,0,
+					&Ke->values[0],1);
+
+		GetB(B,basalelement,dim,xyz_list,gauss);
+		GetBprime(Bprime,basalelement,dim,xyz_list,gauss);
+
+		D_scalar=dt*gauss->weight*Jdet;
+		for(int i=0;i<dim*dim;i++) D[i]=0.;
+		D[0] = D_scalar*vx;
+		if(dim==2) D[1*dim+1] = D_scalar*vy;
+
+		TripleMultiply(B,dim,numnodes,1,
+					D,dim,dim,0,
+					Bprime,dim,numnodes,0,
+					&Ke->values[0],1);
+
+		if(stabilization==2){
+			/*Streamline upwinding*/
+			if(dim==1){
+			 vel=fabs(vx)+1.e-8;
+			 D[0] = h/(2.*vel)*vx*vx;
+			}
+			else{
+			 vel=sqrt(vx*vx+vy*vy)+1.e-8;
+			 D[0*dim+0]=h/(2*vel)*vx*vx;
+			 D[1*dim+0]=h/(2*vel)*vy*vx;
+			 D[0*dim+1]=h/(2*vel)*vx*vy;
+			 D[1*dim+1]=h/(2*vel)*vy*vy;
+			}
+		}
+		else if(stabilization==1){
+			/*SSA*/
+			if(dim==1){
+				vx_input->GetInputAverage(&vx);
+				D[0]=h/2.*fabs(vx);
+			}
+			else{
+				vx_input->GetInputAverage(&vx);
+				vy_input->GetInputAverage(&vy);
+				D[0*dim+0]=h/2.0*fabs(vx);
+				D[1*dim+1]=h/2.0*fabs(vy);
+			}
+		}
+		if(stabilization==1 || stabilization==2){
+			for(int i=0;i<dim*dim;i++) D[i]=D_scalar*D[i];
+			TripleMultiply(Bprime,dim,numnodes,1,
+						D,dim,dim,0,
+						Bprime,dim,numnodes,0,
+						&Ke->values[0],1);
+		}
+	}
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(basis);
+	xDelete<IssmDouble>(B);
+	xDelete<IssmDouble>(Bprime);
+	xDelete<IssmDouble>(D);
+	delete gauss;
+	if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;};
+	return Ke;
+}/*}}}*/
+ElementVector* FreeSurfaceBaseAnalysis::CreatePVector(Element* element){/*{{{*/
+	/*Intermediaries*/
+	int         domaintype,dim;
+	IssmDouble  Jdet,dt;
+	IssmDouble  mb,mb_correction,bed,vz;
+	Element*    basalelement = NULL;
+	IssmDouble *xyz_list  = NULL;
+
+	/*Get basal element*/
+	element->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DhorizontalEnum:
+			basalelement = element;
+			dim = 2;
+			break;
+		case Domain2DverticalEnum:
+			if(!element->IsOnBase()) return NULL;
+			basalelement = element->SpawnBasalElement();
+			dim = 1;
+			break;
+		case Domain3DEnum:
+			if(!element->IsOnBase()) return NULL;
+			basalelement = element->SpawnBasalElement();
+			dim = 2;
+			break;
+		default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
+	}
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = basalelement->GetNumberOfNodes();
+
+	/*Initialize Element vector and other vectors*/
+	ElementVector* pe    = basalelement->NewElementVector();
+	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	basalelement->GetVerticesCoordinates(&xyz_list);
+	basalelement->FindParam(&dt,TimesteppingTimeStepEnum);
+	Input* mb_input            = basalelement->GetInput(BasalforcingsMeltingRateEnum);   _assert_(mb_input);
+	Input* mb_correction_input = basalelement->GetInput(BasalforcingsMeltingRateCorrectionEnum);
+	Input* base_input           = basalelement->GetInput(BaseEnum);                        _assert_(base_input);
+	Input* vz_input      = NULL;
+	switch(dim){
+		case 1: vz_input = basalelement->GetInput(VyEnum); _assert_(vz_input); break;
+		case 2: vz_input = basalelement->GetInput(VzEnum); _assert_(vz_input); break;
+		default: _error_("not implemented");
+	}
+
+	/*Initialize mb_correction to 0, do not forget!:*/
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=basalelement->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		basalelement->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		basalelement->NodalFunctions(basis,gauss);
+
+		vz_input->GetInputValue(&vz,gauss);
+		mb_input->GetInputValue(&mb,gauss);
+		base_input->GetInputValue(&bed,gauss);
+		if(mb_correction_input)
+		 mb_correction_input->GetInputValue(&mb_correction,gauss);
+		else
+		 mb_correction=0.;
+
+		for(int i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*(bed+dt*(mb-mb_correction) + dt*vz)*basis[i];
+	}
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(basis);
+	delete gauss;
+	if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;};
+	return pe;
+
+}/*}}}*/
+void FreeSurfaceBaseAnalysis::GetB(IssmDouble* B,Element* element,int dim,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
+	/*Compute B  matrix. B=[B1 B2 B3] where Bi is of size 3*NDOF2. 
+	 * For node i, Bi can be expressed in the actual coordinate system
+	 * by: 
+	 *       Bi=[ N ]
+	 *          [ N ]
+	 * where N is the finiteelement function for node i.
+	 *
+	 * We assume B_prog has been allocated already, of size: 2x(NDOF1*numnodes)
+	 */
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Get nodal functions*/
+	IssmDouble* basis=xNew<IssmDouble>(numnodes);
+	element->NodalFunctions(basis,gauss);
+
+	/*Build B: */
+	for(int i=0;i<numnodes;i++){
+		for(int j=0;j<dim;j++){
+			B[numnodes*j+i] = basis[i];
+		}
+	}
+
+	/*Clean-up*/
+	xDelete<IssmDouble>(basis);
+}/*}}}*/
+void FreeSurfaceBaseAnalysis::GetBprime(IssmDouble* Bprime,Element* element,int dim,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
+	/*Compute B'  matrix. B'=[B1' B2' B3'] where Bi' is of size 3*NDOF2. 
+	 * For node i, Bi' can be expressed in the actual coordinate system
+	 * by: 
+	 *       Bi_prime=[ dN/dx ]
+	 *                [ dN/dy ]
+	 * where N is the finiteelement function for node i.
+	 *
+	 * We assume B' has been allocated already, of size: 3x(NDOF2*numnodes)
+	 */
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Get nodal functions derivatives*/
+	IssmDouble* dbasis=xNew<IssmDouble>(dim*numnodes);
+	element->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+
+	/*Build B': */
+	for(int i=0;i<numnodes;i++){
+		for(int j=0;j<dim;j++){
+			Bprime[numnodes*j+i] = dbasis[j*numnodes+i];
+		}
+	}
+
+	/*Clean-up*/
+	xDelete<IssmDouble>(dbasis);
+
+}/*}}}*/
+void FreeSurfaceBaseAnalysis::GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element){/*{{{*/
+	   _error_("not implemented yet");
+}/*}}}*/
+void FreeSurfaceBaseAnalysis::InputUpdateFromSolution(IssmDouble* solution,Element* element){/*{{{*/
+	element->InputUpdateFromSolutionOneDof(solution,BaseEnum);
+}/*}}}*/
+void FreeSurfaceBaseAnalysis::UpdateConstraints(FemModel* femmodel){/*{{{*/
+
+	/*Intermediary*/
+	IssmDouble phi,isonbase,base;
+
+	for(int i=0;i<femmodel->elements->Size();i++){
+
+		Element* element=dynamic_cast<Element*>(femmodel->elements->GetObjectByOffset(i));
+		if(!element->IsOnBase()) continue;
+
+		int             numnodes = element->GetNumberOfNodes();
+		Input* groundedice_input = element->GetInput(MaskGroundediceLevelsetEnum);  _assert_(groundedice_input);
+		Input* onbase_input       = element->GetInput(MeshVertexonbaseEnum);          _assert_(onbase_input);
+		Input* base_input        = element->GetInput(BaseEnum);                     _assert_(base_input);
+
+		Gauss* gauss=element->NewGauss();
+		for(int iv=0;iv<numnodes;iv++){
+			gauss->GaussNode(element->GetElementType(),iv);
+			onbase_input->GetInputValue(&isonbase,gauss);
+			if(isonbase==1.){
+				groundedice_input->GetInputValue(&phi,gauss);
+				if(phi>=0.){
+					base_input->GetInputValue(&base,gauss);
+					element->nodes[iv]->ApplyConstraint(0,base);
+				}
+				else{
+					element->nodes[iv]->DofInFSet(0);
+				}
+			}
+		}
+		delete gauss;
+	}
+}/*}}}*/
Index: /issm/trunk/src/c/analyses/FreeSurfaceBaseAnalysis.h
===================================================================
--- /issm/trunk/src/c/analyses/FreeSurfaceBaseAnalysis.h	(revision 17805)
+++ /issm/trunk/src/c/analyses/FreeSurfaceBaseAnalysis.h	(revision 17806)
@@ -12,5 +12,6 @@
 
 	public:
-		int  DofsPerNode(int** doflist,int meshtype,int approximation);
+		/*Model processing*/
+		int  DofsPerNode(int** doflist,int domaintype,int approximation);
 		void UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum);
 		void UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);
@@ -18,4 +19,16 @@
 		void CreateConstraints(Constraints* constraints,IoModel* iomodel);
 		void CreateLoads(Loads* loads, IoModel* iomodel);
+
+		/*Finite element Analysis*/
+		void           Core(FemModel* femmodel);
+		ElementVector* CreateDVector(Element* element);
+		ElementMatrix* CreateJacobianMatrix(Element* element);
+		ElementMatrix* CreateKMatrix(Element* element);
+		ElementVector* CreatePVector(Element* element);
+		void GetB(IssmDouble* B,Element* element,int dim,IssmDouble* xyz_list,Gauss* gauss);
+		void GetBprime(IssmDouble* B,Element* element,int dim,IssmDouble* xyz_list,Gauss* gauss);
+		void GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element);
+		void InputUpdateFromSolution(IssmDouble* solution,Element* element);
+		void UpdateConstraints(FemModel* femmodel);
 };
 #endif
Index: /issm/trunk/src/c/analyses/FreeSurfaceTopAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/FreeSurfaceTopAnalysis.cpp	(revision 17805)
+++ /issm/trunk/src/c/analyses/FreeSurfaceTopAnalysis.cpp	(revision 17806)
@@ -6,5 +6,5 @@
 
 /*Model processing*/
-int  FreeSurfaceTopAnalysis::DofsPerNode(int** doflist,int meshtype,int approximation){/*{{{*/
+int  FreeSurfaceTopAnalysis::DofsPerNode(int** doflist,int domaintype,int approximation){/*{{{*/
 	return 1;
 }/*}}}*/
@@ -14,7 +14,11 @@
 
 	/*Now, is the model 3d? otherwise, do nothing: */
-	if (iomodel->meshtype==Mesh2DhorizontalEnum)return;
-
+	if (iomodel->domaintype==Domain2DhorizontalEnum)return;
+
+	int smb_model;
 	int finiteelement = P1Enum;
+
+	/*Fetch data needed: */
+	iomodel->Constant(&smb_model,SurfaceforcingsEnum);
 
 	/*Update elements: */
@@ -30,18 +34,25 @@
 	iomodel->FetchDataToInput(elements,SurfaceEnum);
 	iomodel->FetchDataToInput(elements,MaskIceLevelsetEnum);
-	iomodel->FetchDataToInput(elements,SurfaceforcingsMassBalanceEnum,0.);
 	iomodel->FetchDataToInput(elements,VxEnum);
-	iomodel->FetchDataToInput(elements,MeshVertexonsurfaceEnum);
-	if(iomodel->meshtype==Mesh3DEnum){
+	if(iomodel->domaintype!=Domain2DhorizontalEnum) iomodel->FetchDataToInput(elements,MeshVertexonsurfaceEnum);
+	if(iomodel->domaintype==Domain3DEnum){
 		iomodel->FetchDataToInput(elements,VzEnum);
-		iomodel->FetchDataToInput(elements,MeshElementonbedEnum);
+		iomodel->FetchDataToInput(elements,MeshElementonbaseEnum);
 		iomodel->FetchDataToInput(elements,MeshElementonsurfaceEnum);
 	}
+	switch(smb_model){
+		case SMBEnum:
+			iomodel->FetchDataToInput(elements,SurfaceforcingsMassBalanceEnum,0.);
+			break;
+		default:
+			/*Nothing for now*/
+			;
+	}
 }/*}}}*/
 void FreeSurfaceTopAnalysis::CreateNodes(Nodes* nodes,IoModel* iomodel){/*{{{*/
 
-	if(iomodel->meshtype!=Mesh2DhorizontalEnum) iomodel->FetchData(2,MeshVertexonbedEnum,MeshVertexonsurfaceEnum);
+	if(iomodel->domaintype!=Domain2DhorizontalEnum) iomodel->FetchData(2,MeshVertexonbaseEnum,MeshVertexonsurfaceEnum);
 	::CreateNodes(nodes,iomodel,FreeSurfaceTopAnalysisEnum,P1Enum);
-	iomodel->DeleteData(2,MeshVertexonbedEnum,MeshVertexonsurfaceEnum);
+	iomodel->DeleteData(2,MeshVertexonbaseEnum,MeshVertexonsurfaceEnum);
 }/*}}}*/
 void FreeSurfaceTopAnalysis::CreateConstraints(Constraints* constraints,IoModel* iomodel){/*{{{*/
@@ -58,5 +69,5 @@
 	IssmDouble *nodeonsurface=NULL;
 	iomodel->FetchData(&vertex_pairing,&numvertex_pairing,NULL,MasstransportVertexPairingEnum);
-	iomodel->FetchData(&nodeonsurface,NULL,NULL,MeshVertexonsurfaceEnum);
+	if(iomodel->domaintype!=Domain2DhorizontalEnum) iomodel->FetchData(&nodeonsurface,NULL,NULL,MeshVertexonsurfaceEnum);
 	for(int i=0;i<numvertex_pairing;i++){
 
@@ -67,5 +78,7 @@
 
 			/*Skip if one of the two is not on the bed*/
-			if(!(reCast<bool>(nodeonsurface[reCast<int>(vertex_pairing[2*i+0])-1])) || !(reCast<bool>(nodeonsurface[reCast<int>(vertex_pairing[2*i+1])-1]))) continue;
+			if(iomodel->domaintype!=Domain2DhorizontalEnum){
+				if(!(reCast<bool>(nodeonsurface[reCast<int>(vertex_pairing[2*i+0])-1])) || !(reCast<bool>(nodeonsurface[reCast<int>(vertex_pairing[2*i+1])-1]))) continue;
+			}
 
 			/*Get node ids*/
@@ -86,2 +99,277 @@
 	iomodel->DeleteData(nodeonsurface,MeshVertexonsurfaceEnum);
 }/*}}}*/
+
+/*Finite Element Analysis*/
+void           FreeSurfaceTopAnalysis::Core(FemModel* femmodel){/*{{{*/
+	_error_("not implemented");
+}/*}}}*/
+ElementVector* FreeSurfaceTopAnalysis::CreateDVector(Element* element){/*{{{*/
+	/*Default, return NULL*/
+	return NULL;
+}/*}}}*/
+ElementMatrix* FreeSurfaceTopAnalysis::CreateJacobianMatrix(Element* element){/*{{{*/
+_error_("Not implemented");
+}/*}}}*/
+ElementMatrix* FreeSurfaceTopAnalysis::CreateKMatrix(Element* element){/*{{{*/
+
+	/*Intermediaries*/
+	int         domaintype,dim,stabilization;
+	Element*    topelement = NULL;
+	IssmDouble *xyz_list  = NULL;
+	IssmDouble  Jdet,D_scalar,dt,h;
+	IssmDouble  vel,vx,vy;
+
+	/*Get top element*/
+	element->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DhorizontalEnum:
+			topelement = element;
+			dim = 2;
+			break;
+		case Domain2DverticalEnum:
+			if(!element->IsOnSurface()) return NULL;
+			topelement = element->SpawnTopElement();
+			dim = 1;
+			break;
+		case Domain3DEnum:
+			if(!element->IsOnSurface()) return NULL;
+			topelement = element->SpawnTopElement();
+			dim = 2;
+			break;
+		default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
+	}
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = topelement->GetNumberOfNodes();
+
+	/*Initialize Element vector*/
+	ElementMatrix* Ke     = topelement->NewElementMatrix(NoneApproximationEnum);
+	IssmDouble*    basis  = xNew<IssmDouble>(numnodes);
+	IssmDouble*    B      = xNew<IssmDouble>(dim*numnodes);
+	IssmDouble*    Bprime = xNew<IssmDouble>(dim*numnodes);
+	IssmDouble*    D      = xNew<IssmDouble>(dim*dim);
+
+	/*Retrieve all inputs and parameters*/
+	topelement->GetVerticesCoordinates(&xyz_list);
+	topelement->FindParam(&dt,TimesteppingTimeStepEnum);
+	topelement->FindParam(&stabilization,MasstransportStabilizationEnum);
+	Input* vx_input=topelement->GetInput(VxEnum); _assert_(vx_input);
+	Input* vy_input=NULL;
+	if(dim>1){vy_input = topelement->GetInput(VyEnum); _assert_(vy_input);}
+	h = topelement->CharacteristicLength();
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=topelement->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		topelement->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		topelement->NodalFunctions(basis,gauss);
+
+		vx_input->GetInputValue(&vx,gauss);
+		if(dim==2) vy_input->GetInputValue(&vy,gauss);
+
+		D_scalar=gauss->weight*Jdet;
+		TripleMultiply(basis,1,numnodes,1,
+					&D_scalar,1,1,0,
+					basis,1,numnodes,0,
+					&Ke->values[0],1);
+
+		GetB(B,topelement,dim,xyz_list,gauss);
+		GetBprime(Bprime,topelement,dim,xyz_list,gauss);
+
+		D_scalar=dt*gauss->weight*Jdet;
+		for(int i=0;i<dim*dim;i++) D[i]=0.;
+		D[0] = D_scalar*vx;
+		if(dim==2) D[1*dim+1]=D_scalar*vy;
+
+		TripleMultiply(B,dim,numnodes,1,
+					D,dim,dim,0,
+					Bprime,dim,numnodes,0,
+					&Ke->values[0],1);
+
+		if(stabilization==2){
+			/*Streamline upwinding*/
+			if(dim==1){
+				vel=fabs(vx)+1.e-8;
+				D[0] = h/(2.*vel)*vx*vx;
+			}
+			else{
+				vel=sqrt(vx*vx+vy*vy)+1.e-8;
+				D[0*dim+0]=h/(2*vel)*vx*vx;
+				D[1*dim+0]=h/(2*vel)*vy*vx;
+				D[0*dim+1]=h/(2*vel)*vx*vy;
+				D[1*dim+1]=h/(2*vel)*vy*vy;
+			}
+		}
+		else if(stabilization==1){
+			/*SSA*/
+			if(dim==1){
+				vx_input->GetInputAverage(&vx);
+				D[0]=h/2.*fabs(vx);
+			}
+			else{
+				vx_input->GetInputAverage(&vx);
+				vy_input->GetInputAverage(&vy);
+				D[0*dim+0]=h/2.0*fabs(vx);
+				D[1*dim+1]=h/2.0*fabs(vy);
+			}
+		}
+		if(stabilization==1 || stabilization==2){
+			for(int i=0;i<dim*dim;i++) D[i]=D_scalar*D[i];
+			TripleMultiply(Bprime,dim,numnodes,1,
+						D,dim,dim,0,
+						Bprime,dim,numnodes,0,
+						&Ke->values[0],1);
+		}
+	}
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(basis);
+	xDelete<IssmDouble>(B);
+	xDelete<IssmDouble>(Bprime);
+	xDelete<IssmDouble>(D);
+	delete gauss;
+	if(domaintype!=Domain2DhorizontalEnum){topelement->DeleteMaterials(); delete topelement;};
+	return Ke;
+}/*}}}*/
+ElementVector* FreeSurfaceTopAnalysis::CreatePVector(Element* element){/*{{{*/
+	/*Intermediaries*/
+	int         domaintype,dim;
+	IssmDouble  Jdet,dt;
+	IssmDouble  ms,surface,vz;
+	Element*    topelement = NULL;
+	IssmDouble *xyz_list  = NULL;
+
+	/*Get top element*/
+	element->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DhorizontalEnum:
+			topelement = element;
+			dim = 2;
+			break;
+		case Domain2DverticalEnum:
+			if(!element->IsOnSurface()) return NULL;
+			topelement = element->SpawnTopElement();
+			dim = 1;
+			break;
+		case Domain3DEnum:
+			if(!element->IsOnSurface()) return NULL;
+			topelement = element->SpawnTopElement();
+			dim = 2;
+			break;
+		default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
+	}
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = topelement->GetNumberOfNodes();
+
+	/*Initialize Element vector and other vectors*/
+	ElementVector* pe    = topelement->NewElementVector();
+	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	topelement->GetVerticesCoordinates(&xyz_list);
+	topelement->FindParam(&dt,TimesteppingTimeStepEnum);
+	Input* ms_input      = topelement->GetInput(SurfaceforcingsMassBalanceEnum);  _assert_(ms_input);
+	Input* surface_input = topelement->GetInput(SurfaceEnum);                     _assert_(surface_input);
+	Input* vz_input      = NULL;
+	switch(dim){
+		case 1: vz_input = topelement->GetInput(VyEnum); _assert_(vz_input); break;
+		case 2: vz_input = topelement->GetInput(VzEnum); _assert_(vz_input); break;
+		default: _error_("not implemented");
+	}
+
+	/*Initialize mb_correction to 0, do not forget!:*/
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=topelement->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		topelement->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		topelement->NodalFunctions(basis,gauss);
+
+		ms_input->GetInputValue(&ms,gauss);
+		vz_input->GetInputValue(&vz,gauss);
+		surface_input->GetInputValue(&surface,gauss);
+
+		for(int i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*(surface + dt*ms + dt*vz)*basis[i];
+	}
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(basis);
+	delete gauss;
+	if(domaintype!=Domain2DhorizontalEnum){topelement->DeleteMaterials(); delete topelement;};
+	return pe;
+
+}/*}}}*/
+void FreeSurfaceTopAnalysis::GetB(IssmDouble* B,Element* element,int dim,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
+	/*Compute B  matrix. B=[B1 B2 B3] where Bi is of size 3*NDOF2. 
+	 * For node i, Bi can be expressed in the actual coordinate system
+	 * by: 
+	 *       Bi=[ N ]
+	 *          [ N ]
+	 * where N is the finiteelement function for node i.
+	 *
+	 * We assume B_prog has been allocated already, of size: 2x(NDOF1*numnodes)
+	 */
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Get nodal functions*/
+	IssmDouble* basis=xNew<IssmDouble>(numnodes);
+	element->NodalFunctions(basis,gauss);
+
+	/*Build B: */
+	for(int i=0;i<numnodes;i++){
+		for(int j=0;j<dim;j++){
+			B[numnodes*j+i] = basis[i];
+		}
+	}
+
+	/*Clean-up*/
+	xDelete<IssmDouble>(basis);
+}/*}}}*/
+void FreeSurfaceTopAnalysis::GetBprime(IssmDouble* Bprime,Element* element,int dim,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
+	/*Compute B'  matrix. B'=[B1' B2' B3'] where Bi' is of size 3*NDOF2. 
+	 * For node i, Bi' can be expressed in the actual coordinate system
+	 * by: 
+	 *       Bi_prime=[ dN/dx ]
+	 *                [ dN/dy ]
+	 * where N is the finiteelement function for node i.
+	 *
+	 * We assume B' has been allocated already, of size: 3x(NDOF2*numnodes)
+	 */
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Get nodal functions derivatives*/
+	IssmDouble* dbasis=xNew<IssmDouble>(dim*numnodes);
+	element->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+
+	/*Build B': */
+	for(int i=0;i<numnodes;i++){
+		for(int j=0;j<dim;j++){
+			Bprime[numnodes*j+i] = dbasis[j*numnodes+i];
+		}
+	}
+
+	/*Clean-up*/
+	xDelete<IssmDouble>(dbasis);
+
+}/*}}}*/
+void FreeSurfaceTopAnalysis::GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element){/*{{{*/
+	   _error_("not implemented yet");
+}/*}}}*/
+void FreeSurfaceTopAnalysis::InputUpdateFromSolution(IssmDouble* solution,Element* element){/*{{{*/
+
+	element->InputUpdateFromSolutionOneDof(solution,SurfaceEnum);
+}/*}}}*/
+void FreeSurfaceTopAnalysis::UpdateConstraints(FemModel* femmodel){/*{{{*/
+	/*Default, do nothing*/
+	return;
+}/*}}}*/
Index: /issm/trunk/src/c/analyses/FreeSurfaceTopAnalysis.h
===================================================================
--- /issm/trunk/src/c/analyses/FreeSurfaceTopAnalysis.h	(revision 17805)
+++ /issm/trunk/src/c/analyses/FreeSurfaceTopAnalysis.h	(revision 17806)
@@ -12,5 +12,6 @@
 
 	public:
-		int  DofsPerNode(int** doflist,int meshtype,int approximation);
+		/*Model processing*/
+		int  DofsPerNode(int** doflist,int domaintype,int approximation);
 		void UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum);
 		void UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);
@@ -18,4 +19,16 @@
 		void CreateConstraints(Constraints* constraints,IoModel* iomodel);
 		void CreateLoads(Loads* loads, IoModel* iomodel);
+
+		/*Finite element Analysis*/
+		void           Core(FemModel* femmodel);
+		ElementVector* CreateDVector(Element* element);
+		ElementMatrix* CreateJacobianMatrix(Element* element);
+		ElementMatrix* CreateKMatrix(Element* element);
+		ElementVector* CreatePVector(Element* element);
+		void GetB(IssmDouble* B,Element* element,int dim,IssmDouble* xyz_list,Gauss* gauss);
+		void GetBprime(IssmDouble* B,Element* element,int dim,IssmDouble* xyz_list,Gauss* gauss);
+		void GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element);
+		void InputUpdateFromSolution(IssmDouble* solution,Element* element);
+		void UpdateConstraints(FemModel* femmodel);
 };
 #endif
Index: /issm/trunk/src/c/analyses/GiaAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/GiaAnalysis.cpp	(revision 17805)
+++ /issm/trunk/src/c/analyses/GiaAnalysis.cpp	(revision 17806)
@@ -6,5 +6,5 @@
 
 /*Model processing*/
-int  GiaAnalysis::DofsPerNode(int** doflist,int meshtype,int approximation){/*{{{*/
+int  GiaAnalysis::DofsPerNode(int** doflist,int domaintype,int approximation){/*{{{*/
 	return 1;
 }/*}}}*/
@@ -36,2 +36,30 @@
 	/*No loads*/
 }/*}}}*/
+
+/*Finite Element Analysis*/
+void           GiaAnalysis::Core(FemModel* femmodel){/*{{{*/
+	_error_("not implemented");
+}/*}}}*/
+ElementVector* GiaAnalysis::CreateDVector(Element* element){/*{{{*/
+	/*Default, return NULL*/
+	return NULL;
+}/*}}}*/
+ElementMatrix* GiaAnalysis::CreateJacobianMatrix(Element* element){/*{{{*/
+_error_("Not implemented");
+}/*}}}*/
+ElementMatrix* GiaAnalysis::CreateKMatrix(Element* element){/*{{{*/
+	_error_("not implemented yet");
+}/*}}}*/
+ElementVector* GiaAnalysis::CreatePVector(Element* element){/*{{{*/
+_error_("not implemented yet");
+}/*}}}*/
+void GiaAnalysis::GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element){/*{{{*/
+	   _error_("not implemented yet");
+}/*}}}*/
+void GiaAnalysis::InputUpdateFromSolution(IssmDouble* solution,Element* element){/*{{{*/
+	_error_("not implemented yet");
+}/*}}}*/
+void GiaAnalysis::UpdateConstraints(FemModel* femmodel){/*{{{*/
+	/*Default, do nothing*/
+	return;
+}/*}}}*/
Index: /issm/trunk/src/c/analyses/GiaAnalysis.h
===================================================================
--- /issm/trunk/src/c/analyses/GiaAnalysis.h	(revision 17805)
+++ /issm/trunk/src/c/analyses/GiaAnalysis.h	(revision 17806)
@@ -12,5 +12,6 @@
 
 	public:
-		int  DofsPerNode(int** doflist,int meshtype,int approximation);
+		/*Model processing*/
+		int  DofsPerNode(int** doflist,int domaintype,int approximation);
 		void UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum);
 		void UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);
@@ -18,4 +19,14 @@
 		void CreateConstraints(Constraints* constraints,IoModel* iomodel);
 		void CreateLoads(Loads* loads, IoModel* iomodel);
+
+		/*Finite element Analysis*/
+		void           Core(FemModel* femmodel);
+		ElementVector* CreateDVector(Element* element);
+		ElementMatrix* CreateJacobianMatrix(Element* element);
+		ElementMatrix* CreateKMatrix(Element* element);
+		ElementVector* CreatePVector(Element* element);
+		void GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element);
+		void InputUpdateFromSolution(IssmDouble* solution,Element* element);
+		void UpdateConstraints(FemModel* femmodel);
 };
 #endif
Index: /issm/trunk/src/c/analyses/HydrologyDCEfficientAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/HydrologyDCEfficientAnalysis.cpp	(revision 17805)
+++ /issm/trunk/src/c/analyses/HydrologyDCEfficientAnalysis.cpp	(revision 17806)
@@ -6,5 +6,5 @@
 
 /*Model processing*/
-int  HydrologyDCEfficientAnalysis::DofsPerNode(int** doflist,int meshtype,int approximation){/*{{{*/
+int  HydrologyDCEfficientAnalysis::DofsPerNode(int** doflist,int domaintype,int approximation){/*{{{*/
 	return 1;
 }/*}}}*/
@@ -48,13 +48,17 @@
 		}
 	}
-
 	iomodel->FetchDataToInput(elements,ThicknessEnum);
-	iomodel->FetchDataToInput(elements,SurfaceEnum);
-	iomodel->FetchDataToInput(elements,BedEnum);
+	iomodel->FetchDataToInput(elements,BaseEnum);
 	iomodel->FetchDataToInput(elements,MaskIceLevelsetEnum);
-	iomodel->FetchDataToInput(elements,MeshElementonbedEnum);
-	iomodel->FetchDataToInput(elements,MeshElementonsurfaceEnum);
-	iomodel->FetchDataToInput(elements,BasalforcingsMeltingRateEnum);
 	iomodel->FetchDataToInput(elements,EplHeadEnum);
+	iomodel->FetchDataToInput(elements,SedimentHeadEnum);
+	iomodel->FetchDataToInput(elements,HydrologydcEplInitialThicknessEnum);
+	iomodel->FetchDataToInput(elements,HydrologydcEplMaxThicknessEnum);
+	iomodel->FetchDataToInput(elements,HydrologydcSedimentTransmitivityEnum);
+	iomodel->FetchDataToInput(elements,HydrologydcEplThicknessEnum);
+	if(iomodel->domaintype==Domain3DEnum) iomodel->FetchDataToInput(elements,MeshElementonbaseEnum);
+	
+	//	elements->InputDuplicate(HydrologydcEplInitialThicknessEnum,HydrologydcEplThicknessEnum);
+
 }/*}}}*/
 void HydrologyDCEfficientAnalysis::CreateNodes(Nodes* nodes,IoModel* iomodel){/*{{{*/
@@ -70,7 +74,7 @@
 	if(!isefficientlayer) return;
 
-	iomodel->FetchData(3,MeshVertexonbedEnum,MeshVertexonsurfaceEnum,FlowequationVertexEquationEnum);
+	if(iomodel->domaintype!=Domain2DhorizontalEnum) iomodel->FetchData(2,MeshVertexonbaseEnum,MeshVertexonsurfaceEnum);
 	::CreateNodes(nodes,iomodel,HydrologyDCEfficientAnalysisEnum,P1Enum);
-	iomodel->DeleteData(3,MeshVertexonbedEnum,MeshVertexonsurfaceEnum,FlowequationVertexEquationEnum);
+	iomodel->DeleteData(2,MeshVertexonbaseEnum,MeshVertexonsurfaceEnum);
 }/*}}}*/
 void HydrologyDCEfficientAnalysis::CreateConstraints(Constraints* constraints,IoModel* iomodel){/*{{{*/
@@ -90,15 +94,665 @@
 }/*}}}*/
 void HydrologyDCEfficientAnalysis::CreateLoads(Loads* loads, IoModel* iomodel){/*{{{*/
-
-	/*Do we really want DC?*/
-	int  hydrology_model;
-	iomodel->Constant(&hydrology_model,HydrologyModelEnum);
-	if(hydrology_model!=HydrologydcEnum) return;
-
-	/*Do we want an efficient layer*/
-	bool isefficientlayer;
-	iomodel->Constant(&isefficientlayer,HydrologydcIsefficientlayerEnum);
-	if(!isefficientlayer) return;
-
 	/*Nothing for now*/
 }/*}}}*/
+
+/*Finite Element Analysis*/
+void HydrologyDCEfficientAnalysis::Core(FemModel* femmodel){/*{{{*/
+	_error_("not implemented");
+}/*}}}*/
+ElementVector* HydrologyDCEfficientAnalysis::CreateDVector(Element* element){/*{{{*/
+	/*Default, return NULL*/
+	return NULL;
+}/*}}}*/
+ElementMatrix* HydrologyDCEfficientAnalysis::CreateJacobianMatrix(Element* element){/*{{{*/
+_error_("Not implemented");
+}/*}}}*/
+ElementMatrix* HydrologyDCEfficientAnalysis::CreateKMatrix(Element* element){/*{{{*/
+
+	/*Intermediaries*/
+	bool     active_element;
+	int      domaintype;
+	Element* basalelement;
+
+	/*Get basal element*/
+	element->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DhorizontalEnum:
+			basalelement = element;
+			break;
+		case Domain3DEnum:
+			if(!element->IsOnBase()) return NULL;
+			basalelement = element->SpawnBasalElement();
+			break;
+		default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
+	}
+
+	Input* active_element_input = basalelement->GetInput(HydrologydcMaskEplactiveEltEnum); _assert_(active_element_input);
+	active_element_input->GetInputValue(&active_element);
+
+	/*Check that all nodes are active, else return empty matrix*/
+	if(!active_element) {
+	if(domaintype!=Domain2DhorizontalEnum){
+			basalelement->DeleteMaterials(); 
+			delete basalelement;
+		}
+		return NULL;
+	}
+	/* Intermediaries */
+	IssmDouble  D_scalar,Jdet,dt;
+	IssmDouble  epl_thickness;
+	IssmDouble  transfer;
+	IssmDouble *xyz_list = NULL;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = basalelement->GetNumberOfNodes();
+
+	/*Initialize Element vector*/
+	ElementMatrix* Ke     = basalelement->NewElementMatrix();
+	IssmDouble*    B      = xNew<IssmDouble>(2*numnodes);
+	IssmDouble*    basis  = xNew<IssmDouble>(numnodes);
+	IssmDouble     D[2][2]={0.};
+
+	/*Retrieve all inputs and parameters*/
+	basalelement->GetVerticesCoordinates(&xyz_list);
+	basalelement->FindParam(&dt,TimesteppingTimeStepEnum);
+	Input* thickness_input = basalelement->GetInput(HydrologydcEplThicknessEnum);          _assert_(thickness_input);
+	Input* sed_head_input  = basalelement->GetInput(SedimentHeadEnum);
+	Input* epl_head_input  = basalelement->GetInput(EplHeadEnum);
+	Input* sed_trans_input = basalelement->GetInput(HydrologydcSedimentTransmitivityEnum);
+	Input* residual_input  = basalelement->GetInput(SedimentHeadResidualEnum);
+
+	IssmDouble epl_specificstoring   = EplSpecificStoring(basalelement);
+	IssmDouble epl_conductivity      = basalelement->GetMaterialParameter(HydrologydcEplConductivityEnum);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=basalelement->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss           ->GaussPoint(ig);
+		basalelement    ->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		thickness_input ->GetInputValue(&epl_thickness,gauss);
+
+		/*Diffusivity*/
+		D_scalar=epl_conductivity*epl_thickness*gauss->weight*Jdet;
+		if(dt!=0.) D_scalar=D_scalar*dt;
+		D[0][0]=D_scalar;
+		D[1][1]=D_scalar;
+		GetB(B,basalelement,xyz_list,gauss); 
+		TripleMultiply(B,2,numnodes,1,
+					&D[0][0],2,2,0,
+					B,2,numnodes,0,
+					&Ke->values[0],1);
+
+		/*Transient*/
+		if(dt!=0.){
+			basalelement->NodalFunctions(&basis[0],gauss);
+			D_scalar=epl_specificstoring*epl_thickness*gauss->weight*Jdet;
+			TripleMultiply(basis,numnodes,1,0,
+						&D_scalar,1,1,0,
+						basis,1,numnodes,0,
+						&Ke->values[0],1);
+			
+			/*Transfer EPL part*/
+			transfer=GetHydrologyKMatrixTransfer(basalelement,gauss,thickness_input,sed_head_input,epl_head_input,sed_trans_input,residual_input);
+			D_scalar=transfer*gauss->weight*Jdet*dt;
+			TripleMultiply(basis,numnodes,1,0,
+										 &D_scalar,1,1,0,
+										 basis,1,numnodes,0,
+										 &Ke->values[0],1);
+		}
+	}
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(basis);
+	xDelete<IssmDouble>(B);
+	delete gauss;
+	if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;};
+	return Ke;
+
+}/*}}}*/
+ElementVector* HydrologyDCEfficientAnalysis::CreatePVector(Element* element){/*{{{*/
+
+	/*Intermediaries*/
+	bool     active_element;
+	int      domaintype;
+	Element* basalelement;
+
+	/*Get basal element*/
+	element->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DhorizontalEnum:
+			basalelement = element;
+			break;
+		case Domain3DEnum:
+			if(!element->IsOnBase()) return NULL;
+			basalelement = element->SpawnBasalElement();
+			break;
+		default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
+	}
+
+	Input* active_element_input = basalelement->GetInput(HydrologydcMaskEplactiveEltEnum); _assert_(active_element_input);
+	active_element_input->GetInputValue(&active_element);
+
+	/*Check that all nodes are active, else return empty matrix*/
+	if(!active_element) {
+	if(domaintype!=Domain2DhorizontalEnum){
+			basalelement->DeleteMaterials(); 
+			delete basalelement;
+		}
+		return NULL;
+	}
+	/*Intermediaries */
+	IssmDouble dt,scalar,water_head;
+	IssmDouble transfer;
+	IssmDouble epl_thickness;
+	IssmDouble Jdet;
+	IssmDouble residual,connectivity;
+
+	IssmDouble *xyz_list     = NULL;
+	Input*      old_wh_input = NULL;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes    = basalelement->GetNumberOfNodes();
+	int numvertices = basalelement->GetNumberOfVertices();
+
+	/*Initialize Element vector*/
+	ElementVector* pe    = basalelement->NewElementVector();
+	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	basalelement->GetVerticesCoordinates(&xyz_list);
+	basalelement->FindParam(&dt,TimesteppingTimeStepEnum);	
+
+	Input* thickness_input = basalelement->GetInput(HydrologydcEplThicknessEnum); _assert_(thickness_input);
+	Input* sed_head_input  = basalelement->GetInput(SedimentHeadEnum);
+	Input* epl_head_input  = basalelement->GetInput(EplHeadEnum);
+	Input* sed_trans_input = basalelement->GetInput(HydrologydcSedimentTransmitivityEnum);
+	Input* residual_input  = basalelement->GetInput(SedimentHeadResidualEnum);    _assert_(residual_input);
+	if(dt!= 0.){old_wh_input = basalelement->GetInput(EplHeadOldEnum);            _assert_(old_wh_input);}
+
+	IssmDouble epl_specificstoring = EplSpecificStoring(basalelement);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=basalelement->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		basalelement ->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		basalelement ->NodalFunctions(basis,gauss);
+
+		/*Transient and transfer terms*/
+		if(dt!=0.){
+			old_wh_input    ->GetInputValue(&water_head,gauss);
+			thickness_input ->GetInputValue(&epl_thickness,gauss);
+			
+			/*Dealing with the sediment part of the transfer term*/
+			transfer=GetHydrologyPVectorTransfer(basalelement,gauss,thickness_input,sed_head_input,epl_head_input,sed_trans_input,residual_input);
+			scalar = Jdet*gauss->weight*((water_head*epl_specificstoring*epl_thickness)+(transfer*dt));
+			for(int i=0;i<numnodes;i++)pe->values[i]+=scalar*basis[i];
+		}
+	}
+	delete gauss;
+
+	/*	Add residual if necessary*/
+	gauss=basalelement->NewGauss();
+	for(int iv=0;iv<numvertices;iv++){
+		gauss->GaussVertex(iv);
+
+		connectivity = IssmDouble(basalelement->VertexConnectivity(iv));
+		residual_input->GetInputValue(&residual,gauss);
+		pe->values[iv]+=residual/connectivity;
+
+	}
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(basis);
+	delete gauss;
+	if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;};
+	return pe;
+}/*}}}*/
+void HydrologyDCEfficientAnalysis::GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element){/*{{{*/
+	element->GetSolutionFromInputsOneDof(solution,EplHeadEnum);
+}/*}}}*/
+void HydrologyDCEfficientAnalysis::InputUpdateFromSolution(IssmDouble* solution,Element* element){/*{{{*/
+
+	int domaintype,i;
+	Element*   basalelement=NULL;
+
+	element->FindParam(&domaintype,DomainTypeEnum);
+
+	if(domaintype!=Domain2DhorizontalEnum){
+		if(!element->IsOnBase()) return;
+		basalelement=element->SpawnBasalElement();
+	}
+	else{
+		basalelement = element;
+	}
+	
+	/*Intermediary*/
+	int* doflist = NULL;
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = basalelement->GetNumberOfNodes();
+
+	/*Fetch dof list and allocate solution vector*/
+	basalelement->GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
+	IssmDouble* eplHeads    = xNew<IssmDouble>(numnodes);
+
+	/*Use the dof list to index into the solution vector: */
+	for(i=0;i<numnodes;i++){
+		eplHeads[i]=solution[doflist[i]];
+		if(xIsNan<IssmDouble>(eplHeads[i])) _error_("NaN found in solution vector");
+	}
+	/*Add input to the element: */
+	element->AddBasalInput(EplHeadEnum,eplHeads,P1Enum);
+
+	/*Free ressources:*/
+	xDelete<IssmDouble>(eplHeads);
+	xDelete<int>(doflist);
+	if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;};
+} /*}}}*/
+void HydrologyDCEfficientAnalysis::UpdateConstraints(FemModel* femmodel){/*{{{*/
+	/*Default, do nothing*/
+	return;
+}/*}}}*/
+
+/*Intermediaries*/
+IssmDouble HydrologyDCEfficientAnalysis::EplSpecificStoring(Element* element){/*{{{*/
+	IssmDouble rho_freshwater        = element->GetMaterialParameter(MaterialsRhoFreshwaterEnum);
+	IssmDouble g                     = element->GetMaterialParameter(ConstantsGEnum);
+	IssmDouble epl_porosity          = element->GetMaterialParameter(HydrologydcEplPorosityEnum);
+	IssmDouble epl_compressibility   = element->GetMaterialParameter(HydrologydcEplCompressibilityEnum);
+	IssmDouble water_compressibility = element->GetMaterialParameter(HydrologydcWaterCompressibilityEnum);
+	return rho_freshwater*g*epl_porosity*(water_compressibility+(epl_compressibility/epl_porosity));		 
+}/*}}}*/
+IssmDouble HydrologyDCEfficientAnalysis::SedimentStoring(Element* element){/*{{{*/
+	IssmDouble rho_freshwater           = element->GetMaterialParameter(MaterialsRhoFreshwaterEnum);
+	IssmDouble g                        = element->GetMaterialParameter(ConstantsGEnum);
+	IssmDouble sediment_porosity        = element->GetMaterialParameter(HydrologydcSedimentPorosityEnum);
+	IssmDouble sediment_thickness       = element->GetMaterialParameter(HydrologydcSedimentThicknessEnum);
+	IssmDouble sediment_compressibility = element->GetMaterialParameter(HydrologydcSedimentCompressibilityEnum);
+	IssmDouble water_compressibility    = element->GetMaterialParameter(HydrologydcWaterCompressibilityEnum);
+	return rho_freshwater*g*sediment_porosity*sediment_thickness*(water_compressibility+(sediment_compressibility/sediment_porosity));		 
+}/*}}}*/
+IssmDouble HydrologyDCEfficientAnalysis::GetHydrologyKMatrixTransfer(Element* element, Gauss* gauss, Input* epl_thick_input, Input* sed_head_input, Input* epl_head_input, Input* sed_trans_input, Input* residual_input){/*{{{*/
+	
+	int transfermethod;
+	IssmDouble epl_thickness;
+	IssmDouble epl_head,sed_head;
+	IssmDouble sediment_transmitivity;
+	IssmDouble leakage,residual,transfer;
+
+	IssmDouble sediment_thickness  = element->GetMaterialParameter(HydrologydcSedimentThicknessEnum);
+	IssmDouble sediment_storing    = SedimentStoring(element);
+ 	IssmDouble epl_specificstoring = EplSpecificStoring(element);		
+
+	element->FindParam(&transfermethod,HydrologydcTransferFlagEnum);
+	/*Switch between the different transfer methods cases*/
+	switch(transfermethod){
+	case 0:
+		/*Just keepping the transfer to zero*/
+		transfer=0.0;
+		break;
+	case 1:
+		_assert_(epl_thick_input); 
+		_assert_(sed_head_input); 
+		_assert_(epl_head_input); 
+		_assert_(sed_trans_input); 
+		_assert_(residual_input); 
+		/* get input */
+		epl_thick_input->GetInputValue(&epl_thickness,gauss);
+		sed_head_input->GetInputValue(&sed_head,gauss);
+		epl_head_input->GetInputValue(&epl_head,gauss);
+		sed_trans_input->GetInputValue(&sediment_transmitivity,gauss);
+		residual_input->GetInputValue(&residual,gauss);
+		element->FindParam(&leakage,HydrologydcLeakageFactorEnum);
+
+		if(epl_head>sed_head){
+			if(residual>0.0){	
+				transfer=0.0;
+			}
+			else{
+				transfer=(epl_specificstoring*epl_thickness*sediment_transmitivity)/(sediment_thickness*leakage);
+			}
+		}
+		else{
+			transfer=(sediment_storing*sediment_transmitivity)/(sediment_thickness*leakage);
+		}
+		break;
+	default:
+		_error_("no case higher than 1 for the Transfer method");
+	}
+	
+	return transfer;
+}/*}}}*/
+IssmDouble HydrologyDCEfficientAnalysis::GetHydrologyPVectorTransfer(Element* element, Gauss* gauss, Input* epl_thick_input, Input* sed_head_input, Input* epl_head_input, Input* sed_trans_input, Input* residual_input){/*{{{*/
+
+	int transfermethod;
+	IssmDouble epl_thickness;
+	IssmDouble epl_head,sediment_head;
+	IssmDouble sediment_transmitivity;
+	IssmDouble leakage,residual,transfer;
+
+	IssmDouble sediment_thickness = element->GetMaterialParameter(HydrologydcSedimentThicknessEnum);
+	IssmDouble sediment_storing   = SedimentStoring(element);
+ 	IssmDouble epl_specificstoring = EplSpecificStoring(element);		
+
+	element->FindParam(&transfermethod,HydrologydcTransferFlagEnum);
+	/*Switch between the different transfer methods cases*/
+	switch(transfermethod){
+	case 0:
+		/*Just keepping the transfer to zero*/
+		transfer=0.0;
+		break;
+	case 1:
+		_assert_(epl_thick_input); 
+		_assert_(sed_head_input); 
+		_assert_(epl_head_input); 
+		_assert_(sed_trans_input); 
+		_assert_(residual_input); 
+		/* get input */
+		epl_thick_input->GetInputValue(&epl_thickness,gauss);
+		sed_head_input->GetInputValue(&sediment_head,gauss);
+		epl_head_input->GetInputValue(&epl_head,gauss);
+		sed_trans_input->GetInputValue(&sediment_transmitivity,gauss);
+		residual_input->GetInputValue(&residual,gauss);
+		element->FindParam(&leakage,HydrologydcLeakageFactorEnum);
+		
+		if(epl_head>sediment_head){
+			if(residual>0.0){	
+				transfer=0.0;
+			}
+			else{
+				transfer=(epl_specificstoring*epl_thickness*sediment_transmitivity*sediment_head)/(sediment_thickness*leakage);
+			}
+		}
+		else{
+			transfer=(sediment_storing*sediment_transmitivity*sediment_head)/(sediment_thickness*leakage);
+		}
+		break;
+	default:
+		_error_("no case higher than 1 for the Transfer method");
+	}
+	return transfer;
+}/*}}}*/
+
+void HydrologyDCEfficientAnalysis::ComputeEPLThickness(FemModel* femmodel){/*{{{*/
+
+	bool        active_element;
+	int         domaintype;
+	IssmDouble  dt,A,B;
+	IssmDouble  EPLgrad2;
+	IssmDouble  EPL_N;
+
+	femmodel->parameters->FindParam(&domaintype,DomainTypeEnum);
+
+	for(int j=0;j<femmodel->elements->Size();j++){
+		
+		Element* element=(Element*)femmodel->elements->GetObjectByOffset(j);
+		
+		switch(domaintype){
+		case Domain2DhorizontalEnum:
+			if(!element->IsOnBase()) return;			
+			B = element->GetMaterialParameter(MaterialsRheologyBbarEnum);
+			break;
+		case Domain3DEnum:
+			B = element->GetMaterialParameter(MaterialsRheologyBEnum);
+			break;
+		default:
+		_error_("not Implemented Yet");
+		}
+			
+		int         numnodes      = element->GetNumberOfNodes();
+		IssmDouble* thickness     = xNew<IssmDouble>(numnodes);
+		IssmDouble* eplhead       = xNew<IssmDouble>(numnodes);
+		IssmDouble* epl_slopeX    = xNew<IssmDouble>(numnodes);
+		IssmDouble* epl_slopeY    = xNew<IssmDouble>(numnodes);
+		IssmDouble* old_thickness = xNew<IssmDouble>(numnodes);
+		IssmDouble* ice_thickness = xNew<IssmDouble>(numnodes);
+		IssmDouble* bed           = xNew<IssmDouble>(numnodes);
+
+		Input* 	active_element_input=element->GetInput(HydrologydcMaskEplactiveEltEnum); _assert_(active_element_input);		
+		active_element_input->GetInputValue(&active_element);
+		element->FindParam(&dt,TimesteppingTimeStepEnum);
+	
+		/*For now, assuming just one way to compute EPL thickness*/
+		IssmDouble gravity          = element->GetMaterialParameter(ConstantsGEnum);
+		IssmDouble rho_water        = element->GetMaterialParameter(MaterialsRhoFreshwaterEnum);
+		IssmDouble rho_ice          = element->GetMaterialParameter(MaterialsRhoIceEnum);
+		IssmDouble n                =	element->GetMaterialParameter(MaterialsRheologyNEnum);
+		IssmDouble latentheat       = element->GetMaterialParameter(MaterialsLatentheatEnum);
+		IssmDouble epl_conductivity = element->GetMaterialParameter(HydrologydcEplConductivityEnum);
+		IssmDouble init_thick       =	element->GetMaterialParameter(HydrologydcEplInitialThicknessEnum);
+		IssmDouble max_thick        =	element->GetMaterialParameter(HydrologydcEplMaxThicknessEnum);
+		
+		A=pow(B,-n);
+		
+		element->GetInputListOnVertices(&eplhead[0],EplHeadEnum);
+		element->GetInputListOnVertices(&epl_slopeX[0],EplHeadSlopeXEnum); 
+		element->GetInputListOnVertices(&epl_slopeY[0],EplHeadSlopeYEnum);
+		element->GetInputListOnVertices(&old_thickness[0],HydrologydcEplThicknessOldEnum);
+		element->GetInputListOnVertices(&ice_thickness[0],ThicknessEnum);
+		element->GetInputListOnVertices(&bed[0],BaseEnum);
+			
+		if(!active_element){
+			
+			/*Keeping thickness to initial value if EPL is not active*/
+			for(int i=0;i<numnodes;i++){
+				thickness[i]=init_thick;
+			}
+		}
+		else{
+			for(int i=0;i<numnodes;i++){
+				
+				/*Compute first the effective pressure in the EPL*/
+				EPL_N=gravity*((rho_ice*ice_thickness[i])-(rho_water*(eplhead[i]-bed[i])));
+				if(EPL_N<0.0)EPL_N=0.0;
+				/*Get then the square of the gradient of EPL heads*/
+				EPLgrad2 = (epl_slopeX[i]*epl_slopeX[i]+epl_slopeY[i]*epl_slopeY[i]);
+				
+				/*And proceed to the real thing*/
+				thickness[i] = old_thickness[i]*(1+((rho_water*gravity*dt)/(rho_ice*latentheat))*epl_conductivity*EPLgrad2-2.0*(A*dt/(pow(n,n)))*(pow(EPL_N,n)));
+				
+				/*Take care of otherthikening*/
+				if(thickness[i]>max_thick){
+					thickness[i] = max_thick;
+				}
+			}
+		}
+		element->AddInput(HydrologydcEplThicknessEnum,thickness,element->GetElementType());
+		xDelete<IssmDouble>(thickness);
+		xDelete<IssmDouble>(eplhead);
+		xDelete<IssmDouble>(epl_slopeX);
+		xDelete<IssmDouble>(epl_slopeY);
+		xDelete<IssmDouble>(old_thickness);
+		xDelete<IssmDouble>(ice_thickness);
+		xDelete<IssmDouble>(bed);
+	}
+}
+/*}}}*/
+void HydrologyDCEfficientAnalysis::GetB(IssmDouble* B,Element* element,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
+	/*Compute B  matrix. B=[B1 B2 B3] where Bi is of size 3*NDOF2. 
+	 * For node i, Bi can be expressed in the actual coordinate system
+	 * by: 
+	 *       Bi=[ dN/dx ]
+	 *          [ dN/dy ]
+	 * where N is the finiteelement function for node i.
+	 *
+	 * We assume B has been allocated already, of size: 3x(NDOF2*numnodes)
+	 */
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Get nodal functions derivatives*/
+	IssmDouble* dbasis=xNew<IssmDouble>(2*numnodes);
+	element->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+
+	/*Build B: */
+	for(int i=0;i<numnodes;i++){
+		B[numnodes*0+i] = dbasis[0*numnodes+i];
+		B[numnodes*1+i] = dbasis[1*numnodes+i];
+	}
+
+	/*Clean-up*/
+	xDelete<IssmDouble>(dbasis);
+}/*}}}*/
+void  HydrologyDCEfficientAnalysis::HydrologyEPLGetMask(Vector<IssmDouble>* vec_mask,Element* element){
+
+	bool        active_element;
+	int         i,j;
+	int         domaintype;
+	IssmDouble  h_max;
+	IssmDouble  sedheadmin;
+	Element*   basalelement=NULL;
+
+	/*Get basal element*/
+	element->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DhorizontalEnum:
+			basalelement = element;
+			break;
+		case Domain3DEnum:
+			if(!element->IsOnBase()) return;
+			basalelement = element->SpawnBasalElement();
+			break;
+		default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
+	}
+
+	/*Intermediaries*/
+
+	int         numnodes      =basalelement->GetNumberOfNodes();
+	IssmDouble* epl_thickness =xNew<IssmDouble>(numnodes);
+	IssmDouble* old_active    =xNew<IssmDouble>(numnodes);
+	IssmDouble* sedhead       =xNew<IssmDouble>(numnodes);
+	IssmDouble* eplhead       =xNew<IssmDouble>(numnodes);
+	IssmDouble* residual      =xNew<IssmDouble>(numnodes);
+
+	IssmDouble init_thick =	basalelement->GetMaterialParameter(HydrologydcEplInitialThicknessEnum);
+
+	Input* active_element_input=basalelement->GetInput(HydrologydcMaskEplactiveEltEnum); _assert_(active_element_input);
+	active_element_input->GetInputValue(&active_element);
+
+	basalelement-> GetInputListOnVertices(&old_active[0],HydrologydcMaskEplactiveNodeEnum);	
+	basalelement-> GetInputListOnVertices(&epl_thickness[0],HydrologydcEplThicknessEnum);	
+	basalelement-> GetInputListOnVertices(&sedhead[0],SedimentHeadEnum);
+	basalelement-> GetInputListOnVertices(&eplhead[0],EplHeadEnum);
+	basalelement-> GetInputListOnVertices(&residual[0],SedimentHeadResidualEnum);
+
+	/*Get minimum sediment head of the element*/
+	sedheadmin=sedhead[0];
+	for(i=1;i<numnodes;i++) if(sedhead[i]<=sedheadmin)sedheadmin=sedhead[i];
+
+	for(i=0;i<numnodes;i++){
+		/*Activate EPL if residual is >0 */
+		if(residual[i]>0.){
+			vec_mask->SetValue(basalelement->nodes[i]->Sid(),1.,INS_VAL);
+		}
+
+		/*If mask was already one, keep one*/
+		else if(old_active[i]>0.){
+			vec_mask->SetValue(basalelement->nodes[i]->Sid(),1.,INS_VAL);
+			/*If epl thickness gets under 10-3 initial thickness, close the layer*/
+			if(epl_thickness[i]<0.001*init_thick){
+				vec_mask->SetValue(basalelement->nodes[i]->Sid(),0.,INS_VAL);
+				epl_thickness[i]=init_thick;
+			}
+		}
+		/*Increase of the efficient system is needed if the epl head reach the maximum value (sediment max value for now)*/
+		GetHydrologyDCInefficientHmax(&h_max,basalelement,basalelement->nodes[i]);
+		if(eplhead[i]>=h_max && active_element){
+			for(j=0;j<numnodes;j++){
+				if(old_active[j]>0.){
+					vec_mask->SetValue(basalelement->nodes[i]->Sid(),1.,INS_VAL);
+				}
+				/*Increase of the domain is on the downstream node in term of sediment head*/
+				if(sedhead[j] == sedheadmin){
+					vec_mask->SetValue(basalelement->nodes[j]->Sid(),1.,INS_VAL);
+				}
+			}
+		}
+	}
+	if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;};
+	xDelete<IssmDouble>(epl_thickness);
+	xDelete<IssmDouble>(old_active);
+	xDelete<IssmDouble>(sedhead);
+	xDelete<IssmDouble>(eplhead);
+	xDelete<IssmDouble>(residual);
+}
+/*}}}*/
+void HydrologyDCEfficientAnalysis::HydrologyEPLGetActive(Vector<IssmDouble>* active_vec, Element* element){
+	/*Constants*/
+
+	int      domaintype;
+	Element*   basalelement=NULL;
+
+	/*Get basal element*/
+	element->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DhorizontalEnum:
+			basalelement = element;
+			break;
+		case Domain3DEnum:
+			if(!element->IsOnBase()) return;
+			basalelement = element->SpawnBasalElement();
+			break;
+		default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
+	}
+	
+	const int   numnodes = basalelement->GetNumberOfNodes();
+	IssmDouble  flag     = 0.;
+	IssmDouble* active   = xNew<IssmDouble>(numnodes);
+		
+	basalelement->GetInputListOnVertices(&active[0],HydrologydcMaskEplactiveNodeEnum);
+	
+	for(int i=0;i<numnodes;i++) flag+=active[i];
+
+	if(flag>0.){
+		for(int i=0;i<numnodes;i++){
+			active_vec->SetValue(basalelement->nodes[i]->Sid(),1.,INS_VAL);
+		}
+	}
+	else{
+		/*Do not do anything: at least one node is active for this element but this element is not solved for*/
+	}
+	if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;};
+	xDelete<IssmDouble>(active);
+}
+
+void HydrologyDCEfficientAnalysis::GetHydrologyDCInefficientHmax(IssmDouble* ph_max,Element* element, Node* innode){/*{{{*/
+	
+	int        hmax_flag;
+	IssmDouble h_max;
+	IssmDouble rho_ice,rho_water;
+	IssmDouble thickness,bed;
+	/*Get the flag to the limitation method*/
+	element->FindParam(&hmax_flag,HydrologydcSedimentlimitFlagEnum);
+	
+	/*Switch between the different cases*/
+	switch(hmax_flag){
+	case 0:
+		h_max=1.0e+10;
+		break;
+	case 1:
+		element->FindParam(&h_max,HydrologydcSedimentlimitEnum);
+		break;
+	case 2:
+		/*Compute max*/
+		rho_water = element->GetMaterialParameter(MaterialsRhoFreshwaterEnum);
+		rho_ice   = element->GetMaterialParameter(MaterialsRhoIceEnum);
+		element-> GetInputValue(&thickness,innode,ThicknessEnum);
+		element-> GetInputValue(&bed,innode,BaseEnum);
+		h_max=((rho_ice*thickness)/rho_water)+bed;
+		break;
+	case 3:
+		_error_("Using normal stress  not supported yet");
+		break;
+	default:
+		_error_("no case higher than 3 for SedimentlimitFlag");
+	}
+	/*Assign output pointer*/
+	*ph_max=h_max;
+}
+/*}}}*/
Index: /issm/trunk/src/c/analyses/HydrologyDCEfficientAnalysis.h
===================================================================
--- /issm/trunk/src/c/analyses/HydrologyDCEfficientAnalysis.h	(revision 17805)
+++ /issm/trunk/src/c/analyses/HydrologyDCEfficientAnalysis.h	(revision 17806)
@@ -8,9 +8,11 @@
 /*Headers*/
 #include "./Analysis.h"
-
+class Node;
+class Input;
 class HydrologyDCEfficientAnalysis: public Analysis{
 
 	public:
-		int  DofsPerNode(int** doflist,int meshtype,int approximation);
+		/*Model processing*/
+		int  DofsPerNode(int** doflist,int domaintype,int approximation);
 		void UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum);
 		void UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);
@@ -18,4 +20,25 @@
 		void CreateConstraints(Constraints* constraints,IoModel* iomodel);
 		void CreateLoads(Loads* loads, IoModel* iomodel);
+
+		/*Finite element Analysis*/
+		void           Core(FemModel* femmodel);
+		ElementVector* CreateDVector(Element* element);
+		ElementMatrix* CreateJacobianMatrix(Element* element);
+		ElementMatrix* CreateKMatrix(Element* element);
+		ElementVector* CreatePVector(Element* element);
+		void GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element);
+		void InputUpdateFromSolution(IssmDouble* solution,Element* element);
+		void UpdateConstraints(FemModel* femmodel);
+
+		/*Intermediaries*/
+		void GetB(IssmDouble* B,Element* element,IssmDouble* xyz_list,Gauss* gauss);
+		IssmDouble EplSpecificStoring(Element* element);
+		IssmDouble SedimentStoring(Element* element);
+		IssmDouble GetHydrologyKMatrixTransfer(Element* element, Gauss* gauss, Input* epl_thick_input, Input* sed_head_input, Input* epl_head_input, Input* sed_trans_input, Input* residual_input);
+		IssmDouble GetHydrologyPVectorTransfer(Element* element, Gauss* gauss, Input* epl_thick_input, Input* sed_head_input, Input* epl_head_input, Input* sed_trans_input, Input* residual_input);
+		void HydrologyEPLGetMask(Vector<IssmDouble>* vec_mask,Element* element);
+		void HydrologyEPLGetActive(Vector<IssmDouble>* active_vec, Element* element);
+		void GetHydrologyDCInefficientHmax(IssmDouble* ph_max,Element* element, Node* innode);
+		void ComputeEPLThickness(FemModel* femmodel);
 };
 #endif
Index: /issm/trunk/src/c/analyses/HydrologyDCInefficientAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/HydrologyDCInefficientAnalysis.cpp	(revision 17805)
+++ /issm/trunk/src/c/analyses/HydrologyDCInefficientAnalysis.cpp	(revision 17806)
@@ -2,9 +2,10 @@
 #include "../toolkits/toolkits.h"
 #include "../classes/classes.h"
+#include "../classes/Node.h"
 #include "../shared/shared.h"
 #include "../modules/modules.h"
 
 /*Model processing*/
-int  HydrologyDCInefficientAnalysis::DofsPerNode(int** doflist,int meshtype,int approximation){/*{{{*/
+int  HydrologyDCInefficientAnalysis::DofsPerNode(int** doflist,int domaintype,int approximation){/*{{{*/
 	return 1;
 }/*}}}*/
@@ -14,4 +15,6 @@
 	int         sedimentlimit_flag;
 	int         transfer_flag;
+	int         penalty_lock;
+	int         hydro_maxiter;
 	bool        isefficientlayer;
 	IssmDouble  sedimentlimit;
@@ -31,4 +34,6 @@
 	iomodel->FetchData(&penalty_factor,HydrologydcPenaltyFactorEnum);
 	iomodel->FetchData(&rel_tol,HydrologydcRelTolEnum);
+	iomodel->FetchData(&penalty_lock,HydrologydcPenaltyLockEnum);
+	iomodel->FetchData(&hydro_maxiter,HydrologydcMaxIterEnum);
 
 	if(sedimentlimit_flag==1){
@@ -48,4 +53,6 @@
 	parameters->AddObject(new IntParam(HydrologydcTransferFlagEnum,transfer_flag));
 	parameters->AddObject(new DoubleParam(HydrologydcRelTolEnum,rel_tol));
+	parameters->AddObject(new IntParam(HydrologydcPenaltyLockEnum,penalty_lock));
+	parameters->AddObject(new IntParam(HydrologydcMaxIterEnum,hydro_maxiter));
 
 }/*}}}*/
@@ -75,12 +82,13 @@
 
 	iomodel->FetchDataToInput(elements,ThicknessEnum);
-	iomodel->FetchDataToInput(elements,SurfaceEnum);
-	iomodel->FetchDataToInput(elements,BedEnum);
+	iomodel->FetchDataToInput(elements,BaseEnum);
 	iomodel->FetchDataToInput(elements,MaskIceLevelsetEnum);
-	iomodel->FetchDataToInput(elements,MeshElementonbedEnum);
-	iomodel->FetchDataToInput(elements,MeshElementonsurfaceEnum);
 	iomodel->FetchDataToInput(elements,BasalforcingsMeltingRateEnum);
+	iomodel->FetchDataToInput(elements,HydrologydcBasalMoulinInputEnum);
 	iomodel->FetchDataToInput(elements,SedimentHeadEnum);
-	if(isefficientlayer)iomodel->FetchDataToInput(elements,HydrologydcMaskEplactiveEnum);
+	iomodel->FetchDataToInput(elements,HydrologydcSedimentTransmitivityEnum);
+	if(iomodel->domaintype==Domain3DEnum) iomodel->FetchDataToInput(elements,MeshElementonbaseEnum);
+
+	if(isefficientlayer)iomodel->FetchDataToInput(elements,HydrologydcMaskEplactiveNodeEnum);
 }/*}}}*/
 void HydrologyDCInefficientAnalysis::CreateNodes(Nodes* nodes,IoModel* iomodel){/*{{{*/
@@ -93,7 +101,7 @@
 	if(hydrology_model!=HydrologydcEnum) return;
 
-	if(iomodel->meshtype==Mesh3DEnum) iomodel->FetchData(2,MeshVertexonbedEnum,MeshVertexonsurfaceEnum);
+	if(iomodel->domaintype!=Domain2DhorizontalEnum) iomodel->FetchData(2,MeshVertexonbaseEnum,MeshVertexonsurfaceEnum);
 	::CreateNodes(nodes,iomodel,HydrologyDCInefficientAnalysisEnum,P1Enum);
-	iomodel->DeleteData(2,MeshVertexonbedEnum,MeshVertexonsurfaceEnum);
+	iomodel->DeleteData(2,MeshVertexonbaseEnum,MeshVertexonsurfaceEnum);
 }/*}}}*/
 void HydrologyDCInefficientAnalysis::CreateConstraints(Constraints* constraints,IoModel* iomodel){/*{{{*/
@@ -113,10 +121,10 @@
 	if(hydrology_model!=HydrologydcEnum) return;
 
-	iomodel->FetchData(1,MeshVertexonbedEnum);
-
-	//create penalties for nodes: no node can have a temperature over the melting point
+	if(iomodel->domaintype==Domain3DEnum) iomodel->FetchData(1,MeshVertexonbaseEnum);
+
+	//create penalties for nodes: no node can have water above the max
 	CreateSingleNodeToElementConnectivity(iomodel);
 	for(int i=0;i<iomodel->numberofvertices;i++){
-		if (iomodel->meshtype==Mesh3DEnum){
+		if (iomodel->domaintype!=Domain3DEnum){
 			/*keep only this partition's nodes:*/
 			if(iomodel->my_vertices[i]){
@@ -124,5 +132,5 @@
 			}
 		}
-		else if(reCast<int>(iomodel->Data(MeshVertexonbedEnum)[i])){
+		else if(reCast<int>(iomodel->Data(MeshVertexonbaseEnum)[i])){
 			if(iomodel->my_vertices[i]){
 				loads->AddObject(new Pengrid(iomodel->loadcounter+i+1,i,iomodel,HydrologyDCInefficientAnalysisEnum));
@@ -130,4 +138,559 @@
 		}
 	}
-	iomodel->DeleteData(1,MeshVertexonbedEnum);
-}/*}}}*/
+	iomodel->DeleteData(1,MeshVertexonbaseEnum);
+}/*}}}*/
+
+/*Finite Element Analysis*/
+void           HydrologyDCInefficientAnalysis::Core(FemModel* femmodel){/*{{{*/
+	_error_("not implemented");
+}/*}}}*/
+ElementVector* HydrologyDCInefficientAnalysis::CreateDVector(Element* element){/*{{{*/
+	/*Default, return NULL*/
+	return NULL;
+}/*}}}*/
+ElementMatrix* HydrologyDCInefficientAnalysis::CreateJacobianMatrix(Element* element){/*{{{*/
+_error_("Not implemented");
+}/*}}}*/
+ElementMatrix* HydrologyDCInefficientAnalysis::CreateKMatrix(Element* element){/*{{{*/
+
+	/*Intermediaries*/
+	int      domaintype;
+	Element* basalelement;
+
+	/*Get basal element*/
+	element->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DhorizontalEnum:
+			basalelement = element;
+			break;
+		case Domain3DEnum:
+			if(!element->IsOnBase()) return NULL;
+			basalelement = element->SpawnBasalElement();
+			break;
+		default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
+	}
+
+	/*Intermediaries */
+	bool        active_element,isefficientlayer;
+	IssmDouble  D_scalar,Jdet,dt;
+	IssmDouble  sediment_transmitivity;
+	IssmDouble  transfer;
+	IssmDouble *xyz_list  = NULL;
+
+	/*Define transfer related variables*/
+	Input* active_element_input =NULL;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = basalelement->GetNumberOfNodes();
+
+	/*Initialize Element vector*/
+	ElementMatrix* Ke     = basalelement->NewElementMatrix();
+	IssmDouble*    B      = xNew<IssmDouble>(2*numnodes);
+	IssmDouble*    basis  = xNew<IssmDouble>(numnodes);
+	IssmDouble     D[2][2]= {0.};
+
+	/*Retrieve all inputs and parameters*/
+	basalelement ->GetVerticesCoordinates(&xyz_list);
+	basalelement ->FindParam(&dt,TimesteppingTimeStepEnum);
+	basalelement ->FindParam(&isefficientlayer,HydrologydcIsefficientlayerEnum);
+
+	Input* epl_thick_input   = basalelement->GetInput(HydrologydcEplThicknessEnum);
+	Input* sed_head_input    = basalelement->GetInput(SedimentHeadEnum);
+	Input* epl_head_input    = basalelement->GetInput(EplHeadEnum);
+	Input* thickness_input   = basalelement->GetInput(ThicknessEnum);
+	Input* base_input         = basalelement->GetInput(BaseEnum);
+	Input* SedTrans_input    = basalelement->GetInput(HydrologydcSedimentTransmitivityEnum); _assert_(SedTrans_input);
+	IssmDouble sediment_storing = SedimentStoring(basalelement);
+	/*Transfer related Inputs*/
+	if(isefficientlayer){
+		active_element_input = basalelement->GetInput(HydrologydcMaskEplactiveEltEnum); _assert_(active_element_input);
+	}
+	
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=basalelement->NewGauss(2);
+	for(int ig=gauss -> begin();ig<gauss->end();ig++){
+		gauss          -> GaussPoint(ig);
+		basalelement   -> JacobianDeterminant(&Jdet,xyz_list,gauss);
+		SedTrans_input -> GetInputValue(&sediment_transmitivity,gauss);
+		/*Diffusivity*/
+		D_scalar=sediment_transmitivity*gauss->weight*Jdet;
+		if(dt!=0.) D_scalar=D_scalar*dt;
+		D[0][0]=D_scalar;
+		D[1][1]=D_scalar;
+		GetB(B,basalelement,xyz_list,gauss); 
+		TripleMultiply(B,2,numnodes,1,
+									 &D[0][0],2,2,0,
+									 B,2,numnodes,0,
+									 &Ke->values[0],1);
+
+		/*Transient*/
+		if(dt!=0.){
+			basalelement->NodalFunctions(&basis[0],gauss);
+			D_scalar=sediment_storing*gauss->weight*Jdet;
+			TripleMultiply(basis,numnodes,1,0,
+										 &D_scalar,1,1,0,
+										 basis,1,numnodes,0,
+										 &Ke->values[0],1);
+			
+			/*Transfer EPL part*/
+			if(isefficientlayer){
+				active_element_input->GetInputValue(&active_element);
+				if(active_element){
+					transfer=GetHydrologyKMatrixTransfer(basalelement,gauss,epl_thick_input,sed_head_input,epl_head_input,SedTrans_input,thickness_input,base_input);
+					basalelement->NodalFunctions(&basis[0],gauss);
+					D_scalar=transfer*gauss->weight*Jdet*dt;
+					TripleMultiply(basis,numnodes,1,0,
+												 &D_scalar,1,1,0,
+												 basis,1,numnodes,0,
+												 &Ke->values[0],1);
+				}
+			}
+		}
+	}
+	/*Clean up and return*/
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(B);
+	xDelete<IssmDouble>(basis);
+	delete gauss;
+	if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;};
+	return Ke;
+}/*}}}*/
+ElementVector* HydrologyDCInefficientAnalysis::CreatePVector(Element* element){/*{{{*/
+
+	/*Intermediaries*/
+	int      domaintype;
+	Element* basalelement;
+
+	/*Get basal element*/
+	element->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DhorizontalEnum:
+			basalelement = element;
+			break;
+		case Domain3DEnum:
+			if(!element->IsOnBase()) return NULL;
+			basalelement = element->SpawnBasalElement();
+			break;
+		default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
+	}
+
+	/*Intermediaries */
+	bool       active_element,isefficientlayer;
+	IssmDouble dt,scalar;
+	IssmDouble water_head;
+	IssmDouble water_load,transfer;
+	IssmDouble Jdet;
+
+	IssmDouble *xyz_list             = NULL;
+	Input*      old_wh_input         = NULL;
+	Input*      active_element_input = NULL;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = basalelement->GetNumberOfNodes();
+
+	/*Initialize Element vector*/
+	ElementVector* pe    = basalelement->NewElementVector();
+	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	basalelement->GetVerticesCoordinates(&xyz_list);
+	basalelement->FindParam(&dt,TimesteppingTimeStepEnum);
+	basalelement->FindParam(&isefficientlayer,HydrologydcIsefficientlayerEnum);
+
+	Input* epl_thick_input   = basalelement->GetInput(HydrologydcEplThicknessEnum);
+	Input* sed_head_input    = basalelement->GetInput(SedimentHeadEnum);
+	Input* epl_head_input    = basalelement->GetInput(EplHeadEnum);
+	Input* sed_trans_input   = basalelement->GetInput(HydrologydcSedimentTransmitivityEnum);
+	Input* thickness_input   = basalelement->GetInput(ThicknessEnum);
+	Input* base_input        = basalelement->GetInput(BaseEnum);
+	Input* water_input       = basalelement->GetInput(BasalforcingsMeltingRateEnum);    _assert_(water_input);
+	if(dt!= 0.){old_wh_input = basalelement->GetInput(SedimentHeadOldEnum);             _assert_(old_wh_input);}
+
+	IssmDouble sediment_storing    = SedimentStoring(basalelement);
+
+	/*Transfer related Inputs*/
+	if(isefficientlayer){
+		active_element_input = basalelement->GetInput(HydrologydcMaskEplactiveEltEnum); _assert_(active_element_input);
+	}
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=basalelement->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+	
+		basalelement->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		basalelement->NodalFunctions(basis,gauss);
+
+		/*Loading term*/
+		water_input->GetInputValue(&water_load,gauss);
+
+		scalar = Jdet*gauss->weight*(water_load);
+		if(dt!=0.) scalar = scalar*dt;
+		for(int i=0;i<numnodes;i++){
+			pe->values[i]+=scalar*basis[i];
+		}
+			
+		/*Transient and transfer terms*/
+		if(dt!=0.){
+			old_wh_input    ->GetInputValue(&water_head,gauss);
+			if(isefficientlayer){
+				/*Dealing with the sediment part of the transfer term*/
+				active_element_input->GetInputValue(&active_element);
+				if(active_element){
+					transfer=GetHydrologyPVectorTransfer(basalelement,gauss,epl_thick_input,sed_head_input,epl_head_input,sed_trans_input,thickness_input,base_input);
+				}
+				else{
+					transfer=0.0;
+				}
+				scalar = Jdet*gauss->weight*((water_head*sediment_storing)+(dt*transfer));
+				for(int i=0;i<numnodes;i++)pe->values[i]+=scalar*basis[i];
+			}
+			else{
+				scalar = Jdet*gauss->weight*(water_head*sediment_storing);
+				for(int i=0;i<numnodes;i++)pe->values[i]+=scalar*basis[i];
+			}
+		}
+	}
+	/*Clean up and return*/
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(basis);
+	delete gauss;
+	if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;};
+	return pe;
+}/*}}}*/
+void HydrologyDCInefficientAnalysis::GetB(IssmDouble* B,Element* element,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
+	/*Compute B  matrix. B=[B1 B2 B3] where Bi is of size 3*NDOF2. 
+	 * For node i, Bi can be expressed in the actual coordinate system
+	 * by: 
+	 *       Bi=[ dN/dx ]
+	 *          [ dN/dy ]
+	 * where N is the finiteelement function for node i.
+	 *
+	 * We assume B has been allocated already, of size: 3x(NDOF2*numnodes)
+	 */
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Get nodal functions derivatives*/
+	IssmDouble* dbasis=xNew<IssmDouble>(2*numnodes);
+	element->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+
+	/*Build B: */
+	for(int i=0;i<numnodes;i++){
+		B[numnodes*0+i] = dbasis[0*numnodes+i];
+		B[numnodes*1+i] = dbasis[1*numnodes+i];
+	}
+
+	/*Clean-up*/
+	xDelete<IssmDouble>(dbasis);
+}/*}}}*/
+void HydrologyDCInefficientAnalysis::GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element){/*{{{*/
+	element->GetSolutionFromInputsOneDof(solution,SedimentHeadEnum);
+}/*}}}*/
+void HydrologyDCInefficientAnalysis::InputUpdateFromSolution(IssmDouble* solution,Element* element){/*{{{*/
+
+	int        domaintype;
+	bool       converged;
+	int*       doflist=NULL;
+	Element*   basalelement=NULL;
+
+	element->FindParam(&domaintype,DomainTypeEnum);
+	if(domaintype!=Domain2DhorizontalEnum){
+		if(!element->IsOnBase()) return;
+		basalelement=element->SpawnBasalElement();
+	}
+	else{
+		basalelement = element;
+	}
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = basalelement->GetNumberOfNodes();
+
+	/*Fetch dof list and allocate solution vector*/
+	basalelement->GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
+	IssmDouble* values   = xNew<IssmDouble>(numnodes);
+	IssmDouble* pressure = xNew<IssmDouble>(numnodes);
+	IssmDouble* residual = xNew<IssmDouble>(numnodes);
+
+	/*Use the dof list to index into the solution vector: */
+	for(int i=0;i<numnodes;i++){
+		values[i] =solution[doflist[i]];
+		if(xIsNan<IssmDouble>(values[i])) _error_("NaN found in solution vector");
+	}
+
+	/*If converged keep the residual in mind, also compute effective pressure*/
+	basalelement->GetInputValue(&converged,ConvergedEnum);
+
+	/*Get inputs*/
+	if(converged){
+		IssmDouble penalty_factor,kmax,kappa,h_max;
+		IssmDouble rho_freshwater,rho_ice;
+		IssmDouble g;
+		IssmDouble* thickness = xNew<IssmDouble>(numnodes);
+		IssmDouble* base      = xNew<IssmDouble>(numnodes);
+
+		basalelement->FindParam(&kmax,HydrologySedimentKmaxEnum);
+		basalelement->FindParam(&penalty_factor,HydrologydcPenaltyFactorEnum);
+		basalelement->GetMaterialParameter(MaterialsRhoFreshwaterEnum);
+		basalelement->GetMaterialParameter(MaterialsRhoIceEnum);
+		basalelement->GetMaterialParameter(ConstantsGEnum);
+		
+		basalelement->GetInputListOnVertices(thickness,ThicknessEnum);
+		basalelement->GetInputListOnVertices(base,BaseEnum);
+
+		kappa=kmax*pow(10.,penalty_factor);
+
+		for(int i=0;i<numnodes;i++){
+
+			GetHydrologyDCInefficientHmax(&h_max,basalelement,basalelement->GetNode(i));
+			if(values[i]>h_max) {
+				residual[i] = kappa*(values[i]-h_max);
+				pressure[i]=(rho_ice*g*thickness[i])-(rho_freshwater*g*(values[i]-base[i]));
+			}
+			else{
+				residual[i] = 0.;
+				pressure[i]=(rho_ice*g*thickness[i])-(rho_freshwater*g*(h_max-base[i]));
+			}
+		}
+		xDelete<IssmDouble>(thickness);
+		xDelete<IssmDouble>(base);
+	}
+
+	/*Add input to the element: */
+	element->AddBasalInput(SedimentHeadEnum,values,P1Enum);
+	element->AddBasalInput(SedimentHeadResidualEnum,residual,P1Enum);
+	element->AddBasalInput(EffectivePressureEnum,pressure,P1Enum);
+
+	/*Free ressources:*/
+	xDelete<IssmDouble>(values);
+	xDelete<IssmDouble>(residual);
+	xDelete<IssmDouble>(pressure);
+	xDelete<int>(doflist);
+	if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;};
+}/*}}}*/
+void HydrologyDCInefficientAnalysis::UpdateConstraints(FemModel* femmodel){/*{{{*/
+	/*Default, do nothing*/
+	return;
+}/*}}}*/
+
+/*Intermediaries*/
+IssmDouble HydrologyDCInefficientAnalysis::SedimentStoring(Element* element){/*{{{*/
+	IssmDouble rho_freshwater           = element->GetMaterialParameter(MaterialsRhoFreshwaterEnum);
+	IssmDouble g                        = element->GetMaterialParameter(ConstantsGEnum);
+	IssmDouble sediment_porosity        = element->GetMaterialParameter(HydrologydcSedimentPorosityEnum);
+	IssmDouble sediment_thickness       = element->GetMaterialParameter(HydrologydcSedimentThicknessEnum);
+	IssmDouble sediment_compressibility = element->GetMaterialParameter(HydrologydcSedimentCompressibilityEnum);
+	IssmDouble water_compressibility    = element->GetMaterialParameter(HydrologydcWaterCompressibilityEnum);
+	return rho_freshwater*g*sediment_porosity*sediment_thickness*(water_compressibility+(sediment_compressibility/sediment_porosity));		 
+}/*}}}*/
+
+IssmDouble HydrologyDCInefficientAnalysis::EplSpecificStoring(Element* element){/*{{{*/
+	IssmDouble rho_freshwater        = element->GetMaterialParameter(MaterialsRhoFreshwaterEnum);
+	IssmDouble g                     = element->GetMaterialParameter(ConstantsGEnum);
+	IssmDouble epl_porosity          = element->GetMaterialParameter(HydrologydcEplPorosityEnum);
+	IssmDouble epl_compressibility   = element->GetMaterialParameter(HydrologydcEplCompressibilityEnum);
+	IssmDouble water_compressibility = element->GetMaterialParameter(HydrologydcWaterCompressibilityEnum);
+	return rho_freshwater*g*epl_porosity*(water_compressibility+(epl_compressibility/epl_porosity));		 
+}/*}}}*/
+
+IssmDouble HydrologyDCInefficientAnalysis::GetHydrologyDCInefficientHmax(Element* element, Gauss* gauss, Input* thick_input, Input* base_input){/*{{{*/
+	int        hmax_flag;
+	IssmDouble h_max;
+	IssmDouble rho_ice,rho_water;
+	IssmDouble thickness,bed;
+	/*Get the flag to the limitation method*/
+	element->FindParam(&hmax_flag,HydrologydcSedimentlimitFlagEnum);
+	
+	/*Switch between the different cases*/
+	switch(hmax_flag){
+	case 0:
+		h_max=1.0e+10;
+		break;
+	case 1:
+		element->FindParam(&h_max,HydrologydcSedimentlimitEnum);
+		break;
+	case 2:
+	
+		rho_water = element->GetMaterialParameter(MaterialsRhoFreshwaterEnum);
+		rho_ice   = element->GetMaterialParameter(MaterialsRhoIceEnum);
+
+		_assert_(thick_input);
+		_assert_(base_input);
+
+		/*Compute max*/
+		thick_input->GetInputValue(&thickness,gauss);
+		base_input->GetInputValue(&bed,gauss);
+		h_max=((rho_ice*thickness)/rho_water)+bed;
+		break;
+	case 3:
+		_error_("Using normal stress  not supported yet");
+		break;
+	default:
+		_error_("no case higher than 3 for SedimentlimitFlag");
+	}
+	return h_max;
+}/*}}}*/
+void  HydrologyDCInefficientAnalysis::GetHydrologyDCInefficientHmax(IssmDouble* ph_max,Element* element, Node* innode){/*{{{*/
+	
+	int        hmax_flag;
+	IssmDouble h_max;
+	IssmDouble rho_ice,rho_water;
+	IssmDouble thickness,bed;
+	/*Get the flag to the limitation method*/
+	element->FindParam(&hmax_flag,HydrologydcSedimentlimitFlagEnum);
+	
+	/*Switch between the different cases*/
+	switch(hmax_flag){
+	case 0:
+		h_max=1.0e+10;
+		break;
+	case 1:
+		element->FindParam(&h_max,HydrologydcSedimentlimitEnum);
+		break;
+	case 2:
+		/*Compute max*/
+		rho_water = element->GetMaterialParameter(MaterialsRhoFreshwaterEnum);
+		rho_ice   = element->GetMaterialParameter(MaterialsRhoIceEnum);
+		element->GetInputValue(&thickness,innode,ThicknessEnum);
+		element->GetInputValue(&bed,innode,BaseEnum);
+		h_max=((rho_ice*thickness)/rho_water)+bed;
+		break;
+	case 3:
+		_error_("Using normal stress  not supported yet");
+		break;
+	default:
+		_error_("no case higher than 3 for SedimentlimitFlag");
+	}
+	/*Assign output pointer*/
+	*ph_max=h_max;
+}
+/*}}}*/
+IssmDouble HydrologyDCInefficientAnalysis::GetHydrologyKMatrixTransfer(Element* element, Gauss* gauss, Input* epl_thick_input, Input* sed_head_input, Input* epl_head_input, Input* sed_trans_input, Input* thickness_input, Input* base_input){/*{{{*/
+
+	int transfermethod;
+	IssmDouble epl_thickness;
+	IssmDouble epl_head,sed_head;
+	IssmDouble sediment_transmitivity;
+	IssmDouble leakage,h_max,transfer;
+
+	IssmDouble sediment_thickness  = element->GetMaterialParameter(HydrologydcSedimentThicknessEnum);
+	IssmDouble sediment_storing    = SedimentStoring(element);
+ 	IssmDouble epl_specificstoring = EplSpecificStoring(element);		
+
+	element->FindParam(&transfermethod,HydrologydcTransferFlagEnum);
+	/*Switch between the different transfer methods cases*/
+	switch(transfermethod){
+	case 0:
+		/*Just keepping the transfer to zero*/
+		transfer=0.0;
+		break;
+	case 1:
+		
+		_assert_(epl_thick_input);
+		_assert_(sed_head_input);
+		_assert_(epl_head_input);
+		_assert_(sed_trans_input);
+		_assert_(thickness_input);
+		_assert_(base_input);
+
+		epl_thick_input->GetInputValue(&epl_thickness,gauss);
+		sed_head_input->GetInputValue(&sed_head,gauss);
+		epl_head_input->GetInputValue(&epl_head,gauss);
+		sed_trans_input->GetInputValue(&sediment_transmitivity,gauss);
+		element->FindParam(&leakage,HydrologydcLeakageFactorEnum);
+	
+		if(epl_head>sed_head){
+			h_max=GetHydrologyDCInefficientHmax(element,gauss,thickness_input,base_input);
+			if(sed_head>=h_max){
+				transfer=0.0;
+			}
+			else{
+				transfer=(epl_specificstoring*epl_thickness*sediment_transmitivity)/(sediment_thickness*leakage);
+			}
+		}
+		else{
+			transfer=(sediment_storing*sediment_transmitivity)/(sediment_thickness*leakage);
+		}
+		break;
+	default:
+		_error_("no case higher than 1 for the Transfer method");
+	}
+	
+	return transfer;
+}/*}}}*/
+
+IssmDouble HydrologyDCInefficientAnalysis::GetHydrologyPVectorTransfer(Element* element, Gauss* gauss, Input* epl_thick_input, Input* sed_head_input, Input* epl_head_input, Input* sed_trans_input, Input* thickness_input, Input* base_input){/*{{{*/
+
+	int transfermethod;
+	IssmDouble epl_thickness;
+	IssmDouble epl_head,sediment_head;
+	IssmDouble sediment_transmitivity;
+	IssmDouble leakage,h_max,transfer;
+
+	IssmDouble sediment_thickness = element->GetMaterialParameter(HydrologydcSedimentThicknessEnum);
+	IssmDouble sediment_storing   = SedimentStoring(element);
+ 	IssmDouble epl_specificstoring = EplSpecificStoring(element);		
+
+	element->FindParam(&transfermethod,HydrologydcTransferFlagEnum);
+	/*Switch between the different transfer methods cases*/
+	switch(transfermethod){
+	case 0:
+		/*Just keepping the transfer to zero*/
+		transfer=0.0;
+		break;
+	case 1:
+		
+		_assert_(epl_thick_input);
+		_assert_(sed_head_input);
+		_assert_(epl_head_input);
+		_assert_(sed_trans_input);
+		_assert_(thickness_input);
+		_assert_(base_input);
+
+		epl_thick_input->GetInputValue(&epl_thickness,gauss);
+		sed_head_input->GetInputValue(&sediment_head,gauss);
+		epl_head_input->GetInputValue(&epl_head,gauss);
+		sed_trans_input->GetInputValue(&sediment_transmitivity,gauss);
+
+		element->FindParam(&leakage,HydrologydcLeakageFactorEnum);
+
+		if(epl_head>sediment_head){
+			h_max=GetHydrologyDCInefficientHmax(element,gauss,thickness_input,base_input);
+			if(sediment_head>=h_max){
+				transfer=0.0;
+			}
+			else{
+				transfer=(epl_specificstoring*epl_thickness*sediment_transmitivity*epl_head)/(sediment_thickness*leakage);
+			}
+		}
+		else{
+			transfer=(sediment_storing*sediment_transmitivity*epl_head)/(sediment_thickness*leakage);
+		}
+		break;
+	default:
+		_error_("no case higher than 1 for the Transfer method");
+	}
+	return transfer;
+}/*}}}*/
+
+void HydrologyDCInefficientAnalysis::ElementizeEplMask(FemModel* femmodel){/*{{{*/
+
+	bool     element_active;
+	Element* element=NULL;
+
+	for(int i=0;i<femmodel->elements->Size();i++){
+		element=dynamic_cast<Element*>(femmodel->elements->GetObjectByOffset(i));
+
+		int numvertices = element->GetNumberOfVertices();
+		Input* node_mask_input = element->GetInput(HydrologydcMaskEplactiveNodeEnum);
+		if(node_mask_input->Max()>0.) {
+			element_active = true;
+		}
+		else{
+			element_active = false;
+		}
+		element->AddInput(new BoolInput(HydrologydcMaskEplactiveEltEnum,element_active));
+	}
+}/*}}}*/
+
Index: /issm/trunk/src/c/analyses/HydrologyDCInefficientAnalysis.h
===================================================================
--- /issm/trunk/src/c/analyses/HydrologyDCInefficientAnalysis.h	(revision 17805)
+++ /issm/trunk/src/c/analyses/HydrologyDCInefficientAnalysis.h	(revision 17806)
@@ -8,9 +8,11 @@
 /*Headers*/
 #include "./Analysis.h"
-
+class Node; 
+class Input;
 class HydrologyDCInefficientAnalysis: public Analysis{
 
 	public:
-		int  DofsPerNode(int** doflist,int meshtype,int approximation);
+		/*Model processing*/
+		int  DofsPerNode(int** doflist,int domaintype,int approximation);
 		void UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum);
 		void UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);
@@ -18,4 +20,24 @@
 		void CreateConstraints(Constraints* constraints,IoModel* iomodel);
 		void CreateLoads(Loads* loads, IoModel* iomodel);
+
+		/*Finite element Analysis*/
+		void           Core(FemModel* femmodel);
+		ElementVector* CreateDVector(Element* element);
+		ElementMatrix* CreateJacobianMatrix(Element* element);
+		ElementMatrix* CreateKMatrix(Element* element);
+		ElementVector* CreatePVector(Element* element);
+		void GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element);
+		void InputUpdateFromSolution(IssmDouble* solution,Element* element);
+		void UpdateConstraints(FemModel* femmodel);
+
+		/*Intermediaries*/
+		void GetB(IssmDouble* B,Element* element,IssmDouble* xyz_list,Gauss* gauss);
+		IssmDouble SedimentStoring(Element* element);
+		IssmDouble EplSpecificStoring(Element* element);
+		IssmDouble GetHydrologyDCInefficientHmax(Element* element, Gauss* gauss, Input* thickness_input, Input* base_input);
+		void GetHydrologyDCInefficientHmax(IssmDouble* ph_max,Element* element, Node* innode);
+		IssmDouble GetHydrologyKMatrixTransfer(Element* element, Gauss* gauss, Input* epl_thick_input, Input* sed_head_input, Input* epl_head_input, Input* sed_trans_input, Input* thickness_input, Input* base_input);
+		IssmDouble GetHydrologyPVectorTransfer(Element* element, Gauss* gauss, Input* epl_thick_input, Input* sed_head_input, Input* epl_head_input, Input* sed_trans_input, Input* thickness_input, Input* base_input);
+		void ElementizeEplMask(FemModel* femmodel);
 };
 #endif
Index: /issm/trunk/src/c/analyses/HydrologyShreveAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/HydrologyShreveAnalysis.cpp	(revision 17805)
+++ /issm/trunk/src/c/analyses/HydrologyShreveAnalysis.cpp	(revision 17806)
@@ -6,5 +6,5 @@
 
 /*Model processing*/
-int  HydrologyShreveAnalysis::DofsPerNode(int** doflist,int meshtype,int approximation){/*{{{*/
+int  HydrologyShreveAnalysis::DofsPerNode(int** doflist,int domaintype,int approximation){/*{{{*/
 	return 1;
 }/*}}}*/
@@ -43,6 +43,6 @@
 	iomodel->FetchDataToInput(elements,ThicknessEnum);
 	iomodel->FetchDataToInput(elements,SurfaceEnum);
-	iomodel->FetchDataToInput(elements,BedEnum);
-	iomodel->FetchDataToInput(elements,MeshElementonbedEnum);
+	iomodel->FetchDataToInput(elements,BaseEnum);
+	iomodel->FetchDataToInput(elements,MeshElementonbaseEnum);
 	iomodel->FetchDataToInput(elements,MeshElementonsurfaceEnum);
 	iomodel->FetchDataToInput(elements,MaskIceLevelsetEnum);
@@ -62,7 +62,7 @@
 	if(hydrology_model!=HydrologyshreveEnum) return;
 
-	if(iomodel->meshtype==Mesh3DEnum) iomodel->FetchData(2,MeshVertexonbedEnum,MeshVertexonsurfaceEnum);
+	if(iomodel->domaintype==Domain3DEnum) iomodel->FetchData(2,MeshVertexonbaseEnum,MeshVertexonsurfaceEnum);
 	::CreateNodes(nodes,iomodel,HydrologyShreveAnalysisEnum,P1Enum);
-	iomodel->DeleteData(2,MeshVertexonbedEnum,MeshVertexonsurfaceEnum);
+	iomodel->DeleteData(2,MeshVertexonbaseEnum,MeshVertexonsurfaceEnum);
 }/*}}}*/
 void HydrologyShreveAnalysis::CreateConstraints(Constraints* constraints,IoModel* iomodel){/*{{{*/
@@ -80,2 +80,295 @@
 	/*No loads*/
 }/*}}}*/
+
+/*Finite Element Analysis*/
+void           HydrologyShreveAnalysis::Core(FemModel* femmodel){/*{{{*/
+	_error_("not implemented");
+}/*}}}*/
+ElementVector* HydrologyShreveAnalysis::CreateDVector(Element* element){/*{{{*/
+	/*Default, return NULL*/
+	return NULL;
+}/*}}}*/
+ElementMatrix* HydrologyShreveAnalysis::CreateJacobianMatrix(Element* element){/*{{{*/
+_error_("Not implemented");
+}/*}}}*/
+ElementMatrix* HydrologyShreveAnalysis::CreateKMatrix(Element* element){/*{{{*/
+
+	/*Intermediaries */
+	IssmDouble diffusivity;
+	IssmDouble Jdet,D_scalar,dt,h;
+	IssmDouble vx,vy,vel,dvxdx,dvydy;
+	IssmDouble dvx[2],dvy[2];
+	IssmDouble* xyz_list = NULL;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Initialize Element vector and other vectors*/
+	ElementMatrix* Ke     = element->NewElementMatrix();
+	IssmDouble*    basis  = xNew<IssmDouble>(numnodes);
+	IssmDouble*    B      = xNew<IssmDouble>(2*numnodes);
+	IssmDouble*    Bprime = xNew<IssmDouble>(2*numnodes);
+	IssmDouble     D[2][2]={0.};
+
+	/*Create water velocity vx and vy from current inputs*/
+	CreateHydrologyWaterVelocityInput(element);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+	element->FindParam(&dt,TimesteppingTimeStepEnum);
+	element->FindParam(&diffusivity,HydrologyshreveStabilizationEnum);
+	Input* vx_input=element->GetInput(HydrologyWaterVxEnum); _assert_(vx_input);
+	Input* vy_input=element->GetInput(HydrologyWaterVyEnum); _assert_(vy_input);
+	h = element->CharacteristicLength();
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		element->NodalFunctions(basis,gauss);
+
+		vx_input->GetInputValue(&vx,gauss);
+		vy_input->GetInputValue(&vy,gauss);
+		vx_input->GetInputDerivativeValue(&dvx[0],xyz_list,gauss);
+		vy_input->GetInputDerivativeValue(&dvy[0],xyz_list,gauss);
+
+		D_scalar=gauss->weight*Jdet;
+
+		TripleMultiply(basis,1,numnodes,1,
+					&D_scalar,1,1,0,
+					basis,1,numnodes,0,
+					Ke->values,1);
+
+		GetB(B,element,xyz_list,gauss);
+		GetBprime(Bprime,element,xyz_list,gauss);
+
+		dvxdx=dvx[0];
+		dvydy=dvy[1];
+		D_scalar=dt*gauss->weight*Jdet;
+
+		D[0][0]=D_scalar*dvxdx;
+		D[1][1]=D_scalar*dvydy;
+		TripleMultiply(B,2,numnodes,1,
+					&D[0][0],2,2,0,
+					B,2,numnodes,0,
+					&Ke->values[0],1);
+
+		D[0][0]=D_scalar*vx;
+		D[1][1]=D_scalar*vy;
+		TripleMultiply(B,2,numnodes,1,
+					&D[0][0],2,2,0,
+					Bprime,2,numnodes,0,
+					&Ke->values[0],1);
+
+		/*Artificial diffusivity*/
+		vel=sqrt(vx*vx+vy*vy);
+		D[0][0]=D_scalar*diffusivity*h/(2*vel)*vx*vx;
+		D[1][0]=D_scalar*diffusivity*h/(2*vel)*vy*vx;
+		D[0][1]=D_scalar*diffusivity*h/(2*vel)*vx*vy;
+		D[1][1]=D_scalar*diffusivity*h/(2*vel)*vy*vy;
+		TripleMultiply(Bprime,2,numnodes,1,
+					&D[0][0],2,2,0,
+					Bprime,2,numnodes,0,
+					&Ke->values[0],1);
+	}
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(basis);
+	xDelete<IssmDouble>(B);
+	xDelete<IssmDouble>(Bprime);
+	delete gauss;
+	return Ke;
+}/*}}}*/
+ElementVector* HydrologyShreveAnalysis::CreatePVector(Element* element){/*{{{*/
+
+	/*Skip if water or ice shelf element*/
+	if(element->IsFloating()) return NULL;
+
+	/*Intermediaries */
+	IssmDouble  Jdet,dt;
+	IssmDouble  mb,oldw;
+	IssmDouble* xyz_list = NULL;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Initialize Element vector and other vectors*/
+	ElementVector* pe    = element->NewElementVector();
+	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+	element->FindParam(&dt,TimesteppingTimeStepEnum);
+	Input* mb_input   = element->GetInput(BasalforcingsMeltingRateEnum); _assert_(mb_input);
+	Input* oldw_input = element->GetInput(WaterColumnOldEnum);           _assert_(oldw_input);
+
+	/*Initialize mb_correction to 0, do not forget!:*/
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		element->NodalFunctions(basis,gauss);
+
+		mb_input->GetInputValue(&mb,gauss);
+		oldw_input->GetInputValue(&oldw,gauss);
+
+		if(dt!=0.){
+			for(int i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*(oldw+dt*mb)*basis[i];
+		}
+		else{
+			for(int i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*mb*basis[i];
+		}
+	}
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(basis);
+	delete gauss;
+	return pe;
+}/*}}}*/
+void HydrologyShreveAnalysis::GetB(IssmDouble* B,Element* element,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
+	/*Compute B  matrix. B=[B1 B2 B3] where Bi is of size 3*NDOF2. 
+	 * For node i, Bi can be expressed in the actual coordinate system
+	 * by: 
+	 *       Bi=[ N ]
+	 *          [ N ]
+	 * where N is the finiteelement function for node i.
+	 *
+	 * We assume B_prog has been allocated already, of size: 2x(NDOF1*numnodes)
+	 */
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Get nodal functions*/
+	IssmDouble* basis=xNew<IssmDouble>(numnodes);
+	element->NodalFunctions(basis,gauss);
+
+	/*Build B: */
+	for(int i=0;i<numnodes;i++){
+		B[numnodes*0+i] = basis[i];
+		B[numnodes*1+i] = basis[i];
+	}
+
+	/*Clean-up*/
+	xDelete<IssmDouble>(basis);
+}/*}}}*/
+void HydrologyShreveAnalysis::GetBprime(IssmDouble* Bprime,Element* element,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
+	/*Compute B'  matrix. B'=[B1' B2' B3'] where Bi' is of size 3*NDOF2. 
+	 * For node i, Bi' can be expressed in the actual coordinate system
+	 * by: 
+	 *       Bi_prime=[ dN/dx ]
+	 *                [ dN/dy ]
+	 * where N is the finiteelement function for node i.
+	 *
+	 * We assume B' has been allocated already, of size: 3x(NDOF2*numnodes)
+	 */
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Get nodal functions derivatives*/
+	IssmDouble* dbasis=xNew<IssmDouble>(2*numnodes);
+	element->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+
+	/*Build B': */
+	for(int i=0;i<numnodes;i++){
+		Bprime[numnodes*0+i] = dbasis[0*numnodes+i];
+		Bprime[numnodes*1+i] = dbasis[1*numnodes+i];
+	}
+
+	/*Clean-up*/
+	xDelete<IssmDouble>(dbasis);
+
+}/*}}}*/
+void HydrologyShreveAnalysis::GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element){/*{{{*/
+	element->GetSolutionFromInputsOneDof(solution,WatercolumnEnum);
+}/*}}}*/
+void HydrologyShreveAnalysis::InputUpdateFromSolution(IssmDouble* solution,Element* element){/*{{{*/
+
+	/*Intermediary*/
+	int* doflist = NULL;
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Fetch dof list and allocate solution vector*/
+	element->GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
+	IssmDouble* values = xNew<IssmDouble>(numnodes);
+
+	/*Use the dof list to index into the solution vector: */
+	for(int i=0;i<numnodes;i++){
+		values[i]=solution[doflist[i]];
+		if(xIsNan<IssmDouble>(values[i])) _error_("NaN found in solution vector");
+		if (values[i]<10e-10) values[i]=10e-10; //correcting the water column to positive values
+	}
+
+	/*Add input to the element: */
+	element->AddInput(WatercolumnEnum,values,element->GetElementType());
+
+	/*Free ressources:*/
+	xDelete<IssmDouble>(values);
+	xDelete<int>(doflist);
+}/*}}}*/
+void HydrologyShreveAnalysis::UpdateConstraints(FemModel* femmodel){/*{{{*/
+	/*Default, do nothing*/
+	return;
+}/*}}}*/
+
+/*Intermediaries*/
+void HydrologyShreveAnalysis::CreateHydrologyWaterVelocityInput(Element* element){/*{{{*/
+
+	/*Intermediaries*/
+	IssmDouble dsdx,dsdy,dbdx,dbdy,w;
+
+	/*Retrieve all inputs and parameters*/
+	IssmDouble  rho_ice   = element->GetMaterialParameter(MaterialsRhoIceEnum);
+	IssmDouble  rho_water = element->GetMaterialParameter(MaterialsRhoWaterEnum);
+	IssmDouble  g         = element->GetMaterialParameter(ConstantsGEnum);
+	IssmDouble  CR        = element->GetMaterialParameter(HydrologyshreveCREnum);
+	IssmDouble  n_man     = element->GetMaterialParameter(HydrologyshreveNEnum);
+	IssmDouble  mu_water  = element->GetMaterialParameter(MaterialsMuWaterEnum);
+	Input* surfaceslopex_input = element->GetInput(SurfaceSlopeXEnum); _assert_(surfaceslopex_input);
+	Input* surfaceslopey_input = element->GetInput(SurfaceSlopeYEnum); _assert_(surfaceslopey_input);
+	Input* bedslopex_input     = element->GetInput(BedSlopeXEnum);     _assert_(bedslopex_input);
+	Input* bedslopey_input     = element->GetInput(BedSlopeYEnum);     _assert_(bedslopey_input);
+	Input* watercolumn_input   = element->GetInput(WatercolumnEnum);   _assert_(watercolumn_input);
+
+	/* compute VelocityFactor */
+	IssmDouble VelocityFactor = n_man*CR*CR*rho_water*g/mu_water;
+
+	/*Fetch number of vertices and allocate output*/
+	int numvertices = element->GetNumberOfVertices();
+	IssmDouble* vx  = xNew<IssmDouble>(numvertices);
+	IssmDouble* vy  = xNew<IssmDouble>(numvertices);
+
+	Gauss* gauss=element->NewGauss();
+	for(int iv=0;iv<numvertices;iv++){
+		gauss->GaussVertex(iv);
+		surfaceslopex_input->GetInputValue(&dsdx,gauss);
+		surfaceslopey_input->GetInputValue(&dsdy,gauss);
+		bedslopex_input->GetInputValue(&dbdx,gauss);
+		bedslopey_input->GetInputValue(&dbdy,gauss);
+		watercolumn_input->GetInputValue(&w,gauss);
+
+		/* Water velocity x and y components */
+	//	vx[iv]= - w*w/(12 * mu_water)*(rho_ice*g*dsdx+(rho_water-rho_ice)*g*dbdx);
+	//	vy[iv]= - w*w/(12 * mu_water)*(rho_ice*g*dsdy+(rho_water-rho_ice)*g*dbdy);
+		vx[iv]= - w*w/(VelocityFactor* mu_water)*(rho_ice*g*dsdx+(rho_water-rho_ice)*g*dbdx);
+		vy[iv]= - w*w/(VelocityFactor* mu_water)*(rho_ice*g*dsdy+(rho_water-rho_ice)*g*dbdy);
+	}
+
+	/*clean-up*/
+	delete gauss;
+
+	/*Add to inputs*/
+	element->AddInput(HydrologyWaterVxEnum,vx,P1Enum);
+	element->AddInput(HydrologyWaterVyEnum,vy,P1Enum);
+	xDelete<IssmDouble>(vx);
+	xDelete<IssmDouble>(vy);
+}/*}}}*/
Index: /issm/trunk/src/c/analyses/HydrologyShreveAnalysis.h
===================================================================
--- /issm/trunk/src/c/analyses/HydrologyShreveAnalysis.h	(revision 17805)
+++ /issm/trunk/src/c/analyses/HydrologyShreveAnalysis.h	(revision 17806)
@@ -12,5 +12,6 @@
 
 	public:
-		int  DofsPerNode(int** doflist,int meshtype,int approximation);
+		/*Model processing*/
+		int  DofsPerNode(int** doflist,int domaintype,int approximation);
 		void UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum);
 		void UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);
@@ -18,4 +19,19 @@
 		void CreateConstraints(Constraints* constraints,IoModel* iomodel);
 		void CreateLoads(Loads* loads, IoModel* iomodel);
+
+		/*Finite element Analysis*/
+		void           Core(FemModel* femmodel);
+		ElementVector* CreateDVector(Element* element);
+		ElementMatrix* CreateJacobianMatrix(Element* element);
+		ElementMatrix* CreateKMatrix(Element* element);
+		ElementVector* CreatePVector(Element* element);
+		void GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element);
+		void InputUpdateFromSolution(IssmDouble* solution,Element* element);
+		void UpdateConstraints(FemModel* femmodel);
+
+		/*Intermediaries*/
+		void GetB(IssmDouble* B,Element* element,IssmDouble* xyz_list,Gauss* gauss);
+		void GetBprime(IssmDouble* Bprime,Element* element,IssmDouble* xyz_list,Gauss* gauss);
+		void CreateHydrologyWaterVelocityInput(Element* element);
 };
 #endif
Index: /issm/trunk/src/c/analyses/L2ProjectionBaseAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/L2ProjectionBaseAnalysis.cpp	(revision 17805)
+++ /issm/trunk/src/c/analyses/L2ProjectionBaseAnalysis.cpp	(revision 17806)
@@ -6,5 +6,5 @@
 
 /*Model processing*/
-int  L2ProjectionBaseAnalysis::DofsPerNode(int** doflist,int meshtype,int approximation){/*{{{*/
+int  L2ProjectionBaseAnalysis::DofsPerNode(int** doflist,int domaintype,int approximation){/*{{{*/
 	return 1;
 }/*}}}*/
@@ -24,24 +24,27 @@
 
 	iomodel->FetchDataToInput(elements,SurfaceEnum);
-	iomodel->FetchDataToInput(elements,BedEnum);
+	iomodel->FetchDataToInput(elements,BaseEnum);
 	iomodel->FetchDataToInput(elements,MaskIceLevelsetEnum);
-	if(iomodel->meshtype==Mesh3DEnum){
-		iomodel->FetchDataToInput(elements,MeshElementonbedEnum);
-		iomodel->FetchDataToInput(elements,MeshElementonsurfaceEnum);
-	}
-	if(iomodel->meshtype==Mesh2DverticalEnum){
-		iomodel->FetchDataToInput(elements,MeshVertexonbedEnum);
+	if(iomodel->domaintype==Domain3DEnum){
+		if(iomodel->meshelementtype==PentaEnum){
+			iomodel->FetchDataToInput(elements,MeshElementonbaseEnum);
+			iomodel->FetchDataToInput(elements,MeshElementonsurfaceEnum);
+		}
+		iomodel->FetchDataToInput(elements,MeshVertexonbaseEnum);
+	}
+	if(iomodel->domaintype==Domain2DverticalEnum){
+		iomodel->FetchDataToInput(elements,MeshVertexonbaseEnum);
 	}
 }/*}}}*/
 void L2ProjectionBaseAnalysis::CreateNodes(Nodes* nodes,IoModel* iomodel){/*{{{*/
 
-	if(iomodel->meshtype==Mesh3DEnum){
-		iomodel->FetchData(2,MeshVertexonbedEnum,MeshVertexonsurfaceEnum);
-	}
-	else if(iomodel->meshtype==Mesh2DverticalEnum){
-		iomodel->FetchData(1,MeshVertexonbedEnum);
+	if(iomodel->domaintype==Domain3DEnum){
+		iomodel->FetchData(2,MeshVertexonbaseEnum,MeshVertexonsurfaceEnum);
+	}
+	else if(iomodel->domaintype==Domain2DverticalEnum){
+		iomodel->FetchData(1,MeshVertexonbaseEnum);
 	}
 	::CreateNodes(nodes,iomodel,L2ProjectionBaseAnalysisEnum,P1Enum);
-	iomodel->DeleteData(2,MeshVertexonbedEnum,MeshVertexonsurfaceEnum);
+	iomodel->DeleteData(2,MeshVertexonbaseEnum,MeshVertexonsurfaceEnum);
 }/*}}}*/
 void L2ProjectionBaseAnalysis::CreateConstraints(Constraints* constraints,IoModel* iomodel){/*{{{*/
@@ -53,2 +56,178 @@
 	/*No loads*/
 }/*}}}*/
+
+/*Finite Element Analysis*/
+void           L2ProjectionBaseAnalysis::Core(FemModel* femmodel){/*{{{*/
+	_error_("not implemented");
+}/*}}}*/
+ElementVector* L2ProjectionBaseAnalysis::CreateDVector(Element* element){/*{{{*/
+	/*Default, return NULL*/
+	return NULL;
+}/*}}}*/
+ElementMatrix* L2ProjectionBaseAnalysis::CreateJacobianMatrix(Element* element){/*{{{*/
+_error_("Not implemented");
+}/*}}}*/
+ElementMatrix* L2ProjectionBaseAnalysis::CreateKMatrix(Element* element){/*{{{*/
+
+	/*Intermediaries*/
+	int      domaintype;
+	Element* basalelement;
+
+	/*Get basal element*/
+	element->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DhorizontalEnum:
+			basalelement = element;
+			break;
+		case Domain2DverticalEnum:
+			if(!element->IsOnBase()) return NULL;
+			basalelement = element->SpawnBasalElement();
+			break;
+		case Domain3DEnum:
+			if(!element->IsOnBase()) return NULL;
+			basalelement = element->SpawnBasalElement();
+			break;
+		default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
+	}
+
+	/*Intermediaries */
+	IssmDouble  D,Jdet;
+	IssmDouble *xyz_list  = NULL;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = basalelement->GetNumberOfNodes();
+
+	/*Initialize Element vector*/
+	ElementMatrix* Ke    = basalelement->NewElementMatrix(NoneApproximationEnum);
+	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	basalelement->GetVerticesCoordinates(&xyz_list);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=basalelement->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		basalelement->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		basalelement->NodalFunctions(basis,gauss);
+		D=gauss->weight*Jdet;
+
+		TripleMultiply(basis,1,numnodes,1,
+					&D,1,1,0,
+					basis,1,numnodes,0,
+					&Ke->values[0],1);
+	}
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(basis);
+	delete gauss;
+	if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;};
+	return Ke;
+}/*}}}*/
+ElementVector* L2ProjectionBaseAnalysis::CreatePVector(Element* element){/*{{{*/
+
+	/*Intermediaries*/
+	int      domaintype;
+	Element* basalelement;
+
+	/*Get basal element*/
+	element->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DhorizontalEnum:
+			basalelement = element;
+			break;
+		case Domain2DverticalEnum:
+			if(!element->IsOnBase()) return NULL;
+			basalelement = element->SpawnBasalElement();
+			break;
+		case Domain3DEnum:
+			if(!element->IsOnBase()) return NULL;
+			basalelement = element->SpawnBasalElement();
+			break;
+		default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
+	}
+
+	/*Intermediaries */
+	int         input_enum;
+	IssmDouble  Jdet,value,slopes[2];
+	Input      *input     = NULL;
+	Input      *input2    = NULL;
+	IssmDouble *xyz_list  = NULL;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = basalelement->GetNumberOfNodes();
+
+	/*Initialize Element vector*/
+	ElementVector* pe    = basalelement->NewElementVector();
+	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	basalelement->GetVerticesCoordinates(&xyz_list);
+	basalelement->FindParam(&input_enum,InputToL2ProjectEnum);
+	switch(input_enum){
+		case SurfaceSlopeXEnum: input2 = basalelement->GetInput(SurfaceEnum); _assert_(input2); break;
+		case SurfaceSlopeYEnum: input2 = basalelement->GetInput(SurfaceEnum); _assert_(input2); break;
+		case BedSlopeXEnum:     input2 = basalelement->GetInput(BaseEnum);     _assert_(input2); break;
+		case BedSlopeYEnum:     input2 = basalelement->GetInput(BaseEnum);     _assert_(input2); break;
+		case LevelsetfunctionSlopeXEnum: input2 = basalelement->GetInput(MaskIceLevelsetEnum);     _assert_(input2); break;
+		case LevelsetfunctionSlopeYEnum: input2 = basalelement->GetInput(MaskIceLevelsetEnum);     _assert_(input2); break;
+		default: input = element->GetInput(input_enum);
+	}
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=basalelement->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		basalelement->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		basalelement->NodalFunctions(basis,gauss);
+
+		if(input2) input2->GetInputDerivativeValue(&slopes[0],xyz_list,gauss);
+		switch(input_enum){
+			case SurfaceSlopeXEnum: case BedSlopeXEnum: case LevelsetfunctionSlopeXEnum: value = slopes[0]; break;
+			case SurfaceSlopeYEnum: case BedSlopeYEnum: case LevelsetfunctionSlopeYEnum: value = slopes[1]; break;
+			default: input->GetInputValue(&value,gauss);
+		}
+
+		for(int i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*value*basis[i];
+	}
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(basis);
+	delete gauss;
+	if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;};
+	return pe;
+}/*}}}*/
+void L2ProjectionBaseAnalysis::GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element){/*{{{*/
+	   _error_("not implemented yet");
+}/*}}}*/
+void L2ProjectionBaseAnalysis::InputUpdateFromSolution(IssmDouble* solution,Element* element){/*{{{*/
+
+	int inputenum,domaintype,elementtype;
+
+	element->FindParam(&inputenum,InputToL2ProjectEnum);
+	element->FindParam(&domaintype,DomainTypeEnum);
+	element->FindParam(&elementtype,MeshElementtypeEnum);
+	switch(domaintype){
+		case Domain2DhorizontalEnum:
+			element->InputUpdateFromSolutionOneDof(solution,inputenum);
+			break;
+		case Domain2DverticalEnum:
+			element->InputUpdateFromSolutionOneDof(solution,inputenum);
+			break;
+		case Domain3DEnum:
+			if(elementtype==TetraEnum)
+			 element->InputUpdateFromSolutionOneDof(solution,inputenum);
+			else
+			 element->InputUpdateFromSolutionOneDofCollapsed(solution,inputenum);
+			break;
+		default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
+	}
+}/*}}}*/
+void L2ProjectionBaseAnalysis::UpdateConstraints(FemModel* femmodel){/*{{{*/
+	/*Default, do nothing*/
+	return;
+}/*}}}*/
Index: /issm/trunk/src/c/analyses/L2ProjectionBaseAnalysis.h
===================================================================
--- /issm/trunk/src/c/analyses/L2ProjectionBaseAnalysis.h	(revision 17805)
+++ /issm/trunk/src/c/analyses/L2ProjectionBaseAnalysis.h	(revision 17806)
@@ -12,5 +12,6 @@
 
 	public:
-		int  DofsPerNode(int** doflist,int meshtype,int approximation);
+		/*Model processing*/
+		int  DofsPerNode(int** doflist,int domaintype,int approximation);
 		void UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum);
 		void UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);
@@ -18,4 +19,14 @@
 		void CreateConstraints(Constraints* constraints,IoModel* iomodel);
 		void CreateLoads(Loads* loads, IoModel* iomodel);
+
+		/*Finite element Analysis*/
+		void           Core(FemModel* femmodel);
+		ElementVector* CreateDVector(Element* element);
+		ElementMatrix* CreateJacobianMatrix(Element* element);
+		ElementMatrix* CreateKMatrix(Element* element);
+		ElementVector* CreatePVector(Element* element);
+		void GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element);
+		void InputUpdateFromSolution(IssmDouble* solution,Element* element);
+		void UpdateConstraints(FemModel* femmodel);
 };
 #endif
Index: /issm/trunk/src/c/analyses/L2ProjectionEPLAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/L2ProjectionEPLAnalysis.cpp	(revision 17806)
+++ /issm/trunk/src/c/analyses/L2ProjectionEPLAnalysis.cpp	(revision 17806)
@@ -0,0 +1,252 @@
+#include "./L2ProjectionEPLAnalysis.h"
+#include "../toolkits/toolkits.h"
+#include "../classes/classes.h"
+#include "../shared/shared.h"
+#include "../modules/modules.h"
+
+/*Model processing*/
+int  L2ProjectionEPLAnalysis::DofsPerNode(int** doflist,int domaintype,int approximation){/*{{{*/
+	return 1;
+}/*}}}*/
+void L2ProjectionEPLAnalysis::UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum){/*{{{*/
+}/*}}}*/
+void L2ProjectionEPLAnalysis::UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type){/*{{{*/
+
+	bool   isefficientlayer;
+	int    hydrology_model;
+
+	/*Now, do we really want DC?*/
+	iomodel->Constant(&hydrology_model,HydrologyModelEnum);
+	if(hydrology_model!=HydrologydcEnum) return;
+
+	/*Do we want an efficient layer*/
+	iomodel->Constant(&isefficientlayer,HydrologydcIsefficientlayerEnum);
+	if(!isefficientlayer) return;
+
+	/*Update elements: */
+	int counter=0;
+	for(int i=0;i<iomodel->numberofelements;i++){
+		if(iomodel->my_elements[i]){
+			Element* element=(Element*)elements->GetObjectByOffset(counter);
+			element->Update(i,iomodel,analysis_counter,analysis_type,P1Enum);
+			counter++;
+		}
+	}
+
+	iomodel->FetchDataToInput(elements,EplHeadEnum);
+	iomodel->FetchDataToInput(elements,MaskIceLevelsetEnum);
+	if(iomodel->domaintype==Domain3DEnum){
+		iomodel->FetchDataToInput(elements,MeshElementonbaseEnum);
+	}
+}/*}}}*/
+void L2ProjectionEPLAnalysis::CreateNodes(Nodes* nodes,IoModel* iomodel){/*{{{*/
+	/*Now, do we really want DC?*/
+	int  hydrology_model;
+	iomodel->Constant(&hydrology_model,HydrologyModelEnum);
+	if(hydrology_model!=HydrologydcEnum) return;
+
+	/*Do we want an efficient layer*/
+	bool isefficientlayer;
+	iomodel->Constant(&isefficientlayer,HydrologydcIsefficientlayerEnum);
+	if(!isefficientlayer) return;
+
+	if(iomodel->domaintype==Domain3DEnum){
+		iomodel->FetchData(1,MeshVertexonbaseEnum);
+	}
+	else if(iomodel->domaintype==Domain2DverticalEnum){
+		iomodel->FetchData(1,MeshVertexonbaseEnum);
+	}
+	::CreateNodes(nodes,iomodel,L2ProjectionEPLAnalysisEnum,P1Enum);
+	iomodel->DeleteData(1,MeshVertexonbaseEnum);
+}/*}}}*/
+void L2ProjectionEPLAnalysis::CreateConstraints(Constraints* constraints,IoModel* iomodel){/*{{{*/
+
+	/*No constraints*/
+}/*}}}*/
+void L2ProjectionEPLAnalysis::CreateLoads(Loads* loads, IoModel* iomodel){/*{{{*/
+
+	/*No loads*/
+}/*}}}*/
+
+/*Finite Element Analysis*/
+void           L2ProjectionEPLAnalysis::Core(FemModel* femmodel){/*{{{*/
+	_error_("not implemented");
+}/*}}}*/
+ElementVector* L2ProjectionEPLAnalysis::CreateDVector(Element* element){/*{{{*/
+	/*Default, return NULL*/
+	return NULL;
+}/*}}}*/
+ElementMatrix* L2ProjectionEPLAnalysis::CreateJacobianMatrix(Element* element){/*{{{*/
+_error_("Not implemented");
+}/*}}}*/
+ElementMatrix* L2ProjectionEPLAnalysis::CreateKMatrix(Element* element){/*{{{*/
+
+	/*Intermediaries*/
+	int      domaintype;
+	bool     active_element;
+	Element* basalelement;
+
+	/*Get basal element*/
+	element->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DhorizontalEnum:
+			basalelement = element;
+			break;
+		case Domain2DverticalEnum:
+			if(!element->IsOnBase()) return NULL;
+			basalelement = element->SpawnBasalElement();
+			break;
+		case Domain3DEnum:
+			if(!element->IsOnBase()) return NULL;
+			basalelement = element->SpawnBasalElement();
+			break;
+		default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
+	}
+
+	Input* active_element_input=basalelement->GetInput(HydrologydcMaskEplactiveEltEnum); _assert_(active_element_input);
+	active_element_input->GetInputValue(&active_element);
+
+	/* Check that all nodes are active, else return empty matrix */
+	if(!active_element){
+		if(domaintype!=Domain2DhorizontalEnum){
+			basalelement->DeleteMaterials();
+			delete basalelement;
+		}
+		return NULL;
+	}
+
+	/*Intermediaries */
+	IssmDouble  D,Jdet;
+	IssmDouble *xyz_list  = NULL;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = basalelement->GetNumberOfNodes();
+
+	/*Initialize Element vector*/
+	ElementMatrix* Ke    = basalelement->NewElementMatrix(NoneApproximationEnum);
+	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	basalelement->GetVerticesCoordinates(&xyz_list);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=basalelement->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		basalelement->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		basalelement->NodalFunctions(basis,gauss);
+		D=gauss->weight*Jdet;
+
+		TripleMultiply(basis,1,numnodes,1,
+					&D,1,1,0,
+					basis,1,numnodes,0,
+					&Ke->values[0],1);
+	}
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(basis);
+	delete gauss;
+	if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;};
+	return Ke;
+}/*}}}*/
+ElementVector* L2ProjectionEPLAnalysis::CreatePVector(Element* element){/*{{{*/
+
+	/*Intermediaries*/
+	int      domaintype;
+	bool     active_element;
+	Element* basalelement;
+
+	/*Get basal element*/
+	element->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DhorizontalEnum:
+			basalelement = element;
+			break;
+		case Domain3DEnum:
+			if(!element->IsOnBase()) return NULL;
+			basalelement = element->SpawnBasalElement();
+			break;
+		default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
+	}
+
+	Input* active_element_input = basalelement->GetInput(HydrologydcMaskEplactiveEltEnum); _assert_(active_element_input);
+	active_element_input->GetInputValue(&active_element);
+
+	/*Check that all nodes are active, else return empty matrix*/
+	if(!active_element) {
+		if(domaintype!=Domain2DhorizontalEnum){
+			basalelement->DeleteMaterials();
+			delete basalelement;
+		}
+		return NULL;
+	}
+	
+	/*Intermediaries */
+	int         input_enum,index;
+	IssmDouble  Jdet,slopes[2];
+	Input      *input     = NULL;
+	IssmDouble *xyz_list  = NULL;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = basalelement->GetNumberOfNodes();
+
+	/*Initialize Element vector*/
+	ElementVector* pe    = basalelement->NewElementVector();
+	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	basalelement->GetVerticesCoordinates(&xyz_list);
+	basalelement->FindParam(&input_enum,InputToL2ProjectEnum);
+	switch(input_enum){
+		case EplHeadSlopeXEnum: input = basalelement->GetInput(EplHeadEnum); index = 0; _assert_(input); break;
+		case EplHeadSlopeYEnum: input = basalelement->GetInput(EplHeadEnum); index = 1; _assert_(input); break;
+		default: _error_("not implemented");
+	}
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=basalelement->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		basalelement->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		basalelement->NodalFunctions(basis,gauss);
+
+		input->GetInputDerivativeValue(&slopes[0],xyz_list,gauss);
+		for(int i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*slopes[index]*basis[i];
+	}
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(basis);
+	delete gauss;
+	if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;};
+	return pe;
+}/*}}}*/
+void L2ProjectionEPLAnalysis::GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element){/*{{{*/
+	   _error_("not implemented yet");
+}/*}}}*/
+void L2ProjectionEPLAnalysis::InputUpdateFromSolution(IssmDouble* solution,Element* element){/*{{{*/
+	int inputenum,domaintype;
+
+	element->FindParam(&inputenum,InputToL2ProjectEnum);
+	element->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DhorizontalEnum:
+			element->InputUpdateFromSolutionOneDof(solution,inputenum);
+			break;
+		case Domain2DverticalEnum:
+			element->InputUpdateFromSolutionOneDof(solution,inputenum);
+			break;
+		case Domain3DEnum:
+			element->InputUpdateFromSolutionOneDofCollapsed(solution,inputenum);
+			break;
+		default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
+	}
+}/*}}}*/
+void L2ProjectionEPLAnalysis::UpdateConstraints(FemModel* femmodel){/*{{{*/
+	/*Default, do nothing*/
+	return;
+}/*}}}*/
+
Index: /issm/trunk/src/c/analyses/L2ProjectionEPLAnalysis.h
===================================================================
--- /issm/trunk/src/c/analyses/L2ProjectionEPLAnalysis.h	(revision 17806)
+++ /issm/trunk/src/c/analyses/L2ProjectionEPLAnalysis.h	(revision 17806)
@@ -0,0 +1,32 @@
+/*! \file L2ProjectionEPLAnalysis.h 
+ *  \brief: header file for generic external result object
+ */
+
+#ifndef _L2ProjectionEPLAnalysis_
+#define _L2ProjectionEPLAnalysis_
+
+/*Headers*/
+#include "./Analysis.h"
+
+class L2ProjectionEPLAnalysis: public Analysis{
+
+	public:
+		/*Model processing*/
+		int  DofsPerNode(int** doflist,int domaintype,int approximation);
+		void UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum);
+		void UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);
+		void CreateNodes(Nodes* nodes,IoModel* iomodel);
+		void CreateConstraints(Constraints* constraints,IoModel* iomodel);
+		void CreateLoads(Loads* loads, IoModel* iomodel);
+
+		/*Finite element Analysis*/
+		void           Core(FemModel* femmodel);
+		ElementVector* CreateDVector(Element* element);
+		ElementMatrix* CreateJacobianMatrix(Element* element);
+		ElementMatrix* CreateKMatrix(Element* element);
+		ElementVector* CreatePVector(Element* element);
+		void GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element);
+		void InputUpdateFromSolution(IssmDouble* solution,Element* element);
+		void UpdateConstraints(FemModel* femmodel);
+};
+#endif
Index: /issm/trunk/src/c/analyses/LevelsetAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/LevelsetAnalysis.cpp	(revision 17806)
+++ /issm/trunk/src/c/analyses/LevelsetAnalysis.cpp	(revision 17806)
@@ -0,0 +1,351 @@
+#ifdef HAVE_CONFIG_H
+   #include <config.h>
+#else
+#error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
+#endif
+#include "./LevelsetAnalysis.h"
+#include "../toolkits/toolkits.h"
+#include "../classes/classes.h"
+#include "../shared/shared.h"
+#include "../modules/modules.h"
+#include "../solutionsequences/solutionsequences.h"
+
+int LevelsetAnalysis::DofsPerNode(int** doflist,int domaintype,int approximation){/*{{{*/
+	return 1;
+}
+/*}}}*/
+void LevelsetAnalysis::UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum){/*{{{*/
+	return;
+}
+/*}}}*/
+void LevelsetAnalysis::UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type){/*{{{*/
+	int  finiteelement;
+
+	/*Finite element type*/
+	finiteelement = P1Enum;
+
+	/*Update elements: */
+	int counter=0;
+	for(int i=0;i<iomodel->numberofelements;i++){
+		if(iomodel->my_elements[i]){
+			Element* element=(Element*)elements->GetObjectByOffset(counter);
+			element->Update(i,iomodel,analysis_counter,analysis_type,finiteelement);
+			counter++;
+		}
+	}
+	
+	iomodel->FetchDataToInput(elements,MaskIceLevelsetEnum);
+	iomodel->FetchDataToInput(elements,VxEnum);
+	iomodel->FetchDataToInput(elements,VyEnum);
+	iomodel->FetchDataToInput(elements,MasstransportCalvingrateEnum);
+}
+/*}}}*/
+void LevelsetAnalysis::CreateNodes(Nodes* nodes,IoModel* iomodel){/*{{{*/
+	int finiteelement=P1Enum;
+	if(iomodel->domaintype!=Domain2DhorizontalEnum) iomodel->FetchData(2,MeshVertexonbaseEnum,MeshVertexonsurfaceEnum);
+	::CreateNodes(nodes,iomodel,LevelsetAnalysisEnum,finiteelement);
+	iomodel->DeleteData(2,MeshVertexonbaseEnum,MeshVertexonsurfaceEnum);
+}
+/*}}}*/
+void LevelsetAnalysis::CreateConstraints(Constraints* constraints,IoModel* iomodel){/*{{{*/
+	return;
+}
+/*}}}*/
+void LevelsetAnalysis::CreateLoads(Loads* loads, IoModel* iomodel){/*{{{*/
+	return;
+}/*}}}*/
+
+/*Finite element Analysis*/
+void LevelsetAnalysis::Core(FemModel* femmodel){/*{{{*/
+
+	#if !defined(_DEVELOPMENT_)
+	_error_("Not implemented yet");
+	#endif
+
+	/*parameters: */
+	bool save_results;
+	femmodel->parameters->FindParam(&save_results,SaveResultsEnum);
+
+	/*activate formulation: */
+	femmodel->SetCurrentConfiguration(LevelsetAnalysisEnum);
+
+	if(VerboseSolution()) _printf0_("call computational core:\n");
+	solutionsequence_linear(femmodel);
+
+	if(save_results){
+		if(VerboseSolution()) _printf0_("   saving results\n");
+		int outputs = MaskIceLevelsetEnum;
+		femmodel->RequestedOutputsx(&femmodel->results,&outputs,1);
+	}
+}/*}}}*/
+ElementVector* LevelsetAnalysis::CreateDVector(Element* element){/*{{{*/
+	/*Default, return NULL*/
+	return NULL;
+}/*}}}*/
+ElementMatrix* LevelsetAnalysis::CreateJacobianMatrix(Element* element){/*{{{*/
+	/* Jacobian required for the Newton solver */
+	_error_("not implemented yet");
+}/*}}}*/
+ElementMatrix* LevelsetAnalysis::CreateKMatrix(Element* element){/*{{{*/
+
+	_error_("NOT IMPLEMENTED YET");
+
+}/*}}}*/
+ElementVector* LevelsetAnalysis::CreatePVector(Element* element){/*{{{*/
+	
+	if(!element->IsOnBase()) return NULL;
+	Element* basalelement = element->SpawnBasalElement();
+
+	/*Intermediaries */
+	int i, ig, domaintype;
+	IssmDouble  Jdet,dt;
+	IssmDouble  lsf;
+	IssmDouble* xyz_list = NULL;
+	
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = basalelement->GetNumberOfNodes();
+
+	/*Initialize Element vector*/
+	ElementVector* pe = basalelement->NewElementVector();
+	basalelement->FindParam(&dt,TimesteppingTimeStepEnum);
+	
+	if(dt!=0.){
+		/*Initialize basis vector*/
+		IssmDouble*    basis = xNew<IssmDouble>(numnodes);
+
+		/*Retrieve all inputs and parameters*/
+		basalelement->GetVerticesCoordinates(&xyz_list);
+		Input* levelset_input     = basalelement->GetInput(MaskIceLevelsetEnum);                    _assert_(levelset_input);
+
+		/* Start  looping on the number of gaussian points: */
+		Gauss* gauss=basalelement->NewGauss(2);
+		for(ig=gauss->begin();ig<gauss->end();ig++){
+			gauss->GaussPoint(ig);
+
+			basalelement->JacobianDeterminant(&Jdet,xyz_list,gauss);
+			basalelement->NodalFunctions(basis,gauss);
+
+			/* old function value */
+			levelset_input->GetInputValue(&lsf,gauss);
+			for(i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*lsf*basis[i];
+		}
+
+		/*Clean up and return*/
+		xDelete<IssmDouble>(xyz_list);
+		xDelete<IssmDouble>(basis);
+		basalelement->FindParam(&domaintype,DomainTypeEnum);
+		if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;};
+		delete gauss;
+	}
+
+	return pe;
+}/*}}}*/
+void LevelsetAnalysis::GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element){/*{{{*/
+	_error_("not implemented yet");
+}/*}}}*/
+void LevelsetAnalysis::InputUpdateFromSolution(IssmDouble* solution,Element* element){/*{{{*/
+
+	int domaintype;
+	element->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DhorizontalEnum:
+			element->InputUpdateFromSolutionOneDof(solution,MaskIceLevelsetEnum);
+			break;
+		case Domain3DEnum:
+			element->InputUpdateFromSolutionOneDofCollapsed(solution,MaskIceLevelsetEnum);
+			break;
+		default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
+	}
+}/*}}}*/
+void LevelsetAnalysis::UpdateConstraints(FemModel* femmodel){/*{{{*/
+	/*Default, do nothing*/
+	return;
+}/*}}}*/
+void LevelsetAnalysis::GetB(IssmDouble* B,Element* element,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
+	/*Compute B  matrix. B=[B1 B2 B3] where Bi is of size 3*NDOF2. 
+	 * For node i, Bi can be expressed in the actual coordinate system
+	 * by: 
+	 *       Bi=[ N ]
+	 *          [ N ]
+	 * where N is the finiteelement function for node i.
+	 *
+	 * We assume B_prog has been allocated already, of size: 2x(NDOF1*numnodes)
+	 */
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Get nodal functions*/
+	IssmDouble* basis=xNew<IssmDouble>(numnodes);
+	element->NodalFunctions(basis,gauss);
+
+	/*Build B: */
+	for(int i=0;i<numnodes;i++){
+		B[numnodes*0+i] = basis[i];
+		B[numnodes*1+i] = basis[i];
+	}
+
+	/*Clean-up*/
+	xDelete<IssmDouble>(basis);
+}/*}}}*/
+void LevelsetAnalysis::GetBprime(IssmDouble* Bprime,Element* element,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
+	/*Compute B'  matrix. B'=[B1' B2' B3'] where Bi' is of size 3*NDOF2. 
+	 * For node i, Bi' can be expressed in the actual coordinate system
+	 * by: 
+	 *       Bi_prime=[ dN/dx ]
+	 *                [ dN/dy ]
+	 * where N is the finiteelement function for node i.
+	 *
+	 * We assume B' has been allocated already, of size: 3x(NDOF2*numnodes)
+	 */
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Get nodal functions derivatives*/
+	IssmDouble* dbasis=xNew<IssmDouble>(2*numnodes);
+	element->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+
+	/*Build B': */
+	for(int i=0;i<numnodes;i++){
+		Bprime[numnodes*0+i] = dbasis[0*numnodes+i];
+		Bprime[numnodes*1+i] = dbasis[1*numnodes+i];
+	}
+
+	/*Clean-up*/
+	xDelete<IssmDouble>(dbasis);
+
+}/*}}}*/
+void LevelsetAnalysis::SetDistanceOnIntersectedElements(FemModel* femmodel){/*{{{*/
+
+	/* Intermediaries */
+	int i,k;
+	IssmDouble dmaxp=0.,dmaxm=0,val=0.;
+
+	/*Initialize vector with number of vertices*/
+	int numvertices=femmodel->vertices->NumberOfVertices();
+	Element* element;
+
+	Vector<IssmDouble>* vec_dist_zerolevelset = NULL;
+	GetVectorFromInputsx(&vec_dist_zerolevelset, femmodel, MaskIceLevelsetEnum, VertexEnum);
+	
+	/* set NaN on elements intersected by zero levelset */
+	for(i=0;i<femmodel->elements->Size();i++){
+		element=dynamic_cast<Element*>(femmodel->elements->GetObjectByOffset(i));
+		if(element->IsZeroLevelset(MaskIceLevelsetEnum))
+			for(k=0;k<element->GetNumberOfVertices();k++)
+				vec_dist_zerolevelset->SetValue(element->vertices[k]->Sid(),NAN,INS_VAL); 
+	}
+
+	/* set distance on elements intersected by zero levelset */
+	for(i=0;i<femmodel->elements->Size();i++){
+		element=dynamic_cast<Element*>(femmodel->elements->GetObjectByOffset(i));
+		if(element->IsZeroLevelset(MaskIceLevelsetEnum)){
+			SetDistanceToZeroLevelsetElement(vec_dist_zerolevelset, element);
+
+			/* Get maximum distance to interface along vertices */
+			for(k=0;k<element->GetNumberOfVertices();k++){
+					vec_dist_zerolevelset->GetValue(&val,element->vertices[k]->Sid()); 
+					if((val>0.) && (val>dmaxp))
+						 dmaxp=val;
+					else if((val<0.) && (val<dmaxm))
+						 dmaxm=val;
+			}
+		}
+	}
+
+	/* set all none intersected vertices to max/min distance */
+	for(i=0;i<numvertices;i++){
+		vec_dist_zerolevelset->GetValue(&val,i);
+		if(val==1.) //FIXME: improve check
+			vec_dist_zerolevelset->SetValue(i,3.*dmaxp,INS_VAL);
+		else if(val==-1.)
+			vec_dist_zerolevelset->SetValue(i,3.*dmaxm,INS_VAL);
+	}
+
+	/*Assemble vector and serialize */
+	vec_dist_zerolevelset->Assemble();
+	IssmDouble* dist_zerolevelset=vec_dist_zerolevelset->ToMPISerial();
+	InputUpdateFromVectorx(femmodel,dist_zerolevelset,MaskIceLevelsetEnum,VertexSIdEnum);
+
+	/*Clean up and return*/
+	delete vec_dist_zerolevelset;
+	delete dist_zerolevelset;
+}/*}}}*/
+void LevelsetAnalysis::SetDistanceToZeroLevelsetElement(Vector<IssmDouble>* vec_signed_dist, Element* element){/*{{{*/
+
+	if(!element->IsZeroLevelset(MaskIceLevelsetEnum))
+		return;
+
+	/* Intermediaries */
+	const int dim=3;
+	int i,d;
+	int numvertices=element->GetNumberOfVertices();
+	IssmDouble s0[dim], s1[dim], v[dim];
+	IssmDouble dist,lsf_old;
+
+	IssmDouble* lsf = xNew<IssmDouble>(numvertices);
+	IssmDouble* sign_lsf = xNew<IssmDouble>(numvertices);
+	IssmDouble* signed_dist = xNew<IssmDouble>(numvertices);
+	IssmDouble* xyz_list = NULL;
+	IssmDouble* xyz_list_zero = NULL;
+
+	/* retrieve inputs and parameters */
+	element->GetVerticesCoordinates(&xyz_list);
+	element->GetInputListOnVertices(lsf,MaskIceLevelsetEnum);
+
+	/* get sign of levelset function */
+	for(i=0;i<numvertices;i++)
+		sign_lsf[i]=(lsf[i]>=0.?1.:-1.);
+
+	element->ZeroLevelsetCoordinates(&xyz_list_zero, xyz_list, MaskIceLevelsetEnum);
+	for(d=0;d<dim;d++){
+		s0[d]=xyz_list_zero[0+d];
+		s1[d]=xyz_list_zero[3+d];
+	}
+
+	/* get signed_distance of vertices to zero levelset straight */
+	for(i=0;i<numvertices;i++){
+		for(d=0;d<dim;d++)
+			v[d]=xyz_list[3*i+d];
+		dist=GetDistanceToStraight(&v[0],&s0[0],&s1[0]);
+		signed_dist[i]=sign_lsf[i]*dist;
+	}
+	
+	/* insert signed_distance into vec_signed_dist, if computed distance is smaller */
+	for(i=0;i<numvertices;i++){
+		vec_signed_dist->GetValue(&lsf_old, element->vertices[i]->Sid());
+		if(xIsNan<IssmDouble>(lsf_old) || fabs(signed_dist[i])<fabs(lsf_old))
+			vec_signed_dist->SetValue(element->vertices[i]->Sid(),signed_dist[i],INS_VAL);
+	}
+
+	xDelete<IssmDouble>(lsf);
+	xDelete<IssmDouble>(sign_lsf);
+	xDelete<IssmDouble>(signed_dist);
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(xyz_list_zero);
+}/*}}}*/
+IssmDouble LevelsetAnalysis::GetDistanceToStraight(IssmDouble* q, IssmDouble* s0, IssmDouble* s1){/*{{{*/
+	// returns distance d of point q to straight going through points s0, s1
+	// d=|a x b|/|b|
+	// with a=q-s0, b=s1-s0
+	
+	/* Intermediaries */
+	const int dim=2;
+	int i;
+	IssmDouble a[dim], b[dim];
+	IssmDouble norm_b;
+
+	for(i=0;i<dim;i++){
+		a[i]=q[i]-s0[i];
+		b[i]=s1[i]-s0[i];
+	}
+	
+	norm_b=0.;
+	for(i=0;i<dim;i++)
+		norm_b+=b[i]*b[i];
+	norm_b=sqrt(norm_b);
+	_assert_(norm_b>0.);
+
+	return fabs(a[0]*b[1]-a[1]*b[0])/norm_b;
+}/*}}}*/
Index: /issm/trunk/src/c/analyses/LevelsetAnalysis.h
===================================================================
--- /issm/trunk/src/c/analyses/LevelsetAnalysis.h	(revision 17806)
+++ /issm/trunk/src/c/analyses/LevelsetAnalysis.h	(revision 17806)
@@ -0,0 +1,37 @@
+/*! \file LevelsetAnalysis.h 
+ *  \brief: header file for generic external result object
+ */
+
+#ifndef _LevelsetAnalysis_
+#define _LevelsetAnalysis_
+
+/*Headers*/
+#include "./Analysis.h"
+
+class LevelsetAnalysis: public Analysis{
+
+	public:
+		/*Model processing*/
+		int  DofsPerNode(int** doflist,int domaintype,int approximation);
+		void UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum);
+		void UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);
+		void CreateNodes(Nodes* nodes,IoModel* iomodel);
+		void CreateConstraints(Constraints* constraints,IoModel* iomodel);
+		void CreateLoads(Loads* loads, IoModel* iomodel);
+
+		/*Finite element Analysis*/
+		void           Core(FemModel* femmodel);
+		ElementVector* CreateDVector(Element* element);
+		ElementMatrix* CreateJacobianMatrix(Element* element);
+		ElementMatrix* CreateKMatrix(Element* element);
+		ElementVector* CreatePVector(Element* element);
+		void GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element);
+		void InputUpdateFromSolution(IssmDouble* solution,Element* element);
+		void UpdateConstraints(FemModel* femmodel);
+		void GetB(IssmDouble* B,Element* element,IssmDouble* xyz_list,Gauss* gauss);
+		void GetBprime(IssmDouble* Bprime,Element* element,IssmDouble* xyz_list,Gauss* gauss);
+		void SetDistanceOnIntersectedElements(FemModel* femmodel);
+		void SetDistanceToZeroLevelsetElement(Vector<IssmDouble>* vec_signed_dist, Element* element);
+		IssmDouble GetDistanceToStraight(IssmDouble* q, IssmDouble* s0, IssmDouble* s1);
+};
+#endif
Index: /issm/trunk/src/c/analyses/LsfReinitializationAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/LsfReinitializationAnalysis.cpp	(revision 17806)
+++ /issm/trunk/src/c/analyses/LsfReinitializationAnalysis.cpp	(revision 17806)
@@ -0,0 +1,558 @@
+#include "./LsfReinitializationAnalysis.h"
+#include "../toolkits/toolkits.h"
+#include "../classes/classes.h"
+#include "../shared/shared.h"
+#include "../modules/modules.h"
+#include "../solutionsequences/solutionsequences.h"
+#include "../cores/cores.h"
+
+#include "../modules/GetVectorFromInputsx/GetVectorFromInputsx.h"
+
+/*Model processing*/
+int  LsfReinitializationAnalysis::DofsPerNode(int** doflist,int domaintype,int approximation){/*{{{*/
+	return 1;
+}/*}}}*/
+void LsfReinitializationAnalysis::UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum){/*{{{*/
+	/* Do nothing for now */
+}/*}}}*/
+void LsfReinitializationAnalysis::UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type){/*{{{*/
+	int    finiteelement;
+
+	/*Finite element type*/
+	finiteelement = P1Enum;
+
+	/*Update elements: */
+	int counter=0;
+	for(int i=0;i<iomodel->numberofelements;i++){
+		if(iomodel->my_elements[i]){
+			Element* element=(Element*)elements->GetObjectByOffset(counter);
+			element->Update(i,iomodel,analysis_counter,analysis_type,finiteelement);
+			counter++;
+		}
+	}
+
+	iomodel->FetchDataToInput(elements,MaskIceLevelsetEnum);
+}/*}}}*/
+void LsfReinitializationAnalysis::CreateNodes(Nodes* nodes,IoModel* iomodel){/*{{{*/
+	int finiteelement=P1Enum;
+	if(iomodel->domaintype!=Domain2DhorizontalEnum) iomodel->FetchData(2,MeshVertexonbaseEnum,MeshVertexonsurfaceEnum);
+	::CreateNodes(nodes,iomodel,LsfReinitializationAnalysisEnum,finiteelement);
+	iomodel->DeleteData(2,MeshVertexonbaseEnum,MeshVertexonsurfaceEnum);
+}/*}}}*/
+void LsfReinitializationAnalysis::CreateConstraints(Constraints* constraints,IoModel* iomodel){/*{{{*/
+	/* Do nothing for now */
+}/*}}}*/
+void LsfReinitializationAnalysis::CreateLoads(Loads* loads, IoModel* iomodel){/*{{{*/
+	/* Do nothing for now */
+}/*}}}*/
+
+/*Finite element Analysis*/
+void  LsfReinitializationAnalysis::Core(FemModel* femmodel){/*{{{*/
+
+	/*parameters: */
+	bool save_results;
+	int maxiter = 3;
+	int step;
+	IssmDouble reltol = 0.05;
+
+	Vector<IssmDouble>* lsfg     = NULL;
+	Vector<IssmDouble>* lsfg_old = NULL;
+
+	femmodel->parameters->FindParam(&save_results,SaveResultsEnum);
+
+	/*activate formulation: */
+	femmodel->SetCurrentConfiguration(LsfReinitializationAnalysisEnum);
+
+	/* set spcs for reinitialization */
+	if(VerboseSolution()) _printf0_("Update spcs for reinitialization:\n");
+	SetReinitSPCs(femmodel);
+
+	step = 1;
+	for(;;){
+
+		_printf_("smoothing lsf slope\n");
+		/* smoothen slope of lsf for computation of normal on ice domain*/
+		levelsetfunctionslope_core(femmodel);
+
+		//solve current artificial time step
+		if(VerboseSolution()) _printf0_("call computational core for reinitialization in step " << step << ":\n");
+		solutionsequence_linear(femmodel);
+		GetSolutionFromInputsx(&lsfg,femmodel);
+
+		if(step>1){
+			if(VerboseSolution()) _printf0_("   checking reinitialization convergence\n");
+			if(ReinitConvergence(lsfg,lsfg_old,reltol)) break;
+		}
+		if(step>maxiter){
+			if(VerboseSolution()) _printf0_("   maximum number reinitialization iterations " << maxiter << " reached\n");
+			break;
+		}
+
+		/*update results and increase counter*/
+		delete lsfg_old;lsfg_old=lsfg;
+		step++;
+	}
+
+	if(save_results){
+		if(VerboseSolution()) _printf0_("   saving results\n");
+		int outputs[1] = {MaskIceLevelsetEnum};
+		femmodel->RequestedOutputsx(&femmodel->results,&outputs[0],1);
+	}
+
+}/*}}}*/
+ElementVector* LsfReinitializationAnalysis::CreateDVector(Element* element){/*{{{*/
+	/*Default, return NULL*/
+	return NULL;
+}/*}}}*/
+ElementMatrix* LsfReinitializationAnalysis::CreateJacobianMatrix(Element* element){/*{{{*/
+	_error_("not implemented yet");
+}/*}}}*/
+ElementMatrix* LsfReinitializationAnalysis::CreateKMatrix(Element* element){/*{{{*/
+	
+	/*Intermediaries */
+	const int dim = 2;
+	int        i,row,col,stabilization;
+	IssmDouble Jdet,D_scalar;
+	IssmDouble dtau = 1.;
+	IssmDouble mu = 1.;
+	IssmDouble* xyz_list = NULL;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Initialize Element vector and other vectors*/
+	ElementMatrix* Ke     = element->NewElementMatrix();
+	IssmDouble*    basis    = xNew<IssmDouble>(numnodes);
+	IssmDouble*    Bprime = xNew<IssmDouble>(dim*numnodes);
+	IssmDouble*    D		= xNew<IssmDouble>(dim*dim);
+	IssmDouble*    dlsf	= xNew<IssmDouble>(dim);
+	IssmDouble*    normal= xNew<IssmDouble>(dim);
+
+	element->GetVerticesCoordinates(&xyz_list);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){/*{{{*/
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		D_scalar=gauss->weight*Jdet;
+
+		if(dtau!=0.){
+			element->NodalFunctions(basis,gauss);
+			TripleMultiply(basis,numnodes,1,0,
+						&D_scalar,1,1,0,
+						basis,1,numnodes,0,
+						&Ke->values[0],1);
+			D_scalar*=dtau;
+		}
+
+		GetBprime(Bprime,element,xyz_list,gauss);
+
+		for(row=0;row<dim;row++)
+			for(col=0;col<dim;col++)
+				if(row==col)
+					D[row*dim+col]=mu*D_scalar;
+				else
+					D[row*dim+col]=0.;
+		TripleMultiply(Bprime,dim,numnodes,1,
+					D,dim,dim,0,
+					Bprime,dim,numnodes,0,
+					&Ke->values[0],1);
+
+		/* Stabilization */
+		stabilization=0;
+		if (stabilization==0){/* no stabilization, do nothing*/}
+		
+	}/*}}}*/
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(basis);
+	xDelete<IssmDouble>(Bprime);
+	xDelete<IssmDouble>(D);
+	delete gauss;
+	return Ke;
+}/*}}}*/
+ElementVector* LsfReinitializationAnalysis::CreatePVector(Element* element){/*{{{*/
+	
+	/*Intermediaries */
+	int i,k;
+	int dim = 2;
+	IssmDouble dtau = 1.;
+	IssmDouble mu = 1.;
+	IssmDouble Jdet, D_scalar;
+	IssmDouble lsf;
+	IssmDouble norm_dlsf;
+	IssmDouble dbasis_normal;
+
+	/*Fetch number of nodes */
+	int numnodes = element->GetNumberOfNodes();
+
+	IssmDouble* xyz_list = NULL;
+	IssmDouble* basis = xNew<IssmDouble>(numnodes);
+	IssmDouble* dbasis=xNew<IssmDouble>(dim*numnodes);
+	IssmDouble* dlsf = xNew<IssmDouble>(dim);
+	IssmDouble* normal = xNew<IssmDouble>(dim);
+	element->GetVerticesCoordinates(&xyz_list);
+
+	/*Initialize Element vector*/
+	ElementVector* pe = element->NewElementVector();
+
+	/*Retrieve all inputs and parameters*/
+	Input* lsf_input = element->GetInput(MaskIceLevelsetEnum); _assert_(lsf_input);
+	Input* lsf_slopex_input=element->GetInput(LevelsetfunctionSlopeXEnum); _assert_(lsf_slopex_input);
+	Input* lsf_slopey_input=element->GetInput(LevelsetfunctionSlopeYEnum); _assert_(lsf_slopey_input);
+
+	Gauss* gauss=element->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		element->NodalFunctions(basis,gauss);
+		element->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+
+		D_scalar=Jdet*gauss->weight;
+
+		if(dtau!=0.){
+			/* old function value */
+			lsf_input->GetInputValue(&lsf,gauss);
+			for(i=0;i<numnodes;i++) pe->values[i]+=D_scalar*lsf*basis[i];
+			D_scalar*=dtau;
+		}
+
+		lsf_slopex_input->GetInputValue(&dlsf[0],gauss);
+		lsf_slopey_input->GetInputValue(&dlsf[1],gauss);
+
+		/*get normal*/
+		norm_dlsf=0.;
+		for(i=0;i<dim;i++) norm_dlsf+=dlsf[i]*dlsf[i]; 
+		norm_dlsf=sqrt(norm_dlsf);
+		if(norm_dlsf>0.)
+			for(i=0;i<dim;i++)	normal[i]=dlsf[i]/norm_dlsf;
+		else
+			for(i=0;i<dim;i++)	normal[i]=0.;
+
+		/* multiply normal and dbasis */
+		for(i=0;i<numnodes;i++){
+			dbasis_normal=0.;
+			for(k=0;k<dim;k++) dbasis_normal+=dbasis[k*numnodes+i]*normal[k];
+			pe->values[i]+=D_scalar*mu*dbasis_normal; 
+		}
+	}
+
+	xDelete<IssmDouble>(basis);
+	xDelete<IssmDouble>(dbasis);
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(dlsf);
+	xDelete<IssmDouble>(normal);
+	return pe;
+	}/*}}}*/
+void LsfReinitializationAnalysis::GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element){/*{{{*/
+
+	IssmDouble   lsf;
+	int          dim;
+	int*         doflist = NULL;
+
+	/*Get some parameters*/
+	element->FindParam(&dim,DomainDimensionEnum);
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Fetch dof list and allocate solution vector*/
+	element->GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
+	IssmDouble* values = xNew<IssmDouble>(numnodes);
+
+	/*Get inputs*/
+	Input* lsf_input=element->GetInput(MaskIceLevelsetEnum); _assert_(lsf_input);
+
+	Gauss* gauss=element->NewGauss();
+	for(int i=0;i<numnodes;i++){
+		gauss->GaussNode(element->FiniteElement(),i);
+
+		lsf_input->GetInputValue(&lsf,gauss);
+		values[i]=lsf;
+	}
+
+	solution->SetValues(numnodes,doflist,values,INS_VAL);
+
+	/*Free ressources:*/
+	delete gauss;
+	xDelete<IssmDouble>(values);
+	xDelete<int>(doflist);
+
+}/*}}}*/
+void LsfReinitializationAnalysis::InputUpdateFromSolution(IssmDouble* solution,Element* element){/*{{{*/
+
+	int domaintype;
+	element->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DhorizontalEnum:
+			element->InputUpdateFromSolutionOneDof(solution,MaskIceLevelsetEnum);
+			break;
+		case Domain3DEnum:
+			element->InputUpdateFromSolutionOneDofCollapsed(solution,MaskIceLevelsetEnum);
+			break;
+		default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
+	}
+}/*}}}*/
+void LsfReinitializationAnalysis::UpdateConstraints(FemModel* femmodel){/*{{{*/
+	/* Do nothing for now */
+}/*}}}*/
+void LsfReinitializationAnalysis::GetB(IssmDouble* B,Element* element,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
+	/*Compute B  matrix. B=[B1 B2 B3] where Bi is of size 3*NDOF2. 
+	 * For node i, Bi can be expressed in the actual coordinate system
+	 * by: 
+	 *       Bi=[ N ]
+	 *          [ N ]
+	 * where N is the finiteelement function for node i.
+	 *
+	 * We assume B_prog has been allocated already, of size: 2x(NDOF1*numnodes)
+	 */
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Get nodal functions*/
+	IssmDouble* basis=xNew<IssmDouble>(numnodes);
+	element->NodalFunctions(basis,gauss);
+
+	/*Build B: */
+	for(int i=0;i<numnodes;i++){
+		B[numnodes*0+i] = basis[i];
+		B[numnodes*1+i] = basis[i];
+	}
+
+	/*Clean-up*/
+	xDelete<IssmDouble>(basis);
+}/*}}}*/
+void LsfReinitializationAnalysis::GetBprime(IssmDouble* Bprime,Element* element,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
+	/*Compute B'  matrix. B'=[B1' B2' B3'] where Bi' is of size 3*NDOF2. 
+	 * For node i, Bi' can be expressed in the actual coordinate system
+	 * by: 
+	 *       Bi_prime=[ dN/dx ]
+	 *                [ dN/dy ]
+	 * where N is the finiteelement function for node i.
+	 *
+	 * We assume B' has been allocated already, of size: 3x(NDOF2*numnodes)
+	 */
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Get nodal functions derivatives*/
+	IssmDouble* dbasis=xNew<IssmDouble>(2*numnodes);
+	element->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+
+	/*Build B': */
+	for(int i=0;i<numnodes;i++){
+		Bprime[numnodes*0+i] = dbasis[0*numnodes+i];
+		Bprime[numnodes*1+i] = dbasis[1*numnodes+i];
+	}
+
+	/*Clean-up*/
+	xDelete<IssmDouble>(dbasis);
+
+}/*}}}*/
+
+/* Other */
+void LsfReinitializationAnalysis::SetReinitSPCs(FemModel* femmodel){/*{{{*/
+
+	int i,k, numnodes;
+	Element* element;
+	Node* node;
+
+	/* deactivate all spcs */
+	for(i=0;i<femmodel->elements->Size();i++){
+		element=dynamic_cast<Element*>(femmodel->elements->GetObjectByOffset(i));
+		for(k=0;k<element->GetNumberOfNodes();k++){
+			node=element->GetNode(k);
+			if(node->IsActive()){
+				node->DofInFSet(0); 
+			}
+		}
+	}
+
+	SetDistanceOnIntersectedElements(femmodel);
+
+	/* reactivate spcs on elements intersected by zero levelset */
+	for(i=0;i<femmodel->elements->Size();i++){
+		element=dynamic_cast<Element*>(femmodel->elements->GetObjectByOffset(i));
+		if(element->IsZeroLevelset(MaskIceLevelsetEnum)){
+			/*iterate over nodes and set spc */
+			numnodes=element->GetNumberOfNodes();
+			IssmDouble* lsf = xNew<IssmDouble>(numnodes);
+			element->GetInputListOnNodes(&lsf[0],MaskIceLevelsetEnum);
+			for(k=0;k<numnodes;k++){
+				node=element->GetNode(k);
+				if(node->IsActive()){
+					node->ApplyConstraint(0,lsf[k]);
+				}
+			}
+			xDelete<IssmDouble>(lsf);
+		}
+	}
+
+}/*}}}*/
+void LsfReinitializationAnalysis::SetDistanceOnIntersectedElements(FemModel* femmodel){/*{{{*/
+
+	/* Intermediaries */
+	int i,k;
+	IssmDouble dmaxp,dmaxm,val;
+	Element* element;
+
+	/*Initialize vector with number of vertices*/
+	int numvertices=femmodel->vertices->NumberOfVertices();
+
+	Vector<IssmDouble>* vec_dist_zerolevelset = NULL;
+	GetVectorFromInputsx(&vec_dist_zerolevelset, femmodel, MaskIceLevelsetEnum, VertexEnum);
+	
+	/* set distance on elements intersected by zero levelset */
+	for(i=0;i<femmodel->elements->Size();i++){
+		element=dynamic_cast<Element*>(femmodel->elements->GetObjectByOffset(i));
+		if(element->IsZeroLevelset(MaskIceLevelsetEnum)){
+			SetDistanceToZeroLevelsetElement(vec_dist_zerolevelset, element);
+		}
+	}
+	vec_dist_zerolevelset->Assemble();
+
+	/* Get maximum distance to interface along vertices */
+	dmaxp=0.; dmaxm=0.;
+	for(i=0;i<numvertices;i++){
+		vec_dist_zerolevelset->GetValue(&val,i); 
+		if((val>0.) && (val>dmaxp))
+			 dmaxp=val;
+		else if((val<0.) && (val<dmaxm))
+			 dmaxm=val;
+	}
+	//wait until all values are computed
+
+	/* set all none intersected vertices to max/min distance */
+	for(i=0;i<numvertices;i++){
+		vec_dist_zerolevelset->GetValue(&val,i);
+		if(val==1.) //FIXME: improve check
+			vec_dist_zerolevelset->SetValue(i,3.*dmaxp,INS_VAL);
+		else if(val==-1.)
+			vec_dist_zerolevelset->SetValue(i,3.*dmaxm,INS_VAL);
+	}
+
+	/*Assemble vector and serialize */
+	vec_dist_zerolevelset->Assemble();
+	IssmDouble* dist_zerolevelset=vec_dist_zerolevelset->ToMPISerial();
+	InputUpdateFromVectorx(femmodel,dist_zerolevelset,MaskIceLevelsetEnum,VertexSIdEnum);
+
+	/*Clean up and return*/
+	delete vec_dist_zerolevelset;
+	delete dist_zerolevelset;
+
+}/*}}}*/
+void LsfReinitializationAnalysis::SetDistanceToZeroLevelsetElement(Vector<IssmDouble>* vec_signed_dist, Element* element){/*{{{*/
+
+	if(!element->IsZeroLevelset(MaskIceLevelsetEnum))
+		return;
+
+	/* Intermediaries */
+	int dim=3;
+	int i,d;
+	IssmDouble dist,lsf_old;
+
+	int numvertices=element->GetNumberOfVertices();
+
+	IssmDouble* lsf = xNew<IssmDouble>(numvertices);
+	IssmDouble* sign_lsf = xNew<IssmDouble>(numvertices);
+	IssmDouble* signed_dist = xNew<IssmDouble>(numvertices);
+	IssmDouble* s0 = xNew<IssmDouble>(dim);
+	IssmDouble* s1 = xNew<IssmDouble>(dim);
+	IssmDouble* v = xNew<IssmDouble>(dim);
+	IssmDouble* xyz_list = NULL;
+	IssmDouble* xyz_list_zero = NULL;
+
+	/* retrieve inputs and parameters */
+	element->GetVerticesCoordinates(&xyz_list);
+	element->GetInputListOnVertices(lsf,MaskIceLevelsetEnum);
+
+	/* get sign of levelset function */
+	for(i=0;i<numvertices;i++)
+		sign_lsf[i]=(lsf[i]>=0.?1.:-1.);
+
+	element->ZeroLevelsetCoordinates(&xyz_list_zero, xyz_list, MaskIceLevelsetEnum);
+	for(i=0;i<dim;i++){
+		s0[i]=xyz_list_zero[0+i];
+		s1[i]=xyz_list_zero[3+i];
+	}
+
+	/* get signed_distance of vertices to zero levelset straight */
+	for(i=0;i<numvertices;i++){
+		for(d=0;d<dim;d++)
+			v[d]=xyz_list[dim*i+d];
+		dist=GetDistanceToStraight(&v[0],&s0[0],&s1[0]);
+		signed_dist[i]=sign_lsf[i]*dist;
+	}
+	
+	/* insert signed_distance into vec_signed_dist, if computed distance is smaller */
+	for(i=0;i<numvertices;i++){
+		vec_signed_dist->GetValue(&lsf_old, element->vertices[i]->Sid());
+		/* initial lsf values are +-1. Update those fields or if distance to interface smaller.*/
+		if(fabs(lsf_old)==1. || fabs(signed_dist[i])<fabs(lsf_old))
+			vec_signed_dist->SetValue(element->vertices[i]->Sid(),signed_dist[i],INS_VAL);
+	}
+
+	xDelete<IssmDouble>(lsf);
+	xDelete<IssmDouble>(sign_lsf);
+	xDelete<IssmDouble>(signed_dist);
+	xDelete<IssmDouble>(s0);
+	xDelete<IssmDouble>(s1);
+	xDelete<IssmDouble>(v);
+
+}/*}}}*/
+IssmDouble LsfReinitializationAnalysis::GetDistanceToStraight(IssmDouble* q, IssmDouble* s0, IssmDouble* s1){/*{{{*/
+	// returns distance d of point q to straight going through points s0, s1
+	// d=|a x b|/|b|
+	// with a=q-s0, b=s1-s0
+	
+	/* Intermediaries */
+	const int dim=2;
+	int i;
+	IssmDouble a[dim], b[dim];
+	IssmDouble norm_b;
+
+	for(i=0;i<dim;i++){
+		a[i]=q[i]-s0[i];
+		b[i]=s1[i]-s0[i];
+	}
+	
+	norm_b=0.;
+	for(i=0;i<dim;i++)
+		norm_b+=b[i]*b[i];
+	norm_b=sqrt(norm_b);
+	_assert_(norm_b>0.);
+
+	return fabs(a[0]*b[1]-a[1]*b[0])/norm_b;
+}/*}}}*/
+bool LsfReinitializationAnalysis::ReinitConvergence(Vector<IssmDouble>* lsfg,Vector<IssmDouble>* lsfg_old,IssmDouble reltol){/*{{{*/
+
+	/*Output*/
+	bool converged = true;
+
+	/*Intermediary*/
+	Vector<IssmDouble>* dlsfg    = NULL;
+	IssmDouble          norm_dlsf,norm_lsf;
+
+	/*compute norm(du)/norm(u)*/
+	dlsfg=lsfg_old->Duplicate(); lsfg_old->Copy(dlsfg); dlsfg->AYPX(lsfg,-1.0);
+	norm_dlsf=dlsfg->Norm(NORM_TWO); norm_lsf=lsfg_old->Norm(NORM_TWO);
+	if (xIsNan<IssmDouble>(norm_dlsf) || xIsNan<IssmDouble>(norm_lsf)) _error_("convergence criterion is NaN!");
+	if((norm_dlsf/norm_lsf)<reltol){
+		if(VerboseConvergence()) _printf0_("\n"<<setw(50)<<left<<"   Velocity convergence: norm(du)/norm(u)"<<norm_dlsf/norm_lsf*100<<" < "<<reltol*100<<" %\n");
+	}
+	else{ 
+		if(VerboseConvergence()) _printf0_("\n"<<setw(50)<<left<<"   Velocity convergence: norm(du)/norm(u)"<<norm_dlsf/norm_lsf*100<<" > "<<reltol*100<<" %\n");
+		converged=false;
+	}
+
+	/*Cleanup*/
+	delete dlsfg;
+
+	return converged;
+}/*}}}*/
Index: /issm/trunk/src/c/analyses/LsfReinitializationAnalysis.h
===================================================================
--- /issm/trunk/src/c/analyses/LsfReinitializationAnalysis.h	(revision 17806)
+++ /issm/trunk/src/c/analyses/LsfReinitializationAnalysis.h	(revision 17806)
@@ -0,0 +1,41 @@
+/*! \file LsfReinitializationAnalysis.h 
+ *  \brief: header file for generic external result object
+ */
+
+#ifndef _LsfReinitializationAnalysis_
+#define _LsfReinitializationAnalysis_
+
+/*Headers*/
+#include "./Analysis.h"
+
+class LsfReinitializationAnalysis: public Analysis{
+	
+public:
+	/*Model processing*/
+	int  DofsPerNode(int** doflist,int domaintype,int approximation);
+	void UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum);
+	void UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);
+	void CreateNodes(Nodes* nodes,IoModel* iomodel);
+	void CreateConstraints(Constraints* constraints,IoModel* iomodel);
+	void CreateLoads(Loads* loads, IoModel* iomodel);
+
+	/*Finite element Analysis*/
+	void           Core(FemModel* femmodel);
+	ElementVector* CreateDVector(Element* element);
+	ElementMatrix* CreateJacobianMatrix(Element* element);
+	ElementMatrix* CreateKMatrix(Element* element);
+	ElementVector* CreatePVector(Element* element);
+	void GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element);
+	void InputUpdateFromSolution(IssmDouble* solution,Element* element);
+	void UpdateConstraints(FemModel* femmodel);
+	void GetB(IssmDouble* B,Element* element,IssmDouble* xyz_list,Gauss* gauss);
+	void GetBprime(IssmDouble* Bprime,Element* element,IssmDouble* xyz_list,Gauss* gauss);
+	
+	/* Other */
+	void SetReinitSPCs(FemModel* femmodel);
+	void SetDistanceOnIntersectedElements(FemModel* femmodel);
+	void SetDistanceToZeroLevelsetElement(Vector<IssmDouble>* vec_dist, Element* element);
+	IssmDouble GetDistanceToStraight(IssmDouble* q, IssmDouble* s0, IssmDouble* s1);
+	bool ReinitConvergence(Vector<IssmDouble>* lsfg,Vector<IssmDouble>* lsfg_old,IssmDouble reltol);
+};
+#endif
Index: /issm/trunk/src/c/analyses/MasstransportAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/MasstransportAnalysis.cpp	(revision 17805)
+++ /issm/trunk/src/c/analyses/MasstransportAnalysis.cpp	(revision 17806)
@@ -6,15 +6,29 @@
 
 /*Model processing*/
-int  MasstransportAnalysis::DofsPerNode(int** doflist,int meshtype,int approximation){/*{{{*/
+int  MasstransportAnalysis::DofsPerNode(int** doflist,int domaintype,int approximation){/*{{{*/
 	return 1;
 }/*}}}*/
 void MasstransportAnalysis::UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum){/*{{{*/
 
+	int     numoutputs;
+	char**  requestedoutputs = NULL;
+
 	parameters->AddObject(iomodel->CopyConstantObject(FlowequationIsFSEnum));
 
+	parameters->AddObject(iomodel->CopyConstantObject(MasstransportIsfreesurfaceEnum));
+	parameters->AddObject(iomodel->CopyConstantObject(MasstransportHydrostaticAdjustmentEnum));
+	parameters->AddObject(iomodel->CopyConstantObject(MasstransportStabilizationEnum));
+	parameters->AddObject(iomodel->CopyConstantObject(MasstransportMinThicknessEnum));
+	parameters->AddObject(iomodel->CopyConstantObject(MasstransportPenaltyFactorEnum));
+
+	iomodel->FetchData(&requestedoutputs,&numoutputs,MasstransportRequestedOutputsEnum);
+	parameters->AddObject(new IntParam(MasstransportNumRequestedOutputsEnum,numoutputs));
+	if(numoutputs)parameters->AddObject(new StringArrayParam(MasstransportRequestedOutputsEnum,requestedoutputs,numoutputs));
+	iomodel->DeleteData(&requestedoutputs,numoutputs,MasstransportRequestedOutputsEnum);
+
 }/*}}}*/
 void MasstransportAnalysis::UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type){/*{{{*/
 
-	int    stabilization,finiteelement;
+	int    stabilization,finiteelement,smb_model;
 	bool   dakota_analysis;
 	bool   issmbgradients;
@@ -22,12 +36,12 @@
 	bool   isdelta18o;
 	bool   isgroundingline;
+	bool   islevelset;
 
 	/*Fetch data needed: */
 	iomodel->Constant(&stabilization,MasstransportStabilizationEnum);
 	iomodel->Constant(&dakota_analysis,QmuIsdakotaEnum);
-	iomodel->Constant(&ispdd,SurfaceforcingsIspddEnum);
-	iomodel->Constant(&isdelta18o,SurfaceforcingsIsdelta18oEnum);
-	iomodel->Constant(&issmbgradients,SurfaceforcingsIssmbgradientsEnum);
+	iomodel->Constant(&smb_model,SurfaceforcingsEnum);
 	iomodel->Constant(&isgroundingline,TransientIsgroundinglineEnum);
+	iomodel->Constant(&islevelset,TransientIslevelsetEnum);
 
 	/*Finite element type*/
@@ -49,5 +63,5 @@
 	iomodel->FetchDataToInput(elements,ThicknessEnum);
 	iomodel->FetchDataToInput(elements,SurfaceEnum);
-	iomodel->FetchDataToInput(elements,BedEnum);
+	iomodel->FetchDataToInput(elements,BaseEnum);
 	iomodel->FetchDataToInput(elements,MaskIceLevelsetEnum);
 	iomodel->FetchDataToInput(elements,MaskGroundediceLevelsetEnum);
@@ -62,5 +76,5 @@
 
 	if(dakota_analysis){
-		elements->InputDuplicate(BedEnum,QmuBedEnum);
+		elements->InputDuplicate(BaseEnum,QmuBaseEnum);
 		elements->InputDuplicate(ThicknessEnum,QmuThicknessEnum);
 		elements->InputDuplicate(SurfaceEnum,QmuSurfaceEnum);
@@ -69,30 +83,45 @@
 	}
 
-	if(iomodel->meshtype==Mesh3DEnum){
-		iomodel->FetchDataToInput(elements,MeshElementonbedEnum);
+	if(iomodel->domaintype==Domain3DEnum){
+		iomodel->FetchDataToInput(elements,MeshElementonbaseEnum);
 		iomodel->FetchDataToInput(elements,MeshElementonsurfaceEnum);
 	}
 
-	if(issmbgradients){
-		iomodel->FetchDataToInput(elements,SurfaceforcingsHrefEnum);
-		iomodel->FetchDataToInput(elements,SurfaceforcingsSmbrefEnum);
-		iomodel->FetchDataToInput(elements,SurfaceforcingsBPosEnum);
-		iomodel->FetchDataToInput(elements,SurfaceforcingsBNegEnum);
-	}
-	if(ispdd){
-		iomodel->FetchDataToInput(elements,ThermalSpctemperatureEnum);
-		if(isdelta18o){
-			iomodel->FetchDataToInput(elements,SurfaceforcingsTemperaturesLgmEnum);
-			iomodel->FetchDataToInput(elements,SurfaceforcingsTemperaturesPresentdayEnum);
-			iomodel->FetchDataToInput(elements,SurfaceforcingsPrecipitationsPresentdayEnum);
-		}
-		else{
-			iomodel->FetchDataToInput(elements,SurfaceforcingsPrecipitationEnum);
-			iomodel->FetchDataToInput(elements,SurfaceforcingsMonthlytemperaturesEnum);
-		}
-	}
-	if(~ispdd && ~issmbgradients){
-		iomodel->FetchDataToInput(elements,SurfaceforcingsMassBalanceEnum,0.);
-	}
+	if(islevelset){
+		iomodel->FetchDataToInput(elements,IceMaskNodeActivationEnum);
+		if(iomodel->domaintype!=Domain2DhorizontalEnum)
+			iomodel->FetchDataToInput(elements,MeshVertexonbaseEnum); // required for updating active nodes
+	}
+
+	switch(smb_model){
+		case SMBEnum:
+			iomodel->FetchDataToInput(elements,SurfaceforcingsMassBalanceEnum,0.);
+			break;
+		case SMBpddEnum:
+			iomodel->Constant(&isdelta18o,SurfaceforcingsIsdelta18oEnum);
+			iomodel->FetchDataToInput(elements,ThermalSpctemperatureEnum);
+			if(isdelta18o){
+				iomodel->FetchDataToInput(elements,SurfaceforcingsTemperaturesLgmEnum);
+				iomodel->FetchDataToInput(elements,SurfaceforcingsTemperaturesPresentdayEnum);
+				iomodel->FetchDataToInput(elements,SurfaceforcingsPrecipitationsPresentdayEnum);
+			}
+			else{
+				iomodel->FetchDataToInput(elements,SurfaceforcingsPrecipitationEnum);
+				iomodel->FetchDataToInput(elements,SurfaceforcingsMonthlytemperaturesEnum);
+			}
+			break;
+		case SMBgradientsEnum:
+			iomodel->FetchDataToInput(elements,SurfaceforcingsHrefEnum);
+			iomodel->FetchDataToInput(elements,SurfaceforcingsSmbrefEnum);
+			iomodel->FetchDataToInput(elements,SurfaceforcingsBPosEnum);
+			iomodel->FetchDataToInput(elements,SurfaceforcingsBNegEnum);
+			break;
+		case SMBhenningEnum:
+			iomodel->FetchDataToInput(elements,SurfaceforcingsSmbrefEnum,0.);
+			break;
+		default:
+			_error_("Surface mass balance model "<<EnumToStringx(smb_model)<<" not supported yet");
+	}
+
 }/*}}}*/
 void MasstransportAnalysis::CreateNodes(Nodes* nodes,IoModel* iomodel){/*{{{*/
@@ -103,8 +132,8 @@
 
 	/*Check in 3d*/
-	if(stabilization==3 && iomodel->meshtype==Mesh3DEnum) _error_("DG 3d not implemented yet");
+	if(stabilization==3 && iomodel->domaintype==Domain3DEnum) _error_("DG 3d not implemented yet");
 
 	/*Create Nodes either DG or CG depending on stabilization*/
-	if(iomodel->meshtype!=Mesh2DhorizontalEnum) iomodel->FetchData(2,MeshVertexonbedEnum,MeshVertexonsurfaceEnum);
+	if(iomodel->domaintype!=Domain2DhorizontalEnum) iomodel->FetchData(2,MeshVertexonbaseEnum,MeshVertexonsurfaceEnum);
 	if(stabilization!=3){
 		::CreateNodes(nodes,iomodel,MasstransportAnalysisEnum,P1Enum);
@@ -113,5 +142,5 @@
 		::CreateNodes(nodes,iomodel,MasstransportAnalysisEnum,P1DGEnum);
 	}
-	iomodel->DeleteData(2,MeshVertexonbedEnum,MeshVertexonsurfaceEnum);
+	iomodel->DeleteData(2,MeshVertexonbaseEnum,MeshVertexonsurfaceEnum);
 }/*}}}*/
 void MasstransportAnalysis::CreateConstraints(Constraints* constraints,IoModel* iomodel){/*{{{*/
@@ -164,7 +193,7 @@
 	/*Create Penpair for vertex_pairing: */
 	IssmDouble *vertex_pairing=NULL;
-	IssmDouble *nodeonbed=NULL;
+	IssmDouble *nodeonbase=NULL;
 	iomodel->FetchData(&vertex_pairing,&numvertex_pairing,NULL,MasstransportVertexPairingEnum);
-	iomodel->FetchData(&nodeonbed,NULL,NULL,MeshVertexonbedEnum);
+	if(iomodel->domaintype!=Domain2DhorizontalEnum) iomodel->FetchData(&nodeonbase,NULL,NULL,MeshVertexonbaseEnum);
 
 	for(int i=0;i<numvertex_pairing;i++){
@@ -176,5 +205,7 @@
 
 			/*Skip if one of the two is not on the bed*/
-			if(!(reCast<bool>(nodeonbed[reCast<int>(vertex_pairing[2*i+0])-1])) || !(reCast<bool>(nodeonbed[reCast<int>(vertex_pairing[2*i+1])-1]))) continue;
+			if(iomodel->domaintype!=Domain2DhorizontalEnum){
+				if(!(reCast<bool>(nodeonbase[reCast<int>(vertex_pairing[2*i+0])-1])) || !(reCast<bool>(nodeonbase[reCast<int>(vertex_pairing[2*i+1])-1]))) continue;
+			}
 
 			/*Get node ids*/
@@ -193,5 +224,539 @@
 	/*free ressources: */
 	iomodel->DeleteData(vertex_pairing,MasstransportVertexPairingEnum);
-	iomodel->DeleteData(nodeonbed,MeshVertexonbedEnum);
-
-}/*}}}*/
+	iomodel->DeleteData(nodeonbase,MeshVertexonbaseEnum);
+
+}/*}}}*/
+
+/*Finite Element Analysis*/
+void           MasstransportAnalysis::Core(FemModel* femmodel){/*{{{*/
+	_error_("not implemented");
+}/*}}}*/
+ElementVector* MasstransportAnalysis::CreateDVector(Element* element){/*{{{*/
+	/*Default, return NULL*/
+	return NULL;
+}/*}}}*/
+ElementMatrix* MasstransportAnalysis::CreateJacobianMatrix(Element* element){/*{{{*/
+_error_("Not implemented");
+}/*}}}*/
+ElementMatrix* MasstransportAnalysis::CreateKMatrix(Element* element){/*{{{*/
+
+	/* Check if ice in element */
+	if(!element->IsIceInElement()) return NULL;
+
+	if(!element->IsOnBase()) return NULL;
+	Element* basalelement = element->SpawnBasalElement();
+
+	ElementMatrix* Ke = NULL;
+	switch(element->FiniteElement()){
+		case P1Enum: case P2Enum:
+			Ke = CreateKMatrixCG(basalelement);
+			break;
+		case P1DGEnum:
+			Ke = CreateKMatrixDG(basalelement);
+			break;
+		default:
+			_error_("Element type " << EnumToStringx(element->FiniteElement()) << " not supported yet");
+	}
+
+	int domaintype;
+	element->FindParam(&domaintype,DomainTypeEnum);
+	if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;};
+	return Ke;
+}/*}}}*/
+ElementMatrix* MasstransportAnalysis::CreateKMatrixCG(Element* element){/*{{{*/
+
+	/* Check if ice in element */
+	if(!element->IsIceInElement()) return NULL;
+
+	/*Intermediaries */
+	int        stabilization;
+	int        domaintype,dim;
+	IssmDouble Jdet,D_scalar,dt,h;
+	IssmDouble vel,vx,vy,dvxdx,dvydy;
+	IssmDouble dvx[2],dvy[2];
+	IssmDouble* xyz_list = NULL;
+
+	/*Get problem dimension*/
+	element->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DverticalEnum:   dim = 1; break;
+		case Domain2DhorizontalEnum: dim = 2; break;
+		case Domain3DEnum:           dim = 2; break;
+		default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
+	}
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Initialize Element vector and other vectors*/
+	ElementMatrix* Ke     = element->NewElementMatrix();
+	IssmDouble*    basis  = xNew<IssmDouble>(numnodes);
+	IssmDouble*    B      = xNew<IssmDouble>(dim*numnodes);
+	IssmDouble*    Bprime = xNew<IssmDouble>(dim*numnodes);
+	IssmDouble*    D      = xNewZeroInit<IssmDouble>(dim*dim);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+	element->FindParam(&dt,TimesteppingTimeStepEnum);
+	element->FindParam(&domaintype,DomainTypeEnum);
+	element->FindParam(&stabilization,MasstransportStabilizationEnum);
+	Input* vxaverage_input=NULL;
+	Input* vyaverage_input=NULL;
+	if(domaintype==Domain2DhorizontalEnum){
+		vxaverage_input=element->GetInput(VxEnum); _assert_(vxaverage_input);
+		vyaverage_input=element->GetInput(VyEnum); _assert_(vyaverage_input);
+	}
+	else{
+		if(dim==1){
+			vxaverage_input=element->GetInput(VxEnum); _assert_(vxaverage_input);
+		}
+		if(dim==2){
+			vxaverage_input=element->GetInput(VxAverageEnum); _assert_(vxaverage_input);
+			vyaverage_input=element->GetInput(VyAverageEnum); _assert_(vyaverage_input);
+		}
+
+	}
+	h = element->CharacteristicLength();
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		element->NodalFunctions(basis,gauss);
+
+		vxaverage_input->GetInputValue(&vx,gauss);
+		vxaverage_input->GetInputDerivativeValue(&dvx[0],xyz_list,gauss);
+		if(dim==2){
+			vyaverage_input->GetInputValue(&vy,gauss);
+			vyaverage_input->GetInputDerivativeValue(&dvy[0],xyz_list,gauss);
+		}
+
+		D_scalar=gauss->weight*Jdet;
+		TripleMultiply(basis,1,numnodes,1,
+					&D_scalar,1,1,0,
+					basis,1,numnodes,0,
+					&Ke->values[0],1);
+
+		GetB(B,element,dim,xyz_list,gauss);
+		GetBprime(Bprime,element,dim,xyz_list,gauss);
+
+		dvxdx=dvx[0];
+		if(dim==2) dvydy=dvy[1];
+		D_scalar=dt*gauss->weight*Jdet;
+
+		D[0*dim+0]=D_scalar*dvxdx;
+		if(dim==2) D[1*dim+1]=D_scalar*dvydy;
+
+		TripleMultiply(B,dim,numnodes,1,
+					D,dim,dim,0,
+					B,dim,numnodes,0,
+					&Ke->values[0],1);
+
+		D[0*dim+0]=D_scalar*vx;
+		if(dim==2) D[1*dim+1]=D_scalar*vy;
+
+		TripleMultiply(B,dim,numnodes,1,
+					D,dim,dim,0,
+					Bprime,dim,numnodes,0,
+					&Ke->values[0],1);
+
+		if(stabilization==2){
+			if(dim==1){
+				vel=fabs(vx)+1.e-8;
+				D[0]=h/(2*vel)*vx*vx;
+			}
+			else{
+				/*Streamline upwinding*/
+				vel=sqrt(vx*vx+vy*vy)+1.e-8;
+				D[0*dim+0]=h/(2*vel)*vx*vx;
+				D[1*dim+0]=h/(2*vel)*vy*vx;
+				D[0*dim+1]=h/(2*vel)*vx*vy;
+				D[1*dim+1]=h/(2*vel)*vy*vy;
+			}
+		}
+		else if(stabilization==1){
+			/*SSA*/
+			vxaverage_input->GetInputAverage(&vx);
+			if(dim==2) vyaverage_input->GetInputAverage(&vy);
+			D[0*dim+0]=h/2.0*fabs(vx);
+			if(dim==2) D[1*dim+1]=h/2.0*fabs(vy);
+		}
+		if(stabilization==1 || stabilization==2){
+			if(dim==1) D[0]=D_scalar*D[0];
+			else{
+				D[0*dim+0]=D_scalar*D[0*dim+0];
+				D[1*dim+0]=D_scalar*D[1*dim+0];
+				D[0*dim+1]=D_scalar*D[0*dim+1];
+				D[1*dim+1]=D_scalar*D[1*dim+1];
+			}
+
+			TripleMultiply(Bprime,dim,numnodes,1,
+						D,dim,dim,0,
+						Bprime,dim,numnodes,0,
+						&Ke->values[0],1);
+		}
+	}
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(basis);
+	xDelete<IssmDouble>(B);
+	xDelete<IssmDouble>(Bprime);
+	xDelete<IssmDouble>(D);
+	delete gauss;
+	return Ke;
+}/*}}}*/
+ElementMatrix* MasstransportAnalysis::CreateKMatrixDG(Element* element){/*{{{*/
+
+	/* Check if ice in element */
+	if(!element->IsIceInElement()) return NULL;
+
+	/*Intermediaries */
+	int        domaintype;
+	IssmDouble Jdet,D_scalar,dt,vx,vy;
+	IssmDouble* xyz_list = NULL;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Initialize Element vector and other vectors*/
+	ElementMatrix* Ke     = element->NewElementMatrix();
+	IssmDouble*    basis  = xNew<IssmDouble>(numnodes);
+	IssmDouble*    B      = xNew<IssmDouble>(2*numnodes);
+	IssmDouble*    Bprime = xNew<IssmDouble>(2*numnodes);
+	IssmDouble     D[2][2];
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+	element->FindParam(&dt,TimesteppingTimeStepEnum);
+	element->FindParam(&domaintype,DomainTypeEnum);
+	Input* vxaverage_input=NULL;
+	Input* vyaverage_input=NULL;
+	if(domaintype==Domain2DhorizontalEnum){
+		vxaverage_input=element->GetInput(VxEnum); _assert_(vxaverage_input);
+		vyaverage_input=element->GetInput(VyEnum); _assert_(vyaverage_input);
+	}
+	else{
+		vxaverage_input=element->GetInput(VxAverageEnum); _assert_(vxaverage_input);
+		vyaverage_input=element->GetInput(VyAverageEnum); _assert_(vyaverage_input);
+	}
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		element->NodalFunctions(basis,gauss);
+
+		vxaverage_input->GetInputValue(&vx,gauss);
+		vyaverage_input->GetInputValue(&vy,gauss);
+
+		D_scalar=gauss->weight*Jdet;
+		TripleMultiply(basis,1,numnodes,1,
+					&D_scalar,1,1,0,
+					basis,1,numnodes,0,
+					&Ke->values[0],1);
+
+		/*WARNING: B and Bprime are inverted compared to CG*/
+		GetB(Bprime,element,2,xyz_list,gauss);
+		GetBprime(B,element,2,xyz_list,gauss);
+
+		D_scalar = - dt*gauss->weight*Jdet;
+		D[0][0]  = D_scalar*vx;
+		D[0][1]  = 0.;
+		D[1][0]  = 0.;
+		D[1][1]  = D_scalar*vy;
+		TripleMultiply(B,2,numnodes,1,
+					&D[0][0],2,2,0,
+					Bprime,2,numnodes,0,
+					&Ke->values[0],1);
+
+	}
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(basis);
+	xDelete<IssmDouble>(B);
+	xDelete<IssmDouble>(Bprime);
+	delete gauss;
+	return Ke;
+}/*}}}*/
+ElementVector* MasstransportAnalysis::CreatePVector(Element* element){/*{{{*/
+
+	/* Check if ice in element */
+	if(!element->IsIceInElement()) return NULL;
+
+	if(!element->IsOnBase()) return NULL;
+	Element* basalelement = element->SpawnBasalElement();
+
+	ElementVector* pe = NULL;
+	switch(element->FiniteElement()){
+		case P1Enum: case P2Enum:
+			pe = CreatePVectorCG(basalelement);
+			break;
+		case P1DGEnum:
+			pe = CreatePVectorDG(basalelement);
+			break;
+		default:
+			_error_("Element type " << EnumToStringx(element->FiniteElement()) << " not supported yet");
+	}
+
+	int domaintype;
+	element->FindParam(&domaintype,DomainTypeEnum);
+	if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;};
+	return pe;
+}/*}}}*/
+ElementVector* MasstransportAnalysis::CreatePVectorCG(Element* element){/*{{{*/
+
+	/* Check if ice in element */
+	if(!element->IsIceInElement()) return NULL;
+
+	/*Intermediaries */
+	IssmDouble  Jdet,dt;
+	IssmDouble  ms,mb,mb_correction=0.,thickness;
+	IssmDouble* xyz_list = NULL;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Initialize Element vector and other vectors*/
+	ElementVector* pe    = element->NewElementVector();
+	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+	element->FindParam(&dt,TimesteppingTimeStepEnum);
+	Input* mb_correction_input = element->GetInput(BasalforcingsMeltingRateCorrectionEnum);
+	Input* mb_input            = element->GetInput(BasalforcingsMeltingRateEnum);     _assert_(mb_input);
+	Input* ms_input            = element->GetInput(SurfaceforcingsMassBalanceEnum);   _assert_(ms_input);
+	Input* thickness_input     = element->GetInput(ThicknessEnum);                    _assert_(thickness_input);
+
+	/*Initialize mb_correction to 0, do not forget!:*/
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		element->NodalFunctions(basis,gauss);
+
+		ms_input->GetInputValue(&ms,gauss);
+		mb_input->GetInputValue(&mb,gauss);
+		thickness_input->GetInputValue(&thickness,gauss);
+		if(mb_correction_input)
+		 mb_correction_input->GetInputValue(&mb_correction,gauss);
+
+		for(int i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*(thickness+dt*(ms-mb-mb_correction))*basis[i];
+	}
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(basis);
+	delete gauss;
+	return pe;
+}/*}}}*/
+ElementVector* MasstransportAnalysis::CreatePVectorDG(Element* element){/*{{{*/
+
+	/* Check if ice in element */
+	if(!element->IsIceInElement()) return NULL;
+
+	/*Intermediaries */
+	IssmDouble  Jdet,dt;
+	IssmDouble  ms,mb,mb_correction=0.,thickness;
+	IssmDouble* xyz_list = NULL;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Initialize Element vector and other vectors*/
+	ElementVector* pe    = element->NewElementVector();
+	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+	element->FindParam(&dt,TimesteppingTimeStepEnum);
+	Input* mb_correction_input = element->GetInput(BasalforcingsMeltingRateCorrectionEnum);
+	Input* mb_input            = element->GetInput(BasalforcingsMeltingRateEnum);     _assert_(mb_input);
+	Input* ms_input            = element->GetInput(SurfaceforcingsMassBalanceEnum);   _assert_(ms_input);
+	Input* thickness_input     = element->GetInput(ThicknessEnum);                    _assert_(thickness_input);
+
+	/*Initialize mb_correction to 0, do not forget!:*/
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		element->NodalFunctions(basis,gauss);
+
+		ms_input->GetInputValue(&ms,gauss);
+		mb_input->GetInputValue(&mb,gauss);
+		thickness_input->GetInputValue(&thickness,gauss);
+		if(mb_correction_input)
+		 mb_correction_input->GetInputValue(&mb_correction,gauss);
+
+		for(int i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*(thickness+dt*(ms-mb-mb_correction))*basis[i];
+	}
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(basis);
+	delete gauss;
+	return pe;
+}/*}}}*/
+void MasstransportAnalysis::GetB(IssmDouble* B,Element* element,int dim,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
+	/*Compute B  matrix. B=[B1 B2 B3] where Bi is of size 3*NDOF2. 
+	 * For node i, Bi can be expressed in the actual coordinate system
+	 * by: 
+	 *       Bi=[ N ]
+	 *          [ N ]
+	 * where N is the finiteelement function for node i.
+	 *
+	 * We assume B_prog has been allocated already, of size: 2x(NDOF1*numnodes)
+	 */
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Get nodal functions*/
+	IssmDouble* basis=xNew<IssmDouble>(numnodes);
+	element->NodalFunctions(basis,gauss);
+
+	/*Build B: */
+	for(int i=0;i<numnodes;i++){
+		for(int j=0;j<dim;j++){
+			B[numnodes*j+i] = basis[i];
+		}
+	}
+
+	/*Clean-up*/
+	xDelete<IssmDouble>(basis);
+}/*}}}*/
+void MasstransportAnalysis::GetBprime(IssmDouble* Bprime,Element* element,int dim,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
+	/*Compute B'  matrix. B'=[B1' B2' B3'] where Bi' is of size 3*NDOF2. 
+	 * For node i, Bi' can be expressed in the actual coordinate system
+	 * by: 
+	 *       Bi_prime=[ dN/dx ]
+	 *                [ dN/dy ]
+	 * where N is the finiteelement function for node i.
+	 *
+	 * We assume B' has been allocated already, of size: 3x(NDOF2*numnodes)
+	 */
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Get nodal functions derivatives*/
+	IssmDouble* dbasis=xNew<IssmDouble>(dim*numnodes);
+	element->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+
+	/*Build B': */
+	for(int i=0;i<numnodes;i++){
+		for(int j=0;j<dim;j++){
+			Bprime[numnodes*j+i] = dbasis[j*numnodes+i];
+		}
+	}
+
+	/*Clean-up*/
+	xDelete<IssmDouble>(dbasis);
+
+}/*}}}*/
+void MasstransportAnalysis::GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element){/*{{{*/
+	   _error_("not implemented yet");
+}/*}}}*/
+void MasstransportAnalysis::InputUpdateFromSolution(IssmDouble* solution,Element* element){/*{{{*/
+
+	int        i,hydroadjustment,domaintype;
+	int*       doflist=NULL;
+	IssmDouble rho_ice,rho_water,minthickness;
+	Element*   basalelement=NULL;
+
+	element->FindParam(&domaintype,DomainTypeEnum);
+	if(domaintype!=Domain2DhorizontalEnum){
+		if(!element->IsOnBase()) return;
+		basalelement=element->SpawnBasalElement();
+	}
+	else{
+		basalelement = element;
+	}
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = basalelement->GetNumberOfNodes();
+
+	/*Fetch dof list and allocate solution vector*/
+	basalelement->GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
+	IssmDouble* newthickness = xNew<IssmDouble>(numnodes);
+	IssmDouble* newbed       = xNew<IssmDouble>(numnodes);
+	IssmDouble* newsurface   = xNew<IssmDouble>(numnodes);
+	IssmDouble* oldthickness = xNew<IssmDouble>(numnodes);
+	IssmDouble* oldbed       = xNew<IssmDouble>(numnodes);
+	IssmDouble* oldsurface   = xNew<IssmDouble>(numnodes);
+	IssmDouble* phi          = xNew<IssmDouble>(numnodes);
+
+	/*Use the dof list to index into the solution vector: */
+	basalelement->FindParam(&minthickness,MasstransportMinThicknessEnum);
+	for(i=0;i<numnodes;i++){
+		newthickness[i]=solution[doflist[i]];
+		if(xIsNan<IssmDouble>(newthickness[i])) _error_("NaN found in solution vector");
+		/*Constrain thickness to be at least 1m*/
+		if(newthickness[i]<minthickness) newthickness[i]=minthickness;
+	}
+
+	/*Get previous bed, thickness and surface*/
+	basalelement->GetInputListOnNodes(&oldbed[0],BaseEnum);
+	basalelement->GetInputListOnNodes(&oldsurface[0],SurfaceEnum);
+	basalelement->GetInputListOnNodes(&oldthickness[0],ThicknessEnum);
+	basalelement->GetInputListOnNodes(&phi[0],MaskGroundediceLevelsetEnum);
+
+	/*Find MasstransportHydrostaticAdjustment to figure out how to update the geometry:*/
+	basalelement->FindParam(&hydroadjustment,MasstransportHydrostaticAdjustmentEnum);
+	rho_ice   = basalelement->GetMaterialParameter(MaterialsRhoIceEnum);
+	rho_water = basalelement->GetMaterialParameter(MaterialsRhoWaterEnum);
+
+	for(i=0;i<numnodes;i++) {
+		/*If shelf: hydrostatic equilibrium*/
+		if (phi[i]>0.){
+			newsurface[i] = oldbed[i]+newthickness[i]; //surface = oldbed + newthickness
+			newbed[i]     = oldbed[i];                 //same bed: do nothing
+		}
+		else{ //this is an ice shelf
+			if(hydroadjustment==AbsoluteEnum){
+				newsurface[i] = newthickness[i]*(1-rho_ice/rho_water);
+				newbed[i]     = newthickness[i]*(-rho_ice/rho_water);
+			}
+			else if(hydroadjustment==IncrementalEnum){
+				newsurface[i] = oldsurface[i]+(1.0-rho_ice/rho_water)*(newthickness[i]-oldthickness[i]); //surface = oldsurface + (1-di) * dH
+				newbed[i]     = oldbed[i]-rho_ice/rho_water*(newthickness[i]-oldthickness[i]); //bed               = oldbed + di * dH
+			}
+			else _error_("Hydrostatic adjustment " << hydroadjustment << " (" << EnumToStringx(hydroadjustment) << ") not supported yet");
+		}
+	}
+
+	/*Add input to the element: */
+	element->AddBasalInput(ThicknessEnum,newthickness,P1Enum);
+	element->AddBasalInput(SurfaceEnum,newsurface,P1Enum);
+	element->AddBasalInput(BaseEnum,newbed,P1Enum);
+
+	/*Free ressources:*/
+	xDelete<IssmDouble>(newthickness);
+	xDelete<IssmDouble>(newbed);
+	xDelete<IssmDouble>(newsurface);
+	xDelete<IssmDouble>(oldthickness);
+	xDelete<IssmDouble>(oldbed);
+	xDelete<IssmDouble>(oldsurface);
+	xDelete<IssmDouble>(phi);
+	xDelete<int>(doflist);
+	if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;};
+}/*}}}*/
+void MasstransportAnalysis::UpdateConstraints(FemModel* femmodel){/*{{{*/
+
+	bool islevelset;
+	femmodel->parameters->FindParam(&islevelset,TransientIslevelsetEnum);
+	if(islevelset){
+		SetActiveNodesLSMx(femmodel);
+	}
+	return;
+}/*}}}*/
Index: /issm/trunk/src/c/analyses/MasstransportAnalysis.h
===================================================================
--- /issm/trunk/src/c/analyses/MasstransportAnalysis.h	(revision 17805)
+++ /issm/trunk/src/c/analyses/MasstransportAnalysis.h	(revision 17806)
@@ -12,5 +12,6 @@
 
 	public:
-		int  DofsPerNode(int** doflist,int meshtype,int approximation);
+		/*Model processing*/
+		int  DofsPerNode(int** doflist,int domaintype,int approximation);
 		void UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum);
 		void UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);
@@ -18,4 +19,20 @@
 		void CreateConstraints(Constraints* constraints,IoModel* iomodel);
 		void CreateLoads(Loads* loads, IoModel* iomodel);
+
+		/*Finite element Analysis*/
+		void           Core(FemModel* femmodel);
+		ElementVector* CreateDVector(Element* element);
+		ElementMatrix* CreateJacobianMatrix(Element* element);
+		ElementMatrix* CreateKMatrix(Element* element);
+		ElementMatrix* CreateKMatrixCG(Element* element);
+		ElementMatrix* CreateKMatrixDG(Element* element);
+		ElementVector* CreatePVector(Element* element);
+		ElementVector* CreatePVectorCG(Element* element);
+		ElementVector* CreatePVectorDG(Element* element);
+		void GetB(IssmDouble* B,Element* element,int dim,IssmDouble* xyz_list,Gauss* gauss);
+		void GetBprime(IssmDouble* B,Element* element,int dim,IssmDouble* xyz_list,Gauss* gauss);
+		void GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element);
+		void InputUpdateFromSolution(IssmDouble* solution,Element* element);
+		void UpdateConstraints(FemModel* femmodel);
 };
 #endif
Index: /issm/trunk/src/c/analyses/MeltingAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/MeltingAnalysis.cpp	(revision 17805)
+++ /issm/trunk/src/c/analyses/MeltingAnalysis.cpp	(revision 17806)
@@ -6,5 +6,5 @@
 
 /*Model processing*/
-int  MeltingAnalysis::DofsPerNode(int** doflist,int meshtype,int approximation){/*{{{*/
+int  MeltingAnalysis::DofsPerNode(int** doflist,int domaintype,int approximation){/*{{{*/
 	return 1;
 }/*}}}*/
@@ -14,5 +14,5 @@
 
 	/*Now, is the model 3d? otherwise, do nothing: */
-	if(iomodel->meshtype==Mesh2DhorizontalEnum)return;
+	if(iomodel->domaintype==Domain2DhorizontalEnum)return;
 
 	/*Update elements: */
@@ -29,10 +29,10 @@
 	iomodel->FetchDataToInput(elements,ThicknessEnum);
 	iomodel->FetchDataToInput(elements,SurfaceEnum);
-	iomodel->FetchDataToInput(elements,BedEnum);
+	iomodel->FetchDataToInput(elements,BaseEnum);
 	iomodel->FetchDataToInput(elements,FrictionCoefficientEnum);
 	iomodel->FetchDataToInput(elements,FrictionPEnum);
 	iomodel->FetchDataToInput(elements,FrictionQEnum);
 	iomodel->FetchDataToInput(elements,MaskIceLevelsetEnum);
-	iomodel->FetchDataToInput(elements,MeshElementonbedEnum);
+	iomodel->FetchDataToInput(elements,MeshElementonbaseEnum);
 	iomodel->FetchDataToInput(elements,MeshElementonsurfaceEnum);
 	iomodel->FetchDataToInput(elements,FlowequationElementEquationEnum);
@@ -44,7 +44,7 @@
 void MeltingAnalysis::CreateNodes(Nodes* nodes,IoModel* iomodel){/*{{{*/
 
-	if(iomodel->meshtype==Mesh3DEnum) iomodel->FetchData(2,MeshVertexonbedEnum,MeshVertexonsurfaceEnum);
+	if(iomodel->domaintype==Domain3DEnum) iomodel->FetchData(2,MeshVertexonbaseEnum,MeshVertexonsurfaceEnum);
 	::CreateNodes(nodes,iomodel,MeltingAnalysisEnum,P1Enum);
-	iomodel->DeleteData(2,MeshVertexonbedEnum,MeshVertexonsurfaceEnum);
+	iomodel->DeleteData(2,MeshVertexonbaseEnum,MeshVertexonsurfaceEnum);
 }/*}}}*/
 void MeltingAnalysis::CreateConstraints(Constraints* constraints,IoModel* iomodel){/*{{{*/
@@ -54,18 +54,87 @@
 
 	/*if 2d: Error*/
-	if(iomodel->meshtype==Mesh2DhorizontalEnum) _error_("2d meshes not supported yet");
+	if(iomodel->domaintype==Domain2DhorizontalEnum) _error_("2d meshes not supported yet");
 
 	//create penalties for nodes: no node can have a temperature over the melting point
-	iomodel->FetchData(1,MeshVertexonbedEnum);
+	iomodel->FetchData(1,MeshVertexonbaseEnum);
 	CreateSingleNodeToElementConnectivity(iomodel);
 
 	for(int i=0;i<iomodel->numberofvertices;i++){
 		if(iomodel->my_vertices[i]){
-			if (reCast<int>(iomodel->Data(MeshVertexonbedEnum)[i])){
+			if (reCast<int>(iomodel->Data(MeshVertexonbaseEnum)[i])){
 				loads->AddObject(new Pengrid(iomodel->loadcounter+i+1,i,iomodel,MeltingAnalysisEnum));
 			}
 		}
 	}
-	iomodel->DeleteData(1,MeshVertexonbedEnum);
+	iomodel->DeleteData(1,MeshVertexonbaseEnum);
 
 }/*}}}*/
+
+/*Finite Element Analysis*/
+void           MeltingAnalysis::Core(FemModel* femmodel){/*{{{*/
+	_error_("not implemented");
+}/*}}}*/
+ElementVector* MeltingAnalysis::CreateDVector(Element* element){/*{{{*/
+	/*Default, return NULL*/
+	return NULL;
+}/*}}}*/
+ElementMatrix* MeltingAnalysis::CreateJacobianMatrix(Element* element){/*{{{*/
+_error_("Not implemented");
+}/*}}}*/
+ElementMatrix* MeltingAnalysis::CreateKMatrix(Element* element){/*{{{*/
+
+	/*Get basal element*/
+	if(!element->IsOnBase()) return NULL;
+	Element* basalelement = element->SpawnBasalElement();
+
+	/*Intermediaries */
+	IssmDouble  D,Jdet;
+	IssmDouble *xyz_list  = NULL;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = basalelement->GetNumberOfNodes();
+
+	/*Initialize Element vector*/
+	ElementMatrix* Ke    = basalelement->NewElementMatrix(NoneApproximationEnum);
+	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	basalelement->GetVerticesCoordinates(&xyz_list);
+	IssmDouble latentheat   = element->GetMaterialParameter(MaterialsLatentheatEnum);
+	IssmDouble heatcapacity = element->GetMaterialParameter(MaterialsHeatcapacityEnum);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=basalelement->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		basalelement->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		basalelement->NodalFunctions(basis,gauss);
+		D=latentheat/heatcapacity*gauss->weight*Jdet;
+
+		TripleMultiply(basis,1,numnodes,1,
+					&D,1,1,0,
+					basis,1,numnodes,0,
+					&Ke->values[0],1);
+	}
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(basis);
+	delete gauss;
+	basalelement->DeleteMaterials(); delete basalelement;
+	return Ke;
+}/*}}}*/
+ElementVector* MeltingAnalysis::CreatePVector(Element* element){/*{{{*/
+	return NULL;
+}/*}}}*/
+void MeltingAnalysis::GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element){/*{{{*/
+	   _error_("not implemented yet");
+}/*}}}*/
+void MeltingAnalysis::InputUpdateFromSolution(IssmDouble* solution,Element* element){/*{{{*/
+	element->InputUpdateFromSolutionOneDof(solution,BasalforcingsMeltingRateEnum);
+}/*}}}*/
+void MeltingAnalysis::UpdateConstraints(FemModel* femmodel){/*{{{*/
+	/*Default, do nothing*/
+	return;
+}/*}}}*/
Index: /issm/trunk/src/c/analyses/MeltingAnalysis.h
===================================================================
--- /issm/trunk/src/c/analyses/MeltingAnalysis.h	(revision 17805)
+++ /issm/trunk/src/c/analyses/MeltingAnalysis.h	(revision 17806)
@@ -12,5 +12,6 @@
 
 	public:
-		int  DofsPerNode(int** doflist,int meshtype,int approximation);
+		/*Model processing*/
+		int  DofsPerNode(int** doflist,int domaintype,int approximation);
 		void UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum);
 		void UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);
@@ -18,4 +19,14 @@
 		void CreateConstraints(Constraints* constraints,IoModel* iomodel);
 		void CreateLoads(Loads* loads, IoModel* iomodel);
+
+		/*Finite element Analysis*/
+		void           Core(FemModel* femmodel);
+		ElementVector* CreateDVector(Element* element);
+		ElementMatrix* CreateJacobianMatrix(Element* element);
+		ElementMatrix* CreateKMatrix(Element* element);
+		ElementVector* CreatePVector(Element* element);
+		void GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element);
+		void InputUpdateFromSolution(IssmDouble* solution,Element* element);
+		void UpdateConstraints(FemModel* femmodel);
 };
 #endif
Index: /issm/trunk/src/c/analyses/MeshdeformationAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/MeshdeformationAnalysis.cpp	(revision 17805)
+++ /issm/trunk/src/c/analyses/MeshdeformationAnalysis.cpp	(revision 17806)
@@ -6,5 +6,5 @@
 
 /*Model processing*/
-int  MeshdeformationAnalysis::DofsPerNode(int** doflist,int meshtype,int approximation){/*{{{*/
+int  MeshdeformationAnalysis::DofsPerNode(int** doflist,int domaintype,int approximation){/*{{{*/
 	_error_("not implemented");
 }/*}}}*/
@@ -24,2 +24,30 @@
 	   _error_("not implemented yet");
 }/*}}}*/
+
+/*Finite Element Analysis*/
+void           MeshdeformationAnalysis::Core(FemModel* femmodel){/*{{{*/
+	_error_("not implemented");
+}/*}}}*/
+ElementVector* MeshdeformationAnalysis::CreateDVector(Element* element){/*{{{*/
+	/*Default, return NULL*/
+	return NULL;
+}/*}}}*/
+ElementMatrix* MeshdeformationAnalysis::CreateJacobianMatrix(Element* element){/*{{{*/
+_error_("Not implemented");
+}/*}}}*/
+ElementMatrix* MeshdeformationAnalysis::CreateKMatrix(Element* element){/*{{{*/
+	_error_("not implemented yet");
+}/*}}}*/
+ElementVector* MeshdeformationAnalysis::CreatePVector(Element* element){/*{{{*/
+_error_("not implemented yet");
+}/*}}}*/
+void MeshdeformationAnalysis::GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element){/*{{{*/
+	   _error_("not implemented yet");
+}/*}}}*/
+void MeshdeformationAnalysis::InputUpdateFromSolution(IssmDouble* solution,Element* element){/*{{{*/
+	_error_("not implemented yet");
+}/*}}}*/
+void MeshdeformationAnalysis::UpdateConstraints(FemModel* femmodel){/*{{{*/
+	/*Default, do nothing*/
+	return;
+}/*}}}*/
Index: /issm/trunk/src/c/analyses/MeshdeformationAnalysis.h
===================================================================
--- /issm/trunk/src/c/analyses/MeshdeformationAnalysis.h	(revision 17805)
+++ /issm/trunk/src/c/analyses/MeshdeformationAnalysis.h	(revision 17806)
@@ -12,5 +12,6 @@
 
 	public:
-		int  DofsPerNode(int** doflist,int meshtype,int approximation);
+		/*Model processing*/
+		int  DofsPerNode(int** doflist,int domaintype,int approximation);
 		void UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum);
 		void UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);
@@ -18,4 +19,14 @@
 		void CreateConstraints(Constraints* constraints,IoModel* iomodel);
 		void CreateLoads(Loads* loads, IoModel* iomodel);
+
+		/*Finite element Analysis*/
+		void           Core(FemModel* femmodel);
+		ElementVector* CreateDVector(Element* element);
+		ElementMatrix* CreateJacobianMatrix(Element* element);
+		ElementMatrix* CreateKMatrix(Element* element);
+		ElementVector* CreatePVector(Element* element);
+		void GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element);
+		void InputUpdateFromSolution(IssmDouble* solution,Element* element);
+		void UpdateConstraints(FemModel* femmodel);
 };
 #endif
Index: /issm/trunk/src/c/analyses/SmoothedSurfaceSlopeXAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/SmoothedSurfaceSlopeXAnalysis.cpp	(revision 17805)
+++ /issm/trunk/src/c/analyses/SmoothedSurfaceSlopeXAnalysis.cpp	(revision 17806)
@@ -6,5 +6,5 @@
 
 /*Model processing*/
-int  SmoothedSurfaceSlopeXAnalysis::DofsPerNode(int** doflist,int meshtype,int approximation){/*{{{*/
+int  SmoothedSurfaceSlopeXAnalysis::DofsPerNode(int** doflist,int domaintype,int approximation){/*{{{*/
 	return 1;
 }/*}}}*/
@@ -24,18 +24,18 @@
 
 	iomodel->FetchDataToInput(elements,SurfaceEnum);
-	iomodel->FetchDataToInput(elements,BedEnum);
+	iomodel->FetchDataToInput(elements,BaseEnum);
 	iomodel->FetchDataToInput(elements,MaskIceLevelsetEnum);
-	if(iomodel->meshtype==Mesh3DEnum){
-		iomodel->FetchDataToInput(elements,MeshElementonbedEnum);
+	if(iomodel->domaintype==Domain3DEnum){
+		iomodel->FetchDataToInput(elements,MeshElementonbaseEnum);
 		iomodel->FetchDataToInput(elements,MeshElementonsurfaceEnum);
 	}
-	if(iomodel->meshtype==Mesh2DverticalEnum){
-		iomodel->FetchDataToInput(elements,MeshVertexonbedEnum);
+	if(iomodel->domaintype==Domain2DverticalEnum){
+		iomodel->FetchDataToInput(elements,MeshVertexonbaseEnum);
 	}
 }/*}}}*/
 void SmoothedSurfaceSlopeXAnalysis::CreateNodes(Nodes* nodes,IoModel* iomodel){/*{{{*/
-	iomodel->FetchData(1,MeshVertexonbedEnum);
+	if(iomodel->domaintype==Domain3DEnum) iomodel->FetchData(1,MeshVertexonbaseEnum);
 	::CreateNodes(nodes,iomodel,SmoothedSurfaceSlopeXAnalysisEnum,P1Enum);
-	iomodel->DeleteData(1,MeshVertexonbedEnum);
+	if(iomodel->domaintype==Domain3DEnum) iomodel->DeleteData(1,MeshVertexonbaseEnum);
 }/*}}}*/
 void SmoothedSurfaceSlopeXAnalysis::CreateConstraints(Constraints* constraints,IoModel* iomodel){/*{{{*/
@@ -43,2 +43,141 @@
 void SmoothedSurfaceSlopeXAnalysis::CreateLoads(Loads* loads, IoModel* iomodel){/*{{{*/
 }/*}}}*/
+
+/*Finite Element Analysis*/
+void           SmoothedSurfaceSlopeXAnalysis::Core(FemModel* femmodel){/*{{{*/
+	_error_("not implemented");
+}/*}}}*/
+ElementVector* SmoothedSurfaceSlopeXAnalysis::CreateDVector(Element* element){/*{{{*/
+	/*Default, return NULL*/
+	return NULL;
+}/*}}}*/
+ElementMatrix* SmoothedSurfaceSlopeXAnalysis::CreateJacobianMatrix(Element* element){/*{{{*/
+_error_("Not implemented");
+}/*}}}*/
+ElementMatrix* SmoothedSurfaceSlopeXAnalysis::CreateKMatrix(Element* element){/*{{{*/
+
+	/* Intermediaries */
+	IssmDouble  Jdet,thickness,l=8.;
+	IssmDouble *xyz_list = NULL;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Initialize Element matrix and vectors*/
+	ElementMatrix* Ke     = element->NewElementMatrix();
+	IssmDouble*    dbasis = xNew<IssmDouble>(2*numnodes);
+	IssmDouble*    basis  = xNew<IssmDouble>(numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+	Input* thickness_input = element->GetInput(ThicknessEnum); _assert_(thickness_input);
+
+	/* Start looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		thickness_input->GetInputValue(&thickness,gauss);
+		if(thickness<50.) thickness=50.;
+
+		element->NodalFunctions(basis,gauss);
+		element->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+
+		for(int i=0;i<numnodes;i++){
+			for(int j=0;j<numnodes;j++){
+				Ke->values[i*numnodes+j] += gauss->weight*Jdet*(
+							basis[i]*basis[j]
+							+(l*thickness)*(l*thickness)*(dbasis[0*numnodes+i]*dbasis[0*numnodes+j] + dbasis[1*numnodes+i]*dbasis[1*numnodes+j])
+							);
+			}
+		}
+	}
+
+	/*Clean up and return*/
+	delete gauss;
+	xDelete<IssmDouble>(dbasis);
+	xDelete<IssmDouble>(basis);
+	xDelete<IssmDouble>(xyz_list);
+	return Ke;
+}/*}}}*/
+ElementVector* SmoothedSurfaceSlopeXAnalysis::CreatePVector(Element* element){/*{{{*/
+
+	/*Intermediaries*/
+	int      domaintype;
+	Element* basalelement;
+
+	/*Get basal element*/
+	element->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DhorizontalEnum:
+			basalelement = element;
+			break;
+		case Domain3DEnum:
+			if(!element->IsOnBase()) return NULL;
+			basalelement = element->SpawnBasalElement();
+			break;
+		default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
+	}
+
+	/*Intermediaries */
+	int         input_enum;
+	IssmDouble  Jdet,thickness,slope[2];
+	IssmDouble  taud_x,norms,normv,vx,vy;
+	IssmDouble *xyz_list  = NULL;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = basalelement->GetNumberOfNodes();
+
+	/*Initialize Element vector*/
+	ElementVector* pe    = basalelement->NewElementVector();
+	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	basalelement->GetVerticesCoordinates(&xyz_list);
+	IssmDouble rho_ice   = element->GetMaterialParameter(MaterialsRhoIceEnum);
+	IssmDouble gravity   = element->GetMaterialParameter(ConstantsGEnum);
+	Input* H_input       = basalelement->GetInput(ThicknessEnum); _assert_(H_input);
+	Input* surface_input = basalelement->GetInput(SurfaceEnum);   _assert_(surface_input);
+	Input* vx_input      = basalelement->GetInput(VxEnum);
+	Input* vy_input      = basalelement->GetInput(VyEnum);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=basalelement->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		basalelement->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		basalelement->NodalFunctions(basis,gauss);
+
+		H_input->GetInputValue(&thickness,gauss);
+		surface_input->GetInputDerivativeValue(&slope[0],xyz_list,gauss);
+		if(vx_input && vy_input){
+			vx_input->GetInputValue(&vx,gauss);
+			vy_input->GetInputValue(&vy,gauss);
+			norms = sqrt(slope[0]*slope[0]+slope[1]*slope[1]+1.e-10);
+			normv = sqrt(vx*vx + vy*vy);
+			if(normv>15./(365.*24.*3600.)) slope[0] = -vx/normv*norms;
+		}
+		taud_x = rho_ice*gravity*thickness*slope[0];
+
+		for(int i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*taud_x*basis[i];
+	}
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(basis);
+	delete gauss;
+	if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;};
+	return pe;
+}/*}}}*/
+void SmoothedSurfaceSlopeXAnalysis::GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element){/*{{{*/
+	   _error_("not implemented yet");
+}/*}}}*/
+void SmoothedSurfaceSlopeXAnalysis::InputUpdateFromSolution(IssmDouble* solution,Element* element){/*{{{*/
+	element->InputUpdateFromSolutionOneDof(solution,SurfaceSlopeXEnum);
+}/*}}}*/
+void SmoothedSurfaceSlopeXAnalysis::UpdateConstraints(FemModel* femmodel){/*{{{*/
+	/*Default, do nothing*/
+	return;
+}/*}}}*/
Index: /issm/trunk/src/c/analyses/SmoothedSurfaceSlopeXAnalysis.h
===================================================================
--- /issm/trunk/src/c/analyses/SmoothedSurfaceSlopeXAnalysis.h	(revision 17805)
+++ /issm/trunk/src/c/analyses/SmoothedSurfaceSlopeXAnalysis.h	(revision 17806)
@@ -12,5 +12,6 @@
 
 	public:
-		int  DofsPerNode(int** doflist,int meshtype,int approximation);
+		/*Model processing*/
+		int  DofsPerNode(int** doflist,int domaintype,int approximation);
 		void UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum);
 		void UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);
@@ -18,4 +19,14 @@
 		void CreateConstraints(Constraints* constraints,IoModel* iomodel);
 		void CreateLoads(Loads* loads, IoModel* iomodel);
+
+		/*Finite element Analysis*/
+		void           Core(FemModel* femmodel);
+		ElementVector* CreateDVector(Element* element);
+		ElementMatrix* CreateJacobianMatrix(Element* element);
+		ElementMatrix* CreateKMatrix(Element* element);
+		ElementVector* CreatePVector(Element* element);
+		void GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element);
+		void InputUpdateFromSolution(IssmDouble* solution,Element* element);
+		void UpdateConstraints(FemModel* femmodel);
 };
 #endif
Index: /issm/trunk/src/c/analyses/SmoothedSurfaceSlopeYAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/SmoothedSurfaceSlopeYAnalysis.cpp	(revision 17805)
+++ /issm/trunk/src/c/analyses/SmoothedSurfaceSlopeYAnalysis.cpp	(revision 17806)
@@ -6,5 +6,5 @@
 
 /*Model processing*/
-int  SmoothedSurfaceSlopeYAnalysis::DofsPerNode(int** doflist,int meshtype,int approximation){/*{{{*/
+int  SmoothedSurfaceSlopeYAnalysis::DofsPerNode(int** doflist,int domaintype,int approximation){/*{{{*/
 	return 1;
 }/*}}}*/
@@ -24,18 +24,18 @@
 
 	iomodel->FetchDataToInput(elements,SurfaceEnum);
-	iomodel->FetchDataToInput(elements,BedEnum);
+	iomodel->FetchDataToInput(elements,BaseEnum);
 	iomodel->FetchDataToInput(elements,MaskIceLevelsetEnum);
-	if(iomodel->meshtype==Mesh3DEnum){
-		iomodel->FetchDataToInput(elements,MeshElementonbedEnum);
+	if(iomodel->domaintype==Domain3DEnum){
+		iomodel->FetchDataToInput(elements,MeshElementonbaseEnum);
 		iomodel->FetchDataToInput(elements,MeshElementonsurfaceEnum);
 	}
-	if(iomodel->meshtype==Mesh2DverticalEnum){
-		iomodel->FetchDataToInput(elements,MeshVertexonbedEnum);
+	if(iomodel->domaintype==Domain2DverticalEnum){
+		iomodel->FetchDataToInput(elements,MeshVertexonbaseEnum);
 	}
 }/*}}}*/
 void SmoothedSurfaceSlopeYAnalysis::CreateNodes(Nodes* nodes,IoModel* iomodel){/*{{{*/
-	iomodel->FetchData(1,MeshVertexonbedEnum);
+	if(iomodel->domaintype==Domain3DEnum) iomodel->FetchData(1,MeshVertexonbaseEnum);
 	::CreateNodes(nodes,iomodel,SmoothedSurfaceSlopeYAnalysisEnum,P1Enum);
-	iomodel->DeleteData(1,MeshVertexonbedEnum);
+	if(iomodel->domaintype==Domain3DEnum) iomodel->DeleteData(1,MeshVertexonbaseEnum);
 }/*}}}*/
 void SmoothedSurfaceSlopeYAnalysis::CreateConstraints(Constraints* constraints,IoModel* iomodel){/*{{{*/
@@ -43,2 +43,141 @@
 void SmoothedSurfaceSlopeYAnalysis::CreateLoads(Loads* loads, IoModel* iomodel){/*{{{*/
 }/*}}}*/
+
+/*Finite Element Analysis*/
+void           SmoothedSurfaceSlopeYAnalysis::Core(FemModel* femmodel){/*{{{*/
+	_error_("not implemented");
+}/*}}}*/
+ElementVector* SmoothedSurfaceSlopeYAnalysis::CreateDVector(Element* element){/*{{{*/
+	/*Default, return NULL*/
+	return NULL;
+}/*}}}*/
+ElementMatrix* SmoothedSurfaceSlopeYAnalysis::CreateJacobianMatrix(Element* element){/*{{{*/
+_error_("Not implemented");
+}/*}}}*/
+ElementMatrix* SmoothedSurfaceSlopeYAnalysis::CreateKMatrix(Element* element){/*{{{*/
+
+	/* Intermediaries */
+	IssmDouble  Jdet,thickness,l=8.;
+	IssmDouble *xyz_list = NULL;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Initialize Element matrix and vectors*/
+	ElementMatrix* Ke     = element->NewElementMatrix();
+	IssmDouble*    dbasis = xNew<IssmDouble>(2*numnodes);
+	IssmDouble*    basis  = xNew<IssmDouble>(numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+	Input* thickness_input = element->GetInput(ThicknessEnum); _assert_(thickness_input);
+
+	/* Start looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		thickness_input->GetInputValue(&thickness,gauss);
+		if(thickness<50.) thickness=50.;
+
+		element->NodalFunctions(basis,gauss);
+		element->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+
+		for(int i=0;i<numnodes;i++){
+			for(int j=0;j<numnodes;j++){
+				Ke->values[i*numnodes+j] += gauss->weight*Jdet*(
+							basis[i]*basis[j]
+							+(l*thickness)*(l*thickness)*(dbasis[0*numnodes+i]*dbasis[0*numnodes+j] + dbasis[1*numnodes+i]*dbasis[1*numnodes+j])
+							);
+			}
+		}
+	}
+
+	/*Clean up and return*/
+	delete gauss;
+	xDelete<IssmDouble>(dbasis);
+	xDelete<IssmDouble>(basis);
+	xDelete<IssmDouble>(xyz_list);
+	return Ke;
+}/*}}}*/
+ElementVector* SmoothedSurfaceSlopeYAnalysis::CreatePVector(Element* element){/*{{{*/
+
+	/*Intermediaries*/
+	int      domaintype;
+	Element* basalelement;
+
+	/*Get basal element*/
+	element->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DhorizontalEnum:
+			basalelement = element;
+			break;
+		case Domain3DEnum:
+			if(!element->IsOnBase()) return NULL;
+			basalelement = element->SpawnBasalElement();
+			break;
+		default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
+	}
+
+	/*Intermediaries */
+	int         input_enum;
+	IssmDouble  Jdet,thickness,slope[2];
+	IssmDouble  taud_y,norms,normv,vx,vy;
+	IssmDouble *xyz_list  = NULL;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = basalelement->GetNumberOfNodes();
+
+	/*Initialize Element vector*/
+	ElementVector* pe    = basalelement->NewElementVector();
+	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	basalelement->GetVerticesCoordinates(&xyz_list);
+	IssmDouble rho_ice   = element->GetMaterialParameter(MaterialsRhoIceEnum);
+	IssmDouble gravity   = element->GetMaterialParameter(ConstantsGEnum);
+	Input* H_input       = basalelement->GetInput(ThicknessEnum); _assert_(H_input);
+	Input* surface_input = basalelement->GetInput(SurfaceEnum);   _assert_(surface_input);
+	Input* vx_input      = basalelement->GetInput(VxEnum);
+	Input* vy_input      = basalelement->GetInput(VyEnum);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=basalelement->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		basalelement->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		basalelement->NodalFunctions(basis,gauss);
+
+		H_input->GetInputValue(&thickness,gauss);
+		surface_input->GetInputDerivativeValue(&slope[0],xyz_list,gauss);
+		if(vx_input && vy_input){
+			vx_input->GetInputValue(&vx,gauss);
+			vy_input->GetInputValue(&vy,gauss);
+			norms = sqrt(slope[0]*slope[0]+slope[1]*slope[1]+1.e-10);
+			normv = sqrt(vx*vx + vy*vy);
+			if(normv>15./(365.*24.*3600.)) slope[1] = -vy/normv*norms;
+		}
+		taud_y = rho_ice*gravity*thickness*slope[1];
+
+		for(int i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*taud_y*basis[i];
+	}
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(basis);
+	delete gauss;
+	if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;};
+	return pe;
+}/*}}}*/
+void SmoothedSurfaceSlopeYAnalysis::GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element){/*{{{*/
+	   _error_("not implemented yet");
+}/*}}}*/
+void SmoothedSurfaceSlopeYAnalysis::InputUpdateFromSolution(IssmDouble* solution,Element* element){/*{{{*/
+	element->InputUpdateFromSolutionOneDof(solution,SurfaceSlopeYEnum);
+}/*}}}*/
+void SmoothedSurfaceSlopeYAnalysis::UpdateConstraints(FemModel* femmodel){/*{{{*/
+	/*Default, do nothing*/
+	return;
+}/*}}}*/
Index: /issm/trunk/src/c/analyses/SmoothedSurfaceSlopeYAnalysis.h
===================================================================
--- /issm/trunk/src/c/analyses/SmoothedSurfaceSlopeYAnalysis.h	(revision 17805)
+++ /issm/trunk/src/c/analyses/SmoothedSurfaceSlopeYAnalysis.h	(revision 17806)
@@ -12,5 +12,6 @@
 
 	public:
-		int  DofsPerNode(int** doflist,int meshtype,int approximation);
+		/*Model processing*/
+		int  DofsPerNode(int** doflist,int domaintype,int approximation);
 		void UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum);
 		void UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);
@@ -18,4 +19,14 @@
 		void CreateConstraints(Constraints* constraints,IoModel* iomodel);
 		void CreateLoads(Loads* loads, IoModel* iomodel);
+
+		/*Finite element Analysis*/
+		void           Core(FemModel* femmodel);
+		ElementVector* CreateDVector(Element* element);
+		ElementMatrix* CreateJacobianMatrix(Element* element);
+		ElementMatrix* CreateKMatrix(Element* element);
+		ElementVector* CreatePVector(Element* element);
+		void GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element);
+		void InputUpdateFromSolution(IssmDouble* solution,Element* element);
+		void UpdateConstraints(FemModel* femmodel);
 };
 #endif
Index: /issm/trunk/src/c/analyses/StressbalanceAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/StressbalanceAnalysis.cpp	(revision 17805)
+++ /issm/trunk/src/c/analyses/StressbalanceAnalysis.cpp	(revision 17806)
@@ -4,7 +4,11 @@
 #include "../shared/shared.h"
 #include "../modules/modules.h"
+#include "../solutionsequences/solutionsequences.h"
+#include "../cores/cores.h"
+
+//#define FSANALYTICAL 21
 
 /*Model processing*/
-int  StressbalanceAnalysis::DofsPerNode(int** pdoftype,int meshtype,int approximation){/*{{{*/
+int  StressbalanceAnalysis::DofsPerNode(int** pdoftype,int domaintype,int approximation){/*{{{*/
 
 	/*output*/
@@ -13,12 +17,25 @@
 
 	switch(approximation){
-		case SSAApproximationEnum:  numdofs =2; break;
+		case SSAApproximationEnum:
+			 switch(domaintype){
+				 case Domain3DEnum:           numdofs=2; break;
+				 case Domain2DhorizontalEnum: numdofs=2; break;
+				 case Domain2DverticalEnum:   numdofs=1; break;
+				 default: _error_("mesh type not supported yet");
+			 }
+			 break;
 		case L1L2ApproximationEnum: numdofs =2; break;
-		case HOApproximationEnum:   numdofs =2; break;
+		case HOApproximationEnum:   
+			 switch(domaintype){
+				 case Domain3DEnum:         numdofs=2; break;
+				 case Domain2DverticalEnum: numdofs=1; break;
+				 default: _error_("mesh type not supported yet");
+			 }
+			 break;
 		case SIAApproximationEnum:  numdofs =2; break;
 		case FSvelocityEnum:
-			 switch(meshtype){
-				 case Mesh3DEnum:         numdofs=3; break;
-				 case Mesh2DverticalEnum: numdofs=2; break;
+			 switch(domaintype){
+				 case Domain3DEnum:         numdofs=3; break;
+				 case Domain2DverticalEnum: numdofs=2; break;
 				 default: _error_("mesh type not supported yet");
 			}
@@ -26,7 +43,7 @@
 		case FSpressureEnum: numdofs=1; break;
 		case NoneApproximationEnum:
-			 switch(meshtype){
-				 case Mesh3DEnum:         numdofs=4; break;
-				 case Mesh2DverticalEnum: numdofs=3; break;
+			 switch(domaintype){
+				 case Domain3DEnum:         numdofs=4; break;
+				 case Domain2DverticalEnum: numdofs=3; break;
 				 default: _error_("mesh type not supported yet");
 			}
@@ -69,6 +86,7 @@
 
 	/*Intermediaries*/
-	int         numoutputs;
-	char**      requestedoutputs = NULL;
+	int     fe_FS;
+	int     numoutputs;
+	char**  requestedoutputs = NULL;
 
 	parameters->AddObject(iomodel->CopyConstantObject(FlowequationIsSIAEnum));
@@ -89,4 +107,11 @@
 	parameters->AddObject(iomodel->CopyConstantObject(StressbalanceViscosityOvershootEnum));
 
+	/*XTH parameters*/
+	iomodel->Constant(&fe_FS,FlowequationFeFSEnum);
+	if(fe_FS==XTaylorHoodEnum){
+		parameters->AddObject(iomodel->CopyConstantObject(AugmentedLagrangianREnum));
+		parameters->AddObject(iomodel->CopyConstantObject(AugmentedLagrangianThetaEnum));
+	}
+
 	/*Requested outputs*/
 	iomodel->FetchData(&requestedoutputs,&numoutputs,StressbalanceRequestedOutputsEnum);
@@ -105,4 +130,6 @@
 	bool   control_analysis;
 	bool   dakota_analysis;
+	bool   islevelset;
+	bool   isdamage;
 
 	/*Fetch constants needed: */
@@ -114,4 +141,5 @@
 	iomodel->Constant(&dakota_analysis,QmuIsdakotaEnum);
 	iomodel->Constant(&materials_type,MaterialsEnum);
+	iomodel->Constant(&islevelset,TransientIslevelsetEnum);
 
 	/*return if no processing required*/
@@ -127,4 +155,9 @@
 	else
 	 iscoupling = false;
+
+	/*is damage mechanics being used?*/
+	if(materials_type==MaticeEnum) isdamage = false;
+	else if(materials_type==MatdamageiceEnum) isdamage = true;
+	else _error_("Material type not recognized");
 
 	/*Get finite element type*/
@@ -171,5 +204,5 @@
 	iomodel->FetchDataToInput(elements,ThicknessEnum);
 	iomodel->FetchDataToInput(elements,SurfaceEnum);
-	iomodel->FetchDataToInput(elements,BedEnum);
+	iomodel->FetchDataToInput(elements,BaseEnum);
 	iomodel->FetchDataToInput(elements,FrictionCoefficientEnum);
 	iomodel->FetchDataToInput(elements,FrictionPEnum);
@@ -185,9 +218,11 @@
 	iomodel->FetchDataToInput(elements,LoadingforceXEnum);
 	iomodel->FetchDataToInput(elements,LoadingforceYEnum);
-	iomodel->FetchDataToInput(elements,DamageDEnum);
-
-	if(iomodel->meshtype==Mesh3DEnum){
-		iomodel->FetchDataToInput(elements,MeshElementonbedEnum);
-		iomodel->FetchDataToInput(elements,MeshElementonsurfaceEnum);
+	if(isdamage)iomodel->FetchDataToInput(elements,DamageDEnum);
+
+	if(iomodel->domaintype==Domain3DEnum){
+		if(iomodel->meshelementtype==PentaEnum){
+			iomodel->FetchDataToInput(elements,MeshElementonbaseEnum);
+			iomodel->FetchDataToInput(elements,MeshElementonsurfaceEnum);
+		}
 		iomodel->FetchDataToInput(elements,BasalforcingsMeltingRateEnum);
 		iomodel->FetchDataToInput(elements,FlowequationBorderFSEnum);
@@ -196,8 +231,16 @@
 		if(dakota_analysis)elements->InputDuplicate(VzEnum,QmuVzEnum);
 	}
+	if(iomodel->domaintype==Domain2DverticalEnum){
+		iomodel->FetchDataToInput(elements,MeshVertexonsurfaceEnum);
+	}
 	if(isFS){
-		iomodel->FetchDataToInput(elements,MeshVertexonbedEnum);
+		iomodel->FetchDataToInput(elements,MeshVertexonbaseEnum);
 		iomodel->FetchDataToInput(elements,PressureEnum,0.);
 		if(dakota_analysis)elements->InputDuplicate(PressureEnum,QmuPressureEnum);
+	}
+	if(islevelset){
+		iomodel->FetchDataToInput(elements,IceMaskNodeActivationEnum);
+		if(iomodel->domaintype!=Domain2DhorizontalEnum)
+			iomodel->FetchDataToInput(elements,MeshVertexonbaseEnum); // required for updating active nodes
 	}
 
@@ -252,7 +295,7 @@
 		}
 		iomodel->FetchData(3,FlowequationBorderSSAEnum,FlowequationVertexEquationEnum,StressbalanceReferentialEnum);
-		if(iomodel->meshtype==Mesh3DEnum) iomodel->FetchData(3,MeshVertexonbedEnum,MeshVertexonsurfaceEnum,FlowequationBorderFSEnum);
+		if(iomodel->domaintype!=Domain2DhorizontalEnum) iomodel->FetchData(3,MeshVertexonbaseEnum,MeshVertexonsurfaceEnum,FlowequationBorderFSEnum);
 		::CreateNodes(nodes,iomodel,StressbalanceAnalysisEnum,finiteelement,approximation);
-		iomodel->DeleteData(6,MeshVertexonbedEnum,MeshVertexonsurfaceEnum,FlowequationBorderSSAEnum,FlowequationBorderFSEnum,
+		iomodel->DeleteData(6,MeshVertexonbaseEnum,MeshVertexonsurfaceEnum,FlowequationBorderSSAEnum,FlowequationBorderFSEnum,
 					FlowequationVertexEquationEnum,StressbalanceReferentialEnum);
 	}
@@ -264,5 +307,5 @@
 		if(!nodes) nodes = new Nodes();
 
-		iomodel->FetchData(6,MeshVertexonbedEnum,MeshVertexonsurfaceEnum,FlowequationBorderSSAEnum,FlowequationBorderFSEnum,
+		iomodel->FetchData(6,MeshVertexonbaseEnum,MeshVertexonsurfaceEnum,FlowequationBorderSSAEnum,FlowequationBorderFSEnum,
 					FlowequationVertexEquationEnum,StressbalanceReferentialEnum);
 		if(isFS){
@@ -301,5 +344,5 @@
 			}
 		}
-		iomodel->DeleteData(6,MeshVertexonbedEnum,MeshVertexonsurfaceEnum,FlowequationBorderSSAEnum,FlowequationBorderFSEnum,
+		iomodel->DeleteData(6,MeshVertexonbaseEnum,MeshVertexonsurfaceEnum,FlowequationBorderSSAEnum,FlowequationBorderFSEnum,
 					FlowequationVertexEquationEnum,StressbalanceReferentialEnum);
 	}
@@ -324,5 +367,5 @@
 	IssmDouble *nodeonHO   = NULL;
 	IssmDouble *nodeonFS   = NULL;
-	IssmDouble *nodeonbed      = NULL;
+	IssmDouble *nodeonbase      = NULL;
 	IssmDouble *groundedice_ls = NULL;
 	IssmDouble *vertices_type  = NULL;
@@ -368,5 +411,7 @@
 				case MINIEnum          : finiteelement = P1bubbleEnum; break;
 				case TaylorHoodEnum    : finiteelement = P2Enum;       break;
-				default: _error_("finite element "<<finiteelement<<" not supported");
+				case XTaylorHoodEnum   : finiteelement = P2Enum;       break;
+				case OneLayerP4zEnum   : finiteelement = P2xP4Enum;    break;
+				default: _error_("finite element "<<EnumToStringx(finiteelement)<<" not supported");
 			}
 		}
@@ -380,10 +425,10 @@
 			iomodel->FetchData(&vertices_type,NULL,NULL,FlowequationVertexEquationEnum);
 			iomodel->FetchData(&nodeonFS,NULL,NULL,FlowequationBorderFSEnum);
-			iomodel->FetchData(&nodeonbed,NULL,NULL,MeshVertexonbedEnum);
+			iomodel->FetchData(&nodeonbase,NULL,NULL,MeshVertexonbaseEnum);
 			iomodel->FetchData(&groundedice_ls,NULL,NULL,MaskGroundediceLevelsetEnum);
-			if(iomodel->meshtype==Mesh3DEnum){
+			if(iomodel->domaintype==Domain3DEnum){
 				iomodel->FetchData(&spcvz,&Mz,&Nz,StressbalanceSpcvzEnum);
 			}
-			else if (iomodel->meshtype==Mesh2DverticalEnum){
+			else if (iomodel->domaintype==Domain2DverticalEnum){
 				iomodel->FetchData(&spcvz,&Mz,&Nz,StressbalanceSpcvyEnum);
 			}
@@ -391,25 +436,13 @@
 				_error_("not supported yet");
 			}
-			for(i=0;i<iomodel->numberofvertices;i++){
-				if(iomodel->my_vertices[i]){
-					if(nodeonbed[i]>0. && groundedice_ls[i]>0. && nodeonFS[i]>0.){
-						if(vertices_type[i] == FSApproximationEnum){
-							for(j=0;j<Nz;j++) spcvz[i*Nz+j] = 0.;
-						}
-						else{
-							_error_("not supported");
-						}
-					}
-				}
-			}
-			if(iomodel->meshtype==Mesh3DEnum){
-				IoModelToConstraintsx(constraints,iomodel,StressbalanceSpcvxEnum,StressbalanceAnalysisEnum,finiteelement,1);
-				IoModelToConstraintsx(constraints,iomodel,StressbalanceSpcvyEnum,StressbalanceAnalysisEnum,finiteelement,2);
-				IoModelToConstraintsx(constraints,iomodel,spcvz,Mz,Nz,StressbalanceAnalysisEnum,finiteelement,3);
+			if(iomodel->domaintype==Domain3DEnum){
+				IoModelToConstraintsx(constraints,iomodel,StressbalanceSpcvxEnum,StressbalanceAnalysisEnum,finiteelement,0);
+				IoModelToConstraintsx(constraints,iomodel,StressbalanceSpcvyEnum,StressbalanceAnalysisEnum,finiteelement,1);
+				IoModelToConstraintsx(constraints,iomodel,spcvz,Mz,Nz,StressbalanceAnalysisEnum,finiteelement,2);
 				iomodel->DeleteData(spcvz,StressbalanceSpcvzEnum);
 			}
-			else if (iomodel->meshtype==Mesh2DverticalEnum){
-				IoModelToConstraintsx(constraints,iomodel,StressbalanceSpcvxEnum,StressbalanceAnalysisEnum,finiteelement,1);
-				IoModelToConstraintsx(constraints,iomodel,spcvz,Mz,Nz,StressbalanceAnalysisEnum,finiteelement,2);
+			else if (iomodel->domaintype==Domain2DverticalEnum){
+				IoModelToConstraintsx(constraints,iomodel,StressbalanceSpcvxEnum,StressbalanceAnalysisEnum,finiteelement,0);
+				IoModelToConstraintsx(constraints,iomodel,spcvz,Mz,Nz,StressbalanceAnalysisEnum,finiteelement,1);
 				iomodel->DeleteData(spcvz,StressbalanceSpcvyEnum);
 			}
@@ -419,5 +452,5 @@
 			iomodel->DeleteData(vertices_type,FlowequationVertexEquationEnum);
 			iomodel->DeleteData(nodeonFS,FlowequationBorderFSEnum);
-			iomodel->DeleteData(nodeonbed,MeshVertexonbedEnum);
+			iomodel->DeleteData(nodeonbase,MeshVertexonbaseEnum);
 			iomodel->DeleteData(groundedice_ls,MaskGroundediceLevelsetEnum);
 
@@ -428,9 +461,19 @@
 			iomodel->FetchData(&z,NULL,NULL,MeshZEnum);
 			switch(finiteelement){
+				case P1Enum:
+					for(i=0;i<iomodel->numberofvertices;i++){
+						if(iomodel->my_vertices[i]){
+							if(reCast<int,IssmDouble>(vertices_type[i])==NoneApproximationEnum){
+								constraints->AddObject(new SpcStatic(count+1,iomodel->nodecounter+iomodel->numberofvertices+iomodel->numberofelements+i+1,0,g*rho_ice*(surface[i]-z[i])/FSreconditioning,StressbalanceAnalysisEnum));
+								count++;
+							}
+						}
+					}
+					break;
 				case P1bubbleEnum:
 					for(i=0;i<iomodel->numberofvertices;i++){
 						if(iomodel->my_vertices[i]){
 							if(reCast<int,IssmDouble>(vertices_type[i])==NoneApproximationEnum){
-								constraints->AddObject(new SpcStatic(count+1,iomodel->nodecounter+iomodel->numberofvertices+iomodel->numberofelements+i+1,1,g*rho_ice*(surface[i]-z[i])/FSreconditioning,StressbalanceAnalysisEnum));
+								constraints->AddObject(new SpcStatic(count+1,iomodel->nodecounter+iomodel->numberofvertices+iomodel->numberofelements+i+1,0,g*rho_ice*(surface[i]-z[i])/FSreconditioning,StressbalanceAnalysisEnum));
 								count++;
 							}
@@ -442,9 +485,12 @@
 						if(iomodel->my_vertices[i]){
 							if(reCast<int,IssmDouble>(vertices_type[i])==NoneApproximationEnum){
-								constraints->AddObject(new SpcStatic(count+1,iomodel->nodecounter+iomodel->numberofvertices+iomodel->numberofedges+i+1,1,g*rho_ice*(surface[i]-z[i])/FSreconditioning,StressbalanceAnalysisEnum));
+								constraints->AddObject(new SpcStatic(count+1,iomodel->nodecounter+iomodel->numberofvertices+iomodel->numberofedges+i+1,0,g*rho_ice*(surface[i]-z[i])/FSreconditioning,StressbalanceAnalysisEnum));
 								count++;
 							}
 						}
 					}
+					break;
+				case P2xP4Enum:
+					//Nothing yet
 					break;
 				default:
@@ -456,6 +502,8 @@
 		}
 		else{
-			IoModelToConstraintsx(constraints,iomodel,StressbalanceSpcvxEnum,StressbalanceAnalysisEnum,finiteelement,1);
-			IoModelToConstraintsx(constraints,iomodel,StressbalanceSpcvyEnum,StressbalanceAnalysisEnum,finiteelement,2);
+			IoModelToConstraintsx(constraints,iomodel,StressbalanceSpcvxEnum,StressbalanceAnalysisEnum,finiteelement,0);
+			if(iomodel->domaintype!=Domain2DverticalEnum){
+				IoModelToConstraintsx(constraints,iomodel,StressbalanceSpcvyEnum,StressbalanceAnalysisEnum,finiteelement,1);
+			}
 		}
 
@@ -468,8 +516,8 @@
 	iomodel->FetchData(&spcvz,&Mz,&Nz,StressbalanceSpcvzEnum);
 	iomodel->FetchData(&nodeonSSA,NULL,NULL,FlowequationBorderSSAEnum);
-	if(iomodel->meshtype==Mesh3DEnum)iomodel->FetchData(&nodeonHO,NULL,NULL,FlowequationBorderHOEnum);
-	if(iomodel->meshtype==Mesh3DEnum)iomodel->FetchData(&nodeonFS,NULL,NULL,FlowequationBorderFSEnum);
-	if(iomodel->meshtype==Mesh3DEnum)iomodel->FetchData(&nodeonbed,NULL,NULL,MeshVertexonbedEnum);
-	if(iomodel->meshtype==Mesh3DEnum)iomodel->FetchData(&groundedice_ls,NULL,NULL,MaskGroundediceLevelsetEnum);
+	if(iomodel->domaintype==Domain3DEnum)iomodel->FetchData(&nodeonHO,NULL,NULL,FlowequationBorderHOEnum);
+	if(iomodel->domaintype==Domain3DEnum)iomodel->FetchData(&nodeonFS,NULL,NULL,FlowequationBorderFSEnum);
+	if(iomodel->domaintype==Domain3DEnum)iomodel->FetchData(&nodeonbase,NULL,NULL,MeshVertexonbaseEnum);
+	if(iomodel->domaintype==Domain3DEnum)iomodel->FetchData(&groundedice_ls,NULL,NULL,MaskGroundediceLevelsetEnum);
 	iomodel->FetchData(&vertices_type,NULL,NULL,FlowequationVertexEquationEnum);
 	iomodel->FetchData(&surface,NULL,NULL,SurfaceEnum);
@@ -503,14 +551,14 @@
 				/*If grionSSA, spc HO dofs: 3 & 4*/
 					if (reCast<int,IssmDouble>(nodeonHO[i])){
+						constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,0,0,StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
+						count++;
 						constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,1,0,StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
 						count++;
-						constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,2,0,StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
-						count++;
 						if (!xIsNan<IssmDouble>(spcvx[i])){
-							constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,3,spcvx[i],StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
+							constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,2,spcvx[i],StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
 							count++;
 						}
 						if (!xIsNan<IssmDouble>(spcvy[i])){
-							constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,4,spcvy[i],StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
+							constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,3,spcvy[i],StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
 							count++;
 						}
@@ -518,14 +566,14 @@
 					}
 					else if (reCast<int,IssmDouble>(nodeonSSA[i])){
+						constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,2,0,StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
+						count++;
 						constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,3,0,StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
 						count++;
-						constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,4,0,StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
-						count++;
 						if (!xIsNan<IssmDouble>(spcvx[i])){
-							constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,1,spcvx[i],StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
+							constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,0,spcvx[i],StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
 							count++;
 						}
 						if (!xIsNan<IssmDouble>(spcvy[i])){
-							constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,2,spcvy[i],StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
+							constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,1,spcvy[i],StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
 							count++;
 						}
@@ -538,16 +586,16 @@
 				/*If grion,HO spc FS dofs: 3 4 & 5*/
 					if (reCast<int,IssmDouble>(nodeonHO[i])){
+						constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,2,0,StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
+						count++;
 						constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,3,0,StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
 						count++;
 						constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,4,0,StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
 						count++;
-						constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,5,0,StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
-						count++;
 						if (!xIsNan<IssmDouble>(spcvx[i])){
-							constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,1,spcvx[i],StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
+							constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,0,spcvx[i],StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
 							count++;
 						}
 						if (!xIsNan<IssmDouble>(spcvy[i])){
-							constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,2,spcvy[i],StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
+							constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,1,spcvy[i],StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
 							count++;
 						}
@@ -555,18 +603,18 @@
 					}
 					else if (reCast<int,IssmDouble>(nodeonFS[i])){ //spc HO nodes: 1 & 2
+						constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,0,0,StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
+						count++;
 						constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,1,0,StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
 						count++;
-						constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,2,0,StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
-						count++;
 						if (!xIsNan<IssmDouble>(spcvx[i])){
-							constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,3,spcvx[i],StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
+							constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,2,spcvx[i],StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
 							count++;
 						}
 						if (!xIsNan<IssmDouble>(spcvy[i])){
-							constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,4,spcvy[i],StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
+							constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,3,spcvy[i],StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
 							count++;
 						}
 						if (!xIsNan<IssmDouble>(spcvz[i])){
-							constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,5,spcvz[i],StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
+							constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,4,spcvz[i],StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
 							count++;
 						}
@@ -578,16 +626,16 @@
 				/*If grion,HO spc FS dofs: 3 4 & 5*/
 					if (reCast<int,IssmDouble>(nodeonSSA[i])){
+						constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,2,0,StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
+						count++;
 						constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,3,0,StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
 						count++;
 						constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,4,0,StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
 						count++;
-						constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,5,0,StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
-						count++;
 						if (!xIsNan<IssmDouble>(spcvx[i])){
-							constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,1,spcvx[i],StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
+							constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,0,spcvx[i],StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
 							count++;
 						}
 						if (!xIsNan<IssmDouble>(spcvy[i])){
-							constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,2,spcvy[i],StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
+							constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,1,spcvy[i],StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
 							count++;
 						}
@@ -595,18 +643,18 @@
 					}
 					else if (reCast<int,IssmDouble>(nodeonFS[i])){ //spc SSA nodes: 1 & 2
+						constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,0,0,StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
+						count++;
 						constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,1,0,StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
 						count++;
-						constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,2,0,StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
-						count++;
 						if (!xIsNan<IssmDouble>(spcvx[i])){
-							constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,3,spcvx[i],StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
+							constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,2,spcvx[i],StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
 							count++;
 						}
 						if (!xIsNan<IssmDouble>(spcvy[i])){
-							constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,4,spcvy[i],StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
+							constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,3,spcvy[i],StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
 							count++;
 						}
 						if (!xIsNan<IssmDouble>(spcvz[i])){
-							constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,5,spcvz[i],StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
+							constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,4,spcvz[i],StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
 							count++;
 						}
@@ -617,5 +665,5 @@
 			else{
 				if (Mx==iomodel->numberofvertices && !xIsNan<IssmDouble>(spcvx[i])){
-					constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,1,spcvx[i],StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
+					constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,0,spcvx[i],StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
 					count++;
 
@@ -631,5 +679,5 @@
 
 					if(spcpresent){
-						constraints->AddObject(new SpcTransient(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,1,Nx,timesx,values,StressbalanceAnalysisEnum));
+						constraints->AddObject(new SpcTransient(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,0,Nx,timesx,values,StressbalanceAnalysisEnum));
 						count++;
 					}
@@ -637,10 +685,10 @@
 				}
 				else if (vertices_type[i]==SIAApproximationEnum){
-					constraints->AddObject(new SpcDynamic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,1,StressbalanceAnalysisEnum));
+					constraints->AddObject(new SpcDynamic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,0,StressbalanceAnalysisEnum));
 					count++;
 				}
 
 				if (My==iomodel->numberofvertices && !xIsNan<IssmDouble>(spcvy[i])){
-					constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,2,spcvy[i],StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vy.
+					constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,1,spcvy[i],StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vy.
 					count++;
 				}
@@ -654,5 +702,5 @@
 					}
 					if(spcpresent){
-						constraints->AddObject(new SpcTransient(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,2,Ny,timesy,values,StressbalanceAnalysisEnum));
+						constraints->AddObject(new SpcTransient(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,1,Ny,timesy,values,StressbalanceAnalysisEnum));
 						count++;
 					}
@@ -660,5 +708,5 @@
 				}
 				else if (vertices_type[i]==SIAApproximationEnum){
-					constraints->AddObject(new SpcDynamic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,2,StressbalanceAnalysisEnum));
+					constraints->AddObject(new SpcDynamic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,1,StressbalanceAnalysisEnum));
 					count++;
 				}
@@ -666,5 +714,5 @@
 				if (reCast<int,IssmDouble>(vertices_type[i])==FSApproximationEnum ||  (reCast<int,IssmDouble>(vertices_type[i])==NoneApproximationEnum)){
 					if (Mz==iomodel->numberofvertices && !xIsNan<IssmDouble>(spcvz[i])){
-						constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,3,spcvz[i],StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 2 to vy
+						constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,2,spcvz[i],StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 2 to vy
 						count++;
 					}
@@ -678,5 +726,5 @@
 						}
 						if(spcpresent){
-							constraints->AddObject(new SpcTransient(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,3,Nz,timesz,values,StressbalanceAnalysisEnum));
+							constraints->AddObject(new SpcTransient(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,2,Nz,timesz,values,StressbalanceAnalysisEnum));
 							count++;
 						}
@@ -686,25 +734,6 @@
 				}
 				if (reCast<int,IssmDouble>(vertices_type[i])==NoneApproximationEnum){
-					constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+iomodel->numberofvertices+i+1,1,g*rho_ice*(surface[i]-z[i])/FSreconditioning,StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 2 to vy
+					constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+iomodel->numberofvertices+i+1,0,g*rho_ice*(surface[i]-z[i])/FSreconditioning,StressbalanceAnalysisEnum)); //add count'th spc, on node i+1, setting dof 2 to vy
 					count++;
-				}
-			}
-
-			/*Constraint at the bedrock interface (v.n = vz = 0) (Coordinates will be updated according to the bed slope)*/
-			if (iomodel->meshtype==Mesh3DEnum) if(nodeonbed[i]>0. && groundedice_ls[i]>=0. && nodeonFS[i]>0.){
-				 switch(reCast<int,IssmDouble>(vertices_type[i])){
-					case SSAFSApproximationEnum:
-						constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,5,0.,StressbalanceAnalysisEnum));
-						count++;
-						break;
-					case HOFSApproximationEnum:
-						constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,5,0.,StressbalanceAnalysisEnum));
-						count++;
-						break;
-					case FSApproximationEnum:
-						constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,3,0.,StressbalanceAnalysisEnum));
-						count++;
-						break;
-					default: _error_("Vertex approximation " << EnumToStringx(reCast<int,IssmDouble>(vertices_type[i])) << " not supported");
 				}
 			}
@@ -717,8 +746,8 @@
 	iomodel->DeleteData(spcvz,StressbalanceSpcvzEnum);
 	iomodel->DeleteData(nodeonSSA,FlowequationBorderSSAEnum);
-	if(iomodel->meshtype==Mesh3DEnum)iomodel->DeleteData(nodeonHO,FlowequationBorderHOEnum);
-	if(iomodel->meshtype==Mesh3DEnum)iomodel->DeleteData(nodeonFS,FlowequationBorderFSEnum);
-	if(iomodel->meshtype==Mesh3DEnum)iomodel->DeleteData(nodeonbed,MeshVertexonbedEnum);
-	if(iomodel->meshtype==Mesh3DEnum)iomodel->DeleteData(groundedice_ls,MaskGroundediceLevelsetEnum);
+	if(iomodel->domaintype==Domain3DEnum)iomodel->DeleteData(nodeonHO,FlowequationBorderHOEnum);
+	if(iomodel->domaintype==Domain3DEnum)iomodel->DeleteData(nodeonFS,FlowequationBorderFSEnum);
+	if(iomodel->domaintype==Domain3DEnum)iomodel->DeleteData(nodeonbase,MeshVertexonbaseEnum);
+	if(iomodel->domaintype==Domain3DEnum)iomodel->DeleteData(groundedice_ls,MaskGroundediceLevelsetEnum);
 	iomodel->DeleteData(vertices_type,FlowequationVertexEquationEnum);
 	iomodel->DeleteData(surface,SurfaceEnum);
@@ -782,8 +811,7 @@
 
 	/*Create Riffront loads for rifts: */
-#ifdef _HAVE_RIFTS_
 	if(numrifts){
 		iomodel->FetchData(&riftinfo,&numriftsegments,NULL,RiftsRiftstructEnum);
-		iomodel->FetchData(5,RiftsRiftstructEnum,ThicknessEnum,BedEnum,SurfaceEnum,MaskGroundediceLevelsetEnum);
+		iomodel->FetchData(5,RiftsRiftstructEnum,ThicknessEnum,BaseEnum,SurfaceEnum,MaskGroundediceLevelsetEnum);
 		for(i=0;i<numriftsegments;i++){
 			if(iomodel->my_elements[reCast<int,IssmDouble>(*(riftinfo+RIFTINFOSIZE*i+2))-1]){
@@ -792,7 +820,5483 @@
 			}
 		}
-		iomodel->DeleteData(5,RiftsRiftstructEnum,ThicknessEnum,BedEnum,SurfaceEnum,MaskGroundediceLevelsetEnum);
+		iomodel->DeleteData(5,RiftsRiftstructEnum,ThicknessEnum,BaseEnum,SurfaceEnum,MaskGroundediceLevelsetEnum);
 		xDelete<IssmDouble>(riftinfo);
 	}
+}/*}}}*/
+
+/*Finite Element Analysis*/
+void           StressbalanceAnalysis::Core(FemModel* femmodel){/*{{{*/
+
+	/*Intermediaries*/
+	bool isSSA,isL1L2,isHO,isFS;
+	bool conserve_loads = true;
+	int  newton,domaintype,fe_FS;
+
+	/* recover parameters:*/
+	femmodel->parameters->FindParam(&isSSA,FlowequationIsSSAEnum);
+	femmodel->parameters->FindParam(&isL1L2,FlowequationIsL1L2Enum);
+	femmodel->parameters->FindParam(&isHO,FlowequationIsHOEnum);
+	femmodel->parameters->FindParam(&isFS,FlowequationIsFSEnum);
+	femmodel->parameters->FindParam(&fe_FS,FlowequationFeFSEnum);
+	femmodel->parameters->FindParam(&domaintype,DomainTypeEnum);
+	femmodel->parameters->FindParam(&newton,StressbalanceIsnewtonEnum);
+
+	if(isFS && !(isSSA || isHO || isL1L2)){
+		if(VerboseSolution()) _printf0_("   computing velocities\n");
+
+		femmodel->SetCurrentConfiguration(StressbalanceAnalysisEnum);
+		if (fe_FS==XTaylorHoodEnum)
+		 solutionsequence_la_theta(femmodel);
+		else if(newton>0)
+		 solutionsequence_newton(femmodel);
+		else
+		 solutionsequence_nonlinear(femmodel,conserve_loads); 
+	}
+	else if(!isFS && (isSSA || isHO || isL1L2)){ 
+		if(VerboseSolution()) _printf0_("   computing velocities\n");
+
+		femmodel->SetCurrentConfiguration(StressbalanceAnalysisEnum);
+		if(newton>0)
+		 solutionsequence_newton(femmodel);
+		else
+		 solutionsequence_nonlinear(femmodel,conserve_loads); 
+
+		if(domaintype==Domain2DverticalEnum && isSSA){
+			femmodel->parameters->SetParam(VxEnum,InputToExtrudeEnum);
+			extrudefrombase_core(femmodel);
+			femmodel->parameters->SetParam(VelEnum,InputToExtrudeEnum);
+			extrudefrombase_core(femmodel);
+		}
+	}
+	else if ((isSSA || isL1L2 || isHO) && isFS){
+		if(VerboseSolution()) _printf0_("   computing coupling between lower order models and FS\n");
+		solutionsequence_FScoupling_nonlinear(femmodel,conserve_loads);
+	}
+	else{
+		_error_("not supported");
+	}
+
+}/*}}}*/
+ElementVector* StressbalanceAnalysis::CreateDVector(Element* element){/*{{{*/
+
+	int approximation;
+	element->GetInputValue(&approximation,ApproximationEnum);
+	switch(approximation){
+		case FSApproximationEnum: 
+			return CreateDVectorFS(element);
+		default:
+			return NULL; //no need for doftypes outside of FS approximation
+	}
+	return NULL;
+
+}/*}}}*/
+ElementMatrix* StressbalanceAnalysis::CreateJacobianMatrix(Element* element){/*{{{*/
+
+	int approximation;
+	element->GetInputValue(&approximation,ApproximationEnum);
+	switch(approximation){
+		case SSAApproximationEnum: 
+			return CreateJacobianMatrixSSA(element);
+		case HOApproximationEnum: 
+			return CreateJacobianMatrixHO(element);
+		case FSApproximationEnum: 
+			return CreateJacobianMatrixFS(element);
+		case NoneApproximationEnum:
+			return NULL;
+		default:
+			_error_("Approximation "<<EnumToStringx(approximation)<<" not supported");
+	}
+}/*}}}*/
+ElementMatrix* StressbalanceAnalysis::CreateKMatrix(Element* element){/*{{{*/
+	int approximation;
+	element->GetInputValue(&approximation,ApproximationEnum);
+	switch(approximation){
+		case SIAApproximationEnum:
+			return NULL;
+		case SSAApproximationEnum: 
+			return CreateKMatrixSSA(element);
+		case L1L2ApproximationEnum: 
+			return CreateKMatrixL1L2(element);
+		case HOApproximationEnum: 
+			return CreateKMatrixHO(element);
+		case FSApproximationEnum: 
+			return CreateKMatrixFS(element);
+		case SSAHOApproximationEnum: 
+			return CreateKMatrixSSAHO(element);
+		case HOFSApproximationEnum: 
+			return CreateKMatrixHOFS(element);
+		case SSAFSApproximationEnum: 
+			return CreateKMatrixSSAFS(element);
+		case NoneApproximationEnum:
+			return NULL;
+		default:
+			_error_("Approximation "<<EnumToStringx(approximation)<<" not supported");
+	}
+}/*}}}*/
+ElementVector* StressbalanceAnalysis::CreatePVector(Element* element){/*{{{*/
+
+	int approximation;
+	element->GetInputValue(&approximation,ApproximationEnum);
+	switch(approximation){
+		case SIAApproximationEnum:
+			return NULL;
+		case SSAApproximationEnum: 
+			return CreatePVectorSSA(element);
+		case L1L2ApproximationEnum: 
+			return CreatePVectorL1L2(element);
+		case HOApproximationEnum: 
+			return CreatePVectorHO(element);
+		case FSApproximationEnum: 
+			return CreatePVectorFS(element);
+		case SSAHOApproximationEnum: 
+			return CreatePVectorSSAHO(element);
+		case HOFSApproximationEnum: 
+			return CreatePVectorHOFS(element);
+		case SSAFSApproximationEnum: 
+			return CreatePVectorSSAFS(element);
+		case NoneApproximationEnum:
+			return NULL;
+		default:
+			_error_("Approximation "<<EnumToStringx(approximation)<<" not supported");
+	}
+}/*}}}*/
+void StressbalanceAnalysis::GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element){/*{{{*/
+
+	int approximation;
+	element->GetInputValue(&approximation,ApproximationEnum);
+	switch(approximation){
+		case FSApproximationEnum: case NoneApproximationEnum:
+			GetSolutionFromInputsFS(solution,element);
+			return;
+		case SSAApproximationEnum: case HOApproximationEnum: case SIAApproximationEnum:
+			GetSolutionFromInputsHoriz(solution,element);
+			return;
+		case L1L2ApproximationEnum:
+			GetSolutionFromInputsHoriz(solution,element);
+			return;
+		case SSAHOApproximationEnum: case HOFSApproximationEnum: case SSAFSApproximationEnum:
+			/*the elements around will create the solution*/
+			return;
+		default:
+			_error_("Approximation "<<EnumToStringx(approximation)<<" not supported");
+	}
+}/*}}}*/
+void StressbalanceAnalysis::GetSolutionFromInputsHoriz(Vector<IssmDouble>* solution,Element* element){/*{{{*/
+
+	IssmDouble   vx,vy;
+	int          domaintype,dim,approximation,dofpernode;
+	int*         doflist = NULL;
+
+	/*Get some parameters*/
+	element->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DhorizontalEnum: dim = 2; dofpernode = 2; break;
+		case Domain2DverticalEnum:   dim = 2; dofpernode = 1; break;
+		case Domain3DEnum:           dim = 3; dofpernode = 2; break;
+		default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
+	}
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+	int numdof   = numnodes*dofpernode;
+	element->GetInputValue(&approximation,ApproximationEnum);
+
+	/*Fetch dof list and allocate solution vector*/
+	element->GetDofList(&doflist,approximation,GsetEnum);
+	IssmDouble* values = xNew<IssmDouble>(numdof);
+
+	/*Get inputs*/
+	Input* vx_input=element->GetInput(VxEnum); _assert_(vx_input);
+	Input* vy_input=NULL;
+	if(domaintype!=Domain2DverticalEnum){vy_input=element->GetInput(VyEnum); _assert_(vy_input);}
+
+	/*Ok, we have vx and vy in values, fill in vx and vy arrays: */
+	Gauss* gauss=element->NewGauss();
+	for(int i=0;i<numnodes;i++){
+		gauss->GaussNode(element->FiniteElement(),i);
+
+		/*Recover vx and vy*/
+		vx_input->GetInputValue(&vx,gauss);
+		values[i*dofpernode+0]=vx;
+		if(dofpernode==2){
+			vy_input->GetInputValue(&vy,gauss);
+			values[i*dofpernode+1]=vy;
+		}
+	}
+
+	solution->SetValues(numdof,doflist,values,INS_VAL);
+
+	/*Free ressources:*/
+	delete gauss;
+	xDelete<IssmDouble>(values);
+	xDelete<int>(doflist);
+}/*}}}*/
+void StressbalanceAnalysis::InputUpdateFromSolution(IssmDouble* solution,Element* element){/*{{{*/
+
+	int approximation;
+	element->GetInputValue(&approximation,ApproximationEnum);
+	switch(approximation){
+		case FSApproximationEnum: case NoneApproximationEnum:
+			InputUpdateFromSolutionFS(solution,element);
+			return;
+		case SIAApproximationEnum: 
+			return;
+		case SSAApproximationEnum: 
+			InputUpdateFromSolutionSSA(solution,element);
+			return;
+		case HOApproximationEnum: 
+			InputUpdateFromSolutionHO(solution,element);
+			return;
+		case L1L2ApproximationEnum:
+			InputUpdateFromSolutionL1L2(solution,element);
+			return;
+		case SSAHOApproximationEnum:
+			InputUpdateFromSolutionSSAHO(solution,element);
+			return;
+		case HOFSApproximationEnum:
+			InputUpdateFromSolutionHOFS(solution,element);
+			return;
+		case SSAFSApproximationEnum:
+			InputUpdateFromSolutionSSAFS(solution,element);
+			return;
+		default:
+			_error_("Approximation "<<EnumToStringx(approximation)<<" not supported");
+	}
+}/*}}}*/
+void StressbalanceAnalysis::UpdateConstraints(FemModel* femmodel){/*{{{*/
+	/*Default, do nothing*/
+	bool islevelset;
+	femmodel->parameters->FindParam(&islevelset,TransientIslevelsetEnum);
+	if(islevelset){
+		SetActiveNodesLSMx(femmodel);
+	}
+	return;
+}/*}}}*/
+
+/*SSA*/
+ElementMatrix* StressbalanceAnalysis::CreateJacobianMatrixSSA(Element* element){/*{{{*/
+
+	/*Intermediaries*/
+	int      domaintype;
+	Element* basalelement;
+
+	/*Get basal element*/
+	element->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DhorizontalEnum:
+			basalelement = element;
+			break;
+		case Domain3DEnum:
+			if(!element->IsOnBase()) return NULL;
+			basalelement = element->SpawnBasalElement();
+			break;
+		default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
+	}
+
+	/*Intermediaries */
+	IssmDouble Jdet,thickness;
+	IssmDouble eps1dotdphii,eps1dotdphij;
+	IssmDouble eps2dotdphii,eps2dotdphij;
+	IssmDouble mu_prime;
+	IssmDouble epsilon[3];/* epsilon=[exx,eyy,exy];*/
+	IssmDouble eps1[2],eps2[2];
+	IssmDouble *xyz_list = NULL;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = basalelement->GetNumberOfNodes();
+
+	/*Initialize Element matrix, vectors and Gaussian points*/
+	ElementMatrix* Ke=this->CreateKMatrixSSA(element); //Initialize Jacobian with regular SSA (first part of the Gateau derivative)
+	IssmDouble*    dbasis = xNew<IssmDouble>(2*numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+	Input* thickness_input = basalelement->GetInput(ThicknessEnum);_assert_(thickness_input);
+	Input* vx_input        = basalelement->GetInput(VxEnum);       _assert_(vx_input);
+	Input* vy_input        = basalelement->GetInput(VyEnum);       _assert_(vy_input);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss = basalelement->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		basalelement->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		basalelement->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+
+		thickness_input->GetInputValue(&thickness, gauss);
+		basalelement->StrainRateSSA(&epsilon[0],xyz_list,gauss,vx_input,vy_input);
+		basalelement->ViscositySSADerivativeEpsSquare(&mu_prime,&epsilon[0]);
+		eps1[0]=2*epsilon[0]+epsilon[1];   eps2[0]=epsilon[2];
+		eps1[1]=epsilon[2];                eps2[1]=epsilon[0]+2*epsilon[1];
+
+		for(int i=0;i<numnodes;i++){
+			for(int j=0;j<numnodes;j++){
+				eps1dotdphii=eps1[0]*dbasis[0*numnodes+i]+eps1[1]*dbasis[1*numnodes+i];
+				eps1dotdphij=eps1[0]*dbasis[0*numnodes+j]+eps1[1]*dbasis[1*numnodes+j];
+				eps2dotdphii=eps2[0]*dbasis[0*numnodes+i]+eps2[1]*dbasis[1*numnodes+i];
+				eps2dotdphij=eps2[0]*dbasis[0*numnodes+j]+eps2[1]*dbasis[1*numnodes+j];
+
+				Ke->values[2*numnodes*(2*i+0)+2*j+0]+=gauss->weight*Jdet*2.*mu_prime*thickness*eps1dotdphij*eps1dotdphii;
+				Ke->values[2*numnodes*(2*i+0)+2*j+1]+=gauss->weight*Jdet*2.*mu_prime*thickness*eps2dotdphij*eps1dotdphii;
+				Ke->values[2*numnodes*(2*i+1)+2*j+0]+=gauss->weight*Jdet*2.*mu_prime*thickness*eps1dotdphij*eps2dotdphii;
+				Ke->values[2*numnodes*(2*i+1)+2*j+1]+=gauss->weight*Jdet*2.*mu_prime*thickness*eps2dotdphij*eps2dotdphii;
+			}
+		}
+	}
+
+	/*Transform Coordinate System*/
+	basalelement->TransformStiffnessMatrixCoord(Ke,XYEnum);
+
+	/*Clean up and return*/
+	delete gauss;
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(dbasis);
+
+	/*clean-up and return*/
+	if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;};
+	return Ke;
+
+}/*}}}*/
+ElementMatrix* StressbalanceAnalysis::CreateKMatrixSSA(Element* element){/*{{{*/
+
+	/* Check if ice in element */
+	if(!element->IsIceInElement()) return NULL;
+
+	/*Intermediaries*/
+	int      domaintype;
+	Element* basalelement;
+
+	/*Get basal element*/
+	element->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DhorizontalEnum:
+			basalelement = element;
+			break;
+		case Domain3DEnum: case Domain2DverticalEnum:
+			if(!element->IsOnBase()) return NULL;
+			basalelement = element->SpawnBasalElement();
+			break;
+		default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
+	}
+
+	/*compute all stiffness matrices for this element*/
+	ElementMatrix* Ke1=CreateKMatrixSSAViscous(basalelement);
+	ElementMatrix* Ke2=CreateKMatrixSSAFriction(basalelement);
+	ElementMatrix* Ke =new ElementMatrix(Ke1,Ke2);
+
+	/*clean-up and return*/
+	if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;};
+	delete Ke1;
+	delete Ke2;
+	return Ke;
+}/*}}}*/
+ElementMatrix* StressbalanceAnalysis::CreateKMatrixSSAFriction(Element* element){/*{{{*/
+
+	/*Return if element is inactive*/
+	if(element->IsFloating() || !element->IsIceInElement()) return NULL;
+
+	/*Intermediaries*/
+	int         dim,domaintype;
+	bool        mainlyfloating;
+	int         migration_style,point1;
+	IssmDouble  alpha2,Jdet,fraction1,fraction2;
+	IssmDouble  gllevelset,phi=1.;
+	IssmDouble *xyz_list  = NULL;
+	Gauss*      gauss     = NULL;
+
+	/*Get problem dimension*/
+	element->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DverticalEnum:   dim = 1;break;
+		case Domain2DhorizontalEnum: dim = 2;break;
+		case Domain3DEnum:           dim = 2;break;
+		default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
+	}
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+	int numdof   = numnodes*dim;
+
+	/*Initialize Element matrix and vectors*/
+	ElementMatrix* Ke = element->NewElementMatrix(SSAApproximationEnum);
+	IssmDouble*    B  = xNew<IssmDouble>(dim*numdof);
+	IssmDouble*    D  = xNewZeroInit<IssmDouble>(dim*dim);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+	element->FindParam(&migration_style,GroundinglineMigrationEnum);
+	Input* surface_input    = element->GetInput(SurfaceEnum); _assert_(surface_input);
+	Input* vx_input         = element->GetInput(VxEnum);      _assert_(vx_input);
+	Input* gllevelset_input = NULL;
+	Input* vy_input         = NULL;
+	if(dim==2){vy_input     = element->GetInput(VyEnum);      _assert_(vy_input);}
+
+	/*build friction object, used later on: */
+	Friction* friction=new Friction(element,1);
+
+	/*Recover portion of element that is grounded*/
+	if(migration_style==SubelementMigrationEnum) phi=element->GetGroundedPortion(xyz_list);
+	if(migration_style==SubelementMigration2Enum){
+		gllevelset_input=element->GetInput(MaskGroundediceLevelsetEnum); _assert_(gllevelset_input);
+		element->GetGroundedPart(&point1,&fraction1,&fraction2,&mainlyfloating);
+	   gauss = element->NewGauss(point1,fraction1,fraction2,mainlyfloating,2);
+	}
+	else{
+		gauss = element->NewGauss(2);
+	}
+
+	/* Start  looping on the number of gaussian points: */
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		friction->GetAlpha2(&alpha2, gauss,vx_input,vy_input,NULL);
+		if(migration_style==SubelementMigrationEnum) alpha2=phi*alpha2;
+		if(migration_style==SubelementMigration2Enum){
+			gllevelset_input->GetInputValue(&gllevelset, gauss);
+			if(gllevelset<0.) alpha2=0.;
+		}
+
+		this->GetBSSAFriction(B,element,dim,xyz_list,gauss);
+		element->JacobianDeterminant(&Jdet, xyz_list,gauss);
+		for(int i=0;i<dim;i++) D[i*dim+i]=alpha2*gauss->weight*Jdet;
+
+		TripleMultiply(B,dim,numdof,1,
+					D,dim,dim,0,
+					B,dim,numdof,0,
+					&Ke->values[0],1);
+	}
+
+	/*Transform Coordinate System*/
+	if(dim==2) element->TransformStiffnessMatrixCoord(Ke,XYEnum);
+
+	/*Clean up and return*/
+	delete gauss;
+	delete friction;
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(B);
+	xDelete<IssmDouble>(D);
+	return Ke;
+}/*}}}*/
+ElementMatrix* StressbalanceAnalysis::CreateKMatrixSSAViscous(Element* element){/*{{{*/
+
+	/* Check if ice in element */
+	if(!element->IsIceInElement()) return NULL;
+
+	/*Intermediaries*/
+	int         dim,domaintype,bsize;
+	IssmDouble  viscosity,newviscosity,oldviscosity;
+	IssmDouble  viscosity_overshoot,thickness,Jdet;
+	IssmDouble  D_scalar;
+	IssmDouble *xyz_list = NULL;
+
+	/*Get problem dimension*/
+	element->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DverticalEnum:   dim = 1; bsize = 1; break;
+		case Domain2DhorizontalEnum: dim = 2; bsize = 3; break;
+		case Domain3DEnum:           dim = 2; bsize = 3; break;
+		default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
+	}
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+	int numdof   = numnodes*dim;
+
+	/*Initialize Element matrix and vectors*/
+	ElementMatrix* Ke     = element->NewElementMatrix(SSAApproximationEnum);
+	IssmDouble*    B      = xNew<IssmDouble>(bsize*numdof);
+	IssmDouble*    Bprime = xNew<IssmDouble>(bsize*numdof);
+	IssmDouble*    D      = xNewZeroInit<IssmDouble>(bsize*bsize);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+	Input* thickness_input=element->GetInput(ThicknessEnum); _assert_(thickness_input);
+	Input* vx_input=element->GetInput(VxEnum);               _assert_(vx_input);
+	Input* vxold_input=element->GetInput(VxPicardEnum);      _assert_(vxold_input);
+	Input* vy_input    = NULL;
+	Input* vyold_input = NULL;
+	if(dim==2){
+		vy_input    = element->GetInput(VyEnum);       _assert_(vy_input);
+		vyold_input = element->GetInput(VyPicardEnum); _assert_(vyold_input);
+	}
+	element->FindParam(&viscosity_overshoot,StressbalanceViscosityOvershootEnum);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss = element->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		this->GetBSSA(B,element,dim,xyz_list,gauss);
+		this->GetBSSAprime(Bprime,element,dim,xyz_list,gauss);
+
+		element->ViscositySSA(&viscosity,dim,xyz_list,gauss,vx_input,vy_input);
+		element->ViscositySSA(&oldviscosity,dim,xyz_list,gauss,vxold_input,vyold_input);
+		thickness_input->GetInputValue(&thickness, gauss);
+
+		newviscosity=viscosity+viscosity_overshoot*(viscosity-oldviscosity);
+		D_scalar=2.*newviscosity*thickness*gauss->weight*Jdet;
+		for(int i=0;i<bsize;i++) D[i*bsize+i]=D_scalar;
+
+		TripleMultiply(B,bsize,numdof,1,
+					D,bsize,bsize,0,
+					Bprime,bsize,numdof,0,
+					&Ke->values[0],1);
+
+		for(int i=0;i<bsize*numdof;i++) if(B[i]==1.) _error_("STREAM");
+		for(int i=0;i<bsize*numdof;i++) if(Bprime[i]==1.) _error_("STREAM");
+	}
+
+	/*Transform Coordinate System*/
+	if(dim==2) element->TransformStiffnessMatrixCoord(Ke,XYEnum);
+
+	/*Clean up and return*/
+	delete gauss;
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(D);
+	xDelete<IssmDouble>(Bprime);
+	xDelete<IssmDouble>(B);
+	return Ke;
+}/*}}}*/
+ElementVector* StressbalanceAnalysis::CreatePVectorSSA(Element* element){/*{{{*/
+
+	/* Check if ice in element */
+	if(!element->IsIceInElement()) return NULL;
+
+	/*Intermediaries*/
+	int      domaintype;
+	Element* basalelement;
+
+	/*Get basal element*/
+	element->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DhorizontalEnum:
+			basalelement = element;
+			break;
+		case Domain3DEnum: case Domain2DverticalEnum:
+			if(!element->IsOnBase()) return NULL;
+			basalelement = element->SpawnBasalElement();
+			break;
+		default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
+	}
+
+	/*compute all load vectors for this element*/
+	ElementVector* pe1=CreatePVectorSSADrivingStress(basalelement);
+	ElementVector* pe2=CreatePVectorSSAFront(basalelement);
+	ElementVector* pe =new ElementVector(pe1,pe2);
+
+	/*clean-up and return*/
+	if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;};
+	delete pe1;
+	delete pe2;
+	return pe;
+}/*}}}*/
+ElementVector* StressbalanceAnalysis::CreatePVectorSSADrivingStress(Element* element){/*{{{*/
+
+	/* Check if ice in element */
+	if(!element->IsIceInElement()) return NULL;
+
+	/*Intermediaries */
+	int         dim,domaintype;
+	IssmDouble  thickness,Jdet,slope[2];
+	IssmDouble* xyz_list = NULL;
+
+	/*Get problem dimension*/
+	element->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DverticalEnum:   dim = 1;break;
+		case Domain2DhorizontalEnum: dim = 2;break;
+		case Domain3DEnum:           dim = 2;break;
+		default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
+	}
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Initialize Element vector and vectors*/
+	ElementVector* pe    = element->NewElementVector(SSAApproximationEnum);
+	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+	Input*     thickness_input=element->GetInput(ThicknessEnum); _assert_(thickness_input); 
+	Input*     surface_input  =element->GetInput(SurfaceEnum);   _assert_(surface_input);
+	IssmDouble rhog = element->GetMaterialParameter(MaterialsRhoIceEnum)*element->GetMaterialParameter(ConstantsGEnum);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		element->NodalFunctions(basis, gauss);
+
+		thickness_input->GetInputValue(&thickness,gauss);
+		surface_input->GetInputDerivativeValue(&slope[0],xyz_list,gauss);
+
+		for(int i=0;i<numnodes;i++){
+			pe->values[i*dim+0]+=-rhog*thickness*slope[0]*Jdet*gauss->weight*basis[i];
+			if(dim==2) pe->values[i*dim+1]+=-rhog*thickness*slope[1]*Jdet*gauss->weight*basis[i];
+		}
+	}
+
+	/*Transform coordinate system*/
+	if(dim==2) element->TransformLoadVectorCoord(pe,XYEnum);
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(basis);
+	delete gauss;
+	return pe;
+}/*}}}*/
+ElementVector* StressbalanceAnalysis::CreatePVectorSSAFront(Element* element){/*{{{*/
+
+	/* Check if ice in element */
+	if(!element->IsIceInElement()) return NULL;
+
+	/*If no front, return NULL*/
+	if(!element->IsIcefront()) return NULL;
+
+	/*Intermediaries*/
+	int         dim,domaintype;
+	IssmDouble  Jdet,thickness,bed,water_pressure,ice_pressure;
+	IssmDouble  surface_under_water,base_under_water,pressure;
+	IssmDouble *xyz_list = NULL;
+	IssmDouble *xyz_list_front = NULL;
+	IssmDouble  normal[2];
+
+	/*Get problem dimension*/
+	element->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DverticalEnum:   dim = 1;break;
+		case Domain2DhorizontalEnum: dim = 2;break;
+		case Domain3DEnum:           dim = 2;break;
+		default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
+	}
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Initialize Element vector and other vectors*/
+	ElementVector* pe    = element->NewElementVector(SSAApproximationEnum);
+	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	Input* thickness_input = element->GetInput(ThicknessEnum); _assert_(thickness_input);
+	Input* base_input       = element->GetInput(BaseEnum);       _assert_(base_input);
+	IssmDouble rho_water   = element->GetMaterialParameter(MaterialsRhoWaterEnum);
+	IssmDouble rho_ice     = element->GetMaterialParameter(MaterialsRhoIceEnum);
+	IssmDouble gravity     = element->GetMaterialParameter(ConstantsGEnum);
+	element->GetVerticesCoordinates(&xyz_list);
+	//element->ZeroLevelsetCoordinates(&xyz_list_front,xyz_list,MaskIceLevelsetEnum);
+	element->GetIcefrontCoordinates(&xyz_list_front,xyz_list,MaskIceLevelsetEnum);
+	element->NormalSection(&normal[0],xyz_list_front);
+
+	/*Start looping on Gaussian points*/
+	Gauss* gauss=element->NewGauss(xyz_list,xyz_list_front,3);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+
+		gauss->GaussPoint(ig);
+		thickness_input->GetInputValue(&thickness,gauss);
+		base_input->GetInputValue(&bed,gauss);
+		element->JacobianDeterminantSurface(&Jdet,xyz_list_front,gauss);
+		element->NodalFunctions(basis,gauss);
+
+		surface_under_water = min(0.,thickness+bed); // 0 if the top of the glacier is above water level
+		base_under_water    = min(0.,bed);           // 0 if the bottom of the glacier is above water level
+		water_pressure = 1.0/2.0*gravity*rho_water*(surface_under_water*surface_under_water - base_under_water*base_under_water);
+		ice_pressure   = 1.0/2.0*gravity*rho_ice*thickness*thickness;
+		pressure = ice_pressure + water_pressure;
+
+		for(int i=0;i<numnodes;i++){
+			pe->values[dim*i+0]+= pressure*Jdet*gauss->weight*normal[0]*basis[i];
+			if(dim==2) pe->values[dim*i+1]+= pressure*Jdet*gauss->weight*normal[1]*basis[i];
+		}
+	}
+
+	/*Transform coordinate system*/
+	if(dim==2) element->TransformLoadVectorCoord(pe,XYEnum);
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(xyz_list_front);
+	xDelete<IssmDouble>(basis);
+	delete gauss;
+	return pe;
+}/*}}}*/
+void StressbalanceAnalysis::GetBSSA(IssmDouble* B,Element* element,int dim,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
+	/*Compute B  matrix. B=[B1 B2 B3] where Bi is of size 3*NDOF2. 
+	 * For node i, Bi can be expressed in the actual coordinate system
+	 * by: 
+	 *                   2D                      1D
+	 *       Bi=[ dN/dx           0    ]   Bi=[ dN/dx ]
+	 *          [   0           dN/dy  ]      
+	 *          [ 1/2*dN/dy  1/2*dN/dx ]     
+	 * where N is the finiteelement function for node i.
+	 *
+	 * We assume B has been allocated already, of size: 3x(NDOF2*numnodes)
+	 */
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Get nodal functions derivatives*/
+	IssmDouble* dbasis=xNew<IssmDouble>(dim*numnodes);
+	element->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+
+	/*Build B: */
+	if(dim==2){
+		for(int i=0;i<numnodes;i++){
+			B[2*numnodes*0+2*i+0] = dbasis[0*numnodes+i];
+			B[2*numnodes*0+2*i+1] = 0.;
+			B[2*numnodes*1+2*i+0] = 0.;
+			B[2*numnodes*1+2*i+1] = dbasis[1*numnodes+i];
+			B[2*numnodes*2+2*i+0] = .5*dbasis[1*numnodes+i];
+			B[2*numnodes*2+2*i+1] = .5*dbasis[0*numnodes+i];
+		}
+	}
+	else{
+		for(int i=0;i<numnodes;i++){
+			B[i] = dbasis[i];
+		}
+	}
+
+	/*Clean-up*/
+	xDelete<IssmDouble>(dbasis);
+}/*}}}*/
+void StressbalanceAnalysis::GetBSSAFriction(IssmDouble* B,Element* element,int dim,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
+	/*Compute B  matrix. B=[B1 B2 B3] where Bi is square and of size 2. 
+	 * For node i, Bi can be expressed in the actual coordinate system
+	 * by: 
+	 *                       2D             1D
+	 *                 Bi=[ N   0 ]    Bi = N
+	 *                    [ 0   N ]
+	 * where N is the finiteelement function for node i.
+	 *
+	 * We assume B has been allocated already, of size: 2 x (numdof*numnodes)
+	 */
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Get nodal functions derivatives*/
+	IssmDouble* basis=xNew<IssmDouble>(numnodes);
+	element->NodalFunctions(basis,gauss);
+
+	/*Build L: */
+	if(dim==2){
+		for(int i=0;i<numnodes;i++){
+			B[2*numnodes*0+2*i+0] = basis[i];
+			B[2*numnodes*0+2*i+1] = 0.;
+			B[2*numnodes*1+2*i+0] = 0.;
+			B[2*numnodes*1+2*i+1] = basis[i];
+		}
+	}
+	else{
+		for(int i=0;i<numnodes;i++){
+			B[i] = basis[i];
+		}
+	}
+
+	/*Clean-up*/
+	xDelete<IssmDouble>(basis);
+}/*}}}*/
+void StressbalanceAnalysis::GetBSSAprime(IssmDouble* Bprime,Element* element,int dim,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
+	/*Compute B'  matrix. B'=[B1' B2' B3'] where Bi' is of size 3*NDOF2. 
+	 * For node i, Bi' can be expressed in the actual coordinate system
+	 * by: 
+	 *                         2D                        1D
+	 *       Bi_prime=[ 2*dN/dx    dN/dy ]     Bi_prime=[ 2*dN/dx ]
+	 *                [   dN/dx  2*dN/dy ]
+	 *                [   dN/dy    dN/dx ]
+	 * where hNis the finiteelement function for node i.
+	 *
+	 * We assume B' has been allocated already, of size: 3x(NDOF2*numnodes)
+	 */
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Get nodal functions derivatives*/
+	IssmDouble* dbasis=xNew<IssmDouble>(dim*numnodes);
+	element->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+
+	/*Build B': */
+	if(dim==2){
+		for(int i=0;i<numnodes;i++){
+			Bprime[2*numnodes*0+2*i+0] = 2.*dbasis[0*numnodes+i];
+			Bprime[2*numnodes*0+2*i+1] =    dbasis[1*numnodes+i];
+			Bprime[2*numnodes*1+2*i+0] =    dbasis[0*numnodes+i];
+			Bprime[2*numnodes*1+2*i+1] = 2.*dbasis[1*numnodes+i];
+			Bprime[2*numnodes*2+2*i+0] =    dbasis[1*numnodes+i];
+			Bprime[2*numnodes*2+2*i+1] =    dbasis[0*numnodes+i];
+		}
+	}
+	else{
+		for(int i=0;i<numnodes;i++){
+			Bprime[i] = 2.*dbasis[i];
+		}
+	}
+
+	/*Clean-up*/
+	xDelete<IssmDouble>(dbasis);
+}/*}}}*/
+void StressbalanceAnalysis::InputUpdateFromSolutionSSA(IssmDouble* solution,Element* element){/*{{{*/
+
+	int         i,dim,domaintype;
+	IssmDouble  rho_ice,g;
+	int*        doflist=NULL;
+	IssmDouble* xyz_list=NULL;
+	Element*    basalelement=NULL;
+
+	/*Deal with pressure first*/
+	int numvertices = element->GetNumberOfVertices();
+	IssmDouble* pressure  = xNew<IssmDouble>(numvertices);
+	IssmDouble* thickness = xNew<IssmDouble>(numvertices);
+	IssmDouble* surface   = xNew<IssmDouble>(numvertices);
+
+	element->FindParam(&domaintype,DomainTypeEnum);
+	rho_ice =element->GetMaterialParameter(MaterialsRhoIceEnum);
+	g       =element->GetMaterialParameter(ConstantsGEnum);
+	switch(domaintype){
+		case Domain2DhorizontalEnum:
+			element->GetInputListOnVertices(thickness,ThicknessEnum);
+			for(i=0;i<numvertices;i++) pressure[i]=rho_ice*g*thickness[i];
+			dim=2;
+			break;
+		case Domain3DEnum:
+			element->GetVerticesCoordinates(&xyz_list);
+			element->GetInputListOnVertices(surface,SurfaceEnum);
+			for(i=0;i<numvertices;i++) pressure[i]=rho_ice*g*(surface[i]-xyz_list[i*3+2]);
+			dim=2;
+			break;
+		case Domain2DverticalEnum:
+			element->GetVerticesCoordinates(&xyz_list);
+			element->GetInputListOnVertices(surface,SurfaceEnum);
+			for(i=0;i<numvertices;i++) pressure[i]=rho_ice*g*(surface[i]-xyz_list[i*3+2]);
+			dim=1;
+			break;
+		default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
+	}
+	element->AddInput(PressureEnum,pressure,P1Enum);
+	xDelete<IssmDouble>(pressure);
+	xDelete<IssmDouble>(thickness);
+	xDelete<IssmDouble>(surface);
+
+	/*Get basal element*/
+	switch(domaintype){
+		case Domain2DhorizontalEnum:
+			basalelement = element;
+			break;
+		case Domain3DEnum: case Domain2DverticalEnum:
+			if(!element->IsOnBase()){xDelete<IssmDouble>(xyz_list); return;}
+			basalelement=element->SpawnBasalElement();
+			break;
+		default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
+	}
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = basalelement->GetNumberOfNodes();
+	int numdof   = numnodes*dim;
+
+	/*Fetch dof list and allocate solution vectors*/
+	basalelement->GetDofList(&doflist,SSAApproximationEnum,GsetEnum);
+	IssmDouble* values    = xNew<IssmDouble>(numdof);
+	IssmDouble* vx        = xNew<IssmDouble>(numnodes);
+	IssmDouble* vy        = xNew<IssmDouble>(numnodes);
+	IssmDouble* vz        = xNew<IssmDouble>(numnodes);
+	IssmDouble* vel       = xNew<IssmDouble>(numnodes);
+
+	/*Use the dof list to index into the solution vector: */
+	for(i=0;i<numdof;i++) values[i]=solution[doflist[i]];
+
+	/*Transform solution in Cartesian Space*/
+	if(dim==2) basalelement->TransformSolutionCoord(&values[0],XYEnum);
+
+	/*Ok, we have vx and vy in values, fill in vx and vy arrays: */
+	for(i=0;i<numnodes;i++){
+		vx[i]=values[i*dim+0];
+		if(xIsNan<IssmDouble>(vx[i])) _error_("NaN found in solution vector");
+
+		if(dim==2){
+			vy[i]=values[i*dim+1];
+			if(xIsNan<IssmDouble>(vy[i])) _error_("NaN found in solution vector");
+		}
+	}
+
+	/*Get Vz and compute vel*/
+	if(dim==2){
+		basalelement->GetInputListOnNodes(&vz[0],VzEnum,0.);
+		for(i=0;i<numnodes;i++) vel[i]=sqrt(vx[i]*vx[i] + vy[i]*vy[i] + vz[i]*vz[i]);
+	}
+	else{
+		basalelement->GetInputListOnNodes(&vy[0],VyEnum,0.);
+		for(i=0;i<numnodes;i++) vel[i]=sqrt(vx[i]*vx[i] + vy[i]*vy[i]);
+	}
+
+	/*Now, we have to move the previous Vx and Vy inputs  to old 
+	 * status, otherwise, we'll wipe them off: */
+	element->InputChangeName(VxEnum,VxPicardEnum);
+	if(dim==2)element->InputChangeName(VyEnum,VyPicardEnum);
+
+	/*Add vx and vy as inputs to the tria element: */
+	element->AddBasalInput(VxEnum,vx,element->GetElementType());
+	if(dim==2)element->AddBasalInput(VyEnum,vy,element->GetElementType());
+	element->AddBasalInput(VelEnum,vel,element->GetElementType());
+
+	/*Free ressources:*/
+	xDelete<IssmDouble>(vel);
+	xDelete<IssmDouble>(vz);
+	xDelete<IssmDouble>(vy);
+	xDelete<IssmDouble>(vx);
+	xDelete<IssmDouble>(values);
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<int>(doflist);
+	if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;};
+}/*}}}*/
+
+/*L1L2*/
+ElementMatrix* StressbalanceAnalysis::CreateKMatrixL1L2(Element* element){/*{{{*/
+
+	/*compute all stiffness matrices for this element*/
+	ElementMatrix* Ke1=CreateKMatrixL1L2Viscous(element);
+	ElementMatrix* Ke2=CreateKMatrixL1L2Friction(element);
+	ElementMatrix* Ke =new ElementMatrix(Ke1,Ke2);
+
+	/*clean-up and return*/
+	delete Ke1;
+	delete Ke2;
+	return Ke;
+}/*}}}*/
+ElementMatrix* StressbalanceAnalysis::CreateKMatrixL1L2Friction(Element* element){/*{{{*/
+
+	if(!element->IsOnBase() || element->IsFloating()) return NULL;
+	Element* basalelement = element->SpawnBasalElement();
+	ElementMatrix* Ke = CreateKMatrixSSAFriction(basalelement);
+
+	/*clean-up and return*/
+	basalelement->DeleteMaterials(); delete basalelement;
+	return Ke;
+}/*}}}*/
+ElementMatrix* StressbalanceAnalysis::CreateKMatrixL1L2Viscous(Element* element){/*{{{*/
+
+	/*Intermediaries*/
+	IssmDouble  viscosity,Jdet;
+	IssmDouble *xyz_list = NULL;
+
+	/*Get element on base*/
+	Element* basalelement = element->GetBasalElement()->SpawnBasalElement();
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = basalelement->GetNumberOfNodes();
+	int numdof   = numnodes*2;
+
+	/*Initialize Element matrix and vectors*/
+	ElementMatrix* Ke     = basalelement->NewElementMatrix(L1L2ApproximationEnum);
+	IssmDouble*    B      = xNew<IssmDouble>(3*numdof);
+	IssmDouble*    Bprime = xNew<IssmDouble>(3*numdof);
+	IssmDouble*    D      = xNewZeroInit<IssmDouble>(3*3);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+	Input* surface_input = element->GetInput(SurfaceEnum); _assert_(surface_input);
+	Input* vx_input      = element->GetInput(VxEnum);      _assert_(vx_input);
+	Input* vy_input      = element->GetInput(VyEnum);      _assert_(vy_input);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss      = element->NewGauss(5);
+	Gauss* gauss_base = basalelement->NewGauss();
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+
+		gauss->GaussPoint(ig);
+		gauss->SynchronizeGaussBase(gauss_base);
+
+		element->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		this->GetBSSA(B,basalelement,2,xyz_list,gauss_base);
+		this->GetBSSAprime(Bprime,basalelement,2,xyz_list,gauss_base);
+
+		element->ViscosityL1L2(&viscosity,xyz_list,gauss,vx_input,vy_input,surface_input);
+
+		for(int i=0;i<3;i++) D[i*3+i]=2*viscosity*gauss->weight*Jdet;
+
+		TripleMultiply(B,3,numdof,1,
+					D,3,3,0,
+					Bprime,3,numdof,0,
+					&Ke->values[0],1);
+	}
+
+	/*Transform Coordinate System*/
+	basalelement->TransformStiffnessMatrixCoord(Ke,XYEnum);
+
+	/*Clean up and return*/
+	delete gauss;
+	delete gauss_base;
+	basalelement->DeleteMaterials(); delete basalelement;
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(D);
+	xDelete<IssmDouble>(Bprime);
+	xDelete<IssmDouble>(B);
+	return Ke;
+}/*}}}*/
+ElementVector* StressbalanceAnalysis::CreatePVectorL1L2(Element* element){/*{{{*/
+
+	/*Intermediaries*/
+	int      domaintype;
+	Element* basalelement;
+
+	/*Get basal element*/
+	element->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DhorizontalEnum:
+			basalelement = element;
+			break;
+		case Domain3DEnum: case Domain2DverticalEnum:
+			if(!element->IsOnBase()) return NULL;
+			basalelement = element->SpawnBasalElement();
+			break;
+		default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
+	}
+
+	/*compute all load vectors for this element*/
+	ElementVector* pe1=CreatePVectorL1L2DrivingStress(basalelement);
+	ElementVector* pe2=CreatePVectorL1L2Front(basalelement);
+	ElementVector* pe =new ElementVector(pe1,pe2);
+
+	/*clean-up and return*/
+	if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;};
+	delete pe1;
+	delete pe2;
+	return pe;
+}/*}}}*/
+ElementVector* StressbalanceAnalysis::CreatePVectorL1L2DrivingStress(Element* element){/*{{{*/
+
+	/*Intermediaries */
+	IssmDouble  thickness,Jdet,slope[2];
+	IssmDouble* xyz_list = NULL;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Initialize Element vector and vectors*/
+	ElementVector* pe    = element->NewElementVector(L1L2ApproximationEnum);
+	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+	Input*     thickness_input=element->GetInput(ThicknessEnum); _assert_(thickness_input); 
+	Input*     surface_input  =element->GetInput(SurfaceEnum);   _assert_(surface_input);
+	IssmDouble rhog = element->GetMaterialParameter(MaterialsRhoIceEnum)*element->GetMaterialParameter(ConstantsGEnum);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		element->NodalFunctions(basis, gauss);
+
+		thickness_input->GetInputValue(&thickness,gauss);
+		surface_input->GetInputDerivativeValue(&slope[0],xyz_list,gauss);
+
+		for(int i=0;i<numnodes;i++){
+			pe->values[i*2+0]+=-rhog*thickness*slope[0]*Jdet*gauss->weight*basis[i];
+			pe->values[i*2+1]+=-rhog*thickness*slope[1]*Jdet*gauss->weight*basis[i];
+		}
+	}
+
+	/*Transform coordinate system*/
+	element->TransformLoadVectorCoord(pe,XYEnum);
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(basis);
+	delete gauss;
+	return pe;
+}/*}}}*/
+ElementVector* StressbalanceAnalysis::CreatePVectorL1L2Front(Element* element){/*{{{*/
+
+	/*If no front, return NULL*/
+	if(!element->IsIcefront()) return NULL;
+
+	/*Intermediaries*/
+	IssmDouble  Jdet,thickness,bed,water_pressure,ice_pressure;
+	IssmDouble  surface_under_water,base_under_water,pressure;
+	IssmDouble *xyz_list = NULL;
+	IssmDouble *xyz_list_front = NULL;
+	IssmDouble  normal[2];
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Initialize Element vector and other vectors*/
+	ElementVector* pe    = element->NewElementVector(L1L2ApproximationEnum);
+	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	Input* thickness_input = element->GetInput(ThicknessEnum); _assert_(thickness_input);
+	Input* base_input       = element->GetInput(BaseEnum);       _assert_(base_input);
+	IssmDouble rho_water   = element->GetMaterialParameter(MaterialsRhoWaterEnum);
+	IssmDouble rho_ice     = element->GetMaterialParameter(MaterialsRhoIceEnum);
+	IssmDouble gravity     = element->GetMaterialParameter(ConstantsGEnum);
+	element->GetVerticesCoordinates(&xyz_list);
+	element->ZeroLevelsetCoordinates(&xyz_list_front,xyz_list,MaskIceLevelsetEnum);
+	element->NormalSection(&normal[0],xyz_list_front);
+
+	/*Start looping on Gaussian points*/
+	Gauss* gauss=element->NewGauss(xyz_list,xyz_list_front,3);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+
+		gauss->GaussPoint(ig);
+		thickness_input->GetInputValue(&thickness,gauss);
+		base_input->GetInputValue(&bed,gauss);
+		element->JacobianDeterminantSurface(&Jdet,xyz_list_front,gauss);
+		element->NodalFunctions(basis,gauss);
+
+		surface_under_water = min(0.,thickness+bed); // 0 if the top of the glacier is above water level
+		base_under_water    = min(0.,bed);           // 0 if the bottom of the glacier is above water level
+		water_pressure = 1.0/2.0*gravity*rho_water*(surface_under_water*surface_under_water - base_under_water*base_under_water);
+		ice_pressure   = 1.0/2.0*gravity*rho_ice*thickness*thickness;
+		pressure = ice_pressure + water_pressure;
+
+		for (int i=0;i<numnodes;i++){
+			pe->values[2*i+0]+= pressure*Jdet*gauss->weight*normal[0]*basis[i];
+			pe->values[2*i+1]+= pressure*Jdet*gauss->weight*normal[1]*basis[i];
+		}
+	}
+
+	/*Transform coordinate system*/
+	element->TransformLoadVectorCoord(pe,XYEnum);
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(xyz_list_front);
+	xDelete<IssmDouble>(basis);
+	delete gauss;
+	return pe;
+}/*}}}*/
+void StressbalanceAnalysis::InputUpdateFromSolutionL1L2(IssmDouble* solution,Element* element){/*{{{*/
+
+	int         i,dim,domaintype;
+	IssmDouble  rho_ice,g;
+	int*        doflist=NULL;
+	IssmDouble* xyz_list=NULL;
+	Element*    basalelement=NULL;
+
+	/*Deal with pressure first*/
+	int numvertices = element->GetNumberOfVertices();
+	IssmDouble* pressure  = xNew<IssmDouble>(numvertices);
+	IssmDouble* thickness = xNew<IssmDouble>(numvertices);
+	IssmDouble* surface   = xNew<IssmDouble>(numvertices);
+
+	element->FindParam(&dim,DomainDimensionEnum);
+	element->FindParam(&domaintype,DomainTypeEnum);
+	rho_ice =element->GetMaterialParameter(MaterialsRhoIceEnum);
+	g       =element->GetMaterialParameter(ConstantsGEnum);
+	if(dim==2){
+		element->GetInputListOnVertices(thickness,ThicknessEnum);
+		for(i=0;i<numvertices;i++) pressure[i]=rho_ice*g*thickness[i];
+	}
+	else{
+		element->GetVerticesCoordinates(&xyz_list);
+		element->GetInputListOnVertices(surface,SurfaceEnum);
+		for(i=0;i<numvertices;i++) pressure[i]=rho_ice*g*(surface[i]-xyz_list[i*3+2]);
+	}
+	element->AddInput(PressureEnum,pressure,P1Enum);
+	xDelete<IssmDouble>(pressure);
+	xDelete<IssmDouble>(thickness);
+	xDelete<IssmDouble>(surface);
+
+	/*Get basal element*/
+	switch(domaintype){
+		case Domain2DhorizontalEnum:
+			basalelement = element;
+			break;
+		case Domain3DEnum:
+			if(!element->IsOnBase()){xDelete<IssmDouble>(xyz_list); return;}
+			basalelement=element->SpawnBasalElement();
+			break;
+		default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
+	}
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = basalelement->GetNumberOfNodes();
+	int numdof   = numnodes*2;
+
+	/*Fetch dof list and allocate solution vectors*/
+	basalelement->GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
+	IssmDouble* values    = xNew<IssmDouble>(numdof);
+	IssmDouble* vx        = xNew<IssmDouble>(numnodes);
+	IssmDouble* vy        = xNew<IssmDouble>(numnodes);
+	IssmDouble* vz        = xNew<IssmDouble>(numnodes);
+	IssmDouble* vel       = xNew<IssmDouble>(numnodes);
+
+	/*Use the dof list to index into the solution vector: */
+	for(i=0;i<numdof;i++) values[i]=solution[doflist[i]];
+
+	/*Transform solution in Cartesian Space*/
+	basalelement->TransformSolutionCoord(&values[0],XYEnum);
+	basalelement->FindParam(&domaintype,DomainTypeEnum);
+
+	/*Ok, we have vx and vy in values, fill in vx and vy arrays: */
+	for(i=0;i<numnodes;i++){
+		vx[i]=values[i*2+0];
+		vy[i]=values[i*2+1];
+
+		/*Check solution*/
+		if(xIsNan<IssmDouble>(vx[i])) _error_("NaN found in solution vector");
+		if(xIsNan<IssmDouble>(vy[i])) _error_("NaN found in solution vector");
+	}
+
+	/*Get Vz and compute vel*/
+	basalelement->GetInputListOnNodes(&vz[0],VzEnum,0.);
+	for(i=0;i<numnodes;i++) vel[i]=sqrt(vx[i]*vx[i] + vy[i]*vy[i] + vz[i]*vz[i]);
+
+	/*Now, we have to move the previous Vx and Vy inputs  to old 
+	 * status, otherwise, we'll wipe them off: */
+	element->InputChangeName(VxEnum,VxPicardEnum);
+	element->InputChangeName(VyEnum,VyPicardEnum);
+
+	/*Add vx and vy as inputs to the tria element: */
+	element->AddBasalInput(VxEnum,vx,element->GetElementType());
+	element->AddBasalInput(VyEnum,vy,element->GetElementType());
+	element->AddBasalInput(VelEnum,vel,element->GetElementType());
+
+	/*Free ressources:*/
+	xDelete<IssmDouble>(vel);
+	xDelete<IssmDouble>(vz);
+	xDelete<IssmDouble>(vy);
+	xDelete<IssmDouble>(vx);
+	xDelete<IssmDouble>(values);
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<int>(doflist);
+	if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;};
+}/*}}}*/
+
+/*HO*/
+ElementMatrix* StressbalanceAnalysis::CreateJacobianMatrixHO(Element* element){/*{{{*/
+
+	/*Intermediaries */
+	IssmDouble Jdet;
+	IssmDouble eps1dotdphii,eps1dotdphij;
+	IssmDouble eps2dotdphii,eps2dotdphij;
+	IssmDouble mu_prime;
+	IssmDouble epsilon[5]; /* epsilon=[exx,eyy,exy,exz,eyz];*/
+	IssmDouble eps1[3],eps2[3];
+	IssmDouble *xyz_list = NULL;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Initialize Element matrix, vectors and Gaussian points*/
+	ElementMatrix* Ke=this->CreateKMatrixHO(element); //Initialize Jacobian with regular HO (first part of the Gateau derivative)
+	IssmDouble*    dbasis = xNew<IssmDouble>(3*numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+	Input* vx_input = element->GetInput(VxEnum); _assert_(vx_input);
+	Input* vy_input = element->GetInput(VyEnum); _assert_(vy_input);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss = element->NewGauss(5);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		element->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+
+		element->StrainRateHO(&epsilon[0],xyz_list,gauss,vx_input,vy_input);
+		element->ViscosityHODerivativeEpsSquare(&mu_prime,&epsilon[0]);
+		eps1[0]=2*epsilon[0]+epsilon[1];   eps2[0]=epsilon[2];
+		eps1[1]=epsilon[2];                eps2[1]=epsilon[0]+2*epsilon[1];
+		eps1[2]=epsilon[3];                eps2[2]=epsilon[4];
+
+		for(int i=0;i<numnodes;i++){
+			for(int j=0;j<numnodes;j++){
+				eps1dotdphii=eps1[0]*dbasis[0*numnodes+i]+eps1[1]*dbasis[1*numnodes+i]+eps1[2]*dbasis[2*numnodes+i];
+				eps1dotdphij=eps1[0]*dbasis[0*numnodes+j]+eps1[1]*dbasis[1*numnodes+j]+eps1[2]*dbasis[2*numnodes+j];
+				eps2dotdphii=eps2[0]*dbasis[0*numnodes+i]+eps2[1]*dbasis[1*numnodes+i]+eps2[2]*dbasis[2*numnodes+i];
+				eps2dotdphij=eps2[0]*dbasis[0*numnodes+j]+eps2[1]*dbasis[1*numnodes+j]+eps2[2]*dbasis[2*numnodes+j];
+
+				Ke->values[2*numnodes*(2*i+0)+2*j+0]+=gauss->weight*Jdet*2.*mu_prime*eps1dotdphij*eps1dotdphii;
+				Ke->values[2*numnodes*(2*i+0)+2*j+1]+=gauss->weight*Jdet*2.*mu_prime*eps2dotdphij*eps1dotdphii;
+				Ke->values[2*numnodes*(2*i+1)+2*j+0]+=gauss->weight*Jdet*2.*mu_prime*eps1dotdphij*eps2dotdphii;
+				Ke->values[2*numnodes*(2*i+1)+2*j+1]+=gauss->weight*Jdet*2.*mu_prime*eps2dotdphij*eps2dotdphii;
+			}
+		}
+	}
+
+	/*Transform Coordinate System*/
+	element->TransformStiffnessMatrixCoord(Ke,XYEnum);
+
+	/*Clean up and return*/
+	delete gauss;
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(dbasis);
+	return Ke;
+}/*}}}*/
+ElementMatrix* StressbalanceAnalysis::CreateKMatrixHO(Element* element){/*{{{*/
+
+	/* Check if ice in element */
+	if(!element->IsIceInElement()) return NULL;
+
+	/*compute all stiffness matrices for this element*/
+	ElementMatrix* Ke1=CreateKMatrixHOViscous(element);
+	ElementMatrix* Ke2=CreateKMatrixHOFriction(element);
+	ElementMatrix* Ke =new ElementMatrix(Ke1,Ke2);
+
+	/*clean-up and return*/
+	delete Ke1;
+	delete Ke2;
+	return Ke;
+}/*}}}*/
+ElementMatrix* StressbalanceAnalysis::CreateKMatrixHOViscous(Element* element){/*{{{*/
+
+	/* Check if ice in element */
+	if(!element->IsIceInElement()) return NULL;
+
+	/*Intermediaries*/
+	int         dim,bsize;
+	IssmDouble  viscosity,newviscosity,oldviscosity;
+	IssmDouble  viscosity_overshoot,thickness,Jdet;
+	IssmDouble  D_scalar;
+	IssmDouble *xyz_list = NULL;
+
+	/*Get problem dimension*/
+	element->FindParam(&dim,DomainDimensionEnum);
+	if(dim==2) bsize = 2;
+	else       bsize = 5;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+	int numdof   = numnodes*(dim-1);
+
+	/*Initialize Element matrix and vectors*/
+	ElementMatrix* Ke     = element->NewElementMatrix(HOApproximationEnum);
+	IssmDouble*    B      = xNew<IssmDouble>(bsize*numdof);
+	IssmDouble*    Bprime = xNew<IssmDouble>(bsize*numdof);
+	IssmDouble*    D      = xNewZeroInit<IssmDouble>(bsize*bsize);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+	Input* vx_input    = element->GetInput(VxEnum);       _assert_(vx_input);
+	Input* vxold_input = element->GetInput(VxPicardEnum); _assert_(vxold_input);
+	Input* vy_input    = NULL;
+	Input* vyold_input = NULL;
+	if(dim==3){
+		vy_input=element->GetInput(VyEnum);          _assert_(vy_input);
+		vyold_input=element->GetInput(VyPicardEnum); _assert_(vyold_input);
+	}
+	element->FindParam(&viscosity_overshoot,StressbalanceViscosityOvershootEnum);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss = element->NewGauss(5);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		this->GetBHO(B,element,dim,xyz_list,gauss);
+		this->GetBHOprime(Bprime,element,dim,xyz_list,gauss);
+
+		element->ViscosityHO(&viscosity,dim,xyz_list,gauss,vx_input,vy_input);
+		element->ViscosityHO(&oldviscosity,dim,xyz_list,gauss,vxold_input,vyold_input);
+
+		newviscosity=viscosity+viscosity_overshoot*(viscosity-oldviscosity);
+		D_scalar=2.*newviscosity*gauss->weight*Jdet;
+		for(int i=0;i<bsize;i++) D[i*bsize+i]=D_scalar;
+
+		TripleMultiply(B,bsize,numdof,1,
+					D,bsize,bsize,0,
+					Bprime,bsize,numdof,0,
+					&Ke->values[0],1);
+	}
+
+	/*Transform Coordinate System*/
+	if(dim==3) element->TransformStiffnessMatrixCoord(Ke,XYEnum);
+
+	/*Clean up and return*/
+	delete gauss;
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(D);
+	xDelete<IssmDouble>(Bprime);
+	xDelete<IssmDouble>(B);
+	return Ke;
+}/*}}}*/
+ElementMatrix* StressbalanceAnalysis::CreateKMatrixHOFriction(Element* element){/*{{{*/
+
+	/* Check if ice in element */
+	if(!element->IsIceInElement()) return NULL;
+
+	if(element->IsFloating() || !element->IsOnBase()) return NULL;
+
+	/*Intermediaries*/
+	int         dim;
+	bool        mainlyfloating;
+	int         migration_style,point1;
+	IssmDouble  alpha2,Jdet,fraction1,fraction2;
+	IssmDouble  gllevelset,phi=1.;
+	IssmDouble *xyz_list_base = NULL;
+	Gauss*      gauss         = NULL;
+
+	/*Get problem dimension*/
+	element->FindParam(&dim,DomainDimensionEnum);
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+	int numdof   = numnodes*(dim-1);
+
+	/*Initialize Element matrix and vectors*/
+	ElementMatrix* Ke = element->NewElementMatrix(HOApproximationEnum);
+	IssmDouble*    B  = xNew<IssmDouble>((dim-1)*numdof);
+	IssmDouble*    D  = xNewZeroInit<IssmDouble>((dim-1)*(dim-1));
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinatesBase(&xyz_list_base);
+	element->FindParam(&migration_style,GroundinglineMigrationEnum);
+	Input* vx_input = element->GetInput(VxEnum);   _assert_(vx_input);
+	Input* vy_input = element->GetInput(VyEnum);   _assert_(vy_input);
+	Input* vz_input = NULL;
+	Input* gllevelset_input = NULL;
+	if(dim==3){vz_input=element->GetInput(VzEnum); _assert_(vz_input);}
+
+	/*build friction object, used later on: */
+	Friction* friction=new Friction(element,2);
+
+	/*Recover portion of element that is grounded*/
+	if(migration_style==SubelementMigrationEnum) phi=element->GetGroundedPortion(xyz_list_base);
+	if(migration_style==SubelementMigration2Enum){
+		gllevelset_input=element->GetInput(MaskGroundediceLevelsetEnum); _assert_(gllevelset_input);
+		element->GetGroundedPart(&point1,&fraction1,&fraction2,&mainlyfloating);
+		//gauss = element->NewGauss(point1,fraction1,fraction2,mainlyfloating,2);
+		gauss=element->NewGaussBase(2);
+	}
+	else{
+		gauss=element->NewGaussBase(2);
+	}
+
+	/* Start  looping on the number of gaussian points: */
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		friction->GetAlpha2(&alpha2,gauss,vx_input,vy_input,vz_input);
+		if(migration_style==SubelementMigrationEnum) alpha2=phi*alpha2;
+		if(migration_style==SubelementMigration2Enum){
+			gllevelset_input->GetInputValue(&gllevelset, gauss);
+			if(gllevelset<0.) alpha2=0.;
+		}
+
+		this->GetBHOFriction(B,element,dim,xyz_list_base,gauss);
+		element->JacobianDeterminantBase(&Jdet,xyz_list_base,gauss);
+		for(int i=0;i<dim-1;i++) D[i*(dim-1)+i]=alpha2*gauss->weight*Jdet;
+
+		TripleMultiply(B,dim-1,numdof,1,
+					D,dim-1,dim-1,0,
+					B,dim-1,numdof,0,
+					&Ke->values[0],1);
+	}
+
+	/*Transform Coordinate System*/
+	if(dim==3) element->TransformStiffnessMatrixCoord(Ke,XYEnum);
+
+	/*Clean up and return*/
+	delete gauss;
+	delete friction;
+	xDelete<IssmDouble>(xyz_list_base);
+	xDelete<IssmDouble>(B);
+	xDelete<IssmDouble>(D);
+	return Ke;
+}/*}}}*/
+#ifdef FSANALYTICAL
+ElementVector* StressbalanceAnalysis::CreatePVectorHO(Element* element){/*{{{*/
+
+	/* Check if ice in element */
+	if(!element->IsIceInElement()) return NULL;
+
+	/*Intermediaries */
+	int         dim;
+	IssmDouble  x_coord,y_coord,z_coord;
+	IssmDouble  Jdet,forcex,forcey,forcez;
+	IssmDouble* xyz_list = NULL;
+
+	/*Get problem dimension*/
+	element->FindParam(&dim,DomainDimensionEnum);
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Initialize Element vector and vectors*/
+	ElementVector* pe=element->NewElementVector(HOApproximationEnum);
+	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGauss(3);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		element->NodalFunctions(basis, gauss);
+
+		x_coord=element->GetXcoord(gauss);
+		y_coord=element->GetYcoord(gauss);
+		if(dim==3) z_coord=element->GetZcoord(gauss);
+		else z_coord=0.;
+
+		forcex=fx(x_coord,y_coord,z_coord,FSANALYTICAL);
+		forcey=fy(x_coord,y_coord,z_coord,FSANALYTICAL);
+
+		for(int i=0;i<numnodes;i++){
+			pe->values[i*(dim-1)+0]+=forcex*Jdet*gauss->weight*basis[i];
+			pe->values[i*(dim-1)+1]+=forcey*Jdet*gauss->weight*basis[i];
+		}
+	}
+
+	/*Transform coordinate system*/
+	if(dim==3) element->TransformLoadVectorCoord(pe,XYEnum);
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(basis);
+	xDelete<IssmDouble>(xyz_list);
+	delete gauss;
+	return pe;
+}/*}}}*/
+#else
+ElementVector* StressbalanceAnalysis::CreatePVectorHO(Element* element){/*{{{*/
+
+	/* Check if ice in element */
+	if(!element->IsIceInElement()) return NULL;
+
+	/*compute all load vectors for this element*/
+	ElementVector* pe1=CreatePVectorHODrivingStress(element);
+	ElementVector* pe2=CreatePVectorHOFront(element);
+	ElementVector* pe =new ElementVector(pe1,pe2);
+
+	/*clean-up and return*/
+	delete pe1;
+	delete pe2;
+	return pe;
+}/*}}}*/
 #endif
-}/*}}}*/
+ElementVector* StressbalanceAnalysis::CreatePVectorHODrivingStress(Element* element){/*{{{*/
+
+	/* Check if ice in element */
+	if(!element->IsIceInElement()) return NULL;
+
+	/*Intermediaries */
+	int         dim;
+	IssmDouble  Jdet,slope[3];
+	IssmDouble* xyz_list = NULL;
+
+	/*Get problem dimension*/
+	element->FindParam(&dim,DomainDimensionEnum);
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Initialize Element vector and vectors*/
+	ElementVector* pe=element->NewElementVector(HOApproximationEnum);
+	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+	Input*     surface_input = element->GetInput(SurfaceEnum);   _assert_(surface_input);
+	IssmDouble rhog = element->GetMaterialParameter(MaterialsRhoIceEnum)*element->GetMaterialParameter(ConstantsGEnum);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGauss(3);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		element->NodalFunctions(basis, gauss);
+		surface_input->GetInputDerivativeValue(&slope[0],xyz_list,gauss);
+
+		for(int i=0;i<numnodes;i++){
+			pe->values[i*(dim-1)+0]+=-rhog*slope[0]*Jdet*gauss->weight*basis[i];
+			if(dim==3) pe->values[i*(dim-1)+1]+=-rhog*slope[1]*Jdet*gauss->weight*basis[i];
+		}
+	}
+
+	/*Transform coordinate system*/
+	if(dim==3) element->TransformLoadVectorCoord(pe,XYEnum);
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(basis);
+	xDelete<IssmDouble>(xyz_list);
+	delete gauss;
+	return pe;
+}/*}}}*/
+ElementVector* StressbalanceAnalysis::CreatePVectorHOFront(Element* element){/*{{{*/
+
+	/* Check if ice in element */
+	if(!element->IsIceInElement()) return NULL;
+
+	/*If no front, return NULL*/
+	if(!element->IsIcefront()) return NULL;
+
+	/*Intermediaries*/
+	int         dim;
+	IssmDouble  Jdet,surface,z,water_pressure,ice_pressure;
+	IssmDouble  surface_under_water,base_under_water,pressure;
+	IssmDouble* xyz_list       = NULL;
+	IssmDouble* xyz_list_front = NULL;
+	IssmDouble  normal[3];
+	Gauss*      gauss = NULL;
+
+	/*Get problem dimension*/
+	element->FindParam(&dim,DomainDimensionEnum);
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes    = element->GetNumberOfNodes();
+	int numvertices = element->GetNumberOfVertices();
+
+	/*Initialize Element vector and other vectors*/
+	ElementVector* pe    = element->NewElementVector(HOApproximationEnum);
+	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	Input* surface_input = element->GetInput(SurfaceEnum); _assert_(surface_input);
+	IssmDouble rho_water = element->GetMaterialParameter(MaterialsRhoWaterEnum);
+	IssmDouble rho_ice   = element->GetMaterialParameter(MaterialsRhoIceEnum);
+	IssmDouble gravity   = element->GetMaterialParameter(ConstantsGEnum);
+	element->GetVerticesCoordinates(&xyz_list);
+	element->ZeroLevelsetCoordinates(&xyz_list_front,xyz_list,MaskIceLevelsetEnum);
+	element->NormalSection(&normal[0],xyz_list_front);
+
+	/*Initialize gauss points*/
+	IssmDouble zmax=xyz_list[0*3+(dim-1)]; for(int i=1;i<numvertices;i++) if(xyz_list[i*3+(dim-1)]>zmax) zmax=xyz_list[i*3+(dim-1)];
+	IssmDouble zmin=xyz_list[0*3+(dim-1)]; for(int i=1;i<numvertices;i++) if(xyz_list[i*3+(dim-1)]<zmin) zmin=xyz_list[i*3+(dim-1)];
+	if(zmax>0. && zmin<0.) gauss=element->NewGauss(xyz_list,xyz_list_front,3,10);//refined in vertical because of the sea level discontinuity
+	else                   gauss=element->NewGauss(xyz_list,xyz_list_front,3,3);
+
+	/* Start  looping on the number of gaussian points: */
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+
+		gauss->GaussPoint(ig);
+		surface_input->GetInputValue(&surface,gauss);
+		if(dim==3) z=element->GetZcoord(gauss);
+		else       z=element->GetYcoord(gauss);
+		element->NodalFunctions(basis,gauss);
+		element->JacobianDeterminantSurface(&Jdet,xyz_list_front,gauss);
+
+		water_pressure = rho_water*gravity*min(0.,z);//0 if the gaussian point is above water level
+		ice_pressure   = rho_ice*gravity*(surface-z);
+		pressure       = ice_pressure + water_pressure;
+
+		for (int i=0;i<numnodes;i++){
+			pe->values[(dim-1)*i+0]+= pressure*Jdet*gauss->weight*normal[0]*basis[i];
+			if(dim==3) pe->values[(dim-1)*i+1]+= pressure*Jdet*gauss->weight*normal[1]*basis[i];
+		}
+	}
+
+	/*Transform coordinate system*/
+	if(dim==3)element->TransformLoadVectorCoord(pe,XYEnum);
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(basis);
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(xyz_list_front);
+	delete gauss;
+	return pe;
+}/*}}}*/
+void StressbalanceAnalysis::GetBHO(IssmDouble* B,Element* element,int dim,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
+	/*Compute B  matrix. B=[B1 B2 B3 B4 B5 B6] where Bi is of size 5*NDOF2. 
+	 * For node i, Bi can be expressed in the actual coordinate system
+	 * by: 
+	 *                   3D                        2D
+	 *
+	 *       Bi=[ dh/dx          0      ]  Bi=[ dh/dx]
+	 *          [   0           dh/dy   ]     [ dh/dy]
+	 *          [ 1/2*dh/dy  1/2*dh/dx  ]     
+	 *          [ 1/2*dh/dz      0      ]    
+	 *          [  0         1/2*dh/dz  ]   
+	 * where h is the interpolation function for node i.
+	 *
+	 * We assume B has been allocated already, of size: 5x(NDOF2*numnodes)
+	 */
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Get nodal functions derivatives*/
+	IssmDouble* dbasis=xNew<IssmDouble>(dim*numnodes);
+	element->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+
+	/*Build B: */
+	if(dim==2){
+		for(int i=0;i<numnodes;i++){
+			B[numnodes*0+i] = dbasis[0*numnodes+i];
+			B[numnodes*1+i] = .5*dbasis[1*numnodes+i];
+		}
+	}
+	else{
+		for(int i=0;i<numnodes;i++){
+			B[2*numnodes*0+2*i+0] = dbasis[0*numnodes+i];
+			B[2*numnodes*0+2*i+1] = 0.;
+			B[2*numnodes*1+2*i+0] = 0.;
+			B[2*numnodes*1+2*i+1] = dbasis[1*numnodes+i];
+			B[2*numnodes*2+2*i+0] = .5*dbasis[1*numnodes+i];
+			B[2*numnodes*2+2*i+1] = .5*dbasis[0*numnodes+i];
+			B[2*numnodes*3+2*i+0] = .5*dbasis[2*numnodes+i];
+			B[2*numnodes*3+2*i+1] = 0.;
+			B[2*numnodes*4+2*i+0] = 0.;
+			B[2*numnodes*4+2*i+1] = .5*dbasis[2*numnodes+i];
+		}
+	}
+
+
+	/*Clean-up*/
+	xDelete<IssmDouble>(dbasis);
+}/*}}}*/
+void StressbalanceAnalysis::GetBHOprime(IssmDouble* Bprime,Element* element,int dim,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
+	/*Compute B'  matrix. B'=[B1' B2' B3'] where Bi' is of size 3*NDOF2. 
+	 * For node i, Bi' can be expressed in the actual coordinate system
+	 * by: 
+	 *                          3D                      2D
+	 *       Bi_prime=[ 2*dN/dx    dN/dy ] Bi_prime=[ 2*dN/dx ]
+	 *                [   dN/dx  2*dN/dy ]          [   dN/dy ]
+	 *                [   dN/dy    dN/dx ]  
+	 * where hNis the finiteelement function for node i.
+	 *
+	 * We assume B' has been allocated already, of size: 3x(NDOF2*numnodes)
+	 */
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Get nodal functions derivatives*/
+	IssmDouble* dbasis=xNew<IssmDouble>(dim*numnodes);
+	element->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+
+	/*Build B': */
+	if(dim==3){
+		for(int i=0;i<numnodes;i++){
+			Bprime[2*numnodes*0+2*i+0] = 2.*dbasis[0*numnodes+i];
+			Bprime[2*numnodes*0+2*i+1] = dbasis[1*numnodes+i];
+			Bprime[2*numnodes*1+2*i+0] = dbasis[0*numnodes+i];
+			Bprime[2*numnodes*1+2*i+1] = 2.*dbasis[1*numnodes+i];
+			Bprime[2*numnodes*2+2*i+0] = dbasis[1*numnodes+i];
+			Bprime[2*numnodes*2+2*i+1] = dbasis[0*numnodes+i];
+			Bprime[2*numnodes*3+2*i+0] = dbasis[2*numnodes+i];
+			Bprime[2*numnodes*3+2*i+1] = 0.;
+			Bprime[2*numnodes*4+2*i+0] = 0.;
+			Bprime[2*numnodes*4+2*i+1] = dbasis[2*numnodes+i];
+		}
+	}
+	else{
+		for(int i=0;i<numnodes;i++){
+			Bprime[numnodes*0+i] = 2.*dbasis[0*numnodes+i];
+			Bprime[numnodes*1+i] = dbasis[1*numnodes+i];
+		}
+	}
+
+	/*Clean-up*/
+	xDelete<IssmDouble>(dbasis);
+}/*}}}*/
+void StressbalanceAnalysis::GetBHOFriction(IssmDouble* B,Element* element,int dim,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
+	/*Compute B  matrix. B=[B1 B2 B3] where Bi is square and of size 2. 
+	 * For node i, Bi can be expressed in the actual coordinate system
+	 * by: 
+	 *                       3D           2D
+	 *                 Bi=[ N   0 ]    Bi=N
+	 *                    [ 0   N ]
+	 * where N is the finiteelement function for node i.
+	 *
+	 * We assume B has been allocated already, of size: 2 x (numdof*numnodes)
+	 */
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Get nodal functions derivatives*/
+	IssmDouble* basis=xNew<IssmDouble>(numnodes);
+	element->NodalFunctions(basis,gauss);
+
+	/*Build L: */
+	if(dim==3){
+		for(int i=0;i<numnodes;i++){
+			B[2*numnodes*0+2*i+0] = basis[i];
+			B[2*numnodes*0+2*i+1] = 0.;
+			B[2*numnodes*1+2*i+0] = 0.;
+			B[2*numnodes*1+2*i+1] = basis[i];
+		}
+	}
+	else{
+		for(int i=0;i<numnodes;i++){
+			B[i] = basis[i];
+		}
+	}
+
+	/*Clean-up*/
+	xDelete<IssmDouble>(basis);
+}/*}}}*/
+void StressbalanceAnalysis::InputUpdateFromSolutionHO(IssmDouble* solution,Element* element){/*{{{*/
+
+	int         i,dim;
+	int*        doflist=NULL;
+	IssmDouble* xyz_list=NULL;
+
+	/*Get mesh dimension*/
+	element->FindParam(&dim,DomainDimensionEnum);
+
+	/*Deal with pressure first*/
+	int numvertices = element->GetNumberOfVertices();
+	IssmDouble* pressure  = xNew<IssmDouble>(numvertices);
+	IssmDouble* surface   = xNew<IssmDouble>(numvertices);
+	IssmDouble  rho_ice   = element->GetMaterialParameter(MaterialsRhoIceEnum);
+	IssmDouble  g         = element->GetMaterialParameter(ConstantsGEnum);
+	element->GetVerticesCoordinates(&xyz_list);
+	element->GetInputListOnVertices(surface,SurfaceEnum);
+	for(i=0;i<numvertices;i++) pressure[i]=rho_ice*g*(surface[i]-xyz_list[i*3+2]);
+	element->AddInput(PressureEnum,pressure,P1Enum);
+	xDelete<IssmDouble>(pressure);
+	xDelete<IssmDouble>(surface);
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+	int numdof   = numnodes*(dim-1);
+
+	/*Fetch dof list and allocate solution vectors*/
+	element->GetDofList(&doflist,HOApproximationEnum,GsetEnum);
+	IssmDouble* values = xNew<IssmDouble>(numdof);
+	IssmDouble* vx     = xNew<IssmDouble>(numnodes);
+	IssmDouble* vy     = xNew<IssmDouble>(numnodes);
+	IssmDouble* vz     = xNew<IssmDouble>(numnodes);
+	IssmDouble* vel    = xNew<IssmDouble>(numnodes);
+
+	/*Use the dof list to index into the solution vector: */
+	for(i=0;i<numdof;i++) values[i]=solution[doflist[i]];
+
+	/*Transform solution in Cartesian Space*/
+	if(dim==3) element->TransformSolutionCoord(&values[0],XYEnum);
+
+	/*Ok, we have vx and vy in values, fill in vx and vy arrays: */
+	for(i=0;i<numnodes;i++){
+		vx[i]=values[i*(dim-1)+0];
+		if(xIsNan<IssmDouble>(vx[i])) _error_("NaN found in solution vector");
+		if(dim==3){
+			vy[i]=values[i*(dim-1)+1];
+			if(xIsNan<IssmDouble>(vy[i])) _error_("NaN found in solution vector");
+		}
+	}
+
+	/*Get Vz and compute vel*/
+	if(dim==3){
+		element->GetInputListOnNodes(&vz[0],VzEnum,0.);
+		for(i=0;i<numnodes;i++) vel[i]=sqrt(vx[i]*vx[i] + vy[i]*vy[i] + vz[i]*vz[i]);
+	}
+	else{
+		element->GetInputListOnNodes(&vy[0],VyEnum,0.);
+		for(i=0;i<numnodes;i++) vel[i]=sqrt(vx[i]*vx[i] + vy[i]*vy[i]);
+	}
+
+	/*Now, we have to move the previous Vx and Vy inputs  to old 
+	 * status, otherwise, we'll wipe them off: */
+	element->InputChangeName(VxEnum,VxPicardEnum);
+	if(dim==3)element->InputChangeName(VyEnum,VyPicardEnum);
+
+	/*Add vx and vy as inputs to the element: */
+	//element->AddInput(VxEnum,  vx,element->GetElementType());
+	//element->AddInput(VyEnum,  vy,element->GetElementType());
+	//element->AddInput(VelEnum,vel,element->GetElementType());
+	element->AddInput(VxEnum,vx,element->GetElementType());
+	if(dim==3)element->AddInput(VyEnum,vy,element->GetElementType());
+	element->AddInput(VelEnum,vel,element->GetElementType());
+
+	/*Free ressources:*/
+	xDelete<IssmDouble>(vel);
+	xDelete<IssmDouble>(vz);
+	xDelete<IssmDouble>(vy);
+	xDelete<IssmDouble>(vx);
+	xDelete<IssmDouble>(values);
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<int>(doflist);
+}/*}}}*/
+
+/*FS*/
+ElementVector* StressbalanceAnalysis::CreateDVectorFS(Element* element){/*{{{*/
+
+	int dim;
+
+	/*Get problem dimension*/
+	element->FindParam(&dim,DomainDimensionEnum);
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int vnumnodes = element->NumberofNodesVelocity();
+	int pnumnodes = element->NumberofNodesPressure();
+
+	/*Initialize output vector*/
+	ElementVector* de = element->NewElementVector(FSvelocityEnum);
+
+	for(int i=0;i<vnumnodes;i++){
+		for(int j=0;j<dim;j++) de->values[i*dim+j]=VelocityEnum;
+	}
+	for(int i=0;i<pnumnodes;i++){
+		de->values[vnumnodes*dim+i]=PressureEnum;
+	}
+
+	return de;
+
+}/*}}}*/
+ElementMatrix* StressbalanceAnalysis::CreateJacobianMatrixFS(Element* element){/*{{{*/
+
+	/*Intermediaries */
+	int        i,j;
+	IssmDouble Jdet;
+	IssmDouble eps1dotdphii,eps1dotdphij;
+	IssmDouble eps2dotdphii,eps2dotdphij;
+	IssmDouble eps3dotdphii,eps3dotdphij;
+	IssmDouble mu_prime;
+	IssmDouble epsilon[6]; /* epsilon=[exx,eyy,ezz,exy,exz,eyz];*/
+	IssmDouble eps1[3],eps2[3],eps3[3];
+	IssmDouble *xyz_list = NULL;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int vnumnodes = element->NumberofNodesVelocity();
+	int pnumnodes = element->NumberofNodesPressure();
+	int numdof    = vnumnodes*NDOF3 + pnumnodes*NDOF1;
+
+	/*Prepare coordinate system list*/
+	int* cs_list = xNew<int>(vnumnodes+pnumnodes);
+	for(i=0;i<vnumnodes;i++) cs_list[i]           = XYZEnum;
+	for(i=0;i<pnumnodes;i++) cs_list[vnumnodes+i] = PressureEnum;
+
+	/*Initialize Element matrix, vectors and Gaussian points*/
+	ElementMatrix* Ke=this->CreateKMatrixFS(element); //Initialize Jacobian with regular FS (first part of the Gateau derivative)
+	IssmDouble*    dbasis = xNew<IssmDouble>(3*vnumnodes);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+	Input* vx_input = element->GetInput(VxEnum); _assert_(vx_input);
+	Input* vy_input = element->GetInput(VyEnum); _assert_(vy_input);
+	Input* vz_input = element->GetInput(VzEnum); _assert_(vz_input);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss = element->NewGauss(5);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		element->NodalFunctionsDerivativesVelocity(dbasis,xyz_list,gauss);
+
+		//element->StrainRateFS(&epsilon[0],xyz_list,gauss,vx_input,vy_input,vz_input);
+		//eps1[0]=epsilon[0];   eps2[0]=epsilon[3];   eps3[0]=epsilon[4];
+		//eps1[1]=epsilon[3];   eps2[1]=epsilon[1];   eps3[1]=epsilon[5];
+		//eps1[2]=epsilon[4];   eps2[2]=epsilon[5];   eps3[2]=epsilon[2];
+		element->StrainRateHO(&epsilon[0],xyz_list,gauss,vx_input,vy_input);
+		eps1[0]=epsilon[0];   eps2[0]=epsilon[2];   eps3[0]=epsilon[3];
+		eps1[1]=epsilon[2];   eps2[1]=epsilon[1];   eps3[1]=epsilon[4];
+		eps1[2]=epsilon[3];   eps2[2]=epsilon[4];   eps3[2]= -epsilon[0] -epsilon[1];
+		element->ViscosityFSDerivativeEpsSquare(&mu_prime,&epsilon[0]);
+
+		for(i=0;i<vnumnodes;i++){
+			for(j=0;j<vnumnodes;j++){
+				eps1dotdphii=eps1[0]*dbasis[0*vnumnodes+i]+eps1[1]*dbasis[1*vnumnodes+i]+eps1[2]*dbasis[2*vnumnodes+i];
+				eps1dotdphij=eps1[0]*dbasis[0*vnumnodes+j]+eps1[1]*dbasis[1*vnumnodes+j]+eps1[2]*dbasis[2*vnumnodes+j];
+				eps2dotdphii=eps2[0]*dbasis[0*vnumnodes+i]+eps2[1]*dbasis[1*vnumnodes+i]+eps2[2]*dbasis[2*vnumnodes+i];
+				eps2dotdphij=eps2[0]*dbasis[0*vnumnodes+j]+eps2[1]*dbasis[1*vnumnodes+j]+eps2[2]*dbasis[2*vnumnodes+j];
+				eps3dotdphii=eps3[0]*dbasis[0*vnumnodes+i]+eps3[1]*dbasis[1*vnumnodes+i]+eps3[2]*dbasis[2*vnumnodes+i];
+				eps3dotdphij=eps3[0]*dbasis[0*vnumnodes+j]+eps3[1]*dbasis[1*vnumnodes+j]+eps3[2]*dbasis[2*vnumnodes+j];
+
+				Ke->values[numdof*(3*i+0)+3*j+0]+=gauss->weight*Jdet*2*mu_prime*eps1dotdphij*eps1dotdphii;
+				Ke->values[numdof*(3*i+0)+3*j+1]+=gauss->weight*Jdet*2*mu_prime*eps2dotdphij*eps1dotdphii;
+				Ke->values[numdof*(3*i+0)+3*j+2]+=gauss->weight*Jdet*2*mu_prime*eps3dotdphij*eps1dotdphii;
+
+				Ke->values[numdof*(3*i+1)+3*j+0]+=gauss->weight*Jdet*2*mu_prime*eps1dotdphij*eps2dotdphii;
+				Ke->values[numdof*(3*i+1)+3*j+1]+=gauss->weight*Jdet*2*mu_prime*eps2dotdphij*eps2dotdphii;
+				Ke->values[numdof*(3*i+1)+3*j+2]+=gauss->weight*Jdet*2*mu_prime*eps3dotdphij*eps2dotdphii;
+
+				Ke->values[numdof*(3*i+2)+3*j+0]+=gauss->weight*Jdet*2*mu_prime*eps1dotdphij*eps3dotdphii;
+				Ke->values[numdof*(3*i+2)+3*j+1]+=gauss->weight*Jdet*2*mu_prime*eps2dotdphij*eps3dotdphii;
+				Ke->values[numdof*(3*i+2)+3*j+2]+=gauss->weight*Jdet*2*mu_prime*eps3dotdphij*eps3dotdphii;
+			}
+		}
+	}
+
+	/*Transform Coordinate System*/
+	element->TransformStiffnessMatrixCoord(Ke,cs_list);
+
+	/*Clean up and return*/
+	delete gauss;
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(dbasis);
+	xDelete<int>(cs_list);
+	return Ke;
+}/*}}}*/
+ElementMatrix* StressbalanceAnalysis::CreateKMatrixFS(Element* element){/*{{{*/
+
+	/*Get type of algorithm*/
+	int fe_FS;
+	element->FindParam(&fe_FS,FlowequationFeFSEnum);
+
+	/*compute all stiffness matrices for this element*/
+	ElementMatrix* Ke1=NULL;
+	if(fe_FS==XTaylorHoodEnum)
+	 Ke1=CreateKMatrixFSViscousXTH(element);
+	else
+	 Ke1=CreateKMatrixFSViscous(element);
+
+	ElementMatrix* Ke2=CreateKMatrixFSFriction(element);
+	ElementMatrix* Ke3=CreateKMatrixFSShelf(element);
+	ElementMatrix* Ke =new ElementMatrix(Ke1,Ke2,Ke3);
+
+	/*clean-up and return*/
+	delete Ke1;
+	delete Ke2;
+	delete Ke3;
+	return Ke;
+}/*}}}*/
+ElementMatrix* StressbalanceAnalysis::CreateKMatrixFSViscousXTH(Element* element){/*{{{*/
+
+	/*Intermediaries*/
+	int         i,dim,epssize;
+	IssmDouble  r,FSreconditioning,Jdet;
+	IssmDouble *xyz_list = NULL;
+
+	/*Get problem dimension*/
+	element->FindParam(&dim,DomainDimensionEnum);
+	element->FindParam(&r,AugmentedLagrangianREnum);
+	if(dim==2) epssize = 3;
+	else       epssize = 6;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int vnumnodes = element->NumberofNodesVelocity();
+	int pnumnodes = element->NumberofNodesPressure();
+	int numdof    = vnumnodes*dim + pnumnodes;
+	int bsize     = epssize + 2;
+
+	/*Prepare coordinate system list*/
+	int* cs_list = xNew<int>(vnumnodes+pnumnodes);
+	if(dim==2) for(i=0;i<vnumnodes;i++) cs_list[i] = XYEnum;
+	else       for(i=0;i<vnumnodes;i++) cs_list[i] = XYZEnum;
+	for(i=0;i<pnumnodes;i++) cs_list[vnumnodes+i] = PressureEnum;
+
+	/*Initialize Element matrix and vectors*/
+	ElementMatrix* Ke     = element->NewElementMatrix(FSvelocityEnum);
+	IssmDouble*    B      = xNew<IssmDouble>(bsize*numdof);
+	IssmDouble*    Bprime = xNew<IssmDouble>(bsize*numdof);
+	IssmDouble*    D      = xNewZeroInit<IssmDouble>(bsize*bsize);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+	element->FindParam(&FSreconditioning,StressbalanceFSreconditioningEnum);
+	Input* vx_input=element->GetInput(VxEnum);     _assert_(vx_input);
+	Input* vy_input=element->GetInput(VyEnum);     _assert_(vy_input);
+	Input* vz_input;
+	if(dim==3){vz_input=element->GetInput(VzEnum); _assert_(vz_input);}
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss = element->NewGauss(5);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		this->GetBFS(B,element,dim,xyz_list,gauss);
+		this->GetBFSprime(Bprime,element,dim,xyz_list,gauss);
+
+		for(i=0;i<epssize;i++)     D[i*bsize+i] = + r*gauss->weight*Jdet;
+		for(i=epssize;i<bsize;i++) D[i*bsize+i] = - FSreconditioning*gauss->weight*Jdet;
+
+		TripleMultiply(B,bsize,numdof,1,
+					D,bsize,bsize,0,
+					Bprime,bsize,numdof,0,
+					&Ke->values[0],1);
+	}
+
+	/*Transform Coordinate System*/
+	element->TransformStiffnessMatrixCoord(Ke,cs_list);
+
+	/*Clean up and return*/
+	delete gauss;
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(D);
+	xDelete<IssmDouble>(Bprime);
+	xDelete<IssmDouble>(B);
+	xDelete<int>(cs_list);
+	return Ke;
+}/*}}}*/
+ElementMatrix* StressbalanceAnalysis::CreateKMatrixFSViscous(Element* element){/*{{{*/
+
+	/*Intermediaries*/
+	int         i,dim,epssize;
+	IssmDouble  viscosity,FSreconditioning,Jdet;
+	IssmDouble *xyz_list = NULL;
+
+	/*Get problem dimension*/
+	element->FindParam(&dim,DomainDimensionEnum);
+	if(dim==2) epssize = 3;
+	else       epssize = 6;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int vnumnodes = element->NumberofNodesVelocity();
+	int pnumnodes = element->NumberofNodesPressure();
+	int numdof    = vnumnodes*dim + pnumnodes;
+	int bsize     = epssize + 2;
+
+	/*Prepare coordinate system list*/
+	int* cs_list = xNew<int>(vnumnodes+pnumnodes);
+	if(dim==2) for(i=0;i<vnumnodes;i++) cs_list[i] = XYEnum;
+	else       for(i=0;i<vnumnodes;i++) cs_list[i] = XYZEnum;
+	for(i=0;i<pnumnodes;i++) cs_list[vnumnodes+i] = PressureEnum;
+
+	/*Initialize Element matrix and vectors*/
+	ElementMatrix* Ke     = element->NewElementMatrix(FSvelocityEnum);
+	IssmDouble*    B      = xNew<IssmDouble>(bsize*numdof);
+	IssmDouble*    Bprime = xNew<IssmDouble>(bsize*numdof);
+	IssmDouble*    D      = xNewZeroInit<IssmDouble>(bsize*bsize);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+	element->FindParam(&FSreconditioning,StressbalanceFSreconditioningEnum);
+	Input* vx_input=element->GetInput(VxEnum);     _assert_(vx_input);
+	Input* vy_input=element->GetInput(VyEnum);     _assert_(vy_input);
+	Input* vz_input;
+	if(dim==3){vz_input=element->GetInput(VzEnum); _assert_(vz_input);}
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss = element->NewGauss(5);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		this->GetBFS(B,element,dim,xyz_list,gauss);
+		this->GetBFSprime(Bprime,element,dim,xyz_list,gauss);
+
+		element->ViscosityFS(&viscosity,dim,xyz_list,gauss,vx_input,vy_input,vz_input);
+		for(i=0;i<epssize;i++)     D[i*bsize+i] = + 2.*viscosity*gauss->weight*Jdet;
+		for(i=epssize;i<bsize;i++) D[i*bsize+i] = - FSreconditioning*gauss->weight*Jdet;
+
+		TripleMultiply(B,bsize,numdof,1,
+					D,bsize,bsize,0,
+					Bprime,bsize,numdof,0,
+					&Ke->values[0],1);
+	}
+
+	/*Transform Coordinate System*/
+	element->TransformStiffnessMatrixCoord(Ke,cs_list);
+
+	/*Clean up and return*/
+	delete gauss;
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(D);
+	xDelete<IssmDouble>(Bprime);
+	xDelete<IssmDouble>(B);
+	xDelete<int>(cs_list);
+	return Ke;
+}/*}}}*/
+ElementMatrix* StressbalanceAnalysis::CreateKMatrixFSShelf(Element* element){/*{{{*/
+
+	if(!element->IsFloating() || !element->IsOnBase()) return NULL;
+
+	/*If on not water or not FS, skip stiffness: */
+	int approximation,shelf_dampening;
+	element->GetInputValue(&approximation,ApproximationEnum);
+	if(approximation!=FSApproximationEnum && approximation!=SSAFSApproximationEnum && approximation!=HOFSApproximationEnum) return NULL;
+	element->FindParam(&shelf_dampening,StressbalanceShelfDampeningEnum);
+	if(shelf_dampening==0) return NULL;
+
+	/*Intermediaries*/
+	bool        mainlyfloating;
+	int         j,i,dim;
+	IssmDouble  Jdet,slope2,scalar,dt;
+	IssmDouble  slope[3];
+	IssmDouble *xyz_list_base = NULL;
+	IssmDouble *xyz_list      = NULL;
+	Gauss*      gauss         = NULL;
+
+	/*Get problem dimension*/
+	element->FindParam(&dim,DomainDimensionEnum);
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int vnumnodes = element->NumberofNodesVelocity();
+	int pnumnodes = element->NumberofNodesPressure();
+	int numdof    = vnumnodes*dim + pnumnodes;
+
+	/*Initialize Element matrix and vectors*/
+	ElementMatrix* Ke = element->NewElementMatrix(FSvelocityEnum);
+	IssmDouble*    vbasis = xNew<IssmDouble>(vnumnodes);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinatesBase(&xyz_list_base);
+	element->GetVerticesCoordinates(&xyz_list);
+	element->FindParam(&dt,TimesteppingTimeStepEnum);
+	if(dt==0)   dt=1.e+5;
+	IssmDouble  rho_water     = element->GetMaterialParameter(MaterialsRhoWaterEnum);
+	IssmDouble  gravity       = element->GetMaterialParameter(ConstantsGEnum);
+	Input*      surface_input = element->GetInput(SurfaceEnum); _assert_(surface_input);
+
+	/* Start  looping on the number of gaussian points: */
+	gauss=element->NewGaussBase(3);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		surface_input->GetInputDerivativeValue(&slope[0],xyz_list,gauss);
+		element->NodalFunctionsVelocity(vbasis,gauss);
+		element->JacobianDeterminantBase(&Jdet,xyz_list_base,gauss);
+		if(dim==2) slope2=slope[0]*slope[0];
+		else if(dim==3) slope2=slope[0]*slope[0]+slope[1]*slope[1];
+		scalar  = rho_water*gravity*sqrt(1+slope2)*gauss->weight*Jdet*dt; 
+		for(i=0;i<vnumnodes;i++){
+			for(j=0;j<vnumnodes;j++){
+				Ke->values[numdof*((i+1)*dim-1)+(j+1)*dim-1] += scalar*vbasis[i]*vbasis[j];
+			}
+		}
+	}
+
+	/*DO NOT Transform Coordinate System: this stiffness matrix is already expressed in tangential coordinates*/
+
+	/*Clean up and return*/
+	delete gauss;
+	xDelete<IssmDouble>(xyz_list_base);
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(vbasis);
+	return Ke;
+}/*}}}*/
+#ifdef FSANALYTICAL
+ElementMatrix* StressbalanceAnalysis::CreateKMatrixFSFriction(Element* element){/*{{{*/
+
+	if(element->IsFloating() || !element->IsOnBase()) return NULL;
+
+	/*If on water or not FS, skip stiffness: */
+	int approximation;
+	element->GetInputValue(&approximation,ApproximationEnum);
+	if(approximation!=FSApproximationEnum && approximation!=SSAFSApproximationEnum && approximation!=HOFSApproximationEnum) return NULL;
+
+	/*Intermediaries*/
+	int         i,dim;
+	IssmDouble  alpha2,Jdet;
+	IssmDouble  x_coord,y_coord,z_coord;
+	IssmDouble *xyz_list_base = NULL;
+	Gauss*      gauss         = NULL;
+
+	/*Get problem dimension*/
+	element->FindParam(&dim,DomainDimensionEnum);
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int vnumnodes = element->NumberofNodesVelocity();
+	int pnumnodes = element->NumberofNodesPressure();
+	int numdof    = vnumnodes*dim + pnumnodes;
+
+	/*Initialize Element matrix and vectors*/
+	ElementMatrix* Ke = element->NewElementMatrix(FSvelocityEnum);
+	IssmDouble*    B  = xNew<IssmDouble>((dim-1)*numdof);
+	IssmDouble*    D  = xNewZeroInit<IssmDouble>((dim-1)*(dim-1));
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinatesBase(&xyz_list_base);
+	Input* vx_input         = element->GetInput(VxEnum);      _assert_(vx_input);
+	Input* vy_input         = element->GetInput(VyEnum);      _assert_(vy_input);
+	Input* vz_input         = NULL;
+	if(dim==3){    vz_input = element->GetInput(VzEnum);      _assert_(vz_input);}
+
+	/* Start  looping on the number of gaussian points: */
+	gauss=element->NewGaussBase(10);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		x_coord=element->GetXcoord(gauss);
+		y_coord=element->GetYcoord(gauss);
+		if(dim==3) z_coord=element->GetZcoord(gauss);
+		else z_coord=0.;
+
+		alpha2=alpha(x_coord,y_coord,z_coord,FSANALYTICAL);
+
+		this->GetBFSFriction(B,element,dim,xyz_list_base,gauss);
+		element->JacobianDeterminantBase(&Jdet,xyz_list_base,gauss);
+		for(int i=0;i<dim-1;i++) D[i*(dim-1)+i] = alpha2*gauss->weight*Jdet; //taub_x = -alpha2 v_x (same for y)
+
+		TripleMultiply(B,dim-1,numdof,1,
+					D,dim-1,dim-1,0,
+					B,dim-1,numdof,0,
+					&Ke->values[0],1);
+	}
+
+	/*DO NOT Transform Coordinate System: this stiffness matrix is already expressed in tangential coordinates*/
+
+	/*Clean up and return*/
+	delete gauss;
+	xDelete<IssmDouble>(xyz_list_base);
+	xDelete<IssmDouble>(B);
+	xDelete<IssmDouble>(D);
+	return Ke;
+}/*}}}*/
+ElementVector* StressbalanceAnalysis::CreatePVectorFS(Element* element){/*{{{*/
+
+	int         i,dim,fe_FS;
+	IssmDouble  x_coord,y_coord,z_coord;
+	IssmDouble  Jdet,forcex,forcey,forcez;
+	IssmDouble *xyz_list = NULL;
+
+	element->FindParam(&fe_FS,FlowequationFeFSEnum);
+	element->FindParam(&dim,DomainDimensionEnum);
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int vnumnodes = element->NumberofNodesVelocity();
+	int pnumnodes = element->NumberofNodesPressure();
+
+	/*Prepare coordinate system list*/
+	int* cs_list = xNew<int>(vnumnodes+pnumnodes);
+	if(dim==2) for(i=0;i<vnumnodes;i++) cs_list[i] = XYEnum;
+	else       for(i=0;i<vnumnodes;i++) cs_list[i] = XYZEnum;
+	for(i=0;i<pnumnodes;i++) cs_list[vnumnodes+i] = PressureEnum;
+
+	/*Initialize vectors*/
+	ElementVector* pe     = element->NewElementVector(FSvelocityEnum);
+	IssmDouble*    vbasis = xNew<IssmDouble>(vnumnodes);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGauss(5);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		element->NodalFunctionsVelocity(vbasis,gauss);
+
+		x_coord=element->GetXcoord(gauss);
+		y_coord=element->GetYcoord(gauss);
+		if(dim==3) z_coord=element->GetZcoord(gauss);
+		else z_coord=0.;
+
+		forcex=fx(x_coord,y_coord,z_coord,FSANALYTICAL);
+		forcey=fy(x_coord,y_coord,z_coord,FSANALYTICAL);
+		forcez=fz(x_coord,y_coord,z_coord,FSANALYTICAL);
+
+		for(i=0;i<vnumnodes;i++){
+			pe->values[i*dim+0] += forcex *Jdet*gauss->weight*vbasis[i];
+			pe->values[i*dim+1] += forcey *Jdet*gauss->weight*vbasis[i];
+			if(dim==3) pe->values[i*dim+2] += forcez *Jdet*gauss->weight*vbasis[i];
+		}
+	}
+
+	/*Transform coordinate system*/
+	element->TransformLoadVectorCoord(pe,cs_list);
+
+	/*Clean up and return*/
+	delete gauss;
+	xDelete<int>(cs_list);
+	xDelete<IssmDouble>(vbasis);
+	xDelete<IssmDouble>(xyz_list);
+	if(fe_FS==XTaylorHoodEnum){
+		ElementVector* pe2=CreatePVectorFSViscousXTH(element);
+		ElementVector* pe3 = new ElementVector(pe,pe2);
+		delete pe;
+		delete pe2;
+		return pe3;
+	}
+	return pe;
+}/*}}}*/
+#else
+ElementMatrix* StressbalanceAnalysis::CreateKMatrixFSFriction(Element* element){/*{{{*/
+
+	if(element->IsFloating() || !element->IsOnBase()) return NULL;
+
+	/*If on water or not FS, skip stiffness: */
+	int approximation;
+	element->GetInputValue(&approximation,ApproximationEnum);
+	if(approximation!=FSApproximationEnum && approximation!=SSAFSApproximationEnum && approximation!=HOFSApproximationEnum) return NULL;
+
+	/*Intermediaries*/
+	bool        mainlyfloating;
+	int         i,dim,domaintype,epssize;
+	int         migration_style,point1;
+	IssmDouble  alpha2,Jdet,fraction1,fraction2;
+	IssmDouble  gllevelset,phi=1.;
+	IssmDouble *xyz_list_base = NULL;
+	Gauss*      gauss         = NULL;
+
+	/*Get problem dimension*/
+	element->FindParam(&dim,DomainDimensionEnum);
+	element->FindParam(&domaintype,DomainTypeEnum);
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int vnumnodes = element->NumberofNodesVelocity();
+	int pnumnodes = element->NumberofNodesPressure();
+	int numdof    = vnumnodes*dim + pnumnodes;
+
+	/*Initialize Element matrix and vectors*/
+	ElementMatrix* Ke = element->NewElementMatrix(FSvelocityEnum);
+	IssmDouble*    B  = xNew<IssmDouble>((dim-1)*numdof);
+	IssmDouble*    D  = xNewZeroInit<IssmDouble>((dim-1)*(dim-1));
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinatesBase(&xyz_list_base);
+	element->FindParam(&migration_style,GroundinglineMigrationEnum);
+	Input* vx_input         = element->GetInput(VxEnum);      _assert_(vx_input);
+	Input* vy_input         = element->GetInput(VyEnum);      _assert_(vy_input);
+	Input* vz_input         = NULL;
+	if(dim==3){    vz_input = element->GetInput(VzEnum);      _assert_(vz_input);}
+	Input* gllevelset_input = NULL;
+
+	/*build friction object, used later on: */
+	Friction* friction=new Friction(element,dim==3?3:1);
+
+	/*Recover portion of element that is grounded*/
+	if(migration_style==SubelementMigrationEnum) phi=element->GetGroundedPortion(xyz_list_base);
+	if(migration_style==SubelementMigration2Enum){
+		if(domaintype==Domain2DverticalEnum) _error_("Subelement Migration 2 not implemented yet for Flowline");
+		gllevelset_input=element->GetInput(MaskGroundediceLevelsetEnum); _assert_(gllevelset_input);
+		element->GetGroundedPart(&point1,&fraction1,&fraction2,&mainlyfloating);
+		//gauss = element->NewGauss(point1,fraction1,fraction2,mainlyfloating,2);
+		gauss=element->NewGaussBase(3);
+	}
+	else{
+		gauss=element->NewGaussBase(3);
+	}
+
+	/* Start  looping on the number of gaussian points: */
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		friction->GetAlpha2(&alpha2,gauss,vx_input,vy_input,vz_input);
+		if(migration_style==SubelementMigrationEnum) alpha2=phi*alpha2;
+		if(migration_style==SubelementMigration2Enum){
+			gllevelset_input->GetInputValue(&gllevelset, gauss);
+			if(gllevelset<0.) alpha2=0.;
+		}
+
+		this->GetBFSFriction(B,element,dim,xyz_list_base,gauss);
+		element->JacobianDeterminantBase(&Jdet,xyz_list_base,gauss);
+		for(int i=0;i<dim-1;i++) D[i*(dim-1)+i] = alpha2*gauss->weight*Jdet; //taub_x = -alpha2 v_x (same for y)
+
+		TripleMultiply(B,dim-1,numdof,1,
+					D,dim-1,dim-1,0,
+					B,dim-1,numdof,0,
+					&Ke->values[0],1);
+	}
+
+	/*DO NOT Transform Coordinate System: this stiffness matrix is already expressed in tangential coordinates*/
+
+	/*Clean up and return*/
+	delete gauss;
+	delete friction;
+	xDelete<IssmDouble>(xyz_list_base);
+	xDelete<IssmDouble>(B);
+	xDelete<IssmDouble>(D);
+	return Ke;
+}/*}}}*/
+ElementVector* StressbalanceAnalysis::CreatePVectorFS(Element* element){/*{{{*/
+
+	ElementVector* pe = NULL;
+
+	int fe_FS;
+	element->FindParam(&fe_FS,FlowequationFeFSEnum);
+
+	if(fe_FS==XTaylorHoodEnum){
+		ElementVector* pe1=CreatePVectorFSViscous(element);
+		ElementVector* pe2=CreatePVectorFSShelf(element);
+		ElementVector* pe3=CreatePVectorFSFront(element);
+		ElementVector* petemp =new ElementVector(pe1,pe2,pe3);
+		ElementVector* pe4=CreatePVectorFSViscousXTH(element);
+		pe = new ElementVector(petemp,pe4);
+		delete pe1;
+		delete pe2;
+		delete pe3;
+		delete petemp;
+		delete pe4;
+	}
+	else{
+		ElementVector* pe1=CreatePVectorFSViscous(element);
+		ElementVector* pe2=CreatePVectorFSShelf(element);
+		ElementVector* pe3=CreatePVectorFSFront(element);
+		pe =new ElementVector(pe1,pe2,pe3);
+		delete pe1;
+		delete pe2;
+		delete pe3;
+	}
+
+	/*clean-up and return*/
+	return pe;
+}/*}}}*/
+#endif
+ElementVector* StressbalanceAnalysis::CreatePVectorFSViscous(Element* element){/*{{{*/
+
+	int         i,dim;
+	IssmDouble  Jdet,forcex,forcey,forcez;
+	IssmDouble *xyz_list = NULL;
+
+	/*Get problem dimension*/
+	element->FindParam(&dim,DomainDimensionEnum);
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int vnumnodes = element->NumberofNodesVelocity();
+	int pnumnodes = element->NumberofNodesPressure();
+
+	/*Prepare coordinate system list*/
+	int* cs_list = xNew<int>(vnumnodes+pnumnodes);
+	if(dim==2) for(i=0;i<vnumnodes;i++) cs_list[i] = XYEnum;
+	else       for(i=0;i<vnumnodes;i++) cs_list[i] = XYZEnum;
+	for(i=0;i<pnumnodes;i++) cs_list[vnumnodes+i] = PressureEnum;
+
+	/*Initialize vectors*/
+	ElementVector* pe     = element->NewElementVector(FSvelocityEnum);
+	IssmDouble*    vbasis = xNew<IssmDouble>(vnumnodes);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+	IssmDouble  rho_ice =element->GetMaterialParameter(MaterialsRhoIceEnum);
+	IssmDouble  gravity =element->GetMaterialParameter(ConstantsGEnum);
+	Input*      loadingforcex_input=element->GetInput(LoadingforceXEnum);  _assert_(loadingforcex_input);
+	Input*      loadingforcey_input=element->GetInput(LoadingforceYEnum);  _assert_(loadingforcey_input);
+	Input*      loadingforcez_input=NULL;
+	if(dim==3){
+		loadingforcez_input=element->GetInput(LoadingforceZEnum);  _assert_(loadingforcez_input);
+	}
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGauss(5);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		element->NodalFunctionsVelocity(vbasis,gauss);
+
+		loadingforcex_input->GetInputValue(&forcex,gauss);
+		loadingforcey_input->GetInputValue(&forcey,gauss);
+		if(dim==3) loadingforcez_input->GetInputValue(&forcez,gauss);
+
+		for(i=0;i<vnumnodes;i++){
+			pe->values[i*dim+0] += +rho_ice*forcex *Jdet*gauss->weight*vbasis[i];
+			pe->values[i*dim+1] += +rho_ice*forcey *Jdet*gauss->weight*vbasis[i];
+			if(dim==3){
+				pe->values[i*dim+2] += +rho_ice*forcez*Jdet*gauss->weight*vbasis[i];
+				pe->values[i*dim+2] += -rho_ice*gravity*Jdet*gauss->weight*vbasis[i];
+			}
+			else{
+				pe->values[i*dim+1] += -rho_ice*gravity*Jdet*gauss->weight*vbasis[i];
+			}
+		}
+	}
+
+	/*Transform coordinate system*/
+	element->TransformLoadVectorCoord(pe,cs_list);
+
+	/*Clean up and return*/
+	delete gauss;
+	xDelete<int>(cs_list);
+	xDelete<IssmDouble>(vbasis);
+	xDelete<IssmDouble>(xyz_list);
+	return pe;
+}/*}}}*/
+ElementVector* StressbalanceAnalysis::CreatePVectorFSViscousXTH(Element* element){/*{{{*/
+
+	int         i,tausize,dim;
+	IssmDouble  Jdet,r;
+	IssmDouble  epsxx,epsyy,epszz,epsxy,epsxz,epsyz;
+	IssmDouble  sigmapxx,sigmapyy,sigmapzz,sigmapxy,sigmapxz,sigmapyz;
+	IssmDouble *xyz_list = NULL;
+	Gauss*      gauss    = NULL;
+
+	/*Get problem dimension*/
+	element->FindParam(&dim,DomainDimensionEnum);
+	if(dim==2) tausize = 3;
+	else       tausize = 6;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int vnumnodes = element->NumberofNodesVelocity();
+	int pnumnodes = element->NumberofNodesPressure();
+	int tnumnodes = element->GetNumberOfVertices();      //Tensors, P1 DG
+
+	/*Prepare coordinate system list*/
+	int* cs_list = xNew<int>(vnumnodes+pnumnodes);
+	if(dim==2) for(i=0;i<vnumnodes;i++) cs_list[i] = XYEnum;
+	else       for(i=0;i<vnumnodes;i++) cs_list[i] = XYZEnum;
+	for(i=0;i<pnumnodes;i++) cs_list[vnumnodes+i]  = PressureEnum;
+
+	/*Initialize vectors*/
+	ElementVector* pe      = element->NewElementVector(FSvelocityEnum);
+	IssmDouble*    Dstar   = xNewZeroInit<IssmDouble>((dim*vnumnodes)*(tausize*tnumnodes));
+	IssmDouble*    tau     = xNew<IssmDouble>(tausize*tnumnodes);
+	IssmDouble*    d       = xNew<IssmDouble>(tausize*tnumnodes);
+	IssmDouble*    vdbasis = xNew<IssmDouble>(dim*vnumnodes);
+	IssmDouble*    tbasis  = xNew<IssmDouble>(tnumnodes);
+	IssmDouble*    D       = xNewZeroInit<IssmDouble>(tausize*tnumnodes*tausize*tnumnodes);
+
+	/*Retrieve all inputs and parameters*/
+	element->FindParam(&r,AugmentedLagrangianREnum);
+	element->GetVerticesCoordinates(&xyz_list);
+
+	/*Get d and tau*/
+	Input* epsxx_input=element->GetInput(StrainRatexxEnum); _assert_(epsxx_input);
+	Input* epsyy_input=element->GetInput(StrainRateyyEnum); _assert_(epsyy_input);
+	Input* epsxy_input=element->GetInput(StrainRatexyEnum); _assert_(epsxy_input);
+	Input* epszz_input=NULL; Input* epsxz_input=NULL; Input* epsyz_input=NULL;
+	Input* sigmapxx_input=element->GetInput(DeviatoricStressxxEnum); _assert_(sigmapxx_input);
+	Input* sigmapyy_input=element->GetInput(DeviatoricStressyyEnum); _assert_(sigmapyy_input);
+	Input* sigmapxy_input=element->GetInput(DeviatoricStressxyEnum); _assert_(sigmapxy_input);
+	Input* sigmapzz_input=NULL; Input* sigmapxz_input=NULL; Input* sigmapyz_input=NULL;
+	if(dim==3){
+		epszz_input=element->GetInput(StrainRatezzEnum); _assert_(epszz_input);
+		epsxz_input=element->GetInput(StrainRatexzEnum); _assert_(epsxz_input);
+		epsyz_input=element->GetInput(StrainRateyzEnum); _assert_(epsyz_input);
+		sigmapzz_input=element->GetInput(DeviatoricStresszzEnum); _assert_(sigmapzz_input);
+		sigmapxz_input=element->GetInput(DeviatoricStressxzEnum); _assert_(sigmapxz_input);
+		sigmapyz_input=element->GetInput(DeviatoricStressyzEnum); _assert_(sigmapyz_input);
+	}
+
+	gauss = element->NewGauss();
+	for(int i=0;i<tnumnodes;i++){
+		gauss->GaussNode(P1DGEnum,i);
+
+		epsxx_input->GetInputValue(&epsxx,gauss); sigmapxx_input->GetInputValue(&sigmapxx,gauss);
+		epsyy_input->GetInputValue(&epsyy,gauss); sigmapyy_input->GetInputValue(&sigmapyy,gauss);
+		epsxy_input->GetInputValue(&epsxy,gauss); sigmapxy_input->GetInputValue(&sigmapxy,gauss);
+		if(dim==2){
+			d[i*tausize+0]=epsxx;  tau[i*tausize+0]=sigmapxx;
+			d[i*tausize+1]=epsyy;  tau[i*tausize+1]=sigmapyy;
+			d[i*tausize+2]=epsxy;  tau[i*tausize+2]=sigmapxy;
+		}
+		else{
+			epszz_input->GetInputValue(&epszz,gauss); sigmapzz_input->GetInputValue(&sigmapzz,gauss);
+			epsxz_input->GetInputValue(&epsxz,gauss); sigmapxz_input->GetInputValue(&sigmapxz,gauss);
+			epsyz_input->GetInputValue(&epsyz,gauss); sigmapyz_input->GetInputValue(&sigmapyz,gauss);
+			d[i*tausize+0]=epsxx;  tau[i*tausize+0]=sigmapxx;
+			d[i*tausize+1]=epsyy;  tau[i*tausize+1]=sigmapyy;
+			d[i*tausize+2]=epszz;  tau[i*tausize+2]=sigmapzz;
+			d[i*tausize+3]=epsxy;  tau[i*tausize+3]=sigmapxy;
+			d[i*tausize+4]=epsxz;  tau[i*tausize+4]=sigmapxz;
+			d[i*tausize+5]=epsyz;  tau[i*tausize+5]=sigmapyz;
+		}
+	}
+
+	/* Start  looping on the number of gaussian points: */
+	delete gauss;
+	gauss=element->NewGauss(5);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+		element->JacobianDeterminant(&Jdet,xyz_list,gauss);
+
+		/*Create Dstar*/
+		/*In dim = 2
+		 *
+		 *       <----------------- tausize ---------------> x tnumnodes
+		 *       |  gamma_ij^x         0       gamma_ij^y  | ^
+		 * Dij = |                                         | dim
+		 *       |     0          gamma_ij^y   gamma_ij^x  | v
+		 *                                                   x
+		 *                                                   vnumnodes
+		 *
+		 *In dim = 3
+		 *
+		 *       |  gamma_ij^x         0          0         gamma_ij^y  gamma_ij^z      0      |
+		 *       |                                                                             |
+		 * Dij = |     0          gamma_ij^y      0         gamma_ij^x     0        gamma_ij^z |
+		 *       |                                                                             |
+		 *       |     0               0      gamma_ij^z        0       gamma_ij^x  gamma_ij^y |
+		 *
+		 * gamma_ij^x = zeta_j dphi_i/dx
+		 *
+		 * where:
+		 *   - zeta_j is the nodal function for the j^th node of the tensor (P1DG)
+		 *   - phi_i  is the nodal function for the i^th node of the velocity (P2)*/
+		element->NodalFunctionsDerivativesVelocity(vdbasis,xyz_list,gauss);
+		element->NodalFunctionsTensor(tbasis,gauss);
+		if(dim==2){
+			for(int i=0;i<vnumnodes;i++){
+				for(int j=0;j<tnumnodes;j++){
+					Dstar[(i*dim+0)*tausize*tnumnodes + j*tausize+0] += gauss->weight*Jdet*tbasis[j]*vdbasis[0*vnumnodes+i];
+					Dstar[(i*dim+0)*tausize*tnumnodes + j*tausize+2] += gauss->weight*Jdet*tbasis[j]*vdbasis[1*vnumnodes+i];
+
+					Dstar[(i*dim+1)*tausize*tnumnodes + j*tausize+1] += gauss->weight*Jdet*tbasis[j]*vdbasis[1*vnumnodes+i];
+					Dstar[(i*dim+1)*tausize*tnumnodes + j*tausize+2] += gauss->weight*Jdet*tbasis[j]*vdbasis[0*vnumnodes+i];
+				}
+			}
+		}
+		else{
+			for(int i=0;i<vnumnodes;i++){
+				for(int j=0;j<tnumnodes;j++){
+					Dstar[(i*dim+0)*tausize*tnumnodes + j*tausize+0] += gauss->weight*Jdet*tbasis[j]*vdbasis[0*vnumnodes+i];
+					Dstar[(i*dim+0)*tausize*tnumnodes + j*tausize+3] += gauss->weight*Jdet*tbasis[j]*vdbasis[1*vnumnodes+i];
+					Dstar[(i*dim+0)*tausize*tnumnodes + j*tausize+4] += gauss->weight*Jdet*tbasis[j]*vdbasis[2*vnumnodes+i];
+
+					Dstar[(i*dim+1)*tausize*tnumnodes + j*tausize+1] += gauss->weight*Jdet*tbasis[j]*vdbasis[1*vnumnodes+i];
+					Dstar[(i*dim+1)*tausize*tnumnodes + j*tausize+3] += gauss->weight*Jdet*tbasis[j]*vdbasis[0*vnumnodes+i];
+					Dstar[(i*dim+1)*tausize*tnumnodes + j*tausize+5] += gauss->weight*Jdet*tbasis[j]*vdbasis[2*vnumnodes+i];
+
+					Dstar[(i*dim+2)*tausize*tnumnodes + j*tausize+2] += gauss->weight*Jdet*tbasis[j]*vdbasis[2*vnumnodes+i];
+					Dstar[(i*dim+2)*tausize*tnumnodes + j*tausize+4] += gauss->weight*Jdet*tbasis[j]*vdbasis[0*vnumnodes+i];
+					Dstar[(i*dim+2)*tausize*tnumnodes + j*tausize+5] += gauss->weight*Jdet*tbasis[j]*vdbasis[1*vnumnodes+i];
+				}
+			}
+		}
+	}
+
+	/*contribution -Dstar tau*/
+	for(i=0;i<tausize*tnumnodes;i++) D[i*(tausize*tnumnodes)+i] = -1.;
+	TripleMultiply(Dstar,dim*vnumnodes,tausize*tnumnodes,0,
+				D,tausize*tnumnodes,tausize*tnumnodes,0,
+				tau,tausize*tnumnodes,1,0,
+				&pe->values[0],1);
+
+	/*contribution + r Dstar d*/
+	for(i=0;i<tausize*tnumnodes;i++) D[i*(tausize*tnumnodes)+i] = +r;
+	TripleMultiply(Dstar,dim*vnumnodes,tausize*tnumnodes,0,
+				D,tausize*tnumnodes,tausize*tnumnodes,0,
+				d,tausize*tnumnodes,1,0,
+				&pe->values[0],1);
+
+	/*Transform coordinate system*/
+	element->TransformLoadVectorCoord(pe,cs_list);
+
+	/*Clean up and return*/
+	delete gauss;
+	xDelete<int>(cs_list);
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(Dstar);
+	xDelete<IssmDouble>(d);
+	xDelete<IssmDouble>(D);
+	xDelete<IssmDouble>(tau);
+	xDelete<IssmDouble>(vdbasis);
+	xDelete<IssmDouble>(tbasis);
+	return pe;
+}/*}}}*/
+ElementVector* StressbalanceAnalysis::CreatePVectorFSShelf(Element* element){/*{{{*/
+
+	int         i,dim;
+	IssmDouble  Jdet,water_pressure,bed;
+	IssmDouble	normal[3];
+	IssmDouble *xyz_list_base = NULL;
+
+	/*Get basal element*/
+	if(!element->IsOnBase() || !element->IsFloating()) return NULL;
+
+	/*Get problem dimension*/
+	element->FindParam(&dim,DomainDimensionEnum);
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int vnumnodes = element->NumberofNodesVelocity();
+	int pnumnodes = element->NumberofNodesPressure();
+
+	/*Prepare coordinate system list*/
+	int* cs_list = xNew<int>(vnumnodes+pnumnodes);
+	if(dim==2) for(i=0;i<vnumnodes;i++) cs_list[i] = XYEnum;
+	else       for(i=0;i<vnumnodes;i++) cs_list[i] = XYZEnum;
+	for(i=0;i<pnumnodes;i++) cs_list[vnumnodes+i] = PressureEnum;
+
+	/*Initialize vectors*/
+	ElementVector* pe     = element->NewElementVector(FSvelocityEnum);
+	IssmDouble*    vbasis = xNew<IssmDouble>(vnumnodes);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinatesBase(&xyz_list_base);
+	Input*      base_input=element->GetInput(BaseEnum); _assert_(base_input);
+	IssmDouble  rho_water=element->GetMaterialParameter(MaterialsRhoWaterEnum);
+	IssmDouble  gravity  =element->GetMaterialParameter(ConstantsGEnum);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGaussBase(5);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminantBase(&Jdet,xyz_list_base,gauss);
+		element->NodalFunctionsVelocity(vbasis,gauss);
+
+		element->NormalBase(&normal[0],xyz_list_base);
+		_assert_(normal[dim-1]<0.);
+		base_input->GetInputValue(&bed, gauss);
+		water_pressure=gravity*rho_water*bed;
+
+		for(i=0;i<vnumnodes;i++){
+			pe->values[i*dim+0] += water_pressure*gauss->weight*Jdet*vbasis[i]*normal[0];
+			pe->values[i*dim+1] += water_pressure*gauss->weight*Jdet*vbasis[i]*normal[1];
+			if(dim==3){
+				pe->values[i*dim+2]+=water_pressure*gauss->weight*Jdet*vbasis[i]*normal[2];
+			}
+		}
+	}
+
+	/*Transform coordinate system*/
+	element->TransformLoadVectorCoord(pe,cs_list);
+
+	/*Clean up and return*/
+	delete gauss;
+	xDelete<int>(cs_list);
+	xDelete<IssmDouble>(vbasis);
+	xDelete<IssmDouble>(xyz_list_base);
+	return pe;
+}/*}}}*/
+ElementVector* StressbalanceAnalysis::CreatePVectorFSFront(Element* element){/*{{{*/
+
+	/*If no front, return NULL*/
+	if(!element->IsIcefront()) return NULL;
+
+	/*Intermediaries*/
+	int         i,dim;
+	IssmDouble  Jdet,pressure,surface,z;
+	IssmDouble	normal[3];
+	IssmDouble *xyz_list       = NULL;
+	IssmDouble *xyz_list_front = NULL;
+	Gauss      *gauss          = NULL;
+
+	/*Make sure current element is floating*/
+	if(!element->IsFloating()) return NULL;
+
+	/*Get problem dimension*/
+	element->FindParam(&dim,DomainDimensionEnum);
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int vnumnodes   = element->NumberofNodesVelocity();
+	int pnumnodes   = element->NumberofNodesPressure();
+	int numvertices = element->GetNumberOfVertices();
+
+	/*Prepare coordinate system list*/
+	int* cs_list = xNew<int>(vnumnodes+pnumnodes);
+	if(dim==2) for(i=0;i<vnumnodes;i++) cs_list[i] = XYEnum;
+	else       for(i=0;i<vnumnodes;i++) cs_list[i] = XYZEnum;
+	for(i=0;i<pnumnodes;i++) cs_list[vnumnodes+i] = PressureEnum;
+
+	/*Initialize vectors*/
+	ElementVector* pe     = element->NewElementVector(FSvelocityEnum);
+	IssmDouble*    vbasis = xNew<IssmDouble>(vnumnodes);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+	element->ZeroLevelsetCoordinates(&xyz_list_front,xyz_list,MaskIceLevelsetEnum);
+	element->NormalSection(&normal[0],xyz_list_front);
+	Input* surface_input  = element->GetInput(SurfaceEnum); _assert_(surface_input);
+	IssmDouble  rho_water = element->GetMaterialParameter(MaterialsRhoWaterEnum);
+	IssmDouble  gravity   = element->GetMaterialParameter(ConstantsGEnum);
+
+	/*Initialize gauss points*/
+	IssmDouble zmax=xyz_list[0*3+(dim-1)]; for(int i=1;i<numvertices;i++) if(xyz_list[i*3+(dim-1)]>zmax) zmax=xyz_list[i*3+(dim-1)];
+	IssmDouble zmin=xyz_list[0*3+(dim-1)]; for(int i=1;i<numvertices;i++) if(xyz_list[i*3+(dim-1)]<zmin) zmin=xyz_list[i*3+(dim-1)];
+	if(zmax>0. && zmin<0.) gauss=element->NewGauss(xyz_list,xyz_list_front,3,30);//refined in vertical because of the sea level discontinuity
+	else                   gauss=element->NewGauss(xyz_list,xyz_list_front,3,3);
+
+	/* Start  looping on the number of gaussian points: */
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminantSurface(&Jdet,xyz_list_front,gauss);
+		element->NodalFunctionsVelocity(vbasis,gauss);
+		surface_input->GetInputValue(&surface,gauss);
+		if(dim==3) z=element->GetZcoord(gauss);
+		else       z=element->GetYcoord(gauss);
+		pressure = rho_water*gravity*min(0.,z);//0 if the gaussian point is above water level
+
+		for (int i=0;i<vnumnodes;i++){
+			pe->values[dim*i+0]+= pressure*Jdet*gauss->weight*normal[0]*vbasis[i];
+			pe->values[dim*i+1]+= pressure*Jdet*gauss->weight*normal[1]*vbasis[i];
+			if(dim==3) pe->values[dim*i+2]+= pressure*Jdet*gauss->weight*normal[2]*vbasis[i];
+		}
+	}
+
+	/*Transform coordinate system*/
+	element->TransformLoadVectorCoord(pe,cs_list);
+
+	/*Clean up and return*/
+	delete gauss;
+	xDelete<int>(cs_list);
+	xDelete<IssmDouble>(vbasis);
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(xyz_list_front);
+	return pe;
+}/*}}}*/
+void StressbalanceAnalysis::GetBFS(IssmDouble* B,Element* element,int dim,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
+	/*Compute B  matrix. B=[Bv1 Bv2 ... Bp1 Bp2 ...] where Bvi is of size 3*NDOF3. 
+	 * For node i, Bvi can be expressed in the actual coordinate system
+	 * by: 	   Bvi=[ dphi/dx          0        ]
+	 *					 [   0           dphi/dy     ]
+	 *					 [ 1/2*dphi/dy    1/2*dphi/dx]
+	 *					 [   0             0         ]
+	 *					 [ dphi/dx         dphi/dy   ]
+	 *
+	 *         Bpi=[  0    ]
+	 *					[  0    ]
+	 *					[  0    ]
+	 *					[ phi_p ]
+	 *					[  0    ]
+	 *
+	 *	In 3d:
+	 *     	   Bvi=[ dh/dx          0             0      ]
+	 *					[   0           dh/dy           0      ]
+	 *					[   0             0           dh/dz    ]
+	 *					[ 1/2*dh/dy    1/2*dh/dx        0      ]
+	 *					[ 1/2*dh/dz       0         1/2*dh/dx  ]
+	 *					[   0          1/2*dh/dz    1/2*dh/dy  ]
+	 *					[   0             0             0      ]
+	 *					[ dh/dx         dh/dy         dh/dz    ]
+	 *
+	 *         Bpi=[ 0 ]
+	 *					[ 0 ]
+	 *					[ 0 ]
+	 *					[ 0 ]
+	 *					[ 0 ]
+	 *					[ 0 ]
+	 *					[ h ]
+	 *					[ 0 ]
+	 *	where phi is the finiteelement function for node i.
+	 *	Same thing for Bb except the last column that does not exist.
+	 */
+
+	/*Fetch number of nodes for this finite element*/
+	int pnumnodes = element->NumberofNodesPressure();
+	int vnumnodes = element->NumberofNodesVelocity();
+
+	/*Get nodal functions derivatives*/
+	IssmDouble* vdbasis=xNew<IssmDouble>(dim*vnumnodes);
+	IssmDouble* pbasis =xNew<IssmDouble>(pnumnodes);
+	element->NodalFunctionsDerivativesVelocity(vdbasis,xyz_list,gauss);
+	element->NodalFunctionsPressure(pbasis,gauss);
+
+	/*Build B: */
+	if(dim==2){
+		for(int i=0;i<vnumnodes;i++){
+			B[(dim*vnumnodes+pnumnodes)*0+dim*i+0] = vdbasis[0*vnumnodes+i];
+			B[(dim*vnumnodes+pnumnodes)*0+dim*i+1] = 0.;
+			B[(dim*vnumnodes+pnumnodes)*1+dim*i+0] = 0.;
+			B[(dim*vnumnodes+pnumnodes)*1+dim*i+1] = vdbasis[1*vnumnodes+i];
+			B[(dim*vnumnodes+pnumnodes)*2+dim*i+0] = .5*vdbasis[1*vnumnodes+i];
+			B[(dim*vnumnodes+pnumnodes)*2+dim*i+1] = .5*vdbasis[0*vnumnodes+i];
+			B[(dim*vnumnodes+pnumnodes)*3+dim*i+0] = 0.;
+			B[(dim*vnumnodes+pnumnodes)*3+dim*i+1] = 0.;
+			B[(dim*vnumnodes+pnumnodes)*4+dim*i+0] = vdbasis[0*vnumnodes+i];
+			B[(dim*vnumnodes+pnumnodes)*4+dim*i+1] = vdbasis[1*vnumnodes+i];
+		}
+		for(int i=0;i<pnumnodes;i++){
+			B[(dim*vnumnodes+pnumnodes)*0+(dim*vnumnodes)+i] = 0.;
+			B[(dim*vnumnodes+pnumnodes)*1+(dim*vnumnodes)+i] = 0.;
+			B[(dim*vnumnodes+pnumnodes)*2+(dim*vnumnodes)+i] = 0.;
+			B[(dim*vnumnodes+pnumnodes)*3+(dim*vnumnodes)+i] = pbasis[i];
+			B[(dim*vnumnodes+pnumnodes)*4+(dim*vnumnodes)+i] = 0.;
+		}
+	}
+	else{
+		for(int i=0;i<vnumnodes;i++){
+			B[(dim*vnumnodes+pnumnodes)*0+dim*i+0] = vdbasis[0*vnumnodes+i];
+			B[(dim*vnumnodes+pnumnodes)*0+dim*i+1] = 0.;
+			B[(dim*vnumnodes+pnumnodes)*0+dim*i+2] = 0.;
+			B[(dim*vnumnodes+pnumnodes)*1+dim*i+0] = 0.;
+			B[(dim*vnumnodes+pnumnodes)*1+dim*i+1] = vdbasis[1*vnumnodes+i];
+			B[(dim*vnumnodes+pnumnodes)*1+dim*i+2] = 0.;
+			B[(dim*vnumnodes+pnumnodes)*2+dim*i+0] = 0.;
+			B[(dim*vnumnodes+pnumnodes)*2+dim*i+1] = 0.;
+			B[(dim*vnumnodes+pnumnodes)*2+dim*i+2] = vdbasis[2*vnumnodes+i];
+			B[(dim*vnumnodes+pnumnodes)*3+dim*i+0] = .5*vdbasis[1*vnumnodes+i];
+			B[(dim*vnumnodes+pnumnodes)*3+dim*i+1] = .5*vdbasis[0*vnumnodes+i];
+			B[(dim*vnumnodes+pnumnodes)*3+dim*i+2] = 0.;
+			B[(dim*vnumnodes+pnumnodes)*4+dim*i+0] = .5*vdbasis[2*vnumnodes+i];
+			B[(dim*vnumnodes+pnumnodes)*4+dim*i+1] = 0.;
+			B[(dim*vnumnodes+pnumnodes)*4+dim*i+2] = .5*vdbasis[0*vnumnodes+i];
+			B[(dim*vnumnodes+pnumnodes)*5+dim*i+0] = 0.;
+			B[(dim*vnumnodes+pnumnodes)*5+dim*i+1] = .5*vdbasis[2*vnumnodes+i];
+			B[(dim*vnumnodes+pnumnodes)*5+dim*i+2] = .5*vdbasis[1*vnumnodes+i];
+			B[(dim*vnumnodes+pnumnodes)*6+dim*i+0] = 0.;
+			B[(dim*vnumnodes+pnumnodes)*6+dim*i+1] = 0.;
+			B[(dim*vnumnodes+pnumnodes)*6+dim*i+2] = 0.;
+			B[(dim*vnumnodes+pnumnodes)*7+dim*i+0] = vdbasis[0*vnumnodes+i];
+			B[(dim*vnumnodes+pnumnodes)*7+dim*i+1] = vdbasis[1*vnumnodes+i];
+			B[(dim*vnumnodes+pnumnodes)*7+dim*i+2] = vdbasis[2*vnumnodes+i];
+		}
+		for(int i=0;i<pnumnodes;i++){
+			B[(dim*vnumnodes+pnumnodes)*0+(dim*vnumnodes)+i] = 0.;
+			B[(dim*vnumnodes+pnumnodes)*1+(dim*vnumnodes)+i] = 0.;
+			B[(dim*vnumnodes+pnumnodes)*2+(dim*vnumnodes)+i] = 0.;
+			B[(dim*vnumnodes+pnumnodes)*3+(dim*vnumnodes)+i] = 0.;
+			B[(dim*vnumnodes+pnumnodes)*4+(dim*vnumnodes)+i] = 0.;
+			B[(dim*vnumnodes+pnumnodes)*5+(dim*vnumnodes)+i] = 0.;
+			B[(dim*vnumnodes+pnumnodes)*6+(dim*vnumnodes)+i] = pbasis[i];
+			B[(dim*vnumnodes+pnumnodes)*7+(dim*vnumnodes)+i] = 0.;
+		}
+	}
+
+	/*Clean up*/
+	xDelete<IssmDouble>(vdbasis);
+	xDelete<IssmDouble>(pbasis);
+}/*}}}*/
+void StressbalanceAnalysis::GetBFSprime(IssmDouble* Bprime,Element* element,int dim,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
+	/*	Compute B'  matrix. B'=[B1' B2' B3' B4' B5' B6' Bb'] where Bi' is of size 3*NDOF2. 
+	 *	For node i, Bi' can be expressed in the actual coordinate system
+	 *	by: 
+	 *			Bvi' = [  dphi/dx     0     ]
+	 *					 [     0      dphi/dy ]
+	 *					 [  dphi/dy   dphi/dx ]
+	 *					 [  dphi/dx   dphi/dy ]
+	 *					 [     0      0       ]
+	 *
+	 * by: 	  Bpi=[  0  ]
+	 *					[  0  ]
+	 *					[  0  ]
+	 *					[  0  ]
+	 *					[ phi ]
+	 *
+	 *	In 3d
+	 *     	   Bvi=[ dh/dx     0        0    ]
+	 *					[   0      dh/dy      0    ]
+	 *					[   0        0      dh/dz  ]
+	 *					[ dh/dy    dh/dx      0    ]
+	 *					[ dh/dz      0      dh/dx  ]
+	 *					[   0      dh/dz    dh/dy  ]
+	 *					[ dh/dx    dh/dy    dh/dz  ]
+	 *					[   0        0        0    ]
+	 *
+	 *         Bpi=[ 0 ]
+	 *					[ 0 ]
+	 *					[ 0 ]
+	 *					[ 0 ]
+	 *					[ 0 ]
+	 *					[ 0 ]
+	 *					[ 0 ]
+	 *					[ h ]
+	 *	where phi is the finiteelement function for node i.
+	 *	In 3d:
+	 */
+
+	/*Fetch number of nodes for this finite element*/
+	int pnumnodes = element->NumberofNodesPressure();
+	int vnumnodes = element->NumberofNodesVelocity();
+
+	/*Get nodal functions derivatives*/
+	IssmDouble* vdbasis=xNew<IssmDouble>(dim*vnumnodes);
+	IssmDouble* pbasis =xNew<IssmDouble>(pnumnodes);
+	element->NodalFunctionsDerivativesVelocity(vdbasis,xyz_list,gauss);
+	element->NodalFunctionsPressure(pbasis,gauss);
+
+	/*Build B_prime: */
+	if(dim==2){
+		for(int i=0;i<vnumnodes;i++){
+			Bprime[(dim*vnumnodes+pnumnodes)*0+dim*i+0] = vdbasis[0*vnumnodes+i];
+			Bprime[(dim*vnumnodes+pnumnodes)*0+dim*i+1] = 0.;
+			Bprime[(dim*vnumnodes+pnumnodes)*1+dim*i+0] = 0.;
+			Bprime[(dim*vnumnodes+pnumnodes)*1+dim*i+1] = vdbasis[1*vnumnodes+i];
+			Bprime[(dim*vnumnodes+pnumnodes)*2+dim*i+0] = vdbasis[1*vnumnodes+i];
+			Bprime[(dim*vnumnodes+pnumnodes)*2+dim*i+1] = vdbasis[0*vnumnodes+i];
+			Bprime[(dim*vnumnodes+pnumnodes)*3+dim*i+0] = vdbasis[0*vnumnodes+i];
+			Bprime[(dim*vnumnodes+pnumnodes)*3+dim*i+1] = vdbasis[1*vnumnodes+i];
+			Bprime[(dim*vnumnodes+pnumnodes)*4+dim*i+0] = 0.;
+			Bprime[(dim*vnumnodes+pnumnodes)*4+dim*i+1] = 0.;
+		}
+		for(int i=0;i<pnumnodes;i++){
+			Bprime[(dim*vnumnodes+pnumnodes)*0+(dim*vnumnodes)+i] = 0.;
+			Bprime[(dim*vnumnodes+pnumnodes)*1+(dim*vnumnodes)+i] = 0.;
+			Bprime[(dim*vnumnodes+pnumnodes)*2+(dim*vnumnodes)+i] = 0.;
+			Bprime[(dim*vnumnodes+pnumnodes)*3+(dim*vnumnodes)+i] = 0.;
+			Bprime[(dim*vnumnodes+pnumnodes)*4+(dim*vnumnodes)+i] = pbasis[i];
+		}
+	}
+	else{
+		for(int i=0;i<vnumnodes;i++){
+			Bprime[(dim*vnumnodes+pnumnodes)*0+dim*i+0] = vdbasis[0*vnumnodes+i];
+			Bprime[(dim*vnumnodes+pnumnodes)*0+dim*i+1] = 0.;
+			Bprime[(dim*vnumnodes+pnumnodes)*0+dim*i+2] = 0.;
+			Bprime[(dim*vnumnodes+pnumnodes)*1+dim*i+0] = 0.;
+			Bprime[(dim*vnumnodes+pnumnodes)*1+dim*i+1] = vdbasis[1*vnumnodes+i];
+			Bprime[(dim*vnumnodes+pnumnodes)*1+dim*i+2] = 0.;
+			Bprime[(dim*vnumnodes+pnumnodes)*2+dim*i+0] = 0.;
+			Bprime[(dim*vnumnodes+pnumnodes)*2+dim*i+1] = 0.;
+			Bprime[(dim*vnumnodes+pnumnodes)*2+dim*i+2] = vdbasis[2*vnumnodes+i];
+			Bprime[(dim*vnumnodes+pnumnodes)*3+dim*i+0] = vdbasis[1*vnumnodes+i];
+			Bprime[(dim*vnumnodes+pnumnodes)*3+dim*i+1] = vdbasis[0*vnumnodes+i];
+			Bprime[(dim*vnumnodes+pnumnodes)*3+dim*i+2] = 0.;
+			Bprime[(dim*vnumnodes+pnumnodes)*4+dim*i+0] = vdbasis[2*vnumnodes+i];
+			Bprime[(dim*vnumnodes+pnumnodes)*4+dim*i+1] = 0.;
+			Bprime[(dim*vnumnodes+pnumnodes)*4+dim*i+2] = vdbasis[0*vnumnodes+i];
+			Bprime[(dim*vnumnodes+pnumnodes)*5+dim*i+0] = 0.;
+			Bprime[(dim*vnumnodes+pnumnodes)*5+dim*i+1] = vdbasis[2*vnumnodes+i];
+			Bprime[(dim*vnumnodes+pnumnodes)*5+dim*i+2] = vdbasis[1*vnumnodes+i];
+			Bprime[(dim*vnumnodes+pnumnodes)*6+dim*i+0] = vdbasis[0*vnumnodes+i];
+			Bprime[(dim*vnumnodes+pnumnodes)*6+dim*i+1] = vdbasis[1*vnumnodes+i];
+			Bprime[(dim*vnumnodes+pnumnodes)*6+dim*i+2] = vdbasis[2*vnumnodes+i];
+			Bprime[(dim*vnumnodes+pnumnodes)*7+dim*i+0] = 0.;
+			Bprime[(dim*vnumnodes+pnumnodes)*7+dim*i+1] = 0.;
+			Bprime[(dim*vnumnodes+pnumnodes)*7+dim*i+2] = 0.;
+		}
+		for(int i=0;i<pnumnodes;i++){
+			Bprime[(dim*vnumnodes+pnumnodes)*0+(dim*vnumnodes)+i] = 0.;
+			Bprime[(dim*vnumnodes+pnumnodes)*1+(dim*vnumnodes)+i] = 0.;
+			Bprime[(dim*vnumnodes+pnumnodes)*2+(dim*vnumnodes)+i] = 0.;
+			Bprime[(dim*vnumnodes+pnumnodes)*3+(dim*vnumnodes)+i] = 0.;
+			Bprime[(dim*vnumnodes+pnumnodes)*4+(dim*vnumnodes)+i] = 0.;
+			Bprime[(dim*vnumnodes+pnumnodes)*5+(dim*vnumnodes)+i] = 0.;
+			Bprime[(dim*vnumnodes+pnumnodes)*6+(dim*vnumnodes)+i] = 0.;
+			Bprime[(dim*vnumnodes+pnumnodes)*7+(dim*vnumnodes)+i] = pbasis[i];
+		}
+	}
+
+	/*Clean up*/
+	xDelete<IssmDouble>(vdbasis);
+	xDelete<IssmDouble>(pbasis);
+}/*}}}*/
+void StressbalanceAnalysis::GetBFSFriction(IssmDouble* B,Element* element,int dim,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
+	/* Compute L  matrix. L=[L1 L2 L3] where Li is square and of size numdof. 
+	 * For node i, Li can be expressed in the actual coordinate system
+	 * by in 3d 
+	 *       Li=[ h 0 0 0 ]
+	 *	 	      [ 0 h 0 0 ]
+	 *	in 2d:
+	 *       Li=[ h 0 0 ]
+	 * where h is the interpolation function for node i.
+	 */
+
+	/*Fetch number of nodes for this finite element*/
+	int pnumnodes = element->NumberofNodesPressure();
+	int vnumnodes = element->NumberofNodesVelocity();
+	int pnumdof   = pnumnodes;
+	int vnumdof   = vnumnodes*dim;
+
+	/*Get nodal functions derivatives*/
+	IssmDouble* vbasis=xNew<IssmDouble>(vnumnodes);
+	element->NodalFunctionsVelocity(vbasis,gauss);
+
+	/*Build B: */
+	if(dim==3){
+		for(int i=0;i<vnumnodes;i++){
+			B[(vnumdof+pnumdof)*0+3*i+0] = vbasis[i];
+			B[(vnumdof+pnumdof)*0+3*i+1] = 0.;
+			B[(vnumdof+pnumdof)*0+3*i+2] = 0.;
+
+			B[(vnumdof+pnumdof)*1+3*i+0] = 0.;
+			B[(vnumdof+pnumdof)*1+3*i+1] = vbasis[i];
+			B[(vnumdof+pnumdof)*1+3*i+2] = 0.;
+		}
+		for(int i=0;i<pnumnodes;i++){
+			B[(vnumdof+pnumdof)*0+i+vnumdof+0] = 0.;
+			B[(vnumdof+pnumdof)*1+i+vnumdof+0] = 0.;
+		}
+	}
+	else{
+		for(int i=0;i<vnumnodes;i++){
+			B[2*i+0] = vbasis[i];
+			B[2*i+1] = 0.;
+		}
+
+		for(int i=0;i<pnumnodes;i++){
+			B[i+vnumdof+0] = 0.;
+		}
+	}
+
+	/*Clean-up*/
+	xDelete<IssmDouble>(vbasis);
+}/*}}}*/
+void StressbalanceAnalysis::GetSolutionFromInputsFS(Vector<IssmDouble>* solution,Element* element){/*{{{*/
+
+	int*         vdoflist=NULL;
+	int*         pdoflist=NULL;
+	Input*       vz_input=NULL;
+	int          dim;
+	IssmDouble   vx,vy,vz,p;
+	IssmDouble   FSreconditioning;
+
+	/*Get some parameters*/
+	element->FindParam(&dim,DomainDimensionEnum);
+	element->FindParam(&FSreconditioning,StressbalanceFSreconditioningEnum);
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int vnumnodes = element->NumberofNodesVelocity();
+	int pnumnodes = element->NumberofNodesPressure();
+	int vnumdof   = vnumnodes*dim;
+	int pnumdof   = pnumnodes*1;
+
+	/*Initialize values*/
+	IssmDouble* vvalues = xNew<IssmDouble>(vnumdof);
+	IssmDouble* pvalues = xNew<IssmDouble>(pnumdof);
+
+	/*Get dof list: */
+	element->GetDofListVelocity(&vdoflist,GsetEnum);
+	element->GetDofListPressure(&pdoflist,GsetEnum);
+	Input*     vx_input=element->GetInput(VxEnum);       _assert_(vx_input);
+	Input*     vy_input=element->GetInput(VyEnum);       _assert_(vy_input);
+	if(dim==3){vz_input=element->GetInput(VzEnum);       _assert_(vz_input);}
+	Input*     p_input =element->GetInput(PressureEnum); _assert_(p_input);
+
+	element->FindParam(&FSreconditioning,StressbalanceFSreconditioningEnum);
+
+	/*Ok, we have the velocities in inputs, fill in solution */
+	Gauss* gauss = element->NewGauss();
+	for(int i=0;i<vnumnodes;i++){
+		gauss->GaussNode(element->VelocityInterpolation(),i);
+		vx_input->GetInputValue(&vx,gauss);
+		vy_input->GetInputValue(&vy,gauss);
+		vvalues[i*dim+0]=vx;
+		vvalues[i*dim+1]=vy;
+		if(dim==3){
+			vz_input->GetInputValue(&vz,gauss);
+			vvalues[i*dim+2]=vz;
+		}
+	}
+	for(int i=0;i<pnumnodes;i++){
+		gauss->GaussNode(element->PressureInterpolation(),i);
+		p_input->GetInputValue(&p ,gauss);
+		pvalues[i]=p/FSreconditioning;
+	}
+
+	/*Add value to global vector*/
+	solution->SetValues(vnumdof,vdoflist,vvalues,INS_VAL);
+	solution->SetValues(pnumdof,pdoflist,pvalues,INS_VAL);
+
+	/*Free ressources:*/
+	delete gauss;
+	xDelete<int>(pdoflist);
+	xDelete<int>(vdoflist);
+	xDelete<IssmDouble>(pvalues);
+	xDelete<IssmDouble>(vvalues);
+}/*}}}*/
+void StressbalanceAnalysis::InitializeXTH(Elements* elements,Parameters* parameters){/*{{{*/
+
+	/*Intermediaries*/
+	int        dim;
+	IssmDouble dvx[3],dvy[3],dvz[3];
+	IssmDouble viscosity;
+	IssmDouble *xyz_list = NULL;
+
+	/*Get problem dimension*/
+	parameters->FindParam(&dim,DomainDimensionEnum);
+
+	for(int i=0;i<elements->Size();i++){
+		Element* element=dynamic_cast<Element*>(elements->GetObjectByOffset(i));
+
+		/*Get inputs and parameters*/
+		element->GetVerticesCoordinates(&xyz_list);
+		Input* vx_input=element->GetInput(VxEnum); _assert_(vx_input);
+		Input* vy_input=element->GetInput(VyEnum); _assert_(vy_input);
+		Input* vz_input;
+		if(dim==3){vz_input=element->GetInput(VzEnum); _assert_(vz_input);}
+
+		/*Allocate new inputs*/
+		int tnumnodes = element->GetNumberOfVertices();      //Tensors, P1 DG
+		IssmDouble* epsxx = xNew<IssmDouble>(tnumnodes); IssmDouble* sigmapxx = xNew<IssmDouble>(tnumnodes);
+		IssmDouble* epsyy = xNew<IssmDouble>(tnumnodes); IssmDouble* sigmapyy = xNew<IssmDouble>(tnumnodes); 
+		IssmDouble* epsxy = xNew<IssmDouble>(tnumnodes); IssmDouble* sigmapxy = xNew<IssmDouble>(tnumnodes); 
+		IssmDouble* epszz = NULL;                        IssmDouble* sigmapzz = NULL;  
+		IssmDouble* epsxz = NULL;                        IssmDouble* sigmapxz = NULL;  
+		IssmDouble* epsyz = NULL;                        IssmDouble* sigmapyz = NULL;  
+		if(dim==3){
+			epszz = xNew<IssmDouble>(tnumnodes); sigmapzz = xNew<IssmDouble>(tnumnodes);
+			epsxz = xNew<IssmDouble>(tnumnodes); sigmapxz = xNew<IssmDouble>(tnumnodes); 
+			epsyz = xNew<IssmDouble>(tnumnodes); sigmapyz = xNew<IssmDouble>(tnumnodes); 
+		}
+
+		/*Get d and tau*/
+		Gauss* gauss = element->NewGauss();
+		for(int i=0;i<tnumnodes;i++){
+			gauss->GaussNode(P1DGEnum,i);
+
+			vx_input->GetInputDerivativeValue(&dvx[0],xyz_list,gauss);
+			vy_input->GetInputDerivativeValue(&dvy[0],xyz_list,gauss);
+			if(dim==3){
+				vz_input->GetInputDerivativeValue(&dvz[0],xyz_list,gauss);
+			}
+
+			element->ViscosityFS(&viscosity,dim,xyz_list,gauss,vx_input,vy_input,vz_input);
+			epsxx[i] = dvx[0];                sigmapxx[i] = 2.*viscosity*epsxx[i];
+			epsyy[i] = dvy[1];                sigmapyy[i] = 2.*viscosity*epsyy[i];
+			epsxy[i] = 0.5*(dvx[1] + dvy[0]); sigmapxy[i] = 2.*viscosity*epsxy[i];
+			if(dim==3){
+				epszz[i] = dvz[2];                sigmapzz[i] = 2.*viscosity*epszz[i];
+				epsxz[i] = 0.5*(dvx[2] + dvz[0]); sigmapxz[i] = 2.*viscosity*epsxz[i];
+				epsyz[i] = 0.5*(dvy[2] + dvz[1]); sigmapyz[i] = 2.*viscosity*epsyz[i];
+			}
+		}
+
+		/*Add inputs*/
+		element->AddInput(StrainRatexxEnum,epsxx,P1DGEnum); element->AddInput(DeviatoricStressxxEnum,sigmapxx,P1DGEnum);
+		element->AddInput(StrainRateyyEnum,epsyy,P1DGEnum); element->AddInput(DeviatoricStressyyEnum,sigmapyy,P1DGEnum);
+		element->AddInput(StrainRatexyEnum,epsxy,P1DGEnum); element->AddInput(DeviatoricStressxyEnum,sigmapxy,P1DGEnum);
+		if(dim==3){
+			element->AddInput(StrainRatezzEnum,epszz,P1DGEnum); element->AddInput(DeviatoricStresszzEnum,sigmapzz,P1DGEnum);
+			element->AddInput(StrainRatexzEnum,epsxz,P1DGEnum); element->AddInput(DeviatoricStressxzEnum,sigmapxz,P1DGEnum);
+			element->AddInput(StrainRateyzEnum,epsyz,P1DGEnum); element->AddInput(DeviatoricStressyzEnum,sigmapyz,P1DGEnum);
+		}
+
+		/*Clean up*/
+		delete gauss;
+		xDelete<IssmDouble>(xyz_list);
+		xDelete<IssmDouble>(epsxx); xDelete<IssmDouble>(sigmapxx);
+		xDelete<IssmDouble>(epsyy); xDelete<IssmDouble>(sigmapyy);
+		xDelete<IssmDouble>(epszz); xDelete<IssmDouble>(sigmapzz);
+		xDelete<IssmDouble>(epsxy); xDelete<IssmDouble>(sigmapxy);
+		xDelete<IssmDouble>(epsxz); xDelete<IssmDouble>(sigmapxz);
+		xDelete<IssmDouble>(epsyz); xDelete<IssmDouble>(sigmapyz);
+	}
+
+}/*}}}*/
+void StressbalanceAnalysis::InputUpdateFromSolutionFS(IssmDouble* solution,Element* element){/*{{{*/
+
+	bool         results_on_nodes;
+	int          i,dim;
+	int*         vdoflist=NULL;
+	int*         pdoflist=NULL;
+	IssmDouble   FSreconditioning;
+
+	element->FindParam(&dim,DomainDimensionEnum);
+	element->FindParam(&FSreconditioning,StressbalanceFSreconditioningEnum);
+	element->FindParam(&results_on_nodes,SettingsResultsOnNodesEnum);
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int vnumnodes = element->NumberofNodesVelocity();
+	int pnumnodes = element->NumberofNodesPressure();
+	int vnumdof   = vnumnodes*dim;
+	int pnumdof   = pnumnodes*1;
+
+	/*Initialize values*/
+	IssmDouble* values   = xNew<IssmDouble>(vnumdof+pnumdof);
+	IssmDouble* vx       = xNew<IssmDouble>(vnumnodes);
+	IssmDouble* vy       = xNew<IssmDouble>(vnumnodes);
+	IssmDouble* vz       = xNew<IssmDouble>(vnumnodes);
+	IssmDouble* vel      = xNew<IssmDouble>(vnumnodes);
+	IssmDouble* pressure = xNew<IssmDouble>(pnumnodes);
+
+	/*Prepare coordinate system list*/
+	int* cs_list = xNew<int>(vnumnodes+pnumnodes);
+	if(dim==2) for(i=0;i<vnumnodes;i++) cs_list[i] = XYEnum;
+	else       for(i=0;i<vnumnodes;i++) cs_list[i] = XYZEnum;
+	for(i=0;i<pnumnodes;i++) cs_list[vnumnodes+i] = PressureEnum;
+
+	/*Get dof list: */
+	element->GetDofListVelocity(&vdoflist,GsetEnum);
+	element->GetDofListPressure(&pdoflist,GsetEnum);
+
+	/*Use the dof list to index into the solution vector: */
+	for(i=0;i<vnumdof;i++) values[i]        =solution[vdoflist[i]];
+	for(i=0;i<pnumdof;i++) values[vnumdof+i]=solution[pdoflist[i]];
+
+	/*Transform solution in Cartesian Space*/
+	element->TransformSolutionCoord(values,cs_list);
+
+	/*Ok, we have vx and vy in values, fill in all arrays: */
+	for(i=0;i<vnumnodes;i++){
+		vx[i] = values[i*dim+0];
+		vy[i] = values[i*dim+1];
+		if(xIsNan<IssmDouble>(vx[i])) _error_("NaN found in solution vector");
+		if(xIsNan<IssmDouble>(vy[i])) _error_("NaN found in solution vector");
+
+		if(dim==3){
+			vz[i] = values[i*dim+2];
+			if(xIsNan<IssmDouble>(vz[i])) _error_("NaN found in solution vector");
+		}
+	}
+	for(i=0;i<pnumnodes;i++){
+		pressure[i] = values[vnumdof+i];
+		if(xIsNan<IssmDouble>(pressure[i])) _error_("NaN found in solution vector");
+	}
+
+	/*Recondition pressure and compute vel: */
+	for(i=0;i<pnumnodes;i++) pressure[i] = pressure[i]*FSreconditioning;
+	if(dim==3) for(i=0;i<vnumnodes;i++) vel[i] = sqrt(vx[i]*vx[i] + vy[i]*vy[i] + vz[i]*vz[i]);
+	else       for(i=0;i<vnumnodes;i++) vel[i] = sqrt(vx[i]*vx[i] + vy[i]*vy[i]);
+
+	/*Now, we have to move the previous inputs  to old 
+	 * status, otherwise, we'll wipe them off: */
+	element->InputChangeName(VxEnum,VxPicardEnum);
+	element->InputChangeName(VyEnum,VyPicardEnum);
+	element->InputChangeName(PressureEnum,PressurePicardEnum);
+	if(dim==3) element->InputChangeName(VzEnum,VzPicardEnum);
+
+	/*Add vx and vy as inputs to the tria element: */
+	element->AddInput(VxEnum,      vx,      element->VelocityInterpolation());
+	element->AddInput(VyEnum,      vy,      element->VelocityInterpolation());
+	element->AddInput(VelEnum,     vel,     element->VelocityInterpolation());
+	element->AddInput(PressureEnum,pressure,element->PressureInterpolation());
+	if(dim==3) element->AddInput(VzEnum,vz, element->VelocityInterpolation());
+
+	/*Free ressources:*/
+	xDelete<IssmDouble>(pressure);
+	xDelete<IssmDouble>(vel);
+	xDelete<IssmDouble>(vz);
+	xDelete<IssmDouble>(vy);
+	xDelete<IssmDouble>(vx);
+	xDelete<IssmDouble>(values);
+	xDelete<int>(vdoflist);
+	xDelete<int>(pdoflist);
+	xDelete<int>(cs_list);
+}/*}}}*/
+void StressbalanceAnalysis::InputUpdateFromSolutionFSXTH_d(Elements* elements,Parameters* parameters){/*{{{*/
+
+	/*Intermediaries*/
+	int         dim,tausize;
+	IssmDouble  epsxx,epsyy,epszz,epsxy,epsxz,epsyz,D_scalar;
+	IssmDouble  epsxx_old,epsyy_old,epszz_old,epsxy_old,epsxz_old,epsyz_old;
+	IssmDouble  sigmapxx,sigmapyy,sigmapzz,sigmapxy,sigmapxz,sigmapyz;
+	IssmDouble  dvx[3],dvy[3],dvz[3],B,n;
+	IssmDouble *xyz_list = NULL;
+	IssmDouble  Jdet,r;
+
+	parameters->FindParam(&r,AugmentedLagrangianREnum);
+	parameters->FindParam(&dim,DomainDimensionEnum);
+	if(dim==2) tausize = 3;
+	else       tausize = 6;
+
+	for(int i=0;i<elements->Size();i++){
+		Element* element=dynamic_cast<Element*>(elements->GetObjectByOffset(i));
+
+		/*Get inputs and parameters*/
+		element->GetVerticesCoordinates(&xyz_list);
+		Input*  B_input=element->GetInput(MaterialsRheologyBEnum); _assert_(B_input);
+		Input*  n_input=element->GetInput(MaterialsRheologyNEnum); _assert_(n_input);
+		Input* vx_input=element->GetInput(VxEnum);                 _assert_(vx_input);
+		Input* vy_input=element->GetInput(VyEnum);                 _assert_(vy_input);
+		Input* vz_input;
+		if(dim==3){vz_input=element->GetInput(VzEnum); _assert_(vz_input);}
+
+		/*Fetch number of nodes and dof for this finite element*/
+		int tnumnodes = element->GetNumberOfVertices();      //Tensors, P1 DG
+
+		/*Initialize vectors*/
+		IssmDouble* tbasis = xNew<IssmDouble>(tnumnodes);
+		IssmDouble* Ke     = xNewZeroInit<IssmDouble>(tnumnodes*tnumnodes);
+		IssmDouble* pe_xx  = xNewZeroInit<IssmDouble>(tnumnodes);
+		IssmDouble* pe_yy  = xNewZeroInit<IssmDouble>(tnumnodes);
+		IssmDouble* pe_xy  = xNewZeroInit<IssmDouble>(tnumnodes);
+		IssmDouble* pe_zz  = NULL; IssmDouble* pe_xz  = NULL; IssmDouble* pe_yz  = NULL;
+		if(dim==3){
+			pe_zz = xNewZeroInit<IssmDouble>(tnumnodes);
+			pe_xz = xNewZeroInit<IssmDouble>(tnumnodes);
+			pe_yz = xNewZeroInit<IssmDouble>(tnumnodes);
+		}
+
+		/*Get previous d*/
+		Input* epsxx_input=element->GetInput(StrainRatexxEnum); _assert_(epsxx_input);
+		Input* epsyy_input=element->GetInput(StrainRateyyEnum); _assert_(epsyy_input);
+		Input* epsxy_input=element->GetInput(StrainRatexyEnum); _assert_(epsxy_input);
+		Input* epszz_input=NULL; Input* epsxz_input=NULL; Input* epsyz_input=NULL;
+		if(dim==3){
+			epszz_input=element->GetInput(StrainRatezzEnum); _assert_(epszz_input);
+			epsxz_input=element->GetInput(StrainRatexzEnum); _assert_(epsxz_input);
+			epsyz_input=element->GetInput(StrainRateyzEnum); _assert_(epsyz_input);
+		}
+
+		/*Get tau*/
+		Input* sigmapxx_input=element->GetInput(DeviatoricStressxxEnum); _assert_(sigmapxx_input);
+		Input* sigmapyy_input=element->GetInput(DeviatoricStressyyEnum); _assert_(sigmapyy_input);
+		Input* sigmapxy_input=element->GetInput(DeviatoricStressxyEnum); _assert_(sigmapxy_input);
+		Input* sigmapzz_input=NULL; Input* sigmapxz_input=NULL; Input* sigmapyz_input=NULL;
+		if(dim==3){
+			sigmapzz_input=element->GetInput(DeviatoricStresszzEnum); _assert_(sigmapzz_input);
+			sigmapxz_input=element->GetInput(DeviatoricStressxzEnum); _assert_(sigmapxz_input);
+			sigmapyz_input=element->GetInput(DeviatoricStressyzEnum); _assert_(sigmapyz_input);
+		}
+
+		Gauss* gauss=element->NewGauss(5);
+		for(int ig=gauss->begin();ig<gauss->end();ig++){
+			gauss->GaussPoint(ig);
+			element->JacobianDeterminant(&Jdet,xyz_list,gauss);
+			element->NodalFunctionsTensor(tbasis,gauss);
+
+			/*Get tau from inputs*/
+			sigmapxx_input->GetInputValue(&sigmapxx,gauss);
+			sigmapyy_input->GetInputValue(&sigmapyy,gauss);
+			sigmapxy_input->GetInputValue(&sigmapxy,gauss);
+			if(dim==3){
+				sigmapzz_input->GetInputValue(&sigmapzz,gauss);
+				sigmapxz_input->GetInputValue(&sigmapxz,gauss);
+				sigmapyz_input->GetInputValue(&sigmapyz,gauss);
+			}
+
+			/*Get previous d*/
+			epsxx_input->GetInputValue(&epsxx_old,gauss);
+			epsyy_input->GetInputValue(&epsyy_old,gauss);
+			epsxy_input->GetInputValue(&epsxy_old,gauss);
+			if(dim==3){
+				epszz_input->GetInputValue(&epszz_old,gauss);
+				epsxz_input->GetInputValue(&epsxz_old,gauss);
+				epsyz_input->GetInputValue(&epsyz_old,gauss);
+			}
+
+			/*Calculate d from previous results*/
+			vx_input->GetInputDerivativeValue(&dvx[0],xyz_list,gauss);
+			vy_input->GetInputDerivativeValue(&dvy[0],xyz_list,gauss);
+			if(dim==3){
+				vz_input->GetInputDerivativeValue(&dvz[0],xyz_list,gauss);
+			}
+			epsxx = dvx[0];
+			epsyy = dvy[1];
+			epsxy = 0.5*(dvx[1] + dvy[0]); 
+			if(dim==3){
+				epszz = dvz[2];               
+				epsxz = 0.5*(dvx[2] + dvz[0]);
+				epsyz = 0.5*(dvy[2] + dvz[1]);
+			}
+
+			/*Solve 2 eta_0 |d|^s-1 + r |d| = |rD(u) + tau|*/
+			IssmDouble coef1,coef2,coef3;
+			B_input->GetInputValue(&B,gauss);
+			n_input->GetInputValue(&n,gauss);
+			coef1 = B*pow(1./sqrt(2.),(1.-n)/n); //2 eta_0 = 2 * B/(2* (1/sqrt(2)  )^(n-1)/n ) 
+			coef2 = r;
+			if(dim==2){
+				coef3 = sqrt(
+							  (r*epsxx + sigmapxx)*(r*epsxx + sigmapxx)
+							+ (r*epsyy + sigmapyy)*(r*epsyy + sigmapyy)
+							+ 2*(r*epsxy + sigmapxy)*(r*epsxy + sigmapxy)
+							);
+			}
+			else{
+				coef3 = sqrt(
+					  		  (r*epsxx + sigmapxx)*(r*epsxx + sigmapxx)
+							+ (r*epsyy + sigmapyy)*(r*epsyy + sigmapyy)
+							+ (r*epszz + sigmapzz)*(r*epszz + sigmapzz)
+							+ 2*(r*epsxy + sigmapxy)*(r*epsxy + sigmapxy)
+							+ 2*(r*epsxz + sigmapxz)*(r*epsxz + sigmapxz)
+							+ 2*(r*epsyz + sigmapyz)*(r*epsyz + sigmapyz)
+							);
+			}
+			IssmDouble dnorm;
+			if(dim==2){
+				dnorm = sqrt( epsxx_old*epsxx_old + epsyy_old*epsyy_old + 2.*epsxy_old*epsxy_old );
+			}
+			else{
+				dnorm = sqrt( epsxx_old*epsxx_old + epsyy_old*epsyy_old + epszz_old*epszz_old 
+							+2.*(epsxy_old*epsxy_old + epsxz_old*epsxz_old + epsyz_old*epsyz_old));
+			}
+			/*Initial guess cannot be 0 otherwise log(0)  - inf*/
+			if(dnorm==0.) dnorm=1.;
+			NewtonSolveDnorm(&dnorm,coef1,coef2,coef3,n,dnorm);
+			_assert_(dnorm>=0.);
+			_assert_(!xIsNan<IssmDouble>(dnorm));
+
+			/*Create Ke*/
+			D_scalar=(coef1*pow(dnorm,(1.-n)/n)+r)*gauss->weight*Jdet;
+			TripleMultiply(tbasis,tnumnodes,1,0,
+						&D_scalar,1,1,0,
+						tbasis,1,tnumnodes,0,
+						Ke,1);
+
+			/*Create Right hand sides*/
+			for(int ii=0;ii<tnumnodes;ii++) pe_xx[ii] += (r*epsxx+sigmapxx)*tbasis[ii]*gauss->weight*Jdet;
+			for(int ii=0;ii<tnumnodes;ii++) pe_yy[ii] += (r*epsyy+sigmapyy)*tbasis[ii]*gauss->weight*Jdet;
+			for(int ii=0;ii<tnumnodes;ii++) pe_xy[ii] += (r*epsxy+sigmapxy)*tbasis[ii]*gauss->weight*Jdet;
+			if(dim==3){
+				for(int ii=0;ii<tnumnodes;ii++) pe_zz[ii] += (r*epszz+sigmapzz)*tbasis[ii]*gauss->weight*Jdet;
+				for(int ii=0;ii<tnumnodes;ii++) pe_xz[ii] += (r*epsxz+sigmapxz)*tbasis[ii]*gauss->weight*Jdet;
+				for(int ii=0;ii<tnumnodes;ii++) pe_yz[ii] += (r*epsyz+sigmapyz)*tbasis[ii]*gauss->weight*Jdet;
+			}
+		}
+
+		/*Solve the systems*/
+		IssmDouble* d_xx = xNew<IssmDouble>(tnumnodes);
+		IssmDouble* d_yy = xNew<IssmDouble>(tnumnodes);
+		IssmDouble* d_xy = xNew<IssmDouble>(tnumnodes);
+		IssmDouble* d_zz = NULL;
+		IssmDouble* d_xz = NULL;
+		IssmDouble* d_yz = NULL;
+		if(dim==2){
+			_assert_(tnumnodes==3);
+			Matrix3x3Solve(&d_xx[0],Ke,pe_xx);
+			Matrix3x3Solve(&d_yy[0],Ke,pe_yy);
+			Matrix3x3Solve(&d_xy[0],Ke,pe_xy);
+			for(int i=0;i<3;i++) _assert_(!xIsNan<IssmDouble>(d_xx[i]));
+			for(int i=0;i<3;i++) _assert_(!xIsNan<IssmDouble>(d_yy[i]));
+			for(int i=0;i<3;i++) _assert_(!xIsNan<IssmDouble>(d_xx[i]));
+			element->AddInput(StrainRatexxEnum,d_xx,P1DGEnum);
+			element->AddInput(StrainRateyyEnum,d_yy,P1DGEnum);
+			element->AddInput(StrainRatexyEnum,d_xy,P1DGEnum);
+		}
+		else{
+			_assert_(tnumnodes==4);
+			Matrix4x4Solve(&d_xx[0],Ke,pe_xx);
+			Matrix4x4Solve(&d_yy[0],Ke,pe_yy);
+			Matrix4x4Solve(&d_xy[0],Ke,pe_xy);
+			Matrix4x4Solve(&d_zz[0],Ke,pe_zz);
+			Matrix4x4Solve(&d_xz[0],Ke,pe_xz);
+			Matrix4x4Solve(&d_yz[0],Ke,pe_yz);
+			element->AddInput(StrainRatexxEnum,d_xx,P1DGEnum);
+			element->AddInput(StrainRateyyEnum,d_yy,P1DGEnum);
+			element->AddInput(StrainRatexyEnum,d_xy,P1DGEnum);
+			element->AddInput(StrainRatezzEnum,d_zz,P1DGEnum);
+			element->AddInput(StrainRatexzEnum,d_xz,P1DGEnum);
+			element->AddInput(StrainRateyzEnum,d_yz,P1DGEnum);
+		}
+
+		/*Clean up*/
+		delete gauss;
+		xDelete<IssmDouble>(xyz_list);
+		xDelete<IssmDouble>(tbasis);
+		xDelete<IssmDouble>(Ke);
+		xDelete<IssmDouble>(pe_xx); xDelete<IssmDouble>(d_xx);
+		xDelete<IssmDouble>(pe_yy); xDelete<IssmDouble>(d_yy);
+		xDelete<IssmDouble>(pe_zz); xDelete<IssmDouble>(d_zz);
+		xDelete<IssmDouble>(pe_xy); xDelete<IssmDouble>(d_xy);
+		xDelete<IssmDouble>(pe_xz); xDelete<IssmDouble>(d_xz);
+		xDelete<IssmDouble>(pe_yz); xDelete<IssmDouble>(d_yz);
+	}
+}/*}}}*/
+void StressbalanceAnalysis::InputUpdateFromSolutionFSXTH_tau(Elements* elements,Parameters* parameters){/*{{{*/
+
+	/*Intermediaries*/
+	int         dim,tausize;
+	IssmDouble  epsxx,epsyy,epszz,epsxy,epsxz,epsyz,D_scalar;
+	IssmDouble  d_xx,d_yy,d_zz,d_xy,d_xz,d_yz;
+	IssmDouble  sigmapxx,sigmapyy,sigmapzz,sigmapxy,sigmapxz,sigmapyz;
+	IssmDouble  dvx[3],dvy[3],dvz[3];
+	IssmDouble *xyz_list = NULL;
+	IssmDouble  Jdet,r;
+
+	parameters->FindParam(&r,AugmentedLagrangianREnum);
+	parameters->FindParam(&dim,DomainDimensionEnum);
+	if(dim==2) tausize = 3;
+	else       tausize = 6;
+
+	for(int i=0;i<elements->Size();i++){
+		Element* element=dynamic_cast<Element*>(elements->GetObjectByOffset(i));
+
+		/*Get inputs and parameters*/
+		element->GetVerticesCoordinates(&xyz_list);
+		Input* vx_input=element->GetInput(VxEnum);                 _assert_(vx_input);
+		Input* vy_input=element->GetInput(VyEnum);                 _assert_(vy_input);
+		Input* vz_input;
+		if(dim==3){vz_input=element->GetInput(VzEnum); _assert_(vz_input);}
+
+		/*Get previous tau*/
+		Input* sigmapxx_input=element->GetInput(DeviatoricStressxxEnum); _assert_(sigmapxx_input);
+		Input* sigmapyy_input=element->GetInput(DeviatoricStressyyEnum); _assert_(sigmapyy_input);
+		Input* sigmapxy_input=element->GetInput(DeviatoricStressxyEnum); _assert_(sigmapxy_input);
+		Input* sigmapzz_input=NULL; Input* sigmapxz_input=NULL; Input* sigmapyz_input=NULL;
+		if(dim==3){
+			sigmapzz_input=element->GetInput(DeviatoricStresszzEnum); _assert_(sigmapzz_input);
+			sigmapxz_input=element->GetInput(DeviatoricStressxzEnum); _assert_(sigmapxz_input);
+			sigmapyz_input=element->GetInput(DeviatoricStressyzEnum); _assert_(sigmapyz_input);
+		}
+
+		/*Get NEW d*/
+		Input* epsxx_input=element->GetInput(StrainRatexxEnum); _assert_(epsxx_input);
+		Input* epsyy_input=element->GetInput(StrainRateyyEnum); _assert_(epsyy_input);
+		Input* epsxy_input=element->GetInput(StrainRatexyEnum); _assert_(epsxy_input);
+		Input* epszz_input=NULL; Input* epsxz_input=NULL; Input* epsyz_input=NULL;
+		if(dim==3){
+			epszz_input=element->GetInput(StrainRatezzEnum); _assert_(epszz_input);
+			epsxz_input=element->GetInput(StrainRatexzEnum); _assert_(epsxz_input);
+			epsyz_input=element->GetInput(StrainRateyzEnum); _assert_(epsyz_input);
+		}
+
+		/*Fetch number of nodes and dof for this finite element*/
+		int tnumnodes = element->GetNumberOfVertices();      //Tensors, P1 DG
+
+		/*Update tau accordingly*/
+		IssmDouble* tau_xx = xNew<IssmDouble>(tnumnodes);
+		IssmDouble* tau_yy = xNew<IssmDouble>(tnumnodes);
+		IssmDouble* tau_xy = xNew<IssmDouble>(tnumnodes);
+		IssmDouble* tau_zz = NULL;
+		IssmDouble* tau_xz = NULL;
+		IssmDouble* tau_yz = NULL;
+		Gauss* gauss = element->NewGauss();
+		for(int ig=0;ig<tnumnodes;ig++){
+			gauss->GaussNode(P1DGEnum,ig);
+
+			/*Get D(u)*/
+			vx_input->GetInputDerivativeValue(&dvx[0],xyz_list,gauss);
+			vy_input->GetInputDerivativeValue(&dvy[0],xyz_list,gauss);
+			if(dim==3){
+				vz_input->GetInputDerivativeValue(&dvz[0],xyz_list,gauss);
+			}
+			epsxx = dvx[0];
+			epsyy = dvy[1];
+			epsxy = 0.5*(dvx[1] + dvy[0]); 
+			if(dim==3){
+				epszz = dvz[2]; 
+				epsxz = 0.5*(dvx[2] + dvz[0]);
+				epsyz = 0.5*(dvy[2] + dvz[1]);
+			}
+
+			/*Get tau^(n-1) from inputs*/
+			sigmapxx_input->GetInputValue(&sigmapxx,gauss);
+			sigmapyy_input->GetInputValue(&sigmapyy,gauss);
+			sigmapxy_input->GetInputValue(&sigmapxy,gauss);
+			if(dim==3){
+				sigmapzz_input->GetInputValue(&sigmapzz,gauss);
+				sigmapxz_input->GetInputValue(&sigmapxz,gauss);
+				sigmapyz_input->GetInputValue(&sigmapyz,gauss);
+			}
+
+			/*Get new d*/
+			epsxx_input->GetInputValue(&d_xx,gauss);
+			epsyy_input->GetInputValue(&d_yy,gauss);
+			epsxy_input->GetInputValue(&d_xy,gauss);
+			if(dim==3){
+				epszz_input->GetInputValue(&d_zz,gauss);
+				epsxz_input->GetInputValue(&d_xz,gauss);
+				epsyz_input->GetInputValue(&d_yz,gauss);
+			}
+
+			/*Get d and update tau accordingly*/
+			tau_xx[ig] = sigmapxx + r*(epsxx - d_xx);
+			tau_yy[ig] = sigmapyy + r*(epsyy - d_yy);
+			tau_xy[ig] = sigmapxy + r*(epsxy - d_xy);
+			if(dim==3){
+				tau_zz[ig] = sigmapzz + r*(epszz - d_zz);
+				tau_xz[ig] = sigmapxz + r*(epsxz - d_xz);
+				tau_yz[ig] = sigmapyz + r*(epsyz - d_yz);
+			}
+		}
+
+		/*Add inputs*/
+		element->AddInput(DeviatoricStressxxEnum,tau_xx,P1DGEnum);
+		element->AddInput(DeviatoricStressyyEnum,tau_yy,P1DGEnum);
+		element->AddInput(DeviatoricStressxyEnum,tau_xy,P1DGEnum);
+		if(dim==3){
+			element->AddInput(DeviatoricStresszzEnum,tau_zz,P1DGEnum);
+			element->AddInput(DeviatoricStressxzEnum,tau_xz,P1DGEnum);
+			element->AddInput(DeviatoricStressyzEnum,tau_yz,P1DGEnum);
+		}
+
+		/*Clean up and */
+		delete gauss;
+		xDelete<IssmDouble>(xyz_list);
+		xDelete<IssmDouble>(tau_xx);
+		xDelete<IssmDouble>(tau_yy);
+		xDelete<IssmDouble>(tau_zz);
+		xDelete<IssmDouble>(tau_xy);
+		xDelete<IssmDouble>(tau_xz);
+		xDelete<IssmDouble>(tau_yz);
+	}
+}/*}}}*/
+
+/*Coupling (Tiling)*/
+ElementMatrix* StressbalanceAnalysis::CreateKMatrixSSA3d(Element* element){/*{{{*/
+
+	/*compute all stiffness matrices for this element*/
+	ElementMatrix* Ke1=CreateKMatrixSSA3dViscous(element);
+	ElementMatrix* Ke2=CreateKMatrixSSA3dFriction(element);
+	ElementMatrix* Ke =new ElementMatrix(Ke1,Ke2);
+
+	/*clean-up and return*/
+	delete Ke1;
+	delete Ke2;
+	return Ke;
+}/*}}}*/
+ElementMatrix* StressbalanceAnalysis::CreateKMatrixSSA3dFriction(Element* element){/*{{{*/
+
+	/*Initialize Element matrix and return if necessary*/
+	if(element->IsFloating() || !element->IsOnBase()) return NULL;
+
+	/*Build a tria element using the 3 nodes of the base of the penta. Then use 
+	 * the tria functionality to build a friction stiffness matrix on these 3
+	 * nodes: */
+	Element* basalelement = element->SpawnBasalElement();
+	ElementMatrix* Ke=CreateKMatrixSSAFriction(basalelement);
+	basalelement->DeleteMaterials(); delete basalelement;
+
+	/*clean-up and return*/
+	return Ke;
+}/*}}}*/
+ElementMatrix* StressbalanceAnalysis::CreateKMatrixSSA3dViscous(Element* element){/*{{{*/
+
+	/*Constants*/
+	const int    numdof2d=2*3;
+
+	/*Intermediaries */
+	int         i,j,approximation;
+	int         dim=3;
+	IssmDouble  Jdet,viscosity,oldviscosity,newviscosity,viscosity_overshoot;
+	IssmDouble  epsilon[5],oldepsilon[5];       /* epsilon=[exx,eyy,exy,exz,eyz];*/
+	IssmDouble  epsilons[6];                    //6 for FS
+	IssmDouble  B[3][numdof2d];
+	IssmDouble  Bprime[3][numdof2d];
+	IssmDouble  D[3][3]= {0.0};                 // material matrix, simple scalar matrix.
+	IssmDouble  D_scalar;
+	IssmDouble  Ke_gg[numdof2d][numdof2d]={0.0};
+	IssmDouble  *xyz_list  = NULL;
+
+	/*Find penta on bed as this is a SSA elements: */
+	Element* pentabase=element->GetBasalElement();
+	Element* basaltria=pentabase->SpawnBasalElement();
+
+	/*Initialize Element matrix*/
+	ElementMatrix* Ke=basaltria->NewElementMatrix(SSAApproximationEnum);
+	element->GetInputValue(&approximation,ApproximationEnum);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+	element->FindParam(&viscosity_overshoot,StressbalanceViscosityOvershootEnum);
+	Input* vx_input   =element->GetInput(VxEnum);       _assert_(vx_input);
+	Input* vy_input   =element->GetInput(VyEnum);       _assert_(vy_input);
+	Input* vxold_input=element->GetInput(VxPicardEnum); _assert_(vxold_input);
+	Input* vyold_input=element->GetInput(VyPicardEnum); _assert_(vyold_input);
+	Input* vz_input   =element->GetInput(VzEnum);       _assert_(vz_input);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGauss(5);
+	Gauss* gauss_tria=new GaussTria();
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+
+		gauss->GaussPoint(ig);
+		gauss->SynchronizeGaussBase(gauss_tria);
+
+		element->JacobianDeterminant(&Jdet, xyz_list,gauss);
+		this->GetBSSA(&B[0][0],basaltria,2,xyz_list, gauss_tria);
+		this->GetBSSAprime(&Bprime[0][0],basaltria,2,xyz_list, gauss_tria);
+
+		if(approximation==SSAHOApproximationEnum){
+			element->ViscosityHO(&viscosity,dim,xyz_list,gauss,vx_input,vy_input);
+			element->ViscosityHO(&oldviscosity,dim,xyz_list,gauss,vxold_input,vyold_input);
+			newviscosity=viscosity+viscosity_overshoot*(viscosity-oldviscosity);
+		}
+		else if (approximation==SSAFSApproximationEnum){
+			element->ViscosityFS(&newviscosity,dim,xyz_list,gauss,vx_input,vy_input,vz_input);
+		}
+		else _error_("approximation " << approximation << " (" << EnumToStringx(approximation) << ") not supported yet");
+
+		D_scalar=2*newviscosity*gauss->weight*Jdet;
+		for (i=0;i<3;i++) D[i][i]=D_scalar;
+
+		TripleMultiply( &B[0][0],3,numdof2d,1,
+					&D[0][0],3,3,0,
+					&Bprime[0][0],3,numdof2d,0,
+					&Ke_gg[0][0],1);
+
+	}
+	for(i=0;i<numdof2d;i++) for(j=0;j<numdof2d;j++) Ke->values[i*numdof2d+j]+=Ke_gg[i][j];
+
+	/*Transform Coordinate System*/
+	basaltria->TransformStiffnessMatrixCoord(Ke,XYEnum);
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(xyz_list);
+	delete basaltria->material;
+	delete basaltria;
+	delete gauss_tria;
+	delete gauss;
+	return Ke;
+
+}/*}}}*/
+ElementMatrix* StressbalanceAnalysis::CreateKMatrixHOFS(Element* element){/*{{{*/
+
+	/*compute all stiffness matrices for this element*/
+	ElementMatrix* Ke1=CreateKMatrixFS(element);
+	int indices[3]={18,19,20};
+	Ke1->StaticCondensation(3,&indices[0]);
+	int init = element->FiniteElement();
+	element->SetTemporaryElementType(P1Enum); // P1 needed for HO
+	ElementMatrix* Ke2=CreateKMatrixHO(element);
+	element->SetTemporaryElementType(init); // P1 needed for HO
+	ElementMatrix* Ke3=CreateKMatrixCouplingHOFS(element);
+	ElementMatrix* Ke =new ElementMatrix(Ke1,Ke2,Ke3);
+
+	/*clean-up and return*/
+	delete Ke1;
+	delete Ke2;
+	delete Ke3;
+	return Ke;
+}/*}}}*/
+ElementMatrix* StressbalanceAnalysis::CreateKMatrixSSAHO(Element* element){/*{{{*/
+
+	/*compute all stiffness matrices for this element*/
+	ElementMatrix* Ke1=CreateKMatrixSSA3d(element);
+	ElementMatrix* Ke2=CreateKMatrixHO(element);
+	ElementMatrix* Ke3=CreateKMatrixCouplingSSAHO(element);
+	ElementMatrix* Ke =new ElementMatrix(Ke1,Ke2,Ke3);
+
+	/*clean-up and return*/
+	delete Ke1;
+	delete Ke2;
+	delete Ke3;
+	return Ke;
+}/*}}}*/
+ElementMatrix* StressbalanceAnalysis::CreateKMatrixSSAFS(Element* element){/*{{{*/
+
+	/*compute all stiffness matrices for this element*/
+	ElementMatrix* Ke1=CreateKMatrixFS(element);
+	int indices[3]={18,19,20};
+	Ke1->StaticCondensation(3,&indices[0]);
+	int init = element->FiniteElement();
+	element->SetTemporaryElementType(P1Enum); 
+	ElementMatrix* Ke2=CreateKMatrixSSA3d(element);
+	element->SetTemporaryElementType(init); 
+	ElementMatrix* Ke3=CreateKMatrixCouplingSSAFS(element);
+	ElementMatrix* Ke =new ElementMatrix(Ke1,Ke2,Ke3);
+
+	/*clean-up and return*/
+	delete Ke1;
+	delete Ke2;
+	delete Ke3;
+	return Ke;
+}/*}}}*/
+ElementMatrix* StressbalanceAnalysis::CreateKMatrixCouplingHOFS(Element* element){/*{{{*/
+
+	/*Constants*/
+	int numnodes       = 3*6+1;
+	int numdofp        = 2*6;
+	int numdofs        = 4*6 + 3;
+	int numdoftotal    = (2+4)*6+ 3;
+
+	/*Intermediaries*/
+	int   i,j,init;
+	int*   cs_list     = xNew<int>(6*3+1);
+	int*   cs_list2    = xNew<int>(6*2+1);
+	Node  **node_list  = xNew<Node*>(6*3+1);
+
+	/*Some parameters needed*/
+	init = element->FiniteElement();
+
+	/*prepare node list*/
+	for(i=0;i<6+1;i++){
+		node_list[i+6] = element->GetNode(i);
+		cs_list[i+6]   = XYZEnum;
+		cs_list2[i]    = XYZEnum;
+	}
+	for(i=0;i<6;i++){
+		node_list[i]       = element->GetNode(i);
+		node_list[i+2*6+1] = element->GetNode(i+6*1);
+		cs_list[i]         = XYEnum;
+		cs_list[i+2*6+1]   = PressureEnum;
+		cs_list2[i+6+1]    = PressureEnum;
+	}
+
+	/*compute all stiffness matrices for this element*/
+	ElementMatrix* Ke1=element->NewElementMatrixCoupling(6,HOApproximationEnum);
+	ElementMatrix* Ke2=element->NewElementMatrix(FSvelocityEnum);
+	ElementMatrix* Ke=new ElementMatrix(Ke1,Ke2);
+	delete Ke1; delete Ke2;
+
+	/*Compute HO Matrix with P1 element type\n");*/
+	Ke1=CreateKMatrixFS(element); element->TransformInvStiffnessMatrixCoord(Ke1,node_list,2*6+1,cs_list2);
+	int indices[3]={18,19,20};
+	Ke1->StaticCondensation(3,&indices[0]);
+	element->SetTemporaryElementType(P1Enum); // P1 needed for HO
+	Ke2=CreateKMatrixHO(element); element->TransformInvStiffnessMatrixCoord(Ke2,XYEnum);
+	element->SetTemporaryElementType(init); // P1 needed for HO
+	/*Compute FS Matrix and condense it \n");*/
+
+	for(i=0;i<numdofs;i++) for(j=0;j<6;j++){
+		Ke->values[(i+numdofp)*numdoftotal+2*j+0]+=Ke1->values[i*numdofs+3*j+0];
+		Ke->values[(i+numdofp)*numdoftotal+2*j+1]+=Ke1->values[i*numdofs+3*j+1];
+	}
+	for(i=0;i<numdofp;i++) for(j=0;j<6;j++){
+		Ke->values[i*numdoftotal+numdofp+3*j+0]+=Ke2->values[i*numdofp+2*j+0];
+		Ke->values[i*numdoftotal+numdofp+3*j+1]+=Ke2->values[i*numdofp+2*j+1];
+	}
+
+	/*Transform Coordinate System*/ //Do not transform, already done in the matrices
+	element->TransformStiffnessMatrixCoord(Ke,node_list,numnodes,cs_list);
+
+	/*clean-up and return*/
+	xDelete<int>(cs_list);
+	xDelete<int>(cs_list2);
+	xDelete<Node*>(node_list);
+	delete Ke1;
+	delete Ke2;
+	return Ke;
+}/*}}}*/
+ElementMatrix* StressbalanceAnalysis::CreateKMatrixCouplingSSAHO(Element* element){/*{{{*/
+
+	/*compute all stiffness matrices for this element*/
+	ElementMatrix* Ke1=CreateKMatrixCouplingSSAHOViscous(element);
+	ElementMatrix* Ke2=CreateKMatrixCouplingSSAHOFriction(element);
+	ElementMatrix* Ke=new ElementMatrix(Ke1,Ke2);
+
+	/*clean-up and return*/
+	delete Ke1;
+	delete Ke2;
+	return Ke;
+}/*}}}*/
+ElementMatrix* StressbalanceAnalysis::CreateKMatrixCouplingSSAHOFriction(Element* element){/*{{{*/
+
+	if(element->IsFloating() || !element->IsOnBase()) return NULL;
+
+	/*Constants*/
+	int numnodes    = element->GetNumberOfNodes();
+	int numdof      = 2*numnodes;
+	int numdoftotal = 4*numnodes;
+
+	/*Intermediaries */
+	int         i,j;
+	IssmDouble  Jdet2d,alpha2;
+	IssmDouble *xyz_list_tria = NULL;
+	IssmDouble* L             = xNewZeroInit<IssmDouble>(2*numdof);
+	IssmDouble  DL[2][2]      = {{ 0,0 },{0,0}}; //for basal drag
+	IssmDouble  DL_scalar;
+	IssmDouble* Ke_gg         = xNewZeroInit<IssmDouble>(numdof*numdof);
+	Node      **node_list     = xNew<Node*>(2*numnodes);
+	int*        cs_list       = xNew<int>(2*numnodes);
+
+	/*Initialize Element matrix and return if necessary*/
+	ElementMatrix* Ke1=element->NewElementMatrix(SSAApproximationEnum);
+	ElementMatrix* Ke2=element->NewElementMatrix(HOApproximationEnum);
+	ElementMatrix* Ke=new ElementMatrix(Ke1,Ke2);
+	delete Ke1; delete Ke2;
+
+	/*Prepare node list*/
+	for(i=0;i<numnodes;i++){
+		node_list[i+0*numnodes] = element->GetNode(i);
+		node_list[i+1*numnodes] = element->GetNode(i);
+		cs_list[i+0*numnodes] = XYEnum;
+		cs_list[i+1*numnodes] = XYEnum;
+	}
+
+	/*retrieve inputs :*/
+	element->GetVerticesCoordinatesBase(&xyz_list_tria);
+	Input* vx_input=element->GetInput(VxEnum);  _assert_(vx_input);
+	Input* vy_input=element->GetInput(VyEnum);  _assert_(vy_input);
+	Input* vz_input=element->GetInput(VzEnum);  _assert_(vz_input);
+
+	/*build friction object, used later on: */
+	Friction* friction=new Friction(element,2);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGaussBase(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+
+		gauss->GaussPoint(ig);
+
+		/*Friction: */
+		friction->GetAlpha2(&alpha2,gauss,vx_input,vy_input,vz_input);
+		element->JacobianDeterminantBase(&Jdet2d, xyz_list_tria,gauss);
+		this->GetBHOFriction(L,element,3,xyz_list_tria,gauss);
+
+		DL_scalar=alpha2*gauss->weight*Jdet2d;
+		for (i=0;i<2;i++) DL[i][i]=DL_scalar; 
+
+		/*  Do the triple producte tL*D*L: */
+		TripleMultiply( L,2,numdof,1,
+					&DL[0][0],2,2,0,
+					L,2,numdof,0,
+					Ke_gg,1);
+	}
+
+	for(i=0;i<numdof;i++) for(j=0;j<numdof;j++) Ke->values[i*numdoftotal+(numdof+j)]+=Ke_gg[i*numdof+j];
+	for(i=0;i<numdof;i++) for(j=0;j<numdof;j++) Ke->values[(i+numdof)*numdoftotal+j]+=Ke_gg[i*numdof+j];
+
+	/*Transform Coordinate System*/
+	element->TransformStiffnessMatrixCoord(Ke,node_list,2*numnodes,cs_list);
+
+	/*Clean up and return*/
+	delete gauss;
+	delete friction;
+	xDelete<int>(cs_list);
+	xDelete<Node*>(node_list);
+	xDelete<IssmDouble>(xyz_list_tria);
+	xDelete<IssmDouble>(Ke_gg);
+	xDelete<IssmDouble>(L);
+	return Ke;
+}/*}}}*/
+ElementMatrix* StressbalanceAnalysis::CreateKMatrixCouplingSSAHOViscous(Element* element){/*{{{*/
+
+	/*Constants*/
+	int numnodes    = element->GetNumberOfNodes();
+	int numdofm     = 1 *numnodes; //*2/2
+	int numdofp     = 2 *numnodes;
+	int numdoftotal = 2 *2 *numnodes;//2 dof per nodes and 2 sets of nodes for HO and SSA
+
+	/*Intermediaries */
+	int         i,j;
+	IssmDouble  Jdet,viscosity,oldviscosity,newviscosity,viscosity_overshoot; //viscosity
+	IssmDouble  *xyz_list      = NULL;
+	IssmDouble* B              = xNew<IssmDouble>(3*numdofp);
+	IssmDouble* Bprime         = xNew<IssmDouble>(3*numdofm);
+	IssmDouble  D[3][3]={0.0}; // material matrix, simple scalar matrix.
+	IssmDouble  D_scalar;
+	IssmDouble* Ke_gg          = xNewZeroInit<IssmDouble>(numdofp*numdofm);
+	Node       **node_list     = xNew<Node*>(2*numnodes);
+	int*         cs_list= xNew<int>(2*numnodes);
+
+	/*Find penta on bed as HO must be coupled to the dofs on the bed: */
+	Element* pentabase=element->GetBasalElement();
+	Element* basaltria=pentabase->SpawnBasalElement();
+
+	/*prepare node list*/
+	for(i=0;i<numnodes;i++){
+		node_list[i+0*numnodes] = pentabase->GetNode(i);
+		node_list[i+1*numnodes] = element  ->GetNode(i);
+		cs_list[i+0*numnodes] = XYEnum;
+		cs_list[i+1*numnodes] = XYEnum;
+	}
+
+	/*Initialize Element matrix*/
+	ElementMatrix* Ke1= pentabase->NewElementMatrix(SSAApproximationEnum);
+	ElementMatrix* Ke2= element  ->NewElementMatrix(HOApproximationEnum);
+	ElementMatrix* Ke =new ElementMatrix(Ke1,Ke2);
+	delete Ke1; delete Ke2;
+
+	/* Get node coordinates and dof list: */
+	element->GetVerticesCoordinates(&xyz_list);
+	element->FindParam(&viscosity_overshoot,StressbalanceViscosityOvershootEnum);
+	Input* vx_input   =element->GetInput(VxEnum);       _assert_(vx_input);
+	Input* vy_input   =element->GetInput(VyEnum);       _assert_(vy_input);
+	Input* vxold_input=element->GetInput(VxPicardEnum); _assert_(vxold_input);
+	Input* vyold_input=element->GetInput(VyPicardEnum); _assert_(vyold_input);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGauss(5);
+	Gauss* gauss_tria=new GaussTria();
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+
+		gauss->GaussPoint(ig);
+		gauss->SynchronizeGaussBase(gauss_tria);
+
+		element->JacobianDeterminant(&Jdet, xyz_list,gauss);
+		this->GetBSSAHO(B, element,xyz_list, gauss);
+		this->GetBSSAprime(Bprime,basaltria,2,xyz_list, gauss_tria); 
+		element->ViscosityHO(&viscosity,3,xyz_list,gauss,vx_input,vy_input);
+		element->ViscosityHO(&oldviscosity,3,xyz_list,gauss,vxold_input,vyold_input);
+
+		newviscosity=viscosity+viscosity_overshoot*(viscosity-oldviscosity);
+		D_scalar=2*newviscosity*gauss->weight*Jdet;
+		for (i=0;i<3;i++) D[i][i]=D_scalar;
+
+		TripleMultiply( B,3,numdofp,1,
+					&D[0][0],3,3,0,
+					Bprime,3,numdofm,0,
+					Ke_gg,1);
+	} 
+	for(i=0;i<numdofp;i++) for(j=0;j<numdofm;j++) Ke->values[(i+2*numdofm)*numdoftotal+j]+=Ke_gg[i*numdofm+j];
+	for(i=0;i<numdofm;i++) for(j=0;j<numdofp;j++) Ke->values[i*numdoftotal+(j+2*numdofm)]+=Ke_gg[j*numdofm+i];
+
+	/*Transform Coordinate System*/
+	element->TransformStiffnessMatrixCoord(Ke,node_list,2*numnodes,cs_list);
+
+	/*Clean-up and return*/
+	basaltria->DeleteMaterials(); delete basaltria;
+	
+	delete gauss;
+	delete gauss_tria;
+	xDelete<IssmDouble>(B);
+	xDelete<IssmDouble>(Bprime);
+	xDelete<IssmDouble>(Ke_gg);
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<Node*>(node_list);
+	xDelete<int>(cs_list);
+	return Ke;
+
+}/*}}}*/
+ElementMatrix* StressbalanceAnalysis::CreateKMatrixCouplingSSAFS(Element* element){/*{{{*/
+
+	/*compute all stiffness matrices for this element*/
+	ElementMatrix* Ke1=CreateKMatrixCouplingSSAFSViscous(element);
+	ElementMatrix* Ke2=CreateKMatrixCouplingSSAFSFriction(element);
+	ElementMatrix* Ke =new ElementMatrix(Ke1,Ke2);
+
+	/*clean-up and return*/
+	delete Ke1;
+	delete Ke2;
+	return Ke;
+}/*}}}*/
+ElementMatrix* StressbalanceAnalysis::CreateKMatrixCouplingSSAFSFriction(Element* element){/*{{{*/
+
+	/*Constants*/
+	const int numdofs   = (6+1)*3 + 6*1;
+	const int numdofm   = 6 *2;
+	const int numdof2d  = 3 *3;
+	const int numdof2dm = 3 *2;
+	const int numdoftot = 6*2 + (6+1)*3 +6; // HO + FS vel + FS Pressure
+
+	/*Intermediaries */
+	int        i,j,approximation;
+	int        dim=3;
+	IssmDouble FSreconditioning,viscosity,alpha2_gauss,Jdet2d;
+	IssmDouble bed_normal[3];
+	IssmDouble LSSAFS[8][numdof2dm];
+	IssmDouble LprimeSSAFS[8][numdofs];
+	IssmDouble DLSSAFS[8][8]={0.0};
+	IssmDouble LFSSSA[4][numdof2d];
+	IssmDouble LprimeFSSSA[4][numdof2dm];
+	IssmDouble DLFSSSA[4][4]={0.0};
+	IssmDouble Ke_drag[numdof2dm][numdofs]={0.0};
+	IssmDouble Ke_drag2[numdof2d][numdof2dm]={0.0};
+	IssmDouble *xyz_list      = NULL;
+	IssmDouble *xyz_list_tria = NULL;
+
+	/*If on water or not FS, skip stiffness: */
+	element->GetInputValue(&approximation,ApproximationEnum);
+	if(element->IsFloating() || !element->IsOnBase()) return NULL;
+
+	int vnumnodes = element->NumberofNodesVelocity();
+	int pnumnodes = element->NumberofNodesPressure();
+	int numnodes  = 2*vnumnodes-1+pnumnodes;
+
+	/*Prepare node list*/
+	int* cs_list = xNew<int>(2*vnumnodes-1+pnumnodes);
+	Node **node_list = xNew<Node*>(2*vnumnodes-1+pnumnodes);
+	for(i=0;i<vnumnodes-1;i++){
+		node_list[i] = element->GetNode(i);
+		cs_list[i]   = XYEnum;
+	}
+	for(i=0;i<vnumnodes;i++){
+		node_list[i+vnumnodes-1] = element->GetNode(i);
+		cs_list[i+vnumnodes-1]   = XYZEnum;
+	}
+	for(i=0;i<pnumnodes;i++){
+		node_list[2*vnumnodes-1+i] = element->GetNode(vnumnodes+i);
+		cs_list[2*vnumnodes-1+i]   = PressureEnum;
+	}
+
+	ElementMatrix* Ke1=element->NewElementMatrixCoupling(6,SSAApproximationEnum);
+	ElementMatrix* Ke2=element->NewElementMatrix(FSvelocityEnum);
+	ElementMatrix* Ke=new ElementMatrix(Ke1,Ke2);
+	delete Ke1; delete Ke2;
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+	element->GetVerticesCoordinatesBase(&xyz_list_tria);
+	element->FindParam(&FSreconditioning,StressbalanceFSreconditioningEnum);
+	Input* vx_input=element->GetInput(VxEnum); _assert_(vx_input);
+	Input* vy_input=element->GetInput(VyEnum); _assert_(vy_input);
+	Input* vz_input=element->GetInput(VzEnum); _assert_(vz_input);
+
+	/*build friction object, used later on: */
+	Friction* friction=new Friction(element,3);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGaussBase(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminantBase(&Jdet2d,xyz_list_tria,gauss);
+		this->GetLSSAFS(&LSSAFS[0][0], element,gauss);
+		this->GetLprimeSSAFS(&LprimeSSAFS[0][0], element,xyz_list, gauss);
+		this->GetLFSSSA(&LFSSSA[0][0],element, gauss);
+		this->GetLprimeFSSSA(&LprimeFSSSA[0][0], element,xyz_list, gauss);
+
+		element->ViscosityFS(&viscosity,dim,xyz_list,gauss,vx_input,vy_input,vz_input);
+
+		element->NormalBase(&bed_normal[0],xyz_list_tria);
+		friction->GetAlpha2(&alpha2_gauss, gauss,vx_input,vy_input,vz_input);
+
+		DLSSAFS[0][0]=alpha2_gauss*gauss->weight*Jdet2d;
+		DLSSAFS[1][1]=alpha2_gauss*gauss->weight*Jdet2d;
+		DLSSAFS[2][2]=-alpha2_gauss*gauss->weight*Jdet2d*bed_normal[0]*bed_normal[2];
+		DLSSAFS[3][3]=-alpha2_gauss*gauss->weight*Jdet2d*bed_normal[1]*bed_normal[2];
+		DLSSAFS[4][4]=-2*viscosity*gauss->weight*Jdet2d*bed_normal[0];
+		DLSSAFS[5][5]=-2*viscosity*gauss->weight*Jdet2d*bed_normal[1];
+		DLSSAFS[6][6]=FSreconditioning*gauss->weight*Jdet2d*bed_normal[0];
+		DLSSAFS[7][7]=FSreconditioning*gauss->weight*Jdet2d*bed_normal[1];
+
+		DLFSSSA[0][0]=alpha2_gauss*gauss->weight*Jdet2d;
+		DLFSSSA[1][1]=alpha2_gauss*gauss->weight*Jdet2d;
+		DLFSSSA[2][2]=-alpha2_gauss*gauss->weight*Jdet2d*bed_normal[0]*bed_normal[2];
+		DLFSSSA[3][3]=-alpha2_gauss*gauss->weight*Jdet2d*bed_normal[1]*bed_normal[2];
+
+		TripleMultiply( &LSSAFS[0][0],8,numdof2dm,1,
+					&DLSSAFS[0][0],8,8,0,
+					&LprimeSSAFS[0][0],8,numdofs,0,
+					&Ke_drag[0][0],1);
+
+		TripleMultiply( &LFSSSA[0][0],4,numdof2d,1,
+					&DLFSSSA[0][0],4,4,0,
+					&LprimeFSSSA[0][0],4,numdof2dm,0,
+					&Ke_drag2[0][0],1);
+	}
+
+	for(i=0;i<numdof2dm;i++) for(j=0;j<numdofs;j++) Ke->values[i*numdoftot+j+numdofm]+=Ke_drag[i][j];
+	for(i=0;i<numdof2d;i++) for(j=0;j<numdof2dm;j++) Ke->values[(i+numdofm)*numdoftot+j]+=Ke_drag2[i][j];
+		
+	/*Transform Coordinate System*/
+	element->TransformStiffnessMatrixCoord(Ke,node_list,numnodes,cs_list);
+
+	/*Clean up and return*/
+	xDelete<int>(cs_list);
+	xDelete<Node*>(node_list);
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(xyz_list_tria);
+	delete gauss;
+	delete friction;
+	return Ke;
+}/*}}}*/
+ElementMatrix* StressbalanceAnalysis::CreateKMatrixCouplingSSAFSViscous(Element* element){/*{{{*/
+
+	/*Constants*/
+	const int numdofm     = 2 *3;
+	const int numdofs     = 4 *6+ 3;
+	const int numdoftotal = 2 *numdofm+numdofs;
+
+	/*Intermediaries */
+	int        i,j;
+	int        dim=3;
+	IssmDouble Jdet,viscosity,FSreconditioning,D_scalar;
+	IssmDouble B[4][numdofs];
+	IssmDouble Bprime[4][numdofm];
+	IssmDouble B2[3][numdofm];
+	IssmDouble Bprime2[3][numdofs];
+	IssmDouble D[4][4]={0.0};            // material matrix, simple scalar matrix.
+	IssmDouble D2[3][3]={0.0};            // material matrix, simple scalar matrix.
+	IssmDouble Ke_gg[numdofs][numdofm]={0.0}; //local element stiffness matrix 
+	IssmDouble Ke_gg2[numdofm][numdofs]={0.0}; //local element stiffness matrix 
+	IssmDouble *xyz_list    = NULL;
+
+	/*Find penta on bed as FS must be coupled to the dofs on the bed: */
+	Element* pentabase=element->GetBasalElement();
+	Element* basaltria=pentabase->SpawnBasalElement();
+
+	int vnumnodes = element->NumberofNodesVelocity();
+	int pnumnodes = element->NumberofNodesPressure();
+	int numnodes  = 2*vnumnodes-1+pnumnodes;
+
+	/*Prepare node list*/
+	int* cs_list     = xNew<int>(2*vnumnodes-1+pnumnodes);
+	Node **node_list = xNew<Node*>(2*vnumnodes-1+pnumnodes);
+	for(i=0;i<vnumnodes-1;i++){
+		node_list[i] = pentabase->GetNode(i);
+		cs_list[i]   = XYEnum;
+	}
+	for(i=0;i<vnumnodes;i++){
+		node_list[i+vnumnodes-1] = element->GetNode(i);
+		cs_list[i+vnumnodes-1]   = XYZEnum;
+	}
+	for(i=0;i<pnumnodes;i++){
+		node_list[2*vnumnodes-1+i] = element->GetNode(vnumnodes+i);
+		cs_list[2*vnumnodes-1+i]   = PressureEnum;
+	}
+
+	/*Initialize Element matrix and return if necessary*/
+	ElementMatrix* Ke1=pentabase->NewElementMatrixCoupling(6,SSAApproximationEnum);
+	ElementMatrix* Ke2=element->NewElementMatrix(FSvelocityEnum);
+	ElementMatrix* Ke =new ElementMatrix(Ke1,Ke2);
+	delete Ke1; delete Ke2;
+
+	/* Get node coordinates and dof list: */
+	element->GetVerticesCoordinates(&xyz_list);
+	element->FindParam(&FSreconditioning,StressbalanceFSreconditioningEnum);
+	Input* vx_input=element->GetInput(VxEnum); _assert_(vx_input);
+	Input* vy_input=element->GetInput(VyEnum); _assert_(vy_input);
+	Input* vz_input=element->GetInput(VzEnum); _assert_(vz_input);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGauss(5);
+	Gauss* gauss_tria=new GaussTria();
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+
+		gauss->GaussPoint(ig);
+		gauss->SynchronizeGaussBase(gauss_tria);
+
+		element->JacobianDeterminant(&Jdet, xyz_list,gauss);
+		this->GetBSSAFS(&B[0][0],element,xyz_list, gauss);
+		this->GetBprimeSSAFSTria(&Bprime[0][0], basaltria,xyz_list, gauss_tria);
+		this->GetBSSAFSTria(&B2[0][0], basaltria,xyz_list, gauss_tria);
+		this->GetBprimeSSAFS(&Bprime2[0][0], element,xyz_list, gauss);
+
+		element->ViscosityFS(&viscosity,dim,xyz_list,gauss,vx_input,vy_input,vz_input);
+
+		D_scalar=2*viscosity*gauss->weight*Jdet;
+		for (i=0;i<3;i++) D[i][i]=D_scalar;
+		D[3][3]=-gauss->weight*Jdet*FSreconditioning;
+		for (i=0;i<3;i++) D2[i][i]=D_scalar;
+
+		TripleMultiply( &B[0][0],4,numdofs,1,
+					&D[0][0],4,4,0,
+					&Bprime[0][0],4,numdofm,0,
+					&Ke_gg[0][0],1);
+
+		TripleMultiply( &B2[0][0],3,numdofm,1,
+					&D2[0][0],3,3,0,
+					&Bprime2[0][0],3,numdofs,0,
+					&Ke_gg2[0][0],1);
+
+	} 
+	for(i=0;i<numdofs;i++) for(j=0;j<numdofm;j++) Ke->values[(i+2*numdofm)*numdoftotal+j]+=Ke_gg[i][j];
+	for(i=0;i<numdofm;i++) for(j=0;j<numdofs;j++) Ke->values[i*numdoftotal+(j+2*numdofm)]+=Ke_gg2[i][j];
+
+	/*Transform Coordinate System*/
+	element->TransformStiffnessMatrixCoord(Ke,node_list,numnodes,cs_list);
+
+	/*Clean-up and return*/
+	xDelete<int>(cs_list);
+	xDelete<Node*>(node_list);
+	xDelete<IssmDouble>(xyz_list);
+	delete basaltria->material; delete basaltria;
+	delete gauss;
+	delete gauss_tria;
+	return Ke;
+
+}/*}}}*/
+ElementVector* StressbalanceAnalysis::CreatePVectorSSAHO(Element* element){/*{{{*/
+
+	/*compute all load vectors for this element*/
+	ElementVector* pe1=CreatePVectorSSA(element);
+	ElementVector* pe2=CreatePVectorHO(element);
+	ElementVector* pe =new ElementVector(pe1,pe2);
+
+	/*clean-up and return*/
+	delete pe1;
+	delete pe2;
+	return pe;
+}/*}}}*/
+ElementVector* StressbalanceAnalysis::CreatePVectorSSAFS(Element* element){/*{{{*/
+
+	/*compute all load vectors for this element*/
+	int init = element->FiniteElement();
+	element->SetTemporaryElementType(P1Enum); // P1 needed for HO
+	ElementVector* pe1=CreatePVectorSSA(element);
+	element->SetTemporaryElementType(init); // P1 needed for HO
+	ElementVector* pe2=CreatePVectorFS(element);
+	int indices[3]={18,19,20};
+	element->SetTemporaryElementType(MINIcondensedEnum); // P1 needed for HO
+	ElementMatrix* Ke = CreateKMatrixFS(element);
+	element->SetTemporaryElementType(init); // P1 needed for HO
+	pe2->StaticCondensation(Ke,3,&indices[0]);
+	delete Ke;
+	ElementVector* pe3=CreatePVectorCouplingSSAFS(element);
+	ElementVector* pe =new ElementVector(pe1,pe2,pe3);
+
+	/*clean-up and return*/
+	delete pe1;
+	delete pe2;
+	delete pe3;
+	return pe;
+}/*}}}*/
+ElementVector* StressbalanceAnalysis::CreatePVectorHOFS(Element* element){/*{{{*/
+
+	/*compute all load vectors for this element*/
+	int init = element->FiniteElement();
+	element->SetTemporaryElementType(P1Enum);
+	ElementVector* pe1=CreatePVectorHO(element);
+	element->SetTemporaryElementType(init);
+	ElementVector* pe2=CreatePVectorFS(element);
+	int indices[3]={18,19,20};
+	element->SetTemporaryElementType(MINIcondensedEnum);
+	ElementMatrix* Ke = CreateKMatrixFS(element);
+	element->SetTemporaryElementType(init);
+	pe2->StaticCondensation(Ke,3,&indices[0]);
+	delete Ke;
+	ElementVector* pe3=CreatePVectorCouplingHOFS(element);
+	ElementVector* pe =new ElementVector(pe1,pe2,pe3);
+
+	/*clean-up and return*/
+	delete pe1;
+	delete pe2;
+	delete pe3;
+	return pe;
+}/*}}}*/
+ElementVector* StressbalanceAnalysis::CreatePVectorCouplingHOFS(Element* element){/*{{{*/
+
+	/*compute all load vectors for this element*/
+	ElementVector* pe1=CreatePVectorCouplingHOFSViscous(element);
+	ElementVector* pe2=CreatePVectorCouplingHOFSFriction(element);
+	ElementVector* pe =new ElementVector(pe1,pe2);
+
+	/*clean-up and return*/
+	delete pe1;
+	delete pe2;
+	return pe;
+}/*}}}*/
+ElementVector* StressbalanceAnalysis::CreatePVectorCouplingHOFSFriction(Element* element){/*{{{*/
+
+	/*Intermediaries*/
+	int         i,j,approximation;
+	int         dim=3;
+	IssmDouble  Jdet,Jdet2d,FSreconditioning;
+	IssmDouble	bed_normal[3];
+	IssmDouble  viscosity, w, alpha2_gauss;
+	IssmDouble  dw[3];
+	IssmDouble	*xyz_list_tria = NULL;
+	IssmDouble  *xyz_list      = NULL;
+	IssmDouble  basis[6]; //for the six nodes of the penta
+
+	/*Initialize Element vector and return if necessary*/
+	if(!element->IsOnBase() || element->IsFloating()) return NULL;
+	element->GetInputValue(&approximation,ApproximationEnum);
+	if(approximation!=HOFSApproximationEnum) return NULL;
+
+	int vnumnodes = element->NumberofNodesVelocity();
+	int pnumnodes = element->NumberofNodesPressure();
+	int numnodes  = vnumnodes+pnumnodes;
+
+	/*Prepare coordinate system list*/
+	int*   cs_list   = xNew<int>(vnumnodes+pnumnodes);
+	Node **node_list = xNew<Node*>(vnumnodes+pnumnodes);
+	for(i=0;i<vnumnodes;i++){
+		cs_list[i]           = XYZEnum;
+		node_list[i]           = element->GetNode(i);
+	}
+	for(i=0;i<pnumnodes;i++){
+		cs_list[vnumnodes+i] = PressureEnum;
+		node_list[vnumnodes+i] = element->GetNode(vnumnodes+i);
+	}
+
+	ElementVector* pe=element->NewElementVector(FSvelocityEnum);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+	element->GetVerticesCoordinatesBase(&xyz_list_tria);
+	element->FindParam(&FSreconditioning,StressbalanceFSreconditioningEnum);
+	Input* vx_input=  element->GetInput(VxEnum);   _assert_(vx_input);
+	Input* vy_input=  element->GetInput(VyEnum);   _assert_(vy_input);
+	Input* vz_input=  element->GetInput(VzEnum);   _assert_(vz_input);
+	Input* vzHO_input=element->GetInput(VzHOEnum); _assert_(vzHO_input);
+
+	/*build friction object, used later on: */
+	Friction* friction=new Friction(element,3);
+
+	/* Start looping on the number of gauss 2d (nodes on the bedrock) */
+	Gauss* gauss=element->NewGaussBase(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminantBase(&Jdet2d,xyz_list_tria,gauss);
+		element->NodalFunctionsP1(basis, gauss);
+
+		vzHO_input->GetInputValue(&w, gauss);
+		vzHO_input->GetInputDerivativeValue(&dw[0],xyz_list,gauss);
+
+		element->NormalBase(&bed_normal[0],xyz_list_tria);
+		element->ViscosityFS(&viscosity,dim,xyz_list,gauss,vx_input,vy_input,vz_input);
+		friction->GetAlpha2(&alpha2_gauss, gauss,vx_input,vy_input,vz_input);
+
+		for(i=0;i<3;i++){
+			pe->values[i*3+0]+=Jdet2d*gauss->weight*(alpha2_gauss*w*bed_normal[0]*bed_normal[2]+2*viscosity*dw[2]*bed_normal[0])*basis[i];
+			pe->values[i*3+1]+=Jdet2d*gauss->weight*(alpha2_gauss*w*bed_normal[1]*bed_normal[2]+2*viscosity*dw[2]*bed_normal[1])*basis[i];
+			pe->values[i*3+2]+=Jdet2d*gauss->weight*2*viscosity*(dw[0]*bed_normal[0]+dw[1]*bed_normal[1]+dw[2]*bed_normal[2])*basis[i];
+		}
+	}
+
+	/*Transform coordinate system*/
+	element->TransformLoadVectorCoord(pe,node_list,vnumnodes+pnumnodes,cs_list);
+
+	/*Clean up and return*/
+	xDelete<int>(cs_list);
+	xDelete<Node*>(node_list);
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(xyz_list_tria);
+	delete gauss;
+	delete friction;
+	return pe;
+}/*}}}*/
+ElementVector* StressbalanceAnalysis::CreatePVectorCouplingHOFSViscous(Element* element){/*{{{*/
+
+	/*Intermediaries */
+	int         i,approximation;
+	int         dim=3;
+	IssmDouble  viscosity,Jdet,FSreconditioning;
+	IssmDouble  dw[3];
+	IssmDouble  *xyz_list = NULL;
+	IssmDouble  basis[6]; //for the six nodes of the penta
+	IssmDouble  dbasis[3][6]; //for the six nodes of the penta
+
+	/*Initialize Element vector and return if necessary*/
+	element->GetInputValue(&approximation,ApproximationEnum);
+	if(approximation!=HOFSApproximationEnum) return NULL;
+	int   vnumnodes = element->NumberofNodesVelocity();
+	int   pnumnodes = element->NumberofNodesPressure();
+
+	/*Prepare coordinate system list*/
+	int*   cs_list   = xNew<int>(vnumnodes+pnumnodes);
+	Node **node_list = xNew<Node*>(vnumnodes+pnumnodes);
+	for(i=0;i<vnumnodes;i++){
+		cs_list[i]             = XYZEnum;
+		node_list[i]           = element->GetNode(i);
+	}
+	for(i=0;i<pnumnodes;i++){
+		cs_list[vnumnodes+i]   = PressureEnum;
+		node_list[vnumnodes+i] = element->GetNode(vnumnodes+i);
+	}
+	ElementVector* pe = element->NewElementVector(FSvelocityEnum);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+	element->FindParam(&FSreconditioning,StressbalanceFSreconditioningEnum);
+	Input* vx_input   =element->GetInput(VxEnum);   _assert_(vx_input);
+	Input* vy_input   =element->GetInput(VyEnum);   _assert_(vy_input);
+	Input* vz_input   =element->GetInput(VzEnum);   _assert_(vz_input);
+	Input* vzHO_input=element->GetInput(VzHOEnum);  _assert_(vzHO_input);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGauss(5);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminant(&Jdet, xyz_list,gauss);
+		element->NodalFunctionsP1(&basis[0],gauss);
+		element->NodalFunctionsP1Derivatives(&dbasis[0][0],xyz_list,gauss);
+		
+		element->ViscosityFS(&viscosity,dim,xyz_list,gauss,vx_input,vy_input,vz_input);
+		vzHO_input->GetInputDerivativeValue(&dw[0],xyz_list,gauss);
+
+		for(i=0;i<6;i++){
+			pe->values[i*3+0]+=-Jdet*gauss->weight*viscosity*dw[0]*dbasis[2][i];
+			pe->values[i*3+1]+=-Jdet*gauss->weight*viscosity*dw[1]*dbasis[2][i];
+			pe->values[i*3+2]+=-Jdet*gauss->weight*viscosity*(dw[0]*dbasis[0][i]+dw[1]*dbasis[1][i]+2*dw[2]*dbasis[2][i]);
+			pe->values[3*vnumnodes+i]+=Jdet*gauss->weight*FSreconditioning*dw[2]*basis[i];
+		}
+	}
+
+	/*Transform coordinate system*/
+	element->TransformLoadVectorCoord(pe,node_list,vnumnodes+pnumnodes,cs_list);
+
+	/*Clean up and return*/
+	xDelete<int>(cs_list);
+	xDelete<Node*>(node_list);
+	xDelete<IssmDouble>(xyz_list);
+	delete gauss;
+	return pe;
+}/*}}}*/
+ElementVector* StressbalanceAnalysis::CreatePVectorCouplingSSAFS(Element* element){/*{{{*/
+
+	/*compute all load vectors for this element*/
+	ElementVector* pe1=CreatePVectorCouplingSSAFSViscous(element);
+	ElementVector* pe2=CreatePVectorCouplingSSAFSFriction(element);
+	ElementVector* pe =new ElementVector(pe1,pe2);
+
+	/*clean-up and return*/
+	delete pe1;
+	delete pe2;
+	return pe;
+}/*}}}*/
+ElementVector* StressbalanceAnalysis::CreatePVectorCouplingSSAFSFriction(Element* element){/*{{{*/
+
+	/*Intermediaries*/
+	int         i,j,approximation;
+	int         dim=3;
+	IssmDouble  Jdet,Jdet2d,FSreconditioning;
+	IssmDouble	bed_normal[3];
+	IssmDouble  viscosity, w, alpha2_gauss;
+	IssmDouble  dw[3];
+	IssmDouble  basis[6]; //for the six nodes of the penta
+	IssmDouble	*xyz_list_tria = NULL;
+	IssmDouble  *xyz_list      = NULL;
+
+	/*Initialize Element vector and return if necessary*/
+	if(!element->IsOnBase() || element->IsFloating()) return NULL;
+	element->GetInputValue(&approximation,ApproximationEnum);
+	if(approximation!=SSAFSApproximationEnum) return NULL;
+	int vnumnodes = element->NumberofNodesVelocity();
+	int pnumnodes = element->NumberofNodesPressure();
+
+	/*Prepare coordinate system list*/
+	int* cs_list     = xNew<int>(vnumnodes+pnumnodes);
+	Node **node_list = xNew<Node*>(vnumnodes+pnumnodes);
+	for(i=0;i<vnumnodes;i++){
+		cs_list[i]             = XYZEnum;
+		node_list[i]           = element->GetNode(i);
+	}
+	for(i=0;i<pnumnodes;i++){
+		cs_list[vnumnodes+i]   = PressureEnum;
+		node_list[vnumnodes+i] = element->GetNode(vnumnodes+i);
+	}
+	ElementVector* pe=element->NewElementVector(FSvelocityEnum);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+	element->GetVerticesCoordinatesBase(&xyz_list_tria);
+	element->FindParam(&FSreconditioning,StressbalanceFSreconditioningEnum);
+	Input* vx_input=   element->GetInput(VxEnum);    _assert_(vx_input);
+	Input* vy_input=   element->GetInput(VyEnum);    _assert_(vy_input);
+	Input* vz_input=   element->GetInput(VzEnum);    _assert_(vz_input);
+	Input* vzSSA_input=element->GetInput(VzSSAEnum); _assert_(vzSSA_input);
+
+	/*build friction object, used later on: */
+	Friction* friction=new Friction(element,3);
+
+	/* Start looping on the number of gauss 2d (nodes on the bedrock) */
+	Gauss* gauss=element->NewGaussBase(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminantBase(&Jdet2d,xyz_list_tria,gauss);
+		element->NodalFunctionsP1(basis, gauss);
+
+		vzSSA_input->GetInputValue(&w, gauss);
+		vzSSA_input->GetInputDerivativeValue(&dw[0],xyz_list,gauss);
+
+		element->NormalBase(&bed_normal[0],xyz_list_tria);
+		element->ViscosityFS(&viscosity,dim,xyz_list,gauss,vx_input,vy_input,vz_input);
+		friction->GetAlpha2(&alpha2_gauss, gauss,vx_input,vy_input,vz_input);
+
+		for(i=0;i<3;i++){
+			pe->values[i*3+0]+=Jdet2d*gauss->weight*(alpha2_gauss*w*bed_normal[0]*bed_normal[2]+2*viscosity*dw[2]*bed_normal[0])*basis[i];
+			pe->values[i*3+1]+=Jdet2d*gauss->weight*(alpha2_gauss*w*bed_normal[1]*bed_normal[2]+2*viscosity*dw[2]*bed_normal[1])*basis[i];
+			pe->values[i*3+2]+=Jdet2d*gauss->weight*2*viscosity*(dw[0]*bed_normal[0]+dw[1]*bed_normal[1]+dw[2]*bed_normal[2])*basis[i];
+		}
+	}
+
+	/*Transform coordinate system*/
+	element->TransformLoadVectorCoord(pe,node_list,vnumnodes+pnumnodes,cs_list);
+
+	/*Clean up and return*/
+	xDelete<int>(cs_list);
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(xyz_list_tria);
+	xDelete<Node*>(node_list);
+	delete gauss;
+	delete friction;
+	return pe;
+}/*}}}*/
+ElementVector* StressbalanceAnalysis::CreatePVectorCouplingSSAFSViscous(Element* element){/*{{{*/
+
+	/*Intermediaries */
+	int         i,approximation;
+	IssmDouble  viscosity,Jdet,FSreconditioning;
+	IssmDouble  dw[3];
+	IssmDouble  *xyz_list = NULL;
+	IssmDouble  basis[6]; //for the six nodes of the penta
+	IssmDouble  dbasis[3][6]; //for the six nodes of the penta
+
+	/*Initialize Element vector and return if necessary*/
+	element->GetInputValue(&approximation,ApproximationEnum);
+	if(approximation!=SSAFSApproximationEnum) return NULL;
+	int vnumnodes = element->NumberofNodesVelocity();
+	int pnumnodes = element->NumberofNodesPressure();
+
+	/*Prepare coordinate system list*/
+	int* cs_list = xNew<int>(vnumnodes+pnumnodes);
+	Node **node_list = xNew<Node*>(vnumnodes+pnumnodes);
+	for(i=0;i<vnumnodes;i++){
+		cs_list[i]             = XYZEnum;
+		node_list[i]           = element->GetNode(i);
+	}
+	for(i=0;i<pnumnodes;i++){
+		cs_list[vnumnodes+i]   = PressureEnum;
+		node_list[vnumnodes+i] = element->GetNode(vnumnodes+i);
+	}
+	ElementVector* pe=element->NewElementVector(FSvelocityEnum);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+	element->FindParam(&FSreconditioning,StressbalanceFSreconditioningEnum);
+	Input* vx_input   =element->GetInput(VxEnum);      _assert_(vx_input);
+	Input* vy_input   =element->GetInput(VyEnum);      _assert_(vy_input);
+	Input* vz_input   =element->GetInput(VzEnum);      _assert_(vz_input);
+	Input* vzSSA_input=element->GetInput(VzSSAEnum);   _assert_(vzSSA_input);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGauss(5);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+
+		gauss->GaussPoint(ig);
+		element->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		element->NodalFunctionsP1(&basis[0], gauss);
+		element->NodalFunctionsP1Derivatives(&dbasis[0][0],xyz_list, gauss);
+
+		vzSSA_input->GetInputDerivativeValue(&dw[0],xyz_list,gauss);
+		element->ViscosityFS(&viscosity,3,xyz_list,gauss,vx_input,vy_input,vz_input);
+
+		for(i=0;i<6;i++){
+			pe->values[i*3+0]+=-Jdet*gauss->weight*viscosity*dw[0]*dbasis[2][i];
+			pe->values[i*3+1]+=-Jdet*gauss->weight*viscosity*dw[1]*dbasis[2][i];
+			pe->values[i*3+2]+=-Jdet*gauss->weight*viscosity*(dw[0]*dbasis[0][i]+dw[1]*dbasis[1][i]+2*dw[2]*dbasis[2][i]);
+			pe->values[3*vnumnodes+i]+=Jdet*gauss->weight*FSreconditioning*dw[2]*basis[i];
+		}
+	}
+
+	/*Transform coordinate system*/
+	element->TransformLoadVectorCoord(pe,node_list,vnumnodes+pnumnodes,cs_list);
+
+	/*Clean up and return*/
+	xDelete<int>(cs_list);
+	xDelete<Node*>(node_list);
+	xDelete<IssmDouble>(xyz_list);
+	delete gauss;
+	return pe;
+}/*}}}*/
+void StressbalanceAnalysis::GetBSSAHO(IssmDouble* B,Element* element,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
+	/*Compute B  matrix. B=[B1 B2 B3 B4 B5 B6] where Bi is of size 3*NDOF2. 
+	 * For node i, Bi can be expressed in the actual coordinate system
+	 * by: 
+	 *       Bi=[ dh/dx          0      ]
+	 *          [   0           dh/dy   ]
+	 *          [ 1/2*dh/dy  1/2*dh/dx  ]
+	 * where h is the interpolation function for node i.
+	 *
+	 * We assume B has been allocated already, of size: 5x(NDOF2*NUMNODESP1)
+	 */
+
+	int numnodes = element->GetNumberOfNodes();
+	IssmDouble* dbasis=xNew<IssmDouble>(3*numnodes);
+
+	/*Get dbasis in actual coordinate system: */
+	element->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+
+	/*Build B: */
+	for(int i=0;i<numnodes;i++){
+		B[2*numnodes*0+2*i+0] = dbasis[0*numnodes+i];
+		B[2*numnodes*0+2*i+1] = 0.;
+		B[2*numnodes*1+2*i+0] = 0.;
+		B[2*numnodes*1+2*i+1] = dbasis[1*numnodes+i];
+		B[2*numnodes*2+2*i+0] = .5*dbasis[1*numnodes+i];
+		B[2*numnodes*2+2*i+1] = .5*dbasis[0*numnodes+i];
+	}
+
+	/*Clean-up*/
+	xDelete<IssmDouble>(dbasis);
+}/*}}}*/
+void StressbalanceAnalysis::GetBSSAFS(IssmDouble* B,Element* element,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
+	/*Compute B  matrix. B=[B1 B2 B3 B4 B5 B6] where Bi is of size 5*NDOF2. 
+	 * For node i, Bi can be expressed in the actual coordinate system
+	 * by: 
+	 *       Bi=[ dh/dx          0       0   0 ]
+	 *          [   0           dh/dy    0   0 ]
+	 *          [ 1/2*dh/dy  1/2*dh/dx   0   0 ]
+	 *          [   0            0       0   h ]
+	 * where h is the interpolation function for node i.
+	 *
+	 * We assume B has been allocated already, of size: 5x(NDOF2*NUMNODESP1)
+	 */
+
+	int i;
+	IssmDouble dbasismini[3][7];
+	IssmDouble basis[6];
+
+	/*Get dbasis in actual coordinate system: */
+	element->NodalFunctionsMINIDerivatives(&dbasismini[0][0],xyz_list, gauss);
+	element->NodalFunctionsP1(basis,gauss);
+
+	/*Build B: */
+	for(i=0;i<6;i++){
+		B[(3*7+6)*0+3*i+0] = dbasismini[0][i];
+		B[(3*7+6)*0+3*i+1] = 0.;
+		B[(3*7+6)*0+3*i+2] = 0.;
+		B[(3*7+6)*1+3*i+0] = 0.;
+		B[(3*7+6)*1+3*i+1] = dbasismini[1][i];
+		B[(3*7+6)*1+3*i+2] = 0.;
+		B[(3*7+6)*2+3*i+0] = 0.5*dbasismini[1][i];
+		B[(3*7+6)*2+3*i+1] = 0.5*dbasismini[0][i];
+		B[(3*7+6)*2+3*i+2] = 0.;
+		B[(3*7+6)*3+3*i+0] = 0.;
+		B[(3*7+6)*3+3*i+1] = 0.;
+		B[(3*7+6)*3+3*i+2] = 0.;
+	}
+	for(i=0;i<1;i++){
+		B[(3*7+6)*0+3*(6+i)+0] = 0.;
+		B[(3*7+6)*0+3*(6+i)+1] = 0.;
+		B[(3*7+6)*0+3*(6+i)+2] = 0.;
+		B[(3*7+6)*1+3*(6+i)+0] = 0.;
+		B[(3*7+6)*1+3*(6+i)+1] = 0.;
+		B[(3*7+6)*1+3*(6+i)+2] = 0.;
+		B[(3*7+6)*2+3*(6+i)+0] = 0.;
+		B[(3*7+6)*2+3*(6+i)+1] = 0.;
+		B[(3*7+6)*2+3*(6+i)+2] = 0.;
+		B[(3*7+6)*3+3*(6+i)+0] = 0.;
+		B[(3*7+6)*3+3*(6+i)+1] = 0.;
+		B[(3*7+6)*3+3*(6+i)+2] = 0.;
+	}
+
+	for(i=0;i<6;i++){ //last column not for the bubble function
+		B[(3*7+6)*0+7*3+i] = 0;
+		B[(3*7+6)*1+7*3+i] = 0;
+		B[(3*7+6)*2+7*3+i] = 0;
+		B[(3*7+6)*3+7*3+i] = basis[i];
+	}
+}/*}}}*/
+void StressbalanceAnalysis::GetBprimeSSAFS(IssmDouble* Bprime,Element* element,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
+	/*Compute Bprime  matrix. Bprime=[Bprime1 Bprime2 Bprime3 Bprime4 Bprime5 Bprime6] where Bprimei is of size 5*NDOF2. 
+	 * For node i, Bprimei can be expressed in the actual coordinate system
+	 * by: 
+	 *       Bprimei=[ 2*dh/dx    dh/dy   0   0 ]
+	 *               [  dh/dx    2*dh/dy  0   0 ]
+	 *               [  dh/dy     dh/dx   0   0 ]
+	 * where h is the interpolation function for node i.
+	 *
+	 * We assume Bprime has been allocated already, of size: 5x(NDOF2*NUMNODESP1)
+	 */
+
+	int    i;
+	IssmDouble dbasismini[3][7];
+
+	/*Get dbasis in actual coordinate system: */
+	element->NodalFunctionsMINIDerivatives(&dbasismini[0][0],xyz_list, gauss);
+
+	/*Build Bprime: */
+	for(i=0;i<6;i++){
+		Bprime[(3*7+6)*0+3*i+0] = 2.*dbasismini[0][i];
+		Bprime[(3*7+6)*0+3*i+1] = dbasismini[1][i];
+		Bprime[(3*7+6)*0+3*i+2] = 0.;
+		Bprime[(3*7+6)*1+3*i+0] = dbasismini[0][i];
+		Bprime[(3*7+6)*1+3*i+1] = 2.*dbasismini[1][i];
+		Bprime[(3*7+6)*1+3*i+2] = 0.;
+		Bprime[(3*7+6)*2+3*i+0] = dbasismini[1][i];
+		Bprime[(3*7+6)*2+3*i+1] = dbasismini[0][i];
+		Bprime[(3*7+6)*2+3*i+2] = 0.;
+	}
+
+	for(i=0;i<1;i++){ //Add zeros for the bubble function
+		Bprime[(3*7+6)*0+3*(6+i)+0] = 0.;
+		Bprime[(3*7+6)*0+3*(6+i)+1] = 0.;
+		Bprime[(3*7+6)*0+3*(6+i)+2] = 0.;
+		Bprime[(3*7+6)*1+3*(6+i)+0] = 0.;
+		Bprime[(3*7+6)*1+3*(6+i)+1] = 0.;
+		Bprime[(3*7+6)*1+3*(6+i)+2] = 0.;
+		Bprime[(3*7+6)*2+3*(6+i)+0] = 0.;
+		Bprime[(3*7+6)*2+3*(6+i)+1] = 0.;
+		Bprime[(3*7+6)*2+3*(6+i)+2] = 0.;
+	}
+
+	for(i=0;i<6;i++){ //last column not for the bubble function
+		Bprime[(3*7+6)*0+7*3+i] = 0.;
+		Bprime[(3*7+6)*1+7*3+i] = 0.;
+		Bprime[(3*7+6)*2+7*3+i] = 0.;
+	}
+}/*}}}*/
+void StressbalanceAnalysis::GetBSSAFSTria(IssmDouble* B,Element* element,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
+	/*Compute B  matrix. B=[B1 B2 B3] where Bi is of size 3*NDOF2. 
+	 * For node i, Bi can be expressed in the actual coordinate system
+	 * by: 
+	 *       Bi=[   dN/dx         0     ]
+	 *          [       0       dN/dy   ]
+	 *          [  1/2*dN/dy  1/2*dN/dx ]
+	 * where N is the finiteelement function for node i.
+	 *
+	 * We assume B has been allocated already, of size: 3x(NDOF2*numnodes)
+	 */
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Get nodal functions derivatives*/
+	IssmDouble* dbasis=xNew<IssmDouble>(2*numnodes);
+	element->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+
+	/*Build B': */
+	for(int i=0;i<numnodes;i++){
+		B[2*numnodes*0+2*i+0] = dbasis[0*numnodes+i];
+		B[2*numnodes*0+2*i+1] = 0.;
+		B[2*numnodes*1+2*i+0] = 0.;
+		B[2*numnodes*1+2*i+1] = dbasis[1*numnodes+i];
+		B[2*numnodes*2+2*i+0] = 0.5*dbasis[1*numnodes+i];
+		B[2*numnodes*2+2*i+1] = 0.5*dbasis[0*numnodes+i];
+	}
+
+	/*Clean-up*/
+	xDelete<IssmDouble>(dbasis);
+}/*}}}*/
+void StressbalanceAnalysis::GetBprimeSSAFSTria(IssmDouble* Bprime,Element* element,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
+	/*Compute Bprime  matrix. Bprime=[Bprime1 Bprime2 Bprime3] where Bprimei is of size 3*NDOF2. 
+	 * For node i, Bprimei can be expressed in the actual coordinate system
+	 * by: 
+	 *       Bprimei=[  dN/dx    0   ]
+	 *               [    0    dN/dy ]
+	 *               [  dN/dy  dN/dx ]
+	 N               [  dN/dx  dN/dy ]
+	 * where N is the finiteelement function for node i.
+	 *
+	 * We assume Bprime has been allocated already, of size: 3x(NDOF2*numnodes)
+	 */
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Get nodal functions*/
+	IssmDouble* dbasis=xNew<IssmDouble>(2*numnodes);
+	element->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+
+	/*Build Bprime: */
+	for(int i=0;i<numnodes;i++){
+		Bprime[2*numnodes*0+2*i+0] = dbasis[0*numnodes+i];
+		Bprime[2*numnodes*0+2*i+1] = 0.;
+		Bprime[2*numnodes*1+2*i+0] = 0.;
+		Bprime[2*numnodes*1+2*i+1] = dbasis[1*numnodes+i];
+		Bprime[2*numnodes*2+2*i+0] = dbasis[1*numnodes+i];
+		Bprime[2*numnodes*2+2*i+1] = dbasis[0*numnodes+i];
+		Bprime[2*numnodes*3+2*i+0] = dbasis[0*numnodes+i];
+		Bprime[2*numnodes*3+2*i+1] = dbasis[1*numnodes+i];
+	}
+
+	/*Clean-up*/
+	xDelete<IssmDouble>(dbasis);
+}/*}}}*/
+void StressbalanceAnalysis::GetLSSAFS(IssmDouble* LFS,Element* element,Gauss* gauss_in){/*{{{*/
+	/*
+	 * Compute L  matrix. L=[L1 L2 L3] where Li is square and of size numdof. 
+	 * For node i, Li can be expressed in the actual coordinate system
+	 * by: 
+	 *       Li=[ h    0 ]
+	 *	 	      [ 0    h ]
+	 *	 	      [ h    0 ]
+	 *	 	      [ 0    h ]
+	 *	 	      [ h    0 ]
+	 *	 	      [ 0    h ]
+	 *	 	      [ h    0 ]
+	 *	 	      [ 0    h ]
+	 * where h is the interpolation function for node i.
+	 */
+
+	int num_dof=2;
+	IssmDouble L1L2l3[3];
+
+	/*Cast gauss to GaussPenta*/
+	_assert_(gauss_in->Enum()==GaussPentaEnum);
+	GaussPenta* gauss = dynamic_cast<GaussPenta*>(gauss_in);
+
+	/*Get L1L2l3 in actual coordinate system: */
+	L1L2l3[0]=gauss->coord1*(1-gauss->coord4)/2.0;
+	L1L2l3[1]=gauss->coord2*(1-gauss->coord4)/2.0;
+	L1L2l3[2]=gauss->coord3*(1-gauss->coord4)/2.0;
+
+	/*Build LFS: */
+	for(int i=0;i<3;i++){
+		LFS[num_dof*3*0+num_dof*i+0] = L1L2l3[i];
+		LFS[num_dof*3*0+num_dof*i+1] = 0;
+		LFS[num_dof*3*1+num_dof*i+0] = 0;
+		LFS[num_dof*3*1+num_dof*i+1] = L1L2l3[i];
+		LFS[num_dof*3*2+num_dof*i+0] = L1L2l3[i];
+		LFS[num_dof*3*2+num_dof*i+1] = 0;
+		LFS[num_dof*3*3+num_dof*i+0] = 0;
+		LFS[num_dof*3*3+num_dof*i+1] = L1L2l3[i];
+		LFS[num_dof*3*4+num_dof*i+0] = L1L2l3[i];
+		LFS[num_dof*3*4+num_dof*i+1] = 0;
+		LFS[num_dof*3*5+num_dof*i+0] = 0;
+		LFS[num_dof*3*5+num_dof*i+1] = L1L2l3[i];
+		LFS[num_dof*3*6+num_dof*i+0] = L1L2l3[i];
+		LFS[num_dof*3*6+num_dof*i+1] = 0;
+		LFS[num_dof*3*7+num_dof*i+0] = 0;
+		LFS[num_dof*3*7+num_dof*i+1] = L1L2l3[i];
+	}
+}/*}}}*/
+void StressbalanceAnalysis::GetLprimeSSAFS(IssmDouble* LprimeFS,Element* element,IssmDouble* xyz_list,Gauss* gauss_in){/*{{{*/
+	/* Compute Lprime  matrix. Lprime=[Lp1 Lp2 Lp3] where Lpi is square and of size numdof. 
+	 * For node i, Lpi can be expressed in the actual coordinate system
+	 * by: 
+	 *       Lpi=[ h    0    0   0]
+	 *		       [ 0    h    0   0]
+	 *		       [ 0    0    h   0]
+	 *		       [ 0    0    h   0]
+	 *		       [ 0    0  dh/dz 0]
+	 *		       [ 0    0  dh/dz 0]
+	 *           [ 0    0    0   h]
+	 *           [ 0    0    0   h]
+	 * where h is the interpolation function for node i.
+	 */
+	int num_dof=3;
+	int num_dof_vel=3*7;
+	int num_dof_total=3*7+1*6;
+	IssmDouble L1L2l3[3];
+	IssmDouble dbasis[3][6];
+
+	/*Cast gauss to GaussPenta*/
+	_assert_(gauss_in->Enum()==GaussPentaEnum);
+	GaussPenta* gauss = dynamic_cast<GaussPenta*>(gauss_in);
+
+	/*Get L1L2l3 in actual coordinate system: */
+	L1L2l3[0]=gauss->coord1*(1-gauss->coord4)/2.0;
+	L1L2l3[1]=gauss->coord2*(1-gauss->coord4)/2.0;
+	L1L2l3[2]=gauss->coord3*(1-gauss->coord4)/2.0;
+
+	element->NodalFunctionsP1Derivatives(&dbasis[0][0],xyz_list,gauss);
+
+	/*Build LprimeFS: */
+	for(int i=0;i<3;i++){
+		LprimeFS[num_dof_total*0+num_dof*i+0] = L1L2l3[i];
+		LprimeFS[num_dof_total*0+num_dof*i+1] = 0.;
+		LprimeFS[num_dof_total*0+num_dof*i+2] = 0.;
+		LprimeFS[num_dof_total*1+num_dof*i+0] = 0.;
+		LprimeFS[num_dof_total*1+num_dof*i+1] = L1L2l3[i];
+		LprimeFS[num_dof_total*1+num_dof*i+2] = 0.;
+		LprimeFS[num_dof_total*2+num_dof*i+0] = 0.;
+		LprimeFS[num_dof_total*2+num_dof*i+1] = 0.;
+		LprimeFS[num_dof_total*2+num_dof*i+2] = L1L2l3[i];
+		LprimeFS[num_dof_total*3+num_dof*i+0] = 0.;
+		LprimeFS[num_dof_total*3+num_dof*i+1] = 0.;
+		LprimeFS[num_dof_total*3+num_dof*i+2] = L1L2l3[i];
+		LprimeFS[num_dof_total*4+num_dof*i+0] = 0.;
+		LprimeFS[num_dof_total*4+num_dof*i+1] = 0.;
+		LprimeFS[num_dof_total*4+num_dof*i+2] = dbasis[2][i];
+		LprimeFS[num_dof_total*5+num_dof*i+0] = 0.;
+		LprimeFS[num_dof_total*5+num_dof*i+1] = 0.;
+		LprimeFS[num_dof_total*5+num_dof*i+2] = dbasis[2][i];
+		LprimeFS[num_dof_total*6+num_dof*i+0] = 0.;
+		LprimeFS[num_dof_total*6+num_dof*i+1] = 0.;
+		LprimeFS[num_dof_total*6+num_dof*i+2] = 0.;
+		LprimeFS[num_dof_total*7+num_dof*i+0] = 0.;
+		LprimeFS[num_dof_total*7+num_dof*i+1] = 0.;
+		LprimeFS[num_dof_total*7+num_dof*i+2] = 0.;
+	}
+	for(int i=3;i<7;i++){
+		LprimeFS[num_dof_total*0+num_dof*i+0] = 0.;
+		LprimeFS[num_dof_total*0+num_dof*i+1] = 0.;
+		LprimeFS[num_dof_total*0+num_dof*i+2] = 0.;
+		LprimeFS[num_dof_total*1+num_dof*i+0] = 0.;
+		LprimeFS[num_dof_total*1+num_dof*i+1] = 0.;
+		LprimeFS[num_dof_total*1+num_dof*i+2] = 0.;
+		LprimeFS[num_dof_total*2+num_dof*i+0] = 0.;
+		LprimeFS[num_dof_total*2+num_dof*i+1] = 0.;
+		LprimeFS[num_dof_total*2+num_dof*i+2] = 0.;
+		LprimeFS[num_dof_total*3+num_dof*i+0] = 0.;
+		LprimeFS[num_dof_total*3+num_dof*i+1] = 0.;
+		LprimeFS[num_dof_total*3+num_dof*i+2] = 0.;
+		LprimeFS[num_dof_total*4+num_dof*i+0] = 0.;
+		LprimeFS[num_dof_total*4+num_dof*i+1] = 0.;
+		LprimeFS[num_dof_total*4+num_dof*i+2] = 0.;
+		LprimeFS[num_dof_total*5+num_dof*i+0] = 0.;
+		LprimeFS[num_dof_total*5+num_dof*i+1] = 0.;
+		LprimeFS[num_dof_total*5+num_dof*i+2] = 0.;
+		LprimeFS[num_dof_total*6+num_dof*i+0] = 0.;
+		LprimeFS[num_dof_total*6+num_dof*i+1] = 0.;
+		LprimeFS[num_dof_total*6+num_dof*i+2] = 0.;
+		LprimeFS[num_dof_total*7+num_dof*i+0] = 0.;
+		LprimeFS[num_dof_total*7+num_dof*i+1] = 0.;
+		LprimeFS[num_dof_total*7+num_dof*i+2] = 0.;
+	}
+	for(int i=0;i<3;i++){
+		LprimeFS[num_dof_total*0+num_dof_vel+i] = 0.;
+		LprimeFS[num_dof_total*1+num_dof_vel+i] = 0.;
+		LprimeFS[num_dof_total*2+num_dof_vel+i] = 0.;
+		LprimeFS[num_dof_total*3+num_dof_vel+i] = 0.;
+		LprimeFS[num_dof_total*4+num_dof_vel+i] = 0.;
+		LprimeFS[num_dof_total*5+num_dof_vel+i] = 0.;
+		LprimeFS[num_dof_total*6+num_dof_vel+i] = L1L2l3[i];
+		LprimeFS[num_dof_total*7+num_dof_vel+i] = L1L2l3[i];
+	}
+	for(int i=3;i<6;i++){
+		LprimeFS[num_dof_total*0+num_dof_vel+i] = 0.;
+		LprimeFS[num_dof_total*1+num_dof_vel+i] = 0.;
+		LprimeFS[num_dof_total*2+num_dof_vel+i] = 0.;
+		LprimeFS[num_dof_total*3+num_dof_vel+i] = 0.;
+		LprimeFS[num_dof_total*4+num_dof_vel+i] = 0.;
+		LprimeFS[num_dof_total*5+num_dof_vel+i] = 0.;
+		LprimeFS[num_dof_total*6+num_dof_vel+i] = 0.;
+		LprimeFS[num_dof_total*7+num_dof_vel+i] = 0.;
+	}
+}/*}}}*/
+void StressbalanceAnalysis::GetLFSSSA(IssmDouble* LFS,Element* element,Gauss* gauss_in){/*{{{*/
+	/* Compute L  matrix. L=[L1 L2 L3] where Li is square and of size numdof. 
+	 * For node i, Li can be expressed in the actual coordinate system
+	 * by: 
+	 *       Li=[ h    0    0 ]
+	 *	 	      [ 0    h    0 ]
+	 *		      [ 0    0    h ]
+	 *		      [ 0    0    h ]
+	 * where h is the interpolation function for node i.
+	 */
+
+	int num_dof=3;
+	IssmDouble L1L2l3[3];
+
+	/*Cast gauss to GaussPenta*/
+	_assert_(gauss_in->Enum()==GaussPentaEnum);
+	GaussPenta* gauss = dynamic_cast<GaussPenta*>(gauss_in);
+
+	/*Get L1L2l3 in actual coordinate system: */
+	L1L2l3[0]=gauss->coord1*(1-gauss->coord4)/2.0;
+	L1L2l3[1]=gauss->coord2*(1-gauss->coord4)/2.0;
+	L1L2l3[2]=gauss->coord3*(1-gauss->coord4)/2.0;
+
+	/*Build LFS: */
+	for(int i=0;i<3;i++){
+		LFS[num_dof*3*0+num_dof*i+0] = L1L2l3[i];
+		LFS[num_dof*3*0+num_dof*i+1] = 0.;
+		LFS[num_dof*3*0+num_dof*i+2] = 0.;
+		LFS[num_dof*3*1+num_dof*i+0] = 0.;
+		LFS[num_dof*3*1+num_dof*i+1] = L1L2l3[i];
+		LFS[num_dof*3*1+num_dof*i+2] = 0.;
+		LFS[num_dof*3*2+num_dof*i+0] = 0.;
+		LFS[num_dof*3*2+num_dof*i+1] = 0.;
+		LFS[num_dof*3*2+num_dof*i+2] = L1L2l3[i];
+		LFS[num_dof*3*3+num_dof*i+0] = 0.;
+		LFS[num_dof*3*3+num_dof*i+1] = 0.;
+		LFS[num_dof*3*3+num_dof*i+2] = L1L2l3[i];
+	}
+}/*}}}*/
+void StressbalanceAnalysis::GetLprimeFSSSA(IssmDouble* LprimeFS,Element* element,IssmDouble* xyz_list,Gauss* gauss_in){/*{{{*/
+	/* Compute Lprime  matrix. Lprime=[Lp1 Lp2 Lp3] where Lpi is square and of size numdof. 
+	 * For node i, Lpi can be expressed in the actual coordinate system
+	 * by: 
+	 *       Lpi=[ h    0 ]
+	 *		       [ 0    h ]
+	 *		       [ h    0 ]
+	 *		       [ 0    h ]
+	 * where h is the interpolation function for node i.
+	 */
+	int num_dof=2;
+	IssmDouble L1L2l3[3];
+
+	/*Cast gauss to GaussPenta*/
+	_assert_(gauss_in->Enum()==GaussPentaEnum);
+	GaussPenta* gauss = dynamic_cast<GaussPenta*>(gauss_in);
+
+	/*Get L1L2l3 in actual coordinate system: */
+	L1L2l3[0]=gauss->coord1*(1-gauss->coord4)/2.0;
+	L1L2l3[1]=gauss->coord2*(1-gauss->coord4)/2.0;
+	L1L2l3[2]=gauss->coord3*(1-gauss->coord4)/2.0;
+
+	/*Build LprimeFS: */
+	for(int i=0;i<3;i++){
+		LprimeFS[num_dof*3*0+num_dof*i+0] = L1L2l3[i];
+		LprimeFS[num_dof*3*0+num_dof*i+1] = 0.;
+		LprimeFS[num_dof*3*1+num_dof*i+0] = 0.;
+		LprimeFS[num_dof*3*1+num_dof*i+1] = L1L2l3[i];
+		LprimeFS[num_dof*3*2+num_dof*i+0] = L1L2l3[i];
+		LprimeFS[num_dof*3*2+num_dof*i+1] = 0.;
+		LprimeFS[num_dof*3*3+num_dof*i+0] = 0.;
+		LprimeFS[num_dof*3*3+num_dof*i+1] = L1L2l3[i];
+	}
+}/*}}}*/
+void StressbalanceAnalysis::InputUpdateFromSolutionHOFS(IssmDouble* solution,Element* element){/*{{{*/
+
+	int         i;
+	IssmDouble  rho_ice,g,FSreconditioning;
+	int*        doflistHO  = NULL;
+	int*        doflistFSv = NULL;
+	int*        doflistFSp = NULL;
+
+	/*Only works with Penta for now*/
+	if(element->ObjectEnum()!=PentaEnum) _error_("Coupling not supported for "<<EnumToStringx(element->ObjectEnum()));
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes  = 6;
+	int numdofHO  = 6*2;
+	int numdofFSv = 6*3;
+	int numdofFSp = 6;
+
+	/*Fetch dof list and allocate solution vectors*/
+	element->GetDofList(&doflistFSv,FSvelocityEnum,GsetEnum);
+	element->GetDofList(&doflistHO, HOApproximationEnum, GsetEnum);
+	element->GetDofListPressure(&doflistFSp,GsetEnum);
+	IssmDouble* HOvalues  = xNew<IssmDouble>(numdofHO);
+	IssmDouble* FSvalues  = xNew<IssmDouble>(numdofFSv+numdofFSp);
+	IssmDouble* vx        = xNew<IssmDouble>(numnodes);
+	IssmDouble* vy        = xNew<IssmDouble>(numnodes);
+	IssmDouble* vz        = xNew<IssmDouble>(numnodes);
+	IssmDouble* vzHO      = xNew<IssmDouble>(numnodes);
+	IssmDouble* vzFS      = xNew<IssmDouble>(numnodes);
+	IssmDouble* vel       = xNew<IssmDouble>(numnodes);
+	IssmDouble* pressure  = xNew<IssmDouble>(numnodes);
+
+	/*Prepare coordinate system list*/
+	int* cs_list = xNew<int>(2*numnodes);
+	for(i=0;i<numnodes;i++) cs_list[i]          = XYZEnum;
+	for(i=0;i<numnodes;i++) cs_list[numnodes+i] = PressureEnum;
+
+	/*Use the dof list to index into the solution vector: */
+	element->FindParam(&FSreconditioning,StressbalanceFSreconditioningEnum);
+	for(i=0;i<numdofHO ;i++) HOvalues[i]=solution[doflistHO[i]];
+	for(i=0;i<numdofFSv;i++) FSvalues[i]=solution[doflistFSv[i]];
+	for(i=0;i<numdofFSp;i++) FSvalues[numdofFSv+i]=solution[doflistFSp[i]];
+
+	/*Transform solution in Cartesian Space*/
+	element->TransformSolutionCoord(FSvalues,2*numnodes,cs_list);
+	element->TransformSolutionCoord(HOvalues,numnodes,XYEnum);
+
+	/*Ok, we have vx and vy in values, fill in vx and vy arrays: */
+	for(i=0;i<numnodes;i++){
+		vx[i]       = FSvalues[i*3+0]+HOvalues[i*2+0];
+		vy[i]       = FSvalues[i*3+1]+HOvalues[i*2+1];
+		vzFS[i]     = FSvalues[i*3+2];
+		pressure[i] = FSvalues[numnodes*3+i]*FSreconditioning;
+
+		/*Check solution*/
+		if(xIsNan<IssmDouble>(vx[i]))       _error_("NaN found in solution vector");
+		if(xIsNan<IssmDouble>(vy[i]))       _error_("NaN found in solution vector");
+		if(xIsNan<IssmDouble>(vzFS[i]))     _error_("NaN found in solution vector");
+		if(xIsNan<IssmDouble>(pressure[i])) _error_("NaN found in solution vector");
+	}
+
+	/*Get Vz and compute vel*/
+	element->GetInputListOnVertices(vzHO,VzHOEnum);
+	for(i=0;i<numnodes;i++){
+		vz[i] = vzHO[i]+vzFS[i];
+		vel[i]= sqrt(vx[i]*vx[i] + vy[i]*vy[i] + vz[i]*vz[i]);
+	}
+
+	/*Now, we have to move the previous Vx and Vy inputs  to old 
+	 * status, otherwise, we'll wipe them off: */
+	element->InputChangeName(VxEnum,VxPicardEnum);
+	element->InputChangeName(VyEnum,VyPicardEnum);
+	element->InputChangeName(VzEnum,VzPicardEnum);
+	element->InputChangeName(PressureEnum,PressurePicardEnum);
+
+	/*Add vx and vy as inputs to element: */
+	element->AddInput(VxEnum,vx,P1Enum);
+	element->AddInput(VyEnum,vy,P1Enum);
+	element->AddInput(VzEnum,vz,P1Enum);
+	element->AddInput(VzFSEnum,vzFS,P1Enum);
+	element->AddInput(VelEnum,vel,P1Enum);
+	element->AddInput(PressureEnum,pressure,P1Enum);
+
+	/*Free ressources:*/
+	xDelete<IssmDouble>(pressure);
+	xDelete<IssmDouble>(vel);
+	xDelete<IssmDouble>(vz);
+	xDelete<IssmDouble>(vzHO);
+	xDelete<IssmDouble>(vzFS);
+	xDelete<IssmDouble>(vy);
+	xDelete<IssmDouble>(vx);
+	xDelete<IssmDouble>(FSvalues);
+	xDelete<IssmDouble>(HOvalues);
+	xDelete<int>(doflistFSp);
+	xDelete<int>(doflistFSv);
+	xDelete<int>(doflistHO);
+	xDelete<int>(cs_list);
+}/*}}}*/
+void StressbalanceAnalysis::InputUpdateFromSolutionSSAFS(IssmDouble* solution,Element* element){/*{{{*/
+
+	int         i;
+	IssmDouble  rho_ice,g,FSreconditioning;
+	int*        doflistSSA  = NULL;
+	int*        doflistFSv = NULL;
+	int*        doflistFSp = NULL;
+
+	/*we have to add results of this element for FS and results from the element
+	 * at base for SSA, so we need to have the pointer toward the basal element*/
+	Element* basalelement=element->GetBasalElement();
+	if(basalelement->ObjectEnum()!=PentaEnum){
+		_error_("Coupling not supported for "<<EnumToStringx(basalelement->ObjectEnum()));
+	}
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes  = 6;
+	int numdof2d  = numnodes;
+	int numdofSSA = 6*2;
+	int numdofFSv = 6*3;
+	int numdofFSp = 6;
+
+	/*Fetch dof list and allocate solution vectors*/
+	element->GetDofList(&doflistFSv,FSvelocityEnum,GsetEnum);
+	element->GetDofListPressure(&doflistFSp,GsetEnum);
+	basalelement->GetDofList(&doflistSSA, SSAApproximationEnum, GsetEnum);
+	IssmDouble* SSAvalues  = xNew<IssmDouble>(numdofSSA);
+	IssmDouble* FSvalues  = xNew<IssmDouble>(numdofFSv+numdofFSp);
+	IssmDouble* vx        = xNew<IssmDouble>(numnodes);
+	IssmDouble* vy        = xNew<IssmDouble>(numnodes);
+	IssmDouble* vz        = xNew<IssmDouble>(numnodes);
+	IssmDouble* vzSSA      = xNew<IssmDouble>(numnodes);
+	IssmDouble* vzFS      = xNew<IssmDouble>(numnodes);
+	IssmDouble* vel       = xNew<IssmDouble>(numnodes);
+	IssmDouble* pressure  = xNew<IssmDouble>(numnodes);
+
+	/*Prepare coordinate system list*/
+	int* cs_list = xNew<int>(2*numnodes);
+	for(i=0;i<numnodes;i++) cs_list[i]          = XYZEnum;
+	for(i=0;i<numnodes;i++) cs_list[numnodes+i] = PressureEnum;
+
+	/*Use the dof list to index into the solution vector: */
+	element->FindParam(&FSreconditioning,StressbalanceFSreconditioningEnum);
+	for(i=0;i<numdof2d;i++){
+		SSAvalues[i]          = solution[doflistSSA[i]];
+		SSAvalues[i+numdof2d] = solution[doflistSSA[i]];
+	}
+	for(i=0;i<numdofFSv;i++) FSvalues[i]=solution[doflistFSv[i]];
+	for(i=0;i<numdofFSp;i++) FSvalues[numdofFSv+i]=solution[doflistFSp[i]];
+
+	/*Transform solution in Cartesian Space*/
+	element->TransformSolutionCoord(FSvalues,2*numnodes,cs_list);
+	element->TransformSolutionCoord(SSAvalues,numnodes,XYEnum);
+
+	/*Ok, we have vx and vy in values, fill in vx and vy arrays: */
+
+	for(i=0;i<numnodes;i++){
+		vx[i]       = FSvalues[i*3+0]+SSAvalues[i*2+0];
+		vy[i]       = FSvalues[i*3+1]+SSAvalues[i*2+1];
+		vzFS[i]     = FSvalues[i*3+2];
+		pressure[i] = FSvalues[numnodes*3+i]*FSreconditioning;
+
+		/*Check solution*/
+		if(xIsNan<IssmDouble>(vx[i]))       _error_("NaN found in solution vector");
+		if(xIsNan<IssmDouble>(vy[i]))       _error_("NaN found in solution vector");
+		if(xIsNan<IssmDouble>(vzFS[i]))     _error_("NaN found in solution vector");
+		if(xIsNan<IssmDouble>(pressure[i])) _error_("NaN found in solution vector");
+	}
+
+	/*Get Vz and compute vel*/
+	element->GetInputListOnVertices(vzSSA,VzSSAEnum);
+	for(i=0;i<numnodes;i++){
+		vz[i] = vzSSA[i]+vzFS[i];
+		vel[i]= sqrt(vx[i]*vx[i] + vy[i]*vy[i] + vz[i]*vz[i]);
+	}
+
+	/*Now, we have to move the previous Vx and Vy inputs  to old 
+	 * status, otherwise, we'll wipe them off: */
+	element->InputChangeName(VxEnum,VxPicardEnum);
+	element->InputChangeName(VyEnum,VyPicardEnum);
+	element->InputChangeName(VzEnum,VzPicardEnum);
+	element->InputChangeName(PressureEnum,PressurePicardEnum);
+
+	/*Add vx and vy as inputs to element: */
+	element->AddInput(VxEnum,vx,P1Enum);
+	element->AddInput(VyEnum,vy,P1Enum);
+	element->AddInput(VzEnum,vz,P1Enum);
+	element->AddInput(VzFSEnum,vzFS,P1Enum);
+	element->AddInput(VelEnum,vel,P1Enum);
+	element->AddInput(PressureEnum,pressure,P1Enum);
+
+	/*Free ressources:*/
+	xDelete<IssmDouble>(pressure);
+	xDelete<IssmDouble>(vel);
+	xDelete<IssmDouble>(vz);
+	xDelete<IssmDouble>(vzSSA);
+	xDelete<IssmDouble>(vzFS);
+	xDelete<IssmDouble>(vy);
+	xDelete<IssmDouble>(vx);
+	xDelete<IssmDouble>(FSvalues);
+	xDelete<IssmDouble>(SSAvalues);
+	xDelete<int>(doflistFSp);
+	xDelete<int>(doflistFSv);
+	xDelete<int>(doflistSSA);
+	xDelete<int>(cs_list);
+}/*}}}*/
+void StressbalanceAnalysis::InputUpdateFromSolutionSSAHO(IssmDouble* solution,Element* element){/*{{{*/
+
+	int         i,domaintype;
+	IssmDouble  rho_ice,g;
+	int*        SSAdoflist = NULL;
+	int*        HOdoflist  = NULL;
+	IssmDouble* xyz_list   = NULL;
+
+	/*we have to add results of this element for HO and results from the element
+	 * at base for SSA, so we need to have the pointer toward the basal element*/
+	Element* basalelement=element->GetBasalElement();
+	if(basalelement->ObjectEnum()!=PentaEnum){
+		_error_("Coupling not supported for "<<EnumToStringx(basalelement->ObjectEnum()));
+	}
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+	int numdof   = numnodes*2;
+	int numdof2d = numnodes;
+
+	/*Fetch dof list and allocate solution vectors*/
+	basalelement->GetDofList(&SSAdoflist,SSAApproximationEnum,GsetEnum);
+	element     ->GetDofList(&HOdoflist, HOApproximationEnum, GsetEnum);
+	IssmDouble* HOvalues  = xNew<IssmDouble>(numdof);
+	IssmDouble* SSAvalues = xNew<IssmDouble>(numdof);
+	IssmDouble* vx        = xNew<IssmDouble>(numnodes);
+	IssmDouble* vy        = xNew<IssmDouble>(numnodes);
+	IssmDouble* vz        = xNew<IssmDouble>(numnodes);
+	IssmDouble* vel       = xNew<IssmDouble>(numnodes);
+	IssmDouble* pressure  = xNew<IssmDouble>(numnodes);
+	IssmDouble* surface   = xNew<IssmDouble>(numnodes);
+
+	/*Use the dof list to index into the solution vector: */
+	for(i=0;i<numdof2d;i++){
+		HOvalues[i]  = solution[HOdoflist[i]];
+		SSAvalues[i] = solution[SSAdoflist[i]];
+	}
+	for(i=numdof2d;i<numdof;i++){
+		HOvalues[i]  = solution[HOdoflist[i]];
+		SSAvalues[i] = SSAvalues[i-numdof2d];
+	}
+
+	/*Transform solution in Cartesian Space*/
+	basalelement->TransformSolutionCoord(SSAvalues,XYEnum);
+	element->TransformSolutionCoord(HOvalues,XYEnum);
+
+	/*Ok, we have vx and vy in values, fill in vx and vy arrays: */
+	for(i=0;i<numnodes;i++){
+		vx[i]=SSAvalues[i*2+0]+HOvalues[i*2+0];
+		vy[i]=SSAvalues[i*2+1]+HOvalues[i*2+1];
+
+		/*Check solution*/
+		if(xIsNan<IssmDouble>(vx[i])) _error_("NaN found in solution vector");
+		if(xIsNan<IssmDouble>(vy[i])) _error_("NaN found in solution vector");
+	}
+
+	/*Get Vz and compute vel*/
+	element->GetInputListOnNodes(&vz[0],VzEnum,0.);
+	for(i=0;i<numnodes;i++) vel[i]=sqrt(vx[i]*vx[i] + vy[i]*vy[i] + vz[i]*vz[i]);
+
+	/*For pressure: we have not computed pressure in this analysis, for this element. We are in 2D, 
+	 *so the pressure is just the pressure at the bedrock: */
+	rho_ice = element->GetMaterialParameter(MaterialsRhoIceEnum);
+	g       = element->GetMaterialParameter(ConstantsGEnum);
+	element->GetVerticesCoordinates(&xyz_list);
+	element->GetInputListOnNodes(&surface[0],SurfaceEnum);
+	for(i=0;i<numnodes;i++) pressure[i]=rho_ice*g*(surface[i]-xyz_list[i*3+2]);
+
+	/*Now, we have to move the previous Vx and Vy inputs  to old 
+	 * status, otherwise, we'll wipe them off: */
+	element->InputChangeName(VxEnum,VxPicardEnum);
+	element->InputChangeName(VyEnum,VyPicardEnum);
+	element->InputChangeName(PressureEnum,PressurePicardEnum);
+
+	/*Add vx and vy as inputs to element: */
+	element->AddInput(VxEnum,vx,P1Enum);
+	element->AddInput(VyEnum,vy,P1Enum);
+	element->AddInput(VelEnum,vel,P1Enum);
+	element->AddInput(PressureEnum,pressure,P1Enum);
+
+	/*Free ressources:*/
+	xDelete<IssmDouble>(surface);
+	xDelete<IssmDouble>(pressure);
+	xDelete<IssmDouble>(vel);
+	xDelete<IssmDouble>(vz);
+	xDelete<IssmDouble>(vy);
+	xDelete<IssmDouble>(vx);
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(SSAvalues);
+	xDelete<IssmDouble>(HOvalues);
+	xDelete<int>(SSAdoflist);
+	xDelete<int>(HOdoflist);
+}/*}}}*/
Index: /issm/trunk/src/c/analyses/StressbalanceAnalysis.h
===================================================================
--- /issm/trunk/src/c/analyses/StressbalanceAnalysis.h	(revision 17805)
+++ /issm/trunk/src/c/analyses/StressbalanceAnalysis.h	(revision 17806)
@@ -11,6 +11,7 @@
 class StressbalanceAnalysis: public Analysis{
 
-	public:
-		int  DofsPerNode(int** doflist,int meshtype,int approximation);
+  public:
+		/*Model processing*/
+		int  DofsPerNode(int** doflist,int domaintype,int approximation);
 		void UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum);
 		void UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);
@@ -18,4 +19,104 @@
 		void CreateConstraints(Constraints* constraints,IoModel* iomodel);
 		void CreateLoads(Loads* loads, IoModel* iomodel);
+
+		/*Finite element Analysis*/
+		void           Core(FemModel* femmodel);
+		ElementVector* CreateDVector(Element* element);
+		ElementMatrix* CreateJacobianMatrix(Element* element);
+		ElementMatrix* CreateKMatrix(Element* element);
+		ElementVector* CreatePVector(Element* element);
+		void GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element);
+		void GetSolutionFromInputsHoriz(Vector<IssmDouble>* solution,Element* element);
+		void InputUpdateFromSolution(IssmDouble* solution,Element* element);
+		void UpdateConstraints(FemModel* femmodel);
+
+		/*SSA*/
+		ElementMatrix* CreateJacobianMatrixSSA(Element* element);
+		ElementMatrix* CreateKMatrixSSA(Element* element);
+		ElementMatrix* CreateKMatrixSSAViscous(Element* element);
+		ElementMatrix* CreateKMatrixSSAFriction(Element* element);
+		ElementVector* CreatePVectorSSA(Element* element);
+		ElementVector* CreatePVectorSSADrivingStress(Element* element);
+		ElementVector* CreatePVectorSSAFront(Element* element);
+		void GetBSSA(IssmDouble* B,Element* element,int dim,IssmDouble* xyz_list,Gauss* gauss);
+		void GetBSSAprime(IssmDouble* B,Element* element,int dim,IssmDouble* xyz_list,Gauss* gauss);
+		void GetBSSAFriction(IssmDouble* B,Element* element,int dim,IssmDouble* xyz_list,Gauss* gauss);
+		void InputUpdateFromSolutionSSA(IssmDouble* solution,Element* element);
+		/*L1L2*/
+		ElementMatrix* CreateKMatrixL1L2(Element* element);
+		ElementMatrix* CreateKMatrixL1L2Viscous(Element* element);
+		ElementMatrix* CreateKMatrixL1L2Friction(Element* element);
+		ElementVector* CreatePVectorL1L2(Element* element);
+		ElementVector* CreatePVectorL1L2DrivingStress(Element* element);
+		ElementVector* CreatePVectorL1L2Front(Element* element);
+		void InputUpdateFromSolutionL1L2(IssmDouble* solution,Element* element);
+		/*HO*/
+		ElementMatrix* CreateJacobianMatrixHO(Element* element);
+		ElementMatrix* CreateKMatrixHO(Element* element);
+		ElementMatrix* CreateKMatrixHOViscous(Element* element);
+		ElementMatrix* CreateKMatrixHOFriction(Element* element);
+		ElementVector* CreatePVectorHO(Element* element);
+		ElementVector* CreatePVectorHODrivingStress(Element* element);
+		ElementVector* CreatePVectorHOFront(Element* element);
+		void GetBHO(IssmDouble* B,Element* element,int dim,IssmDouble* xyz_list,Gauss* gauss);
+		void GetBHOprime(IssmDouble* B,Element* element,int dim,IssmDouble* xyz_list,Gauss* gauss);
+		void GetBHOFriction(IssmDouble* B,Element* element,int dim,IssmDouble* xyz_list,Gauss* gauss);
+		void InputUpdateFromSolutionHO(IssmDouble* solution,Element* element);
+		/*FS*/
+		ElementVector* CreateDVectorFS(Element* element);
+		ElementMatrix* CreateJacobianMatrixFS(Element* element);
+		ElementMatrix* CreateKMatrixFS(Element* element);
+		ElementMatrix* CreateKMatrixFSViscousXTH(Element* element);
+		ElementMatrix* CreateKMatrixFSViscous(Element* element);
+		ElementMatrix* CreateKMatrixFSFriction(Element* element);
+		ElementMatrix* CreateKMatrixFSShelf(Element* element);
+		ElementVector* CreatePVectorFS(Element* element);
+		ElementVector* CreatePVectorFSViscous(Element* element);
+		ElementVector* CreatePVectorFSViscousXTH(Element* element);
+		ElementVector* CreatePVectorFSShelf(Element* element);
+		ElementVector* CreatePVectorFSFront(Element* element);
+		void GetBFS(IssmDouble* B,Element* element,int dim,IssmDouble* xyz_list,Gauss* gauss);
+		void GetBFSprime(IssmDouble* B,Element* element,int dim,IssmDouble* xyz_list,Gauss* gauss);
+		void GetBFSFriction(IssmDouble* B,Element* element,int dim,IssmDouble* xyz_list,Gauss* gauss);
+		void GetSolutionFromInputsFS(Vector<IssmDouble>* solution,Element* element);
+		void InputUpdateFromSolutionFS(IssmDouble* solution,Element* element);
+		void InputUpdateFromSolutionFSXTH_d(Elements* elements,Parameters* parameters);
+		void InputUpdateFromSolutionFSXTH_tau(Elements* elements,Parameters* parameters);
+		void InitializeXTH(Elements* elements,Parameters* parameters);
+		/*Coupling*/
+		ElementMatrix* CreateKMatrixSSA3d(Element* element);
+		ElementMatrix* CreateKMatrixSSA3dFriction(Element* element);
+		ElementMatrix* CreateKMatrixSSA3dViscous(Element* element);
+		ElementMatrix* CreateKMatrixHOFS(Element* element);
+		ElementMatrix* CreateKMatrixSSAHO(Element* element);
+		ElementMatrix* CreateKMatrixSSAFS(Element* element);
+		ElementMatrix* CreateKMatrixCouplingHOFS(Element* element);
+		ElementMatrix* CreateKMatrixCouplingSSAHO(Element* element);
+		ElementMatrix* CreateKMatrixCouplingSSAHOFriction(Element* element);
+		ElementMatrix* CreateKMatrixCouplingSSAHOViscous(Element* element);
+		ElementMatrix* CreateKMatrixCouplingSSAFS(Element* element);
+		ElementMatrix* CreateKMatrixCouplingSSAFSFriction(Element* element);
+		ElementMatrix* CreateKMatrixCouplingSSAFSViscous(Element* element);
+		ElementVector* CreatePVectorSSAHO(Element* element);
+		ElementVector* CreatePVectorSSAFS(Element* element);
+		ElementVector* CreatePVectorCouplingSSAFS(Element* element);
+		ElementVector* CreatePVectorCouplingSSAFSFriction(Element* element);
+		ElementVector* CreatePVectorCouplingSSAFSViscous(Element* element);
+		ElementVector* CreatePVectorHOFS(Element* element);
+		ElementVector* CreatePVectorCouplingHOFS(Element* element);
+		ElementVector* CreatePVectorCouplingHOFSFriction(Element* element);
+		ElementVector* CreatePVectorCouplingHOFSViscous(Element* element);
+		void GetBSSAHO(IssmDouble* B,Element* element,IssmDouble* xyz_list,Gauss* gauss);
+		void GetBSSAFS(IssmDouble* B,Element* element,IssmDouble* xyz_list,Gauss* gauss);
+		void GetBprimeSSAFS(IssmDouble* Bprime,Element* element,IssmDouble* xyz_list,Gauss* gauss);
+		void GetBSSAFSTria(IssmDouble* B,Element* element,IssmDouble* xyz_list,Gauss* gauss);
+		void GetBprimeSSAFSTria(IssmDouble* Bprime,Element* element,IssmDouble* xyz_list,Gauss* gauss);
+		void GetLFSSSA(IssmDouble* L,Element* element,Gauss* gauss);
+		void GetLSSAFS(IssmDouble* L,Element* element,Gauss* gauss);
+		void GetLprimeFSSSA(IssmDouble* Lprime,Element* element,IssmDouble* xyz_list,Gauss* gauss);
+		void GetLprimeSSAFS(IssmDouble* Lprime,Element* element,IssmDouble* xyz_list,Gauss* gauss);
+		void InputUpdateFromSolutionHOFS(IssmDouble* solution,Element* element);
+		void InputUpdateFromSolutionSSAFS(IssmDouble* solution,Element* element);
+		void InputUpdateFromSolutionSSAHO(IssmDouble* solution,Element* element);
 };
 #endif
Index: /issm/trunk/src/c/analyses/StressbalanceSIAAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/StressbalanceSIAAnalysis.cpp	(revision 17805)
+++ /issm/trunk/src/c/analyses/StressbalanceSIAAnalysis.cpp	(revision 17806)
@@ -4,7 +4,8 @@
 #include "../shared/shared.h"
 #include "../modules/modules.h"
+#include "../solutionsequences/solutionsequences.h"
 
 /*Model processing*/
-int  StressbalanceSIAAnalysis::DofsPerNode(int** doflist,int meshtype,int approximation){/*{{{*/
+int  StressbalanceSIAAnalysis::DofsPerNode(int** doflist,int domaintype,int approximation){/*{{{*/
 	return 2;
 }/*}}}*/
@@ -18,5 +19,7 @@
 	/*Fetch data needed: */
 	bool   isSIA;
+	bool   islevelset;
 	iomodel->Constant(&isSIA,FlowequationIsSIAEnum);
+	iomodel->Constant(&islevelset,TransientIslevelsetEnum);
 
 	/*Now, is the flag SIA on? otherwise, do nothing: */
@@ -36,4 +39,10 @@
 
 	iomodel->FetchDataToInput(elements,ThicknessEnum);
+	iomodel->FetchDataToInput(elements,FrictionCoefficientEnum);
+	if(islevelset){
+		iomodel->FetchDataToInput(elements,IceMaskNodeActivationEnum);
+		if(iomodel->domaintype!=Domain2DhorizontalEnum)
+			iomodel->FetchDataToInput(elements,MeshVertexonbaseEnum); // required for updating active nodes
+	}
 
 	/*Free data: */
@@ -54,6 +63,8 @@
 	/*First create nodes*/
 	int    lid=0;
-	iomodel->FetchData(6,MeshVertexonbedEnum,MeshVertexonsurfaceEnum,FlowequationBorderSSAEnum,FlowequationBorderFSEnum,
-				FlowequationVertexEquationEnum,StressbalanceReferentialEnum);
+	iomodel->FetchData(4,FlowequationBorderSSAEnum,FlowequationBorderFSEnum,FlowequationVertexEquationEnum,StressbalanceReferentialEnum);
+	if(iomodel->domaintype!=Domain2DhorizontalEnum){
+		iomodel->FetchData(2,MeshVertexonbaseEnum,MeshVertexonsurfaceEnum);
+	}
 
 	for(int i=0;i<iomodel->numberofvertices;i++){
@@ -73,5 +84,5 @@
 	}
 
-	iomodel->DeleteData(6,MeshVertexonbedEnum,MeshVertexonsurfaceEnum,FlowequationBorderSSAEnum,FlowequationBorderFSEnum,
+	iomodel->DeleteData(6,MeshVertexonbaseEnum,MeshVertexonsurfaceEnum,FlowequationBorderSSAEnum,FlowequationBorderFSEnum,
 				FlowequationVertexEquationEnum,StressbalanceReferentialEnum);
 
@@ -103,18 +114,18 @@
 			if (reCast<int,IssmDouble>(iomodel->Data(FlowequationVertexEquationEnum)[i])!=SIAApproximationEnum){
 
+				constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,0,0,StressbalanceSIAAnalysisEnum));
+				count++;
+
 				constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,1,0,StressbalanceSIAAnalysisEnum));
-				count++;
-
-				constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,2,0,StressbalanceSIAAnalysisEnum));
 				count++;
 			}
 			else{
 				if (!xIsNan<IssmDouble>(iomodel->Data(StressbalanceSpcvxEnum)[i])){
-					constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,1,iomodel->Data(StressbalanceSpcvxEnum)[i]/yts,StressbalanceSIAAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
+					constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,0,iomodel->Data(StressbalanceSpcvxEnum)[i]/yts,StressbalanceSIAAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
 					count++;
 				}
 
 				if (!xIsNan<IssmDouble>(iomodel->Data(StressbalanceSpcvyEnum)[i])){
-					constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,2,iomodel->Data(StressbalanceSpcvyEnum)[i]/yts,StressbalanceSIAAnalysisEnum)); //add count'th spc, on node i+1, setting dof 2 to vy
+					constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,1,iomodel->Data(StressbalanceSpcvyEnum)[i]/yts,StressbalanceSIAAnalysisEnum)); //add count'th spc, on node i+1, setting dof 2 to vy
 					count++;
 				}
@@ -132,2 +143,445 @@
 
 }/*}}}*/
+
+/*Finite Element Analysis*/
+void           StressbalanceSIAAnalysis::Core(FemModel* femmodel){/*{{{*/
+
+		if(VerboseSolution()) _printf0_("   computing SIA velocities\n");
+		femmodel->SetCurrentConfiguration(StressbalanceSIAAnalysisEnum);
+		solutionsequence_linear(femmodel);
+}/*}}}*/
+ElementVector* StressbalanceSIAAnalysis::CreateDVector(Element* element){/*{{{*/
+	/*Default, return NULL*/
+	return NULL;
+}/*}}}*/
+ElementMatrix* StressbalanceSIAAnalysis::CreateJacobianMatrix(Element* element){/*{{{*/
+_error_("Not implemented");
+}/*}}}*/
+ElementMatrix* StressbalanceSIAAnalysis::CreateKMatrix(Element* element){/*{{{*/
+
+	/* Check if ice in element */
+	if(!element->IsIceInElement()) return NULL;
+
+	int domaintype;
+	element->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DhorizontalEnum:
+			return CreateKMatrix2D(element);
+		case Domain3DEnum:
+			return CreateKMatrix3D(element);
+		default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
+	}
+}/*}}}*/
+ElementMatrix* StressbalanceSIAAnalysis::CreateKMatrix2D(Element* element){/*{{{*/
+
+	/* Check if ice in element */
+	if(!element->IsIceInElement()) return NULL;
+
+	/*Intermediaries */
+	IssmDouble connectivity;
+
+	/*Fetch number vertices for this element*/
+	int numvertices = element->GetNumberOfVertices();
+
+	/*Initialize Element vector*/
+	ElementMatrix* Ke=element->NewElementMatrix();
+	for(int iv=0;iv<numvertices;iv++){
+		connectivity=(IssmDouble)element->VertexConnectivity(iv);
+		Ke->values[(2*iv+0)*2*numvertices+(2*iv+0)]=1./connectivity;
+		Ke->values[(2*iv+1)*2*numvertices+(2*iv+1)]=1./connectivity;
+	}
+
+	/*Clean up and return*/
+	return Ke;
+}/*}}}*/
+ElementMatrix* StressbalanceSIAAnalysis::CreateKMatrix3D(Element* element){/*{{{*/
+
+	/* Check if ice in element */
+	if(!element->IsIceInElement()) return NULL;
+
+	/*Intermediaries */
+	int         i0,i1,j0,j1,nodeup,nodedown,numsegments;
+	IssmDouble  slope[2],connectivity[2],one0,one1;
+	int        *pairindices = NULL;
+
+	/*Fetch number vertices for this element*/
+	int numvertices = element->GetNumberOfVertices();
+	int numdof      = 2*numvertices;
+
+	/*Initialize Element vector*/
+	ElementMatrix* Ke=element->NewElementMatrix();
+
+	element->VerticalSegmentIndices(&pairindices,&numsegments);
+	for(int is=0;is<numsegments;is++){
+		nodedown = pairindices[is*2+0];
+		nodeup   = pairindices[is*2+1];
+		connectivity[0]=(IssmDouble)element->VertexConnectivity(nodedown);
+		connectivity[1]=(IssmDouble)element->VertexConnectivity(nodeup);
+		one0=1./connectivity[0];
+		one1=1./connectivity[1];
+
+		/*2 dofs of first node*/
+		i0=2*nodedown;  i1=2*nodedown+1;
+		/*2 dofs of second node*/
+		j0=2*nodeup;    j1=2*nodeup+1;
+
+		/*Create matrix for these two nodes*/
+		if(element->IsOnBase() && element->IsOnSurface()){
+			Ke->values[i0*numdof+i0] = +one0;
+			Ke->values[i1*numdof+i1] = +one0;
+			Ke->values[j0*numdof+i0] = -one1;
+			Ke->values[j0*numdof+j0] = +one1;
+			Ke->values[j1*numdof+i1] = -one1;
+			Ke->values[j1*numdof+j1] = +one1;
+		}
+		else if(element->IsOnBase()){
+			Ke->values[i0*numdof+i0] = one0;
+			Ke->values[i1*numdof+i1] = one0;
+			Ke->values[j0*numdof+i0] = -2.*one1;
+			Ke->values[j0*numdof+j0] = +2.*one1;
+			Ke->values[j1*numdof+i1] = -2.*one1;
+			Ke->values[j1*numdof+j1] = +2.*one1;
+		}
+		else if(element->IsOnSurface()){
+			Ke->values[j0*numdof+i0] = -one1;
+			Ke->values[j0*numdof+j0] = +one1;
+			Ke->values[j1*numdof+i1] = -one1;
+			Ke->values[j1*numdof+j1] = +one1;
+		}
+		else{ //node is on two horizontal layers and beams include the values only once, so the have to use half of the connectivity
+			Ke->values[j0*numdof+i0] = -2.*one1;
+			Ke->values[j0*numdof+j0] = +2.*one1;
+			Ke->values[j1*numdof+i1] = -2.*one1;
+			Ke->values[j1*numdof+j1] = +2.*one1;
+		}
+	}
+
+	/*Clean up and return*/
+	xDelete<int>(pairindices);
+	return Ke;
+}/*}}}*/
+ElementVector* StressbalanceSIAAnalysis::CreatePVector(Element* element){/*{{{*/
+
+	/* Check if ice in element */
+	if(!element->IsIceInElement()) return NULL;
+
+	int domaintype;
+	element->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DhorizontalEnum:
+			return CreatePVector2D(element);
+		case Domain3DEnum:
+			return CreatePVector3D(element);
+		default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
+	}
+}/*}}}*/
+ElementVector* StressbalanceSIAAnalysis::CreatePVector2D(Element* element){/*{{{*/
+
+	/* Check if ice in element */
+	if(!element->IsIceInElement()) return NULL;
+
+	/*Intermediaries */
+	int        frictionlaw = 1;
+	IssmDouble ub,vb,slope2,drag,thickness,surface,connectivity;
+	IssmDouble slope[2];
+
+	/*Fetch number vertices for this element*/
+	int numvertices = element->GetNumberOfVertices();
+
+	/*Initialize Element vector*/
+	ElementVector* pe=element->NewElementVector();
+
+	/*Retrieve all inputs and parameters*/
+	IssmDouble  rho_ice    = element->GetMaterialParameter(MaterialsRhoIceEnum);
+	IssmDouble  gravity    = element->GetMaterialParameter(ConstantsGEnum);
+	IssmDouble  n          = element->GetMaterialParameter(MaterialsRheologyNEnum);
+	IssmDouble  B          = element->GetMaterialParameter(MaterialsRheologyBbarEnum);
+	Input* slopex_input    = element->GetInput(SurfaceSlopeXEnum);        _assert_(slopex_input);
+	Input* slopey_input    = element->GetInput(SurfaceSlopeYEnum);        _assert_(slopey_input);
+	Input* thickness_input = element->GetInput(ThicknessEnum);            _assert_(thickness_input);
+	Input* surface_input   = element->GetInput(SurfaceEnum);              _assert_(surface_input);
+	Input* drag_input      = element->GetInput(FrictionCoefficientEnum);  _assert_(drag_input);
+
+	Gauss* gauss=element->NewGauss();
+	for(int iv=0;iv<numvertices;iv++){
+		gauss->GaussVertex(iv);
+
+		connectivity=(IssmDouble)element->VertexConnectivity(iv);
+
+		thickness_input->GetInputValue(&thickness,gauss);
+		surface_input->GetInputValue(&surface,gauss);
+		drag_input->GetInputValue(&drag,gauss);
+		slopex_input->GetInputValue(&slope[0],gauss);
+		slopey_input->GetInputValue(&slope[1],gauss);
+		slope2=slope[0]*slope[0]+slope[1]*slope[1];
+
+		switch(frictionlaw){
+			case 1:
+				/*Payne 1995 (m = 1, B = 5e-3/yts = 1.58e-10  m/s/Pa*/
+				ub=-1.58*1.e-10*rho_ice*gravity*thickness*slope[0];
+				vb=-1.58*1.e-10*rho_ice*gravity*thickness*slope[1];
+				break;
+			case 2:
+				/*Ritz et al. 1996*/
+				ub=drag*(rho_ice*gravity*thickness)*(rho_ice*gravity*thickness)*slope[0]/sqrt(slope2);
+				vb=drag*(rho_ice*gravity*thickness)*(rho_ice*gravity*thickness)*slope[1]/sqrt(slope2);
+				break;
+			case 3:
+				/*Rutt et al. 2009*/
+				ub=-drag*rho_ice*gravity*thickness*slope[0];
+				vb=-drag*rho_ice*gravity*thickness*slope[1];
+				break;
+			case 4:
+				/*Henning Akesson*/
+				drag = -4e-15 * surface + 8.6e-12;
+				ub=-drag*rho_ice*gravity*thickness*slope[0];
+				vb=-drag*rho_ice*gravity*thickness*slope[1];
+				break;
+			default:
+				_error_("Not supported yet");
+		}
+
+		pe->values[2*iv+0]=(ub-2.*pow(rho_ice*gravity,n)*pow(slope2,((n-1.)/2.))*pow(thickness,n)/(pow(B,n)*(n+1))*slope[0])/connectivity;
+		pe->values[2*iv+1]=(vb-2.*pow(rho_ice*gravity,n)*pow(slope2,((n-1.)/2.))*pow(thickness,n)/(pow(B,n)*(n+1))*slope[1])/connectivity;
+	}
+
+	/*Clean up and return*/
+	delete gauss;
+	return pe;
+}/*}}}*/
+ElementVector* StressbalanceSIAAnalysis::CreatePVector3D(Element* element){/*{{{*/
+
+	/* Check if ice in element */
+	if(!element->IsIceInElement()) return NULL;
+
+	/*Intermediaries */
+	int         frictionlaw = 1;
+	int         nodeup,nodedown,numsegments;
+	IssmDouble  ub,vb,slope2,drag,surface,thickness,constant_part,z,Jdet;
+	IssmDouble  slope[2],connectivity[2],xyz_list_line[2][3];
+	IssmDouble *xyz_list = NULL;
+	int        *pairindices = NULL;
+
+	/*Fetch number vertices for this element*/
+	int numvertices = element->GetNumberOfVertices();
+
+	/*Initialize Element vector*/
+	ElementVector* pe=element->NewElementVector();
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+	IssmDouble  rho_ice    = element->GetMaterialParameter(MaterialsRhoIceEnum);
+	IssmDouble  gravity    = element->GetMaterialParameter(ConstantsGEnum);
+	IssmDouble  n          = element->GetMaterialParameter(MaterialsRheologyNEnum);
+	IssmDouble  B          = element->GetMaterialParameter(MaterialsRheologyBEnum);
+	Input* surface_input   = element->GetInput(SurfaceEnum);              _assert_(surface_input);
+	Input* slopex_input    = element->GetInput(SurfaceSlopeXEnum);        _assert_(slopex_input);
+	Input* slopey_input    = element->GetInput(SurfaceSlopeYEnum);        _assert_(slopey_input);
+	Input* thickness_input = element->GetInput(ThicknessEnum);            _assert_(thickness_input);
+	Input* drag_input      = element->GetInput(FrictionCoefficientEnum);  _assert_(drag_input);
+
+	/*Get Vertical segment indices*/
+	element->VerticalSegmentIndices(&pairindices,&numsegments);
+	for(int is=0;is<numsegments;is++){
+		nodedown = pairindices[is*2+0];
+		nodeup   = pairindices[is*2+1];
+		connectivity[0]=(IssmDouble)element->VertexConnectivity(nodedown);
+		connectivity[1]=(IssmDouble)element->VertexConnectivity(nodeup);
+		for(int i=0;i<3;i++){
+			xyz_list_line[0][i]=xyz_list[nodedown*3+i];
+			xyz_list_line[1][i]=xyz_list[nodeup*3+i];
+		}
+
+		Gauss* gauss=element->NewGaussLine(nodedown,nodeup,3);
+		for(int ig=gauss->begin();ig<gauss->end();ig++){
+			gauss->GaussPoint(ig);
+
+			slopex_input->GetInputValue(&slope[0],gauss);
+			slopey_input->GetInputValue(&slope[1],gauss);
+			surface_input->GetInputValue(&surface,gauss);
+			thickness_input->GetInputValue(&thickness,gauss);
+
+			slope2=slope[0]*slope[0]+slope[1]*slope[1];
+			constant_part=-2.*pow(rho_ice*gravity,n)*pow(slope2,((n-1.)/2.));
+
+			z = element->GetZcoord(gauss);
+			element->JacobianDeterminantLine(&Jdet,&xyz_list_line[0][0],gauss);
+
+			if(element->IsOnSurface()){
+				pe->values[2*nodeup+0]+=constant_part*pow((surface-z)/B,n)*slope[0]*Jdet*gauss->weight/connectivity[1];
+				pe->values[2*nodeup+1]+=constant_part*pow((surface-z)/B,n)*slope[1]*Jdet*gauss->weight/connectivity[1];
+			}
+			else{/*connectivity is too large, should take only half on it*/
+				pe->values[2*nodeup+0]+=constant_part*pow((surface-z)/B,n)*slope[0]*Jdet*gauss->weight*2./connectivity[1];
+				pe->values[2*nodeup+1]+=constant_part*pow((surface-z)/B,n)*slope[1]*Jdet*gauss->weight*2./connectivity[1];
+			}
+		}
+
+		/*Deal with basal velocities*/
+		if(element->IsOnBase()){
+			drag_input->GetInputValue(&drag,gauss);
+
+			switch(frictionlaw){
+				case 1:
+					/*Payne 1995 (m = 1, B = 5e-3/yts = 1.58e-10  m/s/Pa*/
+					ub=-1.58*1.e-10*rho_ice*gravity*thickness*slope[0];
+					vb=-1.58*1.e-10*rho_ice*gravity*thickness*slope[1];
+					break;
+				case 2:
+					/*Ritz et al. 1996*/
+					ub=drag*(rho_ice*gravity*thickness)*(rho_ice*gravity*thickness)*slope[0]/sqrt(slope2);
+					vb=drag*(rho_ice*gravity*thickness)*(rho_ice*gravity*thickness)*slope[1]/sqrt(slope2);
+					break;
+				case 3:
+					/*Rutt et al. 2009*/
+					ub=-drag*rho_ice*gravity*thickness*slope[0];
+					vb=-drag*rho_ice*gravity*thickness*slope[1];
+					break;
+				case 4:
+					/*Henning Akesson*/
+					drag = -4e-15 * surface + 8.6e-12;
+					ub=-drag*rho_ice*gravity*thickness*slope[0];
+					vb=-drag*rho_ice*gravity*thickness*slope[1];
+					break;
+				default:
+					_error_("Not supported yet");
+			}
+
+			pe->values[2*nodedown+0]+=ub/connectivity[0];
+			pe->values[2*nodedown+1]+=vb/connectivity[0];
+		}
+		delete gauss;
+	}
+
+	/*Clean up and return*/
+	xDelete<int>(pairindices);
+	xDelete<IssmDouble>(xyz_list);
+	return pe;
+
+}/*}}}*/
+void StressbalanceSIAAnalysis::GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element){/*{{{*/
+
+	IssmDouble vx,vy;
+	int       *doflist = NULL;
+
+	/*Fetch number of nodes and initialize values*/
+	int         numnodes = element->GetNumberOfNodes();
+	int         numdof   = numnodes*2;
+	IssmDouble* values   = xNew<IssmDouble>(numdof);
+
+	/*Get dof list and inputs */
+	element->GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
+	Input* vx_input=element->GetInput(VxEnum); _assert_(vx_input);
+	Input* vy_input=element->GetInput(VyEnum); _assert_(vy_input);
+
+	/*Ok, we have the velocities in inputs, fill in solution */
+	Gauss* gauss=element->NewGauss();
+	for(int i=0;i<numnodes;i++){
+		gauss->GaussVertex(i);
+		vx_input->GetInputValue(&vx,gauss);
+		vy_input->GetInputValue(&vy,gauss);
+		values[i*2+0]=vx;
+		values[i*2+1]=vy;
+	}
+
+	/*Add value to global vector*/
+	solution->SetValues(numdof,doflist,values,INS_VAL);
+
+	/*Free ressources:*/
+	delete gauss;
+	xDelete<int>(doflist);
+	xDelete<IssmDouble>(values);
+}/*}}}*/
+void StressbalanceSIAAnalysis::InputUpdateFromSolution(IssmDouble* solution,Element* element){/*{{{*/
+
+	int         i,domaintype;
+	IssmDouble  rho_ice,g;
+	int*        doflist=NULL;
+	IssmDouble* xyz_list=NULL;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+	int numdof   = numnodes*2;
+
+	/*Fetch dof list and allocate solution vectors*/
+	element->GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
+	IssmDouble* values    = xNew<IssmDouble>(numdof);
+	IssmDouble* vx        = xNew<IssmDouble>(numdof);
+	IssmDouble* vy        = xNew<IssmDouble>(numdof);
+	IssmDouble* vz        = xNew<IssmDouble>(numdof);
+	IssmDouble* vel       = xNew<IssmDouble>(numdof);
+	IssmDouble* pressure  = xNew<IssmDouble>(numdof);
+	IssmDouble* thickness = xNew<IssmDouble>(numdof);
+	IssmDouble* surface   = xNew<IssmDouble>(numnodes);
+
+	/*Use the dof list to index into the solution vector: */
+	for(i=0;i<numdof;i++) values[i]=solution[doflist[i]];
+
+	/*Transform solution in Cartesian Space*/
+	element->TransformSolutionCoord(&values[0],XYEnum);
+
+	/*Ok, we have vx and vy in values, fill in vx and vy arrays: */
+	for(i=0;i<numnodes;i++){
+		vx[i]=values[i*NDOF2+0];
+		vy[i]=values[i*NDOF2+1];
+
+		/*Check solution*/
+		if(xIsNan<IssmDouble>(vx[i])) _error_("NaN found in solution vector");
+		if(xIsNan<IssmDouble>(vy[i])) _error_("NaN found in solution vector");
+	}
+
+	/*Get Vz and compute vel*/
+	element->GetInputListOnNodes(&vz[0],VzEnum,0.);
+	for(i=0;i<numnodes;i++) vel[i]=sqrt(vx[i]*vx[i] + vy[i]*vy[i] + vz[i]*vz[i]);
+
+	/*For pressure: we have not computed pressure in this analysis, for this element. We are in 2D, 
+	 *so the pressure is just the pressure at the bedrock: */
+	rho_ice  = element->GetMaterialParameter(MaterialsRhoIceEnum);
+	g        = element->GetMaterialParameter(ConstantsGEnum);
+	element->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DhorizontalEnum:
+			element->GetInputListOnNodes(&thickness[0],ThicknessEnum);
+			for(i=0;i<numnodes;i++) pressure[i]=rho_ice*g*thickness[i];
+			break;
+		case Domain3DEnum:   
+			element->GetVerticesCoordinates(&xyz_list);
+			element->GetInputListOnNodes(&surface[0],SurfaceEnum);
+			for(i=0;i<numnodes;i++) pressure[i]=rho_ice*g*(surface[i]-xyz_list[i*3+2]);
+			break;
+		default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
+	}
+
+	/*Now, we have to move the previous Vx and Vy inputs  to old 
+	 * status, otherwise, we'll wipe them off: */
+	element->InputChangeName(VxEnum,VxPicardEnum);
+	element->InputChangeName(VyEnum,VyPicardEnum);
+	element->InputChangeName(PressureEnum,PressurePicardEnum);
+
+	/*Add vx and vy as inputs to the tria element: */
+	element->AddInput(VxEnum,vx,P1Enum);
+	element->AddInput(VyEnum,vy,P1Enum);
+	element->AddInput(VelEnum,vel,P1Enum);
+	element->AddInput(PressureEnum,pressure,P1Enum);
+
+	/*Free ressources:*/
+	xDelete<IssmDouble>(thickness);
+	xDelete<IssmDouble>(surface);
+	xDelete<IssmDouble>(pressure);
+	xDelete<IssmDouble>(vel);
+	xDelete<IssmDouble>(vz);
+	xDelete<IssmDouble>(vy);
+	xDelete<IssmDouble>(vx);
+	xDelete<IssmDouble>(values);
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<int>(doflist);
+}/*}}}*/
+void StressbalanceSIAAnalysis::UpdateConstraints(FemModel* femmodel){/*{{{*/
+
+	bool islevelset;
+	femmodel->parameters->FindParam(&islevelset,TransientIslevelsetEnum);
+	if(islevelset){
+		SetActiveNodesLSMx(femmodel);
+	}
+	return;
+}/*}}}*/
Index: /issm/trunk/src/c/analyses/StressbalanceSIAAnalysis.h
===================================================================
--- /issm/trunk/src/c/analyses/StressbalanceSIAAnalysis.h	(revision 17805)
+++ /issm/trunk/src/c/analyses/StressbalanceSIAAnalysis.h	(revision 17806)
@@ -12,5 +12,6 @@
 
 	public:
-		int  DofsPerNode(int** doflist,int meshtype,int approximation);
+		/*Model processing*/
+		int  DofsPerNode(int** doflist,int domaintype,int approximation);
 		void UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum);
 		void UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);
@@ -18,4 +19,18 @@
 		void CreateConstraints(Constraints* constraints,IoModel* iomodel);
 		void CreateLoads(Loads* loads, IoModel* iomodel);
+
+		/*Finite element Analysis*/
+		void           Core(FemModel* femmodel);
+		ElementVector* CreateDVector(Element* element);
+		ElementMatrix* CreateJacobianMatrix(Element* element);
+		ElementMatrix* CreateKMatrix(Element* element);
+		ElementMatrix* CreateKMatrix2D(Element* element);
+		ElementMatrix* CreateKMatrix3D(Element* element);
+		ElementVector* CreatePVector(Element* element);
+		ElementVector* CreatePVector2D(Element* element);
+		ElementVector* CreatePVector3D(Element* element);
+		void GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element);
+		void InputUpdateFromSolution(IssmDouble* solution,Element* element);
+		void UpdateConstraints(FemModel* femmodel);
 };
 #endif
Index: /issm/trunk/src/c/analyses/StressbalanceVerticalAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/StressbalanceVerticalAnalysis.cpp	(revision 17805)
+++ /issm/trunk/src/c/analyses/StressbalanceVerticalAnalysis.cpp	(revision 17806)
@@ -4,7 +4,8 @@
 #include "../shared/shared.h"
 #include "../modules/modules.h"
+#include "../solutionsequences/solutionsequences.h"
 
 /*Model processing*/
-int  StressbalanceVerticalAnalysis::DofsPerNode(int** doflist,int meshtype,int approximation){/*{{{*/
+int  StressbalanceVerticalAnalysis::DofsPerNode(int** doflist,int domaintype,int approximation){/*{{{*/
 	return 1;
 }/*}}}*/
@@ -17,5 +18,5 @@
 
 	/*return if not 3d mesh*/
-	if(iomodel->meshtype!=Mesh3DEnum) return;
+	if(iomodel->domaintype!=Domain3DEnum) return;
 
 	/*Update elements: */
@@ -31,8 +32,11 @@
 	iomodel->FetchDataToInput(elements,ThicknessEnum);
 	iomodel->FetchDataToInput(elements,SurfaceEnum);
-	iomodel->FetchDataToInput(elements,BedEnum);
+	iomodel->FetchDataToInput(elements,BaseEnum);
 	iomodel->FetchDataToInput(elements,MaskIceLevelsetEnum);
-	iomodel->FetchDataToInput(elements,MeshElementonbedEnum);
-	iomodel->FetchDataToInput(elements,MeshElementonsurfaceEnum);
+	if(iomodel->meshelementtype==PentaEnum){
+		iomodel->FetchDataToInput(elements,MeshElementonbaseEnum);
+		iomodel->FetchDataToInput(elements,MeshElementonsurfaceEnum);
+	}
+	iomodel->FetchDataToInput(elements,MeshVertexonsurfaceEnum);
 	iomodel->FetchDataToInput(elements,BasalforcingsMeltingRateEnum);
 	iomodel->FetchDataToInput(elements,VxEnum,0.);
@@ -42,9 +46,9 @@
 
 	/*return if not 3d mesh*/
-	if(iomodel->meshtype!=Mesh3DEnum) return;
-
-	iomodel->FetchData(3,MeshVertexonbedEnum,MeshVertexonsurfaceEnum,FlowequationVertexEquationEnum);
+	if(iomodel->domaintype!=Domain3DEnum) return;
+
+	iomodel->FetchData(3,MeshVertexonbaseEnum,MeshVertexonsurfaceEnum,FlowequationVertexEquationEnum);
 	::CreateNodes(nodes,iomodel,StressbalanceVerticalAnalysisEnum,P1Enum);
-	iomodel->DeleteData(3,MeshVertexonbedEnum,MeshVertexonsurfaceEnum,FlowequationVertexEquationEnum);
+	iomodel->DeleteData(3,MeshVertexonbaseEnum,MeshVertexonsurfaceEnum,FlowequationVertexEquationEnum);
 }/*}}}*/
 void StressbalanceVerticalAnalysis::CreateConstraints(Constraints* constraints,IoModel* iomodel){/*{{{*/
@@ -58,5 +62,5 @@
 
 	/*return if not 3d mesh*/
-	if(iomodel->meshtype!=Mesh3DEnum) return;
+	if(iomodel->domaintype!=Domain3DEnum) return;
 
 	/*Fetch data: */
@@ -73,10 +77,10 @@
 
 			if (reCast<int,IssmDouble>(iomodel->Data(FlowequationBorderFSEnum)[i])){
-				constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,1,0,StressbalanceVerticalAnalysisEnum)); //spc to zero as vertical velocity is done in Horiz for FS
+				constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,0,0,StressbalanceVerticalAnalysisEnum)); //spc to zero as vertical velocity is done in Horiz for FS
 				count++;
 			}
 			else if (!xIsNan<IssmDouble>(iomodel->Data(StressbalanceSpcvzEnum)[i])){
-				constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,1,
-								iomodel->Data(StressbalanceSpcvzEnum)[i]/yts,StressbalanceVerticalAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
+				constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,0,
+								iomodel->Data(StressbalanceSpcvzEnum)[i],StressbalanceVerticalAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
 				count++;
 
@@ -94,2 +98,379 @@
 
 }/*}}}*/
+
+/*Finite Element Analysis*/
+void           StressbalanceVerticalAnalysis::Core(FemModel* femmodel){/*{{{*/
+
+		if(VerboseSolution()) _printf0_("   computing vertical velocities\n");
+		femmodel->SetCurrentConfiguration(StressbalanceVerticalAnalysisEnum);
+		solutionsequence_linear(femmodel);
+}/*}}}*/
+ElementVector* StressbalanceVerticalAnalysis::CreateDVector(Element* element){/*{{{*/
+	/*Default, return NULL*/
+	return NULL;
+}/*}}}*/
+ElementMatrix* StressbalanceVerticalAnalysis::CreateJacobianMatrix(Element* element){/*{{{*/
+_error_("Not implemented");
+}/*}}}*/
+ElementMatrix* StressbalanceVerticalAnalysis::CreateKMatrix(Element* element){/*{{{*/
+
+	/*compute all stiffness matrices for this element*/
+	ElementMatrix* Ke1=CreateKMatrixVolume(element);
+	ElementMatrix* Ke2=CreateKMatrixSurface(element);
+	ElementMatrix* Ke =new ElementMatrix(Ke1,Ke2);
+
+	/*clean-up and return*/
+	delete Ke1;
+	delete Ke2;
+	return Ke;
+
+}/*}}}*/
+ElementMatrix* StressbalanceVerticalAnalysis::CreateKMatrixVolume(Element* element){/*{{{*/
+
+	/*Intermediaries*/
+	IssmDouble  D,Jdet;
+	IssmDouble *xyz_list = NULL;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Initialize Element matrix and vectors*/
+	ElementMatrix* Ke     = element->NewElementMatrix(NoneApproximationEnum);
+	IssmDouble*    B      = xNew<IssmDouble>(numnodes);
+	IssmDouble*    Bprime = xNew<IssmDouble>(numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss = element->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		this->GetB(B,element,xyz_list,gauss);
+		this->GetBprime(Bprime,element,xyz_list,gauss);
+		D=gauss->weight*Jdet;
+
+		TripleMultiply(B,1,numnodes,1,
+					&D,1,1,0,
+					Bprime,1,numnodes,0,
+					&Ke->values[0],1);
+	}
+
+	/*Clean up and return*/
+	delete gauss;
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(Bprime);
+	xDelete<IssmDouble>(B);
+	return Ke;
+
+}/*}}}*/
+ElementMatrix* StressbalanceVerticalAnalysis::CreateKMatrixSurface(Element* element){/*{{{*/
+
+
+	if(!element->IsOnSurface()) return NULL;
+
+	/*Intermediaries*/
+	IssmDouble  D,Jdet,normal[3];
+	IssmDouble *xyz_list = NULL;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Initialize Element matrix and vectors*/
+	ElementMatrix* Ke    = element->NewElementMatrix(NoneApproximationEnum);
+	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinatesTop(&xyz_list);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss = element->NewGaussTop(2);
+	element->NormalTop(&normal[0],xyz_list);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminantTop(&Jdet,xyz_list,gauss);
+		element->NodalFunctions(basis,gauss);
+		D = -gauss->weight*Jdet*normal[2];
+
+		TripleMultiply( basis,1,numnodes,1,
+					&D,1,1,0,
+					basis,1,numnodes,0,
+					&Ke->values[0],1);
+	}
+
+	/*Clean up and return*/
+	delete gauss;
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(basis);
+	return Ke;
+}/*}}}*/
+ElementVector* StressbalanceVerticalAnalysis::CreatePVector(Element* element){/*{{{*/
+
+	/*compute all load vectors for this element*/
+	ElementVector* pe1=CreatePVectorVolume(element);
+	ElementVector* pe2=CreatePVectorBase(element);
+	ElementVector* pe =new ElementVector(pe1,pe2);
+
+	/*clean-up and return*/
+	delete pe1;
+	delete pe2;
+	return pe;
+}/*}}}*/
+ElementVector* StressbalanceVerticalAnalysis::CreatePVectorVolume(Element* element){/*{{{*/
+
+	/*Intermediaries*/
+	int         approximation;
+	IssmDouble  Jdet,dudx,dvdy,dwdz;
+	IssmDouble  du[3],dv[3],dw[3];
+	IssmDouble* xyz_list = NULL;
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Initialize Element vector and basis functions*/
+	ElementVector* pe    = element->NewElementVector();
+	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+	element->GetInputValue(&approximation,ApproximationEnum);
+	Input* vx_input=element->GetInput(VxEnum); _assert_(vx_input);
+	Input* vy_input=element->GetInput(VyEnum); _assert_(vy_input);
+	Input* vzFS_input=NULL;
+	if(approximation==HOFSApproximationEnum || approximation==SSAFSApproximationEnum){
+		vzFS_input=element->GetInput(VzFSEnum); _assert_(vzFS_input);
+	}
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		element->NodalFunctions(basis,gauss);
+
+		vx_input->GetInputDerivativeValue(&du[0],xyz_list,gauss);
+		vy_input->GetInputDerivativeValue(&dv[0],xyz_list,gauss);
+		if(approximation==HOFSApproximationEnum || approximation==SSAFSApproximationEnum){
+			vzFS_input->GetInputDerivativeValue(&dw[0],xyz_list,gauss);
+			dwdz=dw[2];
+		}
+		else dwdz=0;
+		dudx=du[0];
+		dvdy=dv[1];
+
+		for(int i=0;i<numnodes;i++) pe->values[i] += (dudx+dvdy+dwdz)*Jdet*gauss->weight*basis[i];
+	}
+
+	/*Clean up and return*/
+	delete gauss;
+	xDelete<IssmDouble>(basis);
+	xDelete<IssmDouble>(xyz_list);
+	return pe;
+}/*}}}*/
+ElementVector* StressbalanceVerticalAnalysis::CreatePVectorBase(Element* element){/*{{{*/
+
+	/*Intermediaries */
+	int         approximation;
+	IssmDouble *xyz_list      = NULL;
+	IssmDouble *xyz_list_base = NULL;
+	IssmDouble  Jdet,slope[3];
+	IssmDouble  vx,vy,vz=0.,dbdx,dbdy,basalmeltingvalue;
+
+	if(!element->IsOnBase()) return NULL;
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Initialize Element vector*/
+	ElementVector* pe    = element->NewElementVector();
+	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+	element->GetVerticesCoordinatesBase(&xyz_list_base);
+	element->GetInputValue(&approximation,ApproximationEnum);
+	Input* base_input=element->GetInput(BaseEnum);                                _assert_(base_input);
+	Input* basal_melting_input=element->GetInput(BasalforcingsMeltingRateEnum); _assert_(basal_melting_input);
+	Input* vx_input=element->GetInput(VxEnum);                                  _assert_(vx_input);
+	Input* vy_input=element->GetInput(VyEnum);                                  _assert_(vy_input);
+	Input* vzFS_input=NULL;
+	if(approximation==HOFSApproximationEnum || approximation==SSAFSApproximationEnum){
+		vzFS_input=element->GetInput(VzFSEnum);       _assert_(vzFS_input);
+	}
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGaussBase(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		basal_melting_input->GetInputValue(&basalmeltingvalue,gauss);
+		base_input->GetInputDerivativeValue(&slope[0],xyz_list,gauss);
+		vx_input->GetInputValue(&vx,gauss);
+		vy_input->GetInputValue(&vy,gauss);
+		if(approximation==HOFSApproximationEnum || approximation==SSAFSApproximationEnum){
+			vzFS_input->GetInputValue(&vz,gauss);
+		}
+		dbdx=slope[0];
+		dbdy=slope[1];
+
+		element->JacobianDeterminantBase(&Jdet,xyz_list_base,gauss);
+		element->NodalFunctions(basis,gauss);
+
+		for(int i=0;i<numnodes;i++) pe->values[i]+=-Jdet*gauss->weight*(vx*dbdx+vy*dbdy-vz-basalmeltingvalue)*basis[i];
+	}
+
+	/*Clean up and return*/
+	delete gauss;
+	xDelete<IssmDouble>(basis);
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(xyz_list_base);
+	return pe;
+}/*}}}*/
+void StressbalanceVerticalAnalysis::GetB(IssmDouble* B,Element* element,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
+	/*	Compute B  matrix. B=[dh1/dz dh2/dz dh3/dz dh4/dz dh5/dz dh6/dz];
+		where hi is the interpolation function for node i.*/
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Get nodal functions derivatives*/
+	IssmDouble* dbasis=xNew<IssmDouble>(3*numnodes);
+	element->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+
+	/*Build B: */
+	for(int i=0;i<numnodes;i++){
+		B[i] = dbasis[2*numnodes+i];  
+	}
+
+	/*Clean-up*/
+	xDelete<IssmDouble>(dbasis);
+}/*}}}*/
+void StressbalanceVerticalAnalysis::GetBprime(IssmDouble* Bprime,Element* element,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
+
+	element->NodalFunctions(Bprime,gauss);
+
+}/*}}}*/
+void StressbalanceVerticalAnalysis::GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element){/*{{{*/
+	element->GetSolutionFromInputsOneDof(solution,VzEnum);
+}/*}}}*/
+void StressbalanceVerticalAnalysis::InputUpdateFromSolution(IssmDouble* solution,Element* element){/*{{{*/
+
+	int          numnodes = element->GetNumberOfNodes();
+	int          numdof=numnodes*1;
+
+	int          i;
+	int          approximation;
+	int*         doflist  = NULL;
+	IssmDouble*  xyz_list = NULL;
+	IssmDouble   rho_ice,g;
+
+	/*Get the approximation and do nothing if the element in FS or None*/
+	element->GetInputValue(&approximation,ApproximationEnum);
+	if(approximation==FSApproximationEnum || approximation==NoneApproximationEnum){
+		return;
+	}
+
+	/*Get dof list and vertices coordinates: */
+	element->GetVerticesCoordinates(&xyz_list);
+	element->GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
+	IssmDouble*  values    = xNew<IssmDouble>(numdof);
+	IssmDouble*  vx        = xNew<IssmDouble>(numnodes);
+	IssmDouble*  vy        = xNew<IssmDouble>(numnodes);
+	IssmDouble*  vz        = xNew<IssmDouble>(numnodes);
+	IssmDouble*  vzSSA     = xNew<IssmDouble>(numnodes);
+	IssmDouble*  vzHO      = xNew<IssmDouble>(numnodes);
+	IssmDouble*  vzFS      = xNew<IssmDouble>(numnodes);
+	IssmDouble*  vel       = xNew<IssmDouble>(numnodes);
+	IssmDouble*  pressure  = xNew<IssmDouble>(numnodes);
+	IssmDouble*  surface   = xNew<IssmDouble>(numnodes);
+
+	/*Use the dof list to index into the solution vector vz: */
+	for(i=0;i<numdof;i++) values[i]=solution[doflist[i]];
+	for(i=0;i<numdof;i++){
+		vz[i]=values[i*1+0];
+
+		/*Check solution*/
+		if(xIsNan<IssmDouble>(vz[i])) _error_("NaN found in solution vector");
+	}
+
+	/*Get Vx and Vy*/
+	element->GetInputListOnNodes(&vx[0],VxEnum,0.0); //default is 0
+	element->GetInputListOnNodes(&vy[0],VyEnum,0.0); //default is 0
+
+	/*Do some modifications if we actually have a HOFS or SSAFS element*/
+	if(approximation==HOFSApproximationEnum){
+		Input* vzFS_input=element->GetInput(VzFSEnum);
+		if (vzFS_input){
+			if (vzFS_input->ObjectEnum()!=PentaInputEnum) _error_("Cannot compute Vel as VzFS is of type " << EnumToStringx(vzFS_input->ObjectEnum()));
+			element->GetInputListOnNodes(&vzFS[0],VzFSEnum,0.);
+		}
+		else _error_("Cannot compute Vz as VzFS in not present in HOFS element");
+		for(i=0;i<numnodes;i++){
+			vzHO[i]=vz[i];
+			vz[i]=vzHO[i]+vzFS[i];
+		}
+	}
+	else if(approximation==SSAFSApproximationEnum){
+		Input* vzFS_input=element->GetInput(VzFSEnum);
+		if (vzFS_input){
+			if (vzFS_input->ObjectEnum()!=PentaInputEnum) _error_("Cannot compute Vel as VzFS is of type " << EnumToStringx(vzFS_input->ObjectEnum()));
+			element->GetInputListOnNodes(&vzFS[0],VzFSEnum,0.);
+		}
+		else _error_("Cannot compute Vz as VzFS in not present in SSAFS element");
+		for(i=0;i<numnodes;i++){
+			vzSSA[i]=vz[i];
+			vz[i]=vzSSA[i]+vzFS[i];
+		}
+	}
+
+	/*Now Compute vel*/
+	for(i=0;i<numnodes;i++) vel[i]=pow( pow(vx[i],2.0) + pow(vy[i],2.0) + pow(vz[i],2.0) , 0.5);
+
+	/*For pressure: we have not computed pressure in this analysis, for this element. We are in 3D, 
+	 *so the pressure is just the pressure at the z elevation: except it this is a HOFS element */
+	if(approximation!=HOFSApproximationEnum &&  approximation!=SSAFSApproximationEnum){
+		rho_ice = element->GetMaterialParameter(MaterialsRhoIceEnum);
+		g       = element->GetMaterialParameter(ConstantsGEnum);
+		element->GetInputListOnNodes(&surface[0],SurfaceEnum,0.);
+		for(i=0;i<numnodes;i++) pressure[i]=rho_ice*g*(surface[i]-xyz_list[i*3+2]);
+	}
+
+	/*Now, we have to move the previous Vz inputs to old 
+	 * status, otherwise, we'll wipe them off and add the new inputs: */
+	element->InputChangeName(VzEnum,VzPicardEnum);
+
+	if(approximation!=HOFSApproximationEnum && approximation!=SSAFSApproximationEnum){
+		element->InputChangeName(PressureEnum,PressurePicardEnum);
+		element->AddInput(PressureEnum,pressure,element->GetElementType());
+	}
+	else if(approximation==HOFSApproximationEnum){
+		element->AddInput(VzHOEnum,vzHO,P1Enum);
+	}
+	else if(approximation==SSAFSApproximationEnum){
+		element->AddInput(VzSSAEnum,vzSSA,P1Enum);
+	}
+	element->AddInput(VzEnum,vz,P1Enum);
+	element->AddInput(VelEnum,vel,P1Enum);
+
+	/*Free ressources:*/
+	xDelete<IssmDouble>(surface);
+	xDelete<IssmDouble>(pressure);
+	xDelete<IssmDouble>(vel);
+	xDelete<IssmDouble>(vz);
+	xDelete<IssmDouble>(vzSSA);
+	xDelete<IssmDouble>(vzHO);
+	xDelete<IssmDouble>(vzFS);
+	xDelete<IssmDouble>(vy);
+	xDelete<IssmDouble>(vx);
+	xDelete<IssmDouble>(values);
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<int>(doflist);
+}/*}}}*/
+void StressbalanceVerticalAnalysis::UpdateConstraints(FemModel* femmodel){/*{{{*/
+	/*Default, do nothing*/
+	return;
+}/*}}}*/
Index: /issm/trunk/src/c/analyses/StressbalanceVerticalAnalysis.h
===================================================================
--- /issm/trunk/src/c/analyses/StressbalanceVerticalAnalysis.h	(revision 17805)
+++ /issm/trunk/src/c/analyses/StressbalanceVerticalAnalysis.h	(revision 17806)
@@ -12,5 +12,6 @@
 
 	public:
-		int  DofsPerNode(int** doflist,int meshtype,int approximation);
+		/*Model processing*/
+		int  DofsPerNode(int** doflist,int domaintype,int approximation);
 		void UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum);
 		void UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);
@@ -18,4 +19,20 @@
 		void CreateConstraints(Constraints* constraints,IoModel* iomodel);
 		void CreateLoads(Loads* loads, IoModel* iomodel);
+
+		/*Finite element Analysis*/
+		void           Core(FemModel* femmodel);
+		ElementVector* CreateDVector(Element* element);
+		ElementMatrix* CreateJacobianMatrix(Element* element);
+		ElementMatrix* CreateKMatrix(Element* element);
+		ElementMatrix* CreateKMatrixVolume(Element* element);
+		ElementMatrix* CreateKMatrixSurface(Element* element);
+		ElementVector* CreatePVector(Element* element);
+		ElementVector* CreatePVectorVolume(Element* element);
+		ElementVector* CreatePVectorBase(Element* element);
+		void GetB(IssmDouble* B,Element* element,IssmDouble* xyz_list,Gauss* gauss);
+		void GetBprime(IssmDouble* B,Element* element,IssmDouble* xyz_list,Gauss* gauss);
+		void GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element);
+		void InputUpdateFromSolution(IssmDouble* solution,Element* element);
+		void UpdateConstraints(FemModel* femmodel);
 };
 #endif
Index: /issm/trunk/src/c/analyses/ThermalAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/ThermalAnalysis.cpp	(revision 17805)
+++ /issm/trunk/src/c/analyses/ThermalAnalysis.cpp	(revision 17806)
@@ -6,13 +6,30 @@
 
 /*Model processing*/
-int  ThermalAnalysis::DofsPerNode(int** doflist,int meshtype,int approximation){/*{{{*/
+int  ThermalAnalysis::DofsPerNode(int** doflist,int domaintype,int approximation){/*{{{*/
 	return 1;
 }/*}}}*/
 void ThermalAnalysis::UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum){/*{{{*/
+
+	int     numoutputs;
+	char**  requestedoutputs = NULL;
+
+	parameters->AddObject(iomodel->CopyConstantObject(ThermalMaxiterEnum));
+	parameters->AddObject(iomodel->CopyConstantObject(ThermalStabilizationEnum));
+	parameters->AddObject(iomodel->CopyConstantObject(ThermalPenaltyFactorEnum));
+	parameters->AddObject(iomodel->CopyConstantObject(ThermalPenaltyThresholdEnum));
+	parameters->AddObject(iomodel->CopyConstantObject(ThermalPenaltyLockEnum));
+	parameters->AddObject(iomodel->CopyConstantObject(ThermalIsenthalpyEnum));
+	parameters->AddObject(iomodel->CopyConstantObject(ThermalIsdynamicbasalspcEnum));
+
+	iomodel->FetchData(&requestedoutputs,&numoutputs,ThermalRequestedOutputsEnum);
+	parameters->AddObject(new IntParam(ThermalNumRequestedOutputsEnum,numoutputs));
+	if(numoutputs)parameters->AddObject(new StringArrayParam(ThermalRequestedOutputsEnum,requestedoutputs,numoutputs));
+	iomodel->DeleteData(&requestedoutputs,numoutputs,ThermalRequestedOutputsEnum);
+
 }/*}}}*/
 void ThermalAnalysis::UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type){/*{{{*/
 
 	/*Now, is the model 3d? otherwise, do nothing: */
-	if(iomodel->meshtype==Mesh2DhorizontalEnum)return;
+	if(iomodel->domaintype==Domain2DhorizontalEnum)return;
 
 	/*Update elements: */
@@ -26,10 +43,11 @@
 	}
 
-	bool dakota_analysis;
+	bool dakota_analysis, islevelset;
 	iomodel->Constant(&dakota_analysis,QmuIsdakotaEnum);
+	iomodel->Constant(&islevelset,TransientIslevelsetEnum);
 
 	iomodel->FetchDataToInput(elements,ThicknessEnum);
 	iomodel->FetchDataToInput(elements,SurfaceEnum);
-	iomodel->FetchDataToInput(elements,BedEnum);
+	iomodel->FetchDataToInput(elements,BaseEnum);
 	iomodel->FetchDataToInput(elements,FrictionCoefficientEnum);
 	iomodel->FetchDataToInput(elements,FrictionPEnum);
@@ -37,5 +55,5 @@
 	iomodel->FetchDataToInput(elements,MaskIceLevelsetEnum);
 	iomodel->FetchDataToInput(elements,MaskGroundediceLevelsetEnum);
-	iomodel->FetchDataToInput(elements,MeshElementonbedEnum);
+	iomodel->FetchDataToInput(elements,MeshElementonbaseEnum);
 	iomodel->FetchDataToInput(elements,MeshElementonsurfaceEnum);
 	iomodel->FetchDataToInput(elements,FlowequationElementEquationEnum);
@@ -58,15 +76,19 @@
 		elements->InputDuplicate(VxMeshEnum,QmuVzMeshEnum);
 	}
+	if(islevelset){
+		iomodel->FetchDataToInput(elements,IceMaskNodeActivationEnum);
+		iomodel->FetchDataToInput(elements,MeshVertexonbaseEnum); // required for updating active nodes
+	}
 }/*}}}*/
 void ThermalAnalysis::CreateNodes(Nodes* nodes,IoModel* iomodel){/*{{{*/
 
-	if(iomodel->meshtype==Mesh3DEnum) iomodel->FetchData(2,MeshVertexonbedEnum,MeshVertexonsurfaceEnum);
+	if(iomodel->domaintype==Domain3DEnum) iomodel->FetchData(2,MeshVertexonbaseEnum,MeshVertexonsurfaceEnum);
 	::CreateNodes(nodes,iomodel,ThermalAnalysisEnum,P1Enum);
-	iomodel->DeleteData(2,MeshVertexonbedEnum,MeshVertexonsurfaceEnum);
+	iomodel->DeleteData(2,MeshVertexonbaseEnum,MeshVertexonsurfaceEnum);
 }/*}}}*/
 void ThermalAnalysis::CreateConstraints(Constraints* constraints,IoModel* iomodel){/*{{{*/
 
 	/*Only 3d mesh supported*/
-	if(iomodel->meshtype==Mesh3DEnum){
+	if(iomodel->domaintype==Domain3DEnum){
 		IoModelToConstraintsx(constraints,iomodel,ThermalSpctemperatureEnum,ThermalAnalysisEnum,P1Enum);
 	}
@@ -75,5 +97,5 @@
 void ThermalAnalysis::CreateLoads(Loads* loads, IoModel* iomodel){/*{{{*/
 
-	if(iomodel->meshtype==Mesh2DhorizontalEnum) _error_("2d meshes not supported yet");
+	if(iomodel->domaintype==Domain2DhorizontalEnum) _error_("2d meshes not supported yet");
 
 	/*create penalties for nodes: no node can have a temperature over the melting point*/
@@ -93,2 +115,608 @@
 
 }/*}}}*/
+
+/*Finite Element Analysis*/
+void           ThermalAnalysis::Core(FemModel* femmodel){/*{{{*/
+	_error_("not implemented");
+}/*}}}*/
+ElementVector* ThermalAnalysis::CreateDVector(Element* element){/*{{{*/
+	/*Default, return NULL*/
+	return NULL;
+}/*}}}*/
+ElementMatrix* ThermalAnalysis::CreateJacobianMatrix(Element* element){/*{{{*/
+_error_("Not implemented");
+}/*}}}*/
+ElementMatrix* ThermalAnalysis::CreateKMatrix(Element* element){/*{{{*/
+
+	/* Check if ice in element */
+	if(!element->IsIceInElement()) return NULL;
+
+	/*compute all stiffness matrices for this element*/
+	ElementMatrix* Ke1=CreateKMatrixVolume(element);
+	ElementMatrix* Ke2=CreateKMatrixShelf(element);
+	ElementMatrix* Ke =new ElementMatrix(Ke1,Ke2);
+
+	/*clean-up and return*/
+	delete Ke1;
+	delete Ke2;
+	return Ke;
+}/*}}}*/
+ElementMatrix* ThermalAnalysis::CreateKMatrixVolume(Element* element){/*{{{*/
+
+	/* Check if ice in element */
+	if(!element->IsIceInElement()) return NULL;
+
+	/*Intermediaries */
+	int         stabilization;
+	IssmDouble  Jdet,dt,u,v,w,um,vm,wm,vel;
+	IssmDouble  h,hx,hy,hz,vx,vy,vz;
+	IssmDouble  tau_parameter,diameter;
+	IssmDouble  D_scalar;
+	IssmDouble* xyz_list = NULL;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Initialize Element vector and other vectors*/
+	ElementMatrix* Ke     = element->NewElementMatrix();
+	IssmDouble*    basis  = xNew<IssmDouble>(numnodes);
+	IssmDouble*    dbasis = xNew<IssmDouble>(3*numnodes);
+	IssmDouble*    B      = xNew<IssmDouble>(3*numnodes);
+	IssmDouble*    Bprime = xNew<IssmDouble>(3*numnodes);
+	IssmDouble     D[3][3]={0.};
+	IssmDouble     K[3][3];
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+	element->FindParam(&dt,TimesteppingTimeStepEnum);
+	element->FindParam(&stabilization,ThermalStabilizationEnum);
+	IssmDouble  rho_water           = element->GetMaterialParameter(MaterialsRhoWaterEnum);
+	IssmDouble  rho_ice             = element->GetMaterialParameter(MaterialsRhoIceEnum);
+	IssmDouble  gravity             = element->GetMaterialParameter(ConstantsGEnum);
+	IssmDouble  heatcapacity        = element->GetMaterialParameter(MaterialsHeatcapacityEnum);
+	IssmDouble  thermalconductivity = element->GetMaterialParameter(MaterialsThermalconductivityEnum);
+	IssmDouble  kappa = thermalconductivity/(rho_ice*heatcapacity);
+	Input* vx_input  = element->GetInput(VxEnum);     _assert_(vx_input);
+	Input* vy_input  = element->GetInput(VyEnum);     _assert_(vy_input);
+	Input* vz_input  = element->GetInput(VzEnum);     _assert_(vz_input);
+	Input* vxm_input = element->GetInput(VxMeshEnum); _assert_(vxm_input);
+	Input* vym_input = element->GetInput(VyMeshEnum); _assert_(vym_input);
+	Input* vzm_input = element->GetInput(VzMeshEnum); _assert_(vzm_input);
+	if(stabilization==2) diameter=element->MinEdgeLength(xyz_list);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		D_scalar=gauss->weight*Jdet;
+		if(dt!=0.) D_scalar=D_scalar*dt;
+
+		/*Conduction: */
+		GetBConduct(B,element,xyz_list,gauss); 
+		D[0][0]=D_scalar*kappa;
+		D[1][1]=D_scalar*kappa;
+		D[2][2]=D_scalar*kappa;
+		TripleMultiply(B,3,numnodes,1,
+					&D[0][0],3,3,0,
+					B,3,numnodes,0,
+					&Ke->values[0],1);
+
+		/*Advection: */
+		GetBAdvec(B,element,xyz_list,gauss); 
+		GetBAdvecprime(Bprime,element,xyz_list,gauss); 
+		vx_input->GetInputValue(&u,gauss); vxm_input->GetInputValue(&um,gauss); vx=u-um;
+		vy_input->GetInputValue(&v,gauss); vym_input->GetInputValue(&vm,gauss); vy=v-vm;
+		vz_input->GetInputValue(&w,gauss); vzm_input->GetInputValue(&wm,gauss); vz=w-wm;
+		D[0][0]=D_scalar*vx;
+		D[1][1]=D_scalar*vy;
+		D[2][2]=D_scalar*vz;
+		TripleMultiply(B,3,numnodes,1,
+					&D[0][0],3,3,0,
+					Bprime,3,numnodes,0,
+					&Ke->values[0],1);
+
+		/*Transient: */
+		if(dt!=0.){
+			D_scalar=gauss->weight*Jdet;
+			element->NodalFunctions(basis,gauss);
+			TripleMultiply(basis,numnodes,1,0,
+						&D_scalar,1,1,0,
+						basis,1,numnodes,0,
+						&Ke->values[0],1);
+			D_scalar=D_scalar*dt;
+		}
+
+		/*Artifficial diffusivity*/
+		if(stabilization==1){
+			element->ElementSizes(&hx,&hy,&hz);
+			vel=sqrt(vx*vx + vy*vy + vz*vz)+1.e-14;
+			h=sqrt( pow(hx*vx/vel,2) + pow(hy*vy/vel,2) + pow(hz*vz/vel,2));
+			K[0][0]=h/(2.*vel)*fabs(vx*vx);  K[0][1]=h/(2.*vel)*fabs(vx*vy); K[0][2]=h/(2.*vel)*fabs(vx*vz);
+			K[1][0]=h/(2.*vel)*fabs(vy*vx);  K[1][1]=h/(2.*vel)*fabs(vy*vy); K[1][2]=h/(2.*vel)*fabs(vy*vz);
+			K[2][0]=h/(2.*vel)*fabs(vz*vx);  K[2][1]=h/(2.*vel)*fabs(vz*vy); K[2][2]=h/(2.*vel)*fabs(vz*vz);
+			for(int i=0;i<3;i++) for(int j=0;j<3;j++) K[i][j] = D_scalar*K[i][j];
+
+			GetBAdvecprime(Bprime,element,xyz_list,gauss); 
+
+			TripleMultiply(Bprime,3,numnodes,1,
+						&K[0][0],3,3,0,
+						Bprime,3,numnodes,0,
+						&Ke->values[0],1);
+		}
+		else if(stabilization==2){
+			element->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+			tau_parameter=element->StabilizationParameter(u-um,v-vm,w-wm,diameter,kappa);
+			for(int i=0;i<numnodes;i++){
+				for(int j=0;j<numnodes;j++){
+					Ke->values[i*numnodes+j]+=tau_parameter*D_scalar*
+					  ((u-um)*dbasis[0*numnodes+i]+(v-vm)*dbasis[1*numnodes+i]+(w-wm)*dbasis[2*numnodes+i])*((u-um)*dbasis[0*numnodes+j]+(v-vm)*dbasis[1*numnodes+j]+(w-wm)*dbasis[2*numnodes+j]);
+				}
+			}
+			if(dt!=0.){
+				D_scalar=gauss->weight*Jdet;
+				for(int i=0;i<numnodes;i++){
+					for(int j=0;j<numnodes;j++){
+						Ke->values[i*numnodes+j]+=tau_parameter*D_scalar*basis[j]*((u-um)*dbasis[0*numnodes+i]+(v-vm)*dbasis[1*numnodes+i]+(w-wm)*dbasis[2*numnodes+i]);
+					}
+				}
+			}
+		}
+	}
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(B);
+	xDelete<IssmDouble>(Bprime);
+	xDelete<IssmDouble>(basis);
+	xDelete<IssmDouble>(dbasis);
+	delete gauss;
+	return Ke;
+}/*}}}*/
+ElementMatrix* ThermalAnalysis::CreateKMatrixShelf(Element* element){/*{{{*/
+
+	/* Check if ice in element */
+	if(!element->IsIceInElement()) return NULL;
+
+	/*Initialize Element matrix and return if necessary*/
+	if(!element->IsOnBase() || !element->IsFloating()) return NULL;
+
+	IssmDouble  dt,Jdet,D;
+	IssmDouble *xyz_list_base = NULL;
+
+	/*Get basal element*/
+	if(!element->IsOnBase() || !element->IsFloating()) return NULL;
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Initialize vectors*/
+	ElementMatrix* Ke    = element->NewElementMatrix();
+	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinatesBase(&xyz_list_base);
+	element->FindParam(&dt,TimesteppingTimeStepEnum);
+	IssmDouble  gravity             = element->GetMaterialParameter(ConstantsGEnum);
+	IssmDouble  rho_water           = element->GetMaterialParameter(MaterialsRhoWaterEnum);
+	IssmDouble  rho_ice             = element->GetMaterialParameter(MaterialsRhoIceEnum);
+	IssmDouble  heatcapacity        = element->GetMaterialParameter(MaterialsHeatcapacityEnum);
+	IssmDouble  mixed_layer_capacity= element->GetMaterialParameter(MaterialsMixedLayerCapacityEnum);
+	IssmDouble  thermal_exchange_vel= element->GetMaterialParameter(MaterialsThermalExchangeVelocityEnum);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGaussBase(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminantBase(&Jdet,xyz_list_base,gauss);
+		element->NodalFunctions(basis,gauss);
+
+		D=gauss->weight*Jdet*rho_water*mixed_layer_capacity*thermal_exchange_vel/(heatcapacity*rho_ice);
+		if(reCast<bool,IssmDouble>(dt)) D=dt*D;
+		TripleMultiply(basis,numnodes,1,0,
+					&D,1,1,0,
+					basis,1,numnodes,0,
+					&Ke->values[0],1);
+
+	}
+
+	/*Clean up and return*/
+	delete gauss;
+	xDelete<IssmDouble>(basis);
+	xDelete<IssmDouble>(xyz_list_base);
+	return Ke;
+}/*}}}*/
+ElementVector* ThermalAnalysis::CreatePVector(Element* element){/*{{{*/
+	
+	/* Check if ice in element */
+	if(!element->IsIceInElement()) return NULL;
+
+	/*compute all load vectors for this element*/
+	ElementVector* pe1=CreatePVectorVolume(element);
+	ElementVector* pe2=CreatePVectorSheet(element);
+	ElementVector* pe3=CreatePVectorShelf(element);
+	ElementVector* pe =new ElementVector(pe1,pe2,pe3);
+
+	/*clean-up and return*/
+	delete pe1;
+	delete pe2;
+	delete pe3;
+	return pe;
+}/*}}}*/
+ElementVector* ThermalAnalysis::CreatePVectorVolume(Element* element){/*{{{*/
+
+	/* Check if ice in element */
+	if(!element->IsIceInElement()) return NULL;
+
+	/*Intermediaries*/
+	int         stabilization;
+	IssmDouble  Jdet,phi,dt;
+	IssmDouble  temperature;
+	IssmDouble  tau_parameter,diameter;
+	IssmDouble  u,v,w;
+	IssmDouble  scalar_def,scalar_transient;
+	IssmDouble* xyz_list = NULL;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Initialize Element vector*/
+	ElementVector* pe     = element->NewElementVector();
+	IssmDouble*    basis  = xNew<IssmDouble>(numnodes);
+	IssmDouble*    dbasis = xNew<IssmDouble>(3*numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+	IssmDouble  rho_ice             = element->GetMaterialParameter(MaterialsRhoIceEnum);
+	IssmDouble  heatcapacity        = element->GetMaterialParameter(MaterialsHeatcapacityEnum);
+	IssmDouble  thermalconductivity = element->GetMaterialParameter(MaterialsThermalconductivityEnum);
+	IssmDouble  kappa = thermalconductivity/(rho_ice*heatcapacity);
+	element->FindParam(&dt,TimesteppingTimeStepEnum);
+	element->FindParam(&stabilization,ThermalStabilizationEnum);
+	Input* vx_input=element->GetInput(VxEnum); _assert_(vx_input);
+	Input* vy_input=element->GetInput(VyEnum); _assert_(vy_input);
+	Input* vz_input=element->GetInput(VzEnum); _assert_(vz_input);
+	Input* temperature_input = NULL;
+	if(reCast<bool,IssmDouble>(dt)){temperature_input = element->GetInput(TemperatureEnum); _assert_(temperature_input);}
+	if(stabilization==2) diameter=element->MinEdgeLength(xyz_list);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGauss(3);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		element->NodalFunctions(basis,gauss);
+		element->ViscousHeating(&phi,xyz_list,gauss,vx_input,vy_input,vz_input);
+
+		scalar_def=phi/(rho_ice*heatcapacity)*Jdet*gauss->weight;
+		if(reCast<bool,IssmDouble>(dt)) scalar_def=scalar_def*dt;
+
+		for(int i=0;i<numnodes;i++) pe->values[i]+=scalar_def*basis[i];
+
+		/* Build transient now */
+		if(reCast<bool,IssmDouble>(dt)){
+			temperature_input->GetInputValue(&temperature, gauss);
+			scalar_transient=temperature*Jdet*gauss->weight;
+			for(int i=0;i<numnodes;i++) pe->values[i]+=scalar_transient*basis[i];
+		}
+
+		if(stabilization==2){
+			element->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+
+			vx_input->GetInputValue(&u,gauss);
+			vy_input->GetInputValue(&v,gauss);
+			vz_input->GetInputValue(&w,gauss);
+
+			tau_parameter=element->StabilizationParameter(u,v,w,diameter,kappa);
+
+			for(int i=0;i<numnodes;i++) pe->values[i]+=tau_parameter*scalar_def*(u*dbasis[0*numnodes+i]+v*dbasis[1*numnodes+i]+w*dbasis[2*numnodes+i]);
+			if(reCast<bool,IssmDouble>(dt)){
+				for(int i=0;i<numnodes;i++) pe->values[i]+=tau_parameter*scalar_transient*(u*dbasis[0*numnodes+i]+v*dbasis[1*numnodes+i]+w*dbasis[2*numnodes+i]);
+			}
+		}
+	}
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(basis);
+	xDelete<IssmDouble>(dbasis);
+	xDelete<IssmDouble>(xyz_list);
+	delete gauss;
+	return pe;
+
+}/*}}}*/
+ElementVector* ThermalAnalysis::CreatePVectorSheet(Element* element){/*{{{*/
+
+	/* Check if ice in element */
+	if(!element->IsIceInElement()) return NULL;
+
+	/* Geothermal flux on ice sheet base and basal friction */
+	if(!element->IsOnBase() || element->IsFloating()) return NULL;
+
+	IssmDouble  dt,Jdet,geothermalflux,vx,vy,vz;
+	IssmDouble  alpha2,scalar,basalfriction,heatflux;
+	IssmDouble *xyz_list_base = NULL;
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Initialize vectors*/
+	ElementVector* pe    = element->NewElementVector();
+	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinatesBase(&xyz_list_base);
+	element->FindParam(&dt,TimesteppingTimeStepEnum);
+	Input* vx_input             = element->GetInput(VxEnum);                          _assert_(vx_input);
+	Input* vy_input             = element->GetInput(VyEnum);                          _assert_(vy_input);
+	Input* vz_input             = element->GetInput(VzEnum);                          _assert_(vz_input);
+	Input* geothermalflux_input = element->GetInput(BasalforcingsGeothermalfluxEnum); _assert_(geothermalflux_input);
+	IssmDouble  rho_ice             = element->GetMaterialParameter(MaterialsRhoIceEnum);
+	IssmDouble  heatcapacity        = element->GetMaterialParameter(MaterialsHeatcapacityEnum);
+
+	/*Build friction element, needed later: */
+	Friction* friction=new Friction(element,3);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss   = element->NewGaussBase(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminantBase(&Jdet,xyz_list_base,gauss);
+		element->NodalFunctions(basis,gauss);
+
+		geothermalflux_input->GetInputValue(&geothermalflux,gauss);
+		friction->GetAlpha2(&alpha2,gauss,vx_input,vy_input,vz_input);
+		vx_input->GetInputValue(&vx,gauss);
+		vy_input->GetInputValue(&vy,gauss);
+		vz_input->GetInputValue(&vz,gauss);
+		vz = 0.;//FIXME
+		basalfriction = alpha2*(vx*vx + vy*vy + vz*vz);
+		heatflux      = (basalfriction+geothermalflux)/(rho_ice*heatcapacity);
+
+		scalar = gauss->weight*Jdet*heatflux;
+		if(dt!=0.) scalar=dt*scalar;
+
+		for(int i=0;i<numnodes;i++) pe->values[i]+=scalar*basis[i];
+	}
+
+	/*Clean up and return*/
+	delete gauss;
+	delete friction;
+	xDelete<IssmDouble>(basis);
+	xDelete<IssmDouble>(xyz_list_base);
+	return pe;
+}/*}}}*/
+ElementVector* ThermalAnalysis::CreatePVectorShelf(Element* element){/*{{{*/
+
+	/* Check if ice in element */
+	if(!element->IsIceInElement()) return NULL;
+
+	IssmDouble  t_pmp,dt,Jdet,scalar_ocean,pressure;
+	IssmDouble *xyz_list_base = NULL;
+
+	/*Get basal element*/
+	if(!element->IsOnBase() || !element->IsFloating()) return NULL;
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Initialize vectors*/
+	ElementVector* pe    = element->NewElementVector();
+	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinatesBase(&xyz_list_base);
+	element->FindParam(&dt,TimesteppingTimeStepEnum);
+	Input*      pressure_input=element->GetInput(PressureEnum); _assert_(pressure_input);
+	IssmDouble  gravity             = element->GetMaterialParameter(ConstantsGEnum);
+	IssmDouble  rho_water           = element->GetMaterialParameter(MaterialsRhoWaterEnum);
+	IssmDouble  rho_ice             = element->GetMaterialParameter(MaterialsRhoIceEnum);
+	IssmDouble  heatcapacity        = element->GetMaterialParameter(MaterialsHeatcapacityEnum);
+	IssmDouble  mixed_layer_capacity= element->GetMaterialParameter(MaterialsMixedLayerCapacityEnum);
+	IssmDouble  thermal_exchange_vel= element->GetMaterialParameter(MaterialsThermalExchangeVelocityEnum);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGaussBase(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminantBase(&Jdet,xyz_list_base,gauss);
+		element->NodalFunctions(basis,gauss);
+
+		pressure_input->GetInputValue(&pressure,gauss);
+		t_pmp=element->TMeltingPoint(pressure);
+
+		scalar_ocean=gauss->weight*Jdet*rho_water*mixed_layer_capacity*thermal_exchange_vel*(t_pmp)/(heatcapacity*rho_ice);
+		if(reCast<bool,IssmDouble>(dt)) scalar_ocean=dt*scalar_ocean;
+
+		for(int i=0;i<numnodes;i++) pe->values[i]+=scalar_ocean*basis[i];
+	}
+
+	/*Clean up and return*/
+	delete gauss;
+	xDelete<IssmDouble>(basis);
+	xDelete<IssmDouble>(xyz_list_base);
+	return pe;
+}/*}}}*/
+void ThermalAnalysis::GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element){/*{{{*/
+	element->GetSolutionFromInputsOneDof(solution,TemperatureEnum);
+}/*}}}*/
+void ThermalAnalysis::GetBConduct(IssmDouble* B,Element* element,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
+	/*Compute B  matrix. B=[B1 B2 B3 B4 B5 B6] where Bi is of size 5*NDOF1. 
+	 * For node i, Bi' can be expressed in the actual coordinate system
+	 * by: 
+	 *       Bi_conduct=[ dh/dx ]
+	 *                  [ dh/dy ]
+	 *                  [ dh/dz ]
+	 * where h is the interpolation function for node i.
+	 *
+	 * We assume B has been allocated already, of size: 3x(NDOF1*numnodes)
+	 */
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Get nodal functions derivatives*/
+	IssmDouble* dbasis=xNew<IssmDouble>(3*numnodes);
+	element->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+
+	/*Build B: */
+	for(int i=0;i<numnodes;i++){
+		B[numnodes*0+i] = dbasis[0*numnodes+i];
+		B[numnodes*1+i] = dbasis[1*numnodes+i];
+		B[numnodes*2+i] = dbasis[2*numnodes+i];
+	}
+
+	/*Clean-up*/
+	xDelete<IssmDouble>(dbasis);
+}/*}}}*/
+void ThermalAnalysis::GetBAdvec(IssmDouble* B,Element* element,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
+	/*Compute B  matrix. B=[B1 B2 B3 B4 B5 B6] where Bi is of size 5*NDOF1. 
+	 * For node i, Bi' can be expressed in the actual coordinate system
+	 * by: 
+	 *       Bi_advec =[ h ]
+	 *                 [ h ]
+	 *                 [ h ]
+	 * where h is the interpolation function for node i.
+	 *
+	 * We assume B has been allocated already, of size: 3x(NDOF1*NUMNODESP1)
+	 */
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Get nodal functions*/
+	IssmDouble* basis=xNew<IssmDouble>(numnodes);
+	element->NodalFunctions(basis,gauss);
+
+	/*Build B: */
+	for(int i=0;i<numnodes;i++){
+		B[numnodes*0+i] = basis[i];
+		B[numnodes*1+i] = basis[i];
+		B[numnodes*2+i] = basis[i];
+	}
+
+	/*Clean-up*/
+	xDelete<IssmDouble>(basis);
+}/*}}}*/
+void ThermalAnalysis::GetBAdvecprime(IssmDouble* B,Element* element,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
+	/*Compute B  matrix. B=[B1 B2 B3 B4 B5 B6] where Bi is of size 5*NDOF1. 
+	 * For node i, Bi' can be expressed in the actual coordinate system
+	 * by: 
+	 *       Biprime_advec=[ dh/dx ]
+	 *                     [ dh/dy ]
+	 *                     [ dh/dz ]
+	 * where h is the interpolation function for node i.
+	 *
+	 * We assume B has been allocated already, of size: 3x(NDOF1*numnodes)
+	 */
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Get nodal functions derivatives*/
+	IssmDouble* dbasis=xNew<IssmDouble>(3*numnodes);
+	element->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+
+	/*Build B: */
+	for(int i=0;i<numnodes;i++){
+		B[numnodes*0+i] = dbasis[0*numnodes+i];
+		B[numnodes*1+i] = dbasis[1*numnodes+i];
+		B[numnodes*2+i] = dbasis[2*numnodes+i];
+	}
+
+	/*Clean-up*/
+	xDelete<IssmDouble>(dbasis);
+}/*}}}*/
+void ThermalAnalysis::InputUpdateFromSolution(IssmDouble* solution,Element* element){/*{{{*/
+
+	bool        converged;
+	int         i,rheology_law;
+	int        *doflist   = NULL;
+	IssmDouble *xyz_list  = NULL;
+	bool        hack      = false;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Fetch dof list and allocate solution vector*/
+	element->GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
+	IssmDouble* values    = xNew<IssmDouble>(numnodes);
+	IssmDouble* surface   = xNew<IssmDouble>(numnodes);
+	IssmDouble* B         = xNew<IssmDouble>(numnodes);
+
+	/*Use the dof list to index into the solution vector: */
+	for(i=0;i<numnodes;i++){
+		values[i]=solution[doflist[i]];
+
+		/*Check solution*/
+		if(xIsNan<IssmDouble>(values[i])) _error_("NaN found in solution vector");
+		//if(values[i]<0)      _printf_("temperature < 0°K found in solution vector\n");
+		//if(values[i]>275)    _printf_("temperature > 275°K found in solution vector (Paterson's rheology associated is negative)\n");
+	}
+
+	/*Force temperature between [Tpmp-50 Tpmp] to disable penalties*/
+	if(hack){
+		IssmDouble* pressure = xNew<IssmDouble>(numnodes);
+		element->GetInputListOnNodes(&pressure[0],PressureEnum);
+		for(i=0;i<numnodes;i++){
+			if(values[i]>element->TMeltingPoint(pressure[i]))     values[i]=element->TMeltingPoint(pressure[i]);
+			if(values[i]<element->TMeltingPoint(pressure[i])-50.) values[i]=element->TMeltingPoint(pressure[i])-50.;
+		}
+		xDelete<IssmDouble>(pressure);
+	}
+
+	/*Get all inputs and parameters*/
+	element->GetInputValue(&converged,ConvergedEnum);
+	if(converged){
+		element->AddInput(TemperatureEnum,values,element->GetElementType());
+
+		/*Update Rheology only if converged (we must make sure that the temperature is below melting point
+		 * otherwise the rheology could be negative*/
+		element->FindParam(&rheology_law,MaterialsRheologyLawEnum);
+		element->GetInputListOnNodes(&surface[0],SurfaceEnum);
+		switch(rheology_law){
+			case NoneEnum:
+				/*Do nothing: B is not temperature dependent*/
+				break;
+			case CuffeyEnum:
+				for(i=0;i<numnodes;i++) B[i]=Cuffey(values[i]);
+				element->AddInput(MaterialsRheologyBEnum,&B[0],element->GetElementType());
+				break;
+			case PatersonEnum:
+				for(i=0;i<numnodes;i++) B[i]=Paterson(values[i]);
+				element->AddInput(MaterialsRheologyBEnum,&B[0],element->GetElementType());
+				break;
+			case ArrheniusEnum:{
+				element->GetVerticesCoordinates(&xyz_list);
+				for(i=0;i<numnodes;i++) B[i]=Arrhenius(values[i],surface[i]-xyz_list[i*3+2],element->GetMaterialParameter(MaterialsRheologyNEnum));
+				element->AddInput(MaterialsRheologyBEnum,&B[0],element->GetElementType());
+				break;
+				}
+			default:
+				_error_("Rheology law " << EnumToStringx(rheology_law) << " not supported yet");
+		}
+	}
+	else{
+		element->AddInput(TemperaturePicardEnum,values,element->GetElementType());
+	}
+
+	/*Free ressources:*/
+	xDelete<IssmDouble>(values);
+	xDelete<IssmDouble>(surface);
+	xDelete<IssmDouble>(B);
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<int>(doflist);
+}/*}}}*/
+void ThermalAnalysis::UpdateConstraints(FemModel* femmodel){/*{{{*/
+
+	bool islevelset;
+	femmodel->parameters->FindParam(&islevelset,TransientIslevelsetEnum);
+	if(islevelset){
+		SetActiveNodesLSMx(femmodel);
+	}
+	return;
+}/*}}}*/
Index: /issm/trunk/src/c/analyses/ThermalAnalysis.h
===================================================================
--- /issm/trunk/src/c/analyses/ThermalAnalysis.h	(revision 17805)
+++ /issm/trunk/src/c/analyses/ThermalAnalysis.h	(revision 17806)
@@ -12,5 +12,6 @@
 
 	public:
-		int  DofsPerNode(int** doflist,int meshtype,int approximation);
+		/*Model processing*/
+		int  DofsPerNode(int** doflist,int domaintype,int approximation);
 		void UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum);
 		void UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);
@@ -18,4 +19,22 @@
 		void CreateConstraints(Constraints* constraints,IoModel* iomodel);
 		void CreateLoads(Loads* loads, IoModel* iomodel);
+
+		/*Finite element Analysis*/
+		void           Core(FemModel* femmodel);
+		ElementVector* CreateDVector(Element* element);
+		ElementMatrix* CreateJacobianMatrix(Element* element);
+		ElementMatrix* CreateKMatrix(Element* element);
+		ElementMatrix* CreateKMatrixVolume(Element* element);
+		ElementMatrix* CreateKMatrixShelf(Element* element);
+		ElementVector* CreatePVector(Element* element);
+		ElementVector* CreatePVectorVolume(Element* element);
+		ElementVector* CreatePVectorSheet(Element* element);
+		ElementVector* CreatePVectorShelf(Element* element);
+		void GetBConduct(IssmDouble* B,Element* element,IssmDouble* xyz_list,Gauss* gauss);
+		void GetBAdvec(IssmDouble* B,Element* element,IssmDouble* xyz_list,Gauss* gauss);
+		void GetBAdvecprime(IssmDouble* B,Element* element,IssmDouble* xyz_list,Gauss* gauss);
+		void GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element);
+		void InputUpdateFromSolution(IssmDouble* solution,Element* element);
+		void UpdateConstraints(FemModel* femmodel);
 };
 #endif
Index: /issm/trunk/src/c/analyses/analyses.h
===================================================================
--- /issm/trunk/src/c/analyses/analyses.h	(revision 17805)
+++ /issm/trunk/src/c/analyses/analyses.h	(revision 17806)
@@ -14,7 +14,9 @@
 #include "./BalancevelocityAnalysis.h"
 #include "./DamageEvolutionAnalysis.h"
+#include "./DepthAverageAnalysis.h"
 #include "./EnthalpyAnalysis.h"
 #include "./ExtrudeFromBaseAnalysis.h"
 #include "./ExtrudeFromTopAnalysis.h"
+#include "./ExtrapolationAnalysis.h"
 #include "./FreeSurfaceBaseAnalysis.h"
 #include "./FreeSurfaceTopAnalysis.h"
@@ -23,4 +25,6 @@
 #include "./HydrologyDCInefficientAnalysis.h"
 #include "./HydrologyShreveAnalysis.h"
+#include "./LevelsetAnalysis.h"
+#include "./LsfReinitializationAnalysis.h"
 #include "./MasstransportAnalysis.h"
 #include "./MeltingAnalysis.h"
@@ -32,6 +36,6 @@
 #include "./StressbalanceVerticalAnalysis.h"
 #include "./L2ProjectionBaseAnalysis.h"
+#include "./L2ProjectionEPLAnalysis.h"
 #include "./ThermalAnalysis.h"
-
-#include "EnumToAnalysis.h"
+#include "./EnumToAnalysis.h"
 #endif
Index: /issm/trunk/src/c/bamg/BamgOpts.cpp
===================================================================
--- /issm/trunk/src/c/bamg/BamgOpts.cpp	(revision 17805)
+++ /issm/trunk/src/c/bamg/BamgOpts.cpp	(revision 17806)
@@ -20,4 +20,5 @@
 	this->omega=0;
 	this->power=0;
+	this->random=0;
 	this->verbose=0;
 
Index: /issm/trunk/src/c/bamg/BamgOpts.h
===================================================================
--- /issm/trunk/src/c/bamg/BamgOpts.h	(revision 17805)
+++ /issm/trunk/src/c/bamg/BamgOpts.h	(revision 17806)
@@ -25,4 +25,5 @@
 		double  omega;
 		double  power;
+		bool    random;
 		int     verbose;
 
Index: /issm/trunk/src/c/bamg/BamgQuadtree.cpp
===================================================================
--- /issm/trunk/src/c/bamg/BamgQuadtree.cpp	(revision 17805)
+++ /issm/trunk/src/c/bamg/BamgQuadtree.cpp	(revision 17806)
@@ -150,8 +150,8 @@
 
 		/*Get integer coodinate of current point w*/
-		register long i=w.i.x, j=w.i.y;
+		long i=w.i.x, j=w.i.y;
 
 		/*Initialize level*/
-		register long level=MaxISize;
+		long level=MaxISize;
 
 		/*Get inital box (the largest)*/
@@ -426,6 +426,6 @@
 		int  pi[ MaxDepth  ];
 		Icoor1 ii[  MaxDepth ], jj [ MaxDepth];
-		register int l=0; // level
-		register BamgQuadtreeBox * b;
+		int l=0; // level
+		BamgQuadtreeBox * b;
 		Icoor1 hb =  MaxISize;
 		Icoor1 i0=0,j0=0;
@@ -444,5 +444,5 @@
 			b= pb[l];
 			while (pi[l]--){ 	      
-				register int k = pi[l];
+				int k = pi[l];
 
 				if (b->nbitems>0){ // BamgVertex BamgQuadtreeBox none empty
@@ -457,9 +457,9 @@
 				}
 				else{ // Pointer BamgQuadtreeBox 
-					register BamgQuadtreeBox *b0=b;
+					BamgQuadtreeBox *b0=b;
 					if ((b=b->b[k])){
 						hb >>=1 ; // div by 2
-						register long iii = ii[l]+I_IJ(k,hb);
-						register long jjj = jj[l]+J_IJ(k,hb);
+						long iii = ii[l]+I_IJ(k,hb);
+						long jjj = jj[l]+J_IJ(k,hb);
 
 						if  (INTER_SEG(iii,iii+hb,i-hx,i+hx) && INTER_SEG(jjj,jjj+hb,j-hy,j+hy)){
Index: /issm/trunk/src/c/bamg/BamgVertex.cpp
===================================================================
--- /issm/trunk/src/c/bamg/BamgVertex.cpp	(revision 17805)
+++ /issm/trunk/src/c/bamg/BamgVertex.cpp	(revision 17806)
@@ -125,10 +125,10 @@
 		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/Smoothing)*/
 
-		register BamgVertex* s=this;
+		BamgVertex* s=this;
 		BamgVertex &vP = *s,vPsave=vP;
 
-		register Triangle* tbegin= t , *tria = t , *ttc;
-
-		register int k=0,kk=0,j = EdgesVertexTriangle[IndexInTriangle][0],jc;
+		Triangle* tbegin= t , *tria = t , *ttc;
+
+		int k=0,kk=0,j = EdgesVertexTriangle[IndexInTriangle][0],jc;
 		R2 P(s->r),PNew(0,0);
 		do {
Index: /issm/trunk/src/c/bamg/Geometry.cpp
===================================================================
--- /issm/trunk/src/c/bamg/Geometry.cpp	(revision 17805)
+++ /issm/trunk/src/c/bamg/Geometry.cpp	(revision 17806)
@@ -598,5 +598,5 @@
 				long *po=p;                     
 				long  n=*p;                     
-				register float angleold=-1000 ; // angle = - infinity
+				float angleold=-1000 ; // angle = - infinity
 				ord=0; exch=0;
 
@@ -878,5 +878,5 @@
 		double sg;
 		if (eg0 == eg1) { 
-			register double s0=vg0,s1=vg1;
+			double s0=vg0,s1=vg1;
 			sg =  s0*(1.0-s) +  s*s1;
 			on=eg0;
Index: /issm/trunk/src/c/bamg/ListofIntersectionTriangles.cpp
===================================================================
--- /issm/trunk/src/c/bamg/ListofIntersectionTriangles.cpp	(revision 17805)
+++ /issm/trunk/src/c/bamg/ListofIntersectionTriangles.cpp	(revision 17806)
@@ -83,5 +83,5 @@
 		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/NewItem)*/
 
-		register int n;
+		int n;
 		R2 x(0,0);
 		if ( d0) x =      (*tt)[0].r * d0;
@@ -97,5 +97,5 @@
 			lIntTria[Size].x = x;
 			Metric m0,m1,m2;
-			register BamgVertex * v;
+			BamgVertex * v;
 			if ((v=(*tt)(0))) m0    = v->m;
 			if ((v=(*tt)(1))) m1    = v->m;
@@ -111,5 +111,5 @@
 		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/NewItem)*/
 
-		register int n;
+		int n;
 		if(!Size ||  Norme2_2(lIntTria[Size-1].x-A)) {
 			if (Size==MaxSize) ReShape();
@@ -183,5 +183,5 @@
 	void ListofIntersectionTriangles::ReShape(){ 
 
-		register int newsize = MaxSize*2;
+		int newsize = MaxSize*2;
 		IntersectionTriangles* nw = new IntersectionTriangles[newsize];
 		_assert_(nw);
Index: /issm/trunk/src/c/bamg/Mesh.cpp
===================================================================
--- /issm/trunk/src/c/bamg/Mesh.cpp	(revision 17805)
+++ /issm/trunk/src/c/bamg/Mesh.cpp	(revision 17806)
@@ -2775,5 +2775,5 @@
 	/*}}}*/
 	/*FUNCTION Mesh::Insert{{{*/
-	void Mesh::Insert() {
+	void Mesh::Insert(bool random) {
 		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/Insert)*/
 
@@ -2822,5 +2822,6 @@
 		//Get Prime number
 		const long PrimeNumber= BigPrimeNumber(nbv);
-		int   k0=rand()%nbv; 
+		int temp = rand(); if(!random) temp = 756804110;
+		int  k0=temp%nbv; 
 
 		//Build orderedvertices
@@ -2904,28 +2905,8 @@
 			_printf_("      NbSwap/nbv:          " << NbSwap/nbv << "\n");
 		}
-
-#ifdef NBLOOPOPTIM
-
-		k0 = rand()%nbv ; 
-		for (int is4=0; is4<nbv; is4++) 
-		 orderedvertices[is4]= &vertices[k0 = (k0 + PrimeNumber)% nbv];
-
-		for(int Nbloop=0;Nbloop<NBLOOPOPTIM;Nbloop++){
-			long  NbSwap = 0;
-			for (int is1=0; is1<nbv; is1++) 
-			 NbSwap += orderedvertices[is1]->Optim(0,0);
-			if (verbose>3) {
-				_printf_("      Optim Loop: " << Nbloop << "\n");
-				_printf_("      NbSwap/nbv:          " << NbSwap/nbv << "\n");
-			}
-			if(!NbSwap) break;
-		}
-		CreateSingleVertexToTriangleConnectivity(); 
-		// because we break the TriangleContainingTheVertex
-#endif
 	}
 	/*}}}*/
 	/*FUNCTION Mesh::InsertNewPoints{{{*/
-	long Mesh::InsertNewPoints(long nbvold,long & NbTSwap) {
+	long Mesh::InsertNewPoints(long nbvold,long & NbTSwap,bool random) {
 		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/InsertNewPoints)*/
 
@@ -2948,9 +2929,10 @@
 		const long PrimeNumber= BigPrimeNumber(nbv)  ;
 		//remainder of the division of rand() by nbvnew
-		long k3 = rand()%nbvnew;
+		int  temp = rand(); if(!random) temp = 1098566905;
+		long k3 = temp%nbvnew;
 		//loop over the new points
 		for (int is3=0; is3<nbvnew; is3++){
-			register long j=nbvold +(k3 = (k3+PrimeNumber)%nbvnew);
-			register long i=nbvold+is3; 
+			long j=nbvold +(k3 = (k3+PrimeNumber)%nbvnew);
+			long i=nbvold+is3; 
 			orderedvertices[i]= vertices + j;
 			orderedvertices[i]->ReferenceNumber=i;
@@ -3212,5 +3194,5 @@
 			}
 			Bh.CreateSingleVertexToTriangleConnectivity();     
-			InsertNewPoints(nbvold,NbTSwap)   ;            
+			InsertNewPoints(nbvold,NbTSwap,bamgopts->random);
 		}  
 		else Bh.CreateSingleVertexToTriangleConnectivity();     
@@ -3270,5 +3252,5 @@
 			  }// for triangle   
 
-			if (!InsertNewPoints(nbvold,NbTSwap)) break;
+			if (!InsertNewPoints(nbvold,NbTSwap,bamgopts->random)) break;
 			for (i=nbtold;i<nbt;i++) first_np_or_next_t[i]=iter;
 			Headt = nbt; // empty list 
@@ -3740,6 +3722,6 @@
 
 		long *renu= new long[nbt];
-		register Triangle *t0,*t,*te=triangles+nbt;
-		register long k=0,it,i,j;
+		Triangle *t0,*t,*te=triangles+nbt;
+		long k=0,it,i,j;
 
 		for ( it=0;it<nbt;it++) 
@@ -3932,5 +3914,5 @@
 		for(i=Head0;i>=0;i=first_np_or_next_t0[ip=i],first_np_or_next_t0[ip]=-1) {
 			//  pour tous les triangles autour du sommet s
-			register Triangle* t= vertices[i].t;
+			Triangle* t= vertices[i].t;
 			if (!t){
 				_error_("!t");
@@ -4119,5 +4101,5 @@
 	detop = det(*(*t)(VerticesOfTriangularEdge[jj][0]),*(*t)(VerticesOfTriangularEdge[jj][1]),B);
 
-	while(t->det>0) { 
+	while(t->det>0){
 
 		/*Increase counter*/
@@ -4172,6 +4154,6 @@
 	/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/ConsRefTriangle)*/
 
-	register Triangle *t0,*t;
-	register long k=0, num;   
+	Triangle *t0,*t;
+	long k=0, num;   
 
 	//initialize all triangles as -1 (outside)
@@ -4231,5 +4213,5 @@
 
 	/*Insert Vertices*/
-	Insert();
+	Insert(true);
 }
 /*}}}*/
@@ -4534,5 +4516,5 @@
 		if (verbose>3) _printf_("      Creating initial Constrained Delaunay Triangulation...\n");
 		if (verbose>3) _printf_("         Inserting boundary points\n");
-		Insert();
+		Insert(bamgopts->random);
 
 		//Force the boundary
@@ -4725,5 +4707,5 @@
 					L=0;// length of the curve
 					long i=0;// index of new points on the curve
-					register GeomVertex * GA0 = *(*peequi)[k0equi].GeomEdgeHook;
+					GeomVertex * GA0 = *(*peequi)[k0equi].GeomEdgeHook;
 					BamgVertex *A0;
 					A0 = GA0->MeshVertexHook;  // the vertex in new mesh
@@ -4799,5 +4781,5 @@
 							if (ee[k1].GeomEdgeHook->IsRequiredVertex()) {
 								_assert_(eeequi[k1equi].GeomEdgeHook->IsRequiredVertex());
-								register GeomVertex * GA1 = *eeequi[k1equi].GeomEdgeHook;
+								GeomVertex * GA1 = *eeequi[k1equi].GeomEdgeHook;
 								A1=GA1->MeshVertexHook;// the vertex in new mesh
 								_assert_(A1-vertices>=0 && A1-vertices<nbv);
@@ -4862,5 +4844,5 @@
 		if (verbose>3) _printf_("      Creating initial Constrained Delaunay Triangulation...\n");
 		if (verbose>3) _printf_("         Inserting boundary points\n");
-		Insert();
+		Insert(bamgopts->random);
 
 		//Force the boundary
Index: /issm/trunk/src/c/bamg/Mesh.h
===================================================================
--- /issm/trunk/src/c/bamg/Mesh.h	(revision 17805)
+++ /issm/trunk/src/c/bamg/Mesh.h	(revision 17806)
@@ -77,5 +77,5 @@
 			R2 I2ToR2(const I2 & P) const;
 			void AddVertex(BamgVertex & s,Triangle * t,Icoor2 *  =0) ;
-			void Insert();
+			void Insert(bool random);
 			void Echo(void);
 			void ForceBoundary();
@@ -92,5 +92,5 @@
 			void MakeBamgQuadtree();
 			void NewPoints(Mesh &,BamgOpts* bamgopts,int KeepVertices=1);
-			long InsertNewPoints(long nbvold,long & NbTSwap) ; 
+			long InsertNewPoints(long nbvold,long & NbTSwap,bool random); 
 			void TrianglesRenumberBySubDomain(bool justcompress=false);
 			void SmoothingVertex(int =3,double=0.3);
Index: /issm/trunk/src/c/bamg/Triangle.cpp
===================================================================
--- /issm/trunk/src/c/bamg/Triangle.cpp	(revision 17805)
+++ /issm/trunk/src/c/bamg/Triangle.cpp	(revision 17806)
@@ -231,7 +231,7 @@
 		// Copy all the mark 
 		a &= 3;
-		register Triangle *tt=adj[a];
+		Triangle *tt=adj[a];
 		AdjEdgeIndex [a] &= 55; // remove MarkUnSwap
-		register short aatt = AdjEdgeIndex[a] & 3;
+		short aatt = AdjEdgeIndex[a] & 3;
 		if(tt){ 
 			tt->adj[aatt]=this;
@@ -255,5 +255,5 @@
 	void Triangle::SetHidden(int a){
 		//Get Adjacent Triangle number a
-		register Triangle* t = adj[a];
+		Triangle* t = adj[a];
 		//if it exist
 		//C|=D -> C=(C|D) bitwise inclusive OR
@@ -264,5 +264,5 @@
 	void Triangle::SetLocked(int a){
 		//mark the edge as on Boundary
-		register Triangle * t = adj[a];
+		Triangle * t = adj[a];
 		t->AdjEdgeIndex[AdjEdgeIndex[a] & 3] |=4;
 		AdjEdgeIndex[a] |= 4;
@@ -270,5 +270,5 @@
 	/*FUNCTION Triangle::SetMarkUnSwap{{{*/
 	void Triangle::SetMarkUnSwap(int a){
-		register Triangle * t = adj[a];
+		Triangle * t = adj[a];
 		t->AdjEdgeIndex[AdjEdgeIndex[a] & 3] |=8;
 		AdjEdgeIndex[a] |=8 ;
@@ -282,5 +282,5 @@
 	/*FUNCTION Triangle::SetUnMarkUnSwap{{{*/
 	void Triangle::SetUnMarkUnSwap(int a){ 
-		register Triangle * t = adj[a];
+		Triangle * t = adj[a];
 		t->AdjEdgeIndex[AdjEdgeIndex[a] & 3] &=55; // 23 + 32 
 		AdjEdgeIndex[a] &=55 ;
@@ -292,12 +292,12 @@
 		if(a/4 !=0) return 0;// arete lock or MarkUnSwap
 
-		register Triangle *t1=this,*t2=adj[a];// les 2 triangles adjacent
-		register short a1=a,a2=AdjEdgeIndex[a];// les 2 numero de l arete dans les 2 triangles
+		Triangle *t1=this,*t2=adj[a];// les 2 triangles adjacent
+		short a1=a,a2=AdjEdgeIndex[a];// les 2 numero de l arete dans les 2 triangles
 		if(a2/4 !=0) return 0; // arete lock or MarkUnSwap
 
-		register BamgVertex  *sa=t1->vertices[VerticesOfTriangularEdge[a1][0]];
-		register BamgVertex  *sb=t1->vertices[VerticesOfTriangularEdge[a1][1]];
-		register BamgVertex  *s1=t1->vertices[OppositeVertex[a1]];
-		register BamgVertex  *s2=t2->vertices[OppositeVertex[a2]];
+		BamgVertex  *sa=t1->vertices[VerticesOfTriangularEdge[a1][0]];
+		BamgVertex  *sb=t1->vertices[VerticesOfTriangularEdge[a1][1]];
+		BamgVertex  *s1=t1->vertices[OppositeVertex[a1]];
+		BamgVertex  *s2=t2->vertices[OppositeVertex[a2]];
 
 		Icoor2 det1=t1->det , det2=t2->det ;
@@ -328,5 +328,5 @@
 					 if(kopt) {
 						 // critere de Delaunay pure isotrope
-						 register Icoor2 xb1 = sb->i.x - s1->i.x,
+						 Icoor2 xb1 = sb->i.x - s1->i.x,
 									 x21 = s2->i.x - s1->i.x,
 									 yb1 = sb->i.y - s1->i.y,
@@ -336,5 +336,5 @@
 									 yba = sb->i.y - sa->i.y,
 									 y2a = s2->i.y - sa->i.y;
-						 register double
+						 double
 							cosb12 =  double(xb1*x21 + yb1*y21),
 									 cosba2 =  double(xba*x2a + yba*y2a) ,
Index: /issm/trunk/src/c/classes/Constraints/SpcDynamic.cpp
===================================================================
--- /issm/trunk/src/c/classes/Constraints/SpcDynamic.cpp	(revision 17805)
+++ /issm/trunk/src/c/classes/Constraints/SpcDynamic.cpp	(revision 17806)
@@ -124,5 +124,5 @@
 
 	Node* node=(Node*)nodes->GetObjectById(NULL,nodeid);
-	pos=node->GetDof(dof-1,GsetEnum);
+	pos=node->GetDof(dof,GsetEnum);
 
 	this->value=yg_serial[pos];
Index: /issm/trunk/src/c/classes/Elements/Element.cpp
===================================================================
--- /issm/trunk/src/c/classes/Elements/Element.cpp	(revision 17806)
+++ /issm/trunk/src/c/classes/Elements/Element.cpp	(revision 17806)
@@ -0,0 +1,1513 @@
+/*!\file Element.cpp
+ * \brief: implementation of the Element object
+ */
+/*Headers:*/
+/*{{{*/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#else
+#error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
+#endif
+#include <stdio.h>
+#include <string.h>
+#include "../classes.h"
+#include "../../shared/shared.h"
+/*}}}*/
+
+/*Constructors/destructor/copy*/
+Element::Element(){/*{{{*/
+	this->id  = -1;
+	this->sid = -1;
+	this->inputs     = NULL;
+	this->nodes      = NULL;
+	this->vertices   = NULL;
+	this->material   = NULL;
+	this->matpar     = NULL;
+	this->inputs     = NULL;
+	this->parameters = NULL;
+}/*}}}*/
+Element::~Element(){/*{{{*/
+	delete inputs;
+}
+/*}}}*/
+
+/*Other*/
+void Element::AddInput(Input* input_in){/*{{{*/
+
+	/*Call inputs method*/
+	_assert_(this->inputs);
+	this->inputs->AddInput(input_in);
+}/*}}}*/
+/* bool Element::AllActive(void){/\*{{{*\/ */
+
+/* 	int numnodes = this->GetNumberOfNodes(); */
+/* 	for(int i=0;i<numnodes;i++){ */
+/* 		if(!this->nodes[i]->IsActive()) return false; */
+/* 	} */
+/* 	return true; */
+/* }/\*}}}*\/ */
+/* bool Element::AnyActive(void){/\*{{{*\/ */
+
+/* 	int numnodes = this->GetNumberOfNodes(); */
+/* 	for(int i=0;i<numnodes;i++){ */
+/* 		if(this->nodes[i]->IsActive()) return true; */
+/* 	} */
+/* 	return false; */
+/* }/\*}}}*\/ */
+void Element::CoordinateSystemTransform(IssmDouble** ptransform,Node** nodes_list,int numnodes,int* cs_array){/*{{{*/
+
+	int         i,counter;
+	int         numdofs   = 0;
+	IssmDouble  norm;
+	IssmDouble *transform = NULL;
+	IssmDouble  coord_system[3][3];
+
+	/*Some checks in debugging mode*/
+	_assert_(numnodes && nodes_list);
+
+	/*Get total number of dofs*/
+	for(i=0;i<numnodes;i++){
+		switch(cs_array[i]){
+			case PressureEnum: numdofs+=1; break;
+			case XYEnum:       numdofs+=2; break;
+			case XYZEnum:      numdofs+=3; break;
+			default: _error_("Coordinate system " << EnumToStringx(cs_array[i]) << " not supported yet");
+		}
+	}
+
+	/*Allocate and initialize transform matrix*/
+	transform=xNew<IssmDouble>(numdofs*numdofs);
+	for(i=0;i<numdofs*numdofs;i++) transform[i]=0.0;
+
+	/*Create transform matrix for all nodes (x,y for 2d and x,y,z for 3d). It is a block matrix
+	 *for 3 nodes:
+
+	 *     | T1 0  0 |
+	 * Q = | 0  T2 0 |
+	 *     | 0  0  T3|
+	 *
+	 * Where T1 is the transform matrix for node 1. It is a simple copy of the coordinate system
+	 * associated to this node*/
+	counter=0;
+	for(i=0;i<numnodes;i++){
+		nodes_list[i]->GetCoordinateSystem(&coord_system[0][0]);
+		switch(cs_array[i]){
+			case PressureEnum:
+				/*DO NOT change anything*/
+				transform[(numdofs)*(counter) + counter] = 1.;
+				counter+=1;
+				break;
+			case XYEnum:
+				/*We remove the z component, we need to renormalize x and y: x=[x1 x2 0] y=[-x2 x1 0]*/
+				norm = sqrt( coord_system[0][0]*coord_system[0][0] + coord_system[1][0]*coord_system[1][0]); _assert_(norm>1.e-4);
+				transform[(numdofs)*(counter+0) + counter+0] =   coord_system[0][0]/norm;
+				transform[(numdofs)*(counter+0) + counter+1] = - coord_system[1][0]/norm;
+				transform[(numdofs)*(counter+1) + counter+0] =   coord_system[1][0]/norm;
+				transform[(numdofs)*(counter+1) + counter+1] =   coord_system[0][0]/norm;
+				counter+=2;
+				break;
+			case XYZEnum:
+				/*The 3 coordinates are changed (x,y,z)*/
+				transform[(numdofs)*(counter+0) + counter+0] = coord_system[0][0];
+				transform[(numdofs)*(counter+0) + counter+1] = coord_system[0][1];
+				transform[(numdofs)*(counter+0) + counter+2] = coord_system[0][2];
+				transform[(numdofs)*(counter+1) + counter+0] = coord_system[1][0];
+				transform[(numdofs)*(counter+1) + counter+1] = coord_system[1][1];
+				transform[(numdofs)*(counter+1) + counter+2] = coord_system[1][2];
+				transform[(numdofs)*(counter+2) + counter+0] = coord_system[2][0];
+				transform[(numdofs)*(counter+2) + counter+1] = coord_system[2][1];
+				transform[(numdofs)*(counter+2) + counter+2] = coord_system[2][2];
+				counter+=3;
+				break;
+			default:
+				_error_("Coordinate system " << EnumToStringx(cs_array[i]) << " not supported yet");
+		}
+	}
+
+	/*Assign output pointer*/
+	*ptransform=transform;
+}
+/*}}}*/
+void Element::DeleteMaterials(void){/*{{{*/
+	delete this->material;
+}/*}}}*/
+void Element::DeepEcho(void){/*{{{*/
+
+	_printf_(EnumToStringx(this->ObjectEnum())<<" element:\n");
+	_printf_("   id : "<<this->id <<"\n");
+	_printf_("   sid: "<<this->sid<<"\n");
+	if(vertices){
+		int numvertices = this->GetNumberOfVertices();
+		for(int i=0;i<numvertices;i++) vertices[i]->Echo();
+	}
+	else _printf_("vertices = NULL\n");
+
+	if(nodes){
+		int numnodes = this->GetNumberOfNodes();
+		for(int i=0;i<numnodes;i++) nodes[i]->DeepEcho();
+	}
+	else _printf_("nodes = NULL\n");
+
+	if (material) material->DeepEcho();
+	else _printf_("material = NULL\n");
+
+	if (matpar) matpar->DeepEcho();
+	else _printf_("matpar = NULL\n");
+
+	_printf_("   parameters\n");
+	if (parameters) parameters->DeepEcho();
+	else _printf_("parameters = NULL\n");
+
+	_printf_("   inputs\n");
+	if (inputs) inputs->DeepEcho();
+	else _printf_("inputs=NULL\n");
+
+	return;
+}
+/*}}}*/
+void Element::Echo(void){/*{{{*/
+	_printf_(EnumToStringx(this->ObjectEnum())<<" element:\n");
+	_printf_("   id : "<<this->id <<"\n");
+	_printf_("   sid: "<<this->sid<<"\n");
+	if(vertices){
+		int numvertices = this->GetNumberOfVertices();
+		for(int i=0;i<numvertices;i++) vertices[i]->Echo();
+	}
+	else _printf_("vertices = NULL\n");
+
+	if(nodes){
+		int numnodes = this->GetNumberOfNodes();
+		for(int i=0;i<numnodes;i++) nodes[i]->Echo();
+	}
+	else _printf_("nodes = NULL\n");
+
+	if (material) material->Echo();
+	else _printf_("material = NULL\n");
+
+	if (matpar) matpar->Echo();
+	else _printf_("matpar = NULL\n");
+
+	_printf_("   parameters\n");
+	if (parameters) parameters->Echo();
+	else _printf_("parameters = NULL\n");
+
+	_printf_("   inputs\n");
+	if (inputs) inputs->Echo();
+	else _printf_("inputs=NULL\n");
+}
+/*}}}*/
+IssmDouble Element::Divergence(void){/*{{{*/
+	/*Compute element divergence*/
+
+	/*Intermediaries*/
+	IssmDouble Jdet;
+	IssmDouble divergence=0.;
+	IssmDouble dvx[3],dvy[3],dvz[3];
+	IssmDouble *xyz_list = NULL;
+
+	/*Get inputs and parameters*/
+	Input* vx_input        = this->GetInput(VxEnum); _assert_(vx_input);
+	Input* vy_input        = this->GetInput(VyEnum); _assert_(vy_input);
+	Input* vz_input        = this->GetInput(VzEnum); _assert_(vz_input);
+	this->GetVerticesCoordinates(&xyz_list);
+
+	Gauss* gauss=this->NewGaussBase(5);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+		this->JacobianDeterminant(&Jdet,xyz_list,gauss);
+
+		/*Get strain rate assuming that epsilon has been allocated*/
+		vx_input->GetInputDerivativeValue(&dvx[0],xyz_list,gauss);
+		vy_input->GetInputDerivativeValue(&dvy[0],xyz_list,gauss);
+		vz_input->GetInputDerivativeValue(&dvz[0],xyz_list,gauss);
+
+		divergence += (dvx[0]+dvy[1]+dvz[2])*gauss->weight*Jdet;
+	}
+
+	/*Clean up and return*/
+	delete gauss;
+	return divergence;
+}/*}}}*/
+void Element::ThermalToEnthalpy(IssmDouble* penthalpy,IssmDouble temperature,IssmDouble waterfraction,IssmDouble pressure){/*{{{*/
+	matpar->ThermalToEnthalpy(penthalpy,temperature,waterfraction,pressure);
+}/*}}}*/
+void Element::EnthalpyToThermal(IssmDouble* ptemperature,IssmDouble* pwaterfraction,IssmDouble enthalpy,IssmDouble pressure){/*{{{*/
+	matpar->EnthalpyToThermal(ptemperature,pwaterfraction,enthalpy,pressure);
+}/*}}}*/
+IssmDouble Element::EnthalpyDiffusionParameter(IssmDouble enthalpy,IssmDouble pressure){/*{{{*/
+	return matpar->GetEnthalpyDiffusionParameter(enthalpy,pressure);
+}/*}}}*/
+IssmDouble Element::EnthalpyDiffusionParameterVolume(int numvertices,IssmDouble* enthalpy,IssmDouble* pressure){/*{{{*/
+	return matpar->GetEnthalpyDiffusionParameterVolume(numvertices,enthalpy,pressure);
+}/*}}}*/
+void Element::FindParam(bool* pvalue,int paramenum){/*{{{*/
+	this->parameters->FindParam(pvalue,paramenum);
+}/*}}}*/
+void Element::FindParam(int* pvalue,int paramenum){/*{{{*/
+	this->parameters->FindParam(pvalue,paramenum);
+}/*}}}*/
+void Element::FindParam(IssmDouble* pvalue,int paramenum){/*{{{*/
+	this->parameters->FindParam(pvalue,paramenum);
+}/*}}}*/
+void Element::FindParam(int** pvalues,int* psize,int paramenum){/*{{{*/
+	this->parameters->FindParam(pvalues,psize,paramenum);
+}/*}}}*/
+void Element::GetDofList(int** pdoflist,int approximation_enum,int setenum){/*{{{*/
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = this->GetNumberOfNodes();
+
+	/*First, figure out size of doflist and create it: */
+	int numberofdofs=0;
+	for(int i=0;i<numnodes;i++) numberofdofs+=nodes[i]->GetNumberOfDofs(approximation_enum,setenum);
+
+	/*Allocate output*/
+	int* doflist=xNew<int>(numberofdofs);
+
+	/*Populate: */
+	int count=0;
+	for(int i=0;i<numnodes;i++){
+		nodes[i]->GetDofList(doflist+count,approximation_enum,setenum);
+		count+=nodes[i]->GetNumberOfDofs(approximation_enum,setenum);
+	}
+
+	/*Assign output pointers:*/
+	*pdoflist=doflist;
+}
+/*}}}*/
+void Element::GetDofListVelocity(int** pdoflist,int setenum){/*{{{*/
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = this->NumberofNodesVelocity();
+
+	/*First, figure out size of doflist and create it: */
+	int numberofdofs=0;
+	for(int i=0;i<numnodes;i++) numberofdofs+=nodes[i]->GetNumberOfDofs(FSvelocityEnum,setenum);
+
+	/*Allocate output*/
+	int* doflist=xNew<int>(numberofdofs);
+
+	/*Populate: */
+	int count=0;
+	for(int i=0;i<numnodes;i++){
+		nodes[i]->GetDofList(doflist+count,FSvelocityEnum,setenum);
+		count+=nodes[i]->GetNumberOfDofs(FSvelocityEnum,setenum);
+	}
+
+	/*Assign output pointers:*/
+	*pdoflist=doflist;
+}
+/*}}}*/
+void Element::GetDofListPressure(int** pdoflist,int setenum){/*{{{*/
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int vnumnodes = this->NumberofNodesVelocity();
+	int pnumnodes = this->NumberofNodesPressure();
+
+	/*First, figure out size of doflist and create it: */
+	int numberofdofs=0;
+	for(int i=vnumnodes;i<vnumnodes+pnumnodes;i++) numberofdofs+=nodes[i]->GetNumberOfDofs(FSApproximationEnum,setenum);
+
+	/*Allocate output*/
+	int* doflist=xNew<int>(numberofdofs);
+
+	/*Populate: */
+	int count=0;
+	for(int i=vnumnodes;i<vnumnodes+pnumnodes;i++){
+		nodes[i]->GetDofList(doflist+count,FSApproximationEnum,setenum);
+		count+=nodes[i]->GetNumberOfDofs(FSApproximationEnum,setenum);
+	}
+
+	/*Assign output pointers:*/
+	*pdoflist=doflist;
+}
+/*}}}*/
+IssmDouble Element::GetMaterialParameter(int enum_in){/*{{{*/
+
+	_assert_(this->matpar);
+	switch(enum_in){ // FIXME: change this to material
+		case MaterialsRheologyNEnum:
+			return this->material->GetN();
+		case MaterialsRheologyBEnum:
+			return this->material->GetB();
+		case MaterialsRheologyBbarEnum:
+			return this->material->GetBbar();
+		default:
+			return this->matpar->GetMaterialParameter(enum_in);
+	}
+}/*}}}*/
+void Element::GetPhi(IssmDouble* phi, IssmDouble*  epsilon, IssmDouble viscosity){/*{{{*/
+	/*Compute deformational heating from epsilon and viscosity */
+
+	IssmDouble epsilon_matrix[3][3];
+	IssmDouble epsilon_eff;
+	IssmDouble epsilon_sqr[3][3];
+
+	/* Build epsilon matrix */
+	epsilon_matrix[0][0]=epsilon[0];
+	epsilon_matrix[1][0]=epsilon[3];
+	epsilon_matrix[2][0]=epsilon[4];
+	epsilon_matrix[0][1]=epsilon[3];
+	epsilon_matrix[1][1]=epsilon[1];
+	epsilon_matrix[2][1]=epsilon[5];
+	epsilon_matrix[0][2]=epsilon[4];
+	epsilon_matrix[1][2]=epsilon[5];
+	epsilon_matrix[2][2]=epsilon[2];
+
+	/* Effective value of epsilon_matrix */
+	epsilon_sqr[0][0]=epsilon_matrix[0][0]*epsilon_matrix[0][0];
+	epsilon_sqr[1][0]=epsilon_matrix[1][0]*epsilon_matrix[1][0];
+	epsilon_sqr[2][0]=epsilon_matrix[2][0]*epsilon_matrix[2][0];
+	epsilon_sqr[0][1]=epsilon_matrix[0][1]*epsilon_matrix[0][1];
+	epsilon_sqr[1][1]=epsilon_matrix[1][1]*epsilon_matrix[1][1];
+	epsilon_sqr[2][1]=epsilon_matrix[2][1]*epsilon_matrix[2][1];
+	epsilon_sqr[0][2]=epsilon_matrix[0][2]*epsilon_matrix[0][2];
+	epsilon_sqr[1][2]=epsilon_matrix[1][2]*epsilon_matrix[1][2];
+	epsilon_sqr[2][2]=epsilon_matrix[2][2]*epsilon_matrix[2][2];
+	epsilon_eff=1/sqrt(2.)*sqrt(epsilon_sqr[0][0]+epsilon_sqr[0][1]+ epsilon_sqr[0][2]+ epsilon_sqr[1][0]+ epsilon_sqr[1][1]+ epsilon_sqr[1][2]+ epsilon_sqr[2][0]+ epsilon_sqr[2][1]+ epsilon_sqr[2][2]);
+
+	/*Phi = Tr(sigma * eps) 
+	 *    = Tr(sigma'* eps)
+	 *    = 2 * eps_eff * sigma'_eff
+	 *    = 4 * mu * eps_eff ^2*/
+	*phi=4.*epsilon_eff*epsilon_eff*viscosity;
+}
+/*}}}*/
+Input* Element::GetInput(int inputenum){/*{{{*/
+	return inputs->GetInput(inputenum);
+}/*}}}*/
+void Element::GetInputListOnVertices(IssmDouble* pvalue,int enumtype){/*{{{*/
+
+	/*Recover input*/
+	Input* input=this->GetInput(enumtype);
+	if (!input) _error_("Input " << EnumToStringx(enumtype) << " not found in element");
+
+	/*Fetch number vertices for this element*/
+	int numvertices = this->GetNumberOfVertices();
+
+	/*Checks in debugging mode*/
+	_assert_(pvalue);
+
+	/* Start looping on the number of vertices: */
+	Gauss*gauss=this->NewGauss();
+	for(int iv=0;iv<numvertices;iv++){
+		gauss->GaussVertex(iv);
+		input->GetInputValue(&pvalue[iv],gauss);
+	}
+
+	/*clean-up*/
+	delete gauss;
+}
+/*}}}*/
+void Element::GetInputListOnVertices(IssmDouble* pvalue,int enumtype,IssmDouble defaultvalue){/*{{{*/
+
+	/*Recover input*/
+	Input* input=this->GetInput(enumtype);
+
+	/*Checks in debugging mode*/
+	_assert_(pvalue);
+
+	/*Fetch number vertices for this element*/
+	int numvertices = this->GetNumberOfVertices();
+
+	/* Start looping on the number of vertices: */
+	if (input){
+		Gauss* gauss=this->NewGauss();
+		for (int iv=0;iv<numvertices;iv++){
+			gauss->GaussVertex(iv);
+			input->GetInputValue(&pvalue[iv],gauss);
+		}
+		delete gauss;
+	}
+	else{
+		for(int iv=0;iv<numvertices;iv++) pvalue[iv]=defaultvalue;
+	}
+}
+/*}}}*/
+void Element::GetInputListOnNodes(IssmDouble* pvalue,int enumtype,IssmDouble defaultvalue){/*{{{*/
+
+	_assert_(pvalue);
+
+	Input *input    = this->GetInput(enumtype);
+	int    numnodes = this->GetNumberOfNodes();
+
+	/* Start looping on the number of vertices: */
+	if(input){
+		Gauss* gauss=this->NewGauss();
+		for(int iv=0;iv<numnodes;iv++){
+			gauss->GaussNode(this->FiniteElement(),iv);
+			input->GetInputValue(&pvalue[iv],gauss);
+		}
+		delete gauss;
+	}
+	else{
+		for(int iv=0;iv<numnodes;iv++) pvalue[iv]=defaultvalue;
+	}
+}
+/*}}}*/
+void Element::GetInputListOnNodes(IssmDouble* pvalue,int enumtype){/*{{{*/
+
+	_assert_(pvalue);
+
+	int    numnodes = this->GetNumberOfNodes();
+	Input *input    = this->GetInput(enumtype);
+	if(!input) _error_("Input " << EnumToStringx(enumtype) << " not found in element");
+
+	/* Start looping on the number of vertices: */
+	Gauss* gauss=this->NewGauss();
+	for(int iv=0;iv<numnodes;iv++){
+		gauss->GaussNode(this->FiniteElement(),iv);
+		input->GetInputValue(&pvalue[iv],gauss);
+	}
+	delete gauss;
+}
+/*}}}*/
+void Element::GetInputListOnNodesVelocity(IssmDouble* pvalue,int enumtype){/*{{{*/
+
+	_assert_(pvalue);
+
+	int    numnodes = this->NumberofNodesVelocity();
+	Input *input    = this->GetInput(enumtype);
+	if(!input) _error_("Input " << EnumToStringx(enumtype) << " not found in element");
+
+	/* Start looping on the number of vertices: */
+	Gauss* gauss=this->NewGauss();
+	for(int iv=0;iv<numnodes;iv++){
+		gauss->GaussNode(this->VelocityInterpolation(),iv);
+		input->GetInputValue(&pvalue[iv],gauss);
+	}
+	delete gauss;
+}
+/*}}}*/
+void Element::GetInputValue(bool* pvalue,int inputenum){/*{{{*/
+
+	Input* input=inputs->GetInput(inputenum);
+	if(!input) _error_("Input " << EnumToStringx(inputenum) << " not found in element");
+	input->GetInputValue(pvalue);
+
+}/*}}}*/
+void Element::GetInputValue(int* pvalue,int inputenum){/*{{{*/
+
+	Input* input=inputs->GetInput(inputenum);
+	if(!input) _error_("Input " << EnumToStringx(inputenum) << " not found in element");
+	input->GetInputValue(pvalue);
+
+}/*}}}*/
+void Element::GetInputValue(IssmDouble* pvalue,int inputenum){/*{{{*/
+
+	Input* input=inputs->GetInput(inputenum);
+	if(!input) _error_("Input " << EnumToStringx(inputenum) << " not found in element");
+	input->GetInputValue(pvalue);
+
+}/*}}}*/
+void Element::GetInputValue(IssmDouble* pvalue,Gauss* gauss,int inputenum){/*{{{*/
+
+	Input* input=inputs->GetInput(inputenum);
+	if(!input) _error_("Input " << EnumToStringx(inputenum) << " not found in element");
+	input->GetInputValue(pvalue,gauss);
+
+}/*}}}*/
+void Element::GetNodesSidList(int* sidlist){/*{{{*/
+
+	_assert_(sidlist);
+	_assert_(nodes);
+	int numnodes = this->GetNumberOfNodes();
+	for(int i=0;i<numnodes;i++){
+		sidlist[i]=nodes[i]->Sid();
+	}
+}
+/*}}}*/
+void Element::GetNodesLidList(int* lidlist){/*{{{*/
+
+	_assert_(lidlist);
+	_assert_(nodes);
+	int numnodes = this->GetNumberOfNodes();
+	for(int i=0;i<numnodes;i++){
+		lidlist[i]=nodes[i]->Lid();
+	}
+}
+/*}}}*/
+void  Element::GetVectorFromInputs(Vector<IssmDouble>* vector,int input_enum){/*{{{*/
+
+	/*Fetch number vertices for this element and allocate arrays*/
+	int numvertices = this->GetNumberOfVertices();
+	int*        vertexpidlist = xNew<int>(numvertices);
+	IssmDouble* values        = xNew<IssmDouble>(numvertices);
+
+	/*Fill in values*/
+	this->GetVertexPidList(vertexpidlist);
+	this->GetInputListOnVertices(values,input_enum);
+	vector->SetValues(numvertices,vertexpidlist,values,INS_VAL);
+
+	/*Clean up*/
+	xDelete<int>(vertexpidlist);
+	xDelete<IssmDouble>(values);
+
+}
+/*}}}*/
+void  Element::GetVertexPidList(int* pidlist){/*{{{*/
+
+	int numvertices = this->GetNumberOfVertices();
+	for(int i=0;i<numvertices;i++) pidlist[i]=vertices[i]->Pid();
+
+}
+/*}}}*/
+void Element::GetVerticesCoordinates(IssmDouble** pxyz_list){/*{{{*/
+
+	int         numvertices = this->GetNumberOfVertices();
+	IssmDouble* xyz_list    = xNew<IssmDouble>(numvertices*3);
+	::GetVerticesCoordinates(xyz_list,this->vertices,numvertices);
+
+	*pxyz_list = xyz_list;
+
+}/*}}}*/
+void Element::GetVerticesSidList(int* sidlist){/*{{{*/
+
+	int numvertices = this->GetNumberOfVertices();
+	for(int i=0;i<numvertices;i++) sidlist[i]=this->vertices[i]->Sid();
+}
+/*}}}*/
+void Element::GetVerticesConnectivityList(int* connectivity){/*{{{*/
+
+	int numvertices = this->GetNumberOfVertices();
+	for(int i=0;i<numvertices;i++) connectivity[i]=this->vertices[i]->Connectivity();
+}
+/*}}}*/
+bool Element::HasNodeOnBase(){/*{{{*/
+	return (this->inputs->Max(MeshVertexonbaseEnum)>0.);
+}/*}}}*/
+bool Element::HasNodeOnSurface(){/*{{{*/
+	return (this->inputs->Max(MeshVertexonsurfaceEnum)>0.);
+}/*}}}*/
+int  Element::Id(){/*{{{*/
+
+	return this->id;
+
+}
+/*}}}*/
+void Element::InputChangeName(int original_enum,int new_enum){/*{{{*/
+	this->inputs->ChangeEnum(original_enum,new_enum);
+}
+/*}}}*/
+void Element::InputCreate(IssmDouble* vector,IoModel* iomodel,int M,int N,int vector_type,int vector_enum,int code){/*{{{*/
+
+	/*Intermediaries*/
+	int        i,t,row;
+	IssmDouble time;
+
+	/*Branch on type of vector: nodal or elementary: */
+	if(vector_type==1){ //nodal vector
+
+		int         numvertices = this->GetNumberOfVertices();
+		int        *vertexids   = xNew<int>(numvertices);
+		IssmDouble *values      = xNew<IssmDouble>(numvertices);
+
+		/*Recover vertices ids needed to initialize inputs*/
+		_assert_(iomodel->elements);
+		for(i=0;i<numvertices;i++){ 
+			vertexids[i]=reCast<int>(iomodel->elements[numvertices*this->Sid()+i]); //ids for vertices are in the elements array from Matlab
+		}
+
+		/*Are we in transient or static? */
+		if(M==iomodel->numberofvertices){
+			for(i=0;i<numvertices;i++) values[i]=vector[vertexids[i]-1];
+			this->AddInput(vector_enum,values,P1Enum);
+		}
+		else if(M==iomodel->numberofvertices+1){
+			/*create transient input: */
+			IssmDouble* times = xNew<IssmDouble>(N);
+			for(t=0;t<N;t++) times[t] = vector[(M-1)*N+t];
+			TransientInput* transientinput=new TransientInput(vector_enum,times,N);
+			for(t=0;t<N;t++){
+				for(i=0;i<numvertices;i++) values[i]=vector[N*(vertexids[i]-1)+t];
+				switch(this->ObjectEnum()){
+					case TriaEnum:  transientinput->AddTimeInput(new TriaInput( vector_enum,values,P1Enum)); break;
+					case PentaEnum: transientinput->AddTimeInput(new PentaInput(vector_enum,values,P1Enum)); break;
+					case TetraEnum: transientinput->AddTimeInput(new TetraInput(vector_enum,values,P1Enum)); break;
+					default: _error_("Not implemented yet");
+				}
+			}
+			this->inputs->AddInput(transientinput);
+			xDelete<IssmDouble>(times);
+		}
+		else _error_("nodal vector is either numberofvertices or numberofvertices+1 long. Field provided (" << EnumToStringx(vector_enum) << ") is " << M << " long");
+
+		xDelete<IssmDouble>(values);
+		xDelete<int>(vertexids);
+	}
+	else if(vector_type==2){ //element vector
+		/*Are we in transient or static? */
+		if(M==iomodel->numberofelements){
+			if (code==5){ //boolean
+				this->inputs->AddInput(new BoolInput(vector_enum,reCast<bool>(vector[this->Sid()])));
+			}
+			else if (code==6){ //integer
+				this->inputs->AddInput(new IntInput(vector_enum,reCast<int>(vector[this->Sid()])));
+			}
+			else if (code==7){ //IssmDouble
+				this->inputs->AddInput(new DoubleInput(vector_enum,vector[this->Sid()]));
+			}
+			else _error_("could not recognize nature of vector from code " << code);
+		}
+		else {
+			_error_("transient element inputs not supported yet!");
+		}
+	}
+	else{
+		_error_("Cannot add input for vector type " << vector_type << " (not supported)");
+	}
+}/*}}}*/
+void Element::InputUpdateFromConstant(int constant, int name){/*{{{*/
+
+	/*Check that name is an element input*/
+	if(!IsInput(name)) return;
+
+	/*update input*/
+	this->inputs->AddInput(new IntInput(name,constant));
+}
+/*}}}*/
+void Element::InputUpdateFromConstant(IssmDouble constant, int name){/*{{{*/
+
+	/*Check that name is an element input*/
+	if(!IsInput(name)) return;
+
+	/*update input*/
+	this->inputs->AddInput(new DoubleInput(name,constant));
+}
+/*}}}*/
+void Element::InputUpdateFromConstant(bool constant, int name){/*{{{*/
+
+	/*Check that name is an element input*/
+	if(!IsInput(name)) return;
+
+	/*update input*/
+	this->inputs->AddInput(new BoolInput(name,constant));
+}
+/*}}}*/
+bool Element::IsFloating(){/*{{{*/
+
+	bool shelf;
+	int  migration_style;
+	parameters->FindParam(&migration_style,GroundinglineMigrationEnum);
+
+	if(migration_style==SubelementMigrationEnum || migration_style==SubelementMigration2Enum || migration_style==ContactEnum){ //Floating if all nodes are floating
+		if(this->inputs->Max(MaskGroundediceLevelsetEnum) <= 0.) shelf=true;
+		else shelf=false;
+	}
+	else if(migration_style==NoneEnum || migration_style==AgressiveMigrationEnum || migration_style==SoftMigrationEnum){ //Floating if all nodes are floating
+		if(this->inputs->Min(MaskGroundediceLevelsetEnum) > 0.) shelf=false;
+		else shelf=true;
+	}
+	else _error_("migration_style not implemented yet");
+
+	return shelf;
+}/*}}}*/
+bool Element::IsIceInElement(){/*{{{*/
+	return (this->inputs->Min(MaskIceLevelsetEnum)<0.);
+}
+/*}}}*/
+bool Element::IsInput(int name){/*{{{*/
+	if (
+				name==ThicknessEnum ||
+				name==SurfaceEnum ||
+				name==BaseEnum ||
+				name==BedEnum ||
+				name==SurfaceSlopeXEnum ||
+				name==SurfaceSlopeYEnum ||
+				name==SurfaceforcingsMassBalanceEnum ||
+				name==BasalforcingsMeltingRateEnum ||
+				name==BasalforcingsGeothermalfluxEnum ||
+				name==SurfaceAreaEnum||
+				name==DamageDEnum ||
+				name==DamageDbarEnum ||
+				name==PressureEnum ||
+				name==VxEnum ||
+				name==VyEnum ||
+				name==VzEnum ||
+				name==VxMeshEnum ||
+				name==VyMeshEnum ||
+				name==VzMeshEnum ||
+				name==InversionVxObsEnum ||
+				name==InversionVyObsEnum ||
+				name==InversionVzObsEnum ||
+				name==TemperatureEnum ||
+				name==EnthalpyEnum ||
+				name==EnthalpyPicardEnum ||
+				name==WaterfractionEnum||
+				name==WatercolumnEnum || 
+				name==FrictionCoefficientEnum ||
+				name==MaskGroundediceLevelsetEnum ||
+				name==MaskIceLevelsetEnum ||
+				name==IceMaskNodeActivationEnum ||
+				name==LevelsetfunctionSlopeXEnum ||
+				name==LevelsetfunctionSlopeYEnum ||
+				name==LevelsetfunctionPicardEnum ||
+				name==MasstransportCalvingrateEnum ||
+				name==GradientEnum ||
+				name==OldGradientEnum  ||
+				name==ConvergedEnum || 
+				name==QmuVxEnum ||
+				name==QmuVyEnum ||
+				name==QmuVzEnum ||
+				name==QmuVxMeshEnum ||
+				name==QmuVyMeshEnum ||
+				name==QmuVzMeshEnum ||
+				name==QmuPressureEnum ||
+				name==QmuBaseEnum ||
+				name==QmuThicknessEnum ||
+				name==QmuSurfaceEnum ||
+				name==QmuTemperatureEnum ||
+				name==QmuMeltingEnum ||
+				name==QmuMaskGroundediceLevelsetEnum ||
+				name==QmuMaskIceLevelsetEnum ||
+				name==QmuMaterialsRheologyBEnum ||
+				name==MaterialsRheologyBEnum ||
+				name==MaterialsRheologyBbarEnum ||
+				name==MaterialsRheologyNEnum ||
+				name==GiaWEnum || 
+				name==GiadWdtEnum ||
+				name==SedimentHeadEnum ||
+				name==EplHeadEnum ||
+				name==SedimentHeadOldEnum ||
+				name==EplHeadOldEnum ||
+				name==HydrologydcEplThicknessOldEnum ||
+				name==HydrologydcEplInitialThicknessEnum ||
+				name==HydrologydcEplThicknessEnum ||
+				name==HydrologydcMaskEplactiveNodeEnum ||
+				name==MeshVertexonbaseEnum 
+
+				) {
+					return true;
+				}
+	else return false;
+}
+/*}}}*/
+ElementVector* Element::NewElementVector(int approximation_enum){/*{{{*/
+	return new ElementVector(nodes,this->GetNumberOfNodes(),this->parameters,approximation_enum);
+}
+/*}}}*/
+ElementMatrix* Element::NewElementMatrix(int approximation_enum){/*{{{*/
+	return new ElementMatrix(nodes,this->GetNumberOfNodes(),this->parameters,approximation_enum);
+}
+/*}}}*/
+ElementMatrix* Element::NewElementMatrixCoupling(int number_nodes,int approximation_enum){/*{{{*/
+	return new ElementMatrix(nodes,number_nodes,this->parameters,approximation_enum);
+}
+/*}}}*/
+IssmDouble Element::PureIceEnthalpy(IssmDouble pressure){/*{{{*/
+	return this->matpar->PureIceEnthalpy(pressure);
+}/*}}}*/
+void Element::ResultInterpolation(int* pinterpolation,int* pnodesperelement,int output_enum){/*{{{*/
+
+	Input* input=this->inputs->GetInput(output_enum);
+
+	/*If this input is not already in Inputs, maybe it needs to be computed?*/
+	if(!input){
+		switch(output_enum){
+			case ViscousHeatingEnum:
+				this->ViscousHeatingCreateInput();
+				input=this->inputs->GetInput(output_enum);
+				break;
+			case StressTensorxxEnum: 
+			case StressTensorxyEnum: 
+			case StressTensorxzEnum: 
+			case StressTensoryyEnum: 
+			case StressTensoryzEnum: 
+			case StressTensorzzEnum: 
+				this->ComputeStressTensor();
+				input=this->inputs->GetInput(output_enum);
+				break;
+			case DeviatoricStressxxEnum: 
+			case DeviatoricStressxyEnum: 
+			case DeviatoricStressxzEnum: 
+			case DeviatoricStressyyEnum: 
+			case DeviatoricStressyzEnum: 
+			case DeviatoricStresszzEnum: 
+				this->ComputeDeviatoricStressTensor();
+				input=this->inputs->GetInput(output_enum);
+				break;
+			case SigmaNNEnum: 
+				this->ComputeSigmaNN();
+				input=this->inputs->GetInput(output_enum);
+				break;
+			default:
+				_error_("input "<<EnumToStringx(output_enum)<<" not found in element");
+		}
+	}
+
+	/*Assign output pointer*/
+	*pinterpolation   = input->GetResultInterpolation();
+	*pnodesperelement = input->GetResultNumberOfNodes();
+}/*}}}*/
+void Element::ResultToVector(Vector<IssmDouble>* vector,int output_enum){/*{{{*/
+
+	Input* input=this->inputs->GetInput(output_enum);
+	if(!input) _error_("input "<<EnumToStringx(output_enum)<<" not found in element");
+
+	switch(input->GetResultInterpolation()){
+		case P0Enum:{
+			IssmDouble  value;
+			bool        bvalue;
+			Input*      input = this->GetInput(output_enum); _assert_(input);
+			switch(input->ObjectEnum()){
+				case DoubleInputEnum:
+					input->GetInputValue(&value);
+					break;
+				case BoolInputEnum:
+					input->GetInputValue(&bvalue);
+					value=reCast<IssmDouble>(bvalue);
+					break;
+				default:
+					_error_("Input of type "<<EnumToStringx(input->GetResultInterpolation())<<" not supported");
+			}
+			vector->SetValue(this->Sid(),value,INS_VAL);
+			break;
+		}
+		case P1Enum:{
+			int         numvertices = this->GetNumberOfVertices();
+			IssmDouble *values      = xNew<IssmDouble>(numvertices);
+			int        *connectivity= xNew<int>(numvertices);
+			int        *sidlist     = xNew<int>(numvertices);
+
+			this->GetVerticesSidList(sidlist);
+			this->GetVerticesConnectivityList(connectivity);
+			this->GetInputListOnVertices(values,output_enum);
+			for(int i=0;i<numvertices;i++) values[i] = values[i]/reCast<IssmDouble>(connectivity[i]);
+
+			vector->SetValues(numvertices,sidlist,values,ADD_VAL);
+
+			xDelete<IssmDouble>(values);
+			xDelete<int>(connectivity);
+			xDelete<int>(sidlist);
+			break;
+		}
+		default:
+					 _error_("interpolation "<<EnumToStringx(input->GetResultInterpolation())<<" not supported yet");
+	}
+} /*}}}*/
+void Element::ResultToPatch(IssmDouble* values,int nodesperelement,int output_enum){/*{{{*/
+
+	Input* input=this->inputs->GetInput(output_enum);
+	if(!input) _error_("input "<<EnumToStringx(output_enum)<<" not found in element");
+
+	input->ResultToPatch(values,nodesperelement,this->Sid());
+
+} /*}}}*/
+void Element::SetwiseNodeConnectivity(int* pd_nz,int* po_nz,Node* node,bool* flags,int* flagsindices,int set1_enum,int set2_enum){/*{{{*/
+
+	/*Intermediaries*/
+	const int numnodes = this->GetNumberOfNodes();
+
+	/*Output */
+	int d_nz = 0;
+	int o_nz = 0;
+
+	/*Loop over all nodes*/
+	for(int i=0;i<numnodes;i++){
+
+		if(!flags[this->nodes[i]->Lid()]){
+
+			/*flag current node so that no other element processes it*/
+			flags[this->nodes[i]->Lid()]=true;
+
+			int counter=0;
+			while(flagsindices[counter]>=0) counter++;
+			flagsindices[counter]=this->nodes[i]->Lid();
+
+			/*if node is clone, we have an off-diagonal non-zero, else it is a diagonal non-zero*/
+			switch(set2_enum){
+				case FsetEnum:
+					if(nodes[i]->indexing.fsize){
+						if(this->nodes[i]->IsClone())
+						 o_nz += 1;
+						else
+						 d_nz += 1;
+					}
+					break;
+				case GsetEnum:
+					if(nodes[i]->indexing.gsize){
+						if(this->nodes[i]->IsClone())
+						 o_nz += 1;
+						else
+						 d_nz += 1;
+					}
+					break;
+				case SsetEnum:
+					if(nodes[i]->indexing.ssize){
+						if(this->nodes[i]->IsClone())
+						 o_nz += 1;
+						else
+						 d_nz += 1;
+					}
+					break;
+				default: _error_("not supported");
+			}
+		}
+	}
+
+	/*Special case: 2d/3d coupling, the node of this element might be connected
+	 *to the basal element*/
+	int analysis_type,approximation,numlayers;
+	parameters->FindParam(&analysis_type,AnalysisTypeEnum);
+	if(analysis_type==StressbalanceAnalysisEnum){
+		inputs->GetInputValue(&approximation,ApproximationEnum);
+		if(approximation==SSAHOApproximationEnum || approximation==SSAFSApproximationEnum){
+			parameters->FindParam(&numlayers,MeshNumberoflayersEnum);
+			o_nz += numlayers*3;
+			d_nz += numlayers*3;
+		}
+	}
+
+	/*Assign output pointers: */
+	*pd_nz=d_nz;
+	*po_nz=o_nz;
+}
+/*}}}*/
+int  Element::Sid(){/*{{{*/
+
+	return this->sid;
+
+}
+/*}}}*/
+IssmDouble Element::TMeltingPoint(IssmDouble pressure){/*{{{*/
+	_assert_(matpar);
+	return this->matpar->TMeltingPoint(pressure);
+}/*}}}*/
+void Element::ViscousHeatingCreateInput(void){/*{{{*/
+
+	/*Intermediaries*/
+	IssmDouble phi;
+	IssmDouble viscosity;
+	IssmDouble epsilon[6];
+	IssmDouble thickness;
+	IssmDouble *xyz_list = NULL;
+
+	/*Fetch number vertices and allocate memory*/
+	int         numvertices    = this->GetNumberOfVertices();
+	IssmDouble* viscousheating = xNew<IssmDouble>(numvertices);
+
+	/*Retrieve all inputs and parameters*/
+	this->GetVerticesCoordinatesBase(&xyz_list);
+	Input* vx_input        = this->GetInput(VxEnum); _assert_(vx_input);
+	Input* vy_input        = this->GetInput(VyEnum); _assert_(vy_input);
+	Input* vz_input        = this->GetInput(VzEnum); _assert_(vz_input);
+	Input* thickness_input = this->GetInput(ThicknessEnum); _assert_(thickness_input);
+
+	/*loop over vertices: */
+	Gauss* gauss=this->NewGauss();
+	for (int iv=0;iv<numvertices;iv++){
+		gauss->GaussVertex(iv);
+
+		thickness_input->GetInputValue(&thickness,gauss);
+
+		this->StrainRateFS(&epsilon[0],xyz_list,gauss,vx_input,vy_input,vz_input);
+		this->ViscosityFS(&viscosity,3,xyz_list,gauss,vx_input,vy_input,vz_input);
+		this->GetPhi(&phi,&epsilon[0],viscosity);
+
+		viscousheating[iv]=phi*thickness;
+	}
+
+	/*Create PentaVertex input, which will hold the basal friction:*/
+	this->AddInput(ViscousHeatingEnum,viscousheating,P1Enum);
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(viscousheating);
+	delete gauss;
+}
+/*}}}*/
+void Element::ViscosityFS(IssmDouble* pviscosity,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input){/*{{{*/
+	/*The effective strain rate is defined in Paterson 3d Ed p 91 eq 9,
+	 * and Cuffey p 303 eq 8.18:
+	 *
+	 *  2 eps_eff^2 = eps_xx^2 + eps_yy^2 + eps_zz^2 + 2(eps_xy^2 + eps_xz^2 + eps_yz^2)
+	 *
+	 *  or
+	 *
+	 *  eps_eff = 1/sqrt(2) sqrt( \sum_ij eps_ij^2 )
+	 *
+	 *          = 1/sqrt(2) ||eps||_F
+	 *
+	 *  where ||.||_F is the Frobenius norm */
+
+	/*Intermediaries*/
+	IssmDouble viscosity;
+	IssmDouble epsilon3d[6]; /* epsilon=[exx,eyy,ezz,exy,exz,eyz];*/
+	IssmDouble epsilon2d[3]; /* epsilon=[exx,eyy,exy];            */
+	IssmDouble eps_eff;
+	IssmDouble eps0=1.e-27;
+
+	if(dim==3){
+		/* eps_eff^2 = exx^2 + eyy^2 + exy^2 + exz^2 + eyz^2 + exx*eyy */
+		this->StrainRateFS(&epsilon3d[0],xyz_list,gauss,vx_input,vy_input,vz_input);
+		eps_eff = sqrt(epsilon3d[0]*epsilon3d[0] + epsilon3d[1]*epsilon3d[1] + epsilon3d[3]*epsilon3d[3] +  epsilon3d[4]*epsilon3d[4] + epsilon3d[5]*epsilon3d[5] + epsilon3d[0]*epsilon3d[1]+eps0*eps0);
+	}
+	else{
+		/* eps_eff^2 = 1/2 ( exx^2 + eyy^2 + 2*exy^2 )*/
+		this->StrainRateSSA(&epsilon2d[0],xyz_list,gauss,vx_input,vy_input);
+		eps_eff = 1./sqrt(2.)*sqrt(epsilon2d[0]*epsilon2d[0] + epsilon2d[1]*epsilon2d[1] + 2.*epsilon2d[2]*epsilon2d[2]);
+	}
+
+	/*Get viscosity*/
+	material->GetViscosity(&viscosity,eps_eff);
+
+	/*Assign output pointer*/
+	*pviscosity=viscosity;
+}
+/*}}}*/
+void Element::ViscosityL1L2(IssmDouble* pviscosity,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* surface_input){/*{{{*/
+	/*Compute the L1L2 viscosity
+	 *
+	 *      1
+	 * mu = - A^-1 (sigma'_e)^(1-n)
+	 *      2
+	 *
+	 * sigma'_e^2 = |sigma'_//|^2 + |sigma'_perp|^2 (see Perego 2012 eq. 17,18)
+	 *
+	 * L1L2 assumptions:
+	 *
+	 * (1) |eps_b|_// = A (|sigma'_//|^2 + |sigma'_perp|^2)^((n-1)/2) |sigma'_//|
+	 * (2) |sigma'_perp|^2 = |rho g (s-z) grad(s)|^2
+	 *
+	 * Assuming that n = 3, we have a polynom of degree 3 to solve (the only unkown is X=|sigma'_//|)
+	 *
+	 * A X^3 + A |rho g (s-z) grad(s)|^2 X - |eps_b|_// = 0     */
+
+	IssmDouble z,s,viscosity,p,q,delta;
+	IssmDouble tau_perp,tau_par,eps_b,A;
+	IssmDouble epsilon[5];   /*exx eyy exy exz eyz*/
+	IssmDouble slope[3];
+
+	/*Check that both inputs have been found*/
+	if (!vx_input || !vy_input || !surface_input) _error_("Input missing");
+
+	/*Get tau_perp*/
+	surface_input->GetInputValue(&s,gauss);
+	surface_input->GetInputDerivativeValue(&slope[0],xyz_list,gauss);
+	z=GetZcoord(gauss);
+	tau_perp = matpar->GetRhoIce() * matpar->GetG() * fabs(s-z)*sqrt(slope[0]*slope[0]+slope[1]*slope[1]);
+
+	/* Get eps_b*/
+	this->StrainRateHO(&epsilon[0],xyz_list,gauss,vx_input,vy_input);
+	eps_b = sqrt(epsilon[0]*epsilon[0] + epsilon[1]*epsilon[1] + epsilon[0]*epsilon[1] + epsilon[2]*epsilon[2]);
+	if(eps_b==0.){
+		*pviscosity = 2.5e+17;
+		return;
+	}
+
+	/*Get A*/
+	_assert_(material->GetN()==3.0);
+	A=material->GetA();
+
+	/*Solve for tau_perp (http://fr.wikipedia.org/wiki/Méthode_de_Cardan)*/
+	p     = tau_perp *tau_perp;
+	q     = - eps_b/A;
+	delta = q *q + p*p*p*4./27.;
+	_assert_(delta>0);
+	tau_par = pow(0.5*(-q+sqrt(delta)),1./3.) - pow(0.5*(q+sqrt(delta)),1./3.);
+
+	/*Viscosity*/
+	viscosity = 1./(2.*A*(tau_par*tau_par + tau_perp*tau_perp));
+	_assert_(!xIsNan(viscosity));
+	_assert_(viscosity > 0.);
+
+	/*Assign output pointer*/
+	*pviscosity = viscosity;
+}/*}}}*/
+void Element::ViscosityHO(IssmDouble* pviscosity,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input){/*{{{*/
+
+	/*Intermediaries*/
+	IssmDouble viscosity;
+	IssmDouble epsilon3d[5];/* epsilon=[exx,eyy,exy,exz,eyz];*/
+	IssmDouble epsilon2d[2];/* epsilon=[exx,exy];            */
+	IssmDouble eps_eff;
+
+	if(dim==3){
+		/* eps_eff^2 = exx^2 + eyy^2 + exy^2 + exz^2 + eyz^2 + exx*eyy */
+		this->StrainRateHO(&epsilon3d[0],xyz_list,gauss,vx_input,vy_input);
+		eps_eff = sqrt(epsilon3d[0]*epsilon3d[0] + epsilon3d[1]*epsilon3d[1] + epsilon3d[2]*epsilon3d[2] +  epsilon3d[3]*epsilon3d[3] + epsilon3d[4]*epsilon3d[4] + epsilon3d[0]*epsilon3d[1]);
+	}
+	else{
+		/* eps_eff^2 = 1/2 (exx^2 + 2*exy^2 )*/
+		this->StrainRateHO2dvertical(&epsilon2d[0],xyz_list,gauss,vx_input,vy_input);
+		eps_eff = 1./sqrt(2.)*sqrt(epsilon2d[0]*epsilon2d[0] + 2.*epsilon2d[1]*epsilon2d[1]);
+	}
+
+	/*Get viscosity*/
+	material->GetViscosity(&viscosity,eps_eff);
+
+	/*Assign output pointer*/
+	*pviscosity=viscosity;
+}/*}}}*/
+void Element::ViscositySSA(IssmDouble* pviscosity,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input){/*{{{*/
+
+	/*Intermediaries*/
+	IssmDouble viscosity;
+	IssmDouble epsilon2d[3];/* epsilon=[exx,eyy,exy];    */
+	IssmDouble epsilon1d;   /* epsilon=[exx];    */
+	IssmDouble eps_eff;
+
+	 if(dim==2){
+		 /* eps_eff^2 = exx^2 + eyy^2 + exy^2 + exx*eyy*/
+		 this->StrainRateSSA(&epsilon2d[0],xyz_list,gauss,vx_input,vy_input);
+		 eps_eff = sqrt(epsilon2d[0]*epsilon2d[0] + epsilon2d[1]*epsilon2d[1] + epsilon2d[2]*epsilon2d[2] + epsilon2d[0]*epsilon2d[1]);
+	 }
+	 else{
+		 /* eps_eff^2 = 1/2 exx^2*/
+		 this->StrainRateSSA1d(&epsilon1d,xyz_list,gauss,vx_input);
+		 eps_eff = sqrt(epsilon1d*epsilon1d/2.);
+	 }
+
+	/*Get viscosity*/
+	material->GetViscosityBar(&viscosity,eps_eff);
+
+	/*Assign output pointer*/
+	*pviscosity=viscosity;
+}/*}}}*/
+void Element::ViscositySSADerivativeEpsSquare(IssmDouble* pmu_prime,IssmDouble* epsilon){/*{{{*/
+	this->material->GetViscosity2dDerivativeEpsSquare(pmu_prime,epsilon);
+}/*}}}*/
+void Element::ViscosityHODerivativeEpsSquare(IssmDouble* pmu_prime,IssmDouble* epsilon){/*{{{*/
+	this->material->GetViscosityDerivativeEpsSquare(pmu_prime,epsilon);
+}/*}}}*/
+void Element::ViscosityFSDerivativeEpsSquare(IssmDouble* pmu_prime,IssmDouble* epsilon){/*{{{*/
+	this->material->GetViscosityDerivativeEpsSquare(pmu_prime,epsilon);
+}/*}}}*/
+void Element::StrainRateFS(IssmDouble* epsilon,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input){/*{{{*/
+	/*Compute the 3d Strain Rate (6 components):
+	 *
+	 * epsilon=[exx eyy ezz exy exz eyz]
+	 */
+
+	/*Intermediaries*/
+	IssmDouble dvx[3];
+	IssmDouble dvy[3];
+	IssmDouble dvz[3];
+
+	/*Check that both inputs have been found*/
+	if (!vx_input || !vy_input || !vz_input){
+		_error_("Input missing. Here are the input pointers we have for vx: " << vx_input << ", vy: " << vy_input << ", vz: " << vz_input << "\n");
+	}
+
+	/*Get strain rate assuming that epsilon has been allocated*/
+	vx_input->GetInputDerivativeValue(&dvx[0],xyz_list,gauss);
+	vy_input->GetInputDerivativeValue(&dvy[0],xyz_list,gauss);
+	vz_input->GetInputDerivativeValue(&dvz[0],xyz_list,gauss);
+	epsilon[0] = dvx[0];
+	epsilon[1] = dvy[1];
+	epsilon[2] = dvz[2];
+	epsilon[3] = 0.5*(dvx[1] + dvy[0]);
+	epsilon[4] = 0.5*(dvx[2] + dvz[0]);
+	epsilon[5] = 0.5*(dvy[2] + dvz[1]);
+
+}/*}}}*/
+void Element::StrainRateHO(IssmDouble* epsilon,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input){/*{{{*/
+	/*Compute the 3d Blatter/HOStrain Rate (5 components):
+	 *
+	 * epsilon=[exx eyy exy exz eyz]
+	 *
+	 * with exz=1/2 du/dz
+	 *      eyz=1/2 dv/dz
+	 *
+	 * the contribution of vz is neglected
+	 */
+
+	/*Intermediaries*/
+	IssmDouble dvx[3];
+	IssmDouble dvy[3];
+
+	/*Check that both inputs have been found*/
+	if (!vx_input || !vy_input){
+		_error_("Input missing. Here are the input pointers we have for vx: " << vx_input << ", vy: " << vy_input << "\n");
+	}
+
+	/*Get strain rate assuming that epsilon has been allocated*/
+	vx_input->GetInputDerivativeValue(&dvx[0],xyz_list,gauss);
+	vy_input->GetInputDerivativeValue(&dvy[0],xyz_list,gauss);
+	epsilon[0] = dvx[0];
+	epsilon[1] = dvy[1];
+	epsilon[2] = 0.5*(dvx[1] + dvy[0]);
+	epsilon[3] = 0.5*dvx[2];
+	epsilon[4] = 0.5*dvy[2];
+
+}/*}}}*/
+void Element::StrainRateHO2dvertical(IssmDouble* epsilon,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input){/*{{{*/
+	/*Compute the 2d Blatter/HOStrain Rate (2 components):
+	 *
+	 * epsilon=[exx exz]
+	 *
+	 * with exz=1/2 du/dz
+	 *
+	 * the contribution of vz is neglected
+	 */
+
+	/*Intermediaries*/
+	IssmDouble dvx[3];
+
+	/*Check that both inputs have been found*/
+	if (!vx_input){
+		_error_("Input missing. Here are the input pointers we have for vx: " << vx_input <<"\n");
+	}
+
+	/*Get strain rate assuming that epsilon has been allocated*/
+	vx_input->GetInputDerivativeValue(&dvx[0],xyz_list,gauss);
+	epsilon[0] = dvx[0];
+	epsilon[1] = 0.5*dvx[1];
+
+}/*}}}*/
+void Element::StrainRateSSA(IssmDouble* epsilon,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input){/*{{{*/
+
+	/*Intermediaries*/
+	IssmDouble dvx[3];
+	IssmDouble dvy[3];
+
+	/*Check that both inputs have been found*/
+	if(!vx_input || !vy_input){
+		_error_("Input missing. Here are the input pointers we have for vx: " << vx_input << ", vy: " << vy_input << "\n");
+	}
+
+	/*Get strain rate assuming that epsilon has been allocated*/
+	vx_input->GetInputDerivativeValue(&dvx[0],xyz_list,gauss);
+	vy_input->GetInputDerivativeValue(&dvy[0],xyz_list,gauss);
+	epsilon[0] = dvx[0];
+	epsilon[1] = dvy[1];
+	epsilon[2] = 0.5*(dvx[1] + dvy[0]);
+
+}/*}}}*/
+void Element::StrainRateSSA1d(IssmDouble* epsilon,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input){/*{{{*/
+
+	/*Intermediaries*/
+	IssmDouble dvx[3];
+
+	/*Check that both inputs have been found*/
+	if (!vx_input){
+		_error_("Input missing. Here are the input pointers we have for vx: " << vx_input << "\n");
+	}
+
+	/*Get strain rate assuming that epsilon has been allocated*/
+	vx_input->GetInputDerivativeValue(&dvx[0],xyz_list,gauss);
+	*epsilon = dvx[0];
+
+}/*}}}*/
+void Element::TransformInvStiffnessMatrixCoord(ElementMatrix* Ke,int transformenum){/*{{{*/
+
+	/*All nodes have the same Coordinate System*/
+	int numnodes  = this->GetNumberOfNodes();
+	int* cs_array = xNew<int>(numnodes);
+	for(int i=0;i<numnodes;i++) cs_array[i]=transformenum;
+
+	/*Call core*/
+	TransformInvStiffnessMatrixCoord(Ke,this->nodes,numnodes,cs_array);
+
+	/*Clean-up*/
+	xDelete<int>(cs_array);
+}/*}}}*/
+void Element::TransformInvStiffnessMatrixCoord(ElementMatrix* Ke,Node** nodes_list,int numnodes,int* cs_array){/*{{{*/
+
+	int         i,j;
+	int         numdofs   = 0;
+	IssmDouble *transform = NULL;
+	IssmDouble *values    = NULL;
+
+	/*Get total number of dofs*/
+	for(i=0;i<numnodes;i++){
+		switch(cs_array[i]){
+			case PressureEnum: numdofs+=1; break;
+			case XYEnum:       numdofs+=2; break;
+			case XYZEnum:      numdofs+=3; break;
+			default: _error_("Coordinate system " << EnumToStringx(cs_array[i]) << " not supported yet");
+		}
+	}
+
+	/*Copy current stiffness matrix*/
+	values=xNew<IssmDouble>(Ke->nrows*Ke->ncols);
+	for(i=0;i<Ke->nrows;i++) for(j=0;j<Ke->ncols;j++) values[i*Ke->ncols+j]=Ke->values[i*Ke->ncols+j];
+
+	/*Get Coordinate Systems transform matrix*/
+	CoordinateSystemTransform(&transform,nodes_list,numnodes,cs_array);
+
+	/*Transform matrix: R*Ke*R^T */
+	TripleMultiply(transform,numdofs,numdofs,0,
+				values,Ke->nrows,Ke->ncols,0,
+				transform,numdofs,numdofs,1,
+				&Ke->values[0],0);
+
+	/*Free Matrix*/
+	xDelete<IssmDouble>(transform);
+	xDelete<IssmDouble>(values);
+}/*}}}*/
+void Element::TransformLoadVectorCoord(ElementVector* pe,int transformenum){/*{{{*/
+
+	/*All nodes have the same Coordinate System*/
+	int  numnodes = this->GetNumberOfNodes();
+	int* cs_array = xNew<int>(numnodes);
+	for(int i=0;i<numnodes;i++) cs_array[i]=transformenum;
+
+	/*Call core*/
+	this->TransformLoadVectorCoord(pe,this->nodes,numnodes,cs_array);
+
+	/*Clean-up*/
+	xDelete<int>(cs_array);
+}/*}}}*/
+void Element::TransformLoadVectorCoord(ElementVector* pe,int* cs_array){/*{{{*/
+
+	this->TransformLoadVectorCoord(pe,this->nodes,this->GetNumberOfNodes(),cs_array);
+
+}/*}}}*/
+void Element::TransformLoadVectorCoord(ElementVector* pe,Node** nodes_list,int numnodes,int* cs_array){/*{{{*/
+
+	int         i;
+	int         numdofs   = 0;
+	IssmDouble *transform = NULL;
+	IssmDouble *values    = NULL;
+
+	/*Get total number of dofs*/
+	for(i=0;i<numnodes;i++){
+		switch(cs_array[i]){
+			case PressureEnum: numdofs+=1; break;
+			case XYEnum:       numdofs+=2; break;
+			case XYZEnum:      numdofs+=3; break;
+			default: _error_("Coordinate system " << EnumToStringx(cs_array[i]) << " not supported yet");
+		}
+	}
+
+	/*Copy current load vector*/
+	values=xNew<IssmDouble>(pe->nrows);
+	for(i=0;i<pe->nrows;i++) values[i]=pe->values[i];
+
+	/*Get Coordinate Systems transform matrix*/
+	CoordinateSystemTransform(&transform,nodes_list,numnodes,cs_array);
+
+	/*Transform matrix: R^T*pe */
+	MatrixMultiply(transform,numdofs,numdofs,1,
+				values,pe->nrows,1,0,
+				&pe->values[0],0);
+
+	/*Free Matrices*/
+	xDelete<IssmDouble>(transform);
+	xDelete<IssmDouble>(values);
+}/*}}}*/
+void Element::TransformSolutionCoord(IssmDouble* values,int transformenum){/*{{{*/
+
+	/*All nodes have the same Coordinate System*/
+	int  numnodes = this->GetNumberOfNodes();
+	int* cs_array = xNew<int>(numnodes);
+	for(int i=0;i<numnodes;i++) cs_array[i]=transformenum;
+
+	/*Call core*/
+	this->TransformSolutionCoord(values,this->nodes,numnodes,cs_array);
+
+	/*Clean-up*/
+	xDelete<int>(cs_array);
+}/*}}}*/
+void Element::TransformSolutionCoord(IssmDouble* values,int* transformenum_list){/*{{{*/
+	this->TransformSolutionCoord(values,this->nodes,this->GetNumberOfNodes(),transformenum_list);
+}/*}}}*/
+void Element::TransformSolutionCoord(IssmDouble* values,int numnodes,int transformenum){/*{{{*/
+
+	/*All nodes have the same Coordinate System*/
+	int* cs_array = xNew<int>(numnodes);
+	for(int i=0;i<numnodes;i++) cs_array[i]=transformenum;
+
+	/*Call core*/
+	this->TransformSolutionCoord(values,this->nodes,numnodes,cs_array);
+
+	/*Clean-up*/
+	xDelete<int>(cs_array);
+}/*}}}*/
+void Element::TransformSolutionCoord(IssmDouble* solution,int numnodes,int* cs_array){/*{{{*/
+	this->TransformSolutionCoord(solution,this->nodes,numnodes,cs_array);
+}/*}}}*/
+void Element::TransformSolutionCoord(IssmDouble* values,Node** nodes_list,int numnodes,int transformenum){/*{{{*/
+	/*NOT NEEDED*/
+	/*All nodes have the same Coordinate System*/
+	int* cs_array = xNew<int>(numnodes);
+	for(int i=0;i<numnodes;i++) cs_array[i]=transformenum;
+
+	/*Call core*/
+	this->TransformSolutionCoord(values,nodes_list,numnodes,cs_array);
+
+	/*Clean-up*/
+	xDelete<int>(cs_array);
+}/*}}}*/
+void Element::TransformSolutionCoord(IssmDouble* solution,Node** nodes_list,int numnodes,int* cs_array){/*{{{*/
+
+	int         i;
+	int         numdofs   = 0;
+	IssmDouble *transform = NULL;
+	IssmDouble *values    = NULL;
+
+	/*Get total number of dofs*/
+	for(i=0;i<numnodes;i++){
+		switch(cs_array[i]){
+			case PressureEnum: numdofs+=1; break;
+			case XYEnum:       numdofs+=2; break;
+			case XYZEnum:      numdofs+=3; break;
+			default: _error_("Coordinate system " << EnumToStringx(cs_array[i]) << " not supported yet");
+		}
+	}
+
+	/*Copy current solution vector*/
+	values=xNew<IssmDouble>(numdofs);
+	for(i=0;i<numdofs;i++) values[i]=solution[i];
+
+	/*Get Coordinate Systems transform matrix*/
+	CoordinateSystemTransform(&transform,nodes_list,numnodes,cs_array);
+
+	/*Transform matrix: R*U */
+	MatrixMultiply(transform,numdofs,numdofs,0,
+				values,numdofs,1,0,
+				&solution[0],0);
+
+	/*Free Matrices*/
+	xDelete<IssmDouble>(transform);
+	xDelete<IssmDouble>(values);
+}/*}}}*/
+void Element::TransformStiffnessMatrixCoord(ElementMatrix* Ke,int transformenum){/*{{{*/
+
+	/*All nodes have the same Coordinate System*/
+	int  numnodes = this->GetNumberOfNodes();
+	int* cs_array = xNew<int>(numnodes);
+	for(int i=0;i<numnodes;i++) cs_array[i]=transformenum;
+
+	/*Call core*/
+	this->TransformStiffnessMatrixCoord(Ke,this->nodes,numnodes,cs_array);
+
+	/*Clean-up*/
+	xDelete<int>(cs_array);
+}/*}}}*/
+void Element::TransformStiffnessMatrixCoord(ElementMatrix* Ke,int* transformenum_list){/*{{{*/
+	this->TransformStiffnessMatrixCoord(Ke,this->nodes,this->GetNumberOfNodes(),transformenum_list);
+}/*}}}*/
+void Element::TransformStiffnessMatrixCoord(ElementMatrix* Ke,Node** nodes_list,int numnodes,int* cs_array){/*{{{*/
+
+	int         numdofs = 0;
+	IssmDouble *transform = NULL;
+	IssmDouble *values    = NULL;
+
+	/*Get total number of dofs*/
+	for(int i=0;i<numnodes;i++){
+		switch(cs_array[i]){
+			case PressureEnum: numdofs+=1; break;
+			case XYEnum:       numdofs+=2; break;
+			case XYZEnum:      numdofs+=3; break;
+			default: _error_("Coordinate system " << EnumToStringx(cs_array[i]) << " not supported yet");
+		}
+	}
+
+	/*Copy current stiffness matrix*/
+	values=xNew<IssmDouble>(Ke->nrows*Ke->ncols);
+	for(int i=0;i<Ke->nrows*Ke->ncols;i++) values[i]=Ke->values[i];
+
+	/*Get Coordinate Systems transform matrix*/
+	CoordinateSystemTransform(&transform,nodes_list,numnodes,cs_array);
+
+	/*Transform matrix: R^T*Ke*R */
+	TripleMultiply(transform,numdofs,numdofs,1,
+				values,Ke->nrows,Ke->ncols,0,
+				transform,numdofs,numdofs,0,
+				&Ke->values[0],0);
+
+	/*Free Matrix*/
+	xDelete<IssmDouble>(transform);
+	xDelete<IssmDouble>(values);
+}/*}}}*/
Index: /issm/trunk/src/c/classes/Elements/Element.h
===================================================================
--- /issm/trunk/src/c/classes/Elements/Element.h	(revision 17805)
+++ /issm/trunk/src/c/classes/Elements/Element.h	(revision 17806)
@@ -11,68 +11,239 @@
 /*{{{*/
 #include "../../datastructures/datastructures.h"
+#include "../../toolkits/toolkits.h"
 #include "../Update.h"
-
 class DataSet;
 class Parameters;
+class Parameter;
 class Elements;
 class Loads;
+class Nodes;
 class Node;
-class Nodes;
 class Vertices;
+class Vertex;
 class Materials;
+class Material;
+class Matpar;
+class Inputs;
+class Input;
+class Gauss;
+class ElementVector;
 template <class doublematrix> class Matrix;
 template <class doubletype> class Vector;
-
-#include "../../toolkits/toolkits.h"
+class ElementMatrix;
+class ElementVector;
 /*}}}*/
 
 class Element: public Object,public Update{
 
+	public:
+		int          id;
+		int          sid;
+		Inputs      *inputs;
+		Node       **nodes;
+		Vertex     **vertices;
+		Material    *material;
+		Matpar      *matpar;
+		Parameters  *parameters;
+
 	public: 
-
-		virtual        ~Element(){};
-
-		virtual void   Configure(Elements* elements,Loads* loads,Nodes* nodes,Vertices* vertices,Materials* materials,Parameters* parameters)=0;
-		virtual void   SetCurrentConfiguration(Elements* elements,Loads* loads,Nodes* nodes,Materials* materials,Parameters* parameters)=0;
-		virtual void   SetwiseNodeConnectivity(int* d_nz,int* o_nz,Node* node,bool* flags,int* flagsindices,int set1_enum,int set2_enum)=0;
-		virtual void   CreateKMatrix(Matrix<IssmDouble>* Kff, Matrix<IssmDouble>*  Kfs)=0;
-		virtual void   CreateDVector(Vector<IssmDouble>* df)=0;
-		virtual void   CreatePVector(Vector<IssmDouble>* pf)=0;
-		virtual void   CreateJacobianMatrix(Matrix<IssmDouble>* Jff)=0;
-		virtual void   GetSolutionFromInputs(Vector<IssmDouble>* solution)=0;
+		/*Constructors/Destructores*/
+		Element();
+		~Element();
+
+		/*Functions*/
+		void       AddInput(Input* input_in);
+		/* bool       AllActive(void); */
+		/* bool       AnyActive(void); */
+		void       CoordinateSystemTransform(IssmDouble** ptransform,Node** nodes,int numnodes,int* cs_array);
+		void       Echo();
+		void       DeepEcho();
+		void       DeleteMaterials(void);
+		IssmDouble Divergence(void);
+		void       ThermalToEnthalpy(IssmDouble* penthalpy,IssmDouble temperature,IssmDouble waterfraction,IssmDouble pressure);
+		void       EnthalpyToThermal(IssmDouble* ptemperature,IssmDouble* pwaterfraction,IssmDouble enthalpy,IssmDouble pressure);
+		IssmDouble EnthalpyDiffusionParameter(IssmDouble enthalpy,IssmDouble pressure);
+		IssmDouble EnthalpyDiffusionParameterVolume(int numvertices,IssmDouble* enthalpy,IssmDouble* pressure);
+		void       FindParam(bool* pvalue,int paramenum);
+		void       FindParam(int* pvalue,int paramenum);
+		void       FindParam(IssmDouble* pvalue,int paramenum);
+		void       FindParam(int** pvalues,int* psize,int paramenum);
+		void	     GetDofList(int** pdoflist,int approximation_enum,int setenum);
+		void	     GetDofListVelocity(int** pdoflist,int setenum);
+		void	     GetDofListPressure(int** pdoflist,int setenum);
+		Input*     GetInput(int inputenum);
+		void       GetInputListOnNodes(IssmDouble* pvalue,int enumtype);
+		void       GetInputListOnNodes(IssmDouble* pvalue,int enumtype,IssmDouble defaultvalue);
+		void       GetInputListOnNodesVelocity(IssmDouble* pvalue,int enumtype);
+		void       GetInputListOnVertices(IssmDouble* pvalue,int enumtype);
+		void       GetInputListOnVertices(IssmDouble* pvalue,int enumtype,IssmDouble defaultvalue);
+		void       GetInputValue(bool* pvalue,int enum_type);
+		void       GetInputValue(int* pvalue,int enum_type);
+		void       GetInputValue(IssmDouble* pvalue,int enum_type);
+		void       GetInputValue(IssmDouble* pvalue,Gauss* gauss,int enum_type);
+		IssmDouble GetMaterialParameter(int enum_in);
+		void       GetNodesSidList(int* sidlist);
+		void       GetNodesLidList(int* lidlist);
+		void       GetPhi(IssmDouble* phi, IssmDouble*  epsilon, IssmDouble viscosity);
+		void       GetVectorFromInputs(Vector<IssmDouble>* vector, int name_enum);
+		void	     GetVertexPidList(int* pidlist);
+		void       GetVerticesCoordinates(IssmDouble** xyz_list);
+		void       GetVerticesSidList(int* sidlist);
+		void       GetVerticesConnectivityList(int* connectivitylist);
+		bool       HasNodeOnBase();
+		bool       HasNodeOnSurface();
+		int        Id();
+		int        Sid();
+		void       InputChangeName(int enum_type,int enum_type_old);
+		void       InputCreate(IssmDouble* vector,IoModel* iomodel,int M,int N,int vector_type,int vector_enum,int code);
+		void       InputUpdateFromConstant(IssmDouble constant, int name);
+		void       InputUpdateFromConstant(int constant, int name);
+		void       InputUpdateFromConstant(bool constant, int name);
+		bool       IsIceInElement();
+		bool	     IsInput(int name);
+		bool       IsFloating(); 
+		ElementVector*  NewElementVector(int approximation_enum=NoneApproximationEnum);
+		ElementMatrix*  NewElementMatrix(int approximation_enum=NoneApproximationEnum);
+		ElementMatrix*  NewElementMatrixCoupling(int number_nodes,int approximation_enum=NoneApproximationEnum);
+		IssmDouble PureIceEnthalpy(IssmDouble pressure);
+		void       ResultInterpolation(int* pinterpolation,int*nodesperelement,int output_enum);
+		void       ResultToVector(Vector<IssmDouble>* vector,int output_enum);
+		void       ResultToPatch(IssmDouble* values,int nodesperelement,int output_enum);
+		void       SetwiseNodeConnectivity(int* d_nz,int* o_nz,Node* node,bool* flags,int* flagsindices,int set1_enum,int set2_enum);
+		void       StrainRateSSA(IssmDouble* epsilon,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input);
+		void       StrainRateSSA1d(IssmDouble* epsilon,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input);
+		void       StrainRateHO(IssmDouble* epsilon,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input);
+		void       StrainRateHO2dvertical(IssmDouble* epsilon,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input);
+		void       StrainRateFS(IssmDouble* epsilon,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input);
+		IssmDouble TMeltingPoint(IssmDouble pressure);
+		void       TransformInvStiffnessMatrixCoord(ElementMatrix* Ke,int cs_enum);
+		void       TransformInvStiffnessMatrixCoord(ElementMatrix* Ke,Node** nodes,int numnodes,int cs_enum);
+		void       TransformInvStiffnessMatrixCoord(ElementMatrix* Ke,Node** nodes,int numnodes,int* cs_array);
+		void       TransformLoadVectorCoord(ElementVector* pe,int cs_enum);
+		void       TransformLoadVectorCoord(ElementVector* pe,int* cs_array);
+		void       TransformLoadVectorCoord(ElementVector* pe,Node** nodes,int numnodes,int cs_enum);
+		void       TransformLoadVectorCoord(ElementVector* pe,Node** nodes,int numnodes,int* cs_array);
+		void       TransformSolutionCoord(IssmDouble* solution,int cs_enum);
+		void       TransformSolutionCoord(IssmDouble* solution,int* cs_array);
+		void       TransformSolutionCoord(IssmDouble* solution,int numnodes,int cs_enum);
+		void       TransformSolutionCoord(IssmDouble* solution,int numnodes,int* cs_array);
+		void       TransformSolutionCoord(IssmDouble* solution,Node** nodes,int numnodes,int cs_enum);
+		void       TransformSolutionCoord(IssmDouble* solution,Node** nodes,int numnodes,int* cs_array);
+		void       TransformStiffnessMatrixCoord(ElementMatrix* Ke,int cs_enum);
+		void       TransformStiffnessMatrixCoord(ElementMatrix* Ke,int* cs_array);
+		void       TransformStiffnessMatrixCoord(ElementMatrix* Ke,Node** nodes,int numnodes,int cs_enum);
+		void       TransformStiffnessMatrixCoord(ElementMatrix* Ke,Node** nodes,int numnodes,int* cs_array);
+		void       ViscousHeatingCreateInput(void);
+		void       ViscosityFS(IssmDouble* pviscosity,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input);
+		void       ViscosityHO(IssmDouble* pviscosity,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input);
+		void       ViscosityL1L2(IssmDouble* pviscosity,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* surf);
+		void       ViscositySSA(IssmDouble* pviscosity,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input);
+		void       ViscositySSADerivativeEpsSquare(IssmDouble* pmu_prime,IssmDouble* epsilon);
+		void       ViscosityHODerivativeEpsSquare(IssmDouble* pmu_prime,IssmDouble* epsilon);
+		void       ViscosityFSDerivativeEpsSquare(IssmDouble* pmu_prime,IssmDouble* epsilon);
+		void       TransformLoadVectorCoord(ElementVector* pe,int numnodes,int transformenum){_error_("not implemented yet");};/*Tiling only*/
+		void       TransformLoadVectorCoord(ElementVector* pe,int numnodes,int* transformenum_list){_error_("not implemented yet");};/*Tiling only*/
+		void       TransformStiffnessMatrixCoord(ElementMatrix* Ke,int numnodes,int* transformenum_list){_error_("not implemented yet");};/*Tiling only*/
+
+		/*Virtual functions*/
+		virtual void       AddBasalInput(int input_enum, IssmDouble* values, int interpolation_enum)=0;
+		virtual void       AddInput(int input_enum, IssmDouble* values, int interpolation_enum)=0;
+		virtual IssmDouble CharacteristicLength(void)=0;
+		virtual void       Configure(Elements* elements,Loads* loads,Nodes* nodes,Vertices* vertices,Materials* materials,Parameters* parameters)=0;
+		virtual void       SetCurrentConfiguration(Elements* elements,Loads* loads,Nodes* nodes,Materials* materials,Parameters* parameters)=0;
+		virtual void   ElementSizes(IssmDouble* phx,IssmDouble* phy,IssmDouble* phz)=0;
+
+		virtual int    FiniteElement(void)=0;
+		virtual IssmDouble MinEdgeLength(IssmDouble* xyz_list)=0;
+		virtual void   NodalFunctions(IssmDouble* basis,Gauss* gauss)=0;
+		virtual void   NodalFunctionsP1(IssmDouble* basis,Gauss* gauss)=0;
+		virtual void   NodalFunctionsVelocity(IssmDouble* basis, Gauss* gauss)=0;
+		virtual void   NodalFunctionsPressure(IssmDouble* basis, Gauss* gauss)=0;
+		virtual void   NodalFunctionsTensor(IssmDouble* basis, Gauss* gauss)=0;
+		virtual void   NodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss)=0;
+		virtual void   NodalFunctionsP1Derivatives(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss)=0;
+		virtual void   NodalFunctionsMINIDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss)=0;
+		virtual void   NodalFunctionsDerivativesVelocity(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss)=0;
+		virtual void   NormalSection(IssmDouble* normal,IssmDouble* xyz_list)=0;
+		virtual void   NormalTop(IssmDouble* normal,IssmDouble* xyz_list)=0;
+		virtual void   NormalBase(IssmDouble* normal,IssmDouble* xyz_list)=0;
+
+		virtual Element* GetUpperElement(void)=0;
+		virtual Element* GetLowerElement(void)=0;
+		virtual Element* GetSurfaceElement(void)=0;
+		virtual Element* GetBasalElement(void)=0;
+
+		virtual void   JacobianDeterminant(IssmDouble*  Jdet, IssmDouble* xyz_list,Gauss* gauss)=0;
+		virtual void   JacobianDeterminantLine(IssmDouble* Jdet, IssmDouble* xyz_list,Gauss* gauss)=0;
+		virtual void   JacobianDeterminantSurface(IssmDouble* Jdet, IssmDouble* xyz_list,Gauss* gauss)=0;
+		virtual void   JacobianDeterminantBase(IssmDouble* Jdet,IssmDouble* xyz_list_base,Gauss* gauss)=0;
+		virtual void   JacobianDeterminantTop(IssmDouble* Jdet,IssmDouble* xyz_list_base,Gauss* gauss)=0;
+		virtual void   GetSolutionFromInputsOneDof(Vector<IssmDouble>* solution,int solutionenum)=0;
 		virtual int    GetNodeIndex(Node* node)=0;
 		virtual int    GetNumberOfNodes(void)=0;
-		virtual void   GetNodesSidList(int* sidlist)=0;
-		virtual void   GetNodesLidList(int* sidlist)=0;
-
-		virtual int    Sid()=0;
-		virtual bool   IsFloating()=0; 
+		virtual int    GetNumberOfVertices(void)=0;
+
 		virtual bool   IsNodeOnShelfFromFlags(IssmDouble* flags)=0; 
-		virtual bool   IsOnBed()=0;
-		virtual void   GetInputListOnVertices(IssmDouble* pvalue,int enumtype)=0;
-		virtual void   GetInputListOnVertices(IssmDouble* pvalue,int enumtype,IssmDouble defaultvalue)=0;
+		virtual bool   IsOnBase()=0;
+		virtual bool   IsOnSurface()=0;
+		virtual void   GetGroundedPart(int* point1,IssmDouble* fraction1,IssmDouble* fraction2, bool* mainlyfloating)=0;
+		virtual IssmDouble GetGroundedPortion(IssmDouble* xyz_list)=0;
 		virtual void   GetInputValue(IssmDouble* pvalue,Node* node,int enumtype)=0;
-		virtual void   GetMaterialInputValue(IssmDouble* pvalue,Node* node,int enumtype)=0;
+		virtual Node*  GetNode(int node_number)=0;
+		virtual void   GetVerticesCoordinatesBase(IssmDouble** xyz_list)=0;
+		virtual void   GetVerticesCoordinatesTop(IssmDouble** xyz_list)=0;
+		virtual IssmDouble GetXcoord(Gauss* gauss)=0;
+		virtual IssmDouble GetYcoord(Gauss* gauss)=0;
+		virtual IssmDouble GetZcoord(Gauss* gauss)=0;
+		virtual int    GetElementType(void)=0;
 
 		virtual IssmDouble SurfaceArea(void)=0;
-		virtual void   InputDepthAverageAtBase(int enum_type,int average_enum_type,int object_enum)=0;
+		virtual void   InputDepthAverageAtBase(int enum_type,int average_enum_type)=0;
+		virtual void   ComputeSigmaNN(void)=0;
 		virtual void   ComputeBasalStress(Vector<IssmDouble>* sigma_b)=0;
 		virtual void   ComputeStrainRate(Vector<IssmDouble>* eps)=0;
-		virtual void   ResultInterpolation(int* pinterpolation,int output_enum)=0;
-		virtual void   ResultToVector(Vector<IssmPDouble>* vector,int output_enum)=0;
+		virtual void   ComputeStressTensor(void)=0;
+		virtual void   ComputeDeviatoricStressTensor(void)=0;
+
 		virtual void   Update(int index, IoModel* iomodel,int analysis_counter,int analysis_type,int finite_element)=0;
 		virtual void   InputDuplicate(int original_enum,int new_enum)=0;
-		virtual void   InputCreate(IssmDouble* vector,IoModel* iomodel,int M,int N,int vector_type,int vector_enum,int code)=0;
+		virtual void   InputUpdateFromSolutionOneDofCollapsed(IssmDouble* solution,int inputenum)=0;
+		virtual void   InputUpdateFromSolutionOneDof(IssmDouble* solution,int inputenum)=0;
 
 		virtual int    NodalValue(IssmDouble* pvalue, int index, int natureofdataenum)=0;
+		virtual int    NumberofNodesVelocity(void)=0;
+		virtual int    NumberofNodesPressure(void)=0;
+		virtual Gauss* NewGauss(void)=0;
+		virtual Gauss* NewGauss(int order)=0;
+      virtual Gauss* NewGauss(IssmDouble* xyz_list, IssmDouble* xyz_list_front,int order)=0;
+      virtual Gauss* NewGauss(IssmDouble* xyz_list, IssmDouble* xyz_list_front,int order_horiz,int order_vert)=0;
+      virtual Gauss* NewGauss(int point1,IssmDouble fraction1,IssmDouble fraction2,bool mainlyfloating,int order)=0;
+		virtual Gauss* NewGaussBase(int order)=0;
+		virtual Gauss* NewGaussLine(int vertex1,int vertex2,int order)=0;
+		virtual Gauss* NewGaussTop(int order)=0;
+
 		virtual void   InputScale(int enum_type,IssmDouble scale_factor)=0;
-		virtual void   GetVectorFromInputs(Vector<IssmDouble>* vector, int name_enum)=0;
 		virtual IssmDouble TimeAdapt()=0;
 		virtual void   PositiveDegreeDay(IssmDouble* pdds,IssmDouble* pds,IssmDouble signorm)=0;
 		virtual void   Delta18oParameterization(void)=0;
-		virtual void   SmbGradients()=0;
-		virtual void   ResetCoordinateSystem()=0;
-
-		#ifdef _HAVE_RESPONSES_
+		virtual void   SmbGradients(void)=0;
+	   virtual Element*   SpawnBasalElement(void)=0;
+		virtual Element*   SpawnTopElement(void)=0;
+		virtual void   ReduceMatrices(ElementMatrix* Ke,ElementVector* pe)=0;
+		virtual void   ResetFSBasalBoundaryCondition()=0;
+		virtual void   SetTemporaryElementType(int element_type_in)=0;
+		virtual IssmDouble StabilizationParameter(IssmDouble u, IssmDouble v, IssmDouble w, IssmDouble diameter, IssmDouble kappa)=0;
+		virtual void   ValueP1OnGauss(IssmDouble* pvalue,IssmDouble* values,Gauss* gauss)=0;
+		virtual void   ValueP1DerivativesOnGauss(IssmDouble* dvalue,IssmDouble* values,IssmDouble* xyz_list,Gauss* gauss)=0;
+		virtual void   ViscousHeating(IssmDouble* pphi,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input)=0;
+
+		virtual int    VelocityInterpolation()=0;
+		virtual int    PressureInterpolation()=0;
+		virtual bool   IsZeroLevelset(int levelset_enum)=0;
+		virtual bool   IsIcefront(void)=0;
+		virtual void   ZeroLevelsetCoordinates(IssmDouble** pxyz_zero,IssmDouble* xyz_list,int levelsetenum)=0;
+		virtual void   GetIcefrontCoordinates(IssmDouble** pxyz_front,IssmDouble* xyz_list,int levelsetenum)=0;
+		virtual void   GetNormalFromLSF(IssmDouble *pnormal)=0;
+
 		virtual void   AverageOntoPartition(Vector<IssmDouble>* partition_contributions,Vector<IssmDouble>* partition_areas,IssmDouble* vertex_response,IssmDouble* qmu_part)=0;
 		virtual void   MinVel(IssmDouble* pminvel)=0;
@@ -93,5 +264,8 @@
 		virtual IssmDouble IceVolumeAboveFloatation(void)=0;
 		virtual IssmDouble TotalSmb(void)=0;
-		#endif
+		virtual IssmDouble Misfit(int modelenum,int observationenum,int weightsenum)=0;
+		virtual IssmDouble MisfitArea(int weightsenum)=0;
+		virtual int    VertexConnectivity(int vertexindex)=0;
+		virtual void   VerticalSegmentIndices(int** pindices,int* pnumseg)=0;
 
 		#ifdef _HAVE_GIA_
@@ -99,5 +273,4 @@
 		#endif
 
-		#ifdef _HAVE_CONTROL_
 		virtual void   Gradj(Vector<IssmDouble>* gradient,int control_type,int control_index)=0;
 		virtual IssmDouble ThicknessAbsMisfit(void)=0;
@@ -120,27 +293,12 @@
 		virtual void   SetControlInputsFromVector(IssmDouble* vector,int control_enum,int control_index)=0;
 		virtual void   InputControlUpdate(IssmDouble scalar,bool save_parameter)=0;
-		#endif
 
 		virtual void UpdateConstraintsExtrudeFromBase(void)=0;
 		virtual void UpdateConstraintsExtrudeFromTop(void)=0;
 
-		#ifdef _HAVE_THERMAL_
-		virtual void UpdateBasalConstraintsEnthalpy(void)=0;
-		virtual void ComputeBasalMeltingrate(void)=0;
-		virtual void DrainWaterfraction(void)=0;
-		#endif
-
-		#ifdef _HAVE_HYDROLOGY_
-		virtual void GetHydrologyDCInefficientHmax(IssmDouble* ph_max, Node* innode)=0;
-		virtual void GetHydrologyTransfer(Vector<IssmDouble>* transfer)=0; 
-		virtual void HydrologyEPLGetMask(Vector<IssmDouble>* mask)=0;
-		virtual void HydrologyEPLGetActive(Vector<IssmDouble>* active)=0;
-		#endif
-
-		#ifdef _HAVE_GROUNDINGLINE_
 		virtual void   MigrateGroundingLine(IssmDouble* sheet_ungrounding)=0;
+		virtual void   FSContactMigration(Vector<IssmDouble>* vertexgrounded,Vector<IssmDouble>* vertexfloating)=0;
 		virtual void   PotentialUngrounding(Vector<IssmDouble>* potential_sheet_ungrounding)=0;
 		virtual int    UpdatePotentialUngrounding(IssmDouble* potential_sheet_ungrounding,Vector<IssmDouble>* vec_nodes_on_iceshelf,IssmDouble* nodes_on_iceshelf)=0;
-		#endif
 
 };
Index: /issm/trunk/src/c/classes/Elements/ElementHook.cpp
===================================================================
--- /issm/trunk/src/c/classes/Elements/ElementHook.cpp	(revision 17805)
+++ /issm/trunk/src/c/classes/Elements/ElementHook.cpp	(revision 17806)
@@ -89,22 +89,11 @@
 /*}}}*/
 /*FUNCTION ElementHook::SpawnTriaHook{{{*/
-void ElementHook::SpawnTriaHook(ElementHook* triahook,int location){
+void ElementHook::SpawnTriaHook(ElementHook* triahook,int index1,int index2,int index3){
 
 	/*Create arrow of indices depending on location (0=base 1=surface)*/
 	int indices[3];
-	switch(location){
-		case 0:
-			indices[0] = 0;
-			indices[1] = 1;
-			indices[2] = 2;
-			break;
-		case 1:
-			indices[0] = 3;
-			indices[1] = 4;
-			indices[2] = 5;
-			break;
-		default:
-			_error_("case "<<location<<" not supported");
-	}
+	indices[0] = index1;
+	indices[1] = index2;
+	indices[2] = index3;
 
 	triahook->numanalyses=this->numanalyses;
Index: /issm/trunk/src/c/classes/Elements/ElementHook.h
===================================================================
--- /issm/trunk/src/c/classes/Elements/ElementHook.h	(revision 17805)
+++ /issm/trunk/src/c/classes/Elements/ElementHook.h	(revision 17806)
@@ -25,5 +25,5 @@
 
 		void SetHookNodes(int* node_ids,int numnodes,int analysis_counter);
-		void SpawnTriaHook(ElementHook* triahook,int location); //3d only
+		void SpawnTriaHook(ElementHook* triahook,int index1,int index2,int index3); //3d only
 		void SpawnSegHook(ElementHook* triahook,int ndex1,int index2); //2d only
 		void InitHookNeighbors(int* element_ids);               //3d only
Index: /issm/trunk/src/c/classes/Elements/Penta.cpp
===================================================================
--- /issm/trunk/src/c/classes/Elements/Penta.cpp	(revision 17805)
+++ /issm/trunk/src/c/classes/Elements/Penta.cpp	(revision 17806)
@@ -20,19 +20,6 @@
 
 /*Constructors/destructor/copy*/
-/*FUNCTION Penta::Penta(){{{*/
-Penta::Penta(){
-
-	this->nodes             = NULL;
-	this->vertices          = NULL;
-	this->material          = NULL;
-	this->matpar            = NULL;
-	this->verticalneighbors = NULL;
-	this->inputs            = NULL;
-	this->parameters        = NULL;
-}
-/*}}}*/
 /*FUNCTION Penta::~Penta(){{{*/
 Penta::~Penta(){
-	delete inputs;
 	this->parameters=NULL;
 }
@@ -41,5 +28,5 @@
 Penta::Penta(int penta_id, int penta_sid, int index, IoModel* iomodel,int nummodels)
 	:PentaRef(nummodels)
-	,ElementHook(nummodels,index+1,6,iomodel){
+	,ElementHook(nummodels,index+1,NUMVERTICES,iomodel){
 
 	int penta_elements_ids[2];
@@ -121,26 +108,35 @@
 
 /*Other*/
-/*FUNCTION Penta::BedNormal {{{*/
-void Penta::BedNormal(IssmDouble* bed_normal, IssmDouble xyz_list[3][3]){
-
-	int i;
-	IssmDouble v13[3],v23[3];
-	IssmDouble normal[3];
-	IssmDouble normal_norm;
-
-	for (i=0;i<3;i++){
-		v13[i]=xyz_list[0][i]-xyz_list[2][i];
-		v23[i]=xyz_list[1][i]-xyz_list[2][i];
-	}
-
-	normal[0]=v13[1]*v23[2]-v13[2]*v23[1];
-	normal[1]=v13[2]*v23[0]-v13[0]*v23[2];
-	normal[2]=v13[0]*v23[1]-v13[1]*v23[0];
-	normal_norm=sqrt( pow(normal[0],2)+pow(normal[1],2)+pow(normal[2],2) );
-
-	/*Bed normal is opposite to surface normal*/
-	*(bed_normal)=-normal[0]/normal_norm;
-	*(bed_normal+1)=-normal[1]/normal_norm;
-	*(bed_normal+2)=-normal[2]/normal_norm;
+/*FUNCTION Penta::AddInput{{{*/
+void  Penta::AddInput(int input_enum,IssmDouble* values, int interpolation_enum){
+
+	_assert_(this->inputs);
+	this->inputs->AddInput(new PentaInput(input_enum,values,interpolation_enum));
+}
+/*}}}*/
+/*FUNCTION Penta::AddBasalInput{{{*/
+void  Penta::AddBasalInput(int input_enum,IssmDouble* values, int interpolation_enum){
+
+	_assert_(this->inputs);
+	if(!IsOnBase()) return;
+	else{
+		if(interpolation_enum==P1Enum){
+			int        i;
+			IssmDouble extrudedvalues[NUMVERTICES];
+			Penta*     penta=NULL;
+
+			for(i=0;i<NUMVERTICES2D;i++){
+				extrudedvalues[i]=values[i];
+				extrudedvalues[i+NUMVERTICES2D]=values[i];
+			}
+			penta=this;
+			for(;;){
+				penta->inputs->AddInput(new PentaInput(input_enum,&extrudedvalues[0],P1Enum));
+				if (penta->IsOnSurface()) break;
+				penta=penta->GetUpperPenta(); _assert_(penta->Id()!=this->id);
+			}
+		}
+		else _error_("not implemented yet");
+	}
 }
 /*}}}*/
@@ -156,5 +152,5 @@
 
 	/* Basal friction can only be found at the base of an ice sheet: */
-	if (!IsOnBed() || IsFloating()){
+	if (!IsOnBase() || IsFloating()){
 		//empty friction: 
 		this->inputs->AddInput(new PentaInput(BasalFrictionEnum,&basalfriction[0],P1Enum));
@@ -168,5 +164,5 @@
 
 	/*Build friction element, needed later: */
-	friction=new Friction("3d",inputs,matpar,StressbalanceAnalysisEnum);
+	friction=new Friction(this,3);
 
 	/* Start looping on the number of gauss 2d (nodes on the bedrock) */
@@ -177,5 +173,5 @@
 		gauss->GaussPoint(ig);
 
-		friction->GetAlpha2(&alpha2,gauss,VxEnum,VyEnum,VzEnum);
+		friction->GetAlpha2(&alpha2,gauss,vx_input,vy_input,vz_input);
 		vx_input->GetInputValue(&vx,gauss);
 		vy_input->GetInputValue(&vy,gauss);
@@ -204,5 +200,5 @@
 	IssmDouble  pressure,viscosity,Jdet2d;
 	IssmDouble  bed_normal[3];
-	IssmDouble  basalforce[3];
+	IssmDouble  basalforce[3] = {0.};
 	IssmDouble  epsilon[6]; /* epsilon=[exx,eyy,ezz,exy,exz,eyz];*/
 	IssmDouble  stresstensor[6]={0.0};
@@ -223,5 +219,5 @@
 	this->parameters->FindParam(&FSreconditioning,StressbalanceFSreconditioningEnum);
 
-	if(!IsOnBed()){
+	if(!IsOnBase()){
 		//put zero
 		sigma_b->SetValue(id-1,0.0,INS_VAL);
@@ -234,5 +230,5 @@
 
 	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
 	for(i=0;i<3;i++) for(j=0;j<3;j++) xyz_list_tria[i][j]=xyz_list[i][j];
 
@@ -250,6 +246,6 @@
 
 		/*Compute strain rate viscosity and pressure: */
-		this->GetStrainRate3d(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input,vz_input);
-		material->GetViscosity3dFS(&viscosity,&epsilon[0]);
+		this->StrainRateFS(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input,vz_input);
+		this->ViscosityFS(&viscosity,3,&xyz_list[0][0],gauss,vx_input,vy_input,vz_input);
 		pressure_input->GetInputValue(&pressure,gauss);
 
@@ -263,5 +259,5 @@
 
 		/*Get normal vector to the bed */
-		BedNormal(&bed_normal[0],xyz_list_tria);
+		NormalBase(&bed_normal[0],&xyz_list_tria[0][0]);
 
 		/*basalforce*/
@@ -302,5 +298,5 @@
 
 	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
 
 	/*Retrieve all inputs we will be needing: */
@@ -316,6 +312,6 @@
 
 		/*Compute strain rate viscosity and pressure: */
-		this->GetStrainRate3d(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input,vz_input);
-		material->GetViscosity3d(&viscosity,&epsilon[0]);
+		this->StrainRateFS(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input,vz_input);
+		this->ViscosityFS(&viscosity,3,&xyz_list[0][0],gauss,vx_input,vy_input,vz_input);
 		pressure_input->GetInputValue(&pressure,gauss);
 
@@ -341,4 +337,56 @@
 }
 /*}}}*/
+/*FUNCTION Penta::ComputeDeviatoricStressTensor {{{*/
+void  Penta::ComputeDeviatoricStressTensor(){
+
+	IssmDouble      xyz_list[NUMVERTICES][3];
+	IssmDouble      viscosity;
+	IssmDouble      epsilon[6]; /* epsilon=[exx,eyy,exy];*/
+	IssmDouble      tau_xx[NUMVERTICES];
+	IssmDouble		tau_yy[NUMVERTICES];
+	IssmDouble		tau_zz[NUMVERTICES];
+	IssmDouble      tau_xy[NUMVERTICES];
+	IssmDouble		tau_xz[NUMVERTICES];
+	IssmDouble		tau_yz[NUMVERTICES];
+	GaussPenta* gauss=NULL;
+
+	/* Get node coordinates and dof list: */
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+
+	/*Retrieve all inputs we will be needing: */
+	Input* vx_input=inputs->GetInput(VxEnum);             _assert_(vx_input);
+	Input* vy_input=inputs->GetInput(VyEnum);             _assert_(vy_input);
+	Input* vz_input=inputs->GetInput(VzEnum);             _assert_(vz_input);
+
+	/* Start looping on the number of vertices: */
+	gauss=new GaussPenta();
+	for (int iv=0;iv<NUMVERTICES;iv++){
+		gauss->GaussVertex(iv);
+
+		/*Compute strain rate viscosity and pressure: */
+		this->StrainRateFS(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input,vz_input);
+		this->ViscosityFS(&viscosity,3,&xyz_list[0][0],gauss,vx_input,vy_input,vz_input);
+
+		/*Compute Stress*/
+		tau_xx[iv]=2*viscosity*epsilon[0]; // tau = nu eps 
+		tau_yy[iv]=2*viscosity*epsilon[1];
+		tau_zz[iv]=2*viscosity*epsilon[2];
+		tau_xy[iv]=2*viscosity*epsilon[3];
+		tau_xz[iv]=2*viscosity*epsilon[4];
+		tau_yz[iv]=2*viscosity*epsilon[5];
+	}
+
+	/*Add Stress tensor components into inputs*/
+	this->inputs->AddInput(new PentaInput(StressTensorxxEnum,&tau_xx[0],P1Enum));
+	this->inputs->AddInput(new PentaInput(StressTensorxyEnum,&tau_xy[0],P1Enum));
+	this->inputs->AddInput(new PentaInput(StressTensorxzEnum,&tau_xz[0],P1Enum));
+	this->inputs->AddInput(new PentaInput(StressTensoryyEnum,&tau_yy[0],P1Enum));
+	this->inputs->AddInput(new PentaInput(StressTensoryzEnum,&tau_yz[0],P1Enum));
+	this->inputs->AddInput(new PentaInput(StressTensorzzEnum,&tau_zz[0],P1Enum));
+
+	/*Clean up and return*/
+	delete gauss;
+}
+/*}}}*/
 /*FUNCTION Penta::Configure {{{*/
 void  Penta::Configure(Elements* elementsin, Loads* loadsin, Nodes* nodesin,Vertices* verticesin, Materials* materialsin, Parameters* parametersin){
@@ -375,471 +423,8 @@
 }
 /*}}}*/
-/*FUNCTION Penta::CreateKMatrix(Matrix<IssmDouble>* Kff, Matrix<IssmDouble>* Kfs) {{{*/
-void  Penta::CreateKMatrix(Matrix<IssmDouble>* Kff, Matrix<IssmDouble>* Kfs){
-
-	/*Skip if water element*/
-	if(NoIceInElement()) return;
-
-	/*Create element stiffness matrix*/
-	ElementMatrix* Ke=CreateKMatrix();
-
-	if(Ke){
-		int analysis_type;
-		parameters->FindParam(&analysis_type,AnalysisTypeEnum);
-		if(analysis_type==StressbalanceAnalysisEnum){
-			int approximation;
-			inputs->GetInputValue(&approximation,ApproximationEnum);
-			if(approximation==HOFSApproximationEnum || approximation==SSAFSApproximationEnum){
-				//Do nothing condensatino already done for Stokes part
-			}
-			else{
-				/*Condense if requested*/
-				if(this->element_type==MINIcondensedEnum){
-					int indices[3]={18,19,20};
-					Ke->StaticCondensation(3,&indices[0]);
-				}
-				else if(this->element_type==P1bubblecondensedEnum){
-					int size   = nodes[6]->GetNumberOfDofs(NoneApproximationEnum,GsetEnum);
-					int offset = 0;
-					for(int i=0;i<6;i++) offset+=nodes[i]->GetNumberOfDofs(NoneApproximationEnum,GsetEnum);
-					int* indices=xNew<int>(size);
-					for(int i=0;i<size;i++) indices[i] = offset+i;
-					Ke->StaticCondensation(size,indices);
-					xDelete<int>(indices);
-				}
-			}
-		}
-
-		/*Add to global matrix*/
-		Ke->AddToGlobal(Kff,Kfs);
-		delete Ke;
-	}
-}
-/*}}}*/
-/*FUNCTION Penta::CreateKMatrix(void){{{*/
-ElementMatrix* Penta::CreateKMatrix(void){
-
-	/*retrieve parameters: */
-	int analysis_type;
-	parameters->FindParam(&analysis_type,AnalysisTypeEnum);
-
-	/*Checks in debugging {{{*/
-	_assert_(this->nodes && this->material && this->matpar && this->verticalneighbors && this->parameters && this->inputs);
-	/*}}}*/
-
-	/*Skip if water element*/
-	if(NoIceInElement()) return NULL;
-
-	/*Just branch to the correct element stiffness matrix generator, according to the type of analysis we are carrying out: */
-	switch(analysis_type){
-		#ifdef _HAVE_STRESSBALANCE_
-		case StressbalanceAnalysisEnum:
-			return CreateKMatrixStressbalanceHoriz();
-			break;
-		case AdjointHorizAnalysisEnum:
-			return CreateKMatrixAdjointHoriz();
-			break;
-		case StressbalanceSIAAnalysisEnum:
-			return CreateKMatrixStressbalanceSIA();
-			break;
-		case StressbalanceVerticalAnalysisEnum:
-			return CreateKMatrixStressbalanceVert();
-			break;
-		#endif
-		case L2ProjectionBaseAnalysisEnum:
-			return CreateBasalMassMatrix();
-			break;
-		case MasstransportAnalysisEnum:
-			return CreateKMatrixMasstransport();
-			break;
-		case FreeSurfaceTopAnalysisEnum:
-			return CreateKMatrixFreeSurfaceTop();
-			break;
-		case FreeSurfaceBaseAnalysisEnum:
-			return CreateKMatrixFreeSurfaceBase();
-			break;
-		#ifdef _HAVE_BALANCED_
-		case BalancethicknessAnalysisEnum:
-			return CreateKMatrixBalancethickness();
-			break;
-		#endif
-		#ifdef _HAVE_THERMAL_
-		case ThermalAnalysisEnum:
-			return CreateKMatrixThermal();
-			break;
-		case EnthalpyAnalysisEnum:
-			return CreateKMatrixEnthalpy();
-			break;
-		case MeltingAnalysisEnum:
-			return CreateKMatrixMelting();
-			break;
-		#endif
-		#ifdef _HAVE_HYDROLOGY_
-	  case HydrologyDCInefficientAnalysisEnum:
-			return CreateKMatrixHydrologyDCInefficient();
-			break;
-	  case HydrologyDCEfficientAnalysisEnum:
-			return CreateKMatrixHydrologyDCEfficient();
-			break;
-		#endif
-		default:
-			_error_("analysis " << EnumToStringx(analysis_type) << " not supported yet");
-	}
-
-	/*Make compiler happy*/
-	return NULL;
-}
-/*}}}*/
-/*FUNCTION Penta::CreateKMatrixMasstransport {{{*/
-ElementMatrix* Penta::CreateKMatrixMasstransport(void){
-
-	if (!IsOnBed()) return NULL;
-
-	/*Depth Averaging Vx and Vy*/
-	this->InputDepthAverageAtBase(VxEnum,VxAverageEnum);
-	this->InputDepthAverageAtBase(VyEnum,VyAverageEnum);
-
-	Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.
-	ElementMatrix* Ke=tria->CreateKMatrixMasstransport();
-	delete tria->material; delete tria;
-
-	/*Delete Vx and Vy averaged*/
-	this->inputs->DeleteInput(VxAverageEnum);
-	this->inputs->DeleteInput(VyAverageEnum);
-
-	/*clean up and return*/
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Penta::CreateKMatrixFreeSurfaceTop {{{*/
-ElementMatrix* Penta::CreateKMatrixFreeSurfaceTop(void){
-
-	if(!IsOnSurface()) return NULL;
-
-	Tria* tria=(Tria*)SpawnTria(1); //lower face is 0, upper face is 1.
-	ElementMatrix* Ke=tria->CreateKMatrixFreeSurfaceTop();
-	delete tria->material; delete tria;
-
-	/*clean up and return*/
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Penta::CreateKMatrixFreeSurfaceBase {{{*/
-ElementMatrix* Penta::CreateKMatrixFreeSurfaceBase(void){
-
-	if(!IsOnBed()) return NULL;
-
-	Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.
-	ElementMatrix* Ke=tria->CreateKMatrixFreeSurfaceBase();
-	delete tria->material; delete tria;
-
-	/*clean up and return*/
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Penta::CreateBasalMassMatrix{{{*/
-ElementMatrix* Penta::CreateBasalMassMatrix(void){
-
-	if (!IsOnBed()) return NULL;
-
-	Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.
-	ElementMatrix* Ke=tria->CreateMassMatrix();
-	delete tria->material; delete tria;
-
-	/*clean up and return*/
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Penta::CreateDVector {{{*/
-void  Penta::CreateDVector(Vector<IssmDouble>* df){
-
-	/*retrieve parameters: */
-	ElementVector* De=NULL;
-	int analysis_type;
-	parameters->FindParam(&analysis_type,AnalysisTypeEnum);
-
-	/*Checks in debugging*/
-	_assert_(this->nodes && this->material && this->matpar && this->verticalneighbors && this->parameters && this->inputs);
-
-	switch(analysis_type){
-		#ifdef _HAVE_STRESSBALANCE_
-		case StressbalanceAnalysisEnum:
-			De=CreateDVectorStressbalanceHoriz();
-			break;
-		#endif
-	}
-
-	/*Add to global Vector*/
-	if(De){
-		De->InsertIntoGlobal(df);
-		delete De;
-	}
-}
-/*}}}*/
-/*FUNCTION Penta::CreatePVector(Vector<IssmDouble>* pf) {{{*/
-void  Penta::CreatePVector(Vector<IssmDouble>* pf){
-
-	/*Skip if water element*/
-	if(NoIceInElement()) return;
-
-	/*Create element load vector*/
-	ElementVector* pe = CreatePVector();
-
-	if(pe){
-		int analysis_type;
-		parameters->FindParam(&analysis_type,AnalysisTypeEnum);
-		if(analysis_type==StressbalanceAnalysisEnum){
-			/*StaticCondensation if requested*/
-			if(this->element_type==MINIcondensedEnum){
-				int approximation;
-				inputs->GetInputValue(&approximation,ApproximationEnum);
-				if(approximation==HOFSApproximationEnum || approximation==SSAFSApproximationEnum){
-					//Do nothing, condensation already done in PVectorCoupling
-				}
-				else{
-					int indices[3]={18,19,20};
-
-					this->element_type=MINIEnum;
-					ElementMatrix* Ke = CreateKMatrixStressbalanceFS();
-					this->element_type=MINIcondensedEnum;
-
-					pe->StaticCondensation(Ke,3,&indices[0]);
-					delete Ke;
-				}
-			}
-			else if(this->element_type==P1bubblecondensedEnum){
-				int size   = nodes[6]->GetNumberOfDofs(NoneApproximationEnum,GsetEnum);
-				int offset = 0;
-				for(int i=0;i<6;i++) offset+=nodes[i]->GetNumberOfDofs(NoneApproximationEnum,GsetEnum);
-				int* indices=xNew<int>(size);
-				for(int i=0;i<size;i++) indices[i] = offset+i;
-
-				this->element_type=P1bubbleEnum;
-				ElementMatrix* Ke = CreateKMatrix();
-				this->element_type=P1bubblecondensedEnum;
-				pe->StaticCondensation(Ke,size,indices);
-				xDelete<int>(indices);
-				delete Ke;
-			}
-		}
-
-		/*Add to global Vector*/
-		pe->AddToGlobal(pf);
-		delete pe;
-	}
-}
-/*}}}*/
-/*FUNCTION Penta::CreatePVector(void) {{{*/
-ElementVector* Penta::CreatePVector(void){
-
-	/*retrieve parameters: */
-	int analysis_type;
-	parameters->FindParam(&analysis_type,AnalysisTypeEnum);
-
-	/*if debugging mode, check that all pointers exist {{{*/
-	_assert_(this->nodes && this->material && this->matpar && this->verticalneighbors && this->parameters && this->inputs);
-	/*}}}*/
-
-	/*Skip if water element*/
-	if(NoIceInElement()) return NULL;
-
-	/*Just branch to the correct element stiffness matrix generator, according to the type of analysis we are carrying out: */
-	switch(analysis_type){
-		#ifdef _HAVE_STRESSBALANCE_
-		case StressbalanceAnalysisEnum:
-			return CreatePVectorStressbalanceHoriz();
-			break;
-		case StressbalanceSIAAnalysisEnum:
-			return CreatePVectorStressbalanceSIA();
-			break;
-		case StressbalanceVerticalAnalysisEnum:
-			return CreatePVectorStressbalanceVert();
-			break;
-		#endif
-	 	#ifdef _HAVE_CONTROL_
-		case AdjointHorizAnalysisEnum:
-			return CreatePVectorAdjointHoriz();
-			break;
-		#endif
-		#ifdef _HAVE_THERMAL_
-		case ThermalAnalysisEnum:
-			return CreatePVectorThermal();
-			break;
-		case EnthalpyAnalysisEnum:
-			return CreatePVectorEnthalpy();
-			break;
-		case MeltingAnalysisEnum:
-			return CreatePVectorMelting();
-			break;
-		#endif
-		case L2ProjectionBaseAnalysisEnum:
-			return CreatePVectorL2ProjectionBase();
-			break;
-		case MasstransportAnalysisEnum:
-			return CreatePVectorMasstransport();
-			break;
-		case FreeSurfaceTopAnalysisEnum:
-			return CreatePVectorFreeSurfaceTop();
-			break;
-		case FreeSurfaceBaseAnalysisEnum:
-			return CreatePVectorFreeSurfaceBase();
-			break;
-		#ifdef _HAVE_BALANCED_
-		case BalancethicknessAnalysisEnum:
-			return CreatePVectorBalancethickness();
-			break;
-		#endif
-		#ifdef _HAVE_HYDROLOGY_
-	  case HydrologyDCInefficientAnalysisEnum:
-			return CreatePVectorHydrologyDCInefficient();
-			break;
-	  case HydrologyDCEfficientAnalysisEnum:
-			return CreatePVectorHydrologyDCEfficient();
-			break;
-		#endif
-		default:
-			_error_("analysis " << analysis_type << " (" << EnumToStringx(analysis_type) << ") not supported yet");
-	}
-
-	/*make compiler happy*/
-	return NULL;
-}
-/*}}}*/
-/*FUNCTION Penta::CreatePVectorMasstransport {{{*/
-ElementVector* Penta::CreatePVectorMasstransport(void){
-
-	if (!IsOnBed()) return NULL;
-
-	/*Depth Averaging Vx and Vy*/
-	this->InputDepthAverageAtBase(VxEnum,VxAverageEnum);
-	this->InputDepthAverageAtBase(VyEnum,VyAverageEnum);
-
-	/*Call Tria function*/
-	Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.
-	ElementVector* pe=tria->CreatePVectorMasstransport();
-	delete tria->material; delete tria;
-
-	/*Delete Vx and Vy averaged*/
-	this->inputs->DeleteInput(VxAverageEnum);
-	this->inputs->DeleteInput(VyAverageEnum);
-
-	/*Clean up and return*/
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Penta::CreatePVectorFreeSurfaceTop {{{*/
-ElementVector* Penta::CreatePVectorFreeSurfaceTop(void){
-
-	if(!IsOnSurface()) return NULL;
-
-	/*Call Tria function*/
-	Tria* tria=(Tria*)SpawnTria(1); //lower face is 0, upper face is 1.
-	ElementVector* pe=tria->CreatePVectorFreeSurfaceTop();
-	delete tria->material; delete tria;
-
-	/*Clean up and return*/
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Penta::CreatePVectorFreeSurfaceBase {{{*/
-ElementVector* Penta::CreatePVectorFreeSurfaceBase(void){
-
-	if(!IsOnBed()) return NULL;
-
-	/*Call Tria function*/
-	Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.
-	ElementVector* pe=tria->CreatePVectorFreeSurfaceBase();
-	delete tria->material; delete tria;
-
-	/*Clean up and return*/
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Penta::CreatePVectorL2ProjectionBase {{{*/
-ElementVector* Penta::CreatePVectorL2ProjectionBase(void){
-
-	if (!IsOnBed()) return NULL;
-
-	/*Call Tria function*/
-	Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.
-	ElementVector* pe=tria->CreatePVectorL2Projection();
-	delete tria->material; delete tria;
-
-	/*clean up and return*/
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Penta::CreateJacobianMatrix{{{*/
-void  Penta::CreateJacobianMatrix(Matrix<IssmDouble>* Jff){
-
-	/*retrieve parameters: */
-	ElementMatrix* Ke=NULL;
-	int analysis_type;
-	parameters->FindParam(&analysis_type,AnalysisTypeEnum);
-
-	/*Checks in debugging {{{*/
-	_assert_(this->nodes && this->material && this->matpar && this->verticalneighbors && this->parameters && this->inputs);
-	/*}}}*/
-
-	/*Skip if water element*/
-	if(NoIceInElement()) return;
-
-	/*Just branch to the correct element stiffness matrix generator, according to the type of analysis we are carrying out: */
-	switch(analysis_type){
-#ifdef _HAVE_STRESSBALANCE_
-		case StressbalanceAnalysisEnum:
-			Ke=CreateJacobianStressbalanceHoriz();
-			break;
-#endif
-		default:
-			_error_("analysis " << analysis_type << " (" << EnumToStringx(analysis_type) << ") not supported yet");
-	}
-
-	/*Add to global matrix*/
-	if(Ke){
-		/*Condense if requested*/
-		if(this->element_type==MINIcondensedEnum){
-			int indices[3]={18,19,20};
-			Ke->StaticCondensation(3,&indices[0]);
-		}
-		else if(this->element_type==P1bubblecondensedEnum){
-			int size   = nodes[6]->GetNumberOfDofs(NoneApproximationEnum,GsetEnum);
-			int offset = 0;
-			for(int i=0;i<6;i++) offset+=nodes[i]->GetNumberOfDofs(NoneApproximationEnum,GsetEnum);
-			int* indices=xNew<int>(size);
-			for(int i=0;i<size;i++) indices[i] = offset+i;
-			Ke->StaticCondensation(size,indices);
-			xDelete<int>(indices);
-		}
-
-		Ke->AddToGlobal(Jff);
-		delete Ke;
-	}
-}
-/*}}}*/
-/*FUNCTION Penta::DeepEcho{{{*/
-void Penta::DeepEcho(void){
-
-	_printf_("Penta:\n");
-	_printf_("   id: " << id << "\n");
-	nodes[0]->DeepEcho();
-	nodes[1]->DeepEcho();
-	nodes[2]->DeepEcho();
-	nodes[3]->DeepEcho();
-	nodes[4]->DeepEcho();
-	nodes[5]->DeepEcho();
-	material->DeepEcho();
-	matpar->DeepEcho();
-	_printf_("   neighbor ids: " << verticalneighbors[0]->Id() << "-" << verticalneighbors[1]->Id() << "\n");
-	_printf_("   parameters\n");
-	parameters->DeepEcho();
-	_printf_("   inputs\n");
-	inputs->DeepEcho();
-}
-/*}}}*/
 /*FUNCTION Penta::Delta18oParameterization{{{*/
 void  Penta::Delta18oParameterization(void){
         /*Are we on the base? If not, return*/
-        if(!IsOnBed()) return;
+        if(!IsOnBase()) return;
 
 	int        i;
@@ -905,6 +490,6 @@
 	this->inputs->AddInput(NewPrecipitationInput);
 
-	this->InputExtrude(SurfaceforcingsMonthlytemperaturesEnum,ElementEnum);
-	this->InputExtrude(SurfaceforcingsPrecipitationEnum,ElementEnum);
+	this->InputExtrude(SurfaceforcingsMonthlytemperaturesEnum);
+	this->InputExtrude(SurfaceforcingsPrecipitationEnum);
 
 	/*clean-up*/
@@ -912,8 +497,89 @@
 }
 /*}}}*/
-/*FUNCTION Penta::Echo{{{*/
-
-void Penta::Echo(void){
-	this->DeepEcho();
+/*FUNCTION Penta::FiniteElement{{{*/
+int Penta::FiniteElement(void){
+	return this->element_type;
+}
+/*}}}*/
+/*FUNCTION Penta::FSContactMigration{{{*/
+void Penta::FSContactMigration(Vector<IssmDouble>* vertexgrounded,Vector<IssmDouble>* vertexfloating){
+
+	if(!IsOnBase()) return;
+
+	/*Intermediaries*/
+	IssmDouble* xyz_list = NULL;
+	IssmDouble  pressure,water_pressure,sigma_nn,viscosity,bed,base;
+	IssmDouble  bed_normal[3];
+	IssmDouble  epsilon[6]; /* epsilon=[exx eyy ezz exy exz eyz];*/
+	IssmDouble  surface=0,value=0;
+	bool grounded;
+
+	/* Get node coordinates and dof list: */
+	GetVerticesCoordinates(&xyz_list);
+
+	/*Retrieve all inputs we will be needing: */
+	Input* pressure_input = inputs->GetInput(PressureEnum); _assert_(pressure_input);
+	Input* base_input     = inputs->GetInput(BaseEnum);     _assert_(base_input);
+	Input* bed_input      = inputs->GetInput(BedEnum);      _assert_(bed_input);
+	Input* vx_input       = inputs->GetInput(VxEnum);       _assert_(vx_input);
+	Input* vy_input       = inputs->GetInput(VyEnum);       _assert_(vy_input);
+	Input* vz_input       = inputs->GetInput(VzEnum);       _assert_(vz_input);
+
+	/*Create gauss point in the middle of the basal edge*/
+	Gauss* gauss=NewGaussBase(1);
+	gauss->GaussPoint(0);
+
+	if(!IsFloating()){ 
+		/*Check for basal force only if grounded and touching GL*/
+		if(this->inputs->Min(MaskGroundediceLevelsetEnum)==0.){
+			this->StrainRateFS(&epsilon[0],xyz_list,gauss,vx_input,vy_input,vz_input);
+			this->ViscosityFS(&viscosity,3,xyz_list,gauss,vx_input,vy_input,vz_input);
+			pressure_input->GetInputValue(&pressure, gauss);
+			base_input->GetInputValue(&base, gauss); _assert_(base<0.);
+
+			/*Compute Stress*/
+			IssmDouble sigma_xx=2.*viscosity*epsilon[0]-pressure;
+			IssmDouble sigma_yy=2.*viscosity*epsilon[1]-pressure;
+			IssmDouble sigma_zz=2.*viscosity*epsilon[2]-pressure;
+			IssmDouble sigma_xy=2.*viscosity*epsilon[3];
+			IssmDouble sigma_xz=2.*viscosity*epsilon[4];
+			IssmDouble sigma_yz=2.*viscosity*epsilon[5];
+
+			/*Get normal vector to the bed */
+			NormalBase(&bed_normal[0],xyz_list);
+
+			/*basalforce*/
+			sigma_nn = sigma_xx*bed_normal[0]*bed_normal[0] + sigma_yy*bed_normal[1]*bed_normal[1] + sigma_zz*bed_normal[2]*bed_normal[2] 
+			  + 2.*sigma_xy*bed_normal[0]*bed_normal[1] + 2.*sigma_xz*bed_normal[0]*bed_normal[2] + 2.*sigma_yz*bed_normal[1]*bed_normal[2];
+
+			/*Compute water pressure*/
+			IssmDouble rho_ice   = matpar->GetRhoIce();
+			IssmDouble rho_water = matpar->GetRhoWater();
+			IssmDouble gravity   = matpar->GetG();
+			water_pressure=gravity*rho_water*base;
+
+			/*Compare basal stress to water pressure and determine whether it should ground*/
+			if (sigma_nn<water_pressure) grounded=true;
+			else                         grounded=false;
+		}
+		else{
+			grounded=true;
+		}
+	}
+	else{
+		/*Check for basal elevation if floating*/
+		base_input->GetInputValue(&base, gauss);
+		bed_input->GetInputValue(&bed, gauss);
+		if (base<bed) grounded=true;
+		else          grounded=false;
+	}
+	for(int i=0;i<NUMVERTICES;i++){
+		if(grounded) vertexgrounded->SetValue(vertices[i]->Pid(),+1.,INS_VAL);
+		else         vertexfloating->SetValue(vertices[i]->Pid(),+1.,INS_VAL);
+	}
+
+	/*clean up*/
+	delete gauss;
+	xDelete<IssmDouble>(xyz_list);
 }
 /*}}}*/
@@ -926,5 +592,5 @@
 /*}}}*/
 /*FUNCTION Penta::GetAreaCoordinates{{{*/
-void Penta::GetAreaCoordinates(IssmDouble* area_coordinates,IssmDouble xyz_zero[4][3],IssmDouble xyz_list[6][3],int numpoints){
+void Penta::GetAreaCoordinates(IssmDouble* area_coordinates,IssmDouble* xyz_zero,IssmDouble* xyz_list,int numpoints){
 	/*Computeportion of the element that is grounded*/ 
 
@@ -933,10 +599,10 @@
 	IssmDouble  xyz_bis[3][3];
 
-	area_init=fabs(xyz_list[1][0]*xyz_list[2][1] - xyz_list[1][1]*xyz_list[2][0] + xyz_list[0][0]*xyz_list[1][1] - xyz_list[0][1]*xyz_list[1][0] + xyz_list[2][0]*xyz_list[0][1] - xyz_list[2][1]*xyz_list[0][0])/2.;
+	area_init=fabs(xyz_list[1*3+0]*xyz_list[2*3+1] - xyz_list[1*3+1]*xyz_list[2*3+0] + xyz_list[0*3+0]*xyz_list[1*3+1] - xyz_list[0*3+1]*xyz_list[1*3+0] + xyz_list[2*3+0]*xyz_list[0*3+1] - xyz_list[2*3+1]*xyz_list[0*3+0])/2.;
 
 	/*Initialize xyz_list with original xyz_list of triangle coordinates*/
 	for(j=0;j<3;j++){ 
 		for(k=0;k<3;k++){
-			xyz_bis[j][k]=xyz_list[j][k];
+			xyz_bis[j][k]=xyz_list[j*3+k];
 		}
 	}
@@ -945,5 +611,5 @@
 			for(k=0;k<3;k++){
 				/*Change appropriate line*/
-				xyz_bis[j][k]=xyz_zero[i][k];
+				xyz_bis[j][k]=xyz_zero[i*3+k];
 			}
 
@@ -955,5 +621,5 @@
 			for(k=0;k<3;k++){
 				/*Reinitialize xyz_list with original coordinates*/
-				xyz_bis[j][k]=xyz_list[j][k];
+				xyz_bis[j][k]=xyz_list[j*3+k];
 			}
 		}
@@ -961,18 +627,59 @@
 }
 /*}}}*/
-/*FUNCTION Penta::GetBasalElement{{{*/
-Penta* Penta::GetBasalElement(void){
+/*FUNCTION Penta::GetUpperPenta{{{*/
+Penta* Penta::GetUpperPenta(void){
+
+	Penta* upper_penta=NULL;
+
+	upper_penta=(Penta*)verticalneighbors[1]; //first one (0) under, second one (1) above
+
+	return upper_penta;
+}
+/*}}}*/
+/*FUNCTION Penta::GetLowerPenta{{{*/
+Penta* Penta::GetLowerPenta(void){
+
+	Penta* lower_penta=NULL;
+
+	lower_penta=(Penta*)verticalneighbors[0]; //first one (0) under, second one (1) above
+
+	return lower_penta;
+}
+/*}}}*/
+/*FUNCTION Penta::GetSurfacePenta{{{*/
+Penta* Penta::GetSurfacePenta(void){
 
 	/*Output*/
 	Penta* penta=NULL;
 
-	/*Go through all elements till the bed is reached*/
+	/*Go through all pentas till the surface is reached*/
+	penta=this;
+	for(;;){
+		/*Stop if we have reached the surface, else, take upper penta*/
+		if (penta->IsOnSurface()) break;
+
+		/* get upper Penta*/
+		penta=penta->GetUpperPenta();
+		_assert_(penta->Id()!=this->id);
+	}
+
+	/*return output*/
+	return penta;
+}
+/*}}}*/
+/*FUNCTION Penta::GetBasalPenta{{{*/
+Penta* Penta::GetBasalPenta(void){
+
+	/*Output*/
+	Penta* penta=NULL;
+
+	/*Go through all pentas till the bed is reached*/
 	penta=this;
 	for(;;){
 		/*Stop if we have reached the surface, else, take lower penta*/
-		if (penta->IsOnBed()) break;
+		if (penta->IsOnBase()) break;
 
 		/* get lower Penta*/
-		penta=penta->GetLowerElement();
+		penta=penta->GetLowerPenta();
 		_assert_(penta->Id()!=this->id);
 	}
@@ -982,75 +689,34 @@
 }
 /*}}}*/
-/*FUNCTION Penta::GetDofList {{{*/
-void  Penta::GetDofList(int** pdoflist,int approximation_enum,int setenum){
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*First, figure out size of doflist and create it: */
-	int numberofdofs=0;
-	for(int i=0;i<numnodes;i++) numberofdofs+=nodes[i]->GetNumberOfDofs(approximation_enum,setenum);
-
-	/*Allocate output*/
-	int* doflist=xNew<int>(numberofdofs);
-
-	/*Populate: */
-	int count=0;
-	for(int i=0;i<numnodes;i++){
-		nodes[i]->GetDofList(doflist+count,approximation_enum,setenum);
-		count+=nodes[i]->GetNumberOfDofs(approximation_enum,setenum);
-	}
-
-	/*Assign output pointers:*/
-	*pdoflist=doflist;
-}
-/*}}}*/
-/*FUNCTION Penta::GetDofListVelocity{{{*/
-void  Penta::GetDofListVelocity(int** pdoflist,int setenum){
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodesVelocity();
-
-	/*First, figure out size of doflist and create it: */
-	int numberofdofs=0;
-	for(int i=0;i<numnodes;i++) numberofdofs+=nodes[i]->GetNumberOfDofs(FSvelocityEnum,setenum);
-
-	/*Allocate output*/
-	int* doflist=xNew<int>(numberofdofs);
-
-	/*Populate: */
-	int count=0;
-	for(int i=0;i<numnodes;i++){
-		nodes[i]->GetDofList(doflist+count,FSvelocityEnum,setenum);
-		count+=nodes[i]->GetNumberOfDofs(FSvelocityEnum,setenum);
-	}
-
-	/*Assign output pointers:*/
-	*pdoflist=doflist;
-}
-/*}}}*/
-/*FUNCTION Penta::GetDofListPressure{{{*/
-void  Penta::GetDofListPressure(int** pdoflist,int setenum){
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int vnumnodes = this->NumberofNodesVelocity();
-	int pnumnodes = this->NumberofNodesPressure();
-
-	/*First, figure out size of doflist and create it: */
-	int numberofdofs=0;
-	for(int i=vnumnodes;i<vnumnodes+pnumnodes;i++) numberofdofs+=nodes[i]->GetNumberOfDofs(FSApproximationEnum,setenum);
-
-	/*Allocate output*/
-	int* doflist=xNew<int>(numberofdofs);
-
-	/*Populate: */
-	int count=0;
-	for(int i=vnumnodes;i<vnumnodes+pnumnodes;i++){
-		nodes[i]->GetDofList(doflist+count,FSApproximationEnum,setenum);
-		count+=nodes[i]->GetNumberOfDofs(FSApproximationEnum,setenum);
-	}
-
-	/*Assign output pointers:*/
-	*pdoflist=doflist;
+/*FUNCTION Penta::GetUpperElement{{{*/
+Element* Penta::GetUpperElement(void){
+
+	/*Output*/
+	Element* upper_element=this->GetUpperPenta();
+	return upper_element;
+}
+/*}}}*/
+/*FUNCTION Penta::GetLowerElement{{{*/
+Element* Penta::GetLowerElement(void){
+
+	/*Output*/
+	Element* lower_element=this->GetLowerPenta();
+	return lower_element;
+}
+/*}}}*/
+/*FUNCTION Penta::GetSurfaceElement{{{*/
+Element* Penta::GetSurfaceElement(void){
+
+	/*Output*/
+	Element* element=this->GetSurfacePenta();
+	return element;
+}
+/*}}}*/
+/*FUNCTION Penta::GetBasalElement{{{*/
+Element* Penta::GetBasalElement(void){
+
+	/*Output*/
+	Element* element=this->GetBasalPenta();
+	return element;
 }
 /*}}}*/
@@ -1211,23 +877,4 @@
 }
 /*}}}*/
-/*FUNCTION Penta::GetVertexPidList {{{*/
-void  Penta::GetVertexPidList(int* doflist){
-
-	for(int i=0;i<6;i++) doflist[i]=vertices[i]->Pid();
-
-}
-/*}}}*/
-/*FUNCTION Penta::GetVertexSidList{{{*/
-void  Penta::GetVertexSidList(int* sidlist){
-
-	for(int i=0;i<NUMVERTICES;i++) sidlist[i]=vertices[i]->Sid();
-
-}
-/*}}}*/
-/*FUNCTION Penta::GetConnectivityList {{{*/
-void  Penta::GetConnectivityList(int* connectivity){
-	for(int i=0;i<NUMVERTICES;i++) connectivity[i]=vertices[i]->Connectivity();
-}
-/*}}}*/
 /*FUNCTION Penta::GetElementType {{{*/
 int Penta::GetElementType(){
@@ -1237,6 +884,6 @@
 }
 /*}}}*/
-/*FUNCTION Penta::GetElementSizes{{{*/
-void Penta::GetElementSizes(IssmDouble* hx,IssmDouble* hy,IssmDouble* hz){
+/*FUNCTION Penta::ElementSizes{{{*/
+void Penta::ElementSizes(IssmDouble* hx,IssmDouble* hy,IssmDouble* hz){
 
 	IssmDouble xyz_list[NUMVERTICES][3];
@@ -1245,5 +892,5 @@
 
 	/*Get xyz list: */
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
 	xmin=xyz_list[0][0]; xmax=xyz_list[0][0];
 	ymin=xyz_list[0][1]; ymax=xyz_list[0][1];
@@ -1264,14 +911,4 @@
 }
 /*}}}*/
-/*FUNCTION Penta::GetLowerElement{{{*/
-Penta* Penta::GetLowerElement(void){
-
-	Penta* upper_penta=NULL;
-
-	upper_penta=(Penta*)verticalneighbors[0]; //first one (0) under, second one (1) above
-
-	return upper_penta;
-}
-/*}}}*/
 /*FUNCTION Penta::GetNodeIndex {{{*/
 int Penta::GetNodeIndex(Node* node){
@@ -1285,28 +922,4 @@
 	_error_("Node provided not found among element nodes");
 
-}
-/*}}}*/
-/*FUNCTION Penta::GetNodesSidList{{{*/
-void Penta::GetNodesSidList(int* sidlist){
-
-	_assert_(sidlist);
-	_assert_(nodes);
-	int numnodes = this->NumberofNodes();
-
-	for(int i=0;i<numnodes;i++){
-		sidlist[i]=nodes[i]->Sid();
-	}
-}
-/*}}}*/
-/*FUNCTION Penta::GetNodesLidList{{{*/
-void Penta::GetNodesLidList(int* lidlist){
-
-	_assert_(lidlist);
-	_assert_(nodes);
-	int numnodes = this->NumberofNodes();
-
-	for(int i=0;i<numnodes;i++){
-		lidlist[i]=nodes[i]->Lid();
-	}
 }
 /*}}}*/
@@ -1316,86 +929,14 @@
 }
 /*}}}*/
-/*FUNCTION Penta::GetInputListOnVertices(IssmDouble* pvalue,int enumtype) {{{*/
-void Penta::GetInputListOnVertices(IssmDouble* pvalue,int enumtype){
-
-	/*Recover input*/
-	Input* input=inputs->GetInput(enumtype);
-	if (!input) _error_("Input " << EnumToStringx(enumtype) << " not found in element");
-
-	/*Checks in debugging mode*/
-	_assert_(pvalue);
-
-	/* Start looping on the number of vertices: */
-	GaussPenta *gauss=new GaussPenta();
-	for (int iv=0;iv<NUMVERTICES;iv++){
-		gauss->GaussVertex(iv);
-		input->GetInputValue(&pvalue[iv],gauss);
-	}
-
-	/*clean-up*/
-	delete gauss;
-}
-/*}}}*/
-/*FUNCTION Penta::GetInputListOnVertices(IssmDouble* pvalue,int enumtype,IssmDouble defaultvalue) {{{*/
-void Penta::GetInputListOnVertices(IssmDouble* pvalue,int enumtype,IssmDouble defaultvalue){
-
-	/*Recover input*/
-	Input* input=inputs->GetInput(enumtype);
-
-	/*Checks in debugging mode*/
-	_assert_(pvalue);
-
-	/* Start looping on the number of vertices: */
-	if (input){
-		GaussPenta *gauss=new GaussPenta();
-		for (int iv=0;iv<NUMVERTICES;iv++){
-			gauss->GaussVertex(iv);
-			input->GetInputValue(&pvalue[iv],gauss);
-		}
-		delete gauss;
-	}
-	else{
-		for (int iv=0;iv<NUMVERTICES;iv++) pvalue[iv]=defaultvalue;
-	}
-}
-/*}}}*/
-/*FUNCTION Penta::GetInputListOnNodes(IssmDouble* pvalue,int enumtype,IssmDouble defaultvalue) {{{*/
-void Penta::GetInputListOnNodes(IssmDouble* pvalue,int enumtype,IssmDouble defaultvalue){
-
-	_assert_(pvalue);
-
-	Input *input    = inputs->GetInput(enumtype);
-	int    numnodes = this->NumberofNodes();
-
-	/* Start looping on the number of vertices: */
-	if(input){
-		GaussPenta* gauss=new GaussPenta();
-		for(int iv=0;iv<this->NumberofNodes();iv++){
-			gauss->GaussNode(this->element_type,iv);
-			input->GetInputValue(&pvalue[iv],gauss);
-		}
-		delete gauss;
-	}
-	else{
-		for(int iv=0;iv<numnodes;iv++) pvalue[iv]=defaultvalue;
-	}
-}
-/*}}}*/
-/*FUNCTION Penta::GetInputListOnNodes(IssmDouble* pvalue,int enumtype) {{{*/
-void Penta::GetInputListOnNodes(IssmDouble* pvalue,int enumtype){
-
-	_assert_(pvalue);
-
-	/*Recover input*/
-	Input* input=inputs->GetInput(enumtype);
-	if(!input) _error_("Input " << EnumToStringx(enumtype) << " not found in element");
-
-	/* Start looping on the number of vertices: */
-	GaussPenta* gauss=new GaussPenta();
-	for(int iv=0;iv<this->NumberofNodes();iv++){
-		gauss->GaussNode(this->element_type,iv);
-		input->GetInputValue(&pvalue[iv],gauss);
-	}
-	delete gauss;
+/*FUNCTION Penta::GetNumberOfVertices;{{{*/
+int Penta::GetNumberOfVertices(void){
+	return NUMVERTICES; 
+}
+/*}}}*/
+/*FUNCTION Penta::GetNode(int node_number) {{{*/
+Node* Penta::GetNode(int node_number){
+	_assert_(node_number>=0); 
+	_assert_(node_number<this->NumberofNodes()); 
+	return this->nodes[node_number];
 }
 /*}}}*/
@@ -1413,57 +954,26 @@
 }
 /*}}}*/
-/*FUNCTION Penta::GetMaterialInputValue(IssmDouble* pvalue,Node* node,int enumtype) {{{*/
-void Penta::GetMaterialInputValue(IssmDouble* pvalue,Node* node,int enumtype){
-
-	Input* input=this->material->inputs->GetInput(enumtype);
-	if(!input) _error_("No input of type " << EnumToStringx(enumtype) << " found in tria");
-
-	GaussPenta* gauss=new GaussPenta();
-	gauss->GaussVertex(this->GetNodeIndex(node));
-
-	input->GetInputValue(pvalue,gauss);
-	delete gauss;
-}
-/*}}}*/
-/*FUNCTION Penta::GetPhi {{{*/
-void Penta::GetPhi(IssmDouble* phi, IssmDouble*  epsilon, IssmDouble viscosity){
-	/*Compute deformational heating from epsilon and viscosity */
-
-	IssmDouble epsilon_matrix[3][3];
-	IssmDouble epsilon_eff;
-	IssmDouble epsilon_sqr[3][3];
-
-	/* Build epsilon matrix */
-	epsilon_matrix[0][0]=*(epsilon+0);
-	epsilon_matrix[1][0]=*(epsilon+3);
-	epsilon_matrix[2][0]=*(epsilon+4);
-	epsilon_matrix[0][1]=*(epsilon+3);
-	epsilon_matrix[1][1]=*(epsilon+1);
-	epsilon_matrix[2][1]=*(epsilon+5);
-	epsilon_matrix[0][2]=*(epsilon+4);
-	epsilon_matrix[1][2]=*(epsilon+5);
-	epsilon_matrix[2][2]=*(epsilon+2);
-
-	/* Effective value of epsilon_matrix */
-	epsilon_sqr[0][0]=pow(epsilon_matrix[0][0],2);
-	epsilon_sqr[1][0]=pow(epsilon_matrix[1][0],2);
-	epsilon_sqr[2][0]=pow(epsilon_matrix[2][0],2);
-	epsilon_sqr[0][1]=pow(epsilon_matrix[0][1],2);
-	epsilon_sqr[1][1]=pow(epsilon_matrix[1][1],2);
-	epsilon_sqr[2][1]=pow(epsilon_matrix[2][1],2);
-	epsilon_sqr[0][2]=pow(epsilon_matrix[0][2],2);
-	epsilon_sqr[1][2]=pow(epsilon_matrix[1][2],2);
-	epsilon_sqr[2][2]=pow(epsilon_matrix[2][2],2);
-	epsilon_eff=1/pow(2,0.5)*pow((epsilon_sqr[0][0]+epsilon_sqr[0][1]+ epsilon_sqr[0][2]+ epsilon_sqr[1][0]+ epsilon_sqr[1][1]+ epsilon_sqr[1][2]+ epsilon_sqr[2][0]+ epsilon_sqr[2][1]+ epsilon_sqr[2][2]),0.5);
-
-	/*Phi = Tr(sigma * eps) 
-	 *    = Tr(sigma'* eps)
-	 *    = 2 * eps_eff * sigma'_eff
-	 *    = 4 * mu * eps_eff ^2*/
-	*phi=4*pow(epsilon_eff,2.0)*viscosity;
-}
-/*}}}*/
-/*FUNCTION Penta::GetQuadNormal {{{*/
-void Penta:: GetQuadNormal(IssmDouble* normal,IssmDouble xyz_list[4][3]){
+/*FUNCTION Penta::GetVerticesCoordinatesBase(IssmDouble** pxyz_list){{{*/
+void Penta::GetVerticesCoordinatesBase(IssmDouble** pxyz_list){
+
+	IssmDouble* xyz_list = xNew<IssmDouble>(NUMVERTICES2D*3);
+	::GetVerticesCoordinates(xyz_list,this->vertices,NUMVERTICES2D);
+
+	/*Assign output pointer*/
+	*pxyz_list = xyz_list;
+
+}/*}}}*/
+/*FUNCTION Penta::GetVerticesCoordinatesTop(IssmDouble** pxyz_list){{{*/
+void Penta::GetVerticesCoordinatesTop(IssmDouble** pxyz_list){
+
+	IssmDouble* xyz_list = xNew<IssmDouble>(NUMVERTICES2D*3);
+	::GetVerticesCoordinates(xyz_list,&this->vertices[3],NUMVERTICES2D);
+
+	/*Assign output pointer*/
+	*pxyz_list = xyz_list;
+
+}/*}}}*/
+/*FUNCTION Penta::NormalSection{{{*/
+void Penta::NormalSection(IssmDouble* normal,IssmDouble* xyz_list){
 
 	/*Build unit outward pointing vector*/
@@ -1472,71 +982,19 @@
 	IssmDouble norm;
 
-	AB[0]=xyz_list[1][0] - xyz_list[0][0];
-	AB[1]=xyz_list[1][1] - xyz_list[0][1];
-	AB[2]=xyz_list[1][2] - xyz_list[0][2];
-	AC[0]=xyz_list[2][0] - xyz_list[0][0];
-	AC[1]=xyz_list[2][1] - xyz_list[0][1];
-	AC[2]=xyz_list[2][2] - xyz_list[0][2];
+	AB[0]=xyz_list[1*3+0] - xyz_list[0*3+0];
+	AB[1]=xyz_list[1*3+1] - xyz_list[0*3+1];
+	AB[2]=xyz_list[1*3+2] - xyz_list[0*3+2];
+	AC[0]=xyz_list[2*3+0] - xyz_list[0*3+0];
+	AC[1]=xyz_list[2*3+1] - xyz_list[0*3+1];
+	AC[2]=xyz_list[2*3+2] - xyz_list[0*3+2];
 
 	cross(normal,AB,AC);
-	norm=sqrt(pow(normal[0],2.0)+pow(normal[1],2.0)+pow(normal[2],2.0));
+	norm=sqrt(normal[0]*normal[0]+normal[1]*normal[1]+normal[2]*normal[2]);
 
 	for(int i=0;i<3;i++) normal[i]=normal[i]/norm;
 }
 /*}}}*/
-/*FUNCTION Penta::GetSolutionFromInputs{{{*/
-void  Penta::GetSolutionFromInputs(Vector<IssmDouble>* solution){
-
-	int analysis_type;
-
-	/*retrive parameters: */
-	parameters->FindParam(&analysis_type,AnalysisTypeEnum);
-
-	/*Just branch to the correct InputUpdateFromSolution generator, according to the type of analysis we are carrying out: */
-	switch(analysis_type){
-	#ifdef _HAVE_STRESSBALANCE_
-	case StressbalanceAnalysisEnum:
-		int approximation;
-		inputs->GetInputValue(&approximation,ApproximationEnum);
-		if(approximation==FSApproximationEnum || approximation==NoneApproximationEnum){
-			GetSolutionFromInputsStressbalanceFS(solution);
-		}
-		else if (approximation==SSAApproximationEnum || approximation==HOApproximationEnum || approximation==SIAApproximationEnum){
-			GetSolutionFromInputsStressbalanceHoriz(solution);
-		}
-		else if (approximation==SSAHOApproximationEnum || approximation==HOFSApproximationEnum || approximation==SSAFSApproximationEnum){
-			return; //the elements around will create the solution
-		}
-		break;
-	case StressbalanceSIAAnalysisEnum:
-		GetSolutionFromInputsStressbalanceSIA(solution);
-		break;
-	case StressbalanceVerticalAnalysisEnum:
-		GetSolutionFromInputsOneDof(solution, VzEnum);
-		break;
-	#endif
-	#ifdef _HAVE_THERMAL_
-	case ThermalAnalysisEnum:
-		GetSolutionFromInputsOneDof(solution, TemperatureEnum);
-		break;
-	case EnthalpyAnalysisEnum:
-		GetSolutionFromInputsOneDof(solution, EnthalpyEnum);
-		break;
-	#endif
-	#ifdef _HAVE_HYDROLOGY_
-	case HydrologyDCInefficientAnalysisEnum:
-		GetSolutionFromInputsOneDof(solution, SedimentHeadEnum);
-		break;
-	case HydrologyDCEfficientAnalysisEnum:
-		GetSolutionFromInputsOneDof(solution, EplHeadEnum);
-		break;
-  #endif
-	default:
-		_error_("analysis: " << analysis_type << " (" << EnumToStringx(analysis_type) << ") not supported yet");
-	}
-}
-/*}}}*/
-/*FUNCTION Penta::GetStabilizationParameter {{{*/
-IssmDouble Penta::GetStabilizationParameter(IssmDouble u, IssmDouble v, IssmDouble w, IssmDouble diameter, IssmDouble kappa){
+/*FUNCTION Penta::StabilizationParameter {{{*/
+IssmDouble Penta::StabilizationParameter(IssmDouble u, IssmDouble v, IssmDouble w, IssmDouble diameter, IssmDouble kappa){
 	/*Compute stabilization parameter*/
 	/*kappa=thermalconductivity/(rho_ice*hearcapacity) for thermal model*/
@@ -1555,89 +1013,36 @@
 }
 /*}}}*/
-/*FUNCTION Penta::GetStrainRate3dHO{{{*/
-void Penta::GetStrainRate3dHO(IssmDouble* epsilon,IssmDouble* xyz_list, GaussPenta* gauss, Input* vx_input, Input* vy_input){
-	/*Compute the 3d Blatter/HOStrain Rate (5 components):
-	 *
-	 * epsilon=[exx eyy exy exz eyz]
-	 *
-	 * with exz=1/2 du/dz
-	 *      eyz=1/2 dv/dz
-	 *
-	 * the contribution of vz is neglected
-	 */
-
-	int i;
-	IssmDouble epsilonvx[5];
-	IssmDouble epsilonvy[5];
-
-	/*Check that both inputs have been found*/
-	if (!vx_input || !vy_input){
-		_error_("Input missing. Here are the input pointers we have for vx: " << vx_input << ", vy: " << vy_input << "\n");
-	}
-
-	/*Get strain rate assuming that epsilon has been allocated*/
-	vx_input->GetVxStrainRate3dHO(epsilonvx,xyz_list,gauss);
-	vy_input->GetVyStrainRate3dHO(epsilonvy,xyz_list,gauss);
-
-	/*Sum all contributions*/
-	for(i=0;i<5;i++) epsilon[i]=epsilonvx[i]+epsilonvy[i];
-}
-/*}}}*/
-/*FUNCTION Penta::GetStrainRate3d{{{*/
-void Penta::GetStrainRate3d(IssmDouble* epsilon,IssmDouble* xyz_list, GaussPenta* gauss, Input* vx_input, Input* vy_input, Input* vz_input){
-	/*Compute the 3d Strain Rate (6 components):
-	 *
-	 * epsilon=[exx eyy ezz exy exz eyz]
-	 */
-
-	IssmDouble epsilonvx[6];
-	IssmDouble epsilonvy[6];
-	IssmDouble epsilonvz[6];
-
-	/*Check that both inputs have been found*/
-	if (!vx_input || !vy_input || !vz_input){
-		_error_("Input missing. Here are the input pointers we have for vx: " << vx_input << ", vy: " << vy_input << ", vz: " << vz_input << "\n");
-	}
-
-	/*Get strain rate assuming that epsilon has been allocated*/
-	vx_input->GetVxStrainRate3d(epsilonvx,xyz_list,gauss);
-	vy_input->GetVyStrainRate3d(epsilonvy,xyz_list,gauss);
-	vz_input->GetVzStrainRate3d(epsilonvz,xyz_list,gauss);
-
-	/*Sum all contributions*/
-	for(int i=0;i<6;i++) epsilon[i]=epsilonvx[i]+epsilonvy[i]+epsilonvz[i];
-}
-/*}}}*/
-/*FUNCTION Penta::GetUpperElement{{{*/
-Penta* Penta::GetUpperElement(void){
-
-	Penta* upper_penta=NULL;
-
-	upper_penta=(Penta*)verticalneighbors[1]; //first one under, second one above
-
-	return upper_penta;
-}
-/*}}}*/
-/*FUNCTION Penta::GetVectorFromInputs{{{*/
-void  Penta::GetVectorFromInputs(Vector<IssmDouble>* vector,int input_enum){
-
-	int vertexpidlist[NUMVERTICES];
-
-	/*Get out if this is not an element input*/
-	if (!IsInput(input_enum)) return;
-
-	/*Prepare index list*/
-	this->GetVertexPidList(&vertexpidlist[0]);
-
-	/*Get input (either in element or material)*/
-	Input* input=inputs->GetInput(input_enum);
-	if(!input) _error_("Input " << EnumToStringx(input_enum) << " not found in element");
-
-	/*We found the enum.  Use its values to fill into the vector, using the vertices ids: */
-	input->GetVectorFromInputs(vector,&vertexpidlist[0]);
+/*FUNCTION Penta::GetXcoord {{{*/
+IssmDouble Penta::GetXcoord(Gauss* gauss){
+
+	int    i;
+	IssmDouble x;
+	IssmDouble xyz_list[NUMVERTICES][3];
+	IssmDouble x_list[NUMVERTICES];
+
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	for(i=0;i<NUMVERTICES;i++) x_list[i]=xyz_list[i][0];
+	PentaRef::GetInputValue(&x,x_list,gauss,P1Enum);
+
+	return x;
+}
+/*}}}*/
+/*FUNCTION Penta::GetYcoord {{{*/
+IssmDouble Penta::GetYcoord(Gauss* gauss){
+
+	int    i;
+	IssmDouble y;
+	IssmDouble xyz_list[NUMVERTICES][3];
+	IssmDouble y_list[NUMVERTICES];
+
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	for(i=0;i<NUMVERTICES;i++) y_list[i]=xyz_list[i][1];
+	PentaRef::GetInputValue(&y,y_list,gauss,P1Enum);
+
+	return y;
 }
 /*}}}*/
 /*FUNCTION Penta::GetZcoord {{{*/
-IssmDouble Penta::GetZcoord(GaussPenta* gauss){
+IssmDouble Penta::GetZcoord(Gauss* gauss){
 
 	int    i;
@@ -1646,18 +1051,19 @@
 	IssmDouble z_list[NUMVERTICES];
 
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
 	for(i=0;i<NUMVERTICES;i++) z_list[i]=xyz_list[i][2];
-	PentaRef::GetInputValue(&z,z_list,gauss);
+	PentaRef::GetInputValue(&z,z_list,gauss,P1Enum);
 
 	return z;
 }
 /*}}}*/
-/*FUNCTION Penta::GetZeroLevelsetCoordinates{{{*/
-void Penta::GetZeroLevelsetCoordinates(IssmDouble* xyz_zero,IssmDouble xyz_list[6][3],int levelsetenum){
-	/*Computeportion of the element that is grounded*/ 
+/*FUNCTION Penta::ZeroLevelsetCoordinates{{{*/
+void Penta::ZeroLevelsetCoordinates(IssmDouble** pxyz_zero,IssmDouble* xyz_list,int levelsetenum){
+	/*Compute portion of the element that is grounded*/ 
 
 	int         normal_orientation=0;
 	IssmDouble  s1,s2;
 	IssmDouble  levelset[NUMVERTICES];
+	IssmDouble* xyz_zero = xNew<IssmDouble>(4*3);
 
 	/*Recover parameters and values*/
@@ -1669,24 +1075,24 @@
 		s2=levelset[2]/(levelset[2]-levelset[0]);
 
-		if(levelset[2]>0.) normal_orientation=1;
+		if(levelset[2]<0.) normal_orientation=1; //orientation of quadrangle at base and top, depending on distribution of levelsetfunction
 		/*New point 1*/
-		xyz_zero[3*normal_orientation+0]=xyz_list[2][0]+s1*(xyz_list[1][0]-xyz_list[2][0]);
-		xyz_zero[3*normal_orientation+1]=xyz_list[2][1]+s1*(xyz_list[1][1]-xyz_list[2][1]);
-		xyz_zero[3*normal_orientation+2]=xyz_list[2][2]+s1*(xyz_list[1][2]-xyz_list[2][2]);
+		xyz_zero[3*normal_orientation+0]=xyz_list[2*3+0]+s1*(xyz_list[1*3+0]-xyz_list[2*3+0]);
+		xyz_zero[3*normal_orientation+1]=xyz_list[2*3+1]+s1*(xyz_list[1*3+1]-xyz_list[2*3+1]);
+		xyz_zero[3*normal_orientation+2]=xyz_list[2*3+2]+s1*(xyz_list[1*3+2]-xyz_list[2*3+2]);
 
 		/*New point 0*/
-		xyz_zero[3*(1-normal_orientation)+0]=xyz_list[2][0]+s2*(xyz_list[0][0]-xyz_list[2][0]);
-		xyz_zero[3*(1-normal_orientation)+1]=xyz_list[2][1]+s2*(xyz_list[0][1]-xyz_list[2][1]);
-		xyz_zero[3*(1-normal_orientation)+2]=xyz_list[2][2]+s2*(xyz_list[0][2]-xyz_list[2][2]);
+		xyz_zero[3*(1-normal_orientation)+0]=xyz_list[2*3+0]+s2*(xyz_list[0*3+0]-xyz_list[2*3+0]);
+		xyz_zero[3*(1-normal_orientation)+1]=xyz_list[2*3+1]+s2*(xyz_list[0*3+1]-xyz_list[2*3+1]);
+		xyz_zero[3*(1-normal_orientation)+2]=xyz_list[2*3+2]+s2*(xyz_list[0*3+2]-xyz_list[2*3+2]);
 
 		/*New point 3*/
-		xyz_zero[3*(2+1-normal_orientation)+0]=xyz_list[5][0]+s1*(xyz_list[4][0]-xyz_list[5][0]);
-		xyz_zero[3*(2+1-normal_orientation)+1]=xyz_list[5][1]+s1*(xyz_list[4][1]-xyz_list[5][1]);
-		xyz_zero[3*(2+1-normal_orientation)+2]=xyz_list[5][2]+s1*(xyz_list[4][2]-xyz_list[5][2]);
+		xyz_zero[3*(2+1-normal_orientation)+0]=xyz_list[5*3+0]+s1*(xyz_list[4*3+0]-xyz_list[5*3+0]);
+		xyz_zero[3*(2+1-normal_orientation)+1]=xyz_list[5*3+1]+s1*(xyz_list[4*3+1]-xyz_list[5*3+1]);
+		xyz_zero[3*(2+1-normal_orientation)+2]=xyz_list[5*3+2]+s1*(xyz_list[4*3+2]-xyz_list[5*3+2]);
 
 		/*New point 4*/
-		xyz_zero[3*(2+normal_orientation)+0]=xyz_list[5][0]+s2*(xyz_list[3][0]-xyz_list[5][0]);
-		xyz_zero[3*(2+normal_orientation)+1]=xyz_list[5][1]+s2*(xyz_list[3][1]-xyz_list[5][1]);
-		xyz_zero[3*(2+normal_orientation)+2]=xyz_list[5][2]+s2*(xyz_list[3][2]-xyz_list[5][2]);
+		xyz_zero[3*(2+normal_orientation)+0]=xyz_list[5*3+0]+s2*(xyz_list[3*3+0]-xyz_list[5*3+0]);
+		xyz_zero[3*(2+normal_orientation)+1]=xyz_list[5*3+1]+s2*(xyz_list[3*3+1]-xyz_list[5*3+1]);
+		xyz_zero[3*(2+normal_orientation)+2]=xyz_list[5*3+2]+s2*(xyz_list[3*3+2]-xyz_list[5*3+2]);
 	}
 	else if(levelset[1]*levelset[2]>0.){ //Nodes 1 and 2 are similar, so points must be found on segment 0-1 and 0-2
@@ -1695,24 +1101,24 @@
 		s2=levelset[0]/(levelset[0]-levelset[1]);
 
-		if(levelset[0]>0.) normal_orientation=1;
+		if(levelset[0]<0.) normal_orientation=1;
 		/*New point 1*/
-		xyz_zero[3*normal_orientation+0]=xyz_list[0][0]+s1*(xyz_list[2][0]-xyz_list[0][0]);
-		xyz_zero[3*normal_orientation+1]=xyz_list[0][1]+s1*(xyz_list[2][1]-xyz_list[0][1]);
-		xyz_zero[3*normal_orientation+2]=xyz_list[0][2]+s1*(xyz_list[2][2]-xyz_list[0][2]);
+		xyz_zero[3*normal_orientation+0]=xyz_list[0*3+0]+s1*(xyz_list[2*3+0]-xyz_list[0*3+0]);
+		xyz_zero[3*normal_orientation+1]=xyz_list[0*3+1]+s1*(xyz_list[2*3+1]-xyz_list[0*3+1]);
+		xyz_zero[3*normal_orientation+2]=xyz_list[0*3+2]+s1*(xyz_list[2*3+2]-xyz_list[0*3+2]);
 
 		/*New point 2*/
-		xyz_zero[3*(1-normal_orientation)+0]=xyz_list[0][0]+s2*(xyz_list[1][0]-xyz_list[0][0]);
-		xyz_zero[3*(1-normal_orientation)+1]=xyz_list[0][1]+s2*(xyz_list[1][1]-xyz_list[0][1]);
-		xyz_zero[3*(1-normal_orientation)+2]=xyz_list[0][2]+s2*(xyz_list[1][2]-xyz_list[0][2]);
+		xyz_zero[3*(1-normal_orientation)+0]=xyz_list[0*3+0]+s2*(xyz_list[1*3+0]-xyz_list[0*3+0]);
+		xyz_zero[3*(1-normal_orientation)+1]=xyz_list[0*3+1]+s2*(xyz_list[1*3+1]-xyz_list[0*3+1]);
+		xyz_zero[3*(1-normal_orientation)+2]=xyz_list[0*3+2]+s2*(xyz_list[1*3+2]-xyz_list[0*3+2]);
 
 		/*New point 3*/
-		xyz_zero[3*(2+1-normal_orientation)+0]=xyz_list[3][0]+s1*(xyz_list[5][0]-xyz_list[3][0]);
-		xyz_zero[3*(2+1-normal_orientation)+1]=xyz_list[3][1]+s1*(xyz_list[5][1]-xyz_list[3][1]);
-		xyz_zero[3*(2+1-normal_orientation)+2]=xyz_list[3][2]+s1*(xyz_list[5][2]-xyz_list[3][2]);
+		xyz_zero[3*(2+1-normal_orientation)+0]=xyz_list[3*3+0]+s1*(xyz_list[5*3+0]-xyz_list[3*3+0]);
+		xyz_zero[3*(2+1-normal_orientation)+1]=xyz_list[3*3+1]+s1*(xyz_list[5*3+1]-xyz_list[3*3+1]);
+		xyz_zero[3*(2+1-normal_orientation)+2]=xyz_list[3*3+2]+s1*(xyz_list[5*3+2]-xyz_list[3*3+2]);
 
 		/*New point 4*/
-		xyz_zero[3*(2+normal_orientation)+0]=xyz_list[3][0]+s2*(xyz_list[4][0]-xyz_list[3][0]);
-		xyz_zero[3*(2+normal_orientation)+1]=xyz_list[3][1]+s2*(xyz_list[4][1]-xyz_list[3][1]);
-		xyz_zero[3*(2+normal_orientation)+2]=xyz_list[3][2]+s2*(xyz_list[4][2]-xyz_list[3][2]);
+		xyz_zero[3*(2+normal_orientation)+0]=xyz_list[3*3+0]+s2*(xyz_list[4*3+0]-xyz_list[3*3+0]);
+		xyz_zero[3*(2+normal_orientation)+1]=xyz_list[3*3+1]+s2*(xyz_list[4*3+1]-xyz_list[3*3+1]);
+		xyz_zero[3*(2+normal_orientation)+2]=xyz_list[3*3+2]+s2*(xyz_list[4*3+2]-xyz_list[3*3+2]);
 	}
 	else if(levelset[0]*levelset[2]>0.){ //Nodes 0 and 2 are similar, so points must be found on segment 1-0 and 1-2
@@ -1721,178 +1127,93 @@
 		s2=levelset[1]/(levelset[1]-levelset[2]);
 
-		if(levelset[1]>0.) normal_orientation=1;
+		if(levelset[1]<0.) normal_orientation=1;
 		/*New point 0*/
-		xyz_zero[3*normal_orientation+0]=xyz_list[1][0]+s1*(xyz_list[0][0]-xyz_list[1][0]);
-		xyz_zero[3*normal_orientation+1]=xyz_list[1][1]+s1*(xyz_list[0][1]-xyz_list[1][1]);
-		xyz_zero[3*normal_orientation+2]=xyz_list[1][2]+s1*(xyz_list[0][2]-xyz_list[1][2]);
+		xyz_zero[3*normal_orientation+0]=xyz_list[1*3+0]+s1*(xyz_list[0*3+0]-xyz_list[1*3+0]);
+		xyz_zero[3*normal_orientation+1]=xyz_list[1*3+1]+s1*(xyz_list[0*3+1]-xyz_list[1*3+1]);
+		xyz_zero[3*normal_orientation+2]=xyz_list[1*3+2]+s1*(xyz_list[0*3+2]-xyz_list[1*3+2]);
 
 		/*New point 2*/
-		xyz_zero[3*(1-normal_orientation)+0]=xyz_list[1][0]+s2*(xyz_list[2][0]-xyz_list[1][0]);
-		xyz_zero[3*(1-normal_orientation)+1]=xyz_list[1][1]+s2*(xyz_list[2][1]-xyz_list[1][1]);
-		xyz_zero[3*(1-normal_orientation)+2]=xyz_list[1][2]+s2*(xyz_list[2][2]-xyz_list[1][2]);
+		xyz_zero[3*(1-normal_orientation)+0]=xyz_list[1*3+0]+s2*(xyz_list[2*3+0]-xyz_list[1*3+0]);
+		xyz_zero[3*(1-normal_orientation)+1]=xyz_list[1*3+1]+s2*(xyz_list[2*3+1]-xyz_list[1*3+1]);
+		xyz_zero[3*(1-normal_orientation)+2]=xyz_list[1*3+2]+s2*(xyz_list[2*3+2]-xyz_list[1*3+2]);
 
 		/*New point 3*/
-		xyz_zero[3*(2+1-normal_orientation)+0]=xyz_list[4][0]+s1*(xyz_list[3][0]-xyz_list[4][0]);
-		xyz_zero[3*(2+1-normal_orientation)+1]=xyz_list[4][1]+s1*(xyz_list[3][1]-xyz_list[4][1]);
-		xyz_zero[3*(2+1-normal_orientation)+2]=xyz_list[4][2]+s1*(xyz_list[3][2]-xyz_list[4][2]);
+		xyz_zero[3*(2+1-normal_orientation)+0]=xyz_list[4*3+0]+s1*(xyz_list[3*3+0]-xyz_list[4*3+0]);
+		xyz_zero[3*(2+1-normal_orientation)+1]=xyz_list[4*3+1]+s1*(xyz_list[3*3+1]-xyz_list[4*3+1]);
+		xyz_zero[3*(2+1-normal_orientation)+2]=xyz_list[4*3+2]+s1*(xyz_list[3*3+2]-xyz_list[4*3+2]);
 
 		/*New point 4*/
-		xyz_zero[3*(2+normal_orientation)+0]=xyz_list[4][0]+s2*(xyz_list[5][0]-xyz_list[4][0]);
-		xyz_zero[3*(2+normal_orientation)+1]=xyz_list[4][1]+s2*(xyz_list[5][1]-xyz_list[4][1]);
-		xyz_zero[3*(2+normal_orientation)+2]=xyz_list[4][2]+s2*(xyz_list[5][2]-xyz_list[4][2]);
+		xyz_zero[3*(2+normal_orientation)+0]=xyz_list[4*3+0]+s2*(xyz_list[5*3+0]-xyz_list[4*3+0]);
+		xyz_zero[3*(2+normal_orientation)+1]=xyz_list[4*3+1]+s2*(xyz_list[5*3+1]-xyz_list[4*3+1]);
+		xyz_zero[3*(2+normal_orientation)+2]=xyz_list[4*3+2]+s2*(xyz_list[5*3+2]-xyz_list[4*3+2]);
 	}
 	else if(levelset[0]==0. && levelset[1]==0.){ //front is on point 0 and 1
-		xyz_zero[3*0+0]=xyz_list[0][0];
-		xyz_zero[3*0+1]=xyz_list[0][1];
-		xyz_zero[3*0+2]=xyz_list[0][2];
+		xyz_zero[3*0+0]=xyz_list[0*3+0];
+		xyz_zero[3*0+1]=xyz_list[0*3+1];
+		xyz_zero[3*0+2]=xyz_list[0*3+2];
 
 		/*New point 2*/
-		xyz_zero[3*1+0]=xyz_list[1][0];
-		xyz_zero[3*1+1]=xyz_list[1][1];
-		xyz_zero[3*1+2]=xyz_list[1][2];
+		xyz_zero[3*1+0]=xyz_list[1*3+0];
+		xyz_zero[3*1+1]=xyz_list[1*3+1];
+		xyz_zero[3*1+2]=xyz_list[1*3+2];
 
 		/*New point 3*/
-		xyz_zero[3*2+0]=xyz_list[4][0];
-		xyz_zero[3*2+1]=xyz_list[4][1];
-		xyz_zero[3*2+2]=xyz_list[4][2];
+		xyz_zero[3*2+0]=xyz_list[4*3+0];
+		xyz_zero[3*2+1]=xyz_list[4*3+1];
+		xyz_zero[3*2+2]=xyz_list[4*3+2];
 
 		/*New point 4*/
-		xyz_zero[3*3+0]=xyz_list[3][0];
-		xyz_zero[3*3+1]=xyz_list[3][1];
-		xyz_zero[3*3+2]=xyz_list[3][2];
+		xyz_zero[3*3+0]=xyz_list[3*3+0];
+		xyz_zero[3*3+1]=xyz_list[3*3+1];
+		xyz_zero[3*3+2]=xyz_list[3*3+2];
 	}
 	else if(levelset[0]==0. && levelset[2]==0.){ //front is on point 0 and 1
-		xyz_zero[3*0+0]=xyz_list[2][0];
-		xyz_zero[3*0+1]=xyz_list[2][1];
-		xyz_zero[3*0+2]=xyz_list[2][2];
+		xyz_zero[3*0+0]=xyz_list[2*3+0];
+		xyz_zero[3*0+1]=xyz_list[2*3+1];
+		xyz_zero[3*0+2]=xyz_list[2*3+2];
 
 		/*New point 2*/
-		xyz_zero[3*1+0]=xyz_list[0][0];
-		xyz_zero[3*1+1]=xyz_list[0][1];
-		xyz_zero[3*1+2]=xyz_list[0][2];
+		xyz_zero[3*1+0]=xyz_list[0*3+0];
+		xyz_zero[3*1+1]=xyz_list[0*3+1];
+		xyz_zero[3*1+2]=xyz_list[0*3+2];
 
 		/*New point 3*/
-		xyz_zero[3*2+0]=xyz_list[3][0];
-		xyz_zero[3*2+1]=xyz_list[3][1];
-		xyz_zero[3*2+2]=xyz_list[3][2];
+		xyz_zero[3*2+0]=xyz_list[3*3+0];
+		xyz_zero[3*2+1]=xyz_list[3*3+1];
+		xyz_zero[3*2+2]=xyz_list[3*3+2];
 
 		/*New point 4*/
-		xyz_zero[3*3+0]=xyz_list[5][0];
-		xyz_zero[3*3+1]=xyz_list[5][1];
-		xyz_zero[3*3+2]=xyz_list[5][2];
+		xyz_zero[3*3+0]=xyz_list[5*3+0];
+		xyz_zero[3*3+1]=xyz_list[5*3+1];
+		xyz_zero[3*3+2]=xyz_list[5*3+2];
 	}
 	else if(levelset[1]==0. && levelset[2]==0.){ //front is on point 0 and 1
-		xyz_zero[3*0+0]=xyz_list[1][0];
-		xyz_zero[3*0+1]=xyz_list[1][1];
-		xyz_zero[3*0+2]=xyz_list[1][2];
+		xyz_zero[3*0+0]=xyz_list[1*3+0];
+		xyz_zero[3*0+1]=xyz_list[1*3+1];
+		xyz_zero[3*0+2]=xyz_list[1*3+2];
 
 		/*New point 2*/
-		xyz_zero[3*1+0]=xyz_list[2][0];
-		xyz_zero[3*1+1]=xyz_list[2][1];
-		xyz_zero[3*1+2]=xyz_list[2][2];
+		xyz_zero[3*1+0]=xyz_list[2*3+0];
+		xyz_zero[3*1+1]=xyz_list[2*3+1];
+		xyz_zero[3*1+2]=xyz_list[2*3+2];
 
 		/*New point 3*/
-		xyz_zero[3*2+0]=xyz_list[5][0];
-		xyz_zero[3*2+1]=xyz_list[5][1];
-		xyz_zero[3*2+2]=xyz_list[5][2];
+		xyz_zero[3*2+0]=xyz_list[5*3+0];
+		xyz_zero[3*2+1]=xyz_list[5*3+1];
+		xyz_zero[3*2+2]=xyz_list[5*3+2];
 
 		/*New point 4*/
-		xyz_zero[3*3+0]=xyz_list[4][0];
-		xyz_zero[3*3+1]=xyz_list[4][1];
-		xyz_zero[3*3+2]=xyz_list[4][2];
+		xyz_zero[3*3+0]=xyz_list[4*3+0];
+		xyz_zero[3*3+1]=xyz_list[4*3+1];
+		xyz_zero[3*3+2]=xyz_list[4*3+2];
 	}
 	else _error_("Case not covered");
-}
-/*}}}*/
-/*FUNCTION Penta::Sid {{{*/
-int    Penta::Sid(){
-
-	return sid;
-
-}
-/*}}}*/
-/*FUNCTION Penta::Id {{{*/
-int    Penta::Id(void){
-	return id; 
-}
-/*}}}*/
-/*FUNCTION Penta::InputCreate(IssmDouble* vector,IoModel* iomodel,int M,int N,int vector_type,int vector_enum,int code){{{*/
-void Penta::InputCreate(IssmDouble* vector,IoModel* iomodel,int M,int N,int vector_type,int vector_enum,int code){
-
-	/*Intermediaries*/
-	int             i,t;
-	int             penta_vertex_ids[6];
-	int             row;
-	IssmDouble      nodeinputs[6];
-	IssmDouble      time;
-	TransientInput *transientinput      = NULL;
-
-	/*Branch on type of vector: nodal or elementary: */
-	if(vector_type==1){ //nodal vector
-
-		/*Recover vertices ids needed to initialize inputs*/
-		for(i=0;i<6;i++){ 
-			_assert_(iomodel->elements);
-			penta_vertex_ids[i]=iomodel->elements[6*this->sid+i]; //ids for vertices are in the elements array from Matlab
-		}
-
-		/*Are we in transient or static? */
-		if(M==iomodel->numberofvertices){
-
-			/*create input values: */
-			for(i=0;i<6;i++)nodeinputs[i]=(IssmDouble)vector[penta_vertex_ids[i]-1];
-
-			/*create static input: */
-			this->inputs->AddInput(new PentaInput(vector_enum,nodeinputs,P1Enum));
-		}
-		else if(M==iomodel->numberofvertices+1){
-			/*create transient input: */
-			for(t=0;t<N;t++){ //N is the number of times
-
-				/*create input values: */
-				for(i=0;i<6;i++){
-					row=penta_vertex_ids[i]-1;
-					nodeinputs[i]=(IssmDouble)vector[N*row+t];
-				}
-
-				/*time? :*/
-				time=(IssmDouble)vector[(M-1)*N+t];
-
-				if(t==0)transientinput=new TransientInput(vector_enum);
-				transientinput->AddTimeInput(new PentaInput(vector_enum,nodeinputs,P1Enum),time);
-			}
-			this->inputs->AddInput(transientinput);
-		}
-		else _error_("nodal vector is either numberofvertices (" << iomodel->numberofvertices << "), or numberofvertices+1 long. Field provided is " << M << " long. Enum " << EnumToStringx(vector_enum));
-	}
-	else if(vector_type==2){ //element vector
-		/*Are we in transient or static? */
-		if(M==iomodel->numberofelements){
-
-			/*static mode: create an input out of the element value: */
-
-			if (code==5){ //boolean
-				this->inputs->AddInput(new BoolInput(vector_enum,reCast<bool,IssmDouble>(vector[this->sid])));
-			}
-			else if (code==6){ //integer
-				this->inputs->AddInput(new IntInput(vector_enum,reCast<int,IssmDouble>(vector[this->sid])));
-			}
-			else if (code==7){ //IssmDouble
-				this->inputs->AddInput(new DoubleInput(vector_enum,vector[this->sid]));
-			}
-			else _error_("could not recognize nature of vector from code " << code);
-		}
-		else {
-			_error_("transient elementary inputs not supported yet!");
-		}
-	}
-	else{
-		_error_("Cannot add input for vector type " << vector_type << " (not supported)");
-	}
-
+
+	/*Assign output pointer*/
+	*pxyz_zero= xyz_zero;
 }
 /*}}}*/
 /*FUNCTION Penta::InputDepthAverageAtBase{{{*/
-void  Penta::InputDepthAverageAtBase(int enum_type,int average_enum_type,int object_enum){
+void  Penta::InputDepthAverageAtBase(int enum_type,int average_enum_type){
 
 	int  step,i;
@@ -1900,4 +1221,5 @@
 	IssmDouble  Helem_list[NUMVERTICES];
 	IssmDouble  zeros_list[NUMVERTICES]={0.0};
+	IssmDouble  p0top1_list[NUMVERTICES];
 	Penta* penta=NULL;
 	Input* original_input=NULL;
@@ -1911,5 +1233,5 @@
 
 	/*Are we on the base? If not, return*/
-	if(!IsOnBed()) return;
+	if(!IsOnBase()) return;
 
 	/*OK, we are on bed. Initialize global inputs as 0*/
@@ -1922,10 +1244,5 @@
 
 		/*Step1: Get original input (to be depth avegaged): */
-		if (object_enum==MeshElementsEnum)
-		 original_input=(Input*)penta->inputs->GetInput(enum_type);
-		else if (object_enum==MaterialsEnum)
-		 original_input=(Input*)penta->material->inputs->GetInput(enum_type);
-		else
-		 _error_("object " << EnumToStringx(object_enum) << " not supported yet");
+		original_input=(Input*)penta->inputs->GetInput(enum_type);
 		if(!original_input) _error_("could not find input with enum " << EnumToStringx(enum_type));
 
@@ -1938,10 +1255,11 @@
 			else if (original_input->ObjectEnum()==DoubleInputEnum)
 			 total_integrated_input=new DoubleInput(average_enum_type,0.0);
-			else
+			else{
 			 _error_("object " << EnumToStringx(original_input->ObjectEnum()) << " not supported yet");
+			}
 		}
 
 		/*Step2: Create element thickness input*/
-		GetVerticesCoordinates(&xyz_list[0][0],penta->vertices,NUMVERTICES);
+		::GetVerticesCoordinates(&xyz_list[0][0],penta->vertices,NUMVERTICES);
 		for(i=0;i<3;i++){
 			Helem_list[i]=xyz_list[i+3][2]-xyz_list[i][2];
@@ -1951,6 +1269,19 @@
 
 		/*Step3: Vertically integrate A COPY of the original*/
-		element_integrated_input=(Input*)original_input->copy();
-		element_integrated_input->VerticallyIntegrate(element_thickness_input);
+		if(original_input->ObjectEnum()==PentaInputEnum){
+			if(((PentaInput*)original_input)->element_type==P0Enum){
+				original_input->GetInputValue(&p0top1_list[i]);
+				element_integrated_input= new  PentaInput(original_input->InstanceEnum(),p0top1_list,P1Enum);
+				element_integrated_input->VerticallyIntegrate(element_thickness_input);
+			}
+			else{
+				element_integrated_input= (Input*)original_input->copy();
+				element_integrated_input->VerticallyIntegrate(element_thickness_input);
+			}
+		}
+		else{
+			element_integrated_input= (Input*)original_input->copy();
+			element_integrated_input->VerticallyIntegrate(element_thickness_input);
+		}
 
 		/*Add contributions to global inputs*/
@@ -1966,5 +1297,5 @@
 
 		/* get upper Penta*/
-		penta=penta->GetUpperElement();
+		penta=penta->GetUpperPenta();
 		_assert_(penta->Id()!=this->id);
 
@@ -1982,10 +1313,5 @@
 
 	/*Finally, add to inputs*/
-	if (object_enum==MeshElementsEnum)
-	 this->inputs->AddInput((Input*)depth_averaged_input);
-	else if (object_enum==MaterialsEnum)
-	 this->material->inputs->AddInput((Input*)depth_averaged_input);
-	else
-	 _error_("object " << EnumToStringx(object_enum) << " not supported yet");
+	this->inputs->AddInput((Input*)depth_averaged_input);
 }
 /*}}}*/
@@ -1999,5 +1325,5 @@
 /*}}}*/
 /*FUNCTION Penta::InputExtrude {{{*/
-void  Penta::InputExtrude(int enum_type,int object_type){
+void  Penta::InputExtrude(int enum_type){
 
 	int     i,num_inputs;
@@ -2007,22 +1333,12 @@
 
 	/*Are we on the base, not on the surface?:*/
-	if(!IsOnBed()) return;
+	if(!IsOnBase()) return;
 
 	/*Step1: Get and Extrude original input: */
-	if(object_type==ElementEnum){
-		num_inputs=1;
-		base_inputs=xNew<Input*>(num_inputs);
-		base_inputs[0]=(Input*)this->inputs->GetInput(enum_type);
-	}
-	else if(object_type==MaterialsEnum){
-		num_inputs=1;
-		base_inputs=xNew<Input*>(num_inputs);
-		base_inputs[0]=(Input*)material->inputs->GetInput(enum_type);
-	}
-	else{
-		_error_("object of type " << EnumToStringx(object_type) << " not supported yet");
-	}
+	num_inputs=1;
+	base_inputs=xNew<Input*>(num_inputs);
+	base_inputs[0]=(Input*)this->inputs->GetInput(enum_type);
 	for(i=0;i<num_inputs;i++){
-		if(!base_inputs[i]) _error_("could not find input with enum " << EnumToStringx(enum_type) << " in object " << EnumToStringx(object_type));
+		if(!base_inputs[i]) _error_("could not find input with enum " << EnumToStringx(enum_type));
 		base_inputs[i]->Extrude();
 	}
@@ -2035,5 +1351,5 @@
 	for(;;){
 		/* get upper Penta*/
-		penta=penta->GetUpperElement();
+		penta=penta->GetUpperPenta();
 		_assert_(penta->Id()!=this->id);
 
@@ -2041,13 +1357,5 @@
 		for(i=0;i<num_inputs;i++){
 			copy=(Input*)base_inputs[i]->copy();
-			if (object_type==ElementEnum){
-				penta->inputs->AddInput((Input*)copy);
-			}
-			else if(object_type==MaterialsEnum){
-				penta->material->inputs->AddInput((Input*)copy);
-			}
-			else{
-				_error_("object of type " << EnumToStringx(object_type) << " not supported yet");
-			}
+			penta->inputs->AddInput((Input*)copy);
 		}
 
@@ -2073,41 +1381,13 @@
 }
 /*}}}*/
-/*FUNCTION Penta::InputUpdateFromConstant(bool value, int name);{{{*/
-void  Penta::InputUpdateFromConstant(bool constant, int name){
-
-	/*Check that name is an element input*/
-	if (!IsInput(name)) return;
-
-	/*update input*/
-	this->inputs->AddInput(new BoolInput(name,constant));
-}
-/*}}}*/
-/*FUNCTION Penta::InputUpdateFromConstant(IssmDouble value, int name);{{{*/
-void  Penta::InputUpdateFromConstant(IssmDouble constant, int name){
-	/*Check that name is an element input*/
-	if (!IsInput(name)) return;
-
-	/*update input*/
-	this->inputs->AddInput(new DoubleInput(name,constant));
-}
-/*}}}*/
-/*FUNCTION Penta::InputUpdateFromConstant(int value, int name);{{{*/
-void  Penta::InputUpdateFromConstant(int constant, int name){
-	/*Check that name is an element input*/
-	if (!IsInput(name)) return;
-
-	/*update input*/
-	this->inputs->AddInput(new IntInput(name,constant));
-}
-/*}}}*/
 /*FUNCTION Penta::InputUpdateFromIoModel {{{*/
 void Penta::InputUpdateFromIoModel(int index,IoModel* iomodel){ 
 
 	/*Intermediaries*/
-	IssmInt i,j;
-	int     penta_vertex_ids[6];
-	IssmDouble  nodeinputs[6];
-	IssmDouble  cmmininputs[6];
-	IssmDouble  cmmaxinputs[6];
+	int         i,j;
+	int         penta_vertex_ids[NUMVERTICES];
+	IssmDouble  nodeinputs[NUMVERTICES];
+	IssmDouble  cmmininputs[NUMVERTICES];
+	IssmDouble  cmmaxinputs[NUMVERTICES];
 
 	IssmDouble  yts;
@@ -2121,16 +1401,11 @@
 	if(control_analysis) iomodel->Constant(&num_responses,InversionNumCostFunctionsEnum);
 
-	/*Checks if debuging*/
-	/*{{{*/
+	/*Recover vertices ids needed to initialize inputs*/
 	_assert_(iomodel->elements);
-	/*}}}*/
-
-	/*Recover vertices ids needed to initialize inputs*/
-	for(i=0;i<6;i++){ 
-		penta_vertex_ids[i]=iomodel->elements[6*index+i]; //ids for vertices are in the elements array from Matlab
+	for(i=0;i<NUMVERTICES;i++){ 
+		penta_vertex_ids[i]=iomodel->elements[NUMVERTICES*index+i]; //ids for vertices are in the elements array from Matlab
 	}
 
 	/*Control Inputs*/
-	#ifdef _HAVE_CONTROL_
 	if (control_analysis && iomodel->Data(InversionControlParametersEnum)){
 		for(i=0;i<num_control_type;i++){
@@ -2138,7 +1413,7 @@
 				case BalancethicknessThickeningRateEnum:
 					if (iomodel->Data(BalancethicknessThickeningRateEnum)){
-						for(j=0;j<6;j++)nodeinputs[j]=iomodel->Data(BalancethicknessThickeningRateEnum)[penta_vertex_ids[j]-1]/yts;
-						for(j=0;j<6;j++)cmmininputs[j]=iomodel->Data(InversionMinParametersEnum)[(penta_vertex_ids[j]-1)*num_control_type+i]/yts;
-						for(j=0;j<6;j++)cmmaxinputs[j]=iomodel->Data(InversionMaxParametersEnum)[(penta_vertex_ids[j]-1)*num_control_type+i]/yts;
+						for(j=0;j<NUMVERTICES;j++)nodeinputs[j]=iomodel->Data(BalancethicknessThickeningRateEnum)[penta_vertex_ids[j]-1]/yts;
+						for(j=0;j<NUMVERTICES;j++)cmmininputs[j]=iomodel->Data(InversionMinParametersEnum)[(penta_vertex_ids[j]-1)*num_control_type+i]/yts;
+						for(j=0;j<NUMVERTICES;j++)cmmaxinputs[j]=iomodel->Data(InversionMaxParametersEnum)[(penta_vertex_ids[j]-1)*num_control_type+i]/yts;
 						this->inputs->AddInput(new ControlInput(BalancethicknessThickeningRateEnum,PentaInputEnum,nodeinputs,cmmininputs,cmmaxinputs,i+1));
 					}
@@ -2146,7 +1421,7 @@
 				case VxEnum:
 					if (iomodel->Data(VxEnum)){
-						for(j=0;j<6;j++)nodeinputs[j]=iomodel->Data(VxEnum)[penta_vertex_ids[j]-1]/yts;
-						for(j=0;j<6;j++)cmmininputs[j]=iomodel->Data(InversionMinParametersEnum)[(penta_vertex_ids[j]-1)*num_control_type+i]/yts;
-						for(j=0;j<6;j++)cmmaxinputs[j]=iomodel->Data(InversionMaxParametersEnum)[(penta_vertex_ids[j]-1)*num_control_type+i]/yts;
+						for(j=0;j<NUMVERTICES;j++)nodeinputs[j]=iomodel->Data(VxEnum)[penta_vertex_ids[j]-1]/yts;
+						for(j=0;j<NUMVERTICES;j++)cmmininputs[j]=iomodel->Data(InversionMinParametersEnum)[(penta_vertex_ids[j]-1)*num_control_type+i]/yts;
+						for(j=0;j<NUMVERTICES;j++)cmmaxinputs[j]=iomodel->Data(InversionMaxParametersEnum)[(penta_vertex_ids[j]-1)*num_control_type+i]/yts;
 						this->inputs->AddInput(new ControlInput(VxEnum,PentaInputEnum,nodeinputs,cmmininputs,cmmaxinputs,i+1));
 					}
@@ -2154,7 +1429,7 @@
 				case VyEnum:
 					if (iomodel->Data(VyEnum)){
-						for(j=0;j<6;j++)nodeinputs[j]=iomodel->Data(VyEnum)[penta_vertex_ids[j]-1]/yts;
-						for(j=0;j<6;j++)cmmininputs[j]=iomodel->Data(InversionMinParametersEnum)[(penta_vertex_ids[j]-1)*num_control_type+i]/yts;
-						for(j=0;j<6;j++)cmmaxinputs[j]=iomodel->Data(InversionMaxParametersEnum)[(penta_vertex_ids[j]-1)*num_control_type+i]/yts;
+						for(j=0;j<NUMVERTICES;j++)nodeinputs[j]=iomodel->Data(VyEnum)[penta_vertex_ids[j]-1]/yts;
+						for(j=0;j<NUMVERTICES;j++)cmmininputs[j]=iomodel->Data(InversionMinParametersEnum)[(penta_vertex_ids[j]-1)*num_control_type+i]/yts;
+						for(j=0;j<NUMVERTICES;j++)cmmaxinputs[j]=iomodel->Data(InversionMaxParametersEnum)[(penta_vertex_ids[j]-1)*num_control_type+i]/yts;
 						this->inputs->AddInput(new ControlInput(VyEnum,PentaInputEnum,nodeinputs,cmmininputs,cmmaxinputs,i+1));
 					}
@@ -2162,13 +1437,26 @@
 				case FrictionCoefficientEnum:
 					if (iomodel->Data(FrictionCoefficientEnum)){
-						for(j=0;j<6;j++)nodeinputs[j]=iomodel->Data(FrictionCoefficientEnum)[penta_vertex_ids[j]-1];
-						for(j=0;j<6;j++)cmmininputs[j]=iomodel->Data(InversionMinParametersEnum)[(penta_vertex_ids[j]-1)*num_control_type+i];
-						for(j=0;j<6;j++)cmmaxinputs[j]=iomodel->Data(InversionMaxParametersEnum)[(penta_vertex_ids[j]-1)*num_control_type+i];
+						for(j=0;j<NUMVERTICES;j++)nodeinputs[j]=iomodel->Data(FrictionCoefficientEnum)[penta_vertex_ids[j]-1];
+						for(j=0;j<NUMVERTICES;j++)cmmininputs[j]=iomodel->Data(InversionMinParametersEnum)[(penta_vertex_ids[j]-1)*num_control_type+i];
+						for(j=0;j<NUMVERTICES;j++)cmmaxinputs[j]=iomodel->Data(InversionMaxParametersEnum)[(penta_vertex_ids[j]-1)*num_control_type+i];
 						this->inputs->AddInput(new ControlInput(FrictionCoefficientEnum,PentaInputEnum,nodeinputs,cmmininputs,cmmaxinputs,i+1));
 					}
 					break;
-				/*Material will take care of it*/ 
-				case MaterialsRheologyBbarEnum: break;
-				case DamageDbarEnum:break;
+				case MaterialsRheologyBbarEnum:
+					if(iomodel->Data(MaterialsRheologyBEnum)){
+						for(j=0;j<NUMVERTICES;j++) nodeinputs[j]=iomodel->Data(MaterialsRheologyBEnum)[penta_vertex_ids[j]-1];
+						for(j=0;j<NUMVERTICES;j++)cmmininputs[j]=iomodel->Data(InversionMinParametersEnum)[(penta_vertex_ids[j]-1)*num_control_type+i];
+						for(j=0;j<NUMVERTICES;j++)cmmaxinputs[j]=iomodel->Data(InversionMaxParametersEnum)[(penta_vertex_ids[j]-1)*num_control_type+i];
+						this->inputs->AddInput(new ControlInput(MaterialsRheologyBEnum,PentaInputEnum,nodeinputs,cmmininputs,cmmaxinputs,i+1));
+					}
+					break;
+				case DamageDbarEnum:
+					if(iomodel->Data(DamageDEnum)){
+						for(j=0;j<NUMVERTICES;j++) nodeinputs[j]=iomodel->Data(DamageDEnum)[penta_vertex_ids[j]-1];
+						for(j=0;j<NUMVERTICES;j++)cmmininputs[j]=iomodel->Data(InversionMinParametersEnum)[(penta_vertex_ids[j]-1)*num_control_type+i];
+						for(j=0;j<NUMVERTICES;j++)cmmaxinputs[j]=iomodel->Data(InversionMaxParametersEnum)[(penta_vertex_ids[j]-1)*num_control_type+i];
+						this->inputs->AddInput(new ControlInput(DamageDEnum,PentaInputEnum,nodeinputs,cmmininputs,cmmaxinputs,i+1));
+					}
+					break;
 				default:
 					_error_("Control " << EnumToStringx(reCast<int,IssmDouble>(iomodel->Data(InversionControlParametersEnum)[i])) << " not implemented yet");
@@ -2176,5 +1464,4 @@
 		}
 	}
-	#endif
 
 	/*Need to know the type of approximation for this element*/
@@ -2189,5 +1476,5 @@
 		DatasetInput* datasetinput=new DatasetInput(InversionCostFunctionsCoefficientsEnum);
 		for(i=0;i<num_responses;i++){
-			for(j=0;j<6;j++)nodeinputs[j]=iomodel->Data(InversionCostFunctionsCoefficientsEnum)[(penta_vertex_ids[j]-1)*num_responses+i];
+			for(j=0;j<NUMVERTICES;j++)nodeinputs[j]=iomodel->Data(InversionCostFunctionsCoefficientsEnum)[(penta_vertex_ids[j]-1)*num_responses+i];
 			datasetinput->AddInput(new PentaInput(InversionCostFunctionsCoefficientsEnum,nodeinputs,P1Enum),reCast<int>(iomodel->Data(InversionCostFunctionsEnum)[i]));
 		}
@@ -2198,279 +1485,19 @@
 }
 /*}}}*/
-/*FUNCTION Penta::InputUpdateFromSolution {{{*/
-void  Penta::InputUpdateFromSolution(IssmDouble* solution){
-
-	int analysis_type,inputenum;
-
-	/*retreive parameters: */
-	parameters->FindParam(&analysis_type,AnalysisTypeEnum);
-
-	/*Just branch to the correct InputUpdateFromSolution generator, according to the type of analysis we are carrying out: */
-	switch(analysis_type){
-	#ifdef _HAVE_STRESSBALANCE_
-	case StressbalanceAnalysisEnum:
-		InputUpdateFromSolutionStressbalanceHoriz( solution);
-		break;
-	case StressbalanceSIAAnalysisEnum:
-		InputUpdateFromSolutionStressbalanceSIA( solution);
-		break;
-	case StressbalanceVerticalAnalysisEnum:
-		InputUpdateFromSolutionStressbalanceVert( solution);
-		break;
-	#endif
-	#ifdef _HAVE_CONTROL_
-	case AdjointHorizAnalysisEnum:
-		int approximation;
-		inputs->GetInputValue(&approximation,ApproximationEnum);
-		if(approximation==FSApproximationEnum || approximation==NoneApproximationEnum){
-			InputUpdateFromSolutionAdjointFS( solution);
-		}
-		else{
-			InputUpdateFromSolutionAdjointHoriz( solution);
-		}
-		break;
-	#endif
-	#ifdef _HAVE_THERMAL_
-	case ThermalAnalysisEnum:
-		InputUpdateFromSolutionThermal( solution);
-		break;
-	case EnthalpyAnalysisEnum:
-		InputUpdateFromSolutionEnthalpy( solution);
-		break;
-	case MeltingAnalysisEnum:
-		InputUpdateFromSolutionOneDof(solution,BasalforcingsMeltingRateEnum);
-		break;
-	#endif
-	case L2ProjectionBaseAnalysisEnum:
-		this->parameters->FindParam(&inputenum,InputToL2ProjectEnum);
-		InputUpdateFromSolutionOneDofCollapsed(solution,inputenum);
-		break;
-	case MasstransportAnalysisEnum:
-		InputUpdateFromSolutionMasstransport(solution);
-		break;
-	case FreeSurfaceTopAnalysisEnum:
-		InputUpdateFromSolutionFreeSurfaceTop(solution);
-		break;
-	case FreeSurfaceBaseAnalysisEnum:
-		InputUpdateFromSolutionFreeSurfaceBase(solution);
-		break;
-	#ifdef _HAVE_BALANCED_
-	case BalancethicknessAnalysisEnum:
-		InputUpdateFromSolutionOneDofCollapsed(solution,ThicknessEnum);
-		break;
-	#endif
-	#ifdef _HAVE_HYDROLOGY_
-	case HydrologyDCInefficientAnalysisEnum:
-		InputUpdateFromSolutionHydrologyDCInefficient(solution);
-		break;
-	case HydrologyDCEfficientAnalysisEnum:
-		InputUpdateFromSolutionOneDofCollapsed(solution,EplHeadEnum);
-		break;
-	#endif
-	default: 
-		_error_("analysis " << analysis_type << " (" << EnumToStringx(analysis_type) << ") not supported yet");
-	}
-}
-/*}}}*/
-/*FUNCTION Penta::InputUpdateFromSolutionMasstransport{{{*/
-void  Penta::InputUpdateFromSolutionMasstransport(IssmDouble* solution){
-
-	const int  numdof   = NDOF1*NUMVERTICES;
-	const int  numdof2d = NDOF1*NUMVERTICES2D;
-
-	int    i,hydroadjustment;
-	int*   doflist = NULL;
-	IssmDouble rho_ice,rho_water,minthickness;
-	IssmDouble newthickness[numdof];
-	IssmDouble newbed[numdof];
-	IssmDouble newsurface[numdof];
-	IssmDouble oldbed[NUMVERTICES];
-	IssmDouble oldsurface[NUMVERTICES];
-	IssmDouble oldthickness[NUMVERTICES];
-	IssmDouble phi[NUMVERTICES];
-	Penta  *penta   = NULL;
-
-	/*If not on bed, return*/
-	if (!IsOnBed()) return;
-
-	/*Get dof list: */
-	GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
-
-	/*Use the dof list to index into the solution vector and extrude it */
-	this->parameters->FindParam(&minthickness,MasstransportMinThicknessEnum);
-	for(i=0;i<numdof2d;i++){
-		newthickness[i]=solution[doflist[i]];
-		if(xIsNan<IssmDouble>(newthickness[i])) _error_("NaN found in solution vector");
-		/*Constrain thickness to be at least 1m*/
-		if(newthickness[i]<minthickness) newthickness[i]=minthickness;
-		newthickness[i+numdof2d]=newthickness[i];
-	}
-
-	/*Get previous bed, thickness and surface*/
-	GetInputListOnVertices(&oldbed[0],BedEnum);
-	GetInputListOnVertices(&oldsurface[0],SurfaceEnum);
-	GetInputListOnVertices(&oldthickness[0],ThicknessEnum);
-	GetInputListOnVertices(&phi[0],MaskGroundediceLevelsetEnum);
-
-	/*Fing MasstransportHydrostaticAdjustment to figure out how to update the geometry:*/
-	this->parameters->FindParam(&hydroadjustment,MasstransportHydrostaticAdjustmentEnum);
-
-	/*recover material parameters: */
-	rho_ice=matpar->GetRhoIce();
-	rho_water=matpar->GetRhoWater();
-
-	for(i=0;i<numdof;i++) {
-		/*If shelf: hydrostatic equilibrium*/
-		if (phi[i]>0.){
-			newsurface[i]=oldbed[i]+newthickness[i]; //surface = oldbed + newthickness
-			newbed[i]=oldbed[i];               //same bed: do nothing
-		}
-		else{ //so it is an ice shelf
-			if(hydroadjustment==AbsoluteEnum){
-				newsurface[i]=newthickness[i]*(1-rho_ice/rho_water);
-				newbed[i]=newthickness[i]*(-rho_ice/rho_water);
-			}
-			else if(hydroadjustment==IncrementalEnum){
-				newsurface[i]=oldsurface[i]+(1.0-rho_ice/rho_water)*(newthickness[i]-oldthickness[i]); //surface = oldsurface + (1-di) * dH 
-				newbed[i]=oldbed[i]-rho_ice/rho_water*(newthickness[i]-oldthickness[i]); //bed = oldbed + di * dH
-			}
-			else _error_("Hydrostatic adjustment " << hydroadjustment << " (" << EnumToStringx(hydroadjustment) << ") not supported yet");
-		}
-	}
-
-	/*Start looping over all elements above current element and update all inputs*/
-	penta=this;
-	for(;;){
-		/*Add input to the element: */
-		penta->inputs->AddInput(new PentaInput(ThicknessEnum,newthickness,P1Enum));
-		penta->inputs->AddInput(new PentaInput(SurfaceEnum,newsurface,P1Enum));
-		penta->inputs->AddInput(new PentaInput(BedEnum,newbed,P1Enum));
-
-		/*Stop if we have reached the surface*/
-		if (penta->IsOnSurface()) break;
-
-		/* get upper Penta*/
-		penta=penta->GetUpperElement(); _assert_(penta->Id()!=this->id);
-	}
-
-	/*Free ressources:*/
-	xDelete<int>(doflist);
-}
-/*}}}*/
-/*FUNCTION Penta::InputUpdateFromSolutionFreeSurfaceTop{{{*/
-void  Penta::InputUpdateFromSolutionFreeSurfaceTop(IssmDouble* solution){
-
-	const int  numdof   = NDOF1*NUMVERTICES;
-	const int  numdof2d = NDOF1*NUMVERTICES2D;
-
-	int    i;
-	int*   doflist = NULL;
-	IssmDouble newthickness[numdof];
-	IssmDouble newbed[numdof];
-	IssmDouble newsurface[numdof];
-
-	/*If not on bed, return*/
-	if (!IsOnSurface()) return;
-
-	/*Get dof list: */
-	GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
-
-	/*Use the dof list to index into the solution vector and extrude it */
-	for(i=0;i<numdof2d;i++){
-		newsurface[i+numdof2d]=solution[doflist[i+numdof2d]];
-		if(xIsNan<IssmDouble>(newsurface[i+numdof2d])) _error_("NaN found in solution vector");
-		newsurface[i]=newsurface[i+numdof2d];
-	}
-
-	/*Get previous bed and thickness*/
-	GetInputListOnVertices(&newbed[0],BedEnum);
-
-	for(i=0;i<numdof;i++) {
-		newthickness[i]=newsurface[i]-newbed[i];
-		_assert_(newthickness[i]>0.);
-	}
-
-	/*Start looping over all elements above current element and update all inputs*/
-	Penta* penta=this;
-	for(;;){
-		/*Add input to the element: */
-		penta->inputs->AddInput(new PentaInput(ThicknessEnum,newthickness,P1Enum));
-		penta->inputs->AddInput(new PentaInput(SurfaceEnum,newsurface,P1Enum));
-
-		/*Stop if we have reached the surface*/
-		if(penta->IsOnBed()) break;
-
-		/* get upper Penta*/
-		penta=penta->GetLowerElement(); _assert_(penta->Id()!=this->id);
-	}
-
-	/*Free ressources:*/
-	xDelete<int>(doflist);
-}
-/*}}}*/
-/*FUNCTION Penta::InputUpdateFromSolutionFreeSurfaceBase{{{*/
-void  Penta::InputUpdateFromSolutionFreeSurfaceBase(IssmDouble* solution){
-
-	const int  numdof   = NDOF1*NUMVERTICES;
-	const int  numdof2d = NDOF1*NUMVERTICES2D;
-
-	int    i;
-	int*   doflist = NULL;
-	IssmDouble newthickness[numdof];
-	IssmDouble newbed[numdof];
-	IssmDouble newsurface[numdof];
-
-	/*If not on bed, return*/
-	if (!IsOnBed()) return;
-
-	/*Get dof list: */
-	GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
-
-	/*Use the dof list to index into the solution vector and extrude it */
-	for(i=0;i<numdof2d;i++){
-		newbed[i]=solution[doflist[i]];
-		if(xIsNan<IssmDouble>(newbed[i])) _error_("NaN found in solution vector");
-		newbed[i+numdof2d]=newbed[i];
-	}
-
-	/*Get previous bed and thickness*/
-	GetInputListOnVertices(&newsurface[0],SurfaceEnum);
-
-	for(i=0;i<numdof;i++) {
-		newthickness[i]=newsurface[i]-newbed[i];
-		_assert_(newthickness[i]>0.);
-	}
-
-	/*Start looping over all elements above current element and update all inputs*/
-	Penta* penta=this;
-	for(;;){
-		/*Add input to the element: */
-		penta->inputs->AddInput(new PentaInput(ThicknessEnum,newthickness,P1Enum));
-		penta->inputs->AddInput(new PentaInput(BedEnum,newbed,P1Enum));
-
-		/*Stop if we have reached the surface*/
-		if(penta->IsOnSurface()) break;
-
-		/* get upper Penta*/
-		penta=penta->GetUpperElement(); _assert_(penta->Id()!=this->id);
-	}
-
-	/*Free ressources:*/
-	xDelete<int>(doflist);
-}
-/*}}}*/
 /*FUNCTION Penta::InputUpdateFromSolutionOneDof{{{*/
 void  Penta::InputUpdateFromSolutionOneDof(IssmDouble* solution,int enum_type){
 
-	const int numdof = NDOF1*NUMVERTICES;
-
-	IssmDouble values[numdof];
-	int*   doflist=NULL;
-
-	/*Get dof list: */
+	/*Intermediary*/
+	int* doflist = NULL;
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = this->NumberofNodes();
+
+	/*Fetch dof list and allocate solution vector*/
 	GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
+	IssmDouble* values    = xNew<IssmDouble>(numnodes);
 
 	/*Use the dof list to index into the solution vector: */
-	for(int i=0;i<numdof;i++){
+	for(int i=0;i<numnodes;i++){
 		values[i]=solution[doflist[i]];
 		if(xIsNan<IssmDouble>(values[i])) _error_("NaN found in solution vector");
@@ -2481,4 +1508,5 @@
 
 	/*Free ressources:*/
+	xDelete<IssmDouble>(values);
 	xDelete<int>(doflist);
 }
@@ -2495,5 +1523,5 @@
 
 	/*If not on bed, return*/
-	if (!IsOnBed()) return;
+	if (!IsOnBase()) return;
 
 	/*Get dof list: */
@@ -2517,5 +1545,5 @@
 
 		/* get upper Penta*/
-		penta=penta->GetUpperElement(); _assert_(penta->Id()!=this->id);
+		penta=penta->GetUpperPenta(); _assert_(penta->Id()!=this->id);
 	}
 
@@ -2584,92 +1612,18 @@
 }
 /*}}}*/
-/*FUNCTION Penta::IsOnBed{{{*/
-bool Penta::IsOnBed(void){
-
-	bool onbed;
-	inputs->GetInputValue(&onbed,MeshElementonbedEnum);
-	return onbed;
-}
-/*}}}*/
-/*FUNCTION Penta::IsInput{{{*/
-bool Penta::IsInput(int name){
-	if (
-				name==ThicknessEnum ||
-				name==SurfaceEnum ||
-				name==BedEnum ||
-				name==BathymetryEnum ||
-				name==SurfaceSlopeXEnum ||
-				name==SurfaceSlopeYEnum ||
-				name==SurfaceforcingsMassBalanceEnum ||
-				name==BasalforcingsMeltingRateEnum ||
-				name==BasalforcingsGeothermalfluxEnum ||
-				name==SurfaceAreaEnum||
-				name==PressureEnum ||
-				name==VxEnum ||
-				name==VyEnum ||
-				name==VzEnum ||
-				name==VxMeshEnum ||
-				name==VyMeshEnum ||
-				name==VzMeshEnum ||
-				name==InversionVxObsEnum ||
-				name==InversionVyObsEnum ||
-				name==InversionVzObsEnum ||
-				name==TemperatureEnum ||
-				name==EnthalpyEnum ||
-				name==EnthalpyPicardEnum ||
-				name==WaterfractionEnum||
-				name==FrictionCoefficientEnum ||
-				name==MaskGroundediceLevelsetEnum ||
-				name==MaskIceLevelsetEnum ||
-				name==GradientEnum ||
-				name==OldGradientEnum  ||
-				name==ConvergedEnum || 
-				name==QmuVxEnum ||
-				name==QmuVyEnum ||
-				name==QmuVzEnum ||
-				name==QmuVxMeshEnum ||
-				name==QmuVyMeshEnum ||
-				name==QmuVzMeshEnum ||
-				name==QmuPressureEnum ||
-				name==QmuBedEnum ||
-				name==QmuThicknessEnum ||
-				name==QmuSurfaceEnum ||
-				name==QmuTemperatureEnum ||
-				name==QmuMeltingEnum ||
-				name==QmuMaskGroundediceLevelsetEnum ||
-				name==QmuMaskIceLevelsetEnum ||
-				name==GiaWEnum || 
-				name==GiadWdtEnum ||
-				name==SedimentHeadEnum ||
-				name==EplHeadEnum ||
-				name==SedimentHeadOldEnum ||
-				name==EplHeadOldEnum ||
-				name==HydrologydcMaskEplactiveEnum ||
-				name==WaterTransferEnum
-
-				) {
-		return true;
-	}
-	else return false;
-}
-/*}}}*/
-/*FUNCTION Penta::IsFloating{{{*/
-bool   Penta::IsFloating(){
-
-	bool shelf;
-	int  migration_style;
-	parameters->FindParam(&migration_style,GroundinglineMigrationEnum);
-
-	if(migration_style==SubelementMigrationEnum || migration_style==SubelementMigration2Enum){ //Floating if all nodes are floating
-		if(this->inputs->Max(MaskGroundediceLevelsetEnum) <= 0.) shelf=true;
-		else shelf=false;
-	}
-	else if(migration_style==NoneEnum || migration_style==AgressiveMigrationEnum || migration_style==SoftMigrationEnum){ //Floating if all nodes are floating
-		if(this->inputs->Min(MaskGroundediceLevelsetEnum) > 0.) shelf=false;
-		else shelf=true;
-	}
-	else _error_("migration_style not implemented yet");
-
-	return shelf;
+/*FUNCTION Penta::IsOnBase{{{*/
+bool Penta::IsOnBase(void){
+
+	bool onbase;
+	inputs->GetInputValue(&onbase,MeshElementonbaseEnum);
+	return onbase;
+}
+/*}}}*/
+/*FUNCTION Penta::IsOnSurface{{{*/
+bool Penta::IsOnSurface(void){
+
+	bool onsurface;
+	inputs->GetInputValue(&onsurface,MeshElementonsurfaceEnum);
+	return onsurface;
 }
 /*}}}*/
@@ -2689,28 +1643,46 @@
 }
 /*}}}*/
-/*FUNCTION Penta::IsOnSurface{{{*/
-bool Penta::IsOnSurface(void){
-
-	bool onsurface;
-	inputs->GetInputValue(&onsurface,MeshElementonsurfaceEnum);
-	return onsurface;
-}
-/*}}}*/
-/*FUNCTION Penta::NoIceInElement {{{*/
-bool   Penta::NoIceInElement(){
-
-	/*Get levelset*/
-	IssmDouble ls[NUMVERTICES];
-	GetInputListOnVertices(&ls[0],MaskIceLevelsetEnum);
-
-	/*If the level set is >0, ice is present in this element*/
-	if(ls[0]>0. || ls[1]>0. || ls[2]>0.) return false;
-
-	/*If the level set is awlays <=0, there is no ice here*/
-	return true;
+/*FUNCTION Penta::JacobianDeterminant{{{*/
+void Penta::JacobianDeterminant(IssmDouble* pJdet,IssmDouble* xyz_list,Gauss* gauss){
+
+	_assert_(gauss->Enum()==GaussPentaEnum);
+	this->GetJacobianDeterminant(pJdet,xyz_list,(GaussPenta*)gauss);
+
+}
+/*}}}*/
+/*FUNCTION Penta::JacobianDeterminantBase{{{*/
+void Penta::JacobianDeterminantBase(IssmDouble* pJdet,IssmDouble* xyz_list_base,Gauss* gauss){
+
+	_assert_(gauss->Enum()==GaussPentaEnum);
+	this->GetTriaJacobianDeterminant(pJdet,xyz_list_base,(GaussPenta*)gauss);
+
+}
+/*}}}*/
+/*FUNCTION Penta::JacobianDeterminantLine{{{*/
+void Penta::JacobianDeterminantLine(IssmDouble* pJdet,IssmDouble* xyz_list_line,Gauss* gauss){
+
+	_assert_(gauss->Enum()==GaussPentaEnum);
+	this->GetSegmentJacobianDeterminant(pJdet,xyz_list_line,(GaussPenta*)gauss);
+
+}
+/*}}}*/
+/*FUNCTION Penta::JacobianDeterminantTop{{{*/
+void Penta::JacobianDeterminantTop(IssmDouble* pJdet,IssmDouble* xyz_list_top,Gauss* gauss){
+
+	_assert_(gauss->Enum()==GaussPentaEnum);
+	this->GetTriaJacobianDeterminant(pJdet,xyz_list_top,(GaussPenta*)gauss);
+
+}
+/*}}}*/
+/*FUNCTION Penta::JacobianDeterminantSurface{{{*/
+void Penta::JacobianDeterminantSurface(IssmDouble* pJdet,IssmDouble* xyz_list_quad,Gauss* gauss){
+
+	_assert_(gauss->Enum()==GaussPentaEnum);
+	this->GetQuadJacobianDeterminant(pJdet,xyz_list_quad,(GaussPenta*)gauss);
+
 }
 /*}}}*/
 /*FUNCTION Penta::MinEdgeLength{{{*/
-IssmDouble Penta::MinEdgeLength(IssmDouble xyz_list[6][3]){
+IssmDouble Penta::MinEdgeLength(IssmDouble* xyz_list){
 	/*Return the minimum lenght of the nine egdes of the penta*/
 
@@ -2726,5 +1698,5 @@
 
 		/*Compute the length of this edge and compare it to the minimal length*/
-		length=sqrt(pow(xyz_list[node0][0]-xyz_list[node1][0],2)+pow(xyz_list[node0][1]-xyz_list[node1][1],2)+pow(xyz_list[node0][2]-xyz_list[node1][2],2));
+		length=sqrt(pow(xyz_list[node0*3+0]-xyz_list[node1*3+0],2)+pow(xyz_list[node0*3+1]-xyz_list[node1*3+1],2)+pow(xyz_list[node0*3+2]-xyz_list[node1*3+2],2));
 		if(length<minlength || minlength<0) minlength=length;
 	}
@@ -2763,4 +1735,167 @@
 	if(found)*pvalue=value;
 	return found;
+}
+/*}}}*/
+/*FUNCTION Penta::NewGauss(){{{*/
+Gauss* Penta::NewGauss(void){
+	return new GaussPenta();
+}
+/*}}}*/
+/*FUNCTION Penta::NewGauss(int order){{{*/
+Gauss* Penta::NewGauss(int order){
+	return new GaussPenta(order,order);
+}
+/*}}}*/
+/*FUNCTION Penta::NewGauss(IssmDouble* xyz_list, IssmDouble* xyz_list_front,int order_horiz,int order_vert){{{*/
+Gauss* Penta::NewGauss(IssmDouble* xyz_list, IssmDouble* xyz_list_front,int order_horiz,int order_vert){
+
+	IssmDouble  area_coordinates[4][3];
+
+	GetAreaCoordinates(&area_coordinates[0][0],xyz_list_front,xyz_list,4);
+
+	return new GaussPenta(area_coordinates,order_horiz,order_vert);
+}
+/*}}}*/
+/*FUNCTION Penta::NewGaussBase(int order){{{*/
+Gauss* Penta::NewGaussBase(int order){
+	return new GaussPenta(0,1,2,order);
+}
+/*}}}*/
+/*FUNCTION Penta::NewGaussLine(int vertex1,int vertex2,int order){{{*/
+Gauss* Penta::NewGaussLine(int vertex1,int vertex2,int order){
+	return new GaussPenta(vertex1,vertex2,order);
+}
+/*}}}*/
+/*FUNCTION Penta::NewGaussTop(int order){{{*/
+Gauss* Penta::NewGaussTop(int order){
+	return new GaussPenta(3,4,5,order);
+}
+/*}}}*/
+/*FUNCTION Penta::NodalFunctions{{{*/
+void Penta::NodalFunctions(IssmDouble* basis, Gauss* gauss){
+
+	_assert_(gauss->Enum()==GaussPentaEnum);
+	this->GetNodalFunctions(basis,(GaussPenta*)gauss);
+
+}
+/*}}}*/
+/*FUNCTION Penta::NodalFunctionsP1{{{*/
+void Penta::NodalFunctionsP1(IssmDouble* basis, Gauss* gauss){
+
+	_assert_(gauss->Enum()==GaussPentaEnum);
+	this->GetNodalFunctionsP1(basis,(GaussPenta*)gauss);
+
+}
+/*}}}*/
+/*FUNCTION Penta::NodalFunctionsDerivatives{{{*/
+void Penta::NodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss){
+
+	_assert_(gauss->Enum()==GaussPentaEnum);
+	this->GetNodalFunctionsDerivatives(dbasis,xyz_list,(GaussPenta*)gauss);
+
+}
+/*}}}*/
+/*FUNCTION Penta::NodalFunctionsP1Derivatives{{{*/
+void Penta::NodalFunctionsP1Derivatives(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss){
+
+	_assert_(gauss->Enum()==GaussPentaEnum);
+	this->GetNodalFunctionsP1Derivatives(dbasis,xyz_list,(GaussPenta*)gauss);
+
+}
+/*}}}*/
+/*FUNCTION Penta::NodalFunctionsMINIDerivatives{{{*/
+void Penta::NodalFunctionsMINIDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss){
+
+	_assert_(gauss->Enum()==GaussPentaEnum);
+	this->GetNodalFunctionsMINIDerivatives(dbasis,xyz_list,(GaussPenta*)gauss);
+
+}
+/*}}}*/
+/*FUNCTION Penta::NodalFunctionsDerivativesVelocity{{{*/
+void Penta::NodalFunctionsDerivativesVelocity(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss){
+
+	_assert_(gauss->Enum()==GaussPentaEnum);
+	this->GetNodalFunctionsDerivativesVelocity(dbasis,xyz_list,(GaussPenta*)gauss);
+
+}
+/*}}}*/
+/*FUNCTION Penta::NodalFunctionsVelocity{{{*/
+void Penta::NodalFunctionsVelocity(IssmDouble* basis, Gauss* gauss){
+
+	_assert_(gauss->Enum()==GaussPentaEnum);
+	this->GetNodalFunctionsVelocity(basis,(GaussPenta*)gauss);
+
+}
+/*}}}*/
+/*FUNCTION Penta::NodalFunctionsPressure{{{*/
+void Penta::NodalFunctionsPressure(IssmDouble* basis, Gauss* gauss){
+
+	_assert_(gauss->Enum()==GaussPentaEnum);
+	this->GetNodalFunctionsPressure(basis,(GaussPenta*)gauss);
+
+}
+/*}}}*/
+/*FUNCTION Penta::NodalFunctionsTensor{{{*/
+void Penta::NodalFunctionsTensor(IssmDouble* basis, Gauss* gauss){
+
+	_assert_(gauss->Enum()==GaussPentaEnum);
+	this->GetNodalFunctionsTensor(basis,(GaussPenta*)gauss);
+
+}
+/*}}}*/
+/*FUNCTION Penta::NormalBase {{{*/
+void Penta::NormalBase(IssmDouble* bed_normal,IssmDouble* xyz_list){
+
+	IssmDouble v13[3],v23[3];
+	IssmDouble normal[3];
+	IssmDouble normal_norm;
+
+	for(int i=0;i<3;i++){
+		v13[i]=xyz_list[0*3+i]-xyz_list[2*3+i];
+		v23[i]=xyz_list[1*3+i]-xyz_list[2*3+i];
+	}
+
+	normal[0]=v13[1]*v23[2]-v13[2]*v23[1];
+	normal[1]=v13[2]*v23[0]-v13[0]*v23[2];
+	normal[2]=v13[0]*v23[1]-v13[1]*v23[0];
+	normal_norm=sqrt(normal[0]*normal[0]+ normal[1]*normal[1]+ normal[2]*normal[2]);
+
+	/*Bed normal is opposite to surface normal*/
+	bed_normal[0]=-normal[0]/normal_norm;
+	bed_normal[1]=-normal[1]/normal_norm;
+	bed_normal[2]=-normal[2]/normal_norm;
+}
+/*}}}*/
+/*FUNCTION Penta::NormalTop {{{*/
+void Penta::NormalTop(IssmDouble* top_normal,IssmDouble* xyz_list){
+
+	int i;
+	IssmDouble v13[3],v23[3];
+	IssmDouble normal[3];
+	IssmDouble normal_norm;
+
+	for (i=0;i<3;i++){
+		v13[i]=xyz_list[0*3+i]-xyz_list[2*3+i];
+		v23[i]=xyz_list[1*3+i]-xyz_list[2*3+i];
+	}
+
+	normal[0]=v13[1]*v23[2]-v13[2]*v23[1];
+	normal[1]=v13[2]*v23[0]-v13[0]*v23[2];
+	normal[2]=v13[0]*v23[1]-v13[1]*v23[0];
+	normal_norm=sqrt(normal[0]*normal[0] + normal[1]*normal[1] + normal[2]*normal[2]);
+
+	top_normal[0]=normal[0]/normal_norm;
+	top_normal[1]=normal[1]/normal_norm;
+	top_normal[2]=normal[2]/normal_norm;
+}
+/*}}}*/
+/*FUNCTION Penta::NumberofNodesPressure{{{*/
+int Penta::NumberofNodesPressure(void){
+	return PentaRef::NumberofNodesPressure();
+}
+/*}}}*/
+/*FUNCTION Penta::NumberofNodesVelocity{{{*/
+int Penta::NumberofNodesVelocity(void){
+	return PentaRef::NumberofNodesVelocity();
 }
 /*}}}*/
@@ -2811,5 +1946,5 @@
    this->inputs->AddInput(new PentaInput(SurfaceforcingsMassBalanceEnum,&agd[0],P1Enum));
    //this->inputs->AddInput(new PentaVertexInput(ThermalSpcTemperatureEnum,&Tsurf[0]));
-   this->InputExtrude(SurfaceforcingsMassBalanceEnum,ElementEnum);
+   this->InputExtrude(SurfaceforcingsMassBalanceEnum);
 
 	/*clean-up*/
@@ -2817,93 +1952,74 @@
 }
 /*}}}*/
-/*FUNCTION Penta::ResultInterpolation{{{*/
-void Penta::ResultInterpolation(int* pinterpolation,int output_enum){
-
-	Input* input=this->inputs->GetInput(output_enum);
-
-	/*If this input is not already in Inputs, maybe it needs to be computed?*/
-	if(!input){
-		switch(output_enum){
-			case ViscousHeatingEnum:
-				this->ViscousHeatingCreateInput();
-				input=this->inputs->GetInput(output_enum);
-				break;
-			case StressTensorxxEnum: 
-				this->ComputeStressTensor();
-				input=this->inputs->GetInput(output_enum);
-				break;
-			case StressTensorxyEnum: 
-				this->ComputeStressTensor();
-				input=this->inputs->GetInput(output_enum);
-				break;
-			case StressTensorxzEnum: 
-				this->ComputeStressTensor();
-				input=this->inputs->GetInput(output_enum);
-				break;
-			case StressTensoryyEnum: 
-				this->ComputeStressTensor();
-				input=this->inputs->GetInput(output_enum);
-				break;
-			case StressTensoryzEnum: 
-				this->ComputeStressTensor();
-				input=this->inputs->GetInput(output_enum);
-				break;
-			case StressTensorzzEnum: 
-				this->ComputeStressTensor();
-				input=this->inputs->GetInput(output_enum);
-				break;
-			default:
-				_error_("input "<<EnumToStringx(output_enum)<<" not found in element");
+/*FUNCTION Penta::ReduceMatrices{{{*/
+void Penta::ReduceMatrices(ElementMatrix* Ke,ElementVector* pe){
+
+	int analysis_type;
+	parameters->FindParam(&analysis_type,AnalysisTypeEnum);
+
+	if(pe){
+		if(analysis_type==StressbalanceAnalysisEnum){
+			if(this->element_type==MINIcondensedEnum){
+				int approximation;
+				inputs->GetInputValue(&approximation,ApproximationEnum);
+				if(approximation==HOFSApproximationEnum || approximation==SSAFSApproximationEnum){
+					//Do nothing, condensation already done in PVectorCoupling
+				}
+				else{
+					int indices[3]={18,19,20};
+					pe->StaticCondensation(Ke,3,&indices[0]);
+				}
+			}
+			else if(this->element_type==P1bubblecondensedEnum){
+				int size   = nodes[6]->GetNumberOfDofs(NoneApproximationEnum,GsetEnum);
+				int offset = 0;
+				for(int i=0;i<6;i++) offset+=nodes[i]->GetNumberOfDofs(NoneApproximationEnum,GsetEnum);
+				int* indices=xNew<int>(size);
+				for(int i=0;i<size;i++) indices[i] = offset+i;
+				pe->StaticCondensation(Ke,size,indices);
+				xDelete<int>(indices);
+			}
 		}
 	}
 
-	/*Assign output pointer*/
-	*pinterpolation = input->GetResultInterpolation();
-
-}
-/*}}}*/
-/*FUNCTION Penta::ResultToVector{{{*/
-void Penta::ResultToVector(Vector<IssmPDouble>* vector,int output_enum){
-
-	Input* input=this->inputs->GetInput(output_enum);
-	if(!input) _error_("input "<<EnumToStringx(output_enum)<<" not found in element");
-
-	switch(input->GetResultInterpolation()){
-		case P0Enum:
-			_error_("not implemented...");
-			break;
-		case P1Enum:{
-			IssmDouble  values[NUMVERTICES];
-			IssmPDouble pvalues[NUMVERTICES]; 
-			int         connectivity[NUMVERTICES];
-			int         sidlist[NUMVERTICES];
-
-			this->GetVertexSidList(&sidlist[0]);
-			this->GetConnectivityList(&connectivity[0]);
-			this->GetInputListOnVertices(&values[0],output_enum);
-			for(int i=0;i<NUMVERTICES;i++) pvalues[i] = reCast<IssmPDouble>(values[i])/reCast<IssmPDouble>(connectivity[i]);
-
-			vector->SetValues(NUMVERTICES,&sidlist[0],&pvalues[0],ADD_VAL);
-			break;
-					}
-		default:
-			_error_("interpolation "<<EnumToStringx(input->GetResultInterpolation())<<" not supported yet");
-	}
-
-
-}
-/*}}}*/
-/*FUNCTION Penta::ResetCoordinateSystem{{{*/
-void  Penta::ResetCoordinateSystem(void){
-
-	int        approximation;
-	int        numindices;
-	int       *indices = NULL;
-	IssmDouble slopex,slopey;
-	IssmDouble xz_plane[6];
+	if(Ke){
+		if(analysis_type==StressbalanceAnalysisEnum){
+			int approximation;
+			inputs->GetInputValue(&approximation,ApproximationEnum);
+			if(approximation==HOFSApproximationEnum || approximation==SSAFSApproximationEnum){
+				//Do nothing condensatino already done for Stokes part
+			}
+			else{
+				if(this->element_type==MINIcondensedEnum){
+					int indices[3]={18,19,20};
+					Ke->StaticCondensation(3,&indices[0]);
+				}
+				else if(this->element_type==P1bubblecondensedEnum){
+					int size   = nodes[6]->GetNumberOfDofs(NoneApproximationEnum,GsetEnum);
+					int offset = 0;
+					for(int i=0;i<6;i++) offset+=nodes[i]->GetNumberOfDofs(NoneApproximationEnum,GsetEnum);
+					int* indices=xNew<int>(size);
+					for(int i=0;i<size;i++) indices[i] = offset+i;
+					Ke->StaticCondensation(size,indices);
+					xDelete<int>(indices);
+				}
+			}
+		}
+	}
+}
+/*}}}*/
+/*FUNCTION Penta::ResetFSBasalBoundaryCondition{{{*/
+void  Penta::ResetFSBasalBoundaryCondition(void){
+
+	int          approximation;
+	int          numindices;
+	int         *indices = NULL;
+	IssmDouble   slopex,slopey,groundedice;
+	IssmDouble   xz_plane[6];
+	IssmDouble*  vertexapproximation= NULL;
 
 	/*For FS only: we want the CS to be tangential to the bedrock*/
 	inputs->GetInputValue(&approximation,ApproximationEnum);
-	if(IsFloating() || !IsOnBed() || (approximation!=FSApproximationEnum && approximation!=SSAFSApproximationEnum &&  approximation!=HOFSApproximationEnum)) return;
+	if(!IsOnBase() || (approximation!=FSApproximationEnum && approximation!=SSAFSApproximationEnum &&  approximation!=HOFSApproximationEnum)) return;
 
 	/*Get number of nodes for velocity only and base*/
@@ -2913,4 +2029,5 @@
 	Input* slopex_input=inputs->GetInput(BedSlopeXEnum); _assert_(slopex_input);
 	Input* slopey_input=inputs->GetInput(BedSlopeYEnum); _assert_(slopey_input);
+	Input* groundedicelevelset_input=inputs->GetInput(MaskGroundediceLevelsetEnum); _assert_(groundedicelevelset_input);
 
 	/*Loop over basal nodes and update their CS*/
@@ -2921,4 +2038,5 @@
 		slopex_input->GetInputValue(&slopex,gauss);
 		slopey_input->GetInputValue(&slopey,gauss);
+		groundedicelevelset_input->GetInputValue(&groundedice,gauss);
 
 		/*New X axis          New Z axis*/
@@ -2927,4 +2045,23 @@
 		xz_plane[2]=slopex;   xz_plane[5]=1.;          
 
+		if(groundedice>=0){
+			if(this->nodes[indices[i]]->GetApproximation()==FSvelocityEnum){
+				this->nodes[indices[i]]->DofInSSet(2); //vz 
+			}
+			else if(this->nodes[indices[i]]->GetApproximation()==SSAFSApproximationEnum || this->nodes[indices[i]]->GetApproximation()==HOFSApproximationEnum){
+				this->nodes[indices[i]]->DofInSSet(4); //vz 
+			}
+			else _error_("Flow equation approximation"<<EnumToStringx(this->nodes[indices[i]]->GetApproximation())<<" not supported yet");
+		}
+		else{
+			if(this->nodes[indices[i]]->GetApproximation()==FSvelocityEnum){
+				this->nodes[indices[i]]->DofInFSet(2); //vz
+			}
+			else if(this->nodes[indices[i]]->GetApproximation()==SSAFSApproximationEnum || this->nodes[indices[i]]->GetApproximation()==HOFSApproximationEnum){
+				this->nodes[indices[i]]->DofInFSet(4); //vz 
+			}
+			else _error_("Flow equation approximation"<<EnumToStringx(this->nodes[indices[i]]->GetApproximation())<<" not supported yet");
+		}
+
 		XZvectorsToCoordinateSystem(&this->nodes[indices[i]]->coord_system[0][0],&xz_plane[0]);
 	}
@@ -2944,7 +2081,6 @@
 void  Penta::SetCurrentConfiguration(Elements* elementsin, Loads* loadsin, Nodes* nodesin, Materials* materialsin, Parameters* parametersin){
 
+	/*go into parameters and get the analysis_counter: */
 	int analysis_counter;
-
-	/*go into parameters and get the analysis_counter: */
 	parametersin->FindParam(&analysis_counter,AnalysisCounterEnum);
 
@@ -2952,82 +2088,17 @@
 	this->element_type=this->element_type_list[analysis_counter];
 
-	/*Pick up nodes */
-	if (this->hnodes[analysis_counter]) this->nodes=(Node**)this->hnodes[analysis_counter]->deliverp();
+	/*Pick up nodes*/
+	if(this->hnodes[analysis_counter]) this->nodes=(Node**)this->hnodes[analysis_counter]->deliverp();
 	else this->nodes=NULL;
-}
-/*}}}*/
-/*FUNCTION Penta::SetwiseNodeConnectivity{{{*/
-void Penta::SetwiseNodeConnectivity(int* pd_nz,int* po_nz,Node* node,bool* flags,int* flagsindices,int set1_enum,int set2_enum){
-
-	/*Intermediaries*/
-	const int numnodes = this->NumberofNodes();
-
-	/*Output */
-	int d_nz = 0;
-	int o_nz = 0;
-
-	/*Loop over all nodes*/
-	for(int i=0;i<numnodes;i++){
-
-		if(!flags[this->nodes[i]->Lid()]){
-
-			/*flag current node so that no other element processes it*/
-			flags[this->nodes[i]->Lid()]=true;
-
-			int counter=0;
-			while(flagsindices[counter]>=0) counter++;
-			flagsindices[counter]=this->nodes[i]->Lid();
-
-			/*if node is clone, we have an off-diagonal non-zero, else it is a diagonal non-zero*/
-			switch(set2_enum){
-				case FsetEnum:
-					if(nodes[i]->indexing.fsize){
-						if(this->nodes[i]->IsClone())
-						 o_nz += 1;
-						else
-						 d_nz += 1;
-					}
-					break;
-				case GsetEnum:
-					if(nodes[i]->indexing.gsize){
-						if(this->nodes[i]->IsClone())
-						 o_nz += 1;
-						else
-						 d_nz += 1;
-					}
-					break;
-				case SsetEnum:
-					if(nodes[i]->indexing.ssize){
-						if(this->nodes[i]->IsClone())
-						 o_nz += 1;
-						else
-						 d_nz += 1;
-					}
-					break;
-				default: _error_("not supported");
-			}
-		}
-	}
-
-	/*Special case: 2d/3d coupling, the node of this element might be connected
-	 *to the basal element*/
-	int analysis_type,approximation,numlayers;
-	parameters->FindParam(&analysis_type,AnalysisTypeEnum);
-	if(analysis_type==StressbalanceAnalysisEnum){
-		inputs->GetInputValue(&approximation,ApproximationEnum);
-		if(approximation==SSAHOApproximationEnum || approximation==SSAFSApproximationEnum){
-			parameters->FindParam(&numlayers,MeshNumberoflayersEnum);
-			o_nz += numlayers*3;
-			d_nz += numlayers*3;
-		}
-	}
-
-	/*Assign output pointers: */
-	*pd_nz=d_nz;
-	*po_nz=o_nz;
+
+}
+/*}}}*/
+/*FUNCTION Penta::SetTemporaryElementType{{{*/
+void Penta::SetTemporaryElementType(int element_type_in){
+	this->element_type=element_type_in;
 }
 /*}}}*/
 /*FUNCTION Penta::SpawnTria {{{*/
-Tria*  Penta::SpawnTria(int location){
+Tria*  Penta::SpawnTria(int index1,int index2,int index3){
 
 	int analysis_counter;
@@ -3039,13 +2110,11 @@
 	Tria* tria=new Tria();
 	tria->id=this->id;
-	tria->inputs=(Inputs*)this->inputs->SpawnTriaInputs(location);
+	tria->inputs=(Inputs*)this->inputs->SpawnTriaInputs(index1,index2,index3);
 	tria->parameters=this->parameters;
 	tria->element_type=P1Enum; //Only P1 CG for now (TO BE CHANGED)
-	this->SpawnTriaHook(dynamic_cast<ElementHook*>(tria),location);
+	this->SpawnTriaHook(dynamic_cast<ElementHook*>(tria),index1,index2,index3);
 
 	/*Spawn material*/
-	tria->material=(Material*)this->material->copy();
-	delete tria->material->inputs;
-	tria->material->inputs=(Inputs*)this->material->inputs->SpawnTriaInputs(location);
+	tria->material=(Material*)this->material->copy2(tria);
 
 	/*recover nodes, material and matpar: */
@@ -3055,4 +2124,32 @@
 
 	/*Return new Tria*/
+	return tria;
+}
+/*}}}*/
+/*FUNCTION Penta::SpawnBasalElement{{{*/
+Element*  Penta::SpawnBasalElement(void){
+
+	_assert_(this->IsOnBase());
+
+	this->InputDepthAverageAtBase(MaterialsRheologyBEnum,MaterialsRheologyBbarEnum);
+	if(this->material->IsDamage())this->InputDepthAverageAtBase(DamageDEnum,DamageDbarEnum);
+	if(this->inputs->GetInput(VxEnum)) this->InputDepthAverageAtBase(VxEnum,VxAverageEnum);
+	if(this->inputs->GetInput(VyEnum)) this->InputDepthAverageAtBase(VyEnum,VyAverageEnum);
+	Tria* tria=(Tria*)SpawnTria(0,1,2);
+	this->inputs->DeleteInput(MaterialsRheologyBbarEnum);
+	this->inputs->DeleteInput(DamageDbarEnum);
+	this->inputs->DeleteInput(VxAverageEnum);
+	this->inputs->DeleteInput(VyAverageEnum);
+
+	return tria;
+}
+/*}}}*/
+/*FUNCTION Penta::SpawnTopElement{{{*/
+Element*  Penta::SpawnTopElement(void){
+
+	_assert_(this->IsOnSurface());
+
+	Tria* tria=(Tria*)SpawnTria(3,4,5);
+
 	return tria;
 }
@@ -3115,10 +2212,10 @@
 
 	/*If on water, return 0: */
-	if(NoIceInElement())return 0;
+	if(!IsIceInElement())return 0;
 
 	/*Bail out if this element if:
 	 * -> Non SSA not on the surface
 	 * -> SSA (2d model) and not on bed) */
-	if ((approximation!=SSAApproximationEnum && !IsOnSurface()) || (approximation==SSAApproximationEnum && !IsOnBed())){
+	if ((approximation!=SSAApproximationEnum && !IsOnSurface()) || (approximation==SSAApproximationEnum && !IsOnBase())){
 		return 0;
 	}
@@ -3127,5 +2224,5 @@
 		/*This element should be collapsed into a tria element at its base. Create this tria element, 
 		 * and compute SurfaceArea*/
-		tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.
+		tria=(Tria*)SpawnTria(0,1,2);
 		S=tria->SurfaceArea();
 		delete tria->material; delete tria;
@@ -3134,33 +2231,9 @@
 	else{
 
-		tria=(Tria*)SpawnTria(1); //lower face is 0, upper face is 1.
+		tria=(Tria*)SpawnTria(3,4,5);
 		S=tria->SurfaceArea();
 		delete tria->material; delete tria;
 		return S;
 	}
-}
-/*}}}*/
-/*FUNCTION Penta::SurfaceNormal {{{*/
-void Penta::SurfaceNormal(IssmDouble* surface_normal, IssmDouble xyz_list[3][3]){
-
-	int    i;
-	IssmDouble v13[3],v23[3];
-	IssmDouble normal[3];
-	IssmDouble normal_norm;
-
-	for (i=0;i<3;i++){
-		v13[i]=xyz_list[0][i]-xyz_list[2][i];
-		v23[i]=xyz_list[1][i]-xyz_list[2][i];
-	}
-
-	normal[0]=v13[1]*v23[2]-v13[2]*v23[1];
-	normal[1]=v13[2]*v23[0]-v13[0]*v23[2];
-	normal[2]=v13[0]*v23[1]-v13[1]*v23[0];
-
-	normal_norm=sqrt( pow(normal[0],2)+pow(normal[1],2)+pow(normal[2],2) );
-
-	*(surface_normal)=normal[0]/normal_norm;
-	*(surface_normal+1)=normal[1]/normal_norm;
-	*(surface_normal+2)=normal[2]/normal_norm;
 }
 /*}}}*/
@@ -3183,5 +2256,5 @@
 
 	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
 
 	minx=xyz_list[0][0];
@@ -3272,4 +2345,20 @@
 			penta_node_ids[ 8]=iomodel->nodecounter+iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+2]+1;
 			break;
+		case P1xP3Enum:
+			numnodes         = 12;
+			penta_node_ids   = xNew<int>(numnodes);
+			penta_node_ids[ 0]=iomodel->nodecounter+iomodel->elements[6*index+0];
+			penta_node_ids[ 1]=iomodel->nodecounter+iomodel->elements[6*index+1];
+			penta_node_ids[ 2]=iomodel->nodecounter+iomodel->elements[6*index+2];
+			penta_node_ids[ 3]=iomodel->nodecounter+iomodel->elements[6*index+3];
+			penta_node_ids[ 4]=iomodel->nodecounter+iomodel->elements[6*index+4];
+			penta_node_ids[ 5]=iomodel->nodecounter+iomodel->elements[6*index+5];
+			penta_node_ids[ 6]=iomodel->nodecounter+iomodel->numberofvertices+2*iomodel->elementtoedgeconnectivity[9*index+0]+1;
+			penta_node_ids[ 7]=iomodel->nodecounter+iomodel->numberofvertices+2*iomodel->elementtoedgeconnectivity[9*index+1]+1;
+			penta_node_ids[ 8]=iomodel->nodecounter+iomodel->numberofvertices+2*iomodel->elementtoedgeconnectivity[9*index+2]+1;
+			penta_node_ids[ 9]=iomodel->nodecounter+iomodel->numberofvertices+2*iomodel->elementtoedgeconnectivity[9*index+0]+2;
+			penta_node_ids[10]=iomodel->nodecounter+iomodel->numberofvertices+2*iomodel->elementtoedgeconnectivity[9*index+1]+2;
+			penta_node_ids[11]=iomodel->nodecounter+iomodel->numberofvertices+2*iomodel->elementtoedgeconnectivity[9*index+2]+2;
+			break;
 		case P2xP1Enum:
 			numnodes         = 12;
@@ -3288,6 +2377,40 @@
 			penta_node_ids[11]=iomodel->nodecounter+iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+8]+1;
 			break;
+		case P2xP4Enum:
+			numnodes         = 30;
+			penta_node_ids   = xNew<int>(numnodes);
+			penta_node_ids[ 0]=iomodel->nodecounter+iomodel->elements[6*index+0]; /*Vertex 1*/
+			penta_node_ids[ 1]=iomodel->nodecounter+iomodel->elements[6*index+1]; /*Vertex 2*/
+			penta_node_ids[ 2]=iomodel->nodecounter+iomodel->elements[6*index+2]; /*Vertex 3*/
+			penta_node_ids[ 3]=iomodel->nodecounter+iomodel->elements[6*index+3]; /*Vertex 4*/
+			penta_node_ids[ 4]=iomodel->nodecounter+iomodel->elements[6*index+4]; /*Vertex 5*/
+			penta_node_ids[ 5]=iomodel->nodecounter+iomodel->elements[6*index+5]; /*Vertex 6*/
+			penta_node_ids[ 6]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->elementtoedgeconnectivity[9*index+0]+1; /*mid vertical edge 1*/
+			penta_node_ids[ 7]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->elementtoedgeconnectivity[9*index+1]+1; /*mid vertical edge 2*/
+			penta_node_ids[ 8]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->elementtoedgeconnectivity[9*index+2]+1; /*mid vertical edge 3*/
+			penta_node_ids[ 9]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->elementtoedgeconnectivity[9*index+3]+1; /*mid basal edge 1*/
+			penta_node_ids[10]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->elementtoedgeconnectivity[9*index+4]+1; /*mid basal edge 2*/
+			penta_node_ids[11]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->elementtoedgeconnectivity[9*index+5]+1; /*mid basal edge 3*/
+			penta_node_ids[12]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->elementtoedgeconnectivity[9*index+6]+1; /*mid top edge 1*/
+			penta_node_ids[13]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->elementtoedgeconnectivity[9*index+7]+1; /*mid top edge 2*/
+			penta_node_ids[14]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->elementtoedgeconnectivity[9*index+8]+1; /*mid top edge 3*/
+			penta_node_ids[15]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->elementtoedgeconnectivity[9*index+0]+2; /* 1/4 vertical edge 1*/
+			penta_node_ids[16]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->elementtoedgeconnectivity[9*index+1]+2; /* 1/4 vertical edge 2*/
+			penta_node_ids[17]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->elementtoedgeconnectivity[9*index+2]+2; /* 1/4 vertical edge 3*/
+			penta_node_ids[18]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->elementtoedgeconnectivity[9*index+0]+3; /* 2/4 vertical edge 1*/
+			penta_node_ids[19]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->elementtoedgeconnectivity[9*index+1]+3; /* 2/4 vertical edge 2*/
+			penta_node_ids[20]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->elementtoedgeconnectivity[9*index+2]+3; /* 2/4 vertical edge 3*/
+			penta_node_ids[21]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->numberofedges+3*iomodel->elementtofaceconnectivity[5*index+2]+1; /* 1/4 vertical face 1*/
+			penta_node_ids[22]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->numberofedges+3*iomodel->elementtofaceconnectivity[5*index+3]+1; /* 1/4 vertical face 2*/
+			penta_node_ids[23]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->numberofedges+3*iomodel->elementtofaceconnectivity[5*index+4]+1; /* 1/4 vertical face 3*/
+			penta_node_ids[24]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->numberofedges+3*iomodel->elementtofaceconnectivity[5*index+2]+2; /* 2/4 vertical face 1*/
+			penta_node_ids[25]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->numberofedges+3*iomodel->elementtofaceconnectivity[5*index+3]+2; /* 2/4 vertical face 2*/
+			penta_node_ids[26]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->numberofedges+3*iomodel->elementtofaceconnectivity[5*index+4]+2; /* 2/4 vertical face 3*/
+			penta_node_ids[27]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->numberofedges+3*iomodel->elementtofaceconnectivity[5*index+2]+3; /* 3/4 vertical face 1*/
+			penta_node_ids[28]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->numberofedges+3*iomodel->elementtofaceconnectivity[5*index+3]+3; /* 3/4 vertical face 2*/
+			penta_node_ids[29]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->numberofedges+3*iomodel->elementtofaceconnectivity[5*index+4]+3; /* 3/4 vertical face 3*/
+			break;
 		case P2Enum:
-			numnodes         = 15;
+			numnodes         = 18;
 			penta_node_ids   = xNew<int>(numnodes);
 			penta_node_ids[ 0]=iomodel->nodecounter+iomodel->elements[6*index+0];
@@ -3306,4 +2429,7 @@
 			penta_node_ids[13]=iomodel->nodecounter+iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+7]+1;
 			penta_node_ids[14]=iomodel->nodecounter+iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+8]+1;
+			penta_node_ids[15]=iomodel->nodecounter+iomodel->numberofvertices+iomodel->numberofedges+iomodel->elementtofaceconnectivity[5*index+2]+1;
+			penta_node_ids[16]=iomodel->nodecounter+iomodel->numberofvertices+iomodel->numberofedges+iomodel->elementtofaceconnectivity[5*index+3]+1;
+			penta_node_ids[17]=iomodel->nodecounter+iomodel->numberofvertices+iomodel->numberofedges+iomodel->elementtofaceconnectivity[5*index+4]+1;
 			break;
 		case P1P1Enum: case P1P1GLSEnum:
@@ -3343,5 +2469,5 @@
 			break;
 		case TaylorHoodEnum:
-			numnodes         = 21;
+			numnodes         = 24;
 			penta_node_ids   = xNew<int>(numnodes);
 			penta_node_ids[ 0]=iomodel->nodecounter+iomodel->elements[6*index+0];
@@ -3360,11 +2486,55 @@
 			penta_node_ids[13]=iomodel->nodecounter+iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+7]+1;
 			penta_node_ids[14]=iomodel->nodecounter+iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+8]+1;
-
-			penta_node_ids[15]=iomodel->nodecounter+iomodel->numberofvertices+iomodel->numberofedges+iomodel->elements[6*index+0];
-			penta_node_ids[16]=iomodel->nodecounter+iomodel->numberofvertices+iomodel->numberofedges+iomodel->elements[6*index+1];
-			penta_node_ids[17]=iomodel->nodecounter+iomodel->numberofvertices+iomodel->numberofedges+iomodel->elements[6*index+2];
-			penta_node_ids[18]=iomodel->nodecounter+iomodel->numberofvertices+iomodel->numberofedges+iomodel->elements[6*index+3];
-			penta_node_ids[19]=iomodel->nodecounter+iomodel->numberofvertices+iomodel->numberofedges+iomodel->elements[6*index+4];
-			penta_node_ids[20]=iomodel->nodecounter+iomodel->numberofvertices+iomodel->numberofedges+iomodel->elements[6*index+5];
+			penta_node_ids[15]=iomodel->nodecounter+iomodel->numberofvertices+iomodel->numberofedges+iomodel->elementtofaceconnectivity[5*index+2]+1;
+			penta_node_ids[16]=iomodel->nodecounter+iomodel->numberofvertices+iomodel->numberofedges+iomodel->elementtofaceconnectivity[5*index+3]+1;
+			penta_node_ids[17]=iomodel->nodecounter+iomodel->numberofvertices+iomodel->numberofedges+iomodel->elementtofaceconnectivity[5*index+4]+1;
+
+			penta_node_ids[18]=iomodel->nodecounter+iomodel->numberofvertices+iomodel->numberofedges+iomodel->numberoffaces+iomodel->elements[6*index+0];
+			penta_node_ids[19]=iomodel->nodecounter+iomodel->numberofvertices+iomodel->numberofedges+iomodel->numberoffaces+iomodel->elements[6*index+1];
+			penta_node_ids[20]=iomodel->nodecounter+iomodel->numberofvertices+iomodel->numberofedges+iomodel->numberoffaces+iomodel->elements[6*index+2];
+			penta_node_ids[21]=iomodel->nodecounter+iomodel->numberofvertices+iomodel->numberofedges+iomodel->numberoffaces+iomodel->elements[6*index+3];
+			penta_node_ids[22]=iomodel->nodecounter+iomodel->numberofvertices+iomodel->numberofedges+iomodel->numberoffaces+iomodel->elements[6*index+4];
+			penta_node_ids[23]=iomodel->nodecounter+iomodel->numberofvertices+iomodel->numberofedges+iomodel->numberoffaces+iomodel->elements[6*index+5];
+			break;
+		case OneLayerP4zEnum:
+			numnodes         = 30+6;
+			penta_node_ids   = xNew<int>(numnodes);
+			penta_node_ids[ 0]=iomodel->nodecounter+iomodel->elements[6*index+0]; /*Vertex 1*/
+			penta_node_ids[ 1]=iomodel->nodecounter+iomodel->elements[6*index+1]; /*Vertex 2*/
+			penta_node_ids[ 2]=iomodel->nodecounter+iomodel->elements[6*index+2]; /*Vertex 3*/
+			penta_node_ids[ 3]=iomodel->nodecounter+iomodel->elements[6*index+3]; /*Vertex 4*/
+			penta_node_ids[ 4]=iomodel->nodecounter+iomodel->elements[6*index+4]; /*Vertex 5*/
+			penta_node_ids[ 5]=iomodel->nodecounter+iomodel->elements[6*index+5]; /*Vertex 6*/
+			penta_node_ids[ 6]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->elementtoedgeconnectivity[9*index+0]+1; /*mid vertical edge 1*/
+			penta_node_ids[ 7]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->elementtoedgeconnectivity[9*index+1]+1; /*mid vertical edge 2*/
+			penta_node_ids[ 8]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->elementtoedgeconnectivity[9*index+2]+1; /*mid vertical edge 3*/
+			penta_node_ids[ 9]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->elementtoedgeconnectivity[9*index+3]+1; /*mid basal edge 1*/
+			penta_node_ids[10]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->elementtoedgeconnectivity[9*index+4]+1; /*mid basal edge 2*/
+			penta_node_ids[11]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->elementtoedgeconnectivity[9*index+5]+1; /*mid basal edge 3*/
+			penta_node_ids[12]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->elementtoedgeconnectivity[9*index+6]+1; /*mid top edge 1*/
+			penta_node_ids[13]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->elementtoedgeconnectivity[9*index+7]+1; /*mid top edge 2*/
+			penta_node_ids[14]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->elementtoedgeconnectivity[9*index+8]+1; /*mid top edge 3*/
+			penta_node_ids[15]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->elementtoedgeconnectivity[9*index+0]+2; /* 1/4 vertical edge 1*/
+			penta_node_ids[16]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->elementtoedgeconnectivity[9*index+1]+2; /* 1/4 vertical edge 2*/
+			penta_node_ids[17]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->elementtoedgeconnectivity[9*index+2]+2; /* 1/4 vertical edge 3*/
+			penta_node_ids[18]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->elementtoedgeconnectivity[9*index+0]+3; /* 2/4 vertical edge 1*/
+			penta_node_ids[19]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->elementtoedgeconnectivity[9*index+1]+3; /* 2/4 vertical edge 2*/
+			penta_node_ids[20]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->elementtoedgeconnectivity[9*index+2]+3; /* 2/4 vertical edge 3*/
+			penta_node_ids[21]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->numberofedges+3*iomodel->elementtofaceconnectivity[5*index+2]+1; /* 1/4 vertical face 1*/
+			penta_node_ids[22]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->numberofedges+3*iomodel->elementtofaceconnectivity[5*index+3]+1; /* 1/4 vertical face 2*/
+			penta_node_ids[23]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->numberofedges+3*iomodel->elementtofaceconnectivity[5*index+4]+1; /* 1/4 vertical face 3*/
+			penta_node_ids[24]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->numberofedges+3*iomodel->elementtofaceconnectivity[5*index+2]+2; /* 2/4 vertical face 1*/
+			penta_node_ids[25]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->numberofedges+3*iomodel->elementtofaceconnectivity[5*index+3]+2; /* 2/4 vertical face 2*/
+			penta_node_ids[26]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->numberofedges+3*iomodel->elementtofaceconnectivity[5*index+4]+2; /* 2/4 vertical face 3*/
+			penta_node_ids[27]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->numberofedges+3*iomodel->elementtofaceconnectivity[5*index+2]+3; /* 3/4 vertical face 1*/
+			penta_node_ids[28]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->numberofedges+3*iomodel->elementtofaceconnectivity[5*index+3]+3; /* 3/4 vertical face 2*/
+			penta_node_ids[29]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->numberofedges+3*iomodel->elementtofaceconnectivity[5*index+4]+3; /* 3/4 vertical face 3*/
+
+			penta_node_ids[30]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->numberofedges+3*iomodel->numberoffaces+iomodel->elements[6*index+0];
+			penta_node_ids[31]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->numberofedges+3*iomodel->numberoffaces+iomodel->elements[6*index+1];
+			penta_node_ids[32]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->numberofedges+3*iomodel->numberoffaces+iomodel->elements[6*index+2];
+			penta_node_ids[33]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->numberofedges+3*iomodel->numberoffaces+iomodel->elements[6*index+3];
+			penta_node_ids[34]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->numberofedges+3*iomodel->numberoffaces+iomodel->elements[6*index+4];
+			penta_node_ids[35]=iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->numberofedges+3*iomodel->numberoffaces+iomodel->elements[6*index+5];
 			break;
 		default:
@@ -3419,45 +2589,146 @@
 }
 /*}}}*/
-/*FUNCTION Penta::ViscousHeatingCreateInput {{{*/
-void Penta::ViscousHeatingCreateInput(void){
+/*FUNCTION Penta::UpdateConstraintsExtrudeFromBase{{{*/
+void  Penta::UpdateConstraintsExtrudeFromBase(void){
+
+	if(!IsOnBase()) return;
+
+	int        extrusioninput;
+	IssmDouble value,isonbase;
+
+	this->parameters->FindParam(&extrusioninput,InputToExtrudeEnum);
+	Input* input = inputs->GetInput(extrusioninput);      _assert_(extrusioninput);
+	Input* onbase = inputs->GetInput(MeshVertexonbaseEnum); _assert_(onbase);
+
+	GaussPenta* gauss=new GaussPenta();
+	for(int iv=0;iv<this->NumberofNodes();iv++){
+		gauss->GaussNode(this->element_type,iv);
+		onbase->GetInputValue(&isonbase,gauss);
+		if(isonbase==1.){
+			input->GetInputValue(&value,gauss);
+			this->nodes[iv]->ApplyConstraint(0,value);
+		}
+	}
+	delete gauss;
+
+}
+/*}}}*/
+/*FUNCTION Penta::UpdateConstraintsExtrudeFromTop{{{*/
+void  Penta::UpdateConstraintsExtrudeFromTop(void){
+
+	if(!IsOnSurface()) return;
+
+	int extrusioninput;
+	int indices[3]={3,4,5};
+	IssmDouble value;
+
+	this->parameters->FindParam(&extrusioninput,InputToExtrudeEnum);
+	Input* input = inputs->GetInput(extrusioninput); _assert_(extrusioninput);
+
+	GaussPenta* gauss=new GaussPenta();
+	for(int i=0;i<3;i++){
+		gauss->GaussNode(P1Enum,indices[i]);
+		input->GetInputValue(&value,gauss);
+		this->nodes[indices[i]]->ApplyConstraint(0,value);
+	}
+	delete gauss;
+
+}
+/*}}}*/
+/*FUNCTION Penta::ValueP1OnGauss{{{*/
+void Penta::ValueP1OnGauss(IssmDouble* pvalue,IssmDouble* values,Gauss* gauss){
+	PentaRef::GetInputValue(pvalue,values,gauss,P1Enum);
+}
+/*}}}*/
+/*FUNCTION Penta::ValueP1DerivativesOnGauss{{{*/
+void Penta::ValueP1DerivativesOnGauss(IssmDouble* dvalue,IssmDouble* values,IssmDouble* xyz_list,Gauss* gauss){
+	PentaRef::GetInputDerivativeValue(dvalue,values,xyz_list,gauss);
+}
+/*}}}*/
+/*FUNCTION Penta::VertexConnectivity{{{*/
+int Penta::VertexConnectivity(int vertexindex){
+	_assert_(this->vertices);
+	return this->vertices[vertexindex]->Connectivity();
+}
+/*}}}*/
+/*FUNCTION Penta::VerticalSegmentIndices{{{*/
+void Penta::VerticalSegmentIndices(int** pindices,int* pnumseg){
+
+	/*output*/
+	int *indices = xNew<int>(3*2);
+	indices[0*2 + 0] = 0; indices[0*2 + 1] = 3;
+	indices[1*2 + 0] = 1; indices[1*2 + 1] = 4;
+	indices[2*2 + 0] = 2; indices[2*2 + 1] = 5;
+
+	/*Assign output pointers*/
+	*pindices = indices;
+	*pnumseg  = 3;
+}
+/*}}}*/
+/*FUNCTION Penta::ViscousHeating{{{*/
+void Penta::ViscousHeating(IssmDouble* pphi,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input){
 
 	/*Intermediaries*/
 	IssmDouble phi;
 	IssmDouble viscosity;
-	IssmDouble xyz_list[NUMVERTICES][3];
 	IssmDouble epsilon[6];
-	IssmDouble viscousheating[NUMVERTICES];
-	IssmDouble thickness;
+
+	_assert_(gauss->Enum()==GaussPentaEnum);
+	this->StrainRateFS(&epsilon[0],xyz_list,(GaussPenta*)gauss,vx_input,vy_input,vz_input);
+	this->ViscosityFS(&viscosity,3,xyz_list,(GaussPenta*)gauss,vx_input,vy_input,vz_input);
+	GetPhi(&phi,&epsilon[0],viscosity);
+
+	/*Assign output pointer*/
+	*pphi = phi;
+}
+/*}}}*/
+/*FUNCTION Penta::VelocityInterpolation{{{*/
+int Penta::VelocityInterpolation(void){
+	return PentaRef::VelocityInterpolation();
+}
+/*}}}*/
+/*FUNCTION Penta::PressureInterpolation{{{*/
+int Penta::PressureInterpolation(void){
+	return PentaRef::PressureInterpolation();
+}
+/*}}}*/
+/*FUNCTION Penta::IsZeroLevelset{{{*/
+bool Penta::IsZeroLevelset(int levelset_enum){
+
+	bool        iszerols;
+	IssmDouble  ls[NUMVERTICES];
 
 	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);
-	Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);
-	Input* vz_input=inputs->GetInput(VzEnum); _assert_(vz_input);
-	Input* thickness_input=inputs->GetInput(ThicknessEnum); _assert_(thickness_input);
-
-	/*loop over vertices: */
-	GaussPenta* gauss=new GaussPenta();
-	for (int iv=0;iv<NUMVERTICES;iv++){
-		gauss->GaussVertex(iv);
-
-		thickness_input->GetInputValue(&thickness,gauss);
-
-		this->GetStrainRate3d(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input,vz_input);
-		material->GetViscosity3dFS(&viscosity,&epsilon[0]);
-		GetPhi(&phi, &epsilon[0], viscosity);
-
-		viscousheating[iv]=phi*thickness;
-	}
-
-	/*Create PentaVertex input, which will hold the basal friction:*/
-	this->inputs->AddInput(new PentaInput(ViscousHeatingEnum,&viscousheating[0],P1Enum));
-
-	/*Clean up and return*/
-	delete gauss;
-}
-/*}}}*/
-
-#ifdef _HAVE_RESPONSES_
+	GetInputListOnVertices(&ls[0],levelset_enum);
+
+	/*If the level set has always same sign, there is no ice front here*/
+	iszerols = false;
+	if(IsIceInElement()){
+		if(ls[0]*ls[1]<0. || ls[0]*ls[2]<0. || (ls[0]*ls[1]*ls[2]==0. && ls[0]*ls[1]+ls[0]*ls[2]+ls[1]*ls[2]<=0.)){
+			iszerols = true;
+		}
+	}
+	return iszerols;
+}
+/*}}}*/
+bool  Penta::IsIcefront(void){/*{{{*/
+
+	bool isicefront;
+	int i,nrice;
+   IssmDouble ls[NUMVERTICES];
+
+	/*Retrieve all inputs and parameters*/
+	GetInputListOnVertices(&ls[0],MaskIceLevelsetEnum);
+
+	/* If only one vertex has ice, there is an ice front here */
+	isicefront=false;
+	if(IsIceInElement()){
+		nrice=0;       
+		for(i=0;i<NUMVERTICES2D;i++)
+			if(ls[i]<0.) nrice++;
+		if(nrice==1) isicefront= true;
+	}
+	return isicefront;
+}/*}}}*/
 /*FUNCTION Penta::AverageOntoPartition {{{*/
 void  Penta::AverageOntoPartition(Vector<IssmDouble>* partition_contributions,Vector<IssmDouble>* partition_areas,IssmDouble* vertex_response,IssmDouble* qmu_part){
@@ -3472,7 +2743,7 @@
 	IssmDouble xyz_list[NUMVERTICES][3];
 
-	if(NoIceInElement())return 0;
-
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	if(!IsIceInElement())return 0;
+
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
 
 	/*First calculate the area of the base (cross section triangle)
@@ -3496,9 +2767,9 @@
 	IssmDouble xyz_list[NUMVERTICES][3];
 
-	if(NoIceInElement() || IsFloating() || !IsOnBed())return 0;
+	if(!IsIceInElement() || IsFloating() || !IsOnBase())return 0;
 
 	rho_ice=matpar->GetRhoIce();
 	rho_water=matpar->GetRhoWater();
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
 
 	/*First calculate the area of the base (cross section triangle)
@@ -3509,9 +2780,9 @@
 	/*Now get the average height above floatation*/
 	Input* surface_input    = inputs->GetInput(SurfaceEnum);    _assert_(surface_input);
-	Input* bed_input        = inputs->GetInput(BedEnum);        _assert_(bed_input);
-	Input* bathymetry_input = inputs->GetInput(BathymetryEnum); _assert_(bathymetry_input);
+	Input* base_input        = inputs->GetInput(BaseEnum);        _assert_(base_input);
+	Input* bed_input = inputs->GetInput(BedEnum); _assert_(bed_input);
 	surface_input->GetInputAverage(&surface);
-	bed_input->GetInputAverage(&bed);
-	bathymetry_input->GetInputAverage(&bathymetry);
+	base_input->GetInputAverage(&bed);
+	bed_input->GetInputAverage(&bathymetry);
 
 	/*Return: */
@@ -3564,5 +2835,5 @@
 	IssmDouble mass_flux=0;
 
-	if(!IsOnBed()) return mass_flux;
+	if(!IsOnBase()) return mass_flux;
 
 	/*Depth Averaging Vx and Vy*/
@@ -3571,5 +2842,5 @@
 
 	/*Spawn Tria element from the base of the Penta: */
-	Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.
+	Tria* tria=(Tria*)SpawnTria(0,1,2);
 	mass_flux=tria->MassFlux(segment);
 	delete tria->material; delete tria;
@@ -3588,5 +2859,5 @@
 	IssmDouble mass_flux=0;
 
-	if(!IsOnBed()) return mass_flux;
+	if(!IsOnBase()) return mass_flux;
 
 	/*Depth Averaging Vx and Vy*/
@@ -3595,5 +2866,5 @@
 
 	/*Spawn Tria element from the base of the Penta: */
-	Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.
+	Tria* tria=(Tria*)SpawnTria(0,1,2);
 	mass_flux=tria->MassFlux(x1,y1,x2,y2,segment_id);
 	delete tria->material; delete tria;
@@ -3719,7 +2990,7 @@
 	rho_ice=matpar->GetRhoIce();
 
-	if(NoIceInElement() || !IsOnSurface()) return 0.;
-
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	if(!IsIceInElement() || !IsOnSurface()) return 0.;
+
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
 
 	/*First calculate the area of the base (cross section triangle)
@@ -3738,5 +3009,4 @@
 }
 /*}}}*/
-#endif
 
 #ifdef _HAVE_GIA_
@@ -3748,1374 +3018,4 @@
 #endif
 
-#ifdef _HAVE_THERMAL_
-/*FUNCTION Penta::CreateKMatrixEnthalpy {{{*/
-ElementMatrix* Penta::CreateKMatrixEnthalpy(void){
-
-	/*compute all stiffness matrices for this element*/
-	ElementMatrix* Ke1=CreateKMatrixEnthalpyVolume();
-	ElementMatrix* Ke2=CreateKMatrixEnthalpyShelf();
-	ElementMatrix* Ke =new ElementMatrix(Ke1,Ke2);
-
-	/*clean-up and return*/
-	delete Ke1;
-	delete Ke2;
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Penta::CreateKMatrixEnthalpyVolume {{{*/
-ElementMatrix* Penta::CreateKMatrixEnthalpyVolume(void){
-
-	/*Constants*/
-	const int    numdof=NDOF1*NUMVERTICES;
-
-	/*Intermediaries */
-	int        stabilization;
-	int        i,j;
-	IssmDouble Jdet,u,v,w,um,vm,wm;
-	IssmDouble h,hx,hy,hz,vx,vy,vz,vel;
-	IssmDouble gravity,rho_ice,rho_water;
-	IssmDouble epsvel=2.220446049250313e-16;
-	IssmDouble heatcapacity,thermalconductivity,dt;
-	IssmDouble pressure,enthalpy;
-	IssmDouble latentheat,kappa;
-	IssmDouble tau_parameter,diameter;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble B_conduct[3][numdof];
-	IssmDouble B_advec[3][numdof];
-	IssmDouble Bprime_advec[3][numdof];
-	IssmDouble L[numdof];
-	IssmDouble dbasis[3][6];
-	IssmDouble D_scalar_conduct,D_scalar_advec;
-	IssmDouble D_scalar_trans,D_scalar_stab;
-	IssmDouble D[3][3];
-	IssmDouble K[3][3]={0.0};
-	GaussPenta *gauss=NULL;
-
-	/*Initialize Element matrix*/
-	ElementMatrix* Ke=new ElementMatrix(nodes,NUMVERTICES,this->parameters,NoneApproximationEnum);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	rho_water=matpar->GetRhoWater();
-	rho_ice=matpar->GetRhoIce();
-	gravity=matpar->GetG();
-	heatcapacity=matpar->GetHeatCapacity();
-	latentheat=matpar->GetLatentHeat();
-	thermalconductivity=matpar->GetThermalConductivity();
-	this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);
-	this->parameters->FindParam(&stabilization,ThermalStabilizationEnum);
-	Input* pressure_input=inputs->GetInput(PressureEnum);      _assert_(pressure_input);
-	Input* enthalpy_input=inputs->GetInput(EnthalpyPicardEnum);_assert_(enthalpy_input); //for this iteration of the step
-	Input* vx_input=inputs->GetInput(VxEnum);                  _assert_(vx_input);
-	Input* vy_input=inputs->GetInput(VyEnum);                  _assert_(vy_input);
-	Input* vz_input=inputs->GetInput(VzEnum);                  _assert_(vz_input);
-	Input* vxm_input=inputs->GetInput(VxMeshEnum);             _assert_(vxm_input);
-	Input* vym_input=inputs->GetInput(VyMeshEnum);             _assert_(vym_input);
-	Input* vzm_input=inputs->GetInput(VzMeshEnum);             _assert_(vzm_input);
-	if (stabilization==2) diameter=MinEdgeLength(xyz_list);
-
-	/* Start  looping on the number of gaussian points: */
-	gauss=new GaussPenta(2,2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-
-		/*Conduction: */  
-		GetBConduct(&B_conduct[0][0],&xyz_list[0][0],gauss); 
-
-		enthalpy_input->GetInputValue(&enthalpy, gauss);
-		pressure_input->GetInputValue(&pressure, gauss);
-		kappa=matpar->GetEnthalpyDiffusionParameter(enthalpy,pressure); _assert_(kappa>0.);
-		D_scalar_conduct=gauss->weight*Jdet*kappa/rho_ice;
-		if(reCast<bool,IssmDouble>(dt)) D_scalar_conduct=D_scalar_conduct*dt;
-
-		D[0][0]=D_scalar_conduct; D[0][1]=0; D[0][2]=0;
-		D[1][0]=0; D[1][1]=D_scalar_conduct; D[1][2]=0;
-		D[2][0]=0; D[2][1]=0; D[2][2]=D_scalar_conduct;
-
-		TripleMultiply(&B_conduct[0][0],3,numdof,1,
-					&D[0][0],3,3,0,
-					&B_conduct[0][0],3,numdof,0,
-					&Ke->values[0],1);
-
-		/*Advection: */
-		GetBAdvec(&B_advec[0][0],&xyz_list[0][0],gauss); 
-		GetBprimeAdvec(&Bprime_advec[0][0],&xyz_list[0][0],gauss); 
-
-		vx_input->GetInputValue(&u, gauss); vxm_input->GetInputValue(&um,gauss); vx=u-um; 
-		vy_input->GetInputValue(&v, gauss); vym_input->GetInputValue(&vm,gauss); vy=v-vm; 
-		vz_input->GetInputValue(&w, gauss); vzm_input->GetInputValue(&wm,gauss); vz=w-wm;
-
-		D_scalar_advec=gauss->weight*Jdet;
-		if(reCast<bool,IssmDouble>(dt)) D_scalar_advec=D_scalar_advec*dt;
-
-		D[0][0]=D_scalar_advec*vx;D[0][1]=0;                D[0][2]=0;
-		D[1][0]=0;                D[1][1]=D_scalar_advec*vy;D[1][2]=0;
-		D[2][0]=0;                D[2][1]=0;                D[2][2]=D_scalar_advec*vz;
-
-		TripleMultiply(&B_advec[0][0],3,numdof,1,
-					&D[0][0],3,3,0,
-					&Bprime_advec[0][0],3,numdof,0,
-					&Ke->values[0],1);
-
-		/*Transient: */
-		if(reCast<bool,IssmDouble>(dt)){
-			GetNodalFunctionsP1(&L[0], gauss);
-			D_scalar_trans=gauss->weight*Jdet;
-
-			TripleMultiply(&L[0],numdof,1,0,
-						&D_scalar_trans,1,1,0,
-						&L[0],1,numdof,0,
-						&Ke->values[0],1);
-		}
-
-		/*Artificial diffusivity*/
-		if(stabilization==1){
-			/*Build K: */
-			GetElementSizes(&hx,&hy,&hz);
-			vel=sqrt(vx*vx + vy*vy + vz*vz)+1.e-14;
-			h=sqrt( pow(hx*vx/vel,2) + pow(hy*vy/vel,2) + pow(hz*vz/vel,2));
-
-			K[0][0]=h/(2*vel)*vx*vx;  K[0][1]=h/(2*vel)*vx*vy; K[0][2]=h/(2*vel)*vx*vz;
-			K[1][0]=h/(2*vel)*vy*vx;  K[1][1]=h/(2*vel)*vy*vy; K[1][2]=h/(2*vel)*vy*vz;
-			K[2][0]=h/(2*vel)*vz*vx;  K[2][1]=h/(2*vel)*vz*vy; K[2][2]=h/(2*vel)*vz*vz;
-
-			D_scalar_stab=gauss->weight*Jdet;
-			if(reCast<bool,IssmDouble>(dt)) D_scalar_stab=D_scalar_stab*dt;
-			for(i=0;i<3;i++) for(j=0;j<3;j++) K[i][j] = D_scalar_stab*K[i][j];
-
-			GetBprimeAdvec(&Bprime_advec[0][0],&xyz_list[0][0],gauss); 
-
-			TripleMultiply(&Bprime_advec[0][0],3,numdof,1,
-						&K[0][0],3,3,0,
-						&Bprime_advec[0][0],3,numdof,0,
-						&Ke->values[0],1);
-		}
-		else if(stabilization==2){
-			GetNodalFunctionsP1Derivatives(&dbasis[0][0],&xyz_list[0][0], gauss);
-			tau_parameter=GetStabilizationParameter(u-um,v-vm,w-wm,diameter,kappa);
-
-			for(i=0;i<numdof;i++){
-				for(j=0;j<numdof;j++){
-					Ke->values[i*numdof+j]+=tau_parameter*D_scalar_advec*
-					  ((u-um)*dbasis[0][i]+(v-vm)*dbasis[1][i]+(w-wm)*dbasis[2][i])*((u-um)*dbasis[0][j]+(v-vm)*dbasis[1][j]+(w-wm)*dbasis[2][j]);
-				}
-			}
-			if(reCast<bool,IssmDouble>(dt)){
-				for(i=0;i<numdof;i++){
-					for(j=0;j<numdof;j++){
-						Ke->values[i*numdof+j]+=tau_parameter*D_scalar_trans*L[j]*((u-um)*dbasis[0][i]+(v-vm)*dbasis[1][i]+(w-wm)*dbasis[2][i]);
-					}
-				}
-			}
-		}
-	}
-
-	/*Clean up and return*/
-	delete gauss;
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Penta::CreateKMatrixEnthalpyShelf {{{*/
-ElementMatrix* Penta::CreateKMatrixEnthalpyShelf(void){
-
-	/*Constants*/
-	const int    numdof=NDOF1*NUMVERTICES;
-
-	/*Intermediaries */
-	int        i,j;
-	IssmDouble mixed_layer_capacity,thermal_exchange_velocity;
-	IssmDouble rho_ice,rho_water,heatcapacity;
-	IssmDouble Jdet2d,dt;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble xyz_list_tria[NUMVERTICES2D][3];
-	IssmDouble basis[NUMVERTICES];
-	IssmDouble D_scalar;
-	GaussPenta *gauss=NULL;
-
-	/*Initialize Element matrix and return if necessary*/
-	if (!IsOnBed() || !IsFloating()) return NULL;
-	ElementMatrix* Ke=new ElementMatrix(nodes,NUMVERTICES,this->parameters,NoneApproximationEnum);
-
-	/*Retrieve all inputs and parameters*/
-	this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);
-	mixed_layer_capacity=matpar->GetMixedLayerCapacity();
-	thermal_exchange_velocity=matpar->GetThermalExchangeVelocity();
-	rho_water=matpar->GetRhoWater();
-	rho_ice=matpar->GetRhoIce();
-	heatcapacity=matpar->GetHeatCapacity();
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	for(i=0;i<NUMVERTICES2D;i++) for(j=0;j<3;j++) xyz_list_tria[i][j]=xyz_list[i][j];
-
-	/* Start looping on the number of gauss (nodes on the bedrock) */
-	gauss=new GaussPenta(0,1,2,2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetTriaJacobianDeterminant(&Jdet2d, &xyz_list_tria[0][0], gauss);
-		GetNodalFunctionsP1(&basis[0], gauss);
-
-		D_scalar=gauss->weight*Jdet2d*rho_water*mixed_layer_capacity*thermal_exchange_velocity/(rho_ice*heatcapacity);
-		if(reCast<bool,IssmDouble>(dt)) D_scalar=dt*D_scalar;
-
-		TripleMultiply(&basis[0],numdof,1,0,
-					&D_scalar,1,1,0,
-					&basis[0],1,numdof,0,
-					&Ke->values[0],1);
-	}
-
-	/*Clean up and return*/
-	delete gauss;
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Penta::CreateKMatrixMelting {{{*/
-ElementMatrix* Penta::CreateKMatrixMelting(void){
-
-	if (!IsOnBed()) return NULL;
-
-	Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.
-	ElementMatrix* Ke=tria->CreateKMatrixMelting();
-
-	delete tria->material; delete tria;
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Penta::CreateKMatrixThermal {{{*/
-ElementMatrix* Penta::CreateKMatrixThermal(void){
-
-	/*compute all stiffness matrices for this element*/
-	ElementMatrix* Ke1=CreateKMatrixThermalVolume();
-	ElementMatrix* Ke2=CreateKMatrixThermalShelf();
-	ElementMatrix* Ke =new ElementMatrix(Ke1,Ke2);
-
-	/*clean-up and return*/
-	delete Ke1;
-	delete Ke2;
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Penta::CreateKMatrixThermalVolume {{{*/
-ElementMatrix* Penta::CreateKMatrixThermalVolume(void){
-
-	/*Constants*/
-	const int    numdof=NDOF1*NUMVERTICES;
-
-	/*Intermediaries */
-	int        stabilization;
-	int        i,j;
-	IssmDouble Jdet,u,v,w,um,vm,wm,vel;
-	IssmDouble h,hx,hy,hz,vx,vy,vz;
-	IssmDouble gravity,rho_ice,rho_water,kappa;
-	IssmDouble heatcapacity,thermalconductivity,dt;
-	IssmDouble tau_parameter,diameter;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble B_conduct[3][numdof];
-	IssmDouble B_advec[3][numdof];
-	IssmDouble Bprime_advec[3][numdof];
-	IssmDouble L[numdof];
-	IssmDouble dbasis[3][6];
-	IssmDouble D_scalar_conduct,D_scalar_advec;
-	IssmDouble D_scalar_trans,D_scalar_stab;
-	IssmDouble D[3][3];
-	IssmDouble K[3][3]={0.0};
-	GaussPenta *gauss=NULL;
-
-	/*Initialize Element matrix*/
-	ElementMatrix* Ke=new ElementMatrix(nodes,NUMVERTICES,this->parameters,NoneApproximationEnum);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	rho_water=matpar->GetRhoWater();
-	rho_ice=matpar->GetRhoIce();
-	gravity=matpar->GetG();
-	heatcapacity=matpar->GetHeatCapacity();
-	thermalconductivity=matpar->GetThermalConductivity();
-	kappa=thermalconductivity/(rho_ice*heatcapacity);
-	this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);
-	this->parameters->FindParam(&stabilization,ThermalStabilizationEnum);
-	Input* vx_input=inputs->GetInput(VxEnum);      _assert_(vx_input);
-	Input* vy_input=inputs->GetInput(VyEnum);      _assert_(vy_input);
-	Input* vz_input=inputs->GetInput(VzEnum);      _assert_(vz_input);
-	Input* vxm_input=inputs->GetInput(VxMeshEnum); _assert_(vxm_input);
-	Input* vym_input=inputs->GetInput(VyMeshEnum); _assert_(vym_input);
-	Input* vzm_input=inputs->GetInput(VzMeshEnum); _assert_(vzm_input);
-	if (stabilization==2) diameter=MinEdgeLength(xyz_list);
-
-	/* Start  looping on the number of gaussian points: */
-	gauss=new GaussPenta(2,2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-
-		/*Conduction: */
-
-		GetBConduct(&B_conduct[0][0],&xyz_list[0][0],gauss); 
-
-		D_scalar_conduct=gauss->weight*Jdet*kappa;
-		if(reCast<bool,IssmDouble>(dt)) D_scalar_conduct=D_scalar_conduct*dt;
-
-		D[0][0]=D_scalar_conduct; D[0][1]=0; D[0][2]=0;
-		D[1][0]=0; D[1][1]=D_scalar_conduct; D[1][2]=0;
-		D[2][0]=0; D[2][1]=0; D[2][2]=D_scalar_conduct;
-
-		TripleMultiply(&B_conduct[0][0],3,numdof,1,
-					&D[0][0],3,3,0,
-					&B_conduct[0][0],3,numdof,0,
-					&Ke->values[0],1);
-
-		/*Advection: */
-		GetBAdvec(&B_advec[0][0],&xyz_list[0][0],gauss); 
-		GetBprimeAdvec(&Bprime_advec[0][0],&xyz_list[0][0],gauss); 
-
-		vx_input->GetInputValue(&u, gauss); vxm_input->GetInputValue(&um,gauss); vx=u-um;
-		vy_input->GetInputValue(&v, gauss); vym_input->GetInputValue(&vm,gauss); vy=v-vm;
-		vz_input->GetInputValue(&w, gauss); vzm_input->GetInputValue(&wm,gauss); vz=w-wm;
-
-		D_scalar_advec=gauss->weight*Jdet;
-		if(reCast<bool,IssmDouble>(dt)) D_scalar_advec=D_scalar_advec*dt;
-
-		D[0][0]=D_scalar_advec*vx;    D[0][1]=0;                    D[0][2]=0;
-		D[1][0]=0;                    D[1][1]=D_scalar_advec*vy;    D[1][2]=0;
-		D[2][0]=0;                    D[2][1]=0;                    D[2][2]=D_scalar_advec*vz;
-
-		TripleMultiply(&B_advec[0][0],3,numdof,1,
-					&D[0][0],3,3,0,
-					&Bprime_advec[0][0],3,numdof,0,
-					&Ke->values[0],1);
-
-		/*Transient: */
-		if(reCast<bool,IssmDouble>(dt)){
-			GetNodalFunctionsP1(&L[0], gauss);
-			D_scalar_trans=gauss->weight*Jdet;
-
-			TripleMultiply(&L[0],numdof,1,0,
-						&D_scalar_trans,1,1,0,
-						&L[0],1,numdof,0,
-						&Ke->values[0],1);
-		}
-
-		/*Artifficial diffusivity*/
-		if(stabilization==1){
-			/*Build K: */
-			GetElementSizes(&hx,&hy,&hz);
-			vel=sqrt(vx*vx + vy*vy + vz*vz)+1.e-14;
-			h=sqrt( pow(hx*vx/vel,2) + pow(hy*vy/vel,2) + pow(hz*vz/vel,2));
-
-			K[0][0]=h/(2*vel)*fabs(vx*vx);  K[0][1]=h/(2*vel)*fabs(vx*vy); K[0][2]=h/(2*vel)*fabs(vx*vz);
-			K[1][0]=h/(2*vel)*fabs(vy*vx);  K[1][1]=h/(2*vel)*fabs(vy*vy); K[1][2]=h/(2*vel)*fabs(vy*vz);
-			K[2][0]=h/(2*vel)*fabs(vz*vx);  K[2][1]=h/(2*vel)*fabs(vz*vy); K[2][2]=h/(2*vel)*fabs(vz*vz);
-
-			D_scalar_stab=gauss->weight*Jdet;
-			if(reCast<bool,IssmDouble>(dt)) D_scalar_stab=D_scalar_stab*dt;
-			for(i=0;i<3;i++) for(j=0;j<3;j++) K[i][j] = D_scalar_stab*K[i][j];
-
-			GetBprimeAdvec(&Bprime_advec[0][0],&xyz_list[0][0],gauss); 
-
-			TripleMultiply(&Bprime_advec[0][0],3,numdof,1,
-						&K[0][0],3,3,0,
-						&Bprime_advec[0][0],3,numdof,0,
-						&Ke->values[0],1);
-		}
-		else if(stabilization==2){
-			GetNodalFunctionsP1Derivatives(&dbasis[0][0],&xyz_list[0][0], gauss);
-			tau_parameter=GetStabilizationParameter(u-um,v-vm,w-wm,diameter,kappa);
-
-			for(i=0;i<numdof;i++){
-				for(j=0;j<numdof;j++){
-					Ke->values[i*numdof+j]+=tau_parameter*D_scalar_advec*
-					  ((u-um)*dbasis[0][i]+(v-vm)*dbasis[1][i]+(w-wm)*dbasis[2][i])*((u-um)*dbasis[0][j]+(v-vm)*dbasis[1][j]+(w-wm)*dbasis[2][j]);
-				}
-			}
-			if(reCast<bool,IssmDouble>(dt)){
-				for(i=0;i<numdof;i++){
-					for(j=0;j<numdof;j++){
-						Ke->values[i*numdof+j]+=tau_parameter*D_scalar_trans*L[j]*((u-um)*dbasis[0][i]+(v-vm)*dbasis[1][i]+(w-wm)*dbasis[2][i]);
-					}
-				}
-			}
-		}
-	}
-
-	/*Clean up and return*/
-	delete gauss;
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Penta::CreateKMatrixThermalShelf {{{*/
-ElementMatrix* Penta::CreateKMatrixThermalShelf(void){
-
-	/*Constants*/
-	const int    numdof=NDOF1*NUMVERTICES;
-
-	/*Intermediaries */
-	int       i,j;
-	IssmDouble mixed_layer_capacity,thermal_exchange_velocity;
-	IssmDouble rho_ice,rho_water,heatcapacity;
-	IssmDouble Jdet2d,dt;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble xyz_list_tria[NUMVERTICES2D][3];
-	IssmDouble basis[NUMVERTICES];
-	IssmDouble D_scalar;
-	GaussPenta *gauss=NULL;
-
-	/*Initialize Element matrix and return if necessary*/
-	if (!IsOnBed() || !IsFloating()) return NULL;
-	ElementMatrix* Ke=new ElementMatrix(nodes,NUMVERTICES,this->parameters,NoneApproximationEnum);
-
-	/*Retrieve all inputs and parameters*/
-	this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);
-	mixed_layer_capacity=matpar->GetMixedLayerCapacity();
-	thermal_exchange_velocity=matpar->GetThermalExchangeVelocity();
-	rho_water=matpar->GetRhoWater();
-	rho_ice=matpar->GetRhoIce();
-	heatcapacity=matpar->GetHeatCapacity();
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	for(i=0;i<NUMVERTICES2D;i++) for(j=0;j<3;j++) xyz_list_tria[i][j]=xyz_list[i][j];
-
-	/* Start looping on the number of gauss (nodes on the bedrock) */
-	gauss=new GaussPenta(0,1,2,2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetTriaJacobianDeterminant(&Jdet2d, &xyz_list_tria[0][0], gauss);
-		GetNodalFunctionsP1(&basis[0], gauss);
-
-		D_scalar=gauss->weight*Jdet2d*rho_water*mixed_layer_capacity*thermal_exchange_velocity/(heatcapacity*rho_ice);
-		if(reCast<bool,IssmDouble>(dt)) D_scalar=dt*D_scalar;
-
-		TripleMultiply(&basis[0],numdof,1,0,
-					&D_scalar,1,1,0,
-					&basis[0],1,numdof,0,
-					&Ke->values[0],1);
-	}
-
-	/*Clean up and return*/
-	delete gauss;
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Penta::CreatePVectorEnthalpy {{{*/
-ElementVector* Penta::CreatePVectorEnthalpy(void){
-
-	/*compute all load vectors for this element*/
-	ElementVector* pe1=CreatePVectorEnthalpyVolume();
-	ElementVector* pe2=CreatePVectorEnthalpySheet();
-	ElementVector* pe3=CreatePVectorEnthalpyShelf();
-	ElementVector* pe =new ElementVector(pe1,pe2,pe3);
-
-	/*clean-up and return*/
-	delete pe1;
-	delete pe2;
-	delete pe3;
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Penta::CreatePVectorEnthalpyVolume {{{*/
-ElementVector* Penta::CreatePVectorEnthalpyVolume(void){
-
-	/*Constants*/
-	const int  numdof=NUMVERTICES*NDOF1;
-
-	/*Intermediaries*/
-	int        i;
-	int        stabilization;
-	IssmDouble Jdet,phi,dt;
-	IssmDouble rho_ice,heatcapacity;
-	IssmDouble thermalconductivity,kappa;
-	IssmDouble viscosity,pressure;
-	IssmDouble enthalpy,enthalpypicard;
-	IssmDouble tau_parameter,diameter;
-	IssmDouble u,v,w;
-	IssmDouble scalar_def,scalar_transient;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble L[numdof];
-	IssmDouble dbasis[3][6];
-	IssmDouble epsilon[6];
-	GaussPenta *gauss=NULL;
-
-	/*Initialize Element vector*/
-	ElementVector* pe=new ElementVector(nodes,NUMVERTICES,this->parameters);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	rho_ice=matpar->GetRhoIce();
-	heatcapacity=matpar->GetHeatCapacity();
-	thermalconductivity=matpar->GetThermalConductivity();
-	this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);
-	this->parameters->FindParam(&stabilization,ThermalStabilizationEnum);
-	Input* vx_input=inputs->GetInput(VxEnum);                                  _assert_(vx_input);
-	Input* vy_input=inputs->GetInput(VyEnum);                                  _assert_(vy_input);
-	Input* vz_input=inputs->GetInput(VzEnum);                                  _assert_(vz_input);
-	Input* pressure_input=inputs->GetInput(PressureEnum);                      _assert_(pressure_input);
-	Input* enthalpy_input=NULL; 
-	Input* enthalpypicard_input=NULL; 
-	if(reCast<bool,IssmDouble>(dt)){
-		enthalpy_input=inputs->GetInput(EnthalpyEnum); _assert_(enthalpy_input);
-	}
-	if (stabilization==2){
-		diameter=MinEdgeLength(xyz_list);
-		enthalpypicard_input=inputs->GetInput(EnthalpyPicardEnum); _assert_(enthalpypicard_input);
-	}
-
-	/* Start  looping on the number of gaussian points: */
-	gauss=new GaussPenta(2,3);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		GetNodalFunctionsP1(&L[0], gauss);
-
-		this->GetStrainRate3d(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input,vz_input);
-		material->GetViscosity3dFS(&viscosity,&epsilon[0]);
-		GetPhi(&phi, &epsilon[0], viscosity);
-
-		scalar_def=phi/rho_ice*Jdet*gauss->weight;
-		if(reCast<bool,IssmDouble>(dt)) scalar_def=scalar_def*dt;
-		
-		/*TODO: add -beta*laplace T_m(p)*/
-		for(i=0;i<NUMVERTICES;i++)  pe->values[i]+=scalar_def*L[i];
-
-		/* Build transient now */
-		if(reCast<bool,IssmDouble>(dt)){
-			enthalpy_input->GetInputValue(&enthalpy, gauss);
-			scalar_transient=enthalpy*Jdet*gauss->weight;
-			for(i=0;i<NUMVERTICES;i++)  pe->values[i]+=scalar_transient*L[i];
-		}
-
-		if(stabilization==2){
-			GetNodalFunctionsP1Derivatives(&dbasis[0][0],&xyz_list[0][0], gauss);
-
-			vx_input->GetInputValue(&u, gauss);
-			vy_input->GetInputValue(&v, gauss);
-			vz_input->GetInputValue(&w, gauss);
-			pressure_input->GetInputValue(&pressure, gauss);
-			enthalpypicard_input->GetInputValue(&enthalpypicard, gauss);
-			kappa=matpar->GetEnthalpyDiffusionParameter(enthalpy,pressure);
-			kappa/=rho_ice;
-			tau_parameter=GetStabilizationParameter(u,v,w,diameter,kappa); 
-
-			for(i=0;i<NUMVERTICES;i++)  pe->values[i]+=tau_parameter*scalar_def*(u*dbasis[0][i]+v*dbasis[1][i]+w*dbasis[2][i]);
-			if(reCast<bool,IssmDouble>(dt)){
-				for(i=0;i<NUMVERTICES;i++)  pe->values[i]+=tau_parameter*scalar_transient*(u*dbasis[0][i]+v*dbasis[1][i]+w*dbasis[2][i]);
-			}
-		}
-	}
-
-	/*Clean up and return*/
-	delete gauss;
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Penta::CreatePVectorEnthalpyShelf {{{*/
-ElementVector* Penta::CreatePVectorEnthalpyShelf(void){
-
-	/*Constants*/
-	const int  numdof=NUMVERTICES*NDOF1;
-
-	/*Intermediaries */
-	int        i,j;
-	IssmDouble Jdet2d;
-	IssmDouble heatcapacity,h_pmp;
-	IssmDouble mixed_layer_capacity,thermal_exchange_velocity;
-	IssmDouble rho_ice,rho_water,pressure,dt,scalar_ocean;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble xyz_list_tria[NUMVERTICES2D][3];
-	IssmDouble basis[NUMVERTICES];
-	GaussPenta* gauss=NULL;
-
-	/* Ice/ocean heat exchange flux on ice shelf base */
-	if (!IsOnBed() || !IsFloating()) return NULL;
-
-	/*Initialize Element vector*/
-	ElementVector* pe=new ElementVector(nodes,NUMVERTICES,this->parameters);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	for(i=0;i<NUMVERTICES2D;i++) for(j=0;j<3;j++) xyz_list_tria[i][j]=xyz_list[i][j];
-	mixed_layer_capacity=matpar->GetMixedLayerCapacity();
-	thermal_exchange_velocity=matpar->GetThermalExchangeVelocity();
-	rho_water=matpar->GetRhoWater();
-	rho_ice=matpar->GetRhoIce();
-	heatcapacity=matpar->GetHeatCapacity();
-	this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);
-	Input* pressure_input=inputs->GetInput(PressureEnum); _assert_(pressure_input);
-
-	/* Start looping on the number of gauss 2d (nodes on the bedrock) */
-	gauss=new GaussPenta(0,1,2,2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetTriaJacobianDeterminant(&Jdet2d, &xyz_list_tria[0][0], gauss);
-		GetNodalFunctionsP1(&basis[0], gauss);
-
-		pressure_input->GetInputValue(&pressure,gauss);
-		h_pmp=matpar->PureIceEnthalpy(pressure);
-
-		scalar_ocean=gauss->weight*Jdet2d*rho_water*mixed_layer_capacity*thermal_exchange_velocity*(h_pmp)/(rho_ice*heatcapacity);
-		if(reCast<bool,IssmDouble>(dt)) scalar_ocean=dt*scalar_ocean;
-
-		for(i=0;i<numdof;i++) pe->values[i]+=scalar_ocean*basis[i];
-	}
-
-	/*Clean up and return*/
-	delete gauss;
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Penta::CreatePVectorEnthalpySheet {{{*/
-ElementVector* Penta::CreatePVectorEnthalpySheet(void){
-
-	/*Constants*/
-	const int  numdof=NUMVERTICES*NDOF1;
-
-	/*Intermediaries */
-	int        i,j;
-	int        analysis_type;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble xyz_list_tria[NUMVERTICES2D][3]={0.0};
-	IssmDouble Jdet2d,dt;
-	IssmDouble rho_ice,heatcapacity;
-	IssmDouble geothermalflux_value, heatflux_value;
-	IssmDouble basalfriction,alpha2,vx,vy,vz;
-	IssmDouble scalar,enthalpy,enthalpyup;
-	IssmDouble pressure,pressureup;
-	IssmDouble watercolumn;
-	IssmDouble basis[NUMVERTICES];
-	Friction*  friction=NULL;
-	GaussPenta* gauss=NULL;
-	GaussPenta* gaussup=NULL;
-
-	/* Geothermal flux on ice sheet base and basal friction */
-	if (!IsOnBed() || IsFloating()) return NULL;
-
-	/*Initialize Element vector*/
-	ElementVector* pe=new ElementVector(nodes,NUMVERTICES,this->parameters);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	for(i=0;i<NUMVERTICES2D;i++) for(j=0;j<3;j++) xyz_list_tria[i][j]=xyz_list[i][j];
-	parameters->FindParam(&analysis_type,AnalysisTypeEnum);
-	rho_ice=matpar->GetRhoIce();
-	heatcapacity=matpar->GetHeatCapacity();
-	this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);
-	Input* vx_input=inputs->GetInput(VxEnum);                         _assert_(vx_input);
-	Input* vy_input=inputs->GetInput(VyEnum);                         _assert_(vy_input);
-	Input* vz_input=inputs->GetInput(VzEnum);                         _assert_(vz_input);
-	Input* enthalpy_input=inputs->GetInput(EnthalpyEnum);             _assert_(enthalpy_input);
-	Input* pressure_input=inputs->GetInput(PressureEnum);             _assert_(pressure_input);
-	Input* geothermalflux_input=inputs->GetInput(BasalforcingsGeothermalfluxEnum); _assert_(geothermalflux_input);
-	Input* watercolumn_input=inputs->GetInput(WatercolumnEnum); _assert_(watercolumn_input);
-
-	/*Build friction element, needed later: */
-	friction=new Friction("3d",inputs,matpar,analysis_type);
-
-	/* Start looping on the number of gauss 2d (nodes on the bedrock) */
-	gauss=new GaussPenta(0,1,2,2);
-	gaussup=new GaussPenta(3,4,5,2);
-
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-		gaussup->GaussPoint(ig);
-
-		GetTriaJacobianDeterminant(&Jdet2d, &xyz_list_tria[0][0], gauss);
-		GetNodalFunctionsP1(&basis[0], gauss);
-
-		enthalpy_input->GetInputValue(&enthalpy,gauss);
-		pressure_input->GetInputValue(&pressure,gauss);
-		watercolumn_input->GetInputValue(&watercolumn,gauss);
-
-		if((watercolumn<=0.) && (enthalpy<matpar->PureIceEnthalpy(pressure))){
-			/* the above check is equivalent to 
-			 NOT ((watercolumn>0.) AND (enthalpy<PIE)) AND (enthalpy<PIE)*/
-			geothermalflux_input->GetInputValue(&geothermalflux_value,gauss);
-
-			friction->GetAlpha2(&alpha2,gauss,VxEnum,VyEnum,VzEnum);
-			vx_input->GetInputValue(&vx,gauss);
-			vy_input->GetInputValue(&vy,gauss);
-			vz_input->GetInputValue(&vz,gauss);
-			basalfriction=alpha2*(pow(vx,2.0)+pow(vy,2.0)+pow(vz,2.0));
-
-			heatflux_value=(basalfriction+geothermalflux_value)/(rho_ice);
-			scalar=gauss->weight*Jdet2d*heatflux_value;
-			if(reCast<bool,IssmDouble>(dt)) scalar=dt*scalar;
-			for(i=0;i<numdof;i++) pe->values[i]+=scalar*basis[i];
-		}
-		else if(enthalpy>=matpar->PureIceEnthalpy(pressure)){
-			/* check positive thickness of temperate basal ice layer */
-			enthalpy_input->GetInputValue(&enthalpyup,gaussup);
-			pressure_input->GetInputValue(&pressureup,gaussup);
-			if(enthalpyup>=matpar->PureIceEnthalpy(pressureup)){
-				// TODO: temperate ice has positive thickness: grad enthalpy*n=0.
-			}
-			else{
-				// only base temperate, set Dirichlet BCs in Penta::UpdateBasalConstraintsEnthalpy()
-			}
-		}
-		else {
-			// base cold, but watercolumn positive. Set base to h_pmp.
-		}
-	}
-
-	/*Clean up and return*/
-	delete gauss;
-	delete gaussup;
-	delete friction;
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Penta::CreatePVectorMelting {{{*/
-ElementVector* Penta::CreatePVectorMelting(void){
-	return NULL;
-}
-/*}}}*/
-/*FUNCTION Penta::CreatePVectorThermal {{{*/
-ElementVector* Penta::CreatePVectorThermal(void){
-
-	/*compute all load vectors for this element*/
-	ElementVector* pe1=CreatePVectorThermalVolume();
-	ElementVector* pe2=CreatePVectorThermalSheet();
-	ElementVector* pe3=CreatePVectorThermalShelf();
-	ElementVector* pe =new ElementVector(pe1,pe2,pe3);
-
-	/*clean-up and return*/
-	delete pe1;
-	delete pe2;
-	delete pe3;
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Penta::CreatePVectorThermalVolume {{{*/
-ElementVector* Penta::CreatePVectorThermalVolume(void){
-
-	/*Constants*/
-	const int  numdof=NUMVERTICES*NDOF1;
-
-	/*Intermediaries*/
-	int        i;
-	int        stabilization;
-	IssmDouble Jdet,phi,dt;
-	IssmDouble rho_ice,heatcapacity;
-	IssmDouble thermalconductivity,kappa;
-	IssmDouble viscosity,temperature;
-	IssmDouble tau_parameter,diameter;
-	IssmDouble u,v,w;
-	IssmDouble scalar_def,scalar_transient;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble L[numdof];
-	IssmDouble dbasis[3][6];
-	IssmDouble epsilon[6];
-	GaussPenta *gauss=NULL;
-
-	/*Initialize Element vector*/
-	ElementVector* pe=new ElementVector(nodes,NUMVERTICES,this->parameters);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	rho_ice=matpar->GetRhoIce();
-	heatcapacity=matpar->GetHeatCapacity();
-	thermalconductivity=matpar->GetThermalConductivity();
-	kappa=thermalconductivity/(rho_ice*heatcapacity);
-	this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);
-	this->parameters->FindParam(&stabilization,ThermalStabilizationEnum);
-	Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);
-	Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);
-	Input* vz_input=inputs->GetInput(VzEnum); _assert_(vz_input);
-	Input* temperature_input=NULL;
-	if(reCast<bool,IssmDouble>(dt)) temperature_input=inputs->GetInput(TemperatureEnum); _assert_(inputs);
-	if(stabilization==2) diameter=MinEdgeLength(xyz_list);
-
-	/* Start  looping on the number of gaussian points: */
-	gauss=new GaussPenta(2,3);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		GetNodalFunctionsP1(&L[0], gauss);
-
-		this->GetStrainRate3d(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input,vz_input);
-		material->GetViscosity3dFS(&viscosity,&epsilon[0]);
-		GetPhi(&phi, &epsilon[0], viscosity);
-
-		scalar_def=phi/(rho_ice*heatcapacity)*Jdet*gauss->weight;
-		if(reCast<bool,IssmDouble>(dt)) scalar_def=scalar_def*dt;
-
-		for(i=0;i<NUMVERTICES;i++)  pe->values[i]+=scalar_def*L[i];
-
-		/* Build transient now */
-		if(reCast<bool,IssmDouble>(dt)){
-			temperature_input->GetInputValue(&temperature, gauss);
-			scalar_transient=temperature*Jdet*gauss->weight;
-			for(i=0;i<NUMVERTICES;i++)  pe->values[i]+=scalar_transient*L[i];
-		}
-
-		if(stabilization==2){
-			GetNodalFunctionsP1Derivatives(&dbasis[0][0],&xyz_list[0][0], gauss);
-
-			vx_input->GetInputValue(&u, gauss);
-			vy_input->GetInputValue(&v, gauss);
-			vz_input->GetInputValue(&w, gauss);
-
-			tau_parameter=GetStabilizationParameter(u,v,w,diameter,kappa);
-
-			for(i=0;i<NUMVERTICES;i++)  pe->values[i]+=tau_parameter*scalar_def*(u*dbasis[0][i]+v*dbasis[1][i]+w*dbasis[2][i]);
-			if(reCast<bool,IssmDouble>(dt)){
-				for(i=0;i<NUMVERTICES;i++)  pe->values[i]+=tau_parameter*scalar_transient*(u*dbasis[0][i]+v*dbasis[1][i]+w*dbasis[2][i]);
-			}
-		}
-	}
-
-	/*Clean up and return*/
-	delete gauss;
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Penta::CreatePVectorThermalShelf {{{*/
-ElementVector* Penta::CreatePVectorThermalShelf(void){
-
-	/*Constants*/
-	const int  numdof=NUMVERTICES*NDOF1;
-
-	/*Intermediaries */
-	int        i,j;
-	IssmDouble Jdet2d;
-	IssmDouble mixed_layer_capacity,thermal_exchange_velocity;
-	IssmDouble rho_ice,rho_water,pressure,dt,scalar_ocean;
-	IssmDouble heatcapacity,t_pmp;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble xyz_list_tria[NUMVERTICES2D][3];
-	IssmDouble basis[NUMVERTICES];
-	GaussPenta* gauss=NULL;
-
-	/* Ice/ocean heat exchange flux on ice shelf base */
-	if (!IsOnBed() || !IsFloating()) return NULL;
-
-	/*Initialize Element vector*/
-	ElementVector* pe=new ElementVector(nodes,NUMVERTICES,this->parameters);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	for(i=0;i<NUMVERTICES2D;i++) for(j=0;j<3;j++) xyz_list_tria[i][j]=xyz_list[i][j];
-	mixed_layer_capacity=matpar->GetMixedLayerCapacity();
-	thermal_exchange_velocity=matpar->GetThermalExchangeVelocity();
-	rho_water=matpar->GetRhoWater();
-	rho_ice=matpar->GetRhoIce();
-	heatcapacity=matpar->GetHeatCapacity();
-	this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);
-	Input* pressure_input=inputs->GetInput(PressureEnum); _assert_(pressure_input);
-
-	/* Start looping on the number of gauss 2d (nodes on the bedrock) */
-	gauss=new GaussPenta(0,1,2,2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetTriaJacobianDeterminant(&Jdet2d, &xyz_list_tria[0][0], gauss);
-		GetNodalFunctionsP1(&basis[0], gauss);
-
-		pressure_input->GetInputValue(&pressure,gauss);
-		t_pmp=matpar->TMeltingPoint(pressure);
-
-		scalar_ocean=gauss->weight*Jdet2d*rho_water*mixed_layer_capacity*thermal_exchange_velocity*(t_pmp)/(heatcapacity*rho_ice);
-		if(reCast<bool,IssmDouble>(dt)) scalar_ocean=dt*scalar_ocean;
-
-		for(i=0;i<numdof;i++) pe->values[i]+=scalar_ocean*basis[i];
-	}
-
-	/*Clean up and return*/
-	delete gauss;
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Penta::CreatePVectorThermalSheet {{{*/
-ElementVector* Penta::CreatePVectorThermalSheet(void){
-
-	/*Constants*/
-	const int  numdof=NUMVERTICES*NDOF1;
-
-	/*Intermediaries */
-	int         i,j;
-	int         analysis_type;
-	IssmDouble  xyz_list[NUMVERTICES][3];
-	IssmDouble  xyz_list_tria[NUMVERTICES2D][3]={0.0};
-	IssmDouble  Jdet2d,dt;
-	IssmDouble  rho_ice,heatcapacity,geothermalflux_value;
-	IssmDouble  basalfriction,alpha2,vx,vy;
-	IssmDouble  basis[NUMVERTICES];
-	IssmDouble  scalar;
-	Friction*   friction=NULL;
-	GaussPenta* gauss=NULL;
-
-	/* Geothermal flux on ice sheet base and basal friction */
-	if (!IsOnBed() || IsFloating()) return NULL;
-
-	/*Initialize Element vector*/
-	ElementVector* pe=new ElementVector(nodes,NUMVERTICES,this->parameters);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	for(i=0;i<NUMVERTICES2D;i++) for(j=0;j<3;j++) xyz_list_tria[i][j]=xyz_list[i][j];
-	parameters->FindParam(&analysis_type,AnalysisTypeEnum);
-	rho_ice=matpar->GetRhoIce();
-	heatcapacity=matpar->GetHeatCapacity();
-	this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);
-	Input* vx_input=inputs->GetInput(VxEnum);                         _assert_(vx_input);
-	Input* vy_input=inputs->GetInput(VyEnum);                         _assert_(vy_input);
-	Input* vz_input=inputs->GetInput(VzEnum);                         _assert_(vz_input);
-	Input* geothermalflux_input=inputs->GetInput(BasalforcingsGeothermalfluxEnum); _assert_(geothermalflux_input);
-
-	/*Build frictoin element, needed later: */
-	friction=new Friction("3d",inputs,matpar,analysis_type);
-
-	/* Start looping on the number of gauss 2d (nodes on the bedrock) */
-	gauss=new GaussPenta(0,1,2,2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetTriaJacobianDeterminant(&Jdet2d, &xyz_list_tria[0][0], gauss);
-		GetNodalFunctionsP1(&basis[0], gauss);
-
-			geothermalflux_input->GetInputValue(&geothermalflux_value,gauss);
-			friction->GetAlpha2(&alpha2,gauss,VxEnum,VyEnum,VzEnum);
-			vx_input->GetInputValue(&vx,gauss);
-			vy_input->GetInputValue(&vy,gauss);
-			basalfriction=alpha2*(pow(vx,2.0)+pow(vy,2.0));
-
-			scalar=gauss->weight*Jdet2d*(basalfriction+geothermalflux_value)/(heatcapacity*rho_ice);
-			if(reCast<bool,IssmDouble>(dt)) scalar=dt*scalar;
-
-			for(i=0;i<numdof;i++) pe->values[i]+=scalar*basis[i];
-	}
-
-	/*Clean up and return*/
-	delete gauss;
-	delete friction;
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Penta::InputUpdateFromSolutionThermal {{{*/
-void  Penta::InputUpdateFromSolutionThermal(IssmDouble* solution){
-
-	const int    numdof=NDOF1*NUMVERTICES;
-
-	bool        converged;
-	int         i,rheology_law;
-	IssmDouble  xyz_list[NUMVERTICES][3];
-	IssmDouble  values[numdof];
-	IssmDouble  B[numdof];
-	IssmDouble  B_average,s_average;
-	int        *doflist = NULL;
-	bool        hack    = false;
-
-	/*Get dof list: */
-	GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
-
-	/*Use the dof list to index into the solution vector: */
-	for(i=0;i<numdof;i++){
-		values[i]=solution[doflist[i]];
-
-		/*Check solution*/
-		if(xIsNan<IssmDouble>(values[i])) _error_("NaN found in solution vector");
-		//if(values[i]<0)      _printf_("temperature < 0°K found in solution vector\n");
-		//if(values[i]>275)    _printf_("temperature > 275°K found in solution vector (Paterson's rheology associated is negative)\n");
-	}
-
-	if(hack){
-		/*Force temperature between [Tpmp-50 Tpmp] to disable penalties*/
-		IssmDouble pressure[numdof];
-		GetInputListOnVertices(&pressure[0],PressureEnum);
-		for(i=0;i<numdof;i++){
-			if(values[i]>matpar->TMeltingPoint(pressure[i]))     values[i]=matpar->TMeltingPoint(pressure[i]);
-			if(values[i]<matpar->TMeltingPoint(pressure[i])-50.) values[i]=matpar->TMeltingPoint(pressure[i])-50.;
-		}
-	}
-
-
-	/*Get all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	Input* surface_input=inputs->GetInput(SurfaceEnum); _assert_(surface_input);
-
-	this->inputs->GetInputValue(&converged,ConvergedEnum);
-	if(converged){
-		this->inputs->AddInput(new PentaInput(TemperatureEnum,values,P1Enum));
-
-		/*Update Rheology only if converged (we must make sure that the temperature is below melting point
-		 * otherwise the rheology could be negative*/
-		this->parameters->FindParam(&rheology_law,MaterialsRheologyLawEnum);
-		switch(rheology_law){
-			case NoneEnum:
-				/*Do nothing: B is not temperature dependent*/
-				break;
-			case PatersonEnum:
-				B_average=Paterson((values[0]+values[1]+values[2]+values[3]+values[4]+values[5])/6.0);
-				for(i=0;i<numdof;i++) B[i]=B_average;
-				this->material->inputs->AddInput(new PentaInput(MaterialsRheologyBEnum,B,P1Enum));
-				break;
-			case ArrheniusEnum:
-				surface_input->GetInputAverage(&s_average);
-				B_average=Arrhenius((values[0]+values[1]+values[2]+values[3]+values[4]+values[5])/6.0,
-							s_average-((xyz_list[0][2]+xyz_list[1][2]+xyz_list[2][2]+xyz_list[3][2]+xyz_list[4][2]+xyz_list[5][2])/6.0),
-							material->GetN());
-				for(i=0;i<numdof;i++) B[i]=B_average;
-				this->material->inputs->AddInput(new PentaInput(MaterialsRheologyBEnum,B,P1Enum));
-				break;
-			default:
-				_error_("Rheology law " << EnumToStringx(rheology_law) << " not supported yet");
-
-		}
-	}
-	else{
-		this->inputs->AddInput(new PentaInput(TemperaturePicardEnum,values,P1Enum));
-	}
-
-	/*Free ressources:*/
-	xDelete<int>(doflist);
-}
-/*}}}*/
-/*FUNCTION Penta::InputUpdateFromSolutionEnthalpy {{{*/
-void  Penta::InputUpdateFromSolutionEnthalpy(IssmDouble* solution){
-
-	const int    numdof=NDOF1*NUMVERTICES;
-
-	bool       converged=false;
-	int        i,rheology_law;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble values[numdof];
-	IssmDouble pressure[NUMVERTICES];
-	IssmDouble temperatures[numdof];
-	IssmDouble waterfraction[numdof];
-	IssmDouble B[numdof];
-	IssmDouble B_average,s_average;
-	int*       doflist=NULL;
-
-	/*Get dof list: */
-	GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
-
-	/*Use the dof list to index into the solution vector: */
-	for(i=0;i<numdof;i++){
-		values[i]=solution[doflist[i]];
-
-		/*Check solution*/
-		if(xIsNan<IssmDouble>(values[i])) _error_("NaN found in solution vector");
-	}
-
-	/*Get all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	GetInputListOnVertices(&pressure[0],PressureEnum);
-	Input* surface_input=inputs->GetInput(SurfaceEnum); _assert_(surface_input);
-
-	this->inputs->GetInputValue(&converged,ConvergedEnum);
-	if(converged){
-		/*Convert enthalpy into temperature and water fraction*/
-		for(i=0;i<numdof;i++){
-			matpar->EnthalpyToThermal(&temperatures[i],&waterfraction[i],values[i],pressure[i]);
-			if(waterfraction[i]<0) _error_("Negative water fraction found in solution vector");
-			//if(waterfraction[i]>1) _error_("Water fraction >1 found in solution vector");
-		}
-
-		this->inputs->AddInput(new PentaInput(EnthalpyEnum,values,P1Enum));
-		this->inputs->AddInput(new PentaInput(WaterfractionEnum,waterfraction,P1Enum));
-		this->inputs->AddInput(new PentaInput(TemperatureEnum,temperatures,P1Enum));
-
-		/*Update Rheology only if converged (we must make sure that the temperature is below melting point
-		 * otherwise the rheology could be negative*/
-		this->parameters->FindParam(&rheology_law,MaterialsRheologyLawEnum);
-		switch(rheology_law){
-			case NoneEnum:
-				/*Do nothing: B is not temperature dependent*/
-				break;
-			case PatersonEnum:
-				B_average=Paterson((temperatures[0]+temperatures[1]+temperatures[2]+temperatures[3]+temperatures[4]+temperatures[5])/6.0);
-				for(i=0;i<numdof;i++) B[i]=B_average;
-				this->material->inputs->AddInput(new PentaInput(MaterialsRheologyBEnum,B,P1Enum));
-				break;
-			case ArrheniusEnum:
-				surface_input->GetInputAverage(&s_average);
-				B_average=Arrhenius((temperatures[0]+temperatures[1]+temperatures[2]+temperatures[3]+temperatures[4]+temperatures[5])/6.0,
-							s_average-((xyz_list[0][2]+xyz_list[1][2]+xyz_list[2][2]+xyz_list[3][2]+xyz_list[4][2]+xyz_list[5][2])/6.0),
-							material->GetN());
-				for(i=0;i<numdof;i++) B[i]=B_average;
-				this->material->inputs->AddInput(new PentaInput(MaterialsRheologyBEnum,B,P1Enum));
-				break;
-			case LliboutryDuvalEnum:
-				B_average=LliboutryDuval((values[0]+values[1]+values[2]+values[3]+values[4]+values[5])/6.0,
-																 (pressure[0]+pressure[1]+pressure[2]+pressure[3]+pressure[4]+pressure[5])/6.0,
-																 material->GetN(), 
-																 matpar->GetBeta(), matpar->GetReferenceTemperature(), matpar->GetHeatCapacity(), matpar->GetLatentHeat());
-				for(i=0;i<numdof;i++) B[i]=B_average;
-				this->material->inputs->AddInput(new PentaInput(MaterialsRheologyBEnum,B,P1Enum));
-				break;
-			default:
-				_error_("Rheology law " << EnumToStringx(rheology_law) << " not supported yet");
-		}
-	}
-	else{
-		this->inputs->AddInput(new PentaInput(EnthalpyPicardEnum,values,P1Enum));
-	}
-
-	/*Free ressources:*/
-	xDelete<int>(doflist);
-}
-/*}}}*/
-/*FUNCTION Penta::UpdateBasalConstraintsEnthalpy{{{*/
-void  Penta::UpdateBasalConstraintsEnthalpy(void){
-
-	/*Intermediary*/
-	bool        isenthalpy,isdynamicbasalspc,setspc;
-	int         numindices, numindicesup;
-	IssmDouble  pressure, pressureup;
-	IssmDouble  h_pmp, enthalpy, enthalpyup;
-	IssmDouble  watercolumn;
-	int        *indices = NULL, *indicesup = NULL;
-
-	/* Only update Constraints at the base of grounded ice*/
-	if(!IsOnBed() || IsFloating()) return;
-
-	/*Check wether dynamic basal boundary conditions are activated */
-	parameters->FindParam(&isenthalpy,ThermalIsenthalpyEnum);
-	if(!isenthalpy) return;
-	parameters->FindParam(&isdynamicbasalspc,ThermalIsdynamicbasalspcEnum);
-	if(!isdynamicbasalspc) return;
-
-	/*Fetch indices of basal & surface nodes for this finite element*/
-	BasalNodeIndices(&numindices,&indices,this->element_type);
-	SurfaceNodeIndices(&numindicesup,&indicesup,this->element_type);
-	_assert_(numindices==numindicesup);
-
-	/*Get parameters and inputs: */
-	Input* pressure_input=inputs->GetInput(PressureEnum); _assert_(pressure_input);
-	Input* enthalpy_input=inputs->GetInput(EnthalpyEnum); _assert_(enthalpy_input);
-	Input* watercolumn_input=inputs->GetInput(WatercolumnEnum); //_assert_(watercolumn_input);
-
-	/*if there is a temperate layer of zero thickness, set spc enthalpy=h_pmp at that node*/
-	GaussPenta* gauss=new GaussPenta();
-	GaussPenta* gaussup=new GaussPenta();
-	for(int i=0;i<numindices;i++){
-		gauss->GaussNode(this->element_type,indices[i]);
-		gaussup->GaussNode(this->element_type,indicesup[i]); 
-
-		/*Check wether there is a temperate layer at the base or not */
-		/*check if node is temperate, if not, continue*/
-		enthalpy_input->GetInputValue(&enthalpy, gauss);
-		pressure_input->GetInputValue(&pressure, gauss);
-		watercolumn_input->GetInputValue(&watercolumn,gauss);
-		setspc = false;
-		if (enthalpy>=matpar->PureIceEnthalpy(pressure)){		
-			/*check if upper node is temperate, too. 
-				if yes, then we have a temperate layer of positive thickness and reset the spc. 
-				if not, apply dirichlet BC.*/
-			enthalpy_input->GetInputValue(&enthalpyup, gaussup);
-			pressure_input->GetInputValue(&pressureup, gaussup);    
-			setspc=((enthalpyup<matpar->PureIceEnthalpy(pressureup)) && (watercolumn>=0.))?true:false;
-		}
-
-		if (setspc) {
-			/*Calculate enthalpy at pressure melting point */
-			h_pmp=matpar->PureIceEnthalpy(pressure);
-			/*Apply Dirichlet condition (dof = 0 here, since there is only one degree of freedom per node)*/
-			nodes[indices[i]]->ApplyConstraint(1,h_pmp);
-		}
-		else {
-			/*remove spc*/
-			nodes[indices[i]]->DofInFSet(0);
-		}
-	}
-
-	/*Free ressources:*/
-	xDelete<int>(indices);
-	xDelete<int>(indicesup);
-	delete gauss;
-	delete gaussup;
-}
-/*}}}*/
-/*FUNCTION Penta::ComputeBasalMeltingrate{{{*/
-void Penta::ComputeBasalMeltingrate(void){
-	/*Calculate the basal melt rates of the enthalpy model after Aschwanden 2012*/
-	/* melting rate is positive when melting, negative when refreezing*/
-
-	/* Intermediaries */
-	bool        isenthalpy, checkpositivethickness, istemperatelayer;
-	int         i,j,analysis_type;
-	IssmDouble  xyz_list[NUMVERTICES][3];
-	IssmDouble  xyz_list_tria[NUMVERTICES2D][3];
-	IssmDouble  heatflux,kappa;
-	IssmDouble  vec_heatflux[3];
-	IssmDouble  normal_base[3], d1enthalpy[3];
-	IssmDouble  basalmeltingrate[NUMVERTICES], watercolumn[NUMVERTICES];
-	IssmDouble  enthalpy[NUMVERTICES],pressure[NUMVERTICES];
-	IssmDouble  temperature, waterfraction;
-	IssmDouble  latentheat, rho_ice;
-	IssmDouble  basalfriction, alpha2;
-	IssmDouble  vx[NUMVERTICES],vy[NUMVERTICES],vz[NUMVERTICES];
-	IssmDouble  geothermalflux[NUMVERTICES];
-	IssmDouble  dt, yts;
-	IssmDouble  melting_overshoot,meltingrate_enthalpy;
-	IssmDouble  lambda,heating;
-	Friction   *friction  = NULL;
-
-	/* Only compute melt rates at the base of grounded ice*/
-	if(!IsOnBed() || IsFloating()) return;
-
-	/*Check wether enthalpy is activated*/
-	parameters->FindParam(&isenthalpy,ThermalIsenthalpyEnum);
-	if(!isenthalpy) return;
-
-	/*Fetch parameters and inputs */
-	latentheat=matpar->GetLatentHeat();
-	rho_ice=matpar->GetRhoIce();
-	GetInputListOnVertices(&vx[0],VxEnum);
-	GetInputListOnVertices(&vy[0],VyEnum);
-	GetInputListOnVertices(&vz[0],VzEnum);
-	GetInputListOnVertices(&enthalpy[0],EnthalpyEnum);
-	GetInputListOnVertices(&pressure[0],PressureEnum);
-	GetInputListOnVertices(&watercolumn[0],WatercolumnEnum);
-	GetInputListOnVertices(&basalmeltingrate[0],BasalforcingsMeltingRateEnum);
-	GetInputListOnVertices(&geothermalflux[0],BasalforcingsGeothermalfluxEnum);
-	Input* enthalpy_input=inputs->GetInput(EnthalpyEnum); _assert_(enthalpy_input);
-
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	for(i=0;i<NUMVERTICES2D;i++) for(j=0;j<3;j++) xyz_list_tria[i][j]=xyz_list[i][j];
-
-	/*Build friction element, needed later: */
-	parameters->FindParam(&analysis_type,AnalysisTypeEnum);
-	friction=new Friction("3d",inputs,matpar,analysis_type);
-
-	/*Ok, get meltingrates now from basal conditions*/
-	GaussPenta* gauss=new GaussPenta();
-	for(int iv=0;iv<3;iv++){
-
-		gauss->GaussVertex(iv);
-		checkpositivethickness=true;
-
-		_assert_(watercolumn[iv]>=0.);
-
-		/*Calculate basal meltingrate after Fig.5 of A.Aschwanden 2012*/
-		meltingrate_enthalpy=0.;
-		heating=0.;
-		if((watercolumn[iv]>0.) && (enthalpy[iv]<matpar->PureIceEnthalpy(pressure[iv]))){
-			/*ensure that no ice is at T<Tm(p), if water layer present*/
-			enthalpy[iv]=matpar->PureIceEnthalpy(pressure[iv]); 
-		}
-		else if(enthalpy[iv]<matpar->PureIceEnthalpy(pressure[iv])){
-			/*cold base: set q*n=q_geo*n+frictionheating as Neumann BC in Penta::CreatePVectorEnthalpySheet*/
-			checkpositivethickness=false; // cold base, skip next test
-		}
-		else {/*we have a temperate base, go to next test*/}
-
-		if(checkpositivethickness){
-			/*ok, from here on all basal ice is temperate. Check for positive thickness of layer of temperate ice. */
-			istemperatelayer=false;
-			if(enthalpy[iv+3]>=matpar->PureIceEnthalpy(pressure[iv+3])) istemperatelayer=true;
-			if(istemperatelayer) for(i=0;i<3;i++) vec_heatflux[i]=0.; // TODO: add -k*nabla T_pmp
-			else{
-				enthalpy_input->GetInputDerivativeValue(&d1enthalpy[0],&xyz_list[0][0],gauss);
-				kappa=matpar->GetEnthalpyDiffusionParameterVolume(enthalpy[iv],enthalpy[iv+NUMVERTICES2D], pressure[iv],pressure[iv+NUMVERTICES2D]); _assert_(kappa>0.);
-				for(i=0;i<3;i++) vec_heatflux[i]=-kappa*d1enthalpy[i];
-			}
-
-			/*geothermal heatflux*/
-			BedNormal(&normal_base[0],xyz_list_tria);
-			heatflux=0.;
-			for(i=0;i<3;i++) heatflux+=(vec_heatflux[i])*normal_base[i];
-
-			/*basal friction*/
-			friction->GetAlpha2(&alpha2,gauss,VxEnum,VyEnum,VzEnum);
-			basalfriction=alpha2*(pow(vx[iv],2.0)+pow(vy[iv],2.0)+pow(vz[iv],2.0));
-
-			matpar->EnthalpyToThermal(&temperature, &waterfraction, enthalpy[iv],pressure[iv]);
-			// -Mb= Fb-(q-q_geo)/((1-w)*L), cf Aschwanden 2012, eq.66
-			heating=(heatflux+basalfriction+geothermalflux[iv]);
-			meltingrate_enthalpy=heating/((1-waterfraction)*latentheat*rho_ice); // m/s water equivalent 
-		}
-
-		/*Update water column, basal meltingrate*/
-		this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);
-		if(reCast<bool,IssmDouble>(dt)){
-			if(watercolumn[iv]+meltingrate_enthalpy*dt<0.){				
-				melting_overshoot=watercolumn[iv]+meltingrate_enthalpy*dt;
-				lambda=melting_overshoot/(meltingrate_enthalpy*dt); _assert_(lambda>0); _assert_(lambda<1);
-				basalmeltingrate[iv]=(1.-lambda)*meltingrate_enthalpy;
-				watercolumn[iv]=0.;
-				yts=365*24*60*60;
-				enthalpy[iv]+=dt/yts*lambda*heating;
-			}
-			else{
-				basalmeltingrate[iv]=meltingrate_enthalpy;
-				watercolumn[iv]+=dt*meltingrate_enthalpy; 
-			}
-		}
-		else{
-			basalmeltingrate[iv]=meltingrate_enthalpy;
-			watercolumn[iv]+=meltingrate_enthalpy;
-		}	  
-	}  
-	/*feed updated variables back into model*/
-	this->inputs->AddInput(new PentaInput(EnthalpyEnum,enthalpy,P1Enum));
-	this->inputs->AddInput(new PentaInput(WatercolumnEnum,watercolumn,P1Enum));
-	this->inputs->AddInput(new PentaInput(BasalforcingsMeltingRateEnum,basalmeltingrate,P1Enum));
-
-	/*Clean up and return*/
-	delete gauss;
-	delete friction;
-}
-/*}}}*/
-/*FUNCTION Penta::DrainWaterfraction{{{*/
-void Penta::DrainWaterfraction(void){
-
-    /*Intermediaries*/
-	bool isenthalpy;
-	IssmDouble waterfraction[NUMVERTICES], temperature[NUMVERTICES];
-	IssmDouble watercolumnbase[NUMVERTICES];
-	IssmDouble enthalpy[NUMVERTICES], pressure[NUMVERTICES]; 
-	IssmDouble latentheat, dt;
-	IssmDouble dw, dwc;
-	Penta *pentabase = NULL;
-
-	/*Check wether enthalpy is activated*/
-	parameters->FindParam(&isenthalpy,ThermalIsenthalpyEnum);
-	if(!isenthalpy) return;       
-	
-	/*get basal element, needed for basal watercolumn*/
-	pentabase=this->GetBasalElement();
-	
-	this->GetInputListOnVertices(&enthalpy[0],EnthalpyEnum);
-	this->GetInputListOnVertices(&pressure[0],PressureEnum);
-	pentabase->GetInputListOnVertices(&watercolumnbase[0], WatercolumnEnum);
-
-	this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);
-	latentheat=matpar->GetLatentHeat();
-
-	for(int iv=0;iv<NUMVERTICES;iv++){ 
-		matpar->EnthalpyToThermal(&temperature[iv],&waterfraction[iv], enthalpy[iv],pressure[iv]); 
-		dw=DrainageFunctionWaterfraction(waterfraction[iv], dt);
-		/*drain water fraction & update enthalpy*/
-		waterfraction[iv]-=dw;
-		matpar->ThermalToEnthalpy(&enthalpy[iv], temperature[iv], waterfraction[iv], pressure[iv]);        
-		/*add drained water to watercolumn at base*/
-		dwc=dw*this->IceVolume();
-		watercolumnbase[iv%NUMVERTICES2D]+=dwc;
-	}
-
-	/*feed updated results back into model*/
-	this->inputs->AddInput(new PentaInput(EnthalpyEnum,enthalpy,P1Enum));
-	this->inputs->AddInput(new PentaInput(WaterfractionEnum,waterfraction,P1Enum));
-	pentabase->inputs->AddInput(new PentaInput(WatercolumnEnum, watercolumnbase,P1Enum));
-
-}
-/*}}}*/
-#endif
-
-#ifdef _HAVE_CONTROL_
 /*FUNCTION Penta::ControlInputGetGradient{{{*/
 void Penta::ControlInputGetGradient(Vector<IssmDouble>* gradient,int enum_type,int control_index){
@@ -5125,10 +3025,10 @@
 
 	if(enum_type==MaterialsRheologyBbarEnum){
-		if(!IsOnBed()) return;
-		input=(Input*)material->inputs->GetInput(MaterialsRheologyBEnum);
+		if(!IsOnBase()) return;
+		input=(Input*)inputs->GetInput(MaterialsRheologyBEnum);
 	}
 	else if(enum_type==DamageDbarEnum){
-		if(!IsOnBed()) return;
-		input=(Input*)material->inputs->GetInput(DamageDEnum);
+		if(!IsOnBase()) return;
+		input=(Input*)inputs->GetInput(DamageDEnum);
 	}
 	else{
@@ -5148,8 +3048,8 @@
 
 	if(enum_type==MaterialsRheologyBbarEnum){
-		input=(Input*)material->inputs->GetInput(MaterialsRheologyBEnum);
+		input=(Input*)inputs->GetInput(MaterialsRheologyBEnum);
 	}
 	else if(enum_type==DamageDbarEnum){
-		input=(Input*)material->inputs->GetInput(DamageDEnum);
+		input=(Input*)inputs->GetInput(DamageDEnum);
 	}
 	else{
@@ -5170,8 +3070,8 @@
 
 	if(enum_type==MaterialsRheologyBbarEnum){
-		input=(Input*)material->inputs->GetInput(MaterialsRheologyBEnum);
+		input=(Input*)inputs->GetInput(MaterialsRheologyBEnum);
 	}
 	else if(enum_type==DamageDbarEnum){
-		input=(Input*)material->inputs->GetInput(DamageDEnum);
+		input=(Input*)inputs->GetInput(DamageDEnum);
 	}
 	else{
@@ -5193,8 +3093,8 @@
 
 	if(control_enum==MaterialsRheologyBbarEnum){
-		input=(Input*)material->inputs->GetInput(MaterialsRheologyBEnum);
+		input=(Input*)inputs->GetInput(MaterialsRheologyBEnum);
 	}
 	else if(control_enum==DamageDbarEnum){
-		input=(Input*)material->inputs->GetInput(DamageDEnum);
+		input=(Input*)inputs->GetInput(DamageDEnum);
 	}
 	else{
@@ -5210,6 +3110,6 @@
 	IssmDouble  value,gradient;
 
-	this->GetConnectivityList(&connectivity[0]);
-	this->GetVertexSidList(&sidlist[0]);
+	this->GetVerticesConnectivityList(&connectivity[0]);
+	this->GetVerticesSidList(&sidlist[0]);
 
 	GaussPenta* gauss=new GaussPenta();
@@ -5229,622 +3129,4 @@
 
 }/*}}}*/
-/*FUNCTION Penta::CreateKMatrixAdjointHoriz{{{*/
-ElementMatrix* Penta::CreateKMatrixAdjointHoriz(void){
-
-	int approximation;
-	inputs->GetInputValue(&approximation,ApproximationEnum);
-
-	switch(approximation){
-		case SSAApproximationEnum:
-			return CreateKMatrixAdjointSSA2d();
-		case HOApproximationEnum:
-			return CreateKMatrixAdjointHO();
-		case FSApproximationEnum:
-			return CreateKMatrixAdjointFS();
-		case NoneApproximationEnum:
-			return NULL;
-		default:
-			_error_("Approximation " << EnumToStringx(approximation) << " not supported yet");
-	}
-}
-/*}}}*/
-/*FUNCTION Penta::CreateKMatrixAdjointSSA2d{{{*/
-ElementMatrix* Penta::CreateKMatrixAdjointSSA2d(void){
-
-	/*Figure out if this penta is collapsed. If so, then bailout, except if it is at the 
-	  bedrock, in which case we spawn a tria element using the 3 first nodes, and use it to build 
-	  the stiffness matrix. */
-	if (!IsOnBed()) return NULL;
-
-	/*Depth average some fields*/
-	switch(this->material->ObjectEnum()){
-		case MaticeEnum:
-			this->InputDepthAverageAtBase(MaterialsRheologyBEnum,MaterialsRheologyBbarEnum,MaterialsEnum);
-			this->InputDepthAverageAtBase(DamageDEnum,DamageDbarEnum,MaterialsEnum);
-			break;
-		default:
-			_error_("material "<<EnumToStringx(this->material->ObjectEnum())<<" not supported");
-	}
-
-	/*Call Tria function*/
-	Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.
-	ElementMatrix* Ke=tria->CreateKMatrixAdjointSSA();
-	delete tria->material; delete tria;
-
-	/*Delete averaged fields*/
-	this->material->inputs->DeleteInput(MaterialsRheologyBbarEnum);
-	this->material->inputs->DeleteInput(DamageDbarEnum);
-
-	/*clean up and return*/
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Penta::CreateKMatrixAdjointHO{{{*/
-ElementMatrix* Penta::CreateKMatrixAdjointHO(void){
-
-	/*Intermediaries */
-	int        i,j;
-	bool       incomplete_adjoint;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble Jdet;
-	IssmDouble eps1dotdphii,eps1dotdphij;
-	IssmDouble eps2dotdphii,eps2dotdphij;
-	IssmDouble mu_prime;
-	IssmDouble epsilon[5]; /* epsilon=[exx,eyy,exy,exz,eyz];*/
-	IssmDouble eps1[3],eps2[3];
-	IssmDouble dphi[3][NUMVERTICES];
-	GaussPenta *gauss=NULL;
-
-	/*Initialize Jacobian with regular HO (first part of the Gateau derivative)*/
-	parameters->FindParam(&incomplete_adjoint,InversionIncompleteAdjointEnum);
-	ElementMatrix* Ke=CreateKMatrixStressbalanceHO();
-	if(incomplete_adjoint) return Ke;
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	Input* vx_input=inputs->GetInput(VxEnum);       _assert_(vx_input);
-	Input* vy_input=inputs->GetInput(VyEnum);       _assert_(vy_input);
-
-	/* Start  looping on the number of gaussian points: */
-	gauss=new GaussPenta(5,5);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		GetNodalFunctionsP1Derivatives(&dphi[0][0],&xyz_list[0][0],gauss);
-
-		this->GetStrainRate3dHO(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input);
-		material->GetViscosityDerivativeEpsSquare(&mu_prime,&epsilon[0]);
-		eps1[0]=2*epsilon[0]+epsilon[1];   eps2[0]=epsilon[2];
-		eps1[1]=epsilon[2];                eps2[1]=epsilon[0]+2*epsilon[1];
-		eps1[2]=epsilon[3];                eps2[2]=epsilon[4];
-
-		for(i=0;i<6;i++){
-			for(j=0;j<6;j++){
-				eps1dotdphii=eps1[0]*dphi[0][i]+eps1[1]*dphi[1][i]+eps1[2]*dphi[2][i];
-				eps1dotdphij=eps1[0]*dphi[0][j]+eps1[1]*dphi[1][j]+eps1[2]*dphi[2][j];
-				eps2dotdphii=eps2[0]*dphi[0][i]+eps2[1]*dphi[1][i]+eps2[2]*dphi[2][i];
-				eps2dotdphij=eps2[0]*dphi[0][j]+eps2[1]*dphi[1][j]+eps2[2]*dphi[2][j];
-
-				Ke->values[12*(2*i+0)+2*j+0]+=gauss->weight*Jdet*2*mu_prime*eps1dotdphij*eps1dotdphii;
-				Ke->values[12*(2*i+0)+2*j+1]+=gauss->weight*Jdet*2*mu_prime*eps2dotdphij*eps1dotdphii;
-				Ke->values[12*(2*i+1)+2*j+0]+=gauss->weight*Jdet*2*mu_prime*eps1dotdphij*eps2dotdphii;
-				Ke->values[12*(2*i+1)+2*j+1]+=gauss->weight*Jdet*2*mu_prime*eps2dotdphij*eps2dotdphii;
-			}
-		}
-	}
-
-	/*Transform Coordinate System*/
-	TransformStiffnessMatrixCoord(Ke,nodes,NUMVERTICES,XYEnum);
-
-	/*Clean up and return*/
-	delete gauss;
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Penta::CreateKMatrixAdjointFS{{{*/
-ElementMatrix* Penta::CreateKMatrixAdjointFS(void){
-
-	/*Intermediaries */
-	int        i,j;
-	bool       incomplete_adjoint;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble Jdet;
-	IssmDouble eps1dotdphii,eps1dotdphij;
-	IssmDouble eps2dotdphii,eps2dotdphij;
-	IssmDouble eps3dotdphii,eps3dotdphij;
-	IssmDouble mu_prime;
-	IssmDouble epsilon[5]; /* epsilon=[exx,eyy,exy,exz,eyz];*/
-	IssmDouble eps1[3],eps2[3],eps3[3];
-	IssmDouble dphi[3][NUMVERTICES];
-	GaussPenta *gauss=NULL;
-
-	/*Initialize Jacobian with regular FS (first part of the Gateau derivative)*/
-	parameters->FindParam(&incomplete_adjoint,InversionIncompleteAdjointEnum);
-	ElementMatrix* Ke=CreateKMatrixStressbalanceFS();
-	if(incomplete_adjoint) return Ke;
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int vnumnodes = this->NumberofNodesVelocity();
-	int pnumnodes = this->NumberofNodesPressure();
-	int numdof    = vnumnodes*NDOF3 + pnumnodes*NDOF1;
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	Input* vx_input=inputs->GetInput(VxEnum);       _assert_(vx_input);
-	Input* vy_input=inputs->GetInput(VyEnum);       _assert_(vy_input);
-	Input* vz_input=inputs->GetInput(VzEnum);       _assert_(vz_input);
-
-	/* Start  looping on the number of gaussian points: */
-	gauss=new GaussPenta(5,5);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		GetNodalFunctionsP1Derivatives(&dphi[0][0],&xyz_list[0][0],gauss);
-
-		this->GetStrainRate3dHO(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input);
-		material->GetViscosityDerivativeEpsSquare(&mu_prime,&epsilon[0]);
-		eps1[0]=epsilon[0];   eps2[0]=epsilon[2];   eps3[0]=epsilon[3];
-		eps1[1]=epsilon[2];   eps2[1]=epsilon[1];   eps3[1]=epsilon[4];
-		eps1[2]=epsilon[3];   eps2[2]=epsilon[4];   eps3[2]= -epsilon[0] -epsilon[1];
-
-		for(i=0;i<6;i++){
-			for(j=0;j<6;j++){
-				eps1dotdphii=eps1[0]*dphi[0][i]+eps1[1]*dphi[1][i]+eps1[2]*dphi[2][i];
-				eps1dotdphij=eps1[0]*dphi[0][j]+eps1[1]*dphi[1][j]+eps1[2]*dphi[2][j];
-				eps2dotdphii=eps2[0]*dphi[0][i]+eps2[1]*dphi[1][i]+eps2[2]*dphi[2][i];
-				eps2dotdphij=eps2[0]*dphi[0][j]+eps2[1]*dphi[1][j]+eps2[2]*dphi[2][j];
-				eps3dotdphii=eps3[0]*dphi[0][i]+eps3[1]*dphi[1][i]+eps3[2]*dphi[2][i];
-				eps3dotdphij=eps3[0]*dphi[0][j]+eps3[1]*dphi[1][j]+eps3[2]*dphi[2][j];
-
-				Ke->values[numdof*(4*i+0)+4*j+0]+=gauss->weight*Jdet*2*mu_prime*eps1dotdphij*eps1dotdphii;
-				Ke->values[numdof*(4*i+0)+4*j+1]+=gauss->weight*Jdet*2*mu_prime*eps2dotdphij*eps1dotdphii;
-				Ke->values[numdof*(4*i+0)+4*j+2]+=gauss->weight*Jdet*2*mu_prime*eps3dotdphij*eps1dotdphii;
-
-				Ke->values[numdof*(4*i+1)+4*j+0]+=gauss->weight*Jdet*2*mu_prime*eps1dotdphij*eps2dotdphii;
-				Ke->values[numdof*(4*i+1)+4*j+1]+=gauss->weight*Jdet*2*mu_prime*eps2dotdphij*eps2dotdphii;
-				Ke->values[numdof*(4*i+1)+4*j+2]+=gauss->weight*Jdet*2*mu_prime*eps3dotdphij*eps2dotdphii;
-
-				Ke->values[numdof*(4*i+2)+4*j+0]+=gauss->weight*Jdet*2*mu_prime*eps1dotdphij*eps3dotdphii;
-				Ke->values[numdof*(4*i+2)+4*j+1]+=gauss->weight*Jdet*2*mu_prime*eps2dotdphij*eps3dotdphii;
-				Ke->values[numdof*(4*i+2)+4*j+2]+=gauss->weight*Jdet*2*mu_prime*eps3dotdphij*eps3dotdphii;
-			}
-		}
-	}
-
-	/*Transform Coordinate System*/
-	TransformStiffnessMatrixCoord(Ke,nodes,NUMVERTICES,XYZEnum);
-
-	/*Clean up and return*/
-	delete gauss;
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Penta::CreatePVectorAdjointHoriz{{{*/
-ElementVector* Penta::CreatePVectorAdjointHoriz(void){
-
-	int approximation;
-	inputs->GetInputValue(&approximation,ApproximationEnum);
-
-	switch(approximation){
-		case SSAApproximationEnum:
-			return CreatePVectorAdjointSSA();
-		case HOApproximationEnum:
-			return CreatePVectorAdjointHO();
-		case NoneApproximationEnum:
-			return NULL;
-		case FSApproximationEnum:
-			return CreatePVectorAdjointFS();
-		default:
-			_error_("Approximation " << EnumToStringx(approximation) << " not supported yet");
-	}
-}
-/*}}}*/
-/*FUNCTION Penta::CreatePVectorAdjointSSA{{{*/
-ElementVector* Penta::CreatePVectorAdjointSSA(){
-
-	if (!IsOnBed()) return NULL;
-
-	/*Call Tria function*/
-	Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.
-	ElementVector* pe=tria->CreatePVectorAdjointHoriz();
-	delete tria->material; delete tria;
-
-	/*clean up and return*/
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Penta::CreatePVectorAdjointHO{{{*/
-ElementVector* Penta::CreatePVectorAdjointHO(void){
-
-	/*Nothing to be done if not on surface*/
-	if (!IsOnSurface()) return NULL;
-
-	/*Intermediaries */
-	int        i,j,resp;
-	int       *responses=NULL;
-	int        num_responses;
-	IssmDouble Jdet2d;
-	IssmDouble obs_velocity_mag,velocity_mag;
-	IssmDouble dux,duy;
-	IssmDouble epsvel=2.220446049250313e-16;
-	IssmDouble meanvel=3.170979198376458e-05; /*1000 m/yr*/
-	IssmDouble scalex=0.,scaley=0.,scale=0.,S=0.;
-	IssmDouble vx,vy,vxobs,vyobs,weight;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble xyz_list_tria[NUMVERTICES2D][3];
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Initialize Element vector*/
-	ElementVector* pe    = new ElementVector(nodes,numnodes,this->parameters);
-	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	this->parameters->FindParam(&num_responses,InversionNumCostFunctionsEnum);
-	this->parameters->FindParam(&responses,NULL,InversionCostFunctionsEnum);
-	Input* weights_input=inputs->GetInput(InversionCostFunctionsCoefficientsEnum);   _assert_(weights_input);
-	Input* vx_input     =inputs->GetInput(VxEnum);        _assert_(vx_input);
-	Input* vy_input     =inputs->GetInput(VyEnum);        _assert_(vy_input);
-	Input* vxobs_input  =inputs->GetInput(InversionVxObsEnum);     _assert_(vxobs_input);
-	Input* vyobs_input  =inputs->GetInput(InversionVyObsEnum);     _assert_(vyobs_input);
-
-	for(i=0;i<NUMVERTICES2D;i++) for(j=0;j<3;j++) xyz_list_tria[i][j]=xyz_list[i][j];
-
-	/*Get Surface if required by one response*/
-	for(resp=0;resp<num_responses;resp++){
-		if(responses[resp]==SurfaceAverageVelMisfitEnum){
-			inputs->GetInputValue(&S,SurfaceAreaEnum); break;
-		}
-	}
-
-	/* Start  looping on the number of gaussian points: */
-	GaussPenta* gauss=new GaussPenta(3,4,5,4);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		/* Get Jacobian determinant: */
-		GetTriaJacobianDeterminant(&Jdet2d,&xyz_list_tria[0][0],gauss);
-
-		/*Get all parameters at gaussian point*/
-		vx_input->GetInputValue(&vx,gauss);
-		vy_input->GetInputValue(&vy,gauss);
-		vxobs_input->GetInputValue(&vxobs,gauss);
-		vyobs_input->GetInputValue(&vyobs,gauss);
-		GetNodalFunctions(basis, gauss);
-
-		/*Loop over all requested responses*/
-		for(resp=0;resp<num_responses;resp++){
-
-			weights_input->GetInputValue(&weight,gauss,responses[resp]);
-
-			switch(responses[resp]){
-				case SurfaceAbsVelMisfitEnum:
-					/*
-					 *      1  [           2              2 ]
-					 * J = --- | (u - u   )  +  (v - v   )  |
-					 *      2  [       obs            obs   ]
-					 *
-					 *        dJ
-					 * DU = - -- = (u   - u )
-					 *        du     obs
-					 */
-					for(i=0;i<numnodes;i++){
-						dux=vxobs-vx;
-						duy=vyobs-vy;
-						pe->values[i*NDOF2+0]+=dux*weight*Jdet2d*gauss->weight*basis[i]; 
-						pe->values[i*NDOF2+1]+=duy*weight*Jdet2d*gauss->weight*basis[i]; 
-					}
-					break;
-				case SurfaceRelVelMisfitEnum:
-					/*
-					 *      1  [     \bar{v}^2             2   \bar{v}^2              2 ]
-					 * J = --- | -------------  (u - u   ) + -------------  (v - v   )  |
-					 *      2  [  (u   + eps)^2       obs    (v   + eps)^2       obs    ]
-					 *              obs                        obs                      
-					 *
-					 *        dJ     \bar{v}^2
-					 * DU = - -- = ------------- (u   - u )
-					 *        du   (u   + eps)^2    obs
-					 *               obs
-					 */
-					for(i=0;i<numnodes;i++){
-						scalex=pow(meanvel/(vxobs+epsvel),2); if(vxobs==0)scalex=0;
-						scaley=pow(meanvel/(vyobs+epsvel),2); if(vyobs==0)scaley=0;
-						dux=scalex*(vxobs-vx);
-						duy=scaley*(vyobs-vy);
-						pe->values[i*NDOF2+0]+=dux*weight*Jdet2d*gauss->weight*basis[i]; 
-						pe->values[i*NDOF2+1]+=duy*weight*Jdet2d*gauss->weight*basis[i]; 
-					}
-					break;
-				case SurfaceLogVelMisfitEnum:
-					/*
-					 *                 [        vel + eps     ] 2
-					 * J = 4 \bar{v}^2 | log ( -----------  ) |  
-					 *                 [       vel   + eps    ]
-					 *                            obs
-					 *
-					 *        dJ                 2 * log(...)
-					 * DU = - -- = - 4 \bar{v}^2 -------------  u
-					 *        du                 vel^2 + eps
-					 *            
-					 */
-					for(i=0;i<numnodes;i++){
-						velocity_mag    =sqrt(pow(vx,   2)+pow(vy,   2))+epsvel;
-						obs_velocity_mag=sqrt(pow(vxobs,2)+pow(vyobs,2))+epsvel;
-						scale=-8*pow(meanvel,2)/pow(velocity_mag,2)*log(velocity_mag/obs_velocity_mag);
-						dux=scale*vx;
-						duy=scale*vy;
-						pe->values[i*NDOF2+0]+=dux*weight*Jdet2d*gauss->weight*basis[i]; 
-						pe->values[i*NDOF2+1]+=duy*weight*Jdet2d*gauss->weight*basis[i]; 
-					}
-					break;
-				case SurfaceAverageVelMisfitEnum:
-					/*
-					 *      1                    2              2
-					 * J = ---  sqrt(  (u - u   )  +  (v - v   )  )
-					 *      S                obs            obs
-					 *
-					 *        dJ      1       1 
-					 * DU = - -- = - --- ----------- * 2 (u - u   )
-					 *        du      S  2 sqrt(...)           obs
-					 */
-					for(i=0;i<numnodes;i++){
-						scale=1./(S*2*sqrt(pow(vx-vxobs,2)+pow(vy-vyobs,2))+epsvel);
-						dux=scale*(vxobs-vx);
-						duy=scale*(vyobs-vy);
-						pe->values[i*NDOF2+0]+=dux*weight*Jdet2d*gauss->weight*basis[i]; 
-						pe->values[i*NDOF2+1]+=duy*weight*Jdet2d*gauss->weight*basis[i]; 
-					}
-					break;
-				case SurfaceLogVxVyMisfitEnum:
-					/*
-					 *      1            [        |u| + eps     2          |v| + eps     2  ]
-					 * J = --- \bar{v}^2 | log ( -----------  )   +  log ( -----------  )   |  
-					 *      2            [       |u    |+ eps              |v    |+ eps     ]
-					 *                              obs                       obs
-					 *        dJ                              1      u                             1
-					 * DU = - -- = - \bar{v}^2 log(u...) --------- ----  ~ - \bar{v}^2 log(u...) ------
-					 *        du                         |u| + eps  |u|                           u + eps
-					 */
-					for(i=0;i<numnodes;i++){
-						dux = - meanvel*meanvel * log((fabs(vx)+epsvel)/(fabs(vxobs)+epsvel)) / (vx+epsvel);
-						duy = - meanvel*meanvel * log((fabs(vy)+epsvel)/(fabs(vyobs)+epsvel)) / (vy+epsvel);
-						pe->values[i*NDOF2+0]+=dux*weight*Jdet2d*gauss->weight*basis[i]; 
-						pe->values[i*NDOF2+1]+=duy*weight*Jdet2d*gauss->weight*basis[i]; 
-					}
-					break;
-				case DragCoefficientAbsGradientEnum:
-					/*Nothing in P vector*/
-					break;
-				case ThicknessAbsGradientEnum:
-					/*Nothing in P vector*/
-					break;
-				case ThicknessAlongGradientEnum:
-					/*Nothing in P vector*/
-					break;
-				case ThicknessAcrossGradientEnum:
-					/*Nothing in P vector*/
-					break;
-				case RheologyBbarAbsGradientEnum:
-					/*Nothing in P vector*/
-					break;
-				default:
-					_error_("response " << EnumToStringx(responses[resp]) << " not supported yet");
-			}
-		}
-	}
-
-	/*Clean up and return*/
-	xDelete<IssmDouble>(basis);
-	xDelete<int>(responses);
-	delete gauss;
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Penta::CreatePVectorAdjointFS{{{*/
-ElementVector* Penta::CreatePVectorAdjointFS(void){
-
-	if(!IsOnSurface()) return NULL;
-
-	/*Intermediaries */
-	int         i,j,resp;
-	int        *responses= NULL;
-	int         num_responses;
-	IssmDouble  Jdet2d;
-	IssmDouble  obs_velocity_mag,velocity_mag;
-	IssmDouble  dux,duy;
-	IssmDouble  epsvel  = 2.220446049250313e-16;
-	IssmDouble  meanvel = 3.170979198376458e-05;  /*1000 m/yr */
-	IssmDouble  scalex  = 0,scaley=0,scale=0,S=0;
-	IssmDouble  vx,vy,vxobs,vyobs,weight;
-	IssmDouble  xyz_list[NUMVERTICES][3];
-	IssmDouble	xyz_list_tria[NUMVERTICES2D][3];
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int vnumnodes = this->NumberofNodesVelocity();
-	int pnumnodes = this->NumberofNodesPressure();
-
-	/*Prepare coordinate system list*/
-	int* cs_list = xNew<int>(vnumnodes+pnumnodes);
-	for(i=0;i<vnumnodes;i++) cs_list[i]           = XYZEnum;
-	for(i=0;i<pnumnodes;i++) cs_list[vnumnodes+i] = PressureEnum;
-
-	/*Initialize Element matrix and vectors*/
-	ElementVector* pe     = new ElementVector(nodes,vnumnodes+pnumnodes,this->parameters,FSApproximationEnum);
-	IssmDouble*    vbasis = xNew<IssmDouble>(vnumnodes);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	this->parameters->FindParam(&num_responses,InversionNumCostFunctionsEnum);
-	this->parameters->FindParam(&responses,NULL,InversionCostFunctionsEnum);
-	Input* weights_input = inputs->GetInput(InversionCostFunctionsCoefficientsEnum); _assert_(weights_input);
-	Input* vx_input      = inputs->GetInput(VxEnum);                                 _assert_(vx_input);
-	Input* vy_input      = inputs->GetInput(VyEnum);                                 _assert_(vy_input);
-	Input* vxobs_input   = inputs->GetInput(InversionVxObsEnum);                     _assert_(vxobs_input);
-	Input* vyobs_input   = inputs->GetInput(InversionVyObsEnum);                     _assert_(vyobs_input);
-
-	for(i=0;i<NUMVERTICES2D;i++) for(j=0;j<3;j++) xyz_list_tria[i][j]=xyz_list[i][j];
-
-	/*Get Surface if required by one response*/
-	for(resp=0;resp<num_responses;resp++){
-		if(responses[resp]==SurfaceAverageVelMisfitEnum){
-			inputs->GetInputValue(&S,SurfaceAreaEnum); break;
-		}
-	}
-
-	/* Start  looping on the number of gaussian points: */
-	GaussPenta* gauss=new GaussPenta(3,4,5,4);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		/* Get Jacobian determinant: */
-		GetTriaJacobianDeterminant(&Jdet2d,&xyz_list_tria[0][0],gauss);
-
-		/*Get all parameters at gaussian point*/
-		vx_input->GetInputValue(&vx,gauss);
-		vy_input->GetInputValue(&vy,gauss);
-		vxobs_input->GetInputValue(&vxobs,gauss);
-		vyobs_input->GetInputValue(&vyobs,gauss);
-		GetNodalFunctionsVelocity(vbasis,gauss);
-
-		/*Loop over all requested responses*/
-		for(resp=0;resp<num_responses;resp++){
-
-			weights_input->GetInputValue(&weight,gauss,responses[resp]);
-
-			switch(responses[resp]){
-
-				case SurfaceAbsVelMisfitEnum:
-					/*
-					 *      1  [           2              2 ]
-					 * J = --- | (u - u   )  +  (v - v   )  |
-					 *      2  [       obs            obs   ]
-					 *
-					 *        dJ
-					 * DU = - -- = (u   - u )
-					 *        du     obs
-					 */
-					for(i=0;i<vnumnodes;i++){
-						dux=vxobs-vx;
-						duy=vyobs-vy;
-						pe->values[i*NDOF3+0]+=dux*weight*Jdet2d*gauss->weight*vbasis[i]; 
-						pe->values[i*NDOF3+1]+=duy*weight*Jdet2d*gauss->weight*vbasis[i]; 
-					}
-					break;
-				case SurfaceRelVelMisfitEnum:
-					/*
-					 *      1  [     \bar{v}^2             2   \bar{v}^2              2 ]
-					 * J = --- | -------------  (u - u   ) + -------------  (v - v   )  |
-					 *      2  [  (u   + eps)^2       obs    (v   + eps)^2       obs    ]
-					 *              obs                        obs                      
-					 *
-					 *        dJ     \bar{v}^2
-					 * DU = - -- = ------------- (u   - u )
-					 *        du   (u   + eps)^2    obs
-					 *               obs
-					 */
-					for(i=0;i<vnumnodes;i++){
-						scalex=pow(meanvel/(vxobs+epsvel),2); if(vxobs==0)scalex=0;
-						scaley=pow(meanvel/(vyobs+epsvel),2); if(vyobs==0)scaley=0;
-						dux=scalex*(vxobs-vx);
-						duy=scaley*(vyobs-vy);
-						pe->values[i*NDOF3+0]+=dux*weight*Jdet2d*gauss->weight*vbasis[i]; 
-						pe->values[i*NDOF3+1]+=duy*weight*Jdet2d*gauss->weight*vbasis[i]; 
-					}
-					break;
-				case SurfaceLogVelMisfitEnum:
-					/*
-					 *                 [        vel + eps     ] 2
-					 * J = 4 \bar{v}^2 | log ( -----------  ) |  
-					 *                 [       vel   + eps    ]
-					 *                            obs
-					 *
-					 *        dJ                 2 * log(...)
-					 * DU = - -- = - 4 \bar{v}^2 -------------  u
-					 *        du                 vel^2 + eps
-					 *            
-					 */
-					for(i=0;i<vnumnodes;i++){
-						velocity_mag    =sqrt(pow(vx,   2)+pow(vy,   2))+epsvel;
-						obs_velocity_mag=sqrt(pow(vxobs,2)+pow(vyobs,2))+epsvel;
-						scale=-8*pow(meanvel,2)/pow(velocity_mag,2)*log(velocity_mag/obs_velocity_mag);
-						dux=scale*vx;
-						duy=scale*vy;
-						pe->values[i*NDOF3+0]+=dux*weight*Jdet2d*gauss->weight*vbasis[i]; 
-						pe->values[i*NDOF3+1]+=duy*weight*Jdet2d*gauss->weight*vbasis[i]; 
-					}
-					break;
-				case SurfaceAverageVelMisfitEnum:
-					/*
-					 *      1                    2              2
-					 * J = ---  sqrt(  (u - u   )  +  (v - v   )  )
-					 *      S                obs            obs
-					 *
-					 *        dJ      1       1 
-					 * DU = - -- = - --- ----------- * 2 (u - u   )
-					 *        du      S  2 sqrt(...)           obs
-					 */
-					for(i=0;i<vnumnodes;i++){
-						scale=1./(S*2*sqrt(pow(vx-vxobs,2)+pow(vy-vyobs,2))+epsvel);
-						dux=scale*(vxobs-vx);
-						duy=scale*(vyobs-vy);
-						pe->values[i*NDOF3+0]+=dux*weight*Jdet2d*gauss->weight*vbasis[i]; 
-						pe->values[i*NDOF3+1]+=duy*weight*Jdet2d*gauss->weight*vbasis[i]; 
-					}
-					break;
-				case SurfaceLogVxVyMisfitEnum:
-					/*
-					 *      1            [        |u| + eps     2          |v| + eps     2  ]
-					 * J = --- \bar{v}^2 | log ( -----------  )   +  log ( -----------  )   |  
-					 *      2            [       |u    |+ eps              |v    |+ eps     ]
-					 *                              obs                       obs
-					 *        dJ                              1      u                             1
-					 * DU = - -- = - \bar{v}^2 log(u...) --------- ----  ~ - \bar{v}^2 log(u...) ------
-					 *        du                         |u| + eps  |u|                           u + eps
-					 */
-					for(i=0;i<vnumnodes;i++){
-						dux = - meanvel*meanvel * log((fabs(vx)+epsvel)/(fabs(vxobs)+epsvel)) / (vx+epsvel);
-						duy = - meanvel*meanvel * log((fabs(vy)+epsvel)/(fabs(vyobs)+epsvel)) / (vy+epsvel);
-						pe->values[i*NDOF3+0]+=dux*weight*Jdet2d*gauss->weight*vbasis[i]; 
-						pe->values[i*NDOF3+1]+=duy*weight*Jdet2d*gauss->weight*vbasis[i]; 
-					}
-					break;
-				case DragCoefficientAbsGradientEnum:
-					/*Nothing in P vector*/
-					break;
-				case ThicknessAbsGradientEnum:
-					/*Nothing in P vector*/
-					break;
-				case ThicknessAcrossGradientEnum:
-					/*Nothing in P vector*/
-					break;
-				case ThicknessAlongGradientEnum:
-					/*Nothing in P vector*/
-					break;
-				case RheologyBbarAbsGradientEnum:
-					/*Nothing in P vector*/
-					break;
-				default:
-					_error_("response " << EnumToStringx(responses[resp]) << " not supported yet");
-			}
-		}
-	}
-
-	/*Clean up and return*/
-	xDelete<int>(responses);
-	xDelete<int>(cs_list);
-	xDelete<IssmDouble>(vbasis);
-	delete gauss;
-	return pe;
-}
-/*}}}*/
 /*FUNCTION Penta::GradientIndexing{{{*/
 void Penta::GradientIndexing(int* indexing,int control_index){
@@ -5869,5 +3151,5 @@
 
 	/*If on water, skip grad (=0): */
-	if(NoIceInElement())return;
+	if(!IsIceInElement())return;
 					
 	/*First deal with ∂/∂alpha(KU-F)*/
@@ -5935,6 +3217,6 @@
 			break;
 		case DragCoefficientAbsGradientEnum:
-			if(IsOnBed()){
-				tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.
+			if(IsOnBase()){
+				tria=(Tria*)SpawnTria(0,1,2);
 				tria->GradjDragGradient(gradient,control_index);
 				delete tria->material; delete tria;
@@ -5942,6 +3224,6 @@
 			break;
 		case RheologyBbarAbsGradientEnum:
-			if(IsOnBed()){
-				tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.
+			if(IsOnBase()){
+				tria=(Tria*)SpawnTria(0,1,2);
 				tria->GradjBGradient(gradient,control_index);
 				delete tria->material; delete tria;
@@ -5958,8 +3240,8 @@
 
 	/*Gradient is 0 if on shelf or not on bed*/
-	if(IsFloating() || !IsOnBed()) return;
+	if(IsFloating() || !IsOnBase()) return;
 
 	/*Spawn tria*/
-	Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.
+	Tria* tria=(Tria*)SpawnTria(0,1,2);
 	tria->GradjDragSSA(gradient,control_index);
 	delete tria->material; delete tria;
@@ -5984,10 +3266,10 @@
 
 	/*Gradient is 0 if on shelf or not on bed*/
-	if(IsFloating() || !IsOnBed()) return;
+	if(IsFloating() || !IsOnBase()) return;
 
 	/*Retrieve all inputs and parameters*/
 	parameters->FindParam(&analysis_type,AnalysisTypeEnum);
 	GradientIndexing(&vertexpidlist[0],control_index);
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
 	for(i=0;i<NUMVERTICES2D;i++) for(j=0;j<3;j++) xyz_list_tria[i][j]=xyz_list[i][j];
 	Input* adjointx_input=inputs->GetInput(AdjointxEnum);               _assert_(adjointx_input);
@@ -5998,5 +3280,5 @@
 
 	/*Build frictoin element, needed later: */
-	friction=new Friction("2d",inputs,matpar,analysis_type);
+	friction=new Friction(this,2);
 
 	/* Start  looping on the number of gaussian points: */
@@ -6010,5 +3292,5 @@
 
 		/*Build alpha_complement_list: */
-		friction->GetAlphaComplement(&alpha_complement, gauss,VxEnum,VyEnum,VzEnum);
+		friction->GetAlphaComplement(&alpha_complement,gauss,vx_input,vy_input,NULL);
 
 		dragcoefficient_input->GetInputValue(&drag, gauss);
@@ -6057,9 +3339,9 @@
 
 	/*Gradient is 0 if on shelf or not on bed*/
-	if(IsFloating() || !IsOnBed()) return;
+	if(IsFloating() || !IsOnBase()) return;
 
 	/*Retrieve all inputs and parameters*/
 	parameters->FindParam(&analysis_type,AnalysisTypeEnum);
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
 	for(i=0;i<NUMVERTICES2D;i++) for(j=0;j<3;j++) xyz_list_tria[i][j]=xyz_list[i][j];
 	GradientIndexing(&vertexpidlist[0],control_index);
@@ -6073,5 +3355,5 @@
 
 	/*Build frictoin element, needed later: */
-	friction=new Friction("3d",inputs,matpar,analysis_type);
+	friction=new Friction(this,3);
 
 	/* Start  looping on the number of gaussian points: */
@@ -6082,5 +3364,5 @@
 
 		/*Recover alpha_complement and drag: */
-		friction->GetAlphaComplement(&alpha_complement, gauss,VxEnum,VyEnum,VzEnum);
+		friction->GetAlphaComplement(&alpha_complement,gauss,vx_input,vy_input,vz_input);
 		drag_input->GetInputValue(&drag,gauss);
 
@@ -6096,5 +3378,5 @@
 
 		/*Get normal vector to the bed */
-		SurfaceNormal(&surface_normal[0],xyz_list_tria);
+		NormalTop(&surface_normal[0],&xyz_list_tria[0][0]);
 
 		bed_normal[0]=-surface_normal[0]; //Function is for upper surface, so the normal to the bed is the opposite of the result
@@ -6133,18 +3415,18 @@
 
 	/*This element should be collapsed into a tria element at its base*/
-	if (!IsOnBed()) return; 
+	if (!IsOnBase()) return; 
 
 	/*Depth Average B*/
-	this->InputDepthAverageAtBase(MaterialsRheologyBEnum,MaterialsRheologyBbarEnum,MaterialsEnum);
-	this->InputDepthAverageAtBase(DamageDEnum,DamageDbarEnum,MaterialsEnum);
+	this->InputDepthAverageAtBase(MaterialsRheologyBEnum,MaterialsRheologyBbarEnum);
+	if(this->material->IsDamage())this->InputDepthAverageAtBase(DamageDEnum,DamageDbarEnum);
 
 	/*Collapse element to the base*/
-	Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.
+	Tria* tria=(Tria*)SpawnTria(0,1,2);
 	tria->GradjBSSA(gradient,control_index);
 	delete tria->material; delete tria;
 
 	/*delete Average B*/
-	this->material->inputs->DeleteInput(MaterialsRheologyBbarEnum);
-	this->material->inputs->DeleteInput(DamageDbarEnum);
+	this->inputs->DeleteInput(MaterialsRheologyBbarEnum);
+	this->inputs->DeleteInput(DamageDbarEnum);
 
 } /*}}}*/
@@ -6153,18 +3435,18 @@
 
 	/*Gradient is computed on bed only (Bbar)*/
-	if (!IsOnBed()) return;
+	if (!IsOnBase()) return;
 
 	/*Depth Average B and D*/
-	this->InputDepthAverageAtBase(MaterialsRheologyBEnum,MaterialsRheologyBbarEnum,MaterialsEnum);
-	this->InputDepthAverageAtBase(DamageDEnum,DamageDbarEnum,MaterialsEnum);
+	this->InputDepthAverageAtBase(MaterialsRheologyBEnum,MaterialsRheologyBbarEnum);
+	if(this->material->IsDamage())this->InputDepthAverageAtBase(DamageDEnum,DamageDbarEnum);
 
 	/*Collapse element to the base*/
-	Tria* tria=(Tria*)SpawnTria(0);
+	Tria* tria=(Tria*)SpawnTria(0,1,2);
 	tria->GradjBSSA(gradient,control_index);    //We use SSA as an estimate for now
 	delete tria->material; delete tria;
 
 	/*delete Average B*/
-	this->material->inputs->DeleteInput(MaterialsRheologyBbarEnum);
-	this->material->inputs->DeleteInput(DamageDbarEnum);
+	this->inputs->DeleteInput(MaterialsRheologyBbarEnum);
+	this->inputs->DeleteInput(DamageDbarEnum);
 } /*}}}*/
 /*FUNCTION Penta::GradjBbarFS {{{*/
@@ -6172,18 +3454,18 @@
 
 	/*Gradient is computed on bed only (Bbar)*/
-	if (!IsOnBed()) return;
+	if (!IsOnBase()) return;
 
 	/*Depth Average B and D*/
-	this->InputDepthAverageAtBase(MaterialsRheologyBEnum,MaterialsRheologyBbarEnum,MaterialsEnum);
-	this->InputDepthAverageAtBase(DamageDEnum,DamageDbarEnum,MaterialsEnum);
+	this->InputDepthAverageAtBase(MaterialsRheologyBEnum,MaterialsRheologyBbarEnum);
+	if(this->material->IsDamage())this->InputDepthAverageAtBase(DamageDEnum,DamageDbarEnum);
 
 	/*Collapse element to the base*/
-	Tria* tria=(Tria*)SpawnTria(0);
+	Tria* tria=(Tria*)SpawnTria(0,1,2);
 	tria->GradjBSSA(gradient,control_index);    //We use SSA as an estimate for now
 	delete tria->material; delete tria;
 
 	/*delete Average B*/
-	this->material->inputs->DeleteInput(MaterialsRheologyBbarEnum);
-	this->material->inputs->DeleteInput(DamageDbarEnum);
+	this->inputs->DeleteInput(MaterialsRheologyBbarEnum);
+	this->inputs->DeleteInput(DamageDbarEnum);
 } /*}}}*/
 /*FUNCTION Penta::InputControlUpdate{{{*/
@@ -6202,16 +3484,15 @@
 
 		if(control_type[i]==MaterialsRheologyBbarEnum){
-			if (!IsOnBed()) goto cleanup_and_return;
-			input=(Input*)material->inputs->GetInput(MaterialsRheologyBEnum); _assert_(input);
+			if (!IsOnBase()) goto cleanup_and_return;
+			input=(Input*)this->inputs->GetInput(MaterialsRheologyBEnum); _assert_(input);
 		}
 		else if(control_type[i]==DamageDbarEnum){
-			if (!IsOnBed()) goto cleanup_and_return;
-			input=(Input*)material->inputs->GetInput(DamageDEnum); _assert_(input);
+			if (!IsOnBase()) goto cleanup_and_return;
+			input=(Input*)this->inputs->GetInput(DamageDEnum); _assert_(input);
 		}
 		else{
 			input=(Input*)this->inputs->GetInput(control_type[i]); _assert_(input);
 		}
-
-		if (input->ObjectEnum()!=ControlInputEnum) _error_("input " << EnumToStringx(control_type[i]) << " is not a ControlInput");
+		if(input->ObjectEnum()!=ControlInputEnum) _error_("input " << EnumToStringx(control_type[i]) << " is not a ControlInput");
 
 		((ControlInput*)input)->UpdateValue(scalar);
@@ -6220,8 +3501,8 @@
 
 		if(control_type[i]==MaterialsRheologyBbarEnum){
-			this->InputExtrude(MaterialsRheologyBEnum,MaterialsEnum);
+			this->InputExtrude(MaterialsRheologyBEnum);
 		}
 		else if(control_type[i]==DamageDbarEnum){
-			this->InputExtrude(DamageDEnum,MaterialsEnum);
+			this->InputExtrude(DamageDEnum);
 		}
 	}
@@ -6232,103 +3513,4 @@
 }
 /*}}}*/
-/*FUNCTION Penta::InputUpdateFromSolutionAdjointFS {{{*/
-void  Penta::InputUpdateFromSolutionAdjointFS(IssmDouble* solution){
-
-	int          i;
-	int*         vdoflist=NULL;
-	int*         pdoflist=NULL;
-	IssmDouble   FSreconditioning;
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int vnumnodes = this->NumberofNodesVelocity();
-	int pnumnodes = this->NumberofNodesPressure();
-	int vnumdof   = vnumnodes*NDOF3;
-	int pnumdof   = pnumnodes*NDOF1;
-
-	/*Initialize values*/
-	IssmDouble* vvalues = xNew<IssmDouble>(vnumdof);
-	IssmDouble* pvalues = xNew<IssmDouble>(pnumdof);
-	IssmDouble* lambdax = xNew<IssmDouble>(vnumnodes);
-	IssmDouble* lambday = xNew<IssmDouble>(vnumnodes);
-	IssmDouble* lambdaz = xNew<IssmDouble>(vnumnodes);
-	IssmDouble* lambdap = xNew<IssmDouble>(pnumnodes);
-
-	/*Get dof list: */
-	GetDofListVelocity(&vdoflist,GsetEnum);
-	GetDofListPressure(&pdoflist,GsetEnum);
-
-	/*Use the dof list to index into the solution vector: */
-	for(i=0;i<vnumdof;i++) vvalues[i]=solution[vdoflist[i]];
-	for(i=0;i<pnumdof;i++) pvalues[i]=solution[pdoflist[i]];
-
-	/*Transform solution in Cartesian Space*/
-	TransformSolutionCoord(&vvalues[0],nodes,vnumnodes,XYZEnum);
-
-	/*fill in all arrays: */
-	for(i=0;i<vnumnodes;i++){
-		lambdax[i] = vvalues[i*NDOF3+0]; if(xIsNan<IssmDouble>(lambdax[i])) _error_("NaN found in solution vector");
-		lambday[i] = vvalues[i*NDOF3+1]; if(xIsNan<IssmDouble>(lambday[i])) _error_("NaN found in solution vector");
-		lambdaz[i] = vvalues[i*NDOF3+2]; if(xIsNan<IssmDouble>(lambdaz[i])) _error_("NaN found in solution vector");
-	}
-	for(i=0;i<pnumnodes;i++){
-		lambdap[i] = pvalues[i]; if(xIsNan<IssmDouble>(lambdap[i])) _error_("NaN found in solution vector");
-	}
-
-	/*Recondition pressure and compute vel: */
-	this->parameters->FindParam(&FSreconditioning,StressbalanceFSreconditioningEnum);
-	for(i=0;i<pnumnodes;i++) lambdap[i]=lambdap[i]*FSreconditioning;
-
-	/*Add vx and vy as inputs to the tria element: */
-	this->inputs->AddInput(new PentaInput(AdjointxEnum,lambdax,P1Enum));
-	this->inputs->AddInput(new PentaInput(AdjointyEnum,lambday,P1Enum));
-	this->inputs->AddInput(new PentaInput(AdjointzEnum,lambdaz,P1Enum));
-	this->inputs->AddInput(new PentaInput(AdjointpEnum,lambdap,P1Enum));
-
-	/*Free ressources:*/
-	xDelete<int>(vdoflist);
-	xDelete<int>(pdoflist);
-	xDelete<IssmDouble>(lambdap);
-	xDelete<IssmDouble>(lambdaz);
-	xDelete<IssmDouble>(lambday);
-	xDelete<IssmDouble>(lambdax);
-	xDelete<IssmDouble>(vvalues);
-	xDelete<IssmDouble>(pvalues);
-}
-/*}}}*/
-/*FUNCTION Penta::InputUpdateFromSolutionAdjointHoriz {{{*/
-void  Penta::InputUpdateFromSolutionAdjointHoriz(IssmDouble* solution){
-
-	const int numdof=NDOF2*NUMVERTICES;
-
-	int    i;
-	IssmDouble values[numdof];
-	IssmDouble lambdax[NUMVERTICES];
-	IssmDouble lambday[NUMVERTICES];
-	int*   doflist=NULL;
-
-	/*Get dof list: */
-	GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
-
-	/*Use the dof list to index into the solution vector: */
-	for(i=0;i<numdof;i++) values[i]=solution[doflist[i]];
-
-	/*Ok, we have vx and vy in values, fill in vx and vy arrays: */
-	for(i=0;i<NUMVERTICES;i++){
-		lambdax[i]=values[i*NDOF2+0];
-		lambday[i]=values[i*NDOF2+1];
-
-		/*Check solution*/
-		if(xIsNan<IssmDouble>(lambdax[i]))       _error_("NaN found in solution vector");
-		if(xIsNan<IssmDouble>(lambday[i]))       _error_("NaN found in solution vector");
-	}
-
-	/*Add vx and vy as inputs to the tria element: */
-	this->inputs->AddInput(new PentaInput(AdjointxEnum,lambdax,P1Enum));
-	this->inputs->AddInput(new PentaInput(AdjointyEnum,lambday,P1Enum));
-
-	/*Free ressources:*/
-	xDelete<int>(doflist);
-}
-/*}}}*/
 /*FUNCTION Penta::SurfaceAverageVelMisfit {{{*/
 IssmDouble Penta::SurfaceAverageVelMisfit(void){
@@ -6342,10 +3524,10 @@
 
 	/*If on water, return 0: */
-	if(NoIceInElement())return 0;
+	if(!IsIceInElement())return 0;
 
 	/*Bail out if this element if:
 	 * -> Non SSA and not on the surface
 	 * -> SSA (2d model) and not on bed) */
-	if ((approximation!=SSAApproximationEnum && !IsOnSurface()) || (approximation==SSAApproximationEnum && !IsOnBed())){
+	if ((approximation!=SSAApproximationEnum && !IsOnSurface()) || (approximation==SSAApproximationEnum && !IsOnBase())){
 		return 0;
 	}
@@ -6354,5 +3536,5 @@
 		/*This element should be collapsed into a tria element at its base. Create this tria element, 
 		 * and compute SurfaceAverageVelMisfit*/
-		tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.
+		tria=(Tria*)SpawnTria(0,1,2);
 		J=tria->SurfaceAverageVelMisfit();
 		delete tria->material; delete tria;
@@ -6361,5 +3543,5 @@
 	else{
 
-		tria=(Tria*)SpawnTria(1); //lower face is 0, upper face is 1.
+		tria=(Tria*)SpawnTria(3,4,5);
 		J=tria->SurfaceAverageVelMisfit();
 		delete tria->material; delete tria;
@@ -6379,10 +3561,10 @@
 
 	/*If on water, return 0: */
-	if(NoIceInElement())return 0;
+	if(!IsIceInElement())return 0;
 
 	/*Bail out if this element if:
 	 * -> Non SSA and not on the surface
 	 * -> SSA (2d model) and not on bed) */
-	if ((approximation!=SSAApproximationEnum && !IsOnSurface()) || (approximation==SSAApproximationEnum && !IsOnBed())){
+	if ((approximation!=SSAApproximationEnum && !IsOnSurface()) || (approximation==SSAApproximationEnum && !IsOnBase())){
 		return 0;
 	}
@@ -6391,5 +3573,5 @@
 		/*This element should be collapsed into a tria element at its base. Create this tria element, 
 		 * and compute SurfaceAbsVelMisfit*/
-		tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.
+		tria=(Tria*)SpawnTria(0,1,2);
 		J=tria->SurfaceAbsVelMisfit();
 		delete tria->material; delete tria;
@@ -6398,5 +3580,5 @@
 	else{
 
-		tria=(Tria*)SpawnTria(1); //lower face is 0, upper face is 1.
+		tria=(Tria*)SpawnTria(3,4,5);
 		J=tria->SurfaceAbsVelMisfit();
 		delete tria->material; delete tria;
@@ -6416,10 +3598,10 @@
 
 	/*If on water, return 0: */
-	if(NoIceInElement())return 0;
+	if(!IsIceInElement())return 0;
 
 	/*Bail out if this element if:
 	 * -> Non SSA and not on the surface
 	 * -> SSA (2d model) and not on bed) */
-	if ((approximation!=SSAApproximationEnum && !IsOnSurface()) || (approximation==SSAApproximationEnum && !IsOnBed())){
+	if ((approximation!=SSAApproximationEnum && !IsOnSurface()) || (approximation==SSAApproximationEnum && !IsOnBase())){
 		return 0;
 	}
@@ -6428,5 +3610,5 @@
 		/*This element should be collapsed into a tria element at its base. Create this tria element, 
 		 * and compute SurfaceLogVelMisfit*/
-		tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.
+		tria=(Tria*)SpawnTria(0,1,2); //lower face is 0, upper face is 1.
 		J=tria->SurfaceLogVelMisfit();
 		delete tria->material; delete tria;
@@ -6435,5 +3617,5 @@
 	else{
 
-		tria=(Tria*)SpawnTria(1); //lower face is 0, upper face is 1.
+		tria=(Tria*)SpawnTria(3,4,5); //lower face is 0, upper face is 1.
 		J=tria->SurfaceLogVelMisfit();
 		delete tria->material; delete tria;
@@ -6455,10 +3637,10 @@
 
 	/*If on water, return 0: */
-	if(NoIceInElement())return 0;
+	if(!IsIceInElement())return 0;
 
 	/*Bail out if this element if:
 	 * -> Non SSA and not on the surface
 	 * -> SSA (2d model) and not on bed) */
-	if ((approximation!=SSAApproximationEnum && !IsOnSurface()) || (approximation==SSAApproximationEnum && !IsOnBed())){
+	if ((approximation!=SSAApproximationEnum && !IsOnSurface()) || (approximation==SSAApproximationEnum && !IsOnBase())){
 		return 0;
 	}
@@ -6467,5 +3649,5 @@
 		/*This element should be collapsed into a tria element at its base. Create this tria element, 
 		 * and compute SurfaceLogVxVyMisfit*/
-		tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.
+		tria=(Tria*)SpawnTria(0,1,2);
 		J=tria->SurfaceLogVxVyMisfit();
 		delete tria->material; delete tria;
@@ -6474,5 +3656,5 @@
 	else{
 
-		tria=(Tria*)SpawnTria(1); //lower face is 0, upper face is 1.
+		tria=(Tria*)SpawnTria(3,4,5);
 		J=tria->SurfaceLogVxVyMisfit();
 		delete tria->material; delete tria;
@@ -6492,10 +3674,10 @@
 
 	/*If on water, return 0: */
-	if(NoIceInElement())return 0;
+	if(!IsIceInElement())return 0;
 
 	/*Bail out if this element if:
 	 * -> Non SSA and not on the surface
 	 * -> SSA (2d model) and not on bed) */
-	if ((approximation!=SSAApproximationEnum && !IsOnSurface()) || (approximation==SSAApproximationEnum && !IsOnBed())){
+	if ((approximation!=SSAApproximationEnum && !IsOnSurface()) || (approximation==SSAApproximationEnum && !IsOnBase())){
 		return 0;
 	}
@@ -6504,5 +3686,5 @@
 		/*This element should be collapsed into a tria element at its base. Create this tria element, 
 		 * and compute SurfaceRelVelMisfit*/
-		tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.
+		tria=(Tria*)SpawnTria(0,1,2);
 		J=tria->SurfaceRelVelMisfit();
 		delete tria->material; delete tria;
@@ -6511,5 +3693,5 @@
 	else{
 
-		tria=(Tria*)SpawnTria(1); //lower face is 0, upper face is 1.
+		tria=(Tria*)SpawnTria(3,4,5);
 		J=tria->SurfaceRelVelMisfit();
 		delete tria->material; delete tria;
@@ -6535,8 +3717,8 @@
 
 	/*If on water, return 0: */
-	if(NoIceInElement())return 0;
+	if(!IsIceInElement())return 0;
 	_error_("Not implemented yet");
 
-	tria=(Tria*)SpawnTria(0);
+	tria=(Tria*)SpawnTria(0,1,2);
 	J=tria->ThicknessAbsMisfit();
 	delete tria->material; delete tria;
@@ -6551,7 +3733,7 @@
 
 	/*If on water, on shelf or not on bed, skip: */
-	if(NoIceInElement()|| IsFloating() || !IsOnBed()) return 0;
-
-	tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1
+	if(!IsIceInElement()|| IsFloating() || !IsOnBase()) return 0;
+
+	tria=(Tria*)SpawnTria(0,1,2); //lower face is 0, upper face is 1
 	J=tria->DragCoefficientAbsGradient();
 	delete tria->material; delete tria;
@@ -6566,7 +3748,7 @@
 
 	/*If on water, on shelf or not on bed, skip: */
-	if(NoIceInElement() || !IsOnBed()) return 0;
-
-	tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1
+	if(!IsIceInElement() || !IsOnBase()) return 0;
+
+	tria=(Tria*)SpawnTria(0,1,2);
 	J=tria->RheologyBbarAbsGradient();
 	delete tria->material; delete tria;
@@ -6616,11 +3798,5 @@
 	}
 	new_input = new PentaInput(control_enum,values,P1Enum);
-
-	if(control_enum==MaterialsRheologyBbarEnum){
-		input=(Input*)material->inputs->GetInput(control_enum); _assert_(input);
-	}
-	else{
-		input=(Input*)this->inputs->GetInput(control_enum);   _assert_(input);
-	}
+	input=(Input*)this->inputs->GetInput(control_enum);   _assert_(input);
 
 	if (input->ObjectEnum()!=ControlInputEnum){
@@ -6631,5 +3807,4 @@
 }
 /*}}}*/
-#endif
 
 #ifdef _HAVE_DAKOTA_
@@ -6667,5 +3842,5 @@
 					GetInputListOnVertices(&thickness_init[0],ThicknessEnum);
 					GetInputListOnVertices(&hydrostatic_ratio[0],GeometryHydrostaticRatioEnum);
-					GetInputListOnVertices(&bed[0],BedEnum);
+					GetInputListOnVertices(&bed[0],BaseEnum);
 					GetInputListOnVertices(&surface[0],SurfaceEnum);
 
@@ -6720,8 +3895,8 @@
 					/*Add new inputs: */
 					this->inputs->AddInput(new PentaInput(ThicknessEnum,thickness,P1Enum));
-					this->inputs->AddInput(new PentaInput(BedEnum,bed,P1Enum));
+					this->inputs->AddInput(new PentaInput(BaseEnum,bed,P1Enum));
 					this->inputs->AddInput(new PentaInput(SurfaceEnum,surface,P1Enum));
-
 					break;
+
 				default:
 					this->inputs->AddInput(new PentaInput(name,values,P1Enum));
@@ -6775,4021 +3950,4 @@
 /*}}}*/
 #endif
-
-#ifdef _HAVE_STRESSBALANCE_
-/*FUNCTION Penta::CreateDVectorStressbalanceHoriz {{{*/
-ElementVector* Penta::CreateDVectorStressbalanceHoriz(void){
-
-	int approximation;
-	inputs->GetInputValue(&approximation,ApproximationEnum);
-
-	switch(approximation){
-		case FSApproximationEnum:
-			return CreateDVectorStressbalanceFS();
-		default:
-			return NULL; //no need for doftypes outside of FS approximation
-	}
-}
-/*}}}*/
-/*FUNCTION Penta::CreateDVectorStressbalanceFS{{{*/
-ElementVector* Penta::CreateDVectorStressbalanceFS(void){
-
-	/*output: */
-	ElementVector* De=NULL;
-
-	/*Initialize Element vector and return if necessary*/
-	int approximation;
-	inputs->GetInputValue(&approximation,ApproximationEnum);
-	if(approximation!=FSApproximationEnum) return NULL;
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int vnumnodes = this->NumberofNodesVelocity();
-	int pnumnodes = this->NumberofNodesPressure();
-
-	De=new ElementVector(nodes,vnumnodes+pnumnodes,this->parameters,FSvelocityEnum);
-
-	for(int i=0;i<vnumnodes;i++){
-		De->values[i*3+0]=VelocityEnum;
-		De->values[i*3+1]=VelocityEnum;
-		De->values[i*3+2]=VelocityEnum;
-	}
-	for(int i=0;i<pnumnodes;i++){
-		De->values[vnumnodes*3+i]=PressureEnum;
-	}
-
-	return De;
-}
-/*}}}*/
-/*FUNCTION Penta::CreateKMatrixCouplingSSAHO{{{*/
-ElementMatrix* Penta::CreateKMatrixCouplingSSAHO(void){
-
-	/*compute all stiffness matrices for this element*/
-	ElementMatrix* Ke1=CreateKMatrixCouplingSSAHOViscous();
-	ElementMatrix* Ke2=CreateKMatrixCouplingSSAHOFriction();
-	ElementMatrix* Ke=new ElementMatrix(Ke1,Ke2);
-
-	/*clean-up and return*/
-	delete Ke1;
-	delete Ke2;
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Penta::CreateKMatrixCouplingSSAHOViscous{{{*/
-ElementMatrix* Penta::CreateKMatrixCouplingSSAHOViscous(void){
-
-	/*Constants*/
-	const int numnodes    = 2 *NUMVERTICES;
-	const int numdofm     = NDOF2 *NUMVERTICES2D;
-	const int numdofp     = NDOF2 *NUMVERTICES;
-	const int numdoftotal = 2 *NDOF2*NUMVERTICES;
-
-	/*Intermediaries */
-	int         i,j;
-	IssmDouble  Jdet;
-	IssmDouble  viscosity,oldviscosity,newviscosity,viscosity_overshoot; //viscosity
-	IssmDouble  epsilon[5],oldepsilon[5]; /* epsilon=[exx,eyy,exy,exz,eyz];*/
-	IssmDouble  xyz_list[NUMVERTICES][3];
-	IssmDouble  B[3][numdofp];
-	IssmDouble  Bprime[3][numdofm];
-	IssmDouble  D[3][3]={0.0};            // material matrix, simple scalar matrix.
-	IssmDouble  D_scalar;
-	IssmDouble  Ke_gg[numdofp][numdofm]={0.0}; //local element stiffness matrix 
-	IssmDouble  Ke_gg_gaussian[numdofp][numdofm]; //stiffness matrix evaluated at the gaussian point.
-	GaussPenta *gauss=NULL;
-	GaussTria  *gauss_tria=NULL;
-	Node       *node_list[numnodes];
-	int         cs_list[numnodes];
-
-	/*Find penta on bed as HO must be coupled to the dofs on the bed: */
-	Penta* pentabase=GetBasalElement();
-	Tria*  tria=pentabase->SpawnTria(0); //lower face is 0, upper face is 1.
-
-	/*prepare node list*/
-	for(i=0;i<NUMVERTICES;i++){
-		node_list[i+0*NUMVERTICES] = pentabase->nodes[i];
-		node_list[i+1*NUMVERTICES] = this->nodes[i];
-		cs_list[i+0*NUMVERTICES] = XYEnum;
-		cs_list[i+1*NUMVERTICES] = XYEnum;
-	}
-
-	/*Initialize Element matrix*/
-	ElementMatrix* Ke1=new ElementMatrix(pentabase->nodes,NUMVERTICES,this->parameters,SSAApproximationEnum);
-	ElementMatrix* Ke2=new ElementMatrix(this->nodes     ,NUMVERTICES,this->parameters,HOApproximationEnum);
-	ElementMatrix* Ke =new ElementMatrix(Ke1,Ke2);
-	delete Ke1; delete Ke2;
-
-	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	this->parameters->FindParam(&viscosity_overshoot,StressbalanceViscosityOvershootEnum);
-	Input* vx_input=inputs->GetInput(VxEnum);       _assert_(vx_input);
-	Input* vy_input=inputs->GetInput(VyEnum);       _assert_(vy_input);
-	Input* vxold_input=inputs->GetInput(VxPicardEnum); _assert_(vxold_input);
-	Input* vyold_input=inputs->GetInput(VyPicardEnum); _assert_(vyold_input);
-
-	/* Start  looping on the number of gaussian points: */
-	gauss=new GaussPenta(5,5);
-	gauss_tria=new GaussTria();
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-		gauss->SynchronizeGaussTria(gauss_tria);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		GetBSSAHO(&B[0][0], &xyz_list[0][0], gauss);
-		tria->GetBprimeSSA(&Bprime[0][0], &xyz_list[0][0], gauss_tria);
-
-		this->GetStrainRate3dHO(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input);
-		this->GetStrainRate3dHO(&oldepsilon[0],&xyz_list[0][0],gauss,vxold_input,vyold_input);
-		material->GetViscosity3d(&viscosity, &epsilon[0]);
-		material->GetViscosity3d(&oldviscosity, &oldepsilon[0]);
-
-		newviscosity=viscosity+viscosity_overshoot*(viscosity-oldviscosity);
-		D_scalar=2*newviscosity*gauss->weight*Jdet;
-		for (i=0;i<3;i++) D[i][i]=D_scalar;
-
-		TripleMultiply( &B[0][0],3,numdofp,1,
-					&D[0][0],3,3,0,
-					&Bprime[0][0],3,numdofm,0,
-					&Ke_gg_gaussian[0][0],0);
-
-		for( i=0; i<numdofp; i++) for(j=0;j<numdofm; j++) Ke_gg[i][j]+=Ke_gg_gaussian[i][j];
-	} 
-	for(i=0;i<numdofp;i++) for(j=0;j<numdofm;j++) Ke->values[(i+2*numdofm)*numdoftotal+j]+=Ke_gg[i][j];
-	for(i=0;i<numdofm;i++) for(j=0;j<numdofp;j++) Ke->values[i*numdoftotal+(j+2*numdofm)]+=Ke_gg[j][i];
-
-	/*Transform Coordinate System*/
-	TransformStiffnessMatrixCoord(Ke,node_list,numnodes,cs_list);
-
-	/*Clean-up and return*/
-	delete tria->material; delete tria;
-	delete gauss;
-	delete gauss_tria;
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Penta::CreateKMatrixCouplingSSAHOFriction{{{*/
-ElementMatrix* Penta::CreateKMatrixCouplingSSAHOFriction(void){
-
-	/*Constants*/
-	const int numnodes    = 2 *NUMVERTICES;
-	const int numdof      = NDOF2 *NUMVERTICES;
-	const int numdoftotal = NDOF4 *NUMVERTICES;
-
-	/*Intermediaries */
-	int       i,j,analysis_type;
-	IssmDouble Jdet2d,alpha2;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble xyz_list_tria[NUMVERTICES2D][3]={0.0};
-	IssmDouble L[2][numdof];
-	IssmDouble DL[2][2]                  ={{ 0,0 },{0,0}}; //for basal drag
-	IssmDouble DL_scalar;
-	IssmDouble Ke_gg[numdof][numdof]     ={0.0};
-	IssmDouble Ke_gg_gaussian[numdof][numdof]; //stiffness matrix contribution from drag
-	Friction  *friction = NULL;
-	GaussPenta *gauss=NULL;
-	Node       *node_list[numnodes];
-	int         cs_list[numnodes];
-
-	/*Initialize Element matrix and return if necessary*/
-	if(IsFloating() || !IsOnBed()) return NULL;
-	ElementMatrix* Ke1=new ElementMatrix(nodes,NUMVERTICES,this->parameters,SSAApproximationEnum);
-	ElementMatrix* Ke2=new ElementMatrix(nodes,NUMVERTICES,this->parameters,HOApproximationEnum);
-	ElementMatrix* Ke=new ElementMatrix(Ke1,Ke2);
-	delete Ke1; delete Ke2;
-
-	/*Prepare node list*/
-	for(i=0;i<NUMVERTICES;i++){
-		node_list[i+0*NUMVERTICES] = this->nodes[i];
-		node_list[i+1*NUMVERTICES] = this->nodes[i];
-		cs_list[i+0*NUMVERTICES] = XYEnum;
-		cs_list[i+1*NUMVERTICES] = XYEnum;
-	}
-
-	/*retrieve inputs :*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	for(i=0;i<NUMVERTICES2D;i++) for(j=0;j<3;j++) xyz_list_tria[i][j]=xyz_list[i][j];
-	parameters->FindParam(&analysis_type,AnalysisTypeEnum);
-	Input* vx_input=inputs->GetInput(VxEnum);           _assert_(vx_input);
-	Input* vy_input=inputs->GetInput(VyEnum);           _assert_(vy_input);
-	Input* vz_input=inputs->GetInput(VzEnum);           _assert_(vz_input);
-
-	/*build friction object, used later on: */
-	friction=new Friction("2d",inputs,matpar,analysis_type);
-
-	/* Start  looping on the number of gaussian points: */
-	gauss=new GaussPenta(0,1,2,2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		/*Friction: */
-		friction->GetAlpha2(&alpha2, gauss,VxEnum,VyEnum,VzEnum);
-
-		GetTriaJacobianDeterminant(&Jdet2d, &xyz_list_tria[0][0],gauss);
-		GetBHOFriction(&L[0][0],gauss);
-
-		DL_scalar=alpha2*gauss->weight*Jdet2d;
-		for (i=0;i<2;i++) DL[i][i]=DL_scalar; 
-
-		/*  Do the triple producte tL*D*L: */
-		TripleMultiply( &L[0][0],2,numdof,1,
-					&DL[0][0],2,2,0,
-					&L[0][0],2,numdof,0,
-					&Ke_gg_gaussian[0][0],0);
-
-		for(i=0;i<numdof;i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg_gaussian[i][j];
-	}
-
-	for(i=0;i<numdof;i++) for(j=0;j<numdof;j++) Ke->values[i*numdoftotal+(numdof+j)]+=Ke_gg[i][j];
-	for(i=0;i<numdof;i++) for(j=0;j<numdof;j++) Ke->values[(i+numdof)*numdoftotal+j]+=Ke_gg[i][j];
-
-	/*Transform Coordinate System*/
-	TransformStiffnessMatrixCoord(Ke,node_list,numnodes,cs_list);
-
-	/*Clean up and return*/
-	delete gauss;
-	delete friction;
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Penta::CreateKMatrixCouplingSSAFS{{{*/
-ElementMatrix* Penta::CreateKMatrixCouplingSSAFS(void){
-
-	/*compute all stiffness matrices for this element*/
-	ElementMatrix* Ke1=CreateKMatrixCouplingSSAFSViscous();
-	ElementMatrix* Ke2=CreateKMatrixCouplingSSAFSFriction();
-	ElementMatrix* Ke =new ElementMatrix(Ke1,Ke2);
-
-	/*clean-up and return*/
-	delete Ke1;
-	delete Ke2;
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Penta::CreateKMatrixCouplingSSAFSViscous{{{*/
-ElementMatrix* Penta::CreateKMatrixCouplingSSAFSViscous(void){
-
-	/*Constants*/
-	const int numdofm     = NDOF2 *NUMVERTICES2D;
-	const int numdofs     = NDOF4 *NUMVERTICES + NDOF3;
-	const int numdoftotal = 2 *numdofm+numdofs;
-
-	/*Intermediaries */
-	int        i,j;
-	IssmDouble Jdet;
-	IssmDouble viscosity,FSreconditioning; //viscosity
-	IssmDouble epsilon[6]; /* epsilon=[exx,eyy,exy,exz,eyz];*/
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble B[4][numdofs];
-	IssmDouble Bprime[4][numdofm];
-	IssmDouble B2[3][numdofm];
-	IssmDouble Bprime2[3][numdofs];
-	IssmDouble D[4][4]={0.0};            // material matrix, simple scalar matrix.
-	IssmDouble D2[3][3]={0.0};            // material matrix, simple scalar matrix.
-	IssmDouble D_scalar;
-	IssmDouble Ke_gg[numdofs][numdofm]={0.0}; //local element stiffness matrix 
-	IssmDouble Ke_gg2[numdofm][numdofs]={0.0}; //local element stiffness matrix 
-	IssmDouble Ke_gg_gaussian[numdofs][numdofm]; //stiffness matrix evaluated at the gaussian point.
-	IssmDouble Ke_gg_gaussian2[numdofm][numdofs]; //stiffness matrix evaluated at the gaussian point.
-	GaussPenta *gauss=NULL;
-	GaussTria  *gauss_tria=NULL;
-	Node       *node_list[20];
-
-	/*Find penta on bed as FS must be coupled to the dofs on the bed: */
-	Penta* pentabase=GetBasalElement();
-	Tria* tria=pentabase->SpawnTria(0); //lower face is 0, upper face is 1.
-
-	int vnumnodes = this->NumberofNodesVelocity();
-	int pnumnodes = this->NumberofNodesPressure();
-	int numnodes  = 2*vnumnodes-1+pnumnodes;
-
-	/*Prepare node list*/
-	int* cs_list = xNew<int>(2*vnumnodes+pnumnodes);
-	for(i=0;i<vnumnodes-1;i++){
-		node_list[i] = pentabase->nodes[i];
-		cs_list[i] = XYEnum;
-	}
-	for(i=0;i<vnumnodes;i++){
-		node_list[i+vnumnodes-1] = this->nodes[i];
-		cs_list[i+vnumnodes-1] = XYZEnum;
-	}
-	for(i=0;i<pnumnodes;i++){
-		node_list[2*vnumnodes-1+i] = this->nodes[vnumnodes+i];
-		cs_list[2*vnumnodes-1+i] = PressureEnum;
-	}
-
-	/*Initialize Element matrix and return if necessary*/
-	ElementMatrix* Ke1=new ElementMatrix(pentabase->nodes,NUMVERTICES,    this->parameters,SSAApproximationEnum);
-	ElementMatrix* Ke2=new ElementMatrix(this->nodes     ,2*NUMVERTICES+1,this->parameters,FSvelocityEnum);
-	ElementMatrix* Ke =new ElementMatrix(Ke1,Ke2);
-	delete Ke1; delete Ke2;
-
-	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	parameters->FindParam(&FSreconditioning,StressbalanceFSreconditioningEnum);
-	Input* vx_input=inputs->GetInput(VxEnum);       _assert_(vx_input);
-	Input* vy_input=inputs->GetInput(VyEnum);       _assert_(vy_input);
-	Input* vz_input=inputs->GetInput(VzEnum);       _assert_(vz_input);
-
-	/* Start  looping on the number of gaussian points: */
-	gauss=new GaussPenta(5,5);
-	gauss_tria=new GaussTria();
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-		gauss->SynchronizeGaussTria(gauss_tria);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		GetBSSAFS(&B[0][0], &xyz_list[0][0], gauss);
-		tria->GetBprimeSSAFS(&Bprime[0][0], &xyz_list[0][0], gauss_tria);
-		tria->GetBSSAFS(&B2[0][0], &xyz_list[0][0], gauss_tria);
-		GetBprimeSSAFS(&Bprime2[0][0], &xyz_list[0][0], gauss);
-
-		this->GetStrainRate3d(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input,vz_input);
-		material->GetViscosity3dFS(&viscosity, &epsilon[0]);
-
-		D_scalar=2*viscosity*gauss->weight*Jdet;
-		for (i=0;i<3;i++) D[i][i]=D_scalar;
-		D[3][3]=-gauss->weight*Jdet*FSreconditioning;
-		for (i=0;i<3;i++) D2[i][i]=D_scalar;
-
-		TripleMultiply( &B[0][0],4,numdofs,1,
-					&D[0][0],4,4,0,
-					&Bprime[0][0],4,numdofm,0,
-					&Ke_gg_gaussian[0][0],0);
-
-		TripleMultiply( &B2[0][0],3,numdofm,1,
-					&D2[0][0],3,3,0,
-					&Bprime2[0][0],3,numdofs,0,
-					&Ke_gg_gaussian2[0][0],0);
-
-		for( i=0; i<numdofs; i++) for(j=0;j<numdofm; j++)      Ke_gg[i][j]+=Ke_gg_gaussian[i][j];
-		for( i=0; i<numdofm; i++)      for(j=0;j<numdofs; j++) Ke_gg2[i][j]+=Ke_gg_gaussian2[i][j];
-	} 
-	for(i=0;i<numdofs;i++) for(j=0;j<numdofm;j++)      Ke->values[(i+2*numdofm)*numdoftotal+j]+=Ke_gg[i][j];
-	for(i=0;i<numdofm;i++)      for(j=0;j<numdofs;j++) Ke->values[i*numdoftotal+(j+2*numdofm)]+=Ke_gg2[i][j];
-
-	/*Transform Coordinate System*/
-	TransformStiffnessMatrixCoord(Ke,node_list,numnodes,cs_list);
-
-	/*Clean-up and return*/
-	xDelete<int>(cs_list);
-	delete tria->material; delete tria;
-	delete gauss;
-	delete gauss_tria;
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Penta::CreateKMatrixCouplingSSAFSFriction {{{*/
-ElementMatrix* Penta::CreateKMatrixCouplingSSAFSFriction(void){
-	/*Constants*/
-	const int numdofs   = (NUMVERTICES+1)*NDOF3 + NUMVERTICES*NDOF1;
-	const int numdofm   = NUMVERTICES *NDOF2;
-	const int numdof2d  = NUMVERTICES2D *NDOF3;
-	const int numdof2dm = NUMVERTICES2D *NDOF2;
-	const int numdoftot = NUMVERTICES*2 + (NUMVERTICES+1)*3 +NUMVERTICES; // HO + FS vel + FS Pressure
-
-	/*Intermediaries */
-	int        i,j;
-	int        analysis_type,approximation;
-	IssmDouble FSreconditioning;
-	IssmDouble viscosity,alpha2_gauss,Jdet2d;
-	IssmDouble bed_normal[3];
-	IssmDouble epsilon[6]; /* epsilon=[exx,eyy,ezz,exy,exz,eyz];*/
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble xyz_list_tria[NUMVERTICES2D][3];
-	IssmDouble LSSAFS[8][numdof2dm];
-	IssmDouble LprimeSSAFS[8][numdofs];
-	IssmDouble DLSSAFS[8][8]={0.0};
-	IssmDouble LFSSSA[4][numdof2d];
-	IssmDouble LprimeFSSSA[4][numdof2dm];
-	IssmDouble DLFSSSA[4][4]={0.0};
-	IssmDouble Ke_drag_gaussian[numdof2dm][numdofs];
-	IssmDouble Ke_drag_gaussian2[numdof2d][numdof2dm];
-	Friction*  friction=NULL;
-	GaussPenta *gauss=NULL;
-	Node       *node_list[20];
-
-	/*If on water or not FS, skip stiffness: */
-	inputs->GetInputValue(&approximation,ApproximationEnum);
-	if(IsFloating() || !IsOnBed()) return NULL;
-
-	int vnumnodes = this->NumberofNodesVelocity();
-	int pnumnodes = this->NumberofNodesPressure();
-	int numnodes  = 2*vnumnodes-1+pnumnodes;
-
-	/*Prepare node list*/
-	int* cs_list = xNew<int>(2*vnumnodes+pnumnodes);
-	for(i=0;i<vnumnodes-1;i++){
-		node_list[i] = this->nodes[i];
-		cs_list[i] = XYEnum;
-	}
-	for(i=0;i<vnumnodes;i++){
-		node_list[i+vnumnodes-1] = this->nodes[i];
-		cs_list[i+vnumnodes-1] = XYZEnum;
-	}
-	for(i=0;i<pnumnodes;i++){
-		node_list[2*vnumnodes-1+i] = this->nodes[vnumnodes+i];
-		cs_list[2*vnumnodes-1+i] = PressureEnum;
-	}
-
-	ElementMatrix* Ke1=new ElementMatrix(this->nodes,NUMVERTICES,        this->parameters,SSAApproximationEnum);
-	ElementMatrix* Ke2=new ElementMatrix(this->nodes,vnumnodes+pnumnodes,this->parameters,FSvelocityEnum);
-	ElementMatrix* Ke=new ElementMatrix(Ke1,Ke2);
-	delete Ke1; delete Ke2;
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	parameters->FindParam(&analysis_type,AnalysisTypeEnum);
-	parameters->FindParam(&FSreconditioning,StressbalanceFSreconditioningEnum);
-	Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);
-	Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);
-	Input* vz_input=inputs->GetInput(VzEnum); _assert_(vz_input);
-	for(i=0;i<NUMVERTICES2D;i++) for(j=0;j<3;j++) xyz_list_tria[i][j]=xyz_list[i][j];
-
-	/*build friction object, used later on: */
-	friction=new Friction("3d",inputs,matpar,analysis_type);
-
-	/* Start  looping on the number of gaussian points: */
-	gauss=new GaussPenta(0,1,2,2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetTriaJacobianDeterminant(&Jdet2d, &xyz_list_tria[0][0],gauss);
-		GetLSSAFS(&LSSAFS[0][0], gauss);
-		GetLprimeSSAFS(&LprimeSSAFS[0][0], &xyz_list[0][0], gauss);
-		GetLFSSSA(&LFSSSA[0][0], gauss);
-		GetLprimeFSSSA(&LprimeFSSSA[0][0], &xyz_list[0][0], gauss);
-
-		this->GetStrainRate3d(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input,vz_input);
-		material->GetViscosity3dFS(&viscosity,&epsilon[0]);
-
-		BedNormal(&bed_normal[0],xyz_list_tria);
-		friction->GetAlpha2(&alpha2_gauss, gauss,VxEnum,VyEnum,VzEnum);
-
-		DLSSAFS[0][0]=alpha2_gauss*gauss->weight*Jdet2d;
-		DLSSAFS[1][1]=alpha2_gauss*gauss->weight*Jdet2d;
-		DLSSAFS[2][2]=-alpha2_gauss*gauss->weight*Jdet2d*bed_normal[0]*bed_normal[2];
-		DLSSAFS[3][3]=-alpha2_gauss*gauss->weight*Jdet2d*bed_normal[1]*bed_normal[2];
-		DLSSAFS[4][4]=-2*viscosity*gauss->weight*Jdet2d*bed_normal[0];
-		DLSSAFS[5][5]=-2*viscosity*gauss->weight*Jdet2d*bed_normal[1];
-		DLSSAFS[6][6]=FSreconditioning*gauss->weight*Jdet2d*bed_normal[0];
-		DLSSAFS[7][7]=FSreconditioning*gauss->weight*Jdet2d*bed_normal[1];
-
-		DLFSSSA[0][0]=alpha2_gauss*gauss->weight*Jdet2d;
-		DLFSSSA[1][1]=alpha2_gauss*gauss->weight*Jdet2d;
-		DLFSSSA[2][2]=-alpha2_gauss*gauss->weight*Jdet2d*bed_normal[0]*bed_normal[2];
-		DLFSSSA[3][3]=-alpha2_gauss*gauss->weight*Jdet2d*bed_normal[1]*bed_normal[2];
-
-		TripleMultiply( &LSSAFS[0][0],8,numdof2dm,1,
-					&DLSSAFS[0][0],8,8,0,
-					&LprimeSSAFS[0][0],8,numdofs,0,
-					&Ke_drag_gaussian[0][0],0);
-
-		TripleMultiply( &LFSSSA[0][0],4,numdof2d,1,
-					&DLFSSSA[0][0],4,4,0,
-					&LprimeFSSSA[0][0],4,numdof2dm,0,
-					&Ke_drag_gaussian2[0][0],0);
-		for(i=0;i<numdof2dm;i++) for(j=0;j<numdofs;j++) Ke->values[i*numdoftot+j+numdofm]+=Ke_drag_gaussian[i][j];
-		for(i=0;i<numdof2d;i++) for(j=0;j<numdof2dm;j++) Ke->values[(i+numdofm)*numdoftot+j]+=Ke_drag_gaussian2[i][j];
-	}
-
-	/*Transform Coordinate System*/
-	TransformStiffnessMatrixCoord(Ke,node_list,numnodes,cs_list);
-
-	/*Clean up and return*/
-	xDelete<int>(cs_list);
-	delete gauss;
-	delete friction;
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Penta::CreateKMatrixCouplingHOFS{{{*/
-ElementMatrix* Penta::CreateKMatrixCouplingHOFS(void){
-
-	/*Constants*/
-	const int numnodes       = 3 *NUMVERTICES+1;
-	const int numdofp        = NDOF2 *NUMVERTICES;
-	const int numdofs        = NDOF4 * 6 + NDOF3;
-	const int numdoftotal    = (NDOF2+NDOF4) *NUMVERTICES + NDOF3;
-
-	/*Intermediaries*/
-	int   i,j,init;
-	Node  *node_list[NUMVERTICES*3+1];
-	int   cs_list[NUMVERTICES*3+1];
-	int   cs_list2[NUMVERTICES*2+1];
-
-	/*Some parameters needed*/
-	init=this->element_type;
-
-	/*prepare node list*/
-	for(i=0;i<NUMVERTICES+1;i++){
-		node_list[i+NUMVERTICES] = this->nodes[i];
-		cs_list[i+NUMVERTICES]   = XYZEnum;
-		cs_list2[i]              = XYZEnum;
-	}
-	for(i=0;i<NUMVERTICES;i++){
-		node_list[i]                 = this->nodes[i];
-		node_list[i+2*NUMVERTICES+1] = this->nodes[i+NUMVERTICES+1];
-		cs_list[i]                   = XYEnum;
-		cs_list[i+2*NUMVERTICES+1]   = PressureEnum;
-		cs_list2[i+NUMVERTICES+1]    = PressureEnum;
-	}
-
-	/*compute all stiffness matrices for this element*/
-	ElementMatrix* Ke1=new ElementMatrix(this->nodes,NUMVERTICES,this->parameters,HOApproximationEnum);
-	ElementMatrix* Ke2=new ElementMatrix(this->nodes,2*NUMVERTICES+1,this->parameters,FSvelocityEnum);
-	ElementMatrix* Ke=new ElementMatrix(Ke1,Ke2);
-	delete Ke1; delete Ke2;
-
-	/*Compute HO Matrix with P1 element type\n");*/
-	this->element_type=P1Enum;
-	Ke1=CreateKMatrixStressbalanceHO(); TransformInvStiffnessMatrixCoord(Ke1,this->nodes,NUMVERTICES,XYEnum);
-	this->element_type=init;
-	/*Compute FS Matrix and condense it \n");*/
-	Ke2=CreateKMatrixStressbalanceFS(); TransformInvStiffnessMatrixCoord(Ke2,this->nodes,2*NUMVERTICES+1,cs_list2);
-	int indices[3]={18,19,20};
-	Ke2->StaticCondensation(3,&indices[0]);
-
-	for(i=0;i<numdofs;i++) for(j=0;j<NUMVERTICES;j++){
-		Ke->values[(i+numdofp)*numdoftotal+NDOF2*j+0]+=Ke2->values[i*numdofs+NDOF3*j+0];
-		Ke->values[(i+numdofp)*numdoftotal+NDOF2*j+1]+=Ke2->values[i*numdofs+NDOF3*j+1];
-	}
-	for(i=0;i<numdofp;i++) for(j=0;j<NUMVERTICES;j++){
-		Ke->values[i*numdoftotal+numdofp+NDOF3*j+0]+=Ke1->values[i*numdofp+NDOF2*j+0];
-		Ke->values[i*numdoftotal+numdofp+NDOF3*j+1]+=Ke1->values[i*numdofp+NDOF2*j+1];
-	}
-
-	/*Transform Coordinate System*/ //Do not transform, already done in the matrices
-	TransformStiffnessMatrixCoord(Ke,node_list,numnodes,cs_list);
-
-	/*clean-up and return*/
-	delete Ke1;
-	delete Ke2;
-	return Ke;
-}
-//*}}}*/
-/*FUNCTION Penta::CreateKMatrixStressbalanceHoriz {{{*/
-ElementMatrix* Penta::CreateKMatrixStressbalanceHoriz(void){
-
-	int approximation;
-	inputs->GetInputValue(&approximation,ApproximationEnum);
-	switch(approximation){
-		case SSAApproximationEnum:
-			return CreateKMatrixStressbalanceSSA2d();
-		case L1L2ApproximationEnum:
-			return CreateKMatrixStressbalanceL1L2();
-		case HOApproximationEnum:
-			return CreateKMatrixStressbalanceHO();
-		case FSApproximationEnum:
-			return CreateKMatrixStressbalanceFS();
-		case SIAApproximationEnum:
-			return NULL;
-		case NoneApproximationEnum:
-			return NULL;
-		case SSAHOApproximationEnum:
-			return CreateKMatrixStressbalanceSSAHO();
-		case SSAFSApproximationEnum:
-			return CreateKMatrixStressbalanceSSAFS();
-		case HOFSApproximationEnum:
-			return CreateKMatrixStressbalanceHOFS();
-		default:
-			_error_("Approximation " << EnumToStringx(approximation) << " not supported yet");
-	}
-}
-/*}}}*/
-/*FUNCTION Penta::CreateKMatrixStressbalanceSIA{{{*/
-ElementMatrix* Penta::CreateKMatrixStressbalanceSIA(void){
-
-	/*Intermediaries*/
-	IssmDouble connectivity[2];
-	IssmDouble one0,one1;
-	int        i,i0,i1,j0,j1;
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodes(); _assert_(numnodes==6); 
-	int numdof   = numnodes*NDOF2;
-
-	/*Initialize Element matrix*/
-	ElementMatrix* Ke=new ElementMatrix(nodes,numnodes,this->parameters,NoneApproximationEnum);
-
-	/*3 vertical edges*/
-	for(i=0;i<3;i++){
-
-		/*2 dofs of first node*/
-		i0=2*i;     i1=2*i+1;
-		/*2 dofs of second node*/
-		j0=2*(i+3); j1=2*(i+3)+1;
-
-		/*Find connectivity for the two nodes*/
-		connectivity[0]=(IssmDouble)vertices[i]->Connectivity();
-		connectivity[1]=(IssmDouble)vertices[i+3]->Connectivity();
-		one0=1./connectivity[0];
-		one1=1./connectivity[1];
-
-		/*Create matrix for these two nodes*/
-		if (IsOnBed() && IsOnSurface()){
-			Ke->values[i0*numdof+i0] = +one0;
-			Ke->values[i1*numdof+i1] = +one0;
-			Ke->values[j0*numdof+i0] = -one1;
-			Ke->values[j0*numdof+j0] = +one1;
-			Ke->values[j1*numdof+i1] = -one1;
-			Ke->values[j1*numdof+j1] = +one1;
-		}
-		else if (IsOnBed()){
-			Ke->values[i0*numdof+i0] = one0;
-			Ke->values[i1*numdof+i1] = one0;
-			Ke->values[j0*numdof+i0] = -2.*one1;
-			Ke->values[j0*numdof+j0] = +2.*one1;
-			Ke->values[j1*numdof+i1] = -2.*one1;
-			Ke->values[j1*numdof+j1] = +2.*one1;
-		}
-		else if (IsOnSurface()){
-			Ke->values[j0*numdof+i0] = -one1;
-			Ke->values[j0*numdof+j0] = +one1;
-			Ke->values[j1*numdof+i1] = -one1;
-			Ke->values[j1*numdof+j1] = +one1;
-		}
-		else{ //node is on two horizontal layers and beams include the values only once, so the have to use half of the connectivity
-			Ke->values[j0*numdof+i0] = -2.*one1;
-			Ke->values[j0*numdof+j0] = +2.*one1;
-			Ke->values[j1*numdof+i1] = -2.*one1;
-			Ke->values[j1*numdof+j1] = +2.*one1;
-		}
-	}
-
-	/*Clean up and return*/
-	return Ke;
-}/*}}}*/
-/*FUNCTION Penta::CreateKMatrixStressbalanceSSA2d{{{*/
-ElementMatrix* Penta::CreateKMatrixStressbalanceSSA2d(void){
-
-	/*Figure out if this penta is collapsed. If so, then bailout, except if it is at the 
-	  bedrock, in which case we spawn a tria element using the 3 first nodes, and use it to build 
-	  the stiffness matrix. */
-	if (!IsOnBed()) return NULL;
-
-	/*Depth average some fields*/
-	switch(this->material->ObjectEnum()){
-		case MaticeEnum:
-			this->InputDepthAverageAtBase(MaterialsRheologyBEnum,MaterialsRheologyBbarEnum,MaterialsEnum);
-			this->InputDepthAverageAtBase(DamageDEnum,DamageDbarEnum,MaterialsEnum);
-			break;
-		default:
-			_error_("material "<<EnumToStringx(this->material->ObjectEnum())<<" not supported");
-	}
-
-	/*Call Tria function*/
-	Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.
-	ElementMatrix* Ke=tria->CreateKMatrixStressbalanceSSA();
-	delete tria->material; delete tria;
-
-	/*Delete averaged fields*/
-	this->material->inputs->DeleteInput(MaterialsRheologyBbarEnum);
-	this->material->inputs->DeleteInput(DamageDbarEnum);
-
-	/*clean up and return*/
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Penta::CreateKMatrixStressbalanceSSA3d{{{*/
-ElementMatrix* Penta::CreateKMatrixStressbalanceSSA3d(void){
-
-	/*compute all stiffness matrices for this element*/
-	ElementMatrix* Ke1=CreateKMatrixStressbalanceSSA3dViscous();
-	ElementMatrix* Ke2=CreateKMatrixStressbalanceSSA3dFriction();
-	ElementMatrix* Ke =new ElementMatrix(Ke1,Ke2);
-
-	/*clean-up and return*/
-	delete Ke1;
-	delete Ke2;
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Penta::CreateKMatrixStressbalanceSSA3dViscous{{{*/
-ElementMatrix* Penta::CreateKMatrixStressbalanceSSA3dViscous(void){
-
-	/*Constants*/
-	const int    numdof2d=2*NUMVERTICES2D;
-
-	/*Intermediaries */
-	int         i,j,approximation;
-	IssmDouble  Jdet;
-	IssmDouble  viscosity , oldviscosity, newviscosity, viscosity_overshoot;
-	IssmDouble  epsilon[5],oldepsilon[5];       /* epsilon=[exx,eyy,exy,exz,eyz];*/
-	IssmDouble  epsilons[6];                    //6 for FS
-	IssmDouble  xyz_list[NUMVERTICES][3];
-	IssmDouble  B[3][numdof2d];
-	IssmDouble  Bprime[3][numdof2d];
-	IssmDouble  D[3][3]= {0.0};                 // material matrix, simple scalar matrix.
-	IssmDouble  D_scalar;
-	IssmDouble  Ke_gg_gaussian[numdof2d][numdof2d];
-	Tria       *tria       = NULL;
-	Penta      *pentabase  = NULL;
-	GaussPenta *gauss      = NULL;
-	GaussTria  *gauss_tria = NULL;
-
-	/*Find penta on bed as this is a SSA elements: */
-	pentabase=GetBasalElement();
-	tria=pentabase->SpawnTria(0); //lower face is 0, upper face is 1.
-
-	/*Initialize Element matrix*/
-	ElementMatrix* Ke=new ElementMatrix(tria->nodes,NUMVERTICES2D,this->parameters,SSAApproximationEnum);
-	inputs->GetInputValue(&approximation,ApproximationEnum);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	this->parameters->FindParam(&viscosity_overshoot,StressbalanceViscosityOvershootEnum);
-	Input* vx_input=inputs->GetInput(VxEnum);       _assert_(vx_input);
-	Input* vy_input=inputs->GetInput(VyEnum);       _assert_(vy_input);
-	Input* vxold_input=inputs->GetInput(VxPicardEnum); _assert_(vxold_input);
-	Input* vyold_input=inputs->GetInput(VyPicardEnum); _assert_(vyold_input);
-	Input* vz_input=inputs->GetInput(VzEnum);       _assert_(vz_input);
-
-	/* Start  looping on the number of gaussian points: */
-	gauss=new GaussPenta(5,5);
-	gauss_tria=new GaussTria();
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-		gauss->SynchronizeGaussTria(gauss_tria);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		tria->GetBSSA(&B[0][0], &xyz_list[0][0], gauss_tria);
-		tria->GetBprimeSSA(&Bprime[0][0], &xyz_list[0][0], gauss_tria);
-
-		if(approximation==SSAHOApproximationEnum){
-			this->GetStrainRate3dHO(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input);
-			this->GetStrainRate3dHO(&oldepsilon[0],&xyz_list[0][0],gauss,vxold_input,vyold_input);
-			material->GetViscosity3d(&viscosity, &epsilon[0]);
-			material->GetViscosity3d(&oldviscosity, &oldepsilon[0]);
-
-			newviscosity=viscosity+viscosity_overshoot*(viscosity-oldviscosity);
-		}
-		else if (approximation==SSAFSApproximationEnum){
-			this->GetStrainRate3d(&epsilons[0],&xyz_list[0][0],gauss,vx_input,vy_input,vz_input);
-			material->GetViscosity3dFS(&newviscosity,&epsilons[0]);
-		}
-		else _error_("approximation " << approximation << " (" << EnumToStringx(approximation) << ") not supported yet");
-
-		D_scalar=2*newviscosity*gauss->weight*Jdet;
-		for (i=0;i<3;i++) D[i][i]=D_scalar;
-
-		TripleMultiply( &B[0][0],3,numdof2d,1,
-					&D[0][0],3,3,0,
-					&Bprime[0][0],3,numdof2d,0,
-					&Ke_gg_gaussian[0][0],0);
-
-		for(i=0;i<numdof2d;i++) for(j=0;j<numdof2d;j++) Ke->values[i*numdof2d+j]+=Ke_gg_gaussian[i][j];
-	}
-
-	/*Transform Coordinate System*/
-	TransformStiffnessMatrixCoord(Ke,tria->nodes,NUMVERTICES2D,XYEnum);
-
-	/*Clean up and return*/
-	delete tria->material;
-	delete tria;
-	delete gauss_tria;
-	delete gauss;
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Penta::CreateKMatrixStressbalanceSSA3dFriction{{{*/
-ElementMatrix* Penta::CreateKMatrixStressbalanceSSA3dFriction(void){
-
-	/*Initialize Element matrix and return if necessary*/
-	if(IsFloating() || !IsOnBed()) return NULL;
-
-	/*Build a tria element using the 3 nodes of the base of the penta. Then use 
-	 * the tria functionality to build a friction stiffness matrix on these 3
-	 * nodes: */
-	Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.
-	ElementMatrix* Ke=tria->CreateKMatrixStressbalanceSSAFriction();
-	delete tria->material; delete tria;
-
-	/*clean-up and return*/
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Penta::CreateKMatrixStressbalanceSSAHO{{{*/
-ElementMatrix* Penta::CreateKMatrixStressbalanceSSAHO(void){
-
-	/*compute all stiffness matrices for this element*/
-	ElementMatrix* Ke1=CreateKMatrixStressbalanceSSA3d();
-	ElementMatrix* Ke2=CreateKMatrixStressbalanceHO();
-	ElementMatrix* Ke3=CreateKMatrixCouplingSSAHO();
-	ElementMatrix* Ke =new ElementMatrix(Ke1,Ke2,Ke3);
-
-	/*clean-up and return*/
-	delete Ke1;
-	delete Ke2;
-	delete Ke3;
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Penta::CreateKMatrixStressbalanceSSAFS{{{*/
-ElementMatrix* Penta::CreateKMatrixStressbalanceSSAFS(void){
-
-	/*compute all stiffness matrices for this element*/
-	ElementMatrix* Ke1=CreateKMatrixStressbalanceFS();
-	int indices[3]={18,19,20};
-	Ke1->StaticCondensation(3,&indices[0]);
-	int init = this->element_type;
-	this->element_type=P1Enum; //P1 needed for HO 
-	ElementMatrix* Ke2=CreateKMatrixStressbalanceSSA3d();
-	this->element_type=init;
-	ElementMatrix* Ke3=CreateKMatrixCouplingSSAFS();
-	ElementMatrix* Ke =new ElementMatrix(Ke1,Ke2,Ke3);
-
-	/*clean-up and return*/
-	delete Ke1;
-	delete Ke2;
-	delete Ke3;
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Penta::CreateKMatrixStressbalanceL1L2{{{*/
-ElementMatrix* Penta::CreateKMatrixStressbalanceL1L2(void){
-
-	/*compute all stiffness matrices for this element*/
-	ElementMatrix* Ke1=CreateKMatrixStressbalanceL1L2Viscous();
-	ElementMatrix* Ke2=CreateKMatrixStressbalanceL1L2Friction();
-	ElementMatrix* Ke =new ElementMatrix(Ke1,Ke2);
-
-	/*clean-up and return*/
-	delete Ke1;
-	delete Ke2;
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Penta::CreateKMatrixStressbalanceL1L2Viscous{{{*/
-ElementMatrix* Penta::CreateKMatrixStressbalanceL1L2Viscous(void){
-
-	/*Constants*/
-	const int    numdof2d=2*NUMVERTICES2D;
-
-	/*Intermediaries */
-	int         i,j;
-	IssmDouble  Jdet,viscosity;
-	IssmDouble  xyz_list[NUMVERTICES][3];
-	IssmDouble  B[3][numdof2d];
-	IssmDouble  Bprime[3][numdof2d];
-	IssmDouble  Ke_gg_gaussian[numdof2d][numdof2d];
-	IssmDouble  D[3][3]= {0.0};                 // material matrix, simple scalar matrix.
-	Tria       *tria       = NULL;
-	Penta      *pentabase  = NULL;
-	GaussPenta *gauss      = NULL;
-	GaussTria  *gauss_tria = NULL;
-
-	/*Find penta on bed as this is a SSA elements: */
-	pentabase=GetBasalElement();
-	tria=pentabase->SpawnTria(0); //lower face is 0, upper face is 1.
-
-	/*Initialize Element matrix*/
-	ElementMatrix* Ke=new ElementMatrix(tria->nodes,NUMVERTICES2D,this->parameters,L1L2ApproximationEnum);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	Input* vx_input=inputs->GetInput(VxEnum);        _assert_(vx_input);
-	Input* vy_input=inputs->GetInput(VyEnum);        _assert_(vy_input);
-	Input* surf_input=inputs->GetInput(SurfaceEnum); _assert_(surf_input);
-
-	/* Start  looping on the number of gaussian points: */
-	gauss=new GaussPenta(5,5);
-	gauss_tria=new GaussTria();
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-		gauss->SynchronizeGaussTria(gauss_tria);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		tria->GetBSSA(&B[0][0], &xyz_list[0][0], gauss_tria);
-		tria->GetBprimeSSA(&Bprime[0][0], &xyz_list[0][0], gauss_tria);
-
-		/*Get viscosity for L1L2 model*/
-		GetL1L2Viscosity(&viscosity,&xyz_list[0][0],gauss,vx_input,vy_input,surf_input);
-
-		for(i=0;i<3;i++) D[i][i]=2*viscosity*gauss->weight*Jdet;
-
-		TripleMultiply( &B[0][0],3,numdof2d,1,
-					&D[0][0],3,3,0,
-					&Bprime[0][0],3,numdof2d,0,
-					&Ke_gg_gaussian[0][0],0);
-		for(i=0;i<numdof2d;i++) for(j=0;j<numdof2d;j++) Ke->values[i*numdof2d+j]+=Ke_gg_gaussian[i][j];
-	}
-
-	/*Transform Coordinate System*/
-	TransformStiffnessMatrixCoord(Ke,tria->nodes,NUMVERTICES2D,XYEnum);
-
-	/*Clean up and return*/
-	delete tria->material;
-	delete tria;
-	delete gauss_tria;
-	delete gauss;
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Penta::CreateKMatrixStressbalanceL1L2Friction{{{*/
-ElementMatrix* Penta::CreateKMatrixStressbalanceL1L2Friction(void){
-
-	/*Initialize Element matrix and return if necessary*/
-	if(IsFloating() || !IsOnBed()) return NULL;
-
-	/*Build a tria element using the 3 nodes of the base of the penta. Then use 
-	 * the tria functionality to build a friction stiffness matrix on these 3
-	 * nodes: */
-	Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.
-	ElementMatrix* Ke=tria->CreateKMatrixStressbalanceSSAFriction();
-	delete tria->material; delete tria;
-
-	/*clean-up and return*/
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Penta::CreateKMatrixStressbalanceHO{{{*/
-ElementMatrix* Penta::CreateKMatrixStressbalanceHO(void){
-
-	/*compute all stiffness matrices for this element*/
-	ElementMatrix* Ke1=CreateKMatrixStressbalanceHOViscous();
-	ElementMatrix* Ke2=CreateKMatrixStressbalanceHOFriction();
-	ElementMatrix* Ke =new ElementMatrix(Ke1,Ke2);
-
-	/*clean-up and return*/
-	delete Ke1;
-	delete Ke2;
-	return Ke;
-
-}
-/*}}}*/
-/*FUNCTION Penta::CreateKMatrixStressbalanceHOViscous{{{*/
-ElementMatrix* Penta::CreateKMatrixStressbalanceHOViscous(void){
-
-	/*Intermediaries */
-	int         approximation;
-	IssmDouble  xyz_list[NUMVERTICES][3];
-	IssmDouble  Jdet;
-	IssmDouble  viscosity,oldviscosity,newviscosity,viscosity_overshoot; //viscosity
-	IssmDouble  epsilon[5],oldepsilon[5]; /* epsilon=[exx,eyy,exy,exz,eyz];*/
-	IssmDouble  D_scalar;
-	GaussPenta *gauss=NULL;
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodes();
-	int numdof   = numnodes*NDOF2;
-
-	/*Initialize Element matrix and vectors*/
-	ElementMatrix* Ke     = new ElementMatrix(nodes,numnodes,this->parameters,HOApproximationEnum);
-	IssmDouble*    B      = xNew<IssmDouble>(5*numdof);
-	IssmDouble*    Bprime = xNew<IssmDouble>(5*numdof);
-	IssmDouble*    D      = xNewZeroInit<IssmDouble>(5*5);
-
-	/*Retrieve all inputs and parameters*/
-	inputs->GetInputValue(&approximation,ApproximationEnum);
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	this->parameters->FindParam(&viscosity_overshoot,StressbalanceViscosityOvershootEnum);
-	Input* vx_input=inputs->GetInput(VxEnum);       _assert_(vx_input);
-	Input* vy_input=inputs->GetInput(VyEnum);       _assert_(vy_input);
-	Input* vxold_input=inputs->GetInput(VxPicardEnum); _assert_(vxold_input);
-	Input* vyold_input=inputs->GetInput(VyPicardEnum); _assert_(vyold_input);
-
-	/* Start  looping on the number of gaussian points: */
-	gauss=new GaussPenta(5,5);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		GetBHO(&B[0], &xyz_list[0][0], gauss);
-		GetBprimeHO(&Bprime[0], &xyz_list[0][0], gauss);
-
-		this->GetStrainRate3dHO(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input);
-		this->GetStrainRate3dHO(&oldepsilon[0],&xyz_list[0][0],gauss,vxold_input,vyold_input);
-		material->GetViscosity3d(&viscosity, &epsilon[0]);
-		material->GetViscosity3d(&oldviscosity, &oldepsilon[0]);
-		newviscosity=viscosity+viscosity_overshoot*(viscosity-oldviscosity);
-
-		D_scalar=2*newviscosity*gauss->weight*Jdet;
-		for(int i=0;i<5;i++) D[i*5+i]=D_scalar;
-
-		TripleMultiply(B,5,numdof,1,
-					D,5,5,0,
-					Bprime,5,numdof,0,
-					&Ke->values[0],1);
-	}
-
-	/*Transform Coordinate System*/
-	TransformStiffnessMatrixCoord(Ke,nodes,numnodes,XYEnum);
-
-	/*Clean up and return*/
-	delete gauss;
-	xDelete<IssmDouble>(D);
-	xDelete<IssmDouble>(Bprime);
-	xDelete<IssmDouble>(B);
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Penta::CreateKMatrixStressbalanceHOFriction{{{*/
-ElementMatrix* Penta::CreateKMatrixStressbalanceHOFriction(void){
-
-	/*Intermediaries */
-	bool       mainlyfloating;
-	int         i,j;
-	int         analysis_type,migration_style;
-	int         point1;
-	IssmDouble  xyz_list[NUMVERTICES][3];
-	IssmDouble  xyz_list_tria[NUMVERTICES2D][3];
-	IssmDouble  alpha2,Jdet;
-	IssmDouble fraction1,fraction2;
-	IssmDouble gllevelset;
-	IssmDouble  phi=1.0;
-	IssmDouble  DL_scalar;
-	Friction   *friction = NULL;
-	GaussPenta *gauss    = NULL;
-
-	/*Initialize Element matrix and return if necessary*/
-	if(IsFloating() || !IsOnBed()) return NULL;
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodes();
-	int numdof   = numnodes*NDOF2;
-
-	/*Initialize Element matrix and vectors*/
-	ElementMatrix* Ke     = new ElementMatrix(nodes,numnodes,this->parameters,HOApproximationEnum);
-	IssmDouble*    B      = xNew<IssmDouble>(2*numdof);
-	IssmDouble*    D      = xNewZeroInit<IssmDouble>(2*2);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	for(i=0;i<NUMVERTICES2D;i++) for(j=0;j<3;j++) xyz_list_tria[i][j]=xyz_list[i][j];
-	parameters->FindParam(&migration_style,GroundinglineMigrationEnum);
-	parameters->FindParam(&analysis_type,AnalysisTypeEnum);
-	Input* surface_input=inputs->GetInput(SurfaceEnum); _assert_(surface_input);
-	Input* vx_input=inputs->GetInput(VxEnum);           _assert_(vx_input);
-	Input* vy_input=inputs->GetInput(VyEnum);           _assert_(vy_input);
-	Input* vz_input=inputs->GetInput(VzEnum);           _assert_(vz_input);
-	Input* gllevelset_input=NULL;
-
-	/*build friction object, used later on: */
-	friction=new Friction("2d",inputs,matpar,analysis_type);
-
-	/*Recover portion of element that is grounded*/
-	if(migration_style==SubelementMigrationEnum) phi=this->GetGroundedPortion(&xyz_list_tria[0][0]);
-	if(migration_style==SubelementMigration2Enum){
-		gllevelset_input=inputs->GetInput(MaskGroundediceLevelsetEnum); _assert_(gllevelset_input);
-		this->GetGroundedPart(&point1,&fraction1,&fraction2,&mainlyfloating);
-		//gauss=new GaussPenta(point1,fraction1,fraction2,mainlyfloating,2);
-		gauss=new GaussPenta(0,1,2,2);
-	}
-	else{
-		gauss=new GaussPenta(0,1,2,2);
-	}
-
-	/* Start  looping on the number of gaussian points: */
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetTriaJacobianDeterminant(&Jdet,&xyz_list_tria[0][0],gauss);
-		GetBHOFriction(&B[0],gauss);
-
-		friction->GetAlpha2(&alpha2, gauss,VxEnum,VyEnum,VzEnum); 
-		if(migration_style==SubelementMigrationEnum) alpha2=phi*alpha2;
-		if(migration_style==SubelementMigration2Enum){
-			gllevelset_input->GetInputValue(&gllevelset, gauss);
-			if(gllevelset<0) alpha2=0;
-		}
-
-		DL_scalar=alpha2*gauss->weight*Jdet;
-		for (i=0;i<2;i++) D[i*2+i]=DL_scalar;
-
-		TripleMultiply(B,2,numdof,1,
-					D,2,2,0,
-					B,2,numdof,0,
-					&Ke->values[0],1);
-	}
-
-	/*Transform Coordinate System*/
-	TransformStiffnessMatrixCoord(Ke,nodes,numnodes,XYEnum);
-
-	/*Clean up and return*/
-	delete gauss;
-	xDelete<IssmDouble>(D);
-	xDelete<IssmDouble>(B);
-	delete friction;
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Penta::CreateKMatrixStressbalanceHOFS{{{*/
-ElementMatrix* Penta::CreateKMatrixStressbalanceHOFS(void){
-
-	/*compute all stiffness matrices for this element*/
-	ElementMatrix* Ke1=CreateKMatrixStressbalanceFS();
-	int indices[3]={18,19,20};
-	Ke1->StaticCondensation(3,&indices[0]);
-	int init = this->element_type;
-	this->element_type=P1Enum; //P1 needed for HO 
-	ElementMatrix* Ke2=CreateKMatrixStressbalanceHO();
-	this->element_type=init;
-	ElementMatrix* Ke3=CreateKMatrixCouplingHOFS();
-	ElementMatrix* Ke =new ElementMatrix(Ke1,Ke2,Ke3);
-
-	/*clean-up and return*/
-	delete Ke1;
-	delete Ke2;
-	delete Ke3;
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Penta::CreateKMatrixStressbalanceFS{{{*/
-ElementMatrix* Penta::CreateKMatrixStressbalanceFS(void){
-
-	ElementMatrix* Ke1 = NULL;
-	ElementMatrix* Ke2 = NULL;
-	ElementMatrix* Ke  = NULL;
-
-	/*compute all stiffness matrices for this element*/
-	Ke1=CreateKMatrixStressbalanceFSViscous();
-	Ke2=CreateKMatrixStressbalanceFSFriction();
-	Ke =new ElementMatrix(Ke1,Ke2);
-
-	/*clean-up and return*/
-	delete Ke1;
-	delete Ke2;
-	return Ke;
-
-}
-/*}}}*/
-/*FUNCTION Penta::KMatrixGLSstabilization{{{*/
-void Penta::KMatrixGLSstabilization(ElementMatrix* Ke){
-
-	int        numdof  = NUMVERTICES*NDOF4;
-
-	/*Intermediaries */
-	int        i,j;
-	IssmDouble Jdet,viscosity,FSreconditioning,diameter,rigidity;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble epsilon[6]; /* epsilon=[exx,eyy,ezz,exy,exz,eyz];*/
-	GaussPenta *gauss=NULL;
-
-	/*Stabilization*/
-	IssmDouble D_scalar;
-	IssmDouble dbasis[3][6];
-	IssmDouble dmu[3];
-	IssmDouble mu;
-	IssmDouble dnodalbasis[6][6][3];
-	IssmDouble SU[6][4][4];
-	IssmDouble SW[6][4][4];
-	int p,q,ii;
-	int c=3; //index of pressure
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	parameters->FindParam(&FSreconditioning,StressbalanceFSreconditioningEnum);
-	Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);
-	Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);
-	Input* vz_input=inputs->GetInput(VzEnum); _assert_(vz_input);
-
-	/*Find minimal length and B*/
-	rigidity=material->GetB();
-	diameter=MinEdgeLength(xyz_list);
-
-		gauss=new GaussPenta();
-		for(int iv=0;iv<6;iv++){
-			gauss->GaussVertex(iv);
-			GetNodalFunctionsP1Derivatives(&dbasis[0][0],&xyz_list[0][0],gauss);
-			for(i=0;i<6;i++){
-				for(j=0;j<3;j++){
-					dnodalbasis[i][iv][j] = dbasis[j][i];
-				}
-			}
-		}
-		delete gauss;
-
-	/* Start  looping on the number of gaussian points: */
-	gauss=new GaussPenta(5,5);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-
-		this->GetStrainRate3d(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input,vz_input);
-		material->GetViscosity3dFS(&viscosity,&epsilon[0]);
-
-		D_scalar=gauss->weight*Jdet;
-
-		/*Add stabilization*/
-		GetNodalFunctionsP1Derivatives(&dbasis[0][0],&xyz_list[0][0],gauss);
-		dmu[0]=0.; dmu[1]=0.; dmu[2]=0.;
-		mu = 2.*viscosity;
-		for(p=0;p<6;p++) for(i=0;i<4;i++) for(j=0;j<4;j++){
-			SU[p][i][j]=0.;
-			SW[p][i][j]=0.;
-		}
-		for(p=0;p<6;p++){
-			for(i=0;i<3;i++){
-				SU[p][i][c] += dbasis[i][p];
-				SW[p][c][i] += dbasis[i][p];
-				for(j=0;j<3;j++){
-					SU[p][i][i] += -dmu[j]*dbasis[j][p];
-					SU[p][i][j] += -dmu[i]*dbasis[i][p];
-					for(ii=0;ii<6;ii++){
-						SU[p][i][i] += -mu*dnodalbasis[p][ii][j]*dbasis[j][ii];
-						SU[p][i][j] += -mu*dnodalbasis[p][ii][i]*dbasis[j][ii];
-					}
-					SW[p][i][i] += -dmu[j]*dbasis[j][p];
-					SW[p][j][i] += -dmu[j]*dbasis[i][p];
-					for(ii=0;ii<6;ii++){
-						SW[p][i][i] += -mu*dnodalbasis[p][ii][j]*dbasis[j][ii];
-						SW[p][j][i] += -mu*dnodalbasis[p][ii][i]*dbasis[j][ii];
-					}
-				}
-			}
-		}
-		IssmDouble tau = 1./3.*pow(diameter,2)/(8.*2.*viscosity);
-		for(p=0;p<6;p++){
-			for(q=0;q<6;q++){
-				for(i=0;i<4;i++){
-					for(j=0;j<4;j++){
-						Ke->values[(p*4+i)*numdof+q*4+j] += gauss->weight*Jdet*tau*SW[p][i][0]*SU[q][0][j];
-						Ke->values[(p*4+i)*numdof+q*4+j] += gauss->weight*Jdet*tau*SW[p][i][1]*SU[q][1][j];
-						Ke->values[(p*4+i)*numdof+q*4+j] += gauss->weight*Jdet*tau*SW[p][i][2]*SU[q][2][j];
-					}
-				}
-			}
-		}
-	}
-
-	/*Clean up*/
-	delete gauss;
-}
-/*}}}*/
-/*FUNCTION Penta::CreateKMatrixStressbalanceFSViscous {{{*/
-ElementMatrix* Penta::CreateKMatrixStressbalanceFSViscous(void){
-
-	/*Intermediaries */
-	int        i,approximation;
-	IssmDouble Jdet,viscosity,FSreconditioning,D_scalar;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble epsilon[6]; /* epsilon=[exx,eyy,ezz,exy,exz,eyz];*/
-	GaussPenta *gauss=NULL;
-
-	/*If on water or not FS, skip stiffness: */
-	inputs->GetInputValue(&approximation,ApproximationEnum);
-	if(approximation!=FSApproximationEnum && approximation!=SSAFSApproximationEnum && approximation!=HOFSApproximationEnum) return NULL;
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int vnumnodes = this->NumberofNodesVelocity();
-	int pnumnodes = this->NumberofNodesPressure();
-	int numdof    = vnumnodes*NDOF3 + pnumnodes*NDOF1;
-
-	/*Prepare coordinate system list*/
-	int* cs_list = xNew<int>(vnumnodes+pnumnodes);
-	for(i=0;i<vnumnodes;i++) cs_list[i]           = XYZEnum;
-	for(i=0;i<pnumnodes;i++) cs_list[vnumnodes+i] = PressureEnum;
-
-	/*Initialize Element matrix and vectors*/
-	ElementMatrix* Ke     = new ElementMatrix(nodes,vnumnodes+pnumnodes,this->parameters,FSvelocityEnum);
-	IssmDouble*    B      = xNew<IssmDouble>(8*numdof);
-	IssmDouble*    Bprime = xNew<IssmDouble>(8*numdof);
-	IssmDouble*    D      = xNewZeroInit<IssmDouble>(8*8);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	parameters->FindParam(&FSreconditioning,StressbalanceFSreconditioningEnum);
-	Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);
-	Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);
-	Input* vz_input=inputs->GetInput(VzEnum); _assert_(vz_input);
-
-	/* Start  looping on the number of gaussian points: */
-	gauss=new GaussPenta(5,5);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		GetBFS(B,&xyz_list[0][0],gauss); 
-		GetBprimeFS(Bprime,&xyz_list[0][0],gauss); 
-
-		this->GetStrainRate3d(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input,vz_input);
-		material->GetViscosity3dFS(&viscosity,&epsilon[0]);
-
-		D_scalar=gauss->weight*Jdet;
-		for(i=0;i<6;i++) D[i*8+i] = +D_scalar*2.*viscosity;
-		for(i=6;i<8;i++) D[i*8+i] = -D_scalar*FSreconditioning;
-
-		TripleMultiply(B,8,numdof,1,
-					D,8,8,0,
-					Bprime,8,numdof,0,
-					Ke->values,1);
-	}
-
-	/*Transform Coordinate System*/
-	TransformStiffnessMatrixCoord(Ke,nodes,(vnumnodes+pnumnodes),cs_list);
-
-	/*Clean up and return*/
-	delete gauss;
-	xDelete<int>(cs_list);
-	xDelete<IssmDouble>(B);
-	xDelete<IssmDouble>(Bprime);
-	xDelete<IssmDouble>(D);
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Penta::CreateKMatrixStressbalanceFSFriction{{{*/
-ElementMatrix* Penta::CreateKMatrixStressbalanceFSFriction(void){
-
-	/*Intermediaries */
-	int         i,j;
-	int         analysis_type,approximation;
-	IssmDouble  alpha2,Jdet2d;
-	IssmDouble  xyz_list[NUMVERTICES][3];
-	IssmDouble  xyz_list_tria[NUMVERTICES2D][3];
-	Friction   *friction = NULL;
-	GaussPenta *gauss    = NULL;
-
-	/*Initialize Element matrix and return if necessary*/
-	if(IsFloating() || !IsOnBed()) return NULL;
-
-	/*If on water or not FS, skip stiffness: */
-	inputs->GetInputValue(&approximation,ApproximationEnum);
-	if(approximation!=FSApproximationEnum && approximation!=SSAFSApproximationEnum && approximation!=HOFSApproximationEnum) return NULL;
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int vnumnodes = this->NumberofNodesVelocity();
-	int pnumnodes = this->NumberofNodesPressure();
-	int  numdof   = vnumnodes*NDOF3 + pnumnodes*NDOF1;
-
-	/*Initialize Element matrix and vectors*/
-	ElementMatrix* Ke        = new ElementMatrix(nodes,vnumnodes+pnumnodes,this->parameters,FSvelocityEnum);
-	IssmDouble*    BFriction = xNew<IssmDouble>(2*numdof);
-	IssmDouble*    D         = xNewZeroInit<IssmDouble>(2*2);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	parameters->FindParam(&analysis_type,AnalysisTypeEnum);
-	Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);
-	Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);
-	Input* vz_input=inputs->GetInput(VzEnum); _assert_(vz_input);
-	for(i=0;i<NUMVERTICES2D;i++) for(j=0;j<3;j++) xyz_list_tria[i][j]=xyz_list[i][j];
-
-	/*build friction object, used later on: */
-	friction=new Friction("3d",inputs,matpar,analysis_type);
-
-	/* Start  looping on the number of gaussian points: */
-	gauss=new GaussPenta(0,1,2,2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetTriaJacobianDeterminant(&Jdet2d, &xyz_list_tria[0][0],gauss);
-		GetLFS(BFriction,gauss);
-
-		friction->GetAlpha2(&alpha2,gauss,VxEnum,VyEnum,VzEnum);
-
-		D[0*2+0] = +alpha2*gauss->weight*Jdet2d; //taub_x = -alpha2 vx
-		D[1*2+1] = +alpha2*gauss->weight*Jdet2d; //taub_y = -alpha2 vy
-
-		TripleMultiply(BFriction,2,numdof,1,
-					D,2,2,0,
-					BFriction,2,numdof,0,
-					Ke->values,1);
-	}
-
-	/*DO NOT Transform Coordinate System: this stiffness matrix is already expressed in tangential coordinates*/
-	//TransformStiffnessMatrixCoord(Ke,nodes,NUMVERTICES,XYZEnum);
-
-	/*Clean up and return*/
-	delete gauss;
-	delete friction;
-	xDelete<IssmDouble>(BFriction);
-	xDelete<IssmDouble>(D);
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Penta::CreateKMatrixStressbalanceVert {{{*/
-ElementMatrix* Penta::CreateKMatrixStressbalanceVert(void){
-
-	/*compute all stiffness matrices for this element*/
-	ElementMatrix* Ke1=CreateKMatrixStressbalanceVertVolume();
-	ElementMatrix* Ke2=CreateKMatrixStressbalanceVertSurface();
-	ElementMatrix* Ke =new ElementMatrix(Ke1,Ke2);
-
-	/*clean-up and return*/
-	delete Ke1;
-	delete Ke2;
-	return Ke;
-
-}
-/*}}}*/
-/*FUNCTION Penta::CreateKMatrixStressbalanceVertVolume {{{*/
-ElementMatrix* Penta::CreateKMatrixStressbalanceVertVolume(void){
-
-	/*Intermediaries */
-	IssmDouble  Jdet;
-	IssmDouble  xyz_list[NUMVERTICES][3];
-	IssmDouble  B[NDOF1][NUMVERTICES];
-	IssmDouble  Bprime[NDOF1][NUMVERTICES];
-	IssmDouble  DL_scalar;
-	GaussPenta  *gauss=NULL;
-
-	/*Initialize Element matrix*/
-	ElementMatrix* Ke=new ElementMatrix(nodes,NUMVERTICES,this->parameters,NoneApproximationEnum);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-
-	/* Start  looping on the number of gaussian points: */
-	gauss=new GaussPenta(2,2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		GetBVert(&B[0][0], &xyz_list[0][0], gauss);
-		GetBprimeVert(&Bprime[0][0], &xyz_list[0][0], gauss);
-
-		DL_scalar=gauss->weight*Jdet;
-
-		TripleMultiply( &B[0][0],1,NUMVERTICES,1,
-					&DL_scalar,1,1,0,
-					&Bprime[0][0],1,NUMVERTICES,0,
-					&Ke->values[0],1);
-	} 
-
-	/*Clean up and return*/
-	delete gauss;
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Penta::CreateKMatrixStressbalanceVertSurface {{{*/
-ElementMatrix* Penta::CreateKMatrixStressbalanceVertSurface(void){
-
-	if (!IsOnSurface()) return NULL;
-
-	/*Constants*/
-	const int numdof=NDOF1*NUMVERTICES;
-
-	/*Intermediaries */
-	int       i,j;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble xyz_list_tria[NUMVERTICES2D][3];
-	IssmDouble surface_normal[3];
-	IssmDouble Jdet2d,DL_scalar;
-	IssmDouble basis[NUMVERTICES];
-	GaussPenta *gauss=NULL;
-
-	/*Initialize Element matrix*/
-	ElementMatrix* Ke=new ElementMatrix(nodes,NUMVERTICES,this->parameters,NoneApproximationEnum);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	for(i=0;i<NUMVERTICES2D;i++) for(j=0;j<3;j++) xyz_list_tria[i][j]=xyz_list[i+3][j];
-	SurfaceNormal(&surface_normal[0],xyz_list_tria);
-
-	/* Start  looping on the number of gaussian points: */
-	gauss=new GaussPenta(3,4,5,2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetTriaJacobianDeterminant(&Jdet2d, &xyz_list_tria[0][0],gauss);
-		GetNodalFunctionsP1(&basis[0], gauss);
-
-		DL_scalar= - gauss->weight*Jdet2d*surface_normal[2]; 
-
-		TripleMultiply( basis,1,numdof,1,
-					&DL_scalar,1,1,0,
-					basis,1,numdof,0,
-					&Ke->values[0],1);
-	}
-
-	/*Clean up and return*/
-	delete gauss;
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Penta::CreatePVectorCouplingSSAFS {{{*/
-ElementVector* Penta::CreatePVectorCouplingSSAFS(void){
-
-	/*compute all load vectors for this element*/
-	ElementVector* pe1=CreatePVectorCouplingSSAFSViscous();
-	ElementVector* pe2=CreatePVectorCouplingSSAFSFriction();
-	ElementVector* pe =new ElementVector(pe1,pe2);
-
-	/*clean-up and return*/
-	delete pe1;
-	delete pe2;
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Penta::CreatePVectorCouplingSSAFSViscous {{{*/
-ElementVector* Penta::CreatePVectorCouplingSSAFSViscous(void){
-
-	/*Intermediaries */
-	int         i,approximation;
-	IssmDouble  viscosity,Jdet;
-	IssmDouble  FSreconditioning;
-	IssmDouble  epsilon[6]; /* epsilon=[exx,eyy,ezz,exy,exz,eyz];*/
-	IssmDouble  dw[3];
-	IssmDouble  xyz_list[NUMVERTICES][3];
-	IssmDouble  basis[6]; //for the six nodes of the penta
-	IssmDouble  dbasis[3][6]; //for the six nodes of the penta
-	GaussPenta *gauss=NULL;
-
-	/*Initialize Element vector and return if necessary*/
-	inputs->GetInputValue(&approximation,ApproximationEnum);
-	if(approximation!=SSAFSApproximationEnum) return NULL;
-	int vnumnodes = this->NumberofNodesVelocity();
-	int pnumnodes = this->NumberofNodesPressure();
-
-	/*Prepare coordinate system list*/
-	int* cs_list = xNew<int>(vnumnodes+pnumnodes);
-	for(i=0;i<vnumnodes;i++) cs_list[i]           = XYZEnum;
-	for(i=0;i<pnumnodes;i++) cs_list[vnumnodes+i] = PressureEnum;
-	ElementVector* pe=new ElementVector(nodes,vnumnodes+pnumnodes,this->parameters,FSvelocityEnum);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	this->parameters->FindParam(&FSreconditioning,StressbalanceFSreconditioningEnum);
-	Input* vx_input=inputs->GetInput(VxEnum);               _assert_(vx_input);
-	Input* vy_input=inputs->GetInput(VyEnum);               _assert_(vy_input);
-	Input* vz_input=inputs->GetInput(VzEnum);               _assert_(vz_input);
-	Input* vzSSA_input=inputs->GetInput(VzSSAEnum);   _assert_(vzSSA_input);
-
-	/* Start  looping on the number of gaussian points: */
-	gauss=new GaussPenta(5,5);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		GetNodalFunctionsP1(&basis[0], gauss);
-		GetNodalFunctionsP1Derivatives(&dbasis[0][0],&xyz_list[0][0], gauss);
-
-		vzSSA_input->GetInputDerivativeValue(&dw[0],&xyz_list[0][0],gauss);
-
-		this->GetStrainRate3d(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input,vz_input);
-		material->GetViscosity3dFS(&viscosity,&epsilon[0]);
-
-		for(i=0;i<NUMVERTICES;i++){
-			pe->values[i*NDOF3+0]+=-Jdet*gauss->weight*viscosity*dw[0]*dbasis[2][i];
-			pe->values[i*NDOF3+1]+=-Jdet*gauss->weight*viscosity*dw[1]*dbasis[2][i];
-			pe->values[i*NDOF3+2]+=-Jdet*gauss->weight*viscosity*(dw[0]*dbasis[0][i]+dw[1]*dbasis[1][i]+2*dw[2]*dbasis[2][i]);
-			pe->values[NDOF3*vnumnodes+i]+=Jdet*gauss->weight*FSreconditioning*dw[2]*basis[i];
-		}
-	}
-
-	/*Transform coordinate system*/
-	TransformLoadVectorCoord(pe,nodes,vnumnodes+pnumnodes,cs_list);
-
-	/*Clean up and return*/
-	xDelete<int>(cs_list);
-	delete gauss;
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Penta::CreatePVectorCouplingSSAFSFriction{{{*/
-ElementVector* Penta::CreatePVectorCouplingSSAFSFriction(void){
-
-	/*Intermediaries*/
-	int         i,j;
-	int         approximation,analysis_type;
-	IssmDouble  Jdet,Jdet2d;
-	IssmDouble  FSreconditioning;
-	IssmDouble	bed_normal[3];
-	IssmDouble  epsilon[6]; /* epsilon=[exx,eyy,ezz,exy,exz,eyz];*/
-	IssmDouble  viscosity, w, alpha2_gauss;
-	IssmDouble  dw[3];
-	IssmDouble	xyz_list_tria[NUMVERTICES2D][3];
-	IssmDouble  xyz_list[NUMVERTICES][3];
-	IssmDouble  basis[6]; //for the six nodes of the penta
-	Friction*   friction=NULL;
-	GaussPenta  *gauss=NULL;
-
-	/*Initialize Element vector and return if necessary*/
-	if(!IsOnBed() || IsFloating()) return NULL;
-	inputs->GetInputValue(&approximation,ApproximationEnum);
-	if(approximation!=SSAFSApproximationEnum) return NULL;
-	int vnumnodes = this->NumberofNodesVelocity();
-	int pnumnodes = this->NumberofNodesPressure();
-
-	/*Prepare coordinate system list*/
-	int* cs_list = xNew<int>(vnumnodes+pnumnodes);
-	for(i=0;i<vnumnodes;i++) cs_list[i]           = XYZEnum;
-	for(i=0;i<pnumnodes;i++) cs_list[vnumnodes+i] = PressureEnum;
-	ElementVector* pe=new ElementVector(nodes,vnumnodes+pnumnodes,this->parameters,FSvelocityEnum);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	parameters->FindParam(&analysis_type,AnalysisTypeEnum);
-	this->parameters->FindParam(&FSreconditioning,StressbalanceFSreconditioningEnum);
-	Input* vx_input=inputs->GetInput(VxEnum);        _assert_(vx_input);
-	Input* vy_input=inputs->GetInput(VyEnum);        _assert_(vy_input);
-	Input* vz_input=inputs->GetInput(VzEnum);        _assert_(vz_input);
-	Input* vzSSA_input=inputs->GetInput(VzSSAEnum);  _assert_(vzSSA_input);
-
-	for(i=0;i<NUMVERTICES2D;i++) for(j=0;j<3;j++) xyz_list_tria[i][j]=xyz_list[i][j];
-
-	/*build friction object, used later on: */
-	friction=new Friction("3d",inputs,matpar,analysis_type);
-
-	/* Start looping on the number of gauss 2d (nodes on the bedrock) */
-	gauss=new GaussPenta(0,1,2,2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetTriaJacobianDeterminant(&Jdet2d, &xyz_list_tria[0][0], gauss);
-		GetNodalFunctionsP1(basis, gauss);
-
-		vzSSA_input->GetInputValue(&w, gauss);
-		vzSSA_input->GetInputDerivativeValue(&dw[0],&xyz_list[0][0],gauss);
-
-		BedNormal(&bed_normal[0],xyz_list_tria);
-		this->GetStrainRate3d(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input,vz_input);
-		material->GetViscosity3dFS(&viscosity,&epsilon[0]);
-		friction->GetAlpha2(&alpha2_gauss, gauss,VxEnum,VyEnum,VzEnum);
-
-		for(i=0;i<NUMVERTICES2D;i++){
-			pe->values[i*NDOF3+0]+=Jdet2d*gauss->weight*(alpha2_gauss*w*bed_normal[0]*bed_normal[2]+2*viscosity*dw[2]*bed_normal[0])*basis[i];
-			pe->values[i*NDOF3+1]+=Jdet2d*gauss->weight*(alpha2_gauss*w*bed_normal[1]*bed_normal[2]+2*viscosity*dw[2]*bed_normal[1])*basis[i];
-			pe->values[i*NDOF3+2]+=Jdet2d*gauss->weight*2*viscosity*(dw[0]*bed_normal[0]+dw[1]*bed_normal[1]+dw[2]*bed_normal[2])*basis[i];
-		}
-	}
-
-	/*Transform coordinate system*/
-	TransformLoadVectorCoord(pe,nodes,(vnumnodes+pnumnodes),cs_list);
-
-	/*Clean up and return*/
-	xDelete<int>(cs_list);
-	delete gauss;
-	delete friction;
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Penta::CreatePVectorCouplingHOFS {{{*/
-ElementVector* Penta::CreatePVectorCouplingHOFS(void){
-
-	/*compute all load vectors for this element*/
-	ElementVector* pe1=CreatePVectorCouplingHOFSViscous();
-	ElementVector* pe2=CreatePVectorCouplingHOFSFriction();
-	ElementVector* pe =new ElementVector(pe1,pe2);
-
-	/*clean-up and return*/
-	delete pe1;
-	delete pe2;
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Penta::CreatePVectorCouplingHOFSViscous {{{*/
-ElementVector* Penta::CreatePVectorCouplingHOFSViscous(void){
-
-	/*Intermediaries */
-	int         i;
-	int         approximation;
-	IssmDouble  viscosity,Jdet;
-	IssmDouble  FSreconditioning;
-	IssmDouble  epsilon[6]; /* epsilon=[exx,eyy,ezz,exy,exz,eyz];*/
-	IssmDouble  dw[3];
-	IssmDouble  xyz_list[NUMVERTICES][3];
-	IssmDouble  basis[6]; //for the six nodes of the penta
-	IssmDouble  dbasis[3][6]; //for the six nodes of the penta
-	GaussPenta *gauss=NULL;
-
-	/*Initialize Element vector and return if necessary*/
-	inputs->GetInputValue(&approximation,ApproximationEnum);
-	if(approximation!=HOFSApproximationEnum) return NULL;
-	int vnumnodes = this->NumberofNodesVelocity();
-	int pnumnodes = this->NumberofNodesPressure();
-
-	/*Prepare coordinate system list*/
-	int* cs_list = xNew<int>(vnumnodes+pnumnodes);
-	for(i=0;i<vnumnodes;i++) cs_list[i]           = XYZEnum;
-	for(i=0;i<pnumnodes;i++) cs_list[vnumnodes+i] = PressureEnum;
-
-	/*Initialize Element matrix and vectors*/
-	ElementVector* pe=new ElementVector(nodes,vnumnodes+pnumnodes,this->parameters,FSvelocityEnum);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	this->parameters->FindParam(&FSreconditioning,StressbalanceFSreconditioningEnum);
-	Input* vx_input=inputs->GetInput(VxEnum);       _assert_(vx_input);
-	Input* vy_input=inputs->GetInput(VyEnum);       _assert_(vy_input);
-	Input* vz_input=inputs->GetInput(VzEnum);       _assert_(vz_input);
-	Input* vzHO_input=inputs->GetInput(VzHOEnum);   _assert_(vzHO_input);
-
-	/* Start  looping on the number of gaussian points: */
-	gauss=new GaussPenta(5,5);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		GetNodalFunctionsP1(&basis[0], gauss);
-		GetNodalFunctionsP1Derivatives(&dbasis[0][0],&xyz_list[0][0], gauss);
-
-		vzHO_input->GetInputDerivativeValue(&dw[0],&xyz_list[0][0],gauss);
-
-		this->GetStrainRate3d(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input,vz_input);
-		material->GetViscosity3dFS(&viscosity,&epsilon[0]);
-
-		for(i=0;i<NUMVERTICES;i++){
-			pe->values[i*NDOF3+0]+=-Jdet*gauss->weight*viscosity*dw[0]*dbasis[2][i];
-			pe->values[i*NDOF3+1]+=-Jdet*gauss->weight*viscosity*dw[1]*dbasis[2][i];
-			pe->values[i*NDOF3+2]+=-Jdet*gauss->weight*viscosity*(dw[0]*dbasis[0][i]+dw[1]*dbasis[1][i]+2*dw[2]*dbasis[2][i]);
-			pe->values[NDOF3*vnumnodes+i]+=Jdet*gauss->weight*FSreconditioning*dw[2]*basis[i];
-		}
-	}
-
-	/*Transform coordinate system*/
-	TransformLoadVectorCoord(pe,nodes,vnumnodes+pnumnodes,cs_list);
-
-	/*Clean up and return*/
-	xDelete<int>(cs_list);
-	delete gauss;
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Penta::CreatePVectorCouplingHOFSFriction{{{*/
-ElementVector* Penta::CreatePVectorCouplingHOFSFriction(void){
-
-	/*Intermediaries*/
-	int         i,j;
-	int         approximation,analysis_type;
-	IssmDouble  Jdet,Jdet2d;
-	IssmDouble  FSreconditioning;
-	IssmDouble	bed_normal[3];
-	IssmDouble  epsilon[6]; /* epsilon=[exx,eyy,ezz,exy,exz,eyz];*/
-	IssmDouble  viscosity, w, alpha2_gauss;
-	IssmDouble  dw[3];
-	IssmDouble	xyz_list_tria[NUMVERTICES2D][3];
-	IssmDouble  xyz_list[NUMVERTICES][3];
-	IssmDouble  basis[6]; //for the six nodes of the penta
-	Friction*   friction=NULL;
-	GaussPenta  *gauss=NULL;
-
-	/*Initialize Element vector and return if necessary*/
-	if(!IsOnBed() || IsFloating()) return NULL;
-	inputs->GetInputValue(&approximation,ApproximationEnum);
-	if(approximation!=HOFSApproximationEnum) return NULL;
-
-	int vnumnodes = this->NumberofNodesVelocity();
-	int pnumnodes = this->NumberofNodesPressure();
-	int numnodes  = vnumnodes+pnumnodes;
-
-	/*Prepare coordinate system list*/
-	int* cs_list = xNew<int>(vnumnodes+pnumnodes);
-	for(i=0;i<vnumnodes;i++) cs_list[i]           = XYZEnum;
-	for(i=0;i<pnumnodes;i++) cs_list[vnumnodes+i] = PressureEnum;
-
-	ElementVector* pe=new ElementVector(nodes,numnodes,this->parameters,FSvelocityEnum);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	parameters->FindParam(&analysis_type,AnalysisTypeEnum);
-	this->parameters->FindParam(&FSreconditioning,StressbalanceFSreconditioningEnum);
-	Input* vx_input=inputs->GetInput(VxEnum);               _assert_(vx_input);
-	Input* vy_input=inputs->GetInput(VyEnum);               _assert_(vy_input);
-	Input* vz_input=inputs->GetInput(VzEnum);               _assert_(vz_input);
-	Input* vzHO_input=inputs->GetInput(VzHOEnum);   _assert_(vzHO_input);
-
-	for(i=0;i<NUMVERTICES2D;i++) for(j=0;j<3;j++) xyz_list_tria[i][j]=xyz_list[i][j];
-
-	/*build friction object, used later on: */
-	friction=new Friction("3d",inputs,matpar,analysis_type);
-
-	/* Start looping on the number of gauss 2d (nodes on the bedrock) */
-	gauss=new GaussPenta(0,1,2,2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetTriaJacobianDeterminant(&Jdet2d, &xyz_list_tria[0][0], gauss);
-		GetNodalFunctionsP1(basis, gauss);
-
-		vzHO_input->GetInputValue(&w, gauss);
-		vzHO_input->GetInputDerivativeValue(&dw[0],&xyz_list[0][0],gauss);
-
-		BedNormal(&bed_normal[0],xyz_list_tria);
-		this->GetStrainRate3d(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input,vz_input);
-		material->GetViscosity3dFS(&viscosity,&epsilon[0]);
-		friction->GetAlpha2(&alpha2_gauss, gauss,VxEnum,VyEnum,VzEnum);
-
-		for(i=0;i<NUMVERTICES2D;i++){
-			pe->values[i*NDOF3+0]+=Jdet2d*gauss->weight*(alpha2_gauss*w*bed_normal[0]*bed_normal[2]+2*viscosity*dw[2]*bed_normal[0])*basis[i];
-			pe->values[i*NDOF3+1]+=Jdet2d*gauss->weight*(alpha2_gauss*w*bed_normal[1]*bed_normal[2]+2*viscosity*dw[2]*bed_normal[1])*basis[i];
-			pe->values[i*NDOF3+2]+=Jdet2d*gauss->weight*2*viscosity*(dw[0]*bed_normal[0]+dw[1]*bed_normal[1]+dw[2]*bed_normal[2])*basis[i];
-		}
-	}
-
-	/*Transform coordinate system*/
-	TransformLoadVectorCoord(pe,nodes,vnumnodes+pnumnodes,cs_list);
-
-	/*Clean up and return*/
-	xDelete<int>(cs_list);
-	delete gauss;
-	delete friction;
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Penta::CreatePVectorStressbalanceHoriz{{{*/
-ElementVector* Penta::CreatePVectorStressbalanceHoriz(void){
-
-	int approximation;
-	inputs->GetInputValue(&approximation,ApproximationEnum);
-
-	switch(approximation){
-		case SSAApproximationEnum:
-			return CreatePVectorStressbalanceSSA();
-		case HOApproximationEnum:
-			return CreatePVectorStressbalanceHO();
-		case L1L2ApproximationEnum:
-			return CreatePVectorStressbalanceL1L2();
-		case SIAApproximationEnum:
-			return NULL;
-		case NoneApproximationEnum:
-			return NULL;
-		case FSApproximationEnum:
-			return CreatePVectorStressbalanceFS();
-		case SSAHOApproximationEnum:
-			return CreatePVectorStressbalanceSSAHO();
-		case SSAFSApproximationEnum:
-			return CreatePVectorStressbalanceSSAFS();
-		case HOFSApproximationEnum:
-			return CreatePVectorStressbalanceHOFS();
-		default:
-			_error_("Approximation " << EnumToStringx(approximation) << " not supported yet");
-	}
-}
-/*}}}*/
-/*FUNCTION Penta::CreatePVectorStressbalanceSSAHO{{{*/
-ElementVector* Penta::CreatePVectorStressbalanceSSAHO(void){
-
-	/*compute all load vectors for this element*/
-	ElementVector* pe1=CreatePVectorStressbalanceSSA();
-	ElementVector* pe2=CreatePVectorStressbalanceHO();
-	ElementVector* pe =new ElementVector(pe1,pe2);
-
-	/*clean-up and return*/
-	delete pe1;
-	delete pe2;
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Penta::CreatePVectorStressbalanceSSAFS{{{*/
-ElementVector* Penta::CreatePVectorStressbalanceSSAFS(void){
-
-	/*compute all load vectors for this element*/
-	int init = this->element_type;
-	this->element_type=P1Enum;
-	ElementVector* pe1=CreatePVectorStressbalanceSSA();
-	this->element_type=init;
-	ElementVector* pe2=CreatePVectorStressbalanceFS();
-	int indices[3]={18,19,20};
-	this->element_type=MINIcondensedEnum;
-	ElementMatrix* Ke = CreateKMatrixStressbalanceFS();
-	this->element_type=init;
-	pe2->StaticCondensation(Ke,3,&indices[0]);
-	delete Ke;
-	ElementVector* pe3=CreatePVectorCouplingSSAFS();
-	ElementVector* pe =new ElementVector(pe1,pe2,pe3);
-
-	/*clean-up and return*/
-	delete pe1;
-	delete pe2;
-	delete pe3;
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Penta::CreatePVectorStressbalanceHOFS{{{*/
-ElementVector* Penta::CreatePVectorStressbalanceHOFS(void){
-
-	/*compute all load vectors for this element*/
-	int init = this->element_type;
-	this->element_type=P1Enum;
-	ElementVector* pe1=CreatePVectorStressbalanceHO();
-	this->element_type=init;
-	ElementVector* pe2=CreatePVectorStressbalanceFS();
-	int indices[3]={18,19,20};
-	this->element_type=MINIcondensedEnum;
-	ElementMatrix* Ke = CreateKMatrixStressbalanceFS();
-	this->element_type=init;
-	pe2->StaticCondensation(Ke,3,&indices[0]);
-	delete Ke;
-	ElementVector* pe3=CreatePVectorCouplingHOFS();
-	ElementVector* pe =new ElementVector(pe1,pe2,pe3);
-
-	/*clean-up and return*/
-	delete pe1;
-	delete pe2;
-	delete pe3;
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Penta::CreatePVectorStressbalanceSIA{{{*/
-ElementVector* Penta::CreatePVectorStressbalanceSIA(void){
-
-	/*Intermediaries*/
-	int         i,j;
-	int         node0,node1;
-	IssmDouble  connectivity[2];
-	IssmDouble  Jdet;
-	IssmDouble  xyz_list[NUMVERTICES][3];
-	IssmDouble  xyz_list_segment[2][3];
-	IssmDouble  z_list[NUMVERTICES];
-	IssmDouble  slope[2];
-	IssmDouble  slope2,constant_part;
-	IssmDouble  rho_ice,gravity,n,B;
-	IssmDouble  ub,vb,z_g,surface,thickness;
-	GaussPenta* gauss=NULL;
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodes(); _assert_(numnodes==6); 
-
-	/*Initialize Element vector*/
-	ElementVector* pe=new ElementVector(nodes,numnodes,this->parameters);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	rho_ice=matpar->GetRhoIce();
-	gravity=matpar->GetG();
-	n=material->GetN();
-	B=material->GetB();
-	Input* thickness_input=inputs->GetInput(ThicknessEnum);  _assert_(thickness_input);
-	Input* surface_input=inputs->GetInput(SurfaceEnum);      _assert_(surface_input);
-	Input* slopex_input=inputs->GetInput(SurfaceSlopeXEnum); _assert_(slopex_input);
-	Input* slopey_input=inputs->GetInput(SurfaceSlopeYEnum); _assert_(slopey_input);
-	for(i=0;i<NUMVERTICES;i++)z_list[i]=xyz_list[i][2];
-
-	/*Loop on the three segments*/
-	for(i=0;i<3;i++){
-
-		node0=i; node1=i+3;
-
-		for(j=0;j<3;j++){
-			xyz_list_segment[0][j]=xyz_list[node0][j];
-			xyz_list_segment[1][j]=xyz_list[node1][j];
-		}
-
-		connectivity[0]=(IssmDouble)vertices[node0]->Connectivity();
-		connectivity[1]=(IssmDouble)vertices[node1]->Connectivity();
-
-		/*Loop on the Gauss points: */
-		gauss=new GaussPenta(node0,node1,3);
-		for(int ig=gauss->begin();ig<gauss->end();ig++){
-			gauss->GaussPoint(ig);
-
-			slopex_input->GetInputValue(&slope[0],gauss);
-			slopey_input->GetInputValue(&slope[1],gauss);
-			surface_input->GetInputValue(&surface,gauss);
-			thickness_input->GetInputValue(&thickness,gauss);
-
-			slope2=pow(slope[0],2)+pow(slope[1],2);
-			constant_part=-2.*pow(rho_ice*gravity,n)*pow(slope2,((n-1.)/2.));
-
-			PentaRef::GetInputValue(&z_g,&z_list[0],gauss);
-			GetSegmentJacobianDeterminant(&Jdet,&xyz_list_segment[0][0],gauss);
-
-			if(IsOnSurface()){
-				pe->values[2*node1+0]+=constant_part*pow((surface-z_g)/B,n)*slope[0]*Jdet*gauss->weight/connectivity[1];
-				pe->values[2*node1+1]+=constant_part*pow((surface-z_g)/B,n)*slope[1]*Jdet*gauss->weight/connectivity[1];
-			}
-			else{/*connectivity is too large, should take only half on it*/
-				pe->values[2*node1+0]+=constant_part*pow((surface-z_g)/B,n)*slope[0]*Jdet*gauss->weight*2./connectivity[1];
-				pe->values[2*node1+1]+=constant_part*pow((surface-z_g)/B,n)*slope[1]*Jdet*gauss->weight*2./connectivity[1];
-			}
-		}
-		delete gauss;
-
-		/*Deal with lower surface*/
-		if(IsOnBed()){
-			constant_part=-1.58*1.e-10*rho_ice*gravity*thickness;
-			ub=constant_part*slope[0];
-			vb=constant_part*slope[1];
-
-			pe->values[2*node0+0]+=ub/connectivity[0];
-			pe->values[2*node0+1]+=vb/connectivity[0];
-		}
-	}
-
-	/*Clean up and return*/
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Penta::CreatePVectorStressbalanceSSA{{{*/
-ElementVector* Penta::CreatePVectorStressbalanceSSA(void){
-
-	if (!IsOnBed()) return NULL;
-
-	/*Call Tria function*/
-	Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.
-	ElementVector* pe=tria->CreatePVectorStressbalanceSSA();
-	delete tria->material; delete tria;
-
-	/*Clean up and return*/
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Penta::CreatePVectorStressbalanceL1L2{{{*/
-ElementVector* Penta::CreatePVectorStressbalanceL1L2(void){
-
-	if (!IsOnBed()) return NULL;
-
-	/*Call Tria function*/
-	Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.
-	ElementVector* pe=tria->CreatePVectorStressbalanceSSA();
-	delete tria->material; delete tria;
-
-	/*Clean up and return*/
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Penta::CreatePVectorStressbalanceHO{{{*/
-ElementVector* Penta::CreatePVectorStressbalanceHO(void){
-
-	/*compute all load vectors for this element*/
-	ElementVector* pe1=CreatePVectorStressbalanceHODrivingStress();
-	ElementVector* pe2=CreatePVectorStressbalanceHOFront();
-	ElementVector* pe =new ElementVector(pe1,pe2);
-
-	/*clean-up and return*/
-	delete pe1;
-	delete pe2;
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Penta::CreatePVectorStressbalanceHODrivingStress{{{*/
-ElementVector* Penta::CreatePVectorStressbalanceHODrivingStress(void){
-
-	/*Intermediaries*/
-	IssmDouble  Jdet;
-	IssmDouble  slope[3]; //do not put 2! this goes into GetInputDerivativeValue, which addresses slope[3] also!
-	IssmDouble  driving_stress_baseline,thickness;
-	IssmDouble  xyz_list[NUMVERTICES][3];
-	GaussPenta  *gauss=NULL;
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Initialize vector*/
-	ElementVector* pe    = new ElementVector(nodes,numnodes,this->parameters,HOApproximationEnum);
-	IssmDouble*    basis = xNewZeroInit<IssmDouble>(numnodes);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	Input* thickness_input=inputs->GetInput(ThicknessEnum); _assert_(thickness_input);
-	Input* surface_input=inputs->GetInput(SurfaceEnum);     _assert_(surface_input);
-
-	/* Start  looping on the number of gaussian points: */
-	gauss=new GaussPenta(2,3);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		GetNodalFunctions(basis,gauss);
-
-		thickness_input->GetInputValue(&thickness, gauss);
-		surface_input->GetInputDerivativeValue(&slope[0],&xyz_list[0][0],gauss);
-
-		driving_stress_baseline=matpar->GetRhoIce()*matpar->GetG();
-
-		for(int i=0;i<numnodes;i++){
-			pe->values[i*NDOF2+0]+= -driving_stress_baseline*slope[0]*Jdet*gauss->weight*basis[i];
-			pe->values[i*NDOF2+1]+= -driving_stress_baseline*slope[1]*Jdet*gauss->weight*basis[i];
-		}
-	}
-
-	/*Transform coordinate system*/
-	TransformLoadVectorCoord(pe,nodes,numnodes,XYEnum);
-
-	/*Clean up and return*/
-	xDelete<IssmDouble>(basis);
-	delete gauss;
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Penta::CreatePVectorStressbalanceHOFront{{{*/
-ElementVector* Penta::CreatePVectorStressbalanceHOFront(void){
-
-	/*Intermediaries */
-	IssmDouble  ls[NUMVERTICES];
-	IssmDouble  xyz_list[NUMVERTICES][3];
-	bool        isfront;
-
-	/*Retrieve all inputs and parameters*/
-	GetInputListOnVertices(&ls[0],MaskIceLevelsetEnum);
-
-	/*If the level set is awlays <=0, there is no ice front here*/
-	isfront = false;
-	if(ls[0]>0. || ls[1]>0. || ls[2]>0.){
-		if(ls[0]*ls[1]<0. || ls[0]*ls[2]<0. || (ls[0]*ls[1]+ls[0]*ls[2]+ls[1]*ls[2]==0.)){
-			isfront = true;
-		}
-	}
-
-	/*If no front, return NULL*/
-	if(!isfront) return NULL;
-
-	/*Intermediaries*/
-	IssmDouble  rho_ice,rho_water,gravity;
-	IssmDouble  Jdet,surface,z_g,water_pressure,ice_pressure,air_pressure;
-	IssmDouble  surface_under_water,base_under_water,pressure;
-	IssmDouble  xyz_list_front[4][3];
-	IssmDouble  area_coordinates[4][3];
-	IssmDouble  normal[3];
-	GaussPenta* gauss;
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Initialize Element vector and other vectors*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	ElementVector* pe    = new ElementVector(nodes,numnodes,this->parameters,HOApproximationEnum);
-	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
-
-	/*Retrieve all inputs and parameters*/
-	Input* surface_input=inputs->GetInput(SurfaceEnum); _assert_(surface_input);
-	rho_water=matpar->GetRhoWater();
-	rho_ice  =matpar->GetRhoIce();
-	gravity  =matpar->GetG();
-	GetZeroLevelsetCoordinates(&xyz_list_front[0][0],xyz_list,MaskIceLevelsetEnum);
-	GetAreaCoordinates(&area_coordinates[0][0],xyz_list_front,xyz_list,4);
-	GetQuadNormal(&normal[0],xyz_list_front);
-
-	/*Initialize gauss points*/
-	IssmDouble zmax=xyz_list[0][2]; for(int i=1;i<6;i++) if(xyz_list[i][2]>zmax) zmax=xyz_list[i][2];
-	IssmDouble zmin=xyz_list[0][2]; for(int i=1;i<6;i++) if(xyz_list[i][2]<zmin) zmin=xyz_list[i][2];
-	if(zmax>0 && zmin<0) gauss=new GaussPenta(area_coordinates,3,10); //refined in vertical because of the sea level discontinuity
-	else                 gauss=new GaussPenta(area_coordinates,3,3);
-
-	/* Start  looping on the number of gaussian points: */
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-		surface_input->GetInputValue(&surface,gauss);
-		z_g=GetZcoord(gauss);
-		GetNodalFunctions(basis,gauss);
-		GetQuadJacobianDeterminant(&Jdet,xyz_list_front,gauss);
-
-		water_pressure = rho_water*gravity*min(0.,z_g);//0 if the gaussian point is above water level
-		ice_pressure   = rho_ice*gravity*(surface-z_g);
-		air_pressure   = 0;
-		pressure       = ice_pressure + water_pressure + air_pressure;
-
-		for (int i=0;i<numnodes;i++){
-			pe->values[2*i+0]+= pressure*Jdet*gauss->weight*normal[0]*basis[i];
-			pe->values[2*i+1]+= pressure*Jdet*gauss->weight*normal[1]*basis[i];
-		}
-	}
-
-	/*Transform coordinate system*/
-	TransformLoadVectorCoord(pe,nodes,numnodes,XYEnum);
-
-	/*Clean up and return*/
-	xDelete<IssmDouble>(basis);
-	delete gauss;
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Penta::CreatePVectorStressbalanceFS {{{*/
-ElementVector* Penta::CreatePVectorStressbalanceFS(void){
-
-	ElementVector* pe1;
-	ElementVector* pe2;
-	ElementVector* pe3;
-	ElementVector* pe;
-
-	/*compute all stiffness matrices for this element*/
-	pe1=CreatePVectorStressbalanceFSViscous();
-	pe2=CreatePVectorStressbalanceFSShelf();
-	pe3=CreatePVectorStressbalanceFSFront();
-	pe =new ElementVector(pe1,pe2,pe3);
-
-	/*clean-up and return*/
-	delete pe1;
-	delete pe2;
-	delete pe3;
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Penta::CreatePVectorStressbalanceFSFront{{{*/
-ElementVector* Penta::CreatePVectorStressbalanceFSFront(void){
-
-	/*Intermediaries */
-	int         i;
-	IssmDouble  ls[NUMVERTICES];
-	IssmDouble  xyz_list[NUMVERTICES][3];
-	bool        isfront;
-
-	/*Retrieve all inputs and parameters*/
-	GetInputListOnVertices(&ls[0],MaskIceLevelsetEnum);
-
-	/*If the level set is awlays <=0, there is no ice front here*/
-	isfront = false;
-	if(ls[0]>0. || ls[1]>0. || ls[2]>0.){
-		if(ls[0]*ls[1]<0. || ls[0]*ls[2]<0. || (ls[0]*ls[1]+ls[0]*ls[2]+ls[1]*ls[2]==0.)){
-			isfront = true;
-		}
-	}
-
-	/*If no front, return NULL*/
-	if(!isfront) return NULL;
-
-	/*Fetch number of nodes and dof for this finite element*/
-	IssmDouble  rho_ice,rho_water,gravity;
-	IssmDouble  Jdet,z_g,water_pressure,air_pressure;
-	IssmDouble  surface_under_water,base_under_water,pressure;
-	IssmDouble  xyz_list_front[4][3];
-	IssmDouble  area_coordinates[4][3];
-	IssmDouble  normal[3];
-	GaussPenta* gauss;
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int vnumnodes = this->NumberofNodesVelocity();
-	int pnumnodes = this->NumberofNodesPressure();
-
-	/*Prepare coordinate system list*/
-	int* cs_list = xNew<int>(vnumnodes+pnumnodes);
-	for(i=0;i<vnumnodes;i++) cs_list[i]           = XYZEnum;
-	for(i=0;i<pnumnodes;i++) cs_list[vnumnodes+i] = PressureEnum;
-
-	/*Initialize Element matrix and vectors*/
-	ElementVector* pe     = new ElementVector(nodes,vnumnodes+pnumnodes,this->parameters,FSvelocityEnum);
-	IssmDouble*    vbasis = xNew<IssmDouble>(vnumnodes);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	rho_water=matpar->GetRhoWater();
-	rho_ice  =matpar->GetRhoIce();
-	gravity  =matpar->GetG();
-	GetZeroLevelsetCoordinates(&xyz_list_front[0][0],xyz_list,MaskIceLevelsetEnum);
-	GetAreaCoordinates(&area_coordinates[0][0],xyz_list_front,xyz_list,4);
-	GetQuadNormal(&normal[0],xyz_list_front);
-
-	/*Start looping on Gaussian points*/
-	IssmDouble zmax=xyz_list[0][2]; for(int i=1;i<6;i++) if(xyz_list[i][2]>zmax) zmax=xyz_list[i][2];
-	IssmDouble zmin=xyz_list[0][2]; for(int i=1;i<6;i++) if(xyz_list[i][2]<zmin) zmin=xyz_list[i][2];
-	if(zmax>0 && zmin<0) gauss=new GaussPenta(area_coordinates,3,30); //refined in vertical because of the sea level discontinuity
-	else                 gauss=new GaussPenta(area_coordinates,3,3);
-
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-		z_g=GetZcoord(gauss);
-		GetNodalFunctionsVelocity(vbasis,gauss);
-		GetQuadJacobianDeterminant(&Jdet,xyz_list_front,gauss);
-
-		water_pressure=rho_water*gravity*min(0.,z_g);//0 if the gaussian point is above water level
-		air_pressure=0;
-		pressure = water_pressure + air_pressure;
-
-		for(i=0;i<vnumnodes;i++){
-			pe->values[3*i+0]+= pressure*Jdet*gauss->weight*normal[0]*vbasis[i];
-			pe->values[3*i+1]+= pressure*Jdet*gauss->weight*normal[1]*vbasis[i];
-			pe->values[3*i+2]+= pressure*Jdet*gauss->weight*normal[2]*vbasis[i];
-		}
-	}
-
-	/*Transform coordinate system*/
-	TransformLoadVectorCoord(pe,nodes,(vnumnodes+pnumnodes),cs_list);
-
-	/*Clean up and return*/
-	xDelete<int>(cs_list);
-	xDelete<IssmDouble>(vbasis);
-	delete gauss;
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Penta::PVectorGLSstabilization{{{*/
-void Penta::PVectorGLSstabilization(ElementVector* pe){
-
-	/*Intermediaries*/
-	int        i,j;
-	IssmDouble Jdet,gravity,rho_ice,B,D_scalar_stab,viscosity;
-	IssmDouble forcex,forcey,forcez,diameter,FSreconditioning;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble epsilon[6]; /* epsilon=[exx,eyy,ezz,exy,exz,eyz];*/
-	GaussPenta *gauss=NULL;
-
-	/*Stabilization*/
-	IssmDouble dbasis[3][6];
-	IssmDouble dmu[3];
-	IssmDouble mu;
-	IssmDouble dnodalbasis[6][6][3];
-	IssmDouble SW[6][4][4];
-	int p,ii;
-	int c=3; //index of pressure
-
-	/*Retrieve all inputs and parameters*/
-	rho_ice=matpar->GetRhoIce();
-	gravity=matpar->GetG();
-	B=material->GetB();
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);
-	Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);
-	Input* vz_input=inputs->GetInput(VzEnum); _assert_(vz_input);
-
-	/*Find minimal length*/
-	diameter=MinEdgeLength(xyz_list);
-
-		gauss=new GaussPenta();
-		for(int iv=0;iv<6;iv++){
-			gauss->GaussVertex(iv);
-			GetNodalFunctionsP1Derivatives(&dbasis[0][0],&xyz_list[0][0],gauss);
-			for(i=0;i<6;i++){
-				for(j=0;j<3;j++){
-					dnodalbasis[i][iv][j] = dbasis[j][i];
-				}
-			}
-		}
-		delete gauss;
-
-	/* Start  looping on the number of gaussian points: */
-	gauss=new GaussPenta(5,5);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		this->GetStrainRate3d(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input,vz_input);
-		material->GetViscosity3dFS(&viscosity,&epsilon[0]);
-
-		GetNodalFunctionsP1Derivatives(&dbasis[0][0],&xyz_list[0][0],gauss);
-		dmu[0]=0.; dmu[1]=0.; dmu[2]=0.;
-		mu = 2.*viscosity;
-		for(p=0;p<6;p++) for(i=0;i<4;i++) for(j=0;j<4;j++){
-			SW[p][i][j]=0.;
-		}
-		for(p=0;p<6;p++){
-			for(i=0;i<3;i++){
-				SW[p][c][i] += dbasis[i][p];
-				for(j=0;j<3;j++){
-					SW[p][i][i] += -dmu[j]*dbasis[j][p];
-					SW[p][j][i] += -dmu[j]*dbasis[i][p];
-					for(ii=0;ii<6;ii++){
-						SW[p][i][i] += -mu*dnodalbasis[p][ii][j]*dbasis[j][ii];
-						SW[p][j][i] += -mu*dnodalbasis[p][ii][i]*dbasis[j][ii];
-					}
-				}
-			}
-		}
-		IssmDouble tau = 1./3.*pow(diameter,2)/(8.*2.*viscosity);
-		for(p=0;p<6;p++){
-			for(j=0;j<4;j++){
-				pe->values[p*4+j] += gauss->weight*Jdet*tau*rho_ice*forcex*SW[p][j][0];
-				pe->values[p*4+j] += gauss->weight*Jdet*tau*rho_ice*forcey*SW[p][j][1];
-				pe->values[p*4+j] += gauss->weight*Jdet*tau*rho_ice*(forcez-gravity)*SW[p][j][2];
-			}
-		}
-	}
-
-	/*Clean up*/
-	delete gauss;
-}
-/*}}}*/
-/*FUNCTION Penta::CreatePVectorStressbalanceFSViscous {{{*/
-ElementVector* Penta::CreatePVectorStressbalanceFSViscous(void){
-
-	/*Intermediaries*/
-	int        i;
-	int        approximation;
-	IssmDouble Jdet,gravity,rho_ice;
-	IssmDouble forcex,forcey,forcez;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	GaussPenta *gauss=NULL;
-
-	/*Initialize Element vector and return if necessary*/
-	inputs->GetInputValue(&approximation,ApproximationEnum);
-	if(approximation!=FSApproximationEnum && approximation!=SSAFSApproximationEnum && approximation!=HOFSApproximationEnum) return NULL;
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int vnumnodes = this->NumberofNodesVelocity();
-	int pnumnodes = this->NumberofNodesPressure();
-
-	/*Prepare coordinate system list*/
-	int* cs_list = xNew<int>(vnumnodes+pnumnodes);
-	for(i=0;i<vnumnodes;i++) cs_list[i]           = XYZEnum;
-	for(i=0;i<pnumnodes;i++) cs_list[vnumnodes+i] = PressureEnum;
-
-	/*Initialize Element matrix and vectors*/
-	ElementVector* pe     = new ElementVector(nodes,vnumnodes+pnumnodes,this->parameters,FSvelocityEnum);
-	IssmDouble*    vbasis = xNew<IssmDouble>(vnumnodes);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	Input* loadingforcex_input=inputs->GetInput(LoadingforceXEnum);  _assert_(loadingforcex_input);
-	Input* loadingforcey_input=inputs->GetInput(LoadingforceYEnum);  _assert_(loadingforcey_input);
-	Input* loadingforcez_input=inputs->GetInput(LoadingforceZEnum);  _assert_(loadingforcez_input);
-	rho_ice = matpar->GetRhoIce();
-	gravity = matpar->GetG();
-
-	/* Start  looping on the number of gaussian points: */
-	gauss=new GaussPenta(5,5);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		GetNodalFunctionsVelocity(vbasis, gauss);
-
-		loadingforcex_input->GetInputValue(&forcex,gauss);
-		loadingforcey_input->GetInputValue(&forcey,gauss);
-		loadingforcez_input->GetInputValue(&forcez,gauss);
-
-		for(i=0;i<vnumnodes;i++){
-			pe->values[i*NDOF3+2] += -rho_ice*gravity*Jdet*gauss->weight*vbasis[i];
-			pe->values[i*NDOF3+0] += +rho_ice*forcex *Jdet*gauss->weight*vbasis[i];
-			pe->values[i*NDOF3+1] += +rho_ice*forcey *Jdet*gauss->weight*vbasis[i];
-			pe->values[i*NDOF3+2] += +rho_ice*forcez *Jdet*gauss->weight*vbasis[i];
-		}
-	}
-
-	/*Transform coordinate system*/
-	TransformLoadVectorCoord(pe,nodes,vnumnodes+pnumnodes,cs_list);
-
-	/*Clean up and return*/
-	delete gauss;
-	xDelete<int>(cs_list);
-	xDelete<IssmDouble>(vbasis);
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Penta::CreatePVectorStressbalanceFSShelf{{{*/
-ElementVector* Penta::CreatePVectorStressbalanceFSShelf(void){
-
-	/*Intermediaries*/
-	int         i,j;
-	int         approximation,shelf_dampening;
-	IssmDouble  gravity,rho_water,bed,water_pressure;
-	IssmDouble  damper,normal_vel,vx,vy,vz,dt;
-	IssmDouble	xyz_list_tria[NUMVERTICES2D][3];
-	IssmDouble  xyz_list[NUMVERTICES][3];
-	IssmDouble	bed_normal[3];
-	IssmDouble  dz[3];
-	IssmDouble  Jdet2d;
-	GaussPenta  *gauss=NULL;
-
-	/*Initialize Element vector and return if necessary*/
-	if(!IsOnBed() || !IsFloating()) return NULL;
-	inputs->GetInputValue(&approximation,ApproximationEnum);
-	if(approximation!=FSApproximationEnum && approximation!=SSAFSApproximationEnum && approximation!=HOFSApproximationEnum) return NULL;
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int vnumnodes = this->NumberofNodesVelocity();
-	int pnumnodes = this->NumberofNodesPressure();
-
-	/*Prepare coordinate system list*/
-	int* cs_list = xNew<int>(vnumnodes+pnumnodes);
-	for(i=0;i<vnumnodes;i++) cs_list[i]           = XYZEnum;
-	for(i=0;i<pnumnodes;i++) cs_list[vnumnodes+i] = PressureEnum;
-
-	/*Initialize Element matrix and vectors*/
-	ElementVector* pe     = new ElementVector(nodes,vnumnodes+pnumnodes,this->parameters,FSvelocityEnum);
-	IssmDouble*    vbasis = xNew<IssmDouble>(vnumnodes);
-
-	/*Retrieve all inputs and parameters*/
-	this->parameters->FindParam(&shelf_dampening,StressbalanceShelfDampeningEnum);
-	rho_water=matpar->GetRhoWater();
-	gravity=matpar->GetG();
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	Input* bed_input=inputs->GetInput(BedEnum); _assert_(bed_input);
-	Input* vx_input=inputs->GetInput(VxEnum);   _assert_(vx_input);
-	Input* vy_input=inputs->GetInput(VyEnum);   _assert_(vy_input);
-	Input* vz_input=inputs->GetInput(VzEnum);   _assert_(vz_input);
-
-	for(i=0;i<NUMVERTICES2D;i++) for(j=0;j<3;j++) xyz_list_tria[i][j]=xyz_list[i][j];
-
-	/* Start looping on the number of gauss 2d (nodes on the bedrock) */
-	gauss=new GaussPenta(0,1,2,2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetTriaJacobianDeterminant(&Jdet2d, &xyz_list_tria[0][0], gauss);
-		GetNodalFunctionsVelocity(vbasis, gauss);
-
-		BedNormal(&bed_normal[0],xyz_list_tria);
-		bed_input->GetInputValue(&bed, gauss);
-		if(shelf_dampening){ //add dampening to avoid too high vertical velocities when not in hydrostatic equilibrium
-			bed_input->GetInputDerivativeValue(&dz[0],&xyz_list[0][0],gauss);
-			vx_input->GetInputValue(&vx, gauss);
-			vy_input->GetInputValue(&vy, gauss);
-			vz_input->GetInputValue(&vz, gauss);
-			dt=0.;
-			normal_vel=bed_normal[0]*vx+bed_normal[1]*vy+bed_normal[2]*vz;
-			damper=gravity*rho_water*pow(1+pow(dz[0],2)+pow(dz[1],2),0.5)*normal_vel*dt;
-		}
-		else damper=0.;
-		water_pressure=gravity*rho_water*bed;
-
-		for(i=0;i<vnumnodes;i++){
-			pe->values[3*i+0]+=(water_pressure+damper)*gauss->weight*Jdet2d*vbasis[i]*bed_normal[0];
-			pe->values[3*i+1]+=(water_pressure+damper)*gauss->weight*Jdet2d*vbasis[i]*bed_normal[1];
-			pe->values[3*i+2]+=(water_pressure+damper)*gauss->weight*Jdet2d*vbasis[i]*bed_normal[2];
-		}
-	}
-
-	/*Transform coordinate system*/
-	TransformLoadVectorCoord(pe,nodes,(vnumnodes+pnumnodes),cs_list);
-
-	/*Clean up and return*/
-	delete gauss;
-	xDelete<int>(cs_list);
-	xDelete<IssmDouble>(vbasis);
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Penta::CreatePVectorStressbalanceVert {{{*/
-ElementVector* Penta::CreatePVectorStressbalanceVert(void){
-
-	/*compute all load vectors for this element*/
-	ElementVector* pe1=CreatePVectorStressbalanceVertVolume();
-	ElementVector* pe2=CreatePVectorStressbalanceVertBase();
-	ElementVector* pe =new ElementVector(pe1,pe2);
-
-	/*clean-up and return*/
-	delete pe1;
-	delete pe2;
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Penta::CreatePVectorStressbalanceVertVolume {{{*/
-ElementVector* Penta::CreatePVectorStressbalanceVertVolume(void){
-
-	/*Constants*/
-	const int  numdof=NDOF1*NUMVERTICES;
-
-	/*Intermediaries*/
-	int        approximation;
-	IssmDouble     Jdet;
-	IssmDouble     xyz_list[NUMVERTICES][3];
-	IssmDouble     dudx,dvdy,dwdz;
-	IssmDouble     du[3],dv[3],dw[3];
-	IssmDouble     basis[6];
-	GaussPenta *gauss=NULL;
-
-	/*Initialize Element vector*/
-	ElementVector* pe=new ElementVector(nodes,NUMVERTICES,this->parameters);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	inputs->GetInputValue(&approximation,ApproximationEnum);
-	Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);
-	Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);
-	Input* vzFS_input=NULL;
-	if(approximation==HOFSApproximationEnum || approximation==SSAFSApproximationEnum){
-		vzFS_input=inputs->GetInput(VzFSEnum); _assert_(vzFS_input);
-	}
-
-	/* Start  looping on the number of gaussian points: */
-	gauss=new GaussPenta(2,2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		GetNodalFunctionsP1(basis, gauss);
-
-		vx_input->GetInputDerivativeValue(&du[0],&xyz_list[0][0],gauss);
-		vy_input->GetInputDerivativeValue(&dv[0],&xyz_list[0][0],gauss);
-		if(approximation==HOFSApproximationEnum || approximation==SSAFSApproximationEnum){
-			vzFS_input->GetInputDerivativeValue(&dw[0],&xyz_list[0][0],gauss);
-			dwdz=dw[2];
-		}
-		else dwdz=0;
-		dudx=du[0];
-		dvdy=dv[1];
-
-		for(int i=0;i<numdof;i++) pe->values[i] += (dudx+dvdy+dwdz)*Jdet*gauss->weight*basis[i];
-	}
-
-	/*Clean up and return*/
-	delete gauss;
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Penta::CreatePVectorStressbalanceVertBase {{{*/
-ElementVector* Penta::CreatePVectorStressbalanceVertBase(void){
-
-	/*Constants*/
-	const int    numdof=NDOF1*NUMVERTICES;
-
-	/*Intermediaries */
-	int        i,j;
-	int        approximation;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble xyz_list_tria[NUMVERTICES2D][3];
-	IssmDouble Jdet2d;
-	IssmDouble vx,vy,vz,dbdx,dbdy,basalmeltingvalue;
-	IssmDouble slope[3];
-	IssmDouble basis[NUMVERTICES];
-	GaussPenta* gauss=NULL;
-
-	if (!IsOnBed()) return NULL;
-
-	/*Initialize Element vector*/
-	ElementVector* pe=new ElementVector(nodes,NUMVERTICES,this->parameters);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	for(i=0;i<NUMVERTICES2D;i++) for(j=0;j<3;j++) xyz_list_tria[i][j]=xyz_list[i][j];
-	inputs->GetInputValue(&approximation,ApproximationEnum);
-	Input* bed_input=inputs->GetInput(BedEnum);                                _assert_(bed_input);
-	Input* basal_melting_input=inputs->GetInput(BasalforcingsMeltingRateEnum); _assert_(basal_melting_input);
-	Input* vx_input=inputs->GetInput(VxEnum);                                  _assert_(vx_input);
-	Input* vy_input=inputs->GetInput(VyEnum);                                  _assert_(vy_input);
-	Input* vzFS_input=NULL;
-	if(approximation==HOFSApproximationEnum || approximation==SSAFSApproximationEnum){
-		vzFS_input=inputs->GetInput(VzFSEnum);       _assert_(vzFS_input);
-	}
-
-	/* Start  looping on the number of gaussian points: */
-	gauss=new GaussPenta(0,1,2,2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		basal_melting_input->GetInputValue(&basalmeltingvalue, gauss);
-		bed_input->GetInputDerivativeValue(&slope[0],&xyz_list[0][0],gauss);
-		vx_input->GetInputValue(&vx, gauss);
-		vy_input->GetInputValue(&vy, gauss);
-		if(approximation==HOFSApproximationEnum || approximation==SSAFSApproximationEnum){
-			vzFS_input->GetInputValue(&vz, gauss);
-		}
-		else vz=0;
-
-		dbdx=slope[0];
-		dbdy=slope[1];
-
-		GetTriaJacobianDeterminant(&Jdet2d, &xyz_list_tria[0][0],gauss);
-		GetNodalFunctionsP1(&basis[0], gauss);
-
-		for(i=0;i<numdof;i++) pe->values[i]+=-Jdet2d*gauss->weight*(vx*dbdx+vy*dbdy-vz-basalmeltingvalue)*basis[i];
-	}
-
-	/*Clean up and return*/
-	delete gauss;
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Penta::CreateJacobianStressbalanceHoriz{{{*/
-ElementMatrix* Penta::CreateJacobianStressbalanceHoriz(void){
-
-	int approximation;
-	inputs->GetInputValue(&approximation,ApproximationEnum);
-
-	switch(approximation){
-		case SSAApproximationEnum:
-			return CreateJacobianStressbalanceSSA2d();
-		case HOApproximationEnum:
-			return CreateJacobianStressbalanceHO();
-		case FSApproximationEnum:
-			return CreateJacobianStressbalanceFS();
-		case NoneApproximationEnum:
-			return NULL;
-		default:
-			_error_("Approximation " << EnumToStringx(approximation) << " not supported yet");
-	}
-}
-/*}}}*/
-/*FUNCTION Penta::CreateJacobianStressbalanceSSA2d{{{*/
-ElementMatrix* Penta::CreateJacobianStressbalanceSSA2d(void){
-
-	/*Figure out if this penta is collapsed. If so, then bailout, except if it is at the 
-	  bedrock, in which case we spawn a tria element using the 3 first nodes, and use it to build 
-	  the stiffness matrix. */
-	if (!IsOnBed()) return NULL;
-
-	/*Depth average some fields*/
-	switch(this->material->ObjectEnum()){
-		case MaticeEnum:
-			this->InputDepthAverageAtBase(MaterialsRheologyBEnum,MaterialsRheologyBbarEnum,MaterialsEnum);
-			this->InputDepthAverageAtBase(DamageDEnum,DamageDbarEnum,MaterialsEnum);
-			break;
-		default:
-			_error_("material "<<EnumToStringx(this->material->ObjectEnum())<<" not supported");
-	}
-
-	/*Call Tria function*/
-	Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.
-	ElementMatrix* Ke=tria->CreateJacobianStressbalanceSSA();
-	delete tria->material; delete tria;
-
-	/*Delete averaged inputs*/
-	this->material->inputs->DeleteInput(MaterialsRheologyBbarEnum);
-	this->material->inputs->DeleteInput(DamageDbarEnum);
-
-	/*clean up and return*/
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Penta::CreateJacobianStressbalanceHO{{{*/
-ElementMatrix* Penta::CreateJacobianStressbalanceHO(void){
-
-	/*Intermediaries */
-	int        i,j;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble Jdet;
-	IssmDouble eps1dotdphii,eps1dotdphij;
-	IssmDouble eps2dotdphii,eps2dotdphij;
-	IssmDouble mu_prime;
-	IssmDouble epsilon[5]; /* epsilon=[exx,eyy,exy,exz,eyz];*/
-	IssmDouble eps1[3],eps2[3];
-	IssmDouble dphi[3][NUMVERTICES];
-	GaussPenta *gauss=NULL;
-
-	/*Initialize Jacobian with regular HO (first part of the Gateau derivative)*/
-	ElementMatrix* Ke=CreateKMatrixStressbalanceHO();
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	Input* vx_input=inputs->GetInput(VxEnum);       _assert_(vx_input);
-	Input* vy_input=inputs->GetInput(VyEnum);       _assert_(vy_input);
-
-	/* Start  looping on the number of gaussian points: */
-	gauss=new GaussPenta(5,5);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		GetNodalFunctionsP1Derivatives(&dphi[0][0],&xyz_list[0][0],gauss);
-
-		this->GetStrainRate3dHO(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input);
-		material->GetViscosityDerivativeEpsSquare(&mu_prime,&epsilon[0]);
-		eps1[0]=2*epsilon[0]+epsilon[1];   eps2[0]=epsilon[2];
-		eps1[1]=epsilon[2];                eps2[1]=epsilon[0]+2*epsilon[1];
-		eps1[2]=epsilon[3];                eps2[2]=epsilon[4];
-
-		for(i=0;i<6;i++){
-			for(j=0;j<6;j++){
-				eps1dotdphii=eps1[0]*dphi[0][i]+eps1[1]*dphi[1][i]+eps1[2]*dphi[2][i];
-				eps1dotdphij=eps1[0]*dphi[0][j]+eps1[1]*dphi[1][j]+eps1[2]*dphi[2][j];
-				eps2dotdphii=eps2[0]*dphi[0][i]+eps2[1]*dphi[1][i]+eps2[2]*dphi[2][i];
-				eps2dotdphij=eps2[0]*dphi[0][j]+eps2[1]*dphi[1][j]+eps2[2]*dphi[2][j];
-
-				Ke->values[12*(2*i+0)+2*j+0]+=gauss->weight*Jdet*2*mu_prime*eps1dotdphij*eps1dotdphii;
-				Ke->values[12*(2*i+0)+2*j+1]+=gauss->weight*Jdet*2*mu_prime*eps2dotdphij*eps1dotdphii;
-				Ke->values[12*(2*i+1)+2*j+0]+=gauss->weight*Jdet*2*mu_prime*eps1dotdphij*eps2dotdphii;
-				Ke->values[12*(2*i+1)+2*j+1]+=gauss->weight*Jdet*2*mu_prime*eps2dotdphij*eps2dotdphii;
-			}
-		}
-	}
-
-	/*Transform Coordinate System*/
-	TransformStiffnessMatrixCoord(Ke,nodes,NUMVERTICES,XYEnum);
-
-	/*Clean up and return*/
-	delete gauss;
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Penta::CreateJacobianStressbalanceFS{{{*/
-ElementMatrix* Penta::CreateJacobianStressbalanceFS(void){
-
-	/*Intermediaries */
-	int        i,j;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble Jdet;
-	IssmDouble eps1dotdphii,eps1dotdphij;
-	IssmDouble eps2dotdphii,eps2dotdphij;
-	IssmDouble eps3dotdphii,eps3dotdphij;
-	IssmDouble mu_prime;
-	IssmDouble epsilon[6]; /* epsilon=[exx,eyy,ezz,exy,exz,eyz];*/
-	IssmDouble eps1[3],eps2[3],eps3[3];
-	GaussPenta *gauss=NULL;
-
-	/*If on water or not FS, skip stiffness: */
-	//inputs->GetInputValue(&approximation,ApproximationEnum);
-	//if(approximation!=FSApproximationEnum && approximation!=SSAFSApproximationEnum && approximation!=HOFSApproximationEnum) return NULL;
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int vnumnodes = this->NumberofNodesVelocity();
-	int pnumnodes = this->NumberofNodesPressure();
-	int numdof    = vnumnodes*NDOF3 + pnumnodes*NDOF1;
-
-	/*Prepare coordinate system list*/
-	int* cs_list = xNew<int>(vnumnodes+pnumnodes);
-	for(i=0;i<vnumnodes;i++) cs_list[i]           = XYZEnum;
-	for(i=0;i<pnumnodes;i++) cs_list[vnumnodes+i] = PressureEnum;
-
-	/*Initialize Jacobian with regular FS (first part of the Gateau derivative)*/
-	ElementMatrix* Ke=CreateKMatrixStressbalanceFS();
-	IssmDouble*    dbasis = xNew<IssmDouble>(3*vnumnodes);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);
-	Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);
-	Input* vz_input=inputs->GetInput(VzEnum); _assert_(vz_input);
-
-	/* Start  looping on the number of gaussian points: */
-	gauss=new GaussPenta(5,5);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetJacobianDeterminant(&Jdet,&xyz_list[0][0],gauss);
-		GetNodalFunctionsDerivativesVelocity(dbasis,&xyz_list[0][0],gauss);
-
-		//this->GetStrainRate3d(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input,vz_input);
-		//material->GetViscosityDerivativeEpsSquareFS(&mu_prime,&epsilon[0]);
-		//eps1[0]=epsilon[0];   eps2[0]=epsilon[3];   eps3[0]=epsilon[4];
-		//eps1[1]=epsilon[3];   eps2[1]=epsilon[1];   eps3[1]=epsilon[5];
-		//eps1[2]=epsilon[4];   eps2[2]=epsilon[5];   eps3[2]=epsilon[2];
-		this->GetStrainRate3dHO(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input);
-		material->GetViscosityDerivativeEpsSquare(&mu_prime,&epsilon[0]);
-		eps1[0]=epsilon[0];   eps2[0]=epsilon[2];   eps3[0]=epsilon[3];
-		eps1[1]=epsilon[2];   eps2[1]=epsilon[1];   eps3[1]=epsilon[4];
-		eps1[2]=epsilon[3];   eps2[2]=epsilon[4];   eps3[2]= -epsilon[0] -epsilon[1];
-
-		for(i=0;i<vnumnodes-1;i++){
-			for(j=0;j<vnumnodes-1;j++){
-				eps1dotdphii=eps1[0]*dbasis[0*vnumnodes+i]+eps1[1]*dbasis[1*vnumnodes+i]+eps1[2]*dbasis[2*vnumnodes+i];
-				eps1dotdphij=eps1[0]*dbasis[0*vnumnodes+j]+eps1[1]*dbasis[1*vnumnodes+j]+eps1[2]*dbasis[2*vnumnodes+j];
-				eps2dotdphii=eps2[0]*dbasis[0*vnumnodes+i]+eps2[1]*dbasis[1*vnumnodes+i]+eps2[2]*dbasis[2*vnumnodes+i];
-				eps2dotdphij=eps2[0]*dbasis[0*vnumnodes+j]+eps2[1]*dbasis[1*vnumnodes+j]+eps2[2]*dbasis[2*vnumnodes+j];
-				eps3dotdphii=eps3[0]*dbasis[0*vnumnodes+i]+eps3[1]*dbasis[1*vnumnodes+i]+eps3[2]*dbasis[2*vnumnodes+i];
-				eps3dotdphij=eps3[0]*dbasis[0*vnumnodes+j]+eps3[1]*dbasis[1*vnumnodes+j]+eps3[2]*dbasis[2*vnumnodes+j];
-
-				Ke->values[numdof*(3*i+0)+3*j+0]+=gauss->weight*Jdet*2*mu_prime*eps1dotdphij*eps1dotdphii;
-				Ke->values[numdof*(3*i+0)+3*j+1]+=gauss->weight*Jdet*2*mu_prime*eps2dotdphij*eps1dotdphii;
-				Ke->values[numdof*(3*i+0)+3*j+2]+=gauss->weight*Jdet*2*mu_prime*eps3dotdphij*eps1dotdphii;
-
-				Ke->values[numdof*(3*i+1)+3*j+0]+=gauss->weight*Jdet*2*mu_prime*eps1dotdphij*eps2dotdphii;
-				Ke->values[numdof*(3*i+1)+3*j+1]+=gauss->weight*Jdet*2*mu_prime*eps2dotdphij*eps2dotdphii;
-				Ke->values[numdof*(3*i+1)+3*j+2]+=gauss->weight*Jdet*2*mu_prime*eps3dotdphij*eps2dotdphii;
-
-				Ke->values[numdof*(3*i+2)+3*j+0]+=gauss->weight*Jdet*2*mu_prime*eps1dotdphij*eps3dotdphii;
-				Ke->values[numdof*(3*i+2)+3*j+1]+=gauss->weight*Jdet*2*mu_prime*eps2dotdphij*eps3dotdphii;
-				Ke->values[numdof*(3*i+2)+3*j+2]+=gauss->weight*Jdet*2*mu_prime*eps3dotdphij*eps3dotdphii;
-			}
-		}
-	}
-
-	/*Transform Coordinate System*/
-	TransformStiffnessMatrixCoord(Ke,nodes,(vnumnodes+pnumnodes),cs_list);
-
-	/*Clean up and return*/
-	xDelete<int>(cs_list);
-	xDelete<IssmDouble>(dbasis);
-	delete gauss;
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Penta::GetSolutionFromInputsStressbalanceHoriz{{{*/
-void  Penta::GetSolutionFromInputsStressbalanceHoriz(Vector<IssmDouble>* solution){
-
-	int         approximation;
-	int        *doflist = NULL;
-	IssmDouble  vx,vy;
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodes();
-	int numdof   = numnodes*NDOF2;
-
-	/*Get approximation enum and dof list: */
-	inputs->GetInputValue(&approximation,ApproximationEnum);
-	Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);
-	Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);
-
-	/*Fetch dof list and allocate solution vectors*/
-	GetDofList(&doflist,approximation,GsetEnum);
-	IssmDouble* values = xNew<IssmDouble>(numdof);
-
-	/*Ok, we have vx and vy in values, fill in vx and vy arrays: */
-	GaussPenta* gauss=new GaussPenta();
-	for(int i=0;i<numnodes;i++){
-		gauss->GaussNode(this->element_type,i);
-
-		/*Recover vx and vy*/
-		vx_input->GetInputValue(&vx,gauss);
-		vy_input->GetInputValue(&vy,gauss);
-		values[i*NDOF2+0]=vx;
-		values[i*NDOF2+1]=vy;
-	}
-
-	/*Add value to global vector*/
-	solution->SetValues(numdof,doflist,values,INS_VAL);
-
-	/*Free ressources:*/
-	delete gauss;
-	xDelete<IssmDouble>(values);
-	xDelete<int>(doflist);
-}
-/*}}}*/
-/*FUNCTION Penta::GetSolutionFromInputsStressbalanceSIA{{{*/
-void  Penta::GetSolutionFromInputsStressbalanceSIA(Vector<IssmDouble>* solution){
-
-	const int    numdof=NDOF2*NUMVERTICES;
-
-	int          i;
-	int*         doflist=NULL;
-	IssmDouble       vx,vy;
-	IssmDouble       values[numdof];
-	GaussPenta*  gauss=NULL;
-
-	/*Get dof list: */
-	GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
-	Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);
-	Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);
-
-	/*Ok, we have vx and vy in values, fill in vx and vy arrays: */
-	/*P1 element only for now*/
-	gauss=new GaussPenta();
-	for(i=0;i<NUMVERTICES;i++){
-		/*Recover vx and vy*/
-		gauss->GaussVertex(i);
-		vx_input->GetInputValue(&vx,gauss);
-		vy_input->GetInputValue(&vy,gauss);
-		values[i*NDOF2+0]=vx;
-		values[i*NDOF2+1]=vy;
-	}
-
-	/*Add value to global vector*/
-	solution->SetValues(numdof,doflist,values,INS_VAL);
-
-	/*Free ressources:*/
-	delete gauss;
-	xDelete<int>(doflist);
-}
-/*}}}*/
-/*FUNCTION Penta::GetSolutionFromInputsStressbalanceFS{{{*/
-void  Penta::GetSolutionFromInputsStressbalanceFS(Vector<IssmDouble>* solution){
-
-	int*         vdoflist=NULL;
-	int*         pdoflist=NULL;
-	IssmDouble   vx,vy,vz,p;
-	IssmDouble   FSreconditioning;
-	GaussPenta  *gauss;
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int vnumnodes = this->NumberofNodesVelocity();
-	int pnumnodes = this->NumberofNodesPressure();
-	int vnumdof   = vnumnodes*NDOF3;
-	int pnumdof   = pnumnodes*NDOF1;
-
-	/*Initialize values*/
-	IssmDouble* vvalues = xNew<IssmDouble>(vnumdof);
-	IssmDouble* pvalues = xNew<IssmDouble>(pnumdof);
-
-	/*Get dof list: */
-	GetDofListVelocity(&vdoflist,GsetEnum);
-	GetDofListPressure(&pdoflist,GsetEnum);
-	Input* vx_input=inputs->GetInput(VxEnum);       _assert_(vx_input);
-	Input* vy_input=inputs->GetInput(VyEnum);       _assert_(vy_input);
-	Input* vz_input=inputs->GetInput(VzEnum);       _assert_(vz_input);
-	Input* p_input =inputs->GetInput(PressureEnum); _assert_(p_input);
-
-	this->parameters->FindParam(&FSreconditioning,StressbalanceFSreconditioningEnum);
-
-	/*Ok, we have vx vy vz in values, fill in vx vy vz arrays: */
-	gauss = new GaussPenta();
-	for(int i=0;i<vnumnodes;i++){
-		gauss->GaussNode(this->VelocityInterpolation(),i);
-		vx_input->GetInputValue(&vx,gauss);
-		vy_input->GetInputValue(&vy,gauss);
-		vz_input->GetInputValue(&vz,gauss);
-		vvalues[i*NDOF3+0]=vx;
-		vvalues[i*NDOF3+1]=vy;
-		vvalues[i*NDOF3+2]=vz;
-	}
-	for(int i=0;i<pnumnodes;i++){
-		gauss->GaussNode(this->PressureInterpolation(),i);
-		p_input ->GetInputValue(&p ,gauss);
-		pvalues[i]=p/FSreconditioning;
-	}
-
-	/*Add value to global vector*/
-	solution->SetValues(vnumdof,vdoflist,vvalues,INS_VAL);
-	solution->SetValues(pnumdof,pdoflist,pvalues,INS_VAL);
-
-	/*Free ressources:*/
-	delete gauss;
-	xDelete<int>(pdoflist);
-	xDelete<int>(vdoflist);
-	xDelete<IssmDouble>(pvalues);
-	xDelete<IssmDouble>(vvalues);
-}
-/*}}}*/
-/*FUNCTION Penta::GetL1L2Viscosity{{{*/
-void Penta::GetL1L2Viscosity(IssmDouble* pviscosity,IssmDouble* xyz_list, GaussPenta* gauss, Input* vx_input, Input* vy_input,Input* surface_input){
-	/*Compute the L1L2 viscosity
-	 *
-	 *      1
-	 * mu = - A^-1 (sigma'_e)^(1-n)
-	 *      2
-	 *
-	 * sigma'_e^2 = |sigma'_//|^2 + |sigma'_perp|^2 (see Perego 2012 eq. 17,18)
-	 *
-	 * L1L2 assumptions:
-	 *
-	 * (1) |eps_b|_// = A (|sigma'_//|^2 + |sigma'_perp|^2)^((n-1)/2) |sigma'_//|
-	 * (2) |sigma'_perp|^2 = |rho g (s-z) grad(s)|^2
-	 *
-	 * Assuming that n = 3, we have a polynom of degree 3 to solve (the only unkown is X=|sigma'_//|)
-	 *
-	 * A X^3 + A |rho g (s-z) grad(s)|^2 X - |eps_b|_// = 0     */
-
-	int        i;
-	IssmDouble z,s,viscosity,p,q,delta;
-	IssmDouble tau_perp,tau_par,eps_b,A;
-	IssmDouble epsilonvx[5]; /*exx eyy exy exz eyz*/
-	IssmDouble epsilonvy[5]; /*exx eyy exy exz eyz*/
-	IssmDouble epsilon[5];   /*exx eyy exy exz eyz*/
-	IssmDouble z_list[NUMVERTICES];
-	IssmDouble slope[3];
-
-	/*Check that both inputs have been found*/
-	if (!vx_input || !vy_input || !surface_input) _error_("Input missing");
-
-	/*Get tau_perp*/
-	for(i=0;i<NUMVERTICES;i++) z_list[i]=xyz_list[3*i+2];
-	surface_input->GetInputValue(&s,gauss);
-	surface_input->GetInputDerivativeValue(&slope[0],xyz_list,gauss);
-	PentaRef::GetInputValue(&z,&z_list[0],gauss);
-	tau_perp = matpar->GetRhoIce() * matpar->GetG() * fabs(s-z)*sqrt(slope[0]*slope[0]+slope[1]*slope[1]);
-
-	/* Get eps_b*/
-	vx_input->GetVxStrainRate3dHO(epsilonvx,xyz_list,gauss);
-	vy_input->GetVyStrainRate3dHO(epsilonvy,xyz_list,gauss);
-	for(i=0;i<5;i++) epsilon[i]=epsilonvx[i]+epsilonvy[i];
-	eps_b = sqrt(epsilon[0]*epsilon[0] + epsilon[1]*epsilon[1] + epsilon[0]*epsilon[1] + epsilon[2]*epsilon[2]);
-	if(eps_b==0.){
-		*pviscosity = 2.5e+17;
-		return;
-	}
-
-	/*Get A*/
-	_assert_(material->GetN()==3.0);
-	A=material->GetA();
-
-	/*Solve for tau_perp (http://fr.wikipedia.org/wiki/Méthode_de_Cardan)*/
-	p     = tau_perp *tau_perp;
-	q     = - eps_b/A;
-	delta = q *q + p*p*p*4./27.;
-	_assert_(delta>0);
-	tau_par = pow(0.5*(-q+sqrt(delta)),1./3.) - pow(0.5*(q+sqrt(delta)),1./3.);
-
-	/*Viscosity*/
-	viscosity = 1./(2.*A*(tau_par*tau_par + tau_perp*tau_perp));
-	_assert_(!xIsNan(viscosity));
-	_assert_(viscosity > 0.);
-
-	/*Assign output pointer*/
-	*pviscosity = viscosity;
-	return; 
-}
-/*}}}*/
-/*FUNCTION Penta::InputUpdateFromSolutionStressbalanceHoriz {{{*/
-void  Penta::InputUpdateFromSolutionStressbalanceHoriz(IssmDouble* solution){
-
-	int  approximation;
-
-	/*Recover inputs*/
-	inputs->GetInputValue(&approximation,ApproximationEnum);
-
-	/*SSA, everything is done by the element on bed*/
-	if (approximation==SSAApproximationEnum){
-		if (!IsOnBed()){
-			/*Do nothing. Element on bed will take care of it*/
-			return;
-		}
-		else{
-			InputUpdateFromSolutionStressbalanceSSA(solution);
-			return;
-		}
-	}
-	if (approximation==L1L2ApproximationEnum){
-		if (!IsOnBed()) return;
-		InputUpdateFromSolutionStressbalanceL1L2(solution);
-		return;
-	}
-	else if (approximation==HOApproximationEnum){
-		InputUpdateFromSolutionStressbalanceHO(solution);
-	}
-	else if (approximation==HOFSApproximationEnum){
-		InputUpdateFromSolutionStressbalanceHOFS(solution);
-	}
-	else if (approximation==SSAFSApproximationEnum){
-		InputUpdateFromSolutionStressbalanceSSAFS(solution);
-	}
-	else if (approximation==FSApproximationEnum || approximation==NoneApproximationEnum){
-		InputUpdateFromSolutionStressbalanceFS(solution);
-	}
-	else if (approximation==SSAHOApproximationEnum){
-		InputUpdateFromSolutionStressbalanceSSAHO(solution);
-	}
-}
-/*}}}*/
-/*FUNCTION Penta::InputUpdateFromSolutionStressbalanceSSA {{{*/
-void  Penta::InputUpdateFromSolutionStressbalanceSSA(IssmDouble* solution){
-
-	int         numnodes = this->NumberofNodes();
-	int         numdof   = NDOF2*numnodes;
-
-	int         i;
-	IssmDouble  rho_ice,g;
-	IssmDouble  values[2*NUMVERTICES];
-	IssmDouble  vx[NUMVERTICES];
-	IssmDouble  vy[NUMVERTICES];
-	IssmDouble  vz[NUMVERTICES];
-	IssmDouble  vel[NUMVERTICES];
-	IssmDouble  pressure[NUMVERTICES];
-	IssmDouble  surface[NUMVERTICES];
-	IssmDouble  xyz_list[NUMVERTICES][3];
-	int        *doflist = NULL;
-	Penta      *penta   = NULL;
-
-	/*Get dof list: */
-	GetDofList(&doflist,SSAApproximationEnum,GsetEnum);
-
-	/*Use the dof list to index into the solution vector: */
-	for(i=0;i<numdof;i++) values[i]=solution[doflist[i]];
-
-	/*Transform solution in Cartesian Space*/
-	TransformSolutionCoord(&values[0],nodes,NUMVERTICES2D,XYEnum); /*2D: only the first 3 nodes are taken*/
-
-	/*Ok, we have vx and vy in values, fill in vx and vy arrays and extrude */
-	for(i=0;i<3;i++){
-		vx[i]  =values[i*NDOF2+0];
-		vy[i]  =values[i*NDOF2+1];
-		vx[i+3]=vx[i];
-		vy[i+3]=vy[i];
-
-		/*Check solution*/
-		if(xIsNan<IssmDouble>(vx[i])) _error_("NaN found in solution vector");
-		if(xIsNan<IssmDouble>(vy[i])) _error_("NaN found in solution vector");
-	}
-
-	/*Get parameters fro pressure computation*/
-	rho_ice=matpar->GetRhoIce();
-	g=matpar->GetG();
-
-	/*Start looping over all elements above current element and update all inputs*/
-	penta=this;
-	for(;;){
-
-		/*Get node data: */
-		GetVerticesCoordinates(&xyz_list[0][0],penta->vertices,NUMVERTICES);
-
-		/*Now Compute vel*/
-		GetInputListOnVertices(&vz[0],VzEnum,0.0); //default is 0
-		for(i=0;i<NUMVERTICES;i++) vel[i]=pow( pow(vx[i],2.0) + pow(vy[i],2.0) + pow(vz[i],2.0) , 0.5);
-
-		/*Now compute pressure*/
-		GetInputListOnVertices(&surface[0],SurfaceEnum);
-		for(i=0;i<NUMVERTICES;i++) pressure[i]=rho_ice*g*(surface[i]-xyz_list[i][2]);
-
-		/*Now, we have to move the previous Vx and Vy inputs  to old 
-		 * status, otherwise, we'll wipe them off: */
-		penta->inputs->ChangeEnum(VxEnum,VxPicardEnum);
-		penta->inputs->ChangeEnum(VyEnum,VyPicardEnum);
-		penta->inputs->ChangeEnum(PressureEnum,PressurePicardEnum);
-
-		/*Add vx and vy as inputs to the tria element: */
-		penta->inputs->AddInput(new PentaInput(VxEnum,vx,P1Enum));
-		penta->inputs->AddInput(new PentaInput(VyEnum,vy,P1Enum));
-		penta->inputs->AddInput(new PentaInput(VelEnum,vel,P1Enum));
-		penta->inputs->AddInput(new PentaInput(PressureEnum,pressure,P1Enum));
-
-		/*Stop if we have reached the surface*/
-		if (penta->IsOnSurface()) break;
-
-		/* get upper Penta*/
-		penta=penta->GetUpperElement(); _assert_(penta->Id()!=this->id);
-	}
-
-	/*Free ressources:*/
-	xDelete<int>(doflist);
-}
-/*}}}*/
-/*FUNCTION Penta::InputUpdateFromSolutionStressbalanceSSAHO {{{*/
-void  Penta::InputUpdateFromSolutionStressbalanceSSAHO(IssmDouble* solution){
-
-	const int    numdof=NDOF2*NUMVERTICES;
-	const int    numdof2d=NDOF2*NUMVERTICES2D;
-
-	int     i;
-	IssmDouble  rho_ice,g;
-	IssmDouble  SSA_values[numdof];
-	IssmDouble  HO_values[numdof];
-	IssmDouble  vx[NUMVERTICES];
-	IssmDouble  vy[NUMVERTICES];
-	IssmDouble  vz[NUMVERTICES];
-	IssmDouble  vel[NUMVERTICES];
-	IssmDouble  pressure[NUMVERTICES];
-	IssmDouble  surface[NUMVERTICES];
-	IssmDouble  xyz_list[NUMVERTICES][3];
-	int*    doflistp = NULL;
-	int*    doflistm = NULL;
-	Penta   *penta   = NULL;
-
-	/*OK, we have to add results of this element for HO 
-	 * and results from the penta at base for SSA. Now recover results*/
-	penta=GetBasalElement();
-
-	/*Get dof listof this element (HO dofs) and of the penta at base (SSA dofs): */
-	GetDofList(&doflistp,HOApproximationEnum,GsetEnum);
-	penta->GetDofList(&doflistm,SSAApproximationEnum,GsetEnum);
-
-	/*Get node data: */
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-
-	/*Use the dof list to index into the solution vector: */
-	for(i=0;i<numdof2d;i++){
-		HO_values[i]=solution[doflistp[i]];
-		SSA_values[i]=solution[doflistm[i]];
-	}
-	for(i=numdof2d;i<numdof;i++){
-		HO_values[i]=solution[doflistp[i]];
-		SSA_values[i]=SSA_values[i-numdof2d];
-	}
-
-	/*Transform solution in Cartesian Space*/
-	TransformSolutionCoord(&SSA_values[0],penta->nodes,NUMVERTICES,XYEnum);
-	TransformSolutionCoord(&HO_values[0],   this->nodes,NUMVERTICES,XYEnum);
-
-	/*Ok, we have vx and vy in values, fill in vx and vy arrays: */
-	for(i=0;i<NUMVERTICES;i++){
-		vx[i]=SSA_values[i*NDOF2+0]+HO_values[i*NDOF2+0];
-		vy[i]=SSA_values[i*NDOF2+1]+HO_values[i*NDOF2+1];
-
-		/*Check solution*/
-		if(xIsNan<IssmDouble>(vx[i])) _error_("NaN found in solution vector");
-		if(xIsNan<IssmDouble>(vy[i])) _error_("NaN found in solution vector");
-	}
-
-	/*Now Compute vel*/
-	GetInputListOnVertices(&vz[0],VzEnum,0.0); //default is 0
-	for(i=0;i<NUMVERTICES;i++) vel[i]=pow( pow(vx[i],2.0) + pow(vy[i],2.0) + pow(vz[i],2.0) , 0.5);
-
-	/*For pressure: we have not computed pressure in this analysis, for this element. We are in 3D, 
-	 *so the pressure is just the pressure at the z elevation: */
-	rho_ice=matpar->GetRhoIce();
-	g=matpar->GetG();
-	GetInputListOnVertices(&surface[0],SurfaceEnum);
-	for(i=0;i<NUMVERTICES;i++) pressure[i]=rho_ice*g*(surface[i]-xyz_list[i][2]);
-
-	/*Now, we have to move the previous Vx and Vy inputs  to old 
-	 * status, otherwise, we'll wipe them off: */
-	this->inputs->ChangeEnum(VxEnum,VxPicardEnum);
-	this->inputs->ChangeEnum(VyEnum,VyPicardEnum);
-	this->inputs->ChangeEnum(PressureEnum,PressurePicardEnum);
-
-	/*Add vx and vy as inputs to the tria element: */
-	this->inputs->AddInput(new PentaInput(VxEnum,vx,P1Enum));
-	this->inputs->AddInput(new PentaInput(VyEnum,vy,P1Enum));
-	this->inputs->AddInput(new PentaInput(VelEnum,vel,P1Enum));
-	this->inputs->AddInput(new PentaInput(PressureEnum,pressure,P1Enum));
-
-	/*Free ressources:*/
-	xDelete<int>(doflistp);
-	xDelete<int>(doflistm);
-}
-/*}}}*/
-/*FUNCTION Penta::InputUpdateFromSolutionStressbalanceSSAFS {{{*/
-void  Penta::InputUpdateFromSolutionStressbalanceSSAFS(IssmDouble* solution){
-
-	const int    numdofSSA = NDOF2*NUMVERTICES;
-	const int    numdof2d  = NDOF2*NUMVERTICES2D;
-	const int    numdofFSv = NDOF3*NUMVERTICES;
-	const int    numdofFSp = NDOF1*NUMVERTICES;
-
-	int     i;
-	IssmDouble  FSreconditioning;
-	IssmDouble  SSA_values[numdofSSA];
-	IssmDouble  FS_values[numdofFSv+numdofFSp];
-	IssmDouble  vx[NUMVERTICES];
-	IssmDouble  vy[NUMVERTICES];
-	IssmDouble  vz[NUMVERTICES];
-	IssmDouble  vzSSA[NUMVERTICES];
-	IssmDouble  vzFS[NUMVERTICES];
-	IssmDouble  vel[NUMVERTICES];
-	IssmDouble  pressure[NUMVERTICES];
-	IssmDouble  xyz_list[NUMVERTICES][3];
-	int   *doflistSSA = NULL;
-	int   *doflistFSv = NULL;
-	int   *doflistFSp = NULL;
-	Penta *penta      = NULL;
-
-	/*Prepare coordinate system list*/
-	int* cs_list = xNew<int>(2*NUMVERTICES);
-	for(i=0;i<NUMVERTICES;i++) cs_list[i]             = XYZEnum;
-	for(i=0;i<NUMVERTICES;i++) cs_list[NUMVERTICES+i] = PressureEnum;
-
-	/*OK, we have to add results of this element for SSA 
-	 * and results from the penta at base for SSA. Now recover results*/
-	penta=GetBasalElement();
-
-	/*Get dof listof this element (SSA dofs) and of the penta at base (SSA dofs): */
-	penta->GetDofList(&doflistSSA,SSAApproximationEnum,GsetEnum);
-	GetDofList(&doflistFSv,FSvelocityEnum,GsetEnum);
-	GetDofListPressure(&doflistFSp,GsetEnum);
-	this->parameters->FindParam(&FSreconditioning,StressbalanceFSreconditioningEnum);
-
-	/*Get node data: */
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-
-	/*Use the dof list to index into the solution vector: */
-	for(i=0;i<numdof2d;i++){
-		SSA_values[i]=solution[doflistSSA[i]];
-		SSA_values[i+numdof2d]=solution[doflistSSA[i]];
-	}
-	for(i=0;i<numdofFSv;i++) FS_values[i]=solution[doflistFSv[i]];
-	for(i=0;i<numdofFSp;i++) FS_values[numdofFSv+i]=solution[doflistFSp[i]];
-
-	/*Transform solution in Cartesian Space*/
-	TransformSolutionCoord(&SSA_values[0],this->nodes,NUMVERTICES,XYEnum);
-	TransformSolutionCoord(&FS_values[0],this->nodes,2*NUMVERTICES,cs_list);
-
-	/*Ok, we have vx and vy in values, fill in vx and vy arrays: */
-	for(i=0;i<NUMVERTICES;i++){
-		vx[i]       = FS_values[i*NDOF3+0]+SSA_values[i*NDOF2+0];
-		vy[i]       = FS_values[i*NDOF3+1]+SSA_values[i*NDOF2+1];
-		vzFS[i]     = FS_values[i*NDOF3+2];
-		pressure[i] = FS_values[NUMVERTICES*NDOF3+i]*FSreconditioning;
-
-		/*Check solution*/
-		if(xIsNan<IssmDouble>(vx[i]))       _error_("NaN found in solution vector");
-		if(xIsNan<IssmDouble>(vy[i]))       _error_("NaN found in solution vector");
-		if(xIsNan<IssmDouble>(vzFS[i]))     _error_("NaN found in solution vector");
-		if(xIsNan<IssmDouble>(pressure[i])) _error_("NaN found in solution vector");
-	}
-
-	/*Get Vz*/
-	Input* vzSSA_input=inputs->GetInput(VzSSAEnum);
-	if (vzSSA_input){
-		if (vzSSA_input->ObjectEnum()!=PentaInputEnum){
-			_error_("Cannot compute Vel as VzSSA is of type " << EnumToStringx(vzSSA_input->ObjectEnum()));
-		}
-		GetInputListOnVertices(&vzSSA[0],VzSSAEnum);
-	}
-	else{
-		_error_("Cannot update solution as VzSSA is not present");
-	}
-
-	/*Now Compute vel*/
-	for(i=0;i<NUMVERTICES;i++) {
-		vz[i]  = vzSSA[i]+vzFS[i];
-		vel[i] = sqrt(vx[i]*vx[i] + vy[i]*vy[i] + vz[i]*vz[i]);
-	}
-
-	/*Now, we have to move the previous Vx and Vy inputs  to old 
-	 * status, otherwise, we'll wipe them off: */
-	this->inputs->ChangeEnum(VxEnum,VxPicardEnum);
-	this->inputs->ChangeEnum(VyEnum,VyPicardEnum);
-	this->inputs->ChangeEnum(VzEnum,VzPicardEnum);
-	this->inputs->ChangeEnum(PressureEnum,PressurePicardEnum);
-
-	/*Add vx and vy as inputs to the tria element: */
-	this->inputs->AddInput(new PentaInput(VxEnum,vx,P1Enum));
-	this->inputs->AddInput(new PentaInput(VyEnum,vy,P1Enum));
-	this->inputs->AddInput(new PentaInput(VzEnum,vz,P1Enum));
-	this->inputs->AddInput(new PentaInput(VzFSEnum,vzFS,P1Enum));
-	this->inputs->AddInput(new PentaInput(VelEnum,vel,P1Enum));
-	this->inputs->AddInput(new PentaInput(PressureEnum,pressure,P1Enum));
-
-	/*Free ressources:*/
-	xDelete<int>(doflistSSA);
-	xDelete<int>(doflistFSv);
-	xDelete<int>(doflistFSp);
-	xDelete<int>(cs_list);
-}
-/*}}}*/
-/*FUNCTION Penta::InputUpdateFromSolutionStressbalanceL1L2 {{{*/
-void  Penta::InputUpdateFromSolutionStressbalanceL1L2(IssmDouble* solution){
-
-	const int    numdof=NDOF2*NUMVERTICES;
-
-	int     i;
-	IssmDouble  rho_ice,g;
-	IssmDouble  values[numdof];
-	IssmDouble  vx[NUMVERTICES];
-	IssmDouble  vy[NUMVERTICES];
-	IssmDouble  vz[NUMVERTICES];
-	IssmDouble  vel[NUMVERTICES];
-	IssmDouble  pressure[NUMVERTICES];
-	IssmDouble  surface[NUMVERTICES];
-	IssmDouble  xyz_list[NUMVERTICES][3];
-	int    *doflist = NULL;
-	Penta  *penta   = NULL;
-
-	/*Get dof list: */
-	GetDofList(&doflist,L1L2ApproximationEnum,GsetEnum);
-
-	/*Use the dof list to index into the solution vector: */
-	for(i=0;i<numdof;i++) values[i]=solution[doflist[i]];
-
-	/*Transform solution in Cartesian Space*/
-	TransformSolutionCoord(&values[0],nodes,NUMVERTICES2D,XYEnum); /*2D: only the first 3 nodes are taken*/
-
-	/*Ok, we have vx and vy in values, fill in vx and vy arrays and extrude */
-	for(i=0;i<3;i++){
-		vx[i]  =values[i*NDOF2+0];
-		vy[i]  =values[i*NDOF2+1];
-		vx[i+3]=vx[i];
-		vy[i+3]=vy[i];
-
-		/*Check solution*/
-		if(xIsNan<IssmDouble>(vx[i])) _error_("NaN found in solution vector");
-		if(xIsNan<IssmDouble>(vy[i])) _error_("NaN found in solution vector");
-	}
-
-	/*Get parameters fro pressure computation*/
-	rho_ice=matpar->GetRhoIce();
-	g=matpar->GetG();
-
-	/*Start looping over all elements above current element and update all inputs*/
-	penta=this;
-	for(;;){
-
-		/*Get node data: */
-		GetVerticesCoordinates(&xyz_list[0][0],penta->vertices,NUMVERTICES);
-
-		/*Now Compute vel*/
-		GetInputListOnVertices(&vz[0],VzEnum,0.0); //default is 0
-		for(i=0;i<NUMVERTICES;i++) vel[i]=pow( pow(vx[i],2.0) + pow(vy[i],2.0) + pow(vz[i],2.0) , 0.5);
-
-		/*Now compute pressure*/
-		GetInputListOnVertices(&surface[0],SurfaceEnum);
-		for(i=0;i<NUMVERTICES;i++) pressure[i]=rho_ice*g*(surface[i]-xyz_list[i][2]);
-
-		/*Now, we have to move the previous Vx and Vy inputs  to old 
-		 * status, otherwise, we'll wipe them off: */
-		penta->inputs->ChangeEnum(VxEnum,VxPicardEnum);
-		penta->inputs->ChangeEnum(VyEnum,VyPicardEnum);
-		penta->inputs->ChangeEnum(PressureEnum,PressurePicardEnum);
-
-		/*Add vx and vy as inputs to the tria element: */
-		penta->inputs->AddInput(new PentaInput(VxEnum,vx,P1Enum));
-		penta->inputs->AddInput(new PentaInput(VyEnum,vy,P1Enum));
-		penta->inputs->AddInput(new PentaInput(VelEnum,vel,P1Enum));
-		penta->inputs->AddInput(new PentaInput(PressureEnum,pressure,P1Enum));
-
-		/*Stop if we have reached the surface*/
-		if (penta->IsOnSurface()) break;
-
-		/* get upper Penta*/
-		penta=penta->GetUpperElement(); _assert_(penta->Id()!=this->id);
-	}
-
-	/*Free ressources:*/
-	xDelete<int>(doflist);
-}
-/*}}}*/
-/*FUNCTION Penta::InputUpdateFromSolutionStressbalanceHO {{{*/
-void  Penta::InputUpdateFromSolutionStressbalanceHO(IssmDouble* solution){
-
-	int         i;
-	IssmDouble  rho_ice,g;
-	IssmDouble  xyz_list[NUMVERTICES][3];
-	int        *doflist = NULL;
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodes();
-	int numdof   = numnodes*NDOF2;
-
-	/*Fetch dof list and allocate solution vectors*/
-	GetDofList(&doflist,HOApproximationEnum,GsetEnum);
-	IssmDouble* values    = xNew<IssmDouble>(numdof);
-	IssmDouble* vx        = xNew<IssmDouble>(numnodes);
-	IssmDouble* vy        = xNew<IssmDouble>(numnodes);
-	IssmDouble* vz        = xNew<IssmDouble>(numnodes);
-	IssmDouble* vel       = xNew<IssmDouble>(numnodes);
-	IssmDouble* pressure  = xNew<IssmDouble>(numnodes);
-	IssmDouble* surface   = xNew<IssmDouble>(numnodes);
-
-	/*Use the dof list to index into the solution vector: */
-	for(i=0;i<numdof;i++) values[i]=solution[doflist[i]];
-
-	/*Transform solution in Cartesian Space*/
-	TransformSolutionCoord(&values[0],nodes,NUMVERTICES,XYEnum);
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-
-	/*Ok, we have vx and vy in values, fill in vx and vy arrays: */
-	for(i=0;i<numnodes;i++){
-		vx[i]=values[i*NDOF2+0];
-		vy[i]=values[i*NDOF2+1];
-
-		/*Check solution*/
-		if(xIsNan<IssmDouble>(vx[i])) _error_("NaN found in solution vector");
-		if(xIsNan<IssmDouble>(vy[i])) _error_("NaN found in solution vector");
-	}
-
-	/*Get Vz and compute vel*/
-	GetInputListOnNodes(&vz[0],VzEnum,0.);
-	for(i=0;i<numnodes;i++) vel[i]=sqrt(vx[i]*vx[i] + vy[i]*vy[i] + vz[i]*vz[i]);
-
-	/*For pressure: we have not computed pressure in this analysis, for this element. We are in 3D, 
-	 *so the pressure is just the pressure at the z elevation: */
-	rho_ice=matpar->GetRhoIce();
-	g=matpar->GetG();
-	GetInputListOnVertices(&surface[0],SurfaceEnum);
-	for(i=0;i<NUMVERTICES;i++) pressure[i]=rho_ice*g*(surface[i]-xyz_list[i][2]);
-
-	/*Now, we have to move the previous Vx and Vy inputs  to old 
-	 * status, otherwise, we'll wipe them off: */
-	this->inputs->ChangeEnum(VxEnum,VxPicardEnum);
-	this->inputs->ChangeEnum(VyEnum,VyPicardEnum);
-	this->inputs->ChangeEnum(PressureEnum,PressurePicardEnum);
-
-	/*Add vx and vy as inputs to the tria element: */
-	this->inputs->AddInput(new PentaInput(VxEnum,vx,P1Enum));
-	this->inputs->AddInput(new PentaInput(VyEnum,vy,P1Enum));
-	this->inputs->AddInput(new PentaInput(VelEnum,vel,P1Enum));
-	this->inputs->AddInput(new PentaInput(PressureEnum,pressure,P1Enum));
-
-	/*Free ressources:*/
-	xDelete<IssmDouble>(surface);
-	xDelete<IssmDouble>(pressure);
-	xDelete<IssmDouble>(vel);
-	xDelete<IssmDouble>(vz);
-	xDelete<IssmDouble>(vy);
-	xDelete<IssmDouble>(vx);
-	xDelete<IssmDouble>(values);
-	xDelete<int>(doflist);
-}
-/*}}}*/
-/*FUNCTION Penta::InputUpdateFromSolutionStressbalanceHOFS {{{*/
-void  Penta::InputUpdateFromSolutionStressbalanceHOFS(IssmDouble* solution){
-
-	const int    numdofHO  = NDOF2*NUMVERTICES;
-	const int    numdofFSv = NDOF3*NUMVERTICES;
-	const int    numdofFSp = NDOF1*NUMVERTICES;
-
-	int        i;
-	IssmDouble HO_values[numdofHO];
-	IssmDouble FS_values[numdofFSv+numdofFSp];
-	IssmDouble vx[NUMVERTICES];
-	IssmDouble vy[NUMVERTICES];
-	IssmDouble vz[NUMVERTICES];
-	IssmDouble vzHO[NUMVERTICES];
-	IssmDouble vzFS[NUMVERTICES];
-	IssmDouble vel[NUMVERTICES];
-	IssmDouble pressure[NUMVERTICES];
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble FSreconditioning;
-	int*       doflistHO        = NULL;
-	int*       doflistFSv        = NULL;
-	int*       doflistFSp = NULL;
-
-	/*Prepare coordinate system list*/
-	int* cs_list = xNew<int>(2*NUMVERTICES);
-	for(i=0;i<NUMVERTICES;i++) cs_list[i]             = XYZEnum;
-	for(i=0;i<NUMVERTICES;i++) cs_list[NUMVERTICES+i] = PressureEnum;
-
-	/*Get dof listof this element (HO dofs) and of the penta at base (SSA dofs): */
-	GetDofList(&doflistHO,HOApproximationEnum,GsetEnum);
-	GetDofList(&doflistFSv,FSvelocityEnum,GsetEnum);
-	GetDofListPressure(&doflistFSp,GsetEnum);
-	this->parameters->FindParam(&FSreconditioning,StressbalanceFSreconditioningEnum);
-
-	/*Get node data: */
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-
-	/*Use the dof list to index into the solution vector: */
-	for(i=0;i<numdofHO;i++)  HO_values[i]=solution[doflistHO[i]];
-	for(i=0;i<numdofFSv;i++) FS_values[i]=solution[doflistFSv[i]];
-	for(i=0;i<numdofFSp;i++) FS_values[numdofFSv+i]=solution[doflistFSp[i]];
-
-	/*Transform solution in Cartesian Space*/
-	TransformSolutionCoord(&HO_values[0],this->nodes,NUMVERTICES,XYEnum);
-	TransformSolutionCoord(&FS_values[0],this->nodes,2*NUMVERTICES,cs_list);
-
-	/*Ok, we have vx and vy in values, fill in vx and vy arrays: */
-	for(i=0;i<NUMVERTICES;i++){
-		vx[i]       = FS_values[i*NDOF3+0]+HO_values[i*NDOF2+0];
-		vy[i]       = FS_values[i*NDOF3+1]+HO_values[i*NDOF2+1];
-		vzFS[i]     = FS_values[i*NDOF3+2];
-		pressure[i] = FS_values[NUMVERTICES*NDOF3+i]*FSreconditioning;
-
-		/*Check solution*/
-		if(xIsNan<IssmDouble>(vx[i]))       _error_("NaN found in solution vector");
-		if(xIsNan<IssmDouble>(vy[i]))       _error_("NaN found in solution vector");
-		if(xIsNan<IssmDouble>(vzFS[i]))     _error_("NaN found in solution vector");
-		if(xIsNan<IssmDouble>(pressure[i])) _error_("NaN found in solution vector");
-	}
-
-	/*Get Vz*/
-	Input* vzHO_input=inputs->GetInput(VzHOEnum);
-	if (vzHO_input){
-		if (vzHO_input->ObjectEnum()!=PentaInputEnum){
-			_error_("Cannot compute Vel as VzHO is of type " << EnumToStringx(vzHO_input->ObjectEnum()));
-		}
-		GetInputListOnVertices(&vzHO[0],VzHOEnum);
-	}
-	else{
-		_error_("Cannot update solution as VzHO is not present");
-	}
-
-	/*Now Compute vel*/
-	for(i=0;i<NUMVERTICES;i++) {
-		vz[i]  = vzHO[i]+vzFS[i];
-		vel[i] = sqrt(vx[i]*vx[i] + vy[i]*vy[i] + vz[i]*vz[i]);
-	}
-
-	/*Now, we have to move the previous Vx and Vy inputs  to old 
-	 * status, otherwise, we'll wipe them off: */
-	this->inputs->ChangeEnum(VxEnum,VxPicardEnum);
-	this->inputs->ChangeEnum(VyEnum,VyPicardEnum);
-	this->inputs->ChangeEnum(VzEnum,VzPicardEnum);
-	this->inputs->ChangeEnum(PressureEnum,PressurePicardEnum);
-
-	/*Add vx and vy as inputs to the tria element: */
-	this->inputs->AddInput(new PentaInput(VxEnum,vx,P1Enum));
-	this->inputs->AddInput(new PentaInput(VyEnum,vy,P1Enum));
-	this->inputs->AddInput(new PentaInput(VzEnum,vz,P1Enum));
-	this->inputs->AddInput(new PentaInput(VzFSEnum,vzFS,P1Enum));
-	this->inputs->AddInput(new PentaInput(VelEnum,vel,P1Enum));
-	this->inputs->AddInput(new PentaInput(PressureEnum,pressure,P1Enum));
-
-	/*Free ressources:*/
-	xDelete<int>(doflistHO);
-	xDelete<int>(doflistFSv);
-	xDelete<int>(doflistFSp);
-	xDelete<int>(cs_list);
-}
-/*}}}*/
-/*FUNCTION Penta::InputUpdateFromSolutionStressbalanceSIA {{{*/
-void  Penta::InputUpdateFromSolutionStressbalanceSIA(IssmDouble* solution){
-
-	int         numnodes = this->NumberofNodes();
-	int         numdof=NDOF2*numnodes;
-
-	int     i;
-	IssmDouble  rho_ice,g;
-	IssmDouble  values[numdof];
-	IssmDouble  vx[NUMVERTICES];
-	IssmDouble  vy[NUMVERTICES];
-	IssmDouble  vz[NUMVERTICES];
-	IssmDouble  vel[NUMVERTICES];
-	IssmDouble  pressure[NUMVERTICES];
-	IssmDouble  surface[NUMVERTICES];
-	IssmDouble  xyz_list[NUMVERTICES][3];
-	int*    doflist = NULL;
-
-	/*Get dof list: */
-	GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
-
-	/*Get node data: */
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-
-	/*Use the dof list to index into the solution vector: */
-	for(i=0;i<numdof;i++) values[i]=solution[doflist[i]];
-
-	/*Ok, we have vx and vy in values, fill in vx and vy arrays: */
-	for(i=0;i<NUMVERTICES;i++){
-		vx[i]=values[i*NDOF2+0];
-		vy[i]=values[i*NDOF2+1];
-
-		/*Check solution*/
-		if(xIsNan<IssmDouble>(vx[i])) _error_("NaN found in solution vector");
-		if(xIsNan<IssmDouble>(vy[i])) _error_("NaN found in solution vector");
-	}
-
-	/*Now Compute vel*/
-	GetInputListOnVertices(&vz[0],VzEnum,0.0); //default is 0
-	for(i=0;i<NUMVERTICES;i++) vel[i]=pow( pow(vx[i],2.0) + pow(vy[i],2.0) + pow(vz[i],2.0) , 0.5);
-
-	/*For pressure: we have not computed pressure in this analysis, for this element. We are in 3D, 
-	 *so the pressure is just the pressure at the z elevation: */
-	rho_ice=matpar->GetRhoIce();
-	g=matpar->GetG();
-	GetInputListOnVertices(&surface[0],SurfaceEnum);
-	for(i=0;i<NUMVERTICES;i++) pressure[i]=rho_ice*g*(surface[i]-xyz_list[i][2]);
-
-	/*Now, we have to move the previous Vx and Vy inputs  to old 
-	 * status, otherwise, we'll wipe them off: */
-	this->inputs->ChangeEnum(VxEnum,VxPicardEnum);
-	this->inputs->ChangeEnum(VyEnum,VyPicardEnum);
-	this->inputs->ChangeEnum(PressureEnum,PressurePicardEnum);
-
-	/*Add vx and vy as inputs to the tria element: */
-	this->inputs->AddInput(new PentaInput(VxEnum,vx,P1Enum));
-	this->inputs->AddInput(new PentaInput(VyEnum,vy,P1Enum));
-	this->inputs->AddInput(new PentaInput(VelEnum,vel,P1Enum));
-	this->inputs->AddInput(new PentaInput(PressureEnum,pressure,P1Enum));
-
-	/*Free ressources:*/
-	xDelete<int>(doflist);
-}
-/*}}}*/
-/*FUNCTION Penta::InputUpdateFromSolutionStressbalanceVert {{{*/
-void  Penta::InputUpdateFromSolutionStressbalanceVert(IssmDouble* solution){
-
-	int          numnodes = this->NumberofNodes();
-	int          numdof=NDOF1*numnodes;
-
-	int          i;
-	int          approximation;
-	IssmDouble   rho_ice,g;
-	IssmDouble   values[numdof];
-	IssmDouble   vx[NUMVERTICES];
-	IssmDouble   vy[NUMVERTICES];
-	IssmDouble   vz[NUMVERTICES];
-	IssmDouble   vzSSA[NUMVERTICES];
-	IssmDouble   vzHO[NUMVERTICES];
-	IssmDouble   vzFS[NUMVERTICES];
-	IssmDouble   vel[NUMVERTICES];
-	IssmDouble   pressure[NUMVERTICES];
-	IssmDouble   surface[NUMVERTICES];
-	IssmDouble   xyz_list[NUMVERTICES][3];
-	int*         doflist      = NULL;
-
-	/*Get the approximation and do nothing if the element in FS or None*/
-	inputs->GetInputValue(&approximation,ApproximationEnum);
-	if(approximation==FSApproximationEnum || approximation==NoneApproximationEnum){
-		return;
-	}
-
-	/*Get dof list and vertices coordinates: */
-	GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-
-	/*Use the dof list to index into the solution vector vz: */
-	for(i=0;i<numdof;i++) values[i]=solution[doflist[i]];
-	for(i=0;i<NUMVERTICES;i++){
-		vz[i]=values[i*NDOF1+0];
-
-		/*Check solution*/
-		if(xIsNan<IssmDouble>(vz[i])) _error_("NaN found in solution vector");
-	}
-
-	/*Get Vx and Vy*/
-	GetInputListOnVertices(&vx[0],VxEnum,0.0); //default is 0
-	GetInputListOnVertices(&vy[0],VyEnum,0.0); //default is 0
-
-	/*Do some modifications if we actually have a HOFS or SSAFS element*/
-	if(approximation==HOFSApproximationEnum){
-		Input* vzFS_input=inputs->GetInput(VzFSEnum);
-		if (vzFS_input){
-			if (vzFS_input->ObjectEnum()!=PentaInputEnum) _error_("Cannot compute Vel as VzFS is of type " << EnumToStringx(vzFS_input->ObjectEnum()));
-			GetInputListOnVertices(&vzFS[0],VzFSEnum);
-		}
-		else _error_("Cannot compute Vz as VzFS in not present in HOFS element");
-		for(i=0;i<NUMVERTICES;i++){
-			vzHO[i]=vz[i];
-			vz[i]=vzHO[i]+vzFS[i];
-		}
-	}
-	else if(approximation==SSAFSApproximationEnum){
-		Input* vzFS_input=inputs->GetInput(VzFSEnum);
-		if (vzFS_input){
-			if (vzFS_input->ObjectEnum()!=PentaInputEnum) _error_("Cannot compute Vel as VzFS is of type " << EnumToStringx(vzFS_input->ObjectEnum()));
-			GetInputListOnVertices(&vzFS[0],VzFSEnum);
-		}
-		else _error_("Cannot compute Vz as VzFS in not present in SSAFS element");
-		for(i=0;i<NUMVERTICES;i++){
-			vzSSA[i]=vz[i];
-			vz[i]=vzSSA[i]+vzFS[i];
-		}
-	}
-
-	/*Now Compute vel*/
-	for(i=0;i<NUMVERTICES;i++) vel[i]=pow( pow(vx[i],2.0) + pow(vy[i],2.0) + pow(vz[i],2.0) , 0.5);
-
-	/*For pressure: we have not computed pressure in this analysis, for this element. We are in 3D, 
-	 *so the pressure is just the pressure at the z elevation: except it this is a HOFS element */
-	if(approximation!=HOFSApproximationEnum &&  approximation!=SSAFSApproximationEnum){
-		rho_ice=matpar->GetRhoIce();
-		g=matpar->GetG();
-		GetInputListOnVertices(&surface[0],SurfaceEnum);
-		for(i=0;i<NUMVERTICES;i++) pressure[i]=rho_ice*g*(surface[i]-xyz_list[i][2]);
-	}
-
-	/*Now, we have to move the previous Vz inputs to old 
-	 * status, otherwise, we'll wipe them off and add the new inputs: */
-	this->inputs->ChangeEnum(VzEnum,VzPicardEnum);
-
-	if(approximation!=HOFSApproximationEnum && approximation!=SSAFSApproximationEnum){
-		this->inputs->ChangeEnum(PressureEnum,PressurePicardEnum);
-		this->inputs->AddInput(new PentaInput(PressureEnum,pressure,P1Enum));
-	}
-	else if(approximation==HOFSApproximationEnum){
-		this->inputs->AddInput(new PentaInput(VzHOEnum,vzHO,P1Enum));
-	}
-	else if(approximation==SSAFSApproximationEnum){
-		this->inputs->AddInput(new PentaInput(VzSSAEnum,vzSSA,P1Enum));
-	}
-	this->inputs->AddInput(new PentaInput(VzEnum,vz,P1Enum));
-	this->inputs->AddInput(new PentaInput(VelEnum,vel,P1Enum));
-
-	/*Free ressources:*/
-	xDelete<int>(doflist);
-}
-/*}}}*/
-/*FUNCTION Penta::InputUpdateFromSolutionStressbalanceFS {{{*/
-void  Penta::InputUpdateFromSolutionStressbalanceFS(IssmDouble* solution){
-
-	int          i;
-	int*         vdoflist=NULL;
-	int*         pdoflist=NULL;
-	IssmDouble   FSreconditioning;
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int vnumnodes = this->NumberofNodesVelocity();
-	int pnumnodes = this->NumberofNodesPressure();
-	int vnumdof   = vnumnodes*NDOF3;
-	int pnumdof   = pnumnodes*NDOF1;
-
-	/*Initialize values*/
-	IssmDouble* values   = xNew<IssmDouble>(vnumdof+pnumdof);
-	IssmDouble* vx       = xNew<IssmDouble>(vnumnodes);
-	IssmDouble* vy       = xNew<IssmDouble>(vnumnodes);
-	IssmDouble* vz       = xNew<IssmDouble>(vnumnodes);
-	IssmDouble* vel      = xNew<IssmDouble>(vnumnodes);
-	IssmDouble* pressure = xNew<IssmDouble>(pnumnodes);
-
-	/*Prepare coordinate system list*/
-	int* cs_list = xNew<int>(vnumnodes+pnumnodes);
-	for(i=0;i<vnumnodes;i++) cs_list[i]           = XYZEnum;
-	for(i=0;i<pnumnodes;i++) cs_list[vnumnodes+i] = PressureEnum;
-
-	/*Get dof list: */
-	GetDofListVelocity(&vdoflist,GsetEnum);
-	GetDofListPressure(&pdoflist,GsetEnum);
-
-	/*Use the dof list to index into the solution vector: */
-	for(i=0;i<vnumdof;i++) values[i]        =solution[vdoflist[i]];
-	for(i=0;i<pnumdof;i++) values[vnumdof+i]=solution[pdoflist[i]];
-
-	/*Transform solution in Cartesian Space*/
-	TransformSolutionCoord(&values[0],nodes,vnumnodes+pnumdof,cs_list);
-
-	/*Ok, we have vx and vy in values, fill in all arrays: */
-	for(i=0;i<vnumnodes;i++){
-		vx[i] = values[i*NDOF3+0];
-		vy[i] = values[i*NDOF3+1];
-		vz[i] = values[i*NDOF3+2];
-		if(xIsNan<IssmDouble>(vx[i])) _error_("NaN found in solution vector");
-		if(xIsNan<IssmDouble>(vy[i])) _error_("NaN found in solution vector");
-		if(xIsNan<IssmDouble>(vz[i])) _error_("NaN found in solution vector");
-	}
-	for(i=0;i<pnumnodes;i++){
-		pressure[i] = values[vnumdof+i];
-		if(xIsNan<IssmDouble>(pressure[i])) _error_("NaN found in solution vector");
-	}
-
-	/*Recondition pressure and compute vel: */
-	this->parameters->FindParam(&FSreconditioning,StressbalanceFSreconditioningEnum);
-	for(i = 0;i<pnumnodes;i++) pressure[i] = pressure[i]*FSreconditioning;
-	for(i = 0;i<vnumnodes;i++) vel[i]      = sqrt(vx[i]*vx[i] + vy[i]*vy[i] + vz[i]*vz[i]);
-
-	/*Now, we have to move the previous inputs  to old 
-	 * status, otherwise, we'll wipe them off: */
-	this->inputs->ChangeEnum(VxEnum,VxPicardEnum);
-	this->inputs->ChangeEnum(VyEnum,VyPicardEnum);
-	this->inputs->ChangeEnum(VzEnum,VzPicardEnum);
-	this->inputs->ChangeEnum(PressureEnum,PressurePicardEnum);
-
-	/*Add vx and vy as inputs to the tria element: */
-	this->inputs->AddInput(new PentaInput(VxEnum,vx,P1Enum));
-	this->inputs->AddInput(new PentaInput(VyEnum,vy,P1Enum));
-	this->inputs->AddInput(new PentaInput(VzEnum,vz,P1Enum));
-	this->inputs->AddInput(new PentaInput(VelEnum,vel,P1Enum));
-	this->inputs->AddInput(new PentaInput(PressureEnum,pressure,P1Enum));
-
-	/*Free ressources:*/
-	xDelete<IssmDouble>(pressure);
-	xDelete<IssmDouble>(vel);
-	xDelete<IssmDouble>(vz);
-	xDelete<IssmDouble>(vy);
-	xDelete<IssmDouble>(vx);
-	xDelete<IssmDouble>(values);
-	xDelete<int>(vdoflist);
-	xDelete<int>(pdoflist);
-	xDelete<int>(cs_list);
-}
-/*}}}*/
-#endif
-
-#ifdef _HAVE_BALANCED_
-/*FUNCTION Penta::CreateKMatrixBalancethickness {{{*/
-ElementMatrix* Penta::CreateKMatrixBalancethickness(void){
-
-	/*Figure out if this penta is collapsed. If so, then bailout, except if it is at the 
-	  bedrock, in which case we spawn a tria element using the 3 first nodes, and use it to build 
-	  the stiffness matrix. */
-	if (!IsOnBed()) return NULL;
-
-	/*Depth Averaging Vx and Vy*/
-	this->InputDepthAverageAtBase(VxEnum,VxAverageEnum);
-	this->InputDepthAverageAtBase(VyEnum,VyAverageEnum);
-
-	/*Spawn Tria element from the base of the Penta: */
-	Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.
-	ElementMatrix* Ke=tria->CreateKMatrixBalancethickness();
-	delete tria->material; delete tria;
-
-	/*Delete Vx and Vy averaged*/
-	this->inputs->DeleteInput(VxAverageEnum);
-	this->inputs->DeleteInput(VyAverageEnum);
-
-	/*clean up and return*/
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Penta::CreatePVectorBalancethickness {{{*/
-ElementVector* Penta::CreatePVectorBalancethickness(void){
-
-	if (!IsOnBed()) return NULL;
-
-	/*Depth Averaging Vx and Vy*/
-	this->InputDepthAverageAtBase(VxEnum,VxAverageEnum);
-	this->InputDepthAverageAtBase(VyEnum,VyAverageEnum);
-
-	/*Call Tria function*/
-	Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.
-	ElementVector* pe=tria->CreatePVectorBalancethickness();
-	delete tria->material; delete tria;
-
-	/*Delete Vx and Vy averaged*/
-	this->inputs->DeleteInput(VxAverageEnum);
-	this->inputs->DeleteInput(VyAverageEnum);
-
-	/*Clean up and return*/
-	return pe;
-}
-/*}}}*/
-#endif
-
-#ifdef _HAVE_HYDROLOGY_
-/*FUNCTION Penta::CreateKMatrixHydrologyDCInefficient {{{*/
-ElementMatrix* Penta::CreateKMatrixHydrologyDCInefficient(void){
-
-	if (!IsOnBed()) return NULL;
-
-	Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.
-	ElementMatrix* Ke=tria->CreateKMatrixHydrologyDCInefficient();
-	delete tria->material; delete tria;
-
-	/*clean up and return*/
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Penta::CreateKMatrixHydrologyDCEfficient {{{*/
-ElementMatrix* Penta::CreateKMatrixHydrologyDCEfficient(void){
-
-	if (!IsOnBed()) return NULL;
-
-	Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.
-	ElementMatrix* Ke=tria->CreateKMatrixHydrologyDCEfficient();
-	delete tria->material; delete tria;
-
-	/*clean up and return*/
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Penta::CreatePVectorHydrologyDCInefficient {{{*/
-ElementVector* Penta::CreatePVectorHydrologyDCInefficient(void){
-
-	if (!IsOnBed()) return NULL;
-
-	/*Call Tria function*/
-	Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.
-	ElementVector* pe=tria->CreatePVectorHydrologyDCInefficient();
-	delete tria->material; delete tria;
-
-	/*Clean up and return*/
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Penta::CreatePVectorHydrologyDCEfficient {{{*/
-ElementVector* Penta::CreatePVectorHydrologyDCEfficient(void){
-
-	if (!IsOnBed()) return NULL;
-
-	/*Call Tria function*/
-	Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.
-	ElementVector* pe=tria->CreatePVectorHydrologyDCEfficient();
-	delete tria->material; delete tria;
-
-	/*Clean up and return*/
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Penta::GetHydrologyDCInefficientHmax{{{*/
-void  Penta::GetHydrologyDCInefficientHmax(IssmDouble* ph_max, Node* innode){
-
-	if (!IsOnBed()) return;
-
-	Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.
-	tria->GetHydrologyDCInefficientHmax(ph_max,innode);
-	delete tria->material; delete tria;
-}
-/*}}}*/
-/*FUNCTION Penta::GetHydrologyTransfer{{{*/
-void  Penta::GetHydrologyTransfer(Vector<IssmDouble>* transfer){
-
-	if (!IsOnBed()) return;
-
-	Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.
-	tria->GetHydrologyTransfer(transfer);
-	delete tria->material; delete tria;
-}
-/*}}}*/
 /*FUNCTION Penta::GetSolutionFromInputsOneDof {{{*/
 void Penta::GetSolutionFromInputsOneDof(Vector<IssmDouble>* solution, int enum_type){
@@ -10823,98 +3981,4 @@
 }
 /*}}}*/
-/*FUNCTION Penta::HydrologyEPLGetActive {{{*/
-void Penta::HydrologyEPLGetActive(Vector<IssmDouble>* active_vec){
-
-	if (!IsOnBed())return;
-
-	Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.
-	tria->HydrologyEPLGetActive(active_vec);
-	delete tria->material; delete tria;
-
-}
-/*}}}*/
-/*FUNCTION Penta::HydrologyEPLGetMask{{{*/
-void  Penta::HydrologyEPLGetMask(Vector<IssmDouble>* vec_mask){
-
-	if (!IsOnBed())return;
-
-	Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.
-	tria->HydrologyEPLGetMask(vec_mask);
-	delete tria->material; delete tria;
-
-}
-/*}}}*/
-/*FUNCTION Penta::InputUpdateFromSolutionHydrologyDCInefficient{{{*/
-void  Penta::InputUpdateFromSolutionHydrologyDCInefficient(IssmDouble* solution){
-
-	const int   numdof   = NDOF1*NUMVERTICES;
-	const int   numdof2d = NDOF1*NUMVERTICES2D;
-	int*        doflist  = NULL;
-	bool        converged;
-	IssmDouble  values[numdof];
-	IssmDouble  residual[numdof];
-	IssmDouble  penalty_factor;
-	IssmDouble  kmax, kappa, h_max;
-	Penta      *penta    = NULL;
-
-	/*If not on bed, return*/
-	if (!IsOnBed()) return;
-
-	/*Get dof list: */
-	GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
-
-	/*Use the dof list to index into the solution vector and extrude it */
-	for(int i=0;i<numdof2d;i++){
-		values[i]         =solution[doflist[i]];
-		values[i+numdof2d]=values[i];
-		if(xIsNan<IssmDouble>(values[i])) _error_("NaN found in solution vector");
-	}
-
-	/*If converged keep the residual in mind*/
-	this->inputs->GetInputValue(&converged,ConvergedEnum);
-
-	/*Get inputs*/
-	if(converged){
-		this->parameters->FindParam(&kmax,HydrologySedimentKmaxEnum);
-		this->parameters->FindParam(&penalty_factor,HydrologydcPenaltyFactorEnum);
-
-		kappa=kmax*pow(10.,penalty_factor);
-
-		Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.	
-		for(int i=0;i<NUMVERTICES2D;i++){
-			tria->GetHydrologyDCInefficientHmax(&h_max,nodes[i]);
-			if(values[i]>h_max){
-				residual[i]=kappa*(values[i]-h_max);
-				residual[i+numdof2d]=residual[i];
-			}
-			else{
-				residual[i]=0.0;
-				residual[i+numdof2d]=residual[i];
-			}
-		}
-		delete tria->material; delete tria;
-	}
-
-	/*Start looping over all elements above current element and update all inputs*/
-	penta=this;
-	for(;;){
-		/*Add input to the element: */
-		penta->inputs->AddInput(new PentaInput(SedimentHeadEnum,values,P1Enum));
-		penta->inputs->AddInput(new PentaInput(SedimentHeadResidualEnum,residual,P1Enum));
-
-		/*Stop if we have reached the surface*/
-		if (penta->IsOnSurface()) break;
-
-		/* get upper Penta*/
-		penta=penta->GetUpperElement(); _assert_(penta->Id()!=this->id);
-	}
-
-	/*Free ressources:*/
-	xDelete<int>(doflist);
-}
-/*}}}*/
-#endif
-
-#ifdef _HAVE_GROUNDINGLINE_
 /*FUNCTION Penta::MigrateGroundingLine{{{*/
 void  Penta::MigrateGroundingLine(IssmDouble* phi_ungrounding){
@@ -10929,5 +3993,5 @@
 	IssmDouble melting[NUMVERTICES],phi[NUMVERTICES];
 
-	if(!IsOnBed()) return;
+	if(!IsOnBase()) return;
 
 	/*Recover info at the vertices: */
@@ -10937,6 +4001,6 @@
 	GetInputListOnVertices(&h[0],ThicknessEnum);
 	GetInputListOnVertices(&s[0],SurfaceEnum);
-	GetInputListOnVertices(&b[0],BedEnum);
-	GetInputListOnVertices(&r[0],BathymetryEnum);
+	GetInputListOnVertices(&b[0],BaseEnum);
+	GetInputListOnVertices(&r[0],BedEnum);
 	GetInputListOnVertices(&phi[0],MaskGroundediceLevelsetEnum);
 	rho_water   = matpar->GetRhoWater();
@@ -10986,5 +4050,5 @@
 	}
 	this->inputs->AddInput(new PentaInput(MaskGroundediceLevelsetEnum,&phi[0],P1Enum));
-	this->InputExtrude(MaskGroundediceLevelsetEnum,ElementEnum);
+	this->InputExtrude(MaskGroundediceLevelsetEnum);
 
 	/*SubelementMigrationEnum: if one grounded, all grounded*/
@@ -11015,9 +4079,9 @@
 	/*Update inputs*/
 	this->inputs->AddInput(new PentaInput(SurfaceEnum,&s[0],P1Enum));
-	this->inputs->AddInput(new PentaInput(BedEnum,&b[0],P1Enum));
+	this->inputs->AddInput(new PentaInput(BaseEnum,&b[0],P1Enum));
 
 	/*Extrude inputs*/
-	this->InputExtrude(SurfaceEnum,ElementEnum);
-	this->InputExtrude(BedEnum,ElementEnum);
+	this->InputExtrude(SurfaceEnum);
+	this->InputExtrude(BaseEnum);
 }
 /*}}}*/
@@ -11034,5 +4098,5 @@
 	density=rho_ice/rho_water;
 	GetInputListOnVertices(&h[0],ThicknessEnum);
-	GetInputListOnVertices(&r[0],BathymetryEnum);
+	GetInputListOnVertices(&r[0],BedEnum);
 	GetInputListOnVertices(&gl[0],MaskGroundediceLevelsetEnum);
 
@@ -11070,3 +4134,2 @@
 }
 /*}}}*/
-#endif
Index: /issm/trunk/src/c/classes/Elements/Penta.h
===================================================================
--- /issm/trunk/src/c/classes/Elements/Penta.h	(revision 17805)
+++ /issm/trunk/src/c/classes/Elements/Penta.h	(revision 17806)
@@ -23,5 +23,5 @@
 class ElementMatrix;
 class ElementVector;
-
+class GaussPenta;
 #include "../../shared/Exceptions/exceptions.h"
 #include "../../shared/Enum/Enum.h"
@@ -32,18 +32,8 @@
 	public:
 
-		int          id;
-		int          sid;
-
-		Node       **nodes;                       // set of nodes
-		Vertex     **vertices;                    // 6 vertices
-		Material    *material;                    // 1 material ice
-		Matpar      *matpar;                      // 1 material parameter
 		Penta      **verticalneighbors;           // 2 neighbors: first one under, second one above
 
-		Parameters  *parameters;                  //pointer to solution parameters
-		Inputs      *inputs;
-
 		/*Penta constructors and destructor: {{{*/
-		Penta();
+		Penta(){};
 		Penta(int penta_id,int penta_sid,int i, IoModel* iomodel,int nummodels);
 		~Penta();
@@ -51,14 +41,7 @@
 		/*Object virtual functions definitions: {{{*/
 		Object *copy();
-		void    DeepEcho();
-		void    Echo();
 		int     ObjectEnum();
-		int     Id();
 		/*}}}*/
 		/*Update virtual functions definitions: {{{*/
-		void  InputUpdateFromConstant(bool constant, int name);
-		void  InputUpdateFromConstant(IssmDouble constant, int name);
-		void  InputUpdateFromConstant(int constant, int name);
-		void  InputUpdateFromSolution(IssmDouble* solutiong);
 		void  InputUpdateFromVector(IssmDouble* vector, int name, int type);
 		#ifdef _HAVE_DAKOTA_
@@ -70,41 +53,65 @@
 		/*Element virtual functions definitions: {{{*/
 		void   BasalFrictionCreateInput(void);
+		IssmDouble CharacteristicLength(void){_error_("not implemented yet");};
 		void   ComputeBasalStress(Vector<IssmDouble>* sigma_b);
 		void   ComputeStrainRate(Vector<IssmDouble>* eps);
+		void   ComputeSigmaNN(){_error_("not implemented yet");};
 		void   ComputeStressTensor();
+		void   ComputeDeviatoricStressTensor();
 		void   Configure(Elements* elements,Loads* loads,Nodes* nodes,Vertices* vertices,Materials* materials,Parameters* parameters);
+		void   ElementSizes(IssmDouble* hx,IssmDouble* hy,IssmDouble* hz);
+		int    FiniteElement(void);
+		void   FSContactMigration(Vector<IssmDouble>* vertexgrounded,Vector<IssmDouble>* vertexfloating);
 		void   SetCurrentConfiguration(Elements* elements,Loads* loads,Nodes* nodes,Materials* materials,Parameters* parameters);
-		void   SetwiseNodeConnectivity(int* d_nz,int* o_nz,Node* node,bool* flags,int* flagsindices,int set1_enum,int set2_enum);
-		void   CreateKMatrix(Matrix<IssmDouble>* Kff, Matrix<IssmDouble>* Kfs);
-		void   CreateDVector(Vector<IssmDouble>* df);
-		void   CreatePVector(Vector<IssmDouble>* pf);
-		void   CreateJacobianMatrix(Matrix<IssmDouble>* Jff);
 		void   Delta18oParameterization(void);
+		Penta* GetUpperPenta(void);
+		Penta* GetLowerPenta(void);
+		Penta* GetSurfacePenta(void);
+		Penta* GetBasalPenta(void);
+		Element* GetUpperElement(void);
+		Element* GetLowerElement(void);
+		Element* GetSurfaceElement(void);
+		Element* GetBasalElement(void);
+		void   GetGroundedPart(int* point1,IssmDouble* fraction1, IssmDouble* fraction2,bool* mainlyfloating);
+		IssmDouble GetGroundedPortion(IssmDouble* xyz_list);
 		int    GetNodeIndex(Node* node);
-		void   GetNodesSidList(int* sidlist);
-		void   GetNodesLidList(int* lidlist);
 		int    GetNumberOfNodes(void);
-		void   GetSolutionFromInputs(Vector<IssmDouble>* solution);
-		IssmDouble GetZcoord(GaussPenta* gauss);
-		void   GetVectorFromInputs(Vector<IssmDouble>* vector,int name_enum);
-
-		int    Sid();
-		void   InputCreate(IssmDouble* vector,IoModel* iomodel,int M,int N,int vector_type,int vector_enum,int code);
-		void   InputDepthAverageAtBase(int enum_type,int average_enum_type,int object_enum=MeshElementsEnum);
+		int    GetNumberOfVertices(void);
+		void   GetSolutionFromInputsOneDof(Vector<IssmDouble>* solution,int enum_type);
+		IssmDouble GetXcoord(Gauss* gauss);
+		IssmDouble GetYcoord(Gauss* gauss);
+		IssmDouble GetZcoord(Gauss* gauss);
+		void   GetVerticesCoordinatesBase(IssmDouble** pxyz_list);
+		void   GetVerticesCoordinatesTop(IssmDouble** pxyz_list);
+
+		void   InputDepthAverageAtBase(int enum_type,int average_enum_type);
 		void   InputDuplicate(int original_enum,int new_enum);
 		void   InputScale(int enum_type,IssmDouble scale_factor);
-
-		void   ResultInterpolation(int* pinterpolation,int output_enum);
-		void   ResultToVector(Vector<IssmPDouble>* vector,int output_enum);
+		int    NumberofNodesVelocity(void);
+		int    NumberofNodesPressure(void);
+		int    VelocityInterpolation();
+		int    PressureInterpolation();
+		bool   IsZeroLevelset(int levelset_enum);
+		bool   IsIcefront(void);
+		void   ZeroLevelsetCoordinates(IssmDouble** pxyz_zero,IssmDouble* xyz_list,int levelsetenum);
+		void   GetIcefrontCoordinates(IssmDouble** pxyz_front,IssmDouble* xyz_list,int levelsetenum){_error_("not implemented yet");};
+		void   GetNormalFromLSF(IssmDouble *pnormal){_error_("not implemented yet");};
 		void   PositiveDegreeDay(IssmDouble* pdds,IssmDouble* pds,IssmDouble signorm);
-		void   ResetCoordinateSystem(void);
+		void   ReduceMatrices(ElementMatrix* Ke,ElementVector* pe);
+		void   ResetFSBasalBoundaryCondition(void);
 		void   SmbGradients();
+		void   SetTemporaryElementType(int element_type_in);
+	   Element* SpawnBasalElement(void);
+		Element* SpawnTopElement(void);
 		IssmDouble SurfaceArea(void);
 		void   Update(int index, IoModel* iomodel,int analysis_counter,int analysis_type,int finitelement);
 		int    NodalValue(IssmDouble* pvalue, int index, int natureofdataenum);
 		IssmDouble TimeAdapt();
-		void   ViscousHeatingCreateInput(void);
-
-		 #ifdef _HAVE_RESPONSES_
+		void   ValueP1OnGauss(IssmDouble* pvalue,IssmDouble* values,Gauss* gauss);
+		void   ValueP1DerivativesOnGauss(IssmDouble* dvalue,IssmDouble* values,IssmDouble* xyz_list,Gauss* gauss);
+		int    VertexConnectivity(int vertexindex);
+		void   VerticalSegmentIndices(int** pindices,int* pnumseg);
+		void   ViscousHeating(IssmDouble* pphi,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input);
+
 		void   AverageOntoPartition(Vector<IssmDouble>* partition_contributions,Vector<IssmDouble>* partition_areas,IssmDouble* vertex_response,IssmDouble* qmu_part);
 		IssmDouble IceVolume(void);
@@ -125,5 +132,4 @@
 		void   MaxVy(IssmDouble* pmaxvy);
 		void   MaxVz(IssmDouble* pmaxvz);
-		#endif
 
 		#ifdef _HAVE_GIA_
@@ -131,5 +137,4 @@
 		#endif
 
-		#ifdef _HAVE_CONTROL_
 		IssmDouble DragCoefficientAbsGradient(void);
 		void   GradientIndexing(int* indexing,int control_index);
@@ -159,200 +164,57 @@
 		IssmDouble BalancethicknessMisfit(void){_error_("not supported");};
 		void   InputControlUpdate(IssmDouble scalar,bool save_parameter);
-		#endif
-
-		#ifdef _HAVE_GROUNDINGLINE_
+		IssmDouble Misfit(int modelenum,int observationenum,int weightsenum){_error_("not implemented yet");};
+		IssmDouble MisfitArea(int weightsenum){_error_("not implemented yet");};
+
 		void   MigrateGroundingLine(IssmDouble* sheet_ungrounding);
 		void   PotentialUngrounding(Vector<IssmDouble>* potential_sheet_ungrounding);
 		int    UpdatePotentialUngrounding(IssmDouble* potential_sheet_ungrounding,Vector<IssmDouble>* vec_nodes_on_iceshelf,IssmDouble* nodes_on_iceshelf);
-		#endif
-
 		/*}}}*/
 		/*Penta specific routines:{{{*/
-		void	         BedNormal(IssmDouble* bed_normal, IssmDouble xyz_list[3][3]);
+		void           AddBasalInput(int input_enum, IssmDouble* values, int interpolation_enum);
+		void           AddInput(int input_enum, IssmDouble* values, int interpolation_enum);
+		void	         NormalBase(IssmDouble* bed_normal, IssmDouble* xyz_list);
+		void           NormalSection(IssmDouble* normal,IssmDouble* xyz_list);
+		void	         NormalTop(IssmDouble* bed_normal, IssmDouble* xyz_list);
 		ElementMatrix* CreateBasalMassMatrix(void);
-		ElementMatrix* CreateKMatrix(void);
-		ElementMatrix* CreateKMatrixMasstransport(void);
-		ElementMatrix* CreateKMatrixFreeSurfaceTop(void);
-		ElementMatrix* CreateKMatrixFreeSurfaceBase(void);
-		ElementVector* CreatePVector(void);
-		ElementVector* CreatePVectorMasstransport(void);
-		ElementVector* CreatePVectorFreeSurfaceTop(void);
-		ElementVector* CreatePVectorFreeSurfaceBase(void);
-		ElementVector* CreatePVectorL2ProjectionBase(void);
-		void           GetAreaCoordinates(IssmDouble *area_coordinates,IssmDouble xyz_zero[3][3],IssmDouble xyz_list[6][3],int numpoints);
-		void	         GetDofList(int** pdoflist,int approximation_enum,int setenum);
-		void	         GetDofListVelocity(int** pdoflist,int setenum);
-		void	         GetDofListPressure(int** pdoflist,int setenum);
-		void	         GetVertexPidList(int* doflist);
-		void           GetVertexSidList(int* sidlist);
-		void           GetConnectivityList(int* connectivity);
-		void           GetGroundedPart(int* point1,IssmDouble* fraction1, IssmDouble* fraction2,bool* mainlyfloating);
-		IssmDouble     GetGroundedPortion(IssmDouble* xyz_list);
+		void           GetAreaCoordinates(IssmDouble *area_coordinates,IssmDouble* xyz_zero,IssmDouble* xyz_list,int numpoints);
 		int            GetElementType(void);
-		void           GetElementSizes(IssmDouble* hx,IssmDouble* hy,IssmDouble* hz);
-		void           GetInputListOnVertices(IssmDouble* pvalue,int enumtype);
-		void           GetInputListOnVertices(IssmDouble* pvalue,int enumtype,IssmDouble defaultvalue);
-		void           GetInputListOnNodes(IssmDouble* pvalue,int enumtype);
-		void           GetInputListOnNodes(IssmDouble* pvalue,int enumtype,IssmDouble defaultvalue);
 		void           GetInputValue(IssmDouble* pvalue,Node* node,int enumtype);
-		void           GetMaterialInputValue(IssmDouble* pvalue,Node* node,int enumtype);
-		void	         GetPhi(IssmDouble* phi, IssmDouble*  epsilon, IssmDouble viscosity);
-		void           GetQuadNormal(IssmDouble* normal,IssmDouble xyz_list[4][3]);
-		IssmDouble     GetStabilizationParameter(IssmDouble u, IssmDouble v, IssmDouble w, IssmDouble diameter, IssmDouble kappa);
-		void           GetStrainRate3dHO(IssmDouble* epsilon,IssmDouble* xyz_list, GaussPenta* gauss, Input* vx_input, Input* vy_input);
-		void           GetStrainRate3d(IssmDouble* epsilon,IssmDouble* xyz_list, GaussPenta* gauss, Input* vx_input, Input* vy_input, Input* vz_input);
-		Penta*         GetUpperElement(void);
-		void           GetZeroLevelsetCoordinates(IssmDouble* xyz_zero,IssmDouble xyz_list[6][3],int levelsetenum);
-		Penta*         GetLowerElement(void);
-		Penta*         GetBasalElement(void);
-		void	         InputExtrude(int enum_type,int object_type);
-		void           InputUpdateFromSolutionMasstransport(IssmDouble* solutiong);
-		void           InputUpdateFromSolutionFreeSurfaceTop(IssmDouble* solutiong);
-		void           InputUpdateFromSolutionFreeSurfaceBase(IssmDouble* solutiong);
+		Node*          GetNode(int node_number);
+		void	         InputExtrude(int enum_type);
 		void           InputUpdateFromSolutionOneDof(IssmDouble* solutiong,int enum_type);
 		void           InputUpdateFromSolutionOneDofCollapsed(IssmDouble* solutiong,int enum_type);
-		bool	         IsInput(int name);
 		bool	         IsOnSurface(void);
-		bool	         IsOnBed(void);
-		bool           IsFloating(void); 
+		bool	         IsOnBase(void);
 		bool           IsNodeOnShelfFromFlags(IssmDouble* flags);
-		bool           NoIceInElement(void); 
-		IssmDouble     MinEdgeLength(IssmDouble xyz_list[6][3]);
+		void           JacobianDeterminant(IssmDouble*  Jdet, IssmDouble* xyz_list,Gauss* gauss);
+		void           JacobianDeterminantLine(IssmDouble* Jdet, IssmDouble* xyz_list,Gauss* gauss);
+		void           JacobianDeterminantSurface(IssmDouble*  pJdet, IssmDouble* xyz_list,Gauss* gauss);
+		void           JacobianDeterminantBase(IssmDouble* pJdet,IssmDouble* xyz_list_base,Gauss* gauss);
+		void           JacobianDeterminantTop(IssmDouble* pJdet,IssmDouble* xyz_list_base,Gauss* gauss);
+		Gauss*         NewGauss(void);
+		Gauss*         NewGauss(int order);
+		Gauss*         NewGauss(IssmDouble* xyz_list, IssmDouble* xyz_list_front,int order){_error_("not implemented yet");};
+		Gauss*         NewGauss(IssmDouble* xyz_list, IssmDouble* xyz_list_front,int order_horiz,int order_vert);
+		Gauss*         NewGauss(int point1,IssmDouble fraction1,IssmDouble fraction2,bool mainlyfloating,int order){_error_("not implemented yet");};
+		Gauss*         NewGaussBase(int order);
+		Gauss*         NewGaussLine(int vertex1,int vertex2,int order);
+		Gauss*         NewGaussTop(int order);
+		void           NodalFunctions(IssmDouble* basis,Gauss* gauss);
+		void           NodalFunctionsP1(IssmDouble* basis,Gauss* gauss);
+		void           NodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss);
+		void           NodalFunctionsP1Derivatives(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss);
+		void           NodalFunctionsMINIDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss);
+		void           NodalFunctionsDerivativesVelocity(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss);
+		void           NodalFunctionsVelocity(IssmDouble* basis,Gauss* gauss);
+		void           NodalFunctionsPressure(IssmDouble* basis,Gauss* gauss);
+		void           NodalFunctionsTensor(IssmDouble* basis,Gauss* gauss);
+		IssmDouble     MinEdgeLength(IssmDouble* xyz_list);
 		void	         SetClone(int* minranks);
-		Tria*	         SpawnTria(int location);
-		void	         SurfaceNormal(IssmDouble* surface_normal, IssmDouble xyz_list[3][3]);
-
-		#ifdef _HAVE_STRESSBALANCE_
-		ElementMatrix* CreateKMatrixCouplingSSAHO(void);
-		ElementMatrix* CreateKMatrixCouplingSSAHOViscous(void);
-		ElementMatrix* CreateKMatrixCouplingSSAHOFriction(void);
-		ElementMatrix* CreateKMatrixCouplingSSAFS(void);
-		ElementMatrix* CreateKMatrixCouplingSSAFSViscous(void);
-		ElementMatrix* CreateKMatrixCouplingSSAFSFriction(void);
-		ElementMatrix* CreateKMatrixCouplingHOFS(void);
-		ElementMatrix* CreateKMatrixStressbalanceHoriz(void);
-		ElementMatrix* CreateKMatrixAdjointHoriz(void);
-		ElementVector* CreateDVectorStressbalanceHoriz(void);
-		ElementVector* CreateDVectorStressbalanceFS(void);
-		ElementMatrix* CreateKMatrixStressbalanceSIA(void);
-		ElementMatrix* CreateKMatrixStressbalanceSSA2d(void);
-		ElementMatrix* CreateKMatrixStressbalanceSSA3d(void);
-		ElementMatrix* CreateKMatrixStressbalanceSSA3dViscous(void);
-		ElementMatrix* CreateKMatrixStressbalanceSSA3dFriction(void);
-		ElementMatrix* CreateKMatrixStressbalanceSSAHO(void);
-		ElementMatrix* CreateKMatrixStressbalanceSSAFS(void);
-		ElementMatrix* CreateKMatrixStressbalanceL1L2(void);
-		ElementMatrix* CreateKMatrixStressbalanceL1L2Viscous(void);
-		ElementMatrix* CreateKMatrixStressbalanceL1L2Friction(void);
-		ElementMatrix* CreateKMatrixStressbalanceHO(void);
-		ElementMatrix* CreateKMatrixStressbalanceHOViscous(void);
-		ElementMatrix* CreateKMatrixStressbalanceHOFriction(void);
-		ElementMatrix* CreateKMatrixStressbalanceHOFS(void);
-		ElementMatrix* CreateKMatrixStressbalanceFS(void);
-		ElementMatrix* CreateKMatrixStressbalanceFSViscous(void);
-		void           KMatrixGLSstabilization(ElementMatrix* Ke);
-		ElementMatrix* CreateKMatrixStressbalanceFSFriction(void);
-		ElementMatrix* CreateKMatrixStressbalanceVert(void);
-		ElementMatrix* CreateKMatrixStressbalanceVertVolume(void);
-		ElementMatrix* CreateKMatrixStressbalanceVertSurface(void);
-		ElementMatrix* CreateJacobianStressbalanceHoriz(void);
-		ElementMatrix* CreateJacobianStressbalanceSSA2d(void);
-		ElementMatrix* CreateJacobianStressbalanceHO(void);
-		ElementMatrix* CreateJacobianStressbalanceFS(void);
-		void           InputUpdateFromSolutionStressbalanceHoriz( IssmDouble* solutiong);
-		void           InputUpdateFromSolutionStressbalanceSSA( IssmDouble* solutiong);
-		void           InputUpdateFromSolutionStressbalanceSSAHO( IssmDouble* solutiong);
-		void           InputUpdateFromSolutionStressbalanceSSAFS( IssmDouble* solutiong);
-		void           InputUpdateFromSolutionStressbalanceL1L2( IssmDouble* solutiong);
-		void           InputUpdateFromSolutionStressbalanceHO( IssmDouble* solutiong);
-		void           InputUpdateFromSolutionStressbalanceHOFS( IssmDouble* solutiong);
-		void           InputUpdateFromSolutionStressbalanceSIA( IssmDouble* solutiong);
-		void           InputUpdateFromSolutionStressbalanceVert( IssmDouble* solutiong);
-		void           InputUpdateFromSolutionStressbalanceFS( IssmDouble* solutiong);
-		void	         GetSolutionFromInputsStressbalanceHoriz(Vector<IssmDouble>* solutiong);
-		void	         GetSolutionFromInputsStressbalanceSIA(Vector<IssmDouble>* solutiong);
-		void	         GetSolutionFromInputsStressbalanceFS(Vector<IssmDouble>* solutiong);
-		ElementVector* CreatePVectorCouplingSSAFS(void);
-		ElementVector* CreatePVectorCouplingSSAFSViscous(void);
-		ElementVector* CreatePVectorCouplingSSAFSFriction(void);
-		ElementVector* CreatePVectorCouplingHOFS(void);
-		ElementVector* CreatePVectorCouplingHOFSViscous(void);
-		ElementVector* CreatePVectorCouplingHOFSFriction(void);
-		ElementVector* CreatePVectorStressbalanceHoriz(void);
-		ElementVector* CreatePVectorStressbalanceSIA(void);
-		ElementVector* CreatePVectorStressbalanceSSA(void);
-		ElementVector* CreatePVectorStressbalanceSSAHO(void);
-		ElementVector* CreatePVectorStressbalanceSSAFS(void);
-		ElementVector* CreatePVectorStressbalanceL1L2(void);
-		ElementVector* CreatePVectorStressbalanceHO(void);
-		ElementVector* CreatePVectorStressbalanceHODrivingStress(void);
-		ElementVector* CreatePVectorStressbalanceHOFront(void);
-		ElementVector* CreatePVectorStressbalanceHOFS(void);
-		ElementVector* CreatePVectorStressbalanceFS(void);
-		ElementVector* CreatePVectorStressbalanceFSFront(void);
-		ElementVector* CreatePVectorStressbalanceFSViscous(void);
-		void           PVectorGLSstabilization(ElementVector* pe);
-		ElementVector* CreatePVectorStressbalanceFSShelf(void);
-		ElementVector* CreatePVectorStressbalanceVert(void);
-		ElementVector* CreatePVectorStressbalanceVertVolume(void);
-		ElementVector* CreatePVectorStressbalanceVertBase(void);
-		void           GetL1L2Viscosity(IssmDouble*, IssmDouble*, GaussPenta*, Input*, Input*, Input*);
-		#endif
-
-		#ifdef _HAVE_CONTROL_
-		ElementVector* CreatePVectorAdjointHoriz(void);
-		ElementMatrix* CreateKMatrixAdjointSSA2d(void);
-		ElementMatrix* CreateKMatrixAdjointHO(void);
-		ElementMatrix* CreateKMatrixAdjointFS(void);
-		ElementVector* CreatePVectorAdjointSSA(void);
-		ElementVector* CreatePVectorAdjointHO(void);
-		ElementVector* CreatePVectorAdjointFS(void);
-		void           InputUpdateFromSolutionAdjointHoriz( IssmDouble* solutiong);
-		void           InputUpdateFromSolutionAdjointFS( IssmDouble* solutiong);
-		#endif
-
-		#ifdef _HAVE_HYDROLOGY_
-		ElementMatrix* CreateKMatrixHydrologyDCInefficient(void);
-		ElementMatrix* CreateKMatrixHydrologyDCEfficient(void);
-		ElementVector* CreatePVectorHydrologyDCInefficient(void);
-		ElementVector* CreatePVectorHydrologyDCEfficient(void);
-		void    GetHydrologyDCInefficientHmax(IssmDouble* ph_max, Node* innode);
-		void    GetHydrologyTransfer(Vector<IssmDouble>* transfer);
-		void    GetSolutionFromInputsOneDof(Vector<IssmDouble>* solution, int enum_type);
-		void    HydrologyEPLGetActive(Vector<IssmDouble>* active_vec);
-		void    HydrologyEPLGetMask(Vector<IssmDouble>* vec_mask);
-		void    InputUpdateFromSolutionHydrologyDCInefficient(IssmDouble* solution);
-		#endif
-
-		void           UpdateConstraintsExtrudeFromBase(void){_error_("not implemented yet");};
-		void           UpdateConstraintsExtrudeFromTop(void){_error_("not implemented yet");};
-		#ifdef _HAVE_THERMAL_
-		ElementMatrix* CreateKMatrixEnthalpy(void);
-		ElementMatrix* CreateKMatrixEnthalpyVolume(void);
-		ElementMatrix* CreateKMatrixEnthalpyShelf(void);
-		ElementMatrix* CreateKMatrixThermal(void);
-		ElementMatrix* CreateKMatrixMelting(void);
-		ElementMatrix* CreateKMatrixThermalVolume(void);
-		ElementMatrix* CreateKMatrixThermalShelf(void);
-		ElementVector* CreatePVectorEnthalpy(void);
-		ElementVector* CreatePVectorEnthalpyVolume(void);
-		ElementVector* CreatePVectorEnthalpyShelf(void);
-		ElementVector* CreatePVectorEnthalpySheet(void);
-		ElementVector* CreatePVectorMelting(void);
-		ElementVector* CreatePVectorThermal(void);
-		ElementVector* CreatePVectorThermalVolume(void);
-		ElementVector* CreatePVectorThermalShelf(void);
-		ElementVector* CreatePVectorThermalSheet(void);
-		void           InputUpdateFromSolutionThermal(IssmDouble* solutiong);
-		void           InputUpdateFromSolutionEnthalpy(IssmDouble* solutiong);
-		void           UpdateBasalConstraintsEnthalpy(void);
-		void           ComputeBasalMeltingrate(void);
-		void           DrainWaterfraction(void);
-		#endif
-
-		#ifdef _HAVE_BALANCED_
-		ElementMatrix* CreateKMatrixBalancethickness(void);
-		ElementVector* CreatePVectorBalancethickness(void);
-		#endif
+		Tria*	         SpawnTria(int index1,int index2,int index3);
+		IssmDouble     StabilizationParameter(IssmDouble u, IssmDouble v, IssmDouble w, IssmDouble diameter, IssmDouble kappa);
+
+		void           UpdateConstraintsExtrudeFromBase(void);
+		void           UpdateConstraintsExtrudeFromTop(void);
 		/*}}}*/
 };
Index: /issm/trunk/src/c/classes/Elements/PentaRef.cpp
===================================================================
--- /issm/trunk/src/c/classes/Elements/PentaRef.cpp	(revision 17805)
+++ /issm/trunk/src/c/classes/Elements/PentaRef.cpp	(revision 17806)
@@ -16,12 +16,13 @@
 
 /*Element macros*/
+#define NUMNODESP0    1
 #define NUMNODESP1    6
 #define NUMNODESP1_2d 3
 #define NUMNODESP1b   7
 #define NUMNODESP1xP2 9
+#define NUMNODESP1xP3 12
 #define NUMNODESP2xP1 12
-#define NUMNODESP2    15
+#define NUMNODESP2    18
 #define NUMNODESP2xP4 30
-#define NUMNODESP1xP3 12
 
 /*Object constructors and destructor*/
@@ -55,1092 +56,6 @@
 
 /*Reference Element numerics*/
-/*FUNCTION PentaRef::GetBSSAHO {{{*/
-void PentaRef::GetBSSAHO(IssmDouble* B, IssmDouble* xyz_list, GaussPenta* gauss){
-	/*Compute B  matrix. B=[B1 B2 B3 B4 B5 B6] where Bi is of size 5*NDOF2. 
-	 * For node i, Bi can be expressed in the actual coordinate system
-	 * by: 
-	 *       Bi=[ dh/dx          0      ]
-	 *          [   0           dh/dy   ]
-	 *          [ 1/2*dh/dy  1/2*dh/dx  ]
-	 * where h is the interpolation function for node i.
-	 *
-	 * We assume B has been allocated already, of size: 5x(NDOF2*NUMNODESP1)
-	 */
-
-	IssmDouble dbasis[3][NUMNODESP1];
-
-	/*Get dbasis in actual coordinate system: */
-	GetNodalFunctionsP1Derivatives(&dbasis[0][0],xyz_list, gauss);
-
-	/*Build B: */
-	for(int i=0;i<NUMNODESP1;i++){
-		B[NDOF2*NUMNODESP1*0+NDOF2*i+0] = dbasis[0][i];
-		B[NDOF2*NUMNODESP1*0+NDOF2*i+1] = 0.;
-
-		B[NDOF2*NUMNODESP1*1+NDOF2*i+0] = 0.;
-		B[NDOF2*NUMNODESP1*1+NDOF2*i+1] = dbasis[1][i];
-
-		B[NDOF2*NUMNODESP1*2+NDOF2*i+0] = .5*dbasis[1][i];
-		B[NDOF2*NUMNODESP1*2+NDOF2*i+1] = .5*dbasis[0][i];
-	}
-}
-/*}}}*/
-/*FUNCTION PentaRef::GetBSSAFS{{{*/
-void PentaRef::GetBSSAFS(IssmDouble* B, IssmDouble* xyz_list, GaussPenta* gauss){
-	/*Compute B  matrix. B=[B1 B2 B3 B4 B5 B6] where Bi is of size 5*NDOF2. 
-	 * For node i, Bi can be expressed in the actual coordinate system
-	 * by: 
-	 *       Bi=[ dh/dx          0       0   0 ]
-	 *          [   0           dh/dy    0   0 ]
-	 *          [ 1/2*dh/dy  1/2*dh/dx   0   0 ]
-	 *          [   0            0       0   h ]
-	 * where h is the interpolation function for node i.
-	 *
-	 * We assume B has been allocated already, of size: 5x(NDOF2*NUMNODESP1)
-	 */
-
-	int i;
-	IssmDouble dbasismini[3][NUMNODESP1b];
-	IssmDouble basis[NUMNODESP1];
-
-	/*Get dbasis in actual coordinate system: */
-	GetNodalFunctionsMINIDerivatives(&dbasismini[0][0],xyz_list, gauss);
-	GetNodalFunctionsP1(basis,gauss);
-
-	/*Build B: */
-	for(i=0;i<NUMNODESP1;i++){
-		B[(NDOF3*NUMNODESP1b+NUMNODESP1)*0+NDOF3*i+0] = dbasismini[0][i];
-		B[(NDOF3*NUMNODESP1b+NUMNODESP1)*0+NDOF3*i+1] = 0.;
-		B[(NDOF3*NUMNODESP1b+NUMNODESP1)*0+NDOF3*i+2] = 0.;
-		B[(NDOF3*NUMNODESP1b+NUMNODESP1)*1+NDOF3*i+0] = 0.;
-		B[(NDOF3*NUMNODESP1b+NUMNODESP1)*1+NDOF3*i+1] = dbasismini[1][i];
-		B[(NDOF3*NUMNODESP1b+NUMNODESP1)*1+NDOF3*i+2] = 0.;
-		B[(NDOF3*NUMNODESP1b+NUMNODESP1)*2+NDOF3*i+0] = 0.5*dbasismini[1][i];
-		B[(NDOF3*NUMNODESP1b+NUMNODESP1)*2+NDOF3*i+1] = 0.5*dbasismini[0][i];
-		B[(NDOF3*NUMNODESP1b+NUMNODESP1)*2+NDOF3*i+2] = 0.;
-		B[(NDOF3*NUMNODESP1b+NUMNODESP1)*3+NDOF3*i+0] = 0.;
-		B[(NDOF3*NUMNODESP1b+NUMNODESP1)*3+NDOF3*i+1] = 0.;
-		B[(NDOF3*NUMNODESP1b+NUMNODESP1)*3+NDOF3*i+2] = 0.;
-	}
-	for(i=0;i<1;i++){
-		B[(NDOF3*NUMNODESP1b+NUMNODESP1)*0+NDOF3*(NUMNODESP1+i)+0] = 0.;
-		B[(NDOF3*NUMNODESP1b+NUMNODESP1)*0+NDOF3*(NUMNODESP1+i)+1] = 0.;
-		B[(NDOF3*NUMNODESP1b+NUMNODESP1)*0+NDOF3*(NUMNODESP1+i)+2] = 0.;
-		B[(NDOF3*NUMNODESP1b+NUMNODESP1)*1+NDOF3*(NUMNODESP1+i)+0] = 0.;
-		B[(NDOF3*NUMNODESP1b+NUMNODESP1)*1+NDOF3*(NUMNODESP1+i)+1] = 0.;
-		B[(NDOF3*NUMNODESP1b+NUMNODESP1)*1+NDOF3*(NUMNODESP1+i)+2] = 0.;
-		B[(NDOF3*NUMNODESP1b+NUMNODESP1)*2+NDOF3*(NUMNODESP1+i)+0] = 0.;
-		B[(NDOF3*NUMNODESP1b+NUMNODESP1)*2+NDOF3*(NUMNODESP1+i)+1] = 0.;
-		B[(NDOF3*NUMNODESP1b+NUMNODESP1)*2+NDOF3*(NUMNODESP1+i)+2] = 0.;
-		B[(NDOF3*NUMNODESP1b+NUMNODESP1)*3+NDOF3*(NUMNODESP1+i)+0] = 0.;
-		B[(NDOF3*NUMNODESP1b+NUMNODESP1)*3+NDOF3*(NUMNODESP1+i)+1] = 0.;
-		B[(NDOF3*NUMNODESP1b+NUMNODESP1)*3+NDOF3*(NUMNODESP1+i)+2] = 0.;
-	}
-
-	for(i=0;i<NUMNODESP1;i++){ //last column not for the bubble function
-		B[(NDOF3*NUMNODESP1b+NUMNODESP1)*0+NUMNODESP1b*NDOF3+i] = 0;
-		B[(NDOF3*NUMNODESP1b+NUMNODESP1)*1+NUMNODESP1b*NDOF3+i] = 0;
-		B[(NDOF3*NUMNODESP1b+NUMNODESP1)*2+NUMNODESP1b*NDOF3+i] = 0;
-		B[(NDOF3*NUMNODESP1b+NUMNODESP1)*3+NUMNODESP1b*NDOF3+i] = basis[i];
-	}
-}
-/*}}}*/
-/*FUNCTION PentaRef::GetBHO {{{*/
-void PentaRef::GetBHO(IssmDouble* B, IssmDouble* xyz_list, GaussPenta* gauss){
-	/*Compute B  matrix. B=[B1 B2 B3 B4 B5 B6] where Bi is of size 5*NDOF2. 
-	 * For node i, Bi can be expressed in the actual coordinate system
-	 * by: 
-	 *       Bi=[ dh/dx          0      ]
-	 *          [   0           dh/dy   ]
-	 *          [ 1/2*dh/dy  1/2*dh/dx  ]
-	 *          [ 1/2*dh/dz      0      ]
-	 *          [  0         1/2*dh/dz  ]
-	 * where h is the interpolation function for node i.
-	 *
-	 * We assume B has been allocated already, of size: 5x(NDOF2*numnodes)
-	 */
-
-	/*Fetch number of nodes for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Get nodal functions derivatives*/
-	IssmDouble* dbasis=xNew<IssmDouble>(3*numnodes);
-	GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
-
-	/*Build B: */
-	for(int i=0;i<numnodes;i++){
-		B[NDOF2*numnodes*0+NDOF2*i+0] = dbasis[0*numnodes+i];
-		B[NDOF2*numnodes*0+NDOF2*i+1] = 0.;
-		B[NDOF2*numnodes*1+NDOF2*i+0] = 0.;
-		B[NDOF2*numnodes*1+NDOF2*i+1] = dbasis[1*numnodes+i];
-		B[NDOF2*numnodes*2+NDOF2*i+0] = .5*dbasis[1*numnodes+i];
-		B[NDOF2*numnodes*2+NDOF2*i+1] = .5*dbasis[0*numnodes+i];
-		B[NDOF2*numnodes*3+NDOF2*i+0] = .5*dbasis[2*numnodes+i];
-		B[NDOF2*numnodes*3+NDOF2*i+1] = 0.;
-		B[NDOF2*numnodes*4+NDOF2*i+0] = 0.;
-		B[NDOF2*numnodes*4+NDOF2*i+1] = .5*dbasis[2*numnodes+i];
-	}
-
-	/*Clean-up*/
-	xDelete<IssmDouble>(dbasis);
-}
-/*}}}*/
-/*FUNCTION PentaRef::GetBprimeHO {{{*/
-void PentaRef::GetBprimeHO(IssmDouble* B,IssmDouble* xyz_list,GaussPenta* gauss){
-	/*Compute B  prime matrix. B=[B1 B2 B3 B4 B5 B6] where Bi is of size 5*NDOF2. 
-	 * For node i, Bi can be expressed in the actual coordinate system
-	 * by: 
-	 *       Bi=[ 2*dh/dx     dh/dy   ]
-	 *          [   dh/dx    2*dh/dy  ]
-	 *          [ dh/dy      dh/dx    ]
-	 *          [ dh/dz         0     ]
-	 *          [  0         dh/dz    ]
-	 * where h is the interpolation function for node i.
-	 *
-	 * We assume B has been allocated already, of size: 5x(NDOF2*numnodes)
-	 */
-
-	/*Fetch number of nodes for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Get nodal functions derivatives*/
-	IssmDouble* dbasis=xNew<IssmDouble>(3*numnodes);
-	GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
-
-	/*Build BPrime: */
-	for(int i=0;i<numnodes;i++){
-		B[NDOF2*numnodes*0+NDOF2*i+0]=2.*dbasis[0*numnodes+i]; 
-		B[NDOF2*numnodes*0+NDOF2*i+1]=dbasis[1*numnodes+i];
-		B[NDOF2*numnodes*1+NDOF2*i+0]=dbasis[0*numnodes+i];
-		B[NDOF2*numnodes*1+NDOF2*i+1]=2.*dbasis[1*numnodes+i];
-		B[NDOF2*numnodes*2+NDOF2*i+0]=dbasis[1*numnodes+i]; 
-		B[NDOF2*numnodes*2+NDOF2*i+1]=dbasis[0*numnodes+i]; 
-		B[NDOF2*numnodes*3+NDOF2*i+0]=dbasis[2*numnodes+i]; 
-		B[NDOF2*numnodes*3+NDOF2*i+1]=0.;
-		B[NDOF2*numnodes*4+NDOF2*i+0]=0.;
-		B[NDOF2*numnodes*4+NDOF2*i+1]=dbasis[2*numnodes+i]; 
-	}
-
-	/*Clean-up*/
-	xDelete<IssmDouble>(dbasis);
-}
-/*}}}*/
-/*FUNCTION PentaRef::GetBprimeSSAFS{{{*/
-void PentaRef::GetBprimeSSAFS(IssmDouble* Bprime, IssmDouble* xyz_list, GaussPenta* gauss){
-	/*Compute Bprime  matrix. Bprime=[Bprime1 Bprime2 Bprime3 Bprime4 Bprime5 Bprime6] where Bprimei is of size 5*NDOF2. 
-	 * For node i, Bprimei can be expressed in the actual coordinate system
-	 * by: 
-	 *       Bprimei=[ 2*dh/dx    dh/dy   0   0 ]
-	 *               [  dh/dx    2*dh/dy  0   0 ]
-	 *               [  dh/dy     dh/dx   0   0 ]
-	 * where h is the interpolation function for node i.
-	 *
-	 * We assume Bprime has been allocated already, of size: 5x(NDOF2*NUMNODESP1)
-	 */
-
-	int    i;
-	IssmDouble dbasismini[3][NUMNODESP1b];
-
-	/*Get dbasis in actual coordinate system: */
-	GetNodalFunctionsMINIDerivatives(&dbasismini[0][0],xyz_list, gauss);
-
-	/*Build Bprime: */
-	for(i=0;i<NUMNODESP1;i++){
-		Bprime[(NDOF3*NUMNODESP1b+NUMNODESP1)*0+NDOF3*i+0] = 2.*dbasismini[0][i];
-		Bprime[(NDOF3*NUMNODESP1b+NUMNODESP1)*0+NDOF3*i+1] = dbasismini[1][i];
-		Bprime[(NDOF3*NUMNODESP1b+NUMNODESP1)*0+NDOF3*i+2] = 0.;
-		Bprime[(NDOF3*NUMNODESP1b+NUMNODESP1)*1+NDOF3*i+0] = dbasismini[0][i];
-		Bprime[(NDOF3*NUMNODESP1b+NUMNODESP1)*1+NDOF3*i+1] = 2.*dbasismini[1][i];
-		Bprime[(NDOF3*NUMNODESP1b+NUMNODESP1)*1+NDOF3*i+2] = 0.;
-		Bprime[(NDOF3*NUMNODESP1b+NUMNODESP1)*2+NDOF3*i+0] = dbasismini[1][i];
-		Bprime[(NDOF3*NUMNODESP1b+NUMNODESP1)*2+NDOF3*i+1] = dbasismini[0][i];
-		Bprime[(NDOF3*NUMNODESP1b+NUMNODESP1)*2+NDOF3*i+2] = 0.;
-	}
-
-	for(i=0;i<1;i++){ //Add zeros for the bubble function
-		Bprime[(NDOF3*NUMNODESP1b+NUMNODESP1)*0+NDOF3*(NUMNODESP1+i)+0] = 0.;
-		Bprime[(NDOF3*NUMNODESP1b+NUMNODESP1)*0+NDOF3*(NUMNODESP1+i)+1] = 0.;
-		Bprime[(NDOF3*NUMNODESP1b+NUMNODESP1)*0+NDOF3*(NUMNODESP1+i)+2] = 0.;
-		Bprime[(NDOF3*NUMNODESP1b+NUMNODESP1)*1+NDOF3*(NUMNODESP1+i)+0] = 0.;
-		Bprime[(NDOF3*NUMNODESP1b+NUMNODESP1)*1+NDOF3*(NUMNODESP1+i)+1] = 0.;
-		Bprime[(NDOF3*NUMNODESP1b+NUMNODESP1)*1+NDOF3*(NUMNODESP1+i)+2] = 0.;
-		Bprime[(NDOF3*NUMNODESP1b+NUMNODESP1)*2+NDOF3*(NUMNODESP1+i)+0] = 0.;
-		Bprime[(NDOF3*NUMNODESP1b+NUMNODESP1)*2+NDOF3*(NUMNODESP1+i)+1] = 0.;
-		Bprime[(NDOF3*NUMNODESP1b+NUMNODESP1)*2+NDOF3*(NUMNODESP1+i)+2] = 0.;
-	}
-
-	for(i=0;i<NUMNODESP1;i++){ //last column not for the bubble function
-		Bprime[(NDOF3*NUMNODESP1b+NUMNODESP1)*0+NUMNODESP1b*NDOF3+i] = 0.;
-		Bprime[(NDOF3*NUMNODESP1b+NUMNODESP1)*1+NUMNODESP1b*NDOF3+i] = 0.;
-		Bprime[(NDOF3*NUMNODESP1b+NUMNODESP1)*2+NUMNODESP1b*NDOF3+i] = 0.;
-	}
-
-}
-/*}}}*/
-/*FUNCTION PentaRef::GetBFSstrainrate {{{*/
-void PentaRef::GetBFSstrainrate(IssmDouble* B, IssmDouble* xyz_list, GaussPenta* gauss){
-
-	/*Compute B  matrix. B=[B1 B2 B3 B4 B5 B6] where Bi is of size 3*NDOF4. 
-	 * For node i, Bi can be expressed in the actual coordinate system
-	 * by: 		Bi=[ dh/dx          0              0     ]
-	 *					[   0           dh/dy           0     ]
-	 *					[   0             0           dh/dy   ]
-	 *					[ 1/2*dh/dy    1/2*dh/dx        0     ]
-	 *					[ 1/2*dh/dz       0         1/2*dh/dx ]
-	 *					[   0          1/2*dh/dz    1/2*dh/dy ]
-	 *	where h is the interpolation function for node i.
-	 *	Same thing for Bb except the last column that does not exist.
-	 */
-
-	/*Fetch number of nodes for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Get nodal functions derivatives*/
-	IssmDouble* dbasis=xNew<IssmDouble>(3*numnodes);
-	GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
-
-	/*Build B: */
-	for(int i=0;i<numnodes;i++){
-		B[3*numnodes*0+3*i+0] = dbasis[0*numnodes+i+0];
-		B[3*numnodes*0+3*i+1] = 0.;
-		B[3*numnodes*0+3*i+2] = 0.;
-
-		B[3*numnodes*1+3*i+0] = 0.;
-		B[3*numnodes*1+3*i+1] = dbasis[1*numnodes+i+0];
-		B[3*numnodes*1+3*i+2] = 0.;
-
-		B[3*numnodes*2+3*i+0] = 0.;
-		B[3*numnodes*2+3*i+1] = 0.;
-		B[3*numnodes*2+3*i+2] = dbasis[2*numnodes+i+0];
-
-		B[3*numnodes*3+3*i+0] = .5*dbasis[1*numnodes+i+0];
-		B[3*numnodes*3+3*i+1] = .5*dbasis[0*numnodes+i+0];
-		B[3*numnodes*3+3*i+2] = 0.;
-
-		B[3*numnodes*4+3*i+0] = .5*dbasis[2*numnodes+i+0];
-		B[3*numnodes*4+3*i+1] = 0.;
-		B[3*numnodes*4+3*i+2] = .5*dbasis[0*numnodes+i+0];
-
-		B[3*numnodes*5+3*i+0] = 0.;
-		B[3*numnodes*5+3*i+1] = .5*dbasis[2*numnodes+i+0];
-		B[3*numnodes*5+3*i+2] = .5*dbasis[1*numnodes+i+0];
-	}
-
-	/*Clean up*/
-	xDelete<IssmDouble>(dbasis);
-}
-/*}}}*/
-/*FUNCTION PentaRef::GetBFS {{{*/
-void PentaRef::GetBFS(IssmDouble* B, IssmDouble* xyz_list, GaussPenta* gauss){
-
-	/*Compute B  matrix. B=[Bv1 Bv2 ... Bp1 Bp2 ...] where Bvi is of size 3*NDOF3. 
-	 * For node i, Bvi can be expressed in the actual coordinate system
-	 * by: 	   Bvi=[ dh/dx          0             0      ]
-	 *					[   0           dh/dy           0      ]
-	 *					[   0             0           dh/dz    ]
-	 *					[ 1/2*dh/dy    1/2*dh/dx        0      ]
-	 *					[ 1/2*dh/dz       0         1/2*dh/dx  ]
-	 *					[   0          1/2*dh/dz    1/2*dh/dy  ]
-	 *					[   0             0             0      ]
-	 *					[ dh/dx         dh/dy         dh/dz    ]
-	 *
-	 * by: 	  Bpi=[ 0 ]
-	 *					[ 0 ]
-	 *					[ 0 ]
-	 *					[ 0 ]
-	 *					[ 0 ]
-	 *					[ 0 ]
-	 *					[ h ]
-	 *					[ 0 ]
-	 *	where h is the interpolation function for node i.
-	 *	Same thing for Bb except the last column that does not exist.
-	 */
-
-	/*Fetch number of nodes for this finite element*/
-	int pnumnodes = this->NumberofNodesPressure();
-	int vnumnodes = this->NumberofNodesVelocity();
-
-	/*Get nodal functions derivatives*/
-	IssmDouble* vdbasis=xNew<IssmDouble>(3*vnumnodes);
-	IssmDouble* pbasis =xNew<IssmDouble>(pnumnodes);
-	GetNodalFunctionsDerivativesVelocity(vdbasis,xyz_list,gauss);
-	GetNodalFunctionsPressure(pbasis,gauss);
-
-	/*Build B: */
-	for(int i=0;i<vnumnodes;i++){
-		B[(3*vnumnodes+pnumnodes)*0+3*i+0] = vdbasis[0*vnumnodes+i];
-		B[(3*vnumnodes+pnumnodes)*0+3*i+1] = 0.;
-		B[(3*vnumnodes+pnumnodes)*0+3*i+2] = 0.;
-		B[(3*vnumnodes+pnumnodes)*1+3*i+0] = 0.;
-		B[(3*vnumnodes+pnumnodes)*1+3*i+1] = vdbasis[1*vnumnodes+i];
-		B[(3*vnumnodes+pnumnodes)*1+3*i+2] = 0.;
-		B[(3*vnumnodes+pnumnodes)*2+3*i+0] = 0.;
-		B[(3*vnumnodes+pnumnodes)*2+3*i+1] = 0.;
-		B[(3*vnumnodes+pnumnodes)*2+3*i+2] = vdbasis[2*vnumnodes+i];
-		B[(3*vnumnodes+pnumnodes)*3+3*i+0] = .5*vdbasis[1*vnumnodes+i];
-		B[(3*vnumnodes+pnumnodes)*3+3*i+1] = .5*vdbasis[0*vnumnodes+i];
-		B[(3*vnumnodes+pnumnodes)*3+3*i+2] = 0.;
-		B[(3*vnumnodes+pnumnodes)*4+3*i+0] = .5*vdbasis[2*vnumnodes+i];
-		B[(3*vnumnodes+pnumnodes)*4+3*i+1] = 0.;
-		B[(3*vnumnodes+pnumnodes)*4+3*i+2] = .5*vdbasis[0*vnumnodes+i];
-		B[(3*vnumnodes+pnumnodes)*5+3*i+0] = 0.;
-		B[(3*vnumnodes+pnumnodes)*5+3*i+1] = .5*vdbasis[2*vnumnodes+i];
-		B[(3*vnumnodes+pnumnodes)*5+3*i+2] = .5*vdbasis[1*vnumnodes+i];
-		B[(3*vnumnodes+pnumnodes)*6+3*i+0] = 0.;
-		B[(3*vnumnodes+pnumnodes)*6+3*i+1] = 0.;
-		B[(3*vnumnodes+pnumnodes)*6+3*i+2] = 0.;
-		B[(3*vnumnodes+pnumnodes)*7+3*i+0] = vdbasis[0*vnumnodes+i];
-		B[(3*vnumnodes+pnumnodes)*7+3*i+1] = vdbasis[1*vnumnodes+i];
-		B[(3*vnumnodes+pnumnodes)*7+3*i+2] = vdbasis[2*vnumnodes+i];
-	}
-	for(int i=0;i<pnumnodes;i++){
-		B[(3*vnumnodes+pnumnodes)*0+(3*vnumnodes)+i] = 0.;
-		B[(3*vnumnodes+pnumnodes)*1+(3*vnumnodes)+i] = 0.;
-		B[(3*vnumnodes+pnumnodes)*2+(3*vnumnodes)+i] = 0.;
-		B[(3*vnumnodes+pnumnodes)*3+(3*vnumnodes)+i] = 0.;
-		B[(3*vnumnodes+pnumnodes)*4+(3*vnumnodes)+i] = 0.;
-		B[(3*vnumnodes+pnumnodes)*5+(3*vnumnodes)+i] = 0.;
-		B[(3*vnumnodes+pnumnodes)*6+(3*vnumnodes)+i] = pbasis[i];
-		B[(3*vnumnodes+pnumnodes)*7+(3*vnumnodes)+i] = 0.;
-	}
-
-	/*Clean up*/
-	xDelete<IssmDouble>(vdbasis);
-	xDelete<IssmDouble>(pbasis);
-}
-/*}}}*/
-/*FUNCTION PentaRef::GetBFSGLS {{{*/
-void PentaRef::GetBFSGLS(IssmDouble* B, IssmDouble* xyz_list, GaussPenta* gauss){
-
-	/*Compute B  matrix. B=[B1 B2 B3 B4 B5 B6] where Bi is of size 3*NDOF4. 
-	 * For node i, Bi can be expressed in the actual coordinate system
-	 * by: 		Bi=[ dh/dx          0              0       0  ]
-	 *					[   0           dh/dy           0       0  ]
-	 *					[   0             0           dh/dy     0  ]
-	 *					[ 1/2*dh/dy    1/2*dh/dx        0       0  ]
-	 *					[ 1/2*dh/dz       0         1/2*dh/dx   0  ]
-	 *					[   0          1/2*dh/dz    1/2*dh/dy   0  ]
-	 *					[   0             0             0       h  ]
-	 *					[ dh/dx         dh/dy         dh/dz     0  ]
-	 *	where h is the interpolation function for node i.
-	 *	Same thing for Bb except the last column that does not exist.
-	 */
-
-	int i;
-	IssmDouble dbasis[3][NUMNODESP1];
-	IssmDouble basis[NUMNODESP1];
-
-	/*Get dbasismini in actual coordinate system: */
-	GetNodalFunctionsP1Derivatives(&dbasis[0][0],xyz_list, gauss);
-	GetNodalFunctionsP1(&basis[0], gauss);
-
-	/*Build B: */
-	for(i=0;i<NUMNODESP1;i++){
-		B[(NDOF4*NUMNODESP1)*0+NDOF4*i+0] = dbasis[0][i];
-		B[(NDOF4*NUMNODESP1)*0+NDOF4*i+1] = 0.;
-		B[(NDOF4*NUMNODESP1)*0+NDOF4*i+2] = 0.;
-		B[(NDOF4*NUMNODESP1)*1+NDOF4*i+0] = 0.;
-		B[(NDOF4*NUMNODESP1)*1+NDOF4*i+1] = dbasis[1][i];
-		B[(NDOF4*NUMNODESP1)*1+NDOF4*i+2] = 0.;
-		B[(NDOF4*NUMNODESP1)*2+NDOF4*i+0] = 0.;
-		B[(NDOF4*NUMNODESP1)*2+NDOF4*i+1] = 0.;
-		B[(NDOF4*NUMNODESP1)*2+NDOF4*i+2] = dbasis[2][i];
-		B[(NDOF4*NUMNODESP1)*3+NDOF4*i+0] = .5*dbasis[1][i];
-		B[(NDOF4*NUMNODESP1)*3+NDOF4*i+1] = .5*dbasis[0][i];
-		B[(NDOF4*NUMNODESP1)*3+NDOF4*i+2] = 0.;
-		B[(NDOF4*NUMNODESP1)*4+NDOF4*i+0] = .5*dbasis[2][i];
-		B[(NDOF4*NUMNODESP1)*4+NDOF4*i+1] = 0.;
-		B[(NDOF4*NUMNODESP1)*4+NDOF4*i+2] = .5*dbasis[0][i];
-		B[(NDOF4*NUMNODESP1)*5+NDOF4*i+0] = 0.;
-		B[(NDOF4*NUMNODESP1)*5+NDOF4*i+1] = .5*dbasis[2][i];
-		B[(NDOF4*NUMNODESP1)*5+NDOF4*i+2] = .5*dbasis[1][i];
-		B[(NDOF4*NUMNODESP1)*6+NDOF4*i+0] = 0.;
-		B[(NDOF4*NUMNODESP1)*6+NDOF4*i+1] = 0.;
-		B[(NDOF4*NUMNODESP1)*6+NDOF4*i+2] = 0.;
-		B[(NDOF4*NUMNODESP1)*7+NDOF4*i+0] = dbasis[0][i];
-		B[(NDOF4*NUMNODESP1)*7+NDOF4*i+1] = dbasis[1][i];
-		B[(NDOF4*NUMNODESP1)*7+NDOF4*i+2] = dbasis[2][i];
-	}
-
-	for(i=0;i<NUMNODESP1;i++){ //last column not for the bubble function
-		B[(NDOF4*NUMNODESP1)*0+NDOF4*i+3] = 0.;
-		B[(NDOF4*NUMNODESP1)*1+NDOF4*i+3] = 0.;
-		B[(NDOF4*NUMNODESP1)*2+NDOF4*i+3] = 0.;
-		B[(NDOF4*NUMNODESP1)*3+NDOF4*i+3] = 0.;
-		B[(NDOF4*NUMNODESP1)*4+NDOF4*i+3] = 0.;
-		B[(NDOF4*NUMNODESP1)*5+NDOF4*i+3] = 0.;
-		B[(NDOF4*NUMNODESP1)*6+NDOF4*i+3] = basis[i];
-		B[(NDOF4*NUMNODESP1)*7+NDOF4*i+3] = 0.;
-	}
-
-}
-/*}}}*/
-/*FUNCTION PentaRef::GetBprimeFS {{{*/
-void PentaRef::GetBprimeFS(IssmDouble* B_prime, IssmDouble* xyz_list, GaussPenta* gauss){
-	/*	Compute B'  matrix. B'=[B1' B2' B3' B4' B5' B6' Bb'] where Bi' is of size 3*NDOF2. 
-	 *	For node i, Bi' can be expressed in the actual coordinate system
-	 *	by: 
-	 *			Bvi' = [  dh/dx   0          0    ]
-	 *					 [   0      dh/dy      0    ]
-	 *					 [   0      0         dh/dz ]
-	 *					 [  dh/dy   dh/dx      0    ]
-	 *					 [  dh/dz   0        dh/dx  ]
-	 *					 [   0      dh/dz    dh/dy  ]
-	 *					 [  dh/dx   dh/dy    dh/dz  ]
-	 *					 [   0      0          0    ]
-	 *
-	 * by: 	  Bpi=[ 0 ]
-	 *					[ 0 ]
-	 *					[ 0 ]
-	 *					[ 0 ]
-	 *					[ 0 ]
-	 *					[ 0 ]
-	 *					[ 0 ]
-	 *					[ h ]
-	 *	where h is the interpolation function for node i.
-	 */
-
-	/*Fetch number of nodes for this finite element*/
-	int pnumnodes = this->NumberofNodesPressure();
-	int vnumnodes = this->NumberofNodesVelocity();
-
-	/*Get nodal functions derivatives*/
-	IssmDouble* vdbasis=xNew<IssmDouble>(3*vnumnodes);
-	IssmDouble* pbasis =xNew<IssmDouble>(pnumnodes);
-	GetNodalFunctionsDerivativesVelocity(vdbasis,xyz_list,gauss);
-	GetNodalFunctionsPressure(pbasis,gauss);
-
-	/*Build B_prime: */
-	for(int i=0;i<vnumnodes;i++){
-		B_prime[(3*vnumnodes+pnumnodes)*0+3*i+0] = vdbasis[0*vnumnodes+i];
-		B_prime[(3*vnumnodes+pnumnodes)*0+3*i+1] = 0.;
-		B_prime[(3*vnumnodes+pnumnodes)*0+3*i+2] = 0.;
-		B_prime[(3*vnumnodes+pnumnodes)*1+3*i+0] = 0.;
-		B_prime[(3*vnumnodes+pnumnodes)*1+3*i+1] = vdbasis[1*vnumnodes+i];
-		B_prime[(3*vnumnodes+pnumnodes)*1+3*i+2] = 0.;
-		B_prime[(3*vnumnodes+pnumnodes)*2+3*i+0] = 0.;
-		B_prime[(3*vnumnodes+pnumnodes)*2+3*i+1] = 0.;
-		B_prime[(3*vnumnodes+pnumnodes)*2+3*i+2] = vdbasis[2*vnumnodes+i];
-		B_prime[(3*vnumnodes+pnumnodes)*3+3*i+0] = vdbasis[1*vnumnodes+i];
-		B_prime[(3*vnumnodes+pnumnodes)*3+3*i+1] = vdbasis[0*vnumnodes+i];
-		B_prime[(3*vnumnodes+pnumnodes)*3+3*i+2] = 0.;
-		B_prime[(3*vnumnodes+pnumnodes)*4+3*i+0] = vdbasis[2*vnumnodes+i];
-		B_prime[(3*vnumnodes+pnumnodes)*4+3*i+1] = 0.;
-		B_prime[(3*vnumnodes+pnumnodes)*4+3*i+2] = vdbasis[0*vnumnodes+i];
-		B_prime[(3*vnumnodes+pnumnodes)*5+3*i+0] = 0.;
-		B_prime[(3*vnumnodes+pnumnodes)*5+3*i+1] = vdbasis[2*vnumnodes+i];
-		B_prime[(3*vnumnodes+pnumnodes)*5+3*i+2] = vdbasis[1*vnumnodes+i];
-		B_prime[(3*vnumnodes+pnumnodes)*6+3*i+0] = vdbasis[0*vnumnodes+i];
-		B_prime[(3*vnumnodes+pnumnodes)*6+3*i+1] = vdbasis[1*vnumnodes+i];
-		B_prime[(3*vnumnodes+pnumnodes)*6+3*i+2] = vdbasis[2*vnumnodes+i];
-		B_prime[(3*vnumnodes+pnumnodes)*7+3*i+0] = 0.;
-		B_prime[(3*vnumnodes+pnumnodes)*7+3*i+1] = 0.;
-		B_prime[(3*vnumnodes+pnumnodes)*7+3*i+2] = 0.;
-	}
-	for(int i=0;i<pnumnodes;i++){
-		B_prime[(3*vnumnodes+pnumnodes)*0+(3*vnumnodes)+i] = 0.;
-		B_prime[(3*vnumnodes+pnumnodes)*1+(3*vnumnodes)+i] = 0.;
-		B_prime[(3*vnumnodes+pnumnodes)*2+(3*vnumnodes)+i] = 0.;
-		B_prime[(3*vnumnodes+pnumnodes)*3+(3*vnumnodes)+i] = 0.;
-		B_prime[(3*vnumnodes+pnumnodes)*4+(3*vnumnodes)+i] = 0.;
-		B_prime[(3*vnumnodes+pnumnodes)*5+(3*vnumnodes)+i] = 0.;
-		B_prime[(3*vnumnodes+pnumnodes)*6+(3*vnumnodes)+i] = 0.;
-		B_prime[(3*vnumnodes+pnumnodes)*7+(3*vnumnodes)+i] = pbasis[i];
-	}
-
-	/*Clean up*/
-	xDelete<IssmDouble>(vdbasis);
-	xDelete<IssmDouble>(pbasis);
-}
-/*}}}*/
-/*FUNCTION PentaRef::GetBprimeFSGLS {{{*/
-void PentaRef::GetBprimeFSGLS(IssmDouble* B_prime, IssmDouble* xyz_list, GaussPenta* gauss){
-	/*	Compute B'  matrix. B'=[B1' B2' B3' B4' B5' B6' Bb'] where Bi' is of size 3*NDOF2. 
-	 *	For node i, Bi' can be expressed in the actual coordinate system
-	 *	by: 
-	 *				Bi'=[  dh/dx   0          0       0]
-	 *					 [   0      dh/dy      0       0]
-	 *					 [   0      0         dh/dz    0]
-	 *					 [  dh/dy   dh/dx      0       0]
-	 *					 [  dh/dz   0        dh/dx     0]
-	 *					 [   0      dh/dz    dh/dy     0]
-	 *					 [  dh/dx   dh/dy    dh/dz     0]
-	 *					 [   0      0          0       h]
-	 *	where h is the interpolation function for node i.
-	 *
-	 * 	Same thing for the bubble fonction except that there is no fourth column
-	 */
-
-	int i;
-	IssmDouble dbasis[3][NUMNODESP1];
-	IssmDouble basis[NUMNODESP1];
-
-	/*Get dbasismini in actual coordinate system: */
-	GetNodalFunctionsP1Derivatives(&dbasis[0][0],xyz_list, gauss);
-	GetNodalFunctionsP1(basis, gauss);
-
-	/*B_primeuild B_prime: */
-	for(i=0;i<NUMNODESP1;i++){
-		B_prime[(NDOF4*NUMNODESP1)*0+NDOF4*i+0] = dbasis[0][i];
-		B_prime[(NDOF4*NUMNODESP1)*0+NDOF4*i+1] = 0.;
-		B_prime[(NDOF4*NUMNODESP1)*0+NDOF4*i+2] = 0.;
-		B_prime[(NDOF4*NUMNODESP1)*1+NDOF4*i+0] = 0.;
-		B_prime[(NDOF4*NUMNODESP1)*1+NDOF4*i+1] = dbasis[1][i];
-		B_prime[(NDOF4*NUMNODESP1)*1+NDOF4*i+2] = 0.;
-		B_prime[(NDOF4*NUMNODESP1)*2+NDOF4*i+0] = 0.;
-		B_prime[(NDOF4*NUMNODESP1)*2+NDOF4*i+1] = 0.;
-		B_prime[(NDOF4*NUMNODESP1)*2+NDOF4*i+2] = dbasis[2][i];
-		B_prime[(NDOF4*NUMNODESP1)*3+NDOF4*i+0] = dbasis[1][i];
-		B_prime[(NDOF4*NUMNODESP1)*3+NDOF4*i+1] = dbasis[0][i];
-		B_prime[(NDOF4*NUMNODESP1)*3+NDOF4*i+2] = 0.;
-		B_prime[(NDOF4*NUMNODESP1)*4+NDOF4*i+0] = dbasis[2][i];
-		B_prime[(NDOF4*NUMNODESP1)*4+NDOF4*i+1] = 0.;
-		B_prime[(NDOF4*NUMNODESP1)*4+NDOF4*i+2] = dbasis[0][i];
-		B_prime[(NDOF4*NUMNODESP1)*5+NDOF4*i+0] = 0.;
-		B_prime[(NDOF4*NUMNODESP1)*5+NDOF4*i+1] = dbasis[2][i];
-		B_prime[(NDOF4*NUMNODESP1)*5+NDOF4*i+2] = dbasis[1][i];
-		B_prime[(NDOF4*NUMNODESP1)*6+NDOF4*i+0] = dbasis[0][i];
-		B_prime[(NDOF4*NUMNODESP1)*6+NDOF4*i+1] = dbasis[1][i];
-		B_prime[(NDOF4*NUMNODESP1)*6+NDOF4*i+2] = dbasis[2][i];
-		B_prime[(NDOF4*NUMNODESP1)*7+NDOF4*i+0] = 0.;
-		B_prime[(NDOF4*NUMNODESP1)*7+NDOF4*i+1] = 0.;
-		B_prime[(NDOF4*NUMNODESP1)*7+NDOF4*i+2] = 0.;
-	}
-
-	for(i=0;i<NUMNODESP1;i++){ //last column 
-		B_prime[(NDOF4*NUMNODESP1)*0+NDOF4*i+3] = 0.;
-		B_prime[(NDOF4*NUMNODESP1)*1+NDOF4*i+3] = 0.;
-		B_prime[(NDOF4*NUMNODESP1)*2+NDOF4*i+3] = 0.;
-		B_prime[(NDOF4*NUMNODESP1)*3+NDOF4*i+3] = 0.;
-		B_prime[(NDOF4*NUMNODESP1)*4+NDOF4*i+3] = 0.;
-		B_prime[(NDOF4*NUMNODESP1)*5+NDOF4*i+3] = 0.;
-		B_prime[(NDOF4*NUMNODESP1)*6+NDOF4*i+3] = 0.;
-		B_prime[(NDOF4*NUMNODESP1)*7+NDOF4*i+3] = - basis[i];
-	}
-
-}
-/*}}}*/
-/*FUNCTION PentaRef::GetBAdvec{{{*/
-void PentaRef::GetBAdvec(IssmDouble* B_advec, IssmDouble* xyz_list, GaussPenta* gauss){
-	/*Compute B  matrix. B=[B1 B2 B3 B4 B5 B6] where Bi is of size 5*NDOF1. 
-	 * For node i, Bi' can be expressed in the actual coordinate system
-	 * by: 
-	 *       Bi_advec =[ h ]
-	 *                 [ h ]
-	 *                 [ h ]
-	 * where h is the interpolation function for node i.
-	 *
-	 * We assume B has been allocated already, of size: 3x(NDOF1*NUMNODESP1)
-	 */
-
-	/*Fetch number of nodes for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Get nodal functions derivatives*/
-	IssmDouble* basis=xNew<IssmDouble>(numnodes);
-	GetNodalFunctions(basis,gauss);
-
-	/*Build B: */
-	for(int i=0;i<numnodes;i++){
-		B_advec[numnodes*0+i] = basis[i];
-		B_advec[numnodes*1+i] = basis[i];
-		B_advec[numnodes*2+i] = basis[i];
-	}
-
-	/*Clean-up*/
-	xDelete<IssmDouble>(basis);
-}
-/*}}}*/
-/*FUNCTION PentaRef::GetBConduct{{{*/
-void PentaRef::GetBConduct(IssmDouble* B_conduct, IssmDouble* xyz_list, GaussPenta* gauss){
-	/*Compute B  matrix. B=[B1 B2 B3 B4 B5 B6] where Bi is of size 5*NDOF1. 
-	 * For node i, Bi' can be expressed in the actual coordinate system
-	 * by: 
-	 *       Bi_conduct=[ dh/dx ]
-	 *                  [ dh/dy ]
-	 *                  [ dh/dz ]
-	 * where h is the interpolation function for node i.
-	 *
-	 * We assume B has been allocated already, of size: 3x(NDOF1*numnodes)
-	 */
-
-	/*Fetch number of nodes for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Get nodal functions derivatives*/
-	IssmDouble* dbasis=xNew<IssmDouble>(3*numnodes);
-	GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
-
-	/*Build B: */
-	for(int i=0;i<numnodes;i++){
-		B_conduct[numnodes*0+i] = dbasis[0*numnodes+i];
-		B_conduct[numnodes*1+i] = dbasis[1*numnodes+i];
-		B_conduct[numnodes*2+i] = dbasis[2*numnodes+i];
-	}
-
-	/*Clean-up*/
-	xDelete<IssmDouble>(dbasis);
-}
-/*}}}*/
-/*FUNCTION PentaRef::GetBVert{{{*/
-void PentaRef::GetBVert(IssmDouble* B, IssmDouble* xyz_list, GaussPenta* gauss){
-	/*	Compute B  matrix. B=[dh1/dz dh2/dz dh3/dz dh4/dz dh5/dz dh6/dz];
-		where hi is the interpolation function for node i.*/
-
-	/*Fetch number of nodes for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Get nodal functions derivatives*/
-	IssmDouble* dbasis=xNew<IssmDouble>(3*numnodes);
-	GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
-
-	/*Build B: */
-	for(int i=0;i<numnodes;i++){
-		B[i] = dbasis[2*numnodes+i];  
-	}
-
-	/*Clean-up*/
-	xDelete<IssmDouble>(dbasis);
-}
-/*}}}*/
-/*FUNCTION PentaRef::GetBprimeAdvec{{{*/
-void PentaRef::GetBprimeAdvec(IssmDouble* Bprime_advec, IssmDouble* xyz_list, GaussPenta* gauss){
-	/*Compute B  matrix. B=[B1 B2 B3 B4 B5 B6] where Bi is of size 5*NDOF1. 
-	 * For node i, Bi' can be expressed in the actual coordinate system
-	 * by: 
-	 *       Biprime_advec=[ dh/dx ]
-	 *                     [ dh/dy ]
-	 *                     [ dh/dz ]
-	 * where h is the interpolation function for node i.
-	 *
-	 * We assume B has been allocated already, of size: 3x(NDOF1*numnodes)
-	 */
-
-	/*Fetch number of nodes for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Get nodal functions derivatives*/
-	IssmDouble* dbasis=xNew<IssmDouble>(3*numnodes);
-	GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
-
-	/*Build B': */
-	for(int i=0;i<numnodes;i++){
-		Bprime_advec[numnodes*0+i] = dbasis[0*numnodes+i];
-		Bprime_advec[numnodes*1+i] = dbasis[1*numnodes+i];
-		Bprime_advec[numnodes*2+i] = dbasis[2*numnodes+i];
-	}
-
-	/*Clean-up*/
-	xDelete<IssmDouble>(dbasis);
-}
-/*}}}*/
-/*FUNCTION PentaRef::GetBprimeVert{{{*/
-void PentaRef::GetBprimeVert(IssmDouble* B, IssmDouble* xyz_list, GaussPenta* gauss){
-
-	GetNodalFunctions(B,gauss);
-
-}
-/*}}}*/
-/*FUNCTION PentaRef::GetBHOFriction{{{*/
-void PentaRef::GetBHOFriction(IssmDouble* B, GaussPenta* gauss){
-	/*Compute B  matrix. B=[B1 B2 B3] where Bi is square and of size 2x2. 
-	 ** For node i, Bi can be expressed in the actual coordinate system
-	 ** by: 
-	 **                 Bi=[ N   0 ]
-	 **                    [ 0   N ]
-	 ** where N is the interpolation function for node i.
-	 **
-	 ** We assume B has been allocated already, of size: 2 (2 x numnodes)
-	 **/
-
-	/*Fetch number of nodes for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Get nodal functions derivatives*/
-	IssmDouble* basis=xNew<IssmDouble>(numnodes);
-	GetNodalFunctions(basis,gauss);
-
-	for(int i=0;i<numnodes;i++){
-		B[2*numnodes*0+2*i+0] = basis[i];
-		B[2*numnodes*0+2*i+1] = 0.;
-		B[2*numnodes*1+2*i+0] = 0.;
-		B[2*numnodes*1+2*i+1] = basis[i];
-	}
-
-	/*Clean-up*/
-	xDelete<IssmDouble>(basis);
-} 
-/*}}}*/
-/*FUNCTION PentaRef::GetLFS{{{*/
-void PentaRef::GetLFS(IssmDouble* LFS, GaussPenta* gauss){
-	/* Compute L  matrix. L=[L1 L2 L3] where Li is square and of size numdof. 
-	 * For node i, Li can be expressed in the actual coordinate system
-	 * by: 
-	 *       Li=[ h 0 0 0 ]
-	 *	 	      [ 0 h 0 0 ]
-	 * where h is the interpolation function for node i.
-	 */
-
-	/*Fetch number of nodes for this finite element*/
-	int pnumnodes = this->NumberofNodesPressure();
-	int vnumnodes = this->NumberofNodesVelocity();
-	int pnumdof   = pnumnodes;
-	int vnumdof   = vnumnodes*NDOF3;
-
-	/*Get nodal functions derivatives*/
-	IssmDouble* vbasis=xNew<IssmDouble>(vnumnodes);
-	GetNodalFunctionsVelocity(vbasis,gauss);
-
-	/*Build LFS: */
-	for(int i=0;i<vnumnodes;i++){
-		LFS[(vnumdof+pnumdof)*0+3*i+0] = vbasis[i];
-		LFS[(vnumdof+pnumdof)*0+3*i+1] = 0.;
-		LFS[(vnumdof+pnumdof)*0+3*i+2] = 0.;
-
-		LFS[(vnumdof+pnumdof)*1+3*i+0] = 0.;
-		LFS[(vnumdof+pnumdof)*1+3*i+1] = vbasis[i];
-		LFS[(vnumdof+pnumdof)*1+3*i+2] = 0.;
-	}
-
-	for(int i=0;i<pnumnodes;i++){
-		LFS[(vnumdof+pnumdof)*0+i+vnumdof+0] = 0.;
-		LFS[(vnumdof+pnumdof)*1+i+vnumdof+0] = 0.;
-	}
-
-	/*Clean-up*/
-	xDelete<IssmDouble>(vbasis);
-}
-/*}}}*/
-/*FUNCTION PentaRef::GetLprimeFS {{{*/
-void PentaRef::GetLprimeFS(IssmDouble* LprimeFS, IssmDouble* xyz_list, GaussPenta* gauss){
-	/* Compute Lprime  matrix. Lprime=[Lp1 Lp2 Lp3] where Lpi is square and of size numdof. 
-	 * For node i, Lpi can be expressed in the actual coordinate system
-	 * by: 
-	 *       Lpi=[ h    0    0   0]1
-	 *		       [ 0    h    0   0]2
-	 *		       [ h    0    0   0]3
-	 *		       [ 0    h    0   0]4
-	 *		       [ 0    0    h   0]5
-	 *		       [ 0    0    h   0]6
-	 *		       [ 0    0  dh/dz 0]7
-	 *		       [ 0    0  dh/dz 0]8
-	 *		       [ 0    0  dh/dz 0]9
-	 *		       [dh/dz 0  dh/dx 0]0
-	 *		       [ 0 dh/dz dh/dy 0]1
-	 *           [ 0    0    0   h]2
-	 *           [ 0    0    0   h]3
-	 *           [ 0    0    0   h]4
-	 *
-	 *       Li=[ h    0    0   0]1
-	 *	 	      [ 0    h    0   0]2
-	 *		      [ 0    0    h   0]3
-	 *		      [ 0    0    h   0]4
-	 *	 	      [ h    0    0   0]5
-	 *	 	      [ 0    h    0   0]6
-	 *	 	      [ h    0    0   0]7
-	 *	 	      [ 0    h    0   0]8
-	 *		      [ 0    0    h   0]9
-	 *		      [ 0    0    h   0]0
-	 *		      [ 0    0    h   0]1
-	 *	 	      [ h    0    0   0]2
-	 *	 	      [ 0    h    0   0]3
-	 *		      [ 0    0    h   0]4
-	 * where h is the interpolation function for node i.
-	 */
-
-	int        num_dof=4;
-	IssmDouble L1L2l3[NUMNODESP1_2d];
-	IssmDouble dbasis[3][NUMNODESP1];
-
-	/*Get L1L2l3 in actual coordinate system: */
-	L1L2l3[0]=gauss->coord1*(1-gauss->coord4)/2.0;
-	L1L2l3[1]=gauss->coord2*(1-gauss->coord4)/2.0;
-	L1L2l3[2]=gauss->coord3*(1-gauss->coord4)/2.0;
-
-	GetNodalFunctionsP1Derivatives(&dbasis[0][0],xyz_list,gauss);
-
-	/*Build LprimeFS: */
-	for(int i=0;i<3;i++){
-		LprimeFS[num_dof*NUMNODESP1_2d*0+num_dof*i+0]  = L1L2l3[i];
-		LprimeFS[num_dof*NUMNODESP1_2d*0+num_dof*i+1]  = 0.;
-		LprimeFS[num_dof*NUMNODESP1_2d*0+num_dof*i+2]  = 0.;
-		LprimeFS[num_dof*NUMNODESP1_2d*0+num_dof*i+3]  = 0.;
-		LprimeFS[num_dof*NUMNODESP1_2d*1+num_dof*i+0]  = 0.;
-		LprimeFS[num_dof*NUMNODESP1_2d*1+num_dof*i+1]  = L1L2l3[i];
-		LprimeFS[num_dof*NUMNODESP1_2d*1+num_dof*i+2]  = 0.;
-		LprimeFS[num_dof*NUMNODESP1_2d*1+num_dof*i+3]  = 0.;
-		LprimeFS[num_dof*NUMNODESP1_2d*2+num_dof*i+0]  = L1L2l3[i];
-		LprimeFS[num_dof*NUMNODESP1_2d*2+num_dof*i+1]  = 0.;
-		LprimeFS[num_dof*NUMNODESP1_2d*2+num_dof*i+2]  = 0.;
-		LprimeFS[num_dof*NUMNODESP1_2d*2+num_dof*i+3]  = 0.;
-		LprimeFS[num_dof*NUMNODESP1_2d*3+num_dof*i+0]  = 0.;
-		LprimeFS[num_dof*NUMNODESP1_2d*3+num_dof*i+1]  = L1L2l3[i];
-		LprimeFS[num_dof*NUMNODESP1_2d*3+num_dof*i+2]  = 0.;
-		LprimeFS[num_dof*NUMNODESP1_2d*3+num_dof*i+3]  = 0.;
-		LprimeFS[num_dof*NUMNODESP1_2d*4+num_dof*i+0]  = 0.;
-		LprimeFS[num_dof*NUMNODESP1_2d*4+num_dof*i+1]  = 0.;
-		LprimeFS[num_dof*NUMNODESP1_2d*4+num_dof*i+2]  = L1L2l3[i];
-		LprimeFS[num_dof*NUMNODESP1_2d*4+num_dof*i+3]  = 0.;
-		LprimeFS[num_dof*NUMNODESP1_2d*5+num_dof*i+0]  = 0.;
-		LprimeFS[num_dof*NUMNODESP1_2d*5+num_dof*i+1]  = 0.;
-		LprimeFS[num_dof*NUMNODESP1_2d*5+num_dof*i+2]  = L1L2l3[i];
-		LprimeFS[num_dof*NUMNODESP1_2d*5+num_dof*i+3]  = 0.;
-		LprimeFS[num_dof*NUMNODESP1_2d*6+num_dof*i+0]  = 0.;
-		LprimeFS[num_dof*NUMNODESP1_2d*6+num_dof*i+1]  = 0.;
-		LprimeFS[num_dof*NUMNODESP1_2d*6+num_dof*i+2]  = dbasis[2][i];
-		LprimeFS[num_dof*NUMNODESP1_2d*6+num_dof*i+3]  = 0.;
-		LprimeFS[num_dof*NUMNODESP1_2d*7+num_dof*i+0]  = 0.;
-		LprimeFS[num_dof*NUMNODESP1_2d*7+num_dof*i+1]  = 0.;
-		LprimeFS[num_dof*NUMNODESP1_2d*7+num_dof*i+2]  = dbasis[2][i];
-		LprimeFS[num_dof*NUMNODESP1_2d*7+num_dof*i+3]  = 0.;
-		LprimeFS[num_dof*NUMNODESP1_2d*8+num_dof*i+0]  = 0.;
-		LprimeFS[num_dof*NUMNODESP1_2d*8+num_dof*i+1]  = 0.;
-		LprimeFS[num_dof*NUMNODESP1_2d*8+num_dof*i+2]  = dbasis[2][i];
-		LprimeFS[num_dof*NUMNODESP1_2d*8+num_dof*i+3]  = 0.;
-		LprimeFS[num_dof*NUMNODESP1_2d*9+num_dof*i+0]  = dbasis[2][i];
-		LprimeFS[num_dof*NUMNODESP1_2d*9+num_dof*i+1]  = 0.;
-		LprimeFS[num_dof*NUMNODESP1_2d*9+num_dof*i+2]  = dbasis[0][i];
-		LprimeFS[num_dof*NUMNODESP1_2d*9+num_dof*i+3]  = 0.;
-		LprimeFS[num_dof*NUMNODESP1_2d*10+num_dof*i+0] = 0.;
-		LprimeFS[num_dof*NUMNODESP1_2d*10+num_dof*i+1] = dbasis[2][i];
-		LprimeFS[num_dof*NUMNODESP1_2d*10+num_dof*i+2] = dbasis[1][i];
-		LprimeFS[num_dof*NUMNODESP1_2d*10+num_dof*i+3] = 0.;
-		LprimeFS[num_dof*NUMNODESP1_2d*11+num_dof*i+0] = 0.;
-		LprimeFS[num_dof*NUMNODESP1_2d*11+num_dof*i+1] = 0.;
-		LprimeFS[num_dof*NUMNODESP1_2d*11+num_dof*i+2] = 0.;
-		LprimeFS[num_dof*NUMNODESP1_2d*11+num_dof*i+3] = L1L2l3[i];
-		LprimeFS[num_dof*NUMNODESP1_2d*12+num_dof*i+0] = 0.;
-		LprimeFS[num_dof*NUMNODESP1_2d*12+num_dof*i+1] = 0.;
-		LprimeFS[num_dof*NUMNODESP1_2d*12+num_dof*i+2] = 0.;
-		LprimeFS[num_dof*NUMNODESP1_2d*12+num_dof*i+3] = L1L2l3[i];
-		LprimeFS[num_dof*NUMNODESP1_2d*13+num_dof*i+0] = 0.;
-		LprimeFS[num_dof*NUMNODESP1_2d*13+num_dof*i+1] = 0;
-		LprimeFS[num_dof*NUMNODESP1_2d*13+num_dof*i+2] = 0;
-		LprimeFS[num_dof*NUMNODESP1_2d*13+num_dof*i+3] = L1L2l3[i];
-	}
-}
-/*}}}*/
-/*FUNCTION PentaRef::GetLSSAFS {{{*/
-void PentaRef::GetLSSAFS(IssmDouble* LFS, GaussPenta* gauss){
-	/*
-	 * Compute L  matrix. L=[L1 L2 L3] where Li is square and of size numdof. 
-	 * For node i, Li can be expressed in the actual coordinate system
-	 * by: 
-	 *       Li=[ h    0 ]
-	 *	 	      [ 0    h ]
-	 *	 	      [ h    0 ]
-	 *	 	      [ 0    h ]
-	 *	 	      [ h    0 ]
-	 *	 	      [ 0    h ]
-	 *	 	      [ h    0 ]
-	 *	 	      [ 0    h ]
-	 * where h is the interpolation function for node i.
-	 */
-
-	int num_dof=2;
-	IssmDouble L1L2l3[NUMNODESP1_2d];
-
-	/*Get L1L2l3 in actual coordinate system: */
-	L1L2l3[0]=gauss->coord1*(1-gauss->coord4)/2.0;
-	L1L2l3[1]=gauss->coord2*(1-gauss->coord4)/2.0;
-	L1L2l3[2]=gauss->coord3*(1-gauss->coord4)/2.0;
-
-	/*Build LFS: */
-	for(int i=0;i<3;i++){
-		LFS[num_dof*NUMNODESP1_2d*0+num_dof*i+0] = L1L2l3[i];
-		LFS[num_dof*NUMNODESP1_2d*0+num_dof*i+1] = 0;
-		LFS[num_dof*NUMNODESP1_2d*1+num_dof*i+0] = 0;
-		LFS[num_dof*NUMNODESP1_2d*1+num_dof*i+1] = L1L2l3[i];
-		LFS[num_dof*NUMNODESP1_2d*2+num_dof*i+0] = L1L2l3[i];
-		LFS[num_dof*NUMNODESP1_2d*2+num_dof*i+1] = 0;
-		LFS[num_dof*NUMNODESP1_2d*3+num_dof*i+0] = 0;
-		LFS[num_dof*NUMNODESP1_2d*3+num_dof*i+1] = L1L2l3[i];
-		LFS[num_dof*NUMNODESP1_2d*4+num_dof*i+0] = L1L2l3[i];
-		LFS[num_dof*NUMNODESP1_2d*4+num_dof*i+1] = 0;
-		LFS[num_dof*NUMNODESP1_2d*5+num_dof*i+0] = 0;
-		LFS[num_dof*NUMNODESP1_2d*5+num_dof*i+1] = L1L2l3[i];
-		LFS[num_dof*NUMNODESP1_2d*6+num_dof*i+0] = L1L2l3[i];
-		LFS[num_dof*NUMNODESP1_2d*6+num_dof*i+1] = 0;
-		LFS[num_dof*NUMNODESP1_2d*7+num_dof*i+0] = 0;
-		LFS[num_dof*NUMNODESP1_2d*7+num_dof*i+1] = L1L2l3[i];
-	}
-}
-/*}}}*/
-/*FUNCTION PentaRef::GetLprimeSSAFS {{{*/
-void PentaRef::GetLprimeSSAFS(IssmDouble* LprimeFS, IssmDouble* xyz_list, GaussPenta* gauss){
-	/* Compute Lprime  matrix. Lprime=[Lp1 Lp2 Lp3] where Lpi is square and of size numdof. 
-	 * For node i, Lpi can be expressed in the actual coordinate system
-	 * by: 
-	 *       Lpi=[ h    0    0   0]
-	 *		       [ 0    h    0   0]
-	 *		       [ 0    0    h   0]
-	 *		       [ 0    0    h   0]
-	 *		       [ 0    0  dh/dz 0]
-	 *		       [ 0    0  dh/dz 0]
-	 *           [ 0    0    0   h]
-	 *           [ 0    0    0   h]
-	 * where h is the interpolation function for node i.
-	 */
-	int num_dof=3;
-	int num_dof_vel=3*NUMNODESP1b;
-	int num_dof_total=3*NUMNODESP1b+1*NUMNODESP1;
-	IssmDouble L1L2l3[NUMNODESP1_2d];
-	IssmDouble dbasis[3][NUMNODESP1];
-
-	/*Get L1L2l3 in actual coordinate system: */
-	L1L2l3[0]=gauss->coord1*(1-gauss->coord4)/2.0;
-	L1L2l3[1]=gauss->coord2*(1-gauss->coord4)/2.0;
-	L1L2l3[2]=gauss->coord3*(1-gauss->coord4)/2.0;
-
-	GetNodalFunctionsP1Derivatives(&dbasis[0][0],xyz_list,gauss);
-
-	/*Build LprimeFS: */
-	for(int i=0;i<3;i++){
-		LprimeFS[num_dof_total*0+num_dof*i+0] = L1L2l3[i];
-		LprimeFS[num_dof_total*0+num_dof*i+1] = 0.;
-		LprimeFS[num_dof_total*0+num_dof*i+2] = 0.;
-		LprimeFS[num_dof_total*1+num_dof*i+0] = 0.;
-		LprimeFS[num_dof_total*1+num_dof*i+1] = L1L2l3[i];
-		LprimeFS[num_dof_total*1+num_dof*i+2] = 0.;
-		LprimeFS[num_dof_total*2+num_dof*i+0] = 0.;
-		LprimeFS[num_dof_total*2+num_dof*i+1] = 0.;
-		LprimeFS[num_dof_total*2+num_dof*i+2] = L1L2l3[i];
-		LprimeFS[num_dof_total*3+num_dof*i+0] = 0.;
-		LprimeFS[num_dof_total*3+num_dof*i+1] = 0.;
-		LprimeFS[num_dof_total*3+num_dof*i+2] = L1L2l3[i];
-		LprimeFS[num_dof_total*4+num_dof*i+0] = 0.;
-		LprimeFS[num_dof_total*4+num_dof*i+1] = 0.;
-		LprimeFS[num_dof_total*4+num_dof*i+2] = dbasis[2][i];
-		LprimeFS[num_dof_total*5+num_dof*i+0] = 0.;
-		LprimeFS[num_dof_total*5+num_dof*i+1] = 0.;
-		LprimeFS[num_dof_total*5+num_dof*i+2] = dbasis[2][i];
-		LprimeFS[num_dof_total*6+num_dof*i+0] = 0.;
-		LprimeFS[num_dof_total*6+num_dof*i+1] = 0.;
-		LprimeFS[num_dof_total*6+num_dof*i+2] = 0.;
-		LprimeFS[num_dof_total*7+num_dof*i+0] = 0.;
-		LprimeFS[num_dof_total*7+num_dof*i+1] = 0.;
-		LprimeFS[num_dof_total*7+num_dof*i+2] = 0.;
-	}
-	for(int i=3;i<7;i++){
-		LprimeFS[num_dof_total*0+num_dof*i+0] = 0.;
-		LprimeFS[num_dof_total*0+num_dof*i+1] = 0.;
-		LprimeFS[num_dof_total*0+num_dof*i+2] = 0.;
-		LprimeFS[num_dof_total*1+num_dof*i+0] = 0.;
-		LprimeFS[num_dof_total*1+num_dof*i+1] = 0.;
-		LprimeFS[num_dof_total*1+num_dof*i+2] = 0.;
-		LprimeFS[num_dof_total*2+num_dof*i+0] = 0.;
-		LprimeFS[num_dof_total*2+num_dof*i+1] = 0.;
-		LprimeFS[num_dof_total*2+num_dof*i+2] = 0.;
-		LprimeFS[num_dof_total*3+num_dof*i+0] = 0.;
-		LprimeFS[num_dof_total*3+num_dof*i+1] = 0.;
-		LprimeFS[num_dof_total*3+num_dof*i+2] = 0.;
-		LprimeFS[num_dof_total*4+num_dof*i+0] = 0.;
-		LprimeFS[num_dof_total*4+num_dof*i+1] = 0.;
-		LprimeFS[num_dof_total*4+num_dof*i+2] = 0.;
-		LprimeFS[num_dof_total*5+num_dof*i+0] = 0.;
-		LprimeFS[num_dof_total*5+num_dof*i+1] = 0.;
-		LprimeFS[num_dof_total*5+num_dof*i+2] = 0.;
-		LprimeFS[num_dof_total*6+num_dof*i+0] = 0.;
-		LprimeFS[num_dof_total*6+num_dof*i+1] = 0.;
-		LprimeFS[num_dof_total*6+num_dof*i+2] = 0.;
-		LprimeFS[num_dof_total*7+num_dof*i+0] = 0.;
-		LprimeFS[num_dof_total*7+num_dof*i+1] = 0.;
-		LprimeFS[num_dof_total*7+num_dof*i+2] = 0.;
-	}
-	for(int i=0;i<3;i++){
-		LprimeFS[num_dof_total*0+num_dof_vel+i] = 0.;
-		LprimeFS[num_dof_total*1+num_dof_vel+i] = 0.;
-		LprimeFS[num_dof_total*2+num_dof_vel+i] = 0.;
-		LprimeFS[num_dof_total*3+num_dof_vel+i] = 0.;
-		LprimeFS[num_dof_total*4+num_dof_vel+i] = 0.;
-		LprimeFS[num_dof_total*5+num_dof_vel+i] = 0.;
-		LprimeFS[num_dof_total*6+num_dof_vel+i] = L1L2l3[i];
-		LprimeFS[num_dof_total*7+num_dof_vel+i] = L1L2l3[i];
-	}
-	for(int i=3;i<6;i++){
-		LprimeFS[num_dof_total*0+num_dof_vel+i] = 0.;
-		LprimeFS[num_dof_total*1+num_dof_vel+i] = 0.;
-		LprimeFS[num_dof_total*2+num_dof_vel+i] = 0.;
-		LprimeFS[num_dof_total*3+num_dof_vel+i] = 0.;
-		LprimeFS[num_dof_total*4+num_dof_vel+i] = 0.;
-		LprimeFS[num_dof_total*5+num_dof_vel+i] = 0.;
-		LprimeFS[num_dof_total*6+num_dof_vel+i] = 0.;
-		LprimeFS[num_dof_total*7+num_dof_vel+i] = 0.;
-	}
-}
-/*}}}*/
-/*FUNCTION PentaRef::GetLFSSSA {{{*/
-void PentaRef::GetLFSSSA(IssmDouble* LFS, GaussPenta* gauss){
-	/* Compute L  matrix. L=[L1 L2 L3] where Li is square and of size numdof. 
-	 * For node i, Li can be expressed in the actual coordinate system
-	 * by: 
-	 *       Li=[ h    0    0 ]
-	 *	 	      [ 0    h    0 ]
-	 *		      [ 0    0    h ]
-	 *		      [ 0    0    h ]
-	 * where h is the interpolation function for node i.
-	 */
-
-	int num_dof=3;
-	IssmDouble L1L2l3[NUMNODESP1_2d];
-
-	/*Get L1L2l3 in actual coordinate system: */
-	L1L2l3[0]=gauss->coord1*(1-gauss->coord4)/2.0;
-	L1L2l3[1]=gauss->coord2*(1-gauss->coord4)/2.0;
-	L1L2l3[2]=gauss->coord3*(1-gauss->coord4)/2.0;
-
-	/*Build LFS: */
-	for(int i=0;i<3;i++){
-		LFS[num_dof*NUMNODESP1_2d*0+num_dof*i+0] = L1L2l3[i];
-		LFS[num_dof*NUMNODESP1_2d*0+num_dof*i+1] = 0.;
-		LFS[num_dof*NUMNODESP1_2d*0+num_dof*i+2] = 0.;
-		LFS[num_dof*NUMNODESP1_2d*1+num_dof*i+0] = 0.;
-		LFS[num_dof*NUMNODESP1_2d*1+num_dof*i+1] = L1L2l3[i];
-		LFS[num_dof*NUMNODESP1_2d*1+num_dof*i+2] = 0.;
-		LFS[num_dof*NUMNODESP1_2d*2+num_dof*i+0] = 0.;
-		LFS[num_dof*NUMNODESP1_2d*2+num_dof*i+1] = 0.;
-		LFS[num_dof*NUMNODESP1_2d*2+num_dof*i+2] = L1L2l3[i];
-		LFS[num_dof*NUMNODESP1_2d*3+num_dof*i+0] = 0.;
-		LFS[num_dof*NUMNODESP1_2d*3+num_dof*i+1] = 0.;
-		LFS[num_dof*NUMNODESP1_2d*3+num_dof*i+2] = L1L2l3[i];
-	}
-}
-/*}}}*/
-/*FUNCTION PentaRef::GetLprimeFSSSA {{{*/
-void PentaRef::GetLprimeFSSSA(IssmDouble* LprimeFS, IssmDouble* xyz_list, GaussPenta* gauss){
-	/* Compute Lprime  matrix. Lprime=[Lp1 Lp2 Lp3] where Lpi is square and of size numdof. 
-	 * For node i, Lpi can be expressed in the actual coordinate system
-	 * by: 
-	 *       Lpi=[ h    0 ]
-	 *		       [ 0    h ]
-	 *		       [ h    0 ]
-	 *		       [ 0    h ]
-	 * where h is the interpolation function for node i.
-	 */
-	int num_dof=2;
-	IssmDouble L1L2l3[NUMNODESP1_2d];
-	IssmDouble dbasis[3][NUMNODESP1];
-
-	/*Get L1L2l3 in actual coordinate system: */
-	L1L2l3[0]=gauss->coord1*(1-gauss->coord4)/2.0;
-	L1L2l3[1]=gauss->coord2*(1-gauss->coord4)/2.0;
-	L1L2l3[2]=gauss->coord3*(1-gauss->coord4)/2.0;
-	GetNodalFunctionsP1Derivatives(&dbasis[0][0],xyz_list,gauss);
-
-	/*Build LprimeFS: */
-	for(int i=0;i<3;i++){
-		LprimeFS[num_dof*NUMNODESP1_2d*0+num_dof*i+0] = L1L2l3[i];
-		LprimeFS[num_dof*NUMNODESP1_2d*0+num_dof*i+1] = 0.;
-		LprimeFS[num_dof*NUMNODESP1_2d*1+num_dof*i+0] = 0.;
-		LprimeFS[num_dof*NUMNODESP1_2d*1+num_dof*i+1] = L1L2l3[i];
-		LprimeFS[num_dof*NUMNODESP1_2d*2+num_dof*i+0] = L1L2l3[i];
-		LprimeFS[num_dof*NUMNODESP1_2d*2+num_dof*i+1] = 0.;
-		LprimeFS[num_dof*NUMNODESP1_2d*3+num_dof*i+0] = 0.;
-		LprimeFS[num_dof*NUMNODESP1_2d*3+num_dof*i+1] = L1L2l3[i];
-	}
-}
-/*}}}*/
 /*FUNCTION PentaRef::GetJacobian {{{*/
-void PentaRef::GetJacobian(IssmDouble* J, IssmDouble* xyz_list,GaussPenta* gauss){
+void PentaRef::GetJacobian(IssmDouble* J, IssmDouble* xyz_list,Gauss* gauss_in){
 	/*The Jacobian is constant over the element, discard the gaussian points. 
 	 * J is assumed to have been allocated of size NDOF2xNDOF2.*/
@@ -1151,4 +66,8 @@
 	IssmDouble y1,y2,y3,y4,y5,y6;
 	IssmDouble z1,z2,z3,z4,z5,z6;
+
+	/*Cast gauss to GaussPenta*/
+	_assert_(gauss_in->Enum()==GaussPentaEnum);
+	GaussPenta* gauss = dynamic_cast<GaussPenta*>(gauss_in);
 
 	/*Figure out xi,eta and zi (parametric coordinates), for this gaussian point: */
@@ -1195,5 +114,5 @@
 /*}}}*/
 /*FUNCTION PentaRef::GetJacobianDeterminant {{{*/
-void PentaRef::GetJacobianDeterminant(IssmDouble*  Jdet, IssmDouble* xyz_list,GaussPenta* gauss){
+void PentaRef::GetJacobianDeterminant(IssmDouble*  Jdet, IssmDouble* xyz_list,Gauss* gauss){
 	/*On a penta, Jacobian varies according to coordinates. We need to get the Jacobian, and take 
 	 * the determinant of it: */
@@ -1210,5 +129,5 @@
 /*}}}*/
 /*FUNCTION PentaRef::GetTriaJacobianDeterminant{{{*/
-void PentaRef::GetTriaJacobianDeterminant(IssmDouble*  Jdet, IssmDouble* xyz_list,GaussPenta* gauss){
+void PentaRef::GetTriaJacobianDeterminant(IssmDouble*  Jdet, IssmDouble* xyz_list,Gauss* gauss){
 	/*The Jacobian determinant is constant over the element, discard the gaussian points. 
 	 * J is assumed to have been allocated of size NDOF2xNDOF2.*/
@@ -1230,5 +149,5 @@
 /*}}}*/
 /*FUNCTION PentaRef::GetSegmentJacobianDeterminant{{{*/
-void PentaRef::GetSegmentJacobianDeterminant(IssmDouble*  Jdet, IssmDouble* xyz_list,GaussPenta* gauss){
+void PentaRef::GetSegmentJacobianDeterminant(IssmDouble*  Jdet, IssmDouble* xyz_list,Gauss* gauss){
 	/*The Jacobian determinant is constant over the element, discard the gaussian points. 
 	 * J is assumed to have been allocated of size NDOF2xNDOF2.*/
@@ -1247,5 +166,5 @@
 /*}}}*/
 /*FUNCTION PentaRef::GetJacobianInvert {{{*/
-void PentaRef::GetJacobianInvert(IssmDouble* Jinv, IssmDouble* xyz_list,GaussPenta* gauss){
+void PentaRef::GetJacobianInvert(IssmDouble* Jinv, IssmDouble* xyz_list,Gauss* gauss){
 
 	/*Jacobian*/
@@ -1259,14 +178,30 @@
 }
 /*}}}*/
-/*FUNCTION PentaRef::GetNodalFunctions{{{*/
-void PentaRef::GetNodalFunctions(IssmDouble* basis,GaussPenta* gauss){
+/*FUNCTION PentaRef::GetNodalFunctions(IssmDouble* basis,Gauss* gauss){{{*/
+void PentaRef::GetNodalFunctions(IssmDouble* basis,Gauss* gauss){
 	/*This routine returns the values of the nodal functions  at the gaussian point.*/
 
 	_assert_(basis);
+	GetNodalFunctions(basis,gauss,this->element_type);
+
+}
+/*}}}*/
+/*FUNCTION PentaRef::GetNodalFunctions(IssmDouble* basis,Gauss* gauss_in,int finiteelement){{{*/
+void PentaRef::GetNodalFunctions(IssmDouble* basis,Gauss* gauss_in,int finiteelement){
+	/*This routine returns the values of the nodal functions  at the gaussian point.*/
+
+	_assert_(basis);
+
+	/*Cast gauss to GaussPenta*/
+	_assert_(gauss_in->Enum()==GaussPentaEnum);
+	GaussPenta* gauss = dynamic_cast<GaussPenta*>(gauss_in);
 
 	/*Get current coordinates in reference element*/
 	IssmDouble zeta=gauss->coord4;
 
-	switch(this->element_type){
+	switch(finiteelement){
+		case P0Enum: 
+			basis[0]=1.;
+			return;
 		case P1Enum: case P1DGEnum:
 			basis[0]=gauss->coord1*(1.-zeta)/2.;
@@ -1324,62 +259,56 @@
 			basis[ 5]=gauss->coord3*(2.*gauss->coord3-1.)*zeta*(zeta+1.)/2.;
 			/*mid-sides of quads*/
-			basis[ 6]=gauss->coord1*(1.-zeta*zeta);
-			basis[ 7]=gauss->coord2*(1.-zeta*zeta);
-			basis[ 8]=gauss->coord3*(1.-zeta*zeta);
+			basis[ 6]=gauss->coord1*(2.*gauss->coord1-1.)*(1.-zeta*zeta);
+			basis[ 7]=gauss->coord2*(2.*gauss->coord2-1.)*(1.-zeta*zeta);
+			basis[ 8]=gauss->coord3*(2.*gauss->coord3-1.)*(1.-zeta*zeta);
 			/*mid-sides of triangles*/
-			basis[ 9]=2.*gauss->coord3*gauss->coord2*zeta*(zeta-1.);
-			basis[10]=2.*gauss->coord3*gauss->coord1*zeta*(zeta-1.);
-			basis[11]=2.*gauss->coord1*gauss->coord2*zeta*(zeta-1.);
-			basis[12]=2.*gauss->coord3*gauss->coord2*zeta*(zeta+1.);
-			basis[13]=2.*gauss->coord3*gauss->coord1*zeta*(zeta+1.);
-			basis[14]=2.*gauss->coord1*gauss->coord2*zeta*(zeta+1.);
-			return;
-			
-			/*
-						MODIFICATION
-			*/
+			basis[ 9]=4.*gauss->coord3*gauss->coord2*zeta*(zeta-1.)/2.;
+			basis[10]=4.*gauss->coord3*gauss->coord1*zeta*(zeta-1.)/2.;
+			basis[11]=4.*gauss->coord1*gauss->coord2*zeta*(zeta-1.)/2.;
+			basis[12]=4.*gauss->coord3*gauss->coord2*zeta*(zeta+1.)/2.;
+			basis[13]=4.*gauss->coord3*gauss->coord1*zeta*(zeta+1.)/2.;
+			basis[14]=4.*gauss->coord1*gauss->coord2*zeta*(zeta+1.)/2.;
+			/*quad faces*/
+			basis[15]=4.*gauss->coord3*gauss->coord2*(1.-zeta*zeta);
+			basis[16]=4.*gauss->coord3*gauss->coord1*(1.-zeta*zeta);
+			basis[17]=4.*gauss->coord1*gauss->coord2*(1.-zeta*zeta);
+			return;
 		case P2xP4Enum :
 			/*Corner nodes*/
-			basis[ 0]=(2./3.)*gauss->coord1*(2.*gauss->coord1-1.)*(zeta-1.)*(zeta-0.5 )*(zeta)*(zeta+0.5);
-			basis[ 1]=(2./3.)*gauss->coord2*(2.*gauss->coord2-1.)*(zeta-1.)*(zeta-0.5 )*(zeta)*(zeta+0.5);
-			basis[ 2]=(2./3.)*gauss->coord3*(2.*gauss->coord3-1.)*(zeta-1.)*(zeta-0.5 )*(zeta)*(zeta+0.5);
-			basis[ 3]=(2./3.)*gauss->coord1*(2.*gauss->coord1-1.)*(zeta-0.5)*(zeta)*(zeta+0.5)*(zeta +1.);
-			basis[ 4]=(2./3.)*gauss->coord2*(2.*gauss->coord2-1.)*(zeta-0.5)*(zeta)*(zeta+0.5)*(zeta +1.);
-			basis[ 5]=(2./3.)*gauss->coord3*(2.*gauss->coord3-1.)*(zeta-0.5)*(zeta)*(zeta+0.5)*(zeta +1.);
-		
+			basis[ 0]=gauss->coord1*(2.*gauss->coord1-1.)*(2./3.)*(zeta-1.)*(zeta-0.5 )*(zeta)*(zeta+0.5);
+			basis[ 1]=gauss->coord2*(2.*gauss->coord2-1.)*(2./3.)*(zeta-1.)*(zeta-0.5 )*(zeta)*(zeta+0.5);
+			basis[ 2]=gauss->coord3*(2.*gauss->coord3-1.)*(2./3.)*(zeta-1.)*(zeta-0.5 )*(zeta)*(zeta+0.5);
+			basis[ 3]=gauss->coord1*(2.*gauss->coord1-1.)*(2./3.)*(zeta-0.5)*(zeta)*(zeta+0.5)*(zeta +1.);
+			basis[ 4]=gauss->coord2*(2.*gauss->coord2-1.)*(2./3.)*(zeta-0.5)*(zeta)*(zeta+0.5)*(zeta +1.);
+			basis[ 5]=gauss->coord3*(2.*gauss->coord3-1.)*(2./3.)*(zeta-0.5)*(zeta)*(zeta+0.5)*(zeta +1.);
 			/*mid-sides of quads*/
-			basis[ 6]=4.*gauss->coord1*(zeta-1.)*(zeta-0.5)*(zeta+0.5)*(zeta+1.);
-			basis[ 7]=4.*gauss->coord2*(zeta-1.)*(zeta-0.5)*(zeta+0.5)*(zeta+1.);
-			basis[ 8]=4.*gauss->coord3*(zeta-1.)*(zeta-0.5)*(zeta+0.5)*(zeta+1.);
-			
+			basis[ 6]=gauss->coord1*(2.*gauss->coord1-1)*4.*(zeta-1.)*(zeta-0.5)*(zeta+0.5)*(zeta+1.);
+			basis[ 7]=gauss->coord2*(2.*gauss->coord2-1)*4.*(zeta-1.)*(zeta-0.5)*(zeta+0.5)*(zeta+1.);
+			basis[ 8]=gauss->coord3*(2.*gauss->coord3-1)*4.*(zeta-1.)*(zeta-0.5)*(zeta+0.5)*(zeta+1.);
 			/*mid-sides of triangles*/
-			basis[ 9]=(2./3.)*gauss->coord2*gauss->coord3*(zeta-1.)*(zeta-0.5)*zeta*(zeta+0.5);
-			basis[10]=(2./3.)*gauss->coord1*gauss->coord3*(zeta-1.)*(zeta-0.5)*zeta*(zeta+0.5);
-			basis[11]=(2./3.)*gauss->coord1*gauss->coord2*(zeta-1.)*(zeta-0.5)*zeta*(zeta+0.5);
-			basis[12]=(2./3.)*gauss->coord2*gauss->coord3*(zeta-0.5)*zeta*(zeta+0.5)*(zeta+1.);
-			basis[13]=(2./3.)*gauss->coord1*gauss->coord3*(zeta-0.5)*zeta*(zeta+0.5)*(zeta+1.);
-			basis[14]=(2./3.)*gauss->coord1*gauss->coord2*(zeta-0.5)*zeta*(zeta+0.5)*(zeta+1.);
-		
+			basis[ 9]=4.*gauss->coord2*gauss->coord3*(2./3.)*(zeta-1.)*(zeta-0.5)*zeta*(zeta+0.5);
+			basis[10]=4.*gauss->coord1*gauss->coord3*(2./3.)*(zeta-1.)*(zeta-0.5)*zeta*(zeta+0.5);
+			basis[11]=4.*gauss->coord1*gauss->coord2*(2./3.)*(zeta-1.)*(zeta-0.5)*zeta*(zeta+0.5);
+			basis[12]=4.*gauss->coord2*gauss->coord3*(2./3.)*(zeta-0.5)*zeta*(zeta+0.5)*(zeta+1.);
+			basis[13]=4.*gauss->coord1*gauss->coord3*(2./3.)*(zeta-0.5)*zeta*(zeta+0.5)*(zeta+1.);
+			basis[14]=4.*gauss->coord1*gauss->coord2*(2./3.)*(zeta-0.5)*zeta*(zeta+0.5)*(zeta+1.);
 			/*quarter-sides of quads*/
-			basis[15]=-(2./3.)*gauss->coord1*(zeta-1.0)*(zeta-0.5)*zeta*(zeta+1.);
-			basis[16]=-(2./3.)*gauss->coord2*(zeta-1.0)*(zeta-0.5)*zeta*(zeta+1.);
-			basis[17]=-(2./3.)*gauss->coord3*(zeta-1.0)*(zeta-0.5)*zeta*(zeta+1.);
-			basis[18]=-(2./3.)*gauss->coord1*(zeta-1.0)*zeta*(zeta+0.5)*(zeta+1.);
-			basis[19]=-(2./3.)*gauss->coord2*(zeta-1.0)*zeta*(zeta+0.5)*(zeta+1.);
-			basis[20]=-(2./3.)*gauss->coord3*(zeta-1.0)*zeta*(zeta+0.5)*(zeta+1.);
-
+			basis[15]=gauss->coord1*(2.*gauss->coord1-1.)*(-8./3.)*(zeta-1.0)*(zeta-0.5)*zeta*(zeta+1.);
+			basis[16]=gauss->coord2*(2.*gauss->coord2-1.)*(-8./3.)*(zeta-1.0)*(zeta-0.5)*zeta*(zeta+1.);
+			basis[17]=gauss->coord3*(2.*gauss->coord3-1.)*(-8./3.)*(zeta-1.0)*(zeta-0.5)*zeta*(zeta+1.);
+			basis[18]=gauss->coord1*(2.*gauss->coord1-1.)*(-8./3.)*(zeta-1.0)*zeta*(zeta+0.5)*(zeta+1.);
+			basis[19]=gauss->coord2*(2.*gauss->coord2-1.)*(-8./3.)*(zeta-1.0)*zeta*(zeta+0.5)*(zeta+1.);
+			basis[20]=gauss->coord3*(2.*gauss->coord3-1.)*(-8./3.)*(zeta-1.0)*zeta*(zeta+0.5)*(zeta+1.);
 			/* mid-sides of interior triangles*/
-			basis[21]=-(8./3.)*gauss->coord2*gauss->coord3*(zeta-1.0)*(zeta-0.5)*zeta*(zeta+1.);
-			basis[22]=-(8./3.)*gauss->coord1*gauss->coord3*(zeta-1.0)*(zeta-0.5)*zeta*(zeta+1.);
-			basis[23]=-(8./3.)*gauss->coord1*gauss->coord2*(zeta-1.0)*(zeta-0.5)*zeta*(zeta+1.);
-			basis[24]=16.*gauss->coord2*gauss->coord3*(zeta-1.0)*(zeta-0.5)*(zeta+0.5)*(zeta+1.);
-			basis[25]=16.*gauss->coord1*gauss->coord3*(zeta-1.0)*(zeta-0.5)*(zeta+0.5)*(zeta+1.);
-			basis[26]=16.*gauss->coord1*gauss->coord2*(zeta-1.0)*(zeta-0.5)*(zeta+0.5)*(zeta+1.);
-			basis[27]=-(8./3.)*gauss->coord2*gauss->coord3*(zeta-1.0)*zeta*(zeta+0.5)*(zeta+1.);
-			basis[28]=-(8./3.)*gauss->coord1*gauss->coord3*(zeta-1.0)*zeta*(zeta+0.5)*(zeta+1.);
-			basis[29]=-(8./3.)*gauss->coord1*gauss->coord2*(zeta-1.0)*zeta*(zeta+0.5)*(zeta+1.);
-			return;
-			
-			
+			basis[21]=4.*gauss->coord2*gauss->coord3*(-8./3.)*(zeta-1.0)*(zeta-0.5)*zeta*(zeta+1.);
+			basis[22]=4.*gauss->coord1*gauss->coord3*(-8./3.)*(zeta-1.0)*(zeta-0.5)*zeta*(zeta+1.);
+			basis[23]=4.*gauss->coord1*gauss->coord2*(-8./3.)*(zeta-1.0)*(zeta-0.5)*zeta*(zeta+1.);
+			basis[24]=4.*gauss->coord2*gauss->coord3*4.*(zeta-1.0)*(zeta-0.5)*(zeta+0.5)*(zeta+1.);
+			basis[25]=4.*gauss->coord1*gauss->coord3*4.*(zeta-1.0)*(zeta-0.5)*(zeta+0.5)*(zeta+1.);
+			basis[26]=4.*gauss->coord1*gauss->coord2*4.*(zeta-1.0)*(zeta-0.5)*(zeta+0.5)*(zeta+1.);
+			basis[27]=4.*gauss->coord2*gauss->coord3*(-8./3.)*(zeta-1.0)*zeta*(zeta+0.5)*(zeta+1.);
+			basis[28]=4.*gauss->coord1*gauss->coord3*(-8./3.)*(zeta-1.0)*zeta*(zeta+0.5)*(zeta+1.);
+			basis[29]=4.*gauss->coord1*gauss->coord2*(-8./3.)*(zeta-1.0)*zeta*(zeta+0.5)*(zeta+1.);
+			return;
 		case P1xP3Enum :
 			/*Corner nodes*/
@@ -1390,5 +319,4 @@
 			basis[ 4]=(9.)/(16.)*gauss->coord2*(zeta-1./3.)*(zeta+1./3.)*(zeta+1.);
 			basis[ 5]=(9.)/(16.)*gauss->coord3*(zeta-1./3.)*(zeta+1./3.)*(zeta+1.);
-		
 			/*quarter-sides of quads*/
 			basis[ 6]=(27.)/(16.)*gauss->coord1*(zeta-1)*(zeta-1./3.)*(zeta+1.);
@@ -1399,5 +327,4 @@
 			basis[11]=-(27.)/(16.)*gauss->coord3*(zeta-1)*(zeta+1./3.)*(zeta+1.);
 			return;
-			
 		default:
 			_error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
@@ -1406,75 +333,38 @@
 /*}}}*/
 /*FUNCTION PentaRef::GetNodalFunctionsVelocity{{{*/
-void PentaRef::GetNodalFunctionsVelocity(IssmDouble* basis,GaussPenta* gauss){
+void PentaRef::GetNodalFunctionsVelocity(IssmDouble* basis,Gauss* gauss){
 	/*This routine returns the values of the nodal functions  at the gaussian point.*/
 
-	switch(this->element_type){
-		case P1P1Enum:
-			this->element_type = P1Enum;
-			this->GetNodalFunctions(basis,gauss);
-			this->element_type = P1P1Enum;
-			return;
-		case P1P1GLSEnum:
-			this->element_type = P1Enum;
-			this->GetNodalFunctions(basis,gauss);
-			this->element_type = P1P1GLSEnum;
-			return;
-		case MINIcondensedEnum:
-			this->element_type = P1bubbleEnum;
-			this->GetNodalFunctions(basis,gauss);
-			this->element_type = MINIcondensedEnum;
-			return;
-		case MINIEnum:
-			this->element_type = P1bubbleEnum;
-			this->GetNodalFunctions(basis,gauss);
-			this->element_type = MINIEnum;
-			return;
-		case TaylorHoodEnum:
-			this->element_type = P2Enum;
-			this->GetNodalFunctions(basis,gauss);
-			this->element_type = TaylorHoodEnum;
-			return;
-		default:
-			_error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
-	}
+	int save = this->element_type;
+	this->element_type = VelocityInterpolation();
+	this->GetNodalFunctions(basis,gauss);
+	this->element_type = save;
+
 }
 /*}}}*/
 /*FUNCTION PentaRef::GetNodalFunctionsPressure{{{*/
-void PentaRef::GetNodalFunctionsPressure(IssmDouble* basis,GaussPenta* gauss){
+void PentaRef::GetNodalFunctionsPressure(IssmDouble* basis,Gauss* gauss){
 	/*This routine returns the values of the nodal functions  at the gaussian point.*/
 
-	switch(this->element_type){
-		case P1P1Enum:
-			this->element_type = P1Enum;
-			this->GetNodalFunctions(basis,gauss);
-			this->element_type = P1P1Enum;
-			return;
-		case P1P1GLSEnum:
-			this->element_type = P1Enum;
-			this->GetNodalFunctions(basis,gauss);
-			this->element_type = P1P1GLSEnum;
-			return;
-		case MINIcondensedEnum:
-			this->element_type = P1Enum;
-			this->GetNodalFunctions(basis,gauss);
-			this->element_type = MINIcondensedEnum;
-			return;
-		case MINIEnum:
-			this->element_type = P1Enum;
-			this->GetNodalFunctions(basis,gauss);
-			this->element_type = MINIEnum;
-			return;
-		case TaylorHoodEnum:
-			this->element_type = P1Enum;
-			this->GetNodalFunctions(basis,gauss);
-			this->element_type = TaylorHoodEnum;
-			return;
-		default:
-			_error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
-	}
+	int save = this->element_type;
+	this->element_type = PressureInterpolation();
+	this->GetNodalFunctions(basis,gauss);
+	this->element_type = save;
+
+}
+/*}}}*/
+/*FUNCTION PentaRef::GetNodalFunctionsTensor{{{*/
+void PentaRef::GetNodalFunctionsTensor(IssmDouble* basis,Gauss* gauss){
+	/*This routine returns the values of the nodal functions  at the gaussian point.*/
+
+	int save = this->element_type;
+	this->element_type = TensorInterpolation();
+	this->GetNodalFunctions(basis,gauss);
+	this->element_type = save;
+
 }
 /*}}}*/
 /*FUNCTION PentaRef::GetNodalFunctionsDerivatives{{{*/
-void PentaRef::GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list, GaussPenta* gauss){
+void PentaRef::GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list, Gauss* gauss){
 
 	/*This routine returns the values of the nodal functions derivatives  (with respect to the 
@@ -1511,76 +401,33 @@
 /*}}}*/
 /*FUNCTION PentaRef::GetNodalFunctionsDerivativesVelocity{{{*/
-void PentaRef::GetNodalFunctionsDerivativesVelocity(IssmDouble* dbasis,IssmDouble* xyz_list, GaussPenta* gauss){
-	switch(this->element_type){
-		case P1P1Enum:
-			this->element_type = P1Enum;
-			this->GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
-			this->element_type = P1P1Enum;
-			return;
-		case P1P1GLSEnum:
-			this->element_type = P1Enum;
-			this->GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
-			this->element_type = P1P1GLSEnum;
-			return;
-		case MINIcondensedEnum:
-			this->element_type = P1bubbleEnum;
-			this->GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
-			this->element_type = MINIcondensedEnum;
-			return;
-		case MINIEnum:
-			this->element_type = P1bubbleEnum;
-			this->GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
-			this->element_type = MINIEnum;
-			return;
-		case TaylorHoodEnum:
-			this->element_type = P2Enum;
-			this->GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
-			this->element_type = TaylorHoodEnum;
-			return;
-		default:
-			_error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
-	}
+void PentaRef::GetNodalFunctionsDerivativesVelocity(IssmDouble* dbasis,IssmDouble* xyz_list, Gauss* gauss){
+
+	int save = this->element_type;
+	this->element_type = VelocityInterpolation();
+	this->GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+	this->element_type = save;
+
 }
 /*}}}*/
 /*FUNCTION PentaRef::GetNodalFunctionsDerivativesPressure{{{*/
-void PentaRef::GetNodalFunctionsDerivativesPressure(IssmDouble* dbasis,IssmDouble* xyz_list, GaussPenta* gauss){
-	switch(this->element_type){
-		case P1P1Enum:
-			this->element_type = P1Enum;
-			this->GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
-			this->element_type = P1P1Enum;
-			return;
-		case P1P1GLSEnum:
-			this->element_type = P1Enum;
-			this->GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
-			this->element_type = P1P1GLSEnum;
-			return;
-		case MINIcondensedEnum:
-			this->element_type = P1Enum;
-			this->GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
-			this->element_type = MINIcondensedEnum;
-			return;
-		case MINIEnum:
-			this->element_type = P1Enum;
-			this->GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
-			this->element_type = MINIEnum;
-			return;
-		case TaylorHoodEnum:
-			this->element_type = P1Enum;
-			this->GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
-			this->element_type = TaylorHoodEnum;
-			return;
-		default:
-			_error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
-	}
+void PentaRef::GetNodalFunctionsDerivativesPressure(IssmDouble* dbasis,IssmDouble* xyz_list, Gauss* gauss){
+
+	int save = this->element_type;
+	this->element_type = PressureInterpolation();
+	this->GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+	this->element_type = save;
 }
 /*}}}*/
 /*FUNCTION PentaRef::GetNodalFunctionsDerivativesReference{{{*/
-void PentaRef::GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,GaussPenta* gauss){
+void PentaRef::GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,Gauss* gauss_in){
 
 	/*This routine returns the values of the nodal functions derivatives  (with respect to the 
 	 * natural coordinate system) at the gaussian point. */
 
-	_assert_(dbasis && gauss);
+	_assert_(dbasis && gauss_in);
+
+	/*Cast gauss to GaussPenta*/
+	_assert_(gauss_in->Enum()==GaussPentaEnum);
+	GaussPenta* gauss = dynamic_cast<GaussPenta*>(gauss_in);
 
 	/*Get current coordinates in reference element*/
@@ -1588,4 +435,10 @@
 
 	switch(this->element_type){
+		case P0Enum: 
+			/*Zero derivative*/
+			dbasis[NUMNODESP0*0+0]   = 0.;
+			dbasis[NUMNODESP0*1+0]   = 0.;
+			dbasis[NUMNODESP0*2+0]   = 0.;
+			return;
 		case P1Enum: case P1DGEnum:
 			/*Nodal function 1*/
@@ -1761,15 +614,15 @@
 
 			/*Nodal function 7*/
-			dbasis[NUMNODESP2*0+6 ] = -0.5*(1.-zeta*zeta);
-			dbasis[NUMNODESP2*1+6 ] = -SQRT3/6.*(1.-zeta*zeta);
-			dbasis[NUMNODESP2*2+6 ] = -2.*zeta*gauss->coord1;
+			dbasis[NUMNODESP2*0+6 ] = (-2.*gauss->coord1 + 0.5)*(1.-zeta*zeta);
+			dbasis[NUMNODESP2*1+6 ] = (-2.*SQRT3/3.*gauss->coord1 + SQRT3/6.)*(1.-zeta*zeta);
+			dbasis[NUMNODESP2*2+6 ] = -2.*zeta*gauss->coord1*(2.*gauss->coord1-1.);
 			/*Nodal function 8*/
-			dbasis[NUMNODESP2*0+7 ] = 0.5*(1.-zeta*zeta);
-			dbasis[NUMNODESP2*1+7 ] = -SQRT3/6.*(1.-zeta*zeta);
-			dbasis[NUMNODESP2*2+7 ] = -2.*zeta*gauss->coord2;
+			dbasis[NUMNODESP2*0+7 ] = (+2.*gauss->coord2 - 0.5)*(1.-zeta*zeta);
+			dbasis[NUMNODESP2*1+7 ] = (-2.*SQRT3/3.*gauss->coord2 + SQRT3/6.)*(1.-zeta*zeta);
+			dbasis[NUMNODESP2*2+7 ] = -2.*zeta*gauss->coord2*(2.*gauss->coord2-1.);
 			/*Nodal function 9*/
 			dbasis[NUMNODESP2*0+8 ] = 0.;
-			dbasis[NUMNODESP2*1+8 ] = SQRT3/3.*(1.-zeta*zeta);
-			dbasis[NUMNODESP2*2+8 ] = -2.*zeta*gauss->coord3;
+			dbasis[NUMNODESP2*1+8 ] = (+4.*SQRT3/3.*gauss->coord3 - SQRT3/3.)*(1.-zeta*zeta);
+			dbasis[NUMNODESP2*2+8 ] = -2.*zeta*gauss->coord3*(2.*gauss->coord3-1.);
 
 			/*Nodal function 10*/
@@ -1797,183 +650,190 @@
 			dbasis[NUMNODESP2*1+14] = .5*zeta*(zeta+1.)*(-2.*SQRT3/3.*(gauss->coord1+gauss->coord2));
 			dbasis[NUMNODESP2*2+14] = 2.*gauss->coord1*gauss->coord2*(2.*zeta+1.);
-			return;
-			
-			/*
-			Modification
-			*/
+
+			/*Nodal function 16*/
+			dbasis[NUMNODESP2*0+15] = 2.*gauss->coord3*(1.-zeta*zeta);
+			dbasis[NUMNODESP2*1+15] = (1.-zeta*zeta)*(+4.*SQRT3/3.*gauss->coord2 - 2.*SQRT3/3.*gauss->coord3);
+			dbasis[NUMNODESP2*2+15] = -2.*zeta*4.*gauss->coord3*gauss->coord2;
+			/*Nodal function 17*/
+			dbasis[NUMNODESP2*0+16] = -2.*gauss->coord3*(1.-zeta*zeta);
+			dbasis[NUMNODESP2*1+16] = (1.-zeta*zeta)*(+4.*SQRT3/3.*gauss->coord1 - 2.*SQRT3/3.*gauss->coord3);
+			dbasis[NUMNODESP2*2+16] = -2.*zeta*4.*gauss->coord3*gauss->coord1;
+			/*Nodal function 18*/
+			dbasis[NUMNODESP2*0+17] = 2.*(gauss->coord1-gauss->coord2)*(1.-zeta*zeta);
+			dbasis[NUMNODESP2*1+17] = (1.-zeta*zeta)*(-2.*SQRT3/3.*(gauss->coord1+gauss->coord2));
+			dbasis[NUMNODESP2*2+17] = -2.*zeta*4.*gauss->coord1*gauss->coord2;
+			return;
 		case P2xP4Enum :
 			/*Nodal function 1*/
 			dbasis[NUMNODESP2xP4*0+0 ] = (-2* gauss->coord1 + 0.5 ) *(2./3.) *(zeta - 1.)*(zeta - 0.5)*(zeta)*(zeta+0.5) ; 
 			dbasis[NUMNODESP2xP4*1+0 ] = (-((2.*SQRT3)/(3.))*gauss->coord1 + (SQRT3/6.) )*(2./3.)*(zeta - 1.)*(zeta - 0.5)*(zeta)*(zeta+0.5) ; 
-			dbasis[NUMNODESP2xP4*2+0 ] = (2./3.)* gauss->coord1 *(2.* gauss->coord1 -1)*( (2.*zeta-1)*(zeta -0.5)*(zeta +0.5) + 2.* zeta *zeta *(zeta -1.)); 
-      /*Nodal function 2*/
+			dbasis[NUMNODESP2xP4*2+0 ] =  gauss->coord1 *(2.* gauss->coord1 -1)* 2./3.*( (2.*zeta-1)*(zeta -0.5)*(zeta +0.5) + 2.* zeta *zeta *(zeta -1.)); 
+			/*Nodal function 2*/
 			dbasis[NUMNODESP2xP4*0+1 ] = (2.*gauss->coord2 - 0.5 ) *(2./3.) *(zeta - 1.)*(zeta - 0.5)*(zeta)*(zeta+0.5) ; 
 			dbasis[NUMNODESP2xP4*1+1 ] = (-((2.*SQRT3)/(3.))*gauss->coord2 + (SQRT3/6.) )*(2./3.)*(zeta - 1.)*(zeta - 0.5)*(zeta)*(zeta+0.5) ; 
-      dbasis[NUMNODESP2xP4*2+1 ] = (2./3.)*gauss->coord2*(2.*gauss->coord2 -1.)*((2.*zeta-1.)*(zeta -0.5)*(zeta +0.5) + 2. * zeta *zeta*(zeta -1.)); 
-      /*Nodal function 3*/
+			dbasis[NUMNODESP2xP4*2+1 ] = gauss->coord2*(2.*gauss->coord2 -1.)* 2./3.* ((2.*zeta-1.)*(zeta -0.5)*(zeta +0.5) + 2. * zeta *zeta*(zeta -1.)); 
+			/*Nodal function 3*/
 			dbasis[NUMNODESP2xP4*0+2 ] = 0. ; 
 			dbasis[NUMNODESP2xP4*1+2 ] = (((4.*SQRT3)/(3.))*gauss->coord3 - (SQRT3)/(3.))*(2./3.)*(zeta -1.)*(zeta-0.5)*(zeta)*(zeta+0.5); 
-      dbasis[NUMNODESP2xP4*2+2 ] = (2./3.)*gauss->coord3*(2.* gauss->coord3 -1.)*( (2.*zeta-1.)*(zeta -0.5)*(zeta +0.5) + 2.*zeta *zeta*(zeta -1.)); 
-      /*Nodal function 4*/
+			dbasis[NUMNODESP2xP4*2+2 ] = gauss->coord3*(2.* gauss->coord3 -1.)* 2./3.*( (2.*zeta-1.)*(zeta -0.5)*(zeta +0.5) + 2.*zeta *zeta*(zeta -1.)); 
+			/*Nodal function 4*/
 			dbasis[NUMNODESP2xP4*0+3 ] = (-2.* gauss->coord1 + 0.5 ) *(2./3.) *(zeta - 0.5)*(zeta)*(zeta+0.5)*(zeta +1. ); 
 			dbasis[NUMNODESP2xP4*1+3 ] = (-((2.*SQRT3)/(3.)) *gauss->coord1 + (SQRT3)/(6.) ) *(2./3.) *(zeta - 0.5)*(zeta)*(zeta+0.5)*(zeta +1. ); 
-      dbasis[NUMNODESP2xP4*2+3 ] = (2./3.)*gauss->coord1*(2.*gauss->coord1 -1.)*( (2.*zeta+1.)*(zeta -0.5)*(zeta +0.5) + 2.*zeta *zeta*(zeta +1.)); 
-      /*Nodal function 5*/
+			dbasis[NUMNODESP2xP4*2+3 ] = gauss->coord1*(2.*gauss->coord1 -1.)* 2./3.*( (2.*zeta+1.)*(zeta -0.5)*(zeta +0.5) + 2.*zeta *zeta*(zeta +1.)); 
+			/*Nodal function 5*/
 			dbasis[NUMNODESP2xP4*0+4 ] = (2*gauss->coord2 - 0.5 ) *(2./3.) *(zeta - 0.5)*(zeta)*(zeta+0.5)*(zeta +1. ); 
-			dbasis[NUMNODESP2xP4*1+4 ] = -((2.*SQRT3)/(3.)) *gauss->coord2 + (SQRT3/(6.))*(2./3.)*(zeta - 0.5)*(zeta)*(zeta+0.5)*(zeta +1. );
-      dbasis[NUMNODESP2xP4*2+4 ] = (2./3.)*gauss->coord2 *(2.*gauss->coord2 -1.)*( (2.*zeta+1.)*(zeta -0.5)*(zeta +0.5) + 2.*zeta *zeta*(zeta +1.)); 
-      /*Nodal function 6*/
+			dbasis[NUMNODESP2xP4*1+4 ] = (-((2.*SQRT3)/(3.)) *gauss->coord2 + (SQRT3/6.))*(2./3.)*(zeta - 0.5)*(zeta)*(zeta+0.5)*(zeta +1. );
+			dbasis[NUMNODESP2xP4*2+4 ] = gauss->coord2 *(2.*gauss->coord2 -1.)* 2./3.*( (2.*zeta+1.)*(zeta -0.5)*(zeta +0.5) + 2.*zeta *zeta*(zeta +1.)); 
+			/*Nodal function 6*/
 			dbasis[NUMNODESP2xP4*0+5 ] = 0. ; 
 			dbasis[NUMNODESP2xP4*1+5 ] = (((4.*SQRT3)/(3.))*gauss->coord3 - SQRT3/3. ) *(2./3.) *(zeta - 0.5)*(zeta)*(zeta+0.5)*(zeta +1. ); 
-      dbasis[NUMNODESP2xP4*2+5 ] = (2./3.)*gauss->coord3 *(2.*gauss->coord3 -1.)*( (2.*zeta+1.)*(zeta -0.5)*(zeta +0.5) + 2.*zeta *zeta*(zeta +1)); 
-      /*Nodal function 7*/
-			dbasis[NUMNODESP2xP4*0+6 ] =  -2. *(zeta - 1.)*(zeta - 0.5)*(zeta+0.5)*(zeta +1. ) ; 
-			dbasis[NUMNODESP2xP4*1+6 ] =  (-4.*SQRT3)/(6.) *(zeta - 1.)*(zeta - 0.5)*(zeta+0.5)*(zeta +1.)  ; 
-      dbasis[NUMNODESP2xP4*2+6 ] =  4.*gauss->coord1*( 4.*zeta *zeta*zeta - (5./2.)*zeta ); 
-      /*Nodal function 8*/
-			dbasis[NUMNODESP2xP4*0+7 ] =  2.*(zeta - 1.)*(zeta - 0.5)*(zeta+0.5)*(zeta +1. ) ; 
-			dbasis[NUMNODESP2xP4*1+7 ] =  ((-4.*SQRT3)/(6.)) *(zeta - 1.)*(zeta - 0.5)*(zeta+0.5)*(zeta +1. )  ; 
-      dbasis[NUMNODESP2xP4*2+7 ] =  4.* gauss->coord2*( 4.*zeta *zeta*zeta - (5./2.)*zeta ); 
-      /*Nodal function 9*/
+			dbasis[NUMNODESP2xP4*2+5 ] = gauss->coord3 *(2.*gauss->coord3 -1.)* 2./3.*( (2.*zeta+1.)*(zeta -0.5)*(zeta +0.5) + 2.*zeta *zeta*(zeta +1)); 
+			/*Nodal function 7*/
+			dbasis[NUMNODESP2xP4*0+6 ] =  (-2.* gauss->coord1 + 0.5 ) * 4.*(zeta - 1.)*(zeta - 0.5)*(zeta+0.5)*(zeta +1. ) ; 
+			dbasis[NUMNODESP2xP4*1+6 ] =  (-((2.*SQRT3)/(3.)) *gauss->coord1 + (SQRT3)/(6.) )* 4.*(zeta - 1.)*(zeta - 0.5)*(zeta+0.5)*(zeta +1.)  ; 
+			dbasis[NUMNODESP2xP4*2+6 ] =  gauss->coord1*(2.*gauss->coord1-1)* 4.*( 4.*zeta *zeta*zeta - (5./2.)*zeta ); 
+			/*Nodal function 8*/
+			dbasis[NUMNODESP2xP4*0+7 ] =  (2*gauss->coord2 - 0.5 )* 4.*(zeta - 1.)*(zeta - 0.5)*(zeta+0.5)*(zeta +1. ) ; 
+			dbasis[NUMNODESP2xP4*1+7 ] =  (-((2.*SQRT3)/(3.)) *gauss->coord2 + (SQRT3)/(6.)) * 4.*(zeta - 1.)*(zeta - 0.5)*(zeta+0.5)*(zeta +1. )  ; 
+			dbasis[NUMNODESP2xP4*2+7 ] =  gauss->coord2*(2.*gauss->coord2-1)* 4.*( 4.*zeta *zeta*zeta - (5./2.)*zeta ); 
+			/*Nodal function 9*/
 			dbasis[NUMNODESP2xP4*0+8 ] = 0. ; 
-			dbasis[NUMNODESP2xP4*1+8 ] = ((4.*SQRT3)/(3.)) *(zeta - 1.)*(zeta - 0.5)*(zeta+0.5)*(zeta +1. )  ; 
-			dbasis[NUMNODESP2xP4*2+8 ] =  4.*gauss->coord3*( 4.*zeta *zeta*zeta - (5./2.)*zeta ); 
-      /*Nodal function 10*/
-			dbasis[NUMNODESP2xP4*0+9 ] = (4./3.)*(gauss->coord3 )*(zeta - 1.)*(zeta - 0.5)*(zeta)*(zeta+0.5) ; 
-			dbasis[NUMNODESP2xP4*1+9 ] =  4.* (((- SQRT3)/6.)* gauss->coord3+ (SQRT3/3.) *gauss->coord2) *(2./3.) *(zeta - 1.)*(zeta - 0.5)*(zeta)*(zeta+0.5);
+			dbasis[NUMNODESP2xP4*1+8 ] = (((4.*SQRT3)/(3.))*gauss->coord3 - SQRT3/3. ) * 4.*(zeta - 1.)*(zeta - 0.5)*(zeta+0.5)*(zeta +1. )  ; 
+			dbasis[NUMNODESP2xP4*2+8 ] = gauss->coord3*(2.*gauss->coord3-1)* 4.*( 4.*zeta *zeta*zeta - (5./2.)*zeta ); 
+			/*Nodal function 10*/
+			dbasis[NUMNODESP2xP4*0+9 ] = 2.*gauss->coord3 * 2./3.*(zeta - 1.)*(zeta - 0.5)*(zeta)*(zeta+0.5) ; 
+			dbasis[NUMNODESP2xP4*1+9 ] = (4.* SQRT3/3.* gauss->coord2- 2.*SQRT3/3. *gauss->coord3) *(2./3.) *(zeta - 1.)*(zeta - 0.5)*(zeta)*(zeta+0.5);
 			dbasis[NUMNODESP2xP4*2+9 ] = 4.* gauss->coord2 * gauss->coord3 *(2./3.)*((2.*zeta-1.)*(zeta -0.5)*(zeta +0.5) + 2.* zeta*zeta*(zeta -1.)); 
-      /*Nodal function 11*/
-			dbasis[NUMNODESP2xP4*0+10] = -(4./3.)* gauss->coord3*(zeta - 1.)*(zeta - 0.5)*(zeta)*(zeta+0.5) ; 
-			dbasis[NUMNODESP2xP4*1+10] =  4.* ((SQRT3/3.)*gauss->coord1- (SQRT3/6.)*gauss->coord3) *(2./3.) *(zeta - 1.)*(zeta - 0.5)*(zeta)*(zeta+0.5);
+			/*Nodal function 11*/
+			dbasis[NUMNODESP2xP4*0+10] = -2.* gauss->coord3* 2./3.*(zeta - 1.)*(zeta - 0.5)*(zeta)*(zeta+0.5) ; 
+			dbasis[NUMNODESP2xP4*1+10] = (4.*SQRT3/3.*gauss->coord1 - 2.*SQRT3/3.*gauss->coord3) * (2./3.) *(zeta - 1.)*(zeta - 0.5)*(zeta)*(zeta+0.5);
 			dbasis[NUMNODESP2xP4*2+10] = 4.* gauss->coord3*gauss->coord1 *(2./3.)*( (2*zeta-1.)*(zeta -0.5)*(zeta +0.5) + 2* zeta * zeta*(zeta -1));
-      /*Nodal function 12*/
-			dbasis[NUMNODESP2xP4*0+11] = 4.* (gauss->coord1*0.5- gauss->coord2 *0.5 )*(2./3.) *(zeta - 1.)*(zeta - 0.5)*(zeta)*(zeta+0.5) ; 
-			dbasis[NUMNODESP2xP4*1+11] =  4.* (- (SQRT3/6.) *gauss->coord2 - (SQRT3/6.) *gauss->coord1) *(2./3.) *(zeta - 1.)*(zeta - 0.5)*(zeta)*(zeta+0.5);
+			/*Nodal function 12*/
+			dbasis[NUMNODESP2xP4*0+11] = 2.* (gauss->coord1- gauss->coord2)* (2./3.) *(zeta - 1.)*(zeta - 0.5)*(zeta)*(zeta+0.5) ; 
+			dbasis[NUMNODESP2xP4*1+11] = -2.* SQRT3/3.*(gauss->coord2 +gauss->coord1) *(2./3.) *(zeta - 1.)*(zeta - 0.5)*(zeta)*(zeta+0.5);
 			dbasis[NUMNODESP2xP4*2+11] = 4.* gauss->coord1*gauss->coord2 *(2./3.) *( (2.*zeta-1)*(zeta -0.5)*(zeta +0.5) + 2* zeta* zeta*(zeta -1));
-      /*Nodal function 13*/
-			dbasis[NUMNODESP2xP4*0+12] = (4./3.) * gauss->coord3 *(zeta - 0.5)*(zeta)*(zeta+0.5)*(zeta +1. ) ; 
-			dbasis[NUMNODESP2xP4*1+12] =  4.* ( (- SQRT3/6. ) * gauss->coord3 + (SQRT3/3.) *gauss->coord2) *(2./3.) *(zeta - 0.5)*(zeta)*(zeta+0.5)*(zeta +1. );
-			dbasis[NUMNODESP2xP4*2+12] = 4.* gauss->coord2*gauss->coord3 *(2./3.)*( (2.*zeta+1.)*(zeta -0.5)*(zeta +0.5) + 2*zeta*zeta*(zeta +1.)); 
-      /*Nodal function 14*/
-			dbasis[NUMNODESP2xP4*0+13] = (- 4./3.) *gauss->coord3*(zeta - 0.5)*(zeta)*(zeta+0.5)*(zeta +1. ) ; 
-			dbasis[NUMNODESP2xP4*1+13] =  4.* ((SQRT3/3.)*gauss->coord1- (SQRT3/6.)*gauss->coord3) *(2./3.) *(zeta - 0.5)*(zeta)*(zeta+0.5)*(zeta +1. );
-			dbasis[NUMNODESP2xP4*2+13] = 4.* gauss->coord3*gauss->coord1 *(2./3.)*( (2.*zeta+1.)*(zeta -0.5)*(zeta +0.5) + 2.*zeta *zeta*(zeta +1.)); 
-      /*Nodal function 15*/
-			dbasis[NUMNODESP2xP4*0+14] = 4.* ( gauss->coord1*0.5- gauss->coord2*0.5) *(2./3.) *(zeta - 0.5)*(zeta)*(zeta+0.5)*(zeta +1. ) ; 
-			dbasis[NUMNODESP2xP4*1+14] =  4.* (- (SQRT3/6.)*gauss->coord2 - (SQRT3/6.)*gauss->coord1) *(2./3.) *(zeta - 0.5)*(zeta)*(zeta+0.5)*(zeta +1. );
-			dbasis[NUMNODESP2xP4*2+14] = 4.* gauss->coord1*gauss->coord2 *(2./3.)*( (2.*zeta+1.)*(zeta -0.5)*(zeta +0.5) + 2* zeta *zeta*(zeta +1.)); 
-      /*Nodal function 16*/
-			dbasis[NUMNODESP2xP4*0+15] =  (8./6.) *(zeta - 1.)*(zeta - 0.5)*(zeta)*(zeta +1. ) ; 
-			dbasis[NUMNODESP2xP4*1+15] =  (8./3.) *(SQRT3/6.) *(zeta - 1.)*(zeta - 0.5)*(zeta)*(zeta +1. ) ; 
-			dbasis[NUMNODESP2xP4*2+15] =  -(8./3.) *gauss->coord1 *((2.*zeta -1. )*(zeta-0.5)*(zeta +1.) +  zeta*(zeta -1.)*( 2.*zeta + 0.5)); 
-      /*Nodal function 17*/
-			dbasis[NUMNODESP2xP4*0+16] = - (8./6.) *(zeta - 1.)*(zeta - 0.5)*(zeta)*(zeta +1. ) ; 
-			dbasis[NUMNODESP2xP4*1+16] =  (8./3.) * (SQRT3/6.) *(zeta - 1.)*(zeta - 0.5)*(zeta)*(zeta +1. ) ; 
-			dbasis[NUMNODESP2xP4*2+16] =  -(8./3.)*gauss->coord2 *((2.*zeta -1. )*(zeta-0.5)*(zeta +1.) +  zeta *(zeta -1.)*( 2.*zeta + 0.5)); 
-      /*Nodal function 18*/
+			/*Nodal function 13*/
+			dbasis[NUMNODESP2xP4*0+12] = 2.* gauss->coord3 * 2./3.*(zeta - 0.5)*(zeta)*(zeta+0.5)*(zeta +1. ) ; 
+			dbasis[NUMNODESP2xP4*1+12] = (4.*SQRT3/3.* gauss->coord2 - 2.*SQRT3/3. *gauss->coord3) *(2./3.) *(zeta - 0.5)*(zeta)*(zeta+0.5)*(zeta +1. );
+			dbasis[NUMNODESP2xP4*2+12] = 4.*gauss->coord2*gauss->coord3 *(2./3.)*( (2.*zeta+1.)*(zeta -0.5)*(zeta +0.5) + 2*zeta*zeta*(zeta +1.)); 
+			/*Nodal function 14*/
+			dbasis[NUMNODESP2xP4*0+13] = - 2.*gauss->coord3* 2./3.*(zeta - 0.5)*(zeta)*(zeta+0.5)*(zeta +1. ) ; 
+			dbasis[NUMNODESP2xP4*1+13] = (4.*SQRT3/3.*gauss->coord1- 2.*SQRT3/3.*gauss->coord3) * (2./3.) *(zeta - 0.5)*(zeta)*(zeta+0.5)*(zeta +1. );
+			dbasis[NUMNODESP2xP4*2+13] = 4.*gauss->coord3*gauss->coord1 *(2./3.)*( (2.*zeta+1.)*(zeta -0.5)*(zeta +0.5) + 2.*zeta *zeta*(zeta +1.)); 
+			/*Nodal function 15*/
+			dbasis[NUMNODESP2xP4*0+14] = 2.* (gauss->coord1- gauss->coord2)* (2./3.) *(zeta - 0.5)*(zeta)*(zeta+0.5)*(zeta +1. ) ; 
+			dbasis[NUMNODESP2xP4*1+14] = -2.* SQRT3/3.*(gauss->coord2 +gauss->coord1) *(2./3.) *(zeta - 0.5)*(zeta)*(zeta+0.5)*(zeta +1. );
+			dbasis[NUMNODESP2xP4*2+14] = 4.*gauss->coord1*gauss->coord2 *(2./3.)*( (2.*zeta+1.)*(zeta -0.5)*(zeta +0.5) + 2* zeta *zeta*(zeta +1.)); 
+			/*Nodal function 16*/
+			dbasis[NUMNODESP2xP4*0+15] = (-2.* gauss->coord1 + 0.5 )* (-8./3.)*(zeta - 1.)*(zeta - 0.5)*(zeta)*(zeta +1. ) ; 
+			dbasis[NUMNODESP2xP4*1+15] = (-2.*SQRT3/3. *gauss->coord1 + SQRT3/6.) * (-8./3.)*(zeta - 1.)*(zeta - 0.5)*(zeta)*(zeta +1. ) ; 
+			dbasis[NUMNODESP2xP4*2+15] = gauss->coord1*(2.*gauss->coord1-1) * (-8./3.)*((2.*zeta -1.)*(zeta-0.5)*(zeta +1.) +zeta*(zeta -1.)*( 2.*zeta + 0.5)); 
+			/*Nodal function 17*/
+			dbasis[NUMNODESP2xP4*0+16] = (2*gauss->coord2 - 0.5 )* (-8./3.)*(zeta - 1.)*(zeta - 0.5)*(zeta)*(zeta +1. ) ; 
+			dbasis[NUMNODESP2xP4*1+16] = (-2.*SQRT3/3. *gauss->coord2 + SQRT3/6.)* (-8./3.)*(zeta - 1.)*(zeta - 0.5)*(zeta)*(zeta +1. ) ; 
+			dbasis[NUMNODESP2xP4*2+16] = gauss->coord2*(2.*gauss->coord2-1) * (-8./3.)*((2.*zeta -1.)*(zeta-0.5)*(zeta +1.) +zeta *(zeta -1.)*( 2.*zeta + 0.5)); 
+			/*Nodal function 18*/
 			dbasis[NUMNODESP2xP4*0+17] = 0. ; 
-			dbasis[NUMNODESP2xP4*1+17] =  (8./3.) *(SQRT3/3.) *(zeta - 1.)*(zeta - 0.5)*(zeta)*(zeta +1. ) ; 
-			dbasis[NUMNODESP2xP4*2+17] =  -(8./3.)*gauss->coord3 *((2.* zeta -1. ) *(zeta-0.5)* (zeta +1.) +  zeta *(zeta -1.)*( 2.*zeta + 0.5));
-      /*Nodal function 19*/
-			dbasis[NUMNODESP2xP4*0+18] =  (4./3.) *(zeta - 1.)*(zeta)*(zeta+0.5)*(zeta +1. ) ; 
-			dbasis[NUMNODESP2xP4*1+18] =  (8./3.)* (SQRT3/6.)*(zeta - 1.)*(zeta)*(zeta+0.5)*(zeta +1. ) ; 
-			dbasis[NUMNODESP2xP4*2+18] =  -(8./3.)*gauss->coord1*((2.*zeta -1. ) *(zeta+0.5)* (zeta +1.) +  zeta* (zeta -1.)*( 2.*zeta + 3./2.));
-      /*Nodal function 20*/
-			dbasis[NUMNODESP2xP4*0+19] =  (8./6.) *(zeta - 1.)*(zeta)*(zeta+0.5)*(zeta +1. ) ; 
-			dbasis[NUMNODESP2xP4*1+19] =  (8./3.)*(SQRT3/6) *(zeta - 1.)*(zeta)*(zeta+0.5)*(zeta +1. ) ; 
-			dbasis[NUMNODESP2xP4*2+19] =  -(8./3.)*gauss->coord2*((2.*zeta -1. )*(zeta+0.5)*(zeta +1.) +  zeta*(zeta -1.)*( 2.*zeta + 3./2.)); 
-      /*Nodal function 21*/
+			dbasis[NUMNODESP2xP4*1+17] = (4.*SQRT3/3.*gauss->coord3 - SQRT3/3. )* (-8./3.)*(zeta - 1.)*(zeta - 0.5)*(zeta)*(zeta +1. ) ; 
+			dbasis[NUMNODESP2xP4*2+17] = gauss->coord3*(2*gauss->coord3-1) * (-8./3.)*((2.*zeta-1.)*(zeta-0.5)*(zeta +1.) +zeta *(zeta -1.)*( 2.*zeta + 0.5));
+			/*Nodal function 19*/
+			dbasis[NUMNODESP2xP4*0+18] = (-2.* gauss->coord1 + 0.5 ) * (-8./3.)*(zeta - 1.)*(zeta)*(zeta+0.5)*(zeta +1. ) ; 
+			dbasis[NUMNODESP2xP4*1+18] =  (-2.*SQRT3/3. *gauss->coord1 + SQRT3/6. )* (-8./3.)*(zeta - 1.)*(zeta)*(zeta+0.5)*(zeta +1. ) ; 
+			dbasis[NUMNODESP2xP4*2+18] = gauss->coord1*(2.*gauss->coord1-1) * (-8./3.)*((2.*zeta -1. ) *(zeta+0.5)* (zeta +1.) +  zeta* (zeta -1.)*( 2.*zeta + 3./2.));
+			/*Nodal function 20*/
+			dbasis[NUMNODESP2xP4*0+19] = (2*gauss->coord2 - 0.5 )* (-8./3.)*(zeta - 1.)*(zeta)*(zeta+0.5)*(zeta +1. ) ; 
+			dbasis[NUMNODESP2xP4*1+19] = (-2.*SQRT3/3.*gauss->coord2 + SQRT3/6.) * (-8./3.)*(zeta - 1.)*(zeta)*(zeta+0.5)*(zeta +1. ) ; 
+			dbasis[NUMNODESP2xP4*2+19] = gauss->coord2*(2.*gauss->coord2-1)* (-8./3.)*((2.*zeta -1. )*(zeta+0.5)*(zeta +1.) +  zeta*(zeta -1.)*( 2.*zeta + 3./2.)); 
+			/*Nodal function 21*/
 			dbasis[NUMNODESP2xP4*0+20] = 0 ; 
-			dbasis[NUMNODESP2xP4*1+20] =  -(8./3.)* (SQRT3/3) *(zeta - 1.)*(zeta - 0.5)*(zeta)*(zeta +1. ) ; 
-			dbasis[NUMNODESP2xP4*2+20] =  -(8./3.)*gauss->coord3 *(2. *zeta -1. )*(zeta+0.5)*(zeta +1.) +  zeta*(zeta -1.)*( 2.*zeta + 3./2.);
-      /*Nodal function 22*/
-			dbasis[NUMNODESP2xP4*0+21] = -(32./6.) *gauss->coord3 *(zeta - 1.)*(zeta - 0.5)*(zeta)*(zeta +1. ); 
-			dbasis[NUMNODESP2xP4*1+21] = -(32./3.)*(- (SQRT3/6.)*gauss->coord3+ (SQRT3/3.)*gauss->coord2 ) *(zeta - 1.)*(zeta - 0.5)*(zeta)*(zeta +1. ) ; 
-			dbasis[NUMNODESP2xP4*2+21] = -(32./3.)*gauss->coord2 *gauss->coord3*((2.*zeta -1. )*(zeta-0.5)*(zeta +1.) +  zeta*(zeta -1.)*( 2.*zeta + 0.5)); 
-      /*Nodal function 23*/
-			dbasis[NUMNODESP2xP4*0+22] = (32./6.) *gauss->coord3 *(zeta - 1.)*(zeta - 0.5)*(zeta)*(zeta +1. ); 
-			dbasis[NUMNODESP2xP4*1+22] = -(32./3.)*( (SQRT3/3.)*gauss->coord1- (SQRT3/6.)*gauss->coord3 )*(zeta -1.)*(zeta - 0.5)*(zeta)*(zeta +1. ) ; 
-			dbasis[NUMNODESP2xP4*2+22] = -(32./3.) *gauss->coord1*gauss->coord3*((2.*zeta -1. )*(zeta-0.5)*(zeta +1.) +  zeta*(zeta -1.)*( 2.*zeta + 0.5)); 
-      /*Nodal function 24*/
-			dbasis[NUMNODESP2xP4*0+23] = -(32./3.)*( gauss->coord1*0.5- gauss->coord2*0.5) *(zeta - 1.)*(zeta - 0.5)*(zeta)*(zeta +1. ); 
-			dbasis[NUMNODESP2xP4*1+23] = -(32./3.)*(- (SQRT3/6.)*gauss->coord2- (SQRT3/6.)*gauss->coord1 ) *(zeta - 1.)*(zeta - 0.5)*(zeta)*(zeta +1. ) ; 
-			dbasis[NUMNODESP2xP4*2+23] = -(32./3.)*gauss->coord1*gauss->coord2*((2.*zeta -1. )* (zeta-0.5) *(zeta +1.) +  zeta* (zeta -1.)*( 2.*zeta + 0.5));
-      /*Nodal function 25*/
-			dbasis[NUMNODESP2xP4*0+24] = 8. *gauss->coord3 *(zeta - 1.)*(zeta - 0.5)*(zeta+0.5)*(zeta +1. ); 
-			dbasis[NUMNODESP2xP4*1+24] = 16.*(- (SQRT3/6.)*gauss->coord3 + (SQRT3/3.) *gauss->coord2) *(zeta - 1.)*(zeta - 0.5)*(zeta+0.5)*(zeta +1. ) ; 
-			dbasis[NUMNODESP2xP4*2+24] = 16.* gauss->coord2 * gauss->coord3* ( 4.* zeta*zeta*zeta - (5./2.) *zeta ); 
-      /*Nodal function 26*/
-			dbasis[NUMNODESP2xP4*0+25] = 8. *gauss->coord3*(zeta - 1.)*(zeta - 0.5)*(zeta+0.5)*(zeta +1. ); 
-			dbasis[NUMNODESP2xP4*1+25] = -16.*((SQRT3/3.)*gauss->coord1- (SQRT3/6.)*gauss->coord3 )*(zeta - 1.)*(zeta - 0.5)*(zeta+0.5)*(zeta +1. ) ; 
-			dbasis[NUMNODESP2xP4*2+25] = 16. * gauss->coord1 * gauss->coord3 *( 4. *zeta*zeta*zeta - (5./2.)* zeta );
-      /*Nodal function 27*/
-			dbasis[NUMNODESP2xP4*0+26] = 16.*( gauss->coord1*0.5-gauss->coord2*0.5) *(zeta - 1.)*(zeta - 0.5)*(zeta+0.5)*(zeta +1. ); 
-			dbasis[NUMNODESP2xP4*1+26] = 16.*(- (SQRT3/6.)*gauss->coord2- (SQRT3/6.)*gauss->coord1 )*(zeta - 1.)*(zeta - 0.5)*(zeta+0.5)*(zeta +1. ) ; 
-			dbasis[NUMNODESP2xP4*2+26] = 16. *gauss->coord1 *gauss->coord2 *( 4.* zeta*zeta*zeta - (5./2.)*zeta ); 
-      /*Nodal function 28*/
-			dbasis[NUMNODESP2xP4*0+27] = -(32./6.)* gauss->coord3*(zeta - 1.)*(zeta)*(zeta+0.5)*(zeta +1. ); 
-			dbasis[NUMNODESP2xP4*1+27] = -(32./3.)*(- (SQRT3/6.)*gauss->coord3+ (SQRT3/3.)*gauss->coord2 ) *(zeta - 1.)*(zeta)*(zeta+0.5)*(zeta +1. ) ; 
-			dbasis[NUMNODESP2xP4*2+27] = -(32./3.)* gauss->coord2*gauss->coord3* ((2.*zeta -1. )*(zeta+0.5)*(zeta +1.) +  zeta*(zeta -1.)*( 2.*zeta + (3./2.))); 
-      /*Nodal function 29*/
-			dbasis[NUMNODESP2xP4*0+28] = (32./6.) *gauss->coord3 *(zeta - 1.)*(zeta)*(zeta+0.5)*(zeta +1. ); 
-			dbasis[NUMNODESP2xP4*1+28] = -(32./3.)*((SQRT3/3.)*gauss->coord1- (SQRT3/6.)*gauss->coord3 ) *(zeta - 1.)*(zeta)*(zeta+0.5)*(zeta +1. ) ; 
-			dbasis[NUMNODESP2xP4*2+28] = -(32./3.)* gauss->coord1*gauss->coord3* ((2.*zeta -1. )*(zeta+0.5)*(zeta +1.) +  zeta*(zeta -1.)*( 2.*zeta + (3./2.))); 
-      /*Nodal function 30*/
-			dbasis[NUMNODESP2xP4*0+29] = -(32./3.)*( gauss->coord1*0.5- gauss->coord2*0.5)*(zeta - 1.)*(zeta)*(zeta+0.5)*(zeta +1. ); 
-			dbasis[NUMNODESP2xP4*1+29] = -(32./3.)*(- (SQRT3/6.)*gauss->coord2- (SQRT3/6.)*gauss->coord1 ) *(zeta - 1.)*(zeta)*(zeta+0.5)*(zeta +1. ) ; 
-			dbasis[NUMNODESP2xP4*2+29] = -(32./3.)* gauss->coord1*gauss->coord2 *((2.*zeta -1. )*(zeta+0.5)*(zeta +1) +   zeta*(zeta -1.)*( 2.*zeta + (3./2.))); 
-			return;
-			
+			dbasis[NUMNODESP2xP4*1+20] = (4.*SQRT3/3.*gauss->coord3 - SQRT3/3.)* (-8./3.)*(zeta - 1.)*(zeta + 0.5)*(zeta)*(zeta +1. ) ; 
+			dbasis[NUMNODESP2xP4*2+20] = gauss->coord3*(2*gauss->coord3-1) * (-8./3.)*((2. *zeta -1. )*(zeta+0.5)*(zeta +1.) +  zeta*(zeta -1.)*( 2.*zeta + 3./2.));
+			/*Nodal function 22*/
+			dbasis[NUMNODESP2xP4*0+21] = 2. *gauss->coord3 * (-8./3.)*(zeta - 1.)*(zeta - 0.5)*(zeta)*(zeta +1. ); 
+			dbasis[NUMNODESP2xP4*1+21] = (4.* SQRT3/3.*gauss->coord2- 2.*SQRT3/3.*gauss->coord3) * (-8./3.)*(zeta - 1.)*(zeta - 0.5)*(zeta)*(zeta +1. ) ; 
+			dbasis[NUMNODESP2xP4*2+21] = 4.*gauss->coord2 *gauss->coord3* (-8./3.)*((2.*zeta -1. )*(zeta-0.5)*(zeta +1.) +  zeta*(zeta -1.)*( 2.*zeta + 0.5)); 
+			/*Nodal function 23*/
+			dbasis[NUMNODESP2xP4*0+22] = -2. *gauss->coord3 *( -8./3.)*(zeta - 1.)*(zeta - 0.5)*(zeta)*(zeta +1. ); 
+			dbasis[NUMNODESP2xP4*1+22] = (4.* SQRT3/3.*gauss->coord1- 2.*SQRT3/3.*gauss->coord3 )*(-8./3.)*(zeta -1.)*(zeta - 0.5)*(zeta)*(zeta +1. ) ; 
+			dbasis[NUMNODESP2xP4*2+22] = 4.*gauss->coord1*gauss->coord3* (-8./3.)*((2.*zeta -1. )*(zeta-0.5)*(zeta +1.) +  zeta*(zeta -1.)*( 2.*zeta + 0.5)); 
+			/*Nodal function 24*/
+			dbasis[NUMNODESP2xP4*0+23] = 2.*(gauss->coord1- gauss->coord2) * (-8./3.)*(zeta - 1.)*(zeta - 0.5)*(zeta)*(zeta +1. ); 
+			dbasis[NUMNODESP2xP4*1+23] = -2.*SQRT3/3.*(gauss->coord2+ gauss->coord1) * (-8./3.)*(zeta - 1.)*(zeta - 0.5)*(zeta)*(zeta +1. ) ; 
+			dbasis[NUMNODESP2xP4*2+23] = 4.*gauss->coord1*gauss->coord2* (-8./3.)*((2.*zeta -1. )* (zeta-0.5) *(zeta +1.) +  zeta* (zeta -1.)*( 2.*zeta + 0.5));
+			/*Nodal function 25*/
+			dbasis[NUMNODESP2xP4*0+24] = 2. *gauss->coord3 *4.*(zeta - 1.)*(zeta - 0.5)*(zeta+0.5)*(zeta +1. ); 
+			dbasis[NUMNODESP2xP4*1+24] = (4.*SQRT3/3.*gauss->coord2 - 2.* SQRT3/3. *gauss->coord3) *4.*(zeta - 1.)*(zeta - 0.5)*(zeta+0.5)*(zeta +1. ) ; 
+			dbasis[NUMNODESP2xP4*2+24] = 4.* gauss->coord2 * gauss->coord3* 4.*( 4.* zeta*zeta*zeta - 5./2. *zeta ); 
+			/*Nodal function 26*/
+			dbasis[NUMNODESP2xP4*0+25] = -2. *gauss->coord3*4.*(zeta - 1.)*(zeta - 0.5)*(zeta+0.5)*(zeta +1. ); 
+			dbasis[NUMNODESP2xP4*1+25] = (4.*SQRT3/3.*gauss->coord1- 2.*SQRT3/3.*gauss->coord3 )*4.*(zeta - 1.)*(zeta - 0.5)*(zeta+0.5)*(zeta +1. ) ; 
+			dbasis[NUMNODESP2xP4*2+25] = 4. * gauss->coord1 * gauss->coord3 *4.*( 4. *zeta*zeta*zeta - 5./2.* zeta );
+			/*Nodal function 27*/
+			dbasis[NUMNODESP2xP4*0+26] = 2.*( gauss->coord1-gauss->coord2) * 4.*(zeta - 1.)*(zeta - 0.5)*(zeta+0.5)*(zeta +1. ); 
+			dbasis[NUMNODESP2xP4*1+26] = -2.* SQRT3/3.*(gauss->coord1+ gauss->coord2 )*4.*(zeta - 1.)*(zeta - 0.5)*(zeta+0.5)*(zeta +1. ) ; 
+			dbasis[NUMNODESP2xP4*2+26] = 4. *gauss->coord1 *gauss->coord2 *4.*( 4.* zeta*zeta*zeta - 5./2.*zeta ); 
+			/*Nodal function 28*/
+			dbasis[NUMNODESP2xP4*0+27] = 2.* gauss->coord3* (-8./3.)*(zeta - 1.)*(zeta)*(zeta+0.5)*(zeta +1. ); 
+			dbasis[NUMNODESP2xP4*1+27] = (4.*SQRT3/3.*gauss->coord2- 2.*SQRT3/3.*gauss->coord3) * (-8./3.)*(zeta - 1.)*(zeta)*(zeta+0.5)*(zeta +1. ) ; 
+			dbasis[NUMNODESP2xP4*2+27] = 4.* gauss->coord2*gauss->coord3* (-8./3.)*((2.*zeta -1. )*(zeta+0.5)*(zeta +1.) +zeta*(zeta -1.)*( 2.*zeta + 3./2.)); 
+			/*Nodal function 29*/
+			dbasis[NUMNODESP2xP4*0+28] = -2.*gauss->coord3 *(-8./3.)*(zeta - 1.)*(zeta)*(zeta+0.5)*(zeta +1. ); 
+			dbasis[NUMNODESP2xP4*1+28] = (4.*SQRT3/3.*gauss->coord1- 2.*SQRT3/3.*gauss->coord3) * (-8./3.)*(zeta - 1.)*(zeta)*(zeta+0.5)*(zeta +1. ) ; 
+			dbasis[NUMNODESP2xP4*2+28] = 4.* gauss->coord1*gauss->coord3* (-8./3.)*((2.*zeta -1. )*(zeta+0.5)*(zeta +1.) +zeta*(zeta -1.)*( 2.*zeta + 3./2.)); 
+			/*Nodal function 30*/
+			dbasis[NUMNODESP2xP4*0+29] = 2.*(gauss->coord1-gauss->coord2)* (-8./3.)*(zeta - 1.)*(zeta)*(zeta+0.5)*(zeta +1. ); 
+			dbasis[NUMNODESP2xP4*1+29] = -2.*SQRT3/3.*(gauss->coord1+gauss->coord2) * (-8./3.)*(zeta - 1.)*(zeta)*(zeta+0.5)*(zeta +1. ) ; 
+			dbasis[NUMNODESP2xP4*2+29] = 4.* gauss->coord1*gauss->coord2 * (-8./3.)*((2.*zeta -1. )*(zeta+0.5)*(zeta +1) +zeta*(zeta -1.)*( 2.*zeta + 3./2.)); 
+			return;
 		case P1xP3Enum :
 			/*Nodal function 1*/
-	    dbasis[NUMNODESP1xP3*0+0 ] =  (9./32.)*(zeta-1)*(zeta-1./3.)*(zeta+1./3.);
-	    dbasis[NUMNODESP1xP3*1+0 ] = ((3.*SQRT3)/32.)*(zeta-1)*(zeta-1./3.)*(zeta+1./3.);
-	    dbasis[NUMNODESP1xP3*2+0 ] =- (9./16.)* gauss->coord1 *( 2. *zeta *( zeta -1. ) + ( zeta - (1./3.) )*( zeta + (1./3.) ));
+			dbasis[NUMNODESP1xP3*0+0 ] =  (9./32.)*(zeta-1)*(zeta-1./3.)*(zeta+1./3.);
+			dbasis[NUMNODESP1xP3*1+0 ] = ((3.*SQRT3)/32.)*(zeta-1)*(zeta-1./3.)*(zeta+1./3.);
+			dbasis[NUMNODESP1xP3*2+0 ] =- (9./16.)* gauss->coord1 *( 2. *zeta *( zeta -1. ) + ( zeta - (1./3.) )*( zeta + (1./3.) ));
 			/*Nodal function 2*/
-	    dbasis[NUMNODESP1xP3*0+1 ] = - (9./32.)*(zeta-1)*(zeta-1./3.)*(zeta+1./3.);
-	    dbasis[NUMNODESP1xP3*1+1 ] = ((3.*SQRT3)/32.) *(zeta-1)*(zeta-1./3.)*(zeta+1./3.);
-	    dbasis[NUMNODESP1xP3*2+1 ] =- (9./16.)*gauss->coord2 *( 2.* zeta* ( zeta -1. ) + ( zeta - (1./3.) )*( zeta + (1./3.) ));
-		  /*Nodal function 3*/
-	    dbasis[NUMNODESP1xP3*0+2 ] =  0.;
-	    dbasis[NUMNODESP1xP3*1+2 ] = - ((3.*SQRT3)/32.)*(zeta-1)*(zeta-1./3.)*(zeta+1./3.);
-	    dbasis[NUMNODESP1xP3*2+2 ] = - (9./16.)* gauss->coord3* ( 2. *zeta *( zeta -1. ) + ( zeta - (1./3.) )*( zeta + (1./3.) ));
+			dbasis[NUMNODESP1xP3*0+1 ] = - (9./32.)*(zeta-1)*(zeta-1./3.)*(zeta+1./3.);
+			dbasis[NUMNODESP1xP3*1+1 ] = ((3.*SQRT3)/32.) *(zeta-1)*(zeta-1./3.)*(zeta+1./3.);
+			dbasis[NUMNODESP1xP3*2+1 ] =- (9./16.)*gauss->coord2 *( 2.* zeta* ( zeta -1. ) + ( zeta - (1./3.) )*( zeta + (1./3.) ));
+			/*Nodal function 3*/
+			dbasis[NUMNODESP1xP3*0+2 ] =  0.;
+			dbasis[NUMNODESP1xP3*1+2 ] = - ((3.*SQRT3)/16.)*(zeta-1)*(zeta-1./3.)*(zeta+1./3.);
+			dbasis[NUMNODESP1xP3*2+2 ] = - (9./16.)* gauss->coord3* ( 2. *zeta *( zeta -1. ) + ( zeta - (1./3.) )*( zeta + (1./3.) ));
 			/*Nodal function 4*/	 
-	    dbasis[NUMNODESP1xP3*0+3 ] = -  (9./32.)*(zeta-1./3.)*(zeta+1./3.)*(zeta+1.);
-	    dbasis[NUMNODESP1xP3*1+3 ] =  -((3.*SQRT3)/32.) *(zeta-1./3.)*(zeta+1./3.)*(zeta+1.);
-	    dbasis[NUMNODESP1xP3*2+3 ] = (9./16.)* gauss->coord1*( 2.* zeta *( zeta +1. ) + ( zeta - (1./3.) )*( zeta + (1./3.) ));
+			dbasis[NUMNODESP1xP3*0+3 ] = -  (9./32.)*(zeta-1./3.)*(zeta+1./3.)*(zeta+1.);
+			dbasis[NUMNODESP1xP3*1+3 ] =  -((3.*SQRT3)/32.) *(zeta-1./3.)*(zeta+1./3.)*(zeta+1.);
+			dbasis[NUMNODESP1xP3*2+3 ] = (9./16.)* gauss->coord1*( 2.* zeta *( zeta +1. ) + ( zeta - (1./3.) )*( zeta + (1./3.) ));
 			/*Nodal function 5*/	
-	    dbasis[NUMNODESP1xP3*0+4 ] =   (9./32.)* (zeta-1./3.)*(zeta+1./3.)*(zeta+1.);
-	    dbasis[NUMNODESP1xP3*1+4 ] = - ((3.*SQRT3)/32.) *(zeta-1./3.)*(zeta+1./3.)*(zeta+1.);
-	    dbasis[NUMNODESP1xP3*2+4 ] = (9./16.)* gauss->coord2* ( 2.* zeta *( zeta +1. ) + ( zeta - (1./3.) )*( zeta + (1./3.) ));
+			dbasis[NUMNODESP1xP3*0+4 ] =   (9./32.)* (zeta-1./3.)*(zeta+1./3.)*(zeta+1.);
+			dbasis[NUMNODESP1xP3*1+4 ] = - ((3.*SQRT3)/32.) *(zeta-1./3.)*(zeta+1./3.)*(zeta+1.);
+			dbasis[NUMNODESP1xP3*2+4 ] = (9./16.)* gauss->coord2* ( 2.* zeta *( zeta +1. ) + ( zeta - (1./3.) )*( zeta + (1./3.) ));
 			/*Nodal function 6*/	
-	    dbasis[NUMNODESP1xP3*0+5 ] =  0.;
-	    dbasis[NUMNODESP1xP3*1+5 ] =  ((3.*SQRT3)/16.)  *(zeta-1./3.)*(zeta+1./3.)*(zeta+1.);
-	    dbasis[NUMNODESP1xP3*2+5 ] =  (9./16.)* gauss->coord3 *( 2.* zeta * ( zeta  + 1. ) + ( zeta - (1./3.) )*( zeta + (1./3.) ));
+			dbasis[NUMNODESP1xP3*0+5 ] =  0.;
+			dbasis[NUMNODESP1xP3*1+5 ] =  ((3.*SQRT3)/16.)  *(zeta-1./3.)*(zeta+1./3.)*(zeta+1.);
+			dbasis[NUMNODESP1xP3*2+5 ] =  (9./16.)* gauss->coord3 *( 2.* zeta * ( zeta  + 1. ) + ( zeta - (1./3.) )*( zeta + (1./3.) ));
 			/*Nodal function 7*/	
-	    dbasis[NUMNODESP1xP3*0+6 ] = -  (27./32.) *(zeta-1)*(zeta-1./3.)*(zeta+1.);
-	    dbasis[NUMNODESP1xP3*1+6 ] = -  (27./32.) *(zeta-1)*(zeta-1./3.)*(zeta+1.);
-	    dbasis[NUMNODESP1xP3*2+6 ] =  gauss->coord1*(27./16.)*( 2.* zeta *( zeta - (1./3.)) + ( zeta - 1. )*( zeta + 1. ));
+			dbasis[NUMNODESP1xP3*0+6 ] = -  (27./32.) *(zeta-1)*(zeta-1./3.)*(zeta+1.);
+			dbasis[NUMNODESP1xP3*1+6 ] = -  (9.*SQRT3/32.) *(zeta-1)*(zeta-1./3.)*(zeta+1.);
+			dbasis[NUMNODESP1xP3*2+6 ] =  gauss->coord1*(27./16.)*( 2.* zeta *( zeta - (1./3.)) + ( zeta - 1. )*( zeta + 1. ));
 			/*Nodal function 8*/	
-	    dbasis[NUMNODESP1xP3*0+7 ] =  (27./32.) *(zeta-1)*(zeta-1./3.)*(zeta+1.);
-	    dbasis[NUMNODESP1xP3*1+7 ] = -(27./32.) *(zeta-1)*(zeta-1./3.)*(zeta+1.);
-	    dbasis[NUMNODESP1xP3*2+7 ] =  gauss->coord2*(27./16.)*( 2.* zeta *( zeta - (1./3.)) + ( zeta - 1. )*( zeta + 1. ));
+			dbasis[NUMNODESP1xP3*0+7 ] =  (27./32.) *(zeta-1)*(zeta-1./3.)*(zeta+1.);
+			dbasis[NUMNODESP1xP3*1+7 ] = -((9.*SQRT3)/32.) *(zeta-1)*(zeta-1./3.)*(zeta+1.);
+			dbasis[NUMNODESP1xP3*2+7 ] =  gauss->coord2*(27./16.)*( 2.* zeta *( zeta - (1./3.)) + ( zeta - 1. )*( zeta + 1. ));
 			/*Nodal function 9*/	
-	    dbasis[NUMNODESP1xP3*0+8 ] = 0.;
-	    dbasis[NUMNODESP1xP3*1+8 ] =  ((9.*SQRT3)/16.) *(zeta-1.)*(zeta-1./3.)*(zeta+1.);
-	    dbasis[NUMNODESP1xP3*2+8 ] =  gauss->coord3*(27./16.)*( 2. *zeta *( zeta - (1./3.)) + ( zeta - 1. )*( zeta + 1. ));
+			dbasis[NUMNODESP1xP3*0+8 ] = 0.;
+			dbasis[NUMNODESP1xP3*1+8 ] =  ((9.*SQRT3)/16.) *(zeta-1.)*(zeta-1./3.)*(zeta+1.);
+			dbasis[NUMNODESP1xP3*2+8 ] =  gauss->coord3*(27./16.)*( 2. *zeta *( zeta - (1./3.)) + ( zeta - 1. )*( zeta + 1. ));
 			/*Nodal function 10*/	
-	    dbasis[NUMNODESP1xP3*0+9 ] = - (27./32.) *(zeta-1.)*(zeta+1./3.)*(zeta+1.);
-	    dbasis[NUMNODESP1xP3*1+9 ] = - ((9.*SQRT3)/32.) *(zeta-1.)*(zeta+1./3.)*(zeta+1.);
-	    dbasis[NUMNODESP1xP3*2+9 ] =  gauss->coord1 *(27./16.)*( 2* zeta *( zeta + (1./3.)) + ( zeta - 1. )*( zeta + 1. ));
+			dbasis[NUMNODESP1xP3*0+9 ] = (27./32.) *(zeta-1.)*(zeta+1./3.)*(zeta+1.);
+			dbasis[NUMNODESP1xP3*1+9 ] = ((9.*SQRT3)/32.) *(zeta-1.)*(zeta+1./3.)*(zeta+1.);
+			dbasis[NUMNODESP1xP3*2+9 ] =  -gauss->coord1 *(27./16.)*( 2* zeta *( zeta + (1./3.)) + ( zeta - 1. )*( zeta + 1. ));
 			/*Nodal function 11*/	
-	    dbasis[NUMNODESP1xP3*0+10] =  (27./32.) *(zeta-1)*(zeta+1./3.)*(zeta+1);
-	    dbasis[NUMNODESP1xP3*1+10] = - ((9.*SQRT3)/32.)  *(zeta-1.)*(zeta+1./3.)*(zeta+1);
-	    dbasis[NUMNODESP1xP3*2+10] =  gauss->coord2 *(27./16.) * 2.* zeta *( zeta + (1./3.) + ( zeta - 1. )*( zeta + 1. ));
+			dbasis[NUMNODESP1xP3*0+10] = - (27./32.) *(zeta-1)*(zeta+1./3.)*(zeta+1);
+			dbasis[NUMNODESP1xP3*1+10] = ((9.*SQRT3)/32.)  *(zeta-1.)*(zeta+1./3.)*(zeta+1);
+			dbasis[NUMNODESP1xP3*2+10] = -gauss->coord2 *(27./16.) *( 2.* zeta *( zeta + (1./3.)) + ( zeta - 1. )*( zeta + 1. ));
 			/*Nodal function 12*/	
-	    dbasis[NUMNODESP1xP3*0+11] = 0.;
-	    dbasis[NUMNODESP1xP3*1+11] =  ((9.*SQRT3)/16.) *(zeta-1.)*(zeta+1./3.)*(zeta+1);
-	    dbasis[NUMNODESP1xP3*2+11] =  gauss->coord3 *(27./16.)* 2.* zeta *( zeta + (1./3.) + ( zeta - 1. )*( zeta + 1. ));
-			return;
-			
+			dbasis[NUMNODESP1xP3*0+11] = 0.;
+			dbasis[NUMNODESP1xP3*1+11] = -((9.*SQRT3)/16.) *(zeta-1.)*(zeta+1./3.)*(zeta+1);
+			dbasis[NUMNODESP1xP3*2+11] = -gauss->coord3 *(27./16.)*( 2.* zeta *( zeta + (1./3.)) + ( zeta - 1. )*( zeta + 1. ));
+			return;
 		default:
 			_error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
@@ -1983,6 +843,10 @@
 /*}}}*/
 /*FUNCTION PentaRef::GetNodalFunctionsMINI{{{*/
-void PentaRef::GetNodalFunctionsMINI(IssmDouble* l1l7, GaussPenta* gauss){
+void PentaRef::GetNodalFunctionsMINI(IssmDouble* l1l7, Gauss* gauss_in){
 	/*This routine returns the values of the nodal functions  at the gaussian point.*/
+
+	/*Cast gauss to GaussPenta*/
+	_assert_(gauss_in->Enum()==GaussPentaEnum);
+	GaussPenta* gauss = dynamic_cast<GaussPenta*>(gauss_in);
 
 	l1l7[0]=gauss->coord1*(1.0-gauss->coord4)/2.0;
@@ -1997,5 +861,5 @@
 /*}}}*/
 /*FUNCTION PentaRef::GetNodalFunctionsMINIDerivatives{{{*/
-void PentaRef::GetNodalFunctionsMINIDerivatives(IssmDouble* dbasismini,IssmDouble* xyz_list, GaussPenta* gauss){
+void PentaRef::GetNodalFunctionsMINIDerivatives(IssmDouble* dbasismini,IssmDouble* xyz_list, Gauss* gauss){
 
 	/*This routine returns the values of the nodal functions derivatives  (with respect to the 
@@ -2027,8 +891,13 @@
 /*}}}*/
 /*FUNCTION PentaRef::GetNodalFunctionsMINIDerivativesReference{{{*/
-void PentaRef::GetNodalFunctionsMINIDerivativesReference(IssmDouble* dbasis,GaussPenta* gauss){
-
+void PentaRef::GetNodalFunctionsMINIDerivativesReference(IssmDouble* dbasis,Gauss* gauss_in){
 	/*This routine returns the values of the nodal functions derivatives  (with respect to the 
 	 * natural coordinate system) at the gaussian point. */
+
+	/*Cast gauss to GaussPenta*/
+	_assert_(gauss_in->Enum()==GaussPentaEnum);
+	GaussPenta* gauss = dynamic_cast<GaussPenta*>(gauss_in);
+
+
 	IssmDouble zeta=gauss->coord4;
 
@@ -2064,6 +933,10 @@
 /*}}}*/
 /*FUNCTION PentaRef::GetNodalFunctionsP1 {{{*/
-void PentaRef::GetNodalFunctionsP1(IssmDouble* basis, GaussPenta* gauss){
+void PentaRef::GetNodalFunctionsP1(IssmDouble* basis, Gauss* gauss_in){
 	/*This routine returns the values of the nodal functions  at the gaussian point.*/
+
+	/*Cast gauss to GaussPenta*/
+	_assert_(gauss_in->Enum()==GaussPentaEnum);
+	GaussPenta* gauss = dynamic_cast<GaussPenta*>(gauss_in);
 
 	basis[0]=gauss->coord1*(1-gauss->coord4)/2.0;
@@ -2077,5 +950,5 @@
 /*}}}*/
 /*FUNCTION PentaRef::GetNodalFunctionsP1Derivatives {{{*/
-void PentaRef::GetNodalFunctionsP1Derivatives(IssmDouble* dbasis,IssmDouble* xyz_list, GaussPenta* gauss){
+void PentaRef::GetNodalFunctionsP1Derivatives(IssmDouble* dbasis,IssmDouble* xyz_list, Gauss* gauss){
 
 	/*This routine returns the values of the nodal functions derivatives  (with respect to the 
@@ -2106,8 +979,12 @@
 /*}}}*/
 /*FUNCTION PentaRef::GetNodalFunctionsP1DerivativesReference {{{*/
-void PentaRef::GetNodalFunctionsP1DerivativesReference(IssmDouble* dbasis,GaussPenta* gauss){
+void PentaRef::GetNodalFunctionsP1DerivativesReference(IssmDouble* dbasis,Gauss* gauss_in){
 
 	/*This routine returns the values of the nodal functions derivatives  (with respect to the 
 	 * natural coordinate system) at the gaussian point. Those values vary along xi,eta,z */
+
+	/*Cast gauss to GaussPenta*/
+	_assert_(gauss_in->Enum()==GaussPentaEnum);
+	GaussPenta* gauss = dynamic_cast<GaussPenta*>(gauss_in);
 
 	IssmDouble zeta=gauss->coord4;
@@ -2140,21 +1017,21 @@
 /*}}}*/
 /*FUNCTION PentaRef::GetQuadJacobianDeterminant{{{*/
-void PentaRef::GetQuadJacobianDeterminant(IssmDouble* Jdet,IssmDouble xyz_list[4][3],GaussPenta* gauss){
+void PentaRef::GetQuadJacobianDeterminant(IssmDouble* Jdet,IssmDouble* xyz_list,Gauss* gauss){
 	/*This routine returns the values of the nodal functions  at the gaussian point.*/
 
 	IssmDouble x1,x2,x3,x4,y1,y2,y3,y4,z1,z2,z3,z4;
 
-	x1=xyz_list[0][0];
-	y1=xyz_list[0][1];
-	z1=xyz_list[0][2];
-	x2=xyz_list[1][0];
-	y2=xyz_list[1][1];
-	z2=xyz_list[1][2];
-	x3=xyz_list[2][0];
-	y3=xyz_list[2][1];
-	z3=xyz_list[2][2];
-	x4=xyz_list[3][0];
-	y4=xyz_list[3][1];
-	z4=xyz_list[3][2];
+	x1=xyz_list[0*3+0];
+	y1=xyz_list[0*3+1];
+	z1=xyz_list[0*3+2];
+	x2=xyz_list[1*3+0];
+	y2=xyz_list[1*3+1];
+	z2=xyz_list[1*3+2];
+	x3=xyz_list[2*3+0];
+	y3=xyz_list[2*3+1];
+	z3=xyz_list[2*3+2];
+	x4=xyz_list[3*3+0];
+	y4=xyz_list[3*3+1];
+	z4=xyz_list[3*3+2];
 
 	/*Jdet = (Area of the trapezoid)/(Area trapezoid ref) with AreaRef = 4*/
@@ -2165,21 +1042,35 @@
 }
 /*}}}*/
-/*FUNCTION PentaRef::GetInputValue{{{*/
-void PentaRef::GetInputValue(IssmDouble* pvalue,IssmDouble* plist,GaussPenta* gauss){
-	/*P1 interpolation on Gauss point*/
-
-	/*intermediary*/
-	IssmDouble basis[6];
-
-	/*nodal functions: */
-	GetNodalFunctionsP1(&basis[0],gauss);
-
-	/*Assign output pointers:*/
-	*pvalue=basis[0]*plist[0]+basis[1]*plist[1]+basis[2]*plist[2]+basis[3]*plist[3]+basis[4]*plist[4]+basis[5]*plist[5];
+/*FUNCTION PentaRef::GetInputValue(IssmDouble* pvalue,IssmDouble* plist,Gauss* gauss){{{*/
+void PentaRef::GetInputValue(IssmDouble* pvalue,IssmDouble* plist,Gauss* gauss){
+
+	GetInputValue(pvalue,plist,gauss,this->element_type);
+
+}
+/*}}}*/
+/*FUNCTION PentaRef::GetInputValue(IssmDouble* pvalue,IssmDouble* plist,Gauss* gauss,int finiteelement){{{*/
+void PentaRef::GetInputValue(IssmDouble* pvalue,IssmDouble* plist,Gauss* gauss,int finiteelement){
+
+	/*Output*/
+	IssmDouble value =0.;
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = this->NumberofNodes(finiteelement);
+
+	/*Get nodal functions*/
+	IssmDouble* basis=xNew<IssmDouble>(numnodes);
+	GetNodalFunctions(basis, gauss,finiteelement);
+
+	/*Calculate parameter for this Gauss point*/
+	for(int i=0;i<numnodes;i++) value += basis[i]*plist[i];
+
+	/*Assign output pointer*/
+	xDelete<IssmDouble>(basis);
+	*pvalue = value;
 
 }
 /*}}}*/
 /*FUNCTION PentaRef::GetInputDerivativeValue{{{*/
-void PentaRef::GetInputDerivativeValue(IssmDouble* p, IssmDouble* plist,IssmDouble* xyz_list, GaussPenta* gauss){
+void PentaRef::GetInputDerivativeValue(IssmDouble* p, IssmDouble* plist,IssmDouble* xyz_list, Gauss* gauss){
 	/*From node values of parameter p (p_list[0], p_list[1], p_list[2],
 	 * p_list[3], p_list[4] and p_list[4]), return parameter derivative value at
@@ -2191,20 +1082,41 @@
 	 *   p is a vector of size 3x1 already allocated.
 	 */
-	IssmDouble dbasis[3][NUMNODESP1];
-
-	/*Get nodal funnctions derivatives in actual coordinate system: */
-	GetNodalFunctionsP1Derivatives(&dbasis[0][0],xyz_list, gauss);
-
-	/*Assign output*/
-	p[0]=plist[0]*dbasis[0][0]+plist[1]*dbasis[0][1]+plist[2]*dbasis[0][2]+plist[3]*dbasis[0][3]+plist[4]*dbasis[0][4]+plist[5]*dbasis[0][5];
-	p[1]=plist[0]*dbasis[1][0]+plist[1]*dbasis[1][1]+plist[2]*dbasis[1][2]+plist[3]*dbasis[1][3]+plist[4]*dbasis[1][4]+plist[5]*dbasis[1][5];
-	p[2]=plist[0]*dbasis[2][0]+plist[1]*dbasis[2][1]+plist[2]*dbasis[2][2]+plist[3]*dbasis[2][3]+plist[4]*dbasis[2][4]+plist[5]*dbasis[2][5];
-
-}
-/*}}}*/
-/*FUNCTION PentaRef::NumberofNodes{{{*/
+
+	/*Output*/
+	IssmDouble dpx=0.;
+	IssmDouble dpy=0.;
+	IssmDouble dpz=0.;
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = this->NumberofNodes();
+
+	/*Get nodal functions derivatives*/
+	IssmDouble* dbasis=xNew<IssmDouble>(3*numnodes);
+	GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+
+	/*Calculate parameter for this Gauss point*/
+	for(int i=0;i<numnodes;i++) dpx += dbasis[0*numnodes+i]*plist[i];
+	for(int i=0;i<numnodes;i++) dpy += dbasis[1*numnodes+i]*plist[i];
+	for(int i=0;i<numnodes;i++) dpz += dbasis[2*numnodes+i]*plist[i];
+
+	/*Assign values*/
+	xDelete<IssmDouble>(dbasis);
+	p[0]=dpx;
+	p[1]=dpy;
+	p[2]=dpz;
+
+}
+/*}}}*/
+/*FUNCTION PentaRef::NumberofNodes(){{{*/
 int PentaRef::NumberofNodes(void){
 
-	switch(this->element_type){
+	return this->NumberofNodes(this->element_type);
+}
+/*}}}*/
+/*FUNCTION PentaRef::NumberofNodes(int finiteelement){{{*/
+int PentaRef::NumberofNodes(int finiteelement){
+
+	switch(finiteelement){
+		case P0Enum:                return NUMNODESP0;
 		case P1Enum:                return NUMNODESP1;
 		case P1bubbleEnum:          return NUMNODESP1b;
@@ -2218,6 +1130,7 @@
 		case MINIEnum:              return NUMNODESP1b+NUMNODESP1;
 		case TaylorHoodEnum:        return NUMNODESP2+NUMNODESP1;
-		case P2xP4Enum:				return NUMNODESP2xP4;
-		case P1xP3Enum:				return NUMNODESP1xP3;
+		case OneLayerP4zEnum:       return NUMNODESP2xP4+NUMNODESP1;
+		case P2xP4Enum:             return NUMNODESP2xP4;
+		case P1xP3Enum:             return NUMNODESP1xP3;
 		default:       _error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
 	}
@@ -2235,4 +1148,5 @@
 		case MINIEnum:          return NUMNODESP1;
 		case TaylorHoodEnum:    return NUMNODESP1;
+		case OneLayerP4zEnum:   return NUMNODESP1;
 		default: _error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
 	}
@@ -2250,4 +1164,5 @@
 		case MINIEnum:          return NUMNODESP1b;
 		case TaylorHoodEnum:    return NUMNODESP2;
+		case OneLayerP4zEnum:   return NUMNODESP2xP4;
 		default:       _error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
 	}
@@ -2265,4 +1180,5 @@
 		case MINIEnum:          return P1bubbleEnum;
 		case TaylorHoodEnum:    return P2Enum;
+		case OneLayerP4zEnum:   return P2xP4Enum;
 		default:       _error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
 	}
@@ -2280,5 +1196,17 @@
 		case MINIEnum:          return P1Enum;
 		case TaylorHoodEnum:    return P1Enum;
+		case OneLayerP4zEnum:   return P1Enum;
 		default:       _error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
+	}
+
+	return -1;
+}
+/*}}}*/
+/*FUNCTION PentaRef::TensorInterpolation{{{*/
+int PentaRef::TensorInterpolation(void){
+
+	switch(this->element_type){
+		case XTaylorHoodEnum:    return P1DGEnum;
+		default: _error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
 	}
 
@@ -2324,6 +1252,23 @@
 			indices[1] = 1;
 			indices[2] = 2;
-			return;
+			break;
+		case P1xP3Enum:
+			numindices = 3;
+			indices    = xNew<int>(numindices);
+			indices[0] = 0;
+			indices[1] = 1;
+			indices[2] = 2;
+			break;
 		case P2Enum:
+			numindices = 6;
+			indices    = xNew<int>(numindices);
+			indices[0] = 0;
+			indices[1] = 1;
+			indices[2] = 2;
+			indices[3] = 9;
+			indices[4] = 10;
+			indices[5] = 11;
+			break;
+		case P2xP4Enum:
 			numindices = 6;
 			indices    = xNew<int>(numindices);
Index: /issm/trunk/src/c/classes/Elements/PentaRef.h
===================================================================
--- /issm/trunk/src/c/classes/Elements/PentaRef.h	(revision 17805)
+++ /issm/trunk/src/c/classes/Elements/PentaRef.h	(revision 17806)
@@ -7,5 +7,5 @@
 #define _PENTAREF_H_
 
-class GaussPenta;
+class Gauss;
 class PentaRef{
 
@@ -22,57 +22,39 @@
 
 		/*Numerics*/
-		void GetNodalFunctions(IssmDouble* basis, GaussPenta* gauss);
-		void GetNodalFunctionsVelocity(IssmDouble* basis, GaussPenta* gauss);
-		void GetNodalFunctionsPressure(IssmDouble* basis, GaussPenta* gauss);
-		void GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list,GaussPenta* gauss);
-		void GetNodalFunctionsDerivativesVelocity(IssmDouble* dbasis,IssmDouble* xyz_list,GaussPenta* gauss);
-		void GetNodalFunctionsDerivativesPressure(IssmDouble* dbasis,IssmDouble* xyz_list,GaussPenta* gauss);
-		void GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,GaussPenta* gauss);
-		void GetNodalFunctionsP1(IssmDouble* l1l6, GaussPenta* gauss);
-		void GetNodalFunctionsMINI(IssmDouble* l1l7, GaussPenta* gauss);
-		void GetNodalFunctionsP1Derivatives(IssmDouble* dh1dh6,IssmDouble* xyz_list, GaussPenta* gauss);
-		void GetNodalFunctionsMINIDerivatives(IssmDouble* dh1dh7,IssmDouble* xyz_list, GaussPenta* gauss);
-		void GetNodalFunctionsP1DerivativesReference(IssmDouble* dl1dl6,GaussPenta* gauss);
-		void GetNodalFunctionsMINIDerivativesReference(IssmDouble* dl1dl7,GaussPenta* gauss);
-		void GetQuadJacobianDeterminant(IssmDouble*  Jdet, IssmDouble xyz_list[4][3],GaussPenta* gauss);
-		void GetJacobian(IssmDouble* J, IssmDouble* xyz_list,GaussPenta* gauss);
-		void GetJacobianDeterminant(IssmDouble*  Jdet, IssmDouble* xyz_list,GaussPenta* gauss);
-		void GetTriaJacobianDeterminant(IssmDouble*  Jdet, IssmDouble* xyz_list,GaussPenta* gauss);
-		void GetSegmentJacobianDeterminant(IssmDouble*  Jdet, IssmDouble* xyz_list,GaussPenta* gauss);
-		void GetJacobianInvert(IssmDouble*  Jinv, IssmDouble* xyz_list,GaussPenta* gauss);
-		void GetBSSAHO(IssmDouble* B, IssmDouble* xyz_list, GaussPenta* gauss);
-		void GetBSSAFS(IssmDouble* B, IssmDouble* xyz_list, GaussPenta* gauss);
-		void GetBHO(IssmDouble* B, IssmDouble* xyz_list, GaussPenta* gauss);
-		void GetBFSstrainrate(IssmDouble* B, IssmDouble* xyz_list, GaussPenta* gauss);
-		void GetBFS(IssmDouble* B, IssmDouble* xyz_list, GaussPenta* gauss);
-		void GetBFSGLS(IssmDouble* B, IssmDouble* xyz_list, GaussPenta* gauss);
-		void GetBprimeSSAFS(IssmDouble* Bprime, IssmDouble* xyz_list, GaussPenta* gauss);
-		void GetBprimeHO(IssmDouble* B, IssmDouble* xyz_list, GaussPenta* gauss);
-		void GetBprimeFS(IssmDouble* B_prime, IssmDouble* xyz_list, GaussPenta* gauss);
-		void GetBprimeFSGLS(IssmDouble* B_prime, IssmDouble* xyz_list, GaussPenta* gauss);
-		void GetBprimeVert(IssmDouble* B, IssmDouble* xyz_list, GaussPenta* gauss);
-		void GetBAdvec(IssmDouble* B_advec, IssmDouble* xyz_list, GaussPenta* gauss);
-		void GetBConduct(IssmDouble* B_conduct, IssmDouble* xyz_list, GaussPenta* gauss);
-		void GetBVert(IssmDouble* B, IssmDouble* xyz_list, GaussPenta* gauss);
-		void GetBprimeAdvec(IssmDouble* Bprime_advec, IssmDouble* xyz_list, GaussPenta* gauss);
-		void GetBHOFriction(IssmDouble* L, GaussPenta* gauss);
-		void GetLFS(IssmDouble* LFS, GaussPenta* gauss);
-		void GetLprimeFS(IssmDouble* LprimeFS, IssmDouble* xyz_list, GaussPenta* gauss);
-		void GetLSSAFS(IssmDouble* LSSAFS, GaussPenta* gauss);
-		void GetLprimeSSAFS(IssmDouble* LprimeSSAFS, IssmDouble* xyz_list, GaussPenta* gauss);
-		void GetLFSSSA(IssmDouble* LFSSSA, GaussPenta* gauss);
-		void GetLprimeFSSSA(IssmDouble* LprimeFSSSA, IssmDouble* xyz_list, GaussPenta* gauss);
-		void GetInputValue(IssmDouble* pvalue,IssmDouble* plist, GaussPenta* gauss);
-		void GetInputValue(IssmDouble* pvalue,IssmDouble* plist,GaussTria* gauss){_error_("only PentaGauss are supported");};
-		void GetInputDerivativeValue(IssmDouble* pvalues, IssmDouble* plist,IssmDouble* xyz_list, GaussPenta* gauss);
-		void GetInputDerivativeValue(IssmDouble* pvalues, IssmDouble* plist,IssmDouble* xyz_list, GaussTria* gauss){_error_("only PentaGauss are supported");};
+		void GetNodalFunctions(IssmDouble* basis, Gauss* gauss);
+		void GetNodalFunctions(IssmDouble* basis, Gauss* gauss,int finiteelement);
+		void GetNodalFunctionsVelocity(IssmDouble* basis, Gauss* gauss);
+		void GetNodalFunctionsPressure(IssmDouble* basis, Gauss* gauss);
+		void GetNodalFunctionsTensor(IssmDouble* basis, Gauss* gauss);
+		void GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss);
+		void GetNodalFunctionsDerivativesVelocity(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss);
+		void GetNodalFunctionsDerivativesPressure(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss);
+		void GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,Gauss* gauss);
+		void GetNodalFunctionsP1(IssmDouble* l1l6, Gauss* gauss);
+		void GetNodalFunctionsMINI(IssmDouble* l1l7, Gauss* gauss);
+		void GetNodalFunctionsP1Derivatives(IssmDouble* dh1dh6,IssmDouble* xyz_list, Gauss* gauss);
+		void GetNodalFunctionsMINIDerivatives(IssmDouble* dh1dh7,IssmDouble* xyz_list, Gauss* gauss);
+		void GetNodalFunctionsP1DerivativesReference(IssmDouble* dl1dl6,Gauss* gauss);
+		void GetNodalFunctionsMINIDerivativesReference(IssmDouble* dl1dl7,Gauss* gauss);
+		void GetQuadJacobianDeterminant(IssmDouble*  Jdet, IssmDouble* xyz_list,Gauss* gauss);
+		void GetJacobian(IssmDouble* J, IssmDouble* xyz_list,Gauss* gauss);
+		void GetJacobianDeterminant(IssmDouble*  Jdet, IssmDouble* xyz_list,Gauss* gauss);
+		void GetTriaJacobianDeterminant(IssmDouble*  Jdet, IssmDouble* xyz_list,Gauss* gauss);
+		void GetSegmentJacobianDeterminant(IssmDouble*  Jdet, IssmDouble* xyz_list,Gauss* gauss);
+		void GetJacobianInvert(IssmDouble*  Jinv, IssmDouble* xyz_list,Gauss* gauss);
+		void GetLprimeFSSSA(IssmDouble* LprimeFSSSA, IssmDouble* xyz_list, Gauss* gauss);
+		void GetInputValue(IssmDouble* pvalue,IssmDouble* plist, Gauss* gauss);
+		void GetInputValue(IssmDouble* pvalue,IssmDouble* plist, Gauss* gauss,int finiteelement);
+		void GetInputDerivativeValue(IssmDouble* pvalues, IssmDouble* plist,IssmDouble* xyz_list, Gauss* gauss);
 
 		void BasalNodeIndices(int* pnumindices,int** pindices,int finiteelement);
 		void SurfaceNodeIndices(int* pnumindices,int** pindices,int finiteelement);
 		int  NumberofNodes(void);
+		int  NumberofNodes(int finiteelement);
 		int  NumberofNodesVelocity(void);
 		int  NumberofNodesPressure(void);
 		int  VelocityInterpolation(void);
 		int  PressureInterpolation(void);
+		int  TensorInterpolation(void);
 };
 #endif
Index: /issm/trunk/src/c/classes/Elements/Seg.cpp
===================================================================
--- /issm/trunk/src/c/classes/Elements/Seg.cpp	(revision 17805)
+++ /issm/trunk/src/c/classes/Elements/Seg.cpp	(revision 17806)
@@ -19,17 +19,7 @@
 #define NUMVERTICES 2
 /*Constructors/destructor/copy*/
-/*FUNCTION Seg::Seg(){{{*/
-Seg::Seg(){
-	this->nodes      = NULL;
-	this->vertices   = NULL;
-	this->material   = NULL;
-	this->matpar     = NULL;
-	this->inputs     = NULL;
-	this->parameters = NULL;
-}
-/*}}}*/
 /*FUNCTION Seg::Seg(int id, int sid,int index, IoModel* iomodel,int nummodels){{{*/
 Seg::Seg(int seg_id, int seg_sid, int index, IoModel* iomodel,int nummodels)
-		:SegRef(nummodels),ElementHook(nummodels,index+1,2,iomodel){
+		:SegRef(nummodels),ElementHook(nummodels,index+1,NUMVERTICES,iomodel){
 
 			/*id: */
@@ -48,10 +38,8 @@
 			this->material = NULL;
 			this->matpar   = NULL;
-
 		}
 /*}}}*/
 /*FUNCTION Seg::~Seg(){{{*/
 Seg::~Seg(){
-	delete inputs;
 	this->parameters=NULL;
 }
@@ -63,55 +51,21 @@
 /*}}}*/
 
-/*FUNCTION Seg::Echo{{{*/
-void Seg::Echo(void){
-	_printf_("Seg:\n");
-	_printf_("   id: " << id << "\n");
-	if(nodes){
-		nodes[0]->Echo();
-		nodes[1]->Echo();
-	}
-	else _printf_("nodes = NULL\n");
-
-	if (material) material->Echo();
-	else _printf_("material = NULL\n");
-
-	if (matpar) matpar->Echo();
-	else _printf_("matpar = NULL\n");
-
-	_printf_("   parameters\n");
-	if (parameters) parameters->Echo();
-	else _printf_("parameters = NULL\n");
-
-	_printf_("   inputs\n");
-	if (inputs) inputs->Echo();
-	else _printf_("inputs=NULL\n");
-}
-/*}}}*/
-/*FUNCTION Seg::DeepEcho{{{*/
-void Seg::DeepEcho(void){
-
-	_printf_("Seg:\n");
-	_printf_("   id: " << id << "\n");
-	if(nodes){
-		nodes[0]->DeepEcho();
-		nodes[1]->DeepEcho();
-	}
-	else _printf_("nodes = NULL\n");
-
-	if (material) material->DeepEcho();
-	else _printf_("material = NULL\n");
-
-	if (matpar) matpar->DeepEcho();
-	else _printf_("matpar = NULL\n");
-
-	_printf_("   parameters\n");
-	if (parameters) parameters->DeepEcho();
-	else _printf_("parameters = NULL\n");
-
-	_printf_("   inputs\n");
-	if (inputs) inputs->DeepEcho();
-	else _printf_("inputs=NULL\n");
-
-	return;
+/*FUNCTION Seg::CharacteristicLength{{{*/
+IssmDouble Seg::CharacteristicLength(void){
+
+	IssmDouble xyz_list[NUMVERTICES][3];
+	IssmDouble x1,y1,x2,y2;
+
+	/*Get xyz list: */
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	x1=xyz_list[0][0]; y1=xyz_list[0][1];
+	x2=xyz_list[1][0]; y2=xyz_list[1][1];
+
+	return sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1));
+}
+/*}}}*/
+/*FUNCTION Seg::FiniteElement{{{*/
+int Seg::FiniteElement(void){
+	return this->element_type;
 }
 /*}}}*/
@@ -123,368 +77,144 @@
 }
 /*}}}*/
-/*FUNCTION Seg::Id {{{*/
-int    Seg::Id(){
-
-	return id;
-
-}
-/*}}}*/
-
-/*FUNCTION Seg::GetSize{{{*/
-IssmDouble Seg::GetSize(void){
-
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble x1,y1,x2,y2;
-
-	/*Get xyz list: */
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	x1=xyz_list[0][0]; y1=xyz_list[0][1];
-	x2=xyz_list[1][0]; y2=xyz_list[1][1];
-
-	return sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1));
-}
-/*}}}*/
-/*FUNCTION Seg::CreateKMatrixFreeSurfaceTop {{{*/
-ElementMatrix* Seg::CreateKMatrixFreeSurfaceTop(void){
-
-	/*Intermediaries */
-	int        stabilization;
-	IssmDouble Jdet,D_scalar,dt,h;
-	IssmDouble vx,vel;
-	IssmDouble xyz_list[NUMVERTICES][3];
-
-	/*Fetch number of nodes for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Initialize Element matrix and vectors*/
-	ElementMatrix* Ke     = new ElementMatrix(nodes,numnodes,this->parameters,NoneApproximationEnum);
-	IssmDouble*    basis  = xNew<IssmDouble>(numnodes);
-	IssmDouble*    B      = xNew<IssmDouble>(1*numnodes);
-	IssmDouble*    Bprime = xNew<IssmDouble>(1*numnodes);
+
+void  Seg::GetIcefrontCoordinates(IssmDouble** pxyz_front,IssmDouble* xyz_list,int levelsetenum){/*{{{*/
+	
+	/* Intermediaries */
+	int nrfrontnodes,index;
+	IssmDouble  levelset[NUMVERTICES];
+
+	/*Recover parameters and values*/
+	GetInputListOnVertices(&levelset[0],levelsetenum);
+	/* Get nodes where there is no ice */
+	nrfrontnodes=0;
+	for(int i=0;i<NUMVERTICES;i++){
+		if(levelset[i]>=0.){
+			index=i;
+			nrfrontnodes++;
+		}
+	}
+
+	_assert_(nrfrontnodes==1);
+
+	IssmDouble* xyz_front = xNew<IssmDouble>(3);
+
+	/* Return nodes */
+	for(int dir=0;dir<3;dir++){
+		xyz_front[dir]=xyz_list[3*index+dir];
+	}
+
+	*pxyz_front=xyz_front;
+}/*}}}*/
+/*FUNCTION Seg::GetNumberOfNodes;{{{*/
+int Seg::GetNumberOfNodes(void){
+	return this->NumberofNodes();
+}
+/*}}}*/
+/*FUNCTION Seg::GetNumberOfVertices;{{{*/
+int Seg::GetNumberOfVertices(void){
+	return NUMVERTICES;
+}
+/*}}}*/
+/*FUNCTION Seg::GetVerticesCoordinates(IssmDouble** pxyz_list){{{*/
+void Seg::GetVerticesCoordinates(IssmDouble** pxyz_list){
+
+	IssmDouble* xyz_list = xNew<IssmDouble>(NUMVERTICES*3);
+	::GetVerticesCoordinates(xyz_list,this->vertices,NUMVERTICES);
+
+	/*Assign output pointer*/
+	*pxyz_list = xyz_list;
+
+}/*}}}*/
+bool Seg::IsIcefront(void){/*{{{*/
+
+	bool isicefront;
+	int i,nrice;
+	IssmDouble ls[NUMVERTICES];
 
 	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);
-	this->parameters->FindParam(&stabilization,MasstransportStabilizationEnum);
-	Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);
-	h=this->GetSize();
-
-	/* Start  looping on the number of gaussian points: */
-	GaussSeg *gauss=new GaussSeg(2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		GetNodalFunctions(basis,gauss);
-
-		vx_input->GetInputValue(&vx,gauss);
-
-		D_scalar=gauss->weight*Jdet;
-
-		TripleMultiply(basis,1,numnodes,1,
-					&D_scalar,1,1,0,
-					basis,1,numnodes,0,
-					&Ke->values[0],1);
-
-		GetNodalFunctions(B,gauss);
-		GetBprimeMasstransport(Bprime,&xyz_list[0][0],gauss);
-
-		D_scalar=dt*gauss->weight*Jdet*vx;
-		TripleMultiply(B,1,numnodes,1,
-					&D_scalar,1,1,0,
-					Bprime,1,numnodes,0,
-					&Ke->values[0],1);
-
-		if(stabilization==2){
-			/*Streamline upwinding*/
-			vel=fabs(vx)+1.e-8;
-			D_scalar=dt*gauss->weight*Jdet*h/(2.*vel)*vx;
-		}
-		else if(stabilization==1){
-			/*SSA*/
-			vx_input->GetInputAverage(&vx);
-			D_scalar=dt*gauss->weight*Jdet*h/2.*fabs(vx);
-		}
-		if(stabilization==1 || stabilization==2){
-			TripleMultiply(Bprime,1,numnodes,1,
-						&D_scalar,1,1,0,
-						Bprime,1,numnodes,0,
-						&Ke->values[0],1);
-		}
-	}
-
-	/*Clean up and return*/
-	xDelete<IssmDouble>(basis);
-	xDelete<IssmDouble>(B);
-	xDelete<IssmDouble>(Bprime);
-	delete gauss;
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Seg::CreateKMatrixFreeSurfaceBase {{{*/
-ElementMatrix* Seg::CreateKMatrixFreeSurfaceBase(void){
-
-	/*Intermediaries */
-	int        stabilization;
-	IssmDouble Jdet,D_scalar,dt,h;
-	IssmDouble vx,vel;
-	IssmDouble xyz_list[NUMVERTICES][3];
-
-	/*Fetch number of nodes for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Initialize Element matrix and vectors*/
-	ElementMatrix* Ke     = new ElementMatrix(nodes,numnodes,this->parameters,NoneApproximationEnum);
-	IssmDouble*    basis  = xNew<IssmDouble>(numnodes);
-	IssmDouble*    B      = xNew<IssmDouble>(1*numnodes);
-	IssmDouble*    Bprime = xNew<IssmDouble>(1*numnodes);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);
-	this->parameters->FindParam(&stabilization,MasstransportStabilizationEnum);
-	Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);
-	h=this->GetSize();
-
-	/* Start  looping on the number of gaussian points: */
-	GaussSeg *gauss=new GaussSeg(2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		GetNodalFunctions(basis,gauss);
-
-		vx_input->GetInputValue(&vx,gauss);
-
-		D_scalar=gauss->weight*Jdet;
-
-		TripleMultiply(basis,1,numnodes,1,
-					&D_scalar,1,1,0,
-					basis,1,numnodes,0,
-					&Ke->values[0],1);
-
-		GetNodalFunctions(B,gauss);
-		GetBprimeMasstransport(Bprime,&xyz_list[0][0],gauss);
-
-		D_scalar=dt*gauss->weight*Jdet*vx;
-		TripleMultiply(B,1,numnodes,1,
-					&D_scalar,1,1,0,
-					Bprime,1,numnodes,0,
-					&Ke->values[0],1);
-
-		if(stabilization==2){
-			/*Streamline upwinding*/
-			vel=fabs(vx)+1.e-8;
-			D_scalar=dt*gauss->weight*Jdet*h/(2.*vel)*vx;
-		}
-		else if(stabilization==1){
-			/*SSA*/
-			vx_input->GetInputAverage(&vx);
-			D_scalar=dt*gauss->weight*Jdet*h/2.*fabs(vx);
-		}
-		if(stabilization==1 || stabilization==2){
-			TripleMultiply(Bprime,1,numnodes,1,
-						&D_scalar,1,1,0,
-						Bprime,1,numnodes,0,
-						&Ke->values[0],1);
-		}
-	}
-
-	/*Clean up and return*/
-	xDelete<IssmDouble>(basis);
-	xDelete<IssmDouble>(B);
-	xDelete<IssmDouble>(Bprime);
-	delete gauss;
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Seg::CreateMassMatrix {{{*/
-ElementMatrix* Seg::CreateMassMatrix(void){
-
-	/* Intermediaries */
-	IssmDouble  D,Jdet;
-	IssmDouble  xyz_list[NUMVERTICES][3];
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Initialize Element matrix and vectors*/
-	ElementMatrix* Ke    = new ElementMatrix(nodes,numnodes,this->parameters,NoneApproximationEnum);
-	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-
-	/* Start looping on the number of gaussian points: */
-	GaussSeg* gauss=new GaussSeg(2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetNodalFunctions(basis,gauss);
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		D=gauss->weight*Jdet;
-
-		TripleMultiply(basis,1,numnodes,1,
-					&D,1,1,0,
-					basis,1,numnodes,0,
-					&Ke->values[0],1);
-	}
-
-	/*Clean up and return*/
-	delete gauss;
-	xDelete<IssmDouble>(basis);
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Seg::CreatePVectorL2Projection {{{*/
-ElementVector* Seg::CreatePVectorL2Projection(void){
-
-	/*Intermediaries */
-	int        i,input_enum;
-	IssmDouble Jdet;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble value;
-	Input*     input2 = NULL;
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Initialize Element vector*/
-	ElementVector* pe    = new ElementVector(nodes,numnodes,this->parameters);
-	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	this->parameters->FindParam(&input_enum,InputToL2ProjectEnum);
-	Input* input = inputs->GetInput(input_enum);
-	if(!input){
-		switch(input_enum){
-			case SurfaceSlopeXEnum: input2 = inputs->GetInput(SurfaceEnum); _assert_(input2); break;
-			case BedSlopeXEnum:     input2 = inputs->GetInput(BedEnum);     _assert_(input2); break;
-			default: _error_("input not found in element");
-		}
-	}
-
-	/* Start  looping on the number of gaussian points: */
-	GaussSeg* gauss=new GaussSeg(2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		GetNodalFunctions(basis,gauss);
-
-		if(input){
-			input->GetInputValue(&value,gauss);
-		}
-		else{
-			input2->GetInputDerivativeValue(&value,&xyz_list[0][0],gauss);
-		}
-
-		for(i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*value*basis[i];
-	}
-
-	/*Clean up and return*/
-	xDelete<IssmDouble>(basis);
-	delete gauss;
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Seg::CreatePVectorFreeSurfaceTop {{{*/
-ElementVector* Seg::CreatePVectorFreeSurfaceTop(void){
-
-	/*Intermediaries */
-	IssmDouble Jdet,dt;
-	IssmDouble ms,surface,vy;
-	IssmDouble xyz_list[NUMVERTICES][3];
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Initialize Element vector and other vectors*/
-	ElementVector* pe    = new ElementVector(nodes,numnodes,this->parameters);
-	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);
-	Input* vy_input     = inputs->GetInput(VyEnum);                         _assert_(vy_input);
-	Input* ms_input     = inputs->GetInput(SurfaceforcingsMassBalanceEnum); _assert_(ms_input);
-	Input* surface_input= inputs->GetInput(SurfaceEnum);                    _assert_(surface_input);
-
-	/*Initialize mb_correction to 0, do not forget!:*/
-	/* Start  looping on the number of gaussian points: */
-	GaussSeg* gauss=new GaussSeg(2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		GetNodalFunctions(basis,gauss);
-
-		vy_input->GetInputValue(&vy,gauss);
-		ms_input->GetInputValue(&ms,gauss);
-		surface_input->GetInputValue(&surface,gauss);
-
-		for(int i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*(surface + dt*ms + dt*vy)*basis[i];
-	}
-
-	/*Clean up and return*/
-	xDelete<IssmDouble>(basis);
-	delete gauss;
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Seg::CreatePVectorFreeSurfaceBase {{{*/
-ElementVector* Seg::CreatePVectorFreeSurfaceBase(void){
-
-	/*Intermediaries */
-	IssmDouble Jdet,dt;
-	IssmDouble mb,mb_correction,bed,vy;
-	IssmDouble xyz_list[NUMVERTICES][3];
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Initialize Element vector and other vectors*/
-	ElementVector* pe    = new ElementVector(nodes,numnodes,this->parameters);
-	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);
-	Input* vy_input            = inputs->GetInput(VyEnum);                         _assert_(vy_input);
-	Input* mb_input            = inputs->GetInput(BasalforcingsMeltingRateEnum);   _assert_(mb_input);
-	Input* mb_correction_input = inputs->GetInput(BasalforcingsMeltingRateCorrectionEnum);
-	Input* bed_input           = inputs->GetInput(BedEnum);                        _assert_(bed_input);
-
-	/*Initialize mb_correction to 0, do not forget!:*/
-	/* Start  looping on the number of gaussian points: */
-	GaussSeg* gauss=new GaussSeg(2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		GetNodalFunctions(basis,gauss);
-
-		vy_input->GetInputValue(&vy,gauss);
-		mb_input->GetInputValue(&mb,gauss);
-		bed_input->GetInputValue(&bed,gauss);
-		if(mb_correction_input)
-		 mb_correction_input->GetInputValue(&mb_correction,gauss);
-		else
-		 mb_correction=0.;
-
-		for(int i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*(bed+dt*(mb-mb_correction) + dt*vy)*basis[i];
-	}
-
-	/*Clean up and return*/
-	xDelete<IssmDouble>(basis);
-	delete gauss;
-	return pe;
-}
-/*}}}*/
+	GetInputListOnVertices(&ls[0],MaskIceLevelsetEnum);
+
+	/* If only one vertex has ice, there is an ice front here */
+	isicefront=false;
+	if(IsIceInElement()){
+		nrice=0;       
+		for(i=0;i<NUMVERTICES;i++)
+		 if(ls[i]<0.) nrice++;
+		if(nrice==1) isicefront= true;
+	}
+	return isicefront;
+}/*}}}*/
+/*FUNCTION Seg::JacobianDeterminant{{{*/
+void Seg::JacobianDeterminant(IssmDouble* pJdet,IssmDouble* xyz_list,Gauss* gauss){
+
+	_assert_(gauss->Enum()==GaussSegEnum);
+	this->GetJacobianDeterminant(pJdet,xyz_list,(GaussSeg*)gauss);
+
+}
+/*}}}*/
+/*FUNCTION Seg::JacobianDeterminantSurface{{{*/
+void Seg::JacobianDeterminantSurface(IssmDouble* pJdet,IssmDouble* xyz_list,Gauss* gauss){
+
+	*pJdet = 1.;
+
+}
+/*}}}*/
+/*FUNCTION Seg::NewGauss(){{{*/
+Gauss* Seg::NewGauss(void){
+	return new GaussSeg();
+}
+/*}}}*/
+/*FUNCTION Seg::NewGauss(int order){{{*/
+Gauss* Seg::NewGauss(int order){
+	return new GaussSeg(order);
+}
+/*}}}*/
+/*FUNCTION Seg::NewGauss(IssmDouble* xyz_list, IssmDouble* xyz_list_front,int order){{{*/
+Gauss* Seg::NewGauss(IssmDouble* xyz_list, IssmDouble* xyz_list_front,int order){
+
+	/*Output*/
+	Gauss* gauss = NULL;
+
+	if(xyz_list_front[0] == xyz_list[0]){
+		gauss = new GaussSeg(-1.);
+	}
+	else if(xyz_list_front[0] == xyz_list[3*1+0]){
+		gauss = new GaussSeg(+1.);
+	}
+	else{
+		_error_("front is not located on element edge");
+	}
+
+	return gauss;
+}
+/*}}}*/
+/*FUNCTION Seg::NodalFunctions{{{*/
+void Seg::NodalFunctions(IssmDouble* basis, Gauss* gauss){
+
+	_assert_(gauss->Enum()==GaussSegEnum);
+	this->GetNodalFunctions(basis,(GaussSeg*)gauss);
+
+}
+/*}}}*/
+/*FUNCTION Seg::NodalFunctionsDerivatives{{{*/
+void Seg::NodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss){
+
+	_assert_(gauss->Enum()==GaussSegEnum);
+	this->GetNodalFunctionsDerivatives(dbasis,xyz_list,(GaussSeg*)gauss);
+
+}
+/*}}}*/
+/*FUNCTION Seg::NormalSection{{{*/
+void Seg::NormalSection(IssmDouble* normal,IssmDouble* xyz_list_front){
+
+	IssmDouble* xyz_list = xNew<IssmDouble>(NUMVERTICES*3);
+	::GetVerticesCoordinates(xyz_list,this->vertices,NUMVERTICES);
+
+	if(xyz_list_front[0]>xyz_list[0])
+	 normal[0]= + 1.;
+	else
+	 normal[0]= - 1.;
+
+	xDelete<IssmDouble>(xyz_list);
+}
+/*}}}*/
Index: /issm/trunk/src/c/classes/Elements/Seg.h
===================================================================
--- /issm/trunk/src/c/classes/Elements/Seg.h	(revision 17805)
+++ /issm/trunk/src/c/classes/Elements/Seg.h	(revision 17806)
@@ -30,29 +30,16 @@
 	public:
 
-		int          id;
-		int          sid;
-
-		Node       **nodes;                       // nodes
-		Vertex     **vertices;                    // 3 vertices
-		Material    *material;                    // 1 material ice
-		Matpar      *matpar;                      // 1 material parameter
-
-		Parameters  *parameters;                  //pointer to solution parameters
-		Inputs      *inputs;
-
 		/*Seg constructors, destructors {{{*/
-		Seg();
+		Seg(){};
 		Seg(int seg_id,int seg_sid,int i, IoModel* iomodel,int nummodels);
 		~Seg();
 		/*}}}*/
 		/*Object virtual functions definitions:{{{ */
-		void    Echo();
-		void    DeepEcho();
-		int     Id();
 		int     ObjectEnum();
 		Object *copy();
 		/*}}}*/
 		/*Update virtual functions resolution: {{{*/
-		void  InputUpdateFromSolution(IssmDouble* solutiong){_error_("not implemented yet");};
+		void  InputUpdateFromSolutionOneDofCollapsed(IssmDouble* solution,int inputenum){_error_("not implemented yet");};
+		void  InputUpdateFromSolutionOneDof(IssmDouble* solution,int inputenum){_error_("not implemented yet");};
 		void  InputUpdateFromVector(IssmDouble* vector, int name, int type){_error_("not implemented yet");};
 #ifdef _HAVE_DAKOTA_
@@ -60,50 +47,88 @@
 		void  InputUpdateFromMatrixDakota(IssmDouble* matrix, int nows, int ncols, int name, int type){_error_("not implemented yet");};
 #endif
-		void  InputUpdateFromConstant(IssmDouble constant, int name){_error_("not implemented yet");};
-		void  InputUpdateFromConstant(int constant, int name){_error_("not implemented yet");};
-		void  InputUpdateFromConstant(bool constant, int name){_error_("not implemented yet");};
 		void  InputUpdateFromIoModel(int index, IoModel* iomodel){_error_("not implemented yet");};
 		/*}}}*/
 		/*Element virtual functions definitions: {{{*/
+		void        AddBasalInput(int input_enum, IssmDouble* values, int interpolation_enum){_error_("not implemented yet");};
+		void        AddInput(int input_enum, IssmDouble* values, int interpolation_enum){_error_("not implemented yet");};
+		IssmDouble  CharacteristicLength(void);
 		void        ComputeBasalStress(Vector<IssmDouble>* sigma_b){_error_("not implemented yet");};
+		void        ComputeSigmaNN(){_error_("not implemented yet");};
 		void        ComputeStrainRate(Vector<IssmDouble>* eps){_error_("not implemented yet");};
 		void        ComputeStressTensor(){_error_("not implemented yet");};
+		void        ComputeDeviatoricStressTensor(){_error_("not implemented yet");};
 		void        Configure(Elements* elements,Loads* loads,Nodes* nodesin,Vertices* verticesin,Materials* materials,Parameters* parameters){_error_("not implemented yet");};
 		void        SetCurrentConfiguration(Elements* elements,Loads* loads,Nodes* nodes,Materials* materials,Parameters* parameters){_error_("not implemented yet");};
-		void        SetwiseNodeConnectivity(int* d_nz,int* o_nz,Node* node,bool* flags,int* flagsindices,int set1_enum,int set2_enum){_error_("not implemented yet");};
-		void        CreateKMatrix(Matrix<IssmDouble>* Kff, Matrix<IssmDouble>* Kfs){_error_("not implemented yet");};
-		void        CreateDVector(Vector<IssmDouble>* df){_error_("not implemented yet");};
-		void        CreatePVector(Vector<IssmDouble>* pf){_error_("not implemented yet");};
-		ElementVector* CreatePVectorL2Projection(void);
-		void        CreateJacobianMatrix(Matrix<IssmDouble>* Jff){_error_("not implemented yet");};
 		void        Delta18oParameterization(void){_error_("not implemented yet");};
+		void        ElementSizes(IssmDouble* hx,IssmDouble* hy,IssmDouble* hz){_error_("not implemented yet");};
+		void        FSContactMigration(Vector<IssmDouble>* vertexgrounded,Vector<IssmDouble>* vertexfloating){_error_("not implemented yet");};
+		int         FiniteElement(void);
+		Element*    GetUpperElement(void){_error_("not implemented yet");};
+	  	Element*    GetLowerElement(void){_error_("not implemented yet");};
+	  	Element*    GetSurfaceElement(void){_error_("not implemented yet");};
+		Element*    GetBasalElement(void){_error_("not implemented yet");};
 		int         GetNodeIndex(Node* node){_error_("not implemented yet");};
-		void        GetNodesSidList(int* sidlist){_error_("not implemented yet");};
-		void        GetNodesLidList(int* lidlist){_error_("not implemented yet");};
-		int         GetNumberOfNodes(void){_error_("not implemented yet");};
-		int         Sid(){_error_("not implemented yet");};
-		bool        IsOnBed(){_error_("not implemented yet");};
-		bool        IsFloating(){_error_("not implemented yet");};
+		int         GetNumberOfNodes(void);
+		int         GetNumberOfVertices(void);
+		void        GetVerticesCoordinates(IssmDouble** pxyz_list);
+		void        GetVerticesCoordinatesBase(IssmDouble** pxyz_list){_error_("not implemented yet");};
+		void        GetVerticesCoordinatesTop(IssmDouble** pxyz_list){_error_("not implemented yet");};
+		bool        IsOnBase(){_error_("not implemented yet");};
+		bool        IsOnSurface(){_error_("not implemented yet");};
 		bool        IsNodeOnShelfFromFlags(IssmDouble* flags){_error_("not implemented yet");};
-		bool        NoIceInElement(){_error_("not implemented yet");};
-		void           GetInputListOnVertices(IssmDouble* pvalue,int enumtype){_error_("not implemented yet");};
-		void           GetInputListOnVertices(IssmDouble* pvalue,int enumtype,IssmDouble defaultvalue){_error_("not implemented yet");};
-		void           GetInputValue(IssmDouble* pvalue,Node* node,int enumtype){_error_("not implemented yet");};
-		void           GetMaterialInputValue(IssmDouble* pvalue,Node* node,int enumtype){_error_("not implemented yet");};
-		#ifdef _HAVE_THERMAL_
-		void UpdateBasalConstraintsEnthalpy(void){_error_("not implemented yet");};
-		void ComputeBasalMeltingrate(void){_error_("not implemented yet");};
-		void DrainWaterfraction(void){_error_("not implemented yet");};
-		#endif
-		#ifdef _HAVE_HYDROLOGY_
-		void    GetHydrologyDCInefficientHmax(IssmDouble* ph_max, Node* innode){_error_("not implemented yet");};
-		void    GetHydrologyTransfer(Vector<IssmDouble>* transfer){_error_("not implemented yet");};
-		void    HydrologyEPLGetActive(Vector<IssmDouble>* active_vec){_error_("not implemented yet");};
-		void    HydrologyEPLGetMask(Vector<IssmDouble>* vec_mask){_error_("not implemented yet");};
-		#endif
-		void        GetSolutionFromInputs(Vector<IssmDouble>* solution){_error_("not implemented yet");};
-		void        GetVectorFromInputs(Vector<IssmDouble>* vector, int name_enum){_error_("not implemented yet");};
-		void        InputCreate(IssmDouble* vector,IoModel* iomodel,int M,int N,int vector_type,int vector_enum,int code){_error_("not implemented yet");};
-		void        InputDepthAverageAtBase(int enum_type,int average_enum_type,int object_enum=MeshElementsEnum){_error_("not implemented yet");};
+		void        JacobianDeterminant(IssmDouble*  Jdet, IssmDouble* xyz_list,Gauss* gauss);
+		void        JacobianDeterminantLine(IssmDouble* Jdet, IssmDouble* xyz_list,Gauss* gauss){_error_("not implemented yet");};
+		void        JacobianDeterminantSurface(IssmDouble*  pJdet, IssmDouble* xyz_list,Gauss* gauss);
+		void        JacobianDeterminantBase(IssmDouble* pJdet,IssmDouble* xyz_list_base,Gauss* gauss){_error_("not implemented yet");};
+		void        JacobianDeterminantTop(IssmDouble* pJdet,IssmDouble* xyz_list_base,Gauss* gauss){_error_("not implemented yet");};
+		IssmDouble  MinEdgeLength(IssmDouble* xyz_list){_error_("not implemented yet");};
+		void        NodalFunctions(IssmDouble* basis,Gauss* gauss);
+		void        NodalFunctionsP1(IssmDouble* basis,Gauss* gauss){_error_("not implemented yet");};
+		void        NodalFunctionsVelocity(IssmDouble* basis,Gauss* gauss){_error_("not implemented yet");};
+		void        NodalFunctionsPressure(IssmDouble* basis,Gauss* gauss){_error_("not implemented yet");};
+		void        NodalFunctionsTensor(IssmDouble* basis,Gauss* gauss){_error_("not implemented yet");};
+		void        NodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss);
+		void        NodalFunctionsP1Derivatives(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss){_error_("not implemented yet");};
+		void        NodalFunctionsMINIDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss){_error_("not implemented yet");};
+		void        NodalFunctionsDerivativesVelocity(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss){_error_("not implemented yet");};
+		void        NormalSection(IssmDouble* normal,IssmDouble* xyz_list);
+		void        NormalTop(IssmDouble* normal,IssmDouble* xyz_list){_error_("not implemented yet");};
+		void        NormalBase(IssmDouble* normal,IssmDouble* xyz_list){_error_("not implemented yet");};
+		int         NumberofNodesVelocity(void){_error_("not implemented yet");};
+		int         NumberofNodesPressure(void){_error_("not implemented yet");};
+	   Element*    SpawnBasalElement(void){_error_("not implemented yet");};
+		Element*    SpawnTopElement(void){_error_("not implemented yet");};
+		IssmDouble  StabilizationParameter(IssmDouble u, IssmDouble v, IssmDouble w, IssmDouble diameter, IssmDouble kappa){_error_("not implemented yet");};
+		int         PressureInterpolation(void){_error_("not implemented yet");};
+		void        ValueP1OnGauss(IssmDouble* pvalue,IssmDouble* values,Gauss* gauss){_error_("not implemented yet");};
+		void        ValueP1DerivativesOnGauss(IssmDouble* dvalue,IssmDouble* values,IssmDouble* xyz_list,Gauss* gauss){_error_("not implemented yet");};
+		int         VelocityInterpolation(void){_error_("not implemented yet");};
+		void        GetGroundedPart(int* point1,IssmDouble* fraction1, IssmDouble* fraction2,bool* mainlyfloating){_error_("not implemented yet");};
+		IssmDouble  GetGroundedPortion(IssmDouble* xyz_list){_error_("not implemented yet");};
+		void        GetInputValue(IssmDouble* pvalue,Node* node,int enumtype){_error_("not implemented yet");};
+		Node*       GetNode(int node_number){_error_("Not implemented");};
+		IssmDouble  GetXcoord(Gauss* gauss){_error_("Not implemented");};
+		IssmDouble  GetYcoord(Gauss* gauss){_error_("Not implemented");};
+		IssmDouble  GetZcoord(Gauss* gauss){_error_("not implemented yet");};
+		int         GetElementType(void){_error_("not implemented yet");};
+		Gauss*      NewGauss(void);
+		Gauss*      NewGauss(int order);
+      Gauss*      NewGauss(IssmDouble* xyz_list, IssmDouble* xyz_list_front,int order);
+      Gauss*      NewGauss(IssmDouble* xyz_list, IssmDouble* xyz_list_front,int order_horiz,int order_vert){_error_("not implemented yet");};
+      Gauss*      NewGauss(int point1,IssmDouble fraction1,IssmDouble fraction2,bool mainlyfloating,int order){_error_("not implemented yet");};
+		Gauss*      NewGaussBase(int order){_error_("not implemented yet");};
+		Gauss*      NewGaussLine(int vertex1,int vertex2,int order){_error_("not implemented yet");};
+		Gauss*      NewGaussTop(int order){_error_("not implemented yet");};
+		int         VertexConnectivity(int vertexindex){_error_("not implemented yet");};
+		void        VerticalSegmentIndices(int** pindices,int* pnumseg){_error_("not implemented yet");};
+		void        ViscousHeating(IssmDouble* pphi,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input){_error_("not implemented yet");};
+		bool        IsZeroLevelset(int levelset_enum){_error_("not implemented");};
+		bool		   IsIcefront(void);
+		void        ZeroLevelsetCoordinates(IssmDouble** pxyz_zero,IssmDouble* xyz_list,int levelsetenum){_error_("not implemented");};
+		void		   GetIcefrontCoordinates(IssmDouble** pxyz_front,IssmDouble* xyz_list,int levelsetenum);
+		void        GetNormalFromLSF(IssmDouble *pnormal){_error_("not implemented yet");};
+
+		void        GetSolutionFromInputsOneDof(Vector<IssmDouble>* solution,int enum_type){_error_("not implemented yet");};
+		void        InputDepthAverageAtBase(int enum_type,int average_enum_type){_error_("not implemented yet");};
 		void        InputDuplicate(int original_enum,int new_enum){_error_("not implemented yet");};
 		void        InputScale(int enum_type,IssmDouble scale_factor){_error_("not implemented yet");};
@@ -111,7 +136,7 @@
 		int         NodalValue(IssmDouble* pvalue, int index, int natureofdataenum){_error_("not implemented yet");};
 		void        PositiveDegreeDay(IssmDouble* pdds,IssmDouble* pds,IssmDouble signorm){_error_("not implemented yet");};
-		void        ResultInterpolation(int* pinterpolation,int output_enum){_error_("not implemented");};
-		void        ResultToVector(Vector<IssmPDouble>* vector,int output_enum){_error_("not implemented");};
-		void        ResetCoordinateSystem(void){_error_("not implemented yet");};
+		void        ResetFSBasalBoundaryCondition(void){_error_("not implemented yet");};
+		void        ReduceMatrices(ElementMatrix* Ke,ElementVector* pe){_error_("not implemented yet");};
+		void        SetTemporaryElementType(int element_type_in){_error_("not implemented yet");};
 		void	      SmbGradients(){_error_("not implemented yet");};
 		IssmDouble  SurfaceArea(void){_error_("not implemented yet");};
@@ -121,5 +146,4 @@
 		void UpdateConstraintsExtrudeFromTop(){_error_("not implemented");};
 
-#ifdef _HAVE_RESPONSES_
 		void       AverageOntoPartition(Vector<IssmDouble>* partition_contributions,Vector<IssmDouble>* partition_areas,IssmDouble* vertex_response,IssmDouble* qmu_part){_error_("not implemented yet");};
 		IssmDouble IceVolume(void){_error_("not implemented yet");};
@@ -140,5 +164,6 @@
 		void       MaxVy(IssmDouble* pmaxvy){_error_("not implemented yet");};
 		void       MaxVz(IssmDouble* pmaxvz){_error_("not implemented yet");};
-#endif
+		IssmDouble Misfit(int modelenum,int observationenum,int weightsenum){_error_("not implemented yet");};
+		IssmDouble MisfitArea(int weightsenum){_error_("not implemented yet");};
 
 #ifdef _HAVE_GIA_
@@ -146,5 +171,4 @@
 #endif
 
-#ifdef _HAVE_CONTROL_
 		IssmDouble DragCoefficientAbsGradient(void){_error_("not implemented yet");};
 		void       GradientIndexing(int* indexing,int control_index){_error_("not implemented yet");};
@@ -179,19 +203,9 @@
 		IssmDouble SurfaceAverageVelMisfit(void){_error_("not implemented yet");};
 		void       InputControlUpdate(IssmDouble scalar,bool save_parameter){_error_("not implemented yet");};
-#endif
-
-#ifdef _HAVE_GROUNDINGLINE_
+
 		void   PotentialUngrounding(Vector<IssmDouble>* potential_sheet_ungrounding){_error_("not implemented yet");};
 		void   MigrateGroundingLine(IssmDouble* sheet_ungrounding){_error_("not implemented yet");};
 		int    UpdatePotentialUngrounding(IssmDouble* vertices_potentially_ungrounding,Vector<IssmDouble>* vec_nodes_on_iceshelf,IssmDouble* nodes_on_iceshelf){_error_("not implemented yet");};
-#endif
-		/*}}}*/
-		/*Seg specific routines:*/
-		ElementMatrix* CreateMassMatrix(void);
-		ElementMatrix* CreateKMatrixFreeSurfaceTop(void);
-		ElementMatrix* CreateKMatrixFreeSurfaceBase(void);
-		ElementVector* CreatePVectorFreeSurfaceTop(void);
-		ElementVector* CreatePVectorFreeSurfaceBase(void);
-		IssmDouble     GetSize(void);
+		/*}}}*/
 };
 #endif  /* _SEG_H */
Index: /issm/trunk/src/c/classes/Elements/SegRef.cpp
===================================================================
--- /issm/trunk/src/c/classes/Elements/SegRef.cpp	(revision 17805)
+++ /issm/trunk/src/c/classes/Elements/SegRef.cpp	(revision 17806)
@@ -16,4 +16,5 @@
 
 /*Element macros*/
+#define NUMNODESP0  1
 #define NUMNODESP1  2
 
@@ -91,7 +92,15 @@
 
 	switch(element_type){
+		case P0Enum:
+			basis[0]=1.;
+			return;
 		case P1Enum: case P1DGEnum:
 			basis[0]=(1.-gauss->coord1)/2.;
 			basis[1]=(1.+gauss->coord1)/2.;
+			return;
+		case P2Enum:
+			basis[0]=(gauss->coord1-1.)*gauss->coord1/2.;
+			basis[1]=gauss->coord1*(1.+gauss->coord1)/2.;
+			basis[2]=(1.-gauss->coord1)*(1.+gauss->coord1);
 			return;
 		default:
@@ -153,4 +162,8 @@
 
 	switch(finiteelement){
+		case P0Enum:
+			/*Nodal function 1*/
+			dbasis[0] = 0.;
+			break;
 		case P1Enum: case P1DGEnum:
 			/*Nodal function 1*/
@@ -158,4 +171,10 @@
 			/*Nodal function 2*/
 			dbasis[1] = 0.5;
+			return;
+		case P2Enum:
+			/*Nodal function 1*/
+			dbasis[0] = (gauss->coord1-1.)/2. + gauss->coord1/2.;
+			dbasis[1] = (1.+gauss->coord1)/2. + gauss->coord1/2.;
+			dbasis[2] = -2.*gauss->coord1;
 			return;
 		default:
@@ -227,11 +246,7 @@
 
 	IssmDouble x1=xyz_list[3*0+0];
-	IssmDouble y1=xyz_list[3*0+1];
-	IssmDouble z1=xyz_list[3*0+2];
 	IssmDouble x2=xyz_list[3*1+0];
-	IssmDouble y2=xyz_list[3*1+1];
-	IssmDouble z2=xyz_list[3*1+2];
-
-	*J=.5*sqrt(pow(x2-x1,2) + pow(y2-y1,2) + pow(z2-z1,2));
+
+	*J=.5*fabs(x2-x1);
 }
 /*}}}*/
@@ -270,4 +285,5 @@
 
 	switch(finiteelement){
+		case P0Enum:                return NUMNODESP0;
 		case P1Enum:                return NUMNODESP1;
 		case P1DGEnum:              return NUMNODESP1;
Index: /issm/trunk/src/c/classes/Elements/Tetra.cpp
===================================================================
--- /issm/trunk/src/c/classes/Elements/Tetra.cpp	(revision 17806)
+++ /issm/trunk/src/c/classes/Elements/Tetra.cpp	(revision 17806)
@@ -0,0 +1,999 @@
+/*!\file Tetra.cpp
+ * \brief: implementation of the Tetrament object
+ */
+/*Headers:*/
+/*{{{*/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#else
+#error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include "../classes.h"
+#include "../../shared/shared.h"
+/*}}}*/
+
+/*Element macros*/
+#define NUMVERTICES 4
+
+/*Constructors/destructor/copy*/
+/*FUNCTION Tetra::Tetra(int id, int sid,int index, IoModel* iomodel,int nummodels){{{*/
+Tetra::Tetra(int seg_id, int seg_sid, int index, IoModel* iomodel,int nummodels)
+		:TetraRef(nummodels),ElementHook(nummodels,index+1,NUMVERTICES,iomodel){
+
+			/*id: */
+			this->id  = seg_id;
+			this->sid = seg_sid;
+
+			//this->parameters: we still can't point to it, it may not even exist. Configure will handle this.
+			this->parameters = NULL;
+
+			/*intialize inputs: */
+			this->inputs  = new Inputs();
+
+			/*initialize pointers:*/
+			this->nodes    = NULL;
+			this->vertices = NULL;
+			this->material = NULL;
+			this->matpar   = NULL;
+		}
+/*}}}*/
+/*FUNCTION Tetra::~Tetra(){{{*/
+Tetra::~Tetra(){
+	this->parameters=NULL;
+}
+/*}}}*/
+/*FUNCTION Tetra::copy {{{*/
+Object* Tetra::copy() {
+	_error_("not implemented yet");
+}
+/*}}}*/
+
+/*FUNCTION Tetra::FiniteElement{{{*/
+int Tetra::FiniteElement(void){
+	return this->element_type;
+} /*}}}*/
+/*FUNCTION Tetra::ObjectEnum{{{*/
+int Tetra::ObjectEnum(void){
+
+	return TetraEnum;
+
+}/*}}}*/
+
+/*FUNCTION Tetra::AddInput{{{*/
+void  Tetra::AddInput(int input_enum,IssmDouble* values, int interpolation_enum){
+
+	/*Call inputs method*/
+	_assert_(this->inputs);
+	this->inputs->AddInput(new TetraInput(input_enum,values,interpolation_enum));
+}
+/*}}}*/
+/*FUNCTION Tetra::Configure {{{*/
+void  Tetra::Configure(Elements* elementsin, Loads* loadsin, Nodes* nodesin,Vertices* verticesin, Materials* materialsin, Parameters* parametersin){
+
+	int analysis_counter;
+
+	/*go into parameters and get the analysis_counter: */
+	parametersin->FindParam(&analysis_counter,AnalysisCounterEnum);
+
+	/*Get Element type*/
+	this->element_type=this->element_type_list[analysis_counter];
+
+	/*Take care of hooking up all objects for this element, ie links the objects in the hooks to their respective 
+	 * datasets, using internal ids and offsets hidden in hooks: */
+	if (this->hnodes[analysis_counter]) this->hnodes[analysis_counter]->configure(nodesin);
+	this->hvertices->configure(verticesin);
+	this->hmaterial->configure(materialsin);
+	this->hmatpar->configure(materialsin);
+
+	/*Now, go pick up the objects inside the hooks: */
+	if (this->hnodes[analysis_counter]) this->nodes=(Node**)this->hnodes[analysis_counter]->deliverp();
+	else this->nodes=NULL;
+	this->vertices          = (Vertex**)this->hvertices->deliverp();
+	this->material          = (Material*)this->hmaterial->delivers();
+	this->matpar            = (Matpar*)this->hmatpar->delivers();
+
+	/*point parameters to real dataset: */
+	this->parameters=parametersin;
+
+	/*get inputs configured too: */
+	this->inputs->Configure(parameters);
+}
+/*}}}*/
+/*FUNCTION Tetra::FaceOnBaseIndices{{{*/
+void Tetra::FaceOnBaseIndices(int* pindex1,int* pindex2,int* pindex3){
+
+	IssmDouble values[NUMVERTICES];
+	int        indices[4][3] = {{0,1,2},{0,3,1},{1,3,2},{0,2,3}};
+
+	/*Retrieve all inputs and parameters*/
+	GetInputListOnVertices(&values[0],MeshVertexonbaseEnum);
+
+	for(int i=0;i<4;i++){
+		if(values[indices[i][0]] == 1. && values[indices[i][1]] == 1. && values[indices[i][2]] == 1.){
+			*pindex1 = indices[i][0];
+			*pindex2 = indices[i][1];
+			*pindex3 = indices[i][2];
+			return;
+		}
+	}
+
+	_error_("Could not find 3 vertices on bed");
+}
+/*}}}*/
+/*FUNCTION Tetra::FaceOnSurfaceIndices{{{*/
+void Tetra::FaceOnSurfaceIndices(int* pindex1,int* pindex2,int* pindex3){
+
+	IssmDouble values[NUMVERTICES];
+	int        indices[4][3] = {{0,1,2},{0,3,1},{1,3,2},{0,2,3}};
+
+	/*Retrieve all inputs and parameters*/
+	GetInputListOnVertices(&values[0],MeshVertexonsurfaceEnum);
+
+	for(int i=0;i<4;i++){
+		if(values[indices[i][0]] == 1. && values[indices[i][1]] == 1. && values[indices[i][2]] == 1.){
+			*pindex1 = indices[i][0];
+			*pindex2 = indices[i][1];
+			*pindex3 = indices[i][2];
+			return;
+		}
+	}
+
+	_error_("Could not find 3 vertices on bed");
+}
+/*}}}*/
+/*FUNCTION Tetra::FaceOnFrontIndices{{{*/
+void Tetra::FaceOnFrontIndices(int* pindex1,int* pindex2,int* pindex3){
+
+	IssmDouble values[NUMVERTICES];
+	int        indices[4][3] = {{0,1,2},{0,3,1},{1,3,2},{0,2,3}};
+
+	/*Retrieve all inputs and parameters*/
+	GetInputListOnVertices(&values[0],MaskIceLevelsetEnum);
+
+	for(int i=0;i<4;i++){
+		if(values[indices[i][0]] == 0. && values[indices[i][1]] == 0. && values[indices[i][2]] == 0.){
+			*pindex1 = indices[i][0];
+			*pindex2 = indices[i][1];
+			*pindex3 = indices[i][2];
+			return;
+		}
+	}
+
+	_error_("Could not find 3 vertices on bed");
+}
+/*}}}*/
+/*FUNCTION Tetra::GetElementType {{{*/
+int Tetra::GetElementType(){
+
+	/*return TetraRef field*/
+	return this->element_type;
+}
+/*}}}*/
+/*FUNCTION Tetra::GetNumberOfNodes;{{{*/
+int Tetra::GetNumberOfNodes(void){
+	return this->NumberofNodes();
+}
+/*}}}*/
+/*FUNCTION Tetra::GetNumberOfVertices;{{{*/
+int Tetra::GetNumberOfVertices(void){
+	return NUMVERTICES;
+}
+/*}}}*/
+/*FUNCTION Tetra::GetVerticesCoordinatesBase(IssmDouble** pxyz_list){{{*/
+void Tetra::GetVerticesCoordinatesBase(IssmDouble** pxyz_list){
+
+	int        indices[3];
+	IssmDouble xyz_list[NUMVERTICES][3];
+
+	/*Element XYZ list*/
+	::GetVerticesCoordinates(&xyz_list[0][0],this->vertices,NUMVERTICES);
+
+	/*Allocate Output*/
+	IssmDouble* xyz_list_edge = xNew<IssmDouble>(3*3);
+	this->FaceOnBaseIndices(&indices[0],&indices[1],&indices[2]);
+	for(int i=0;i<3;i++) for(int j=0;j<3;j++) xyz_list_edge[i*3+j]=xyz_list[indices[i]][j];
+
+	/*Assign output pointer*/
+	*pxyz_list = xyz_list_edge;
+
+}/*}}}*/
+/*FUNCTION Tetra::GetVerticesCoordinatesTop(IssmDouble** pxyz_list){{{*/
+void Tetra::GetVerticesCoordinatesTop(IssmDouble** pxyz_list){
+
+	int        indices[3];
+	IssmDouble xyz_list[NUMVERTICES][3];
+
+	/*Element XYZ list*/
+	::GetVerticesCoordinates(&xyz_list[0][0],this->vertices,NUMVERTICES);
+
+	/*Allocate Output*/
+	IssmDouble* xyz_list_edge = xNew<IssmDouble>(3*3);
+	this->FaceOnSurfaceIndices(&indices[0],&indices[1],&indices[2]);
+	for(int i=0;i<3;i++) for(int j=0;j<3;j++) xyz_list_edge[i*3+j]=xyz_list[indices[i]][j];
+
+	/*Assign output pointer*/
+	*pxyz_list = xyz_list_edge;
+
+}/*}}}*/
+/*FUNCTION Tetra::GetXcoord {{{*/
+IssmDouble Tetra::GetXcoord(Gauss* gauss){
+
+	int    i;
+	IssmDouble z;
+	IssmDouble xyz_list[NUMVERTICES][3];
+	IssmDouble z_list[NUMVERTICES];
+
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	for(i=0;i<NUMVERTICES;i++) z_list[i]=xyz_list[i][0];
+	TetraRef::GetInputValue(&z,&z_list[0],(GaussTetra*)gauss,P1Enum);
+
+	return z;
+}
+/*}}}*/
+/*FUNCTION Tetra::GetYcoord {{{*/
+IssmDouble Tetra::GetYcoord(Gauss* gauss){
+
+	int    i;
+	IssmDouble z;
+	IssmDouble xyz_list[NUMVERTICES][3];
+	IssmDouble z_list[NUMVERTICES];
+
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	for(i=0;i<NUMVERTICES;i++) z_list[i]=xyz_list[i][1];
+	TetraRef::GetInputValue(&z,&z_list[0],(GaussTetra*)gauss,P1Enum);
+
+	return z;
+}
+/*}}}*/
+/*FUNCTION Tetra::GetZcoord {{{*/
+IssmDouble Tetra::GetZcoord(Gauss* gauss){
+
+	int    i;
+	IssmDouble z;
+	IssmDouble xyz_list[NUMVERTICES][3];
+	IssmDouble z_list[NUMVERTICES];
+
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	for(i=0;i<NUMVERTICES;i++) z_list[i]=xyz_list[i][2];
+	TetraRef::GetInputValue(&z,&z_list[0],(GaussTetra*)gauss,P1Enum);
+
+	return z;
+}
+/*}}}*/
+/*FUNCTION Tetra::HasFaceOnBase{{{*/
+bool Tetra::HasFaceOnBase(){
+
+	IssmDouble values[NUMVERTICES];
+	IssmDouble sum;
+
+	/*Retrieve all inputs and parameters*/
+	GetInputListOnVertices(&values[0],MeshVertexonbaseEnum);
+	sum = values[0]+values[1]+values[2]+values[3];
+
+	_assert_(sum==0. || sum==1. || sum==2. || sum==3.);
+
+	if(sum==3){
+		return true;
+	}
+	else{
+		return false;
+	}
+}
+/*}}}*/
+/*FUNCTION Tetra::HasFaceOnSurface{{{*/
+bool Tetra::HasFaceOnSurface(){
+
+	IssmDouble values[NUMVERTICES];
+	IssmDouble sum;
+
+	/*Retrieve all inputs and parameters*/
+	GetInputListOnVertices(&values[0],MeshVertexonsurfaceEnum);
+	sum = values[0]+values[1]+values[2]+values[3];
+
+	_assert_(sum==0. || sum==1. || sum==2. || sum==3.);
+
+	if(sum==3){
+		return true;
+	}
+	else{
+		return false;
+	}
+}
+/*}}}*/
+/*FUNCTION Tetra::InputUpdateFromIoModel {{{*/
+void Tetra::InputUpdateFromIoModel(int index,IoModel* iomodel){ 
+
+	/*Intermediaries*/
+	int         i,j;
+	int         tetra_vertex_ids[NUMVERTICES];
+	IssmDouble  nodeinputs[NUMVERTICES];
+	IssmDouble  cmmininputs[NUMVERTICES];
+	IssmDouble  cmmaxinputs[NUMVERTICES];
+
+	IssmDouble  yts;
+	bool    control_analysis;
+	int     num_control_type,num_responses;
+
+	/*Fetch parameters: */
+	iomodel->Constant(&yts,ConstantsYtsEnum);
+	iomodel->Constant(&control_analysis,InversionIscontrolEnum);
+	if(control_analysis) iomodel->Constant(&num_control_type,InversionNumControlParametersEnum);
+	if(control_analysis) iomodel->Constant(&num_responses,InversionNumCostFunctionsEnum);
+
+	/*Recover vertices ids needed to initialize inputs*/
+	_assert_(iomodel->elements);
+	for(i=0;i<NUMVERTICES;i++){ 
+		tetra_vertex_ids[i]=iomodel->elements[NUMVERTICES*index+i]; //ids for vertices are in the elements array from Matlab
+	}
+
+	/*Control Inputs*/
+	if (control_analysis && iomodel->Data(InversionControlParametersEnum)){
+		for(i=0;i<num_control_type;i++){
+			switch(reCast<int,IssmDouble>(iomodel->Data(InversionControlParametersEnum)[i])){
+				case BalancethicknessThickeningRateEnum:
+					if (iomodel->Data(BalancethicknessThickeningRateEnum)){
+						for(j=0;j<NUMVERTICES;j++)nodeinputs[j]=iomodel->Data(BalancethicknessThickeningRateEnum)[tetra_vertex_ids[j]-1]/yts;
+						for(j=0;j<NUMVERTICES;j++)cmmininputs[j]=iomodel->Data(InversionMinParametersEnum)[(tetra_vertex_ids[j]-1)*num_control_type+i]/yts;
+						for(j=0;j<NUMVERTICES;j++)cmmaxinputs[j]=iomodel->Data(InversionMaxParametersEnum)[(tetra_vertex_ids[j]-1)*num_control_type+i]/yts;
+						this->inputs->AddInput(new ControlInput(BalancethicknessThickeningRateEnum,TetraInputEnum,nodeinputs,cmmininputs,cmmaxinputs,i+1));
+					}
+					break;
+				case VxEnum:
+					if (iomodel->Data(VxEnum)){
+						for(j=0;j<NUMVERTICES;j++)nodeinputs[j]=iomodel->Data(VxEnum)[tetra_vertex_ids[j]-1]/yts;
+						for(j=0;j<NUMVERTICES;j++)cmmininputs[j]=iomodel->Data(InversionMinParametersEnum)[(tetra_vertex_ids[j]-1)*num_control_type+i]/yts;
+						for(j=0;j<NUMVERTICES;j++)cmmaxinputs[j]=iomodel->Data(InversionMaxParametersEnum)[(tetra_vertex_ids[j]-1)*num_control_type+i]/yts;
+						this->inputs->AddInput(new ControlInput(VxEnum,TetraInputEnum,nodeinputs,cmmininputs,cmmaxinputs,i+1));
+					}
+					break;
+				case VyEnum:
+					if (iomodel->Data(VyEnum)){
+						for(j=0;j<NUMVERTICES;j++)nodeinputs[j]=iomodel->Data(VyEnum)[tetra_vertex_ids[j]-1]/yts;
+						for(j=0;j<NUMVERTICES;j++)cmmininputs[j]=iomodel->Data(InversionMinParametersEnum)[(tetra_vertex_ids[j]-1)*num_control_type+i]/yts;
+						for(j=0;j<NUMVERTICES;j++)cmmaxinputs[j]=iomodel->Data(InversionMaxParametersEnum)[(tetra_vertex_ids[j]-1)*num_control_type+i]/yts;
+						this->inputs->AddInput(new ControlInput(VyEnum,TetraInputEnum,nodeinputs,cmmininputs,cmmaxinputs,i+1));
+					}
+					break;
+				case FrictionCoefficientEnum:
+					if (iomodel->Data(FrictionCoefficientEnum)){
+						for(j=0;j<NUMVERTICES;j++)nodeinputs[j]=iomodel->Data(FrictionCoefficientEnum)[tetra_vertex_ids[j]-1];
+						for(j=0;j<NUMVERTICES;j++)cmmininputs[j]=iomodel->Data(InversionMinParametersEnum)[(tetra_vertex_ids[j]-1)*num_control_type+i];
+						for(j=0;j<NUMVERTICES;j++)cmmaxinputs[j]=iomodel->Data(InversionMaxParametersEnum)[(tetra_vertex_ids[j]-1)*num_control_type+i];
+						this->inputs->AddInput(new ControlInput(FrictionCoefficientEnum,TetraInputEnum,nodeinputs,cmmininputs,cmmaxinputs,i+1));
+					}
+					break;
+				case MaterialsRheologyBbarEnum:
+					if(iomodel->Data(MaterialsRheologyBEnum)){
+						for(j=0;j<NUMVERTICES;j++) nodeinputs[j]=iomodel->Data(MaterialsRheologyBEnum)[tetra_vertex_ids[j]-1];
+						for(j=0;j<NUMVERTICES;j++)cmmininputs[j]=iomodel->Data(InversionMinParametersEnum)[(tetra_vertex_ids[j]-1)*num_control_type+i];
+						for(j=0;j<NUMVERTICES;j++)cmmaxinputs[j]=iomodel->Data(InversionMaxParametersEnum)[(tetra_vertex_ids[j]-1)*num_control_type+i];
+						this->inputs->AddInput(new ControlInput(MaterialsRheologyBEnum,TetraInputEnum,nodeinputs,cmmininputs,cmmaxinputs,i+1));
+					}
+					break;
+				case DamageDbarEnum:
+					if(iomodel->Data(DamageDEnum)){
+						for(j=0;j<NUMVERTICES;j++) nodeinputs[j]=iomodel->Data(DamageDEnum)[tetra_vertex_ids[j]-1];
+						for(j=0;j<NUMVERTICES;j++)cmmininputs[j]=iomodel->Data(InversionMinParametersEnum)[(tetra_vertex_ids[j]-1)*num_control_type+i];
+						for(j=0;j<NUMVERTICES;j++)cmmaxinputs[j]=iomodel->Data(InversionMaxParametersEnum)[(tetra_vertex_ids[j]-1)*num_control_type+i];
+						this->inputs->AddInput(new ControlInput(DamageDEnum,TetraInputEnum,nodeinputs,cmmininputs,cmmaxinputs,i+1));
+					}
+					break;
+				default:
+					_error_("Control " << EnumToStringx(reCast<int,IssmDouble>(iomodel->Data(InversionControlParametersEnum)[i])) << " not implemented yet");
+			}
+		}
+	}
+
+	/*Need to know the type of approximation for this element*/
+	if(iomodel->Data(FlowequationElementEquationEnum)){
+		this->inputs->AddInput(new IntInput(ApproximationEnum,reCast<int>(iomodel->Data(FlowequationElementEquationEnum)[index])));
+	}
+
+	/*DatasetInputs*/
+	if (control_analysis && iomodel->Data(InversionCostFunctionsCoefficientsEnum)) {
+
+		/*Create inputs and add to DataSetInput*/
+		DatasetInput* datasetinput=new DatasetInput(InversionCostFunctionsCoefficientsEnum);
+		for(i=0;i<num_responses;i++){
+			for(j=0;j<NUMVERTICES;j++)nodeinputs[j]=iomodel->Data(InversionCostFunctionsCoefficientsEnum)[(tetra_vertex_ids[j]-1)*num_responses+i];
+			datasetinput->AddInput(new TetraInput(InversionCostFunctionsCoefficientsEnum,nodeinputs,P1Enum),reCast<int>(iomodel->Data(InversionCostFunctionsEnum)[i]));
+		}
+
+		/*Add datasetinput to element inputs*/
+		this->inputs->AddInput(datasetinput);
+	}
+}
+/*}}}*/
+/*FUNCTION Tetra::InputUpdateFromSolutionOneDof{{{*/
+void  Tetra::InputUpdateFromSolutionOneDof(IssmDouble* solution,int enum_type){
+
+	/*Intermediary*/
+	int* doflist = NULL;
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = this->NumberofNodes();
+
+	/*Fetch dof list and allocate solution vector*/
+	GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
+	IssmDouble* values    = xNew<IssmDouble>(numnodes);
+
+	/*Use the dof list to index into the solution vector: */
+	for(int i=0;i<numnodes;i++){
+		values[i]=solution[doflist[i]];
+		if(xIsNan<IssmDouble>(values[i])) _error_("NaN found in solution vector");
+	}
+
+	/*Add input to the element: */
+	this->inputs->AddInput(new TetraInput(enum_type,values,P1Enum));
+
+	/*Free ressources:*/
+	xDelete<IssmDouble>(values);
+	xDelete<int>(doflist);
+}
+/*}}}*/
+/*FUNCTION Tetra::IsOnBase {{{*/
+bool Tetra::IsOnBase(){
+	return HasFaceOnBase();
+}
+/*}}}*/
+/*FUNCTION Tetra::IsOnSurface {{{*/
+bool Tetra::IsOnSurface(){
+	return HasFaceOnSurface();
+}
+/*}}}*/
+bool Tetra::IsIcefront(void){/*{{{*/
+
+	/*Retrieve all inputs and parameters*/
+	IssmDouble ls[NUMVERTICES];
+	GetInputListOnVertices(&ls[0],MaskIceLevelsetEnum);
+
+	/* If only one vertex has ice, there is an ice front here */
+	if(IsIceInElement()){
+		int nrice=0;       
+		for(int i=0;i<NUMVERTICES;i++) if(ls[i]<0.) nrice++;
+		if(nrice==1) return true;
+	}
+	return false;
+}/*}}}*/
+/*FUNCTION Tetra::JacobianDeterminant{{{*/
+void Tetra::JacobianDeterminant(IssmDouble* pJdet,IssmDouble* xyz_list,Gauss* gauss){
+
+	_assert_(gauss->Enum()==GaussTetraEnum);
+	this->GetJacobianDeterminant(pJdet,xyz_list,(GaussTetra*)gauss);
+
+}
+/*}}}*/
+/*FUNCTION Tetra::JacobianDeterminantSurface{{{*/
+void Tetra::JacobianDeterminantSurface(IssmDouble* pJdet,IssmDouble* xyz_list,Gauss* gauss){
+
+	_assert_(gauss->Enum()==GaussTetraEnum);
+	this->GetJacobianDeterminantFace(pJdet,xyz_list,(GaussTetra*)gauss);
+
+}
+/*}}}*/
+/*FUNCTION Tetra::JacobianDeterminantBase{{{*/
+void Tetra::JacobianDeterminantBase(IssmDouble* pJdet,IssmDouble* xyz_list_base,Gauss* gauss){
+
+	_assert_(gauss->Enum()==GaussTetraEnum);
+	this->GetJacobianDeterminantFace(pJdet,xyz_list_base,(GaussTetra*)gauss);
+
+}
+/*}}}*/
+/*FUNCTION Tetra::JacobianDeterminantTop{{{*/
+void Tetra::JacobianDeterminantTop(IssmDouble* pJdet,IssmDouble* xyz_list_base,Gauss* gauss){
+
+	_assert_(gauss->Enum()==GaussTetraEnum);
+	this->GetJacobianDeterminantFace(pJdet,xyz_list_base,(GaussTetra*)gauss);
+
+}
+/*}}}*/
+/*FUNCTION Tetra::NewGauss(){{{*/
+Gauss* Tetra::NewGauss(void){
+	return new GaussTetra();
+}
+/*}}}*/
+/*FUNCTION Tetra::NewGauss(int order){{{*/
+Gauss* Tetra::NewGauss(int order){
+	return new GaussTetra(order);
+}
+/*}}}*/
+/*FUNCTION Tetra::NewGauss(IssmDouble* xyz_list, IssmDouble* xyz_list_front,int order_horiz,int order_vert){{{*/
+Gauss* Tetra::NewGauss(IssmDouble* xyz_list, IssmDouble* xyz_list_front,int order_horiz,int order_vert){
+	/*FIXME: this is messed up, should provide indices and not xyz_list!*/
+	int indices[3];
+	this->FaceOnFrontIndices(&indices[0],&indices[1],&indices[2]);
+	return new GaussTetra(indices[0],indices[1],indices[2],max(order_horiz,order_vert));
+}
+/*}}}*/
+/*FUNCTION Tetra::NewGaussBase(int order){{{*/
+Gauss* Tetra::NewGaussBase(int order){
+
+	int indices[3];
+	this->FaceOnBaseIndices(&indices[0],&indices[1],&indices[2]);
+	return new GaussTetra(indices[0],indices[1],indices[2],order);
+}
+/*}}}*/
+/*FUNCTION Tetra::NewGaussTop(int order){{{*/
+Gauss* Tetra::NewGaussTop(int order){
+
+	int indices[3];
+	this->FaceOnSurfaceIndices(&indices[0],&indices[1],&indices[2]);
+	return new GaussTetra(indices[0],indices[1],indices[2],order);
+}
+/*}}}*/
+/*FUNCTION Tetra::NodalFunctions{{{*/
+void Tetra::NodalFunctions(IssmDouble* basis, Gauss* gauss){
+
+	_assert_(gauss->Enum()==GaussTetraEnum);
+	this->GetNodalFunctions(basis,(GaussTetra*)gauss);
+
+}
+/*}}}*/
+/*FUNCTION Tetra::NodalFunctionsVelocity{{{*/
+void Tetra::NodalFunctionsVelocity(IssmDouble* basis, Gauss* gauss){
+
+	_assert_(gauss->Enum()==GaussTetraEnum);
+	this->GetNodalFunctionsVelocity(basis,(GaussTetra*)gauss);
+
+}
+/*}}}*/
+/*FUNCTION Tetra::NodalFunctionsPressure{{{*/
+void Tetra::NodalFunctionsPressure(IssmDouble* basis, Gauss* gauss){
+
+	_assert_(gauss->Enum()==GaussTetraEnum);
+	this->GetNodalFunctionsPressure(basis,(GaussTetra*)gauss);
+
+}
+/*}}}*/
+/*FUNCTION Tetra::NodalFunctionsTensor{{{*/
+void Tetra::NodalFunctionsTensor(IssmDouble* basis, Gauss* gauss){
+
+	_assert_(gauss->Enum()==GaussTetraEnum);
+	this->GetNodalFunctionsTensor(basis,(GaussTetra*)gauss);
+
+}
+/*}}}*/
+/*FUNCTION Tetra::NodalFunctionsDerivatives{{{*/
+void Tetra::NodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss){
+
+	_assert_(gauss->Enum()==GaussTetraEnum);
+	this->GetNodalFunctionsDerivatives(dbasis,xyz_list,(GaussTetra*)gauss);
+
+}
+/*}}}*/
+/*FUNCTION Tetra::NodalFunctionsDerivativesVelocity{{{*/
+void Tetra::NodalFunctionsDerivativesVelocity(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss){
+
+	_assert_(gauss->Enum()==GaussTetraEnum);
+	this->GetNodalFunctionsDerivativesVelocity(dbasis,xyz_list,(GaussTetra*)gauss);
+
+}
+/*}}}*/
+/*FUNCTION Tetra::NormalSection{{{*/
+void Tetra::NormalSection(IssmDouble* normal,IssmDouble* xyz_list){
+
+	/*Build unit outward pointing vector*/
+	IssmDouble AB[3];
+	IssmDouble AC[3];
+	IssmDouble norm;
+
+	AB[0]=xyz_list[1*3+0] - xyz_list[0*3+0];
+	AB[1]=xyz_list[1*3+1] - xyz_list[0*3+1];
+	AB[2]=xyz_list[1*3+2] - xyz_list[0*3+2];
+	AC[0]=xyz_list[2*3+0] - xyz_list[0*3+0];
+	AC[1]=xyz_list[2*3+1] - xyz_list[0*3+1];
+	AC[2]=xyz_list[2*3+2] - xyz_list[0*3+2];
+
+	cross(normal,AB,AC);
+	norm=sqrt(normal[0]*normal[0]+normal[1]*normal[1]+normal[2]*normal[2]);
+
+	for(int i=0;i<3;i++) normal[i]=normal[i]/norm;
+}
+/*}}}*/
+/*FUNCTION Tetra::NormalBase (THIS ONE){{{*/
+void Tetra::NormalBase(IssmDouble* bed_normal,IssmDouble* xyz_list){
+
+	IssmDouble v13[3],v23[3];
+	IssmDouble normal[3];
+	IssmDouble normal_norm;
+
+	for(int i=0;i<3;i++){
+		v13[i]=xyz_list[0*3+i]-xyz_list[2*3+i];
+		v23[i]=xyz_list[1*3+i]-xyz_list[2*3+i];
+	}
+
+	normal[0]=v13[1]*v23[2]-v13[2]*v23[1];
+	normal[1]=v13[2]*v23[0]-v13[0]*v23[2];
+	normal[2]=v13[0]*v23[1]-v13[1]*v23[0];
+	normal_norm=sqrt(normal[0]*normal[0]+ normal[1]*normal[1]+ normal[2]*normal[2]);
+
+	/*Bed normal is opposite to surface normal*/
+	bed_normal[0]=-normal[0]/normal_norm;
+	bed_normal[1]=-normal[1]/normal_norm;
+	bed_normal[2]=-normal[2]/normal_norm;
+}
+/*}}}*/
+/*FUNCTION Tetra::NormalTop (THIS ONE){{{*/
+void Tetra::NormalTop(IssmDouble* top_normal,IssmDouble* xyz_list){
+
+	IssmDouble v13[3],v23[3];
+	IssmDouble normal[3];
+	IssmDouble normal_norm;
+
+	for(int i=0;i<3;i++){
+		v13[i]=xyz_list[0*3+i]-xyz_list[2*3+i];
+		v23[i]=xyz_list[1*3+i]-xyz_list[2*3+i];
+	}
+
+	normal[0]=v13[1]*v23[2]-v13[2]*v23[1];
+	normal[1]=v13[2]*v23[0]-v13[0]*v23[2];
+	normal[2]=v13[0]*v23[1]-v13[1]*v23[0];
+	normal_norm=sqrt(normal[0]*normal[0]+ normal[1]*normal[1]+ normal[2]*normal[2]);
+
+	top_normal[0]=normal[0]/normal_norm;
+	top_normal[1]=normal[1]/normal_norm;
+	top_normal[2]=normal[2]/normal_norm;
+}
+/*}}}*/
+/*FUNCTION Tetra::NumberofNodesPressure{{{*/
+int Tetra::NumberofNodesPressure(void){
+	return TetraRef::NumberofNodesPressure();
+}
+/*}}}*/
+/*FUNCTION Tetra::NumberofNodesVelocity{{{*/
+int Tetra::NumberofNodesVelocity(void){
+	return TetraRef::NumberofNodesVelocity();
+}
+/*}}}*/
+/*FUNCTION Tetra::ReduceMatrices{{{*/
+void Tetra::ReduceMatrices(ElementMatrix* Ke,ElementVector* pe){
+
+	if(pe){
+		if(this->element_type==MINIcondensedEnum){
+			int indices[3]={12,13,14};
+			pe->StaticCondensation(Ke,3,&indices[0]);
+		}
+		else if(this->element_type==P1bubblecondensedEnum){
+			int size   = nodes[4]->GetNumberOfDofs(NoneApproximationEnum,GsetEnum);
+			int offset = 0;
+			for(int i=0;i<4;i++) offset+=nodes[i]->GetNumberOfDofs(NoneApproximationEnum,GsetEnum);
+			int* indices=xNew<int>(size);
+			for(int i=0;i<size;i++) indices[i] = offset+i;
+			pe->StaticCondensation(Ke,size,indices);
+			xDelete<int>(indices);
+		}
+	}
+
+	if(Ke){
+		if(this->element_type==MINIcondensedEnum){
+			int indices[3]={12,13,14};
+			Ke->StaticCondensation(3,&indices[0]);
+		}
+		else if(this->element_type==P1bubblecondensedEnum){
+			int size   = nodes[4]->GetNumberOfDofs(NoneApproximationEnum,GsetEnum);
+			int offset = 0;
+			for(int i=0;i<4;i++) offset+=nodes[i]->GetNumberOfDofs(NoneApproximationEnum,GsetEnum);
+			int* indices=xNew<int>(size);
+			for(int i=0;i<size;i++) indices[i] = offset+i;
+			Ke->StaticCondensation(size,indices);
+			xDelete<int>(indices);
+		}
+	}
+}
+/*}}}*/
+/*FUNCTION Tetra::ResetFSBasalBoundaryCondition {{{*/
+void  Tetra::ResetFSBasalBoundaryCondition(void){
+
+	int numnodes = this->GetNumberOfNodes();
+
+	int          approximation;
+	IssmDouble*  vertexonbase= NULL;
+	IssmDouble   slopex,slopey,groundedice;
+	IssmDouble   xz_plane[6];
+
+	/*For FS only: we want the CS to be tangential to the bedrock*/
+	inputs->GetInputValue(&approximation,ApproximationEnum);
+	if(IsFloating() || !HasNodeOnBase() ||  approximation!=FSApproximationEnum) return;
+
+	//printf("element number %i \n",this->id);
+	/*Get inputs*/
+	Input* slopex_input=inputs->GetInput(BedSlopeXEnum); _assert_(slopex_input);
+	Input* slopey_input=inputs->GetInput(BedSlopeYEnum); _assert_(slopey_input);
+	Input* groundedicelevelset_input=inputs->GetInput(MaskGroundediceLevelsetEnum); _assert_(groundedicelevelset_input);
+	vertexonbase = xNew<IssmDouble>(numnodes);
+	this->GetInputListOnNodesVelocity(&vertexonbase[0],MeshVertexonbaseEnum);
+
+	/*Loop over basal nodes and update their CS*/
+	GaussTetra* gauss = new GaussTetra();
+	for(int i=0;i<this->NumberofNodesVelocity();i++){
+
+		if(vertexonbase[i]==1){
+			gauss->GaussNode(this->VelocityInterpolation(),i);
+
+			slopex_input->GetInputValue(&slopex,gauss);
+			slopey_input->GetInputValue(&slopey,gauss);
+			groundedicelevelset_input->GetInputValue(&groundedice,gauss);
+
+			/*New X axis          New Z axis*/
+			xz_plane[0]=1.;       xz_plane[3]=-slopex;  
+			xz_plane[1]=0.;       xz_plane[4]=-slopey;  
+			xz_plane[2]=slopex;   xz_plane[5]=1.;          
+
+			if(groundedice>0){
+				if(this->nodes[i]->GetApproximation()==FSvelocityEnum){
+					this->nodes[i]->DofInSSet(2); //vz 
+				}
+				else _error_("Flow equation approximation"<<EnumToStringx(this->nodes[i]->GetApproximation())<<" not supported yet");
+			}
+			else{
+				if(this->nodes[i]->GetApproximation()==FSvelocityEnum){
+					this->nodes[i]->DofInFSet(2); //vz
+				}
+				else _error_("Flow equation approximation"<<EnumToStringx(this->nodes[i]->GetApproximation())<<" not supported yet");
+			}
+
+			XZvectorsToCoordinateSystem(&this->nodes[i]->coord_system[0][0],&xz_plane[0]);
+		}
+	}
+
+	/*cleanup*/
+	xDelete<IssmDouble>(vertexonbase);
+	delete gauss;
+}
+/*}}}*/
+/*FUNCTION Tetra::SetCurrentConfiguration {{{*/
+void  Tetra::SetCurrentConfiguration(Elements* elementsin, Loads* loadsin, Nodes* nodesin, Materials* materialsin, Parameters* parametersin){
+
+	/*go into parameters and get the analysis_counter: */
+	int analysis_counter;
+	parametersin->FindParam(&analysis_counter,AnalysisCounterEnum);
+
+	/*Get Element type*/
+	this->element_type=this->element_type_list[analysis_counter];
+
+	/*Pick up nodes*/
+	if(this->hnodes[analysis_counter]) this->nodes=(Node**)this->hnodes[analysis_counter]->deliverp();
+	else this->nodes=NULL;
+
+}
+/*}}}*/
+/*FUNCTION Tetra::SpawnBasalElement{{{*/
+Element*  Tetra::SpawnBasalElement(void){
+
+	_assert_(HasFaceOnBase());
+
+	int index1,index2,index3;
+	this->FaceOnBaseIndices(&index1,&index2,&index3);
+	return SpawnTria(index1,index2,index3);
+}/*}}}*/
+/*FUNCTION Tetra::SpawnTopElement{{{*/
+Element*  Tetra::SpawnTopElement(void){
+
+	_assert_(HasFaceOnSurface());
+
+	int index1,index2,index3;
+	this->FaceOnSurfaceIndices(&index1,&index2,&index3);
+	return SpawnTria(index1,index2,index3);
+}/*}}}*/
+/*FUNCTION Tetra::SpawnTria{{{*/
+Tria*  Tetra::SpawnTria(int index1,int index2,int index3){
+
+	int analysis_counter;
+
+	/*go into parameters and get the analysis_counter: */
+	this->parameters->FindParam(&analysis_counter,AnalysisCounterEnum);
+
+	/*Create Tria*/
+	Tria* tria=new Tria();
+	tria->id=this->id;
+	tria->inputs=(Inputs*)this->inputs->SpawnTriaInputs(index1,index2,index3);
+	tria->parameters=this->parameters;
+	tria->element_type=P1Enum; //Only P1 CG for now (TO BE CHANGED)
+	this->SpawnTriaHook(dynamic_cast<ElementHook*>(tria),index1,index2,index3);
+
+	/*Spawn material*/
+	tria->material=(Material*)this->material->copy2(tria);
+
+	/*recover nodes, material and matpar: */
+	tria->nodes    = (Node**)tria->hnodes[analysis_counter]->deliverp();
+	tria->vertices = (Vertex**)tria->hvertices->deliverp();
+	tria->matpar   = (Matpar*)tria->hmatpar->delivers();
+
+	/*Return new Tria*/
+	return tria;
+}
+/*}}}*/
+/*FUNCTION Tetra::Update {{{*/
+void Tetra::Update(int index,IoModel* iomodel,int analysis_counter,int analysis_type,int finiteelement_type){ 
+
+	/*Intermediaries*/
+	int        i;
+	int        tetra_vertex_ids[6];
+	IssmDouble nodeinputs[6];
+	IssmDouble yts;
+	bool       dakota_analysis;
+	bool       isFS;
+	int        numnodes;
+	int*       tetra_node_ids = NULL;
+
+	/*Fetch parameters: */
+	iomodel->Constant(&yts,ConstantsYtsEnum);
+	iomodel->Constant(&dakota_analysis,QmuIsdakotaEnum);
+	iomodel->Constant(&isFS,FlowequationIsFSEnum);
+
+	/*Checks if debuging*/
+	_assert_(iomodel->elements);
+
+	/*Recover element type*/
+	this->SetElementType(finiteelement_type,analysis_counter);
+
+	/*Recover vertices ids needed to initialize inputs*/
+	for(i=0;i<4;i++) tetra_vertex_ids[i]=iomodel->elements[4*index+i]; //ids for vertices are in the elements array from Matlab
+
+	/*Recover nodes ids needed to initialize the node hook.*/
+	switch(finiteelement_type){
+		case P1Enum:
+			numnodes         = 4;
+			tetra_node_ids   = xNew<int>(numnodes);
+			tetra_node_ids[0]=iomodel->nodecounter+iomodel->elements[4*index+0];
+			tetra_node_ids[1]=iomodel->nodecounter+iomodel->elements[4*index+1];
+			tetra_node_ids[2]=iomodel->nodecounter+iomodel->elements[4*index+2];
+			tetra_node_ids[3]=iomodel->nodecounter+iomodel->elements[4*index+3];
+			break;
+		case P1bubbleEnum: case P1bubblecondensedEnum:
+			numnodes         = 5;
+			tetra_node_ids   = xNew<int>(numnodes);
+			tetra_node_ids[0]=iomodel->nodecounter+iomodel->elements[4*index+0];
+			tetra_node_ids[1]=iomodel->nodecounter+iomodel->elements[4*index+1];
+			tetra_node_ids[2]=iomodel->nodecounter+iomodel->elements[4*index+2];
+			tetra_node_ids[3]=iomodel->nodecounter+iomodel->elements[4*index+3];
+			tetra_node_ids[4]=iomodel->nodecounter+iomodel->numberofvertices+index+1;
+			break;
+		case P2Enum:
+			numnodes        = 10;
+			tetra_node_ids   = xNew<int>(numnodes);
+			tetra_node_ids[0]=iomodel->nodecounter+iomodel->elements[4*index+0];
+			tetra_node_ids[1]=iomodel->nodecounter+iomodel->elements[4*index+1];
+			tetra_node_ids[2]=iomodel->nodecounter+iomodel->elements[4*index+2];
+			tetra_node_ids[3]=iomodel->nodecounter+iomodel->elements[4*index+3];
+			tetra_node_ids[4]=iomodel->nodecounter+iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[6*index+0]+1;
+			tetra_node_ids[5]=iomodel->nodecounter+iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[6*index+1]+1;
+			tetra_node_ids[6]=iomodel->nodecounter+iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[6*index+2]+1;
+			tetra_node_ids[7]=iomodel->nodecounter+iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[6*index+3]+1;
+			tetra_node_ids[8]=iomodel->nodecounter+iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[6*index+4]+1;
+			tetra_node_ids[9]=iomodel->nodecounter+iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[6*index+5]+1;
+			break;
+		case MINIEnum: case MINIcondensedEnum:
+			numnodes         = 9;
+			tetra_node_ids   = xNew<int>(numnodes);
+			tetra_node_ids[0]=iomodel->nodecounter+iomodel->elements[4*index+0];
+			tetra_node_ids[1]=iomodel->nodecounter+iomodel->elements[4*index+1];
+			tetra_node_ids[2]=iomodel->nodecounter+iomodel->elements[4*index+2];
+			tetra_node_ids[3]=iomodel->nodecounter+iomodel->elements[4*index+3];
+			tetra_node_ids[4]=iomodel->nodecounter+iomodel->numberofvertices+index+1;
+
+			tetra_node_ids[5]=iomodel->nodecounter+iomodel->numberofvertices+iomodel->numberofelements+iomodel->elements[4*index+0];
+			tetra_node_ids[6]=iomodel->nodecounter+iomodel->numberofvertices+iomodel->numberofelements+iomodel->elements[4*index+1];
+			tetra_node_ids[7]=iomodel->nodecounter+iomodel->numberofvertices+iomodel->numberofelements+iomodel->elements[4*index+2];
+			tetra_node_ids[8]=iomodel->nodecounter+iomodel->numberofvertices+iomodel->numberofelements+iomodel->elements[4*index+3];
+			break;
+		case TaylorHoodEnum:
+			numnodes        = 14;
+			tetra_node_ids  = xNew<int>(numnodes);
+			tetra_node_ids[0]=iomodel->nodecounter+iomodel->elements[4*index+0];
+			tetra_node_ids[1]=iomodel->nodecounter+iomodel->elements[4*index+1];
+			tetra_node_ids[2]=iomodel->nodecounter+iomodel->elements[4*index+2];
+			tetra_node_ids[3]=iomodel->nodecounter+iomodel->elements[4*index+3];
+			tetra_node_ids[4]=iomodel->nodecounter+iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[6*index+0]+1;
+			tetra_node_ids[5]=iomodel->nodecounter+iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[6*index+1]+1;
+			tetra_node_ids[6]=iomodel->nodecounter+iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[6*index+2]+1;
+			tetra_node_ids[7]=iomodel->nodecounter+iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[6*index+3]+1;
+			tetra_node_ids[8]=iomodel->nodecounter+iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[6*index+4]+1;
+			tetra_node_ids[9]=iomodel->nodecounter+iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[6*index+5]+1;
+
+			tetra_node_ids[10]=iomodel->nodecounter+iomodel->numberofvertices+iomodel->numberofedges+iomodel->elements[4*index+0];
+			tetra_node_ids[11]=iomodel->nodecounter+iomodel->numberofvertices+iomodel->numberofedges+iomodel->elements[4*index+1];
+			tetra_node_ids[12]=iomodel->nodecounter+iomodel->numberofvertices+iomodel->numberofedges+iomodel->elements[4*index+2];
+			tetra_node_ids[13]=iomodel->nodecounter+iomodel->numberofvertices+iomodel->numberofedges+iomodel->elements[4*index+3];
+			break;
+		default:
+			_error_("Finite element "<<EnumToStringx(finiteelement_type)<<" not supported yet");
+	}
+
+	/*hooks: */
+	this->SetHookNodes(tetra_node_ids,numnodes,analysis_counter); this->nodes=NULL;
+	xDelete<int>(tetra_node_ids);
+
+	/*Fill with IoModel*/
+	this->InputUpdateFromIoModel(index,iomodel);
+}
+/*}}}*/
+/*FUNCTION Tetra::VelocityInterpolation{{{*/
+int Tetra::VelocityInterpolation(void){
+	return TetraRef::VelocityInterpolation();
+}
+/*}}}*/
+/*FUNCTION Tetra::PressureInterpolation{{{*/
+int Tetra::PressureInterpolation(void){
+	return TetraRef::PressureInterpolation();
+}
+/*}}}*/
+/*FUNCTION Tetra::ZeroLevelsetCoordinates{{{*/
+void Tetra::ZeroLevelsetCoordinates(IssmDouble** pxyz_zero,IssmDouble* xyz_list,int levelsetenum){
+	/*Compute portion of the element that is grounded*/ 
+
+	IssmDouble  levelset[NUMVERTICES];
+	IssmDouble* xyz_zero = xNew<IssmDouble>(3*3);
+
+	/*Recover parameters and values*/
+	GetInputListOnVertices(&levelset[0],levelsetenum);
+
+	if(levelset[0]==0. && levelset[1]==0. && levelset[2]==0.){ 
+		xyz_zero[3*0+0]=xyz_list[0*3+0];
+		xyz_zero[3*0+1]=xyz_list[0*3+1];
+		xyz_zero[3*0+2]=xyz_list[0*3+2];
+
+		/*New point 2*/
+		xyz_zero[3*1+0]=xyz_list[1*3+0];
+		xyz_zero[3*1+1]=xyz_list[1*3+1];
+		xyz_zero[3*1+2]=xyz_list[1*3+2];
+
+		/*New point 3*/
+		xyz_zero[3*2+0]=xyz_list[2*3+0];
+		xyz_zero[3*2+1]=xyz_list[2*3+1];
+		xyz_zero[3*2+2]=xyz_list[2*3+2];
+	}
+	else if(levelset[0]==0. && levelset[1]==0. && levelset[3]==0.){ 
+		xyz_zero[3*0+0]=xyz_list[0*3+0];
+		xyz_zero[3*0+1]=xyz_list[0*3+1];
+		xyz_zero[3*0+2]=xyz_list[0*3+2];
+
+		/*New point 2*/
+		xyz_zero[3*1+0]=xyz_list[1*3+0];
+		xyz_zero[3*1+1]=xyz_list[1*3+1];
+		xyz_zero[3*1+2]=xyz_list[1*3+2];
+
+		/*New point 3*/
+		xyz_zero[3*2+0]=xyz_list[3*3+0];
+		xyz_zero[3*2+1]=xyz_list[3*3+1];
+		xyz_zero[3*2+2]=xyz_list[3*3+2];
+	}
+	else if(levelset[1]==0. && levelset[2]==0. && levelset[3]==0.){ 
+		xyz_zero[3*0+0]=xyz_list[1*3+0];
+		xyz_zero[3*0+1]=xyz_list[1*3+1];
+		xyz_zero[3*0+2]=xyz_list[1*3+2];
+
+		/*New point 2*/
+		xyz_zero[3*1+0]=xyz_list[2*3+0];
+		xyz_zero[3*1+1]=xyz_list[2*3+1];
+		xyz_zero[3*1+2]=xyz_list[2*3+2];
+
+		/*New point 3*/
+		xyz_zero[3*2+0]=xyz_list[3*3+0];
+		xyz_zero[3*2+1]=xyz_list[3*3+1];
+		xyz_zero[3*2+2]=xyz_list[3*3+2];
+	}
+	else if(levelset[2]==0. && levelset[0]==0. && levelset[3]==0.){ 
+		xyz_zero[3*0+0]=xyz_list[2*3+0];
+		xyz_zero[3*0+1]=xyz_list[2*3+1];
+		xyz_zero[3*0+2]=xyz_list[2*3+2];
+
+		/*New point 2*/
+		xyz_zero[3*1+0]=xyz_list[0*3+0];
+		xyz_zero[3*1+1]=xyz_list[0*3+1];
+		xyz_zero[3*1+2]=xyz_list[0*3+2];
+
+		/*New point 3*/
+		xyz_zero[3*2+0]=xyz_list[3*3+0];
+		xyz_zero[3*2+1]=xyz_list[3*3+1];
+		xyz_zero[3*2+2]=xyz_list[3*3+2];
+	}
+	else _error_("Case not covered");
+
+	/*Assign output pointer*/
+	*pxyz_zero= xyz_zero;
+}
+/*}}}*/
Index: /issm/trunk/src/c/classes/Elements/Tetra.h
===================================================================
--- /issm/trunk/src/c/classes/Elements/Tetra.h	(revision 17806)
+++ /issm/trunk/src/c/classes/Elements/Tetra.h	(revision 17806)
@@ -0,0 +1,216 @@
+/*! \file Tetra.h 
+ *  \brief: header file for seg object
+ */
+
+#ifndef _TETRA_H_
+#define _TETRA_H_
+
+/*Headers:*/
+/*{{{*/
+#include "./Element.h"
+#include "./ElementHook.h"
+#include "./TetraRef.h"
+class Parameters;
+class Inputs;
+class IoModel;
+class Results;
+class Node;
+class Material;
+class Matpar;
+class ElementMatrix;
+class ElementVector;
+class Vertex;
+
+#include "../../shared/Exceptions/exceptions.h"
+#include "../../shared/Enum/Enum.h"
+/*}}}*/
+
+class Tetra: public Element,public ElementHook,public TetraRef{
+
+	public:
+
+		/*Tetra constructors, destructors {{{*/
+		Tetra(){};
+		Tetra(int seg_id,int seg_sid,int i, IoModel* iomodel,int nummodels);
+		~Tetra();
+		/*}}}*/
+		/*Object virtual functions definitions:{{{ */
+		int     ObjectEnum();
+		Object *copy();
+		/*}}}*/
+		/*Update virtual functions resolution: {{{*/
+		void  InputUpdateFromSolutionOneDofCollapsed(IssmDouble* solution,int inputenum){_error_("not implemented yet");};
+		void  InputUpdateFromSolutionOneDof(IssmDouble* solution,int inputenum);
+		void  InputUpdateFromVector(IssmDouble* vector, int name, int type){_error_("not implemented yet");};
+#ifdef _HAVE_DAKOTA_
+		void  InputUpdateFromVectorDakota(IssmDouble* vector, int name, int type){_error_("not implemented yet");};
+		void  InputUpdateFromMatrixDakota(IssmDouble* matrix, int nows, int ncols, int name, int type){_error_("not implemented yet");};
+#endif
+		void  InputUpdateFromIoModel(int index, IoModel* iomodel);
+		/*}}}*/
+		/*Element virtual functions definitions: {{{*/
+		void        AddBasalInput(int input_enum, IssmDouble* values, int interpolation_enum){_error_("not implemented yet");};
+		void        AddInput(int input_enum, IssmDouble* values, int interpolation_enum);
+		IssmDouble  CharacteristicLength(void){_error_("not implemented yet");};
+		void        ComputeBasalStress(Vector<IssmDouble>* sigma_b){_error_("not implemented yet");};
+		void        ComputeSigmaNN(){_error_("not implemented yet");};
+		void        ComputeStrainRate(Vector<IssmDouble>* eps){_error_("not implemented yet");};
+		void        ComputeStressTensor(){_error_("not implemented yet");};
+		void        ComputeDeviatoricStressTensor(){_error_("not implemented yet");};
+		void        Configure(Elements* elements,Loads* loads,Nodes* nodesin,Vertices* verticesin,Materials* materials,Parameters* parameters);
+		void        SetCurrentConfiguration(Elements* elements,Loads* loads,Nodes* nodes,Materials* materials,Parameters* parameters);
+		void        Delta18oParameterization(void){_error_("not implemented yet");};
+		void        ElementSizes(IssmDouble* hx,IssmDouble* hy,IssmDouble* hz){_error_("not implemented yet");};
+		void        FaceOnFrontIndices(int* pindex1,int* pindex2,int* pindex3);
+		void        FaceOnBaseIndices(int* pindex1,int* pindex2,int* pindex3);
+		void        FaceOnSurfaceIndices(int* pindex1,int* pindex2,int* pindex3);
+		void        FSContactMigration(Vector<IssmDouble>* vertexgrounded,Vector<IssmDouble>* vertexfloating){_error_("not implemented yet");};
+		int         FiniteElement(void);
+		Element*    GetUpperElement(void){_error_("not implemented yet");};
+	  	Element*    GetLowerElement(void){_error_("not implemented yet");};
+	  	Element*    GetSurfaceElement(void){_error_("not implemented yet");};
+		Element*    GetBasalElement(void){_error_("not implemented yet");};
+		int         GetNodeIndex(Node* node){_error_("not implemented yet");};
+		int         GetNumberOfNodes(void);
+		int         GetNumberOfVertices(void);
+		void        GetVerticesCoordinatesBase(IssmDouble** pxyz_list);
+		void        GetVerticesCoordinatesTop(IssmDouble** pxyz_list);
+		bool        HasFaceOnBase();
+		bool        HasFaceOnSurface();
+		bool        IsOnBase();
+		bool        IsOnSurface();
+		bool        IsNodeOnShelfFromFlags(IssmDouble* flags){_error_("not implemented yet");};
+		void        JacobianDeterminant(IssmDouble*  Jdet, IssmDouble* xyz_list,Gauss* gauss);
+		void        JacobianDeterminantLine(IssmDouble* Jdet, IssmDouble* xyz_list,Gauss* gauss){_error_("not implemented yet");};
+		void        JacobianDeterminantSurface(IssmDouble*  pJdet, IssmDouble* xyz_list,Gauss* gauss);
+		void        JacobianDeterminantBase(IssmDouble* pJdet,IssmDouble* xyz_list_base,Gauss* gauss);
+		void        JacobianDeterminantTop(IssmDouble* pJdet,IssmDouble* xyz_list_base,Gauss* gauss);
+		IssmDouble  MinEdgeLength(IssmDouble* xyz_list){_error_("not implemented yet");};
+		void        NodalFunctions(IssmDouble* basis,Gauss* gauss);
+		void        NodalFunctionsP1(IssmDouble* basis,Gauss* gauss){_error_("not implemented yet");};
+		void        NodalFunctionsVelocity(IssmDouble* basis,Gauss* gauss);
+		void        NodalFunctionsPressure(IssmDouble* basis,Gauss* gauss);
+		void        NodalFunctionsTensor(IssmDouble* basis,Gauss* gauss);
+		void        NodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss);
+		void        NodalFunctionsP1Derivatives(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss){_error_("not implemented yet");};
+		void        NodalFunctionsMINIDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss){_error_("not implemented yet");};
+		void        NodalFunctionsDerivativesVelocity(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss);
+		void        NormalSection(IssmDouble* normal,IssmDouble* xyz_list);
+		void        NormalTop(IssmDouble* normal,IssmDouble* xyz_list);
+		void        NormalBase(IssmDouble* normal,IssmDouble* xyz_list);
+		int         NumberofNodesVelocity(void);
+		int         NumberofNodesPressure(void);
+	   Element*    SpawnBasalElement(void);
+		Element*    SpawnTopElement(void);
+		Tria*       SpawnTria(int index1,int index2,int index3);
+		IssmDouble  StabilizationParameter(IssmDouble u, IssmDouble v, IssmDouble w, IssmDouble diameter, IssmDouble kappa){_error_("not implemented yet");};
+		int         PressureInterpolation(void);
+		void        ValueP1OnGauss(IssmDouble* pvalue,IssmDouble* values,Gauss* gauss){_error_("not implemented yet");};
+		void        ValueP1DerivativesOnGauss(IssmDouble* dvalue,IssmDouble* values,IssmDouble* xyz_list,Gauss* gauss){_error_("not implemented yet");};
+		int         VelocityInterpolation(void);
+		void        GetGroundedPart(int* point1,IssmDouble* fraction1, IssmDouble* fraction2,bool* mainlyfloating){_error_("not implemented yet");};
+		IssmDouble  GetGroundedPortion(IssmDouble* xyz_list){_error_("not implemented yet");};
+		void        GetInputValue(IssmDouble* pvalue,Node* node,int enumtype){_error_("not implemented yet");};
+		Node*       GetNode(int node_number){_error_("Not implemented");};
+		IssmDouble  GetXcoord(Gauss* gauss);
+		IssmDouble  GetYcoord(Gauss* gauss);
+		IssmDouble  GetZcoord(Gauss* gauss);
+		int         GetElementType(void);
+		Gauss*      NewGauss(void);
+		Gauss*      NewGauss(int order);
+      Gauss*      NewGauss(IssmDouble* xyz_list, IssmDouble* xyz_list_front,int order){_error_("not implemented yet");};
+      Gauss*      NewGauss(IssmDouble* xyz_list, IssmDouble* xyz_list_front,int order_horiz,int order_vert);
+      Gauss*      NewGauss(int point1,IssmDouble fraction1,IssmDouble fraction2,bool mainlyfloating,int order){_error_("not implemented yet");};
+		Gauss*      NewGaussBase(int order);
+		Gauss*      NewGaussLine(int vertex1,int vertex2,int order){_error_("not implemented yet");};
+		Gauss*      NewGaussTop(int order);
+		int         VertexConnectivity(int vertexindex){_error_("not implemented yet");};
+		void        VerticalSegmentIndices(int** pindices,int* pnumseg){_error_("not implemented yet");};
+		void        ViscousHeating(IssmDouble* pphi,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input){_error_("not implemented yet");};
+		bool        IsZeroLevelset(int levelset_enum){_error_("not implemented");};
+		bool		   IsIcefront(void);
+		void        ZeroLevelsetCoordinates(IssmDouble** pxyz_zero,IssmDouble* xyz_list,int levelsetenum);
+		void		   GetIcefrontCoordinates(IssmDouble** pxyz_front,IssmDouble* xyz_list,int levelsetenum){_error_("not implemented yet");};
+		void        GetNormalFromLSF(IssmDouble *pnormal){_error_("not implemented yet");};
+
+		void        GetSolutionFromInputsOneDof(Vector<IssmDouble>* solution,int enum_type){_error_("not implemented yet");};
+		void        InputDepthAverageAtBase(int enum_type,int average_enum_type){_error_("not implemented yet");};
+		void        InputDuplicate(int original_enum,int new_enum){_error_("not implemented yet");};
+		void        InputScale(int enum_type,IssmDouble scale_factor){_error_("not implemented yet");};
+		void        MaterialUpdateFromTemperature(void){_error_("not implemented yet");};
+		int         NodalValue(IssmDouble* pvalue, int index, int natureofdataenum){_error_("not implemented yet");};
+		void        PositiveDegreeDay(IssmDouble* pdds,IssmDouble* pds,IssmDouble signorm){_error_("not implemented yet");};
+		void        ResetFSBasalBoundaryCondition(void);
+		void        ReduceMatrices(ElementMatrix* Ke,ElementVector* pe);
+		void        SetTemporaryElementType(int element_type_in){_error_("not implemented yet");};
+		void	      SmbGradients(){_error_("not implemented yet");};
+		IssmDouble  SurfaceArea(void){_error_("not implemented yet");};
+		void        Update(int index, IoModel* iomodel,int analysis_counter,int analysis_type,int finitelement);
+		IssmDouble  TimeAdapt(){_error_("not implemented yet");};
+		void UpdateConstraintsExtrudeFromBase(){_error_("not implemented");};
+		void UpdateConstraintsExtrudeFromTop(){_error_("not implemented");};
+
+		void       AverageOntoPartition(Vector<IssmDouble>* partition_contributions,Vector<IssmDouble>* partition_areas,IssmDouble* vertex_response,IssmDouble* qmu_part){_error_("not implemented yet");};
+		IssmDouble IceVolume(void){_error_("not implemented yet");};
+		IssmDouble IceVolumeAboveFloatation(void){_error_("not implemented yet");};
+		IssmDouble TotalSmb(void){_error_("not implemented yet");};
+		void       MinVel(IssmDouble* pminvel){_error_("not implemented yet");};
+		void       MinVx(IssmDouble* pminvx){_error_("not implemented yet");};
+		void       MinVy(IssmDouble* pminvy){_error_("not implemented yet");};
+		void       MinVz(IssmDouble* pminvz){_error_("not implemented yet");};
+		IssmDouble MassFlux(IssmDouble* segment){_error_("not implemented yet");};
+		IssmDouble MassFlux(IssmDouble x1,IssmDouble y1, IssmDouble x2, IssmDouble y2,int segment_id){_error_("not implemented yet");}
+		void       MaxAbsVx(IssmDouble* pmaxabsvx){_error_("not implemented yet");};
+		void       MaxAbsVy(IssmDouble* pmaxabsvy){_error_("not implemented yet");};
+		void       MaxAbsVz(IssmDouble* pmaxabsvz){_error_("not implemented yet");};
+		void       ElementResponse(IssmDouble* presponse,int response_enum){_error_("not implemented yet");};
+		void       MaxVel(IssmDouble* pmaxvel){_error_("not implemented yet");};
+		void       MaxVx(IssmDouble* pmaxvx){_error_("not implemented yet");};
+		void       MaxVy(IssmDouble* pmaxvy){_error_("not implemented yet");};
+		void       MaxVz(IssmDouble* pmaxvz){_error_("not implemented yet");};
+		IssmDouble Misfit(int modelenum,int observationenum,int weightsenum){_error_("not implemented yet");};
+		IssmDouble MisfitArea(int weightsenum){_error_("not implemented yet");};
+
+#ifdef _HAVE_GIA_
+		void   GiaDeflection(Vector<IssmDouble>* wg,Vector<IssmDouble>* dwgdt,IssmDouble* x,IssmDouble* y){_error_("not implemented yet");};
+#endif
+
+		IssmDouble DragCoefficientAbsGradient(void){_error_("not implemented yet");};
+		void       GradientIndexing(int* indexing,int control_index){_error_("not implemented yet");};
+		void       Gradj(Vector<IssmDouble>* gradient,int control_type,int control_index){_error_("not implemented yet");};
+		void       GradjBGradient(Vector<IssmDouble>* gradient,int control_index){_error_("not implemented yet");};
+		void       GradjDGradient(Vector<IssmDouble>* gradient,int control_index){_error_("not implemented yet");};
+		void       GradjBSSA(Vector<IssmDouble>* gradient,int control_index){_error_("not implemented yet");};
+		void       GradjDSSA(Vector<IssmDouble>* gradient,int control_index){_error_("not implemented yet");};
+		void       GradjDragSSA(Vector<IssmDouble>* gradient,int control_index){_error_("not implemented yet");};
+		void       GradjDragFS(Vector<IssmDouble>* gradient,int control_index){_error_("not implemented yet");};
+		void       GradjDragGradient(Vector<IssmDouble>* gradient,int control_index){_error_("not implemented yet");};
+		void       GradjDhDtBalancedthickness(Vector<IssmDouble>* gradient,int control_index){_error_("not implemented yet");};
+		void       GradjVxBalancedthickness(Vector<IssmDouble>* gradient,int control_index){_error_("not implemented yet");};
+		void       GradjVyBalancedthickness(Vector<IssmDouble>* gradient,int control_index){_error_("not implemented yet");};
+		void       GradjThicknessBalancethicknessSoft(Vector<IssmDouble>* gradient,int control_index){_error_("not implemented yet");};
+		void       GetVectorFromControlInputs(Vector<IssmDouble>* gradient,int control_enum,int control_index,const char* data){_error_("not implemented yet");};
+		void       SetControlInputsFromVector(IssmDouble* vector,int control_enum,int control_index){_error_("not implemented yet");};
+		void       ControlInputGetGradient(Vector<IssmDouble>* gradient,int enum_type,int control_index){_error_("not implemented yet");};
+		void       ControlInputScaleGradient(int enum_type,IssmDouble scale){_error_("not implemented yet");};
+		void       ControlInputSetGradient(IssmDouble* gradient,int enum_type,int control_index){_error_("not implemented yet");};
+		void       ControlToVectors(Vector<IssmPDouble>* vector_control, Vector<IssmPDouble>* vector_gradient,int control_enum){_error_("not implemented yet");};
+		IssmDouble RheologyBbarAbsGradient(void){_error_("not implemented yet");};
+		IssmDouble ThicknessAbsMisfit(void){_error_("not implemented yet");};
+		IssmDouble SurfaceAbsVelMisfit(void){_error_("not implemented yet");};
+		IssmDouble ThicknessAbsGradient(void){_error_("not implemented yet");};
+		IssmDouble ThicknessAlongGradient(void){_error_("not implemented yet");};
+		IssmDouble ThicknessAcrossGradient(void){_error_("not implemented yet");};
+		IssmDouble BalancethicknessMisfit(void){_error_("not implemented yet");};
+		IssmDouble SurfaceRelVelMisfit(void){_error_("not implemented yet");};
+		IssmDouble SurfaceLogVelMisfit(void){_error_("not implemented yet");};
+		IssmDouble SurfaceLogVxVyMisfit(void){_error_("not implemented yet");};
+		IssmDouble SurfaceAverageVelMisfit(void){_error_("not implemented yet");};
+		void       InputControlUpdate(IssmDouble scalar,bool save_parameter){_error_("not implemented yet");};
+
+		void   PotentialUngrounding(Vector<IssmDouble>* potential_sheet_ungrounding){_error_("not implemented yet");};
+		void   MigrateGroundingLine(IssmDouble* sheet_ungrounding){_error_("not implemented yet");};
+		int    UpdatePotentialUngrounding(IssmDouble* vertices_potentially_ungrounding,Vector<IssmDouble>* vec_nodes_on_iceshelf,IssmDouble* nodes_on_iceshelf){_error_("not implemented yet");};
+		/*}}}*/
+};
+#endif  /* _TETRA_H_*/
Index: /issm/trunk/src/c/classes/Elements/TetraRef.cpp
===================================================================
--- /issm/trunk/src/c/classes/Elements/TetraRef.cpp	(revision 17806)
+++ /issm/trunk/src/c/classes/Elements/TetraRef.cpp	(revision 17806)
@@ -0,0 +1,632 @@
+/*!\file TetraRef.c
+ * \brief: implementation of the TetraRef object
+ */
+
+/*Headers:*/
+/*{{{*/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#else
+#error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
+#endif
+
+#include "../classes.h"
+#include "../../shared/shared.h"
+/*}}}*/
+
+/*Element macros*/
+#define NUMNODESP0  1
+#define NUMNODESP1  4
+#define NUMNODESP1b 5
+#define NUMNODESP2  10
+
+/*Object constructors and destructor*/
+/*FUNCTION TetraRef::TetraRef(){{{*/
+TetraRef::TetraRef(){
+	this->element_type_list=NULL;
+}
+/*}}}*/
+/*FUNCTION TetraRef::TetraRef(int* types,int nummodels){{{*/
+TetraRef::TetraRef(const int nummodels){
+
+	/*Only allocate pointer*/
+	element_type_list=xNew<int>(nummodels);
+
+}
+/*}}}*/
+/*FUNCTION TetraRef::~TetraRef(){{{*/
+TetraRef::~TetraRef(){
+	xDelete<int>(element_type_list);
+}
+/*}}}*/
+
+/*Management*/
+/*FUNCTION TetraRef::SetElementType{{{*/
+void TetraRef::SetElementType(int type,int type_counter){
+
+	/*initialize element type*/
+	this->element_type_list[type_counter]=type;
+}
+/*}}}*/
+
+/*Reference Element numerics*/
+/*FUNCTION TetraRef::GetNodalFunctions(IssmDouble* basis,GaussTetra* gauss){{{*/
+void TetraRef::GetNodalFunctions(IssmDouble* basis,GaussTetra* gauss){
+	/*This routine returns the values of the nodal functions  at the gaussian point.*/
+	_assert_(basis);
+	GetNodalFunctions(basis,gauss,this->element_type);
+}
+/*}}}*/
+/*FUNCTION TetraRef::GetNodalFunctions(IssmDouble* basis,GaussTetra* gauss,int finiteelement){{{*/
+void TetraRef::GetNodalFunctions(IssmDouble* basis,GaussTetra* gauss,int finiteelement){
+	/*This routine returns the values of the nodal functions  at the gaussian point.*/
+
+	_assert_(basis);
+
+	switch(finiteelement){
+		case P0Enum:
+			basis[0]=1.;
+			return;
+		case P1Enum: case P1DGEnum:
+			basis[0]=gauss->coord1;
+			basis[1]=gauss->coord2;
+			basis[2]=gauss->coord3;
+			basis[3]=gauss->coord4;
+			return;
+		case P1bubbleEnum: case P1bubblecondensedEnum:
+			/*Corner nodes*/
+			basis[0]=gauss->coord1;
+			basis[1]=gauss->coord2;
+			basis[2]=gauss->coord3;
+			basis[3]=gauss->coord4;
+			/*bubble*/
+			basis[4]=256.*gauss->coord1*gauss->coord2*gauss->coord3*gauss->coord4;
+			return;
+		case P2Enum:
+			/*Vertices*/
+			basis[0]=gauss->coord1*(2.*gauss->coord1-1.);
+			basis[1]=gauss->coord2*(2.*gauss->coord2-1.);
+			basis[2]=gauss->coord3*(2.*gauss->coord3-1.);
+			basis[3]=gauss->coord4*(2.*gauss->coord4-1.);
+			/*Edges*/
+			basis[4]=4.*gauss->coord2*gauss->coord3;
+			basis[5]=4.*gauss->coord1*gauss->coord3;
+			basis[6]=4.*gauss->coord1*gauss->coord2;
+			basis[7]=4.*gauss->coord2*gauss->coord4;
+			basis[8]=4.*gauss->coord3*gauss->coord4;
+			basis[9]=4.*gauss->coord1*gauss->coord4;
+			return;
+		default:
+			_error_("Element type "<<EnumToStringx(element_type)<<" not supported yet");
+	}
+}
+/*}}}*/
+/*FUNCTION TetraRef::GetNodalFunctionsVelocity{{{*/
+void TetraRef::GetNodalFunctionsVelocity(IssmDouble* basis,GaussTetra* gauss){
+	/*This routine returns the values of the nodal functions  at the gaussian point.*/
+
+	switch(this->element_type){
+		case P1P1Enum:
+			this->element_type = P1Enum;
+			this->GetNodalFunctions(basis,gauss);
+			this->element_type = P1P1Enum;
+			return;
+		case P1P1GLSEnum:
+			this->element_type = P1Enum;
+			this->GetNodalFunctions(basis,gauss);
+			this->element_type = P1P1GLSEnum;
+			return;
+		case MINIcondensedEnum:
+			this->element_type = P1bubbleEnum;
+			this->GetNodalFunctions(basis,gauss);
+			this->element_type = MINIcondensedEnum;
+			return;
+		case MINIEnum:
+			this->element_type = P1bubbleEnum;
+			this->GetNodalFunctions(basis,gauss);
+			this->element_type = MINIEnum;
+			return;
+		case TaylorHoodEnum:
+			this->element_type = P2Enum;
+			this->GetNodalFunctions(basis,gauss);
+			this->element_type = TaylorHoodEnum;
+			return;
+		default:
+			_error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
+	}
+}
+/*}}}*/
+/*FUNCTION TetraRef::GetNodalFunctionsPressure{{{*/
+void TetraRef::GetNodalFunctionsPressure(IssmDouble* basis,GaussTetra* gauss){
+	/*This routine returns the values of the nodal functions  at the gaussian point.*/
+
+	switch(this->element_type){
+		case P1P1Enum:
+			this->element_type = P1Enum;
+			this->GetNodalFunctions(basis,gauss);
+			this->element_type = P1P1Enum;
+			return;
+		case P1P1GLSEnum:
+			this->element_type = P1Enum;
+			this->GetNodalFunctions(basis,gauss);
+			this->element_type = P1P1GLSEnum;
+			return;
+		case MINIcondensedEnum:
+			this->element_type = P1Enum;
+			this->GetNodalFunctions(basis,gauss);
+			this->element_type = MINIcondensedEnum;
+			return;
+		case MINIEnum:
+			this->element_type = P1Enum;
+			this->GetNodalFunctions(basis,gauss);
+			this->element_type = MINIEnum;
+			return;
+		case TaylorHoodEnum:
+			this->element_type = P1Enum;
+			this->GetNodalFunctions(basis,gauss);
+			this->element_type = TaylorHoodEnum;
+			return;
+		default:
+			_error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
+	}
+}
+/*}}}*/
+/*FUNCTION TetraRef::GetNodalFunctionsTensor{{{*/
+void TetraRef::GetNodalFunctionsTensor(IssmDouble* basis,GaussTetra* gauss){
+	/*This routine returns the values of the nodal functions  at the gaussian point.*/
+
+	switch(this->element_type){
+		case XTaylorHoodEnum:
+			this->element_type = P1DGEnum;
+			this->GetNodalFunctions(basis,gauss);
+			this->element_type = XTaylorHoodEnum;
+			return;
+		default:
+			_error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
+	}
+}
+/*}}}*/
+/*FUNCTION TetraRef::GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list, GaussTetra* gauss){{{*/
+void TetraRef::GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list, GaussTetra* gauss){
+	GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss,this->element_type);
+}
+/*}}}*/
+/*FUNCTION TetraRef::GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list, GaussTetra* gauss,int finiteelement){{{*/
+void TetraRef::GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list, GaussTetra* gauss,int finiteelement){
+
+	/*This routine returns the values of the nodal functions derivatives  (with respect to the 
+	 * actual coordinate system): */
+	IssmDouble    Jinv[3][3];
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = this->NumberofNodes(finiteelement);
+
+	/*Get nodal functions derivatives in reference triangle*/
+	IssmDouble* dbasis_ref=xNew<IssmDouble>(3*numnodes);
+	GetNodalFunctionsDerivativesReference(dbasis_ref,gauss,finiteelement); 
+
+	/*Get Jacobian invert: */
+	GetJacobianInvert(&Jinv[0][0], xyz_list, gauss);
+
+	/*Build dbasis: 
+	 *
+	 * [dhi/dx]= Jinv'*[dhi/dr]
+	 * [dhi/dy]        [dhi/ds]
+	 * [dhi/dz]        [dhi/dzeta]
+	 */
+
+	for(int i=0;i<numnodes;i++){
+		dbasis[numnodes*0+i]=Jinv[0][0]*dbasis_ref[0*numnodes+i]+Jinv[0][1]*dbasis_ref[1*numnodes+i]+Jinv[0][2]*dbasis_ref[2*numnodes+i];
+		dbasis[numnodes*1+i]=Jinv[1][0]*dbasis_ref[0*numnodes+i]+Jinv[1][1]*dbasis_ref[1*numnodes+i]+Jinv[1][2]*dbasis_ref[2*numnodes+i];
+		dbasis[numnodes*2+i]=Jinv[2][0]*dbasis_ref[0*numnodes+i]+Jinv[2][1]*dbasis_ref[1*numnodes+i]+Jinv[2][2]*dbasis_ref[2*numnodes+i];
+	}
+
+	/*Clean up*/
+	xDelete<IssmDouble>(dbasis_ref);
+}
+/*}}}*/
+/*FUNCTION TetraRef::GetNodalFunctionsDerivativesPressure         (THIS ONE and following ones){{{*/
+void TetraRef::GetNodalFunctionsDerivativesPressure(IssmDouble* dbasis,IssmDouble* xyz_list, GaussTetra* gauss){
+	switch(this->element_type){
+		case P1P1Enum:
+			this->element_type = P1Enum;
+			this->GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+			this->element_type = P1P1Enum;
+			return;
+		case P1P1GLSEnum:
+			this->element_type = P1Enum;
+			this->GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+			this->element_type = P1P1GLSEnum;
+			return;
+		case MINIcondensedEnum:
+			this->element_type = P1Enum;
+			this->GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+			this->element_type = MINIcondensedEnum;
+			return;
+		case MINIEnum:
+			this->element_type = P1Enum;
+			this->GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+			this->element_type = MINIEnum;
+			return;
+		case TaylorHoodEnum:
+			this->element_type = P1Enum;
+			this->GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+			this->element_type = TaylorHoodEnum;
+			return;
+		default:
+			_error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
+	}
+}
+/*}}}*/
+/*FUNCTION TetraRef::GetNodalFunctionsDerivativesVelocity{{{*/
+void TetraRef::GetNodalFunctionsDerivativesVelocity(IssmDouble* dbasis,IssmDouble* xyz_list, GaussTetra* gauss){
+	switch(this->element_type){
+		case P1P1Enum:
+			this->element_type = P1Enum;
+			this->GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+			this->element_type = P1P1Enum;
+			return;
+		case P1P1GLSEnum:
+			this->element_type = P1Enum;
+			this->GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+			this->element_type = P1P1GLSEnum;
+			return;
+		case MINIcondensedEnum:
+			this->element_type = P1bubbleEnum;
+			this->GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+			this->element_type = MINIcondensedEnum;
+			return;
+		case MINIEnum:
+			this->element_type = P1bubbleEnum;
+			this->GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+			this->element_type = MINIEnum;
+			return;
+		case TaylorHoodEnum:
+			this->element_type = P2Enum;
+			this->GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+			this->element_type = TaylorHoodEnum;
+			return;
+		default:
+			_error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
+	}
+}
+/*}}}*/
+/*FUNCTION TetraRef::GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,GaussTetra* gauss){{{*/
+void TetraRef::GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,GaussTetra* gauss){
+	/*This routine returns the values of the nodal functions derivatives  (with respect to the 
+	 * natural coordinate system) at the gaussian point. */
+
+	GetNodalFunctionsDerivativesReference(dbasis,gauss,this->element_type);
+
+}
+/*}}}*/
+/*FUNCTION TetraRef::GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,GaussTetra* gauss,int finiteelement){{{*/
+void TetraRef::GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,GaussTetra* gauss,int finiteelement){
+	/*This routine returns the values of the nodal functions derivatives  (with respect to the 
+	 * natural coordinate system) at the gaussian point. */
+
+	_assert_(dbasis && gauss);
+
+	switch(finiteelement){
+		case P0Enum:
+			/*Nodal function 1*/
+			dbasis[NUMNODESP0*0+0] = 0.;
+			dbasis[NUMNODESP0*1+0] = 0.;
+			dbasis[NUMNODESP0*2+0] = 0.;
+			return;
+		case P1Enum: case P1DGEnum:
+			dbasis[NUMNODESP1*0+0] = -1.;
+			dbasis[NUMNODESP1*1+0] = -1.;
+			dbasis[NUMNODESP1*2+0] = -1.;
+
+			dbasis[NUMNODESP1*0+1] = 1.;
+			dbasis[NUMNODESP1*1+1] = 0.;
+			dbasis[NUMNODESP1*2+1] = 0.;
+
+			dbasis[NUMNODESP1*0+2] = 0.;
+			dbasis[NUMNODESP1*1+2] = 1.;
+			dbasis[NUMNODESP1*2+2] = 0.;
+
+			dbasis[NUMNODESP1*0+3] = 0.;
+			dbasis[NUMNODESP1*1+3] = 0.;
+			dbasis[NUMNODESP1*2+3] = 1.;
+			return;
+		case P1bubbleEnum: case P1bubblecondensedEnum:
+			dbasis[NUMNODESP1b*0+0] = -1.;
+			dbasis[NUMNODESP1b*1+0] = -1.;
+			dbasis[NUMNODESP1b*2+0] = -1.;
+
+			dbasis[NUMNODESP1b*0+1] = 1.;
+			dbasis[NUMNODESP1b*1+1] = 0.;
+			dbasis[NUMNODESP1b*2+1] = 0.;
+
+			dbasis[NUMNODESP1b*0+2] = 0.;
+			dbasis[NUMNODESP1b*1+2] = 1.;
+			dbasis[NUMNODESP1b*2+2] = 0.;
+
+			dbasis[NUMNODESP1b*0+3] = 0.;
+			dbasis[NUMNODESP1b*1+3] = 0.;
+			dbasis[NUMNODESP1b*2+3] = 1.;
+
+			dbasis[NUMNODESP1b*0+4] = 256.*(-gauss->coord2*gauss->coord3*gauss->coord4+gauss->coord1*gauss->coord3*gauss->coord4);
+			dbasis[NUMNODESP1b*1+4] = 256.*(-gauss->coord2*gauss->coord3*gauss->coord4+gauss->coord1*gauss->coord2*gauss->coord4);
+			dbasis[NUMNODESP1b*2+4] = 256.*(-gauss->coord2*gauss->coord3*gauss->coord4+gauss->coord1*gauss->coord2*gauss->coord3);
+			return;
+		case P2Enum:
+			dbasis[NUMNODESP2*0+0] = -4.*gauss->coord1+1.;
+			dbasis[NUMNODESP2*1+0] = -4.*gauss->coord1+1.;
+			dbasis[NUMNODESP2*2+0] = -4.*gauss->coord1+1.;
+
+			dbasis[NUMNODESP2*0+1] = 4.*gauss->coord2-1.;
+			dbasis[NUMNODESP2*1+1] = 0.;
+			dbasis[NUMNODESP2*2+1] = 0.;
+
+			dbasis[NUMNODESP2*0+2] = 0.;
+			dbasis[NUMNODESP2*1+2] = 4.*gauss->coord3-1.;
+			dbasis[NUMNODESP2*2+2] = 0.;
+
+			dbasis[NUMNODESP2*0+3] = 0.;
+			dbasis[NUMNODESP2*1+3] = 0.;
+			dbasis[NUMNODESP2*2+3] = 4.*gauss->coord4-1.;
+
+			dbasis[NUMNODESP2*0+4] = 4.*gauss->coord3;
+			dbasis[NUMNODESP2*1+4] = 4.*gauss->coord2;
+			dbasis[NUMNODESP2*2+4] = 0.;
+
+			dbasis[NUMNODESP2*0+5] = -4.*gauss->coord3;
+			dbasis[NUMNODESP2*1+5] = 4.*(gauss->coord1-gauss->coord3);
+			dbasis[NUMNODESP2*2+5] = -4.*gauss->coord3;
+
+			dbasis[NUMNODESP2*0+6] = 4.*(gauss->coord1-gauss->coord2);
+			dbasis[NUMNODESP2*1+6] = -4.*gauss->coord2;
+			dbasis[NUMNODESP2*2+6] = -4.*gauss->coord2;
+
+			dbasis[NUMNODESP2*0+7] = 4.*gauss->coord4;
+			dbasis[NUMNODESP2*1+7] = 0.;
+			dbasis[NUMNODESP2*2+7] = 4.*gauss->coord2;
+
+			dbasis[NUMNODESP2*0+8] = 0.;
+			dbasis[NUMNODESP2*1+8] = 4.*gauss->coord4;
+			dbasis[NUMNODESP2*2+8] = 4.*gauss->coord3;
+
+			dbasis[NUMNODESP2*0+9] = -4.*gauss->coord4;
+			dbasis[NUMNODESP2*1+9] = -4.*gauss->coord4;
+			dbasis[NUMNODESP2*2+9] = 4.*(gauss->coord1-gauss->coord4);
+			return;
+		default:
+			_error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
+	}
+
+}
+/*}}}*/
+/*FUNCTION TetraRef::GetInputDerivativeValue{{{*/
+void TetraRef::GetInputDerivativeValue(IssmDouble* p, IssmDouble* plist,IssmDouble* xyz_list, GaussTetra* gauss){
+	/*From node values of parameter p (p_list[0], p_list[1], p_list[2],
+	 * p_list[3], p_list[4] and p_list[4]), return parameter derivative value at
+	 * gaussian point specified by gauss_coord:
+	 *   dp/dx=p_list[0]*dh1/dx+p_list[1]*dh2/dx+p_list[2]*dh3/dx+p_list[3]*dh4/dx+p_list[4]*dh5/dx+p_list[5]*dh6/dx;
+	 *   dp/dy=p_list[0]*dh1/dy+p_list[1]*dh2/dy+p_list[2]*dh3/dy+p_list[3]*dh4/dy+p_list[4]*dh5/dy+p_list[5]*dh6/dy;
+	 *   dp/dz=p_list[0]*dh1/dz+p_list[1]*dh2/dz+p_list[2]*dh3/dz+p_list[3]*dh4/dz+p_list[4]*dh5/dz+p_list[5]*dh6/dz;
+	 *
+	 *   p is a vector of size 3x1 already allocated.
+	 */
+
+	/*Output*/
+	IssmDouble dpx=0.;
+	IssmDouble dpy=0.;
+	IssmDouble dpz=0.;
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = this->NumberofNodes();
+
+	/*Get nodal functions derivatives*/
+	IssmDouble* dbasis=xNew<IssmDouble>(3*numnodes);
+	GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+
+	/*Calculate parameter for this Gauss point*/
+	for(int i=0;i<numnodes;i++) dpx += dbasis[0*numnodes+i]*plist[i];
+	for(int i=0;i<numnodes;i++) dpy += dbasis[1*numnodes+i]*plist[i];
+	for(int i=0;i<numnodes;i++) dpz += dbasis[2*numnodes+i]*plist[i];
+
+	/*Assign values*/
+	xDelete<IssmDouble>(dbasis);
+	p[0]=dpx;
+	p[1]=dpy;
+	p[2]=dpz;
+}
+/*}}}*/
+/*FUNCTION TetraRef::GetInputValue(IssmDouble* p, IssmDouble* plist, GaussTetra* gauss){{{*/
+void TetraRef::GetInputValue(IssmDouble* p, IssmDouble* plist, GaussTetra* gauss){
+
+	GetInputValue(p,plist,gauss,this->element_type);
+}
+/*}}}*/
+/*FUNCTION TetraRef::GetInputValue(IssmDouble* p, IssmDouble* plist, GaussTetra* gauss,int finiteelement){{{*/
+void TetraRef::GetInputValue(IssmDouble* p, IssmDouble* plist, GaussTetra* gauss,int finiteelement){
+
+	/*Output*/
+	IssmDouble value =0.;
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = this->NumberofNodes(finiteelement);
+
+	/*Get nodal functions*/
+	IssmDouble* basis=xNew<IssmDouble>(numnodes);
+	GetNodalFunctions(basis, gauss,finiteelement);
+
+	/*Calculate parameter for this Gauss point*/
+	for(int i=0;i<numnodes;i++) value += basis[i]*plist[i];
+
+	/*Assign output pointer*/
+	xDelete<IssmDouble>(basis);
+	*p = value;
+}
+/*}}}*/
+/*FUNCTION TetraRef::GetJacobian{{{*/
+void TetraRef::GetJacobian(IssmDouble* J, IssmDouble* xyz_list,GaussTetra* gauss){
+	/*The Jacobian is constant over the element, discard the gaussian points. 
+	 * J is assumed to have been allocated of size 1*/
+
+	IssmDouble x1=xyz_list[3*0+0];
+	IssmDouble x2=xyz_list[3*1+0];
+	IssmDouble x3=xyz_list[3*2+0];
+	IssmDouble x4=xyz_list[3*3+0];
+
+	IssmDouble y1=xyz_list[3*0+1];
+	IssmDouble y2=xyz_list[3*1+1];
+	IssmDouble y3=xyz_list[3*2+1];
+	IssmDouble y4=xyz_list[3*3+1];
+
+	IssmDouble z1=xyz_list[3*0+2];
+	IssmDouble z2=xyz_list[3*1+2];
+	IssmDouble z3=xyz_list[3*2+2];
+	IssmDouble z4=xyz_list[3*3+2];
+
+	J[NDOF3*0+0] = x2-x1;
+	J[NDOF3*0+1] = y2-y1;
+	J[NDOF3*0+2] = z2-z1;
+
+	J[NDOF3*1+0] = x3-x1;
+	J[NDOF3*1+1] = y3-y1;
+	J[NDOF3*1+2] = z3-z1;
+
+	J[NDOF3*2+0] = x4-x1;
+	J[NDOF3*2+1] = y4-y1;
+	J[NDOF3*2+2] = z4-z1;
+}
+/*}}}*/
+/*FUNCTION TetraRef::GetJacobianDeterminant{{{*/
+void TetraRef::GetJacobianDeterminant(IssmDouble*  Jdet, IssmDouble* xyz_list,GaussTetra* gauss){
+	/*The Jacobian determinant is constant over the element, discard the gaussian points. 
+	 * J is assumed to have been allocated of size NDOF2xNDOF2.*/
+	IssmDouble J[3][3];
+
+	/*Call Jacobian routine to get the jacobian:*/
+	GetJacobian(&J[0][0],xyz_list, gauss);
+
+	/*Get Determinant*/
+	Matrix3x3Determinant(Jdet,&J[0][0]);
+	if(*Jdet<0) _error_("negative jacobian determinant!");
+
+}
+/*}}}*/
+/*FUNCTION TetraRef::GetJacobianDeterminantFace{{{*/
+void TetraRef::GetJacobianDeterminantFace(IssmDouble*  Jdet, IssmDouble* xyz_list,GaussTetra* gauss){
+	/*The Jacobian determinant is constant over the element, discard the gaussian points. 
+	 * J is assumed to have been allocated of size NDOF2xNDOF2.*/
+
+	IssmDouble x1=xyz_list[3*0+0];
+	IssmDouble y1=xyz_list[3*0+1];
+	IssmDouble z1=xyz_list[3*0+2];
+	IssmDouble x2=xyz_list[3*1+0];
+	IssmDouble y2=xyz_list[3*1+1];
+	IssmDouble z2=xyz_list[3*1+2];
+	IssmDouble x3=xyz_list[3*2+0];
+	IssmDouble y3=xyz_list[3*2+1];
+	IssmDouble z3=xyz_list[3*2+2];
+
+	/*Jdet = norm( AB ^ AC ) / (2 * area of the reference triangle), with areaRef=sqrt(3) */
+	*Jdet=SQRT3/6.*pow(pow(((y2-y1)*(z3-z1)-(z2-z1)*(y3-y1)),2)+pow(((z2-z1)*(x3-x1)-(x2-x1)*(z3-z1)),2)+pow(((x2-x1)*(y3-y1)-(y2-y1)*(x3-x1)),2),0.5);
+	if(*Jdet<0) _error_("negative jacobian determinant!");
+}
+/*}}}*/
+/*FUNCTION TetraRef::GetJacobianInvert {{{*/
+void TetraRef::GetJacobianInvert(IssmDouble* Jinv, IssmDouble* xyz_list,GaussTetra* gauss){
+
+	/*Jacobian*/
+	IssmDouble J[3][3];
+
+	/*Call Jacobian routine to get the jacobian:*/
+	GetJacobian(&J[0][0], xyz_list, gauss);
+
+	/*Invert Jacobian matrix: */
+	Matrix3x3Invert(Jinv,&J[0][0]);
+}
+/*}}}*/
+/*FUNCTION TetraRef::NumberofNodes(){{{*/
+int TetraRef::NumberofNodes(void){
+
+	return this->NumberofNodes(this->element_type);
+}
+/*}}}*/
+/*FUNCTION TetraRef::NumberofNodes(int finiteelement){{{*/
+int TetraRef::NumberofNodes(int finiteelement){
+
+	switch(finiteelement){
+		case P0Enum:                return NUMNODESP0;
+		case P1Enum:                return NUMNODESP1;
+		case P1DGEnum:              return NUMNODESP1;
+		case P1bubbleEnum:          return NUMNODESP1b;
+		case P1bubblecondensedEnum: return NUMNODESP1b;
+		case P2Enum:                return NUMNODESP2;
+		case P1P1Enum:              return NUMNODESP1*2;
+		case P1P1GLSEnum:           return NUMNODESP1*2;
+		case MINIcondensedEnum:     return NUMNODESP1b+NUMNODESP1;
+		case MINIEnum:              return NUMNODESP1b+NUMNODESP1;
+		case TaylorHoodEnum:        return NUMNODESP2+NUMNODESP1;
+		default: _error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
+	}
+
+	return -1;
+}
+/*}}}*/
+/*FUNCTION TetraRef::NumberofNodesPressure{{{*/
+int TetraRef::NumberofNodesPressure(void){
+
+	switch(this->element_type){
+		case P1P1Enum:          return NUMNODESP1;
+		case P1P1GLSEnum:       return NUMNODESP1;
+		case MINIcondensedEnum: return NUMNODESP1;
+		case MINIEnum:          return NUMNODESP1;
+		case TaylorHoodEnum:    return NUMNODESP1;
+		default: _error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
+	}
+
+	return -1;
+}
+/*}}}*/
+/*FUNCTION TetraRef::NumberofNodesVelocity{{{*/
+int TetraRef::NumberofNodesVelocity(void){
+
+	switch(this->element_type){
+		case P1P1Enum:          return NUMNODESP1;
+		case P1P1GLSEnum:       return NUMNODESP1;
+		case MINIcondensedEnum: return NUMNODESP1b;
+		case MINIEnum:          return NUMNODESP1b;
+		case TaylorHoodEnum:    return NUMNODESP2;
+		default:       _error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
+	}
+
+	return -1;
+}
+/*}}}*/
+/*FUNCTION TetraRef::VelocityInterpolation{{{*/
+int TetraRef::VelocityInterpolation(void){
+
+	switch(this->element_type){
+		case P1P1Enum:          return P1Enum;
+		case P1P1GLSEnum:       return P1Enum;
+		case MINIcondensedEnum: return P1bubbleEnum;
+		case MINIEnum:          return P1bubbleEnum;
+		case TaylorHoodEnum:    return P2Enum;
+		default:       _error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
+	}
+
+	return -1;
+}
+/*}}}*/
+/*FUNCTION TetraRef::PressureInterpolation{{{*/
+int TetraRef::PressureInterpolation(void){
+
+	switch(this->element_type){
+		case P1P1Enum:          return P1Enum;
+		case P1P1GLSEnum:       return P1Enum;
+		case MINIcondensedEnum: return P1Enum;
+		case MINIEnum:          return P1Enum;
+		case TaylorHoodEnum:    return P1Enum;
+		default:       _error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
+	}
+
+	return -1;
+}
+/*}}}*/
Index: /issm/trunk/src/c/classes/Elements/TetraRef.h
===================================================================
--- /issm/trunk/src/c/classes/Elements/TetraRef.h	(revision 17806)
+++ /issm/trunk/src/c/classes/Elements/TetraRef.h	(revision 17806)
@@ -0,0 +1,51 @@
+
+/*!\file:  TetraRef.h
+ * \brief abstract class for handling Tetra oriented routines, like nodal functions, 
+ * strain rate generation, etc ...
+ */ 
+
+#ifndef _TETRAREF_H_
+#define _TETRAREF_H_
+
+class GaussTetra;
+
+class TetraRef{
+
+	public: 
+		int* element_type_list;
+		int  element_type;
+
+		TetraRef();
+		TetraRef(const int nummodels);
+		~TetraRef();
+
+		/*Management*/
+		void SetElementType(int type,int type_counter);
+		void GetBprimeMasstransport(IssmDouble* Bprime, IssmDouble* xyz_list, GaussTetra* gauss);
+		void GetJacobian(IssmDouble* J, IssmDouble* xyz_list,GaussTetra* gauss);
+		void GetJacobianDeterminant(IssmDouble*  Jdet, IssmDouble* xyz_list,GaussTetra* gauss);
+		void GetJacobianDeterminantFace(IssmDouble*  Jdet, IssmDouble* xyz_list,GaussTetra* gauss);
+		void GetJacobianInvert(IssmDouble* Jinv, IssmDouble* xyz_list,GaussTetra* gauss);
+		void GetNodalFunctions(IssmDouble* basis,GaussTetra* gauss);
+		void GetNodalFunctions(IssmDouble* basis,GaussTetra* gauss,int finiteelement);
+		void GetNodalFunctionsVelocity(IssmDouble* basis, GaussTetra* gauss);
+		void GetNodalFunctionsPressure(IssmDouble* basis, GaussTetra* gauss);
+		void GetNodalFunctionsTensor(IssmDouble* basis, GaussTetra* gauss);
+		void GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list, GaussTetra* gauss);
+		void GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list, GaussTetra* gauss,int finiteelement);
+		void GetNodalFunctionsDerivativesVelocity(IssmDouble* dbasis,IssmDouble* xyz_list,GaussTetra* gauss);
+		void GetNodalFunctionsDerivativesPressure(IssmDouble* dbasis,IssmDouble* xyz_list,GaussTetra* gauss);
+		void GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,GaussTetra* gauss);
+		void GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,GaussTetra* gauss,int finiteelement);
+		void GetInputDerivativeValue(IssmDouble* p, IssmDouble* plist,IssmDouble* xyz_list, GaussTetra* gauss);
+		void GetInputValue(IssmDouble* p, IssmDouble* plist, GaussTetra* gauss);
+		void GetInputValue(IssmDouble* p, IssmDouble* plist, GaussTetra* gauss,int finiteelement);
+
+		int  NumberofNodes(void);
+		int  NumberofNodes(int finiteelement);
+		int  NumberofNodesVelocity(void);
+		int  NumberofNodesPressure(void);
+		int  VelocityInterpolation(void);
+		int  PressureInterpolation(void);
+};
+#endif
Index: /issm/trunk/src/c/classes/Elements/Tria.cpp
===================================================================
--- /issm/trunk/src/c/classes/Elements/Tria.cpp	(revision 17805)
+++ /issm/trunk/src/c/classes/Elements/Tria.cpp	(revision 17806)
@@ -24,18 +24,7 @@
 
 /*Constructors/destructor/copy*/
-/*FUNCTION Tria::Tria(){{{*/
-Tria::Tria(){
-	this->nodes      = NULL;
-	this->vertices   = NULL;
-	this->material   = NULL;
-	this->matpar     = NULL;
-	this->inputs     = NULL;
-	this->parameters = NULL;
-
-}
-/*}}}*/
 /*FUNCTION Tria::Tria(int id, int sid,int index, IoModel* iomodel,int nummodels){{{*/
 Tria::Tria(int tria_id, int tria_sid, int index, IoModel* iomodel,int nummodels)
-	:TriaRef(nummodels),ElementHook(nummodels,index+1,3,iomodel){
+	:TriaRef(nummodels),ElementHook(nummodels,index+1,NUMVERTICES,iomodel){
 
 		/*id: */
@@ -54,10 +43,8 @@
 		this->material = NULL;
 		this->matpar   = NULL;
-
 }
 /*}}}*/
 /*FUNCTION Tria::~Tria(){{{*/
 Tria::~Tria(){
-	delete inputs;
 	this->parameters=NULL;
 }
@@ -108,528 +95,49 @@
 
 /*Other*/
-/*FUNCTION Tria::SetwiseNodeConnectivity{{{*/
-void Tria::SetwiseNodeConnectivity(int* pd_nz,int* po_nz,Node* node,bool* flags,int* flagsindices,int set1_enum,int set2_enum){
-
-	/*Intermediaries*/
-	const int numnodes = this->NumberofNodes();
-
-	/*Output */
-	int d_nz = 0;
-	int o_nz = 0;
-
-	/*Loop over all nodes*/
-	for(int i=0;i<numnodes;i++){
-
-		if(!flags[this->nodes[i]->Lid()]){
-
-			/*flag current node so that no other element processes it*/
-			flags[this->nodes[i]->Lid()]=true;
-
-			int counter=0;
-			while(flagsindices[counter]>=0) counter++;
-			flagsindices[counter]=this->nodes[i]->Lid();
-
-			/*if node is clone, we have an off-diagonal non-zero, else it is a diagonal non-zero*/
-			switch(set2_enum){
-				case FsetEnum:
-					if(nodes[i]->indexing.fsize){
-						if(this->nodes[i]->IsClone())
-						 o_nz += 1;
-						else
-						 d_nz += 1;
-					}
-					break;
-				case GsetEnum:
-					if(nodes[i]->indexing.gsize){
-						if(this->nodes[i]->IsClone())
-						 o_nz += 1;
-						else
-						 d_nz += 1;
-					}
-					break;
-				case SsetEnum:
-					if(nodes[i]->indexing.ssize){
-						if(this->nodes[i]->IsClone())
-						 o_nz += 1;
-						else
-						 d_nz += 1;
-					}
-					break;
-				default: _error_("not supported");
+/*FUNCTION Tria::AddBasalInput{{{*/
+void  Tria::AddBasalInput(int input_enum,IssmDouble* values, int interpolation_enum){
+
+	/*Call inputs method*/
+	_assert_(this->inputs);
+	
+	int domaintype;
+	parameters->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DhorizontalEnum:
+			this->inputs->AddInput(new TriaInput(input_enum,values,interpolation_enum));
+			break;
+		case Domain2DverticalEnum:{
+			if(interpolation_enum==P1Enum){
+				IssmDouble values2[NUMVERTICES]={0.};
+				int        numindices;
+				int       *indices = NULL;
+				int        index = this->EdgeOnBaseIndex();
+				NodeOnEdgeIndices(&numindices,&indices,index,this->FiniteElement());
+				for(int i=0;i<numindices;i++){
+					values2[indices[i]] = values[i];
+				}
+				this->inputs->AddInput(new TriaInput(input_enum,values2,interpolation_enum));
+				xDelete<int>(indices);
 			}
-		}
-	}
-
-	/*Assign output pointers: */
-	*pd_nz=d_nz;
-	*po_nz=o_nz;
-}
-/*}}}*/
-/*FUNCTION Tria::CreateKMatrix(Matrix<IssmDouble>* Kff, Matrix<IssmDouble>* Kfs) {{{*/
-void  Tria::CreateKMatrix(Matrix<IssmDouble>* Kff, Matrix<IssmDouble>* Kfs){
-
-
-	/*Skip if water element*/
-	if(NoIceInElement()) return;
-
-	/*Create element stiffness matrix*/
-	ElementMatrix* Ke=CreateKMatrix();
-
-	if(Ke){
-		/*Static condensation if requested*/
-		if(this->element_type==P1bubblecondensedEnum){
-			int size   = nodes[3]->GetNumberOfDofs(NoneApproximationEnum,GsetEnum);
-			int offset = 0;
-			for(int i=0;i<3;i++) offset+=nodes[i]->GetNumberOfDofs(NoneApproximationEnum,GsetEnum);
-			int* indices=xNew<int>(size);
-			for(int i=0;i<size;i++) indices[i] = offset+i;
-			Ke->StaticCondensation(size,indices);
-			xDelete<int>(indices);
-		}
-
-		/*Add to global matrix*/
-		Ke->AddToGlobal(Kff,Kfs);
-		delete Ke;
-	}
-}
-/*}}}*/
-/*FUNCTION Tria::CreateKMatrix(void) {{{*/
-ElementMatrix* Tria::CreateKMatrix(void){
-
-	/*retreive parameters: */
-	int analysis_type;
-	int meshtype;
-	parameters->FindParam(&analysis_type,AnalysisTypeEnum);
-
-	/*Checks in debugging mode{{{*/
-	_assert_(this->nodes && this->material && this->matpar && this->parameters && this->inputs);
-	/*}}}*/
-
-	/*Skip if water element*/
-	if(NoIceInElement()) return NULL;
-
-	/*Just branch to the correct element stiffness matrix generator, according to the type of analysis we are carrying out: */
-	switch(analysis_type){
-		#ifdef _HAVE_STRESSBALANCE_
-		case StressbalanceAnalysisEnum:
-			int approximation;
-			inputs->GetInputValue(&approximation,ApproximationEnum);
-			switch(approximation){
-				case SSAApproximationEnum:
-					return CreateKMatrixStressbalanceSSA();
-				case FSApproximationEnum:
-					return CreateKMatrixStressbalanceFS();
-				case SIAApproximationEnum:
-					return NULL;
-				case NoneApproximationEnum:
-					return NULL;
-				default:
-					_error_("Approximation " << EnumToStringx(approximation) << " not supported yet");
+			else _error_("not implemented yet");
 			}
 			break;
-		case StressbalanceSIAAnalysisEnum:
-			return CreateKMatrixStressbalanceSIA();
-			break;
-		#endif
-	 	#ifdef _HAVE_DAMAGE_
-		case DamageEvolutionAnalysisEnum:
-			return CreateKMatrixDamageEvolution();
-			break;
-		#endif
-		case L2ProjectionBaseAnalysisEnum:
-			parameters->FindParam(&meshtype,MeshTypeEnum);
-			if(meshtype==Mesh2DverticalEnum){
-				return CreateBasalMassMatrix();
-			}
-			else{
-				return CreateMassMatrix();
-			}
-			break;
-		#ifdef _HAVE_MASSTRANSPORT_
-		case MasstransportAnalysisEnum:
-			return CreateKMatrixMasstransport();
-			break;
-		case FreeSurfaceTopAnalysisEnum:
-			parameters->FindParam(&meshtype,MeshTypeEnum);
-			switch(meshtype){
-				case Mesh2DverticalEnum:
-					return CreateKMatrixFreeSurfaceTop1D();
-				case Mesh3DEnum:
-					return CreateKMatrixFreeSurfaceTop();
-				default:
-					_error_("Mesh not supported yet");
-			}
-			break;
-		case FreeSurfaceBaseAnalysisEnum:
-			parameters->FindParam(&meshtype,MeshTypeEnum);
-			switch(meshtype){
-				case Mesh2DverticalEnum:
-					return CreateKMatrixFreeSurfaceBase1D();
-				case Mesh3DEnum:
-					return CreateKMatrixFreeSurfaceBase();
-				default:
-					_error_("Mesh not supported yet");
-			}
-			break;
-		case ExtrudeFromBaseAnalysisEnum: case ExtrudeFromTopAnalysisEnum:
-			return CreateKMatrixExtrusion();
-		#endif
-		#ifdef _HAVE_HYDROLOGY_
-		case HydrologyShreveAnalysisEnum:
-			return CreateKMatrixHydrologyShreve();
-			break;
-		case HydrologyDCInefficientAnalysisEnum:
-			return CreateKMatrixHydrologyDCInefficient();
-			break;
-		case HydrologyDCEfficientAnalysisEnum:
-			return CreateKMatrixHydrologyDCEfficient();
-			break;
-		#endif
-		#ifdef _HAVE_BALANCED_
-		case BalancethicknessAnalysisEnum:
-			return CreateKMatrixBalancethickness();
-			break;
-		case BalancevelocityAnalysisEnum:
-			return CreateKMatrixBalancevelocity();
-			break;
-		case SmoothedSurfaceSlopeXAnalysisEnum: case SmoothedSurfaceSlopeYAnalysisEnum:
-			return CreateKMatrixSmoothedSlope();
-			break;
-		#endif
-		#ifdef _HAVE_CONTROL_
-		case AdjointBalancethicknessAnalysisEnum:
-			return CreateKMatrixAdjointBalancethickness();
-			break;
-		case AdjointHorizAnalysisEnum:
-			return CreateKMatrixAdjointSSA();
-			break;
-		#endif
-		default:
-			_error_("analysis " << analysis_type << " (" << EnumToStringx(analysis_type) << ") not supported yet");
-	}
-
-	/*Make compiler happy*/
-	return NULL;
-}
-/*}}}*/
-/*FUNCTION Tria::CreateMassMatrix {{{*/
-ElementMatrix* Tria::CreateMassMatrix(void){
-
-	/* Intermediaries */
-	IssmDouble  D,Jdet;
-	IssmDouble  xyz_list[NUMVERTICES][3];
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Initialize Element matrix and vectors*/
-	ElementMatrix* Ke    = new ElementMatrix(nodes,numnodes,this->parameters,NoneApproximationEnum);
-	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-
-	/* Start looping on the number of gaussian points: */
-	GaussTria* gauss=new GaussTria(2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetNodalFunctions(basis,gauss);
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		D=gauss->weight*Jdet;
-
-		TripleMultiply(basis,1,numnodes,1,
-					&D,1,1,0,
-					basis,1,numnodes,0,
-					&Ke->values[0],1);
-	}
-
-	/*Clean up and return*/
-	delete gauss;
-	xDelete<IssmDouble>(basis);
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Tria::CreateBasalMassMatrix{{{*/
-ElementMatrix* Tria::CreateBasalMassMatrix(void){
-
-	if(!HasEdgeOnBed()) return NULL;
-
-	int index1,index2;
-	this->EdgeOnBedIndices(&index1,&index2);
-
-	Seg* seg=(Seg*)SpawnSeg(index1,index2); 
-	ElementMatrix* Ke=seg->CreateMassMatrix();
-	delete seg->material; delete seg;
-
-	/*clean up and return*/
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Tria::CreateDVector {{{*/
-void  Tria::CreateDVector(Vector<IssmDouble>* df){
-
-	/*Nothing done yet*/
-}
-/*}}}*/
-/*FUNCTION Tria::CreatePVector(Vector<IssmDouble>* pf) {{{*/
-void  Tria::CreatePVector(Vector<IssmDouble>* pf){
-
-	/*Skip if water element*/
-	if(NoIceInElement()) return;
-
-	/*Create element load vector*/
-	ElementVector* pe = CreatePVector();
-
-	/*Add to global Vector*/
-	if(pe){
-		/*Static condensation if requested*/
-		if(this->element_type==P1bubblecondensedEnum){
-			int size   = nodes[3]->GetNumberOfDofs(NoneApproximationEnum,GsetEnum);
-			int offset = 0;
-			for(int i=0;i<3;i++) offset+=nodes[i]->GetNumberOfDofs(NoneApproximationEnum,GsetEnum);
-			int* indices=xNew<int>(size);
-			for(int i=0;i<size;i++) indices[i] = offset+i;
-
-			this->element_type=P1bubbleEnum;
-			ElementMatrix* Ke = CreateKMatrix();
-			this->element_type=P1bubblecondensedEnum;
-
-			pe->StaticCondensation(Ke,size,indices);
-			xDelete<int>(indices);
-			delete Ke;
-		}
-
-		pe->AddToGlobal(pf);
-		delete pe;
-	}
-}
-/*}}}*/
-/*FUNCTION Tria::CreatePVector(void){{{*/
-ElementVector* Tria::CreatePVector(void){
-
-	/*retrive parameters: */
-	int meshtype;
-	int analysis_type;
-	parameters->FindParam(&analysis_type,AnalysisTypeEnum);
-
-	/*asserts: {{{*/
-	/*if debugging mode, check that all pointers exist*/
-	_assert_(this->nodes && this->material && this->matpar && this->parameters && this->inputs);
-	/*}}}*/
-
-	/*Skip if water element*/
-	if(NoIceInElement()) return NULL;
-
-	/*Just branch to the correct load generator, according to the type of analysis we are carrying out: */
-	switch(analysis_type){
-		#ifdef _HAVE_STRESSBALANCE_
-		case StressbalanceAnalysisEnum:
-			int approximation;
-			inputs->GetInputValue(&approximation,ApproximationEnum);
-			switch(approximation){
-				case SSAApproximationEnum:
-					return CreatePVectorStressbalanceSSA();
-				case FSApproximationEnum:
-					return CreatePVectorStressbalanceFS();
-				case SIAApproximationEnum:
-					return NULL;
-				case NoneApproximationEnum:
-					return NULL;
-				default:
-					_error_("Approximation " << EnumToStringx(approximation) << " not supported yet");
-			}
-			break;
-		case StressbalanceSIAAnalysisEnum:
-			return CreatePVectorStressbalanceSIA();
-			break;
-		#endif
-	 	#ifdef _HAVE_DAMAGE_
-		case DamageEvolutionAnalysisEnum:
-			return CreatePVectorDamageEvolution();
-			break;
-		#endif
-		case L2ProjectionBaseAnalysisEnum:
-			parameters->FindParam(&meshtype,MeshTypeEnum);
-			if(meshtype==Mesh2DverticalEnum){
-				return CreatePVectorL2ProjectionBase();
-			}
-			else{
-				return CreatePVectorL2Projection();
-			}
-			break;
-	 	#ifdef _HAVE_MASSTRANSPORT_
-		case MasstransportAnalysisEnum:
-			return CreatePVectorMasstransport();
-			break;
-		case FreeSurfaceTopAnalysisEnum:
-			parameters->FindParam(&meshtype,MeshTypeEnum);
-			switch(meshtype){
-				case Mesh2DverticalEnum:
-					return CreatePVectorFreeSurfaceTop1D();
-				case Mesh3DEnum:
-					return CreatePVectorFreeSurfaceTop();
-				default:
-					_error_("Mesh not supported yet");
-			}
-			break;
-		case FreeSurfaceBaseAnalysisEnum:
-			parameters->FindParam(&meshtype,MeshTypeEnum);
-			switch(meshtype){
-				case Mesh2DverticalEnum:
-					return CreatePVectorFreeSurfaceBase1D();
-				case Mesh3DEnum:
-					return CreatePVectorFreeSurfaceBase();
-				default:
-					_error_("Mesh not supported yet");
-			}
-			break;
-		case ExtrudeFromBaseAnalysisEnum: case ExtrudeFromTopAnalysisEnum:
-			return NULL;
-			break;
-		#endif
-		#ifdef _HAVE_HYDROLOGY_
-		case HydrologyShreveAnalysisEnum:
-			return CreatePVectorHydrologyShreve();
-			break;
-		case HydrologyDCInefficientAnalysisEnum:
-			return CreatePVectorHydrologyDCInefficient();
-			break;
-		case HydrologyDCEfficientAnalysisEnum:
-			return CreatePVectorHydrologyDCEfficient();
-			break;
-		#endif
-		#ifdef _HAVE_BALANCED_
-		case BalancethicknessAnalysisEnum:
-			return CreatePVectorBalancethickness();
-			break;
-		case BalancevelocityAnalysisEnum:
-			return CreatePVectorBalancevelocity();
-			break;
-		case SmoothedSurfaceSlopeXAnalysisEnum:
-			return CreatePVectorSmoothedSlopeX();
-			break;
-		case SmoothedSurfaceSlopeYAnalysisEnum:
-			return CreatePVectorSmoothedSlopeY();
-			break;
-		#endif
-		#ifdef _HAVE_CONTROL_
-		case AdjointBalancethicknessAnalysisEnum:
-			return CreatePVectorAdjointBalancethickness();
-			break;
-		case AdjointHorizAnalysisEnum:
-			return CreatePVectorAdjointHoriz();
-			break;
-	 	#endif
-		default:
-			_error_("analysis " << analysis_type << " (" << EnumToStringx(analysis_type) << ") not supported yet");
-	}
-
-	/*make compiler happy*/
-	return NULL;
-}
-/*}}}*/
-/*FUNCTION Tria::CreatePVectorL2ProjectionBase{{{*/
-ElementVector* Tria::CreatePVectorL2ProjectionBase(void){
-
-	if(!HasEdgeOnBed()) return NULL;
-
-	int index1,index2;
-	this->EdgeOnBedIndices(&index1,&index2);
-
-	Seg* seg=(Seg*)SpawnSeg(index1,index2); 
-	ElementVector* pe=seg->CreatePVectorL2Projection();
-	delete seg->material; delete seg;
-
-	/*clean up and return*/
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Tria::CreatePVectorL2Projection {{{*/
-ElementVector* Tria::CreatePVectorL2Projection(void){
-
-	/*Intermediaries */
-	int        i,input_enum;
-	IssmDouble Jdet,value;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble slopes[2];
-	Input*     input  = NULL;
-	Input*     input2 = NULL;
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Initialize Element vector*/
-	ElementVector* pe    = new ElementVector(nodes,numnodes,this->parameters);
-	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	this->parameters->FindParam(&input_enum,InputToL2ProjectEnum);
-	switch(input_enum){
-		case SurfaceSlopeXEnum: input2 = inputs->GetInput(SurfaceEnum); _assert_(input2); break;
-		case SurfaceSlopeYEnum: input2 = inputs->GetInput(SurfaceEnum); _assert_(input2); break;
-		case BedSlopeXEnum:     input2 = inputs->GetInput(BedEnum);     _assert_(input2); break;
-		case BedSlopeYEnum:     input2 = inputs->GetInput(BedEnum);     _assert_(input2); break;
-		default: input = inputs->GetInput(input_enum);
-	}
-
-	/* Start  looping on the number of gaussian points: */
-	GaussTria* gauss=new GaussTria(2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		GetNodalFunctions(basis,gauss);
-
-		if(input2) input2->GetInputDerivativeValue(&slopes[0],&xyz_list[0][0],gauss);
-		switch(input_enum){
-			case SurfaceSlopeXEnum: case BedSlopeXEnum: value = slopes[0]; break;
-			case SurfaceSlopeYEnum: case BedSlopeYEnum: value = slopes[1]; break;
-			default: input->GetInputValue(&value,gauss);
-		}
-
-		for(i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*value*basis[i];
-	}
-
-	/*Clean up and return*/
-	xDelete<IssmDouble>(basis);
-	delete gauss;
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Tria::CreateJacobianMatrix{{{*/
-void  Tria::CreateJacobianMatrix(Matrix<IssmDouble>* Jff){
-
-	/*retrieve parameters: */
-	ElementMatrix* Ke=NULL;
-	int analysis_type;
-	parameters->FindParam(&analysis_type,AnalysisTypeEnum);
-
-	/*Checks in debugging {{{*/
-	_assert_(this->nodes && this->material && this->matpar && this->parameters && this->inputs);
-	/*}}}*/
-
-	/*Skip if water element*/
-	if(NoIceInElement()) return;
-
-	/*Just branch to the correct element stiffness matrix generator, according to the type of analysis we are carrying out: */
-	switch(analysis_type){
-#ifdef _HAVE_STRESSBALANCE_
-		case StressbalanceAnalysisEnum:
-			Ke=CreateJacobianStressbalanceSSA();
-			break;
-#endif
-		default:
-			_error_("analysis " << analysis_type << " (" << EnumToStringx(analysis_type) << ") not supported yet");
-	}
-
-	/*Add to global matrix*/
-	if(Ke){
-		Ke->AddToGlobal(Jff);
-		delete Ke;
-	}
+		default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
+	}
+
+}
+/*}}}*/
+/*FUNCTION Tria::AddInput{{{*/
+void  Tria::AddInput(int input_enum,IssmDouble* values, int interpolation_enum){
+
+	/*Call inputs method*/
+	_assert_(this->inputs);
+	this->inputs->AddInput(new TriaInput(input_enum,values,interpolation_enum));
+}
+/*}}}*/
+/*FUNCTION Tria::CharacteristicLength{{{*/
+IssmDouble Tria::CharacteristicLength(void){
+
+	return sqrt(2*this->GetArea());
 }
 /*}}}*/
@@ -639,4 +147,59 @@
 }
 /*}}}*/
+/*FUNCTION Tria::ComputeSigmaNN {{{*/
+void  Tria::ComputeSigmaNN(){
+
+	if(~IsOnBase()){
+		IssmDouble sigma_nn=0;
+		this->inputs->AddInput(new TriaInput(SigmaNNEnum,&sigma_nn,P0Enum));
+		return;
+	}
+	else{
+		IssmDouble* xyz_list=NULL;
+		IssmDouble  pressure,viscosity,sigma_nn;
+		IssmDouble  sigma_xx,sigma_xy,sigma_yy;
+		IssmDouble  epsilon[3]; /* epsilon=[exx,eyy,exy];*/
+		IssmDouble  base_normal[2]; 
+		int domaintype,dim=2;
+
+		/* Get node coordinates and dof list: */
+		GetVerticesCoordinates(&xyz_list);
+
+		/*Retrieve all inputs we will be needing: */
+		this->FindParam(&domaintype,DomainTypeEnum);
+		if(domaintype==Domain2DhorizontalEnum) _error_("stress tensor calculation not supported for mesh of type " <<EnumToStringx(domaintype)<<", extrude mesh or call ComputeDeviatoricStressTensor");
+		Input* pressure_input=inputs->GetInput(PressureEnum); _assert_(pressure_input);
+		Input* vx_input=inputs->GetInput(VxEnum);             _assert_(vx_input);
+		Input* vy_input=inputs->GetInput(VyEnum);             _assert_(vy_input);
+
+		/* Start looping on the number of vertices: */
+		Gauss* gauss=NewGaussBase(1);
+		gauss->GaussPoint(0);
+
+		/*Compute strain rate viscosity and pressure: */
+		this->StrainRateSSA(&epsilon[0],xyz_list,gauss,vx_input,vy_input);
+		this->ViscosityFS(&viscosity,dim,xyz_list,gauss,vx_input,vy_input,NULL);
+		pressure_input->GetInputValue(&pressure,gauss);
+
+		/*Compute Stress*/
+		sigma_xx=2*viscosity*epsilon[0]-pressure; // sigma = nu eps - pressure
+		sigma_yy=2*viscosity*epsilon[1]-pressure;
+		sigma_xy=2*viscosity*epsilon[2];
+
+		/*Get normal vector to the bed */
+		NormalBase(&base_normal[0],xyz_list);
+
+		/*Compute sigma_nn*/
+		sigma_nn=sigma_xx*base_normal[0]*base_normal[0] + sigma_xy*base_normal[0]*base_normal[1] + sigma_yy*base_normal[1]*base_normal[1];
+
+		/*Add Stress tensor components into inputs*/
+		this->inputs->AddInput(new TriaInput(SigmaNNEnum,&sigma_nn,P0Enum));
+
+		/*Clean up and return*/
+		xDelete<IssmDouble>(xyz_list);
+		delete gauss;
+	}
+}
+/*}}}*/
 /*FUNCTION Tria::ComputeStrainRate {{{*/
 void  Tria::ComputeStrainRate(Vector<IssmDouble>* eps){
@@ -647,19 +210,22 @@
 void  Tria::ComputeStressTensor(){
 
-	IssmDouble      xyz_list[NUMVERTICES][3];
-	IssmDouble      pressure,viscosity;
-	IssmDouble      epsilon[3]; /* epsilon=[exx,eyy,exy];*/
-	IssmDouble      sigma_xx[NUMVERTICES];
-	IssmDouble		sigma_yy[NUMVERTICES];
-	IssmDouble		sigma_zz[NUMVERTICES]={0,0,0};
-	IssmDouble      sigma_xy[NUMVERTICES];
-	IssmDouble		sigma_xz[NUMVERTICES]={0,0,0};
-	IssmDouble		sigma_yz[NUMVERTICES]={0,0,0};
-	GaussTria* gauss=NULL;
+	IssmDouble  xyz_list[NUMVERTICES][3];
+	IssmDouble  pressure,viscosity;
+	IssmDouble  epsilon[3]; /* epsilon=[exx,eyy,exy];*/
+	IssmDouble  sigma_xx[NUMVERTICES];
+	IssmDouble	sigma_yy[NUMVERTICES];
+	IssmDouble	sigma_zz[NUMVERTICES]={0,0,0};
+	IssmDouble  sigma_xy[NUMVERTICES];
+	IssmDouble	sigma_xz[NUMVERTICES]={0,0,0};
+	IssmDouble	sigma_yz[NUMVERTICES]={0,0,0};
+	GaussTria*  gauss=NULL;
+	int domaintype,dim=2;
 
 	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
 
 	/*Retrieve all inputs we will be needing: */
+	this->FindParam(&domaintype,DomainTypeEnum);
+	if(domaintype==Domain2DhorizontalEnum) _error_("stress tensor calculation not supported for mesh of type " <<EnumToStringx(domaintype)<<", extrude mesh or call ComputeDeviatoricStressTensor");
 	Input* pressure_input=inputs->GetInput(PressureEnum); _assert_(pressure_input);
 	Input* vx_input=inputs->GetInput(VxEnum);             _assert_(vx_input);
@@ -672,6 +238,6 @@
 
 		/*Compute strain rate viscosity and pressure: */
-		this->GetStrainRate2d(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input);
-		material->GetViscosity2d(&viscosity,&epsilon[0]);
+		this->StrainRateSSA(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input);
+		this->ViscositySSA(&viscosity,dim,&xyz_list[0][0],gauss,vx_input,vy_input);
 		pressure_input->GetInputValue(&pressure,gauss);
 
@@ -694,4 +260,55 @@
 }
 /*}}}*/
+/*FUNCTION Tria::ComputeDeviatoricStressTensor {{{*/
+void  Tria::ComputeDeviatoricStressTensor(){
+
+	IssmDouble  xyz_list[NUMVERTICES][3];
+	IssmDouble  viscosity;
+	IssmDouble  epsilon[3]; /* epsilon=[exx,eyy,exy];*/
+	IssmDouble  tau_xx[NUMVERTICES];
+	IssmDouble	tau_yy[NUMVERTICES];
+	IssmDouble	tau_zz[NUMVERTICES]={0,0,0};
+	IssmDouble  tau_xy[NUMVERTICES];
+	IssmDouble	tau_xz[NUMVERTICES]={0,0,0};
+	IssmDouble	tau_yz[NUMVERTICES]={0,0,0};
+	GaussTria*  gauss=NULL;
+	int domaintype,dim=2;
+
+	/* Get node coordinates and dof list: */
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+
+	/*Retrieve all inputs we will be needing: */
+	this->FindParam(&domaintype,DomainTypeEnum);
+	if(domaintype!=Domain2DhorizontalEnum) _error_("deviatoric stress tensor calculation not implemented for mesh of type " <<EnumToStringx(domaintype));
+	Input* vx_input=inputs->GetInput(VxEnum);             _assert_(vx_input);
+	Input* vy_input=inputs->GetInput(VyEnum);             _assert_(vy_input);
+
+	/* Start looping on the number of vertices: */
+	gauss=new GaussTria();
+	for (int iv=0;iv<NUMVERTICES;iv++){
+		gauss->GaussVertex(iv);
+
+		/*Compute strain rate and viscosity: */
+		this->StrainRateSSA(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input);
+		this->ViscositySSA(&viscosity,dim,&xyz_list[0][0],gauss,vx_input,vy_input);
+
+		/*Compute Stress*/
+		tau_xx[iv]=2*viscosity*epsilon[0]; // tau = nu eps
+		tau_yy[iv]=2*viscosity*epsilon[1];
+		tau_xy[iv]=2*viscosity*epsilon[2];
+	}
+
+	/*Add Stress tensor components into inputs*/
+	this->inputs->AddInput(new TriaInput(DeviatoricStressxxEnum,&tau_xx[0],P1Enum));
+	this->inputs->AddInput(new TriaInput(DeviatoricStressxyEnum,&tau_xy[0],P1Enum));
+	this->inputs->AddInput(new TriaInput(DeviatoricStressxzEnum,&tau_xz[0],P1Enum));
+	this->inputs->AddInput(new TriaInput(DeviatoricStressyyEnum,&tau_yy[0],P1Enum));
+	this->inputs->AddInput(new TriaInput(DeviatoricStressyzEnum,&tau_yz[0],P1Enum));
+	this->inputs->AddInput(new TriaInput(DeviatoricStresszzEnum,&tau_zz[0],P1Enum));
+
+	/*Clean up and return*/
+	delete gauss;
+}
+/*}}}*/
 /*FUNCTION Tria::Configure {{{*/
 void  Tria::Configure(Elements* elementsin, Loads* loadsin,Nodes* nodesin,Vertices *verticesin,Materials* materialsin, Parameters* parametersin){
@@ -724,33 +341,4 @@
 	this->inputs->Configure(parameters);
 
-}
-/*}}}*/
-/*FUNCTION Tria::DeepEcho{{{*/
-void Tria::DeepEcho(void){
-
-	_printf_("Tria:\n");
-	_printf_("   id: " << id << "\n");
-	if(nodes){
-		nodes[0]->DeepEcho();
-		nodes[1]->DeepEcho();
-		nodes[2]->DeepEcho();
-	}
-	else _printf_("nodes = NULL\n");
-
-	if (material) material->DeepEcho();
-	else _printf_("material = NULL\n");
-
-	if (matpar) matpar->DeepEcho();
-	else _printf_("matpar = NULL\n");
-
-	_printf_("   parameters\n");
-	if (parameters) parameters->DeepEcho();
-	else _printf_("parameters = NULL\n");
-
-	_printf_("   inputs\n");
-	if (inputs) inputs->DeepEcho();
-	else _printf_("inputs=NULL\n");
-
-	return;
 }
 /*}}}*/
@@ -826,28 +414,31 @@
 }
 /*}}}*/
-/*FUNCTION Tria::Echo{{{*/
-void Tria::Echo(void){
-	_printf_("Tria:\n");
-	_printf_("   id: " << id << "\n");
-	if(nodes){
-		nodes[0]->Echo();
-		nodes[1]->Echo();
-		nodes[2]->Echo();
-	}
-	else _printf_("nodes = NULL\n");
-
-	if (material) material->Echo();
-	else _printf_("material = NULL\n");
-
-	if (matpar) matpar->Echo();
-	else _printf_("matpar = NULL\n");
-
-	_printf_("   parameters\n");
-	if (parameters) parameters->Echo();
-	else _printf_("parameters = NULL\n");
-
-	_printf_("   inputs\n");
-	if (inputs) inputs->Echo();
-	else _printf_("inputs=NULL\n");
+/*FUNCTION Tria::ElementSizes{{{*/
+void Tria::ElementSizes(IssmDouble* hx,IssmDouble* hy,IssmDouble* hz){
+
+	IssmDouble xyz_list[NUMVERTICES][3];
+	IssmDouble xmin,ymin;
+	IssmDouble xmax,ymax;
+
+	/*Get xyz list: */
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	xmin=xyz_list[0][0]; xmax=xyz_list[0][0];
+	ymin=xyz_list[0][1]; ymax=xyz_list[0][1];
+
+	for(int i=1;i<NUMVERTICES;i++){
+		if(xyz_list[i][0]<xmin) xmin=xyz_list[i][0];
+		if(xyz_list[i][0]>xmax) xmax=xyz_list[i][0];
+		if(xyz_list[i][1]<ymin) ymin=xyz_list[i][1];
+		if(xyz_list[i][1]>ymax) ymax=xyz_list[i][1];
+	}
+
+	*hx=xmax-xmin;
+	*hy=ymax-ymin;
+	*hz=0.;
+}
+/*}}}*/
+/*FUNCTION Tria::FiniteElement{{{*/
+int Tria::FiniteElement(void){
+	return this->element_type;
 }
 /*}}}*/
@@ -866,5 +457,5 @@
 
 	/*Get xyz list: */
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
 	x1=xyz_list[0][0]; y1=xyz_list[0][1];
 	x2=xyz_list[1][0]; y2=xyz_list[1][1];
@@ -876,5 +467,5 @@
 /*}}}*/
 /*FUNCTION Tria::GetAreaCoordinates{{{*/
-void Tria::GetAreaCoordinates(IssmDouble* area_coordinates,IssmDouble xyz_zero[3][3],IssmDouble xyz_list[3][3],int numpoints){
+void Tria::GetAreaCoordinates(IssmDouble* area_coordinates,IssmDouble* xyz_zero,IssmDouble* xyz_list,int numpoints){
 	/*Computeportion of the element that is grounded*/ 
 
@@ -888,5 +479,5 @@
 	for(j=0;j<3;j++){ 
 		for(k=0;k<3;k++){
-			xyz_bis[j][k]=xyz_list[j][k];
+			xyz_bis[j][k]=xyz_list[j*3+k];
 		}
 	}
@@ -895,5 +486,5 @@
 			for(k=0;k<3;k++){
 				/*Change appropriate line*/
-				xyz_bis[j][k]=xyz_zero[i][k];
+				xyz_bis[j][k]=xyz_zero[i*3+k];
 			}
 
@@ -905,81 +496,8 @@
 			for(k=0;k<3;k++){
 				/*Reinitialize xyz_list with original coordinates*/
-				xyz_bis[j][k]=xyz_list[j][k];
+				xyz_bis[j][k]=xyz_list[j*3+k];
 			}
 		}
 	}
-}
-/*}}}*/
-/*FUNCTION Tria::GetDofList {{{*/
-void  Tria::GetDofList(int** pdoflist, int approximation_enum,int setenum){
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*First, figure out size of doflist and create it: */
-	int numberofdofs=0;
-	for(int i=0;i<numnodes;i++) numberofdofs+=nodes[i]->GetNumberOfDofs(approximation_enum,setenum);
-
-	/*Allocate output*/
-	int* doflist=xNew<int>(numberofdofs);
-
-	/*Populate: */
-	int count=0;
-	for(int i=0;i<numnodes;i++){
-		nodes[i]->GetDofList(doflist+count,approximation_enum,setenum);
-		count+=nodes[i]->GetNumberOfDofs(approximation_enum,setenum);
-	}
-
-	/*Assign output pointers:*/
-	*pdoflist=doflist;
-}
-/*}}}*/
-/*FUNCTION Tria::GetDofListVelocity{{{*/
-void  Tria::GetDofListVelocity(int** pdoflist,int setenum){
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodesVelocity();
-
-	/*First, figure out size of doflist and create it: */
-	int numberofdofs=0;
-	for(int i=0;i<numnodes;i++) numberofdofs+=nodes[i]->GetNumberOfDofs(FSvelocityEnum,setenum);
-
-	/*Allocate output*/
-	int* doflist=xNew<int>(numberofdofs);
-
-	/*Populate: */
-	int count=0;
-	for(int i=0;i<numnodes;i++){
-		nodes[i]->GetDofList(doflist+count,FSvelocityEnum,setenum);
-		count+=nodes[i]->GetNumberOfDofs(FSvelocityEnum,setenum);
-	}
-
-	/*Assign output pointers:*/
-	*pdoflist=doflist;
-}
-/*}}}*/
-/*FUNCTION Tria::GetDofListPressure{{{*/
-void  Tria::GetDofListPressure(int** pdoflist,int setenum){
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int vnumnodes = this->NumberofNodesVelocity();
-	int pnumnodes = this->NumberofNodesPressure();
-
-	/*First, figure out size of doflist and create it: */
-	int numberofdofs=0;
-	for(int i=vnumnodes;i<vnumnodes+pnumnodes;i++) numberofdofs+=nodes[i]->GetNumberOfDofs(FSApproximationEnum,setenum);
-
-	/*Allocate output*/
-	int* doflist=xNew<int>(numberofdofs);
-
-	/*Populate: */
-	int count=0;
-	for(int i=vnumnodes;i<vnumnodes+pnumnodes;i++){
-		nodes[i]->GetDofList(doflist+count,FSApproximationEnum,setenum);
-		count+=nodes[i]->GetNumberOfDofs(FSApproximationEnum,setenum);
-	}
-
-	/*Assign output pointers:*/
-	*pdoflist=doflist;
 }
 /*}}}*/
@@ -1051,10 +569,12 @@
 
 	bool              mainlyfloating = true;
+	int               domaintype,index1,index2;
 	const IssmPDouble epsilon        = 1.e-15;
-	IssmDouble         phi,s1,s2,area_init,area_grounded;
-	IssmDouble         gl[NUMVERTICES];
-	IssmDouble         xyz_bis[3][3];
+	IssmDouble        phi,s1,s2,area_init,area_grounded;
+	IssmDouble        gl[NUMVERTICES];
+	IssmDouble        xyz_bis[3][3];
 
 	/*Recover parameters and values*/
+	parameters->FindParam(&domaintype,DomainTypeEnum);
 	GetInputListOnVertices(&gl[0],MaskGroundediceLevelsetEnum);
 
@@ -1064,82 +584,97 @@
 	if(gl[2]==0.) gl[2]=gl[2]+epsilon;
 
-	/*Check that not all nodes are grounded or floating*/
-	if(gl[0]>0 && gl[1]>0 && gl[2]>0){ // All grounded
-		phi=1;
-	}
-	else if(gl[0]<0 && gl[1]<0 && gl[2]<0){ //All floating
-		phi=0;
-	}
-	else{
-		/*Figure out if two nodes are floating or grounded*/
-		if(gl[0]*gl[1]*gl[2]>0) mainlyfloating=false;
-
-		if(gl[0]*gl[1]>0){ //Nodes 0 and 1 are similar, so points must be found on segment 0-2 and 1-2
-			/*Coordinates of point 2: same as initial point 2*/
-			xyz_bis[2][0]=*(xyz_list+3*2+0);
-			xyz_bis[2][1]=*(xyz_list+3*2+1);
-			xyz_bis[2][2]=*(xyz_list+3*2+2);
-
-			/*Portion of the segments*/
-			s1=gl[2]/(gl[2]-gl[1]);
-			s2=gl[2]/(gl[2]-gl[0]);
-
-			/*New point 1*/
-			xyz_bis[1][0]=*(xyz_list+3*2+0)+s1*(*(xyz_list+3*1+0)-*(xyz_list+3*2+0));
-			xyz_bis[1][1]=*(xyz_list+3*2+1)+s1*(*(xyz_list+3*1+1)-*(xyz_list+3*2+1));
-			xyz_bis[1][2]=*(xyz_list+3*2+2)+s1*(*(xyz_list+3*1+2)-*(xyz_list+3*2+2));
-
-			/*New point 0*/
-			xyz_bis[0][0]=*(xyz_list+3*2+0)+s2*(*(xyz_list+3*0+0)-*(xyz_list+3*2+0));
-			xyz_bis[0][1]=*(xyz_list+3*2+1)+s2*(*(xyz_list+3*0+1)-*(xyz_list+3*2+1));
-			xyz_bis[0][2]=*(xyz_list+3*2+2)+s2*(*(xyz_list+3*0+2)-*(xyz_list+3*2+2));
-		}
-		else if(gl[1]*gl[2]>0){ //Nodes 1 and 2 are similar, so points must be found on segment 0-1 and 0-2
-			/*Coordinates of point 0: same as initial point 2*/
-			xyz_bis[0][0]=*(xyz_list+3*0+0);
-			xyz_bis[0][1]=*(xyz_list+3*0+1);
-			xyz_bis[0][2]=*(xyz_list+3*0+2);
-
-			/*Portion of the segments*/
-			s1=gl[0]/(gl[0]-gl[1]);
-			s2=gl[0]/(gl[0]-gl[2]);
-
-			/*New point 1*/
-			xyz_bis[1][0]=*(xyz_list+3*0+0)+s1*(*(xyz_list+3*1+0)-*(xyz_list+3*0+0));
-			xyz_bis[1][1]=*(xyz_list+3*0+1)+s1*(*(xyz_list+3*1+1)-*(xyz_list+3*0+1));
-			xyz_bis[1][2]=*(xyz_list+3*0+2)+s1*(*(xyz_list+3*1+2)-*(xyz_list+3*0+2));
-
-			/*New point 2*/
-			xyz_bis[2][0]=*(xyz_list+3*0+0)+s2*(*(xyz_list+3*2+0)-*(xyz_list+3*0+0));
-			xyz_bis[2][1]=*(xyz_list+3*0+1)+s2*(*(xyz_list+3*2+1)-*(xyz_list+3*0+1));
-			xyz_bis[2][2]=*(xyz_list+3*0+2)+s2*(*(xyz_list+3*2+2)-*(xyz_list+3*0+2));
-		}
-		else if(gl[0]*gl[2]>0){ //Nodes 0 and 2 are similar, so points must be found on segment 1-0 and 1-2
-			/*Coordinates of point 1: same as initial point 2*/
-			xyz_bis[1][0]=*(xyz_list+3*1+0);
-			xyz_bis[1][1]=*(xyz_list+3*1+1);
-			xyz_bis[1][2]=*(xyz_list+3*1+2);
-
-			/*Portion of the segments*/
-			s1=gl[1]/(gl[1]-gl[0]);
-			s2=gl[1]/(gl[1]-gl[2]);
-
-			/*New point 0*/
-			xyz_bis[0][0]=*(xyz_list+3*1+0)+s1*(*(xyz_list+3*0+0)-*(xyz_list+3*1+0));
-			xyz_bis[0][1]=*(xyz_list+3*1+1)+s1*(*(xyz_list+3*0+1)-*(xyz_list+3*1+1));
-			xyz_bis[0][2]=*(xyz_list+3*1+2)+s1*(*(xyz_list+3*0+2)-*(xyz_list+3*1+2));
-
-			/*New point 2*/
-			xyz_bis[2][0]=*(xyz_list+3*1+0)+s2*(*(xyz_list+3*2+0)-*(xyz_list+3*1+0));
-			xyz_bis[2][1]=*(xyz_list+3*1+1)+s2*(*(xyz_list+3*2+1)-*(xyz_list+3*1+1));
-			xyz_bis[2][2]=*(xyz_list+3*1+2)+s2*(*(xyz_list+3*2+2)-*(xyz_list+3*1+2));
-		}
-
-		/*Compute fraction of grounded element*/
-		GetJacobianDeterminant(&area_init, xyz_list,NULL);
-		GetJacobianDeterminant(&area_grounded, &xyz_bis[0][0],NULL);
-		if(mainlyfloating==true) area_grounded=area_init-area_grounded;
-		phi=area_grounded/area_init;
-	}
+	if(domaintype==Domain2DverticalEnum){
+		this->EdgeOnBaseIndices(&index1,&index2);
+		if(gl[index1]>0 && gl[index2]>0) phi=1; // All grounded
+		else if(gl[index1]<0 && gl[index2]<0) phi=0; // All floating
+		else if(gl[index1]<0 && gl[index2]>0){ //index2 grounded
+			phi=1./(1.-gl[index1]/gl[index2]);
+		}
+		else if(gl[index2]<0 && gl[index1]>0){ //index1 grounded
+			phi=1./(1.-gl[index2]/gl[index1]);
+		}
+
+	}
+	else if(domaintype==Domain2DhorizontalEnum || domaintype==Domain3DEnum){
+		/*Check that not all nodes are grounded or floating*/
+		if(gl[0]>0 && gl[1]>0 && gl[2]>0){ // All grounded
+			phi=1;
+		}
+		else if(gl[0]<0 && gl[1]<0 && gl[2]<0){ //All floating
+			phi=0;
+		}
+		else{
+			/*Figure out if two nodes are floating or grounded*/
+			if(gl[0]*gl[1]*gl[2]>0) mainlyfloating=false;
+
+			if(gl[0]*gl[1]>0){ //Nodes 0 and 1 are similar, so points must be found on segment 0-2 and 1-2
+				/*Coordinates of point 2: same as initial point 2*/
+				xyz_bis[2][0]=*(xyz_list+3*2+0);
+				xyz_bis[2][1]=*(xyz_list+3*2+1);
+				xyz_bis[2][2]=*(xyz_list+3*2+2);
+
+				/*Portion of the segments*/
+				s1=gl[2]/(gl[2]-gl[1]);
+				s2=gl[2]/(gl[2]-gl[0]);
+
+				/*New point 1*/
+				xyz_bis[1][0]=*(xyz_list+3*2+0)+s1*(*(xyz_list+3*1+0)-*(xyz_list+3*2+0));
+				xyz_bis[1][1]=*(xyz_list+3*2+1)+s1*(*(xyz_list+3*1+1)-*(xyz_list+3*2+1));
+				xyz_bis[1][2]=*(xyz_list+3*2+2)+s1*(*(xyz_list+3*1+2)-*(xyz_list+3*2+2));
+
+				/*New point 0*/
+				xyz_bis[0][0]=*(xyz_list+3*2+0)+s2*(*(xyz_list+3*0+0)-*(xyz_list+3*2+0));
+				xyz_bis[0][1]=*(xyz_list+3*2+1)+s2*(*(xyz_list+3*0+1)-*(xyz_list+3*2+1));
+				xyz_bis[0][2]=*(xyz_list+3*2+2)+s2*(*(xyz_list+3*0+2)-*(xyz_list+3*2+2));
+			}
+			else if(gl[1]*gl[2]>0){ //Nodes 1 and 2 are similar, so points must be found on segment 0-1 and 0-2
+				/*Coordinates of point 0: same as initial point 2*/
+				xyz_bis[0][0]=*(xyz_list+3*0+0);
+				xyz_bis[0][1]=*(xyz_list+3*0+1);
+				xyz_bis[0][2]=*(xyz_list+3*0+2);
+
+				/*Portion of the segments*/
+				s1=gl[0]/(gl[0]-gl[1]);
+				s2=gl[0]/(gl[0]-gl[2]);
+
+				/*New point 1*/
+				xyz_bis[1][0]=*(xyz_list+3*0+0)+s1*(*(xyz_list+3*1+0)-*(xyz_list+3*0+0));
+				xyz_bis[1][1]=*(xyz_list+3*0+1)+s1*(*(xyz_list+3*1+1)-*(xyz_list+3*0+1));
+				xyz_bis[1][2]=*(xyz_list+3*0+2)+s1*(*(xyz_list+3*1+2)-*(xyz_list+3*0+2));
+
+				/*New point 2*/
+				xyz_bis[2][0]=*(xyz_list+3*0+0)+s2*(*(xyz_list+3*2+0)-*(xyz_list+3*0+0));
+				xyz_bis[2][1]=*(xyz_list+3*0+1)+s2*(*(xyz_list+3*2+1)-*(xyz_list+3*0+1));
+				xyz_bis[2][2]=*(xyz_list+3*0+2)+s2*(*(xyz_list+3*2+2)-*(xyz_list+3*0+2));
+			}
+			else if(gl[0]*gl[2]>0){ //Nodes 0 and 2 are similar, so points must be found on segment 1-0 and 1-2
+				/*Coordinates of point 1: same as initial point 2*/
+				xyz_bis[1][0]=*(xyz_list+3*1+0);
+				xyz_bis[1][1]=*(xyz_list+3*1+1);
+				xyz_bis[1][2]=*(xyz_list+3*1+2);
+
+				/*Portion of the segments*/
+				s1=gl[1]/(gl[1]-gl[0]);
+				s2=gl[1]/(gl[1]-gl[2]);
+
+				/*New point 0*/
+				xyz_bis[0][0]=*(xyz_list+3*1+0)+s1*(*(xyz_list+3*0+0)-*(xyz_list+3*1+0));
+				xyz_bis[0][1]=*(xyz_list+3*1+1)+s1*(*(xyz_list+3*0+1)-*(xyz_list+3*1+1));
+				xyz_bis[0][2]=*(xyz_list+3*1+2)+s1*(*(xyz_list+3*0+2)-*(xyz_list+3*1+2));
+
+				/*New point 2*/
+				xyz_bis[2][0]=*(xyz_list+3*1+0)+s2*(*(xyz_list+3*2+0)-*(xyz_list+3*1+0));
+				xyz_bis[2][1]=*(xyz_list+3*1+1)+s2*(*(xyz_list+3*2+1)-*(xyz_list+3*1+1));
+				xyz_bis[2][2]=*(xyz_list+3*1+2)+s2*(*(xyz_list+3*2+2)-*(xyz_list+3*1+2));
+			}
+
+			/*Compute fraction of grounded element*/
+			GetJacobianDeterminant(&area_init, xyz_list,NULL);
+			GetJacobianDeterminant(&area_grounded, &xyz_bis[0][0],NULL);
+			if(mainlyfloating==true) area_grounded=area_init-area_grounded;
+			phi=area_grounded/area_init;
+		}
+	}
+	else _error_("mesh type "<<EnumToStringx(domaintype)<<"not supported yet ");
 
 	if(phi>1 || phi<0) _error_("Error. Problem with portion of grounded element: value should be between 0 and 1");
@@ -1148,6 +683,42 @@
 }
 /*}}}*/
-/*FUNCTION Tria::GetSegmentNormal {{{*/
-void Tria:: GetSegmentNormal(IssmDouble* normal,IssmDouble xyz_list[2][3]){
+/*FUNCTION Tria::GetVerticesCoordinatesBase(IssmDouble** pxyz_list){{{*/
+void Tria::GetVerticesCoordinatesBase(IssmDouble** pxyz_list){
+
+	int        indices[2];
+	IssmDouble xyz_list[NUMVERTICES][3];
+
+	/*Element XYZ list*/
+	::GetVerticesCoordinates(&xyz_list[0][0],this->vertices,NUMVERTICES);
+
+	/*Allocate Output*/
+	IssmDouble* xyz_list_edge = xNew<IssmDouble>(2*3);
+	this->EdgeOnBaseIndices(&indices[0],&indices[1]);
+	for(int i=0;i<2;i++) for(int j=0;j<2;j++) xyz_list_edge[i*3+j]=xyz_list[indices[i]][j];
+
+	/*Assign output pointer*/
+	*pxyz_list = xyz_list_edge;
+
+}/*}}}*/
+/*FUNCTION Tria::GetVerticesCoordinatesTop(IssmDouble** pxyz_list){{{*/
+void Tria::GetVerticesCoordinatesTop(IssmDouble** pxyz_list){
+
+	int        indices[2];
+	IssmDouble xyz_list[NUMVERTICES][3];
+
+	/*Element XYZ list*/
+	::GetVerticesCoordinates(&xyz_list[0][0],this->vertices,NUMVERTICES);
+
+	/*Allocate Output*/
+	IssmDouble* xyz_list_edge = xNew<IssmDouble>(2*3);
+	this->EdgeOnSurfaceIndices(&indices[0],&indices[1]);
+	for(int i=0;i<2;i++) for(int j=0;j<2;j++) xyz_list_edge[i*3+j]=xyz_list[indices[i]][j];
+
+	/*Assign output pointer*/
+	*pxyz_list = xyz_list_edge;
+
+}/*}}}*/
+/*FUNCTION Tria::NormalSection{{{*/
+void Tria::NormalSection(IssmDouble* normal,IssmDouble* xyz_list){
 
 	/*Build unit outward pointing vector*/
@@ -1155,6 +726,6 @@
 	IssmDouble norm;
 
-	vector[0]=xyz_list[1][0] - xyz_list[0][0];
-	vector[1]=xyz_list[1][1] - xyz_list[0][1];
+	vector[0]=xyz_list[1*3+0] - xyz_list[0*3+0];
+	vector[1]=xyz_list[1*3+1] - xyz_list[0*3+1];
 
 	norm=sqrt(vector[0]*vector[0] + vector[1]*vector[1]);
@@ -1164,7 +735,6 @@
 }
 /*}}}*/
-/*FUNCTION Tria::GetZeroLevelsetCoordinates{{{*/
-void Tria::GetZeroLevelsetCoordinates(IssmDouble* xyz_zero,IssmDouble xyz_list[3][3],int levelsetenum){
-	/*Computeportion of the element that is grounded*/ 
+/*FUNCTION Tria::ZeroLevelsetCoordinates{{{*/
+void Tria::ZeroLevelsetCoordinates(IssmDouble** pxyz_zero,IssmDouble* xyz_list,int levelsetenum){
 
 	int         normal_orientation=0;
@@ -1173,4 +743,5 @@
 
 	/*Recover parameters and values*/
+	IssmDouble* xyz_zero = xNew<IssmDouble>(2*3);
 	GetInputListOnVertices(&levelset[0],levelsetenum);
 
@@ -1180,14 +751,14 @@
 		s2=levelset[2]/(levelset[2]-levelset[0]);
 
-		if(levelset[2]>0.) normal_orientation=1;
+		if(levelset[2]<0.) normal_orientation=1; //orientation of quadrangle depending on distribution of levelsetfunction
 		/*New point 1*/
-		xyz_zero[3*normal_orientation+0]=xyz_list[2][0]+s1*(xyz_list[1][0]-xyz_list[2][0]);
-		xyz_zero[3*normal_orientation+1]=xyz_list[2][1]+s1*(xyz_list[1][1]-xyz_list[2][1]);
-		xyz_zero[3*normal_orientation+2]=xyz_list[2][2]+s1*(xyz_list[1][2]-xyz_list[2][2]);
+		xyz_zero[3*normal_orientation+0]=xyz_list[2*3+0]+s1*(xyz_list[1*3+0]-xyz_list[2*3+0]);
+		xyz_zero[3*normal_orientation+1]=xyz_list[2*3+1]+s1*(xyz_list[1*3+1]-xyz_list[2*3+1]);
+		xyz_zero[3*normal_orientation+2]=xyz_list[2*3+2]+s1*(xyz_list[1*3+2]-xyz_list[2*3+2]);
 
 		/*New point 0*/
-		xyz_zero[3*(1-normal_orientation)+0]=xyz_list[2][0]+s2*(xyz_list[0][0]-xyz_list[2][0]);
-		xyz_zero[3*(1-normal_orientation)+1]=xyz_list[2][1]+s2*(xyz_list[0][1]-xyz_list[2][1]);
-		xyz_zero[3*(1-normal_orientation)+2]=xyz_list[2][2]+s2*(xyz_list[0][2]-xyz_list[2][2]);
+		xyz_zero[3*(1-normal_orientation)+0]=xyz_list[2*3+0]+s2*(xyz_list[0*3+0]-xyz_list[2*3+0]);
+		xyz_zero[3*(1-normal_orientation)+1]=xyz_list[2*3+1]+s2*(xyz_list[0*3+1]-xyz_list[2*3+1]);
+		xyz_zero[3*(1-normal_orientation)+2]=xyz_list[2*3+2]+s2*(xyz_list[0*3+2]-xyz_list[2*3+2]);
 	}
 	else if(levelset[1]*levelset[2]>0.){ //Nodes 1 and 2 are similar, so points must be found on segment 0-1 and 0-2
@@ -1196,14 +767,14 @@
 		s2=levelset[0]/(levelset[0]-levelset[1]);
 
-		if(levelset[0]>0.) normal_orientation=1;
+		if(levelset[0]<0.) normal_orientation=1;
 		/*New point 1*/
-		xyz_zero[3*normal_orientation+0]=xyz_list[0][0]+s1*(xyz_list[2][0]-xyz_list[0][0]);
-		xyz_zero[3*normal_orientation+1]=xyz_list[0][1]+s1*(xyz_list[2][1]-xyz_list[0][1]);
-		xyz_zero[3*normal_orientation+2]=xyz_list[0][2]+s1*(xyz_list[2][2]-xyz_list[0][2]);
+		xyz_zero[3*normal_orientation+0]=xyz_list[0*3+0]+s1*(xyz_list[2*3+0]-xyz_list[0*3+0]);
+		xyz_zero[3*normal_orientation+1]=xyz_list[0*3+1]+s1*(xyz_list[2*3+1]-xyz_list[0*3+1]);
+		xyz_zero[3*normal_orientation+2]=xyz_list[0*3+2]+s1*(xyz_list[2*3+2]-xyz_list[0*3+2]);
 
 		/*New point 2*/
-		xyz_zero[3*(1-normal_orientation)+0]=xyz_list[0][0]+s2*(xyz_list[1][0]-xyz_list[0][0]);
-		xyz_zero[3*(1-normal_orientation)+1]=xyz_list[0][1]+s2*(xyz_list[1][1]-xyz_list[0][1]);
-		xyz_zero[3*(1-normal_orientation)+2]=xyz_list[0][2]+s2*(xyz_list[1][2]-xyz_list[0][2]);
+		xyz_zero[3*(1-normal_orientation)+0]=xyz_list[0*3+0]+s2*(xyz_list[1*3+0]-xyz_list[0*3+0]);
+		xyz_zero[3*(1-normal_orientation)+1]=xyz_list[0*3+1]+s2*(xyz_list[1*3+1]-xyz_list[0*3+1]);
+		xyz_zero[3*(1-normal_orientation)+2]=xyz_list[0*3+2]+s2*(xyz_list[1*3+2]-xyz_list[0*3+2]);
 	}
 	else if(levelset[0]*levelset[2]>0.){ //Nodes 0 and 2 are similar, so points must be found on segment 1-0 and 1-2
@@ -1212,48 +783,123 @@
 		s2=levelset[1]/(levelset[1]-levelset[2]);
 
-		if(levelset[1]>0.) normal_orientation=1;
+		if(levelset[1]<0.) normal_orientation=1;
 		/*New point 0*/
-		xyz_zero[3*normal_orientation+0]=xyz_list[1][0]+s1*(xyz_list[0][0]-xyz_list[1][0]);
-		xyz_zero[3*normal_orientation+1]=xyz_list[1][1]+s1*(xyz_list[0][1]-xyz_list[1][1]);
-		xyz_zero[3*normal_orientation+2]=xyz_list[1][2]+s1*(xyz_list[0][2]-xyz_list[1][2]);
+		xyz_zero[3*normal_orientation+0]=xyz_list[1*3+0]+s1*(xyz_list[0*3+0]-xyz_list[1*3+0]);
+		xyz_zero[3*normal_orientation+1]=xyz_list[1*3+1]+s1*(xyz_list[0*3+1]-xyz_list[1*3+1]);
+		xyz_zero[3*normal_orientation+2]=xyz_list[1*3+2]+s1*(xyz_list[0*3+2]-xyz_list[1*3+2]);
 
 		/*New point 2*/
-		xyz_zero[3*(1-normal_orientation)+0]=xyz_list[1][0]+s2*(xyz_list[2][0]-xyz_list[1][0]);
-		xyz_zero[3*(1-normal_orientation)+1]=xyz_list[1][1]+s2*(xyz_list[2][1]-xyz_list[1][1]);
-		xyz_zero[3*(1-normal_orientation)+2]=xyz_list[1][2]+s2*(xyz_list[2][2]-xyz_list[1][2]);
+		xyz_zero[3*(1-normal_orientation)+0]=xyz_list[1*3+0]+s2*(xyz_list[2*3+0]-xyz_list[1*3+0]);
+		xyz_zero[3*(1-normal_orientation)+1]=xyz_list[1*3+1]+s2*(xyz_list[2*3+1]-xyz_list[1*3+1]);
+		xyz_zero[3*(1-normal_orientation)+2]=xyz_list[1*3+2]+s2*(xyz_list[2*3+2]-xyz_list[1*3+2]);
 	}
 	else if(levelset[0]==0. && levelset[1]==0.){ //front is on point 0 and 1
-		xyz_zero[3*0+0]=xyz_list[0][0];
-		xyz_zero[3*0+1]=xyz_list[0][1];
-		xyz_zero[3*0+2]=xyz_list[0][2];
+		xyz_zero[3*0+0]=xyz_list[0*3+0];
+		xyz_zero[3*0+1]=xyz_list[0*3+1];
+		xyz_zero[3*0+2]=xyz_list[0*3+2];
 
 		/*New point 2*/
-		xyz_zero[3*1+0]=xyz_list[1][0];
-		xyz_zero[3*1+1]=xyz_list[1][1];
-		xyz_zero[3*1+2]=xyz_list[1][2];
+		xyz_zero[3*1+0]=xyz_list[1*3+0];
+		xyz_zero[3*1+1]=xyz_list[1*3+1];
+		xyz_zero[3*1+2]=xyz_list[1*3+2];
 	}
 	else if(levelset[0]==0. && levelset[2]==0.){ //front is on point 0 and 1
-		xyz_zero[3*0+0]=xyz_list[2][0];
-		xyz_zero[3*0+1]=xyz_list[2][1];
-		xyz_zero[3*0+2]=xyz_list[2][2];
+		xyz_zero[3*0+0]=xyz_list[2*3+0];
+		xyz_zero[3*0+1]=xyz_list[2*3+1];
+		xyz_zero[3*0+2]=xyz_list[2*3+2];
 
 		/*New point 2*/
-		xyz_zero[3*1+0]=xyz_list[0][0];
-		xyz_zero[3*1+1]=xyz_list[0][1];
-		xyz_zero[3*1+2]=xyz_list[0][2];
+		xyz_zero[3*1+0]=xyz_list[0*3+0];
+		xyz_zero[3*1+1]=xyz_list[0*3+1];
+		xyz_zero[3*1+2]=xyz_list[0*3+2];
 	}
 	else if(levelset[1]==0. && levelset[2]==0.){ //front is on point 0 and 1
-		xyz_zero[3*0+0]=xyz_list[1][0];
-		xyz_zero[3*0+1]=xyz_list[1][1];
-		xyz_zero[3*0+2]=xyz_list[1][2];
+		xyz_zero[3*0+0]=xyz_list[1*3+0];
+		xyz_zero[3*0+1]=xyz_list[1*3+1];
+		xyz_zero[3*0+2]=xyz_list[1*3+2];
 
 		/*New point 2*/
-		xyz_zero[3*1+0]=xyz_list[2][0];
-		xyz_zero[3*1+1]=xyz_list[2][1];
-		xyz_zero[3*1+2]=xyz_list[2][2];
+		xyz_zero[3*1+0]=xyz_list[2*3+0];
+		xyz_zero[3*1+1]=xyz_list[2*3+1];
+		xyz_zero[3*1+2]=xyz_list[2*3+2];
 	}
 	else _error_("Case not covered");
-}
-/*}}}*/
+
+	/*Assign output pointer*/
+	*pxyz_zero= xyz_zero;
+}
+/*}}}*/
+void  Tria::GetIcefrontCoordinates(IssmDouble** pxyz_front,IssmDouble* xyz_list,int levelsetenum){/*{{{*/
+	
+	/* Intermediaries */
+	int i, dir,nrfrontnodes;
+	IssmDouble  levelset[NUMVERTICES];
+
+	/*Recover parameters and values*/
+	GetInputListOnVertices(&levelset[0],levelsetenum);
+
+	int* indicesfront = xNew<int>(NUMVERTICES);
+	/* Get nodes where there is no ice */
+	nrfrontnodes=0;
+	for(i=0;i<NUMVERTICES;i++){
+		if(levelset[i]>=0.){
+			indicesfront[nrfrontnodes]=i;
+			nrfrontnodes++;
+		}
+	}
+
+	_assert_(nrfrontnodes==2);
+
+	/* arrange order of frontnodes such that they are oriented counterclockwise */
+	if((NUMVERTICES+indicesfront[0]-indicesfront[1])%NUMVERTICES!=NUMVERTICES-1){
+		int index=indicesfront[0];
+		indicesfront[0]=indicesfront[1];
+		indicesfront[1]=index;
+	}	
+
+	IssmDouble* xyz_front = xNew<IssmDouble>(3*nrfrontnodes);
+	/* Return nodes */
+	for(i=0;i<nrfrontnodes;i++){
+		for(dir=0;dir<3;dir++){
+			xyz_front[3*i+dir]=xyz_list[3*indicesfront[i]+dir];
+		}
+	}
+
+	*pxyz_front=xyz_front;
+
+	xDelete<int>(indicesfront);
+}/*}}}*/
+void  Tria::GetNormalFromLSF(IssmDouble *pnormal){/*{{{*/
+
+	/* Intermediaries */
+	int         i;
+	const int   dim=2;
+	IssmDouble* xyz_list = NULL;
+	IssmDouble  dlevelset[dim], norm_dlevelset;
+	IssmDouble  normal[dim]={0.};
+
+	/*Retrieve all inputs and parameters*/
+	Input* levelset_input=this->GetInput(MaskIceLevelsetEnum); _assert_(levelset_input);
+	this->GetVerticesCoordinates(&xyz_list);
+	
+	IssmDouble counter=0.;
+	Gauss* gauss = this->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		/* Get normal on node */
+		levelset_input->GetInputDerivativeValue(&dlevelset[0],xyz_list,gauss);
+		norm_dlevelset=0.;
+		for(i=0;i<dim;i++) norm_dlevelset+=dlevelset[i]*dlevelset[i]; 
+		norm_dlevelset=sqrt(norm_dlevelset)+1.e-14;
+		for(i=0;i<dim;i++) normal[i]+=dlevelset[i]/norm_dlevelset;
+		counter++;
+	}
+	_assert_(counter>0.);
+	for(i=0;i<dim;i++) normal[i] = normal[i]/counter;
+	
+	pnormal=&normal[0];
+
+	delete gauss;
+	xDelete<IssmDouble>(xyz_list);
+}/*}}}*/
 /*FUNCTION Tria::GetNodeIndex {{{*/
 int Tria::GetNodeIndex(Node* node){
@@ -1267,28 +913,4 @@
 }
 /*}}}*/
-/*FUNCTION Tria::GetNodesSidList{{{*/
-void Tria::GetNodesSidList(int* sidlist){
-
-	_assert_(sidlist);
-	_assert_(nodes);
-	int numnodes = this->NumberofNodes();
-
-	for(int i=0;i<numnodes;i++){
-		sidlist[i]=nodes[i]->Sid();
-	}
-}
-/*}}}*/
-/*FUNCTION Tria::GetNodesLidList{{{*/
-void Tria::GetNodesLidList(int* lidlist){
-
-	_assert_(lidlist);
-	_assert_(nodes);
-	int numnodes = this->NumberofNodes();
-
-	for(int i=0;i<numnodes;i++){
-		lidlist[i]=nodes[i]->Lid();
-	}
-}
-/*}}}*/
 /*FUNCTION Tria::GetNumberOfNodes;{{{*/
 int Tria::GetNumberOfNodes(void){
@@ -1296,107 +918,7 @@
 }
 /*}}}*/
-/*FUNCTION Tria::GetInputListOnVertices(IssmDouble* pvalue,int enumtype) {{{*/
-void Tria::GetInputListOnVertices(IssmDouble* pvalue,int enumtype){
-
-	/*Recover input*/
-	Input* input=inputs->GetInput(enumtype);
-	if (!input) _error_("Input " << EnumToStringx(enumtype) << " not found in element");
-
-	/*Checks in debugging mode*/
-	_assert_(pvalue);
-
-	/* Start looping on the number of vertices: */
-	GaussTria* gauss=new GaussTria();
-	for (int iv=0;iv<NUMVERTICES;iv++){
-		gauss->GaussVertex(iv);
-		input->GetInputValue(&pvalue[iv],gauss);
-	}
-
-	/*clean-up*/
-	delete gauss;
-}
-/*}}}*/
-/*FUNCTION Tria::GetInputListOnVertices(IssmDouble* pvalue,int enumtype,IssmDouble defaultvalue) {{{*/
-void Tria::GetInputListOnVertices(IssmDouble* pvalue,int enumtype,IssmDouble defaultvalue){
-
-	Input     *input = inputs->GetInput(enumtype);
-
-	/*Checks in debugging mode*/
-	_assert_(pvalue);
-
-	/* Start looping on the number of vertices: */
-	if (input){
-		GaussTria* gauss=new GaussTria();
-		for (int iv=0;iv<NUMVERTICES;iv++){
-			gauss->GaussVertex(iv);
-			input->GetInputValue(&pvalue[iv],gauss);
-		}
-		delete gauss;
-	}
-	else{
-		for (int iv=0;iv<NUMVERTICES;iv++) pvalue[iv]=defaultvalue;
-	}
-}
-/*}}}*/
-/*FUNCTION Tria::GetInputListOnVertices(IssmDouble* pvalue,int enumtype,IssmDouble defaultvalue,int index) TO BE REMOVED{{{*/
-void Tria::GetInputListOnVertices(IssmDouble* pvalue,int enumtype,IssmDouble defaultvalue,int index){
-
-	Input     *input = inputs->GetInput(enumtype);
-
-	/*Checks in debugging mode*/
-	_assert_(pvalue);
-
-	/* Start looping on the number of vertices: */
-	if (input){
-		GaussTria* gauss=new GaussTria();
-		for (int iv=0;iv<NUMVERTICES;iv++){
-			gauss->GaussVertex(iv);
-			input->GetInputValue(&pvalue[iv],gauss,index);
-		}
-		delete gauss;
-	}
-	else{
-		for (int iv=0;iv<NUMVERTICES;iv++) pvalue[iv]=defaultvalue;
-	}
-}
-/*}}}*/
-/*FUNCTION Tria::GetInputListOnNodes(IssmDouble* pvalue,int enumtype,IssmDouble defaultvalue) {{{*/
-void Tria::GetInputListOnNodes(IssmDouble* pvalue,int enumtype,IssmDouble defaultvalue){
-
-	_assert_(pvalue);
-
-	Input *input    = inputs->GetInput(enumtype);
-	int    numnodes = this->NumberofNodes();
-
-	/* Start looping on the number of vertices: */
-	if(input){
-		GaussTria* gauss=new GaussTria();
-		for(int iv=0;iv<this->NumberofNodes();iv++){
-			gauss->GaussNode(this->element_type,iv);
-			input->GetInputValue(&pvalue[iv],gauss);
-		}
-		delete gauss;
-	}
-	else{
-		for(int iv=0;iv<numnodes;iv++) pvalue[iv]=defaultvalue;
-	}
-}
-/*}}}*/
-/*FUNCTION Tria::GetInputListOnNodes(IssmDouble* pvalue,int enumtype) {{{*/
-void Tria::GetInputListOnNodes(IssmDouble* pvalue,int enumtype){
-
-	_assert_(pvalue);
-
-	/*Recover input*/
-	Input* input=inputs->GetInput(enumtype);
-	if(!input) _error_("Input " << EnumToStringx(enumtype) << " not found in element");
-
-	/* Start looping on the number of vertices: */
-	GaussTria* gauss=new GaussTria();
-	for (int iv=0;iv<this->NumberofNodes();iv++){
-		gauss->GaussNode(this->element_type,iv);
-		input->GetInputValue(&pvalue[iv],gauss);
-	}
-	delete gauss;
+/*FUNCTION Tria::GetNumberOfVertices;{{{*/
+int Tria::GetNumberOfVertices(void){
+	return NUMVERTICES;
 }
 /*}}}*/
@@ -1414,135 +936,40 @@
 }
 /*}}}*/
-/*FUNCTION Tria::GetMaterialInputValue(IssmDouble* pvalue,Node* node,int enumtype) {{{*/
-void Tria::GetMaterialInputValue(IssmDouble* pvalue,Node* node,int enumtype){
-
-	Input* input=this->material->inputs->GetInput(enumtype);
-	if(!input) _error_("No input of type " << EnumToStringx(enumtype) << " found in tria");
-
-	GaussTria* gauss=new GaussTria();
-	gauss->GaussVertex(this->GetNodeIndex(node));
-
-	input->GetInputValue(pvalue,gauss);
-	delete gauss;
-}
-/*}}}*/
-/*FUNCTION Tria::GetVertexPidList {{{*/
-void  Tria::GetVertexPidList(int* doflist){
-
-	for(int i=0;i<3;i++) doflist[i]=vertices[i]->Pid();
-
-}
-/*}}}*/
-/*FUNCTION Tria::GetVertexSidList {{{*/
-void  Tria::GetVertexSidList(int* sidlist){
-	for(int i=0;i<NUMVERTICES;i++) sidlist[i]=vertices[i]->Sid();
-}
-/*}}}*/
-/*FUNCTION Tria::GetConnectivityList {{{*/
-void  Tria::GetConnectivityList(int* connectivity){
-	for(int i=0;i<NUMVERTICES;i++) connectivity[i]=vertices[i]->Connectivity();
-}
-/*}}}*/
-/*FUNCTION Tria::GetSolutionFromInputs{{{*/
-void  Tria::GetSolutionFromInputs(Vector<IssmDouble>* solution){
-
-	/*retrive parameters: */
-	int analysis_type;
-	parameters->FindParam(&analysis_type,AnalysisTypeEnum);
-
-	/*Just branch to the correct InputUpdateFromSolution generator, according to the type of analysis we are carrying out: */
-	switch(analysis_type){
-	#ifdef _HAVE_STRESSBALANCE_
-	case StressbalanceAnalysisEnum:
-		int approximation;
-		inputs->GetInputValue(&approximation,ApproximationEnum);
-		if(approximation==FSApproximationEnum || approximation==NoneApproximationEnum){
-			GetSolutionFromInputsStressbalanceFS(solution);
-		}
-		else if (approximation==SSAApproximationEnum || approximation==SIAApproximationEnum){
-			GetSolutionFromInputsStressbalanceHoriz(solution);
-		}
-		else{
-			_error_("approximation not supported yet");
-		}
-		break;
-	case StressbalanceSIAAnalysisEnum:
-		GetSolutionFromInputsStressbalanceSIA(solution);
-		break;
-	#endif
-	#ifdef _HAVE_HYDROLOGY_
-	case HydrologyShreveAnalysisEnum:
-		GetSolutionFromInputsOneDof(solution,WatercolumnEnum);
-		break;
-	case HydrologyDCInefficientAnalysisEnum:
-		GetSolutionFromInputsOneDof(solution,SedimentHeadEnum);
-		break;
-	case HydrologyDCEfficientAnalysisEnum:
-		GetSolutionFromInputsOneDof(solution,EplHeadEnum);
-		break;
-	#endif
-	default:
-		_error_("analysis: " << EnumToStringx(analysis_type) << " not supported yet");
-	}
-
-}
-/*}}}*/
-/*FUNCTION Tria::GetStrainRate2d(IssmDouble* epsilon,IssmDouble* xyz_list, GaussTria* gauss, Input* vx_input, Input* vy_input){{{*/
-void Tria::GetStrainRate2d(IssmDouble* epsilon,IssmDouble* xyz_list, GaussTria* gauss, Input* vx_input, Input* vy_input){
-	/*Compute the 2d Strain Rate (3 components):
-	 * epsilon=[exx eyy exy] */
-
-	int i;
-	IssmDouble epsilonvx[3];
-	IssmDouble epsilonvy[3];
-
-	/*Check that both inputs have been found*/
-	if (!vx_input || !vy_input){
-		_error_("Input missing. Here are the input pointers we have for vx: " << vx_input << ", vy: " << vy_input << "\n");
-	}
-
-	/*Get strain rate assuming that epsilon has been allocated*/
-	vx_input->GetVxStrainRate2d(epsilonvx,xyz_list,gauss);
-	vy_input->GetVyStrainRate2d(epsilonvy,xyz_list,gauss);
-
-	/*Sum all contributions*/
-	for(i=0;i<3;i++) epsilon[i]=epsilonvx[i]+epsilonvy[i];
-}
-/*}}}*/
-/*FUNCTION Tria::GetVectorFromInputs{{{*/
-void  Tria::GetVectorFromInputs(Vector<IssmDouble>* vector,int input_enum){
-
-	int vertexpidlist[NUMVERTICES];
-
-	/*Get out if this is not an element input*/
-	if(!IsInput(input_enum)) return;
-
-	/*Prepare index list*/
-	this->GetVertexPidList(&vertexpidlist[0]);
-
-	/*Get input (either in element or material)*/
-	Input* input=inputs->GetInput(input_enum);
-	if(!input) _error_("Input " << EnumToStringx(input_enum) << " not found in element");
-
-	/*We found the enum.  Use its values to fill into the vector, using the vertices ids: */
-	input->GetVectorFromInputs(vector,&vertexpidlist[0]);
-}
-/*}}}*/
-/*FUNCTION Tria::Id {{{*/
-int    Tria::Id(){
-
-	return id;
-
-}
-/*}}}*/
-/*FUNCTION Tria::Sid {{{*/
-int    Tria::Sid(){
-
-	return sid;
-
+Node* Tria::GetNode(int node_number){/*{{{*/
+	_assert_(node_number>=0); 
+	_assert_(node_number<this->NumberofNodes()); 
+	return this->nodes[node_number];
+
+}/*}}}*/
+/*FUNCTION Tria::GetXcoord {{{*/
+IssmDouble Tria::GetXcoord(Gauss* gauss){
+
+	IssmDouble x;
+	IssmDouble xyz_list[NUMVERTICES][3];
+	IssmDouble x_list[NUMVERTICES];
+
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	for(int i=0;i<NUMVERTICES;i++) x_list[i]=xyz_list[i][0];
+	TriaRef::GetInputValue(&x,x_list,gauss,P1Enum);
+
+	return x;
+}
+/*}}}*/
+/*FUNCTION Tria::GetYcoord {{{*/
+IssmDouble Tria::GetYcoord(Gauss* gauss){
+
+	IssmDouble y;
+	IssmDouble xyz_list[NUMVERTICES][3];
+	IssmDouble y_list[NUMVERTICES];
+
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	for(int i=0;i<NUMVERTICES;i++) y_list[i]=xyz_list[i][1];
+	TriaRef::GetInputValue(&y,y_list,gauss,P1Enum);
+
+	return y;
 }
 /*}}}*/
 /*FUNCTION Tria::InputDepthAverageAtBase {{{*/
-void  Tria::InputDepthAverageAtBase(int enum_type,int average_enum_type,int object_enum){
+void  Tria::InputDepthAverageAtBase(int enum_type,int average_enum_type){
 
 	/*New input*/
@@ -1551,10 +978,5 @@
 
 	/*copy input of enum_type*/
-	if (object_enum==MeshElementsEnum)
-	 oldinput=(Input*)this->inputs->GetInput(enum_type);
-	else if (object_enum==MaterialsEnum)
-	 oldinput=(Input*)this->material->inputs->GetInput(enum_type);
-	else
-	 _error_("object " << EnumToStringx(object_enum) << " not supported yet");
+	oldinput=(Input*)this->inputs->GetInput(enum_type);
 	if(!oldinput)_error_("could not find old input with enum: " << EnumToStringx(enum_type));
 	newinput=(Input*)oldinput->copy();
@@ -1564,10 +986,5 @@
 
 	/*Add new input to current element*/
-	if (object_enum==MeshElementsEnum)
-	 this->inputs->AddInput((Input*)newinput);
-	else if (object_enum==MaterialsEnum)
-	 this->material->inputs->AddInput((Input*)newinput);
-	else
-	 _error_("object " << EnumToStringx(object_enum) << " not supported yet");
+	this->inputs->AddInput((Input*)newinput);
 }
 /*}}}*/
@@ -1576,6 +993,7 @@
 
 	/*Call inputs method*/
-	if (IsInput(original_enum)) inputs->DuplicateInput(original_enum,new_enum);
-
+	if (IsInput(original_enum)) {
+		inputs->DuplicateInput(original_enum,new_enum);
+	}
 }
 /*}}}*/
@@ -1591,34 +1009,4 @@
 	/*Scale: */
 	input->Scale(scale_factor);
-}
-/*}}}*/
-/*FUNCTION Tria::InputUpdateFromConstant(int value, int name);{{{*/
-void  Tria::InputUpdateFromConstant(int constant, int name){
-
-	/*Check that name is an element input*/
-	if(!IsInput(name)) return;
-
-	/*update input*/
-	this->inputs->AddInput(new IntInput(name,constant));
-}
-/*}}}*/
-/*FUNCTION Tria::InputUpdateFromConstant(IssmDouble value, int name);{{{*/
-void  Tria::InputUpdateFromConstant(IssmDouble constant, int name){
-
-	/*Check that name is an element input*/
-	if(!IsInput(name)) return;
-
-	/*update input*/
-	this->inputs->AddInput(new DoubleInput(name,constant));
-}
-/*}}}*/
-/*FUNCTION Tria::InputUpdateFromConstant(bool value, int name);{{{*/
-void  Tria::InputUpdateFromConstant(bool constant, int name){
-
-	/*Check that name is an element input*/
-	if(!IsInput(name)) return;
-
-	/*update input*/
-	this->inputs->AddInput(new BoolInput(name,constant));
 }
 /*}}}*/
@@ -1654,5 +1042,4 @@
 
 	/*Control Inputs*/
-	#ifdef _HAVE_CONTROL_
 	if (control_analysis && iomodel->Data(InversionControlParametersEnum)){
 		for(i=0;i<num_control_type;i++){
@@ -1698,7 +1085,20 @@
 					}
 					break;
-				/*Material will take care of it*/ 
-				case MaterialsRheologyBbarEnum:break;
-				case DamageDbarEnum: break;
+				case MaterialsRheologyBbarEnum:
+					if(iomodel->Data(MaterialsRheologyBEnum)){
+						for(j=0;j<3;j++) nodeinputs[j]=iomodel->Data(MaterialsRheologyBEnum)[tria_vertex_ids[j]-1];
+						for(j=0;j<3;j++)cmmininputs[j]=iomodel->Data(InversionMinParametersEnum)[(tria_vertex_ids[j]-1)*num_control_type+i];
+						for(j=0;j<3;j++)cmmaxinputs[j]=iomodel->Data(InversionMaxParametersEnum)[(tria_vertex_ids[j]-1)*num_control_type+i];
+						this->inputs->AddInput(new ControlInput(MaterialsRheologyBbarEnum,TriaInputEnum,nodeinputs,cmmininputs,cmmaxinputs,i+1));
+					}
+					break;
+				case DamageDbarEnum:
+					if(iomodel->Data(DamageDEnum)){
+						for(j=0;j<3;j++) nodeinputs[j]=iomodel->Data(DamageDEnum)[tria_vertex_ids[j]-1];
+						for(j=0;j<3;j++)cmmininputs[j]=iomodel->Data(InversionMinParametersEnum)[(tria_vertex_ids[j]-1)*num_control_type+i];
+						for(j=0;j<3;j++)cmmaxinputs[j]=iomodel->Data(InversionMaxParametersEnum)[(tria_vertex_ids[j]-1)*num_control_type+i];
+						this->inputs->AddInput(new ControlInput(DamageDbarEnum,TriaInputEnum,nodeinputs,cmmininputs,cmmaxinputs,i+1));
+					}
+					break;
 				default:
 					_error_("Control " << EnumToStringx(reCast<int,IssmDouble>(iomodel->Data(InversionControlParametersEnum)[i])) << " not implemented yet");
@@ -1706,5 +1106,4 @@
 		}
 	}
-	#endif
 
 	/*DatasetInputs*/
@@ -1723,91 +1122,4 @@
 }
 /*}}}*/
-/*FUNCTION Tria::InputUpdateFromSolution {{{*/
-void  Tria::InputUpdateFromSolution(IssmDouble* solution){
-
-	/*retrive parameters: */
-	int analysis_type,extrusioninput;
-	parameters->FindParam(&analysis_type,AnalysisTypeEnum);
-
-	/*Just branch to the correct InputUpdateFromSolution generator, according to the type of analysis we are carrying out: */
-	switch(analysis_type){
-		#ifdef _HAVE_STRESSBALANCE_
-		case StressbalanceAnalysisEnum:
-			int approximation;
-			inputs->GetInputValue(&approximation,ApproximationEnum);
-			if(approximation==FSApproximationEnum || approximation==NoneApproximationEnum){
-				InputUpdateFromSolutionStressbalanceFS(solution);
-			}
-			else if (approximation==SSAApproximationEnum || approximation==SIAApproximationEnum){
-				InputUpdateFromSolutionStressbalanceHoriz(solution);
-			}
-			else{
-				_error_("approximation not supported yet");
-			}
-			break;
-		case StressbalanceSIAAnalysisEnum:
-			InputUpdateFromSolutionStressbalanceHoriz(solution);
-			break;
-		#endif
-		#ifdef _HAVE_CONTROL_
-		case AdjointHorizAnalysisEnum:
-			InputUpdateFromSolutionAdjointHoriz(solution);
-			break;
-		case AdjointBalancethicknessAnalysisEnum:
-			InputUpdateFromSolutionOneDof(solution,AdjointEnum);
-			break;
-		#endif
-		#ifdef _HAVE_HYDROLOGY_ 
-		case HydrologyShreveAnalysisEnum:
-			InputUpdateFromSolutionHydrologyShreve(solution);
-			break;
-		case HydrologyDCInefficientAnalysisEnum:
-			InputUpdateFromSolutionHydrologyDCInefficient(solution);
-			break;
-		case HydrologyDCEfficientAnalysisEnum:
-			InputUpdateFromSolutionOneDof(solution,EplHeadEnum);
-			break;
-		#endif
-	 	#ifdef _HAVE_DAMAGE_
-		case DamageEvolutionAnalysisEnum:
-			InputUpdateFromSolutionDamageEvolution(solution);
-			break;
-		#endif
-	 	#ifdef _HAVE_BALANCED_
-		case BalancethicknessAnalysisEnum:
-			InputUpdateFromSolutionOneDof(solution,ThicknessEnum);
-			break;
-		case BalancevelocityAnalysisEnum:
-			InputUpdateFromSolutionOneDof(solution,VelEnum);
-			break;
-		case SmoothedSurfaceSlopeXAnalysisEnum:
-			InputUpdateFromSolutionOneDof(solution,SurfaceSlopeXEnum);
-			break;
-		case SmoothedSurfaceSlopeYAnalysisEnum:
-			InputUpdateFromSolutionOneDof(solution,SurfaceSlopeYEnum);
-			break;
-		#endif
-		case L2ProjectionBaseAnalysisEnum:
-			this->parameters->FindParam(&extrusioninput,InputToL2ProjectEnum);
-			InputUpdateFromSolutionOneDof(solution,extrusioninput);
-			break;
-		case MasstransportAnalysisEnum:
-			InputUpdateFromSolutionMasstransport(solution);
-			break;
-		case FreeSurfaceTopAnalysisEnum:
-			InputUpdateFromSolutionOneDof(solution,SurfaceEnum);
-			break;
-		case FreeSurfaceBaseAnalysisEnum:
-			InputUpdateFromSolutionOneDof(solution,BedEnum);
-			break;
-		case ExtrudeFromBaseAnalysisEnum: case ExtrudeFromTopAnalysisEnum:
-			this->parameters->FindParam(&extrusioninput,InputToExtrudeEnum);
-			InputUpdateFromSolutionOneDof(solution,extrusioninput);
-			break;
-		default:
-			_error_("analysis " << analysis_type << " (" << EnumToStringx(analysis_type) << ") not supported yet");
-	}
-}
-/*}}}*/
 /*FUNCTION Tria::InputUpdateFromSolutionOneDof{{{*/
 void  Tria::InputUpdateFromSolutionOneDof(IssmDouble* solution,int enum_type){
@@ -1834,80 +1146,4 @@
 	/*Free ressources:*/
 	xDelete<IssmDouble>(values);
-	xDelete<int>(doflist);
-}
-/*}}}*/
-/*FUNCTION Tria::InputUpdateFromSolutionMasstransport{{{*/
-void  Tria::InputUpdateFromSolutionMasstransport(IssmDouble* solution){
-
-	/*Intermediaries*/
-	int        i,hydroadjustment;
-	int*       doflist=NULL;
-	IssmDouble rho_ice,rho_water,minthickness;
-
-	/*Fetch number of nodes for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Fetch dof list and allocate solution vector*/
-	GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
-	IssmDouble* newthickness = xNew<IssmDouble>(numnodes);
-	IssmDouble* newbed       = xNew<IssmDouble>(numnodes);
-	IssmDouble* newsurface   = xNew<IssmDouble>(numnodes);
-	IssmDouble* oldthickness = xNew<IssmDouble>(numnodes);
-	IssmDouble* oldbed       = xNew<IssmDouble>(numnodes);
-	IssmDouble* oldsurface   = xNew<IssmDouble>(numnodes);
-	IssmDouble* phi          = xNew<IssmDouble>(numnodes);
-
-	/*Use the dof list to index into the solution vector: */
-	this->parameters->FindParam(&minthickness,MasstransportMinThicknessEnum);
-	for(i=0;i<numnodes;i++){
-		newthickness[i]=solution[doflist[i]];
-		if(xIsNan<IssmDouble>(newthickness[i])) _error_("NaN found in solution vector");
-		/*Constrain thickness to be at least 1m*/
-		if(newthickness[i]<minthickness) newthickness[i]=minthickness;
-	}
-
-	/*Get previous bed, thickness and surface*/
-	GetInputListOnNodes(&oldbed[0],BedEnum);
-	GetInputListOnNodes(&oldsurface[0],SurfaceEnum);
-	GetInputListOnNodes(&oldthickness[0],ThicknessEnum);
-	GetInputListOnNodes(&phi[0],MaskGroundediceLevelsetEnum);
-
-	/*Find MasstransportHydrostaticAdjustment to figure out how to update the geometry:*/
-	this->parameters->FindParam(&hydroadjustment,MasstransportHydrostaticAdjustmentEnum);
-	rho_ice=matpar->GetRhoIce();
-	rho_water=matpar->GetRhoWater();
-
-	for(i=0;i<numnodes;i++) {
-		/*If shelf: hydrostatic equilibrium*/
-		if (phi[i]>0.){
-			newsurface[i] = oldbed[i]+newthickness[i]; //surface = oldbed + newthickness
-			newbed[i]     = oldbed[i];                 //same bed: do nothing
-		}
-		else{ //this is an ice shelf
-			if(hydroadjustment==AbsoluteEnum){
-				newsurface[i] = newthickness[i]*(1-rho_ice/rho_water);
-				newbed[i]     = newthickness[i]*(-rho_ice/rho_water);
-			}
-			else if(hydroadjustment==IncrementalEnum){
-				newsurface[i] = oldsurface[i]+(1.0-rho_ice/rho_water)*(newthickness[i]-oldthickness[i]); //surface = oldsurface + (1-di) * dH
-				newbed[i]     = oldbed[i]-rho_ice/rho_water*(newthickness[i]-oldthickness[i]); //bed               = oldbed + di * dH
-			}
-			else _error_("Hydrostatic adjustment " << hydroadjustment << " (" << EnumToStringx(hydroadjustment) << ") not supported yet");
-		}
-	}
-
-	/*Add input to the element: */
-	this->inputs->AddInput(new TriaInput(ThicknessEnum,newthickness,P1Enum));
-	this->inputs->AddInput(new TriaInput(SurfaceEnum,newsurface,P1Enum));
-	this->inputs->AddInput(new TriaInput(BedEnum,newbed,P1Enum));
-
-	/*Free ressources:*/
-	xDelete<IssmDouble>(newthickness);
-	xDelete<IssmDouble>(newbed);
-	xDelete<IssmDouble>(newsurface);
-	xDelete<IssmDouble>(oldthickness);
-	xDelete<IssmDouble>(oldbed);
-	xDelete<IssmDouble>(oldsurface);
-	xDelete<IssmDouble>(phi);
 	xDelete<int>(doflist);
 }
@@ -1930,10 +1166,5 @@
 		}
 		/*update input*/
-		if (name==MaterialsRheologyBbarEnum || name==MaterialsRheologyBEnum || name==DamageDEnum || name==DamageDbarEnum){
-			material->inputs->AddInput(new TriaInput(name,values,P1Enum));
-		}
-		else{
-			this->inputs->AddInput(new TriaInput(name,values,P1Enum));
-		}
+		this->inputs->AddInput(new TriaInput(name,values,P1Enum));
 		break;
 
@@ -1944,10 +1175,5 @@
 		}
 		/*update input*/
-		if(name==MaterialsRheologyBbarEnum || name==MaterialsRheologyBEnum || name==DamageDEnum || name==DamageDbarEnum){
-			material->inputs->AddInput(new TriaInput(name,values,P1Enum));
-		}
-		else{
-			this->inputs->AddInput(new TriaInput(name,values,P1Enum));
-		}
+		this->inputs->AddInput(new TriaInput(name,values,P1Enum));
 		break;
 
@@ -1989,141 +1215,66 @@
 }
 /*}}}*/
-/*FUNCTION Tria::InputCreate(IssmDouble* vector,IoModel* iomodel,int M,int N,int vector_type,int vector_enum,int code){{{*/
-void Tria::InputCreate(IssmDouble* vector,IoModel* iomodel,int M,int N,int vector_type,int vector_enum,int code){
-
-	/*Intermediaries*/
-	int    i,t;
-	int    tria_vertex_ids[3];
-	int    row;
-	IssmDouble nodeinputs[3];
-	IssmDouble time;
-	TransientInput* transientinput=NULL;
-
-	/*Branch on type of vector: nodal or elementary: */
-	if(vector_type==1){ //nodal vector
-
-		/*Recover vertices ids needed to initialize inputs*/
-		for(i=0;i<3;i++){ 
-			_assert_(iomodel->elements);
-			tria_vertex_ids[i]=reCast<int>(iomodel->elements[3*this->sid+i]); //ids for vertices are in the elements array from Matlab
-		}
-
-		/*Are we in transient or static? */
-		if(M==iomodel->numberofvertices){
-
-			/*create input values: */
-			for(i=0;i<3;i++)nodeinputs[i]=vector[tria_vertex_ids[i]-1];
-
-			/*create static input: */
-			this->inputs->AddInput(new TriaInput(vector_enum,nodeinputs,P1Enum));
-		}
-		else if(M==iomodel->numberofvertices+1){
-			/*create transient input: */
-			for(t=0;t<N;t++){ //N is the number of times
-
-				/*create input values: */
-				for(i=0;i<3;i++){
-					row=tria_vertex_ids[i]-1;
-					nodeinputs[i]=vector[N*row+t];
-				}
-
-				/*time? :*/
-				time=vector[(M-1)*N+t];
-
-				if(t==0) transientinput=new TransientInput(vector_enum);
-				transientinput->AddTimeInput(new TriaInput(vector_enum,nodeinputs,P1Enum),time);
-			}
-			this->inputs->AddInput(transientinput);
-		}
-		else _error_("nodal vector is either numberofvertices or numberofvertices+1 long. Field provided (" << EnumToStringx(vector_enum) << ") is " << M << " long");
-	}
-	else if(vector_type==2){ //element vector
-		/*Are we in transient or static? */
-		if(M==iomodel->numberofelements){
-
-			/*static mode: create an input out of the element value: */
-
-			if (code==5){ //boolean
-				this->inputs->AddInput(new BoolInput(vector_enum,reCast<bool>(vector[this->sid])));
-			}
-			else if (code==6){ //integer
-				this->inputs->AddInput(new IntInput(vector_enum,reCast<int>(vector[this->sid])));
-			}
-			else if (code==7){ //IssmDouble
-				this->inputs->AddInput(new DoubleInput(vector_enum,vector[this->sid]));
-			}
-			else _error_("could not recognize nature of vector from code " << code);
-		}
-		else {
-			_error_("transient element inputs not supported yet!");
-		}
-	}
-	else{
-		_error_("Cannot add input for vector type " << vector_type << " (not supported)");
-	}
-
-}
-/*}}}*/
-/*FUNCTION Tria::IsInput{{{*/
-bool Tria::IsInput(int name){
-	if (
-				name==ThicknessEnum ||
-				name==SurfaceEnum ||
-				name==BathymetryEnum ||
-				name==BedEnum ||
-				name==MaskGroundediceLevelsetEnum ||
-				name==MaskIceLevelsetEnum ||
-				name==SurfaceSlopeXEnum ||
-				name==SurfaceSlopeYEnum ||
-				name==BasalforcingsMeltingRateEnum ||
-				name==WatercolumnEnum || 
-				name==SurfaceforcingsMassBalanceEnum ||
-				name==SurfaceAreaEnum||
-				name==VxEnum ||
-				name==VyEnum ||
-				name==PressureEnum ||
-				name==InversionVxObsEnum ||
-				name==InversionVyObsEnum ||
-				name==FrictionCoefficientEnum ||
-				name==MaterialsRheologyBbarEnum ||
-				name==DamageDbarEnum ||
-				name==GradientEnum ||
-				name==OldGradientEnum ||
-				name==ConvergedEnum ||
-				name==SedimentHeadOldEnum ||
-				name==SedimentHeadEnum ||
-				name==EplHeadOldEnum ||
-				name==EplHeadEnum ||
-				name==HydrologydcMaskEplactiveEnum ||
-				name==MeshVertexonbedEnum ||
-				name==WaterTransferEnum ||
-				name==QmuVxEnum ||
-				name==QmuVyEnum ||
-				name==QmuPressureEnum ||
-				name==QmuBedEnum ||
-				name==QmuThicknessEnum ||
-				name==QmuSurfaceEnum ||
-				name==QmuTemperatureEnum ||
-				name==QmuMeltingEnum || 
-				name==QmuMaskGroundediceLevelsetEnum ||
-				name==QmuMaskIceLevelsetEnum ||
-				name==GiaWEnum || 
-				name==GiadWdtEnum
-		){
-		return true;
-	}
-	else return false;
-}
-/*}}}*/
-/*FUNCTION Tria::IsOnBed {{{*/
-bool Tria::IsOnBed(){
-
-	bool onbed;
-	inputs->GetInputValue(&onbed,MeshElementonbedEnum);
-	return onbed;
-}
-/*}}}*/
-/*FUNCTION Tria::HasEdgeOnBed {{{*/
-bool Tria::HasEdgeOnBed(){
+/*FUNCTION Tria::IsOnBase {{{*/
+bool Tria::IsOnBase(){
+
+	int domaintype;
+	this->parameters->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DverticalEnum:
+			return HasEdgeOnBase();
+		case Domain2DhorizontalEnum:
+			return true;
+		default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
+	}
+}
+/*}}}*/
+/*FUNCTION Tria::IsOnSurface {{{*/
+bool Tria::IsOnSurface(){
+
+	int domaintype;
+	this->parameters->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DverticalEnum:
+			return HasEdgeOnSurface();
+		case Domain2DhorizontalEnum:
+			return true;
+		default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
+	}
+}
+/*}}}*/
+/*FUNCTION Tria::JacobianDeterminant{{{*/
+void Tria::JacobianDeterminant(IssmDouble* pJdet,IssmDouble* xyz_list,Gauss* gauss){
+
+	_assert_(gauss->Enum()==GaussTriaEnum);
+	this->GetJacobianDeterminant(pJdet,xyz_list,(GaussTria*)gauss);
+
+}
+/*}}}*/
+/*FUNCTION Tria::JacobianDeterminantBase{{{*/
+void Tria::JacobianDeterminantBase(IssmDouble* pJdet,IssmDouble* xyz_list_base,Gauss* gauss){
+
+	_assert_(gauss->Enum()==GaussTriaEnum);
+	this->GetSegmentJacobianDeterminant(pJdet,xyz_list_base,(GaussTria*)gauss);
+
+}
+/*}}}*/
+/*FUNCTION Tria::JacobianDeterminantSurface{{{*/
+void Tria::JacobianDeterminantSurface(IssmDouble* pJdet,IssmDouble* xyz_list,Gauss* gauss){
+
+	_assert_(gauss->Enum()==GaussTriaEnum);
+	this->GetSegmentJacobianDeterminant(pJdet,xyz_list,(GaussTria*)gauss);
+
+}
+/*}}}*/
+/*FUNCTION Tria::JacobianDeterminantTop{{{*/
+void Tria::JacobianDeterminantTop(IssmDouble* pJdet,IssmDouble* xyz_list_top,Gauss* gauss){
+
+	_assert_(gauss->Enum()==GaussTriaEnum);
+	this->GetSegmentJacobianDeterminant(pJdet,xyz_list_top,(GaussTria*)gauss);
+
+}
+/*}}}*/
+/*FUNCTION Tria::HasEdgeOnBase {{{*/
+bool Tria::HasEdgeOnBase(){
 
 	IssmDouble values[NUMVERTICES];
@@ -2131,5 +1282,5 @@
 
 	/*Retrieve all inputs and parameters*/
-	GetInputListOnVertices(&values[0],MeshVertexonbedEnum);
+	GetInputListOnVertices(&values[0],MeshVertexonbaseEnum);
 	sum = values[0]+values[1]+values[2];
 
@@ -2168,6 +1319,6 @@
 }
 /*}}}*/
-/*FUNCTION Tria::EdgeOnBedIndices{{{*/
-void Tria::EdgeOnBedIndices(int* pindex1,int* pindex2){
+/*FUNCTION Tria::EdgeOnBaseIndices{{{*/
+void Tria::EdgeOnBaseIndices(int* pindex1,int* pindex2){
 
 	IssmDouble values[NUMVERTICES];
@@ -2175,5 +1326,5 @@
 
 	/*Retrieve all inputs and parameters*/
-	GetInputListOnVertices(&values[0],MeshVertexonbedEnum);
+	GetInputListOnVertices(&values[0],MeshVertexonbaseEnum);
 
 	for(int i=0;i<3;i++){
@@ -2210,6 +1361,6 @@
 }
 /*}}}*/
-/*FUNCTION Tria::EdgeOnBedIndex{{{*/
-int Tria::EdgeOnBedIndex(void){
+/*FUNCTION Tria::EdgeOnBaseIndex{{{*/
+int Tria::EdgeOnBaseIndex(void){
 
 	IssmDouble values[NUMVERTICES];
@@ -2217,5 +1368,5 @@
 
 	/*Retrieve all inputs and parameters*/
-	GetInputListOnVertices(&values[0],MeshVertexonbedEnum);
+	GetInputListOnVertices(&values[0],MeshVertexonbaseEnum);
 
 	for(int i=0;i<3;i++){
@@ -2248,22 +1399,79 @@
 }
 /*}}}*/
-/*FUNCTION Tria::IsFloating {{{*/
-bool   Tria::IsFloating(){
-
-	bool shelf;
-	int  migration_style;
-	parameters->FindParam(&migration_style,GroundinglineMigrationEnum);
-
-	if(migration_style==SubelementMigrationEnum || migration_style==SubelementMigration2Enum){ //Floating if all nodes are floating
-		if(this->inputs->Max(MaskGroundediceLevelsetEnum) <= 0.) shelf=true;
-		else shelf=false;
-	}
-	else if(migration_style==NoneEnum || migration_style==AgressiveMigrationEnum || migration_style==SoftMigrationEnum){ //Floating if all nodes are floating
-		if(this->inputs->Min(MaskGroundediceLevelsetEnum) > 0.) shelf=false;
-		else shelf=true;
-	}
-	else _error_("migration_style not implemented yet");
-
-	return shelf;
+/*FUNCTION Tria::FSContactMigration{{{*/
+void Tria::FSContactMigration(Vector<IssmDouble>* vertexgrounded,Vector<IssmDouble>* vertexfloating){
+
+	if(!IsOnBase()) return;
+
+	/*Intermediaries*/
+	IssmDouble* xyz_list = NULL;
+	IssmDouble  pressure,water_pressure,sigma_nn,viscosity,bed,base;
+	IssmDouble  bed_normal[2];
+	IssmDouble  epsilon[3]; /* epsilon=[exx,eyy,exy];*/
+	IssmDouble  surface=0,value=0;
+	bool grounded;
+
+	/* Get node coordinates and dof list: */
+	GetVerticesCoordinates(&xyz_list);
+
+	/*Retrieve all inputs we will be needing: */
+	Input* pressure_input = inputs->GetInput(PressureEnum); _assert_(pressure_input);
+	Input* base_input     = inputs->GetInput(BaseEnum);     _assert_(base_input);
+	Input* bed_input      = inputs->GetInput(BedEnum);      _assert_(bed_input);
+	Input* vx_input       = inputs->GetInput(VxEnum);       _assert_(vx_input);
+	Input* vy_input       = inputs->GetInput(VyEnum);       _assert_(vy_input);
+
+	/*Create gauss point in the middle of the basal edge*/
+	Gauss* gauss=NewGaussBase(1);
+	gauss->GaussPoint(0);
+
+	if(!IsFloating()){ 
+		/*Check for basal force only if grounded and touching GL*/
+		if(this->inputs->Min(MaskGroundediceLevelsetEnum)==0.){
+			this->StrainRateSSA(&epsilon[0],xyz_list,gauss,vx_input,vy_input);
+			this->ViscosityFS(&viscosity,2,xyz_list,gauss,vx_input,vy_input,NULL);
+			pressure_input->GetInputValue(&pressure, gauss);
+			base_input->GetInputValue(&base, gauss); _assert_(base<0.);
+
+			/*Compute Stress*/
+			IssmDouble sigma_xx=2.*viscosity*epsilon[0]-pressure;
+			IssmDouble sigma_yy=2.*viscosity*epsilon[1]-pressure;
+			IssmDouble sigma_xy=2.*viscosity*epsilon[2];
+
+			/*Get normal vector to the bed */
+			NormalBase(&bed_normal[0],xyz_list);
+
+			/*basalforce*/
+			sigma_nn = sigma_xx*bed_normal[0]*bed_normal[0] + sigma_yy*bed_normal[1]*bed_normal[1] + 2.*sigma_xy*bed_normal[0]*bed_normal[1];
+
+			/*Compute water pressure*/
+			IssmDouble rho_ice   = matpar->GetRhoIce();
+			IssmDouble rho_water = matpar->GetRhoWater();
+			IssmDouble gravity   = matpar->GetG();
+			water_pressure=gravity*rho_water*base;
+
+			/*Compare basal stress to water pressure and determine whether it should ground*/
+			if (sigma_nn<water_pressure) grounded=true;
+			else                         grounded=false;
+		}
+		else{
+			grounded=true;
+		}
+	}
+	else{
+		/*Check for basal elevation if floating*/
+		base_input->GetInputValue(&base, gauss);
+		bed_input->GetInputValue(&bed, gauss);
+		if (base<bed) grounded=true;
+		else          grounded=false;
+	}
+	for(int i=0;i<NUMVERTICES;i++){
+		if(grounded) vertexgrounded->SetValue(vertices[i]->Pid(),+1.,INS_VAL);
+		else         vertexfloating->SetValue(vertices[i]->Pid(),+1.,INS_VAL);
+	}
+
+	/*clean up*/
+	delete gauss;
+	xDelete<IssmDouble>(xyz_list);
 }
 /*}}}*/
@@ -2283,16 +1491,98 @@
 }
 /*}}}*/
-/*FUNCTION Tria::NoIceInElement {{{*/
-bool   Tria::NoIceInElement(){
-
-	/*Get levelset*/
-	IssmDouble ls[NUMVERTICES];
-	GetInputListOnVertices(&ls[0],MaskIceLevelsetEnum);
-
-	/*If the level set is >0, ice is present in this element*/
-	if(ls[0]>0. || ls[1]>0. || ls[2]>0.) return false;
-
-	/*If the level set is awlays <=0, there is no ice here*/
-	return true;
+/*FUNCTION Tria::NewGauss(){{{*/
+Gauss* Tria::NewGauss(void){
+	return new GaussTria();
+}
+/*}}}*/
+/*FUNCTION Tria::NewGauss(int order){{{*/
+Gauss* Tria::NewGauss(int order){
+	return new GaussTria(order);
+}
+/*}}}*/
+/*FUNCTION Tria::NewGauss(IssmDouble* xyz_list, IssmDouble* xyz_list_front,int order){{{*/
+Gauss* Tria::NewGauss(IssmDouble* xyz_list, IssmDouble* xyz_list_front,int order){
+
+	IssmDouble  area_coordinates[2][3];
+	GetAreaCoordinates(&area_coordinates[0][0],xyz_list_front,xyz_list,2);
+	return new GaussTria(area_coordinates,order);
+}
+/*}}}*/
+/*FUNCTION Tria::NewGauss(int point1,IssmDouble fraction1,IssmDouble fraction2,bool mainlyfloating){{{*/
+Gauss* Tria::NewGauss(int point1,IssmDouble fraction1,IssmDouble fraction2,bool mainlyfloating,int order){
+
+	return new GaussTria(point1,fraction1,fraction2,mainlyfloating,order);
+}
+/*}}}*/
+/*FUNCTION Tria::NewGauss(IssmDouble* xyz_list, IssmDouble* xyz_list_front,int order_horiz,int order_vert){{{*/
+Gauss* Tria::NewGauss(IssmDouble* xyz_list, IssmDouble* xyz_list_front,int order_horiz,int order_vert){
+
+	IssmDouble  area_coordinates[2][3];
+	GetAreaCoordinates(&area_coordinates[0][0],xyz_list_front,xyz_list,2);
+	return new GaussTria(area_coordinates,order_vert);
+}
+/*}}}*/
+/*FUNCTION Tria::NewGaussBase(int order){{{*/
+Gauss* Tria::NewGaussBase(int order){
+
+	int indices[2];
+	this->EdgeOnBaseIndices(&indices[0],&indices[1]);
+	return new GaussTria(indices[0],indices[1],order);
+}
+/*}}}*/
+/*FUNCTION Tria::NewGaussTop(int order){{{*/
+Gauss* Tria::NewGaussTop(int order){
+
+	int indices[2];
+	this->EdgeOnSurfaceIndices(&indices[0],&indices[1]);
+	return new GaussTria(indices[0],indices[1],order);
+}
+/*}}}*/
+/*FUNCTION Tria::NodalFunctions{{{*/
+void Tria::NodalFunctions(IssmDouble* basis, Gauss* gauss){
+
+	_assert_(gauss->Enum()==GaussTriaEnum);
+	this->GetNodalFunctions(basis,(GaussTria*)gauss);
+
+}
+/*}}}*/
+/*FUNCTION Tria::NodalFunctionsDerivatives{{{*/
+void Tria::NodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss){
+
+	_assert_(gauss->Enum()==GaussTriaEnum);
+	this->GetNodalFunctionsDerivatives(dbasis,xyz_list,(GaussTria*)gauss);
+
+}
+/*}}}*/
+/*FUNCTION Tria::NodalFunctionsDerivativesVelocity{{{*/
+void Tria::NodalFunctionsDerivativesVelocity(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss){
+
+	_assert_(gauss->Enum()==GaussTriaEnum);
+	this->GetNodalFunctionsDerivativesVelocity(dbasis,xyz_list,(GaussTria*)gauss);
+
+}
+/*}}}*/
+/*FUNCTION Tria::NodalFunctionsVelocity{{{*/
+void Tria::NodalFunctionsVelocity(IssmDouble* basis, Gauss* gauss){
+
+	_assert_(gauss->Enum()==GaussTriaEnum);
+	this->GetNodalFunctionsVelocity(basis,(GaussTria*)gauss);
+
+}
+/*}}}*/
+/*FUNCTION Tria::NodalFunctionsPressure{{{*/
+void Tria::NodalFunctionsPressure(IssmDouble* basis, Gauss* gauss){
+
+	_assert_(gauss->Enum()==GaussTriaEnum);
+	this->GetNodalFunctionsPressure(basis,(GaussTria*)gauss);
+
+}
+/*}}}*/
+/*FUNCTION Tria::NodalFunctionsTensor{{{*/
+void Tria::NodalFunctionsTensor(IssmDouble* basis, Gauss* gauss){
+
+	_assert_(gauss->Enum()==GaussTriaEnum);
+	this->GetNodalFunctionsTensor(basis,(GaussTria*)gauss);
+
 }
 /*}}}*/
@@ -2328,4 +1618,56 @@
 	if(found)*pvalue=value;
 	return found;
+}
+/*}}}*/
+/*FUNCTION Tria::NormalBase {{{*/
+void Tria::NormalBase(IssmDouble* bed_normal,IssmDouble* xyz_list){
+
+	/*Build unit outward pointing vector*/
+	IssmDouble vector[2];
+	IssmDouble norm;
+
+	vector[0]=xyz_list[1*3+0] - xyz_list[0*3+0];
+	vector[1]=xyz_list[1*3+1] - xyz_list[0*3+1];
+
+	norm=sqrt(vector[0]*vector[0] + vector[1]*vector[1]);
+
+	bed_normal[0]= + vector[1]/norm;
+	bed_normal[1]= - vector[0]/norm;
+}
+/*}}}*/
+/*FUNCTION Tria::NormalTop {{{*/
+void Tria::NormalTop(IssmDouble* bed_normal,IssmDouble* xyz_list){
+
+	/*Build unit outward pointing vector*/
+	IssmDouble vector[2];
+	IssmDouble norm;
+
+	vector[0]=xyz_list[1*3+0] - xyz_list[0*3+0];
+	vector[1]=xyz_list[1*3+1] - xyz_list[0*3+1];
+
+	norm=sqrt(vector[0]*vector[0] + vector[1]*vector[1]);
+
+	bed_normal[0]= + vector[1]/norm;
+	bed_normal[1]= - vector[0]/norm;
+}
+/*}}}*/
+/*FUNCTION Tria::VelocityInterpolation{{{*/
+int Tria::VelocityInterpolation(void){
+	return TriaRef::VelocityInterpolation();
+}
+/*}}}*/
+/*FUNCTION Tria::PressureInterpolation{{{*/
+int Tria::PressureInterpolation(void){
+	return TriaRef::PressureInterpolation();
+}
+/*}}}*/
+/*FUNCTION Tria::NumberofNodesPressure{{{*/
+int Tria::NumberofNodesPressure(void){
+	return TriaRef::NumberofNodesPressure();
+}
+/*}}}*/
+/*FUNCTION Tria::NumberofNodesVelocity{{{*/
+int Tria::NumberofNodesVelocity(void){
+	return TriaRef::NumberofNodesVelocity();
 }
 /*}}}*/
@@ -2380,116 +1722,92 @@
 }
 /*}}}*/
-/*FUNCTION Tria::ResetCoordinateSystem{{{*/
-void  Tria::ResetCoordinateSystem(void){
-
-	int        approximation;
-	int        numindices;
-	int       *indices = NULL;
-	IssmDouble slope;
-	IssmDouble xz_plane[6];
+/*FUNCTION Tria::ReduceMatrices {{{*/
+void Tria::ReduceMatrices(ElementMatrix* Ke,ElementVector* pe){
+
+	/*Static condensation if requested*/
+	if(pe){
+		if(this->element_type==MINIcondensedEnum){
+			int indices[2]={6,7};
+			pe->StaticCondensation(Ke,2,&indices[0]);
+		}
+		else if(this->element_type==P1bubblecondensedEnum){
+			int size   = nodes[3]->GetNumberOfDofs(NoneApproximationEnum,GsetEnum);
+			int offset = 0;
+			for(int i=0;i<3;i++) offset+=nodes[i]->GetNumberOfDofs(NoneApproximationEnum,GsetEnum);
+			int* indices=xNew<int>(size);
+			for(int i=0;i<size;i++) indices[i] = offset+i;
+			pe->StaticCondensation(Ke,size,indices);
+			xDelete<int>(indices);
+		}
+	}
+
+	if(Ke){
+		if(this->element_type==MINIcondensedEnum){
+			int indices[2]={6,7};
+			Ke->StaticCondensation(2,&indices[0]);
+		}
+		else if(this->element_type==P1bubblecondensedEnum){
+			int size   = nodes[3]->GetNumberOfDofs(NoneApproximationEnum,GsetEnum);
+			int offset = 0;
+			for(int i=0;i<3;i++) offset+=nodes[i]->GetNumberOfDofs(NoneApproximationEnum,GsetEnum);
+			int* indices=xNew<int>(size);
+			for(int i=0;i<size;i++) indices[i] = offset+i;
+			Ke->StaticCondensation(size,indices);
+			xDelete<int>(indices);
+		}
+	}
+
+
+}
+/*}}}*/
+/*FUNCTION Tria::ResetFSBasalBoundaryCondition{{{*/
+void  Tria::ResetFSBasalBoundaryCondition(void){
+
+	int numnodes = this->NumberofNodesVelocity();
+
+	int          approximation;
+	IssmDouble*  vertexonbase= NULL;
+	IssmDouble   slope,groundedice;
+	IssmDouble   xz_plane[6];
 
 	/*For FS only: we want the CS to be tangential to the bedrock*/
 	inputs->GetInputValue(&approximation,ApproximationEnum);
-	if(IsFloating() || !HasEdgeOnBed() || approximation!=FSApproximationEnum) return;
-
-	/*Get number of nodes for velocity only and base*/
-	int index = this->EdgeOnBedIndex();
-	NodeOnEdgeIndices(&numindices,&indices,index,this->VelocityInterpolation());
-
+	if(!HasNodeOnBase() ||  approximation!=FSApproximationEnum) return;
+
+	//printf("element number %i \n",this->id);
 	/*Get inputs*/
-	Input* slope_input=inputs->GetInput(BedSlopeXEnum); _assert_(slope_input);
+	Input* slope_input=inputs->GetInput(BedSlopeXEnum);                             _assert_(slope_input);
+	Input* groundedicelevelset_input=inputs->GetInput(MaskGroundediceLevelsetEnum); _assert_(groundedicelevelset_input);
+	vertexonbase = xNew<IssmDouble>(numnodes);
+	this->GetInputListOnNodesVelocity(&vertexonbase[0],MeshVertexonbaseEnum);
 
 	/*Loop over basal nodes and update their CS*/
 	GaussTria* gauss = new GaussTria();
-	for(int i=0;i<numindices;i++){//FIXME
-
-		gauss->GaussNode(this->VelocityInterpolation(),indices[i]);
-		slope_input->GetInputValue(&slope,gauss);
-		IssmDouble theta = atan(slope);
-
-		/*New X axis                  New Z axis*/
-		xz_plane[0]=cos(theta);       xz_plane[3]=0.;  
-		xz_plane[1]=sin(theta);       xz_plane[4]=0.;  
-		xz_plane[2]=0.;               xz_plane[5]=1.;          
-
-		XZvectorsToCoordinateSystem(&this->nodes[indices[i]]->coord_system[0][0],&xz_plane[0]);
+	for(int i=0;i<this->NumberofNodesVelocity();i++){
+
+		if(vertexonbase[i]==1){
+			gauss->GaussNode(this->VelocityInterpolation(),i);
+			slope_input->GetInputValue(&slope,gauss);
+			groundedicelevelset_input->GetInputValue(&groundedice,gauss);
+			IssmDouble theta = atan(slope);
+
+			/*New X axis                  New Z axis*/
+			xz_plane[0]=cos(theta);       xz_plane[3]=0.;  
+			xz_plane[1]=sin(theta);       xz_plane[4]=0.;  
+			xz_plane[2]=0.;               xz_plane[5]=1.;          
+			if(groundedice>=0){
+				this->nodes[i]->DofInSSet(1); //vy
+			}
+			else{
+				this->nodes[i]->DofInFSet(1); //vy
+			}
+
+			XZvectorsToCoordinateSystem(&this->nodes[i]->coord_system[0][0],&xz_plane[0]);
+		}
 	}
 
 	/*cleanup*/
-	xDelete<int>(indices);
+	xDelete<IssmDouble>(vertexonbase);
 	delete gauss;
-}
-/*}}}*/
-/*FUNCTION Tria::ResultInterpolation{{{*/
-void Tria::ResultInterpolation(int* pinterpolation,int output_enum){
-
-	Input* input=this->inputs->GetInput(output_enum);
-
-	/*If this input is not already in Inputs, maybe it needs to be computed?*/
-	if(!input){
-		switch(output_enum){
-			case StressTensorxxEnum: 
-				this->ComputeStressTensor();
-				input=this->inputs->GetInput(output_enum);
-				break;
-			case StressTensorxyEnum: 
-				this->ComputeStressTensor();
-				input=this->inputs->GetInput(output_enum);
-				break;
-			case StressTensorxzEnum: 
-				this->ComputeStressTensor();
-				input=this->inputs->GetInput(output_enum);
-				break;
-			case StressTensoryyEnum: 
-				this->ComputeStressTensor();
-				input=this->inputs->GetInput(output_enum);
-				break;
-			case StressTensoryzEnum: 
-				this->ComputeStressTensor();
-				input=this->inputs->GetInput(output_enum);
-				break;
-			case StressTensorzzEnum: 
-				this->ComputeStressTensor();
-				input=this->inputs->GetInput(output_enum);
-				break;
-			default:
-				_error_("input "<<EnumToStringx(output_enum)<<" not found in element");
-		}
-	}
-
-	/*Assign output pointer*/
-	*pinterpolation = input->GetResultInterpolation();
-
-}
-/*}}}*/
-/*FUNCTION Tria::ResultToVector{{{*/
-void Tria::ResultToVector(Vector<IssmPDouble>* vector,int output_enum){
-
-	Input* input=this->inputs->GetInput(output_enum);
-	if(!input) _error_("input "<<EnumToStringx(output_enum)<<" not found in element");
-
-	switch(input->GetResultInterpolation()){
-		case P0Enum:
-			_error_("not implemented...");
-			break;
-		case P1Enum:{
-			IssmDouble  values[NUMVERTICES];
-			IssmPDouble pvalues[NUMVERTICES]; 
-			int         connectivity[NUMVERTICES];
-			int         sidlist[NUMVERTICES];
-
-			this->GetVertexSidList(&sidlist[0]);
-			this->GetConnectivityList(&connectivity[0]);
-			this->GetInputListOnVertices(&values[0],output_enum);
-			for(int i=0;i<NUMVERTICES;i++) pvalues[i] = reCast<IssmPDouble>(values[i])/reCast<IssmPDouble>(connectivity[i]);
-
-			vector->SetValues(NUMVERTICES,&sidlist[0],&pvalues[0],ADD_VAL);
-			break;
-					}
-		default:
-			_error_("interpolation "<<EnumToStringx(input->GetResultInterpolation())<<" not supported yet");
-	}
-
-
 }
 /*}}}*/
@@ -2546,20 +1864,4 @@
 }
 /*}}}*/
-/*FUNCTION Tria::SetCurrentConfiguration {{{*/
-void  Tria::SetCurrentConfiguration(Elements* elementsin, Loads* loadsin, Nodes* nodesin, Materials* materialsin, Parameters* parametersin){
-
-	/*go into parameters and get the analysis_counter: */
-	int analysis_counter;
-	parametersin->FindParam(&analysis_counter,AnalysisCounterEnum);
-
-	/*Get Element type*/
-	this->element_type=this->element_type_list[analysis_counter];
-
-	/*Pick up nodes*/
-	if(this->hnodes[analysis_counter]) this->nodes=(Node**)this->hnodes[analysis_counter]->deliverp();
-	else this->nodes=NULL;
-
-}
-/*}}}*/
 /*FUNCTION Tria::SpawnSeg {{{*/
 Seg*  Tria::SpawnSeg(int index1,int index2){
@@ -2579,7 +1881,5 @@
 
 	/*Spawn material*/
-	seg->material=(Material*)this->material->copy();
-	delete seg->material->inputs;
-	seg->material->inputs=(Inputs*)this->material->inputs->SpawnSegInputs(index1,index2);
+	seg->material=(Material*)this->material->copy2(seg);
 
 	/*recover nodes, material and matpar: */
@@ -2592,4 +1892,58 @@
 }
 /*}}}*/
+/*FUNCTION Tria::SpawnBasalElement{{{*/
+Element*  Tria::SpawnBasalElement(void){
+
+	int index1,index2;
+	int domaintype;
+
+	this->parameters->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DhorizontalEnum:
+			return this;
+		case Domain2DverticalEnum:
+			_assert_(HasEdgeOnBase());
+			this->EdgeOnBaseIndices(&index1,&index2);
+			return SpawnSeg(index1,index2);
+		default:
+			_error_("not implemented yet");
+	}
+}
+/*}}}*/
+/*FUNCTION Tria::SpawnTopElement{{{*/
+Element*  Tria::SpawnTopElement(void){
+
+	int index1,index2;
+	int domaintype;
+
+	this->parameters->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DhorizontalEnum:
+			return this;
+		case Domain2DverticalEnum:
+			_assert_(HasEdgeOnSurface());
+			this->EdgeOnSurfaceIndices(&index1,&index2);
+			return SpawnSeg(index2,index1); //reverse order
+		default:
+			_error_("not implemented yet");
+	}
+}
+/*}}}*/
+/*FUNCTION Tria::SetCurrentConfiguration {{{*/
+void  Tria::SetCurrentConfiguration(Elements* elementsin, Loads* loadsin, Nodes* nodesin, Materials* materialsin, Parameters* parametersin){
+
+	/*go into parameters and get the analysis_counter: */
+	int analysis_counter;
+	parametersin->FindParam(&analysis_counter,AnalysisCounterEnum);
+
+	/*Get Element type*/
+	this->element_type=this->element_type_list[analysis_counter];
+
+	/*Pick up nodes*/
+	if(this->hnodes[analysis_counter]) this->nodes=(Node**)this->hnodes[analysis_counter]->deliverp();
+	else this->nodes=NULL;
+
+}
+/*}}}*/
 /*FUNCTION Tria::SurfaceArea {{{*/
 IssmDouble Tria::SurfaceArea(void){
@@ -2601,7 +1955,7 @@
 
 	/*If on water, return 0: */
-	if(NoIceInElement())return 0;
-
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	if(!IsIceInElement()) return 0.;
+
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
 
 	for(int i=0;i<3;i++){
@@ -2618,27 +1972,4 @@
 	/*Return: */
 	return S;
-}
-/*}}}*/
-/*FUNCTION Tria::SurfaceNormal{{{*/
-void Tria::SurfaceNormal(IssmDouble* surface_normal, IssmDouble xyz_list[3][3]){
-
-	IssmDouble v13[3],v23[3];
-	IssmDouble normal[3];
-	IssmDouble normal_norm;
-
-	for(int i=0;i<3;i++){
-		v13[i]=xyz_list[0][i]-xyz_list[2][i];
-		v23[i]=xyz_list[1][i]-xyz_list[2][i];
-	}
-
-	normal[0]=v13[1]*v23[2]-v13[2]*v23[1];
-	normal[1]=v13[2]*v23[0]-v13[0]*v23[2];
-	normal[2]=v13[0]*v23[1]-v13[1]*v23[0];
-
-	normal_norm=sqrt( normal[0]*normal[0] + normal[1]*normal[1] + normal[2]*normal[2]);
-
-	*(surface_normal+0) = normal[0]/normal_norm;
-	*(surface_normal+1) = normal[1]/normal_norm;
-	*(surface_normal+2) = normal[2]/normal_norm;
 }
 /*}}}*/
@@ -2659,13 +1990,9 @@
 
 	/*Get for Vx and Vy, the max of abs value: */
-	#ifdef _HAVE_RESPONSES_
 	this->MaxAbsVx(&maxabsvx);
 	this->MaxAbsVy(&maxabsvy);
-	#else
-		_error_("ISSM was not compiled with responses compiled in, exiting!");
-	#endif
 
 	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
 
 	minx=xyz_list[0][0];
@@ -2760,4 +2087,5 @@
 			break;
 		case TaylorHoodEnum:
+		case XTaylorHoodEnum:
 			numnodes        = 9;
 			tria_node_ids   = xNew<int>(numnodes);
@@ -2788,5 +2116,30 @@
 void  Tria::UpdateConstraintsExtrudeFromBase(void){
 
-	if(!HasEdgeOnBed()) return;
+	if(!HasEdgeOnBase()) return;
+
+	int        extrusioninput;
+	IssmDouble value,isonbase;
+
+	this->parameters->FindParam(&extrusioninput,InputToExtrudeEnum);
+	Input* input = inputs->GetInput(extrusioninput);      _assert_(input);
+	Input* onbase = inputs->GetInput(MeshVertexonbaseEnum); _assert_(onbase);
+
+	GaussTria* gauss=new GaussTria();
+	for(int iv=0;iv<this->NumberofNodes();iv++){
+		gauss->GaussNode(this->element_type,iv);
+		onbase->GetInputValue(&isonbase,gauss);
+		if(isonbase==1.){
+			input->GetInputValue(&value,gauss);
+			this->nodes[iv]->ApplyConstraint(0,value);
+		}
+	}
+	delete gauss;
+
+}
+/*}}}*/
+/*FUNCTION Tria::UpdateConstraintsExtrudeFromTop{{{*/
+void  Tria::UpdateConstraintsExtrudeFromTop(void){
+
+	if(!HasEdgeOnSurface()) return;
 
 	int extrusioninput;
@@ -2795,6 +2148,6 @@
 
 	this->parameters->FindParam(&extrusioninput,InputToExtrudeEnum);
-	Input* input = inputs->GetInput(extrusioninput); _assert_(extrusioninput);
-	this->EdgeOnBedIndices(&indices[0],&indices[1]);
+	Input* input = inputs->GetInput(extrusioninput); _assert_(input);
+	this->EdgeOnSurfaceIndices(&indices[0],&indices[1]);
 
 	GaussTria* gauss=new GaussTria();
@@ -2802,33 +2155,65 @@
 		gauss->GaussNode(P1Enum,indices[i]);
 		input->GetInputValue(&value,gauss);
-		this->nodes[indices[i]]->ApplyConstraint(1,value);
-	}
-
-}
-/*}}}*/
-/*FUNCTION Tria::UpdateConstraintsExtrudeFromTop{{{*/
-void  Tria::UpdateConstraintsExtrudeFromTop(void){
-
-	if(!HasEdgeOnSurface()) return;
-
-	int extrusioninput;
-	int indices[2];
-	IssmDouble value;
-
-	this->parameters->FindParam(&extrusioninput,InputToExtrudeEnum);
-	Input* input = inputs->GetInput(extrusioninput); _assert_(extrusioninput);
-	this->EdgeOnSurfaceIndices(&indices[0],&indices[1]);
-
-	GaussTria* gauss=new GaussTria();
-	for(int i=0;i<2;i++){
-		gauss->GaussNode(P1Enum,indices[i]);
-		input->GetInputValue(&value,gauss);
-		this->nodes[indices[i]]->ApplyConstraint(1,value);
-	}
-
-}
-/*}}}*/
-
-#ifdef _HAVE_RESPONSES_
+		this->nodes[indices[i]]->ApplyConstraint(0,value);
+	}
+	delete gauss;
+
+}
+/*}}}*/
+/*FUNCTION Tria::ValueP1OnGauss{{{*/
+void Tria::ValueP1OnGauss(IssmDouble* pvalue,IssmDouble* values,Gauss* gauss){
+	TriaRef::GetInputValue(pvalue,values,gauss,P1Enum);
+}
+/*}}}*/
+/*FUNCTION Tria::ValueP1DerivativesOnGauss{{{*/
+void Tria::ValueP1DerivativesOnGauss(IssmDouble* dvalue,IssmDouble* values,IssmDouble* xyz_list,Gauss* gauss){
+	TriaRef::GetInputDerivativeValue(dvalue,values,xyz_list,gauss);
+}
+/*}}}*/
+/*FUNCTION Tria::VertexConnectivity{{{*/
+int Tria::VertexConnectivity(int vertexindex){
+	_assert_(this->vertices);
+	return this->vertices[vertexindex]->Connectivity();
+}
+/*}}}*/
+/*FUNCTION Tria::IsZeroLevelset{{{*/
+bool Tria::IsZeroLevelset(int levelset_enum){
+
+	bool iszerols;
+	IssmDouble ls[NUMVERTICES];
+
+	/*Retrieve all inputs and parameters*/
+	GetInputListOnVertices(&ls[0],levelset_enum);
+
+	/*If the level set is awlays <0, there is no ice front here*/
+	iszerols= false;
+	if(IsIceInElement()){
+		if(ls[0]*ls[1]<0. || ls[0]*ls[2]<0. || (ls[0]*ls[1]*ls[2]==0. && ls[0]*ls[1]+ls[0]*ls[2]+ls[1]*ls[2]<=0.)){
+			iszerols = true;
+		}
+	}
+
+	return iszerols;
+}
+/*}}}*/
+bool Tria::IsIcefront(void){/*{{{*/
+
+	bool isicefront;
+	int i,nrice;
+   IssmDouble ls[NUMVERTICES];
+
+	/*Retrieve all inputs and parameters*/
+	GetInputListOnVertices(&ls[0],MaskIceLevelsetEnum);
+
+	/* If only one vertex has ice, there is an ice front here */
+	isicefront=false;
+	if(IsIceInElement()){
+		nrice=0;       
+		for(i=0;i<NUMVERTICES;i++)
+			if(ls[i]<0.) nrice++;
+		if(nrice==1) isicefront= true;
+	}
+	return isicefront;
+}/*}}}*/
 /*FUNCTION Tria::AverageOntoPartition {{{*/
 void  Tria::AverageOntoPartition(Vector<IssmDouble>* partition_contributions,Vector<IssmDouble>* partition_areas,IssmDouble* vertex_response,IssmDouble* qmu_part){
@@ -2846,5 +2231,5 @@
 
 	/*Figure out the average for this element: */
-	this->GetVertexSidList(&offsetsid[0]);
+	this->GetVerticesSidList(&offsetsid[0]);
 	this->GetVertexPidList(&offsetdof[0]);
 	mean=0;
@@ -2877,7 +2262,39 @@
 	IssmDouble xyz_list[NUMVERTICES][3];
 
-	if(NoIceInElement())return 0;
-
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	if(!IsIceInElement())return 0;
+
+	/*First get back the area of the base*/
+	base=this->GetArea();
+
+	/*Now get the average height*/
+	Input* surface_input = inputs->GetInput(SurfaceEnum); _assert_(surface_input);
+	Input* base_input     = inputs->GetInput(BaseEnum);     _assert_(base_input);
+	surface_input->GetInputAverage(&surface);
+	base_input->GetInputAverage(&bed);
+
+	/*Return: */
+	int domaintype;
+	parameters->FindParam(&domaintype,DomainTypeEnum);
+	if(domaintype==Domain2DverticalEnum){
+	  return base;
+	}
+	else{
+	  return base*(surface-bed);
+	}
+}
+/*}}}*/
+/*FUNCTION Tria::IceVolumeAboveFloatation {{{*/
+IssmDouble Tria::IceVolumeAboveFloatation(void){
+
+	/*The volume above floatation: H + rho_water/rho_ice * bathymetry */
+	IssmDouble rho_ice,rho_water;
+	IssmDouble base,surface,bed,bathymetry;
+	IssmDouble xyz_list[NUMVERTICES][3];
+
+	if(!IsIceInElement() || IsFloating())return 0;
+
+	rho_ice=matpar->GetRhoIce();
+	rho_water=matpar->GetRhoWater();
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
 
 	/*First calculate the area of the base (cross section triangle)
@@ -2886,40 +2303,11 @@
 	base = 1./2. * fabs((xyz_list[0][0]-xyz_list[2][0])*(xyz_list[1][1]-xyz_list[0][1]) - (xyz_list[0][0]-xyz_list[1][0])*(xyz_list[2][1]-xyz_list[0][1]));
 
-	/*Now get the average height*/
-	Input* surface_input = inputs->GetInput(SurfaceEnum); _assert_(surface_input);
-	Input* bed_input     = inputs->GetInput(BedEnum);     _assert_(bed_input);
-	surface_input->GetInputAverage(&surface);
-	bed_input->GetInputAverage(&bed);
-
-	/*Return: */
-	return base*(surface-bed);
-}
-/*}}}*/
-/*FUNCTION Tria::IceVolumeAboveFloatation {{{*/
-IssmDouble Tria::IceVolumeAboveFloatation(void){
-
-	/*The volume above floatation: H + rho_water/rho_ice * bathymetry */
-	IssmDouble rho_ice,rho_water;
-	IssmDouble base,surface,bed,bathymetry;
-	IssmDouble xyz_list[NUMVERTICES][3];
-
-	if(NoIceInElement() || IsFloating())return 0;
-
-	rho_ice=matpar->GetRhoIce();
-	rho_water=matpar->GetRhoWater();
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-
-	/*First calculate the area of the base (cross section triangle)
-	 * http://en.wikipedia.org/wiki/Triangle
-	 * base = 1/2 abs((xA-xC)(yB-yA)-(xA-xB)(yC-yA))*/
-	base = 1./2. * fabs((xyz_list[0][0]-xyz_list[2][0])*(xyz_list[1][1]-xyz_list[0][1]) - (xyz_list[0][0]-xyz_list[1][0])*(xyz_list[2][1]-xyz_list[0][1]));
-
 	/*Now get the average height and bathymetry*/
 	Input* surface_input    = inputs->GetInput(SurfaceEnum);    _assert_(surface_input);
-	Input* bed_input        = inputs->GetInput(BedEnum);        _assert_(bed_input);
-	Input* bathymetry_input = inputs->GetInput(BathymetryEnum); _assert_(bathymetry_input);
+	Input* base_input        = inputs->GetInput(BaseEnum);        _assert_(base_input);
+	Input* bed_input = inputs->GetInput(BedEnum); _assert_(bed_input);
 	surface_input->GetInputAverage(&surface);
-	bed_input->GetInputAverage(&bed);
-	bathymetry_input->GetInputAverage(&bathymetry);
+	base_input->GetInputAverage(&bed);
+	bed_input->GetInputAverage(&bathymetry);
 	
 	/*Return: */
@@ -2930,5 +2318,5 @@
 IssmDouble Tria::MassFlux( IssmDouble x1, IssmDouble y1, IssmDouble x2, IssmDouble y2,int segment_id){
 
-	int        meshtype;
+	int        domaintype;
 	IssmDouble mass_flux=0.;
 	IssmDouble xyz_list[NUMVERTICES][3];
@@ -2947,5 +2335,5 @@
 
 	/*Get xyz list: */
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
 
 	/*get area coordinates of 0 and 1 locations: */
@@ -2961,8 +2349,8 @@
 
 	Input* thickness_input=inputs->GetInput(ThicknessEnum); _assert_(thickness_input);
-	this->parameters->FindParam(&meshtype,MeshTypeEnum);
+	this->parameters->FindParam(&domaintype,DomainTypeEnum);
 	Input* vx_input=NULL;
 	Input* vy_input=NULL;
-	if(meshtype==Mesh2DhorizontalEnum){
+	if(domaintype==Domain2DhorizontalEnum){
 		vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);
 		vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);
@@ -2994,5 +2382,5 @@
 IssmDouble Tria::MassFlux( IssmDouble* segment){
 
-	int        meshtype;
+	int        domaintype;
 	IssmDouble mass_flux=0.;
 	IssmDouble xyz_list[NUMVERTICES][3];
@@ -3014,5 +2402,5 @@
 
 	/*Get xyz list: */
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
 
 	/*get area coordinates of 0 and 1 locations: */
@@ -3028,8 +2416,8 @@
 
 	Input* thickness_input=inputs->GetInput(ThicknessEnum); _assert_(thickness_input);
-	this->parameters->FindParam(&meshtype,MeshTypeEnum);
+	this->parameters->FindParam(&domaintype,DomainTypeEnum);
 	Input* vx_input=NULL;
 	Input* vy_input=NULL;
-	if(meshtype==Mesh2DhorizontalEnum){
+	if(domaintype==Domain2DhorizontalEnum){
 		vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);
 		vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);
@@ -3206,7 +2594,7 @@
 	rho_ice=matpar->GetRhoIce();
 
-   if(NoIceInElement())return 0;
-
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+   if(!IsIceInElement())return 0;
+
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
 
 	/*First calculate the area of the base (cross section triangle)
@@ -3224,5 +2612,84 @@
 }
 /*}}}*/
-#endif
+/*FUNCTION Tria::MisfitArea{{{*/
+IssmDouble Tria::MisfitArea(int weightsenum){
+
+	/*Intermediaries*/
+	IssmDouble weight;
+	IssmDouble Jdet;
+	IssmDouble Jelem = 0;
+	IssmDouble xyz_list[NUMVERTICES][3];
+	GaussTria *gauss = NULL;
+
+	/*If on water, return 0: */
+	if(!IsIceInElement())return 0;
+
+	/*Retrieve all inputs we will be needing: */
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	Input* weights_input     =inputs->GetInput(weightsenum);     _assert_(weights_input);
+
+	/* Start  looping on the number of gaussian points: */
+	gauss=new GaussTria(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+
+		gauss->GaussPoint(ig);
+
+		/* Get Jacobian determinant: */
+		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
+
+		/*Get parameters at gauss point*/
+		weights_input->GetInputValue(&weight,gauss);
+
+		/*compute misfit between model and observation */
+		Jelem+=Jdet*weight*gauss->weight;
+	}
+
+	/* clean up and Return: */
+	delete gauss;
+	return Jelem;
+}
+/*}}}*/
+/*FUNCTION Tria::Misfit{{{*/
+IssmDouble Tria::Misfit(int modelenum,int observationenum,int weightsenum){
+
+	/*Intermediaries*/
+	IssmDouble model,observation,weight;
+	IssmDouble Jdet;
+	IssmDouble Jelem = 0;
+	IssmDouble xyz_list[NUMVERTICES][3];
+	GaussTria *gauss = NULL;
+
+	/*If on water, return 0: */
+	if(!IsIceInElement())return 0;
+
+	/*Retrieve all inputs we will be needing: */
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	Input* model_input=inputs->GetInput(modelenum);   _assert_(model_input);
+	Input* observation_input=inputs->GetInput(observationenum);_assert_(observation_input);
+	Input* weights_input     =inputs->GetInput(weightsenum);     _assert_(weights_input);
+
+	/* Start  looping on the number of gaussian points: */
+	gauss=new GaussTria(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+
+		gauss->GaussPoint(ig);
+
+		/* Get Jacobian determinant: */
+		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
+
+		/*Get parameters at gauss point*/
+		model_input->GetInputValue(&model,gauss);
+		observation_input->GetInputValue(&observation,gauss);
+		weights_input->GetInputValue(&weight,gauss);
+
+		/*compute misfit between model and observation */
+		Jelem+=0.5*(model-observation)*(model-observation)*Jdet*weight*gauss->weight;
+	}
+
+	/* clean up and Return: */
+	delete gauss;
+	return Jelem;
+}
+/*}}}*/
 
 #ifdef _HAVE_GIA_
@@ -3308,5 +2775,5 @@
 
 	/*figure out gravity center of our element: */
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
 	x0=(xyz_list[0][0]+xyz_list[1][0]+xyz_list[2][0])/3.0;
 	y0=(xyz_list[0][1]+xyz_list[1][1]+xyz_list[2][1])/3.0;
@@ -3355,1225 +2822,4 @@
 #endif
 
-#ifdef _HAVE_STRESSBALANCE_
-/*FUNCTION Tria::CreateKMatrixStressbalanceFS{{{*/
-ElementMatrix* Tria::CreateKMatrixStressbalanceFS(void){
-
-	ElementMatrix* Ke1 = NULL;
-	ElementMatrix* Ke2 = NULL;
-	ElementMatrix* Ke  = NULL;
-
-	/*compute all stiffness matrices for this element*/
-	Ke1=CreateKMatrixStressbalanceFSViscous();
-	Ke2=CreateKMatrixStressbalanceFSFriction();
-	Ke =new ElementMatrix(Ke1,Ke2);
-
-	/*clean-up and return*/
-	delete Ke1;
-	delete Ke2;
-	return Ke;
-
-}
-/*}}}*/
-/*FUNCTION Tria::CreateKMatrixStressbalanceFSViscous {{{*/
-ElementMatrix* Tria::CreateKMatrixStressbalanceFSViscous(void){
-
-	/*Intermediaries */
-	int        i,approximation;
-	IssmDouble Jdet,viscosity,FSreconditioning,D_scalar;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble epsilon[3]; /* epsilon=[exx,eyy,exy];*/
-	GaussTria *gauss=NULL;
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int vnumnodes = this->NumberofNodesVelocity();
-	int pnumnodes = this->NumberofNodesPressure();
-	int numdof    = vnumnodes*NDOF2 + pnumnodes*NDOF1;
-
-	/*Prepare coordinate system list*/
-	int* cs_list = xNew<int>(vnumnodes+pnumnodes);
-	for(i=0;i<vnumnodes;i++) cs_list[i]           = XYEnum;
-	for(i=0;i<pnumnodes;i++) cs_list[vnumnodes+i] = PressureEnum;
-
-	/*Initialize Element matrix and vectors*/
-	ElementMatrix* Ke     = new ElementMatrix(nodes,vnumnodes+pnumnodes,this->parameters,FSvelocityEnum);
-	IssmDouble*    B      = xNew<IssmDouble>(5*numdof);
-	IssmDouble*    Bprime = xNew<IssmDouble>(5*numdof);
-	IssmDouble*    D      = xNewZeroInit<IssmDouble>(5*5);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	parameters->FindParam(&FSreconditioning,StressbalanceFSreconditioningEnum);
-	Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);
-	Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);
-
-	/* Start  looping on the number of gaussian points: */
-	gauss=new GaussTria(5);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		GetBFS(B,&xyz_list[0][0],gauss); 
-		GetBprimeFS(Bprime,&xyz_list[0][0],gauss); 
-
-		this->GetStrainRate2d(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input);
-		material->GetViscosity2dvertical(&viscosity,&epsilon[0]);
-
-		D_scalar=gauss->weight*Jdet;
-		for(i=0;i<3;i++) D[i*5+i] = +D_scalar*2.*viscosity;
-		for(i=3;i<5;i++) D[i*5+i] = -D_scalar*FSreconditioning;
-
-		TripleMultiply(B,5,numdof,1,
-					D,5,5,0,
-					Bprime,5,numdof,0,
-					Ke->values,1);
-	}
-
-	/*Transform Coordinate System*/
-	TransformStiffnessMatrixCoord(Ke,nodes,(vnumnodes+pnumnodes),cs_list);
-
-	/*Clean up and return*/
-	delete gauss;
-	xDelete<int>(cs_list);
-	xDelete<IssmDouble>(B);
-	xDelete<IssmDouble>(Bprime);
-	xDelete<IssmDouble>(D);
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Tria::CreateKMatrixStressbalanceFSFriction{{{*/
-ElementMatrix* Tria::CreateKMatrixStressbalanceFSFriction(void){
-
-	/*Intermediaries */
-	int         i,j;
-	int         analysis_type;
-	int         indices[2];
-	IssmDouble  alpha2,Jdet;
-	IssmDouble  xyz_list[NUMVERTICES][3];
-	IssmDouble  xyz_list_seg[NUMVERTICES1D][3];
-	Friction   *friction = NULL;
-
-	/*Initialize Element matrix and return if necessary*/
-	if(IsFloating() || !HasEdgeOnBed()) return NULL;
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int vnumnodes = this->NumberofNodesVelocity();
-	int pnumnodes = this->NumberofNodesPressure();
-	int  numdof   = vnumnodes*NDOF2 + pnumnodes*NDOF1;
-
-	/*Prepare coordinate system list*/
-	int* cs_list = xNew<int>(vnumnodes+pnumnodes);
-	for(i=0;i<vnumnodes;i++) cs_list[i]           = XYEnum;
-	for(i=0;i<pnumnodes;i++) cs_list[vnumnodes+i] = PressureEnum;
-
-	/*Initialize Element matrix and vectors*/
-	ElementMatrix* Ke        = new ElementMatrix(nodes,vnumnodes+pnumnodes,this->parameters,FSvelocityEnum);
-	IssmDouble*    BFriction = xNew<IssmDouble>(1*numdof);
-	IssmDouble     D;
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	parameters->FindParam(&analysis_type,AnalysisTypeEnum);
-	Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);
-	Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);
-
-	/*Get vertex indices that lie on bed*/
-	this->EdgeOnBedIndices(&indices[0],&indices[1]);
-	for(i=0;i<NUMVERTICES1D;i++) for(j=0;j<2;j++) xyz_list_seg[i][j]=xyz_list[indices[i]][j];
-
-	/*build friction object, used later on: */
-	friction=new Friction("1d",inputs,matpar,analysis_type);
-
-	/* Start looping on the number of gauss 1d (nodes on the bedrock) */
-	GaussTria* gauss=new GaussTria(indices[0],indices[1],2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetSegmentJacobianDeterminant(&Jdet,&xyz_list_seg[0][0],gauss);
-		GetLFS(BFriction,gauss);
-
-		friction->GetAlpha2(&alpha2,gauss,VxEnum,VyEnum,VzEnum);
-		D = +alpha2*gauss->weight*Jdet; //taub_x = -alpha2 vx
-
-		TripleMultiply(BFriction,1,numdof,1,
-					&D,1,1,0,
-					BFriction,1,numdof,0,
-					Ke->values,1);
-	}
-
-	/*DO NOT Transform Coordinate System: this stiffness matrix is already expressed in tangential coordinates*/
-	//TransformStiffnessMatrixCoord(Ke,nodes,(vnumnodes+pnumnodes),cs_list);
-
-	/*Clean up and return*/
-	delete gauss;
-	delete friction;
-	xDelete<IssmDouble>(BFriction);
-	xDelete<int>(cs_list);
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Tria::CreateKMatrixStressbalanceSSA {{{*/
-ElementMatrix* Tria::CreateKMatrixStressbalanceSSA(void){
-
-	/*compute all stiffness matrices for this element*/
-	ElementMatrix* Ke1=CreateKMatrixStressbalanceSSAViscous();
-	ElementMatrix* Ke2=CreateKMatrixStressbalanceSSAFriction();
-	ElementMatrix* Ke =new ElementMatrix(Ke1,Ke2);
-
-	/*clean-up and return*/
-	delete Ke1;
-	delete Ke2;
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Tria::CreateKMatrixStressbalanceSSAViscous{{{*/
-ElementMatrix* Tria::CreateKMatrixStressbalanceSSAViscous(void){
-
-	/*Intermediaries*/
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble viscosity,newviscosity,oldviscosity;
-	IssmDouble viscosity_overshoot,thickness,Jdet;
-	IssmDouble epsilon[3],oldepsilon[3];    /* epsilon=[exx,eyy,exy];    */
-	IssmDouble D_scalar;
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodes();
-	int numdof   = numnodes*NDOF2;
-
-	/*Initialize Element matrix and vectors*/
-	ElementMatrix* Ke     = new ElementMatrix(nodes,numnodes,this->parameters,SSAApproximationEnum);
-	IssmDouble*    B      = xNew<IssmDouble>(3*numdof);
-	IssmDouble*    Bprime = xNew<IssmDouble>(3*numdof);
-	IssmDouble*    D      = xNewZeroInit<IssmDouble>(3*3);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	Input* thickness_input=inputs->GetInput(ThicknessEnum); _assert_(thickness_input);
-	Input* vx_input=inputs->GetInput(VxEnum);               _assert_(vx_input);
-	Input* vy_input=inputs->GetInput(VyEnum);               _assert_(vy_input);
-	Input* vxold_input=inputs->GetInput(VxPicardEnum);      _assert_(vxold_input);
-	Input* vyold_input=inputs->GetInput(VyPicardEnum);      _assert_(vyold_input);
-	this->parameters->FindParam(&viscosity_overshoot,StressbalanceViscosityOvershootEnum);
-
-	/* Start  looping on the number of gaussian points: */
-	GaussTria* gauss  = new GaussTria(2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		GetBSSA(&B[0], &xyz_list[0][0], gauss);
-		GetBprimeSSA(&Bprime[0], &xyz_list[0][0], gauss);
-
-		this->GetStrainRate2d(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input);
-		this->GetStrainRate2d(&oldepsilon[0],&xyz_list[0][0],gauss,vxold_input,vyold_input);
-		material->GetViscosity2d(&viscosity, &epsilon[0]);
-		material->GetViscosity2d(&oldviscosity, &oldepsilon[0]);
-		thickness_input->GetInputValue(&thickness, gauss);
-
-		newviscosity=viscosity+viscosity_overshoot*(viscosity-oldviscosity);
-		D_scalar=2.*newviscosity*thickness*gauss->weight*Jdet;
-		for(int i=0;i<3;i++) D[i*3+i]=D_scalar;
-
-		TripleMultiply(B,3,numdof,1,
-					D,3,3,0,
-					Bprime,3,numdof,0,
-					&Ke->values[0],1);
-	}
-
-	/*Transform Coordinate System*/
-	TransformStiffnessMatrixCoord(Ke,nodes,numnodes,XYEnum);
-
-	/*Clean up and return*/
-	delete gauss;
-	xDelete<IssmDouble>(D);
-	xDelete<IssmDouble>(Bprime);
-	xDelete<IssmDouble>(B);
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Tria::CreateKMatrixStressbalanceSSAFriction {{{*/
-ElementMatrix* Tria::CreateKMatrixStressbalanceSSAFriction(void){
-
-	/*Intermediaries*/
-	bool       mainlyfloating;
-	int        analysis_type,migration_style;
-	int        point1;
-	IssmDouble alpha2,Jdet;
-	IssmDouble fraction1,fraction2;
-	IssmDouble phi=1.0;
-	IssmDouble D_scalar;
-	IssmDouble gllevelset;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	Friction  *friction = NULL;
-	GaussTria *gauss    = NULL;
-
-	/*Return if element is inactive*/
-	if(IsFloating()) return NULL;
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodes();
-	int numdof   = numnodes*NDOF2;
-
-	/*Initialize Element matrix and vectors*/
-	ElementMatrix* Ke     = new ElementMatrix(nodes,numnodes,this->parameters,SSAApproximationEnum);
-	IssmDouble*    B      = xNew<IssmDouble>(2*numdof);
-	IssmDouble*    D      = xNewZeroInit<IssmDouble>(2*2);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	parameters->FindParam(&migration_style,GroundinglineMigrationEnum);
-	Input* surface_input=inputs->GetInput(SurfaceEnum);       _assert_(surface_input);
-	Input* vx_input=inputs->GetInput(VxEnum);                 _assert_(vx_input);
-	Input* vy_input=inputs->GetInput(VyEnum);                 _assert_(vy_input);
-	Input* gllevelset_input=NULL;
-	parameters->FindParam(&analysis_type,AnalysisTypeEnum);
-
-	/*build friction object, used later on: */
-	friction=new Friction("2d",inputs,matpar,analysis_type);
-
-	/*Recover portion of element that is grounded*/
-	if(migration_style==SubelementMigrationEnum) phi=this->GetGroundedPortion(&xyz_list[0][0]);
-	if(migration_style==SubelementMigration2Enum){
-		gllevelset_input=inputs->GetInput(MaskGroundediceLevelsetEnum); _assert_(gllevelset_input);
-		this->GetGroundedPart(&point1,&fraction1,&fraction2,&mainlyfloating);
-		gauss=new GaussTria(point1,fraction1,fraction2,mainlyfloating,2);
-	}
-	else{
-		gauss=new GaussTria(2);
-	}
-
-	/* Start  looping on the number of gaussian points: */
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		friction->GetAlpha2(&alpha2, gauss,VxEnum,VyEnum,VzEnum);
-		if(migration_style==SubelementMigrationEnum) alpha2=phi*alpha2;
-		if(migration_style==SubelementMigration2Enum){
-			gllevelset_input->GetInputValue(&gllevelset, gauss);
-			if(gllevelset<0) alpha2=0;
-		}
-
-		GetBSSAFriction(&B[0], &xyz_list[0][0], gauss);
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		D_scalar=alpha2*gauss->weight*Jdet;
-		for(int i=0;i<2;i++) D[i*2+i]=D_scalar;
-
-		TripleMultiply(B,2,numdof,1,
-					D,2,2,0,
-					B,2,numdof,0,
-					&Ke->values[0],1);
-	}
-
-	/*Transform Coordinate System*/
-	TransformStiffnessMatrixCoord(Ke,nodes,numnodes,XYEnum);
-
-	/*Clean up and return*/
-	delete gauss;
-	delete friction;
-	xDelete<IssmDouble>(D);
-	xDelete<IssmDouble>(B);
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Tria::CreateKMatrixStressbalanceSIA{{{*/
-ElementMatrix* Tria::CreateKMatrixStressbalanceSIA(void){
-
-	/*Intermediaries*/
-	IssmDouble connectivity;
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodes(); _assert_(numnodes==3); 
-	int numdof   = numnodes*NDOF2;
-
-	/*Initialize Element matrix*/
-	ElementMatrix* Ke=new ElementMatrix(nodes,numnodes,this->parameters,NoneApproximationEnum);
-
-	/*Create Element matrix*/
-	for(int i=0;i<numnodes;i++){
-		connectivity=(IssmDouble)vertices[i]->Connectivity();
-		Ke->values[(2*i+0)*numdof+(2*i+0)]=1./connectivity;
-		Ke->values[(2*i+1)*numdof+(2*i+1)]=1./connectivity;
-	}
-
-	/*Clean up and return*/
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Tria::CreatePVectorStressbalanceFS {{{*/
-ElementVector* Tria::CreatePVectorStressbalanceFS(void){
-
-	ElementVector* pe1;
-	ElementVector* pe2;
-	ElementVector* pe3;
-	ElementVector* pe;
-
-	/*compute all stiffness matrices for this element*/
-	pe1=CreatePVectorStressbalanceFSViscous();
-	pe2=CreatePVectorStressbalanceFSShelf();
-	pe3=CreatePVectorStressbalanceFSFront();
-	pe =new ElementVector(pe1,pe2,pe3);
-
-	/*clean-up and return*/
-	delete pe1;
-	delete pe2;
-	delete pe3;
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Tria::CreatePVectorStressbalanceFSFront{{{*/
-ElementVector* Tria::CreatePVectorStressbalanceFSFront(void){
-
-	/*Intermediaries */
-	int         i;
-	IssmDouble  ls[NUMVERTICES];
-	IssmDouble  xyz_list[NUMVERTICES][3];
-	bool        isfront;
-
-	/*Retrieve all inputs and parameters*/
-	GetInputListOnVertices(&ls[0],MaskIceLevelsetEnum);
-
-	/*If the level set is awlays <=0, there is no ice front here*/
-	isfront = false;
-	if(ls[0]>0. || ls[1]>0. || ls[2]>0.){
-		if(ls[0]*ls[1]<0. || ls[0]*ls[2]<0. || (ls[0]*ls[1]+ls[0]*ls[2]+ls[1]*ls[2]==0.)){
-			isfront = true;
-		}
-	}
-
-	/*If no front, return NULL*/
-	if(!isfront) return NULL;
-
-	/*Intermediaries*/
-	IssmDouble  rho_ice,rho_water,gravity,y_g;
-	IssmDouble  Jdet,water_pressure,air_pressure,pressure;
-	IssmDouble  xyz_list_front[2][3];
-	IssmDouble  area_coordinates[2][3];
-	IssmDouble  normal[2];
-	GaussTria*  gauss = NULL;
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int vnumnodes = this->NumberofNodesVelocity();
-	int pnumnodes = this->NumberofNodesPressure();
-
-	/*Prepare coordinate system list*/
-	int* cs_list = xNew<int>(vnumnodes+pnumnodes);
-	for(i=0;i<vnumnodes;i++) cs_list[i]           = XYEnum;
-	for(i=0;i<pnumnodes;i++) cs_list[vnumnodes+i] = PressureEnum;
-
-	/*Initialize Element matrix and vectors*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	ElementVector* pe     = new ElementVector(nodes,vnumnodes+pnumnodes,this->parameters,FSvelocityEnum);
-	IssmDouble*    vbasis = xNew<IssmDouble>(vnumnodes);
-
-	/*Retrieve all inputs and parameters*/
-	rho_water = matpar->GetRhoWater();
-	gravity   = matpar->GetG();
-	GetZeroLevelsetCoordinates(&xyz_list_front[0][0],xyz_list,MaskIceLevelsetEnum);
-	GetAreaCoordinates(&area_coordinates[0][0],xyz_list_front,xyz_list,2);
-	GetSegmentNormal(&normal[0],xyz_list_front);
-
-	/*Start looping on Gaussian points*/
-	IssmDouble ymax=max(xyz_list_front[0][1],xyz_list_front[1][1]);
-	IssmDouble ymin=min(xyz_list_front[0][1],xyz_list_front[1][1]);
-	if(ymax>0. && ymin<0.) gauss=new GaussTria(area_coordinates,30); //refined in vertical because of the sea level discontinuity
-	else                   gauss=new GaussTria(area_coordinates,3);
-
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-		y_g=GetYcoord(gauss);
-		GetNodalFunctionsVelocity(vbasis,gauss);
-		GetSegmentJacobianDeterminant(&Jdet,&xyz_list_front[0][0],gauss);
-
-		water_pressure = rho_water*gravity*min(0.,y_g); //0 if the gaussian point is above water level
-		air_pressure   = 0.;
-		pressure       = water_pressure + air_pressure;
-
-		for(i=0;i<vnumnodes;i++){
-			pe->values[2*i+0]+= pressure*Jdet*gauss->weight*normal[0]*vbasis[i];
-			pe->values[2*i+1]+= pressure*Jdet*gauss->weight*normal[1]*vbasis[i];
-		}
-	}
-
-
-	/*Transform coordinate system*/
-	TransformLoadVectorCoord(pe,nodes,(vnumnodes+pnumnodes),cs_list);
-
-	/*Clean up and return*/
-	xDelete<int>(cs_list);
-	xDelete<IssmDouble>(vbasis);
-	delete gauss;
-	return pe;
-
-}
-/*}}}*/
-/*FUNCTION Tria::CreatePVectorStressbalanceFSViscous {{{*/
-ElementVector* Tria::CreatePVectorStressbalanceFSViscous(void){
-
-	/*Intermediaries*/
-	int        i;
-	int        approximation;
-	IssmDouble Jdet,gravity,rho_ice;
-	IssmDouble forcex,forcey;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	GaussTria *gauss=NULL;
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int vnumnodes = this->NumberofNodesVelocity();
-	int pnumnodes = this->NumberofNodesPressure();
-
-	/*Prepare coordinate system list*/
-	int* cs_list = xNew<int>(vnumnodes+pnumnodes);
-	for(i=0;i<vnumnodes;i++) cs_list[i]           = XYEnum;
-	for(i=0;i<pnumnodes;i++) cs_list[vnumnodes+i] = PressureEnum;
-
-	/*Initialize Element matrix and vectors*/
-	ElementVector* pe     = new ElementVector(nodes,vnumnodes+pnumnodes,this->parameters,FSvelocityEnum);
-	IssmDouble*    vbasis = xNew<IssmDouble>(vnumnodes);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	Input* loadingforcex_input=inputs->GetInput(LoadingforceXEnum);  _assert_(loadingforcex_input);
-	Input* loadingforcey_input=inputs->GetInput(LoadingforceYEnum);  _assert_(loadingforcey_input);
-	rho_ice = matpar->GetRhoIce();
-	gravity = matpar->GetG();
-
-	/* Start  looping on the number of gaussian points: */
-	gauss=new GaussTria(5);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		GetNodalFunctionsVelocity(vbasis, gauss);
-
-		loadingforcex_input->GetInputValue(&forcex,gauss);
-		loadingforcey_input->GetInputValue(&forcey,gauss);
-
-		for(i=0;i<vnumnodes;i++){
-			pe->values[i*NDOF2+1] += -rho_ice*gravity*Jdet*gauss->weight*vbasis[i];
-			pe->values[i*NDOF2+0] += +rho_ice*forcex *Jdet*gauss->weight*vbasis[i];
-			pe->values[i*NDOF2+1] += +rho_ice*forcey *Jdet*gauss->weight*vbasis[i];
-		}
-	}
-
-	/*Transform coordinate system*/
-	TransformLoadVectorCoord(pe,nodes,vnumnodes+pnumnodes,cs_list);
-
-	/*Clean up and return*/
-	delete gauss;
-	xDelete<int>(cs_list);
-	xDelete<IssmDouble>(vbasis);
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Tria::CreatePVectorStressbalanceFSShelf{{{*/
-ElementVector* Tria::CreatePVectorStressbalanceFSShelf(void){
-
-	/*Intermediaries*/
-	int         i,j;
-	int         indices[2];
-	IssmDouble  gravity,rho_water,bed,water_pressure;
-	IssmDouble  normal_vel,vx,vy,dt;
-	IssmDouble	xyz_list_seg[NUMVERTICES1D][3];
-	IssmDouble  xyz_list[NUMVERTICES][3];
-	IssmDouble	normal[2];
-	IssmDouble  Jdet;
-
-	/*Initialize Element vector and return if necessary*/
-	if(!HasEdgeOnBed() || !IsFloating()) return NULL;
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int vnumnodes = this->NumberofNodesVelocity();
-	int pnumnodes = this->NumberofNodesPressure();
-
-	/*Prepare coordinate system list*/
-	int* cs_list = xNew<int>(vnumnodes+pnumnodes);
-	for(i=0;i<vnumnodes;i++) cs_list[i]           = XYEnum;
-	for(i=0;i<pnumnodes;i++) cs_list[vnumnodes+i] = PressureEnum;
-
-	/*Initialize Element matrix and vectors*/
-	ElementVector* pe     = new ElementVector(nodes,vnumnodes+pnumnodes,this->parameters,FSvelocityEnum);
-	IssmDouble*    vbasis = xNew<IssmDouble>(vnumnodes);
-
-	/*Retrieve all inputs and parameters*/
-	rho_water=matpar->GetRhoWater();
-	gravity=matpar->GetG();
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	Input* bed_input=inputs->GetInput(BedEnum); _assert_(bed_input);
-
-	/*Get vertex indices that lie on bed*/
-	this->EdgeOnBedIndices(&indices[0],&indices[1]);
-
-	for(i=0;i<NUMVERTICES1D;i++) for(j=0;j<2;j++) xyz_list_seg[i][j]=xyz_list[indices[i]][j];
-
-	/* Start looping on the number of gauss 1d (nodes on the bedrock) */
-	GaussTria* gauss=new GaussTria(indices[0],indices[1],2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetSegmentJacobianDeterminant(&Jdet,&xyz_list_seg[0][0],gauss);
-		GetNodalFunctionsVelocity(vbasis, gauss);
-
-		GetSegmentNormal(&normal[0],xyz_list_seg);
-		_assert_(normal[1]<0.);
-		bed_input->GetInputValue(&bed, gauss);
-		water_pressure=gravity*rho_water*bed;
-
-		for(i=0;i<vnumnodes;i++){
-			pe->values[2*i+0]+=(water_pressure)*gauss->weight*Jdet*vbasis[i]*normal[0];
-			pe->values[2*i+1]+=(water_pressure)*gauss->weight*Jdet*vbasis[i]*normal[1];
-		}
-	}
-
-	/*Transform coordinate system*/
-	TransformLoadVectorCoord(pe,nodes,(vnumnodes+pnumnodes),cs_list);
-
-	/*Clean up and return*/
-	delete gauss;
-	xDelete<int>(cs_list);
-	xDelete<IssmDouble>(vbasis);
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Tria::CreatePVectorStressbalanceSSA {{{*/
-ElementVector* Tria::CreatePVectorStressbalanceSSA(){
-
-	/*compute all load vectors for this element*/
-	ElementVector* pe1=CreatePVectorStressbalanceSSADrivingStress();
-	ElementVector* pe2=CreatePVectorStressbalanceSSAFront();
-	ElementVector* pe =new ElementVector(pe1,pe2);
-
-	/*clean-up and return*/
-	delete pe1;
-	delete pe2;
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Tria::CreatePVectorStressbalanceSSADrivingStress {{{*/
-ElementVector* Tria::CreatePVectorStressbalanceSSADrivingStress(){
-
-	/*Intermediaries */
-	int        i;
-	IssmDouble driving_stress_baseline,thickness;
-	IssmDouble Jdet;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble slope[2];
-	IssmDouble icefrontlevel[3];
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Initialize Element vector and vectors*/
-	ElementVector* pe=new ElementVector(nodes,numnodes,this->parameters,SSAApproximationEnum);
-	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	Input* thickness_input=inputs->GetInput(ThicknessEnum); _assert_(thickness_input); 
-	Input* surface_input=inputs->GetInput(SurfaceEnum);     _assert_(surface_input);
-	Input* drag_input=inputs->GetInput(FrictionCoefficientEnum);_assert_(drag_input);
-	GetInputListOnVertices(&icefrontlevel[0],BedEnum);
-
-	/* Start  looping on the number of gaussian points: */
-	GaussTria*     gauss  = new GaussTria(2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		GetNodalFunctions(basis, gauss);
-
-		thickness_input->GetInputValue(&thickness,gauss);
-		surface_input->GetInputDerivativeValue(&slope[0],&xyz_list[0][0],gauss);
-		driving_stress_baseline=matpar->GetRhoIce()*matpar->GetG()*thickness;
-
-		/*Build load vector: */
-		for(i=0;i<numnodes;i++){
-			pe->values[i*NDOF2+0]+=-driving_stress_baseline*slope[0]*Jdet*gauss->weight*basis[i];
-			pe->values[i*NDOF2+1]+=-driving_stress_baseline*slope[1]*Jdet*gauss->weight*basis[i];
-		}
-	}
-
-	/*Transform coordinate system*/
-	TransformLoadVectorCoord(pe,nodes,numnodes,XYEnum);
-
-	/*Clean up and return*/
-	xDelete<IssmDouble>(basis);
-	delete gauss;
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Tria::CreatePVectorStressbalanceSSAFront {{{*/
-ElementVector* Tria::CreatePVectorStressbalanceSSAFront(){
-
-	/*Intermediaries */
-	IssmDouble  ls[NUMVERTICES];
-	IssmDouble  xyz_list[NUMVERTICES][3];
-	bool        isfront;
-
-	/*Retrieve all inputs and parameters*/
-	GetInputListOnVertices(&ls[0],MaskIceLevelsetEnum);
-
-	/*If the level set is awlays <0, there is no ice front here*/
-	isfront = false;
-	if(ls[0]>0. || ls[1]>0. || ls[2]>0.){
-		if(ls[0]*ls[1]<0. || ls[0]*ls[2]<0. || (ls[0]*ls[1]+ls[0]*ls[2]+ls[1]*ls[2]==0.)){
-			isfront = true;
-		}
-	}
-
-	/*If no front, return NULL*/
-	if(!isfront) return NULL;
-
-	/*Intermediaries*/
-	IssmDouble  rho_ice,rho_water,gravity;
-	IssmDouble  Jdet,thickness,bed,water_pressure,ice_pressure,air_pressure;
-	IssmDouble  surface_under_water,base_under_water,pressure;
-	IssmDouble  xyz_list_front[2][3];
-	IssmDouble  area_coordinates[2][3];
-	IssmDouble  normal[2];
-
-	/*Fetch number of nodes for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Initialize Element vector and other vectors*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	ElementVector* pe    = new ElementVector(nodes,numnodes,this->parameters,SSAApproximationEnum);
-	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
-
-	/*Retrieve all inputs and parameters*/
-	Input* thickness_input=inputs->GetInput(ThicknessEnum); _assert_(thickness_input);
-	Input* bed_input      =inputs->GetInput(BedEnum);       _assert_(bed_input);
-	rho_water = matpar->GetRhoWater();
-	rho_ice   = matpar->GetRhoIce();
-	gravity   = matpar->GetG();
-	GetZeroLevelsetCoordinates(&xyz_list_front[0][0],xyz_list,MaskIceLevelsetEnum);
-	GetAreaCoordinates(&area_coordinates[0][0],xyz_list_front,xyz_list,2);
-	GetSegmentNormal(&normal[0],xyz_list_front);
-
-	/*Start looping on Gaussian points*/
-	GaussTria* gauss=new GaussTria(area_coordinates,3);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-		thickness_input->GetInputValue(&thickness,gauss);
-		bed_input->GetInputValue(&bed,gauss);
-		GetSegmentJacobianDeterminant(&Jdet,&xyz_list_front[0][0],gauss);
-		GetNodalFunctions(basis,gauss);
-
-		surface_under_water = min(0.,thickness+bed); // 0 if the top of the glacier is above water level
-		base_under_water    = min(0.,bed);           // 0 if the bottom of the glacier is above water level
-		water_pressure = 1.0/2.0*gravity*rho_water*(pow(surface_under_water,2) - pow(base_under_water,2));
-		ice_pressure   = 1.0/2.0*gravity*rho_ice*pow(thickness,2);
-		air_pressure   = 0;
-		pressure = ice_pressure + water_pressure + air_pressure;
-
-		for (int i=0;i<numnodes;i++){
-			pe->values[2*i+0]+= pressure*Jdet*gauss->weight*normal[0]*basis[i];
-			pe->values[2*i+1]+= pressure*Jdet*gauss->weight*normal[1]*basis[i];
-		}
-	}
-
-	/*Transform coordinate system*/
-	TransformLoadVectorCoord(pe,nodes,numnodes,XYEnum);
-
-	/*Clean up and return*/
-	xDelete<IssmDouble>(basis);
-	delete gauss;
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Tria::CreatePVectorStressbalanceSIA{{{*/
-ElementVector* Tria::CreatePVectorStressbalanceSIA(void){
-
-	/*Intermediaries */
-	IssmDouble constant_part,ub,vb;
-	IssmDouble rho_ice,gravity,n,B;
-	IssmDouble slope2,thickness,connectivity;
-	IssmDouble slope[2];
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodes(); _assert_(numnodes==3); 
-
-	/*Initialize Element vector*/
-	ElementVector* pe=new ElementVector(nodes,numnodes,this->parameters);
-
-	/*Retrieve all inputs and parameters*/
-	rho_ice=matpar->GetRhoIce();
-	gravity=matpar->GetG();
-	n=material->GetN();
-	B=material->GetBbar();
-	Input* slopex_input=inputs->GetInput(SurfaceSlopeXEnum); _assert_(slopex_input);
-	Input* slopey_input=inputs->GetInput(SurfaceSlopeYEnum); _assert_(slopey_input);
-	Input* thickness_input=inputs->GetInput(ThicknessEnum);  _assert_(thickness_input);
-
-	/*Spawn 3 sing elements: */
-	GaussTria* gauss=new GaussTria();
-	for(int i=0;i<numnodes;i++){
-
-		gauss->GaussVertex(i);
-
-		connectivity=(IssmDouble)vertices[i]->Connectivity();
-
-		thickness_input->GetInputValue(&thickness,gauss);
-		slopex_input->GetInputValue(&slope[0],gauss);
-		slopey_input->GetInputValue(&slope[1],gauss);
-		slope2=pow(slope[0],2)+pow(slope[1],2);
-
-		constant_part=-2.*pow(rho_ice*gravity,n)*pow(slope2,((n-1.)/2.));
-
-		ub=-1.58*1.e-10*rho_ice*gravity*thickness*slope[0];
-		vb=-1.58*1.e-10*rho_ice*gravity*thickness*slope[1];
-
-		pe->values[2*i+0]=(ub-2.*pow(rho_ice*gravity,n)*pow(slope2,((n-1.)/2.))*pow(thickness,n)/(pow(B,n)*(n+1))*slope[0])/connectivity;
-		pe->values[2*i+1]=(vb-2.*pow(rho_ice*gravity,n)*pow(slope2,((n-1.)/2.))*pow(thickness,n)/(pow(B,n)*(n+1))*slope[1])/connectivity;
-	}
-
-	/*Clean up and return*/
-	delete gauss;
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Tria::CreateJacobianStressbalanceSSA{{{*/
-ElementMatrix* Tria::CreateJacobianStressbalanceSSA(void){
-
-	/*Intermediaries */
-	int        i,j;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble Jdet,thickness;
-	IssmDouble eps1dotdphii,eps1dotdphij;
-	IssmDouble eps2dotdphii,eps2dotdphij;
-	IssmDouble mu_prime;
-	IssmDouble epsilon[3];/* epsilon=[exx,eyy,exy];*/
-	IssmDouble eps1[2],eps2[2];
-	GaussTria* gauss = NULL;
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Initialize Element matrix, vectors and Gaussian points*/
-	ElementMatrix* Ke=CreateKMatrixStressbalanceSSA(); //Initialize Jacobian with regular SSA (first part of the Gateau derivative)
-	IssmDouble*    dbasis = xNew<IssmDouble>(2*numnodes);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	Input* vx_input=inputs->GetInput(VxEnum);       _assert_(vx_input);
-	Input* vy_input=inputs->GetInput(VyEnum);       _assert_(vy_input);
-	Input* thickness_input=inputs->GetInput(ThicknessEnum); _assert_(thickness_input);
-
-	/* Start  looping on the number of gaussian points: */
-	gauss=new GaussTria(2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		GetNodalFunctionsDerivatives(dbasis,&xyz_list[0][0],gauss);
-
-		thickness_input->GetInputValue(&thickness, gauss);
-		this->GetStrainRate2d(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input);
-		material->GetViscosity2dDerivativeEpsSquare(&mu_prime,&epsilon[0]);
-		eps1[0]=2*epsilon[0]+epsilon[1];   eps2[0]=epsilon[2];
-		eps1[1]=epsilon[2];                eps2[1]=epsilon[0]+2*epsilon[1];
-
-		for(i=0;i<numnodes;i++){
-			for(j=0;j<numnodes;j++){
-				eps1dotdphii=eps1[0]*dbasis[0*numnodes+i]+eps1[1]*dbasis[1*numnodes+i];
-				eps1dotdphij=eps1[0]*dbasis[0*numnodes+j]+eps1[1]*dbasis[1*numnodes+j];
-				eps2dotdphii=eps2[0]*dbasis[0*numnodes+i]+eps2[1]*dbasis[1*numnodes+i];
-				eps2dotdphij=eps2[0]*dbasis[0*numnodes+j]+eps2[1]*dbasis[1*numnodes+j];
-
-				Ke->values[2*numnodes*(2*i+0)+2*j+0]+=gauss->weight*Jdet*2*mu_prime*thickness*eps1dotdphij*eps1dotdphii;
-				Ke->values[2*numnodes*(2*i+0)+2*j+1]+=gauss->weight*Jdet*2*mu_prime*thickness*eps2dotdphij*eps1dotdphii;
-				Ke->values[2*numnodes*(2*i+1)+2*j+0]+=gauss->weight*Jdet*2*mu_prime*thickness*eps1dotdphij*eps2dotdphii;
-				Ke->values[2*numnodes*(2*i+1)+2*j+1]+=gauss->weight*Jdet*2*mu_prime*thickness*eps2dotdphij*eps2dotdphii;
-			}
-		}
-	}
-
-	/*Transform Coordinate System*/
-	TransformStiffnessMatrixCoord(Ke,nodes,numnodes,XYEnum);
-
-	/*Clean up and return*/
-	xDelete<IssmDouble>(dbasis);
-	delete gauss;
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Tria::GetSolutionFromInputsStressbalanceFS{{{*/
-void  Tria::GetSolutionFromInputsStressbalanceFS(Vector<IssmDouble>* solution){
-
-	int*         vdoflist=NULL;
-	int*         pdoflist=NULL;
-	IssmDouble   vx,vy,p;
-	IssmDouble   FSreconditioning;
-	GaussTria   *gauss;
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int vnumnodes = this->NumberofNodesVelocity();
-	int pnumnodes = this->NumberofNodesPressure();
-	int vnumdof   = vnumnodes*NDOF2;
-	int pnumdof   = pnumnodes*NDOF1;
-
-	/*Initialize values*/
-	IssmDouble* vvalues = xNew<IssmDouble>(vnumdof);
-	IssmDouble* pvalues = xNew<IssmDouble>(pnumdof);
-
-	/*Get dof list: */
-	GetDofListVelocity(&vdoflist,GsetEnum);
-	GetDofListPressure(&pdoflist,GsetEnum);
-	Input* vx_input=inputs->GetInput(VxEnum);       _assert_(vx_input);
-	Input* vy_input=inputs->GetInput(VyEnum);       _assert_(vy_input);
-	Input* p_input =inputs->GetInput(PressureEnum); _assert_(p_input);
-
-	this->parameters->FindParam(&FSreconditioning,StressbalanceFSreconditioningEnum);
-
-	/*Ok, we have vx vy vz in values, fill in vx vy vz arrays: */
-	gauss = new GaussTria();
-	for(int i=0;i<vnumnodes;i++){
-		gauss->GaussNode(this->VelocityInterpolation(),i);
-		vx_input->GetInputValue(&vx,gauss);
-		vy_input->GetInputValue(&vy,gauss);
-		vvalues[i*NDOF2+0]=vx;
-		vvalues[i*NDOF2+1]=vy;
-	}
-	for(int i=0;i<pnumnodes;i++){
-		gauss->GaussNode(this->PressureInterpolation(),i);
-		p_input->GetInputValue(&p ,gauss);
-		pvalues[i]=p/FSreconditioning;
-	}
-
-	/*Add value to global vector*/
-	solution->SetValues(vnumdof,vdoflist,vvalues,INS_VAL);
-	solution->SetValues(pnumdof,pdoflist,pvalues,INS_VAL);
-
-	/*Free ressources:*/
-	delete gauss;
-	xDelete<int>(pdoflist);
-	xDelete<int>(vdoflist);
-	xDelete<IssmDouble>(pvalues);
-	xDelete<IssmDouble>(vvalues);
-}
-/*}}}*/
-/*FUNCTION Tria::GetSolutionFromInputsStressbalanceHoriz{{{*/
-void  Tria::GetSolutionFromInputsStressbalanceHoriz(Vector<IssmDouble>* solution){
-
-	IssmDouble   vx,vy;
-	int*         doflist = NULL;
-	GaussTria*   gauss   = NULL;
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodes();
-	int numdof   = numnodes*NDOF2;
-
-	/*Fetch dof list and allocate solution vector*/
-	GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
-	IssmDouble* values = xNew<IssmDouble>(numdof);
-
-	/*Get inputs*/
-	Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);
-	Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);
-
-	/*Ok, we have vx and vy in values, fill in vx and vy arrays: */
-	gauss=new GaussTria();
-	for(int i=0;i<numnodes;i++){
-		gauss->GaussNode(this->element_type,i);
-
-		/*Recover vx and vy*/
-		vx_input->GetInputValue(&vx,gauss);
-		vy_input->GetInputValue(&vy,gauss);
-		values[i*NDOF2+0]=vx;
-		values[i*NDOF2+1]=vy;
-	}
-
-	solution->SetValues(numdof,doflist,values,INS_VAL);
-
-	/*Free ressources:*/
-	delete gauss;
-	xDelete<IssmDouble>(values);
-	xDelete<int>(doflist);
-}
-/*}}}*/
-/*FUNCTION Tria::GetSolutionFromInputsStressbalanceSIA{{{*/
-void  Tria::GetSolutionFromInputsStressbalanceSIA(Vector<IssmDouble>* solution){
-
-	const int    numdof=NDOF2*NUMVERTICES;
-
-	int        i;
-	IssmDouble     vx,vy;
-	IssmDouble     values[numdof];
-	int       *doflist = NULL;
-	GaussTria *gauss   = NULL;
-
-	/*Get dof list: */
-	GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
-
-	/*Get inputs*/
-	Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);
-	Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);
-
-	/*Ok, we have vx and vy in values, fill in vx and vy arrays: */
-	/*P1 element only for now*/
-	gauss=new GaussTria();
-	for(i=0;i<NUMVERTICES;i++){
-
-		gauss->GaussVertex(i);
-
-		/*Recover vx and vy*/
-		vx_input->GetInputValue(&vx,gauss);
-		vy_input->GetInputValue(&vy,gauss);
-		values[i*NDOF2+0]=vx;
-		values[i*NDOF2+1]=vy;
-	}
-
-	solution->SetValues(numdof,doflist,values,INS_VAL);
-
-	/*Free ressources:*/
-	delete gauss;
-	xDelete<int>(doflist);
-}
-/*}}}*/
-/*FUNCTION Tria::GetYcoord {{{*/
-IssmDouble Tria::GetYcoord(GaussTria* gauss){
-
-	IssmDouble y;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble y_list[NUMVERTICES];
-
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	for(int i=0;i<NUMVERTICES;i++) y_list[i]=xyz_list[i][1];
-	TriaRef::GetInputValue(&y,&y_list[0],gauss,P1Enum);
-
-	return y;
-}
-/*}}}*/
-/*FUNCTION Tria::InputUpdateFromSolutionStressbalanceHoriz {{{*/
-void  Tria::InputUpdateFromSolutionStressbalanceHoriz(IssmDouble* solution){
-
-	int        i;
-	IssmDouble rho_ice,g;
-	int*       doflist=NULL;
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodes();
-	int numdof   = numnodes*NDOF2;
-
-	/*Fetch dof list and allocate solution vectors*/
-	GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
-	IssmDouble* values    = xNew<IssmDouble>(numdof);
-	IssmDouble* vx        = xNew<IssmDouble>(numnodes);
-	IssmDouble* vy        = xNew<IssmDouble>(numnodes);
-	IssmDouble* vz        = xNew<IssmDouble>(numnodes);
-	IssmDouble* vel       = xNew<IssmDouble>(numnodes);
-	IssmDouble* pressure  = xNew<IssmDouble>(numnodes);
-	IssmDouble* thickness = xNew<IssmDouble>(numnodes);
-
-	/*Use the dof list to index into the solution vector: */
-	for(i=0;i<numdof;i++) values[i]=solution[doflist[i]];
-
-	/*Transform solution in Cartesian Space*/
-	TransformSolutionCoord(&values[0],nodes,numnodes,XYEnum);
-
-	/*Ok, we have vx and vy in values, fill in vx and vy arrays: */
-	for(i=0;i<numnodes;i++){
-		vx[i]=values[i*NDOF2+0];
-		vy[i]=values[i*NDOF2+1];
-
-		/*Check solution*/
-		if(xIsNan<IssmDouble>(vx[i])) _error_("NaN found in solution vector");
-		if(xIsNan<IssmDouble>(vy[i])) _error_("NaN found in solution vector");
-	}
-
-	/*Get Vz and compute vel*/
-	GetInputListOnNodes(&vz[0],VzEnum,0.);
-	for(i=0;i<numnodes;i++) vel[i]=sqrt(vx[i]*vx[i] + vy[i]*vy[i] + vz[i]*vz[i]);
-
-	/*For pressure: we have not computed pressure in this analysis, for this element. We are in 2D, 
-	 *so the pressure is just the pressure at the bedrock: */
-	rho_ice=matpar->GetRhoIce();
-	g=matpar->GetG();
-	GetInputListOnNodes(&thickness[0],ThicknessEnum);
-	for(i=0;i<numnodes;i++) pressure[i]=rho_ice*g*thickness[i];
-
-	/*Now, we have to move the previous Vx and Vy inputs  to old 
-	 * status, otherwise, we'll wipe them off: */
-	this->inputs->ChangeEnum(VxEnum,VxPicardEnum);
-	this->inputs->ChangeEnum(VyEnum,VyPicardEnum);
-	this->inputs->ChangeEnum(PressureEnum,PressurePicardEnum);
-
-	/*Add vx and vy as inputs to the tria element: */
-	this->inputs->AddInput(new TriaInput(VxEnum,vx,P1Enum));
-	this->inputs->AddInput(new TriaInput(VyEnum,vy,P1Enum));
-	this->inputs->AddInput(new TriaInput(VelEnum,vel,P1Enum));
-	this->inputs->AddInput(new TriaInput(PressureEnum,pressure,P1Enum));
-
-	/*Free ressources:*/
-	xDelete<IssmDouble>(thickness);
-	xDelete<IssmDouble>(pressure);
-	xDelete<IssmDouble>(vel);
-	xDelete<IssmDouble>(vz);
-	xDelete<IssmDouble>(vy);
-	xDelete<IssmDouble>(vx);
-	xDelete<IssmDouble>(values);
-	xDelete<int>(doflist);
-
-}
-/*}}}*/
-/*FUNCTION Tria::InputUpdateFromSolutionStressbalanceFS {{{*/
-void  Tria::InputUpdateFromSolutionStressbalanceFS(IssmDouble* solution){
-
-	int          i;
-	int*         vdoflist=NULL;
-	int*         pdoflist=NULL;
-	IssmDouble   FSreconditioning;
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int vnumnodes = this->NumberofNodesVelocity();
-	int pnumnodes = this->NumberofNodesPressure();
-	int vnumdof   = vnumnodes*NDOF2;
-	int pnumdof   = pnumnodes*NDOF1;
-
-	/*Initialize values*/
-	IssmDouble* values   = xNew<IssmDouble>(vnumdof+pnumdof);
-	IssmDouble* vx       = xNew<IssmDouble>(vnumnodes);
-	IssmDouble* vy       = xNew<IssmDouble>(vnumnodes);
-	IssmDouble* vel      = xNew<IssmDouble>(vnumnodes);
-	IssmDouble* pressure = xNew<IssmDouble>(pnumnodes);
-
-	/*Prepare coordinate system list*/
-	int* cs_list = xNew<int>(vnumnodes+pnumnodes);
-	for(i=0;i<vnumnodes;i++) cs_list[i]           = XYEnum;
-	for(i=0;i<pnumnodes;i++) cs_list[vnumnodes+i] = PressureEnum;
-
-	/*Get dof list: */
-	GetDofListVelocity(&vdoflist,GsetEnum);
-	GetDofListPressure(&pdoflist,GsetEnum);
-
-	/*Use the dof list to index into the solution vector: */
-	for(i=0;i<vnumdof;i++) values[i]        =solution[vdoflist[i]];
-	for(i=0;i<pnumdof;i++) values[vnumdof+i]=solution[pdoflist[i]];
-
-	/*Transform solution in Cartesian Space*/
-	TransformSolutionCoord(&values[0],nodes,vnumnodes+pnumdof,cs_list);
-
-	/*Ok, we have vx and vy in values, fill in all arrays: */
-	for(i=0;i<vnumnodes;i++){
-		vx[i] = values[i*NDOF2+0];
-		vy[i] = values[i*NDOF2+1];
-		if(xIsNan<IssmDouble>(vx[i])) _error_("NaN found in solution vector");
-		if(xIsNan<IssmDouble>(vy[i])) _error_("NaN found in solution vector");
-	}
-	for(i=0;i<pnumnodes;i++){
-		pressure[i] = values[vnumdof+i];
-		if(xIsNan<IssmDouble>(pressure[i])) _error_("NaN found in solution vector");
-	}
-
-	/*Recondition pressure and compute vel: */
-	this->parameters->FindParam(&FSreconditioning,StressbalanceFSreconditioningEnum);
-	for(i=0;i<pnumnodes;i++) pressure[i] = pressure[i]*FSreconditioning;
-	for(i=0;i<vnumnodes;i++) vel[i]      = sqrt(vx[i]*vx[i] + vy[i]*vy[i]);
-
-	/*Now, we have to move the previous inputs  to old 
-	 * status, otherwise, we'll wipe them off: */
-	this->inputs->ChangeEnum(VxEnum,VxPicardEnum);
-	this->inputs->ChangeEnum(VyEnum,VyPicardEnum);
-	this->inputs->ChangeEnum(PressureEnum,PressurePicardEnum);
-
-	/*Add vx and vy as inputs to the tria element: */
-	this->inputs->AddInput(new TriaInput(VxEnum,vx,P1Enum));
-	this->inputs->AddInput(new TriaInput(VyEnum,vy,P1Enum));
-	this->inputs->AddInput(new TriaInput(VelEnum,vel,P1Enum));
-	this->inputs->AddInput(new TriaInput(PressureEnum,pressure,P1Enum));
-
-	/*Free ressources:*/
-	xDelete<IssmDouble>(pressure);
-	xDelete<IssmDouble>(vel);
-	xDelete<IssmDouble>(vy);
-	xDelete<IssmDouble>(vx);
-	xDelete<IssmDouble>(values);
-	xDelete<int>(vdoflist);
-	xDelete<int>(pdoflist);
-	xDelete<int>(cs_list);
-}
-/*}}}*/
-/*FUNCTION Tria::InputUpdateFromSolutionStressbalanceSIA {{{*/
-void  Tria::InputUpdateFromSolutionStressbalanceSIA(IssmDouble* solution){
-
-	int        i;
-	IssmDouble rho_ice,g;
-	int*       doflist=NULL;
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodes();
-	int numdof   = numnodes*NDOF2;
-
-	/*Fetch dof list and allocate solution vectors*/
-	GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
-	IssmDouble* values    = xNew<IssmDouble>(numdof);
-	IssmDouble* vx        = xNew<IssmDouble>(numdof);
-	IssmDouble* vy        = xNew<IssmDouble>(numdof);
-	IssmDouble* vz        = xNew<IssmDouble>(numdof);
-	IssmDouble* vel       = xNew<IssmDouble>(numdof);
-	IssmDouble* pressure  = xNew<IssmDouble>(numdof);
-	IssmDouble* thickness = xNew<IssmDouble>(numdof);
-
-	/*Use the dof list to index into the solution vector: */
-	for(i=0;i<numdof;i++) values[i]=solution[doflist[i]];
-
-	/*Transform solution in Cartesian Space*/
-	TransformSolutionCoord(&values[0],nodes,numnodes,XYEnum);
-
-	/*Ok, we have vx and vy in values, fill in vx and vy arrays: */
-	for(i=0;i<numnodes;i++){
-		vx[i]=values[i*NDOF2+0];
-		vy[i]=values[i*NDOF2+1];
-
-		/*Check solution*/
-		if(xIsNan<IssmDouble>(vx[i])) _error_("NaN found in solution vector");
-		if(xIsNan<IssmDouble>(vy[i])) _error_("NaN found in solution vector");
-	}
-
-	/*Get Vz and compute vel*/
-	GetInputListOnNodes(&vz[0],VzEnum,0.);
-	for(i=0;i<numnodes;i++) vel[i]=sqrt(vx[i]*vx[i] + vy[i]*vy[i] + vz[i]*vz[i]);
-
-	/*For pressure: we have not computed pressure in this analysis, for this element. We are in 2D, 
-	 *so the pressure is just the pressure at the bedrock: */
-	rho_ice=matpar->GetRhoIce();
-	g=matpar->GetG();
-	GetInputListOnNodes(&thickness[0],ThicknessEnum);
-	for(i=0;i<numnodes;i++) pressure[i]=rho_ice*g*thickness[i];
-
-	/*Now, we have to move the previous Vx and Vy inputs  to old 
-	 * status, otherwise, we'll wipe them off: */
-	this->inputs->ChangeEnum(VxEnum,VxPicardEnum);
-	this->inputs->ChangeEnum(VyEnum,VyPicardEnum);
-	this->inputs->ChangeEnum(PressureEnum,PressurePicardEnum);
-
-	/*Add vx and vy as inputs to the tria element: */
-	this->inputs->AddInput(new TriaInput(VxEnum,vx,P1Enum));
-	this->inputs->AddInput(new TriaInput(VyEnum,vy,P1Enum));
-	this->inputs->AddInput(new TriaInput(VelEnum,vel,P1Enum));
-	this->inputs->AddInput(new TriaInput(PressureEnum,pressure,P1Enum));
-
-	/*Free ressources:*/
-	xDelete<IssmDouble>(thickness);
-	xDelete<IssmDouble>(pressure);
-	xDelete<IssmDouble>(vel);
-	xDelete<IssmDouble>(vz);
-	xDelete<IssmDouble>(vy);
-	xDelete<IssmDouble>(vx);
-	xDelete<IssmDouble>(values);
-	xDelete<int>(doflist);
-}
-/*}}}*/
-#endif
-
-#ifdef _HAVE_CONTROL_
 /*FUNCTION Tria::BalancethicknessMisfit{{{*/
 IssmDouble Tria::BalancethicknessMisfit(void){
@@ -4591,8 +2837,8 @@
 
 	/*If on water, return 0: */
-	if(NoIceInElement()) return 0;
+	if(!IsIceInElement()) return 0;
 
 	/*Retrieve all inputs we will be needing: */
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
 	Input* weights_input              = inputs->GetInput(InversionCostFunctionsCoefficientsEnum);   _assert_(weights_input);
 	Input* thickness_input            = inputs->GetInput(ThicknessEnum); _assert_(thickness_input);
@@ -4647,12 +2893,5 @@
 
 	for(int i=0;i<num_controls;i++){
-
-		if(control_type[i]==MaterialsRheologyBbarEnum || control_type[i]==DamageDbarEnum){
-			input=(Input*)material->inputs->GetInput(control_type[i]); _assert_(input);
-		}
-		else{
-			input=(Input*)this->inputs->GetInput(control_type[i]);   _assert_(input);
-		}
-
+		input=(Input*)this->inputs->GetInput(control_type[i]);   _assert_(input);
 		if (input->ObjectEnum()!=ControlInputEnum){
 			_error_("input " << EnumToStringx(control_type[i]) << " is not a ControlInput");
@@ -4673,12 +2912,6 @@
 
 	int vertexpidlist[NUMVERTICES];
-	Input* input=NULL;
-
-	if(enum_type==MaterialsRheologyBbarEnum || enum_type==DamageDbarEnum){
-		input=(Input*)material->inputs->GetInput(enum_type);
-	}
-	else{
-		input=inputs->GetInput(enum_type);
-	}
+
+	Input* input=inputs->GetInput(enum_type);
 	if (!input) _error_("Input " << EnumToStringx(enum_type) << " not found");
 	if (input->ObjectEnum()!=ControlInputEnum) _error_("Input " << EnumToStringx(enum_type) << " is not a ControlInput");
@@ -4691,12 +2924,5 @@
 void Tria::ControlInputScaleGradient(int enum_type,IssmDouble scale){
 
-	Input* input=NULL;
-
-	if(enum_type==MaterialsRheologyBbarEnum || enum_type==DamageDbarEnum){
-		input=(Input*)material->inputs->GetInput(enum_type);
-	}
-	else{
-		input=inputs->GetInput(enum_type);
-	}
+	Input* input=inputs->GetInput(enum_type);
 	if (!input) _error_("Input " << EnumToStringx(enum_type) << " not found");
 	if (input->ObjectEnum()!=ControlInputEnum) _error_("Input " << EnumToStringx(enum_type) << " is not a ControlInput");
@@ -4710,12 +2936,6 @@
 	IssmDouble grad_list[NUMVERTICES];
 	Input* grad_input=NULL;
-	Input* input=NULL;
-
-	if(enum_type==MaterialsRheologyBbarEnum || enum_type==DamageDbarEnum){
-		input=(Input*)material->inputs->GetInput(enum_type);
-	}
-	else{
-		input=inputs->GetInput(enum_type);
-	}
+
+	Input* input=inputs->GetInput(enum_type);
 	if (!input) _error_("Input " << EnumToStringx(enum_type) << " not found");
 	if (input->ObjectEnum()!=ControlInputEnum) _error_("Input " << EnumToStringx(enum_type) << " is not a ControlInput");
@@ -4731,11 +2951,5 @@
 void Tria::ControlToVectors(Vector<IssmPDouble>* vector_control, Vector<IssmPDouble>* vector_gradient,int control_enum){
 
-	Input* input=NULL;
-	if(control_enum==MaterialsRheologyBbarEnum || control_enum==DamageDbarEnum){
-		input=(Input*)material->inputs->GetInput(control_enum);
-	}
-	else{
-		input=inputs->GetInput(control_enum);
-	}
+	Input* input=inputs->GetInput(control_enum);
 	if (!input) _error_("Input " << EnumToStringx(control_enum) << " not found");
 	if (input->ObjectEnum()!=ControlInputEnum) _error_("Input " << EnumToStringx(control_enum) << " is not a ControlInput");
@@ -4747,6 +2961,6 @@
 	IssmDouble  value,gradient;
 
-	this->GetConnectivityList(&connectivity[0]);
-	this->GetVertexSidList(&sidlist[0]);
+	this->GetVerticesConnectivityList(&connectivity[0]);
+	this->GetVerticesSidList(&sidlist[0]);
 
 	GaussTria* gauss=new GaussTria();
@@ -4771,5 +2985,5 @@
 
 	/*If on water, grad = 0: */
-	if(NoIceInElement()) return;
+	if(!IsIceInElement()) return;
 
 	/*First deal with ∂/∂alpha(KU-F)*/
@@ -4847,7 +3061,7 @@
 
 	/*Retrieve all inputs we will be needing: */
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
 	GradientIndexing(&vertexpidlist[0],control_index);
-	Input* rheologyb_input=material->inputs->GetInput(MaterialsRheologyBbarEnum); _assert_(rheologyb_input);
+	Input* rheologyb_input=inputs->GetInput(MaterialsRheologyBbarEnum); _assert_(rheologyb_input);
 	Input* weights_input=inputs->GetInput(InversionCostFunctionsCoefficientsEnum);                _assert_(weights_input);
 
@@ -4889,5 +3103,5 @@
 
 	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
 	GradientIndexing(&doflist[0],control_index);
 
@@ -4898,5 +3112,5 @@
 	Input* adjointx_input=inputs->GetInput(AdjointxEnum);                       _assert_(adjointx_input);
 	Input* adjointy_input=inputs->GetInput(AdjointyEnum);                       _assert_(adjointy_input);
-	Input* rheologyb_input=material->inputs->GetInput(MaterialsRheologyBbarEnum); _assert_(rheologyb_input);
+	Input* rheologyb_input=inputs->GetInput(MaterialsRheologyBbarEnum); _assert_(rheologyb_input);
 
 	/* Start  looping on the number of gaussian points: */
@@ -4913,5 +3127,5 @@
 		adjointy_input->GetInputDerivativeValue(&dadjy[0],&xyz_list[0][0],gauss);
 
-		this->GetStrainRate2d(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input);
+		this->StrainRateSSA(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input);
 		material->GetViscosityComplement(&viscosity_complement,&epsilon[0]);
 
@@ -4946,5 +3160,5 @@
 
 	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
 	GradientIndexing(&doflist[0],control_index);
 
@@ -4955,5 +3169,7 @@
 	Input* adjointx_input=inputs->GetInput(AdjointxEnum);                       _assert_(adjointx_input);
 	Input* adjointy_input=inputs->GetInput(AdjointyEnum);                       _assert_(adjointy_input);
-	Input* rheologyd_input=material->inputs->GetInput(DamageDbarEnum); _assert_(rheologyd_input);
+	if(this->material->IsDamage()){
+		Input* rheologyd_input=inputs->GetInput(DamageDbarEnum); _assert_(rheologyd_input);
+	}
 
 	/* Start  looping on the number of gaussian points: */
@@ -4969,5 +3185,5 @@
 		adjointy_input->GetInputDerivativeValue(&dadjy[0],&xyz_list[0][0],gauss);
 
-		this->GetStrainRate2d(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input);
+		this->StrainRateSSA(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input);
 		material->GetViscosityDComplement(&viscosity_complement,&epsilon[0]);
 
@@ -5008,10 +3224,10 @@
 	/*retrive parameters: */
 	parameters->FindParam(&analysis_type,AnalysisTypeEnum);
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
 	GradientIndexing(&vertexpidlist[0],control_index);
-	this->GetConnectivityList(&connectivity[0]);
+	this->GetVerticesConnectivityList(&connectivity[0]);
 
 	/*Build frictoin element, needed later: */
-	friction=new Friction("2d",inputs,matpar,analysis_type);
+	friction=new Friction(this,2);
 
 	/*Retrieve all inputs we will be needing: */
@@ -5032,5 +3248,5 @@
 
 		/*Build alpha_complement_list: */
-		friction->GetAlphaComplement(&alpha_complement, gauss,VxEnum,VyEnum,VzEnum);
+		friction->GetAlphaComplement(&alpha_complement,gauss,vx_input,vy_input,NULL);
 
 		dragcoefficient_input->GetInputValue(&drag, gauss);
@@ -5057,5 +3273,5 @@
 	//for (int iv=0;iv<NUMVERTICES;iv++){
 	//	gauss->GaussVertex(iv);
-	//	friction->GetAlphaComplement(&alpha_complement, gauss,VxEnum,VyEnum,VzEnum);
+	//	friction->GetAlphaComplement(&alpha_complement,gauss,vx_input,vy_input,vz_input);
 	//	dragcoefficient_input->GetInputValue(&drag, gauss);
 	//	adjointx_input->GetInputValue(&lambda, gauss);
@@ -5088,5 +3304,5 @@
 	/*Retrieve all inputs we will be needing: */
 	if(IsFloating())return;
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
 	GradientIndexing(&vertexpidlist[0],control_index);
 	Input* dragcoefficient_input=inputs->GetInput(FrictionCoefficientEnum); _assert_(dragcoefficient_input);
@@ -5148,5 +3364,5 @@
 
 	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
 	GradientIndexing(&vertexpidlist[0],control_index);
 
@@ -5191,5 +3407,5 @@
 
 	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
 	GradientIndexing(&vertexpidlist[0],control_index);
 
@@ -5240,9 +3456,9 @@
 
 	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
 	GradientIndexing(&vertexpidlist[0],control_index);
 
 	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
 	this->parameters->FindParam(&num_responses,InversionNumCostFunctionsEnum);
 	this->parameters->FindParam(&responses,NULL,InversionCostFunctionsEnum);
@@ -5356,10 +3572,10 @@
 
 	/*If on water, return 0: */
-	if(NoIceInElement()) return 0;
+	if(!IsIceInElement()) return 0;
 
 	/*Retrieve all inputs we will be needing: */
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
 	Input* weights_input  =inputs->GetInput(InversionCostFunctionsCoefficientsEnum);              _assert_(weights_input);
-	Input* rheologyb_input=material->inputs->GetInput(MaterialsRheologyBbarEnum); _assert_(rheologyb_input);
+	Input* rheologyb_input=inputs->GetInput(MaterialsRheologyBbarEnum); _assert_(rheologyb_input);
 
 	/* Start looping on the number of gaussian points: */
@@ -5395,8 +3611,8 @@
 
 	/*If on water, return 0: */
-	if(NoIceInElement())return 0;
+	if(!IsIceInElement())return 0;
 
 	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
 
 	/*Retrieve all inputs we will be needing: */
@@ -5454,8 +3670,8 @@
 
 	/*If on water, return 0: */
-	if(NoIceInElement())return 0;
+	if(!IsIceInElement())return 0;
 
 	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
 
 	/*Retrieve all inputs we will be needing: */
@@ -5513,8 +3729,8 @@
 
 	/*If on water, return 0: */
-	if(NoIceInElement())return 0;
+	if(!IsIceInElement())return 0;
 
 	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
 
 	/*Retrieve all inputs we will be needing: */
@@ -5571,8 +3787,8 @@
 
 	/*If on water, return 0: */
-	if(NoIceInElement())return 0;
+	if(!IsIceInElement())return 0;
 
 	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
 
 	/*Retrieve all inputs we will be needing: */
@@ -5630,8 +3846,8 @@
 
 	/*If on water, return 0: */
-	if(NoIceInElement())return 0;
+	if(!IsIceInElement())return 0;
 
 	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
 
 	/*Retrieve all inputs we will be needing: */
@@ -5692,8 +3908,8 @@
 
 	/*If on water, return 0: */
-	if(NoIceInElement()) return 0;
+	if(!IsIceInElement()) return 0;
 
 	/*Retrieve all inputs we will be needing: */
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
 	Input* weights_input  =inputs->GetInput(InversionCostFunctionsCoefficientsEnum);   _assert_(weights_input);
 	Input* thickness_input=inputs->GetInput(ThicknessEnum); _assert_(thickness_input);
@@ -5736,8 +3952,8 @@
 
 	/*If on water, return 0: */
-	if(NoIceInElement()) return 0;
+	if(!IsIceInElement()) return 0;
 
 	/*Retrieve all inputs we will be needing: */
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
 	Input* weights_input  = inputs->GetInput(InversionCostFunctionsCoefficientsEnum); _assert_(weights_input);
 	Input* thickness_input= inputs->GetInput(ThicknessEnum);                          _assert_(thickness_input);
@@ -5787,8 +4003,8 @@
 
 	/*If on water, return 0: */
-	if(NoIceInElement()) return 0;
+	if(!IsIceInElement()) return 0;
 
 	/*Retrieve all inputs we will be needing: */
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
 	Input* weights_input  = inputs->GetInput(InversionCostFunctionsCoefficientsEnum); _assert_(weights_input);
 	Input* thickness_input= inputs->GetInput(ThicknessEnum);                          _assert_(thickness_input);
@@ -5835,8 +4051,8 @@
 
 	/*If on water, return 0: */
-	if(NoIceInElement())return 0;
+	if(!IsIceInElement())return 0;
 
 	/*Retrieve all inputs we will be needing: */
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
 	Input* thickness_input   =inputs->GetInput(ThicknessEnum);   _assert_(thickness_input);
 	Input* thicknessobs_input=inputs->GetInput(InversionThicknessObsEnum);_assert_(thicknessobs_input);
@@ -5865,277 +4081,4 @@
 	delete gauss;
 	return Jelem;
-}
-/*}}}*/
-/*FUNCTION Tria::CreatePVectorAdjointBalancethickness{{{*/
-ElementVector* Tria::CreatePVectorAdjointBalancethickness(void){
-
-	/*Intermediaries */
-	int        i,resp;
-	IssmDouble Jdet;
-	IssmDouble thickness,thicknessobs,weight;
-	int        num_responses;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble dH[2];
-	IssmDouble vx,vy,vel;
-	int       *responses = NULL;
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Initialize Element vector and vectors*/
-	ElementVector* pe     = new ElementVector(nodes,numnodes,this->parameters);
-	IssmDouble*    basis  = xNew<IssmDouble>(numnodes);
-	IssmDouble*    dbasis = xNew<IssmDouble>(2*numnodes);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	this->parameters->FindParam(&num_responses,InversionNumCostFunctionsEnum);
-	this->parameters->FindParam(&responses,NULL,InversionCostFunctionsEnum);
-	Input* thickness_input    = inputs->GetInput(ThicknessEnum);                          _assert_(thickness_input);
-	Input* thicknessobs_input = inputs->GetInput(InversionThicknessObsEnum);              _assert_(thicknessobs_input);
-	Input* weights_input      = inputs->GetInput(InversionCostFunctionsCoefficientsEnum); _assert_(weights_input);
-	Input* vx_input           = inputs->GetInput(VxEnum);                                 _assert_(vx_input);
-	Input* vy_input           = inputs->GetInput(VyEnum);                                 _assert_(vy_input);
-
-	/* Start  looping on the number of gaussian points: */
-	GaussTria* gauss=new GaussTria(2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		GetNodalFunctions(basis, gauss);
-		GetNodalFunctionsDerivatives(dbasis,&xyz_list[0][0],gauss);
-
-		thickness_input->GetInputValue(&thickness, gauss);
-		thickness_input->GetInputDerivativeValue(&dH[0],&xyz_list[0][0],gauss);
-		thicknessobs_input->GetInputValue(&thicknessobs, gauss);
-
-		/*Loop over all requested responses*/
-		for(resp=0;resp<num_responses;resp++){
-
-			weights_input->GetInputValue(&weight,gauss,responses[resp]);
-
-			switch(responses[resp]){
-				case ThicknessAbsMisfitEnum:
-					for(i=0;i<numnodes;i++) pe->values[i]+=(thicknessobs-thickness)*weight*Jdet*gauss->weight*basis[i];
-					break;
-				case ThicknessAbsGradientEnum:
-					for(i=0;i<numnodes;i++) pe->values[i]+= - weight*dH[0]*dbasis[0*numnodes+i]*Jdet*gauss->weight;
-					for(i=0;i<numnodes;i++) pe->values[i]+= - weight*dH[1]*dbasis[1*numnodes+i]*Jdet*gauss->weight;
-					break;
-				case ThicknessAlongGradientEnum:
-					vx_input->GetInputValue(&vx,gauss);
-					vy_input->GetInputValue(&vy,gauss);
-					vel = sqrt(vx*vx+vy*vy);
-					vx  = vx/(vel+1.e-9);
-					vy  = vy/(vel+1.e-9);
-					for(i=0;i<numnodes;i++) pe->values[i]+= - weight*(dH[0]*vx+dH[1]*vy)*(dbasis[0*numnodes+i]*vx+dbasis[1*numnodes+i]*vy)*Jdet*gauss->weight;
-					break;
-				case ThicknessAcrossGradientEnum:
-					vx_input->GetInputValue(&vx,gauss);
-					vy_input->GetInputValue(&vy,gauss);
-					vel = sqrt(vx*vx+vy*vy);
-					vx  = vx/(vel+1.e-9);
-					vy  = vy/(vel+1.e-9);
-					for(i=0;i<numnodes;i++) pe->values[i]+= - weight*(dH[0]*(-vy)+dH[1]*vx)*(dbasis[0*numnodes+i]*(-vy)+dbasis[1*numnodes+i]*vx)*Jdet*gauss->weight;
-					break;
-				default:
-					_error_("response " << EnumToStringx(responses[resp]) << " not supported yet");
-			}
-		}
-	}
-
-	/*Clean up and return*/
-	xDelete<IssmDouble>(basis);
-	xDelete<IssmDouble>(dbasis);
-	xDelete<int>(responses);
-	delete gauss;
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Tria::CreatePVectorAdjointHoriz{{{*/
-ElementVector* Tria::CreatePVectorAdjointHoriz(void){
-
-	/*Intermediaries */
-	int        i,resp;
-	int       *responses=NULL;
-	int        num_responses;
-	IssmDouble Jdet;
-	IssmDouble obs_velocity_mag,velocity_mag;
-	IssmDouble dux,duy;
-	IssmDouble epsvel=2.220446049250313e-16;
-	IssmDouble meanvel=3.170979198376458e-05; /*1000 m/yr*/
-	IssmDouble scalex=0.,scaley=0.,scale=0.,S=0.;
-	IssmDouble vx,vy,vxobs,vyobs,weight;
-	IssmDouble xyz_list[NUMVERTICES][3];
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Initialize Element vector*/
-	ElementVector* pe    = new ElementVector(nodes,numnodes,this->parameters);
-	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	this->parameters->FindParam(&num_responses,InversionNumCostFunctionsEnum);
-	this->parameters->FindParam(&responses,NULL,InversionCostFunctionsEnum);
-	Input* weights_input=inputs->GetInput(InversionCostFunctionsCoefficientsEnum);   _assert_(weights_input);
-	Input* vx_input     =inputs->GetInput(VxEnum);        _assert_(vx_input);
-	Input* vy_input     =inputs->GetInput(VyEnum);        _assert_(vy_input);
-	Input* vxobs_input  =inputs->GetInput(InversionVxObsEnum);     _assert_(vxobs_input);
-	Input* vyobs_input  =inputs->GetInput(InversionVyObsEnum);     _assert_(vyobs_input);
-
-	/*Get Surface if required by one response*/
-	for(resp=0;resp<num_responses;resp++){
-		if(responses[resp]==SurfaceAverageVelMisfitEnum){
-			inputs->GetInputValue(&S,SurfaceAreaEnum); break;
-		}
-	}
-
-	/* Start  looping on the number of gaussian points: */
-	GaussTria* gauss=new GaussTria(4);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		/* Get Jacobian determinant: */
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-
-		/*Get all parameters at gaussian point*/
-		vx_input->GetInputValue(&vx,gauss);
-		vy_input->GetInputValue(&vy,gauss);
-		vxobs_input->GetInputValue(&vxobs,gauss);
-		vyobs_input->GetInputValue(&vyobs,gauss);
-		GetNodalFunctions(basis, gauss);
-
-		/*Loop over all requested responses*/
-		for(resp=0;resp<num_responses;resp++){
-
-			weights_input->GetInputValue(&weight,gauss,responses[resp]);
-
-			switch(responses[resp]){
-				case SurfaceAbsVelMisfitEnum:
-					/*
-					 *      1  [           2              2 ]
-					 * J = --- | (u - u   )  +  (v - v   )  |
-					 *      2  [       obs            obs   ]
-					 *
-					 *        dJ
-					 * DU = - -- = (u   - u )
-					 *        du     obs
-					 */
-					for(i=0;i<numnodes;i++){
-						dux=vxobs-vx;
-						duy=vyobs-vy;
-						pe->values[i*NDOF2+0]+=dux*weight*Jdet*gauss->weight*basis[i]; 
-						pe->values[i*NDOF2+1]+=duy*weight*Jdet*gauss->weight*basis[i]; 
-					}
-					break;
-				case SurfaceRelVelMisfitEnum:
-					/*
-					 *      1  [     \bar{v}^2             2   \bar{v}^2              2 ]
-					 * J = --- | -------------  (u - u   ) + -------------  (v - v   )  |
-					 *      2  [  (u   + eps)^2       obs    (v   + eps)^2       obs    ]
-					 *              obs                        obs                      
-					 *
-					 *        dJ     \bar{v}^2
-					 * DU = - -- = ------------- (u   - u )
-					 *        du   (u   + eps)^2    obs
-					 *               obs
-					 */
-					for(i=0;i<numnodes;i++){
-						scalex=pow(meanvel/(vxobs+epsvel),2); if(vxobs==0)scalex=0;
-						scaley=pow(meanvel/(vyobs+epsvel),2); if(vyobs==0)scaley=0;
-						dux=scalex*(vxobs-vx);
-						duy=scaley*(vyobs-vy);
-						pe->values[i*NDOF2+0]+=dux*weight*Jdet*gauss->weight*basis[i]; 
-						pe->values[i*NDOF2+1]+=duy*weight*Jdet*gauss->weight*basis[i]; 
-					}
-					break;
-				case SurfaceLogVelMisfitEnum:
-					/*
-					 *                 [        vel + eps     ] 2
-					 * J = 4 \bar{v}^2 | log ( -----------  ) |  
-					 *                 [       vel   + eps    ]
-					 *                            obs
-					 *
-					 *        dJ                 2 * log(...)
-					 * DU = - -- = - 4 \bar{v}^2 -------------  u
-					 *        du                 vel^2 + eps
-					 *            
-					 */
-					for(i=0;i<numnodes;i++){
-						velocity_mag    =sqrt(pow(vx,   2)+pow(vy,   2))+epsvel;
-						obs_velocity_mag=sqrt(pow(vxobs,2)+pow(vyobs,2))+epsvel;
-						scale=-8*pow(meanvel,2)/pow(velocity_mag,2)*log(velocity_mag/obs_velocity_mag);
-						dux=scale*vx;
-						duy=scale*vy;
-						pe->values[i*NDOF2+0]+=dux*weight*Jdet*gauss->weight*basis[i]; 
-						pe->values[i*NDOF2+1]+=duy*weight*Jdet*gauss->weight*basis[i]; 
-					}
-					break;
-				case SurfaceAverageVelMisfitEnum:
-					/*
-					 *      1                    2              2
-					 * J = ---  sqrt(  (u - u   )  +  (v - v   )  )
-					 *      S                obs            obs
-					 *
-					 *        dJ      1       1 
-					 * DU = - -- = - --- ----------- * 2 (u - u   )
-					 *        du      S  2 sqrt(...)           obs
-					 */
-					for(i=0;i<numnodes;i++){
-						scale=1./(S*2*sqrt(pow(vx-vxobs,2)+pow(vy-vyobs,2))+epsvel);
-						dux=scale*(vxobs-vx);
-						duy=scale*(vyobs-vy);
-						pe->values[i*NDOF2+0]+=dux*weight*Jdet*gauss->weight*basis[i]; 
-						pe->values[i*NDOF2+1]+=duy*weight*Jdet*gauss->weight*basis[i]; 
-					}
-					break;
-				case SurfaceLogVxVyMisfitEnum:
-					/*
-					 *      1            [        |u| + eps     2          |v| + eps     2  ]
-					 * J = --- \bar{v}^2 | log ( -----------  )   +  log ( -----------  )   |  
-					 *      2            [       |u    |+ eps              |v    |+ eps     ]
-					 *                              obs                       obs
-					 *        dJ                              1      u                             1
-					 * DU = - -- = - \bar{v}^2 log(u...) --------- ----  ~ - \bar{v}^2 log(u...) ------
-					 *        du                         |u| + eps  |u|                           u + eps
-					 */
-					for(i=0;i<numnodes;i++){
-						dux = - meanvel*meanvel * log((fabs(vx)+epsvel)/(fabs(vxobs)+epsvel)) / (vx+epsvel);
-						duy = - meanvel*meanvel * log((fabs(vy)+epsvel)/(fabs(vyobs)+epsvel)) / (vy+epsvel);
-						pe->values[i*NDOF2+0]+=dux*weight*Jdet*gauss->weight*basis[i]; 
-						pe->values[i*NDOF2+1]+=duy*weight*Jdet*gauss->weight*basis[i]; 
-					}
-					break;
-				case DragCoefficientAbsGradientEnum:
-					/*Nothing in P vector*/
-					break;
-				case ThicknessAbsGradientEnum:
-					/*Nothing in P vector*/
-					break;
-				case ThicknessAlongGradientEnum:
-					/*Nothing in P vector*/
-					break;
-				case ThicknessAcrossGradientEnum:
-					/*Nothing in P vector*/
-					break;
-				case RheologyBbarAbsGradientEnum:
-					/*Nothing in P vector*/
-					break;
-				default:
-					_error_("response " << EnumToStringx(responses[resp]) << " not supported yet");
-			}
-		}
-	}
-
-	/*Clean up and return*/
-	xDelete<IssmDouble>(basis);
-	xDelete<int>(responses);
-	delete gauss;
-	return pe;
 }
 /*}}}*/
@@ -6154,8 +4097,8 @@
 
 	/*If on water, return 0: */
-	if(NoIceInElement()) return 0;
+	if(!IsIceInElement()) return 0;
 
 	/*Retrieve all inputs we will be needing: */
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
 	Input* weights_input=inputs->GetInput(InversionCostFunctionsCoefficientsEnum);         _assert_(weights_input);
 	Input* drag_input   =inputs->GetInput(FrictionCoefficientEnum); _assert_(drag_input);
@@ -6183,141 +4126,4 @@
 }
 /*}}}*/
-/*FUNCTION Tria::CreateKMatrixAdjointBalancethickness {{{*/
-ElementMatrix* Tria::CreateKMatrixAdjointBalancethickness(void){
-
-	ElementMatrix* Ke=NULL;
-
-	/*Get Element Matrix of the forward model*/
-	switch(GetElementType()){
-		case P1Enum:
-			Ke=CreateKMatrixBalancethickness_CG();
-			break;
-		case P1DGEnum:
-			Ke=CreateKMatrixBalancethickness_DG();
-			break;
-		default:
-			_error_("Element type " << EnumToStringx(GetElementType()) << " not supported yet");
-	}
-
-	/*Transpose and return Ke*/
-	Ke->Transpose();
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Tria::CreateKMatrixAdjointSSA{{{*/
-ElementMatrix* Tria::CreateKMatrixAdjointSSA(void){
-
-	/*Intermediaries */
-	int         i,j;
-	bool        incomplete_adjoint;
-	IssmDouble  xyz_list[NUMVERTICES][3];
-	IssmDouble  Jdet,thickness;
-	IssmDouble  eps1dotdphii,eps1dotdphij;
-	IssmDouble  eps2dotdphii,eps2dotdphij;
-	IssmDouble  mu_prime;
-	IssmDouble  epsilon[3];/* epsilon=[exx,eyy,exy];*/
-	IssmDouble  eps1[2],eps2[2];
-	GaussTria  *gauss=NULL;
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Initialize Jacobian with regular SSA (first part of the Gateau derivative)*/
-	parameters->FindParam(&incomplete_adjoint,InversionIncompleteAdjointEnum);
-	ElementMatrix* Ke=CreateKMatrixStressbalanceSSA();
-	if(incomplete_adjoint) return Ke;
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	Input* vx_input=inputs->GetInput(VxEnum);       _assert_(vx_input);
-	Input* vy_input=inputs->GetInput(VyEnum);       _assert_(vy_input);
-	Input* thickness_input=inputs->GetInput(ThicknessEnum); _assert_(thickness_input);
-
-	/*Allocate dbasis*/
-	IssmDouble* dbasis = xNew<IssmDouble>(2*numnodes);
-
-	/* Start  looping on the number of gaussian points: */
-	gauss=new GaussTria(2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		GetNodalFunctionsDerivatives(dbasis,&xyz_list[0][0],gauss);
-
-		thickness_input->GetInputValue(&thickness, gauss);
-		this->GetStrainRate2d(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input);
-		material->GetViscosity2dDerivativeEpsSquare(&mu_prime,&epsilon[0]);
-		eps1[0]=2*epsilon[0]+epsilon[1];   eps2[0]=epsilon[2];
-		eps1[1]=epsilon[2];                eps2[1]=epsilon[0]+2*epsilon[1];
-
-		for(i=0;i<numnodes;i++){
-			for(j=0;j<numnodes;j++){
-				eps1dotdphii=eps1[0]*dbasis[0*numnodes+i]+eps1[1]*dbasis[1*numnodes+i];
-				eps1dotdphij=eps1[0]*dbasis[0*numnodes+j]+eps1[1]*dbasis[1*numnodes+j];
-				eps2dotdphii=eps2[0]*dbasis[0*numnodes+i]+eps2[1]*dbasis[1*numnodes+i];
-				eps2dotdphij=eps2[0]*dbasis[0*numnodes+j]+eps2[1]*dbasis[1*numnodes+j];
-
-				Ke->values[2*numnodes*(2*i+0)+2*j+0]+=gauss->weight*Jdet*2*mu_prime*thickness*eps1dotdphij*eps1dotdphii;
-				Ke->values[2*numnodes*(2*i+0)+2*j+1]+=gauss->weight*Jdet*2*mu_prime*thickness*eps2dotdphij*eps1dotdphii;
-				Ke->values[2*numnodes*(2*i+1)+2*j+0]+=gauss->weight*Jdet*2*mu_prime*thickness*eps1dotdphij*eps2dotdphii;
-				Ke->values[2*numnodes*(2*i+1)+2*j+1]+=gauss->weight*Jdet*2*mu_prime*thickness*eps2dotdphij*eps2dotdphii;
-			}
-		}
-	}
-
-	/*Transform Coordinate System*/
-	TransformStiffnessMatrixCoord(Ke,nodes,numnodes,XYEnum);
-
-	/*Clean up and return*/
-	delete gauss;
-	xDelete<IssmDouble>(dbasis);
-	//Ke->Transpose();
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Tria::InputUpdateFromSolutionAdjointHoriz {{{*/
-void  Tria::InputUpdateFromSolutionAdjointHoriz(IssmDouble* solution){
-
-	int  i;
-	int* doflist=NULL;
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodes();
-	int numdof   = numnodes*NDOF2;
-
-	/*Fetch dof list and allocate solution vectors*/
-	GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
-	IssmDouble* values  = xNew<IssmDouble>(numdof);
-	IssmDouble* lambdax = xNew<IssmDouble>(numnodes);
-	IssmDouble* lambday = xNew<IssmDouble>(numnodes);
-
-	/*Use the dof list to index into the solution vector: */
-	for(i=0;i<numdof;i++) values[i]=solution[doflist[i]];
-
-	/*Transform solution in Cartesian Space*/
-	TransformSolutionCoord(&values[0],nodes,numnodes,XYEnum);
-
-	/*Ok, we have vx and vy in values, fill in vx and vy arrays: */
-	for(i=0;i<numnodes;i++){
-		lambdax[i]=values[i*NDOF2+0];
-		lambday[i]=values[i*NDOF2+1];
-
-		/*Check solution*/
-		if(xIsNan<IssmDouble>(lambdax[i])) _error_("NaN found in solution vector");
-		if(xIsNan<IssmDouble>(lambday[i])) _error_("NaN found in solution vector");
-	}
-
-	/*Add vx and vy as inputs to the tria element: */
-	this->inputs->AddInput(new TriaInput(AdjointxEnum,lambdax,P1Enum));
-	this->inputs->AddInput(new TriaInput(AdjointyEnum,lambday,P1Enum));
-
-	/*Free ressources:*/
-	xDelete<IssmDouble>(values);
-	xDelete<IssmDouble>(lambdax);
-	xDelete<IssmDouble>(lambday);
-	xDelete<int>(doflist);
-}
-/*}}}*/
 /*FUNCTION Tria::GetVectorFromControlInputs{{{*/
 void  Tria::GetVectorFromControlInputs(Vector<IssmDouble>* vector,int control_enum,int control_index,const char* data){
@@ -6333,10 +4139,5 @@
 
 	/*Get input (either in element or material)*/
-	if(control_enum==MaterialsRheologyBbarEnum || control_enum==DamageDbarEnum){
-		input=(Input*)material->inputs->GetInput(control_enum); _assert_(input);
-	}
-	else{
-		input=(Input*)this->inputs->GetInput(control_enum);   _assert_(input);
-	}
+	input=(Input*)this->inputs->GetInput(control_enum);   _assert_(input);
 
 	/*Check that it is a ControlInput*/
@@ -6368,11 +4169,5 @@
 	new_input = new TriaInput(control_enum,values,P1Enum);
 
-	if(control_enum==MaterialsRheologyBbarEnum || control_enum==DamageDbarEnum){
-		input=(Input*)material->inputs->GetInput(control_enum); _assert_(input);
-	}
-	else{
-		input=(Input*)this->inputs->GetInput(control_enum);   _assert_(input);
-	}
-
+	input=(Input*)this->inputs->GetInput(control_enum);   _assert_(input);
 	if (input->ObjectEnum()!=ControlInputEnum){
 		_error_("input " << EnumToStringx(control_enum) << " is not a ControlInput");
@@ -6382,78 +4177,4 @@
 }
 /*}}}*/
-#endif
-
-#ifdef _HAVE_THERMAL_
-/*FUNCTION Tria::CreateKMatrixMelting {{{*/
-ElementMatrix* Tria::CreateKMatrixMelting(void){
-
-	/*Intermediaries */
-	IssmDouble heatcapacity,latentheat;
-	IssmDouble Jdet,D_scalar;
-	IssmDouble xyz_list[NUMVERTICES][3];
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Initialize Element vector and vectors*/
-	ElementMatrix* Ke=new ElementMatrix(nodes,numnodes,this->parameters,NoneApproximationEnum);
-	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	latentheat   = matpar->GetLatentHeat();
-	heatcapacity = matpar->GetHeatCapacity();
-
-	/* Start looping on the number of gauss  (nodes on the bedrock) */
-	GaussTria* gauss=new GaussTria(2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetNodalFunctions(&basis[0],gauss);
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0], gauss);
-
-		D_scalar=latentheat/heatcapacity*gauss->weight*Jdet;
-
-		TripleMultiply(basis,numnodes,1,0,
-					&D_scalar,1,1,0,
-					basis,1,numnodes,0,
-					&Ke->values[0],1);
-	}
-
-	/*Clean up and return*/
-	xDelete<IssmDouble>(basis);
-	delete gauss;
-	return Ke;
-}
-/*}}}*/
-#endif
-
-#ifdef _HAVE_HYDROLOGY_
-/*FUNCTION Tria::AllActive{{{*/
-bool Tria::AllActive(void){
-
-	/*Intermediaries*/
-	const int  numnodes = NUMVERTICES;
-
-	for(int i=0;i<numnodes;i++){
-		if(!this->nodes[i]->IsActive()) return false;
-	}
-
-	return true;
-}
-/*}}}*/
-/*FUNCTION Tria::AnyActive{{{*/
-bool Tria::AnyActive(void){
-
-	/*Intermediaries*/
-	const int  numnodes = NUMVERTICES;
-
-	for(int i=0;i<numnodes;i++){
-		if(this->nodes[i]->IsActive()) return true;
-	}
-
-	return false;
-}/*}}}*/
 /*FUNCTION Tria::CreateHydrologyWaterVelocityInput {{{*/
 void Tria::CreateHydrologyWaterVelocityInput(void){
@@ -6510,415 +4231,4 @@
 }
 /*}}}*/
-/*FUNCTION Tria::CreateKMatrixHydrologyShreve{{{*/
-ElementMatrix* Tria::CreateKMatrixHydrologyShreve(void){
-
-	/*Intermediaries */
-	IssmDouble diffusivity;
-	IssmDouble Jdet,D_scalar,dt,h;
-	IssmDouble vx,vy,vel,dvxdx,dvydy;
-	IssmDouble dvx[2],dvy[2];
-	IssmDouble xyz_list[NUMVERTICES][3];
-
-	/*Skip if water or ice shelf element*/
-	if(NoIceInElement() || IsFloating()) return NULL;
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Initialize Element matrix and vectors*/
-	ElementMatrix* Ke     = new ElementMatrix(nodes,numnodes,this->parameters,NoneApproximationEnum);
-	IssmDouble*    basis  = xNew<IssmDouble>(numnodes);
-	IssmDouble*    B      = xNew<IssmDouble>(2*numnodes);
-	IssmDouble*    Bprime = xNew<IssmDouble>(2*numnodes);
-	IssmDouble     D[2][2];
-
-	/*Create water velocity vx and vy from current inputs*/
-	CreateHydrologyWaterVelocityInput();
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);
-	this->parameters->FindParam(&diffusivity,HydrologyshreveStabilizationEnum);
-	Input* vx_input=inputs->GetInput(HydrologyWaterVxEnum); _assert_(vx_input);
-	Input* vy_input=inputs->GetInput(HydrologyWaterVyEnum); _assert_(vy_input);
-	h=sqrt(2*this->GetArea());
-
-	/* Start  looping on the number of gaussian points: */
-	GaussTria* gauss=new GaussTria(2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		GetNodalFunctions(basis,gauss);
-
-		vx_input->GetInputValue(&vx,gauss);
-		vy_input->GetInputValue(&vy,gauss);
-		vx_input->GetInputDerivativeValue(&dvx[0],&xyz_list[0][0],gauss);
-		vy_input->GetInputDerivativeValue(&dvy[0],&xyz_list[0][0],gauss);
-
-		D_scalar=gauss->weight*Jdet;
-
-		TripleMultiply(basis,1,numnodes,1,
-					&D_scalar,1,1,0,
-					basis,1,numnodes,0,
-					Ke->values,1);
-
-		GetBMasstransport(B,&xyz_list[0][0], gauss);
-		GetBprimeMasstransport(Bprime,&xyz_list[0][0], gauss);
-
-		dvxdx=dvx[0];
-		dvydy=dvy[1];
-		D_scalar=dt*gauss->weight*Jdet;
-
-		D[0][0]=D_scalar*dvxdx;
-		D[0][1]=0.;
-		D[1][0]=0.;
-		D[1][1]=D_scalar*dvydy;
-		TripleMultiply(B,2,numnodes,1,
-					&D[0][0],2,2,0,
-					B,2,numnodes,0,
-					&Ke->values[0],1);
-
-		D[0][0]=D_scalar*vx;
-		D[1][1]=D_scalar*vy;
-		TripleMultiply(B,2,numnodes,1,
-					&D[0][0],2,2,0,
-					Bprime,2,numnodes,0,
-					&Ke->values[0],1);
-
-		/*Artificial diffusivity*/
-		vel=sqrt(vx*vx+vy*vy);
-		D[0][0]=D_scalar*diffusivity*h/(2*vel)*vx*vx;
-		D[1][0]=D_scalar*diffusivity*h/(2*vel)*vy*vx;
-		D[0][1]=D_scalar*diffusivity*h/(2*vel)*vx*vy;
-		D[1][1]=D_scalar*diffusivity*h/(2*vel)*vy*vy;
-		TripleMultiply(Bprime,2,numnodes,1,
-					&D[0][0],2,2,0,
-					Bprime,2,numnodes,0,
-					&Ke->values[0],1);
-	}
-
-	/*Clean up and return*/
-	xDelete<IssmDouble>(basis);
-	xDelete<IssmDouble>(B);
-	xDelete<IssmDouble>(Bprime);
-	delete gauss;
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Tria::CreateKMatrixHydrologyDCInefficient{{{*/
-ElementMatrix* Tria::CreateKMatrixHydrologyDCInefficient(void){
-
-	/* Intermediaries */
-	IssmDouble  D_scalar,Jdet;
-	IssmDouble 	sediment_transmitivity,dt;
-	IssmDouble  sediment_storing;
-	IssmDouble  xyz_list[NUMVERTICES][3];
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Initialize Element matrix and vectors*/
-	ElementMatrix* Ke     = new ElementMatrix(nodes,numnodes,this->parameters);
-	IssmDouble*    B      = xNew<IssmDouble>(5*numnodes);
-	IssmDouble*    basis  = xNew<IssmDouble>(numnodes);
-	IssmDouble     D[2][2];
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);
-	sediment_storing       = matpar->GetSedimentStoring();
-	sediment_transmitivity = matpar->GetSedimentTransmitivity();
-
-	/* Start looping on the number of gaussian points: */
-	GaussTria* gauss=new GaussTria(2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-
-		/*Diffusivity*/
-		D_scalar=sediment_transmitivity*gauss->weight*Jdet;
-		if(reCast<bool,IssmDouble>(dt)) D_scalar=D_scalar*dt;
-		D[0][0]=D_scalar; D[0][1]=0.;
-		D[1][0]=0.;       D[1][1]=D_scalar;
-		GetBHydro(B,&xyz_list[0][0],gauss); 
-		TripleMultiply(B,2,numnodes,1,
-					&D[0][0],2,2,0,
-					B,2,numnodes,0,
-					&Ke->values[0],1);
-
-		/*Transient*/
-		if(reCast<bool,IssmDouble>(dt)){
-			GetNodalFunctions(&basis[0],gauss);
-			D_scalar=sediment_storing*gauss->weight*Jdet;
-
-			TripleMultiply(basis,numnodes,1,0,
-						&D_scalar,1,1,0,
-						basis,1,numnodes,0,
-						&Ke->values[0],1);
-		}
-	}
-	/*Clean up and return*/
-	xDelete<IssmDouble>(basis);
-	xDelete<IssmDouble>(B);
-	delete gauss;
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Tria::CreateKMatrixHydrologyDCEfficient{{{*/
-ElementMatrix* Tria::CreateKMatrixHydrologyDCEfficient(void){
-
-	/* Intermediaries */
-	IssmDouble  D_scalar,Jdet;
-	IssmDouble 	epl_transmitivity,dt;
-	IssmDouble  epl_storing;
-	IssmDouble  xyz_list[NUMVERTICES][3];
-
-	/*Check that all nodes are active, else return empty matrix*/
-	if(!this->AllActive()){
-		return NULL;
-	}
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Initialize Element matrix and vectors*/
-	ElementMatrix* Ke     = new ElementMatrix(nodes,numnodes,this->parameters);
-	IssmDouble*    B      = xNew<IssmDouble>(5*numnodes);
-	IssmDouble*    basis  = xNew<IssmDouble>(numnodes);
-	IssmDouble     D[2][2];
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);
-	epl_storing       = matpar->GetEplStoring();
-	epl_transmitivity = matpar->GetEplTransmitivity();
-
-	/* Start looping on the number of gaussian points: */
-	GaussTria* gauss=new GaussTria(2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-
-		/*Diffusivity*/
-		D_scalar=epl_transmitivity*gauss->weight*Jdet;
-		if(reCast<bool,IssmDouble>(dt)) D_scalar=D_scalar*dt;
-		D[0][0]=D_scalar; D[0][1]=0.;
-		D[1][0]=0.;       D[1][1]=D_scalar;
-		GetBHydro(B,&xyz_list[0][0],gauss); 
-		TripleMultiply(B,2,numnodes,1,
-					&D[0][0],2,2,0,
-					B,2,numnodes,0,
-					&Ke->values[0],1);
-
-		/*Transient*/
-		if(reCast<bool,IssmDouble>(dt)){
-			GetNodalFunctions(basis,gauss);
-			D_scalar=epl_storing*gauss->weight*Jdet;
-
-			TripleMultiply(basis,numnodes,1,0,
-						&D_scalar,1,1,0,
-						basis,1,numnodes,0,
-						&Ke->values[0],1);
-		}
-	}
-
-	/*Clean up and return*/
-	xDelete<IssmDouble>(basis);
-	xDelete<IssmDouble>(B);
-	delete gauss;
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Tria::CreatePVectorHydrologyShreve {{{*/
-ElementVector* Tria::CreatePVectorHydrologyShreve(void){
-
-	/*Intermediaries */
-	int        i;
-	IssmDouble Jdet,dt;
-	IssmDouble basal_melting_g;
-	IssmDouble old_watercolumn_g;
-	IssmDouble xyz_list[NUMVERTICES][3];
-
-	/*Skip if water or ice shelf element*/
-	if(NoIceInElement() || IsFloating()) return NULL;
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Initialize Element vector*/
-	ElementVector* pe=new ElementVector(nodes,numnodes,this->parameters);
-	IssmDouble*    basis = xNewZeroInit<IssmDouble>(numnodes);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);
-	Input* basal_melting_input=inputs->GetInput(BasalforcingsMeltingRateEnum); _assert_(basal_melting_input);
-	Input* old_watercolumn_input=inputs->GetInput(WaterColumnOldEnum);         _assert_(old_watercolumn_input);
-
-	/*Initialize basal_melting_correction_g to 0, do not forget!:*/
-	/* Start  looping on the number of gaussian points: */
-	GaussTria* gauss=new GaussTria(2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		GetNodalFunctions(basis, gauss);
-
-		basal_melting_input->GetInputValue(&basal_melting_g,gauss);
-		old_watercolumn_input->GetInputValue(&old_watercolumn_g,gauss);
-
-		if(reCast<int,IssmDouble>(dt)){
-			for(i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*(old_watercolumn_g+dt*basal_melting_g)*basis[i];
-		}
-		else{
-			for(i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*basal_melting_g*basis[i];
-		}
-	}
-
-	/*Clean up and return*/
-	xDelete<IssmDouble>(basis);
-	delete gauss;
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Tria::CreatePVectorHydrologyDCInefficient {{{*/
-ElementVector* Tria::CreatePVectorHydrologyDCInefficient(void){
-
-	/*Intermediaries */
-	IssmDouble Jdet;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble dt,scalar,water_head;
-	IssmDouble water_load,transfer;
-	IssmDouble sediment_storing;
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Initialize Element vector and other vectors*/
-	ElementVector* pe    = new ElementVector(nodes,numnodes,this->parameters);
-	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
-
-	/*Retrieve all inputs and parameters*/
-	sediment_storing = matpar->GetSedimentStoring();
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);
-	Input* water_input=inputs->GetInput(BasalforcingsMeltingRateEnum);  _assert_(water_input);
-	Input* transfer_input=inputs->GetInput(WaterTransferEnum);  _assert_(transfer_input);
-	Input* old_wh_input=NULL; 
-
-	if(reCast<bool,IssmDouble>(dt)){
-		old_wh_input=inputs->GetInput(SedimentHeadOldEnum); _assert_(old_wh_input);
-	}
-
-	/* Start  looping on the number of gaussian points: */
-	GaussTria* gauss=new GaussTria(2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		GetNodalFunctions(basis, gauss);
-
-		/*Loading term*/
-		water_input->GetInputValue(&water_load,gauss);
-		transfer_input->GetInputValue(&transfer,gauss);
-		scalar = Jdet*gauss->weight*(water_load+transfer);
-		if(reCast<bool,IssmDouble>(dt)) scalar = scalar*dt;
-		for(int i=0;i<numnodes;i++) pe->values[i]+=scalar*basis[i];
-
-		/*Transient term*/
-		if(reCast<bool,IssmDouble>(dt)){
-			old_wh_input->GetInputValue(&water_head,gauss);
-			scalar = Jdet*gauss->weight*water_head*sediment_storing;
-			for(int i=0;i<numnodes;i++) pe->values[i]+=scalar*basis[i];
-		}
-	}
-
-	/*Clean up and return*/
-	xDelete<IssmDouble>(basis);
-	delete gauss;
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Tria::CreatePVectorHydrologyDCEfficient {{{*/
-ElementVector* Tria::CreatePVectorHydrologyDCEfficient(void){
-
-	/*Intermediaries */
-	IssmDouble connectivity;
-	IssmDouble Jdet;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble dt,scalar,water_head;
-	IssmDouble transfer,residual;
-	IssmDouble epl_storing;
-	GaussTria* gauss = NULL;
-
-	/*Check that all nodes are active, else return empty matrix*/
-	if(!this->AllActive()){
-		return NULL;
-	}
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Initialize Element vector and other vectors*/
-	ElementVector* pe    = new ElementVector(nodes,numnodes,this->parameters);
-	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
-
-	/*Retrieve all inputs and parameters*/
-	epl_storing = matpar->GetEplStoring();
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);
-	Input* residual_input=inputs->GetInput(SedimentHeadResidualEnum);  _assert_(residual_input);
-	Input* transfer_input=inputs->GetInput(WaterTransferEnum);  _assert_(transfer_input);
-	Input* old_wh_input=NULL; 
-
-	if(reCast<bool,IssmDouble>(dt)){
-		old_wh_input=inputs->GetInput(EplHeadOldEnum); _assert_(old_wh_input);
-	}
-
-	/* Start  looping on the number of gaussian points: */
-	gauss=new GaussTria(2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		GetNodalFunctions(basis,gauss);
-
-		/*Loading term*/
-		transfer_input->GetInputValue(&transfer,gauss);
-		scalar = Jdet*gauss->weight*(-transfer);
-		if(reCast<bool,IssmDouble>(dt)) scalar = scalar*dt;
-		for(int i=0;i<numnodes;i++) pe->values[i]+=scalar*basis[i];
-
-		/*Transient term*/
-		if(reCast<bool,IssmDouble>(dt)){
-			old_wh_input->GetInputValue(&water_head,gauss);
-			scalar = Jdet*gauss->weight*water_head*epl_storing;
-			for(int i=0;i<numnodes;i++) pe->values[i]+=scalar*basis[i];
-		}
-	}
-	delete gauss;
-
-	/*	Add residual if necessary*/
-	gauss=new GaussTria();
-	for(int iv=0;iv<NUMVERTICES;iv++){
-		gauss->GaussVertex(iv);
-
-		connectivity = IssmDouble(vertices[iv]->Connectivity());
-		residual_input->GetInputValue(&residual,gauss);
-		pe->values[iv]+=residual/connectivity;
-	}
-
-	/*Clean up and return*/
-	xDelete<IssmDouble>(basis);
-	delete gauss;
-	return pe;
-}
-/*}}}*/
 /*FUNCTION Tria::GetSolutionFromInputsOneDof{{{*/
 void  Tria::GetSolutionFromInputsOneDof(Vector<IssmDouble>* solution, int enum_type){
@@ -6954,1389 +4264,4 @@
 }
 /*}}}*/
-/*FUNCTION Tria::InputUpdateFromSolutionHydrologyShreve{{{*/
-void  Tria::InputUpdateFromSolutionHydrologyShreve(IssmDouble* solution){
-
-	/*Intermediary*/
-	int* doflist = NULL;
-
-	/*Fetch number of nodes for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Fetch dof list and allocate solution vector*/
-	GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
-	IssmDouble* values    = xNew<IssmDouble>(numnodes);
-
-	/*Use the dof list to index into the solution vector: */
-	for(int i=0;i<numnodes;i++){
-		values[i]=solution[doflist[i]];
-		if(xIsNan<IssmDouble>(values[i])) _error_("NaN found in solution vector");
-		if (values[i]<10e-10) values[i]=10e-10; //correcting the water column to positive values
-	}
-
-	/*Add input to the element: */
-	this->inputs->AddInput(new TriaInput(WatercolumnEnum,values,P1Enum));
-
-	/*Free ressources:*/
-	xDelete<IssmDouble>(values);
-	xDelete<int>(doflist);
-}
-/*}}}*/
-/*FUNCTION Tria::InputUpdateFromSolutionHydrologyDCInefficient{{{*/
-void  Tria::InputUpdateFromSolutionHydrologyDCInefficient(IssmDouble* solution){
-
-	/*Intermediaries*/
-	int        *doflist  = NULL;
-	bool        converged;
-	IssmDouble  penalty_factor, dt;
-	IssmDouble  kmax, kappa, h_max;
-
-	/*Fetch number of nodes for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Fetch dof list and allocate solution vector*/
-	GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
-	IssmDouble* values   = xNew<IssmDouble>(numnodes);
-	IssmDouble* residual = xNew<IssmDouble>(numnodes);
-
-	/*Use the dof list to index into the solution vector: */
-	for(int i=0;i<numnodes;i++){
-		values[i]=solution[doflist[i]];
-		if(xIsNan<IssmDouble>(values[i])) _error_("NaN found in solution vector");
-	}
-
-	/*If converged keep the residual in mind*/
-	this->inputs->GetInputValue(&converged,ConvergedEnum);
-
-	/*Get inputs*/
-	if(converged){
-		this->parameters->FindParam(&kmax,HydrologySedimentKmaxEnum);
-		this->parameters->FindParam(&penalty_factor,HydrologydcPenaltyFactorEnum);
-
-		kappa=kmax*pow(10.,penalty_factor);
-
-		for(int i=0;i<numnodes;i++){
-			this->GetHydrologyDCInefficientHmax(&h_max,nodes[i]);
-			if(values[i]>h_max){
-				residual[i]=kappa*(values[i]-h_max);
-			}
-			else{
-				residual[i]=0.0;
-			}
-		}
-		this->inputs->AddInput(new TriaInput(SedimentHeadResidualEnum,residual,P1Enum));
-	}
-
-	/*Add input to the element: */
-	this->inputs->AddInput(new TriaInput(SedimentHeadEnum,values,P1Enum));
-
-	/*Free ressources:*/
-	xDelete<IssmDouble>(values);
-	xDelete<IssmDouble>(residual);
-	xDelete<int>(doflist);
-}
-/*}}}*/
-/*FUNCTION Tria::GetHydrologyDCInefficientHmax{{{*/
-void  Tria::GetHydrologyDCInefficientHmax(IssmDouble* ph_max, Node* innode){
-
-		int        hmax_flag;
-		IssmDouble h_max;
-		IssmDouble rho_ice,rho_water;
-		IssmDouble thickness,bed;
-		/*Get the flag to the limitation method*/
-		this->parameters->FindParam(&hmax_flag,HydrologydcSedimentlimitFlagEnum);
-
-		/*Switch between the different cases*/
-		switch(hmax_flag){
-			case 0:
-				h_max=1.0e+10;
-				break;
-			case 1:
-				parameters->FindParam(&h_max,HydrologydcSedimentlimitEnum);
-				break;
-			case 2:
-				rho_ice=matpar->GetRhoIce();
-				rho_water=matpar->GetRhoFreshwater();
-				this->GetInputValue(&thickness,innode,ThicknessEnum);
-				this->GetInputValue(&bed,innode,BedEnum);
-				h_max=((rho_ice*thickness)/rho_water)+bed;
-				break;
-			case 3:
-				_error_("Using normal stress  not supported yet");
-				break;
-			default:
-				_error_("no case higher than 3 for SedimentlimitFlag");
-		}
-		/*Assign output pointer*/
-		*ph_max=h_max;
-}
-/*}}}*/
-/*FUNCTION Tria::GetHydrologyTransfer{{{*/
-void  Tria::GetHydrologyTransfer(Vector<IssmDouble>* transfer){
-
-	const int  numdof   = NDOF1 *NUMVERTICES;
-	int        *doflist = NULL;
-	bool       isefficientlayer;
-	int        transfermethod;
-	IssmDouble sed_trans,sed_thick;
-	IssmDouble leakage,h_max;
-	IssmDouble wh_trans;
-	IssmDouble activeEpl[numdof];
-	IssmDouble eplstoring[numdof],sedstoring[numdof];
-	IssmDouble epl_head[numdof],sed_head[numdof];
-
-	GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
-
-	/*Get the flag to know if the efficient layer is present*/
-	this->parameters->FindParam(&isefficientlayer,HydrologydcIsefficientlayerEnum);
-
-	if(isefficientlayer){
-		/*Also get the flag to the transfer method*/
-		this->parameters->FindParam(&transfermethod,HydrologydcTransferFlagEnum);
-
-		/*Switch between the different transfer methods cases*/
-		switch(transfermethod){
-		case 0:
-			/*Just keepping the transfer to zero, should be OK with the initial value of transfer*/
-			break;
-		case 1:
-
-			GetInputListOnVertices(&activeEpl[0],HydrologydcMaskEplactiveEnum);
-			GetInputListOnVertices(&sed_head[0],SedimentHeadEnum); 
-			GetInputListOnVertices(&epl_head[0],EplHeadEnum);
-
-			this->parameters->FindParam(&leakage,HydrologydcLeakageFactorEnum);
-
-			sed_trans = matpar->GetSedimentTransmitivity();
-			sed_thick = matpar->GetSedimentThickness();
-
-			for(int i=0;i<numdof;i++){
-				/*No transfer if the EPL is not active*/
-				if(activeEpl[i]==0.0){
-					wh_trans=0.0;
-				}
-				else{
-					eplstoring[i]=matpar->GetEplStoring();		
-					sedstoring[i]=matpar->GetSedimentStoring();
-
-					/*EPL head higher than sediment head, transfer from the epl to the sediment*/
-					if(epl_head[i]>sed_head[i]){
-						wh_trans=eplstoring[i]*sed_trans*(epl_head[i]-sed_head[i])/(leakage*sed_thick);				
-
-						/*No transfer if the sediment head is allready at the maximum*/
-						this->GetHydrologyDCInefficientHmax(&h_max,nodes[i]);
-						if(sed_head[i]>=h_max)wh_trans=0.0;
-					}
-					/*EPL head lower than sediment head, transfer from the sediment to the epl*/
-					else if(epl_head[i]<=sed_head[i]){
-						wh_trans=sedstoring[i]*sed_trans*(epl_head[i]-sed_head[i])/(leakage*sed_thick);				
-					}
-				}
-				/*Assign output pointer*/
-				transfer->SetValue(doflist[i],wh_trans,INS_VAL);
-			}
-			break;
-		default:
-			_error_("no case higher than 1 for the Transfer method");
-		}
-	}
-	/*Free ressources:*/
-	xDelete<int>(doflist);
-}
-/*}}}*/
-/*FUNCTION Tria::HydrologyEPLGetActive {{{*/
-void Tria::HydrologyEPLGetActive(Vector<IssmDouble>* active_vec){
-
-	/*Constants*/
-	const int  numnodes = NUMVERTICES;
-	IssmDouble flag     = 0.;
-	IssmDouble active[numnodes];
-
-	GetInputListOnVertices(&active[0],HydrologydcMaskEplactiveEnum);
-
-	for(int i=0;i<numnodes;i++) flag+=active[i];
-
-	if(flag>0.){
-		for(int i=0;i<numnodes;i++){
-			active_vec->SetValue(nodes[i]->Sid(),1.,INS_VAL);
-		}
-	}
-	else{
-		/*Do not do anything: at least one node is active for this element but this element is not solved for*/
-	}
-
-}
-/*}}}*/
-/*FUNCTION Tria::HydrologyEPLGetMask{{{*/
-void  Tria::HydrologyEPLGetMask(Vector<IssmDouble>* vec_mask){
-
-	/*Intermediaries*/
-	int         i,j;
-	const int   numdof         = NDOF1 *NUMVERTICES;
-	IssmDouble  h_max;
-	IssmDouble  sedheadmin;
-	IssmDouble  old_active[numdof];
-	IssmDouble  sedhead[numdof];
-	IssmDouble  eplhead[numdof];
-	IssmDouble  residual[numdof];
-
-	GetInputListOnVertices(&old_active[0],HydrologydcMaskEplactiveEnum);	
-	GetInputListOnVertices(&sedhead[0],SedimentHeadEnum);
-	GetInputListOnVertices(&eplhead[0],EplHeadEnum);
-	GetInputListOnVertices(&residual[0],SedimentHeadResidualEnum);
-
-	/*Get minimum sediment head*/
-	sedheadmin=sedhead[0];
-	for(i=1;i<numdof;i++) if(sedhead[i]<=sedheadmin)sedheadmin=sedhead[i];
-
-	for(i=0;i<numdof;i++){
-		/*Activate EPL if residual is >0 */
-		if(residual[i]>0.){
-			vec_mask->SetValue(nodes[i]->Sid(),1.,INS_VAL);
-		}
-
-		/*If mask was alread one, keep one*/
-		else if(old_active[i]>0.){
-			vec_mask->SetValue(nodes[i]->Sid(),1.,INS_VAL);
-		}
-
-		/*Increase of the efficient system is needed if the epl head reach the maximum value (sediment max value for now)*/
-		this->GetHydrologyDCInefficientHmax(&h_max,nodes[i]);
-		if(eplhead[i]>=h_max && this->AnyActive()){
-			for(j=0;j<numdof;j++){
-				if(old_active[j]>0.){
-					vec_mask->SetValue(nodes[i]->Sid(),1.,INS_VAL);
-				}
-				/*Increase of the domain is on the downstream node in term of sediment head*/
-				if(sedhead[j] == sedheadmin){
-					vec_mask->SetValue(nodes[j]->Sid(),1.,INS_VAL);
-					//	break;
-				}
-			}
-		}
-	}
-}
-/*}}}*/
-#endif
-
-#ifdef _HAVE_MASSTRANSPORT_
-/*FUNCTION Tria::CreateKMatrixExtrusion {{{*/
-ElementMatrix* Tria::CreateKMatrixExtrusion(void){
-
-	/*compute all stiffness matrices for this element*/
-	ElementMatrix* Ke1=CreateKMatrixExtrusionVolume();
-	ElementMatrix* Ke2=CreateKMatrixExtrusionSurface();
-	ElementMatrix* Ke3=CreateKMatrixExtrusionBed();
-	ElementMatrix* Ke =new ElementMatrix(Ke1,Ke2,Ke3);
-
-	/*clean-up and return*/
-	delete Ke1;
-	delete Ke2;
-	delete Ke3;
-	return Ke;
-
-}
-/*}}}*/
-/*FUNCTION Tria::CreateKMatrixExtrusionVolume {{{*/
-ElementMatrix* Tria::CreateKMatrixExtrusionVolume(void){
-
-	/*Intermediaries */
-	IssmDouble  Jdet;
-	IssmDouble  xyz_list[NUMVERTICES][3];
-	IssmDouble  B[NDOF1][NUMVERTICES];
-	IssmDouble  Bprime[NDOF1][NUMVERTICES];
-	IssmDouble  DL_scalar;
-	GaussTria  *gauss=NULL;
-
-	/*Initialize Element matrix*/
-	ElementMatrix* Ke=new ElementMatrix(nodes,NUMVERTICES,this->parameters,NoneApproximationEnum);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-
-	/* Start  looping on the number of gaussian points: */
-	gauss=new GaussTria(2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		GetBExtrusion(&B[0][0], &xyz_list[0][0], gauss);
-		GetNodalFunctions(&Bprime[0][0],gauss);
-
-		DL_scalar=gauss->weight*Jdet;
-
-		TripleMultiply(&B[0][0],1,NUMVERTICES,1,
-					&DL_scalar,1,1,0,
-					&Bprime[0][0],1,NUMVERTICES,0,
-					&Ke->values[0],1);
-	} 
-
-	/*Clean up and return*/
-	delete gauss;
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Tria::CreateKMatrixExtrusionSurface {{{*/
-ElementMatrix* Tria::CreateKMatrixExtrusionSurface(void){
-
-	if (!HasEdgeOnSurface()) return NULL;
-
-	/*Constants*/
-	const int numdof=NDOF1*NUMVERTICES;
-
-	/*Intermediaries */
-	int indices[2];
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble xyz_list_seg[NUMVERTICES1D][3];
-	IssmDouble normal[3];
-	IssmDouble Jdet,DL_scalar;
-	IssmDouble basis[NUMVERTICES];
-	GaussTria *gauss=NULL;
-
-	/*Initialize Element matrix*/
-	ElementMatrix* Ke=new ElementMatrix(nodes,NUMVERTICES,this->parameters,NoneApproximationEnum);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-
-	/*Get vertex indices that lie on bed*/
-	this->EdgeOnSurfaceIndices(&indices[0],&indices[1]);
-	for(int i=0;i<NUMVERTICES1D;i++) for(int j=0;j<2;j++) xyz_list_seg[i][j]=xyz_list[indices[i]][j];
-	GetSegmentNormal(&normal[0],xyz_list_seg);
-
-	/* Start  looping on the number of gaussian points: */
-	gauss=new GaussTria(indices[0],indices[1],2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetSegmentJacobianDeterminant(&Jdet,&xyz_list_seg[0][0],gauss);
-		GetNodalFunctions(&basis[0], gauss);
-
-		DL_scalar= - gauss->weight*Jdet*normal[1]; 
-
-		TripleMultiply( basis,1,numdof,1,
-					&DL_scalar,1,1,0,
-					basis,1,numdof,0,
-					&Ke->values[0],1);
-	}
-
-	/*Clean up and return*/
-	delete gauss;
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Tria::CreateKMatrixExtrusionBed {{{*/
-ElementMatrix* Tria::CreateKMatrixExtrusionBed(void){
-
-	if (!HasEdgeOnBed()) return NULL;
-
-	/*Constants*/
-	const int numdof=NDOF1*NUMVERTICES;
-
-	/*Intermediaries */
-	int indices[2];
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble xyz_list_seg[NUMVERTICES1D][3];
-	IssmDouble normal[3];
-	IssmDouble Jdet,DL_scalar;
-	IssmDouble basis[NUMVERTICES];
-	GaussTria *gauss=NULL;
-
-	/*Initialize Element matrix*/
-	ElementMatrix* Ke=new ElementMatrix(nodes,NUMVERTICES,this->parameters,NoneApproximationEnum);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-
-	/*Get vertex indices that lie on bed*/
-	this->EdgeOnBedIndices(&indices[0],&indices[1]);
-	for(int i=0;i<NUMVERTICES1D;i++) for(int j=0;j<2;j++) xyz_list_seg[i][j]=xyz_list[indices[i]][j];
-	GetSegmentNormal(&normal[0],xyz_list_seg);
-
-	/* Start  looping on the number of gaussian points: */
-	gauss=new GaussTria(indices[0],indices[1],2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetSegmentJacobianDeterminant(&Jdet,&xyz_list_seg[0][0],gauss);
-		GetNodalFunctions(&basis[0], gauss);
-
-		DL_scalar= - gauss->weight*Jdet*normal[1]; 
-
-		TripleMultiply( basis,1,numdof,1,
-					&DL_scalar,1,1,0,
-					basis,1,numdof,0,
-					&Ke->values[0],1);
-	}
-
-	/*Clean up and return*/
-	delete gauss;
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Tria::CreateKMatrixMasstransport {{{*/
-ElementMatrix* Tria::CreateKMatrixMasstransport(void){
-
-	switch(GetElementType()){
-		case P1Enum: case P2Enum:
-			return CreateKMatrixMasstransport_CG();
-		case P1DGEnum:
-			return CreateKMatrixMasstransport_DG();
-		default:
-			_error_("Element type " << EnumToStringx(GetElementType()) << " not supported yet");
-	}
-}
-/*}}}*/
-/*FUNCTION Tria::CreateKMatrixMasstransport_CG {{{*/
-ElementMatrix* Tria::CreateKMatrixMasstransport_CG(void){
-
-	/*Intermediaries */
-	int        stabilization;
-	int        meshtype;
-	IssmDouble Jdet,D_scalar,dt,h;
-	IssmDouble vel,vx,vy,dvxdx,dvydy;
-	IssmDouble dvx[2],dvy[2];
-	IssmDouble xyz_list[NUMVERTICES][3];
-
-	/*Fetch number of nodes for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Initialize Element matrix and vectors*/
-	ElementMatrix* Ke     = new ElementMatrix(nodes,numnodes,this->parameters,NoneApproximationEnum);
-	IssmDouble*    basis  = xNew<IssmDouble>(numnodes);
-	IssmDouble*    B      = xNew<IssmDouble>(2*numnodes);
-	IssmDouble*    Bprime = xNew<IssmDouble>(2*numnodes);
-	IssmDouble     D[2][2];
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);
-	this->parameters->FindParam(&meshtype,MeshTypeEnum);
-	this->parameters->FindParam(&stabilization,MasstransportStabilizationEnum);
-	Input* vxaverage_input=NULL;
-	Input* vyaverage_input=NULL;
-	if(meshtype==Mesh2DhorizontalEnum){
-		vxaverage_input=inputs->GetInput(VxEnum); _assert_(vxaverage_input);
-		vyaverage_input=inputs->GetInput(VyEnum); _assert_(vyaverage_input);
-	}
-	else{
-		vxaverage_input=inputs->GetInput(VxAverageEnum); _assert_(vxaverage_input);
-		vyaverage_input=inputs->GetInput(VyAverageEnum); _assert_(vyaverage_input);
-	}
-	h=sqrt(2*this->GetArea());
-
-	/* Start  looping on the number of gaussian points: */
-	GaussTria *gauss=new GaussTria(2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		GetNodalFunctions(basis,gauss);
-
-		vxaverage_input->GetInputValue(&vx,gauss);
-		vyaverage_input->GetInputValue(&vy,gauss);
-		vxaverage_input->GetInputDerivativeValue(&dvx[0],&xyz_list[0][0],gauss);
-		vyaverage_input->GetInputDerivativeValue(&dvy[0],&xyz_list[0][0],gauss);
-
-		D_scalar=gauss->weight*Jdet;
-
-		TripleMultiply(basis,1,numnodes,1,
-					&D_scalar,1,1,0,
-					basis,1,numnodes,0,
-					&Ke->values[0],1);
-
-		GetBMasstransport(B,&xyz_list[0][0],gauss);
-		GetBprimeMasstransport(Bprime,&xyz_list[0][0],gauss);
-
-		dvxdx=dvx[0];
-		dvydy=dvy[1];
-		D_scalar=dt*gauss->weight*Jdet;
-
-		D[0][0]=D_scalar*dvxdx;
-		D[0][1]=0.;
-		D[1][0]=0.;
-		D[1][1]=D_scalar*dvydy;
-		TripleMultiply(B,2,numnodes,1,
-					&D[0][0],2,2,0,
-					B,2,numnodes,0,
-					&Ke->values[0],1);
-
-		D[0][0]=D_scalar*vx;
-		D[1][1]=D_scalar*vy;
-		TripleMultiply(B,2,numnodes,1,
-					&D[0][0],2,2,0,
-					Bprime,2,numnodes,0,
-					&Ke->values[0],1);
-
-		if(stabilization==2){
-			/*Streamline upwinding*/
-			vel=sqrt(vx*vx+vy*vy)+1.e-8;
-			D[0][0]=h/(2*vel)*vx*vx;
-			D[1][0]=h/(2*vel)*vy*vx;
-			D[0][1]=h/(2*vel)*vx*vy;
-			D[1][1]=h/(2*vel)*vy*vy;
-		}
-		else if(stabilization==1){
-			/*SSA*/
-			vxaverage_input->GetInputAverage(&vx);
-			vyaverage_input->GetInputAverage(&vy);
-			D[0][0]=h/2.0*fabs(vx);
-			D[0][1]=0.;
-			D[1][0]=0.;
-			D[1][1]=h/2.0*fabs(vy);
-		}
-		if(stabilization==1 || stabilization==2){
-			D[0][0]=D_scalar*D[0][0];
-			D[1][0]=D_scalar*D[1][0];
-			D[0][1]=D_scalar*D[0][1];
-			D[1][1]=D_scalar*D[1][1];
-			TripleMultiply(Bprime,2,numnodes,1,
-						&D[0][0],2,2,0,
-						Bprime,2,numnodes,0,
-						&Ke->values[0],1);
-		}
-	}
-
-	/*Clean up and return*/
-	xDelete<IssmDouble>(basis);
-	xDelete<IssmDouble>(B);
-	xDelete<IssmDouble>(Bprime);
-	delete gauss;
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Tria::CreateKMatrixMasstransport_DG {{{*/
-ElementMatrix* Tria::CreateKMatrixMasstransport_DG(void){
-
-	/*Intermediaries */
-	int        meshtype;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble Jdet,D_scalar,dt,vx,vy;
-
-	/*Fetch number of nodes for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Initialize Element matrix and vectors*/
-	ElementMatrix* Ke     = new ElementMatrix(nodes,numnodes,this->parameters,NoneApproximationEnum);
-	IssmDouble*    basis  = xNew<IssmDouble>(numnodes);
-	IssmDouble*    B      = xNew<IssmDouble>(2*numnodes);
-	IssmDouble*    Bprime = xNew<IssmDouble>(2*numnodes);
-	IssmDouble     D[2][2];
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);
-	this->parameters->FindParam(&meshtype,MeshTypeEnum);
-	Input* vxaverage_input=NULL;
-	Input* vyaverage_input=NULL;
-	if(meshtype==Mesh2DhorizontalEnum){
-		vxaverage_input=inputs->GetInput(VxEnum); _assert_(vxaverage_input);
-		vyaverage_input=inputs->GetInput(VyEnum); _assert_(vyaverage_input);
-	}
-	else{
-		vxaverage_input=inputs->GetInput(VxAverageEnum); _assert_(vxaverage_input);
-		vyaverage_input=inputs->GetInput(VyAverageEnum); _assert_(vyaverage_input);
-	}
-
-	/* Start  looping on the number of gaussian points: */
-	GaussTria* gauss=new GaussTria(2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		vxaverage_input->GetInputValue(&vx,gauss);
-		vyaverage_input->GetInputValue(&vy,gauss);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		GetNodalFunctions(basis,gauss);
-
-		D_scalar=gauss->weight*Jdet;
-
-		TripleMultiply(basis,1,numnodes,1,
-					&D_scalar,1,1,0,
-					basis,1,numnodes,0,
-					&Ke->values[0],1);
-
-		/*WARNING: B and Bprime are inverted compared to usual masstransport!!!!*/
-		GetBMasstransport(Bprime, &xyz_list[0][0], gauss);
-		GetBprimeMasstransport(B, &xyz_list[0][0], gauss);
-
-		D_scalar=-dt*gauss->weight*Jdet;
-		D[0][0]=D_scalar*vx;
-		D[0][1]=0.;
-		D[1][0]=0.;
-		D[1][1]=D_scalar*vy;
-
-		TripleMultiply(B,2,numnodes,1,
-					&D[0][0],2,2,0,
-					Bprime,2,numnodes,0,
-					&Ke->values[0],1);
-	}
-
-	/*Clean up and return*/
-	xDelete<IssmDouble>(basis);
-	xDelete<IssmDouble>(B);
-	xDelete<IssmDouble>(Bprime);
-	delete gauss;
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Tria::CreateKMatrixFreeSurfaceTop {{{*/
-ElementMatrix* Tria::CreateKMatrixFreeSurfaceTop(void){
-
-	/*Intermediaries */
-	int        stabilization;
-	IssmDouble Jdet,D_scalar,dt,h;
-	IssmDouble vel,vx,vy;
-	IssmDouble xyz_list[NUMVERTICES][3];
-
-	/*Fetch number of nodes for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Initialize Element matrix and vectors*/
-	ElementMatrix* Ke     = new ElementMatrix(nodes,numnodes,this->parameters,NoneApproximationEnum);
-	IssmDouble*    basis  = xNew<IssmDouble>(numnodes);
-	IssmDouble*    B      = xNew<IssmDouble>(2*numnodes);
-	IssmDouble*    Bprime = xNew<IssmDouble>(2*numnodes);
-	IssmDouble     D[2][2];
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);
-	this->parameters->FindParam(&stabilization,MasstransportStabilizationEnum);
-	Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);
-	Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);
-	h=sqrt(2*this->GetArea());
-
-	/* Start  looping on the number of gaussian points: */
-	GaussTria *gauss=new GaussTria(2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		GetNodalFunctions(basis,gauss);
-
-		vx_input->GetInputValue(&vx,gauss);
-		vy_input->GetInputValue(&vy,gauss);
-
-		D_scalar=gauss->weight*Jdet;
-
-		TripleMultiply(basis,1,numnodes,1,
-					&D_scalar,1,1,0,
-					basis,1,numnodes,0,
-					&Ke->values[0],1);
-
-		GetBMasstransport(B,&xyz_list[0][0],gauss);
-		GetBprimeMasstransport(Bprime,&xyz_list[0][0],gauss);
-
-		D_scalar=dt*gauss->weight*Jdet;
-
-		D[0][0]=D_scalar*vx;
-		D[0][1]=0.;
-		D[1][0]=0.;
-		D[1][1]=D_scalar*vy;
-		TripleMultiply(B,2,numnodes,1,
-					&D[0][0],2,2,0,
-					Bprime,2,numnodes,0,
-					&Ke->values[0],1);
-
-		if(stabilization==2){
-			/*Streamline upwinding*/
-			vel=sqrt(vx*vx+vy*vy)+1.e-8;
-			D[0][0]=h/(2*vel)*vx*vx;
-			D[1][0]=h/(2*vel)*vy*vx;
-			D[0][1]=h/(2*vel)*vx*vy;
-			D[1][1]=h/(2*vel)*vy*vy;
-		}
-		else if(stabilization==1){
-			/*SSA*/
-			vx_input->GetInputAverage(&vx);
-			vy_input->GetInputAverage(&vy);
-			D[0][0]=h/2.0*fabs(vx);
-			D[0][1]=0.;
-			D[1][0]=0.;
-			D[1][1]=h/2.0*fabs(vy);
-		}
-		if(stabilization==1 || stabilization==2){
-			D[0][0]=D_scalar*D[0][0];
-			D[1][0]=D_scalar*D[1][0];
-			D[0][1]=D_scalar*D[0][1];
-			D[1][1]=D_scalar*D[1][1];
-			TripleMultiply(Bprime,2,numnodes,1,
-						&D[0][0],2,2,0,
-						Bprime,2,numnodes,0,
-						&Ke->values[0],1);
-		}
-	}
-
-	/*Clean up and return*/
-	xDelete<IssmDouble>(basis);
-	xDelete<IssmDouble>(B);
-	xDelete<IssmDouble>(Bprime);
-	delete gauss;
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Tria::CreateKMatrixFreeSurfaceTop1D {{{*/
-ElementMatrix* Tria::CreateKMatrixFreeSurfaceTop1D(void){
-
-	if(!HasEdgeOnSurface()) return NULL;
-
-	int index1,index2;
-	this->EdgeOnSurfaceIndices(&index1,&index2);
-
-	Seg* seg=(Seg*)SpawnSeg(index1,index2); 
-	ElementMatrix* Ke=seg->CreateKMatrixFreeSurfaceTop();
-	delete seg->material; delete seg;
-
-	/*clean up and return*/
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Tria::CreateKMatrixFreeSurfaceBase {{{*/
-ElementMatrix* Tria::CreateKMatrixFreeSurfaceBase(void){
-
-	/*Intermediaries */
-	int        stabilization;
-	IssmDouble Jdet,D_scalar,dt,h;
-	IssmDouble vel,vx,vy;
-	IssmDouble xyz_list[NUMVERTICES][3];
-
-	/*Fetch number of nodes for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Initialize Element matrix and vectors*/
-	ElementMatrix* Ke     = new ElementMatrix(nodes,numnodes,this->parameters,NoneApproximationEnum);
-	IssmDouble*    basis  = xNew<IssmDouble>(numnodes);
-	IssmDouble*    B      = xNew<IssmDouble>(2*numnodes);
-	IssmDouble*    Bprime = xNew<IssmDouble>(2*numnodes);
-	IssmDouble     D[2][2];
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);
-	this->parameters->FindParam(&stabilization,MasstransportStabilizationEnum);
-	Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);
-	Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);
-	h=sqrt(2*this->GetArea());
-
-	/* Start  looping on the number of gaussian points: */
-	GaussTria *gauss=new GaussTria(2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		GetNodalFunctions(basis,gauss);
-
-		vx_input->GetInputValue(&vx,gauss);
-		vy_input->GetInputValue(&vy,gauss);
-
-		D_scalar=gauss->weight*Jdet;
-
-		TripleMultiply(basis,1,numnodes,1,
-					&D_scalar,1,1,0,
-					basis,1,numnodes,0,
-					&Ke->values[0],1);
-
-		GetBMasstransport(B,&xyz_list[0][0],gauss);
-		GetBprimeMasstransport(Bprime,&xyz_list[0][0],gauss);
-
-		D_scalar=dt*gauss->weight*Jdet;
-
-		D[0][0]=D_scalar*vx;
-		D[0][1]=0.;
-		D[1][0]=0.;
-		D[1][1]=D_scalar*vy;
-		TripleMultiply(B,2,numnodes,1,
-					&D[0][0],2,2,0,
-					Bprime,2,numnodes,0,
-					&Ke->values[0],1);
-
-		if(stabilization==2){
-			/*Streamline upwinding*/
-			vel=sqrt(vx*vx+vy*vy)+1.e-8;
-			D[0][0]=h/(2*vel)*vx*vx;
-			D[1][0]=h/(2*vel)*vy*vx;
-			D[0][1]=h/(2*vel)*vx*vy;
-			D[1][1]=h/(2*vel)*vy*vy;
-		}
-		else if(stabilization==1){
-			/*SSA*/
-			vx_input->GetInputAverage(&vx);
-			vy_input->GetInputAverage(&vy);
-			D[0][0]=h/2.0*fabs(vx);
-			D[0][1]=0.;
-			D[1][0]=0.;
-			D[1][1]=h/2.0*fabs(vy);
-		}
-		if(stabilization==1 || stabilization==2){
-			D[0][0]=D_scalar*D[0][0];
-			D[1][0]=D_scalar*D[1][0];
-			D[0][1]=D_scalar*D[0][1];
-			D[1][1]=D_scalar*D[1][1];
-			TripleMultiply(Bprime,2,numnodes,1,
-						&D[0][0],2,2,0,
-						Bprime,2,numnodes,0,
-						&Ke->values[0],1);
-		}
-	}
-
-	/*Clean up and return*/
-	xDelete<IssmDouble>(basis);
-	xDelete<IssmDouble>(B);
-	xDelete<IssmDouble>(Bprime);
-	delete gauss;
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Tria::CreateKMatrixFreeSurfaceBase1D {{{*/
-ElementMatrix* Tria::CreateKMatrixFreeSurfaceBase1D(void){
-
-	if(!HasEdgeOnBed()) return NULL;
-
-	int index1,index2;
-	this->EdgeOnBedIndices(&index1,&index2);
-
-	Seg* seg=(Seg*)SpawnSeg(index1,index2); 
-	ElementMatrix* Ke=seg->CreateKMatrixFreeSurfaceBase();
-	delete seg->material; delete seg;
-
-	/*clean up and return*/
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Tria::CreatePVectorMasstransport{{{*/
-ElementVector* Tria::CreatePVectorMasstransport(void){
-
-	switch(GetElementType()){
-		case P1Enum: case P2Enum:
-			return CreatePVectorMasstransport_CG();
-		case P1DGEnum:
-			return CreatePVectorMasstransport_DG();
-		default:
-			_error_("Element type " << EnumToStringx(GetElementType()) << " not supported yet");
-	}
-}
-/*}}}*/
-/*FUNCTION Tria::CreatePVectorMasstransport_CG {{{*/
-ElementVector* Tria::CreatePVectorMasstransport_CG(void){
-
-	/*Intermediaries */
-	IssmDouble Jdet,dt;
-	IssmDouble ms,mb,mb_correction,thickness;
-	IssmDouble xyz_list[NUMVERTICES][3];
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Initialize Element vector and other vectors*/
-	ElementVector* pe    = new ElementVector(nodes,numnodes,this->parameters);
-	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);
-	Input* ms_input     = inputs->GetInput(SurfaceforcingsMassBalanceEnum);      _assert_(ms_input);
-	Input* mb_input     = inputs->GetInput(BasalforcingsMeltingRateEnum); _assert_(mb_input);
-	Input* mb_correction_input = inputs->GetInput(BasalforcingsMeltingRateCorrectionEnum);
-	Input* thickness_input  = inputs->GetInput(ThicknessEnum);     _assert_(thickness_input);
-
-	/*Initialize mb_correction to 0, do not forget!:*/
-	/* Start  looping on the number of gaussian points: */
-	GaussTria* gauss=new GaussTria(2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		GetNodalFunctions(basis,gauss);
-
-		ms_input->GetInputValue(&ms,gauss);
-		mb_input->GetInputValue(&mb,gauss);
-		thickness_input->GetInputValue(&thickness,gauss);
-		if(mb_correction_input)
-		 mb_correction_input->GetInputValue(&mb_correction,gauss);
-		else
-		 mb_correction=0.;
-
-		for(int i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*(thickness+dt*(ms-mb-mb_correction))*basis[i];
-	}
-
-	/*Clean up and return*/
-	xDelete<IssmDouble>(basis);
-	delete gauss;
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Tria::CreatePVectorMasstransport_DG {{{*/
-ElementVector* Tria::CreatePVectorMasstransport_DG(void){
-
-	/*Intermediaries */
-	IssmDouble Jdet,dt;
-	IssmDouble ms,mb,thickness;
-	IssmDouble xyz_list[NUMVERTICES][3];
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Initialize Element vector and other vectors*/
-	ElementVector* pe    = new ElementVector(nodes,numnodes,this->parameters);
-	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
-
-	/*Retrieve all inputs and parameters*/
-	this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	Input* ms_input=inputs->GetInput(SurfaceforcingsMassBalanceEnum); _assert_(ms_input);
-	Input* mb_input=inputs->GetInput(BasalforcingsMeltingRateEnum);   _assert_(mb_input);
-	Input* thickness_input=inputs->GetInput(ThicknessEnum);           _assert_(thickness_input);
-
-	/* Start  looping on the number of gaussian points: */
-	GaussTria* gauss=new GaussTria(2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		GetNodalFunctions(basis,gauss);
-
-		ms_input->GetInputValue(&ms,gauss);
-		mb_input->GetInputValue(&mb,gauss);
-		thickness_input->GetInputValue(&thickness,gauss);
-
-		for(int i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*(thickness+dt*(ms-mb))*basis[i];
-	}
-
-	/*Clean up and return*/
-	xDelete<IssmDouble>(basis);
-	delete gauss;
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Tria::CreatePVectorFreeSurfaceTop {{{*/
-ElementVector* Tria::CreatePVectorFreeSurfaceTop(void){
-
-	/*Intermediaries */
-	IssmDouble Jdet,dt;
-	IssmDouble ms,surface,vz;
-	IssmDouble xyz_list[NUMVERTICES][3];
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Initialize Element vector and other vectors*/
-	ElementVector* pe    = new ElementVector(nodes,numnodes,this->parameters);
-	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);
-	Input* vz_input     = inputs->GetInput(VzEnum);                         _assert_(vz_input);
-	Input* ms_input     = inputs->GetInput(SurfaceforcingsMassBalanceEnum); _assert_(ms_input);
-	Input* surface_input= inputs->GetInput(SurfaceEnum);                    _assert_(surface_input);
-
-	/*Initialize mb_correction to 0, do not forget!:*/
-	/* Start  looping on the number of gaussian points: */
-	GaussTria* gauss=new GaussTria(2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		GetNodalFunctions(basis,gauss);
-
-		vz_input->GetInputValue(&vz,gauss);
-		ms_input->GetInputValue(&ms,gauss);
-		surface_input->GetInputValue(&surface,gauss);
-
-		for(int i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*(surface + dt*ms + dt*vz)*basis[i];
-	}
-
-	/*Clean up and return*/
-	xDelete<IssmDouble>(basis);
-	delete gauss;
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Tria::CreatePVectorFreeSurfaceTop1D {{{*/
-ElementVector* Tria::CreatePVectorFreeSurfaceTop1D(void){
-
-	if(!HasEdgeOnSurface()) return NULL;
-
-	int index1,index2;
-	this->EdgeOnSurfaceIndices(&index1,&index2);
-
-	Seg* seg=(Seg*)SpawnSeg(index1,index2); 
-	ElementVector* pe=seg->CreatePVectorFreeSurfaceTop();
-	delete seg->material; delete seg;
-
-	/*clean up and return*/
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Tria::CreatePVectorFreeSurfaceBase {{{*/
-ElementVector* Tria::CreatePVectorFreeSurfaceBase(void){
-
-	/*Intermediaries */
-	IssmDouble Jdet,dt;
-	IssmDouble mb,mb_correction,bed,vz;
-	IssmDouble xyz_list[NUMVERTICES][3];
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Initialize Element vector and other vectors*/
-	ElementVector* pe    = new ElementVector(nodes,numnodes,this->parameters);
-	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);
-	Input* vz_input  = inputs->GetInput(VzEnum);                         _assert_(vz_input);
-	Input* mb_input  = inputs->GetInput(BasalforcingsMeltingRateEnum);   _assert_(mb_input);
-	Input* mb_correction_input = inputs->GetInput(BasalforcingsMeltingRateCorrectionEnum);
-	Input* bed_input = inputs->GetInput(BedEnum);                        _assert_(bed_input);
-
-	/*Initialize mb_correction to 0, do not forget!:*/
-	/* Start  looping on the number of gaussian points: */
-	GaussTria* gauss=new GaussTria(2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		GetNodalFunctions(basis,gauss);
-
-		vz_input->GetInputValue(&vz,gauss);
-		mb_input->GetInputValue(&mb,gauss);
-		bed_input->GetInputValue(&bed,gauss);
-		if(mb_correction_input)
-		 mb_correction_input->GetInputValue(&mb_correction,gauss);
-		else
-		 mb_correction=0.;
-
-		for(int i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*(bed+dt*(mb-mb_correction) + dt*vz)*basis[i];
-	}
-
-	/*Clean up and return*/
-	xDelete<IssmDouble>(basis);
-	delete gauss;
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Tria::CreatePVectorFreeSurfaceBase1D {{{*/
-ElementVector* Tria::CreatePVectorFreeSurfaceBase1D(void){
-
-	if(!HasEdgeOnBed()) return NULL;
-
-	int index1,index2;
-	this->EdgeOnBedIndices(&index1,&index2);
-
-	Seg* seg=(Seg*)SpawnSeg(index1,index2); 
-	ElementVector* pe=seg->CreatePVectorFreeSurfaceBase();
-	delete seg->material; delete seg;
-
-	/*clean up and return*/
-	return pe;
-}
-/*}}}*/
-#endif
-
-#ifdef _HAVE_DAMAGE_
-/*FUNCTION Tria::CreateKMatrixDamageEvolution {{{*/
-ElementMatrix* Tria::CreateKMatrixDamageEvolution(void){
-
-	switch(GetElementType()){
-		case P1Enum: case P2Enum:
-			return CreateKMatrixDamageEvolution_CG();
-		case P1DGEnum:
-			_error_("DG not implemented yet!");break;
-		default:
-			_error_("Element type " << EnumToStringx(GetElementType()) << " not supported yet");
-	}
-}
-/*}}}*/
-/*FUNCTION Tria::CreateKMatrixDamageEvolution_CG {{{*/
-ElementMatrix* Tria::CreateKMatrixDamageEvolution_CG(void){
-
-	/*Intermediaries */
-	int        stabilization;
-	int        meshtype;
-	IssmDouble Jdet,D_scalar,dt,h;
-	IssmDouble vel,vx,vy,dvxdx,dvydy;
-	IssmDouble dvx[2],dvy[2];
-	IssmDouble xyz_list[NUMVERTICES][3];
-
-	/*Fetch number of nodes for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Initialize Element matrix and vectors*/
-	ElementMatrix* Ke     = new ElementMatrix(nodes,numnodes,this->parameters,NoneApproximationEnum);
-	IssmDouble*    basis  = xNew<IssmDouble>(numnodes);
-	IssmDouble*    B      = xNew<IssmDouble>(2*numnodes);
-	IssmDouble*    Bprime = xNew<IssmDouble>(2*numnodes);
-	IssmDouble     D[2][2];
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);
-	this->parameters->FindParam(&meshtype,MeshTypeEnum);
-	this->parameters->FindParam(&stabilization,DamageStabilizationEnum);
-	Input* vxaverage_input=NULL;
-	Input* vyaverage_input=NULL;
-	if(meshtype==Mesh2DhorizontalEnum){
-		vxaverage_input=inputs->GetInput(VxEnum); _assert_(vxaverage_input);
-		vyaverage_input=inputs->GetInput(VyEnum); _assert_(vyaverage_input);
-	}
-	else{
-		vxaverage_input=inputs->GetInput(VxAverageEnum); _assert_(vxaverage_input);
-		vyaverage_input=inputs->GetInput(VyAverageEnum); _assert_(vyaverage_input);
-	}
-	h=sqrt(2*this->GetArea());
-
-	/* Start  looping on the number of gaussian points: */
-	GaussTria *gauss=new GaussTria(2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		GetNodalFunctions(basis,gauss);
-
-		vxaverage_input->GetInputValue(&vx,gauss);
-		vyaverage_input->GetInputValue(&vy,gauss);
-		vxaverage_input->GetInputDerivativeValue(&dvx[0],&xyz_list[0][0],gauss);
-		vyaverage_input->GetInputDerivativeValue(&dvy[0],&xyz_list[0][0],gauss);
-
-		D_scalar=gauss->weight*Jdet;
-
-		TripleMultiply(basis,1,numnodes,1,
-					&D_scalar,1,1,0,
-					basis,1,numnodes,0,
-					&Ke->values[0],1);
-		GetBMasstransport(B,&xyz_list[0][0],gauss);
-		GetBprimeMasstransport(Bprime,&xyz_list[0][0],gauss);
-
-		dvxdx=dvx[0];
-		dvydy=dvy[1];
-		D_scalar=dt*gauss->weight*Jdet;
-
-		D[0][0]=D_scalar*dvxdx;
-		D[0][1]=0.;
-		D[1][0]=0.;
-		D[1][1]=D_scalar*dvydy;
-		TripleMultiply(B,2,numnodes,1,
-					&D[0][0],2,2,0,
-					B,2,numnodes,0,
-					&Ke->values[0],1);
-
-		D[0][0]=D_scalar*vx;
-		D[1][1]=D_scalar*vy;
-		TripleMultiply(B,2,numnodes,1,
-					&D[0][0],2,2,0,
-					Bprime,2,numnodes,0,
-					&Ke->values[0],1);
-
-		if(stabilization==2){
-			/*Streamline upwinding*/
-			vel=sqrt(vx*vx+vy*vy)+1.e-8;
-			D[0][0]=h/(2*vel)*vx*vx;
-			D[1][0]=h/(2*vel)*vy*vx;
-			D[0][1]=h/(2*vel)*vx*vy;
-			D[1][1]=h/(2*vel)*vy*vy;
-		}
-		else if(stabilization==1){
-			/*SSA*/
-			vxaverage_input->GetInputAverage(&vx);
-			vyaverage_input->GetInputAverage(&vy);
-			D[0][0]=h/2.0*fabs(vx);
-			D[0][1]=0.;
-			D[1][0]=0.;
-			D[1][1]=h/2.0*fabs(vy);
-		}
-		if(stabilization==1 || stabilization==2){
-			D[0][0]=D_scalar*D[0][0];
-			D[1][0]=D_scalar*D[1][0];
-			D[0][1]=D_scalar*D[0][1];
-			D[1][1]=D_scalar*D[1][1];
-			TripleMultiply(Bprime,2,numnodes,1,
-						&D[0][0],2,2,0,
-						Bprime,2,numnodes,0,
-						&Ke->values[0],1);
-		}
-	}
-
-	/*Clean up and return*/
-	xDelete<IssmDouble>(basis);
-	xDelete<IssmDouble>(B);
-	xDelete<IssmDouble>(Bprime);
-	delete gauss;
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Tria::CreatePVectorDamageEvolution{{{*/
-ElementVector* Tria::CreatePVectorDamageEvolution(void){
-
-	switch(GetElementType()){
-		case P1Enum: case P2Enum:
-			return CreatePVectorDamageEvolution_CG();
-		case P1DGEnum:
-			_error_("DG not implemented yet");
-		default:
-			_error_("Element type " << EnumToStringx(GetElementType()) << " not supported yet");
-	}
-}
-/*}}}*/
-/*FUNCTION Tria::CreatePVectorDamageEvolution_CG {{{*/
-ElementVector* Tria::CreatePVectorDamageEvolution_CG(void){
-
-	/*Intermediaries */
-	IssmDouble  Jdet ,dt;
-	IssmDouble  f,damage;
-	IssmDouble  xyz_list[NUMVERTICES][3];
-	IssmDouble  f_list[NUMVERTICES];
-	Input      *damage_input             = NULL;
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Initialize Element vector and other vectors*/
-	ElementVector* pe    = new ElementVector(nodes,numnodes,this->parameters);
-	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);
-	damage_input  = this->material->inputs->GetInput(DamageDbarEnum);     _assert_(damage_input);
-	
-	/*retrieve damage evolution forcing function: */
-	this->DamageEvolutionF(&f_list[0]);
-
-	/*Initialize forcing function f to 0, do not forget!:*/
-	/* Start  looping on the number of gaussian points: */
-	GaussTria* gauss=new GaussTria(2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		GetNodalFunctions(basis,gauss);
-
-		TriaRef::GetInputValue(&f,f_list,gauss);
-		damage_input->GetInputValue(&damage,gauss);
-
-		for(int i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*(damage+dt*f)*basis[i];
-	}
-
-	/*Clean up and return*/
-	xDelete<IssmDouble>(basis);
-	delete gauss;
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Tria::DamageEvolutionF{{{*/
-void Tria::DamageEvolutionF(IssmDouble* f){
-
-	/*Intermediaries */
-	IssmDouble c1,c2,c3,healing,stress_threshold;
-	IssmDouble s_xx,s_xy,s_yy;
-	IssmDouble J2s;
-	IssmDouble Xis;
-	IssmDouble Psi;
-	IssmDouble PosPsi;
-	IssmDouble NegPsi;
-	Input* damage_input=NULL;
-	Input* sigma_xx_input  = NULL;
-	Input* sigma_xy_input  = NULL;
-	Input* sigma_yy_input  = NULL;
-	GaussTria* gauss=NULL;
-	IssmDouble damage,sigma_xx,sigma_xy,sigma_yy;
-
-	/*retrieve parameters:*/
-	this->parameters->FindParam(&c1,DamageC1Enum);
-	this->parameters->FindParam(&c2,DamageC2Enum);
-	this->parameters->FindParam(&c3,DamageC3Enum);
-	this->parameters->FindParam(&healing,DamageHealingEnum);
-	this->parameters->FindParam(&stress_threshold,DamageStressThresholdEnum);
-
-	/*Compute stress tensor: */
-	this->ComputeStressTensor();
-
-	/*retrieve what we need: */
-	sigma_xx_input  = inputs->GetInput(StressTensorxxEnum);  _assert_(sigma_xx_input);
-	sigma_xy_input  = inputs->GetInput(StressTensorxyEnum);  _assert_(sigma_xy_input);
-	sigma_yy_input  = inputs->GetInput(StressTensoryyEnum);  _assert_(sigma_yy_input);
-	damage_input  = this->material->inputs->GetInput(DamageDbarEnum);        _assert_(damage_input);
-
-	/*Damage evolution z mapping: */
-	gauss=new GaussTria();
-	J2s=0;
-	for (int iv=0;iv<NUMVERTICES;iv++){
-		gauss->GaussVertex(iv);
-		
-		damage_input->GetInputValue(&damage,gauss);
-		sigma_xx_input->GetInputValue(&sigma_xx,gauss);
-		sigma_xy_input->GetInputValue(&sigma_xy,gauss);
-		sigma_yy_input->GetInputValue(&sigma_yy,gauss);
-
-		s_xx=sigma_xx/(1-damage);
-		s_xy=sigma_xy/(1-damage);
-		s_yy=sigma_yy/(1-damage);
-
-		J2s=1.0/sqrt(2.0)*sqrt(pow(s_xx,2)+pow(s_yy,2)+2*pow(s_xy,2));
-		
-		Xis=sqrt(3.0)*J2s;
-
-		Psi=Xis-stress_threshold;
-
-		PosPsi=max(Psi,0.0);
-		NegPsi=max(-Psi,0.0);
-
-		f[iv]= c1* ( pow(PosPsi,c2)   -  healing * pow(NegPsi,c2) )  *   pow((1 - damage),-c3);
-
-	}
-	
-	/*Clean up and return*/
-	delete gauss;
-}
-/*}}}*/
-/*FUNCTION Tria::InputUpdateFromSolutionDamageEvolution {{{*/
-void  Tria::InputUpdateFromSolutionDamageEvolution(IssmDouble* solution){
-
-	const int    numdof=NDOF1*NUMVERTICES;
-
-	int         i;
-	IssmDouble  values[numdof];
-	IssmDouble  max_damage;
-	int			*doflist = NULL;
-
-	/*Get dof list: */
-	GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
-
-	/*Get user-supplied max_damage: */
-	this->parameters->FindParam(&max_damage,DamageMaxDamageEnum);
-
-	/*Use the dof list to index into the solution vector: */
-	for(i=0;i<numdof;i++){
-		values[i]=solution[doflist[i]];
-		/*Check solution*/
-		if(xIsNan<IssmDouble>(values[i])) _error_("NaN found in solution vector");
-		/*Enforce D < max_damage and D > 0 */
-		if(values[i]>max_damage) values[i]=max_damage;
-		else if(values[i]<0) values[i]=0;
-	}
-
-	/*Get all inputs and parameters*/
-	this->material->inputs->AddInput(new TriaInput(DamageDbarEnum,values,P1Enum));
-
-	/*Free ressources:*/
-	xDelete<int>(doflist);
-}
-/*}}}*/
-#endif
 
 #ifdef _HAVE_DAKOTA_
@@ -8373,5 +4298,5 @@
 					GetInputListOnVertices(&thickness_init[0],ThicknessEnum);
 					GetInputListOnVertices(&hydrostatic_ratio[0],GeometryHydrostaticRatioEnum);
-					GetInputListOnVertices(&bed[0],BedEnum);
+					GetInputListOnVertices(&bed[0],BaseEnum);
 					GetInputListOnVertices(&surface[0],SurfaceEnum);
 
@@ -8415,7 +4340,10 @@
 					/*Add new inputs: */
 					this->inputs->AddInput(new TriaInput(ThicknessEnum,thickness,P1Enum));
-					this->inputs->AddInput(new TriaInput(BedEnum,bed,P1Enum));
+					this->inputs->AddInput(new TriaInput(BaseEnum,bed,P1Enum));
 					this->inputs->AddInput(new TriaInput(SurfaceEnum,surface,P1Enum));
 
+					break;
+				case MaterialsRheologyBEnum:
+					this->inputs->AddInput(new TriaInput(MaterialsRheologyBbarEnum,values,P1Enum));
 					break;
 				default:
@@ -8471,600 +4399,4 @@
 #endif
 
-#ifdef _HAVE_BALANCED_
-/*FUNCTION Tria::CreateKMatrixBalancethickness {{{*/
-ElementMatrix* Tria::CreateKMatrixBalancethickness(void){
-
-	switch(GetElementType()){
-		case P1Enum:
-			return CreateKMatrixBalancethickness_CG();
-		case P1DGEnum:
-			return CreateKMatrixBalancethickness_DG();
-		default:
-			_error_("Element type " << EnumToStringx(GetElementType()) << " not supported yet");
-	}
-
-}
-/*}}}*/
-/*FUNCTION Tria::CreateKMatrixBalancethickness_CG {{{*/
-ElementMatrix* Tria::CreateKMatrixBalancethickness_CG(void){
-
-	/*Intermediaries */
-	int        stabilization,meshtype;
-	IssmDouble Jdet,vx,vy,dvxdx,dvydy,vel,h;
-	IssmDouble D_scalar;
-	IssmDouble dvx[2],dvy[2];
-	IssmDouble xyz_list[NUMVERTICES][3];
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Initialize Element matrix and vectors*/
-	ElementMatrix* Ke     = new ElementMatrix(nodes,numnodes,this->parameters,NoneApproximationEnum);
-	IssmDouble*    basis  = xNew<IssmDouble>(numnodes);
-	IssmDouble*    B      = xNew<IssmDouble>(2*numnodes);
-	IssmDouble*    Bprime = xNew<IssmDouble>(2*numnodes);
-	IssmDouble     D[2][2];
-
-	/*Retrieve all Inputs and parameters: */
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	this->parameters->FindParam(&stabilization,BalancethicknessStabilizationEnum);
-	this->parameters->FindParam(&meshtype,MeshTypeEnum);
-	Input* vxaverage_input=NULL;
-	Input* vyaverage_input=NULL;
-	if(meshtype==Mesh2DhorizontalEnum){
-		vxaverage_input=inputs->GetInput(VxEnum); _assert_(vxaverage_input);
-		vyaverage_input=inputs->GetInput(VyEnum); _assert_(vyaverage_input);
-	}
-	else{
-		vxaverage_input=inputs->GetInput(VxAverageEnum); _assert_(vxaverage_input);
-		vyaverage_input=inputs->GetInput(VyAverageEnum); _assert_(vyaverage_input);
-	}
-	h=sqrt(2.*this->GetArea());
-
-	/*Start looping on the number of gaussian points:*/
-	GaussTria* gauss=new GaussTria(2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		GetBMasstransport(B,&xyz_list[0][0],gauss);
-		GetBprimeMasstransport(Bprime,&xyz_list[0][0],gauss);
-
-		vxaverage_input->GetInputValue(&vx,gauss);
-		vyaverage_input->GetInputValue(&vy,gauss);
-		vxaverage_input->GetInputDerivativeValue(&dvx[0],&xyz_list[0][0],gauss);
-		vyaverage_input->GetInputDerivativeValue(&dvy[0],&xyz_list[0][0],gauss);
-
-		dvxdx=dvx[0];
-		dvydy=dvy[1];
-		D_scalar=gauss->weight*Jdet;
-
-		D[0][0]=D_scalar*dvxdx;
-		D[0][1]=0.;
-		D[1][0]=0.;
-		D[1][1]=D_scalar*dvydy;
-		TripleMultiply(B,2,numnodes,1,
-					&D[0][0],2,2,0,
-					B,2,numnodes,0,
-					&Ke->values[0],1);
-
-		D[0][0]=D_scalar*vx;
-		D[1][1]=D_scalar*vy;
-		TripleMultiply(B,2,numnodes,1,
-					&D[0][0],2,2,0,
-					Bprime,2,numnodes,0,
-					&Ke->values[0],1);
-
-		if(stabilization==1){
-			/*Streamline upwinding*/
-			vel=sqrt(vx*vx+vy*vy);
-			D[0][0]=h/(2*vel)*vx*vx;
-			D[1][0]=h/(2*vel)*vy*vx;
-			D[0][1]=h/(2*vel)*vx*vy;
-			D[1][1]=h/(2*vel)*vy*vy;
-		}
-		else if(stabilization==2){
-			/*SSA*/
-			vxaverage_input->GetInputAverage(&vx);
-			vyaverage_input->GetInputAverage(&vy);
-			D[0][0]=h/2.0*fabs(vx);
-			D[0][1]=0.;
-			D[1][0]=0.;
-			D[1][1]=h/2.0*fabs(vy);
-		}
-		if(stabilization==1 || stabilization==2){
-			D[0][0]=D_scalar*D[0][0];
-			D[1][0]=D_scalar*D[1][0];
-			D[0][1]=D_scalar*D[0][1];
-			D[1][1]=D_scalar*D[1][1];
-			TripleMultiply(Bprime,2,numnodes,1,
-						&D[0][0],2,2,0,
-						Bprime,2,numnodes,0,
-						&Ke->values[0],1);
-		}
-	}
-
-	/*Clean up and return*/
-	xDelete<IssmDouble>(basis);
-	xDelete<IssmDouble>(B);
-	xDelete<IssmDouble>(Bprime);
-	delete gauss;
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Tria::CreateKMatrixBalancethickness_DG {{{*/
-ElementMatrix* Tria::CreateKMatrixBalancethickness_DG(void){
-
-	/*Intermediaries*/
-	IssmDouble vx,vy,D_scalar,Jdet;
-	IssmDouble xyz_list[NUMVERTICES][3];
-
-	/*Fetch number of nodes for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Initialize Element matrix and vectors*/
-	ElementMatrix* Ke     = new ElementMatrix(nodes,numnodes,this->parameters,NoneApproximationEnum);
-	IssmDouble*    basis  = xNew<IssmDouble>(numnodes);
-	IssmDouble*    B      = xNew<IssmDouble>(2*numnodes);
-	IssmDouble*    Bprime = xNew<IssmDouble>(2*numnodes);
-	IssmDouble     D[2][2];
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);
-	Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);
-
-	/*Start looping on the number of gaussian points:*/
-	GaussTria* gauss=new GaussTria(2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		/*WARNING: B and Bprime are inverted compared to usual masstransport!!!!*/
-		GetBMasstransport(Bprime,&xyz_list[0][0],gauss);
-		GetBprimeMasstransport(B,&xyz_list[0][0],gauss);
-
-		vx_input->GetInputValue(&vx,gauss);
-		vy_input->GetInputValue(&vy,gauss);
-
-		D_scalar=-gauss->weight*Jdet;
-		D[0][0]=D_scalar*vx;
-		D[0][1]=0.;
-		D[1][0]=0.;
-		D[1][1]=D_scalar*vy;
-
-		TripleMultiply(B,2,numnodes,1,
-					&D[0][0],2,2,0,
-					Bprime,2,numnodes,0,
-					&Ke->values[0],1);
-	}
-
-	/*Clean up and return*/
-	xDelete<IssmDouble>(basis);
-	xDelete<IssmDouble>(B);
-	xDelete<IssmDouble>(Bprime);
-	delete gauss;
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Tria::CreateKMatrixBalancevelocity{{{*/
-ElementMatrix* Tria::CreateKMatrixBalancevelocity(void){
-
-	/*Intermediaries */
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble dhdt_g,mb_g,ms_g,Jdet;
-	IssmDouble h,gamma,thickness;
-	IssmDouble hnx,hny,dhnx[2],dhny[2];
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Initialize Element matrix and vectors*/
-	ElementMatrix* Ke     = new ElementMatrix(nodes,numnodes,this->parameters,NoneApproximationEnum);
-	IssmDouble*    B      = xNew<IssmDouble>(2*numnodes);
-	IssmDouble*    basis  = xNew<IssmDouble>(numnodes);
-	IssmDouble*    dbasis = xNew<IssmDouble>(2*numnodes);
-	IssmDouble*    HNx    = xNew<IssmDouble>(numnodes);
-	IssmDouble*    HNy    = xNew<IssmDouble>(numnodes);
-	IssmDouble*    H      = xNew<IssmDouble>(numnodes);
-	IssmDouble*    Nx     = xNew<IssmDouble>(numnodes);
-	IssmDouble*    Ny     = xNew<IssmDouble>(numnodes);
-
-	/*Retrieve all Inputs and parameters: */
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	Input* H_input =inputs->GetInput(ThicknessEnum); _assert_(H_input);
-	h=sqrt(2.*this->GetArea());
-
-	/*Get vector N for all nodes and build HNx and HNy*/
-	GetInputListOnNodes(Nx,SurfaceSlopeXEnum);
-	GetInputListOnNodes(Ny,SurfaceSlopeYEnum);
-	GetInputListOnNodes(H,ThicknessEnum);
-	for(int i=0;i<numnodes;i++){
-		IssmDouble norm=sqrt(Nx[i]*Nx[i]+Ny[i]*Ny[i]+1.e-10);
-		HNx[i] = -H[i]*Nx[i]/norm;
-		HNy[i] = -H[i]*Ny[i]/norm;
-	}
-
-	/*Start looping on the number of gaussian points:*/
-	GaussTria* gauss=new GaussTria(2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		H_input->GetInputValue(&thickness,gauss);
-		if(thickness<50.) thickness=50.;
-		TriaRef::GetInputDerivativeValue(&dhnx[0],HNx,&xyz_list[0][0],gauss);
-		TriaRef::GetInputDerivativeValue(&dhny[0],HNy,&xyz_list[0][0],gauss);
-		TriaRef::GetInputValue(&hnx,HNx,gauss);
-		TriaRef::GetInputValue(&hny,HNy,gauss);
-
-		gamma=h/(2.*thickness+1.e-10);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		GetNodalFunctions(basis,gauss);
-		GetNodalFunctionsDerivatives(dbasis,&xyz_list[0][0],gauss);
-
-		for(int i=0;i<numnodes;i++){
-			for(int j=0;j<numnodes;j++){
-				Ke->values[i*numnodes+j] += gauss->weight*Jdet*(
-							(basis[i]+gamma*(basis[i]*(dhnx[0]+dhny[1]) + dbasis[0*numnodes+i]*hnx + dbasis[1*numnodes+i]*hny))*
-							(basis[j]*(dhnx[0]+dhny[1])  + dbasis[0*numnodes+j]*hnx + dbasis[1*numnodes+j]*hny)
-							);
-			}
-		}
-	}
-
-	/*Clean up and return*/
-	xDelete<IssmDouble>(basis);
-	xDelete<IssmDouble>(dbasis);
-	xDelete<IssmDouble>(H);
-	xDelete<IssmDouble>(Nx);
-	xDelete<IssmDouble>(Ny);
-	xDelete<IssmDouble>(HNx);
-	xDelete<IssmDouble>(HNy);
-	xDelete<IssmDouble>(B);
-	delete gauss;
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Tria::CreateKMatrixSmoothedSlope {{{*/
-ElementMatrix* Tria::CreateKMatrixSmoothedSlope(void){
-
-	/* Intermediaries */
-	IssmDouble D_scalar,Jdet,thickness;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble l=8.;
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Initialize Element matrix and vectors*/
-	ElementMatrix* Ke     = new ElementMatrix(nodes,numnodes,this->parameters);
-	IssmDouble*    dbasis = xNew<IssmDouble>(2*numnodes);
-	IssmDouble*    basis  = xNew<IssmDouble>(numnodes);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	Input* thickness_input=inputs->GetInput(ThicknessEnum); _assert_(thickness_input);
-
-	/* Start looping on the number of gaussian points: */
-	GaussTria* gauss=new GaussTria(2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		thickness_input->GetInputValue(&thickness,gauss);
-		if(thickness<50.) thickness=50.;
-
-		GetNodalFunctions(basis,gauss);
-		GetNodalFunctionsDerivatives(dbasis,&xyz_list[0][0],gauss);
-
-		for(int i=0;i<numnodes;i++){
-			for(int j=0;j<numnodes;j++){
-				Ke->values[i*numnodes+j] += gauss->weight*Jdet*(
-							basis[i]*basis[j]
-							+(l*thickness)*(l*thickness)*(dbasis[0*numnodes+i]*dbasis[0*numnodes+j] + dbasis[1*numnodes+i]*dbasis[1*numnodes+j])
-							);
-			}
-		}
-	}
-
-	/*Clean up and return*/
-	delete gauss;
-	xDelete<IssmDouble>(dbasis);
-	xDelete<IssmDouble>(basis);
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Tria::CreatePVectorBalancethickness{{{*/
-ElementVector* Tria::CreatePVectorBalancethickness(void){
-
-	switch(GetElementType()){
-		case P1Enum:
-			return CreatePVectorBalancethickness_CG();
-			break;
-		case P1DGEnum:
-			return CreatePVectorBalancethickness_DG();
-		default:
-			_error_("Element type " << EnumToStringx(GetElementType()) << " not supported yet");
-	}
-}
-/*}}}*/
-/*FUNCTION Tria::CreatePVectorBalancethickness_CG{{{*/
-ElementVector* Tria::CreatePVectorBalancethickness_CG(void){
-
-	/*Intermediaries */
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble dhdt_g,mb_g,ms_g,Jdet;
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Initialize Element vector and other vectors*/
-	ElementVector* pe    = new ElementVector(nodes,numnodes,this->parameters);
-	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	Input* ms_input=inputs->GetInput(SurfaceforcingsMassBalanceEnum); _assert_(ms_input);
-	Input* mb_input=inputs->GetInput(BasalforcingsMeltingRateEnum);   _assert_(mb_input);
-	Input* dhdt_input=inputs->GetInput(BalancethicknessThickeningRateEnum); _assert_(dhdt_input);
-
-	/* Start  looping on the number of gaussian points: */
-	GaussTria* gauss=new GaussTria(2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		ms_input->GetInputValue(&ms_g,gauss);
-		mb_input->GetInputValue(&mb_g,gauss);
-		dhdt_input->GetInputValue(&dhdt_g,gauss);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		GetNodalFunctions(basis,gauss);
-
-		for(int i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*(ms_g-mb_g-dhdt_g)*basis[i];
-	}
-
-	/*Clean up and return*/
-	xDelete<IssmDouble>(basis);
-	delete gauss;
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Tria::CreatePVectorBalancethickness_DG {{{*/
-ElementVector* Tria::CreatePVectorBalancethickness_DG(void){
-
-	/*Intermediaries */
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble mb_g,ms_g,dhdt_g,Jdet;
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Initialize Element vector and other vectors*/
-	ElementVector* pe    = new ElementVector(nodes,numnodes,this->parameters);
-	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	Input* ms_input=inputs->GetInput(SurfaceforcingsMassBalanceEnum); _assert_(ms_input);
-	Input* mb_input=inputs->GetInput(BasalforcingsMeltingRateEnum);   _assert_(mb_input);
-	Input* dhdt_input=inputs->GetInput(BalancethicknessThickeningRateEnum);_assert_(dhdt_input);
-
-	/* Start  looping on the number of gaussian points: */
-	GaussTria* gauss=new GaussTria(2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		ms_input->GetInputValue(&ms_g,gauss);
-		mb_input->GetInputValue(&mb_g,gauss);
-		dhdt_input->GetInputValue(&dhdt_g,gauss);
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		GetNodalFunctions(basis,gauss);
-
-		for(int i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*(ms_g-mb_g-dhdt_g)*basis[i];
-	}
-
-	/*Clean up and return*/
-	xDelete<IssmDouble>(basis);
-	delete gauss;
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Tria::CreatePVectorBalancevelocity{{{*/
-ElementVector* Tria::CreatePVectorBalancevelocity(void){
-
-	/*Intermediaries */
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble dhdt_g,mb_g,ms_g,Jdet;
-	IssmDouble h,gamma,thickness;
-	IssmDouble hnx,hny,dhnx[2],dhny[2];
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Initialize Element vector and other vectors*/
-	ElementVector* pe    = new ElementVector(nodes,numnodes,this->parameters);
-	IssmDouble*    basis  = xNew<IssmDouble>(numnodes);
-	IssmDouble*    dbasis = xNew<IssmDouble>(numnodes*2);
-	IssmDouble*    HNx    = xNew<IssmDouble>(numnodes);
-	IssmDouble*    HNy    = xNew<IssmDouble>(numnodes);
-	IssmDouble*    H      = xNew<IssmDouble>(numnodes);
-	IssmDouble*    Nx     = xNew<IssmDouble>(numnodes);
-	IssmDouble*    Ny     = xNew<IssmDouble>(numnodes);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	Input* ms_input=inputs->GetInput(SurfaceforcingsMassBalanceEnum); _assert_(ms_input);
-	Input* mb_input=inputs->GetInput(BasalforcingsMeltingRateEnum);   _assert_(mb_input);
-	Input* dhdt_input=inputs->GetInput(BalancethicknessThickeningRateEnum); _assert_(dhdt_input);
-	Input* H_input=inputs->GetInput(ThicknessEnum); _assert_(H_input);
-	h=sqrt(2.*this->GetArea());
-
-	/*Get vector N for all nodes*/
-	GetInputListOnNodes(Nx,SurfaceSlopeXEnum);
-	GetInputListOnNodes(Ny,SurfaceSlopeYEnum);
-	GetInputListOnNodes(H,ThicknessEnum);
-	for(int i=0;i<numnodes;i++){
-		IssmDouble norm=sqrt(Nx[i]*Nx[i]+Ny[i]*Ny[i]+1.e-10);
-		Nx[i] = -H[i]*Nx[i]/norm;
-		Ny[i] = -H[i]*Ny[i]/norm;
-	}
-
-	/* Start  looping on the number of gaussian points: */
-	GaussTria* gauss=new GaussTria(2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		ms_input->GetInputValue(&ms_g,gauss);
-		mb_input->GetInputValue(&mb_g,gauss);
-		dhdt_input->GetInputValue(&dhdt_g,gauss);
-		H_input->GetInputValue(&thickness,gauss);
-		if(thickness<50.) thickness=50.;
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		GetNodalFunctions(basis,gauss);
-		GetNodalFunctionsDerivatives(dbasis,&xyz_list[0][0],gauss);
-
-		TriaRef::GetInputDerivativeValue(&dhnx[0],HNx,&xyz_list[0][0],gauss);
-		TriaRef::GetInputDerivativeValue(&dhny[0],HNy,&xyz_list[0][0],gauss);
-		TriaRef::GetInputValue(&hnx,HNx,gauss);
-		TriaRef::GetInputValue(&hny,HNy,gauss);
-
-		gamma=h/(2.*thickness+1.e-10);
-
-		for(int i=0;i<numnodes;i++){
-			pe->values[i]+=Jdet*gauss->weight*(ms_g-mb_g-dhdt_g)*(
-						basis[i] + gamma*(basis[i]*(dhnx[0]+dhny[1])+hnx*dbasis[0*numnodes+i] + hny*dbasis[1*numnodes+i])
-						);
-		}
-	}
-
-	/*Clean up and return*/
-	xDelete<IssmDouble>(basis);
-	xDelete<IssmDouble>(dbasis);
-	xDelete<IssmDouble>(H);
-	xDelete<IssmDouble>(Nx);
-	xDelete<IssmDouble>(Ny);
-	xDelete<IssmDouble>(HNx);
-	xDelete<IssmDouble>(HNy);
-	delete gauss;
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Tria::CreatePVectorSmoothedSlopeX{{{*/
-ElementVector* Tria::CreatePVectorSmoothedSlopeX(void){
-
-	/*Intermediaries */
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble Jdet;
-	IssmDouble thickness,slope[2];
-	IssmDouble taud_x,norms,normv,vx,vy;
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Initialize Element vector and other vectors*/
-	ElementVector* pe    = new ElementVector(nodes,numnodes,this->parameters);
-	IssmDouble*    basis  = xNew<IssmDouble>(numnodes);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	Input* H_input       = inputs->GetInput(ThicknessEnum); _assert_(H_input);
-	Input* surface_input = inputs->GetInput(SurfaceEnum);   _assert_(surface_input);
-	Input* vx_input      = inputs->GetInput(VxEnum);
-	Input* vy_input      = inputs->GetInput(VyEnum);
-
-	/* Start  looping on the number of gaussian points: */
-	GaussTria* gauss=new GaussTria(2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		H_input->GetInputValue(&thickness,gauss);
-		surface_input->GetInputDerivativeValue(&slope[0],&xyz_list[0][0],gauss);
-		if(vx_input && vy_input){
-			vx_input->GetInputValue(&vx,gauss);
-			vy_input->GetInputValue(&vy,gauss);
-			norms = sqrt(slope[0]*slope[0]+slope[1]*slope[1]+1.e-10);
-			normv = sqrt(vx*vx + vy*vy);
-			if(normv>15./(365.*24.*3600.)) slope[0] = -vx/normv*norms;
-		}
-		taud_x = matpar->GetRhoIce()*matpar->GetG()*thickness*slope[0];
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		GetNodalFunctions(basis,gauss);
-
-		for(int i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*taud_x*basis[i];
-	}
-
-	/*Clean up and return*/
-	xDelete<IssmDouble>(basis);
-	delete gauss;
-	return pe;
-}
-/*}}}*/
-/*FUNCTION Tria::CreatePVectorSmoothedSlopeY{{{*/
-ElementVector* Tria::CreatePVectorSmoothedSlopeY(void){
-
-	/*Intermediaries */
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble Jdet;
-	IssmDouble thickness,slope[2];
-	IssmDouble taud_y,norms,normv,vx,vy;
-
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Initialize Element vector and other vectors*/
-	ElementVector* pe    = new ElementVector(nodes,numnodes,this->parameters);
-	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
-
-	/*Retrieve all inputs and parameters*/
-	GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	Input* H_input       = inputs->GetInput(ThicknessEnum); _assert_(H_input);
-	Input* surface_input = inputs->GetInput(SurfaceEnum);   _assert_(surface_input);
-	Input* vx_input      = inputs->GetInput(VxEnum);
-	Input* vy_input      = inputs->GetInput(VyEnum);
-
-	/* Start  looping on the number of gaussian points: */
-	GaussTria* gauss=new GaussTria(2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		H_input->GetInputValue(&thickness,gauss);
-		surface_input->GetInputDerivativeValue(&slope[0],&xyz_list[0][0],gauss);
-		if(vx_input && vy_input){
-			vx_input->GetInputValue(&vx,gauss);
-			vy_input->GetInputValue(&vy,gauss);
-			norms = sqrt(slope[0]*slope[0]+slope[1]*slope[1]+1.e-10);
-			normv = sqrt(vx*vx + vy*vy);
-			if(normv>15./(365.*24.*3600.)) slope[1] = -vy/normv*norms;
-		}
-		taud_y = matpar->GetRhoIce()*matpar->GetG()*thickness*slope[1];
-
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-		GetNodalFunctions(basis,gauss);
-
-		for(int i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*taud_y*basis[i];
-	}
-
-	/*Clean up and return*/
-	xDelete<IssmDouble>(basis);
-	delete gauss;
-	return pe;
-}
-/*}}}*/
-#endif
-
-#ifdef _HAVE_GROUNDINGLINE_
 /*FUNCTION Tria::MigrateGroundingLine{{{*/
 void  Tria::MigrateGroundingLine(IssmDouble* phi_ungrounding){
@@ -9085,6 +4417,6 @@
 	GetInputListOnVertices(&h[0],ThicknessEnum);
 	GetInputListOnVertices(&s[0],SurfaceEnum);
-	GetInputListOnVertices(&b[0],BedEnum);
-	GetInputListOnVertices(&r[0],BathymetryEnum);
+	GetInputListOnVertices(&b[0],BaseEnum);
+	GetInputListOnVertices(&r[0],BedEnum);
 	GetInputListOnVertices(&phi[0],MaskGroundediceLevelsetEnum);
 	rho_water   = matpar->GetRhoWater();
@@ -9092,4 +4424,35 @@
 	density     = rho_ice/rho_water;
 	oldfloating = this->IsFloating(); //figure out if element is floating before we start to change everything
+
+	if(migration_style == ContactEnum){
+		for(i = 0;i < NUMVERTICES;i++) phi[i] = phi_ungrounding[vertices[i]->Pid()];
+		this->inputs->AddInput(new TriaInput(MaskGroundediceLevelsetEnum,&phi[0],P1Enum));
+
+		/*go through vertices, and update inputs, considering them to be TriaVertex type: */
+		for(i = 0;i < NUMVERTICES;i++){
+			/*Ice shelf: if bed below bathymetry, impose it at the bathymetry and update surface, elso do nothing */
+			if(phi[i] >= 0.){
+					b[i]  = r[i];
+			}
+		}
+
+		/*Add basal melting rate if element just ungrounded*/
+		for(i=0;i<NUMVERTICES;i++){
+			if(phi[i]<0.){
+				floatingelement=true;
+				break;
+			}
+		}
+		if(!oldfloating && floatingelement==true){
+			for(i=0;i<NUMVERTICES;i++) melting[i]=gl_melting_rate/yts;
+			this->inputs->AddInput(new TriaInput(BasalforcingsMeltingRateEnum,&melting[0],P1Enum));
+		} 
+
+		/*Update inputs*/
+		this->inputs->AddInput(new TriaInput(BaseEnum,&b[0],P1Enum));
+		return;
+	}
+
+	this->inputs->AddInput(new TriaInput(MaskGroundediceLevelsetEnum,&phi[0],P1Enum));
 
 	/*go through vertices, and update inputs, considering them to be TriaVertex type: */
@@ -9155,5 +4518,5 @@
 	}
 
-   /*Add basal melting rate if element just ungrounded*/
+	/*Add basal melting rate if element just ungrounded*/
 	if(!oldfloating && floatingelement==true){
 		for(i=0;i<NUMVERTICES;i++)melting[i]=gl_melting_rate/yts;
@@ -9163,5 +4526,5 @@
 	/*Update inputs*/
 	this->inputs->AddInput(new TriaInput(SurfaceEnum,&s[0],P1Enum));
-	this->inputs->AddInput(new TriaInput(BedEnum,&b[0],P1Enum));
+	this->inputs->AddInput(new TriaInput(BaseEnum,&b[0],P1Enum));
 
 }
@@ -9179,5 +4542,5 @@
 	density=rho_ice/rho_water;
 	GetInputListOnVertices(&h[0],ThicknessEnum);
-	GetInputListOnVertices(&r[0],BathymetryEnum);
+	GetInputListOnVertices(&r[0],BedEnum);
 	GetInputListOnVertices(&gl[0],MaskGroundediceLevelsetEnum);
 
@@ -9215,3 +4578,2 @@
 }
 /*}}}*/
-#endif
Index: /issm/trunk/src/c/classes/Elements/Tria.h
===================================================================
--- /issm/trunk/src/c/classes/Elements/Tria.h	(revision 17805)
+++ /issm/trunk/src/c/classes/Elements/Tria.h	(revision 17806)
@@ -22,4 +22,5 @@
 class ElementVector;
 class Vertex;
+class GaussTria;
 
 #include "../../shared/Exceptions/exceptions.h"
@@ -31,29 +32,14 @@
 	public:
 
-		int          id;
-		int          sid;
-
-		Node       **nodes;                       // nodes
-		Vertex     **vertices;                    // 3 vertices
-		Material    *material;                    // 1 material ice
-		Matpar      *matpar;                      // 1 material parameter
-
-		Parameters  *parameters;                  //pointer to solution parameters
-		Inputs      *inputs;
-
 		/*Tria constructors, destructors {{{*/
-		Tria();
+		Tria(){};
 		Tria(int tria_id,int tria_sid,int i, IoModel* iomodel,int nummodels);
 		~Tria();
 		/*}}}*/
 		/*Object virtual functions definitions:{{{ */
-		void    Echo();
-		void    DeepEcho();
-		int     Id();
 		int     ObjectEnum();
 		Object *copy();
 		/*}}}*/
 		/*Update virtual functions resolution: {{{*/
-		void  InputUpdateFromSolution(IssmDouble* solutiong);
 		void  InputUpdateFromVector(IssmDouble* vector, int name, int type);
 		#ifdef _HAVE_DAKOTA_
@@ -61,40 +47,44 @@
 		void  InputUpdateFromMatrixDakota(IssmDouble* matrix, int nows, int ncols, int name, int type);
 		#endif
-		void  InputUpdateFromConstant(IssmDouble constant, int name);
-		void  InputUpdateFromConstant(int constant, int name);
-		void  InputUpdateFromConstant(bool constant, int name);
 		void  InputUpdateFromIoModel(int index, IoModel* iomodel);
 		/*}}}*/
 		/*Element virtual functions definitions: {{{*/
+		IssmDouble  CharacteristicLength(void);
 		void        ComputeBasalStress(Vector<IssmDouble>* sigma_b);
+		void        ComputeSigmaNN();
 		void        ComputeStrainRate(Vector<IssmDouble>* eps);
 		void        ComputeStressTensor();
+		void        ComputeDeviatoricStressTensor();
+		void        ComputeSurfaceNormalVelocity();
 		void        Configure(Elements* elements,Loads* loads,Nodes* nodesin,Vertices* verticesin,Materials* materials,Parameters* parameters);
 		void        SetCurrentConfiguration(Elements* elements,Loads* loads,Nodes* nodes,Materials* materials,Parameters* parameters);
-		void        SetwiseNodeConnectivity(int* d_nz,int* o_nz,Node* node,bool* flags,int* flagsindices,int set1_enum,int set2_enum);
-		void        CreateKMatrix(Matrix<IssmDouble>* Kff, Matrix<IssmDouble>* Kfs);
-		void        CreateDVector(Vector<IssmDouble>* df);
-		void        CreatePVector(Vector<IssmDouble>* pf);
-		void        CreateJacobianMatrix(Matrix<IssmDouble>* Jff);
 		void        Delta18oParameterization(void);
+		void        ElementSizes(IssmDouble* hx,IssmDouble* hy,IssmDouble* hz);
+		void        FSContactMigration(Vector<IssmDouble>* vertexgrounded,Vector<IssmDouble>* vertexfloating);
+		int         FiniteElement(void);
+		Element*    GetUpperElement(void){_error_("not implemented yet");};
+	  	Element*    GetLowerElement(void){_error_("not implemented yet");};
+	  	Element*    GetSurfaceElement(void){_error_("not implemented yet");};
+		Element*    GetBasalElement(void){_error_("not implemented yet");};
+		void        GetGroundedPart(int* point1,IssmDouble* fraction1, IssmDouble* fraction2,bool* mainlyfloating);
+		IssmDouble  GetGroundedPortion(IssmDouble* xyz_list);
 		int         GetNodeIndex(Node* node);
-		void        GetNodesSidList(int* sidlist);
-		void        GetNodesLidList(int* lidlist);
 		int         GetNumberOfNodes(void);
-		int         Sid();
-		bool        IsOnBed();
-		bool        HasEdgeOnBed();
+		int         GetNumberOfVertices(void);
+		bool        IsOnBase();
+		bool        IsOnSurface();
+		bool        HasEdgeOnBase();
 		bool        HasEdgeOnSurface();
 		void        EdgeOnSurfaceIndices(int* pindex1,int* pindex);
-		void        EdgeOnBedIndices(int* pindex1,int* pindex);
-		int         EdgeOnBedIndex();
+		void        EdgeOnBaseIndices(int* pindex1,int* pindex);
+		int         EdgeOnBaseIndex();
 		int         EdgeOnSurfaceIndex();
-		bool        IsFloating();
 		bool        IsNodeOnShelfFromFlags(IssmDouble* flags);
-		bool        NoIceInElement();
-		void        GetSolutionFromInputs(Vector<IssmDouble>* solution);
-		void        GetVectorFromInputs(Vector<IssmDouble>* vector, int name_enum);
-		void        InputCreate(IssmDouble* vector,IoModel* iomodel,int M,int N,int vector_type,int vector_enum,int code);
-		void        InputDepthAverageAtBase(int enum_type,int average_enum_type,int object_enum=MeshElementsEnum);
+		int         NumberofNodesVelocity(void);
+		int         NumberofNodesPressure(void);
+		void        GetSolutionFromInputsOneDof(Vector<IssmDouble>* solution,int enum_type);
+		void        GetVerticesCoordinatesBase(IssmDouble** pxyz_list);
+		void        GetVerticesCoordinatesTop(IssmDouble** pxyz_list);
+		void        InputDepthAverageAtBase(int enum_type,int average_enum_type);
 		void        InputDuplicate(int original_enum,int new_enum);
 		void        InputScale(int enum_type,IssmDouble scale_factor);
@@ -102,13 +92,24 @@
 		int         NodalValue(IssmDouble* pvalue, int index, int natureofdataenum);
 		void        PositiveDegreeDay(IssmDouble* pdds,IssmDouble* pds,IssmDouble signorm);
-		void        ResultInterpolation(int* pinterpolation,int output_enum);
-		void        ResultToVector(Vector<IssmPDouble>* vector,int output_enum);
-		void        ResetCoordinateSystem(void);
+		void        ReduceMatrices(ElementMatrix* Ke,ElementVector* pe);
+		void        ResetFSBasalBoundaryCondition(void);
 		void	      SmbGradients();
+	   Element*    SpawnBasalElement(void);
+		Element*    SpawnTopElement(void);
+		int         VelocityInterpolation();
+		int         PressureInterpolation();
 		IssmDouble  SurfaceArea(void);
 		void        Update(int index, IoModel* iomodel,int analysis_counter,int analysis_type,int finitelement);
 		IssmDouble  TimeAdapt();
-
-		#ifdef _HAVE_RESPONSES_
+		void   ValueP1OnGauss(IssmDouble* pvalue,IssmDouble* values,Gauss* gauss);
+		void   ValueP1DerivativesOnGauss(IssmDouble* dvalue,IssmDouble* values,IssmDouble* xyz_list,Gauss* gauss);
+		int         VertexConnectivity(int vertexindex);
+		void   VerticalSegmentIndices(int** pindices,int* pnumseg){_error_("not implemented yet");};
+		void        ZeroLevelsetCoordinates(IssmDouble** pxyz_zero,IssmDouble* xyz_list,int levelsetenum);
+		void	    GetIcefrontCoordinates(IssmDouble** pxyz_front,IssmDouble* xyz_list,int levelsetenum);
+	    void        GetNormalFromLSF(IssmDouble *pnormal);
+		bool        IsZeroLevelset(int levelset_enum);
+		bool		IsIcefront(void);
+
 		void       AverageOntoPartition(Vector<IssmDouble>* partition_contributions,Vector<IssmDouble>* partition_areas,IssmDouble* vertex_response,IssmDouble* qmu_part);
 		IssmDouble IceVolume(void);
@@ -129,5 +130,6 @@
 		void       MaxVy(IssmDouble* pmaxvy);
 		void       MaxVz(IssmDouble* pmaxvz);
-		#endif
+		IssmDouble Misfit(int modelenum,int observationenum,int weightsenum);
+		IssmDouble MisfitArea(int weightsenum);
 
 		#ifdef _HAVE_GIA_
@@ -135,5 +137,4 @@
 		#endif
 
-		#ifdef _HAVE_CONTROL_
 		IssmDouble DragCoefficientAbsGradient(void);
 		void       GradientIndexing(int* indexing,int control_index);
@@ -168,153 +169,60 @@
 		IssmDouble SurfaceAverageVelMisfit(void);
 		void       InputControlUpdate(IssmDouble scalar,bool save_parameter);
-		#endif
-
-		#ifdef _HAVE_GROUNDINGLINE_
+
 		void   PotentialUngrounding(Vector<IssmDouble>* potential_sheet_ungrounding);
 		void   MigrateGroundingLine(IssmDouble* sheet_ungrounding);
 		int    UpdatePotentialUngrounding(IssmDouble* vertices_potentially_ungrounding,Vector<IssmDouble>* vec_nodes_on_iceshelf,IssmDouble* nodes_on_iceshelf);
-		#endif
 
 		/*}}}*/
 		/*Tria specific routines:{{{*/
-		ElementMatrix* CreateKMatrix(void);
-		ElementMatrix* CreateKMatrixBalancethickness(void);
-		ElementMatrix* CreateKMatrixBalancethickness_DG(void);
-		ElementMatrix* CreateKMatrixBalancethickness_CG(void);
-		ElementMatrix* CreateKMatrixBalancevelocity(void);
-		ElementMatrix* CreateKMatrixSmoothedSlope(void);
-		ElementMatrix* CreateKMatrixMelting(void);
-		ElementMatrix* CreateKMatrixMasstransport(void);
-		ElementMatrix* CreateKMatrixMasstransport_CG(void);
-		ElementMatrix* CreateKMatrixMasstransport_DG(void);
-		ElementMatrix* CreateKMatrixExtrusion(void);
-		ElementMatrix* CreateKMatrixExtrusionVolume(void);
-		ElementMatrix* CreateKMatrixExtrusionSurface(void);
-		ElementMatrix* CreateKMatrixExtrusionBed(void);
-		ElementMatrix* CreateKMatrixFreeSurfaceTop(void);
-		ElementMatrix* CreateKMatrixFreeSurfaceTop1D(void);
-		ElementMatrix* CreateKMatrixFreeSurfaceBase(void);
-		ElementMatrix* CreateKMatrixFreeSurfaceBase1D(void);
-		ElementMatrix* CreateMassMatrix(void);
-		ElementMatrix* CreateBasalMassMatrix(void);
-		ElementVector* CreatePVector(void);
-		ElementVector* CreatePVectorBalancethickness(void);
-		ElementVector* CreatePVectorBalancethickness_DG(void);
-		ElementVector* CreatePVectorBalancethickness_CG(void);
-		ElementVector* CreatePVectorBalancevelocity(void);
-		ElementVector* CreatePVectorSmoothedSlopeX(void);
-		ElementVector* CreatePVectorSmoothedSlopeY(void);
-		ElementVector* CreatePVectorMasstransport(void);
-		ElementVector* CreatePVectorMasstransport_CG(void);
-		ElementVector* CreatePVectorMasstransport_DG(void);
-		ElementVector* CreatePVectorFreeSurfaceTop(void);
-		ElementVector* CreatePVectorFreeSurfaceTop1D(void);
-		ElementVector* CreatePVectorFreeSurfaceBase(void);
-		ElementVector* CreatePVectorFreeSurfaceBase1D(void);
-		ElementVector* CreatePVectorL2Projection(void);
-		ElementVector* CreatePVectorL2ProjectionBase(void);
+		void           AddBasalInput(int input_enum, IssmDouble* values, int interpolation_enum);
+		void           AddInput(int input_enum, IssmDouble* values, int interpolation_enum);
 		IssmDouble     GetArea(void);
-		void           GetAreaCoordinates(IssmDouble *area_coordinates,IssmDouble xyz_zero[3][3],IssmDouble xyz_list[3][3],int numpoints);
+		void           GetAreaCoordinates(IssmDouble *area_coordinates,IssmDouble* xyz_zero,IssmDouble* xyz_list,int numpoints);
 		int            GetElementType(void);
-		void	         GetDofList(int** pdoflist,int approximation_enum,int setenum);
-		void	         GetDofListVelocity(int** pdoflist,int setenum);
-		void	         GetDofListPressure(int** pdoflist,int setenum);
-		void	         GetVertexPidList(int* doflist);
-		void           GetVertexSidList(int* sidlist);
-		void           GetConnectivityList(int* connectivity);
-		void           GetGroundedPart(int* point1,IssmDouble* fraction1, IssmDouble* fraction2,bool* mainlyfloating);
-		IssmDouble     GetGroundedPortion(IssmDouble* xyz_list);
-		void           GetSegmentNormal(IssmDouble* normal,IssmDouble xyz_list[2][3]);
-		void           GetZeroLevelsetCoordinates(IssmDouble* xyz_zero,IssmDouble xyz_list[3][3],int levelsetenum);
-		void           GetInputListOnVertices(IssmDouble* pvalue,int enumtype);
-		void           GetInputListOnVertices(IssmDouble* pvalue,int enumtype,IssmDouble defaultvalue);
-		void           GetInputListOnVertices(IssmDouble* pvalue,int enumtype,IssmDouble defaultvalue,int index); //TO BE REMOVED
-		void           GetInputListOnNodes(IssmDouble* pvalue,int enumtype);
-		void           GetInputListOnNodes(IssmDouble* pvalue,int enumtype,IssmDouble defaultvalue);
+		IssmDouble     GetXcoord(Gauss* gauss);
+		IssmDouble     GetYcoord(Gauss* gauss);
+		IssmDouble     GetZcoord(Gauss* gauss){_error_("not implemented");};
+		void           NormalSection(IssmDouble* normal,IssmDouble* xyz_list);
+		void           NormalTop(IssmDouble* normal,IssmDouble* xyz_list);
+		void           NormalBase(IssmDouble* normal,IssmDouble* xyz_list);
 		void           GetInputValue(IssmDouble* pvalue,Node* node,int enumtype);
 		void           GetMaterialInputValue(IssmDouble* pvalue,Node* node,int enumtype);
-		void           GetStrainRate2d(IssmDouble* epsilon,IssmDouble* xyz_list, GaussTria* gauss, Input* vx_input, Input* vy_input);
+		Node*          GetNode(int node_number);
 		void	         InputUpdateFromSolutionOneDof(IssmDouble* solution,int enum_type);
-		void	         InputUpdateFromSolutionMasstransport(IssmDouble* solution);
-		bool	         IsInput(int name);
+		void	         InputUpdateFromSolutionOneDofCollapsed(IssmDouble* solution,int enum_type){_error_("not implemented yet");};
+		void           JacobianDeterminant(IssmDouble*  pJdet, IssmDouble* xyz_list,Gauss* gauss);
+		void           JacobianDeterminantLine(IssmDouble* Jdet, IssmDouble* xyz_list,Gauss* gauss){_error_("not implemented yet");};
+		void           JacobianDeterminantSurface(IssmDouble*  pJdet, IssmDouble* xyz_list,Gauss* gauss);
+		void           JacobianDeterminantBase(IssmDouble* pJdet,IssmDouble* xyz_list_base,Gauss* gauss);
+		void           JacobianDeterminantTop(IssmDouble* pJdet,IssmDouble* xyz_list_base,Gauss* gauss);
+		IssmDouble     MinEdgeLength(IssmDouble* xyz_list){_error_("not implemented yet");};
+		Gauss*         NewGauss(void);
+		Gauss*         NewGauss(int order);
+      Gauss*         NewGauss(IssmDouble* xyz_list, IssmDouble* xyz_list_front,int order);
+      Gauss*         NewGauss(int point1,IssmDouble fraction1,IssmDouble fraction2,bool mainlyfloating,int order);
+      Gauss*         NewGauss(IssmDouble* xyz_list, IssmDouble* xyz_list_front,int order_horiz,int order_vert);
+		Gauss*         NewGaussBase(int order);
+		Gauss*         NewGaussLine(int vertex1,int vertex2,int order){_error_("not implemented yet");};
+		Gauss*         NewGaussTop(int order);
+		void           NodalFunctions(IssmDouble* basis,Gauss* gauss);
+		void           NodalFunctionsP1(IssmDouble* basis,Gauss* gauss){_error_("not implemented yet");};
+		void           NodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss);
+		void           NodalFunctionsP1Derivatives(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss){_error_("not implemented yet");};
+		void           NodalFunctionsMINIDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss){_error_("not implemented yet");};
+		void           NodalFunctionsDerivativesVelocity(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss);
+		void           NodalFunctionsVelocity(IssmDouble* basis,Gauss* gauss);
+		void           NodalFunctionsPressure(IssmDouble* basis,Gauss* gauss);
+		void           NodalFunctionsTensor(IssmDouble* basis,Gauss* gauss);
 		void	         SetClone(int* minranks);
+		void           SetTemporaryElementType(int element_type_in){_error_("not implemented yet");};
 		Seg*	         SpawnSeg(int index1,int index2);
-		void	         SurfaceNormal(IssmDouble* surface_normal, IssmDouble xyz_list[3][3]);
-
-		#ifdef _HAVE_STRESSBALANCE_
-		ElementMatrix* CreateKMatrixStressbalanceSSA(void);
-		ElementMatrix* CreateKMatrixStressbalanceSSAViscous(void);
-		ElementMatrix* CreateKMatrixStressbalanceSSAFriction(void);
-		ElementMatrix* CreateKMatrixStressbalanceSIA(void);
-		ElementMatrix* CreateKMatrixStressbalanceFS(void);
-		ElementMatrix* CreateKMatrixStressbalanceFSViscous(void);
-		ElementMatrix* CreateKMatrixStressbalanceFSFriction(void);
-		ElementVector* CreatePVectorStressbalanceSSA(void);
-		ElementVector* CreatePVectorStressbalanceSSADrivingStress(void);
-		ElementVector* CreatePVectorStressbalanceSSAFront(void);
-		ElementVector* CreatePVectorStressbalanceSIA(void);
-		ElementVector* CreatePVectorStressbalanceFS(void);
-		ElementVector* CreatePVectorStressbalanceFSFront(void);
-		ElementVector* CreatePVectorStressbalanceFSViscous(void);
-		void           PVectorGLSstabilization(ElementVector* pe);
-		ElementVector* CreatePVectorStressbalanceFSShelf(void);
-		ElementMatrix* CreateJacobianStressbalanceSSA(void);
-		void	         GetSolutionFromInputsStressbalanceFS(Vector<IssmDouble>* solution);
-		void	         GetSolutionFromInputsStressbalanceHoriz(Vector<IssmDouble>* solution);
-		void	         GetSolutionFromInputsStressbalanceSIA(Vector<IssmDouble>* solution);
-		IssmDouble     GetYcoord(GaussTria* gauss);
-		void	         InputUpdateFromSolutionStressbalanceHoriz( IssmDouble* solution);
-		void	         InputUpdateFromSolutionStressbalanceFS( IssmDouble* solution);
-		void	         InputUpdateFromSolutionStressbalanceSIA( IssmDouble* solution);
-		#endif
-
-		#ifdef _HAVE_CONTROL_
-		ElementMatrix* CreateKMatrixAdjointBalancethickness(void);
-		ElementMatrix* CreateKMatrixAdjointSSA(void);
-		ElementVector* CreatePVectorAdjointHoriz(void);
-		ElementVector* CreatePVectorAdjointBalancethickness(void);
-		void	         InputUpdateFromSolutionAdjointHoriz( IssmDouble* solution);
-		#endif
+		IssmDouble     StabilizationParameter(IssmDouble u, IssmDouble v, IssmDouble w, IssmDouble diameter, IssmDouble kappa){_error_("not implemented yet");};
+		void           ViscousHeating(IssmDouble* pphi,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input){_error_("not implemented yet");};
 
 		void UpdateConstraintsExtrudeFromBase(void);
 		void UpdateConstraintsExtrudeFromTop(void);
-		#ifdef _HAVE_THERMAL_
-		void UpdateBasalConstraintsEnthalpy(void){_error_("not implemented yet");};
-		void ComputeBasalMeltingrate(void){_error_("not implemented yet");};
-		void DrainWaterfraction(void){_error_("not implemented yet");};
-		#endif
-
-		#ifdef _HAVE_HYDROLOGY_
-		ElementMatrix* CreateKMatrixHydrologyShreve(void);
-		ElementMatrix* CreateKMatrixHydrologyDCInefficient(void);
-		ElementMatrix* CreateKMatrixHydrologyDCEfficient(void);
-		ElementVector* CreatePVectorHydrologyShreve(void);
-		ElementVector* CreatePVectorHydrologyDCInefficient(void);
-		ElementVector* CreatePVectorHydrologyDCEfficient(void);
-		void    GetSolutionFromInputsOneDof(Vector<IssmDouble>* solution,int enum_type);
-		void    CreateHydrologyWaterVelocityInput(void);
-		void	  InputUpdateFromSolutionHydrology(IssmDouble* solution);
-		void	  InputUpdateFromSolutionHydrologyShreve(IssmDouble* solution);
-		void    InputUpdateFromSolutionHydrologyDC(IssmDouble* solution);
-		void	  InputUpdateFromSolutionHydrologyDCInefficient(IssmDouble* solution);
-		void	  InputUpdateFromSolutionHydrologyDCEfficient(IssmDouble* solution);
-		void    GetHydrologyDCInefficientHmax(IssmDouble* ph_max, Node* innode);
-		void    GetHydrologyTransfer(Vector<IssmDouble>* transfer);
-		void    HydrologyEPLGetActive(Vector<IssmDouble>* active_vec);
-		void    HydrologyEPLGetMask(Vector<IssmDouble>* vec_mask);
-		bool    AllActive(void);
-		bool    AnyActive(void);
-		#endif
-
-		#ifdef _HAVE_DAMAGE_
-		ElementMatrix* CreateKMatrixDamageEvolution(void);
-		ElementMatrix* CreateKMatrixDamageEvolution_CG(void);
-		ElementVector* CreatePVectorDamageEvolution(void);
-		ElementVector* CreatePVectorDamageEvolution_CG(void);
-		void           DamageEvolutionF(IssmDouble* flist);
-		void	         InputUpdateFromSolutionDamageEvolution(IssmDouble* solution);
-		#endif
-
-
+
+		void           CreateHydrologyWaterVelocityInput(void);
 		/*}}}*/
 
Index: /issm/trunk/src/c/classes/Elements/TriaRef.cpp
===================================================================
--- /issm/trunk/src/c/classes/Elements/TriaRef.cpp	(revision 17805)
+++ /issm/trunk/src/c/classes/Elements/TriaRef.cpp	(revision 17806)
@@ -16,4 +16,5 @@
 
 /*Element macros*/
+#define NUMNODESP0  1
 #define NUMNODESP1  3
 #define NUMNODESP1b 4
@@ -50,104 +51,6 @@
 
 /*Reference Element numerics*/
-/*FUNCTION TriaRef::GetBHydro {{{*/
-void TriaRef::GetBHydro(IssmDouble* B, IssmDouble* xyz_list, GaussTria* gauss){
-	/*Compute B  matrix. B=[B1 B2 B3] where Bi is of size 3*NDOF2. 
-	 * For node i, Bi can be expressed in the actual coordinate system
-	 * by: 
-	 *       Bi=[ dN/dx ]
-	 *          [ dN/dy ]
-	 * where N is the finiteelement function for node i.
-	 *
-	 * We assume B has been allocated already, of size: 3x(NDOF2*numnodes)
-	 */
-
-	/*Fetch number of nodes for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Get nodal functions derivatives*/
-	IssmDouble* dbasis=xNew<IssmDouble>(2*numnodes);
-	GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
-
-	/*Build B: */
-	for(int i=0;i<numnodes;i++){
-		B[numnodes*0+i] = dbasis[0*numnodes+i];
-		B[numnodes*1+i] = dbasis[1*numnodes+i];
-	}
-
-	/*Clean-up*/
-	xDelete<IssmDouble>(dbasis);
-}
-/*}}}*/
-/*FUNCTION TriaRef::GetBSSA {{{*/
-void TriaRef::GetBSSA(IssmDouble* B, IssmDouble* xyz_list, GaussTria* gauss){
-	/*Compute B  matrix. B=[B1 B2 B3] where Bi is of size 3*NDOF2. 
-	 * For node i, Bi can be expressed in the actual coordinate system
-	 * by: 
-	 *       Bi=[ dN/dx           0    ]
-	 *          [   0           dN/dy  ]
-	 *          [ 1/2*dN/dy  1/2*dN/dx ]
-	 * where N is the finiteelement function for node i.
-	 *
-	 * We assume B has been allocated already, of size: 3x(NDOF2*numnodes)
-	 */
-
-	/*Fetch number of nodes for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Get nodal functions derivatives*/
-	IssmDouble* dbasis=xNew<IssmDouble>(2*numnodes);
-	GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
-
-	/*Build B: */
-	for(int i=0;i<numnodes;i++){
-		B[NDOF2*numnodes*0+NDOF2*i+0] = dbasis[0*numnodes+i];
-		B[NDOF2*numnodes*0+NDOF2*i+1] = 0.;
-		B[NDOF2*numnodes*1+NDOF2*i+0] = 0.;
-		B[NDOF2*numnodes*1+NDOF2*i+1] = dbasis[1*numnodes+i];
-		B[NDOF2*numnodes*2+NDOF2*i+0] = .5*dbasis[1*numnodes+i];
-		B[NDOF2*numnodes*2+NDOF2*i+1] = .5*dbasis[0*numnodes+i];
-	}
-
-	/*Clean-up*/
-	xDelete<IssmDouble>(dbasis);
-}
-/*}}}*/
-/*FUNCTION TriaRef::GetBSSAFS {{{*/
-void TriaRef::GetBSSAFS(IssmDouble* B, IssmDouble* xyz_list, GaussTria* gauss){
-
-	/*Compute B  matrix. B=[B1 B2 B3] where Bi is of size 3*NDOF2. 
-	 * For node i, Bi can be expressed in the actual coordinate system
-	 * by: 
-	 *       Bi=[   dN/dx         0     ]
-	 *          [       0       dN/dy   ]
-	 *          [  1/2*dN/dy  1/2*dN/dx ]
-	 * where N is the finiteelement function for node i.
-	 *
-	 * We assume B has been allocated already, of size: 3x(NDOF2*numnodes)
-	 */
-
-	/*Fetch number of nodes for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Get nodal functions derivatives*/
-	IssmDouble* dbasis=xNew<IssmDouble>(2*numnodes);
-	GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
-
-	/*Build B': */
-	for(int i=0;i<numnodes;i++){
-		B[NDOF2*numnodes*0+NDOF2*i+0] = dbasis[0*numnodes+i];
-		B[NDOF2*numnodes*0+NDOF2*i+1] = 0.;
-		B[NDOF2*numnodes*1+NDOF2*i+0] = 0.;
-		B[NDOF2*numnodes*1+NDOF2*i+1] = dbasis[1*numnodes+i];
-		B[NDOF2*numnodes*2+NDOF2*i+0] = 0.5*dbasis[1*numnodes+i];
-		B[NDOF2*numnodes*2+NDOF2*i+1] = 0.5*dbasis[0*numnodes+i];
-	}
-
-	/*Clean-up*/
-	xDelete<IssmDouble>(dbasis);
-}
-/*}}}*/
 /*FUNCTION TriaRef::GetSegmentBFlux{{{*/
-void TriaRef::GetSegmentBFlux(IssmDouble* B,GaussTria* gauss, int index1,int index2){
+void TriaRef::GetSegmentBFlux(IssmDouble* B,Gauss* gauss, int index1,int index2){
 	/*Compute B  matrix. B=[phi1 phi2 -phi3 -phi4]
 	 *
@@ -175,5 +78,5 @@
 /*}}}*/
 /*FUNCTION TriaRef::GetSegmentBprimeFlux{{{*/
-void TriaRef::GetSegmentBprimeFlux(IssmDouble* Bprime,GaussTria* gauss, int index1,int index2){
+void TriaRef::GetSegmentBprimeFlux(IssmDouble* Bprime,Gauss* gauss, int index1,int index2){
 	/*Compute Bprime  matrix. Bprime=[phi1 phi2 phi3 phi4]
 	 *
@@ -200,331 +103,6 @@
 }
 /*}}}*/
-/*FUNCTION TriaRef::GetBExtrusion{{{*/
-void TriaRef::GetBExtrusion(IssmDouble* B, IssmDouble* xyz_list, GaussTria* gauss){
-	/*	Compute B  matrix. B=[dh1/dz dh2/dz dh3/dz dh4/dz dh5/dz dh6/dz];
-		where hi is the interpolation function for node i.*/
-
-	/*Fetch number of nodes for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Get nodal functions derivatives*/
-	IssmDouble* dbasis=xNew<IssmDouble>(2*numnodes);
-	GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
-
-	/*Build B: */
-	for(int i=0;i<numnodes;i++){
-		B[i] = dbasis[1*numnodes+i];  
-	}
-
-	/*Clean-up*/
-	xDelete<IssmDouble>(dbasis);
-}
-/*}}}*/
-/*FUNCTION TriaRef::GetBFS {{{*/
-void TriaRef::GetBFS(IssmDouble* B, IssmDouble* xyz_list, GaussTria* gauss){
-	/*Compute B  matrix. B=[Bv1 Bv2 ... Bp1 Bp2 ...] where Bvi is of size 3*NDOF3. 
-	 * For node i, Bvi can be expressed in the actual coordinate system
-	 * by: 	   Bvi=[ dphi/dx          0        ]
-	 *					 [   0           dphi/dy     ]
-	 *					 [ 1/2*dphi/dy    1/2*dphi/dx]
-	 *					 [   0             0         ]
-	 *					 [ dphi/dx         dphi/dy   ]
-	 *
-	 * by: 	  Bpi=[  0    ]
-	 *					[  0    ]
-	 *					[  0    ]
-	 *					[ phi_p ]
-	 *					[  0    ]
-	 *	where phi is the finiteelement function for node i.
-	 *	Same thing for Bb except the last column that does not exist.
-	 */
-
-	/*Fetch number of nodes for this finite element*/
-	int pnumnodes = this->NumberofNodesPressure();
-	int vnumnodes = this->NumberofNodesVelocity();
-
-	/*Get nodal functions derivatives*/
-	IssmDouble* vdbasis=xNew<IssmDouble>(2*vnumnodes);
-	IssmDouble* pbasis =xNew<IssmDouble>(pnumnodes);
-	GetNodalFunctionsDerivativesVelocity(vdbasis,xyz_list,gauss);
-	GetNodalFunctionsPressure(pbasis,gauss);
-
-	/*Build B: */
-	for(int i=0;i<vnumnodes;i++){
-		B[(2*vnumnodes+pnumnodes)*0+2*i+0] = vdbasis[0*vnumnodes+i];
-		B[(2*vnumnodes+pnumnodes)*0+2*i+1] = 0.;
-		B[(2*vnumnodes+pnumnodes)*1+2*i+0] = 0.;
-		B[(2*vnumnodes+pnumnodes)*1+2*i+1] = vdbasis[1*vnumnodes+i];
-		B[(2*vnumnodes+pnumnodes)*2+2*i+0] = .5*vdbasis[1*vnumnodes+i];
-		B[(2*vnumnodes+pnumnodes)*2+2*i+1] = .5*vdbasis[0*vnumnodes+i];
-		B[(2*vnumnodes+pnumnodes)*3+2*i+0] = 0.;
-		B[(2*vnumnodes+pnumnodes)*3+2*i+1] = 0.;
-		B[(2*vnumnodes+pnumnodes)*4+2*i+0] = vdbasis[0*vnumnodes+i];
-		B[(2*vnumnodes+pnumnodes)*4+2*i+1] = vdbasis[1*vnumnodes+i];
-	}
-	for(int i=0;i<pnumnodes;i++){
-		B[(2*vnumnodes+pnumnodes)*0+(2*vnumnodes)+i] = 0.;
-		B[(2*vnumnodes+pnumnodes)*1+(2*vnumnodes)+i] = 0.;
-		B[(2*vnumnodes+pnumnodes)*2+(2*vnumnodes)+i] = 0.;
-		B[(2*vnumnodes+pnumnodes)*3+(2*vnumnodes)+i] = pbasis[i];
-		B[(2*vnumnodes+pnumnodes)*4+(2*vnumnodes)+i] = 0.;
-	}
-
-	/*Clean up*/
-	xDelete<IssmDouble>(vdbasis);
-	xDelete<IssmDouble>(pbasis);
-}
-/*}}}*/
-/*FUNCTION TriaRef::GetBprimeFS {{{*/
-void TriaRef::GetBprimeFS(IssmDouble* B_prime, IssmDouble* xyz_list, GaussTria* gauss){
-	/*	Compute B'  matrix. B'=[B1' B2' B3' B4' B5' B6' Bb'] where Bi' is of size 3*NDOF2. 
-	 *	For node i, Bi' can be expressed in the actual coordinate system
-	 *	by: 
-	 *			Bvi' = [  dphi/dx     0     ]
-	 *					 [     0      dphi/dy ]
-	 *					 [  dphi/dy   dphi/dx ]
-	 *					 [  dphi/dx   dphi/dy ]
-	 *					 [     0      0       ]
-	 *
-	 * by: 	  Bpi=[  0  ]
-	 *					[  0  ]
-	 *					[  0  ]
-	 *					[  0  ]
-	 *					[ phi ]
-	 *	where phi is the finiteelement function for node i.
-	 */
-
-	/*Fetch number of nodes for this finite element*/
-	int pnumnodes = this->NumberofNodesPressure();
-	int vnumnodes = this->NumberofNodesVelocity();
-
-	/*Get nodal functions derivatives*/
-	IssmDouble* vdbasis=xNew<IssmDouble>(2*vnumnodes);
-	IssmDouble* pbasis =xNew<IssmDouble>(pnumnodes);
-	GetNodalFunctionsDerivativesVelocity(vdbasis,xyz_list,gauss);
-	GetNodalFunctionsPressure(pbasis,gauss);
-
-	/*Build B_prime: */
-	for(int i=0;i<vnumnodes;i++){
-		B_prime[(2*vnumnodes+pnumnodes)*0+2*i+0] = vdbasis[0*vnumnodes+i];
-		B_prime[(2*vnumnodes+pnumnodes)*0+2*i+1] = 0.;
-		B_prime[(2*vnumnodes+pnumnodes)*1+2*i+0] = 0.;
-		B_prime[(2*vnumnodes+pnumnodes)*1+2*i+1] = vdbasis[1*vnumnodes+i];
-		B_prime[(2*vnumnodes+pnumnodes)*2+2*i+0] = vdbasis[1*vnumnodes+i];
-		B_prime[(2*vnumnodes+pnumnodes)*2+2*i+1] = vdbasis[0*vnumnodes+i];
-		B_prime[(2*vnumnodes+pnumnodes)*3+2*i+0] = vdbasis[0*vnumnodes+i];
-		B_prime[(2*vnumnodes+pnumnodes)*3+2*i+1] = vdbasis[1*vnumnodes+i];
-		B_prime[(2*vnumnodes+pnumnodes)*4+2*i+0] = 0.;
-		B_prime[(2*vnumnodes+pnumnodes)*4+2*i+1] = 0.;
-	}
-	for(int i=0;i<pnumnodes;i++){
-		B_prime[(2*vnumnodes+pnumnodes)*0+(2*vnumnodes)+i] = 0.;
-		B_prime[(2*vnumnodes+pnumnodes)*1+(2*vnumnodes)+i] = 0.;
-		B_prime[(2*vnumnodes+pnumnodes)*2+(2*vnumnodes)+i] = 0.;
-		B_prime[(2*vnumnodes+pnumnodes)*3+(2*vnumnodes)+i] = 0.;
-		B_prime[(2*vnumnodes+pnumnodes)*4+(2*vnumnodes)+i] = pbasis[i];
-	}
-
-	/*Clean up*/
-	xDelete<IssmDouble>(vdbasis);
-	xDelete<IssmDouble>(pbasis);
-}
-/*}}}*/
-/*FUNCTION TriaRef::GetBMasstransport{{{*/
-void TriaRef::GetBMasstransport(IssmDouble* B, IssmDouble* xyz_list, GaussTria* gauss){
-	/*Compute B  matrix. B=[B1 B2 B3] where Bi is of size 3*NDOF2. 
-	 * For node i, Bi can be expressed in the actual coordinate system
-	 * by: 
-	 *       Bi=[ N ]
-	 *          [ N ]
-	 * where N is the finiteelement function for node i.
-	 *
-	 * We assume B_prog has been allocated already, of size: 2x(NDOF1*numnodes)
-	 */
-
-	/*Fetch number of nodes for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Get nodal functions*/
-	IssmDouble* basis=xNew<IssmDouble>(numnodes);
-	GetNodalFunctions(basis,gauss);
-
-	/*Build B: */
-	for(int i=0;i<numnodes;i++){
-		B[numnodes*0+i] = basis[i];
-		B[numnodes*1+i] = basis[i];
-	}
-
-	/*Clean-up*/
-	xDelete<IssmDouble>(basis);
-}
-/*}}}*/
-/*FUNCTION TriaRef::GetBprimeSSA {{{*/
-void TriaRef::GetBprimeSSA(IssmDouble* Bprime, IssmDouble* xyz_list, GaussTria* gauss){
-
-	/*Compute B'  matrix. B'=[B1' B2' B3'] where Bi' is of size 3*NDOF2. 
-	 * For node i, Bi' can be expressed in the actual coordinate system
-	 * by: 
-	 *       Bi_prime=[ 2*dN/dx    dN/dy ]
-	 *                [   dN/dx  2*dN/dy ]
-	 *                [   dN/dy    dN/dx ]
-	 * where hNis the finiteelement function for node i.
-	 *
-	 * We assume B' has been allocated already, of size: 3x(NDOF2*numnodes)
-	 */
-
-	/*Fetch number of nodes for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Get nodal functions derivatives*/
-	IssmDouble* dbasis=xNew<IssmDouble>(2*numnodes);
-	GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
-
-	/*Build B': */
-	for(int i=0;i<numnodes;i++){
-		Bprime[NDOF2*numnodes*0+NDOF2*i+0] = 2.*dbasis[0*numnodes+i];
-		Bprime[NDOF2*numnodes*0+NDOF2*i+1] =    dbasis[1*numnodes+i];
-		Bprime[NDOF2*numnodes*1+NDOF2*i+0] =    dbasis[0*numnodes+i];
-		Bprime[NDOF2*numnodes*1+NDOF2*i+1] = 2.*dbasis[1*numnodes+i];
-		Bprime[NDOF2*numnodes*2+NDOF2*i+0] =    dbasis[1*numnodes+i];
-		Bprime[NDOF2*numnodes*2+NDOF2*i+1] =    dbasis[0*numnodes+i];
-	}
-
-	/*Clean-up*/
-	xDelete<IssmDouble>(dbasis);
-}
-/*}}}*/
-/*FUNCTION TriaRef::GetBprimeSSAFS {{{*/
-void TriaRef::GetBprimeSSAFS(IssmDouble* Bprime, IssmDouble* xyz_list, GaussTria* gauss){
-	/*Compute Bprime  matrix. Bprime=[Bprime1 Bprime2 Bprime3] where Bprimei is of size 3*NDOF2. 
-	 * For node i, Bprimei can be expressed in the actual coordinate system
-	 * by: 
-	 *       Bprimei=[  dN/dx    0   ]
-	 *               [    0    dN/dy ]
-	 *               [  dN/dy  dN/dx ]
-	 N               [  dN/dx  dN/dy ]
-	 * where N is the finiteelement function for node i.
-	 *
-	 * We assume Bprime has been allocated already, of size: 3x(NDOF2*numnodes)
-	 */
-
-	/*Fetch number of nodes for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Get nodal functions*/
-	IssmDouble* dbasis=xNew<IssmDouble>(2*numnodes);
-	GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
-
-	/*Build Bprime: */
-	for(int i=0;i<numnodes;i++){
-		Bprime[NDOF2*numnodes*0+NDOF2*i+0] = dbasis[0*numnodes+i];
-		Bprime[NDOF2*numnodes*0+NDOF2*i+1] = 0.;
-		Bprime[NDOF2*numnodes*1+NDOF2*i+0] = 0.;
-		Bprime[NDOF2*numnodes*1+NDOF2*i+1] = dbasis[1*numnodes+i];
-		Bprime[NDOF2*numnodes*2+NDOF2*i+0] = dbasis[1*numnodes+i];
-		Bprime[NDOF2*numnodes*2+NDOF2*i+1] = dbasis[0*numnodes+i];
-		Bprime[NDOF2*numnodes*3+NDOF2*i+0] = dbasis[0*numnodes+i];
-		Bprime[NDOF2*numnodes*3+NDOF2*i+1] = dbasis[1*numnodes+i];
-	}
-
-	/*Clean-up*/
-	xDelete<IssmDouble>(dbasis);
-}
-/*}}}*/
-/*FUNCTION TriaRef::GetBprimeMasstransport{{{*/
-void TriaRef::GetBprimeMasstransport(IssmDouble* Bprime, IssmDouble* xyz_list, GaussTria* gauss){
-	/*Compute B'  matrix. B'=[B1' B2' B3'] where Bi' is of size 3*NDOF2. 
-	 * For node i, Bi' can be expressed in the actual coordinate system
-	 * by: 
-	 *       Bi_prime=[ dN/dx ]
-	 *                [ dN/dy ]
-	 * where N is the finiteelement function for node i.
-	 *
-	 * We assume B' has been allocated already, of size: 3x(NDOF2*numnodes)
-	 */
-
-	/*Fetch number of nodes for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Get nodal functions derivatives*/
-	IssmDouble* dbasis=xNew<IssmDouble>(2*numnodes);
-	GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
-
-	/*Build B': */
-	for(int i=0;i<numnodes;i++){
-		Bprime[numnodes*0+i] = dbasis[0*numnodes+i];
-		Bprime[numnodes*1+i] = dbasis[1*numnodes+i];
-	}
-
-	/*Clean-up*/
-	xDelete<IssmDouble>(dbasis);
-}
-/*}}}*/
-/*FUNCTION TriaRef::GetBSSAFriction{{{*/
-void TriaRef::GetBSSAFriction(IssmDouble* B, IssmDouble* xyz_list,GaussTria* gauss){
-	/*Compute B  matrix. B=[B1 B2 B3] where Bi is square and of size 2. 
-	 * For node i, Bi can be expressed in the actual coordinate system
-	 * by: 
-	 *                 Bi=[ N   0 ]
-	 *                    [ 0   N ]
-	 * where N is the finiteelement function for node i.
-	 *
-	 * We assume B has been allocated already, of size: 2 x (numdof*numnodes)
-	 */
-
-	/*Fetch number of nodes for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Get nodal functions derivatives*/
-	IssmDouble* basis=xNew<IssmDouble>(numnodes);
-	GetNodalFunctions(basis,gauss);
-
-	/*Build L: */
-	for(int i=0;i<numnodes;i++){
-		B[2*numnodes*0+2*i+0] = basis[i];
-		B[2*numnodes*0+2*i+1] = 0.;
-		B[2*numnodes*1+2*i+0] = 0.;
-		B[2*numnodes*1+2*i+1] = basis[i];
-	}
-
-	/*Clean-up*/
-	xDelete<IssmDouble>(basis);
-}
-/*}}}*/
-/*FUNCTION TriaRef::GetLFS{{{*/
-void TriaRef::GetLFS(IssmDouble* LFS, GaussTria* gauss){
-	/* Compute L  matrix. L=[L1 L2 L3] where Li is square and of size numdof. 
-	 * For node i, Li can be expressed in the actual coordinate system
-	 * by: 
-	 *       Li=[ h 0 0 ]
-	 * where h is the interpolation function for node i.
-	 */
-
-	/*Fetch number of nodes for this finite element*/
-	int pnumnodes = this->NumberofNodesPressure();
-	int vnumnodes = this->NumberofNodesVelocity();
-	int pnumdof   = pnumnodes;
-	int vnumdof   = vnumnodes*NDOF2;
-
-	/*Get nodal functions derivatives*/
-	IssmDouble* vbasis=xNew<IssmDouble>(vnumnodes);
-	GetNodalFunctionsVelocity(vbasis,gauss);
-
-	/*Build LFS: */
-	for(int i=0;i<vnumnodes;i++){
-		LFS[2*i+0] = vbasis[i];
-		LFS[2*i+1] = 0.;
-	}
-
-	for(int i=0;i<pnumnodes;i++){
-		LFS[i+vnumdof+0] = 0.;
-	}
-
-	/*Clean-up*/
-	xDelete<IssmDouble>(vbasis);
-}
-/*}}}*/
 /*FUNCTION TriaRef::GetJacobian{{{*/
-void TriaRef::GetJacobian(IssmDouble* J, IssmDouble* xyz_list,GaussTria* gauss){
+void TriaRef::GetJacobian(IssmDouble* J, IssmDouble* xyz_list,Gauss* gauss){
 	/*The Jacobian is constant over the element, discard the gaussian points. 
 	 * J is assumed to have been allocated of size NDOF2xNDOF2.*/
@@ -544,5 +122,5 @@
 /*}}}*/
 /*FUNCTION TriaRef::GetSegmentJacobianDeterminant{{{*/
-void TriaRef::GetSegmentJacobianDeterminant(IssmDouble* Jdet, IssmDouble* xyz_list,GaussTria* gauss){
+void TriaRef::GetSegmentJacobianDeterminant(IssmDouble* Jdet, IssmDouble* xyz_list,Gauss* gauss){
 	/*The Jacobian determinant is constant over the element, discard the gaussian points. 
 	 * J is assumed to have been allocated*/
@@ -559,5 +137,5 @@
 /*}}}*/
 /*FUNCTION TriaRef::GetJacobianDeterminant{{{*/
-void TriaRef::GetJacobianDeterminant(IssmDouble* Jdet, IssmDouble* xyz_list,GaussTria* gauss){
+void TriaRef::GetJacobianDeterminant(IssmDouble* Jdet, IssmDouble* xyz_list,Gauss* gauss){
 	/*The Jacobian determinant is constant over the element, discard the gaussian points. 
 	 * J is assumed to have been allocated of size NDOF2xNDOF2.*/
@@ -574,5 +152,5 @@
 /*}}}*/
 /*FUNCTION TriaRef::GetJacobianInvert{{{*/
-void TriaRef::GetJacobianInvert(IssmDouble*  Jinv, IssmDouble* xyz_list,GaussTria* gauss){
+void TriaRef::GetJacobianInvert(IssmDouble*  Jinv, IssmDouble* xyz_list,Gauss* gauss){
 
 	/*Jacobian*/
@@ -587,6 +165,6 @@
 }
 /*}}}*/
-/*FUNCTION TriaRef::GetNodalFunctions(IssmDouble* basis,GaussTria* gauss){{{*/
-void TriaRef::GetNodalFunctions(IssmDouble* basis,GaussTria* gauss){
+/*FUNCTION TriaRef::GetNodalFunctions(IssmDouble* basis,Gauss* gauss){{{*/
+void TriaRef::GetNodalFunctions(IssmDouble* basis,Gauss* gauss){
 	/*This routine returns the values of the nodal functions  at the gaussian point.*/
 
@@ -596,11 +174,18 @@
 }
 /*}}}*/
-/*FUNCTION TriaRef::GetNodalFunctions(IssmDouble* basis,GaussTria* gauss,int finiteelement){{{*/
-void TriaRef::GetNodalFunctions(IssmDouble* basis,GaussTria* gauss,int finiteelement){
+/*FUNCTION TriaRef::GetNodalFunctions(IssmDouble* basis,Gauss* gauss,int finiteelement){{{*/
+void TriaRef::GetNodalFunctions(IssmDouble* basis,Gauss* gauss_in,int finiteelement){
 	/*This routine returns the values of the nodal functions  at the gaussian point.*/
 
 	_assert_(basis);
 
+	/*Cast gauss to GaussTria*/
+	_assert_(gauss_in->Enum()==GaussTriaEnum);
+	GaussTria* gauss = dynamic_cast<GaussTria*>(gauss_in);
+
 	switch(finiteelement){
+		case P0Enum:
+			basis[0]=1.;
+			return;
 		case P1Enum: case P1DGEnum:
 			basis[0]=gauss->coord1;
@@ -632,5 +217,5 @@
 /*}}}*/
 /*FUNCTION TriaRef::GetNodalFunctionsVelocity{{{*/
-void TriaRef::GetNodalFunctionsVelocity(IssmDouble* basis,GaussTria* gauss){
+void TriaRef::GetNodalFunctionsVelocity(IssmDouble* basis,Gauss* gauss){
 	/*This routine returns the values of the nodal functions  at the gaussian point.*/
 
@@ -661,4 +246,9 @@
 			this->element_type = TaylorHoodEnum;
 			return;
+		case XTaylorHoodEnum:
+			this->element_type = P2Enum;
+			this->GetNodalFunctions(basis,gauss);
+			this->element_type = XTaylorHoodEnum;
+			return;
 		default:
 			_error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
@@ -667,5 +257,5 @@
 /*}}}*/
 /*FUNCTION TriaRef::GetNodalFunctionsPressure{{{*/
-void TriaRef::GetNodalFunctionsPressure(IssmDouble* basis,GaussTria* gauss){
+void TriaRef::GetNodalFunctionsPressure(IssmDouble* basis,Gauss* gauss){
 	/*This routine returns the values of the nodal functions  at the gaussian point.*/
 
@@ -696,4 +286,24 @@
 			this->element_type = TaylorHoodEnum;
 			return;
+		case XTaylorHoodEnum:
+			this->element_type = P1Enum;
+			this->GetNodalFunctions(basis,gauss);
+			this->element_type = XTaylorHoodEnum;
+			return;
+		default:
+			_error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
+	}
+}
+/*}}}*/
+/*FUNCTION TriaRef::GetNodalFunctionsTensor{{{*/
+void TriaRef::GetNodalFunctionsTensor(IssmDouble* basis,Gauss* gauss){
+	/*This routine returns the values of the nodal functions  at the gaussian point.*/
+
+	switch(this->element_type){
+		case XTaylorHoodEnum:
+			this->element_type = P1DGEnum;
+			this->GetNodalFunctions(basis,gauss);
+			this->element_type = XTaylorHoodEnum;
+			return;
 		default:
 			_error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
@@ -702,5 +312,5 @@
 /*}}}*/
 /*FUNCTION TriaRef::GetSegmentNodalFunctions{{{*/
-void TriaRef::GetSegmentNodalFunctions(IssmDouble* basis,GaussTria* gauss,int index1,int index2){
+void TriaRef::GetSegmentNodalFunctions(IssmDouble* basis,Gauss* gauss,int index1,int index2){
 	/*This routine returns the values of the nodal functions  at the gaussian point.*/
 
@@ -741,6 +351,6 @@
 }
 /*}}}*/
-/*FUNCTION TriaRef::GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list, GaussTria* gauss){{{*/
-void TriaRef::GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list, GaussTria* gauss){
+/*FUNCTION TriaRef::GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list, Gauss* gauss){{{*/
+void TriaRef::GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list, Gauss* gauss){
 
 	GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss,this->element_type);
@@ -748,6 +358,6 @@
 }
 /*}}}*/
-/*FUNCTION TriaRef::GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list, GaussTria* gauss,int finiteelement){{{*/
-void TriaRef::GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list, GaussTria* gauss,int finiteelement){
+/*FUNCTION TriaRef::GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list, Gauss* gauss,int finiteelement){{{*/
+void TriaRef::GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list, Gauss* gauss,int finiteelement){
 
 	/*This routine returns the values of the nodal functions derivatives  (with respect to the 
@@ -780,5 +390,5 @@
 /*}}}*/
 /*FUNCTION TriaRef::GetNodalFunctionsDerivativesPressure{{{*/
-void TriaRef::GetNodalFunctionsDerivativesPressure(IssmDouble* dbasis,IssmDouble* xyz_list, GaussTria* gauss){
+void TriaRef::GetNodalFunctionsDerivativesPressure(IssmDouble* dbasis,IssmDouble* xyz_list, Gauss* gauss){
 	switch(this->element_type){
 		case P1P1Enum:
@@ -813,5 +423,5 @@
 /*}}}*/
 /*FUNCTION TriaRef::GetNodalFunctionsDerivativesVelocity{{{*/
-void TriaRef::GetNodalFunctionsDerivativesVelocity(IssmDouble* dbasis,IssmDouble* xyz_list, GaussTria* gauss){
+void TriaRef::GetNodalFunctionsDerivativesVelocity(IssmDouble* dbasis,IssmDouble* xyz_list, Gauss* gauss){
 	switch(this->element_type){
 		case P1P1Enum:
@@ -836,15 +446,16 @@
 			return;
 		case TaylorHoodEnum:
+		case XTaylorHoodEnum:
 			this->element_type = P2Enum;
 			this->GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
-			this->element_type = TaylorHoodEnum;
-			return;
-		default:
-			_error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
-	}
-}
-/*}}}*/
-/*FUNCTION TriaRef::GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,GaussTria* gauss){{{*/
-void TriaRef::GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,GaussTria* gauss){
+			this->element_type = XTaylorHoodEnum;
+			return;
+		default:
+			_error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
+	}
+}
+/*}}}*/
+/*FUNCTION TriaRef::GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,Gauss* gauss){{{*/
+void TriaRef::GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,Gauss* gauss){
 	/*This routine returns the values of the nodal functions derivatives  (with respect to the 
 	 * natural coordinate system) at the gaussian point. */
@@ -854,12 +465,21 @@
 }
 /*}}}*/
-/*FUNCTION TriaRef::GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,GaussTria* gauss,int finiteelement){{{*/
-void TriaRef::GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,GaussTria* gauss,int finiteelement){
+/*FUNCTION TriaRef::GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,Gauss* gauss,int finiteelement){{{*/
+void TriaRef::GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,Gauss* gauss_in,int finiteelement){
 	/*This routine returns the values of the nodal functions derivatives  (with respect to the 
 	 * natural coordinate system) at the gaussian point. */
 
-	_assert_(dbasis && gauss);
+	_assert_(dbasis && gauss_in);
+
+	/*Cast gauss to GaussTria*/
+	_assert_(gauss_in->Enum()==GaussTriaEnum);
+	GaussTria* gauss = dynamic_cast<GaussTria*>(gauss_in);
 
 	switch(finiteelement){
+		case P0Enum:
+			/*Nodal function 1*/
+			dbasis[NUMNODESP0*0+0] = 0.;
+			dbasis[NUMNODESP0*1+0] = 0.;
+			return;
 		case P1Enum: case P1DGEnum:
 			/*Nodal function 1*/
@@ -914,5 +534,5 @@
 /*}}}*/
 /*FUNCTION TriaRef::GetInputDerivativeValue{{{*/
-void TriaRef::GetInputDerivativeValue(IssmDouble* p, IssmDouble* plist,IssmDouble* xyz_list, GaussTria* gauss){
+void TriaRef::GetInputDerivativeValue(IssmDouble* p, IssmDouble* plist,IssmDouble* xyz_list, Gauss* gauss){
 
 	/*From node values of parameter p (plist[0],plist[1],plist[2]), return parameter derivative value at gaussian 
@@ -946,12 +566,12 @@
 }
 /*}}}*/
-/*FUNCTION TriaRef::GetInputValue(IssmDouble* p, IssmDouble* plist, GaussTria* gauss){{{*/
-void TriaRef::GetInputValue(IssmDouble* p, IssmDouble* plist, GaussTria* gauss){
+/*FUNCTION TriaRef::GetInputValue(IssmDouble* p, IssmDouble* plist, Gauss* gauss){{{*/
+void TriaRef::GetInputValue(IssmDouble* p, IssmDouble* plist, Gauss* gauss){
 
 	GetInputValue(p,plist,gauss,this->element_type);
 }
 /*}}}*/
-/*FUNCTION TriaRef::GetInputValue(IssmDouble* p, IssmDouble* plist, GaussTria* gauss,int finiteelement){{{*/
-void TriaRef::GetInputValue(IssmDouble* p, IssmDouble* plist, GaussTria* gauss,int finiteelement){
+/*FUNCTION TriaRef::GetInputValue(IssmDouble* p, IssmDouble* plist, Gauss* gauss,int finiteelement){{{*/
+void TriaRef::GetInputValue(IssmDouble* p, IssmDouble* plist, Gauss* gauss,int finiteelement){
 
 	/*Output*/
@@ -983,4 +603,5 @@
 
 	switch(finiteelement){
+		case P0Enum:                return NUMNODESP0;
 		case P1Enum:                return NUMNODESP1;
 		case P1DGEnum:              return NUMNODESP1;
@@ -993,4 +614,5 @@
 		case MINIEnum:              return NUMNODESP1b+NUMNODESP1;
 		case TaylorHoodEnum:        return NUMNODESP2+NUMNODESP1;
+		case XTaylorHoodEnum:       return NUMNODESP2+NUMNODESP1;
 		default: _error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
 	}
@@ -1008,4 +630,5 @@
 		case MINIEnum:          return NUMNODESP1;
 		case TaylorHoodEnum:    return NUMNODESP1;
+		case XTaylorHoodEnum:   return NUMNODESP1;
 		default: _error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
 	}
@@ -1023,4 +646,5 @@
 		case MINIEnum:          return NUMNODESP1b;
 		case TaylorHoodEnum:    return NUMNODESP2;
+		case XTaylorHoodEnum:   return NUMNODESP2;
 		default:       _error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
 	}
@@ -1038,4 +662,5 @@
 		case MINIEnum:          return P1bubbleEnum;
 		case TaylorHoodEnum:    return P2Enum;
+		case XTaylorHoodEnum:   return P2Enum;
 		default:       _error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
 	}
@@ -1053,4 +678,5 @@
 		case MINIEnum:          return P1Enum;
 		case TaylorHoodEnum:    return P1Enum;
+		case XTaylorHoodEnum:   return P1Enum;
 		default:       _error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
 	}
Index: /issm/trunk/src/c/classes/Elements/TriaRef.h
===================================================================
--- /issm/trunk/src/c/classes/Elements/TriaRef.h	(revision 17805)
+++ /issm/trunk/src/c/classes/Elements/TriaRef.h	(revision 17806)
@@ -7,5 +7,5 @@
 #define _TRIAREF_H_
 
-class GaussTria;
+class Gauss;
 
 class TriaRef{
@@ -23,36 +23,25 @@
 
 		/*Numerics*/
-		void GetBExtrusion(IssmDouble* B_prime, IssmDouble* xyz_list, GaussTria* gauss);
-		void GetBFS(IssmDouble* B_prime, IssmDouble* xyz_list, GaussTria* gauss);
-		void GetBSSA(IssmDouble* B, IssmDouble* xyz_list, GaussTria* gauss);
-		void GetBSSAFS(IssmDouble* B , IssmDouble* xyz_list, GaussTria* gauss);
-		void GetBprimeFS(IssmDouble* B_prime, IssmDouble* xyz_list, GaussTria* gauss);
-		void GetBprimeSSA(IssmDouble* Bprime, IssmDouble* xyz_list, GaussTria* gauss);
-		void GetBprimeSSAFS(IssmDouble* Bprime, IssmDouble* xyz_list, GaussTria* gauss);
-		void GetBprimeMasstransport(IssmDouble* Bprime, IssmDouble* xyz_list, GaussTria* gauss);
-		void GetBMasstransport(IssmDouble* B, IssmDouble* xyz_list, GaussTria* gauss);
-		void GetBHydro(IssmDouble* B, IssmDouble* xyz_list, GaussTria* gauss);
-		void GetBSSAFriction(IssmDouble* L, IssmDouble* xyz_list,GaussTria* gauss);
-		void GetJacobian(IssmDouble* J, IssmDouble* xyz_list,GaussTria* gauss);
-		void GetSegmentJacobianDeterminant(IssmDouble* Jdet, IssmDouble* xyz_list,GaussTria* gauss);
-		void GetJacobianDeterminant(IssmDouble* Jdet, IssmDouble* xyz_list,GaussTria* gauss);
-		void GetJacobianInvert(IssmDouble*  Jinv, IssmDouble* xyz_list,GaussTria* gauss);
-		void GetLFS(IssmDouble* LFS, GaussTria* gauss);
-		void GetNodalFunctions(IssmDouble* basis,GaussTria* gauss);
-		void GetNodalFunctions(IssmDouble* basis,GaussTria* gauss,int finiteelement);
-		void GetNodalFunctionsVelocity(IssmDouble* basis, GaussTria* gauss);
-		void GetNodalFunctionsPressure(IssmDouble* basis, GaussTria* gauss);
-		void GetSegmentNodalFunctions(IssmDouble* basis,GaussTria* gauss, int index1,int index2);
-		void GetSegmentBFlux(IssmDouble* B,GaussTria* gauss, int index1,int index2);
-		void GetSegmentBprimeFlux(IssmDouble* Bprime,GaussTria* gauss, int index1,int index2);
-		void GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list, GaussTria* gauss);
-		void GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list, GaussTria* gauss,int finiteelement);
-		void GetNodalFunctionsDerivativesVelocity(IssmDouble* dbasis,IssmDouble* xyz_list,GaussTria* gauss);
-		void GetNodalFunctionsDerivativesPressure(IssmDouble* dbasis,IssmDouble* xyz_list,GaussTria* gauss);
-		void GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,GaussTria* gauss);
-		void GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,GaussTria* gauss,int finiteelement);
-		void GetInputValue(IssmDouble* pp, IssmDouble* plist, GaussTria* gauss);
-		void GetInputValue(IssmDouble* pp, IssmDouble* plist, GaussTria* gauss,int finiteelement);
-		void GetInputDerivativeValue(IssmDouble* pp, IssmDouble* plist,IssmDouble* xyz_list, GaussTria* gauss);
+		void GetJacobian(IssmDouble* J, IssmDouble* xyz_list,Gauss* gauss);
+		void GetSegmentJacobianDeterminant(IssmDouble* Jdet, IssmDouble* xyz_list,Gauss* gauss);
+		void GetJacobianDeterminant(IssmDouble* Jdet, IssmDouble* xyz_list,Gauss* gauss);
+		void GetJacobianInvert(IssmDouble*  Jinv, IssmDouble* xyz_list,Gauss* gauss);
+		void GetNodalFunctions(IssmDouble* basis,Gauss* gauss);
+		void GetNodalFunctions(IssmDouble* basis,Gauss* gauss,int finiteelement);
+		void GetNodalFunctionsVelocity(IssmDouble* basis, Gauss* gauss);
+		void GetNodalFunctionsPressure(IssmDouble* basis, Gauss* gauss);
+		void GetNodalFunctionsTensor(IssmDouble* basis, Gauss* gauss);
+		void GetSegmentNodalFunctions(IssmDouble* basis,Gauss* gauss, int index1,int index2);
+		void GetSegmentBFlux(IssmDouble* B,Gauss* gauss, int index1,int index2);
+		void GetSegmentBprimeFlux(IssmDouble* Bprime,Gauss* gauss, int index1,int index2);
+		void GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list, Gauss* gauss);
+		void GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list, Gauss* gauss,int finiteelement);
+		void GetNodalFunctionsDerivativesVelocity(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss);
+		void GetNodalFunctionsDerivativesPressure(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss);
+		void GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,Gauss* gauss);
+		void GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,Gauss* gauss,int finiteelement);
+		void GetInputValue(IssmDouble* pp, IssmDouble* plist, Gauss* gauss);
+		void GetInputValue(IssmDouble* pp, IssmDouble* plist, Gauss* gauss,int finiteelement);
+		void GetInputDerivativeValue(IssmDouble* pp, IssmDouble* plist,IssmDouble* xyz_list, Gauss* gauss);
 
 		void NodeOnEdgeIndices(int* pnumindices,int** pindices,int index,int finiteelement);
Index: /issm/trunk/src/c/classes/ExternalResults/GenericExternalResult.h
===================================================================
--- /issm/trunk/src/c/classes/ExternalResults/GenericExternalResult.h	(revision 17805)
+++ /issm/trunk/src/c/classes/ExternalResults/GenericExternalResult.h	(revision 17806)
@@ -83,4 +83,14 @@
 		}
 		/*}}}*/
+		GenericExternalResult(int in_id, int in_enum_type,ResultType in_value,int in_step){ /*{{{*/
+			id        = in_id;
+			value     = in_value;
+			step      = in_step;
+			time      = UNDEF;
+
+			/*Convert enum to name*/
+			EnumToStringx(&this->result_name,in_enum_type);
+		}
+		/*}}}*/
 		GenericExternalResult(int in_id,const char* in_result_name,ResultType in_value,int in_step, IssmDouble in_time){ /*{{{*/
 			id        = in_id;
@@ -212,4 +222,16 @@
 
 } /*}}}*/
+template <> inline GenericExternalResult<char*>::GenericExternalResult(int in_id, int in_enum_type,char* in_value,int in_step){ /*{{{*/
+
+	id = in_id;
+	value = xNew<char>(strlen(in_value)+1);
+	xMemCpy<char>(value,in_value,(strlen(in_value)+1));
+	step  = in_step;
+	time  = UNDEF;
+
+	/*Convert enum to name*/
+	EnumToStringx(&this->result_name,in_enum_type);
+
+} /*}}}*/
 template <> inline GenericExternalResult<char*>::~GenericExternalResult(){ /*{{{*/
 	xDelete<char>(result_name);
@@ -346,4 +368,51 @@
 } /*}}}*/
 
+/*Specific instantiations for IssmDouble*: */
+#if defined(_HAVE_ADOLC_) && !defined(_WRAPPERS_)  //We hook off this specific specialization when not running ADOLC, otherwise we get a redeclaration with the next specialization. 
+template <> inline void GenericExternalResult<IssmDouble*>::WriteData(FILE* fid,bool io_gather){ /*{{{*/
+
+	int     i;
+	int     my_rank;
+	int     type;
+	int     rows,cols;
+	char   *name    = NULL;
+	IssmPDouble passiveDouble;
+	IssmPDouble* passiveDoubles;
+
+	/*recover my_rank:*/
+	my_rank=IssmComm::GetRank();
+
+	if(io_gather){
+		/*we are gathering the data on cpu 0, don't write on other cpus: */
+		if(my_rank) return;
+	}
+
+	/*First write enum: */
+	int length=(strlen(this->result_name)+1)*sizeof(char);
+	fwrite(&length,sizeof(int),1,fid);
+	fwrite(this->result_name,length,1,fid);
+
+	/*Now write time and step: */
+	passiveDouble=reCast<IssmPDouble>(time);
+	fwrite(&passiveDouble,sizeof(IssmPDouble),1,fid);
+	fwrite(&step,sizeof(int),1,fid);
+
+	/*writing a IssmDouble array, type is 3:*/
+	type=3;
+	fwrite(&type,sizeof(int),1,fid);
+	rows=this->M;
+	fwrite(&rows,sizeof(int),1,fid);
+	cols=this->N;
+	fwrite(&cols,sizeof(int),1,fid);
+
+	passiveDoubles=xNew<IssmPDouble>(this->M*this->N);
+	for (i=0;i<this->M*this->N;i++)passiveDoubles[i]=reCast<IssmPDouble>(value[i]);
+	fwrite(passiveDoubles,cols*rows*sizeof(IssmPDouble),1,fid);
+	xDelete<IssmPDouble>(passiveDoubles);
+
+}
+/*}}}*/
+#endif
+
 /*Specifics instantiations for Vector*/
 template <> inline GenericExternalResult<Vector<IssmPDouble>*>::GenericExternalResult(int in_id, int in_enum_type,Vector<IssmPDouble>* in_values, int in_M,int in_N,int in_step,IssmDouble in_time){/*{{{*/
@@ -383,4 +452,5 @@
 	return new GenericExternalResult<Vector<IssmPDouble>*>(this->id,StringToEnumx(this->result_name),this->value,this->step,this->time);
 } /*}}}*/
+#if defined(_HAVE_ADOLC_) && !defined(_WRAPPERS_)  //We hook off this specific specialization when not running ADOLC, otherwise we get a redeclaration with the next specialization. 
 template <> inline void GenericExternalResult<Vector<IssmPDouble>*>::WriteData(FILE* fid,bool io_gather){ /*{{{*/
 
@@ -420,4 +490,5 @@
 }
 /*}}}*/
+#endif
 template <> inline int GenericExternalResult<Vector<IssmPDouble>*>::ObjectEnum(void){ /*{{{*/
 	return NoneEnum;
@@ -425,3 +496,49 @@
 } /*}}}*/
 
+/*Specifics instantiations for Vector<IssmDouble>*/
+template <> inline void GenericExternalResult<Vector<IssmDouble>*>::WriteData(FILE* fid,bool io_gather){ /*{{{*/
+
+	int i;
+	char *name   = NULL;
+	int   length,rows,cols=1;
+	IssmDouble*  serialvalues = NULL;
+	IssmPDouble* pserialvalues = NULL;
+
+	if(!io_gather){
+		_error_("not supported yet");
+	}
+
+	/*Serialize vector*/
+	serialvalues = this->value->ToMPISerial();
+	this->value->GetSize(&rows);
+	
+	pserialvalues=xNew<IssmPDouble>(rows);
+	for(i=0;i<rows;i++)pserialvalues[i]=reCast<IssmPDouble>(serialvalues[i]);
+
+	if(IssmComm::GetRank()==0){
+		/*First write name: */
+		length=(strlen(this->result_name)+1)*sizeof(char);
+		fwrite(&length,sizeof(int),1,fid);
+		fwrite(this->result_name,length,1,fid);
+
+		/*Now write time and step: */
+		IssmPDouble passiveDouble=reCast<IssmPDouble>(time);
+		fwrite(&passiveDouble,sizeof(IssmPDouble),1,fid);
+		fwrite(&step,sizeof(int),1,fid);
+
+		/*writing a IssmDouble array, type is 3:*/
+		int type=3;
+		fwrite(&type,sizeof(int),1,fid);
+		fwrite(&rows,sizeof(int),1,fid);
+		fwrite(&cols,sizeof(int),1,fid);
+		fwrite(pserialvalues,cols*rows*sizeof(IssmPDouble),1,fid);
+	}
+
+	/*Clean up*/
+	xDelete<IssmPDouble>(pserialvalues);
+	xDelete<IssmDouble>(serialvalues);
+
+}
+/*}}}*/
+
 #endif  /* _EXTERNAL_RESULTOBJECT_H */
Index: /issm/trunk/src/c/classes/FemModel.cpp
===================================================================
--- /issm/trunk/src/c/classes/FemModel.cpp	(revision 17805)
+++ /issm/trunk/src/c/classes/FemModel.cpp	(revision 17806)
@@ -16,4 +16,6 @@
 #include "../shared/Enum/Enum.h"
 
+#include "../analyses/analyses.h"
+
 /*module includes: {{{*/
 #include "../modules/ModelProcessorx/ModelProcessorx.h"
@@ -22,5 +24,4 @@
 #include "../modules/ConfigureObjectsx/ConfigureObjectsx.h"
 #include "../modules/ParseToolkitsOptionsx/ParseToolkitsOptionsx.h"
-#include "../modules/OutputResultsx/OutputResultsx.h"
 #include "../modules/GetVectorFromInputsx/GetVectorFromInputsx.h"
 #include "../modules/InputUpdateFromVectorx/InputUpdateFromVectorx.h"
@@ -118,5 +119,5 @@
 	this->parameters->FindParam(&waitonlock,SettingsWaitonlockEnum);
 	this->parameters->FindParam(&lockfilename,LockFileNameEnum);
-	if (waitonlock>0){
+	if(waitonlock){
 		_printf0_("write lock file:\n");
 		WriteLockFile(lockfilename);
@@ -245,14 +246,4 @@
 	}
 /*}}}*/
-/*FUNCTION FemModel::OutputResults {{{*/
-void FemModel::OutputResults(void){
-
-	_printf0_("write results to disk:\n");
-
-	/*Just call the OutputResultsx module: */
-	OutputResultsx(this->elements, this->nodes, this->vertices, this->loads, this->materials, this->parameters,this->results);
-
-}
-/*}}}*/
 /*FUNCTION FemModel::SetStaticComm {{{*/
 void FemModel::SetStaticComm(void){
@@ -271,7 +262,7 @@
 	 * analyses. For example: do a SurfaceSlopeX, SurfaceSlopeY, BedSlopeX and BedSlopeY analysis using the 
 	 * Slope configuration.*/
-
 	int found=-1;
 	for(int i=0;i<nummodels;i++){
+	
 		if (analysis_type_list[i]==configuration_type){
 			found=i;
@@ -374,5 +365,5 @@
 	/*get vertex vectors for bed and thickness: */
 	GetVectorFromInputsx(&surface  ,this, SurfaceEnum,VertexEnum);
-	GetVectorFromInputsx(&bed      ,this, BedEnum,    VertexEnum);
+	GetVectorFromInputsx(&bed      ,this, BaseEnum,    VertexEnum);
 
 	/*Allocate vector*/
@@ -416,6 +407,10 @@
 
 	/*start module: */
-	if(VerboseModule()) _printf0_("   Updating constraints for time: " << time << "\n");
-
+	if(VerboseModule()) _printf0_("   Updating constraints and active domain of analysis " << EnumToStringx(analysis_type)  << " for time: " << time << "\n");
+
+	Analysis* analysis= EnumToAnalysis(analysis_type);
+	analysis->UpdateConstraints(this);
+	delete analysis;
+	
 	/*Second, constraints might be time dependent: */
 	SpcNodesx(nodes,constraints,parameters,analysis_type); 
@@ -437,5 +432,5 @@
 	switch (response_descriptor_enum){
 
-		#ifdef _HAVE_RESPONSES_
+		case DivergenceEnum:               this->Divergencex(responses); break;
 		case IceVolumeEnum:                this->IceVolumex(responses); break;
 		case IceVolumeAboveFloatationEnum: this->IceVolumeAboveFloatationx(responses); break;
@@ -452,5 +447,4 @@
 		case MaxAbsVzEnum:                 this->MaxAbsVzx(                responses); break;
 		case MassFluxEnum:                 this->MassFluxx(         responses); break;
-		#ifdef _HAVE_CONTROL_
 		case SurfaceAbsVelMisfitEnum:      SurfaceAbsVelMisfitx(responses, elements,nodes, vertices, loads, materials,parameters); break;
 		case SurfaceRelVelMisfitEnum:      SurfaceRelVelMisfitx(responses, elements,nodes, vertices, loads, materials,parameters); break;
@@ -465,21 +459,17 @@
 		case DragCoefficientAbsGradientEnum:DragCoefficientAbsGradientx(responses, elements,nodes, vertices, loads, materials, parameters); break;
 		case BalancethicknessMisfitEnum:   BalancethicknessMisfitx(responses); break;
-		#endif
 		case TotalSmbEnum:					  this->TotalSmbx(responses); break;
 		case MaterialsRheologyBbarEnum:    this->ElementResponsex(responses,MaterialsRheologyBbarEnum); break;
 		case VelEnum:                      this->ElementResponsex(responses,VelEnum); break;
 		case FrictionCoefficientEnum:      NodalValuex(responses, FrictionCoefficientEnum,elements,nodes, vertices, loads, materials, parameters); break;
-		default: _error_("response descriptor \"" << EnumToStringx(response_descriptor_enum) << "\" not supported yet!"); break;
-		#else
-		default: _error_("ISSM was not compiled with responses capabilities, exiting!");
-		#endif
-	}
-
-}
-/*}}}*/
-void FemModel::RequestedOutputsx(Results **presults,char** requested_outputs, int numoutputs){/*{{{*/
+		default: _error_("response descriptor \"" << EnumToStringx(response_descriptor_enum) << "\" not supported yet!"); break; 
+	}
+
+}
+/*}}}*/
+void FemModel::RequestedOutputsx(Results **presults,char** requested_outputs, int numoutputs, bool save_results){/*{{{*/
 
 	/*Intermediaries*/
-	bool        isvec;
+	bool        isvec,results_on_nodes;
 	int         step,output_enum;
 	IssmDouble  time;
@@ -494,4 +484,5 @@
 	parameters->FindParam(&step,StepEnum);
 	parameters->FindParam(&time,TimeEnum);
+	parameters->FindParam(&results_on_nodes,SettingsResultsOnNodesEnum);
 
 	/*Go through all requested output*/
@@ -505,10 +496,14 @@
 		if(output_enum<0){
 			double_result = OutputDefinitionsResponsex(this,output_string);
+			if(save_results){
+				results->AddResult(new GenericExternalResult<IssmPDouble>(results->Size()+1,output_string,reCast<IssmPDouble>(double_result),step,time));
+				continue;
+			}
 		}
 		else{
 			switch(output_enum){
 
-				#ifdef _HAVE_RESPONSES_
 				/*Scalar output*/
+				case DivergenceEnum:               this->Divergencex(&double_result);               break;
 				case IceVolumeEnum:                this->IceVolumex(&double_result);                break;
 				case IceVolumeAboveFloatationEnum: this->IceVolumeAboveFloatationx(&double_result); break;
@@ -528,5 +523,4 @@
 
 			   /*Scalar control output*/
-				#ifdef _HAVE_CONTROL_
 				case SurfaceAbsVelMisfitEnum:       SurfaceAbsVelMisfitx(&double_result,elements,nodes,vertices,loads,materials,parameters);        break;
 				case SurfaceRelVelMisfitEnum:       SurfaceRelVelMisfitx(&double_result,elements,nodes,vertices,loads,materials,parameters);        break;
@@ -541,5 +535,4 @@
 				case DragCoefficientAbsGradientEnum:DragCoefficientAbsGradientx(&double_result,elements,nodes,vertices,loads,materials,parameters); break;
 				case BalancethicknessMisfitEnum:    BalancethicknessMisfitx(&double_result);                                                        break;
-				#endif
 
 			   /*Vector */
@@ -547,40 +540,60 @@
 
 					/*Vector layout*/
-					int interpolation,size;
+					int interpolation,nodesperelement,size;
 
 					/*Get interpolation (and compute input if necessary)*/
 					for(int j=0;j<elements->Size();j++){
 						Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(j));
-						element->ResultInterpolation(&interpolation,output_enum);
+						element->ResultInterpolation(&interpolation,&nodesperelement,output_enum);
 					}
 
-					/*Allocate vector depending on interpolation*/
-					switch(interpolation){
-						case P0Enum: size = this->elements->NumberOfElements(); break;
-						case P1Enum: size = this->vertices->NumberOfVertices(); break;
-						default:     _error_("Interpolation "<<EnumToStringx(interpolation)<<" not supported yet");
+					if(results_on_nodes){
+
+						/*Allocate matrices*/
+						int         nbe       = this->elements->NumberOfElements();
+						IssmDouble* values    = xNewZeroInit<IssmDouble>(nbe*nodesperelement);
+						IssmDouble* allvalues = xNew<IssmDouble>(nbe*nodesperelement);
+
+						/*Fill-in matrix*/
+						for(int j=0;j<elements->Size();j++){
+							Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(j));
+							element->ResultToPatch(values,nodesperelement,output_enum);
+						}
+
+						/*Gather from all cpus*/
+						ISSM_MPI_Allreduce((void*)values,(void*)allvalues,nbe*nodesperelement,ISSM_MPI_PDOUBLE,ISSM_MPI_SUM,IssmComm::GetComm());
+						xDelete<IssmDouble>(values);
+
+						if(save_results)results->AddResult(new GenericExternalResult<IssmDouble*>(results->Size()+1,output_enum,allvalues,nbe,nodesperelement,step,time));
+						xDelete<IssmDouble>(allvalues);
 
 					}
-					Vector<IssmPDouble> *vector_result = new Vector<IssmPDouble>(this->vertices->NumberOfVertices());
-
-					/*Fill in vector*/
-					for(int j=0;j<elements->Size();j++){
-						Element* element=(Element*)elements->GetObjectByOffset(j);
-						element->ResultToVector(vector_result,output_enum);
+					else{
+
+						/*Allocate vector depending on interpolation*/
+						switch(interpolation){
+							case P0Enum: size = this->elements->NumberOfElements(); break;
+							case P1Enum: size = this->vertices->NumberOfVertices(); break;
+							default:     _error_("Interpolation "<<EnumToStringx(interpolation)<<" not supported yet");
+
+						}
+						Vector<IssmDouble> *vector_result = new Vector<IssmDouble>(size);
+
+						/*Fill in vector*/
+						for(int j=0;j<elements->Size();j++){
+							Element* element=(Element*)elements->GetObjectByOffset(j);
+							element->ResultToVector(vector_result,output_enum);
+						}
+						vector_result->Assemble();
+
+						if(save_results)results->AddResult(new GenericExternalResult<Vector<IssmDouble>*>(results->Size()+1,output_enum,vector_result,step,time));
 					}
-					vector_result->Assemble();
-
-					results->AddResult(new GenericExternalResult<Vector<IssmPDouble>*>(results->Size()+1,output_enum,vector_result,step,time));
 					isvec = true;
 					break;
-
-				#else
-				default: _error_("ISSM was not compiled with responses capabilities, exiting!");
-				#endif
 			}
 		}
 
 		/*Add result to Results*/
-		if(!isvec){
+		if(!isvec && save_results){
 			results->AddResult(new GenericExternalResult<IssmPDouble>(results->Size()+1,output_string,reCast<IssmPDouble>(double_result),step,time));
 		}
@@ -591,5 +604,5 @@
 }
 /*}}}*/
-void FemModel::RequestedOutputsx(Results **presults,int* requested_outputs, int numoutputs){/*{{{*/
+void FemModel::RequestedOutputsx(Results **presults,int* requested_outputs, int numoutputs,bool save_results){/*{{{*/
 
 	/*Convert list of enums to list of string*/
@@ -600,5 +613,5 @@
 
 	/*Call main module*/
-	this->RequestedOutputsx(presults,enumlist,numoutputs);
+	this->RequestedOutputsx(presults,enumlist,numoutputs,save_results);
 
 	/*clean up and return*/
@@ -693,5 +706,4 @@
 }
 /*}}}*/
-#ifdef _HAVE_RESPONSES_
 void FemModel::MassFluxx(IssmDouble* pmass_flux){/*{{{*/
 
@@ -1032,4 +1044,20 @@
 
 }/*}}}*/
+void FemModel::Divergencex(IssmDouble* pdiv){/*{{{*/
+
+	IssmDouble local_divergence=0;
+	IssmDouble total_divergence;
+
+	for(int i=0;i<this->elements->Size();i++){
+		Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i));
+		local_divergence+=element->Divergence();
+	}
+	ISSM_MPI_Reduce(&local_divergence,&total_divergence,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
+	ISSM_MPI_Bcast(&total_divergence,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
+
+	/*Assign output pointers: */
+	*pdiv=total_divergence;
+
+}/*}}}*/
 void FemModel::IceVolumex(IssmDouble* pV){/*{{{*/
 
@@ -1104,6 +1132,4 @@
 
 }/*}}}*/
-#endif
-#ifdef _HAVE_CONTROL_
 void FemModel::BalancethicknessMisfitx(IssmDouble* presponse){/*{{{*/
 
@@ -1228,5 +1254,4 @@
 }
 /*}}}*/
-#endif
 #ifdef  _HAVE_DAKOTA_
 void FemModel::DakotaResponsesx(double* d_responses,char** responses_descriptors,int numresponsedescriptors,int d_numresponses){/*{{{*/
@@ -1341,5 +1366,4 @@
 /*}}}*/
 #endif
-#ifdef _HAVE_HYDROLOGY_
 void FemModel::HydrologyEPLupdateDomainx(void){ /*{{{*/
 
@@ -1348,10 +1372,12 @@
 	Vector<IssmDouble>* active        = NULL;
 	IssmDouble*         serial_active = NULL;
-
-	/*Step 1: update maks, the mask might be extended by residual and/or using downstream sediment head*/
+	
+	HydrologyDCEfficientAnalysis* effanalysis =  new HydrologyDCEfficientAnalysis();
+	/*Step 1: update mask, the mask might be extended by residual and/or using downstream sediment head*/
 	mask=new Vector<IssmDouble>(nodes->NumberOfNodes(HydrologyDCEfficientAnalysisEnum));
+
 	for (int i=0;i<elements->Size();i++){
 		Element* element=dynamic_cast<Element*>(elements->GetObjectByOffset(i));
-		element->HydrologyEPLGetMask(mask);
+		effanalysis->HydrologyEPLGetMask(mask,element);
 	}
 
@@ -1362,5 +1388,5 @@
 
 	/*Update Mask*/
-	InputUpdateFromVectorx(this,serial_mask,HydrologydcMaskEplactiveEnum,NodeSIdEnum);
+	InputUpdateFromVectorx(this,serial_mask,HydrologydcMaskEplactiveNodeEnum,NodeSIdEnum);
 	xDelete<IssmDouble>(serial_mask);
 
@@ -1369,5 +1395,5 @@
 	for (int i=0;i<elements->Size();i++){
 		Element* element=dynamic_cast<Element*>(elements->GetObjectByOffset(i));
-		element->HydrologyEPLGetActive(active);
+		effanalysis->HydrologyEPLGetActive(active,element);
 	}
 
@@ -1392,4 +1418,5 @@
 	}
 	xDelete<IssmDouble>(serial_active);
+	delete effanalysis;
 	int sum_counter;
 	ISSM_MPI_Reduce(&counter,&sum_counter,1,ISSM_MPI_INT,ISSM_MPI_SUM,0,IssmComm::GetComm() );
@@ -1403,22 +1430,46 @@
 }
 /*}}}*/
-void FemModel::HydrologyTransferx(void){ /*{{{*/
-
-	Vector<IssmDouble>* transferg=NULL; 
-
-	/*Vector allocation*/
-	transferg=new Vector<IssmDouble>(nodes->NumberOfNodes());
-
+void FemModel::UpdateConstraintsL2ProjectionEPLx(void){ /*{{{*/
+
+	Vector<IssmDouble>* active        = NULL;
+	IssmDouble*         serial_active = NULL;
+	HydrologyDCEfficientAnalysis* effanalysis = new HydrologyDCEfficientAnalysis();
+
+	/*update node activity. If one element is connected to mask=1, all nodes are active*/
+	active=new Vector<IssmDouble>(nodes->NumberOfNodes(HydrologyDCEfficientAnalysisEnum));
 	for (int i=0;i<elements->Size();i++){
 		Element* element=dynamic_cast<Element*>(elements->GetObjectByOffset(i));
-		element->GetHydrologyTransfer(transferg);
-	}
-	/*Assemble*/
-	transferg->Assemble();
-
-	/*Update Inputs*/
-	InputUpdateFromVectorx(this,transferg,WaterTransferEnum,NodesEnum);
-	delete transferg;
-}
-/*}}}*/
-#endif
+		effanalysis->HydrologyEPLGetActive(active,element);
+	}
+
+	/*Assemble and serialize*/
+	active->Assemble();
+	serial_active=active->ToMPISerial();
+	delete active;
+	delete effanalysis;
+
+	/*Update node activation accordingly*/
+	int counter =0;
+	for (int i=0;i<nodes->Size();i++){
+		Node* node=dynamic_cast<Node*>(nodes->GetObjectByOffset(i));
+		if(node->InAnalysis(L2ProjectionEPLAnalysisEnum)){
+			if(serial_active[node->Sid()]==1.){
+				node->Activate();
+				counter++;
+			}
+			else{
+				node->Deactivate();
+			}
+		}
+	}
+	xDelete<IssmDouble>(serial_active);
+	int sum_counter;
+	ISSM_MPI_Reduce(&counter,&sum_counter,1,ISSM_MPI_INT,ISSM_MPI_SUM,0,IssmComm::GetComm() );
+	ISSM_MPI_Bcast(&sum_counter,1,ISSM_MPI_INT,0,IssmComm::GetComm());                
+	counter=sum_counter;
+	if(VerboseSolution()) _printf0_("   Number of active nodes L2 Projection: "<< counter <<"\n");
+
+	/*Update dof indexings*/
+	this->UpdateConstraintsx();
+}
+/*}}}*/
Index: /issm/trunk/src/c/classes/FemModel.h
===================================================================
--- /issm/trunk/src/c/classes/FemModel.h	(revision 17805)
+++ /issm/trunk/src/c/classes/FemModel.h	(revision 17806)
@@ -54,5 +54,4 @@
 		void InitFromFiles(char* rootpath, char* inputfilename, char* outputfilename, char* petscfilename, char* lockfilename, const int solution_type,const int* analyses,const int nummodels);
 		void Solve(void);
-		void OutputResults(void);
 		void SetStaticComm();
 		void SetCurrentConfiguration(int configuration_type);
@@ -60,5 +59,4 @@
 
 		/*Modules*/ 
-		#ifdef _HAVE_RESPONSES_
 		void MassFluxx(IssmDouble* presponse);
 		void MaxAbsVxx(IssmDouble* presponse);
@@ -74,22 +72,20 @@
 		void MinVzx(IssmDouble* presponse);
 		void TotalSmbx(IssmDouble* pSmb);
+		void Divergencex(IssmDouble* pdiv);
 		void IceVolumex(IssmDouble* pV);
 		void IceVolumeAboveFloatationx(IssmDouble* pV);
 		void ElementResponsex(IssmDouble* presponse,int response_enum);
 		void BalancethicknessMisfitx(IssmDouble* pV);
-		#endif
 		#ifdef  _HAVE_DAKOTA_
 		void DakotaResponsesx(double* d_responses,char** responses_descriptors,int numresponsedescriptors,int d_numresponses);
 		#endif
-		void RequestedOutputsx(Results **presults,char** requested_outputs, int numoutputs);
-		void RequestedOutputsx(Results **presults,int* requested_outputs, int numoutputs);
+		void RequestedOutputsx(Results **presults,char** requested_outputs, int numoutputs,bool save_results=true);
+		void RequestedOutputsx(Results **presults,int* requested_outputs, int numoutputs,bool save_results=true);
 		void RequestedDependentsx(void);
 		void Responsex(IssmDouble* presponse,int response_descriptor_enum);
 		void Responsex(IssmDouble* presponse,const char* response_descriptor);
-		#ifdef _HAVE_CONTROL_
 		void OutputControlsx(Results **presults);
 		void CostFunctionx( IssmDouble* pJ);
 		void ThicknessAbsGradientx( IssmDouble* pJ);
-		#endif
 		#ifdef _HAVE_GIA_
 		void Deflection(Vector<IssmDouble>* wg,Vector<IssmDouble>* dwgdt, IssmDouble* x, IssmDouble* y);
@@ -100,8 +96,7 @@
 		void UpdateConstraintsExtrudeFromBasex();
 		void UpdateConstraintsExtrudeFromTopx();
-		#ifdef _HAVE_HYDROLOGY_
-		void HydrologyTransferx(void);
 		void HydrologyEPLupdateDomainx(void);
-		#endif
+		//		void HydrologyEPLThicknessx(void);
+		void UpdateConstraintsL2ProjectionEPLx(void);
 };
 
Index: /issm/trunk/src/c/classes/Inputs/BoolInput.cpp
===================================================================
--- /issm/trunk/src/c/classes/Inputs/BoolInput.cpp	(revision 17805)
+++ /issm/trunk/src/c/classes/Inputs/BoolInput.cpp	(revision 17806)
@@ -40,7 +40,5 @@
 void BoolInput::DeepEcho(void){
 
-	_printf_("BoolInput:\n");
-	_printf_("   enum: " << this->enum_type << " (" << EnumToStringx(this->enum_type) << ")\n");
-	_printf_("   value: " <<(value?"true":"false") << "\n");
+	_printf_(setw(15)<<"   BoolInput "<<setw(25)<<left<<EnumToStringx(this->enum_type)<<" "<<(value?"true":"false") << "\n");
 }
 /*}}}*/
@@ -72,5 +70,5 @@
 /*}}}*/
 /*FUNCTION BoolInput::SpawnTriaInput{{{*/
-Input* BoolInput::SpawnTriaInput(int location){
+Input* BoolInput::SpawnTriaInput(int index1,int index2,int index3){
 
 		/*output*/
@@ -114,15 +112,6 @@
 void BoolInput::GetInputValue(IssmDouble* pvalue){_error_("not supported yet!");}
 /*}}}*/
-/*FUNCTION BoolInput::GetInputValue(IssmDouble* pvalue,GaussTria* gauss){{{*/
-void BoolInput::GetInputValue(IssmDouble* pvalue,GaussTria* gauss){_error_("not supported yet!");}
-/*}}}*/
-/*FUNCTION BoolInput::GetInputValue(IssmDouble* pvalue,GaussPenta* gauss){{{*/
-void BoolInput::GetInputValue(IssmDouble* pvalue,GaussPenta* gauss){_error_("not supported yet!");}
-/*}}}*/
-/*FUNCTION BoolInput::GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussTria* gauss){{{*/
-void BoolInput::GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussTria* gauss){_error_("not supported yet!");}
-/*}}}*/
-/*FUNCTION BoolInput::GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussPenta* gauss){{{*/
-void BoolInput::GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussPenta* gauss){_error_("not supported yet!");}
+/*FUNCTION BoolInput::GetInputValue(IssmDouble* pvalue,Gauss* gauss){{{*/
+void BoolInput::GetInputValue(IssmDouble* pvalue,Gauss* gauss){_error_("not supported yet!");}
 /*}}}*/
 /*FUNCTION BoolInput::ChangeEnum{{{*/
Index: /issm/trunk/src/c/classes/Inputs/BoolInput.h
===================================================================
--- /issm/trunk/src/c/classes/Inputs/BoolInput.h	(revision 17805)
+++ /issm/trunk/src/c/classes/Inputs/BoolInput.h	(revision 17806)
@@ -7,9 +7,5 @@
 
 /*Headers:*/
-/*{{{*/
 #include "./Input.h"
-class GaussTria;
-class GaussPenta;
-/*}}}*/
 
 class BoolInput: public Input{
@@ -34,5 +30,5 @@
 		/*BoolInput management: {{{*/
 		int   InstanceEnum();
-		Input* SpawnTriaInput(int location);
+		Input* SpawnTriaInput(int index1,int index2,int index3);
 		Input* SpawnSegInput(int index1,int index2);
 		Input* PointwiseDivide(Input* inputB){_error_("not implemented yet");};
@@ -40,4 +36,6 @@
 		Input* PointwiseMax(Input* inputB){_error_("not implemented yet");};
 		int  GetResultInterpolation(void){return P0Enum;};
+		int  GetResultNumberOfNodes(void){return 1;};
+		void ResultToPatch(IssmDouble* values,int nodesperelement,int sid){_error_("not supported yet");};
 		void Configure(Parameters* parameters);
 		void AddTimeValues(IssmDouble* values,int step,IssmDouble time){_error_("not supported yet");};
@@ -47,24 +45,11 @@
 		void GetInputValue(int* pvalue);
 		void GetInputValue(IssmDouble* pvalue);
-		void GetInputValue(IssmDouble* pvalue,GaussSeg* gauss){_error_("not implemented yet");};
-		void GetInputValue(IssmDouble* pvalue,GaussTria* gauss);
-		void GetInputValue(IssmDouble* pvalue,GaussPenta* gauss);
-		void GetInputValue(IssmDouble* pvalue,GaussTria* gauss,IssmDouble time){_error_("not implemented yet");};
-		void GetInputValue(IssmDouble* pvalue,GaussPenta* gauss,IssmDouble time){_error_("not implemented yet");};
-		void GetInputValue(IssmDouble* pvalue,GaussTria* gauss ,int index){_error_("not implemented yet");};
-		void GetInputValue(IssmDouble* pvalue,GaussPenta* gauss ,int index){_error_("not implemented yet");};
-		void GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussSeg* gauss){_error_("not implemented yet");};
-		void GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussTria* gauss);
-		void GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussPenta* gauss);
+		void GetInputValue(IssmDouble* pvalue,Gauss* gauss);
+		void GetInputValue(IssmDouble* pvalue,Gauss* gauss,IssmDouble time){_error_("not implemented yet");};
+		void GetInputValue(IssmDouble* pvalue,Gauss* gauss ,int index){_error_("not implemented yet");};
+		void GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, Gauss* gauss){_error_("not implemented yet");};
 		void GetInputAverage(IssmDouble* pvalue){_error_("not implemented yet");};
 		void GetInputAllTimeAverages(IssmDouble** pvalues,IssmDouble** ptimes, int* pnumtimes){_error_("not implemented yet");};
 		void GetInputUpToCurrentTimeAverages(IssmDouble** pvalues, IssmDouble** ptimes, int* pnumtimes, IssmDouble currenttime){_error_("not implemented yet");};
-		void GetVxStrainRate2d(IssmDouble* epsilonvx,IssmDouble* xyz_list, GaussTria* gauss){_error_("not implemented yet");};
-		void GetVyStrainRate2d(IssmDouble* epsilonvy,IssmDouble* xyz_list, GaussTria* gauss){_error_("not implemented yet");};
-		void GetVxStrainRate3d(IssmDouble* epsilonvx,IssmDouble* xyz_list, GaussPenta* gauss){_error_("not implemented yet");};
-		void GetVyStrainRate3d(IssmDouble* epsilonvy,IssmDouble* xyz_list, GaussPenta* gauss){_error_("not implemented yet");};
-		void GetVzStrainRate3d(IssmDouble* epsilonvz,IssmDouble* xyz_list, GaussPenta* gauss){_error_("not implemented yet");};
-		void GetVxStrainRate3dHO(IssmDouble* epsilonvx,IssmDouble* xyz_list, GaussPenta* gauss){_error_("not implemented yet");};
-		void GetVyStrainRate3dHO(IssmDouble* epsilonvy,IssmDouble* xyz_list, GaussPenta* gauss){_error_("not implemented yet");};
 		void ChangeEnum(int newenumtype);
 		void SquareMin(IssmDouble* psquaremin, Parameters* parameters);
Index: /issm/trunk/src/c/classes/Inputs/ControlInput.cpp
===================================================================
--- /issm/trunk/src/c/classes/Inputs/ControlInput.cpp	(revision 17805)
+++ /issm/trunk/src/c/classes/Inputs/ControlInput.cpp	(revision 17806)
@@ -68,5 +68,5 @@
 
 	_printf_("ControlInput:\n");
-	_printf_("   enum: " << this->enum_type << " (" << EnumToStringx(this->enum_type) << ")\n");
+	_printf_(setw(15)<<"   ControlInput "<<setw(25)<<left<<EnumToStringx(this->enum_type)<<"\n");
 	_printf_("---values: \n");     if (values)      values->Echo();
 	_printf_("---savedvalues: \n");if (savedvalues) savedvalues->Echo();
@@ -146,4 +146,11 @@
 }
 /*}}}*/
+/*FUNCTION ControlInput::GetResultNumberOfNodes{{{*/
+int  ControlInput::GetResultNumberOfNodes(void){
+
+	return values->GetResultNumberOfNodes();
+
+}
+/*}}}*/
 /*FUNCTION ControlInput::GetGradient{{{*/
 void ControlInput::GetGradient(Vector<IssmDouble>* gradient_vec,int* doflist){
@@ -186,6 +193,6 @@
 }/*}}}*/
 /*FUNCTION ControlInput::SpawnTriaInput{{{*/
-Input* ControlInput::SpawnTriaInput(int location){
-	return values->SpawnTriaInput(location);
+Input* ControlInput::SpawnTriaInput(int index1,int index2,int index3){
+	return values->SpawnTriaInput(index1,index2,index3);
 }/*}}}*/
 /*FUNCTION ControlInput::SpawnSegInput{{{*/
@@ -235,26 +242,14 @@
 	values->GetInputValue(pvalue);
 }/*}}}*/
-/*FUNCTION ControlInput::GetInputValue(IssmDouble* pvalue){{{*/
-void ControlInput::GetInputValue(IssmDouble* pvalue,GaussTria* gauss){
+/*FUNCTION ControlInput::GetInputValue(IssmDouble* pvalue,Gauss* gauss){{{*/
+void ControlInput::GetInputValue(IssmDouble* pvalue,Gauss* gauss){
 	values->GetInputValue(pvalue,gauss);
 }/*}}}*/
-/*FUNCTION ControlInput::GetInputValue(IssmDouble* pvalue){{{*/
-void ControlInput::GetInputValue(IssmDouble* pvalue,GaussPenta* gauss){
-	values->GetInputValue(pvalue,gauss);
-}/*}}}*/
-/*FUNCTION ControlInput::GetGradientValue(IssmDouble* pvalue,GaussTria* gauss){{{*/
-void ControlInput::GetGradientValue(IssmDouble* pvalue,GaussTria* gauss){
+/*FUNCTION ControlInput::GetGradientValue{{{*/
+void ControlInput::GetGradientValue(IssmDouble* pvalue,Gauss* gauss){
 	gradient->GetInputValue(pvalue,gauss);
 }/*}}}*/
-/*FUNCTION ControlInput::GetGradientValue(IssmDouble* pvalue,GaussPenta* gauss){{{*/
-void ControlInput::GetGradientValue(IssmDouble* pvalue,GaussPenta* gauss){
-	gradient->GetInputValue(pvalue,gauss);
-}/*}}}*/
-/*FUNCTION ControlInput::GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussTria* gauss){{{*/
-void ControlInput::GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussTria* gauss){
-	values->GetInputDerivativeValue(derivativevalues,xyz_list,gauss);
-}/*}}}*/
-/*FUNCTION ControlInput::GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussPenta* gauss){{{*/
-void ControlInput::GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussPenta* gauss){
+/*FUNCTION ControlInput::GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, Gauss* gauss){{{*/
+void ControlInput::GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, Gauss* gauss){
 	values->GetInputDerivativeValue(derivativevalues,xyz_list,gauss);
 }/*}}}*/
Index: /issm/trunk/src/c/classes/Inputs/ControlInput.h
===================================================================
--- /issm/trunk/src/c/classes/Inputs/ControlInput.h	(revision 17805)
+++ /issm/trunk/src/c/classes/Inputs/ControlInput.h	(revision 17806)
@@ -9,6 +9,6 @@
 /*{{{*/
 #include "./Input.h"
-class GaussTria;
-class GaussPenta;
+class Gauss;
+class Gauss;
 /*}}}*/
 
@@ -38,5 +38,5 @@
 		/*ControlInput management: {{{*/
 		int    InstanceEnum();
-		Input* SpawnTriaInput(int location);
+		Input* SpawnTriaInput(int index1,int index2,int index3);
 		Input* SpawnSegInput(int index1,int index2);
 		Input* PointwiseDivide(Input* inputB){_error_("not implemented yet");};
@@ -47,30 +47,16 @@
 		/*}}}*/
 		/*numerics: {{{*/
-		void GetGradientValue(IssmDouble* pvalue,GaussTria* gauss);
-		void GetGradientValue(IssmDouble* pvalue,GaussPenta* gauss);
+		void GetGradientValue(IssmDouble* pvalue,Gauss* gauss);
 		void SetInput(Input* in_input);
 		void GetInputValue(bool* pvalue);
 		void GetInputValue(int* pvalue);
 		void GetInputValue(IssmDouble* pvalue);
-		void GetInputValue(IssmDouble* pvalue,GaussSeg* gauss){_error_("not implemented yet");};
-		void GetInputValue(IssmDouble* pvalue,GaussTria* gauss);
-		void GetInputValue(IssmDouble* pvalue,GaussPenta* gauss);
-		void GetInputValue(IssmDouble* pvalue,GaussTria* gauss,IssmDouble time){_error_("not implemented yet");};
-		void GetInputValue(IssmDouble* pvalue,GaussPenta* gauss,IssmDouble time){_error_("not implemented yet");};
-		void GetInputValue(IssmDouble* pvalue,GaussTria* gauss ,int index){_error_("not implemented yet");};
-		void GetInputValue(IssmDouble* pvalue,GaussPenta* gauss ,int index){_error_("not implemented yet");};
-		void GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussSeg* gauss){_error_("not implemented yet");};
-		void GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussTria* gauss);
-		void GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussPenta* gauss);
+		void GetInputValue(IssmDouble* pvalue,Gauss* gauss);
+		void GetInputValue(IssmDouble* pvalue,Gauss* gauss,IssmDouble time){_error_("not implemented yet");};
+		void GetInputValue(IssmDouble* pvalue,Gauss* gauss ,int index){_error_("not implemented yet");};
+		void GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list,Gauss* gauss);
 		void GetInputAverage(IssmDouble* pvalue);
 		void GetInputAllTimeAverages(IssmDouble** pvalues,IssmDouble** ptimes, int* pnumtimes){_error_("not implemented yet");};
 		void GetInputUpToCurrentTimeAverages(IssmDouble** pvalues, IssmDouble** ptimes, int* pnumtimes, IssmDouble currenttime){_error_("not implemented yet");};
-		void GetVxStrainRate2d(IssmDouble* epsilonvx,IssmDouble* xyz_list, GaussTria* gauss){_error_("not implemented yet");};
-		void GetVyStrainRate2d(IssmDouble* epsilonvy,IssmDouble* xyz_list, GaussTria* gauss){_error_("not implemented yet");};
-		void GetVxStrainRate3d(IssmDouble* epsilonvx,IssmDouble* xyz_list, GaussPenta* gauss){_error_("not implemented yet");};
-		void GetVyStrainRate3d(IssmDouble* epsilonvy,IssmDouble* xyz_list, GaussPenta* gauss){_error_("not implemented yet");};
-		void GetVzStrainRate3d(IssmDouble* epsilonvz,IssmDouble* xyz_list, GaussPenta* gauss){_error_("not implemented yet");};
-		void GetVxStrainRate3dHO(IssmDouble* epsilonvx,IssmDouble* xyz_list, GaussPenta* gauss){_error_("not implemented yet");};
-		void GetVyStrainRate3dHO(IssmDouble* epsilonvy,IssmDouble* xyz_list, GaussPenta* gauss){_error_("not implemented yet");};
 		void ChangeEnum(int newenumtype){_error_("not implemented yet");};
 		void SquareMin(IssmDouble* psquaremin,Parameters* parameters){_error_("not implemented yet");};
@@ -91,4 +77,6 @@
 		void GetVectorFromInputs(Vector<IssmDouble>* vector,int* doflist);
 		int  GetResultInterpolation(void);
+		int  GetResultNumberOfNodes(void);
+		void ResultToPatch(IssmDouble* values,int nodesperelement,int sid){_error_("not supported yet");};
 		void GetGradient(Vector<IssmDouble>* gradient_vec,int* doflist);
 		void ScaleGradient(IssmDouble scale);
Index: /issm/trunk/src/c/classes/Inputs/DatasetInput.cpp
===================================================================
--- /issm/trunk/src/c/classes/Inputs/DatasetInput.cpp	(revision 17805)
+++ /issm/trunk/src/c/classes/Inputs/DatasetInput.cpp	(revision 17806)
@@ -79,5 +79,5 @@
 /*}}}*/
 /*FUNCTION DatasetInput::SpawnTriaInput{{{*/
-Input* DatasetInput::SpawnTriaInput(int location){
+Input* DatasetInput::SpawnTriaInput(int index1,int index2,int index3){
 
 	/*output*/
@@ -87,5 +87,5 @@
 	outinput=new DatasetInput();
 	outinput->enum_type=this->enum_type;
-	outinput->inputs=dynamic_cast<Inputs*>(this->inputs->SpawnTriaInputs(location));
+	outinput->inputs=dynamic_cast<Inputs*>(this->inputs->SpawnTriaInputs(index1,index2,index3));
 	outinput->numids=this->numids;
 	outinput->ids=xNew<int>(this->numids);
@@ -158,6 +158,6 @@
 }
 /*}}}*/
-/*FUNCTION DatasetInput::GetInputValue(IssmDouble* pvalue,GaussTria* gauss,int id){{{*/
-void DatasetInput::GetInputValue(IssmDouble* pvalue,GaussTria* gauss,int id){
+/*FUNCTION DatasetInput::GetInputValue(IssmDouble* pvalue,Gauss* gauss,int id){{{*/
+void DatasetInput::GetInputValue(IssmDouble* pvalue,Gauss* gauss,int id){
 
 	int  offset = -1;
@@ -172,16 +172,2 @@
 }
 /*}}}*/
-/*FUNCTION DatasetInput::GetInputValue(IssmDouble* pvalue,GaussPenta* gauss,int id){{{*/
-void DatasetInput::GetInputValue(IssmDouble* pvalue,GaussPenta* gauss,int id){
-
-	int  offset = -1;
-	_assert_(this->numids == this->inputs->Size());
-
-	/*Get requested input within dataset*/
-	for(int i=0;i<this->numids;i++) if(this->ids[i]==id) offset=i;
-	if(offset<0) _error_("Could not find input of id "<<id);
-
-	Input* input=dynamic_cast<Input*>(this->inputs->GetObjectByOffset(offset));
-	input->GetInputValue(pvalue,gauss);
-}
-/*}}}*/
Index: /issm/trunk/src/c/classes/Inputs/DatasetInput.h
===================================================================
--- /issm/trunk/src/c/classes/Inputs/DatasetInput.h	(revision 17805)
+++ /issm/trunk/src/c/classes/Inputs/DatasetInput.h	(revision 17806)
@@ -9,6 +9,6 @@
 /*{{{*/
 #include "./Input.h"
-class GaussTria;
-class GaussPenta;
+class Gauss;
+class Gauss;
 /*}}}*/
 
@@ -36,5 +36,5 @@
 		void   AddInput(Input* input,int id);
 		int    InstanceEnum();
-		Input* SpawnTriaInput(int location);
+		Input* SpawnTriaInput(int index1,int index2,int index3);
 		Input* SpawnSegInput(int index1,int index2);
 		Input* PointwiseDivide(Input* inputB){_error_("not implemented yet");};
@@ -48,24 +48,11 @@
 		void GetInputValue(int* pvalue){_error_("not implemented yet");};
 		void GetInputValue(IssmDouble* pvalue){_error_("not implemented yet");};
-		void GetInputValue(IssmDouble* pvalue,GaussSeg* gauss){_error_("not implemented yet");};
-		void GetInputValue(IssmDouble* pvalue,GaussTria* gauss){_error_("not implemented yet");};
-		void GetInputValue(IssmDouble* pvalue,GaussPenta* gauss){_error_("not implemented yet");};
-		void GetInputValue(IssmDouble* pvalue,GaussTria* gauss,IssmDouble time){_error_("not implemented yet");};
-		void GetInputValue(IssmDouble* pvalue,GaussPenta* gauss,IssmDouble time){_error_("not implemented yet");};
-		void GetInputValue(IssmDouble* pvalue,GaussTria* gauss ,int index);
-		void GetInputValue(IssmDouble* pvalue,GaussPenta* gauss ,int index);
-		void GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussSeg* gauss){_error_("not implemented yet");};
-		void GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussTria* gauss){_error_("not implemented yet");};
-		void GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussPenta* gauss){_error_("not implemented yet");};
+		void GetInputValue(IssmDouble* pvalue,Gauss* gauss){_error_("not implemented yet");};
+		void GetInputValue(IssmDouble* pvalue,Gauss* gauss,IssmDouble time){_error_("not implemented yet");};
+		void GetInputValue(IssmDouble* pvalue,Gauss* gauss ,int index);
+		void GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list,Gauss* gauss){_error_("not implemented yet");};
 		void GetInputAverage(IssmDouble* pvalue){_error_("not implemented yet");};
 		void GetInputAllTimeAverages(IssmDouble** pvalues,IssmDouble** ptimes, int* pnumtimes){_error_("not implemented yet");};
 		void GetInputUpToCurrentTimeAverages(IssmDouble** pvalues, IssmDouble** ptimes, int* pnumtimes, IssmDouble currenttime){_error_("not implemented yet");};
-		void GetVxStrainRate2d(IssmDouble* epsilonvx,IssmDouble* xyz_list, GaussTria* gauss){_error_("not implemented yet");};
-		void GetVyStrainRate2d(IssmDouble* epsilonvy,IssmDouble* xyz_list, GaussTria* gauss){_error_("not implemented yet");};
-		void GetVxStrainRate3d(IssmDouble* epsilonvx,IssmDouble* xyz_list, GaussPenta* gauss){_error_("not implemented yet");};
-		void GetVyStrainRate3d(IssmDouble* epsilonvy,IssmDouble* xyz_list, GaussPenta* gauss){_error_("not implemented yet");};
-		void GetVzStrainRate3d(IssmDouble* epsilonvz,IssmDouble* xyz_list, GaussPenta* gauss){_error_("not implemented yet");};
-		void GetVxStrainRate3dHO(IssmDouble* epsilonvx,IssmDouble* xyz_list, GaussPenta* gauss){_error_("not implemented yet");};
-		void GetVyStrainRate3dHO(IssmDouble* epsilonvy,IssmDouble* xyz_list, GaussPenta* gauss){_error_("not implemented yet");};
 		void ChangeEnum(int newenumtype){_error_("not implemented yet");};
 		void SquareMin(IssmDouble* psquaremin,Parameters* parameters){_error_("not implemented yet");};
@@ -85,4 +72,6 @@
 		void GetVectorFromInputs(Vector<IssmDouble>* vector,int* doflist){_error_("not implemented yet");};
 		int GetResultInterpolation(void){_error_("not implemented yet");};
+		int GetResultNumberOfNodes(void){_error_("not implemented yet");};
+		void ResultToPatch(IssmDouble* values,int nodesperelement,int sid){_error_("not supported yet");};
 		void GetGradient(Vector<IssmDouble>* gradient_vec,int* doflist){_error_("not implemented yet");};
 		void ScaleGradient(IssmDouble scale){_error_("not implemented yet");};
Index: /issm/trunk/src/c/classes/Inputs/DoubleInput.cpp
===================================================================
--- /issm/trunk/src/c/classes/Inputs/DoubleInput.cpp	(revision 17805)
+++ /issm/trunk/src/c/classes/Inputs/DoubleInput.cpp	(revision 17806)
@@ -40,7 +40,5 @@
 void DoubleInput::DeepEcho(void){
 
-	_printf_("DoubleInput:\n");
-	_printf_("   enum: " << this->enum_type << " (" << EnumToStringx(this->enum_type) << ")\n");
-	_printf_("   value: " << this->value << "\n");
+	_printf_(setw(15)<<"   DoubleInput "<<setw(25)<<left<<EnumToStringx(this->enum_type)<<" "<<this->value<<"\n");
 }
 /*}}}*/
@@ -72,5 +70,5 @@
 /*}}}*/
 /*FUNCTION DoubleInput::SpawnTriaInput{{{*/
-Input* DoubleInput::SpawnTriaInput(int location){
+Input* DoubleInput::SpawnTriaInput(int index1,int index2,int index3){
 
 	/*output*/
@@ -122,57 +120,6 @@
 }
 /*}}}*/
-/*FUNCTION DoubleInput::GetInputValue(IssmDouble* pvalue,GaussTria* gauss){{{*/
-void DoubleInput::GetInputValue(IssmDouble* pvalue,GaussTria* gauss){*pvalue=this->value;}
-/*}}}*/
-/*FUNCTION DoubleInput::GetInputValue(IssmDouble* pvalue,GaussPenta* gauss){{{*/
-void DoubleInput::GetInputValue(IssmDouble* pvalue,GaussPenta* gauss){*pvalue=this->value;}
-/*}}}*/
-/*FUNCTION DoubleInput::GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussTria* gauss){{{*/
-void DoubleInput::GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussTria* gauss){_error_("not supported yet!");}
-/*}}}*/
-/*FUNCTION DoubleInput::GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussPenta* gauss){{{*/
-void DoubleInput::GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussPenta* gauss){_error_("not supported yet!");}
-/*}}}*/
-/*FUNCTION DoubleInput::GetVxStrainRate2d(IssmDouble* epsilonvx,IssmDouble* xyz_list, GaussTria* gauss){{{*/
-void DoubleInput::GetVxStrainRate2d(IssmDouble* epsilonvx,IssmDouble* xyz_list, GaussTria* gauss){
-	/*Epsilon is zero as vx is constant over the element*/
-	for(int i=0;i<3;i++) epsilonvx[i]=0;
-}
-/*}}}*/
-/*FUNCTION DoubleInput::GetVyStrainRate2d(IssmDouble* epsilonvy,IssmDouble* xyz_list, GaussTria* gauss){{{*/
-void DoubleInput::GetVyStrainRate2d(IssmDouble* epsilonvy,IssmDouble* xyz_list, GaussTria* gauss){
-	/*Epsilon is zero as vy is constant over the element*/
-	for(int i=0;i<3;i++) epsilonvy[i]=0;
-}
-/*}}}*/
-/*FUNCTION DoubleInput::GetVxStrainRate3d(IssmDouble* epsilonvx,IssmDouble* xyz_list, GaussPenta* gauss){{{*/
-void DoubleInput::GetVxStrainRate3d(IssmDouble* epsilonvx,IssmDouble* xyz_list, GaussPenta* gauss){
-	/*Epsilon is zero as vx is constant over the element*/
-	for(int i=0;i<6;i++) epsilonvx[i]=0;
-}
-/*}}}*/
-/*FUNCTION DoubleInput::GetVyStrainRate3d(IssmDouble* epsilonvy,IssmDouble* xyz_list, GaussPenta* gauss){{{*/
-void DoubleInput::GetVyStrainRate3d(IssmDouble* epsilonvy,IssmDouble* xyz_list, GaussPenta* gauss){
-	/*Epsilon is zero as vy is constant over the element*/
-	for(int i=0;i<6;i++) epsilonvy[i]=0;
-}
-/*}}}*/
-/*FUNCTION DoubleInput::GetVzStrainRate3d(IssmDouble* epsilonvz,IssmDouble* xyz_list, GaussPenta* gauss){{{*/
-void DoubleInput::GetVzStrainRate3d(IssmDouble* epsilonvz,IssmDouble* xyz_list, GaussPenta* gauss){
-	/*Epsilon is zero as vz is constant over the element*/
-	for(int i=0;i<6;i++) epsilonvz[i]=0;
-}
-/*}}}*/
-/*FUNCTION DoubleInput::GetVxStrainRate3dHO(IssmDouble* epsilonvx,IssmDouble* xyz_list, GaussPenta* gauss){{{*/
-void DoubleInput::GetVxStrainRate3dHO(IssmDouble* epsilonvx,IssmDouble* xyz_list, GaussPenta* gauss){
-	/*Epsilon is zero as vx is constant over the element*/
-	for(int i=0;i<5;i++) epsilonvx[i]=0;
-}
-/*}}}*/
-/*FUNCTION DoubleInput::GetVyStrainRate3dHO(IssmDouble* epsilonvy,IssmDouble* xyz_list, GaussPenta* gauss){{{*/
-void DoubleInput::GetVyStrainRate3dHO(IssmDouble* epsilonvy,IssmDouble* xyz_list, GaussPenta* gauss){
-	/*Epsilon is zero as vy is constant over the element*/
-	for(int i=0;i<5;i++) epsilonvy[i]=0;
-}
+/*FUNCTION DoubleInput::GetInputValue(IssmDouble* pvalue,Gauss* gauss){{{*/
+void DoubleInput::GetInputValue(IssmDouble* pvalue,Gauss* gauss){*pvalue=this->value;}
 /*}}}*/
 /*FUNCTION DoubleInput::ChangeEnum{{{*/
Index: /issm/trunk/src/c/classes/Inputs/DoubleInput.h
===================================================================
--- /issm/trunk/src/c/classes/Inputs/DoubleInput.h	(revision 17805)
+++ /issm/trunk/src/c/classes/Inputs/DoubleInput.h	(revision 17806)
@@ -9,6 +9,6 @@
 /*{{{*/
 #include "./Input.h"
-class GaussTria;
-class GaussPenta;
+class Gauss;
+class Gauss;
 /*}}}*/
 
@@ -33,5 +33,5 @@
 		/*DoubleInput management: {{{*/
 		int   InstanceEnum();
-		Input* SpawnTriaInput(int location);
+		Input* SpawnTriaInput(int index1,int index2,int index3);
 		Input* SpawnSegInput(int index1,int index2);
 		Input* PointwiseDivide(Input* inputB);
@@ -39,4 +39,6 @@
 		Input* PointwiseMax(Input* inputB);
 		int  GetResultInterpolation(void){return P0Enum;};
+		int  GetResultNumberOfNodes(void){return 1;};
+		void ResultToPatch(IssmDouble* values,int nodesperelement,int sid){_error_("not supported yet");};
 		void AddTimeValues(IssmDouble* values,int step,IssmDouble time){_error_("not supported yet");};
 		void Configure(Parameters* parameters);
@@ -46,24 +48,11 @@
 		void GetInputValue(int* pvalue);
 		void GetInputValue(IssmDouble* pvalue);
-		void GetInputValue(IssmDouble* pvalue,GaussSeg* gauss){_error_("not implemented yet");};
-		void GetInputValue(IssmDouble* pvalue,GaussTria* gauss);
-		void GetInputValue(IssmDouble* pvalue,GaussPenta* gauss);
-		void GetInputValue(IssmDouble* pvalue,GaussTria* gauss,IssmDouble time){_error_("not implemented yet");};
-		void GetInputValue(IssmDouble* pvalue,GaussPenta* gauss,IssmDouble time){_error_("not implemented yet");};
-		void GetInputValue(IssmDouble* pvalue,GaussTria* gauss ,int index){_error_("not implemented yet");};
-		void GetInputValue(IssmDouble* pvalue,GaussPenta* gauss ,int index){_error_("not implemented yet");};
-		void GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussSeg* gauss){_error_("not implemented yet");};
-		void GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussTria* gauss);
-		void GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussPenta* gauss);
+		void GetInputValue(IssmDouble* pvalue,Gauss* gauss);
+		void GetInputValue(IssmDouble* pvalue,Gauss* gauss,IssmDouble time){_error_("not implemented yet");};
+		void GetInputValue(IssmDouble* pvalue,Gauss* gauss ,int index){_error_("not implemented yet");};
+		void GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list,Gauss* gauss){_error_("not implemented yet");};
 		void GetInputAverage(IssmDouble* pvalue);
 		void GetInputAllTimeAverages(IssmDouble** pvalues,IssmDouble** ptimes, int* pnumtimes){_error_("not implemented yet");};
 		void GetInputUpToCurrentTimeAverages(IssmDouble** pvalues, IssmDouble** ptimes, int* pnumtimes, IssmDouble currenttime){_error_("not implemented yet");};
-		void GetVxStrainRate2d(IssmDouble* epsilonvx,IssmDouble* xyz_list, GaussTria* gauss);
-		void GetVyStrainRate2d(IssmDouble* epsilonvy,IssmDouble* xyz_list, GaussTria* gauss);
-		void GetVxStrainRate3d(IssmDouble* epsilonvx,IssmDouble* xyz_list, GaussPenta* gauss);
-		void GetVyStrainRate3d(IssmDouble* epsilonvy,IssmDouble* xyz_list, GaussPenta* gauss);
-		void GetVzStrainRate3d(IssmDouble* epsilonvz,IssmDouble* xyz_list, GaussPenta* gauss);
-		void GetVxStrainRate3dHO(IssmDouble* epsilonvx,IssmDouble* xyz_list, GaussPenta* gauss);
-		void GetVyStrainRate3dHO(IssmDouble* epsilonvy,IssmDouble* xyz_list, GaussPenta* gauss);
 		void ChangeEnum(int newenumtype);
 		void SquareMin(IssmDouble* psquaremin,Parameters* parameters);
Index: /issm/trunk/src/c/classes/Inputs/Input.h
===================================================================
--- /issm/trunk/src/c/classes/Inputs/Input.h	(revision 17805)
+++ /issm/trunk/src/c/classes/Inputs/Input.h	(revision 17806)
@@ -11,8 +11,9 @@
 #include "../../shared/shared.h"
 class Node;
-class GaussTria;
+class Gauss;
+class Gauss;
 class GaussSeg;
 class Parameters;
-class GaussPenta;
+class Gauss;
 template <class doubletype> class Vector;
 /*}}}*/
@@ -28,24 +29,11 @@
 		virtual void GetInputValue(int* pvalue)=0;
 		virtual void GetInputValue(IssmDouble* pvalue)=0;
-		virtual void GetInputValue(IssmDouble* pvalue,GaussSeg* gauss)=0;
-		virtual void GetInputValue(IssmDouble* pvalue,GaussTria* gauss)=0;
-		virtual void GetInputValue(IssmDouble* pvalue,GaussPenta* gauss)=0;
-		virtual void GetInputValue(IssmDouble* pvalue,GaussTria* gauss,IssmDouble time)=0;
-		virtual void GetInputValue(IssmDouble* pvalue,GaussPenta* gauss,IssmDouble time)=0;
-		virtual void GetInputValue(IssmDouble* pvalue,GaussTria* gauss ,int index)=0;
-		virtual void GetInputValue(IssmDouble* pvalue,GaussPenta* gauss,int index)=0;
-		virtual void GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussSeg* gauss)=0;
-		virtual void GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussTria* gauss)=0;
-		virtual void GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussPenta* gauss)=0;
+		virtual void GetInputValue(IssmDouble* pvalue,Gauss* gauss)=0;
+		virtual void GetInputValue(IssmDouble* pvalue,Gauss* gauss,IssmDouble time)=0;
+		virtual void GetInputValue(IssmDouble* pvalue,Gauss* gauss,int index)=0;
+		virtual void GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, Gauss* gauss)=0;
 		virtual void GetInputAverage(IssmDouble* pvalue)=0;
 		virtual void GetInputAllTimeAverages(IssmDouble** pvalues,IssmDouble** ptimes, int* pnumtimes)=0;
 		virtual void GetInputUpToCurrentTimeAverages(IssmDouble** pvalues, IssmDouble** ptimes, int* pnumtimes, IssmDouble currenttime)=0;
-		virtual void GetVxStrainRate2d(IssmDouble* epsilonvx,IssmDouble* xyz_list, GaussTria* gauss)=0;
-		virtual void GetVyStrainRate2d(IssmDouble* epsilonvy,IssmDouble* xyz_list, GaussTria* gauss)=0;
-		virtual void GetVxStrainRate3d(IssmDouble* epsilonvx,IssmDouble* xyz_list, GaussPenta* gauss)=0;
-		virtual void GetVyStrainRate3d(IssmDouble* epsilonvy,IssmDouble* xyz_list, GaussPenta* gauss)=0;
-		virtual void GetVzStrainRate3d(IssmDouble* epsilonvz,IssmDouble* xyz_list, GaussPenta* gauss)=0;
-		virtual void GetVxStrainRate3dHO(IssmDouble* epsilonvx,IssmDouble* xyz_list, GaussPenta* gauss)=0;
-		virtual void GetVyStrainRate3dHO(IssmDouble* epsilonvy,IssmDouble* xyz_list, GaussPenta* gauss)=0;
 		virtual void ChangeEnum(int newenumtype)=0;
 		virtual void Configure(Parameters* parameters)=0;
@@ -58,5 +46,5 @@
 		virtual IssmDouble Max(void)=0;
 		virtual IssmDouble Min(void)=0;
-		virtual void Set(IssmDouble setvalue)=0;
+		virtual void   Set(IssmDouble setvalue)=0;
 		virtual void   Scale(IssmDouble scale_factor)=0;
 		virtual void   AXPY(Input* xinput,IssmDouble scalar)=0;
@@ -66,10 +54,12 @@
 		virtual void   GetVectorFromInputs(Vector<IssmDouble>* vector,int* doflist)=0;
 
-		virtual Input* SpawnTriaInput(int location)=0;
+		virtual Input* SpawnTriaInput(int index1,int index2,int index3)=0;
 		virtual Input* SpawnSegInput(int index1,int index2)=0;
 		virtual Input* PointwiseDivide(Input* inputB)=0;
 		virtual Input* PointwiseMax(Input* inputmax)=0;
 		virtual Input* PointwiseMin(Input* inputmin)=0;
-		virtual int GetResultInterpolation(void)=0;
+		virtual int  GetResultInterpolation(void)=0;
+		virtual int  GetResultNumberOfNodes(void)=0;
+		virtual void ResultToPatch(IssmDouble* values,int nodesperelement,int sid){_error_("not supported yet");};
 };
 #endif
Index: /issm/trunk/src/c/classes/Inputs/Inputs.cpp
===================================================================
--- /issm/trunk/src/c/classes/Inputs/Inputs.cpp	(revision 17805)
+++ /issm/trunk/src/c/classes/Inputs/Inputs.cpp	(revision 17806)
@@ -370,5 +370,5 @@
 /*}}}*/
 /*FUNCTION Inputs::SpawnTriaInputs{{{*/
-Inputs* Inputs::SpawnTriaInputs(int location){
+Inputs* Inputs::SpawnTriaInputs(int index1,int index2,int index3){
 
 	/*Intermediary*/
@@ -385,5 +385,5 @@
 		/*Create new input*/
 		inputin=dynamic_cast<Input*>(*object);
-		inputout=inputin->SpawnTriaInput(location);
+		inputout=inputin->SpawnTriaInput(index1,index2,index3);
 
 		/*Add input to new inputs*/
Index: /issm/trunk/src/c/classes/Inputs/Inputs.h
===================================================================
--- /issm/trunk/src/c/classes/Inputs/Inputs.h	(revision 17805)
+++ /issm/trunk/src/c/classes/Inputs/Inputs.h	(revision 17806)
@@ -28,5 +28,6 @@
 		void        DuplicateInput(int original_enum,int new_enum);
 		Input*      GetInput(int enum_name);
-		Inputs*     SpawnTriaInputs(int position);
+		Inputs*     SpawnTriaInputs(int position);//TO BE REMOVED (replaced by the other one)
+		Inputs*     SpawnTriaInputs(int index1,int index2,int index3);
 		Inputs*     SpawnSegInputs(int index1,int index2);
 		Inputs*     SpawnSegInputs(int position);
Index: /issm/trunk/src/c/classes/Inputs/IntInput.cpp
===================================================================
--- /issm/trunk/src/c/classes/Inputs/IntInput.cpp	(revision 17805)
+++ /issm/trunk/src/c/classes/Inputs/IntInput.cpp	(revision 17806)
@@ -35,7 +35,5 @@
 void IntInput::DeepEcho(void){
 
-	_printf_("IntInput:\n");
-	_printf_("   enum: " << this->enum_type << " (" << EnumToStringx(this->enum_type) << ")\n");
-	_printf_("   value: " << (int)this->value << "\n");
+	_printf_(setw(15)<<"   IntInput "<<setw(25)<<left<<EnumToStringx(this->enum_type)<<" "<<this->value<<"\n");
 }
 /*}}}*/
@@ -72,5 +70,5 @@
 /*}}}*/
 /*FUNCTION IntInput::SpawnTriaInput{{{*/
-Input* IntInput::SpawnTriaInput(int location){
+Input* IntInput::SpawnTriaInput(int index1,int index2,int index3){
 
 	/*output*/
@@ -114,15 +112,6 @@
 }
 /*}}}*/
-/*FUNCTION IntInput::GetInputValue(IssmDouble* pvalue,GaussTria* gauss){{{*/
-void IntInput::GetInputValue(IssmDouble* pvalue,GaussTria* gauss){_error_("not supported yet!");}
-/*}}}*/
-/*FUNCTION IntInput::GetInputValue(IssmDouble* pvalue,GaussPenta* gauss){{{*/
-void IntInput::GetInputValue(IssmDouble* pvalue,GaussPenta* gauss){_error_("not supported yet!");}
-/*}}}*/
-/*FUNCTION IntInput::GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussTria* gauss){{{*/
-void IntInput::GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussTria* gauss){_error_("not supported yet!");}
-/*}}}*/
-/*FUNCTION IntInput::GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussPenta* gauss){{{*/
-void IntInput::GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussPenta* gauss){_error_("not supported yet!");}
+/*FUNCTION IntInput::GetInputValue(IssmDouble* pvalue,Gauss* gauss){{{*/
+void IntInput::GetInputValue(IssmDouble* pvalue,Gauss* gauss){_error_("not supported yet!");}
 /*}}}*/
 /*FUNCTION IntInput::ChangeEnum{{{*/
Index: /issm/trunk/src/c/classes/Inputs/IntInput.h
===================================================================
--- /issm/trunk/src/c/classes/Inputs/IntInput.h	(revision 17805)
+++ /issm/trunk/src/c/classes/Inputs/IntInput.h	(revision 17806)
@@ -9,6 +9,6 @@
 /*{{{*/
 #include "./Input.h"
-class GaussTria;
-class GaussPenta;
+class Gauss;
+class Gauss;
 /*}}}*/
 
@@ -34,5 +34,5 @@
 		/*IntInput management: {{{*/
 		int   InstanceEnum();
-		Input* SpawnTriaInput(int location);
+		Input* SpawnTriaInput(int index1,int index2,int index3);
 		Input* SpawnSegInput(int index1,int index2);
 		Input* PointwiseDivide(Input* inputB){_error_("not implemented yet");};
@@ -40,4 +40,6 @@
 		Input* PointwiseMax(Input* inputB){_error_("not implemented yet");};
 		int  GetResultInterpolation(void){return P0Enum;};
+		int  GetResultNumberOfNodes(void){return 1;};
+		void ResultToPatch(IssmDouble* values,int nodesperelement,int sid){_error_("not supported yet");};
 		void AddTimeValues(IssmDouble* values,int step,IssmDouble time){_error_("not supported yet");};
 		void Configure(Parameters* parameters);
@@ -47,25 +49,11 @@
 		void GetInputValue(int* pvalue);
 		void GetInputValue(IssmDouble* pvalue);
-		void GetInputValue(IssmDouble* pvalue,GaussSeg* gauss){_error_("not implemented yet");};
-		void GetInputValue(IssmDouble* pvalue,GaussTria* gauss);
-		void GetInputValue(IssmDouble* pvalue,GaussPenta* gauss);
-		void GetInputValue(IssmDouble* pvalue,GaussTria* gauss,IssmDouble time){_error_("not implemented yet");};
-		void GetInputValue(IssmDouble* pvalue,GaussPenta* gauss,IssmDouble time){_error_("not implemented yet");};
-		void GetInputValue(IssmDouble* pvalue,GaussTria* gauss ,int index){_error_("not implemented yet");};
-		void GetInputValue(IssmDouble* pvalue,GaussPenta* gauss ,int index){_error_("not implemented yet");};
-		void GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussSeg* gauss){_error_("not implemented yet");};
-		void GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussTria* gauss);
-		void GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussPenta* gauss);
+		void GetInputValue(IssmDouble* pvalue,Gauss* gauss);
+		void GetInputValue(IssmDouble* pvalue,Gauss* gauss,IssmDouble time){_error_("not implemented yet");};
+		void GetInputValue(IssmDouble* pvalue,Gauss* gauss ,int index){_error_("not implemented yet");};
+		void GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list,Gauss* gauss){_error_("not implemented yet");};
 		void GetInputAverage(IssmDouble* pvalue){_error_("not implemented yet");};
 		void GetInputAllTimeAverages(IssmDouble** pvalues,IssmDouble** ptimes, int* pnumtimes){_error_("not implemented yet");};
 		void GetInputUpToCurrentTimeAverages(IssmDouble** pvalues, IssmDouble** ptimes, int* pnumtimes, IssmDouble currenttime){_error_("not implemented yet");};
-
-		void GetVxStrainRate2d(IssmDouble* epsilonvx,IssmDouble* xyz_list, GaussTria* gauss){_error_("not implemented yet");};
-		void GetVyStrainRate2d(IssmDouble* epsilonvy,IssmDouble* xyz_list, GaussTria* gauss){_error_("not implemented yet");};
-		void GetVxStrainRate3d(IssmDouble* epsilonvx,IssmDouble* xyz_list, GaussPenta* gauss){_error_("not implemented yet");};
-		void GetVyStrainRate3d(IssmDouble* epsilonvy,IssmDouble* xyz_list, GaussPenta* gauss){_error_("not implemented yet");};
-		void GetVzStrainRate3d(IssmDouble* epsilonvz,IssmDouble* xyz_list, GaussPenta* gauss){_error_("not implemented yet");};
-		void GetVxStrainRate3dHO(IssmDouble* epsilonvx,IssmDouble* xyz_list, GaussPenta* gauss){_error_("not implemented yet");};
-		void GetVyStrainRate3dHO(IssmDouble* epsilonvy,IssmDouble* xyz_list, GaussPenta* gauss){_error_("not implemented yet");};
 		void ChangeEnum(int newenumtype);
 		void SquareMin(IssmDouble* psquaremin,Parameters* parameters);
Index: /issm/trunk/src/c/classes/Inputs/PentaInput.cpp
===================================================================
--- /issm/trunk/src/c/classes/Inputs/PentaInput.cpp	(revision 17805)
+++ /issm/trunk/src/c/classes/Inputs/PentaInput.cpp	(revision 17806)
@@ -50,7 +50,5 @@
 void PentaInput::DeepEcho(void){
 
-	_printf_("PentaInput:\n");
-	_printf_("   enum: " << this->enum_type << " (" << EnumToStringx(this->enum_type) << ")\n");
-	_printf_("   values: [");
+	_printf_(setw(15)<<"   PentaInput "<<setw(25)<<left<<EnumToStringx(this->enum_type)<<" [");
 	for(int i=0;i<this->NumberofNodes();i++) _printf_(" "<<this->values[i]);
 	_printf_("]\n");
@@ -84,39 +82,29 @@
 /*}}}*/
 /*FUNCTION PentaInput::SpawnTriaInput{{{*/
-Input* PentaInput::SpawnTriaInput(int location){
+Input* PentaInput::SpawnTriaInput(int index1,int index2,int index3){
 
 	/*output*/
 	TriaInput* outinput=NULL;
-	IssmDouble newvalues[3]; //Assume P1 interpolation only for now
-
-	/*Create arrow of indices depending on location (0=base 1=surface)*/
-	int indices[3];
-	switch(location){
-		case 0:
-			indices[0] = 0;
-			indices[1] = 1;
-			indices[2] = 2;
-			break;
-		case 1:
-			indices[0] = 3;
-			indices[1] = 4;
-			indices[2] = 5;
-			break;
-		default:
-			_error_("case "<<location<<" not supported");
-	}
-
-	/*Loop over the new indices*/
-	for(int i=0;i<3;i++){
-
-		/*Check index value*/
-		_assert_(indices[i]>=0 && indices[i]<6);
-
-		/*Assign value to new input*/
-		newvalues[i]=this->values[indices[i]];
-	}
-
-	/*Create new Tria input*/
-	outinput=new TriaInput(this->enum_type,&newvalues[0],P1Enum);
+
+	if(this->element_type==P0Enum){ 
+		outinput=new TriaInput(this->enum_type,&this->values[0],P0Enum);
+	}
+	else{
+		/*Assume P1 interpolation only for now*/
+		IssmDouble newvalues[3]; 
+
+		/*Create array of indices depending on location (0=base 1=surface)*/
+		int indices[3];
+		indices[0] = index1;
+		indices[1] = index2;
+		indices[2] = index3;
+
+		/*Create new input*/
+		for(int i=0;i<3;i++){
+			_assert_(indices[i]>=0 && indices[i]<6);
+			newvalues[i]=this->values[indices[i]];
+		}
+		outinput=new TriaInput(this->enum_type,&newvalues[0],P1Enum);
+	}
 
 	/*Assign output*/
@@ -137,146 +125,50 @@
 }
 /*}}}*/
+/*FUNCTION PentaInput::GetResultNumberOfNodes{{{*/
+int  PentaInput::GetResultNumberOfNodes(void){
+
+	return this->NumberofNodes();;
+
+}
+/*}}}*/
+/*FUNCTION PentaInput::ResultToPatch{{{*/
+void PentaInput::ResultToPatch(IssmDouble* values,int nodesperelement,int sid){
+
+	int numnodes = this->NumberofNodes();
+
+	/*Some checks*/
+	_assert_(values);
+	_assert_(numnodes==nodesperelement);
+
+	/*Fill in arrays*/
+	for(int i=0;i<numnodes;i++) values[sid*numnodes + i] = this->values[i];
+}
+/*}}}*/
 
 /*Object functions*/
-/*FUNCTION PentaInput::GetInputValue(IssmDouble* pvalue,GaussPenta* gauss){{{*/
-void PentaInput::GetInputValue(IssmDouble* pvalue,GaussPenta* gauss){
+/*FUNCTION PentaInput::GetInputValue(IssmDouble* pvalue){{{*/
+void PentaInput::GetInputValue(IssmDouble* pvalue){
+
+	if(this->element_type==P0Enum){
+		pvalue=&values[0];
+	}
+	else _error_("not implemented yet");
+}
+/*}}}*/
+/*FUNCTION PentaInput::GetInputValue(IssmDouble* pvalue,Gauss* gauss){{{*/
+void PentaInput::GetInputValue(IssmDouble* pvalue,Gauss* gauss){
 
 	/*Call PentaRef function*/
-	PentaRef::GetInputValue(pvalue,&values[0],gauss);
-
-}
-/*}}}*/
-/*FUNCTION PentaInput::GetInputDerivativeValue(IssmDouble* p, IssmDouble* xyz_list, GaussPenta* gauss){{{*/
-void PentaInput::GetInputDerivativeValue(IssmDouble* p, IssmDouble* xyz_list, GaussPenta* gauss){
+	_assert_(gauss->Enum()==GaussPentaEnum);
+	PentaRef::GetInputValue(pvalue,&values[0],(GaussPenta*)gauss);
+
+}
+/*}}}*/
+/*FUNCTION PentaInput::GetInputDerivativeValue(IssmDouble* p, IssmDouble* xyz_list, Gauss* gauss){{{*/
+void PentaInput::GetInputDerivativeValue(IssmDouble* p, IssmDouble* xyz_list,Gauss* gauss){
 
 	/*Call PentaRef function*/
-	PentaRef::GetInputDerivativeValue(p,&values[0],xyz_list,gauss);
-}
-/*}}}*/
-/*FUNCTION PentaInput::GetVxStrainRate3d{{{*/
-void PentaInput::GetVxStrainRate3d(IssmDouble* epsilonvx,IssmDouble* xyz_list, GaussPenta* gauss){
-
-	/*Intermediary*/
-	int         numnodes=this->NumberofNodes();
-	IssmDouble* B=xNew<IssmDouble>(numnodes*(NDOF3*numnodes));
-	IssmDouble* velocity=xNew<IssmDouble>(numnodes*NDOF3);
-
-	/*Get B matrix: */
-	GetBFSstrainrate(B,xyz_list,gauss);
-
-	/*Here, we are computing the strain rate of (vx,0,0)*/
-	for(int i=0;i<numnodes;i++){
-		velocity[NDOF3*i+0]=this->values[i];
-		velocity[NDOF3*i+1]=0.;
-		velocity[NDOF3*i+2]=0.;
-	}
-	/*Multiply B by velocity, to get strain rate: */
-	MatrixMultiply(B,numnodes,NDOF3*numnodes,0,velocity,NDOF3*numnodes,1,0,epsilonvx,0);
-
-	/*Clean-up*/
-	xDelete<IssmDouble>(B);
-	xDelete<IssmDouble>(velocity);
-
-}
-/*}}}*/
-/*FUNCTION PentaInput::GetVyStrainRate3d{{{*/
-void PentaInput::GetVyStrainRate3d(IssmDouble* epsilonvx,IssmDouble* xyz_list, GaussPenta* gauss){
-
-	/*Intermediary*/
-	int         numnodes=this->NumberofNodes();
-	IssmDouble* B=xNew<IssmDouble>(numnodes*(NDOF3*numnodes));
-	IssmDouble* velocity=xNew<IssmDouble>(numnodes*NDOF3);
-
-	/*Get B matrix: */
-	GetBFSstrainrate(B,xyz_list,gauss);
-
-	/*Here, we are computing the strain rate of (0,vy,0)*/
-	for(int i=0;i<numnodes;i++){
-		velocity[NDOF3*i+0]=0.;
-		velocity[NDOF3*i+1]=this->values[i];
-		velocity[NDOF3*i+2]=0.;
-	}
-	/*Multiply B by velocity, to get strain rate: */
-	MatrixMultiply(B,numnodes,NDOF3*numnodes,0,velocity,NDOF3*numnodes,1,0,epsilonvx,0);
-
-	/*Clean-up*/
-	xDelete<IssmDouble>(B);
-	xDelete<IssmDouble>(velocity);
-}
-/*}}}*/
-/*FUNCTION PentaInput::GetVzStrainRate3d{{{*/
-void PentaInput::GetVzStrainRate3d(IssmDouble* epsilonvx,IssmDouble* xyz_list, GaussPenta* gauss){
-
-	/*Intermediary*/
-	int         numnodes=this->NumberofNodes();
-	IssmDouble* B=xNew<IssmDouble>(numnodes*(NDOF3*numnodes));
-	IssmDouble* velocity=xNew<IssmDouble>(numnodes*NDOF3);
-
-	/*Get B matrix: */
-	GetBFSstrainrate(B,xyz_list,gauss);
-
-	/*Here, we are computing the strain rate of (0,0,vz)*/
-	for(int i=0;i<numnodes;i++){
-		velocity[NDOF3*i+0]=0.;
-		velocity[NDOF3*i+1]=0.;
-		velocity[NDOF3*i+2]=this->values[i];
-	}
-	/*Multiply B by velocity, to get strain rate: */
-	MatrixMultiply(B,numnodes,NDOF3*numnodes,0,velocity,NDOF3*numnodes,1,0,epsilonvx,0);
-
-	/*Clean-up*/
-	xDelete<IssmDouble>(B);
-	xDelete<IssmDouble>(velocity);
-}
-/*}}}*/
-/*FUNCTION PentaInput::GetVxStrainRate3dHO{{{*/
-void PentaInput::GetVxStrainRate3dHO(IssmDouble* epsilonvx,IssmDouble* xyz_list, GaussPenta* gauss){
-
-	int i;
-	const int numnodes=6;
-	IssmDouble B[5][NDOF2*numnodes];
-	IssmDouble velocity[numnodes][NDOF2];
-
-	/*Get B matrix: */
-	GetBHO(&B[0][0], xyz_list, gauss);
-
-	_assert_(this->NumberofNodes()==6); //Check Tria too
-
-	/*Here, we are computing the strain rate of (vx,0)*/
-	for(i=0;i<numnodes;i++){
-		velocity[i][0]=this->values[i];
-		velocity[i][1]=0.0;
-	}
-
-	/*Multiply B by velocity, to get strain rate: */
-	MatrixMultiply( &B[0][0],5,NDOF2*numnodes,0,
-				&velocity[0][0],NDOF2*numnodes,1,0,
-				epsilonvx,0);
-
-}
-/*}}}*/
-/*FUNCTION PentaInput::GetVyStrainRate3dHO{{{*/
-void PentaInput::GetVyStrainRate3dHO(IssmDouble* epsilonvy,IssmDouble* xyz_list, GaussPenta* gauss){
-
-	int i;
-	const int numnodes=6;
-	IssmDouble B[5][NDOF2*numnodes];
-	IssmDouble velocity[numnodes][NDOF2];
-
-	/*Get B matrix: */
-	GetBHO(&B[0][0], xyz_list, gauss);
-	_assert_(this->NumberofNodes()==6); //Check Tria too
-
-	/*Here, we are computing the strain rate of (0,vy)*/
-	for(i=0;i<numnodes;i++){
-		velocity[i][0]=0.0;
-		velocity[i][1]=this->values[i];
-	}
-
-	/*Multiply B by velocity, to get strain rate: */
-	MatrixMultiply( &B[0][0],5,NDOF2*numnodes,0,
-				&velocity[0][0],NDOF2*numnodes,1,0,
-				epsilonvy,0);
-
+	_assert_(gauss->Enum()==GaussPentaEnum);
+	PentaRef::GetInputDerivativeValue(p,&values[0],xyz_list,(GaussPenta*)gauss);
 }
 /*}}}*/
@@ -438,20 +330,26 @@
 
 	IssmDouble thickness;
+	IssmDouble value=0.;
 
 	/*Check that input provided is a thickness*/
 	if (thickness_input->InstanceEnum()!=ThicknessEnum) _error_("Input provided is not a Thickness (enum_type is " << EnumToStringx(thickness_input->InstanceEnum()) << ")");
 
-	/*vertically integrate depending on type:*/
+	/*vertically integrate depending on type (and use P1 interpolation from now on)*/
 	switch(this->element_type){
-		case P1Enum:{
-			GaussPenta *gauss=new GaussPenta();
-			for(int iv=0;iv<3;iv++){
-				gauss->GaussVertex(iv);
-				thickness_input->GetInputValue(&thickness,gauss);
-				this->values[iv]=0.5*(this->values[iv]+this->values[iv+3]) * thickness;
-				this->values[iv+3]=this->values[iv];
-			}
-			delete gauss;
-			return; }
+		case P1Enum:
+		case P1bubbleEnum:
+		case P2Enum:
+			  {
+				this->element_type=P1Enum;
+				GaussPenta *gauss=new GaussPenta();
+				for(int iv=0;iv<3;iv++){
+					gauss->GaussVertex(iv);
+					thickness_input->GetInputValue(&thickness,gauss);
+					this->values[iv]=0.5*(this->values[iv]+this->values[iv+3]) * thickness;
+					this->values[iv+3]=this->values[iv];
+				}
+				delete gauss;
+				return; 
+			  }
 		default:
 			_error_("not supported yet for type "<<EnumToStringx(this->element_type));
@@ -556,8 +454,6 @@
 /*FUNCTION PentaInput::GetVectorFromInputs{{{*/
 void PentaInput::GetVectorFromInputs(Vector<IssmDouble>* vector,int* doflist){
-
-	const int numnodes=this->NumberofNodes();
-	vector->SetValues(numnodes,doflist,this->values,INS_VAL);
-
+	const int numvertices=6;
+	vector->SetValues(numvertices,doflist,this->values,INS_VAL);
 } /*}}}*/
 /*FUNCTION PentaInput::Configure{{{*/
Index: /issm/trunk/src/c/classes/Inputs/PentaInput.h
===================================================================
--- /issm/trunk/src/c/classes/Inputs/PentaInput.h	(revision 17805)
+++ /issm/trunk/src/c/classes/Inputs/PentaInput.h	(revision 17806)
@@ -10,6 +10,6 @@
 #include "./Input.h"
 #include "../Elements/PentaRef.h"
-class GaussTria;
-class GaussPenta;
+class Gauss;
+class Gauss;
 /*}}}*/
 
@@ -34,5 +34,5 @@
 		/*PentaInput management*/
 		int   InstanceEnum();
-		Input* SpawnTriaInput(int location);
+		Input* SpawnTriaInput(int index1,int index2,int index3);
 		Input* SpawnSegInput(int index1,int index2);
 		Input* PointwiseDivide(Input* inputB);
@@ -40,4 +40,6 @@
 		Input* PointwiseMax(Input* inputB);
 		int  GetResultInterpolation(void);
+		int  GetResultNumberOfNodes(void);
+		void ResultToPatch(IssmDouble* values,int nodesperelement,int sid);
 		void AddTimeValues(IssmDouble* values,int step,IssmDouble time){_error_("not supported yet");};
 		void Configure(Parameters* parameters);
@@ -45,28 +47,13 @@
 		void GetInputValue(bool* pvalue){_error_("not implemented yet");};
 		void GetInputValue(int* pvalue){_error_("not implemented yet");};
-		void GetInputValue(IssmDouble* pvalue){_error_("not implemented yet");};
-		void GetInputValue(IssmDouble* pvalue,GaussSeg* gauss){_error_("not implemented yet");};
-		void GetInputValue(IssmDouble* pvalue,GaussTria* gauss){_error_("not implemented yet");};
-		void GetInputValue(IssmDouble* pvalue,GaussPenta* gauss);
-		void GetInputValue(IssmDouble* pvalue,GaussTria* gauss,IssmDouble time){_error_("not implemented yet");};
-		void GetInputValue(IssmDouble* pvalue,GaussPenta* gauss,IssmDouble time){_error_("not implemented yet");};
-		void GetInputValue(IssmDouble* pvalue,GaussTria* gauss ,int index){_error_("not implemented yet");};
-		void GetInputValue(IssmDouble* pvalue,GaussPenta* gauss ,int index){_error_("not implemented yet");};
-		void GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussSeg* gauss){_error_("not implemented yet");};
-		void GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussTria* gauss){_error_("not implemented yet");};
-		void GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussPenta* gauss);
+		void GetInputValue(IssmDouble* pvalue);
+		void GetInputValue(IssmDouble* pvalue,Gauss* gauss);
+		void GetInputValue(IssmDouble* pvalue,Gauss* gauss,IssmDouble time){_error_("not implemented yet");};
+		void GetInputValue(IssmDouble* pvalue,Gauss* gauss ,int index){_error_("not implemented yet");};
+		void GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list,Gauss* gauss);
 		void GetInputAverage(IssmDouble* pvalue);
 		void GetInputAllTimeAverages(IssmDouble** pvalues,IssmDouble** ptimes, int* pnumtimes){_error_("not implemented yet");};
 		void GetInputUpToCurrentTimeAverages(IssmDouble** pvalues, IssmDouble** ptimes, int* pnumtimes, IssmDouble currenttime){_error_("not implemented yet");};
-
-		void GetVxStrainRate2d(IssmDouble* epsilonvx,IssmDouble* xyz_list, GaussTria* gauss){_error_("not implemented yet");};
-		void GetVyStrainRate2d(IssmDouble* epsilonvy,IssmDouble* xyz_list, GaussTria* gauss){_error_("not implemented yet");};
-		void GetVxStrainRate3d(IssmDouble* epsilonvx,IssmDouble* xyz_list, GaussPenta* gauss);
-		void GetVyStrainRate3d(IssmDouble* epsilonvy,IssmDouble* xyz_list, GaussPenta* gauss);
-		void GetVzStrainRate3d(IssmDouble* epsilonvz,IssmDouble* xyz_list, GaussPenta* gauss);
-		void GetVxStrainRate3dHO(IssmDouble* epsilonvx,IssmDouble* xyz_list, GaussPenta* gauss);
-		void GetVyStrainRate3dHO(IssmDouble* epsilonvy,IssmDouble* xyz_list, GaussPenta* gauss);
 		void ChangeEnum(int newenumtype);
-
 		void SquareMin(IssmDouble* psquaremin,Parameters* parameters);
 		void ConstrainMin(IssmDouble minimum);
Index: /issm/trunk/src/c/classes/Inputs/SegInput.cpp
===================================================================
--- /issm/trunk/src/c/classes/Inputs/SegInput.cpp	(revision 17805)
+++ /issm/trunk/src/c/classes/Inputs/SegInput.cpp	(revision 17806)
@@ -50,7 +50,5 @@
 void SegInput::DeepEcho(void){
 
-	_printf_("SegInput:\n");
-	_printf_("   enum: " << this->enum_type << " (" << EnumToStringx(this->enum_type) << ")\n");
-	_printf_("   values: [");
+	_printf_(setw(15)<<"   SegInput "<<setw(25)<<left<<EnumToStringx(this->enum_type)<<" [");
 	for(int i=0;i<this->NumberofNodes();i++) _printf_(" "<<this->values[i]);
 	_printf_("]\n");
@@ -98,17 +96,19 @@
 }
 /*}}}*/
-/*FUNCTION SegInput::GetInputValue(IssmDouble* pvalue,GaussSeg* gauss){{{*/
-void SegInput::GetInputValue(IssmDouble* pvalue,GaussSeg* gauss){
+/*FUNCTION SegInput::GetInputValue(IssmDouble* pvalue,Gauss* gauss){{{*/
+void SegInput::GetInputValue(IssmDouble* pvalue,Gauss* gauss){
 
 	/*Call SegRef function*/
-	SegRef::GetInputValue(pvalue,&values[0],gauss);
+	_assert_(gauss->Enum()==GaussSegEnum);
+	SegRef::GetInputValue(pvalue,&values[0],(GaussSeg*)gauss);
 
 }
 /*}}}*/
-/*FUNCTION SegInput::GetInputDerivativeValue(IssmDouble* p, IssmDouble* xyz_list, GaussSeg* gauss){{{*/
-void SegInput::GetInputDerivativeValue(IssmDouble* p, IssmDouble* xyz_list, GaussSeg* gauss){
+/*FUNCTION SegInput::GetInputDerivativeValue(IssmDouble* p, IssmDouble* xyz_list, Gauss* gauss){{{*/
+void SegInput::GetInputDerivativeValue(IssmDouble* p, IssmDouble* xyz_list,Gauss* gauss){
 
 	/*Call SegRef function*/
-	SegRef::GetInputDerivativeValue(p,&values[0],xyz_list,gauss);
+	_assert_(gauss->Enum()==GaussSegEnum);
+	SegRef::GetInputDerivativeValue(p,&values[0],xyz_list,(GaussSeg*)gauss);
 }
 /*}}}*/
@@ -118,2 +118,14 @@
 }
 /*}}}*/
+/*FUNCTION SegInput::Min{{{*/
+IssmDouble SegInput::Min(void){
+
+	const int  numnodes=this->NumberofNodes();
+	IssmDouble min=values[0];
+
+	for(int i=1;i<numnodes;i++){
+		if(values[i]<min) min=values[i];
+	}
+	return min;
+}
+/*}}}*/
Index: /issm/trunk/src/c/classes/Inputs/SegInput.h
===================================================================
--- /issm/trunk/src/c/classes/Inputs/SegInput.h	(revision 17805)
+++ /issm/trunk/src/c/classes/Inputs/SegInput.h	(revision 17806)
@@ -11,5 +11,5 @@
 #include "../Elements/SegRef.h"
 class GaussSeg;
-class GaussPenta;
+class Gauss;
 /*}}}*/
 
@@ -34,5 +34,5 @@
 		/*SegInput management:*/
 		int    InstanceEnum();
-		Input* SpawnTriaInput(int location){_error_("not supported yet");};
+		Input* SpawnTriaInput(int index1,int index2,int index3){_error_("not supported yet");};
 		Input* SpawnSegInput(int index1,int index2){_error_("not implemented yet");};
 		Input* PointwiseDivide(Input* inputB){_error_("not supported yet");};
@@ -40,4 +40,6 @@
 		Input* PointwiseMax(Input* inputB){_error_("not supported yet");};
 		int  GetResultInterpolation(void){_error_("not implemented");};
+		int  GetResultNumberOfNodes(void){_error_("not implemented");};
+		void ResultToPatch(IssmDouble* values,int nodesperelement,int sid){_error_("not supported yet");};
 		void   AddTimeValues(IssmDouble* values,int step,IssmDouble time){_error_("not supported yet");};
 		void   Configure(Parameters* parameters);
@@ -47,26 +49,12 @@
 		void GetInputValue(int* pvalue){_error_("not implemented yet");}
 		void GetInputValue(IssmDouble* pvalue){_error_("not implemented yet");}
-		void GetInputValue(IssmDouble* pvalue,GaussSeg* gauss);
-		void GetInputValue(IssmDouble* pvalue,GaussTria* gauss){_error_("not implemented yet");};
-		void GetInputValue(IssmDouble* pvalue,GaussPenta* gauss){_error_("not implemented yet");};
-		void GetInputValue(IssmDouble* pvalue,GaussTria* gauss,IssmDouble time){_error_("not implemented yet");};
-		void GetInputValue(IssmDouble* pvalue,GaussPenta* gauss,IssmDouble time){_error_("not implemented yet");};
-		void GetInputValue(IssmDouble* pvalue,GaussTria* gauss ,int index){_error_("not implemented yet");};
-		void GetInputValue(IssmDouble* pvalue,GaussPenta* gauss,int index){_error_("not implemented yet");};
-		void GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussSeg* gauss);
-		void GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussTria* gauss){_error_("not implemented yet");};
-		void GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussPenta* gauss){_error_("not implemented yet");};
+		void GetInputValue(IssmDouble* pvalue,Gauss* gauss);
+		void GetInputValue(IssmDouble* pvalue,Gauss* gauss,IssmDouble time){_error_("not implemented yet");};
+		void GetInputValue(IssmDouble* pvalue,Gauss* gauss ,int index){_error_("not implemented yet");};
+		void GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list,Gauss* gauss);
 		void GetInputAverage(IssmDouble* pvalue);
 		void GetInputAllTimeAverages(IssmDouble** pvalues,IssmDouble** ptimes, int* pnumtimes){_error_("not implemented yet");};
 		void GetInputUpToCurrentTimeAverages(IssmDouble** pvalues, IssmDouble** ptimes, int* pnumtimes, IssmDouble currenttime){_error_("not implemented yet");};
-		void GetVxStrainRate2d(IssmDouble* epsilonvx,IssmDouble* xyz_list, GaussTria* gauss){_error_("not implemented yet");};
-		void GetVyStrainRate2d(IssmDouble* epsilonvy,IssmDouble* xyz_list, GaussTria* gauss){_error_("not implemented yet");};
-		void GetVxStrainRate3d(IssmDouble* epsilonvx,IssmDouble* xyz_list, GaussPenta* gauss){_error_("not implemented yet");};
-		void GetVyStrainRate3d(IssmDouble* epsilonvy,IssmDouble* xyz_list, GaussPenta* gauss){_error_("not implemented yet");};
-		void GetVzStrainRate3d(IssmDouble* epsilonvz,IssmDouble* xyz_list, GaussPenta* gauss){_error_("not implemented yet");};
-		void GetVxStrainRate3dHO(IssmDouble* epsilonvx,IssmDouble* xyz_list, GaussPenta* gauss){_error_("not implemented yet");};
-		void GetVyStrainRate3dHO(IssmDouble* epsilonvy,IssmDouble* xyz_list, GaussPenta* gauss){_error_("not implemented yet");};
 		void ChangeEnum(int newenumtype){_error_("not implemented yet");};
-
 		void SquareMin(IssmDouble* psquaremin,Parameters* parameters){_error_("not implemented yet");};
 		void ConstrainMin(IssmDouble minimum){_error_("not implemented yet");};
@@ -78,5 +66,5 @@
 		IssmDouble Max(void){_error_("not implemented yet");};
 		IssmDouble MaxAbs(void){_error_("not implemented yet");};
-		IssmDouble Min(void){_error_("not implemented yet");};
+		IssmDouble Min(void);
 		IssmDouble MinAbs(void){_error_("not implemented yet");};
 		void Extrude(void){_error_("not supported yet");};
Index: /issm/trunk/src/c/classes/Inputs/TetraInput.cpp
===================================================================
--- /issm/trunk/src/c/classes/Inputs/TetraInput.cpp	(revision 17806)
+++ /issm/trunk/src/c/classes/Inputs/TetraInput.cpp	(revision 17806)
@@ -0,0 +1,448 @@
+/*!\file TetraInput.c
+ * \brief: implementation of the TetraInput object
+ */
+
+#ifdef HAVE_CONFIG_H
+	#include <config.h>
+#else
+#error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
+#endif
+
+#include "../classes.h"
+#include "../../shared/shared.h"
+
+/*TetraInput constructors and destructor*/
+/*FUNCTION TetraInput::TetraInput(){{{*/
+TetraInput::TetraInput(){
+	values = NULL;
+}
+/*}}}*/
+/*FUNCTION TetraInput::TetraInput(int in_enum_type,IssmDouble* invalues,element_type_in){{{*/
+TetraInput::TetraInput(int in_enum_type,IssmDouble* in_values,int element_type_in)
+	:TetraRef(1)
+{
+
+	/*Set TetraRef*/
+	this->SetElementType(element_type_in,0);
+	this->element_type=element_type_in;
+
+	/*Set Enum*/
+	enum_type=in_enum_type;
+
+	/*Set values*/
+	this->values=xNew<IssmDouble>(this->NumberofNodes());
+	for(int i=0;i<this->NumberofNodes();i++) values[i]=in_values[i];
+}
+/*}}}*/
+/*FUNCTION TetraInput::~TetraInput(){{{*/
+TetraInput::~TetraInput(){
+	xDelete<IssmDouble>(this->values);
+}
+/*}}}*/
+
+/*Object virtual functions definitions:*/
+/*FUNCTION TetraInput::Echo {{{*/
+void TetraInput::Echo(void){
+	this->DeepEcho();
+}
+/*}}}*/
+/*FUNCTION TetraInput::DeepEcho{{{*/
+void TetraInput::DeepEcho(void){
+
+	_printf_(setw(15)<<"   TetraInput "<<setw(25)<<left<<EnumToStringx(this->enum_type)<<" [");
+	for(int i=0;i<this->NumberofNodes();i++) _printf_(" "<<this->values[i]);
+	_printf_("] ("<<EnumToStringx(this->element_type)<<")\n");
+}
+/*}}}*/
+/*FUNCTION TetraInput::Id{{{*/
+int    TetraInput::Id(void){ return -1; }
+/*}}}*/
+/*FUNCTION TetraInput::ObjectEnum{{{*/
+int TetraInput::ObjectEnum(void){
+
+	return TetraInputEnum;
+
+}
+/*}}}*/
+/*FUNCTION TetraInput::copy{{{*/
+Object* TetraInput::copy() {
+
+	return new TetraInput(this->enum_type,this->values,this->element_type);
+
+}
+/*}}}*/
+
+/*TetraInput management*/
+/*FUNCTION TetraInput::InstanceEnum{{{*/
+int TetraInput::InstanceEnum(void){
+
+	return this->enum_type;
+
+}
+/*}}}*/
+/*FUNCTION TetraInput::GetResultInterpolation{{{*/
+int  TetraInput::GetResultInterpolation(void){
+
+	return P1Enum;
+
+}
+/*}}}*/
+/*FUNCTION TetraInput::GetResultNumberOfNodes{{{*/
+int  TetraInput::GetResultNumberOfNodes(void){
+
+	return this->NumberofNodes();
+
+}
+/*}}}*/
+/*FUNCTION TetraInput::ResultToPatch{{{*/
+void TetraInput::ResultToPatch(IssmDouble* values,int nodesperelement,int sid){
+
+	int numnodes = this->NumberofNodes();
+
+	/*Some checks*/
+	_assert_(values);
+	_assert_(numnodes==nodesperelement);
+
+	/*Fill in arrays*/
+	for(int i=0;i<numnodes;i++) values[sid*numnodes + i] = this->values[i];
+}
+/*}}}*/
+
+/*Object functions*/
+/*FUNCTION TetraInput::GetInputValue(IssmDouble* pvalue,Gauss* gauss){{{*/
+void TetraInput::GetInputValue(IssmDouble* pvalue,Gauss* gauss){
+
+	/*Call TetraRef function*/
+	_assert_(gauss->Enum()==GaussTetraEnum);
+	TetraRef::GetInputValue(pvalue,&values[0],(GaussTetra*)gauss);
+
+}
+/*}}}*/
+/*FUNCTION TetraInput::GetInputDerivativeValue(IssmDouble* p, IssmDouble* xyz_list, Gauss* gauss){{{*/
+void TetraInput::GetInputDerivativeValue(IssmDouble* p, IssmDouble* xyz_list, Gauss* gauss){
+
+	/*Call TetraRef function*/
+	_assert_(gauss->Enum()==GaussTetraEnum);
+	TetraRef::GetInputDerivativeValue(p,&values[0],xyz_list,(GaussTetra*)gauss);
+}
+/*}}}*/
+/*FUNCTION TetraInput::ChangeEnum{{{*/
+void TetraInput::ChangeEnum(int newenumtype){
+	this->enum_type=newenumtype;
+}
+/*}}}*/
+/*FUNCTION TetraInput::GetInputAverage{{{*/
+void TetraInput::GetInputAverage(IssmDouble* pvalue){
+
+	int        numnodes  = this->NumberofNodes();
+	IssmDouble numnodesd = reCast<int,IssmDouble>(numnodes);
+	IssmDouble value     = 0.;
+
+	for(int i=0;i<numnodes;i++) value+=values[i];
+	value = value/numnodesd;
+
+	*pvalue=value;
+}
+/*}}}*/
+/*FUNCTION TetraInput::GetInputAllTimeAverages{{{*/
+void TetraInput::GetInputAllTimeAverages(IssmDouble** pvalues,IssmDouble** ptimes, int* pnumtimes){
+
+	IssmDouble* outvalues=NULL;
+	IssmDouble* times=NULL;
+	int         numtimes;
+
+	/*this is not a transient forcing, so we only have 1 value, steady state: */
+	numtimes=1;
+	outvalues=xNew<IssmDouble>(1);
+	times=xNew<IssmDouble>(1);
+
+	this->GetInputAverage(&outvalues[0]);
+	times[0]=0.; /*we don't have a time*/
+
+	*pvalues=outvalues;
+	*ptimes=times;
+	*pnumtimes=numtimes;
+}
+/*}}}*/
+/*FUNCTION TetraInput::GetInputUpToCurrentTimeAverages{{{*/
+void TetraInput::GetInputUpToCurrentTimeAverages(IssmDouble** pvalues, IssmDouble** ptimes, int* pnumtimes, IssmDouble currenttime){
+
+	IssmDouble* outvalues=NULL;
+	IssmDouble* times=NULL;
+	int         numtimes;
+
+	/*this is not a transient forcing, so we only have 1 value, steady state: */
+	numtimes=1;
+	outvalues=xNew<IssmDouble>(1);
+	times=xNew<IssmDouble>(1);
+
+	this->GetInputAverage(&outvalues[0]);
+	times[0]=currenttime; /*we don't have a time*/
+
+	*pvalues=outvalues;
+	*ptimes=times;
+	*pnumtimes=numtimes;
+}
+/*}}}*/
+/*FUNCTION TetraInput::SpawnTriaInput{{{*/
+Input* TetraInput::SpawnTriaInput(int index1,int index2,int index3){
+
+	/*output*/
+	TriaInput* outinput=NULL;
+
+	if(this->element_type==P0Enum){ 
+		outinput=new TriaInput(this->enum_type,&this->values[0],P0Enum);
+	}
+	else{
+		/*Assume P1 interpolation only for now*/
+		IssmDouble newvalues[3]; 
+
+		/*Create array of indices depending on location (0=base 1=surface)*/
+		int indices[3];
+		indices[0] = index1;
+		indices[1] = index2;
+		indices[2] = index3;
+
+		/*Create new input*/
+		for(int i=0;i<3;i++){
+			_assert_(indices[i]>=0 && indices[i]<4);
+			newvalues[i]=this->values[indices[i]];
+		}
+		outinput=new TriaInput(this->enum_type,&newvalues[0],P1Enum);
+	}
+
+	/*Assign output*/
+	return outinput;
+}
+/*}}}*/
+
+/*Intermediary*/
+/*FUNCTION TetraInput::SquareMin{{{*/
+void TetraInput::SquareMin(IssmDouble* psquaremin,Parameters* parameters){
+
+	int        numnodes=this->NumberofNodes();
+	IssmDouble squaremin;
+
+	/*Now, figure out minimum of valuescopy: */
+	squaremin=pow(this->values[0],2);
+	for(int i=1;i<numnodes;i++){
+		if(pow(this->values[i],2)<squaremin)squaremin=pow(this->values[i],2);
+	}
+	/*Assign output pointers:*/
+	*psquaremin=squaremin;
+}
+/*}}}*/
+/*FUNCTION TetraInput::ContrainMin{{{*/
+void TetraInput::ConstrainMin(IssmDouble minimum){
+
+	int numnodes = this->NumberofNodes();
+	for(int i=0;i<numnodes;i++) if (values[i]<minimum) values[i]=minimum;
+}
+/*}}}*/
+/*FUNCTION TetraInput::InfinityNorm{{{*/
+IssmDouble TetraInput::InfinityNorm(void){
+
+	/*Output*/
+	IssmDouble norm=0.;
+	int numnodes=this->NumberofNodes();
+
+	for(int i=0;i<numnodes;i++) if(fabs(values[i])>norm) norm=fabs(values[i]);
+	return norm;
+}
+/*}}}*/
+/*FUNCTION TetraInput::Max{{{*/
+IssmDouble TetraInput::Max(void){
+
+	int  numnodes=this->NumberofNodes();
+	IssmDouble max=values[0];
+
+	for(int i=1;i<numnodes;i++){
+		if(values[i]>max) max=values[i];
+	}
+	return max;
+}
+/*}}}*/
+/*FUNCTION TetraInput::MaxAbs{{{*/
+IssmDouble TetraInput::MaxAbs(void){
+
+	int  numnodes=this->NumberofNodes();
+	IssmDouble max=fabs(values[0]);
+
+	for(int i=1;i<numnodes;i++){
+		if(fabs(values[i])>max) max=fabs(values[i]);
+	}
+	return max;
+}
+/*}}}*/
+/*FUNCTION TetraInput::Min{{{*/
+IssmDouble TetraInput::Min(void){
+
+	const int  numnodes=this->NumberofNodes();
+	IssmDouble min=values[0];
+
+	for(int i=1;i<numnodes;i++){
+		if(values[i]<min) min=values[i];
+	}
+	return min;
+}
+/*}}}*/
+/*FUNCTION TetraInput::MinAbs{{{*/
+IssmDouble TetraInput::MinAbs(void){
+
+	const int  numnodes=this->NumberofNodes();
+	IssmDouble min=fabs(values[0]);
+
+	for(int i=1;i<numnodes;i++){
+		if(fabs(values[i])<min) min=fabs(values[i]);
+	}
+	return min;
+}
+/*}}}*/
+/*FUNCTION TetraInput::Scale{{{*/
+void TetraInput::Scale(IssmDouble scale_factor){
+
+	const int numnodes=this->NumberofNodes();
+	for(int i=0;i<numnodes;i++)values[i]=values[i]*scale_factor;
+}
+/*}}}*/
+/*FUNCTION TetraInput::Set{{{*/
+void TetraInput::Set(IssmDouble setvalue){
+
+	const int numnodes=this->NumberofNodes();
+	for(int i=0;i<numnodes;i++)values[i]=setvalue;
+}
+/*}}}*/
+/*FUNCTION TetraInput::AXPY{{{*/
+void TetraInput::AXPY(Input* xinput,IssmDouble scalar){
+
+	const int numnodes=this->NumberofNodes();
+	TetraInput*  xtriainput=NULL;
+
+	/*xinput is of the same type, so cast it: */
+	if(xinput->ObjectEnum()!=TetraInputEnum) _error_("Operation not permitted because xinput is of type " << EnumToStringx(xinput->ObjectEnum()));
+	xtriainput=(TetraInput*)xinput;
+	if(xtriainput->element_type!=this->element_type) _error_("Operation not permitted because xinput is of type " << EnumToStringx(xinput->ObjectEnum()));
+
+	/*Carry out the AXPY operation depending on type:*/
+	for(int i=0;i<numnodes;i++)this->values[i]=this->values[i]+scalar*xtriainput->values[i];
+
+}
+/*}}}*/
+/*FUNCTION TetraInput::Constrain{{{*/
+void TetraInput::Constrain(IssmDouble cm_min, IssmDouble cm_max){
+
+	int i;
+	const int numnodes=this->NumberofNodes();
+
+	if(!xIsNan<IssmDouble>(cm_min)) for(i=0;i<numnodes;i++)if (this->values[i]<cm_min)this->values[i]=cm_min;
+	if(!xIsNan<IssmDouble>(cm_max)) for(i=0;i<numnodes;i++)if (this->values[i]>cm_max)this->values[i]=cm_max;
+
+}
+/*}}}*/
+/*FUNCTION TetraInput::GetVectorFromInputs{{{*/
+void TetraInput::GetVectorFromInputs(Vector<IssmDouble>* vector,int* doflist){
+	const int numvertices=4;
+	vector->SetValues(numvertices,doflist,this->values,INS_VAL);
+} /*}}}*/
+/*FUNCTION TetraInput::PointwiseMin{{{*/
+Input* TetraInput::PointwiseMin(Input* inputB){
+
+	/*Ouput*/
+	TetraInput* outinput=NULL;
+
+	/*Intermediaries*/
+	int         i;
+	TetraInput  *xinputB   = NULL;
+	const int   numnodes  = this->NumberofNodes();
+	IssmDouble *minvalues = xNew<IssmDouble>(numnodes);
+
+	/*Check that inputB is of the same type*/
+	if(inputB->ObjectEnum()!=TetraInputEnum)       _error_("Operation not permitted because inputB is of type " << EnumToStringx(inputB->ObjectEnum()));
+	xinputB=(TetraInput*)inputB;
+	if(xinputB->element_type!=this->element_type) _error_("Operation not permitted because inputB is of type " << EnumToStringx(xinputB->element_type));
+
+	/*Create point wise min*/
+	for(i=0;i<numnodes;i++){
+		if(this->values[i] > xinputB->values[i]) minvalues[i]=xinputB->values[i];
+		else minvalues[i]=this->values[i];
+	}
+
+	/*Create new Tetra vertex input (copy of current input)*/
+	outinput=new TetraInput(this->enum_type,&minvalues[0],this->element_type);
+
+	/*Return output pointer*/
+	xDelete<IssmDouble>(minvalues);
+	return outinput;
+
+}
+/*}}}*/
+/*FUNCTION TetraInput::PointwiseMax{{{*/
+Input* TetraInput::PointwiseMax(Input* inputB){
+
+	/*Ouput*/
+	TetraInput* outinput=NULL;
+
+	/*Intermediaries*/
+	int         i;
+	TetraInput  *xinputB   = NULL;
+	const int   numnodes  = this->NumberofNodes();
+	IssmDouble *maxvalues = xNew<IssmDouble>(numnodes);
+
+	/*Check that inputB is of the same type*/
+	if(inputB->ObjectEnum()!=TetraInputEnum) _error_("Operation not permitted because inputB is of type " << EnumToStringx(inputB->ObjectEnum()));
+	xinputB=(TetraInput*)inputB;
+	if(xinputB->element_type!=this->element_type) _error_("Operation not permitted because inputB is of type " << EnumToStringx(xinputB->element_type));
+
+	/*Create point wise max*/
+	for(i=0;i<numnodes;i++){
+		if(this->values[i] < xinputB->values[i]) maxvalues[i]=xinputB->values[i];
+		else maxvalues[i]=this->values[i];
+	}
+
+	/*Create new Tetra vertex input (copy of current input)*/
+	outinput=new TetraInput(this->enum_type,&maxvalues[0],this->element_type);
+
+	/*Return output pointer*/
+	xDelete<IssmDouble>(maxvalues);
+	return outinput;
+
+}
+/*}}}*/
+/*FUNCTION TetraInput::PointwiseDivide{{{*/
+Input* TetraInput::PointwiseDivide(Input* inputB){
+
+	/*Ouput*/
+	TetraInput* outinput=NULL;
+
+	/*Intermediaries*/
+	TetraInput *xinputB  = NULL;
+	const int   numnodes = this->NumberofNodes();
+
+	/*Check that inputB is of the same type*/
+	if(inputB->ObjectEnum()!=TetraInputEnum)     _error_("Operation not permitted because inputB is of type " << EnumToStringx(inputB->ObjectEnum()));
+	xinputB=(TetraInput*)inputB;
+	if(xinputB->element_type!=this->element_type) _error_("Operation not permitted because inputB is of type " << EnumToStringx(xinputB->element_type));
+
+	/*Allocate intermediary*/
+	IssmDouble* AdotBvalues=xNew<IssmDouble>(numnodes);
+
+	/*Create point wise division*/
+	for(int i=0;i<numnodes;i++){
+		_assert_(xinputB->values[i]!=0);
+		AdotBvalues[i]=this->values[i]/xinputB->values[i];
+	}
+
+	/*Create new Tetra vertex input (copy of current input)*/
+	outinput=new TetraInput(this->enum_type,AdotBvalues,this->element_type);
+
+	/*Return output pointer*/
+	xDelete<IssmDouble>(AdotBvalues);
+	return outinput;
+
+}
+/*}}}*/
+/*FUNCTION TetraInput::Configure{{{*/
+void TetraInput::Configure(Parameters* parameters){
+	/*do nothing: */
+}
+/*}}}*/
Index: /issm/trunk/src/c/classes/Inputs/TetraInput.h
===================================================================
--- /issm/trunk/src/c/classes/Inputs/TetraInput.h	(revision 17806)
+++ /issm/trunk/src/c/classes/Inputs/TetraInput.h	(revision 17806)
@@ -0,0 +1,75 @@
+/*! \file TetraInput.h 
+ *  \brief: header file for TetraInput object
+ */
+
+#ifndef _TETRAINPUT_H_
+#define _TETRAINPUT_H_
+
+/*Headers:*/
+/*{{{*/
+#include "./Input.h"
+#include "../Elements/TetraRef.h"
+class Gauss;
+class Gauss;
+/*}}}*/
+
+class TetraInput: public Input,public TetraRef{
+
+	public:
+		int         enum_type;
+		IssmDouble* values;
+
+		/*TetraInput constructors, destructors*/
+		TetraInput();
+		TetraInput(int enum_type,IssmDouble* values,int element_type_in);
+		~TetraInput();
+
+		/*Object virtual functions definitions*/
+		void    Echo();
+		void    DeepEcho();
+		int     Id();
+		int     ObjectEnum();
+		Object *copy();
+
+		/*TetraInput management:*/
+		int    InstanceEnum();
+		Input* SpawnTriaInput(int index1,int index2,int index3);
+		Input* SpawnSegInput(int index1,int index2){_error_("not supported yet");};
+		Input* PointwiseDivide(Input* inputB);
+		Input* PointwiseMin(Input* inputB);
+		Input* PointwiseMax(Input* inputB);
+		int    GetResultInterpolation(void);
+		int    GetResultNumberOfNodes(void);
+		void   ResultToPatch(IssmDouble* values,int nodesperelement,int sid);
+		void   AddTimeValues(IssmDouble* values,int step,IssmDouble time){_error_("not supported yet");};
+		void   Configure(Parameters* parameters);
+
+		/*numerics*/
+		void GetInputValue(bool* pvalue){_error_("not implemented yet");}
+		void GetInputValue(int* pvalue){_error_("not implemented yet");}
+		void GetInputValue(IssmDouble* pvalue){_error_("not implemented yet");}
+		void GetInputValue(IssmDouble* pvalue,Gauss* gauss);
+		void GetInputValue(IssmDouble* pvalue,Gauss* gauss,IssmDouble time){_error_("not implemented yet");};
+		void GetInputValue(IssmDouble* pvalue,Gauss* gauss,int index){_error_("not implemented yet");};
+		void GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list,Gauss* gauss);
+		void GetInputAverage(IssmDouble* pvalue);
+		void GetInputAllTimeAverages(IssmDouble** pvalues,IssmDouble** ptimes, int* pnumtimes);
+		void GetInputUpToCurrentTimeAverages(IssmDouble** pvalues, IssmDouble** ptimes, int* pnumtimes, IssmDouble currenttime);
+		void ChangeEnum(int newenumtype);
+		void SquareMin(IssmDouble* psquaremin,Parameters* parameters);
+		void ConstrainMin(IssmDouble minimum);
+		void Set(IssmDouble setvalue);
+		void Scale(IssmDouble scale_factor);
+		void AXPY(Input* xinput,IssmDouble scalar);
+		void Constrain(IssmDouble cm_min, IssmDouble cm_max);
+		IssmDouble InfinityNorm(void);
+		IssmDouble Max(void);
+		IssmDouble MaxAbs(void);
+		IssmDouble Min(void);
+		IssmDouble MinAbs(void);
+		void Extrude(void){_error_("not supported yet");};
+		void VerticallyIntegrate(Input* thickness_input){_error_("not supported yet");};
+		void GetVectorFromInputs(Vector<IssmDouble>* vector,int* doflist);
+
+};
+#endif  /* _TETRAINPUT_H */
Index: /issm/trunk/src/c/classes/Inputs/TransientInput.cpp
===================================================================
--- /issm/trunk/src/c/classes/Inputs/TransientInput.cpp	(revision 17805)
+++ /issm/trunk/src/c/classes/Inputs/TransientInput.cpp	(revision 17806)
@@ -39,4 +39,19 @@
 }
 /*}}}*/
+/*FUNCTION TransientInput::TransientInput(int in_enum_type,IssmDouble* timesin,int N){{{*/
+TransientInput::TransientInput(int in_enum_type,IssmDouble* timesin,int N){
+
+	/*Set Enum*/
+	enum_type=in_enum_type;
+
+	/*Allocate values and timesteps, and copy: */
+	this->numtimesteps=N;
+	this->timesteps=xNew<IssmDouble>(N);
+	xMemCpy(this->timesteps,timesin,N);
+
+	inputs = new Inputs();
+	this->parameters=NULL;
+}
+/*}}}*/
 /*FUNCTION TransientInput::~TransientInput{{{*/
 TransientInput::~TransientInput(){
@@ -66,5 +81,5 @@
 	_printf_("---inputs: \n"); 
 	for(i=0;i<this->numtimesteps;i++){
-		_printf_("   time: " << this->timesteps[i] << "  \n");
+		_printf_("   time: " << this->timesteps[i]<<"  ");
 		((Input*)this->inputs->GetObjectByOffset(i))->Echo();
 	}
@@ -108,5 +123,5 @@
 /*}}}*/
 /*FUNCTION TransientInput::SpawnTriaInput{{{*/
-Input* TransientInput::SpawnTriaInput(int location){
+Input* TransientInput::SpawnTriaInput(int index1,int index2,int index3){
 
 	/*output*/
@@ -119,5 +134,5 @@
 	outinput->timesteps=xNew<IssmDouble>(this->numtimesteps);
 	xMemCpy(outinput->timesteps,this->timesteps,this->numtimesteps);
-	outinput->inputs=(Inputs*)this->inputs->SpawnTriaInputs(location);
+	outinput->inputs=(Inputs*)this->inputs->SpawnTriaInputs(index1,index2,index3);
 	outinput->parameters=this->parameters;
 
@@ -149,6 +164,6 @@
 
 /*Object functions*/
-/*FUNCTION TransientInput::GetInputValue(IssmDouble* pvalue,GaussTria* gauss){{{*/
-void TransientInput::GetInputValue(IssmDouble* pvalue,GaussTria* gauss){
+/*FUNCTION TransientInput::GetInputValue(IssmDouble* pvalue,Gauss* gauss){{{*/
+void TransientInput::GetInputValue(IssmDouble* pvalue,Gauss* gauss){
 	IssmDouble time;
 
@@ -165,10 +180,6 @@
 }
 /*}}}*/
-/*FUNCTION TransientInput::GetInputValue(IssmDouble* pvalue,GaussPenta* gauss){{{*/
-void TransientInput::GetInputValue(IssmDouble* pvalue,GaussPenta* gauss){
-	IssmDouble time;
-
-	/*First, recover current time from parameters: */
-	this->parameters->FindParam(&time,TimeEnum);
+/*FUNCTION TransientInput::GetInputValue(IssmDouble* pvalue,Gauss* gauss,IssmDouble time){{{*/
+void TransientInput::GetInputValue(IssmDouble* pvalue,Gauss* gauss,IssmDouble time){
 
 	/*Retrieve interpolated values for this time step: */
@@ -181,30 +192,6 @@
 }
 /*}}}*/
-/*FUNCTION TransientInput::GetInputValue(IssmDouble* pvalue,GaussTria* gauss,IssmDouble time){{{*/
-void TransientInput::GetInputValue(IssmDouble* pvalue,GaussTria* gauss,IssmDouble time){
-
-	/*Retrieve interpolated values for this time step: */
-	Input* input=GetTimeInput(time);
-
-	/*Call input function*/
-	input->GetInputValue(pvalue,gauss);
-
-	delete input;
-}
-/*}}}*/
-/*FUNCTION TransientInput::GetInputValue(IssmDouble* pvalue,GaussPenta* gauss,IssmDouble time){{{*/
-void TransientInput::GetInputValue(IssmDouble* pvalue,GaussPenta* gauss,IssmDouble time){
-
-	/*Retrieve interpolated values for this time step: */
-	Input* input=GetTimeInput(time);
-
-	/*Call input function*/
-	input->GetInputValue(pvalue,gauss);
-
-	delete input;
-}
-/*}}}*/
-/*FUNCTION TransientInput::GetInputDerivativeValue(IssmDouble* p, IssmDouble* xyz_list, GaussTria* gauss){{{*/
-void TransientInput::GetInputDerivativeValue(IssmDouble* p, IssmDouble* xyz_list, GaussTria* gauss){
+/*FUNCTION TransientInput::GetInputDerivativeValue(IssmDouble* p, IssmDouble* xyz_list, Gauss* gauss){{{*/
+void TransientInput::GetInputDerivativeValue(IssmDouble* p, IssmDouble* xyz_list, Gauss* gauss){
 
 	IssmDouble time;
@@ -220,5 +207,4 @@
 
 	delete input;
-
 }
 /*}}}*/
@@ -342,11 +328,41 @@
 }
 /*}}}*/
+/*FUNCTION TransientInput::AddTimeInput{{{*/
+void TransientInput::AddTimeInput(Input* input){
+
+	_assert_(this->inputs->Size()<this->numtimesteps);
+	inputs->AddObject(input);
+
+}
+/*}}}*/
 /*FUNCTION TransientInput::GetResultInterpolation{{{*/
-int  TransientInput::GetResultInterpolation(void){
-
-	IssmDouble time;
-	parameters->FindParam(&time,TimeEnum);
-	Input* input=GetTimeInput(time);
-	return input->GetResultInterpolation();
+int TransientInput::GetResultInterpolation(void){
+
+	IssmDouble time;
+	int        output;
+
+	parameters->FindParam(&time,TimeEnum);
+	Input* input=GetTimeInput(time);
+	output = input->GetResultInterpolation();
+
+	/*Clean up and return*/
+	delete input;
+	return output;
+
+}
+/*}}}*/
+/*FUNCTION TransientInput::GetResultNumberOfNodes{{{*/
+int TransientInput::GetResultNumberOfNodes(void){
+
+	IssmDouble time;
+	int        output;
+
+	parameters->FindParam(&time,TimeEnum);
+	Input* input=GetTimeInput(time);
+	output = input->GetResultNumberOfNodes();
+
+	/*Clean up and return*/
+	delete input;
+	return output;
 
 }
Index: /issm/trunk/src/c/classes/Inputs/TransientInput.h
===================================================================
--- /issm/trunk/src/c/classes/Inputs/TransientInput.h	(revision 17805)
+++ /issm/trunk/src/c/classes/Inputs/TransientInput.h	(revision 17806)
@@ -9,7 +9,7 @@
 /*{{{*/
 #include "./Input.h"
-class GaussTria;
+class Gauss;
 class Parameters;
-class GaussPenta;
+class Gauss;
 /*}}}*/
 
@@ -26,6 +26,8 @@
 		TransientInput();
 		TransientInput(int enum_type);
+		TransientInput(int in_enum_type,IssmDouble* times,int N);
 		~TransientInput();
 		void AddTimeInput(Input* input,IssmDouble time);
+		void AddTimeInput(Input* input);
 		/*}}}*/
 		/*Object virtual functions definitions:{{{*/
@@ -38,5 +40,5 @@
 		/*TransientInput management: {{{*/
 		int    InstanceEnum();
-		Input* SpawnTriaInput(int location);
+		Input* SpawnTriaInput(int index1,int index2,int index3);
 		Input* SpawnSegInput(int index1,int index2);
 		Input* PointwiseDivide(Input* forcingB){_error_("not implemented yet");};
@@ -44,4 +46,6 @@
 		Input* PointwiseMax(Input* forcingB){_error_("not implemented yet");};
 		int  GetResultInterpolation(void);
+		int  GetResultNumberOfNodes(void);
+		void ResultToPatch(IssmDouble* values,int nodesperelement,int sid){_error_("not supported yet");};
 		void Configure(Parameters* parameters);
 		/*}}}*/
@@ -50,26 +54,12 @@
 		void GetInputValue(int* pvalue){_error_("not implemented yet");};
 		void GetInputValue(IssmDouble* pvalue){_error_("not implemented yet");};
-		void GetInputValue(IssmDouble* pvalue,GaussSeg* gauss){_error_("not implemented yet");};
-		void GetInputValue(IssmDouble* pvalue,GaussTria* gauss);
-		void GetInputValue(IssmDouble* pvalue,GaussPenta* gauss);
-		void GetInputValue(IssmDouble* pvalue,GaussTria* gauss,IssmDouble time);
-		void GetInputValue(IssmDouble* pvalue,GaussPenta* gauss,IssmDouble time);
-		void GetInputValue(IssmDouble* pvalue,GaussTria* gauss ,int index){_error_("not implemented yet");};
-		void GetInputValue(IssmDouble* pvalue,GaussPenta* gauss ,int index){_error_("not implemented yet");};
-		void GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussSeg* gauss){_error_("not implemented yet");};
-		void GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussTria* gauss);
-		void GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussPenta* gauss){_error_("not implemented yet");};
+		void GetInputValue(IssmDouble* pvalue,Gauss* gauss);
+		void GetInputValue(IssmDouble* pvalue,Gauss* gauss,IssmDouble time);
+		void GetInputValue(IssmDouble* pvalue,Gauss* gauss ,int index){_error_("not implemented yet");};
+		void GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list,Gauss* gauss);
 		void GetInputAverage(IssmDouble* pvalue);
 		void GetInputAllTimeAverages(IssmDouble** pvalues,IssmDouble** ptimes, int* pnumtimes);
 		void GetInputUpToCurrentTimeAverages(IssmDouble** pvalues, IssmDouble** ptimes, int* pnumtimes, IssmDouble currenttime);
-		void GetVxStrainRate2d(IssmDouble* epsilonvx,IssmDouble* xyz_list, GaussTria* gauss){_error_("not implemented yet");};
-		void GetVyStrainRate2d(IssmDouble* epsilonvy,IssmDouble* xyz_list, GaussTria* gauss){_error_("not implemented yet");};
-		void GetVxStrainRate3d(IssmDouble* epsilonvx,IssmDouble* xyz_list, GaussPenta* gauss){_error_("not implemented yet");};
-		void GetVyStrainRate3d(IssmDouble* epsilonvy,IssmDouble* xyz_list, GaussPenta* gauss){_error_("not implemented yet");};
-		void GetVzStrainRate3d(IssmDouble* epsilonvz,IssmDouble* xyz_list, GaussPenta* gauss){_error_("not implemented yet");};
-		void GetVxStrainRate3dHO(IssmDouble* epsilonvx,IssmDouble* xyz_list, GaussPenta* gauss){_error_("not implemented yet");};
-		void GetVyStrainRate3dHO(IssmDouble* epsilonvy,IssmDouble* xyz_list, GaussPenta* gauss){_error_("not implemented yet");};
 		void ChangeEnum(int newenumtype);
-
 		void SquareMin(IssmDouble* psquaremin,Parameters* parameters);
 		void ConstrainMin(IssmDouble minimum){_error_("not implemented yet");};
Index: /issm/trunk/src/c/classes/Inputs/TriaInput.cpp
===================================================================
--- /issm/trunk/src/c/classes/Inputs/TriaInput.cpp	(revision 17805)
+++ /issm/trunk/src/c/classes/Inputs/TriaInput.cpp	(revision 17806)
@@ -50,9 +50,7 @@
 void TriaInput::DeepEcho(void){
 
-	_printf_("TriaInput:\n");
-	_printf_("   enum: " << this->enum_type << " (" << EnumToStringx(this->enum_type) << ")\n");
-	_printf_("   values: [");
+	_printf_(setw(15)<<"   TriaInput "<<setw(25)<<left<<EnumToStringx(this->enum_type)<<" [");
 	for(int i=0;i<this->NumberofNodes();i++) _printf_(" "<<this->values[i]);
-	_printf_("]\n");
+	_printf_("] ("<<EnumToStringx(this->element_type)<<")\n");
 }
 /*}}}*/
@@ -84,5 +82,5 @@
 /*}}}*/
 /*FUNCTION TriaInput::SpawnTriaInput{{{*/
-Input* TriaInput::SpawnTriaInput(int location){
+Input* TriaInput::SpawnTriaInput(int index1,int index2,int index3){
 
 	/*output*/
@@ -102,13 +100,19 @@
 	/*output*/
 	SegInput* outinput=NULL;
-	IssmDouble newvalues[2]; //Assume P1 interpolation only for now
-
-	/*Create arrow of indices depending on location (0=base 1=surface)*/
-
-	newvalues[0]=this->values[index1];
-	newvalues[1]=this->values[index2];
-
-	/*Create new Seg input*/
-	outinput=new SegInput(this->enum_type,&newvalues[0],P1Enum);
+
+	if(this->element_type==P0Enum){ 
+		outinput=new SegInput(this->enum_type,&this->values[0],P0Enum);
+	}
+	else{
+		/*Assume P1 interpolation only for now*/
+		IssmDouble newvalues[2];
+
+		/*Create array of indices depending on location (0=base 1=surface)*/
+		newvalues[0]=this->values[index1];
+		newvalues[1]=this->values[index2];
+
+		/*Create new Seg input*/
+		outinput=new SegInput(this->enum_type,&newvalues[0],P1Enum);
+	}
 
 	/*Assign output*/
@@ -124,71 +128,41 @@
 }
 /*}}}*/
+/*FUNCTION TriaInput::GetResultNumberOfNodes{{{*/
+int  TriaInput::GetResultNumberOfNodes(void){
+
+	return this->NumberofNodes();
+
+}
+/*}}}*/
+/*FUNCTION TriaInput::ResultToPatch{{{*/
+void TriaInput::ResultToPatch(IssmDouble* values,int nodesperelement,int sid){
+
+	int numnodes = this->NumberofNodes();
+
+	/*Some checks*/
+	_assert_(values);
+	_assert_(numnodes==nodesperelement);
+
+	/*Fill in arrays*/
+	for(int i=0;i<numnodes;i++) values[sid*numnodes + i] = this->values[i];
+}
+/*}}}*/
 
 /*Object functions*/
-/*FUNCTION TriaInput::GetInputValue(IssmDouble* pvalue,GaussTria* gauss){{{*/
-void TriaInput::GetInputValue(IssmDouble* pvalue,GaussTria* gauss){
+/*FUNCTION TriaInput::GetInputValue(IssmDouble* pvalue,Gauss* gauss){{{*/
+void TriaInput::GetInputValue(IssmDouble* pvalue,Gauss* gauss){
 
 	/*Call TriaRef function*/
-	TriaRef::GetInputValue(pvalue,&values[0],gauss);
-
-}
-/*}}}*/
-/*FUNCTION TriaInput::GetInputDerivativeValue(IssmDouble* p, IssmDouble* xyz_list, GaussTria* gauss){{{*/
-void TriaInput::GetInputDerivativeValue(IssmDouble* p, IssmDouble* xyz_list, GaussTria* gauss){
+	_assert_(gauss->Enum()==GaussTriaEnum);
+	TriaRef::GetInputValue(pvalue,&values[0],(GaussTria*)gauss);
+
+}
+/*}}}*/
+/*FUNCTION TriaInput::GetInputDerivativeValue(IssmDouble* p, IssmDouble* xyz_list, Gauss* gauss){{{*/
+void TriaInput::GetInputDerivativeValue(IssmDouble* p, IssmDouble* xyz_list, Gauss* gauss){
 
 	/*Call TriaRef function*/
-	TriaRef::GetInputDerivativeValue(p,&values[0],xyz_list,gauss);
-}
-/*}}}*/
-/*FUNCTION TriaInput::GetVxStrainRate2d{{{*/
-void TriaInput::GetVxStrainRate2d(IssmDouble* epsilonvx,IssmDouble* xyz_list, GaussTria* gauss){
-
-	/*Intermediary*/
-	int numnodes=this->NumberofNodes();
-	IssmDouble* B=xNew<IssmDouble>(numnodes*(NDOF2*numnodes));
-	IssmDouble* velocity=xNew<IssmDouble>(numnodes*NDOF2);
-
-	/*Get B matrix: */
-	GetBSSA(&B[0],xyz_list,gauss);
-
-	/*Here, we are computing the strain rate of (vx,0)*/
-	for(int i=0;i<numnodes;i++){
-		velocity[2*i+0]=this->values[i];
-		velocity[2*i+1]=0.;
-	}
-	/*Get epsilon(vx) = B*velocity*/
-	MatrixMultiply(&B[0],numnodes,NDOF2*numnodes,0,
-				&velocity[0],NDOF2*numnodes,1,0,
-				epsilonvx,0);
-
-	/*clean up*/
-	xDelete<IssmDouble>(B);
-	xDelete<IssmDouble>(velocity);
-}
-/*}}}*/
-/*FUNCTION TriaInput::GetVyStrainRate2d{{{*/
-void TriaInput::GetVyStrainRate2d(IssmDouble* epsilonvy,IssmDouble* xyz_list, GaussTria* gauss){
-
-	/*Intermediary*/
-	int numnodes=this->NumberofNodes();
-	IssmDouble* B=xNew<IssmDouble>(numnodes*(NDOF2*numnodes));
-	IssmDouble* velocity=xNew<IssmDouble>(numnodes*NDOF2);
-
-	/*Get B matrix: */
-	GetBSSA(&B[0],xyz_list,gauss);
-
-	/*Here, we are computing the strain rate of (0,vy)*/
-	for(int i=0;i<numnodes;i++){
-		velocity[2*i+0]=0.;
-		velocity[2*i+1]=this->values[i];
-	}
-	/*Get epsilon(vy) = B*velocity*/
-	MatrixMultiply(&B[0],numnodes,NDOF2*numnodes,0,
-				&velocity[0],NDOF2*numnodes,1,0,
-				epsilonvy,0);
-
-	/*clean up*/
-	xDelete<IssmDouble>(B);
-	xDelete<IssmDouble>(velocity);
+	_assert_(gauss->Enum()==GaussTriaEnum);
+	TriaRef::GetInputDerivativeValue(p,&values[0],xyz_list,(GaussTria*)gauss);
 }
 /*}}}*/
@@ -377,8 +351,6 @@
 /*FUNCTION TriaInput::GetVectorFromInputs{{{*/
 void TriaInput::GetVectorFromInputs(Vector<IssmDouble>* vector,int* doflist){
-
-	const int numnodes=this->NumberofNodes();
-	vector->SetValues(numnodes,doflist,this->values,INS_VAL);
-
+	const int numvertices=3;
+	vector->SetValues(numvertices,doflist,this->values,INS_VAL);
 } /*}}}*/
 /*FUNCTION TriaInput::PointwiseMin{{{*/
Index: /issm/trunk/src/c/classes/Inputs/TriaInput.h
===================================================================
--- /issm/trunk/src/c/classes/Inputs/TriaInput.h	(revision 17805)
+++ /issm/trunk/src/c/classes/Inputs/TriaInput.h	(revision 17806)
@@ -10,6 +10,6 @@
 #include "./Input.h"
 #include "../Elements/TriaRef.h"
-class GaussTria;
-class GaussPenta;
+class Gauss;
+class Gauss;
 /*}}}*/
 
@@ -34,5 +34,5 @@
 		/*TriaInput management:*/
 		int    InstanceEnum();
-		Input* SpawnTriaInput(int location);
+		Input* SpawnTriaInput(int index1,int index2,int index3);
 		Input* SpawnSegInput(int index1,int index2);
 		Input* PointwiseDivide(Input* inputB);
@@ -40,4 +40,6 @@
 		Input* PointwiseMax(Input* inputB);
 		int    GetResultInterpolation(void);
+		int    GetResultNumberOfNodes(void);
+		void   ResultToPatch(IssmDouble* values,int nodesperelement,int sid);
 		void   AddTimeValues(IssmDouble* values,int step,IssmDouble time){_error_("not supported yet");};
 		void   Configure(Parameters* parameters);
@@ -47,26 +49,12 @@
 		void GetInputValue(int* pvalue){_error_("not implemented yet");}
 		void GetInputValue(IssmDouble* pvalue){_error_("not implemented yet");}
-		void GetInputValue(IssmDouble* pvalue,GaussSeg* gauss){_error_("not implemented yet");};
-		void GetInputValue(IssmDouble* pvalue,GaussTria* gauss);
-		void GetInputValue(IssmDouble* pvalue,GaussPenta* gauss){_error_("not implemented yet");};
-		void GetInputValue(IssmDouble* pvalue,GaussTria* gauss,IssmDouble time){_error_("not implemented yet");};
-		void GetInputValue(IssmDouble* pvalue,GaussPenta* gauss,IssmDouble time){_error_("not implemented yet");};
-		void GetInputValue(IssmDouble* pvalue,GaussTria* gauss ,int index){_error_("not implemented yet");};
-		void GetInputValue(IssmDouble* pvalue,GaussPenta* gauss,int index){_error_("not implemented yet");};
-		void GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussSeg* gauss){_error_("not implemented yet");};
-		void GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussTria* gauss);
-		void GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussPenta* gauss){_error_("not implemented yet");};
+		void GetInputValue(IssmDouble* pvalue,Gauss* gauss);
+		void GetInputValue(IssmDouble* pvalue,Gauss* gauss,IssmDouble time){_error_("not implemented yet");};
+		void GetInputValue(IssmDouble* pvalue,Gauss* gauss,int index){_error_("not implemented yet");};
+		void GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list,Gauss* gauss);
 		void GetInputAverage(IssmDouble* pvalue);
 		void GetInputAllTimeAverages(IssmDouble** pvalues,IssmDouble** ptimes, int* pnumtimes);
 		void GetInputUpToCurrentTimeAverages(IssmDouble** pvalues, IssmDouble** ptimes, int* pnumtimes, IssmDouble currenttime);
-		void GetVxStrainRate2d(IssmDouble* epsilonvx,IssmDouble* xyz_list, GaussTria* gauss);
-		void GetVyStrainRate2d(IssmDouble* epsilonvy,IssmDouble* xyz_list, GaussTria* gauss);
-		void GetVxStrainRate3d(IssmDouble* epsilonvx,IssmDouble* xyz_list, GaussPenta* gauss){_error_("not implemented yet");};
-		void GetVyStrainRate3d(IssmDouble* epsilonvy,IssmDouble* xyz_list, GaussPenta* gauss){_error_("not implemented yet");};
-		void GetVzStrainRate3d(IssmDouble* epsilonvz,IssmDouble* xyz_list, GaussPenta* gauss){_error_("not implemented yet");};
-		void GetVxStrainRate3dHO(IssmDouble* epsilonvx,IssmDouble* xyz_list, GaussPenta* gauss){_error_("not implemented yet");};
-		void GetVyStrainRate3dHO(IssmDouble* epsilonvy,IssmDouble* xyz_list, GaussPenta* gauss){_error_("not implemented yet");};
 		void ChangeEnum(int newenumtype);
-
 		void SquareMin(IssmDouble* psquaremin,Parameters* parameters);
 		void ConstrainMin(IssmDouble minimum);
Index: /issm/trunk/src/c/classes/IoModel.cpp
===================================================================
--- /issm/trunk/src/c/classes/IoModel.cpp	(revision 17805)
+++ /issm/trunk/src/c/classes/IoModel.cpp	(revision 17806)
@@ -30,5 +30,7 @@
 	this->my_vertices=NULL;
 
-	this->meshtype=-1;
+	this->domaintype=-1;
+	this->domaindim=-1;
+	this->meshelementtype=-1;
 	this->numberofvertices=-1;
 	this->numberofelements=-1;
@@ -38,4 +40,5 @@
 	this->faces=NULL;
 	this->edges=NULL;
+	this->elementtofaceconnectivity      =NULL;
 	this->elementtoedgeconnectivity      =NULL;
 	this->singlenodetoelementconnectivity=NULL;
@@ -74,5 +77,7 @@
 	this->my_vertices = NULL;
 
-	FetchData(&this->meshtype,MeshTypeEnum);
+	FetchData(&this->domaintype,DomainTypeEnum);
+	FetchData(&this->domaindim,DomainDimensionEnum);
+	FetchData(&this->meshelementtype,MeshElementtypeEnum);
 	FetchData(&this->numberofvertices,MeshNumberofverticesEnum);
 	FetchData(&this->numberofelements,MeshNumberofelementsEnum);
@@ -80,4 +85,5 @@
 	this->faces                           = NULL;
 	this->edges                           = NULL;
+	this->elementtofaceconnectivity       = NULL;
 	this->elementtoedgeconnectivity       = NULL;
 	this->singlenodetoelementconnectivity = NULL;
@@ -125,4 +131,5 @@
 	xDelete<int>(this->faces);
 	xDelete<int>(this->edges);
+	xDelete<int>(this->elementtofaceconnectivity);
 	xDelete<int>(this->elementtoedgeconnectivity);
 	xDelete<int>(this->singlenodetoelementconnectivity);
@@ -158,11 +165,11 @@
 				_printf0_(" Enums in marshalled file are not compatible with compiled code          \n");
 				_printf0_("                                                                         \n");
+				_printf0_("   * If you are running ISSM on your local machine:                      \n");
+				_printf0_("     make sure that all the code is compiled and installed (make install)\n");
 				_printf0_("   * If you are running ISSM on a remote cluster:                        \n");
 				_printf0_("     make sure that you are using the same version of ISSM on your local \n");
 				_printf0_("     machine and remote cluster (you might need to run svn update)       \n");
-				_printf0_("   * If you are running ISSM on your local machine:                      \n");
-				_printf0_("     make sure that all the code is compiled (modules and executables)   \n");
 				_printf0_("   * If you are a developer and just added a new Enum:                   \n");
-				_printf0_("     you might need to run ./Synchronize.sh in src/c/EnumDefinitions     \n");
+				_printf0_("     you might need to run ./Synchronize.sh in src/c/shared/Enum         \n");
 				_printf0_("     and recompile                                                       \n");
 				_printf0_("=========================================================================\n");
@@ -1195,4 +1202,58 @@
 }
 /*}}}*/
+/*FUNCTION IoModel::FetchMultipleData(int** pvector, int* pM,int data_enum){{{*/
+void  IoModel::FetchMultipleData(int** pvector, int* pnum_instances,int data_enum){
+
+	int     num_instances;
+	fpos_t* file_positions=NULL;
+
+	/*output: */
+	int* vector=NULL;
+
+	/*intermediary: */
+	int          integer;
+	int         *codes   = NULL;
+	int          code;
+
+	/*recover my_rank:*/
+	int my_rank=IssmComm::GetRank();
+	
+	/*Get file pointers to beginning of the data (multiple instances of it): */
+	file_positions=this->SetFilePointersToData(&codes,NULL,&num_instances,data_enum);
+
+	if(num_instances){
+
+		/*Allocate vector :*/
+		vector=xNew<int>(num_instances);
+
+		for(int i=0;i<num_instances;i++){
+
+			if(my_rank==0){
+				code=codes[i];
+
+				if(code!=2)_error_("expecting an integer for enum " << EnumToStringx(data_enum));
+				
+				/*We have to read a integer from disk. First read the dimensions of the integer, then the integer: */
+				fsetpos(fid,file_positions+i);
+				if(my_rank==0){  
+					if(fread(&integer,sizeof(int),1,fid)!=1) _error_("could not read integer ");
+				}
+			}
+			ISSM_MPI_Bcast(&integer,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 
+
+			/*Assign: */
+			vector[i]=integer;
+		}
+	}
+			
+	/*Free ressources:*/
+	xDelete<fpos_t>(file_positions);
+	xDelete<int>(codes);
+
+	/*Assign output pointers: */
+	*pvector=vector;
+	*pnum_instances=num_instances;
+}
+/*}}}*/
 /*FUNCTION IoModel::FetchMultipleData(IssmDouble*** pmatrices,int** pmdims,int** pndims, int* pM,int data_enum){{{*/
 void  IoModel::FetchMultipleData(IssmDouble*** pmatrices,int** pmdims,int** pndims, int* pnumrecords,int data_enum){
@@ -1300,4 +1361,111 @@
 }
 /*}}}*/
+/*FUNCTION IoModel::FetchMultipleData(int*** pmatrices,int** pmdims,int** pndims, int* pM,int data_enum){{{*/
+void  IoModel::FetchMultipleData(int*** pmatrices,int** pmdims,int** pndims, int* pnumrecords,int data_enum){
+
+	int     num_instances;
+	fpos_t* file_positions=NULL;
+
+	/*output: */
+	int        **matrices = NULL;
+	int         *mdims    = NULL;
+	int         *ndims    = NULL;
+
+	/*intermediary: */
+	int          M, N;
+	IssmPDouble *pmatrix = NULL;
+	IssmDouble  *matrix  = NULL;
+	int         *integer_matrix=NULL;
+	int         *codes   = NULL;
+	int          code;
+
+	/*recover my_rank:*/
+	int my_rank=IssmComm::GetRank();
+	
+	/*Get file pointers to beginning of the data (multiple instances of it): */
+	file_positions=this->SetFilePointersToData(&codes,NULL,&num_instances,data_enum);
+
+	if(num_instances){
+
+		/*Allocate matrices :*/
+		matrices=xNew<int*>(num_instances);
+		mdims=xNew<int>(num_instances);
+		ndims=xNew<int>(num_instances);
+
+		for(int i=0;i<num_instances;i++){
+
+			if(my_rank==0){
+				code=codes[i];
+
+				if((code!=5) && (code!=6) && (code!=7))_error_("expecting a IssmDouble, integer or boolean matrix for enum " << EnumToStringx(data_enum));
+
+				/*We have to read a matrix from disk. First read the dimensions of the matrix, then the whole matrix: */
+				/*numberofelements: */
+				fsetpos(fid,file_positions+i);
+				if(fread(&M,sizeof(int),1,fid)!=1) _error_("could not read number of rows for matrix ");
+			}
+			ISSM_MPI_Bcast(&M,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 
+
+			if(my_rank==0){  
+				if(fread(&N,sizeof(int),1,fid)!=1) _error_("could not read number of columns for matrix ");
+			}
+			ISSM_MPI_Bcast(&N,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 
+
+
+			/*Now allocate matrix: */
+			if(M*N){
+				pmatrix=xNew<IssmPDouble>(M*N);
+				integer_matrix=xNew<int>(M*N);
+
+				/*Read matrix on node 0, then broadcast: */
+				if(my_rank==0){  
+					if(fread(pmatrix,M*N*sizeof(IssmPDouble),1,fid)!=1) _error_("could not read matrix ");
+				}
+				ISSM_MPI_Bcast(pmatrix,M*N,ISSM_MPI_PDOUBLE,0,IssmComm::GetComm()); 
+
+				_assert_(this->independents);
+				if(this->independents[data_enum]){
+					/*this data has already been checked out! So cancel all that we've done here, and return 
+					 * the data[data_enum] directly: */
+					matrix=this->data[data_enum];
+					for (int i=0;i<M*N;++i) integer_matrix[i]=reCast<int>(matrix[i]);
+				}
+				else{
+					for (int i=0;i<M*N;++i) integer_matrix[i]=pmatrix[i];
+				}
+				xDelete<IssmPDouble>(pmatrix);
+			}
+			else
+				integer_matrix=NULL;
+			
+			
+			/*Assign: */
+			mdims[i]=M;
+			matrices[i]=integer_matrix;
+			ndims[i]=N;
+		}
+	}
+			
+	/*Free ressources:*/
+	xDelete<fpos_t>(file_positions);
+	xDelete<int>(codes);
+
+	/*Assign output pointers: */
+	*pmatrices=matrices;
+	if(pmdims){
+		*pmdims=mdims;
+	}
+	else{
+		xDelete<int>(mdims);
+	}
+	if(pndims){
+		*pndims=ndims;
+	}
+	else{
+		xDelete<int>(ndims);
+	}
+	*pnumrecords=num_instances;
+}
+/*}}}*/
 /*FUNCTION IoModel::FetchDataToInput(Elements* elements,int vector_enum,IssmDouble default_value){{{*/
 void IoModel::FetchDataToInput(Elements* elements,int vector_enum,IssmDouble default_value){
@@ -1318,5 +1486,5 @@
 	for(int i=0;i<elements->Size();i++){
 		Element* element=dynamic_cast<Element*>(elements->GetObjectByOffset(i));
-		if(!doublearray) element->InputUpdateFromConstant(default_value,vector_enum); 
+		if(!doublearray) element->AddInput(vector_enum,&default_value,P0Enum); 
 		else             element->InputCreate(doublearray,this,M,N,vector_layout,vector_enum,code);//we need i to index into elements.
 	}
Index: /issm/trunk/src/c/classes/IoModel.h
===================================================================
--- /issm/trunk/src/c/classes/IoModel.h	(revision 17805)
+++ /issm/trunk/src/c/classes/IoModel.h	(revision 17806)
@@ -31,5 +31,7 @@
 
 		/*Mesh properties and connectivity tables*/
-		int  meshtype;
+		int  domaintype;
+		int  domaindim;
+		int  meshelementtype;
 		int  numberofvertices;
 		int  numberofelements;
@@ -40,4 +42,5 @@
 		int *edges;
 		int *elementtoedgeconnectivity;
+		int *elementtofaceconnectivity;
 		int *singlenodetoelementconnectivity;
 		int *numbernodetoelementconnectivity;
@@ -79,4 +82,6 @@
 		void        FetchMultipleData(char***   pstringarray,int* pnumstrings,int data_enum);
 		void        FetchMultipleData(IssmDouble*** pmatrixarray,int** pmdims,int** pndims, int* pnumrecords,int data_enum);
+		void        FetchMultipleData(int*** pmatrices,int** pmdims,int** pndims, int* pnumrecords,int data_enum);
+		void        FetchMultipleData(int** pvector, int* pnum_instances,int data_enum);
 		void        FetchData(Option **poption,int data_enum);
 		void        FetchData(int num,...);
Index: /issm/trunk/src/c/classes/Loads/Friction.cpp
===================================================================
--- /issm/trunk/src/c/classes/Loads/Friction.cpp	(revision 17805)
+++ /issm/trunk/src/c/classes/Loads/Friction.cpp	(revision 17806)
@@ -18,23 +18,17 @@
 /*FUNCTION Friction::Friction() {{{*/
 Friction::Friction(){
-	this->element_type=NULL;
-	this->inputs=NULL;
-	this->matpar=NULL;
+	this->element=NULL;
+	this->dim=0;
 }
 /*}}}*/
-/*FUNCTION Friction::Friction(const char* element_type, Inputs* inputs,Matpar* matpar,int analysis_type){{{*/
-Friction::Friction(const char* element_type_in,Inputs* inputs_in,Matpar* matpar_in, int in_analysis_type){
+/*FUNCTION Friction::Friction(Element* element,int dim){{{*/
+Friction::Friction(Element* element_in,int dim_in){
 
-	this->analysis_type=in_analysis_type;
-	this->inputs=inputs_in;
-	this->element_type=xNew<char>(strlen(element_type_in)+1);
-	xMemCpy<char>(this->element_type,element_type_in,(strlen(element_type_in)+1));
-
-	this->matpar=matpar_in;
+	this->element=element_in;
+	this->dim=dim_in;
 }
 /*}}}*/
 /*FUNCTION Friction::~Friction() {{{*/
 Friction::~Friction(){
-	xDelete<char>(element_type);
 }
 /*}}}*/
@@ -44,12 +38,9 @@
 void Friction::Echo(void){
 	_printf_("Friction:\n");
-	_printf_("   analysis_type: " << EnumToStringx(analysis_type) << "\n");
-	_printf_("   element_type: " << this->element_type << "\n");
-	inputs->Echo();
-	matpar->Echo();
+	_printf_("   dim: " << this->dim<< "\n");
 }
 /*}}}*/
-/*FUNCTION Friction::GetAlpha2(IssmDouble* palpha2, GaussTria* gauss,int vxenum,int vyenum,int vzenum){{{*/
-void Friction::GetAlpha2(IssmDouble* palpha2, GaussTria* gauss,int vxenum,int vyenum,int vzenum){
+/*FUNCTION Friction::GetAlpha2{{{*/
+void Friction::GetAlpha2(IssmDouble* palpha2, Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input){
 
 	/*This routine calculates the basal friction coefficient 
@@ -59,5 +50,4 @@
 	IssmDouble  r,s;
 	IssmDouble  drag_p, drag_q;
-	IssmDouble  gravity,rho_ice,rho_water;
 	IssmDouble  Neff;
 	IssmDouble  thickness,bed;
@@ -67,14 +57,12 @@
 
 	/*Recover parameters: */
-	inputs->GetInputValue(&drag_p,FrictionPEnum);
-	inputs->GetInputValue(&drag_q,FrictionQEnum);
-	this->GetInputValue(&thickness, gauss,ThicknessEnum);
-	this->GetInputValue(&bed, gauss,BedEnum);
-	this->GetInputValue(&drag_coefficient, gauss,FrictionCoefficientEnum);
-
-	/*Get material parameters: */
-	gravity=matpar->GetG();
-	rho_ice=matpar->GetRhoIce();
-	rho_water=matpar->GetRhoWater();
+	element->GetInputValue(&drag_p,FrictionPEnum);
+	element->GetInputValue(&drag_q,FrictionQEnum);
+	element->GetInputValue(&thickness, gauss,ThicknessEnum);
+	element->GetInputValue(&bed, gauss,BaseEnum);
+	element->GetInputValue(&drag_coefficient, gauss,FrictionCoefficientEnum);
+	IssmDouble rho_water   = element->GetMaterialParameter(MaterialsRhoWaterEnum);
+	IssmDouble rho_ice     = element->GetMaterialParameter(MaterialsRhoIceEnum);
+	IssmDouble gravity     = element->GetMaterialParameter(ConstantsGEnum);
 
 	//compute r and q coefficients: */
@@ -84,32 +72,30 @@
 	//From bed and thickness, compute effective pressure when drag is viscous:
 	Neff=gravity*(rho_ice*thickness+rho_water*bed);
+	if(Neff<0)Neff=0;
 
-	/*If effective pressure becomes negative, sliding becomes unstable (Paterson 4th edition p 148). This is because 
-	  the water pressure is so high, the ice sheet elevates over its ice bumps and slides. But the limit behaviour 
-	  for friction should be an ice shelf sliding (no basal drag). Therefore, for any effective pressure Neff < 0, we should 
-	  replace it by Neff=0 (ie, equival it to an ice shelf)*/
-	if (Neff<0)Neff=0;
-
-	if(strcmp(element_type,"1d")==0){
-		this->GetInputValue(&vx, gauss,vxenum);
-		vmag=sqrt(vx*vx);
+	switch(dim){
+		case 1:
+			vx_input->GetInputValue(&vx,gauss);
+			vmag=sqrt(vx*vx);
+			break;
+		case 2:
+			vx_input->GetInputValue(&vx,gauss);
+			vy_input->GetInputValue(&vy,gauss);
+			vmag=sqrt(vx*vx+vy*vy);
+			break;
+		case 3:
+			vx_input->GetInputValue(&vx,gauss);
+			vy_input->GetInputValue(&vy,gauss);
+			vz_input->GetInputValue(&vz,gauss);
+			vmag=sqrt(vx*vx+vy*vy+vz*vz);
+			break;
+		default:
+			_error_("not supported");
 	}
-	else if(strcmp(element_type,"2d")==0){
-		this->GetInputValue(&vx, gauss,vxenum);
-		this->GetInputValue(&vy, gauss,vyenum);
-		vmag=sqrt(pow(vx,2)+pow(vy,2));
-	}
-	else if (strcmp(element_type,"3d")==0){
-		this->GetInputValue(&vx, gauss,vxenum);
-		this->GetInputValue(&vy, gauss,vyenum);
-		this->GetInputValue(&vz, gauss,vzenum);
-		vmag=sqrt(pow(vx,2)+pow(vy,2)+pow(vz,2));
-	}
-	else _error_("element_type "<< element_type << " not supported yet");
 
 	/*Checks that s-1>0 if v=0*/
-        if(vmag==0 && (s-1)<0) _error_("velocity is 0 and (s-1)=" << (s-1) << "<0, alpha2 is Inf");
+	if(vmag==0. && (s-1.)<0.) _error_("velocity is 0 and (s-1)=" << (s-1.) << "<0, alpha2 is Inf");
 
-	alpha2=pow(drag_coefficient,2)*pow(Neff,r)*pow(vmag,(s-1));
+	alpha2=drag_coefficient*drag_coefficient*pow(Neff,r)*pow(vmag,(s-1.));
 	_assert_(!xIsNan<IssmDouble>(alpha2));
 
@@ -118,70 +104,6 @@
 }
 /*}}}*/
-/*FUNCTION Friction::GetAlpha2(IssmDouble* palpha2, GaussPenta* gauss,int vxenum,int vyenum,int vzenum){{{*/
-void Friction::GetAlpha2(IssmDouble* palpha2, GaussPenta* gauss,int vxenum,int vyenum,int vzenum){
-
-	/*This routine calculates the basal friction coefficient 
-	  alpha2= drag^2 * Neff ^r * vel ^s, with Neff=rho_ice*g*thickness+rho_ice*g*bed, r=q/p and s=1/p**/
-
-	/*diverse: */
-	IssmDouble  r,s;
-	IssmDouble  drag_p, drag_q;
-	IssmDouble  gravity,rho_ice,rho_water;
-	IssmDouble  Neff;
-	IssmDouble  thickness,bed;
-	IssmDouble  vx,vy,vz,vmag;
-	IssmDouble  drag_coefficient;
-	IssmDouble  alpha2;
-
-	/*Recover parameters: */
-	inputs->GetInputValue(&drag_p,FrictionPEnum);
-	inputs->GetInputValue(&drag_q,FrictionQEnum);
-	this->GetInputValue(&thickness, gauss,ThicknessEnum);
-	this->GetInputValue(&bed, gauss,BedEnum);
-	this->GetInputValue(&drag_coefficient, gauss,FrictionCoefficientEnum);
-
-	/*Get material parameters: */
-	gravity=matpar->GetG();
-	rho_ice=matpar->GetRhoIce();
-	rho_water=matpar->GetRhoWater();
-
-	//compute r and q coefficients: */
-	r=drag_q/drag_p;
-	s=1./drag_p;
-
-	//From bed and thickness, compute effective pressure when drag is viscous:
-	Neff=gravity*(rho_ice*thickness+rho_water*bed);
-
-	/*If effective pressure becomes negative, sliding becomes unstable (Paterson 4th edition p 148). This is because 
-	  the water pressure is so high, the ice sheet elevates over its ice bumps and slides. But the limit behaviour 
-	  for friction should be an ice shelf sliding (no basal drag). Therefore, for any effective pressure Neff < 0, we should 
-	  replace it by Neff=0 (ie, equival it to an ice shelf)*/
-	if (Neff<0)Neff=0;
-
-	if(strcmp(element_type,"2d")==0){
-		this->GetInputValue(&vx, gauss,vxenum);
-		this->GetInputValue(&vy, gauss,vyenum);
-		vmag=sqrt(pow(vx,2)+pow(vy,2));
-	}
-	else if (strcmp(element_type,"3d")==0){
-		this->GetInputValue(&vx, gauss,vxenum);
-		this->GetInputValue(&vy, gauss,vyenum);
-		this->GetInputValue(&vz, gauss,vzenum);
-		vmag=sqrt(pow(vx,2)+pow(vy,2)+pow(vz,2));
-	}
-	else _error_("element_type "<< element_type << " not supported yet");
-
-	/*Checks that s-1>0 if v=0*/
-	if(vmag==0 && (s-1)<0) _error_("velocity is 0 and (s-1)=" << (s-1) << "<0, alpha_complement is Inf");
-
-	alpha2=pow(drag_coefficient,2)*pow(Neff,r)*pow(vmag,(s-1));
-	_assert_(!xIsNan<IssmDouble>(alpha2));
-
-	/*Assign output pointers:*/
-	*palpha2=alpha2;
-}
-/*}}}*/
-/*FUNCTION Friction::GetAlphaComplement(IssmDouble* palpha_complement, GaussTria* gauss,int vxenum,int vyenum,int vzenum) {{{*/
-void Friction::GetAlphaComplement(IssmDouble* palpha_complement, GaussTria* gauss,int vxenum,int vyenum,int vzenum){
+/*FUNCTION Friction::GetAlphaComplement(IssmDouble* palpha_complement, Gauss* gauss,int vxenum,int vyenum,int vzenum) {{{*/
+void Friction::GetAlphaComplement(IssmDouble* palpha_complement, Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input){
 
 	/* FrictionGetAlpha2 computes alpha2= drag^2 * Neff ^r * vel ^s, with Neff=rho_ice*g*thickness+rho_ice*g*bed, r=q/p and s=1/p. 
@@ -196,18 +118,15 @@
 	IssmDouble  drag_coefficient;
 	IssmDouble  bed,thickness;
-	IssmDouble  gravity,rho_ice,rho_water;
 	IssmDouble  alpha_complement;
 
 	/*Recover parameters: */
-	inputs->GetInputValue(&drag_p,FrictionPEnum);
-	inputs->GetInputValue(&drag_q,FrictionQEnum);
-	this->GetInputValue(&thickness, gauss,ThicknessEnum);
-	this->GetInputValue(&bed, gauss,BedEnum);
-	this->GetInputValue(&drag_coefficient, gauss,FrictionCoefficientEnum);
-
-	/*Get material parameters: */
-	gravity=matpar->GetG();
-	rho_ice=matpar->GetRhoIce();
-	rho_water=matpar->GetRhoWater();
+	element->GetInputValue(&drag_p,FrictionPEnum);
+	element->GetInputValue(&drag_q,FrictionQEnum);
+	element->GetInputValue(&thickness, gauss,ThicknessEnum);
+	element->GetInputValue(&bed, gauss,BaseEnum);
+	element->GetInputValue(&drag_coefficient, gauss,FrictionCoefficientEnum);
+	IssmDouble rho_water   = element->GetMaterialParameter(MaterialsRhoWaterEnum);
+	IssmDouble rho_ice     = element->GetMaterialParameter(MaterialsRhoIceEnum);
+	IssmDouble gravity     = element->GetMaterialParameter(ConstantsGEnum);
 
 	//compute r and q coefficients: */
@@ -217,29 +136,31 @@
 	//From bed and thickness, compute effective pressure when drag is viscous:
 	Neff=gravity*(rho_ice*thickness+rho_water*bed);
-
-	/*If effective pressure becomes negative, sliding becomes unstable (Paterson 4th edition p 148). This is because 
-	  the water pressure is so high, the ice sheet elevates over its ice bumps and slides. But the limit behaviour 
-	  for friction should be an ice shelf sliding (no basal drag). Therefore, for any effective pressure Neff < 0, we should 
-	  replace it by Neff=0 (ie, equival it to an ice shelf)*/
-	if (Neff<0)Neff=0;
+	if(Neff<0)Neff=0;
 
 	//We need the velocity magnitude to evaluate the basal stress:
-	if(strcmp(element_type,"2d")==0){
-		this->GetInputValue(&vx, gauss,vxenum);
-		this->GetInputValue(&vy, gauss,vyenum);
-		vmag=sqrt(pow(vx,2)+pow(vy,2));
+	switch(dim){
+		case 1:
+			vx_input->GetInputValue(&vx,gauss);
+			vmag=sqrt(vx*vx);
+			break;
+		case 2:
+			vx_input->GetInputValue(&vx,gauss);
+			vy_input->GetInputValue(&vy,gauss);
+			vmag=sqrt(vx*vx+vy*vy);
+			break;
+		case 3:
+			vx_input->GetInputValue(&vx,gauss);
+			vy_input->GetInputValue(&vy,gauss);
+			vz_input->GetInputValue(&vz,gauss);
+			vmag=sqrt(vx*vx+vy*vy+vz*vz);
+			break;
+		default:
+			_error_("not supported");
 	}
-	else if (strcmp(element_type,"3d")==0){
-		this->GetInputValue(&vx, gauss,vxenum);
-		this->GetInputValue(&vy, gauss,vyenum);
-		this->GetInputValue(&vz, gauss,vzenum);
-		vmag=sqrt(pow(vx,2)+pow(vy,2)+pow(vz,2));
-	}
-	else _error_("element_type "<< element_type << " not supported yet");
 
 	/*Checks that s-1>0 if v=0*/
-	if(vmag==0 && (s-1)<0) _error_("velocity is 0 and (s-1)=" << (s-1) << "<0, alpha_complement is Inf");
+	if(vmag==0. && (s-1.)<0.) _error_("velocity is 0 and (s-1)=" << (s-1.) << "<0, alpha2 is Inf");
 
-	alpha_complement=pow(Neff,r)*pow(vmag,(s-1));            _assert_(!xIsNan<IssmDouble>(alpha_complement));
+	alpha_complement=pow(Neff,r)*pow(vmag,(s-1));_assert_(!xIsNan<IssmDouble>(alpha_complement));
 
 	/*Assign output pointers:*/
@@ -247,85 +168,2 @@
 }
 /*}}}*/
-/*FUNCTION Friction::GetAlphaComplement(IssmDouble* palpha_complement, GaussPenta* gauss,int vxenum,int vyenum,int vzenum) {{{*/
-void Friction::GetAlphaComplement(IssmDouble* palpha_complement, GaussPenta* gauss,int vxenum,int vyenum,int vzenum){
-
-	/* FrictionGetAlpha2 computes alpha2= drag^2 * Neff ^r * vel ^s, with Neff=rho_ice*g*thickness+rho_ice*g*bed, r=q/p and s=1/p. 
-	 * FrictionGetAlphaComplement is used in control methods on drag, and it computes: 
-	 * alpha_complement= Neff ^r * vel ^s*/
-
-	/*diverse: */
-	IssmDouble  r,s;
-	IssmDouble  vx,vy,vz,vmag;
-	IssmDouble  drag_p,drag_q;
-	IssmDouble  Neff;
-	IssmDouble  drag_coefficient;
-	IssmDouble  bed,thickness;
-	IssmDouble  gravity,rho_ice,rho_water;
-	IssmDouble  alpha_complement;
-
-	/*Recover parameters: */
-	inputs->GetInputValue(&drag_p,FrictionPEnum);
-	inputs->GetInputValue(&drag_q,FrictionQEnum);
-	this->GetInputValue(&thickness, gauss,ThicknessEnum);
-	this->GetInputValue(&bed, gauss,BedEnum);
-	this->GetInputValue(&drag_coefficient, gauss,FrictionCoefficientEnum);
-
-	/*Get material parameters: */
-	gravity=matpar->GetG();
-	rho_ice=matpar->GetRhoIce();
-	rho_water=matpar->GetRhoWater();
-
-	//compute r and q coefficients: */
-	r=drag_q/drag_p;
-	s=1./drag_p;
-
-	//From bed and thickness, compute effective pressure when drag is viscous:
-	Neff=gravity*(rho_ice*thickness+rho_water*bed);
-
-	/*If effective pressure becomes negative, sliding becomes unstable (Paterson 4th edition p 148). This is because 
-	  the water pressure is so high, the ice sheet elevates over its ice bumps and slides. But the limit behaviour 
-	  for friction should be an ice shelf sliding (no basal drag). Therefore, for any effective pressure Neff < 0, we should 
-	  replace it by Neff=0 (ie, equival it to an ice shelf)*/
-	if (Neff<0)Neff=0;
-
-	//We need the velocity magnitude to evaluate the basal stress:
-	if(strcmp(element_type,"2d")==0){
-		this->GetInputValue(&vx, gauss,vxenum);
-		this->GetInputValue(&vy, gauss,vyenum);
-		vmag=sqrt(pow(vx,2)+pow(vy,2));
-	}
-	else if (strcmp(element_type,"3d")==0){
-		this->GetInputValue(&vx, gauss,vxenum);
-		this->GetInputValue(&vy, gauss,vyenum);
-		this->GetInputValue(&vz, gauss,vzenum);
-		vmag=sqrt(pow(vx,2)+pow(vy,2)+pow(vz,2));
-	}
-	else _error_("element_type "<< element_type << " not supported yet");
-
-	/*Checks that s-1>0 if v=0*/
-	if(vmag==0 && (s-1)<0) _error_("velocity is 0 and (s-1)=" << (s-1) << "<0, alpha_complement is Inf");
-
-	alpha_complement=pow(Neff,r)*pow(vmag,(s-1));            _assert_(!xIsNan<IssmDouble>(alpha_complement));
-
-	/*Assign output pointers:*/
-	*palpha_complement=alpha_complement;
-}
-/*}}}*/
-/*FUNCTION Friction::GetInputValue{{{*/
-void Friction::GetInputValue(IssmDouble* pvalue,GaussTria* gauss,int enum_type){
-
-	Input* input=inputs->GetInput(enum_type);
-	if(!input) _error_("input " << EnumToStringx(enum_type) << " not found");
-	input->GetInputValue(pvalue,gauss);
-
-}
-/*}}}*/
-/*FUNCTION Friction::GetInputValue{{{*/
-void Friction::GetInputValue(IssmDouble* pvalue,GaussPenta* gauss,int enum_type){
-
-	Input* input=inputs->GetInput(enum_type);
-	if(!input) _error_("input " << EnumToStringx(enum_type) << " not found");
-	input->GetInputValue(pvalue,gauss);
-
-}
-/*}}}*/
Index: /issm/trunk/src/c/classes/Loads/Friction.h
===================================================================
--- /issm/trunk/src/c/classes/Loads/Friction.h	(revision 17805)
+++ /issm/trunk/src/c/classes/Loads/Friction.h	(revision 17806)
@@ -19,21 +19,15 @@
 		int analysis_type;
 
-		char* element_type;
-		Inputs* inputs;
-		Matpar* matpar;
+		Element* element;
+		int      dim;
 
 		/*methods: */
 		Friction();
-		Friction(const char* element_type, Inputs* inputs,Matpar* matpar, int analysis_type);
+		Friction(Element* element_in,int dim_in);
 		~Friction();
 
 		void  Echo(void);
-		void  GetAlpha2(IssmDouble* palpha2, GaussTria* gauss,int vxenum,int vyenum,int vzenum);
-		void  GetAlpha2(IssmDouble* palpha2, GaussPenta* gauss,int vxenum,int vyenum,int vzenum);
-		void  GetAlphaComplement(IssmDouble* alpha_complement, GaussTria* gauss,int vxenum,int vyenum,int vzenum);
-		void  GetAlphaComplement(IssmDouble* alpha_complement, GaussPenta* gauss,int vxenum,int vyenum,int vzenum);
-		void  GetInputValue(IssmDouble* pvalue,GaussTria* gauss,int enum_type);
-		void  GetInputValue(IssmDouble* pvalue,GaussPenta* gauss,int enum_type);
-
+		void  GetAlpha2(IssmDouble* palpha2, Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input);
+		void  GetAlphaComplement(IssmDouble* alpha_complement,Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input);
 };
 
Index: /issm/trunk/src/c/classes/Loads/Load.h
===================================================================
--- /issm/trunk/src/c/classes/Loads/Load.h	(revision 17805)
+++ /issm/trunk/src/c/classes/Loads/Load.h	(revision 17806)
@@ -24,5 +24,4 @@
 
 	public: 
-
 		virtual       ~Load(){};
 		virtual void  Configure(Elements* elements,Loads* loads,Nodes* nodes,Vertices* vertices,Materials* materials,Parameters* parameters)=0;
Index: /issm/trunk/src/c/classes/Loads/Numericalflux.cpp
===================================================================
--- /issm/trunk/src/c/classes/Loads/Numericalflux.cpp	(revision 17805)
+++ /issm/trunk/src/c/classes/Loads/Numericalflux.cpp	(revision 17806)
@@ -23,5 +23,4 @@
 /*FUNCTION Numericalflux::Numericalflux(){{{*/
 Numericalflux::Numericalflux(){
-	this->inputs     = NULL;
 	this->parameters = NULL;
 	this->helement   = NULL;
@@ -112,4 +111,5 @@
 	this->id=numericalflux_id;
 	this->analysis_type=in_analysis_type;
+	this->flux_type = numericalflux_type;
 
 	/*Hooks: */
@@ -118,8 +118,4 @@
 	this->helement  =new Hook(numericalflux_elem_ids,1); // take only the first element for now
 
-	//intialize  and add as many inputs per element as requested: 
-	this->inputs=new Inputs();
-	this->inputs->AddInput(new IntInput(NumericalfluxTypeEnum,numericalflux_type));
-
 	//this->parameters: we still can't point to it, it may not even exist. Configure will handle this.
 	this->parameters=NULL;
@@ -130,5 +126,4 @@
 /*FUNCTION Numericalflux::~Numericalflux(){{{*/
 Numericalflux::~Numericalflux(){
-	delete inputs;
 	this->parameters=NULL;
 	delete helement;
@@ -144,9 +139,9 @@
 	_printf_("   id: " << id << "\n");
 	_printf_("   analysis_type: " << EnumToStringx(analysis_type) << "\n");
+	_printf_("   flux_type: " << this->flux_type<< "\n");
 	hnodes->Echo();
 	hvertices->Echo();
 	helement->Echo();
 	_printf_("   parameters: " << parameters << "\n");
-	_printf_("   inputs: " << inputs << "\n");
 }
 /*}}}*/
@@ -157,4 +152,5 @@
 	_printf_("   id: " << id << "\n");
 	_printf_("   analysis_type: " << EnumToStringx(analysis_type) << "\n");
+	_printf_("   flux_type: " << this->flux_type<< "\n");
 	hnodes->DeepEcho();
 	hvertices->DeepEcho();
@@ -165,7 +161,4 @@
 	else
 	 _printf_("      NULL\n");
-	_printf_("   inputs\n");
-	inputs->DeepEcho();
-
 }		
 /*}}}*/
@@ -192,10 +185,6 @@
 	numericalflux->id=this->id;
 	numericalflux->analysis_type=this->analysis_type;
-	if(this->inputs){
-		numericalflux->inputs=(Inputs*)this->inputs->Copy();
-	}
-	else{
-		numericalflux->inputs=new Inputs();
-	}
+	numericalflux->flux_type=this->flux_type;
+
 	/*point parameters: */
 	numericalflux->parameters=this->parameters;
@@ -303,10 +292,8 @@
 void Numericalflux::GetNodesSidList(int* sidlist){
 
-	int type;
-	inputs->GetInputValue(&type,NumericalfluxTypeEnum);
 	_assert_(sidlist);
 	_assert_(nodes);
 
-	switch(type){
+	switch(this->flux_type){
 		case InternalEnum:
 			for(int i=0;i<NUMNODES_INTERNAL;i++) sidlist[i]=nodes[i]->Sid();
@@ -316,5 +303,5 @@
 			return;
 		default:
-			_error_("Numericalflux type " << EnumToStringx(type) << " not supported yet");
+			_error_("Numericalflux type " << EnumToStringx(this->flux_type) << " not supported yet");
 	}
 }
@@ -323,10 +310,8 @@
 void Numericalflux::GetNodesLidList(int* lidlist){
 
-	int type;
-	inputs->GetInputValue(&type,NumericalfluxTypeEnum);
 	_assert_(lidlist);
 	_assert_(nodes);
 
-	switch(type){
+	switch(this->flux_type){
 		case InternalEnum:
 			for(int i=0;i<NUMNODES_INTERNAL;i++) lidlist[i]=nodes[i]->Lid();
@@ -336,5 +321,5 @@
 			return;
 		default:
-			_error_("Numericalflux type " << EnumToStringx(type) << " not supported yet");
+			_error_("Numericalflux type " << EnumToStringx(this->flux_type) << " not supported yet");
 	}
 }
@@ -343,8 +328,5 @@
 int Numericalflux::GetNumberOfNodes(void){
 
-	int type;
-	inputs->GetInputValue(&type,NumericalfluxTypeEnum);
-
-	switch(type){
+	switch(this->flux_type){
 		case InternalEnum:
 			return NUMNODES_INTERNAL;
@@ -352,5 +334,5 @@
 			return NUMNODES_BOUNDARY;
 		default:
-			_error_("Numericalflux type " << EnumToStringx(type) << " not supported yet");
+			_error_("Numericalflux type " << EnumToStringx(this->flux_type) << " not supported yet");
 	}
 
@@ -444,8 +426,5 @@
 ElementMatrix* Numericalflux::CreateKMatrixMasstransport(void){
 
-	int type;
-	inputs->GetInputValue(&type,NumericalfluxTypeEnum);
-
-	switch(type){
+	switch(this->flux_type){
 		case InternalEnum:
 			return CreateKMatrixMasstransportInternal();
@@ -476,5 +455,5 @@
 	/*Initialize Element matrix and return if necessary*/
 	Tria*  tria=(Tria*)element;
-	if(tria->NoIceInElement()) return NULL;
+	if(!tria->IsIceInElement()) return NULL;
 	ElementMatrix* Ke=new ElementMatrix(nodes,NUMNODES_INTERNAL,this->parameters);
 
@@ -540,5 +519,5 @@
 	ElementMatrix* Ke = NULL;
 	Tria*  tria=(Tria*)element;
-	if(tria->NoIceInElement()) return NULL;
+	if(!tria->IsIceInElement()) return NULL;
 
 	/*Retrieve all inputs and parameters*/
@@ -597,8 +576,5 @@
 ElementMatrix* Numericalflux::CreateKMatrixBalancethickness(void){
 
-	int type;
-	inputs->GetInputValue(&type,NumericalfluxTypeEnum);
-
-	switch(type){
+	switch(this->flux_type){
 		case InternalEnum:
 			return CreateKMatrixBalancethicknessInternal();
@@ -629,5 +605,5 @@
 	/*Initialize Element matrix and return if necessary*/
 	Tria*  tria=(Tria*)element;
-	if(tria->NoIceInElement()) return NULL;
+	if(!tria->IsIceInElement()) return NULL;
 	ElementMatrix* Ke=new ElementMatrix(nodes,NUMNODES_INTERNAL,this->parameters);
 
@@ -692,5 +668,5 @@
 	ElementMatrix* Ke = NULL;
 	Tria*  tria=(Tria*)element;
-	if(tria->NoIceInElement()) return NULL;
+	if(!tria->IsIceInElement()) return NULL;
 
 	/*Retrieve all inputs and parameters*/
@@ -748,8 +724,5 @@
 ElementMatrix* Numericalflux::CreateKMatrixAdjointBalancethickness(void){
 
-	int type;
-	inputs->GetInputValue(&type,NumericalfluxTypeEnum);
-
-	switch(type){
+	switch(this->flux_type){
 		case InternalEnum:
 			return CreateKMatrixAdjointBalancethicknessInternal();
@@ -780,8 +753,5 @@
 ElementVector* Numericalflux::CreatePVectorMasstransport(void){
 
-	int type;
-	inputs->GetInputValue(&type,NumericalfluxTypeEnum);
-
-	switch(type){
+	switch(this->flux_type){
 		case InternalEnum:
 			return CreatePVectorMasstransportInternal();
@@ -818,5 +788,5 @@
 	ElementVector* pe = NULL;
 	Tria*  tria=(Tria*)element;
-	if(tria->NoIceInElement()) return NULL;
+	if(!tria->IsIceInElement()) return NULL;
 
 	/*Retrieve all inputs and parameters*/
@@ -874,8 +844,5 @@
 ElementVector* Numericalflux::CreatePVectorBalancethickness(void){
 
-	int type;
-	inputs->GetInputValue(&type,NumericalfluxTypeEnum);
-
-	switch(type){
+	switch(this->flux_type){
 		case InternalEnum:
 			return CreatePVectorBalancethicknessInternal();
@@ -912,5 +879,5 @@
 	ElementVector* pe = NULL;
 	Tria*  tria=(Tria*)element;
-	if(tria->NoIceInElement()) return NULL;
+	if(!tria->IsIceInElement()) return NULL;
 
 	/*Retrieve all inputs and parameters*/
Index: /issm/trunk/src/c/classes/Loads/Numericalflux.h
===================================================================
--- /issm/trunk/src/c/classes/Loads/Numericalflux.h	(revision 17805)
+++ /issm/trunk/src/c/classes/Loads/Numericalflux.h	(revision 17806)
@@ -10,5 +10,4 @@
 class Hook;
 class Parameters;
-class Inputs;
 class IoModel;
 class Element;
@@ -22,4 +21,5 @@
 		int id;
 		int analysis_type;
+		int flux_type;
 
 		/*Hooks*/
@@ -33,5 +33,4 @@
 		Node       **nodes;
 		Parameters  *parameters;
-		Inputs      *inputs;
 
 		/*Numericalflux constructors,destructors {{{*/
@@ -54,5 +53,4 @@
 		void InputUpdateFromConstant(int constant, int name){/*Do nothing*/};
 		void InputUpdateFromConstant(bool constant, int name){_error_("Not implemented yet!");}
-		void InputUpdateFromSolution(IssmDouble* solution){_error_("Not implemented yet!");}
 		void InputUpdateFromIoModel(int index, IoModel* iomodel){_error_("not implemented yet");};
 		/*}}}*/
Index: /issm/trunk/src/c/classes/Loads/Pengrid.cpp
===================================================================
--- /issm/trunk/src/c/classes/Loads/Pengrid.cpp	(revision 17805)
+++ /issm/trunk/src/c/classes/Loads/Pengrid.cpp	(revision 17806)
@@ -13,4 +13,5 @@
 #include "../classes.h"
 #include "shared/shared.h"
+#include "../../analyses/analyses.h"
 /*}}}*/
 
@@ -21,5 +22,4 @@
 /*FUNCTION Pengrid::Pengrid(){{{*/
 Pengrid::Pengrid(){
-	this->inputs=NULL;
 	this->parameters=NULL;
 	this->hnode=NULL;
@@ -62,7 +62,4 @@
 	this->hmatpar=new Hook(&pengrid_matpar_id,1);
 
-	//initialize inputs: none needed
-	this->inputs=new Inputs();
-
 	//this->parameters: we still can't point to it, it may not even exist. Configure will handle this.
 	this->parameters=NULL;
@@ -79,5 +76,4 @@
 /*FUNCTION Pengrid::~Pengrid(){{{*/
 Pengrid::~Pengrid(){
-	delete inputs;
 	delete hnode;
 	delete helement;
@@ -106,6 +102,4 @@
 	_printf_("   parameters\n");
 	parameters->DeepEcho();
-	_printf_("   inputs\n");
-	inputs->DeepEcho();
 }
 /*}}}*/
@@ -129,10 +123,5 @@
 	pengrid->id=this->id;
 	pengrid->analysis_type=this->analysis_type;
-	if(this->inputs){
-		pengrid->inputs=(Inputs*)this->inputs->Copy();
-	}
-	else{
-		pengrid->inputs=new Inputs();
-	}
+
 	/*point parameters: */
 	pengrid->parameters=this->parameters;
@@ -192,6 +181,21 @@
 void  Pengrid::CreatePVector(Vector<IssmDouble>* pf){
 
-	/*No loads applied, do nothing: */
-	return;
+	ElementVector* pe=NULL;
+	int analysis_type;
+	this->parameters->FindParam(&analysis_type,AnalysisTypeEnum);
+
+	switch(analysis_type){
+		
+	case HydrologyDCInefficientAnalysisEnum:
+		pe = CreatePVectorHydrologyDCInefficient();
+		break;
+	default:
+		/*No loads applied, do nothing: */
+		return;
+	}
+	if(pe){
+		pe->AddToGlobal(pf);
+		delete pe;
+	}
 
 }
@@ -230,5 +234,4 @@
 
 	switch(analysis_type){
-		#ifdef _HAVE_THERMAL_
 		case ThermalAnalysisEnum:
 			Ke=PenaltyCreateKMatrixThermal(kmax);
@@ -237,15 +240,7 @@
 			Ke=PenaltyCreateKMatrixMelting(kmax);
 			break;
-		#endif
-		#ifdef _HAVE_HYDROLOGY_
 		case HydrologyDCInefficientAnalysisEnum:
 			Ke=PenaltyCreateKMatrixHydrologyDCInefficient(kmax);
 			break;
-		#endif
-		#ifdef _HAVE_DAMAGE_
-		case DamageEvolutionAnalysisEnum:
-			Ke=PenaltyCreateKMatrixDamageEvolution(kmax);
-			break;
-		#endif
 		default:
 			_error_("analysis " << analysis_type << " (" << EnumToStringx(analysis_type) << ") not supported yet");
@@ -268,5 +263,4 @@
 
 	switch(analysis_type){
-		#ifdef _HAVE_THERMAL_
 		case ThermalAnalysisEnum:
 			pe=PenaltyCreatePVectorThermal(kmax);
@@ -277,16 +271,7 @@
 		case StressbalanceAnalysisEnum: case AdjointHorizAnalysisEnum:
 			break;
-		#endif
-		#ifdef _HAVE_HYDROLOGY_
 		case HydrologyDCInefficientAnalysisEnum:
 			pe=PenaltyCreatePVectorHydrologyDCInefficient(kmax);
 			break;
-		#endif
-		#ifdef _HAVE_DAMAGE_
-		case DamageEvolutionAnalysisEnum:
-			pe=PenaltyCreatePVectorDamageEvolution(kmax);
-			break;
-		#endif
-
 		default:
 			_error_("analysis " << analysis_type << " (" << EnumToStringx(analysis_type) << ") not supported yet");
@@ -381,11 +366,5 @@
 /*FUNCTION Pengrid::InputUpdateFromConstant(IssmDouble constant, int name) {{{*/
 void  Pengrid::InputUpdateFromConstant(IssmDouble constant, int name){
-	switch(name){
-
-		case MeltingOffsetEnum:
-			inputs->AddInput(new DoubleInput(name,constant));
-			return;
-
-	}
+	/*Nothing*/
 }
 /*}}}*/
@@ -407,9 +386,4 @@
 }
 /*}}}*/
-/*FUNCTION Pengrid::InputUpdateFromSolution{{{*/
-void  Pengrid::InputUpdateFromSolution(IssmDouble* solution){
-	/*Nothing updated yet*/
-}
-/*}}}*/		
 
 /*Pengrid management:*/
@@ -426,5 +400,4 @@
 		return;
 	}
-	#ifdef _HAVE_THERMAL_
 	else if (analysis_type==ThermalAnalysisEnum){
 		ConstraintActivateThermal(punstable);
@@ -434,18 +407,8 @@
 		return;
 	}
-	#endif
-	#ifdef _HAVE_HYDROLOGY_
 	else if (analysis_type==HydrologyDCInefficientAnalysisEnum){
 		ConstraintActivateHydrologyDCInefficient(punstable);
 		return;
 	}
-	#endif
-	#ifdef _HAVE_DAMAGE_
-	else if (analysis_type==DamageEvolutionAnalysisEnum){
-		ConstraintActivateDamageEvolution(punstable);
-		return;
-	}
-	#endif
-
 	else{
 		_error_("analysis: " << EnumToStringx(analysis_type) << " not supported yet");
@@ -454,5 +417,4 @@
 }
 /*}}}*/
-#ifdef _HAVE_THERMAL_
 /*FUNCTION Pengrid::ConstraintActivateThermal {{{*/
 void  Pengrid::ConstraintActivateThermal(int* punstable){
@@ -531,5 +493,5 @@
 	ElementMatrix* Ke=new ElementMatrix(&node,1,this->parameters);
 
-	/*Retrieve all inputs and parameters*/
+	/*Retrieve all parameters*/
 	penta->GetInputValue(&pressure,node,PressureEnum);
 	penta->GetInputValue(&temperature,node,TemperatureEnum);
@@ -582,8 +544,8 @@
 	ElementVector* pe=new ElementVector(&node,NUMVERTICES,this->parameters);
 
-	/*Retrieve all inputs and parameters*/
+	/*Retrieve all parameters*/
 	penta->GetInputValue(&pressure,node,PressureEnum);
 	penta->GetInputValue(&temperature,node,TemperatureEnum);
-	inputs->GetInputValue(&melting_offset,MeltingOffsetEnum);
+	parameters->FindParam(&melting_offset,MeltingOffsetEnum);
 	parameters->FindParam(&dt,TimesteppingTimeStepEnum);
 	parameters->FindParam(&penalty_factor,ThermalPenaltyFactorEnum);
@@ -621,5 +583,5 @@
 	ElementVector* pe=new ElementVector(&node,1,this->parameters);
 
-	/*Retrieve all inputs and parameters*/
+	/*Retrieve all parameters*/
 	penta->GetInputValue(&pressure,node,PressureEnum);
 	parameters->FindParam(&penalty_factor,ThermalPenaltyFactorEnum);
@@ -634,15 +596,15 @@
 }
 /*}}}*/
-#endif
-#ifdef _HAVE_HYDROLOGY_
 /*FUNCTION Pengrid::ConstraintActivateHydrologyDCInefficient{{{*/
 void  Pengrid::ConstraintActivateHydrologyDCInefficient(int* punstable){
 
 	//   The penalty is stable if it doesn't change during two consecutive iterations.   
-	int        unstable        = 0;
+	int        unstable=0;
 	int        new_active;
+	int        penalty_lock;
 	IssmDouble pressure;
 	IssmDouble h;
 	IssmDouble h_max;	
+	HydrologyDCInefficientAnalysis* inefanalysis = NULL;
 
 	/*check that pengrid is not a clone (penalty to be added only once)*/
@@ -652,103 +614,25 @@
 		return;
 	}
-
-	/*Get sediment water head h*/
-	element->GetInputValue(&h,node,SedimentHeadEnum);
-	element->GetHydrologyDCInefficientHmax(&h_max,node);
-	if (h>h_max)
-	 new_active=1;
-	else
-	 new_active=0;
-
-	if(this->active==new_active)
-	 unstable=0;
-	else
-	 unstable=1;
-
-	/*Set penalty flag*/
-	this->active=new_active;
-
-	/*Assign output pointers:*/
-	*punstable=unstable;
-}
-/*}}}*/
-/*FUNCTION Pengrid::PenaltyCreateKMatrixHydrologyDCInefficient {{{*/
-ElementMatrix* Pengrid::PenaltyCreateKMatrixHydrologyDCInefficient(IssmDouble kmax){
-
-	IssmDouble    penalty_factor;
-
-	/*Retrieve parameters*/
-	parameters->FindParam(&penalty_factor,HydrologydcPenaltyFactorEnum);
-
-	/*Initialize Element matrix and return if necessary*/
-	if(!this->active) return NULL;
-	ElementMatrix* Ke=new ElementMatrix(&node,NUMVERTICES,this->parameters);
-
-	Ke->values[0]=kmax*pow(10.,penalty_factor);
-
-	/*Clean up and return*/
-	return Ke;
-}
-/*}}}*/
-/*FUNCTION Pengrid::PenaltyCreatePVectorHydrologyDCInefficient {{{*/
-ElementVector* Pengrid::PenaltyCreatePVectorHydrologyDCInefficient(IssmDouble kmax){
-
-	IssmDouble h_max;
-	IssmDouble penalty_factor;
-
-	/*Initialize Element matrix and return if necessary*/
-	if(!this->active) return NULL;
-	ElementVector* pe=new ElementVector(&node,1,this->parameters);
-
-	/*Retrieve parameters*/
-	parameters->FindParam(&penalty_factor,HydrologydcPenaltyFactorEnum);
-
-	/*Get h_max and compute penalty*/
-	element->GetHydrologyDCInefficientHmax(&h_max,node);
-	pe->values[0]=kmax*pow(10.,penalty_factor)*h_max;
-
-	/*Clean up and return*/
-	return pe;
-}
-/*}}}*/
-#endif
-#ifdef _HAVE_DAMAGE_
-/*FUNCTION Pengrid::ConstraintActivateDamageEvolution {{{*/
-void  Pengrid::ConstraintActivateDamageEvolution(int* punstable){
-
-	//   The penalty is stable if it doesn't change during to successive iterations.   
-	IssmDouble max_damage;
-	IssmDouble damage;
-	int        new_active;
-	int        unstable=0;
-	int        penalty_lock;
-
-	/*check that pengrid is not a clone (penalty to be added only once)*/
-	if (node->IsClone()){
+	if(!element->IsOnBase()){
 		unstable=0;
+		active=0;
 		*punstable=unstable;
 		return;
 	}
 
-	//First recover damage  using the element: */
-	element->GetMaterialInputValue(&damage,node,DamageDbarEnum);
-
-	//Recover our data:
-	parameters->FindParam(&penalty_lock,DamagePenaltyLockEnum);
-	parameters->FindParam(&max_damage,DamageMaxDamageEnum);
-	
-	//Figure out if damage>max_damage, in which case, this penalty needs to be activated.
-	//Would need to do the same for damage<0 if penalties are used.  For now, ConstraintStatex 
-	//is not called in solutionsequence_damage_nonlinear, so no penalties are applied.
-
-	if (damage>max_damage){
-		new_active=1;
+	/*Get sediment water head h*/
+	inefanalysis = new HydrologyDCInefficientAnalysis();
+	element->GetInputValue(&h,node,SedimentHeadEnum);
+	inefanalysis->GetHydrologyDCInefficientHmax(&h_max,element,node);
+	parameters->FindParam(&penalty_lock,HydrologydcPenaltyLockEnum);
+
+	if (h>h_max){
+	 new_active=1;
 	}
 	else{
-		new_active=0;
-	}
-
-	//Figure out stability of this penalty
-	if (active==new_active){
+	 new_active=0;
+	}
+
+	if(this->active==new_active){
 		unstable=0;
 	}
@@ -762,19 +646,21 @@
 		if(zigzag_counter>penalty_lock){
 			unstable=0;
-			active=1;
+			active=0;
 		}
 	}
-
-	//Set penalty flag
-	active=new_active;
-
-	//*Assign output pointers:*/
+	/*Set penalty flag*/
+	this->active=new_active;
+
+	/*Assign output pointers:*/
+	delete inefanalysis;
 	*punstable=unstable;
 }
 /*}}}*/
-/*FUNCTION Pengrid::PenaltyCreateKMatrixDamageEvolution {{{*/
-ElementMatrix* Pengrid::PenaltyCreateKMatrixDamageEvolution(IssmDouble kmax){
-
+/*FUNCTION Pengrid::PenaltyCreateKMatrixHydrologyDCInefficient {{{*/
+ElementMatrix* Pengrid::PenaltyCreateKMatrixHydrologyDCInefficient(IssmDouble kmax){
 	IssmDouble    penalty_factor;
+
+	/*Retrieve parameters*/
+	parameters->FindParam(&penalty_factor,HydrologydcPenaltyFactorEnum);
 
 	/*Initialize Element matrix and return if necessary*/
@@ -782,7 +668,4 @@
 	ElementMatrix* Ke=new ElementMatrix(&node,NUMVERTICES,this->parameters);
 
-	/*recover parameters: */
-	parameters->FindParam(&penalty_factor,DamagePenaltyFactorEnum);
-
 	Ke->values[0]=kmax*pow(10.,penalty_factor);
 
@@ -791,27 +674,46 @@
 }
 /*}}}*/
-/*FUNCTION Pengrid::PenaltyCreatePVectorDamageEvolution {{{*/
-ElementVector* Pengrid::PenaltyCreatePVectorDamageEvolution(IssmDouble kmax){
-
+/*FUNCTION Pengrid::PenaltyCreatePVectorHydrologyDCInefficient {{{*/
+ElementVector* Pengrid::PenaltyCreatePVectorHydrologyDCInefficient(IssmDouble kmax){
+
+	IssmDouble h_max;
 	IssmDouble penalty_factor;
-	IssmDouble max_damage;
+	HydrologyDCInefficientAnalysis* inefanalysis = NULL;
 
 	/*Initialize Element matrix and return if necessary*/
 	if(!this->active) return NULL;
 	ElementVector* pe=new ElementVector(&node,1,this->parameters);
-
-	//Recover our data:
-	parameters->FindParam(&penalty_factor,DamagePenaltyFactorEnum);
-	parameters->FindParam(&max_damage,DamageMaxDamageEnum);
-
-	//right hand side penalizes to max_damage
-	pe->values[0]=kmax*pow(10.,penalty_factor)*max_damage;
+	inefanalysis = new HydrologyDCInefficientAnalysis();
+
+	/*Retrieve parameters*/
+	parameters->FindParam(&penalty_factor,HydrologydcPenaltyFactorEnum);
+
+	/*Get h_max and compute penalty*/
+	inefanalysis->GetHydrologyDCInefficientHmax(&h_max,element,node);
+
+	pe->values[0]=kmax*pow(10.,penalty_factor)*h_max;
+
+	/*Clean up and return*/
+	delete inefanalysis;
+	return pe;
+}
+/*}}}*/
+/*FUNCTION Pengrid::CreatePVectorHydrologyDCInefficient {{{*/
+ElementVector* Pengrid::CreatePVectorHydrologyDCInefficient(void){
+
+	IssmDouble moulin_load,dt;
+
+	/*Initialize Element matrix*/
+	ElementVector* pe=new ElementVector(&node,1,this->parameters);
+
+	this->element->GetInputValue(&moulin_load,node,HydrologydcBasalMoulinInputEnum);
+	parameters->FindParam(&dt,TimesteppingTimeStepEnum);
+
+	if(dt!=0.0) pe->values[0]=moulin_load*dt;
 
 	/*Clean up and return*/
 	return pe;
-}
-/*}}}*/
-#endif
-
+ }
+/*}}}*/
 /*FUNCTION Pengrid::ResetConstraint {{{*/
 void  Pengrid::ResetConstraint(void){
Index: /issm/trunk/src/c/classes/Loads/Pengrid.h
===================================================================
--- /issm/trunk/src/c/classes/Loads/Pengrid.h	(revision 17805)
+++ /issm/trunk/src/c/classes/Loads/Pengrid.h	(revision 17806)
@@ -23,6 +23,6 @@
 	private: 
 
-		int		id;
-		int analysis_type;
+		int        id;
+		int        analysis_type;
 
 		/*Hooks*/
@@ -37,5 +37,4 @@
 
 		Parameters* parameters; //pointer to solution parameters
-		Inputs*  inputs;
 
 		/*internals: */
@@ -64,5 +63,4 @@
 		void  InputUpdateFromConstant(int constant, int name);
 		void  InputUpdateFromConstant(bool constant, int name);
-		void  InputUpdateFromSolution(IssmDouble* solution);
 		void  InputUpdateFromIoModel(int index, IoModel* iomodel){_error_("not implemented yet");};
 		/*}}}*/
@@ -84,5 +82,4 @@
 		/*}}}*/
 		/*Pengrid management {{{*/
-		#ifdef _HAVE_THERMAL_
 		ElementMatrix* PenaltyCreateKMatrixThermal(IssmDouble kmax);
 		ElementMatrix* PenaltyCreateKMatrixMelting(IssmDouble kmax);
@@ -90,17 +87,9 @@
 		ElementVector* PenaltyCreatePVectorMelting(IssmDouble kmax);
 		void           ConstraintActivateThermal(int* punstable);
-		#endif
-		#ifdef _HAVE_DAMAGE_
-		ElementMatrix* PenaltyCreateKMatrixDamageEvolution(IssmDouble kmax);
-		ElementVector* PenaltyCreatePVectorDamageEvolution(IssmDouble kmax);
-		void           ConstraintActivateDamageEvolution(int* punstable);
-		#endif
-
-		#ifdef _HAVE_HYDROLOGY_
 		ElementMatrix* PenaltyCreateKMatrixHydrologyDCInefficient(IssmDouble kmax);
 		ElementVector* PenaltyCreatePVectorHydrologyDCInefficient(IssmDouble kmax);
 		void           ConstraintActivateHydrologyDCInefficient(int* punstable);
-		#endif
 		void  ConstraintActivate(int* punstable);
+		ElementVector* CreatePVectorHydrologyDCInefficient(void);
 		void  ResetConstraint(void);
 		/*}}}*/
Index: /issm/trunk/src/c/classes/Loads/Penpair.h
===================================================================
--- /issm/trunk/src/c/classes/Loads/Penpair.h	(revision 17805)
+++ /issm/trunk/src/c/classes/Loads/Penpair.h	(revision 17806)
@@ -44,5 +44,4 @@
 		void  InputUpdateFromConstant(int constant, int name);
 		void  InputUpdateFromConstant(bool constant, int name);
-		void  InputUpdateFromSolution(IssmDouble* solution){_error_("Not implemented yet!");}
 		void  InputUpdateFromIoModel(int index, IoModel* iomodel){_error_("not implemented yet");};
 		/*}}}*/
Index: /issm/trunk/src/c/classes/Loads/Riftfront.cpp
===================================================================
--- /issm/trunk/src/c/classes/Loads/Riftfront.cpp	(revision 17805)
+++ /issm/trunk/src/c/classes/Loads/Riftfront.cpp	(revision 17806)
@@ -22,5 +22,4 @@
 /*FUNCTION Riftfront::Riftfront(){{{*/
 Riftfront::Riftfront(){
-	this->inputs=NULL;
 	this->parameters=NULL;
 	this->hnodes=NULL;
@@ -90,18 +89,10 @@
 	this->state=reCast<int,IssmDouble>(*(iomodel->Data(RiftsRiftstructEnum)+RIFTINFOSIZE*i+11));
 
-	//intialize inputs, and add as many inputs per element as requested: 
-	this->inputs=new Inputs();
-
-	riftfront_type=SegmentRiftfrontEnum;
-	riftfront_fill = reCast<int,IssmDouble>(*(iomodel->Data(RiftsRiftstructEnum)+RIFTINFOSIZE*i+7));
-	riftfront_friction=*(iomodel->Data(RiftsRiftstructEnum)+RIFTINFOSIZE*i+8);
-	riftfront_fractionincrement=*(iomodel->Data(RiftsRiftstructEnum)+RIFTINFOSIZE*i+10);
-	riftfront_shelf=reCast<bool,IssmDouble>(iomodel->Data(MaskGroundediceLevelsetEnum)[node1-1]<0.);
-
-	this->inputs->AddInput(new IntInput(RiftfrontTypeEnum,riftfront_type));
-	this->inputs->AddInput(new IntInput(FillEnum,riftfront_fill));
-	this->inputs->AddInput(new DoubleInput(FrictionEnum,riftfront_friction));
-	this->inputs->AddInput(new DoubleInput(FractionIncrementEnum,riftfront_fractionincrement));
-	this->inputs->AddInput(new BoolInput(SegmentOnIceShelfEnum,riftfront_shelf));
+	//intialize properties
+	this->type=SegmentRiftfrontEnum;
+	this->fill = reCast<int,IssmDouble>(*(iomodel->Data(RiftsRiftstructEnum)+RIFTINFOSIZE*i+7));
+	this->friction=*(iomodel->Data(RiftsRiftstructEnum)+RIFTINFOSIZE*i+8);
+	this->fractionincrement=*(iomodel->Data(RiftsRiftstructEnum)+RIFTINFOSIZE*i+10);
+	this->shelf=reCast<bool,IssmDouble>(iomodel->Data(MaskGroundediceLevelsetEnum)[node1-1]<0.);
 
 	//parameters and hooked fields: we still can't point to them, they may not even exist. Configure will handle this.
@@ -115,7 +106,5 @@
 /*FUNCTION Riftfront::~Riftfront(){{{*/
 Riftfront::~Riftfront(){
-	delete inputs;
 	this->parameters=NULL;
-
 	delete hnodes;
 	delete helements;
@@ -127,13 +116,4 @@
 /*FUNCTION Riftfront::Echo {{{*/
 void Riftfront::Echo(void){
-
-	Input* input=NULL;
-	int fill;
-	IssmDouble friction,fractionincrement;
-
-	/*recover some inputs first: */
-	input=(Input*)this->inputs->GetInput(FillEnum); input->GetInputValue(&fill);
-	input=(Input*)this->inputs->GetInput(FrictionEnum); input->GetInputValue(&friction);
-	input=(Input*)this->inputs->GetInput(FractionIncrementEnum); input->GetInputValue(&fractionincrement);
 
 	_printf_("Riftfront:\n");
@@ -144,5 +124,4 @@
 	_printf_("   hmatpar: " << hmatpar << "\n");
 	_printf_("   parameters: " << parameters << "\n");
-	_printf_("   inputs: " << inputs << "\n");
 	_printf_("   internal parameters: \n");
 	_printf_("   normal: " << normal[0] << "|" << normal[1] << "\n");
@@ -173,6 +152,4 @@
 	_printf_("   parameters\n");
 	if(parameters)parameters->DeepEcho();
-	_printf_("   inputs\n");
-	if(inputs)inputs->DeepEcho();
 }
 /*}}}*/
@@ -197,10 +174,10 @@
 	riftfront->id=this->id;
 	riftfront->analysis_type=this->analysis_type;
-	if(this->inputs){
-		riftfront->inputs=(Inputs*)this->inputs->Copy();
-	}
-	else{
-		riftfront->inputs=new Inputs();
-	}
+	riftfront->type=this->type;
+	riftfront->fill=this->fill;
+	riftfront->friction=this->friction;
+	riftfront->fractionincrement=this->fractionincrement;
+	riftfront->shelf=this->shelf;
+
 	/*point parameters: */
 	riftfront->parameters=this->parameters;
@@ -237,11 +214,4 @@
 /*FUNCTION Riftfront::InputUpdateFromConstant(bool constant,int name) {{{*/
 void  Riftfront::InputUpdateFromConstant(bool constant,int name){
-
-	/*Check that name is a Riftfront input*/
-	if (!IsInput(name)) return;
-
-	/*update input*/
-	this->inputs->AddInput(new BoolInput(name,constant));
-
 }
 /*}}}*/
@@ -249,10 +219,4 @@
 void  Riftfront::InputUpdateFromConstant(IssmDouble constant,int name){
 
-	/*Check that name is a Riftfront input*/
-	if (!IsInput(name)) return;
-
-	/*update input*/
-	this->inputs->AddInput(new DoubleInput(name,constant));
-
 }
 /*}}}*/
@@ -260,10 +224,5 @@
 void    Riftfront::InputUpdateFromVector(IssmDouble* vector, int name, int type){
 
-	/*Check that name is a Riftfront input*/
-	if (!IsInput(name)) return;
-
-	/*update input*/
 	_error_("not implemented yet");
-	//this->inputs->AddInput(new DoubleInput(name,constant));
 
 }
@@ -458,5 +417,4 @@
 	IssmDouble  h[2];
 	IssmDouble  penalty_offset;
-	IssmDouble  friction;
 
 	/*Objects: */
@@ -475,5 +433,4 @@
 	/*Get some parameters: */
 	this->parameters->FindParam(&penalty_offset,StressbalancePenaltyFactorEnum);
-	this->inputs->GetInputValue(&friction,FrictionEnum);
 	tria1->GetInputValue(&h[0],nodes[0],ThicknessEnum);
 	tria2->GetInputValue(&h[1],nodes[1],ThicknessEnum);
@@ -547,6 +504,4 @@
 	IssmDouble pressure_melange;
 	IssmDouble pressure_water;
-	int        fill;
-	bool       shelf;
 
 	/*Objects: */
@@ -564,6 +519,4 @@
 
 	/*Get some inputs: */
-	this->inputs->GetInputValue(&fill,FillEnum);
-	this->inputs->GetInputValue(&shelf,SegmentOnIceShelfEnum);
 	rho_ice=matpar->GetRhoIce();
 	rho_water=matpar->GetRhoWater();
@@ -573,6 +526,6 @@
 	if (h[0]!=h[1])_error_("different thicknesses not supported for rift fronts");
 	thickness=h[0];
-	tria1->GetInputValue(&b[0],nodes[0],BedEnum);
-	tria2->GetInputValue(&b[1],nodes[1],BedEnum);
+	tria1->GetInputValue(&b[0],nodes[0],BaseEnum);
+	tria2->GetInputValue(&b[1],nodes[1],BaseEnum);
 	if (b[0]!=b[1])_error_("different beds not supported for rift fronts");
 	bed=b[0];
@@ -636,5 +589,5 @@
 
 	IssmDouble  penetration;
-	int         activate;
+	bool        activate;
 	int         unstable;
 	IssmDouble  vx1;
@@ -642,5 +595,4 @@
 	IssmDouble  vx2;
 	IssmDouble  vy2;
-	IssmDouble  fractionincrement;
 
 	/*Objects: */
@@ -671,7 +623,4 @@
 		return 1;
 	}
-
-	/*recover parameters: */
-	this->inputs->GetInputValue(&fractionincrement,FractionIncrementEnum);
 
 	/*First recover velocity: */
@@ -685,6 +634,6 @@
 
 	/*activation: */
-	if(penetration<0)activate=1;
-	else  activate=0;
+	if(penetration<0)activate=true;
+	else  activate=false;
 
 	/*Here, we try to avoid zigzaging. When a penalty activates and deactivates for more than penalty_lock times, 
@@ -734,15 +683,2 @@
 }
 /*}}}*/
-/*FUNCTION Riftfront::IsInput{{{*/
-bool Riftfront::IsInput(int name){
-	if (
-				name==ConvergedEnum ||
-				name==ThicknessEnum ||
-				name==SurfaceEnum ||
-				name==BedEnum 
-		){
-		return true;
-	}
-	else return false;
-}
-/*}}}*/
Index: /issm/trunk/src/c/classes/Loads/Riftfront.h
===================================================================
--- /issm/trunk/src/c/classes/Loads/Riftfront.h	(revision 17805)
+++ /issm/trunk/src/c/classes/Loads/Riftfront.h	(revision 17806)
@@ -11,5 +11,4 @@
 class Hook;
 class Parameters;
-class Inputs;
 class IoModel;
 /*}}}*/
@@ -20,4 +19,11 @@
 		int		id;
 		int     analysis_type;
+
+		/*properties*/
+		int        type;
+		int        fill;
+		IssmDouble friction;
+		IssmDouble fractionincrement;
+		bool       shelf;
 
 		/*hooks: */
@@ -44,5 +50,4 @@
 
 		Parameters *parameters;           //pointer to solution parameters
-		Inputs     *inputs;
 
 		/*Riftfrontconstructors,destructors: {{{*/
@@ -65,6 +70,5 @@
 		void    InputUpdateFromConstant(int constant, int name){_error_("Not implemented yet!");}
 		void    InputUpdateFromConstant(bool constant, int name);
-		void    InputUpdateFromSolution(IssmDouble* solution){_error_("Not implemented yet!");}
-		void  InputUpdateFromIoModel(int index, IoModel* iomodel){_error_("not implemented yet");};
+		void    InputUpdateFromIoModel(int index, IoModel* iomodel){_error_("not implemented yet");};
 		/*}}}*/
 		/*Load virtual functions definitions: {{{*/
@@ -90,5 +94,4 @@
 		void  FreezeConstraints(void);
 		bool  IsFrozen(void);
-		bool  IsInput(int name);
 		/*}}}*/
 };
Index: /issm/trunk/src/c/classes/Materials/Material.h
===================================================================
--- /issm/trunk/src/c/classes/Materials/Material.h	(revision 17805)
+++ /issm/trunk/src/c/classes/Materials/Material.h	(revision 17806)
@@ -12,4 +12,5 @@
 #include "../../datastructures/datastructures.h"
 #include "../Update.h"
+class Element;
 class Elements;
 /*}}}*/
@@ -18,16 +19,12 @@
 
 	public: 
-		Inputs*  inputs;
-		virtual       ~Material(){};
+		virtual ~Material(){};
 		/*WARNING: input should not be public but it is an easy way to update B from T (using UpdateFromSolution) from Pentas*/
 
 		/*Numerics*/
-		virtual void       InputDuplicate(int original_enum,int new_enum)=0;
+		virtual Material*  copy2(Element* element)=0;
 		virtual void       Configure(Elements* elements)=0;
-		virtual void       GetVectorFromInputs(Vector<IssmDouble>* vector,int input_enum)=0;
-		virtual void       GetViscosity2d(IssmDouble* pviscosity, IssmDouble* pepsilon)=0;
-		virtual void       GetViscosity2dvertical(IssmDouble* pviscosity, IssmDouble* pepsilon)=0;
-		virtual void       GetViscosity3d(IssmDouble* pviscosity3d, IssmDouble* pepsilon)=0;
-		virtual void       GetViscosity3dFS(IssmDouble* pviscosity3d, IssmDouble* epsilon)=0;
+		virtual void       GetViscosity(IssmDouble* pviscosity,IssmDouble epseff)=0;
+		virtual void       GetViscosityBar(IssmDouble* pviscosity,IssmDouble epseff)=0;
 		virtual void       GetViscosityComplement(IssmDouble* pviscosity_complement, IssmDouble* pepsilon)=0;
 		virtual void       GetViscosityDComplement(IssmDouble* pviscosity_complement, IssmDouble* pepsilon)=0;
@@ -36,4 +33,5 @@
 		virtual void       GetViscosity2dDerivativeEpsSquare(IssmDouble* pmu_prime, IssmDouble* pepsilon)=0;
 		virtual IssmDouble GetA()=0;
+		virtual IssmDouble GetAbar()=0;
 		virtual IssmDouble GetB()=0;
 		virtual IssmDouble GetBbar()=0;
@@ -41,4 +39,5 @@
 		virtual IssmDouble GetD()=0;
 		virtual IssmDouble GetDbar()=0;
+		virtual bool       IsDamage()=0;
 
 };
Index: /issm/trunk/src/c/classes/Materials/Materials.cpp
===================================================================
--- /issm/trunk/src/c/classes/Materials/Materials.cpp	(revision 17805)
+++ /issm/trunk/src/c/classes/Materials/Materials.cpp	(revision 17806)
@@ -47,10 +47,2 @@
 }
 /*}}}*/
-/*FUNCTION Materials::InputDuplicate{{{*/
-void Materials::InputDuplicate(int input_enum,int output_enum){
-
-	for(int i=0;i<this->Size();i++){
-		Material* material=(Material*)this->GetObjectByOffset(i);
-		material->InputDuplicate(input_enum,output_enum);
-	}
-}
Index: /issm/trunk/src/c/classes/Materials/Materials.h
===================================================================
--- /issm/trunk/src/c/classes/Materials/Materials.h	(revision 17805)
+++ /issm/trunk/src/c/classes/Materials/Materials.h	(revision 17806)
@@ -24,5 +24,4 @@
 		/*numerics*/
 		void  Configure(Elements* elements,Loads* loads, Nodes* nodes, Vertices* vertices, Materials* materials,Parameters* parameters);
-		void  InputDuplicate(int input_enum,int output_enum);
 
 };
Index: /issm/trunk/src/c/classes/Materials/Matice.cpp
===================================================================
--- /issm/trunk/src/c/classes/Materials/Matice.cpp	(revision 17805)
+++ /issm/trunk/src/c/classes/Materials/Matice.cpp	(revision 17806)
@@ -29,6 +29,7 @@
 /*FUNCTION Matice::Matice(){{{*/
 Matice::Matice(){
-	this->inputs=NULL;
 	this->helement=NULL;
+	this->element=NULL;
+	this->isdamaged=NULL;
 	return;
 }
@@ -42,14 +43,16 @@
 	/*Initialize id*/
 	this->mid=matice_mid;
-
-	/*Initialize inputs*/
-	this->inputs=new Inputs();
-
-	/*Initialize inputs from IoModel*/
-	this->InputUpdateFromIoModel(index,iomodel);
 
 	/*Hooks: */
 	matice_eid=index+1;
 	this->helement=new Hook(&matice_eid,1);
+	this->element=NULL;
+
+	 /*Other perporties*/
+   int    materialtype;
+   iomodel->Constant(&materialtype,MaterialsEnum);
+   if(materialtype==MatdamageiceEnum) this->isdamaged = true;
+   else if(materialtype==MaticeEnum) this->isdamaged = false;
+   else _error_("Material type not recognized");
 
 	return;
@@ -60,5 +63,4 @@
 Matice::~Matice(){
 	delete helement;
-	delete inputs;
 	return;
 }
@@ -71,6 +73,4 @@
 	_printf_("Matice:\n");
 	_printf_("   mid: " << mid << "\n");
-	_printf_("   inputs:\n");
-	inputs->Echo();
 	_printf_("   element:\n");
 	helement->Echo();
@@ -82,6 +82,4 @@
 	_printf_("Matice:\n");
 	_printf_("   mid: " << mid << "\n");
-	_printf_("   inputs:\n");
-	inputs->DeepEcho();
 	_printf_("   element:\n");
 	helement->Echo();
@@ -98,5 +96,5 @@
 }
 /*}}}*/
-/*FUNCTION Matice::copy {{{*/
+/*FUNCTION Matice::copy() {{{*/
 Object* Matice::copy() {
 
@@ -110,6 +108,22 @@
 	matice->mid=this->mid;
 	matice->helement=(Hook*)this->helement->copy();
-	if(this->inputs) matice->inputs=(Inputs*)this->inputs->Copy();
-	else  matice->inputs=new Inputs();
+	matice->element =(Element*)this->helement->delivers();
+
+	return matice;
+}
+/*}}}*/
+/*FUNCTION Matice::copy2(Element* element) {{{*/
+Material* Matice::copy2(Element* element_in) {
+
+	/*Output*/
+	Matice* matice=NULL;
+
+	/*Initialize output*/
+	matice=new Matice();
+
+	/*copy fields: */
+	matice->mid=this->mid;
+	matice->helement=(Hook*)this->helement->copy();
+	matice->element =element_in;
 
 	return matice;
@@ -124,4 +138,5 @@
 	 * datasets, using internal ids and offsets hidden in hooks: */
 	helement->configure((DataSet*)elementsin);
+	this->element  = (Element*)helement->delivers();
 }
 /*}}}*/
@@ -139,5 +154,19 @@
 	IssmDouble B,n;
 
-	inputs->GetInputAverage(&B,MaterialsRheologyBEnum);
+	element->inputs->GetInputAverage(&B,MaterialsRheologyBEnum);
+	n=this->GetN();
+
+	return pow(B,-n);
+}
+/*}}}*/
+/*FUNCTION Matice::GetAbar {{{*/
+IssmDouble Matice::GetAbar(){
+	/*
+	 * A = 1/B^n
+	 */
+
+	IssmDouble B,n;
+
+	element->inputs->GetInputAverage(&B,MaterialsRheologyBbarEnum);
 	n=this->GetN();
 
@@ -151,5 +180,5 @@
 	IssmDouble B;
 
-	inputs->GetInputAverage(&B,MaterialsRheologyBEnum);
+	element->inputs->GetInputAverage(&B,MaterialsRheologyBEnum);
 	return B;
 }
@@ -161,5 +190,5 @@
 	IssmDouble Bbar;
 
-	inputs->GetInputAverage(&Bbar,MaterialsRheologyBbarEnum);
+	element->inputs->GetInputAverage(&Bbar,MaterialsRheologyBbarEnum);
 	return Bbar;
 }
@@ -171,5 +200,5 @@
 	IssmDouble n;
 
-	inputs->GetInputAverage(&n,MaterialsRheologyNEnum);
+	element->inputs->GetInputAverage(&n,MaterialsRheologyNEnum);
 	return n;
 }
@@ -178,8 +207,8 @@
 IssmDouble Matice::GetD(){
 
+	_assert_(this->isdamaged);
 	/*Output*/
 	IssmDouble D;
-
-	inputs->GetInputAverage(&D,DamageDEnum);
+	if(this->isdamaged)element->inputs->GetInputAverage(&D,DamageDEnum);
 	return D;
 }
@@ -188,53 +217,28 @@
 IssmDouble Matice::GetDbar(){
 
+	_assert_(this->isdamaged);
 	/*Output*/
 	IssmDouble Dbar;
-	inputs->GetInputAverage(&Dbar,DamageDbarEnum);
+	if(this->isdamaged)element->inputs->GetInputAverage(&Dbar,DamageDbarEnum);
 	return Dbar;
 }
 /*}}}*/
-/*FUNCTION Matice::GetVectorFromInputs{{{*/
-void  Matice::GetVectorFromInputs(Vector<IssmDouble>* vector,int input_enum){
-
-	/*Intermediaries*/
-	Element *element= NULL;
-
-	/*Recover element*/
-	element=(Element*)helement->delivers();
-
-	/*Check that input_enum is a material input*/
-	if (!IsInput(input_enum)) return;
-
-	switch(element->ObjectEnum()){
-
-		case TriaEnum:{
-
-							  /*Prepare index list*/
-							  int vertexpidlist[3];
-							  ((Tria*)element)->GetVertexPidList(&vertexpidlist[0]);
-
-								 /*Get input (either in element or material)*/
-								 Input* input=inputs->GetInput(input_enum);
-							  if(!input) _error_("Input " << EnumToStringx(input_enum) << " not found in material");
-
-							  /*We found the enum.  Use its values to fill into the vector, using the vertices ids: */
-							  input->GetVectorFromInputs(vector,&vertexpidlist[0]);}
-						break;
-
-		default: _error_("element " << EnumToStringx(element->ObjectEnum()) << " not implemented yet");
-	}
-}
-/*}}}*/
-/*FUNCTION Matice::GetViscosity2d {{{*/
-void  Matice::GetViscosity2d(IssmDouble* pviscosity, IssmDouble* epsilon){
+/*FUNCTION Matice::IsDamage() {{{*/
+bool Matice::IsDamage(){
+
+	return this->isdamaged;
+}
+/*}}}*/
+/*FUNCTION Matice::GetViscosity {{{*/
+void  Matice::GetViscosity(IssmDouble* pviscosity,IssmDouble eps_eff){
 	/*From a string tensor and a material object, return viscosity, using Glen's flow law.
-												    (1-D) B
-	  viscosity= -------------------------------------------------------------------
-						  2[ exx^2+eyy^2+exx*eyy+exy^2+exz^2+eyz^2 ]^[(n-1)/2n]
-
-	  where viscosity is the viscotiy, B the flow law parameter , (u,v) the velocity 
-	  vector, and n the flow law exponent.
-
-	  If epsilon is NULL, it means this is the first time SystemMatrices is being run, and we 
+								(1-D) B
+	  viscosity= -------------------------
+						  2 eps_eff ^[(n-1)/n]
+
+	  where viscosity is the viscotiy, B the flow law parameter , eps_eff is the effective strain rate
+	  and n the flow law exponent.
+
+	  If eps_eff = 0 , it means this is the first time SystemMatrices is being run, and we 
 	  return 10^14, initial viscosity.
 	  */
@@ -243,40 +247,30 @@
 	IssmDouble viscosity;
 
-	/*input strain rate: */
-	IssmDouble exx,eyy,exy;
-
 	/*Intermediary: */
-	IssmDouble A,e;
-	IssmDouble B,D,n;
+	IssmDouble B,D=0.,n;
 
 	/*Get B and n*/
-	B=GetBbar();
-	n=GetN();
-	D=GetDbar();
-
-	if (n==1){
-		/*Viscous behaviour! viscosity=B: */
-		viscosity=(1-D)*B/2;
-	}
-	else{
-		if((epsilon[0]==0) && (epsilon[1]==0) && (epsilon[2]==0)){
-			viscosity=0.5*pow(10.,14);
-		}
+	B=GetB(); _assert_(B>0.);
+	n=GetN(); _assert_(n>0.);
+	if(this->isdamaged){
+		D=GetD();
+		_assert_(D>=0. && D<1.);
+	}
+
+	if (n==1.){
+		/*Linear Viscous behavior (Newtonian fluid) viscosity=B/2: */
+		viscosity=(1.-D)*B/2.;
+	}
+	else{
+
+		/*if no strain rate, return maximum viscosity*/
+		if(eps_eff==0.){
+			viscosity = 1.e+14/2.;
+			//viscosity = B;
+			//viscosity=2.5*pow(10.,17);
+		}
+
 		else{
-			/*Retrive strain rate components: */
-			exx=*(epsilon+0);
-			eyy=*(epsilon+1);
-			exy=*(epsilon+2);
-
-			/*Build viscosity: viscosity=B/(2*A^e) */
-			A=pow(exx,2)+pow(eyy,2)+pow(exy,2)+exx*eyy;
-			if(A==0){
-				/*Maxiviscositym viscosity for 0 shear areas: */
-				viscosity=2.5*pow(10.,17);
-			}
-			else{
-				e=(n-1)/(2*n);
-				viscosity=(1-D)*B/(2*pow(A,e));
-			}
+			viscosity=(1.-D)*B/(2.*pow(eps_eff,(n-1.)/n));
 		}
 	}
@@ -284,7 +278,4 @@
 	/*Checks in debugging mode*/
 	if(viscosity<=0) _error_("Negative viscosity");
-	_assert_(B>0);
-	_assert_(n>0);
-	_assert_(D>=0 && D<1);
 
 	/*Return: */
@@ -292,15 +283,15 @@
 }
 /*}}}*/
-/*FUNCTION Matice::GetViscosity2dvertical {{{*/
-void  Matice::GetViscosity2dvertical(IssmDouble* pviscosity, IssmDouble* epsilon){
+/*FUNCTION Matice::GetViscosityBar {{{*/
+void  Matice::GetViscosityBar(IssmDouble* pviscosity,IssmDouble eps_eff){
 	/*From a string tensor and a material object, return viscosity, using Glen's flow law.
-									   (1-D) B
-	  viscosity= --------------------------------------
-						  2[ exx^2+eyy^2+ 2exy^2]^[(n-1)/2n]
-
-	  where viscosity is the viscotiy, B the flow law parameter , (u,v) the velocity 
-	  vector, and n the flow law exponent.
-
-	  If epsilon is NULL, it means this is the first time SystemMatrices is being run, and we 
+								(1-D) B
+	  viscosity= -------------------------
+						  2 eps_eff ^[(n-1)/n]
+
+	  where viscosity is the viscotiy, B the flow law parameter , eps_eff is the effective strain rate
+	  and n the flow law exponent.
+
+	  If eps_eff = 0 , it means this is the first time SystemMatrices is being run, and we 
 	  return 10^14, initial viscosity.
 	  */
@@ -309,40 +300,29 @@
 	IssmDouble viscosity;
 
-	/*input strain rate: */
-	IssmDouble exx,eyy,exy;
-
 	/*Intermediary: */
-	IssmDouble A,e;
-	IssmDouble B,D,n;
+	IssmDouble B,D=0.,n;
 
 	/*Get B and n*/
-	B=GetB();
-	n=GetN();
-	D=GetD();
-
-	if (n==1){
-		/*Viscous behaviour! viscosity=B: */
-		viscosity=(1-D)*B/2;
-	}
-	else{
-		if((epsilon[0]==0) && (epsilon[1]==0) && (epsilon[2]==0)){
-			viscosity=0.5*pow(10.,14);
-		}
+	B=GetBbar(); _assert_(B>0.);
+	n=GetN();    _assert_(n>0.);
+	if(this->isdamaged){
+		D=GetDbar();
+		_assert_(D>=0. && D<1.);
+	}
+
+	if (n==1.){
+		/*Linear Viscous behavior (Newtonian fluid) viscosity=B/2: */
+		viscosity=(1.-D)*B/2.;
+	}
+	else{
+
+		/*if no strain rate, return maximum viscosity*/
+		if(eps_eff==0.){
+			viscosity = 1.e+14/2.;
+			//viscosity=2.5*pow(10.,17);
+		}
+
 		else{
-			/*Retrive strain rate components: */
-			exx=epsilon[0];
-			eyy=epsilon[1];
-			exy=epsilon[2];
-
-			/*Build viscosity: viscosity=B/(2*A^e) */
-			A=exx*exx+eyy*eyy+2.*exy*exy;
-			if(A==0.){
-				/*Maxiviscositym viscosity for 0 shear areas: */
-				viscosity=2.5*2.e+17;
-			}
-			else{
-				e=(n-1.)/(2.*n);
-				viscosity=(1.-D)*B/(2.*pow(A,e));
-			}
+			viscosity=(1.-D)*B/(2.*pow(eps_eff,(n-1.)/n));
 		}
 	}
@@ -350,157 +330,7 @@
 	/*Checks in debugging mode*/
 	if(viscosity<=0) _error_("Negative viscosity");
-	_assert_(B>0);
-	_assert_(n>0);
-	_assert_(D>=0 && D<1);
 
 	/*Return: */
 	*pviscosity=viscosity;
-}
-/*}}}*/
-/*FUNCTION Matice::GetViscosity3d {{{*/
-void  Matice::GetViscosity3d(IssmDouble* pviscosity3d, IssmDouble* epsilon){
-
-	/*Return viscosity accounting for steady state power law creep [Thomas and SSA, 1982]: 
-	 *
-	 *                                               (1-D)*B
-	 * viscosity3d= -------------------------------------------------------------------
-	 *                      2[ exx^2+eyy^2+exx*eyy+exy^2+exz^2+eyz^2 ]^[(n-1)/2n]
-	 *
-	 *     where mu is the viscotiy, B the flow law parameter , (u,v) the velocity 
-	 *     vector, and n the flow law exponent.
-	 *
-	 * If epsilon is NULL, it means this is the first time Emg is being run, and we 
-	 * return g, initial viscosity.
-	 */
-
-	/*output: */
-	IssmDouble viscosity3d;
-
-	/*input strain rate: */
-	IssmDouble exx,eyy,exy,exz,eyz;
-
-	/*Intermediaries: */
-	IssmDouble A,e;
-	IssmDouble B,D,n;
-
-	/*Get B and n*/
-	B=GetB();
-	D=GetD();
-	n=GetN();
-
-	if (n==1){
-		/*Viscous behaviour! viscosity3d=B: */
-		viscosity3d=(1-D)*B/2;
-	}
-	else{
-		if((epsilon[0]==0) && (epsilon[1]==0) && (epsilon[2]==0) && 
-				(epsilon[3]==0) && (epsilon[4]==0)){
-			viscosity3d=0.5*pow(10.,14);
-		}
-		else{
-
-			/*Retrive strain rate components: */
-			exx=*(epsilon+0);
-			eyy=*(epsilon+1);
-			exy=*(epsilon+2);
-			exz=*(epsilon+3);
-			eyz=*(epsilon+4);
-
-			/*Build viscosity: viscosity3d=2*B/(2*A^e) */
-			A=pow(exx,2)+pow(eyy,2)+pow(exy,2)+pow(exz,2)+pow(eyz,2)+exx*eyy;
-			if(A==0){
-				/*Maxiviscosity3dm viscosity for 0 shear areas: */
-				viscosity3d=2.25*pow(10.,17);
-			}
-			else{
-				e=(n-1)/2/n;
-
-				viscosity3d=(1-D)*B/(2*pow(A,e));
-			}
-		}
-	}
-
-	/*Checks in debugging mode*/
-	if(viscosity3d<=0) _error_("Negative viscosity");
-	_assert_(B>0);
-	_assert_(n>0);
-	_assert_(D>=0 && D<1);
-
-	/*Assign output pointers:*/
-	*pviscosity3d=viscosity3d;
-}
-/*}}}*/
-/*FUNCTION Matice::GetViscosity3dFS {{{*/
-void  Matice::GetViscosity3dFS(IssmDouble* pviscosity3d, IssmDouble* epsilon){
-	/*Return viscosity accounting for steady state power law creep [Thomas and SSA, 1982]: 
-	 *
-	 *                                          (1-D)*B
-	 * viscosity3d= -------------------------------------------------------------------
-	 *                   2[ exx^2+eyy^2+exx*eyy+exy^2+exz^2+eyz^2 ]^[(n-1)/2n]
-	 *
-	 *     where mu is the viscotiy, B the flow law parameter , (u,v) the velocity 
-	 *     vector, and n the flow law exponent.
-	 *
-	 * If epsilon is NULL, it means this is the first time Emg is being run, and we 
-	 * return g, initial viscosity.
-	 */
-
-	/*output: */
-	IssmDouble viscosity3d;
-
-	/*input strain rate: */
-	IssmDouble exx,eyy,exy,exz,eyz,ezz;
-
-	/*Intermediaries: */
-	IssmDouble A,e;
-	IssmDouble B,D,n;
-	IssmDouble eps0;
-
-	/*Get B and n*/
-	eps0=pow(10.,-27);
-	B=GetB();
-	D=GetD();
-	n=GetN();
-
-	if (n==1){
-		/*Viscous behaviour! viscosity3d=B: */
-		viscosity3d=(1-D)*B/2;
-	}
-	else{
-		if((epsilon[0]==0) && (epsilon[1]==0) && (epsilon[2]==0) && 
-				(epsilon[3]==0) && (epsilon[4]==0) && (epsilon[5]==0)){
-			viscosity3d=0.5*pow(10.,14);
-		}
-		else{
-
-			/*Retrive strain rate components: */
-			exx=*(epsilon+0);
-			eyy=*(epsilon+1);
-			ezz=*(epsilon+2); //not used
-			exy=*(epsilon+3);
-			exz=*(epsilon+4);
-			eyz=*(epsilon+5);
-
-			/*Build viscosity: viscosity3d=B/(2*A^e) */
-			A=pow(exx,2)+pow(eyy,2)+pow(exy,2)+pow(exz,2)+pow(eyz,2)+exx*eyy+pow(eps0,2);
-			if(A==0){
-				/*Maxiviscosity3dm viscosity for 0 shear areas: */
-				viscosity3d=2.25*pow(10.,17);
-			}
-			else{
-				e=(n-1)/2/n;
-				viscosity3d=(1-D)*B/(2*pow(A,e));
-			}
-		}
-	}
-
-	/*Checks in debugging mode*/
-	if(viscosity3d<=0) _error_("Negative viscosity");
-	_assert_(B>0);
-	_assert_(n>0);
-	_assert_(D>=0 && D<1);
-
-	/*Assign output pointers:*/
-	*pviscosity3d=viscosity3d;
 }
 /*}}}*/
@@ -525,8 +355,11 @@
 	/*Intermediary value A and exponent e: */
 	IssmDouble A,e;
-	IssmDouble D,n;
+	IssmDouble D=0.,n;
 
 	/*Get D and n*/
-	D=GetDbar();
+	if(this->isdamaged){
+		D=GetDbar(); /* GetD()? */
+		_assert_(D>=0. && D<1.);
+	}
 	n=GetN();
 
@@ -627,7 +460,4 @@
 	IssmDouble exx,eyy,exy,exz,eyz;
 
-	/*Get visocisty and n*/
-	GetViscosity3d(&mu,epsilon);
-	n=GetN();
 
 	if((epsilon[0]==0) && (epsilon[1]==0) && (epsilon[2]==0) && 
@@ -636,4 +466,5 @@
 	}
 	else{
+
 		/*Retrive strain rate components: */
 		exx=epsilon[0];
@@ -644,5 +475,7 @@
 		eff2 = exx*exx + eyy*eyy + exx*eyy + exy*exy + exz*exz + eyz*eyz;
 
-		mu_prime=(1-n)/(2*n) * mu/eff2;
+		GetViscosity(&mu,sqrt(eff2));
+		n=GetN();
+		mu_prime=(1.-n)/(2.*n) * mu/eff2;
 	}
 
@@ -660,8 +493,4 @@
 	/*input strain rate: */
 	IssmDouble exx,eyy,exy,exz,eyz,ezz;
-
-	/*Get visocisty and n*/
-	GetViscosity3d(&mu,epsilon);
-	n=GetN();
 
 	if((epsilon[0]==0) && (epsilon[1]==0) && (epsilon[2]==0) && 
@@ -679,4 +508,6 @@
 		eff2 = exx*exx + eyy*eyy + exx*eyy + exy*exy + exz*exz + eyz*eyz;
 
+		GetViscosity(&mu,sqrt(eff2));
+		n=GetN();
 		mu_prime=(1-n)/(2*n) * mu/eff2;
 	}
@@ -695,8 +526,4 @@
 	/*input strain rate: */
 	IssmDouble exx,eyy,exy;
-
-	/*Get visocisty and n*/
-	GetViscosity2d(&mu,epsilon);
-	n=GetN();
 
 	if((epsilon[0]==0) && (epsilon[1]==0) && (epsilon[2]==0)){
@@ -710,5 +537,7 @@
 		eff2 = exx*exx + eyy*eyy + exx*eyy + exy*exy ;
 
-		mu_prime=(1-n)/(2*n) * mu/eff2;
+		GetViscosityBar(&mu,sqrt(eff2));
+		n=GetN();
+		mu_prime=(1.-n)/(2.*n)*mu/eff2;
 	}
 
@@ -717,104 +546,11 @@
 }
 /*}}}*/
-/*FUNCTION Matice::InputDuplicate{{{*/
-void  Matice::InputDuplicate(int original_enum,int new_enum){
-
-	/*Call inputs method*/
-	if (IsInput(original_enum)) inputs->DuplicateInput(original_enum,new_enum);
-
-}
-/*}}}*/
 /*FUNCTION Matice::InputUpdateFromVector(IssmDouble* vector, int name, int type) {{{*/
 void  Matice::InputUpdateFromVector(IssmDouble* vector, int name, int type){
 
-	/*Intermediaries*/
-	Element *element      = NULL;
-
-	/*Recover element*/
-	element=(Element*)helement->delivers();
-
-	/*Check that name is an element input*/
-	if (!IsInput(name)) return;
-
-	switch(type){
-
-		case VertexEnum:
-
-			switch(element->ObjectEnum()){
-
-				case TriaEnum: {
-					IssmDouble values[3];
-					for (int i=0;i<3;i++) values[i]=vector[((Tria*)element)->vertices[i]->Pid()];
-					this->inputs->AddInput(new TriaInput(name,values,P1Enum));
-					return;
-				}
-				#ifdef _HAVE_3D_
-				case PentaEnum: {
-					IssmDouble valuesp[6];
-					for (int i=0;i<6;i++) valuesp[i]=vector[((Penta*)element)->vertices[i]->Sid()]; //use sid list, to index into serial oriented vector
-					this->inputs->AddInput(new PentaInput(name,valuesp,P1Enum));
-					return;
-				}
-			  	#endif
-				default: _error_("element " << EnumToStringx(element->ObjectEnum()) << " not implemented yet");
-			}
-		default: _error_("type " << type << " (" << EnumToStringx(type) << ") not implemented yet");
-	}
 }
 /*}}}*/
 /*FUNCTION Matice::InputUpdateFromVectorDakota(IssmDouble* vector, int name, int type) {{{*/
 void  Matice::InputUpdateFromVectorDakota(IssmDouble* vector, int name, int type){
-
-	/*Intermediaries*/
-	Element    *element    = NULL;
-	Parameters *parameters = NULL;
-	int         meshtype;
-
-	/*Recover element*/
-	element=(Element*)helement->delivers();
-
-	/*Check that name is an element input*/
-	if (!IsInput(name)) return;
-
-	switch(type){
-
-		case VertexEnum:
-
-			switch(element->ObjectEnum()){
-
-				case TriaEnum: {
-					IssmDouble values[3];
-					for (int i=0;i<3;i++) values[i]=vector[((Tria*)element)->vertices[i]->Sid()]; //index into serial oriented vector 
-					this->inputs->AddInput(new TriaInput(name,values,P1Enum));
-					/*Special case for rheology B in 2D: Pourave land for this solution{{{*/
-					if(name==MaterialsRheologyBEnum){
-						/*Are we in 2D?:*/
-						if(element->ObjectEnum()==TriaEnum){
-							parameters=((Tria*)(element))->parameters;
-						}
-						else{
-							parameters=((Penta*)(element))->parameters;
-						}
-						parameters->FindParam(&meshtype,MeshTypeEnum);
-						if(meshtype==Mesh2DhorizontalEnum){
-							/*Duplicate rheology input: */
-							this->inputs->AddInput(new TriaInput(MaterialsRheologyBbarEnum,values,P1Enum));
-						}
-					}
-					/*}}}*/
-					return;
-				}
-				#ifdef _HAVE_3D_
-				case PentaEnum:{
-					IssmDouble valuesp[6];
-					for (int i=0;i<6;i++) valuesp[i]=vector[((Penta*)element)->vertices[i]->Sid()]; //use sid list, to index into serial oriented vector
-					this->inputs->AddInput(new PentaInput(name,valuesp,P1Enum));
-					return;
-				}
-				# endif
-				default: _error_("element " << EnumToStringx(element->ObjectEnum()) << " not implemented yet");
-			}
-		default: _error_("type " << type << " (" << EnumToStringx(type) << ") not implemented yet");
-	}
 
 }
@@ -840,178 +576,2 @@
 }
 /*}}}*/
-/*FUNCTION Matice::InputUpdateFromSolution{{{*/
-void  Matice::InputUpdateFromSolution(IssmDouble* solution){
-	/*Nothing updated yet*/
-}
-/*}}}*/
-/*FUNCTION Matice::InputUpdateFromIoModel{{{*/
-void Matice::InputUpdateFromIoModel(int index, IoModel* iomodel){
-
-	int i,j;
-	bool   control_analysis;
-	int    num_control_type;
-
-	/*Fetch parameters: */
-	iomodel->Constant(&control_analysis,InversionIscontrolEnum);
-	if(control_analysis) iomodel->Constant(&num_control_type,InversionNumControlParametersEnum);
-
-	if(iomodel->meshtype==Mesh2DhorizontalEnum){
-
-		/*Intermediaries*/
-		const int  num_vertices = 3; //Tria has 3 vertices
-		IssmDouble nodeinputs[num_vertices];
-		IssmDouble cmmininputs[num_vertices];
-		IssmDouble cmmaxinputs[num_vertices];
-
-		/*Get B*/
-		if (iomodel->Data(MaterialsRheologyBEnum)) {
-			for(i=0;i<num_vertices;i++) nodeinputs[i]=iomodel->Data(MaterialsRheologyBEnum)[iomodel->elements[num_vertices*index+i]-1];
-			this->inputs->AddInput(new TriaInput(MaterialsRheologyBbarEnum,nodeinputs,P1Enum));
-		}
-
-		/*Get n*/
-		if (iomodel->Data(MaterialsRheologyNEnum)) {
-			for(i=0;i<num_vertices;i++) nodeinputs[i]=iomodel->Data(MaterialsRheologyNEnum)[index];
-			this->inputs->AddInput(new TriaInput(MaterialsRheologyNEnum,nodeinputs,P1Enum));
-		}
-
-		/*Get D:*/
-		if (iomodel->Data(DamageDEnum)) {
-			for(i=0;i<num_vertices;i++) nodeinputs[i]=iomodel->Data(DamageDEnum)[iomodel->elements[num_vertices*index+i]-1];
-			this->inputs->AddInput(new TriaInput(DamageDbarEnum,nodeinputs,P1Enum));
-		}
-
-		/*Control Inputs*/
-		#ifdef _HAVE_CONTROL_
-		if (control_analysis && iomodel->Data(InversionControlParametersEnum)){
-			for(i=0;i<num_control_type;i++){
-				switch(reCast<int>(iomodel->Data(InversionControlParametersEnum)[i])){
-					case MaterialsRheologyBbarEnum:
-						if (iomodel->Data(MaterialsRheologyBEnum)){
-							_assert_(iomodel->Data(MaterialsRheologyBEnum));_assert_(iomodel->Data(InversionMinParametersEnum)); _assert_(iomodel->Data(InversionMaxParametersEnum)); 
-							for(j=0;j<num_vertices;j++)nodeinputs[j]=iomodel->Data(MaterialsRheologyBEnum)[iomodel->elements[num_vertices*index+j]-1];
-							for(j=0;j<num_vertices;j++)cmmininputs[j]=iomodel->Data(InversionMinParametersEnum)[(iomodel->elements[num_vertices*index+j]-1)*num_control_type+i];
-							for(j=0;j<num_vertices;j++)cmmaxinputs[j]=iomodel->Data(InversionMaxParametersEnum)[(iomodel->elements[num_vertices*index+j]-1)*num_control_type+i];
-							this->inputs->AddInput(new ControlInput(MaterialsRheologyBbarEnum,TriaInputEnum,nodeinputs,cmmininputs,cmmaxinputs,i+1));
-						}
-						break;
-					case DamageDbarEnum:
-						if (iomodel->Data(DamageDEnum)){
-							_assert_(iomodel->Data(DamageDEnum));_assert_(iomodel->Data(InversionMinParametersEnum)); _assert_(iomodel->Data(InversionMaxParametersEnum)); 
-							for(j=0;j<num_vertices;j++)nodeinputs[j]=iomodel->Data(DamageDEnum)[iomodel->elements[num_vertices*index+j]-1];
-							for(j=0;j<num_vertices;j++)cmmininputs[j]=iomodel->Data(InversionMinParametersEnum)[(iomodel->elements[num_vertices*index+j]-1)*num_control_type+i];
-							for(j=0;j<num_vertices;j++)cmmaxinputs[j]=iomodel->Data(InversionMaxParametersEnum)[(iomodel->elements[num_vertices*index+j]-1)*num_control_type+i];
-							this->inputs->AddInput(new ControlInput(DamageDbarEnum,TriaInputEnum,nodeinputs,cmmininputs,cmmaxinputs,i+1));
-						}
-						break;
-				}
-			}
-		}
-		#endif
-	}
-	else if(iomodel->meshtype==Mesh2DverticalEnum){
-
-		/*Intermediaries*/
-		const int num_vertices = 3; //Tria has 3 vertices
-		IssmDouble    nodeinputs[num_vertices];
-		IssmDouble    cmmininputs[num_vertices];
-		IssmDouble    cmmaxinputs[num_vertices];
-
-		/*Get B*/
-		if (iomodel->Data(MaterialsRheologyBEnum)) {
-			for(i=0;i<num_vertices;i++) nodeinputs[i]=iomodel->Data(MaterialsRheologyBEnum)[iomodel->elements[num_vertices*index+i]-1];
-			this->inputs->AddInput(new TriaInput(MaterialsRheologyBEnum,nodeinputs,P1Enum));
-		}
-
-		/*Get n*/
-		if (iomodel->Data(MaterialsRheologyNEnum)) {
-			for(i=0;i<num_vertices;i++) nodeinputs[i]=iomodel->Data(MaterialsRheologyNEnum)[index];
-			this->inputs->AddInput(new TriaInput(MaterialsRheologyNEnum,nodeinputs,P1Enum));
-		}
-
-		/*Get D:*/
-		if (iomodel->Data(DamageDEnum)) {
-			for(i=0;i<num_vertices;i++) nodeinputs[i]=iomodel->Data(DamageDEnum)[iomodel->elements[num_vertices*index+i]-1];
-			this->inputs->AddInput(new TriaInput(DamageDEnum,nodeinputs,P1Enum));
-		}
-	}
-	#ifdef _HAVE_3D_
-	else if(iomodel->meshtype==Mesh3DEnum){
-
-		/*Intermediaries*/
-		const int  num_vertices = 6; //Penta has 6 vertices
-		IssmDouble nodeinputs[num_vertices];
-		IssmDouble cmmininputs[num_vertices];
-		IssmDouble cmmaxinputs[num_vertices];
-
-		/*Get B*/
-		if (iomodel->Data(MaterialsRheologyBEnum)) {
-			for(i=0;i<num_vertices;i++) nodeinputs[i]=iomodel->Data(MaterialsRheologyBEnum)[iomodel->elements[num_vertices*index+i]-1];
-			this->inputs->AddInput(new PentaInput(MaterialsRheologyBEnum,nodeinputs,P1Enum));
-		}
-
-		/*Get n*/
-		if (iomodel->Data(MaterialsRheologyNEnum)) {
-			for(i=0;i<num_vertices;i++) nodeinputs[i]=iomodel->Data(MaterialsRheologyNEnum)[index];
-			this->inputs->AddInput(new PentaInput(MaterialsRheologyNEnum,nodeinputs,P1Enum));
-		}
-		
-		/*Get D*/
-		if (iomodel->Data(DamageDEnum)) {
-			for(i=0;i<num_vertices;i++) nodeinputs[i]=iomodel->Data(DamageDEnum)[iomodel->elements[num_vertices*index+i]-1];
-			this->inputs->AddInput(new PentaInput(DamageDEnum,nodeinputs,P1Enum));
-		}
-		
-		/*Control Inputs*/
-		#ifdef _HAVE_CONTROL_
-		if (control_analysis && iomodel->Data(InversionControlParametersEnum)){
-			for(i=0;i<num_control_type;i++){
-				switch(reCast<int>(iomodel->Data(InversionControlParametersEnum)[i])){
-					case MaterialsRheologyBbarEnum:
-						if (iomodel->Data(MaterialsRheologyBEnum)){
-							_assert_(iomodel->Data(MaterialsRheologyBEnum));_assert_(iomodel->Data(InversionMinParametersEnum)); _assert_(iomodel->Data(InversionMaxParametersEnum)); 
-							for(j=0;j<num_vertices;j++)nodeinputs[j]=iomodel->Data(MaterialsRheologyBEnum)[iomodel->elements[num_vertices*index+j]-1];
-							for(j=0;j<num_vertices;j++)cmmininputs[j]=iomodel->Data(InversionMinParametersEnum)[(iomodel->elements[num_vertices*index+j]-1)*num_control_type+i];
-							for(j=0;j<num_vertices;j++)cmmaxinputs[j]=iomodel->Data(InversionMaxParametersEnum)[(iomodel->elements[num_vertices*index+j]-1)*num_control_type+i];
-							this->inputs->AddInput(new ControlInput(MaterialsRheologyBEnum,PentaInputEnum,nodeinputs,cmmininputs,cmmaxinputs,i+1));
-						}
-						break;
-					case DamageDbarEnum:
-						if (iomodel->Data(DamageDEnum)){
-							_assert_(iomodel->Data(DamageDEnum));_assert_(iomodel->Data(InversionMinParametersEnum)); _assert_(iomodel->Data(InversionMaxParametersEnum)); 
-							for(j=0;j<num_vertices;j++)nodeinputs[j]=iomodel->Data(DamageDEnum)[iomodel->elements[num_vertices*index+j]-1];
-							for(j=0;j<num_vertices;j++)cmmininputs[j]=iomodel->Data(InversionMinParametersEnum)[(iomodel->elements[num_vertices*index+j]-1)*num_control_type+i];
-							for(j=0;j<num_vertices;j++)cmmaxinputs[j]=iomodel->Data(InversionMaxParametersEnum)[(iomodel->elements[num_vertices*index+j]-1)*num_control_type+i];
-							this->inputs->AddInput(new ControlInput(DamageDEnum,PentaInputEnum,nodeinputs,cmmininputs,cmmaxinputs,i+1));
-						}
-						break;
-
-				}
-			}
-		}
-		#endif
-	}
-	#endif
-	else{
-		_error_("Mesh type not supported yet!");
-	}
-
-	return;
-}
-/*}}}*/
-/*FUNCTION Matice::IsInput{{{*/
-bool Matice::IsInput(int name){
-	if (
-				name==MaterialsRheologyBEnum ||
-				name==MaterialsRheologyBbarEnum ||
-				name==MaterialsRheologyNEnum ||
-				name==QmuMaterialsRheologyBEnum ||
-				name==DamageDEnum ||
-				name==DamageDbarEnum
-
-		){
-		return true;
-	}
-	else return false;
-}
-/*}}}*/
Index: /issm/trunk/src/c/classes/Materials/Matice.h
===================================================================
--- /issm/trunk/src/c/classes/Materials/Matice.h	(revision 17805)
+++ /issm/trunk/src/c/classes/Materials/Matice.h	(revision 17806)
@@ -12,4 +12,5 @@
 class IoModel;
 class Elements;
+class Element;
 class Loads;
 class Nodes;
@@ -22,6 +23,8 @@
 
 	private: 
-		int   mid;
-		Hook *helement;
+		int      mid;
+		bool     isdamaged;
+		Hook    *helement;
+		Element *element;
 
 	public:
@@ -45,16 +48,12 @@
 		void  InputUpdateFromConstant(int constant, int name);
 		void  InputUpdateFromConstant(bool constant, int name);
-		void  InputUpdateFromSolution(IssmDouble* solution);
-		void  InputUpdateFromIoModel(int index, IoModel* iomodel);
+		void  InputUpdateFromIoModel(int index, IoModel* iomodel){_error_("not implemented");};
 		/*}}}*/
 		/*Material virtual functions resolution: {{{*/
-		void   InputDuplicate(int original_enum,int new_enum);
 		void   Configure(Elements* elements);
-		void   GetVectorFromInputs(Vector<IssmDouble>* vector,int input_enum);
+		Material*  copy2(Element* element);
 		void       SetCurrentConfiguration(Elements* elements,Loads* loads,Nodes* nodes,Vertices* vertices,Materials* materials,Parameters* parameters);
-		void       GetViscosity2d(IssmDouble* pviscosity, IssmDouble* pepsilon);
-		void       GetViscosity2dvertical(IssmDouble* pviscosity, IssmDouble* pepsilon);
-		void       GetViscosity3d(IssmDouble* pviscosity3d, IssmDouble* pepsilon);
-		void       GetViscosity3dFS(IssmDouble* pviscosity3d, IssmDouble* epsilon);
+		void       GetViscosity(IssmDouble* pviscosity, IssmDouble eps_eff);
+		void       GetViscosityBar(IssmDouble* pviscosity, IssmDouble eps_eff);
 		void       GetViscosityComplement(IssmDouble* pviscosity_complement, IssmDouble* pepsilon);
 		void       GetViscosityDComplement(IssmDouble*, IssmDouble*);
@@ -63,4 +62,5 @@
 		void       GetViscosity2dDerivativeEpsSquare(IssmDouble* pmu_prime, IssmDouble* pepsilon);
 		IssmDouble GetA();
+		IssmDouble GetAbar();
 		IssmDouble GetB();
 		IssmDouble GetBbar();
@@ -68,5 +68,5 @@
 		IssmDouble GetDbar();
 		IssmDouble GetN();
-		bool       IsInput(int name);
+		bool       IsDamage();
 		/*}}}*/
 };
Index: /issm/trunk/src/c/classes/Materials/Matpar.cpp
===================================================================
--- /issm/trunk/src/c/classes/Materials/Matpar.cpp	(revision 17805)
+++ /issm/trunk/src/c/classes/Materials/Matpar.cpp	(revision 17806)
@@ -23,7 +23,7 @@
 	bool ispdd;
 	bool isefficientlayer;
-	int  hydrology_model;
+	int  hydrology_model,smb_model;
 	iomodel->Constant(&hydrology_model,HydrologyModelEnum);
-	iomodel->Constant(&ispdd,SurfaceforcingsIspddEnum);
+	iomodel->Constant(&smb_model,SurfaceforcingsEnum);
 
 	this->mid = matpar_mid;
@@ -34,4 +34,5 @@
 	iomodel->Constant(&this->heatcapacity,MaterialsHeatcapacityEnum);
 	iomodel->Constant(&this->thermalconductivity,MaterialsThermalconductivityEnum);
+	iomodel->Constant(&this->temperateiceconductivity,MaterialsTemperateiceconductivityEnum);
 	iomodel->Constant(&this->latentheat,MaterialsLatentheatEnum);
 	iomodel->Constant(&this->beta,MaterialsBetaEnum);
@@ -42,7 +43,20 @@
 	iomodel->Constant(&this->g,ConstantsGEnum);
 
-	if(ispdd){
-		iomodel->Constant(&this->desfac,SurfaceforcingsDesfacEnum);
-		iomodel->Constant(&this->s0p,SurfaceforcingsS0pEnum);
+	switch(smb_model){
+		case SMBEnum:
+			/*Nothing to add*/
+			break;
+		case SMBpddEnum:
+			iomodel->Constant(&this->desfac,SurfaceforcingsDesfacEnum);
+			iomodel->Constant(&this->s0p,SurfaceforcingsS0pEnum);
+			break;
+		case SMBgradientsEnum:
+			/*Nothing to add*/
+			break;
+		case SMBhenningEnum:
+			/*Nothing to add*/
+			break;
+		default:
+			_error_("Surface mass balance model "<<EnumToStringx(smb_model)<<" not supported yet");
 	}
 
@@ -58,5 +72,4 @@
 		iomodel->Constant(&this->sediment_porosity,HydrologydcSedimentPorosityEnum);
 		iomodel->Constant(&this->sediment_thickness,HydrologydcSedimentThicknessEnum);
-		iomodel->Constant(&this->sediment_transmitivity,HydrologydcSedimentTransmitivityEnum);
 		iomodel->Constant(&this->water_compressibility,HydrologydcWaterCompressibilityEnum);
 		iomodel->Constant(&isefficientlayer,HydrologydcIsefficientlayerEnum);
@@ -65,6 +78,7 @@
 				iomodel->Constant(&this->epl_compressibility,HydrologydcEplCompressibilityEnum);
 				iomodel->Constant(&this->epl_porosity,HydrologydcEplPorosityEnum);
-				iomodel->Constant(&this->epl_thickness,HydrologydcEplThicknessEnum);
-				iomodel->Constant(&this->epl_transmitivity,HydrologydcEplTransmitivityEnum);
+				iomodel->Constant(&this->epl_init_thickness,HydrologydcEplInitialThicknessEnum);
+				iomodel->Constant(&this->epl_max_thickness,HydrologydcEplMaxThicknessEnum);
+				iomodel->Constant(&this->epl_conductivity,HydrologydcEplConductivityEnum);
 		}
 	}
@@ -78,6 +92,4 @@
 	iomodel->Constant(&this->mantle_shear_modulus,MaterialsMantleShearModulusEnum);
 	iomodel->Constant(&this->mantle_density,MaterialsMantleDensityEnum);
-
-	this->inputs=NULL; /*not used here*/
 }
 /*}}}*/
@@ -100,4 +112,5 @@
 	_printf_("   heatcapacity: " << heatcapacity << "\n");
 	_printf_("   thermalconductivity: " << thermalconductivity << "\n");
+	_printf_("   temperateiceconductivity: " << temperateiceconductivity << "\n");
 	_printf_("   latentheat: " << latentheat << "\n");
 	_printf_("   beta: " << beta << "\n");
@@ -169,6 +182,9 @@
 			this->heatcapacity=constant;
 			break;
-		case MaterialsThermalconductivityEnum:
+	  	case MaterialsThermalconductivityEnum:
 			this->thermalconductivity=constant;
+			break;
+	  	case MaterialsTemperateiceconductivityEnum:
+			this->temperateiceconductivity=constant;
 			break;
 		case  MaterialsLatentheatEnum:
@@ -193,5 +209,5 @@
 			this->g=constant;
 			break;
-  	        case  SurfaceforcingsDesfacEnum:
+		case  SurfaceforcingsDesfacEnum:
 			this->desfac=constant;
 			break;
@@ -215,23 +231,47 @@
 }
 /*}}}*/
-/*FUNCTION Matpar::InputUpdateFromSolution{{{*/
-void   Matpar::InputUpdateFromSolution(IssmDouble* solution){
-	/*Nothing updated yet*/
-}
-/*}}}*/
 
 /*Matpar management: */
-/*FUNCTION Matpar::InputDuplicate{{{*/
-void  Matpar::InputDuplicate(int original_enum,int new_enum){
-
-	   /*Call inputs method*/
-	   if (IsInput(original_enum)) inputs->DuplicateInput(original_enum,new_enum);
-
-}
-/*}}}*/
 /*FUNCTION Matpar::Configure {{{*/
 void  Matpar::Configure(Elements* elementsin){
 
 	/*nothing done yet!*/
+
+}
+/*}}}*/
+/*FUNCTION Matpar::Configure {{{*/
+IssmDouble Matpar::GetMaterialParameter(int enum_in){
+
+	switch(enum_in){
+		case MaterialsRhoIceEnum:                    return this->rho_ice;
+		case MaterialsRhoWaterEnum:                  return this->rho_water;
+		case MaterialsRhoFreshwaterEnum:             return this->rho_freshwater;
+		case MaterialsMuWaterEnum:                   return this->mu_water;
+		case MaterialsHeatcapacityEnum:              return this->heatcapacity;
+		case MaterialsThermalconductivityEnum:       return this->thermalconductivity;
+		case MaterialsTemperateiceconductivityEnum:  return this->temperateiceconductivity;
+		case MaterialsLatentheatEnum:                return this->latentheat;
+		case MaterialsBetaEnum:                      return this->beta;
+		case MaterialsMeltingpointEnum:              return this->meltingpoint;
+		case ConstantsReferencetemperatureEnum:      return this->referencetemperature;
+		case MaterialsMixedLayerCapacityEnum:        return this->mixed_layer_capacity;
+		case MaterialsThermalExchangeVelocityEnum:   return this->thermal_exchange_velocity;
+		case HydrologydcSedimentPorosityEnum:        return this->sediment_porosity;
+		case HydrologydcSedimentThicknessEnum:       return this->sediment_thickness;
+		case HydrologydcSedimentCompressibilityEnum: return this->sediment_compressibility;
+		case HydrologydcEplPorosityEnum:             return this->epl_porosity;
+		case HydrologydcEplCompressibilityEnum:      return this->epl_compressibility;
+		case HydrologydcEplConductivityEnum:         return this->epl_conductivity;
+		case HydrologydcEplInitialThicknessEnum:     return this->epl_init_thickness;
+		case HydrologydcEplMaxThicknessEnum:         return this->epl_max_thickness;
+		case HydrologydcWaterCompressibilityEnum:    return this->water_compressibility;
+		case HydrologyshreveCREnum:                  return this->hydro_CR;
+		case HydrologyshreveKnEnum:                  return this->hydro_kn;
+		case HydrologyshreveNEnum:                   return this->hydro_n;
+		case HydrologyshrevePEnum:                   return this->hydro_p;
+		case HydrologyshreveQEnum:                   return this->hydro_q;
+		case ConstantsGEnum:                         return this->g;
+		default: _error_("Enum "<<EnumToStringx(enum_in)<<" not supported yet");
+	}
 
 }
@@ -306,4 +346,9 @@
 IssmDouble Matpar::GetThermalConductivity(){
 	return thermalconductivity;
+}
+/*}}}*/
+/*FUNCTION Matpar::GetTemperateIceConductivity {{{*/
+IssmDouble Matpar::GetTemperateIceConductivity(){
+	return temperateiceconductivity;
 }
 /*}}}*/
@@ -340,18 +385,13 @@
 /*FUNCTION Matpar::GetSedimentStoring {{{*/
 IssmDouble Matpar::GetSedimentStoring(){
-	return this->rho_freshwater* this->g* this->sediment_porosity* this->sediment_thickness*
-    ( this->water_compressibility+( this->sediment_compressibility/ this->sediment_porosity));		 
-}		 
-/*}}}*/ 
-/*FUNCTION Matpar::GetEplStoring {{{*/
-IssmDouble Matpar::GetEplStoring(){
-	return this->rho_freshwater* this->g* this->epl_porosity* this->epl_thickness*
-    ( this->water_compressibility+( this->epl_compressibility/ this->epl_porosity));		 
-}		 
-/*}}}*/ 
-/*FUNCTION Matpar::GetSedimentTransitivity {{{*/
-IssmDouble Matpar::GetSedimentTransmitivity(){
-	return sediment_transmitivity;		 
-}		 
+	return this->rho_freshwater * this->g * this->sediment_porosity * this->sediment_thickness *
+    (this->water_compressibility + (this->sediment_compressibility / this->sediment_porosity));		 
+}		 
+/*}}}*/ 
+/*FUNCTION Matpar::GetEplSpecificStoring {{{*/
+IssmDouble Matpar::GetEplSpecificStoring(){
+	return this->rho_freshwater * this->g * this->epl_porosity * 
+    (this->water_compressibility + (this->epl_compressibility / this->epl_porosity));		 
+}		 	 
 /*}}}*/ 
 /*FUNCTION Matpar::GetSedimentThickness {{{*/
@@ -359,8 +399,18 @@
 	return sediment_thickness;		 
 }		 
-/*}}}*/ 
-/*FUNCTION Matpar::GetEplTransitivity {{{*/
-IssmDouble Matpar::GetEplTransmitivity(){
-	return epl_transmitivity;		 
+/*}}}*/	
+/*FUNCTION Matpar::GetEplInitialThickness {{{*/
+IssmDouble Matpar::GetEplInitialThickness(){
+	return epl_init_thickness;		 
+}		 
+/*}}}*/	
+/*FUNCTION Matpar::GetEplMaxThickness {{{*/
+IssmDouble Matpar::GetEplMaxThickness(){
+	return epl_max_thickness;		 
+}		 
+/*}}}*/	
+/*FUNCTION Matpar::GetEplConductivity {{{*/
+IssmDouble Matpar::GetEplConductivity(){
+	return epl_conductivity;		 
 }		 
 /*}}}*/			 
@@ -377,35 +427,54 @@
 /*FUNCTION Matpar::GetEnthalpyDiffusionParameter{{{*/
 IssmDouble Matpar::GetEnthalpyDiffusionParameter(IssmDouble enthalpy,IssmDouble pressure){
-	/*if (enthalpy<=PureIceEnthalpy(pressure))
+	if (enthalpy<PureIceEnthalpy(pressure))
 		return thermalconductivity/heatcapacity;
 	else
-		return thermalconductivity/heatcapacity*pow(10.,-5);
-	*/
-
-	IssmDouble eps=0.05*heatcapacity;
-	IssmDouble hpmp=PureIceEnthalpy(pressure);
-	IssmDouble kappa_c=thermalconductivity/heatcapacity;
-	IssmDouble kappa_t=thermalconductivity/heatcapacity*pow(10.,-1);
-	return 1./(1.+exp(-(enthalpy-(hpmp))/eps))*(kappa_t-kappa_c) + kappa_c;
+		return temperateiceconductivity/heatcapacity;
 }
 /*}}}*/
 /*FUNCTION Matpar::GetEnthalpyDiffusionParameterVolume{{{*/
-IssmDouble Matpar::GetEnthalpyDiffusionParameterVolume(IssmDouble enthalpy0, IssmDouble enthalpy1, IssmDouble pressure0, IssmDouble pressure1){
-	/*returns kappa depending on distribution of enthalpy over edge of element
-		lambda is the barycentric coordinate that solves H0+(H1-H0)*lambda=H_pureice.
-		it represents the fraction of the ice column which is temperate/cold like H0.
-		if lambda<0 or lambda>1, then the whole ice column is cold or temperate, respectively.
-	*/
-	IssmDouble kappa, kappa0, kappa1;
-	if (enthalpy0!=enthalpy1){
-		IssmDouble lambda=(PureIceEnthalpy(pressure0)-enthalpy0)/(enthalpy1-enthalpy0);
-		if ((lambda>=0.) && (lambda<=1.)){
-			kappa0=GetEnthalpyDiffusionParameter(enthalpy0,pressure0);
-			kappa1=GetEnthalpyDiffusionParameter(enthalpy1,pressure1);
-			kappa=lambda*kappa0+(1.-lambda)*kappa1;
+IssmDouble Matpar::GetEnthalpyDiffusionParameterVolume(int numvertices,IssmDouble* enthalpy,IssmDouble* pressure){
+
+	int         iv;
+	IssmDouble  lambda;                 // fraction of cold ice
+	IssmDouble  kappa,kappa_c,kappa_t;  //enthalpy conductivities
+	IssmDouble  Hc,Ht;
+	IssmDouble* PIE   = xNew<IssmDouble>(numvertices);
+	IssmDouble* dHpmp = xNew<IssmDouble>(numvertices);
+
+	for(iv=0; iv<numvertices; iv++){
+		PIE[iv]=PureIceEnthalpy(pressure[iv]);
+		dHpmp[iv]=enthalpy[iv]-PIE[iv];
+	}
+
+	bool allequalsign=true;
+	if(dHpmp[0]<0)
+		for(iv=1; iv<numvertices;iv++) allequalsign=(allequalsign && (dHpmp[iv]<0));
+	else
+		for(iv=1; iv<numvertices;iv++) allequalsign=(allequalsign && (dHpmp[iv]>=0));
+
+	if(allequalsign){
+		kappa=GetEnthalpyDiffusionParameter(enthalpy[0], pressure[0]);
+	}
+	else {
+		/* return harmonic mean of thermal conductivities, weighted by fraction of cold/temperate ice,
+		 cf Patankar 1980, pp44 */
+		kappa_c=GetEnthalpyDiffusionParameter(PureIceEnthalpy(0.)-1.,0.);
+		kappa_t=GetEnthalpyDiffusionParameter(PureIceEnthalpy(0.)+1.,0.);
+		Hc=0.; Ht=0.;
+		for(iv=0; iv<numvertices;iv++){
+			if(enthalpy[iv]<PIE[iv])
+			 Hc+=(PIE[iv]-enthalpy[iv]);
+			else
+			 Ht+=(enthalpy[iv]-PIE[iv]);
 		}
-	}
-	else
-		kappa=GetEnthalpyDiffusionParameter(enthalpy0, pressure0);
+		_assert_((Hc+Ht)>0.);
+		lambda = Hc/(Hc+Ht);
+		kappa  = 1./(lambda/kappa_c + (1.-lambda)/kappa_t);
+	}
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(PIE);
+	xDelete<IssmDouble>(dHpmp);
 	return kappa;
 }
@@ -448,5 +517,4 @@
 }
 /*}}}*/
-
 /*FUNCTION Matpar::GetLithosphereShearModulus {{{*/			 
 IssmDouble Matpar::GetLithosphereShearModulus(){		 
@@ -469,7 +537,2 @@
 }		 
 /*}}}*/ 
-/*FUNCTION Matpar::IsInput{{{*/
-bool Matpar::IsInput(int name){
-	return false;
-}
-/*}}}*/
Index: /issm/trunk/src/c/classes/Materials/Matpar.h
===================================================================
--- /issm/trunk/src/c/classes/Materials/Matpar.h	(revision 17805)
+++ /issm/trunk/src/c/classes/Materials/Matpar.h	(revision 17806)
@@ -15,5 +15,5 @@
 
 	private: 
-		int	  mid;
+		int	      mid;
 		IssmDouble  rho_ice; 
 		IssmDouble  rho_water;
@@ -22,4 +22,5 @@
 		IssmDouble  heatcapacity;
 		IssmDouble  thermalconductivity;
+		IssmDouble  temperateiceconductivity;
 		IssmDouble  latentheat;
 		IssmDouble  beta;
@@ -43,11 +44,11 @@
 		IssmDouble  sediment_porosity;	 
 		IssmDouble  sediment_thickness;
-		IssmDouble  sediment_transmitivity;	 
 		IssmDouble  water_compressibility;
 
 		IssmDouble  epl_compressibility;
-		IssmDouble  epl_porosity;	 
-		IssmDouble  epl_thickness;
-		IssmDouble  epl_transmitivity;	 
+		IssmDouble  epl_porosity;
+		IssmDouble  epl_init_thickness;
+		IssmDouble  epl_max_thickness;
+		IssmDouble  epl_conductivity;	 
 
 		/*gia: */
@@ -76,15 +77,11 @@
 		void   InputUpdateFromConstant(int constant, int name);
 		void   InputUpdateFromConstant(bool constant, int name);
-		void   InputUpdateFromSolution(IssmDouble* solution);
-		void   InputUpdateFromIoModel(int index, IoModel* iomodel){_error_("not implemented yet");};
+		void   InputUpdateFromIoModel(int index, IoModel* iomodel){_error_("not implemented");};
 		/*}}}*/
 		/*Material virtual functions resolution: {{{*/
-		void       InputDuplicate(int original_enum,int new_enum);
+		Material*  copy2(Element* element){_error_("not implemented");};
 		void       Configure(Elements* elements);
-		void       GetVectorFromInputs(Vector<IssmDouble>* vector,int input_enum){return;}
-		void       GetViscosity2d(IssmDouble* pviscosity, IssmDouble* pepsilon){_error_("not supported");};
-		void       GetViscosity2dvertical(IssmDouble* pviscosity, IssmDouble* pepsilon){_error_("not supported");};
-		void       GetViscosity3d(IssmDouble* pviscosity3d, IssmDouble* pepsilon){_error_("not supported");};
-		void       GetViscosity3dFS(IssmDouble* pviscosity3d, IssmDouble* epsilon){_error_("not supported");};
+		void       GetViscosity(IssmDouble* pviscosity,IssmDouble eps_eff){_error_("not supported");};
+		void       GetViscosityBar(IssmDouble* pviscosity,IssmDouble eps_eff){_error_("not supported");};
 		void       GetViscosityComplement(IssmDouble* pviscosity_complement, IssmDouble* pepsilon){_error_("not supported");};
 		void       GetViscosityDComplement(IssmDouble* pviscosity_complement, IssmDouble* pepsilon){_error_("not supported");};
@@ -93,4 +90,5 @@
 		void       GetViscosity2dDerivativeEpsSquare(IssmDouble* pmu_prime, IssmDouble* pepsilon){_error_("not supported");};
 		IssmDouble GetA(){_error_("not supported");};
+		IssmDouble GetAbar(){_error_("not supported");};
 		IssmDouble GetB(){_error_("not supported");};
 		IssmDouble GetBbar(){_error_("not supported");};
@@ -98,4 +96,5 @@
 		IssmDouble GetD(){_error_("not supported");};
 		IssmDouble GetDbar(){_error_("not supported");};
+		bool       IsDamage(){_error_("not supported");};
 		/*}}}*/
 		/*Numerics: {{{*/
@@ -109,4 +108,5 @@
 		IssmDouble GetHeatCapacity();
 		IssmDouble GetThermalConductivity();
+		IssmDouble GetTemperateIceConductivity();
 		IssmDouble GetLatentHeat();
 		IssmDouble GetBeta();
@@ -119,21 +119,22 @@
 		IssmDouble GetHydrologyN();
 		IssmDouble GetSedimentStoring();
-		IssmDouble GetEplStoring();
-		IssmDouble GetSedimentTransmitivity();
+		IssmDouble GetEplSpecificStoring();
 		IssmDouble GetSedimentThickness();
-		IssmDouble GetEplTransmitivity();
+		IssmDouble GetEplConductivity();
+		IssmDouble GetEplInitialThickness();
+		IssmDouble GetEplMaxThickness();
 		IssmDouble TMeltingPoint(IssmDouble pressure);
 		IssmDouble PureIceEnthalpy(IssmDouble pressure);
 		IssmDouble GetEnthalpyDiffusionParameter(IssmDouble enthalpy,IssmDouble pressure);
-		IssmDouble GetEnthalpyDiffusionParameterVolume(IssmDouble enthalpy0, IssmDouble enthalpy1, IssmDouble pressure0, IssmDouble pressure1);
+		IssmDouble GetEnthalpyDiffusionParameterVolume(int numvertices,IssmDouble* enthalpy,IssmDouble* pressure);
 		IssmDouble GetLithosphereShearModulus();
 		IssmDouble GetLithosphereDensity();
 		IssmDouble GetMantleShearModulus();
 		IssmDouble GetMantleDensity();
-		void   EnthalpyToThermal(IssmDouble* ptemperature,IssmDouble* pwaterfraction,IssmDouble enthalpy,IssmDouble pressure);
-		void   ThermalToEnthalpy(IssmDouble* penthalpy,IssmDouble temperature,IssmDouble waterfraction,IssmDouble pressure);
+		void       EnthalpyToThermal(IssmDouble* ptemperature,IssmDouble* pwaterfraction,IssmDouble enthalpy,IssmDouble pressure);
+		void       ThermalToEnthalpy(IssmDouble* penthalpy,IssmDouble temperature,IssmDouble waterfraction,IssmDouble pressure);
 		IssmDouble GetDesFac();
 		IssmDouble GetS0p(); 
-		bool       IsInput(int name);
+		IssmDouble GetMaterialParameter(int in_enum); 
 		/*}}}*/
 
Index: /issm/trunk/src/c/classes/Misfit.h
===================================================================
--- /issm/trunk/src/c/classes/Misfit.h	(revision 17806)
+++ /issm/trunk/src/c/classes/Misfit.h	(revision 17806)
@@ -0,0 +1,159 @@
+/*!\file Misfit.h
+ * \brief: header file for Misfit object
+ */
+
+#ifndef _MISFIT_H_
+#define _MISFIT_H_
+
+/*Headers:*/
+/*{{{*/
+#include "./Definition.h"
+#include "../datastructures/datastructures.h"
+#include "./Elements/Element.h"
+#include "./Elements/Elements.h"
+#include "./FemModel.h"
+#include "../modules/SurfaceAreax/SurfaceAreax.h"
+#include "../classes/Params/Parameters.h"
+/*}}}*/
+
+class Misfit: public Object, public Definition{
+
+	public: 
+
+		char*       name;
+		int         model_enum;
+		int         observation_enum;
+		int         weights_enum;
+		char*       timeinterpolation;
+		
+		IssmDouble  misfit; //value carried over in time.
+		int         lock; // if lock is on, we just return the value stored in "misfit".  this is used so we don't compute misfit past the final_time
+		
+		/*Misfit constructors, destructors :*/
+		/*FUNCTION Misfit() {{{*/
+		Misfit(){
+
+			this->name = NULL;
+			this->model_enum = UNDEF;
+			this->observation_enum = UNDEF;
+			this->weights_enum = UNDEF;
+			this->timeinterpolation=NULL;
+			this->misfit=0;
+			this->lock=0;
+
+		}
+		/*}}}*/
+		/*FUNCTION Misfit(char* in_name, int in_model_enum, int in_observation_enum char* in_timeinterpolation, int in_weights_enum) {{{*/
+		Misfit(char* in_name, int in_model_enum, int in_observation_enum, char* in_timeinterpolation, int in_weights_enum){
+
+			this->name   = xNew<char>(strlen(in_name)+1);
+			xMemCpy<char>(this->name,in_name,strlen(in_name)+1);
+
+			this->timeinterpolation   = xNew<char>(strlen(in_timeinterpolation)+1);
+			xMemCpy<char>(this->timeinterpolation,in_timeinterpolation,strlen(in_timeinterpolation)+1);
+
+			this->model_enum=in_model_enum;
+			this->observation_enum=in_observation_enum;
+			this->weights_enum=in_weights_enum;
+			
+			this->misfit=0;
+			this->lock=0;
+		}
+		/*}}}*/
+		/*FUNCTION ~Misfit() {{{*/
+		~Misfit(){
+			if(this->name)xDelete(this->name);
+			if(this->timeinterpolation)xDelete(this->timeinterpolation);
+			this->misfit=0;
+			this->lock=0;
+		}
+		/*}}}*/
+		/*Object virtual function resolutoin: */
+		/*FUNCTION Echo(){{{*/
+		void Echo(void){
+			_printf_(" Misfit: " << name << "\n");
+			_printf_("    model_enum: " << model_enum << " " << EnumToStringx(model_enum) << "\n");
+			_printf_("    observation_enum: " << observation_enum << " " << EnumToStringx(observation_enum) << "\n");
+			_printf_("    weights_enum: " << weights_enum << " " << EnumToStringx(weights_enum) << "\n");
+			_printf_("    timeinterpolation: " << timeinterpolation << "\n");
+		}
+		/*}}}*/
+		/*FUNCTION DeepEcho(){{{*/
+		void DeepEcho(void){
+			this->Echo();
+		}
+		/*}}}*/
+		/*FUNCTION Id(){{{*/
+		int Id(void){
+			return -1;
+		}
+		/*}}}*/
+		/*FUNCTION ObjectEnum{{{*/
+		int ObjectEnum(void){
+			return MisfitEnum;
+		}
+		/*}}}*/
+		/*FUNCTION copy {{{*/
+		Object* copy() {
+			return new Misfit(this->name,this->model_enum,this->observation_enum,this->timeinterpolation,this->weights_enum);
+		}
+		/*}}}*/
+		/*Definition virtual function resolutoin: */
+		/*FUNCTION char* Name() {{{*/
+		char* Name(){
+
+			char* name2=xNew<char>(strlen(this->name)+1);
+			xMemCpy(name2,this->name,strlen(this->name)+1);
+
+			return name2;
+		}
+		/*}}}*/
+		/*FUNCTION IssmDouble Response(FemModel* femmodel) {{{*/
+		 IssmDouble Response(FemModel* femmodel){
+
+			 int i;
+			 IssmDouble misfit_t=0.;
+			 IssmDouble all_misfit_t=0.;
+			 IssmDouble dt;
+			 IssmDouble area_t=0.;
+			 IssmDouble all_area_t;
+			 IssmDouble time,starttime,finaltime;
+
+			 femmodel->parameters->FindParam(&starttime,TimesteppingStartTimeEnum);
+			 femmodel->parameters->FindParam(&finaltime,TimesteppingFinalTimeEnum);
+			 femmodel->parameters->FindParam(&time,TimeEnum);
+
+			 /*If we are locked, return time average: */
+			 if(this->lock)return misfit/(time-starttime);
+
+
+			 for(i=0;i<femmodel->elements->Size();i++){
+				 Element* element=(Element*)femmodel->elements->GetObjectByOffset(i);
+				 misfit_t+=element->Misfit(model_enum,observation_enum,weights_enum);
+				 area_t+=element->MisfitArea(weights_enum);
+			 }
+
+			 ISSM_MPI_Allreduce ( (void*)&misfit_t,(void*)&all_misfit_t,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,IssmComm::GetComm());
+			 ISSM_MPI_Allreduce ( (void*)&area_t,(void*)&all_area_t,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,IssmComm::GetComm());
+			 area_t=all_area_t;
+			 misfit_t=all_misfit_t;
+			 
+			 /*Divide by surface area if not nill!: */
+			 if (area_t!=0) misfit_t=misfit_t/area_t;
+
+			 /*Recover delta_t: */
+			 femmodel->parameters->FindParam(&dt,TimesteppingTimeStepEnum);
+
+			 /*Add this time's contribution to curent misfit: */
+			 misfit+=dt*misfit_t;
+
+			 /*Do we lock? i.e. are we at final_time? :*/
+			 if(time==finaltime)this->lock=1;
+
+			 /*What we return is the value of misfit / time: */
+			 return misfit/(time-starttime);
+		 }
+			/*}}}*/
+};
+
+#endif  /* _MISFIT_H_ */
Index: /issm/trunk/src/c/classes/Node.cpp
===================================================================
--- /issm/trunk/src/c/classes/Node.cpp	(revision 17805)
+++ /issm/trunk/src/c/classes/Node.cpp	(revision 17806)
@@ -43,5 +43,5 @@
 
 	Analysis* analysis = EnumToAnalysis(analysis_enum);
-	int numdofs        = analysis->DofsPerNode(&doftypes,iomodel->meshtype,in_approximation);
+	int numdofs        = analysis->DofsPerNode(&doftypes,iomodel->domaintype,in_approximation);
 	indexing.Init(numdofs,doftypes);
 	xDelete<int>(doftypes);
@@ -54,5 +54,4 @@
 
 	/*Stressbalance Horiz*/
-	#ifdef _HAVE_STRESSBALANCE_
 	if(analysis_enum==StressbalanceAnalysisEnum){
 
@@ -62,22 +61,22 @@
 		_assert_(sqrt( coord_system[0][0]*coord_system[0][0] + coord_system[1][0]*coord_system[1][0]) >1.e-4);
 
-		if(iomodel->meshtype==Mesh3DEnum){
+		if(iomodel->domaintype!=Domain2DhorizontalEnum){
 			/*We have a  3d mesh, we may have collapsed elements, hence dead nodes. Freeze them out: */
-			_assert_(iomodel->Data(MeshVertexonbedEnum)); 
+			_assert_(iomodel->Data(MeshVertexonbaseEnum)); 
 			_assert_(iomodel->Data(FlowequationVertexEquationEnum));
-			if(in_approximation==SSAApproximationEnum && !reCast<int>(iomodel->Data(MeshVertexonbedEnum)[io_index])){
+			if(in_approximation==SSAApproximationEnum && !reCast<int>(iomodel->Data(MeshVertexonbaseEnum)[io_index])){
 				this->Deactivate();
 			}
-			if(in_approximation==L1L2ApproximationEnum && !reCast<int>(iomodel->Data(MeshVertexonbedEnum)[io_index])){
+			if(in_approximation==L1L2ApproximationEnum && !reCast<int>(iomodel->Data(MeshVertexonbaseEnum)[io_index])){
 				this->Deactivate();
 			}
 			if(in_approximation==SSAHOApproximationEnum && reCast<int>(iomodel->Data(FlowequationBorderSSAEnum)[io_index])){
-				if(!reCast<int>(iomodel->Data(MeshVertexonbedEnum)[io_index])){
+				if(!reCast<int>(iomodel->Data(MeshVertexonbaseEnum)[io_index])){
 					this->Deactivate();
 				}
 			}
 			if(in_approximation==SSAFSApproximationEnum && reCast<int>(iomodel->Data(FlowequationBorderSSAEnum)[io_index])){
-				if(!reCast<int>(iomodel->Data(MeshVertexonbedEnum)[io_index])){
-					for(k=1;k<=2;k++) this->FreezeDof(k);
+				if(!reCast<int>(iomodel->Data(MeshVertexonbaseEnum)[io_index])){
+					for(k=0;k<=1;k++) this->FreezeDof(k);
 				}
 			}
@@ -88,5 +87,4 @@
 		}
 	}
-	#endif
 
 	/*2d solutions in 3d, we need to constrain all the nodes that are not on base*/
@@ -99,10 +97,12 @@
 				analysis_enum==HydrologyDCInefficientAnalysisEnum ||
 				analysis_enum==DamageEvolutionAnalysisEnum || 
-				analysis_enum==HydrologyDCEfficientAnalysisEnum
+				analysis_enum==HydrologyDCEfficientAnalysisEnum ||
+				analysis_enum==LevelsetAnalysisEnum ||
+				analysis_enum==ExtrapolationAnalysisEnum
 				){
-		if(iomodel->meshtype==Mesh3DEnum || iomodel->meshtype==Mesh2DverticalEnum){
+		if(iomodel->domaintype!=Domain2DhorizontalEnum){
 			/*On a 3d mesh, we may have collapsed elements, hence dead nodes. Freeze them out: */
-			_assert_(iomodel->Data(MeshVertexonbedEnum));
-			if(!(reCast<bool>(iomodel->Data(MeshVertexonbedEnum)[io_index]))){
+			_assert_(iomodel->Data(MeshVertexonbaseEnum));
+			if(!(reCast<bool>(iomodel->Data(MeshVertexonbaseEnum)[io_index]))){
 				this->Deactivate();
 			}
@@ -110,8 +110,7 @@
 	}
 	if(
-				analysis_enum==FreeSurfaceTopAnalysisEnum ||
-				analysis_enum==L2ProjectionTopAnalysisEnum
+				analysis_enum==FreeSurfaceTopAnalysisEnum
 				){
-		if(iomodel->meshtype==Mesh3DEnum || iomodel->meshtype==Mesh2DverticalEnum){
+		if(iomodel->domaintype!=Domain2DhorizontalEnum){
 			/*On a 3d mesh, we may have collapsed elements, hence dead nodes. Freeze them out: */
 			_assert_(iomodel->Data(MeshVertexonsurfaceEnum));
@@ -363,5 +362,4 @@
 }
 /*}}}*/
-#ifdef _HAVE_STRESSBALANCE_
 /*FUNCTION Node::GetCoordinateSystem{{{*/
 void Node::GetCoordinateSystem(IssmDouble* coord_system_out){
@@ -372,5 +370,4 @@
 }
 /*}}}*/
-#endif
 /*FUNCTION Node::InAnalysis{{{*/
 bool Node::InAnalysis(int in_analysis_enum){
@@ -386,6 +383,6 @@
 	/*Dof should be added in the s set, describing which 
 	 * dofs are constrained to a certain value (dirichlet boundary condition*/
-	DofInSSet(dof-1);
-	this->indexing.svalues[dof-1]=value;
+	DofInSSet(dof);
+	this->indexing.svalues[dof]=value;
 }
 /*}}}*/
@@ -408,6 +405,6 @@
 
 	/*Dof should be added to the f-set, and taken out of the s-set:*/
-	DofInFSet(dof-1);
-	this->indexing.svalues[dof-1]=0.;
+	DofInFSet(dof);
+	this->indexing.svalues[dof]=0.;
 }
 /*}}}*/
@@ -459,4 +456,5 @@
 	/*Put dof for this node into the f set (ie, this dof will NOT be constrained 
 	 * to a fixed value during computations. */
+	_assert_(dof<this->indexing.gsize);
 
 	if(this->indexing.f_set[dof] == 0){
@@ -470,5 +468,5 @@
 void  Node::FreezeDof(int dof){
 
-	DofInSSet(dof-1); //with 0 displacement for this dof.
+	DofInSSet(dof); //with 0 displacement for this dof.
 
 }
@@ -901,275 +899,2 @@
 }
 /*}}}*/
-#ifdef _HAVE_STRESSBALANCE_
-void TransformInvStiffnessMatrixCoord(ElementMatrix* Ke,Node** nodes,int numnodes,int cs_enum){/*{{{*/
-
-	int* cs_array=NULL;
-
-	/*All nodes have the same Coordinate System*/
-	cs_array=xNew<int>(numnodes);
-	for(int i=0;i<numnodes;i++) cs_array[i]=cs_enum;
-
-	/*Call core*/
-	TransformInvStiffnessMatrixCoord(Ke,nodes,numnodes,cs_array);
-
-	/*Clean-up*/
-	xDelete<int>(cs_array);
-}
-/*}}}*/
-void TransformInvStiffnessMatrixCoord(ElementMatrix* Ke,Node** nodes,int numnodes,int* cs_array){/*{{{*/
-
-	int     i,j;
-	int     numdofs   = 0;
-	IssmDouble *transform = NULL;
-	IssmDouble *values    = NULL;
-
-	/*Get total number of dofs*/
-	for(i=0;i<numnodes;i++){
-		switch(cs_array[i]){
-			case PressureEnum: numdofs+=1; break;
-			case XYEnum:       numdofs+=2; break;
-			case XYZEnum:      numdofs+=3; break;
-			default: _error_("Coordinate system " << EnumToStringx(cs_array[i]) << " not supported yet");
-		}
-	}
-
-	/*Copy current stiffness matrix*/
-	values=xNew<IssmDouble>(Ke->nrows*Ke->ncols);
-	for(i=0;i<Ke->nrows;i++) for(j=0;j<Ke->ncols;j++) values[i*Ke->ncols+j]=Ke->values[i*Ke->ncols+j];
-
-	/*Get Coordinate Systems transform matrix*/
-	CoordinateSystemTransform(&transform,nodes,numnodes,cs_array);
-
-	/*Transform matrix: R*Ke*R^T */
-	TripleMultiply(transform,numdofs,numdofs,0,
-				values,Ke->nrows,Ke->ncols,0,
-				transform,numdofs,numdofs,1,
-				&Ke->values[0],0);
-
-	/*Free Matrix*/
-	xDelete<IssmDouble>(transform);
-	xDelete<IssmDouble>(values);
-}
-/*}}}*/
-void TransformLoadVectorCoord(ElementVector* pe,Node** nodes,int numnodes,int cs_enum){/*{{{*/
-
-	int* cs_array=NULL;
-
-	/*All nodes have the same Coordinate System*/
-	cs_array=xNew<int>(numnodes);
-	for(int i=0;i<numnodes;i++) cs_array[i]=cs_enum;
-
-	/*Call core*/
-	TransformLoadVectorCoord(pe,nodes,numnodes,cs_array);
-
-	/*Clean-up*/
-	xDelete<int>(cs_array);
-}
-/*}}}*/
-void TransformLoadVectorCoord(ElementVector* pe,Node** nodes,int numnodes,int* cs_array){/*{{{*/
-
-	int     i;
-	int     numdofs   = 0;
-	IssmDouble *transform = NULL;
-	IssmDouble *values    = NULL;
-
-	/*Get total number of dofs*/
-	for(i=0;i<numnodes;i++){
-		switch(cs_array[i]){
-			case PressureEnum: numdofs+=1; break;
-			case XYEnum:       numdofs+=2; break;
-			case XYZEnum:      numdofs+=3; break;
-			default: _error_("Coordinate system " << EnumToStringx(cs_array[i]) << " not supported yet");
-		}
-	}
-
-	/*Copy current load vector*/
-	values=xNew<IssmDouble>(pe->nrows);
-	for(i=0;i<pe->nrows;i++) values[i]=pe->values[i];
-
-	/*Get Coordinate Systems transform matrix*/
-	CoordinateSystemTransform(&transform,nodes,numnodes,cs_array);
-
-	/*Transform matrix: R^T*pe */
-	MatrixMultiply(transform,numdofs,numdofs,1,
-				values,pe->nrows,1,0,
-				&pe->values[0],0);
-
-	/*Free Matrices*/
-	xDelete<IssmDouble>(transform);
-	xDelete<IssmDouble>(values);
-}
-/*}}}*/
-void TransformSolutionCoord(IssmDouble* solution,Node** nodes,int numnodes,int cs_enum){/*{{{*/
-
-	int* cs_array=NULL;
-
-	/*All nodes have the same Coordinate System*/
-	cs_array=xNew<int>(numnodes);
-	for(int i=0;i<numnodes;i++) cs_array[i]=cs_enum;
-
-	/*Call core*/
-	TransformSolutionCoord(solution,nodes,numnodes,cs_array);
-
-	/*Clean-up*/
-	xDelete<int>(cs_array);
-}
-/*}}}*/
-void TransformSolutionCoord(IssmDouble* solution,Node** nodes,int numnodes,int* cs_array){/*{{{*/
-
-	int     i;
-	int     numdofs   = 0;
-	IssmDouble *transform = NULL;
-	IssmDouble *values    = NULL;
-
-	/*Get total number of dofs*/
-	for(i=0;i<numnodes;i++){
-		switch(cs_array[i]){
-			case PressureEnum: numdofs+=1; break;
-			case XYEnum:       numdofs+=2; break;
-			case XYZEnum:      numdofs+=3; break;
-			default: _error_("Coordinate system " << EnumToStringx(cs_array[i]) << " not supported yet");
-		}
-	}
-
-	/*Copy current solution vector*/
-	values=xNew<IssmDouble>(numdofs);
-	for(i=0;i<numdofs;i++) values[i]=solution[i];
-
-	/*Get Coordinate Systems transform matrix*/
-	CoordinateSystemTransform(&transform,nodes,numnodes,cs_array);
-
-	/*Transform matrix: R*U */
-	MatrixMultiply(transform,numdofs,numdofs,0,
-				values,numdofs,1,0,
-				&solution[0],0);
-
-	/*Free Matrices*/
-	xDelete<IssmDouble>(transform);
-	xDelete<IssmDouble>(values);
-}
-/*}}}*/
-void TransformStiffnessMatrixCoord(ElementMatrix* Ke,Node** nodes,int numnodes,int cs_enum){/*{{{*/
-
-	int* cs_array=NULL;
-
-	/*All nodes have the same Coordinate System*/
-	cs_array=xNew<int>(numnodes);
-	for(int i=0;i<numnodes;i++) cs_array[i]=cs_enum;
-
-	/*Call core*/
-	TransformStiffnessMatrixCoord(Ke,nodes,numnodes,cs_array);
-
-	/*Clean-up*/
-	xDelete<int>(cs_array);
-}
-/*}}}*/
-void TransformStiffnessMatrixCoord(ElementMatrix* Ke,Node** nodes,int numnodes,int* cs_array){/*{{{*/
-
-	int         numdofs = 0;
-	IssmDouble *transform = NULL;
-	IssmDouble *values    = NULL;
-
-	/*Get total number of dofs*/
-	for(int i=0;i<numnodes;i++){
-		switch(cs_array[i]){
-			case PressureEnum: numdofs+=1; break;
-			case XYEnum:       numdofs+=2; break;
-			case XYZEnum:      numdofs+=3; break;
-			default: _error_("Coordinate system " << EnumToStringx(cs_array[i]) << " not supported yet");
-		}
-	}
-
-	/*Copy current stiffness matrix*/
-	values=xNew<IssmDouble>(Ke->nrows*Ke->ncols);
-	for(int i=0;i<Ke->nrows*Ke->ncols;i++) values[i]=Ke->values[i];
-
-	/*Get Coordinate Systems transform matrix*/
-	CoordinateSystemTransform(&transform,nodes,numnodes,cs_array);
-
-	/*Transform matrix: R^T*Ke*R */
-	TripleMultiply(transform,numdofs,numdofs,1,
-				values,Ke->nrows,Ke->ncols,0,
-				transform,numdofs,numdofs,0,
-				&Ke->values[0],0);
-
-	/*Free Matrix*/
-	xDelete<IssmDouble>(transform);
-	xDelete<IssmDouble>(values);
-}
-/*}}}*/
-void CoordinateSystemTransform(IssmDouble** ptransform,Node** nodes,int numnodes,int* cs_array){/*{{{*/
-
-	int         i,counter;
-	int         numdofs   = 0;
-	IssmDouble  norm;
-	IssmDouble *transform = NULL;
-	IssmDouble  coord_system[3][3];
-
-	/*Some checks in debugging mode*/
-	_assert_(numnodes && nodes);
-
-	/*Get total number of dofs*/
-	for(i=0;i<numnodes;i++){
-		switch(cs_array[i]){
-			case PressureEnum: numdofs+=1; break;
-			case XYEnum:       numdofs+=2; break;
-			case XYZEnum:      numdofs+=3; break;
-			default: _error_("Coordinate system " << EnumToStringx(cs_array[i]) << " not supported yet");
-		}
-	}
-
-	/*Allocate and initialize transform matrix*/
-	transform=xNew<IssmDouble>(numdofs*numdofs);
-	for(i=0;i<numdofs*numdofs;i++) transform[i]=0.0;
-
-	/*Create transform matrix for all nodes (x,y for 2d and x,y,z for 3d). It is a block matrix
-	 *for 3 nodes:
-
-	 *     | T1 0  0 |
-	 * Q = | 0  T2 0 |
-	 *     | 0  0  T3|
-	 *
-	 * Where T1 is the transform matrix for node 1. It is a simple copy of the coordinate system
-	 * associated to this node*/
-	counter=0;
-	for(i=0;i<numnodes;i++){
-		nodes[i]->GetCoordinateSystem(&coord_system[0][0]);
-		switch(cs_array[i]){
-			case PressureEnum:
-				/*DO NOT change anything*/
-				transform[(numdofs)*(counter) + counter] = 1.;
-				counter+=1;
-				break;
-			case XYEnum:
-				/*We remove the z component, we need to renormalize x and y: x=[x1 x2 0] y=[-x2 x1 0]*/
-				norm = sqrt( coord_system[0][0]*coord_system[0][0] + coord_system[1][0]*coord_system[1][0]); _assert_(norm>1.e-4);
-				transform[(numdofs)*(counter+0) + counter+0] =   coord_system[0][0]/norm;
-				transform[(numdofs)*(counter+0) + counter+1] = - coord_system[1][0]/norm;
-				transform[(numdofs)*(counter+1) + counter+0] =   coord_system[1][0]/norm;
-				transform[(numdofs)*(counter+1) + counter+1] =   coord_system[0][0]/norm;
-				counter+=2;
-				break;
-			case XYZEnum:
-				/*The 3 coordinates are changed (x,y,z)*/
-				transform[(numdofs)*(counter+0) + counter+0] = coord_system[0][0];
-				transform[(numdofs)*(counter+0) + counter+1] = coord_system[0][1];
-				transform[(numdofs)*(counter+0) + counter+2] = coord_system[0][2];
-				transform[(numdofs)*(counter+1) + counter+0] = coord_system[1][0];
-				transform[(numdofs)*(counter+1) + counter+1] = coord_system[1][1];
-				transform[(numdofs)*(counter+1) + counter+2] = coord_system[1][2];
-				transform[(numdofs)*(counter+2) + counter+0] = coord_system[2][0];
-				transform[(numdofs)*(counter+2) + counter+1] = coord_system[2][1];
-				transform[(numdofs)*(counter+2) + counter+2] = coord_system[2][2];
-				counter+=3;
-				break;
-			default:
-				_error_("Coordinate system " << EnumToStringx(cs_array[i]) << " not supported yet");
-		}
-	}
-
-	/*Assign output pointer*/
-	*ptransform=transform;
-}
-/*}}}*/
-#endif
Index: /issm/trunk/src/c/classes/Node.h
===================================================================
--- /issm/trunk/src/c/classes/Node.h	(revision 17805)
+++ /issm/trunk/src/c/classes/Node.h	(revision 17806)
@@ -56,7 +56,5 @@
 		int   Sid(void); 
 		int   Lid(void); 
-#ifdef _HAVE_STRESSBALANCE_
 		void  GetCoordinateSystem(IssmDouble* coord_system_out);
-#endif
 		bool  InAnalysis(int analysis_enum);
 		int   GetApproximation();
@@ -91,15 +89,4 @@
 int* GetGlobalDofList(Node** nodes,int numnodes,int setenum,int approximation);
 int  GetNumberOfDofs(Node** nodes,int numnodes,int setenum,int approximation);
-#ifdef _HAVE_STRESSBALANCE_
-void TransformInvStiffnessMatrixCoord(ElementMatrix* Ke,Node** nodes,int numnodes,int cs_enum);
-void TransformInvStiffnessMatrixCoord(ElementMatrix* Ke,Node** nodes,int numnodes,int* cs_array);
-void TransformLoadVectorCoord(ElementVector* pe,Node** nodes,int numnodes,int cs_enum);
-void TransformLoadVectorCoord(ElementVector* pe,Node** nodes,int numnodes,int* cs_array);
-void TransformSolutionCoord(IssmDouble* solution,Node** nodes,int numnodes,int cs_enum);
-void TransformSolutionCoord(IssmDouble* solution,Node** nodes,int numnodes,int* cs_array);
-void TransformStiffnessMatrixCoord(ElementMatrix* Ke,Node** nodes,int numnodes,int cs_enum);
-void TransformStiffnessMatrixCoord(ElementMatrix* Ke,Node** nodes,int numnodes,int* cs_array);
-void CoordinateSystemTransform(IssmDouble** ptransform,Node** nodes,int numnodes,int* cs_array);
-#endif
 
 #endif  /* _NODE_H_ */
Index: /issm/trunk/src/c/classes/Params/BoolParam.cpp
===================================================================
--- /issm/trunk/src/c/classes/Params/BoolParam.cpp	(revision 17805)
+++ /issm/trunk/src/c/classes/Params/BoolParam.cpp	(revision 17806)
@@ -42,8 +42,5 @@
 /*FUNCTION BoolParam::DeepEcho{{{*/
 void BoolParam::DeepEcho(void){
-
-	_printf_("BoolParam:\n");
-	_printf_("   enum:  " << this->enum_type << " (" << EnumToStringx(this->enum_type) << ")\n");
-	_printf_("   value: " <<(this->value?"true":"false") << "\n");
+	_printf_(setw(22)<<"   BoolParam "<<setw(35)<<left<<EnumToStringx(this->enum_type)<<" "<<(value?"true":"false")<<"\n");
 }
 /*}}}*/
Index: /issm/trunk/src/c/classes/Params/DataSetParam.cpp
===================================================================
--- /issm/trunk/src/c/classes/Params/DataSetParam.cpp	(revision 17805)
+++ /issm/trunk/src/c/classes/Params/DataSetParam.cpp	(revision 17806)
@@ -44,7 +44,7 @@
 void DataSetParam::DeepEcho(void){
 
-	_printf_("DataSetParam:\n");
-	_printf_("   enum:  " << this->enum_type << " (" << EnumToStringx(this->enum_type) << ")\n");
+	_printf_(setw(22)<<"   DataSetParam "<<setw(35)<<left<<EnumToStringx(this->enum_type)<<" ----- begin\n");
 	this->value->Echo();
+	_printf_(setw(22)<<"   DataSetParam "<<setw(35)<<left<<EnumToStringx(this->enum_type)<<" ----- end\n");
 }
 /*}}}*/
Index: /issm/trunk/src/c/classes/Params/DataSetParam.h
===================================================================
--- /issm/trunk/src/c/classes/Params/DataSetParam.h	(revision 17805)
+++ /issm/trunk/src/c/classes/Params/DataSetParam.h	(revision 17806)
@@ -22,7 +22,8 @@
 	private: 
 		int   enum_type;
+
+	public:
 		DataSet* value;
 
-	public:
 		/*DataSetParam constructors, destructors: {{{*/
 		DataSetParam();
Index: /issm/trunk/src/c/classes/Params/DoubleParam.cpp
===================================================================
--- /issm/trunk/src/c/classes/Params/DoubleParam.cpp	(revision 17805)
+++ /issm/trunk/src/c/classes/Params/DoubleParam.cpp	(revision 17806)
@@ -40,7 +40,5 @@
 void DoubleParam::DeepEcho(void){
 
-	_printf_("DoubleParam:\n");
-	_printf_("   enum:  " << this->enum_type << " (" << EnumToStringx(this->enum_type) << ")\n");
-	_printf_("   value: " << this->value << "\n");
+	_printf_(setw(22)<<"   DoubleParam "<<setw(35)<<left<<EnumToStringx(this->enum_type)<<" "<<this->value<<"\n");
 }
 /*}}}*/
Index: /issm/trunk/src/c/classes/Params/DoubleVecParam.cpp
===================================================================
--- /issm/trunk/src/c/classes/Params/DoubleVecParam.cpp	(revision 17805)
+++ /issm/trunk/src/c/classes/Params/DoubleVecParam.cpp	(revision 17806)
@@ -42,7 +42,5 @@
 void DoubleVecParam::Echo(void){
 
-	_printf_("DoubleVecParam:\n");
-	_printf_("   enum: " << this->enum_type << " (" << EnumToStringx(this->enum_type) << ")\n");
-	_printf_("   vector size: " << this->M << "\n");
+	_printf_(setw(22)<<"   DoubleVecParam "<<setw(35)<<left<<EnumToStringx(this->enum_type)<<" size: "<<this->M<<"\n");
 
 }
@@ -50,13 +48,7 @@
 /*FUNCTION DoubleVecParam::DeepEcho{{{*/
 void DoubleVecParam::DeepEcho(void){
-
-	int i;
-
-	_printf_("DoubleVecParam:\n");
-	_printf_("   enum: " << this->enum_type << " (" << EnumToStringx(this->enum_type) << ")\n");
-	_printf_("   vector size: " << this->M << "\n");
-	for(i=0;i<this->M;i++){
-		_printf_(i << " " << this->values[i] << "\n");
-	}
+	_printf_(setw(22)<<"   DoubleVecParam "<<setw(35)<<left<<EnumToStringx(this->enum_type)<<" "<<"[");
+	for(int i=0;i<this->M;i++) _printf_(" "<< this->values[i]);
+	_printf_("\n");
 }
 /*}}}*/
Index: /issm/trunk/src/c/classes/Params/FileParam.cpp
===================================================================
--- /issm/trunk/src/c/classes/Params/FileParam.cpp	(revision 17805)
+++ /issm/trunk/src/c/classes/Params/FileParam.cpp	(revision 17806)
@@ -43,7 +43,5 @@
 void FileParam::DeepEcho(void){
 
-	_printf_("FileParam:\n");
-	_printf_("   enum:  " << this->enum_type << " (" << EnumToStringx(this->enum_type) << ")\n");
-	_printf_("   value: " << this->value << "\n");
+	_printf_(setw(22)<<"   FileParam "<<setw(35)<<left<<EnumToStringx(this->enum_type)<<" "<<this->value<<"\n");
 }
 /*}}}*/
Index: /issm/trunk/src/c/classes/Params/IntParam.cpp
===================================================================
--- /issm/trunk/src/c/classes/Params/IntParam.cpp	(revision 17805)
+++ /issm/trunk/src/c/classes/Params/IntParam.cpp	(revision 17806)
@@ -43,7 +43,5 @@
 void IntParam::DeepEcho(void){
 
-	_printf_("IntParam:\n");
-	_printf_("   enum:  " << this->enum_type << " (" << EnumToStringx(this->enum_type) << ")\n");
-	_printf_("   value: " << this->value << "\n");
+	_printf_(setw(22)<<"   IntParam "<<setw(35)<<left<<EnumToStringx(this->enum_type)<<" "<<this->value<<"\n");
 }
 /*}}}*/
Index: /issm/trunk/src/c/classes/Params/Parameters.cpp
===================================================================
--- /issm/trunk/src/c/classes/Params/Parameters.cpp	(revision 17805)
+++ /issm/trunk/src/c/classes/Params/Parameters.cpp	(revision 17806)
@@ -21,4 +21,5 @@
 #include "./BoolParam.h"
 #include "./DoubleMatParam.h"
+#include "./DataSetParam.h"
 #include "./DoubleParam.h"
 #include "./DoubleVecParam.h"
@@ -472,4 +473,16 @@
 	if(param) param->SetValue(fid); //already exists, just set it.
 	else this->AddObject(new FileParam(enum_type,fid)); //just add the new parameter.
+}
+/*}}}*/
+/*FUNCTION Parameters::SetParam(DataSet* dataset, int enum_type);{{{*/
+void   Parameters::SetParam(DataSet* dataset,int enum_type){
+
+	Param* param=NULL;
+
+	/*first, figure out if the param has already been created: */
+	param=dynamic_cast<Param*>(this->FindParamObject(enum_type));
+
+	if(param) param->SetValue(dataset); //already exists, just set it.
+	else this->AddObject(new DataSetParam(enum_type,dataset)); //just add the new parameter.
 }
 /*}}}*/
Index: /issm/trunk/src/c/classes/Params/Parameters.h
===================================================================
--- /issm/trunk/src/c/classes/Params/Parameters.h	(revision 17805)
+++ /issm/trunk/src/c/classes/Params/Parameters.h	(revision 17806)
@@ -52,4 +52,5 @@
 		void  SetParam(Matrix<IssmDouble>* mat,int enum_type);
 		void  SetParam(FILE* fid,int enum_type);
+		void  SetParam(DataSet* dataset,int enum_type);
 
 		Object* FindParamObject(int enum_type);
Index: /issm/trunk/src/c/classes/Params/StringArrayParam.cpp
===================================================================
--- /issm/trunk/src/c/classes/Params/StringArrayParam.cpp	(revision 17805)
+++ /issm/trunk/src/c/classes/Params/StringArrayParam.cpp	(revision 17806)
@@ -67,13 +67,7 @@
 void StringArrayParam::DeepEcho(void){
 
-	int i;
-	char* string=NULL;
-
-	_printf_("StringArrayParam:\n");
-	_printf_("   enum: " << this->enum_type << " (" << EnumToStringx(this->enum_type) << ")\n");
-	for(i=0;i<this->numstrings;i++){
-		string=this->value[i];
-		_printf_("   " << i << ": " << string << "\n");
-	}
+	_printf_(setw(22)<<"   StringArrayParam "<<setw(35)<<left<<EnumToStringx(this->enum_type)<<" {");
+	for(int i=0;i<this->numstrings;i++) _printf_(" '"<<this->value[i]<<"'");
+	_printf_("}\n");
 }
 /*}}}*/
Index: /issm/trunk/src/c/classes/Params/StringParam.cpp
===================================================================
--- /issm/trunk/src/c/classes/Params/StringParam.cpp	(revision 17805)
+++ /issm/trunk/src/c/classes/Params/StringParam.cpp	(revision 17806)
@@ -44,7 +44,5 @@
 /*FUNCTION StringParam::DeepEcho{{{*/
 void StringParam::DeepEcho(void){
-	_printf_("StringParam:\n");
-	_printf_("   enum:  " << this->enum_type << " (" << EnumToStringx(this->enum_type) << ")\n");
-	_printf_("   value: " << this->value << "\n");
+	_printf_(setw(22)<<"   StringParam "<<setw(35)<<left<<EnumToStringx(this->enum_type)<<" "<<this->value<<"\n");
 }
 /*}}}*/
Index: /issm/trunk/src/c/classes/Update.h
===================================================================
--- /issm/trunk/src/c/classes/Update.h	(revision 17805)
+++ /issm/trunk/src/c/classes/Update.h	(revision 17806)
@@ -22,5 +22,4 @@
 		virtual void  InputUpdateFromConstant(int constant, int name)=0;
 		virtual void  InputUpdateFromConstant(bool constant, int name)=0;
-		virtual void  InputUpdateFromSolution(IssmDouble* solution)=0;
 		virtual void  InputUpdateFromIoModel(int index, IoModel* iomodel)=0;
 
Index: /issm/trunk/src/c/classes/Vertex.cpp
===================================================================
--- /issm/trunk/src/c/classes/Vertex.cpp	(revision 17805)
+++ /issm/trunk/src/c/classes/Vertex.cpp	(revision 17806)
@@ -32,14 +32,14 @@
 	this->y            = iomodel->Data(MeshYEnum)[i];
 	this->z            = iomodel->Data(MeshZEnum)[i];
-	this->meshtype     = iomodel->meshtype;
-
-	_assert_(iomodel->Data(BedEnum) && iomodel->Data(ThicknessEnum) && iomodel->numbernodetoelementconnectivity);
-	switch(iomodel->meshtype){
-		case Mesh3DEnum:
-		case Mesh2DhorizontalEnum:
-			this->sigma = (iomodel->Data(MeshZEnum)[i]-iomodel->Data(BedEnum)[i])/(iomodel->Data(ThicknessEnum)[i]);
+	this->domaintype     = iomodel->domaintype;
+
+	_assert_(iomodel->Data(BaseEnum) && iomodel->Data(ThicknessEnum) && iomodel->numbernodetoelementconnectivity);
+	switch(iomodel->domaintype){
+		case Domain3DEnum:
+		case Domain2DhorizontalEnum:
+			this->sigma = (iomodel->Data(MeshZEnum)[i]-iomodel->Data(BaseEnum)[i])/(iomodel->Data(ThicknessEnum)[i]);
 			break;
-		case Mesh2DverticalEnum:
-			this->sigma = (iomodel->Data(MeshYEnum)[i]-iomodel->Data(BedEnum)[i])/(iomodel->Data(ThicknessEnum)[i]);
+		case Domain2DverticalEnum:
+			this->sigma = (iomodel->Data(MeshYEnum)[i]-iomodel->Data(BaseEnum)[i])/(iomodel->Data(ThicknessEnum)[i]);
 			break;
 	}
@@ -132,17 +132,24 @@
 
 	/*sigma remains constant. z=bed+sigma*thickness*/
-	if(this->meshtype==Mesh2DverticalEnum){
-		oldy = this->y;
-		newy = bed[this->pid]+sigma*(surface[this->pid] - bed[this->pid]);
-		vely = (newy-oldy)/dt;
-		this->y = newy;
-		vy->SetValue(this->pid,vely,INS_VAL);
-	}
-	else{
-		oldz = this->z;
-		newz = bed[this->pid]+sigma*(surface[this->pid] - bed[this->pid]);
-		velz = (newz-oldz)/dt;
-		this->z = newz;
-		vz->SetValue(this->pid,velz,INS_VAL);
+	switch(this->domaintype){
+		case Domain2DhorizontalEnum:
+			/*Nothing*/
+			return;
+		case Domain2DverticalEnum:
+			oldy = this->y;
+			newy = bed[this->pid]+sigma*(surface[this->pid] - bed[this->pid]);
+			vely = (newy-oldy)/dt;
+			this->y = newy;
+			vy->SetValue(this->pid,vely,INS_VAL);
+			return;
+		case Domain3DEnum:
+			oldz = this->z;
+			newz = bed[this->pid]+sigma*(surface[this->pid] - bed[this->pid]);
+			velz = (newz-oldz)/dt;
+			this->z = newz;
+			vz->SetValue(this->pid,velz,INS_VAL);
+			return;
+		default:
+			_error_("not implemented");
 	}
 }
Index: /issm/trunk/src/c/classes/Vertex.h
===================================================================
--- /issm/trunk/src/c/classes/Vertex.h	(revision 17805)
+++ /issm/trunk/src/c/classes/Vertex.h	(revision 17806)
@@ -21,5 +21,5 @@
 	public: 
 		bool       clone;
-		int        meshtype;
+		int        domaintype;
 		int        id;           // random index
 		int        sid;          // "serial" id (rank of this vertex if the dataset was on 1 cpu)
Index: /issm/trunk/src/c/classes/classes.h
===================================================================
--- /issm/trunk/src/c/classes/classes.h	(revision 17805)
+++ /issm/trunk/src/c/classes/classes.h	(revision 17806)
@@ -18,4 +18,5 @@
 #include "./Segment.h"
 #include "./Massfluxatgate.h"
+#include "./Misfit.h"
 
 /*Constraints: */
@@ -44,4 +45,6 @@
 #include "./Elements/Tria.h"
 #include "./Elements/TriaRef.h"
+#include "./Elements/Tetra.h"
+#include "./Elements/TetraRef.h"
 #include "./Elements/ElementHook.h"
 
@@ -58,4 +61,5 @@
 #include "./Inputs/DoubleInput.h"
 #include "./Inputs/IntInput.h"
+#include "./Inputs/TetraInput.h"
 #include "./Inputs/PentaInput.h"
 #include "./Inputs/TriaInput.h"
Index: /issm/trunk/src/c/classes/gauss/Gauss.h
===================================================================
--- /issm/trunk/src/c/classes/gauss/Gauss.h	(revision 17806)
+++ /issm/trunk/src/c/classes/gauss/Gauss.h	(revision 17806)
@@ -0,0 +1,24 @@
+/*!\file Gauss.h
+ * \brief: header file for vvirtual Gauss object
+ */
+
+#ifndef _GAUSS_H_
+#define _GAUSS_H_
+
+class Gauss{
+
+	public: 
+		IssmDouble   weight;
+
+		virtual        ~Gauss(){};
+		virtual int  begin(void)=0;
+		virtual int  end(void)=0;
+		virtual void Echo(void)=0;
+		virtual int  Enum(void)=0;
+		virtual void GaussPoint(int ig)=0;
+		virtual void GaussVertex(int iv)=0;
+		virtual void GaussNode(int finitelement,int iv)=0;
+		virtual void SynchronizeGaussBase(Gauss* gauss)=0;
+
+};
+#endif
Index: /issm/trunk/src/c/classes/gauss/GaussPenta.cpp
===================================================================
--- /issm/trunk/src/c/classes/gauss/GaussPenta.cpp	(revision 17805)
+++ /issm/trunk/src/c/classes/gauss/GaussPenta.cpp	(revision 17806)
@@ -495,4 +495,9 @@
 }
 /*}}}*/
+/*FUNCTION GaussPenta::Enum{{{*/
+int GaussPenta::Enum(void){
+	return GaussPentaEnum;
+}
+/*}}}*/
 /*FUNCTION GaussPenta::GaussPoint{{{*/
 void GaussPenta::GaussPoint(int ig){
@@ -582,4 +587,22 @@
 			}
 			break;
+		case P1xP3Enum: 
+			switch(iv){
+				case 0 : coord1=1.; coord2=0.; coord3=0.; coord4=-1.; break;
+				case 1 : coord1=0.; coord2=1.; coord3=0.; coord4=-1.; break;
+				case 2 : coord1=0.; coord2=0.; coord3=1.; coord4=-1.; break;
+				case 3 : coord1=1.; coord2=0.; coord3=0.; coord4=+1.; break;
+				case 4 : coord1=0.; coord2=1.; coord3=0.; coord4=+1.; break;
+				case 5 : coord1=0.; coord2=0.; coord3=1.; coord4=+1.; break;
+
+				case 6 : coord1=1.; coord2=0.; coord3=0.; coord4=-1./3.; break;
+				case 7 : coord1=0.; coord2=1.; coord3=0.; coord4=-1./3.; break;
+				case 8 : coord1=0.; coord2=0.; coord3=1.; coord4=-1./3.; break;
+				case 9 : coord1=1.; coord2=0.; coord3=0.; coord4=+1./3.; break;
+				case 10: coord1=0.; coord2=1.; coord3=0.; coord4=+1./3.; break;
+				case 11: coord1=0.; coord2=0.; coord3=1.; coord4=+1./3.; break;
+				default: _error_("node index should be in [0 11]");
+			}
+			break;
 		case P2xP1Enum: 
 			switch(iv){
@@ -631,5 +654,48 @@
 				case 13: coord1=.5; coord2=0.; coord3=.5; coord4=+1.;break;
 				case 14: coord1=.5; coord2=.5; coord3=0.; coord4=+1.;break;
-				default: _error_("node index should be in [0 14]");
+
+				case 15: coord1=0.; coord2=.5; coord3=.5; coord4=0.;break;
+				case 16: coord1=.5; coord2=0.; coord3=.5; coord4=0.;break;
+				case 17: coord1=.5; coord2=.5; coord3=0.; coord4=0.;break;
+				default: _error_("node index should be in [0 17]");
+			}
+			break;
+		case P2xP4Enum:
+			switch(iv){
+				case 0: coord1=1.; coord2=0.; coord3=0.; coord4=-1.; break;
+				case 1: coord1=0.; coord2=1.; coord3=0.; coord4=-1.; break;
+				case 2: coord1=0.; coord2=0.; coord3=1.; coord4=-1.; break;
+				case 3: coord1=1.; coord2=0.; coord3=0.; coord4=+1.; break;
+				case 4: coord1=0.; coord2=1.; coord3=0.; coord4=+1.; break;
+				case 5: coord1=0.; coord2=0.; coord3=1.; coord4=+1.; break;
+
+				case 6: coord1=1.; coord2=0.; coord3=0.; coord4=0.; break;
+				case 7: coord1=0.; coord2=1.; coord3=0.; coord4=0.; break;
+				case 8: coord1=0.; coord2=0.; coord3=1.; coord4=0.; break;
+
+				case  9: coord1=0.; coord2=.5; coord3=.5; coord4=-1.;break;
+				case 10: coord1=.5; coord2=0.; coord3=.5; coord4=-1.;break;
+				case 11: coord1=.5; coord2=.5; coord3=0.; coord4=-1.;break;
+				case 12: coord1=0.; coord2=.5; coord3=.5; coord4=+1.;break;
+				case 13: coord1=.5; coord2=0.; coord3=.5; coord4=+1.;break;
+				case 14: coord1=.5; coord2=.5; coord3=0.; coord4=+1.;break;
+
+				case 15: coord1=1.; coord2=0.; coord3=0.; coord4=-.5; break;
+				case 16: coord1=0.; coord2=1.; coord3=0.; coord4=-.5; break;
+				case 17: coord1=0.; coord2=0.; coord3=1.; coord4=-.5; break;
+				case 18: coord1=1.; coord2=0.; coord3=0.; coord4=+.5; break;
+				case 19: coord1=0.; coord2=1.; coord3=0.; coord4=+.5; break;
+				case 20: coord1=0.; coord2=0.; coord3=1.; coord4=+.5; break;
+
+				case 21: coord1=0.; coord2=.5; coord3=.5; coord4=-.5;break;
+				case 22: coord1=.5; coord2=0.; coord3=.5; coord4=-.5;break;
+				case 23: coord1=.5; coord2=.5; coord3=0.; coord4=-.5;break;
+				case 24: coord1=0.; coord2=.5; coord3=.5; coord4=0.;break;
+				case 25: coord1=.5; coord2=0.; coord3=.5; coord4=0.;break;
+				case 26: coord1=.5; coord2=.5; coord3=0.; coord4=0.;break;
+				case 27: coord1=0.; coord2=.5; coord3=.5; coord4=+.5;break;
+				case 28: coord1=.5; coord2=0.; coord3=.5; coord4=+.5;break;
+				case 29: coord1=.5; coord2=.5; coord3=0.; coord4=+.5;break;
+				default: _error_("node index should be in [0 29]");
 			}
 			break;
@@ -669,6 +735,9 @@
 }
 /*}}}*/
-/*FUNCTION GaussPenta::SynchronizeGaussTria{{{*/
-void GaussPenta::SynchronizeGaussTria(GaussTria* gauss_tria){
+/*FUNCTION GaussPenta::SynchronizeGaussBase{{{*/
+void GaussPenta::SynchronizeGaussBase(Gauss* gauss){
+
+	_assert_(gauss->Enum()==GaussTriaEnum);
+	GaussTria* gauss_tria = dynamic_cast<GaussTria*>(gauss);
 
 	gauss_tria->coord1=this->coord1;
Index: /issm/trunk/src/c/classes/gauss/GaussPenta.h
===================================================================
--- /issm/trunk/src/c/classes/gauss/GaussPenta.h	(revision 17805)
+++ /issm/trunk/src/c/classes/gauss/GaussPenta.h	(revision 17806)
@@ -8,7 +8,8 @@
 /*Headers:*/
 #include "../../shared/Numerics/types.h"
+#include "./Gauss.h"
 class GaussTria;
 
-class GaussPenta{
+class GaussPenta: public Gauss{
 
 	private:
@@ -21,5 +22,4 @@
 
 	public:
-		IssmDouble weight;
 		IssmDouble coord1;
 		IssmDouble coord2;
@@ -43,9 +43,10 @@
 		int  end(void);
 		void Echo(void);
+		int  Enum(void);
 		void GaussPoint(int ig);
 		void GaussVertex(int iv);
 		void GaussNode(int finitelement,int iv);
 		void GaussFaceTria(int index1, int index2, int index3, int order);
-		void SynchronizeGaussTria(GaussTria* gauss_tria);
+		void SynchronizeGaussBase(Gauss* gauss);
 };
 #endif
Index: /issm/trunk/src/c/classes/gauss/GaussSeg.cpp
===================================================================
--- /issm/trunk/src/c/classes/gauss/GaussSeg.cpp	(revision 17805)
+++ /issm/trunk/src/c/classes/gauss/GaussSeg.cpp	(revision 17806)
@@ -12,4 +12,16 @@
 
 /*GaussSeg constructors and destructors:*/
+/*FUNCTION GaussSeg::GaussSeg() {{{*/
+GaussSeg::GaussSeg(){
+
+	numgauss=-1;
+
+	weights=NULL;
+	coords1=NULL;
+
+	weight=UNDEF;
+	coord1=UNDEF;
+}
+/*}}}*/
 /*FUNCTION GaussSeg::GaussSeg(int order) {{{*/
 GaussSeg::GaussSeg(int order){
@@ -34,4 +46,22 @@
 	xDelete<IssmPDouble>(pcoords1);
 	xDelete<IssmPDouble>(pweights);
+
+	/*Initialize static fields as undefinite*/
+	weight=UNDEF;
+	coord1=UNDEF;
+}
+/*}}}*/
+/*FUNCTION GaussSeg::GaussSeg(IssmDouble position) {{{*/
+GaussSeg::GaussSeg(IssmDouble position){
+
+	/*Get gauss points*/
+	this->numgauss = 1;
+	this->coords1=xNew<IssmDouble>(numgauss);
+	this->weights=xNew<IssmDouble>(numgauss);
+
+	/*cast : */
+	_assert_(position>=-1. && position<=+1.);
+	this->coords1[0]=position;
+	this->weights[0]=1.;
 
 	/*Initialize static fields as undefinite*/
@@ -70,4 +100,9 @@
 }
 /*}}}*/
+/*FUNCTION GaussSeg::Enum{{{*/
+int GaussSeg::Enum(void){
+	return GaussSegEnum;
+}
+/*}}}*/
 /*FUNCTION GaussSeg::GaussPoint{{{*/
 void GaussSeg::GaussPoint(int ig){
@@ -79,4 +114,38 @@
 	 weight=weights[ig];
 	 coord1=coords1[ig];
+}
+/*}}}*/
+/*FUNCTION GaussSeg::GaussVertex{{{*/
+void GaussSeg::GaussVertex(int iv){
+
+	/*in debugging mode: check that the default constructor has been called*/
+	_assert_(numgauss==-1);
+
+	/*update static arrays*/
+	switch(iv){
+		case 0: coord1=-1.; break;
+		case 1: coord1=+1.; break;
+		default: _error_("vertex index should be in [0 1]");
+	}
+}
+/*}}}*/
+/*FUNCTION GaussSeg::GaussNode{{{*/
+void GaussSeg::GaussNode(int finiteelement,int iv){
+
+	/*in debugging mode: check that the default constructor has been called*/
+	_assert_(numgauss==-1);
+
+	/*update static arrays*/
+	switch(finiteelement){
+		case P1Enum: case P1DGEnum:
+			switch(iv){
+				case 0: coord1=-1.; break;
+				case 1: coord1=+1.; break;
+				default: _error_("node index should be in [0 1]");
+			}
+			break;
+		default: _error_("Finite element "<<EnumToStringx(finiteelement)<<" not supported");
+	}
+
 }
 /*}}}*/
@@ -105,2 +174,8 @@
 }
 /*}}}*/
+/*FUNCTION GaussSeg::SynchronizeGaussBase{{{*/
+void GaussSeg::SynchronizeGaussBase(Gauss* gauss){
+
+	_error_("not supported");
+}
+/*}}}*/
Index: /issm/trunk/src/c/classes/gauss/GaussSeg.h
===================================================================
--- /issm/trunk/src/c/classes/gauss/GaussSeg.h	(revision 17805)
+++ /issm/trunk/src/c/classes/gauss/GaussSeg.h	(revision 17806)
@@ -8,6 +8,7 @@
 /*Headers:*/
 #include "../../shared/Numerics/types.h"
+#include "./Gauss.h"
 
-class GaussSeg{
+class GaussSeg: public Gauss{
 
 	private:
@@ -17,5 +18,4 @@
 
 	public:
-		IssmDouble weight;
 		IssmDouble coord1;
 
@@ -23,5 +23,7 @@
 
 		/*GaussSeg constructors, destructors*/
+		GaussSeg();
 		GaussSeg(int order);
+		GaussSeg(IssmDouble position);
 		~GaussSeg();
 
@@ -30,5 +32,9 @@
 		int  end(void);
 		void Echo(void);
+		int  Enum(void);
 		void GaussPoint(int ig);
+		void GaussVertex(int iv);
+		void GaussNode(int finitelement,int iv);
+		void SynchronizeGaussBase(Gauss* gauss);
 };
 #endif
Index: /issm/trunk/src/c/classes/gauss/GaussTetra.cpp
===================================================================
--- /issm/trunk/src/c/classes/gauss/GaussTetra.cpp	(revision 17806)
+++ /issm/trunk/src/c/classes/gauss/GaussTetra.cpp	(revision 17806)
@@ -0,0 +1,252 @@
+/*!\file GaussTetra.c
+ * \brief: implementation of the GaussTetra object
+ */
+
+#include <math.h>
+#include "./GaussTetra.h"
+#include "../../shared/io/Print/Print.h"
+#include "../../shared/Exceptions/exceptions.h"
+#include "../../shared/MemOps/MemOps.h"
+#include "../../shared/Enum/Enum.h"
+#include "../../shared/Numerics/GaussPoints.h"
+#include "../../shared/Numerics/constants.h"
+
+/*GaussTetra constructors and destructors:*/
+/*FUNCTION GaussTetra::GaussTetra() {{{*/
+GaussTetra::GaussTetra(){
+
+	numgauss=-1;
+
+	weights=NULL;
+	coords1=NULL;
+	coords2=NULL;
+	coords3=NULL;
+	coords4=NULL;
+
+	weight=UNDEF;
+	coord1=UNDEF;
+	coord2=UNDEF;
+	coord3=UNDEF;
+	coord4=UNDEF;
+}
+/*}}}*/
+/*FUNCTION GaussTetra::GaussTetra(int order) {{{*/
+GaussTetra::GaussTetra(int order){
+	/*Get gauss points*/
+	GaussLegendreTetra(&numgauss,&coords1,&coords2,&coords3,&coords4,&weights,order);
+	for(int i=0;i<numgauss;i++) this->weights[i]=this->weights[i]/6.; //FIXME: double check that
+
+	/*Initialize static fields as undefinite*/
+	weight=UNDEF;
+	coord1=UNDEF;
+	coord2=UNDEF;
+	coord3=UNDEF;
+}
+/*}}}*/
+/*FUNCTION GaussTetra::GaussTetra(int index1,int index2,int index3,int order) {{{*/
+GaussTetra::GaussTetra(int index1,int index2,int index3,int order){
+
+	/*Basal Tria*/
+	if(index1==0 && index2==1 && index3==2){
+		GaussLegendreTria(&numgauss,&coords1,&coords2,&coords3,&weights,order);
+		coords4=xNew<IssmDouble>(numgauss);
+		for(int i=0;i<numgauss;i++) coords4[i]=0.;
+	}
+	else if(index1==0 && index2==3 && index3==1){
+		GaussLegendreTria(&numgauss,&coords1,&coords2,&coords4,&weights,order);
+		coords3=xNew<IssmDouble>(numgauss);
+		for(int i=0;i<numgauss;i++) coords3[i]=0.;
+	}
+	else if(index1==1 && index2==3 && index3==2){
+		GaussLegendreTria(&numgauss,&coords2,&coords3,&coords4,&weights,order);
+		coords1=xNew<IssmDouble>(numgauss);
+		for(int i=0;i<numgauss;i++) coords1[i]=0.;
+	}
+	else if(index1==0 && index2==2 && index3==3){
+		GaussLegendreTria(&numgauss,&coords1,&coords3,&coords4,&weights,order);
+		coords2=xNew<IssmDouble>(numgauss);
+		for(int i=0;i<numgauss;i++) coords2[i]=0.;
+	}
+	else{
+		_error_(index1 <<" "<<index2 <<" "<<index3 <<" Not supported yet");
+	}
+}
+/*}}}*/
+/*FUNCTION GaussTetra::~GaussTetra(){{{*/
+GaussTetra::~GaussTetra(){
+	xDelete<IssmDouble>(weights);
+	xDelete<IssmDouble>(coords1);
+	xDelete<IssmDouble>(coords2);
+	xDelete<IssmDouble>(coords3);
+	xDelete<IssmDouble>(coords4);
+}
+/*}}}*/
+
+/*Methods*/
+/*FUNCTION GaussTetra::Echo{{{*/
+void GaussTetra::Echo(void){
+
+	_printf_("GaussTetra:\n");
+	_printf_("   numgauss: " << numgauss << "\n");
+
+	if (weights){
+	 _printf_("   weights = ["); 
+	 for(int i=0;i<numgauss;i++) _printf_(" " << weights[i] << "\n");
+	 _printf_("]\n");
+	}
+	else _printf_("weights = NULL\n");
+	if (coords1){
+	 _printf_("   coords1 = ["); 
+	 for(int i=0;i<numgauss;i++) _printf_(" " << coords1[i] << "\n");
+	 _printf_("]\n");
+	}
+	else _printf_("coords1 = NULL\n");
+	if (coords2){
+	 _printf_("   coords2 = ["); 
+	 for(int i=0;i<numgauss;i++) _printf_(" " << coords2[i] << "\n");
+	 _printf_("]\n");
+	}
+	else _printf_("coords2 = NULL\n");
+	if (coords3){
+	 _printf_("   coords3 = ["); 
+	 for(int i=0;i<numgauss;i++) _printf_(" " << coords3[i] << "\n");
+	 _printf_("]\n");
+	}
+	else _printf_("coords3 = NULL\n");
+	if (coords4){
+		_printf_("   coords4 = ["); 
+		for(int i=0;i<numgauss;i++) _printf_(" " << coords4[i] << "\n");
+		_printf_("]\n");
+	}
+	else _printf_("coords4 = NULL\n");
+
+	_printf_("   weight = " << weight << "\n");
+	_printf_("   coord1 = " << coord1 << "\n");
+	_printf_("   coord2 = " << coord2 << "\n");
+	_printf_("   coord3 = " << coord3 << "\n");
+	_printf_("   coord4 = " << coord4 << "\n");
+
+}
+/*}}}*/
+/*FUNCTION GaussTetra::Enum{{{*/
+int GaussTetra::Enum(void){
+	return GaussTetraEnum;
+}
+/*}}}*/
+/*FUNCTION GaussTetra::GaussPoint{{{*/
+void GaussTetra::GaussPoint(int ig){
+
+	/*Check input in debugging mode*/
+	 _assert_(ig>=0 && ig< numgauss);
+
+	 /*update static arrays*/
+	 weight=weights[ig];
+	 coord1=coords1[ig];
+	 coord2=coords2[ig];
+	 coord3=coords3[ig];
+	 coord4=coords4[ig];
+
+}
+/*}}}*/
+/*FUNCTION GaussTetra::GaussVertex{{{*/
+void GaussTetra::GaussVertex(int iv){
+
+	/*in debugging mode: check that the default constructor has been called*/
+	_assert_(numgauss==-1);
+
+	/*update static arrays*/
+	switch(iv){
+		case 0: coord1=1.; coord2=0.; coord3=0.; coord4=0.; break;
+		case 1: coord1=0.; coord2=1.; coord3=0.; coord4=0.; break;
+		case 2: coord1=0.; coord2=0.; coord3=1.; coord4=0.; break;
+		case 3: coord1=0.; coord2=0.; coord3=0.; coord4=1.; break;
+		default: _error_("vertex index should be in [0 3]");
+
+	}
+
+}
+/*}}}*/
+/*FUNCTION GaussTetra::GaussNode{{{*/
+void GaussTetra::GaussNode(int finiteelement,int iv){
+
+	/*in debugging mode: check that the default constructor has been called*/
+	_assert_(numgauss==-1);
+
+	/*update static arrays*/
+	switch(finiteelement){
+		case P1Enum: case P1DGEnum:
+			switch(iv){
+				case 0: coord1=1.; coord2=0.; coord3=0.; coord4=0.; break;
+				case 1: coord1=0.; coord2=1.; coord3=0.; coord4=0.; break;
+				case 2: coord1=0.; coord2=0.; coord3=1.; coord4=0.; break;
+				case 3: coord1=0.; coord2=0.; coord3=0.; coord4=1.; break;
+				default: _error_("node index should be in [0 3]");
+			}
+			break;
+		case P1bubbleEnum: case P1bubblecondensedEnum:
+			switch(iv){
+				case 0: coord1=1.; coord2=0.; coord3=0.; coord4=0.; break;
+				case 1: coord1=0.; coord2=1.; coord3=0.; coord4=0.; break;
+				case 2: coord1=0.; coord2=0.; coord3=1.; coord4=0.; break;
+				case 3: coord1=0.; coord2=0.; coord3=0.; coord4=1.; break;
+				case 4: coord1=1./4.; coord2=1./4.; coord3=1./4.; coord4=1./4.; break;
+				default: _error_("node index should be in [0 4]");
+			}
+			break;
+		case P2Enum:
+			switch(iv){
+				case 0: coord1=1.; coord2=0.; coord3=0.; coord4=0.; break;
+				case 1: coord1=0.; coord2=1.; coord3=0.; coord4=0.; break;
+				case 2: coord1=0.; coord2=0.; coord3=1.; coord4=0.; break;
+				case 3: coord1=0.; coord2=0.; coord3=0.; coord4=1.; break;
+
+				case 4: coord1=0.; coord2=.5; coord3=.5; coord4=0.; break;
+				case 5: coord1=.5; coord2=0.; coord3=.5; coord4=0.; break;
+				case 6: coord1=.5; coord2=.5; coord3=0.; coord4=0.; break;
+				case 7: coord1=.5; coord2=0.; coord3=0.; coord4=.5; break;
+				case 8: coord1=0.; coord2=.5; coord3=0.; coord4=.5; break;
+				case 9: coord1=0.; coord2=0.; coord3=.5; coord4=.5; break;
+				default: _error_("node index should be in [0 9]");
+			}
+			break;
+		default: _error_("Finite element "<<EnumToStringx(finiteelement)<<" not supported");
+	}
+
+}
+/*}}}*/
+/*FUNCTION GaussTetra::begin{{{*/
+int GaussTetra::begin(void){
+
+	/*Check that this has been initialized*/
+	_assert_(numgauss>0);
+	_assert_(weights);
+	_assert_(coords1);
+	_assert_(coords2);
+	_assert_(coords3);
+	_assert_(coords4);
+
+	/*return first gauss index*/
+	return 0;
+}
+/*}}}*/
+/*FUNCTION GaussTetra::end{{{*/
+int GaussTetra::end(void){
+
+	/*Check that this has been initialized*/
+	_assert_(numgauss>0);
+	_assert_(weights);
+	_assert_(coords1);
+	_assert_(coords2);
+	_assert_(coords3);
+	_assert_(coords4);
+
+	/*return last gauss index +1*/
+	return numgauss;
+}
+/*}}}*/
+/*FUNCTION GaussTetra::SynchronizeGaussBase{{{*/
+void GaussTetra::SynchronizeGaussBase(Gauss* gauss){
+
+	_error_("not supported");
+}
+/*}}}*/
Index: /issm/trunk/src/c/classes/gauss/GaussTetra.h
===================================================================
--- /issm/trunk/src/c/classes/gauss/GaussTetra.h	(revision 17806)
+++ /issm/trunk/src/c/classes/gauss/GaussTetra.h	(revision 17806)
@@ -0,0 +1,46 @@
+/*!\file GaussTetra.h
+ * \brief: header file for node object
+ */
+
+#ifndef _GAUSSTETRA_H_
+#define _GAUSSTETRA_H_
+
+/*Headers:*/
+#include "../../shared/Numerics/types.h"
+#include "./Gauss.h"
+
+class GaussTetra: public Gauss{
+
+	private:
+		int numgauss;
+		IssmDouble* weights;
+		IssmDouble* coords1;
+		IssmDouble* coords2;
+		IssmDouble* coords3;
+		IssmDouble* coords4;
+
+	public:
+		IssmDouble coord1;
+		IssmDouble coord2;
+		IssmDouble coord3;
+		IssmDouble coord4;
+
+	public:
+
+		/*GaussTetra constructors, destructors*/
+		GaussTetra();
+		GaussTetra(int order);
+		GaussTetra(int index1,int index2,int index3,int order);
+		~GaussTetra();
+
+		/*Methods*/
+		int  begin(void);
+		int  end(void);
+		void Echo(void);
+		int  Enum(void);
+		void GaussPoint(int ig);
+		void GaussVertex(int iv);
+		void GaussNode(int finitelement,int iv);
+		void SynchronizeGaussBase(Gauss* gauss);
+};
+#endif
Index: /issm/trunk/src/c/classes/gauss/GaussTria.cpp
===================================================================
--- /issm/trunk/src/c/classes/gauss/GaussTria.cpp	(revision 17805)
+++ /issm/trunk/src/c/classes/gauss/GaussTria.cpp	(revision 17806)
@@ -339,4 +339,9 @@
 	_printf_("   coord3 = " << coord3 << "\n");
 
+}
+/*}}}*/
+/*FUNCTION GaussTria::Enum{{{*/
+int GaussTria::Enum(void){
+	return GaussTriaEnum;
 }
 /*}}}*/
@@ -498,2 +503,8 @@
 }
 /*}}}*/
+/*FUNCTION GaussTria::SynchronizeGaussBase{{{*/
+void GaussTria::SynchronizeGaussBase(Gauss* gauss){
+
+	_error_("not supported");
+}
+/*}}}*/
Index: /issm/trunk/src/c/classes/gauss/GaussTria.h
===================================================================
--- /issm/trunk/src/c/classes/gauss/GaussTria.h	(revision 17805)
+++ /issm/trunk/src/c/classes/gauss/GaussTria.h	(revision 17806)
@@ -8,6 +8,7 @@
 /*Headers:*/
 #include "../../shared/Numerics/types.h"
+#include "./Gauss.h"
 
-class GaussTria{
+class GaussTria: public Gauss{
 
 	private:
@@ -19,5 +20,4 @@
 
 	public:
-		IssmDouble weight;
 		IssmDouble coord1;
 		IssmDouble coord2;
@@ -38,4 +38,5 @@
 		int  end(void);
 		void Echo(void);
+		int  Enum(void);
 		void GaussFromCoords(IssmDouble x1,IssmDouble y1,IssmDouble* xyz_list);
 		void GaussPoint(int ig);
@@ -43,4 +44,5 @@
 		void GaussNode(int finitelement,int iv);
 		void GaussEdgeCenter(int index1,int index2);
+		void SynchronizeGaussBase(Gauss* gauss);
 };
 #endif  /* _GAUSSTRIA_H_ */
Index: /issm/trunk/src/c/classes/gauss/gaussobjects.h
===================================================================
--- /issm/trunk/src/c/classes/gauss/gaussobjects.h	(revision 17805)
+++ /issm/trunk/src/c/classes/gauss/gaussobjects.h	(revision 17806)
@@ -6,6 +6,8 @@
 #define ALL_GAUSS_OBJECTS_H_
 
+#include "./Gauss.h"
 #include "./GaussSeg.h"
 #include "./GaussTria.h"
+#include "./GaussTetra.h"
 #include "./GaussPenta.h"
 
Index: /issm/trunk/src/c/classes/kriging/Observations.cpp
===================================================================
--- /issm/trunk/src/c/classes/kriging/Observations.cpp	(revision 17805)
+++ /issm/trunk/src/c/classes/kriging/Observations.cpp	(revision 17806)
@@ -158,15 +158,14 @@
 
 	/*Assign output pointer*/
-	if(index>=0){
+	if(nobs || hmin==radius){
 		observation=dynamic_cast<Observation*>(this->GetObjectByOffset(index));
-		*px=observation->x;
-		*py=observation->y;
-		*pobs=observation->value;
+		*px   = observation->x;
+		*py   = observation->y;
+		*pobs = observation->value;
 	}
 	else{
-
-		*px=UNDEF;
-		*py=UNDEF;
-		*pobs=UNDEF;
+		*px   = UNDEF;
+		*py   = UNDEF;
+		*pobs = UNDEF;
 	}
 	xDelete<int>(indices);
@@ -180,8 +179,10 @@
 	for(int i=0;i<n;i++){
 		this->ClosestObservation(&xi,&yi,&obs,x[i],y[i],radius);
-		if(xi==UNDEF && yi==UNDEF)
+		if(xi==UNDEF && yi==UNDEF){
 		 distances[i]=UNDEF;
-		else
+		}
+		else{
 		 distances[i]=sqrt( (x[i]-xi)*(x[i]-xi) + (y[i]-yi)*(y[i]-yi) );
+		}
 	}
 }/*}}}*/
@@ -202,5 +203,5 @@
 
 	/*If radius is not provided or is 0, return all observations*/
-	if(radius==0) radius=this->quadtree->root->length;
+	if(radius==0.) radius=this->quadtree->root->length*2.;
 
 	/*Compute radius square*/
@@ -214,10 +215,10 @@
 	}
 	nobs = 0;
-	for (i=0;i<tempnobs;i++){
+	for(i=0;i<tempnobs;i++){
 		observation=dynamic_cast<Observation*>(this->GetObjectByOffset(tempindices[i]));
 		h2 = (observation->x-x_interp)*(observation->x-x_interp) + (observation->y-y_interp)*(observation->y-y_interp);
 
 		if(nobs==maxdata && h2>radius2) continue;
-		if(nobs<=maxdata){
+		if(nobs<maxdata){
 			indices[nobs]   = tempindices[i];
 			dists[nobs]     = h2;
@@ -256,5 +257,5 @@
 
 		/*Loop over all observations and fill in x, y and obs*/
-		for (i=0;i<nobs;i++){
+		for(i=0;i<nobs;i++){
 			observation=dynamic_cast<Observation*>(this->GetObjectByOffset(indices[i]));
 			observation->WriteXYObs(&x[i],&y[i],&obs[i]);
@@ -353,13 +354,8 @@
 	IssmPDouble   prediction,error;
 	IssmPDouble   numerator,denominator,ratio;
-	IssmPDouble  *x            = NULL;
-	IssmPDouble  *y            = NULL;
-	IssmPDouble  *obs          = NULL;
-	IssmPDouble  *Gamma        = NULL;
-	IssmPDouble  *GinvG0       = NULL;
-	IssmPDouble  *Ginv1        = NULL;
-	IssmPDouble  *GinvZ        = NULL;
-	IssmPDouble  *gamma0       = NULL;
-	IssmPDouble  *ones         = NULL;
+	IssmPDouble  *x      = NULL;
+	IssmPDouble  *y      = NULL;
+	IssmPDouble  *obs    = NULL;
+	IssmPDouble  *Lambda = NULL;
 
 	/*Some checks*/
@@ -381,41 +377,40 @@
 
 	/*Allocate intermediary matrix and vectors*/
-	Gamma  = xNew<IssmPDouble>(n_obs*n_obs);
-	gamma0 = xNew<IssmPDouble>(n_obs);
-	ones   = xNew<IssmPDouble>(n_obs);
-
+	IssmPDouble* A = xNew<IssmPDouble>((n_obs+1)*(n_obs+1));
+	IssmPDouble* B = xNew<IssmPDouble>(n_obs+1);
+
+	IssmDouble unbias = variogram->Covariance(0.,0.);
 	/*First: Create semivariogram matrix for observations*/
 	for(i=0;i<n_obs;i++){
 		for(j=0;j<=i;j++){
-			//Gamma[i*n_obs+j] = variogram->SemiVariogram(x[i]-x[j],y[i]-y[j]);
-			Gamma[i*n_obs+j] = variogram->Covariance(x[i]-x[j],y[i]-y[j]);
-			Gamma[j*n_obs+i] = Gamma[i*n_obs+j];
-		}
-	}
-	for(i=0;i<n_obs;i++) ones[i]=1;
+			A[i*(n_obs+1)+j] = variogram->Covariance(x[i]-x[j],y[i]-y[j]);
+			A[j*(n_obs+1)+i] = A[i*(n_obs+1)+j];
+		}
+		A[i*(n_obs+1)+n_obs] = unbias;
+		//A[i*(n_obs+1)+n_obs] = 1.;
+	}
+	for(i=0;i<n_obs;i++) A[n_obs*(n_obs+1)+i]=unbias;
+	//for(i=0;i<n_obs;i++) A[n_obs*(n_obs+1)+i]=1.;
+	A[n_obs*(n_obs+1)+n_obs] = 0.;
 
 	/*Get semivariogram vector associated to this location*/
-	//for(i=0;i<n_obs;i++) gamma0[i] = variogram->SemiVariogram(x[i]-x_interp,y[i]-y_interp);
-	for(i=0;i<n_obs;i++) gamma0[i] = variogram->Covariance(x[i]-x_interp,y[i]-y_interp);
+	for(i=0;i<n_obs;i++) B[i] = variogram->Covariance(x[i]-x_interp,y[i]-y_interp);
+	B[n_obs] = unbias;
+	//B[n_obs] = 1.;
 
 	/*Solve the three linear systems*/
 #if _HAVE_GSL_
-	DenseGslSolve(&GinvG0,Gamma,gamma0,n_obs); // Gamma^-1 gamma0
-	DenseGslSolve(&Ginv1, Gamma,ones,n_obs);   // Gamma^-1 ones
-	DenseGslSolve(&GinvZ, Gamma,obs,n_obs);    // Gamma^-1 Z
+	DenseGslSolve(&Lambda,A,B,n_obs+1);    // Gamma^-1 Z
 #else
 	_error_("GSL is required");
 #endif
 
-	/*Prepare predictor*/
-	numerator=-1.; denominator=0.;
-	for(i=0;i<n_obs;i++) numerator  +=GinvG0[i];
-	for(i=0;i<n_obs;i++) denominator+=Ginv1[i];
-	ratio=numerator/denominator;
-
+	/*Compute predictor*/
 	prediction = 0.;
-	error      = - numerator*numerator/denominator;
-	for(i=0;i<n_obs;i++) prediction += (gamma0[i]-ratio)*GinvZ[i];
-	for(i=0;i<n_obs;i++) error += gamma0[i]*GinvG0[i];
+	for(i=0;i<n_obs;i++) prediction += Lambda[i]*obs[i];
+
+	/*Compute error (GSLIB p15 eq II.14)*/
+	error = variogram->Covariance(0.,0.)*(1. - Lambda[n_obs]);;
+	for(i=0;i<n_obs;i++) error += -Lambda[i]*B[i];
 
 	/*clean-up*/
@@ -425,10 +420,7 @@
 	xDelete<IssmPDouble>(y);
 	xDelete<IssmPDouble>(obs);
-	xDelete<IssmPDouble>(Gamma);
-	xDelete<IssmPDouble>(gamma0);
-	xDelete<IssmPDouble>(ones);
-	xDelete<IssmPDouble>(GinvG0);
-	xDelete<IssmPDouble>(Ginv1);
-	xDelete<IssmPDouble>(GinvZ);
+	xDelete<IssmPDouble>(A);
+	xDelete<IssmPDouble>(B);
+	xDelete<IssmPDouble>(Lambda);
 
 }/*}}}*/
@@ -465,7 +457,4 @@
 	_assert_(maxdata>0);
 	_assert_(pprediction);
-
-	/*If radius is not provided or is 0, return all observations*/
-	if(radius==0) radius=this->quadtree->root->length;
 
 	/*Get list of observations for current point*/
@@ -505,4 +494,6 @@
 				Green[i*n_obs+j] = Green[j*n_obs+i];
 			}
+			/*Zero diagonal (should be done already, but just in case)*/
+			Green[i*n_obs+i] = 0.;
 		}
 
Index: /issm/trunk/src/c/classes/kriging/Quadtree.cpp
===================================================================
--- /issm/trunk/src/c/classes/kriging/Quadtree.cpp	(revision 17805)
+++ /issm/trunk/src/c/classes/kriging/Quadtree.cpp	(revision 17806)
@@ -237,10 +237,10 @@
 
 		/*We found the closest observation, now average observation (do not change xi and yi to avoid round off errors*/
-		box->obs[index]->x = (box->obs[index]->weight*box->obs[index]->x + x)/(box->obs[index]->weight+1);
-		box->obs[index]->y = (box->obs[index]->weight*box->obs[index]->y + y)/(box->obs[index]->weight+1);
-		box->obs[index]->xi= int((box->obs[index]->weight*double(box->obs[index]->xi) + double(xi))/(box->obs[index]->weight+1));
-		box->obs[index]->yi= int((box->obs[index]->weight*double(box->obs[index]->yi) + double(yi))/(box->obs[index]->weight+1));
-		box->obs[index]->value   = (box->obs[index]->weight*box->obs[index]->value + value)/(box->obs[index]->weight+1);
-		box->obs[index]->weight += 1;
+		box->obs[index]->x = (box->obs[index]->weight*box->obs[index]->x + x)/(box->obs[index]->weight+1.);
+		box->obs[index]->y = (box->obs[index]->weight*box->obs[index]->y + y)/(box->obs[index]->weight+1.);
+		box->obs[index]->xi= int((box->obs[index]->weight*double(box->obs[index]->xi) + double(xi))/(box->obs[index]->weight+1.));
+		box->obs[index]->yi= int((box->obs[index]->weight*double(box->obs[index]->yi) + double(yi))/(box->obs[index]->weight+1.));
+		box->obs[index]->value   = (box->obs[index]->weight*box->obs[index]->value + value)/(box->obs[index]->weight+1.);
+		box->obs[index]->weight += 1.;
 	}
 	else{
Index: /issm/trunk/src/c/classes/matrix/ElementMatrix.cpp
===================================================================
--- /issm/trunk/src/c/classes/matrix/ElementMatrix.cpp	(revision 17805)
+++ /issm/trunk/src/c/classes/matrix/ElementMatrix.cpp	(revision 17806)
@@ -268,7 +268,8 @@
 			for(i=0;i<this->row_fsize;i++){
 				for(j=0;j<this->row_fsize;j++){
-					*(localvalues+this->row_fsize*i+j)=*(this->values+this->ncols*this->row_flocaldoflist[i]+this->row_flocaldoflist[j]);
+					localvalues[this->row_fsize*i+j]=this->values[this->ncols*this->row_flocaldoflist[i]+this->row_flocaldoflist[j]];
 				}
 			}
+
 			/*add local values into global  matrix, using the fglobaldoflist: */
 			Kff->SetValues(this->row_fsize,this->row_fglobaldoflist,this->row_fsize,this->row_fglobaldoflist,localvalues,ADD_VAL);
@@ -283,5 +284,5 @@
 			for(i=0;i<this->row_fsize;i++){
 				for(j=0;j<this->row_ssize;j++){
-					*(localvalues+this->row_ssize*i+j)=*(this->values+this->ncols*this->row_flocaldoflist[i]+this->row_slocaldoflist[j]);
+					localvalues[this->row_ssize*i+j]=this->values[this->ncols*this->row_flocaldoflist[i]+this->row_slocaldoflist[j]];
 				}
 			}
Index: /issm/trunk/src/c/cores/AnalysisConfiguration.cpp
===================================================================
--- /issm/trunk/src/c/cores/AnalysisConfiguration.cpp	(revision 17805)
+++ /issm/trunk/src/c/cores/AnalysisConfiguration.cpp	(revision 17806)
@@ -26,5 +26,5 @@
 
 		case StressbalanceSolutionEnum:
-			numanalyses=4;
+			numanalyses=6;
 			analyses=xNew<int>(numanalyses);
 			analyses[0]=StressbalanceAnalysisEnum;
@@ -32,4 +32,6 @@
 			analyses[2]=StressbalanceSIAAnalysisEnum;
 			analyses[3]=L2ProjectionBaseAnalysisEnum;
+			analyses[4]=ExtrudeFromBaseAnalysisEnum;
+			analyses[5]=DepthAverageAnalysisEnum;
 			break;
 
@@ -55,5 +57,5 @@
 
 		case HydrologySolutionEnum:
-			numanalyses=4;
+			numanalyses=5;
 			analyses=xNew<int>(numanalyses);
 			analyses[0]=HydrologyShreveAnalysisEnum;
@@ -61,4 +63,5 @@
 			analyses[2]=HydrologyDCEfficientAnalysisEnum;
 			analyses[3]=L2ProjectionBaseAnalysisEnum;
+			analyses[4]=L2ProjectionEPLAnalysisEnum;
 			break;
 
@@ -114,5 +117,5 @@
 
 		case TransientSolutionEnum:
-			numanalyses=12;
+			numanalyses=20;
 			analyses=xNew<int>(numanalyses);
 			analyses[ 0]=StressbalanceAnalysisEnum;
@@ -128,4 +131,12 @@
 			analyses[10]=ExtrudeFromBaseAnalysisEnum;
 			analyses[11]=ExtrudeFromTopAnalysisEnum;
+			analyses[12]=LevelsetAnalysisEnum;
+			analyses[13]=ExtrapolationAnalysisEnum;
+			analyses[14]=LsfReinitializationAnalysisEnum;
+			analyses[15]=DamageEvolutionAnalysisEnum;
+			analyses[16]=HydrologyShreveAnalysisEnum;
+			analyses[17]=HydrologyDCInefficientAnalysisEnum;
+			analyses[18]=HydrologyDCEfficientAnalysisEnum;
+			analyses[19]=L2ProjectionEPLAnalysisEnum;
 			break;
 
Index: /issm/trunk/src/c/cores/CorePointerFromSolutionEnum.cpp
===================================================================
--- /issm/trunk/src/c/cores/CorePointerFromSolutionEnum.cpp	(revision 17805)
+++ /issm/trunk/src/c/cores/CorePointerFromSolutionEnum.cpp	(revision 17806)
@@ -24,96 +24,46 @@
 
 		case StressbalanceSolutionEnum:
-			#ifdef _HAVE_STRESSBALANCE_
 			solutioncore=&stressbalance_core;
-			#else
-			_error_("ISSM was not compiled with stressbalance capabilities. Exiting");
-			#endif
 			break;
 		case SteadystateSolutionEnum:
-			#ifdef _HAVE_STEADYSTATE_
 			solutioncore=&steadystate_core;
-			#else
-			_error_("ISSM was not compiled with steady state capabilities. Exiting");
-			#endif
 			break;
 		case ThermalSolutionEnum:
-			#ifdef _HAVE_THERMAL_
 			solutioncore=&thermal_core;
-			#else
-			_error_("ISSM was not compiled with thermal capabilities. Exiting");
-			#endif
 			break;
 		case BalancethicknessSolutionEnum:
-			#ifdef _HAVE_BALANCED_
 			solutioncore=&balancethickness_core;
-			#else
-			_error_("ISSM was not compiled with balanced capabilities. Exiting");
-			#endif
 			break;
 		case BalancethicknessSoftSolutionEnum:
-			#ifdef _HAVE_BALANCED_
 			solutioncore=&dummy_core;
-			#else
-			_error_("ISSM was not compiled with balanced capabilities. Exiting");
-			#endif
 			break;
 		case BalancevelocitySolutionEnum:
-			#ifdef _HAVE_BALANCED_
 			solutioncore=&balancevelocity_core;
-			#else
-			_error_("ISSM was not compiled with balanced capabilities. Exiting");
-			#endif
 			break;
 		case HydrologySolutionEnum:
-			#ifdef _HAVE_HYDROLOGY_
 			solutioncore=&hydrology_core;
-			#else
-			_error_("ISSM was not compiled with hydrology capabilities. Exiting");
-			#endif
 			break;
 		case SurfaceSlopeSolutionEnum:
-			#ifdef _HAVE_SLOPE_
 			solutioncore=&surfaceslope_core;
-			#else
-			_error_("ISSM was not compiled with slope capabilities. Exiting");
-			#endif
 			break;
 		case BedSlopeSolutionEnum:
-			#ifdef _HAVE_SLOPE_
 			solutioncore=&bedslope_core;
-			#else
-			_error_("ISSM was not compiled with slope capabilities. Exiting");
-			#endif
 			break;
 		case TransientSolutionEnum:
-			#ifdef _HAVE_TRANSIENT_
 			solutioncore=&transient_core;
-			#else
-			_error_("ISSM was not compiled with transient capabilities. Exiting");
-			#endif
 			break;
 		case MasstransportSolutionEnum:
-			#ifdef _HAVE_MASSTRANSPORT_
 			solutioncore=&masstransport_core;
-			#else
-			_error_("ISSM was not compiled with masstransport capabilities. Exiting");
-			#endif
 			break;
-
 		case GiaSolutionEnum:
-			#ifdef _HAVE_GIA_
+			#if _HAVE_GIA_
 			solutioncore=&gia_core;
 			#else
-			_error_("ISSM was not compiled with gia capabilities. Exiting");
+			_error_("ISSM not compiled with Gia capability");
 			#endif
 			break;
 		case DamageEvolutionSolutionEnum:
-			#ifdef _HAVE_DAMAGE_
 			solutioncore=&damage_core;
-			#else
-			_error_("ISSM was not compiled with damage evolution capabilities. Exiting");
-			#endif
 			break;
-
 		default:
 			_error_("solution type: " << EnumToStringx(solutiontype) << " not supported yet!");
@@ -124,4 +74,3 @@
 	_assert_(psolutioncore);
 	*psolutioncore=solutioncore;
-
 }
Index: /issm/trunk/src/c/cores/WrapperCorePointerFromSolutionEnum.cpp
===================================================================
--- /issm/trunk/src/c/cores/WrapperCorePointerFromSolutionEnum.cpp	(revision 17805)
+++ /issm/trunk/src/c/cores/WrapperCorePointerFromSolutionEnum.cpp	(revision 17806)
@@ -42,10 +42,6 @@
 	}
 	else if(control_analysis){
-		#ifdef _HAVE_CONTROL_
 		if(tao_analysis) solutioncore=controltao_core;
 		else solutioncore=control_core;
-		#else
-		_error_("ISSM was not compiled with control support, cannot carry out control analysis!");
-		#endif
 	}
 	else CorePointerFromSolutionEnum(&solutioncore,parameters,solutiontype);  /*This means we retrieve a core solution that is not a wrapper*/
Index: /issm/trunk/src/c/cores/bedslope_core.cpp
===================================================================
--- /issm/trunk/src/c/cores/bedslope_core.cpp	(revision 17805)
+++ /issm/trunk/src/c/cores/bedslope_core.cpp	(revision 17806)
@@ -14,9 +14,9 @@
 	/*parameters: */
 	bool save_results;
-	int  meshtype;
+	int  domaintype;
 
 	/*Recover some parameters: */
 	femmodel->parameters->FindParam(&save_results,SaveResultsEnum);
-	femmodel->parameters->FindParam(&meshtype,MeshTypeEnum);
+	femmodel->parameters->FindParam(&domaintype,DomainTypeEnum);
 
 	if(VerboseSolution()) _printf0_("   computing slope\n");
@@ -28,5 +28,5 @@
 	solutionsequence_linear(femmodel);
 
-	if(meshtype!=Mesh2DverticalEnum){
+	if(domaintype!=Domain2DverticalEnum){
 		femmodel->parameters->SetParam(BedSlopeYEnum,InputToL2ProjectEnum);
 		solutionsequence_linear(femmodel);
@@ -35,5 +35,5 @@
 	if(save_results){
 		if(VerboseSolution()) _printf0_("   saving results\n");
-		if(meshtype!=Mesh2DverticalEnum){
+		if(domaintype!=Domain2DverticalEnum){
 			int outputs[2] = {BedSlopeXEnum,BedSlopeYEnum};
 			femmodel->RequestedOutputsx(&femmodel->results,&outputs[0],2);
Index: /issm/trunk/src/c/cores/cores.h
===================================================================
--- /issm/trunk/src/c/cores/cores.h	(revision 17805)
+++ /issm/trunk/src/c/cores/cores.h	(revision 17806)
@@ -24,4 +24,5 @@
 void thermal_core(FemModel* femmodel);
 void surfaceslope_core(FemModel* femmodel);
+void levelsetfunctionslope_core(FemModel* femmodel);
 void bedslope_core(FemModel* femmodel);
 void meshdeformation_core(FemModel* femmodel);
@@ -29,4 +30,5 @@
 void controltao_core(FemModel* femmodel);
 void masstransport_core(FemModel* femmodel);
+void depthaverage_core(FemModel* femmodel);
 void extrudefrombase_core(FemModel* femmodel);
 void extrudefromtop_core(FemModel* femmodel);
Index: /issm/trunk/src/c/cores/damage_core.cpp
===================================================================
--- /issm/trunk/src/c/cores/damage_core.cpp	(revision 17805)
+++ /issm/trunk/src/c/cores/damage_core.cpp	(revision 17806)
@@ -14,8 +14,9 @@
 	/*intermediary*/
 	bool   save_results;
-	bool   dakota_analysis  = false;
+	bool   dakota_analysis     = false;
 	int    solution_type;
+	int    numoutputs          = 0; 
+	char   **requested_outputs = NULL;
 
-	if(VerboseSolution()) _printf0_("   computing damage\n");
 	
 	//first recover parameters common to all solutions
@@ -23,4 +24,6 @@
 	femmodel->parameters->FindParam(&dakota_analysis,QmuIsdakotaEnum);
 	femmodel->parameters->FindParam(&solution_type,SolutionTypeEnum);
+	femmodel->parameters->FindParam(&numoutputs,DamageEvolutionNumRequestedOutputsEnum);
+	if(numoutputs) femmodel->parameters->FindParam(&requested_outputs,&numoutputs,DamageEvolutionRequestedOutputsEnum);
 
 	if(dakota_analysis && solution_type!=TransientSolutionEnum){
@@ -29,4 +32,5 @@
 	}
 
+	if(VerboseSolution()) _printf0_("   computing damage\n");
 	femmodel->SetCurrentConfiguration(DamageEvolutionAnalysisEnum);
 	solutionsequence_linear(femmodel);
@@ -34,6 +38,13 @@
 	if(save_results){
 		if(VerboseSolution()) _printf0_("   saving results\n");
-		int outputs = DamageDEnum;
-		femmodel->RequestedOutputsx(&femmodel->results,&outputs,1);
+		femmodel->RequestedOutputsx(&femmodel->results,requested_outputs,numoutputs);
+	}
+	
+	/*Free resources:*/	
+	if(numoutputs){
+		for(int i=0;i<numoutputs;i++){
+			xDelete<char>(requested_outputs[i]);
+		} 
+		xDelete<char*>(requested_outputs);
 	}
 }
Index: /issm/trunk/src/c/cores/depthaverage_core.cpp
===================================================================
--- /issm/trunk/src/c/cores/depthaverage_core.cpp	(revision 17806)
+++ /issm/trunk/src/c/cores/depthaverage_core.cpp	(revision 17806)
@@ -0,0 +1,20 @@
+/*!\file: depthaverage_core.cpp
+ * \brief: core of the extrusion solution
+ */ 
+
+#include "./cores.h"
+#include "../toolkits/toolkits.h"
+#include "../classes/classes.h"
+#include "../shared/shared.h"
+#include "../solutionsequences/solutionsequences.h"
+#include "../modules/modules.h"
+
+void depthaverage_core(FemModel* femmodel){
+
+	if(VerboseSolution()) _printf0_("depth averaging...\n");
+
+	/*Call on core computations: */
+	femmodel->SetCurrentConfiguration(DepthAverageAnalysisEnum);
+	solutionsequence_linear(femmodel);
+
+}
Index: /issm/trunk/src/c/cores/gia_core.cpp
===================================================================
--- /issm/trunk/src/c/cores/gia_core.cpp	(revision 17805)
+++ /issm/trunk/src/c/cores/gia_core.cpp	(revision 17806)
@@ -50,5 +50,5 @@
 	if(save_results){
 		if(VerboseSolution()) _printf0_("   saving results\n");
-		const int outputs[2] = {GiaWEnum,GiadWdtEnum};
+		int outputs[2] = {GiaWEnum,GiadWdtEnum};
 		femmodel->RequestedOutputsx(&femmodel->results,&outputs[0],2);
 	}
Index: /issm/trunk/src/c/cores/hydrology_core.cpp
===================================================================
--- /issm/trunk/src/c/cores/hydrology_core.cpp	(revision 17805)
+++ /issm/trunk/src/c/cores/hydrology_core.cpp	(revision 17806)
@@ -12,21 +12,12 @@
 void hydrology_core(FemModel* femmodel){
 
-	int i;
-
 	/*intermediary*/
-	int        step,nsteps;
-	int        output_frequency,hydrology_model;
+	int        hydrology_model;
 	bool       save_results;
 	bool       modify_loads=true;
 	bool       isefficientlayer;
-	IssmDouble starttime,final_time;
-	IssmDouble time,dt;
 
 	/*first recover parameters common to all solutions*/
-	femmodel->parameters->FindParam(&starttime,TimesteppingStartTimeEnum);
-	femmodel->parameters->FindParam(&final_time,TimesteppingFinalTimeEnum);
-	femmodel->parameters->FindParam(&dt,TimesteppingTimeStepEnum);
 	femmodel->parameters->FindParam(&save_results,SaveResultsEnum);
-	femmodel->parameters->FindParam(&output_frequency,SettingsOutputFrequencyEnum);
 	femmodel->parameters->FindParam(&hydrology_model,HydrologyModelEnum);
 
@@ -37,69 +28,52 @@
 	}
 
-	/*Compute number of time steps: */
-	if((dt==0)|| (final_time==0)){
-		dt=0;
-		nsteps=1;
+	/*Using the Shreve based Model*/
+	if (hydrology_model==HydrologyshreveEnum){
+		if(VerboseSolution()) _printf0_("   computing water column\n");
+		femmodel->SetCurrentConfiguration(HydrologyShreveAnalysisEnum);
+		solutionsequence_nonlinear(femmodel,modify_loads);
+		
+		/*transfer water column thickness to old water column thickness: */
+		
+		InputDuplicatex(femmodel,WatercolumnEnum,WaterColumnOldEnum);
+		
+		if(save_results){
+			if(VerboseSolution()) _printf0_("   saving results \n");
+			int outputs[3] = {WatercolumnEnum,HydrologyWaterVxEnum,HydrologyWaterVyEnum};
+			femmodel->RequestedOutputsx(&femmodel->results,&outputs[0],3);
+			
+			/*unload results*/
+			if(VerboseSolution()) _printf0_("   saving temporary results\n");
+			OutputResultsx(femmodel);
+		}
 	}
-	else nsteps=reCast<int,IssmDouble>((final_time-starttime)/dt);
 
-	/*initialize: */
-	step=0;
-	time=starttime;
-
-	/*Loop through time: */
-	for(i=0;i<nsteps;i++){
-
-		if(nsteps)if(VerboseSolution()) _printf0_("time step:" << i+1 << "/" << nsteps << "\n");
-		time+=dt;
-		step+=1;
-		femmodel->parameters->SetParam(time,TimeEnum);
-		femmodel->parameters->SetParam(step,StepEnum);
-
-		if (hydrology_model==HydrologyshreveEnum){
-			if(VerboseSolution()) _printf0_("   computing water column\n");
-			femmodel->SetCurrentConfiguration(HydrologyShreveAnalysisEnum);
-			solutionsequence_nonlinear(femmodel,modify_loads);
-
-			/*transfer water column thickness to old water column thickness: */
-
-			InputDuplicatex(femmodel,WatercolumnEnum,WaterColumnOldEnum);
-
-			if(save_results && ((i+1)%output_frequency==0 || (i+1)==nsteps)){
-				if(VerboseSolution()) _printf0_("   saving results \n");
-				int outputs[3] = {WatercolumnEnum,HydrologyWaterVxEnum,HydrologyWaterVyEnum};
+	/*Using the double continuum model*/
+	else if (hydrology_model==HydrologydcEnum){
+		InputDuplicatex(femmodel,SedimentHeadEnum,SedimentHeadOldEnum);
+		femmodel->parameters->FindParam(&isefficientlayer,HydrologydcIsefficientlayerEnum);
+		if (isefficientlayer){
+			InputDuplicatex(femmodel,EplHeadEnum,EplHeadOldEnum);
+			InputDuplicatex(femmodel,HydrologydcEplThicknessEnum,HydrologydcEplThicknessOldEnum);
+		}
+		
+		/*Proceed now to heads computations*/
+		if(VerboseSolution()) _printf0_("   computing water head\n");
+		solutionsequence_hydro_nonlinear(femmodel);
+		if(save_results){
+			if(VerboseSolution()) _printf0_("   saving results \n");
+			if(isefficientlayer){
+				int outputs[9] = {SedimentHeadEnum,SedimentHeadResidualEnum,EplHeadEnum,HydrologydcMaskEplactiveNodeEnum,HydrologydcMaskEplactiveEltEnum,EplHeadSlopeXEnum,EplHeadSlopeYEnum,HydrologydcEplThicknessEnum,EffectivePressureEnum};
+				femmodel->RequestedOutputsx(&femmodel->results,&outputs[0],9);
+			}
+			else{
+				int outputs[3] = {SedimentHeadEnum,SedimentHeadResidualEnum,EffectivePressureEnum};
 				femmodel->RequestedOutputsx(&femmodel->results,&outputs[0],3);
-
-				/*unload results*/
-				if(VerboseSolution()) _printf0_("   saving temporary results\n");
-				OutputResultsx(femmodel->elements, femmodel->nodes, femmodel->vertices, femmodel->loads, femmodel->materials, femmodel->parameters,femmodel->results);
 			}
+			/*unload results*/
+			if(VerboseSolution()) _printf0_("   saving temporary results\n");
+			OutputResultsx(femmodel);
 		}
-
-		else if (hydrology_model==HydrologydcEnum){
-			InputDuplicatex(femmodel,SedimentHeadEnum,SedimentHeadOldEnum);
-			femmodel->parameters->FindParam(&isefficientlayer,HydrologydcIsefficientlayerEnum);
-			if (isefficientlayer){
-				InputDuplicatex(femmodel,EplHeadEnum,EplHeadOldEnum);
-			}
-
-			if(VerboseSolution()) _printf0_("   computing water head\n");
-			solutionsequence_hydro_nonlinear(femmodel);
-			if(save_results && ((i+1)%output_frequency==0 || (i+1)==nsteps)){
-				if(VerboseSolution()) _printf0_("   saving results \n");
-				if(isefficientlayer){
-					int outputs[4] = {SedimentHeadEnum,SedimentHeadResidualEnum,EplHeadEnum,HydrologydcMaskEplactiveEnum};
-					femmodel->RequestedOutputsx(&femmodel->results,&outputs[0],4);
-				}
-				else{
-					int outputs[2] = {SedimentHeadEnum,SedimentHeadResidualEnum};
-					femmodel->RequestedOutputsx(&femmodel->results,&outputs[0],2);
-				}
-				/*unload results*/
-				if(VerboseSolution()) _printf0_("   saving temporary results\n");
-				OutputResultsx(femmodel->elements, femmodel->nodes, femmodel->vertices, femmodel->loads, femmodel->materials, femmodel->parameters,femmodel->results);
-			}
-		}
-
 	}
 }
+
Index: /issm/trunk/src/c/cores/levelsetfunctionslope_core.cpp
===================================================================
--- /issm/trunk/src/c/cores/levelsetfunctionslope_core.cpp	(revision 17806)
+++ /issm/trunk/src/c/cores/levelsetfunctionslope_core.cpp	(revision 17806)
@@ -0,0 +1,52 @@
+/*!\file: levelsetfunctionslope_core.cpp
+ * \brief: core of the slope solution 
+ */ 
+
+#include "./cores.h"
+#include "../toolkits/toolkits.h"
+#include "../classes/classes.h"
+#include "../shared/shared.h"
+#include "../solutionsequences/solutionsequences.h"
+#include "../modules/modules.h"
+
+void levelsetfunctionslope_core(FemModel* femmodel){
+
+	/*parameters: */
+	bool save_results;
+	int  domaintype;
+
+	/*Recover some parameters: */
+	femmodel->parameters->FindParam(&save_results,SaveResultsEnum);
+	femmodel->parameters->FindParam(&domaintype,DomainTypeEnum);
+
+	if(VerboseSolution()) _printf0_("computing slope of levelset function...\n");
+
+	/*Call on core computations: */
+	femmodel->SetCurrentConfiguration(L2ProjectionBaseAnalysisEnum);
+
+	femmodel->parameters->SetParam(LevelsetfunctionSlopeXEnum,InputToL2ProjectEnum);
+	solutionsequence_linear(femmodel);
+
+	if(domaintype!=Domain2DverticalEnum){
+		femmodel->parameters->SetParam(LevelsetfunctionSlopeYEnum,InputToL2ProjectEnum);
+		solutionsequence_linear(femmodel);
+	}
+	if(domaintype==Domain2DverticalEnum){
+	      femmodel->parameters->SetParam(LevelsetfunctionSlopeXEnum,InputToExtrudeEnum);
+		extrudefrombase_core(femmodel);
+	}
+
+	if(save_results){
+		if(VerboseSolution()) _printf0_("saving results:\n");
+		if(domaintype!=Domain2DverticalEnum){
+			int outputs[2] = {LevelsetfunctionSlopeXEnum,LevelsetfunctionSlopeYEnum};
+			femmodel->RequestedOutputsx(&femmodel->results,&outputs[0],2);
+
+		}
+		else{
+			int outputs = LevelsetfunctionSlopeXEnum;
+			femmodel->RequestedOutputsx(&femmodel->results,&outputs,1);
+		}
+	}
+
+}
Index: /issm/trunk/src/c/cores/masstransport_core.cpp
===================================================================
--- /issm/trunk/src/c/cores/masstransport_core.cpp	(revision 17805)
+++ /issm/trunk/src/c/cores/masstransport_core.cpp	(revision 17806)
@@ -14,5 +14,5 @@
 	/*parameters: */
 	int    i;
-	int    numoutputs,meshtype;
+	int    numoutputs,domaintype;
 	bool   save_results;
 	bool   issmbgradients,ispdd,isdelta18o,isFS,isfreesurface,dakota_analysis;
@@ -25,12 +25,9 @@
 	/*recover parameters: */
 	femmodel->parameters->FindParam(&save_results,SaveResultsEnum);
-	femmodel->parameters->FindParam(&issmbgradients,SurfaceforcingsIssmbgradientsEnum);
-	femmodel->parameters->FindParam(&ispdd,SurfaceforcingsIspddEnum);
-	femmodel->parameters->FindParam(&isdelta18o,SurfaceforcingsIsdelta18oEnum);
 	femmodel->parameters->FindParam(&isFS,FlowequationIsFSEnum);
 	femmodel->parameters->FindParam(&isfreesurface,MasstransportIsfreesurfaceEnum);
 	femmodel->parameters->FindParam(&dakota_analysis,QmuIsdakotaEnum);
 	femmodel->parameters->FindParam(&solution_type,SolutionTypeEnum);
-	femmodel->parameters->FindParam(&meshtype,MeshTypeEnum);
+	femmodel->parameters->FindParam(&domaintype,DomainTypeEnum);
 	femmodel->parameters->FindParam(&numoutputs,MasstransportNumRequestedOutputsEnum);
 	if(numoutputs) femmodel->parameters->FindParam(&requested_outputs,&numoutputs,MasstransportRequestedOutputsEnum);
@@ -40,31 +37,22 @@
 		InputDuplicatex(femmodel,QmuSurfaceEnum,SurfaceEnum);
 		InputDuplicatex(femmodel,QmuThicknessEnum,ThicknessEnum);
-		InputDuplicatex(femmodel,QmuBedEnum,BedEnum);
+		InputDuplicatex(femmodel,QmuBaseEnum,BaseEnum);
 	}
 
-	if(issmbgradients){
-	  if(VerboseSolution())_printf_("	call smb gradients module\n\n");
-	  SmbGradientsx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters);
-	}
-	if(ispdd){
-		if(isdelta18o){
-			if(VerboseSolution()) _printf0_("   call Delta18oParametrization module\n");
-			Delta18oParameterizationx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters);
-		} 
-		if(VerboseSolution()) _printf0_("   call positive degree day module\n");
-		PositiveDegreeDayx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters);
-	}
+	/*Calculate new Surface Mass Balance (SMB)*/
+	SurfaceMassBalancex(femmodel);
 
+	/*Transport mass or free surface*/
 	if(isFS && isfreesurface){
 		if(VerboseSolution()) _printf0_("   call free surface computational core\n");
 		femmodel->SetCurrentConfiguration(FreeSurfaceBaseAnalysisEnum);
 		solutionsequence_linear(femmodel);
-		if(meshtype==Mesh2DverticalEnum){
-			femmodel->parameters->SetParam(BedEnum,InputToExtrudeEnum);
+		if(domaintype!=Domain2DhorizontalEnum){
+			femmodel->parameters->SetParam(BaseEnum,InputToExtrudeEnum);
 			extrudefrombase_core(femmodel);
 		}
 		femmodel->SetCurrentConfiguration(FreeSurfaceTopAnalysisEnum);
 		solutionsequence_linear(femmodel);
-		if(meshtype==Mesh2DverticalEnum){
+		if(domaintype!=Domain2DhorizontalEnum){
 			femmodel->parameters->SetParam(SurfaceEnum,InputToExtrudeEnum);
 			extrudefromtop_core(femmodel);
@@ -74,4 +62,12 @@
 		if(VerboseSolution()) _printf0_("   call computational core\n");
 		solutionsequence_linear(femmodel);
+		if(domaintype==Domain2DverticalEnum){
+			femmodel->parameters->SetParam(ThicknessEnum,InputToExtrudeEnum);
+			extrudefrombase_core(femmodel);
+			femmodel->parameters->SetParam(BaseEnum,InputToExtrudeEnum);
+			extrudefrombase_core(femmodel);
+			femmodel->parameters->SetParam(SurfaceEnum,InputToExtrudeEnum);
+			extrudefrombase_core(femmodel);
+		}
 	}
 
@@ -84,4 +80,4 @@
 
 	/*Free ressources:*/
-	if(numoutputs){for(int i=0;i<numoutputs;i++){char* string=requested_outputs[i];xDelete<char>(string);} xDelete<char*>(requested_outputs);} 
+	if(numoutputs){for(int i=0;i<numoutputs;i++){xDelete<char>(requested_outputs[i]);} xDelete<char*>(requested_outputs);}
 }
Index: /issm/trunk/src/c/cores/steadystate_core.cpp
===================================================================
--- /issm/trunk/src/c/cores/steadystate_core.cpp	(revision 17805)
+++ /issm/trunk/src/c/cores/steadystate_core.cpp	(revision 17806)
@@ -50,11 +50,7 @@
 
 		if(VerboseSolution()) _printf0_("   computing temperature and velocity for step: " << step << "\n");
-		#ifdef _HAVE_THERMAL_
 		thermal_core(femmodel);
 		if(!isenthalpy)femmodel->SetCurrentConfiguration(ThermalAnalysisEnum);/*Could be MeltingAnalysis...*/
 		GetSolutionFromInputsx(&tg,femmodel);
-		#else
-		_error_("ISSM was not compiled with thermal capabilities. Exiting");
-		#endif
 
 		if(VerboseSolution()) _printf0_("   computing new velocity\n");
@@ -87,5 +83,5 @@
 	delete tg;
 	delete ug;	
-	if(numoutputs){ for (i=0;i<numoutputs;i++){char* string=requested_outputs[i];xDelete<char>(string);} xDelete<char*>(requested_outputs);}
+	if(numoutputs){for(int i=0;i<numoutputs;i++){xDelete<char>(requested_outputs[i]);} xDelete<char*>(requested_outputs);}
 }
 bool steadystateconvergence(Vector<IssmDouble>* tg,Vector<IssmDouble>* tg_old,Vector<IssmDouble>* ug,Vector<IssmDouble>* ug_old,IssmDouble reltol){
Index: /issm/trunk/src/c/cores/stressbalance_core.cpp
===================================================================
--- /issm/trunk/src/c/cores/stressbalance_core.cpp	(revision 17805)
+++ /issm/trunk/src/c/cores/stressbalance_core.cpp	(revision 17806)
@@ -6,4 +6,5 @@
 #include "../toolkits/toolkits.h"
 #include "../classes/classes.h"
+#include "../analyses/analyses.h"
 #include "../shared/shared.h"
 #include "../modules/modules.h"
@@ -13,18 +14,15 @@
 
 	/*parameters: */
-	bool  dakota_analysis;
-	int   meshtype;
-	bool  isSIA,isSSA,isL1L2,isHO,isFS;
-	bool  conserve_loads    = true;
-	bool  save_results;
-	int   newton;
-	int   solution_type;
-	int   numoutputs        = 0;
-	char** requested_outputs = NULL;
-	int    i;
-
+	bool       dakota_analysis;
+	int        domaintype;
+	bool       isSIA,isSSA,isL1L2,isHO,isFS;
+	bool       save_results;
+	int        solution_type;
+	int        numoutputs        = 0;
+	char     **requested_outputs = NULL;
+	Analysis  *analysis          = NULL;
 
 	/* recover parameters:*/
-	femmodel->parameters->FindParam(&meshtype,MeshTypeEnum);
+	femmodel->parameters->FindParam(&domaintype,DomainTypeEnum);
 	femmodel->parameters->FindParam(&isSIA,FlowequationIsSIAEnum);
 	femmodel->parameters->FindParam(&isSSA,FlowequationIsSSAEnum);
@@ -32,5 +30,4 @@
 	femmodel->parameters->FindParam(&isHO,FlowequationIsHOEnum);
 	femmodel->parameters->FindParam(&isFS,FlowequationIsFSEnum);
-	femmodel->parameters->FindParam(&newton,StressbalanceIsnewtonEnum);
 	femmodel->parameters->FindParam(&dakota_analysis,QmuIsdakotaEnum);
 	femmodel->parameters->FindParam(&save_results,SaveResultsEnum);
@@ -43,46 +40,44 @@
 		InputDuplicatex(femmodel,QmuVxEnum,VxEnum);
 		InputDuplicatex(femmodel,QmuVyEnum,VyEnum);
-		InputDuplicatex(femmodel,QmuVzEnum,VzEnum);
+		if(domaintype==Domain3DEnum) InputDuplicatex(femmodel,QmuVzEnum,VzEnum);
 		if(isFS) InputDuplicatex(femmodel,QmuPressureEnum,PressureEnum);
 	}
 
-	/*Compute slopes: */
-	if(isSIA) surfaceslope_core(femmodel);
+	/*Compute slopes if necessary */
+	if(isSIA || (isFS && domaintype==Domain2DverticalEnum)) surfaceslope_core(femmodel);
 	if(isFS){
 		bedslope_core(femmodel);
 		femmodel->SetCurrentConfiguration(StressbalanceAnalysisEnum);
-		ResetCoordinateSystemx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters);
+		ResetFSBasalBoundaryConditionx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters);
 	}
 
+	/*Compute SIA velocities*/
 	if(isSIA){
-		if(VerboseSolution()) _printf0_("   computing SIA velocities\n");
 
 		/*Take the last velocity into account so that the velocity on the SSA domain is not zero*/
 		if(isSSA || isL1L2 || isHO ) ResetBoundaryConditions(femmodel,StressbalanceSIAAnalysisEnum);
-		femmodel->SetCurrentConfiguration(StressbalanceSIAAnalysisEnum);
-		solutionsequence_linear(femmodel);
+
+		analysis = new StressbalanceSIAAnalysis();
+		analysis->Core(femmodel);
+		delete analysis;
+
+		/*Reset velocities for other ice flow models*/
 		if(isSSA || isL1L2 || isHO) ResetBoundaryConditions(femmodel,StressbalanceAnalysisEnum);
 	}
 
-	if ((isSSA || isHO || isL1L2) ^ isFS){ // ^ = xor
-		if(VerboseSolution()) _printf0_("   computing velocities\n");
-
-		femmodel->SetCurrentConfiguration(StressbalanceAnalysisEnum);
-		if(newton>0)
-		 solutionsequence_newton(femmodel);
-		else
-		 solutionsequence_nonlinear(femmodel,conserve_loads); 
+	/*Compute stressbalance for SSA L1L2 HO and FS*/
+	if(isSSA || isL1L2 || isHO || isFS){
+		analysis = new StressbalanceAnalysis();
+		analysis->Core(femmodel);
+		delete analysis;
 	}
 
-	if ((isSSA || isL1L2 || isHO) && isFS){
-		if(VerboseSolution()) _printf0_("   computing coupling betweem lower order models and full-FS\n");
-		solutionsequence_FScoupling_nonlinear(femmodel,conserve_loads);
+	/*Compute vertical velocities*/
+	if (domaintype==Domain3DEnum && (isSIA || isSSA || isL1L2 || isHO)){
+		analysis = new StressbalanceVerticalAnalysis();
+		analysis->Core(femmodel);
+		delete analysis;
 	}
 
-	if (meshtype==Mesh3DEnum && (isSIA || isSSA || isL1L2 || isHO)){
-		if(VerboseSolution()) _printf0_("   computing vertical velocities\n");
-		femmodel->SetCurrentConfiguration(StressbalanceVerticalAnalysisEnum);
-		solutionsequence_linear(femmodel);
-	}
 
 	if(save_results){
@@ -94,4 +89,4 @@
 
 	/*Free ressources:*/	
-	if(numoutputs){ for (i=0;i<numoutputs;i++){char* string=requested_outputs[i];xDelete<char>(string);} xDelete<char*>(requested_outputs);}
+	if(numoutputs){for(int i=0;i<numoutputs;i++){xDelete<char>(requested_outputs[i]);} xDelete<char*>(requested_outputs);}
 }
Index: /issm/trunk/src/c/cores/surfaceslope_core.cpp
===================================================================
--- /issm/trunk/src/c/cores/surfaceslope_core.cpp	(revision 17805)
+++ /issm/trunk/src/c/cores/surfaceslope_core.cpp	(revision 17806)
@@ -14,9 +14,9 @@
 	/*parameters: */
 	bool save_results;
-	int  meshtype;
+	int  domaintype;
 
 	/*Recover some parameters: */
 	femmodel->parameters->FindParam(&save_results,SaveResultsEnum);
-	femmodel->parameters->FindParam(&meshtype,MeshTypeEnum);
+	femmodel->parameters->FindParam(&domaintype,DomainTypeEnum);
 
 	if(VerboseSolution()) _printf0_("computing slope...\n");
@@ -28,12 +28,16 @@
 	solutionsequence_linear(femmodel);
 
-	if(meshtype!=Mesh2DverticalEnum){
+	if(domaintype!=Domain2DverticalEnum){
 		femmodel->parameters->SetParam(SurfaceSlopeYEnum,InputToL2ProjectEnum);
 		solutionsequence_linear(femmodel);
+	}
+	if(domaintype==Domain2DverticalEnum){
+		femmodel->parameters->SetParam(SurfaceSlopeXEnum,InputToExtrudeEnum);
+		extrudefrombase_core(femmodel);
 	}
 
 	if(save_results){
 		if(VerboseSolution()) _printf0_("saving results:\n");
-		if(meshtype!=Mesh2DverticalEnum){
+		if(domaintype!=Domain2DverticalEnum){
 			int outputs[2] = {SurfaceSlopeXEnum,SurfaceSlopeYEnum};
 			femmodel->RequestedOutputsx(&femmodel->results,&outputs[0],2);
Index: /issm/trunk/src/c/cores/thermal_core.cpp
===================================================================
--- /issm/trunk/src/c/cores/thermal_core.cpp	(revision 17805)
+++ /issm/trunk/src/c/cores/thermal_core.cpp	(revision 17806)
@@ -6,4 +6,5 @@
 #include "../toolkits/toolkits.h"
 #include "../classes/classes.h"
+#include "../analyses/analyses.h"
 #include "../shared/shared.h"
 #include "../modules/modules.h"
@@ -17,4 +18,5 @@
 	int    solution_type,numoutputs;
 	char** requested_outputs = NULL;
+	EnthalpyAnalysis * enthalpy_analysis = NULL;
 
 	/*first recover parameters common to all solutions*/
@@ -46,6 +48,10 @@
 		InputDuplicatex(femmodel,EnthalpyEnum,EnthalpyPicardEnum);
 
-		/*Post process*/
-		if(solution_type!=SteadystateSolutionEnum) PostprocessingEnthalpyx(femmodel);
+		if(solution_type!=SteadystateSolutionEnum){
+			/*Post process*/
+			enthalpy_analysis = new EnthalpyAnalysis();
+			enthalpy_analysis->PostProcessing(femmodel);
+			delete enthalpy_analysis;
+		}
 	}
 	else{
@@ -63,3 +69,7 @@
 		femmodel->RequestedOutputsx(&femmodel->results,requested_outputs,numoutputs);
 	}
+
+	/*Free ressources:*/	
+	if(numoutputs){for(int i=0;i<numoutputs;i++){xDelete<char>(requested_outputs[i]);} xDelete<char*>(requested_outputs);}
+
 }
Index: /issm/trunk/src/c/cores/transient_core.cpp
===================================================================
--- /issm/trunk/src/c/cores/transient_core.cpp	(revision 17805)
+++ /issm/trunk/src/c/cores/transient_core.cpp	(revision 17806)
@@ -22,10 +22,11 @@
 	int    i;
 	IssmDouble starttime,finaltime,dt,yts;
-	bool   isstressbalance,ismasstransport,isFS,isthermal,isgroundingline,isdelta18o,isgia;
+	bool   isstressbalance,ismasstransport,isFS,isthermal,isgroundingline,isgia,islevelset,isdamageevolution,ishydrology;
 	bool   save_results,dakota_analysis;
 	bool   time_adapt=false;
 	int    output_frequency;
-	int    meshtype,groundingline_migration;
+	int    domaintype,groundingline_migration,smb_model;
 	int    numoutputs         = 0;
+  Analysis *analysis = NULL;
 	char** requested_outputs = NULL;
 
@@ -36,5 +37,5 @@
 
 	//first recover parameters common to all solutions
-	femmodel->parameters->FindParam(&meshtype,MeshTypeEnum);
+	femmodel->parameters->FindParam(&domaintype,DomainTypeEnum);
 	femmodel->parameters->FindParam(&starttime,TimesteppingStartTimeEnum);
 	femmodel->parameters->FindParam(&finaltime,TimesteppingFinalTimeEnum);
@@ -49,9 +50,11 @@
 	femmodel->parameters->FindParam(&isgia,TransientIsgiaEnum);
 	femmodel->parameters->FindParam(&isgroundingline,TransientIsgroundinglineEnum);
+	femmodel->parameters->FindParam(&islevelset,TransientIslevelsetEnum);
+	femmodel->parameters->FindParam(&isdamageevolution,TransientIsdamageevolutionEnum);
+	femmodel->parameters->FindParam(&ishydrology,TransientIshydrologyEnum);
 	femmodel->parameters->FindParam(&isFS,FlowequationIsFSEnum);
 	if(isgroundingline) femmodel->parameters->FindParam(&groundingline_migration,GroundinglineMigrationEnum);
 	femmodel->parameters->FindParam(&numoutputs,TransientNumRequestedOutputsEnum);
 	if(numoutputs) femmodel->parameters->FindParam(&requested_outputs,&numoutputs,TransientRequestedOutputsEnum);
-	femmodel->parameters->FindParam(&isdelta18o,SurfaceforcingsIsdelta18oEnum);
 
 	/*initialize: */
@@ -64,5 +67,5 @@
 			InputDuplicatex(femmodel,QmuVxEnum,VxEnum);
 			InputDuplicatex(femmodel,QmuVyEnum,VyEnum);
-			if(meshtype==Mesh3DEnum){
+			if(domaintype==Domain3DEnum){
 				InputDuplicatex(femmodel,QmuVzEnum,VzEnum);
 				if(isFS)InputDuplicatex(femmodel,QmuPressureEnum,PressureEnum);
@@ -72,9 +75,9 @@
 			InputDuplicatex(femmodel,QmuThicknessEnum,ThicknessEnum);
 			InputDuplicatex(femmodel,QmuSurfaceEnum,SurfaceEnum);
-			InputDuplicatex(femmodel,QmuBedEnum,BedEnum);
+			InputDuplicatex(femmodel,QmuBaseEnum,BaseEnum);
 			InputDuplicatex(femmodel,QmuMaskIceLevelsetEnum,MaskIceLevelsetEnum);
 		}
 		if(isgroundingline) InputDuplicatex(femmodel,QmuMaskGroundediceLevelsetEnum,MaskGroundediceLevelsetEnum);
-		if(isthermal && meshtype==Mesh3DEnum){
+		if(isthermal && domaintype==Domain3DEnum){
 			//Update Vertex Position after updating Thickness and Bed
 			femmodel->SetCurrentConfiguration(MasstransportAnalysisEnum);
@@ -93,5 +96,4 @@
 
 	while(time < finaltime - (yts*DBL_EPSILON)){ //make sure we run up to finaltime.
-
 		/*Increment*/
 		if(time_adapt){
@@ -106,5 +108,5 @@
 
 		if(VerboseSolution()) _printf0_("iteration " << step << "/" << floor((finaltime-time)/dt)+step << "  time [yr]: " << time/yts << " (time step: " << dt/yts << ")\n");
-		if(step%output_frequency==0 || time==finaltime)
+		if(step%output_frequency==0 || (time >= finaltime - (yts*DBL_EPSILON)) || step==1)
 		 save_results=true;
 		else
@@ -112,20 +114,50 @@
 		femmodel->parameters->SetParam(save_results,SaveResultsEnum);
 
-		if(isthermal && meshtype==Mesh3DEnum){
-			if(VerboseSolution()) _printf0_("   computing temperatures\n");
-			#ifdef _HAVE_THERMAL_
+		if(isthermal && domaintype==Domain3DEnum){
+			if(VerboseSolution()) _printf0_("   computing thermal regime\n");
 			thermal_core(femmodel);
-			#else
-			_error_("ISSM was not compiled with thermal capabilities. Exiting");
-			#endif
+		}
+
+		if(ishydrology){
+			if(VerboseSolution()) _printf0_("   computing water heads\n");
+			hydrology_core(femmodel);
 		}
 
 		if(isstressbalance){
 			if(VerboseSolution()) _printf0_("   computing new velocity\n");
-			#ifdef _HAVE_STRESSBALANCE_
 			stressbalance_core(femmodel);
-			#else
-			_error_("ISSM was not compiled with stressbalance capabilities. Exiting");
-			#endif
+		}
+
+		if(isdamageevolution){
+			if(VerboseSolution()) _printf0_("   computing damage\n");
+			damage_core(femmodel);
+		}
+
+		if(islevelset){
+			if(VerboseSolution()) _printf0_("   computing movement of ice boundaries\n");
+			/* smoothen slope of lsf for computation of normal on ice domain*/
+			levelsetfunctionslope_core(femmodel);
+
+			/* extrapolate velocities onto domain with no ice */
+			Analysis* extanalysis = new ExtrapolationAnalysis();
+			const int nvars=2;
+			int vars[nvars] = {VxEnum, VyEnum};
+			for(int iv=0;iv<nvars;iv++){
+				femmodel->parameters->SetParam(vars[iv],ExtrapolationVariableEnum); 
+				extanalysis->Core(femmodel);
+			}
+			delete extanalysis;	
+
+			/* solve level set equation */
+			analysis = new LevelsetAnalysis();
+			analysis->Core(femmodel);
+			delete analysis;
+
+			/* update vertices included for next calculation */
+			GetMaskOfIceVerticesLSMx(femmodel);
+
+			/* add computation domain mask to outputs */
+			int outputs[1] = {IceMaskNodeActivationEnum};
+			femmodel->RequestedOutputsx(&femmodel->results,&outputs[0],1);
 		}
 
@@ -136,14 +168,17 @@
 			femmodel->UpdateVertexPositionsx();
 		}
-
+		
 		if(isgroundingline){
 			if(VerboseSolution()) _printf0_("   computing new grounding line position\n");
-			#ifdef _HAVE_GROUNDINGLINE_
 			GroundinglineMigrationx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters);
-			#else
-			_error_("ISSM was not compiled with grounding line migration capabilities. Exiting");
-			#endif
+
+			if(groundingline_migration==ContactEnum){
+				femmodel->parameters->SetParam(MaskGroundediceLevelsetEnum,InputToExtrudeEnum);
+				extrudefrombase_core(femmodel);
+				femmodel->parameters->SetParam(BaseEnum,InputToExtrudeEnum);
+				extrudefrombase_core(femmodel);
+			}
 			if(save_results){
-				int outputs[3] = {SurfaceEnum,BedEnum,MaskGroundediceLevelsetEnum};
+				int outputs[3] = {SurfaceEnum,BaseEnum,MaskGroundediceLevelsetEnum};
 				femmodel->RequestedOutputsx(&femmodel->results,&outputs[0],3);
 			}
@@ -156,21 +191,17 @@
 			_error_("ISSM was not compiled with gia capabilities. Exiting");
 			#endif
-
 		}
 
 		/*unload results*/
+		if(VerboseSolution()) _printf0_("   computing requested outputs\n");
+		femmodel->RequestedOutputsx(&femmodel->results,requested_outputs,numoutputs,save_results);
+		if(isgroundingline && (groundingline_migration==SubelementMigrationEnum || groundingline_migration==SubelementMigration2Enum)){
+			int outputs[1] = {MaskGroundediceLevelsetEnum};
+			femmodel->RequestedOutputsx(&femmodel->results,&outputs[0],1,save_results);
+		}
+
 		if(save_results){
-			if(VerboseSolution()) _printf0_("   saving transient results\n");
-			femmodel->RequestedOutputsx(&femmodel->results,requested_outputs,numoutputs);
-			if(isdelta18o){
-				int outputs[2] = {SurfaceforcingsMonthlytemperaturesEnum,SurfaceforcingsPrecipitationEnum};
-				femmodel->RequestedOutputsx(&femmodel->results,&outputs[0],2);
-			}
-			if(isgroundingline && (groundingline_migration==SubelementMigrationEnum || groundingline_migration==SubelementMigration2Enum)){
-				int outputs[1] = {MaskGroundediceLevelsetEnum};
-				femmodel->RequestedOutputsx(&femmodel->results,&outputs[0],1);
-			}
 			if(VerboseSolution()) _printf0_("   saving temporary results\n");
-			OutputResultsx(femmodel->elements, femmodel->nodes, femmodel->vertices, femmodel->loads, femmodel->materials, femmodel->parameters,femmodel->results);
+			OutputResultsx(femmodel);
 		}
 	}
@@ -179,4 +210,4 @@
 
 	/*Free ressources:*/	
-	if(numoutputs){ for (i=0;i<numoutputs;i++){char* string=requested_outputs[i];xDelete<char>(string);} xDelete<char*>(requested_outputs);}
+	if(numoutputs){for(int i=0;i<numoutputs;i++){xDelete<char>(requested_outputs[i]);} xDelete<char*>(requested_outputs);}
 }
Index: /issm/trunk/src/c/main/issm.cpp
===================================================================
--- /issm/trunk/src/c/main/issm.cpp	(revision 17805)
+++ /issm/trunk/src/c/main/issm.cpp	(revision 17806)
@@ -20,5 +20,5 @@
 
 	/*Output results: */
-	femmodel->OutputResults();
+	OutputResultsx(femmodel);
 
 	/*Wrap up: */
Index: /issm/trunk/src/c/modules/ConstraintsStatex/ConstraintsStatex.cpp
===================================================================
--- /issm/trunk/src/c/modules/ConstraintsStatex/ConstraintsStatex.cpp	(revision 17805)
+++ /issm/trunk/src/c/modules/ConstraintsStatex/ConstraintsStatex.cpp	(revision 17806)
@@ -26,9 +26,7 @@
 
 	/*Rift penalties first*/
-	#ifdef _HAVE_RIFTS_
 	if(RiftIsPresent(femmodel->loads,analysis_type)){
 		RiftConstraintsState(&converged,&num_unstable_constraints,femmodel->loads,min_mechanical_constraints,analysis_type);
 	}
-	#endif
 
 	/*Deal with pengrid*/
Index: /issm/trunk/src/c/modules/CreateJacobianMatrixx/CreateJacobianMatrixx.cpp
===================================================================
--- /issm/trunk/src/c/modules/CreateJacobianMatrixx/CreateJacobianMatrixx.cpp	(revision 17805)
+++ /issm/trunk/src/c/modules/CreateJacobianMatrixx/CreateJacobianMatrixx.cpp	(revision 17806)
@@ -10,6 +10,6 @@
 void CreateJacobianMatrixx(Matrix<IssmDouble>** pJff,FemModel* femmodel,IssmDouble kmax){
 
-	int      i,connectivity;
-	int      configuration_type;
+	int      i;
+	int      configuration_type,analysisenum;
 	Element *element = NULL;
 	Load    *load    = NULL;
@@ -21,5 +21,6 @@
 	/*Recover some parameters*/
 	femmodel->parameters->FindParam(&configuration_type,ConfigurationTypeEnum);
-	femmodel->parameters->FindParam(&connectivity,MeshAverageVertexConnectivityEnum);
+	femmodel->parameters->FindParam(&analysisenum,AnalysisTypeEnum);
+	Analysis* analysis = EnumToAnalysis(analysisenum);
 
 	/*Initialize Jacobian Matrix*/
@@ -29,5 +30,7 @@
 	for(i=0;i<femmodel->elements->Size();i++){
 		element=dynamic_cast<Element*>(femmodel->elements->GetObjectByOffset(i));
-		element->CreateJacobianMatrix(Jff);
+		ElementMatrix* Je = analysis->CreateJacobianMatrix(element);
+		if(Je) Je->AddToGlobal(Jff);
+		delete Je;
 	}
 	for (i=0;i<femmodel->loads->Size();i++){
@@ -39,4 +42,5 @@
 
 	/*Assign output pointer*/
+	delete analysis;
 	*pJff=Jff;
 
Index: /issm/trunk/src/c/modules/CreateJacobianMatrixx/CreateJacobianMatrixx.h
===================================================================
--- /issm/trunk/src/c/modules/CreateJacobianMatrixx/CreateJacobianMatrixx.h	(revision 17805)
+++ /issm/trunk/src/c/modules/CreateJacobianMatrixx/CreateJacobianMatrixx.h	(revision 17806)
@@ -6,4 +6,5 @@
 
 #include "../../classes/classes.h"
+#include "../../analyses/analyses.h"
 
 /* local prototypes: */
Index: /issm/trunk/src/c/modules/GetSolutionFromInputsx/GetSolutionFromInputsx.cpp
===================================================================
--- /issm/trunk/src/c/modules/GetSolutionFromInputsx/GetSolutionFromInputsx.cpp	(revision 17805)
+++ /issm/trunk/src/c/modules/GetSolutionFromInputsx/GetSolutionFromInputsx.cpp	(revision 17806)
@@ -11,7 +11,5 @@
 	/*intermediary: */
 	int      gsize;
-	Element* element = NULL;
-
-	int configuration_type;
+	int      configuration,analysisenum;
 
 	/*output: */
@@ -21,9 +19,10 @@
 
 	/*retrive parameters: */
-	femmodel->parameters->FindParam(&configuration_type,ConfigurationTypeEnum);
+	femmodel->parameters->FindParam(&configuration,ConfigurationTypeEnum);
+	femmodel->parameters->FindParam(&analysisenum,AnalysisTypeEnum);
 
 	/*Get size of vector: */
-	gsize=femmodel->nodes->NumberOfDofs(configuration_type,GsetEnum);
-	if(gsize==0) _error_("Allocating a Vec of size 0 as gsize=0 for configuration: " << EnumToStringx(configuration_type));
+	gsize=femmodel->nodes->NumberOfDofs(configuration,GsetEnum);
+	if(gsize==0) _error_("Allocating a Vec of size 0 as gsize=0 for configuration "<<EnumToStringx(configuration));
 
 	/*Initialize solution: */
@@ -31,8 +30,10 @@
 
 	/*Go through elements and plug solution: */
+	Analysis* analysis = EnumToAnalysis(analysisenum);
 	for(int i=0;i<femmodel->elements->Size();i++){
-		element=dynamic_cast<Element*>(femmodel->elements->GetObjectByOffset(i));
-		element->GetSolutionFromInputs(solution);
+		Element* element=dynamic_cast<Element*>(femmodel->elements->GetObjectByOffset(i));
+		analysis->GetSolutionFromInputs(solution,element);
 	}
+	delete analysis;
 
 	/*Assemble vector: */
Index: /issm/trunk/src/c/modules/GetSolutionFromInputsx/GetSolutionFromInputsx.h
===================================================================
--- /issm/trunk/src/c/modules/GetSolutionFromInputsx/GetSolutionFromInputsx.h	(revision 17805)
+++ /issm/trunk/src/c/modules/GetSolutionFromInputsx/GetSolutionFromInputsx.h	(revision 17806)
@@ -7,4 +7,5 @@
 
 #include "../../classes/classes.h"
+#include "../../analyses/analyses.h"
 
 /* local prototypes: */
Index: /issm/trunk/src/c/modules/GetVectorFromInputsx/GetVectorFromInputsx.cpp
===================================================================
--- /issm/trunk/src/c/modules/GetVectorFromInputsx/GetVectorFromInputsx.cpp	(revision 17805)
+++ /issm/trunk/src/c/modules/GetVectorFromInputsx/GetVectorFromInputsx.cpp	(revision 17806)
@@ -21,10 +21,4 @@
 			Element* element=dynamic_cast<Element*>(femmodel->elements->GetObjectByOffset(i));
 			element->GetVectorFromInputs(vector,name);
-		}
-
-		/*Look up in materials*/
-		for(i=0;i<femmodel->materials->Size();i++){
-			Material* material=(Material*)femmodel->materials->GetObjectByOffset(i);
-			material->GetVectorFromInputs(vector,name);
 		}
 	}
Index: /issm/trunk/src/c/modules/GroundinglineMigrationx/GroundinglineMigrationx.cpp
===================================================================
--- /issm/trunk/src/c/modules/GroundinglineMigrationx/GroundinglineMigrationx.cpp	(revision 17805)
+++ /issm/trunk/src/c/modules/GroundinglineMigrationx/GroundinglineMigrationx.cpp	(revision 17806)
@@ -23,19 +23,24 @@
 	if(migration_style==NoneEnum) return;
 
-	if(migration_style!=AgressiveMigrationEnum  &&
-		migration_style!=SoftMigrationEnum       &&
-		migration_style!=SubelementMigrationEnum &&
-		migration_style!=SubelementMigration2Enum)
-	 _error_("Grounding line migration "<<EnumToStringx(migration_style) << " not supported yet!");
-
 	/*Set toolkit to default*/
 	ToolkitsOptionsFromAnalysis(parameters,DefaultAnalysisEnum);
 
-	if(migration_style==SoftMigrationEnum){
-		/*Create flag for grounded vertices above the hydrostatic equilibrium: */
-		vertices_potentially_ungrounding=PotentialUngrounding(elements,vertices,parameters);
-
-		/*propagate ice shelf into connex areas of the ice sheet that potentially want to unground: */
-		phi_ungrounding=PropagateFloatingiceToGroundedNeighbors(elements,nodes,vertices,parameters,vertices_potentially_ungrounding);
+	switch(migration_style){
+		case SoftMigrationEnum:
+			/*Create flag for grounded vertices above the hydrostatic equilibrium: */
+			vertices_potentially_ungrounding=PotentialUngrounding(elements,vertices,parameters);
+			/*propagate ice shelf into connex areas of the ice sheet that potentially want to unground: */
+			phi_ungrounding=PropagateFloatingiceToGroundedNeighbors(elements,nodes,vertices,parameters,vertices_potentially_ungrounding);
+			break;
+		case ContactEnum:
+			phi_ungrounding=ContactFSLevelset(elements,vertices);
+			break;
+		case AgressiveMigrationEnum:
+		case SubelementMigrationEnum:
+		case SubelementMigration2Enum:
+			/*Nothing additional to do here, MigrateGroundingLine takes care of everything*/
+			break;
+		default:
+			_error_("Grounding line migration "<<EnumToStringx(migration_style) << " not supported yet!");
 	}
 
@@ -51,4 +56,56 @@
 }
 
+/*FUNCTION ContactFSLevelset{{{*/
+IssmDouble*    ContactFSLevelset(Elements* elements,Vertices* vertices){ 
+
+	Vector<IssmDouble>* vertexgrounded = NULL;
+	Vector<IssmDouble>* vertexfloating = NULL;
+	IssmDouble*  serial_vertexgrounded = NULL;
+	IssmDouble*  serial_vertexfloating = NULL;
+	IssmDouble*  phi                   = NULL;
+
+	/*Initialize vector with number of vertices*/
+	int numberofvertices = vertices->NumberOfVertices();
+	vertexgrounded = new Vector<IssmDouble>(numberofvertices);
+	vertexfloating = new Vector<IssmDouble>(numberofvertices);
+	phi            = xNew<IssmDouble>(numberofvertices);
+
+	/*Fill vector vertices_potentially_floating: */
+	for(int i=0;i<elements->Size();i++){
+		Element* element=dynamic_cast<Element*>(elements->GetObjectByOffset(i));
+		element->FSContactMigration(vertexgrounded,vertexfloating);
+	}
+
+	/*Assemble vector and serialize */
+	vertexgrounded->Assemble();
+	vertexfloating->Assemble();
+	serial_vertexgrounded=vertexgrounded->ToMPISerial();
+	serial_vertexfloating=vertexfloating->ToMPISerial();
+
+	/*find vertices on GL */
+	for(int i=0;i<numberofvertices;i++){
+		if(serial_vertexgrounded[i]==1. && serial_vertexfloating[i]==1.){
+			phi[i]=0.;
+		}
+		else if(serial_vertexgrounded[i]==1.){
+			phi[i]=1.;
+		}
+		else if(serial_vertexfloating[i]==1.){
+			phi[i]=-1.;
+		}
+		else{
+			phi[i]=9999.;
+		}
+	}
+
+	/*free ressouces and return: */
+	delete vertexgrounded;
+	delete vertexfloating;
+	xDelete<IssmDouble>(serial_vertexgrounded);
+	xDelete<IssmDouble>(serial_vertexfloating);
+
+	return phi;
+}
+/*}}}*/
 /*FUNCTION PotentialUngrounding {{{*/
 IssmDouble*    PotentialUngrounding(Elements* elements,Vertices* vertices,Parameters* parameters){ 
Index: /issm/trunk/src/c/modules/GroundinglineMigrationx/GroundinglineMigrationx.h
===================================================================
--- /issm/trunk/src/c/modules/GroundinglineMigrationx/GroundinglineMigrationx.h	(revision 17805)
+++ /issm/trunk/src/c/modules/GroundinglineMigrationx/GroundinglineMigrationx.h	(revision 17806)
@@ -13,4 +13,5 @@
 /* local prototypes: */
 void         GroundinglineMigrationx(Elements* elements,Nodes* nodes, Vertices* vertices,Loads* loads,Materials* materials, Parameters* parameters);
+IssmDouble*  ContactFSLevelset(Elements* elements,Vertices* vertices);
 IssmDouble*  PotentialUngrounding(Elements* elements,Vertices* vertices,Parameters* parameters);
 IssmDouble*  PropagateFloatingiceToGroundedNeighbors(Elements* elements,Nodes* nodes,Vertices* vertices,Parameters* parameters,IssmDouble* vertices_potentially_ungrounding);
Index: /issm/trunk/src/c/modules/InputDuplicatex/InputDuplicatex.cpp
===================================================================
--- /issm/trunk/src/c/modules/InputDuplicatex/InputDuplicatex.cpp	(revision 17805)
+++ /issm/trunk/src/c/modules/InputDuplicatex/InputDuplicatex.cpp	(revision 17806)
@@ -9,5 +9,4 @@
 
 void InputDuplicatex(FemModel* femmodel,int original_enum, int new_enum){
-
 	/*Go through elemnets, and ask to reinitialie the input: */
 	for(int i=0;i<femmodel->elements->Size();i++){
@@ -15,8 +14,3 @@
 		element->InputDuplicate(original_enum,new_enum);
 	}
-	for(int i=0;i<femmodel->materials->Size();i++){
-		Material* material=(Material*)femmodel->materials->GetObjectByOffset(i);
-		material->InputDuplicate(original_enum,new_enum);
-	}
-
 }
Index: /issm/trunk/src/c/modules/InputUpdateFromSolutionx/InputUpdateFromSolutionx.cpp
===================================================================
--- /issm/trunk/src/c/modules/InputUpdateFromSolutionx/InputUpdateFromSolutionx.cpp	(revision 17805)
+++ /issm/trunk/src/c/modules/InputUpdateFromSolutionx/InputUpdateFromSolutionx.cpp	(revision 17806)
@@ -21,7 +21,13 @@
 void InputUpdateFromSolutionx(FemModel* femmodel,IssmDouble* solution){
 
+	/*retrive parameters: */
+	int analysisenum;
+	femmodel->parameters->FindParam(&analysisenum,AnalysisTypeEnum);
+
+	Analysis* analysis = EnumToAnalysis(analysisenum);
 	for(int i=0;i<femmodel->elements->Size();i++){
 		Element* element=dynamic_cast<Element*>(femmodel->elements->GetObjectByOffset(i));
-		element->InputUpdateFromSolution(solution);
+		analysis->InputUpdateFromSolution(solution,element);
 	}
+	delete analysis;
 }
Index: /issm/trunk/src/c/modules/InputUpdateFromSolutionx/InputUpdateFromSolutionx.h
===================================================================
--- /issm/trunk/src/c/modules/InputUpdateFromSolutionx/InputUpdateFromSolutionx.h	(revision 17805)
+++ /issm/trunk/src/c/modules/InputUpdateFromSolutionx/InputUpdateFromSolutionx.h	(revision 17806)
@@ -7,4 +7,5 @@
 
 #include "../../classes/classes.h"
+#include "../../analyses/analyses.h"
 
 /* local prototypes: */
Index: /issm/trunk/src/c/modules/InterpFromMeshToGridx/InterpFromMeshToGridx.cpp
===================================================================
--- /issm/trunk/src/c/modules/InterpFromMeshToGridx/InterpFromMeshToGridx.cpp	(revision 17805)
+++ /issm/trunk/src/c/modules/InterpFromMeshToGridx/InterpFromMeshToGridx.cpp	(revision 17806)
@@ -107,18 +107,18 @@
 		/*Get indices i and j that form a square around the currant triangle*/
 		if (yflip){
-			i1=max(0,      (int)floor((y_tria_max-y_grid_max)/yposting)-1);
-			i2=min(nlines, (int)ceil((y_tria_min-y_grid_max)/yposting));
+			i1=max(0,       (int)floor((y_tria_max-y_grid_max)/yposting)-1);
+			i2=min(nlines-1,(int)ceil((y_tria_min-y_grid_max)/yposting));
 		}
 		else{
-			i1=max(0,      (int)floor((y_tria_min-y_grid_min)/yposting)-1);
-			i2=min(nlines, (int)ceil((y_tria_max-y_grid_min)/yposting));
+			i1=max(0,       (int)floor((y_tria_min-y_grid_min)/yposting)-1);
+			i2=min(nlines-1,(int)ceil((y_tria_max-y_grid_min)/yposting));
 		}
 		if (xflip){
-			j1=max(0,     (int)floor((x_tria_max-x_grid_max)/xposting)-1);
-			j2=min(ncols, (int)ceil((x_tria_min-x_grid_max)/xposting));
+			j1=max(0,      (int)floor((x_tria_max-x_grid_max)/xposting)-1);
+			j2=min(ncols-1,(int)ceil((x_tria_min-x_grid_max)/xposting));
 		}
 		else{
-			j1=max(0,     (int)floor((x_tria_min-x_grid_min)/xposting)-1);
-			j2=min(ncols, (int)ceil((x_tria_max-x_grid_min)/xposting));
+			j1=max(0,      (int)floor((x_tria_min-x_grid_min)/xposting)-1);
+			j2=min(ncols-1,(int)ceil((x_tria_max-x_grid_min)/xposting));
 		}
 
Index: /issm/trunk/src/c/modules/IoModelToConstraintsx/IoModelToConstraintsx.cpp
===================================================================
--- /issm/trunk/src/c/modules/IoModelToConstraintsx/IoModelToConstraintsx.cpp	(revision 17805)
+++ /issm/trunk/src/c/modules/IoModelToConstraintsx/IoModelToConstraintsx.cpp	(revision 17806)
@@ -33,5 +33,7 @@
 
 	/*intermediary: */
-	int         i,j,count,elementnbv;
+	bool        isnan;
+	int         i,j,count,elementnbv,numfacevertices;
+	int*        faceverticesid   = NULL;
 	IssmDouble  value;
 	IssmDouble *times            = NULL;
@@ -39,7 +41,8 @@
 	bool        spcpresent       = false;
 
-	/*P2 finite elements*/
-	int   v1,v2;
+	/*Higher-order finite elements*/
+	int   v1,v2,v3,v4;
 	bool *my_edges = NULL;
+	bool *my_faces = NULL;
 
 	switch(finite_element){
@@ -48,8 +51,8 @@
 			break;
 		case P1bubbleEnum:
-			switch(iomodel->meshtype){
-				case Mesh2DhorizontalEnum: elementnbv = 3; break;
-				case Mesh2DverticalEnum:   elementnbv = 3; break;
-				case Mesh3DEnum:           elementnbv = 6; break;
+			switch(iomodel->meshelementtype){
+				case TriaEnum:  elementnbv = 3; break;
+				case TetraEnum: elementnbv = 4; break;
+				case PentaEnum: elementnbv = 6; break;
 				default: _error_("mesh type not supported yet");
 			}
@@ -61,4 +64,7 @@
 			EdgesPartitioning(&my_edges,iomodel);
 			break;
+		case P1xP3Enum:
+			EdgesPartitioning(&my_edges,iomodel);
+			break;
 		case P2xP1Enum:
 			EdgesPartitioning(&my_edges,iomodel);
@@ -66,4 +72,11 @@
 		case P2Enum:
 			EdgesPartitioning(&my_edges,iomodel);
+	      if(iomodel->meshelementtype==PentaEnum){
+				FacesPartitioning(&my_faces,iomodel);
+			}
+			break;
+		case P2xP4Enum:
+			EdgesPartitioning(&my_edges,iomodel);
+			FacesPartitioning(&my_faces,iomodel);
 			break;
 		default:
@@ -101,4 +114,90 @@
 											dof,(spcdata[v1]+spcdata[v2])/2.,analysis_type));
 							count++;
+						}
+					}
+				}
+				if(iomodel->meshelementtype==PentaEnum){
+					for(i=0;i<iomodel->numberoffaces;i++){
+						if(iomodel->faces[i*6+5]==2){/*Vertical quads*/
+							if(my_faces[i]){
+								FaceGetVertexIndices(iomodel,&numfacevertices,&faceverticesid,i);
+								isnan=0;
+								for(j=0;j<numfacevertices;j++){
+									if(xIsNan<IssmDouble>(spcdata[faceverticesid[j]-1])) isnan=1;
+								}
+								if(isnan==0){
+									value=0;
+									for(j=0;j<numfacevertices;j++){
+										value=value+spcdata[faceverticesid[j]-1]/numfacevertices;
+									}
+									constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+iomodel->numberofvertices+iomodel->numberofedges+i+1,
+													dof,value,analysis_type));
+									count++;
+								}
+								xDelete<int>(faceverticesid);
+							}
+						}
+					}
+				}
+				break;
+			case P2xP4Enum:
+				for(i=0;i<iomodel->numberofvertices;i++){
+					if((iomodel->my_vertices[i])){
+						if (!xIsNan<IssmDouble>(spcdata[i])){
+							constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,dof,spcdata[i],analysis_type));
+							count++;
+						}
+					}
+				}
+				for(i=0;i<iomodel->numberofedges;i++){
+					if(iomodel->edges[i*3+2]==2){/*Vertical edges*/
+						if(my_edges[i]){
+							v1 = iomodel->edges[3*i+0]-1;
+							v2 = iomodel->edges[3*i+1]-1;
+							if(!xIsNan<IssmDouble>(spcdata[v1]) && !xIsNan<IssmDouble>(spcdata[v2])){
+								constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+iomodel->numberofvertices+3*i+1,
+												dof,1./2.*spcdata[v1]+1./2.*spcdata[v2],analysis_type));
+								constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+2,iomodel->nodecounter+iomodel->numberofvertices+3*i+2,
+												dof,1./2.*spcdata[v1]+1./2.*spcdata[v2],analysis_type));
+								constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+3,iomodel->nodecounter+iomodel->numberofvertices+3*i+3,
+												dof,1./2.*spcdata[v1]+1./2.*spcdata[v2],analysis_type));
+								count=count+3;
+							}
+						}
+					}
+					if(iomodel->edges[i*3+2]==1){/*Horizontal edges*/
+						if(my_edges[i]){
+							v1 = iomodel->edges[3*i+0]-1;
+							v2 = iomodel->edges[3*i+1]-1;
+							if(!xIsNan<IssmDouble>(spcdata[v1]) && !xIsNan<IssmDouble>(spcdata[v2])){
+								constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+iomodel->numberofvertices+3*i+1,
+												dof,1./2.*spcdata[v1]+1./2.*spcdata[v2],analysis_type));
+								count=count+1;
+							}
+						}
+					}
+				}
+				for(i=0;i<iomodel->numberoffaces;i++){
+					if(iomodel->faces[i*6+5]==2){/*Vertical quads*/
+						if(my_faces[i]){
+							FaceGetVertexIndices(iomodel,&numfacevertices,&faceverticesid,i);
+							isnan=0;
+							for(j=0;j<numfacevertices;j++){
+								if(xIsNan<IssmDouble>(spcdata[faceverticesid[j]-1])) isnan=1;
+							}
+							if(isnan==0){
+								value=0;
+								for(j=0;j<numfacevertices;j++){
+									value=value+spcdata[faceverticesid[j]-1]/numfacevertices;
+								}
+								constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->numberofedges+3*i+1,
+												dof,value,analysis_type));
+								constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+2,iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->numberofedges+3*i+2,
+												dof,value,analysis_type));
+								constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+3,iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->numberofedges+3*i+3,
+												dof,value,analysis_type));
+								count=count+3;
+							}
+							xDelete<int>(faceverticesid);
 						}
 					}
@@ -160,4 +259,29 @@
 				}
 				break;
+			case P1xP3Enum:
+				for(i=0;i<iomodel->numberofvertices;i++){
+					if((iomodel->my_vertices[i])){
+						if (!xIsNan<IssmDouble>(spcdata[i])){
+							constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,dof,spcdata[i],analysis_type));
+							count++;
+						}
+					}
+				}
+				for(i=0;i<iomodel->numberofedges;i++){
+					if(iomodel->edges[i*3+2]==2){
+						if(my_edges[i]){
+							v1 = iomodel->edges[3*i+0]-1;
+							v2 = iomodel->edges[3*i+1]-1;
+							if(!xIsNan<IssmDouble>(spcdata[v1]) && !xIsNan<IssmDouble>(spcdata[v2])){
+								constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+iomodel->numberofvertices+2*i+1,
+												dof,2./3.*spcdata[v1]+1./3.*spcdata[v2],analysis_type));
+								constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+2,iomodel->nodecounter+iomodel->numberofvertices+2*i+2,
+												dof,1./3.*spcdata[v1]+2./3.*spcdata[v2],analysis_type));
+								count=count+2;
+							}
+						}
+					}
+				}
+				break;
 			case P2xP1Enum:
 				for(i=0;i<iomodel->numberofvertices;i++){
@@ -346,3 +470,4 @@
 	xDelete<IssmDouble>(values);
 	xDelete<bool>(my_edges);
+	xDelete<bool>(my_faces);
 }
Index: /issm/trunk/src/c/modules/IoModelToConstraintsx/IoModelToConstraintsx.h
===================================================================
--- /issm/trunk/src/c/modules/IoModelToConstraintsx/IoModelToConstraintsx.h	(revision 17805)
+++ /issm/trunk/src/c/modules/IoModelToConstraintsx/IoModelToConstraintsx.h	(revision 17806)
@@ -8,6 +8,6 @@
 
 /* local prototypes: */
-void IoModelToConstraintsx(Constraints* constraints,IoModel* iomodel,int vector_enum,int analysis_type,int finite_element,int dof=1);
-void IoModelToConstraintsx(Constraints* constraints,IoModel* iomodel,IssmDouble* spcdata,int M,int N,int analysis_type,int finite_element,int dof=1);
+void IoModelToConstraintsx(Constraints* constraints,IoModel* iomodel,int vector_enum,int analysis_type,int finite_element,int dof=0);
+void IoModelToConstraintsx(Constraints* constraints,IoModel* iomodel,IssmDouble* spcdata,int M,int N,int analysis_type,int finite_element,int dof=0);
 
 #endif  /* _IOMODELTOELEMENTINPUTX_H */
Index: /issm/trunk/src/c/modules/Krigingx/pKrigingx.cpp
===================================================================
--- /issm/trunk/src/c/modules/Krigingx/pKrigingx.cpp	(revision 17805)
+++ /issm/trunk/src/c/modules/Krigingx/pKrigingx.cpp	(revision 17806)
@@ -22,4 +22,5 @@
 	/*Intermediaries*/
 	int           mindata,maxdata;
+	double        dmindata,dmaxdata;
 	double        radius;
 	char         *output       = NULL;
@@ -39,6 +40,7 @@
 	ISSM_MPI_Barrier(ISSM_MPI_COMM_WORLD); start=ISSM_MPI_Wtime();
 	options->Get(&radius,"searchradius",0.);
-	options->Get(&mindata,"mindata",1);
-	options->Get(&maxdata,"maxdata",50);
+
+	options->Get(&dmindata,"mindata",1.);  mindata=int(dmindata);//FIXME (Options come as double but we want to retrive integers)
+	options->Get(&dmaxdata,"maxdata",50.); maxdata=int(dmaxdata);//FIXME (Options come as double but we want to retrive integers)
 
 	/*Process observation dataset*/
@@ -106,4 +108,17 @@
 		xDelete<double>(predictions); predictions=sumpredictions;
 	}
+	else if(strcmp(output,"distance")==0){
+
+		/*partition loop across threads: */
+		for(int idx=my_rank;idx<n_interp;idx+=num_procs){
+			_printf0_("      interpolation progress: "<<setw(6)<<setprecision(4)<<double(idx)/double(n_interp)*100.<<"%  \n");
+			observations->Distances(&predictions[idx],&x_interp[idx],&y_interp[idx],1,radius);
+		}
+		_printf0_("      interpolation progress: "<<fixed<<setw(6)<<setprecision(4)<<100.<<"%  \n");
+
+		double *sumpredictions =xNew<double>(n_interp);
+		ISSM_MPI_Allreduce(predictions,sumpredictions,n_interp,ISSM_MPI_PDOUBLE,ISSM_MPI_SUM,IssmComm::GetComm());
+		xDelete<double>(predictions); predictions=sumpredictions;
+	}
 	else if(strcmp(output,"idw")==0){
 		double power;
Index: /issm/trunk/src/c/modules/MeshPartitionx/MeshPartitionx.h
===================================================================
--- /issm/trunk/src/c/modules/MeshPartitionx/MeshPartitionx.h	(revision 17805)
+++ /issm/trunk/src/c/modules/MeshPartitionx/MeshPartitionx.h	(revision 17806)
@@ -11,5 +11,5 @@
 template <class doubletype> 
 int MeshPartitionx(int** pepart, int** pnpart, int numberofelements,int numberofnodes,int* elements,
-		int numberofelements2d,int numberofnodes2d,doubletype* elements2d,int numlayers,int elements_width, int meshtype,int num_procs){
+		int numberofelements2d,int numberofnodes2d,doubletype* elements2d,int numlayers,int elements_width, int meshelementtype,int num_procs){
 
 	int noerr=1;
@@ -31,6 +31,7 @@
 	int  edgecut=1;
 
-	switch(meshtype){
-		case Mesh2DhorizontalEnum:
+	switch(meshelementtype){
+		case TriaEnum:
+		case TetraEnum:
 			epart=xNew<int>(numberofelements);
 			npart=xNew<int>(numberofnodes);
@@ -57,30 +58,5 @@
 			else _error_("At least one processor is required");
 			break;
-		case Mesh2DverticalEnum:
-			epart=xNew<int>(numberofelements);
-			npart=xNew<int>(numberofnodes);
-			index=xNew<int>(elements_width*numberofelements);
-			for (i=0;i<numberofelements;i++){
-				for (j=0;j<elements_width;j++){
-					*(index+elements_width*i+j)=(*(elements+elements_width*i+j))-1; //-1 for C indexing in Metis
-				}
-			}
-
-			/*Partition using Metis:*/
-			if (num_procs>1){
-#ifdef _HAVE_METIS_
-				METIS_PartMeshNodalPatch(&numberofelements,&numberofnodes, index, &etype, &numflag, &num_procs, &edgecut, epart, npart);
-#else
-				_error_("metis has not beed installed. Cannot run with more than 1 cpu");
-#endif
-			}
-			else if (num_procs==1){
-				/*METIS does not know how to deal with one cpu only!*/
-				for (i=0;i<numberofelements;i++) epart[i]=0;
-				for (i=0;i<numberofnodes;i++)    npart[i]=0;
-			}
-			else _error_("At least one processor is required");
-			break;
-		case Mesh3DEnum:
+		case PentaEnum:
 			/*We have a 3d mesh, made of a regularly extruded 2d mesh. We first partition the 2d mesh, then we extrude the partition: */
 
@@ -134,5 +110,5 @@
 			break;
 		default:
-			_error_("mesh type "<<EnumToStringx(meshtype)<<" not supported yet");
+			_error_("mesh type "<<EnumToStringx(meshelementtype)<<" not supported yet");
 	}
 
Index: /issm/trunk/src/c/modules/ModelProcessorx/Control/UpdateElementsAndMaterialsControl.cpp
===================================================================
--- /issm/trunk/src/c/modules/ModelProcessorx/Control/UpdateElementsAndMaterialsControl.cpp	(revision 17805)
+++ /issm/trunk/src/c/modules/ModelProcessorx/Control/UpdateElementsAndMaterialsControl.cpp	(revision 17806)
@@ -45,5 +45,5 @@
 	}
 
-	/*Update elements and materials: */
+	/*Update elements: */
 	counter=0;
 	for (i=0;i<iomodel->numberofelements;i++){
@@ -51,7 +51,4 @@
 			element=(Element*)elements->GetObjectByOffset(counter);
 			element->InputUpdateFromIoModel(i,iomodel); //we need i to index into elements.
-
-			material=(Material*)materials->GetObjectByOffset(counter);
-			material->InputUpdateFromIoModel(i,iomodel); //we need i to index into elements.
 			counter++;
 		}
Index: /issm/trunk/src/c/modules/ModelProcessorx/CreateEdges.cpp
===================================================================
--- /issm/trunk/src/c/modules/ModelProcessorx/CreateEdges.cpp	(revision 17805)
+++ /issm/trunk/src/c/modules/ModelProcessorx/CreateEdges.cpp	(revision 17806)
@@ -23,38 +23,42 @@
 
 	/*Mesh dependent variables*/
-	if(iomodel->meshtype==Mesh2DhorizontalEnum){
-		elementnbv = 3;
-		elementnbe = 3;
-		elementedges         = xNew<int>(elementnbe*2);
-		elementedges_markers = xNew<int>(elementnbe);
-		elementedges[2*0+0] = 1; elementedges[2*0+1] = 2; elementedges_markers[0] = 1;
-		elementedges[2*1+0] = 2; elementedges[2*1+1] = 0; elementedges_markers[1] = 1;
-		elementedges[2*2+0] = 0; elementedges[2*2+1] = 1; elementedges_markers[2] = 1;
-	}
-	else if(iomodel->meshtype==Mesh2DverticalEnum){
-		elementnbv = 3;
-		elementnbe = 3;
-		elementedges         = xNew<int>(elementnbe*2);
-		elementedges_markers = xNew<int>(elementnbe);
-		elementedges[2*0+0] = 1; elementedges[2*0+1] = 2; elementedges_markers[0] = 1;
-		elementedges[2*1+0] = 2; elementedges[2*1+1] = 0; elementedges_markers[1] = 1;
-		elementedges[2*2+0] = 0; elementedges[2*2+1] = 1; elementedges_markers[2] = 1;
-	}
-	else if(iomodel->meshtype==Mesh3DEnum){
-		elementnbv = 6;
-		elementnbe = 9;
-		elementedges         = xNew<int>(elementnbe*2);
-		elementedges_markers = xNew<int>(elementnbe);
-		elementedges[2*0+0] = 0; elementedges[2*0+1] = 3; elementedges_markers[0] = 2;
-		elementedges[2*1+0] = 1; elementedges[2*1+1] = 4; elementedges_markers[1] = 2;
-		elementedges[2*2+0] = 2; elementedges[2*2+1] = 5; elementedges_markers[2] = 2;
-		elementedges[2*3+0] = 1; elementedges[2*3+1] = 2; elementedges_markers[3] = 1;
-		elementedges[2*4+0] = 2; elementedges[2*4+1] = 0; elementedges_markers[4] = 1;
-		elementedges[2*5+0] = 0; elementedges[2*5+1] = 1; elementedges_markers[5] = 1;
-		elementedges[2*6+0] = 4; elementedges[2*6+1] = 5; elementedges_markers[6] = 3;
-		elementedges[2*7+0] = 5; elementedges[2*7+1] = 3; elementedges_markers[7] = 3;
-		elementedges[2*8+0] = 3; elementedges[2*8+1] = 4; elementedges_markers[8] = 3;
-	}
-	else{
+	switch(iomodel->meshelementtype){
+		case TriaEnum:
+			elementnbv = 3;
+			elementnbe = 3;
+			elementedges         = xNew<int>(elementnbe*2);
+			elementedges_markers = xNew<int>(elementnbe);
+			elementedges[2*0+0] = 1; elementedges[2*0+1] = 2; elementedges_markers[0] = 1;
+			elementedges[2*1+0] = 2; elementedges[2*1+1] = 0; elementedges_markers[1] = 1;
+			elementedges[2*2+0] = 0; elementedges[2*2+1] = 1; elementedges_markers[2] = 1;
+			break;
+		case TetraEnum:
+			elementnbv = 4;
+			elementnbe = 6;
+			elementedges         = xNew<int>(elementnbe*2);
+			elementedges_markers = xNew<int>(elementnbe);
+			elementedges[2*0+0] = 1; elementedges[2*0+1] = 2; elementedges_markers[0] = 1;
+			elementedges[2*1+0] = 2; elementedges[2*1+1] = 0; elementedges_markers[1] = 1;
+			elementedges[2*2+0] = 0; elementedges[2*2+1] = 1; elementedges_markers[2] = 1;
+			elementedges[2*3+0] = 0; elementedges[2*3+1] = 3; elementedges_markers[3] = 1;
+			elementedges[2*4+0] = 1; elementedges[2*4+1] = 3; elementedges_markers[4] = 1;
+			elementedges[2*5+0] = 2; elementedges[2*5+1] = 3; elementedges_markers[5] = 1;
+			break;
+		case PentaEnum:
+			elementnbv = 6;
+			elementnbe = 9;
+			elementedges         = xNew<int>(elementnbe*2);
+			elementedges_markers = xNew<int>(elementnbe);
+			elementedges[2*0+0] = 0; elementedges[2*0+1] = 3; elementedges_markers[0] = 2;
+			elementedges[2*1+0] = 1; elementedges[2*1+1] = 4; elementedges_markers[1] = 2;
+			elementedges[2*2+0] = 2; elementedges[2*2+1] = 5; elementedges_markers[2] = 2;
+			elementedges[2*3+0] = 1; elementedges[2*3+1] = 2; elementedges_markers[3] = 1;
+			elementedges[2*4+0] = 2; elementedges[2*4+1] = 0; elementedges_markers[4] = 1;
+			elementedges[2*5+0] = 0; elementedges[2*5+1] = 1; elementedges_markers[5] = 1;
+			elementedges[2*6+0] = 4; elementedges[2*6+1] = 5; elementedges_markers[6] = 1;
+			elementedges[2*7+0] = 5; elementedges[2*7+1] = 3; elementedges_markers[7] = 1;
+			elementedges[2*8+0] = 3; elementedges[2*8+1] = 4; elementedges_markers[8] = 1;
+			break;
+		default:
 		_error_("mesh dimension not supported yet");
 	}
Index: /issm/trunk/src/c/modules/ModelProcessorx/CreateElementsVerticesAndMaterials.cpp
===================================================================
--- /issm/trunk/src/c/modules/ModelProcessorx/CreateElementsVerticesAndMaterials.cpp	(revision 17805)
+++ /issm/trunk/src/c/modules/ModelProcessorx/CreateElementsVerticesAndMaterials.cpp	(revision 17806)
@@ -26,18 +26,16 @@
 	/*Create elements*/
 	if(control_analysis)iomodel->FetchData(3,InversionControlParametersEnum,InversionMinParametersEnum,InversionMaxParametersEnum);
-	switch(iomodel->meshtype){
-		case Mesh2DhorizontalEnum:
-			materials->InputDuplicate(MaterialsRheologyBbarEnum,QmuMaterialsRheologyBEnum);
+	switch(iomodel->meshelementtype){
+		case TriaEnum:
 			for(i=0;i<iomodel->numberofelements;i++){
 				if(iomodel->my_elements[i]) elements->AddObject(new Tria(i+1,i,i,iomodel,nummodels));
 			}
 			break;
-		case Mesh2DverticalEnum:
+		case TetraEnum:
 			for(i=0;i<iomodel->numberofelements;i++){
-				if(iomodel->my_elements[i]) elements->AddObject(new Tria(i+1,i,i,iomodel,nummodels));
+				if(iomodel->my_elements[i]) elements->AddObject(new Tetra(i+1,i,i,iomodel,nummodels));
 			}
 			break;
-		#ifdef _HAVE_3D_
-		case Mesh3DEnum:
+		case PentaEnum:
 			iomodel->FetchData(2,MeshUpperelementsEnum,MeshLowerelementsEnum);
 			for(i=0;i<iomodel->numberofelements;i++){
@@ -45,5 +43,4 @@
 			}
 			break;
-		#endif
 		default:
 			_error_("Mesh not supported yet");
@@ -53,19 +50,35 @@
 	switch(materials_type){
 		case MaticeEnum:
-			iomodel->FetchData(3,MaterialsRheologyBEnum,MaterialsRheologyNEnum,DamageDEnum);
+			iomodel->FetchDataToInput(elements,MaterialsRheologyBEnum);
+			iomodel->FetchDataToInput(elements,MaterialsRheologyNEnum);
 			for (i=0;i<iomodel->numberofelements;i++) if(iomodel->my_elements[i]) materials->AddObject(new Matice(i+1,i,iomodel));
-			if(dakota_analysis){
-				switch(iomodel->meshtype){
-					case Mesh2DhorizontalEnum:
-						materials->InputDuplicate(MaterialsRheologyBbarEnum,QmuMaterialsRheologyBEnum);
-						break;
-				   #ifdef _HAVE_3D_
-					case Mesh3DEnum:
-						materials->InputDuplicate(MaterialsRheologyBEnum,QmuMaterialsRheologyBEnum); 
-						break;
-				   #endif
-					default:
-						_error_("Mesh not supported yet");
-				}
+			switch(iomodel->domaindim){
+				case 2:
+					elements->InputDuplicate(MaterialsRheologyBEnum,MaterialsRheologyBbarEnum);
+					if(dakota_analysis) elements->InputDuplicate(MaterialsRheologyBbarEnum,QmuMaterialsRheologyBEnum);
+					break;
+				case 3:
+					if(dakota_analysis) elements->InputDuplicate(MaterialsRheologyBEnum,QmuMaterialsRheologyBEnum); 
+					break;
+				default:
+					_error_("Mesh not supported yet");
+			}
+			break;
+		case MatdamageiceEnum:
+			iomodel->FetchDataToInput(elements,MaterialsRheologyBEnum);
+			iomodel->FetchDataToInput(elements,MaterialsRheologyNEnum);
+			iomodel->FetchDataToInput(elements,DamageDEnum);
+			for (i=0;i<iomodel->numberofelements;i++) if(iomodel->my_elements[i]) materials->AddObject(new Matice(i+1,i,iomodel));
+			switch(iomodel->domaindim){
+				case 2:
+					elements->InputDuplicate(MaterialsRheologyBEnum,MaterialsRheologyBbarEnum);
+					elements->InputDuplicate(DamageDEnum,DamageDbarEnum);
+					if(dakota_analysis) elements->InputDuplicate(MaterialsRheologyBbarEnum,QmuMaterialsRheologyBEnum);
+					break;
+				case 3:
+					if(dakota_analysis) elements->InputDuplicate(MaterialsRheologyBEnum,QmuMaterialsRheologyBEnum); 
+					break;
+				default:
+					_error_("Mesh not supported yet");
 			}
 			break;
@@ -85,5 +98,5 @@
 
 	/*Fetch data:*/
-	iomodel->FetchData(6,MeshXEnum,MeshYEnum,MeshZEnum,BedEnum,ThicknessEnum,MaskIceLevelsetEnum);
+	iomodel->FetchData(6,MeshXEnum,MeshYEnum,MeshZEnum,BaseEnum,ThicknessEnum,MaskIceLevelsetEnum);
 	CreateNumberNodeToElementConnectivity(iomodel);
 
@@ -93,4 +106,4 @@
 
 	/*Free data: */
-	iomodel->DeleteData(6,MeshXEnum,MeshYEnum,MeshZEnum,BedEnum,ThicknessEnum,MaskIceLevelsetEnum);
+	iomodel->DeleteData(6,MeshXEnum,MeshYEnum,MeshZEnum,BaseEnum,ThicknessEnum,MaskIceLevelsetEnum);
 }
Index: /issm/trunk/src/c/modules/ModelProcessorx/CreateFaces.cpp
===================================================================
--- /issm/trunk/src/c/modules/ModelProcessorx/CreateFaces.cpp	(revision 17805)
+++ /issm/trunk/src/c/modules/ModelProcessorx/CreateFaces.cpp	(revision 17806)
@@ -5,14 +5,26 @@
 #include "../../classes/classes.h"
 #include "../../shared/shared.h"
-
-void CreateFaces(IoModel* iomodel){
+#include "./ModelProcessorx.h"
+
+void CreateFaces(IoModel* iomodel){/*{{{*/
 
 	/*If faces are already present, exit*/
 	if(iomodel->faces) return;
 
-	/*Check Iomodel properties*/
-	if(iomodel->meshtype!=Mesh2DhorizontalEnum)             _error_("only 2d model are supported");
+	/*Some checks*/
 	if(iomodel->numberofvertices<3) _error_("not enough elements in mesh");
 	_assert_(iomodel->elements);
+
+	/*Check Iomodel properties*/
+	if(iomodel->domaintype==Domain2DhorizontalEnum || iomodel->domaintype==Domain2DverticalEnum){
+		/*Keep going*/
+	}
+	else if(iomodel->domaintype==Domain3DEnum){
+		CreateFaces3d(iomodel);
+		return;
+	}
+	else{
+		_error_("mesh dimension not supported yet");
+	}
 
 	/*Intermediaries*/
@@ -31,5 +43,5 @@
 	/*Initialize chain*/
 	int* head_minv = xNew<int>(iomodel->numberofvertices);
-	int* next_edge = xNew<int>(maxnbf);
+	int* next_face = xNew<int>(maxnbf);
 	for(i=0;i<iomodel->numberofvertices;i++) head_minv[i]=-1;
 
@@ -57,5 +69,5 @@
 			/*Go through all processed faces connected to v1 and check whether we have seen this edge yet*/
 			_assert_(v1>=0 && v1<iomodel->numberofvertices);
-			for(int e=head_minv[v1]; e!=-1; e=next_edge[e]){
+			for(int e=head_minv[v1]; e!=-1; e=next_face[e]){
 				if(facestemp[e*4+1]==v2){
 					exist = true;
@@ -76,5 +88,5 @@
 
 				/*Update chain*/
-				next_edge[nbf] = head_minv[v1];
+				next_face[nbf] = head_minv[v1];
 				head_minv[v1]  = nbf;
 
@@ -87,5 +99,5 @@
 	/*Clean up*/
 	xDelete<int>(head_minv);
-	xDelete<int>(next_edge);
+	xDelete<int>(next_face);
 
 	/*Create final faces*/
@@ -109,3 +121,191 @@
 	iomodel->faces         = faces;
 	iomodel->numberoffaces = nbf;
-}
+}/*}}}*/
+void CreateFaces3d(IoModel* iomodel){/*{{{*/
+
+	/*Intermediaries*/
+	bool exist;
+	int  i,j,k,v0,cols;
+	int  maxnbf,nbf,elementnbf,elementnbv,facemaxnbv;
+	int *elementfaces         = NULL;
+	int *elementfaces_markers = NULL;
+
+	/*Maximum number of faces*/
+	maxnbf = 5*iomodel->numberofelements;
+
+	/*Initialize intermediaries*/
+	int*  facestemp = xNew<int>(maxnbf*6);         /*format: [vertex1 vertex2 vertex3 element1 element2 marker]    */
+	for(i=0;i<maxnbf;i++) facestemp[i*6+4]=-1;     /*Initialize last column of faces as -1 (boundary face)         */
+
+	/*Initialize chain*/
+	int* head_minv = xNew<int>(iomodel->numberofvertices);
+	int* next_face = xNew<int>(maxnbf);
+	for(i=0;i<iomodel->numberofvertices;i++) head_minv[i]=-1;
+
+	/*Mesh specific face indexing per element*/
+	if(iomodel->meshelementtype==PentaEnum){
+		elementnbv = 6; /*Number of vertices per element*/
+		elementnbf = 5; /*Number of faces per element*/
+		facemaxnbv = 4; /*Maximum number of vertices per face*/
+		cols       = facemaxnbv + 1;
+		elementfaces         = xNew<int>(elementnbf*cols);
+		elementfaces_markers = xNew<int>(elementnbf);
+		/*2 triangles*/
+		elementfaces_markers[0] = 1;
+		elementfaces_markers[1] = 1;
+		elementfaces[cols*0+0] = 3; elementfaces[cols*0+1] = 0;  elementfaces[cols*0+2] = 1; elementfaces[cols*0+3] = 2;
+		elementfaces[cols*1+0] = 3; elementfaces[cols*1+1] = 3;  elementfaces[cols*1+2] = 4; elementfaces[cols*1+3] = 5;
+		/*3 quads*/
+		elementfaces_markers[2] = 2;
+		elementfaces_markers[3] = 2;
+		elementfaces_markers[4] = 2;
+		elementfaces[cols*2+0] = 4; elementfaces[cols*2+1] = 1;  elementfaces[cols*2+2] = 2; elementfaces[cols*2+3] = 5;  elementfaces[cols*2+4] = 4;
+		elementfaces[cols*3+0] = 4; elementfaces[cols*3+1] = 2;  elementfaces[cols*3+2] = 0; elementfaces[cols*3+3] = 3;  elementfaces[cols*3+4] = 5;
+		elementfaces[cols*4+0] = 4; elementfaces[cols*4+1] = 0;  elementfaces[cols*4+2] = 1; elementfaces[cols*4+3] = 4;  elementfaces[cols*4+4] = 3;
+	}
+	else{
+		_error_("mesh dimension not supported yet");
+	}
+	int *element_face_connectivity = xNew<int>(iomodel->numberofelements*elementnbf); /*format: [face1 face2 ...] */
+
+	/*Initialize number of faces and list of vertex indices*/
+	nbf = 0;
+	int* v = xNew<int>(facemaxnbv);
+
+	for(i=0;i<iomodel->numberofelements;i++){
+		for(j=0;j<elementnbf;j++){
+
+			/*Get indices of current face*/
+			for(k=0;k<elementfaces[cols*j+0];k++){
+				v[k] = iomodel->elements[i*elementnbv + elementfaces[cols*j+k+1]] - 1;
+			}
+
+			/*Sort list of vertices*/
+			HeapSort(v,elementfaces[cols*j+0]);
+			v0 = v[0];
+
+			/*This face a priori has not been processed yet*/
+			exist = false;
+
+			/*Go through all processed faces connected to v1 and check whether we have seen this edge yet*/
+			_assert_(v0>=0 && v0<iomodel->numberofvertices);
+			for(int e=head_minv[v0]; e!=-1; e=next_face[e]){
+				if(facestemp[e*6+1]==v[1]+1 && facestemp[e*6+2]==v[2]+1){
+					exist = true;
+					facestemp[e*6+4]=i+1;
+					element_face_connectivity[i*elementnbf+j]=e;
+					break;
+				}
+			}
+
+			/*If this face is new, add it to the lists*/
+			if(!exist){
+				_assert_(nbf<maxnbf);
+
+				/*Update faces*/
+				facestemp[nbf*6+0] = v[0]+1;
+				facestemp[nbf*6+1] = v[1]+1;
+				facestemp[nbf*6+2] = v[2]+1;
+				facestemp[nbf*6+3] = i+1;
+				facestemp[nbf*6+5] = elementfaces_markers[j];
+
+				/*Update Connectivity*/
+				element_face_connectivity[i*elementnbf+j]=nbf;
+
+				/*Update chain*/
+				next_face[nbf] = head_minv[v0];
+				head_minv[v0]  = nbf;
+
+				/*Increase number of faces*/
+				nbf++;
+			}
+		}
+	}
+
+	/*Clean up*/
+	xDelete<int>(head_minv);
+	xDelete<int>(next_face);
+	xDelete<int>(v);
+	xDelete<int>(elementfaces);
+	xDelete<int>(elementfaces_markers);
+
+	/*Create final faces (now that we have the correct size)*/
+	int* faces = xNew<int>(nbf*6); /*vertex1 vertex2 vertex3 element1 element2 marker*/
+	xMemCpy<int>(faces,facestemp,nbf*6);
+	xDelete<int>(facestemp);
+
+	/*Assign output pointers*/
+	iomodel->faces                     = faces;
+	iomodel->numberoffaces             = nbf;
+	iomodel->elementtofaceconnectivity = element_face_connectivity;
+}/*}}}*/
+void FaceGetVertexIndices(IoModel* iomodel,int* pnumvertices,int** pverticesid,int facenumber){/*{{{*/
+
+	int numbervertices;
+	if(iomodel->domaintype==Domain3DEnum){
+		if((iomodel->faces[6*facenumber+5])==1){
+			numbervertices=3;
+		}
+		else if((iomodel->faces[6*facenumber+5])==2){
+			numbervertices=4;
+		}
+		else _error_("face marker not supported yet ");
+	}
+	else _error_("mesh type not supported yet");
+
+	int* facevertices = xNew<int>(numbervertices);
+	if(numbervertices==3){
+		for(int i=0;i<3;i++) facevertices[i]=iomodel->faces[6*facenumber+i]-1;
+	}
+	else if(numbervertices==4){
+		int  i,j,k,cols,faceid;
+		int  maxnbf,nbf,elementnbf,elementnbv,facemaxnbv;
+		int *elementfaces         = NULL;
+		int *elementfaces_markers = NULL;
+		int elementid=iomodel->faces[6*facenumber+3];
+		int counter=0;
+
+		/*Recreate element properties*/
+		elementnbv = 6; /*Number of vertices per element*/
+		elementnbf = 5; /*Number of faces per element*/
+		facemaxnbv = 4; /*Maximum number of vertices per face*/
+		cols       = facemaxnbv + 1;
+		elementfaces         = xNew<int>(elementnbf*cols);
+		elementfaces_markers = xNew<int>(elementnbf);
+		/*2 triangles*/
+		elementfaces_markers[0] = 1;
+		elementfaces_markers[1] = 1;
+		elementfaces[cols*0+0] = 3; elementfaces[cols*0+1] = 0;  elementfaces[cols*0+2] = 1; elementfaces[cols*0+3] = 2;
+		elementfaces[cols*1+0] = 3; elementfaces[cols*1+1] = 3;  elementfaces[cols*1+2] = 4; elementfaces[cols*1+3] = 5;
+		/*3 quads*/
+		elementfaces_markers[2] = 2;
+		elementfaces_markers[3] = 2;
+		elementfaces_markers[4] = 2;
+		elementfaces[cols*2+0] = 4; elementfaces[cols*2+1] = 1;  elementfaces[cols*2+2] = 2; elementfaces[cols*2+3] = 5;  elementfaces[cols*2+4] = 4;
+		elementfaces[cols*3+0] = 4; elementfaces[cols*3+1] = 2;  elementfaces[cols*3+2] = 0; elementfaces[cols*3+3] = 3;  elementfaces[cols*3+4] = 5;
+		elementfaces[cols*4+0] = 4; elementfaces[cols*4+1] = 0;  elementfaces[cols*4+2] = 1; elementfaces[cols*4+3] = 4;  elementfaces[cols*4+4] = 3;
+
+		for(faceid=2;faceid<5;faceid++){
+			counter=0;
+			for(j=0;j<3;j++){
+				for(k=1;k<5;k++){
+					if(iomodel->elements[(elementid-1)*6+elementfaces[cols*faceid+k]] == iomodel->faces[6*facenumber+j]) counter++;
+				}
+			}
+			if(counter==3) break;
+		}
+		if(counter!=3) _error_("face not found in element");
+
+		for(j=0;j<4;j++){
+			facevertices[j]=iomodel->elements[(elementid-1)*6+elementfaces[cols*faceid+j+1]];
+		}
+
+		/*Delete*/
+		xDelete<int>(elementfaces);
+		xDelete<int>(elementfaces_markers);
+	}
+
+	/*Output results*/
+	*pverticesid=facevertices;
+	*pnumvertices=numbervertices;
+}/*}}}*/
Index: /issm/trunk/src/c/modules/ModelProcessorx/CreateNodes.cpp
===================================================================
--- /issm/trunk/src/c/modules/ModelProcessorx/CreateNodes.cpp	(revision 17805)
+++ /issm/trunk/src/c/modules/ModelProcessorx/CreateNodes.cpp	(revision 17806)
@@ -12,5 +12,8 @@
 
 	/*Intermediaries*/
-	int   i,j,counter,lid=0;
+	int   i,j,counter,vnodes,lid=0;
+	int   numberoffaces;
+	int   id0 = iomodel->nodecounter;
+	bool *my_faces = NULL;
 	bool *my_edges = NULL;
 	bool *my_nodes = NULL;
@@ -21,5 +24,5 @@
 			for(i=0;i<iomodel->numberofvertices;i++){
 				if(iomodel->my_vertices[i]){
-					nodes->AddObject(new Node(iomodel->nodecounter+i+1,i,lid++,i,iomodel,analysis,approximation));
+					nodes->AddObject(new Node(id0+i+1,i,lid++,i,iomodel,analysis,approximation));
 				}
 			}
@@ -31,5 +34,5 @@
 				for(j=0;j<3;j++){
 					if(my_nodes[3*i+j]){ 
-						nodes->AddObject(new Node(iomodel->nodecounter+3*i+j+1,iomodel->nodecounter+3*i+j,lid++,iomodel->elements[+3*i+j]-1,iomodel,analysis,approximation));
+						nodes->AddObject(new Node(id0+3*i+j+1,id0+3*i+j,lid++,iomodel->elements[+3*i+j]-1,iomodel,analysis,approximation));
 
 					}
@@ -41,10 +44,10 @@
 			for(i=0;i<iomodel->numberofvertices;i++){
 				if(iomodel->my_vertices[i]){
-					nodes->AddObject(new Node(iomodel->nodecounter+i+1,i,lid++,i,iomodel,analysis,approximation));
+					nodes->AddObject(new Node(id0+i+1,i,lid++,i,iomodel,analysis,approximation));
 				}
 			}
 			for(i=0;i<iomodel->numberofelements;i++){
 				if(iomodel->my_elements[i]){
-					nodes->AddObject(new Node(iomodel->nodecounter+iomodel->numberofvertices+i+1,iomodel->numberofvertices+i,lid++,0,iomodel,analysis,approximation));
+					nodes->AddObject(new Node(id0+iomodel->numberofvertices+i+1,iomodel->numberofvertices+i,lid++,0,iomodel,analysis,approximation));
 				}
 			}
@@ -54,10 +57,10 @@
 			for(i=0;i<iomodel->numberofvertices;i++){
 				if(iomodel->my_vertices[i]){
-					nodes->AddObject(new Node(iomodel->nodecounter+i+1,i,lid++,i,iomodel,analysis,approximation));
+					nodes->AddObject(new Node(id0+i+1,i,lid++,i,iomodel,analysis,approximation));
 				}
 			}
 			for(i=0;i<iomodel->numberofelements;i++){
 				if(iomodel->my_elements[i]){
-					node = new Node(iomodel->nodecounter+iomodel->numberofvertices+i+1,iomodel->numberofvertices+i,lid++,0,iomodel,analysis,approximation);
+					node = new Node(id0+iomodel->numberofvertices+i+1,iomodel->numberofvertices+i,lid++,0,iomodel,analysis,approximation);
 					node->Deactivate();
 					nodes->AddObject(node);
@@ -70,5 +73,5 @@
 			for(i=0;i<iomodel->numberofvertices;i++){
 				if(iomodel->my_vertices[i]){
-					nodes->AddObject(new Node(iomodel->nodecounter+i+1,i,lid++,i,iomodel,analysis,approximation));
+					nodes->AddObject(new Node(id0+i+1,i,lid++,i,iomodel,analysis,approximation));
 				}
 			}
@@ -78,5 +81,5 @@
 				if(iomodel->edges[i*3+2]==2){
 					if(my_edges[i]){
-						node = new Node(iomodel->nodecounter+iomodel->numberofvertices+i+1,counter+1,lid++,0,iomodel,analysis,approximation);
+						node = new Node(id0+iomodel->numberofvertices+i+1,counter+1,lid++,0,iomodel,analysis,approximation);
 						nodes->AddObject(node);
 					}
@@ -85,9 +88,32 @@
 			}
 			break;
+
+		case P1xP3Enum:
+			EdgesPartitioning(&my_edges,iomodel);
+			for(i=0;i<iomodel->numberofvertices;i++){
+				if(iomodel->my_vertices[i]){
+					nodes->AddObject(new Node(id0+i+1,i,lid++,i,iomodel,analysis,approximation));
+				}
+			}
+
+			counter = iomodel->numberofvertices;
+			for(i=0;i<iomodel->numberofedges;i++){
+				if(iomodel->edges[i*3+2]==2){
+					if(my_edges[i]){
+						node = new Node(id0+iomodel->numberofvertices+2*i+1,counter+1,lid++,0,iomodel,analysis,approximation);
+						nodes->AddObject(node);
+						node = new Node(id0+iomodel->numberofvertices+2*i+2,counter+2,lid++,0,iomodel,analysis,approximation);
+						nodes->AddObject(node);
+					}
+					counter=counter+2;
+				}
+			}
+			break;
+
 		case P2xP1Enum:
 			EdgesPartitioning(&my_edges,iomodel);
 			for(i=0;i<iomodel->numberofvertices;i++){
 				if(iomodel->my_vertices[i]){
-					nodes->AddObject(new Node(iomodel->nodecounter+i+1,i,lid++,i,iomodel,analysis,approximation));
+					nodes->AddObject(new Node(id0+i+1,i,lid++,i,iomodel,analysis,approximation));
 				}
 			}
@@ -97,5 +123,5 @@
 				if(iomodel->edges[i*3+2]!=2){
 					if(my_edges[i]){
-						node = new Node(iomodel->nodecounter+iomodel->numberofvertices+i+1,counter+1,lid++,0,iomodel,analysis,approximation);
+						node = new Node(id0+iomodel->numberofvertices+i+1,counter+1,lid++,0,iomodel,analysis,approximation);
 						nodes->AddObject(node);
 					}
@@ -109,10 +135,81 @@
 			for(i=0;i<iomodel->numberofvertices;i++){
 				if(iomodel->my_vertices[i]){
-					nodes->AddObject(new Node(iomodel->nodecounter+i+1,i,lid++,i,iomodel,analysis,approximation));
+					nodes->AddObject(new Node(id0+i+1,i,lid++,i,iomodel,analysis,approximation));
 				}
 			}
 			for(i=0;i<iomodel->numberofedges;i++){
 				if(my_edges[i]){
-					nodes->AddObject(new Node(iomodel->nodecounter+iomodel->numberofvertices+i+1,iomodel->numberofvertices+i,lid++,0,iomodel,analysis,approximation));
+					nodes->AddObject(new Node(id0+iomodel->numberofvertices+i+1,iomodel->numberofvertices+i,lid++,0,iomodel,analysis,approximation));
+				}
+			}
+			id0 = id0+iomodel->numberofvertices+iomodel->numberofedges;
+	      if(iomodel->meshelementtype==PentaEnum){
+				FacesPartitioning(&my_faces,iomodel);
+				for(i=0;i<iomodel->numberoffaces;i++){
+					if(iomodel->faces[i*6+5]==2){/*Vertical quads*/
+						if(my_faces[i]){
+							node = new Node(id0+i+1,iomodel->numberofvertices+iomodel->numberofedges+i,lid++,0,iomodel,analysis,approximation);
+							nodes->AddObject(node);
+						}
+					}
+					else if(iomodel->faces[i*6+5]==1){/*Triangular base/top*/
+						/*Nothing*/
+					}
+					else{
+						_error_("not supported");
+					}
+				}
+			}
+			break;
+		case P2xP4Enum:
+			EdgesPartitioning(&my_edges,iomodel);
+			FacesPartitioning(&my_faces,iomodel);
+			for(i=0;i<iomodel->numberofvertices;i++){
+				if(iomodel->my_vertices[i]){
+					nodes->AddObject(new Node(id0+i+1,i,lid++,i,iomodel,analysis,approximation));
+				}
+			}
+			counter = iomodel->numberofvertices;
+			for(i=0;i<iomodel->numberofedges;i++){
+				if(iomodel->edges[i*3+2]==2){/*Vertical edges*/
+					if(my_edges[i]){
+						node = new Node(id0+iomodel->numberofvertices+3*i+1,counter+1,lid++,0,iomodel,analysis,approximation);
+						nodes->AddObject(node);
+						node = new Node(id0+iomodel->numberofvertices+3*i+2,counter+2,lid++,0,iomodel,analysis,approximation);
+						nodes->AddObject(node);
+						node = new Node(id0+iomodel->numberofvertices+3*i+3,counter+3,lid++,0,iomodel,analysis,approximation);
+						nodes->AddObject(node);
+					}
+					counter=counter+3;
+				}
+				else if(iomodel->edges[i*3+2]==1){/*Horizontal edges*/
+					if(my_edges[i]){
+						node = new Node(id0+iomodel->numberofvertices+3*i+1,counter+1,lid++,0,iomodel,analysis,approximation);
+						nodes->AddObject(node);
+					}
+					counter=counter+1;
+				}
+				else{
+					_error_("not supported");
+				}
+			}
+			id0 = id0+iomodel->numberofvertices+3*iomodel->numberofedges;
+			for(i=0;i<iomodel->numberoffaces;i++){
+				if(iomodel->faces[i*6+5]==2){/*Vertical quads*/
+					if(my_faces[i]){
+						node = new Node(id0+3*i+1,counter+1,lid++,0,iomodel,analysis,approximation);
+						nodes->AddObject(node);
+						node = new Node(id0+3*i+2,counter+2,lid++,0,iomodel,analysis,approximation);
+						nodes->AddObject(node);
+						node = new Node(id0+3*i+3,counter+3,lid++,0,iomodel,analysis,approximation);
+						nodes->AddObject(node);
+					}
+					counter=counter+3;
+				}
+				else if(iomodel->faces[i*6+5]==1){/*Triangular base/top*/
+					/*Nothing*/
+				}
+				else{
+					_error_("not supported");
 				}
 			}
@@ -125,11 +222,12 @@
 			for(i=0;i<iomodel->numberofvertices;i++){
 				if(iomodel->my_vertices[i]){
-					nodes->AddObject(new Node(iomodel->nodecounter+i+1,i,lid++,i,iomodel,analysis,FSvelocityEnum));
-				}
-			}
-			/*P1 pressure*/
-			for(i=0;i<iomodel->numberofvertices;i++){
-				if(iomodel->my_vertices[i]){
-					nodes->AddObject(new Node(iomodel->nodecounter+iomodel->numberofvertices+i+1,iomodel->numberofvertices+i,lid++,i,iomodel,analysis,FSpressureEnum));
+					nodes->AddObject(new Node(id0+i+1,i,lid++,i,iomodel,analysis,FSvelocityEnum));
+				}
+			}
+			/*P1 pressure*/
+			vnodes = id0+iomodel->numberofvertices;
+			for(i=0;i<iomodel->numberofvertices;i++){
+				if(iomodel->my_vertices[i]){
+					nodes->AddObject(new Node(vnodes+i+1,iomodel->numberofvertices+i,lid++,i,iomodel,analysis,FSpressureEnum));
 				}
 			}
@@ -140,11 +238,12 @@
 			for(i=0;i<iomodel->numberofvertices;i++){
 				if(iomodel->my_vertices[i]){
-					nodes->AddObject(new Node(iomodel->nodecounter+i+1,i,lid++,i,iomodel,analysis,FSvelocityEnum));
-				}
-			}
-			/*P1 pressure*/
-			for(i=0;i<iomodel->numberofvertices;i++){
-				if(iomodel->my_vertices[i]){
-					nodes->AddObject(new Node(iomodel->nodecounter+iomodel->numberofvertices+i+1,iomodel->numberofvertices+i,lid++,i,iomodel,analysis,FSpressureEnum));
+					nodes->AddObject(new Node(id0+i+1,i,lid++,i,iomodel,analysis,FSvelocityEnum));
+				}
+			}
+			/*P1 pressure*/
+			vnodes = id0+iomodel->numberofvertices;
+			for(i=0;i<iomodel->numberofvertices;i++){
+				if(iomodel->my_vertices[i]){
+					nodes->AddObject(new Node(vnodes+i+1,iomodel->numberofvertices+i,lid++,i,iomodel,analysis,FSpressureEnum));
 				}
 			}
@@ -155,10 +254,10 @@
 			for(i=0;i<iomodel->numberofvertices;i++){
 				if(iomodel->my_vertices[i]){
-					nodes->AddObject(new Node(iomodel->nodecounter+i+1,i,lid++,i,iomodel,analysis,FSvelocityEnum));
+					nodes->AddObject(new Node(id0+i+1,i,lid++,i,iomodel,analysis,FSvelocityEnum));
 				}
 			}
 			for(i=0;i<iomodel->numberofelements;i++){
 				if(iomodel->my_elements[i]){
-					node = new Node(iomodel->nodecounter+iomodel->numberofvertices+i+1,iomodel->numberofvertices+i,lid++,0,iomodel,analysis,FSvelocityEnum);
+					node = new Node(id0+iomodel->numberofvertices+i+1,iomodel->numberofvertices+i,lid++,0,iomodel,analysis,FSvelocityEnum);
 					node->Deactivate();
 					nodes->AddObject(node);
@@ -166,7 +265,8 @@
 			}
 			/*P1 pressure*/
-			for(i=0;i<iomodel->numberofvertices;i++){
-				if(iomodel->my_vertices[i]){
-					nodes->AddObject(new Node(iomodel->nodecounter+iomodel->numberofvertices+iomodel->numberofelements+i+1,iomodel->numberofvertices+iomodel->numberofelements+i,lid++,i,iomodel,analysis,FSpressureEnum));
+			vnodes = id0+iomodel->numberofvertices+iomodel->numberofelements;
+			for(i=0;i<iomodel->numberofvertices;i++){
+				if(iomodel->my_vertices[i]){
+					nodes->AddObject(new Node(vnodes+i+1,iomodel->numberofvertices+iomodel->numberofelements+i,lid++,i,iomodel,analysis,FSpressureEnum));
 				}
 			}
@@ -177,20 +277,22 @@
 			for(i=0;i<iomodel->numberofvertices;i++){
 				if(iomodel->my_vertices[i]){
-					nodes->AddObject(new Node(iomodel->nodecounter+i+1,i,lid++,i,iomodel,analysis,FSvelocityEnum));
+					nodes->AddObject(new Node(id0+i+1,i,lid++,i,iomodel,analysis,FSvelocityEnum));
 				}
 			}
 			for(i=0;i<iomodel->numberofelements;i++){
 				if(iomodel->my_elements[i]){
-					nodes->AddObject(new Node(iomodel->nodecounter+iomodel->numberofvertices+i+1,iomodel->numberofvertices+i,lid++,0,iomodel,analysis,FSvelocityEnum));
-				}
-			}
-			/*P1 pressure*/
-			for(i=0;i<iomodel->numberofvertices;i++){
-				if(iomodel->my_vertices[i]){
-					nodes->AddObject(new Node(iomodel->nodecounter+iomodel->numberofvertices+iomodel->numberofelements+i+1,iomodel->numberofvertices+iomodel->numberofelements+i,lid++,i,iomodel,analysis,FSpressureEnum));
+					nodes->AddObject(new Node(id0+iomodel->numberofvertices+i+1,iomodel->numberofvertices+i,lid++,0,iomodel,analysis,FSvelocityEnum));
+				}
+			}
+			/*P1 pressure*/
+			vnodes = id0+iomodel->numberofvertices+iomodel->numberofelements;
+			for(i=0;i<iomodel->numberofvertices;i++){
+				if(iomodel->my_vertices[i]){
+					nodes->AddObject(new Node(vnodes+i+1,iomodel->numberofvertices+iomodel->numberofelements+i,lid++,i,iomodel,analysis,FSpressureEnum));
 				}
 			}
 			break;
 		case TaylorHoodEnum:
+		case XTaylorHoodEnum:
 			_assert_(approximation==FSApproximationEnum);
 			/*P2 velocity*/
@@ -198,18 +300,107 @@
 			for(i=0;i<iomodel->numberofvertices;i++){
 				if(iomodel->my_vertices[i]){
-					nodes->AddObject(new Node(iomodel->nodecounter+i+1,i,lid++,i,iomodel,analysis,FSvelocityEnum));
+					nodes->AddObject(new Node(id0+i+1,i,lid++,i,iomodel,analysis,FSvelocityEnum));
 				}
 			}
 			for(i=0;i<iomodel->numberofedges;i++){
 				if(my_edges[i]){
-					nodes->AddObject(new Node(iomodel->nodecounter+iomodel->numberofvertices+i+1,iomodel->numberofvertices+i,lid++,0,iomodel,analysis,FSvelocityEnum));
-				}
-			}
-
-			/*P1 pressure*/
-			for(i=0;i<iomodel->numberofvertices;i++){
-				if(iomodel->my_vertices[i]){
-					nodes->AddObject(new Node(iomodel->nodecounter+iomodel->numberofvertices+iomodel->numberofedges+i+1,iomodel->numberofvertices+iomodel->numberofedges+i,lid++,i,iomodel,analysis,FSpressureEnum));
-				}
+					nodes->AddObject(new Node(id0+iomodel->numberofvertices+i+1,iomodel->numberofvertices+i,lid++,0,iomodel,analysis,FSvelocityEnum));
+				}
+			}
+			id0 = id0+iomodel->numberofvertices+iomodel->numberofedges;
+	      if(iomodel->meshelementtype==PentaEnum){
+				FacesPartitioning(&my_faces,iomodel);
+				for(i=0;i<iomodel->numberoffaces;i++){
+					if(iomodel->faces[i*6+5]==2){/*Vertical quads*/
+						if(my_faces[i]){
+							node = new Node(id0+i+1,iomodel->numberofvertices+iomodel->numberofedges+i,lid++,0,iomodel,analysis,FSvelocityEnum);
+							nodes->AddObject(node);
+						}
+					}
+					else if(iomodel->faces[i*6+5]==1){/*Triangular base/top*/
+						/*Nothing*/
+					}
+					else{
+						_error_("not supported");
+					}
+				}
+			}
+
+			/*P1 pressure*/
+	      if(iomodel->meshelementtype==PentaEnum){
+				numberoffaces=iomodel->numberoffaces;
+			}
+			else{
+				numberoffaces=0;
+			}
+			vnodes = id0+numberoffaces;
+			for(i=0;i<iomodel->numberofvertices;i++){
+				if(iomodel->my_vertices[i]){
+					nodes->AddObject(new Node(vnodes+i+1,iomodel->numberofvertices+iomodel->numberofedges+numberoffaces+i,lid++,i,iomodel,analysis,FSpressureEnum));
+				}
+			}
+			break;
+		case OneLayerP4zEnum:
+			_assert_(approximation==FSApproximationEnum);
+			EdgesPartitioning(&my_edges,iomodel);
+			FacesPartitioning(&my_faces,iomodel);
+			/*P2xP4 velocity*/
+			for(i=0;i<iomodel->numberofvertices;i++){
+				if(iomodel->my_vertices[i]){
+					nodes->AddObject(new Node(id0+i+1,i,lid++,i,iomodel,analysis,FSvelocityEnum));
+				}
+			}
+			counter = iomodel->numberofvertices;
+			for(i=0;i<iomodel->numberofedges;i++){
+				if(iomodel->edges[i*3+2]==2){/*Vertical edges*/
+					if(my_edges[i]){
+						node = new Node(id0+iomodel->numberofvertices+3*i+1,counter+1,lid++,0,iomodel,analysis,FSvelocityEnum);
+						nodes->AddObject(node);
+						node = new Node(id0+iomodel->numberofvertices+3*i+2,counter+2,lid++,0,iomodel,analysis,FSvelocityEnum);
+						nodes->AddObject(node);
+						node = new Node(id0+iomodel->numberofvertices+3*i+3,counter+3,lid++,0,iomodel,analysis,FSvelocityEnum);
+						nodes->AddObject(node);
+					}
+					counter=counter+3;
+				}
+				else if(iomodel->edges[i*3+2]==1){/*Horizontal edges*/
+					if(my_edges[i]){
+						node = new Node(id0+iomodel->numberofvertices+3*i+1,counter+1,lid++,0,iomodel,analysis,FSvelocityEnum);
+						nodes->AddObject(node);
+					}
+					counter=counter+1;
+				}
+				else{
+					_error_("not supported");
+				}
+			}
+			id0 = id0+iomodel->numberofvertices+3*iomodel->numberofedges;
+			for(i=0;i<iomodel->numberoffaces;i++){
+				if(iomodel->faces[i*6+5]==2){/*Vertical quads*/
+					if(my_faces[i]){
+						node = new Node(id0+3*i+1,counter+1,lid++,0,iomodel,analysis,FSvelocityEnum);
+						nodes->AddObject(node);
+						node = new Node(id0+3*i+2,counter+2,lid++,0,iomodel,analysis,FSvelocityEnum);
+						nodes->AddObject(node);
+						node = new Node(id0+3*i+3,counter+3,lid++,0,iomodel,analysis,FSvelocityEnum);
+						nodes->AddObject(node);
+					}
+					counter=counter+3;
+				}
+				else if(iomodel->faces[i*6+5]==1){/*Triangular base/top*/
+					/*Nothing*/
+				}
+				else{
+					_error_("not supported");
+				}
+			}
+
+			/*P1 pressure*/
+			vnodes = id0+3*iomodel->numberoffaces;
+			for(i=0;i<iomodel->numberofvertices;i++){
+				if(iomodel->my_vertices[i]){
+					nodes->AddObject(new Node(vnodes+i+1,counter+1,lid++,i,iomodel,analysis,FSpressureEnum));
+				}
+				counter++;
 			}
 			break;
@@ -220,4 +411,5 @@
 
 	/*Clean up*/
+	xDelete<bool>(my_faces);
 	xDelete<bool>(my_edges);
 	xDelete<bool>(my_nodes);
Index: /issm/trunk/src/c/modules/ModelProcessorx/CreateNumberNodeToElementConnectivity.cpp
===================================================================
--- /issm/trunk/src/c/modules/ModelProcessorx/CreateNumberNodeToElementConnectivity.cpp	(revision 17805)
+++ /issm/trunk/src/c/modules/ModelProcessorx/CreateNumberNodeToElementConnectivity.cpp	(revision 17806)
@@ -36,8 +36,8 @@
 
 	/*Get element width*/
-	switch(iomodel->meshtype){
-		case Mesh2DhorizontalEnum: elementswidth=3; break;
-		case Mesh2DverticalEnum:   elementswidth=3; break;
-		case Mesh3DEnum:           elementswidth=6; break;
+	switch(iomodel->meshelementtype){
+		case TriaEnum:  elementswidth=3; break;
+		case TetraEnum: elementswidth=4; break;
+		case PentaEnum: elementswidth=6; break;
 		default:                   _error_("mesh not supported yet");
 	}
Index: /issm/trunk/src/c/modules/ModelProcessorx/CreateOutputDefinitions.cpp
===================================================================
--- /issm/trunk/src/c/modules/ModelProcessorx/CreateOutputDefinitions.cpp	(revision 17805)
+++ /issm/trunk/src/c/modules/ModelProcessorx/CreateOutputDefinitions.cpp	(revision 17806)
@@ -8,15 +8,11 @@
 #include "./ModelProcessorx.h"
 
-void CreateOutputDefinitions(Parameters* parameters,IoModel* iomodel){
+void CreateOutputDefinitions(Elements* elements, Parameters* parameters,IoModel* iomodel){
 
 	int i,j;
 	
-	DataSet     *output_definitions      = NULL;
-	int         *output_definition_enums = NULL;
+	DataSet*     output_definitions      = NULL;
+	int*         output_definition_enums = NULL;
 	int          num_output_definitions;
-	int          numgates;
-	char       **gatenames               = NULL;
-	IssmDouble **gatesegments            = NULL;
-	int         *gatesegments_M          = NULL;
 
 	/*Create output_definitions dataset: */
@@ -28,5 +24,13 @@
 
 			if (output_definition_enums[i]==MassfluxatgateEnum){
+
 				/*Deal with mass flux gates:{{{ */
+				
+				/*massfluxatgate variables: */
+				int          numgates;
+				char       **gatenames               = NULL;
+				IssmDouble **gatesegments            = NULL;
+				int         *gatesegments_M          = NULL;
+
 
 				/*Fetch segments and names: */
@@ -47,4 +51,68 @@
 				/*}}}*/
 			}
+			else if (output_definition_enums[i]==MisfitEnum){
+				/*Deal with misfits: {{{*/
+				
+				/*misfit variables: */
+				int          nummisfits;
+				char**       misfit_name_s             = NULL;    
+				int*         misfit_model_enum_s        = NULL;
+				IssmDouble** misfit_observation_s      = NULL;
+				int*         misfit_observation_enum_s  = NULL;
+				int*         misfit_observation_M_s    = NULL;
+				int*         misfit_observation_N_s    = NULL;
+				char**       misfit_timeinterpolation_s = NULL;
+				IssmDouble** misfit_weights_s           = NULL;
+				int*         misfit_weights_M_s    = NULL;
+				int*         misfit_weights_N_s    = NULL;
+				int*         misfit_weights_enum_s= NULL;
+
+				/*Fetch name, model_enum, observation, observation_enum, etc ... (see src/m/classes/misfit.m): */
+				iomodel->FetchMultipleData(&misfit_name_s,&nummisfits,MisfitNameEnum);
+				iomodel->FetchMultipleData(&misfit_model_enum_s,&nummisfits,MisfitModelEnumEnum);
+				iomodel->FetchMultipleData(&misfit_observation_s,&misfit_observation_M_s,&misfit_observation_N_s,&nummisfits,MisfitObservationEnum);
+				iomodel->FetchMultipleData(&misfit_observation_enum_s,&nummisfits,MisfitObservationEnumEnum);
+				iomodel->FetchMultipleData(&misfit_timeinterpolation_s,&nummisfits,MisfitTimeinterpolationEnum);
+				iomodel->FetchMultipleData(&misfit_weights_s,&misfit_weights_M_s,&misfit_weights_N_s,&nummisfits,MisfitWeightsEnum);
+				iomodel->FetchMultipleData(&misfit_weights_enum_s,&nummisfits,MisfitWeightsEnumEnum);
+
+				for(j=0;j<nummisfits;j++){
+
+					/*First create a misfit object for that specific enum (misfit_model_enum_s[j]):*/
+					output_definitions->AddObject(new Misfit(misfit_name_s[j],misfit_model_enum_s[j],misfit_observation_enum_s[j],misfit_timeinterpolation_s[j],misfit_weights_enum_s[j]));
+
+					/*Now, for this particular misfit object, make sure we plug into the elements: the observation, and the weights.*/
+					for(i=0;i<elements->Size();i++){
+						Element* element=dynamic_cast<Element*>(elements->GetObjectByOffset(i));
+						element->InputCreate(misfit_observation_s[j], iomodel,misfit_observation_M_s[j],misfit_observation_N_s[j],1,misfit_observation_enum_s[j],7);
+						element->InputCreate(misfit_weights_s[j], iomodel,misfit_weights_M_s[j],misfit_weights_N_s[j],1,misfit_weights_enum_s[j],7);
+					}
+
+				}
+
+				/*Free ressources:*/
+				for(j=0;j<nummisfits;j++){
+					char* string=NULL;
+					IssmDouble* matrix = NULL;
+
+					string = misfit_name_s[j];    xDelete<char>(string);
+					string = misfit_timeinterpolation_s[j];    xDelete<char>(string);
+					matrix = misfit_observation_s[j]; xDelete<IssmDouble>(matrix);
+					matrix = misfit_weights_s[j]; xDelete<IssmDouble>(matrix);
+				}
+				xDelete<char*>(misfit_name_s);
+				xDelete<int>(misfit_model_enum_s);
+				xDelete<IssmDouble*>(misfit_observation_s);
+				xDelete<int>(misfit_observation_enum_s);
+				xDelete<int>(misfit_observation_M_s);
+				xDelete<int>(misfit_observation_N_s);
+				xDelete<char*>(misfit_timeinterpolation_s);
+				xDelete<IssmDouble*>(misfit_weights_s);
+				xDelete<int>(misfit_weights_M_s);
+				xDelete<int>(misfit_weights_N_s);
+				xDelete<int>(misfit_weights_enum_s);
+				/*}}}*/
+			}
+
 			else _error_("output definition enum " << output_definition_enums[i] << "not supported yet!");
 		}
Index: /issm/trunk/src/c/modules/ModelProcessorx/CreateParameters.cpp
===================================================================
--- /issm/trunk/src/c/modules/ModelProcessorx/CreateParameters.cpp	(revision 17805)
+++ /issm/trunk/src/c/modules/ModelProcessorx/CreateParameters.cpp	(revision 17806)
@@ -19,5 +19,5 @@
 
 	int         i,j,m,k;
-	int         numoutputs,meshtype;
+	int         numoutputs,domaintype,materialtype,smb_model;
 	char**      requestedoutputs = NULL;
 	IssmDouble  time;
@@ -41,5 +41,7 @@
 
 	/*Copy some constants from iomodel */
-	parameters->AddObject(iomodel->CopyConstantObject(MeshTypeEnum));
+	parameters->AddObject(iomodel->CopyConstantObject(DomainTypeEnum));
+	parameters->AddObject(iomodel->CopyConstantObject(DomainDimensionEnum));
+	parameters->AddObject(iomodel->CopyConstantObject(MeshElementtypeEnum));
 	parameters->AddObject(iomodel->CopyConstantObject(SettingsOutputFrequencyEnum));
 	parameters->AddObject(iomodel->CopyConstantObject(SteadystateReltolEnum));
@@ -51,10 +53,4 @@
 	parameters->AddObject(iomodel->CopyConstantObject(TimesteppingTimeStepEnum));
 	parameters->AddObject(iomodel->CopyConstantObject(TimesteppingCflCoefficientEnum));
-	parameters->AddObject(iomodel->CopyConstantObject(MasstransportIsfreesurfaceEnum));
-	parameters->AddObject(iomodel->CopyConstantObject(MasstransportHydrostaticAdjustmentEnum));
-	parameters->AddObject(iomodel->CopyConstantObject(MasstransportStabilizationEnum));
-	parameters->AddObject(iomodel->CopyConstantObject(MasstransportMinThicknessEnum));
-	parameters->AddObject(iomodel->CopyConstantObject(MasstransportPenaltyFactorEnum));
-	parameters->AddObject(iomodel->CopyConstantObject(ThermalPenaltyFactorEnum));
 	parameters->AddObject(iomodel->CopyConstantObject(SettingsLowmemEnum));
 	parameters->AddObject(iomodel->CopyConstantObject(DebugProfilingEnum));
@@ -63,11 +59,8 @@
 	parameters->AddObject(iomodel->CopyConstantObject(BalancethicknessStabilizationEnum));
 	parameters->AddObject(iomodel->CopyConstantObject(GroundinglineMeltingRateEnum));
-	parameters->AddObject(iomodel->CopyConstantObject(ThermalMaxiterEnum));
-	parameters->AddObject(iomodel->CopyConstantObject(ThermalStabilizationEnum));
-	parameters->AddObject(iomodel->CopyConstantObject(ThermalPenaltyThresholdEnum));
-	parameters->AddObject(iomodel->CopyConstantObject(ThermalPenaltyLockEnum));
 	parameters->AddObject(iomodel->CopyConstantObject(SettingsWaitonlockEnum));
 	parameters->AddObject(iomodel->CopyConstantObject(MeshNumberofelementsEnum));
 	parameters->AddObject(iomodel->CopyConstantObject(MeshNumberofverticesEnum));
+	parameters->AddObject(iomodel->CopyConstantObject(SettingsResultsOnNodesEnum));
 	parameters->AddObject(iomodel->CopyConstantObject(SettingsIoGatherEnum));
 	parameters->AddObject(iomodel->CopyConstantObject(GroundinglineMigrationEnum));
@@ -77,6 +70,7 @@
 	parameters->AddObject(iomodel->CopyConstantObject(TransientIsgroundinglineEnum));
 	parameters->AddObject(iomodel->CopyConstantObject(TransientIsgiaEnum));
-	parameters->AddObject(iomodel->CopyConstantObject(ThermalIsenthalpyEnum));
-	parameters->AddObject(iomodel->CopyConstantObject(ThermalIsdynamicbasalspcEnum));
+	parameters->AddObject(iomodel->CopyConstantObject(TransientIslevelsetEnum));
+	parameters->AddObject(iomodel->CopyConstantObject(TransientIsdamageevolutionEnum));
+	parameters->AddObject(iomodel->CopyConstantObject(TransientIshydrologyEnum));
 	parameters->AddObject(iomodel->CopyConstantObject(MaterialsRheologyLawEnum));
 	parameters->AddObject(iomodel->CopyConstantObject(AutodiffIsautodiffEnum));
@@ -84,7 +78,4 @@
 	parameters->AddObject(iomodel->CopyConstantObject(InversionIscontrolEnum));
 	parameters->AddObject(iomodel->CopyConstantObject(InversionTaoEnum));
-	parameters->AddObject(iomodel->CopyConstantObject(SurfaceforcingsIspddEnum));
-	parameters->AddObject(iomodel->CopyConstantObject(SurfaceforcingsIsdelta18oEnum));
-	parameters->AddObject(iomodel->CopyConstantObject(SurfaceforcingsIssmbgradientsEnum));
 	parameters->AddObject(iomodel->CopyConstantObject(GiaCrossSectionShapeEnum));
 
@@ -96,31 +87,43 @@
 	parameters->AddObject(iomodel->CopyConstantObject(StressbalanceReltolEnum));
 	parameters->AddObject(iomodel->CopyConstantObject(StressbalanceAbstolEnum));
-	if(iomodel->meshtype==Mesh3DEnum)
+	if(iomodel->domaintype==Domain3DEnum)
 	 parameters->AddObject(iomodel->CopyConstantObject(MeshNumberoflayersEnum));
 
-	iomodel->Constant(&ispdd,SurfaceforcingsIspddEnum);
-	if(ispdd){
-
-		parameters->AddObject(iomodel->CopyConstantObject(SurfaceforcingsDesfacEnum));
-		parameters->AddObject(iomodel->CopyConstantObject(SurfaceforcingsS0pEnum));
-
-		iomodel->Constant(&isdelta18o,SurfaceforcingsIsdelta18oEnum);
-		if(isdelta18o){
-			IssmDouble *temp = NULL;
-			IssmDouble  yts;
-			int         N,M;
-
-			iomodel->Constant(&yts,ConstantsYtsEnum);
-
-			iomodel->FetchData(&temp,&N,&M,SurfaceforcingsDelta18oEnum); _assert_(N==2);
-			for(i=0;i<M;i++) temp[M+i]=yts*temp[M+i];
-			parameters->AddObject(new TransientParam(SurfaceforcingsDelta18oEnum,&temp[0],&temp[M],M));
-			iomodel->DeleteData(temp,SurfaceforcingsDelta18oEnum);
-
-			iomodel->FetchData(&temp,&N,&M,SurfaceforcingsDelta18oSurfaceEnum); _assert_(N==2);
-			for(i=0;i<M;i++) temp[M+i]=yts*temp[M+i];
-			parameters->AddObject(new TransientParam(SurfaceforcingsDelta18oSurfaceEnum,&temp[0],&temp[M],M));
-			iomodel->DeleteData(temp,SurfaceforcingsDelta18oSurfaceEnum);
-		}
+	/*Surface mass balance parameters*/
+	parameters->AddObject(iomodel->CopyConstantObject(SurfaceforcingsEnum));
+	iomodel->Constant(&smb_model,SurfaceforcingsEnum);
+	switch(smb_model){
+		case SMBEnum:
+			/*Nothing to add to parameters*/
+			break;
+		case SMBpddEnum:
+			parameters->AddObject(iomodel->CopyConstantObject(SurfaceforcingsIsdelta18oEnum));
+			parameters->AddObject(iomodel->CopyConstantObject(SurfaceforcingsDesfacEnum));
+			parameters->AddObject(iomodel->CopyConstantObject(SurfaceforcingsS0pEnum));
+			iomodel->Constant(&isdelta18o,SurfaceforcingsIsdelta18oEnum);
+			if(isdelta18o){
+				IssmDouble *temp = NULL;
+				IssmDouble  yts;
+				int         N,M;
+				iomodel->Constant(&yts,ConstantsYtsEnum);
+				iomodel->FetchData(&temp,&N,&M,SurfaceforcingsDelta18oEnum); _assert_(N==2);
+				for(i=0;i<M;i++) temp[M+i]=yts*temp[M+i];
+				parameters->AddObject(new TransientParam(SurfaceforcingsDelta18oEnum,&temp[0],&temp[M],M));
+				iomodel->DeleteData(temp,SurfaceforcingsDelta18oEnum);
+
+				iomodel->FetchData(&temp,&N,&M,SurfaceforcingsDelta18oSurfaceEnum); _assert_(N==2);
+				for(i=0;i<M;i++) temp[M+i]=yts*temp[M+i];
+				parameters->AddObject(new TransientParam(SurfaceforcingsDelta18oSurfaceEnum,&temp[0],&temp[M],M));
+				iomodel->DeleteData(temp,SurfaceforcingsDelta18oSurfaceEnum);
+			}
+			break;
+		case SMBgradientsEnum:
+			/*Nothing to add to parameters*/
+			break;
+		case SMBhenningEnum:
+			/*Nothing to add to parameters*/
+			break;
+		default:
+			_error_("Surface mass balance model "<<EnumToStringx(smb_model)<<" not supported yet");
 	}
 
@@ -129,6 +132,6 @@
 
 	iomodel->Constant(&time,TimesteppingStartTimeEnum);
-	parameters->AddObject(new DoubleParam(TimeEnum,time));  //start at time 0 by default for all solutions FIXME: to be deleted
-	parameters->AddObject(new IntParam(StepEnum,1));  //start at time 0 by default for all solutions FIXME: to be deleted
+	parameters->AddObject(new DoubleParam(TimeEnum,time));  
+	parameters->AddObject(new IntParam(StepEnum,1));  
 
 	/*By default, save all results*/
@@ -146,13 +149,11 @@
 	iomodel->DeleteData(&requestedoutputs,numoutputs,SteadystateRequestedOutputsEnum);
 
-	iomodel->FetchData(&requestedoutputs,&numoutputs,MasstransportRequestedOutputsEnum);
-	parameters->AddObject(new IntParam(MasstransportNumRequestedOutputsEnum,numoutputs));
-	if(numoutputs)parameters->AddObject(new StringArrayParam(MasstransportRequestedOutputsEnum,requestedoutputs,numoutputs));
-	iomodel->DeleteData(&requestedoutputs,numoutputs,MasstransportRequestedOutputsEnum);
-
-	iomodel->FetchData(&requestedoutputs,&numoutputs,ThermalRequestedOutputsEnum);
-	parameters->AddObject(new IntParam(ThermalNumRequestedOutputsEnum,numoutputs));
-	if(numoutputs)parameters->AddObject(new StringArrayParam(ThermalRequestedOutputsEnum,requestedoutputs,numoutputs));
-	iomodel->DeleteData(&requestedoutputs,numoutputs,ThermalRequestedOutputsEnum);
+	iomodel->Constant(&materialtype,MaterialsEnum);
+	if(materialtype==MatdamageiceEnum){
+		iomodel->FetchData(&requestedoutputs,&numoutputs,DamageEvolutionRequestedOutputsEnum);
+		parameters->AddObject(new IntParam(DamageEvolutionNumRequestedOutputsEnum,numoutputs));
+		if(numoutputs)parameters->AddObject(new StringArrayParam(DamageEvolutionRequestedOutputsEnum,requestedoutputs,numoutputs));
+		iomodel->DeleteData(&requestedoutputs,numoutputs,DamageEvolutionRequestedOutputsEnum);
+	}
 
 	/*Deal with mass flux segments: {{{*/
@@ -218,11 +219,7 @@
 	/*}}}*/
 
-	/*Output definitions dataset: */
-	CreateOutputDefinitions(parameters,iomodel);
-
+	
 	/*Before returning, create parameters in case we are running Qmu or control types runs: */
-	#ifdef _HAVE_CONTROL_
 	CreateParametersControl(parameters,iomodel,solution_type);
-	#endif
 
 	#ifdef _HAVE_DAKOTA_
Index: /issm/trunk/src/c/modules/ModelProcessorx/CreateSingleNodeToElementConnectivity.cpp
===================================================================
--- /issm/trunk/src/c/modules/ModelProcessorx/CreateSingleNodeToElementConnectivity.cpp	(revision 17805)
+++ /issm/trunk/src/c/modules/ModelProcessorx/CreateSingleNodeToElementConnectivity.cpp	(revision 17806)
@@ -30,9 +30,9 @@
 
 	/*Get element width (3 or 6)*/
-	if(iomodel->meshtype==Mesh2DhorizontalEnum){
-		elementswidth=3;
-	}
-	else{
-		elementswidth=6;
+	switch(iomodel->domaintype){
+		case Domain2DhorizontalEnum: elementswidth=3; break;
+		case Domain2DverticalEnum  : elementswidth=3; break;
+		case Domain3DEnum          : elementswidth=6; break;
+		default:  _error_("mesh type "<<EnumToStringx(iomodel->domaintype)<<" not supported yet");
 	}
 
Index: /issm/trunk/src/c/modules/ModelProcessorx/EdgesPartitioning.cpp
===================================================================
--- /issm/trunk/src/c/modules/ModelProcessorx/EdgesPartitioning.cpp	(revision 17805)
+++ /issm/trunk/src/c/modules/ModelProcessorx/EdgesPartitioning.cpp	(revision 17806)
@@ -18,16 +18,11 @@
 
 	/*Mesh dependent variables*/
-	if(iomodel->meshtype==Mesh2DhorizontalEnum){
-		elementnbe = 3;
+	switch(iomodel->meshelementtype){
+		case TriaEnum:  elementnbe = 3; break;
+		case TetraEnum: elementnbe = 6; break;
+		case PentaEnum: elementnbe = 9; break;
+		default: _error_("mesh dimension not supported yet");
 	}
-	else if(iomodel->meshtype==Mesh2DverticalEnum){
-		elementnbe = 3;
-	}
-	else if(iomodel->meshtype==Mesh3DEnum){
-		elementnbe = 9;
-	}
-	else{
-		_error_("mesh dimension not supported yet");
-	}
+
 	/*output: */
 	bool* my_edges=xNewZeroInit<bool>(iomodel->numberofedges);
Index: /issm/trunk/src/c/modules/ModelProcessorx/ElementsAndVerticesPartitioning.cpp
===================================================================
--- /issm/trunk/src/c/modules/ModelProcessorx/ElementsAndVerticesPartitioning.cpp	(revision 17805)
+++ /issm/trunk/src/c/modules/ModelProcessorx/ElementsAndVerticesPartitioning.cpp	(revision 17806)
@@ -17,5 +17,5 @@
 void  ElementsAndVerticesPartitioning(bool** pmy_elements, int** pmy_vertices, IoModel* iomodel){
 
-	int i;
+	int i,j;
 
 	const int RIFTINFOSIZE = 12;
@@ -51,6 +51,6 @@
 	/*Number of vertices per elements, needed to correctly retrieve data: */
 	/*Determine parallel partitioning of elements: we use Metis for now. First load the data, then partition*/
-	switch(iomodel->meshtype){
-		case Mesh2DhorizontalEnum:
+	switch(iomodel->meshelementtype){
+		case TriaEnum:
 			elements_width=3;
 			numberofelements2d = 0;
@@ -58,12 +58,12 @@
 			numlayers          = 0;
 			break;
-		case Mesh2DverticalEnum:
-			elements_width=3;
+		case TetraEnum:
+			elements_width=4;
 			numberofelements2d = 0;
 			numberofvertices2d = 0;
 			numlayers          = 0;
 			break;
-		case Mesh3DEnum:
-			elements_width=6; //penta elements
+		case PentaEnum:
+			elements_width=6;
 			iomodel->FetchData(&elements2d,NULL,NULL,MeshElements2dEnum);
 			iomodel->Constant(&numberofelements2d,MeshNumberofelements2dEnum);
@@ -75,5 +75,5 @@
 	}
 
-	MeshPartitionx(&epart,&npart,iomodel->numberofelements,iomodel->numberofvertices,iomodel->elements,numberofelements2d,numberofvertices2d,elements2d,numlayers,elements_width,iomodel->meshtype,num_procs);
+	MeshPartitionx(&epart,&npart,iomodel->numberofelements,iomodel->numberofvertices,iomodel->elements,numberofelements2d,numberofvertices2d,elements2d,numlayers,elements_width,iomodel->meshelementtype,num_procs);
 
 	/*Free elements2d: */
@@ -96,23 +96,15 @@
 
 	/*Start figuring out, out of the partition, which elements belong to this cpu: */
-	for (i=0;i<iomodel->numberofelements;i++){
+	for(i=0;i<iomodel->numberofelements;i++){
 
 		/*!All elements have been partitioned above, only deal with elements for this cpu: */
 		if(my_rank==epart[i]){ 
-
 			my_elements[i]=true;
-
 			/*Now that we are here, we can also start building the list of vertices belonging to this cpu partition: we use 
 			 *the  element index to do this. For each element n, we know index[n][0:2] holds the indices (matlab indexing) 
 			 into the vertices coordinates. If we start plugging 1 into my_vertices for each index[n][i] (i=0:2), then my_vertices 
 			 will hold which vertices belong to this partition*/
-			my_vertices[iomodel->elements[elements_width*i+0]-1]=1;
-			my_vertices[iomodel->elements[elements_width*i+1]-1]=1;
-			my_vertices[iomodel->elements[elements_width*i+2]-1]=1;
-
-			if(elements_width==6){
-				my_vertices[iomodel->elements[elements_width*i+3]-1]=1;
-				my_vertices[iomodel->elements[elements_width*i+4]-1]=1;
-				my_vertices[iomodel->elements[elements_width*i+5]-1]=1;
+			for(j=0;j<elements_width;j++){
+				my_vertices[iomodel->elements[elements_width*i+j]-1]=1;
 			}
 		}
Index: /issm/trunk/src/c/modules/ModelProcessorx/FacesPartitioning.cpp
===================================================================
--- /issm/trunk/src/c/modules/ModelProcessorx/FacesPartitioning.cpp	(revision 17805)
+++ /issm/trunk/src/c/modules/ModelProcessorx/FacesPartitioning.cpp	(revision 17806)
@@ -11,29 +11,34 @@
 
 	/*Intermediaries*/
-	int  el1,el2;
-	bool my_face;
-
-	/*Check Iomodel properties*/
-	if(iomodel->meshtype!=Mesh2DhorizontalEnum) _error_("only 2d model are supported");
+	int elementnbf;
 
 	/*Get faces and elements*/
 	CreateFaces(iomodel);
+	_assert_(iomodel->elementtofaceconnectivity);
 
+	/*Mesh dependent variables*/
+	if(iomodel->domaintype==Domain2DhorizontalEnum){
+		elementnbf = 3;
+	}
+	else if(iomodel->domaintype==Domain2DverticalEnum){
+		elementnbf = 3;
+	}
+	else if(iomodel->domaintype==Domain3DEnum){
+		elementnbf = 5;
+	}
+	else{
+		_error_("mesh dimension not supported yet");
+	}
 	/*output: */
-	bool* my_faces=xNew<bool>(iomodel->numberoffaces);
+	bool* my_faces=xNewZeroInit<bool>(iomodel->numberoffaces);
 
-	for(int i=0;i<iomodel->numberoffaces;i++){
-
-		/*Get left and right elements*/
-		el1=iomodel->faces[4*i+2]-1; //faces are [node1 node2 elem1 elem2]
-		el2=iomodel->faces[4*i+3]-1; //faces are [node1 node2 elem1 elem2]
-
-		/*Check whether we should include this face (el2 is -2 for boundary faces)*/
-		my_face = iomodel->my_elements[el1];
-		if(!my_face && el2>=0){
-			my_face = iomodel->my_elements[el2];
+	for(int i=0;i<iomodel->numberofelements;i++){
+		if(iomodel->my_elements[i]){
+			for(int j=0;j<elementnbf;j++){
+				_assert_(iomodel->elementtofaceconnectivity[i*elementnbf+j] >= 0);
+				_assert_(iomodel->elementtofaceconnectivity[i*elementnbf+j] <  iomodel->numberoffaces);
+				my_faces[iomodel->elementtofaceconnectivity[i*elementnbf+j]] = true;
+			}
 		}
-
-		my_faces[i] = my_face;
 	}
 
Index: /issm/trunk/src/c/modules/ModelProcessorx/ModelProcessorx.cpp
===================================================================
--- /issm/trunk/src/c/modules/ModelProcessorx/ModelProcessorx.cpp	(revision 17805)
+++ /issm/trunk/src/c/modules/ModelProcessorx/ModelProcessorx.cpp	(revision 17806)
@@ -16,5 +16,5 @@
 
 	int   i,analysis_enum,verbose;
-	bool  isthermal,ismasstransport,isstressbalance,isgroundingline,isenthalpy;
+	bool  isthermal,ismasstransport,isstressbalance,isgroundingline,isenthalpy,islevelset,isdamage,ishydrology;
 
 	/*Initialize datasets*/
@@ -34,7 +34,10 @@
 	iomodel->Constant(&isthermal,TransientIsthermalEnum);
 	iomodel->Constant(&isenthalpy,ThermalIsenthalpyEnum);
+	iomodel->Constant(&islevelset,TransientIslevelsetEnum);
 	iomodel->Constant(&ismasstransport,TransientIsmasstransportEnum);
 	iomodel->Constant(&isstressbalance,TransientIsstressbalanceEnum);
 	iomodel->Constant(&isgroundingline,TransientIsgroundinglineEnum);
+	iomodel->Constant(&isdamage,TransientIsdamageevolutionEnum);
+	iomodel->Constant(&ishydrology,TransientIshydrologyEnum);
 
 	SetVerbosityLevel(verbose);
@@ -57,7 +60,7 @@
 
 		/*Hack for trasient runs (FIXME: to be improved)*/
-		if(solution_enum==TransientSolutionEnum && analysis_enum==ThermalAnalysisEnum  && iomodel->meshtype==Mesh2DhorizontalEnum) continue;
-		if(solution_enum==TransientSolutionEnum && analysis_enum==MeltingAnalysisEnum  && iomodel->meshtype==Mesh2DhorizontalEnum) continue;
-		if(solution_enum==TransientSolutionEnum && analysis_enum==EnthalpyAnalysisEnum && iomodel->meshtype==Mesh2DhorizontalEnum) continue;
+		if(solution_enum==TransientSolutionEnum && analysis_enum==ThermalAnalysisEnum  && iomodel->domaintype==Domain2DhorizontalEnum) continue;
+		if(solution_enum==TransientSolutionEnum && analysis_enum==MeltingAnalysisEnum  && iomodel->domaintype==Domain2DhorizontalEnum) continue;
+		if(solution_enum==TransientSolutionEnum && analysis_enum==EnthalpyAnalysisEnum && iomodel->domaintype==Domain2DhorizontalEnum) continue;
 		if(solution_enum==TransientSolutionEnum && analysis_enum==ThermalAnalysisEnum && isthermal==false) continue;
 		if(solution_enum==TransientSolutionEnum && analysis_enum==MeltingAnalysisEnum && isthermal==false) continue;
@@ -73,4 +76,11 @@
 		if(solution_enum==SteadystateSolutionEnum && analysis_enum==MeltingAnalysisEnum && isenthalpy==true) continue;
 		if(solution_enum==SteadystateSolutionEnum && analysis_enum==EnthalpyAnalysisEnum && isenthalpy==false) continue;
+		if(solution_enum==TransientSolutionEnum && analysis_enum==LevelsetAnalysisEnum && islevelset==false) continue;
+		if(solution_enum==TransientSolutionEnum && analysis_enum==ExtrapolationAnalysisEnum && islevelset==false) continue;
+		if(solution_enum==TransientSolutionEnum && analysis_enum==LsfReinitializationAnalysisEnum && islevelset==false) continue;
+		if(solution_enum==TransientSolutionEnum && analysis_enum==HydrologyShreveAnalysisEnum && ishydrology==false) continue;
+		if(solution_enum==TransientSolutionEnum && analysis_enum==HydrologyDCEfficientAnalysisEnum && ishydrology==false) continue;
+		if(solution_enum==TransientSolutionEnum && analysis_enum==HydrologyDCInefficientAnalysisEnum && ishydrology==false) continue;
+		if(solution_enum==TransientSolutionEnum && analysis_enum==DamageEvolutionAnalysisEnum && isdamage==false) continue;
 
 		if(VerboseMProcessor()) _printf0_("   creating datasets for analysis " << EnumToStringx(analysis_enum) << "\n");
@@ -93,15 +103,14 @@
 
 	/*Solution specific updates*/
-	#ifdef _HAVE_CONTROL_
 	UpdateElementsAndMaterialsControl(elements,materials,iomodel);
-	#endif
 	#ifdef _HAVE_DAKOTA_
 	UpdateElementsAndMaterialsDakota(elements,materials,iomodel);
 	#endif
-	#ifdef _HAVE_TRANSIENT_
 	if(solution_enum==TransientSolutionEnum){
 		UpdateElementsTransient(elements,parameters,iomodel,analysis_enum);
 	}
-	#endif
+
+	/*Output definitions dataset: */
+	CreateOutputDefinitions(elements,parameters,iomodel);
 
 	/* Sort datasets:
Index: /issm/trunk/src/c/modules/ModelProcessorx/ModelProcessorx.h
===================================================================
--- /issm/trunk/src/c/modules/ModelProcessorx/ModelProcessorx.h	(revision 17805)
+++ /issm/trunk/src/c/modules/ModelProcessorx/ModelProcessorx.h	(revision 17806)
@@ -17,5 +17,5 @@
 void CreateParametersControl(Parameters* parameters,IoModel* iomodel,int solution_type);
 void CreateParametersDakota(Parameters* parameters,IoModel* iomodel,char* rootpath);
-void CreateOutputDefinitions(Parameters* parameters,IoModel* iomodel);
+void CreateOutputDefinitions(Elements* elements, Parameters* parameters,IoModel* iomodel);
 void UpdateElementsAndMaterialsControl(Elements* elements,Materials* materials, IoModel* iomodel);
 void UpdateElementsAndMaterialsDakota(Elements* elements,Materials* materials, IoModel* iomodel);
@@ -30,6 +30,8 @@
 
 /*Mesh properties*/
+void CreateEdges(IoModel* iomodel);
 void CreateFaces(IoModel* iomodel);
-void CreateEdges(IoModel* iomodel);
+void CreateFaces3d(IoModel* iomodel);
+void FaceGetVertexIndices(IoModel* iomodel,int* pnumvertices,int** pverticesid,int facenumber);
 
 /*Connectivity*/
Index: /issm/trunk/src/c/modules/ModelProcessorx/NodesPartitioning.cpp
===================================================================
--- /issm/trunk/src/c/modules/ModelProcessorx/NodesPartitioning.cpp	(revision 17805)
+++ /issm/trunk/src/c/modules/ModelProcessorx/NodesPartitioning.cpp	(revision 17806)
@@ -65,5 +65,5 @@
 
 	/*First: add all the nodes of all the elements belonging to this cpu*/
-	if(iomodel->meshtype==Mesh2DhorizontalEnum){
+	if(iomodel->domaintype==Domain2DhorizontalEnum){
 		for (i=0;i<iomodel->numberofelements;i++){
 			if (my_elements[i]){
Index: /issm/trunk/src/c/modules/ModelProcessorx/Transient/UpdateElementsTransient.cpp
===================================================================
--- /issm/trunk/src/c/modules/ModelProcessorx/Transient/UpdateElementsTransient.cpp	(revision 17805)
+++ /issm/trunk/src/c/modules/ModelProcessorx/Transient/UpdateElementsTransient.cpp	(revision 17806)
@@ -15,5 +15,5 @@
 
 	if(isgroundingline){
-		iomodel->FetchDataToInput(elements,BathymetryEnum);
+		iomodel->FetchDataToInput(elements,BedEnum);
 	}
 }
Index: /issm/trunk/src/c/modules/OutputDefinitionsResponsex/OutputDefinitionsResponsex.cpp
===================================================================
--- /issm/trunk/src/c/modules/OutputDefinitionsResponsex/OutputDefinitionsResponsex.cpp	(revision 17805)
+++ /issm/trunk/src/c/modules/OutputDefinitionsResponsex/OutputDefinitionsResponsex.cpp	(revision 17806)
@@ -15,5 +15,5 @@
 
 	/*Ok, go find the output definitions dataset in the parameters, where our responses are hiding: */
-	femmodel->parameters->FindParam(&output_definitions,OutputdefinitionEnum); _assert_(output_definitions);
+	output_definitions=((DataSetParam*)femmodel->parameters->FindParamObject(OutputdefinitionEnum))->value;
 
 	/*Now, go through the output definitions, and retrieve the object which corresponds to our requested response, output_string: */
@@ -24,12 +24,17 @@
 		char* name = definition->Name();
 		if (strcmp(name,output_string)==0){
+
 			/*This is the object that we have been chasing for. compute the response and return: */
 			return_value=definition->Response(femmodel);
-			delete output_definitions;
+		
+			/*cleanup: */
 			xDelete<char>(name);
+
+			/*return:*/
 			return return_value;
 		}
 		xDelete<char>(name);
 	}
+	
 	/*If we are here, did not find the definition for this response, not good!: */
 	_error_("Could not find the response for output definition " << output_string << " because could not find the definition itself!");
Index: /issm/trunk/src/c/modules/OutputResultsx/OutputResultsx.cpp
===================================================================
--- /issm/trunk/src/c/modules/OutputResultsx/OutputResultsx.cpp	(revision 17805)
+++ /issm/trunk/src/c/modules/OutputResultsx/OutputResultsx.cpp	(revision 17806)
@@ -15,5 +15,5 @@
 #include "../../classes/classes.h"
 
-void OutputResultsx(Elements* elements, Nodes* nodes, Vertices* vertices, Loads* loads, Materials* materials, Parameters* parameters,Results* results){
+void OutputResultsx(FemModel* femmodel){
 
 	int         my_rank;
@@ -27,5 +27,5 @@
 
 	/*retrieve parameters: */
-	parameters->FindParam(&dakota_analysis,QmuIsdakotaEnum);
+	femmodel->parameters->FindParam(&dakota_analysis,QmuIsdakotaEnum);
 
 	/*recover my_rank:*/
@@ -40,18 +40,18 @@
 	 *therefore, we need to include the solutiontype into the filename: */
 	if(my_rank==0){
-		parameters->FindParam(&solutiontype,SolutionTypeEnum);
+		femmodel->parameters->FindParam(&solutiontype,SolutionTypeEnum);
 		EnumToStringx(&solutiontypestring,solutiontype);
-		results->AddResult(new GenericExternalResult<char*>(results->Size()+1,SolutionTypeEnum,solutiontypestring,1,0));
+		femmodel->results->AddResult(new GenericExternalResult<char*>(femmodel->results->Size()+1,SolutionTypeEnum,solutiontypestring,1));
 		xDelete<char>(solutiontypestring);
 	}
 
 	/*Now, open file for writing, if not already done: */
-	if(!parameters->Exist(OutputFilePointerEnum)){
+	if(!femmodel->parameters->Exist(OutputFilePointerEnum)){
 
 		/*We don't have a file pointer. Retrieve the output file name and open it for writing:*/
-		parameters->FindParam(&outputfilename,OutputFileNameEnum);
+		femmodel->parameters->FindParam(&outputfilename,OutputFileNameEnum);
 
 		/*What strategy? : */
-		parameters->FindParam(&io_gather,SettingsIoGatherEnum);
+		femmodel->parameters->FindParam(&io_gather,SettingsIoGatherEnum);
 
 		if(io_gather){
@@ -61,5 +61,5 @@
 		else{
 			/*We are opening different  files for output on all cpus. Append the  rank to the filename, and open: */
-			parameters->FindParam(&fid,OutputFilePointerEnum);
+			femmodel->parameters->FindParam(&fid,OutputFilePointerEnum);
 			sprintf(cpu_outputfilename,"%s.%i",outputfilename,my_rank);
 			fid=pfopen(cpu_outputfilename ,"wb");
@@ -68,15 +68,15 @@
 
 		/*Add file pointer in parameters for further calls to OutputResultsx: */
-		parameters->SetParam(fid,OutputFilePointerEnum);
+		femmodel->parameters->SetParam(fid,OutputFilePointerEnum);
 	}
 
 	/*Write results to disk: */
-	results->Write(parameters);
+	femmodel->results->Write(femmodel->parameters);
 
 	/*Delete and reinitialize results, in parallel: */
-	results->clear();
+	femmodel->results->clear();
 
 	/*Close output file? :*/
-	/*WARNING: issm.cpp is taking care of it for now (quick fix)
+	/*FIXME WARNING: issm.cpp is taking care of it for now (quick fix)
 	  if((step==1) && (time==0)){
 	  if(io_gather){
Index: /issm/trunk/src/c/modules/OutputResultsx/OutputResultsx.h
===================================================================
--- /issm/trunk/src/c/modules/OutputResultsx/OutputResultsx.h	(revision 17805)
+++ /issm/trunk/src/c/modules/OutputResultsx/OutputResultsx.h	(revision 17806)
@@ -14,5 +14,5 @@
 #include "../../classes/classes.h"
 
-void OutputResultsx(Elements* elements, Nodes* nodes, Vertices* vertices, Loads* loads,  Materials* materials, Parameters* parameters, Results* results);
+void OutputResultsx(FemModel* femmodel);
 
 #endif  /* _OUTPUTRESULTS_H */
Index: /issm/trunk/src/c/modules/ResetConstraintsx/ResetConstraintsx.cpp
===================================================================
--- /issm/trunk/src/c/modules/ResetConstraintsx/ResetConstraintsx.cpp	(revision 17805)
+++ /issm/trunk/src/c/modules/ResetConstraintsx/ResetConstraintsx.cpp	(revision 17806)
@@ -24,9 +24,7 @@
 
 	/*Deal with rift first*/
-	#ifdef _HAVE_RIFTS_
 	if(RiftIsPresent(femmodel->loads,analysis_type)){
 		_error_("rift constraints reset not supported yet!");
 	}
-	#endif
 
 	/*Reset pengrid to inactive mode*/
Index: /issm/trunk/src/c/modules/ResetFSBasalBoundaryConditionx/ResetFSBasalBoundaryConditionx.cpp
===================================================================
--- /issm/trunk/src/c/modules/ResetFSBasalBoundaryConditionx/ResetFSBasalBoundaryConditionx.cpp	(revision 17806)
+++ /issm/trunk/src/c/modules/ResetFSBasalBoundaryConditionx/ResetFSBasalBoundaryConditionx.cpp	(revision 17806)
@@ -0,0 +1,18 @@
+/*!\file ResetFSBasalBoundaryConditionx
+ * \brief: reset coordinate system for full-FS: tangential to the bedrock
+ */
+
+#include "./ResetFSBasalBoundaryConditionx.h"
+#include "../../shared/shared.h"
+#include "../../toolkits/toolkits.h"
+
+void ResetFSBasalBoundaryConditionx(Elements* elements,Nodes* nodes, Vertices* vertices, Loads* loads,Materials* materials,Parameters* parameters){
+
+	Element *element = NULL;
+
+	for (int i=0;i<elements->Size();i++){
+		element=dynamic_cast<Element*>(elements->GetObjectByOffset(i));
+		element->ResetFSBasalBoundaryCondition();
+	}
+
+}
Index: /issm/trunk/src/c/modules/ResetFSBasalBoundaryConditionx/ResetFSBasalBoundaryConditionx.h
===================================================================
--- /issm/trunk/src/c/modules/ResetFSBasalBoundaryConditionx/ResetFSBasalBoundaryConditionx.h	(revision 17806)
+++ /issm/trunk/src/c/modules/ResetFSBasalBoundaryConditionx/ResetFSBasalBoundaryConditionx.h	(revision 17806)
@@ -0,0 +1,13 @@
+/*!\file:  ResetFSBasalBoundaryConditionx.h
+ * \brief header file for reset coordinate system module
+ */ 
+
+#ifndef _RESETFSBASALBOUNDARYCONDITIONX_H
+#define _RESETFSBASALBOUNDARYCONDITIONX_H
+
+#include "../../classes/classes.h"
+
+/* local prototypes: */
+void ResetFSBasalBoundaryConditionx(Elements* elements,Nodes* nodes, Vertices* vertices, Loads* loads,Materials* materials,  Parameters* parameters); 
+
+#endif  /* _RESETFSBASALBOUNDARYCONDITIONX_H */
Index: /issm/trunk/src/c/modules/SetActiveNodesLSMx/SetActiveNodesLSMx.cpp
===================================================================
--- /issm/trunk/src/c/modules/SetActiveNodesLSMx/SetActiveNodesLSMx.cpp	(revision 17806)
+++ /issm/trunk/src/c/modules/SetActiveNodesLSMx/SetActiveNodesLSMx.cpp	(revision 17806)
@@ -0,0 +1,130 @@
+/*!\file GetMaskOfIceVerticesLSMx 
+ * \brief: Return a mask for all the vertices determining whether the node should be active or not. 
+ */
+
+#include "./SetActiveNodesLSMx.h"
+
+#include "../../classes/classes.h"
+#include "../../shared/shared.h"
+#include "../../toolkits/toolkits.h"
+#include "../modules.h"
+
+void SetActiveNodesLSMx(FemModel* femmodel){/*{{{*/
+	/* activate/deactivate nodes for levelset method according to IceMaskNodeActivation */
+
+	/* intermediaries */
+	bool solvein2d=false;
+	int i,in,domaintype,analysis_type;
+	Elements* elements = femmodel->elements;
+
+	/* find parameters */
+	femmodel->parameters->FindParam(&domaintype,DomainTypeEnum);
+
+	for(i=0;i<elements->Size();i++){
+		Element    *element  = dynamic_cast<Element*>(elements->GetObjectByOffset(i));
+		int         numnodes = element->GetNumberOfNodes();
+		IssmDouble *mask     = xNew<IssmDouble>(numnodes);
+		// include switch for elements with multiple different sets of nodes
+		switch(element->GetElementType()){
+			case MINIEnum:case TaylorHoodEnum:{
+				Input* input=element->GetInput(IceMaskNodeActivationEnum);
+				if(!input) _error_("Input " << EnumToStringx(IceMaskNodeActivationEnum) << " not found in element");
+
+				/* Start looping on the number of vertices: */
+				Gauss* gauss=element->NewGauss();
+				for(int iv=0;iv<element->NumberofNodesVelocity();iv++){
+					gauss->GaussNode(element->VelocityInterpolation(),iv);
+					input->GetInputValue(&mask[iv],gauss);
+				}
+				for(int iv=0;iv<element->NumberofNodesPressure();iv++){
+					gauss->GaussNode(element->PressureInterpolation(),iv);
+					input->GetInputValue(&mask[element->NumberofNodesVelocity()+iv],gauss);
+				}
+				delete gauss;
+				break;
+			}
+			default:
+				element->GetInputListOnNodes(&mask[0],IceMaskNodeActivationEnum);
+				break;
+		}
+
+		/* if solving 2d problem on vertically extende mesh, solve on basal layer only*/
+		if(domaintype!=Domain2DhorizontalEnum){
+			femmodel->parameters->FindParam(&analysis_type,AnalysisTypeEnum);
+			if(
+					analysis_type==FreeSurfaceBaseAnalysisEnum || 
+					analysis_type==MasstransportAnalysisEnum || 
+					analysis_type==MeltingAnalysisEnum || 
+					analysis_type==L2ProjectionBaseAnalysisEnum || 
+					analysis_type==BalancethicknessAnalysisEnum ||
+					analysis_type==HydrologyDCInefficientAnalysisEnum ||
+					analysis_type==DamageEvolutionAnalysisEnum || 
+					analysis_type==HydrologyDCEfficientAnalysisEnum ||
+					analysis_type==LevelsetAnalysisEnum ||
+					analysis_type==ExtrapolationAnalysisEnum
+					){ solvein2d=true;}
+
+			if(analysis_type==StressbalanceAnalysisEnum){
+				bool isSIA,isSSA;
+				femmodel->parameters->FindParam(&isSIA,FlowequationIsSIAEnum);
+				femmodel->parameters->FindParam(&isSSA,FlowequationIsSSAEnum);
+				if(isSIA || isSSA)
+					solvein2d=true;
+			}
+
+			if(solvein2d){
+				IssmDouble *mask_isonbase = xNew<IssmDouble>(numnodes);
+				element->GetInputListOnNodes(&mask_isonbase[0],MeshVertexonbaseEnum);
+				for(in=0;in<numnodes;in++)	 mask[in]*=mask_isonbase[in];
+				xDelete<IssmDouble>(mask_isonbase);
+			}
+		}
+
+		for(in=0;in<numnodes;in++){
+			Node* node=element->GetNode(in);
+			if(mask[in]==1.){
+				node->Activate();
+			}
+			else {
+				node->Deactivate();
+			}
+		}
+
+		xDelete<IssmDouble>(mask);
+	}
+}/*}}}*/
+void GetMaskOfIceVerticesLSMx(FemModel* femmodel){/*{{{*/
+
+	/* Intermediaries */
+	int i;
+
+	/*Initialize vector with number of vertices*/
+	int numvertices=femmodel->vertices->NumberOfVertices();
+	Vector<IssmDouble>* vec_mask_ice=new Vector<IssmDouble>(numvertices); //vertices that have ice at next time step
+	/*Fill vector with values: */
+	for(i=0;i<femmodel->elements->Size();i++){
+		Element* element=dynamic_cast<Element*>(femmodel->elements->GetObjectByOffset(i));
+		SetMaskOfIceElement(vec_mask_ice, element);
+	}
+
+	/*Assemble vector and serialize */
+	vec_mask_ice->Assemble();
+	IssmDouble* mask_ice=vec_mask_ice->ToMPISerial();
+	InputUpdateFromVectorx(femmodel,mask_ice,IceMaskNodeActivationEnum,VertexSIdEnum);
+
+	/*Clean up and return*/
+	delete vec_mask_ice;
+	delete mask_ice;
+
+}/*}}}*/
+void SetMaskOfIceElement(Vector<IssmDouble>* vec_mask_ice, Element* element){/*{{{*/
+
+	/* Intermediaries */
+	int numvertices = element->GetNumberOfVertices();
+	
+	if(element->IsIceInElement()){
+		for(int i = 0;i<numvertices;i++){
+			vec_mask_ice->SetValue(element->vertices[i]->Sid(),1.,INS_VAL);
+		}
+	}
+}/*}}}*/
Index: /issm/trunk/src/c/modules/SetActiveNodesLSMx/SetActiveNodesLSMx.h
===================================================================
--- /issm/trunk/src/c/modules/SetActiveNodesLSMx/SetActiveNodesLSMx.h	(revision 17806)
+++ /issm/trunk/src/c/modules/SetActiveNodesLSMx/SetActiveNodesLSMx.h	(revision 17806)
@@ -0,0 +1,13 @@
+/*!\file:  SetActiveNodesLSMx.h
+ * \brief header file for updating single point constraints  for next time step
+ */ 
+
+#ifndef _SETACTIVENODESLSMX_H
+#define _SETACTIVENODESLSMX_H
+
+#include "../../classes/classes.h"
+
+void SetActiveNodesLSMx(FemModel* femmodel);
+void GetMaskOfIceVerticesLSMx(FemModel* femmodel);
+void SetMaskOfIceElement(Vector<IssmDouble>* vec_mask_ice, Element* element);
+#endif  /* _UPDATESPCSX_H */
Index: /issm/trunk/src/c/modules/SurfaceAreax/SurfaceAreax.h
===================================================================
--- /issm/trunk/src/c/modules/SurfaceAreax/SurfaceAreax.h	(revision 17805)
+++ /issm/trunk/src/c/modules/SurfaceAreax/SurfaceAreax.h	(revision 17806)
@@ -6,5 +6,6 @@
 #define _SURFACEAREAX_H
 
-#include "../../classes/classes.h"
+#include "../../shared/shared.h"
+class FemModel;
 
 /* local prototypes: */
Index: /issm/trunk/src/c/modules/SurfaceMassBalancex/SurfaceMassBalancex.cpp
===================================================================
--- /issm/trunk/src/c/modules/SurfaceMassBalancex/SurfaceMassBalancex.cpp	(revision 17806)
+++ /issm/trunk/src/c/modules/SurfaceMassBalancex/SurfaceMassBalancex.cpp	(revision 17806)
@@ -0,0 +1,228 @@
+/*!\file SurfaceMassBalancex
+ * \brief: calculates SMB 
+ */
+
+#include "./SurfaceMassBalancex.h"
+#include "../../shared/shared.h"
+#include "../../toolkits/toolkits.h"
+
+void SurfaceMassBalancex(FemModel* femmodel){/*{{{*/
+
+	/*Intermediaties*/
+	int  smb_model;
+	bool isdelta18o;
+
+	/*First, get SMB model from parameters*/
+	femmodel->parameters->FindParam(&smb_model,SurfaceforcingsEnum);
+
+	/*branch to correct module*/
+	switch(smb_model){
+		case SMBEnum:
+			/*Nothing to be done*/
+			break;
+		case SMBpddEnum:
+			femmodel->parameters->FindParam(&isdelta18o,SurfaceforcingsIsdelta18oEnum);
+			if(isdelta18o){
+				if(VerboseSolution()) _printf0_("   call Delta18oParametrization module\n");
+				Delta18oParameterizationx(femmodel);
+			} 
+			if(VerboseSolution()) _printf0_("   call positive degree day module\n");
+			PositiveDegreeDayx(femmodel);
+			break;
+		case SMBgradientsEnum:
+			if(VerboseSolution())_printf_("	call smb gradients module\n");
+			SmbGradientsx(femmodel);
+			break;
+		case SMBhenningEnum:
+			if(VerboseSolution())_printf_("  call smb Henning module\n");
+			SmbHenningx(femmodel);
+			break;
+		default:
+			_error_("Surface mass balance model "<<EnumToStringx(smb_model)<<" not supported yet");
+	}
+
+}/*}}}*/
+
+void SmbGradientsx(FemModel* femmodel){/*{{{*/
+
+	// void SurfaceMassBalancex(hd,agd,ni){
+	//    INPUT parameters: ni: working size of arrays
+	//    INPUT: surface elevation (m): hd(NA)
+	//    OUTPUT: mass-balance (m/yr ice): agd(NA)
+
+	for(int i=0;i<femmodel->elements->Size();i++){
+		Element* element=dynamic_cast<Element*>(femmodel->elements->GetObjectByOffset(i));
+		element->SmbGradients();
+	}
+
+}/*}}}*/
+void Delta18oParameterizationx(FemModel* femmodel){/*{{{*/
+
+	for(int i=0;i<femmodel->elements->Size();i++){
+		Element* element=dynamic_cast<Element*>(femmodel->elements->GetObjectByOffset(i));
+		element->Delta18oParameterization();
+	}
+
+}/*}}}*/
+void PositiveDegreeDayx(FemModel* femmodel){/*{{{*/
+
+	// void PositiveDegreeDayx(hd,vTempsea,vPrec,agd,Tsurf,ni){
+	//    note "v" prefix means 12 monthly means, ie time dimension
+	//    INPUT parameters: ni: working size of arrays
+	//    INPUT: surface elevation (m): hd(NA)
+	//    monthly mean surface sealevel temperature (degrees C): vTempsea(NA
+	//    ,NTIME) 
+	//    monthly mean precip rate (m/yr water equivalent): vPrec(NA,NTIME)
+	//    OUTPUT: mass-balance (m/yr ice): agd(NA)
+	//    mean annual surface temperature (degrees C): Tsurf(NA)
+
+	int    i, it, jj, itm;
+	IssmDouble DT = 0.02, sigfac, snormfac;
+	IssmDouble signorm = 5.5;      // signorm : sigma of the temperature distribution for a normal day 
+	IssmDouble siglim;       // sigma limit for the integration which is equal to 2.5 sigmanorm
+	IssmDouble signormc = signorm - 0.5;     // sigma of the temperature distribution for cloudy day
+	IssmDouble siglimc, siglim0, siglim0c;
+	IssmDouble tstep, tsint, tint, tstepc;
+	int    NPDMAX = 1504, NPDCMAX = 1454;
+	//IssmDouble pdds[NPDMAX]={0}; 
+	//IssmDouble pds[NPDCMAX]={0};
+	IssmDouble pddt, pd ; // pd : snow/precip fraction, precipitation falling as snow
+	IssmDouble PDup, PDCUT = 2.0;    // PDcut: rain/snow cutoff temperature (C)
+	IssmDouble tstar; // monthly mean surface temp
+
+	IssmDouble *pdds    = NULL;
+	IssmDouble *pds     = NULL;
+	Element    *element = NULL;
+
+	pdds=xNew<IssmDouble>(NPDMAX+1); 
+	pds=xNew<IssmDouble>(NPDCMAX+1); 
+
+	/* initialize PDD (creation of a lookup table)*/
+	tstep    = 0.1;
+	tsint    = tstep*0.5;
+	sigfac   = -1.0/(2.0*pow(signorm,2));
+	snormfac = 1.0/(signorm*sqrt(2.0*acos(-1.0)));
+	siglim   = 2.5*signorm;
+	siglimc  = 2.5*signormc;
+	siglim0  = siglim/DT + 0.5;
+	siglim0c = siglimc/DT + 0.5;
+	PDup     = siglimc+PDCUT;
+
+	itm = reCast<int,IssmDouble>((2*siglim/DT + 1.5));
+
+	if(itm >= NPDMAX) _error_("increase NPDMAX in massBalance.cpp");
+	for(it = 0; it < itm; it++){  
+		//    tstar = REAL(it)*DT-siglim;
+		tstar = it*DT-siglim;
+		tint = tsint;
+		pddt = 0.;
+		for ( jj = 0; jj < 600; jj++){
+			if (tint > (tstar+siglim)){break;}
+			pddt = pddt + tint*exp(sigfac*(pow((tint-tstar),2)))*tstep;
+			tint = tint+tstep;
+		}
+		pdds[it] = pddt*snormfac;
+	}
+	pdds[itm+1] = siglim + DT;
+
+	//*********compute PD(T) : snow/precip fraction. precipitation falling as snow
+	tstepc   = 0.1;
+	tsint    = PDCUT-tstepc*0.5;
+	signormc = signorm - 0.5;
+	sigfac   = -1.0/(2.0*pow(signormc,2));
+	snormfac = 1.0/(signormc*sqrt(2.0*acos(-1.0)));
+	siglimc  = 2.5*signormc ;
+	itm = reCast<int,IssmDouble>((PDCUT+2.*siglimc)/DT + 1.5);
+	if(itm >= NPDCMAX) _error_("increase NPDCMAX in p35com");
+	for(it = 0; it < itm; it++ ){
+		tstar = it*DT-siglimc;
+		//    tstar = REAL(it)*DT-siglimc;
+		tint = tsint;          // start against upper bound
+		pd = 0.;
+		for (jj = 0; jj < 600; jj++){
+			if (tint<(tstar-siglimc)) {break;}
+			pd = pd + exp(sigfac*(pow((tint-tstar),2)))*tstepc;
+			tint = tint-tstepc;
+		}
+		pds[it] = pd*snormfac;  // gaussian integral lookup table for snow fraction
+	}
+	pds[itm+1] = 0.;
+	//     *******END initialize PDD
+
+	for(i=0;i<femmodel->elements->Size();i++){
+		element=dynamic_cast<Element*>(femmodel->elements->GetObjectByOffset(i));
+		element->PositiveDegreeDay(pdds,pds,signorm);
+	}
+
+	/*free ressouces: */
+	xDelete<IssmDouble>(pdds);
+	xDelete<IssmDouble>(pds);
+}/*}}}*/
+void SmbHenningx(FemModel* femmodel){/*{{{*/
+
+	/*Intermediaries*/
+	IssmDouble  z_critical = 1675.;
+	IssmDouble  dz = 0;
+	IssmDouble  a = -15.86;
+	IssmDouble  b = 0.00969;
+	IssmDouble  c = -0.235;
+	IssmDouble  f = 1.;
+	IssmDouble  g = -0.0011;
+	IssmDouble  h = -1.54e-5;
+	IssmDouble  smb,smbref,anomaly,yts,z;
+    
+    /* Get constants */
+    femmodel->parameters->FindParam(&yts,ConstantsYtsEnum);
+    /*iomodel->Constant(&yts,ConstantsYtsEnum);*/
+    /*this->parameters->FindParam(&yts,ConstantsYtsEnum);*/
+    /*Mathieu original*/
+    /*IssmDouble  smb,smbref,z;*/
+    
+	/*Loop over all the elements of this partition*/
+	for(int i=0;i<femmodel->elements->Size();i++){
+		Element* element=dynamic_cast<Element*>(femmodel->elements->GetObjectByOffset(i));
+
+		/*Get reference SMB (uncorrected) and allocate all arrays*/
+		int         numvertices = element->GetNumberOfVertices();
+		IssmDouble* surfacelist = xNew<IssmDouble>(numvertices);
+		IssmDouble* smblistref  = xNew<IssmDouble>(numvertices);
+		IssmDouble* smblist     = xNew<IssmDouble>(numvertices);
+		element->GetInputListOnVertices(surfacelist,SurfaceEnum);
+		element->GetInputListOnVertices(smblistref,SurfaceforcingsSmbrefEnum);
+
+		/*Loop over all vertices of element and correct SMB as a function of altitude z*/
+		for(int v=0;v<numvertices;v++){
+
+			/*Get vertex elevation, anoma smb*/
+			z      = surfacelist[v];
+			anomaly = smblistref[v];
+
+            /* Henning edited acc. to Riannes equations*/
+            /* Set SMB maximum elevation, if dz = 0 -> z_critical = 1675 */
+            z_critical = z_critical + dz;
+            
+            /* Calculate smb acc. to the surface elevation z */
+            if(z<z_critical){
+				smb = a + b*z + c;
+			}
+			else{
+			  smb = (a + b*z)*(f + g*(z-z_critical) + h*(z-z_critical)*(z-z_critical)) + c;
+			}
+            
+            /* Compute smb including anomaly,
+             correct for number of seconds in a year [s/yr]*/
+            smb = smb + anomaly*yts;
+            
+			/*Update array accordingly*/
+			smblist[v] = smb;
+
+		}
+
+		/*Add input to element and Free memory*/
+		element->AddInput(SurfaceforcingsMassBalanceEnum,smblist,P1Enum);
+		xDelete<IssmDouble>(surfacelist);
+		xDelete<IssmDouble>(smblistref);
+		xDelete<IssmDouble>(smblist);
+	}
+
+}/*}}}*/
Index: /issm/trunk/src/c/modules/SurfaceMassBalancex/SurfaceMassBalancex.h
===================================================================
--- /issm/trunk/src/c/modules/SurfaceMassBalancex/SurfaceMassBalancex.h	(revision 17806)
+++ /issm/trunk/src/c/modules/SurfaceMassBalancex/SurfaceMassBalancex.h	(revision 17806)
@@ -0,0 +1,17 @@
+/*!\file:  SurfaceMassBalancex.h
+ * \brief header file for SMB
+ */ 
+
+#ifndef _SurfaceMassBalancex_H
+#define _SurfaceMassBalancex_H
+
+#include "../../classes/classes.h"
+
+/* local prototypes: */
+void SurfaceMassBalancex(FemModel* femmodel);
+void SmbGradientsx(FemModel* femmodel);
+void Delta18oParameterizationx(FemModel* femmodel);
+void PositiveDegreeDayx(FemModel* femmodel);
+void SmbHenningx(FemModel* femmodel);
+
+#endif  /* _SurfaceMassBalancex_H*/
Index: /issm/trunk/src/c/modules/SystemMatricesx/SystemMatricesx.cpp
===================================================================
--- /issm/trunk/src/c/modules/SystemMatricesx/SystemMatricesx.cpp	(revision 17805)
+++ /issm/trunk/src/c/modules/SystemMatricesx/SystemMatricesx.cpp	(revision 17806)
@@ -12,5 +12,5 @@
 	/*intermediary: */
 	int      i,M,N;
-	int      configuration_type;
+	int      configuration_type,analysisenum;
 	Element *element = NULL;
 	Load    *load    = NULL;
@@ -26,6 +26,8 @@
 	if(VerboseModule()) _printf0_("   Generating matrices");
 
-	/*retrive parameters: */
+	/*retrieve parameters: */
 	femmodel->parameters->FindParam(&configuration_type,ConfigurationTypeEnum);
+	femmodel->parameters->FindParam(&analysisenum,AnalysisTypeEnum);
+	Analysis* analysis = EnumToAnalysis(analysisenum);
 
 	/*First, we might need to do a dry run to get kmax if penalties are employed*/
@@ -39,5 +41,10 @@
 		for (i=0;i<femmodel->elements->Size();i++){
 			element=dynamic_cast<Element*>(femmodel->elements->GetObjectByOffset(i));
-			element->CreateKMatrix(Kff_temp,NULL);
+			ElementMatrix* Ke = analysis->CreateKMatrix(element);
+			ElementVector* pe = analysis->CreatePVector(element);
+			element->ReduceMatrices(Ke,pe);
+			if(Ke) Ke->AddToGlobal(Kff_temp,NULL);
+			delete Ke;
+			delete pe;
 		}
 
@@ -62,23 +69,25 @@
 	}
 
-	/*Fill stiffness matrix from elements and loads */
+	/*Fill stiffness matrix and load vector from elements*/
 	for (i=0;i<femmodel->elements->Size();i++){
 		element=dynamic_cast<Element*>(femmodel->elements->GetObjectByOffset(i));
-		element->CreateKMatrix(Kff,Kfs);
+		ElementMatrix* Ke = analysis->CreateKMatrix(element);
+		ElementVector* pe = analysis->CreatePVector(element);
+		element->ReduceMatrices(Ke,pe);
+		if(Ke) Ke->AddToGlobal(Kff,Kfs);
+		if(pe){
+			pe->AddToGlobal(pf);
+		}
+		delete Ke;
+		delete pe;
 	}
 
-	for (i=0;i<femmodel->loads->Size();i++){
+	/*Fill stiffness matrix and load vector from loads*/
+	for(i=0;i<femmodel->loads->Size();i++){
 		load=dynamic_cast<Load*>(femmodel->loads->GetObjectByOffset(i));
-		if(load->InAnalysis(configuration_type)) load->CreateKMatrix(Kff,Kfs);
-	}
-
-	/*Fill right hand side vector, from elements and loads */
-	for (i=0;i<femmodel->elements->Size();i++){
-		element=dynamic_cast<Element*>(femmodel->elements->GetObjectByOffset(i));
-		element->CreatePVector(pf);
-	}
-	for (i=0;i<femmodel->loads->Size();i++){
-		load=dynamic_cast<Load*>(femmodel->loads->GetObjectByOffset(i));
-		if(load->InAnalysis(configuration_type)) load->CreatePVector(pf);
+		if(load->InAnalysis(configuration_type)){
+			load->CreateKMatrix(Kff,Kfs);
+			load->CreatePVector(pf);
+		}
 	}
 
@@ -87,16 +96,19 @@
 		for (i=0;i<femmodel->loads->Size();i++){
 			load=dynamic_cast<Load*>(femmodel->loads->GetObjectByOffset(i));
-			if(load->InAnalysis(configuration_type)) load->PenaltyCreateKMatrix(Kff,Kfs,kmax);
-		}
-		for (i=0;i<femmodel->loads->Size();i++){
-			load=dynamic_cast<Load*>(femmodel->loads->GetObjectByOffset(i));
-			if(load->InAnalysis(configuration_type)) load->PenaltyCreatePVector(pf,kmax);
+			if(load->InAnalysis(configuration_type)){
+				load->PenaltyCreateKMatrix(Kff,Kfs,kmax);
+				load->PenaltyCreatePVector(pf,kmax);
+			}
 		}
 	}
 
 	/*Create dof vector for stiffness matrix preconditioning*/
-	for (i=0;i<femmodel->elements->Size();i++){
-		element=dynamic_cast<Element*>(femmodel->elements->GetObjectByOffset(i));
-		element->CreateDVector(df);
+	if(pdf){
+		for(i=0;i<femmodel->elements->Size();i++){
+			element=dynamic_cast<Element*>(femmodel->elements->GetObjectByOffset(i));
+			ElementVector* de=analysis->CreateDVector(element);
+			if(de) de->InsertIntoGlobal(df);
+			delete de;
+		}
 	}
 
@@ -109,5 +121,6 @@
 	//Kfs->AllocationInfo();
 
-	/*Assign output pointers: */
+	/*cleanu up and assign output pointers: */
+	delete analysis;
 	if(pKff) *pKff=Kff;
 	else      delete Kff;
Index: /issm/trunk/src/c/modules/SystemMatricesx/SystemMatricesx.h
===================================================================
--- /issm/trunk/src/c/modules/SystemMatricesx/SystemMatricesx.h	(revision 17805)
+++ /issm/trunk/src/c/modules/SystemMatricesx/SystemMatricesx.h	(revision 17806)
@@ -6,4 +6,5 @@
 
 #include "../../classes/classes.h"
+#include "../../analyses/analyses.h"
 
 /* local prototypes: */
Index: /issm/trunk/src/c/modules/modules.h
===================================================================
--- /issm/trunk/src/c/modules/modules.h	(revision 17805)
+++ /issm/trunk/src/c/modules/modules.h	(revision 17806)
@@ -24,5 +24,4 @@
 #include "./CreateNodalConstraintsx/CreateNodalConstraintsx.h"
 #include "./CreateJacobianMatrixx/CreateJacobianMatrixx.h"
-#include "./Delta18oParameterizationx/Delta18oParameterizationx.h"
 #include "./DragCoefficientAbsGradientx/DragCoefficientAbsGradientx.h"
 #include "./ElementConnectivityx/ElementConnectivityx.h"
@@ -33,4 +32,5 @@
 #include "./GiaDeflectionCorex/GiaDeflectionCorex.h"
 #include "./SetControlInputsFromVectorx/SetControlInputsFromVectorx.h"
+#include "./SetActiveNodesLSMx/SetActiveNodesLSMx.h"
 #include "./Gradjx/Gradjx.h"
 #include "./GroundinglineMigrationx/GroundinglineMigrationx.h"
@@ -75,6 +75,4 @@
 #include "./ConstraintsStatex/ConstraintsStatex.h"
 #include "./PointCloudFindNeighborsx/PointCloudFindNeighborsx.h"
-#include "./PositiveDegreeDayx/PositiveDegreeDayx.h"
-#include "./PostprocessingEnthalpyx/PostprocessingEnthalpyx.h"
 #include "./PropagateFlagsFromConnectivityx/PropagateFlagsFromConnectivityx.h"
 #include "./Reduceloadx/Reduceloadx.h"
@@ -82,9 +80,9 @@
 #include "./Reducevectorgtofx/Reducevectorgtofx.h"
 #include "./ResetConstraintsx/ResetConstraintsx.h"
-#include "./ResetCoordinateSystemx/ResetCoordinateSystemx.h"
+#include "./ResetFSBasalBoundaryConditionx/ResetFSBasalBoundaryConditionx.h"
 #include "./RheologyBbarAbsGradientx/RheologyBbarAbsGradientx.h"
 #include "./Scotchx/Scotchx.h"
 #include "./Shp2Kmlx/Shp2Kmlx.h"
-#include "./SmbGradientsx/SmbGradientsx.h"
+#include "./SurfaceMassBalancex/SurfaceMassBalancex.h"
 #include "./Solverx/Solverx.h"
 #include "./SystemMatricesx/SystemMatricesx.h"
Index: /issm/trunk/src/c/shared/Bamg/BigPrimeNumber.cpp
===================================================================
--- /issm/trunk/src/c/shared/Bamg/BigPrimeNumber.cpp	(revision 17805)
+++ /issm/trunk/src/c/shared/Bamg/BigPrimeNumber.cpp	(revision 17806)
@@ -7,5 +7,5 @@
 		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/AGoodNumberPrimeWith)*/
 
-		//list of big prime numbers
+		/*list of big prime numbers*/
 		const long BigPrimeNumber[] ={ 567890359L,
 			567890431L,  567890437L,  567890461L,  567890471L,
@@ -13,19 +13,19 @@
 			567890591L,  567890599L,  567890621L,  567890629L , 0};
 
-		//initialize o and pi
-		long o =0;
-		long pi=BigPrimeNumber[1];
+		/*initialize o and pi*/
+		long o  = 0;
+		long pi = BigPrimeNumber[1];
 
-		//loop until BigPrimeNumber[i]==0 (end of BigPrimeNumber)
+		/*loop until BigPrimeNumber[i]==0 (end of BigPrimeNumber)*/
 		for (int i=0; BigPrimeNumber[i]; i++){
 
-			//compute r, rest of the remainder of the division of BigPrimeNumber[i] by n
+			/*compute r, remainder of the division of BigPrimeNumber[i] by n*/
 			long r = BigPrimeNumber[i] % n;
 
 			/*compute oo = min ( r , n-r , |n - 2r|, |n-3r|)*/
-			long oo =Min(Min(r,n-r),Min(Abs(n-2*r),Abs(n-3*r)));
-			if ( o < oo){
-				o=oo;
-				pi=BigPrimeNumber[i];
+			long oo = Min(Min(r,n-r),Min(Abs(n-2*r),Abs(n-3*r)));
+			if(o < oo){
+				o  = oo;
+				pi = BigPrimeNumber[i];
 			}
 		}
Index: /issm/trunk/src/c/shared/Elements/Cuffey.cpp
===================================================================
--- /issm/trunk/src/c/shared/Elements/Cuffey.cpp	(revision 17806)
+++ /issm/trunk/src/c/shared/Elements/Cuffey.cpp	(revision 17806)
@@ -0,0 +1,57 @@
+/* \file Cuffey.cpp
+ * \brief figure out B of ice for a certain temperature
+ *	  INPUT function B=Cuffey(temperature)
+ *    where rigidigty (in s^(1/3)Pa) is the flow law paramter in the flow law sigma=B*e(1/3) (Cuffey, p75). 
+ */
+
+#include <math.h>
+
+#include "../Numerics/types.h"
+
+IssmDouble Cuffey(IssmDouble temperature){
+
+	/*output: */
+	IssmDouble B,T;
+
+	/*Switch to celsius from Kelvin: */
+	T=temperature-273.15;
+
+	if(T<=-45.0){
+		B=1.e+8*(-0.000396645116301*pow(T+50.,3)+ 0.013345579471334*pow(T+50.,2) -0.356868703259105*(T+50.)+7.272363035371383);
+	}
+	else if((T>=-45.0) && (T<=-40.0)){
+		B=1.e+8*(-0.000396645116301*pow(T+45.,3)+ 0.007395902726819*pow(T+45.,2) -0.253161292268336*(T+45.)+5.772078366321591);
+	}
+	else if((T>=-40.0) && (T<=-35.0)){
+		B=1.e+8*(0.000408322072669*pow(T+40.,3)+  0.001446225982305*pow(T+40.,2)  -0.208950648722716*(T+40.)+4.641588833612773);
+	}
+	else if((T>=-35.0) && (T<=-30.0)){
+		B=1.e+8*(-0.000423888728124*pow(T+35.,3)+ 0.007571057072334*pow(T+35.,2)  -0.163864233449525*(T+35.)+3.684031498640382);
+	}
+	else if((T>=-30.0) && (T<=-25.0)){
+		B=1.e+8*(0.000147154327025*pow(T+30.,3)+ 0.001212726150476*pow(T+30.,2) -0.119945317335478*(T+30.)+3.001000667185614);
+	}
+	else if((T>=-25.0) && (T<=-20.0)){
+		B=1.e+8*(-0.000193435838672*pow(T+25.,3)+ 0.003420041055847*pow(T+25.,2)  -0.096781481303861*(T+25.)+2.449986525148220);
+	}
+	else if((T>=-20.0) && (T<=-15.0)){
+		B=1.e+8*(0.000219771255067*pow(T+20.,3)+  0.000518503475772*pow(T+20.,2)  -0.077088758645767*(T+20.)+2.027400665191131);
+	}
+	else if((T>=-15.0) && (T<=-10.0)){
+		B=1.e+8*(-0.000653438900191*pow(T+15.,3)+ 0.003815072301777*pow(T+15.,2)  -0.055420879758021*(T+15.)+1.682390865739973);
+	}
+	else if((T>=-10.0) && (T<=-5.0)){
+		B=1.e+8*(0.000692439419762*pow(T+10.,3) -0.005986511201093 *pow(T+10.,2) -0.066278074254598*(T+10.)+1.418983411970382);
+	}
+	else if((T>=-5.0) && (T<=-2.0)){
+		B=1.e+8*(-0.000132282004110*pow(T+5.,3) +0.004400080095332*pow(T+5.,2)    -0.074210229783403*(T+5.)+ 1.024485188140279);
+	}
+	else{
+		B=1.e+8*(-0.000132282004110*pow(T+2.,3) +0.003209542058346*pow(T+2.,2)    -0.051381363322371*(T+2.)+ 0.837883605537096);
+	}
+
+	/*B cannot be negative!*/
+	if(B<0) B=1.e+6;
+
+	return B;
+}
Index: /issm/trunk/src/c/shared/Elements/DrainageFunctionWaterfraction.cpp
===================================================================
--- /issm/trunk/src/c/shared/Elements/DrainageFunctionWaterfraction.cpp	(revision 17805)
+++ /issm/trunk/src/c/shared/Elements/DrainageFunctionWaterfraction.cpp	(revision 17806)
@@ -14,32 +14,32 @@
 
 	IssmDouble w0=0.01, w1=0.02, w2=0.03;
-	IssmDouble Dret, D0=0, D1=0.005, D2=0.05;
-	IssmDouble yts=365*24*60*60;
-	dt/=yts;
+	IssmDouble yts=365.*24.*60.*60.;
+	IssmDouble Dret, D0=0., D1=0.005/yts, D2=0.05/yts;
 
 	/*get drainage function value*/
 	if((w0==w1)||(w1==w2)||(w0==w2))
 		_error_("Error: equal ordinates in DrainageFunctionWaterfraction -> division by zero. Abort");
+	
 	if(waterfraction<=w0)
 		Dret=D0;
-	if((waterfraction>w0) && (waterfraction<=w1))
+	else if((waterfraction>w0) && (waterfraction<=w1))
 		Dret=(D1-D0)/(w1-w0)*(waterfraction-w0)+D0;
-	if((waterfraction>w1) && (waterfraction<=w2))
+	else if((waterfraction>w1) && (waterfraction<=w2))
 		Dret=(D2-D1)/(w2-w1)*(waterfraction-w1)+D1;
 	else 
 		Dret=D2;
 
-	/*check if dt*Dret>waterfraction. If so, drain whole waterfraction*/
+	/*drain only up to w0*/
 	if(dt==0.){
-		if(Dret>waterfraction)
-			return waterfraction;
+		if((waterfraction>w0) && (waterfraction-Dret*yts<w0))
+			return waterfraction-w0;
+		else
+			return Dret*yts;
+	}
+	else{
+		if((waterfraction>w0) && (waterfraction-dt*Dret<w0))
+			return (waterfraction-w0)/dt;
 		else
 			return Dret;
 	}
-	else{
-		if(dt*Dret>waterfraction)
-			return waterfraction;
-		else
-			return dt*Dret;
-	}
 }
Index: /issm/trunk/src/c/shared/Elements/LliboutryDuval.cpp
===================================================================
--- /issm/trunk/src/c/shared/Elements/LliboutryDuval.cpp	(revision 17805)
+++ /issm/trunk/src/c/shared/Elements/LliboutryDuval.cpp	(revision 17806)
@@ -36,8 +36,8 @@
 
 	/*check feasibility*/
-  _assert_(pressure>0);
+  _assert_(pressure>=0);
   _assert_(n>0);
-  _assert_(betaCC>0);
-  _assert_(referencetemperature>0);
+  _assert_(betaCC>=0);
+  _assert_(referencetemperature>=0);
   _assert_(heatcapacity>0);
   _assert_(latentheat>0);
@@ -53,59 +53,25 @@
   if (enthalpy < H_sp){
     Tstar = referencetemperature + enthalpy/heatcapacity - betaCC*pressure;	
-    waterfraction = 0;
+    waterfraction = 0.;
   }
   else{
     Tstar=Tpmp;
     waterfraction=(enthalpy - H_sp)/latentheat;
+		if (waterfraction > 0.01)
+			waterfraction = 0.01;
   }
 
   /*Get A*/
-  if(Tstar<263.15){
-    A=3.61*pow(10.,-13.) * exp(  -6.*pow(10.,4.)/(R*Tstar));
+  if(Tstar<=263.15){
+    A=3.61e-13 * exp(  -6.e+4/(R*Tstar));
   }
   else{
-    A=1.73*pow(10.,  3.) * exp(-13.9*pow(10.,4.)/(R*Tstar));
+    A=1.73e3   * exp(-13.9e+4/(R*Tstar));
   }
-  A*=(1 + 181.25*waterfraction);
+  A*=(1. + 181.25*waterfraction);
 
   /*Convert to B*/
-  _assert_(n>0);
   B=pow(A,-1./n);
 
   return B;
 }
-
-// /*Get stiffness from temperature, waterfraction and depth*/
-// IssmDouble LliboutryDuval(IssmDouble temperature, IssmDouble waterfraction, IssmDouble depth,IssmDouble n){
-// 	/*Use parameterization for the rheology: Greve and Blatter 2009
-// 	 * get enthalpy from temperature and water fraction,
-// 	 * and use LliboutryDuval(IssmDouble enthalpy, IssmDouble pressure,IssmDouble n) */
-// 
-// 	/*TODO: update params from model*/
-//   IssmDouble rho_ice=910; // kg/m^3
-//   IssmDouble g=9.81; //kg*m/s^2
-//   IssmDouble heatcapacity=2009; // J/kg/K
-//   IssmDouble referencetemperature=253.15;
-//   IssmDouble betaCC=7.9*pow(10.,-8.);
-//   IssmDouble latentheat=3.34*pow(10,5.); // from Aschwanden 2012
-// 
-//   IssmDouble Tstar, enthalpy, pressure, B;
-//   _assert_(temperature>0);
-//   _assert_(waterfraction>0);
-//   _assert_(depth>0);
-// 
-//   /*get pressure*/
-//   pressure= rho_ice*g*depth;
-//   Tstar=temperature-betaCC*pressure; // TODO: check whether plus or minus
-//   /*get enthalpy*/
-//   if (Tstar < 273.15){
-//     enthalpy=heatcapacity*(Tstar - referencetemperature);
-//   }
-//   else{
-//     enthalpy=heatcapacity*(273.15 - referencetemperature) + waterfraction*latentheat;
-//   }
-// 
-//   B=LliboutryDuval(enthalpy, pressure, n, betaCC, referencetemperature, heatcapacity, latentheat);
-// 
-//   return B;
-// }
Index: /issm/trunk/src/c/shared/Elements/Paterson.cpp
===================================================================
--- /issm/trunk/src/c/shared/Elements/Paterson.cpp	(revision 17805)
+++ /issm/trunk/src/c/shared/Elements/Paterson.cpp	(revision 17806)
@@ -11,59 +11,46 @@
 IssmDouble Paterson(IssmDouble temperature){
 
-	/*output: */
-	IssmDouble B;
-	IssmDouble T;
+	IssmDouble B,T;
 
 	/*Switch to celsius from Kelvin: */
 	T=temperature-273.15;
 
-//	%The routine below is equivalent to:
-//	% n=3; T=temperature-273;
-//	% %From Paterson,
-//	% Temp=[0;-2;-5;-10;-15;-20;-25;-30;-35;-40;-45;-50];
-//	% A=[6.8*10^-15;2.4*10^-15;1.6*10^-15;4.9*10^-16;2.9*10^-16;1.7*10^-16;9.4*
-//	% 10^-17;5.1*10^-17;2.7*10^-17;1.4*10^-17;7.3*10^-18;3.6*10^-18];;%s-1(kPa-3)
-//	% %Convert into B B
-//	% B=A.^(-1/n)*10^3; %s^(1/3)Pa
-//	% %Now, do a cubic fit between Temp and B: 
-//	% fittedmodel=fit(Temp,B,'cubicspline');
-//	% B=fittedmodel(temperature);
 
 	if(T<=-45.0){
-		B=pow((IssmPDouble)10,(IssmPDouble)8)*(-0.000292866376675*pow(T+50,3)+ 0.011672640664130*pow(T+50,2)  -0.325004442485481*(T+50)+  6.524779401948101);
+		B=1.e+8*(-0.000292866376675*pow(T+50.,3)+ 0.011672640664130*pow(T+50.,2)  -0.325004442485481*(T+50.)+  6.524779401948101);
 	}
 	else if((T>=-45.0) && (T<=-40.0)){
-		B=pow((IssmPDouble)10,(IssmPDouble)8)*(-0.000292866376675*pow(T+45,3)+ 0.007279645014004*pow(T+45,2)  -0.230243014094813*(T+45)+  5.154964909039554);
+		B=1.e+8*(-0.000292866376675*pow(T+45.,3)+ 0.007279645014004*pow(T+45.,2)  -0.230243014094813*(T+45.)+  5.154964909039554);
 	}
 	else if((T>=-40.0) && (T<=-35.0)){
-		B=pow((IssmPDouble)10,(IssmPDouble)8)*(0.000072737147457*pow(T+40,3)+  0.002886649363879*pow(T+40,2)  -0.179411542205399*(T+40)+  4.149132666831214);
+		B=1.e+8*(0.000072737147457*pow(T+40.,3)+  0.002886649363879*pow(T+40.,2)  -0.179411542205399*(T+40.)+  4.149132666831214);
 	}
 	else if((T>=-35.0) && (T<=-30.0)){
-		B=pow((IssmPDouble)10,(IssmPDouble)8)*(-0.000086144770023*pow(T+35,3)+ 0.003977706575736*pow(T+35,2)  -0.145089762507325*(T+35)+  3.333333333333331);
+		B=1.e+8*(-0.000086144770023*pow(T+35.,3)+ 0.003977706575736*pow(T+35.,2)  -0.145089762507325*(T+35.)+  3.333333333333331);
 	}
 	else if((T>=-30.0) && (T<=-25.0)){
-		B=pow((IssmPDouble)10,(IssmPDouble)8)*(-0.000043984685769*pow(T+30,3)+ 0.002685535025386*pow(T+30,2)  -0.111773554501713*(T+30)+  2.696559088937191);
+		B=1.e+8*(-0.000043984685769*pow(T+30.,3)+ 0.002685535025386*pow(T+30.,2)  -0.111773554501713*(T+30.)+  2.696559088937191);
 	}
 	else if((T>=-25.0) && (T<=-20.0)){
-		B=pow((IssmPDouble)10,(IssmPDouble)8)*(-0.000029799523463*pow(T+25,3)+ 0.002025764738854*pow(T+25,2)  -0.088217055680511*(T+25)+  2.199331606342181);
+		B=1.e+8*(-0.000029799523463*pow(T+25.,3)+ 0.002025764738854*pow(T+25.,2)  -0.088217055680511*(T+25.)+  2.199331606342181);
 	}
 	else if((T>=-20.0) && (T<=-15.0)){
-		B=pow((IssmPDouble)10,(IssmPDouble)8)*(0.000136920904777*pow(T+20,3)+  0.001578771886910*pow(T+20,2)  -0.070194372551690*(T+20)+  1.805165505978111);
+		B=1.e+8*(0.000136920904777*pow(T+20.,3)+  0.001578771886910*pow(T+20.,2)  -0.070194372551690*(T+20.)+  1.805165505978111);
 	}
 	else if((T>=-15.0) && (T<=-10.0)){
-		B=pow((IssmPDouble)10,(IssmPDouble)8)*(-0.000899763781026*pow(T+15,3)+ 0.003632585458564*pow(T+15,2)  -0.044137585824322*(T+15)+  1.510778053489523);
+		B=1.e+8*(-0.000899763781026*pow(T+15.,3)+ 0.003632585458564*pow(T+15.,2)  -0.044137585824322*(T+15.)+  1.510778053489523);
 	}
 	else if((T>=-10.0) && (T<=-5.0)){
-		B=pow((IssmPDouble)10,(IssmPDouble)8)*(0.001676964325070*pow(T+10,3)-  0.009863871256831*pow(T+10,2)  -0.075294014815659*(T+10)+  1.268434288203714);
+		B=1.e+8*(0.001676964325070*pow(T+10.,3)-  0.009863871256831*pow(T+10.,2)  -0.075294014815659*(T+10.)+  1.268434288203714);
 	}
 	else if((T>=-5.0) && (T<=-2.0)){
-		B=pow((IssmPDouble)10,(IssmPDouble)8)*(-0.003748937622487*pow(T+5,3)+0.015290593619213*pow(T+5,2)  -0.048160403003748*(T+5)+  0.854987973338348);
+		B=1.e+8*(-0.003748937622487*pow(T+5.,3)+0.015290593619213*pow(T+5.,2)  -0.048160403003748*(T+5.)+  0.854987973338348);
 	}
 	else{
-		B=pow((IssmPDouble)10,(IssmPDouble)8)*(-0.003748937622488*pow(T+2,3)-0.018449844983174*pow(T+2,2)  -0.057638157095631*(T+2)+  0.746900791092860);
+		B=1.e+8*(-0.003748937622488*pow(T+2.,3)-0.018449844983174*pow(T+2.,2)  -0.057638157095631*(T+2.)+  0.746900791092860);
 	}
 
 	/*B cannot be negative!*/
-	if(B<0) B=pow((IssmPDouble)10,(IssmPDouble)6);
+	if(B<0) B=1.e+6;
 
 	return B;
Index: /issm/trunk/src/c/shared/Elements/elements.h
===================================================================
--- /issm/trunk/src/c/shared/Elements/elements.h	(revision 17805)
+++ /issm/trunk/src/c/shared/Elements/elements.h	(revision 17806)
@@ -8,4 +8,5 @@
 #include "../Numerics/types.h"
 
+IssmDouble Cuffey(IssmDouble temperature);
 IssmDouble Paterson(IssmDouble temperature);
 IssmDouble Arrhenius(IssmDouble temperature,IssmDouble depth,IssmDouble n);
Index: /issm/trunk/src/c/shared/Enum/EnumDefinitions.h
===================================================================
--- /issm/trunk/src/c/shared/Enum/EnumDefinitions.h	(revision 17805)
+++ /issm/trunk/src/c/shared/Enum/EnumDefinitions.h	(revision 17806)
@@ -41,6 +41,6 @@
 	BasalforcingsMeltingRateCorrectionEnum,
 	BasalforcingsMeltingRateEnum,
-	BathymetryEnum,
 	BedEnum,
+	BaseEnum,
 	ConstantsGEnum,
 	ConstantsReferencetemperatureEnum,
@@ -98,7 +98,11 @@
 	SedimentHeadOldEnum,
 	SedimentHeadResidualEnum,
+	EffectivePressureEnum,
 	EplHeadEnum,
 	EplHeadOldEnum,
-  HydrologydcRelTolEnum,
+  EplHeadSlopeXEnum,
+	EplHeadSlopeYEnum,
+	HydrologydcMaxIterEnum,
+	HydrologydcRelTolEnum,
 	HydrologydcSpcsedimentHeadEnum,
 	HydrologydcSedimentCompressibilityEnum,
@@ -108,9 +112,13 @@
 	HydrologydcWaterCompressibilityEnum,
 	HydrologydcSpceplHeadEnum,
-	HydrologydcMaskEplactiveEnum,
+	HydrologydcMaskEplactiveNodeEnum,
+	HydrologydcMaskEplactiveEltEnum,
 	HydrologydcEplCompressibilityEnum,
 	HydrologydcEplPorosityEnum,
+	HydrologydcEplInitialThicknessEnum,
+	HydrologydcEplMaxThicknessEnum,
 	HydrologydcEplThicknessEnum,
-	HydrologydcEplTransmitivityEnum,
+	HydrologydcEplThicknessOldEnum,
+	HydrologydcEplConductivityEnum,
 	HydrologydcIsefficientlayerEnum,
 	HydrologydcSedimentlimitFlagEnum,
@@ -119,9 +127,10 @@
 	HydrologydcLeakageFactorEnum,
 	HydrologydcPenaltyFactorEnum,
+	HydrologydcPenaltyLockEnum,
+	HydrologydcBasalMoulinInputEnum,
 	HydrologyLayerEnum,
 	HydrologySedimentEnum,
 	HydrologyEfficientEnum,
 	HydrologySedimentKmaxEnum,
-	WaterTransferEnum,
 	IndependentObjectEnum,
 	InversionControlParametersEnum,
@@ -155,5 +164,7 @@
 	MaterialsRheologyLawEnum,
 	MaterialsRheologyNEnum,
+	DamageIsdamageEnum,
 	DamageDEnum,
+	DamageFEnum,
 	QmuDamageDEnum,
 	DamageDbarEnum,
@@ -163,4 +174,5 @@
 	DamageC3Enum,
 	DamageC4Enum,
+	DamageElementinterpEnum,
 	DamageHealingEnum,
 	DamageStressThresholdEnum,
@@ -172,4 +184,7 @@
 	DamageSpcdamageEnum,
 	DamageMaxDamageEnum,
+	DamageEquivStressEnum,
+	DamageEvolutionNumRequestedOutputsEnum,
+	DamageEvolutionRequestedOutputsEnum,
 	MaterialsRhoIceEnum,
 	MaterialsRhoWaterEnum,
@@ -178,4 +193,5 @@
 	MaterialsThermalExchangeVelocityEnum,
 	MaterialsThermalconductivityEnum,
+	MaterialsTemperateiceconductivityEnum,
 	MaterialsLithosphereShearModulusEnum,
 	MaterialsLithosphereDensityEnum,
@@ -183,5 +199,5 @@
 	MaterialsMantleDensityEnum,
 	MeshAverageVertexConnectivityEnum,
-	MeshElementonbedEnum,
+	MeshElementonbaseEnum,
 	MeshElementonsurfaceEnum,
 	MeshElements2dEnum,
@@ -194,13 +210,15 @@
 	MeshNumberofverticesEnum,
 	MeshUpperelementsEnum,
-	MeshVertexonbedEnum,
+	MeshVertexonbaseEnum,
 	MeshVertexonsurfaceEnum,
 	MeshXEnum,
 	MeshYEnum,
 	MeshZEnum,
-	MeshTypeEnum,
-	Mesh2DhorizontalEnum,
-	Mesh2DverticalEnum,
-	Mesh3DEnum,
+	MeshElementtypeEnum,
+	DomainTypeEnum,
+	DomainDimensionEnum,
+	Domain2DhorizontalEnum,
+	Domain2DverticalEnum,
+	Domain3DEnum,
 	MiscellaneousNameEnum, //FIXME: only used by qmu, should not be marshalled (already in queueing script)
 	MasstransportHydrostaticAdjustmentEnum,
@@ -209,4 +227,5 @@
 	MasstransportPenaltyFactorEnum,
 	MasstransportSpcthicknessEnum,
+	MasstransportCalvingrateEnum,
 	MasstransportStabilizationEnum,
 	MasstransportVertexPairingEnum,
@@ -225,14 +244,10 @@
 	RiftsNumriftsEnum,
 	RiftsRiftstructEnum,
+	SettingsResultsOnNodesEnum,
 	SettingsIoGatherEnum,
 	SettingsLowmemEnum,
 	SettingsOutputFrequencyEnum,
 	SettingsWaitonlockEnum,
-	SurfaceforcingsDelta18oEnum,
-	SurfaceforcingsDelta18oSurfaceEnum,
-	SurfaceforcingsIsdelta18oEnum,
-	SurfaceforcingsPrecipitationsPresentdayEnum,
-	SurfaceforcingsTemperaturesPresentdayEnum,
-	SurfaceforcingsTemperaturesLgmEnum,
+
 	DebugProfilingEnum,
 	ProfilingCurrentMemEnum,
@@ -245,15 +260,5 @@
 	SteadystateRequestedOutputsEnum,
 	SurfaceEnum,
-	SurfaceforcingsPrecipitationEnum,
-	SurfaceforcingsMassBalanceEnum,
-	SurfaceforcingsIspddEnum,
-	SurfaceforcingsDesfacEnum,
-	SurfaceforcingsS0pEnum,
-	SurfaceforcingsIssmbgradientsEnum,
-	SurfaceforcingsMonthlytemperaturesEnum,
-	SurfaceforcingsHrefEnum,
-	SurfaceforcingsSmbrefEnum,
-	SurfaceforcingsBPosEnum,
-	SurfaceforcingsBNegEnum,
+
 	ThermalIsenthalpyEnum,
 	ThermalIsdynamicbasalspcEnum,
@@ -279,7 +284,33 @@
 	TransientIsthermalEnum,
 	TransientIsgiaEnum,
-	TransientIsdamageEnum,
+	TransientIsdamageevolutionEnum,
+	TransientIshydrologyEnum,
 	TransientNumRequestedOutputsEnum,
 	TransientRequestedOutputsEnum,
+	/*}}}*/
+	/*Surfaceforcings{{{*/
+	SurfaceforcingsEnum,
+	SMBEnum,
+	SurfaceforcingsMassBalanceEnum,
+	SMBpddEnum,
+	SurfaceforcingsDelta18oEnum,
+	SurfaceforcingsDelta18oSurfaceEnum,
+	SurfaceforcingsIsdelta18oEnum,
+	SurfaceforcingsPrecipitationsPresentdayEnum,
+	SurfaceforcingsTemperaturesPresentdayEnum,
+	SurfaceforcingsTemperaturesLgmEnum,
+	SurfaceforcingsPrecipitationEnum,
+	SurfaceforcingsDesfacEnum,
+	SurfaceforcingsS0pEnum,
+	SMBgradientsEnum,
+	SurfaceforcingsMonthlytemperaturesEnum,
+	SurfaceforcingsHrefEnum,
+	SurfaceforcingsSmbrefEnum,
+	SurfaceforcingsBPosEnum,
+	SurfaceforcingsBNegEnum,
+	SMBhenningEnum,
+	/*TO BE REMOVED*/
+	SurfaceforcingsIspddEnum,
+	SurfaceforcingsIssmbgradientsEnum,
 	/*}}}*/
 	/*Solutions and Analyses{{{ */
@@ -297,4 +328,5 @@
 	BalancevelocityAnalysisEnum,
 	BalancevelocitySolutionEnum,
+	L2ProjectionEPLAnalysisEnum,
 	L2ProjectionBaseAnalysisEnum,
 	BedSlopeSolutionEnum,
@@ -317,8 +349,9 @@
 	FreeSurfaceBaseAnalysisEnum,
 	FreeSurfaceTopAnalysisEnum,
+	SurfaceNormalVelocityEnum,
 	ExtrudeFromBaseAnalysisEnum,
 	ExtrudeFromTopAnalysisEnum,
+	DepthAverageAnalysisEnum,
 	SteadystateSolutionEnum,
-	L2ProjectionTopAnalysisEnum,
 	SurfaceSlopeSolutionEnum,
 	SmoothedSurfaceSlopeXAnalysisEnum,
@@ -331,4 +364,7 @@
 	MeshdeformationSolutionEnum,
 	MeshdeformationAnalysisEnum,
+	LevelsetAnalysisEnum,
+	ExtrapolationAnalysisEnum,
+	LsfReinitializationAnalysisEnum,
 	/*}}}*/
 	/*Approximations {{{*/
@@ -377,8 +413,10 @@
 	InputToExtrudeEnum,
 	InputToL2ProjectEnum,
+	InputToDepthaverageEnum,
 	IntParamEnum,
 	IntVecParamEnum,
 	TransientParamEnum,
 	MaticeEnum,
+	MatdamageiceEnum,
 	MatparEnum,
 	NodeEnum,
@@ -388,6 +426,4 @@
 	PengridEnum,
 	PenpairEnum,
-	PentaEnum,
-	PentaInputEnum,
 	ProfilerEnum,
 	MatrixParamEnum,
@@ -407,4 +443,8 @@
 	TriaEnum,
 	TriaInputEnum,
+	TetraEnum,
+	TetraInputEnum,
+	PentaEnum,
+	PentaInputEnum,
 	VertexEnum,
 	VertexPIdEnum,
@@ -447,5 +487,5 @@
 	QmuVzEnum,
 	QmuThicknessEnum,
-	QmuBedEnum,
+	QmuBaseEnum,
 	QmuSurfaceEnum,
 	QmuMeltingEnum,
@@ -499,4 +539,5 @@
 	HydrologyWaterVxEnum,
 	HydrologyWaterVyEnum,
+	SigmaNNEnum,
 	StressTensorEnum,
 	StressTensorxxEnum,
@@ -506,4 +547,19 @@
 	StressTensoryzEnum,
 	StressTensorzzEnum,
+	DeviatoricStressEnum,
+	DeviatoricStressxxEnum,
+	DeviatoricStressxyEnum,
+	DeviatoricStressxzEnum,
+	DeviatoricStressyyEnum,
+	DeviatoricStressyzEnum,
+	DeviatoricStresszzEnum,
+	StrainRateEnum,
+	StrainRatexxEnum,
+	StrainRatexyEnum,
+	StrainRatexzEnum,
+	StrainRateyyEnum,
+	StrainRateyzEnum,
+	StrainRatezzEnum,
+	DivergenceEnum,
 	GiaCrossSectionShapeEnum,
 	GiadWdtEnum,
@@ -519,4 +575,6 @@
 	P2xP1Enum,
 	P1xP2Enum,
+	P1xP3Enum,
+	P2xP4Enum,
 	P1P1Enum,
 	P1P1GLSEnum,
@@ -524,6 +582,6 @@
 	MINIcondensedEnum,
 	TaylorHoodEnum,
-	P2xP4Enum,
-	P1xP3Enum,
+	XTaylorHoodEnum,
+	OneLayerP4zEnum,
 	/*}}}*/
 	/*Results{{{*/
@@ -545,4 +603,13 @@
 	MassfluxatgateNameEnum,
 	MassfluxatgateSegmentsEnum,
+	MisfitNameEnum,
+	MisfitModelEnumEnum,
+	MisfitObservationEnum,
+	MisfitObservationEnumEnum,
+	MisfitTimeinterpolationEnum,
+	MisfitWeightsEnum,
+	MisfitWeightsEnumEnum,
+	SurfaceObservationEnum,
+	WeightsSurfaceObservationEnum,
 	/*}}}*/
 	/*Responses{{{*/
@@ -565,13 +632,22 @@
 	AbsoluteEnum,
 	IncrementalEnum,
+	AugmentedLagrangianREnum,
+	AugmentedLagrangianThetaEnum,
 	/*}}}*/
 	/*Grounding Line{{{*/
+	NoneEnum,
 	AgressiveMigrationEnum,
-	NoneEnum,
 	SoftMigrationEnum,
 	SubelementMigrationEnum,
 	SubelementMigration2Enum,
+	ContactEnum,
 	MaskGroundediceLevelsetEnum,
 	QmuMaskGroundediceLevelsetEnum,
+	/*}}}*/
+	/*Gauss{{{*/
+	GaussSegEnum,
+	GaussTriaEnum,
+	GaussTetraEnum,
+	GaussPentaEnum,
 	/*}}}*/
 	/*Solver{{{*/
@@ -632,8 +708,17 @@
 	OptionStructEnum,
 	/*}}}*/
-	/*Rheology law (move too Material) {{{*/
+	/*Rheology law (move to Material) {{{*/
+	CuffeyEnum,
 	PatersonEnum,
 	ArrheniusEnum,
 	LliboutryDuvalEnum,
+	/*}}}*/
+	/*Levelset related enums (will be moved to appropriate place when finished){{{*/
+	TransientIslevelsetEnum,
+	ExtrapolationVariableEnum,
+	IceMaskNodeActivationEnum,
+	LevelsetfunctionSlopeXEnum,
+	LevelsetfunctionSlopeYEnum,
+	LevelsetfunctionPicardEnum,
 	/*}}}*/
 	MaximumNumberOfDefinitionsEnum
Index: /issm/trunk/src/c/shared/Enum/EnumToStringx.cpp
===================================================================
--- /issm/trunk/src/c/shared/Enum/EnumToStringx.cpp	(revision 17805)
+++ /issm/trunk/src/c/shared/Enum/EnumToStringx.cpp	(revision 17806)
@@ -49,6 +49,6 @@
 		case BasalforcingsMeltingRateCorrectionEnum : return "BasalforcingsMeltingRateCorrection";
 		case BasalforcingsMeltingRateEnum : return "BasalforcingsMeltingRate";
-		case BathymetryEnum : return "Bathymetry";
 		case BedEnum : return "Bed";
+		case BaseEnum : return "Base";
 		case ConstantsGEnum : return "ConstantsG";
 		case ConstantsReferencetemperatureEnum : return "ConstantsReferencetemperature";
@@ -106,6 +106,10 @@
 		case SedimentHeadOldEnum : return "SedimentHeadOld";
 		case SedimentHeadResidualEnum : return "SedimentHeadResidual";
+		case EffectivePressureEnum : return "EffectivePressure";
 		case EplHeadEnum : return "EplHead";
 		case EplHeadOldEnum : return "EplHeadOld";
+		case EplHeadSlopeXEnum : return "EplHeadSlopeX";
+		case EplHeadSlopeYEnum : return "EplHeadSlopeY";
+		case HydrologydcMaxIterEnum : return "HydrologydcMaxIter";
 		case HydrologydcRelTolEnum : return "HydrologydcRelTol";
 		case HydrologydcSpcsedimentHeadEnum : return "HydrologydcSpcsedimentHead";
@@ -116,9 +120,13 @@
 		case HydrologydcWaterCompressibilityEnum : return "HydrologydcWaterCompressibility";
 		case HydrologydcSpceplHeadEnum : return "HydrologydcSpceplHead";
-		case HydrologydcMaskEplactiveEnum : return "HydrologydcMaskEplactive";
+		case HydrologydcMaskEplactiveNodeEnum : return "HydrologydcMaskEplactiveNode";
+		case HydrologydcMaskEplactiveEltEnum : return "HydrologydcMaskEplactiveElt";
 		case HydrologydcEplCompressibilityEnum : return "HydrologydcEplCompressibility";
 		case HydrologydcEplPorosityEnum : return "HydrologydcEplPorosity";
+		case HydrologydcEplInitialThicknessEnum : return "HydrologydcEplInitialThickness";
+		case HydrologydcEplMaxThicknessEnum : return "HydrologydcEplMaxThickness";
 		case HydrologydcEplThicknessEnum : return "HydrologydcEplThickness";
-		case HydrologydcEplTransmitivityEnum : return "HydrologydcEplTransmitivity";
+		case HydrologydcEplThicknessOldEnum : return "HydrologydcEplThicknessOld";
+		case HydrologydcEplConductivityEnum : return "HydrologydcEplConductivity";
 		case HydrologydcIsefficientlayerEnum : return "HydrologydcIsefficientlayer";
 		case HydrologydcSedimentlimitFlagEnum : return "HydrologydcSedimentlimitFlag";
@@ -127,9 +135,10 @@
 		case HydrologydcLeakageFactorEnum : return "HydrologydcLeakageFactor";
 		case HydrologydcPenaltyFactorEnum : return "HydrologydcPenaltyFactor";
+		case HydrologydcPenaltyLockEnum : return "HydrologydcPenaltyLock";
+		case HydrologydcBasalMoulinInputEnum : return "HydrologydcBasalMoulinInput";
 		case HydrologyLayerEnum : return "HydrologyLayer";
 		case HydrologySedimentEnum : return "HydrologySediment";
 		case HydrologyEfficientEnum : return "HydrologyEfficient";
 		case HydrologySedimentKmaxEnum : return "HydrologySedimentKmax";
-		case WaterTransferEnum : return "WaterTransfer";
 		case IndependentObjectEnum : return "IndependentObject";
 		case InversionControlParametersEnum : return "InversionControlParameters";
@@ -163,5 +172,7 @@
 		case MaterialsRheologyLawEnum : return "MaterialsRheologyLaw";
 		case MaterialsRheologyNEnum : return "MaterialsRheologyN";
+		case DamageIsdamageEnum : return "DamageIsdamage";
 		case DamageDEnum : return "DamageD";
+		case DamageFEnum : return "DamageF";
 		case QmuDamageDEnum : return "QmuDamageD";
 		case DamageDbarEnum : return "DamageDbar";
@@ -171,4 +182,5 @@
 		case DamageC3Enum : return "DamageC3";
 		case DamageC4Enum : return "DamageC4";
+		case DamageElementinterpEnum : return "DamageElementinterp";
 		case DamageHealingEnum : return "DamageHealing";
 		case DamageStressThresholdEnum : return "DamageStressThreshold";
@@ -180,4 +192,7 @@
 		case DamageSpcdamageEnum : return "DamageSpcdamage";
 		case DamageMaxDamageEnum : return "DamageMaxDamage";
+		case DamageEquivStressEnum : return "DamageEquivStress";
+		case DamageEvolutionNumRequestedOutputsEnum : return "DamageEvolutionNumRequestedOutputs";
+		case DamageEvolutionRequestedOutputsEnum : return "DamageEvolutionRequestedOutputs";
 		case MaterialsRhoIceEnum : return "MaterialsRhoIce";
 		case MaterialsRhoWaterEnum : return "MaterialsRhoWater";
@@ -186,4 +201,5 @@
 		case MaterialsThermalExchangeVelocityEnum : return "MaterialsThermalExchangeVelocity";
 		case MaterialsThermalconductivityEnum : return "MaterialsThermalconductivity";
+		case MaterialsTemperateiceconductivityEnum : return "MaterialsTemperateiceconductivity";
 		case MaterialsLithosphereShearModulusEnum : return "MaterialsLithosphereShearModulus";
 		case MaterialsLithosphereDensityEnum : return "MaterialsLithosphereDensity";
@@ -191,5 +207,5 @@
 		case MaterialsMantleDensityEnum : return "MaterialsMantleDensity";
 		case MeshAverageVertexConnectivityEnum : return "MeshAverageVertexConnectivity";
-		case MeshElementonbedEnum : return "MeshElementonbed";
+		case MeshElementonbaseEnum : return "MeshElementonbase";
 		case MeshElementonsurfaceEnum : return "MeshElementonsurface";
 		case MeshElements2dEnum : return "MeshElements2d";
@@ -202,13 +218,15 @@
 		case MeshNumberofverticesEnum : return "MeshNumberofvertices";
 		case MeshUpperelementsEnum : return "MeshUpperelements";
-		case MeshVertexonbedEnum : return "MeshVertexonbed";
+		case MeshVertexonbaseEnum : return "MeshVertexonbase";
 		case MeshVertexonsurfaceEnum : return "MeshVertexonsurface";
 		case MeshXEnum : return "MeshX";
 		case MeshYEnum : return "MeshY";
 		case MeshZEnum : return "MeshZ";
-		case MeshTypeEnum : return "MeshType";
-		case Mesh2DhorizontalEnum : return "Mesh2Dhorizontal";
-		case Mesh2DverticalEnum : return "Mesh2Dvertical";
-		case Mesh3DEnum : return "Mesh3D";
+		case MeshElementtypeEnum : return "MeshElementtype";
+		case DomainTypeEnum : return "DomainType";
+		case DomainDimensionEnum : return "DomainDimension";
+		case Domain2DhorizontalEnum : return "Domain2Dhorizontal";
+		case Domain2DverticalEnum : return "Domain2Dvertical";
+		case Domain3DEnum : return "Domain3D";
 		case MiscellaneousNameEnum : return "MiscellaneousName";
 		case MasstransportHydrostaticAdjustmentEnum : return "MasstransportHydrostaticAdjustment";
@@ -217,4 +235,5 @@
 		case MasstransportPenaltyFactorEnum : return "MasstransportPenaltyFactor";
 		case MasstransportSpcthicknessEnum : return "MasstransportSpcthickness";
+		case MasstransportCalvingrateEnum : return "MasstransportCalvingrate";
 		case MasstransportStabilizationEnum : return "MasstransportStabilization";
 		case MasstransportVertexPairingEnum : return "MasstransportVertexPairing";
@@ -233,14 +252,9 @@
 		case RiftsNumriftsEnum : return "RiftsNumrifts";
 		case RiftsRiftstructEnum : return "RiftsRiftstruct";
+		case SettingsResultsOnNodesEnum : return "SettingsResultsOnNodes";
 		case SettingsIoGatherEnum : return "SettingsIoGather";
 		case SettingsLowmemEnum : return "SettingsLowmem";
 		case SettingsOutputFrequencyEnum : return "SettingsOutputFrequency";
 		case SettingsWaitonlockEnum : return "SettingsWaitonlock";
-		case SurfaceforcingsDelta18oEnum : return "SurfaceforcingsDelta18o";
-		case SurfaceforcingsDelta18oSurfaceEnum : return "SurfaceforcingsDelta18oSurface";
-		case SurfaceforcingsIsdelta18oEnum : return "SurfaceforcingsIsdelta18o";
-		case SurfaceforcingsPrecipitationsPresentdayEnum : return "SurfaceforcingsPrecipitationsPresentday";
-		case SurfaceforcingsTemperaturesPresentdayEnum : return "SurfaceforcingsTemperaturesPresentday";
-		case SurfaceforcingsTemperaturesLgmEnum : return "SurfaceforcingsTemperaturesLgm";
 		case DebugProfilingEnum : return "DebugProfiling";
 		case ProfilingCurrentMemEnum : return "ProfilingCurrentMem";
@@ -253,15 +267,4 @@
 		case SteadystateRequestedOutputsEnum : return "SteadystateRequestedOutputs";
 		case SurfaceEnum : return "Surface";
-		case SurfaceforcingsPrecipitationEnum : return "SurfaceforcingsPrecipitation";
-		case SurfaceforcingsMassBalanceEnum : return "SurfaceforcingsMassBalance";
-		case SurfaceforcingsIspddEnum : return "SurfaceforcingsIspdd";
-		case SurfaceforcingsDesfacEnum : return "SurfaceforcingsDesfac";
-		case SurfaceforcingsS0pEnum : return "SurfaceforcingsS0p";
-		case SurfaceforcingsIssmbgradientsEnum : return "SurfaceforcingsIssmbgradients";
-		case SurfaceforcingsMonthlytemperaturesEnum : return "SurfaceforcingsMonthlytemperatures";
-		case SurfaceforcingsHrefEnum : return "SurfaceforcingsHref";
-		case SurfaceforcingsSmbrefEnum : return "SurfaceforcingsSmbref";
-		case SurfaceforcingsBPosEnum : return "SurfaceforcingsBPos";
-		case SurfaceforcingsBNegEnum : return "SurfaceforcingsBNeg";
 		case ThermalIsenthalpyEnum : return "ThermalIsenthalpy";
 		case ThermalIsdynamicbasalspcEnum : return "ThermalIsdynamicbasalspc";
@@ -287,7 +290,30 @@
 		case TransientIsthermalEnum : return "TransientIsthermal";
 		case TransientIsgiaEnum : return "TransientIsgia";
-		case TransientIsdamageEnum : return "TransientIsdamage";
+		case TransientIsdamageevolutionEnum : return "TransientIsdamageevolution";
+		case TransientIshydrologyEnum : return "TransientIshydrology";
 		case TransientNumRequestedOutputsEnum : return "TransientNumRequestedOutputs";
 		case TransientRequestedOutputsEnum : return "TransientRequestedOutputs";
+		case SurfaceforcingsEnum : return "Surfaceforcings";
+		case SMBEnum : return "SMB";
+		case SurfaceforcingsMassBalanceEnum : return "SurfaceforcingsMassBalance";
+		case SMBpddEnum : return "SMBpdd";
+		case SurfaceforcingsDelta18oEnum : return "SurfaceforcingsDelta18o";
+		case SurfaceforcingsDelta18oSurfaceEnum : return "SurfaceforcingsDelta18oSurface";
+		case SurfaceforcingsIsdelta18oEnum : return "SurfaceforcingsIsdelta18o";
+		case SurfaceforcingsPrecipitationsPresentdayEnum : return "SurfaceforcingsPrecipitationsPresentday";
+		case SurfaceforcingsTemperaturesPresentdayEnum : return "SurfaceforcingsTemperaturesPresentday";
+		case SurfaceforcingsTemperaturesLgmEnum : return "SurfaceforcingsTemperaturesLgm";
+		case SurfaceforcingsPrecipitationEnum : return "SurfaceforcingsPrecipitation";
+		case SurfaceforcingsDesfacEnum : return "SurfaceforcingsDesfac";
+		case SurfaceforcingsS0pEnum : return "SurfaceforcingsS0p";
+		case SMBgradientsEnum : return "SMBgradients";
+		case SurfaceforcingsMonthlytemperaturesEnum : return "SurfaceforcingsMonthlytemperatures";
+		case SurfaceforcingsHrefEnum : return "SurfaceforcingsHref";
+		case SurfaceforcingsSmbrefEnum : return "SurfaceforcingsSmbref";
+		case SurfaceforcingsBPosEnum : return "SurfaceforcingsBPos";
+		case SurfaceforcingsBNegEnum : return "SurfaceforcingsBNeg";
+		case SMBhenningEnum : return "SMBhenning";
+		case SurfaceforcingsIspddEnum : return "SurfaceforcingsIspdd";
+		case SurfaceforcingsIssmbgradientsEnum : return "SurfaceforcingsIssmbgradients";
 		case SolutionTypeEnum : return "SolutionType";
 		case AnalysisTypeEnum : return "AnalysisType";
@@ -303,4 +329,5 @@
 		case BalancevelocityAnalysisEnum : return "BalancevelocityAnalysis";
 		case BalancevelocitySolutionEnum : return "BalancevelocitySolution";
+		case L2ProjectionEPLAnalysisEnum : return "L2ProjectionEPLAnalysis";
 		case L2ProjectionBaseAnalysisEnum : return "L2ProjectionBaseAnalysis";
 		case BedSlopeSolutionEnum : return "BedSlopeSolution";
@@ -323,8 +350,9 @@
 		case FreeSurfaceBaseAnalysisEnum : return "FreeSurfaceBaseAnalysis";
 		case FreeSurfaceTopAnalysisEnum : return "FreeSurfaceTopAnalysis";
+		case SurfaceNormalVelocityEnum : return "SurfaceNormalVelocity";
 		case ExtrudeFromBaseAnalysisEnum : return "ExtrudeFromBaseAnalysis";
 		case ExtrudeFromTopAnalysisEnum : return "ExtrudeFromTopAnalysis";
+		case DepthAverageAnalysisEnum : return "DepthAverageAnalysis";
 		case SteadystateSolutionEnum : return "SteadystateSolution";
-		case L2ProjectionTopAnalysisEnum : return "L2ProjectionTopAnalysis";
 		case SurfaceSlopeSolutionEnum : return "SurfaceSlopeSolution";
 		case SmoothedSurfaceSlopeXAnalysisEnum : return "SmoothedSurfaceSlopeXAnalysis";
@@ -337,4 +365,7 @@
 		case MeshdeformationSolutionEnum : return "MeshdeformationSolution";
 		case MeshdeformationAnalysisEnum : return "MeshdeformationAnalysis";
+		case LevelsetAnalysisEnum : return "LevelsetAnalysis";
+		case ExtrapolationAnalysisEnum : return "ExtrapolationAnalysis";
+		case LsfReinitializationAnalysisEnum : return "LsfReinitializationAnalysis";
 		case ApproximationEnum : return "Approximation";
 		case NoneApproximationEnum : return "NoneApproximation";
@@ -377,8 +408,10 @@
 		case InputToExtrudeEnum : return "InputToExtrude";
 		case InputToL2ProjectEnum : return "InputToL2Project";
+		case InputToDepthaverageEnum : return "InputToDepthaverage";
 		case IntParamEnum : return "IntParam";
 		case IntVecParamEnum : return "IntVecParam";
 		case TransientParamEnum : return "TransientParam";
 		case MaticeEnum : return "Matice";
+		case MatdamageiceEnum : return "Matdamageice";
 		case MatparEnum : return "Matpar";
 		case NodeEnum : return "Node";
@@ -388,6 +421,4 @@
 		case PengridEnum : return "Pengrid";
 		case PenpairEnum : return "Penpair";
-		case PentaEnum : return "Penta";
-		case PentaInputEnum : return "PentaInput";
 		case ProfilerEnum : return "Profiler";
 		case MatrixParamEnum : return "MatrixParam";
@@ -407,4 +438,8 @@
 		case TriaEnum : return "Tria";
 		case TriaInputEnum : return "TriaInput";
+		case TetraEnum : return "Tetra";
+		case TetraInputEnum : return "TetraInput";
+		case PentaEnum : return "Penta";
+		case PentaInputEnum : return "PentaInput";
 		case VertexEnum : return "Vertex";
 		case VertexPIdEnum : return "VertexPId";
@@ -441,5 +476,5 @@
 		case QmuVzEnum : return "QmuVz";
 		case QmuThicknessEnum : return "QmuThickness";
-		case QmuBedEnum : return "QmuBed";
+		case QmuBaseEnum : return "QmuBase";
 		case QmuSurfaceEnum : return "QmuSurface";
 		case QmuMeltingEnum : return "QmuMelting";
@@ -493,4 +528,5 @@
 		case HydrologyWaterVxEnum : return "HydrologyWaterVx";
 		case HydrologyWaterVyEnum : return "HydrologyWaterVy";
+		case SigmaNNEnum : return "SigmaNN";
 		case StressTensorEnum : return "StressTensor";
 		case StressTensorxxEnum : return "StressTensorxx";
@@ -500,4 +536,19 @@
 		case StressTensoryzEnum : return "StressTensoryz";
 		case StressTensorzzEnum : return "StressTensorzz";
+		case DeviatoricStressEnum : return "DeviatoricStress";
+		case DeviatoricStressxxEnum : return "DeviatoricStressxx";
+		case DeviatoricStressxyEnum : return "DeviatoricStressxy";
+		case DeviatoricStressxzEnum : return "DeviatoricStressxz";
+		case DeviatoricStressyyEnum : return "DeviatoricStressyy";
+		case DeviatoricStressyzEnum : return "DeviatoricStressyz";
+		case DeviatoricStresszzEnum : return "DeviatoricStresszz";
+		case StrainRateEnum : return "StrainRate";
+		case StrainRatexxEnum : return "StrainRatexx";
+		case StrainRatexyEnum : return "StrainRatexy";
+		case StrainRatexzEnum : return "StrainRatexz";
+		case StrainRateyyEnum : return "StrainRateyy";
+		case StrainRateyzEnum : return "StrainRateyz";
+		case StrainRatezzEnum : return "StrainRatezz";
+		case DivergenceEnum : return "Divergence";
 		case GiaCrossSectionShapeEnum : return "GiaCrossSectionShape";
 		case GiadWdtEnum : return "GiadWdt";
@@ -511,4 +562,6 @@
 		case P2xP1Enum : return "P2xP1";
 		case P1xP2Enum : return "P1xP2";
+		case P1xP3Enum : return "P1xP3";
+		case P2xP4Enum : return "P2xP4";
 		case P1P1Enum : return "P1P1";
 		case P1P1GLSEnum : return "P1P1GLS";
@@ -516,6 +569,6 @@
 		case MINIcondensedEnum : return "MINIcondensed";
 		case TaylorHoodEnum : return "TaylorHood";
-		case P2xP4Enum : return "P2xP4";
-		case P1xP3Enum : return "P1xP3";
+		case XTaylorHoodEnum : return "XTaylorHood";
+		case OneLayerP4zEnum : return "OneLayerP4z";
 		case SaveResultsEnum : return "SaveResults";
 		case BoolExternalResultEnum : return "BoolExternalResult";
@@ -533,4 +586,13 @@
 		case MassfluxatgateNameEnum : return "MassfluxatgateName";
 		case MassfluxatgateSegmentsEnum : return "MassfluxatgateSegments";
+		case MisfitNameEnum : return "MisfitName";
+		case MisfitModelEnumEnum : return "MisfitModelEnum";
+		case MisfitObservationEnum : return "MisfitObservation";
+		case MisfitObservationEnumEnum : return "MisfitObservationEnum";
+		case MisfitTimeinterpolationEnum : return "MisfitTimeinterpolation";
+		case MisfitWeightsEnum : return "MisfitWeights";
+		case MisfitWeightsEnumEnum : return "MisfitWeightsEnum";
+		case SurfaceObservationEnum : return "SurfaceObservation";
+		case WeightsSurfaceObservationEnum : return "WeightsSurfaceObservation";
 		case MinVelEnum : return "MinVel";
 		case MaxVelEnum : return "MaxVel";
@@ -549,11 +611,18 @@
 		case AbsoluteEnum : return "Absolute";
 		case IncrementalEnum : return "Incremental";
+		case AugmentedLagrangianREnum : return "AugmentedLagrangianR";
+		case AugmentedLagrangianThetaEnum : return "AugmentedLagrangianTheta";
+		case NoneEnum : return "None";
 		case AgressiveMigrationEnum : return "AgressiveMigration";
-		case NoneEnum : return "None";
 		case SoftMigrationEnum : return "SoftMigration";
 		case SubelementMigrationEnum : return "SubelementMigration";
 		case SubelementMigration2Enum : return "SubelementMigration2";
+		case ContactEnum : return "Contact";
 		case MaskGroundediceLevelsetEnum : return "MaskGroundediceLevelset";
 		case QmuMaskGroundediceLevelsetEnum : return "QmuMaskGroundediceLevelset";
+		case GaussSegEnum : return "GaussSeg";
+		case GaussTriaEnum : return "GaussTria";
+		case GaussTetraEnum : return "GaussTetra";
+		case GaussPentaEnum : return "GaussPenta";
 		case FSSolverEnum : return "FSSolver";
 		case AdjointEnum : return "Adjoint";
@@ -601,7 +670,14 @@
 		case OptionCellEnum : return "OptionCell";
 		case OptionStructEnum : return "OptionStruct";
+		case CuffeyEnum : return "Cuffey";
 		case PatersonEnum : return "Paterson";
 		case ArrheniusEnum : return "Arrhenius";
 		case LliboutryDuvalEnum : return "LliboutryDuval";
+		case TransientIslevelsetEnum : return "TransientIslevelset";
+		case ExtrapolationVariableEnum : return "ExtrapolationVariable";
+		case IceMaskNodeActivationEnum : return "IceMaskNodeActivation";
+		case LevelsetfunctionSlopeXEnum : return "LevelsetfunctionSlopeX";
+		case LevelsetfunctionSlopeYEnum : return "LevelsetfunctionSlopeY";
+		case LevelsetfunctionPicardEnum : return "LevelsetfunctionPicard";
 		case MaximumNumberOfDefinitionsEnum : return "MaximumNumberOfDefinitions";
 		default : return "unknown";
Index: /issm/trunk/src/c/shared/Enum/StringToEnumx.cpp
===================================================================
--- /issm/trunk/src/c/shared/Enum/StringToEnumx.cpp	(revision 17805)
+++ /issm/trunk/src/c/shared/Enum/StringToEnumx.cpp	(revision 17806)
@@ -49,6 +49,6 @@
 	      else if (strcmp(name,"BasalforcingsMeltingRateCorrection")==0) return BasalforcingsMeltingRateCorrectionEnum;
 	      else if (strcmp(name,"BasalforcingsMeltingRate")==0) return BasalforcingsMeltingRateEnum;
-	      else if (strcmp(name,"Bathymetry")==0) return BathymetryEnum;
 	      else if (strcmp(name,"Bed")==0) return BedEnum;
+	      else if (strcmp(name,"Base")==0) return BaseEnum;
 	      else if (strcmp(name,"ConstantsG")==0) return ConstantsGEnum;
 	      else if (strcmp(name,"ConstantsReferencetemperature")==0) return ConstantsReferencetemperatureEnum;
@@ -106,6 +106,10 @@
 	      else if (strcmp(name,"SedimentHeadOld")==0) return SedimentHeadOldEnum;
 	      else if (strcmp(name,"SedimentHeadResidual")==0) return SedimentHeadResidualEnum;
+	      else if (strcmp(name,"EffectivePressure")==0) return EffectivePressureEnum;
 	      else if (strcmp(name,"EplHead")==0) return EplHeadEnum;
 	      else if (strcmp(name,"EplHeadOld")==0) return EplHeadOldEnum;
+	      else if (strcmp(name,"EplHeadSlopeX")==0) return EplHeadSlopeXEnum;
+	      else if (strcmp(name,"EplHeadSlopeY")==0) return EplHeadSlopeYEnum;
+	      else if (strcmp(name,"HydrologydcMaxIter")==0) return HydrologydcMaxIterEnum;
 	      else if (strcmp(name,"HydrologydcRelTol")==0) return HydrologydcRelTolEnum;
 	      else if (strcmp(name,"HydrologydcSpcsedimentHead")==0) return HydrologydcSpcsedimentHeadEnum;
@@ -116,9 +120,13 @@
 	      else if (strcmp(name,"HydrologydcWaterCompressibility")==0) return HydrologydcWaterCompressibilityEnum;
 	      else if (strcmp(name,"HydrologydcSpceplHead")==0) return HydrologydcSpceplHeadEnum;
-	      else if (strcmp(name,"HydrologydcMaskEplactive")==0) return HydrologydcMaskEplactiveEnum;
+	      else if (strcmp(name,"HydrologydcMaskEplactiveNode")==0) return HydrologydcMaskEplactiveNodeEnum;
+	      else if (strcmp(name,"HydrologydcMaskEplactiveElt")==0) return HydrologydcMaskEplactiveEltEnum;
 	      else if (strcmp(name,"HydrologydcEplCompressibility")==0) return HydrologydcEplCompressibilityEnum;
 	      else if (strcmp(name,"HydrologydcEplPorosity")==0) return HydrologydcEplPorosityEnum;
+	      else if (strcmp(name,"HydrologydcEplInitialThickness")==0) return HydrologydcEplInitialThicknessEnum;
+	      else if (strcmp(name,"HydrologydcEplMaxThickness")==0) return HydrologydcEplMaxThicknessEnum;
 	      else if (strcmp(name,"HydrologydcEplThickness")==0) return HydrologydcEplThicknessEnum;
-	      else if (strcmp(name,"HydrologydcEplTransmitivity")==0) return HydrologydcEplTransmitivityEnum;
+	      else if (strcmp(name,"HydrologydcEplThicknessOld")==0) return HydrologydcEplThicknessOldEnum;
+	      else if (strcmp(name,"HydrologydcEplConductivity")==0) return HydrologydcEplConductivityEnum;
 	      else if (strcmp(name,"HydrologydcIsefficientlayer")==0) return HydrologydcIsefficientlayerEnum;
 	      else if (strcmp(name,"HydrologydcSedimentlimitFlag")==0) return HydrologydcSedimentlimitFlagEnum;
@@ -127,9 +135,13 @@
 	      else if (strcmp(name,"HydrologydcLeakageFactor")==0) return HydrologydcLeakageFactorEnum;
 	      else if (strcmp(name,"HydrologydcPenaltyFactor")==0) return HydrologydcPenaltyFactorEnum;
-	      else if (strcmp(name,"HydrologyLayer")==0) return HydrologyLayerEnum;
+	      else if (strcmp(name,"HydrologydcPenaltyLock")==0) return HydrologydcPenaltyLockEnum;
+	      else if (strcmp(name,"HydrologydcBasalMoulinInput")==0) return HydrologydcBasalMoulinInputEnum;
+         else stage=2;
+   }
+   if(stage==2){
+	      if (strcmp(name,"HydrologyLayer")==0) return HydrologyLayerEnum;
 	      else if (strcmp(name,"HydrologySediment")==0) return HydrologySedimentEnum;
 	      else if (strcmp(name,"HydrologyEfficient")==0) return HydrologyEfficientEnum;
 	      else if (strcmp(name,"HydrologySedimentKmax")==0) return HydrologySedimentKmaxEnum;
-	      else if (strcmp(name,"WaterTransfer")==0) return WaterTransferEnum;
 	      else if (strcmp(name,"IndependentObject")==0) return IndependentObjectEnum;
 	      else if (strcmp(name,"InversionControlParameters")==0) return InversionControlParametersEnum;
@@ -137,8 +149,5 @@
 	      else if (strcmp(name,"InversionCostFunctionsCoefficients")==0) return InversionCostFunctionsCoefficientsEnum;
 	      else if (strcmp(name,"InversionCostFunctions")==0) return InversionCostFunctionsEnum;
-         else stage=2;
-   }
-   if(stage==2){
-	      if (strcmp(name,"InversionGradientScaling")==0) return InversionGradientScalingEnum;
+	      else if (strcmp(name,"InversionGradientScaling")==0) return InversionGradientScalingEnum;
 	      else if (strcmp(name,"InversionIscontrol")==0) return InversionIscontrolEnum;
 	      else if (strcmp(name,"InversionTao")==0) return InversionTaoEnum;
@@ -166,5 +175,7 @@
 	      else if (strcmp(name,"MaterialsRheologyLaw")==0) return MaterialsRheologyLawEnum;
 	      else if (strcmp(name,"MaterialsRheologyN")==0) return MaterialsRheologyNEnum;
+	      else if (strcmp(name,"DamageIsdamage")==0) return DamageIsdamageEnum;
 	      else if (strcmp(name,"DamageD")==0) return DamageDEnum;
+	      else if (strcmp(name,"DamageF")==0) return DamageFEnum;
 	      else if (strcmp(name,"QmuDamageD")==0) return QmuDamageDEnum;
 	      else if (strcmp(name,"DamageDbar")==0) return DamageDbarEnum;
@@ -174,4 +185,5 @@
 	      else if (strcmp(name,"DamageC3")==0) return DamageC3Enum;
 	      else if (strcmp(name,"DamageC4")==0) return DamageC4Enum;
+	      else if (strcmp(name,"DamageElementinterp")==0) return DamageElementinterpEnum;
 	      else if (strcmp(name,"DamageHealing")==0) return DamageHealingEnum;
 	      else if (strcmp(name,"DamageStressThreshold")==0) return DamageStressThresholdEnum;
@@ -183,4 +195,7 @@
 	      else if (strcmp(name,"DamageSpcdamage")==0) return DamageSpcdamageEnum;
 	      else if (strcmp(name,"DamageMaxDamage")==0) return DamageMaxDamageEnum;
+	      else if (strcmp(name,"DamageEquivStress")==0) return DamageEquivStressEnum;
+	      else if (strcmp(name,"DamageEvolutionNumRequestedOutputs")==0) return DamageEvolutionNumRequestedOutputsEnum;
+	      else if (strcmp(name,"DamageEvolutionRequestedOutputs")==0) return DamageEvolutionRequestedOutputsEnum;
 	      else if (strcmp(name,"MaterialsRhoIce")==0) return MaterialsRhoIceEnum;
 	      else if (strcmp(name,"MaterialsRhoWater")==0) return MaterialsRhoWaterEnum;
@@ -189,4 +204,5 @@
 	      else if (strcmp(name,"MaterialsThermalExchangeVelocity")==0) return MaterialsThermalExchangeVelocityEnum;
 	      else if (strcmp(name,"MaterialsThermalconductivity")==0) return MaterialsThermalconductivityEnum;
+	      else if (strcmp(name,"MaterialsTemperateiceconductivity")==0) return MaterialsTemperateiceconductivityEnum;
 	      else if (strcmp(name,"MaterialsLithosphereShearModulus")==0) return MaterialsLithosphereShearModulusEnum;
 	      else if (strcmp(name,"MaterialsLithosphereDensity")==0) return MaterialsLithosphereDensityEnum;
@@ -194,5 +210,5 @@
 	      else if (strcmp(name,"MaterialsMantleDensity")==0) return MaterialsMantleDensityEnum;
 	      else if (strcmp(name,"MeshAverageVertexConnectivity")==0) return MeshAverageVertexConnectivityEnum;
-	      else if (strcmp(name,"MeshElementonbed")==0) return MeshElementonbedEnum;
+	      else if (strcmp(name,"MeshElementonbase")==0) return MeshElementonbaseEnum;
 	      else if (strcmp(name,"MeshElementonsurface")==0) return MeshElementonsurfaceEnum;
 	      else if (strcmp(name,"MeshElements2d")==0) return MeshElements2dEnum;
@@ -205,13 +221,15 @@
 	      else if (strcmp(name,"MeshNumberofvertices")==0) return MeshNumberofverticesEnum;
 	      else if (strcmp(name,"MeshUpperelements")==0) return MeshUpperelementsEnum;
-	      else if (strcmp(name,"MeshVertexonbed")==0) return MeshVertexonbedEnum;
+	      else if (strcmp(name,"MeshVertexonbase")==0) return MeshVertexonbaseEnum;
 	      else if (strcmp(name,"MeshVertexonsurface")==0) return MeshVertexonsurfaceEnum;
 	      else if (strcmp(name,"MeshX")==0) return MeshXEnum;
 	      else if (strcmp(name,"MeshY")==0) return MeshYEnum;
 	      else if (strcmp(name,"MeshZ")==0) return MeshZEnum;
-	      else if (strcmp(name,"MeshType")==0) return MeshTypeEnum;
-	      else if (strcmp(name,"Mesh2Dhorizontal")==0) return Mesh2DhorizontalEnum;
-	      else if (strcmp(name,"Mesh2Dvertical")==0) return Mesh2DverticalEnum;
-	      else if (strcmp(name,"Mesh3D")==0) return Mesh3DEnum;
+	      else if (strcmp(name,"MeshElementtype")==0) return MeshElementtypeEnum;
+	      else if (strcmp(name,"DomainType")==0) return DomainTypeEnum;
+	      else if (strcmp(name,"DomainDimension")==0) return DomainDimensionEnum;
+	      else if (strcmp(name,"Domain2Dhorizontal")==0) return Domain2DhorizontalEnum;
+	      else if (strcmp(name,"Domain2Dvertical")==0) return Domain2DverticalEnum;
+	      else if (strcmp(name,"Domain3D")==0) return Domain3DEnum;
 	      else if (strcmp(name,"MiscellaneousName")==0) return MiscellaneousNameEnum;
 	      else if (strcmp(name,"MasstransportHydrostaticAdjustment")==0) return MasstransportHydrostaticAdjustmentEnum;
@@ -220,4 +238,5 @@
 	      else if (strcmp(name,"MasstransportPenaltyFactor")==0) return MasstransportPenaltyFactorEnum;
 	      else if (strcmp(name,"MasstransportSpcthickness")==0) return MasstransportSpcthicknessEnum;
+	      else if (strcmp(name,"MasstransportCalvingrate")==0) return MasstransportCalvingrateEnum;
 	      else if (strcmp(name,"MasstransportStabilization")==0) return MasstransportStabilizationEnum;
 	      else if (strcmp(name,"MasstransportVertexPairing")==0) return MasstransportVertexPairingEnum;
@@ -236,15 +255,13 @@
 	      else if (strcmp(name,"RiftsNumrifts")==0) return RiftsNumriftsEnum;
 	      else if (strcmp(name,"RiftsRiftstruct")==0) return RiftsRiftstructEnum;
+	      else if (strcmp(name,"SettingsResultsOnNodes")==0) return SettingsResultsOnNodesEnum;
 	      else if (strcmp(name,"SettingsIoGather")==0) return SettingsIoGatherEnum;
 	      else if (strcmp(name,"SettingsLowmem")==0) return SettingsLowmemEnum;
 	      else if (strcmp(name,"SettingsOutputFrequency")==0) return SettingsOutputFrequencyEnum;
 	      else if (strcmp(name,"SettingsWaitonlock")==0) return SettingsWaitonlockEnum;
-	      else if (strcmp(name,"SurfaceforcingsDelta18o")==0) return SurfaceforcingsDelta18oEnum;
-	      else if (strcmp(name,"SurfaceforcingsDelta18oSurface")==0) return SurfaceforcingsDelta18oSurfaceEnum;
-	      else if (strcmp(name,"SurfaceforcingsIsdelta18o")==0) return SurfaceforcingsIsdelta18oEnum;
-	      else if (strcmp(name,"SurfaceforcingsPrecipitationsPresentday")==0) return SurfaceforcingsPrecipitationsPresentdayEnum;
-	      else if (strcmp(name,"SurfaceforcingsTemperaturesPresentday")==0) return SurfaceforcingsTemperaturesPresentdayEnum;
-	      else if (strcmp(name,"SurfaceforcingsTemperaturesLgm")==0) return SurfaceforcingsTemperaturesLgmEnum;
-	      else if (strcmp(name,"DebugProfiling")==0) return DebugProfilingEnum;
+         else stage=3;
+   }
+   if(stage==3){
+	      if (strcmp(name,"DebugProfiling")==0) return DebugProfilingEnum;
 	      else if (strcmp(name,"ProfilingCurrentMem")==0) return ProfilingCurrentMemEnum;
 	      else if (strcmp(name,"ProfilingCurrentFlops")==0) return ProfilingCurrentFlopsEnum;
@@ -256,18 +273,4 @@
 	      else if (strcmp(name,"SteadystateRequestedOutputs")==0) return SteadystateRequestedOutputsEnum;
 	      else if (strcmp(name,"Surface")==0) return SurfaceEnum;
-	      else if (strcmp(name,"SurfaceforcingsPrecipitation")==0) return SurfaceforcingsPrecipitationEnum;
-	      else if (strcmp(name,"SurfaceforcingsMassBalance")==0) return SurfaceforcingsMassBalanceEnum;
-	      else if (strcmp(name,"SurfaceforcingsIspdd")==0) return SurfaceforcingsIspddEnum;
-	      else if (strcmp(name,"SurfaceforcingsDesfac")==0) return SurfaceforcingsDesfacEnum;
-         else stage=3;
-   }
-   if(stage==3){
-	      if (strcmp(name,"SurfaceforcingsS0p")==0) return SurfaceforcingsS0pEnum;
-	      else if (strcmp(name,"SurfaceforcingsIssmbgradients")==0) return SurfaceforcingsIssmbgradientsEnum;
-	      else if (strcmp(name,"SurfaceforcingsMonthlytemperatures")==0) return SurfaceforcingsMonthlytemperaturesEnum;
-	      else if (strcmp(name,"SurfaceforcingsHref")==0) return SurfaceforcingsHrefEnum;
-	      else if (strcmp(name,"SurfaceforcingsSmbref")==0) return SurfaceforcingsSmbrefEnum;
-	      else if (strcmp(name,"SurfaceforcingsBPos")==0) return SurfaceforcingsBPosEnum;
-	      else if (strcmp(name,"SurfaceforcingsBNeg")==0) return SurfaceforcingsBNegEnum;
 	      else if (strcmp(name,"ThermalIsenthalpy")==0) return ThermalIsenthalpyEnum;
 	      else if (strcmp(name,"ThermalIsdynamicbasalspc")==0) return ThermalIsdynamicbasalspcEnum;
@@ -293,7 +296,30 @@
 	      else if (strcmp(name,"TransientIsthermal")==0) return TransientIsthermalEnum;
 	      else if (strcmp(name,"TransientIsgia")==0) return TransientIsgiaEnum;
-	      else if (strcmp(name,"TransientIsdamage")==0) return TransientIsdamageEnum;
+	      else if (strcmp(name,"TransientIsdamageevolution")==0) return TransientIsdamageevolutionEnum;
+	      else if (strcmp(name,"TransientIshydrology")==0) return TransientIshydrologyEnum;
 	      else if (strcmp(name,"TransientNumRequestedOutputs")==0) return TransientNumRequestedOutputsEnum;
 	      else if (strcmp(name,"TransientRequestedOutputs")==0) return TransientRequestedOutputsEnum;
+	      else if (strcmp(name,"Surfaceforcings")==0) return SurfaceforcingsEnum;
+	      else if (strcmp(name,"SMB")==0) return SMBEnum;
+	      else if (strcmp(name,"SurfaceforcingsMassBalance")==0) return SurfaceforcingsMassBalanceEnum;
+	      else if (strcmp(name,"SMBpdd")==0) return SMBpddEnum;
+	      else if (strcmp(name,"SurfaceforcingsDelta18o")==0) return SurfaceforcingsDelta18oEnum;
+	      else if (strcmp(name,"SurfaceforcingsDelta18oSurface")==0) return SurfaceforcingsDelta18oSurfaceEnum;
+	      else if (strcmp(name,"SurfaceforcingsIsdelta18o")==0) return SurfaceforcingsIsdelta18oEnum;
+	      else if (strcmp(name,"SurfaceforcingsPrecipitationsPresentday")==0) return SurfaceforcingsPrecipitationsPresentdayEnum;
+	      else if (strcmp(name,"SurfaceforcingsTemperaturesPresentday")==0) return SurfaceforcingsTemperaturesPresentdayEnum;
+	      else if (strcmp(name,"SurfaceforcingsTemperaturesLgm")==0) return SurfaceforcingsTemperaturesLgmEnum;
+	      else if (strcmp(name,"SurfaceforcingsPrecipitation")==0) return SurfaceforcingsPrecipitationEnum;
+	      else if (strcmp(name,"SurfaceforcingsDesfac")==0) return SurfaceforcingsDesfacEnum;
+	      else if (strcmp(name,"SurfaceforcingsS0p")==0) return SurfaceforcingsS0pEnum;
+	      else if (strcmp(name,"SMBgradients")==0) return SMBgradientsEnum;
+	      else if (strcmp(name,"SurfaceforcingsMonthlytemperatures")==0) return SurfaceforcingsMonthlytemperaturesEnum;
+	      else if (strcmp(name,"SurfaceforcingsHref")==0) return SurfaceforcingsHrefEnum;
+	      else if (strcmp(name,"SurfaceforcingsSmbref")==0) return SurfaceforcingsSmbrefEnum;
+	      else if (strcmp(name,"SurfaceforcingsBPos")==0) return SurfaceforcingsBPosEnum;
+	      else if (strcmp(name,"SurfaceforcingsBNeg")==0) return SurfaceforcingsBNegEnum;
+	      else if (strcmp(name,"SMBhenning")==0) return SMBhenningEnum;
+	      else if (strcmp(name,"SurfaceforcingsIspdd")==0) return SurfaceforcingsIspddEnum;
+	      else if (strcmp(name,"SurfaceforcingsIssmbgradients")==0) return SurfaceforcingsIssmbgradientsEnum;
 	      else if (strcmp(name,"SolutionType")==0) return SolutionTypeEnum;
 	      else if (strcmp(name,"AnalysisType")==0) return AnalysisTypeEnum;
@@ -309,4 +335,5 @@
 	      else if (strcmp(name,"BalancevelocityAnalysis")==0) return BalancevelocityAnalysisEnum;
 	      else if (strcmp(name,"BalancevelocitySolution")==0) return BalancevelocitySolutionEnum;
+	      else if (strcmp(name,"L2ProjectionEPLAnalysis")==0) return L2ProjectionEPLAnalysisEnum;
 	      else if (strcmp(name,"L2ProjectionBaseAnalysis")==0) return L2ProjectionBaseAnalysisEnum;
 	      else if (strcmp(name,"BedSlopeSolution")==0) return BedSlopeSolutionEnum;
@@ -329,8 +356,9 @@
 	      else if (strcmp(name,"FreeSurfaceBaseAnalysis")==0) return FreeSurfaceBaseAnalysisEnum;
 	      else if (strcmp(name,"FreeSurfaceTopAnalysis")==0) return FreeSurfaceTopAnalysisEnum;
+	      else if (strcmp(name,"SurfaceNormalVelocity")==0) return SurfaceNormalVelocityEnum;
 	      else if (strcmp(name,"ExtrudeFromBaseAnalysis")==0) return ExtrudeFromBaseAnalysisEnum;
 	      else if (strcmp(name,"ExtrudeFromTopAnalysis")==0) return ExtrudeFromTopAnalysisEnum;
+	      else if (strcmp(name,"DepthAverageAnalysis")==0) return DepthAverageAnalysisEnum;
 	      else if (strcmp(name,"SteadystateSolution")==0) return SteadystateSolutionEnum;
-	      else if (strcmp(name,"L2ProjectionTopAnalysis")==0) return L2ProjectionTopAnalysisEnum;
 	      else if (strcmp(name,"SurfaceSlopeSolution")==0) return SurfaceSlopeSolutionEnum;
 	      else if (strcmp(name,"SmoothedSurfaceSlopeXAnalysis")==0) return SmoothedSurfaceSlopeXAnalysisEnum;
@@ -343,4 +371,7 @@
 	      else if (strcmp(name,"MeshdeformationSolution")==0) return MeshdeformationSolutionEnum;
 	      else if (strcmp(name,"MeshdeformationAnalysis")==0) return MeshdeformationAnalysisEnum;
+	      else if (strcmp(name,"LevelsetAnalysis")==0) return LevelsetAnalysisEnum;
+	      else if (strcmp(name,"ExtrapolationAnalysis")==0) return ExtrapolationAnalysisEnum;
+	      else if (strcmp(name,"LsfReinitializationAnalysis")==0) return LsfReinitializationAnalysisEnum;
 	      else if (strcmp(name,"Approximation")==0) return ApproximationEnum;
 	      else if (strcmp(name,"NoneApproximation")==0) return NoneApproximationEnum;
@@ -352,5 +383,8 @@
 	      else if (strcmp(name,"HOApproximation")==0) return HOApproximationEnum;
 	      else if (strcmp(name,"HOFSApproximation")==0) return HOFSApproximationEnum;
-	      else if (strcmp(name,"FSApproximation")==0) return FSApproximationEnum;
+         else stage=4;
+   }
+   if(stage==4){
+	      if (strcmp(name,"FSApproximation")==0) return FSApproximationEnum;
 	      else if (strcmp(name,"FSvelocity")==0) return FSvelocityEnum;
 	      else if (strcmp(name,"FSpressure")==0) return FSpressureEnum;
@@ -383,11 +417,10 @@
 	      else if (strcmp(name,"InputToExtrude")==0) return InputToExtrudeEnum;
 	      else if (strcmp(name,"InputToL2Project")==0) return InputToL2ProjectEnum;
-         else stage=4;
-   }
-   if(stage==4){
-	      if (strcmp(name,"IntParam")==0) return IntParamEnum;
+	      else if (strcmp(name,"InputToDepthaverage")==0) return InputToDepthaverageEnum;
+	      else if (strcmp(name,"IntParam")==0) return IntParamEnum;
 	      else if (strcmp(name,"IntVecParam")==0) return IntVecParamEnum;
 	      else if (strcmp(name,"TransientParam")==0) return TransientParamEnum;
 	      else if (strcmp(name,"Matice")==0) return MaticeEnum;
+	      else if (strcmp(name,"Matdamageice")==0) return MatdamageiceEnum;
 	      else if (strcmp(name,"Matpar")==0) return MatparEnum;
 	      else if (strcmp(name,"Node")==0) return NodeEnum;
@@ -397,6 +430,4 @@
 	      else if (strcmp(name,"Pengrid")==0) return PengridEnum;
 	      else if (strcmp(name,"Penpair")==0) return PenpairEnum;
-	      else if (strcmp(name,"Penta")==0) return PentaEnum;
-	      else if (strcmp(name,"PentaInput")==0) return PentaInputEnum;
 	      else if (strcmp(name,"Profiler")==0) return ProfilerEnum;
 	      else if (strcmp(name,"MatrixParam")==0) return MatrixParamEnum;
@@ -416,4 +447,8 @@
 	      else if (strcmp(name,"Tria")==0) return TriaEnum;
 	      else if (strcmp(name,"TriaInput")==0) return TriaInputEnum;
+	      else if (strcmp(name,"Tetra")==0) return TetraEnum;
+	      else if (strcmp(name,"TetraInput")==0) return TetraInputEnum;
+	      else if (strcmp(name,"Penta")==0) return PentaEnum;
+	      else if (strcmp(name,"PentaInput")==0) return PentaInputEnum;
 	      else if (strcmp(name,"Vertex")==0) return VertexEnum;
 	      else if (strcmp(name,"VertexPId")==0) return VertexPIdEnum;
@@ -450,5 +485,5 @@
 	      else if (strcmp(name,"QmuVz")==0) return QmuVzEnum;
 	      else if (strcmp(name,"QmuThickness")==0) return QmuThicknessEnum;
-	      else if (strcmp(name,"QmuBed")==0) return QmuBedEnum;
+	      else if (strcmp(name,"QmuBase")==0) return QmuBaseEnum;
 	      else if (strcmp(name,"QmuSurface")==0) return QmuSurfaceEnum;
 	      else if (strcmp(name,"QmuMelting")==0) return QmuMeltingEnum;
@@ -471,5 +506,8 @@
 	      else if (strcmp(name,"ThicknessAbsMisfit")==0) return ThicknessAbsMisfitEnum;
 	      else if (strcmp(name,"Vel")==0) return VelEnum;
-	      else if (strcmp(name,"Velocity")==0) return VelocityEnum;
+         else stage=5;
+   }
+   if(stage==5){
+	      if (strcmp(name,"Velocity")==0) return VelocityEnum;
 	      else if (strcmp(name,"VxAverage")==0) return VxAverageEnum;
 	      else if (strcmp(name,"Vx")==0) return VxEnum;
@@ -502,14 +540,27 @@
 	      else if (strcmp(name,"HydrologyWaterVx")==0) return HydrologyWaterVxEnum;
 	      else if (strcmp(name,"HydrologyWaterVy")==0) return HydrologyWaterVyEnum;
+	      else if (strcmp(name,"SigmaNN")==0) return SigmaNNEnum;
 	      else if (strcmp(name,"StressTensor")==0) return StressTensorEnum;
 	      else if (strcmp(name,"StressTensorxx")==0) return StressTensorxxEnum;
 	      else if (strcmp(name,"StressTensorxy")==0) return StressTensorxyEnum;
 	      else if (strcmp(name,"StressTensorxz")==0) return StressTensorxzEnum;
-         else stage=5;
-   }
-   if(stage==5){
-	      if (strcmp(name,"StressTensoryy")==0) return StressTensoryyEnum;
+	      else if (strcmp(name,"StressTensoryy")==0) return StressTensoryyEnum;
 	      else if (strcmp(name,"StressTensoryz")==0) return StressTensoryzEnum;
 	      else if (strcmp(name,"StressTensorzz")==0) return StressTensorzzEnum;
+	      else if (strcmp(name,"DeviatoricStress")==0) return DeviatoricStressEnum;
+	      else if (strcmp(name,"DeviatoricStressxx")==0) return DeviatoricStressxxEnum;
+	      else if (strcmp(name,"DeviatoricStressxy")==0) return DeviatoricStressxyEnum;
+	      else if (strcmp(name,"DeviatoricStressxz")==0) return DeviatoricStressxzEnum;
+	      else if (strcmp(name,"DeviatoricStressyy")==0) return DeviatoricStressyyEnum;
+	      else if (strcmp(name,"DeviatoricStressyz")==0) return DeviatoricStressyzEnum;
+	      else if (strcmp(name,"DeviatoricStresszz")==0) return DeviatoricStresszzEnum;
+	      else if (strcmp(name,"StrainRate")==0) return StrainRateEnum;
+	      else if (strcmp(name,"StrainRatexx")==0) return StrainRatexxEnum;
+	      else if (strcmp(name,"StrainRatexy")==0) return StrainRatexyEnum;
+	      else if (strcmp(name,"StrainRatexz")==0) return StrainRatexzEnum;
+	      else if (strcmp(name,"StrainRateyy")==0) return StrainRateyyEnum;
+	      else if (strcmp(name,"StrainRateyz")==0) return StrainRateyzEnum;
+	      else if (strcmp(name,"StrainRatezz")==0) return StrainRatezzEnum;
+	      else if (strcmp(name,"Divergence")==0) return DivergenceEnum;
 	      else if (strcmp(name,"GiaCrossSectionShape")==0) return GiaCrossSectionShapeEnum;
 	      else if (strcmp(name,"GiadWdt")==0) return GiadWdtEnum;
@@ -523,4 +574,6 @@
 	      else if (strcmp(name,"P2xP1")==0) return P2xP1Enum;
 	      else if (strcmp(name,"P1xP2")==0) return P1xP2Enum;
+	      else if (strcmp(name,"P1xP3")==0) return P1xP3Enum;
+	      else if (strcmp(name,"P2xP4")==0) return P2xP4Enum;
 	      else if (strcmp(name,"P1P1")==0) return P1P1Enum;
 	      else if (strcmp(name,"P1P1GLS")==0) return P1P1GLSEnum;
@@ -528,6 +581,6 @@
 	      else if (strcmp(name,"MINIcondensed")==0) return MINIcondensedEnum;
 	      else if (strcmp(name,"TaylorHood")==0) return TaylorHoodEnum;
-	      else if (strcmp(name,"P2xP4")==0) return P2xP4Enum;
-	      else if (strcmp(name,"P1xP3")==0) return P1xP3Enum;
+	      else if (strcmp(name,"XTaylorHood")==0) return XTaylorHoodEnum;
+	      else if (strcmp(name,"OneLayerP4z")==0) return OneLayerP4zEnum;
 	      else if (strcmp(name,"SaveResults")==0) return SaveResultsEnum;
 	      else if (strcmp(name,"BoolExternalResult")==0) return BoolExternalResultEnum;
@@ -545,4 +598,13 @@
 	      else if (strcmp(name,"MassfluxatgateName")==0) return MassfluxatgateNameEnum;
 	      else if (strcmp(name,"MassfluxatgateSegments")==0) return MassfluxatgateSegmentsEnum;
+	      else if (strcmp(name,"MisfitName")==0) return MisfitNameEnum;
+	      else if (strcmp(name,"MisfitModelEnum")==0) return MisfitModelEnumEnum;
+	      else if (strcmp(name,"MisfitObservation")==0) return MisfitObservationEnum;
+	      else if (strcmp(name,"MisfitObservationEnum")==0) return MisfitObservationEnumEnum;
+	      else if (strcmp(name,"MisfitTimeinterpolation")==0) return MisfitTimeinterpolationEnum;
+	      else if (strcmp(name,"MisfitWeights")==0) return MisfitWeightsEnum;
+	      else if (strcmp(name,"MisfitWeightsEnum")==0) return MisfitWeightsEnumEnum;
+	      else if (strcmp(name,"SurfaceObservation")==0) return SurfaceObservationEnum;
+	      else if (strcmp(name,"WeightsSurfaceObservation")==0) return WeightsSurfaceObservationEnum;
 	      else if (strcmp(name,"MinVel")==0) return MinVelEnum;
 	      else if (strcmp(name,"MaxVel")==0) return MaxVelEnum;
@@ -561,11 +623,21 @@
 	      else if (strcmp(name,"Absolute")==0) return AbsoluteEnum;
 	      else if (strcmp(name,"Incremental")==0) return IncrementalEnum;
+	      else if (strcmp(name,"AugmentedLagrangianR")==0) return AugmentedLagrangianREnum;
+	      else if (strcmp(name,"AugmentedLagrangianTheta")==0) return AugmentedLagrangianThetaEnum;
+	      else if (strcmp(name,"None")==0) return NoneEnum;
 	      else if (strcmp(name,"AgressiveMigration")==0) return AgressiveMigrationEnum;
-	      else if (strcmp(name,"None")==0) return NoneEnum;
 	      else if (strcmp(name,"SoftMigration")==0) return SoftMigrationEnum;
 	      else if (strcmp(name,"SubelementMigration")==0) return SubelementMigrationEnum;
-	      else if (strcmp(name,"SubelementMigration2")==0) return SubelementMigration2Enum;
+         else stage=6;
+   }
+   if(stage==6){
+	      if (strcmp(name,"SubelementMigration2")==0) return SubelementMigration2Enum;
+	      else if (strcmp(name,"Contact")==0) return ContactEnum;
 	      else if (strcmp(name,"MaskGroundediceLevelset")==0) return MaskGroundediceLevelsetEnum;
 	      else if (strcmp(name,"QmuMaskGroundediceLevelset")==0) return QmuMaskGroundediceLevelsetEnum;
+	      else if (strcmp(name,"GaussSeg")==0) return GaussSegEnum;
+	      else if (strcmp(name,"GaussTria")==0) return GaussTriaEnum;
+	      else if (strcmp(name,"GaussTetra")==0) return GaussTetraEnum;
+	      else if (strcmp(name,"GaussPenta")==0) return GaussPentaEnum;
 	      else if (strcmp(name,"FSSolver")==0) return FSSolverEnum;
 	      else if (strcmp(name,"Adjoint")==0) return AdjointEnum;
@@ -613,9 +685,16 @@
 	      else if (strcmp(name,"OptionCell")==0) return OptionCellEnum;
 	      else if (strcmp(name,"OptionStruct")==0) return OptionStructEnum;
+	      else if (strcmp(name,"Cuffey")==0) return CuffeyEnum;
 	      else if (strcmp(name,"Paterson")==0) return PatersonEnum;
 	      else if (strcmp(name,"Arrhenius")==0) return ArrheniusEnum;
 	      else if (strcmp(name,"LliboutryDuval")==0) return LliboutryDuvalEnum;
+	      else if (strcmp(name,"TransientIslevelset")==0) return TransientIslevelsetEnum;
+	      else if (strcmp(name,"ExtrapolationVariable")==0) return ExtrapolationVariableEnum;
+	      else if (strcmp(name,"IceMaskNodeActivation")==0) return IceMaskNodeActivationEnum;
+	      else if (strcmp(name,"LevelsetfunctionSlopeX")==0) return LevelsetfunctionSlopeXEnum;
+	      else if (strcmp(name,"LevelsetfunctionSlopeY")==0) return LevelsetfunctionSlopeYEnum;
+	      else if (strcmp(name,"LevelsetfunctionPicard")==0) return LevelsetfunctionPicardEnum;
 	      else if (strcmp(name,"MaximumNumberOfDefinitions")==0) return MaximumNumberOfDefinitionsEnum;
-         else stage=6;
+         else stage=7;
    }
 	/*If we reach this point, the string provided has not been found*/
Index: /issm/trunk/src/c/shared/Enum/Synchronize.sh
===================================================================
--- /issm/trunk/src/c/shared/Enum/Synchronize.sh	(revision 17805)
+++ /issm/trunk/src/c/shared/Enum/Synchronize.sh	(revision 17806)
@@ -14,4 +14,79 @@
 NUMENUMS=$(wc -l temp | awk '{printf("%s",$1);}');
 
+#Deal with Analyses
+#Build EnumToAnalysis.cpp {{{
+#Header
+cat <<END > $ISSM_DIR/src/c/analyses/EnumToAnalysis.cpp
+/*
+* \file EnumToAnalysis.cpp
+* \brief: output class depending on enum
+*
+*   WARNING: DO NOT MODIFY THIS FILE
+*            this file has been automatically generated by Synchronize.sh
+*            Please read README for more information
+*/
+
+#include "./analyses.h"
+#include "../shared/shared.h"
+
+Analysis* EnumToAnalysis(int analysis_enum){
+
+	switch(analysis_enum){
+END
+#core
+cat temp | grep [a-zA-Z]Analysis | \
+	grep -v DefaultAnalysis | grep -v FlaimAnalysis | grep -v SurfaceSlopeAnalysis | grep -v BedSlopeAnalysis | \
+	awk '{print "\t\t#ifdef _HAVE_"toupper(substr($1,1,length($1)-12))"_\n\t\t" "case " $1" : return new " substr($1,1,length($1)-4) "();\n\t\t#endif"}' \
+		>> $ISSM_DIR/src/c/analyses/EnumToAnalysis.cpp
+
+#Footer
+cat <<END >> $ISSM_DIR/src/c/analyses/EnumToAnalysis.cpp
+		default : _error_("enum provided not supported ("<<EnumToStringx(analysis_enum)<<")");
+	}
+}
+END
+#}}}
+#Build analyses.m4{{{
+#Header
+cat <<END > $ISSM_DIR/m4/analyses.m4
+
+dnl   WARNING: DO NOT MODIFY THIS FILE
+dnl            this file has been automatically generated by Synchronize.sh
+dnl            Please read README for more information
+
+# AX_ANALYSES_SELECTION
+# -----------------
+# Check for analyses compilation
+AC_DEFUN([AX_ANALYSES_SELECTION],
+[
+
+END
+#core
+cat temp | grep [a-zA-Z]Analysis | \
+	grep -v DefaultAnalysis | grep -v FlaimAnalysis | grep -v SurfaceSlopeAnalysis | grep -v BedSlopeAnalysis | \
+	sed -e "s/AnalysisEnum//g" | \
+	awk '{print "dnl with-" $1"{{{\n\
+AC_ARG_WITH([" $1"],\n\
+\tAS_HELP_STRING([--with-" $1" = YES], [compile with " $1" capabilities (default is yes)]),\n\
+\t[" toupper($1)"=$withval],[" toupper($1)"=yes])\n\
+AC_MSG_CHECKING(for " $1" capability compilation)\n\n\
+HAVE_"  toupper($1)"=no \n\
+if test \"x$"  toupper($1)"\" = \"xyes\"; then\n\
+	HAVE_"  toupper($1)"=yes\n\
+	AC_DEFINE([_HAVE_"  toupper($1)"_],[1],[with " $1"capability])\n\
+fi\n\
+AM_CONDITIONAL([" toupper($1)"], [test x$HAVE_" toupper($1)" = xyes])\n\
+AC_MSG_RESULT($HAVE_" toupper($1)")\n\
+dnl }}}"}' \
+	>> $ISSM_DIR/m4/analyses.m4
+
+#Footer
+cat <<END >> $ISSM_DIR/m4/analyses.m4
+
+])
+END
+#}}}
+
+#Enum to String conversions
 #Build EnumToStringx.cpp {{{
 #Header
@@ -104,36 +179,6 @@
 END
 #}}}
-##Build EnumToAnalysis.cpp {{{
-##Header
-#cat <<END > $ISSM_DIR/src/c/analyses/EnumToAnalysis.cpp
-#/*
-#* \file EnumToAnalysis.cpp
-#* \brief: output class depending on enum
-#*
-#*   WARNING: DO NOT MODIFY THIS FILE
-#*            this file has been automatically generated by Synchronize.sh
-#*            Please read README for more information
-#*/
-#
-##include "./analyses.h"
-##include "../shared/shared.h"
-#
-#Analysis* EnumToAnalysis(int analysis_enum){
-#
-#	switch(analysis_enum){
-#END
-##core
-#cat temp | grep [a-z]Analysis | \
-#	grep -v DefaultAnalysis | grep -v FlaimAnalysis | grep -v SurfaceSlopeAnalysis | grep -v BedSlopeAnalysis | \
-#	awk '{print "\t\t#ifdef _HAVE_"toupper(substr($1,1,length($1)-12))"_\n\t\t" "case " $1" : return new " substr($1,1,length($1)-4) "();\n\t\t#endif"}' \
-#		>> $ISSM_DIR/src/c/analyses/EnumToAnalysis.cpp
-#
-##Footer
-#cat <<END >> $ISSM_DIR/src/c/analyses/EnumToAnalysis.cpp
-#default : _error_("enum provided not supported ("<<EnumToStringx(analysis_enum)<<")");
-#	}
-#}
-#END
-##}}}
+
+#Deal with Python Enums
 #Build EnumDefinitions.py{{{
 cat <<END > $ISSM_DIR/src/m/enum/EnumDefinitions.py
@@ -153,5 +198,5 @@
 #}}}
 
-# go through the lines of temp
+#Deal with Matlab Enums`
 ENUM=0;
 
Index: /issm/trunk/src/c/shared/Exceptions/Exceptions.cpp
===================================================================
--- /issm/trunk/src/c/shared/Exceptions/Exceptions.cpp	(revision 17805)
+++ /issm/trunk/src/c/shared/Exceptions/Exceptions.cpp	(revision 17806)
@@ -45,4 +45,6 @@
 
 	file_line= what_line;
+	/*When error messages are not shown properly, uncomment the following line*/
+	//this->Report();
 
 }/*}}}*/
Index: /issm/trunk/src/c/shared/Exceptions/exceptions.h
===================================================================
--- /issm/trunk/src/c/shared/Exceptions/exceptions.h	(revision 17805)
+++ /issm/trunk/src/c/shared/Exceptions/exceptions.h	(revision 17806)
@@ -63,5 +63,5 @@
 		return 0;\
 	}\
-	catch (exception& e) {\
+	catch(exception& e) {\
 		_printf_("Standard exception: " << e.what() << "\n\n");\
 		return 0;\
Index: /issm/trunk/src/c/shared/FSanalyticals/fsanalyticals.cpp
===================================================================
--- /issm/trunk/src/c/shared/FSanalyticals/fsanalyticals.cpp	(revision 17806)
+++ /issm/trunk/src/c/shared/FSanalyticals/fsanalyticals.cpp	(revision 17806)
@@ -0,0 +1,146 @@
+/*!\file fx.cpp
+ * \brief: analytical fonction for FS 
+ * test case for a cube with Dirichlet conditions on all faces and no variation in z
+ * case 1: 2d test with quadratic functions
+ * case 2: 2d test with sinusoidal functions
+ * case 3: 3d test with quadratic functions
+ * case 4: 3d test with sinusoidal functions
+ * case 5: 3d test with sinusoidal functions, no variations with z, non homogeneous Dirichlet conditions
+ * case 6: 3d test with sinusoidal functions, non homogeneous Dirichlet conditions
+ */
+
+#include <math.h>
+#include "../Numerics/types.h"
+#include "../Numerics/constants.h"
+#include "./fsanalyticals.h"
+#include "../shared.h"
+
+IssmDouble fx(IssmDouble x,IssmDouble y,IssmDouble z,int testid){ /*{{{*/ 
+	IssmDouble p=2;
+	IssmDouble q=2;
+	IssmDouble a=1;
+
+	switch(testid){
+		case 1:
+			z=y;
+			return  4*pow(x, 2)*z*pow(x - 1, 2) + 4*pow(x, 2)*z*(z - 1)*(2*z - 1) + 4*pow(x, 2)*pow(x - 1, 2)*(z - 1) + 2*pow(x, 2)*pow(x - 1, 2)*(2*z - 1) + 16*x*z*(x - 1)*(z - 1)*(2*z - 1) - 4*pow(z, 3)*(6*pow(x, 2) - 6*x + 1) + 6*pow(z, 2)*(6*pow(x, 2) - 6*x + 1) + 4*z*pow(x - 1, 2)*(z - 1)*(2*z - 1) - 2*z*(6*pow(x, 2) - 6*x + 1) + z - 1.0L/2.0L;
+		case 2: case 11:
+			z=y;
+			return 10*pow(PI, 2)*pow(p, 2)*pow(sin(PI*p*x), 3)*pow(sin(PI*p*z), 2)*cos(PI*p*z) - 2*pow(PI, 2)*pow(p, 2)*pow(sin(PI*p*x), 3)*pow(cos(PI*p*z), 3) - 6*pow(PI, 2)*pow(p, 2)*sin(PI*p*x)*pow(sin(PI*p*z), 2)*pow(cos(PI*p*x), 2)*cos(PI*p*z) + PI*q*sin(PI*q*z)*cos(PI*q*x);
+		case 3: 
+			return 4*pow(x, 2)*y*z*pow(x - 1, 2)*(z - 1) + 4*pow(x, 2)*y*z*(y - 1)*(2*y - 1)*(z - 1) + 2*pow(x, 2)*y*pow(x - 1, 2)*(y - 1)*(2*y - 1) + 4*pow(x, 2)*z*pow(x - 1, 2)*(y - 1)*(z - 1) + 2*pow(x, 2)*z*pow(x - 1, 2)*(2*y - 1)*(z - 1) - 4*x*pow(y, 2)*z*(x - 1)*(y - 1)*(z - 1) - 2*x*pow(y, 2)*z*(2*x - 1)*(y - 1)*(z - 1) - 4*x*y*z*(x - 1)*pow(y - 1, 2)*(z - 1) + 16*x*y*z*(x - 1)*(y - 1)*(2*y - 1)*(z - 1) - 2*x*y*z*(2*x - 1)*pow(y - 1, 2)*(z - 1) - 2*pow(y, 2)*z*(x - 1)*(2*x - 1)*(y - 1)*(z - 1) + 4*y*z*pow(x - 1, 2)*(y - 1)*(2*y - 1)*(z - 1) - 2*y*z*(x - 1)*(2*x - 1)*pow(y - 1, 2)*(z - 1) + y - 1.0L/2.0L;
+		case 4: 
+			return 4*pow(PI, 2)*pow(p, 2)*(cos(PI*p*x) - 1)*sin(PI*p*y)*sin(PI*p*z) + 2*pow(PI, 2)*pow(p, 2)*sin(PI*p*y)*sin(PI*p*z)*cos(PI*p*x) + PI*q*sin(PI*q*y)*sin(PI*q*z)*cos(PI*q*x);
+		case 5: 
+			return 2.*(cos(PI*p*x) - 1)*PI*PI*p*p*sin(PI*p*y) + 3*PI*PI*p*p*sin(PI*p*y)*cos(PI*p*x) + PI*q*sin(PI*q*y)*cos(PI*q*x);
+		case 6: 
+			return 4. * PI*PI * p*p * (cos(p*PI*x)-1) * sin(p*PI*y) * sin(p*PI*z)+ 2. * PI*PI*p*p*  sin(p*PI*y)    * sin(p*PI*z) * cos(p*PI*x) + q * PI * cos(q*PI*x) * sin(q*PI*y) * sin(q*PI*z);
+		case 7: 
+			z=y;
+			return 4*pow(x, 2)*z*pow(x - 1, 2) + 4*pow(x, 2)*z*(z - 1)*(2*z - 1) + 4*pow(x, 2)*pow(x - 1, 2)*(z - 1) + 2*pow(x, 2)*pow(x - 1, 2)*(2*z - 1) + 16*x*z*(x - 1)*(z - 1)*(2*z - 1) - 4*pow(z, 3)*(6*pow(x, 2) - 6*x + 1) + 6*pow(z, 2)*(6*pow(x, 2) - 6*x + 1) + 4*z*pow(x - 1, 2)*(z - 1)*(2*z - 1) - 2*z*(6*pow(x, 2) - 6*x + 1) + 1;
+		case 8: case 18:
+			return 1.0;
+		case 9:
+			return 4*pow(PI, 2)*pow(p, 2)*(cos(PI*p*x) - 1)*sin(PI*p*y)*sin(PI*p*z) + 2*pow(PI, 2)*pow(p, 2)*sin(PI*p*y)*sin(PI*p*z)*cos(PI*p*x) + 2*x*z;
+		case 10:
+			return 4*pow(PI, 2)*pow(p, 2)*(cos(PI*p*x) - 1)*sin(PI*p*y)*sin(PI*p*z) + 2*pow(PI, 2)*pow(p, 2)*sin(PI*p*y)*sin(PI*p*z)*cos(PI*p*x) + PI*q*pow(z, a)*sin(PI*q*y)*cos(PI*q*x);
+		case 21:
+			z=y;
+			return z - 4.0L/3.0L*pow(2, 1.0L/3.0L)*(pow(x, 2)*z*(x - 1)*(z - 1)*(2*z - 1) + x*z*pow(x - 1, 2)*(z - 1)*(2*z - 1))*(4*(pow(x, 2)*z*(x - 1)*(z - 1)*(2*z - 1) + x*z*pow(x - 1, 2)*(z - 1)*(2*z - 1))*(pow(x, 2)*z*(z - 1)*(2*z - 1) + 4*x*z*(x - 1)*(z - 1)*(2*z - 1) + z*pow(x - 1, 2)*(z - 1)*(2*z - 1)) + 4*(2*pow(z, 3)*(6*pow(x, 2) - 6*x + 1) - 3*pow(z, 2)*(6*pow(x, 2) - 6*x + 1) + z*(6*pow(x, 2) - 6*x + 1))*(2*pow(z, 3)*(2*pow(x, 3) - 3*pow(x, 2) + x) - 3*pow(z, 2)*(2*pow(x, 3) - 3*pow(x, 2) + x) + z*(2*pow(x, 3) - 3*pow(x, 2) + x)) + (2*pow(x, 2)*z*pow(x - 1, 2)*(z - 1) + pow(x, 2)*z*pow(x - 1, 2)*(2*z - 1) + pow(x, 2)*pow(x - 1, 2)*(z - 1)*(2*z - 1) - pow(z, 4)*(6*pow(x, 2) - 6*x + 1) + 2*pow(z, 3)*(6*pow(x, 2) - 6*x + 1) - pow(z, 2)*(6*pow(x, 2) - 6*x + 1))*(2*pow(x, 2)*z*(x - 1)*(z - 1) + pow(x, 2)*z*(x - 1)*(2*z - 1) + pow(x, 2)*(x - 1)*(z - 1)*(2*z - 1) + 2*x*z*pow(x - 1, 2)*(z - 1) + x*z*pow(x - 1, 2)*(2*z - 1) + x*pow(x - 1, 2)*(z - 1)*(2*z - 1) - 3*pow(z, 4)*(2*x - 1) + 6*pow(z, 3)*(2*x - 1) - 3*pow(z, 2)*(2*x - 1)))/pow(4*pow(pow(x, 2)*z*(x - 1)*(z - 1)*(2*z - 1) + x*z*pow(x - 1, 2)*(z - 1)*(2*z - 1), 2) + 4*pow(2*pow(z, 3)*(2*pow(x, 3) - 3*pow(x, 2) + x) - 3*pow(z, 2)*(2*pow(x, 3) - 3*pow(x, 2) + x) + z*(2*pow(x, 3) - 3*pow(x, 2) + x), 2) + (1.0L/2.0L)*pow(2*pow(x, 2)*z*pow(x - 1, 2)*(z - 1) + pow(x, 2)*z*pow(x - 1, 2)*(2*z - 1) + pow(x, 2)*pow(x - 1, 2)*(z - 1)*(2*z - 1) - pow(z, 4)*(6*pow(x, 2) - 6*x + 1) + 2*pow(z, 3)*(6*pow(x, 2) - 6*x + 1) - pow(z, 2)*(6*pow(x, 2) - 6*x + 1), 2), 4.0L/3.0L) - 1.0L/3.0L*pow(2, 1.0L/3.0L)*(4*(pow(x, 2)*z*(x - 1)*(z - 1)*(2*z - 1) + x*z*pow(x - 1, 2)*(z - 1)*(2*z - 1))*(2*pow(x, 2)*z*(x - 1)*(z - 1) + pow(x, 2)*z*(x - 1)*(2*z - 1) + pow(x, 2)*(x - 1)*(z - 1)*(2*z - 1) + 2*x*z*pow(x - 1, 2)*(z - 1) + x*z*pow(x - 1, 2)*(2*z - 1) + x*pow(x - 1, 2)*(z - 1)*(2*z - 1)) + 4*(2*pow(z, 3)*(2*pow(x, 3) - 3*pow(x, 2) + x) - 3*pow(z, 2)*(2*pow(x, 3) - 3*pow(x, 2) + x) + z*(2*pow(x, 3) - 3*pow(x, 2) + x))*(2*pow(x, 3) - 3*pow(x, 2) + x + 6*pow(z, 2)*(2*pow(x, 3) - 3*pow(x, 2) + x) - 6*z*(2*pow(x, 3) - 3*pow(x, 2) + x)) + (2*pow(x, 2)*z*pow(x - 1, 2) + 2*pow(x, 2)*pow(x - 1, 2)*(z - 1) + pow(x, 2)*pow(x - 1, 2)*(2*z - 1) - 2*pow(z, 3)*(6*pow(x, 2) - 6*x + 1) + 3*pow(z, 2)*(6*pow(x, 2) - 6*x + 1) - z*(6*pow(x, 2) - 6*x + 1))*(2*pow(x, 2)*z*pow(x - 1, 2)*(z - 1) + pow(x, 2)*z*pow(x - 1, 2)*(2*z - 1) + pow(x, 2)*pow(x - 1, 2)*(z - 1)*(2*z - 1) - pow(z, 4)*(6*pow(x, 2) - 6*x + 1) + 2*pow(z, 3)*(6*pow(x, 2) - 6*x + 1) - pow(z, 2)*(6*pow(x, 2) - 6*x + 1)))*(2*pow(x, 2)*z*pow(x - 1, 2)*(z - 1) + pow(x, 2)*z*pow(x - 1, 2)*(2*z - 1) + pow(x, 2)*pow(x - 1, 2)*(z - 1)*(2*z - 1) - pow(z, 4)*(6*pow(x, 2) - 6*x + 1) + 2*pow(z, 3)*(6*pow(x, 2) - 6*x + 1) - pow(z, 2)*(6*pow(x, 2) - 6*x + 1))/pow(4*pow(pow(x, 2)*z*(x - 1)*(z - 1)*(2*z - 1) + x*z*pow(x - 1, 2)*(z - 1)*(2*z - 1), 2) + 4*pow(2*pow(z, 3)*(2*pow(x, 3) - 3*pow(x, 2) + x) - 3*pow(z, 2)*(2*pow(x, 3) - 3*pow(x, 2) + x) + z*(2*pow(x, 3) - 3*pow(x, 2) + x), 2) + (1.0L/2.0L)*pow(2*pow(x, 2)*z*pow(x - 1, 2)*(z - 1) + pow(x, 2)*z*pow(x - 1, 2)*(2*z - 1) + pow(x, 2)*pow(x - 1, 2)*(z - 1)*(2*z - 1) - pow(z, 4)*(6*pow(x, 2) - 6*x + 1) + 2*pow(z, 3)*(6*pow(x, 2) - 6*x + 1) - pow(z, 2)*(6*pow(x, 2) - 6*x + 1), 2), 4.0L/3.0L) + 2*pow(2, 1.0L/3.0L)*(pow(x, 2)*z*(z - 1)*(2*z - 1) + 4*x*z*(x - 1)*(z - 1)*(2*z - 1) + z*pow(x - 1, 2)*(z - 1)*(2*z - 1))/pow(4*pow(pow(x, 2)*z*(x - 1)*(z - 1)*(2*z - 1) + x*z*pow(x - 1, 2)*(z - 1)*(2*z - 1), 2) + 4*pow(2*pow(z, 3)*(2*pow(x, 3) - 3*pow(x, 2) + x) - 3*pow(z, 2)*(2*pow(x, 3) - 3*pow(x, 2) + x) + z*(2*pow(x, 3) - 3*pow(x, 2) + x), 2) + (1.0L/2.0L)*pow(2*pow(x, 2)*z*pow(x - 1, 2)*(z - 1) + pow(x, 2)*z*pow(x - 1, 2)*(2*z - 1) + pow(x, 2)*pow(x - 1, 2)*(z - 1)*(2*z - 1) - pow(z, 4)*(6*pow(x, 2) - 6*x + 1) + 2*pow(z, 3)*(6*pow(x, 2) - 6*x + 1) - pow(z, 2)*(6*pow(x, 2) - 6*x + 1), 2), 1.0L/3.0L) - 1.0L/2.0L + pow(2, 1.0L/3.0L)*(2*pow(x, 2)*z*pow(x - 1, 2) + 2*pow(x, 2)*pow(x - 1, 2)*(z - 1) + pow(x, 2)*pow(x - 1, 2)*(2*z - 1) - 2*pow(z, 3)*(6*pow(x, 2) - 6*x + 1) + 3*pow(z, 2)*(6*pow(x, 2) - 6*x + 1) - z*(6*pow(x, 2) - 6*x + 1))/pow(4*pow(pow(x, 2)*z*(x - 1)*(z - 1)*(2*z - 1) + x*z*pow(x - 1, 2)*(z - 1)*(2*z - 1), 2) + 4*pow(2*pow(z, 3)*(2*pow(x, 3) - 3*pow(x, 2) + x) - 3*pow(z, 2)*(2*pow(x, 3) - 3*pow(x, 2) + x) + z*(2*pow(x, 3) - 3*pow(x, 2) + x), 2) + (1.0L/2.0L)*pow(2*pow(x, 2)*z*pow(x - 1, 2)*(z - 1) + pow(x, 2)*z*pow(x - 1, 2)*(2*z - 1) + pow(x, 2)*pow(x - 1, 2)*(z - 1)*(2*z - 1) - pow(z, 4)*(6*pow(x, 2) - 6*x + 1) + 2*pow(z, 3)*(6*pow(x, 2) - 6*x + 1) - pow(z, 2)*(6*pow(x, 2) - 6*x + 1), 2), 1.0L/3.0L);
+		case 24:
+			return 2*pow(2, 1.0L/3.0L)*pow(PI, 2)*pow(p, 2)*sin(PI*p*y)*sin(PI*p*z)*cos(PI*p*x)/pow(6*pow(PI, 2)*pow(p, 2)*pow(sin(PI*p*x), 2)*pow(sin(PI*p*y), 2)*pow(sin(PI*p*z), 2) + (1.0L/2.0L)*pow(-2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*z)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*z)*cos(PI*p*x), 2) + (1.0L/2.0L)*pow(pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*x)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*x)*cos(PI*p*z), 2) + (1.0L/2.0L)*pow(pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*y)*cos(PI*p*x) - 2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*y)*cos(PI*p*z), 2), 1.0L/3.0L) - 2.0L/3.0L*pow(2, 1.0L/3.0L)*PI*p*(12*pow(PI, 3)*pow(p, 3)*sin(PI*p*x)*pow(sin(PI*p*y), 2)*pow(sin(PI*p*z), 2)*cos(PI*p*x) - (-2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*z)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*z)*cos(PI*p*x))*(pow(PI, 2)*pow(p, 2)*(cos(PI*p*y) - 1)*sin(PI*p*x)*sin(PI*p*z) - 2*pow(PI, 2)*pow(p, 2)*sin(PI*p*x)*sin(PI*p*z)*cos(PI*p*y)) + (pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*x)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*x)*cos(PI*p*z))*(pow(PI, 3)*pow(p, 3)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*cos(PI*p*x)*cos(PI*p*y) + pow(PI, 2)*pow(p, 2)*(cos(PI*p*y) - 1)*cos(PI*p*x)*cos(PI*p*z)) - (pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*y)*cos(PI*p*x) - 2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*y)*cos(PI*p*z))*(pow(PI, 3)*pow(p, 3)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*x)*sin(PI*p*y) - 2*pow(PI, 2)*pow(p, 2)*sin(PI*p*x)*sin(PI*p*y)*cos(PI*p*z)))*sin(PI*p*x)*sin(PI*p*y)*sin(PI*p*z)/pow(6*pow(PI, 2)*pow(p, 2)*pow(sin(PI*p*x), 2)*pow(sin(PI*p*y), 2)*pow(sin(PI*p*z), 2) + (1.0L/2.0L)*pow(-2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*z)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*z)*cos(PI*p*x), 2) + (1.0L/2.0L)*pow(pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*x)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*x)*cos(PI*p*z), 2) + (1.0L/2.0L)*pow(pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*y)*cos(PI*p*x) - 2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*y)*cos(PI*p*z), 2), 4.0L/3.0L) + PI*q*sin(PI*q*y)*sin(PI*q*z)*cos(PI*q*x) - 1.0L/6.0L*pow(2, 1.0L/3.0L)*(-2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*z)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*z)*cos(PI*p*x))*(12*pow(PI, 3)*pow(p, 3)*pow(sin(PI*p*x), 2)*sin(PI*p*y)*pow(sin(PI*p*z), 2)*cos(PI*p*y) + (-2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*z)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*z)*cos(PI*p*x))*(2*pow(PI, 2)*pow(p, 2)*(cos(PI*p*x) - 1)*sin(PI*p*y)*sin(PI*p*z) - pow(PI, 2)*pow(p, 2)*sin(PI*p*y)*sin(PI*p*z)*cos(PI*p*x)) - (pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*x)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*x)*cos(PI*p*z))*(pow(PI, 3)*pow(p, 3)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*x)*sin(PI*p*y) + pow(PI, 2)*pow(p, 2)*sin(PI*p*x)*sin(PI*p*y)*cos(PI*p*z)) + (pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*y)*cos(PI*p*x) - 2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*y)*cos(PI*p*z))*(pow(PI, 3)*pow(p, 3)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*cos(PI*p*x)*cos(PI*p*y) - 2*pow(PI, 2)*pow(p, 2)*(cos(PI*p*x) - 1)*cos(PI*p*y)*cos(PI*p*z)))/pow(6*pow(PI, 2)*pow(p, 2)*pow(sin(PI*p*x), 2)*pow(sin(PI*p*y), 2)*pow(sin(PI*p*z), 2) + (1.0L/2.0L)*pow(-2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*z)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*z)*cos(PI*p*x), 2) + (1.0L/2.0L)*pow(pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*x)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*x)*cos(PI*p*z), 2) + (1.0L/2.0L)*pow(pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*y)*cos(PI*p*x) - 2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*y)*cos(PI*p*z), 2), 4.0L/3.0L) - 1.0L/6.0L*pow(2, 1.0L/3.0L)*(pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*y)*cos(PI*p*x) - 2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*y)*cos(PI*p*z))*(12*pow(PI, 3)*pow(p, 3)*pow(sin(PI*p*x), 2)*pow(sin(PI*p*y), 2)*sin(PI*p*z)*cos(PI*p*z) + (-2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*z)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*z)*cos(PI*p*x))*(-2*pow(PI, 2)*pow(p, 2)*(cos(PI*p*x) - 1)*cos(PI*p*y)*cos(PI*p*z) + pow(PI, 2)*pow(p, 2)*(cos(PI*p*y) - 1)*cos(PI*p*x)*cos(PI*p*z)) - (pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*x)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*x)*cos(PI*p*z))*(pow(PI, 2)*pow(p, 2)*(cos(PI*p*y) - 1)*sin(PI*p*x)*sin(PI*p*z) + pow(PI, 2)*pow(p, 2)*sin(PI*p*x)*sin(PI*p*z)*cos(PI*p*y)) + (pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*y)*cos(PI*p*x) - 2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*y)*cos(PI*p*z))*(2*pow(PI, 2)*pow(p, 2)*(cos(PI*p*x) - 1)*sin(PI*p*y)*sin(PI*p*z) - pow(PI, 2)*pow(p, 2)*sin(PI*p*y)*sin(PI*p*z)*cos(PI*p*x)))/pow(6*pow(PI, 2)*pow(p, 2)*pow(sin(PI*p*x), 2)*pow(sin(PI*p*y), 2)*pow(sin(PI*p*z), 2) + (1.0L/2.0L)*pow(-2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*z)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*z)*cos(PI*p*x), 2) + (1.0L/2.0L)*pow(pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*x)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*x)*cos(PI*p*z), 2) + (1.0L/2.0L)*pow(pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*y)*cos(PI*p*x) - 2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*y)*cos(PI*p*z), 2), 4.0L/3.0L) + pow(2, 1.0L/3.0L)*(2*pow(PI, 2)*pow(p, 2)*(cos(PI*p*x) - 1)*sin(PI*p*y)*sin(PI*p*z) - pow(PI, 2)*pow(p, 2)*sin(PI*p*y)*sin(PI*p*z)*cos(PI*p*x))/pow(6*pow(PI, 2)*pow(p, 2)*pow(sin(PI*p*x), 2)*pow(sin(PI*p*y), 2)*pow(sin(PI*p*z), 2) + (1.0L/2.0L)*pow(-2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*z)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*z)*cos(PI*p*x), 2) + (1.0L/2.0L)*pow(pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*x)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*x)*cos(PI*p*z), 2) + (1.0L/2.0L)*pow(pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*y)*cos(PI*p*x) - 2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*y)*cos(PI*p*z), 2), 1.0L/3.0L);
+
+		case 101: 
+			return 4*pow(x, 2)*y*z*pow(x - 1, 2)*(z - 1) + 8*pow(x, 2)*y*z*(y - 1)*(2*y - 1)*(z - 1) + 2*pow(x, 2)*y*pow(x - 1, 2)*(y - 1)*(2*y - 1) + 4*pow(x, 2)*z*pow(x - 1, 2)*(y - 1)*(z - 1) + 2*pow(x, 2)*z*pow(x - 1, 2)*(2*y - 1)*(z - 1) - 12*x*pow(y, 2)*z*(x - 1)*(y - 1)*(z - 1) - 6*x*pow(y, 2)*z*(2*x - 1)*(y - 1)*(z - 1) - 12*x*y*z*(x - 1)*pow(y - 1, 2)*(z - 1) + 32*x*y*z*(x - 1)*(y - 1)*(2*y - 1)*(z - 1) - 6*x*y*z*(2*x - 1)*pow(y - 1, 2)*(z - 1) - 6*pow(y, 2)*z*(x - 1)*(2*x - 1)*(y - 1)*(z - 1) + 8*y*z*pow(x - 1, 2)*(y - 1)*(2*y - 1)*(z - 1) - 6*y*z*(x - 1)*(2*x - 1)*pow(y - 1, 2)*(z - 1);
+		default:
+			_error_("FS analytical solution"<<testid<<" not implemented yet");
+	}
+}
+/*}}}*/
+IssmDouble fy(IssmDouble x,IssmDouble y,IssmDouble z,int testid){ /*{{{*/ 
+	IssmDouble p=2;
+	IssmDouble q=2;
+	IssmDouble a=1;
+
+	switch(testid){
+		case 1:
+			z=y;
+			return -8*pow(x, 3) + 4*pow(x, 2)*z*(x - 1)*(z - 1) + 2*pow(x, 2)*z*(x - 1)*(2*z - 1) + 2*pow(x, 2)*(x - 1)*(z - 1)*(2*z - 1) + 12*pow(x, 2) + 4*x*z*pow(x - 1, 2)*(z - 1) + 2*x*z*pow(x - 1, 2)*(2*z - 1) + 2*x*pow(x - 1, 2)*(z - 1)*(2*z - 1) - 3*x - 6*pow(z, 4)*(2*x - 1) + 12*pow(z, 3)*(2*x - 1) - 6*pow(z, 2)*(2*x - 1) - 24*pow(z, 2)*(2*pow(x, 3) - 3*pow(x, 2) + x) + 24*z*(2*pow(x, 3) - 3*pow(x, 2) + x) - 1.0L/2.0L;
+		case 2: case 11:
+			z=y;
+			return -10*pow(PI, 2)*pow(p, 2)*pow(sin(PI*p*x), 2)*pow(sin(PI*p*z), 3)*cos(PI*p*x) + 6*pow(PI, 2)*pow(p, 2)*pow(sin(PI*p*x), 2)*sin(PI*p*z)*cos(PI*p*x)*pow(cos(PI*p*z), 2) + 2*pow(PI, 2)*pow(p, 2)*pow(sin(PI*p*z), 3)*pow(cos(PI*p*x), 3) + PI*q*sin(PI*q*x)*cos(PI*q*z);
+		case 3: 
+			return 4*pow(x, 2)*y*z*(x - 1)*(y - 1)*(z - 1) + 2*pow(x, 2)*y*z*(x - 1)*(2*y - 1)*(z - 1) + 2*pow(x, 2)*z*(x - 1)*(y - 1)*(2*y - 1)*(z - 1) - 4*x*pow(y, 2)*z*(x - 1)*(2*x - 1)*(z - 1) - 4*x*pow(y, 2)*z*pow(y - 1, 2)*(z - 1) - 2*x*pow(y, 2)*(x - 1)*(2*x - 1)*pow(y - 1, 2) + 4*x*y*z*pow(x - 1, 2)*(y - 1)*(z - 1) + 2*x*y*z*pow(x - 1, 2)*(2*y - 1)*(z - 1) - 16*x*y*z*(x - 1)*(2*x - 1)*(y - 1)*(z - 1) + 2*x*z*pow(x - 1, 2)*(y - 1)*(2*y - 1)*(z - 1) - 4*x*z*(x - 1)*(2*x - 1)*pow(y - 1, 2)*(z - 1) + x - 4*pow(y, 2)*z*(x - 1)*pow(y - 1, 2)*(z - 1) - 2*pow(y, 2)*z*(2*x - 1)*pow(y - 1, 2)*(z - 1) - 1.0L/2.0L;
+		case 4: 
+			return -2*pow(PI, 2)*pow(p, 2)*(cos(PI*p*y) - 1)*sin(PI*p*x)*sin(PI*p*z) - pow(PI, 2)*pow(p, 2)*sin(PI*p*x)*sin(PI*p*z)*cos(PI*p*y) + PI*q*sin(PI*q*x)*sin(PI*q*z)*cos(PI*q*y);
+		case 5: 
+			return -(cos(PI*p*y) - 1)*PI*PI*p*p*sin(PI*p*x) + PI*q*sin(PI*q*x)*cos(PI*q*y);
+		case 6: 
+			return - 4. * PI*PI * p*p * (cos(p*PI*y)-1) * sin(p*PI*x) * sin(p*PI*z)-  2. * PI*PI * p*p *  sin(p*PI*x)    * cos(p*PI*y) * sin(p*PI*z)+ q * PI * sin(q*PI*x) * cos(q*PI*y) * sin(q*PI*z);
+		case 7: 
+			z=y;
+			return -8*pow(x, 3) + 4*pow(x, 2)*z*(x - 1)*(z - 1) + 2*pow(x, 2)*z*(x - 1)*(2*z - 1) + 2*pow(x, 2)*(x - 1)*(z - 1)*(2*z - 1) + 12*pow(x, 2) + 4*x*z*pow(x - 1, 2)*(z - 1) + 2*x*z*pow(x - 1, 2)*(2*z - 1) + 2*x*pow(x - 1, 2)*(z - 1)*(2*z - 1) - 4*x - 6*pow(z, 4)*(2*x - 1) + 12*pow(z, 3)*(2*x - 1) - 6*pow(z, 2)*(2*x - 1) - 24*pow(z, 2)*(2*pow(x, 3) - 3*pow(x, 2) + x) + 24*z*(2*pow(x, 3) - 3*pow(x, 2) + x);
+		case 8: case 18:
+			return 1.0;
+		case 9: 
+			return -2*pow(PI, 2)*pow(p, 2)*(cos(PI*p*y) - 1)*sin(PI*p*x)*sin(PI*p*z) - pow(PI, 2)*pow(p, 2)*sin(PI*p*x)*sin(PI*p*z)*cos(PI*p*y) + 2*y*z;
+		case 10:
+			return -2*pow(PI, 2)*pow(p, 2)*(cos(PI*p*y) - 1)*sin(PI*p*x)*sin(PI*p*z) - pow(PI, 2)*pow(p, 2)*sin(PI*p*x)*sin(PI*p*z)*cos(PI*p*y) + PI*q*pow(z, a)*sin(PI*q*x)*cos(PI*q*y);
+		case 21:
+			z=y;
+			return x + (4.0L/3.0L)*pow(2, 1.0L/3.0L)*(2*pow(z, 3)*(2*pow(x, 3) - 3*pow(x, 2) + x) - 3*pow(z, 2)*(2*pow(x, 3) - 3*pow(x, 2) + x) + z*(2*pow(x, 3) - 3*pow(x, 2) + x))*(4*(pow(x, 2)*z*(x - 1)*(z - 1)*(2*z - 1) + x*z*pow(x - 1, 2)*(z - 1)*(2*z - 1))*(2*pow(x, 2)*z*(x - 1)*(z - 1) + pow(x, 2)*z*(x - 1)*(2*z - 1) + pow(x, 2)*(x - 1)*(z - 1)*(2*z - 1) + 2*x*z*pow(x - 1, 2)*(z - 1) + x*z*pow(x - 1, 2)*(2*z - 1) + x*pow(x - 1, 2)*(z - 1)*(2*z - 1)) + 4*(2*pow(z, 3)*(2*pow(x, 3) - 3*pow(x, 2) + x) - 3*pow(z, 2)*(2*pow(x, 3) - 3*pow(x, 2) + x) + z*(2*pow(x, 3) - 3*pow(x, 2) + x))*(2*pow(x, 3) - 3*pow(x, 2) + x + 6*pow(z, 2)*(2*pow(x, 3) - 3*pow(x, 2) + x) - 6*z*(2*pow(x, 3) - 3*pow(x, 2) + x)) + (2*pow(x, 2)*z*pow(x - 1, 2) + 2*pow(x, 2)*pow(x - 1, 2)*(z - 1) + pow(x, 2)*pow(x - 1, 2)*(2*z - 1) - 2*pow(z, 3)*(6*pow(x, 2) - 6*x + 1) + 3*pow(z, 2)*(6*pow(x, 2) - 6*x + 1) - z*(6*pow(x, 2) - 6*x + 1))*(2*pow(x, 2)*z*pow(x - 1, 2)*(z - 1) + pow(x, 2)*z*pow(x - 1, 2)*(2*z - 1) + pow(x, 2)*pow(x - 1, 2)*(z - 1)*(2*z - 1) - pow(z, 4)*(6*pow(x, 2) - 6*x + 1) + 2*pow(z, 3)*(6*pow(x, 2) - 6*x + 1) - pow(z, 2)*(6*pow(x, 2) - 6*x + 1)))/pow(4*pow(pow(x, 2)*z*(x - 1)*(z - 1)*(2*z - 1) + x*z*pow(x - 1, 2)*(z - 1)*(2*z - 1), 2) + 4*pow(2*pow(z, 3)*(2*pow(x, 3) - 3*pow(x, 2) + x) - 3*pow(z, 2)*(2*pow(x, 3) - 3*pow(x, 2) + x) + z*(2*pow(x, 3) - 3*pow(x, 2) + x), 2) + (1.0L/2.0L)*pow(2*pow(x, 2)*z*pow(x - 1, 2)*(z - 1) + pow(x, 2)*z*pow(x - 1, 2)*(2*z - 1) + pow(x, 2)*pow(x - 1, 2)*(z - 1)*(2*z - 1) - pow(z, 4)*(6*pow(x, 2) - 6*x + 1) + 2*pow(z, 3)*(6*pow(x, 2) - 6*x + 1) - pow(z, 2)*(6*pow(x, 2) - 6*x + 1), 2), 4.0L/3.0L) - 1.0L/3.0L*pow(2, 1.0L/3.0L)*(4*(pow(x, 2)*z*(x - 1)*(z - 1)*(2*z - 1) + x*z*pow(x - 1, 2)*(z - 1)*(2*z - 1))*(pow(x, 2)*z*(z - 1)*(2*z - 1) + 4*x*z*(x - 1)*(z - 1)*(2*z - 1) + z*pow(x - 1, 2)*(z - 1)*(2*z - 1)) + 4*(2*pow(z, 3)*(6*pow(x, 2) - 6*x + 1) - 3*pow(z, 2)*(6*pow(x, 2) - 6*x + 1) + z*(6*pow(x, 2) - 6*x + 1))*(2*pow(z, 3)*(2*pow(x, 3) - 3*pow(x, 2) + x) - 3*pow(z, 2)*(2*pow(x, 3) - 3*pow(x, 2) + x) + z*(2*pow(x, 3) - 3*pow(x, 2) + x)) + (2*pow(x, 2)*z*pow(x - 1, 2)*(z - 1) + pow(x, 2)*z*pow(x - 1, 2)*(2*z - 1) + pow(x, 2)*pow(x - 1, 2)*(z - 1)*(2*z - 1) - pow(z, 4)*(6*pow(x, 2) - 6*x + 1) + 2*pow(z, 3)*(6*pow(x, 2) - 6*x + 1) - pow(z, 2)*(6*pow(x, 2) - 6*x + 1))*(2*pow(x, 2)*z*(x - 1)*(z - 1) + pow(x, 2)*z*(x - 1)*(2*z - 1) + pow(x, 2)*(x - 1)*(z - 1)*(2*z - 1) + 2*x*z*pow(x - 1, 2)*(z - 1) + x*z*pow(x - 1, 2)*(2*z - 1) + x*pow(x - 1, 2)*(z - 1)*(2*z - 1) - 3*pow(z, 4)*(2*x - 1) + 6*pow(z, 3)*(2*x - 1) - 3*pow(z, 2)*(2*x - 1)))*(2*pow(x, 2)*z*pow(x - 1, 2)*(z - 1) + pow(x, 2)*z*pow(x - 1, 2)*(2*z - 1) + pow(x, 2)*pow(x - 1, 2)*(z - 1)*(2*z - 1) - pow(z, 4)*(6*pow(x, 2) - 6*x + 1) + 2*pow(z, 3)*(6*pow(x, 2) - 6*x + 1) - pow(z, 2)*(6*pow(x, 2) - 6*x + 1))/pow(4*pow(pow(x, 2)*z*(x - 1)*(z - 1)*(2*z - 1) + x*z*pow(x - 1, 2)*(z - 1)*(2*z - 1), 2) + 4*pow(2*pow(z, 3)*(2*pow(x, 3) - 3*pow(x, 2) + x) - 3*pow(z, 2)*(2*pow(x, 3) - 3*pow(x, 2) + x) + z*(2*pow(x, 3) - 3*pow(x, 2) + x), 2) + (1.0L/2.0L)*pow(2*pow(x, 2)*z*pow(x - 1, 2)*(z - 1) + pow(x, 2)*z*pow(x - 1, 2)*(2*z - 1) + pow(x, 2)*pow(x - 1, 2)*(z - 1)*(2*z - 1) - pow(z, 4)*(6*pow(x, 2) - 6*x + 1) + 2*pow(z, 3)*(6*pow(x, 2) - 6*x + 1) - pow(z, 2)*(6*pow(x, 2) - 6*x + 1), 2), 4.0L/3.0L) - 1.0L/2.0L - 2*pow(2, 1.0L/3.0L)*(2*pow(x, 3) - 3*pow(x, 2) + x + 6*pow(z, 2)*(2*pow(x, 3) - 3*pow(x, 2) + x) - 6*z*(2*pow(x, 3) - 3*pow(x, 2) + x))/pow(4*pow(pow(x, 2)*z*(x - 1)*(z - 1)*(2*z - 1) + x*z*pow(x - 1, 2)*(z - 1)*(2*z - 1), 2) + 4*pow(2*pow(z, 3)*(2*pow(x, 3) - 3*pow(x, 2) + x) - 3*pow(z, 2)*(2*pow(x, 3) - 3*pow(x, 2) + x) + z*(2*pow(x, 3) - 3*pow(x, 2) + x), 2) + (1.0L/2.0L)*pow(2*pow(x, 2)*z*pow(x - 1, 2)*(z - 1) + pow(x, 2)*z*pow(x - 1, 2)*(2*z - 1) + pow(x, 2)*pow(x - 1, 2)*(z - 1)*(2*z - 1) - pow(z, 4)*(6*pow(x, 2) - 6*x + 1) + 2*pow(z, 3)*(6*pow(x, 2) - 6*x + 1) - pow(z, 2)*(6*pow(x, 2) - 6*x + 1), 2), 1.0L/3.0L) + pow(2, 1.0L/3.0L)*(2*pow(x, 2)*z*(x - 1)*(z - 1) + pow(x, 2)*z*(x - 1)*(2*z - 1) + pow(x, 2)*(x - 1)*(z - 1)*(2*z - 1) + 2*x*z*pow(x - 1, 2)*(z - 1) + x*z*pow(x - 1, 2)*(2*z - 1) + x*pow(x - 1, 2)*(z - 1)*(2*z - 1) - 3*pow(z, 4)*(2*x - 1) + 6*pow(z, 3)*(2*x - 1) - 3*pow(z, 2)*(2*x - 1))/pow(4*pow(pow(x, 2)*z*(x - 1)*(z - 1)*(2*z - 1) + x*z*pow(x - 1, 2)*(z - 1)*(2*z - 1), 2) + 4*pow(2*pow(z, 3)*(2*pow(x, 3) - 3*pow(x, 2) + x) - 3*pow(z, 2)*(2*pow(x, 3) - 3*pow(x, 2) + x) + z*(2*pow(x, 3) - 3*pow(x, 2) + x), 2) + (1.0L/2.0L)*pow(2*pow(x, 2)*z*pow(x - 1, 2)*(z - 1) + pow(x, 2)*z*pow(x - 1, 2)*(2*z - 1) + pow(x, 2)*pow(x - 1, 2)*(z - 1)*(2*z - 1) - pow(z, 4)*(6*pow(x, 2) - 6*x + 1) + 2*pow(z, 3)*(6*pow(x, 2) - 6*x + 1) - pow(z, 2)*(6*pow(x, 2) - 6*x + 1), 2), 1.0L/3.0L);
+		case 24:
+			return -pow(2, 1.0L/3.0L)*pow(PI, 2)*pow(p, 2)*sin(PI*p*x)*sin(PI*p*z)*cos(PI*p*y)/pow(6*pow(PI, 2)*pow(p, 2)*pow(sin(PI*p*x), 2)*pow(sin(PI*p*y), 2)*pow(sin(PI*p*z), 2) + (1.0L/2.0L)*pow(-2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*z)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*z)*cos(PI*p*x), 2) + (1.0L/2.0L)*pow(pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*x)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*x)*cos(PI*p*z), 2) + (1.0L/2.0L)*pow(pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*y)*cos(PI*p*x) - 2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*y)*cos(PI*p*z), 2), 1.0L/3.0L) + (1.0L/3.0L)*pow(2, 1.0L/3.0L)*PI*p*(12*pow(PI, 3)*pow(p, 3)*pow(sin(PI*p*x), 2)*sin(PI*p*y)*pow(sin(PI*p*z), 2)*cos(PI*p*y) + (-2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*z)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*z)*cos(PI*p*x))*(2*pow(PI, 2)*pow(p, 2)*(cos(PI*p*x) - 1)*sin(PI*p*y)*sin(PI*p*z) - pow(PI, 2)*pow(p, 2)*sin(PI*p*y)*sin(PI*p*z)*cos(PI*p*x)) - (pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*x)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*x)*cos(PI*p*z))*(pow(PI, 3)*pow(p, 3)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*x)*sin(PI*p*y) + pow(PI, 2)*pow(p, 2)*sin(PI*p*x)*sin(PI*p*y)*cos(PI*p*z)) + (pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*y)*cos(PI*p*x) - 2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*y)*cos(PI*p*z))*(pow(PI, 3)*pow(p, 3)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*cos(PI*p*x)*cos(PI*p*y) - 2*pow(PI, 2)*pow(p, 2)*(cos(PI*p*x) - 1)*cos(PI*p*y)*cos(PI*p*z)))*sin(PI*p*x)*sin(PI*p*y)*sin(PI*p*z)/pow(6*pow(PI, 2)*pow(p, 2)*pow(sin(PI*p*x), 2)*pow(sin(PI*p*y), 2)*pow(sin(PI*p*z), 2) + (1.0L/2.0L)*pow(-2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*z)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*z)*cos(PI*p*x), 2) + (1.0L/2.0L)*pow(pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*x)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*x)*cos(PI*p*z), 2) + (1.0L/2.0L)*pow(pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*y)*cos(PI*p*x) - 2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*y)*cos(PI*p*z), 2), 4.0L/3.0L) + PI*q*sin(PI*q*x)*sin(PI*q*z)*cos(PI*q*y) - 1.0L/6.0L*pow(2, 1.0L/3.0L)*(-2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*z)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*z)*cos(PI*p*x))*(12*pow(PI, 3)*pow(p, 3)*sin(PI*p*x)*pow(sin(PI*p*y), 2)*pow(sin(PI*p*z), 2)*cos(PI*p*x) - (-2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*z)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*z)*cos(PI*p*x))*(pow(PI, 2)*pow(p, 2)*(cos(PI*p*y) - 1)*sin(PI*p*x)*sin(PI*p*z) - 2*pow(PI, 2)*pow(p, 2)*sin(PI*p*x)*sin(PI*p*z)*cos(PI*p*y)) + (pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*x)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*x)*cos(PI*p*z))*(pow(PI, 3)*pow(p, 3)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*cos(PI*p*x)*cos(PI*p*y) + pow(PI, 2)*pow(p, 2)*(cos(PI*p*y) - 1)*cos(PI*p*x)*cos(PI*p*z)) - (pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*y)*cos(PI*p*x) - 2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*y)*cos(PI*p*z))*(pow(PI, 3)*pow(p, 3)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*x)*sin(PI*p*y) - 2*pow(PI, 2)*pow(p, 2)*sin(PI*p*x)*sin(PI*p*y)*cos(PI*p*z)))/pow(6*pow(PI, 2)*pow(p, 2)*pow(sin(PI*p*x), 2)*pow(sin(PI*p*y), 2)*pow(sin(PI*p*z), 2) + (1.0L/2.0L)*pow(-2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*z)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*z)*cos(PI*p*x), 2) + (1.0L/2.0L)*pow(pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*x)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*x)*cos(PI*p*z), 2) + (1.0L/2.0L)*pow(pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*y)*cos(PI*p*x) - 2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*y)*cos(PI*p*z), 2), 4.0L/3.0L) - 1.0L/6.0L*pow(2, 1.0L/3.0L)*(pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*x)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*x)*cos(PI*p*z))*(12*pow(PI, 3)*pow(p, 3)*pow(sin(PI*p*x), 2)*pow(sin(PI*p*y), 2)*sin(PI*p*z)*cos(PI*p*z) + (-2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*z)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*z)*cos(PI*p*x))*(-2*pow(PI, 2)*pow(p, 2)*(cos(PI*p*x) - 1)*cos(PI*p*y)*cos(PI*p*z) + pow(PI, 2)*pow(p, 2)*(cos(PI*p*y) - 1)*cos(PI*p*x)*cos(PI*p*z)) - (pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*x)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*x)*cos(PI*p*z))*(pow(PI, 2)*pow(p, 2)*(cos(PI*p*y) - 1)*sin(PI*p*x)*sin(PI*p*z) + pow(PI, 2)*pow(p, 2)*sin(PI*p*x)*sin(PI*p*z)*cos(PI*p*y)) + (pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*y)*cos(PI*p*x) - 2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*y)*cos(PI*p*z))*(2*pow(PI, 2)*pow(p, 2)*(cos(PI*p*x) - 1)*sin(PI*p*y)*sin(PI*p*z) - pow(PI, 2)*pow(p, 2)*sin(PI*p*y)*sin(PI*p*z)*cos(PI*p*x)))/pow(6*pow(PI, 2)*pow(p, 2)*pow(sin(PI*p*x), 2)*pow(sin(PI*p*y), 2)*pow(sin(PI*p*z), 2) + (1.0L/2.0L)*pow(-2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*z)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*z)*cos(PI*p*x), 2) + (1.0L/2.0L)*pow(pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*x)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*x)*cos(PI*p*z), 2) + (1.0L/2.0L)*pow(pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*y)*cos(PI*p*x) - 2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*y)*cos(PI*p*z), 2), 4.0L/3.0L) - 1.0L/2.0L*pow(2, 1.0L/3.0L)*(pow(PI, 2)*pow(p, 2)*(cos(PI*p*y) - 1)*sin(PI*p*x)*sin(PI*p*z) - 2*pow(PI, 2)*pow(p, 2)*sin(PI*p*x)*sin(PI*p*z)*cos(PI*p*y))/pow(6*pow(PI, 2)*pow(p, 2)*pow(sin(PI*p*x), 2)*pow(sin(PI*p*y), 2)*pow(sin(PI*p*z), 2) + (1.0L/2.0L)*pow(-2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*z)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*z)*cos(PI*p*x), 2) + (1.0L/2.0L)*pow(pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*x)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*x)*cos(PI*p*z), 2) + (1.0L/2.0L)*pow(pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*y)*cos(PI*p*x) - 2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*y)*cos(PI*p*z), 2), 1.0L/3.0L) - 1.0L/2.0L*pow(2, 1.0L/3.0L)*(pow(PI, 2)*pow(p, 2)*(cos(PI*p*y) - 1)*sin(PI*p*x)*sin(PI*p*z) + pow(PI, 2)*pow(p, 2)*sin(PI*p*x)*sin(PI*p*z)*cos(PI*p*y))/pow(6*pow(PI, 2)*pow(p, 2)*pow(sin(PI*p*x), 2)*pow(sin(PI*p*y), 2)*pow(sin(PI*p*z), 2) + (1.0L/2.0L)*pow(-2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*z)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*z)*cos(PI*p*x), 2) + (1.0L/2.0L)*pow(pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*x)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*x)*cos(PI*p*z), 2) + (1.0L/2.0L)*pow(pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*y)*cos(PI*p*x) - 2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*y)*cos(PI*p*z), 2), 1.0L/3.0L); 
+
+		case 101: 
+			return 12*pow(x, 2)*y*z*(x - 1)*(y - 1)*(z - 1) + 6*pow(x, 2)*y*z*(x - 1)*(2*y - 1)*(z - 1) + 6*pow(x, 2)*z*(x - 1)*(y - 1)*(2*y - 1)*(z - 1) - 8*x*pow(y, 2)*z*(x - 1)*(2*x - 1)*(z - 1) - 4*x*pow(y, 2)*z*pow(y - 1, 2)*(z - 1) - 2*x*pow(y, 2)*(x - 1)*(2*x - 1)*pow(y - 1, 2) + 12*x*y*z*pow(x - 1, 2)*(y - 1)*(z - 1) + 6*x*y*z*pow(x - 1, 2)*(2*y - 1)*(z - 1) - 32*x*y*z*(x - 1)*(2*x - 1)*(y - 1)*(z - 1) + 6*x*z*pow(x - 1, 2)*(y - 1)*(2*y - 1)*(z - 1) - 8*x*z*(x - 1)*(2*x - 1)*pow(y - 1, 2)*(z - 1) - 4*pow(y, 2)*z*(x - 1)*pow(y - 1, 2)*(z - 1) - 2*pow(y, 2)*z*(2*x - 1)*pow(y - 1, 2)*(z - 1);
+		default:
+			_error_("FS analytical solution"<<testid<<" not implemented yet");
+	}
+}
+/*}}}*/
+IssmDouble fz(IssmDouble x,IssmDouble y,IssmDouble z,int testid){ /*{{{*/ 
+	IssmDouble p = 2.0;  
+	IssmDouble q = 2.0;   
+	IssmDouble a = 1.0;
+
+	switch(testid){
+		case 1: case 2: case 7: case 8: case 11: case 18: case 21:
+			return 0.;
+		case 3: 
+			return 2*pow(x, 2)*y*z*(x - 1)*(y - 1)*(2*y - 1) + 2*pow(x, 2)*y*(x - 1)*(y - 1)*(2*y - 1)*(z - 1) - 2*x*pow(y, 2)*z*(x - 1)*(2*x - 1)*(y - 1) - 2*x*pow(y, 2)*(x - 1)*(2*x - 1)*(y - 1)*(z - 1) + 2*x*y*z*pow(x - 1, 2)*(y - 1)*(2*y - 1) - 2*x*y*z*(x - 1)*(2*x - 1)*pow(y - 1, 2) + 2*x*y*pow(x - 1, 2)*(y - 1)*(2*y - 1)*(z - 1) - 2*x*y*(x - 1)*(2*x - 1)*pow(y - 1, 2)*(z - 1);
+		case 4: 
+			return -2*pow(PI, 2)*pow(p, 2)*(cos(PI*p*z) - 1)*sin(PI*p*x)*sin(PI*p*y) - pow(PI, 2)*pow(p, 2)*sin(PI*p*x)*sin(PI*p*y)*cos(PI*p*z) + PI*q*sin(PI*q*x)*sin(PI*q*y)*cos(PI*q*z);
+		case 5: 
+			return 2*PI*PI*p*p*sin(PI*p*x)*sin(PI*p*y);
+		case 6: 
+			return - 2. * PI*PI * p*p * (cos(p*PI*z)-1) * sin(p*PI*x) * sin(p*PI*y)-PI*PI * p*p *  sin(p*PI*x)    * sin(p*PI*y) * cos(p*PI*z)+ q * PI * sin(q*PI*x) * sin(q*PI*y) * cos(q*PI*z);
+		case 9:
+			return -2*pow(PI, 3)*pow(p, 3)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*x)*sin(PI*p*y) - pow(PI, 2)*pow(p, 2)*sin(PI*p*x)*sin(PI*p*y)*cos(PI*p*z) + pow(x, 2) + pow(y, 2);
+		case 10:
+			return a*pow(z, a - 1)*(sin(PI*q*x)*sin(PI*q*y) + 1) - 2*pow(PI, 3)*pow(p, 3)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*x)*sin(PI*p*y) - pow(PI, 2)*pow(p, 2)*sin(PI*p*x)*sin(PI*p*y)*cos(PI*p*z);
+		case 24:
+			return -pow(2, 1.0L/3.0L)*pow(PI, 2)*pow(p, 2)*sin(PI*p*x)*sin(PI*p*y)*cos(PI*p*z)/pow(6*pow(PI, 2)*pow(p, 2)*pow(sin(PI*p*x), 2)*pow(sin(PI*p*y), 2)*pow(sin(PI*p*z), 2) + (1.0L/2.0L)*pow(-2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*z)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*z)*cos(PI*p*x), 2) + (1.0L/2.0L)*pow(pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*x)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*x)*cos(PI*p*z), 2) + (1.0L/2.0L)*pow(pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*y)*cos(PI*p*x) - 2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*y)*cos(PI*p*z), 2), 1.0L/3.0L) + (1.0L/3.0L)*pow(2, 1.0L/3.0L)*PI*p*(12*pow(PI, 3)*pow(p, 3)*pow(sin(PI*p*x), 2)*pow(sin(PI*p*y), 2)*sin(PI*p*z)*cos(PI*p*z) + (-2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*z)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*z)*cos(PI*p*x))*(-2*pow(PI, 2)*pow(p, 2)*(cos(PI*p*x) - 1)*cos(PI*p*y)*cos(PI*p*z) + pow(PI, 2)*pow(p, 2)*(cos(PI*p*y) - 1)*cos(PI*p*x)*cos(PI*p*z)) - (pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*x)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*x)*cos(PI*p*z))*(pow(PI, 2)*pow(p, 2)*(cos(PI*p*y) - 1)*sin(PI*p*x)*sin(PI*p*z) + pow(PI, 2)*pow(p, 2)*sin(PI*p*x)*sin(PI*p*z)*cos(PI*p*y)) + (pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*y)*cos(PI*p*x) - 2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*y)*cos(PI*p*z))*(2*pow(PI, 2)*pow(p, 2)*(cos(PI*p*x) - 1)*sin(PI*p*y)*sin(PI*p*z) - pow(PI, 2)*pow(p, 2)*sin(PI*p*y)*sin(PI*p*z)*cos(PI*p*x)))*sin(PI*p*x)*sin(PI*p*y)*sin(PI*p*z)/pow(6*pow(PI, 2)*pow(p, 2)*pow(sin(PI*p*x), 2)*pow(sin(PI*p*y), 2)*pow(sin(PI*p*z), 2) + (1.0L/2.0L)*pow(-2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*z)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*z)*cos(PI*p*x), 2) + (1.0L/2.0L)*pow(pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*x)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*x)*cos(PI*p*z), 2) + (1.0L/2.0L)*pow(pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*y)*cos(PI*p*x) - 2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*y)*cos(PI*p*z), 2), 4.0L/3.0L) + PI*q*sin(PI*q*x)*sin(PI*q*y)*cos(PI*q*z) - 1.0L/6.0L*pow(2, 1.0L/3.0L)*(pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*x)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*x)*cos(PI*p*z))*(12*pow(PI, 3)*pow(p, 3)*pow(sin(PI*p*x), 2)*sin(PI*p*y)*pow(sin(PI*p*z), 2)*cos(PI*p*y) + (-2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*z)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*z)*cos(PI*p*x))*(2*pow(PI, 2)*pow(p, 2)*(cos(PI*p*x) - 1)*sin(PI*p*y)*sin(PI*p*z) - pow(PI, 2)*pow(p, 2)*sin(PI*p*y)*sin(PI*p*z)*cos(PI*p*x)) - (pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*x)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*x)*cos(PI*p*z))*(pow(PI, 3)*pow(p, 3)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*x)*sin(PI*p*y) + pow(PI, 2)*pow(p, 2)*sin(PI*p*x)*sin(PI*p*y)*cos(PI*p*z)) + (pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*y)*cos(PI*p*x) - 2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*y)*cos(PI*p*z))*(pow(PI, 3)*pow(p, 3)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*cos(PI*p*x)*cos(PI*p*y) - 2*pow(PI, 2)*pow(p, 2)*(cos(PI*p*x) - 1)*cos(PI*p*y)*cos(PI*p*z)))/pow(6*pow(PI, 2)*pow(p, 2)*pow(sin(PI*p*x), 2)*pow(sin(PI*p*y), 2)*pow(sin(PI*p*z), 2) + (1.0L/2.0L)*pow(-2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*z)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*z)*cos(PI*p*x), 2) + (1.0L/2.0L)*pow(pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*x)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*x)*cos(PI*p*z), 2) + (1.0L/2.0L)*pow(pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*y)*cos(PI*p*x) - 2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*y)*cos(PI*p*z), 2), 4.0L/3.0L) - 1.0L/6.0L*pow(2, 1.0L/3.0L)*(pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*y)*cos(PI*p*x) - 2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*y)*cos(PI*p*z))*(12*pow(PI, 3)*pow(p, 3)*sin(PI*p*x)*pow(sin(PI*p*y), 2)*pow(sin(PI*p*z), 2)*cos(PI*p*x) - (-2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*z)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*z)*cos(PI*p*x))*(pow(PI, 2)*pow(p, 2)*(cos(PI*p*y) - 1)*sin(PI*p*x)*sin(PI*p*z) - 2*pow(PI, 2)*pow(p, 2)*sin(PI*p*x)*sin(PI*p*z)*cos(PI*p*y)) + (pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*x)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*x)*cos(PI*p*z))*(pow(PI, 3)*pow(p, 3)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*cos(PI*p*x)*cos(PI*p*y) + pow(PI, 2)*pow(p, 2)*(cos(PI*p*y) - 1)*cos(PI*p*x)*cos(PI*p*z)) - (pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*y)*cos(PI*p*x) - 2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*y)*cos(PI*p*z))*(pow(PI, 3)*pow(p, 3)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*x)*sin(PI*p*y) - 2*pow(PI, 2)*pow(p, 2)*sin(PI*p*x)*sin(PI*p*y)*cos(PI*p*z)))/pow(6*pow(PI, 2)*pow(p, 2)*pow(sin(PI*p*x), 2)*pow(sin(PI*p*y), 2)*pow(sin(PI*p*z), 2) + (1.0L/2.0L)*pow(-2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*z)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*z)*cos(PI*p*x), 2) + (1.0L/2.0L)*pow(pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*x)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*x)*cos(PI*p*z), 2) + (1.0L/2.0L)*pow(pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*y)*cos(PI*p*x) - 2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*y)*cos(PI*p*z), 2), 4.0L/3.0L) - 1.0L/2.0L*pow(2, 1.0L/3.0L)*(pow(PI, 3)*pow(p, 3)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*x)*sin(PI*p*y) - 2*pow(PI, 2)*pow(p, 2)*sin(PI*p*x)*sin(PI*p*y)*cos(PI*p*z))/pow(6*pow(PI, 2)*pow(p, 2)*pow(sin(PI*p*x), 2)*pow(sin(PI*p*y), 2)*pow(sin(PI*p*z), 2) + (1.0L/2.0L)*pow(-2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*z)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*z)*cos(PI*p*x), 2) + (1.0L/2.0L)*pow(pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*x)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*x)*cos(PI*p*z), 2) + (1.0L/2.0L)*pow(pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*y)*cos(PI*p*x) - 2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*y)*cos(PI*p*z), 2), 1.0L/3.0L) - 1.0L/2.0L*pow(2, 1.0L/3.0L)*(pow(PI, 3)*pow(p, 3)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*x)*sin(PI*p*y) + pow(PI, 2)*pow(p, 2)*sin(PI*p*x)*sin(PI*p*y)*cos(PI*p*z))/pow(6*pow(PI, 2)*pow(p, 2)*pow(sin(PI*p*x), 2)*pow(sin(PI*p*y), 2)*pow(sin(PI*p*z), 2) + (1.0L/2.0L)*pow(-2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*z)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*z)*cos(PI*p*x), 2) + (1.0L/2.0L)*pow(pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*x)*cos(PI*p*y) + PI*p*(cos(PI*p*y) - 1)*sin(PI*p*x)*cos(PI*p*z), 2) + (1.0L/2.0L)*pow(pow(PI, 2)*pow(p, 2)*(cos(PI*p*z)/(PI*p) - 1/(PI*p))*sin(PI*p*y)*cos(PI*p*x) - 2*PI*p*(cos(PI*p*x) - 1)*sin(PI*p*y)*cos(PI*p*z), 2), 1.0L/3.0L);
+		default:
+			_error_("FS analytical solution"<<testid<<" not implemented yet");
+	}
+}
+/*}}}*/
+IssmDouble alpha(IssmDouble x,IssmDouble y,IssmDouble z,int testid){ /*{{{*/ 
+	IssmDouble p = 2.0;  
+	IssmDouble q = 2.0;   
+
+	switch(testid){
+		case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 21:
+			return 0.;
+		case 11:
+			z=y;
+			return -10*PI*p*sqrt((9.0L/25.0L)*pow(PI, 2)*pow(p, 2)*pow(cos(2*PI*p*x), 2) + 1)*(9*pow(PI, 2)*pow(p, 2)*pow(sin(PI*p*x), 2)*pow(cos(2*PI*p*x), 2)*pow(cos(PI*p*z), 2) - 9*pow(PI, 2)*pow(p, 2)*pow(sin(PI*p*z), 2)*pow(cos(PI*p*x), 2)*pow(cos(2*PI*p*x), 2) + 90*PI*p*sin(PI*p*x)*sin(PI*p*z)*cos(PI*p*x)*cos(2*PI*p*x)*cos(PI*p*z) - 25*pow(sin(PI*p*x), 2)*pow(cos(PI*p*z), 2) + 25*pow(sin(PI*p*z), 2)*pow(cos(PI*p*x), 2))/((9*pow(PI, 2)*pow(p, 2)*pow(cos(2*PI*p*x), 2) + 25)*(3*PI*p*sin(PI*p*z)*cos(PI*p*x)*cos(2*PI*p*x) - 5*sin(PI*p*x)*cos(PI*p*z))*sin(PI*p*x)*sin(PI*p*z));
+		case 18:
+			return (120.0L/109.0L)*sqrt(109.)/(10*x - 3*z);
+		default:
+			_error_("FS analytical solution"<<testid<<" not implemented yet");
+	}
+}
+/*}}}*/
+
Index: /issm/trunk/src/c/shared/FSanalyticals/fsanalyticals.h
===================================================================
--- /issm/trunk/src/c/shared/FSanalyticals/fsanalyticals.h	(revision 17806)
+++ /issm/trunk/src/c/shared/FSanalyticals/fsanalyticals.h	(revision 17806)
@@ -0,0 +1,15 @@
+/*!\file: elements.h
+ * \brief prototypes for elements.h
+ */ 
+
+#ifndef _SHARED_ANALYTICALS_H_
+#define _SHARED_ANALYTICALS_H_
+
+#include "../Numerics/types.h"
+
+IssmDouble fx(IssmDouble x_coord, IssmDouble y_coord, IssmDouble z_coord, int testid);
+IssmDouble fy(IssmDouble x_coord, IssmDouble y_coord, IssmDouble z_coord, int testid);
+IssmDouble fz(IssmDouble x_coord, IssmDouble y_coord, IssmDouble z_coord, int testid);
+IssmDouble alpha(IssmDouble x_coord, IssmDouble y_coord, IssmDouble z_coord, int testid);
+
+#endif //ifndef _SHARED_ANALYTICALS_H_
Index: /issm/trunk/src/c/shared/Matrix/MatrixUtils.cpp
===================================================================
--- /issm/trunk/src/c/shared/Matrix/MatrixUtils.cpp	(revision 17805)
+++ /issm/trunk/src/c/shared/Matrix/MatrixUtils.cpp	(revision 17806)
@@ -367,2 +367,15 @@
 
 }/*}}}*/
+/*FUNCTION Matrix3x3Solve(IssmDouble* X,IssmDouble* A,IssmDouble* B) {{{*/
+void Matrix3x3Solve(IssmDouble* X,IssmDouble* A,IssmDouble* B){
+
+	IssmDouble Ainv[3][3];
+
+	Matrix3x3Invert(&Ainv[0][0],A);
+	for(int i=0;i<3;i++) X[i]=Ainv[i][0]*B[0] + Ainv[i][1]*B[1] + Ainv[i][2]*B[2];
+
+}/*}}}*/
+/*FUNCTION Matrix4x4Solve(IssmDouble* X,IssmDouble* A,IssmDouble *B) {{{*/
+void Matrix4x4Solve(IssmDouble* X,IssmDouble* A,IssmDouble *B){
+	_error_("STOP");
+}/*}}}*/
Index: /issm/trunk/src/c/shared/Matrix/matrix.h
===================================================================
--- /issm/trunk/src/c/shared/Matrix/matrix.h	(revision 17805)
+++ /issm/trunk/src/c/shared/Matrix/matrix.h	(revision 17806)
@@ -15,4 +15,6 @@
 void Matrix3x3Invert(IssmDouble* Ainv, IssmDouble* A);
 void Matrix3x3Determinant(IssmDouble* Adet,IssmDouble* A);
+void Matrix3x3Solve(IssmDouble* X,IssmDouble* A,IssmDouble* B);
+void Matrix4x4Solve(IssmDouble* X,IssmDouble* A,IssmDouble* B);
 
 #endif //ifndef _MATRIXUTILS_H_
Index: /issm/trunk/src/c/shared/Numerics/GaussPoints.cpp
===================================================================
--- /issm/trunk/src/c/shared/Numerics/GaussPoints.cpp	(revision 17805)
+++ /issm/trunk/src/c/shared/Numerics/GaussPoints.cpp	(revision 17806)
@@ -42,6 +42,18 @@
 	static IssmPDouble xi4[]={-0.861136311594053,-0.339981043584856, 0.339981043584856, 0.861136311594053};
 
-	static IssmPDouble* wgtp[MAX_LINE_GAUS_PTS]={wgt1 ,wgt2 ,wgt3 ,wgt4 };
-	static IssmPDouble* xip [MAX_LINE_GAUS_PTS]={xi1  ,xi2  ,xi3  ,xi4  };
+	/*npoint= 5*/
+	static IssmPDouble wgt5[]={0.5688888888888889,0.4786286704993665,0.4786286704993665,0.2369268850561891,0.2369268850561891};
+	static IssmPDouble xi5[]={0.0000000000000000,-0.5384693101056831,0.5384693101056831,-0.9061798459386640,0.9061798459386640};
+
+	/*npoint= 6*/
+	static IssmPDouble wgt6[]={0.3607615730481386,0.3607615730481386,0.4679139345726910,0.4679139345726910,0.1713244923791704,0.1713244923791704};
+	static IssmPDouble xi6[]={-0.6612093864662645,0.6612093864662645,-0.2386191860831969,0.2386191860831969,-0.9324695142031521,0.9324695142031521};
+
+	/*npoint= 7*/
+	static IssmPDouble wgt7[]={0.4179591836734694,0.3818300505051189,0.3818300505051189,0.2797053914892766,0.2797053914892766,0.1294849661688697,0.1294849661688697};
+	static IssmPDouble xi7[]={0.0000000000000000,-0.4058451513773972,0.4058451513773972,-0.7415311855993945,0.7415311855993945,-0.9491079123427585,0.9491079123427585};
+
+	static IssmPDouble* wgtp[MAX_LINE_GAUS_PTS]={wgt1 ,wgt2 ,wgt3 ,wgt4, wgt5, wgt6, wgt7};
+	static IssmPDouble* xip [MAX_LINE_GAUS_PTS]={xi1  ,xi2  ,xi3  ,xi4, xi5, xi6, xi7};
 
 	*pxgaus =xNew<IssmPDouble>(ngaus);
@@ -1199,5 +1211,5 @@
 }/*}}}*/
 /*FUNCTION GaussLegendreTetra{{{*/
-void GaussLegendreTetra( int* pngaus, IssmPDouble** pl1, IssmPDouble** pl2, IssmPDouble** pl3, IssmPDouble** pl4, IssmPDouble** pwgt, int iord ) {
+void GaussLegendreTetra( int* pngaus, IssmDouble** pl1, IssmDouble** pl2, IssmDouble** pl3, IssmDouble** pl4, IssmDouble** pwgt, int iord ) {
 	/* Gauss quadrature points for the tetrahedron.
 
@@ -1252,4 +1264,7 @@
 	static IssmPDouble l13[]={
 		0.250000000000000, 0.500000000000000, 0.166666666666667, 
+		0.166666666666667, 0.166666666666667};
+	static IssmPDouble l23[]={
+		0.250000000000000, 0.166666666666667, 0.500000000000000, 
 		0.166666666666667, 0.166666666666667};
 	static IssmPDouble l33[]={
@@ -1376,5 +1391,5 @@
 	static IssmPDouble* wgtp[MAX_TETRA_SYM_ORD]={wgt1,wgt2,wgt3,wgt4,wgt5,wgt6};
 	static IssmPDouble* l1p [MAX_TETRA_SYM_ORD]={l11 ,l12 ,l13 ,l14 ,l15 ,l16 };
-	static IssmPDouble* l2p [MAX_TETRA_SYM_ORD]={l21 ,l22 ,l32 ,l24 ,l25 ,l26 };
+	static IssmPDouble* l2p [MAX_TETRA_SYM_ORD]={l21 ,l22 ,l23 ,l24 ,l25 ,l26 };
 	static IssmPDouble* l3p [MAX_TETRA_SYM_ORD]={l31 ,l32 ,l33 ,l34 ,l35 ,l36 };
 	static IssmPDouble* l4p [MAX_TETRA_SYM_ORD]={l41 ,l42 ,l43 ,l44 ,l45 ,l46 };
@@ -1399,9 +1414,9 @@
 		*pngaus=np[iord-1];
 
-		*pl1  =xNew<IssmPDouble>(*pngaus);
-		*pl2  =xNew<IssmPDouble>(*pngaus);
-		*pl3  =xNew<IssmPDouble>(*pngaus);
-		*pl4  =xNew<IssmPDouble>(*pngaus);
-		*pwgt =xNew<IssmPDouble>(*pngaus);
+		*pl1  =xNew<IssmDouble>(*pngaus);
+		*pl2  =xNew<IssmDouble>(*pngaus);
+		*pl3  =xNew<IssmDouble>(*pngaus);
+		*pl4  =xNew<IssmDouble>(*pngaus);
+		*pwgt =xNew<IssmDouble>(*pngaus);
 
 		for (i=0; i<*pngaus; i++) {
@@ -1419,9 +1434,9 @@
 		*pngaus=nigaus*nigaus*nigaus;
 
-		*pl1  =xNew<IssmPDouble>(*pngaus);
-		*pl2  =xNew<IssmPDouble>(*pngaus);
-		*pl3  =xNew<IssmPDouble>(*pngaus);
-		*pl4  =xNew<IssmPDouble>(*pngaus);
-		*pwgt =xNew<IssmPDouble>(*pngaus);
+		*pl1  =xNew<IssmDouble>(*pngaus);
+		*pl2  =xNew<IssmDouble>(*pngaus);
+		*pl3  =xNew<IssmDouble>(*pngaus);
+		*pl4  =xNew<IssmDouble>(*pngaus);
+		*pwgt =xNew<IssmDouble>(*pngaus);
 
 		/*  get the gauss points in each direction  */
Index: /issm/trunk/src/c/shared/Numerics/GaussPoints.h
===================================================================
--- /issm/trunk/src/c/shared/Numerics/GaussPoints.h	(revision 17805)
+++ /issm/trunk/src/c/shared/Numerics/GaussPoints.h	(revision 17806)
@@ -7,10 +7,10 @@
 #define _GAUSSPOINTS_H
 
-#define MAX_LINE_GAUS_PTS    4
+#define MAX_LINE_GAUS_PTS    7
 void GaussLegendreLinear(IssmPDouble** pxgaus, IssmPDouble** pxwgt, int ngaus);
 #define MAX_TRIA_SYM_ORD    20
 void GaussLegendreTria(int* pngaus, IssmDouble** pl1, IssmDouble** pl2, IssmDouble** pl3, IssmDouble** pwgt, int iord);
 #define MAX_TETRA_SYM_ORD    6
-void GaussLegendreTetra(int* pngaus, IssmPDouble** pl1, IssmPDouble** pl2, IssmPDouble** pl3, IssmPDouble** pl4, IssmPDouble** pwgt, int iord);
+void GaussLegendreTetra(int* pngaus, IssmDouble** pl1, IssmDouble** pl2, IssmDouble** pl3, IssmDouble** pl4, IssmDouble** pwgt, int iord);
 #define MAX_LINE_GLOB_PTS    5
 void GaussLobatto(IssmPDouble** pxgaus, IssmPDouble** pxwgt, int ngaus);
Index: /issm/trunk/src/c/shared/Numerics/NewtonSolveDnorm.cpp
===================================================================
--- /issm/trunk/src/c/shared/Numerics/NewtonSolveDnorm.cpp	(revision 17806)
+++ /issm/trunk/src/c/shared/Numerics/NewtonSolveDnorm.cpp	(revision 17806)
@@ -0,0 +1,53 @@
+#include <math.h>
+#include "./types.h"
+#include "../Exceptions/exceptions.h"
+
+int NewtonSolveDnorm(IssmDouble* pdnorm,IssmDouble c1,IssmDouble c2,IssmDouble c3,IssmDouble n,IssmDouble dnorm){
+	/* solve the following equation using Newton-Raphson
+	 *
+	 *   c1*x^(s-1) + c2*x = c3
+	 *
+	 *   s = (1+n)/n
+	 *
+	 *   we solve y = 10^x:
+	 */
+
+	/*trivial solution*/
+	if(c3==0.){
+		*pdnorm = 0.;
+		return 0;
+	}
+
+	/*Intermediaries*/
+	int        counter = 0;
+	IssmDouble s = (1.+n)/n;
+	IssmDouble y2;
+	IssmDouble threshold = 1.e-12;
+
+	/*Initial guess*/
+	_assert_(dnorm>0.); 
+	IssmDouble y1 = log10(dnorm);
+
+	while(true){
+
+		/*Newton step*/
+		y2 = y1 - (c1*pow(pow(10.,y1),s-1.) + c2*pow(10.,y1) - c3)/((s-1)*c1*log(10.)*pow(pow(10.,y1),s-1.) + c2*log(10.)*pow(10.,y1));
+
+		if( fabs(y2-y1)/(fabs(y2))<threshold ){
+			break;
+		}
+		else{
+			y1=y2;
+			counter++;
+		}
+
+		if(counter>50) break;
+	}
+
+	/*Avoid extremely large values that indicate non convergence*/
+	if(y2>50.) y2 = 50;
+
+	/*Assign output pointer*/
+	*pdnorm = pow(10.,y2);
+	return 0;
+}
Index: /issm/trunk/src/c/shared/Numerics/numerics.h
===================================================================
--- /issm/trunk/src/c/shared/Numerics/numerics.h	(revision 17805)
+++ /issm/trunk/src/c/shared/Numerics/numerics.h	(revision 17806)
@@ -38,3 +38,5 @@
 int         cubic(IssmDouble a, IssmDouble b, IssmDouble c, IssmDouble d, double X[3], int *num);
 
+int         NewtonSolveDnorm(IssmDouble* pdnorm,IssmDouble c1,IssmDouble c2,IssmDouble c3,IssmDouble n,IssmDouble dnorm);
+
 #endif //ifndef _NUMERICS_H_
Index: /issm/trunk/src/c/shared/shared.h
===================================================================
--- /issm/trunk/src/c/shared/shared.h	(revision 17805)
+++ /issm/trunk/src/c/shared/shared.h	(revision 17806)
@@ -6,4 +6,5 @@
 #define _SHARED_H_
 
+#include "./FSanalyticals/fsanalyticals.h"
 #include "./MemOps/MemOps.h"
 #include "./Bamg/shared.h"
Index: sm/trunk/src/c/solutionsequences/solutionsequence_damage_nonlinear.cpp
===================================================================
--- /issm/trunk/src/c/solutionsequences/solutionsequence_damage_nonlinear.cpp	(revision 17805)
+++ 	(revision )
@@ -1,80 +1,0 @@
-/*
- * \brief: solutionsequence_damage_nonlinear.cpp: core of the damage solution 
- */ 
-
-#include "../toolkits/toolkits.h"
-#include "../classes/classes.h"
-#include "../shared/shared.h"
-#include "../modules/modules.h"
-
-void solutionsequence_damage_nonlinear(FemModel* femmodel){
-
-	/*solution : */
-	Vector<IssmDouble>* Dg=NULL; 
-	Vector<IssmDouble>* Df=NULL; 
-	Vector<IssmDouble>* Df_old=NULL; 
-	Vector<IssmDouble>* ys=NULL; 
-
-	/*intermediary: */
-	Matrix<IssmDouble>* Kff=NULL;
-	Matrix<IssmDouble>* Kfs=NULL;
-	Vector<IssmDouble>* pf=NULL;
-	Vector<IssmDouble>* df=NULL;
-
-	bool converged;
-	int constraints_converged;
-	int num_unstable_constraints;
-	int count;
-	int damage_penalty_threshold;
-	int damage_maxiter;
-
-	/*parameters:*/
-	int  configuration_type;
-
-	/*Recover parameters: */
-	femmodel->parameters->FindParam(&damage_penalty_threshold,DamagePenaltyThresholdEnum);
-	femmodel->parameters->FindParam(&configuration_type,ConfigurationTypeEnum);
-	femmodel->parameters->FindParam(&damage_maxiter,DamageMaxiterEnum);
-
-	count=1;
-	converged=false;
-
-	InputUpdateFromConstantx(femmodel,true,ResetPenaltiesEnum);
-	InputUpdateFromConstantx(femmodel,false,ConvergedEnum);
-	femmodel->UpdateConstraintsx();
-
-	for(;;){
-
-		delete Df_old; Df_old=Df;
-		SystemMatricesx(&Kff, &Kfs, &pf,&df, NULL,femmodel);
-		CreateNodalConstraintsx(&ys,femmodel->nodes,configuration_type);
-		Reduceloadx(pf, Kfs, ys); delete Kfs;
-		Solverx(&Df, Kff, pf,Df_old, df, femmodel->parameters);
-		delete Kff;delete pf;delete Dg; delete df;
-		Mergesolutionfromftogx(&Dg, Df,ys,femmodel->nodes,femmodel->parameters); delete ys;
-		InputUpdateFromSolutionx(femmodel,Dg);
-
-		ConstraintsStatex(&constraints_converged,&num_unstable_constraints,femmodel);
-
-		if (!converged){
-			if(VerboseConvergence()) _printf0_("   #unstable constraints = " << num_unstable_constraints << "\n");
-			if (num_unstable_constraints <= damage_penalty_threshold)converged=true;
-			if (count>=damage_maxiter){
-				converged=true;
-				_printf0_("   maximum number of iterations (" << damage_maxiter << ") exceeded\n"); 
-			}
-		}
-		count++;
-
-		InputUpdateFromConstantx(femmodel,converged,ConvergedEnum);
-
-		if(converged)break;
-	}
-
-	InputUpdateFromSolutionx(femmodel,Dg);
-
-	/*Free ressources: */
-	delete Dg;
-	delete Df;
-	delete Df_old;
-}
Index: /issm/trunk/src/c/solutionsequences/solutionsequence_hydro_nonlinear.cpp
===================================================================
--- /issm/trunk/src/c/solutionsequences/solutionsequence_hydro_nonlinear.cpp	(revision 17805)
+++ /issm/trunk/src/c/solutionsequences/solutionsequence_hydro_nonlinear.cpp	(revision 17806)
@@ -7,4 +7,6 @@
 #include "../shared/shared.h"
 #include "../modules/modules.h"
+/*FIXME, dirty hack to get the solutionsequence linear needed to compute the slopes*/
+#include "../solutionsequences/solutionsequences.h"
 
 void solutionsequence_hydro_nonlinear(FemModel* femmodel){
@@ -18,14 +20,20 @@
 	Vector<IssmDouble>* uf_epl=NULL;
 	Vector<IssmDouble>* uf_epl_sub_iter=NULL; 
+	Vector<IssmDouble>* ug_epl_sub_iter=NULL;
 	Vector<IssmDouble>* ug_epl_main_iter=NULL;
 
 	Vector<IssmDouble>* ys=NULL; 
 	Vector<IssmDouble>* dug=NULL;
+	Vector<IssmDouble>* duf=NULL;
 
 	Matrix<IssmDouble>* Kff=NULL;
 	Matrix<IssmDouble>* Kfs=NULL;
+
 	Vector<IssmDouble>* pf=NULL;
 	Vector<IssmDouble>* df=NULL;
 
+	HydrologyDCInefficientAnalysis* inefanalysis = NULL;
+	HydrologyDCEfficientAnalysis* effanalysis = NULL;
+	
 	bool       sedconverged,eplconverged,hydroconverged;
 	bool       isefficientlayer;
@@ -34,5 +42,5 @@
 	int        sedcount,eplcount,hydrocount;
 	int        hydro_maxiter;
-	IssmDouble sediment_kmax,time;
+	IssmDouble sediment_kmax;
 	IssmDouble eps_hyd;
 	IssmDouble ndu_sed,nu_sed;
@@ -42,31 +50,38 @@
 	femmodel->SetCurrentConfiguration(HydrologyDCInefficientAnalysisEnum);
 	femmodel->parameters->FindParam(&isefficientlayer,HydrologydcIsefficientlayerEnum);
+	femmodel->parameters->FindParam(&hydro_maxiter,HydrologydcMaxIterEnum);
 	femmodel->parameters->FindParam(&eps_hyd,HydrologydcRelTolEnum);
-	femmodel->parameters->FindParam(&time,TimeEnum);
-	hydro_maxiter=150;
+
 	hydrocount=1;
 	hydroconverged=false;
+	/*We don't need the outer loop if only one layer is used*/
+	if(!isefficientlayer) hydroconverged=true;
 
 	/*Retrieve inputs as the initial state for the non linear iteration*/
-	//femmodel->SetCurrentConfiguration(HydrologyDCInefficientAnalysisEnum);
-	GetSolutionFromInputsx(&ug_sed,femmodel);
+	GetSolutionFromInputsx(&ug_sed,femmodel);	
+	Reducevectorgtofx(&uf_sed, ug_sed, femmodel->nodes,femmodel->parameters);
 
 	if(isefficientlayer) {
+		inefanalysis = new HydrologyDCInefficientAnalysis();
+		effanalysis = new HydrologyDCEfficientAnalysis();
 		femmodel->SetCurrentConfiguration(HydrologyDCEfficientAnalysisEnum);
 		GetSolutionFromInputsx(&ug_epl,femmodel);
+		/*Initialize the element mask*/
+		inefanalysis->ElementizeEplMask(femmodel);
 	}
-
-	/*Iteration on the two layers*/
+	/*The real computation starts here, outermost loop is on the two layer system*/
 	for(;;){
+
 		sedcount=1;
 		eplcount=1;
-		//save pointer to old velocity
-		ug_sed_main_iter=ug_sed->Duplicate();
-		ug_sed->Copy(ug_sed_main_iter);
+
+		/*If there is two layers we need an outer loop value to compute convergence*/
 		if(isefficientlayer){
+			ug_sed_main_iter=ug_sed->Duplicate();
+			ug_sed->Copy(ug_sed_main_iter);
 			ug_epl_main_iter=ug_epl->Duplicate();
 			ug_epl->Copy(ug_epl_main_iter);
 		}
-
+		/*Loop on sediment layer to deal with transfer and head value*/
 		femmodel->SetCurrentConfiguration(HydrologyDCInefficientAnalysisEnum);
 		InputUpdateFromConstantx(femmodel,true,ResetPenaltiesEnum);
@@ -74,32 +89,62 @@
 		femmodel->UpdateConstraintsx();
 		femmodel->parameters->SetParam(HydrologySedimentEnum,HydrologyLayerEnum);
-
-		/*Iteration on the sediment layer*/
-		sedconverged=false;
+		
+		/*Reset constraint on the ZigZag Lock, this thing doesn't work, it have to disapear*/
+		ResetConstraintsx(femmodel);
+
+		/* {{{ *//*Treating the sediment*/
 		for(;;){
-			femmodel->HydrologyTransferx();
-			SystemMatricesx(&Kff,&Kfs,&pf,&df,&sediment_kmax,femmodel);
-			CreateNodalConstraintsx(&ys,femmodel->nodes,HydrologyDCInefficientAnalysisEnum);
-			Reduceloadx(pf,Kfs,ys); delete Kfs;
-			delete uf_sed;
-			Solverx(&uf_sed,Kff,pf,uf_sed_sub_iter,df,femmodel->parameters);
-			delete Kff; delete pf; delete df;
+			sedconverged=false;
+			uf_sed_sub_iter=uf_sed->Duplicate();_assert_(uf_sed_sub_iter);
+			uf_sed->Copy(uf_sed_sub_iter);
+			/* {{{ *//*Loop on the sediment layer to deal with the penalization*/
+			for(;;){
+				/* {{{ *//*Core of the computation*/
+				if(VerboseSolution()) _printf0_("Building Sediment Matrix...\n");
+				SystemMatricesx(&Kff,&Kfs,&pf,&df,&sediment_kmax,femmodel);
+				CreateNodalConstraintsx(&ys,femmodel->nodes,HydrologyDCInefficientAnalysisEnum);
+				Reduceloadx(pf,Kfs,ys); delete Kfs;
+				delete uf_sed;
+				Solverx(&uf_sed,Kff,pf,uf_sed_sub_iter,df,femmodel->parameters);
+				delete Kff; delete pf; delete df;
+				delete ug_sed;
+				Mergesolutionfromftogx(&ug_sed,uf_sed,ys,femmodel->nodes,femmodel->parameters); delete ys;
+				InputUpdateFromSolutionx(femmodel,ug_sed);
+				ConstraintsStatex(&constraints_converged,&num_unstable_constraints,femmodel);
+				/* }}} */
+				if (!sedconverged){
+					if(VerboseConvergence()) _printf0_("   # Sediment unstable constraints = " << num_unstable_constraints << "\n");
+					if(num_unstable_constraints==0) sedconverged = true;
+					if (sedcount>=hydro_maxiter){
+						_error_("   maximum number of Sediment iterations (" << hydro_maxiter << ") exceeded");
+					}
+				}
+				/*Add an iteration and get out of the loop if the penalisation is converged*/
+				sedcount++;
+				if(sedconverged)break;
+			}
+		
+			/* }}} *//*End of the sediment penalization loop*/
+			/*Update EPL mask*/
+			if(isefficientlayer){
+				inefanalysis->ElementizeEplMask(femmodel);
+			}
+			sedconverged=false;
+			
+			/*Checking convegence on the value of the sediment head*/
+			duf=uf_sed_sub_iter->Duplicate();_assert_(duf);
+			uf_sed_sub_iter->Copy(duf);
+			duf->AYPX(uf_sed,-1.0);
+			ndu_sed=duf->Norm(NORM_TWO);
+			delete duf;
+			nu_sed=uf_sed_sub_iter->Norm(NORM_TWO);
+			if (xIsNan<IssmDouble>(ndu_sed) || xIsNan<IssmDouble>(nu_sed)) _error_("convergence criterion is NaN!");
+			if (ndu_sed==0.0 && nu_sed==0.0) nu_sed=1.0e-6; /*Hacking the case where the layer is empty*/
+			if(VerboseConvergence()) _printf0_(setw(50) << left << "   Inner Sediment Convergence criterion:" << ndu_sed/nu_sed*100 << "%, aiming lower than " << eps_hyd*10*100 << " %\n");
+			if((ndu_sed/nu_sed)<eps_hyd*10.){
+				if(VerboseConvergence()) _printf0_("   # Inner sediment convergence achieve \n");
+				sedconverged=true;
+			}
 			delete uf_sed_sub_iter;
-			uf_sed_sub_iter=uf_sed->Duplicate();
-			uf_sed->Copy(uf_sed_sub_iter);
-			delete ug_sed;
-			Mergesolutionfromftogx(&ug_sed,uf_sed,ys,femmodel->nodes,femmodel->parameters); delete ys;
-			InputUpdateFromSolutionx(femmodel,ug_sed);
-			ConstraintsStatex(&constraints_converged,&num_unstable_constraints,femmodel);
-
-			if (!sedconverged){
-				if(VerboseConvergence()) _printf0_("   # Sediment unstable constraints = " << num_unstable_constraints << "\n");
-				if(num_unstable_constraints==0) sedconverged = true;
-				if (sedcount>=hydro_maxiter){
-					_error_("   maximum number of Sediment iterations (" << hydro_maxiter << ") exceeded");
-				}
-			}
-			sedcount++;
-
 			if(sedconverged){
 				femmodel->parameters->SetParam(sediment_kmax,HydrologySedimentKmaxEnum);
@@ -110,17 +155,37 @@
 			}
 		}
-
-		/*Second layer*/
+		/* }}} *//*End of the global sediment loop*/
+		/* {{{ *//*Now dealing with the EPL in the same way*/
 		if(isefficientlayer){
 			femmodel->SetCurrentConfiguration(HydrologyDCEfficientAnalysisEnum);
+			/*updating mask*/
+			femmodel->HydrologyEPLupdateDomainx();
 			InputUpdateFromConstantx(femmodel,true,ResetPenaltiesEnum);
 			InputUpdateFromConstantx(femmodel,false,ConvergedEnum);
-			femmodel->HydrologyEPLupdateDomainx();
 			femmodel->parameters->SetParam(HydrologyEfficientEnum,HydrologyLayerEnum);
 
-			/*Iteration on the EPL layer*/
-			eplconverged = false;
 			for(;;){
-				femmodel->HydrologyTransferx();
+				eplconverged=false;
+				ug_epl_sub_iter=ug_epl->Duplicate();_assert_(ug_epl_sub_iter);
+				ug_epl->Copy(ug_epl_sub_iter);
+				/* {{{ *//*Retrieve the EPL head slopes and compute EPL Thickness*/
+				if(VerboseSolution()) _printf0_("computing EPL Head slope...\n");
+				inefanalysis->ElementizeEplMask(femmodel);
+				femmodel->SetCurrentConfiguration(L2ProjectionEPLAnalysisEnum);
+				femmodel->UpdateConstraintsL2ProjectionEPLx();
+				femmodel->parameters->SetParam(EplHeadSlopeXEnum,InputToL2ProjectEnum);
+				solutionsequence_linear(femmodel);
+				femmodel->parameters->SetParam(EplHeadSlopeYEnum,InputToL2ProjectEnum);
+				solutionsequence_linear(femmodel);
+				femmodel->SetCurrentConfiguration(HydrologyDCEfficientAnalysisEnum);
+
+				effanalysis->ComputeEPLThickness(femmodel);
+
+				//updating mask after the computation of the epl thickness (Allow to close too thin EPL)
+				femmodel->HydrologyEPLupdateDomainx();
+				inefanalysis->ElementizeEplMask(femmodel);
+				/* }}} */
+					
+				if(VerboseSolution()) _printf0_("Building EPL Matrix...\n");
 				SystemMatricesx(&Kff,&Kfs,&pf,&df,NULL,femmodel);
 				CreateNodalConstraintsx(&ys,femmodel->nodes,HydrologyDCEfficientAnalysisEnum);
@@ -129,5 +194,5 @@
 				Solverx(&uf_epl,Kff,pf,uf_epl_sub_iter,df,femmodel->parameters);
 				delete Kff; delete pf; delete df;
-				delete uf_epl_sub_iter; 
+				delete uf_epl_sub_iter;
 				uf_epl_sub_iter=uf_epl->Duplicate();
 				uf_epl->Copy(uf_epl_sub_iter);
@@ -136,18 +201,24 @@
 				InputUpdateFromSolutionx(femmodel,ug_epl);
 				ConstraintsStatex(&constraints_converged,&num_unstable_constraints,femmodel);
-				femmodel->HydrologyEPLupdateDomainx();			
-
-				if (!eplconverged){
-					if(VerboseConvergence()) _printf0_("   # EPL unstable constraints = " << num_unstable_constraints << "\n");
-					if(num_unstable_constraints==0) eplconverged = true;
-					if (eplcount>=hydro_maxiter){
-						_error_("   maximum number of EPL iterations (" << hydro_maxiter << ") exceeded");
-					}
+						
+				dug=ug_epl_sub_iter->Duplicate();_assert_(dug);
+				ug_epl_sub_iter->Copy(dug);
+				dug->AYPX(ug_epl,-1.0);
+				ndu_epl=dug->Norm(NORM_TWO);
+				delete dug;
+				nu_epl=ug_epl_sub_iter->Norm(NORM_TWO);
+				if (xIsNan<IssmDouble>(ndu_epl) || xIsNan<IssmDouble>(nu_epl)) _error_("convergence criterion is NaN!");
+				if (ndu_epl==0.0 && nu_epl==0.0) nu_epl=1.0e-6; /*Hacking the case where the EPL is used but empty*/
+				if(VerboseConvergence()) _printf0_(setw(50) << left << "   Inner EPL Convergence criterion:" << ndu_epl/nu_epl*100 << "%, aiming lower than " << eps_hyd*10*100 << " %\n");
+				if((ndu_epl/nu_epl)<eps_hyd*10.) eplconverged=true;
+				if (eplcount>=hydro_maxiter){
+					_error_("   maximum number of EPL iterations (" << hydro_maxiter << ") exceeded");
 				}
 				eplcount++;
-
+				
+				delete ug_epl_sub_iter;
 				if(eplconverged){
+					if(VerboseSolution()) _printf0_("eplconverged...\n");
 					InputUpdateFromConstantx(femmodel,eplconverged,ConvergedEnum);
-					InputUpdateFromConstantx(femmodel,sediment_kmax,MeltingOffsetEnum);
 					InputUpdateFromSolutionx(femmodel,ug_epl);
 					break;
@@ -155,8 +226,10 @@
 			}
 		}
-		/*System convergence check*/
+		/* }}} */ /*End of the global EPL loop*/
+
+		/* {{{ */ /*Now dealing with the convergence of the whole system*/
 		if(!hydroconverged){
 			//compute norm(du)/norm(u)
-			dug=ug_sed->Duplicate(); _assert_(dug);
+			dug=ug_sed_main_iter->Duplicate(); _assert_(dug);
 			ug_sed_main_iter->Copy(dug);	
 			dug->AYPX(ug_sed,-1.0);
@@ -166,34 +239,23 @@
 			delete ug_sed_main_iter;
 			if (xIsNan<IssmDouble>(ndu_sed) || xIsNan<IssmDouble>(nu_sed)) _error_("Sed convergence criterion is NaN!");
+			if (ndu_sed==0.0 && nu_sed==0.0) nu_sed=1.0e-6; /*Hacking the case where the Sediment is used but empty*/
+			dug=ug_epl_main_iter->Duplicate();_assert_(dug); 
+			ug_epl_main_iter->Copy(dug); 
+			dug->AYPX(ug_epl,-1.0);
+			ndu_epl=dug->Norm(NORM_TWO); 
+			delete dug;
+			nu_epl=ug_epl_main_iter->Norm(NORM_TWO);
+			delete ug_epl_main_iter;
+			if (xIsNan<IssmDouble>(ndu_epl) || xIsNan<IssmDouble>(nu_epl)) _error_("EPL convergence criterion is NaN!");
+			if (ndu_epl==0.0 && nu_epl==0.0) nu_epl=1.0e-6; /*Hacking the case where the EPL is used but empty*/
 			if (!xIsNan<IssmDouble>(eps_hyd)){
-				if (!isefficientlayer){
-					if ((ndu_sed/nu_sed)<eps_hyd){
-						if(VerboseConvergence()) _printf0_(setw(50) << left << "   Converged after, " << hydrocount << " iterations \n");
-						hydroconverged=true;
-					}
-					else{ 
-						if(VerboseConvergence()) _printf0_(setw(50) << left << "   Sediment Convergence criterion:" << ndu_sed/nu_sed*100 << " > " << eps_hyd*100 << " %\n");
-						hydroconverged=false;
-					}
-				}
-				else{
-					dug=ug_epl->Duplicate();_assert_(dug); 
-					ug_epl_main_iter->Copy(dug);_assert_(ug_epl_main_iter); 
-					dug->AYPX(ug_epl,-1.0);
-					ndu_epl=dug->Norm(NORM_TWO); 
-					delete dug;
-					nu_epl=ug_epl_main_iter->Norm(NORM_TWO);
-					delete ug_epl_main_iter;
-					if (xIsNan<IssmDouble>(ndu_epl) || xIsNan<IssmDouble>(nu_epl)) _error_("EPL convergence criterion is NaN!");
-					if (ndu_epl==0.0 && nu_epl==0.0) nu_epl=1.0e-6; /*Hacking the case where the EPL is used but empty*/
-					if ((ndu_epl/nu_epl)<eps_hyd && (ndu_sed/nu_sed)<(eps_hyd*10)){
-						if (VerboseConvergence()) _printf0_(setw(50) << left << "   Converged after, " << hydrocount << " iterations \n");
-						hydroconverged=true;
-					}
-					else{ 
-						if(VerboseConvergence()) _printf0_(setw(50) << left << "   Sediment Convergence criterion:" << ndu_sed/nu_sed*100 << " aiming lower than " << eps_hyd*100 << " %\n");
-						if(VerboseConvergence()) _printf0_(setw(50) << left << "   EPL Convergence criterion:" << ndu_epl/nu_epl*100 << " aiming lower than " << eps_hyd*100 << " %\n");
-						hydroconverged=false;
-					}
+				if ((ndu_epl/nu_epl)<eps_hyd && (ndu_sed/nu_sed)<(eps_hyd)){
+					if (VerboseConvergence()) _printf0_(setw(50) << left << "   Converged after, " << hydrocount << " iterations \n");
+					hydroconverged=true;
+				}
+				else{ 
+					if(VerboseConvergence()) _printf0_(setw(50) << left << "   Sediment Convergence criterion:" << ndu_sed/nu_sed*100 << "%, aiming lower than " << eps_hyd*100 << " %\n");
+					if(VerboseConvergence()) _printf0_(setw(50) << left << "   EPL Convergence criterion:" << ndu_epl/nu_epl*100 << "%, aiming lower than " << eps_hyd*100 << " %\n");
+					hydroconverged=false;
 				}
 			}
@@ -206,8 +268,8 @@
 		if(hydroconverged)break;
 	}
-
+	/* }}} */
+	if(isefficientlayer)InputUpdateFromSolutionx(femmodel,ug_epl);
+	femmodel->SetCurrentConfiguration(HydrologyDCInefficientAnalysisEnum);
 	InputUpdateFromSolutionx(femmodel,ug_sed);
-	if(isefficientlayer)InputUpdateFromSolutionx(femmodel,ug_epl);
-
 	/*Free ressources: */
 	delete ug_epl;
@@ -215,6 +277,6 @@
 	delete uf_sed;
 	delete uf_epl;
-	delete uf_sed_sub_iter;
 	delete uf_epl_sub_iter;
-	//delete dug;
+	delete inefanalysis;
+	delete effanalysis;
 }
Index: /issm/trunk/src/c/solutionsequences/solutionsequence_la_theta.cpp
===================================================================
--- /issm/trunk/src/c/solutionsequences/solutionsequence_la_theta.cpp	(revision 17806)
+++ /issm/trunk/src/c/solutionsequences/solutionsequence_la_theta.cpp	(revision 17806)
@@ -0,0 +1,102 @@
+/*!\file: solutionsequence_la_theta.cpp
+ * \brief: numerical core of la_theta solutions
+ */ 
+
+#include "../toolkits/toolkits.h"
+#include "../classes/classes.h"
+#include "../shared/shared.h"
+#include "../modules/modules.h"
+
+void solutionsequence_la_theta(FemModel* femmodel){
+
+	/*intermediary: */
+	Matrix<IssmDouble>*  Kff    = NULL;
+	Matrix<IssmDouble>*  Kfs    = NULL;
+	Vector<IssmDouble>*  ug_old = NULL;
+	Vector<IssmDouble>*  ug     = NULL;
+	Vector<IssmDouble>*  uf     = NULL;
+	Vector<IssmDouble>*  pf     = NULL;
+	Vector<IssmDouble>*  df     = NULL;
+	Vector<IssmDouble>*  ys     = NULL;
+	IssmDouble           eps_rel,r,theta; // 0<theta<.5   -> .15<theta<.45
+	int                  configuration_type,max_nonlinear_iterations;
+
+	/*Create analysis*/
+	StressbalanceAnalysis* analysis = new StressbalanceAnalysis();
+
+	/*Recover parameters: */
+	femmodel->parameters->FindParam(&configuration_type,ConfigurationTypeEnum);
+	femmodel->parameters->FindParam(&eps_rel,StressbalanceReltolEnum);
+	femmodel->parameters->FindParam(&max_nonlinear_iterations,StressbalanceMaxiterEnum);
+	femmodel->parameters->FindParam(&r,AugmentedLagrangianREnum);
+	femmodel->parameters->FindParam(&theta,AugmentedLagrangianThetaEnum);
+
+	/*Update constraints and initialize d and tau if necessary*/
+	femmodel->UpdateConstraintsx();
+	analysis->InitializeXTH(femmodel->elements,femmodel->parameters);
+
+	/*Convergence criterion*/
+	int  count = 0;
+	GetSolutionFromInputsx(&ug,femmodel);
+	Vector<IssmDouble>* vx     = NULL;
+	Vector<IssmDouble>* vx_old = NULL;
+	GetVectorFromInputsx(&vx,femmodel,VxEnum,VertexEnum);
+
+	while(true){
+		count++;
+
+		/*save pointer to old velocity*/
+		delete ug_old;ug_old=ug;
+		delete vx_old;vx_old=vx;
+
+		/*Calculate d*/
+		if(theta>0.){
+			analysis->InputUpdateFromSolutionFSXTH_d(femmodel->elements,femmodel->parameters);
+		}
+
+		/*Solve KU=F*/
+		SystemMatricesx(&Kff,&Kfs,&pf,&df,NULL,femmodel);
+		CreateNodalConstraintsx(&ys,femmodel->nodes,configuration_type);
+		Reduceloadx(pf, Kfs, ys); delete Kfs;
+		Solverx(&uf, Kff, pf, NULL, df, femmodel->parameters); 
+		delete Kff; delete pf; delete df;
+		Mergesolutionfromftogx(&ug, uf,ys,femmodel->nodes,femmodel->parameters);delete uf; delete ys;
+
+		/*Update solution*/
+		InputUpdateFromSolutionx(femmodel,ug); 
+
+		/*Update d and tau accordingly*/
+		analysis->InputUpdateFromSolutionFSXTH_d(  femmodel->elements,femmodel->parameters);
+		analysis->InputUpdateFromSolutionFSXTH_tau(femmodel->elements,femmodel->parameters);
+		GetVectorFromInputsx(&vx,femmodel,VxEnum,VertexEnum);
+
+		/*Check for convergence*/
+		//Vector<IssmDouble>* dug=ug_old->Duplicate(); ug_old->Copy(dug); dug->AYPX(ug,-1.0);
+		//IssmDouble ndu=dug->Norm(NORM_TWO);   delete dug;
+		//IssmDouble nu =ug_old->Norm(NORM_TWO);
+		Vector<IssmDouble>* dvx=vx_old->Duplicate(); vx_old->Copy(dvx); dvx->AYPX(vx,-1.0);
+		IssmDouble ndu=dvx->Norm(NORM_TWO);   delete dvx;
+		IssmDouble nu =vx_old->Norm(NORM_TWO);
+		if (xIsNan<IssmDouble>(ndu) || xIsNan<IssmDouble>(nu)) _error_("convergence criterion is NaN!");
+		if((ndu/nu)<eps_rel){
+			if(VerboseConvergence()) _printf0_(setw(50) << left << "   Convergence criterion: norm(du)/norm(u)" << ndu/nu*100 << " < " << eps_rel*100 << " %\n");
+			break;
+		}
+		else{ 
+			if(VerboseConvergence()) _printf0_(setw(50) << left << "   Convergence criterion: norm(du)/norm(u)" << ndu/nu*100 << " > " << eps_rel*100 << " %\n");
+		}
+
+		if(count>=max_nonlinear_iterations){
+			_printf0_("   maximum number of nonlinear iterations (" << max_nonlinear_iterations << ") exceeded\n"); 
+			break;
+		}
+	}
+
+	if(VerboseConvergence()) _printf0_("\n   total number of iterations: " << count-1 << "\n");
+
+	delete ug;  
+	delete ug_old;  
+	delete vx;  
+	delete vx_old;  
+	delete analysis;
+}
Index: /issm/trunk/src/c/solutionsequences/solutionsequence_linear.cpp
===================================================================
--- /issm/trunk/src/c/solutionsequences/solutionsequence_linear.cpp	(revision 17805)
+++ /issm/trunk/src/c/solutionsequences/solutionsequence_linear.cpp	(revision 17806)
@@ -23,5 +23,4 @@
 	femmodel->parameters->FindParam(&configuration_type,ConfigurationTypeEnum);
 	femmodel->UpdateConstraintsx();
-
 	SystemMatricesx(&Kff,&Kfs,&pf,&df,NULL,femmodel);
 	CreateNodalConstraintsx(&ys,femmodel->nodes,configuration_type);
Index: /issm/trunk/src/c/solutionsequences/solutionsequence_newton.cpp
===================================================================
--- /issm/trunk/src/c/solutionsequences/solutionsequence_newton.cpp	(revision 17805)
+++ /issm/trunk/src/c/solutionsequences/solutionsequence_newton.cpp	(revision 17806)
@@ -86,16 +86,18 @@
 		delete Kff; delete pf;
 		if(converged==true){	
+			int step; IssmDouble time;
 			bool max_iteration_state=false;
-			int tempStep=1;
-			IssmDouble tempTime=1.0;
-			femmodel->results->AddObject(new GenericExternalResult<bool>(femmodel->results->Size()+1, MaxIterationConvergenceFlagEnum, max_iteration_state, tempStep, tempTime));
+			femmodel->parameters->FindParam(&time,TimeEnum);
+			femmodel->parameters->FindParam(&step,StepEnum);
+			femmodel->results->AddObject(new GenericExternalResult<bool>(femmodel->results->Size()+1, MaxIterationConvergenceFlagEnum, max_iteration_state, step,time));
 			break;
 		}
 		if(count>=max_nonlinear_iterations){
 			_printf0_("   maximum number of Newton iterations (" << max_nonlinear_iterations << ") exceeded\n"); 
+			int step; IssmDouble time;
 			bool max_iteration_state=true;
-			int tempStep=1;
-			IssmDouble tempTime=1.0;
-			femmodel->results->AddObject(new GenericExternalResult<bool>(femmodel->results->Size()+1, MaxIterationConvergenceFlagEnum, max_iteration_state, tempStep, tempTime));
+			femmodel->parameters->FindParam(&time,TimeEnum);
+			femmodel->parameters->FindParam(&step,StepEnum);
+			femmodel->results->AddObject(new GenericExternalResult<bool>(femmodel->results->Size()+1, MaxIterationConvergenceFlagEnum, max_iteration_state, step, time));
 			break;
 		}
Index: /issm/trunk/src/c/solutionsequences/solutionsequence_nonlinear.cpp
===================================================================
--- /issm/trunk/src/c/solutionsequences/solutionsequence_nonlinear.cpp	(revision 17805)
+++ /issm/trunk/src/c/solutionsequences/solutionsequence_nonlinear.cpp	(revision 17806)
@@ -85,7 +85,8 @@
 		if(converged==true){
 			bool max_iteration_state=false;
-			int tempStep=1;
-			IssmDouble tempTime=1.0;
-			femmodel->results->AddObject(new GenericExternalResult<bool>(femmodel->results->Size()+1, MaxIterationConvergenceFlagEnum, max_iteration_state, tempStep, tempTime));
+			int step; IssmDouble time;
+			femmodel->parameters->FindParam(&time,TimeEnum);
+			femmodel->parameters->FindParam(&step,StepEnum);
+			femmodel->results->AddObject(new GenericExternalResult<bool>(femmodel->results->Size()+1, MaxIterationConvergenceFlagEnum, max_iteration_state, step, time));
 			break;
 		}
@@ -96,7 +97,8 @@
 			InputUpdateFromSolutionx(femmodel,ug);		
 			bool max_iteration_state=true;
-			int tempStep=1;
-			IssmDouble tempTime=1.0;
-			femmodel->results->AddObject(new GenericExternalResult<bool>(femmodel->results->Size()+1, MaxIterationConvergenceFlagEnum, max_iteration_state, tempStep, tempTime));
+			int step; IssmDouble time;
+			femmodel->parameters->FindParam(&time,TimeEnum);
+			femmodel->parameters->FindParam(&step,StepEnum);
+			femmodel->results->AddObject(new GenericExternalResult<bool>(femmodel->results->Size()+1, MaxIterationConvergenceFlagEnum, max_iteration_state, step, time));
 			break;
 		}
Index: /issm/trunk/src/c/solutionsequences/solutionsequence_thermal_nonlinear.cpp
===================================================================
--- /issm/trunk/src/c/solutionsequences/solutionsequence_thermal_nonlinear.cpp	(revision 17805)
+++ /issm/trunk/src/c/solutionsequences/solutionsequence_thermal_nonlinear.cpp	(revision 17806)
@@ -74,5 +74,5 @@
 
 	InputUpdateFromSolutionx(femmodel,tg);
-	InputUpdateFromConstantx(femmodel,melting_offset,MeltingOffsetEnum);
+	femmodel->parameters->SetParam(melting_offset,MeltingOffsetEnum);
 
 	/*Free ressources: */
Index: /issm/trunk/src/c/solutionsequences/solutionsequences.h
===================================================================
--- /issm/trunk/src/c/solutionsequences/solutionsequences.h	(revision 17805)
+++ /issm/trunk/src/c/solutionsequences/solutionsequences.h	(revision 17806)
@@ -13,5 +13,4 @@
 
 void solutionsequence_thermal_nonlinear(FemModel* femmodel);
-void solutionsequence_damage_nonlinear(FemModel* femmodel);
 void solutionsequence_hydro_nonlinear(FemModel* femmodel);
 void solutionsequence_nonlinear(FemModel* femmodel,bool conserve_loads);
@@ -19,4 +18,5 @@
 void solutionsequence_FScoupling_nonlinear(FemModel* femmodel,bool conserve_loads);
 void solutionsequence_linear(FemModel* femmodel);
+void solutionsequence_la_theta(FemModel* femmodel);
 void solutionsequence_adjoint_linear(FemModel* femmodel);
 
Index: /issm/trunk/src/c/toolkits/gsl/DenseGslSolve.cpp
===================================================================
--- /issm/trunk/src/c/toolkits/gsl/DenseGslSolve.cpp	(revision 17805)
+++ /issm/trunk/src/c/toolkits/gsl/DenseGslSolve.cpp	(revision 17806)
@@ -32,5 +32,5 @@
 }
 /*}}}*/
-void DenseGslSolve(/*output*/ IssmPDouble** px,/*stiffness matrix:*/ IssmPDouble* Kff, int Kff_M, int Kff_N, /*right hand side load vector: */ IssmPDouble* pf, int pf_M, Parameters* parameters){ /*{{{*/
+void DenseGslSolve(IssmPDouble** px,IssmPDouble* Kff,int Kff_M,int Kff_N,IssmPDouble* pf,int pf_M,Parameters* parameters){ /*{{{*/
 
 	/*Intermediary: */
Index: /issm/trunk/src/c/toolkits/gsl/gslincludes.h
===================================================================
--- /issm/trunk/src/c/toolkits/gsl/gslincludes.h	(revision 17805)
+++ /issm/trunk/src/c/toolkits/gsl/gslincludes.h	(revision 17806)
@@ -21,5 +21,5 @@
 
 void DenseGslSolve(IssmPDouble** pX,IssmPDouble* A,IssmPDouble* B, int n);
-void DenseGslSolve(IssmDouble** px, IssmDouble* Kff,int Kff_M, int Kff_N, IssmDouble* pf, int pf_M, Parameters* parameters);
+void DenseGslSolve(IssmDouble** pX,IssmDouble* Kff,int Kff_M,int Kff_N,IssmDouble* pf,int pf_M,Parameters* parameters);
 
 void SolverxSeq(IssmPDouble *X, IssmPDouble *A, IssmPDouble *B,int n);
Index: /issm/trunk/src/c/toolkits/mpi/issmmpi.cpp
===================================================================
--- /issm/trunk/src/c/toolkits/mpi/issmmpi.cpp	(revision 17805)
+++ /issm/trunk/src/c/toolkits/mpi/issmmpi.cpp	(revision 17806)
@@ -324,5 +324,5 @@
 	       source,
 	       tag,
-	       AMPI_SEND, // as long as there are no other variants
+	       AMPI_FROM_SEND, // as long as there are no other variants
 	       comm,
 	       status);
@@ -464,5 +464,5 @@
 	       dest,
 	       tag,
-	       AMPI_RECV, // as long as there are no other variants
+	       AMPI_TO_RECV, // as long as there are no other variants
 	       comm);
 # else
Index: /issm/trunk/src/c/toolkits/mpi/issmmpi.h
===================================================================
--- /issm/trunk/src/c/toolkits/mpi/issmmpi.h	(revision 17805)
+++ /issm/trunk/src/c/toolkits/mpi/issmmpi.h	(revision 17806)
@@ -12,6 +12,7 @@
 #error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
 #endif
-
 #include <cstddef>
+#include <cassert>
+#include "../../shared/Numerics/types.h"
 
 #ifdef _HAVE_MPI_
@@ -83,4 +84,36 @@
 	/*}}}*/
 # endif 
+
+template <class T> ISSM_MPI_Datatype TypeToMPIType(){assert(false);};
+template <> inline ISSM_MPI_Datatype TypeToMPIType<IssmDouble>(){return ISSM_MPI_DOUBLE;};
+template <> inline ISSM_MPI_Datatype TypeToMPIType<int>(){return ISSM_MPI_INT;};
+template <> inline ISSM_MPI_Datatype TypeToMPIType<char>(){return ISSM_MPI_CHAR;};
+template <class T> int ISSM_MPI_Bcast(T *buffer, int count,int root, ISSM_MPI_Comm comm){  /*{{{*/
+
+	int rc=0;
+
+	/*Get MPI type*/
+	ISSM_MPI_Datatype datatype = TypeToMPIType<T>();
+
+#ifdef _HAVE_MPI_
+# ifdef _HAVE_AMPI_
+	rc=AMPI_Bcast(buffer, 
+				count,
+				datatype,
+				root,
+				comm);
+# else
+	rc=MPI_Bcast(buffer, 
+				count,
+				datatype,
+				root,
+				comm);
+# endif
+#else 
+	// nothing to be done here 
+#endif
+	return rc;
+}/*}}}*/
+
 /* interfaces  {{{*/
 int ISSM_MPI_Allgather(void *sendbuf, int sendcount, ISSM_MPI_Datatype sendtype, void *recvbuf, int recvcount, ISSM_MPI_Datatype recvtype, ISSM_MPI_Comm comm);
Index: /issm/trunk/src/c/toolkits/objects/Matrix.h
===================================================================
--- /issm/trunk/src/c/toolkits/objects/Matrix.h	(revision 17805)
+++ /issm/trunk/src/c/toolkits/objects/Matrix.h	(revision 17806)
@@ -16,4 +16,5 @@
 #include <cstring>
 #include "../../shared/Enum/Enum.h"
+#include "../petsc/petscincludes.h"
 #include "../issm/issmtoolkit.h"
 /*}}}*/
Index: /issm/trunk/src/c/toolkits/objects/Solver.h
===================================================================
--- /issm/trunk/src/c/toolkits/objects/Solver.h	(revision 17805)
+++ /issm/trunk/src/c/toolkits/objects/Solver.h	(revision 17806)
@@ -14,4 +14,5 @@
 #include "./Vector.h"
 #include "../issm/issmtoolkit.h"
+#include "../petsc/petscincludes.h"
 class Parameters;
 
Index: /issm/trunk/src/c/toolkits/objects/Vector.h
===================================================================
--- /issm/trunk/src/c/toolkits/objects/Vector.h	(revision 17805)
+++ /issm/trunk/src/c/toolkits/objects/Vector.h	(revision 17806)
@@ -16,4 +16,5 @@
 #include <cstring>
 #include "../../shared/Enum/Enum.h"
+#include "../petsc/petscincludes.h"
 #include "../issm/issmtoolkit.h"
 /*}}}*/
@@ -304,4 +305,18 @@
 		}
 		/*}}}*/
+		/*FUNCTION Max{{{*/
+		doubletype Max(void){_assert_(this);
+
+			doubletype max=0;
+
+			if(type==PetscVecType){
+				#ifdef _HAVE_PETSC_
+				max=this->pvector->Max();
+				#endif
+			}
+			else _error_("operation not supported yet");
+			return max;
+		}
+		/*}}}*/
 		/*FUNCTION Norm{{{*/
 		doubletype Norm(NormMode norm_type){_assert_(this);
Index: /issm/trunk/src/c/toolkits/petsc/objects/PetscMat.cpp
===================================================================
--- /issm/trunk/src/c/toolkits/petsc/objects/PetscMat.cpp	(revision 17805)
+++ /issm/trunk/src/c/toolkits/petsc/objects/PetscMat.cpp	(revision 17806)
@@ -47,5 +47,5 @@
 	MatSetFromOptions(this->matrix);
 	MatMPIAIJSetPreallocation(this->matrix,0,d_nnz,0,o_nnz);
-	//MatSetOption(this->matrix,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);
+//	MatSetOption(this->matrix,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);
 
 }
Index: /issm/trunk/src/c/toolkits/petsc/objects/PetscVec.cpp
===================================================================
--- /issm/trunk/src/c/toolkits/petsc/objects/PetscVec.cpp	(revision 17805)
+++ /issm/trunk/src/c/toolkits/petsc/objects/PetscVec.cpp	(revision 17806)
@@ -188,4 +188,15 @@
 }
 /*}}}*/
+/*FUNCTION PetscVec::Max{{{*/
+IssmDouble PetscVec::Max(void){
+
+	_assert_(this->vector);
+
+	IssmDouble max;
+	VecMax(this->vector,NULL,&max);
+	return max;
+
+}
+/*}}}*/
 /*FUNCTION PetscVec::Norm{{{*/
 IssmDouble PetscVec::Norm(NormMode mode){
Index: /issm/trunk/src/c/toolkits/petsc/objects/PetscVec.h
===================================================================
--- /issm/trunk/src/c/toolkits/petsc/objects/PetscVec.h	(revision 17805)
+++ /issm/trunk/src/c/toolkits/petsc/objects/PetscVec.h	(revision 17806)
@@ -38,21 +38,22 @@
 
 		/*PetscVec specific routines*/
-		void Echo(void);
-		void Assemble(void);
-		void SetValues(int ssize, int* list, IssmDouble* values, InsMode mode);
-		void SetValue(int dof, IssmDouble value, InsMode  mode);
-		void GetValue(IssmDouble* pvalue, int dof);
-		void GetSize(int* pM);
-		void GetLocalSize(int* pM);
-		PetscVec* Duplicate(void);
-		void Set(IssmDouble value);
-		void AXPY(PetscVec* X, IssmDouble a);
-		void AYPX(PetscVec* X, IssmDouble a);
+		void        Echo(void);
+		void        Assemble(void);
+		void        SetValues(int ssize, int* list, IssmDouble* values, InsMode mode);
+		void        SetValue(int dof, IssmDouble value, InsMode  mode);
+		void        GetValue(IssmDouble* pvalue, int dof);
+		void        GetSize(int* pM);
+		void        GetLocalSize(int* pM);
+		PetscVec*   Duplicate(void);
+		void        Set(IssmDouble value);
+		void        AXPY(PetscVec* X, IssmDouble a);
+		void        AYPX(PetscVec* X, IssmDouble a);
 		IssmDouble* ToMPISerial(void);
-		void Copy(PetscVec* to);
-		IssmDouble Norm(NormMode norm_type);
-		void Scale(IssmDouble scale_factor);
-		void PointwiseDivide(PetscVec* x,PetscVec* y);
-		IssmDouble Dot(PetscVec* vector);
+		void        Copy(PetscVec* to);
+		IssmDouble  Norm(NormMode norm_type);
+		IssmDouble  Max(void);
+		void        Scale(IssmDouble scale_factor);
+		void        PointwiseDivide(PetscVec* x,PetscVec* y);
+		IssmDouble  Dot(PetscVec* vector);
 };
 
Index: /issm/trunk/src/c/toolkits/petsc/patches/NewVec.cpp
===================================================================
--- /issm/trunk/src/c/toolkits/petsc/patches/NewVec.cpp	(revision 17805)
+++ /issm/trunk/src/c/toolkits/petsc/patches/NewVec.cpp	(revision 17806)
@@ -33,11 +33,7 @@
 
 	VecCreate(comm,&vector); 
-
 	VecSetSizes(vector,local_size,PETSC_DECIDE); 
 	VecSetFromOptions(vector); 
 
-	/*fill with 0: */
-	VecSet(vector,0.0);
-
 	return vector;
 }
Index: /issm/trunk/src/m/Makefile.am
===================================================================
--- /issm/trunk/src/m/Makefile.am	(revision 17805)
+++ /issm/trunk/src/m/Makefile.am	(revision 17806)
@@ -13,4 +13,5 @@
 					./kml/*.m \
 					./enum/*.m \
+					./dev/issmversion.m \
 					./classes/*.m \
 					./classes/qmu/*.m \
@@ -60,8 +61,10 @@
 					./classes/clusters/*.py \
 					./consistency/*.py \
+					./dev/issmversion.py \
 					./boundaryconditions/*.py \
 					./exp/*.py \
 					./geometry/*.py \
 					./coordsystems/*.py \
+					./interp/*.py \
 					./mech/*.py \
 					./mesh/*.py \
Index: /issm/trunk/src/m/boundaryconditions/PattynSMB.m
===================================================================
--- /issm/trunk/src/m/boundaryconditions/PattynSMB.m	(revision 17806)
+++ /issm/trunk/src/m/boundaryconditions/PattynSMB.m	(revision 17806)
@@ -0,0 +1,51 @@
+function smb=PattynSMB(md,Tf)
+%PATTYNSMB- Compute SMB over Antarctica (from Pattyn 2006, pg. 18, "GRANTISM: An ExcelTM model for Greenland and 
+%           Antarctic ice-sheet response to climate changes")
+%
+%   Usage:
+%      md=PattynSMB(md,Tf)
+%
+%      where Tf is a background forcing temperature ("an anomalous temperature relative to the present conditions)
+%
+%
+%   See also: SETICESHELFBC, SETMARINEICESHEETBC
+
+ 
+% Tma    : Mean annual surface temperature in [deg C]
+% Tms    : Mean summer temperature in [deg C]
+% h      : Surface/bedrock elevation (I assume in meters but paper does not specify)
+% phi    : Latitude in degrees SOUTH
+% lambda : Longitude in degrees WEST
+% Tf     : Background forcing temperature ("an anomalous temperature relative to the present conditions)
+% ACCdot : Accumulation rate in units of [m/a] ice equivalent
+% ABLdot : Surface ablation rate in [m/a] ice equivalent
+
+	%Double check lat and long exist:
+	if isnan(md.mesh.lat),
+		error('PattynSMB error message: md.mesh.lat field required');
+	end
+
+	%Delta Temperature forcing 
+	if (nargin==1),
+		Tf=0; 
+	end
+
+	% Calculate mean annual surface temperature, Eqn (11)
+	% Here, -0.012 is the atmospheric Lapse rate from sea level in deg/m.
+	% It is multiplied by surface elevation from sea level
+	Tma = -15.15 - 0.012*md.geometry.surface;
+
+	%% Calculate summer temperature, Eqn (12)
+	%% No melting at PIG in mean conditions - need about 6 degress Tf to start having a negative yearly SMB
+	Tms = 16.81 - 0.00692*md.geometry.surface - 0.27937*abs(md.mesh.lat) + Tf;
+
+	%% Calculate Accumulation perturbation with Tf forcing, Eqn (9)
+	ACCdot = 2.5*2.^((Tma+Tf)/10.) - 2.5*2.^(Tma/10.);
+
+	%% Calculate Ablation, Eqn (10) (use for both Antarctica & Greenland), max melt is 10m/a
+	ABLdot=zeros(size(ACCdot));
+	pos=Tms>=0;
+	ABLdot(pos)=min(1.4*Tms(Tms>=0),10);
+
+	smb=ACCdot-ABLdot;
+end
Index: /issm/trunk/src/m/boundaryconditions/PattynSMB.py
===================================================================
--- /issm/trunk/src/m/boundaryconditions/PattynSMB.py	(revision 17806)
+++ /issm/trunk/src/m/boundaryconditions/PattynSMB.py	(revision 17806)
@@ -0,0 +1,50 @@
+import os
+import numpy as npy
+def PattynSMB(md,Tf):
+	"""
+    PATTYNSMB- Compute SMB over Antarctica (from Pattyn 2006, pg. 18, "GRANTISM: An ExcelTM model for Greenland 
+	and Antarctic ice-sheet response to climate changes")
+
+    Usage:
+      md=PattynSMB(md,Tf)
+
+      where Tf is a background forcing temperature ("an anomalous temperature relative to the present conditions)
+
+
+    See also: SETICESHELFBC, SETMARINEICESHEETBC
+	"""
+ 
+	# Tma    : Mean annual surface temperature in [deg C]
+	# Tms    : Mean summer temperature in [deg C]
+	# h      : Surface/bedrock elevation (I assume in meters but paper does not specify)
+	# phi    : Latitude in degrees SOUTH
+	# lambda : Longitude in degrees WEST
+	# Tf     : Background forcing temperature ("an anomalous temperature relative to the present conditions)
+	# ACCdot : Accumulation rate in units of [m/a] ice equivalent
+	# ABLdot : Surface ablation rate in [m/a] ice equivalent
+
+	#Double check lat and long exist:
+	if npy.any(npy.isnan(md.mesh.lat)): 
+		raise IOError('PattynSMB error message: md.mesh.lat field required')
+
+	# Calculate mean annual surface temperature, Eqn (11)
+	# Here, -0.012 is the atmospheric Lapse rate from sea level in deg/m.
+	# It is multiplied by surface elevation from sea level
+	Tma = -15.15 - 0.012*md.geometry.surface
+	
+
+	# Calculate summer temperature, Eqn (12)
+	# No melting at PIG in mean conditions - need about 6 degress Tf to start having a negative yearly SMB
+	Tms = 16.81 - 0.00692*md.geometry.surface - 0.27937*npy.abs(md.mesh.lat) + Tf
+	Tms= Tms[0]
+
+	# Calculate Accumulation perturbation with Tf forcing, Eqn (9)
+	ACCdot = 2.5*2**((Tma+Tf)/10.) - 2.5*2**(Tma/10.)
+
+	# Calculate Ablation, Eqn (10) (use for both Antarctica & Greenland), max melt is 10m/a
+	ABLdot=0.*npy.ones(md.mesh.numberofvertices)
+	pos=npy.nonzero(Tms>=0)
+	ABLdot[pos]=npy.minimum(1.4*Tms[pos],10)
+
+	smb=ACCdot-ABLdot
+	return smb[0]
Index: /issm/trunk/src/m/boundaryconditions/SetIceSheetBC.m
===================================================================
--- /issm/trunk/src/m/boundaryconditions/SetIceSheetBC.m	(revision 17805)
+++ /issm/trunk/src/m/boundaryconditions/SetIceSheetBC.m	(revision 17806)
@@ -29,22 +29,13 @@
 %No ice front: do nothing
 
-%Create zeros basal melting rate and surface mass balance if not specified
-if (isnan(md.surfaceforcings.precipitation) & (md.surfaceforcings.ispdd==1)),
-	md.surfaceforcings.precipitation=zeros(md.mesh.numberofvertices,1);
-	disp('      no surfaceforcings.precipitation specified: values set as zero');
-end
-if (isnan(md.surfaceforcings.mass_balance) & (md.surfaceforcings.ispdd==0)),
-	md.surfaceforcings.mass_balance=zeros(md.mesh.numberofvertices,1);
-	disp('      no surfaceforcings.mass_balance specified: values set as zero');
-end
-if isnan(md.basalforcings.melting_rate),
-	md.basalforcings.melting_rate=zeros(md.mesh.numberofvertices,1);
-	disp('      no basalforcings.melting_rate specified: values set as zero');
-end
+%Initialize surface and basal forcings
+md.surfaceforcings = initialize(md.surfaceforcings,md);
+md.basalforcings   = initialize(md.basalforcings,md);
+
+%Deal with other boundary conditions
 if isnan(md.balancethickness.thickening_rate),
 	md.balancethickness.thickening_rate=zeros(md.mesh.numberofvertices,1);
 	disp('      no balancethickness.thickening_rate specified: values set as zero');
 end
-
 md.masstransport.spcthickness=NaN*ones(md.mesh.numberofvertices,1);
 md.balancethickness.spcthickness=NaN*ones(md.mesh.numberofvertices,1);
Index: /issm/trunk/src/m/boundaryconditions/SetIceSheetBC.py
===================================================================
--- /issm/trunk/src/m/boundaryconditions/SetIceSheetBC.py	(revision 17805)
+++ /issm/trunk/src/m/boundaryconditions/SetIceSheetBC.py	(revision 17806)
@@ -1,5 +1,5 @@
 import os
 import numpy
-from ContourToMesh import *
+from ContourToMesh import ContourToMesh
 
 def SetIceSheetBC(md):
@@ -34,18 +34,12 @@
 	#No ice front -> do nothing
 
-	#Create zeros basal melting rate and surface mass balance if not specified
-	if numpy.all(numpy.isnan(md.surfaceforcings.precipitation)) and (md.surfaceforcings.ispdd==1):
-		md.surfaceforcings.precipitation=numpy.zeros((md.mesh.numberofvertices,1))
-		print "      no surfaceforcings.precipitation specified: values set as zero"
-	if numpy.all(numpy.isnan(md.surfaceforcings.mass_balance)) and (md.surfaceforcings.ispdd==0):
-		md.surfaceforcings.mass_balance=numpy.zeros((md.mesh.numberofvertices,1))
-		print "      no surfaceforcings.mass_balance specified: values set as zero"
-	if numpy.all(numpy.isnan(md.basalforcings.melting_rate)):
-		md.basalforcings.melting_rate=numpy.zeros((md.mesh.numberofvertices,1))
-		print "      no basalforcings.melting_rate specified: values set as zero"
+	#Create zeros basalforcings and surfaceforcings
+	md.surfaceforcings.initialize(md)
+	md.basalforcings.initialize(md)
+
+	#Deal with other boundary conditions
 	if numpy.all(numpy.isnan(md.balancethickness.thickening_rate)):
 		md.balancethickness.thickening_rate=numpy.zeros((md.mesh.numberofvertices,1))
 		print "      no balancethickness.thickening_rate specified: values set as zero"
-
 	md.masstransport.spcthickness=float('nan')*numpy.ones((md.mesh.numberofvertices,1))
 	md.balancethickness.spcthickness=float('nan')*numpy.ones((md.mesh.numberofvertices,1))
Index: /issm/trunk/src/m/boundaryconditions/SetIceShelfBC.m
===================================================================
--- /issm/trunk/src/m/boundaryconditions/SetIceShelfBC.m	(revision 17805)
+++ /issm/trunk/src/m/boundaryconditions/SetIceShelfBC.m	(revision 17806)
@@ -38,7 +38,7 @@
 
 %First find segments that are not completely on the front
-if strcmp(meshtype(md.mesh),'3D'),
+if strcmp(elementtype(md.mesh),'Penta'),
 	numbernodesfront=4;
-elseif strcmp(meshtype(md.mesh),'2Dhorizontal'),
+elseif strcmp(elementtype(md.mesh),'Tria'),
 	numbernodesfront=2;
 else
@@ -62,22 +62,13 @@
 end
 
-%Create zeros basalforcings and surfaceforcings
-if (isnan(md.surfaceforcings.precipitation) & (md.surfaceforcings.ispdd==1)),
-	md.surfaceforcings.precipitation=zeros(md.mesh.numberofvertices,1);
-	disp('      no surfaceforcings.precipitation specified: values set as zero');
-end
-if (isnan(md.surfaceforcings.mass_balance) & (md.surfaceforcings.ispdd==0)),
-	        md.surfaceforcings.mass_balance=zeros(md.mesh.numberofvertices,1);
-		disp('      no surfaceforcings.mass_balance specified: values set as zero');
-end
-if isnan(md.basalforcings.melting_rate),
-	md.basalforcings.melting_rate=zeros(md.mesh.numberofvertices,1);
-	disp('      no basalforcings.melting_rate specified: values set as zero');
-end
+%Initialize surface and basal forcings
+md.surfaceforcings = initialize(md.surfaceforcings,md);
+md.basalforcings   = initialize(md.basalforcings,md);
+
+%Deal with other boundary conditions
 if isnan(md.balancethickness.thickening_rate),
 	md.balancethickness.thickening_rate=zeros(md.mesh.numberofvertices,1);
 	disp('      no balancethickness.thickening_rate specified: values set as zero');
 end
-
 md.masstransport.spcthickness=NaN*ones(md.mesh.numberofvertices,1);
 md.balancethickness.spcthickness=NaN*ones(md.mesh.numberofvertices,1);
Index: /issm/trunk/src/m/boundaryconditions/SetIceShelfBC.py
===================================================================
--- /issm/trunk/src/m/boundaryconditions/SetIceShelfBC.py	(revision 17805)
+++ /issm/trunk/src/m/boundaryconditions/SetIceShelfBC.py	(revision 17806)
@@ -1,6 +1,6 @@
 import os
 import numpy
-from ContourToMesh import *
-from MatlabFuncs import *
+from ContourToMesh import ContourToMesh
+import MatlabFuncs as m
 
 def SetIceShelfBC(md,icefrontfile=''):
@@ -44,7 +44,7 @@
 
 	#First find segments that are not completely on the front
-	if strcmp(md.mesh.meshtype(),'3D'):
+	if m.strcmp(md.mesh.elementtype(),'Penta'):
 		numbernodesfront=4;
-	elif strcmp(md.mesh.meshtype(),'2Dhorizontal'):
+	elif m.strcmp(md.mesh.elementtype(),'Tria'):
 		numbernodesfront=2;
 	else:
@@ -77,17 +77,11 @@
 
 	#Create zeros basalforcings and surfaceforcings
-	if numpy.all(numpy.isnan(md.surfaceforcings.precipitation)) and (md.surfaceforcings.ispdd==1):
-		md.surfaceforcings.precipitation=numpy.zeros((md.mesh.numberofvertices,1))
-		print "      no surfaceforcings.precipitation specified: values set as zero"
-	if numpy.all(numpy.isnan(md.surfaceforcings.mass_balance)) and (md.surfaceforcings.ispdd==0):
-		md.surfaceforcings.mass_balance=numpy.zeros((md.mesh.numberofvertices,1))
-		print "      no surfaceforcings.mass_balance specified: values set as zero"
-	if numpy.all(numpy.isnan(md.basalforcings.melting_rate)):
-		md.basalforcings.melting_rate=numpy.zeros((md.mesh.numberofvertices,1))
-		print "      no basalforcings.melting_rate specified: values set as zero"
+	md.surfaceforcings.initialize(md)
+	md.basalforcings.initialize(md)
+
+	#Deal with other boundary conditions
 	if numpy.all(numpy.isnan(md.balancethickness.thickening_rate)):
 		md.balancethickness.thickening_rate=numpy.zeros((md.mesh.numberofvertices,1))
 		print "      no balancethickness.thickening_rate specified: values set as zero"
-
 	md.masstransport.spcthickness=float('nan')*numpy.ones((md.mesh.numberofvertices,1))
 	md.balancethickness.spcthickness=float('nan')*numpy.ones((md.mesh.numberofvertices,1))
Index: /issm/trunk/src/m/boundaryconditions/SetMarineIceSheetBC.m
===================================================================
--- /issm/trunk/src/m/boundaryconditions/SetMarineIceSheetBC.m	(revision 17805)
+++ /issm/trunk/src/m/boundaryconditions/SetMarineIceSheetBC.m	(revision 17806)
@@ -52,8 +52,10 @@
 
 %First find segments that are not completely on the front
-if(md.mesh.dimension==2),
+if strcmp(elementtype(md.mesh),'Penta'),
+	numbernodesfront=4;
+elseif strcmp(elementtype(md.mesh),'Tria'),
 	numbernodesfront=2;
-else 
-	numbernodesfront=4;
+else
+	error('mesh type not supported yet');
 end
 segmentsfront=md.mask.ice_levelset(md.mesh.segments(:,1:numbernodesfront))==0;
@@ -63,5 +65,5 @@
 md.stressbalance.spcvx(pos(:))=0;
 md.stressbalance.spcvy(pos(:))=0;
-md.stressbalance.spcvz(pos(:))=0;
+md.stressbalance.spcvz(pos(:))=0; % FIXME probably shouldn't spc vertical velocity here
 
 %Dirichlet Values
@@ -78,17 +80,9 @@
 md.hydrology.spcwatercolumn(pos,1)=1;
 
-%Create zeros basalforcings and surfaceforcings
-if (isnan(md.surfaceforcings.precipitation) & (md.surfaceforcings.ispdd==1)),
-	md.surfaceforcings.precipitation=zeros(md.mesh.numberofvertices,1);
-	disp('      no surfaceforcings.precipitation specified: values set as zero');
-end
-if (isnan(md.surfaceforcings.mass_balance) & (md.surfaceforcings.ispdd==0)),
-	md.surfaceforcings.mass_balance=zeros(md.mesh.numberofvertices,1);
-	disp('      no surfaceforcings.mass_balance specified: values set as zero');
-end
-if isnan(md.basalforcings.melting_rate),
-	md.basalforcings.melting_rate=zeros(md.mesh.numberofvertices,1);
-	disp('      no basalforcings.melting_rate specified: values set as zero');
-end
+%Initialize surface and basal forcings
+md.surfaceforcings = initialize(md.surfaceforcings,md);
+md.basalforcings   = initialize(md.basalforcings,md);
+
+%Deal with other boundary conditions
 if isnan(md.balancethickness.thickening_rate),
 	md.balancethickness.thickening_rate=zeros(md.mesh.numberofvertices,1);
Index: /issm/trunk/src/m/boundaryconditions/SetMarineIceSheetBC.py
===================================================================
--- /issm/trunk/src/m/boundaryconditions/SetMarineIceSheetBC.py	(revision 17805)
+++ /issm/trunk/src/m/boundaryconditions/SetMarineIceSheetBC.py	(revision 17806)
@@ -1,5 +1,6 @@
 import os
 import numpy
-from ContourToMesh import *
+from ContourToMesh import ContourToMesh
+import MatlabFuncs as m
 
 def SetMarineIceSheetBC(md,icefrontfile=''):
@@ -52,8 +53,10 @@
 
 	#First find segments that are not completely on the front
-	if md.mesh.dimension==2:
+	if m.strcmp(md.mesh.elementtype(),'Penta'):
+		numbernodesfront=4
+	elif m.strcmp(md.mesh.elementtype(),'Tria'):
 		numbernodesfront=2
 	else:
-		numbernodesfront=4
+			raise StandardError("Mesh type not supported")
 	if any(md.mask.ice_levelset<=0):
 		values=md.mask.ice_levelset[md.mesh.segments[:,0:-1]-1]
@@ -82,13 +85,8 @@
 
 	#Create zeros basalforcings and surfaceforcings
-	if numpy.all(numpy.isnan(md.surfaceforcings.precipitation)) and (md.surfaceforcings.ispdd==1):
-		md.surfaceforcings.precipitation=numpy.zeros((md.mesh.numberofvertices,1))
-		print "      no surfaceforcings.precipitation specified: values set as zero"
-	if numpy.all(numpy.isnan(md.surfaceforcings.mass_balance)) and (md.surfaceforcings.ispdd==0):
-		md.surfaceforcings.mass_balance=numpy.zeros((md.mesh.numberofvertices,1))
-		print "      no surfaceforcings.mass_balance specified: values set as zero"
-	if numpy.all(numpy.isnan(md.basalforcings.melting_rate)):
-		md.basalforcings.melting_rate=numpy.zeros((md.mesh.numberofvertices,1))
-		print "      no basalforcings.melting_rate specified: values set as zero"
+	md.surfaceforcings.initialize(md)
+	md.basalforcings.initialize(md)
+
+	#Deal with other boundary conditions
 	if numpy.all(numpy.isnan(md.balancethickness.thickening_rate)):
 		md.balancethickness.thickening_rate=numpy.zeros((md.mesh.numberofvertices,1))
Index: /issm/trunk/src/m/classes/SMB.m
===================================================================
--- /issm/trunk/src/m/classes/SMB.m	(revision 17806)
+++ /issm/trunk/src/m/classes/SMB.m	(revision 17806)
@@ -0,0 +1,58 @@
+%SMB Class definition
+%
+%   Usage:
+%      SMB=SMB();
+
+classdef SMB
+	properties (SetAccess=public) 
+		mass_balance = NaN;
+	end
+	methods
+        function createxml(obj,fid) % {{{
+            fprintf(fid, '\n\n');
+            fprintf(fid, '%s\n', '<!-- surfaceforcings(SMB) -->');
+			 fprintf(fid,'%s%s%s%s%s\n%s\n%s\n','<parameter key ="mass_balance" type="',class(obj.mass_balance),'" default="',obj.mass_balance,'">','     <section name="surfaceforcings(SMB)" />','     <help> surface mass balance [m/yr ice eq] </help>','</parameter>');
+           
+        end % }}}
+		function obj = SMB(varargin) % {{{
+			switch nargin
+				case 0
+				otherwise
+					error('constructor not supported');
+			end
+		end % }}}
+		function self = extrude(self,md) % {{{
+
+			self.mass_balance=project3d(md,'vector',self.mass_balance,'type','node');
+
+		end % }}}
+		function self = initialize(self,md) % {{{
+
+			if isnan(self.mass_balance)
+				self.mass_balance=zeros(md.mesh.numberofvertices,1);
+				disp('      no surfaceforcings.mass_balance specified: values set as zero');
+			end
+
+		end % }}}
+		function md = checkconsistency(obj,md,solution,analyses) % {{{
+
+			if ismember(MasstransportAnalysisEnum(),analyses),
+				md = checkfield(md,'fieldname','surfaceforcings.mass_balance','forcing',1,'NaN',1);
+			end
+			if ismember(BalancethicknessAnalysisEnum(),analyses),
+				md = checkfield(md,'fieldname','surfaceforcings.mass_balance','size',[md.mesh.numberofvertices 1],'NaN',1);
+			end
+		end % }}}
+		function disp(obj) % {{{
+			disp(sprintf('   surface forcings parameters:'));
+			fielddisplay(obj,'mass_balance','surface mass balance [m/yr ice eq]');
+		end % }}}
+		function marshall(obj,md,fid) % {{{
+
+			yts=365.0*24.0*3600.0;
+
+			WriteData(fid,'enum',SurfaceforcingsEnum(),'data',SMBEnum(),'format','Integer');
+			WriteData(fid,'object',obj,'class','surfaceforcings','fieldname','mass_balance','format','DoubleMat','mattype',1,'scale',1./yts,'forcinglength',md.mesh.numberofvertices+1);
+		end % }}}
+	end
+end
Index: /issm/trunk/src/m/classes/SMB.py
===================================================================
--- /issm/trunk/src/m/classes/SMB.py	(revision 17806)
+++ /issm/trunk/src/m/classes/SMB.py	(revision 17806)
@@ -0,0 +1,53 @@
+import numpy
+from fielddisplay import fielddisplay
+from EnumDefinitions import *
+from checkfield import checkfield
+from WriteData import WriteData
+from project3d import project3d
+
+class SMB(object):
+	"""
+	SMB Class definition
+
+	   Usage:
+	      SMB=SMB();
+	"""
+
+	def __init__(self): # {{{
+		self.mass_balance = float('NaN')
+		#}}}
+	def __repr__(self): # {{{
+		string="   surface forcings parameters:"
+		string="%s\n%s"%(string,fielddisplay(self,'mass_balance','surface mass balance [m/yr ice eq]'))
+		return string
+		#}}}
+	def extrude(self,md): # {{{
+
+		self.mass_balance=project3d(md,'vector',self.mass_balance,'type','node');
+		return self
+	#}}}
+	def initialize(self,md): # {{{
+
+		if numpy.all(numpy.isnan(self.mass_balance)):
+			self.mass_balance=numpy.zeros((md.mesh.numberofvertices,1))
+			print "      no SMB.mass_balance specified: values set as zero"
+
+		return self
+	#}}}
+	def checkconsistency(self,md,solution,analyses):    # {{{
+
+		if MasstransportAnalysisEnum() in analyses:
+			md = checkfield(md,'fieldname','surfaceforcings.mass_balance','forcing',1,'NaN',1)
+
+		if BalancethicknessAnalysisEnum() in analyses:
+			md = checkfield(md,'fieldname','surfaceforcings.mass_balance','size',[md.mesh.numberofvertices],'NaN',1)
+
+		return md
+	# }}}
+	def marshall(self,md,fid):    # {{{
+
+		yts=365.0*24.0*3600.0
+
+		WriteData(fid,'enum',SurfaceforcingsEnum(),'data',SMBEnum(),'format','Integer');
+		WriteData(fid,'object',self,'class','surfaceforcings','fieldname','mass_balance','format','DoubleMat','mattype',1,'scale',1./yts,'forcinglength',md.mesh.numberofvertices+1)
+	# }}}
Index: /issm/trunk/src/m/classes/SMBgradients.m
===================================================================
--- /issm/trunk/src/m/classes/SMBgradients.m	(revision 17806)
+++ /issm/trunk/src/m/classes/SMBgradients.m	(revision 17806)
@@ -0,0 +1,68 @@
+%SMBgradients Class definition
+%
+%   Usage:
+%      SMBgradients=SMBgradients();
+
+classdef SMBgradients
+	properties (SetAccess=public) 
+		href   = NaN;
+		smbref = NaN;
+		b_pos  = NaN;
+		b_neg  = NaN;
+	end
+	methods
+		function obj = SMBgradients(varargin) % {{{
+			switch nargin
+				case 0
+					obj=setdefaultparameters(obj);
+				otherwise
+					error('constructor not supported');
+			end
+		end % }}}
+		function self = extrude(self,md) % {{{
+
+			%Nothing for now
+
+		end % }}}
+		function self = initialize(self,md) % {{{
+
+			%Nothing done for now
+
+		end % }}}
+		function obj = setdefaultparameters(obj) % {{{
+
+			%Nothing for now
+
+		end % }}}
+		function md = checkconsistency(obj,md,solution,analyses) % {{{
+
+			if ismember(MasstransportAnalysisEnum(),analyses),
+				md = checkfield(md,'fieldname','surfaceforcings.href','forcing',1,'NaN',1);
+				md = checkfield(md,'fieldname','surfaceforcings.smbref','forcing',1,'NaN',1);
+				md = checkfield(md,'fieldname','surfaceforcings.b_pos','forcing',1,'NaN',1);
+				md = checkfield(md,'fieldname','surfaceforcings.b_neg','forcing',1,'NaN',1);
+			end
+		end % }}}
+		function disp(obj) % {{{
+			disp(sprintf('   surface forcings parameters:'));
+
+			disp(sprintf('\n   SMB gradients parameters:'));
+			fielddisplay(obj,'href',' reference elevation from which deviation is used to calculate SMB adjustment in smb gradients method');
+			fielddisplay(obj,'smbref',' reference smb from which deviation is calculated in smb gradients method');
+			fielddisplay(obj,'b_pos',' slope of hs - smb regression line for accumulation regime required if smb gradients is activated');
+			fielddisplay(obj,'b_neg',' slope of hs - smb regression line for ablation regime required if smb gradients is activated');
+
+		end % }}}
+		function marshall(obj,md,fid) % {{{
+
+			yts=365.0*24.0*3600.0;
+
+			WriteData(fid,'enum',SurfaceforcingsEnum(),'data',SMBgradientsEnum(),'format','Integer');
+			WriteData(fid,'object',obj,'class','surfaceforcings','fieldname','href','format','DoubleMat','mattype',1,'forcinglength',md.mesh.numberofvertices+1);
+			WriteData(fid,'object',obj,'class','surfaceforcings','fieldname','smbref','format','DoubleMat','mattype',1,'scale',1./yts,'forcinglength',md.mesh.numberofvertices+1);
+			WriteData(fid,'object',obj,'class','surfaceforcings','fieldname','b_pos','format','DoubleMat','mattype',1,'scale',1./yts,'forcinglength',md.mesh.numberofvertices+1);
+			WriteData(fid,'object',obj,'class','surfaceforcings','fieldname','b_neg','format','DoubleMat','mattype',1,'scale',1./yts,'forcinglength',md.mesh.numberofvertices+1);
+
+		end % }}}
+	end
+end
Index: /issm/trunk/src/m/classes/SMBgradients.py
===================================================================
--- /issm/trunk/src/m/classes/SMBgradients.py	(revision 17806)
+++ /issm/trunk/src/m/classes/SMBgradients.py	(revision 17806)
@@ -0,0 +1,62 @@
+from fielddisplay import fielddisplay
+from EnumDefinitions import *
+from checkfield import checkfield
+from WriteData import WriteData
+from project3d import project3d
+
+class SMBgradients(object):
+	"""
+	SMBgradients Class definition
+
+	   Usage:
+	      SMBgradients=SMBgradients();
+	"""
+
+	def __init__(self): # {{{
+		self.href    = float('NaN')
+		self.smbref  = float('NaN')
+		self.b_pos   = float('NaN')
+		self.b_neg   = float('NaN')
+		#}}}
+	def __repr__(self): # {{{
+		string="   surface forcings parameters:"
+
+		string="%s\n%s"%(string,fielddisplay(self,'issmbgradients','is smb gradients method activated (0 or 1, default is 0)'))
+		string="%s\n%s"%(string,fielddisplay(self,'href',' reference elevation from which deviation is used to calculate SMB adjustment in smb gradients method'))
+		string="%s\n%s"%(string,fielddisplay(self,'smbref',' reference smb from which deviation is calculated in smb gradients method'))
+		string="%s\n%s"%(string,fielddisplay(self,'b_pos',' slope of hs - smb regression line for accumulation regime required if smb gradients is activated'))
+		string="%s\n%s"%(string,fielddisplay(self,'b_neg',' slope of hs - smb regression line for ablation regime required if smb gradients is activated'))
+
+		return string
+		#}}}
+	def extrude(self,md): # {{{
+
+		#Nothing for now
+		return self
+	#}}}
+	def initialize(self,md): # {{{
+
+		#Nothing for now
+
+		return self
+	#}}}
+	def checkconsistency(self,md,solution,analyses):    # {{{
+
+		if MasstransportAnalysisEnum() in analyses:
+			md = checkfield(md,'fieldname','surfaceforcings.href','forcing',1,'NaN',1)
+			md = checkfield(md,'fieldname','surfaceforcings.smbref','forcing',1,'NaN',1)
+			md = checkfield(md,'fieldname','surfaceforcings.b_pos','forcing',1,'NaN',1)
+			md = checkfield(md,'fieldname','surfaceforcings.b_neg','forcing',1,'NaN',1)
+
+		return md
+	# }}}
+	def marshall(self,md,fid):    # {{{
+
+		yts=365.0*24.0*3600.0
+
+		WriteData(fid,'enum',SurfaceforcingsEnum(),'data',SMBgradientsEnum(),'format','Integer');
+		WriteData(fid,'object',self,'class','surfaceforcings','fieldname','href','format','DoubleMat','mattype',1,'forcinglength',md.mesh.numberofvertices+1)
+		WriteData(fid,'object',self,'class','surfaceforcings','fieldname','smbref','format','DoubleMat','mattype',1,'scale',1./yts,'forcinglength',md.mesh.numberofvertices+1)
+		WriteData(fid,'object',self,'class','surfaceforcings','fieldname','b_pos','format','DoubleMat','mattype',1,'scale',1./yts,'forcinglength',md.mesh.numberofvertices+1)
+		WriteData(fid,'object',self,'class','surfaceforcings','fieldname','b_neg','format','DoubleMat','mattype',1,'scale',1./yts,'forcinglength',md.mesh.numberofvertices+1)
+	# }}}
Index: /issm/trunk/src/m/classes/SMBhenning.m
===================================================================
--- /issm/trunk/src/m/classes/SMBhenning.m	(revision 17806)
+++ /issm/trunk/src/m/classes/SMBhenning.m	(revision 17806)
@@ -0,0 +1,52 @@
+%SMBhenning Class definition
+%
+%   Usage:
+%      SMBhenning=SMBhenning();
+
+classdef SMBhenning
+	properties (SetAccess=public) 
+		smbref = NaN;
+	end
+	methods
+		function obj = SMBhenning(varargin) % {{{
+			switch nargin
+				case 0
+				otherwise
+					error('constructor not supported');
+			end
+		end % }}}
+		function self = extrude(self,md) % {{{
+
+			self.smbref=project3d(md,'vector',self.smbref,'type','node');
+
+		end % }}}
+		function self = initialize(self,md) % {{{
+
+			if isnan(self.smbref)
+				self.smbref=zeros(md.mesh.numberofvertices,1);
+				disp('      no surfaceforcings.smbref specified: values set as zero');
+			end
+
+		end % }}}
+		function md = checkconsistency(obj,md,solution,analyses) % {{{
+
+			if ismember(MasstransportAnalysisEnum(),analyses),
+				md = checkfield(md,'fieldname','surfaceforcings.smbref','forcing',1,'NaN',1);
+			end
+			if ismember(BalancethicknessAnalysisEnum(),analyses),
+				md = checkfield(md,'fieldname','surfaceforcings.smbref','size',[md.mesh.numberofvertices 1],'NaN',1);
+			end
+		end % }}}
+		function disp(obj) % {{{
+			disp(sprintf('   surface forcings parameters:'));
+			fielddisplay(obj,'smbref','reference smb from which deviation is calculated [m/yr ice eq]');
+		end % }}}
+		function marshall(obj,md,fid) % {{{
+
+			yts=365.0*24.0*3600.0;
+
+			WriteData(fid,'enum',SurfaceforcingsEnum(),'data',SMBhenningEnum(),'format','Integer');
+			WriteData(fid,'object',obj,'class','surfaceforcings','fieldname','smbref','format','DoubleMat','mattype',1,'scale',1./yts,'forcinglength',md.mesh.numberofvertices+1);
+		end % }}}
+	end
+end
Index: /issm/trunk/src/m/classes/SMBpdd.m
===================================================================
--- /issm/trunk/src/m/classes/SMBpdd.m	(revision 17806)
+++ /issm/trunk/src/m/classes/SMBpdd.m	(revision 17806)
@@ -0,0 +1,106 @@
+%SMBpdd Class definition
+%
+%   Usage:
+%      SMBpdd=SMBpdd();
+
+classdef SMBpdd
+	properties (SetAccess=public) 
+		precipitation             = NaN;
+		monthlytemperatures       = NaN;
+		desfac                    = 0.5;
+		s0p                       = 0;
+		isdelta18o                = 0;
+		delta18o                  = NaN;
+		delta18o_surface          = NaN;
+		temperatures_presentday   = NaN;
+		temperatures_lgm          = NaN;
+		precipitations_presentday = NaN;
+	end
+	methods
+		function obj = SMBpdd(varargin) % {{{
+			switch nargin
+				case 0
+					obj=setdefaultparameters(obj);
+				otherwise
+					error('constructor not supported');
+			end
+		end % }}}
+		function self = extrude(self,md) % {{{
+
+			self.precipitation=project3d(md,'vector',self.precipitation,'type','node');
+			self.monthlytemperatures=project3d(md,'vector',self.monthlytemperatures,'type','node');
+			if(self.isdelta18o),self.temperatures_lgm=project3d(md,'vector',self.temperatures_lgm,'type','node');end
+			if(self.isdelta18o),self.temperatures_presentday=project3d(md,'vector',self.temperatures_presentday,'type','node');end
+			if(self.isdelta18o),self.precipitations_presentday=project3d(md,'vector',self.precipitations_presentday,'type','node');end
+
+
+		end % }}}
+		function self = initialize(self,md) % {{{
+
+			if isnan(self.precipitation),
+				self.precipitation=zeros(md.mesh.numberofvertices,1);
+				disp('      no SMBpdd.precipitation specified: values set as zero');
+			end
+
+		end % }}}
+		function obj = setdefaultparameters(obj) % {{{
+
+		  obj.isdelta18o = 0;
+		  obj.desfac     = 0.5;
+		  obj.s0p        = 0;
+		end % }}}
+		function md = checkconsistency(obj,md,solution,analyses) % {{{
+
+			if ismember(MasstransportAnalysisEnum(),analyses),
+				md = checkfield(md,'fieldname','surfaceforcings.desfac','<=',1,'numel',1);
+				md = checkfield(md,'fieldname','surfaceforcings.s0p','>=',0,'numel',1);
+				if(obj.isdelta18o==0)
+					md = checkfield(md,'fieldname','surfaceforcings.monthlytemperatures','forcing',1,'NaN',1);
+					md = checkfield(md,'fieldname','surfaceforcings.precipitation','forcing',1,'NaN',1);
+				else
+					md = checkfield(md,'fieldname','surfaceforcings.delta18o','NaN',1);
+					md = checkfield(md,'fieldname','surfaceforcings.delta18o_surface','NaN',1);
+					md = checkfield(md,'fieldname','surfaceforcings.temperatures_presentday','size',[md.mesh.numberofvertices+1 12],'NaN',1);
+					md = checkfield(md,'fieldname','surfaceforcings.temperatures_lgm','size',[md.mesh.numberofvertices+1 12],'NaN',1);
+					md = checkfield(md,'fieldname','surfaceforcings.precipitations_presentday','size',[md.mesh.numberofvertices+1 12],'NaN',1);
+				end
+			end
+		end % }}}
+		function disp(obj) % {{{
+			disp(sprintf('   surface forcings parameters:'));
+
+			disp(sprintf('\n   PDD and deltaO18 parameters:'));
+			fielddisplay(obj,'isdelta18o','is temperature and precipitation delta18o parametrisation activated (0 or 1, default is 0)');
+			fielddisplay(obj,'desfac','desertification elevation factor (between 0 and 1, default is 0.5) [m]');
+			fielddisplay(obj,'s0p','should be set to elevation from precip source (between 0 and a few 1000s m, default is 0) [m]');
+			fielddisplay(obj,'monthlytemperatures','monthly surface temperatures [K], required if pdd is activated and delta18o not activated');
+			fielddisplay(obj,'precipitation','surface precipitation [m/yr water eq]');
+			fielddisplay(obj,'temperatures_presentday','monthly present day surface temperatures [K], required if pdd is activated and delta18o activated');
+			fielddisplay(obj,'temperatures_lgm','monthly LGM surface temperatures [K], required if pdd is activated and delta18o activated');
+			fielddisplay(obj,'precipitations_presentday','monthly surface precipitation [m/yr water eq], required if pdd is activated and delta18o activated');
+			fielddisplay(obj,'delta18o','delta18o, required if pdd is activated and delta18o activated');
+			fielddisplay(obj,'delta18o_surface','surface elevation of the delta18o site, required if pdd is activated and delta18o activated');
+
+		end % }}}
+		function marshall(obj,md,fid) % {{{
+
+			yts=365.0*24.0*3600.0;
+
+			WriteData(fid,'enum',SurfaceforcingsEnum(),'data',SMBpddEnum(),'format','Integer');
+
+			WriteData(fid,'object',obj,'class','surfaceforcings','fieldname','precipitation','format','DoubleMat','mattype',1,'scale',1./yts,'forcinglength',md.mesh.numberofvertices+1);
+			WriteData(fid,'object',obj,'class','surfaceforcings','fieldname','desfac','format','Double');
+			WriteData(fid,'object',obj,'class','surfaceforcings','fieldname','s0p','format','Double');
+			WriteData(fid,'object',obj,'class','surfaceforcings','fieldname','isdelta18o','format','Boolean');
+			if obj.isdelta18o
+				WriteData(fid,'object',obj,'class','surfaceforcings','fieldname','temperatures_presentday','format','DoubleMat','mattype',1);
+				WriteData(fid,'object',obj,'class','surfaceforcings','fieldname','temperatures_lgm','format','DoubleMat','mattype',1);
+				WriteData(fid,'object',obj,'class','surfaceforcings','fieldname','precipitations_presentday','format','DoubleMat','mattype',1);
+				WriteData(fid,'object',obj,'class','surfaceforcings','fieldname','delta18o_surface','format','DoubleMat','mattype',1);
+				WriteData(fid,'object',obj,'class','surfaceforcings','fieldname','delta18o','format','DoubleMat','mattype',1);
+			else
+				WriteData(fid,'object',obj,'class','surfaceforcings','fieldname','monthlytemperatures','format','DoubleMat','mattype',1,'forcinglength',md.mesh.numberofvertices+1);
+			end
+		end % }}}
+	end
+end
Index: /issm/trunk/src/m/classes/SMBpdd.py
===================================================================
--- /issm/trunk/src/m/classes/SMBpdd.py	(revision 17806)
+++ /issm/trunk/src/m/classes/SMBpdd.py	(revision 17806)
@@ -0,0 +1,108 @@
+import numpy
+from fielddisplay import fielddisplay
+from EnumDefinitions import *
+from checkfield import checkfield
+from WriteData import WriteData
+from project3d import project3d
+
+class SMBpdd(object):
+	"""
+	SMBpdd Class definition
+
+	   Usage:
+	      SMBpdd=SMBpdd();
+	"""
+
+	def __init__(self): # {{{
+		self.precipitation             = float('NaN')
+		self.monthlytemperatures       = float('NaN')
+		self.desfac                    = 0.
+		self.s0p                       = 0.
+		self.isdelta18o                = 0
+		self.delta18o                  = float('NaN')
+		self.delta18o_surface          = float('NaN')
+		self.temperatures_presentday   = float('NaN')
+		self.temperatures_lgm          = float('NaN')
+		self.precipitations_presentday = float('NaN')
+
+		#set defaults
+		self.setdefaultparameters()
+		#}}}
+	def __repr__(self): # {{{
+		string="   surface forcings parameters:"
+
+		string="%s\n%s"%(string,fielddisplay(self,'precipitation','surface precipitation [m/yr water eq]'))
+		string="%s\n%s"%(string,fielddisplay(self,'desfac','desertification elevation factor (between 0 and 1, default is 0.5) [m]'))
+		string="%s\n%s"%(string,fielddisplay(self,'isdelta18o','is temperature and precipitation delta18o parametrisation activated (0 or 1, default is 0)'))
+		string="%s\n%s"%(string,fielddisplay(self,'s0p','should be set to elevation from precip source (between 0 and a few 1000s m, default is 0) [m]'))
+		string="%s\n%s"%(string,fielddisplay(self,'monthlytemperatures','monthly surface temperatures [K], required if pdd is activated and delta18o not activated'))
+		string="%s\n%s"%(string,fielddisplay(self,'temperatures_presentday','monthly present day surface temperatures [K], required if pdd is activated and delta18o activated'))
+		string="%s\n%s"%(string,fielddisplay(self,'temperatures_lgm','monthly LGM surface temperatures [K], required if pdd is activated and delta18o activated'))
+		string="%s\n%s"%(string,fielddisplay(self,'precipitations_presentday','monthly surface precipitation [m/yr water eq], required if pdd is activated and delta18o activated'))
+		string="%s\n%s"%(string,fielddisplay(self,'delta18o','delta18o, required if pdd is activated and delta18o activated'))
+		string="%s\n%s"%(string,fielddisplay(self,'delta18o_surface','surface elevation of the delta18o site, required if pdd is activated and delta18o activated'))
+
+		return string
+		#}}}
+	def extrude(self,md): # {{{
+
+		self.precipitation=project3d(md,'vector',self.precipitation,'type','node');
+		self.monthlytemperatures=project3d(md,'vector',self.monthlytemperatures,'type','node');
+		if self.isdelta18o: self.temperatures_lgm=project3d(md,'vector',self.temperatures_lgm,'type','node')
+		if self.isdelta18o: self.temperatures_presentday=project3d(md,'vector',self.temperatures_presentday,'type','node')
+		if self.isdelta18o: self.precipitations_presentday=project3d(md,'vector',self.precipitations_presentday,'type','node')
+		return self
+	#}}}
+	def initialize(self,md): # {{{
+
+		if numpy.all(numpy.isnan(self.precipitation)):
+			self.precipitation=numpy.zeros((md.mesh.numberofvertices,1))
+			print "      no SMBpdd.precipitation specified: values set as zero"
+
+		return self
+	#}}}
+	def setdefaultparameters(self): # {{{
+		  
+		#pdd method not used in default mode
+		self.isdelta18o = 0
+		self.desfac     = 0.5
+		self.s0p        = 0.
+
+		return self
+	#}}}
+	def checkconsistency(self,md,solution,analyses):    # {{{
+
+		if MasstransportAnalysisEnum() in analyses:
+			md = checkfield(md,'fieldname','surfaceforcings.desfac','<=',1,'numel',[1]);
+			md = checkfield(md,'fieldname','surfaceforcings.s0p','>=',0,'numel',[1]);
+			if not self.isdelta18o:
+				md = checkfield(md,'fieldname','surfaceforcings.monthlytemperatures','forcing',1,'NaN',1)
+				md = checkfield(md,'fieldname','surfaceforcings.precipitation','forcing',1,'NaN',1)
+			else:
+				md = checkfield(md,'fieldname','surfaceforcings.delta18o','NaN',1)
+				md = checkfield(md,'fieldname','surfaceforcings.delta18o_surface','NaN',1)
+				md = checkfield(md,'fieldname','surfaceforcings.temperatures_presentday','size',[md.mesh.numberofvertices+1,12],'NaN',1)
+				md = checkfield(md,'fieldname','surfaceforcings.temperatures_lgm','size',[md.mesh.numberofvertices+1,12],'NaN',1)
+				md = checkfield(md,'fieldname','surfaceforcings.precipitations_presentday','size',[md.mesh.numberofvertices+1,12],'NaN',1)
+
+		return md
+	# }}}
+	def marshall(self,md,fid):    # {{{
+
+		yts=365.0*24.0*3600.0
+
+		WriteData(fid,'enum',SurfaceforcingsEnum(),'data',SMBpddEnum(),'format','Integer');
+
+		WriteData(fid,'object',self,'class','surfaceforcings','fieldname','precipitation','format','DoubleMat','mattype',1,'scale',1./yts,'forcinglength',md.mesh.numberofvertices+1)
+		WriteData(fid,'object',self,'class','surfaceforcings','fieldname','isdelta18o','format','Boolean')
+		WriteData(fid,'object',self,'class','surfaceforcings','fieldname','desfac','format','Double');
+		WriteData(fid,'object',self,'class','surfaceforcings','fieldname','s0p','format','Double');
+		if self.isdelta18o:
+			WriteData(fid,'object',self,'class','surfaceforcings','fieldname','temperatures_presentday','format','DoubleMat','mattype',1)
+			WriteData(fid,'object',self,'class','surfaceforcings','fieldname','temperatures_lgm','format','DoubleMat','mattype',1)
+			WriteData(fid,'object',self,'class','surfaceforcings','fieldname','precipitations_presentday','format','DoubleMat','mattype',1)
+			WriteData(fid,'object',self,'class','surfaceforcings','fieldname','delta18o_surface','format','DoubleMat','mattype',1)
+			WriteData(fid,'object',self,'class','surfaceforcings','fieldname','delta18o','format','DoubleMat','mattype',1)
+		else:
+			WriteData(fid,'object',self,'class','surfaceforcings','fieldname','monthlytemperatures','format','DoubleMat','mattype',1,'forcinglength',md.mesh.numberofvertices+1)
+	# }}}
Index: /issm/trunk/src/m/classes/autodiff.m
===================================================================
--- /issm/trunk/src/m/classes/autodiff.m	(revision 17805)
+++ /issm/trunk/src/m/classes/autodiff.m	(revision 17806)
@@ -20,4 +20,24 @@
 		%}}}
 	methods
+     	function createxml(obj,fid) % {{{
+            fprintf(fid, '<!-- autodiff -->\n');            
+                    
+            % automatic differentiation parameters 
+            fprintf(fid,'%s\n%s\n%s\n','<frame key="1" label="automatic differentiation parameters">','<section name="autodiff" />');                    
+                fprintf(fid,'%s%s%s\n%s\n%s%s%s\n%s\n%s\n','  <parameter key ="isautodiff" type="',class(obj.isautodiff),'" optional="false">','     <section name="autodiff" />','         <option value="',convert2str(obj.isautodiff),'" type="string" default="true"></option>','     <help> indicates if the automatic differentiation is activated </help>','  </parameter>');
+             
+                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="dependents" type="',class(obj.dependents),'" default="',convert2str(obj.dependents),'">','     <section name="autodiff" />','     <help> list of dependent variables </help>','  </parameter>');
+                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="independents" type="',class(obj.independents),'" default="',convert2str(obj.independents),'">','     <section name="autodiff" />','     <help> list of independent variables </help>','  </parameter>');
+                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="driver" type="',class(obj.driver),'" default="',convert2str(obj.driver),'">','     <section name="autodiff" />','     <help> ADOLC driver (''fos_forward'' or ''fov_forward'') </help>','  </parameter>');
+                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="obufsize" type="',class(obj.obufsize),'" default="',convert2str(obj.obufsize),'">','     <section name="autodiff" />','     <help> Number of operations per buffer (==OBUFSIZE in usrparms.h)  </help>','  </parameter>');
+                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="lbufsize" type="',class(obj.lbufsize),'" default="',convert2str(obj.lbufsize),'">','     <section name="autodiff" />','     <help> Number of locations per buffer (==LBUFSIZE in usrparms.h) </help>','  </parameter>');
+                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="cbufsize" type="',class(obj.cbufsize),'" default="',convert2str(obj.cbufsize),'">','     <section name="autodiff" />','     <help> Number of values per buffer (==CBUFSIZE in usrparms.h) </help>','  </parameter>');
+                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="tbufsize" type="',class(obj.tbufsize),'" default="',convert2str(obj.tbufsize),'">','     <section name="autodiff" />','     <help> Number of taylors per buffer (&amp;lt;=TBUFSIZE in usrparms.h) </help>','  </parameter>');
+                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="gcTriggerRatio" type="',class(obj.gcTriggerRatio),'" default="',convert2str(obj.gcTriggerRatio),'">','     <section name="autodiff" />','     <help> free location block sorting/consolidation triggered if the ratio between allocated and used locations exceeds gcTriggerRatio </help>','  </parameter>');
+                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="gcTriggerRatio" type="',class(obj.gcTriggerRatio),'" default="',convert2str(obj.gcTriggerRatio),'">','     <section name="autodiff" />','     <help> free location block sorting/consolidation triggered if the allocated locations exceed gcTriggerMaxSize </help>','  </parameter>');
+            
+            fprintf(fid,'%s\n%s\n','</frame>');    
+        
+        end % }}}
 		function obj = autodiff(varargin) % {{{
 			switch nargin
@@ -42,13 +62,13 @@
 
 			%Driver value:
-			md = checkfield(md,'autodiff.driver','values',{'fos_forward','fov_forward','fov_forward_all','fos_reverse','fov_reverse','fov_reverse_all'});
+			md = checkfield(md,'fieldname','autodiff.driver','values',{'fos_forward','fov_forward','fov_forward_all','fos_reverse','fov_reverse','fov_reverse_all'});
 			
 			%buffer values: 
-			md = checkfield(md,'autodiff.obufsize','>=',16);
-			md = checkfield(md,'autodiff.lbufsize','>=',16);
-			md = checkfield(md,'autodiff.cbufsize','>=',16);
-			md = checkfield(md,'autodiff.tbufsize','>=',16);
-			md = checkfield(md,'autodiff.gcTriggerRatio','>=',0);
-			md = checkfield(md,'autodiff.gcTriggerMaxSize','>=',65536);
+			md = checkfield(md,'fieldname','autodiff.obufsize','>=',16);
+			md = checkfield(md,'fieldname','autodiff.lbufsize','>=',16);
+			md = checkfield(md,'fieldname','autodiff.cbufsize','>=',16);
+			md = checkfield(md,'fieldname','autodiff.tbufsize','>=',16);
+			md = checkfield(md,'fieldname','autodiff.gcTriggerRatio','>=',0);
+			md = checkfield(md,'fieldname','autodiff.gcTriggerMaxSize','>=',65536);
 
 			%go through our dependents and independents and check consistency: 
Index: /issm/trunk/src/m/classes/autodiff.py
===================================================================
--- /issm/trunk/src/m/classes/autodiff.py	(revision 17805)
+++ /issm/trunk/src/m/classes/autodiff.py	(revision 17806)
@@ -1,9 +1,9 @@
 import numpy
-from dependent import *
-from independent import *
+from dependent import dependent
+from independent import independent
 from fielddisplay import fielddisplay
 from EnumDefinitions import *
-from checkfield import *
-from WriteData import *
+from checkfield import checkfield
+from WriteData import WriteData
 
 class autodiff(object):
@@ -62,13 +62,13 @@
 			return md 
 		
-		md = checkfield(md,'autodiff.obufsize','>=',524288)
-		md = checkfield(md,'autodiff.lbufsize','>=',524288)
-		md = checkfield(md,'autodiff.cbufsize','>=',524288)
-		md = checkfield(md,'autodiff.tbufsize','>=',524288)
-		md = checkfield(md,'autodiff.gcTriggerRatio','>=',2.0)
-		md = checkfield(md,'autodiff.gcTriggerMaxSize','>=',2000000)
+		md = checkfield(md,'fieldname','autodiff.obufsize','>=',524288)
+		md = checkfield(md,'fieldname','autodiff.lbufsize','>=',524288)
+		md = checkfield(md,'fieldname','autodiff.cbufsize','>=',524288)
+		md = checkfield(md,'fieldname','autodiff.tbufsize','>=',524288)
+		md = checkfield(md,'fieldname','autodiff.gcTriggerRatio','>=',2.0)
+		md = checkfield(md,'fieldname','autodiff.gcTriggerMaxSize','>=',2000000)
 
 		#Driver value:
-		md = checkfield(md,'autodiff.driver','values',['fos_forward','fov_forward','fov_forward_all','fos_reverse','fov_reverse','fov_reverse_all'])
+		md = checkfield(md,'fieldname','autodiff.driver','values',['fos_forward','fov_forward','fov_forward_all','fos_reverse','fov_reverse','fov_reverse_all'])
 
 		#go through our dependents and independents and check consistency: 
Index: /issm/trunk/src/m/classes/balancethickness.m
===================================================================
--- /issm/trunk/src/m/classes/balancethickness.m	(revision 17805)
+++ /issm/trunk/src/m/classes/balancethickness.m	(revision 17806)
@@ -11,4 +11,13 @@
 	end
 	methods
+        function createxml(obj,fid) % {{{
+            fprintf(fid, '\n\n');
+            fprintf(fid, '%s\n', '<!-- balancethickness -->');
+            
+			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="spcthickness" type="',   	class(obj.spcthickness),'" default="',        convert2str(obj.spcthickness),'">',	'     <section name="balancethickness" />','     <help> thickness constraints (NaN means no constraint) [m] </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="thickening_rate" type="', 	class(obj.thickening_rate),'" default="',            convert2str(obj.thickening_rate),'">',     '     <section name="balancethickness" />','     <help> ice thickening rate used in the mass conservation (dh/dt) [m/yr] </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n',        '<parameter key ="stabilization" type="',      class(obj.stabilization),'" default="',          convert2str(obj.stabilization),'">',	'     <section name="balancethickness" />','     <help> 0: None, 1: SU, 2: SSAs artificial diffusivity, 3:DG </help>','</parameter>');
+
+        end % }}}
 		function obj = balancethickness(varargin) % {{{
 			switch nargin
@@ -29,7 +38,7 @@
 			if solution~=BalancethicknessSolutionEnum(), return; end
 
-			md = checkfield(md,'balancethickness.spcthickness');
-			md = checkfield(md,'balancethickness.thickening_rate','size',[md.mesh.numberofvertices 1],'NaN',1);
-			md = checkfield(md,'balancethickness.stabilization','size',[1 1],'values',[0 1 2 3]);
+			md = checkfield(md,'fieldname','balancethickness.spcthickness');
+			md = checkfield(md,'fieldname','balancethickness.thickening_rate','size',[md.mesh.numberofvertices 1],'NaN',1);
+			md = checkfield(md,'fieldname','balancethickness.stabilization','size',[1 1],'values',[0 1 2 3]);
 		end % }}}
 		function disp(obj) % {{{
Index: /issm/trunk/src/m/classes/balancethickness.py
===================================================================
--- /issm/trunk/src/m/classes/balancethickness.py	(revision 17805)
+++ /issm/trunk/src/m/classes/balancethickness.py	(revision 17806)
@@ -1,6 +1,6 @@
 from fielddisplay import fielddisplay
 from EnumDefinitions import *
-from checkfield import *
-from WriteData import *
+from checkfield import checkfield
+from WriteData import WriteData
 
 class balancethickness(object):
@@ -42,7 +42,7 @@
 			return md
 
-		md = checkfield(md,'balancethickness.spcthickness')
-		md = checkfield(md,'balancethickness.thickening_rate','size',[md.mesh.numberofvertices],'NaN',1)
-		md = checkfield(md,'balancethickness.stabilization','size',[1],'values',[0,1,2,3])
+		md = checkfield(md,'fieldname','balancethickness.spcthickness')
+		md = checkfield(md,'fieldname','balancethickness.thickening_rate','size',[md.mesh.numberofvertices],'NaN',1)
+		md = checkfield(md,'fieldname','balancethickness.stabilization','size',[1],'values',[0,1,2,3])
 
 		return md
Index: /issm/trunk/src/m/classes/basalforcings.m
===================================================================
--- /issm/trunk/src/m/classes/basalforcings.m	(revision 17805)
+++ /issm/trunk/src/m/classes/basalforcings.m	(revision 17806)
@@ -11,4 +11,12 @@
 	end
 	methods
+        function createxml(obj,fid) % {{{
+            fprintf(fid, '\n\n');
+            fprintf(fid, '%s\n', '<!-- basalforcings -->');
+			 fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="melting_rate" type="',            class(obj.melting_rate),'" default="',              num2str(obj.melting_rate),'">',              '     <section name="basalforcings" />','     <help> basal melting rate (positive if melting) [m/yr] </help>','</parameter>');
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="melting_rate_correction" type="', class(obj.melting_rate_correction),'" default="',   num2str(obj.melting_rate_correction),'">',   '     <section name="basalforcings" />','     <help> additional melting applied to compensate for dh/dt [m/yr] </help>','</parameter>');
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n',        '<parameter key ="geothermalflux" type="',          class(obj.geothermalflux),'" default="',            num2str(obj.geothermalflux),'">',            '     <section name="basalforcings" />','     <help> geothermal heat flux [W/m^2] </help>','</parameter>');
+             
+        end % }}}
 		function obj = basalforcings(varargin) % {{{
 			switch nargin
@@ -19,4 +27,12 @@
 			end
 		end % }}}
+		function self = initialize(self,md) % {{{
+
+			if isnan(self.melting_rate),
+				self.melting_rate=zeros(md.mesh.numberofvertices,1);
+				disp('      no basalforcings.melting_rate specified: values set as zero');
+			end
+
+		end % }}}
 		function obj = setdefaultparameters(obj) % {{{
 
@@ -25,12 +41,12 @@
 
 			if ismember(MasstransportAnalysisEnum(),analyses) & ~(solution==TransientSolutionEnum() & md.transient.ismasstransport==0),
-				md = checkfield(md,'basalforcings.melting_rate','NaN',1,'forcing',1);
+				md = checkfield(md,'fieldname','basalforcings.melting_rate','NaN',1,'forcing',1);
 			end
 			if ismember(BalancethicknessAnalysisEnum(),analyses),
-				md = checkfield(md,'basalforcings.melting_rate','NaN',1,'size',[md.mesh.numberofvertices 1]);
+				md = checkfield(md,'fieldname','basalforcings.melting_rate','NaN',1,'size',[md.mesh.numberofvertices 1]);
 			end
 			if ismember(ThermalAnalysisEnum(),analyses) & ~(solution==TransientSolutionEnum() & md.transient.isthermal==0),
-				md = checkfield(md,'basalforcings.melting_rate','NaN',1,'forcing',1);
-				md = checkfield(md,'basalforcings.geothermalflux','NaN',1,'forcing',1,'>=',0);
+				md = checkfield(md,'fieldname','basalforcings.melting_rate','NaN',1,'forcing',1);
+				md = checkfield(md,'fieldname','basalforcings.geothermalflux','NaN',1,'forcing',1,'>=',0);
 			end
 		end % }}}
Index: /issm/trunk/src/m/classes/basalforcings.py
===================================================================
--- /issm/trunk/src/m/classes/basalforcings.py	(revision 17805)
+++ /issm/trunk/src/m/classes/basalforcings.py	(revision 17806)
@@ -1,6 +1,6 @@
 from fielddisplay import fielddisplay
 from EnumDefinitions import *
-from checkfield import *
-from WriteData import *
+from checkfield import checkfield
+from WriteData import WriteData
 import numpy
 
@@ -30,4 +30,12 @@
 		return string
 		#}}}
+	def initialize(self,md): # {{{
+
+		if numpy.all(numpy.isnan(self.melting_rate)):
+			self.melting_rate=numpy.zeros((md.mesh.numberofvertices,1))
+			print "      no basalforcings.melting_rate specified: values set as zero"
+
+		return self
+	#}}}
 	def setdefaultparameters(self): # {{{
 		return self
@@ -36,12 +44,12 @@
 
 		if MasstransportAnalysisEnum() in analyses and not (solution==TransientSolutionEnum() and not md.transient.ismasstransport):
-			md = checkfield(md,'basalforcings.melting_rate','NaN',1,'forcing',1)
+			md = checkfield(md,'fieldname','basalforcings.melting_rate','NaN',1,'forcing',1)
 
 		if BalancethicknessAnalysisEnum() in analyses:
-			md = checkfield(md,'basalforcings.melting_rate','NaN',1,'size',[md.mesh.numberofvertices])
+			md = checkfield(md,'fieldname','basalforcings.melting_rate','NaN',1,'size',[md.mesh.numberofvertices])
 
 		if ThermalAnalysisEnum() in analyses and not (solution==TransientSolutionEnum() and not md.transient.isthermal):
-			md = checkfield(md,'basalforcings.melting_rate','NaN',1,'forcing',1)
-			md = checkfield(md,'basalforcings.geothermalflux','NaN',1,'forcing',1,'>=',0)
+			md = checkfield(md,'fieldname','basalforcings.melting_rate','NaN',1,'forcing',1)
+			md = checkfield(md,'fieldname','basalforcings.geothermalflux','NaN',1,'forcing',1,'>=',0)
 
 		return md
Index: /issm/trunk/src/m/classes/clusters/acenet.m
===================================================================
--- /issm/trunk/src/m/classes/clusters/acenet.m	(revision 17805)
+++ /issm/trunk/src/m/classes/clusters/acenet.m	(revision 17806)
@@ -72,4 +72,6 @@
           fprintf(fid,'module load gcc openmpi/gcc\n');
           fprintf(fid,'module load issm\n');
+			 fprintf(fid,'export ISSM_DIR="%s/../"\n',cluster.codepath); %FIXME
+			 fprintf(fid,'source $ISSM_DIR/etc/environment.sh\n');       %FIXME
           fprintf(fid,'\n');
           fprintf(fid,'mpiexec -np %i %s/issm.exe %s %s %s 2> %s.errlog >%s.outlog ',...
Index: /issm/trunk/src/m/classes/clusters/discover.m
===================================================================
--- /issm/trunk/src/m/classes/clusters/discover.m	(revision 17805)
+++ /issm/trunk/src/m/classes/clusters/discover.m	(revision 17806)
@@ -96,8 +96,8 @@
 			 %write queuing script 
 			 fid=fopen([modelname '.queue'],'w');
-			 fprintf(fid,'#PBS -S /bin/bash\n');
+			 fprintf(fid,'#!/bin/bash\n');
 %			 fprintf(fid,'#PBS -N %s\n',modelname);
-			 fprintf(fid,'#PBS -l select=%i:ncpus=%i:proc=%s\n',cluster.numnodes,cluster.cpuspernode,cluster.processor);
-			 fprintf(fid,'#PBS -l walltime=%i\n',cluster.time*60); %walltime is in seconds.
+			 fprintf(fid,'#PBS -l select=%i:mpiprocs=%i:proc=%s\n',cluster.numnodes,cluster.cpuspernode,cluster.processor);
+			 fprintf(fid,'#PBS -l walltime=%i:00\n',cluster.time); %SLURM walltime is in minutes:
 			 fprintf(fid,'#PBS -q %s \n',cluster.queue);
 			 fprintf(fid,'#PBS -W group_list=s1010\n');
Index: /issm/trunk/src/m/classes/clusters/generic.m
===================================================================
--- /issm/trunk/src/m/classes/clusters/generic.m	(revision 17805)
+++ /issm/trunk/src/m/classes/clusters/generic.m	(revision 17806)
@@ -19,7 +19,26 @@
 		valgrindlib=[issmdir() '/externalpackages/valgrind/install/lib/libmpidebug.so'];
 		valgrindsup=[issmdir() '/externalpackages/valgrind/issm.supp'];
+		verbose=1;
 		%}}}
 	end
 	methods
+        function createxml(obj,fid) % {{{
+            fprintf(fid, '\n\n');
+            fprintf(fid, '%s\n', '<!-- generic -->');
+            
+			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="name" type="',class(obj.name),'" default="',convert2str(obj.name),'">',	'     <section name="cluster" />','     <help> N/A </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="login" type="',class(obj.login),'" default="',convert2str(obj.login),'">',     '     <section name="cluster" />','     <help> N/A </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',	'<parameter key ="np" type="',class(obj.np),'" default="',convert2str(obj.np),'">',	'     <section name="cluster" />','     <help> N/A </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="port" type="',class(obj.port),'" default="',convert2str(obj.port),'">',	'     <section name="cluster" />','     <help> N/A </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="codepath" type="',class(obj.codepath),'" default="',convert2str(obj.codepath),'">',     '     <section name="cluster" />','     <help> N/A </help>','</parameter>');
+             
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="executionpath" type="',class(obj.executionpath),'" default="',convert2str(obj.executionpath),'">',	'     <section name="cluster" />','     <help> N/A </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="etcpath" type="',class(obj.etcpath),'" default="',convert2str(obj.etcpath),'">',     '     <section name="cluster" />','     <help> N/A </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="valgrind" type="',class(obj.valgrind),'" default="',convert2str(obj.valgrind),'">',	'     <section name="cluster" />','     <help> N/A </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="valgrindlib" type="',class(obj.valgrindlib),'" default="',convert2str(obj.valgrindlib),'">',     '     <section name="cluster" />','     <help> N/A </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="valgrindsup" type="',class(obj.valgrindsup),'" default="',convert2str(obj.valgrindsup),'">',     '     <section name="cluster" />','     <help> N/A </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n',    	'<parameter key ="verbose" type="',class(obj.verbose),'" default="',convert2str(obj.verbose),'">',	'     <section name="cluster" />','     <help> N/A </help>','</parameter>');
+             
+        end % }}}
 		function cluster=generic(varargin) % {{{
 
@@ -50,4 +69,5 @@
 			disp(sprintf('    valgrindlib: %s',cluster.valgrindlib));
 			disp(sprintf('    valgrindsup: %s',cluster.valgrindsup));
+			disp(sprintf('    verbose: %s',cluster.verbose));
 		end
 		%}}}
@@ -114,4 +134,7 @@
 				fid=fopen([modelname '.bat'],'w');
 				fprintf(fid,'@echo off\n');
+
+				warning('parallel runs not allowed yet in Windows. Defaulting to 1 cpus');
+				cluster.np=1;
 
 				if cluster.np>1,
@@ -189,8 +212,8 @@
 				system(compressstring);
 
-				disp('uploading input file and queueing script');
+				if cluster.verbose, disp('uploading input file and queueing script'); end
 				issmscpout(cluster.name,cluster.executionpath,cluster.login,cluster.port,{[dirname '.tar.gz']});
 
-				disp('launching solution sequence on remote cluster');
+				if cluster.verbose, disp('launching solution sequence on remote cluster'); end
 				launchcommand=['source ' cluster.etcpath '/environment.sh && cd ' cluster.executionpath ' && rm -rf ./' dirname ' && mkdir ' dirname ...
 					' && cd ' dirname ' && mv ../' dirname '.tar.gz ./ && tar -zxf ' dirname '.tar.gz  && source  ' modelname '.queue '];
Index: /issm/trunk/src/m/classes/clusters/generic.py
===================================================================
--- /issm/trunk/src/m/classes/clusters/generic.py	(revision 17805)
+++ /issm/trunk/src/m/classes/clusters/generic.py	(revision 17806)
@@ -1,13 +1,14 @@
 import socket
+import os
 import math
 import subprocess
 from IssmConfig import IssmConfig
 from EnumToString import EnumToString
-from issmdir import *
-from pairoptions import *
-from issmssh import *
-from issmscpin import *
-from issmscpout import *
-from MatlabFuncs import *
+from issmdir import issmdir
+from pairoptions import pairoptions
+from issmssh import issmssh
+from issmscpin import issmscpin
+from issmscpout import issmscpout
+import MatlabFuncs as m
 
 class generic(object):
@@ -37,5 +38,5 @@
 
 		#get name
-		self.name=options.getfieldvalue('name',socket.gethostname().lower().split('.')[0])
+		self.name=socket.gethostname()
 
 		#initialize cluster using user settings if provided
@@ -46,5 +47,4 @@
 		self=options.AssignObjectFields(self)
 	# }}}
-
 	def __repr__(self):    # {{{
 		#  display the object
@@ -61,5 +61,4 @@
 		return s
 	# }}}
-
 	def checkconsistency(self,md,solution,analyses):    # {{{
 		if self.np<1:
@@ -70,9 +69,8 @@
 		return md
 	# }}}
-
 	def BuildQueueScript(self,dirname,modelname,solution,io_gather,isvalgrind,isgprof):    # {{{
 
 		#write queuing script 
-		if not ispc():
+		if not m.ispc():
 
 			fid=open(modelname+'.queue','w')
@@ -123,9 +121,8 @@
 			fid.close()
 	# }}}
-
 	def BuildKrigingQueueScript(self,modelname,solution,io_gather,isvalgrind,isgprof):    # {{{
 
 		#write queuing script 
-		if not ispc():
+		if not m.ispc():
 
 			fid=open(modelname+'.queue','w')
@@ -165,5 +162,4 @@
 			fid.close()
 	# }}}
-
 	def LaunchQueueJob(self,modelname,dirname,filelist):    # {{{
 
@@ -184,8 +180,7 @@
 		issmssh(self.name,self.login,self.port,launchcommand)
 	# }}}
-
 	def Download(self,dirname,filelist):     # {{{
 
-		if ispc():
+		if m.ispc():
 			#do nothing
 			return
@@ -195,3 +190,2 @@
 		issmscpin(self.name,self.login,self.port,directory,filelist)
 	# }}}
-
Index: /issm/trunk/src/m/classes/clusters/greenplanet.m
===================================================================
--- /issm/trunk/src/m/classes/clusters/greenplanet.m	(revision 17805)
+++ /issm/trunk/src/m/classes/clusters/greenplanet.m	(revision 17806)
@@ -19,4 +19,5 @@
 		 interactive=0;
 		 time=24*60;
+		 memory=2;
 	 end
 	 properties (SetAccess=private) 
@@ -47,4 +48,6 @@
 			 disp(sprintf('    executionpath: %s',cluster.executionpath));
 			 disp(sprintf('    interactive: %i',cluster.interactive));
+			 disp(sprintf('    time: %i',cluster.time));
+			 disp(sprintf('    memory: %i',cluster.memory));
 		 end
 		 %}}}
@@ -78,4 +81,6 @@
 			 fprintf(fid,'#PBS -q %s \n',cluster.queue);
 			 fprintf(fid,'#PBS -l nodes=%i:ppn=%i\n',cluster.numnodes,cluster.cpuspernode);
+			 fprintf(fid,'#PBS -l walltime=%i\n',cluster.time*60);%walltime is in seconds.
+			 fprintf(fid,'#PBS -l mem=%igb\n',cluster.memory);
 			 fprintf(fid,'#PBS -m bea\n');
 			 fprintf(fid,'#PBS -M mmorligh@uci.edu\n');
@@ -103,5 +108,8 @@
 			 fprintf(fid,'#PBS -N %s\n',modelname);
 			 fprintf(fid,'#PBS -q %s \n',cluster.queue);
-			 fprintf(fid,'#PBS -l nodes=%i:ppn=%i\n',cluster.numnodes,cluster.cpuspernode);
+			 fprintf(fid,'#PBS -l nodes=%i:ppn=%i\n',cluster.numnodes, ...
+							 cluster.cpuspernode);
+			 fprintf(fid,'#PBS -l walltime=%i\n',cluster.time*60); %walltime is in seconds.
+			 fprintf(fid,'#PBS -l mem=%igb\n',cluster.memory);
 			 fprintf(fid,'#PBS -m bea\n');
 			 fprintf(fid,'#PBS -M mmorligh@uci.edu\n');
@@ -147,6 +155,6 @@
 
 			 disp('launching solution sequence on remote cluster');
-			 launchcommand=['cd ' cluster.executionpath ' && rm -rf ./' dirname ' && mkdir ' dirname ...
-				 ' && cd ' dirname ' && mv ../' dirname '.tar.gz ./ && tar -zxf ' dirname '.tar.gz  && qsub ' modelname '.queue '];
+			  launchcommand=['cd ' cluster.executionpath ' && rm -rf ./' dirname ' && mkdir ' dirname ...
+											 ' && cd ' dirname ' && mv ../' dirname '.tar.gz ./ && tar -zxf ' dirname '.tar.gz  && hostname && qsub ' modelname '.queue '];
 			 issmssh(cluster.name,cluster.login,cluster.port,launchcommand);
 		 end %}}}
Index: /issm/trunk/src/m/classes/constants.m
===================================================================
--- /issm/trunk/src/m/classes/constants.m	(revision 17805)
+++ /issm/trunk/src/m/classes/constants.m	(revision 17806)
@@ -11,4 +11,11 @@
 	end
 	methods
+        function createxml(obj,fid) % {{{
+            fprintf(fid, '\n\n');
+            fprintf(fid, '%s\n', '<!-- constants -->');
+			 fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="g" type="',class(obj.g),'" default="',num2str(obj.g),'">','     <section name="constants" />','     <help> gravitational acceleration [m/s^2] </help>','</parameter>');
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="yts" type="',class(obj.yts),'" default="',num2str(obj.yts),'">','     <section name="constants" />','     <help> number of seconds in a year [s/yr] </help>','</parameter>');
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n','<parameter key ="referencetemperature" type="',class(obj.referencetemperature),'" default="',num2str(obj.referencetemperature),'">','     <section name="constants" />','     <help> reference temperature used in the enthalpy model [K] </help>','</parameter>');
+		end % }}}
 		function obj = constants(varargin) % {{{
 			switch nargin
@@ -33,7 +40,7 @@
 		function md = checkconsistency(obj,md,solution,analyses) % {{{
 
-%			md = checkfield(md,'constants.g','>',0,'size',[1 1]);
-			md = checkfield(md,'constants.yts','>',0,'size',[1 1]);
-			md = checkfield(md,'constants.referencetemperature','size',[1 1]);
+%			md = checkfield(md,'fieldname','constants.g','>',0,'size',[1 1]);
+			md = checkfield(md,'fieldname','constants.yts','>',0,'size',[1 1]);
+			md = checkfield(md,'fieldname','constants.referencetemperature','size',[1 1]);
 
 		end % }}}
Index: /issm/trunk/src/m/classes/constants.py
===================================================================
--- /issm/trunk/src/m/classes/constants.py	(revision 17805)
+++ /issm/trunk/src/m/classes/constants.py	(revision 17806)
@@ -1,6 +1,6 @@
 from fielddisplay import fielddisplay
 from EnumDefinitions import *
-from checkfield import *
-from WriteData import *
+from checkfield import checkfield
+from WriteData import WriteData
 
 class constants(object):
@@ -45,7 +45,7 @@
 	def checkconsistency(self,md,solution,analyses):    # {{{
 
-		md = checkfield(md,'constants.g','>',0,'size',[1])
-		md = checkfield(md,'constants.yts','>',0,'size',[1])
-		md = checkfield(md,'constants.referencetemperature','size',[1])
+		md = checkfield(md,'fieldname','constants.g','>',0,'size',[1])
+		md = checkfield(md,'fieldname','constants.yts','>',0,'size',[1])
+		md = checkfield(md,'fieldname','constants.referencetemperature','size',[1])
 
 		return md
Index: /issm/trunk/src/m/classes/damage.m
===================================================================
--- /issm/trunk/src/m/classes/damage.m	(revision 17805)
+++ /issm/trunk/src/m/classes/damage.m	(revision 17806)
@@ -7,4 +7,5 @@
 	properties (SetAccess=public)  
 		%damage 
+		isdamage            = NaN;
 		D                   = NaN;
 		law                 = '';
@@ -14,6 +15,7 @@
 		%numerical
 		stabilization       = NaN;
+		maxiter             = NaN;
+		elementinterp       = '';
 		penalty_threshold   = NaN;
-		maxiter             = NaN;
 		penalty_lock        = NaN;
 		penalty_factor      = NaN;
@@ -26,6 +28,56 @@
 		c4                  = NaN;
 		healing             = NaN;
+		equiv_stress		  = NaN;
+		requested_outputs   = {};
 	end
 	methods
+        function createxml(obj,fid) % {{{
+            fprintf(fid, '\n\n');
+            fprintf(fid, '%s\n', '<!-- damage -->');
+            fprintf(fid, '%s\n', '<!-- Note: this class depends on different input of law -->');
+            
+            %fprintf(fid,'%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="law" type="logical"',           '" default="',                num2str(obj.law),'">',   '     <section name="damage" />','     <help> damage law (string) from {"undamaged","pralong"} </help>','</parameter>');
+            % drop-down 
+            fprintf(fid,'%s%s%s%s%s\n\t%s\n','<parameter key ="law" type="','alternative','" optional="','false','">','<section name="damage" />');
+            
+            % law = 'undamage'
+            fprintf(fid,'\t%s%s%s%s%s\n\t\t%s\n','<option value="undamage" type="','string','" default="','true','">','<help> law = undamage </help>');
+            % footer for option
+            fprintf(fid,'\t%s\n%s\n','</option>');
+            
+            % law = 'pralong'
+            fprintf(fid,'\t%s%s%s%s%s\n\t\t%s\n','<option value="pralong" type="','string','" default="','false','">','<help> law = pralong </help>');
+                
+            fprintf(fid,'\t\t%s%s%s%s%s\n\t\t\t%s\n\t\t%s\n',   '<parameter key ="stress_threshold" type="',class(obj.stress_threshold),'" default="',num2str(obj.stress_threshold),'">','<help> damage stress threshold [Pa] </help>','</parameter>');
+            fprintf(fid,'\t\t%s%s%s%s%s\n\t\t\t%s\n\t\t%s\n',	'<parameter key ="c1" type="', class(obj.c1),'" default="',   num2str(obj.c1),'">',   '<help> damage parameter 1 </help>','</parameter>');
+            fprintf(fid,'\t\t%s%s%s%s%s\n\t\t\t%s\n\t\t%s\n',  	'<parameter key ="c2" type="',          class(obj.c2),'" default="',            num2str(obj.c2),'">','<help> damage parameter 2 </help>','</parameter>');
+            fprintf(fid,'\t\t%s%s%s%s%s\n\t\t\t%s\n\t\t%s\n',  	'<parameter key ="c3" type="',          class(obj.c3),'" default="',            num2str(obj.c3),'">','<help> damage parameter 3 [W/m^2] </help>','</parameter>');
+            fprintf(fid,'\t\t%s%s%s%s%s\n\t\t\t%s\n\t\t%s\n',  	'<parameter key ="c4" type="',            class(obj.c4),'" default="',              num2str(obj.c4),'">','<help> damage parameter 4 </help>','</parameter>');
+            fprintf(fid,'\t\t%s%s%s%s%s\n\t\t\t%s\n\t\t%s\n',  	'<parameter key ="healing" type="', class(obj.healing),'" default="',   num2str(obj.healing),'">','<help> damage healing parameter 1 </help>','</parameter>');
+            fprintf(fid,'\t\t%s%s%s%s%s\n\t\t\t%s\n\t\t%s\n',  	'<parameter key ="equiv_stress" type="',          class(obj.equiv_stress),'" default="',convert2str(obj.equiv_stress),'">','<help> 0: von Mises </help>','</parameter>');
+            fprintf(fid,'\t\t%s%s%s%s%s\n\t\t\t%s\n\t\t%s\n',  	'<parameter key ="requested_outputs" type="',          class(obj.requested_outputs),'" default="',convert2str(obj.requested_outputs),'">','<help> additional outputs requested </help>','</parameter>');
+             
+                
+            % footer for option
+            fprintf(fid,'\t%s\n%s\n','</option>');
+                 
+            
+            % footer for drop-down
+            fprintf(fid,'\t%s\n%s\n%s','<help> damage law (string) from {"undamaged","pralong"} </help>','</parameter>');
+            
+            
+			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="D" type="',              class(obj.D),'" default="',                  num2str(obj.D),'">',              '     <section name="damage" />','     <help> damage tensor (scalar) </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="law" type="',            class(obj.law),'" default="',                num2str(obj.law),'">',   '     <section name="damage" />','     <help> damage law (string) from {"undamaged","pralong"} </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',        '<parameter key ="spcdamage" type="',      class(obj.spcdamage),'" default="',          num2str(obj.spcdamage),'">',            '     <section name="damage" />','     <help> damage constraints (NaN means no constraint) </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',        '<parameter key ="max_damage" type="',     class(obj.max_damage),'" default="',         num2str(obj.max_damage),'">',            '     <section name="damage" />','     <help> maximum possible damage (0&amp;lt;=max_damage&amp;lt;1) </help>','</parameter>');
+             
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="stabilization" type="',       class(obj.stabilization),'" default="',              num2str(obj.stabilization),'">',              '     <section name="damage" />','     <help> 0: no, 1: artificial_diffusivity, 2: SUPG </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="maxiter" type="',             class(obj.maxiter),'" default="',   num2str(obj.maxiter),'">',   '     <section name="damage" />','     <help> maximum number of non linear iterations </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',        '<parameter key ="penalty_lock" type="',        class(obj.penalty_lock),'" default="',            num2str(obj.penalty_lock),'">',            '     <section name="damage" />','     <help> stabilize unstable damage constraints that keep zigzagging after n iteration (default is 0, no stabilization) </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',        '<parameter key ="penalty_threshold" type="',   class(obj.penalty_threshold),'" default="',            num2str(obj.penalty_threshold),'">',            '     <section name="damage" />','     <help> threshold to declare convergence of damage evolution solution (default is 0) </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',        '<parameter key ="penalty_factor" type="',      class(obj.penalty_factor),'" default="',            num2str(obj.penalty_factor),'">',            '     <section name="damage" />','     <help> scaling exponent (default is 3) </help>','</parameter>');
+ 
+        end % }}}
+        
 		function obj = damage(varargin) % {{{
 			switch nargin
@@ -49,4 +101,5 @@
 
 			%damage parameters: 
+			obj.isdamage=0;
 			obj.D=0;
 			obj.law='undamaged';
@@ -59,4 +112,7 @@
 			%Maximum number of iterations
 			obj.maxiter=100;
+
+			%finite element interpolation
+			obj.elementinterp='P1';
 
 			%factor used to compute the values of the penalties: kappa=max(stiffness matrix)*10^penalty_factor
@@ -76,26 +132,36 @@
 			obj.c3=0;
 			obj.c4=0;
+			obj.equiv_stress=0;
+
+			 %output default:
+			 obj.requested_outputs={'default'};
 
 		end % }}}
 		function md = checkconsistency(obj,md,solution,analyses) % {{{
 			
-			md = checkfield(md,'damage.D','>=',0,'<=',obj.max_damage,'size',[md.mesh.numberofvertices 1]);
-			md = checkfield(md,'damage.max_damage','<',1,'>=',0);
-			md = checkfield(md,'damage.law','values',{'undamaged','pralong'});
-			md = checkfield(md,'damage.spcdamage','forcing',1);
-			
-			md = checkfield(md,'damage.stabilization','numel',[1],'values',[0 1 2]);
-			md = checkfield(md,'damage.maxiter','>=0',0);
-			md = checkfield(md,'damage.penalty_factor','>=0',0);
-			md = checkfield(md,'damage.penalty_lock','>=0',0);
-			md = checkfield(md,'damage.penalty_threshold','>=0',0);
+			md = checkfield(md,'fieldname','damage.isdamage','values',[1,0]);
+			if obj.isdamage,
+				md = checkfield(md,'fieldname','damage.law','values',{'undamaged','pralong'});
+				md = checkfield(md,'fieldname','damage.D','>=',0,'<=',obj.max_damage,'size',[md.mesh.numberofvertices 1]);
+				md = checkfield(md,'fieldname','damage.spcdamage','forcing',1);
+				md = checkfield(md,'fieldname','damage.max_damage','<',1,'>=',0);
+				
+				md = checkfield(md,'fieldname','damage.stabilization','numel',[1],'values',[0 1 2]);
+				md = checkfield(md,'fieldname','damage.maxiter','>=0',0);
+				md = checkfield(md,'fieldname','damage.elementinterp','values',{'P1','P2'});
+				md = checkfield(md,'fieldname','damage.penalty_factor','>=0',0);
+				md = checkfield(md,'fieldname','damage.penalty_lock','>=0',0);
+				md = checkfield(md,'fieldname','damage.penalty_threshold','>=0',0);
+			end
 
 			if strcmpi(obj.law,'pralong'),
-				md = checkfield(md,'damage.healing','>=',0);
-				md = checkfield(md,'damage.c1','>=',0);
-				md = checkfield(md,'damage.c2','>=',0);
-				md = checkfield(md,'damage.c3','>=',0);
-				md = checkfield(md,'damage.c4','>=',0);
-				md = checkfield(md,'damage.stress_threshold','>=',0);
+				md = checkfield(md,'fieldname','damage.healing','>=',0);
+				md = checkfield(md,'fieldname','damage.c1','>=',0);
+				md = checkfield(md,'fieldname','damage.c2','>=',0);
+				md = checkfield(md,'fieldname','damage.c3','>=',0);
+				md = checkfield(md,'fieldname','damage.c4','>=',0);
+				md = checkfield(md,'fieldname','damage.stress_threshold','>=',0);
+				md = checkfield(md,'fieldname','damage.equiv_stress','numel',[1],'values',[0 1]);
+				md = checkfield(md,'fieldname','damage.requested_outputs','stringrow',1);
 			elseif strcmpi(obj.law,'undamaged'),
 				if (solution==DamageEvolutionSolutionEnum),
@@ -107,17 +173,29 @@
 
 		end % }}}
+		function list=defaultoutputs(self,md) % {{{
+
+			if strcmp(domaintype(md.mesh),'2Dhorizontal'),
+            list = {'DamageDbar'};
+         else
+            list = {'DamageD'};
+			end
+		end % }}}
 		function disp(obj) % {{{
 			disp(sprintf('   Damage:\n'));
 
-			fielddisplay(obj,'D','damage tensor (scalar)');
-			fielddisplay(obj,'law','damage law (string) from {''undamaged'',''pralong''}');
-			fielddisplay(obj,'spcdamage','damage constraints (NaN means no constraint)');
-			fielddisplay(obj,'max_damage','maximum possible damage (0<=max_damage<1)');
-			
-			fielddisplay(obj,'stabilization','0: no, 1: artificial_diffusivity, 2: SUPG');
-			fielddisplay(obj,'maxiter','maximum number of non linear iterations');
-			fielddisplay(obj,'penalty_lock','stabilize unstable damage constraints that keep zigzagging after n iteration (default is 0, no stabilization)');
-			fielddisplay(obj,'penalty_threshold','threshold to declare convergence of damage evolution solution (default is 0)');
-			fielddisplay(obj,'penalty_factor','scaling exponent (default is 3)');
+			fielddisplay(obj,'isdamage','is damage mechanics being used? {true,false}');
+			if obj.isdamage,
+				fielddisplay(obj,'law','damage law (string) from {''undamaged'',''pralong''}');
+				fielddisplay(obj,'D','damage tensor (scalar)');
+				fielddisplay(obj,'spcdamage','damage constraints (NaN means no constraint)');
+				fielddisplay(obj,'max_damage','maximum possible damage (0<=max_damage<1)');
+				
+				fielddisplay(obj,'stabilization','0: no, 1: artificial_diffusivity, 2: SUPG');
+				fielddisplay(obj,'maxiter','maximum number of non linear iterations');
+				fielddisplay(obj,'elementinterp','interpolation scheme for finite elements {''P1'',''P2''}');
+				fielddisplay(obj,'penalty_lock','stabilize unstable damage constraints that keep zigzagging after n iteration (default is 0, no stabilization)');
+				fielddisplay(obj,'penalty_threshold','threshold to declare convergence of damage evolution solution (default is 0)');
+				fielddisplay(obj,'penalty_factor','scaling exponent (default is 3)');
+			end
 
 			if strcmpi(obj.law,'pralong'),
@@ -126,6 +204,8 @@
 				fielddisplay(obj,'c3','damage parameter 3');
 				fielddisplay(obj,'c4','damage parameter 4');
-				fielddisplay(obj,'healing','damage healing parameter 1');
+				fielddisplay(obj,'healing','damage healing parameter');
 				fielddisplay(obj,'stress_threshold','damage stress threshold [Pa]');
+				fielddisplay(obj,'equiv_stress','0: von Mises, 1: max principal');
+				fielddisplay(obj,'requested_outputs','additional outputs requested');
 			end
 
@@ -133,14 +213,18 @@
 		function marshall(obj,md,fid) % {{{
 		
-			WriteData(fid,'object',obj,'fieldname','D','format','DoubleMat','mattype',1);
-			WriteData(fid,'object',obj,'fieldname','law','format','String');
-			WriteData(fid,'object',obj,'fieldname','spcdamage','format','DoubleMat','mattype',1,'forcinglength',md.mesh.numberofvertices+1);
-			WriteData(fid,'object',obj,'fieldname','max_damage','format','Double');
-
-			WriteData(fid,'object',obj,'fieldname','stabilization','format','Integer');
-			WriteData(fid,'object',obj,'fieldname','penalty_threshold','format','Integer');
-			WriteData(fid,'object',obj,'fieldname','maxiter','format','Integer');
-			WriteData(fid,'object',obj,'fieldname','penalty_lock','format','Integer');
-			WriteData(fid,'object',obj,'fieldname','penalty_factor','format','Double');
+			WriteData(fid,'object',obj,'fieldname','isdamage','format','Boolean');
+			if obj.isdamage,
+				WriteData(fid,'object',obj,'fieldname','law','format','String');
+				WriteData(fid,'object',obj,'fieldname','D','format','DoubleMat','mattype',1);
+				WriteData(fid,'object',obj,'fieldname','spcdamage','format','DoubleMat','mattype',1,'forcinglength',md.mesh.numberofvertices+1);
+				WriteData(fid,'object',obj,'fieldname','max_damage','format','Double');
+
+				WriteData(fid,'object',obj,'fieldname','stabilization','format','Integer');
+				WriteData(fid,'object',obj,'fieldname','maxiter','format','Integer');
+				WriteData(fid,'object',obj,'fieldname','elementinterp','format','String');
+				WriteData(fid,'object',obj,'fieldname','penalty_threshold','format','Integer');
+				WriteData(fid,'object',obj,'fieldname','penalty_lock','format','Integer');
+				WriteData(fid,'object',obj,'fieldname','penalty_factor','format','Double');
+			end
 	
 			if strcmpi(obj.law,'pralong'),
@@ -151,4 +235,16 @@
 				WriteData(fid,'object',obj,'fieldname','stress_threshold','format','Double');
 				WriteData(fid,'object',obj,'fieldname','healing','format','Double');
+				WriteData(fid,'object',obj,'fieldname','equiv_stress','format','Integer');
+			end
+
+			%process requested outputs
+			outputs = obj.requested_outputs;
+			pos = find(ismember(outputs,'default'));
+			if ~isempty(pos),
+				outputs(pos) = [];                         %remove 'default' from outputs
+				outputs      = [outputs defaultoutputs(obj,md)]; %add defaults
+			end
+			if obj.isdamage,
+				WriteData(fid,'data',outputs,'enum',DamageEvolutionRequestedOutputsEnum,'format','StringArray');
 			end
 
Index: /issm/trunk/src/m/classes/damage.py
===================================================================
--- /issm/trunk/src/m/classes/damage.py	(revision 17805)
+++ /issm/trunk/src/m/classes/damage.py	(revision 17806)
@@ -2,6 +2,7 @@
 from EnumDefinitions import *
 from StringToEnum import StringToEnum
-from checkfield import *
-from WriteData import *
+from checkfield import checkfield
+from WriteData import WriteData
+import MatlabFuncs as m
 
 class damage(object):
@@ -10,5 +11,5 @@
 
 	   Usage:
-	      damage=damage();
+	      damage=damage()
 	"""
 
@@ -16,4 +17,5 @@
 			
 		#damage: 
+		self.isdamage           = float('NaN')
 		self.D						= float('NaN')
 		self.law						= ''
@@ -23,6 +25,7 @@
 		#numerical
 		stabilization				= float('NaN')
+		maxiter						= float('NaN')
+		elementinterp           = ''
 		penalty_threshold			= float('NaN')
-		maxiter						= float('NaN')
 		penalty_lock				= float('NaN')
 		penalty_factor				= float('NaN')
@@ -35,4 +38,6 @@
 		self.c4                 = float('NaN')
 		self.healing				= float('NaN')
+		self.equiv_stress       = float('NaN')
+		self.requested_outputs  = []
 
 		if not len(args):
@@ -44,15 +49,18 @@
 	def __repr__(self):    # {{{
 		s ='   Damage:\n'
+		
+		s+="%s\n" % fielddisplay(self,"isdamage","is damage mechanics being used? [0 (default) or 1]")
+		if self.isdamage:
+			s+="%s\n" % fielddisplay(self,"D","damage tensor (scalar for now)")
+			s+="%s\n" % fielddisplay(self,"law","damage law (string) from ['undamaged','pralong']")
+			s+="%s\n" % fielddisplay(self,"spcdamage","damage constraints (NaN means no constraint)")
+			s+="%s\n" % fielddisplay(self,"max_damage","maximum possible damage (0<=max_damage<1)")
 
-		s+="%s\n" % fielddisplay(self,"D","damage tensor (scalar for now)")
-		s+="%s\n" % fielddisplay(self,"law","damage law (string) from ['undamaged','pralong']")
-		s+="%s\n" % fielddisplay(self,"spcdamage","damage constraints (NaN means no constraint)")
-		s+="%s\n" % fielddisplay(self,"max_damage","maximum possible damage (0<=max_damage<1)")
-
-		s+="%s\n" % fielddisplay(self,"stabilization","0: no, 1: artificial_diffusivity, 2: SUPG")
-		s+="%s\n" % fielddisplay(self,"maxiter","maximum number of non linear iterations")
-		s+="%s\n" % fielddisplay(self,"penalty_lock","stabilize unstable damage constraints that keep zigzagging after n iteration (default is 0, no stabilization)")
-		s+="%s\n" % fielddisplay(self,"penalty_lock","threshold to declare convergence of damage evolution solution (default is 0)")
-		s+="%s\n" % fielddisplay(self,"penalty_lock","scaling exponent (default is 3)")
+			s+="%s\n" % fielddisplay(self,"stabilization","0: no, 1: artificial_diffusivity, 2: SUPG")
+			s+="%s\n" % fielddisplay(self,"maxiter","maximum number of non linear iterations")
+			s+="%s\n" %	fielddisplay(self,"elementinterp","interpolation scheme for finite elements {''P1'',''P2''}")
+			s+="%s\n" % fielddisplay(self,"penalty_lock","stabilize unstable damage constraints that keep zigzagging after n iteration (default is 0, no stabilization)")
+			s+="%s\n" % fielddisplay(self,"penalty_threshold","threshold to declare convergence of damage evolution solution (default is 0)")
+			s+="%s\n" % fielddisplay(self,"penalty_factor","scaling exponent (default is 3)")
 
 		if (self.law=='pralong'):
@@ -62,4 +70,7 @@
 			s+="%s\n" % fielddisplay(self,"c4","damage parameter 4 ")
 			s+="%s\n" % fielddisplay(self,"stress_threshold","damage stress threshold [Pa]")
+			s+="%s\n" % fielddisplay(self,"healing","damage healing parameter")
+			s+="%s\n" % fielddisplay(self,"equiv_stress","0: von Mises, 1: max principal")
+			s+="%s\n" % fielddisplay(self,'requested_outputs','additional outputs requested')
 
 		return s
@@ -68,4 +79,5 @@
 
 		#damage parameters: 
+		self.isdamage=0
 		self.D=0
 		self.law='undamaged'
@@ -78,4 +90,7 @@
 		#Maximum number of iterations
 		self.maxiter=100
+
+		#finite element interpolation
+		self.elementinterp='P1'
 
 		#factor used to compute the values of the penalties: kappa=max(stiffness matrix)*10^penalty_factor
@@ -95,29 +110,49 @@
 		self.c4=0
 		self.healing=0
+		self.equiv_stress=0
 
+		#output default:
+		self.requested_outputs=['default']
+
+		return self
 	# }}}
+	def defaultoutputs(self,md): # {{{
+		
+		if md.mesh.domaintype().lower()=='2dhorizontal':
+			list = ['DamageDbar']
+		else:
+			list = ['DamageD']
+		return list
+
+	#}}}
 	def checkconsistency(self,md,solution,analyses):    # {{{
 
-		md = checkfield(md,'damage.D','>=',0,'<=',self.max_damage,'size',[md.mesh.numberofvertices])
-		md = checkfield(md,'damage.max_damage','<',1,'>=',0)
-		md = checkfield(md,'damage.law','values',['undamaged','pralong'])
-		md = checkfield(md,'damage.spcdamage','forcing',1)
-			
-		md = checkfield(md,'damage.stabilization','numel',[1],'values',[0,1,2]);
-		md = checkfield(md,'damage.maxiter','>=0',0);
-		md = checkfield(md,'damage.penalty_factor','>=0',0);
-		md = checkfield(md,'damage.penalty_lock','>=0',0);
-		md = checkfield(md,'damage.penalty_threshold','>=0',0);
+		md = checkfield(md,'fieldname','damage.isdamage','numel',[1],'values',[0,1])
+		if self.isdamage:
+			md = checkfield(md,'fieldname','damage.D','>=',0,'<=',self.max_damage,'size',[md.mesh.numberofvertices])
+			md = checkfield(md,'fieldname','damage.max_damage','<',1,'>=',0)
+			md = checkfield(md,'fieldname','damage.law','values',['undamaged','pralong'])
+			md = checkfield(md,'fieldname','damage.spcdamage','forcing',1)
+				
+			md = checkfield(md,'fieldname','damage.stabilization','numel',[1],'values',[0,1,2])
+			md = checkfield(md,'fieldname','damage.maxiter','>=0',0)
+			md = checkfield(md,'fieldname','damage.elementinterp','values',['P1','P2'])
+			md = checkfield(md,'fieldname','damage.penalty_factor','>=0',0)
+			md = checkfield(md,'fieldname','damage.penalty_lock','>=0',0)
+			md = checkfield(md,'fieldname','damage.penalty_threshold','>=0',0)
 
 		if self.law == 'pralong':
-			md = checkfield(md,'damage.healing','>=',0);
-			md = checkfield(md,'damage.c1','>=',0)
-			md = checkfield(md,'damage.c2','>=',0)
-			md = checkfield(md,'damage.c3','>=',0)
-			md = checkfield(md,'damage.c4','>=',0)
-			md = checkfield(md,'damage.stress_threshold','>=',0)
-		elif strcmpi(self.law,'undamaged'):
+			md = checkfield(md,'fieldname','damage.healing','>=',0)
+			md = checkfield(md,'fieldname','damage.c1','>=',0)
+			md = checkfield(md,'fieldname','damage.c2','>=',0)
+			md = checkfield(md,'fieldname','damage.c3','>=',0)
+			md = checkfield(md,'fieldname','damage.c4','>=',0)
+			md = checkfield(md,'fieldname','damage.stress_threshold','>=',0)
+			md = checkfield(md,'fieldname','damage.healing','>=',0)
+			md = checkfield(md,'fieldname','damage.equiv_stress','numel',[1],'values',[0,1])
+			md = checkfield(md,'fieldname','damage.requested_outputs','stringrow',1)
+		elif m.strcmpi(self.law,'undamaged'):
 			if (solution==DamageEvolutionSolutionEnum):
-				raise RuntimeError('Invalid evolution law (md.damage.law) for a damage solution');
+				raise RuntimeError('Invalid evolution law (md.damage.law) for a damage solution')
 
 		return md
@@ -125,14 +160,17 @@
 	def marshall(self,md,fid):    # {{{
 
-		WriteData(fid,'object',self,'fieldname','D','format','DoubleMat','mattype',1)
-		WriteData(fid,'object',self,'fieldname','law','format','String')
-		WriteData(fid,'object',self,'fieldname','spcdamage','format','DoubleMat','mattype',1,'forcinglength',md.mesh.numberofvertices+1);
-		WriteData(fid,'object',self,'fieldname','max_damage','format','Double');
+		WriteData(fid,'object',self,'fieldname','isdamage','format','Boolean')
+		if self.isdamage:
+			WriteData(fid,'object',self,'fieldname','D','format','DoubleMat','mattype',1)
+			WriteData(fid,'object',self,'fieldname','law','format','String')
+			WriteData(fid,'object',self,'fieldname','spcdamage','format','DoubleMat','mattype',1,'forcinglength',md.mesh.numberofvertices+1)
+			WriteData(fid,'object',self,'fieldname','max_damage','format','Double')
 
-		WriteData(fid,'object',self,'fieldname','stabilization','format','Integer');
-		WriteData(fid,'object',self,'fieldname','penalty_threshold','format','Integer');
-		WriteData(fid,'object',self,'fieldname','maxiter','format','Integer');
-		WriteData(fid,'object',self,'fieldname','penalty_lock','format','Integer');
-		WriteData(fid,'object',self,'fieldname','penalty_factor','format','Double');
+			WriteData(fid,'object',self,'fieldname','stabilization','format','Integer')
+			WriteData(fid,'object',self,'fieldname','elementinterp','format','String')
+			WriteData(fid,'object',self,'fieldname','penalty_threshold','format','Integer')
+			WriteData(fid,'object',self,'fieldname','maxiter','format','Integer')
+			WriteData(fid,'object',self,'fieldname','penalty_lock','format','Integer')
+			WriteData(fid,'object',self,'fieldname','penalty_factor','format','Double')
 
 		if self.law=='pralong':
@@ -142,3 +180,13 @@
 			WriteData(fid,'object',self,'fieldname','c4','format','Double')
 			WriteData(fid,'object',self,'fieldname','stress_threshold','format','Double')
+			WriteData(fid,'object',self,'fieldname','healing','format','Double')
+			WriteData(fid,'object',self,'fieldname','equiv_stress','format','Integer')
+			
+		#process requested outputs
+		outputs = self.requested_outputs
+		indices = [i for i, x in enumerate(outputs) if x == 'default']
+		if len(indices) > 0:
+			outputscopy=outputs[0:max(0,indices[0]-1)]+self.defaultoutputs(md)+outputs[indices[0]+1:]
+			outputs    =outputscopy
+		WriteData(fid,'data',outputs,'enum',DamageEvolutionRequestedOutputsEnum(),'format','StringArray')
 	# }}}
Index: /issm/trunk/src/m/classes/debug.m
===================================================================
--- /issm/trunk/src/m/classes/debug.m	(revision 17805)
+++ /issm/trunk/src/m/classes/debug.m	(revision 17806)
@@ -11,4 +11,11 @@
 	end
 	methods
+        function createxml(obj,fid) % {{{
+            fprintf(fid, '\n\n');
+            fprintf(fid, '%s\n', '<!-- Debug -->');
+			 fprintf(fid,'%s%s%s\n%s\n%s%s%s\n%s\n%s\n',    '<parameter key ="valgrind" type="',              class(obj.valgrind),'" optional="false">',              '     <section name="debug" />','        <option value="',convert2str(obj.valgrind),'" type="string" default="true"></option>','     <help> use Valgrind to debug (0 or 1) </help>','</parameter>');
+             fprintf(fid,'%s%s%s\n%s\n%s%s%s\n%s\n%s\n',    '<parameter key ="gprof" type="',              class(obj.gprof),'" optional="false">',              '     <section name="debug" />','        <option value="',convert2str(obj.gprof),'" type="string" default="true"></option>','     <help> use gnu-profiler to find out where the time is spent </help>','</parameter>');
+             fprintf(fid,'%s%s%s\n%s\n%s%s%s\n%s\n',    '<parameter key ="profiling" type="',              class(obj.profiling),'" optional="false">',              '     <section name="debug" />','        <option value="',convert2str(obj.profiling),'" type="string" default="true"></option>','     <help> enables profiling (memory, flops, time) </help>','</parameter>');
+        end % }}}
 		function obj = debug(varargin) % {{{
 			switch nargin
Index: /issm/trunk/src/m/classes/dependent.py
===================================================================
--- /issm/trunk/src/m/classes/dependent.py	(revision 17805)
+++ /issm/trunk/src/m/classes/dependent.py	(revision 17806)
@@ -1,10 +1,9 @@
 import os.path
 import numpy
-from pairoptions import *
-from fielddisplay import *
-from MatlabFuncs import *
+from pairoptions import pairoptions
+from fielddisplay import fielddisplay
+import MatlabFuncs as m
 from EnumDefinitions import *
-from WriteData import *
-from MeshProfileIntersection import *
+from MeshProfileIntersection import MeshProfileIntersection
 
 class dependent(object):
Index: /issm/trunk/src/m/classes/flaim.m
===================================================================
--- /issm/trunk/src/m/classes/flaim.m	(revision 17805)
+++ /issm/trunk/src/m/classes/flaim.m	(revision 17806)
@@ -21,4 +21,37 @@
 	end
 	methods
+  	 	function createxml(obj,fid) % {{{
+            fprintf(fid, '<!-- flaim -->\n');            
+                    
+            % Input
+            fprintf(fid,'%s\n%s\n%s\n','<frame key="1" label="Input:">','<section name="flaim" />');                    
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="targets" type="',class(obj.targets),'" default="',convert2str(obj.targets),'">','     <section name="flaim" />','     <help> name of kml output targets file </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="tracks" type="',class(obj.tracks),'" default="',convert2str(obj.tracks),'">','     <section name="flaim" />','     <help> name of kml input tracks file </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="flightreqs" type="',class(obj.flightreqs),'" default="',convert2str(obj.flightreqs),'">','     <section name="flaim" />','     <help> structure of kml flight requirements (not used yet) </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="criterion" type="',class(obj.criterion),'" default="',convert2str(obj.criterion),'">','     <section name="flaim" />','     <help> element or nodal criterion for flight path evaluation (metric) </help>','  </parameter>');
+        	fprintf(fid,'%s\n%s\n','</frame>');    
+            
+            % Arguments
+            fprintf(fid,'%s\n%s\n%s\n','<frame key="2" label="Arguments:">','<section name="flaim" />');                    
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="gridsatequator" type="',class(obj.gridsatequator),'" default="',convert2str(obj.gridsatequator),'">','     <section name="flaim" />','     <help> number of grids at equator (determines resolution) </help>','  </parameter>');
+            fprintf(fid,'%s%s%s\n%s\n%s%s%s\n%s\n%s\n','  <parameter key ="usevalueordering" type="',class(obj.usevalueordering),'" optional="false">','     <section name="flaim" />','         <option value="',convert2str(obj.usevalueordering),'" type="string" default="true"></option>','     <help> flag to consider target values for flight path evaluation </help>','  </parameter>');
+            fprintf(fid,'%s%s%s\n%s\n%s%s%s\n%s\n%s\n','  <parameter key ="split_antimeridian" type="',class(obj.split_antimeridian),'" optional="false">','     <section name="flaim" />','         <option value="',convert2str(obj.split_antimeridian),'" type="string" default="true"></option>','     <help> flag to split polygons on the antimeridian </help>','  </parameter>');
+            fprintf(fid,'%s\n%s\n','</frame>');   
+            
+            % Optimization
+            fprintf(fid,'%s\n%s\n%s\n','<frame key="3" label="Optimization:">','<section name="flaim" />');                    
+            fprintf(fid,'%s%s%s\n%s\n%s%s%s\n%s\n%s\n','  <parameter key ="path_optimize" type="',class(obj.path_optimize),'" optional="false">','     <section name="flaim" />','         <option value="',convert2str(obj.path_optimize),'" type="string" default="true"></option>','     <help> optimize? (default false) </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="opt_ndir" type="',class(obj.opt_ndir),'" default="',convert2str(obj.opt_ndir),'">','     <section name="flaim" />','     <help> number of directions to test when moving a point.  If this value = 1, a random direction is tested. A value > 1 results in directions equally spaced from [0, 2*PI] being tested. For example, 4 would result in directions [0, PI/2, PI, 3PI/2] </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="opt_dist" type="',class(obj.opt_dist),'" default="',convert2str(obj.opt_dist),'">','     <section name="flaim" />','     <help> specifies the distance in km (default 25) to move a randomly selected path point on each iteration </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="opt_niter" type="',class(obj.opt_niter),'" default="',convert2str(obj.opt_niter),'">','     <section name="flaim" />','     <help> number of iterations (default 30,000) to run for flightplan optimization, i.e. the number of times to randomly select a point and move it. </help>','  </parameter>');
+        	fprintf(fid,'%s\n%s\n','</frame>');     
+            
+            % Output
+            fprintf(fid,'%s\n%s\n%s\n','<frame key="4" label="Output:">','<section name="flaim" />');                    
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="solution" type="',class(obj.solution),'" default="',convert2str(obj.solution),'">','     <section name="flaim" />','     <help> name of kml solution file </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="quality" type="',class(obj.quality),'" default="',convert2str(obj.quality),'">','     <section name="flaim" />','     <help> quality of kml solution </help>','  </parameter>');
+            fprintf(fid,'%s\n%s\n','</frame>');              
+        
+        end % }}}
 		function obj = flaim(varargin) % {{{
 			switch nargin
@@ -37,9 +70,9 @@
 			if solution~=FlaimSolutionEnum(), return; end
 
-			md = checkfield(md,'flaim.tracks','file',1);
+			md = checkfield(md,'fieldname','flaim.tracks','file',1);
 			if any(isnan(md.flaim.criterion)) || isempty(md.flaim.criterion)
-				md = checkfield(md,'flaim.targets','file',1);
+				md = checkfield(md,'fieldname','flaim.targets','file',1);
 			else
-				md = checkfield(md,'flaim.criterion','numel',[md.mesh.numberofvertices md.mesh.numberofelements]);
+				md = checkfield(md,'fieldname','flaim.criterion','numel',[md.mesh.numberofvertices md.mesh.numberofelements]);
 			end
 
Index: /issm/trunk/src/m/classes/flaim.py
===================================================================
--- /issm/trunk/src/m/classes/flaim.py	(revision 17805)
+++ /issm/trunk/src/m/classes/flaim.py	(revision 17806)
@@ -3,6 +3,6 @@
 from fielddisplay import fielddisplay
 from EnumDefinitions import *
-from checkfield import *
-from WriteData import *
+from checkfield import checkfield
+from WriteData import WriteData
 
 class flaim(object):
@@ -63,9 +63,9 @@
 			return md
 
-		md = checkfield(md,'flaim.tracks','file',1)
+		md = checkfield(md,'fieldname','flaim.tracks','file',1)
 		if numpy.any(numpy.isnan(md.flaim.criterion)) or not md.flaim.criterion:
-			md = checkfield(md,'flaim.targets','file',1)
+			md = checkfield(md,'fieldname','flaim.targets','file',1)
 		else:
-			md = checkfield(md,'flaim.criterion','numel',[md.mesh.numberofvertices,md.mesh.numberofelements])
+			md = checkfield(md,'fieldname','flaim.criterion','numel',[md.mesh.numberofvertices,md.mesh.numberofelements])
 
 		return md
Index: /issm/trunk/src/m/classes/flowequation.m
===================================================================
--- /issm/trunk/src/m/classes/flowequation.m	(revision 17805)
+++ /issm/trunk/src/m/classes/flowequation.m	(revision 17806)
@@ -14,4 +14,6 @@
 		fe_HO            = '';
 		fe_FS            = '';
+		XTH_r            = 1.;
+		XTH_theta        = 0.;
 		vertex_equation  = NaN;
 		element_equation = NaN;
@@ -57,4 +59,27 @@
 	end
 	methods
+        function createxml(obj,fid) % {{{
+            fprintf(fid, '\n\n');
+            fprintf(fid, '%s\n', '<!-- flowequation -->');
+            fprintf(fid,'%s\n%s\n%s\n','<frame key="1" label="Flow equation parameters">','<section name="flowequation" />');                    
+            
+			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="isSIA" type="',              class(obj.isSIA),'" default="',                  convert2str(obj.isSIA),'">',              '     <section name="flowequation" />','     <help> is the Shallow Ice Approximation (SIA) used ? </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="isSSA" type="',            class(obj.isSSA),'" default="',                convert2str(obj.isSSA),'">',   '     <section name="flowequation" />','     <help> is the Shelfy-Stream Approximation (SSA) used ? </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',        '<parameter key ="isL1L2" type="',      class(obj.isL1L2),'" default="',          convert2str(obj.isL1L2),'">',            '     <section name="flowequation" />','     <help> is the L1L2 approximation used ? </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',        '<parameter key ="isHO" type="',     class(obj.isHO),'" default="',         convert2str(obj.isHO),'">',            '     <section name="flowequation" />','     <help> is the Higher-Order (HO) approximation used ? </help>','</parameter>');
+            
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="isFS" type="',       class(obj.isFS),'" default="',              convert2str(obj.isFS),'">',              '     <section name="flowequation" />','     <help> are the Full-FS (FS) equations used ? </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="fe_SSA" type="',             class(obj.fe_SSA),'" default="',   convert2str(obj.fe_SSA),'">',   '     <section name="flowequation" />','     <help> Finite Element for SSA  "P1", "P1bubble" "P1bubblecondensed" "P2" </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',        '<parameter key ="fe_HO" type="',        class(obj.fe_HO),'" default="',            convert2str(obj.fe_HO),'">',            '     <section name="flowequation" />','     <help> Finite Element for HO   "P1" "P1bubble" "P1bubblecondensed" "P1xP2" "P2xP1" "P2" </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',        '<parameter key ="fe_FS" type="',   class(obj.fe_FS),'" default="',            convert2str(obj.fe_FS),'">',            '     <section name="flowequation" />','     <help> Finite Element for FS   "P1P1" (debugging only) "P1P1GLS" "MINIcondensed" "MINI" "TaylorHood" </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',        '<parameter key ="vertex_equation" type="',      class(obj.vertex_equation),'" default="',            convert2str(obj.vertex_equation),'">',            '     <section name="flowequation" />','     <help> flow equation for each vertex </help>','</parameter>');
+       
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="element_equation" type="',            class(obj.element_equation),'" default="',              convert2str(obj.element_equation),'">',              '     <section name="flowequation" />','     <help> flow equation for each element </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="borderSSA" type="', class(obj.borderSSA),'" default="',   convert2str(obj.borderSSA),'">',   '     <section name="flowequation" />','     <help> vertices on SSAs border (for tiling) </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',        '<parameter key ="borderHO" type="',          class(obj.borderHO),'" default="',            convert2str(obj.borderHO),'">',            '     <section name="flowequation" />','     <help> vertices on HOs border (for tiling) </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n',        '<parameter key ="borderFS" type="',          class(obj.borderFS),'" default="',            convert2str(obj.borderFS),'">',            '     <section name="flowequation" />','     <help> vertices on FS border (for tiling) </help>','</parameter>');
+      
+            fprintf(fid,'%s\n%s\n','</frame>');
+        end % }}}
 		function obj = flowequation(varargin) % {{{
 			switch nargin
@@ -80,24 +105,26 @@
 			if ismember(StressbalanceAnalysisEnum(),analyses),
 
-				md = checkfield(md,'flowequation.isSIA','numel',[1],'values',[0 1]);
-				md = checkfield(md,'flowequation.isSSA','numel',[1],'values',[0 1]);
-				md = checkfield(md,'flowequation.isL1L2','numel',[1],'values',[0 1]);
-				md = checkfield(md,'flowequation.isHO','numel',[1],'values',[0 1]);
-				md = checkfield(md,'flowequation.isFS','numel',[1],'values',[0 1]);
-				md = checkfield(md,'flowequation.fe_SSA','values',{'P1','P1bubble','P1bubblecondensed','P2'});
-				md = checkfield(md,'flowequation.fe_HO' ,'values',{'P1','P1bubble','P1bubblecondensed','P1xP2','P2xP1','P2'});
-				md = checkfield(md,'flowequation.fe_FS' ,'values',{'P1P1','P1P1GLS','MINIcondensed','MINI','TaylorHood'});
-				md = checkfield(md,'flowequation.borderSSA','size',[md.mesh.numberofvertices 1],'values',[0 1]);
-				md = checkfield(md,'flowequation.borderHO','size',[md.mesh.numberofvertices 1],'values',[0 1]);
-				md = checkfield(md,'flowequation.borderFS','size',[md.mesh.numberofvertices 1],'values',[0 1]);
-				if strcmp(meshtype(md.mesh),'2Dhorizontal')
-					md = checkfield(md,'flowequation.vertex_equation','size',[md.mesh.numberofvertices 1],'values',[1:2]);
-					md = checkfield(md,'flowequation.element_equation','size',[md.mesh.numberofelements 1],'values',[1:2]);
-				elseif strcmp(meshtype(md.mesh),'2Dvertical')
-					md = checkfield(md,'flowequation.vertex_equation','size',[md.mesh.numberofvertices 1],'values',[4]);
-					md = checkfield(md,'flowequation.element_equation','size',[md.mesh.numberofelements 1],'values',[4]);
-				elseif strcmp(meshtype(md.mesh),'3D'),
-					md = checkfield(md,'flowequation.vertex_equation','size',[md.mesh.numberofvertices 1],'values',[0:8]);
-					md = checkfield(md,'flowequation.element_equation','size',[md.mesh.numberofelements 1],'values',[0:8]);
+				md = checkfield(md,'fieldname','flowequation.isSIA','numel',[1],'values',[0 1]);
+				md = checkfield(md,'fieldname','flowequation.isSSA','numel',[1],'values',[0 1]);
+				md = checkfield(md,'fieldname','flowequation.isL1L2','numel',[1],'values',[0 1]);
+				md = checkfield(md,'fieldname','flowequation.isHO','numel',[1],'values',[0 1]);
+				md = checkfield(md,'fieldname','flowequation.isFS','numel',[1],'values',[0 1]);
+				md = checkfield(md,'fieldname','flowequation.fe_SSA','values',{'P1','P1bubble','P1bubblecondensed','P2'});
+				md = checkfield(md,'fieldname','flowequation.fe_HO' ,'values',{'P1','P1bubble','P1bubblecondensed','P1xP2','P2xP1','P2','P1xP3','P2xP4'});
+				md = checkfield(md,'fieldname','flowequation.fe_FS' ,'values',{'P1P1','P1P1GLS','MINIcondensed','MINI','TaylorHood','XTaylorHood','OneLayerP4z'});
+				md = checkfield(md,'fieldname','flowequation.XTH_r','numel',[1],'>',0.);
+				md = checkfield(md,'fieldname','flowequation.XTH_theta','numel',[1],'>=',0.,'<',0.5);
+				md = checkfield(md,'fieldname','flowequation.borderSSA','size',[md.mesh.numberofvertices 1],'values',[0 1]);
+				md = checkfield(md,'fieldname','flowequation.borderHO','size',[md.mesh.numberofvertices 1],'values',[0 1]);
+				md = checkfield(md,'fieldname','flowequation.borderFS','size',[md.mesh.numberofvertices 1],'values',[0 1]);
+				if strcmp(domaintype(md.mesh),'2Dhorizontal')
+					md = checkfield(md,'fieldname','flowequation.vertex_equation','size',[md.mesh.numberofvertices 1],'values',[1:2]);
+					md = checkfield(md,'fieldname','flowequation.element_equation','size',[md.mesh.numberofelements 1],'values',[1:2]);
+				elseif strcmp(domaintype(md.mesh),'2Dvertical')
+					md = checkfield(md,'fieldname','flowequation.vertex_equation','size',[md.mesh.numberofvertices 1],'values',[2:4]);
+					md = checkfield(md,'fieldname','flowequation.element_equation','size',[md.mesh.numberofelements 1],'values',[2:4]);
+				elseif strcmp(domaintype(md.mesh),'3D'),
+					md = checkfield(md,'fieldname','flowequation.vertex_equation','size',[md.mesh.numberofvertices 1],'values',[0:8]);
+					md = checkfield(md,'fieldname','flowequation.element_equation','size',[md.mesh.numberofelements 1],'values',[0:8]);
 				else
 					error('Case not supported yet');
@@ -126,5 +153,5 @@
 			fielddisplay(obj,'fe_SSA','Finite Element for SSA  ''P1'', ''P1bubble'' ''P1bubblecondensed'' ''P2''');
 			fielddisplay(obj,'fe_HO', 'Finite Element for HO   ''P1'' ''P1bubble'' ''P1bubblecondensed'' ''P1xP2'' ''P2xP1'' ''P2''');
-			fielddisplay(obj,'fe_FS', 'Finite Element for FS   ''P1P1'' (debugging only) ''P1P1GLS'' ''MINIcondensed'' ''MINI'' ''TaylorHood''');
+			fielddisplay(obj,'fe_FS', 'Finite Element for FS   ''P1P1'' (debugging only) ''P1P1GLS'' ''MINIcondensed'' ''MINI'' ''TaylorHood'' ''XTaylorHood''');
 			fielddisplay(obj,'vertex_equation','flow equation for each vertex');
 			fielddisplay(obj,'element_equation','flow equation for each element');
@@ -143,4 +170,6 @@
 			WriteData(fid,'enum',FlowequationFeHOEnum() ,'data',StringToEnum(obj.fe_HO) ,'format','Integer');
 			WriteData(fid,'enum',FlowequationFeFSEnum() ,'data',StringToEnum(obj.fe_FS) ,'format','Integer');
+			WriteData(fid,'enum',AugmentedLagrangianREnum() ,'data',obj.XTH_r ,'format','Double');
+			WriteData(fid,'enum',AugmentedLagrangianThetaEnum() ,'data',obj.XTH_theta ,'format','Double');
 			WriteData(fid,'object',obj,'fieldname','borderSSA','format','DoubleMat','mattype',1);
 			WriteData(fid,'object',obj,'fieldname','borderHO','format','DoubleMat','mattype',1);
Index: /issm/trunk/src/m/classes/flowequation.py
===================================================================
--- /issm/trunk/src/m/classes/flowequation.py	(revision 17805)
+++ /issm/trunk/src/m/classes/flowequation.py	(revision 17806)
@@ -3,6 +3,7 @@
 from fielddisplay import fielddisplay
 from EnumDefinitions import *
-from checkfield import *
-from WriteData import *
+from checkfield import checkfield
+from WriteData import WriteData
+import MatlabFuncs as m
 
 class flowequation(object):
@@ -24,4 +25,6 @@
 		self.fe_HO            = ''
 		self.fe_FS            = ''
+		self.XTH_r            = 1.
+		self.XTH_theta        = 0.
 		self.vertex_equation  = float('NaN')
 		self.element_equation = float('NaN')
@@ -44,5 +47,5 @@
 		string="%s\n%s"%(string,fielddisplay(self,'fe_SSA',"Finite Element for SSA: 'P1', 'P1bubble' 'P1bubblecondensed' 'P2'"))
 		string="%s\n%s"%(string,fielddisplay(self,'fe_HO' ,"Finite Element for HO:  'P1' 'P1bubble' 'P1bubblecondensed' 'P1xP2' 'P2xP1' 'P2'"))
-		string="%s\n%s"%(string,fielddisplay(self,'fe_FS' ,"Finite Element for FS:  'P1P1' (debugging only) 'P1P1GLS' 'MINIcondensed' 'MINI' 'TaylorHood'"))
+		string="%s\n%s"%(string,fielddisplay(self,'fe_FS' ,"Finite Element for FS:  'P1P1' (debugging only) 'P1P1GLS' 'MINIcondensed' 'MINI' 'TaylorHood' 'XTaylorHood'"))
 		string="%s\n%s"%(string,fielddisplay(self,'vertex_equation',"flow equation for each vertex"))
 		string="%s\n%s"%(string,fielddisplay(self,'element_equation',"flow equation for each element"))
@@ -68,21 +71,23 @@
 
 		if StressbalanceAnalysisEnum() in analyses:
-			md = checkfield(md,'flowequation.isSIA','numel',[1],'values',[0,1])
-			md = checkfield(md,'flowequation.isSSA','numel',[1],'values',[0,1])
-			md = checkfield(md,'flowequation.isL1L2','numel',[1],'values',[0,1])
-			md = checkfield(md,'flowequation.isHO','numel',[1],'values',[0,1])
-			md = checkfield(md,'flowequation.isFS','numel',[1],'values',[0,1])
-			md = checkfield(md,'flowequation.fe_SSA','values',['P1','P1bubble','P1bubblecondensed','P2'])
-			md = checkfield(md,'flowequation.fe_HO' ,'values',['P1','P1bubble','P1bubblecondensed','P1xP2','P2xP1','P2'])
-			md = checkfield(md,'flowequation.fe_FS' ,'values',['P1P1','P1P1GLS','MINIcondensed','MINI','TaylorHood'])
-			md = checkfield(md,'flowequation.borderSSA','size',[md.mesh.numberofvertices],'values',[0,1])
-			md = checkfield(md,'flowequation.borderHO','size',[md.mesh.numberofvertices],'values',[0,1])
-			md = checkfield(md,'flowequation.borderFS','size',[md.mesh.numberofvertices],'values',[0,1])
-			if strcmp(md.mesh.meshtype(),'2Dhorizontal'):
-				md = checkfield(md,'flowequation.vertex_equation','size',[md.mesh.numberofvertices],'values',[1,2])
-				md = checkfield(md,'flowequation.element_equation','size',[md.mesh.numberofelements],'values',[1,2])
-			elif strcmp(md.mesh.meshtype(),'3D'):
-				md = checkfield(md,'flowequation.vertex_equation','size',[md.mesh.numberofvertices],'values',numpy.arange(0,8+1))
-				md = checkfield(md,'flowequation.element_equation','size',[md.mesh.numberofelements],'values',numpy.arange(0,8+1))
+			md = checkfield(md,'fieldname','flowequation.isSIA','numel',[1],'values',[0,1])
+			md = checkfield(md,'fieldname','flowequation.isSSA','numel',[1],'values',[0,1])
+			md = checkfield(md,'fieldname','flowequation.isL1L2','numel',[1],'values',[0,1])
+			md = checkfield(md,'fieldname','flowequation.isHO','numel',[1],'values',[0,1])
+			md = checkfield(md,'fieldname','flowequation.isFS','numel',[1],'values',[0,1])
+			md = checkfield(md,'fieldname','flowequation.fe_SSA','values',['P1','P1bubble','P1bubblecondensed','P2'])
+			md = checkfield(md,'fieldname','flowequation.fe_HO' ,'values',['P1','P1bubble','P1bubblecondensed','P1xP2','P2xP1','P2','P1xP3','P2xP4'])
+			md = checkfield(md,'fieldname','flowequation.fe_FS' ,'values',['P1P1','P1P1GLS','MINIcondensed','MINI','TaylorHood','XTaylorHood','OneLayerP4z'])
+			md = checkfield(md,'fieldname','flowequation.borderSSA','size',[md.mesh.numberofvertices],'values',[0,1])
+			md = checkfield(md,'fieldname','flowequation.borderHO','size',[md.mesh.numberofvertices],'values',[0,1])
+			md = checkfield(md,'fieldname','flowequation.borderFS','size',[md.mesh.numberofvertices],'values',[0,1])
+			md = checkfield(md,'fieldname','flowequation.XTH_r','numel',[1],'>',0.)
+			md = checkfield(md,'fieldname','flowequation.XTH_theta','numel',[1],'>=',0.,'<',.5)
+			if m.strcmp(md.mesh.domaintype(),'2Dhorizontal'):
+				md = checkfield(md,'fieldname','flowequation.vertex_equation','size',[md.mesh.numberofvertices],'values',[1,2])
+				md = checkfield(md,'fieldname','flowequation.element_equation','size',[md.mesh.numberofelements],'values',[1,2])
+			elif m.strcmp(md.mesh.domaintype(),'3D'):
+				md = checkfield(md,'fieldname','flowequation.vertex_equation','size',[md.mesh.numberofvertices],'values',numpy.arange(0,8+1))
+				md = checkfield(md,'fieldname','flowequation.element_equation','size',[md.mesh.numberofelements],'values',numpy.arange(0,8+1))
 			else:
 				raise RuntimeError('mesh type not supported yet')
@@ -106,4 +111,6 @@
 		WriteData(fid,'enum',FlowequationFeHOEnum() ,'data',StringToEnum(self.fe_HO)[0] ,'format','Integer')
 		WriteData(fid,'enum',FlowequationFeFSEnum() ,'data',StringToEnum(self.fe_FS)[0] ,'format','Integer')
+		WriteData(fid,'enum',AugmentedLagrangianREnum() ,'data',self.XTH_r ,'format','Double')
+		WriteData(fid,'enum',AugmentedLagrangianThetaEnum() ,'data',self.XTH_theta ,'format','Double')
 		WriteData(fid,'object',self,'fieldname','borderSSA','format','DoubleMat','mattype',1)
 		WriteData(fid,'object',self,'fieldname','borderHO','format','DoubleMat','mattype',1)
Index: /issm/trunk/src/m/classes/friction.m
===================================================================
--- /issm/trunk/src/m/classes/friction.m	(revision 17805)
+++ /issm/trunk/src/m/classes/friction.m	(revision 17806)
@@ -11,4 +11,13 @@
 	end
 	methods
+        function createxml(obj,fid) % {{{
+            fprintf(fid, '\n\n');
+            fprintf(fid, '%s\n', '<!-- Friction: Sigma= drag^2 * Neff ^r * u ^s, with Neff=rho_ice*g*thickness+rho_water*g*bed, r=q/p and s=1/p -->');
+            fprintf(fid,'%s\n%s\n%s\n','<frame key="1" label="Friction: Sigma= drag^2 * Neff ^r * u ^s, with Neff=rho_ice*g*thickness+rho_water*g*bed, r=q/p and s=1/p">','<section name="friction" />');   
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="coefficient" type="',   	class(obj.coefficient),'" default="',     	convert2str(obj.coefficient),'">',              '     <section name="friction" />','     <help> friction coefficient [SI] </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="p" type="',               class(obj.p),'" default="',                 convert2str(obj.p),'">',   '     <section name="friction" />','     <help> p exponent </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n',        '<parameter key ="q" type="',               class(obj.q),'" default="',                 convert2str(obj.q),'">',            '     <section name="friction" />','     <help> q exponent </help>','</parameter>');
+            fprintf(fid,'%s\n%s\n','</frame>');
+        end % }}}
 		function obj = friction(varargin) % {{{
 			switch nargin
@@ -26,8 +35,7 @@
 			%Early return
 			if ~ismember(StressbalanceAnalysisEnum(),analyses) & ~ismember(ThermalAnalysisEnum(),analyses), return; end
-
-			md = checkfield(md,'friction.coefficient','NaN',1,'size',[md.mesh.numberofvertices 1]);
-			md = checkfield(md,'friction.q','NaN',1,'size',[md.mesh.numberofelements 1]);
-			md = checkfield(md,'friction.p','NaN',1,'size',[md.mesh.numberofelements 1]);
+			md = checkfield(md,'fieldname','friction.coefficient','forcing',1,'NaN',1);
+			md = checkfield(md,'fieldname','friction.q','NaN',1,'size',[md.mesh.numberofelements 1]);
+			md = checkfield(md,'fieldname','friction.p','NaN',1,'size',[md.mesh.numberofelements 1]);
 		end % }}}
 		function disp(obj) % {{{
@@ -38,7 +46,12 @@
 		end % }}}
 		function marshall(obj,md,fid) % {{{
-			WriteData(fid,'object',obj,'fieldname','coefficient','format','DoubleMat','mattype',1);
+			yts=365.0*24.0*3600.0;
+
+			WriteData(fid,'object',obj,'fieldname','coefficient','format','DoubleMat','mattype',1,'forcinglength',md.mesh.numberofvertices+1);
+			%WriteData(fid,'object',obj,'fieldname','coefficient','format','DoubleMat','mattype',1);
 			WriteData(fid,'object',obj,'fieldname','p','format','DoubleMat','mattype',2);
 			WriteData(fid,'object',obj,'fieldname','q','format','DoubleMat','mattype',2);
+			
+
 		end % }}}
 	end
Index: /issm/trunk/src/m/classes/friction.py
===================================================================
--- /issm/trunk/src/m/classes/friction.py	(revision 17805)
+++ /issm/trunk/src/m/classes/friction.py	(revision 17806)
@@ -1,6 +1,6 @@
 from fielddisplay import fielddisplay
 from EnumDefinitions import *
-from checkfield import *
-from WriteData import *
+from checkfield import checkfield
+from WriteData import WriteData
 
 class friction(object):
@@ -38,7 +38,7 @@
 			return md
 
-		md = checkfield(md,'friction.coefficient','NaN',1,'size',[md.mesh.numberofvertices])
-		md = checkfield(md,'friction.q','NaN',1,'size',[md.mesh.numberofelements])
-		md = checkfield(md,'friction.p','NaN',1,'size',[md.mesh.numberofelements])
+		md = checkfield(md,'fieldname','friction.coefficient','forcing',1,'NaN',1)
+		md = checkfield(md,'fieldname','friction.q','NaN',1,'size',[md.mesh.numberofelements])
+		md = checkfield(md,'fieldname','friction.p','NaN',1,'size',[md.mesh.numberofelements])
 
 		return md
Index: /issm/trunk/src/m/classes/geometry.m
===================================================================
--- /issm/trunk/src/m/classes/geometry.m	(revision 17805)
+++ /issm/trunk/src/m/classes/geometry.m	(revision 17806)
@@ -8,9 +8,40 @@
 		surface           = NaN;
 		thickness         = NaN;
+		base              = NaN;
 		bed               = NaN;
-		bathymetry        = NaN;
 		hydrostatic_ratio = NaN;
 	end
+	methods (Static)
+		function obj = loadobj(obj) % {{{
+			% This function is directly called by matlab when a model object is
+			% loaded. Update old properties here
+
+			%2014 March 26th
+			if isstruct(obj),
+				disp('WARNING: updating geometry');
+				disp('         md.geometry.bed        is now md.geometry.base');
+				disp('         md.geometry.bathymetry is now md.geometry.bed');
+				obj2=obj;
+				obj=geometry();
+				obj.surface    = obj2.surface;
+				obj.thickness  = obj2.thickness;
+				obj.base       = obj2.bed;
+				obj.bed        = obj2.bathymetry;
+			end
+
+		end% }}}
+	end
 	methods
+        function createxml(obj,fid) % {{{
+            fprintf(fid, '\n\n');
+            fprintf(fid, '%s\n', '<!-- geometry -->');
+            fprintf(fid,'%s\n%s\n%s\n','<frame key="1" label="Geometry parameters">','<section name="geometry" />'); 
+			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="surface" type="','path','" optional="','false','">','     <section name="geometry" />','     <help> surface elevation [m] </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="thickness" type="','path','" optional="','false','">','     <section name="geometry" />','     <help> ice thickness [m] </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="bed" type="','path','" optional="','false','">','     <section name="geometry" />','     <help> bed elevation [m] </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="bathymetry" type="',class(obj.bathymetry),'" default="',convert2str(obj.bathymetry),'">','     <section name="geometry" />','     <help> bathymetry elevation [m] </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n','<parameter key ="hydrostatic_ratio" type="',class(obj.hydrostatic_ratio),'" default="',convert2str(obj.hydrostatic_ratio),'">','     <section name="geometry" />','     <help> coefficient for ice shelves; thickness correction: hydrostatic_ratio H_obs+ (1-hydrostatic_ratio) H_hydro </help>','</parameter>');
+            fprintf(fid,'%s\n%s\n','</frame>');
+        end % }}}
 		function obj = geometry(varargin) % {{{
 			switch nargin
@@ -27,14 +58,14 @@
 
 			if (solution==TransientSolutionEnum() & md.transient.isgia) | (solution==GiaSolutionEnum()),
-				md = checkfield(md,'geometry.thickness','forcing',1,'NaN',1,'>=',0);
+				md = checkfield(md,'fieldname','geometry.thickness','forcing',1,'NaN',1,'>=',0);
 			else
-				md = checkfield(md,'geometry.surface'  ,'NaN',1,'size',[md.mesh.numberofvertices 1]);
-				md = checkfield(md,'geometry.bed'      ,'NaN',1,'size',[md.mesh.numberofvertices 1]);
-				md = checkfield(md,'geometry.thickness','NaN',1,'size',[md.mesh.numberofvertices 1],'>',0);
-				if any((obj.thickness-obj.surface+obj.bed)>10^-9),
-					md = checkmessage(md,['equality thickness=surface-bed violated']);
+				md = checkfield(md,'fieldname','geometry.surface'  ,'NaN',1,'size',[md.mesh.numberofvertices 1]);
+				md = checkfield(md,'fieldname','geometry.base'      ,'NaN',1,'size',[md.mesh.numberofvertices 1]);
+				md = checkfield(md,'fieldname','geometry.thickness','NaN',1,'size',[md.mesh.numberofvertices 1],'>',0);
+				if any((obj.thickness-obj.surface+obj.base)>10^-9),
+					md = checkmessage(md,['equality thickness=surface-base violated']);
 				end 
 				if solution==TransientSolutionEnum() & md.transient.isgroundingline,
-					md = checkfield(md,'geometry.bathymetry','NaN',1,'size',[md.mesh.numberofvertices 1]);
+					md = checkfield(md,'fieldname','geometry.bed','NaN',1,'size',[md.mesh.numberofvertices 1]);
 				end
 			end
@@ -43,9 +74,8 @@
 			disp(sprintf('   geometry parameters:'));
 
-			fielddisplay(obj,'surface','surface elevation [m]');
+			fielddisplay(obj,'surface','ice upper surface elevation [m]');
 			fielddisplay(obj,'thickness','ice thickness [m]');
+			fielddisplay(obj,'base','ice base elevation [m]');
 			fielddisplay(obj,'bed','bed elevation [m]');
-			fielddisplay(obj,'bathymetry','bathymetry elevation [m]');
-			fielddisplay(obj,'hydrostatic_ratio','coefficient for ice shelves'' thickness correction: hydrostatic_ratio H_obs+ (1-hydrostatic_ratio) H_hydro');
 
 		end % }}}
@@ -53,6 +83,6 @@
 			WriteData(fid,'data',obj.surface,'format','DoubleMat','mattype',1,'enum',SurfaceEnum());
 			WriteData(fid,'data',obj.thickness,'format','DoubleMat','mattype',1,'enum',ThicknessEnum(),'forcinglength',md.mesh.numberofvertices+1);
+			WriteData(fid,'data',obj.base,'format','DoubleMat','mattype',1,'enum',BaseEnum());
 			WriteData(fid,'data',obj.bed,'format','DoubleMat','mattype',1,'enum',BedEnum());
-			WriteData(fid,'data',obj.bathymetry,'format','DoubleMat','mattype',1,'enum',BathymetryEnum());
 			WriteData(fid,'object',obj,'fieldname','hydrostatic_ratio','format','DoubleMat','mattype',1);
 		end % }}}
Index: /issm/trunk/src/m/classes/geometry.py
===================================================================
--- /issm/trunk/src/m/classes/geometry.py	(revision 17805)
+++ /issm/trunk/src/m/classes/geometry.py	(revision 17806)
@@ -1,6 +1,6 @@
 from fielddisplay import fielddisplay
 from EnumDefinitions import *
-from checkfield import *
-from WriteData import *
+from checkfield import checkfield
+from WriteData import WriteData
 
 class geometry(object):
@@ -15,6 +15,6 @@
 		self.surface           = float('NaN')
 		self.thickness         = float('NaN')
-		self.bed               = float('NaN')
-		self.bathymetry        = float('NaN')
+		self.base               = float('NaN')
+		self.bed        = float('NaN')
 		self.hydrostatic_ratio = float('NaN')
 
@@ -26,9 +26,8 @@
 
 		string="   geometry parameters:"
-		string="%s\n%s"%(string,fielddisplay(self,'surface','surface elevation [m]'))
+		string="%s\n%s"%(string,fielddisplay(self,'surface','ice upper surface elevation [m]'))
 		string="%s\n%s"%(string,fielddisplay(self,'thickness','ice thickness [m]'))
+		string="%s\n%s"%(string,fielddisplay(self,'base','ice base elevation [m]'))
 		string="%s\n%s"%(string,fielddisplay(self,'bed','bed elevation [m]'))
-		string="%s\n%s"%(string,fielddisplay(self,'bathymetry','bathymetry elevation [m]'))
-		string="%s\n%s"%(string,fielddisplay(self,'hydrostatic_ratio','coefficient for ice shelves'' thickness correction: hydrostatic_ratio H_obs+ (1-hydrostatic_ratio) H_hydro'))
 		return string
 		#}}}
@@ -38,11 +37,11 @@
 	def checkconsistency(self,md,solution,analyses):    # {{{
 
-		md = checkfield(md,'geometry.surface'  ,'NaN',1,'size',[md.mesh.numberofvertices])
-		md = checkfield(md,'geometry.bed'      ,'NaN',1,'size',[md.mesh.numberofvertices])
-		md = checkfield(md,'geometry.thickness','NaN',1,'size',[md.mesh.numberofvertices],'>',0,'forcing',1)
-		if any((self.thickness-self.surface+self.bed)>10**-9):
-			md.checkmessage("equality thickness=surface-bed violated")
+		md = checkfield(md,'fieldname','geometry.surface'  ,'NaN',1,'size',[md.mesh.numberofvertices])
+		md = checkfield(md,'fieldname','geometry.base'      ,'NaN',1,'size',[md.mesh.numberofvertices])
+		md = checkfield(md,'fieldname','geometry.thickness','NaN',1,'size',[md.mesh.numberofvertices],'>',0,'forcing',1)
+		if any((self.thickness-self.surface+self.base)>10**-9):
+			md.checkmessage("equality thickness=surface-base violated")
 		if solution==TransientSolutionEnum() and md.transient.isgroundingline:
-			md = checkfield(md,'geometry.bathymetry','NaN',1,'size',[md.mesh.numberofvertices])
+			md = checkfield(md,'fieldname','geometry.bed','NaN',1,'size',[md.mesh.numberofvertices])
 
 		return md
@@ -51,6 +50,6 @@
 		WriteData(fid,'data',self.surface,'format','DoubleMat','mattype',1,'enum',SurfaceEnum())
 		WriteData(fid,'data',self.thickness,'format','DoubleMat','mattype',1,'enum',ThicknessEnum(),'forcinglength',md.mesh.numberofvertices+1)
+		WriteData(fid,'data',self.base,'format','DoubleMat','mattype',1,'enum',BaseEnum())
 		WriteData(fid,'data',self.bed,'format','DoubleMat','mattype',1,'enum',BedEnum())
-		WriteData(fid,'data',self.bathymetry,'format','DoubleMat','mattype',1,'enum',BathymetryEnum())
 		WriteData(fid,'object',self,'fieldname','hydrostatic_ratio','format','DoubleMat','mattype',1)
 	# }}}
Index: /issm/trunk/src/m/classes/gia.m
===================================================================
--- /issm/trunk/src/m/classes/gia.m	(revision 17805)
+++ /issm/trunk/src/m/classes/gia.m	(revision 17806)
@@ -11,4 +11,15 @@
 	end
 	methods
+         function createxml(obj,fid) % {{{
+            fprintf(fid, '<!-- gia -->\n');            
+                    
+            % gia solution parameters
+            fprintf(fid,'%s\n%s\n%s\n','<frame key="1" label="gia parameters">','<section name="gia" />');                    
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="mantle_viscosity" type="',class(obj.mantle_viscosity),'" default="',convert2str(obj.mantle_viscosity),'">','     <section name="gia" />','     <help> mantle viscosity[Pa s] </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="lithosphere_thickness" type="',class(obj.lithosphere_thickness),'" default="',convert2str(obj.lithosphere_thickness),'">','     <section name="gia" />','     <help> lithosphere thickness (km) </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="cross_section_shape" type="',class(obj.cross_section_shape),'" default="',convert2str(obj.cross_section_shape),'">','     <section name="gia" />','     <help> 1: square-edged (default). 2: elliptical.  See iedge in GiaDeflectionCore </help>','  </parameter>');
+            fprintf(fid,'%s\n%s\n','</frame>');    
+        
+        end % }}}
 		function obj = gia(varargin) % {{{
 			switch nargin
@@ -25,7 +36,7 @@
 
 			if ~ismember(GiaAnalysisEnum(),analyses), return; end
-			md = checkfield(md,'gia.mantle_viscosity','NaN',1,'size',[md.mesh.numberofvertices 1],'>',0);
-			md = checkfield(md,'gia.lithosphere_thickness','NaN',1,'size',[md.mesh.numberofvertices 1],'>',0);
-			md = checkfield(md,'gia.cross_section_shape','numel',[1],'values',[1,2]);
+			md = checkfield(md,'fieldname','gia.mantle_viscosity','NaN',1,'size',[md.mesh.numberofvertices 1],'>',0);
+			md = checkfield(md,'fieldname','gia.lithosphere_thickness','NaN',1,'size',[md.mesh.numberofvertices 1],'>',0);
+			md = checkfield(md,'fieldname','gia.cross_section_shape','numel',[1],'values',[1,2]);
 
 			%be sure that if we are running a masstransport ice flow model coupled with gia, that thickness forcings 
Index: /issm/trunk/src/m/classes/gia.py
===================================================================
--- /issm/trunk/src/m/classes/gia.py	(revision 17805)
+++ /issm/trunk/src/m/classes/gia.py	(revision 17806)
@@ -1,6 +1,6 @@
 from fielddisplay import fielddisplay
 from EnumDefinitions import *
-from checkfield import *
-from WriteData import *
+from checkfield import checkfield
+from WriteData import WriteData
 
 class gia(object):
@@ -42,7 +42,7 @@
 			return md 
 		
-		md = checkfield(md,'gia.mantle_viscosity','NaN',1,'size',[md.mesh.numberofvertices,1],'>',0)
-		md = checkfield(md,'gia.lithosphere_thickness','NaN',1,'size',[md.mesh.numberofvertices,1],'>',0)
-		md = checkfield(md,'gia.cross_section_shape','numel',[1],'values',[1,2])
+		md = checkfield(md,'fieldname','gia.mantle_viscosity','NaN',1,'size',[md.mesh.numberofvertices,1],'>',0)
+		md = checkfield(md,'fieldname','gia.lithosphere_thickness','NaN',1,'size',[md.mesh.numberofvertices,1],'>',0)
+		md = checkfield(md,'fieldname','gia.cross_section_shape','numel',[1],'values',[1,2])
 
 		#be sure that if we are running a masstransport ice flow model coupled with gia, that thickness forcings 
Index: /issm/trunk/src/m/classes/groundingline.m
===================================================================
--- /issm/trunk/src/m/classes/groundingline.m	(revision 17805)
+++ /issm/trunk/src/m/classes/groundingline.m	(revision 17806)
@@ -10,4 +10,14 @@
 	end
 	methods
+         function createxml(obj,fid) % {{{
+            fprintf(fid, '\n\n');
+            fprintf(fid, '%s\n', '<!-- groundingline -->');
+            
+            % Convergence criteria          
+            fprintf(fid,'%s\n%s\n%s\n','<frame key="1" label="Grounding line migration parameters">','<section name="groundingline" />');  
+			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="migration" type="',      class(obj.migration),'" default="',        convert2str(obj.migration),'">',	'     <section name="groundingline" />','     <help> type of grounding line migration: "SoftMigration","AgressiveMigration" or "None" </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n',    '<parameter key ="melting_rate" type="',          class(obj.melting_rate),'" default="',            convert2str(obj.melting_rate),'">',     '     <section name="groundingline" />','     <help> melting rate applied when previously grounded parts start floating [m/yr] </help>','</parameter>');
+            fprintf(fid,'%s\n%s\n','</frame>');
+        end % }}}
 		function obj = groundingline(varargin) % {{{
 			switch nargin
@@ -29,16 +39,15 @@
 		function md = checkconsistency(obj,md,solution,analyses) % {{{
 
-			md = checkfield(md,'groundingline.migration','values',{'None' 'AgressiveMigration' 'SoftMigration' 'SubelementMigration','SubelementMigration2'});
+			md = checkfield(md,'fieldname','groundingline.migration','values',{'None' 'AgressiveMigration' 'SoftMigration' 'SubelementMigration','SubelementMigration2' 'Contact'});
 
 			if ~strcmp(obj.migration,'None'),
-				if isnan(md.geometry.bathymetry),
+				if isnan(md.geometry.bed),
 					md = checkmessage(md,['requesting grounding line migration, but bathymetry is absent!']);
 				end
 				pos=find(md.mask.groundedice_levelset>0.);
-				if any(abs(md.geometry.bed(pos)-md.geometry.bathymetry(pos))>10^-10),
+				if any(abs(md.geometry.base(pos)-md.geometry.bed(pos))>10^-10),
 					md = checkmessage(md,['bathymetry not equal to bed on grounded ice!']);
 				end
-				pos=find(md.mask.groundedice_levelset<0.);
-				if any(md.geometry.bathymetry(pos)-md.geometry.bed(pos)>10^-9),
+				if any(md.geometry.bed - md.geometry.base > 10^-9),
 					md = checkmessage(md,['bathymetry superior to bed on floating ice!']);
 				end
Index: /issm/trunk/src/m/classes/groundingline.py
===================================================================
--- /issm/trunk/src/m/classes/groundingline.py	(revision 17805)
+++ /issm/trunk/src/m/classes/groundingline.py	(revision 17806)
@@ -3,7 +3,7 @@
 from EnumDefinitions import *
 from StringToEnum import StringToEnum
-from checkfield import *
-from WriteData import *
-from MatlabFuncs import *
+from checkfield import checkfield
+from WriteData import WriteData
+import MatlabFuncs as m
 
 class groundingline(object):
@@ -42,14 +42,13 @@
 	def checkconsistency(self,md,solution,analyses):    # {{{
 
-		md = checkfield(md,'groundingline.migration','values',['None','AgressiveMigration','SoftMigration','SubelementMigration','SubelementMigration2'])
+		md = checkfield(md,'fieldname','groundingline.migration','values',['None','AgressiveMigration','SoftMigration','SubelementMigration','SubelementMigration2','Contact'])
 
-		if not strcmp(self.migration,'None'):
-			if numpy.any(numpy.isnan(md.geometry.bathymetry)):
+		if not m.strcmp(self.migration,'None'):
+			if numpy.any(numpy.isnan(md.geometry.bed)):
 				md.checkmessage("requesting grounding line migration, but bathymetry is absent!")
 			pos=numpy.nonzero(md.mask.groundedice_levelset>0.)[0]
-			if any(numpy.abs(md.geometry.bed[pos]-md.geometry.bathymetry[pos])>10**-10):
+			if any(numpy.abs(md.geometry.base[pos]-md.geometry.bed[pos])>10**-10):
 				md.checkmessage("bathymetry not equal to bed on grounded ice!")
-			pos=numpy.nonzero(md.mask.groundedice_levelset<0.)[0]
-			if any(md.geometry.bathymetry[pos]-md.geometry.bed[pos]>10**-9):
+			if any(md.geometry.bed - md.geometry.base > 10**-9):
 				md.checkmessage("bathymetry superior to bed on floating ice!")
 
Index: /issm/trunk/src/m/classes/hydrologydc.m
===================================================================
--- /issm/trunk/src/m/classes/hydrologydc.m	(revision 17805)
+++ /issm/trunk/src/m/classes/hydrologydc.m	(revision 17806)
@@ -9,22 +9,27 @@
 		isefficientlayer         = 0;
 		penalty_factor           = 0;
+		penalty_lock             = 0;
 		rel_tol                  = 0;
+		max_iter                 = 0;
 		sedimentlimit_flag       = 0;
 		sedimentlimit            = 0;
 		transfer_flag            = 0;
 		leakage_factor           = 0;
+		basal_moulin_input       = NaN;
 
 		spcsediment_head         = NaN;
+		sediment_transmitivity   = NaN;
 		sediment_compressibility = 0;
 		sediment_porosity        = 0;
 		sediment_thickness       = 0;
-		sediment_transmitivity   = 0;
+
 
 		spcepl_head              = NaN;
-		mask_eplactive           = NaN;
+		mask_eplactive_node      = NaN;
 		epl_compressibility      = 0;
 		epl_porosity             = 0;
-		epl_thickness            = 0;
-		epl_transmitivity        = 0;
+		epl_initial_thickness    = 0;
+		epl_max_thickness    = 0;
+		epl_conductivity         = 0;
   end
 	methods
@@ -39,12 +44,20 @@
 		end 
 		% }}}
+		function self = initialize(self,md) % {{{
+			if isnan(self.basal_moulin_input),
+				self.basal_moulin_input=zeros(md.mesh.numberofvertices,1);
+				disp('      no hydrology.basal_moulin_input specified: values set as zero');
+			end
+
+		end % }}}
 		% {{{ function obj = setdefaultparameters(obj) 
 		function obj = setdefaultparameters(obj) 
 
-		%Parameters from de Fleurian 2013
+		%Parameters from de Fleurian 2014
 			obj.water_compressibility    = 5.04e-10;
 			obj.isefficientlayer         = 1;
 			obj.penalty_factor           = 3;
 			obj.rel_tol                  = 1.0e-06;
+			obj.max_iter                 = 100;
 			obj.sedimentlimit_flag       = 0;
 			obj.sedimentlimit            = 0;
@@ -59,6 +72,7 @@
 			obj.epl_compressibility      = 1.0e-08;
 			obj.epl_porosity             = 0.4;
-			obj.epl_thickness            = 1.0;
-			obj.epl_transmitivity        = 8.0e-02;
+			obj.epl_initial_thickness    = 1.0;
+			obj.epl_max_thickness    = 5.0;
+			obj.epl_conductivity         = 8.0e-02;
 
 		end 
@@ -71,30 +85,33 @@
 			end
 
-			md = checkfield(md,'hydrology.water_compressibility','>',0,'numel',1);
-			md = checkfield(md,'hydrology.isefficientlayer','numel',[1],'values',[0 1]);
-			md = checkfield(md,'hydrology.penalty_factor','>',0,'numel',1);
-			md = checkfield(md,'hydrology.rel_tol','>',0,'numel',1);
-			md = checkfield(md,'hydrology.sedimentlimit_flag','numel',[1],'values',[0 1 2 3]);
-			md = checkfield(md,'hydrology.transfer_flag','numel',[1],'values',[0 1]);
+			md = checkfield(md,'fieldname','hydrology.water_compressibility','>',0,'numel',1);
+			md = checkfield(md,'fieldname','hydrology.isefficientlayer','numel',[1],'values',[0 1]);
+			md = checkfield(md,'fieldname','hydrology.penalty_factor','>',0,'numel',1);
+			md = checkfield(md,'fieldname','hydrology.rel_tol','>',0,'numel',1);
+			md = checkfield(md,'fieldname','hydrology.max_iter','>',0,'numel',1);
+			md = checkfield(md,'fieldname','hydrology.sedimentlimit_flag','numel',[1],'values',[0 1 2 3]);
+			md = checkfield(md,'fieldname','hydrology.transfer_flag','numel',[1],'values',[0 1]);
 			if obj.sedimentlimit_flag==1,
-				md = checkfield(md,'hydrology.sedimentlimit','>',0,'numel',1);
+				md = checkfield(md,'fieldname','hydrology.sedimentlimit','>',0,'numel',1);
 	    end
 			if obj.transfer_flag==1,
-				md = checkfield(md,'hydrology.leakage_factor','>',0,'numel',1);
-	    end
-
-			md = checkfield(md,'hydrology.spcsediment_head','forcing',1);
-			md = checkfield(md,'hydrology.sediment_compressibility','>',0,'numel',1);
-			md = checkfield(md,'hydrology.sediment_porosity','>',0,'numel',1);
-			md = checkfield(md,'hydrology.sediment_thickness','>',0,'numel',1);
-			md = checkfield(md,'hydrology.sediment_transmitivity','>',0,'numel',1);
+				md = checkfield(md,'fieldname','hydrology.leakage_factor','>',0,'numel',1);
+	    end
+			md = checkfield(md,'fieldname','hydrology.basal_moulin_input','NaN',1,'forcing',1);
+
+			md = checkfield(md,'fieldname','hydrology.spcsediment_head','forcing',1);
+			md = checkfield(md,'fieldname','hydrology.sediment_compressibility','>',0,'numel',1);
+			md = checkfield(md,'fieldname','hydrology.sediment_porosity','>',0,'numel',1);
+			md = checkfield(md,'fieldname','hydrology.sediment_thickness','>',0,'numel',1);
+			md = checkfield(md,'fieldname','hydrology.sediment_transmitivity','>=',0,'size',[md.mesh.numberofvertices 1]);
 
 			if obj.isefficientlayer==1,
-				md = checkfield(md,'hydrology.spcepl_head','forcing',1);
-				md = checkfield(md,'hydrology.mask_eplactive','size',[md.mesh.numberofvertices 1],'values',[0 1]);
-				md = checkfield(md,'hydrology.epl_compressibility','>',0,'numel',1);
-				md = checkfield(md,'hydrology.epl_porosity','>',0,'numel',1);
-				md = checkfield(md,'hydrology.epl_thickness','>',0,'numel',1);
-				md = checkfield(md,'hydrology.epl_transmitivity','>',0,'numel',1);
+				md = checkfield(md,'fieldname','hydrology.spcepl_head','forcing',1);
+				md = checkfield(md,'fieldname','hydrology.mask_eplactive_node','size',[md.mesh.numberofvertices 1],'values',[0 1]);
+				md = checkfield(md,'fieldname','hydrology.epl_compressibility','>',0,'numel',1);
+				md = checkfield(md,'fieldname','hydrology.epl_porosity','>',0,'numel',1);
+				md = checkfield(md,'fieldname','hydrology.epl_initial_thickness','>',0,'numel',1);
+				md = checkfield(md,'fieldname','hydrology.epl_max_thickness','>',0,'numel',1);
+				md = checkfield(md,'fieldname','hydrology.epl_conductivity','>',0,'numel',1);
 	    end
 		end 
@@ -107,5 +124,7 @@
 			fielddisplay(obj,'isefficientlayer','do we use an efficient drainage system [1: true; 0: false]');
 			fielddisplay(obj,'penalty_factor','exponent of the value used in the penalisation method [dimensionless]');
+			fielddisplay(obj,'penalty_lock','stabilize unstable constraints that keep zigzagging after n iteration (default is 0, no stabilization)');
 			fielddisplay(obj,'rel_tol','tolerance of the nonlinear iteration for the transfer between layers [dimensionless]');
+			fielddisplay(obj,'max_iter','maximum number of nonlinear iteration');
 			fielddisplay(obj,'sedimentlimit_flag','what kind of upper limit is applied for the inefficient layer');
 			disp(sprintf('%55s  0: no limit',' '));
@@ -122,4 +141,5 @@
 				fielddisplay(obj,'leakage_factor','user defined leakage factor [m]');
 	    end
+			fielddisplay(obj,'basal_moulin_input','Figure out what it is');
 			disp(sprintf('   - for the sediment layer'));
 			fielddisplay(obj,'spcsediment_head','sediment water head constraints (NaN means no constraint) [m above MSL]');
@@ -132,9 +152,10 @@
 				disp(sprintf('   - for the epl layer'));
 				fielddisplay(obj,'spcepl_head','epl water head constraints (NaN means no constraint) [m above MSL]');
-				fielddisplay(obj,'mask_eplactive','active (1) or not (0) EPL');
+				fielddisplay(obj,'mask_eplactive_node','active (1) or not (0) EPL');
 				fielddisplay(obj,'epl_compressibility','epl compressibility [Pa^-1]');
 				fielddisplay(obj,'epl_porosity','epl [dimensionless]');
-				fielddisplay(obj,'epl_thickness','epl thickness [m]');
-				fielddisplay(obj,'epl_transmitivity','epl transmitivity [m^2/s]');
+				fielddisplay(obj,'epl_initial_thickness','epl initial thickness [m]');
+				fielddisplay(obj,'epl_max_thickness','epl maximal thickness [m]');
+				fielddisplay(obj,'epl_conductivity','epl conductivity [m^2/s]');
 	    end
 
@@ -147,5 +168,7 @@
 			WriteData(fid,'object',obj,'fieldname','isefficientlayer','format','Boolean');
 			WriteData(fid,'object',obj,'fieldname','penalty_factor','format','Double');
+			WriteData(fid,'object',obj,'fieldname','penalty_lock','format','Integer');
 			WriteData(fid,'object',obj,'fieldname','rel_tol','format','Double');
+			WriteData(fid,'object',obj,'fieldname','max_iter','format','Integer');
 			WriteData(fid,'object',obj,'fieldname','sedimentlimit_flag','format','Integer');
 			WriteData(fid,'object',obj,'fieldname','transfer_flag','format','Integer');
@@ -156,4 +179,5 @@
 				WriteData(fid,'object',obj,'fieldname','leakage_factor','format','Double');
 	    end
+			WriteData(fid,'object',obj,'fieldname','basal_moulin_input','format','DoubleMat','mattype',1,'forcinglength',md.mesh.numberofvertices+1)
 
 			WriteData(fid,'object',obj,'fieldname','spcsediment_head','format','DoubleMat','mattype',1,'forcinglength',md.mesh.numberofvertices+1);
@@ -161,13 +185,14 @@
 			WriteData(fid,'object',obj,'fieldname','sediment_porosity','format','Double');			
 			WriteData(fid,'object',obj,'fieldname','sediment_thickness','format','Double');
-			WriteData(fid,'object',obj,'fieldname','sediment_transmitivity','format','Double');		
+			WriteData(fid,'object',obj,'fieldname','sediment_transmitivity','format','DoubleMat','mattype',1');		
 
 			if obj.isefficientlayer==1,	
 				WriteData(fid,'object',obj,'fieldname','spcepl_head','format','DoubleMat','mattype',1,'forcinglength',md.mesh.numberofvertices+1);	
-				WriteData(fid,'object',obj,'fieldname','mask_eplactive','format','DoubleMat','mattype',1);
+				WriteData(fid,'object',obj,'fieldname','mask_eplactive_node','format','DoubleMat','mattype',1);
 				WriteData(fid,'object',obj,'fieldname','epl_compressibility','format','Double');			
 				WriteData(fid,'object',obj,'fieldname','epl_porosity','format','Double');			
-				WriteData(fid,'object',obj,'fieldname','epl_thickness','format','Double');
-				WriteData(fid,'object',obj,'fieldname','epl_transmitivity','format','Double');
+				WriteData(fid,'object',obj,'fieldname','epl_initial_thickness','format','Double');
+				WriteData(fid,'object',obj,'fieldname','epl_max_thickness','format','Double');
+				WriteData(fid,'object',obj,'fieldname','epl_conductivity','format','Double');
 			end
 		end 
Index: /issm/trunk/src/m/classes/hydrologydc.py
===================================================================
--- /issm/trunk/src/m/classes/hydrologydc.py	(revision 17806)
+++ /issm/trunk/src/m/classes/hydrologydc.py	(revision 17806)
@@ -0,0 +1,175 @@
+from fielddisplay import fielddisplay
+from EnumDefinitions import *
+from checkfield import checkfield
+from WriteData import WriteData
+
+class hydrologydc(object):
+    """
+    Hydrologydc class definition
+    
+    Usage:
+    hydrologydc=hydrologydc();
+    """
+
+    def __init__(self): # {{{
+		self.water_compressibility    = 0
+		self.isefficientlayer         = 0
+		self.penalty_factor           = 0
+		self.penalty_lock             = 0
+		self.rel_tol                  = 0
+		self.max_iter                 = 0
+		self.sedimentlimit_flag       = 0
+		self.sedimentlimit            = 0
+		self.transfer_flag            = 0
+		self.leakage_factor           = 0
+
+		self.spcsediment_head         = float('NaN')
+		self.sediment_transmitivity   = float('NaN')
+		self.sediment_compressibility = 0
+		self.sediment_porosity        = 0
+		self.sediment_thickness       = 0
+
+
+		self.spcepl_head              = float('NaN')
+		self.mask_eplactive_node      = float('NaN')
+		self.epl_compressibility      = 0
+		self.epl_porosity             = 0
+		self.epl_initial_thickness    = 0
+		self.epl_conductivity         = 0
+                
+		#set defaults
+		self.setdefaultparameters()
+                #}}}
+                
+	def __repr__(self): # {{{
+            string='   hydrology Dual Porous Continuum Equivalent parameters:'
+            string='   - general parameters'
+            string="%s\n%s"%(string,fielddisplay(self,'water_compressibility','compressibility of water [Pa^-1]'))
+            string="%s\n%s"%(string,fielddisplay(self,'isefficientlayer','do we use an efficient drainage system [1: true 0: false]'))
+            string="%s\n%s"%(string,fielddisplay(self,'penalty_factor','exponent of the value used in the penalisation method [dimensionless]'))
+            string="%s\n%s"%(string,fielddisplay(self,'penalty_lock','stabilize unstable constraints that keep zigzagging after n iteration (default is 0, no stabilization)'))
+            string="%s\n%s"%(string,fielddisplay(self,'rel_tol','tolerance of the nonlinear iteration for the transfer between layers [dimensionless]'))
+            string="%s\n%s"%(string,fielddisplay(self,'max_iter','maximum number of nonlinear iteration'))
+            string="%s\n%s"%(string,fielddisplay(self,'sedimentlimit_flag','what kind of upper limit is applied for the inefficient layer'))
+            string='%55s  0: no limit',' '
+            string='%55s  1: user defined: %s',' ','sedimentlimit'
+            string='%55s  2: hydrostatic pressure',' '
+            string='%55s  3: normal stress',' '
+
+            if self.sedimentlimit_flag==1:
+                string="%s\n%s"%(string,fielddisplay(self,'sedimentlimit','user defined upper limit for the inefficient layer [m]'))
+                string="%s\n%s"%(string,fielddisplay(self,'transfer_flag',['what kind of transfer method is applied between the layers']))
+                string='%55s  0: no transfer',' '
+                string='%55s  1: constant leakage factor: %s',' ','leakage_factor'
+                
+            if self.transfer_flag is 1:
+                string="%s\n%s"%(string,fielddisplay(self,'leakage_factor','user defined leakage factor [m]'))
+                string='   - for the sediment layer'
+                string="%s\n%s"%(string,fielddisplay(self,'spcsediment_head','sediment water head constraints (NaN means no constraint) [m above MSL]'))
+                string="%s\n%s"%(string,fielddisplay(self,'sediment_compressibility','sediment compressibility [Pa^-1]'))
+                string="%s\n%s"%(string,fielddisplay(self,'sediment_porosity','sediment [dimensionless]'))
+                string="%s\n%s"%(string,fielddisplay(self,'sediment_thickness','sediment thickness [m]'))
+                string="%s\n%s"%(string,fielddisplay(self,'sediment_transmitivity','sediment transmitivity [m^2/s]'))
+            
+            if self.isefficientlayer==1:
+                string='   - for the epl layer'
+                string="%s\n%s"%(string,fielddisplay(self,'spcepl_head','epl water head constraints (NaN means no constraint) [m above MSL]'))
+                string="%s\n%s"%(string,fielddisplay(self,'mask_eplactive_node','active (1) or not (0) EPL'))
+                string="%s\n%s"%(string,fielddisplay(self,'epl_compressibility','epl compressibility [Pa^-1]'))
+                string="%s\n%s"%(string,fielddisplay(self,'epl_porosity','epl [dimensionless]'))
+                string="%s\n%s"%(string,fielddisplay(self,'epl_initial_thickness','epl initial thickness [m]'))
+                string="%s\n%s"%(string,fielddisplay(self,'epl_conductivity','epl conductivity [m^2/s]'))
+            
+            #}}}
+    def setdefaultparameters(self): #{{{ 
+        
+        #Parameters from de Fleurian 2014
+        self.water_compressibility    = 5.04e-10
+        self.isefficientlayer         = 1
+        self.penalty_factor           = 3
+        self.rel_tol                  = 1.0e-06
+        self.max_iter                 = 100
+        self.sedimentlimit_flag       = 0
+        self.sedimentlimit            = 0
+        self.transfer_flag            = 0
+        self.leakage_factor           = 10.0
+        
+        self.sediment_compressibility = 1.0e-08
+        self.sediment_porosity        = 0.4
+        self.sediment_thickness       = 20.0
+        self.sediment_transmitivity   = 8.0e-04
+        
+        self.epl_compressibility      = 1.0e-08
+        self.epl_porosity             = 0.4
+        self.epl_initial_thickness    = 1.0
+        self.epl_conductivity         = 8.0e-02
+        
+        return self
+    # }}}
+    
+    def checkconsistency(self,md,solution,analyses): #{{{ 
+        
+        #Early return
+        if HydrologyDCInefficientAnalysisEnum() not in analyses:
+            return md
+
+        md = checkfield(md,'fieldname','hydrology.water_compressibility','>',0,'numel',1)
+        md = checkfield(md,'fieldname','hydrology.isefficientlayer','numel',[1],'values',[0 1])
+        md = checkfield(md,'fieldname','hydrology.penalty_factor','>',0,'numel',1)
+        md = checkfield(md,'fieldname','hydrology.rel_tol','>',0,'numel',1)
+        md = checkfield(md,'fieldname','hydrology.max_iter','>',0,'numel',1)
+        md = checkfield(md,'fieldname','hydrology.sedimentlimit_flag','numel',[1],'values',[0 1 2 3])
+        md = checkfield(md,'fieldname','hydrology.transfer_flag','numel',[1],'values',[0 1])
+        
+        if self.sedimentlimit_flag==1:
+            md = checkfield(md,'fieldname','hydrology.sedimentlimit','>',0,'numel',1)
+    
+        if self.transfer_flag==1:
+            md = checkfield(md,'fieldname','hydrology.leakage_factor','>',0,'numel',1)
+            
+        md = checkfield(md,'fieldname','hydrology.spcsediment_head','forcing',1)
+        md = checkfield(md,'fieldname','hydrology.sediment_compressibility','>',0,'numel',1)
+        md = checkfield(md,'fieldname','hydrology.sediment_porosity','>',0,'numel',1)
+        md = checkfield(md,'fieldname','hydrology.sediment_thickness','>',0,'numel',1)
+        md = checkfield(md,'fieldname','hydrology.sediment_transmitivity','>=',0,'size',[md.mesh.numberofvertices 1])
+        if self.isefficientlayer==1:
+            md = checkfield(md,'fieldname','hydrology.spcepl_head','forcing',1)
+            md = checkfield(md,'fieldname','hydrology.mask_eplactive_node','size',[md.mesh.numberofvertices 1],'values',[0 1])
+            md = checkfield(md,'fieldname','hydrology.epl_compressibility','>',0,'numel',1)
+            md = checkfield(md,'fieldname','hydrology.epl_porosity','>',0,'numel',1)
+            md = checkfield(md,'fieldname','hydrology.epl_initial_thickness','>',0,'numel',1)
+            md = checkfield(md,'fieldname','hydrology.epl_conductivity','>',0,'numel',1)
+
+        # }}}
+    def marshall(self,md,fid): #{{{ 
+        WriteData(fid,'enum',HydrologyModelEnum(),'data',HydrologydcEnum(),'format','Integer')
+        WriteData(fid,'object',self,'fieldname','water_compressibility','format','Double')
+        WriteData(fid,'object',self,'fieldname','isefficientlayer','format','Boolean')
+        WriteData(fid,'object',self,'fieldname','penalty_factor','format','Double')
+        WriteData(fid,'object',self,'fieldname','penalty_lock','format','Integer')
+        WriteData(fid,'object',self,'fieldname','rel_tol','format','Double')
+        WriteData(fid,'object',self,'fieldname','max_iter','format','Integer')
+        WriteData(fid,'object',self,'fieldname','sedimentlimit_flag','format','Integer')
+        WriteData(fid,'object',self,'fieldname','transfer_flag','format','Integer')
+
+        if self.sedimentlimit_flag==1:
+            WriteData(fid,'object',self,'fieldname','sedimentlimit','format','Double')
+
+        if self.transfer_flag==1:
+            WriteData(fid,'object',self,'fieldname','leakage_factor','format','Double')
+
+        WriteData(fid,'object',self,'fieldname','spcsediment_head','format','DoubleMat','mattype',1,'forcinglength',md.mesh.numberofvertices+1)
+        WriteData(fid,'object',self,'fieldname','sediment_compressibility','format','Double')
+        WriteData(fid,'object',self,'fieldname','sediment_porosity','format','Double')			
+        WriteData(fid,'object',self,'fieldname','sediment_thickness','format','Double')
+        WriteData(fid,'object',self,'fieldname','sediment_transmitivity','format','DoubleMat','mattype',1)		
+
+        if self.isefficientlayer==1:	
+            WriteData(fid,'object',self,'fieldname','spcepl_head','format','DoubleMat','mattype',1,'forcinglength',md.mesh.numberofvertices+1)	
+            WriteData(fid,'object',self,'fieldname','mask_eplactive_node','format','DoubleMat','mattype',1)
+            WriteData(fid,'object',self,'fieldname','epl_compressibility','format','Double')			
+            WriteData(fid,'object',self,'fieldname','epl_porosity','format','Double')			
+            WriteData(fid,'object',self,'fieldname','epl_initial_thickness','format','Double')
+            WriteData(fid,'object',self,'fieldname','epl_conductivity','format','Double')
+# }}}
+
Index: /issm/trunk/src/m/classes/hydrologyshreve.m
===================================================================
--- /issm/trunk/src/m/classes/hydrologyshreve.m	(revision 17805)
+++ /issm/trunk/src/m/classes/hydrologyshreve.m	(revision 17806)
@@ -15,4 +15,20 @@
 	end
 	methods
+        function createxml(obj,fid) % {{{
+            fprintf(fid, '\n\n');
+            fprintf(fid, '%s\n', '<!-- Hydrology -->');
+            
+            % Convergence criteria            
+            fprintf(fid,'%s\n%s\n%s\n','<frame key="1" label="Hydrologyshreve solution parameters">','<section name="hydrologyshreve" />');                    
+            
+			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="spcwatercolumn" type="',      class(obj.spcwatercolumn),'" default="',        convert2str(obj.spcwatercolumn),'">',	'     <section name="hydrologyshreve" />','     <help> water thickness constraints (NaN means no constraint) [m] </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="n" type="',          class(obj.n),'" default="',            convert2str(obj.n),'">',     '     <section name="hydrologyshreve" />','     <help> Manning roughness coefficient </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',	'<parameter key ="CR" type="',        class(obj.CR),'" default="',          convert2str(obj.CR),'">',	'     <section name="hydrologyshreve" />','     <help> tortuosity parameter </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="p" type="',          class(obj.p),'" default="',            convert2str(obj.p),'">',	'     <section name="hydrologyshreve" />','     <help> dimensionless exponent in Manning velocity formula </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="q" type="',  	class(obj.q),'" default="',       convert2str(obj.q),'">',     '     <section name="hydrologyshreve" />','     <help> dimensionless exponent in Manning velocity formula </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="kn" type="',         class(obj.kn),'" default="',           convert2str(obj.kn),'">',	'     <section name="hydrologyshreve" />','     <help> parameter in effective pressure formula </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="stabilization" type="',         class(obj.stabilization),'" default="',           convert2str(obj.stabilization),'">',	'     <section name="hydrologyshreve" />','     <help> artificial diffusivity (default is 1). can be more than 1 to increase diffusivity. </help>','</parameter>');
+            fprintf(fid,'%s\n%s\n','</frame>');
+        end % }}}
 		function obj = hydrologyshreve(varargin) % {{{
 			switch nargin
@@ -44,6 +60,6 @@
 			end
 
-			md = checkfield(md,'hydrology.spcwatercolumn','forcing',1);
-			md = checkfield(md,'hydrology.stabilization','>=',0);
+			md = checkfield(md,'fieldname','hydrology.spcwatercolumn','forcing',1);
+			md = checkfield(md,'fieldname','hydrology.stabilization','>=',0);
 		end % }}}
 		function disp(obj) % {{{
Index: /issm/trunk/src/m/classes/hydrologyshreve.py
===================================================================
--- /issm/trunk/src/m/classes/hydrologyshreve.py	(revision 17805)
+++ /issm/trunk/src/m/classes/hydrologyshreve.py	(revision 17806)
@@ -1,6 +1,6 @@
 from fielddisplay import fielddisplay
 from EnumDefinitions import *
-from checkfield import *
-from WriteData import *
+from checkfield import checkfield
+from WriteData import WriteData
 
 class hydrologyshreve(object):
@@ -52,11 +52,11 @@
 	#}}}
 	def checkconsistency(self,md,solution,analyses):    # {{{
-
+		
 		#Early return
 		if HydrologyShreveAnalysisEnum() not in analyses:
 			return md
 
-		md = checkfield(md,'hydrology.spcwatercolumn','forcing',1)
-		md = checkfield(md,'hydrology.stabilization','>=',0)
+		md = checkfield(md,'fieldname','hydrology.spcwatercolumn','forcing',1)
+		md = checkfield(md,'fieldname','hydrology.stabilization','>=',0)
 
 		return md
Index: /issm/trunk/src/m/classes/independent.m
===================================================================
--- /issm/trunk/src/m/classes/independent.m	(revision 17805)
+++ /issm/trunk/src/m/classes/independent.m	(revision 17806)
@@ -44,5 +44,5 @@
 					error('independent checkconsistency error: nods should be set to the size of the independent variable');
 				end
-				md = checkfield(md,['autodiff.independents{' num2str(i) '}.fov_forward_indices'],'>=',1,'<=',obj.nods,'size',[NaN 1]);
+				md = checkfield(md,'fieldname',['autodiff.independents{' num2str(i) '}.fov_forward_indices'],'>=',1,'<=',obj.nods,'size',[NaN 1]);
 			end
 
Index: /issm/trunk/src/m/classes/independent.py
===================================================================
--- /issm/trunk/src/m/classes/independent.py	(revision 17805)
+++ /issm/trunk/src/m/classes/independent.py	(revision 17806)
@@ -1,8 +1,7 @@
 import numpy
-from pairoptions import *
-from fielddisplay import *
-from MatlabFuncs import *
+from pairoptions import pairoptions
+from fielddisplay import fielddisplay
+import MatlabFuncs as m
 from EnumDefinitions import *
-from WriteData import *
 
 class independent(object):
@@ -58,5 +57,5 @@
 			if self.nods==0:
 				raise TypeError("independent checkconsistency error: nods should be set to the size of the independent variable")
-			md = checkfield(md,"autodiff.independents[%d].fov_forward_indices" % i,'>=',1,'<=',self.nods,'size',[float('NaN'),1])
+			md = checkfield(md,'fieldname',"autodiff.independents[%d].fov_forward_indices" % i,'>=',1,'<=',self.nods,'size',[float('NaN'),1])
 
 		return md
Index: /issm/trunk/src/m/classes/initialization.m
===================================================================
--- /issm/trunk/src/m/classes/initialization.m	(revision 17805)
+++ /issm/trunk/src/m/classes/initialization.m	(revision 17806)
@@ -15,7 +15,25 @@
 		sediment_head = NaN;
 		epl_head      = NaN;
+		epl_thickness = NaN;
 		watercolumn   = NaN;
 	end
 	methods
+        function createxml(obj,fid) % {{{
+            fprintf(fid, '\n\n');
+            fprintf(fid, '%s\n', '<!-- initialization -->');
+            fprintf(fid,'%s\n%s\n%s\n','<frame key="1" label="Initial field values">','<section name="initialization" />');                    
+            
+			 fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="vx" type="',class(obj.vx),'" default="',obj.vx,'">','     <section name="initialization" />','     <help> x component of velocity [m/yr] </help>','</parameter>');
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="vy" type="',class(obj.vy),'" default="',obj.vy,'">','     <section name="initialization" />','     <help> y component of velocity [m/yr] </help>','</parameter>');
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="vz" type="',class(obj.vz),'" default="',obj.vz,'">','     <section name="initialization" />','     <help> z component of velocity [m/yr] </help>','</parameter>');
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="vel" type="',class(obj.vel),'" default="',obj.vel,'">','     <section name="initialization" />','     <help> velocity norm [m/yr] </help>','</parameter>');
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="pressure" type="',class(obj.pressure),'" default="',obj.pressure,'">','     <section name="initialization" />','     <help> pressure field [Pa] </help>','</parameter>');
+        	 fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="temperature" type="',class(obj.temperature),'" default="',obj.temperature,'">','     <section name="initialization" />','     <help> fraction of water in the ice </help>','</parameter>');
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="waterfraction" type="',class(obj.waterfraction),'" default="',obj.waterfraction,'">','     <section name="initialization" />','     <help> ice thickness [m] </help>','</parameter>');
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="sediment_head" type="',class(obj.sediment_head),'" default="',obj.sediment_head,'">','     <section name="initialization" />','     <help> sediment water head of subglacial system [m] </help>','</parameter>');
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="epl_head" type="',class(obj.epl_head),'" default="',obj.epl_head,'">','     <section name="initialization" />','     <help> epl water head of subglacial system [m] </help>','</parameter>');
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n','<parameter key ="watercolumn" type="',class(obj.watercolumn),'" default="',obj.watercolumn,'">','     <section name="initialization" />','     <help> thickness of subglacial water [m] </help>','</parameter>');
+            fprintf(fid,'%s\n%s\n','</frame>');
+        end % }}}
 		function obj = initialization(varargin) % {{{
 			switch nargin
@@ -32,15 +50,15 @@
 			if ismember(StressbalanceAnalysisEnum(),analyses)
 				if ~(isnan(md.initialization.vx) | isnan(md.initialization.vy)),
-					md = checkfield(md,'initialization.vx','NaN',1,'size',[md.mesh.numberofvertices 1]);
-					md = checkfield(md,'initialization.vy','NaN',1,'size',[md.mesh.numberofvertices 1]);
+					md = checkfield(md,'fieldname','initialization.vx','NaN',1,'size',[md.mesh.numberofvertices 1]);
+					md = checkfield(md,'fieldname','initialization.vy','NaN',1,'size',[md.mesh.numberofvertices 1]);
 				end
 			end
 			if ismember(MasstransportAnalysisEnum(),analyses),
-				md = checkfield(md,'initialization.vx','NaN',1,'size',[md.mesh.numberofvertices 1]);
-				md = checkfield(md,'initialization.vy','NaN',1,'size',[md.mesh.numberofvertices 1]);
+				md = checkfield(md,'fieldname','initialization.vx','NaN',1,'size',[md.mesh.numberofvertices 1]);
+				md = checkfield(md,'fieldname','initialization.vy','NaN',1,'size',[md.mesh.numberofvertices 1]);
 			end
 			if ismember(BalancethicknessAnalysisEnum(),analyses) & solution==BalancethicknessSolutionEnum,
-				md = checkfield(md,'initialization.vx','NaN',1,'size',[md.mesh.numberofvertices 1]);
-				md = checkfield(md,'initialization.vy','NaN',1,'size',[md.mesh.numberofvertices 1]);
+				md = checkfield(md,'fieldname','initialization.vx','NaN',1,'size',[md.mesh.numberofvertices 1]);
+				md = checkfield(md,'fieldname','initialization.vy','NaN',1,'size',[md.mesh.numberofvertices 1]);
 				%Triangle with zero velocity
 				if any(sum(abs(md.initialization.vx(md.mesh.elements)),2)==0 & sum(abs(md.initialization.vy(md.mesh.elements)),2)==0)
@@ -49,23 +67,23 @@
 			end
 			if ismember(ThermalAnalysisEnum(),analyses),
-				md = checkfield(md,'initialization.vx','NaN',1,'size',[md.mesh.numberofvertices 1]);
-				md = checkfield(md,'initialization.vy','NaN',1,'size',[md.mesh.numberofvertices 1]);
-				if strcmp(meshtype(md.mesh),'3D')
-					md = checkfield(md,'initialization.vz','NaN',1,'size',[md.mesh.numberofvertices 1]);
+				md = checkfield(md,'fieldname','initialization.vx','NaN',1,'size',[md.mesh.numberofvertices 1]);
+				md = checkfield(md,'fieldname','initialization.vy','NaN',1,'size',[md.mesh.numberofvertices 1]);
+				if dimension(md.mesh)==3
+					md = checkfield(md,'fieldname','initialization.vz','NaN',1,'size',[md.mesh.numberofvertices 1]);
 				end
-				md = checkfield(md,'initialization.pressure','NaN',1,'size',[md.mesh.numberofvertices 1]);
+				md = checkfield(md,'fieldname','initialization.pressure','NaN',1,'size',[md.mesh.numberofvertices 1]);
 			end
 			if (ismember(EnthalpyAnalysisEnum(),analyses) & md.thermal.isenthalpy)
-				md = checkfield(md,'initialization.waterfraction','>=',0,'size',[md.mesh.numberofvertices 1]);
-				md = checkfield(md,'initialization.watercolumn'  ,'>=',0,'size',[md.mesh.numberofvertices 1]);
+				md = checkfield(md,'fieldname','initialization.waterfraction','>=',0,'size',[md.mesh.numberofvertices 1]);
+				md = checkfield(md,'fieldname','initialization.watercolumn'  ,'>=',0,'size',[md.mesh.numberofvertices 1]);
 			end
 			if ismember(HydrologyShreveAnalysisEnum(),analyses),
 				if isa(md.hydrology,'hydrologyshreve'),
-					md = checkfield(md,'initialization.watercolumn','NaN',1,'size',[md.mesh.numberofvertices 1]);
+					md = checkfield(md,'fieldname','initialization.watercolumn','NaN',1,'size',[md.mesh.numberofvertices 1]);
 				end
 			end
 			if ismember(HydrologyDCInefficientAnalysisEnum(),analyses),
 				if isa(md.hydrology,'hydrologydc'),
-					md = checkfield(md,'initialization.sediment_head','NaN',1,'size',[md.mesh.numberofvertices 1]);
+					md = checkfield(md,'fieldname','initialization.sediment_head','NaN',1,'size',[md.mesh.numberofvertices 1]);
 				end
 			end
@@ -73,5 +91,7 @@
 				if isa(md.hydrology,'hydrologydc'),
 					if md.hydrology.isefficientlayer==1,
-						md = checkfield(md,'initialization.epl_head','NaN',1,'size',[md.mesh.numberofvertices 1]);
+						md = checkfield(md,'fieldname', ...
+														'initialization.epl_head','NaN',1,'size',[md.mesh.numberofvertices 1]);
+						md = checkfield(md,'fieldname','initialization.epl_thickness','NaN',1,'size',[md.mesh.numberofvertices 1]);
 					end
 				end
@@ -90,4 +110,5 @@
 			fielddisplay(obj,'sediment_head','sediment water head of subglacial system [m]');
 			fielddisplay(obj,'epl_head','epl water head of subglacial system [m]');
+			fielddisplay(obj,'epl_thickness','epl layer thickness [m]');
 			fielddisplay(obj,'watercolumn','thickness of subglacial water [m]');
 
@@ -105,4 +126,5 @@
 			WriteData(fid,'data',obj.sediment_head,'format','DoubleMat','mattype',1,'enum',SedimentHeadEnum);
 			WriteData(fid,'data',obj.epl_head,'format','DoubleMat','mattype',1,'enum',EplHeadEnum);
+			WriteData(fid,'data',obj.epl_thickness,'format','DoubleMat','mattype',1,'enum',HydrologydcEplThicknessEnum);
 			WriteData(fid,'data',obj.watercolumn,'format','DoubleMat','mattype',1,'enum',WatercolumnEnum);
 
Index: /issm/trunk/src/m/classes/initialization.py
===================================================================
--- /issm/trunk/src/m/classes/initialization.py	(revision 17805)
+++ /issm/trunk/src/m/classes/initialization.py	(revision 17806)
@@ -2,6 +2,7 @@
 from fielddisplay import fielddisplay
 from EnumDefinitions import *
-from checkfield import *
-from WriteData import *
+from checkfield import checkfield
+from WriteData import WriteData
+import MatlabFuncs as m
 
 class initialization(object):
@@ -50,12 +51,12 @@
 		if StressbalanceAnalysisEnum() in analyses:
 			if not numpy.any(numpy.logical_or(numpy.isnan(md.initialization.vx),numpy.isnan(md.initialization.vy))):
-				md = checkfield(md,'initialization.vx','NaN',1,'size',[md.mesh.numberofvertices])
-				md = checkfield(md,'initialization.vy','NaN',1,'size',[md.mesh.numberofvertices])
+				md = checkfield(md,'fieldname','initialization.vx','NaN',1,'size',[md.mesh.numberofvertices])
+				md = checkfield(md,'fieldname','initialization.vy','NaN',1,'size',[md.mesh.numberofvertices])
 		if MasstransportAnalysisEnum() in analyses:
-			md = checkfield(md,'initialization.vx','NaN',1,'size',[md.mesh.numberofvertices])
-			md = checkfield(md,'initialization.vy','NaN',1,'size',[md.mesh.numberofvertices])
+			md = checkfield(md,'fieldname','initialization.vx','NaN',1,'size',[md.mesh.numberofvertices])
+			md = checkfield(md,'fieldname','initialization.vy','NaN',1,'size',[md.mesh.numberofvertices])
 		if BalancethicknessAnalysisEnum() in analyses:
-			md = checkfield(md,'initialization.vx','NaN',1,'size',[md.mesh.numberofvertices])
-			md = checkfield(md,'initialization.vy','NaN',1,'size',[md.mesh.numberofvertices])
+			md = checkfield(md,'fieldname','initialization.vx','NaN',1,'size',[md.mesh.numberofvertices])
+			md = checkfield(md,'fieldname','initialization.vy','NaN',1,'size',[md.mesh.numberofvertices])
 			#Triangle with zero velocity
 			if numpy.any(numpy.logical_and(numpy.sum(numpy.abs(md.initialization.vx[md.mesh.elements-1]),axis=1)==0,\
@@ -63,14 +64,14 @@
 				md.checkmessage("at least one triangle has all its vertices with a zero velocity")
 		if ThermalAnalysisEnum() in analyses:
-			md = checkfield(md,'initialization.vx','NaN',1,'size',[md.mesh.numberofvertices])
-			md = checkfield(md,'initialization.vy','NaN',1,'size',[md.mesh.numberofvertices])
-			if strcmp(md.mesh.meshtype(),'3D'):
-				md = checkfield(md,'initialization.vz','NaN',1,'size',[md.mesh.numberofvertices])
-			md = checkfield(md,'initialization.pressure','NaN',1,'size',[md.mesh.numberofvertices])
+			md = checkfield(md,'fieldname','initialization.vx','NaN',1,'size',[md.mesh.numberofvertices])
+			md = checkfield(md,'fieldname','initialization.vy','NaN',1,'size',[md.mesh.numberofvertices])
+			if md.mesh.dimension()==3:
+				md = checkfield(md,'fieldname','initialization.vz','NaN',1,'size',[md.mesh.numberofvertices])
+			md = checkfield(md,'fieldname','initialization.pressure','NaN',1,'size',[md.mesh.numberofvertices])
 		if (EnthalpyAnalysisEnum() in analyses and md.thermal.isenthalpy):
-			md = checkfield(md,'initialization.waterfraction','>=',0,'size',[md.mesh.numberofvertices])
-			md = checkfield(md,'initialization.watercolumn'  ,'>=',0,'size',[md.mesh.numberofvertices])
+			md = checkfield(md,'fieldname','initialization.waterfraction','>=',0,'size',[md.mesh.numberofvertices])
+			md = checkfield(md,'fieldname','initialization.watercolumn'  ,'>=',0,'size',[md.mesh.numberofvertices])
 		if HydrologyShreveAnalysisEnum() in analyses:
-			md = checkfield(md,'initialization.watercolumn','NaN',1,'size',[md.mesh.numberofvertices])
+			md = checkfield(md,'fieldname','initialization.watercolumn','NaN',1,'size',[md.mesh.numberofvertices])
 		return md
 	# }}}
Index: /issm/trunk/src/m/classes/inversion.m
===================================================================
--- /issm/trunk/src/m/classes/inversion.m	(revision 17805)
+++ /issm/trunk/src/m/classes/inversion.m	(revision 17806)
@@ -26,4 +26,48 @@
 	end
 	methods
+         function createxml(obj,fid) % {{{
+            fprintf(fid, '<!-- inversion -->\n');            
+                    
+            % inversion parameters
+            fprintf(fid,'%s\n%s\n%s\n','<frame key="1" label="inversion parameters">','<section name="inversion" />');                    
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="iscontrol" type="',class(obj.iscontrol),'" default="',convert2str(obj.iscontrol),'">','     <section name="inversion" />','     <help> is inversion activated? </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="incomplete_adjoint" type="',class(obj.incomplete_adjoint),'" default="',convert2str(obj.incomplete_adjoint),'">','     <section name="inversion" />','     <help> 1: linear viscosity, 0: non-linear viscosity </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="control_parameters" type="',class(obj.control_parameters),'" default="',convert2str(obj.control_parameters),'">','     <section name="inversion" />','     <help> ex: {''FrictionCoefficient''}, or {''MaterialsRheologyBbar''} </help>','  </parameter>');
+                
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="nsteps" type="',class(obj.nsteps),'" default="',convert2str(obj.nsteps),'">','     <section name="inversion" />','     <help> number of optimization searches </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="cost_functions" type="',class(obj.cost_functions),'" default="',convert2str(obj.cost_functions),'">','     <section name="inversion" />','     <help> indicate the type of response for each optimization step  </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="cost_functions_coefficients" type="',class(obj.cost_functions_coefficients),'" default="',convert2str(obj.cost_functions_coefficients),'">','     <section name="inversion" />','     <help> cost_functions_coefficients applied to the misfit of each vertex and for each control_parameter </help>','  </parameter>');
+                
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="cost_function_threshold" type="',class(obj.cost_function_threshold),'" default="',convert2str(obj.cost_function_threshold),'">','     <section name="inversion" />','     <help> misfit convergence criterion. Default is 1%, NaN if not applied </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="maxiter_per_step" type="',class(obj.maxiter_per_step),'" default="',convert2str(obj.maxiter_per_step),'">','     <section name="inversion" />','     <help> maximum iterations during each optimization step  </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="gradient_scaling" type="',class(obj.gradient_scaling),'" default="',convert2str(obj.gradient_scaling),'">','     <section name="inversion" />','     <help> scaling factor on gradient direction during optimization, for each optimization step </help>','  </parameter>');
+               
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="step_threshold" type="',class(obj.step_threshold),'" default="',convert2str(obj.step_threshold),'">','     <section name="inversion" />','     <help> decrease threshold for misfit, default is 30% </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="min_parameters" type="',class(obj.min_parameters),'" default="',convert2str(obj.min_parameters),'">','     <section name="inversion" />','     <help> absolute minimum acceptable value of the inversed parameter on each vertex </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="max_parameters" type="',class(obj.max_parameters),'" default="',convert2str(obj.max_parameters),'">','     <section name="inversion" />','     <help> absolute maximum acceptable value of the inversed parameter on each vertex </help>','  </parameter>');
+               
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="vx_obs" type="',class(obj.vx_obs),'" default="',convert2str(obj.vx_obs),'">','     <section name="inversion" />','     <help> observed velocity x component [m/yr] </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="vy_obs" type="',class(obj.vy_obs),'" default="',convert2str(obj.vy_obs),'">','     <section name="inversion" />','     <help> observed velocity y component [m/yr]  </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="vel_obs" type="',class(obj.vel_obs),'" default="',convert2str(obj.vel_obs),'">','     <section name="inversion" />','     <help> observed velocity magnitude [m/yr] </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="thickness_obs" type="',class(obj.thickness_obs),'" default="',convert2str(obj.thickness_obs),'">','     <section name="inversion" />','     <help> observed thickness [m]) </help>','  </parameter>');
+               
+            fprintf(fid,'%s\n%s\n','</frame>');    
+            
+            fprintf(fid,'%s\n%s\n%s\n','<frame key="2" label="Available cost functions">','<section name="inversion" />');                    
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="SurfaceAbsVelMisfit" type="','string','" default="','101','">','     <section name="inversion" />','     <help>  </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="SurfaceRelVelMisfit" type="','string','" default="','102','">','     <section name="inversion" />','     <help>   </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="SurfaceLogVelMisfit" type="','string','" default="','103','">','     <section name="inversion" />','     <help>  </help>','  </parameter>');
+                
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="SurfaceLogVxVyMisfit" type="','string','" default="','104','">','     <section name="inversion" />','     <help>  </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="SurfaceAverageVelMisfit" type="','string','" default="','105','">','     <section name="inversion" />','     <help>   </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="ThicknessAbsMisfit" type="','string','" default="','106','">','     <section name="inversion" />','     <help>  </help>','  </parameter>');
+               
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="DragCoefficientAbsGradient" type="','string','" default="','107','">','     <section name="inversion" />','     <help>  </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="RheologyBbarAbsGradient" type="','string','" default="','108','">','     <section name="inversion" />','     <help>  </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="ThicknessAbsGradient" type="','string','" default="','109','">','     <section name="inversion" />','     <help> </help>','  </parameter>');
+               
+            fprintf(fid,'%s\n%s\n','</frame>');    
+        
+        end % }}}       
 		function obj = inversion(varargin) % {{{
 			switch nargin
@@ -32,14 +76,14 @@
 				case 1
 					if isa(varargin{1},'taoinversion'),
-						disp('converting taoinversion to inversion');
+						disp('converting taoinversion');
 						in=varargin{1};
 						obj=inversion();
 						obj.iscontrol                   = in.iscontrol;
-						obj.tao                         = 1;
+						obj.tao                         = 1;rsion to inve
 						obj.incomplete_adjoint          = in.incomplete_adjoint;
 						obj.control_parameters          = in.control_parameters;
 						obj.nsteps                      = in.nsteps;
 						obj.maxiter_per_step            = 10*ones(in.nsteps,1);
-						obj.cost_functions              = repmat(in.cost_functions,in.nsteps,1);
+						obj.cost_functions              = in.cost_functions;
 						obj.cost_functions_coefficients = in.cost_functions_coefficients;
 						obj.gradient_scaling            = 100*ones(in.nsteps,1);
@@ -107,17 +151,17 @@
 			num_costfunc=size(md.inversion.cost_functions,2);
 
-			md = checkfield(md,'inversion.iscontrol','values',[0 1]);
-			md = checkfield(md,'inversion.tao','values',[0 1]);
-			md = checkfield(md,'inversion.incomplete_adjoint','values',[0 1]);
-			md = checkfield(md,'inversion.control_parameters','cell',1,'values',...
+			md = checkfield(md,'fieldname','inversion.iscontrol','values',[0 1]);
+			md = checkfield(md,'fieldname','inversion.tao','values',[0 1]);
+			md = checkfield(md,'fieldname','inversion.incomplete_adjoint','values',[0 1]);
+			md = checkfield(md,'fieldname','inversion.control_parameters','cell',1,'values',...
 				{'BalancethicknessThickeningRate' 'FrictionCoefficient' 'MaterialsRheologyBbar' 'DamageDbar' 'Vx' 'Vy' 'Thickness'});
-			md = checkfield(md,'inversion.nsteps','numel',1,'>=',0);
-			md = checkfield(md,'inversion.maxiter_per_step','size',[md.inversion.nsteps 1],'>=',0);
-			md = checkfield(md,'inversion.step_threshold','size',[md.inversion.nsteps 1]);
-			md = checkfield(md,'inversion.cost_functions','size',[1 num_costfunc],'values',[101:105 201 501:506]);
-			md = checkfield(md,'inversion.cost_functions_coefficients','size',[md.mesh.numberofvertices num_costfunc],'>=',0);
-			md = checkfield(md,'inversion.gradient_scaling','size',[md.inversion.nsteps num_controls]);
-			md = checkfield(md,'inversion.min_parameters','size',[md.mesh.numberofvertices num_controls]);
-			md = checkfield(md,'inversion.max_parameters','size',[md.mesh.numberofvertices num_controls]);
+			md = checkfield(md,'fieldname','inversion.nsteps','numel',1,'>=',0);
+			md = checkfield(md,'fieldname','inversion.maxiter_per_step','size',[md.inversion.nsteps 1],'>=',0);
+			md = checkfield(md,'fieldname','inversion.step_threshold','size',[md.inversion.nsteps 1]);
+			md = checkfield(md,'fieldname','inversion.cost_functions','size',[1 num_costfunc],'values',[101:105 201 501:506]);
+			md = checkfield(md,'fieldname','inversion.cost_functions_coefficients','size',[md.mesh.numberofvertices num_costfunc],'>=',0);
+			md = checkfield(md,'fieldname','inversion.gradient_scaling','size',[md.inversion.nsteps num_controls]);
+			md = checkfield(md,'fieldname','inversion.min_parameters','size',[md.mesh.numberofvertices num_controls]);
+			md = checkfield(md,'fieldname','inversion.max_parameters','size',[md.mesh.numberofvertices num_controls]);
 
 			%Only SSA, HO and FS are supported right now
@@ -129,10 +173,10 @@
 
 			if solution==BalancethicknessSolutionEnum()
-				md = checkfield(md,'inversion.thickness_obs','size',[md.mesh.numberofvertices 1],'NaN',1);
+				md = checkfield(md,'fieldname','inversion.thickness_obs','size',[md.mesh.numberofvertices 1],'NaN',1);
 			elseif solution==BalancethicknessSoftSolutionEnum()
-				md = checkfield(md,'inversion.thickness_obs','size',[md.mesh.numberofvertices 1],'NaN',1);
+				md = checkfield(md,'fieldname','inversion.thickness_obs','size',[md.mesh.numberofvertices 1],'NaN',1);
 			else
-				md = checkfield(md,'inversion.vx_obs','size',[md.mesh.numberofvertices 1],'NaN',1);
-				md = checkfield(md,'inversion.vy_obs','size',[md.mesh.numberofvertices 1],'NaN',1);
+				md = checkfield(md,'fieldname','inversion.vx_obs','size',[md.mesh.numberofvertices 1],'NaN',1);
+				md = checkfield(md,'fieldname','inversion.vy_obs','size',[md.mesh.numberofvertices 1],'NaN',1);
 			end
 		end % }}}
@@ -199,16 +243,16 @@
 			num_cost_functions=size(obj.cost_functions,2);
 			data=obj.cost_functions;
-			pos=find(data==101); data(pos)=SurfaceAbsVelMisfitEnum();
-			pos=find(data==102); data(pos)=SurfaceRelVelMisfitEnum();
-			pos=find(data==103); data(pos)=SurfaceLogVelMisfitEnum();
-			pos=find(data==104); data(pos)=SurfaceLogVxVyMisfitEnum();
-			pos=find(data==105); data(pos)=SurfaceAverageVelMisfitEnum();
-			pos=find(data==201); data(pos)=ThicknessAbsMisfitEnum();
-			pos=find(data==501); data(pos)=DragCoefficientAbsGradientEnum();
-			pos=find(data==502); data(pos)=RheologyBbarAbsGradientEnum();
-			pos=find(data==503); data(pos)=ThicknessAbsGradientEnum();
-			pos=find(data==504); data(pos)=ThicknessAlongGradientEnum();
-			pos=find(data==505); data(pos)=ThicknessAcrossGradientEnum();
-			pos=find(data==506); data(pos)=BalancethicknessMisfitEnum();
+			pos=find(obj.cost_functions==101); data(pos)=SurfaceAbsVelMisfitEnum();
+			pos=find(obj.cost_functions==102); data(pos)=SurfaceRelVelMisfitEnum();
+			pos=find(obj.cost_functions==103); data(pos)=SurfaceLogVelMisfitEnum();
+			pos=find(obj.cost_functions==104); data(pos)=SurfaceLogVxVyMisfitEnum();
+			pos=find(obj.cost_functions==105); data(pos)=SurfaceAverageVelMisfitEnum();
+			pos=find(obj.cost_functions==201); data(pos)=ThicknessAbsMisfitEnum();
+			pos=find(obj.cost_functions==501); data(pos)=DragCoefficientAbsGradientEnum();
+			pos=find(obj.cost_functions==502); data(pos)=RheologyBbarAbsGradientEnum();
+			pos=find(obj.cost_functions==503); data(pos)=ThicknessAbsGradientEnum();
+			pos=find(obj.cost_functions==504); data(pos)=ThicknessAlongGradientEnum();
+			pos=find(obj.cost_functions==505); data(pos)=ThicknessAcrossGradientEnum();
+			pos=find(obj.cost_functions==506); data(pos)=BalancethicknessMisfitEnum();
 			WriteData(fid,'data',data,'enum',InversionCostFunctionsEnum(),'format','DoubleMat','mattype',3);
 			WriteData(fid,'data',num_cost_functions,'enum',InversionNumCostFunctionsEnum(),'format','Integer');
Index: /issm/trunk/src/m/classes/inversion.py
===================================================================
--- /issm/trunk/src/m/classes/inversion.py	(revision 17805)
+++ /issm/trunk/src/m/classes/inversion.py	(revision 17806)
@@ -4,6 +4,6 @@
 from EnumDefinitions import *
 from StringToEnum import StringToEnum
-from checkfield import *
-from WriteData import *
+from checkfield import checkfield
+from WriteData import WriteData
 
 class inversion(object):
@@ -116,16 +116,16 @@
 		num_costfunc=numpy.size(md.inversion.cost_functions)
 
-		md = checkfield(md,'inversion.iscontrol','values',[0,1])
-		md = checkfield(md,'inversion.tao','values',[0,1])
-		md = checkfield(md,'inversion.incomplete_adjoint','values',[0,1])
-		md = checkfield(md,'inversion.control_parameters','cell',1,'values',['BalancethicknessThickeningRate','FrictionCoefficient','MaterialsRheologyBbar','DamageDbar','Vx','Vy'])
-		md = checkfield(md,'inversion.nsteps','numel',[1],'>=',0)
-		md = checkfield(md,'inversion.maxiter_per_step','size',[md.inversion.nsteps],'>=',0)
-		md = checkfield(md,'inversion.step_threshold','size',[md.inversion.nsteps])
-		md = checkfield(md,'inversion.cost_functions','size',[num_costfunc],'values',[101,102,103,104,105,201,501,502,503,504,505])
-		md = checkfield(md,'inversion.cost_functions_coefficients','size',[md.mesh.numberofvertices,num_costfunc],'>=',0)
-		md = checkfield(md,'inversion.gradient_scaling','size',[md.inversion.nsteps,num_controls])
-		md = checkfield(md,'inversion.min_parameters','size',[md.mesh.numberofvertices,num_controls])
-		md = checkfield(md,'inversion.max_parameters','size',[md.mesh.numberofvertices,num_controls])
+		md = checkfield(md,'fieldname','inversion.iscontrol','values',[0,1])
+		md = checkfield(md,'fieldname','inversion.tao','values',[0,1])
+		md = checkfield(md,'fieldname','inversion.incomplete_adjoint','values',[0,1])
+		md = checkfield(md,'fieldname','inversion.control_parameters','cell',1,'values',['BalancethicknessThickeningRate','FrictionCoefficient','MaterialsRheologyBbar','DamageDbar','Vx','Vy'])
+		md = checkfield(md,'fieldname','inversion.nsteps','numel',[1],'>=',0)
+		md = checkfield(md,'fieldname','inversion.maxiter_per_step','size',[md.inversion.nsteps],'>=',0)
+		md = checkfield(md,'fieldname','inversion.step_threshold','size',[md.inversion.nsteps])
+		md = checkfield(md,'fieldname','inversion.cost_functions','size',[num_costfunc],'values',[101,102,103,104,105,201,501,502,503,504,505])
+		md = checkfield(md,'fieldname','inversion.cost_functions_coefficients','size',[md.mesh.numberofvertices,num_costfunc],'>=',0)
+		md = checkfield(md,'fieldname','inversion.gradient_scaling','size',[md.inversion.nsteps,num_controls])
+		md = checkfield(md,'fieldname','inversion.min_parameters','size',[md.mesh.numberofvertices,num_controls])
+		md = checkfield(md,'fieldname','inversion.max_parameters','size',[md.mesh.numberofvertices,num_controls])
 
 		#Only SSA, HO and FS are supported right now
@@ -135,8 +135,8 @@
 
 		if solution==BalancethicknessSolutionEnum():
-			md = checkfield(md,'inversion.thickness_obs','size',[md.mesh.numberofvertices],'NaN',1)
+			md = checkfield(md,'fieldname','inversion.thickness_obs','size',[md.mesh.numberofvertices],'NaN',1)
 		else:
-			md = checkfield(md,'inversion.vx_obs','size',[md.mesh.numberofvertices],'NaN',1)
-			md = checkfield(md,'inversion.vy_obs','size',[md.mesh.numberofvertices],'NaN',1)
+			md = checkfield(md,'fieldname','inversion.vx_obs','size',[md.mesh.numberofvertices],'NaN',1)
+			md = checkfield(md,'fieldname','inversion.vy_obs','size',[md.mesh.numberofvertices],'NaN',1)
 
 		return md
@@ -173,15 +173,26 @@
 		num_cost_functions=numpy.size(self.cost_functions)
 		data=copy.deepcopy(self.cost_functions)
-		data=[SurfaceAbsVelMisfitEnum()        if x==101 else x for x in data]
-		data=[SurfaceRelVelMisfitEnum()        if x==102 else x for x in data]
-		data=[SurfaceLogVelMisfitEnum()        if x==103 else x for x in data]
-		data=[SurfaceLogVxVyMisfitEnum()       if x==104 else x for x in data]
-		data=[SurfaceAverageVelMisfitEnum()    if x==105 else x for x in data]
-		data=[ThicknessAbsMisfitEnum()         if x==201 else x for x in data]
-		data=[DragCoefficientAbsGradientEnum() if x==501 else x for x in data]
-		data=[RheologyBbarAbsGradientEnum()    if x==502 else x for x in data]
-		data=[ThicknessAbsGradientEnum()       if x==503 else x for x in data]
-		data=[ThicknessAlongGradientEnum()     if x==504 else x for x in data]
-		data=[ThicknessAcrossGradientEnum()    if x==505 else x for x in data]
+		pos=[i for i,x in enumerate(self.cost_functions) if x==101];
+		for i in pos: data[i]=SurfaceAbsVelMisfitEnum()        
+		pos=[i for i,x in enumerate(self.cost_functions) if x==102];
+		for i in pos: data[i]=SurfaceRelVelMisfitEnum()        
+		pos=[i for i,x in enumerate(self.cost_functions) if x==103];
+		for i in pos: data[i]=SurfaceLogVelMisfitEnum()        
+		pos=[i for i,x in enumerate(self.cost_functions) if x==104];
+		for i in pos: data[i]=SurfaceLogVxVyMisfitEnum()       
+		pos=[i for i,x in enumerate(self.cost_functions) if x==105];
+		for i in pos: data[i]=SurfaceAverageVelMisfitEnum()    
+		pos=[i for i,x in enumerate(self.cost_functions) if x==201];
+		for i in pos: data[i]=ThicknessAbsMisfitEnum()         
+		pos=[i for i,x in enumerate(self.cost_functions) if x==501];
+		for i in pos: data[i]=DragCoefficientAbsGradientEnum() 
+		pos=[i for i,x in enumerate(self.cost_functions) if x==502];
+		for i in pos: data[i]=RheologyBbarAbsGradientEnum()    
+		pos=[i for i,x in enumerate(self.cost_functions) if x==503];
+		for i in pos: data[i]=ThicknessAbsGradientEnum()       
+		pos=[i for i,x in enumerate(self.cost_functions) if x==504];
+		for i in pos: data[i]=ThicknessAlongGradientEnum()     
+		pos=[i for i,x in enumerate(self.cost_functions) if x==505];
+		for i in pos: data[i]=ThicknessAcrossGradientEnum()    
 		WriteData(fid,'data',numpy.array(data).reshape(1,-1),'enum',InversionCostFunctionsEnum(),'format','DoubleMat','mattype',3)
 		WriteData(fid,'data',num_cost_functions,'enum',InversionNumCostFunctionsEnum(),'format','Integer')
Index: /issm/trunk/src/m/classes/mask.m
===================================================================
--- /issm/trunk/src/m/classes/mask.m	(revision 17805)
+++ /issm/trunk/src/m/classes/mask.m	(revision 17806)
@@ -9,5 +9,23 @@
 		ice_levelset         = NaN;
 	end
+	methods (Static)
+		function obj = loadobj(obj) % {{{
+			% This function is directly called by matlab when a model object is
+			% loaded. Update old properties here
+
+			%2014 February 5th
+			if numel(obj.ice_levelset)>1 & all(obj.ice_levelset>=0),
+				disp('WARNING: md.mask.ice_levelset>=0, you probably need to change the sign of this levelset');
+			end
+
+		end% }}}
+	end
 	methods
+        function createxml(obj,fid) % {{{
+            fprintf(fid, '\n\n');
+            fprintf(fid, '%s\n', '<!-- mask -->');
+			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="groundedice_levelset" type="',class(obj.groundedice_levelset),'" default="',obj.groundedice_levelset,'">','     <section name="mask" />','     <help> is ice grounded ? grounded ice if > 0, grounding line position if = 0, floating ice if &amp;lt; 0 </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n','<parameter key ="ice_levelset" type="',class(obj.ice_levelset),'" default="',obj.ice_levelset,'">','     <section name="mask" />','     <help> presence of ice if > 0, icefront position if = 0, no ice if &amp;lt; 0 </help>','</parameter>');
+		end % }}}
 		function obj = mask(varargin) % {{{
 			switch nargin
@@ -23,10 +41,10 @@
 		function md = checkconsistency(obj,md,solution,analyses) % {{{
 
-			md = checkfield(md,'mask.groundedice_levelset','size',[md.mesh.numberofvertices 1]);
-			md = checkfield(md,'mask.ice_levelset'        ,'size',[md.mesh.numberofvertices 1]);
-			isice=(md.mask.ice_levelset>0);
-			if any(sum(isice(md.mesh.elements),2)==0),
-				warning('elements with no ice not implemented yet, each element should have at least one vertex with md.mask.ice_levelset > 0');
-			end
+			md = checkfield(md,'fieldname','mask.groundedice_levelset','size',[md.mesh.numberofvertices 1]);
+			md = checkfield(md,'fieldname','mask.ice_levelset'        ,'size',[md.mesh.numberofvertices 1]);
+			%isice=(md.mask.ice_levelset>0);
+			%if any(sum(isice(md.mesh.elements),2)==0),
+		%		warning('elements with no ice not implemented yet, each element should have at least one vertex with md.mask.ice_levelset > 0');
+		%	end
 		end % }}}
 		function disp(obj) % {{{
@@ -34,9 +52,17 @@
 
 			fielddisplay(obj,'groundedice_levelset','is ice grounded ? grounded ice if > 0, grounding line position if = 0, floating ice if < 0');
-			fielddisplay(obj,'ice_levelset','presence of ice if > 0, icefront position if = 0, no ice if < 0');
+			fielddisplay(obj,'ice_levelset','presence of ice if < 0, icefront position if = 0, no ice if > 0');
 		end % }}}
 		function marshall(obj,md,fid) % {{{
 			WriteData(fid,'object',obj,'fieldname','groundedice_levelset','format','DoubleMat','mattype',1);
 			WriteData(fid,'object',obj,'fieldname','ice_levelset','format','DoubleMat','mattype',1);
+
+			% get mask of vertices of elements with ice
+			isice=md.mask.ice_levelset<=0.;
+			vlist = zeros(md.mesh.numberofvertices,1);
+			pos=find(sum(isice(md.mesh.elements),2)>0);
+			vlist(md.mesh.elements(pos,:))=1;
+			WriteData(fid,'data',vlist,'enum',IceMaskNodeActivationEnum(),'format','DoubleMat','mattype',1);
+
 		end % }}}
 	end
Index: /issm/trunk/src/m/classes/mask.py
===================================================================
--- /issm/trunk/src/m/classes/mask.py	(revision 17805)
+++ /issm/trunk/src/m/classes/mask.py	(revision 17806)
@@ -1,6 +1,7 @@
+import numpy
 from fielddisplay import fielddisplay
 from EnumDefinitions import *
-from checkfield import *
-from WriteData import *
+from checkfield import checkfield
+from WriteData import WriteData
 
 class mask(object):
@@ -24,5 +25,5 @@
 
 		string="%s\n%s"%(string,fielddisplay(self,"groundedice_levelset","is ice grounded ? grounded ice if > 0, grounding line position if = 0, floating ice if < 0"))
-		string="%s\n%s"%(string,fielddisplay(self,"ice_levelset","presence of ice if > 0, icefront position if = 0, no ice if < 0"))
+		string="%s\n%s"%(string,fielddisplay(self,"ice_levelset","presence of ice if < 0, icefront position if = 0, no ice if > 0"))
 		return string
 		#}}}
@@ -32,9 +33,9 @@
 	def checkconsistency(self,md,solution,analyses):    # {{{
 
-		md = checkfield(md,'mask.ice_levelset'        ,'size',[md.mesh.numberofvertices])
-		isice=numpy.array(md.mask.ice_levelset>0,int)
-		totallyicefree=(numpy.sum(isice[md.mesh.elements-1],axis=1)==0).astype(int)
-		if any(totallyicefree):
-			raise TypeError("elements with no ice not implemented yet, each element should have at least one vertex with md.mask.ice_levelset > 0")
+		md = checkfield(md,'fieldname','mask.ice_levelset'        ,'size',[md.mesh.numberofvertices])
+		#isice=numpy.array(md.mask.ice_levelset<0,int)
+		#totallyicefree=(numpy.sum(isice[md.mesh.elements-1],axis=1)==0).astype(int)
+		#if any(totallyicefree):
+		#	raise TypeError("elements with no ice not implemented yet, each element should have at least one vertex with md.mask.ice_levelset > 0")
 
 		return md
@@ -43,3 +44,10 @@
 		WriteData(fid,'object',self,'fieldname','groundedice_levelset','format','DoubleMat','mattype',1)
 		WriteData(fid,'object',self,'fieldname','ice_levelset','format','DoubleMat','mattype',1)
+
+		# get mask of vertices of elements with ice
+		isice=numpy.array(md.mask.ice_levelset<0.,int)
+		vlist = numpy.zeros((md.mesh.numberofvertices,1), dtype=int)
+		pos=numpy.nonzero(numpy.sum(isice[md.mesh.elements-1],axis=1))[0]
+		vlist[md.mesh.elements[pos,:]-1]=1
+		WriteData(fid,'data',vlist,'enum',IceMaskNodeActivationEnum(),'format','DoubleMat','mattype',1);
 	# }}}
Index: /issm/trunk/src/m/classes/massfluxatgate.py
===================================================================
--- /issm/trunk/src/m/classes/massfluxatgate.py	(revision 17805)
+++ /issm/trunk/src/m/classes/massfluxatgate.py	(revision 17806)
@@ -1,7 +1,7 @@
 from fielddisplay import fielddisplay
 from EnumDefinitions import *
-from checkfield import *
-from WriteData import *
-from MeshProfileIntersection import *
+from checkfield import checkfield
+from WriteData import WriteData
+from MeshProfileIntersection import MeshProfileIntersection
 import os
 
Index: /issm/trunk/src/m/classes/masstransport.m
===================================================================
--- /issm/trunk/src/m/classes/masstransport.m	(revision 17805)
+++ /issm/trunk/src/m/classes/masstransport.m	(revision 17806)
@@ -7,4 +7,5 @@
 	properties (SetAccess=public) 
 		 spcthickness           = NaN;
+		 calvingrate            = NaN;
 		 isfreesurface          = 0;
 		 min_thickness          = 0;
@@ -42,4 +43,25 @@
 	end
 	methods
+         function createxml(obj,fid) % {{{
+            fprintf(fid, '<!-- masstransport -->\n');            
+                    
+            % Masstransport solution parameters
+            fprintf(fid,'%s\n%s\n%s\n','<frame key="1" label="Masstransport solution parameters">','<section name="masstransport" />');                    
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="spcthickness" type="',class(obj.spcthickness),'" default="',convert2str(obj.spcthickness),'">','     <section name="masstransport" />','     <help> thickness constraints (NaN means no constraint) [m] </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="calvingrate" type="',class(obj.calvingrate),'" default="',convert2str(obj.calvingrate),'">','     <section name="masstransport" />','     <help> calving rate at given location [m/a] </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="isfreesurface" type="',class(obj.isfreesurface),'" default="',convert2str(obj.isfreesurface),'">','     <section name="masstransport" />','     <help> do we use free surfaces (FS only) are mass conservation </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="min_thickness" type="',class(obj.min_thickness),'" default="',convert2str(obj.min_thickness),'">','     <section name="masstransport" />','     <help> minimum ice thickness allowed [m] </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="hydrostatic_adjustment" type="',class(obj.hydrostatic_adjustment),'" default="',convert2str(obj.hydrostatic_adjustment),'">','     <section name="masstransport" />','     <help> adjustment of ice shelves surface and bed elevations: ''Incremental'' or ''Absolute''  </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="stabilization" type="',class(obj.stabilization),'" default="',convert2str(obj.stabilization),'">','     <section name="masstransport" />','     <help> 0: no, 1:  artificial_diffusivity, 2: streamline upwinding, 3: discontinuous Galerkin </help>','  </parameter>');
+            fprintf(fid,'%s\n%s\n','</frame>');    
+            
+            %Penalty options
+            fprintf(fid,'%s\n%s\n%s\n','<frame key="2" label="Penalty options">','<section name="masstransport" />'); 
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="vertex_pairing" type="',class(obj.vertex_pairing),'" default="',convert2str(obj.vertex_pairing),'">','     <section name="masstransport" />','     <help> offset used by penalties: penalty = Kmax*10^offset </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="penalty_factor" type="',class(obj.penalty_factor),'" default="',convert2str(obj.penalty_factor),'">','     <section name="masstransport" />','     <help> pairs of vertices that are penalized </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="requested_outputs" type="',class(obj.requested_outputs),'" default="',convert2str(obj.requested_outputs),'">','     <section name="masstransport" />','     <help> additional outputs requested </help>','  </parameter>');
+            fprintf(fid,'%s\n%s\n','</frame>');
+        
+        end % }}}
 		function obj = masstransport(varargin) % {{{
 			switch nargin
@@ -62,5 +84,5 @@
 		function list = defaultoutputs(self,md) % {{{
 
-			list = {'Thickness','Surface','Bed'};
+			list = {'Thickness','Surface','Base'};
 
 		end % }}}
@@ -87,10 +109,14 @@
 			if ~ismember(MasstransportAnalysisEnum(),analyses) |  (solution==TransientSolutionEnum() & md.transient.ismasstransport==0), return; end
 
-			md = checkfield(md,'masstransport.spcthickness','forcing',1);
-			md = checkfield(md,'masstransport.isfreesurface','values',[0 1]);
-			md = checkfield(md,'masstransport.hydrostatic_adjustment','values',{'Absolute' 'Incremental'});
-			md = checkfield(md,'masstransport.stabilization','values',[0 1 2 3]);
-			md = checkfield(md,'masstransport.min_thickness','>',0);
-			md = checkfield(md,'masstransport.requested_outputs','stringrow',1);
+			md = checkfield(md,'fieldname','masstransport.spcthickness','forcing',1);
+			if(ismember(LevelsetAnalysisEnum(), analyses) & md.transient.islevelset)
+				md = checkfield(md,'fieldname','masstransport.calvingrate','NaN',1,'size',[md.mesh.numberofvertices 1],'>=',0);
+			end
+
+			md = checkfield(md,'fieldname','masstransport.isfreesurface','values',[0 1]);
+			md = checkfield(md,'fieldname','masstransport.hydrostatic_adjustment','values',{'Absolute' 'Incremental'});
+			md = checkfield(md,'fieldname','masstransport.stabilization','values',[0 1 2 3]);
+			md = checkfield(md,'fieldname','masstransport.min_thickness','>',0);
+			md = checkfield(md,'fieldname','masstransport.requested_outputs','stringrow',1);
 
 		end % }}}
@@ -98,4 +124,5 @@
 			disp(sprintf('   Masstransport solution parameters:'));
 			fielddisplay(obj,'spcthickness','thickness constraints (NaN means no constraint) [m]');
+			fielddisplay(obj,'calvingrate','calving rate at given location [m/a]');
 			fielddisplay(obj,'isfreesurface','do we use free surfaces (FS only) are mass conservation');
 			fielddisplay(obj,'min_thickness','minimum ice thickness allowed [m]');
@@ -110,5 +137,9 @@
 		end % }}}
 		function marshall(obj,md,fid) % {{{
+
+			yts=365.*24.*3600.;
+
 			WriteData(fid,'object',obj,'fieldname','spcthickness','format','DoubleMat','mattype',1,'forcinglength',md.mesh.numberofvertices+1);
+			WriteData(fid,'object',obj,'fieldname','calvingrate','format','DoubleMat','mattype',1,'forcinglength',md.mesh.numberofvertices+1,'scale',1./yts);
 			WriteData(fid,'object',obj,'fieldname','isfreesurface','format','Boolean');
 			WriteData(fid,'object',obj,'fieldname','min_thickness','format','Double');
Index: /issm/trunk/src/m/classes/masstransport.py
===================================================================
--- /issm/trunk/src/m/classes/masstransport.py	(revision 17805)
+++ /issm/trunk/src/m/classes/masstransport.py	(revision 17806)
@@ -2,6 +2,6 @@
 from EnumDefinitions import *
 from StringToEnum import StringToEnum
-from checkfield import *
-from WriteData import *
+from checkfield import checkfield
+from WriteData import WriteData
 
 class masstransport(object):
@@ -15,4 +15,5 @@
 	def __init__(self): # {{{
 		self.spcthickness           = float('NaN')
+		self.calvingrate            = float('NaN')
 		self.isfreesurface          = 0
 		self.min_thickness          = 0
@@ -30,4 +31,5 @@
 		string='   Masstransport solution parameters:'
 		string="%s\n%s"%(string,fielddisplay(self,'spcthickness','thickness constraints (NaN means no constraint) [m]'))
+		string="%s\n%s"%(string,fielddisplay(self,'calvingrate','calving rate at given location [m/a]'))
 		string="%s\n%s"%(string,fielddisplay(self,'isfreesurface','do we use free surfaces (FS only) are mass conservation'))
 		string="%s\n%s"%(string,fielddisplay(self,'min_thickness','minimum ice thickness allowed [m]'))
@@ -40,5 +42,5 @@
 	def defaultoutputs(self,md): # {{{
 
-		return ['Thickness','Surface','Bed']
+		return ['Thickness','Surface','Base']
 
 	#}}}
@@ -67,15 +69,21 @@
 			return md
 
-		md = checkfield(md,'masstransport.spcthickness','forcing',1)
-		md = checkfield(md,'masstransport.isfreesurface','values',[0,1])
-		md = checkfield(md,'masstransport.hydrostatic_adjustment','values',['Absolute','Incremental'])
-		md = checkfield(md,'masstransport.stabilization','values',[0,1,2,3])
-		md = checkfield(md,'masstransport.min_thickness','>',0)
-		md = checkfield(md,'masstransport.requested_outputs','stringrow',1)
+		md = checkfield(md,'fieldname','masstransport.spcthickness','forcing',1)
+		if LevelsetAnalysisEnum() in analyses and md.transient.islevelset:
+			md = checkfield(md,'fieldname','masstransport.calvingrate','NaN',1,'size',[md.mesh.numberofvertices],'>=',0)
+		md = checkfield(md,'fieldname','masstransport.isfreesurface','values',[0,1])
+		md = checkfield(md,'fieldname','masstransport.hydrostatic_adjustment','values',['Absolute','Incremental'])
+		md = checkfield(md,'fieldname','masstransport.stabilization','values',[0,1,2,3])
+		md = checkfield(md,'fieldname','masstransport.min_thickness','>',0)
+		md = checkfield(md,'fieldname','masstransport.requested_outputs','stringrow',1)
 
 		return md
 	# }}}
 	def marshall(self,md,fid):    # {{{
+
+		yts=365.*24.*3600.
+
 		WriteData(fid,'object',self,'fieldname','spcthickness','format','DoubleMat','mattype',1,'forcinglength',md.mesh.numberofvertices+1)
+		WriteData(fid,'object',self,'fieldname','calvingrate','format','DoubleMat','mattype',1,'forcinglength',md.mesh.numberofvertices+1,'scale',1./yts)
 		WriteData(fid,'object',self,'fieldname','isfreesurface','format','Boolean')
 		WriteData(fid,'object',self,'fieldname','min_thickness','format','Double')
Index: /issm/trunk/src/m/classes/matdamageice.m
===================================================================
--- /issm/trunk/src/m/classes/matdamageice.m	(revision 17806)
+++ /issm/trunk/src/m/classes/matdamageice.m	(revision 17806)
@@ -0,0 +1,197 @@
+%MATDAMAGEICE class definition
+%
+%   Usage:
+%      matdamageice=matdamageice();
+
+classdef matdamageice
+	properties (SetAccess=public) 
+		rho_ice                    = 0.;
+		rho_water                  = 0.;
+		rho_freshwater             = 0.;
+		mu_water                   = 0.;
+		heatcapacity               = 0.;
+		latentheat                 = 0.;
+		thermalconductivity        = 0.;
+		temperateiceconductivity   = 0.;
+		meltingpoint               = 0.;
+		beta                       = 0.;
+		mixed_layer_capacity       = 0.;
+		thermal_exchange_velocity  = 0.;
+		rheology_B   = NaN;
+		rheology_n   = NaN;
+		rheology_law = '';
+
+		%gia: 
+		lithosphere_shear_modulus  = 0.;
+		lithosphere_density        = 0.;
+		mantle_shear_modulus       = 0.;
+		mantle_density             = 0.;
+
+	end
+	methods
+        function createxml(obj,fid) % {{{
+            fprintf(fid, '\n\n');
+            fprintf(fid, '<!-- materials -->\n');
+			 fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="rho_ice" type="',class(obj.rho_ice),'" default="',convert2str(obj.rho_ice),'">','     <section name="materials" />','     <help> ice density [kg/m^3] </help>','</parameter>');
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="rho_water" type="',class(obj.rho_water),'" default="',convert2str(obj.rho_water),'">','     <section name="materials" />','     <help> ocean water density [kg/m^3] </help>','</parameter>');
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="rho_freshwater" type="',class(obj.rho_freshwater),'" default="',convert2str(obj.rho_freshwater),'">','     <section name="materials" />','     <help> fresh water density [kg/m^3] </help>','</parameter>');
+             
+  
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="mu_water" type="',class(obj.mu_water),'" default="',convert2str(obj.mu_water),'">','     <section name="materials" />','     <help> water viscosity [N s/m^2] </help>','</parameter>');
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="heatcapacity" type="',class(obj.heatcapacity),'" default="',convert2str(obj.heatcapacity),'">','     <section name="materials" />','     <help> heat capacity [J/kg/K] </help>','</parameter>');
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="latentheat" type="',class(obj.latentheat),'" default="',convert2str(obj.latentheat),'">','     <section name="materials" />','     <help> latent heat of fusion [J/kg] </help>','</parameter>');
+             
+             
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="thermalconductivity" type="',class(obj.thermalconductivity),'" default="',convert2str(obj.thermalconductivity),'">','     <section name="materials" />','     <help> ice thermal conductivity [W/m/K] </help>','</parameter>');
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="temperateiceconductivity" type="',class(obj.temperateiceconductivity),'" default="',convert2str(obj.temperateiceconductivity),'">','     <section name="materials" />','     <help> temperate ice thermal conductivity [W/m/K] </help>','</parameter>');
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="meltingpoint" type="',class(obj.meltingpoint),'" default="',convert2str(obj.meltingpoint),'">','     <section name="materials" />','     <help> melting point of ice at 1atm in K </help>','</parameter>');
+             
+             
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="beta" type="',class(obj.beta),'" default="',convert2str(obj.beta),'">','     <section name="materials" />','     <help> rate of change of melting point with pressure [K/Pa] </help>','</parameter>');
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="mixed_layer_capacity" type="',class(obj.mixed_layer_capacity),'" default="',convert2str(obj.mixed_layer_capacity),'">','     <section name="materials" />','     <help> mixed layer capacity [W/kg/K] </help>','</parameter>');
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="thermal_exchange_velocity" type="',class(obj.thermal_exchange_velocity),'" default="',convert2str(obj.thermal_exchange_velocity),'">','     <section name="materials" />','     <help> thermal exchange velocity [m/s] </help>','</parameter>');
+             
+             
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="rheology_B" type="',class(obj.rheology_B),'" default="',convert2str(obj.rheology_B),'">','     <section name="materials" />','     <help> flow law parameter [Pa/s^(1/n)] </help>','</parameter>');
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="rheology_n" type="',class(obj.rheology_n),'" default="',convert2str(obj.rheology_n),'">','     <section name="materials" />','     <help> Glens flow law exponent </help>','</parameter>');
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="rheology_law" type="',class(obj.rheology_law),'" default="',convert2str(obj.rheology_law),'">','     <section name="materials" />','     <help> law for the temperature dependance of the rheology: "None", "Paterson",  "Arrhenius" or "LliboutryDuval" </help>','</parameter>');
+             
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="lithosphere_shear_modulus" type="',class(obj.lithosphere_shear_modulus),'" default="',convert2str(obj.lithosphere_shear_modulus),'">','     <section name="materials" />','     <help> Lithosphere shear modulus [Pa] </help>','</parameter>');
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="lithosphere_density" type="',class(obj.lithosphere_density),'" default="',convert2str(obj.lithosphere_density),'">','     <section name="materials" />','     <help> Lithosphere density [g/cm^-3] </help>','</parameter>');
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="mantle_shear_modulus" type="',class(obj.mantle_shear_modulus),'" default="',convert2str(obj.mantle_shear_modulus),'">','     <section name="materials" />','     <help> Mantle shear modulus [Pa] </help>','</parameter>');
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="mantle_density" type="',class(obj.mantle_density),'" default="',convert2str(obj.mantle_density),'">','     <section name="materials" />','     <help> Mantle density [g/cm^-3] </help>','</parameter>');
+        
+         
+        end % }}}
+		function obj = matdamageice(varargin) % {{{
+			switch nargin
+				case 0
+					obj=setdefaultparameters(obj);
+				case 1
+					inputstruct=varargin{1};
+					list1 = properties('matdamageice');
+					list2 = fieldnames(inputstruct);
+					for i=1:length(list1)
+						fieldname = list1{i};
+						if ismember(fieldname,list2),
+							obj.(fieldname) = inputstruct.(fieldname);
+						end
+					end
+				otherwise
+					error('constructor not supported');
+			end
+		end % }}}
+		function obj = setdefaultparameters(obj) % {{{
+
+			%ice density (kg/m^3)
+			obj.rho_ice=917.;
+
+			%ocean water density (kg/m^3)
+			obj.rho_water=1023.;
+
+			%fresh water density (kg/m^3)
+			obj.rho_freshwater=1000.;
+
+			%water viscosity (N.s/m^2)
+			obj.mu_water=0.001787;  
+
+			%ice heat capacity cp (J/kg/K)
+			obj.heatcapacity=2093.;
+
+			%ice latent heat of fusion L (J/kg)
+			obj.latentheat=3.34*10^5;
+
+			%ice thermal conductivity (W/m/K)
+			obj.thermalconductivity=2.4;
+			
+			%wet ice thermal conductivity (W/m/K)
+			obj.temperateiceconductivity=.24;
+
+			%the melting point of ice at 1 atmosphere of pressure in K
+			obj.meltingpoint=273.15;
+
+			%rate of change of melting point with pressure (K/Pa)
+			obj.beta=9.8*10^-8;
+
+			%mixed layer (ice-water interface) heat capacity (J/kg/K)
+			obj.mixed_layer_capacity=3974.;
+
+			%thermal exchange velocity (ice-water interface) (m/s)
+			obj.thermal_exchange_velocity=1.00*10^-4;
+
+			%Rheology law: what is the temperature dependence of B with T
+			%available: none, paterson and arrhenius
+			obj.rheology_law='Paterson';
+
+			% GIA:
+			obj.lithosphere_shear_modulus  = 6.7*10^10;  % (Pa)
+			obj.lithosphere_density        = 3.32;       % (g/cm^-3)
+			obj.mantle_shear_modulus       = 1.45*10^11; % (Pa)
+			obj.mantle_density             = 3.34;       % (g/cm^-3)
+
+		end % }}}
+		function md = checkconsistency(obj,md,solution,analyses) % {{{
+			md = checkfield(md,'fieldname','materials.rho_ice','>',0);
+			md = checkfield(md,'fieldname','materials.rho_water','>',0);
+			md = checkfield(md,'fieldname','materials.rho_freshwater','>',0);
+			md = checkfield(md,'fieldname','materials.mu_water','>',0);
+			md = checkfield(md,'fieldname','materials.rheology_B','>',0,'size',[md.mesh.numberofvertices 1]);
+			md = checkfield(md,'fieldname','materials.rheology_n','>',0,'size',[md.mesh.numberofelements 1]);
+			md = checkfield(md,'fieldname','materials.rheology_law','values',{'None' 'Cuffey' 'Paterson' 'Arrhenius' 'LliboutryDuval'});
+
+			if ismember(GiaAnalysisEnum(),analyses),
+				md = checkfield(md,'fieldname','materials.lithosphere_shear_modulus','>',0,'numel',1);
+				md = checkfield(md,'fieldname','materials.lithosphere_density','>',0,'numel',1);
+				md = checkfield(md,'fieldname','materials.mantle_shear_modulus','>',0,'numel',1);
+				md = checkfield(md,'fieldname','materials.mantle_density','>',0,'numel',1);
+			end
+
+		end % }}}
+		function disp(obj) % {{{
+			disp(sprintf('   Materials:'));
+
+			fielddisplay(obj,'rho_ice','ice density [kg/m^3]');
+			fielddisplay(obj,'rho_water','ocean water density [kg/m^3]');
+			fielddisplay(obj,'rho_freshwater','fresh water density [kg/m^3]');
+			fielddisplay(obj,'mu_water','water viscosity [N s/m^2]');
+			fielddisplay(obj,'heatcapacity','heat capacity [J/kg/K]');
+			fielddisplay(obj,'thermalconductivity',['ice thermal conductivity [W/m/K]']);
+			fielddisplay(obj,'temperateiceconductivity','temperate ice thermal conductivity [W/m/K]');
+			fielddisplay(obj,'meltingpoint','melting point of ice at 1atm in K');
+			fielddisplay(obj,'latentheat','latent heat of fusion [J/kg]');
+			fielddisplay(obj,'beta','rate of change of melting point with pressure [K/Pa]');
+			fielddisplay(obj,'mixed_layer_capacity','mixed layer capacity [W/kg/K]');
+			fielddisplay(obj,'thermal_exchange_velocity','thermal exchange velocity [m/s]');
+			fielddisplay(obj,'rheology_B','flow law parameter [Pa/s^(1/n)]');
+			fielddisplay(obj,'rheology_n','Glen''s flow law exponent');
+			fielddisplay(obj,'rheology_law',['law for the temperature dependance of the rheology: ''None'', ''Cuffey'', ''Paterson'', ''Arrhenius'' or ''LliboutryDuval''']);
+			fielddisplay(obj,'lithosphere_shear_modulus','Lithosphere shear modulus [Pa]');
+			fielddisplay(obj,'lithosphere_density','Lithosphere density [g/cm^-3]');
+			fielddisplay(obj,'mantle_shear_modulus','Mantle shear modulus [Pa]');
+			fielddisplay(obj,'mantle_density','Mantle density [g/cm^-3]');
+		end % }}}
+		function marshall(obj,md,fid) % {{{
+			WriteData(fid,'enum',MaterialsEnum(),'data',MatdamageiceEnum(),'format','Integer');
+			WriteData(fid,'object',obj,'class','materials','fieldname','rho_ice','format','Double');
+			WriteData(fid,'object',obj,'class','materials','fieldname','rho_water','format','Double');
+			WriteData(fid,'object',obj,'class','materials','fieldname','rho_freshwater','format','Double');
+			WriteData(fid,'object',obj,'class','materials','fieldname','mu_water','format','Double');
+			WriteData(fid,'object',obj,'class','materials','fieldname','heatcapacity','format','Double');
+			WriteData(fid,'object',obj,'class','materials','fieldname','latentheat','format','Double');
+			WriteData(fid,'object',obj,'class','materials','fieldname','thermalconductivity','format','Double');
+			WriteData(fid,'object',obj,'class','materials','fieldname','temperateiceconductivity','format','Double');
+			WriteData(fid,'object',obj,'class','materials','fieldname','meltingpoint','format','Double');
+			WriteData(fid,'object',obj,'class','materials','fieldname','beta','format','Double');
+			WriteData(fid,'object',obj,'class','materials','fieldname','mixed_layer_capacity','format','Double');
+			WriteData(fid,'object',obj,'class','materials','fieldname','thermal_exchange_velocity','format','Double');
+			WriteData(fid,'object',obj,'class','materials','fieldname','rheology_B','format','DoubleMat','mattype',1);
+			WriteData(fid,'object',obj,'class','materials','fieldname','rheology_n','format','DoubleMat','mattype',2);
+			WriteData(fid,'data',StringToEnum(obj.rheology_law),'enum',MaterialsRheologyLawEnum(),'format','Integer');
+
+			WriteData(fid,'object',obj,'class','materials','fieldname','lithosphere_shear_modulus','format','Double');
+			WriteData(fid,'object',obj,'class','materials','fieldname','lithosphere_density','format','Double','scale',10^3);
+			WriteData(fid,'object',obj,'class','materials','fieldname','mantle_shear_modulus','format','Double');
+			WriteData(fid,'object',obj,'class','materials','fieldname','mantle_density','format','Double','scale',10^3);
+		end % }}}
+	end
+end
Index: /issm/trunk/src/m/classes/matdamageice.py
===================================================================
--- /issm/trunk/src/m/classes/matdamageice.py	(revision 17806)
+++ /issm/trunk/src/m/classes/matdamageice.py	(revision 17806)
@@ -0,0 +1,150 @@
+from fielddisplay import fielddisplay
+from EnumDefinitions import MaterialsEnum, MatdamageiceEnum, MaterialsRheologyLawEnum
+from StringToEnum import StringToEnum
+from checkfield import checkfield
+from WriteData import WriteData
+
+class matdamageice(object):
+	"""
+	MATICE class definition
+
+	   Usage:
+	      matdamagice=matdamageice();
+	"""
+
+	def __init__(self): # {{{
+		self.rho_ice                   = 0.
+		self.rho_water                 = 0.
+		self.rho_freshwater            = 0.
+		self.mu_water                  = 0.
+		self.heatcapacity              = 0.
+		self.latentheat                = 0.
+		self.thermalconductivity       = 0.
+		self.temperateiceconductivity  = 0.
+		self.meltingpoint              = 0.
+		self.beta                      = 0.
+		self.mixed_layer_capacity      = 0.
+		self.thermal_exchange_velocity = 0.
+		self.rheology_B                = float('NaN')
+		self.rheology_n                = float('NaN')
+		self.rheology_law              = ''
+
+		#gia: 
+		self.lithosphere_shear_modulus  = 0.
+		self.lithosphere_density        = 0.
+		self.mantle_shear_modulus       = 0.
+		self.mantle_density             = 0.
+
+		self.setdefaultparameters()
+		#}}}
+	def __repr__(self): # {{{
+		string="   Materials:"
+
+		string="%s\n%s"%(string,fielddisplay(self,"rho_ice","ice density [kg/m^3]"))
+		string="%s\n%s"%(string,fielddisplay(self,"rho_water","water density [kg/m^3]"))
+		string="%s\n%s"%(string,fielddisplay(self,"rho_freshwater","fresh water density [kg/m^3]"))
+		string="%s\n%s"%(string,fielddisplay(self,"mu_water","water viscosity [N s/m^2]"))
+		string="%s\n%s"%(string,fielddisplay(self,"heatcapacity","heat capacity [J/kg/K]"))
+		string="%s\n%s"%(string,fielddisplay(self,"thermalconductivity","ice thermal conductivity [W/m/K]"))
+		string="%s\n%s"%(string,fielddisplay(self,"temperateiceconductivity","temperate ice thermal conductivity [W/m/K]"))
+		string="%s\n%s"%(string,fielddisplay(self,"meltingpoint","melting point of ice at 1atm in K"))
+		string="%s\n%s"%(string,fielddisplay(self,"latentheat","latent heat of fusion [J/m^3]"))
+		string="%s\n%s"%(string,fielddisplay(self,"beta","rate of change of melting point with pressure [K/Pa]"))
+		string="%s\n%s"%(string,fielddisplay(self,"mixed_layer_capacity","mixed layer capacity [W/kg/K]"))
+		string="%s\n%s"%(string,fielddisplay(self,"thermal_exchange_velocity","thermal exchange velocity [m/s]"))
+		string="%s\n%s"%(string,fielddisplay(self,"rheology_B","flow law parameter [Pa/s^(1/n)]"))
+		string="%s\n%s"%(string,fielddisplay(self,"rheology_n","Glen's flow law exponent"))
+		string="%s\n%s"%(string,fielddisplay(self,"rheology_law","law for the temperature dependance of the rheology: 'None', 'Cuffey', 'Paterson', 'Arrhenius' or 'LliboutryDuval'"))
+		string="%s\n%s"%(string,fielddisplay(self,"lithosphere_shear_modulus","Lithosphere shear modulus [Pa]"))
+		string="%s\n%s"%(string,fielddisplay(self,"lithosphere_density","Lithosphere density [g/cm^-3]"))
+		string="%s\n%s"%(string,fielddisplay(self,"mantle_shear_modulus","Mantle shear modulus [Pa]"))
+		string="%s\n%s"%(string,fielddisplay(self,"mantle_density","Mantle density [g/cm^-3]"))
+
+		return string
+		#}}}
+	def setdefaultparameters(self): # {{{
+		#ice density (kg/m^3)
+		self.rho_ice=917.
+
+		#ocean water density (kg/m^3)
+		self.rho_water=1023.
+
+		#fresh water density (kg/m^3)
+		self.rho_freshwater=1000.
+
+		#water viscosity (N.s/m^2)
+		self.mu_water=0.001787  
+
+		#ice heat capacity cp (J/kg/K)
+		self.heatcapacity=2093.
+
+		#ice latent heat of fusion L (J/kg)
+		self.latentheat=3.34*10**5
+
+		#ice thermal conductivity (W/m/K)
+		self.thermalconductivity=2.4
+
+		#temperate ice thermal conductivity (W/m/K)
+		self.temperateiceconductivity=0.24
+
+		#the melting point of ice at 1 atmosphere of pressure in K
+		self.meltingpoint=273.15
+
+		#rate of change of melting point with pressure (K/Pa)
+		self.beta=9.8*10**-8
+
+		#mixed layer (ice-water interface) heat capacity (J/kg/K)
+		self.mixed_layer_capacity=3974.
+
+		#thermal exchange velocity (ice-water interface) (m/s)
+		self.thermal_exchange_velocity=1.00*10**-4
+
+		#Rheology law: what is the temperature dependence of B with T
+		#available: none, paterson and arrhenius
+		self.rheology_law='Paterson'
+
+		# GIA:
+		self.lithosphere_shear_modulus  = 6.7*10**10  # (Pa)
+		self.lithosphere_density        = 3.32        # (g/cm^-3)
+		self.mantle_shear_modulus       = 1.45*10**11 # (Pa)
+		self.mantle_density             = 3.34        # (g/cm^-3)
+
+		return self
+		#}}}
+	def checkconsistency(self,md,solution,analyses):    # {{{
+		md = checkfield(md,'fieldname','materials.rho_ice','>',0)
+		md = checkfield(md,'fieldname','materials.rho_water','>',0)
+		md = checkfield(md,'fieldname','materials.rho_freshwater','>',0)
+		md = checkfield(md,'fieldname','materials.mu_water','>',0)
+		md = checkfield(md,'fieldname','materials.rheology_B','>',0,'size',[md.mesh.numberofvertices])
+		md = checkfield(md,'fieldname','materials.rheology_n','>',0,'size',[md.mesh.numberofelements])
+		md = checkfield(md,'fieldname','materials.rheology_law','values',['None','Cuffey','Paterson','Arrhenius','LliboutryDuval'])
+		md = checkfield(md,'fieldname','materials.lithosphere_shear_modulus','>',0,'numel',[1]);
+		md = checkfield(md,'fieldname','materials.lithosphere_density','>',0,'numel',[1]);
+		md = checkfield(md,'fieldname','materials.mantle_shear_modulus','>',0,'numel',[1]);
+		md = checkfield(md,'fieldname','materials.mantle_density','>',0,'numel',[1]);
+		return md
+	# }}}
+	def marshall(self,md,fid):    # {{{
+		WriteData(fid,'enum',MaterialsEnum(),'data',MatdamageiceEnum(),'format','Integer');
+		WriteData(fid,'object',self,'class','materials','fieldname','rho_ice','format','Double')
+		WriteData(fid,'object',self,'class','materials','fieldname','rho_water','format','Double')
+		WriteData(fid,'object',self,'class','materials','fieldname','rho_freshwater','format','Double')
+		WriteData(fid,'object',self,'class','materials','fieldname','mu_water','format','Double')
+		WriteData(fid,'object',self,'class','materials','fieldname','heatcapacity','format','Double')
+		WriteData(fid,'object',self,'class','materials','fieldname','latentheat','format','Double')
+		WriteData(fid,'object',self,'class','materials','fieldname','thermalconductivity','format','Double')
+		WriteData(fid,'object',self,'class','materials','fieldname','temperateiceconductivity','format','Double')
+		WriteData(fid,'object',self,'class','materials','fieldname','meltingpoint','format','Double')
+		WriteData(fid,'object',self,'class','materials','fieldname','beta','format','Double')
+		WriteData(fid,'object',self,'class','materials','fieldname','mixed_layer_capacity','format','Double')
+		WriteData(fid,'object',self,'class','materials','fieldname','thermal_exchange_velocity','format','Double')
+		WriteData(fid,'object',self,'class','materials','fieldname','rheology_B','format','DoubleMat','mattype',1)
+		WriteData(fid,'object',self,'class','materials','fieldname','rheology_n','format','DoubleMat','mattype',2)
+		WriteData(fid,'data',StringToEnum(self.rheology_law)[0],'enum',MaterialsRheologyLawEnum(),'format','Integer')
+
+		WriteData(fid,'object',self,'class','materials','fieldname','lithosphere_shear_modulus','format','Double');
+		WriteData(fid,'object',self,'class','materials','fieldname','lithosphere_density','format','Double','scale',10.**3.);
+		WriteData(fid,'object',self,'class','materials','fieldname','mantle_shear_modulus','format','Double');
+		WriteData(fid,'object',self,'class','materials','fieldname','mantle_density','format','Double','scale',10.**3.);
+	# }}}
Index: /issm/trunk/src/m/classes/matice.m
===================================================================
--- /issm/trunk/src/m/classes/matice.m	(revision 17805)
+++ /issm/trunk/src/m/classes/matice.m	(revision 17806)
@@ -13,4 +13,5 @@
 		latentheat                 = 0.;
 		thermalconductivity        = 0.;
+		temperateiceconductivity   = 0.;
 		meltingpoint               = 0.;
 		beta                       = 0.;
@@ -29,4 +30,38 @@
 	end
 	methods
+        function createxml(obj,fid) % {{{
+            fprintf(fid, '\n\n');
+            fprintf(fid, '<!-- materials -->\n');
+			 fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="rho_ice" type="',class(obj.rho_ice),'" default="',convert2str(obj.rho_ice),'">','     <section name="materials" />','     <help> ice density [kg/m^3] </help>','</parameter>');
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="rho_water" type="',class(obj.rho_water),'" default="',convert2str(obj.rho_water),'">','     <section name="materials" />','     <help> ocean water density [kg/m^3] </help>','</parameter>');
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="rho_freshwater" type="',class(obj.rho_freshwater),'" default="',convert2str(obj.rho_freshwater),'">','     <section name="materials" />','     <help> fresh water density [kg/m^3] </help>','</parameter>');
+             
+  
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="mu_water" type="',class(obj.mu_water),'" default="',convert2str(obj.mu_water),'">','     <section name="materials" />','     <help> water viscosity [N s/m^2] </help>','</parameter>');
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="heatcapacity" type="',class(obj.heatcapacity),'" default="',convert2str(obj.heatcapacity),'">','     <section name="materials" />','     <help> heat capacity [J/kg/K] </help>','</parameter>');
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="latentheat" type="',class(obj.latentheat),'" default="',convert2str(obj.latentheat),'">','     <section name="materials" />','     <help> latent heat of fusion [J/kg] </help>','</parameter>');
+             
+             
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="thermalconductivity" type="',class(obj.thermalconductivity),'" default="',convert2str(obj.thermalconductivity),'">','     <section name="materials" />','     <help> ice thermal conductivity [W/m/K] </help>','</parameter>');
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="temperateiceconductivity" type="',class(obj.temperateiceconductivity),'" default="',convert2str(obj.temperateiceconductivity),'">','     <section name="materials" />','     <help> temperate ice thermal conductivity [W/m/K] </help>','</parameter>');
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="meltingpoint" type="',class(obj.meltingpoint),'" default="',convert2str(obj.meltingpoint),'">','     <section name="materials" />','     <help> melting point of ice at 1atm in K </help>','</parameter>');
+             
+             
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="beta" type="',class(obj.beta),'" default="',convert2str(obj.beta),'">','     <section name="materials" />','     <help> rate of change of melting point with pressure [K/Pa] </help>','</parameter>');
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="mixed_layer_capacity" type="',class(obj.mixed_layer_capacity),'" default="',convert2str(obj.mixed_layer_capacity),'">','     <section name="materials" />','     <help> mixed layer capacity [W/kg/K] </help>','</parameter>');
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="thermal_exchange_velocity" type="',class(obj.thermal_exchange_velocity),'" default="',convert2str(obj.thermal_exchange_velocity),'">','     <section name="materials" />','     <help> thermal exchange velocity [m/s] </help>','</parameter>');
+             
+             
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="rheology_B" type="',class(obj.rheology_B),'" default="',convert2str(obj.rheology_B),'">','     <section name="materials" />','     <help> flow law parameter [Pa/s^(1/n)] </help>','</parameter>');
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="rheology_n" type="',class(obj.rheology_n),'" default="',convert2str(obj.rheology_n),'">','     <section name="materials" />','     <help> Glens flow law exponent </help>','</parameter>');
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="rheology_law" type="',class(obj.rheology_law),'" default="',convert2str(obj.rheology_law),'">','     <section name="materials" />','     <help> law for the temperature dependance of the rheology: "None", "Paterson",  "Arrhenius" or "LliboutryDuval" </help>','</parameter>');
+             
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="lithosphere_shear_modulus" type="',class(obj.lithosphere_shear_modulus),'" default="',convert2str(obj.lithosphere_shear_modulus),'">','     <section name="materials" />','     <help> Lithosphere shear modulus [Pa] </help>','</parameter>');
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="lithosphere_density" type="',class(obj.lithosphere_density),'" default="',convert2str(obj.lithosphere_density),'">','     <section name="materials" />','     <help> Lithosphere density [g/cm^-3] </help>','</parameter>');
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="mantle_shear_modulus" type="',class(obj.mantle_shear_modulus),'" default="',convert2str(obj.mantle_shear_modulus),'">','     <section name="materials" />','     <help> Mantle shear modulus [Pa] </help>','</parameter>');
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="mantle_density" type="',class(obj.mantle_density),'" default="',convert2str(obj.mantle_density),'">','     <section name="materials" />','     <help> Mantle density [g/cm^-3] </help>','</parameter>');
+        
+         
+        end % }}}
 		function obj = matice(varargin) % {{{
 			switch nargin
@@ -69,4 +104,7 @@
 			%ice thermal conductivity (W/m/K)
 			obj.thermalconductivity=2.4;
+			
+			%wet ice thermal conductivity (W/m/K)
+			obj.temperateiceconductivity=.24;
 
 			%the melting point of ice at 1 atmosphere of pressure in K
@@ -94,17 +132,17 @@
 		end % }}}
 		function md = checkconsistency(obj,md,solution,analyses) % {{{
-			md = checkfield(md,'materials.rho_ice','>',0);
-			md = checkfield(md,'materials.rho_water','>',0);
-			md = checkfield(md,'materials.rho_freshwater','>',0);
-			md = checkfield(md,'materials.mu_water','>',0);
-			md = checkfield(md,'materials.rheology_B','>',0,'size',[md.mesh.numberofvertices 1]);
-			md = checkfield(md,'materials.rheology_n','>',0,'size',[md.mesh.numberofelements 1]);
-			md = checkfield(md,'materials.rheology_law','values',{'None' 'Paterson' 'Arrhenius' 'LliboutryDuval'});
+			md = checkfield(md,'fieldname','materials.rho_ice','>',0);
+			md = checkfield(md,'fieldname','materials.rho_water','>',0);
+			md = checkfield(md,'fieldname','materials.rho_freshwater','>',0);
+			md = checkfield(md,'fieldname','materials.mu_water','>',0);
+			md = checkfield(md,'fieldname','materials.rheology_B','>',0,'size',[md.mesh.numberofvertices 1]);
+			md = checkfield(md,'fieldname','materials.rheology_n','>',0,'size',[md.mesh.numberofelements 1]);
+			md = checkfield(md,'fieldname','materials.rheology_law','values',{'None' 'Cuffey' 'Paterson' 'Arrhenius' 'LliboutryDuval'});
 
 			if ismember(GiaAnalysisEnum(),analyses),
-				md = checkfield(md,'materials.lithosphere_shear_modulus','>',0,'numel',1);
-				md = checkfield(md,'materials.lithosphere_density','>',0,'numel',1);
-				md = checkfield(md,'materials.mantle_shear_modulus','>',0,'numel',1);
-				md = checkfield(md,'materials.mantle_density','>',0,'numel',1);
+				md = checkfield(md,'fieldname','materials.lithosphere_shear_modulus','>',0,'numel',1);
+				md = checkfield(md,'fieldname','materials.lithosphere_density','>',0,'numel',1);
+				md = checkfield(md,'fieldname','materials.mantle_shear_modulus','>',0,'numel',1);
+				md = checkfield(md,'fieldname','materials.mantle_density','>',0,'numel',1);
 			end
 
@@ -118,7 +156,8 @@
 			fielddisplay(obj,'mu_water','water viscosity [N s/m^2]');
 			fielddisplay(obj,'heatcapacity','heat capacity [J/kg/K]');
-			fielddisplay(obj,'thermalconductivity','ice thermal conductivity [W/m/K]');
+			fielddisplay(obj,'thermalconductivity',['ice thermal conductivity [W/m/K]']);
+			fielddisplay(obj,'temperateiceconductivity','temperate ice thermal conductivity [W/m/K]');
 			fielddisplay(obj,'meltingpoint','melting point of ice at 1atm in K');
-			fielddisplay(obj,'latentheat','latent heat of fusion [J/m^3]');
+			fielddisplay(obj,'latentheat','latent heat of fusion [J/kg]');
 			fielddisplay(obj,'beta','rate of change of melting point with pressure [K/Pa]');
 			fielddisplay(obj,'mixed_layer_capacity','mixed layer capacity [W/kg/K]');
@@ -126,5 +165,5 @@
 			fielddisplay(obj,'rheology_B','flow law parameter [Pa/s^(1/n)]');
 			fielddisplay(obj,'rheology_n','Glen''s flow law exponent');
-			fielddisplay(obj,'rheology_law',['law for the temperature dependance of the rheology: ''None'', ''Paterson'',  ''Arrhenius'' or ''LliboutryDuval''']);
+			fielddisplay(obj,'rheology_law',['law for the temperature dependance of the rheology: ''None'', ''Cuffey'', ''Paterson'', ''Arrhenius'' or ''LliboutryDuval''']);
 			fielddisplay(obj,'lithosphere_shear_modulus','Lithosphere shear modulus [Pa]');
 			fielddisplay(obj,'lithosphere_density','Lithosphere density [g/cm^-3]');
@@ -141,4 +180,5 @@
 			WriteData(fid,'object',obj,'class','materials','fieldname','latentheat','format','Double');
 			WriteData(fid,'object',obj,'class','materials','fieldname','thermalconductivity','format','Double');
+			WriteData(fid,'object',obj,'class','materials','fieldname','temperateiceconductivity','format','Double');
 			WriteData(fid,'object',obj,'class','materials','fieldname','meltingpoint','format','Double');
 			WriteData(fid,'object',obj,'class','materials','fieldname','beta','format','Double');
Index: /issm/trunk/src/m/classes/matice.py
===================================================================
--- /issm/trunk/src/m/classes/matice.py	(revision 17805)
+++ /issm/trunk/src/m/classes/matice.py	(revision 17806)
@@ -2,6 +2,6 @@
 from EnumDefinitions import *
 from StringToEnum import StringToEnum
-from checkfield import *
-from WriteData import *
+from checkfield import checkfield
+from WriteData import WriteData
 
 class matice(object):
@@ -21,4 +21,5 @@
 		self.latentheat                = 0.
 		self.thermalconductivity       = 0.
+		self.temperateiceconductivity  = 0.
 		self.meltingpoint              = 0.
 		self.beta                      = 0.
@@ -46,4 +47,5 @@
 		string="%s\n%s"%(string,fielddisplay(self,"heatcapacity","heat capacity [J/kg/K]"))
 		string="%s\n%s"%(string,fielddisplay(self,"thermalconductivity","ice thermal conductivity [W/m/K]"))
+		string="%s\n%s"%(string,fielddisplay(self,"temperateiceconductivity","temperate ice thermal conductivity [W/m/K]"))
 		string="%s\n%s"%(string,fielddisplay(self,"meltingpoint","melting point of ice at 1atm in K"))
 		string="%s\n%s"%(string,fielddisplay(self,"latentheat","latent heat of fusion [J/m^3]"))
@@ -53,5 +55,5 @@
 		string="%s\n%s"%(string,fielddisplay(self,"rheology_B","flow law parameter [Pa/s^(1/n)]"))
 		string="%s\n%s"%(string,fielddisplay(self,"rheology_n","Glen's flow law exponent"))
-		string="%s\n%s"%(string,fielddisplay(self,"rheology_law","law for the temperature dependance of the rheology: 'None', 'Paterson', 'Arrhenius' or 'LliboutryDuval'"))
+		string="%s\n%s"%(string,fielddisplay(self,"rheology_law","law for the temperature dependance of the rheology: 'None', 'Cuffey', 'Paterson', 'Arrhenius' or 'LliboutryDuval'"))
 		string="%s\n%s"%(string,fielddisplay(self,"lithosphere_shear_modulus","Lithosphere shear modulus [Pa]"))
 		string="%s\n%s"%(string,fielddisplay(self,"lithosphere_density","Lithosphere density [g/cm^-3]"))
@@ -83,4 +85,7 @@
 		self.thermalconductivity=2.4
 
+		#temperate ice thermal conductivity (W/m/K)
+		self.temperateiceconductivity=0.24
+
 		#the melting point of ice at 1 atmosphere of pressure in K
 		self.meltingpoint=273.15
@@ -108,15 +113,15 @@
 		#}}}
 	def checkconsistency(self,md,solution,analyses):    # {{{
-		md = checkfield(md,'materials.rho_ice','>',0)
-		md = checkfield(md,'materials.rho_water','>',0)
-		md = checkfield(md,'materials.rho_freshwater','>',0)
-		md = checkfield(md,'materials.mu_water','>',0)
-		md = checkfield(md,'materials.rheology_B','>',0,'size',[md.mesh.numberofvertices])
-		md = checkfield(md,'materials.rheology_n','>',0,'size',[md.mesh.numberofelements])
-		md = checkfield(md,'materials.rheology_law','values',['None','Paterson','Arrhenius','LliboutryDuval'])
-		md = checkfield(md,'materials.lithosphere_shear_modulus','>',0,'numel',[1]);
-		md = checkfield(md,'materials.lithosphere_density','>',0,'numel',[1]);
-		md = checkfield(md,'materials.mantle_shear_modulus','>',0,'numel',[1]);
-		md = checkfield(md,'materials.mantle_density','>',0,'numel',[1]);
+		md = checkfield(md,'fieldname','materials.rho_ice','>',0)
+		md = checkfield(md,'fieldname','materials.rho_water','>',0)
+		md = checkfield(md,'fieldname','materials.rho_freshwater','>',0)
+		md = checkfield(md,'fieldname','materials.mu_water','>',0)
+		md = checkfield(md,'fieldname','materials.rheology_B','>',0,'size',[md.mesh.numberofvertices])
+		md = checkfield(md,'fieldname','materials.rheology_n','>',0,'size',[md.mesh.numberofelements])
+		md = checkfield(md,'fieldname','materials.rheology_law','values',['None','Cuffey','Paterson','Arrhenius','LliboutryDuval'])
+		md = checkfield(md,'fieldname','materials.lithosphere_shear_modulus','>',0,'numel',[1]);
+		md = checkfield(md,'fieldname','materials.lithosphere_density','>',0,'numel',[1]);
+		md = checkfield(md,'fieldname','materials.mantle_shear_modulus','>',0,'numel',[1]);
+		md = checkfield(md,'fieldname','materials.mantle_density','>',0,'numel',[1]);
 		return md
 	# }}}
@@ -130,4 +135,5 @@
 		WriteData(fid,'object',self,'class','materials','fieldname','latentheat','format','Double')
 		WriteData(fid,'object',self,'class','materials','fieldname','thermalconductivity','format','Double')
+		WriteData(fid,'object',self,'class','materials','fieldname','temperateiceconductivity','format','Double')
 		WriteData(fid,'object',self,'class','materials','fieldname','meltingpoint','format','Double')
 		WriteData(fid,'object',self,'class','materials','fieldname','beta','format','Double')
Index: sm/trunk/src/m/classes/mesh.m
===================================================================
--- /issm/trunk/src/m/classes/mesh.m	(revision 17805)
+++ 	(revision )
@@ -1,210 +1,0 @@
-%MESH class definition
-%
-%   Usage:
-%      mesh=mesh();
-
-classdef mesh
-	properties (SetAccess=public) 
-		x                           = NaN;
-		y                           = NaN;
-		z                           = NaN
-		elements                    = NaN
-		dimension                   = 0;
-		numberoflayers              = 0;
-		numberofelements            = 0;
-		numberofvertices            = 0;
-		numberofedges               = 0;
-
-		lat                         = NaN
-		long                        = NaN
-		hemisphere                  = NaN
-
-		elementonbed                = NaN
-		elementonsurface            = NaN
-		vertexonbed                 = NaN
-		vertexonsurface             = NaN
-		lowerelements               = NaN
-		lowervertex                 = NaN
-		upperelements               = NaN
-		uppervertex                 = NaN
-		vertexonboundary            = NaN
-
-		edges                       = NaN
-		segments                    = NaN
-		segmentmarkers              = NaN
-		vertexconnectivity          = NaN
-		elementconnectivity         = NaN
-		average_vertex_connectivity = 0;
-
-		x2d                         = NaN
-		y2d                         = NaN
-		elements2d                  = NaN
-		numberofvertices2d          = 0;
-		numberofelements2d          = 0;
-
-		extractedvertices           = NaN
-		extractedelements           = NaN
-	end
-	methods (Static)
-		function obj = loadobj(obj) % {{{
-			% This function is directly called by matlab when a model object is
-			% loaded. Update old properties here
-
-			%2012 June 28th
-			if numel(obj.edges)>1 & any(isnan(obj.edges(:)))
-				disp('Update model edges from previous version');
-				obj.edges(isnan(obj.edges))=-1;
-			end
-
-		end% }}}
-	end
-	methods
-		function obj = mesh(varargin) % {{{
-			switch nargin
-				case 0
-					obj=setdefaultparameters(obj);
-				otherwise
-					error('constructor not supported');
-			end
-		end % }}}
-		function obj = setdefaultparameters(obj) % {{{
-
-			%the connectivity is the averaged number of nodes linked to a
-			%given node through an edge. This connectivity is used to initially
-			%allocate memory to the stiffness matrix. A value of 16 seems to
-			%give a good memory/time ration. This value can be checked in
-			%trunk/test/Miscellaneous/runme.m
-			obj.average_vertex_connectivity=25;
-		end % }}}
-		function md = checkconsistency(obj,md,solution,analyses) % {{{
-
-			md = checkfield(md,'mesh.x','NaN',1,'size',[md.mesh.numberofvertices 1]);
-			md = checkfield(md,'mesh.y','NaN',1,'size',[md.mesh.numberofvertices 1]);
-			md = checkfield(md,'mesh.z','NaN',1,'size',[md.mesh.numberofvertices 1]);
-			md = checkfield(md,'mesh.elements','NaN',1,'>',0,'values',1:md.mesh.numberofvertices);
-			if(md.mesh.dimension==2),
-				md = checkfield(md,'mesh.elements','size',[md.mesh.numberofelements 3]);
-			else
-				md = checkfield(md,'mesh.elements','size',[md.mesh.numberofelements 6]);
-			end
-			if any(~ismember(1:md.mesh.numberofvertices,sort(unique(md.mesh.elements(:)))));
-				md = checkmessage(md,'orphan nodes have been found. Check the mesh outline');
-			end
-			md = checkfield(md,'mesh.dimension','values',[2 3]);
-			md = checkfield(md,'mesh.numberoflayers','>=',0);
-			md = checkfield(md,'mesh.numberofelements','>',0);
-			md = checkfield(md,'mesh.numberofvertices','>',0);
-			%no checks for numberofedges lat long and hemisphere
-			md = checkfield(md,'mesh.elementonbed','size',[md.mesh.numberofelements 1],'values',[0 1]);
-			md = checkfield(md,'mesh.elementonsurface','size',[md.mesh.numberofelements 1],'values',[0 1]);
-			md = checkfield(md,'mesh.vertexonbed','size',[md.mesh.numberofvertices 1],'values',[0 1]);
-			md = checkfield(md,'mesh.vertexonsurface','size',[md.mesh.numberofvertices 1],'values',[0 1]);
-			if (md.mesh.dimension==3),
-				md = checkfield(md,'mesh.z','>=',md.geometry.bed-10^-10,'message','''mesh.z'' lower than bedrock');
-				md = checkfield(md,'mesh.z','<=',md.geometry.surface+10^-10,'message','''mesh.z'' higher than surface elevation');
-			end
-			if (md.mesh.dimension==2),
-				md = checkfield(md,'mesh.average_vertex_connectivity','>=',9,'message','''mesh.average_vertex_connectivity'' should be at least 9 in 2d');
-			else
-				md = checkfield(md,'mesh.average_vertex_connectivity','>=',24,'message','''mesh.average_vertex_connectivity'' should be at least 24 in 3d');
-			end
-
-			%Solution specific checks
-			switch(solution),
-				case MasstransportSolutionEnum(),
-					if md.masstransport.stabilization==3,
-						md = checkfield(md,'mesh.dimension','values',2,'message','Discontinuous Galerkin only supported for 2d meshes');
-					end
-				case BalancethicknessSolutionEnum(),
-					if md.balancethickness.stabilization==3,
-						md = checkfield(md,'mesh.dimension','values',2,'message','Discontinuous Galerkin only supported for 2d meshes');
-					end
-				case TransientSolutionEnum(),
-					if md.transient.ismasstransport & md.masstransport.stabilization==3,
-						md = checkfield(md,'mesh.dimension','values',2,'message','Discontinuous Galerkin only supported for 2d meshes');
-					end
-				case ThermalSolutionEnum(),
-					md = checkfield(md,'mesh.dimension','values',3,'message','thermal solution only supported on 3d meshes');
-			end
-		end % }}}
-		function disp(obj) % {{{
-			disp(sprintf('   Mesh:')); 
-
-			if obj.dimension==3,
-				disp(sprintf('\n      Elements and vertices of the original 2d mesh:'));
-				fielddisplay(obj,'numberofelements2d','number of elements');
-				fielddisplay(obj,'numberofvertices2d','number of vertices');
-				fielddisplay(obj,'elements2d','vertex indices of the mesh elements');
-				fielddisplay(obj,'x2d','vertices x coordinate [m]');
-				fielddisplay(obj,'y2d','vertices y coordinate [m]');
-
-				disp(sprintf('\n      Elements and vertices of the extruded 3d mesh:'));
-			else
-				disp(sprintf('\n      Elements and vertices:'));
-			end
-			fielddisplay(obj,'numberofelements','number of elements');
-			fielddisplay(obj,'numberofvertices','number of vertices');
-			fielddisplay(obj,'elements','vertex indices of the mesh elements');
-			fielddisplay(obj,'x','vertices x coordinate [m]');
-			fielddisplay(obj,'y','vertices y coordinate [m]');
-			fielddisplay(obj,'z','vertices z coordinate [m]');
-			fielddisplay(obj,'edges','edges of the 2d mesh (vertex1 vertex2 element1 element2)');
-			fielddisplay(obj,'numberofedges','number of edges of the 2d mesh');
-
-			disp(sprintf('\n      Properties:'));
-			fielddisplay(obj,'dimension','mesh dimension');
-			fielddisplay(obj,'numberoflayers','number of extrusion layers');
-			fielddisplay(obj,'vertexonbed','lower vertices flags list');
-			fielddisplay(obj,'elementonbed','lower elements flags list');
-			fielddisplay(obj,'vertexonsurface','upper vertices flags list');
-			fielddisplay(obj,'elementonsurface','upper elements flags list');
-			fielddisplay(obj,'uppervertex','upper vertex list (NaN for vertex on the upper surface)');
-			fielddisplay(obj,'upperelements','upper element list (NaN for element on the upper layer)');
-			fielddisplay(obj,'lowervertex','lower vertex list (NaN for vertex on the lower surface)');
-			fielddisplay(obj,'lowerelements','lower element list (NaN for element on the lower layer');
-			fielddisplay(obj,'vertexonboundary','vertices on the boundary of the domain flag list');
-
-			fielddisplay(obj,'segments','edges on domain boundary (vertex1 vertex2 element)');
-			fielddisplay(obj,'segmentmarkers','number associated to each segment');
-			fielddisplay(obj,'vertexconnectivity','list of vertices connected to vertex_i');
-			fielddisplay(obj,'elementconnectivity','list of vertices connected to element_i');
-			fielddisplay(obj,'average_vertex_connectivity','average number of vertices connected to one vertex');
-
-			disp(sprintf('\n      Extracted model:'));
-			fielddisplay(obj,'extractedvertices','vertices extracted from the model');
-			fielddisplay(obj,'extractedelements','elements extracted from the model');
-
-			disp(sprintf('\n      Projection:'));
-			fielddisplay(obj,'lat','vertices latitude [degrees]');
-			fielddisplay(obj,'long','vertices longitude [degrees]');
-			fielddisplay(obj,'hemisphere','Indicate hemisphere ''n'' or ''s'' ');
-		end % }}}
-		function marshall(obj,md,fid) % {{{
-			WriteData(fid,'enum',MeshTypeEnum(),'data',StringToEnum(['Mesh' meshtype(obj)]),'format','Integer');
-			WriteData(fid,'object',obj,'fieldname','x','format','DoubleMat','mattype',1);
-			WriteData(fid,'object',obj,'fieldname','y','format','DoubleMat','mattype',1);
-			WriteData(fid,'object',obj,'fieldname','z','format','DoubleMat','mattype',1);
-			WriteData(fid,'object',obj,'fieldname','elements','format','DoubleMat','mattype',2);
-			WriteData(fid,'object',obj,'fieldname','numberoflayers','format','Integer');
-			WriteData(fid,'object',obj,'fieldname','numberofelements','format','Integer');
-			WriteData(fid,'object',obj,'fieldname','numberofvertices','format','Integer');
-			WriteData(fid,'object',obj,'fieldname','elementonbed','format','BooleanMat','mattype',2);
-			WriteData(fid,'object',obj,'fieldname','elementonsurface','format','BooleanMat','mattype',2);
-			WriteData(fid,'object',obj,'fieldname','vertexonbed','format','BooleanMat','mattype',1);
-			WriteData(fid,'object',obj,'fieldname','vertexonsurface','format','BooleanMat','mattype',1);
-			WriteData(fid,'object',obj,'fieldname','lowerelements','format','DoubleMat','mattype',2);
-			WriteData(fid,'object',obj,'fieldname','upperelements','format','DoubleMat','mattype',2);
-			WriteData(fid,'object',obj,'fieldname','average_vertex_connectivity','format','Integer');
-			WriteData(fid,'object',obj,'fieldname','elements2d','format','DoubleMat','mattype',3);
-			WriteData(fid,'object',obj,'fieldname','numberofvertices2d','format','Integer');
-			WriteData(fid,'object',obj,'fieldname','numberofelements2d','format','Integer');
-		end % }}}
-		function type = meshtype(obj) % {{{
-			if obj.dimension==2,
-				type = '2Dhorizontal';
-			else
-				type = '3D';
-			end
-		end % }}}
-	end
-end
Index: sm/trunk/src/m/classes/mesh.py
===================================================================
--- /issm/trunk/src/m/classes/mesh.py	(revision 17805)
+++ 	(revision )
@@ -1,190 +1,0 @@
-import numpy
-from fielddisplay import fielddisplay
-from EnumDefinitions import *
-from checkfield import *
-from MatlabFuncs import *
-
-class mesh(object):
-	"""
-	MESH class definition
-
-	   Usage:
-	      mesh=mesh();
-	"""
-
-	def __init__(self): # {{{
-		self.x                           = float('NaN');
-		self.y                           = float('NaN');
-		self.z                           = float('NaN');
-		self.elements                    = float('NaN');
-		self.dimension                   = 0;
-		self.numberoflayers              = 0;
-		self.numberofelements            = 0;
-		self.numberofvertices            = 0;
-		self.numberofedges               = 0;
-		
-		self.lat                         = float('NaN');
-		self.long                        = float('NaN');
-		self.hemisphere                  = float('NaN');
-
-		self.elementonbed                = float('NaN');
-		self.elementonsurface            = float('NaN');
-		self.vertexonbed                 = float('NaN');
-		self.vertexonsurface             = float('NaN');
-		self.lowerelements               = float('NaN');
-		self.lowervertex                 = float('NaN');
-		self.upperelements               = float('NaN');
-		self.uppervertex                 = float('NaN');
-		self.vertexonboundary            = float('NaN');
-
-		self.edges                       = float('NaN');
-		self.segments                    = float('NaN');
-		self.segmentmarkers              = float('NaN');
-		self.vertexconnectivity          = float('NaN');
-		self.elementconnectivity         = float('NaN');
-		self.average_vertex_connectivity = 0;
-
-		self.x2d                         = float('NaN');
-		self.y2d                         = float('NaN');
-		self.elements2d                  = float('NaN');
-		self.numberofvertices2d          = 0;
-		self.numberofelements2d          = 0;
-
-		self.extractedvertices           = float('NaN');
-		self.extractedelements           = float('NaN');
-
-		#set defaults
-		self.setdefaultparameters()
-		#}}}
-	def __repr__(self): # {{{
-		string="   Mesh:" 
-
-
-		if self.dimension==3:
-			string="%s\n%s"%(string,"\n      Elements and vertices of the original 2d mesh:")
-			
-			string="%s\n%s"%(string,fielddisplay(self,"numberofelements2d","number of elements"))
-			string="%s\n%s"%(string,fielddisplay(self,"numberofvertices2d","number of vertices"))
-			string="%s\n%s"%(string,fielddisplay(self,"elements2d","vertex indices of the mesh elements"))
-			string="%s\n%s"%(string,fielddisplay(self,"x2d","vertices x coordinate [m]"))
-			string="%s\n%s"%(string,fielddisplay(self,"y2d","vertices y coordinate [m]"))
-
-			string="%s\n%s"%(string,"\n\n      Elements and vertices of the extruded 3d mesh:")
-		else:
-			string="%s\n%s"%(string,"\n      Elements and vertices:")
-		string="%s\n%s"%(string,fielddisplay(self,"numberofelements","number of elements"))
-		string="%s\n%s"%(string,fielddisplay(self,"numberofvertices","number of vertices"))
-		string="%s\n%s"%(string,fielddisplay(self,"elements","vertex indices of the mesh elements"))
-		string="%s\n%s"%(string,fielddisplay(self,"x","vertices x coordinate [m]"))
-		string="%s\n%s"%(string,fielddisplay(self,"y","vertices y coordinate [m]"))
-		string="%s\n%s"%(string,fielddisplay(self,"z","vertices z coordinate [m]"))
-		string="%s\n%s"%(string,fielddisplay(self,"edges","edges of the 2d mesh (vertex1 vertex2 element1 element2)"))
-		string="%s\n%s"%(string,fielddisplay(self,"numberofedges","number of edges of the 2d mesh"))
-
-		string="%s%s"%(string,"\n\n      Properties:")
-		string="%s\n%s"%(string,fielddisplay(self,"dimension","mesh dimension (2d or 3d)"))
-		string="%s\n%s"%(string,fielddisplay(self,"numberoflayers","number of extrusion layers"))
-		string="%s\n%s"%(string,fielddisplay(self,"vertexonbed","lower vertices flags list"))
-		string="%s\n%s"%(string,fielddisplay(self,"elementonbed","lower elements flags list"))
-		string="%s\n%s"%(string,fielddisplay(self,"vertexonsurface","upper vertices flags list"))
-		string="%s\n%s"%(string,fielddisplay(self,"elementonsurface","upper elements flags list"))
-		string="%s\n%s"%(string,fielddisplay(self,"uppervertex","upper vertex list (-1 for vertex on the upper surface)"))
-		string="%s\n%s"%(string,fielddisplay(self,"upperelements","upper element list (-1 for element on the upper layer)"))
-		string="%s\n%s"%(string,fielddisplay(self,"lowervertex","lower vertex list (-1 for vertex on the lower surface)"))
-		string="%s\n%s"%(string,fielddisplay(self,"lowerelements","lower element list (-1 for element on the lower layer)"))
-		string="%s\n%s"%(string,fielddisplay(self,"vertexonboundary","vertices on the boundary of the domain flag list"))
-		string="%s\n%s"%(string,fielddisplay(self,"segments","edges on domain boundary (vertex1 vertex2 element)"))
-		string="%s\n%s"%(string,fielddisplay(self,"segmentmarkers","number associated to each segment"))
-		string="%s\n%s"%(string,fielddisplay(self,"vertexconnectivity","list of vertices connected to vertex_i"))
-		string="%s\n%s"%(string,fielddisplay(self,"elementconnectivity","list of vertices connected to element_i"))
-		string="%s\n%s"%(string,fielddisplay(self,"average_vertex_connectivity","average number of vertices connected to one vertex"))
-
-		string="%s%s"%(string,"\n\n      Extracted model:")
-		string="%s\n%s"%(string,fielddisplay(self,"extractedvertices","vertices extracted from the model"))
-		string="%s\n%s"%(string,fielddisplay(self,"extractedelements","elements extracted from the model"))
-
-		string="%s%s"%(string,"\n\n      Projection:")
-		string="%s\n%s"%(string,fielddisplay(self,"lat","vertices latitude [degrees]"))
-		string="%s\n%s"%(string,fielddisplay(self,"long","vertices longitude [degrees]"))
-		string="%s\n%s"%(string,fielddisplay(self,"hemisphere","Indicate hemisphere 'n' or 's'"))
-		return string
-		#}}}
-	def setdefaultparameters(self): # {{{
-		
-		#the connectivity is the averaged number of nodes linked to a
-		#given node through an edge. This connectivity is used to initially
-		#allocate memory to the stiffness matrix. A value of 16 seems to
-		#give a good memory/time ration. This value can be checked in
-		#trunk/test/Miscellaneous/runme.m
-		self.average_vertex_connectivity=25
-
-		return self
-	#}}}
-	def checkconsistency(self,md,solution,analyses):    # {{{
-
-		md = checkfield(md,'mesh.x','NaN',1,'size',[md.mesh.numberofvertices])
-		md = checkfield(md,'mesh.y','NaN',1,'size',[md.mesh.numberofvertices])
-		md = checkfield(md,'mesh.z','NaN',1,'size',[md.mesh.numberofvertices])
-		md = checkfield(md,'mesh.elements','NaN',1,'>',0,'values',numpy.arange(1,md.mesh.numberofvertices+1))
-		if md.mesh.dimension==2:
-			md = checkfield(md,'mesh.elements','size',[md.mesh.numberofelements,3])
-		else:
-			md = checkfield(md,'mesh.elements','size',[md.mesh.numberofelements,6])
-		if numpy.any(numpy.logical_not(ismember(numpy.arange(1,md.mesh.numberofvertices+1),md.mesh.elements))):
-			md.checkmessage("orphan nodes have been found. Check the mesh outline")
-		md = checkfield(md,'mesh.dimension','values',[2,3])
-		md = checkfield(md,'mesh.numberoflayers','>=',0)
-		md = checkfield(md,'mesh.numberofelements','>',0)
-		md = checkfield(md,'mesh.numberofvertices','>',0)
-		#no checks for numberofedges lat long and hemisphere
-		md = checkfield(md,'mesh.elementonbed','size',[md.mesh.numberofelements],'values',[0,1])
-		md = checkfield(md,'mesh.elementonsurface','size',[md.mesh.numberofelements],'values',[0,1])
-		md = checkfield(md,'mesh.vertexonbed','size',[md.mesh.numberofvertices],'values',[0,1])
-		md = checkfield(md,'mesh.vertexonsurface','size',[md.mesh.numberofvertices],'values',[0,1])
-		if md.mesh.dimension==2:
-			md = checkfield(md,'mesh.average_vertex_connectivity','>=',9,'message',"'mesh.average_vertex_connectivity' should be at least 9 in 2d")
-		else:
-			md = checkfield(md,'mesh.average_vertex_connectivity','>=',24,'message',"'mesh.average_vertex_connectivity' should be at least 24 in 3d")
-
-		#Solution specific checks
-		if   solution==MasstransportSolutionEnum():
-			if md.masstransport.stabilization==3:
-				md = checkfield(md,'mesh.dimension','values',2,'message',"Discontinuous Galerkin only supported for 2d meshes")
-		elif solution==BalancethicknessSolutionEnum():
-			if md.balancethickness.stabilization==3:
-				md = checkfield(md,'mesh.dimension','values',2,'message',"Discontinuous Galerkin only supported for 2d meshes")
-		elif solution==TransientSolutionEnum():
-			if md.transient.ismasstransport and md.masstransport.stabilization==3:
-				md = checkfield(md,'mesh.dimension','values',2,'message',"Discontinuous Galerkin only supported for 2d meshes")
-		elif solution==ThermalSolutionEnum():
-			md = checkfield(md,'mesh.dimension','values',3,'message','thermal solution only supported on 3d meshes')
-
-		return md
-	# }}}
-	def meshtype(self): # {{{
-
-		if self.dimension==2:
-			return "2Dhorizontal"
-		else:
-			return "3D"
-	#}}}
-	def marshall(self,md,fid):    # {{{
-		WriteData(fid,'enum',MeshTypeEnum(),'data',StringToEnum("Mesh"+self.meshtype())[0],'format','Integer');
-		WriteData(fid,'object',self,'fieldname','x','format','DoubleMat','mattype',1)
-		WriteData(fid,'object',self,'fieldname','y','format','DoubleMat','mattype',1)
-		WriteData(fid,'object',self,'fieldname','z','format','DoubleMat','mattype',1)
-		WriteData(fid,'object',self,'fieldname','elements','format','DoubleMat','mattype',2)
-		WriteData(fid,'object',self,'fieldname','numberoflayers','format','Integer')
-		WriteData(fid,'object',self,'fieldname','numberofelements','format','Integer')
-		WriteData(fid,'object',self,'fieldname','numberofvertices','format','Integer')
-		WriteData(fid,'object',self,'fieldname','elementonbed','format','BooleanMat','mattype',2)
-		WriteData(fid,'object',self,'fieldname','elementonsurface','format','BooleanMat','mattype',2)
-		WriteData(fid,'object',self,'fieldname','vertexonbed','format','BooleanMat','mattype',1)
-		WriteData(fid,'object',self,'fieldname','vertexonsurface','format','BooleanMat','mattype',1)
-		WriteData(fid,'object',self,'fieldname','lowerelements','format','DoubleMat','mattype',2)
-		WriteData(fid,'object',self,'fieldname','upperelements','format','DoubleMat','mattype',2)
-		WriteData(fid,'object',self,'fieldname','average_vertex_connectivity','format','Integer')
-		WriteData(fid,'object',self,'fieldname','elements2d','format','DoubleMat','mattype',3)
-		WriteData(fid,'object',self,'fieldname','numberofvertices2d','format','Integer')
-		WriteData(fid,'object',self,'fieldname','numberofelements2d','format','Integer')
-	# }}}
Index: /issm/trunk/src/m/classes/mesh2d.m
===================================================================
--- /issm/trunk/src/m/classes/mesh2d.m	(revision 17805)
+++ /issm/trunk/src/m/classes/mesh2d.m	(revision 17806)
@@ -30,8 +30,18 @@
 	end
 	methods
-		function obj = mesh2d(varargin) % {{{
+		function self = mesh2d(varargin) % {{{
 			switch nargin
 				case 0
-					obj=setdefaultparameters(obj);
+					self=setdefaultparameters(self);
+				case 1
+					self=mesh2d();
+					object=varargin{1};
+					fields=fieldnames(object);
+					for i=1:length(fields)
+						field=fields{i};
+						if ismember(field,properties('mesh2d')),
+							self.(field)=object.(field);
+						end
+					end
 				otherwise
 					error('constructor not supported');
@@ -49,14 +59,14 @@
 		function md = checkconsistency(obj,md,solution,analyses) % {{{
 
-			md = checkfield(md,'mesh.x','NaN',1,'size',[md.mesh.numberofvertices 1]);
-			md = checkfield(md,'mesh.y','NaN',1,'size',[md.mesh.numberofvertices 1]);
-			md = checkfield(md,'mesh.elements','NaN',1,'>',0,'values',1:md.mesh.numberofvertices);
-			md = checkfield(md,'mesh.elements','size',[md.mesh.numberofelements 3]);
+			md = checkfield(md,'fieldname','mesh.x','NaN',1,'size',[md.mesh.numberofvertices 1]);
+			md = checkfield(md,'fieldname','mesh.y','NaN',1,'size',[md.mesh.numberofvertices 1]);
+			md = checkfield(md,'fieldname','mesh.elements','NaN',1,'>',0,'values',1:md.mesh.numberofvertices);
+			md = checkfield(md,'fieldname','mesh.elements','size',[md.mesh.numberofelements 3]);
 			if any(~ismember(1:md.mesh.numberofvertices,sort(unique(md.mesh.elements(:)))));
 				md = checkmessage(md,'orphan nodes have been found. Check the mesh outline');
 			end
-			md = checkfield(md,'mesh.numberofelements','>',0);
-			md = checkfield(md,'mesh.numberofvertices','>',0);
-			md = checkfield(md,'mesh.average_vertex_connectivity','>=',9,'message','''mesh.average_vertex_connectivity'' should be at least 9 in 2d');
+			md = checkfield(md,'fieldname','mesh.numberofelements','>',0);
+			md = checkfield(md,'fieldname','mesh.numberofvertices','>',0);
+			md = checkfield(md,'fieldname','mesh.average_vertex_connectivity','>=',9,'message','''mesh.average_vertex_connectivity'' should be at least 9 in 2d');
 
 			switch(solution),
@@ -66,5 +76,5 @@
 		end % }}}
 		function disp(obj) % {{{
-			disp(sprintf('   2d Mesh:')); 
+			disp(sprintf('   2D tria Mesh (horizontal):')); 
 
 			disp(sprintf('\n      Elements and vertices:'));
@@ -94,6 +104,83 @@
 			fielddisplay(obj,'hemisphere','Indicate hemisphere ''n'' or ''s'' ');
 		end % }}}
+        function createxml(obj,fid) % {{{
+            fprintf(fid, '<!-- mesh -->\n');
+            
+            % drop-down 
+            fprintf(fid,'%s%s%s%s%s\n%s\n','<parameter key ="Dimension" type="','alternative','" optional="','false','">','     <section name="mesh" />');
+            
+                % dimension=0
+                fprintf(fid,'%s%s%s%s%s\n%s\n','     <option value="0" type="','string','" default="','true','">','        <help> dimension is 0 </help>');
+                % footer for dim=0
+                fprintf(fid,'%s\n%s\n','     </option>');
+
+                % dimension=3
+                fprintf(fid,'%s%s%s\n%s\n','     <option value="3" type="','string','">','        <help> dimension is 3 </help>');
+
+                    fprintf(fid,'       <!-- Elements and vertices of the original 2d mesh -->\n');
+                    %fprintf(fid,'%s\n%s\n%s\n','       <frame key="dim=3" label="Elements and vertices of the original 2d mesh">','       <section name="mesh" />');
+                    fprintf(fid,'%s%s%s%s%s\n%s\n%s\n','          <parameter key ="x2d" type="',class(obj.x2d),'" default="',convert2str(obj.x2d),'">','              <help> vertices x coordinate [m] </help>','          </parameter>');
+                    fprintf(fid,'%s%s%s%s%s\n%s\n%s\n','          <parameter key ="y2d" type="',class(obj.y2d),'" default="',convert2str(obj.y2d),'">','              <help> vertices y coordinate [m] </help>','          </parameter>');
+                    fprintf(fid,'%s%s%s%s%s\n%s\n%s\n','          <parameter key ="elements2d" type="',class(obj.elements2d),'" default="',convert2str(obj.elements2d),'">','              <help> vertex indices of the mesh elements </help>','          </parameter>');
+                    fprintf(fid,'%s%s%s%s%s\n%s\n%s\n','          <parameter key ="numberofvertices2d" type="',class(obj.numberofvertices2d),'" default="',convert2str(obj.numberofvertices2d),'">','              <help> number of vertices </help>','          </parameter>');
+                    fprintf(fid,'%s%s%s%s%s\n%s\n%s\n','          <parameter key ="numberofelements2d" type="',class(obj.numberofelements2d),'" default="',convert2str(obj.numberofelements2d),'">','              <help> number of elements </help>','          </parameter>');
+                    %fprintf(fid,'%s\n%s\n','       </frame>');
+                % footer for dim=3
+                fprintf(fid,'%s\n%s\n','     </option>');   
+            
+            % footer for drop-down
+            fprintf(fid,'%s\n%s\n%s','     <help> select a mesh dimension 0(default) or 3 </help>','</parameter>');
+            
+                    
+            % elements and vertices
+            fprintf(fid,'%s\n%s\n%s\n','<frame key="1" label="Elements and vertices">','<section name="mesh" />');                    
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="numberofelements" type="',class(obj.numberofelements),'" default="',convert2str(obj.numberofelements),'">','     <section name="mesh" />','     <help> number of elements </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="numberofvertices" type="',class(obj.numberofvertices),'" default="',convert2str(obj.numberofvertices),'">','     <section name="mesh" />','     <help> number of verticies </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="elements" type="',class(obj.elements),'" default="',convert2str(obj.elements),'">','     <section name="mesh" />','     <help> vertex indices of the mesh elements </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="x" type="',class(obj.x),'" default="',convert2str(obj.x),'">','     <section name="mesh" />','     <help> vertices x coordinate [m] </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="y" type="',class(obj.y),'" default="',convert2str(obj.y),'">','     <section name="mesh" />','     <help> vertices y coordinate [m] </help>','  </parameter>');
+		    fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="z" type="',class(obj.z),'" default="',convert2str(obj.z),'">','     <section name="mesh" />','     <help> vertices z coordinate [m] </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="edges" type="',class(obj.edges),'" default="',convert2str(obj.edges),'">','     <section name="mesh" />','     <help> edges of the 2d mesh (vertex1 vertex2 element1 element2) </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="numberofedges" type="',class(obj.numberofedges),'" default="',convert2str(obj.numberofedges),'">','     <section name="mesh" />','     <help> number of edges of the 2d mesh </help>','  </parameter>');
+            fprintf(fid,'%s\n%s\n','</frame>');
+            
+            % properties
+            fprintf(fid,'%s\n%s\n%s\n','<frame key="2" label="Properties">','<section name="mesh" />');             
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="selected dimension" type="',class(obj.dimension),'" default="',convert2str(obj.dimension),'">','     <section name="mesh" />','     <help> mesh dimension </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="numberoflayers" type="',class(obj.numberoflayers),'" default="',convert2str(obj.numberoflayers),'">','     <section name="mesh" />','     <help> number of extrusion layers </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="vertexonbed" type="',class(obj.vertexonbed),'" default="',convert2str(obj.vertexonbed),'">','     <section name="mesh" />','     <help> lower vertices flags list </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="elementonbed" type="',class(obj.elementonbed),'" default="',convert2str(obj.elementonbed),'">','     <section name="mesh" />','     <help> lower elements flags list </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="vertexonsurface" type="',class(obj.vertexonsurface),'" default="',convert2str(obj.vertexonsurface),'">','     <section name="mesh" />','     <help> upper vertices flags list </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="elementonsurface" type="',class(obj.elementonsurface),'" default="',convert2str(obj.elementonsurface),'">','     <section name="mesh" />','     <help> upper element flag list </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="uppervertex" type="',class(obj.uppervertex),'" default="',convert2str(obj.uppervertex),'">','     <section name="mesh" />','     <help> upper vertex list (NaN for vertex on the upper surface) </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="upperelements" type="',class(obj.upperelements),'" default="',convert2str(obj.upperelements),'">','     <section name="mesh" />','     <help> upper element list (NaN for element on the upper layer) </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="lowervertex" type="',class(obj.lowervertex),'" default="',convert2str(obj.lowervertex),'">','     <section name="mesh" />','     <help> lower vertex list (NaN for vertex on the lower surface) </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="lowerelements" type="',class(obj.lowerelements),'" default="',convert2str(obj.lowerelements),'">','     <section name="mesh" />','     <help> lower element list (NaN for element on the lower layer </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="vertexonboundary" type="',class(obj.vertexonboundary),'" default="',convert2str(obj.vertexonboundary),'">','     <section name="mesh" />','     <help> vertices on the boundary of the domain flag list </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="segments" type="',class(obj.segments),'" default="',convert2str(obj.segments),'">','     <section name="mesh" />','     <help> edges on domain boundary (vertex1 vertex2 element) </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="segmentmarkers" type="',class(obj.segmentmarkers),'" default="',convert2str(obj.segmentmarkers),'">','     <section name="mesh" />','     <help> number associated to each segment </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="vertexconnectivity" type="',class(obj.vertexconnectivity),'" default="',convert2str(obj.vertexconnectivity),'">','     <section name="mesh" />','     <help> list of vertices connected to vertex_i </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="elementconnectivity" type="',class(obj.elementconnectivity),'" default="',convert2str(obj.elementconnectivity),'">','     <section name="mesh" />','     <help> list of vertices connected to element_i </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="average_vertex_connectivity" type="',class(obj.average_vertex_connectivity),'" default="',convert2str(obj.average_vertex_connectivity),'">','     <section name="mesh" />','     <help> average number of vertices connected to one vertex </help>','  </parameter>');
+            fprintf(fid,'%s\n%s\n','</frame>');
+            
+            %extracted model
+            fprintf(fid,'%s\n%s\n%s\n','<frame key="3" label="Extracted Model">','<section name="mesh" />'); 
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="extractedvertices" type="',class(obj.extractedvertices),'" default="',convert2str(obj.extractedvertices),'">','     <section name="mesh" />','     <help> vertices extracted from the model </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="extractedelements" type="',class(obj.extractedelements),'" default="',convert2str(obj.extractedelements),'">','     <section name="mesh" />','     <help> elements extracted from the model </help>','  </parameter>');
+            fprintf(fid,'%s\n%s\n','</frame>');
+            
+            %projection
+            fprintf(fid,'%s\n%s\n%s\n','<frame key="4" label="Projection">','<section name="mesh" />'); 
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="lat" type="',class(obj.lat),'" default="',convert2str(obj.lat),'">','     <section name="mesh" />','     <help> vertices latitude [degrees] </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="long" type="',class(obj.long),'" default="',convert2str(obj.long),'">','     <section name="mesh" />','     <help> verticies longitude [degrees] </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n','  <parameter key ="hemisphere" type="',class(obj.hemisphere),'" default="',convert2str(obj.hemisphere),'">','     <section name="mesh" />','     <help> Indicate hemisphere ''n'' or ''s'' </help>','  </parameter>');
+            fprintf(fid,'%s\n%s\n','</frame>');
+        
+        end % }}}
 		function marshall(obj,md,fid) % {{{
-			WriteData(fid,'enum',MeshTypeEnum(),'data',StringToEnum(['Mesh' meshtype(obj)]),'format','Integer');
+			WriteData(fid,'enum',DomainTypeEnum(),'data',StringToEnum(['Domain' domaintype(obj)]),'format','Integer');
+			WriteData(fid,'enum',DomainDimensionEnum(),'data',dimension(obj),'format','Integer');
+			WriteData(fid,'enum',MeshElementtypeEnum(),'data',StringToEnum(elementtype(obj)),'format','Integer');
 			WriteData(fid,'object',obj,'class','mesh','fieldname','x','format','DoubleMat','mattype',1);
 			WriteData(fid,'object',obj,'class','mesh','fieldname','y','format','DoubleMat','mattype',1);
@@ -104,6 +191,12 @@
 			WriteData(fid,'object',obj,'class','mesh','fieldname','average_vertex_connectivity','format','Integer');
 		end % }}}
-		function t = meshtype(obj) % {{{
+		function t = domaintype(obj) % {{{
 			t = '2Dhorizontal';
+		end % }}}
+		function d = dimension(obj) % {{{
+			d = 2;
+		end % }}}
+		function s = elementtype(obj) % {{{
+			s = 'Tria';
 		end % }}}
 	end
Index: /issm/trunk/src/m/classes/mesh2d.py
===================================================================
--- /issm/trunk/src/m/classes/mesh2d.py	(revision 17805)
+++ /issm/trunk/src/m/classes/mesh2d.py	(revision 17806)
@@ -2,6 +2,7 @@
 from fielddisplay import fielddisplay
 from EnumDefinitions import *
-from checkfield import *
-from MatlabFuncs import *
+from checkfield import checkfield
+import MatlabFuncs as m
+from WriteData import WriteData
 
 class mesh2d(object):
@@ -41,5 +42,5 @@
 		#}}}
 	def __repr__(self): # {{{
-		string="   2d Mesh:" 
+		string="   2D tria Mesh (horizontal):" 
 
 		string="%s\n%s"%(string,"\n      Elements and vertices:")
@@ -83,14 +84,13 @@
 	def checkconsistency(self,md,solution,analyses):    # {{{
 
-		md = checkfield(md,'mesh.x','NaN',1,'size',[md.mesh.numberofvertices])
-		md = checkfield(md,'mesh.y','NaN',1,'size',[md.mesh.numberofvertices])
-		md = checkfield(md,'mesh.z','NaN',1,'size',[md.mesh.numberofvertices])
-		md = checkfield(md,'mesh.elements','NaN',1,'>',0,'values',numpy.arange(1,md.mesh.numberofvertices+1))
-		md = checkfield(md,'mesh.elements','size',[md.mesh.numberofelements,3])
-		if numpy.any(numpy.logical_not(ismember(numpy.arange(1,md.mesh.numberofvertices+1),md.mesh.elements))):
+		md = checkfield(md,'fieldname','mesh.x','NaN',1,'size',[md.mesh.numberofvertices])
+		md = checkfield(md,'fieldname','mesh.y','NaN',1,'size',[md.mesh.numberofvertices])
+		md = checkfield(md,'fieldname','mesh.elements','NaN',1,'>',0,'values',numpy.arange(1,md.mesh.numberofvertices+1))
+		md = checkfield(md,'fieldname','mesh.elements','size',[md.mesh.numberofelements,3])
+		if numpy.any(numpy.logical_not(m.ismember(numpy.arange(1,md.mesh.numberofvertices+1),md.mesh.elements))):
 			md.checkmessage("orphan nodes have been found. Check the mesh outline")
-		md = checkfield(md,'mesh.numberofelements','>',0)
-		md = checkfield(md,'mesh.numberofvertices','>',0)
-		md = checkfield(md,'mesh.average_vertex_connectivity','>=',9,'message',"'mesh.average_vertex_connectivity' should be at least 9 in 2d")
+		md = checkfield(md,'fieldname','mesh.numberofelements','>',0)
+		md = checkfield(md,'fieldname','mesh.numberofvertices','>',0)
+		md = checkfield(md,'fieldname','mesh.average_vertex_connectivity','>=',9,'message',"'mesh.average_vertex_connectivity' should be at least 9 in 2d")
 		if solution==ThermalSolutionEnum():
 			md.checkmessage("thermal not supported for 2d mesh")
@@ -98,9 +98,17 @@
 		return md
 	# }}}
-	def meshtype(self): # {{{
+	def domaintype(self): # {{{
 		return "2Dhorizontal"
 	#}}}
+	def dimension(self): # {{{
+		return 2
+	#}}}
+	def elementtype(self): # {{{
+		return "Tria"
+	#}}}
 	def marshall(self,md,fid):    # {{{
-		WriteData(fid,'enum',MeshTypeEnum(),'data',StringToEnum("Mesh"+self.meshtype())[0],'format','Integer');
+		WriteData(fid,'enum',DomainTypeEnum(),'data',StringToEnum("Domain"+self.domaintype())[0],'format','Integer');
+		WriteData(fid,'enum',DomainDimensionEnum(),'data',self.dimension(),'format','Integer');
+		WriteData(fid,'enum',MeshElementtypeEnum(),'data',StringToEnum(self.elementtype())[0],'format','Integer');
 		WriteData(fid,'object',self,'class','mesh','fieldname','x','format','DoubleMat','mattype',1)
 		WriteData(fid,'object',self,'class','mesh','fieldname','y','format','DoubleMat','mattype',1)
Index: /issm/trunk/src/m/classes/mesh2dvertical.m
===================================================================
--- /issm/trunk/src/m/classes/mesh2dvertical.m	(revision 17805)
+++ /issm/trunk/src/m/classes/mesh2dvertical.m	(revision 17806)
@@ -18,5 +18,5 @@
 
 		vertexonboundary            = NaN
-		vertexonbed                 = NaN
+		vertexonbase                 = NaN
 		vertexonsurface             = NaN
 
@@ -58,16 +58,16 @@
 		function md = checkconsistency(obj,md,solution,analyses) % {{{
 
-			md = checkfield(md,'mesh.x','NaN',1,'size',[md.mesh.numberofvertices 1]);
-			md = checkfield(md,'mesh.y','NaN',1,'size',[md.mesh.numberofvertices 1]);
-			md = checkfield(md,'mesh.elements','NaN',1,'>',0,'values',1:md.mesh.numberofvertices);
-			md = checkfield(md,'mesh.elements','size',[md.mesh.numberofelements 3]);
+			md = checkfield(md,'fieldname','mesh.x','NaN',1,'size',[md.mesh.numberofvertices 1]);
+			md = checkfield(md,'fieldname','mesh.y','NaN',1,'size',[md.mesh.numberofvertices 1]);
+			md = checkfield(md,'fieldname','mesh.elements','NaN',1,'>',0,'values',1:md.mesh.numberofvertices);
+			md = checkfield(md,'fieldname','mesh.elements','size',[md.mesh.numberofelements 3]);
 			if any(~ismember(1:md.mesh.numberofvertices,sort(unique(md.mesh.elements(:)))));
 				md = checkmessage(md,'orphan nodes have been found. Check the mesh outline');
 			end
-			md = checkfield(md,'mesh.numberofelements','>',0);
-			md = checkfield(md,'mesh.numberofvertices','>',0);
-			md = checkfield(md,'mesh.vertexonbed','size',[md.mesh.numberofvertices 1],'values',[0 1]);
-			md = checkfield(md,'mesh.vertexonsurface','size',[md.mesh.numberofvertices 1],'values',[0 1]);
-			md = checkfield(md,'mesh.average_vertex_connectivity','>=',9,'message','''mesh.average_vertex_connectivity'' should be at least 9 in 2d');
+			md = checkfield(md,'fieldname','mesh.numberofelements','>',0);
+			md = checkfield(md,'fieldname','mesh.numberofvertices','>',0);
+			md = checkfield(md,'fieldname','mesh.vertexonbase','size',[md.mesh.numberofvertices 1],'values',[0 1]);
+			md = checkfield(md,'fieldname','mesh.vertexonsurface','size',[md.mesh.numberofvertices 1],'values',[0 1]);
+			md = checkfield(md,'fieldname','mesh.average_vertex_connectivity','>=',9,'message','''mesh.average_vertex_connectivity'' should be at least 9 in 2d');
 
 			switch(solution),
@@ -77,5 +77,5 @@
 		end % }}}
 		function disp(obj) % {{{
-			disp(sprintf('   2d vertical Mesh:')); 
+			disp(sprintf('   2D tria Mesh (vertical):')); 
 
 			disp(sprintf('\n      Elements and vertices:'));
@@ -90,5 +90,5 @@
 			disp(sprintf('\n      Properties:'));
 			fielddisplay(obj,'vertexonboundary','vertices on the boundary of the domain flag list');
-			fielddisplay(obj,'vertexonbed','vertices on the bed of the domain flag list');
+			fielddisplay(obj,'vertexonbase','vertices on the bed of the domain flag list');
 			fielddisplay(obj,'vertexonsurface','vertices on the surface of the domain flag list');
 			fielddisplay(obj,'segments','edges on domain boundary (vertex1 vertex2 element)');
@@ -104,5 +104,7 @@
 		end % }}}
 		function marshall(obj,md,fid) % {{{
-			WriteData(fid,'enum',MeshTypeEnum(),'data',StringToEnum(['Mesh' meshtype(obj)]),'format','Integer');
+			WriteData(fid,'enum',DomainTypeEnum(),'data',StringToEnum(['Domain' domaintype(obj)]),'format','Integer');
+			WriteData(fid,'enum',DomainDimensionEnum(),'data',dimension(obj),'format','Integer');
+			WriteData(fid,'enum',MeshElementtypeEnum(),'data',StringToEnum(elementtype(obj)),'format','Integer');
 			WriteData(fid,'object',obj,'class','mesh','fieldname','x','format','DoubleMat','mattype',1);
 			WriteData(fid,'object',obj,'class','mesh','fieldname','y','format','DoubleMat','mattype',1);
@@ -111,10 +113,16 @@
 			WriteData(fid,'object',obj,'class','mesh','fieldname','numberofelements','format','Integer');
 			WriteData(fid,'object',obj,'class','mesh','fieldname','numberofvertices','format','Integer');
-			WriteData(fid,'object',obj,'class','mesh','fieldname','vertexonbed','format','BooleanMat','mattype',1);
+			WriteData(fid,'object',obj,'class','mesh','fieldname','vertexonbase','format','BooleanMat','mattype',1);
 			WriteData(fid,'object',obj,'class','mesh','fieldname','vertexonsurface','format','BooleanMat','mattype',1);
 			WriteData(fid,'object',obj,'class','mesh','fieldname','average_vertex_connectivity','format','Integer');
 		end % }}}
-		function t = meshtype(obj) % {{{
+		function t = domaintype(obj) % {{{
 			t = '2Dvertical';
+		end % }}}
+		function d = dimension(obj) % {{{
+			d = 2;
+		end % }}}
+		function s = elementtype(obj) % {{{
+			s = 'Tria';
 		end % }}}
 		function flags = vertexflags(self,value) % {{{
Index: /issm/trunk/src/m/classes/mesh3dprisms.m
===================================================================
--- /issm/trunk/src/m/classes/mesh3dprisms.m	(revision 17806)
+++ /issm/trunk/src/m/classes/mesh3dprisms.m	(revision 17806)
@@ -0,0 +1,168 @@
+%MESH3DPRISMS class definition
+%
+%   Usage:
+%      mesh=mesh3dprisms();
+
+classdef mesh3dprisms
+	properties (SetAccess=public) 
+		x                           = NaN;
+		y                           = NaN;
+		z                           = NaN
+		elements                    = NaN
+		numberoflayers              = 0;
+		numberofelements            = 0;
+		numberofvertices            = 0;
+
+		lat                         = NaN
+		long                        = NaN
+		hemisphere                  = NaN
+
+		elementonbase                = NaN
+		elementonsurface            = NaN
+		vertexonbase                 = NaN
+		vertexonsurface             = NaN
+		lowerelements               = NaN
+		lowervertex                 = NaN
+		upperelements               = NaN
+		uppervertex                 = NaN
+		vertexonboundary            = NaN
+
+		vertexconnectivity          = NaN
+		elementconnectivity         = NaN
+		average_vertex_connectivity = 0;
+
+		x2d                         = NaN
+		y2d                         = NaN
+		elements2d                  = NaN
+		numberofvertices2d          = 0;
+		numberofelements2d          = 0;
+
+		extractedvertices           = NaN
+		extractedelements           = NaN
+	end
+	methods
+		function self = mesh3dprisms(varargin) % {{{
+			switch nargin
+				case 0
+					self=setdefaultparameters(self);
+				case 1
+					self=mesh3dprisms();
+					object=varargin{1};
+					fields=fieldnames(object);
+					for i=1:length(fields)
+						field=fields{i};
+						if ismember(field,properties('mesh3dprisms')),
+							self.(field)=object.(field);
+						end
+					end
+				otherwise
+					error('constructor not supported');
+			end
+		end % }}}
+		function obj = setdefaultparameters(obj) % {{{
+
+			%the connectivity is the averaged number of nodes linked to a
+			%given node through an edge. This connectivity is used to initially
+			%allocate memory to the stiffness matrix. A value of 16 seems to
+			%give a good memory/time ration. This value can be checked in
+			%trunk/test/Miscellaneous/runme.m
+			obj.average_vertex_connectivity=25;
+		end % }}}
+		function md = checkconsistency(obj,md,solution,analyses) % {{{
+
+			md = checkfield(md,'fieldname','mesh.x','NaN',1,'size',[md.mesh.numberofvertices 1]);
+			md = checkfield(md,'fieldname','mesh.y','NaN',1,'size',[md.mesh.numberofvertices 1]);
+			md = checkfield(md,'fieldname','mesh.z','NaN',1,'size',[md.mesh.numberofvertices 1]);
+			md = checkfield(md,'fieldname','mesh.elements','NaN',1,'>',0,'values',1:md.mesh.numberofvertices);
+			md = checkfield(md,'fieldname','mesh.elements','size',[md.mesh.numberofelements 6]);
+			if any(~ismember(1:md.mesh.numberofvertices,sort(unique(md.mesh.elements(:)))));
+				md = checkmessage(md,'orphan nodes have been found. Check the mesh outline');
+			end
+			md = checkfield(md,'fieldname','mesh.numberoflayers','>=',0);
+			md = checkfield(md,'fieldname','mesh.numberofelements','>',0);
+			md = checkfield(md,'fieldname','mesh.numberofvertices','>',0);
+			%no checks for numberofedges lat long and hemisphere
+			md = checkfield(md,'fieldname','mesh.elementonbase','size',[md.mesh.numberofelements 1],'values',[0 1]);
+			md = checkfield(md,'fieldname','mesh.elementonsurface','size',[md.mesh.numberofelements 1],'values',[0 1]);
+			md = checkfield(md,'fieldname','mesh.vertexonbase','size',[md.mesh.numberofvertices 1],'values',[0 1]);
+			md = checkfield(md,'fieldname','mesh.vertexonsurface','size',[md.mesh.numberofvertices 1],'values',[0 1]);
+			md = checkfield(md,'fieldname','mesh.z','>=',md.geometry.base-10^-10,'message','''mesh.z'' lower than bedrock');
+			md = checkfield(md,'fieldname','mesh.z','<=',md.geometry.surface+10^-10,'message','''mesh.z'' higher than surface elevation');
+			md = checkfield(md,'fieldname','mesh.average_vertex_connectivity','>=',24,'message','''mesh.average_vertex_connectivity'' should be at least 24 in 3d');
+		end % }}}
+		function disp(obj) % {{{
+			disp(sprintf('   3D prism Mesh:')); 
+
+			disp(sprintf('\n      Elements and vertices of the original 2d mesh:'));
+			fielddisplay(obj,'numberofelements2d','number of elements');
+			fielddisplay(obj,'numberofvertices2d','number of vertices');
+			fielddisplay(obj,'elements2d','vertex indices of the mesh elements');
+			fielddisplay(obj,'x2d','vertices x coordinate [m]');
+			fielddisplay(obj,'y2d','vertices y coordinate [m]');
+
+			disp(sprintf('\n      Elements and vertices of the extruded 3d mesh:'));
+			fielddisplay(obj,'numberofelements','number of elements');
+			fielddisplay(obj,'numberofvertices','number of vertices');
+			fielddisplay(obj,'elements','vertex indices of the mesh elements');
+			fielddisplay(obj,'x','vertices x coordinate [m]');
+			fielddisplay(obj,'y','vertices y coordinate [m]');
+			fielddisplay(obj,'z','vertices z coordinate [m]');
+
+			disp(sprintf('\n      Properties:'));
+			fielddisplay(obj,'numberoflayers','number of extrusion layers');
+			fielddisplay(obj,'vertexonbase','lower vertices flags list');
+			fielddisplay(obj,'elementonbase','lower elements flags list');
+			fielddisplay(obj,'vertexonsurface','upper vertices flags list');
+			fielddisplay(obj,'elementonsurface','upper elements flags list');
+			fielddisplay(obj,'uppervertex','upper vertex list (NaN for vertex on the upper surface)');
+			fielddisplay(obj,'upperelements','upper element list (NaN for element on the upper layer)');
+			fielddisplay(obj,'lowervertex','lower vertex list (NaN for vertex on the lower surface)');
+			fielddisplay(obj,'lowerelements','lower element list (NaN for element on the lower layer');
+			fielddisplay(obj,'vertexonboundary','vertices on the boundary of the domain flag list');
+
+			fielddisplay(obj,'vertexconnectivity','list of vertices connected to vertex_i');
+			fielddisplay(obj,'elementconnectivity','list of vertices connected to element_i');
+			fielddisplay(obj,'average_vertex_connectivity','average number of vertices connected to one vertex');
+
+			disp(sprintf('\n      Extracted model:'));
+			fielddisplay(obj,'extractedvertices','vertices extracted from the model');
+			fielddisplay(obj,'extractedelements','elements extracted from the model');
+
+			disp(sprintf('\n      Projection:'));
+			fielddisplay(obj,'lat','vertices latitude [degrees]');
+			fielddisplay(obj,'long','vertices longitude [degrees]');
+			fielddisplay(obj,'hemisphere','Indicate hemisphere ''n'' or ''s'' ');
+		end % }}}
+		function marshall(obj,md,fid) % {{{
+			WriteData(fid,'enum',DomainTypeEnum(),'data',StringToEnum(['Domain' domaintype(obj)]),'format','Integer');
+			WriteData(fid,'enum',DomainDimensionEnum(),'data',dimension(obj),'format','Integer');
+			WriteData(fid,'enum',MeshElementtypeEnum(),'data',StringToEnum(elementtype(obj)),'format','Integer');
+			WriteData(fid,'object',obj,'class','mesh','fieldname','x','format','DoubleMat','mattype',1);
+			WriteData(fid,'object',obj,'class','mesh','fieldname','y','format','DoubleMat','mattype',1);
+			WriteData(fid,'object',obj,'class','mesh','fieldname','z','format','DoubleMat','mattype',1);
+			WriteData(fid,'object',obj,'class','mesh','fieldname','elements','format','DoubleMat','mattype',2);
+			WriteData(fid,'object',obj,'class','mesh','fieldname','numberoflayers','format','Integer');
+			WriteData(fid,'object',obj,'class','mesh','fieldname','numberofelements','format','Integer');
+			WriteData(fid,'object',obj,'class','mesh','fieldname','numberofvertices','format','Integer');
+			WriteData(fid,'object',obj,'class','mesh','fieldname','elementonbase','format','BooleanMat','mattype',2);
+			WriteData(fid,'object',obj,'class','mesh','fieldname','elementonsurface','format','BooleanMat','mattype',2);
+			WriteData(fid,'object',obj,'class','mesh','fieldname','vertexonbase','format','BooleanMat','mattype',1);
+			WriteData(fid,'object',obj,'class','mesh','fieldname','vertexonsurface','format','BooleanMat','mattype',1);
+			WriteData(fid,'object',obj,'class','mesh','fieldname','lowerelements','format','DoubleMat','mattype',2);
+			WriteData(fid,'object',obj,'class','mesh','fieldname','upperelements','format','DoubleMat','mattype',2);
+			WriteData(fid,'object',obj,'class','mesh','fieldname','average_vertex_connectivity','format','Integer');
+			WriteData(fid,'object',obj,'class','mesh','fieldname','elements2d','format','DoubleMat','mattype',3);
+			WriteData(fid,'object',obj,'class','mesh','fieldname','numberofvertices2d','format','Integer');
+			WriteData(fid,'object',obj,'class','mesh','fieldname','numberofelements2d','format','Integer');
+		end % }}}
+		function type = domaintype(obj) % {{{
+			type = '3D';
+		end % }}}
+		function d = dimension(obj) % {{{
+			d = 3;
+		end % }}}
+		function s = elementtype(obj) % {{{
+			s = 'Penta';
+		end % }}}
+	end
+end
Index: /issm/trunk/src/m/classes/mesh3dprisms.py
===================================================================
--- /issm/trunk/src/m/classes/mesh3dprisms.py	(revision 17806)
+++ /issm/trunk/src/m/classes/mesh3dprisms.py	(revision 17806)
@@ -0,0 +1,161 @@
+import numpy
+from fielddisplay import fielddisplay
+from EnumDefinitions import *
+from checkfield import *
+import MatlabFuncs as m
+from WriteData import WriteData
+
+class mesh3dprisms(object):
+	"""
+	MESH3DPRISMS class definition
+
+	   Usage:
+	      mesh3d=mesh3dprisms();
+	"""
+
+	def __init__(self): # {{{
+		self.x                           = float('NaN');
+		self.y                           = float('NaN');
+		self.z                           = float('NaN');
+		self.elements                    = float('NaN');
+		self.numberoflayers              = 0;
+		self.numberofelements            = 0;
+		self.numberofvertices            = 0;
+		
+		self.lat                         = float('NaN');
+		self.long                        = float('NaN');
+		self.hemisphere                  = float('NaN');
+
+		self.elementonbase                = float('NaN');
+		self.elementonsurface            = float('NaN');
+		self.vertexonbase                 = float('NaN');
+		self.vertexonsurface             = float('NaN');
+		self.lowerelements               = float('NaN');
+		self.lowervertex                 = float('NaN');
+		self.upperelements               = float('NaN');
+		self.uppervertex                 = float('NaN');
+		self.vertexonboundary            = float('NaN');
+
+		self.vertexconnectivity          = float('NaN');
+		self.elementconnectivity         = float('NaN');
+		self.average_vertex_connectivity = 0;
+
+		self.x2d                         = float('NaN');
+		self.y2d                         = float('NaN');
+		self.elements2d                  = float('NaN');
+		self.numberofvertices2d          = 0;
+		self.numberofelements2d          = 0;
+
+		self.extractedvertices           = float('NaN');
+		self.extractedelements           = float('NaN');
+
+		#set defaults
+		self.setdefaultparameters()
+		#}}}
+	def __repr__(self): # {{{
+		string="   3D prism Mesh:" 
+
+		string="%s\n%s"%(string,"\n      Elements and vertices of the original 2d mesh3dprisms:")
+		
+		string="%s\n%s"%(string,fielddisplay(self,"numberofelements2d","number of elements"))
+		string="%s\n%s"%(string,fielddisplay(self,"numberofvertices2d","number of vertices"))
+		string="%s\n%s"%(string,fielddisplay(self,"elements2d","vertex indices of the mesh3dprisms elements"))
+		string="%s\n%s"%(string,fielddisplay(self,"x2d","vertices x coordinate [m]"))
+		string="%s\n%s"%(string,fielddisplay(self,"y2d","vertices y coordinate [m]"))
+
+		string="%s\n%s"%(string,"\n\n      Elements and vertices of the extruded 3d mesh3dprisms:")
+		string="%s\n%s"%(string,fielddisplay(self,"numberofelements","number of elements"))
+		string="%s\n%s"%(string,fielddisplay(self,"numberofvertices","number of vertices"))
+		string="%s\n%s"%(string,fielddisplay(self,"elements","vertex indices of the mesh3dprisms elements"))
+		string="%s\n%s"%(string,fielddisplay(self,"x","vertices x coordinate [m]"))
+		string="%s\n%s"%(string,fielddisplay(self,"y","vertices y coordinate [m]"))
+		string="%s\n%s"%(string,fielddisplay(self,"z","vertices z coordinate [m]"))
+
+		string="%s%s"%(string,"\n\n      Properties:")
+		string="%s\n%s"%(string,fielddisplay(self,"numberoflayers","number of extrusion layers"))
+		string="%s\n%s"%(string,fielddisplay(self,"vertexonbase","lower vertices flags list"))
+		string="%s\n%s"%(string,fielddisplay(self,"elementonbase","lower elements flags list"))
+		string="%s\n%s"%(string,fielddisplay(self,"vertexonsurface","upper vertices flags list"))
+		string="%s\n%s"%(string,fielddisplay(self,"elementonsurface","upper elements flags list"))
+		string="%s\n%s"%(string,fielddisplay(self,"uppervertex","upper vertex list (-1 for vertex on the upper surface)"))
+		string="%s\n%s"%(string,fielddisplay(self,"upperelements","upper element list (-1 for element on the upper layer)"))
+		string="%s\n%s"%(string,fielddisplay(self,"lowervertex","lower vertex list (-1 for vertex on the lower surface)"))
+		string="%s\n%s"%(string,fielddisplay(self,"lowerelements","lower element list (-1 for element on the lower layer)"))
+		string="%s\n%s"%(string,fielddisplay(self,"vertexonboundary","vertices on the boundary of the domain flag list"))
+		string="%s\n%s"%(string,fielddisplay(self,"vertexconnectivity","list of vertices connected to vertex_i"))
+		string="%s\n%s"%(string,fielddisplay(self,"elementconnectivity","list of vertices connected to element_i"))
+		string="%s\n%s"%(string,fielddisplay(self,"average_vertex_connectivity","average number of vertices connected to one vertex"))
+
+		string="%s%s"%(string,"\n\n      Extracted model:")
+		string="%s\n%s"%(string,fielddisplay(self,"extractedvertices","vertices extracted from the model"))
+		string="%s\n%s"%(string,fielddisplay(self,"extractedelements","elements extracted from the model"))
+
+		string="%s%s"%(string,"\n\n      Projection:")
+		string="%s\n%s"%(string,fielddisplay(self,"lat","vertices latitude [degrees]"))
+		string="%s\n%s"%(string,fielddisplay(self,"long","vertices longitude [degrees]"))
+		string="%s\n%s"%(string,fielddisplay(self,"hemisphere","Indicate hemisphere 'n' or 's'"))
+		return string
+		#}}}
+	def setdefaultparameters(self): # {{{
+		
+		#the connectivity is the averaged number of nodes linked to a
+		#given node through an edge. This connectivity is used to initially
+		#allocate memory to the stiffness matrix. A value of 16 seems to
+		#give a good memory/time ration. This value can be checked in
+		#trunk/test/Miscellaneous/runme.m
+		self.average_vertex_connectivity=25
+
+		return self
+	#}}}
+	def checkconsistency(self,md,solution,analyses):    # {{{
+
+		md = checkfield(md,'fieldname','mesh.x','NaN',1,'size',[md.mesh.numberofvertices])
+		md = checkfield(md,'fieldname','mesh.y','NaN',1,'size',[md.mesh.numberofvertices])
+		md = checkfield(md,'fieldname','mesh.z','NaN',1,'size',[md.mesh.numberofvertices])
+		md = checkfield(md,'fieldname','mesh.elements','NaN',1,'>',0,'values',numpy.arange(1,md.mesh.numberofvertices+1))
+		md = checkfield(md,'fieldname','mesh.elements','size',[md.mesh.numberofelements,6])
+		if numpy.any(numpy.logical_not(m.ismember(numpy.arange(1,md.mesh.numberofvertices+1),md.mesh.elements))):
+			md.checkmessage("orphan nodes have been found. Check the mesh3dprisms outline")
+		md = checkfield(md,'fieldname','mesh.numberoflayers','>=',0)
+		md = checkfield(md,'fieldname','mesh.numberofelements','>',0)
+		md = checkfield(md,'fieldname','mesh.numberofvertices','>',0)
+		#no checks for numberofedges lat long and hemisphere
+		md = checkfield(md,'fieldname','mesh.elementonbase','size',[md.mesh.numberofelements],'values',[0,1])
+		md = checkfield(md,'fieldname','mesh.elementonsurface','size',[md.mesh.numberofelements],'values',[0,1])
+		md = checkfield(md,'fieldname','mesh.vertexonbase','size',[md.mesh.numberofvertices],'values',[0,1])
+		md = checkfield(md,'fieldname','mesh.vertexonsurface','size',[md.mesh.numberofvertices],'values',[0,1])
+		md = checkfield(md,'fieldname','mesh.average_vertex_connectivity','>=',24,'message',"'mesh.average_vertex_connectivity' should be at least 24 in 3d")
+
+		return md
+	# }}}
+	def domaintype(self): # {{{
+		return "3D"
+	#}}}
+	def dimension(self): # {{{
+		return 3
+	#}}}
+	def elementtype(self): # {{{
+		return "Penta"
+	#}}}
+	def marshall(self,md,fid):    # {{{
+		WriteData(fid,'enum',DomainTypeEnum(),'data',StringToEnum("Domain"+self.domaintype())[0],'format','Integer');
+		WriteData(fid,'enum',DomainDimensionEnum(),'data',self.dimension(),'format','Integer');
+		WriteData(fid,'enum',MeshElementtypeEnum(),'data',StringToEnum(self.elementtype())[0],'format','Integer');
+		WriteData(fid,'object',self,'class','mesh','fieldname','x','format','DoubleMat','mattype',1)
+		WriteData(fid,'object',self,'class','mesh','fieldname','y','format','DoubleMat','mattype',1)
+		WriteData(fid,'object',self,'class','mesh','fieldname','z','format','DoubleMat','mattype',1)
+		WriteData(fid,'object',self,'class','mesh','fieldname','elements','format','DoubleMat','mattype',2)
+		WriteData(fid,'object',self,'class','mesh','fieldname','numberoflayers','format','Integer')
+		WriteData(fid,'object',self,'class','mesh','fieldname','numberofelements','format','Integer')
+		WriteData(fid,'object',self,'class','mesh','fieldname','numberofvertices','format','Integer')
+		WriteData(fid,'object',self,'class','mesh','fieldname','elementonbase','format','BooleanMat','mattype',2)
+		WriteData(fid,'object',self,'class','mesh','fieldname','elementonsurface','format','BooleanMat','mattype',2)
+		WriteData(fid,'object',self,'class','mesh','fieldname','vertexonbase','format','BooleanMat','mattype',1)
+		WriteData(fid,'object',self,'class','mesh','fieldname','vertexonsurface','format','BooleanMat','mattype',1)
+		WriteData(fid,'object',self,'class','mesh','fieldname','lowerelements','format','DoubleMat','mattype',2)
+		WriteData(fid,'object',self,'class','mesh','fieldname','upperelements','format','DoubleMat','mattype',2)
+		WriteData(fid,'object',self,'class','mesh','fieldname','average_vertex_connectivity','format','Integer')
+		WriteData(fid,'object',self,'class','mesh','fieldname','elements2d','format','DoubleMat','mattype',3)
+		WriteData(fid,'object',self,'class','mesh','fieldname','numberofvertices2d','format','Integer')
+		WriteData(fid,'object',self,'class','mesh','fieldname','numberofelements2d','format','Integer')
+	# }}}
Index: /issm/trunk/src/m/classes/mesh3dtetras.m
===================================================================
--- /issm/trunk/src/m/classes/mesh3dtetras.m	(revision 17806)
+++ /issm/trunk/src/m/classes/mesh3dtetras.m	(revision 17806)
@@ -0,0 +1,160 @@
+%MESH3DTETRAS class definition
+%
+%   Usage:
+%      mesh=mesh3dtetras();
+
+classdef mesh3dtetras
+	properties (SetAccess=public) 
+		x                           = NaN;
+		y                           = NaN;
+		z                           = NaN
+		elements                    = NaN
+		numberoflayers              = 0;
+		numberofelements            = 0;
+		numberofvertices            = 0;
+
+		lat                         = NaN
+		long                        = NaN
+		hemisphere                  = NaN
+
+		vertexonbase                 = NaN
+		vertexonsurface             = NaN
+		lowerelements               = NaN
+		lowervertex                 = NaN
+		upperelements               = NaN
+		uppervertex                 = NaN
+		vertexonboundary            = NaN
+
+		vertexconnectivity          = NaN
+		elementconnectivity         = NaN
+		average_vertex_connectivity = 0;
+
+		x2d                         = NaN
+		y2d                         = NaN
+		elements2d                  = NaN
+		numberofvertices2d          = 0;
+		numberofelements2d          = 0;
+
+		extractedvertices           = NaN
+		extractedelements           = NaN
+	end
+	methods
+		function self = mesh3dtetras(varargin) % {{{
+			switch nargin
+				case 0
+					self=setdefaultparameters(self);
+				case 1
+					inputstruct=varargin{1};
+					list1 = properties('mesh3dtetras');
+					list2 = fieldnames(inputstruct);
+					for i=1:length(list1)
+						fieldname = list1{i};
+						if ismember(fieldname,list2),
+							self.(fieldname) = inputstruct.(fieldname);
+						end
+					end
+				otherwise
+					error('constructor not supported');
+			end
+		end % }}}
+		function obj = setdefaultparameters(obj) % {{{
+
+			%the connectivity is the averaged number of nodes linked to a
+			%given node through an edge. This connectivity is used to initially
+			%allocate memory to the stiffness matrix. A value of 16 seems to
+			%give a good memory/time ration. This value can be checked in
+			%trunk/test/Miscellaneous/runme.m
+			obj.average_vertex_connectivity=25;
+		end % }}}
+		function md = checkconsistency(obj,md,solution,analyses) % {{{
+
+			md = checkfield(md,'fieldname','mesh.x','NaN',1,'size',[md.mesh.numberofvertices 1]);
+			md = checkfield(md,'fieldname','mesh.y','NaN',1,'size',[md.mesh.numberofvertices 1]);
+			md = checkfield(md,'fieldname','mesh.z','NaN',1,'size',[md.mesh.numberofvertices 1]);
+			md = checkfield(md,'fieldname','mesh.elements','NaN',1,'>',0,'values',1:md.mesh.numberofvertices);
+			md = checkfield(md,'fieldname','mesh.elements','size',[md.mesh.numberofelements 4]);
+			if any(~ismember(1:md.mesh.numberofvertices,sort(unique(md.mesh.elements(:)))));
+				md = checkmessage(md,'orphan nodes have been found. Check the mesh outline');
+			end
+			md = checkfield(md,'fieldname','mesh.numberoflayers','>=',0);
+			md = checkfield(md,'fieldname','mesh.numberofelements','>',0);
+			md = checkfield(md,'fieldname','mesh.numberofvertices','>',0);
+			%no checks for numberofedges lat long and hemisphere
+			md = checkfield(md,'fieldname','mesh.vertexonbase','size',[md.mesh.numberofvertices 1],'values',[0 1]);
+			md = checkfield(md,'fieldname','mesh.vertexonsurface','size',[md.mesh.numberofvertices 1],'values',[0 1]);
+			md = checkfield(md,'fieldname','mesh.z','>=',md.geometry.base-10^-10,'message','''mesh.z'' lower than bedrock');
+			md = checkfield(md,'fieldname','mesh.z','<=',md.geometry.surface+10^-10,'message','''mesh.z'' higher than surface elevation');
+			md = checkfield(md,'fieldname','mesh.average_vertex_connectivity','>=',24,'message','''mesh.average_vertex_connectivity'' should be at least 24 in 3d');
+		end % }}}
+		function disp(obj) % {{{
+			disp(sprintf('   3D tetra Mesh:')); 
+
+			disp(sprintf('\n      Elements and vertices of the original 2d mesh:'));
+			fielddisplay(obj,'numberofelements2d','number of elements');
+			fielddisplay(obj,'numberofvertices2d','number of vertices');
+			fielddisplay(obj,'elements2d','vertex indices of the mesh elements');
+			fielddisplay(obj,'x2d','vertices x coordinate [m]');
+			fielddisplay(obj,'y2d','vertices y coordinate [m]');
+
+			disp(sprintf('\n      Elements and vertices of the extruded 3d mesh:'));
+			fielddisplay(obj,'numberofelements','number of elements');
+			fielddisplay(obj,'numberofvertices','number of vertices');
+			fielddisplay(obj,'elements','vertex indices of the mesh elements');
+			fielddisplay(obj,'x','vertices x coordinate [m]');
+			fielddisplay(obj,'y','vertices y coordinate [m]');
+			fielddisplay(obj,'z','vertices z coordinate [m]');
+
+			disp(sprintf('\n      Properties:'));
+			fielddisplay(obj,'numberoflayers','number of extrusion layers');
+			fielddisplay(obj,'vertexonbase','lower vertices flags list');
+			fielddisplay(obj,'vertexonsurface','upper vertices flags list');
+			fielddisplay(obj,'uppervertex','upper vertex list (NaN for vertex on the upper surface)');
+			fielddisplay(obj,'upperelements','upper element list (NaN for element on the upper layer)');
+			fielddisplay(obj,'lowervertex','lower vertex list (NaN for vertex on the lower surface)');
+			fielddisplay(obj,'lowerelements','lower element list (NaN for element on the lower layer');
+			fielddisplay(obj,'vertexonboundary','vertices on the boundary of the domain flag list');
+
+			fielddisplay(obj,'vertexconnectivity','list of vertices connected to vertex_i');
+			fielddisplay(obj,'elementconnectivity','list of vertices connected to element_i');
+			fielddisplay(obj,'average_vertex_connectivity','average number of vertices connected to one vertex');
+
+			disp(sprintf('\n      Extracted model:'));
+			fielddisplay(obj,'extractedvertices','vertices extracted from the model');
+			fielddisplay(obj,'extractedelements','elements extracted from the model');
+
+			disp(sprintf('\n      Projection:'));
+			fielddisplay(obj,'lat','vertices latitude [degrees]');
+			fielddisplay(obj,'long','vertices longitude [degrees]');
+			fielddisplay(obj,'hemisphere','Indicate hemisphere ''n'' or ''s'' ');
+		end % }}}
+		function marshall(obj,md,fid) % {{{
+			WriteData(fid,'enum',DomainTypeEnum(),'data',StringToEnum(['Domain' domaintype(obj)]),'format','Integer');
+			WriteData(fid,'enum',DomainDimensionEnum(),'data',dimension(obj),'format','Integer');
+			WriteData(fid,'enum',MeshElementtypeEnum(),'data',StringToEnum(elementtype(obj)),'format','Integer');
+			WriteData(fid,'object',obj,'class','mesh','fieldname','x','format','DoubleMat','mattype',1);
+			WriteData(fid,'object',obj,'class','mesh','fieldname','y','format','DoubleMat','mattype',1);
+			WriteData(fid,'object',obj,'class','mesh','fieldname','z','format','DoubleMat','mattype',1);
+			WriteData(fid,'object',obj,'class','mesh','fieldname','elements','format','DoubleMat','mattype',2);
+			WriteData(fid,'object',obj,'class','mesh','fieldname','numberoflayers','format','Integer');
+			WriteData(fid,'object',obj,'class','mesh','fieldname','numberofelements','format','Integer');
+			WriteData(fid,'object',obj,'class','mesh','fieldname','numberofvertices','format','Integer');
+			WriteData(fid,'object',obj,'class','mesh','fieldname','vertexonbase','format','BooleanMat','mattype',1);
+			WriteData(fid,'object',obj,'class','mesh','fieldname','vertexonsurface','format','BooleanMat','mattype',1);
+			WriteData(fid,'object',obj,'class','mesh','fieldname','lowerelements','format','DoubleMat','mattype',2);
+			WriteData(fid,'object',obj,'class','mesh','fieldname','upperelements','format','DoubleMat','mattype',2);
+			WriteData(fid,'object',obj,'class','mesh','fieldname','average_vertex_connectivity','format','Integer');
+			WriteData(fid,'object',obj,'class','mesh','fieldname','elements2d','format','DoubleMat','mattype',3);
+			WriteData(fid,'object',obj,'class','mesh','fieldname','numberofvertices2d','format','Integer');
+			WriteData(fid,'object',obj,'class','mesh','fieldname','numberofelements2d','format','Integer');
+		end % }}}
+		function t = domaintype(obj) % {{{
+			t = '3D';
+		end % }}}
+		function d = dimension(obj) % {{{
+			d = 3;
+		end % }}}
+		function s = elementtype(obj) % {{{
+			s = 'Tetra';
+		end % }}}
+	end
+end
Index: /issm/trunk/src/m/classes/miscellaneous.m
===================================================================
--- /issm/trunk/src/m/classes/miscellaneous.m	(revision 17805)
+++ /issm/trunk/src/m/classes/miscellaneous.m	(revision 17806)
@@ -11,4 +11,15 @@
 	end
 	methods
+        function createxml(obj,fid) % {{{
+            fprintf(fid, '<!-- miscellaneous -->\n');            
+                    
+            % miscellaneous solution parameters
+            fprintf(fid,'%s\n%s\n%s\n','<frame key="1" label="miscellaneous parameters">','<section name="miscellaneous" />');                    
+                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="notes" type="',class(obj.notes),'" default="',convert2str(obj.notes),'">','     <section name="miscellaneous" />','     <help> notes in a cell of strings </help>','  </parameter>');
+                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="name" type="',class(obj.name),'" default="',convert2str(obj.name),'">','     <section name="miscellaneous" />','     <help> model name </help>','  </parameter>');
+                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="dummy" type="',class(obj.dummy),'" default="',convert2str(obj.dummy),'">','     <section name="miscellaneous" />','     <help> empty field to store some data </help>','  </parameter>');
+            fprintf(fid,'%s\n%s\n','</frame>');    
+        
+        end % }}}        
 		function obj = miscellaneous(varargin) % {{{
 			switch nargin
@@ -21,5 +32,5 @@
 		function md = checkconsistency(obj,md,solution,analyses) % {{{
 
-			md = checkfield(md,'miscellaneous.name','empty',1);
+			md = checkfield(md,'fieldname','miscellaneous.name','empty',1);
 
 		end % }}}
Index: /issm/trunk/src/m/classes/miscellaneous.py
===================================================================
--- /issm/trunk/src/m/classes/miscellaneous.py	(revision 17805)
+++ /issm/trunk/src/m/classes/miscellaneous.py	(revision 17806)
@@ -2,6 +2,6 @@
 from fielddisplay import fielddisplay
 from EnumDefinitions import *
-from checkfield import *
-from WriteData import *
+from checkfield import checkfield
+from WriteData import WriteData
 
 class miscellaneous(object):
@@ -34,5 +34,5 @@
 	#}}}
 	def checkconsistency(self,md,solution,analyses):    # {{{
-		md = checkfield(md,'miscellaneous.name','empty',1)
+		md = checkfield(md,'fieldname','miscellaneous.name','empty',1)
 		return md
 	# }}}
Index: /issm/trunk/src/m/classes/misfit.m
===================================================================
--- /issm/trunk/src/m/classes/misfit.m	(revision 17806)
+++ /issm/trunk/src/m/classes/misfit.m	(revision 17806)
@@ -0,0 +1,89 @@
+%MISFIT class definition
+%
+%   Usage:
+%      misfit=misfit();
+%      misfit=misfit('name','SurfaceAltimetry',...
+%                    'model_enum',SurfaceEnum,...
+%                    'observation_enum',SurfaceObservationsEnum,...
+%                    'observation',md.geometry.surface,...
+%                    'timeinterpolation','nearestneighbor',...
+%                    'weights',ones(md.mesh.numberofvertices,1),...
+%                    'weights_enum',WeightsSurfaceObservationsEnum);
+%
+%
+
+classdef misfit
+	properties (SetAccess=public)
+		%misfit
+		name              = '';
+		model_enum        = NaN; %enum for field that is modeled
+		observation       = NaN; %observed field that we compare the model against
+		observation_enum  = NaN; %enum for observed field.
+		timeinterpolation = '';
+		weights           = NaN; %weight coefficients for every vertex
+		weights_enum      = NaN; %enum to identify this particular set of weights
+		cumulated         = NaN; %do we cumulate misfit through time?
+	end
+	
+	methods
+		function obj = misfit(varargin) % {{{
+			if nargin==0,
+				obj=setdefaultparameters(obj);
+			else
+				%use provided options to change fields
+				options=pairoptions(varargin{:});
+
+				%get name
+				obj.name=getfieldvalue(options,'name','');
+				obj.model_enum=getfieldvalue(options,'model_enum');
+				obj.observation=getfieldvalue(options,'observation',NaN);
+				obj.observation_enum=getfieldvalue(options,'observation_enum');
+				obj.timeinterpolation=getfieldvalue(options,'timeinterpolation','nearestneighbor');
+				obj.weights=getfieldvalue(options,'weights',NaN);
+				obj.weights_enum=getfieldvalue(options,'weights_enum',NaN);
+
+			end
+		end % }}}
+		function obj = setdefaultparameters(obj) % {{{
+			obj.timeinterpolation='nearestneighbor';
+		end % }}}
+		function md = checkconsistency(obj,md,solution,analyses) % {{{
+
+			if ~ischar(obj.name),
+				error('misfit error message: ''name'' field should be a string!');
+			end
+
+			if ~ischar(obj.timeinterpolation),
+				error('misfit error message: ''timeinterpolation'' field should be a string!');
+			end
+			md = checkfield(md,'fieldname','obj.observation','field',obj.observation,'forcing',1,'NaN',1);
+			md = checkfield(md,'fieldname','obj.timeinterpolation','field',obj.timeinterpolation,'values',{'nearestneighbor'});
+			md = checkfield(md,'fieldname','obj.weights','field',obj.weights,'forcing',1,'NaN',1);
+
+		end % }}}
+		function md = disp(obj) % {{{
+		
+			disp(sprintf('   Misfit:\n'));
+
+			fielddisplay(obj,'name','identifier for this misfit response');
+			fielddisplay(obj,'model_enum','enum for field that is modeled');
+			fielddisplay(obj,'observation','observed field that we compare the model against');
+			fielddisplay(obj,'observation_enum','observation enum');
+			fielddisplay(obj,'timeinterpolation','interpolation routine used to interpolate misfit between two time steps (default is ''nearestneighbor''');
+			fielddisplay(obj,'weights','weights (at vertices) to apply to the misfit');
+			fielddisplay(obj,'weights_enum','enum for weights for identification purposes');
+
+		end % }}}
+		function md = marshall(obj,md,fid) % {{{
+
+		WriteData(fid,'object',obj,'fieldname','name','format','String');
+		WriteData(fid,'object',obj,'fieldname','model_enum','format','Integer');
+		WriteData(fid,'object',obj,'fieldname','observation','format','DoubleMat','mattype',1,'forcinglength',md.mesh.numberofvertices+1);
+		WriteData(fid,'object',obj,'fieldname','observation_enum','format','Integer');
+		WriteData(fid,'object',obj,'fieldname','timeinterpolation','format','String');
+		WriteData(fid,'object',obj,'fieldname','weights','format','DoubleMat','mattype',1,'forcinglength',md.mesh.numberofvertices+1);
+		WriteData(fid,'object',obj,'fieldname','weights_enum','format','Integer');
+
+		end % }}}
+	end
+end
Index: /issm/trunk/src/m/classes/model.m
===================================================================
--- /issm/trunk/src/m/classes/model.m	(revision 17805)
+++ /issm/trunk/src/m/classes/model.m	(revision 17806)
@@ -30,8 +30,8 @@
 
 		balancethickness = 0;
-		stressbalance       = 0;
+		stressbalance    = 0;
 		groundingline    = 0;
 		hydrology        = 0;
-		masstransport       = 0;
+		masstransport    = 0;
 		thermal          = 0;
 		steadystate      = 0;
@@ -99,4 +99,28 @@
 				md.damage.D=zeros(md.mesh.numberofvertices,1);
 				md.damage.spcdamage=NaN*ones(md.mesh.numberofvertices,1);
+			end
+			%2013 November 18
+			if ~isa(md.outputdefinition,'outputdefinition'),
+				md.outputdefinition=outputdefinition();
+			end
+			%2014 January 9th
+			if isa(md.surfaceforcings,'surfaceforcings'),
+				disp('Recovering old surfaceforcings class');
+				mass_balance=md.surfaceforcings.mass_balance;
+				md.surfaceforcings=SMB();
+				md.surfaceforcings.mass_balance=mass_balance;
+			end
+			%2014 March 26th
+			if isa(md.mesh,'mesh'),
+				disp('Recovering old mesh class');
+				if isprop(md.mesh,'dimension'),
+					if md.mesh.dimension==2,
+						md.mesh=mesh2d(md.mesh);
+					else
+						md.mesh=mesh3dprisms(md.mesh);
+					end
+				else
+					md.mesh=mesh2dvertical(md.mesh);
+				end
 			end
 		end% }}}
@@ -132,9 +156,9 @@
 
 			%Check that the model is really a 3d model
-			if ~md.mesh.dimension==3,
+			if ~strcmp(md.mesh.elementtype(),'Penta'),
 				error('collapse error message: only 3d mesh can be collapsed')
 			end
 
-			%Start with changing alle the fields from the 3d mesh 
+			%Start with changing all the fields from the 3d mesh 
 
 			%drag is limited to nodes that are on the bedrock.
@@ -168,10 +192,4 @@
 			if ~isnan(md.gia.lithosphere_thickness), md.gia.lithosphere_thickness=project2d(md,md.gia.lithosphere_thickness,1); end
 
-			%bedinfo and surface info
-			md.mesh.elementonbed=ones(md.mesh.numberofelements2d,1);
-			md.mesh.elementonsurface=ones(md.mesh.numberofelements2d,1);
-			md.mesh.vertexonbed=ones(md.mesh.numberofvertices2d,1);
-			md.mesh.vertexonsurface=ones(md.mesh.numberofvertices2d,1);
-
 			%elementstype
 			if ~isnan(md.flowequation.element_equation)
@@ -214,6 +232,6 @@
 			md.geometry.surface=project2d(md,md.geometry.surface,1);
 			md.geometry.thickness=project2d(md,md.geometry.thickness,1);
+			md.geometry.base=project2d(md,md.geometry.base,1);
 			md.geometry.bed=project2d(md,md.geometry.bed,1);
-			md.geometry.bathymetry=project2d(md,md.geometry.bathymetry,1);
 			md.mesh.vertexonboundary=project2d(md,md.mesh.vertexonboundary,1);
 			md.mesh.elementconnectivity=project2d(md,md.mesh.elementconnectivity,1);
@@ -226,10 +244,12 @@
 
 			%Initialize with the 2d mesh
-			md.mesh.x=md.mesh.x2d;
-			md.mesh.y=md.mesh.y2d;
-			md.mesh.z=zeros(size(md.mesh.x2d));
-			md.mesh.numberofvertices=md.mesh.numberofvertices2d;
-			md.mesh.numberofelements=md.mesh.numberofelements2d;
-			md.mesh.elements=md.mesh.elements2d;
+			mesh=mesh2d();
+			mesh.x=md.mesh.x2d;
+			mesh.y=md.mesh.y2d;
+			mesh.z=zeros(size(md.mesh.x2d));
+			mesh.numberofvertices=md.mesh.numberofvertices2d;
+			mesh.numberofelements=md.mesh.numberofelements2d;
+			mesh.elements=md.mesh.elements2d;
+			md.mesh=mesh;
 
 			%Keep a trace of lower and upper nodes
@@ -247,6 +267,4 @@
 			md.mesh.numberoflayers=0;
 
-			%Update mesh type
-			md.mesh.dimension=2;
 		end % }}}
 		function md2 = extract(md,area) % {{{
@@ -316,5 +334,5 @@
 			elements_2(:,2)=Pnode(elements_2(:,2));
 			elements_2(:,3)=Pnode(elements_2(:,3));
-			if md1.mesh.dimension==3,
+			if isa(md1.mesh,'mesh3dprisms'),
 				elements_2(:,4)=Pnode(elements_2(:,4));
 				elements_2(:,5)=Pnode(elements_2(:,5));
@@ -372,5 +390,5 @@
 
 			%mesh.uppervertex mesh.lowervertex
-			if md1.mesh.dimension==3
+			if isa(md1.mesh,'mesh3dprisms'),
 				md2.mesh.uppervertex=md1.mesh.uppervertex(pos_node);
 				pos=find(~isnan(md2.mesh.uppervertex));
@@ -391,5 +409,5 @@
 
 			%Initial 2d mesh 
-			if md1.mesh.dimension==3
+			if isa(md1.mesh,'mesh3dprisms'),
 				flag_elem_2d=flag_elem(1:md1.mesh.numberofelements2d);
 				pos_elem_2d=find(flag_elem_2d);
@@ -409,28 +427,30 @@
 
 			%Edges
-			if size(md2.mesh.edges,2)>1, %do not use ~isnan because there are some NaNs...
-				%renumber first two columns
-				pos=find(md2.mesh.edges(:,4)~=-1);
-				md2.mesh.edges(:  ,1)=Pnode(md2.mesh.edges(:,1));
-				md2.mesh.edges(:  ,2)=Pnode(md2.mesh.edges(:,2));
-				md2.mesh.edges(:  ,3)=Pelem(md2.mesh.edges(:,3));
-				md2.mesh.edges(pos,4)=Pelem(md2.mesh.edges(pos,4));
-				%remove edges when the 2 vertices are not in the domain.
-				md2.mesh.edges=md2.mesh.edges(find(md2.mesh.edges(:,1) & md2.mesh.edges(:,2)),:);
-				%Replace all zeros by -1 in the last two columns
-				pos=find(md2.mesh.edges(:,3)==0);
-				md2.mesh.edges(pos,3)=-1;
-				pos=find(md2.mesh.edges(:,4)==0);
-				md2.mesh.edges(pos,4)=-1;
-				%Invert -1 on the third column with last column (Also invert first two columns!!)
-				pos=find(md2.mesh.edges(:,3)==-1);
-				md2.mesh.edges(pos,3)=md2.mesh.edges(pos,4);
-				md2.mesh.edges(pos,4)=-1;
-				values=md2.mesh.edges(pos,2);
-				md2.mesh.edges(pos,2)=md2.mesh.edges(pos,1);
-				md2.mesh.edges(pos,1)=values;
-				%Finally remove edges that do not belong to any element
-				pos=find(md2.mesh.edges(:,3)==-1 & md2.mesh.edges(:,4)==-1);
-				md2.mesh.edges(pos,:)=[];
+			if(dimension(md.mesh)==2),
+				if size(md2.mesh.edges,2)>1, %do not use ~isnan because there are some NaNs...
+					%renumber first two columns
+					pos=find(md2.mesh.edges(:,4)~=-1);
+					md2.mesh.edges(:  ,1)=Pnode(md2.mesh.edges(:,1));
+					md2.mesh.edges(:  ,2)=Pnode(md2.mesh.edges(:,2));
+					md2.mesh.edges(:  ,3)=Pelem(md2.mesh.edges(:,3));
+					md2.mesh.edges(pos,4)=Pelem(md2.mesh.edges(pos,4));
+					%remove edges when the 2 vertices are not in the domain.
+					md2.mesh.edges=md2.mesh.edges(find(md2.mesh.edges(:,1) & md2.mesh.edges(:,2)),:);
+					%Replace all zeros by -1 in the last two columns
+					pos=find(md2.mesh.edges(:,3)==0);
+					md2.mesh.edges(pos,3)=-1;
+					pos=find(md2.mesh.edges(:,4)==0);
+					md2.mesh.edges(pos,4)=-1;
+					%Invert -1 on the third column with last column (Also invert first two columns!!)
+					pos=find(md2.mesh.edges(:,3)==-1);
+					md2.mesh.edges(pos,3)=md2.mesh.edges(pos,4);
+					md2.mesh.edges(pos,4)=-1;
+					values=md2.mesh.edges(pos,2);
+					md2.mesh.edges(pos,2)=md2.mesh.edges(pos,1);
+					md2.mesh.edges(pos,1)=values;
+					%Finally remove edges that do not belong to any element
+					pos=find(md2.mesh.edges(:,3)==-1 & md2.mesh.edges(:,4)==-1);
+					md2.mesh.edges(pos,:)=[];
+				end
 			end
 
@@ -450,5 +470,5 @@
 
 			%recreate segments
-			if md1.mesh.dimension==2
+			if isa(md1.mesh,'mesh2d'),
 				md2.mesh.vertexconnectivity=NodeConnectivity(md2.mesh.elements,md2.mesh.numberofvertices);
 				md2.mesh.elementconnectivity=ElementConnectivity(md2.mesh.elements,md2.mesh.vertexconnectivity);
@@ -459,6 +479,6 @@
 				md2.mesh.vertexconnectivity=NodeConnectivity(md2.mesh.elements2d,md2.mesh.numberofvertices2d);
 				md2.mesh.elementconnectivity=ElementConnectivity(md2.mesh.elements2d,md2.mesh.vertexconnectivity);
-				md2.mesh.segments=contourenvelope(md2);
-				md2.mesh.vertexonboundary=zeros(numberofvertices2/md2.mesh.numberoflayers,1); md2.mesh.vertexonboundary(md2.mesh.segments(:,1:2))=1;
+				segments=contourenvelope(md2);
+				md2.mesh.vertexonboundary=zeros(numberofvertices2/md2.mesh.numberoflayers,1); md2.mesh.vertexonboundary(segments(:,1:2))=1;
 				md2.mesh.vertexonboundary=repmat(md2.mesh.vertexonboundary,md2.mesh.numberoflayers,1);
 				%Then do it for 3d as usual
@@ -589,14 +609,34 @@
 				error('number of layers should be at least 2');
 			end
-			if md.mesh.dimension==3,
+			if strcmp(md.mesh.domaintype(),'3D')
 				error('Cannot extrude a 3d mesh (extrude cannot be called more than once)');
 			end
 
 			%Initialize with the 2d mesh
+			mesh2d = md.mesh;
+			md.mesh=mesh3dprisms();
+			md.mesh.x                           = mesh2d.x;
+			md.mesh.y                           = mesh2d.y;
+			md.mesh.elements                    = mesh2d.elements;
+			md.mesh.numberofelements            = mesh2d.numberofelements;
+			md.mesh.numberofvertices            = mesh2d.numberofvertices;
+
+			md.mesh.lat                         = mesh2d.lat;
+			md.mesh.long                        = mesh2d.long;
+			md.mesh.hemisphere                  = mesh2d.hemisphere;
+
+			md.mesh.vertexonboundary            = mesh2d.vertexonboundary;
+			md.mesh.vertexconnectivity          = mesh2d.vertexconnectivity;
+			md.mesh.elementconnectivity         = mesh2d.elementconnectivity;
+			md.mesh.average_vertex_connectivity = mesh2d.average_vertex_connectivity;
+
+			md.mesh.extractedvertices           = mesh2d.extractedvertices;
+			md.mesh.extractedelements           = mesh2d.extractedelements;
+
 			x3d=[]; 
 			y3d=[];
 			z3d=[];  %the lower node is on the bed
 			thickness3d=md.geometry.thickness; %thickness and bed for these nodes
-			bed3d=md.geometry.bed;
+			bed3d=md.geometry.base;
 
 			%Create the new layers
@@ -617,18 +657,18 @@
 
 			%Keep a trace of lower and upper nodes
-			mesh.lowervertex=NaN*ones(number_nodes3d,1);
-			mesh.uppervertex=NaN*ones(number_nodes3d,1);
-			mesh.lowervertex(md.mesh.numberofvertices+1:end)=1:(numlayers-1)*md.mesh.numberofvertices;
-			mesh.uppervertex(1:(numlayers-1)*md.mesh.numberofvertices)=md.mesh.numberofvertices+1:number_nodes3d;
-			md.mesh.lowervertex=mesh.lowervertex;
-			md.mesh.uppervertex=mesh.uppervertex;
+			lowervertex=NaN*ones(number_nodes3d,1);
+			uppervertex=NaN*ones(number_nodes3d,1);
+			lowervertex(md.mesh.numberofvertices+1:end)=1:(numlayers-1)*md.mesh.numberofvertices;
+			uppervertex(1:(numlayers-1)*md.mesh.numberofvertices)=md.mesh.numberofvertices+1:number_nodes3d;
+			md.mesh.lowervertex=lowervertex;
+			md.mesh.uppervertex=uppervertex;
 
 			%same for lower and upper elements
-			mesh.lowerelements=NaN*ones(number_el3d,1);
-			mesh.upperelements=NaN*ones(number_el3d,1);
-			mesh.lowerelements(md.mesh.numberofelements+1:end)=1:(numlayers-2)*md.mesh.numberofelements;
-			mesh.upperelements(1:(numlayers-2)*md.mesh.numberofelements)=md.mesh.numberofelements+1:(numlayers-1)*md.mesh.numberofelements;
-			md.mesh.lowerelements=mesh.lowerelements;
-			md.mesh.upperelements=mesh.upperelements;
+			lowerelements=NaN*ones(number_el3d,1);
+			upperelements=NaN*ones(number_el3d,1);
+			lowerelements(md.mesh.numberofelements+1:end)=1:(numlayers-2)*md.mesh.numberofelements;
+			upperelements(1:(numlayers-2)*md.mesh.numberofelements)=md.mesh.numberofelements+1:(numlayers-1)*md.mesh.numberofelements;
+			md.mesh.lowerelements=lowerelements;
+			md.mesh.upperelements=upperelements;
 
 			%Save old mesh 
@@ -638,7 +678,4 @@
 			md.mesh.numberofelements2d=md.mesh.numberofelements;
 			md.mesh.numberofvertices2d=md.mesh.numberofvertices;
-
-			%Update mesh type
-			md.mesh.dimension=3;
 
 			%Build global 3d mesh 
@@ -668,8 +705,7 @@
 			md.inversion.vy_obs=project3d(md,'vector',md.inversion.vy_obs,'type','node');
 			md.inversion.vel_obs=project3d(md,'vector',md.inversion.vel_obs,'type','node');
-			md.surfaceforcings.mass_balance=project3d(md,'vector',md.surfaceforcings.mass_balance,'type','node');
-			md.surfaceforcings.precipitation=project3d(md,'vector',md.surfaceforcings.precipitation,'type','node');
+			md.inversion.thickness_obs=project3d(md,'vector',md.inversion.thickness_obs,'type','node');
+			md.surfaceforcings = extrude(md.surfaceforcings,md);
 			md.balancethickness.thickening_rate=project3d(md,'vector',md.balancethickness.thickening_rate,'type','node');
-			md.surfaceforcings.monthlytemperatures=project3d(md,'vector',md.surfaceforcings.monthlytemperatures,'type','node');
 
 			%results
@@ -683,9 +719,10 @@
       if ~isnan(md.initialization.sediment_head),md.initialization.sediment_head=project3d(md,'vector',md.initialization.sediment_head,'type','node','layer',1);end;
       if ~isnan(md.initialization.epl_head),md.initialization.epl_head=project3d(md,'vector',md.initialization.epl_head,'type','node','layer',1);end;
+      if ~isnan(md.initialization.epl_thickness),md.initialization.epl_thickness=project3d(md,'vector',md.initialization.epl_thickness,'type','node','layer',1);end;
 
 			%bedinfo and surface info
-			md.mesh.elementonbed=project3d(md,'vector',ones(md.mesh.numberofelements2d,1),'type','element','layer',1);
+			md.mesh.elementonbase=project3d(md,'vector',ones(md.mesh.numberofelements2d,1),'type','element','layer',1);
 			md.mesh.elementonsurface=project3d(md,'vector',ones(md.mesh.numberofelements2d,1),'type','element','layer',md.mesh.numberoflayers-1);
-			md.mesh.vertexonbed=project3d(md,'vector',ones(md.mesh.numberofvertices2d,1),'type','node','layer',1);
+			md.mesh.vertexonbase=project3d(md,'vector',ones(md.mesh.numberofvertices2d,1),'type','node','layer',1);
 			md.mesh.vertexonsurface=project3d(md,'vector',ones(md.mesh.numberofvertices2d,1),'type','node','layer',md.mesh.numberoflayers);
 
@@ -712,13 +749,25 @@
 			md.stressbalance.spcvz=project3d(md,'vector',md.stressbalance.spcvz,'type','node');
 			md.thermal.spctemperature=project3d(md,'vector',md.thermal.spctemperature,'type','node','layer',md.mesh.numberoflayers,'padding',NaN);
+			if (length(md.initialization.temperature)==md.mesh.numberofvertices),
+				md.thermal.spctemperature=NaN*ones(md.mesh.numberofvertices,1);
+				if isprop(md.mesh,'vertexonsurface'),
+					pos=find(md.mesh.vertexonsurface);
+					md.thermal.spctemperature(pos)=md.initialization.temperature(pos); %impose observed temperature on surface
+				end
+			end
 			md.masstransport.spcthickness=project3d(md,'vector',md.masstransport.spcthickness,'type','node');
+			md.masstransport.calvingrate=project3d(md,'vector',md.masstransport.calvingrate,'type','node');
 			md.balancethickness.spcthickness=project3d(md,'vector',md.balancethickness.spcthickness,'type','node');
 			md.damage.spcdamage=project3d(md,'vector',md.damage.spcdamage,'type','node');
 			md.stressbalance.referential=project3d(md,'vector',md.stressbalance.referential,'type','node');
 			md.stressbalance.loadingforce=project3d(md,'vector',md.stressbalance.loadingforce,'type','node');
+
+			% Hydrologydc variables
 			if isa(md.hydrology,'hydrologydc');
 				md.hydrology.spcsediment_head=project3d(md,'vector',md.hydrology.spcsediment_head,'type','node','layer',1);
 				md.hydrology.spcepl_head=project3d(md,'vector',md.hydrology.spcepl_head,'type','node','layer',1);
-				md.hydrology.mask_eplactive=project3d(md,'vector',md.hydrology.mask_eplactive,'type','node','layer',1);
+				md.hydrology.mask_eplactive_node=project3d(md,'vector',md.hydrology.mask_eplactive_node,'type','node','layer',1);
+				md.hydrology.sediment_transmitivity=project3d(md,'vector',md.hydrology.sediment_transmitivity,'type','node','layer',1);
+				md.hydrology.basal_moulin_input=project3d(md,'vector',md.hydrology.basal_moulin_input,'type','node','layer',1);
 	    end
 
@@ -745,6 +794,6 @@
 			md.gia.lithosphere_thickness=project3d(md,'vector',md.gia.lithosphere_thickness,'type','node');
 			md.geometry.hydrostatic_ratio=project3d(md,'vector',md.geometry.hydrostatic_ratio,'type','node');
+			md.geometry.base=project3d(md,'vector',md.geometry.base,'type','node');
 			md.geometry.bed=project3d(md,'vector',md.geometry.bed,'type','node');
-			md.geometry.bathymetry=project3d(md,'vector',md.geometry.bathymetry,'type','node');
 			md.mesh.vertexonboundary=project3d(md,'vector',md.mesh.vertexonboundary,'type','node');
 			md.mask.groundedice_levelset=project3d(md,'vector',md.mask.groundedice_levelset,'type','node');
@@ -754,7 +803,4 @@
 			if ~isnan(md.inversion.max_parameters),md.inversion.max_parameters=project3d(md,'vector',md.inversion.max_parameters,'type','node');end;
 			if ~isnan(md.qmu.partition),md.qmu.partition=project3d(md,'vector',md.qmu.partition','type','node');end
-			if(md.surfaceforcings.isdelta18o),md.surfaceforcings.temperatures_lgm=project3d(md,'vector',md.surfaceforcings.temperatures_lgm,'type','node');end
-			if(md.surfaceforcings.isdelta18o),md.surfaceforcings.temperatures_presentday=project3d(md,'vector',md.surfaceforcings.temperatures_presentday,'type','node');end
-			if(md.surfaceforcings.isdelta18o),md.surfaceforcings.precipitations_presentday=project3d(md,'vector',md.surfaceforcings.precipitations_presentday,'type','node');end
 
 			%Put lithostatic pressure if there is an existing pressure
@@ -796,5 +842,5 @@
 			if isfield(structmd,'uppergrids'), md.mesh.uppervertex=structmd.uppergrids; end
 			if isfield(structmd,'lowergrids'), md.mesh.lowervertex=structmd.lowergrids; end
-			if isfield(structmd,'gridonbed'), md.mesh.vertexonbed=structmd.gridonbed; end
+			if isfield(structmd,'gridonbase'), md.mesh.vertexonbase=structmd.gridonbase; end
 			if isfield(structmd,'gridonsurface'), md.mesh.vertexonsurface=structmd.gridonsurface; end
 			if isfield(structmd,'extractedgrids'), md.mesh.extractedvertices=structmd.extractedgrids; end
@@ -880,7 +926,7 @@
 			if isfield(structmd,'watercolumn'), md.initialization.watercolumn=structmd.watercolumn; end
 			if isfield(structmd,'surface'), md.geometry.surface=structmd.surface; end
-			if isfield(structmd,'bed'), md.geometry.bed=structmd.bed; end
+			if isfield(structmd,'bed'), md.geometry.base=structmd.bed; end
 			if isfield(structmd,'thickness'), md.geometry.thickness=structmd.thickness; end
-			if isfield(structmd,'bathymetry'), md.geometry.bathymetry=structmd.bathymetry; end
+			if isfield(structmd,'bathymetry'), md.geometry.bed=structmd.bathymetry; end
 			if isfield(structmd,'thickness_coeff'), md.geometry.hydrostatic_ratio=structmd.thickness_coeff; end
 			if isfield(structmd,'connectivity'), md.mesh.average_vertex_connectivity=structmd.connectivity; end
@@ -893,5 +939,4 @@
 			if isfield(structmd,'segments'), md.mesh.segments=structmd.segments; end
 			if isfield(structmd,'segmentmarkers'), md.mesh.segmentmarkers=structmd.segmentmarkers; end
-			if isfield(structmd,'dim'), md.mesh.dimension=structmd.dim; end
 			if isfield(structmd,'numlayers'), md.mesh.numberoflayers=structmd.numlayers; end
 			if isfield(structmd,'numberofelements'), md.mesh.numberofelements=structmd.numberofelements; end
@@ -907,8 +952,8 @@
 			if isfield(structmd,'upperelements'), md.mesh.upperelements=structmd.upperelements; end
 			if isfield(structmd,'lowerelements'), md.mesh.lowerelements=structmd.lowerelements; end
-			if isfield(structmd,'elementonbed'), md.mesh.elementonbed=structmd.elementonbed; end
+			if isfield(structmd,'elementonbase'), md.mesh.elementonbase=structmd.elementonbase; end
 			if isfield(structmd,'elementonsurface'), md.mesh.elementonsurface=structmd.elementonsurface; end
 			if isfield(structmd,'nodeonsurface'), md.mesh.vertexonsurface=structmd.nodeonsurface; end
-			if isfield(structmd,'nodeonbed'), md.mesh.vertexonbed=structmd.nodeonbed; end
+			if isfield(structmd,'nodeonbase'), md.mesh.vertexonbase=structmd.nodeonbase; end
 			if isfield(structmd,'elements2d'), md.mesh.elements2d=structmd.elements2d; end
 			if isfield(structmd,'y2d'), md.mesh.y2d=structmd.y2d; end
@@ -927,9 +972,4 @@
 			if isfield(structmd,'part'); md.qmu.partition=structmd.part; end
 
-			%Field changes
-			if (isfield(structmd,'type') & ischar(structmd.type)), 
-				if strcmpi(structmd.type,'2d'), md.mesh.dimension=2; end
-				if strcmpi(structmd.type,'3d'), md.mesh.dimension=3; end
-			end
 			if isnumeric(md.verbose),
 				md.verbose=verbose;
@@ -1053,10 +1093,10 @@
 
 			%initialize subclasses
-			md.mesh             = mesh();
+			md.mesh             = mesh2d();
 			md.mask             = mask();
 			md.constants        = constants();
 			md.geometry         = geometry();
 			md.initialization   = initialization();
-			md.surfaceforcings  = surfaceforcings();
+			md.surfaceforcings  = SMB();
 			md.basalforcings    = basalforcings();
 			md.friction         = friction();
@@ -1073,7 +1113,7 @@
 			md.cluster          = generic();
 			md.balancethickness = balancethickness();
-			md.stressbalance       = stressbalance();
+			md.stressbalance    = stressbalance();
 			md.hydrology        = hydrologyshreve();
-			md.masstransport       = masstransport();
+			md.masstransport    = masstransport();
 			md.thermal          = thermal();
 			md.steadystate      = steadystate();
@@ -1091,4 +1131,135 @@
 		end
 		%}}}
+		function md = tetras(md,varargin) % {{{
+			%TETRAS - split 3d prismatic mesh into 3 tetrahedrons
+			%
+			%   Usage:
+			%      md=tetra(md)
+
+			if ~isa(md.mesh,'mesh3dprisms')
+				error('mesh is not a 3d prismatic mesh');
+			end
+
+			%Initialize tetra mesh
+			md.mesh=mesh3dtetras(md.mesh);
+
+			%Subdivision from Philipp Furnstahl (http://studierstube.icg.tugraz.at/thesis/fuernstahl_thesis.pdf)
+			steiner  = 0;
+			nbv      = md.mesh.numberofvertices;
+			nbt      = 3*md.mesh.numberofelements;
+			elements = zeros(nbt,4);
+			for i=1:md.mesh.numberofelements
+				v1=md.mesh.elements(i,1); v2=md.mesh.elements(i,2); v3=md.mesh.elements(i,3);
+				v4=md.mesh.elements(i,4); v5=md.mesh.elements(i,5); v6=md.mesh.elements(i,6);
+				if(min(v2,v4)<min(v1,v5) & min(v1,v6)<min(v3,v4) & min(v3,v5)<min(v2,v6)),
+					steiner = steiner+1; nbv = nbv+1; nbt = nbt+5; v7 = nbv;
+					md.mesh.x=[md.mesh.x; mean(md.mesh.x(md.mesh.elements(i,:)))];
+					md.mesh.y=[md.mesh.y; mean(md.mesh.y(md.mesh.elements(i,:)))];
+					md.mesh.z=[md.mesh.z; mean(md.mesh.z(md.mesh.elements(i,:)))];
+					elements(3*(i-1)+1,:) = [v1 v2 v3 v7];
+					elements(3*(i-1)+2,:) = [v1 v2 v4 v7];
+					elements(3*(i-1)+3,:) = [v2 v4 v5 v7];
+					elements(end+1,:) = [v2 v3 v5 v7];
+					elements(end+1,:) = [v3 v5 v6 v7];
+					elements(end+1,:) = [v1 v3 v6 v7];
+					elements(end+1,:) = [v1 v4 v6 v7];
+					elements(end+1,:) = [v4 v5 v6 v7];
+				elseif(min(v2,v4)<min(v1,v5) & min(v1,v6)<min(v3,v4) & min(v3,v5)>min(v2,v6)),
+					elements(3*(i-1)+1,:) = [v1 v2 v4 v6];
+					elements(3*(i-1)+2,:) = [v2 v4 v5 v6];
+					elements(3*(i-1)+3,:) = [v1 v2 v3 v6];
+				elseif(min(v2,v4)<min(v1,v5) & min(v1,v6)>min(v3,v4) & min(v3,v5)<min(v2,v6)),
+					elements(3*(i-1)+1,:) = [v1 v2 v3 v4];
+					elements(3*(i-1)+2,:) = [v2 v3 v4 v5];
+					elements(3*(i-1)+3,:) = [v3 v4 v5 v6];
+				elseif(min(v2,v4)<min(v1,v5) & min(v1,v6)>min(v3,v4) & min(v3,v5)>min(v2,v6)),
+					elements(3*(i-1)+1,:) = [v1 v2 v3 v4];
+					elements(3*(i-1)+2,:) = [v2 v4 v5 v6];
+					elements(3*(i-1)+3,:) = [v2 v3 v4 v6];
+				elseif(min(v2,v4)>min(v1,v5) & min(v1,v6)<min(v3,v4) & min(v3,v5)>min(v2,v6)),
+					elements(3*(i-1)+1,:) = [v1 v4 v5 v6];
+					elements(3*(i-1)+2,:) = [v1 v2 v3 v5];
+					elements(3*(i-1)+3,:) = [v1 v3 v5 v6];
+				elseif(min(v2,v4)>min(v1,v5) & min(v1,v6)<min(v3,v4) & min(v3,v5)>min(v2,v6)),
+					elements(3*(i-1)+1,:) = [v1 v4 v5 v6];
+					elements(3*(i-1)+2,:) = [v1 v2 v5 v6];
+					elements(3*(i-1)+3,:) = [v1 v2 v3 v6];
+				elseif(min(v2,v4)>min(v1,v5) & min(v1,v6)>min(v3,v4) & min(v3,v5)<min(v2,v6)),
+					elements(3*(i-1)+1,:) = [v1 v3 v4 v5];
+					elements(3*(i-1)+2,:) = [v1 v2 v3 v5];
+					elements(3*(i-1)+3,:) = [v3 v4 v5 v6];
+				elseif(min(v2,v4)>min(v1,v5) & min(v1,v6)<min(v3,v4) & min(v3,v5)<min(v2,v6)),
+					%NEW
+					elements(3*(i-1)+1,:) = [v1 v5 v6 v4];
+					elements(3*(i-1)+2,:) = [v1 v2 v3 v5];
+					elements(3*(i-1)+3,:) = [v5 v6 v3 v1];
+				elseif(min(v2,v4)>min(v1,v5) & min(v1,v6)>min(v3,v4) & min(v3,v5)>min(v2,v6)),
+					steiner = steiner+1; nbv = nbv+1; nbt = nbt+5; v7 = nbv;
+					md.mesh.x=[md.mesh.x; mean(md.mesh.x(md.mesh.elements(i,:)))];
+					md.mesh.y=[md.mesh.y; mean(md.mesh.y(md.mesh.elements(i,:)))];
+					md.mesh.z=[md.mesh.z; mean(md.mesh.z(md.mesh.elements(i,:)))];
+					elements(3*(i-1)+1,:) = [v1 v2 v3 v7];
+					elements(3*(i-1)+2,:) = [v1 v4 v5 v7];
+					elements(3*(i-1)+3,:) = [v1 v2 v5 v7];
+					elements(end+1,:) = [v2 v5 v6 v7];
+					elements(end+1,:) = [v2 v3 v6 v7];
+					elements(end+1,:) = [v3 v4 v6 v7];
+					elements(end+1,:) = [v1 v3 v4 v7];
+					elements(end+1,:) = [v4 v5 v6 v7];
+				else
+					error('Case not supported'); %not supposed to happen!
+				end
+				%Reorder elements to make sure they are direct
+				for j=1:3
+					element = elements(3*(i-1)+j,:);
+					matrix = [md.mesh.x(element), md.mesh.y(element), md.mesh.z(element), ones(4,1)];
+					if det(matrix)>0,
+						elements(3*(i-1)+j,1)=element(2);
+						elements(3*(i-1)+j,2)=element(1);
+					end
+				end
+			end
+			%%Split in 3 tetras
+			%subelement1 = [1 2 3 5];
+			%subelement2 = [4 6 5 1];
+			%subelement3 = [5 6 3 1];
+			%elements=[md.mesh.elements(:,subelement1);md.mesh.elements(:,subelement2);md.mesh.elements(:,subelement3)];
+			if steiner==0,
+				disp('No Steiner point required to split prismatic mesh into tets');
+			else
+				disp([num2str(steiner) ' Steiner points had to be included'])
+				error('Steiner point not supported yet');
+			end
+
+			pos_elements = repmat([1:md.mesh.numberofelements]',3,1);
+
+			md.mesh.elements=elements;
+			md.mesh.numberofelements=size(elements,1);
+
+			%p and q (same deal, except for element that are on the bedrock: )
+			if ~isnan(md.friction.p),
+				md.friction.p=md.friction.p(pos_elements);
+				md.friction.q=md.friction.q(pos_elements);
+			end
+
+			%elementstype
+			if ~isnan(md.flowequation.element_equation)
+				oldelements_type=md.flowequation.element_equation;
+				md.flowequation.element_equation=md.flowequation.element_equation(pos_elements);
+			end
+
+			%connectivity
+			md.mesh.elementconnectivity=NaN;
+
+			%materials
+			if ~isnan(md.materials.rheology_n),
+				md.materials.rheology_n=md.materials.rheology_n(pos_elements);
+			end
+
+			%increase connectivity if less than 25:
+			if md.mesh.average_vertex_connectivity<=25,
+				md.mesh.average_vertex_connectivity=100;
+			end
+		end % }}}
 		function disp(obj) % {{{
 			disp(sprintf('%19s: %-22s -- %s','mesh'            ,['[1x1 ' class(obj.mesh) ']'],'mesh properties'));
@@ -1099,5 +1270,5 @@
 			disp(sprintf('%19s: %-22s -- %s','basalforcings'   ,['[1x1 ' class(obj.basalforcings) ']'],'bed forcings'));
 			disp(sprintf('%19s: %-22s -- %s','materials'       ,['[1x1 ' class(obj.materials) ']'],'material properties'));
-			disp(sprintf('%19s: %-22s -- %s','damage'          ,['[1x1 ' class(obj.damage) ']'],'damage propagation laws'));
+			disp(sprintf('%19s: %-22s -- %s','damage'          ,['[1x1 ' class(obj.damage) ']'],'parameters for damage evolution solution'));
 			disp(sprintf('%19s: %-22s -- %s','friction'        ,['[1x1 ' class(obj.friction) ']'],'basal friction/drag properties'));
 			disp(sprintf('%19s: %-22s -- %s','flowequation'    ,['[1x1 ' class(obj.flowequation) ']'],'flow equations'));
Index: /issm/trunk/src/m/classes/model.py
===================================================================
--- /issm/trunk/src/m/classes/model.py	(revision 17805)
+++ /issm/trunk/src/m/classes/model.py	(revision 17806)
@@ -3,9 +3,12 @@
 import copy
 import sys
-from mesh import mesh
+from mesh2d import mesh2d
+from mesh3dprisms import mesh3dprisms
 from mask import mask
 from geometry import geometry
 from constants import constants
-from surfaceforcings import surfaceforcings
+from SMB import SMB
+from SMBpdd import SMBpdd
+from SMBgradients import SMBgradients
 from basalforcings import basalforcings
 from matice import matice
@@ -39,13 +42,14 @@
 from miscellaneous import miscellaneous
 from private import private
-from EnumDefinitions import *
-from mumpsoptions import *
-from iluasmoptions import *
-from project3d import *
-from FlagElements import *
-from NodeConnectivity import *
-from ElementConnectivity import *
-from contourenvelope import *
-from PythonFuncs import *
+from mumpsoptions import mumpsoptions
+from iluasmoptions import iluasmoptions
+from project3d import project3d
+from project2d import project2d
+from FlagElements import FlagElements
+from NodeConnectivity import NodeConnectivity
+from ElementConnectivity import ElementConnectivity
+from contourenvelope import contourenvelope
+import MatlabFuncs as m
+from DepthAverage import DepthAverage
 #}}}
 
@@ -53,9 +57,9 @@
 	#properties
 	def __init__(self):#{{{
-		self.mesh             = mesh()
+		self.mesh             = mesh2d()
 		self.mask             = mask()
 		self.geometry         = geometry()
 		self.constants        = constants()
-		self.surfaceforcings  = surfaceforcings()
+		self.surfaceforcings  = SMB()
 		self.basalforcings    = basalforcings()
 		self.materials        = matice()
@@ -172,5 +176,5 @@
 	# }}}
 	def checkmessage(self,string):    # {{{
-		print ("model not consistent: %s" % string)
+		print "model not consistent: ", string
 		self.private.isconsistent=False
 		return self
@@ -184,13 +188,13 @@
 		   It can either be a domain file (argus type, .exp extension), or an array of element flags. 
 		   If user wants every element outside the domain to be 
-		   extract2d, add '~' to the name of the domain file (ex: '~HO.exp');
+		   extract2d, add '~' to the name of the domain file (ex: '~HO.exp')
 		   an empty string '' will be considered as an empty domain
 		   a string 'all' will be considered as the entire domain
 
 		   Usage:
-		      md2=extract(md,area);
+		      md2=extract(md,area)
 
 		   Examples:
-		      md2=extract(md,'Domain.exp');
+		      md2=extract(md,'Domain.exp')
 
 		   See also: EXTRUDE, COLLAPSE
@@ -237,5 +241,5 @@
 		elements_2[:,1]=Pnode[elements_2[:,1]-1]
 		elements_2[:,2]=Pnode[elements_2[:,2]-1]
-		if md1.mesh.dimension==3:
+		if md1.mesh.__class__.__name__=='mesh3dprisms':
 			elements_2[:,3]=Pnode[elements_2[:,3]-1]
 			elements_2[:,4]=Pnode[elements_2[:,4]-1]
@@ -255,5 +259,5 @@
 			field=getattr(md1,fieldi)
 			fieldsize=numpy.shape(field)
-			if hasattr(field,'__dict__') and not ismember(fieldi,['results'])[0]:    #recursive call
+			if hasattr(field,'__dict__') and not m.ismember(fieldi,['results'])[0]:    #recursive call
 				object_fields=vars(field)
 				for fieldj in object_fields:
@@ -289,5 +293,5 @@
 
 		#mesh.uppervertex mesh.lowervertex
-		if md1.mesh.dimension==3:
+		if md1.mesh.__class__.__name__=='mesh3dprisms':
 			md2.mesh.uppervertex=md1.mesh.uppervertex[pos_node]
 			pos=numpy.nonzero(numpy.logical_not(md2.mesh.uppervertex==-1))[0]
@@ -307,5 +311,5 @@
 
 		#Initial 2d mesh 
-		if md1.mesh.dimension==3:
+		if md1.mesh.__class__.__name__=='mesh3dprisms':
 			flag_elem_2d=flag_elem[numpy.arange(0,md1.mesh.numberofelements2d)]
 			pos_elem_2d=numpy.nonzero(flag_elem_2d)[0]
@@ -324,28 +328,29 @@
 
 		#Edges
-		if numpy.ndim(md2.mesh.edges)>1 and numpy.size(md2.mesh.edges,axis=1)>1:    #do not use ~isnan because there are some NaNs...
-			#renumber first two columns
-			pos=numpy.nonzero(md2.mesh.edges[:,3]!=-1)[0]
-			md2.mesh.edges[:  ,0]=Pnode[md2.mesh.edges[:,0]-1]
-			md2.mesh.edges[:  ,1]=Pnode[md2.mesh.edges[:,1]-1]
-			md2.mesh.edges[:  ,2]=Pelem[md2.mesh.edges[:,2]-1]
-			md2.mesh.edges[pos,3]=Pelem[md2.mesh.edges[pos,3]-1]
-			#remove edges when the 2 vertices are not in the domain.
-			md2.mesh.edges=md2.mesh.edges[numpy.nonzero(numpy.logical_and(md2.mesh.edges[:,0],md2.mesh.edges[:,1]))[0],:]
-			#Replace all zeros by -1 in the last two columns
-			pos=numpy.nonzero(md2.mesh.edges[:,2]==0)[0]
-			md2.mesh.edges[pos,2]=-1
-			pos=numpy.nonzero(md2.mesh.edges[:,3]==0)[0]
-			md2.mesh.edges[pos,3]=-1
-			#Invert -1 on the third column with last column (Also invert first two columns!!)
-			pos=numpy.nonzero(md2.mesh.edges[:,2]==-1)[0]
-			md2.mesh.edges[pos,2]=md2.mesh.edges[pos,3]
-			md2.mesh.edges[pos,3]=-1
-			values=md2.mesh.edges[pos,1]
-			md2.mesh.edges[pos,1]=md2.mesh.edges[pos,0]
-			md2.mesh.edges[pos,0]=values
-			#Finally remove edges that do not belong to any element
-			pos=numpy.nonzero(numpy.logical_and(md2.mesh.edges[:,1]==-1,md2.mesh.edges[:,2]==-1))[0]
-			md2.mesh.edges=numpy.delete(md2.mesh.edges,pos,axis=0)
+		if m.strcmp(md.mesh.domaintype(),'2Dhorizontal'):
+			if numpy.ndim(md2.mesh.edges)>1 and numpy.size(md2.mesh.edges,axis=1)>1:    #do not use ~isnan because there are some numpy.nans...
+				#renumber first two columns
+				pos=numpy.nonzero(md2.mesh.edges[:,3]!=-1)[0]
+				md2.mesh.edges[:  ,0]=Pnode[md2.mesh.edges[:,0]-1]
+				md2.mesh.edges[:  ,1]=Pnode[md2.mesh.edges[:,1]-1]
+				md2.mesh.edges[:  ,2]=Pelem[md2.mesh.edges[:,2]-1]
+				md2.mesh.edges[pos,3]=Pelem[md2.mesh.edges[pos,3]-1]
+				#remove edges when the 2 vertices are not in the domain.
+				md2.mesh.edges=md2.mesh.edges[numpy.nonzero(numpy.logical_and(md2.mesh.edges[:,0],md2.mesh.edges[:,1]))[0],:]
+				#Replace all zeros by -1 in the last two columns
+				pos=numpy.nonzero(md2.mesh.edges[:,2]==0)[0]
+				md2.mesh.edges[pos,2]=-1
+				pos=numpy.nonzero(md2.mesh.edges[:,3]==0)[0]
+				md2.mesh.edges[pos,3]=-1
+				#Invert -1 on the third column with last column (Also invert first two columns!!)
+				pos=numpy.nonzero(md2.mesh.edges[:,2]==-1)[0]
+				md2.mesh.edges[pos,2]=md2.mesh.edges[pos,3]
+				md2.mesh.edges[pos,3]=-1
+				values=md2.mesh.edges[pos,1]
+				md2.mesh.edges[pos,1]=md2.mesh.edges[pos,0]
+				md2.mesh.edges[pos,0]=values
+				#Finally remove edges that do not belong to any element
+				pos=numpy.nonzero(numpy.logical_and(md2.mesh.edges[:,1]==-1,md2.mesh.edges[:,2]==-1))[0]
+				md2.mesh.edges=numpy.delete(md2.mesh.edges,pos,axis=0)
 
 		#Penalties
@@ -360,5 +365,5 @@
 
 		#recreate segments
-		if md1.mesh.dimension==2:
+		if md1.mesh.__class__.__name__=='mesh2d':
 			[md2.mesh.vertexconnectivity]=NodeConnectivity(md2.mesh.elements,md2.mesh.numberofvertices)
 			[md2.mesh.elementconnectivity]=ElementConnectivity(md2.mesh.elements,md2.mesh.vertexconnectivity)
@@ -370,7 +375,7 @@
 			[md2.mesh.vertexconnectivity]=NodeConnectivity(md2.mesh.elements2d,md2.mesh.numberofvertices2d)
 			[md2.mesh.elementconnectivity]=ElementConnectivity(md2.mesh.elements2d,md2.mesh.vertexconnectivity)
-			md2.mesh.segments=contourenvelope(md2)
+			segments=contourenvelope(md2)
 			md2.mesh.vertexonboundary=numpy.zeros(numberofvertices2/md2.mesh.numberoflayers,bool)
-			md2.mesh.vertexonboundary[md2.mesh.segments[:,0:2]-1]=True
+			md2.mesh.vertexonboundary[segments[:,0:2]-1]=True
 			md2.mesh.vertexonboundary=numpy.tile(md2.mesh.vertexonboundary,md2.mesh.numberoflayers)
 			#Then do it for 3d as usual
@@ -390,6 +395,6 @@
 				md2.stressbalance.spcvy[nodestoflag2]=md2.inversion.vy_obs[nodestoflag2]
 			else:
-				md2.stressbalance.spcvx[nodestoflag2]=float('NaN')
-				md2.stressbalance.spcvy[nodestoflag2]=float('NaN')
+				md2.stressbalance.spcvx[nodestoflag2]=numpy.nan
+				md2.stressbalance.spcvy[nodestoflag2]=numpy.nan
 				print "\n!! extract warning: spc values should be checked !!\n\n"
 			#put 0 for vz
@@ -450,12 +455,12 @@
 
 		   Usage:
-		      md=extrude(md,numlayers,extrusionexponent);
-		      md=extrude(md,numlayers,lowerexponent,upperexponent);
-		      md=extrude(md,listofcoefficients);
+		      md=extrude(md,numlayers,extrusionexponent)
+		      md=extrude(md,numlayers,lowerexponent,upperexponent)
+		      md=extrude(md,listofcoefficients)
 
 		   Example:
-		      md=extrude(md,8,3);
-		      md=extrude(md,8,3,2);
-		      md=extrude(md,[0 0.2 0.5 0.7 0.9 0.95 1]);
+		      md=extrude(md,8,3)
+		      md=extrude(md,8,3,2)
+		      md=extrude(md,[0 0.2 0.5 0.7 0.9 0.95 1])
 
 		   See also: MODELEXTRACT, COLLAPSE
@@ -496,13 +501,33 @@
 		if numlayers<2:
 			raise TypeError("number of layers should be at least 2")
-		if md.mesh.dimension==3:
+		if md.mesh.__class__.__name__=='mesh3dprisms':
 			raise TypeError("Cannot extrude a 3d mesh (extrude cannot be called more than once)")
 
 		#Initialize with the 2d mesh
+		mesh2d = md.mesh
+		md.mesh=mesh3dprisms()
+		md.mesh.x                           = mesh2d.x
+		md.mesh.y                           = mesh2d.y
+		md.mesh.elements                    = mesh2d.elements
+		md.mesh.numberofelements            = mesh2d.numberofelements
+		md.mesh.numberofvertices            = mesh2d.numberofvertices
+
+		md.mesh.lat                         = mesh2d.lat
+		md.mesh.long                        = mesh2d.long
+		md.mesh.hemisphere                  = mesh2d.hemisphere
+
+		md.mesh.vertexonboundary            = mesh2d.vertexonboundary
+		md.mesh.vertexconnectivity          = mesh2d.vertexconnectivity
+		md.mesh.elementconnectivity         = mesh2d.elementconnectivity
+		md.mesh.average_vertex_connectivity = mesh2d.average_vertex_connectivity
+
+		md.mesh.extractedvertices           = mesh2d.extractedvertices
+		md.mesh.extractedelements           = mesh2d.extractedelements
+
 		x3d=numpy.empty((0))
 		y3d=numpy.empty((0))
 		z3d=numpy.empty((0))    #the lower node is on the bed
 		thickness3d=md.geometry.thickness    #thickness and bed for these nodes
-		bed3d=md.geometry.bed
+		bed3d=md.geometry.base
 
 		#Create the new layers
@@ -521,18 +546,18 @@
 
 		#Keep a trace of lower and upper nodes
-		mesh.lowervertex=-1*numpy.ones(number_nodes3d,int)
-		mesh.uppervertex=-1*numpy.ones(number_nodes3d,int)
-		mesh.lowervertex[md.mesh.numberofvertices:]=numpy.arange(1,(numlayers-1)*md.mesh.numberofvertices+1)
-		mesh.uppervertex[:(numlayers-1)*md.mesh.numberofvertices]=numpy.arange(md.mesh.numberofvertices+1,number_nodes3d+1)
-		md.mesh.lowervertex=mesh.lowervertex
-		md.mesh.uppervertex=mesh.uppervertex
+		lowervertex=-1*numpy.ones(number_nodes3d,int)
+		uppervertex=-1*numpy.ones(number_nodes3d,int)
+		lowervertex[md.mesh.numberofvertices:]=numpy.arange(1,(numlayers-1)*md.mesh.numberofvertices+1)
+		uppervertex[:(numlayers-1)*md.mesh.numberofvertices]=numpy.arange(md.mesh.numberofvertices+1,number_nodes3d+1)
+		md.mesh.lowervertex=lowervertex
+		md.mesh.uppervertex=uppervertex
 
 		#same for lower and upper elements
-		mesh.lowerelements=-1*numpy.ones(number_el3d,int)
-		mesh.upperelements=-1*numpy.ones(number_el3d,int)
-		mesh.lowerelements[md.mesh.numberofelements:]=numpy.arange(1,(numlayers-2)*md.mesh.numberofelements+1)
-		mesh.upperelements[:(numlayers-2)*md.mesh.numberofelements]=numpy.arange(md.mesh.numberofelements+1,(numlayers-1)*md.mesh.numberofelements+1)
-		md.mesh.lowerelements=mesh.lowerelements
-		md.mesh.upperelements=mesh.upperelements
+		lowerelements=-1*numpy.ones(number_el3d,int)
+		upperelements=-1*numpy.ones(number_el3d,int)
+		lowerelements[md.mesh.numberofelements:]=numpy.arange(1,(numlayers-2)*md.mesh.numberofelements+1)
+		upperelements[:(numlayers-2)*md.mesh.numberofelements]=numpy.arange(md.mesh.numberofelements+1,(numlayers-1)*md.mesh.numberofelements+1)
+		md.mesh.lowerelements=lowerelements
+		md.mesh.upperelements=upperelements
 
 		#Save old mesh 
@@ -542,7 +567,4 @@
 		md.mesh.numberofelements2d=md.mesh.numberofelements
 		md.mesh.numberofvertices2d=md.mesh.numberofvertices
-
-		#Update mesh type
-		md.mesh.dimension=3
 
 		#Build global 3d mesh 
@@ -572,8 +594,7 @@
 		md.inversion.vy_obs=project3d(md,'vector',md.inversion.vy_obs,'type','node')
 		md.inversion.vel_obs=project3d(md,'vector',md.inversion.vel_obs,'type','node')
-		md.surfaceforcings.mass_balance=project3d(md,'vector',md.surfaceforcings.mass_balance,'type','node')
-		md.surfaceforcings.precipitation=project3d(md,'vector',md.surfaceforcings.precipitation,'type','node')
+		md.inversion.thickness_obs=project3d(md,'vector',md.inversion.thickness_obs,'type','node')
+		md.surfaceforcings.extrude(md)
 		md.balancethickness.thickening_rate=project3d(md,'vector',md.balancethickness.thickening_rate,'type','node')
-		md.surfaceforcings.monthlytemperatures=project3d(md,'vector',md.surfaceforcings.monthlytemperatures,'type','node')
 
 		#results
@@ -590,9 +611,12 @@
 		if not numpy.any(numpy.isnan(md.initialization.waterfraction)):
 			md.initialization.waterfraction=project3d(md,'vector',md.initialization.waterfraction,'type','node')
+		if not numpy.any(numpy.isnan(md.initialization.watercolumn)):
+			md.initialization.watercolumn=project3d(md,'vector',md.initialization.watercolumn,'type','node')
+
 
 		#bedinfo and surface info
-		md.mesh.elementonbed=project3d(md,'vector',numpy.ones(md.mesh.numberofelements2d,bool),'type','element','layer',1)
+		md.mesh.elementonbase=project3d(md,'vector',numpy.ones(md.mesh.numberofelements2d,bool),'type','element','layer',1)
 		md.mesh.elementonsurface=project3d(md,'vector',numpy.ones(md.mesh.numberofelements2d,bool),'type','element','layer',md.mesh.numberoflayers-1)
-		md.mesh.vertexonbed=project3d(md,'vector',numpy.ones(md.mesh.numberofvertices2d,bool),'type','node','layer',1)
+		md.mesh.vertexonbase=project3d(md,'vector',numpy.ones(md.mesh.numberofvertices2d,bool),'type','node','layer',1)
 		md.mesh.vertexonsurface=project3d(md,'vector',numpy.ones(md.mesh.numberofvertices2d,bool),'type','node','layer',md.mesh.numberoflayers)
 
@@ -617,5 +641,10 @@
 		md.stressbalance.spcvy=project3d(md,'vector',md.stressbalance.spcvy,'type','node')
 		md.stressbalance.spcvz=project3d(md,'vector',md.stressbalance.spcvz,'type','node')
-		md.thermal.spctemperature=project3d(md,'vector',md.thermal.spctemperature,'type','node','layer',md.mesh.numberoflayers,'padding',float('NaN'))
+		md.thermal.spctemperature=project3d(md,'vector',md.thermal.spctemperature,'type','node','layer',md.mesh.numberoflayers,'padding',numpy.nan)
+		if isinstance(md.initialization.temperature,numpy.ndarray) and numpy.size(md.initialization.temperature,axis=0)==md.mesh.numberofvertices:
+			md.thermal.spctemperature=numpy.nan*numpy.ones((md.mesh.numberofvertices,1))
+			if hasattr(md.mesh,'vertexonsurface'):
+				pos=numpy.nonzero(md.mesh.vertexonsurface)[0]
+				md.thermal.spctemperature[pos]=md.initialization.temperature[pos]    #impose observed temperature on surface
 		md.masstransport.spcthickness=project3d(md,'vector',md.masstransport.spcthickness,'type','node')
 		md.balancethickness.spcthickness=project3d(md,'vector',md.balancethickness.spcthickness,'type','node')
@@ -623,4 +652,5 @@
 		md.stressbalance.referential=project3d(md,'vector',md.stressbalance.referential,'type','node')
 		md.stressbalance.loadingforce=project3d(md,'vector',md.stressbalance.loadingforce,'type','node')
+		md.masstransport.calvingrate=project3d(md,'vector',md.masstransport.calvingrate,'type','node')
 
 		#connectivity
@@ -645,11 +675,11 @@
 		md.gia.lithosphere_thickness=project3d(md,'vector',md.gia.lithosphere_thickness,'type','node')
 		md.geometry.hydrostatic_ratio=project3d(md,'vector',md.geometry.hydrostatic_ratio,'type','node')
+		md.geometry.base=project3d(md,'vector',md.geometry.base,'type','node')
 		md.geometry.bed=project3d(md,'vector',md.geometry.bed,'type','node')
-		md.geometry.bathymetry=project3d(md,'vector',md.geometry.bathymetry,'type','node')
 		md.mesh.vertexonboundary=project3d(md,'vector',md.mesh.vertexonboundary,'type','node')
 		md.mask.ice_levelset=project3d(md,'vector',md.mask.ice_levelset,'type','node')
 		md.mask.groundedice_levelset=project3d(md,'vector',md.mask.groundedice_levelset,'type','node')
 		if not numpy.any(numpy.isnan(md.inversion.cost_functions_coefficients)):
-			md.inversion.cost_functions_coefficients=project3d(md,'vector',md.inversion.cost_functions_coefficients,'type','node');end;
+			md.inversion.cost_functions_coefficients=project3d(md,'vector',md.inversion.cost_functions_coefficients,'type','node')
 		if not numpy.any(numpy.isnan(md.inversion.min_parameters)):
 			md.inversion.min_parameters=project3d(md,'vector',md.inversion.min_parameters,'type','node')
@@ -658,10 +688,4 @@
 		if not numpy.any(numpy.isnan(md.qmu.partition)):
 			md.qmu.partition=project3d(md,'vector',numpy.transpose(md.qmu.partition),'type','node')
-		if(md.surfaceforcings.isdelta18o):
-			md.surfaceforcings.temperatures_lgm=project3d(md,'vector',md.surfaceforcings.temperatures_lgm,'type','node')
-		if(md.surfaceforcings.isdelta18o):
-			md.surfaceforcings.temperatures_presentday=project3d(md,'vector',md.surfaceforcings.temperatures_presentday,'type','node')
-		if(md.surfaceforcings.isdelta18o):
-			md.surfaceforcings.precipitations_presentday=project3d(md,'vector',md.surfaceforcings.precipitations_presentday,'type','node')
 
 		#Put lithostatic pressure if there is an existing pressure
@@ -680,2 +704,124 @@
 		return md
 		# }}}
+	def collapse(md): #{{{
+		'''
+		collapses a 3d mesh into a 2d mesh
+			
+		This routine collapses a 3d model into a 2d model and collapses all
+		the fileds of the 3d model by taking their depth-averaged values
+			
+		Usage:
+			md=collapse(md)
+		'''	
+
+		#Check that the model is really a 3d model
+		if md.mesh.domaintype().lower() != '3d':
+			raise StandardError("only a 3D model can be collapsed")
+		
+		#drag is limited to nodes that are on the bedrock.
+		md.friction.coefficient=project2d(md,md.friction.coefficient,1)
+
+		#p and q (same deal, except for element that are on the bedrock: )
+		md.friction.p=project2d(md,md.friction.p,1)
+		md.friction.q=project2d(md,md.friction.q,1)
+
+		#observations
+		if not numpy.isnan(md.inversion.vx_obs).all(): md.inversion.vx_obs=project2d(md,md.inversion.vx_obs,md.mesh.numberoflayers) 
+		if not numpy.isnan(md.inversion.vy_obs).all(): md.inversion.vy_obs=project2d(md,md.inversion.vy_obs,md.mesh.numberoflayers) 
+		if not numpy.isnan(md.inversion.vel_obs).all(): md.inversion.vel_obs=project2d(md,md.inversion.vel_obs,md.mesh.numberoflayers) 
+		if not numpy.isnan(md.inversion.cost_functions_coefficients).all(): md.inversion.cost_functions_coefficients=project2d(md,md.inversion.cost_functions_coefficients,md.mesh.numberoflayers) 
+		if md.inversion.min_parameters.size>1: md.inversion.min_parameters=project2d(md,md.inversion.min_parameters,md.mesh.numberoflayers) 
+		if md.inversion.max_parameters.size>1: md.inversion.max_parameters=project2d(md,md.inversion.max_parameters,md.mesh.numberoflayers) 
+		if not numpy.isnan(md.surfaceforcings.mass_balance).all():
+			md.surfaceforcings.mass_balance=project2d(md,md.surfaceforcings.mass_balance,md.mesh.numberoflayers) 
+		
+		if not numpy.isnan(md.balancethickness.thickening_rate).all(): md.balancethickness.thickening_rate=project2d(md,md.balancethickness.thickening_rate,md.mesh.numberoflayers) 
+
+		#results
+		if not numpy.isnan(md.initialization.vx).all(): md.initialization.vx=DepthAverage(md,md.initialization.vx)
+		if not numpy.isnan(md.initialization.vy).all(): md.initialization.vy=DepthAverage(md,md.initialization.vy)
+		if not numpy.isnan(md.initialization.vz).all(): md.initialization.vz=DepthAverage(md,md.initialization.vz)
+		if not numpy.isnan(md.initialization.vel).all(): md.initialization.vel=DepthAverage(md,md.initialization.vel)
+		if not numpy.isnan(md.initialization.temperature).all(): md.initialization.temperature=DepthAverage(md,md.initialization.temperature)
+
+		#gia
+		if not numpy.isnan(md.gia.mantle_viscosity).all(): md.gia.mantle_viscosity=project2d(md,md.gia.mantle_viscosity,1) 
+		if not numpy.isnan(md.gia.lithosphere_thickness).all(): md.gia.lithosphere_thickness=project2d(md,md.gia.lithosphere_thickness,1) 
+
+		#elementstype
+		if not numpy.isnan(md.flowequation.element_equation).all():
+			md.flowequation.element_equation=project2d(md,md.flowequation.element_equation,1)
+			md.flowequation.vertex_equation=project2d(md,md.flowequation.vertex_equation,1)
+			md.flowequation.borderSSA=project2d(md,md.flowequation.borderSSA,1)
+			md.flowequation.borderHO=project2d(md,md.flowequation.borderHO,1)
+			md.flowequation.borderFS=project2d(md,md.flowequation.borderFS,1)
+
+		#boundary conditions
+		md.stressbalance.spcvx=project2d(md,md.stressbalance.spcvx,md.mesh.numberoflayers)
+		md.stressbalance.spcvy=project2d(md,md.stressbalance.spcvy,md.mesh.numberoflayers)
+		md.stressbalance.spcvz=project2d(md,md.stressbalance.spcvz,md.mesh.numberoflayers)
+		md.stressbalance.referential=project2d(md,md.stressbalance.referential,md.mesh.numberoflayers)
+		md.stressbalance.loadingforce=project2d(md,md.stressbalance.loadingforce,md.mesh.numberoflayers)
+		md.masstransport.spcthickness=project2d(md,md.masstransport.spcthickness,md.mesh.numberoflayers)
+		md.damage.spcdamage=project2d(md,md.damage.spcdamage,md.mesh.numberoflayers-1)
+		md.thermal.spctemperature=project2d(md,md.thermal.spctemperature,md.mesh.numberoflayers-1)
+
+		#materials
+		md.materials.rheology_B=DepthAverage(md,md.materials.rheology_B)
+		md.materials.rheology_n=project2d(md,md.materials.rheology_n,1)
+		
+		#damage: 
+		md.damage.D=DepthAverage(md,md.damage.D)
+
+		#special for thermal modeling:
+		md.basalforcings.melting_rate=project2d(md,md.basalforcings.melting_rate,1) 
+		md.basalforcings.geothermalflux=project2d(md,md.basalforcings.geothermalflux,1) #bedrock only gets geothermal flux
+
+		#update of connectivity matrix
+		md.mesh.average_vertex_connectivity=25
+
+		#Collapse the mesh
+		nodes2d=md.mesh.numberofvertices2d
+		elements2d=md.mesh.numberofelements2d
+
+		#parameters
+		md.geometry.surface=project2d(md,md.geometry.surface,1)
+		md.geometry.thickness=project2d(md,md.geometry.thickness,1)
+		md.geometry.base=project2d(md,md.geometry.base,1)
+		md.geometry.bed=project2d(md,md.geometry.bed,1)
+		md.mesh.vertexonboundary=project2d(md,md.mesh.vertexonboundary,1)
+		md.mesh.elementconnectivity=project2d(md,md.mesh.elementconnectivity,1)
+		md.mask.groundedice_levelset=project2d(md,md.mask.groundedice_levelset,1)
+		md.mask.ice_levelset=project2d(md,md.mask.ice_levelset,1)
+
+		#lat long
+		if md.mesh.lat.size==md.mesh.numberofvertices:  md.mesh.lat=project2d(md,md.mesh.lat,1) 
+		if md.mesh.long.size==md.mesh.numberofvertices: md.mesh.long=project2d(md,md.mesh.long,1) 
+
+		#Initialize with the 2d mesh
+		mesh=mesh2d()
+		mesh.x=md.mesh.x2d
+		mesh.y=md.mesh.y2d
+		mesh.z=numpy.zeros_like(md.mesh.x2d)
+		mesh.numberofvertices=md.mesh.numberofvertices2d
+		mesh.numberofelements=md.mesh.numberofelements2d
+		mesh.elements=md.mesh.elements2d
+		md.mesh=mesh
+
+		#Keep a trace of lower and upper nodes
+		md.mesh.lowervertex=numpy.nan
+		md.mesh.uppervertex=numpy.nan
+		md.mesh.lowerelements=numpy.nan
+		md.mesh.upperelements=numpy.nan
+
+		#Remove old mesh 
+		md.mesh.x2d=numpy.nan
+		md.mesh.y2d=numpy.nan
+		md.mesh.elements2d=numpy.nan
+		md.mesh.numberofelements2d=md.mesh.numberofelements
+		md.mesh.numberofvertices2d=md.mesh.numberofvertices
+		md.mesh.numberoflayers=0
+
+		return md
+
+#}}}
Index: /issm/trunk/src/m/classes/modellist.m
===================================================================
--- /issm/trunk/src/m/classes/modellist.m	(revision 17805)
+++ /issm/trunk/src/m/classes/modellist.m	(revision 17806)
@@ -32,5 +32,5 @@
 
 			%2D or 3D?
-			if md.mesh.dimension==3,
+			if dimension(md.mesh)==3,
 				numberofelements=md.mesh.numberofelements2d; %this will be forgotten when we get out.
 				flags=project2d(md,flags,1);
@@ -84,5 +84,5 @@
 			for i=1:size(flag_list,1),
 				disp(['   ' num2str(i) '/' num2str(size(flag_list,1))]);
-				if md.mesh.dimension==3,
+				if dimension(md.mesh)==3,
 					flags2d=flag_list{i};
 					realflags=project3d(md,flags2d,'element');
Index: /issm/trunk/src/m/classes/oldclasses/README
===================================================================
--- /issm/trunk/src/m/classes/oldclasses/README	(revision 17805)
+++ /issm/trunk/src/m/classes/oldclasses/README	(revision 17806)
@@ -1,3 +1,4 @@
 We put here all old classes so that matlab can still load old models
 When an object is renamed or deleted, matlab is not able to load it
-anymore. We keep it here so that matlab can load the object
+anymore. We keep it here so that matlab can load the object (just remove all
+methods)
Index: /issm/trunk/src/m/classes/oldclasses/diagnostic.m
===================================================================
--- /issm/trunk/src/m/classes/oldclasses/diagnostic.m	(revision 17805)
+++ /issm/trunk/src/m/classes/oldclasses/diagnostic.m	(revision 17806)
@@ -26,107 +26,3 @@
 		requested_outputs        = NaN;
 	end
-	methods
-		function obj = diagnostic(varargin) % {{{
-			switch nargin
-				case 0
-					obj=setdefaultparameters(obj);
-				otherwise
-					error('constructor not supported');
-			end
-		end % }}}
-		function obj = setdefaultparameters(obj) % {{{
-
-			 %maximum of non-linear iterations.
-			 obj.maxiter=100;
-
-			 %Convergence criterion: absolute, relative and residual
-			 obj.restol=10^-4; 
-			 obj.reltol=0.01;
-			 obj.abstol=10;
-
-			 obj.FSreconditioning=10^13;
-			 obj.shelf_dampening=0;
-
-			 %Penalty factor applied kappa=max(stiffness matrix)*10^penalty_factor
-			 obj.penalty_factor=3;
-
-			 %coefficient to update the viscosity between each iteration of
-			 %a diagnostic according to the following formula
-			 %viscosity(n)=viscosity(n)+viscosity_overshoot(viscosity(n)-viscosity(n-1))
-			 obj.viscosity_overshoot=0;
-
-			 %Stop the iterations of rift if below a threshold
-			 obj.rift_penalty_threshold=0;
-
-			 %in some solutions, it might be needed to stop a run when only
-			 %a few constraints remain unstable. For thermal computation, this
-			 %parameter is often used.
-			 obj.rift_penalty_lock=10;
-
-		end % }}}
-		function disp(obj) % {{{
-
-			disp(sprintf('   Stressbalance solution parameters:'));
-
-			disp(sprintf('\n      %s','Convergence criteria:'));
-			fielddisplay(obj,'restol','mechanical equilibrium residual convergence criterion');
-			fielddisplay(obj,'reltol','velocity relative convergence criterion, NaN: not applied');
-			fielddisplay(obj,'abstol','velocity absolute convergence criterion, NaN: not applied');
-			fielddisplay(obj,'isnewton','0: Picard''s fixed point, 1: Newton''s method, 2: hybrid');
-			fielddisplay(obj,'maxiter','maximum number of nonlinear iterations');
-			fielddisplay(obj,'viscosity_overshoot','over-shooting constant new=new+C*(new-old)');
-
-			disp(sprintf('\n      %s','boundary conditions:'));
-			fielddisplay(obj,'spcvx','x-axis velocity constraint (NaN means no constraint) [m/yr]');
-			fielddisplay(obj,'spcvy','y-axis velocity constraint (NaN means no constraint) [m/yr]');
-			fielddisplay(obj,'spcvz','z-axis velocity constraint (NaN means no constraint) [m/yr]');
-			fielddisplay(obj,'icefront','segments on ice front list (last column 0: Air, 1: Water, 2: Ice)');
-
-			disp(sprintf('\n      %s','Rift options:'));
-			fielddisplay(obj,'rift_penalty_threshold','threshold for instability of mechanical constraints');
-			fielddisplay(obj,'rift_penalty_lock','number of iterations before rift penalties are locked');
-
-			disp(sprintf('\n      %s','Penalty options:'));
-			fielddisplay(obj,'penalty_factor','offset used by penalties: penalty = Kmax*10^offset');
-			fielddisplay(obj,'vertex_pairing','pairs of vertices that are penalized');
-
-			disp(sprintf('\n      %s','Other:'));
-			fielddisplay(obj,'shelf_dampening','use dampening for floating ice ? Only for FS model');
-			fielddisplay(obj,'FSreconditioning','multiplier for incompressibility equation. Only for FS model');
-			fielddisplay(obj,'referential','local referential');
-			fielddisplay(obj,'loadingforce','loading force applied on each point [N/m^3]');
-			fielddisplay(obj,'requested_outputs','additional outputs requested');
-
-		end % }}}
-
-		function marshall(obj,md,fid) % {{{
-			WriteData(fid,'object',obj,'fieldname','spcvx','format','DoubleMat','mattype',1,'forcinglength',md.mesh.numberofvertices+1);
-			WriteData(fid,'object',obj,'fieldname','spcvy','format','DoubleMat','mattype',1,'forcinglength',md.mesh.numberofvertices+1);
-			WriteData(fid,'object',obj,'fieldname','spcvz','format','DoubleMat','mattype',1,'forcinglength',md.mesh.numberofvertices+1);
-			WriteData(fid,'object',obj,'fieldname','restol','format','Double');
-			WriteData(fid,'object',obj,'fieldname','reltol','format','Double');
-			WriteData(fid,'object',obj,'fieldname','abstol','format','Double');
-			WriteData(fid,'object',obj,'fieldname','isnewton','format','Integer');
-			WriteData(fid,'object',obj,'fieldname','FSreconditioning','format','Double');
-			WriteData(fid,'object',obj,'fieldname','viscosity_overshoot','format','Double');
-			WriteData(fid,'object',obj,'fieldname','maxiter','format','Integer');
-			WriteData(fid,'object',obj,'fieldname','shelf_dampening','format','Integer');
-			WriteData(fid,'object',obj,'fieldname','vertex_pairing','format','DoubleMat','mattype',3);
-			WriteData(fid,'object',obj,'fieldname','penalty_factor','format','Double');
-			WriteData(fid,'object',obj,'fieldname','rift_penalty_lock','format','Integer');
-			WriteData(fid,'object',obj,'fieldname','rift_penalty_threshold','format','Integer');
-			WriteData(fid,'object',obj,'fieldname','referential','format','DoubleMat','mattype',1);
-			WriteData(fid,'data',obj.loadingforce(:,1),'format','DoubleMat','mattype',1,'enum',LoadingforceXEnum);
-			WriteData(fid,'data',obj.loadingforce(:,2),'format','DoubleMat','mattype',1,'enum',LoadingforceYEnum);
-			WriteData(fid,'data',obj.loadingforce(:,3),'format','DoubleMat','mattype',1,'enum',LoadingforceZEnum);
-			WriteData(fid,'object',obj,'fieldname','requested_outputs','format','DoubleMat','mattype',3);
-
-			%marshall ice front
-			data=obj.icefront;
-			pos=find(data(:,end)==0); data(pos,end)=AirEnum();
-			pos=find(data(:,end)==1); data(pos,end)=WaterEnum();
-			pos=find(data(:,end)==2); data(pos,end)=IceEnum();
-			WriteData(fid,'data',data,'enum',StressbalanceIcefrontEnum(),'format','DoubleMat','mattype',3);
-		end % }}}
-	end
 end
Index: /issm/trunk/src/m/classes/oldclasses/hydrology.m
===================================================================
--- /issm/trunk/src/m/classes/oldclasses/hydrology.m	(revision 17805)
+++ /issm/trunk/src/m/classes/oldclasses/hydrology.m	(revision 17806)
@@ -14,54 +14,3 @@
 		stabilization  = 0;
 	end
-	methods
-		function obj = hydrology(varargin) % {{{
-			switch nargin
-				case 0
-					obj=setdefaultparameters(obj);
-				otherwise
-					error('constructor not supported');
-			end
-		end % }}}
-		function obj = setdefaultparameters(obj) % {{{
-
-			%Parameters from Johnson's 2002 thesis, section 3.5.4			 
-			obj.n=.02;			 
-			obj.CR=.01;
-			obj.p=2;		 
-			obj.q=1;		 
-			obj.kn=0;
-
-			%Type of stabilization to use 0:nothing 1:artificial_diffusivity
-			obj.stabilization=1;
-		end % }}}
-		function md = checkconsistency(obj,md,solution,analyses) % {{{
-
-			%Early return
-			if ~ismember(HydrologyAnalysisEnum(),analyses), return; end
-
-			md = checkfield(md,'hydrology.spcwatercolumn','forcing',1);
-			md = checkfield(md,'hydrology.stabilization','>=',0);
-		end % }}}
-		function disp(obj) % {{{
-			disp(sprintf('   hydrology solution parameters:'));
-
-			fielddisplay(obj,'spcwatercolumn','water thickness constraints (NaN means no constraint)');
-			fielddisplay(obj,'n','Manning roughness coefficient');
-			fielddisplay(obj,'CR','tortuosity parameter');
-			fielddisplay(obj,'p','dimensionless exponent in Manning velocity formula');
-			fielddisplay(obj,'q','dimensionless exponent in Manning velocity formula');
-			fielddisplay(obj,'kn','parameter in effective pressure formula');
-			fielddisplay(obj,'stabilization','artificial diffusivity (default is 1). can be more than 1 to increase diffusivity.');
-
-		end % }}}
-		function marshall(obj,md,fid) % {{{
-			WriteData(fid,'object',obj,'fieldname','spcwatercolumn','format','DoubleMat','mattype',1);
-			WriteData(fid,'object',obj,'fieldname','n','format','Double');
-			WriteData(fid,'object',obj,'fieldname','CR','format','Double');
-			WriteData(fid,'object',obj,'fieldname','p','format','Double');
-			WriteData(fid,'object',obj,'fieldname','q','format','Double');
-			WriteData(fid,'object',obj,'fieldname','kn','format','Double');
-			WriteData(fid,'object',obj,'fieldname','stabilization','format','Double');
-		end % }}}
-	end
 end
Index: /issm/trunk/src/m/classes/oldclasses/mesh.m
===================================================================
--- /issm/trunk/src/m/classes/oldclasses/mesh.m	(revision 17806)
+++ /issm/trunk/src/m/classes/oldclasses/mesh.m	(revision 17806)
@@ -0,0 +1,43 @@
+classdef mesh
+	properties (SetAccess=public) 
+		x                           = NaN;
+		y                           = NaN;
+		z                           = NaN
+		elements                    = NaN
+		dimension                   = 0;
+		numberoflayers              = 0;
+		numberofelements            = 0;
+		numberofvertices            = 0;
+		numberofedges               = 0;
+
+		lat                         = NaN
+		long                        = NaN
+		hemisphere                  = NaN
+
+		elementonbed                = NaN
+		elementonsurface            = NaN
+		vertexonbed                 = NaN
+		vertexonsurface             = NaN
+		lowerelements               = NaN
+		lowervertex                 = NaN
+		upperelements               = NaN
+		uppervertex                 = NaN
+		vertexonboundary            = NaN
+
+		edges                       = NaN
+		segments                    = NaN
+		segmentmarkers              = NaN
+		vertexconnectivity          = NaN
+		elementconnectivity         = NaN
+		average_vertex_connectivity = 0;
+
+		x2d                         = NaN
+		y2d                         = NaN
+		elements2d                  = NaN
+		numberofvertices2d          = 0;
+		numberofelements2d          = 0;
+
+		extractedvertices           = NaN
+		extractedelements           = NaN
+	end
+end
Index: /issm/trunk/src/m/classes/oldclasses/prognostic.m
===================================================================
--- /issm/trunk/src/m/classes/oldclasses/prognostic.m	(revision 17805)
+++ /issm/trunk/src/m/classes/oldclasses/prognostic.m	(revision 17806)
@@ -14,63 +14,3 @@
 		 requested_outputs      = NaN;
 	end
-	methods
-		function obj = prognostic(varargin) % {{{
-			switch nargin
-				case 0
-					obj=setdefaultparameters(obj);
-				otherwise
-					error('constructor not supported');
-			end
-		end % }}}
-		function obj = setdefaultparameters(obj) % {{{
-
-			%Type of stabilization to use 0:nothing 1:artificial_diffusivity 3:Discontinuous Galerkin
-			obj.stabilization=1;
-
-			%Factor applied to compute the penalties kappa=max(stiffness matrix)*10^penalty_factor
-			obj.penalty_factor=3;
-
-			%Minimum ice thickness that can be used
-			obj.min_thickness=1;
-
-			%Hydrostatic adjustment
-			obj.hydrostatic_adjustment='Absolute';
-		end % }}}
-		function md = checkconsistency(obj,md,solution,analyses) % {{{
-
-			%Early return
-			if ~ismember(PrognosticAnalysisEnum(),analyses) |  (solution==TransientSolutionEnum() & md.transient.isprognostic==0), return; end
-
-			md = checkfield(md,'prognostic.spcthickness','forcing',1);
-			md = checkfield(md,'prognostic.hydrostatic_adjustment','values',{'Absolute' 'Incremental'});
-			md = checkfield(md,'prognostic.stabilization','values',[0 1 2 3]);
-			md = checkfield(md,'prognostic.min_thickness','>',0);
-			if ~isempty(md.prognostic.requested_outputs),
-				md = checkfield(md,'prognostic.requested_outputs','size',[NaN 1]);
-			end
-
-		end % }}}
-		function disp(obj) % {{{
-			disp(sprintf('   Prognostic solution parameters:'));
-			fielddisplay(obj,'spcthickness','thickness constraints (NaN means no constraint) [m]');
-			fielddisplay(obj,'min_thickness','minimum ice thickness allowed [m]');
-			fielddisplay(obj,'hydrostatic_adjustment','adjustment of ice shelves surface and bed elevations: ''Incremental'' or ''Absolute'' ');
-			fielddisplay(obj,'stabilization','0: no, 1: artificial_diffusivity, 2: streamline upwinding, 3: discontinuous Galerkin');
-
-			disp(sprintf('\n      %s','Penalty options:'));
-			fielddisplay(obj,'penalty_factor','offset used by penalties: penalty = Kmax*10^offset');
-			fielddisplay(obj,'vertex_pairing','pairs of vertices that are penalized');
-			fielddisplay(obj,'requested_outputs','additional outputs requested');
-
-		end % }}}
-		function marshall(obj,md,fid) % {{{
-			WriteData(fid,'object',obj,'fieldname','spcthickness','format','DoubleMat','mattype',1,'forcinglength',md.mesh.numberofvertices+1);
-			WriteData(fid,'object',obj,'fieldname','min_thickness','format','Double');
-			WriteData(fid,'data',StringToEnum(obj.hydrostatic_adjustment),'format','Integer','enum',PrognosticHydrostaticAdjustmentEnum());
-			WriteData(fid,'object',obj,'fieldname','stabilization','format','Integer');
-			WriteData(fid,'object',obj,'fieldname','vertex_pairing','format','DoubleMat','mattype',3);
-			WriteData(fid,'object',obj,'fieldname','penalty_factor','format','Double');
-			WriteData(fid,'object',obj,'fieldname','requested_outputs','format','DoubleMat','mattype',3);
-		end % }}}
-	end
 end
Index: /issm/trunk/src/m/classes/oldclasses/surfaceforcings.m
===================================================================
--- /issm/trunk/src/m/classes/oldclasses/surfaceforcings.m	(revision 17806)
+++ /issm/trunk/src/m/classes/oldclasses/surfaceforcings.m	(revision 17806)
@@ -0,0 +1,26 @@
+%SURFACEFORCING Class definition
+%
+%   Usage:
+%      surfaceforcings=surfaceforcings();
+
+classdef surfaceforcings
+	properties (SetAccess=public) 
+		precipitation             = NaN;
+		mass_balance              = NaN;
+		ispdd                     = 0;
+		issmbgradients            = 0;
+		isdelta18o                = 0;
+		href                      = NaN;
+		smbref                    = NaN;
+		b_pos                     = NaN;
+		b_neg                     = NaN;
+		monthlytemperatures       = NaN;
+		delta18o                  = NaN;
+		delta18o_surface          = NaN;
+		temperatures_presentday   = NaN;
+		temperatures_lgm          = NaN;
+		precipitations_presentday = NaN;
+		desfac                    = 0.5;
+		s0p                       = 0;
+	end
+end
Index: /issm/trunk/src/m/classes/organizer.m
===================================================================
--- /issm/trunk/src/m/classes/organizer.m	(revision 17805)
+++ /issm/trunk/src/m/classes/organizer.m	(revision 17806)
@@ -97,12 +97,16 @@
 			%figure out if the model is there
 			if exist(path,'file'),
-				struc=load(path,'-mat');
-				name=char(fieldnames(struc));
-				md=struc.(name);
-				if nargout,
-					varargout{1}=md;
-				end
+				path=path;
+			elseif exist([path '.mat'],'file'),
+				path=[path '.mat'];
 			else
 				error(['Could not find ' path ]);
+			end
+
+			struc=load(path,'-mat');
+			name=char(fieldnames(struc));
+			md=struc.(name);
+			if nargout,
+				varargout{1}=md;
 			end
 		end%}}}
Index: /issm/trunk/src/m/classes/organizer.py
===================================================================
--- /issm/trunk/src/m/classes/organizer.py	(revision 17805)
+++ /issm/trunk/src/m/classes/organizer.py	(revision 17806)
@@ -1,10 +1,11 @@
 import os.path
 from collections import OrderedDict
-from pairoptions import *
-from loadvars import *
-from loadmodel import *
-from savevars import *
+import pairoptions
+from loadvars import loadvars
+from loadmodel import loadmodel
+from savevars import savevars
 from model import model
 from whichdb import whichdb
+import MatlabFuncs as m
 
 class organizer(object):
@@ -34,5 +35,5 @@
 
 		#process options
-		options=pairoptions(*args)
+		options=pairoptions.pairoptions(*args)
 
 		#Get prefix
@@ -40,5 +41,5 @@
 		if not isinstance(prefix,(str,unicode)):
 			raise TypeError("prefix is not a string")
-		if not strcmp(prefix,prefix.strip()) or len(prefix.split()) > 1:
+		if not m.strcmp(prefix,prefix.strip()) or len(prefix.split()) > 1:
 			raise TypeError("prefix should not have any white space")
 		self.prefix=prefix
@@ -60,5 +61,5 @@
 			if not isinstance(trunkprefix,(str,unicode)):
 				raise TypeError("trunkprefix is not a string")
-			if not strcmp(trunkprefix,trunkprefix.strip()) or len(trunkprefix.split()) > 1:
+			if not m.strcmp(trunkprefix,trunkprefix.strip()) or len(trunkprefix.split()) > 1:
 				raise TypeError("trunkprefix should not have any white space")
 			self.trunkprefix=trunkprefix
@@ -123,5 +124,5 @@
 		if not isinstance(string,(str,unicode)):
 			raise TypeError("Step provided should be a string")
-		if not strcmp(string,string.strip()) or len(string.split()) > 1:
+		if not m.strcmp(string,string.strip()) or len(string.split()) > 1:
 			raise TypeError("Step provided should not have any white space")
 		if self._currentstep>0 and string in [step['string'] for step in self.steps]:
Index: /issm/trunk/src/m/classes/outputdefinition.m
===================================================================
--- /issm/trunk/src/m/classes/outputdefinition.m	(revision 17805)
+++ /issm/trunk/src/m/classes/outputdefinition.m	(revision 17806)
@@ -9,4 +9,13 @@
 	end
 	methods
+	   function createxml(obj,fid) % {{{
+            fprintf(fid, '<!-- outputdefinition -->\n');            
+                    
+            % outputdefinition solution parameters
+            fprintf(fid,'%s\n%s\n%s\n','<frame key="1" label="outputdefinition">','<section name="outputdefinition" />');                    
+                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="definitions" type="',class(obj.definitions),'" default="',convert2str(obj.definitions),'">','     <section name="outputdefinition" />','     <help> list of potential outputs that can be requested, but which need additional data to be defined </help>','  </parameter>');
+            fprintf(fid,'%s\n%s\n','</frame>');    
+        
+        end % }}}
 		function obj = outputdefinition(varargin) % {{{
 			switch nargin
@@ -24,5 +33,5 @@
 		function md = checkconsistency(obj,md,solution,analyses) % {{{
 
-			md = checkfield(md,'outputdefinition.definitions','cell',1);
+			md = checkfield(md,'fieldname','outputdefinition.definitions','cell',1);
 
 			for i=1:length(obj.definitions),
Index: /issm/trunk/src/m/classes/outputdefinition.py
===================================================================
--- /issm/trunk/src/m/classes/outputdefinition.py	(revision 17805)
+++ /issm/trunk/src/m/classes/outputdefinition.py	(revision 17806)
@@ -2,6 +2,6 @@
 from EnumDefinitions import *
 from StringToEnum import StringToEnum
-from checkfield import *
-from WriteData import *
+from checkfield import checkfield
+from WriteData import WriteData
 import numpy as npy
 
@@ -29,5 +29,5 @@
 	def checkconsistency(self,md,solution,analyses):    # {{{
 		
-		md = checkfield(md,'outputdefinition.definitions','cell',1)
+		md = checkfield(md,'fieldname','outputdefinition.definitions','cell',1)
 		for definition in self.definitions:
 			definition.checkconsistency(md,solution,analyses);
Index: /issm/trunk/src/m/classes/pairoptions.py
===================================================================
--- /issm/trunk/src/m/classes/pairoptions.py	(revision 17805)
+++ /issm/trunk/src/m/classes/pairoptions.py	(revision 17806)
@@ -1,4 +1,4 @@
 from collections import OrderedDict
-from WriteData import *
+from WriteData import WriteData
 
 class pairoptions(object):
Index: /issm/trunk/src/m/classes/plotoptions.py
===================================================================
--- /issm/trunk/src/m/classes/plotoptions.py	(revision 17805)
+++ /issm/trunk/src/m/classes/plotoptions.py	(revision 17806)
@@ -1,4 +1,4 @@
 from collections import OrderedDict, Counter, defaultdict
-from pairoptions import *
+import pairoptions
 
 class plotoptions(object):
@@ -41,5 +41,5 @@
 
 		#go through args and build list (like pairoptions)
-		rawoptions=pairoptions(*arg)
+		rawoptions=pairoptions.pairoptions(*arg)
 		numoptions=len(arg)/2
 		rawlist=[] # cannot be a dict since they do not support duplicate keys
@@ -69,5 +69,5 @@
 		#self.list=defaultdict(dict)
 		for i in xrange(numberofplots):
-			self.list[i]=pairoptions()
+			self.list[i]=pairoptions.pairoptions()
 
 		#process plot options
Index: /issm/trunk/src/m/classes/private.py
===================================================================
--- /issm/trunk/src/m/classes/private.py	(revision 17805)
+++ /issm/trunk/src/m/classes/private.py	(revision 17806)
@@ -2,5 +2,5 @@
 from fielddisplay import fielddisplay
 from EnumDefinitions import *
-from checkfield import *
+from checkfield import checkfield
 
 class private(object):
Index: /issm/trunk/src/m/classes/qmu.m
===================================================================
--- /issm/trunk/src/m/classes/qmu.m	(revision 17805)
+++ /issm/trunk/src/m/classes/qmu.m	(revision 17806)
@@ -24,4 +24,33 @@
 	end
 	methods
+        function createxml(obj,fid) % {{{
+            fprintf(fid, '<!-- qmu -->\n');            
+                    
+            % qmu solution parameters
+            fprintf(fid,'%s\n%s\n%s\n','<frame key="1" label="qmu parameters">','<section name="qmu" />');                    
+                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="isdakota" type="',class(obj.isdakota),'" default="',convert2str(obj.isdakota),'">','     <section name="qmu" />','     <help> is qmu analysis activated? </help>','  </parameter>');
+                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="variables" type="',class(obj.variables),'" default="',convert2str(obj.variables),'">','     <section name="qmu" />','     <help> (arrays of each variable class) </help>','  </parameter>');
+                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="responses" type="',class(obj.responses),'" default="',convert2str(obj.responses),'">','     <section name="qmu" />','     <help> (arrays of each response class) </help>','  </parameter>');
+                
+                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="numberofresponses" type="',class(obj.numberofresponses),'" default="',convert2str(obj.numberofresponses),'">','     <section name="qmu" />','     <help> number of responses </help>','  </parameter>');
+                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="params" type="',class(obj.params),'" default="',convert2str(obj.params),'">','     <section name="qmu" />','     <help> (array of method-independent parameters)  </help>','  </parameter>');
+                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="results" type="',class(obj.results),'" default="',convert2str(obj.results),'">','     <section name="qmu" />','     <help> (information from dakota files) </help>','  </parameter>');
+                
+                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="partition" type="',class(obj.partition),'" default="',convert2str(obj.partition),'">','     <section name="qmu" />','     <help> user provided mesh partitioning, defaults to metis if not specified </help>','  </parameter>');
+                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="numberofpartitions" type="',class(obj.numberofpartitions),'" default="',convert2str(obj.numberofpartitions),'">','     <section name="qmu" />','     <help> number of partitions for semi-discrete qmu  </help>','  </parameter>');
+                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="variabledescriptors" type="',class(obj.variabledescriptors),'" default="',convert2str(obj.variabledescriptors),'">','     <section name="qmu" />','     <help>  </help>','  </parameter>');
+            
+                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="responsedescriptors" type="',class(obj.responsedescriptors),'" default="',convert2str(obj.responsedescriptors),'">','     <section name="qmu" />','     <help> use an enthalpy formulation to include temperate ice (default is 0) </help>','  </parameter>');
+                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="method" type="',class(obj.method),'" default="',convert2str(obj.method),'">','     <section name="qmu" />','     <help> array of dakota_method class </help>','  </parameter>');
+                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="mass_flux_profile_directory" type="',class(obj.mass_flux_profile_directory),'" default="',convert2str(obj.mass_flux_profile_directory),'">','     <section name="qmu" />','     <help> directory for mass flux profiles </help>','  </parameter>');
+                
+                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="mass_flux_profiles" type="',class(obj.mass_flux_profiles),'" default="',convert2str(obj.mass_flux_profiles),'">','     <section name="qmu" />','     <help>  </help>','  </parameter>');
+                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="mass_flux_segments" type="',class(obj.mass_flux_segments),'" default="',convert2str(obj.mass_flux_segments),'">','     <section name="qmu" />','     <help>  </help>','  </parameter>');
+                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="adjacency" type="',class(obj.adjacency),'" default="',convert2str(obj.adjacency),'">','     <section name="qmu" />','     <help> additional outputs requested </help>','  </parameter>');
+                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="vertex_weight" type="',class(obj.vertex_weight),'" default="',convert2str(obj.vertex_weight),'">','     <section name="qmu" />','     <help> weight applied to each mesh vertex </help>','  </parameter>');
+            
+            fprintf(fid,'%s\n%s\n','</frame>');    
+        
+        end % }}}        
 		function obj = qmu(varargin) % {{{
 			switch nargin
Index: /issm/trunk/src/m/classes/qmu.py
===================================================================
--- /issm/trunk/src/m/classes/qmu.py	(revision 17805)
+++ /issm/trunk/src/m/classes/qmu.py	(revision 17806)
@@ -3,7 +3,7 @@
 from fielddisplay import fielddisplay
 from EnumDefinitions import *
-from checkfield import *
-from WriteData import *
-from MatlabFuncs import *
+from checkfield import checkfield
+from WriteData import WriteData
+import MatlabFuncs as m
 
 class qmu(object):
@@ -56,5 +56,5 @@
 				md.checkmessage("for qmu analysis, partitioning vector cannot go over npart, number of partition areas")
 
-		if not strcmpi(md.cluster.name,'none'):
+		if not m.strcmpi(md.cluster.name,'none'):
 			if not md.settings.waitonlock:
 				md.checkmessage("waitonlock should be activated when running qmu in parallel mode!")
Index: /issm/trunk/src/m/classes/results.py
===================================================================
--- /issm/trunk/src/m/classes/results.py	(revision 17805)
+++ /issm/trunk/src/m/classes/results.py	(revision 17806)
@@ -1,8 +1,7 @@
 import numpy
-from pairoptions import *
-from fielddisplay import *
-from MatlabFuncs import *
+from pairoptions import pairoptions
+from fielddisplay import fielddisplay
+import MatlabFuncs as m
 from EnumDefinitions import *
-from WriteData import *
 
 class results(object):
Index: /issm/trunk/src/m/classes/rifts.m
===================================================================
--- /issm/trunk/src/m/classes/rifts.m	(revision 17805)
+++ /issm/trunk/src/m/classes/rifts.m	(revision 17806)
@@ -10,4 +10,11 @@
 	end
 	methods
+        function createxml(obj,fid) % {{{
+            fprintf(fid, '\n\n');
+            fprintf(fid, '%s\n', '<!-- rifts -->');
+			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="riftstruct" type="',              class(obj.riftstruct),'" default="',                  obj.riftstruct,'">',              '     <section name="rifts" />','     <help> structure containing all rift information (vertices coordinates, segments, type of melange, ...) </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="riftproperties" type="',            class(obj.riftproperties),'" default="',                obj.riftproperties,'">',   '     <section name="rifts" />','     <help> N/A </help>','</parameter>');
+    
+        end % }}}
 		function obj = rifts(varargin) % {{{
 			switch nargin
@@ -28,5 +35,5 @@
 			end
 			if numrifts,
-				if ~(md.mesh.dimension==2),
+				if ~(strcmp(domaintype(md.mesh),'2Dhorizontal')),
 					md = checkmessage(md,['models with rifts are only supported in 2d for now!']);
 				end
@@ -39,5 +46,5 @@
 				end
 				for i=1:numrifts,
-					md = checkfield(md,sprintf('rifts.riftstruct(%d).fill',i),'values',[WaterEnum() AirEnum() IceEnum() MelangeEnum()]);
+					md = checkfield(md,'fieldname',sprintf('rifts.riftstruct(%d).fill',i),'values',[WaterEnum() AirEnum() IceEnum() MelangeEnum()]);
 				end
 			else
Index: /issm/trunk/src/m/classes/rifts.py
===================================================================
--- /issm/trunk/src/m/classes/rifts.py	(revision 17805)
+++ /issm/trunk/src/m/classes/rifts.py	(revision 17806)
@@ -2,7 +2,8 @@
 from fielddisplay import fielddisplay
 from EnumDefinitions import *
-from checkfield import *
-from WriteData import *
-from isnans import *
+from checkfield import checkfield
+from WriteData import WriteData
+from isnans import isnans
+import MatlabFuncs as m
 
 class rifts(object):
@@ -39,5 +40,5 @@
 
 		if numrifts:
-			if not md.mesh.dimension==2:
+			if not m.strcmp(md.mesh.domaintype(),'2Dhorizontal'):
 				md.checkmessage("models with rifts are only supported in 2d for now!")
 			if not isinstance(self.riftstruct,list):
@@ -47,5 +48,5 @@
 				md.checkmessage("model should be processed for rifts (run meshprocessrifts)!")
 			for i,rift in enumerate(self.riftstruct):
-				md = checkfield(md,"rifts.riftstruct[%d]['fill']" % i,'values',[WaterEnum(),AirEnum(),IceEnum(),MelangeEnum()])
+				md = checkfield(md,'fieldname',"rifts.riftstruct[%d]['fill']" % i,'values',[WaterEnum(),AirEnum(),IceEnum(),MelangeEnum()])
 		else:
 			if self.riftstruct and numpy.any(numpy.logical_not(isnans(self.riftstruct))):
Index: /issm/trunk/src/m/classes/settings.m
===================================================================
--- /issm/trunk/src/m/classes/settings.m	(revision 17805)
+++ /issm/trunk/src/m/classes/settings.m	(revision 17806)
@@ -6,4 +6,5 @@
 classdef settings
 	properties (SetAccess=public) 
+		results_on_nodes    = 0;
 		io_gather           = 0;
 		lowmem              = 0;
@@ -18,4 +19,19 @@
 	end
 	methods
+        function createxml(obj,fid) % {{{
+            fprintf(fid, '\n\n');
+            fprintf(fid, '%s\n', '<!-- settings -->');
+			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="results_on_nodes" type="',      class(obj.results_on_nodes),'" default="',        convert2str(obj.results_on_nodes),'">',	'     <section name="settings" />','     <help> results are output for all the nodes of each element </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="io_gather" type="',          class(obj.io_gather),'" default="',           convert2str(obj.io_gather),'">',     '     <section name="settings" />','     <help> I/O gathering strategy for result outputs (default 1) </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',	'<parameter key ="lowmem" type="',        class(obj.lowmem),'" default="',         convert2str(obj.lowmem),'">',	'     <section name="settings" />','     <help> is the memory limited ? (0 or 1) </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="output_frequency" type="',          class(obj.output_frequency),'" default="',           convert2str(obj.output_frequency),'">',	'     <section name="settings" />','     <help> frequency at which results are saved in all solutions with multiple time_steps </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="waitonlock" type="',  	class(obj.waitonlock),'" default="',      convert2str(obj.waitonlock),'">',     '     <section name="settings" />','     <help> maximum number of minutes to wait for batch results (NaN to deactivate) </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="upload_server" type="',         class(obj.upload_server),'" default="',          convert2str(obj.upload_server),'">',	'     <section name="settings" />','     <help> server hostname where model should be uploaded </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="upload_path" type="',             class(obj.upload_path),'" default="',              convert2str(obj.upload_path),'">',     '     <section name="settings" />','     <help> path on server where model should be uploaded </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="upload_login" type="',        class(obj.upload_login),'" default="',         convert2str(obj.upload_login),'">',	'     <section name="settings" />','     <help> server login </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="upload_port" type="',    	class(obj.upload_port),'" default="',      convert2str(obj.upload_port),'">',     '     <section name="settings" />','     <help> port login (default is 0) </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n',    	'<parameter key ="upload_filename" type="',         class(obj.upload_filename),'" default="',          convert2str(obj.upload_filename),'">',	'     <section name="settings" />','     <help> unique id generated when uploading the file to server </help>','</parameter>');
+             
+        end % }}}
 		function obj = settings(varargin) % {{{
 			switch nargin
@@ -49,8 +65,9 @@
 		function md = checkconsistency(obj,md,solution,analyses) % {{{
 
-			md = checkfield(md,'settings.io_gather','numel',[1],'values',[0 1]);
-			md = checkfield(md,'settings.lowmem','numel',[1],'values',[0 1]);
-			md = checkfield(md,'settings.output_frequency','numel',[1],'>=',1);
-			md = checkfield(md,'settings.waitonlock','numel',[1]);
+			md = checkfield(md,'fieldname','settings.results_on_nodes','numel',[1],'values',[0 1]);
+			md = checkfield(md,'fieldname','settings.io_gather','numel',[1],'values',[0 1]);
+			md = checkfield(md,'fieldname','settings.lowmem','numel',[1],'values',[0 1]);
+			md = checkfield(md,'fieldname','settings.output_frequency','numel',[1],'>=',1);
+			md = checkfield(md,'fieldname','settings.waitonlock','numel',[1]);
 
 		end % }}}
@@ -58,4 +75,5 @@
 			disp(sprintf('   general settings parameters:'));
 
+			fielddisplay(obj,'results_on_nodes','results are output for all the nodes of each element');
 			fielddisplay(obj,'io_gather','I/O gathering strategy for result outputs (default 1)');
 			fielddisplay(obj,'lowmem','is the memory limited ? (0 or 1)');
@@ -70,4 +88,5 @@
 		end % }}}
 		function marshall(obj,md,fid) % {{{
+			WriteData(fid,'object',obj,'fieldname','results_on_nodes','format','Boolean');
 			WriteData(fid,'object',obj,'fieldname','io_gather','format','Boolean');
 			WriteData(fid,'object',obj,'fieldname','lowmem','format','Boolean');
Index: /issm/trunk/src/m/classes/settings.py
===================================================================
--- /issm/trunk/src/m/classes/settings.py	(revision 17805)
+++ /issm/trunk/src/m/classes/settings.py	(revision 17806)
@@ -1,6 +1,6 @@
 from fielddisplay import fielddisplay
 from EnumDefinitions import *
-from checkfield import *
-from WriteData import *
+from checkfield import checkfield
+from WriteData import WriteData
 
 class settings(object):
@@ -13,4 +13,5 @@
 
 	def __init__(self): # {{{
+		self.results_on_nodes    = 0
 		self.io_gather           = 0
 		self.lowmem              = 0
@@ -25,4 +26,5 @@
 		string="   general settings parameters:"
 
+		string="%s\n%s"%(string,fielddisplay(self,"results_on_nodes","results are output for all the nodes of each element"))
 		string="%s\n%s"%(string,fielddisplay(self,"io_gather","I/O gathering strategy for result outputs (default 1)"))
 		string="%s\n%s"%(string,fielddisplay(self,"lowmem","is the memory limited ? (0 or 1)"))
@@ -51,12 +53,14 @@
 	#}}}
 	def checkconsistency(self,md,solution,analyses):    # {{{
-		md = checkfield(md,'settings.io_gather','numel',[1],'values',[0,1])
-		md = checkfield(md,'settings.lowmem','numel',[1],'values',[0,1])
-		md = checkfield(md,'settings.output_frequency','numel',[1],'>=',1)
-		md = checkfield(md,'settings.waitonlock','numel',[1])
+		md = checkfield(md,'fieldname','settings.results_on_nodes','numel',[1],'values',[0,1])
+		md = checkfield(md,'fieldname','settings.io_gather','numel',[1],'values',[0,1])
+		md = checkfield(md,'fieldname','settings.lowmem','numel',[1],'values',[0,1])
+		md = checkfield(md,'fieldname','settings.output_frequency','numel',[1],'>=',1)
+		md = checkfield(md,'fieldname','settings.waitonlock','numel',[1])
 
 		return md
 	# }}}
 	def marshall(self,md,fid):    # {{{
+		WriteData(fid,'object',self,'fieldname','results_on_nodes','format','Boolean')
 		WriteData(fid,'object',self,'fieldname','io_gather','format','Boolean')
 		WriteData(fid,'object',self,'fieldname','lowmem','format','Boolean')
Index: /issm/trunk/src/m/classes/snowpack.m
===================================================================
--- /issm/trunk/src/m/classes/snowpack.m	(revision 17805)
+++ /issm/trunk/src/m/classes/snowpack.m	(revision 17806)
@@ -219,119 +219,119 @@
 		function md = checkconsistency(obj,md,solution,analyses) % {{{
 			%snowpack:  %{{{
-			md=checkfield(md,'snowpack.snowpack_meas_tss','values',[0 1]);
-			md=checkfield(md,'snowpack.snowpack_enforce_measured_snow_heights','values',[0 1]);
-			md=checkfield(md,'snowpack.snowpack_sw_mode','values',[0 1 2]);
-			md=checkfield(md,'snowpack.snowpack_incoming_longwave','values',[0 1]);
-			md=checkfield(md,'snowpack.snowpack_height_of_wind_value','>=',0);
-			md=checkfield(md,'snowpack.snowpack_height_of_meteo_values','>=',0);
-			md=checkfield(md,'snowpack.snowpack_neutral','values',[-1 0 1]);
-			md=checkfield(md,'snowpack.snowpack_roughness_length','>=',0);
-			md=checkfield(md,'snowpack.snowpack_number_slopes','values',[1 3 5 9]);
-			md=checkfield(md,'snowpack.snowpack_snow_redistribution','values',[0 1]);
-			md=checkfield(md,'snowpack.snowpack_calculation_step_length','>',0);
-			md=checkfield(md,'snowpack.snowpack_change_bc','values',[0 1]);
-			md=checkfield(md,'snowpack.snowpack_thresh_change_bc','<=',0);
-			md=checkfield(md,'snowpack.snowpack_snp_soil','values',[0 1]);
-			md=checkfield(md,'snowpack.snowpack_soil_flux','values',[0 1]);
-			md=checkfield(md,'snowpack.snowpack_geo_heat','>=',0);
-			md=checkfield(md,'snowpack.snowpack_canopy','values',[0 1]);
+			md=checkfield(md,'fieldname','snowpack.snowpack_meas_tss','values',[0 1]);
+			md=checkfield(md,'fieldname','snowpack.snowpack_enforce_measured_snow_heights','values',[0 1]);
+			md=checkfield(md,'fieldname','snowpack.snowpack_sw_mode','values',[0 1 2]);
+			md=checkfield(md,'fieldname','snowpack.snowpack_incoming_longwave','values',[0 1]);
+			md=checkfield(md,'fieldname','snowpack.snowpack_height_of_wind_value','>=',0);
+			md=checkfield(md,'fieldname','snowpack.snowpack_height_of_meteo_values','>=',0);
+			md=checkfield(md,'fieldname','snowpack.snowpack_neutral','values',[-1 0 1]);
+			md=checkfield(md,'fieldname','snowpack.snowpack_roughness_length','>=',0);
+			md=checkfield(md,'fieldname','snowpack.snowpack_number_slopes','values',[1 3 5 9]);
+			md=checkfield(md,'fieldname','snowpack.snowpack_snow_redistribution','values',[0 1]);
+			md=checkfield(md,'fieldname','snowpack.snowpack_calculation_step_length','>',0);
+			md=checkfield(md,'fieldname','snowpack.snowpack_change_bc','values',[0 1]);
+			md=checkfield(md,'fieldname','snowpack.snowpack_thresh_change_bc','<=',0);
+			md=checkfield(md,'fieldname','snowpack.snowpack_snp_soil','values',[0 1]);
+			md=checkfield(md,'fieldname','snowpack.snowpack_soil_flux','values',[0 1]);
+			md=checkfield(md,'fieldname','snowpack.snowpack_geo_heat','>=',0);
+			md=checkfield(md,'fieldname','snowpack.snowpack_canopy','values',[0 1]);
 			%}}}
 			%snowpackadvanced:  %{{{
-			md=checkfield(md,'snowpack.snowpackadvanced_variant','values',{'JAPAN','DEFAULT','ANTARCTICA'});
-			md=checkfield(md,'snowpack.snowpackadvanced_hn_density','values',{'PARAMETERIZED','EVENT','MEASURED'});
+			md=checkfield(md,'fieldname','snowpack.snowpackadvanced_variant','values',{'JAPAN','DEFAULT','ANTARCTICA'});
+			md=checkfield(md,'fieldname','snowpack.snowpackadvanced_hn_density','values',{'PARAMETERIZED','EVENT','MEASURED'});
 			%}}}
 			%general:  %{{{
-			md=checkfield(md,'snowpack.general_buff_chunk_size','>',0);
-			md=checkfield(md,'snowpack.general_buff_before','>',0);
+			md=checkfield(md,'fieldname','snowpack.general_buff_chunk_size','>',0);
+			md=checkfield(md,'fieldname','snowpack.general_buff_before','>',0);
 			%}}}
 			%input {{{
-			md=checkfield(md,'snowpack.input_coordsys','values',{'CH1903','UTM','UPS','PROJ4','LOCAL'});
-			md=checkfield(md,'snowpack.input_coordparam','values','null');
-			md=checkfield(md,'snowpack.input_time_zone','>',-12,'<',12);
-			md=checkfield(md,'snowpack.input_meteo','values',{'BORMA','COSMO','GEOTOP','GRIB','GSN','IMIS','SMET','SNOWPACK'});
-			md=checkfield(md,'snowpack.input_meteopath','empty',1);
-			md=checkfield(md,'snowpack.input_station1 ','empty',1);
-			md=checkfield(md,'snowpack.input_snowfile1','empty',1);
+			md=checkfield(md,'fieldname','snowpack.input_coordsys','values',{'CH1903','UTM','UPS','PROJ4','LOCAL'});
+			md=checkfield(md,'fieldname','snowpack.input_coordparam','values','null');
+			md=checkfield(md,'fieldname','snowpack.input_time_zone','>',-12,'<',12);
+			md=checkfield(md,'fieldname','snowpack.input_meteo','values',{'BORMA','COSMO','GEOTOP','GRIB','GSN','IMIS','SMET','SNOWPACK'});
+			md=checkfield(md,'fieldname','snowpack.input_meteopath','empty',1);
+			md=checkfield(md,'fieldname','snowpack.input_station1 ','empty',1);
+			md=checkfield(md,'fieldname','snowpack.input_snowfile1','empty',1);
 			%}}}
 			%output {{{
-			md=checkfield(md,'snowpack.output_coordsys','values',{'CH1903','UTM','UPS','PROJ4','LOCAL'});
-			md=checkfield(md,'snowpack.output_coordparam','values','null');
-			md=checkfield(md,'snowpack.output_time_zone','>',-12,'<',12);
-			md=checkfield(md,'snowpack.output_meteopath','empty',1);
-			md=checkfield(md,'snowpack.output_experiment','empty',1);
-			md=checkfield(md,'snowpack.output_ts_write','values',[0 1]);
-			md=checkfield(md,'snowpack.output_ts_start','>=',0);
-			md=checkfield(md,'snowpack.output_ts_days_between','>=',0);
-			md=checkfield(md,'snowpack.output_profile','values',{'ASCII','IMIS','ASCII IMIS'});
-			md=checkfield(md,'snowpack.output_prof_write','values',[0 1]);
-			md=checkfield(md,'snowpack.output_prof_start','>=',0);
-			md=checkfield(md,'snowpack.output_prof_days_between','>=',0);
+			md=checkfield(md,'fieldname','snowpack.output_coordsys','values',{'CH1903','UTM','UPS','PROJ4','LOCAL'});
+			md=checkfield(md,'fieldname','snowpack.output_coordparam','values','null');
+			md=checkfield(md,'fieldname','snowpack.output_time_zone','>',-12,'<',12);
+			md=checkfield(md,'fieldname','snowpack.output_meteopath','empty',1);
+			md=checkfield(md,'fieldname','snowpack.output_experiment','empty',1);
+			md=checkfield(md,'fieldname','snowpack.output_ts_write','values',[0 1]);
+			md=checkfield(md,'fieldname','snowpack.output_ts_start','>=',0);
+			md=checkfield(md,'fieldname','snowpack.output_ts_days_between','>=',0);
+			md=checkfield(md,'fieldname','snowpack.output_profile','values',{'ASCII','IMIS','ASCII IMIS'});
+			md=checkfield(md,'fieldname','snowpack.output_prof_write','values',[0 1]);
+			md=checkfield(md,'fieldname','snowpack.output_prof_start','>=',0);
+			md=checkfield(md,'fieldname','snowpack.output_prof_days_between','>=',0);
 			%}}}
 			%interpolations1d %{{{
-			md=checkfield(md,'snowpack.interpolations1d_window_size','>',0);
-			md=checkfield(md,'snowpack.interpolations1d_hnw_resample','values',{'NONE','NEAREST_NEIGHBOUR','ACCUMULATE','LINEAR'});
-			md=checkfield(md,'snowpack.interpolations1d_hs_resample','values',{'NONE','NEAREST_NEIGHBOUR','ACCUMULATE','LINEAR'});
-			md=checkfield(md,'snowpack.interpolations1d_tsg_resample','values',{'NONE','NEAREST_NEIGHBOUR','ACCUMULATE','LINEAR'});
-			md=checkfield(md,'snowpack.interpolations1d_rho_hn_resample','values',{'NONE','NEAREST_NEIGHBOUR','ACCUMULATE','LINEAR'});
-			md=checkfield(md,'snowpack.interpolations1d_vw_resample','values',{'NONE','NEAREST_NEIGHBOUR','ACCUMULATE','LINEAR'});
-			md=checkfield(md,'snowpack.interpolations1d_vw_args','values',{'EXTRAPOLATE'});
+			md=checkfield(md,'fieldname','snowpack.interpolations1d_window_size','>',0);
+			md=checkfield(md,'fieldname','snowpack.interpolations1d_hnw_resample','values',{'NONE','NEAREST_NEIGHBOUR','ACCUMULATE','LINEAR'});
+			md=checkfield(md,'fieldname','snowpack.interpolations1d_hs_resample','values',{'NONE','NEAREST_NEIGHBOUR','ACCUMULATE','LINEAR'});
+			md=checkfield(md,'fieldname','snowpack.interpolations1d_tsg_resample','values',{'NONE','NEAREST_NEIGHBOUR','ACCUMULATE','LINEAR'});
+			md=checkfield(md,'fieldname','snowpack.interpolations1d_rho_hn_resample','values',{'NONE','NEAREST_NEIGHBOUR','ACCUMULATE','LINEAR'});
+			md=checkfield(md,'fieldname','snowpack.interpolations1d_vw_resample','values',{'NONE','NEAREST_NEIGHBOUR','ACCUMULATE','LINEAR'});
+			md=checkfield(md,'fieldname','snowpack.interpolations1d_vw_args','values',{'EXTRAPOLATE'});
 			%}}}
 			%filters {{{
 			filter_values={'MIN_MAX','RATE_FILTER1','RATE_FILTER2','UNHEATED_RAIN_GAUGE_FILTER','WMO_UNDERCATCH_FILTER','WMO_UNDERCATCH_FILTER-SIMPLIFIED','UNVENTILLATED_TEMPERATURE_SENSOR','ADD_AN_OFFSET'};
 
-			md=checkfield(md,'snowpack.filters_ta_filter1','values',{filter_values});
-			if strcmpi(md.snowpack.filters_ta_filter1,'MIN_MAX'), md=checkfield(md,'snowpack.filters_ta_filter1','size',[1 NaN]); end
-			md=checkfield(md,'snowpack.filters_ta_arg1','values',{filter_values});
-			if strcmpi(md.snowpack.filters_ta_arg1,'MIN_MAX'), md=checkfield(md,'snowpack.filters_ta_arg1','size',[1 NaN]); end
-			md=checkfield(md,'snowpack.filters_rh_filter1','values',{filter_values});
-			if strcmpi(md.snowpack.filters_rh_filter1,'MIN_MAX'), md=checkfield(md,'snowpack.filters_rh_filter1','size',[1 NaN]); end
-			md=checkfield(md,'snowpack.filters_rh_arg1','values',{filter_values});
-			if strcmpi(md.snowpack.filters_rh_arg1,'MIN_MAX'), md=checkfield(md,'snowpack.filters_rh_arg1','size',[1 NaN]); end
-			md=checkfield(md,'snowpack.filters_rh_filter2','values',{filter_values});
-			if strcmpi(md.snowpack.filters_rh_filter2,'MIN_MAX'), md=checkfield(md,'snowpack.filters_rh_filter2','size',[1 NaN]); end
-			md=checkfield(md,'snowpack.filters_rh_arg2','values',{filter_values});
-			if strcmpi(md.snowpack.filters_rh_arg2,'MIN_MAX'), md=checkfield(md,'snowpack.filters_rh_arg2','size',[1 NaN]); end
-			md=checkfield(md,'snowpack.filters_iswr_filter1','values',{filter_values});
-			if strcmpi(md.snowpack.filters_iswr_filter1,'MIN_MAX'), md=checkfield(md,'snowpack.filters_iswr_filter1','size',[1 NaN]); end
-			md=checkfield(md,'snowpack.filters_iswr_arg1','values',{filter_values});
-			if strcmpi(md.snowpack.filters_iswr_arg1,'MIN_MAX'), md=checkfield(md,'snowpack.filters_iswr_arg1','size',[1 NaN]); end
-			md=checkfield(md,'snowpack.filters_iswr_filter2','values',{filter_values});
-			if strcmpi(md.snowpack.filters_iswr_filter2,'MIN_MAX'), md=checkfield(md,'snowpack.filters_iswr_filter2','size',[1 NaN]); end
-			md=checkfield(md,'snowpack.filters_iswr_arg2','values',{filter_values});
-			if strcmpi(md.snowpack.filters_iswr_arg2,'MIN_MAX'), md=checkfield(md,'snowpack.filters_iswr_arg2','size',[1 NaN]); end
-			md=checkfield(md,'snowpack.filters_rswr_filter1','values',{filter_values});
-			if strcmpi(md.snowpack.filters_rswr_filter1,'MIN_MAX'), md=checkfield(md,'snowpack.filters_rswr_filter1','size',[1 NaN]); end
-			md=checkfield(md,'snowpack.filters_rswr_arg1','values',{filter_values});
-			if strcmpi(md.snowpack.filters_rswr_arg1,'MIN_MAX'), md=checkfield(md,'snowpack.filters_rswr_arg1','size',[1 NaN]); end
-			md=checkfield(md,'snowpack.filters_rswr_filter2','values',{filter_values});
-			if strcmpi(md.snowpack.filters_rswr_filter2,'MIN_MAX'), md=checkfield(md,'snowpack.filters_rswr_filter2','size',[1 NaN]); end
-			md=checkfield(md,'snowpack.filters_rswr_arg2','values',{filter_values});
-			if strcmpi(md.snowpack.filters_rswr_arg2,'MIN_MAX'), md=checkfield(md,'snowpack.filters_rswr_arg2','size',[1 NaN]); end
+			md=checkfield(md,'fieldname','snowpack.filters_ta_filter1','values',{filter_values});
+			if strcmpi(md.snowpack.filters_ta_filter1,'MIN_MAX'), md=checkfield(md,'fieldname','snowpack.filters_ta_filter1','size',[1 NaN]); end
+			md=checkfield(md,'fieldname','snowpack.filters_ta_arg1','values',{filter_values});
+			if strcmpi(md.snowpack.filters_ta_arg1,'MIN_MAX'), md=checkfield(md,'fieldname','snowpack.filters_ta_arg1','size',[1 NaN]); end
+			md=checkfield(md,'fieldname','snowpack.filters_rh_filter1','values',{filter_values});
+			if strcmpi(md.snowpack.filters_rh_filter1,'MIN_MAX'), md=checkfield(md,'fieldname','snowpack.filters_rh_filter1','size',[1 NaN]); end
+			md=checkfield(md,'fieldname','snowpack.filters_rh_arg1','values',{filter_values});
+			if strcmpi(md.snowpack.filters_rh_arg1,'MIN_MAX'), md=checkfield(md,'fieldname','snowpack.filters_rh_arg1','size',[1 NaN]); end
+			md=checkfield(md,'fieldname','snowpack.filters_rh_filter2','values',{filter_values});
+			if strcmpi(md.snowpack.filters_rh_filter2,'MIN_MAX'), md=checkfield(md,'fieldname','snowpack.filters_rh_filter2','size',[1 NaN]); end
+			md=checkfield(md,'fieldname','snowpack.filters_rh_arg2','values',{filter_values});
+			if strcmpi(md.snowpack.filters_rh_arg2,'MIN_MAX'), md=checkfield(md,'fieldname','snowpack.filters_rh_arg2','size',[1 NaN]); end
+			md=checkfield(md,'fieldname','snowpack.filters_iswr_filter1','values',{filter_values});
+			if strcmpi(md.snowpack.filters_iswr_filter1,'MIN_MAX'), md=checkfield(md,'fieldname','snowpack.filters_iswr_filter1','size',[1 NaN]); end
+			md=checkfield(md,'fieldname','snowpack.filters_iswr_arg1','values',{filter_values});
+			if strcmpi(md.snowpack.filters_iswr_arg1,'MIN_MAX'), md=checkfield(md,'fieldname','snowpack.filters_iswr_arg1','size',[1 NaN]); end
+			md=checkfield(md,'fieldname','snowpack.filters_iswr_filter2','values',{filter_values});
+			if strcmpi(md.snowpack.filters_iswr_filter2,'MIN_MAX'), md=checkfield(md,'fieldname','snowpack.filters_iswr_filter2','size',[1 NaN]); end
+			md=checkfield(md,'fieldname','snowpack.filters_iswr_arg2','values',{filter_values});
+			if strcmpi(md.snowpack.filters_iswr_arg2,'MIN_MAX'), md=checkfield(md,'fieldname','snowpack.filters_iswr_arg2','size',[1 NaN]); end
+			md=checkfield(md,'fieldname','snowpack.filters_rswr_filter1','values',{filter_values});
+			if strcmpi(md.snowpack.filters_rswr_filter1,'MIN_MAX'), md=checkfield(md,'fieldname','snowpack.filters_rswr_filter1','size',[1 NaN]); end
+			md=checkfield(md,'fieldname','snowpack.filters_rswr_arg1','values',{filter_values});
+			if strcmpi(md.snowpack.filters_rswr_arg1,'MIN_MAX'), md=checkfield(md,'fieldname','snowpack.filters_rswr_arg1','size',[1 NaN]); end
+			md=checkfield(md,'fieldname','snowpack.filters_rswr_filter2','values',{filter_values});
+			if strcmpi(md.snowpack.filters_rswr_filter2,'MIN_MAX'), md=checkfield(md,'fieldname','snowpack.filters_rswr_filter2','size',[1 NaN]); end
+			md=checkfield(md,'fieldname','snowpack.filters_rswr_arg2','values',{filter_values});
+			if strcmpi(md.snowpack.filters_rswr_arg2,'MIN_MAX'), md=checkfield(md,'fieldname','snowpack.filters_rswr_arg2','size',[1 NaN]); end
 
 			%for ta between 190 and 280 k;
-			md=checkfield(md,'snowpack.filters_ilwr_filter1','values',{filter_values});
-			if strcmpi(md.snowpack.filters_ilwr_filter1,'MIN_MAX'), md=checkfield(md,'snowpack.filters_ilwr_filter1','size',[1 NaN]); end
-			md=checkfield(md,'snowpack.filters_ilwr_arg1','values',{filter_values});
-			if strcmpi(md.snowpack.filters_ilwr_arg1,'MIN_MAX'), md=checkfield(md,'snowpack.filters_ilwr_arg1','size',[1 NaN]); end
-			md=checkfield(md,'snowpack.filters_ilwr_filter2','values',{filter_values});
-			if strcmpi(md.snowpack.filters_ilwr_filter2,'MIN_MAX'), md=checkfield(md,'snowpack.filters_ilwr_filter2','size',[1 NaN]); end
-			md=checkfield(md,'snowpack.filters_ilwr_arg2','values',{filter_values});
-			if strcmpi(md.snowpack.filters_ilwr_arg2,'MIN_MAX'), md=checkfield(md,'snowpack.filters_ilwr_arg2','size',[1 NaN]); end
-			md=checkfield(md,'snowpack.filters_tss_filter1','values',{filter_values});
-			if strcmpi(md.snowpack.filters_tss_filter1,'MIN_MAX'), md=checkfield(md,'snowpack.filters_tss_filter1','size',[1 NaN]); end
-			md=checkfield(md,'snowpack.filters_tss_arg1','values',{filter_values});
-			if strcmpi(md.snowpack.filters_tss_arg1,'MIN_MAX'), md=checkfield(md,'snowpack.filters_tss_arg1','size',[1 NaN]); end
-			md=checkfield(md,'snowpack.filters_tsg_filter1','values',{filter_values});
-			if strcmpi(md.snowpack.filters_tsg_filter1,'MIN_MAX'), md=checkfield(md,'snowpack.filters_tsg_filter1','size',[1 NaN]); end
-			md=checkfield(md,'snowpack.filters_tsg_arg1','values',{filter_values});
-			if strcmpi(md.snowpack.filters_tsg_arg1,'MIN_MAX'), md=checkfield(md,'snowpack.filters_tsg_arg1','size',[1 NaN]); end
-			md=checkfield(md,'snowpack.filters_vw_filter1','values',{filter_values});
-			if strcmpi(md.snowpack.filters_vw_filter1,'MIN_MAX'), md=checkfield(md,'snowpack.filters_vw_filter1','size',[1 NaN]); end
-			md=checkfield(md,'snowpack.filters_vw_arg1','values',{filter_values});
-			if strcmpi(md.snowpack.filters_vw_arg1,'MIN_MAX'), md=checkfield(md,'snowpack.filters_vw_arg1','size',[1 NaN]); end
-			md=checkfield(md,'snowpack.filters_vw_filter2','values',{filter_values});
-			if strcmpi(md.snowpack.filters_vw_filter2,'MIN_MAX'), md=checkfield(md,'snowpack.filters_vw_filter2','size',[1 NaN]); end
-			md=checkfield(md,'snowpack.filters_vw_arg2','values',{filter_values});
-			if strcmpi(md.snowpack.filters_vw_arg2,'MIN_MAX'), md=checkfield(md,'snowpack.filters_vw_arg2','size',[1 NaN]); end
+			md=checkfield(md,'fieldname','snowpack.filters_ilwr_filter1','values',{filter_values});
+			if strcmpi(md.snowpack.filters_ilwr_filter1,'MIN_MAX'), md=checkfield(md,'fieldname','snowpack.filters_ilwr_filter1','size',[1 NaN]); end
+			md=checkfield(md,'fieldname','snowpack.filters_ilwr_arg1','values',{filter_values});
+			if strcmpi(md.snowpack.filters_ilwr_arg1,'MIN_MAX'), md=checkfield(md,'fieldname','snowpack.filters_ilwr_arg1','size',[1 NaN]); end
+			md=checkfield(md,'fieldname','snowpack.filters_ilwr_filter2','values',{filter_values});
+			if strcmpi(md.snowpack.filters_ilwr_filter2,'MIN_MAX'), md=checkfield(md,'fieldname','snowpack.filters_ilwr_filter2','size',[1 NaN]); end
+			md=checkfield(md,'fieldname','snowpack.filters_ilwr_arg2','values',{filter_values});
+			if strcmpi(md.snowpack.filters_ilwr_arg2,'MIN_MAX'), md=checkfield(md,'fieldname','snowpack.filters_ilwr_arg2','size',[1 NaN]); end
+			md=checkfield(md,'fieldname','snowpack.filters_tss_filter1','values',{filter_values});
+			if strcmpi(md.snowpack.filters_tss_filter1,'MIN_MAX'), md=checkfield(md,'fieldname','snowpack.filters_tss_filter1','size',[1 NaN]); end
+			md=checkfield(md,'fieldname','snowpack.filters_tss_arg1','values',{filter_values});
+			if strcmpi(md.snowpack.filters_tss_arg1,'MIN_MAX'), md=checkfield(md,'fieldname','snowpack.filters_tss_arg1','size',[1 NaN]); end
+			md=checkfield(md,'fieldname','snowpack.filters_tsg_filter1','values',{filter_values});
+			if strcmpi(md.snowpack.filters_tsg_filter1,'MIN_MAX'), md=checkfield(md,'fieldname','snowpack.filters_tsg_filter1','size',[1 NaN]); end
+			md=checkfield(md,'fieldname','snowpack.filters_tsg_arg1','values',{filter_values});
+			if strcmpi(md.snowpack.filters_tsg_arg1,'MIN_MAX'), md=checkfield(md,'fieldname','snowpack.filters_tsg_arg1','size',[1 NaN]); end
+			md=checkfield(md,'fieldname','snowpack.filters_vw_filter1','values',{filter_values});
+			if strcmpi(md.snowpack.filters_vw_filter1,'MIN_MAX'), md=checkfield(md,'fieldname','snowpack.filters_vw_filter1','size',[1 NaN]); end
+			md=checkfield(md,'fieldname','snowpack.filters_vw_arg1','values',{filter_values});
+			if strcmpi(md.snowpack.filters_vw_arg1,'MIN_MAX'), md=checkfield(md,'fieldname','snowpack.filters_vw_arg1','size',[1 NaN]); end
+			md=checkfield(md,'fieldname','snowpack.filters_vw_filter2','values',{filter_values});
+			if strcmpi(md.snowpack.filters_vw_filter2,'MIN_MAX'), md=checkfield(md,'fieldname','snowpack.filters_vw_filter2','size',[1 NaN]); end
+			md=checkfield(md,'fieldname','snowpack.filters_vw_arg2','values',{filter_values});
+			if strcmpi(md.snowpack.filters_vw_arg2,'MIN_MAX'), md=checkfield(md,'fieldname','snowpack.filters_vw_arg2','size',[1 NaN]); end
 
 			%}}}
Index: /issm/trunk/src/m/classes/spheremesh.m
===================================================================
--- /issm/trunk/src/m/classes/spheremesh.m	(revision 17805)
+++ /issm/trunk/src/m/classes/spheremesh.m	(revision 17806)
@@ -13,5 +13,4 @@
 		phi                         = NaN
 		elements                    = NaN
-		dimension                   = 0;
 		numberoflayers              = 0;
 		numberofelements            = 0;
@@ -42,43 +41,19 @@
 		function md = checkconsistency(obj,md,solution,analyses) % {{{
 
-			md = checkfield(md,'spheremesh.x','NaN',1,'size',[md.spheremesh.numberofvertices 1]);
-			md = checkfield(md,'spheremesh.y','NaN',1,'size',[md.spheremesh.numberofvertices 1]);
-			md = checkfield(md,'spheremesh.z','NaN',1,'size',[md.spheremesh.numberofvertices 1]);
-			md = checkfield(md,'spheremesh.r','NaN',1,'size',[md.spheremesh.numberofvertices 1]);
-			md = checkfield(md,'spheremesh.theta','NaN',1,'size',[md.spheremesh.numberofvertices 1]);
-			md = checkfield(md,'spheremesh.phi','NaN',1,'size',[md.spheremesh.numberofvertices 1]);
-			md = checkfield(md,'spheremesh.elements','NaN',1,'>',0,'values',1:md.spheremesh.numberofvertices);
-			if(md.spheremesh.dimension==2),
-				md = checkfield(md,'spheremesh.elements','size',[md.spheremesh.numberofelements 3]);
-			else
-				md = checkfield(md,'spheremesh.elements','size',[md.spheremesh.numberofelements 6]);
-			end
+			md = checkfield(md,'fieldname','spheremesh.x','NaN',1,'size',[md.spheremesh.numberofvertices 1]);
+			md = checkfield(md,'fieldname','spheremesh.y','NaN',1,'size',[md.spheremesh.numberofvertices 1]);
+			md = checkfield(md,'fieldname','spheremesh.z','NaN',1,'size',[md.spheremesh.numberofvertices 1]);
+			md = checkfield(md,'fieldname','spheremesh.r','NaN',1,'size',[md.spheremesh.numberofvertices 1]);
+			md = checkfield(md,'fieldname','spheremesh.theta','NaN',1,'size',[md.spheremesh.numberofvertices 1]);
+			md = checkfield(md,'fieldname','spheremesh.phi','NaN',1,'size',[md.spheremesh.numberofvertices 1]);
+			md = checkfield(md,'fieldname','spheremesh.elements','NaN',1,'>',0,'values',1:md.spheremesh.numberofvertices);
+			md = checkfield(md,'fieldname','spheremesh.elements','size',[md.spheremesh.numberofelements 3]);
 			if any(~ismember(1:md.spheremesh.numberofvertices,sort(unique(md.spheremesh.elements(:)))));
 				md = checkmessage(md,'orphan nodes have been found. Check the spheremesh outline');
 			end
-			md = checkfield(md,'spheremesh.dimension','values',[2 3]);
-			md = checkfield(md,'spheremesh.numberoflayers','>=',0);
-			md = checkfield(md,'spheremesh.numberofelements','>',0);
-			md = checkfield(md,'spheremesh.numberofvertices','>',0);
-			if (md.spheremesh.dimension==2),
-				md = checkfield(md,'spheremesh.average_vertex_connectivity','>=',9,'message','''spheremesh.average_vertex_connectivity'' should be at least 9 in 2d');
-			else
-				md = checkfield(md,'spheremesh.average_vertex_connectivity','>=',24,'message','''spheremesh.average_vertex_connectivity'' should be at least 24 in 3d');
-			end
-			md = checkfield(md,'spheremesh.elementconnectivity','size',[md.spheremesh.numberofelements 3],'NaN',1);
-
-			%Solution specific checks
-			switch(solution),
-				case MasstransportSolutionEnum(),
-					if md.masstransport.stabilization==3,
-						md = checkfield(md,'spheremesh.dimension','values',2,'message','Discontinuous Galerkin only supported for 2d spheremeshes');
-					end
-				case TransientSolutionEnum(),
-					if md.transient.ismasstransport & md.masstransport.stabilization==3,
-						md = checkfield(md,'spheremesh.dimension','values',2,'message','Discontinuous Galerkin only supported for 2d spheremeshes');
-					end
-				case ThermalSolutionEnum(),
-					md = checkfield(md,'spheremesh.dimension','values',3,'message','thermal solution only supported on 3d spheremeshes');
-			end
+			md = checkfield(md,'fieldname','spheremesh.numberoflayers','>=',0);
+			md = checkfield(md,'fieldname','spheremesh.numberofelements','>',0);
+			md = checkfield(md,'fieldname','spheremesh.numberofvertices','>',0);
+			md = checkfield(md,'fieldname','spheremesh.elementconnectivity','size',[md.spheremesh.numberofelements 3],'NaN',1);
 		end % }}}
 		function disp(obj) % {{{
@@ -97,5 +72,4 @@
 
 			disp(sprintf('\n      Properties:'));
-			fielddisplay(obj,'dimension','spheremesh dimension (2d or 3d)');
 			fielddisplay(obj,'numberoflayers','number of extrusion layers');
 
@@ -113,5 +87,4 @@
 			WriteData(fid,'object',obj,'fieldname','phi','format','DoubleMat','mattype',1);
 			WriteData(fid,'object',obj,'fieldname','elements','format','DoubleMat','mattype',2);
-			WriteData(fid,'object',obj,'fieldname','dimension','format','Integer');
 			WriteData(fid,'object',obj,'fieldname','numberoflayers','format','Integer');
 			WriteData(fid,'object',obj,'fieldname','numberofelements','format','Integer');
Index: /issm/trunk/src/m/classes/steadystate.m
===================================================================
--- /issm/trunk/src/m/classes/steadystate.m	(revision 17805)
+++ /issm/trunk/src/m/classes/steadystate.m	(revision 17806)
@@ -11,4 +11,15 @@
 	end
 	methods
+        function createxml(obj,fid) % {{{
+            fprintf(fid, '<!-- steadystate -->\n');            
+                    
+            % steadystate solution parameters
+            fprintf(fid,'%s\n%s\n%s\n','<frame key="1" label="steadystate solution parameters">','<section name="steadystate" />');                    
+                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="reltol" type="',class(obj.reltol),'" default="',convert2str(obj.reltol),'">','     <section name="steadystate" />','     <help> relative tolerance criterion [K] </help>','  </parameter>');
+                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="maxiter" type="',class(obj.maxiter),'" default="',convert2str(obj.maxiter),'">','     <section name="steadystate" />','     <help> maximum number of iterations </help>','  </parameter>');
+                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="requested_outputs" type="',class(obj.requested_outputs),'" default="',convert2str(obj.requested_outputs),'">','     <section name="steadystate" />','     <help> additional requested outputs </help>','  </parameter>');
+            fprintf(fid,'%s\n%s\n','</frame>');    
+        
+        end % }}}
 		function obj = steadystate(varargin) % {{{
 			switch nargin
@@ -42,5 +53,5 @@
 				md = checkmessage(md,['for a steadystate computation, timestepping.time_step must be zero.']);
 			end
-			md = checkfield(md,'steadystate.requested_outputs','stringrow',1);
+			md = checkfield(md,'fieldname','steadystate.requested_outputs','stringrow',1);
 
 			if isnan(md.stressbalance.reltol),
Index: /issm/trunk/src/m/classes/steadystate.py
===================================================================
--- /issm/trunk/src/m/classes/steadystate.py	(revision 17805)
+++ /issm/trunk/src/m/classes/steadystate.py	(revision 17806)
@@ -2,6 +2,6 @@
 from fielddisplay import fielddisplay
 from EnumDefinitions import *
-from checkfield import *
-from WriteData import *
+from checkfield import checkfield
+from WriteData import WriteData
 
 class steadystate(object):
@@ -58,5 +58,5 @@
 			md.checkmessage("for a steadystate computation, stressbalance.reltol (relative convergence criterion) must be defined!")
 
-		md = checkfield(md,'steadystate.requested_outputs','stringrow',1)
+		md = checkfield(md,'fieldname','steadystate.requested_outputs','stringrow',1)
 
 		return md
Index: /issm/trunk/src/m/classes/stressbalance.m
===================================================================
--- /issm/trunk/src/m/classes/stressbalance.m	(revision 17805)
+++ /issm/trunk/src/m/classes/stressbalance.m	(revision 17806)
@@ -26,4 +26,42 @@
 	end
 	methods
+        function createxml(obj,fid) % {{{
+            fprintf(fid, '\n\n');
+            fprintf(fid, '%s\n', '<!-- StressBalance solution parameters: -->');
+            
+            % Convergence criteria            
+            fprintf(fid,'%s\n%s\n%s\n','<frame key="1" label="Convergence criteria">','<section name="stressbalance" />'); 
+			 fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="restol" type="',      class(obj.restol),'" default="',        convert2str(obj.restol),'">',	'     <section name="stressbalance" />','     <help> mechanical equilibrium residual convergence criterion </help>','</parameter>');
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="reltol" type="',          class(obj.reltol),'" default="',            convert2str(obj.reltol),'">',     '     <section name="stressbalance" />','     <help> velocity relative convergence criterion, NaN: not applied </help>','</parameter>');
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',	'<parameter key ="abstol" type="',        class(obj.abstol),'" default="',          convert2str(obj.abstol),'">',	'     <section name="stressbalance" />','     <help> velocity absolute convergence criterion, NaN: not applied </help>','</parameter>');
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="isnewton" type="',          class(obj.isnewton),'" default="',            convert2str(obj.isnewton),'">',	'     <section name="stressbalance" />','     <help> 0: Picards fixed point, 1: Newtons method, 2: hybrid </help>','</parameter>');
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="maxiter" type="',  	class(obj.maxiter),'" default="',       convert2str(obj.maxiter),'">',     '     <section name="stressbalance" />','     <help> maximum number of nonlinear iterations </help>','</parameter>');
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="viscosity_overshoot" type="',         class(obj.viscosity_overshoot),'" default="',           convert2str(obj.viscosity_overshoot),'">',	'     <section name="stressbalance" />','     <help> over-shooting constant new=new+C*(new-old) </help>','</parameter>');
+            fprintf(fid,'%s\n%s\n','</frame>');
+            
+            % boundary conditions    
+            fprintf(fid,'%s\n%s\n%s\n','<frame key="2" label="Boundary conditions">','<section name="stressbalance" />'); 			 
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="spcvx" type="',     	class(obj.spcvx),'" default="',    	convert2str(obj.spcvx),'">',     '     <section name="stressbalance" />','     <help> x-axis velocity constraint (NaN means no constraint) [m/yr] </help>','</parameter>');
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="spcvy" type="',     	class(obj.spcvy),'" default="',    	convert2str(obj.spcvy),'">',	'     <section name="stressbalance" />','     <help> y-axis velocity constraint (NaN means no constraint) [m/yr] </help>','</parameter>');
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="spcvz" type="',    	class(obj.spcvz),'" default="',    	convert2str(obj.spcvz),'">',     '     <section name="stressbalance" />','     <help> z-axis velocity constraint (NaN means no constraint) [m/yr] </help>','</parameter>');
+            fprintf(fid,'%s\n%s\n','</frame>');
+            
+            % Rift options   
+            fprintf(fid,'%s\n%s\n%s\n','<frame key="3" label="Rift options">','<section name="stressbalance" />'); 	
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="rift_penalty_threshold" type="',    	class(obj.rift_penalty_threshold),'" default="',       convert2str(obj.rift_penalty_threshold),'">',     '     <section name="stressbalance" />','     <help> threshold for instability of mechanical constraints </help>','</parameter>');
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    	'<parameter key ="rift_penalty_lock" type="',         class(obj.rift_penalty_lock),'" default="',           convert2str(obj.rift_penalty_lock),'">',	'     <section name="stressbalance" />','     <help> number of iterations before rift penalties are locked </help>','</parameter>');
+            fprintf(fid,'%s\n%s\n','</frame>'); 
+            
+            %others
+            fprintf(fid,'%s\n%s\n%s\n','<frame key="4" label="Other">','<section name="stressbalance" />'); 	
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="shelf_dampening" type="',  	class(obj.shelf_dampening),'" default="',       convert2str(obj.shelf_dampening),'">',     '     <section name="stressbalance" />','     <help> use dampening for floating ice ? Only for FS model </help>','</parameter>');
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',  	'<parameter key ="FSreconditioning" type="', 	class(obj.FSreconditioning),'" default="',           convert2str(obj.FSreconditioning),'">',	'     <section name="stressbalance" />','     <help> multiplier for incompressibility equation. Only for FS model </help>','</parameter>');
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="referential" type="',  	class(obj.referential),'" default="',       convert2str(obj.referential),'">',     '     <section name="stressbalance" />','     <help> local referential </help>','</parameter>');
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',  	'<parameter key ="loadingforce" type="', 	class(obj.loadingforce),'" default="',           convert2str(obj.loadingforce),'">',	'     <section name="stressbalance" />','     <help> loading force applied on each point [N/m^3] </help>','</parameter>');
+             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="requested_outputs" type="',  	class(obj.requested_outputs),'" default="',       convert2str(obj.requested_outputs),'">',     '     <section name="stressbalance" />','     <help> additional outputs requested </help>','</parameter>');
+             
+            
+            fprintf(fid,'%s\n%s\n','</frame>'); 
+        end % }}}
 		function obj = stressbalance(varargin) % {{{
 			switch nargin
@@ -82,17 +120,17 @@
 			if ~ismember(StressbalanceAnalysisEnum(),analyses), return; end
 
-			md = checkfield(md,'stressbalance.spcvx','forcing',1);
-			md = checkfield(md,'stressbalance.spcvy','forcing',1);
-			md = checkfield(md,'stressbalance.spcvz','forcing',1);
-			md = checkfield(md,'stressbalance.restol','size',[1 1],'>',0,'NaN',1);
-			md = checkfield(md,'stressbalance.reltol','size',[1 1]);
-			md = checkfield(md,'stressbalance.abstol','size',[1 1]);
-			md = checkfield(md,'stressbalance.isnewton','numel',[1],'values',[0 1 2]);
-			md = checkfield(md,'stressbalance.FSreconditioning','size',[1 1],'NaN',1);
-			md = checkfield(md,'stressbalance.viscosity_overshoot','size',[1 1],'NaN',1);
-			md = checkfield(md,'stressbalance.maxiter','size',[1 1],'>=',1);
-			md = checkfield(md,'stressbalance.referential','size',[md.mesh.numberofvertices 6]);
-			md = checkfield(md,'stressbalance.loadingforce','size',[md.mesh.numberofvertices 3]);
-			md = checkfield(md,'stressbalance.requested_outputs','stringrow',1);
+			md = checkfield(md,'fieldname','stressbalance.spcvx','forcing',1);
+			md = checkfield(md,'fieldname','stressbalance.spcvy','forcing',1);
+			md = checkfield(md,'fieldname','stressbalance.spcvz','forcing',1);
+			md = checkfield(md,'fieldname','stressbalance.restol','size',[1 1],'>',0,'NaN',1);
+			md = checkfield(md,'fieldname','stressbalance.reltol','size',[1 1]);
+			md = checkfield(md,'fieldname','stressbalance.abstol','size',[1 1]);
+			md = checkfield(md,'fieldname','stressbalance.isnewton','numel',[1],'values',[0 1 2]);
+			md = checkfield(md,'fieldname','stressbalance.FSreconditioning','size',[1 1],'NaN',1);
+			md = checkfield(md,'fieldname','stressbalance.viscosity_overshoot','size',[1 1],'NaN',1);
+			md = checkfield(md,'fieldname','stressbalance.maxiter','size',[1 1],'>=',1);
+			md = checkfield(md,'fieldname','stressbalance.referential','size',[md.mesh.numberofvertices 6]);
+			md = checkfield(md,'fieldname','stressbalance.loadingforce','size',[md.mesh.numberofvertices 3]);
+			md = checkfield(md,'fieldname','stressbalance.requested_outputs','stringrow',1);
 
 			%singular solution
@@ -112,19 +150,17 @@
 			end
 			%CHECK THAT NO rotation specified for FS Grounded ice at base
-			if strcmp(meshtype(md.mesh),'3D') & md.flowequation.isFS,
-				pos=find(md.mask.groundedice_levelset>0. & md.mesh.vertexonbed);
+			if strcmp(domaintype(md.mesh),'3D') & md.flowequation.isFS,
+				pos=find(md.mask.groundedice_levelset>0. & md.mesh.vertexonbase);
 				if any(~isnan(md.stressbalance.referential(pos,:))),
 					md = checkmessage(md,['no referential should be specified for basal vertices of grounded ice']);
 				end
-				md = checkfield(md,'stressbalance.FSreconditioning','>',0);
+				md = checkfield(md,'fieldname','stressbalance.FSreconditioning','>',0);
 			end
 		end % }}}
 		function list=defaultoutputs(self,md) % {{{
 
-			if strcmp(meshtype(md.mesh),'3D'),
+			if dimension(md.mesh)==3,
 				list = {'Vx','Vy','Vz','Vel','Pressure'};
-			elseif strcmp(meshtype(md.mesh),'2Dhorizontal'),
-				list = {'Vx','Vy','Vel','Pressure'};
-			elseif strcmp(meshtype(md.mesh),'2Dvertical'),
+			elseif dimension(md.mesh)==2,
 				list = {'Vx','Vy','Vel','Pressure'};
 			else
Index: /issm/trunk/src/m/classes/stressbalance.py
===================================================================
--- /issm/trunk/src/m/classes/stressbalance.py	(revision 17805)
+++ /issm/trunk/src/m/classes/stressbalance.py	(revision 17806)
@@ -4,7 +4,7 @@
 from fielddisplay import fielddisplay
 from EnumDefinitions import *
-from checkfield import *
-from WriteData import *
-from MatlabFuncs import *
+from checkfield import checkfield
+from WriteData import WriteData
+import MatlabFuncs as m
 
 class stressbalance(object):
@@ -110,12 +110,8 @@
 	def defaultoutputs(self,md): # {{{
 
-		if strcmp(md.mesh.meshtype(),'3D'):
+		if md.mesh.dimension()==3:
 			list = ['Vx','Vy','Vz','Vel','Pressure']
-		elif strcmp(md.mesh.meshtype(),'2Dhorizontal'):
+		else:
 			list = ['Vx','Vy','Vel','Pressure']
-		elif strcmp(md.mesh.meshtype(),'2Dvertical'):
-			list = ['Vx','Vy','Vel','Pressure']
-		else:
-			raise TypeError('mesh type not supported yet');
 		return list
 
@@ -127,18 +123,18 @@
 			return md
 
-		md = checkfield(md,'stressbalance.spcvx','forcing',1)
-		md = checkfield(md,'stressbalance.spcvy','forcing',1)
-		if strcmp(md.mesh.meshtype(),'3D'):
-			md = checkfield(md,'stressbalance.spcvz','forcing',1)
-		md = checkfield(md,'stressbalance.restol','size',[1],'>',0)
-		md = checkfield(md,'stressbalance.reltol','size',[1])
-		md = checkfield(md,'stressbalance.abstol','size',[1])
-		md = checkfield(md,'stressbalance.isnewton','numel',[1],'values',[0,1,2])
-		md = checkfield(md,'stressbalance.FSreconditioning','size',[1],'NaN',1)
-		md = checkfield(md,'stressbalance.viscosity_overshoot','size',[1],'NaN',1)
-		md = checkfield(md,'stressbalance.maxiter','size',[1],'>=',1)
-		md = checkfield(md,'stressbalance.referential','size',[md.mesh.numberofvertices,6])
-		md = checkfield(md,'stressbalance.loadingforce','size',[md.mesh.numberofvertices,3])
-		md = checkfield(md,'stressbalance.requested_outputs','stringrow',1);
+		md = checkfield(md,'fieldname','stressbalance.spcvx','forcing',1)
+		md = checkfield(md,'fieldname','stressbalance.spcvy','forcing',1)
+		if m.strcmp(md.mesh.domaintype(),'3D'):
+			md = checkfield(md,'fieldname','stressbalance.spcvz','forcing',1)
+		md = checkfield(md,'fieldname','stressbalance.restol','size',[1],'>',0)
+		md = checkfield(md,'fieldname','stressbalance.reltol','size',[1])
+		md = checkfield(md,'fieldname','stressbalance.abstol','size',[1])
+		md = checkfield(md,'fieldname','stressbalance.isnewton','numel',[1],'values',[0,1,2])
+		md = checkfield(md,'fieldname','stressbalance.FSreconditioning','size',[1],'NaN',1)
+		md = checkfield(md,'fieldname','stressbalance.viscosity_overshoot','size',[1],'NaN',1)
+		md = checkfield(md,'fieldname','stressbalance.maxiter','size',[1],'>=',1)
+		md = checkfield(md,'fieldname','stressbalance.referential','size',[md.mesh.numberofvertices,6])
+		md = checkfield(md,'fieldname','stressbalance.loadingforce','size',[md.mesh.numberofvertices,3])
+		md = checkfield(md,'fieldname','stressbalance.requested_outputs','stringrow',1);
 
 		#singular solution
@@ -161,6 +157,6 @@
 					md.checkmessage("Vectors in stressbalance.referential (columns 1 to 3 and 4 to 6) must be orthogonal")
 		#CHECK THAT NO rotation specified for FS Grounded ice at base
-		if strcmp(md.mesh.meshtype(),'3D') and md.flowequation.isFS:
-			pos=numpy.nonzero(numpy.logical_and(md.mask.groundedice_levelset,md.mesh.vertexonbed))
+		if m.strcmp(md.mesh.domaintype(),'3D') and md.flowequation.isFS:
+			pos=numpy.nonzero(numpy.logical_and(md.mask.groundedice_levelset,md.mesh.vertexonbase))
 			if numpy.any(numpy.logical_not(numpy.isnan(md.stressbalance.referential[pos,:]))):
 				md.checkmessage("no referential should be specified for basal vertices of grounded ice")
Index: sm/trunk/src/m/classes/surfaceforcings.m
===================================================================
--- /issm/trunk/src/m/classes/surfaceforcings.m	(revision 17805)
+++ 	(revision )
@@ -1,133 +1,0 @@
-%SURFACEFORCING Class definition
-%
-%   Usage:
-%      surfaceforcings=surfaceforcings();
-
-classdef surfaceforcings
-	properties (SetAccess=public) 
-		precipitation             = NaN;
-		mass_balance              = NaN;
-		ispdd                     = 0;
-		issmbgradients            = 0;
-		isdelta18o                = 0;
-		href                      = NaN;
-		smbref                    = NaN;
-		b_pos                     = NaN;
-		b_neg                     = NaN;
-		monthlytemperatures       = NaN;
-		delta18o                  = NaN;
-		delta18o_surface          = NaN;
-		temperatures_presentday   = NaN;
-		temperatures_lgm          = NaN;
-		precipitations_presentday = NaN;
-		desfac                    = 0.5;
-		s0p                       = 0;
-	end
-	methods
-		function obj = surfaceforcings(varargin) % {{{
-			switch nargin
-				case 0
-					obj=setdefaultparameters(obj);
-				otherwise
-					error('constructor not supported');
-			end
-		end % }}}
-		function obj = setdefaultparameters(obj) % {{{
-
-		  %pdd method not used in default mode
-		  obj.ispdd=0;
-		  obj.issmbgradients=0;
-		  obj.isdelta18o=0;
-		  obj.desfac=0.5;
-		  obj.s0p=0;
-		end % }}}
-		function md = checkconsistency(obj,md,solution,analyses) % {{{
-
-			if ismember(MasstransportAnalysisEnum(),analyses),
-				md = checkfield(md,'surfaceforcings.ispdd','numel',[1],'values',[0 1]);
-				md = checkfield(md,'surfaceforcings.issmbgradients','numel',[1],'values',[0 1]);
-				if(obj.ispdd)
-				  md = checkfield(md,'surfaceforcings.desfac','<=',1,'numel',1);
-				  md = checkfield(md,'surfaceforcings.s0p','>=',0,'numel',1);
-					if(obj.isdelta18o==0)
-						md = checkfield(md,'surfaceforcings.monthlytemperatures','forcing',1,'NaN',1);
-						md = checkfield(md,'surfaceforcings.precipitation','forcing',1,'NaN',1);
-					else
-						md = checkfield(md,'surfaceforcings.delta18o','NaN',1);
-						md = checkfield(md,'surfaceforcings.delta18o_surface','NaN',1);
-						md = checkfield(md,'surfaceforcings.temperatures_presentday','size',[md.mesh.numberofvertices+1 12],'NaN',1);
-						md = checkfield(md,'surfaceforcings.temperatures_lgm','size',[md.mesh.numberofvertices+1 12],'NaN',1);
-						md = checkfield(md,'surfaceforcings.precipitations_presentday','size',[md.mesh.numberofvertices+1 12],'NaN',1);
-					end
-				elseif(obj.issmbgradients)
-					md = checkfield(md,'surfaceforcings.href','forcing',1,'NaN',1);
-					md = checkfield(md,'surfaceforcings.smbref','forcing',1,'NaN',1);
-					md = checkfield(md,'surfaceforcings.b_pos','forcing',1,'NaN',1);
-					md = checkfield(md,'surfaceforcings.b_neg','forcing',1,'NaN',1);
-				else
-					md = checkfield(md,'surfaceforcings.mass_balance','forcing',1,'NaN',1);
-				end
-			end
-			if ismember(BalancethicknessAnalysisEnum(),analyses),
-				md = checkfield(md,'surfaceforcings.mass_balance','size',[md.mesh.numberofvertices 1],'NaN',1);
-			end
-		end % }}}
-		function disp(obj) % {{{
-			disp(sprintf('   surface forcings parameters:'));
-
-			disp(sprintf('\n   General parameters:'));
-			fielddisplay(obj,'mass_balance','surface mass balance [m/yr ice eq]');
-
-			disp(sprintf('\n   PDD and deltaO18 parameters:'));
-			fielddisplay(obj,'ispdd','is pdd activated (0 or 1, default is 0)');
-			fielddisplay(obj,'isdelta18o','is temperature and precipitation delta18o parametrisation activated (0 or 1, default is 0)');
-			fielddisplay(obj,'desfac','desertification elevation factor (between 0 and 1, default is 0.5) [m]');
-			fielddisplay(obj,'s0p','should be set to elevation from precip source (between 0 and a few 1000s m, default is 0) [m]');
-			fielddisplay(obj,'monthlytemperatures','monthly surface temperatures [K], required if pdd is activated and delta18o not activated');
-			fielddisplay(obj,'precipitation','surface precipitation [m/yr water eq]');
-			fielddisplay(obj,'temperatures_presentday','monthly present day surface temperatures [K], required if pdd is activated and delta18o activated');
-			fielddisplay(obj,'temperatures_lgm','monthly LGM surface temperatures [K], required if pdd is activated and delta18o activated');
-			fielddisplay(obj,'precipitations_presentday','monthly surface precipitation [m/yr water eq], required if pdd is activated and delta18o activated');
-			fielddisplay(obj,'delta18o','delta18o, required if pdd is activated and delta18o activated');
-			fielddisplay(obj,'delta18o_surface','surface elevation of the delta18o site, required if pdd is activated and delta18o activated');
-
-			disp(sprintf('\n   SMB gradients parameters:'));
-			fielddisplay(obj,'issmbgradients','is smb gradients method activated (0 or 1, default is 0)');
-			fielddisplay(obj,'href',' reference elevation from which deviation is used to calculate SMB adjustment in smb gradients method');
-			fielddisplay(obj,'smbref',' reference smb from which deviation is calculated in smb gradients method');
-			fielddisplay(obj,'b_pos',' slope of hs - smb regression line for accumulation regime required if smb gradients is activated');
-			fielddisplay(obj,'b_neg',' slope of hs - smb regression line for ablation regime required if smb gradients is activated');
-
-		end % }}}
-		function marshall(obj,md,fid) % {{{
-
-			yts=365.0*24.0*3600.0;
-
-			WriteData(fid,'object',obj,'fieldname','precipitation','format','DoubleMat','mattype',1,'scale',1./yts,'forcinglength',md.mesh.numberofvertices+1);
-			WriteData(fid,'object',obj,'fieldname','mass_balance','format','DoubleMat','mattype',1,'scale',1./yts,'forcinglength',md.mesh.numberofvertices+1);
-			WriteData(fid,'object',obj,'fieldname','ispdd','format','Boolean');
-			WriteData(fid,'object',obj,'fieldname','isdelta18o','format','Boolean');
-			if obj.ispdd,
-				WriteData(fid,'object',obj,'fieldname','desfac','format','Double');
-				WriteData(fid,'object',obj,'fieldname','s0p','format','Double');
-				if obj.isdelta18o
-					WriteData(fid,'object',obj,'fieldname','temperatures_presentday','format','DoubleMat','mattype',1);
-					WriteData(fid,'object',obj,'fieldname','temperatures_lgm','format','DoubleMat','mattype',1);
-					WriteData(fid,'object',obj,'fieldname','precipitations_presentday','format','DoubleMat','mattype',1);
-					WriteData(fid,'object',obj,'fieldname','delta18o_surface','format','DoubleMat','mattype',1);
-					WriteData(fid,'object',obj,'fieldname','delta18o','format','DoubleMat','mattype',1);
-				else
-					WriteData(fid,'object',obj,'fieldname','monthlytemperatures','format','DoubleMat','mattype',1,'forcinglength',md.mesh.numberofvertices+1);
-				end
-			end
-			WriteData(fid,'object',obj,'fieldname','issmbgradients','format','Boolean');
-			if obj.issmbgradients,
-				WriteData(fid,'object',obj,'fieldname','href','format','DoubleMat','mattype',1,'forcinglength',md.mesh.numberofvertices+1);
-				WriteData(fid,'object',obj,'fieldname','smbref','format','DoubleMat','mattype',1,'scale',1./yts,'forcinglength',md.mesh.numberofvertices+1);
-				WriteData(fid,'object',obj,'fieldname','b_pos','format','DoubleMat','mattype',1,'scale',1./yts,'forcinglength',md.mesh.numberofvertices+1);
-				WriteData(fid,'object',obj,'fieldname','b_neg','format','DoubleMat','mattype',1,'scale',1./yts,'forcinglength',md.mesh.numberofvertices+1);
-			end
-
-		end % }}}
-	end
-end
Index: sm/trunk/src/m/classes/surfaceforcings.py
===================================================================
--- /issm/trunk/src/m/classes/surfaceforcings.py	(revision 17805)
+++ 	(revision )
@@ -1,130 +1,0 @@
-from fielddisplay import fielddisplay
-from EnumDefinitions import *
-from checkfield import *
-from WriteData import *
-
-class surfaceforcings(object):
-	"""
-	SURFACEFORCING Class definition
-
-	   Usage:
-	      surfaceforcings=surfaceforcings();
-	"""
-
-	def __init__(self): # {{{
-		self.precipitation             = float('NaN')
-		self.mass_balance              = float('NaN')
-		self.ispdd                     = 0
-		self.issmbgradients            = 0
-		self.isdelta18o                = 0
-		self.href                      = float('NaN')
-		self.smbref                    = float('NaN')
-		self.b_pos                     = float('NaN')
-		self.b_neg                     = float('NaN')
-		self.monthlytemperatures       = float('NaN')
-		self.delta18o                  = float('NaN')
-		self.delta18o_surface          = float('NaN')
-		self.temperatures_presentday   = float('NaN')
-		self.temperatures_lgm          = float('NaN')
-		self.precipitations_presentday = float('NaN')
-		self.desfac                    = 0.
-		self.s0p                       = 0.
-
-		#set defaults
-		self.setdefaultparameters()
-
-		#}}}
-	def __repr__(self): # {{{
-		string="   surface forcings parameters:"
-
-		string="%s\n%s"%(string,fielddisplay(self,'precipitation','surface precipitation [m/yr water eq]'))
-		string="%s\n%s"%(string,fielddisplay(self,'mass_balance','surface mass balance [m/yr ice eq]'))
-		string="%s\n%s"%(string,fielddisplay(self,'ispdd','is pdd activated (0 or 1, default is 0)'))
-		string="%s\n%s"%(string,fielddisplay(self,'desfac','desertification elevation factor (between 0 and 1, default is 0.5) [m]'))
-		string="%s\n%s"%(string,fielddisplay(self,'isdelta18o','is temperature and precipitation delta18o parametrisation activated (0 or 1, default is 0)'))
-		string="%s\n%s"%(string,fielddisplay(self,'s0p','should be set to elevation from precip source (between 0 and a few 1000s m, default is 0) [m]'))
-		string="%s\n%s"%(string,fielddisplay(self,'monthlytemperatures','monthly surface temperatures [K], required if pdd is activated and delta18o not activated'))
-		string="%s\n%s"%(string,fielddisplay(self,'precipitation','surface precipitation [m/yr water eq]'))
-		string="%s\n%s"%(string,fielddisplay(self,'temperatures_presentday','monthly present day surface temperatures [K], required if pdd is activated and delta18o activated'))
-		string="%s\n%s"%(string,fielddisplay(self,'temperatures_lgm','monthly LGM surface temperatures [K], required if pdd is activated and delta18o activated'))
-		string="%s\n%s"%(string,fielddisplay(self,'precipitations_presentday','monthly surface precipitation [m/yr water eq], required if pdd is activated and delta18o activated'))
-		string="%s\n%s"%(string,fielddisplay(self,'delta18o','delta18o, required if pdd is activated and delta18o activated'))
-		string="%s\n%s"%(string,fielddisplay(self,'delta18o_surface','surface elevation of the delta18o site, required if pdd is activated and delta18o activated'))
-		string="%s\n%s"%(string,fielddisplay(self,'issmbgradients','is smb gradients method activated (0 or 1, default is 0)'))
-		string="%s\n%s"%(string,fielddisplay(self,'href',' reference elevation from which deviation is used to calculate SMB adjustment in smb gradients method'))
-		string="%s\n%s"%(string,fielddisplay(self,'smbref',' reference smb from which deviation is calculated in smb gradients method'))
-		string="%s\n%s"%(string,fielddisplay(self,'b_pos',' slope of hs - smb regression line for accumulation regime required if smb gradients is activated'))
-		string="%s\n%s"%(string,fielddisplay(self,'b_neg',' slope of hs - smb regression line for ablation regime required if smb gradients is activated'))
-
-		return string
-		#}}}
-	def setdefaultparameters(self): # {{{
-		  
-		#pdd method not used in default mode
-		self.ispdd=0
-		self.issmbgradients=0
-		self.isdelta18o=0
-		self.desfac=0.5
-		self.s0p=0.
-
-		return self
-	#}}}
-	def checkconsistency(self,md,solution,analyses):    # {{{
-
-		if MasstransportAnalysisEnum() in analyses:
-			md = checkfield(md,'surfaceforcings.ispdd','numel',[1],'values',[0,1])
-			md = checkfield(md,'surfaceforcings.issmbgradients','numel',[1],'values',[0,1])
-			if   self.ispdd:
-				md = checkfield(md,'surfaceforcings.desfac','<=',1,'numel',[1]);
-				md = checkfield(md,'surfaceforcings.s0p','>=',0,'numel',[1]);
-				if not self.isdelta18o:
-					md = checkfield(md,'surfaceforcings.monthlytemperatures','forcing',1,'NaN',1)
-					md = checkfield(md,'surfaceforcings.precipitation','forcing',1,'NaN',1)
-				else:
-					md = checkfield(md,'surfaceforcings.delta18o','NaN',1)
-					md = checkfield(md,'surfaceforcings.delta18o_surface','NaN',1)
-					md = checkfield(md,'surfaceforcings.temperatures_presentday','size',[md.mesh.numberofvertices+1,12],'NaN',1)
-					md = checkfield(md,'surfaceforcings.temperatures_lgm','size',[md.mesh.numberofvertices+1,12],'NaN',1)
-					md = checkfield(md,'surfaceforcings.precipitations_presentday','size',[md.mesh.numberofvertices+1,12],'NaN',1)
-			elif self.issmbgradients:
-				md = checkfield(md,'surfaceforcings.href','forcing',1,'NaN',1)
-				md = checkfield(md,'surfaceforcings.smbref','forcing',1,'NaN',1)
-				md = checkfield(md,'surfaceforcings.b_pos','forcing',1,'NaN',1)
-				md = checkfield(md,'surfaceforcings.b_neg','forcing',1,'NaN',1)
-			else:
-				md = checkfield(md,'surfaceforcings.mass_balance','forcing',1,'NaN',1)
-
-		if BalancethicknessAnalysisEnum() in analyses:
-			md = checkfield(md,'surfaceforcings.mass_balance','size',[md.mesh.numberofvertices],'NaN',1)
-
-		return md
-	# }}}
-	def marshall(self,md,fid):    # {{{
-
-		yts=365.0*24.0*3600.0
-
-		WriteData(fid,'object',self,'fieldname','precipitation','format','DoubleMat','mattype',1,'scale',1./yts,'forcinglength',md.mesh.numberofvertices+1)
-		WriteData(fid,'object',self,'fieldname','mass_balance','format','DoubleMat','mattype',1,'scale',1./yts,'forcinglength',md.mesh.numberofvertices+1)
-		WriteData(fid,'object',self,'fieldname','ispdd','format','Boolean')
-		WriteData(fid,'object',self,'fieldname','isdelta18o','format','Boolean')
-
-		if self.ispdd:
-			WriteData(fid,'object',self,'fieldname','desfac','format','Double');
-			WriteData(fid,'object',self,'fieldname','s0p','format','Double');
-			if self.isdelta18o:
-				WriteData(fid,'object',self,'fieldname','temperatures_presentday','format','DoubleMat','mattype',1)
-				WriteData(fid,'object',self,'fieldname','temperatures_lgm','format','DoubleMat','mattype',1)
-				WriteData(fid,'object',self,'fieldname','precipitations_presentday','format','DoubleMat','mattype',1)
-				WriteData(fid,'object',self,'fieldname','delta18o_surface','format','DoubleMat','mattype',1)
-				WriteData(fid,'object',self,'fieldname','delta18o','format','DoubleMat','mattype',1)
-			else:
-				WriteData(fid,'object',self,'fieldname','monthlytemperatures','format','DoubleMat','mattype',1,'forcinglength',md.mesh.numberofvertices+1)
-
-		WriteData(fid,'object',self,'fieldname','issmbgradients','format','Boolean')
-
-		if self.issmbgradients:
-			WriteData(fid,'object',self,'fieldname','href','format','DoubleMat','mattype',1,'forcinglength',md.mesh.numberofvertices+1)
-			WriteData(fid,'object',self,'fieldname','smbref','format','DoubleMat','mattype',1,'scale',1./yts,'forcinglength',md.mesh.numberofvertices+1)
-			WriteData(fid,'object',self,'fieldname','b_pos','format','DoubleMat','mattype',1,'scale',1./yts,'forcinglength',md.mesh.numberofvertices+1)
-			WriteData(fid,'object',self,'fieldname','b_neg','format','DoubleMat','mattype',1,'scale',1./yts,'forcinglength',md.mesh.numberofvertices+1)
-	# }}}
Index: /issm/trunk/src/m/classes/taoinversion.m
===================================================================
--- /issm/trunk/src/m/classes/taoinversion.m	(revision 17805)
+++ /issm/trunk/src/m/classes/taoinversion.m	(revision 17806)
@@ -75,21 +75,21 @@
 			num_costfunc=size(md.inversion.cost_functions,2);
 
-			md = checkfield(md,'inversion.iscontrol','values',[0 1]);
-			md = checkfield(md,'inversion.incomplete_adjoint','values',[0 1]);
-			md = checkfield(md,'inversion.control_parameters','cell',1,'values',...
+			md = checkfield(md,'fieldname','inversion.iscontrol','values',[0 1]);
+			md = checkfield(md,'fieldname','inversion.incomplete_adjoint','values',[0 1]);
+			md = checkfield(md,'fieldname','inversion.control_parameters','cell',1,'values',...
 				{'BalancethicknessThickeningRate' 'FrictionCoefficient' 'MaterialsRheologyBbar' 'MaterialsRheologyZbar' 'Vx' 'Vy' 'Thickness'});
-			md = checkfield(md,'inversion.nsteps','numel',1,'>=',0);
-			md = checkfield(md,'inversion.cost_functions','size',[1 num_costfunc],'values',[101:105 201 501:506]);
-			md = checkfield(md,'inversion.cost_functions_coefficients','size',[md.mesh.numberofvertices num_costfunc],'>=',0);
-			md = checkfield(md,'inversion.min_parameters','size',[md.mesh.numberofvertices num_controls]);
-			md = checkfield(md,'inversion.max_parameters','size',[md.mesh.numberofvertices num_controls]);
+			md = checkfield(md,'fieldname','inversion.nsteps','numel',1,'>=',0);
+			md = checkfield(md,'fieldname','inversion.cost_functions','size',[1 num_costfunc],'values',[101:105 201 501:506]);
+			md = checkfield(md,'fieldname','inversion.cost_functions_coefficients','size',[md.mesh.numberofvertices num_costfunc],'>=',0);
+			md = checkfield(md,'fieldname','inversion.min_parameters','size',[md.mesh.numberofvertices num_controls]);
+			md = checkfield(md,'fieldname','inversion.max_parameters','size',[md.mesh.numberofvertices num_controls]);
 
 			if solution==BalancethicknessSolutionEnum()
-				md = checkfield(md,'inversion.thickness_obs','size',[md.mesh.numberofvertices 1],'NaN',1);
+				md = checkfield(md,'fieldname','inversion.thickness_obs','size',[md.mesh.numberofvertices 1],'NaN',1);
 			elseif solution==BalancethicknessSoftSolutionEnum()
-				md = checkfield(md,'inversion.thickness_obs','size',[md.mesh.numberofvertices 1],'NaN',1);
+				md = checkfield(md,'fieldname','inversion.thickness_obs','size',[md.mesh.numberofvertices 1],'NaN',1);
 			else
-				md = checkfield(md,'inversion.vx_obs','size',[md.mesh.numberofvertices 1],'NaN',1);
-				md = checkfield(md,'inversion.vy_obs','size',[md.mesh.numberofvertices 1],'NaN',1);
+				md = checkfield(md,'fieldname','inversion.vx_obs','size',[md.mesh.numberofvertices 1],'NaN',1);
+				md = checkfield(md,'fieldname','inversion.vy_obs','size',[md.mesh.numberofvertices 1],'NaN',1);
 			end
 		end % }}}
Index: /issm/trunk/src/m/classes/thermal.m
===================================================================
--- /issm/trunk/src/m/classes/thermal.m	(revision 17805)
+++ /issm/trunk/src/m/classes/thermal.m	(revision 17806)
@@ -17,4 +17,21 @@
 	end
 	methods
+        function createxml(obj,fid) % {{{
+            fprintf(fid, '<!-- thermal -->\n');            
+                    
+            % thermal solution parameters
+            fprintf(fid,'%s\n%s\n%s\n','<frame key="1" label="Thermal solution parameters">','<section name="thermal" />');                    
+                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="spctemperature" type="',class(obj.spctemperature),'" default="',convert2str(obj.spctemperature),'">','     <section name="thermal" />','     <help> temperature constraints (NaN means no constraint) [K] </help>','  </parameter>');
+                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="penalty_threshold" type="',class(obj.penalty_threshold),'" default="',convert2str(obj.penalty_threshold),'">','     <section name="thermal" />','     <help> 0: no, 1: artificial_diffusivity, 2: SUPG </help>','  </parameter>');
+                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="stabilization" type="',class(obj.stabilization),'" default="',convert2str(obj.stabilization),'">','     <section name="thermal" />','     <help> maximum number of non linear iterations </help>','  </parameter>');
+                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="maxiter" type="',class(obj.maxiter),'" default="',convert2str(obj.maxiter),'">','     <section name="thermal" />','     <help> stabilize unstable thermal constraints that keep zigzagging after n iteration (default is 0, no stabilization) </help>','  </parameter>');
+                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="penalty_lock" type="',class(obj.penalty_lock),'" default="',convert2str(obj.penalty_lock),'">','     <section name="thermal" />','     <help> threshold to declare convergence of thermal solution (default is 0)  </help>','  </parameter>');
+                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="penalty_factor" type="',class(obj.penalty_factor),'" default="',convert2str(obj.penalty_factor),'">','     <section name="thermal" />','     <help> scaling exponent (default is 3) </help>','  </parameter>');
+                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="isenthalpy" type="',class(obj.isenthalpy),'" default="',convert2str(obj.isenthalpy),'">','     <section name="thermal" />','     <help> use an enthalpy formulation to include temperate ice (default is 0) </help>','  </parameter>');
+                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="isdynamicbasalspc" type="',class(obj.isdynamicbasalspc),'" default="',convert2str(obj.isdynamicbasalspc),'">','     <section name="thermal" />','     <help> enable dynamic setting of basal forcing. required for enthalpy formulation (default is 0)  </help>','  </parameter>');
+                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="requested_outputs" type="',class(obj.requested_outputs),'" default="',convert2str(obj.requested_outputs),'">','     <section name="thermal" />','     <help> additional outputs requested </help>','  </parameter>');
+            fprintf(fid,'%s\n%s\n','</frame>');    
+        
+        end % }}}
 		function obj = thermal(varargin) % {{{
 			switch nargin
@@ -62,18 +79,18 @@
 			if (~ismember(ThermalAnalysisEnum(),analyses) & ~ismember(EnthalpyAnalysisEnum(),analyses)) | (solution==TransientSolutionEnum() & md.transient.isthermal==0), return; end
 
-			md = checkfield(md,'thermal.stabilization','numel',[1],'values',[0 1 2]);
-			md = checkfield(md,'thermal.spctemperature','forcing',1);
-			if (ismember(EnthalpyAnalysisEnum(),analyses) & md.thermal.isenthalpy & md.mesh.dimension==3),
+			md = checkfield(md,'fieldname','thermal.stabilization','numel',[1],'values',[0 1 2]);
+			md = checkfield(md,'fieldname','thermal.spctemperature','forcing',1);
+			if (ismember(EnthalpyAnalysisEnum(),analyses) & md.thermal.isenthalpy & dimension(md.mesh)==3),
 				pos=find(md.thermal.spctemperature(1:md.mesh.numberofvertices,:)~=NaN);
 				replicate=repmat(md.geometry.surface-md.mesh.z,1,size(md.thermal.spctemperature,2));
-				md = checkfield(md,'thermal.spctemperature(find(md.thermal.spctemperature(1:md.mesh.numberofvertices,:)~=NaN))','<',md.materials.meltingpoint-md.materials.beta*md.materials.rho_ice*md.constants.g*replicate(pos),'message','spctemperature should be below the adjusted melting point');
-				md = checkfield(md,'thermal.isenthalpy','numel',[1],'values',[0 1]);
-				md = checkfield(md,'thermal.isdynamicbasalspc','numel', [1],'values',[0 1]);
+				md = checkfield(md,'fieldname','thermal.spctemperature(find(md.thermal.spctemperature(1:md.mesh.numberofvertices,:)~=NaN))','<',md.materials.meltingpoint-md.materials.beta*md.materials.rho_ice*md.constants.g*replicate(pos),'message','spctemperature should be below the adjusted melting point');
+				md = checkfield(md,'fieldname','thermal.isenthalpy','numel',[1],'values',[0 1]);
+				md = checkfield(md,'fieldname','thermal.isdynamicbasalspc','numel', [1],'values',[0 1]);
 				if(md.thermal.isenthalpy)
-					md = checkfield(md,'thermal.isdynamicbasalspc','numel', [1],'values',[1], 'message',['for enthalpy run thermal.isdynamicbasalspc should be 1']);
+					md = checkfield(md,'fieldname','thermal.isdynamicbasalspc','numel', [1],'values',[1], 'message',['for enthalpy run thermal.isdynamicbasalspc should be 1']);
 				end
 	    end
 
-		 md = checkfield(md,'thermal.requested_outputs','stringrow',1);
+		 md = checkfield(md,'fieldname','thermal.requested_outputs','stringrow',1);
     end % }}} 
 		function disp(obj) % {{{
Index: /issm/trunk/src/m/classes/thermal.py
===================================================================
--- /issm/trunk/src/m/classes/thermal.py	(revision 17805)
+++ /issm/trunk/src/m/classes/thermal.py	(revision 17806)
@@ -2,6 +2,7 @@
 from fielddisplay import fielddisplay
 from EnumDefinitions import *
-from checkfield import *
-from WriteData import *
+from checkfield import checkfield
+from WriteData import WriteData
+import MatlabFuncs as m
 
 class thermal(object):
@@ -79,13 +80,15 @@
 			return md
 
-		md = checkfield(md,'thermal.stabilization','numel',[1],'values',[0,1,2])
-		md = checkfield(md,'thermal.spctemperature','forcing',1)
-		if EnthalpyAnalysisEnum() in analyses and md.thermal.isenthalpy and md.mesh.dimension==3:
+		md = checkfield(md,'fieldname','thermal.stabilization','numel',[1],'values',[0,1,2])
+		md = checkfield(md,'fieldname','thermal.spctemperature','forcing',1)
+		if EnthalpyAnalysisEnum() in analyses and md.thermal.isenthalpy and md.mesh.dimension()==3:
 			pos=numpy.nonzero(numpy.logical_not(numpy.isnan(md.thermal.spctemperature[0:md.mesh.numberofvertices])))
 			replicate=numpy.tile(md.geometry.surface-md.mesh.z,(1,numpy.size(md.thermal.spctemperature,axis=1)))
-			md = checkfield(md,'thermal.spctemperature[numpy.nonzero(numpy.logical_not(numpy.isnan(md.thermal.spctemperature[0:md.mesh.numberofvertices,:])))]','<',md.materials.meltingpoint-md.materials.beta*md.materials.rho_ice*md.constants.g*replicate[pos],'message',"spctemperature should be below the adjusted melting point")
-			md = checkfield(md,'thermal.isenthalpy','numel',[1],'values',[0,1])
-			md = checkfield(md,'thermal.isdynamicbasalspc','numel',[1],'values',[0,1]);
-			md = checkfield(md,'thermal.requested_outputs','stringrow',1)
+			md = checkfield(md,'fieldname','thermal.spctemperature[numpy.nonzero(numpy.logical_not(numpy.isnan(md.thermal.spctemperature[0:md.mesh.numberofvertices,:])))]','<',md.materials.meltingpoint-md.materials.beta*md.materials.rho_ice*md.constants.g*replicate[pos],'message',"spctemperature should be below the adjusted melting point")
+			md = checkfield(md,'fieldname','thermal.isenthalpy','numel',[1],'values',[0,1])
+			md = checkfield(md,'fieldname','thermal.isdynamicbasalspc','numel',[1],'values',[0,1]);
+			if(md.thermal.isenthalpy):
+				md = checkfield(md,'fieldname','thermal.isdynamicbasalspc','numel', [1],'values',[1], 'message',"for enthalpy run thermal.isdynamicbasalspc should be true")
+		md = checkfield(md,'fieldname','thermal.requested_outputs','stringrow',1)
 
 		return md
Index: /issm/trunk/src/m/classes/timestepping.m
===================================================================
--- /issm/trunk/src/m/classes/timestepping.m	(revision 17805)
+++ /issm/trunk/src/m/classes/timestepping.m	(revision 17806)
@@ -13,4 +13,15 @@
 	end
 	methods
+       function createxml(obj,fid) % {{{
+            fprintf(fid, '\n\n');
+            fprintf(fid, '%s\n', '<!-- Timestepping -->');
+			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="start_time" type="',              class(obj.start_time),'" default="',                  convert2str(obj.start_time),'">',              '     <section name="timestepping" />','     <help> simulation starting time [yr] </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="final_time" type="',            class(obj.final_time),'" default="',                convert2str(obj.final_time),'">',   '     <section name="timestepping" />','     <help> final time to stop the simulation [yr] </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',        '<parameter key ="time_step" type="',      class(obj.time_step),'" default="',          convert2str(obj.time_step),'">',            '     <section name="timestepping" />','     <help> length of time steps [yr] </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',        '<parameter key ="time_adapt" type="',     class(obj.time_adapt),'" default="',         convert2str(obj.time_adapt),'">',            '     <section name="timestepping" />','     <help> use cfl condition to define time step ? (0 or 1)  </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="cfl_coefficient" type="',       class(obj.cfl_coefficient),'" default="',              convert2str(obj.cfl_coefficient),'">',              '     <section name="timestepping" />','     <help> coefficient applied to cfl condition </help>','</parameter>');
+            
+        end % }}}
+        
 		function obj = timestepping(varargin) % {{{
 			switch nargin
@@ -35,9 +46,9 @@
 		function md = checkconsistency(obj,md,solution,analyses) % {{{
 
-			md = checkfield(md,'timestepping.start_time','numel',[1],'NaN',1);
-			md = checkfield(md,'timestepping.final_time','numel',[1],'NaN',1);
-			md = checkfield(md,'timestepping.time_step','numel',[1],'>=',0,'NaN',1);
-			md = checkfield(md,'timestepping.time_adapt','numel',[1],'values',[0 1]);
-			md = checkfield(md,'timestepping.cfl_coefficient','numel',[1],'>',0,'<=',1);
+			md = checkfield(md,'fieldname','timestepping.start_time','numel',[1],'NaN',1);
+			md = checkfield(md,'fieldname','timestepping.final_time','numel',[1],'NaN',1);
+			md = checkfield(md,'fieldname','timestepping.time_step','numel',[1],'>=',0,'NaN',1);
+			md = checkfield(md,'fieldname','timestepping.time_adapt','numel',[1],'values',[0 1]);
+			md = checkfield(md,'fieldname','timestepping.cfl_coefficient','numel',[1],'>',0,'<=',1);
 			if obj.final_time-obj.start_time<0,
 				md = checkmessage(md,'timestepping.final_time should be larger than timestepping.start_time');
Index: /issm/trunk/src/m/classes/timestepping.py
===================================================================
--- /issm/trunk/src/m/classes/timestepping.py	(revision 17805)
+++ /issm/trunk/src/m/classes/timestepping.py	(revision 17806)
@@ -1,6 +1,6 @@
 from fielddisplay import fielddisplay
 from EnumDefinitions import *
-from checkfield import *
-from WriteData import *
+from checkfield import checkfield
+from WriteData import WriteData
 
 class timestepping(object):
@@ -48,9 +48,9 @@
 	def checkconsistency(self,md,solution,analyses):    # {{{
 
-		md = checkfield(md,'timestepping.start_time','numel',[1],'NaN',1)
-		md = checkfield(md,'timestepping.final_time','numel',[1],'NaN',1)
-		md = checkfield(md,'timestepping.time_step','numel',[1],'>=',0,'NaN',1)
-		md = checkfield(md,'timestepping.time_adapt','numel',[1],'values',[0,1])
-		md = checkfield(md,'timestepping.cfl_coefficient','numel',[1],'>',0,'<=',1)
+		md = checkfield(md,'fieldname','timestepping.start_time','numel',[1],'NaN',1)
+		md = checkfield(md,'fieldname','timestepping.final_time','numel',[1],'NaN',1)
+		md = checkfield(md,'fieldname','timestepping.time_step','numel',[1],'>=',0,'NaN',1)
+		md = checkfield(md,'fieldname','timestepping.time_adapt','numel',[1],'values',[0,1])
+		md = checkfield(md,'fieldname','timestepping.cfl_coefficient','numel',[1],'>',0,'<=',1)
 		if self.final_time-self.start_time<0:
 			md.checkmessage("timestepping.final_time should be larger than timestepping.start_time")
Index: /issm/trunk/src/m/classes/toolkits.py
===================================================================
--- /issm/trunk/src/m/classes/toolkits.py	(revision 17805)
+++ /issm/trunk/src/m/classes/toolkits.py	(revision 17806)
@@ -1,10 +1,9 @@
 from IssmConfig import IssmConfig
-from mumpsoptions import *
-from iluasmoptions import *
+from mumpsoptions import mumpsoptions
+from iluasmoptions import iluasmoptions
 from EnumToString import EnumToString
 from fielddisplay import fielddisplay
 from EnumDefinitions import *
-from checkfield import *
-from MatlabFuncs import *
+from checkfield import checkfield
 
 class toolkits(object):
Index: /issm/trunk/src/m/classes/transient.m
===================================================================
--- /issm/trunk/src/m/classes/transient.m	(revision 17805)
+++ /issm/trunk/src/m/classes/transient.m	(revision 17806)
@@ -6,13 +6,31 @@
 classdef transient
 	properties (SetAccess=public) 
-		ismasstransport      = 0;
-		isstressbalance      = 0;
+		ismasstransport   = 0;
+		isstressbalance   = 0;
 		isthermal         = 0;
 		isgroundingline   = 0;
 		isgia             = 0;
-		isdamage             = 0;
+		isdamageevolution = 0;
+		islevelset        = 0;
+		ishydrology       = 0;
 		requested_outputs = {};
 	end
 	methods
+        function createxml(obj,fid) % {{{
+            fprintf(fid, '<!-- transient -->\n');            
+                    
+            % transient solution parameters
+            fprintf(fid,'%s\n%s\n%s\n','<frame key="1" label="transient solution parameters">','<section name="transient" />');                    
+                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="ismasstransport" type="',class(obj.ismasstransport),'" default="',convert2str(obj.ismasstransport),'">','     <section name="transient" />','     <help> indicates whether a masstransport solution is used in the transient </help>','  </parameter>');
+                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="isstressbalance" type="',class(obj.isstressbalance),'" default="',convert2str(obj.isstressbalance),'">','     <section name="transient" />','     <help> indicates whether a stressbalance solution is used in the transient </help>','  </parameter>');
+                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="isthermal" type="',class(obj.isthermal),'" default="',convert2str(obj.isthermal),'">','     <section name="transient" />','     <help> indicates whether a thermal solution is used in the transient </help>','  </parameter>');
+                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="isgroundingline" type="',class(obj.isgroundingline),'" default="',convert2str(obj.isgroundingline),'">','     <section name="transient" />','     <help> indicates whether a groundingline migration is used in the transient </help>','  </parameter>');
+                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="isgia" type="',class(obj.isgia),'" default="',convert2str(obj.isgia),'">','     <section name="transient" />','     <help> indicates whether a postglacial rebound model is used in the transient </help>','  </parameter>');
+                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="isdamage" type="',class(obj.isdamage),'" default="',convert2str(obj.isdamage),'">','     <section name="transient" />','     <help> indicates whether damage evolution is used in the transient </help>','  </parameter>');
+                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="islevelset" type="',class(obj.islevelset),'" default="',convert2str(obj.islevelset),'">','     <section name="transient" />','     <help> LEVEL SET DESCRIPTION...  </help>','  </parameter>');
+                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="requested_outputs" type="',class(obj.requested_outputs),'" default="',convert2str(obj.requested_outputs),'">','     <section name="transient" />','     <help> list of additional outputs requested </help>','  </parameter>');
+            fprintf(fid,'%s\n%s\n','</frame>');    
+        
+        end % }}}
 		function obj = transient(varargin) % {{{
 			switch nargin
@@ -22,4 +40,19 @@
 					error('constructor not supported');
 			end
+		end % }}}
+		function obj = deactivateall(obj) % {{{
+
+			%full analysis: Stressbalance, Masstransport and Thermal but no groundingline migration for now
+			obj.ismasstransport = 0;
+			obj.isstressbalance = 0;
+			obj.isthermal       = 0;
+			obj.isgroundingline = 0;
+			obj.isgia           = 0;
+			obj.isdamageevolution = 0;
+			obj.islevelset      = 0;
+			obj.ishydrology     = 0;
+
+			%default output
+			obj.requested_outputs={};
 		end % }}}
 		function obj = setdefaultparameters(obj) % {{{
@@ -31,5 +64,7 @@
 			obj.isgroundingline = 0;
 			obj.isgia           = 0;
-			obj.isdamage        = 0;
+			obj.isdamageevolution = 0;
+			obj.islevelset      = 0;
+			obj.ishydrology     = 0;
 
 			%default output
@@ -37,7 +72,9 @@
 		end % }}}
 		function list = defaultoutputs(self,md) % {{{
-
-			list = {'SurfaceforcingsMassBalance'};
-
+			if(self.ismasstransport)
+				list = {'SurfaceforcingsMassBalance'};
+			else
+				list = {};
+			end
 		end % }}}
 		function md = checkconsistency(obj,md,solution,analyses) % {{{
@@ -46,11 +83,13 @@
 			if solution~=TransientSolutionEnum(), return; end
 
-			md = checkfield(md,'transient.ismasstransport','numel',[1],'values',[0 1]);
-			md = checkfield(md,'transient.isstressbalance','numel',[1],'values',[0 1]);
-			md = checkfield(md,'transient.isthermal','numel',[1],'values',[0 1]);
-			md = checkfield(md,'transient.isgroundingline','numel',[1],'values',[0 1]);
-			md = checkfield(md,'transient.isgia','numel',[1],'values',[0 1]);
-			md = checkfield(md,'transient.isdamage','numel',[1],'values',[0 1]);
-			md = checkfield(md,'transient.requested_outputs','stringrow',1);
+			md = checkfield(md,'fieldname','transient.ismasstransport','numel',[1],'values',[0 1]);
+			md = checkfield(md,'fieldname','transient.isstressbalance','numel',[1],'values',[0 1]);
+			md = checkfield(md,'fieldname','transient.isthermal','numel',[1],'values',[0 1]);
+			md = checkfield(md,'fieldname','transient.isgroundingline','numel',[1],'values',[0 1]);
+			md = checkfield(md,'fieldname','transient.isgia','numel',[1],'values',[0 1]);
+			md = checkfield(md,'fieldname','transient.isdamageevolution','numel',[1],'values',[0 1]);
+			md = checkfield(md,'fieldname','transient.islevelset','numel',[1],'values',[0 1]);
+			md = checkfield(md,'fieldname','transient.ishydrology','numel',[1],'values',[0 1]);
+			md = checkfield(md,'fieldname','transient.requested_outputs','stringrow',1);
 
 		end % }}}
@@ -63,5 +102,7 @@
 			fielddisplay(obj,'isgroundingline','indicates whether a groundingline migration is used in the transient');
 			fielddisplay(obj,'isgia','indicates whether a postglacial rebound model is used in the transient');
-			fielddisplay(obj,'isdamage','indicates whether damage evolution is used in the transient');
+			fielddisplay(obj,'isdamageevolution','indicates whether damage evolution is used in the transient');
+			fielddisplay(obj,'islevelset','LEVEL SET DESCRIPTION...');
+			fielddisplay(obj,'ishydrology','indicates whether an hydrology model is used');
 			fielddisplay(obj,'requested_outputs','list of additional outputs requested');
 
@@ -73,5 +114,7 @@
 			WriteData(fid,'object',obj,'fieldname','isgroundingline','format','Boolean');
 			WriteData(fid,'object',obj,'fieldname','isgia','format','Boolean');
-			WriteData(fid,'object',obj,'fieldname','isdamage','format','Boolean');
+			WriteData(fid,'object',obj,'fieldname','isdamageevolution','format','Boolean');
+			WriteData(fid,'object',obj,'fieldname','ishydrology','format','Boolean');
+			WriteData(fid,'object',obj,'fieldname','islevelset','format','Boolean');
 
 			%process requested outputs
Index: /issm/trunk/src/m/classes/transient.py
===================================================================
--- /issm/trunk/src/m/classes/transient.py	(revision 17805)
+++ /issm/trunk/src/m/classes/transient.py	(revision 17806)
@@ -1,6 +1,6 @@
 from fielddisplay import fielddisplay
 from EnumDefinitions import *
-from checkfield import *
-from WriteData import *
+from checkfield import checkfield
+from WriteData import WriteData
 
 class transient(object):
@@ -13,9 +13,12 @@
 
 	def __init__(self): # {{{
-		self.ismasstransport      = False
-		self.isstressbalance      = False
+		self.ismasstransport   = False
+		self.isstressbalance   = False
 		self.isthermal         = False
 		self.isgroundingline   = False
 		self.isgia             = False
+		self.isdamageevolution = False
+		self.islevelset        = False
+		self.ishydrology       = False
 		self.requested_outputs = []
 
@@ -31,4 +34,7 @@
 		string="%s\n%s"%(string,fielddisplay(self,'isgroundingline','indicates if a groundingline migration is used in the transient'))
 		string="%s\n%s"%(string,fielddisplay(self,'isgia','indicates if a postglacial rebound is used in the transient'))
+		string="%s\n%s"%(string,fielddisplay(self,'isdamageevolution','indicates whether damage evolution is used in the transient'))
+		string="%s\n%s"%(string,fielddisplay(self,'islevelset','LEVELSET METHOD DESCRIPTION'))
+		string="%s\n%s"%(string,fielddisplay(self,'ishydrology','indicates whether an hydrology model is used'))
 		string="%s\n%s"%(string,fielddisplay(self,'requested_outputs','list of additional outputs requested'))
 		return string
@@ -36,6 +42,25 @@
 	def defaultoutputs(self,md): # {{{
 
-		return ['SurfaceforcingsMassBalance']
+		if self.ismasstransport:
+			return ['SurfaceforcingsMassBalance']
+		else:
+			return []
 
+	#}}}
+	def setallnullparameters(self): # {{{
+		
+		#Nothing done
+		self.ismasstransport = False
+		self.isstressbalance = False
+		self.isthermal       = False
+		self.isgroundingline = False
+		self.isgia           = False
+		self.isdamageevolution = False
+		self.islevelset      = False
+                self.ishydrology     = False
+
+		#default output
+		self.requested_outputs=[]
+		return self
 	#}}}
 	def setdefaultparameters(self): # {{{
@@ -47,4 +72,7 @@
 		self.isgroundingline = False
 		self.isgia           = False
+		self.isdamageevolution = False
+		self.islevelset      = False
+                self.ishydrology     = False
 
 		#default output
@@ -58,10 +86,13 @@
 			return md
 
-		md = checkfield(md,'transient.ismasstransport','numel',[1],'values',[0,1])
-		md = checkfield(md,'transient.isstressbalance','numel',[1],'values',[0,1])
-		md = checkfield(md,'transient.isthermal','numel',[1],'values',[0,1])
-		md = checkfield(md,'transient.isgroundingline','numel',[1],'values',[0,1])
-		md = checkfield(md,'transient.isgia','numel',[1],'values',[0,1])
-		md = checkfield(md,'transient.requested_outputs','stringrow',1)
+		md = checkfield(md,'fieldname','transient.ismasstransport','numel',[1],'values',[0,1])
+		md = checkfield(md,'fieldname','transient.isstressbalance','numel',[1],'values',[0,1])
+		md = checkfield(md,'fieldname','transient.isthermal','numel',[1],'values',[0,1])
+		md = checkfield(md,'fieldname','transient.isgroundingline','numel',[1],'values',[0,1])
+		md = checkfield(md,'fieldname','transient.isgia','numel',[1],'values',[0,1])
+		md = checkfield(md,'fieldname','transient.isdamageevolution','numel',[1],'values',[0,1])
+		md = checkfield(md,'fieldname','transient.islevelset','numel',[1],'values',[0,1])
+		md = checkfield(md,'fieldname','transient.ishydrology','numel',[1],'values',[0,1])
+		md = checkfield(md,'fieldname','transient.requested_outputs','stringrow',1)
 
 		return md
@@ -73,4 +104,7 @@
 		WriteData(fid,'object',self,'fieldname','isgroundingline','format','Boolean')
 		WriteData(fid,'object',self,'fieldname','isgia','format','Boolean')
+		WriteData(fid,'object',self,'fieldname','isdamageevolution','format','Boolean')
+		WriteData(fid,'object',self,'fieldname','islevelset','format','Boolean')
+		WriteData(fid,'object',self,'fieldname','ishydrology','format','Boolean')
 
 		#process requested outputs
Index: /issm/trunk/src/m/classes/verbose.m
===================================================================
--- /issm/trunk/src/m/classes/verbose.m	(revision 17805)
+++ /issm/trunk/src/m/classes/verbose.m	(revision 17806)
@@ -38,4 +38,19 @@
 	%}}}
 	methods
+        function createxml(obj,fid) % {{{
+            fprintf(fid, '\n\n');
+            fprintf(fid, '%s\n', '<!-- verbose -->');
+             
+             fprintf(fid,'%s%s%s\n%s\n%s%s%s\n%s\n%s\n',    '<parameter key ="mprocessor" type="',              class(obj.mprocessor),'" optional="false">',              '     <section name="verbose" />','        <option value="',convert2str(obj.mprocessor),'" type="string" default="true"></option>','     <help>  </help>','</parameter>');
+             fprintf(fid,'%s%s%s\n%s\n%s%s%s\n%s\n%s\n',    '<parameter key ="module" type="',              class(obj.module),'" optional="false">',              '     <section name="verbose" />','        <option value="',convert2str(obj.module),'" type="string" default="true"></option>','     <help>  </help>','</parameter>');
+             fprintf(fid,'%s%s%s\n%s\n%s%s%s\n%s\n%s\n',    '<parameter key ="solution" type="',              class(obj.solution),'" optional="false">',              '     <section name="verbose" />','        <option value="',convert2str(obj.solution),'" type="string" default="true"></option>','     <help>  </help>','</parameter>');
+             fprintf(fid,'%s%s%s\n%s\n%s%s%s\n%s\n%s\n',    '<parameter key ="solver" type="',              class(obj.solver),'" optional="false">',              '     <section name="verbose" />','        <option value="',convert2str(obj.solver),'" type="string" default="true"></option>','     <help>  </help>','</parameter>');
+             fprintf(fid,'%s%s%s\n%s\n%s%s%s\n%s\n%s\n',    '<parameter key ="convergence" type="',              class(obj.convergence),'" optional="false">',              '     <section name="verbose" />','        <option value="',convert2str(obj.convergence),'" type="string" default="true"></option>','     <help>  </help>','</parameter>');
+             fprintf(fid,'%s%s%s\n%s\n%s%s%s\n%s\n%s\n',    '<parameter key ="control" type="',              class(obj.control),'" optional="false">',              '     <section name="verbose" />','        <option value="',convert2str(obj.control),'" type="string" default="true"></option>','     <help>  </help>','</parameter>');
+             fprintf(fid,'%s%s%s\n%s\n%s%s%s\n%s\n%s\n',    '<parameter key ="qmu" type="',              class(obj.qmu),'" optional="false">',              '     <section name="verbose" />','        <option value="',convert2str(obj.qmu),'" type="string" default="true"></option>','     <help>  </help>','</parameter>');
+             fprintf(fid,'%s%s%s\n%s\n%s%s%s\n%s\n',    '<parameter key ="autodiff" type="',              class(obj.autodiff),'" optional="false">',              '     <section name="verbose" />','        <option value="',convert2str(obj.autodiff),'" type="string" default="true"></option>','     <help>  </help>','</parameter>');
+             
+             
+        end % }}}
 		function verbose=verbose(varargin) % {{{
 
Index: /issm/trunk/src/m/classes/verbose.py
===================================================================
--- /issm/trunk/src/m/classes/verbose.py	(revision 17805)
+++ /issm/trunk/src/m/classes/verbose.py	(revision 17806)
@@ -1,6 +1,6 @@
-from pairoptions import *
-from MatlabFuncs import *
+from pairoptions import pairoptions
+import MatlabFuncs as m
 from EnumDefinitions import *
-from WriteData import *
+from WriteData import WriteData
 
 class verbose(object):
Index: /issm/trunk/src/m/consistency/checkfield.m
===================================================================
--- /issm/trunk/src/m/consistency/checkfield.m	(revision 17805)
+++ /issm/trunk/src/m/consistency/checkfield.m	(revision 17806)
@@ -1,6 +1,9 @@
-function md = checkfield(md,fieldname,varargin)
+function md = checkfield(md,varargin)
 %CHECKFIELD - check field consistency
 %
 %   Used to check model consistency.
+%   Requires: 
+%     'field' or 'fieldname' option. If 'fieldname' is provided, it will retrieve it from the model md. (md.(fieldname)) 
+%             If 'field' is provided, it will assume the argument following 'field' is a numeric array.
 %   Available options:
 %      - NaN: 1 if check that there is no NaN
@@ -22,11 +25,18 @@
 %
 %   Example:
-%      md = checkfield(md,'mesh.elementonbed','size',[md.mesh.numberofelements 1],'values',[0 1]);
+%      md = checkfield(md,'mesh.elementonbase','size',[md.mesh.numberofelements 1],'values',[0 1]);
 
 %get options
 options=pairoptions(varargin{:});
 
-%get field from model
-eval(['field=md.' fieldname ';']);
+%get field: 
+if exist(options,'field'), 
+	field=getfieldvalue(options,'field'); 
+	fieldname=getfieldvalue(options,'fieldname','no fieldname'); 
+else
+	fieldname=getfieldvalue(options,'fieldname'); 
+	eval(['field=md.' fieldname ';']);
+end
+
 
 %check empty
@@ -164,5 +174,5 @@
 end
 
-%Check row of strings
+%Check row of stringrow
 if getfieldvalue(options,'stringrow',0),
 	if(size(field,1)~=1 & size(field,1)~=0),
@@ -170,8 +180,13 @@
 			['field ''' fieldname ''' should have only one row']));
 	end
-	for i=1:size(field,2),
-		if ~ischar(field{i}),
-			md = checkmessage(md,getfieldvalue(options,'message',...
-				['field ''' fieldname ''' values should a cell of chars']));
+	if ~iscell(field),
+		md = checkmessage(md,getfieldvalue(options,'message',...
+			['field ''' fieldname ''' should be a cell of strings']));
+	else
+		for i=1:size(field,2),
+			if ~ischar(field{i}),
+				md = checkmessage(md,getfieldvalue(options,'message',...
+					['field ''' fieldname ''' values should a cell of chars']));
+			end
 		end
 	end
Index: /issm/trunk/src/m/consistency/checkfield.py
===================================================================
--- /issm/trunk/src/m/consistency/checkfield.py	(revision 17805)
+++ /issm/trunk/src/m/consistency/checkfield.py	(revision 17806)
@@ -1,12 +1,16 @@
 import numpy
 import os
-from pairoptions import *
-from MatlabFuncs import *
+from pairoptions import pairoptions
+import MatlabFuncs as m
 
-def checkfield(md,fieldname,*args):
+def checkfield(md,*args):
 	"""
 	CHECKFIELD - check field consistency
 
-	   Used to check model consistency.
+	   Used to check model consistency.,
+	   Requires: 
+	   'field' or 'fieldname' option. If 'fieldname' is provided, it will retrieve it from the model md. (md.(fieldname)) 
+             If 'field' is provided, it will assume the argument following 'field' is a numeric array.
+
 	   Available options:
 	      - NaN: 1 if check that there is no NaN
@@ -28,5 +32,5 @@
 
 	   Example:
-	      md = checkfield(md,'mesh.elementonbed','size',[md.mesh.numberofelements 1],'values',[0 1]);
+	      md = checkfield(md,'mesh.elementonbase','size',[md.mesh.numberofelements 1],'values',[0 1]);
 	"""
 
@@ -35,6 +39,11 @@
 
 	#get field from model
-#	field=getattr(md,fieldname)
-	exec("field=md.%s" % fieldname)
+	if options.exist('field'):
+		field=options.getfieldvalue('field')
+		fieldname=options.getfieldvalue('fieldname','no fieldname')
+	else:
+		fieldname=options.getfieldvalue('fieldname') 
+		exec("field=md.%s" % fieldname)
+
 	if isinstance(field,(bool,int,long,float)):
 		field=numpy.array([field])
@@ -98,5 +107,5 @@
 	if options.exist('values'):
 		fieldvalues=options.getfieldvalue('values')
-		if False in ismember(field,fieldvalues):
+		if False in m.ismember(field,fieldvalues):
 			if   len(fieldvalues)==1:
 				md = md.checkmessage(options.getfieldvalue('message',\
Index: /issm/trunk/src/m/consistency/ismodelselfconsistent.m
===================================================================
--- /issm/trunk/src/m/consistency/ismodelselfconsistent.m	(revision 17805)
+++ /issm/trunk/src/m/consistency/ismodelselfconsistent.m	(revision 17806)
@@ -25,4 +25,5 @@
 	if ~isobject(md.(field))
 		md=checkmessage(md,['field ''' char(field) ''' is not an object']);
+		continue;
 	end
 
Index: /issm/trunk/src/m/consistency/ismodelselfconsistent.py
===================================================================
--- /issm/trunk/src/m/consistency/ismodelselfconsistent.py	(revision 17805)
+++ /issm/trunk/src/m/consistency/ismodelselfconsistent.py	(revision 17806)
@@ -46,4 +46,7 @@
 		analyses=[L2ProjectionBaseAnalysisEnum(),HydrologyShreveAnalysisEnum(),HydrologyDCInefficientAnalysisEnum(),HydrologyDCEfficientAnalysisEnum()]
 
+	elif DamageEvolutionSolutionEnum():
+		analyses=[DamageEvolutionAnalysisEnum()]
+
 	else:
 		raise TypeError("solution type: '%s' not supported yet!" % EnumToString(solutiontype)[0])
Index: /issm/trunk/src/m/contrib/bamg/YamsCall.m
===================================================================
--- /issm/trunk/src/m/contrib/bamg/YamsCall.m	(revision 17805)
+++ /issm/trunk/src/m/contrib/bamg/YamsCall.m	(revision 17806)
@@ -85,5 +85,4 @@
 md.mesh.x=Coor(:,1);
 md.mesh.y=Coor(:,2);
-md.mesh.z=zeros(size(Coor,1),1);
 md.mesh.elements=Tria;
 md.mesh.numberofvertices=size(Coor,1);
Index: /issm/trunk/src/m/contrib/bamg/YamsCall.py
===================================================================
--- /issm/trunk/src/m/contrib/bamg/YamsCall.py	(revision 17805)
+++ /issm/trunk/src/m/contrib/bamg/YamsCall.py	(revision 17806)
@@ -3,7 +3,6 @@
 import subprocess
 import os
-from ComputeHessian import *
-from ComputeMetric import *
-from MatlabFuncs import *
+from ComputeHessian import ComputeHessian
+from ComputeMetric import ComputeMetric
 
 def YamsCall(md,field,hmin,hmax,gradation,epsilon):
@@ -85,5 +84,5 @@
 	#call yams
 	print "%s\n" % '      call Yams...'
-	if   ispc():
+	if   m.ispc():
 		#windows
 		subprocess.call('yams2-win -O 1 -v -0 -ecp -hgrad %g carre0 carre1' % gradation,shell=True)
Index: /issm/trunk/src/m/contrib/bamg/yams.m
===================================================================
--- /issm/trunk/src/m/contrib/bamg/yams.m	(revision 17805)
+++ /issm/trunk/src/m/contrib/bamg/yams.m	(revision 17806)
@@ -106,7 +106,7 @@
 %Fill in rest of fields:
 md.mesh.z=zeros(md.mesh.numberofvertices,1);
-md.mesh.vertexonbed=ones(md.mesh.numberofvertices,1);
+md.mesh.vertexonbase=ones(md.mesh.numberofvertices,1);
 md.mesh.vertexonsurface=ones(md.mesh.numberofvertices,1);
-md.mesh.elementonbed=ones(md.mesh.numberofelements,1);
+md.mesh.elementonbase=ones(md.mesh.numberofelements,1);
 md.mesh.elementonsurface=ones(md.mesh.numberofelements,1);
 if strcmpi(Names.interp,'node'),
Index: /issm/trunk/src/m/contrib/dassflow/importgmsh.m
===================================================================
--- /issm/trunk/src/m/contrib/dassflow/importgmsh.m	(revision 17805)
+++ /issm/trunk/src/m/contrib/dassflow/importgmsh.m	(revision 17806)
@@ -1,3 +1,3 @@
-function md = importgmsh(filename)
+function md = importgmsh(filename,dim)
 
 %some checks
@@ -30,4 +30,6 @@
 x = A(2,:)';
 y = A(3,:)';
+z = A(4,:)';
+
 A=fscanf(fid,'%s',1);
 if ~strcmp(A,'$EndNodes'), 
@@ -43,26 +45,58 @@
 disp(['Number of elements: ' num2str(nbt) ]);
 counter = 0;
-index   = zeros(0,3);
-segments       = zeros(0,2);
-segmentmarkers = zeros(0,1);
+if (dim==2),
+	index   = zeros(0,3);
+	segments       = zeros(0,2);
+	segmentmarkers = zeros(0,1);
+elseif (dim==3),
+	index   = zeros(0,4);
+	segments       = zeros(0,3);
+	segmentmarkers = zeros(0,1);
+else
+	error('not supported');
+end
+
 while(counter<nbt);
 	id = fscanf(fid,'%i',1);
 	ty = fscanf(fid,'%i',1);
-	if(ty>2) error('Type not supported'); end
 	nbf = fscanf(fid,'%i',1);
 	flags = fscanf(fid,'%i',nbf);
 
-	if ty==1,
-		A=fscanf(fid,'%i %i',2);
-		segments(end+1,:)=A;
-		if(flags(1)==5 & flags(2)==3), segmentmarkers(end+1)=3; 
-		elseif(flags(1)==1 & flags(2)==4), segmentmarkers(end+1)=4;
-		elseif(flags(1)==2 & flags(2)==1), segmentmarkers(end+1)=1;
-		elseif(flags(1)==4 & flags(2)==2), segmentmarkers(end+1)=2;
-		else error(['flags ' num2str(flags') ' not supported']);
-		end
-	else
-		A=fscanf(fid,'%i %i %i',3);
-		index(end+1,:)=A;
+	switch(ty)
+		case 1, %segments
+			A=fscanf(fid,'%i %i',2);
+			if (dim==2),  %Actual element
+				segments(end+1,:)=A;
+				if    (flags(1)==5 & flags(2)==3), segmentmarkers(end+1)=3; 
+				elseif(flags(1)==1 & flags(2)==4), segmentmarkers(end+1)=4;
+				elseif(flags(1)==2 & flags(2)==1), segmentmarkers(end+1)=1;
+				elseif(flags(1)==4 & flags(2)==2), segmentmarkers(end+1)=2;
+				else error(['flags ' num2str(flags') ' not supported']);
+				end
+			else
+				error('not supported');
+			end
+		case 2, %tria
+			A=fscanf(fid,'%i %i %i',3);
+			if (dim==2), %Actual element
+				index(end+1,:)=A;
+			else         %Boundary element
+				segments(end+1,:)=A;
+				if    (flags(1)==1), segmentmarkers(end+1)=1; 
+				elseif(flags(1)==2), segmentmarkers(end+1)=2;
+				elseif(flags(1)==3), segmentmarkers(end+1)=3;
+				elseif(flags(1)==4), segmentmarkers(end+1)=4;
+				else error(['flags ' num2str(flags') ' not supported']);
+				end
+			end
+		case 4, %tetra
+			A=fscanf(fid,'%i %i %i %i',4);
+			if (dim==3), %Actual element
+				index(end+1,:)=A;
+			else
+				error('not supported');
+			end
+		otherwise,
+			error(['Type ' num2str(ty) ' not supported']);
 	end
 	counter = counter + 1;
@@ -70,9 +104,18 @@
 
 %recreate segments
-nbs = size(segments,1);
-segments = [segments zeros(nbs,1)];
-for i=1:nbs,
-	E = find(sum(ismember(index,segments(i,:)),2)>1);
-	segments(i,3)=E;
+if dim==2,
+	nbs = size(segments,1);
+	segments = [segments zeros(nbs,1)];
+	for i=1:nbs,
+		E = find(sum(ismember(index,segments(i,:)),2)>1);
+		segments(i,3)=E;
+	end
+else
+	nbs = size(segments,1);
+	segments = [segments zeros(nbs,1)];
+	for i=1:nbs,
+		E = find(sum(ismember(index,segments(i,:)),2)>2);
+		segments(i,4)=E;
+	end
 end
 
@@ -81,10 +124,29 @@
 
 %Create model
-md=meshconvert(model,index,x,y);
-md.mesh=mesh2dvertical(md.mesh);
-md.mesh.segmentmarkers=segmentmarkers;
-md.mesh.segments=segments;
-md.mesh.vertexonbed=zeros(md.mesh.numberofvertices,1);
-md.mesh.vertexonbed(find(vertexflags(md.mesh,1)))=1;
-md.mesh.vertexonsurface=zeros(md.mesh.numberofvertices,1);
-md.mesh.vertexonsurface(find(vertexflags(md.mesh,3)))=1;
+if 0, %2d triangles
+	md=meshconvert(model,index,x,y);
+	md.mesh=mesh2dvertical(md.mesh);
+	md.mesh.segmentmarkers=segmentmarkers;
+	md.mesh.segments=segments;
+	md.mesh.vertexonbase=zeros(md.mesh.numberofvertices,1);
+	md.mesh.vertexonbase(find(vertexflags(md.mesh,1)))=1;
+	md.mesh.vertexonsurface=zeros(md.mesh.numberofvertices,1);
+	md.mesh.vertexonsurface(find(vertexflags(md.mesh,3)))=1;
+else
+	md=model();
+	md.mesh=mesh3dtetras();
+	md.mesh.x = x;
+	md.mesh.y = y;
+	md.mesh.z = z;
+	md.mesh.elements = index;
+	md.mesh.numberofelements=size(md.mesh.elements,1);
+	md.mesh.numberofvertices=length(md.mesh.x);
+
+	%base 2, surface 1, inflow 3, outflow 4
+	md.mesh.vertexonbase=zeros(md.mesh.numberofvertices,1);
+	md.mesh.vertexonbase(segments(find(segmentmarkers==2),1:3))=1;
+	md.mesh.vertexonsurface=zeros(md.mesh.numberofvertices,1);
+	md.mesh.vertexonsurface(segments(find(segmentmarkers==1),1:3))=1;
+	md.mesh.vertexonboundary=zeros(md.mesh.numberofvertices,1);
+	md.mesh.vertexonboundary(segments(:,1:3))=1;
+end
Index: /issm/trunk/src/m/contrib/ecco/PropagateFlagsUntilDistance.m
===================================================================
--- /issm/trunk/src/m/contrib/ecco/PropagateFlagsUntilDistance.m	(revision 17805)
+++ /issm/trunk/src/m/contrib/ecco/PropagateFlagsUntilDistance.m	(revision 17806)
@@ -10,5 +10,5 @@
 
 %make 3d work in 2d: 
-if md.mesh.dimension==3,
+if dimension(md.mesh)==3,
 	md.mesh.x=md.mesh.x2d;
 	md.mesh.y=md.mesh.y2d;
Index: /issm/trunk/src/m/contrib/gslib/gslib.m
===================================================================
--- /issm/trunk/src/m/contrib/gslib/gslib.m	(revision 17805)
+++ /issm/trunk/src/m/contrib/gslib/gslib.m	(revision 17806)
@@ -1,15 +1,7 @@
-function output = gslib(x,y,data,varargin)
+function [B E] = gslib(x,y,data,xmin,ymin,nx,ny,deltax,deltay)
 %GSLIB - use gslib for Kriging
 %
 %   Usage:
 %      output = gslib(x,y,data,varargin)
-
-%Output Matrix
-xmin   = xl(1);
-ymin   = yl(1);
-nx     = 101;
-ny     = 101;
-deltax = 5000;
-deltay = 5000;
 
 %Variogram
Index: /issm/trunk/src/m/contrib/hack/tres.m
===================================================================
--- /issm/trunk/src/m/contrib/hack/tres.m	(revision 17805)
+++ /issm/trunk/src/m/contrib/hack/tres.m	(revision 17806)
@@ -9,5 +9,5 @@
 
 if strcmpi(string,'stressbalance'),
-	if md.mesh.dimension==2,
+	if strcmp(domaintype(md.mesh),'2Dhorizontal'),
 		md.initialization.vx=md.results.StressbalanceSolution.Vx;
 		md.initialization.vy=md.results.StressbalanceSolution.Vy;
Index: /issm/trunk/src/m/contrib/hydrology/effectivepressure.m
===================================================================
--- /issm/trunk/src/m/contrib/hydrology/effectivepressure.m	(revision 17805)
+++ /issm/trunk/src/m/contrib/hydrology/effectivepressure.m	(revision 17806)
@@ -8,5 +8,5 @@
 %      Neff=effectivepressure(md)
 
-Neff=md.materials.rho_ice*md.constants.g*md.geometry.thickness+md.materials.rho_ice*md.constants.g*md.geometry.bed;
+Neff=md.materials.rho_ice*md.constants.g*md.geometry.thickness+md.materials.rho_ice*md.constants.g*md.geometry.base;
 pos=find(Neff<0);
 Neff(pos)=0;
Index: /issm/trunk/src/m/contrib/massbalance/divergence.m
===================================================================
--- /issm/trunk/src/m/contrib/massbalance/divergence.m	(revision 17805)
+++ /issm/trunk/src/m/contrib/massbalance/divergence.m	(revision 17806)
@@ -5,5 +5,5 @@
 %      div=divergence(md,a,b)
 
-if (md.mesh.dimension==2),
+if (dimension(md.mesh)==2),
 	numberofelements=md.mesh.numberofelements;
 	numberofnodes=md.mesh.numberofvertices;
Index: /issm/trunk/src/m/contrib/massbalance/outflux.m
===================================================================
--- /issm/trunk/src/m/contrib/massbalance/outflux.m	(revision 17805)
+++ /issm/trunk/src/m/contrib/massbalance/outflux.m	(revision 17806)
@@ -16,5 +16,5 @@
 
 if nargin==1,
-	if md.mesh.dimension==3,
+	if dimension(md.mesh)==3,
 		vxa=DepthAverage(md,md.initialization.vx);
 		vya=DepthAverage(md,md.initialization.vy);
@@ -28,5 +28,5 @@
 else
 	step=varargin{1};
-	if md.mesh.dimension==3,
+	if dimension(md.mesh)==3,
 		vxa=DepthAverage(md,md.results.TransientSolution(step).Vx);
 		vya=DepthAverage(md,md.results.TransientSolution(step).Vy);
Index: /issm/trunk/src/m/contrib/paraview/exportVTK.m
===================================================================
--- /issm/trunk/src/m/contrib/paraview/exportVTK.m	(revision 17805)
+++ /issm/trunk/src/m/contrib/paraview/exportVTK.m	(revision 17806)
@@ -23,5 +23,10 @@
 
 %get the element related variables
-points=[model.mesh.x model.mesh.y model.mesh.z];
+if dimension(model.mesh)==2,
+	points=[model.mesh.x model.mesh.y zeros(model.mesh.numberofvertices,1)];
+else
+	points=[model.mesh.x model.mesh.y model.mesh.z];
+end
+
 [num_of_points,dim]=size(points);
 [num_of_elt]=size(model.mesh.elements,1);
@@ -39,26 +44,32 @@
 %this is the result structure
 res_struct=model.results;
-%Getting all the solutions of the model
-solnames=fields(res_struct);
-num_of_sols=length(solnames);
-%building solution structure 
-for i=1:num_of_sols
-	sol_struct{i}=res_struct.(solnames{i});
+%checking for results
+if (length(fields(res_struct))>0);
+	%Getting all the solutions of the model
+	solnames=fields(res_struct);
+	num_of_sols=length(solnames);
+	num_of_timesteps=1;
+	%building solution structure 
+	for i=1:num_of_sols
+		sol_struct{i}=res_struct.(solnames{i});
+		%looking for multiple time steps
+		if(size(sol_struct{i},2)>num_of_timesteps);
+			num_of_timesteps=size(sol_struct{i},2);
+  end
+ end
+else
+	num_of_timesteps=1;
 end
+for step=1:num_of_timesteps;
+	
+	timestep=step;
 
-%looking for multiple time steps
-num_of_timesteps=size(sol_struct{1},2);
-
-for step=1:num_of_timesteps;
-	%by default, we take the timestep from the first solution sturcture
-	timestep=sol_struct{1}(step).step;
+	fid = fopen(strcat(path,filesep,name,filesep,name,'.vtk',int2str(timestep),'.vtk'),'w+');
+	fprintf(fid,'# vtk DataFile Version 2.0 \n');
+	fprintf(fid,'Data for run %s \n',model.miscellaneous.name);
+	fprintf(fid,'ASCII \n');
+	fprintf(fid,'DATASET UNSTRUCTURED_GRID \n');
 	
-	FID = fopen(strcat(path,filesep,name,filesep,name,'.vtk',int2str(timestep),'.vtk'),'w+');
-	fprintf(FID,'# vtk DataFile Version 2.0 \n');
-	fprintf(FID,'Data for run %s \n',model.miscellaneous.name);
-	fprintf(FID,'ASCII \n');
-	fprintf(FID,'DATASET UNSTRUCTURED_GRID \n');
-	
-	fprintf(FID,'POINTS %d float\n',num_of_points);
+	fprintf(fid,'POINTS %d float\n',num_of_points);
 	if(dim==3);
 		s='%f %f %f \n';
@@ -67,7 +78,7 @@
   end
 	P=[points zeros(num_of_points,3-dim)];
-	fprintf(FID,s,P');
+	fprintf(fid,s,P');
 	
-	fprintf(FID,'CELLS %d %d\n',num_of_elt,num_of_elt*(point_per_elt+1));
+	fprintf(fid,'CELLS %d %d\n',num_of_elt,num_of_elt*(point_per_elt+1));
 	s='%d';
 	for j=1:point_per_elt
@@ -75,51 +86,64 @@
   end
 	s=cell2mat(horzcat(s,{'\n'}));
-	fprintf(FID,s,[(point_per_elt)*ones(num_of_elt,1) model.mesh.elements-1]');
+	fprintf(fid,s,[(point_per_elt)*ones(num_of_elt,1) model.mesh.elements-1]');
 	
-	fprintf(FID,'CELL_TYPES %d\n',num_of_elt);
+	fprintf(fid,'CELL_TYPES %d\n',num_of_elt);
 	s='%d\n';
-	fprintf(FID,s,celltype*ones(num_of_elt,1));
-	fprintf(FID,'POINT_DATA %s \n',num2str(num_of_points));
+	fprintf(fid,s,celltype*ones(num_of_elt,1));
+	fprintf(fid,'POINT_DATA %s \n',num2str(num_of_points));
 
 	%loop over the different solution structures
-	for j=1:num_of_sols
-		
-		%getting the number of fields in the solution
-		fieldnames=fields(sol_struct{j}(step));
-		num_of_fields=length(fieldnames);
-		
-		%check which field is a real result and print
+	if (exist('num_of_sols'));
+		for j=1:num_of_sols
+			%dealing with results on different timesteps
+			if(size(sol_struct{j},2)>timestep);
+				timestep = step;
+			else
+				timestep = size(sol_struct{j},2);
+	    end
+			
+			%getting the number of fields in the solution
+			fieldnames=fields(sol_struct{j}(timestep));
+			num_of_fields=length(fieldnames);
+			
+			%check which field is a real result and print
 			for k=1:num_of_fields
-			if ((length(sol_struct{j}(step).(fieldnames{k})))== ...
-					num_of_points);
-				%paraview does not like NaN, replacing
-				pos=find(isnan(sol_struct{j}(step).(fieldnames{k})));
-				sol_struct{j}(step).(fieldnames{k})(pos)=-9999;
-				fprintf(FID,'SCALARS %s float 1 \n',fieldnames{k});
-				fprintf(FID,'LOOKUP_TABLE default\n');
-				s='%e\n';
-				fprintf(FID,s,sol_struct{j}(step).(fieldnames{k}));
-    	end		
-	  end 
-	end
-	
+				if ((numel(sol_struct{j}(timestep).(fieldnames{k})))== ...
+						num_of_points);
+					%paraview does not like NaN, replacing
+					nanval=find(isnan(sol_struct{j}(timestep).(fieldnames{k})));
+					sol_struct{j}(timestep).(fieldnames{k})(nanval)=-9999;
+					%also checking for verry small value that mess up
+					smallval=(abs(sol_struct{j}(timestep).(fieldnames{k}))<1.0e-20);
+					sol_struct{j}(timestep).(fieldnames{k})(smallval)=0.0;
+					fprintf(fid,'SCALARS %s float 1 \n',fieldnames{k});
+					fprintf(fid,'LOOKUP_TABLE default\n');
+					s='%e\n';
+					fprintf(fid,s,sol_struct{j}(timestep).(fieldnames{k}));
+		    end		
+	    end 
+	  end
+  end
 	%loop on arguments, if something other than result is asked, do
 	%it now
 	for j= 1:nargin-2
 		res_struct=model.(varargin{j});
-		solnames=fields(res_struct);
-		num_of_sols=length(solnames);
-		for k=1:num_of_sols
-			if ((length(res_struct.(solnames{k})))==num_of_points);
+		fieldnames=fields(res_struct);
+		num_of_fields=length(fieldnames);
+		for k=1:num_of_fields
+			if ((numel(res_struct.(fieldnames{k})))==num_of_points);
 				%paraview does not like NaN, replacing
-				pos=find(isnan(res_struct.(solnames{k})));
-				res_struct.(solnames{k})(pos)=-9999;
-				fprintf(FID,'SCALARS %s float 1 \n',solnames{k});
-				fprintf(FID,'LOOKUP_TABLE default\n');
+				nanval=find(isnan(res_struct.(fieldnames{k})));
+				res_struct.(fieldnames{k})(nanval)=-9999;
+				%also checking for verry small value that mess up
+				smallval=(abs(res_struct.(fieldnames{k}))<1.0e-20);
+				res_struct.(fieldnames{k})(smallval)=0.0;
+				fprintf(fid,'SCALARS %s float 1 \n',fieldnames{k});
+				fprintf(fid,'LOOKUP_TABLE default\n');
 				s='%e\n';
-				fprintf(FID,s,res_struct.(solnames{k}));
+				fprintf(fid,s,res_struct.(fieldnames{k}));
 	    end		
 		end 
 	end
-	fclose(FID);
+	fclose(fid);
 end
Index: /issm/trunk/src/m/coordsystems/gdaltransform.m
===================================================================
--- /issm/trunk/src/m/coordsystems/gdaltransform.m	(revision 17806)
+++ /issm/trunk/src/m/coordsystems/gdaltransform.m	(revision 17806)
@@ -0,0 +1,19 @@
+function [xout,yout] = gdaltransform(x,y,proj_in,proj_out)
+%GDALTRANSFORM - switch from one projection system to another 
+%
+%   Usage:
+%      [x,y] = gdaltransform(x1,y1,'EPSG:3184','EPSG:3411')
+%
+%
+
+	fid=fopen('.rand1234.txt','w');
+	for i=1:length(x),
+		fprintf(fid,'%g %g\n',x(i),y(i));
+	end
+	fclose(fid);
+
+	[s,r]=system(['gdaltransform -s_srs ',proj_in,' -t_srs ',proj_out,'  < .rand1234.txt > .rand1235.txt']);
+
+	A=textread('.rand1235.txt');
+	xout=A(:,1);
+	yout=A(:,2);
Index: /issm/trunk/src/m/coordsystems/ll2xy.py
===================================================================
--- /issm/trunk/src/m/coordsystems/ll2xy.py	(revision 17806)
+++ /issm/trunk/src/m/coordsystems/ll2xy.py	(revision 17806)
@@ -0,0 +1,62 @@
+import numpy as npy 
+
+def ll2xy(lat,lon,sgn=-1,central_meridian=0,standard_parallel=71):
+	'''
+	LL2XY - converts lat lon to polar stereographic
+
+   Converts from geodetic latitude and longitude to Polar 
+   Stereographic (X,Y) coordinates for the polar regions.
+   Author: Michael P. Schodlok, December 2003 (map2ll)
+
+   Usage:
+      x,y = ll2xy(lat,lon,sgn)
+      x,y = ll2xy(lat,lon,sgn,central_meridian,standard_parallel)
+
+      - sgn = Sign of latitude +1 : north latitude (default is mer=45 lat=70)
+                               -1 : south latitude (default is mer=0  lat=71)
+	'''
+
+	assert sgn==1 or sgn==-1, 'error: sgn should be either +1 or -1'
+
+	#Get central_meridian and standard_parallel depending on hemisphere
+	if sgn == 1:
+		delta = 45
+		slat = 70
+		print '		ll2xy: creating coordinates in north polar stereographic (Std Latitude: 70N Meridian: 45)'
+	else: 
+		delta = central_meridian
+		slat = standard_parallel
+		print '		ll2xy: creating coordinates in south polar stereographic (Std Latitude: 71S Meridian: 0)'
+	
+	# Conversion constant from degrees to radians
+	cde = 57.29577951
+	# Radius of the earth in meters
+	re = 6378.273*10**3
+	# Eccentricity of the Hughes ellipsoid squared
+	ex2 = .006693883
+	# Eccentricity of the Hughes ellipsoid
+	ex = npy.sqrt(ex2)
+	
+	latitude = npy.abs(lat) * npy.pi/180.
+	longitude = (lon + delta) * npy.pi/180.
+	
+	# compute X and Y in grid coordinates.
+	T = npy.tan(npy.pi/4-latitude/2) / ((1-ex*npy.sin(latitude))/(1+ex*npy.sin(latitude)))**(ex/2)
+	
+	if (90 - slat) <  1.e-5:
+		rho = 2.*re*T/npy.sqrt((1.+ex)**(1.+ex)*(1.-ex)**(1.-ex))
+	else:
+		sl  = slat*npy.pi/180.
+		tc  = npy.tan(npy.pi/4.-sl/2.)/((1.-ex*npy.sin(sl))/(1.+ex*npy.sin(sl)))**(ex/2.)
+		mc  = npy.cos(sl)/npy.sqrt(1.0-ex2*(npy.sin(sl)**2))
+		rho = re*mc*T/tc
+	
+	y = -rho * sgn * npy.cos(sgn*longitude)
+	x =  rho * sgn * npy.sin(sgn*longitude)
+
+	cnt1=npy.nonzero(latitude>= npy.pi/2.)[0]
+	
+	if cnt1:
+		x[cnt1,0] = 0.0
+		y[cnt1,0] = 0.0
+	return x,y
Index: /issm/trunk/src/m/coordsystems/xy2ll.py
===================================================================
--- /issm/trunk/src/m/coordsystems/xy2ll.py	(revision 17805)
+++ /issm/trunk/src/m/coordsystems/xy2ll.py	(revision 17806)
@@ -25,11 +25,11 @@
 	elif len(args) == 0:
 		if sgn == 1:
-			delta = 45 
-			slat = 70
-			print 'Warning: expecting coordinates in polar stereographic (Std Latitude: 70degN Meridian: 45deg)'
+			delta = 45. 
+			slat = 70.
+			print '		xy2ll: creating coordinates in north polar stereographic (Std Latitude: 70degN Meridian: 45deg)'
 		elif sgn == -1:
-			delta = 0  
-			slat = 71
-			print 'Warning: expecting coordinates in polar stereographic (Std Latitude: 71degS Meridian: 0deg)'
+			delta = 0.  
+			slat = 71.
+			print '		xy2ll: creating coordinates in south polar stereographic (Std Latitude: 71degS Meridian: 0deg)'
 		else:
 			raise ValueError('sgn should be either +1 or -1')
@@ -71,6 +71,6 @@
 	lon = sgn * lon
 	
-	res1 = npy.nonzero(rho <= 0.1)
-	if len(res1[0] > 0):
+	res1 = npy.nonzero(rho <= 0.1)[0]
+	if len(res1) > 0:
 		lat[res1] = 90. * sgn
 		lon[res1] = 0.0
Index: /issm/trunk/src/m/dev/devpath.py
===================================================================
--- /issm/trunk/src/m/dev/devpath.py	(revision 17805)
+++ /issm/trunk/src/m/dev/devpath.py	(revision 17806)
@@ -20,13 +20,14 @@
 				
 sys.path.append(ISSM_DIR + '/lib')
+sys.path.append(ISSM_DIR + '/src/wrappers/python/.libs')
 
 #Manual imports for commonly used functions
 from plotmodel import plotmodel
 
-c = get_ipython().config
-c.InteractiveShellApp.exec_lines = []
-c.InteractiveShellApp.exec_lines.append('%load_ext autoreload')
-c.InteractiveShellApp.exec_lines.append('%autoreload 2')
-c.InteractiveShellApp.exec_lines.append('print "Warning: disable autoreload in startup.py to improve performance." ')
+#c = get_ipython().config
+#c.InteractiveShellApp.exec_lines = []
+#c.InteractiveShellApp.exec_lines.append('%load_ext autoreload')
+#c.InteractiveShellApp.exec_lines.append('%autoreload 2')
+#c.InteractiveShellApp.exec_lines.append('print "Warning: disable autoreload in startup.py to improve performance." ')
 
 print("\n  ISSM development path correctly loaded\n\n")
Index: /issm/trunk/src/m/enum/AugmentedLagrangianREnum.m
===================================================================
--- /issm/trunk/src/m/enum/AugmentedLagrangianREnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/AugmentedLagrangianREnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=AugmentedLagrangianREnum()
+%AUGMENTEDLAGRANGIANRENUM - Enum of AugmentedLagrangianR
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=AugmentedLagrangianREnum()
+
+macro=StringToEnum('AugmentedLagrangianR');
Index: /issm/trunk/src/m/enum/AugmentedLagrangianThetaEnum.m
===================================================================
--- /issm/trunk/src/m/enum/AugmentedLagrangianThetaEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/AugmentedLagrangianThetaEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=AugmentedLagrangianThetaEnum()
+%AUGMENTEDLAGRANGIANTHETAENUM - Enum of AugmentedLagrangianTheta
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=AugmentedLagrangianThetaEnum()
+
+macro=StringToEnum('AugmentedLagrangianTheta');
Index: /issm/trunk/src/m/enum/BaseEnum.m
===================================================================
--- /issm/trunk/src/m/enum/BaseEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/BaseEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=BaseEnum()
+%BASEENUM - Enum of Base
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=BaseEnum()
+
+macro=StringToEnum('Base');
Index: sm/trunk/src/m/enum/BathymetryEnum.m
===================================================================
--- /issm/trunk/src/m/enum/BathymetryEnum.m	(revision 17805)
+++ 	(revision )
@@ -1,11 +1,0 @@
-function macro=BathymetryEnum()
-%BATHYMETRYENUM - Enum of Bathymetry
-%
-%   WARNING: DO NOT MODIFY THIS FILE
-%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
-%            Please read src/c/shared/Enum/README for more information
-%
-%   Usage:
-%      macro=BathymetryEnum()
-
-macro=StringToEnum('Bathymetry');
Index: /issm/trunk/src/m/enum/ContactEnum.m
===================================================================
--- /issm/trunk/src/m/enum/ContactEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/ContactEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=ContactEnum()
+%CONTACTENUM - Enum of Contact
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=ContactEnum()
+
+macro=StringToEnum('Contact');
Index: /issm/trunk/src/m/enum/CuffeyEnum.m
===================================================================
--- /issm/trunk/src/m/enum/CuffeyEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/CuffeyEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=CuffeyEnum()
+%CUFFEYENUM - Enum of Cuffey
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=CuffeyEnum()
+
+macro=StringToEnum('Cuffey');
Index: /issm/trunk/src/m/enum/DamageElementinterpEnum.m
===================================================================
--- /issm/trunk/src/m/enum/DamageElementinterpEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/DamageElementinterpEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=DamageElementinterpEnum()
+%DAMAGEELEMENTINTERPENUM - Enum of DamageElementinterp
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=DamageElementinterpEnum()
+
+macro=StringToEnum('DamageElementinterp');
Index: /issm/trunk/src/m/enum/DamageEquivStressEnum.m
===================================================================
--- /issm/trunk/src/m/enum/DamageEquivStressEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/DamageEquivStressEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=DamageEquivStressEnum()
+%DAMAGEEQUIVSTRESSENUM - Enum of DamageEquivStress
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=DamageEquivStressEnum()
+
+macro=StringToEnum('DamageEquivStress');
Index: /issm/trunk/src/m/enum/DamageEvolutionNumRequestedOutputsEnum.m
===================================================================
--- /issm/trunk/src/m/enum/DamageEvolutionNumRequestedOutputsEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/DamageEvolutionNumRequestedOutputsEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=DamageEvolutionNumRequestedOutputsEnum()
+%DAMAGEEVOLUTIONNUMREQUESTEDOUTPUTSENUM - Enum of DamageEvolutionNumRequestedOutputs
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=DamageEvolutionNumRequestedOutputsEnum()
+
+macro=StringToEnum('DamageEvolutionNumRequestedOutputs');
Index: /issm/trunk/src/m/enum/DamageEvolutionRequestedOutputsEnum.m
===================================================================
--- /issm/trunk/src/m/enum/DamageEvolutionRequestedOutputsEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/DamageEvolutionRequestedOutputsEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=DamageEvolutionRequestedOutputsEnum()
+%DAMAGEEVOLUTIONREQUESTEDOUTPUTSENUM - Enum of DamageEvolutionRequestedOutputs
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=DamageEvolutionRequestedOutputsEnum()
+
+macro=StringToEnum('DamageEvolutionRequestedOutputs');
Index: /issm/trunk/src/m/enum/DamageFEnum.m
===================================================================
--- /issm/trunk/src/m/enum/DamageFEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/DamageFEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=DamageFEnum()
+%DAMAGEFENUM - Enum of DamageF
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=DamageFEnum()
+
+macro=StringToEnum('DamageF');
Index: /issm/trunk/src/m/enum/DamageIsdamageEnum.m
===================================================================
--- /issm/trunk/src/m/enum/DamageIsdamageEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/DamageIsdamageEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=DamageIsdamageEnum()
+%DAMAGEISDAMAGEENUM - Enum of DamageIsdamage
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=DamageIsdamageEnum()
+
+macro=StringToEnum('DamageIsdamage');
Index: /issm/trunk/src/m/enum/DepthAverageAnalysisEnum.m
===================================================================
--- /issm/trunk/src/m/enum/DepthAverageAnalysisEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/DepthAverageAnalysisEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=DepthAverageAnalysisEnum()
+%DEPTHAVERAGEANALYSISENUM - Enum of DepthAverageAnalysis
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=DepthAverageAnalysisEnum()
+
+macro=StringToEnum('DepthAverageAnalysis');
Index: /issm/trunk/src/m/enum/DeviatoricStressEnum.m
===================================================================
--- /issm/trunk/src/m/enum/DeviatoricStressEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/DeviatoricStressEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=DeviatoricStressEnum()
+%DEVIATORICSTRESSENUM - Enum of DeviatoricStress
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=DeviatoricStressEnum()
+
+macro=StringToEnum('DeviatoricStress');
Index: /issm/trunk/src/m/enum/DeviatoricStressxxEnum.m
===================================================================
--- /issm/trunk/src/m/enum/DeviatoricStressxxEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/DeviatoricStressxxEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=DeviatoricStressxxEnum()
+%DEVIATORICSTRESSXXENUM - Enum of DeviatoricStressxx
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=DeviatoricStressxxEnum()
+
+macro=StringToEnum('DeviatoricStressxx');
Index: /issm/trunk/src/m/enum/DeviatoricStressxyEnum.m
===================================================================
--- /issm/trunk/src/m/enum/DeviatoricStressxyEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/DeviatoricStressxyEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=DeviatoricStressxyEnum()
+%DEVIATORICSTRESSXYENUM - Enum of DeviatoricStressxy
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=DeviatoricStressxyEnum()
+
+macro=StringToEnum('DeviatoricStressxy');
Index: /issm/trunk/src/m/enum/DeviatoricStressxzEnum.m
===================================================================
--- /issm/trunk/src/m/enum/DeviatoricStressxzEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/DeviatoricStressxzEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=DeviatoricStressxzEnum()
+%DEVIATORICSTRESSXZENUM - Enum of DeviatoricStressxz
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=DeviatoricStressxzEnum()
+
+macro=StringToEnum('DeviatoricStressxz');
Index: /issm/trunk/src/m/enum/DeviatoricStressyyEnum.m
===================================================================
--- /issm/trunk/src/m/enum/DeviatoricStressyyEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/DeviatoricStressyyEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=DeviatoricStressyyEnum()
+%DEVIATORICSTRESSYYENUM - Enum of DeviatoricStressyy
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=DeviatoricStressyyEnum()
+
+macro=StringToEnum('DeviatoricStressyy');
Index: /issm/trunk/src/m/enum/DeviatoricStressyzEnum.m
===================================================================
--- /issm/trunk/src/m/enum/DeviatoricStressyzEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/DeviatoricStressyzEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=DeviatoricStressyzEnum()
+%DEVIATORICSTRESSYZENUM - Enum of DeviatoricStressyz
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=DeviatoricStressyzEnum()
+
+macro=StringToEnum('DeviatoricStressyz');
Index: /issm/trunk/src/m/enum/DeviatoricStresszzEnum.m
===================================================================
--- /issm/trunk/src/m/enum/DeviatoricStresszzEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/DeviatoricStresszzEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=DeviatoricStresszzEnum()
+%DEVIATORICSTRESSZZENUM - Enum of DeviatoricStresszz
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=DeviatoricStresszzEnum()
+
+macro=StringToEnum('DeviatoricStresszz');
Index: /issm/trunk/src/m/enum/DivergenceEnum.m
===================================================================
--- /issm/trunk/src/m/enum/DivergenceEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/DivergenceEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=DivergenceEnum()
+%DIVERGENCEENUM - Enum of Divergence
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=DivergenceEnum()
+
+macro=StringToEnum('Divergence');
Index: /issm/trunk/src/m/enum/Domain2DhorizontalEnum.m
===================================================================
--- /issm/trunk/src/m/enum/Domain2DhorizontalEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/Domain2DhorizontalEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=Domain2DhorizontalEnum()
+%DOMAIN2DHORIZONTALENUM - Enum of Domain2Dhorizontal
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=Domain2DhorizontalEnum()
+
+macro=StringToEnum('Domain2Dhorizontal');
Index: /issm/trunk/src/m/enum/Domain2DverticalEnum.m
===================================================================
--- /issm/trunk/src/m/enum/Domain2DverticalEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/Domain2DverticalEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=Domain2DverticalEnum()
+%DOMAIN2DVERTICALENUM - Enum of Domain2Dvertical
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=Domain2DverticalEnum()
+
+macro=StringToEnum('Domain2Dvertical');
Index: /issm/trunk/src/m/enum/Domain3DEnum.m
===================================================================
--- /issm/trunk/src/m/enum/Domain3DEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/Domain3DEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=Domain3DEnum()
+%DOMAIN3DENUM - Enum of Domain3D
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=Domain3DEnum()
+
+macro=StringToEnum('Domain3D');
Index: /issm/trunk/src/m/enum/DomainDimensionEnum.m
===================================================================
--- /issm/trunk/src/m/enum/DomainDimensionEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/DomainDimensionEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=DomainDimensionEnum()
+%DOMAINDIMENSIONENUM - Enum of DomainDimension
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=DomainDimensionEnum()
+
+macro=StringToEnum('DomainDimension');
Index: /issm/trunk/src/m/enum/DomainTypeEnum.m
===================================================================
--- /issm/trunk/src/m/enum/DomainTypeEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/DomainTypeEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=DomainTypeEnum()
+%DOMAINTYPEENUM - Enum of DomainType
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=DomainTypeEnum()
+
+macro=StringToEnum('DomainType');
Index: /issm/trunk/src/m/enum/EffectivePressureEnum.m
===================================================================
--- /issm/trunk/src/m/enum/EffectivePressureEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/EffectivePressureEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=EffectivePressureEnum()
+%EFFECTIVEPRESSUREENUM - Enum of EffectivePressure
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=EffectivePressureEnum()
+
+macro=StringToEnum('EffectivePressure');
Index: /issm/trunk/src/m/enum/EnumDefinitions.py
===================================================================
--- /issm/trunk/src/m/enum/EnumDefinitions.py	(revision 17805)
+++ /issm/trunk/src/m/enum/EnumDefinitions.py	(revision 17806)
@@ -41,6 +41,6 @@
 def BasalforcingsMeltingRateCorrectionEnum(): return StringToEnum("BasalforcingsMeltingRateCorrection")[0]
 def BasalforcingsMeltingRateEnum(): return StringToEnum("BasalforcingsMeltingRate")[0]
-def BathymetryEnum(): return StringToEnum("Bathymetry")[0]
 def BedEnum(): return StringToEnum("Bed")[0]
+def BaseEnum(): return StringToEnum("Base")[0]
 def ConstantsGEnum(): return StringToEnum("ConstantsG")[0]
 def ConstantsReferencetemperatureEnum(): return StringToEnum("ConstantsReferencetemperature")[0]
@@ -98,6 +98,10 @@
 def SedimentHeadOldEnum(): return StringToEnum("SedimentHeadOld")[0]
 def SedimentHeadResidualEnum(): return StringToEnum("SedimentHeadResidual")[0]
+def EffectivePressureEnum(): return StringToEnum("EffectivePressure")[0]
 def EplHeadEnum(): return StringToEnum("EplHead")[0]
 def EplHeadOldEnum(): return StringToEnum("EplHeadOld")[0]
+def EplHeadSlopeXEnum(): return StringToEnum("EplHeadSlopeX")[0]
+def EplHeadSlopeYEnum(): return StringToEnum("EplHeadSlopeY")[0]
+def HydrologydcMaxIterEnum(): return StringToEnum("HydrologydcMaxIter")[0]
 def HydrologydcRelTolEnum(): return StringToEnum("HydrologydcRelTol")[0]
 def HydrologydcSpcsedimentHeadEnum(): return StringToEnum("HydrologydcSpcsedimentHead")[0]
@@ -108,9 +112,13 @@
 def HydrologydcWaterCompressibilityEnum(): return StringToEnum("HydrologydcWaterCompressibility")[0]
 def HydrologydcSpceplHeadEnum(): return StringToEnum("HydrologydcSpceplHead")[0]
-def HydrologydcMaskEplactiveEnum(): return StringToEnum("HydrologydcMaskEplactive")[0]
+def HydrologydcMaskEplactiveNodeEnum(): return StringToEnum("HydrologydcMaskEplactiveNode")[0]
+def HydrologydcMaskEplactiveEltEnum(): return StringToEnum("HydrologydcMaskEplactiveElt")[0]
 def HydrologydcEplCompressibilityEnum(): return StringToEnum("HydrologydcEplCompressibility")[0]
 def HydrologydcEplPorosityEnum(): return StringToEnum("HydrologydcEplPorosity")[0]
+def HydrologydcEplInitialThicknessEnum(): return StringToEnum("HydrologydcEplInitialThickness")[0]
+def HydrologydcEplMaxThicknessEnum(): return StringToEnum("HydrologydcEplMaxThickness")[0]
 def HydrologydcEplThicknessEnum(): return StringToEnum("HydrologydcEplThickness")[0]
-def HydrologydcEplTransmitivityEnum(): return StringToEnum("HydrologydcEplTransmitivity")[0]
+def HydrologydcEplThicknessOldEnum(): return StringToEnum("HydrologydcEplThicknessOld")[0]
+def HydrologydcEplConductivityEnum(): return StringToEnum("HydrologydcEplConductivity")[0]
 def HydrologydcIsefficientlayerEnum(): return StringToEnum("HydrologydcIsefficientlayer")[0]
 def HydrologydcSedimentlimitFlagEnum(): return StringToEnum("HydrologydcSedimentlimitFlag")[0]
@@ -119,9 +127,10 @@
 def HydrologydcLeakageFactorEnum(): return StringToEnum("HydrologydcLeakageFactor")[0]
 def HydrologydcPenaltyFactorEnum(): return StringToEnum("HydrologydcPenaltyFactor")[0]
+def HydrologydcPenaltyLockEnum(): return StringToEnum("HydrologydcPenaltyLock")[0]
+def HydrologydcBasalMoulinInputEnum(): return StringToEnum("HydrologydcBasalMoulinInput")[0]
 def HydrologyLayerEnum(): return StringToEnum("HydrologyLayer")[0]
 def HydrologySedimentEnum(): return StringToEnum("HydrologySediment")[0]
 def HydrologyEfficientEnum(): return StringToEnum("HydrologyEfficient")[0]
 def HydrologySedimentKmaxEnum(): return StringToEnum("HydrologySedimentKmax")[0]
-def WaterTransferEnum(): return StringToEnum("WaterTransfer")[0]
 def IndependentObjectEnum(): return StringToEnum("IndependentObject")[0]
 def InversionControlParametersEnum(): return StringToEnum("InversionControlParameters")[0]
@@ -155,5 +164,7 @@
 def MaterialsRheologyLawEnum(): return StringToEnum("MaterialsRheologyLaw")[0]
 def MaterialsRheologyNEnum(): return StringToEnum("MaterialsRheologyN")[0]
+def DamageIsdamageEnum(): return StringToEnum("DamageIsdamage")[0]
 def DamageDEnum(): return StringToEnum("DamageD")[0]
+def DamageFEnum(): return StringToEnum("DamageF")[0]
 def QmuDamageDEnum(): return StringToEnum("QmuDamageD")[0]
 def DamageDbarEnum(): return StringToEnum("DamageDbar")[0]
@@ -163,4 +174,5 @@
 def DamageC3Enum(): return StringToEnum("DamageC3")[0]
 def DamageC4Enum(): return StringToEnum("DamageC4")[0]
+def DamageElementinterpEnum(): return StringToEnum("DamageElementinterp")[0]
 def DamageHealingEnum(): return StringToEnum("DamageHealing")[0]
 def DamageStressThresholdEnum(): return StringToEnum("DamageStressThreshold")[0]
@@ -172,4 +184,7 @@
 def DamageSpcdamageEnum(): return StringToEnum("DamageSpcdamage")[0]
 def DamageMaxDamageEnum(): return StringToEnum("DamageMaxDamage")[0]
+def DamageEquivStressEnum(): return StringToEnum("DamageEquivStress")[0]
+def DamageEvolutionNumRequestedOutputsEnum(): return StringToEnum("DamageEvolutionNumRequestedOutputs")[0]
+def DamageEvolutionRequestedOutputsEnum(): return StringToEnum("DamageEvolutionRequestedOutputs")[0]
 def MaterialsRhoIceEnum(): return StringToEnum("MaterialsRhoIce")[0]
 def MaterialsRhoWaterEnum(): return StringToEnum("MaterialsRhoWater")[0]
@@ -178,4 +193,5 @@
 def MaterialsThermalExchangeVelocityEnum(): return StringToEnum("MaterialsThermalExchangeVelocity")[0]
 def MaterialsThermalconductivityEnum(): return StringToEnum("MaterialsThermalconductivity")[0]
+def MaterialsTemperateiceconductivityEnum(): return StringToEnum("MaterialsTemperateiceconductivity")[0]
 def MaterialsLithosphereShearModulusEnum(): return StringToEnum("MaterialsLithosphereShearModulus")[0]
 def MaterialsLithosphereDensityEnum(): return StringToEnum("MaterialsLithosphereDensity")[0]
@@ -183,5 +199,5 @@
 def MaterialsMantleDensityEnum(): return StringToEnum("MaterialsMantleDensity")[0]
 def MeshAverageVertexConnectivityEnum(): return StringToEnum("MeshAverageVertexConnectivity")[0]
-def MeshElementonbedEnum(): return StringToEnum("MeshElementonbed")[0]
+def MeshElementonbaseEnum(): return StringToEnum("MeshElementonbase")[0]
 def MeshElementonsurfaceEnum(): return StringToEnum("MeshElementonsurface")[0]
 def MeshElements2dEnum(): return StringToEnum("MeshElements2d")[0]
@@ -194,13 +210,15 @@
 def MeshNumberofverticesEnum(): return StringToEnum("MeshNumberofvertices")[0]
 def MeshUpperelementsEnum(): return StringToEnum("MeshUpperelements")[0]
-def MeshVertexonbedEnum(): return StringToEnum("MeshVertexonbed")[0]
+def MeshVertexonbaseEnum(): return StringToEnum("MeshVertexonbase")[0]
 def MeshVertexonsurfaceEnum(): return StringToEnum("MeshVertexonsurface")[0]
 def MeshXEnum(): return StringToEnum("MeshX")[0]
 def MeshYEnum(): return StringToEnum("MeshY")[0]
 def MeshZEnum(): return StringToEnum("MeshZ")[0]
-def MeshTypeEnum(): return StringToEnum("MeshType")[0]
-def Mesh2DhorizontalEnum(): return StringToEnum("Mesh2Dhorizontal")[0]
-def Mesh2DverticalEnum(): return StringToEnum("Mesh2Dvertical")[0]
-def Mesh3DEnum(): return StringToEnum("Mesh3D")[0]
+def MeshElementtypeEnum(): return StringToEnum("MeshElementtype")[0]
+def DomainTypeEnum(): return StringToEnum("DomainType")[0]
+def DomainDimensionEnum(): return StringToEnum("DomainDimension")[0]
+def Domain2DhorizontalEnum(): return StringToEnum("Domain2Dhorizontal")[0]
+def Domain2DverticalEnum(): return StringToEnum("Domain2Dvertical")[0]
+def Domain3DEnum(): return StringToEnum("Domain3D")[0]
 def MiscellaneousNameEnum(): return StringToEnum("MiscellaneousName")[0]
 def MasstransportHydrostaticAdjustmentEnum(): return StringToEnum("MasstransportHydrostaticAdjustment")[0]
@@ -209,4 +227,5 @@
 def MasstransportPenaltyFactorEnum(): return StringToEnum("MasstransportPenaltyFactor")[0]
 def MasstransportSpcthicknessEnum(): return StringToEnum("MasstransportSpcthickness")[0]
+def MasstransportCalvingrateEnum(): return StringToEnum("MasstransportCalvingrate")[0]
 def MasstransportStabilizationEnum(): return StringToEnum("MasstransportStabilization")[0]
 def MasstransportVertexPairingEnum(): return StringToEnum("MasstransportVertexPairing")[0]
@@ -225,14 +244,9 @@
 def RiftsNumriftsEnum(): return StringToEnum("RiftsNumrifts")[0]
 def RiftsRiftstructEnum(): return StringToEnum("RiftsRiftstruct")[0]
+def SettingsResultsOnNodesEnum(): return StringToEnum("SettingsResultsOnNodes")[0]
 def SettingsIoGatherEnum(): return StringToEnum("SettingsIoGather")[0]
 def SettingsLowmemEnum(): return StringToEnum("SettingsLowmem")[0]
 def SettingsOutputFrequencyEnum(): return StringToEnum("SettingsOutputFrequency")[0]
 def SettingsWaitonlockEnum(): return StringToEnum("SettingsWaitonlock")[0]
-def SurfaceforcingsDelta18oEnum(): return StringToEnum("SurfaceforcingsDelta18o")[0]
-def SurfaceforcingsDelta18oSurfaceEnum(): return StringToEnum("SurfaceforcingsDelta18oSurface")[0]
-def SurfaceforcingsIsdelta18oEnum(): return StringToEnum("SurfaceforcingsIsdelta18o")[0]
-def SurfaceforcingsPrecipitationsPresentdayEnum(): return StringToEnum("SurfaceforcingsPrecipitationsPresentday")[0]
-def SurfaceforcingsTemperaturesPresentdayEnum(): return StringToEnum("SurfaceforcingsTemperaturesPresentday")[0]
-def SurfaceforcingsTemperaturesLgmEnum(): return StringToEnum("SurfaceforcingsTemperaturesLgm")[0]
 def DebugProfilingEnum(): return StringToEnum("DebugProfiling")[0]
 def ProfilingCurrentMemEnum(): return StringToEnum("ProfilingCurrentMem")[0]
@@ -245,15 +259,4 @@
 def SteadystateRequestedOutputsEnum(): return StringToEnum("SteadystateRequestedOutputs")[0]
 def SurfaceEnum(): return StringToEnum("Surface")[0]
-def SurfaceforcingsPrecipitationEnum(): return StringToEnum("SurfaceforcingsPrecipitation")[0]
-def SurfaceforcingsMassBalanceEnum(): return StringToEnum("SurfaceforcingsMassBalance")[0]
-def SurfaceforcingsIspddEnum(): return StringToEnum("SurfaceforcingsIspdd")[0]
-def SurfaceforcingsDesfacEnum(): return StringToEnum("SurfaceforcingsDesfac")[0]
-def SurfaceforcingsS0pEnum(): return StringToEnum("SurfaceforcingsS0p")[0]
-def SurfaceforcingsIssmbgradientsEnum(): return StringToEnum("SurfaceforcingsIssmbgradients")[0]
-def SurfaceforcingsMonthlytemperaturesEnum(): return StringToEnum("SurfaceforcingsMonthlytemperatures")[0]
-def SurfaceforcingsHrefEnum(): return StringToEnum("SurfaceforcingsHref")[0]
-def SurfaceforcingsSmbrefEnum(): return StringToEnum("SurfaceforcingsSmbref")[0]
-def SurfaceforcingsBPosEnum(): return StringToEnum("SurfaceforcingsBPos")[0]
-def SurfaceforcingsBNegEnum(): return StringToEnum("SurfaceforcingsBNeg")[0]
 def ThermalIsenthalpyEnum(): return StringToEnum("ThermalIsenthalpy")[0]
 def ThermalIsdynamicbasalspcEnum(): return StringToEnum("ThermalIsdynamicbasalspc")[0]
@@ -279,7 +282,30 @@
 def TransientIsthermalEnum(): return StringToEnum("TransientIsthermal")[0]
 def TransientIsgiaEnum(): return StringToEnum("TransientIsgia")[0]
-def TransientIsdamageEnum(): return StringToEnum("TransientIsdamage")[0]
+def TransientIsdamageevolutionEnum(): return StringToEnum("TransientIsdamageevolution")[0]
+def TransientIshydrologyEnum(): return StringToEnum("TransientIshydrology")[0]
 def TransientNumRequestedOutputsEnum(): return StringToEnum("TransientNumRequestedOutputs")[0]
 def TransientRequestedOutputsEnum(): return StringToEnum("TransientRequestedOutputs")[0]
+def SurfaceforcingsEnum(): return StringToEnum("Surfaceforcings")[0]
+def SMBEnum(): return StringToEnum("SMB")[0]
+def SurfaceforcingsMassBalanceEnum(): return StringToEnum("SurfaceforcingsMassBalance")[0]
+def SMBpddEnum(): return StringToEnum("SMBpdd")[0]
+def SurfaceforcingsDelta18oEnum(): return StringToEnum("SurfaceforcingsDelta18o")[0]
+def SurfaceforcingsDelta18oSurfaceEnum(): return StringToEnum("SurfaceforcingsDelta18oSurface")[0]
+def SurfaceforcingsIsdelta18oEnum(): return StringToEnum("SurfaceforcingsIsdelta18o")[0]
+def SurfaceforcingsPrecipitationsPresentdayEnum(): return StringToEnum("SurfaceforcingsPrecipitationsPresentday")[0]
+def SurfaceforcingsTemperaturesPresentdayEnum(): return StringToEnum("SurfaceforcingsTemperaturesPresentday")[0]
+def SurfaceforcingsTemperaturesLgmEnum(): return StringToEnum("SurfaceforcingsTemperaturesLgm")[0]
+def SurfaceforcingsPrecipitationEnum(): return StringToEnum("SurfaceforcingsPrecipitation")[0]
+def SurfaceforcingsDesfacEnum(): return StringToEnum("SurfaceforcingsDesfac")[0]
+def SurfaceforcingsS0pEnum(): return StringToEnum("SurfaceforcingsS0p")[0]
+def SMBgradientsEnum(): return StringToEnum("SMBgradients")[0]
+def SurfaceforcingsMonthlytemperaturesEnum(): return StringToEnum("SurfaceforcingsMonthlytemperatures")[0]
+def SurfaceforcingsHrefEnum(): return StringToEnum("SurfaceforcingsHref")[0]
+def SurfaceforcingsSmbrefEnum(): return StringToEnum("SurfaceforcingsSmbref")[0]
+def SurfaceforcingsBPosEnum(): return StringToEnum("SurfaceforcingsBPos")[0]
+def SurfaceforcingsBNegEnum(): return StringToEnum("SurfaceforcingsBNeg")[0]
+def SMBhenningEnum(): return StringToEnum("SMBhenning")[0]
+def SurfaceforcingsIspddEnum(): return StringToEnum("SurfaceforcingsIspdd")[0]
+def SurfaceforcingsIssmbgradientsEnum(): return StringToEnum("SurfaceforcingsIssmbgradients")[0]
 def SolutionTypeEnum(): return StringToEnum("SolutionType")[0]
 def AnalysisTypeEnum(): return StringToEnum("AnalysisType")[0]
@@ -295,4 +321,5 @@
 def BalancevelocityAnalysisEnum(): return StringToEnum("BalancevelocityAnalysis")[0]
 def BalancevelocitySolutionEnum(): return StringToEnum("BalancevelocitySolution")[0]
+def L2ProjectionEPLAnalysisEnum(): return StringToEnum("L2ProjectionEPLAnalysis")[0]
 def L2ProjectionBaseAnalysisEnum(): return StringToEnum("L2ProjectionBaseAnalysis")[0]
 def BedSlopeSolutionEnum(): return StringToEnum("BedSlopeSolution")[0]
@@ -315,8 +342,9 @@
 def FreeSurfaceBaseAnalysisEnum(): return StringToEnum("FreeSurfaceBaseAnalysis")[0]
 def FreeSurfaceTopAnalysisEnum(): return StringToEnum("FreeSurfaceTopAnalysis")[0]
+def SurfaceNormalVelocityEnum(): return StringToEnum("SurfaceNormalVelocity")[0]
 def ExtrudeFromBaseAnalysisEnum(): return StringToEnum("ExtrudeFromBaseAnalysis")[0]
 def ExtrudeFromTopAnalysisEnum(): return StringToEnum("ExtrudeFromTopAnalysis")[0]
+def DepthAverageAnalysisEnum(): return StringToEnum("DepthAverageAnalysis")[0]
 def SteadystateSolutionEnum(): return StringToEnum("SteadystateSolution")[0]
-def L2ProjectionTopAnalysisEnum(): return StringToEnum("L2ProjectionTopAnalysis")[0]
 def SurfaceSlopeSolutionEnum(): return StringToEnum("SurfaceSlopeSolution")[0]
 def SmoothedSurfaceSlopeXAnalysisEnum(): return StringToEnum("SmoothedSurfaceSlopeXAnalysis")[0]
@@ -329,4 +357,7 @@
 def MeshdeformationSolutionEnum(): return StringToEnum("MeshdeformationSolution")[0]
 def MeshdeformationAnalysisEnum(): return StringToEnum("MeshdeformationAnalysis")[0]
+def LevelsetAnalysisEnum(): return StringToEnum("LevelsetAnalysis")[0]
+def ExtrapolationAnalysisEnum(): return StringToEnum("ExtrapolationAnalysis")[0]
+def LsfReinitializationAnalysisEnum(): return StringToEnum("LsfReinitializationAnalysis")[0]
 def ApproximationEnum(): return StringToEnum("Approximation")[0]
 def NoneApproximationEnum(): return StringToEnum("NoneApproximation")[0]
@@ -369,8 +400,10 @@
 def InputToExtrudeEnum(): return StringToEnum("InputToExtrude")[0]
 def InputToL2ProjectEnum(): return StringToEnum("InputToL2Project")[0]
+def InputToDepthaverageEnum(): return StringToEnum("InputToDepthaverage")[0]
 def IntParamEnum(): return StringToEnum("IntParam")[0]
 def IntVecParamEnum(): return StringToEnum("IntVecParam")[0]
 def TransientParamEnum(): return StringToEnum("TransientParam")[0]
 def MaticeEnum(): return StringToEnum("Matice")[0]
+def MatdamageiceEnum(): return StringToEnum("Matdamageice")[0]
 def MatparEnum(): return StringToEnum("Matpar")[0]
 def NodeEnum(): return StringToEnum("Node")[0]
@@ -380,6 +413,4 @@
 def PengridEnum(): return StringToEnum("Pengrid")[0]
 def PenpairEnum(): return StringToEnum("Penpair")[0]
-def PentaEnum(): return StringToEnum("Penta")[0]
-def PentaInputEnum(): return StringToEnum("PentaInput")[0]
 def ProfilerEnum(): return StringToEnum("Profiler")[0]
 def MatrixParamEnum(): return StringToEnum("MatrixParam")[0]
@@ -399,4 +430,8 @@
 def TriaEnum(): return StringToEnum("Tria")[0]
 def TriaInputEnum(): return StringToEnum("TriaInput")[0]
+def TetraEnum(): return StringToEnum("Tetra")[0]
+def TetraInputEnum(): return StringToEnum("TetraInput")[0]
+def PentaEnum(): return StringToEnum("Penta")[0]
+def PentaInputEnum(): return StringToEnum("PentaInput")[0]
 def VertexEnum(): return StringToEnum("Vertex")[0]
 def VertexPIdEnum(): return StringToEnum("VertexPId")[0]
@@ -433,5 +468,5 @@
 def QmuVzEnum(): return StringToEnum("QmuVz")[0]
 def QmuThicknessEnum(): return StringToEnum("QmuThickness")[0]
-def QmuBedEnum(): return StringToEnum("QmuBed")[0]
+def QmuBaseEnum(): return StringToEnum("QmuBase")[0]
 def QmuSurfaceEnum(): return StringToEnum("QmuSurface")[0]
 def QmuMeltingEnum(): return StringToEnum("QmuMelting")[0]
@@ -492,4 +527,19 @@
 def StressTensoryzEnum(): return StringToEnum("StressTensoryz")[0]
 def StressTensorzzEnum(): return StringToEnum("StressTensorzz")[0]
+def DeviatoricStressEnum(): return StringToEnum("DeviatoricStress")[0]
+def DeviatoricStressxxEnum(): return StringToEnum("DeviatoricStressxx")[0]
+def DeviatoricStressxyEnum(): return StringToEnum("DeviatoricStressxy")[0]
+def DeviatoricStressxzEnum(): return StringToEnum("DeviatoricStressxz")[0]
+def DeviatoricStressyyEnum(): return StringToEnum("DeviatoricStressyy")[0]
+def DeviatoricStressyzEnum(): return StringToEnum("DeviatoricStressyz")[0]
+def DeviatoricStresszzEnum(): return StringToEnum("DeviatoricStresszz")[0]
+def StrainRateEnum(): return StringToEnum("StrainRate")[0]
+def StrainRatexxEnum(): return StringToEnum("StrainRatexx")[0]
+def StrainRatexyEnum(): return StringToEnum("StrainRatexy")[0]
+def StrainRatexzEnum(): return StringToEnum("StrainRatexz")[0]
+def StrainRateyyEnum(): return StringToEnum("StrainRateyy")[0]
+def StrainRateyzEnum(): return StringToEnum("StrainRateyz")[0]
+def StrainRatezzEnum(): return StringToEnum("StrainRatezz")[0]
+def DivergenceEnum(): return StringToEnum("Divergence")[0]
 def GiaCrossSectionShapeEnum(): return StringToEnum("GiaCrossSectionShape")[0]
 def GiadWdtEnum(): return StringToEnum("GiadWdt")[0]
@@ -503,4 +553,6 @@
 def P2xP1Enum(): return StringToEnum("P2xP1")[0]
 def P1xP2Enum(): return StringToEnum("P1xP2")[0]
+def P1xP3Enum(): return StringToEnum("P1xP3")[0]
+def P2xP4Enum(): return StringToEnum("P2xP4")[0]
 def P1P1Enum(): return StringToEnum("P1P1")[0]
 def P1P1GLSEnum(): return StringToEnum("P1P1GLS")[0]
@@ -508,6 +560,6 @@
 def MINIcondensedEnum(): return StringToEnum("MINIcondensed")[0]
 def TaylorHoodEnum(): return StringToEnum("TaylorHood")[0]
-def P2xP4Enum(): return StringToEnum("P2xP4")[0]
-def P1xP3Enum(): return StringToEnum("P1xP3")[0]
+def XTaylorHoodEnum(): return StringToEnum("XTaylorHood")[0]
+def OneLayerP4zEnum(): return StringToEnum("OneLayerP4z")[0]
 def SaveResultsEnum(): return StringToEnum("SaveResults")[0]
 def BoolExternalResultEnum(): return StringToEnum("BoolExternalResult")[0]
@@ -525,4 +577,13 @@
 def MassfluxatgateNameEnum(): return StringToEnum("MassfluxatgateName")[0]
 def MassfluxatgateSegmentsEnum(): return StringToEnum("MassfluxatgateSegments")[0]
+def MisfitNameEnum(): return StringToEnum("MisfitName")[0]
+def MisfitModelEnumEnum(): return StringToEnum("MisfitModelEnum")[0]
+def MisfitObservationEnum(): return StringToEnum("MisfitObservation")[0]
+def MisfitObservationEnumEnum(): return StringToEnum("MisfitObservationEnum")[0]
+def MisfitTimeinterpolationEnum(): return StringToEnum("MisfitTimeinterpolation")[0]
+def MisfitWeightsEnum(): return StringToEnum("MisfitWeights")[0]
+def MisfitWeightsEnumEnum(): return StringToEnum("MisfitWeightsEnum")[0]
+def SurfaceObservationEnum(): return StringToEnum("SurfaceObservation")[0]
+def WeightsSurfaceObservationEnum(): return StringToEnum("WeightsSurfaceObservation")[0]
 def MinVelEnum(): return StringToEnum("MinVel")[0]
 def MaxVelEnum(): return StringToEnum("MaxVel")[0]
@@ -541,11 +602,18 @@
 def AbsoluteEnum(): return StringToEnum("Absolute")[0]
 def IncrementalEnum(): return StringToEnum("Incremental")[0]
+def AugmentedLagrangianREnum(): return StringToEnum("AugmentedLagrangianR")[0]
+def AugmentedLagrangianThetaEnum(): return StringToEnum("AugmentedLagrangianTheta")[0]
+def NoneEnum(): return StringToEnum("None")[0]
 def AgressiveMigrationEnum(): return StringToEnum("AgressiveMigration")[0]
-def NoneEnum(): return StringToEnum("None")[0]
 def SoftMigrationEnum(): return StringToEnum("SoftMigration")[0]
 def SubelementMigrationEnum(): return StringToEnum("SubelementMigration")[0]
 def SubelementMigration2Enum(): return StringToEnum("SubelementMigration2")[0]
+def ContactEnum(): return StringToEnum("Contact")[0]
 def MaskGroundediceLevelsetEnum(): return StringToEnum("MaskGroundediceLevelset")[0]
 def QmuMaskGroundediceLevelsetEnum(): return StringToEnum("QmuMaskGroundediceLevelset")[0]
+def GaussSegEnum(): return StringToEnum("GaussSeg")[0]
+def GaussTriaEnum(): return StringToEnum("GaussTria")[0]
+def GaussTetraEnum(): return StringToEnum("GaussTetra")[0]
+def GaussPentaEnum(): return StringToEnum("GaussPenta")[0]
 def FSSolverEnum(): return StringToEnum("FSSolver")[0]
 def AdjointEnum(): return StringToEnum("Adjoint")[0]
@@ -593,6 +661,13 @@
 def OptionCellEnum(): return StringToEnum("OptionCell")[0]
 def OptionStructEnum(): return StringToEnum("OptionStruct")[0]
+def CuffeyEnum(): return StringToEnum("Cuffey")[0]
 def PatersonEnum(): return StringToEnum("Paterson")[0]
 def ArrheniusEnum(): return StringToEnum("Arrhenius")[0]
 def LliboutryDuvalEnum(): return StringToEnum("LliboutryDuval")[0]
+def TransientIslevelsetEnum(): return StringToEnum("TransientIslevelset")[0]
+def ExtrapolationVariableEnum(): return StringToEnum("ExtrapolationVariable")[0]
+def IceMaskNodeActivationEnum(): return StringToEnum("IceMaskNodeActivation")[0]
+def LevelsetfunctionSlopeXEnum(): return StringToEnum("LevelsetfunctionSlopeX")[0]
+def LevelsetfunctionSlopeYEnum(): return StringToEnum("LevelsetfunctionSlopeY")[0]
+def LevelsetfunctionPicardEnum(): return StringToEnum("LevelsetfunctionPicard")[0]
 def MaximumNumberOfDefinitionsEnum(): return StringToEnum("MaximumNumberOfDefinitions")[0]
Index: /issm/trunk/src/m/enum/EplHeadSlopeXEnum.m
===================================================================
--- /issm/trunk/src/m/enum/EplHeadSlopeXEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/EplHeadSlopeXEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=EplHeadSlopeXEnum()
+%EPLHEADSLOPEXENUM - Enum of EplHeadSlopeX
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=EplHeadSlopeXEnum()
+
+macro=StringToEnum('EplHeadSlopeX');
Index: /issm/trunk/src/m/enum/EplHeadSlopeYEnum.m
===================================================================
--- /issm/trunk/src/m/enum/EplHeadSlopeYEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/EplHeadSlopeYEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=EplHeadSlopeYEnum()
+%EPLHEADSLOPEYENUM - Enum of EplHeadSlopeY
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=EplHeadSlopeYEnum()
+
+macro=StringToEnum('EplHeadSlopeY');
Index: /issm/trunk/src/m/enum/ExtrapolationAnalysisEnum.m
===================================================================
--- /issm/trunk/src/m/enum/ExtrapolationAnalysisEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/ExtrapolationAnalysisEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=ExtrapolationAnalysisEnum()
+%EXTRAPOLATIONANALYSISENUM - Enum of ExtrapolationAnalysis
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=ExtrapolationAnalysisEnum()
+
+macro=StringToEnum('ExtrapolationAnalysis');
Index: /issm/trunk/src/m/enum/ExtrapolationVariableEnum.m
===================================================================
--- /issm/trunk/src/m/enum/ExtrapolationVariableEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/ExtrapolationVariableEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=ExtrapolationVariableEnum()
+%EXTRAPOLATIONVARIABLEENUM - Enum of ExtrapolationVariable
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=ExtrapolationVariableEnum()
+
+macro=StringToEnum('ExtrapolationVariable');
Index: /issm/trunk/src/m/enum/GaussPentaEnum.m
===================================================================
--- /issm/trunk/src/m/enum/GaussPentaEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/GaussPentaEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=GaussPentaEnum()
+%GAUSSPENTAENUM - Enum of GaussPenta
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=GaussPentaEnum()
+
+macro=StringToEnum('GaussPenta');
Index: /issm/trunk/src/m/enum/GaussSegEnum.m
===================================================================
--- /issm/trunk/src/m/enum/GaussSegEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/GaussSegEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=GaussSegEnum()
+%GAUSSSEGENUM - Enum of GaussSeg
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=GaussSegEnum()
+
+macro=StringToEnum('GaussSeg');
Index: /issm/trunk/src/m/enum/GaussTetraEnum.m
===================================================================
--- /issm/trunk/src/m/enum/GaussTetraEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/GaussTetraEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=GaussTetraEnum()
+%GAUSSTETRAENUM - Enum of GaussTetra
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=GaussTetraEnum()
+
+macro=StringToEnum('GaussTetra');
Index: /issm/trunk/src/m/enum/GaussTriaEnum.m
===================================================================
--- /issm/trunk/src/m/enum/GaussTriaEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/GaussTriaEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=GaussTriaEnum()
+%GAUSSTRIAENUM - Enum of GaussTria
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=GaussTriaEnum()
+
+macro=StringToEnum('GaussTria');
Index: /issm/trunk/src/m/enum/HydrologydcBasalMoulinInputEnum.m
===================================================================
--- /issm/trunk/src/m/enum/HydrologydcBasalMoulinInputEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/HydrologydcBasalMoulinInputEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=HydrologydcBasalMoulinInputEnum()
+%HYDROLOGYDCBASALMOULININPUTENUM - Enum of HydrologydcBasalMoulinInput
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=HydrologydcBasalMoulinInputEnum()
+
+macro=StringToEnum('HydrologydcBasalMoulinInput');
Index: /issm/trunk/src/m/enum/HydrologydcEplConductivityEnum.m
===================================================================
--- /issm/trunk/src/m/enum/HydrologydcEplConductivityEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/HydrologydcEplConductivityEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=HydrologydcEplConductivityEnum()
+%HYDROLOGYDCEPLCONDUCTIVITYENUM - Enum of HydrologydcEplConductivity
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=HydrologydcEplConductivityEnum()
+
+macro=StringToEnum('HydrologydcEplConductivity');
Index: /issm/trunk/src/m/enum/HydrologydcEplInitialThicknessEnum.m
===================================================================
--- /issm/trunk/src/m/enum/HydrologydcEplInitialThicknessEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/HydrologydcEplInitialThicknessEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=HydrologydcEplInitialThicknessEnum()
+%HYDROLOGYDCEPLINITIALTHICKNESSENUM - Enum of HydrologydcEplInitialThickness
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=HydrologydcEplInitialThicknessEnum()
+
+macro=StringToEnum('HydrologydcEplInitialThickness');
Index: /issm/trunk/src/m/enum/HydrologydcEplMaxThicknessEnum.m
===================================================================
--- /issm/trunk/src/m/enum/HydrologydcEplMaxThicknessEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/HydrologydcEplMaxThicknessEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=HydrologydcEplMaxThicknessEnum()
+%HYDROLOGYDCEPLMAXTHICKNESSENUM - Enum of HydrologydcEplMaxThickness
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=HydrologydcEplMaxThicknessEnum()
+
+macro=StringToEnum('HydrologydcEplMaxThickness');
Index: /issm/trunk/src/m/enum/HydrologydcEplThicknessOldEnum.m
===================================================================
--- /issm/trunk/src/m/enum/HydrologydcEplThicknessOldEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/HydrologydcEplThicknessOldEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=HydrologydcEplThicknessOldEnum()
+%HYDROLOGYDCEPLTHICKNESSOLDENUM - Enum of HydrologydcEplThicknessOld
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=HydrologydcEplThicknessOldEnum()
+
+macro=StringToEnum('HydrologydcEplThicknessOld');
Index: sm/trunk/src/m/enum/HydrologydcEplTransmitivityEnum.m
===================================================================
--- /issm/trunk/src/m/enum/HydrologydcEplTransmitivityEnum.m	(revision 17805)
+++ 	(revision )
@@ -1,11 +1,0 @@
-function macro=HydrologydcEplTransmitivityEnum()
-%HYDROLOGYDCEPLTRANSMITIVITYENUM - Enum of HydrologydcEplTransmitivity
-%
-%   WARNING: DO NOT MODIFY THIS FILE
-%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
-%            Please read src/c/shared/Enum/README for more information
-%
-%   Usage:
-%      macro=HydrologydcEplTransmitivityEnum()
-
-macro=StringToEnum('HydrologydcEplTransmitivity');
Index: /issm/trunk/src/m/enum/HydrologydcMaskEplactiveEltEnum.m
===================================================================
--- /issm/trunk/src/m/enum/HydrologydcMaskEplactiveEltEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/HydrologydcMaskEplactiveEltEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=HydrologydcMaskEplactiveEltEnum()
+%HYDROLOGYDCMASKEPLACTIVEELTENUM - Enum of HydrologydcMaskEplactiveElt
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=HydrologydcMaskEplactiveEltEnum()
+
+macro=StringToEnum('HydrologydcMaskEplactiveElt');
Index: sm/trunk/src/m/enum/HydrologydcMaskEplactiveEnum.m
===================================================================
--- /issm/trunk/src/m/enum/HydrologydcMaskEplactiveEnum.m	(revision 17805)
+++ 	(revision )
@@ -1,11 +1,0 @@
-function macro=HydrologydcMaskEplactiveEnum()
-%HYDROLOGYDCMASKEPLACTIVEENUM - Enum of HydrologydcMaskEplactive
-%
-%   WARNING: DO NOT MODIFY THIS FILE
-%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
-%            Please read src/c/shared/Enum/README for more information
-%
-%   Usage:
-%      macro=HydrologydcMaskEplactiveEnum()
-
-macro=StringToEnum('HydrologydcMaskEplactive');
Index: /issm/trunk/src/m/enum/HydrologydcMaskEplactiveNodeEnum.m
===================================================================
--- /issm/trunk/src/m/enum/HydrologydcMaskEplactiveNodeEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/HydrologydcMaskEplactiveNodeEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=HydrologydcMaskEplactiveNodeEnum()
+%HYDROLOGYDCMASKEPLACTIVENODEENUM - Enum of HydrologydcMaskEplactiveNode
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=HydrologydcMaskEplactiveNodeEnum()
+
+macro=StringToEnum('HydrologydcMaskEplactiveNode');
Index: /issm/trunk/src/m/enum/HydrologydcMaxIterEnum.m
===================================================================
--- /issm/trunk/src/m/enum/HydrologydcMaxIterEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/HydrologydcMaxIterEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=HydrologydcMaxIterEnum()
+%HYDROLOGYDCMAXITERENUM - Enum of HydrologydcMaxIter
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=HydrologydcMaxIterEnum()
+
+macro=StringToEnum('HydrologydcMaxIter');
Index: /issm/trunk/src/m/enum/HydrologydcPenaltyLockEnum.m
===================================================================
--- /issm/trunk/src/m/enum/HydrologydcPenaltyLockEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/HydrologydcPenaltyLockEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=HydrologydcPenaltyLockEnum()
+%HYDROLOGYDCPENALTYLOCKENUM - Enum of HydrologydcPenaltyLock
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=HydrologydcPenaltyLockEnum()
+
+macro=StringToEnum('HydrologydcPenaltyLock');
Index: /issm/trunk/src/m/enum/IceMaskNodeActivationEnum.m
===================================================================
--- /issm/trunk/src/m/enum/IceMaskNodeActivationEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/IceMaskNodeActivationEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=IceMaskNodeActivationEnum()
+%ICEMASKNODEACTIVATIONENUM - Enum of IceMaskNodeActivation
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=IceMaskNodeActivationEnum()
+
+macro=StringToEnum('IceMaskNodeActivation');
Index: /issm/trunk/src/m/enum/InputToDepthaverageEnum.m
===================================================================
--- /issm/trunk/src/m/enum/InputToDepthaverageEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/InputToDepthaverageEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=InputToDepthaverageEnum()
+%INPUTTODEPTHAVERAGEENUM - Enum of InputToDepthaverage
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=InputToDepthaverageEnum()
+
+macro=StringToEnum('InputToDepthaverage');
Index: /issm/trunk/src/m/enum/L2ProjectionEPLAnalysisEnum.m
===================================================================
--- /issm/trunk/src/m/enum/L2ProjectionEPLAnalysisEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/L2ProjectionEPLAnalysisEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=L2ProjectionEPLAnalysisEnum()
+%L2PROJECTIONEPLANALYSISENUM - Enum of L2ProjectionEPLAnalysis
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=L2ProjectionEPLAnalysisEnum()
+
+macro=StringToEnum('L2ProjectionEPLAnalysis');
Index: sm/trunk/src/m/enum/L2ProjectionTopAnalysisEnum.m
===================================================================
--- /issm/trunk/src/m/enum/L2ProjectionTopAnalysisEnum.m	(revision 17805)
+++ 	(revision )
@@ -1,11 +1,0 @@
-function macro=L2ProjectionTopAnalysisEnum()
-%L2PROJECTIONTOPANALYSISENUM - Enum of L2ProjectionTopAnalysis
-%
-%   WARNING: DO NOT MODIFY THIS FILE
-%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
-%            Please read src/c/shared/Enum/README for more information
-%
-%   Usage:
-%      macro=L2ProjectionTopAnalysisEnum()
-
-macro=StringToEnum('L2ProjectionTopAnalysis');
Index: /issm/trunk/src/m/enum/LevelsetAnalysisEnum.m
===================================================================
--- /issm/trunk/src/m/enum/LevelsetAnalysisEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/LevelsetAnalysisEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=LevelsetAnalysisEnum()
+%LEVELSETANALYSISENUM - Enum of LevelsetAnalysis
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=LevelsetAnalysisEnum()
+
+macro=StringToEnum('LevelsetAnalysis');
Index: /issm/trunk/src/m/enum/LevelsetfunctionPicardEnum.m
===================================================================
--- /issm/trunk/src/m/enum/LevelsetfunctionPicardEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/LevelsetfunctionPicardEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=LevelsetfunctionPicardEnum()
+%LEVELSETFUNCTIONPICARDENUM - Enum of LevelsetfunctionPicard
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=LevelsetfunctionPicardEnum()
+
+macro=StringToEnum('LevelsetfunctionPicard');
Index: /issm/trunk/src/m/enum/LevelsetfunctionSlopeXEnum.m
===================================================================
--- /issm/trunk/src/m/enum/LevelsetfunctionSlopeXEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/LevelsetfunctionSlopeXEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=LevelsetfunctionSlopeXEnum()
+%LEVELSETFUNCTIONSLOPEXENUM - Enum of LevelsetfunctionSlopeX
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=LevelsetfunctionSlopeXEnum()
+
+macro=StringToEnum('LevelsetfunctionSlopeX');
Index: /issm/trunk/src/m/enum/LevelsetfunctionSlopeYEnum.m
===================================================================
--- /issm/trunk/src/m/enum/LevelsetfunctionSlopeYEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/LevelsetfunctionSlopeYEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=LevelsetfunctionSlopeYEnum()
+%LEVELSETFUNCTIONSLOPEYENUM - Enum of LevelsetfunctionSlopeY
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=LevelsetfunctionSlopeYEnum()
+
+macro=StringToEnum('LevelsetfunctionSlopeY');
Index: /issm/trunk/src/m/enum/LsfReinitializationAnalysisEnum.m
===================================================================
--- /issm/trunk/src/m/enum/LsfReinitializationAnalysisEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/LsfReinitializationAnalysisEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=LsfReinitializationAnalysisEnum()
+%LSFREINITIALIZATIONANALYSISENUM - Enum of LsfReinitializationAnalysis
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=LsfReinitializationAnalysisEnum()
+
+macro=StringToEnum('LsfReinitializationAnalysis');
Index: /issm/trunk/src/m/enum/MasstransportCalvingrateEnum.m
===================================================================
--- /issm/trunk/src/m/enum/MasstransportCalvingrateEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/MasstransportCalvingrateEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=MasstransportCalvingrateEnum()
+%MASSTRANSPORTCALVINGRATEENUM - Enum of MasstransportCalvingrate
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=MasstransportCalvingrateEnum()
+
+macro=StringToEnum('MasstransportCalvingrate');
Index: /issm/trunk/src/m/enum/MatdamageiceEnum.m
===================================================================
--- /issm/trunk/src/m/enum/MatdamageiceEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/MatdamageiceEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=MatdamageiceEnum()
+%MATDAMAGEICEENUM - Enum of Matdamageice
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=MatdamageiceEnum()
+
+macro=StringToEnum('Matdamageice');
Index: /issm/trunk/src/m/enum/MaterialsTemperateiceconductivityEnum.m
===================================================================
--- /issm/trunk/src/m/enum/MaterialsTemperateiceconductivityEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/MaterialsTemperateiceconductivityEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=MaterialsTemperateiceconductivityEnum()
+%MATERIALSTEMPERATEICECONDUCTIVITYENUM - Enum of MaterialsTemperateiceconductivity
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=MaterialsTemperateiceconductivityEnum()
+
+macro=StringToEnum('MaterialsTemperateiceconductivity');
Index: sm/trunk/src/m/enum/Mesh2DhorizontalEnum.m
===================================================================
--- /issm/trunk/src/m/enum/Mesh2DhorizontalEnum.m	(revision 17805)
+++ 	(revision )
@@ -1,11 +1,0 @@
-function macro=Mesh2DhorizontalEnum()
-%MESH2DHORIZONTALENUM - Enum of Mesh2Dhorizontal
-%
-%   WARNING: DO NOT MODIFY THIS FILE
-%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
-%            Please read src/c/shared/Enum/README for more information
-%
-%   Usage:
-%      macro=Mesh2DhorizontalEnum()
-
-macro=StringToEnum('Mesh2Dhorizontal');
Index: sm/trunk/src/m/enum/Mesh2DverticalEnum.m
===================================================================
--- /issm/trunk/src/m/enum/Mesh2DverticalEnum.m	(revision 17805)
+++ 	(revision )
@@ -1,11 +1,0 @@
-function macro=Mesh2DverticalEnum()
-%MESH2DVERTICALENUM - Enum of Mesh2Dvertical
-%
-%   WARNING: DO NOT MODIFY THIS FILE
-%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
-%            Please read src/c/shared/Enum/README for more information
-%
-%   Usage:
-%      macro=Mesh2DverticalEnum()
-
-macro=StringToEnum('Mesh2Dvertical');
Index: sm/trunk/src/m/enum/Mesh3DEnum.m
===================================================================
--- /issm/trunk/src/m/enum/Mesh3DEnum.m	(revision 17805)
+++ 	(revision )
@@ -1,11 +1,0 @@
-function macro=Mesh3DEnum()
-%MESH3DENUM - Enum of Mesh3D
-%
-%   WARNING: DO NOT MODIFY THIS FILE
-%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
-%            Please read src/c/shared/Enum/README for more information
-%
-%   Usage:
-%      macro=Mesh3DEnum()
-
-macro=StringToEnum('Mesh3D');
Index: /issm/trunk/src/m/enum/MeshElementonbaseEnum.m
===================================================================
--- /issm/trunk/src/m/enum/MeshElementonbaseEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/MeshElementonbaseEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=MeshElementonbaseEnum()
+%MESHELEMENTONBASEENUM - Enum of MeshElementonbase
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=MeshElementonbaseEnum()
+
+macro=StringToEnum('MeshElementonbase');
Index: sm/trunk/src/m/enum/MeshElementonbedEnum.m
===================================================================
--- /issm/trunk/src/m/enum/MeshElementonbedEnum.m	(revision 17805)
+++ 	(revision )
@@ -1,11 +1,0 @@
-function macro=MeshElementonbedEnum()
-%MESHELEMENTONBEDENUM - Enum of MeshElementonbed
-%
-%   WARNING: DO NOT MODIFY THIS FILE
-%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
-%            Please read src/c/shared/Enum/README for more information
-%
-%   Usage:
-%      macro=MeshElementonbedEnum()
-
-macro=StringToEnum('MeshElementonbed');
Index: /issm/trunk/src/m/enum/MeshElementtypeEnum.m
===================================================================
--- /issm/trunk/src/m/enum/MeshElementtypeEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/MeshElementtypeEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=MeshElementtypeEnum()
+%MESHELEMENTTYPEENUM - Enum of MeshElementtype
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=MeshElementtypeEnum()
+
+macro=StringToEnum('MeshElementtype');
Index: sm/trunk/src/m/enum/MeshTypeEnum.m
===================================================================
--- /issm/trunk/src/m/enum/MeshTypeEnum.m	(revision 17805)
+++ 	(revision )
@@ -1,11 +1,0 @@
-function macro=MeshTypeEnum()
-%MESHTYPEENUM - Enum of MeshType
-%
-%   WARNING: DO NOT MODIFY THIS FILE
-%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
-%            Please read src/c/shared/Enum/README for more information
-%
-%   Usage:
-%      macro=MeshTypeEnum()
-
-macro=StringToEnum('MeshType');
Index: /issm/trunk/src/m/enum/MeshVertexonbaseEnum.m
===================================================================
--- /issm/trunk/src/m/enum/MeshVertexonbaseEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/MeshVertexonbaseEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=MeshVertexonbaseEnum()
+%MESHVERTEXONBASEENUM - Enum of MeshVertexonbase
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=MeshVertexonbaseEnum()
+
+macro=StringToEnum('MeshVertexonbase');
Index: sm/trunk/src/m/enum/MeshVertexonbedEnum.m
===================================================================
--- /issm/trunk/src/m/enum/MeshVertexonbedEnum.m	(revision 17805)
+++ 	(revision )
@@ -1,11 +1,0 @@
-function macro=MeshVertexonbedEnum()
-%MESHVERTEXONBEDENUM - Enum of MeshVertexonbed
-%
-%   WARNING: DO NOT MODIFY THIS FILE
-%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
-%            Please read src/c/shared/Enum/README for more information
-%
-%   Usage:
-%      macro=MeshVertexonbedEnum()
-
-macro=StringToEnum('MeshVertexonbed');
Index: /issm/trunk/src/m/enum/MisfitModelEnumEnum.m
===================================================================
--- /issm/trunk/src/m/enum/MisfitModelEnumEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/MisfitModelEnumEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=MisfitModelEnumEnum()
+%MISFITMODELENUMENUM - Enum of MisfitModel
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=MisfitModelEnumEnum()
+
+macro=StringToEnum('MisfitModel');
Index: /issm/trunk/src/m/enum/MisfitNameEnum.m
===================================================================
--- /issm/trunk/src/m/enum/MisfitNameEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/MisfitNameEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=MisfitNameEnum()
+%MISFITNAMEENUM - Enum of MisfitName
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=MisfitNameEnum()
+
+macro=StringToEnum('MisfitName');
Index: /issm/trunk/src/m/enum/MisfitObservationEnum.m
===================================================================
--- /issm/trunk/src/m/enum/MisfitObservationEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/MisfitObservationEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=MisfitObservationEnum()
+%MISFITOBSERVATIONENUM - Enum of MisfitObservation
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=MisfitObservationEnum()
+
+macro=StringToEnum('MisfitObservation');
Index: /issm/trunk/src/m/enum/MisfitObservationEnumEnum.m
===================================================================
--- /issm/trunk/src/m/enum/MisfitObservationEnumEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/MisfitObservationEnumEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=MisfitObservationEnumEnum()
+%MISFITOBSERVATIONENUMENUM - Enum of MisfitObservation
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=MisfitObservationEnumEnum()
+
+macro=StringToEnum('MisfitObservation');
Index: /issm/trunk/src/m/enum/MisfitTimeinterpolationEnum.m
===================================================================
--- /issm/trunk/src/m/enum/MisfitTimeinterpolationEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/MisfitTimeinterpolationEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=MisfitTimeinterpolationEnum()
+%MISFITTIMEINTERPOLATIONENUM - Enum of MisfitTimeinterpolation
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=MisfitTimeinterpolationEnum()
+
+macro=StringToEnum('MisfitTimeinterpolation');
Index: /issm/trunk/src/m/enum/MisfitWeightsEnum.m
===================================================================
--- /issm/trunk/src/m/enum/MisfitWeightsEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/MisfitWeightsEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=MisfitWeightsEnum()
+%MISFITWEIGHTSENUM - Enum of MisfitWeights
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=MisfitWeightsEnum()
+
+macro=StringToEnum('MisfitWeights');
Index: /issm/trunk/src/m/enum/MisfitWeightsEnumEnum.m
===================================================================
--- /issm/trunk/src/m/enum/MisfitWeightsEnumEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/MisfitWeightsEnumEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=MisfitWeightsEnumEnum()
+%MISFITWEIGHTSENUMENUM - Enum of MisfitWeights
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=MisfitWeightsEnumEnum()
+
+macro=StringToEnum('MisfitWeights');
Index: /issm/trunk/src/m/enum/OneLayerP4zEnum.m
===================================================================
--- /issm/trunk/src/m/enum/OneLayerP4zEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/OneLayerP4zEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=OneLayerP4zEnum()
+%ONELAYERP4ZENUM - Enum of OneLayerP4z
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=OneLayerP4zEnum()
+
+macro=StringToEnum('OneLayerP4z');
Index: /issm/trunk/src/m/enum/P1xP3Enum.m
===================================================================
--- /issm/trunk/src/m/enum/P1xP3Enum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/P1xP3Enum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=P1xP3Enum()
+%P1XP3ENUM - Enum of P1xP3
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=P1xP3Enum()
+
+macro=StringToEnum('P1xP3');
Index: /issm/trunk/src/m/enum/P2xP4Enum.m
===================================================================
--- /issm/trunk/src/m/enum/P2xP4Enum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/P2xP4Enum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=P2xP4Enum()
+%P2XP4ENUM - Enum of P2xP4
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=P2xP4Enum()
+
+macro=StringToEnum('P2xP4');
Index: /issm/trunk/src/m/enum/QmuBaseEnum.m
===================================================================
--- /issm/trunk/src/m/enum/QmuBaseEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/QmuBaseEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=QmuBaseEnum()
+%QMUBASEENUM - Enum of QmuBase
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=QmuBaseEnum()
+
+macro=StringToEnum('QmuBase');
Index: sm/trunk/src/m/enum/QmuBedEnum.m
===================================================================
--- /issm/trunk/src/m/enum/QmuBedEnum.m	(revision 17805)
+++ 	(revision )
@@ -1,11 +1,0 @@
-function macro=QmuBedEnum()
-%QMUBEDENUM - Enum of QmuBed
-%
-%   WARNING: DO NOT MODIFY THIS FILE
-%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
-%            Please read src/c/shared/Enum/README for more information
-%
-%   Usage:
-%      macro=QmuBedEnum()
-
-macro=StringToEnum('QmuBed');
Index: /issm/trunk/src/m/enum/SMBEnum.m
===================================================================
--- /issm/trunk/src/m/enum/SMBEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/SMBEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=SMBEnum()
+%SMBENUM - Enum of SMB
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=SMBEnum()
+
+macro=StringToEnum('SMB');
Index: /issm/trunk/src/m/enum/SMBgradientsEnum.m
===================================================================
--- /issm/trunk/src/m/enum/SMBgradientsEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/SMBgradientsEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=SMBgradientsEnum()
+%SMBGRADIENTSENUM - Enum of SMBgradients
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=SMBgradientsEnum()
+
+macro=StringToEnum('SMBgradients');
Index: /issm/trunk/src/m/enum/SMBhenningEnum.m
===================================================================
--- /issm/trunk/src/m/enum/SMBhenningEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/SMBhenningEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=SMBhenningEnum()
+%SMBHENNINGENUM - Enum of SMBhenning
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=SMBhenningEnum()
+
+macro=StringToEnum('SMBhenning');
Index: /issm/trunk/src/m/enum/SMBpddEnum.m
===================================================================
--- /issm/trunk/src/m/enum/SMBpddEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/SMBpddEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=SMBpddEnum()
+%SMBPDDENUM - Enum of SMBpdd
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=SMBpddEnum()
+
+macro=StringToEnum('SMBpdd');
Index: /issm/trunk/src/m/enum/SettingsResultsOnNodesEnum.m
===================================================================
--- /issm/trunk/src/m/enum/SettingsResultsOnNodesEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/SettingsResultsOnNodesEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=SettingsResultsOnNodesEnum()
+%SETTINGSRESULTSONNODESENUM - Enum of SettingsResultsOnNodes
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=SettingsResultsOnNodesEnum()
+
+macro=StringToEnum('SettingsResultsOnNodes');
Index: /issm/trunk/src/m/enum/StrainRateEnum.m
===================================================================
--- /issm/trunk/src/m/enum/StrainRateEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/StrainRateEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=StrainRateEnum()
+%STRAINRATEENUM - Enum of StrainRate
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=StrainRateEnum()
+
+macro=StringToEnum('StrainRate');
Index: /issm/trunk/src/m/enum/StrainRatexxEnum.m
===================================================================
--- /issm/trunk/src/m/enum/StrainRatexxEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/StrainRatexxEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=StrainRatexxEnum()
+%STRAINRATEXXENUM - Enum of StrainRatexx
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=StrainRatexxEnum()
+
+macro=StringToEnum('StrainRatexx');
Index: /issm/trunk/src/m/enum/StrainRatexyEnum.m
===================================================================
--- /issm/trunk/src/m/enum/StrainRatexyEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/StrainRatexyEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=StrainRatexyEnum()
+%STRAINRATEXYENUM - Enum of StrainRatexy
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=StrainRatexyEnum()
+
+macro=StringToEnum('StrainRatexy');
Index: /issm/trunk/src/m/enum/StrainRatexzEnum.m
===================================================================
--- /issm/trunk/src/m/enum/StrainRatexzEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/StrainRatexzEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=StrainRatexzEnum()
+%STRAINRATEXZENUM - Enum of StrainRatexz
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=StrainRatexzEnum()
+
+macro=StringToEnum('StrainRatexz');
Index: /issm/trunk/src/m/enum/StrainRateyyEnum.m
===================================================================
--- /issm/trunk/src/m/enum/StrainRateyyEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/StrainRateyyEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=StrainRateyyEnum()
+%STRAINRATEYYENUM - Enum of StrainRateyy
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=StrainRateyyEnum()
+
+macro=StringToEnum('StrainRateyy');
Index: /issm/trunk/src/m/enum/StrainRateyzEnum.m
===================================================================
--- /issm/trunk/src/m/enum/StrainRateyzEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/StrainRateyzEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=StrainRateyzEnum()
+%STRAINRATEYZENUM - Enum of StrainRateyz
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=StrainRateyzEnum()
+
+macro=StringToEnum('StrainRateyz');
Index: /issm/trunk/src/m/enum/StrainRatezzEnum.m
===================================================================
--- /issm/trunk/src/m/enum/StrainRatezzEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/StrainRatezzEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=StrainRatezzEnum()
+%STRAINRATEZZENUM - Enum of StrainRatezz
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=StrainRatezzEnum()
+
+macro=StringToEnum('StrainRatezz');
Index: /issm/trunk/src/m/enum/SurfaceNormalVelocityEnum.m
===================================================================
--- /issm/trunk/src/m/enum/SurfaceNormalVelocityEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/SurfaceNormalVelocityEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=SurfaceNormalVelocityEnum()
+%SURFACENORMALVELOCITYENUM - Enum of SurfaceNormalVelocity
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=SurfaceNormalVelocityEnum()
+
+macro=StringToEnum('SurfaceNormalVelocity');
Index: /issm/trunk/src/m/enum/SurfaceObservationEnum.m
===================================================================
--- /issm/trunk/src/m/enum/SurfaceObservationEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/SurfaceObservationEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=SurfaceObservationEnum()
+%SURFACEOBSERVATIONENUM - Enum of SurfaceObservation
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=SurfaceObservationEnum()
+
+macro=StringToEnum('SurfaceObservation');
Index: /issm/trunk/src/m/enum/SurfaceforcingsEnum.m
===================================================================
--- /issm/trunk/src/m/enum/SurfaceforcingsEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/SurfaceforcingsEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=SurfaceforcingsEnum()
+%SURFACEFORCINGSENUM - Enum of Surfaceforcings
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=SurfaceforcingsEnum()
+
+macro=StringToEnum('Surfaceforcings');
Index: /issm/trunk/src/m/enum/TetraEnum.m
===================================================================
--- /issm/trunk/src/m/enum/TetraEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/TetraEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=TetraEnum()
+%TETRAENUM - Enum of Tetra
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=TetraEnum()
+
+macro=StringToEnum('Tetra');
Index: /issm/trunk/src/m/enum/TetraInputEnum.m
===================================================================
--- /issm/trunk/src/m/enum/TetraInputEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/TetraInputEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=TetraInputEnum()
+%TETRAINPUTENUM - Enum of TetraInput
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=TetraInputEnum()
+
+macro=StringToEnum('TetraInput');
Index: sm/trunk/src/m/enum/TransientIsdamageEnum.m
===================================================================
--- /issm/trunk/src/m/enum/TransientIsdamageEnum.m	(revision 17805)
+++ 	(revision )
@@ -1,11 +1,0 @@
-function macro=TransientIsdamageEnum()
-%TRANSIENTISDAMAGEENUM - Enum of TransientIsdamage
-%
-%   WARNING: DO NOT MODIFY THIS FILE
-%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
-%            Please read src/c/shared/Enum/README for more information
-%
-%   Usage:
-%      macro=TransientIsdamageEnum()
-
-macro=StringToEnum('TransientIsdamage');
Index: /issm/trunk/src/m/enum/TransientIsdamageevolutionEnum.m
===================================================================
--- /issm/trunk/src/m/enum/TransientIsdamageevolutionEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/TransientIsdamageevolutionEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=TransientIsdamageevolutionEnum()
+%TRANSIENTISDAMAGEEVOLUTIONENUM - Enum of TransientIsdamageevolution
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=TransientIsdamageevolutionEnum()
+
+macro=StringToEnum('TransientIsdamageevolution');
Index: /issm/trunk/src/m/enum/TransientIshydrologyEnum.m
===================================================================
--- /issm/trunk/src/m/enum/TransientIshydrologyEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/TransientIshydrologyEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=TransientIshydrologyEnum()
+%TRANSIENTISHYDROLOGYENUM - Enum of TransientIshydrology
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=TransientIshydrologyEnum()
+
+macro=StringToEnum('TransientIshydrology');
Index: /issm/trunk/src/m/enum/TransientIslevelsetEnum.m
===================================================================
--- /issm/trunk/src/m/enum/TransientIslevelsetEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/TransientIslevelsetEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=TransientIslevelsetEnum()
+%TRANSIENTISLEVELSETENUM - Enum of TransientIslevelset
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=TransientIslevelsetEnum()
+
+macro=StringToEnum('TransientIslevelset');
Index: sm/trunk/src/m/enum/WaterTransferEnum.m
===================================================================
--- /issm/trunk/src/m/enum/WaterTransferEnum.m	(revision 17805)
+++ 	(revision )
@@ -1,11 +1,0 @@
-function macro=WaterTransferEnum()
-%WATERTRANSFERENUM - Enum of WaterTransfer
-%
-%   WARNING: DO NOT MODIFY THIS FILE
-%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
-%            Please read src/c/shared/Enum/README for more information
-%
-%   Usage:
-%      macro=WaterTransferEnum()
-
-macro=StringToEnum('WaterTransfer');
Index: /issm/trunk/src/m/enum/WeightsSurfaceObservationEnum.m
===================================================================
--- /issm/trunk/src/m/enum/WeightsSurfaceObservationEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/WeightsSurfaceObservationEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=WeightsSurfaceObservationEnum()
+%WEIGHTSSURFACEOBSERVATIONENUM - Enum of WeightsSurfaceObservation
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=WeightsSurfaceObservationEnum()
+
+macro=StringToEnum('WeightsSurfaceObservation');
Index: /issm/trunk/src/m/enum/XTaylorHoodEnum.m
===================================================================
--- /issm/trunk/src/m/enum/XTaylorHoodEnum.m	(revision 17806)
+++ /issm/trunk/src/m/enum/XTaylorHoodEnum.m	(revision 17806)
@@ -0,0 +1,11 @@
+function macro=XTaylorHoodEnum()
+%XTAYLORHOODENUM - Enum of XTaylorHood
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=XTaylorHoodEnum()
+
+macro=StringToEnum('XTaylorHood');
Index: /issm/trunk/src/m/exp/contourlevelzero.m
===================================================================
--- /issm/trunk/src/m/exp/contourlevelzero.m	(revision 17805)
+++ /issm/trunk/src/m/exp/contourlevelzero.m	(revision 17806)
@@ -10,5 +10,5 @@
 
 %process data 
-if md.mesh.dimension==3,
+if dimension(md.mesh)==3,
 	error('contourlevelzero error message: routine not supported for 3d meshes, project on a layer');
 end
Index: /issm/trunk/src/m/exp/expcoarsen.py
===================================================================
--- /issm/trunk/src/m/exp/expcoarsen.py	(revision 17805)
+++ /issm/trunk/src/m/exp/expcoarsen.py	(revision 17806)
@@ -2,5 +2,4 @@
 import numpy as npy
 from collections import OrderedDict
-from MatlabFuncs import *
 from expread import expread
 from expwrite import expwrite
Index: /issm/trunk/src/m/exp/expdisp.m
===================================================================
--- /issm/trunk/src/m/exp/expdisp.m	(revision 17805)
+++ /issm/trunk/src/m/exp/expdisp.m	(revision 17806)
@@ -44,9 +44,14 @@
 
 figure(figurenumber),hold on
-for i=1:length(domain),
-	if (isnumeric(linestyle))
-		plot(domain(i).x*unitmultiplier,domain(i).y*unitmultiplier,'Color',linestyle,'linewidth',linewidth);
+for i=1:length(domain),		
+	if domain(i).nods==1
+		plot(domain(i).x*unitmultiplier,domain(i).y*unitmultiplier,'o','MarkerEdgeColor','k','MarkerFaceColor','r','MarkerSize',10);
 	else
-		plot(domain(i).x*unitmultiplier,domain(i).y*unitmultiplier,linestyle,'linewidth',linewidth);
-	end
+		if (isnumeric(linestyle))
+			plot(domain(i).x*unitmultiplier,domain(i).y*unitmultiplier,'Color',linestyle,'linewidth',linewidth);
+		else
+			plot(domain(i).x*unitmultiplier,domain(i).y*unitmultiplier,linestyle,'linewidth',linewidth);
+	  end
+  end
 end
+
Index: /issm/trunk/src/m/exp/expread.py
===================================================================
--- /issm/trunk/src/m/exp/expread.py	(revision 17805)
+++ /issm/trunk/src/m/exp/expread.py	(revision 17806)
@@ -2,5 +2,5 @@
 import numpy
 from collections import OrderedDict
-from MatlabFuncs import *
+import MatlabFuncs as m
 
 def expread(filename):
@@ -8,5 +8,5 @@
 	EXPREAD - read a file exp and build a Structure
 
-	   This routine reads a file .exp and build a Structure containing the 
+	   This routine reads a file .exp and builds a list of dicts containing the 
 	   fields x and y corresponding to the coordinates, one for the filename of
 	   the exp file, for the density, for the nodes, and a field closed to 
@@ -48,5 +48,5 @@
 			break
 		A=A.split(None,1)
-		if not (len(A) == 2 and strcmp(A[0],'##') and strncmp(A[1],'Name:',5)):
+		if not (len(A) == 2 and m.strcmp(A[0],'##') and m.strncmp(A[1],'Name:',5)):
 			break
 		if len(A[1])>5: 
@@ -57,21 +57,21 @@
 		#Get Icon
 		A=fid.readline().split(None,1)
-		if not (len(A) == 2 and strcmp(A[0],'##') and strncmp(A[1],'Icon:',5)):
+		if not (len(A) == 2 and m.strcmp(A[0],'##') and m.strncmp(A[1],'Icon:',5)):
 			break
 
 		#Get Info
 		A=fid.readline().split()
-		if not (len(A) == 4 and strcmp(A[0],'#') and strcmp(A[1],'Points')):
+		if not (len(A) == 4 and m.strcmp(A[0],'#') and m.strcmp(A[1],'Points')):
 			break
 
 		#Get number of nodes and density
 		A=fid.readline().split()
-		contour['nods']   =float(A[0])
+		contour['nods']=int(A[0])
 		contour['density']=float(A[1])
 
 		#Get Info
 		A=fid.readline().split()
-		if not (len(A) == 5 and strcmp(A[0],'#') and strcmp(A[1],'X') and strcmp(A[2],'pos') \
-		                                         and strcmp(A[3],'Y') and strcmp(A[4],'pos')):
+		if not (len(A) == 5 and m.strcmp(A[0],'#') and m.strcmp(A[1],'X') and m.strcmp(A[2],'pos') \
+		                                         and m.strcmp(A[3],'Y') and m.strcmp(A[4],'pos')):
 			break
 
Index: /issm/trunk/src/m/extrusion/DepthAverage.m
===================================================================
--- /issm/trunk/src/m/extrusion/DepthAverage.m	(revision 17805)
+++ /issm/trunk/src/m/extrusion/DepthAverage.m	(revision 17806)
@@ -1,4 +1,4 @@
 function  vector_average=DepthAverage(md,vector)
-%DEPTHAVERAGE - computes depth average of 3d vector, and return value on 2d mesh. 
+%DEPTHAVERAGE - computes depth average of 3d vector using the trapezoidal rule, and returns the value on 2d mesh. 
 %
 %   Usage:
@@ -9,5 +9,5 @@
 
 %check that the model given in input is 3d
-if ~md.mesh.dimension==3;
+if ~strcmp(md.mesh.elementtype(),'3D');
 	error('DepthAverage error message: the model given in input must be 3d')
 end
Index: /issm/trunk/src/m/extrusion/DepthAverage.py
===================================================================
--- /issm/trunk/src/m/extrusion/DepthAverage.py	(revision 17806)
+++ /issm/trunk/src/m/extrusion/DepthAverage.py	(revision 17806)
@@ -0,0 +1,50 @@
+import numpy as npy
+from project2d import project2d
+
+def DepthAverage(md,vector):
+	'''
+	computes depth average of 3d vector using the trapezoidal rule, and returns
+	the value on the 2d mesh. 
+	
+	Usage:
+		vector_average=DepthAverage(md,vector)
+	
+	Example:
+		vel_bar=DepthAverage(md,md.initialization.vel)
+	'''
+
+	#check that the model given in input is 3d
+	if md.mesh.domaintype().lower() != '3d':
+		raise TypeError('DepthAverage error message: the model given in input must be 3d')
+
+	# coerce to array in case float is passed
+	if type(vector)!=npy.ndarray:
+		print 'coercing array'
+		vector=npy.array(value)
+
+	vec2d=False
+	if vector.ndim==2:
+		vec2d=True
+		vector=vector.reshape(-1,)
+
+	#nods data
+	if vector.shape[0]==md.mesh.numberofvertices:
+		vector_average=npy.zeros(md.mesh.numberofvertices2d)
+		for i in xrange(1,md.mesh.numberoflayers):
+			vector_average=vector_average+(project2d(md,vector,i)+project2d(md,vector,i+1))/2.*(project2d(md,md.mesh.z,i+1)-project2d(md,md.mesh.z,i))
+		vector_average=vector_average/project2d(md,md.geometry.thickness,1)
+	
+	#element data
+	elif vector.shape[0]==md.mesh.numberofelements:
+		vector_average=npy.zeros(md.mesh.numberofelements2d)
+		for i in xrange(1,md.mesh.numberoflayers):
+			vector_average=vector_average+project2d(md,vector,i)*(project2d(md,md.mesh.z,i+1)-project2d(md,md.mesh.z,i))
+		vector_average=vector_average/project2d(md,md.geometry.thickness,1)
+	
+	else:
+		raise ValueError('vector size not supported yet');
+
+	if vec2d:
+		vector_average=vector_average.reshape(-1,1)
+
+	return vector_average
Index: /issm/trunk/src/m/extrusion/project2d.m
===================================================================
--- /issm/trunk/src/m/extrusion/project2d.m	(revision 17805)
+++ /issm/trunk/src/m/extrusion/project2d.m	(revision 17806)
@@ -20,5 +20,5 @@
 end
 
-if (md3d.mesh.dimension~=3),
+if ~strcmp(md3d.mesh.domaintype,'3D');
 	error('wrong model type ... should be ''3d''');
 end
Index: /issm/trunk/src/m/extrusion/project2d.py
===================================================================
--- /issm/trunk/src/m/extrusion/project2d.py	(revision 17806)
+++ /issm/trunk/src/m/extrusion/project2d.py	(revision 17806)
@@ -0,0 +1,53 @@
+import numpy as npy
+
+def project2d(md3d,value,layer):
+	'''
+	returns the value of a field for a given layer of the mesh
+	
+	project 'value' vector taken at layer 'layer' from extruded 2d-3d
+	mesh onto 2d mesh used to do the extrusion. This routine is used to
+	compare values between a 2d-3d mesh at a certain layer, and the
+	equivalent value (if it exists), on the original 2d mesh.	
+
+	Note: for consistency with usage in ISSM, layers are indexed starting
+	from one.  This routine accounts for the fact that python indexes from
+	zero.  In other words, when using this function consider the bottom
+	layer as layer=1.  
+
+   Usage:
+      projection_value=project2d(md3d,value,layer)
+
+   Example:
+      vel2=project2d(md3d,md3d.vel,2)
+	'''
+
+	if md3d.mesh.domaintype().lower() != '3d':
+		raise StandardError("model passed to project2d function should be 3D")
+
+	if layer<1 or layer>md3d.mesh.numberoflayers:
+		raise ValueError("layer must be between 0 and %i" % md3d.mesh.numberoflayers)
+	
+	# coerce to array in case float is passed
+	if type(value)!=npy.ndarray:
+		print 'coercing array'
+		value=npy.array(value)
+
+	vec2d=False
+	if value.ndim==2: 
+		value=value.reshape(-1,)
+		vec2d=True
+	
+	if value.size==1:
+		projection_value=value[(layer-1)*md3d.mesh.numberofelements2d:layer*md3d.mesh.numberofelements2d]
+	elif value.shape[0]==md3d.mesh.numberofvertices:
+		#print 'indices: ', (layer-1)*md3d.mesh.numberofvertices2d, layer*md3d.mesh.numberofvertices2d
+		projection_value=value[(layer-1)*md3d.mesh.numberofvertices2d:layer*md3d.mesh.numberofvertices2d]
+	elif value.shape[0]==md3d.mesh.numberofvertices+1:
+		projection_value=[value[(layer-1)*md3d.mesh.numberofvertices2d:layer*md3d.mesh.numberofvertices2d], value[-1]]
+	else:
+		projection_value=value[(layer-1)*md3d.mesh.numberofelements2d:layer*md3d.mesh.numberofelements2d]
+
+	if vec2d:
+		projection_value=projection_value.reshape(-1,1)
+
+	return projection_value
Index: /issm/trunk/src/m/extrusion/project3d.m
===================================================================
--- /issm/trunk/src/m/extrusion/project3d.m	(revision 17805)
+++ /issm/trunk/src/m/extrusion/project3d.m	(revision 17806)
@@ -23,5 +23,5 @@
 	error('bad usage');
 end
-if md.mesh.dimension~=3
+if ~strcmp(elementtype(md.mesh),'Penta')
 	error('input model is not 3d');
 end
Index: /issm/trunk/src/m/extrusion/project3d.py
===================================================================
--- /issm/trunk/src/m/extrusion/project3d.py	(revision 17805)
+++ /issm/trunk/src/m/extrusion/project3d.py	(revision 17806)
@@ -1,5 +1,4 @@
 import numpy
-from pairoptions import *
-from MatlabFuncs import *
+from pairoptions import pairoptions
 
 def project3d(md,*args):
@@ -16,10 +15,10 @@
 	      'layer' a layer number where vector should keep its values. If not specified, all layers adopt the 
 	             value of the 2d vector.
-	      'padding': default to 0 (value adopted by other 3d layers not being projected0
+	      'padding': default to 0 (value adopted by other 3d layers not being projected
 
-	   Egs:
-	      extruded_vector=project3d(md,'vector',vector2d,'type','node','layer',1,'padding',NaN);
-	      extruded_vector=project3d(md,'vector',vector2d,'type','element','padding',0);
-	      extruded_vector=project3d(md,'vector',vector2d,'type','node');
+	   Examples:
+	      extruded_vector=project3d(md,'vector',vector2d,'type','node','layer',1,'padding',NaN)
+	      extruded_vector=project3d(md,'vector',vector2d,'type','element','padding',0)
+	      extruded_vector=project3d(md,'vector',vector2d,'type','node')
 	"""
 
@@ -27,5 +26,5 @@
 	if not md:
 		raise TypeError("bad usage")
-	if not md.mesh.dimension==3:
+	if md.mesh.domaintype().lower() != '3d':
 		raise TypeError("input model is not 3d")
 
@@ -33,5 +32,5 @@
 	options      = pairoptions(*args)
 	vector2d     = options.getfieldvalue('vector')       #mandatory
-	type         = options.getfieldvalue('type')         #mandatory
+	vectype      = options.getfieldvalue('type')         #mandatory
 	layer        = options.getfieldvalue('layer',0)      #optional (do all layers otherwise)
 	paddingvalue = options.getfieldvalue('padding',0)    #0 by default
@@ -40,15 +39,15 @@
 	if isinstance(vector2d,numpy.ndarray) and numpy.ndim(vector2d)==1:
 		vector1d=True
-		vector2d=vector2d.reshape(numpy.size(vector2d),1)
+		vector2d=vector2d.reshape(-1,1)
 
-	if   isinstance(vector2d,(bool,int,long,float)) or numpy.size(vector2d)==1:
+	if isinstance(vector2d,(bool,int,long,float)) or numpy.size(vector2d)==1:
 		projected_vector=vector2d
 
-	elif strcmpi(type,'node'):
+	elif vectype.lower()=='node':
 
 		#Initialize 3d vector
-		if   numpy.size(vector2d,axis=0)==md.mesh.numberofvertices2d:
+		if vector2d.shape[0]==md.mesh.numberofvertices2d:
 			projected_vector=(paddingvalue*numpy.ones((md.mesh.numberofvertices,  numpy.size(vector2d,axis=1)))).astype(vector2d.dtype)
-		elif numpy.size(vector2d,axis=0)==md.mesh.numberofvertices2d+1:
+		elif vector2d.shape[0]==md.mesh.numberofvertices2d+1:
 			projected_vector=(paddingvalue*numpy.ones((md.mesh.numberofvertices+1,numpy.size(vector2d,axis=1)))).astype(vector2d.dtype)
 			projected_vector[-1,:]=vector2d[-1,:]
@@ -64,10 +63,10 @@
 			projected_vector[((layer-1)*md.mesh.numberofvertices2d):(layer*md.mesh.numberofvertices2d),:]=vector2d
 
-	elif strcmpi(type,'element'):
+	elif vectype.lower()=='element':
 
 		#Initialize 3d vector
-		if   numpy.size(vector2d,axis=0)==md.mesh.numberofelements2d:
+		if vector2d.shape[0]==md.mesh.numberofelements2d:
 			projected_vector=(paddingvalue*numpy.ones((md.mesh.numberofelements,  numpy.size(vector2d,axis=1)))).astype(vector2d.dtype)
-		elif numpy.size(vector2d,axis=0)==md.mesh.numberofelements2d+1:
+		elif vector2d.shape[0]==md.mesh.numberofelements2d+1:
 			projected_vector=(paddingvalue*numpy.ones((md.mesh.numberofelements+1,numpy.size(vector2d,axis=1)))).astype(vector2d.dtype)
 			projected_vector[-1,:]=vector2d[-1,:]
@@ -87,6 +86,5 @@
 
 	if vector1d:
-		projected_vector=projected_vector.reshape((numpy.size(projected_vector)))
+		projected_vector=projected_vector.reshape(-1,)
 
 	return projected_vector
-
Index: /issm/trunk/src/m/geometry/FlagElements.py
===================================================================
--- /issm/trunk/src/m/geometry/FlagElements.py	(revision 17805)
+++ /issm/trunk/src/m/geometry/FlagElements.py	(revision 17806)
@@ -1,8 +1,8 @@
 import numpy
 import os
-#from basinzoom import *
-from ContourToMesh import *
-from MatlabFuncs import *
-from PythonFuncs import *
+#from basinzoom import basinzoon
+from ContourToMesh import ContourToMesh
+import MatlabFuncs as m
+import PythonFuncs as p
 
 def FlagElements(md,region):
@@ -26,10 +26,10 @@
 			flag=numpy.zeros(md.mesh.numberofelements,bool)
 			invert=0
-		elif strcmpi(region,'all'):
+		elif m.strcmpi(region,'all'):
 			flag=numpy.ones(md.mesh.numberofelements,bool)
 			invert=0
 		else:
 			#make sure that we actually don't want the elements outside the domain outline!
-			if strcmpi(region[0],'~'):
+			if m.strcmpi(region[0],'~'):
 				region=region[1:]
 				invert=1
@@ -39,9 +39,9 @@
 			#does the region domain outline exist or do we have to look for xlim,ylim in basinzoom?
 			if not os.path.exists(region):
-				if len(region)>3 and not strcmp(region[-4:],'.exp'):
+				if len(region)>3 and not m.strcmp(region[-4:],'.exp'):
 					raise IOError("Error: File 'region' not found!" % region)
 				raise RuntimeError("FlagElements.py calling basinzoom.py is not complete.")
 				xlim,ylim=basinzoom('basin',region)
-				flag_nodes=logical_and_n(md.mesh.x<xlim[1],md.mesh.x>xlim[0],md.mesh.y<ylim[1],md.mesh.y>ylim[0])
+				flag_nodes=p.logical_and_n(md.mesh.x<xlim[1],md.mesh.x>xlim[0],md.mesh.y<ylim[1],md.mesh.y>ylim[0])
 				flag=numpy.prod(flag_nodes[md.mesh.elements],axis=1).astype(bool)
 			else:
Index: /issm/trunk/src/m/geometry/ThicknessCorrection.m
===================================================================
--- /issm/trunk/src/m/geometry/ThicknessCorrection.m	(revision 17805)
+++ /issm/trunk/src/m/geometry/ThicknessCorrection.m	(revision 17806)
@@ -75,3 +75,3 @@
 md.geometry.thickness=thickness;
 md.geometry.hydrostatic_ratio=hydrostatic_ratio;
-md.geometry.bed=md.geometry.surface-md.geometry.thickness;
+md.geometry.base=md.geometry.surface-md.geometry.thickness;
Index: /issm/trunk/src/m/geometry/slope.m
===================================================================
--- /issm/trunk/src/m/geometry/slope.m	(revision 17805)
+++ /issm/trunk/src/m/geometry/slope.m	(revision 17806)
@@ -7,5 +7,5 @@
 
 %load some variables (it is much faster if the variab;es are loaded from md once for all) 
-if (md.mesh.dimension==2),
+if dimension(md.mesh)==2,
 	numberofelements=md.mesh.numberofelements;
 	numberofnodes=md.mesh.numberofvertices;
@@ -30,5 +30,5 @@
 s=sqrt(sx.^2+sy.^2);
 
-if md.mesh.dimension==3,
+if dimension(md.mesh)==3,
 	sx=project3d(md,'vector',sx,'type','element');
 	sy=project3d(md,'vector',sy,'type','element');
Index: /issm/trunk/src/m/geometry/slope.py
===================================================================
--- /issm/trunk/src/m/geometry/slope.py	(revision 17805)
+++ /issm/trunk/src/m/geometry/slope.py	(revision 17806)
@@ -12,5 +12,5 @@
 
 	#load some variables (it is much faster if the variables are loaded from md once for all) 
-	if md.mesh.dimension==2:
+	if md.mesh.dimension()==2:
 		numberofelements=md.mesh.numberofelements
 		numberofnodes=md.mesh.numberofvertices
@@ -39,5 +39,5 @@
 	s=npy.sqrt(sx**2+sy**2)
 
-	if md.mesh.dimension==3:
+	if md.mesh.dimension()==3:
 		sx=project3d(md,'vector',sx,'type','element')
 		sy=project3d(md,'vector',sy,'type','element')
Index: /issm/trunk/src/m/interp/PointValues.m
===================================================================
--- /issm/trunk/src/m/interp/PointValues.m	(revision 17806)
+++ /issm/trunk/src/m/interp/PointValues.m	(revision 17806)
@@ -0,0 +1,14 @@
+function [data_interp]=PointValues(md,data,xpoint,ypoint)
+%POINTVALUES - compute the value of a field on a single point
+%
+%   This routine gets the value of a given field of the model on points
+%
+%   Usage:
+%      [z,data]=PointValues(md,data,X,Y,Z)
+
+%Get bed and surface for each 2d point, offset to make sure that it is inside the glacier system
+%offset=10^-3;
+%bed=InterpFromMeshToMesh2d(md.mesh.elements2d,md.mesh.x2d,md.mesh.y2d,project2d(md,md.geometry.bed,1),xpoint,ypoint)+offset;
+%surface=InterpFromMeshToMesh2d(md.mesh.elements2d,md.mesh.x2d,md.mesh.y2d,project2d(md,md.geometry.surface,1),xpoint,ypoint)-offset;
+
+data_interp=InterpFromMeshToMesh2d(md.mesh.elements,md.mesh.x,md.mesh.y,data,xpoint,ypoint);
Index: /issm/trunk/src/m/interp/ProfileValues.m
===================================================================
--- /issm/trunk/src/m/interp/ProfileValues.m	(revision 17805)
+++ /issm/trunk/src/m/interp/ProfileValues.m	(revision 17806)
@@ -11,5 +11,5 @@
 %Get bed and surface for each 2d point, offset to make sure that it is inside the glacier system
 offset=10^-3;
-bed=InterpFromMeshToMesh2d(md.mesh.elements2d,md.mesh.x2d,md.mesh.y2d,project2d(md,md.geometry.bed,1),xprof,yprof)+offset;
+bed=InterpFromMeshToMesh2d(md.mesh.elements2d,md.mesh.x2d,md.mesh.y2d,project2d(md,md.geometry.base,1),xprof,yprof)+offset;
 surface=InterpFromMeshToMesh2d(md.mesh.elements2d,md.mesh.x2d,md.mesh.y2d,project2d(md,md.geometry.surface,1),xprof,yprof)-offset;
 
Index: /issm/trunk/src/m/interp/SectionValues.m
===================================================================
--- /issm/trunk/src/m/interp/SectionValues.m	(revision 17805)
+++ /issm/trunk/src/m/interp/SectionValues.m	(revision 17806)
@@ -29,5 +29,5 @@
 	error('SectionValues error message: wrong resolution type. Resolution must be an array [horizontal_resolution vertical_resolution]')
 end
-if md.mesh.dimension==3
+if dimension(md.mesh)==3
 	if (length(resolution)==2 & isnumeric(resolution(2)))
 		res_v=resolution(2);
@@ -78,5 +78,5 @@
 
 %New mesh and Data interpolation
-if (md.mesh.dimension==2)
+if (dimension(md.mesh)==2)
 
 	%Interpolation of data on specified points
@@ -92,7 +92,7 @@
 	%vertically extrude mesh
 
-	%Get bed and surface for each 2d point, offset to make sure that it is inside the glacier system
+	%Get base and surface for each 2d point, offset to make sure that it is inside the glacier system
 	offset=10^-3;
-	bed=InterpFromMeshToMesh2d(md.mesh.elements2d,md.mesh.x2d,md.mesh.y2d,project2d(md,md.geometry.bed,1),X,Y)+offset;
+	base=InterpFromMeshToMesh2d(md.mesh.elements2d,md.mesh.x2d,md.mesh.y2d,project2d(md,md.geometry.base,1),X,Y)+offset;
 	surface=InterpFromMeshToMesh2d(md.mesh.elements2d,md.mesh.x2d,md.mesh.y2d,project2d(md,md.geometry.surface,1),X,Y)-offset;
 
@@ -111,5 +111,5 @@
 		X3(i:layers:end)=X;
 		Y3(i:layers:end)=Y;
-		Z3(i:layers:end)=bed+(i-1)*(surface-bed)/(layers-1);
+		Z3(i:layers:end)=base+(i-1)*(surface-base)/(layers-1);
 		S3(i:layers:end)=S;
 
Index: /issm/trunk/src/m/interp/SectionValues.py
===================================================================
--- /issm/trunk/src/m/interp/SectionValues.py	(revision 17806)
+++ /issm/trunk/src/m/interp/SectionValues.py	(revision 17806)
@@ -0,0 +1,140 @@
+import os
+from expread import expread
+import numpy as npy
+from project2d import project2d
+#from InterpFromMesh2d import InterpFromMesh2d
+from InterpFromMeshToMesh2d import InterpFromMeshToMesh2d
+#from InterpFromMeshToMesh3d import InterpFromMeshToMesh3d
+
+def SectionValues(md,data,infile,resolution):
+	'''
+	compute the value of a field on a section
+	
+	This routine gets the value of a given field of the model on points
+	given in the file infile (Argus type file). Resolution must be a list
+	[horizontal_resolution, vertical_resolution]
+	
+	Usage:
+	[elements,x,y,z,s,data]=SectionValues(md,data,filename,resolution)
+	[elements,x,y,z,s,data]=SectionValues(md,data,profile_structure,resolution)
+	'''
+
+	if os.path.isfile(infile):
+		profile=expread(infile)[0]
+		nods=profile['nods']
+		x=profile['x']
+		y=profile['y']
+	else:
+		raise IOError('file %s not found' % infile)
+
+	#get the specified resolution
+	if len(resolution)!=2:
+		raise ValueError('SectionValues error message: Resolution must be a list [horizontal_resolution, vertical_resolution]')
+	else:
+		res_h=resolution[0]
+
+	if md.mesh.domaintype().lower() == '3d':
+		if isinstance(resolution[1],int) or isinstance(resolution[1],float):
+			res_v=resolution[1]
+		else:
+			raise ValueError('SectionValues error: resolution must be a length-2 list of integers or floats')
+
+	#initialization
+	X=npy.array([]) #X-coordinate
+	Y=npy.array([]) #Y-coordinate
+	S=npy.array([0.])  #curvilinear coordinate
+	
+	for i in xrange(nods-1):
+	
+		x_start=x[i]
+		x_end=x[i+1]
+		y_start=y[i]
+		y_end=y[i+1]
+		s_start=S[-1]
+	
+		length_segment=npy.sqrt((x_end-x_start)**2+(y_end-y_start)**2)
+		portion=npy.ceil(length_segment/res_h)
+	
+		x_segment=npy.zeros(portion)
+		y_segment=npy.zeros(portion)
+		s_segment=npy.zeros(portion)
+
+		for j in xrange(int(portion)):
+			x_segment[j]=x_start+(j-1)*(x_end-x_start)/portion
+			y_segment[j]=y_start+(j-1)*(y_end-y_start)/portion
+			s_segment[j]=s_start+j*length_segment/portion
+	
+		#plug into X and Y
+		X=npy.append(X,x_segment)
+		Y=npy.append(Y,y_segment)
+		S=npy.append(S,s_segment)
+
+	X=npy.append(X,x[nods-1])
+	Y=npy.append(Y,y[nods-1])
+	
+	#Number of nodes:
+	numberofnodes=X.shape[0]
+	
+	#Compute Z
+	Z=npy.zeros(numberofnodes)
+	
+	#New mesh and Data interpolation
+	if md.mesh.domaintype().lower() == '2d':
+	
+		#Interpolation of data on specified points
+		#data_interp=InterpFromMesh2d(md.mesh.elements,md.mesh.x,md.mesh.y,data,X,Y)[0]
+		data_interp=InterpFromMeshToMesh2d(md.mesh.elements,md.mesh.x,md.mesh.y,data,X,Y)[0]
+		#data_interp=griddata(md.mesh.x,md.mesh.y,data,X,Y)
+	
+		#Compute index
+		index=npy.array([range(1,numberofnodes),range(2,numberofnodes+1)]).T
+	
+	else:
+	
+		#vertically extrude mesh
+	
+		#Get base and surface for each 2d point, offset to make sure that it is inside the glacier system
+		offset=1.e-3
+		base=InterpFromMeshToMesh2d(md.mesh.elements2d,md.mesh.x2d,md.mesh.y2d,project2d(md,md.geometry.base,1),X,Y)[0]+offset
+		base=base.reshape(-1,)
+		surface=InterpFromMeshToMesh2d(md.mesh.elements2d,md.mesh.x2d,md.mesh.y2d,project2d(md,md.geometry.surface,1),X,Y)[0]-offset
+		surface=surface.reshape(-1,)
+	
+		#Some useful parameters
+		layers=int(npy.ceil(npy.mean(md.geometry.thickness)/res_v))
+		print 'layers=', layers
+		nodesperlayer=int(numberofnodes)
+		nodestot=int(nodesperlayer*layers)
+		elementsperlayer=int(nodesperlayer-1)
+		elementstot=int((nodesperlayer-1)*(layers-1))
+	
+		#initialization
+		X3=npy.zeros(nodesperlayer*layers) 
+		Y3=npy.zeros(nodesperlayer*layers) 
+		Z3=npy.zeros(nodesperlayer*layers) 
+		S3=npy.zeros(nodesperlayer*layers) 
+		index3=npy.zeros((elementstot,4))
+	
+		#Get new coordinates in 3d
+		for i in xrange(1,layers+1):
+			X3[i-1::layers]=X
+			Y3[i-1::layers]=Y
+			Z3[i-1::layers]=base+(i-1)*(surface-base)/(layers-1)
+			S3[i-1::layers]=S
+	
+			if i<layers-1:  #Build index3 with quads
+				ids=npy.vstack((npy.arange(i,nodestot-layers,layers),npy.arange(i+1,nodestot-layers,layers),npy.arange(i+layers+1,nodestot,layers),npy.arange(i+layers,nodestot,layers))).T
+				index3[(i-1)*elementsperlayer:i*elementsperlayer,:]=ids
+
+		#Interpolation of data on specified points
+		# TODO data_interp=InterpFromMeshToMesh3d(md.mesh.elements,md.mesh.x,md.mesh.y,md.mesh.z,data,X3,Y3,Z3,npy.nan)
+	
+		#build outputs
+		X=X3 
+		Y=Y3 
+		Z=Z3  
+		S=S3 
+
+		index=index3
+
+		return index,X,Y,Z,S,data_interp
Index: /issm/trunk/src/m/interp/averaging.m
===================================================================
--- /issm/trunk/src/m/interp/averaging.m	(revision 17805)
+++ /issm/trunk/src/m/interp/averaging.m	(revision 17806)
@@ -25,5 +25,5 @@
 	error('averaging error message: data not supported yet');
 end
-if md.mesh.dimension==3 & nargin==4,
+if dimension(md.mesh)==3 & nargin==4,
 	if varargin{1}<=0 | varargin{1}>md.mesh.numberoflayers,
 		error('layer should be between 1 and md.mesh.numberoflayers');
@@ -56,8 +56,8 @@
 %build some variables
 line=index(:);
-if md.mesh.dimension==3 & layer==0,
+if dimension(md.mesh)==3 & layer==0,
 	rep=6;
 	areas=GetAreas(index,md.mesh.x,md.mesh.y,md.mesh.z);
-elseif md.mesh.dimension==2,
+elseif dimension(md.mesh)==2,
 	rep=3;
 	areas=GetAreas(index,md.mesh.x,md.mesh.y);
Index: /issm/trunk/src/m/interp/averaging.py
===================================================================
--- /issm/trunk/src/m/interp/averaging.py	(revision 17805)
+++ /issm/trunk/src/m/interp/averaging.py	(revision 17806)
@@ -2,4 +2,5 @@
 from GetAreas import GetAreas
 from scipy.sparse import csc_matrix
+import MatlabFuncs as m
 
 def averaging(md,data,iterations,layer=0):
@@ -25,7 +26,7 @@
 	'''
 
-	if (len(data)!=md.mesh.numberofelements & len(data)!=md.mesh.numberofvertices):
+	if len(data)!=md.mesh.numberofelements and len(data)!=md.mesh.numberofvertices:
 		raise StandardError('averaging error message: data not supported yet')
-	if md.mesh.dimension==3 and layer!=0:
+	if md.mesh.dimension()==3 and layer!=0:
 		if layer<=0 or layer>md.mesh.numberoflayers:
 			raise ValueError('layer should be between 1 and md.mesh.numberoflayers')
@@ -50,10 +51,11 @@
 		numberofnodes=md.mesh.numberofvertices2d
 		numberofelements=md.mesh.numberofelements2d
+
 	
 	#build some variables
-	if md.mesh.dimension==3 and layer==0:
+	if md.mesh.dimension()==3 and layer==0:
 		rep=6
 		areas=GetAreas(index,md.mesh.x,md.mesh.y,md.mesh.z)
-	elif md.mesh.dimension==2:
+	elif md.mesh.dimension()==2:
 		rep=3
 		areas=GetAreas(index,md.mesh.x,md.mesh.y)
@@ -75,6 +77,8 @@
 		average_node=csc_matrix( (npy.tile(areas*data,(rep,1)).reshape(-1,),(line,npy.zeros(linesize,))), shape=(numberofnodes,1))
 		average_node=average_node/weights
+		average_node = csc_matrix(average_node)
 	else:
 		average_node=data
+
 	
 	#loop over iteration
Index: /issm/trunk/src/m/interp/holefiller.py
===================================================================
--- /issm/trunk/src/m/interp/holefiller.py	(revision 17806)
+++ /issm/trunk/src/m/interp/holefiller.py	(revision 17806)
@@ -0,0 +1,45 @@
+import numpy as npy
+from scipy.spatial import cKDTree
+
+def nearestneighbors(md,data,goodids,badids,knn):
+	'''
+	fill holes using nearest neigbors.  Arguments include:
+
+	md:		the model
+	data:		the data field to be filled (full field, including holes)
+	goodids:	id's into the vertices that have good data
+	badids:	id's into the vertices with missing/bad data
+	knn:		integer representing the k nearest neighbors to use for filling
+				holes.  The average data value over the k nearest neighbors is 
+				then used to fill the hole.
+
+	Usage:
+		filleddata=nearestneighbors(md,goodids,badids,knn)
+
+	Example:
+		filledthickness=nearestneighbors(md,goodids,badids,5)
+	'''
+
+	if type(knn) != int or knn<1:
+		raise TypeError('nearestneighbors error: knn should be an integer>1')
+
+	if len(data) != md.mesh.numberofvertices:
+		raise StandardError('nearestneighbors error: "data" should have length md.mesh.numberofvertices')
+
+	filled=data
+	
+	XYGood=npy.dstack([md.mesh.x[goodids],md.mesh.y[goodids]])[0]
+	XYBad=npy.dstack([md.mesh.x[badids],md.mesh.y[badids]])[0]
+	tree=cKDTree(XYGood)
+	nearest=tree.query(XYBad,k=knn)[1]
+	
+	if knn==1:
+		filled[badids]=filled[goodids][nearest] # can add k=N to return the N nearest neighbors
+	else:
+		for i in range(len(badids)):
+			neardat=[]
+			for j in range(knn):
+				neardat.append(filled[goodids][nearest[i][j]])
+				filled[badids[i]]=npy.mean(neardat)
+				
+	return filled
Index: /issm/trunk/src/m/interp/interp.py
===================================================================
--- /issm/trunk/src/m/interp/interp.py	(revision 17806)
+++ /issm/trunk/src/m/interp/interp.py	(revision 17806)
@@ -0,0 +1,237 @@
+# module for inperpolating/smoothing data
+import numpy as npy
+from scipy.interpolate import CloughTocher2DInterpolator, Rbf
+from scipy.spatial import cKDTree
+try:
+	import matplotlib.pyplot as plt
+except ImportError:
+	print 'could not import matplotlib, no plotting functions enabled.\
+			Set plotonly=False in function call'
+
+def MeshSplineToMesh2d(x,y,data,xi,yi,tol=1e-6,fill_nans=False,**kwargs):#{{{
+	'''
+	Piecewise cubic, C1 smooth, curvature-minimizing interpolant in 2D.
+	The interpolant is guaranteed to be continuously differentiable,
+	and the gradients are chosen such that the curvature of the interpolant
+	is approximately minimized.
+
+	Uses scipy.interpolate.CloughTocher2DInterpolator
+
+	x,y:			data point coordinates
+	data:			data to be interpolated (same length as x,y)
+	xi,yi:		coordintes to interpolate data onto
+	tol:			tolerance for gradient estimation (default 1e-6)
+	fill_nans:	fill nan's (holes) in data using the spline fit? 
+	**kwargs:	optional keywork arguments:
+					maxiter: maximum iterations in gradient estimation
+	
+	Returns interpolated data at given x,y coordinates.
+
+	Usage:
+		interpdata=CloughToucher2d(x,y,data)
+
+	Examples:
+		interpdata=CloughToucher2d(md.mesh.x,md.mesh.y,data)
+		interpdata=CloughToucher2d(md.mesh.x,md.mesh.y,data,tol=1e-3,maxiter=100)
+	'''
+
+	# unpack kwargs
+	maxiter=kwargs.pop('maxiter',None)
+	if 'maxiter' in kwargs: del kwargs['maxiter']
+	if maxiter:
+		assert type(maxiter)==int, 'error, maxiter should be an integer'
+	assert len(kwargs)==0, 'error, unexpected or misspelled kwargs'
+
+	# create sub-vectors that just cover the limits of xi and yi
+	# TODO x,y not necessarily a grid, so need a better definition of dx,dy (e.g. average element size)
+	dx=x[1]-x[0]
+	dy=y[1]-y[0]
+	xlim=[min(xi)-dx,max(xi)+dx]
+	ylim=[min(yi)-dy,max(yi)+dy]
+	xflag=npy.logical_and(x>xlim[0],x<xlim[1])
+	yflag=npy.logical_and(y>ylim[0],y<ylim[1])
+	bothind=npy.nonzero(npy.logical_and(xflag,yflag))
+	subdata=data[bothind]
+	subx=x[bothind]
+	suby=y[bothind]
+	points=npy.array([subx,suby]).T
+
+	# mask out any nan's in the data and corresponding coordinate points
+	mask=npy.isnan(subdata)
+	ind=npy.nonzero(mask)[0]
+	if len(ind) and fill_nans:
+		print "		WARNING: filling nans using spline fit through good data points, which may or may not be appropriate. Check results carefully."
+	subdata=npy.delete(subdata,ind)
+	points=npy.delete(points,ind,axis=0)
+
+	if maxiter:
+		spline=CloughTocher2DInterpolator(points,subdata,tol,maxiter=maxiter)
+	else:
+		spline=CloughTocher2DInterpolator(points,subdata,tol)
+
+	interpdata=spline(xi,yi)
+	
+	if not fill_nans:
+		# identify nan's in xi,yi using nearest neighbors
+		xyinterp=npy.dstack([xi,yi])[0]
+		xg,yg=npy.meshgrid(subx,suby)
+		xydata=npy.dstack([xg.ravel(),yg.ravel()])[0]
+		tree=cKDTree(xydata)
+		nearest=tree.query(xyinterp)[1]
+		pos=npy.nonzero(npy.isnan(subdata[nearest]))
+		interpdata[pos]=subdata[nearest][pos]
+
+	return interpdata
+#}}}
+def GridSplineToMesh2d(x,y,data,xi,yi,default_value=npy.nan,plotonly=False,fill_nans=False):#{{{
+	'''
+	python analog to InterpFromGridToMesh.  This routine uses
+	scipy.interpolate.CloughTocher2dInterpolator to create a bivariate spline
+	interpolation of the input data and then return values of the spline
+	on the x,y coordinates of the model mesh.  The interpolant is piece-wise
+	cubic, C1 smooth (continuously differentiable) and has approximately 
+	minimized curvature.  See "help(scipy.interpolate.CloughTocher2dInterpolator)"
+	for more information on the routine.
+
+	NOTE: this routine will not be appropriate if there are large holes (nan's) in 
+	the input data.  A non-spline interpolation scheme should be used in that case.
+
+	x,y:				vectors defining the coordinates of the input data
+	data:				2D array of input data
+	xi,yi:			x and y coordinates to be interpolated onto
+	default_value:	default value if points lie outside the convex hull of input
+						points (defaults to nan if not specified)
+	plotonly:		plot the data to be interpolated using imshow (useful for
+	fill_nans:		fill nan's (holes) in data using the spline fit? 
+
+	Usage:
+		interpdata=GridToMesh(x,y,data,xi,yi,default_value=npy.nan,plotonly=False,fill_nans=False)
+
+	Examples:
+		interpdata=GridToMesh(x_m,y_m,data,md.mesh.x,md.mesh.y,0)
+	'''
+
+	if npy.ndim(x)==2:
+		x=x.reshape(-1,)
+	if npy.ndim(y)==2:
+		y=y.reshape(-1,)
+	if len(x) != data.shape[1]+1 and len(x) != data.shape[1]:
+		raise ValueError('x should have same length as ncols(data) or ncols(data)+1')
+	if len(y) != data.shape[0]+1 and len(y) != data.shape[0]:
+		raise ValueError('y should have same length as nrows(data) or nrows(data)+1')
+	
+	# create sub-grid that just covers the limits of xi and yi
+	dx=x[1]-x[0]
+	dy=y[1]-y[0]
+	xlim=[min(xi)-dx,max(xi)+dx]
+	ylim=[min(yi)-dy,max(yi)+dy]
+
+	# TODO create grid differently depending on whether data is defined at x,y
+	# or at the center of a grid cell with corner coordinates defined by xi,yi
+	# create points array and flattened data array
+	if len(x)==data.shape[1] and len(y)==data.shape[0]:
+		print '		x,y taken to define the center of data grid cells'
+		xind=npy.nonzero(npy.logical_and(x>xlim[0],x<xlim[1]))[0]
+		yind=npy.nonzero(npy.logical_and(y>ylim[0],y<ylim[1]))[0]
+		xg,yg=npy.meshgrid(x[xind],y[yind])
+		subdata=data[yind[0]:yind[-1]+1,xind[0]:xind[-1]+1]
+	elif len(x)==data.shape[1]+1 and len(y)==data.shape[0]+1:
+		print '		x,y taken to define the corners of data grid cells'
+		xcenter=npy.fromiter(((x[i]+x[i+1])/2 for i in range(len(x)-1)),npy.float)
+		ycenter=npy.fromiter(((y[i]+y[i+1])/2 for i in range(len(y)-1)),npy.float)
+		xind=npy.nonzero(npy.logical_and(xcenter>xlim[0],xcenter<xlim[1]))[0]
+		yind=npy.nonzero(npy.logical_and(ycenter>ylim[0],ycenter<ylim[1]))[0]
+		xg,yg=npy.meshgrid(xcenter[xind],ycenter[yind])
+		subdata=data[yind[0]:yind[-1]+1,xind[0]:xind[-1]+1]
+	else:
+		raise ValueError('x and y have inconsistent sizes: both should have length ncols(data)/nrows(data) or ncols(data)+1/nrows(data)+1')
+
+	points=npy.array([xg.ravel(),yg.ravel()]).T
+	flatsubdata=subdata.ravel()
+
+	if plotonly:
+		plt.imshow(npy.flipud(subdata),origin='upper')
+		plt.show()
+		return
+
+	# mask out any nan's in the data and corresponding coordinate points
+	mask=npy.isnan(flatsubdata)
+	ind=npy.nonzero(mask)[0]
+	if len(ind) and fill_nans:
+		print "		WARNING: filling nans using spline fit through good data points, which may or may not be appropriate. Check results carefully."
+	goodsubdata=npy.delete(flatsubdata,ind)
+	goodpoints=npy.delete(points,ind,axis=0)
+
+	# create spline and index spline at mesh points
+	spline=CloughTocher2DInterpolator(goodpoints,goodsubdata)
+	interpdata=spline(xi,yi)
+
+	if not fill_nans:
+		# identify nan's in xi,yi using nearest neighbors
+		xyinterp=npy.dstack([xi,yi])[0]
+		xydata=npy.dstack([xg.ravel(),yg.ravel()])[0]
+		tree=cKDTree(xydata)
+		nearest=tree.query(xyinterp)[1]
+		pos=npy.nonzero(npy.isnan(flatsubdata[nearest]))
+		interpdata[pos]=flatsubdata[nearest][pos]
+
+	return interpdata
+#}}}
+def RadialInterp(x,y,data,**kwargs):#{{{
+	'''
+	Interpolation using a radial basis function in 2 or 3 dimensions.
+	Useful for smoothing input data after interpolation.
+
+	Uses scipy.interpolate.Rbf
+
+	x,y:			data point coordinates
+	data:			data to be interpolated (same length as x,y)
+
+		function: form of radial basis function for interpolation:
+			'multiquadric': sqrt((r/self.epsilon)**2 + 1) (default)
+			'inverse': 1.0/sqrt((r/self.epsilon)**2 + 1)
+			'gaussian': exp(-(r/self.epsilon)**2)
+			'linear': r
+			'cubic': r**3
+			'quintic': r**5
+			'thin_plate': r**2 * log(r)
+		epsilon: adjustable constant for scaling radial distance.  Defaults to 
+					approximate average distance between nodes.
+		smooth: float>0, adjusts the amount of smoothing applied.  Defaults to 0,
+					such that the function always passes through nodal points.
+		z:	coordinate array if interpolating in 3 dimensions
+
+	Usage:
+		interpdata=RadialInterp(x,y,data,**kwargs)
+
+	Examples:
+		interpdata=RadialInterp(md.mesh.x,md.mesh.y,data)
+		interpdata=RadialInterp(md.mesh.x,md.mesh.y,data,function='gaussian',epsilon=100,smooth=1)
+	'''
+
+	# unpack kwargs
+	function=kwargs.pop('function','multiquadric')
+	if 'function' in kwargs: del kwargs['function']
+	epsilon=kwargs.pop('epsilon',None)
+	if 'epsilon' in kwargs: del kwargs['epsilon']
+	smooth=kwargs.pop('smooth',0)
+	if 'smooth' in kwargs: del kwargs['smooth']
+	z=kwargs.pop('z',None)
+	if 'z' in kwargs: del kwargs['z']
+	assert len(kwargs)==0, 'error, unexpected or misspelled kwargs'
+
+	if z:
+		if epsilon:
+			rbfi=Rbf(x,y,z,data,function=function,smooth=smooth,epsilon=epsilon)
+		else:
+			rbfi=Rbf(x,y,z,data,function=function,smooth=smooth)
+		interpdata=rbfi(x,y,z)
+	else:
+		if epsilon:
+			rbfi=Rbf(x,y,data,function=function,smooth=smooth,epsilon=epsilon)
+		else:
+			rbfi=Rbf(x,y,data,function=function,smooth=smooth)
+		interpdata=rbfi(x,y)
+	
+	return interpdata
+#}}}
Index: sm/trunk/src/m/inversions/misfit.m
===================================================================
--- /issm/trunk/src/m/inversions/misfit.m	(revision 17805)
+++ 	(revision )
@@ -1,39 +1,0 @@
-function J=misfit(md)
-%MISFIT - compute misfit
-%
-%   Usage:
-%      J=misfit(md)
-%
-%   Example:
-%      J=misfit(md)
-%
-
-if md.mesh.dimension==2,
-	elements=md.mesh.elements;
-	x=md.mesh.x;
-	y=md.mesh.y;
-	%vx=md.initialization.vx;
-	%vy=md.initialization.vy;
-	vx=md.results.StressbalanceSolution.Vx;
-	vy=md.results.StressbalanceSolution.Vy;
-	vx_obs=md.inversion.vx_obs;
-	vy_obs=md.inversion.vy_obs;
-else
-	elements=md.mesh.elements2d;
-	x=md.mesh.x2d;
-	y=md.mesh.y2d;
-	vx=project2d(md,md.initialization.vx,md.mesh.numberoflayers);
-	vy=project2d(md,md.initialization.vy,md.mesh.numberoflayers);
-	vx_obs=project2d(md,md.inversion.vx_obs,md.mesh.numberoflayers);
-	vy_obs=project2d(md,md.inversion.vy_obs,md.mesh.numberoflayers);
-end
-
-%compute areas;
-areas=GetAreas(elements,x,y);
-
-%compute delta v on elements
-deltav=1/2*(   (vx-vx_obs).^2+(vy-vy_obs).^2)/md.constants.yts^2;
-deltav_elem=deltav(elements)*[1;1;1]/3;
-
-%compute misfit
-J=sum(deltav_elem.*areas);
Index: /issm/trunk/src/m/inversions/velocitymisfit.m
===================================================================
--- /issm/trunk/src/m/inversions/velocitymisfit.m	(revision 17806)
+++ /issm/trunk/src/m/inversions/velocitymisfit.m	(revision 17806)
@@ -0,0 +1,39 @@
+function J=misfit(md)
+%MISFIT - compute misfit
+%
+%   Usage:
+%      J=misfit(md)
+%
+%   Example:
+%      J=misfit(md)
+%
+
+if dimension(md.mesh)==2,
+	elements=md.mesh.elements;
+	x=md.mesh.x;
+	y=md.mesh.y;
+	%vx=md.initialization.vx;
+	%vy=md.initialization.vy;
+	vx=md.results.StressbalanceSolution.Vx;
+	vy=md.results.StressbalanceSolution.Vy;
+	vx_obs=md.inversion.vx_obs;
+	vy_obs=md.inversion.vy_obs;
+else
+	elements=md.mesh.elements2d;
+	x=md.mesh.x2d;
+	y=md.mesh.y2d;
+	vx=project2d(md,md.initialization.vx,md.mesh.numberoflayers);
+	vy=project2d(md,md.initialization.vy,md.mesh.numberoflayers);
+	vx_obs=project2d(md,md.inversion.vx_obs,md.mesh.numberoflayers);
+	vy_obs=project2d(md,md.inversion.vy_obs,md.mesh.numberoflayers);
+end
+
+%compute areas;
+areas=GetAreas(elements,x,y);
+
+%compute delta v on elements
+deltav=1/2*(   (vx-vx_obs).^2+(vy-vy_obs).^2)/md.constants.yts^2;
+deltav_elem=deltav(elements)*[1;1;1]/3;
+
+%compute misfit
+J=sum(deltav_elem.*areas);
Index: /issm/trunk/src/m/io/loadmodel.py
===================================================================
--- /issm/trunk/src/m/io/loadmodel.py	(revision 17805)
+++ /issm/trunk/src/m/io/loadmodel.py	(revision 17806)
@@ -1,4 +1,3 @@
-import os.path
-from loadvars import *
+from loadvars import loadvars
 from whichdb import whichdb
 
Index: /issm/trunk/src/m/materials/TMeltingPoint.m
===================================================================
--- /issm/trunk/src/m/materials/TMeltingPoint.m	(revision 17806)
+++ /issm/trunk/src/m/materials/TMeltingPoint.m	(revision 17806)
@@ -0,0 +1,15 @@
+function Tm=TMeltingPoint(reftemp, pressure)
+%TMELTINGPOINT- calculate pressure melting point of ice
+%
+%   reftemp is the melting temperature at atmospheric pressure (initialized in md.materials.meltingpoint)   
+%
+%   pressure is in Pa   
+%
+%   Usage:
+%   Tm=TMeltingPoint(md.materials.meltingpoint,pressure)
+
+%variables
+beta=7.9e-8; % K Pa^-1
+
+Tm=reftemp-beta*pressure;
+
Index: /issm/trunk/src/m/materials/TMeltingPoint.py
===================================================================
--- /issm/trunk/src/m/materials/TMeltingPoint.py	(revision 17806)
+++ /issm/trunk/src/m/materials/TMeltingPoint.py	(revision 17806)
@@ -0,0 +1,21 @@
+import numpy as npy
+
+def TMeltingPoint(reftemp,pressure):
+	'''
+	Calculate the pressure melting point of ice at a given pressure
+
+	reftemp is the melting temperature in K at atmospheric pressure (initialized in md.materials.meltingpoint)
+
+	pressure is in Pa
+
+	Usage:
+		Tm=TMeltingPoint(md.materials.meltingpoint,pressure)
+	'''
+
+	#variables
+	beta=7.9e-8
+
+	#ensure ref is same dimension as pressure
+	ref=reftemp*npy.ones_like(pressure)
+
+	return reftemp-beta*pressure
Index: /issm/trunk/src/m/materials/arrhenius.m
===================================================================
--- /issm/trunk/src/m/materials/arrhenius.m	(revision 17805)
+++ /issm/trunk/src/m/materials/arrhenius.m	(revision 17806)
@@ -31,8 +31,12 @@
 end
 
-wf_max=.1;
-if(waterfraction>wf_max)
+wf_max=1.;
+if(any(waterfraction>wf_max))
     error(['waterfraction exceeds permitted maximum of ' num2str(wf_max) '.']);
 end
+
+%limit waterfraction to 1%
+pos1p=find(waterfraction>0.01);
+waterfraction(pos1p)=0.01;
 
 pos=find((temperature<TMeltingPoint(pressure)) & (waterfraction>0)); % cold, wet ice
@@ -40,12 +44,4 @@
     error('cold ice with positive waterfraction detected.');
 end
-
-    function Tm=TMeltingPoint(pressure)
-        Tm=GetThom(T0,pressure);
-    end
-    
-    function Th=GetThom(T,pressure)
-        Th=T-beta*pressure;
-    end
 
 %   values for Activation energy Q and pre-exponential constants from
@@ -71,9 +67,12 @@
         Qa=GetQa(T); 
         A0=GetA0(T);
+        if(w>0.01)
+           w=0.01;
+        end
         A=A0.*exp(-Qa./(R*T)).*(1+181.25*w);        
     end
     
     function B=GetRigidity(T,w,pressure)
-        Thom=GetThom(T, pressure);
+        Thom=TMeltingPoint(T, pressure);
         A=GetA(Thom, w);
         B=1./(A.^(1/n));
Index: /issm/trunk/src/m/materials/cuffey.m
===================================================================
--- /issm/trunk/src/m/materials/cuffey.m	(revision 17806)
+++ /issm/trunk/src/m/materials/cuffey.m	(revision 17806)
@@ -0,0 +1,41 @@
+function rigidity=cuffey(temperature)
+%CUFFEY - calculates ice rigidity as a function of temperature
+%
+%   rigidity (in s^(1/3)Pa) is the flow law parameter in the flow law sigma=B*e(1/3)
+%   (Cuffey and Paterson, p75). 
+%   temperature is in Kelvin degrees
+%
+%   Usage:
+%      rigidity=cuffey(temperature)
+
+if any(temperature<0)
+	error('input temperature should be in Kelvin (positive)');
+end
+T=temperature-273.15;
+
+%The routine below is equivalent to:
+% n=3; T=temperature-273;
+% %From cuffey
+% Temp=[0;-2;-5;-10;-15;-20;-25;-30;-35;-40;-45;-50];
+% A=[2.4*10^-24;1.7*10^-24;9.3*10^-25;3.5*10^-25;2.1*10^-25;1.2*10^-25;6.8*10^-26;3.7*10^-26;2.0*10^-26;1.0*10^-26;5.2*10^-27;2.6*10^-27];%s-1(Pa-3)
+% %Convert into rigidity B
+% B=A.^(-1/n); %s^(1/3)Pa
+% %Now, do a cubic fit between Temp and B: 
+% fittedmodel=fit(Temp,B,'cubicspline');
+% rigidity=fittedmodel(temperature);
+
+rigidity=zeros(length(T),1);
+pos=find(T<=-45);         rigidity(pos)=10^8*(-0.000396645116301*(T(pos)+50).^3+ 0.013345579471334*(T(pos)+50).^2  -0.356868703259105*(T(pos)+50)+7.272363035371383);
+pos=find(-45<=T & T<-40); rigidity(pos)=10^8*(-0.000396645116301*(T(pos)+45).^3+ 0.007395902726819*(T(pos)+45).^2  -0.253161292268336*(T(pos)+45)+5.772078366321591);
+pos=find(-40<=T & T<-35); rigidity(pos)=10^8*(0.000408322072669*(T(pos)+40).^3+  0.001446225982305*(T(pos)+40).^2  -0.208950648722716*(T(pos)+40)+4.641588833612773);
+pos=find(-35<=T & T<-30); rigidity(pos)=10^8*(-0.000423888728124*(T(pos)+35).^3+ 0.007571057072334*(T(pos)+35).^2  -0.163864233449525*(T(pos)+35)+3.684031498640382);
+pos=find(-30<=T & T<-25); rigidity(pos)=10^8*(0.000147154327025*(T(pos)+30).^3+ 0.001212726150476*(T(pos)+30).^2  -0.119945317335478*(T(pos)+30)+3.001000667185614);
+pos=find(-25<=T & T<-20); rigidity(pos)=10^8*(-0.000193435838672*(T(pos)+25).^3+ 0.003420041055847*(T(pos)+25).^2  -0.096781481303861*(T(pos)+25)+2.449986525148220);
+pos=find(-20<=T & T<-15); rigidity(pos)=10^8*(0.000219771255067*(T(pos)+20).^3+  0.000518503475772*(T(pos)+20).^2  -0.077088758645767*(T(pos)+20)+2.027400665191131);
+pos=find(-15<=T & T<-10); rigidity(pos)=10^8*(-0.000653438900191*(T(pos)+15).^3+ 0.003815072301777*(T(pos)+15).^2  -0.055420879758021*(T(pos)+15)+1.682390865739973);
+pos=find(-10<=T & T<-5);  rigidity(pos)=10^8*(0.000692439419762*(T(pos)+10).^3 -0.005986511201093 *(T(pos)+10).^2 -0.066278074254598*(T(pos)+10)+1.418983411970382);
+pos=find(-5<=T & T<-2);   rigidity(pos)=10^8*(-0.000132282004110*(T(pos)+5).^3 +0.004400080095332*(T(pos)+5).^2    -0.074210229783403*(T(pos)+5)+ 1.024485188140279);
+pos=find(-2<=T);          rigidity(pos)=10^8*(-0.000132282004110*(T(pos)+2).^3 +0.003209542058346*(T(pos)+2).^2    -0.051381363322371*(T(pos)+2)+ 0.837883605537096);
+
+%Now make sure that rigidity is positive
+pos=find(rigidity<0);        rigidity(pos)=10^6;
Index: /issm/trunk/src/m/materials/cuffey.py
===================================================================
--- /issm/trunk/src/m/materials/cuffey.py	(revision 17806)
+++ /issm/trunk/src/m/materials/cuffey.py	(revision 17806)
@@ -0,0 +1,49 @@
+import numpy
+
+def cuffey(temperature):
+	"""
+	CUFFEY - calculates ice rigidity as a function of temperature
+
+	   rigidity (in s^(1/3)Pa) is the flow law parameter in the flow law sigma=B*e(1/3)
+		(Cuffey and Paterson, p75). 
+	   temperature is in Kelvin degrees
+
+	   Usage:
+	      rigidity=cuffey(temperature)
+	"""
+	
+	if numpy.any(temperature<0.):
+		raise RuntimeError("input temperature should be in Kelvin (positive)")
+	
+	T = temperature.reshape(-1,)-273.15
+
+	rigidity=numpy.zeros_like(T)
+	pos=numpy.nonzero(T<=-45)
+	rigidity[pos]=10**8*(-0.000396645116301*(T[pos]+50)**3+ 0.013345579471334*(T[pos]+50)**2  -0.356868703259105*(T[pos]+50)+7.272363035371383)
+	pos=numpy.nonzero(numpy.logical_and(-45<=T,T<-40))
+	rigidity[pos]=10**8*(-0.000396645116301*(T[pos]+45)**3+ 0.007395902726819*(T[pos]+45)**2  -0.253161292268336*(T[pos]+45)+5.772078366321591)
+	pos=numpy.nonzero(numpy.logical_and(-40<=T,T<-35))
+	rigidity[pos]=10**8*(0.000408322072669*(T[pos]+40)**3+  0.001446225982305*(T[pos]+40)**2  -0.208950648722716*(T[pos]+40)+4.641588833612773)
+	pos=numpy.nonzero(numpy.logical_and(-35<=T,T<-30))
+	rigidity[pos]=10**8*(-0.000423888728124*(T[pos]+35)**3+ 0.007571057072334*(T[pos]+35)**2  -0.163864233449525*(T[pos]+35)+3.684031498640382)
+	pos=numpy.nonzero(numpy.logical_and(-30<=T,T<-25))
+	rigidity[pos]=10**8*(0.000147154327025*(T[pos]+30)**3+ 0.001212726150476*(T[pos]+30)**2  -0.119945317335478*(T[pos]+30)+3.001000667185614)
+	pos=numpy.nonzero(numpy.logical_and(-25<=T,T<-20))
+	rigidity[pos]=10**8*(-0.000193435838672*(T[pos]+25)**3+ 0.003420041055847*(T[pos]+25)**2  -0.096781481303861*(T[pos]+25)+2.449986525148220)
+	pos=numpy.nonzero(numpy.logical_and(-20<=T,T<-15))
+	rigidity[pos]=10**8*(0.000219771255067*(T[pos]+20)**3+  0.000518503475772*(T[pos]+20)**2  -0.077088758645767*(T[pos]+20)+2.027400665191131)
+	pos=numpy.nonzero(numpy.logical_and(-15<=T,T<-10))
+	rigidity[pos]=10**8*(-0.000653438900191*(T[pos]+15)**3+ 0.003815072301777*(T[pos]+15)**2  -0.055420879758021*(T[pos]+15)+1.682390865739973)
+	pos=numpy.nonzero(numpy.logical_and(-10<=T,T<-5))
+	rigidity[pos]=10**8*(0.000692439419762*(T[pos]+10)**3 -0.005986511201093 *(T[pos]+10)**2 -0.066278074254598*(T[pos]+10)+1.418983411970382)
+	pos=numpy.nonzero(numpy.logical_and(-5<=T,T<-2))
+	rigidity[pos]=10**8*(-0.000132282004110*(T[pos]+5)**3 +0.004400080095332*(T[pos]+5)**2    -0.074210229783403*(T[pos]+5)+ 1.024485188140279)
+	pos=numpy.nonzero(-2<=T)
+	rigidity[pos]=10**8*(-0.000132282004110*(T[pos]+2)**3 +0.003209542058346*(T[pos]+2)**2    -0.051381363322371*(T[pos]+2)+ 0.837883605537096)
+
+	#Now make sure that rigidity is positive
+	pos=numpy.nonzero(rigidity<0)
+	rigidity[pos]=1**6 
+
+	return rigidity
+
Index: /issm/trunk/src/m/materials/paterson.m
===================================================================
--- /issm/trunk/src/m/materials/paterson.m	(revision 17805)
+++ /issm/trunk/src/m/materials/paterson.m	(revision 17806)
@@ -8,5 +8,5 @@
 %      rigidity=paterson(temperature)
 
-if(temperature<0)
+if any(temperature<0)
 	error('input temperature should be in Kelvin (positive)');
 end
Index: /issm/trunk/src/m/materials/paterson.py
===================================================================
--- /issm/trunk/src/m/materials/paterson.py	(revision 17805)
+++ /issm/trunk/src/m/materials/paterson.py	(revision 17806)
@@ -14,6 +14,9 @@
 	if numpy.any(temperature<0.):
 		raise RuntimeError("input temperature should be in Kelvin (positive)")
-	
-	T = temperature.reshape(-1,)-273.15
+
+	if numpy.ndim(temperature)==2:
+		T = temperature.reshape(-1,)-273.15
+	else:
+		T = numpy.array([temperature])-273.15
 
 	#The routine below is equivalent to:
@@ -31,30 +34,42 @@
 
 	rigidity=numpy.zeros_like(T)
-	pos1=numpy.nonzero(T<=-45)
-	rigidity[pos1]=10**8*(-0.000292866376675*(T[pos1]+50)**3+ 0.011672640664130*(T[pos1]+50)**2  -0.325004442485481*(T[pos1]+50)+  6.524779401948101)
-	pos2=numpy.nonzero(numpy.logical_and(-45<=T,T<-40))
-	rigidity[pos2]=10**8*(-0.000292866376675*(T[pos2]+45)**3+ 0.007279645014004*(T[pos2]+45)**2  -0.230243014094813*(T[pos2]+45)+  5.154964909039554)
-	pos3=numpy.nonzero(numpy.logical_and(-40<=T,T<-35))
-	rigidity[pos3]=10**8*(0.000072737147457*(T[pos3]+40)**3+  0.002886649363879*(T[pos3]+40)**2  -0.179411542205399*(T[pos3]+40)+  4.149132666831214)
-	pos4=numpy.nonzero(numpy.logical_and(-35<=T,T<-30))
-	rigidity[pos4]=10**8*(-0.000086144770023*(T[pos4]+35)**3+ 0.003977706575736*(T[pos4]+35)**2  -0.145089762507325*(T[pos4]+35)+  3.333333333333331)
-	pos5=numpy.nonzero(numpy.logical_and(-30<=T,T<-25))
-	rigidity[pos5]=10**8*(-0.000043984685769*(T[pos5]+30)**3+ 0.002685535025386*(T[pos5]+30)**2  -0.111773554501713*(T[pos5]+30)+  2.696559088937191)
-	pos6=numpy.nonzero(numpy.logical_and(-25<=T,T<-20))
-	rigidity[pos6]=10**8*(-0.000029799523463*(T[pos6]+25)**3+ 0.002025764738854*(T[pos6]+25)**2  -0.088217055680511*(T[pos6]+25)+  2.199331606342181)
-	pos7=numpy.nonzero(numpy.logical_and(-20<=T,T<-15))
-	rigidity[pos7]=10**8*(0.000136920904777*(T[pos7]+20)**3+  0.001578771886910*(T[pos7]+20)**2  -0.070194372551690*(T[pos7]+20)+  1.805165505978111)
-	pos8=numpy.nonzero(numpy.logical_and(-15<=T,T<-10))
-	rigidity[pos8]=10**8*(-0.000899763781026*(T[pos8]+15)**3+ 0.003632585458564*(T[pos8]+15)**2  -0.044137585824322*(T[pos8]+15)+  1.510778053489523)
-	pos9=numpy.nonzero(numpy.logical_and(-10<=T,T<-5))
-	rigidity[pos9]=10**8*(0.001676964325070*(T[pos9]+10)**3-  0.009863871256831*(T[pos9]+10)**2  -0.075294014815659*(T[pos9]+10)+  1.268434288203714)
-	pos10=numpy.nonzero(numpy.logical_and(-5<=T,T<-2))
-	rigidity[pos10]=10**8*(-0.003748937622487*(T[pos10]+5)**3+0.015290593619213*(T[pos10]+5)**2  -0.048160403003748*(T[pos10]+5)+  0.854987973338348)
-	pos11=numpy.nonzero(-2<=T)
-	rigidity[pos11]=10**8*(-0.003748937622488*(T[pos11]+2)**3-0.018449844983174*(T[pos11]+2)**2  -0.057638157095631*(T[pos11]+2)+  0.746900791092860)
+	pos1=numpy.nonzero(T<=-45)[0]
+	if len(pos1):
+		rigidity[pos1]=10**8*(-0.000292866376675*(T[pos1]+50)**3+ 0.011672640664130*(T[pos1]+50)**2  -0.325004442485481*(T[pos1]+50)+  6.524779401948101)
+	pos2=numpy.nonzero(numpy.logical_and(-45<=T,T<-40))[0]
+	if len(pos2):
+		rigidity[pos2]=10**8*(-0.000292866376675*(T[pos2]+45)**3+ 0.007279645014004*(T[pos2]+45)**2  -0.230243014094813*(T[pos2]+45)+  5.154964909039554)
+	pos3=numpy.nonzero(numpy.logical_and(-40<=T,T<-35))[0]
+	if len(pos3):
+		rigidity[pos3]=10**8*(0.000072737147457*(T[pos3]+40)**3+  0.002886649363879*(T[pos3]+40)**2  -0.179411542205399*(T[pos3]+40)+  4.149132666831214)
+	pos4=numpy.nonzero(numpy.logical_and(-35<=T,T<-30))[0]
+	if len(pos4):
+		rigidity[pos4]=10**8*(-0.000086144770023*(T[pos4]+35)**3+ 0.003977706575736*(T[pos4]+35)**2  -0.145089762507325*(T[pos4]+35)+  3.333333333333331)
+	pos5=numpy.nonzero(numpy.logical_and(-30<=T,T<-25))[0]
+	if len(pos5):
+		rigidity[pos5]=10**8*(-0.000043984685769*(T[pos5]+30)**3+ 0.002685535025386*(T[pos5]+30)**2  -0.111773554501713*(T[pos5]+30)+  2.696559088937191)
+	pos6=numpy.nonzero(numpy.logical_and(-25<=T,T<-20))[0]
+	if len(pos6):
+		rigidity[pos6]=10**8*(-0.000029799523463*(T[pos6]+25)**3+ 0.002025764738854*(T[pos6]+25)**2  -0.088217055680511*(T[pos6]+25)+  2.199331606342181)
+	pos7=numpy.nonzero(numpy.logical_and(-20<=T,T<-15))[0]
+	if len(pos7):
+		rigidity[pos7]=10**8*(0.000136920904777*(T[pos7]+20)**3+  0.001578771886910*(T[pos7]+20)**2  -0.070194372551690*(T[pos7]+20)+  1.805165505978111)
+	pos8=numpy.nonzero(numpy.logical_and(-15<=T,T<-10))[0]
+	if len(pos8):
+		rigidity[pos8]=10**8*(-0.000899763781026*(T[pos8]+15)**3+ 0.003632585458564*(T[pos8]+15)**2  -0.044137585824322*(T[pos8]+15)+  1.510778053489523)
+	pos9=numpy.nonzero(numpy.logical_and(-10<=T,T<-5))[0]
+	if len(pos9):
+		rigidity[pos9]=10**8*(0.001676964325070*(T[pos9]+10)**3-  0.009863871256831*(T[pos9]+10)**2  -0.075294014815659*(T[pos9]+10)+  1.268434288203714)
+	pos10=numpy.nonzero(numpy.logical_and(-5<=T,T<-2))[0]
+	if len(pos10):
+		rigidity[pos10]=10**8*(-0.003748937622487*(T[pos10]+5)**3+0.015290593619213*(T[pos10]+5)**2  -0.048160403003748*(T[pos10]+5)+  0.854987973338348)
+	pos11=numpy.nonzero(-2<=T)[0]
+	if len(pos11):
+		rigidity[pos11]=10**8*(-0.003748937622488*(T[pos11]+2)**3-0.018449844983174*(T[pos11]+2)**2  -0.057638157095631*(T[pos11]+2)+  0.746900791092860)
 
 	#Now make sure that rigidity is positive
-	pos=numpy.nonzero(rigidity<0)
-	rigidity[pos]=1**6 
+	pos=numpy.nonzero(rigidity<0)[0]
+	if len(pos):
+		rigidity[pos]=1**6 
 
 	return rigidity
Index: /issm/trunk/src/m/mech/analyticaldamage.m
===================================================================
--- /issm/trunk/src/m/mech/analyticaldamage.m	(revision 17805)
+++ /issm/trunk/src/m/mech/analyticaldamage.m	(revision 17806)
@@ -48,5 +48,5 @@
 	error(['md.results.strainrate is not present.  Calculate using md=mechanicalproperties(md,vx,vy)']);
 end
-if ~(md.mesh.dimension==2),
+if dimension(md.mesh)~=2,
 	error('only 2d model supported currently');
 end
@@ -62,5 +62,5 @@
 coordsys = getfieldvalue(options,'coordsys','longitudinal');
 if length(sigmab)==1,
-	sigmab=sigmab*ones(md.mesh.numberofelements,1);
+	sigmab=sigmab*ones(md.mesh.numberofvertices,1);
 end
 
Index: /issm/trunk/src/m/mech/analyticaldamage.py
===================================================================
--- /issm/trunk/src/m/mech/analyticaldamage.py	(revision 17805)
+++ /issm/trunk/src/m/mech/analyticaldamage.py	(revision 17806)
@@ -1,8 +1,8 @@
 import numpy as npy
-from pairoptions import pairoptions
 from averaging import averaging
 from plotmodel import plotmodel
+from thomasparams import thomasparams
 
-def analyticaldamage(md,*args):
+def analyticaldamage(md,**kwargs):
 	'''
 	ANALYTICALDAMAGE - compute damage for an ice shelf 
@@ -14,11 +14,13 @@
 	
 	   Available options:
-			- 'eq'			: analytical equation to use in the calculation.  Must be one of:
+			-eq			: analytical equation to use in the calculation.  Must be one of:
 									'Weertman1D' for a confined ice shelf free to flow in one direction
 									'Weertman2D' for an unconfined ice shelf free to spread in any direction
 									'Thomas' for a 2D ice shelf, taking into account full strain rate tensor (default)
-			- 'smoothing'	: the amount of smoothing to be applied to the strain rate data.
+			-smoothing	: the amount of smoothing to be applied to the strain rate data.
 									Type 'help averaging' for more information on its usage.
-			- 'sigmab'		: a compressive backstress term to be subtracted from the driving stress 
+			-coordsys	: coordinate system for calculating the strain rate
+						components. Must be one of:
+			-sigmab		: a compressive backstress term to be subtracted from the driving stress 
 									in the damage calculation
 	
@@ -34,76 +36,33 @@
 	
 	   Usage:
-	      [damage,B,backstress]=analyticaldamage(md,options)
+	      damage,B,backstress=analyticaldamage(md,kwargs)
 	
 	   Example:
-	      [damage,B,backstress]=analyticaldamage(md,'eq','Weertman2D','smoothing',2,'backstress',10e3)
+	      damage,B,backstress=analyticaldamage(md,eq='Weertman2D',smoothing=2,sigmab=10e3)
 	'''
+
+	#unpack kwargs
+	eq=kwargs.pop('eq','Thomas')
+	if 'eq' in kwargs: del kwargs['eq']
+	smoothing=kwargs.pop('smoothing',0)
+	if 'smoothing' in kwargs: del kwargs['smoothing']
+	coordsys=kwargs.pop('coordsys','longitudinal')
+	if 'coordsys' in kwargs: del kwargs['coordsys']
+	sigmab=kwargs.pop('sigmab',0)
+	if 'sigmab' in kwargs: del kwargs['sigmab']
+	assert len(kwargs)==0, 'error, unexpected or misspelled kwargs'
+
+	if len(sigmab)==1:
+		sigmab=sigmab*npy.ones((md.mesh.numberofvertices,))
 
 	# check inputs
 	if 'strainrate' not in md.results.__dict__:
 		raise StandardError('md.results.strainrate not present.  Calculate using md=mechanicalproperties(md,vx,vy)')
-	if md.mesh.dimension!=2:
-		raise StandardError('only 2D model supported currently')
+	if not '2d' in md.mesh.__doc__:
+		raise StandardError('only 2d (planview) model supported currently')
 	if npy.any(md.flowequation.element_equation!=2):
 		print 'Warning: the model has some non SSA elements. These will be treated like SSA elements'
 
-	# process options
-	options = pairoptions(*args)
-	eq = options.getfieldvalue('eq','Thomas')
-	smoothing = options.getfieldvalue('smoothing',0)
-	sigmab = options.getfieldvalue('sigmab',0)
-	if len(sigmab==1):
-		sigmab=sigmab*npy.ones(md.mesh.numberofvertices,)
-	
-	# average element strain rates onto vertices
-	e1=averaging(md,md.results.strainrate.principalvalue1,smoothing)/md.constants.yts # convert to s^-1
-	e2=averaging(md,md.results.strainrate.principalvalue2,smoothing)/md.constants.yts
-	exx=averaging(md,md.results.strainrate.xx,smoothing)/md.constants.yts
-	eyy=averaging(md,md.results.strainrate.yy,smoothing)/md.constants.yts
-	exy=averaging(md,md.results.strainrate.xy,smoothing)/md.constants.yts
-	
-	# checks: any of e1 or e2 equal to zero?
-	pos=npy.nonzero(e1==0)
-	if npy.any(pos==1):
-		print 'WARNING: first principal strain rate equal to zero.  Value set to 1e-13 s^-1'
-		e1[pos]=1e-13
-	pos=npy.nonzero(e2==0)
-	if npy.any(pos==1):
-		disp('WARNING: second principal strain rate equal to zero.  Value set to 1e-13 s^-1');
-		e2[pos]=1e-13
-	
-	## old method using principal strain rates {{{
-	## ex=maximum principal tensile strain rate
-	#ex=e1;
-	#a=e2./e1;
-	#pos=find(e1<0 & e2>0); # longitudinal compression and lateral tension
-	#a(pos)=e1(pos)./e2(pos);
-	#ex(pos)=e2(pos);
-	#pos2=find(e1<0 & e2<0 & abs(e1)<abs(e2)); # lateral and longitudinal compression
-	#a(pos2)=e1(pos2)./e2(pos2);
-	#ex(pos2)=e2(pos2);
-	#pos3=find(e1>0 & e2>0 & abs(e1)<abs(e2)); # lateral and longitudinal tension 
-	#a(pos3)=e1(pos3)./e2(pos3);
-	#ex(pos3)=e2(pos3);
-	#id=find(e1<0 & e2<0);
-	#a(id)=-a(id); # where both strain rates are compressive, enforce negative alpha
-	#
-	## }}}
-	
-	# new method using longitudinal strain rates defined by observed velocity vector
-	velangle=npy.arctan(md.initialization.vy/md.initialization.vx)
-	ex=0.5*(exx+eyy)+0.5*(exx-eyy)*npy.cos(2.*velangle)+exy*npy.sin(2.*velangle)
-	ey=exx+eyy-ex # trace of strain rate tensor is invariant
-	exy=-0.5*(exx-eyy)*npy.sin(2.*velangle)+exy*npy.cos(2.*velangle)
-	a=ey/ex
-	b=exy/ex
-	pos=npy.nonzero(npy.logical_and(ex<0,ey<0))
-	#length(pos)
-	a[pos]=-a[pos]
-	
-	# a < -1 in areas of strong lateral compression or longitudinal compression
-	# and theta is undefined at a = -2
-	pos=npy.nonzero(abs((abs(a)-2))<1e-3)
-	a[pos]=-2+1e-3
+	a,b,theta,ex=thomasparams(md,eq=eq,smoothing=smoothing,coordsys=coordsys)
 	
 	# spreading stress
@@ -117,18 +76,5 @@
 	n=averaging(md,md.materials.rheology_n,0)
 	
-	if eq=='Weertman1D':
-		theta=1./8*npy.ones(md.mesh.numberofvertices,)
-		a=npy.zeros(md.mesh.numberofvertices,)
-	elif eq=='Weertman2D':
-		theta=1./9*npy.ones(md.mesh.numberofvertices,1)
-		a=npy.ones(md.mesh.numberofvertices,)
-	elif eq=='Thomas':
-		theta=((1+a+a**2+b**2)**((n-1)/2))/(abs(2+a)**n)
-	else:
-		raise StandardError('argument passed to "eq" not valid.  Type "help analyticaldamage" for usage')
-	
-	D=1-(1+a+a**2+b**2)**((n-1)/(2*n))/abs(ex)**(1./n)*(T-sigmab)/B/(2+a)/npy.sign(ex)
-	
-	backstress=npy.zeros(md.mesh.numberofvertices,)
+	D=1.-(1.+a+a**2+b**2)**((n-1.)/(2.*n))/npy.abs(ex)**(1./n)*(T-sigmab)/B/(2.+a)/npy.sign(ex)
 	
 	# D>1 where (2+a).*sign(ex)<0, compressive regions where high backstress needed
@@ -136,18 +82,23 @@
 	D[pos]=0
 	
-	# backstress to bring damage to zero
-	backstress[pos]=T[pos]-(1-D[pos])*B[pos]*npy.sign(ex[pos])*(2+a[pos])*abs(ex[pos])**(1./n[pos])/(1+a[pos]+a[pos]**2)**((n[pos]-1)/2./n[pos])
+	backstress=npy.zeros((md.mesh.numberofvertices,))
+	
+	# backstress to bring D down to one 
+	backstress[pos]=T[pos]-(1.-D[pos])*B[pos]*npy.sign(ex[pos])*(2.+a[pos])*npy.abs(ex[pos])**(1./n[pos])/(1.+a[pos]+a[pos]**2)**((n[pos]-1.)/2./n[pos])
 	
 	pos=npy.nonzero(D<0)
+	#mask=ismember(1:md.mesh.numberofvertices,pos);
 	D[pos]=0
-
+	
 	# backstress to bring negative damage to zero
-	backstress[pos]=T[pos]-(1-D[pos])*B[pos]*npy.sign(ex[pos])*(2+a[pos])*abs(ex[pos])**(1./n[pos])/(1+a[pos]+a[pos]**2)**((n[pos]-1)/2./n[pos])
+	backstress[pos]=T[pos]-(1.-D[pos])*B[pos]*npy.sign(ex[pos])*(2.+a[pos])*npy.abs(ex[pos])**(1./n[pos])/(1.+a[pos]+a[pos]**2)**((n[pos]-1.)/2./n[pos])
 	
 	pos=npy.nonzero(backstress<0)
 	backstress[pos]=0
 	
-	# increased rigidity to bring negative damage to zero
-	B[pos]=npy.sign(ex[pos])/(2+a[pos])*(1+a[pos]+a[pos]**2)**((n[pos]-1)/2./n[pos])*T[pos]/abs(ex[pos])**(1./n[pos]);
+	# rigidity from Thomas relation for D=0 and backstress=0
+	B=npy.sign(ex)/(2.+a)*(1.+a+a**2)**((n-1.)/2./n)*T/(npy.abs(ex)**(1./n))
+	pos=npy.nonzero(B<0)
+	B[pos]=md.materials.rheology_B[pos]
 	
 	damage=D
Index: /issm/trunk/src/m/mech/backstressfrominversion.m
===================================================================
--- /issm/trunk/src/m/mech/backstressfrominversion.m	(revision 17805)
+++ /issm/trunk/src/m/mech/backstressfrominversion.m	(revision 17806)
@@ -41,5 +41,5 @@
 	error(['md.results.strainrate is not present.  Calculate using md=mechanicalproperties(md,vx,vy)']);
 end
-if ~(md.mesh.dimension==2),
+if dimension(md.mesh)~=2,
 	error('only 2d model supported currently');
 end
Index: /issm/trunk/src/m/mech/backstressfrominversion.py
===================================================================
--- /issm/trunk/src/m/mech/backstressfrominversion.py	(revision 17806)
+++ /issm/trunk/src/m/mech/backstressfrominversion.py	(revision 17806)
@@ -0,0 +1,75 @@
+import numpy as npy
+from averaging import averaging
+from thomasparams import thomasparams
+
+def backstressfrominversion(md,**kwargs):
+	'''
+	Compute ice shelf backstress from inversion results.
+
+	This routine computes backstress based on the analytical formalism of
+	Thomas (1973) and Borstad et al. (2013, The Cryoshpere).  The model
+	must contain inversion results for ice rigidity.  Strain rates must
+	also be included, either from observed or modeled velocities.  Ice
+	rigidity B is assumed to be parameterized by the ice temperature in
+	md.materials.rheology_B.
+
+   Available options:
+		- 'tempmask'	: mask the inverted rigidity to be no more than
+							appropriate for the temperature of the ice?  
+							Boolean, defaults to false.
+		- 'smoothing'	: the amount of smoothing to be applied to the strain rate data.
+								Type 'help averaging' for more information on its
+								usage. Defaults to 0.
+		- 'coordsys'	: coordinate system for calculating the strain rate
+							components. Must be one of: 
+				'longitudinal': x axis aligned along a flowline at every point (default)
+				'principal': x axis aligned along maximum principal strain rate
+					at every point
+				'xy': x and y axes same as in polar stereographic projection 
+
+   Return values:
+		'backstress' is the inferred backstress necessary to balance the
+		analytical solution (keeping damage within its appropriate limits, e.g. D
+		in [0,1]).
+
+   Usage:
+      backstress=backstressfrominversion(md,options)
+
+   Example:
+      backstress=backstressfrominversion(md,'smoothing',2,'coordsys','longitudinal','tempmask',true);
+	'''
+
+	# unpack kwargs
+	tempmask=kwargs.pop('tempmask',False)
+	if 'tempmask' in kwargs: del kwargs['maxiter']
+	smoothing=kwargs.pop('smoothing',0)
+	if 'smoothing' in kwargs: del kwargs['smoothing']
+	coordsys=kwargs.pop('coordsys','longitudinal')
+	if 'coordsys' in kwargs: del kwargs['coordsys']
+	assert len(kwargs)==0, 'error, unexpected or misspelled kwargs'
+
+	# some checks
+	if not hasattr(md.results,'strainrate'):
+		raise StandardError('md.results.strainrate not present.  Calculate using md=mechanicalproperties(md,vx,vy)')
+	if not '2d' in md.mesh.__doc__:
+		raise StandardError('only 2d (planview) model supported currently')
+	if any(md.flowequation.element_equation!=2):
+		raise StandardError('Warning: the model has some non-SSA elements.  These will be treated like SSA elements')
+
+	T=0.5*md.materials.rho_ice*md.constants.g*(1-md.materials.rho_ice/md.materials.rho_water)*md.geometry.thickness
+	n=averaging(md,md.materials.rheology_n,0)
+	B=md.materials.rheology_B
+	Bi=md.results.StressbalanceSolution.MaterialsRheologyBbar.reshape(-1,)
+	
+	a0,b0,theta0,ex0=thomasparams(md,eq='Thomas',smoothing=smoothing,coordsys=coordsys)
+	
+	if tempmask:
+		Bi=md.results.StressbalanceSolution.MaterialsRheologyBbar
+		pos=npy.nonzero(Bi>md.materials.rheology_B)
+		Bi[pos]=md.materials.rheology_B[pos]
+	
+	# analytical backstress solution
+	backstress=T-Bi*npy.sign(ex0)*(2+a0)*npy.abs(ex0)**(1./n)/((1+a0+a0**2+b0**2)**((n-1.)/2./n))
+	backstress[npy.nonzero(backstress<0)]=0
+
+	return backstress
Index: /issm/trunk/src/m/mech/basalstress.m
===================================================================
--- /issm/trunk/src/m/mech/basalstress.m	(revision 17805)
+++ /issm/trunk/src/m/mech/basalstress.m	(revision 17806)
@@ -17,5 +17,5 @@
 
 %compute basal drag
-bx=(md.constants.g*(md.materials.rho_ice*md.geometry.thickness+md.materials.rho_water*md.geometry.bed)).^r.*(md.friction.coefficient).^2.*ubx.^s;
-by=(md.constants.g*(md.materials.rho_ice*md.geometry.thickness+md.materials.rho_water*md.geometry.bed)).^r.*(md.friction.coefficient).^2.*uby.^s;
-b=(md.constants.g*(md.materials.rho_ice*md.geometry.thickness+md.materials.rho_water*md.geometry.bed)).^r.*(md.friction.coefficient).^2.*ub.^s;
+bx=(md.constants.g*(md.materials.rho_ice*md.geometry.thickness+md.materials.rho_water*md.geometry.base)).^r.*(md.friction.coefficient).^2.*ubx.^s;
+by=(md.constants.g*(md.materials.rho_ice*md.geometry.thickness+md.materials.rho_water*md.geometry.base)).^r.*(md.friction.coefficient).^2.*uby.^s;
+b=(md.constants.g*(md.materials.rho_ice*md.geometry.thickness+md.materials.rho_water*md.geometry.base)).^r.*(md.friction.coefficient).^2.*ub.^s;
Index: /issm/trunk/src/m/mech/damagefrominversion.m
===================================================================
--- /issm/trunk/src/m/mech/damagefrominversion.m	(revision 17805)
+++ /issm/trunk/src/m/mech/damagefrominversion.m	(revision 17806)
@@ -21,5 +21,5 @@
 	error(['md.results.strainrate is not present.  Calculate using md=mechanicalproperties(md,vx,vy)']);
 end
-if ~(md.mesh.dimension==2),
+if dimension(md.mesh)~=2,
 	error('only 2d model supported currently');
 end
Index: /issm/trunk/src/m/mech/damagefrominversion.py
===================================================================
--- /issm/trunk/src/m/mech/damagefrominversion.py	(revision 17806)
+++ /issm/trunk/src/m/mech/damagefrominversion.py	(revision 17806)
@@ -0,0 +1,44 @@
+import numpy as npy
+
+def damagefrominversion(md):
+	'''
+	compute ice shelf damage from inversion results
+
+	This routine computes damage based on the analytical formalism of Borstad et
+	al. (2013, The Cryosphere).  The model must contain inversion results for
+	ice rigidity.  Ice rigidity B is assumed to be parameterized by the ice
+	temperature in md.materials.rheology_B. 
+	
+	Usage:
+		damage=damagefrominversion(md)
+	
+	Example:
+		damage=damagefrominversion(md)
+	'''
+
+	# check inputs
+	if not hasattr(md.results,'strainrate'):
+		raise StandardError('md.results.strainrate is not present.  Calculate using md=mechanicalproperties(md,vx,vy)')
+	if not '2d' in md.mesh.__doc__:
+		raise StandardError('only 2d (planview) model supported currently')
+	if any(md.flowequation.element_equation!=2):
+		raise StandardError('Warning: the model has some non-SSA elements.  These will be treated like SSA elements')
+	if npy.ndim(md.results.StressbalanceSolution.MaterialsRheologyBbar)==2:
+		Bi=md.results.StressbalanceSolution.MaterialsRheologyBbar.reshape(-1,)
+	else:
+		Bi=md.results.StressbalanceSolution.MaterialsRheologyBbar
+	if npy.ndim(md.materials.rheology_B)==2:
+		BT=md.materials.rheology_B.reshape(-1,)
+	else:
+		BT=md.materials.rheology_B
+
+	damage=npy.zeros_like(Bi)
+
+	# Damage where Bi softer than B(T)
+	pos=npy.nonzero(Bi<BT)[0]
+	damage[pos]=1.-Bi[pos]/BT[pos]
+	
+	pos=npy.nonzero(damage<0)
+	damage[pos]=0
+
+	return damage
Index: /issm/trunk/src/m/mech/mechanicalproperties.m
===================================================================
--- /issm/trunk/src/m/mech/mechanicalproperties.m	(revision 17805)
+++ /issm/trunk/src/m/mech/mechanicalproperties.m	(revision 17806)
@@ -2,7 +2,7 @@
 %MECHANICALPROPERTIES - compute stress and strain rate for a goven velocity
 %
-%   this routine computes the components of the stress tensor
-%   strain rate tensor and their respective principal directions.
-%   the results are in the model md: md.results
+%   this routine computes the components of the (deviatoric) stress tensor,
+%   the strain rate tensor, and their respective principal directions.
+%   The results are in the model md: md.results
 %
 %   Usage:
@@ -15,7 +15,7 @@
 %some checks
 if length(vx)~=md.mesh.numberofvertices | length(vy)~=md.mesh.numberofvertices,
-	error(['the input velocity should be of size ' num2str(md.mesh.numberofvertices) '!'])
+	%error(['the input velocity should be of size ' num2str(md.mesh.numberofvertices) '!'])
 end
-if ~(md.mesh.dimension==2)
+if dimension(md.mesh)~=2
 	error('only 2d model supported yet');
 end
@@ -107,4 +107,5 @@
 %plug onto the model
 %NB: Matlab sorts the eigen value in increasing order, we want the reverse
+%NOTE: all stresses below are deviatoric
 stress=struct('xx',[],'yy',[],'xy',[],'principalvalue1',[],'principalaxis1',[],'principalvalue2',[],'principalaxis2',[],'effectivevalue',[]);
 stress.xx=tau_xx;
@@ -115,5 +116,5 @@
 stress.principalvalue2=valuesstress(:,2);
 stress.principalaxis2=directionsstress(:,3:4);
-stress.effectivevalue=1/sqrt(2)*sqrt(stress.xx.^2+stress.yy.^2+2*stress.xy.^2);
+stress.effectivevalue=1/sqrt(2)*sqrt(stress.xx.^2+stress.yy.^2+2*stress.xy.^2); % effective shear stress (sqrt(J2))
 md.results.stress=stress;
 
@@ -129,4 +130,5 @@
 md.results.strainrate=strainrate;
 
+%exact same stress as above
 deviatoricstress=struct('xx',[],'yy',[],'xy',[],'principalvalue1',[],'principalaxis1',[],'principalvalue2',[],'principalaxis2',[],'effectivevalue',[]);
 deviatoricstress.xx=tau_xx;
@@ -139,2 +141,6 @@
 deviatoricstress.effectivevalue=1/sqrt(2)*sqrt(stress.xx.^2+stress.yy.^2+2*stress.xy.^2);
 md.results.deviatoricstress=deviatoricstress;
+
+viscosity=struct('nu',[]);
+viscosity.nu=nu;
+md.results.viscosity=viscosity;
Index: /issm/trunk/src/m/mech/mechanicalproperties.py
===================================================================
--- /issm/trunk/src/m/mech/mechanicalproperties.py	(revision 17805)
+++ /issm/trunk/src/m/mech/mechanicalproperties.py	(revision 17806)
@@ -2,4 +2,5 @@
 from GetNodalFunctionsCoeff import GetNodalFunctionsCoeff
 from results import results
+from averaging import averaging
 
 def mechanicalproperties(md,vx,vy):
@@ -22,13 +23,19 @@
 	if len(vx)!=md.mesh.numberofvertices or len(vy)!=md.mesh.numberofvertices:
 		raise ValueError('the input velocity should be of size ' + md.mesh.numberofvertices)
-
-	if md.mesh.dimension!=2:
-		raise StandardError('only 2D model supported currently')
+	
+	#if md.mesh.dimension!=2:
+	#	raise StandardError('only 2D model supported currently')
 
 	if npy.any(md.flowequation.element_equation!=2):
 		print 'Warning: the model has some non SSA elements. These will be treated like SSA elements'
+
+	if npy.ndim(vx)==2:
+		vx=vx.reshape(-1,)
+	if npy.ndim(vy)==2:
+		vy=vy.reshape(-1,)
 	
 	#initialization
 	numberofelements=md.mesh.numberofelements
+	numberofvertices=md.mesh.numberofvertices
 	index=md.mesh.elements
 	summation=npy.array([[1],[1],[1]])
@@ -54,5 +61,5 @@
 	nu=npy.zeros((numberofelements,))
 	B_bar=npy.dot(md.materials.rheology_B[index-1],summation/3.).reshape(-1,)
-	power=(md.materials.rheology_n-1.)/(2.*md.materials.rheology_n)
+	power=((md.materials.rheology_n-1.)/(2.*md.materials.rheology_n)).reshape(-1,)
 	second_inv=(ux**2.+vy**2.+((uy+vx)**2.)/4.+ux*vy).reshape(-1,)
 	
@@ -66,4 +73,6 @@
 		location=npy.nonzero(npy.logical_and(second_inv==0,power==0))
 		nu[location]=B_bar[location]
+		location=npy.nonzero(npy.logical_and(second_inv==0,power!=0))
+		nu[location]=10^18
 	elif 'matdamageice' in md.materials.__module__:
 		Zinv=npy.dot(md.materials.rheology_Z[index-1],summation/3.).reshape(-1,)
Index: /issm/trunk/src/m/mech/robintemperature.m
===================================================================
--- /issm/trunk/src/m/mech/robintemperature.m	(revision 17805)
+++ /issm/trunk/src/m/mech/robintemperature.m	(revision 17806)
@@ -35,7 +35,7 @@
 
 %create vertical coordinate variable
-zstar=sqrt(2*alphaT*thickness/accumrate);
+zstar=sqrt(2*alphaT*thickness./accumrate);
 
-tprofile=surftemp+sqrt(2*thickness*pi/accumrate/alphaT)*(-heatflux)/2/rho/c.*(erf(z./zstar)-erf(thickness./zstar));
+tprofile=surftemp+sqrt(2*thickness*pi./accumrate/alphaT).*(-heatflux)/2/rho/c.*(erf(z./zstar)-erf(thickness./zstar));
 
 % difference between surface and base temperature for check (Cuffey2010 p412):
Index: /issm/trunk/src/m/mech/robintemperature.py
===================================================================
--- /issm/trunk/src/m/mech/robintemperature.py	(revision 17806)
+++ /issm/trunk/src/m/mech/robintemperature.py	(revision 17806)
@@ -0,0 +1,41 @@
+import numpy as npy
+from scipy.special import erf
+
+def robintemperature(heatflux,accumrate,thickness,surftemp,z):
+	'''
+	Compute vertical temperature profile of an ice sheet (Robin, 1955)
+
+	This routine computes the vertical temperature profile of an ice sheet
+	according to the solution of Robin (1955), neglecting friction and
+	horizontal advection.  The solution is thus most appropriate at an ice
+	divide.
+
+	The coordinate system for the solution runs from z=0 at the base 
+	to z=H at the surface of the ice.
+
+	Parameters (SI units):
+		-heatflux	Geothermal heat flux (W m^-2)
+		-accumrate	Surface accumulation rate (m s^-1 ice equivalent)
+		-thickness	Ice thickness (m)
+		-surftemp	Surface temperature (K)
+		-z				Vertical position at which to calculate temperature
+						(z can be a scalar or a vector)
+
+	Returns a vector the same length as z containing the temperature in K
+
+	Usage:
+		tprofile=robintemperature(heatflux,accumrate,thickness,surftemp,z)
+	'''
+
+	# some constants (from Holland and Jenkins, 1999)
+	alphaT=1.14e-6 # thermal diffusivity (m^2 s^-1)
+	c=2009. # specific heat capacity (J kg^-1 K^-1)
+	rho=917.  # ice density (kg m^-3)
+	
+	#create vertical coordinate variable
+	zstar=npy.sqrt(2.*alphaT*thickness/accumrate)
+	
+	tprofile=surftemp+npy.sqrt(2.*thickness*npy.pi/accumrate/alphaT)*(-heatflux)/2./rho/c*(erf(z/zstar)-erf(thickness/zstar))
+	
+	# difference between surface and base temperature for check (Cuffey2010 p412):
+	# print tprofile-surftemp
Index: /issm/trunk/src/m/mech/steadystateiceshelftemp.m
===================================================================
--- /issm/trunk/src/m/mech/steadystateiceshelftemp.m	(revision 17805)
+++ /issm/trunk/src/m/mech/steadystateiceshelftemp.m	(revision 17806)
@@ -46,6 +46,6 @@
 
 %calculate depth-averaged temperature (in Celsius)
-%temperature(pos)=-( (Tb(pos)-Ts(pos))*ki./wi(pos) + Hi(pos).*Tb(pos) - (Hi(pos).*Ts(pos) + (Tb(pos)-Ts(pos))*ki./wi(pos)).*exp(Hi(pos).*wi(pos)/ki) )./( Hi(pos).*(exp(Hi(pos).*wi(pos)/ki)-1));
-temperature(pos)=-( ((Tb(pos)-Ts(pos))*ki./wi(pos) + Hi(pos).*Tb(pos))./exp(Hi(pos).*wi(pos)/ki) - Hi(pos).*Ts(pos) + (Tb(pos)-Ts(pos))*ki./wi(pos))./( Hi(pos).*(1-exp(-Hi(pos).*wi(pos)/ki)));
+temperature(pos)=-( (Tb(pos)-Ts(pos))*ki./wi(pos) + Hi(pos).*Tb(pos) - (Hi(pos).*Ts(pos) + (Tb(pos)-Ts(pos))*ki./wi(pos)).*exp(Hi(pos).*wi(pos)/ki) )./( Hi(pos).*(exp(Hi(pos).*wi(pos)/ki)-1));
+%temperature(pos)=-( ((Tb(pos)-Ts(pos))*ki./wi(pos) + Hi(pos).*Tb(pos))./exp(Hi(pos).*wi(pos)/ki) - Hi(pos).*Ts(pos) + (Tb(pos)-Ts(pos))*ki./wi(pos))./( Hi(pos).*(1-exp(-Hi(pos).*wi(pos)/ki)));
 
 %temperature should not be less than surface temp
Index: /issm/trunk/src/m/mech/strainrateuncert.m
===================================================================
--- /issm/trunk/src/m/mech/strainrateuncert.m	(revision 17805)
+++ /issm/trunk/src/m/mech/strainrateuncert.m	(revision 17806)
@@ -32,5 +32,5 @@
 	error(['the velocity error dvy should be of size ' num2str(md.mesh.numberofelements) ' or 1!'])
 end
-if ~(md.mesh.dimension==2)
+if dimension(md.mesh)~=2,
 	error('only 2d model supported yet');
 end
Index: /issm/trunk/src/m/mech/thomasparams.m
===================================================================
--- /issm/trunk/src/m/mech/thomasparams.m	(revision 17805)
+++ /issm/trunk/src/m/mech/thomasparams.m	(revision 17806)
@@ -1,3 +1,3 @@
-function [alpha,beta,theta,ex]=thomasparams(md,varargin)
+function [alpha,beta,theta,ex,sigxx]=thomasparams(md,varargin)
 %THOMASPARAMS - compute Thomas' geometric parameters for an ice shelf 
 %
@@ -35,10 +35,11 @@
 %		the equivalent stress
 %
-%		'exx' is the longitudinal strain rate along a coordinate system defined
-%		by 'coordsys' 
+%		'exx' is the strain rate along a coordinate system defined by 'coordsys' 
 %
-%   Usage: [alpha,beta,theta,exx]=ThomasParams(md,options)
+%		'sigxx' is the deviatoric stress along a coordinate system defined by 'coordsys' 
 %
-%   Example: [alpha,beta,theta,exx]=ThomasParams(md,'eq','Thomas','smoothing',2,'coordsys','longitudinal')
+%   Usage: [alpha,beta,theta,exx,sigxx]=ThomasParams(md,options)
+%
+%   Example: [alpha,beta,theta,exx,sigxx]=ThomasParams(md,'eq','Thomas','smoothing',2,'coordsys','longitudinal')
 
 %some checks
@@ -50,5 +51,5 @@
 	error(['md.results.strainrate is not present.  Calculate using md=mechanicalproperties(md,vx,vy)'])
 end
-if ~(md.mesh.dimension==2)
+if dimension(md.mesh)~=2,
 	error('only 2d model supported currently');
 end
@@ -82,4 +83,8 @@
 end
 
+% rheology
+n=averaging(md,md.materials.rheology_n,0);
+B=md.materials.rheology_B;
+
 switch coordsys
 	case 'principal'
@@ -98,4 +103,5 @@
 		id=find(e1<0 & e2<0);
 		a(id)=-a(id); % where both strain rates are compressive, enforce negative alpha
+		sigxx=(abs(ex)./((1+a+a.^2).^((n-1)/2))).^(1./n).*B;
 		%mask=ismember(1:md.mesh.numberofvertices,id);
 		%plotmodel(md,'data',ex,'mask',mask)
@@ -114,7 +120,8 @@
 		a=ey./ex;
 		b=exy./ex;
-		pos=find(ex<0 & ey<0);
-		%length(pos)
-		a(pos)=-a(pos);
+		%pos=find(ex<0 & ey<0);
+		%a(pos)=-a(pos);
+		%sigxx=(abs(ex)./((1+a+a.^2+b.^2).^((n-1)/2))).^(1./n).*B;
+		sigxx=abs(ex).^(1./n-1).*ex./((1+a+a.^2+b.^2).^((n-1)./(2*n))).*B;
 	otherwise
 		error('argument passed to "coordsys" not valid');
@@ -128,7 +135,4 @@
 end
 a(pos)=-2+1e-3;
-
-% rheology
-n=averaging(md,md.materials.rheology_n,0);
 
 switch eq
Index: /issm/trunk/src/m/mech/thomasparams.py
===================================================================
--- /issm/trunk/src/m/mech/thomasparams.py	(revision 17806)
+++ /issm/trunk/src/m/mech/thomasparams.py	(revision 17806)
@@ -0,0 +1,145 @@
+import numpy as npy
+from averaging import averaging
+
+def thomasparams(md,**kwargs):
+	'''
+	compute Thomas' geometric parameters for an ice shelf 
+
+	This routine computes geometric parameters representing ratios between
+	components of the horizontal strain rate tensor for an ice shelf, as
+	originally developed in Thomas (1973).  The model must contain computed
+	strain rates, either from observed or modeled ice velocities.
+
+   Available options:
+	 -eq			: analytical equation to use in the calculation.  Must be one of:
+				'Thomas' for a 2D ice shelf, taking into account full strain rate
+					tensor (default)
+				'Weertman1D' for a confined ice shelf free to flow in one direction
+				'Weertman2D' for an unconfined ice shelf free to spread in any direction
+
+	 -smoothing	: an integer smoothing parameter for the averaging function
+						(default 0) Type 'help averaging' for more information on its usage.
+
+	 -coordsys	: coordinate system for calculating the strain rate
+						components. Must be one of:
+				'longitudinal': x axis aligned along a flowline at every point (default)
+				'principal': x axis aligned along maximum principal strain rate
+					at every point
+				'xy': x and y axes same as in polar stereographic projection 
+
+   Return values: 
+
+		'alpha' which is the ratio e_yy/e_xx between components of the strain
+		rate tensor
+
+		'beta' which is the ratio e_xy/e_xx between components of the strain rate
+		tensor
+
+		'theta' which is a combination of alpha and beta arising from the form of
+		the equivalent stress
+
+		'exx' is the strain rate along a coordinate system defined by 'coordsys' 
+
+		'sigxx' is the deviatoric stress along a coordinate system defined by 'coordsys' 
+
+   Usage: 
+		alpha,beta,theta,exx,sigxx=thomasparams(md)
+
+   Example: 
+		alpha,beta,theta,exx,sigxx=thomasparams(md,eq='Thomas',smoothing=2,coordsys='longitudinal')
+	'''
+
+	#unpack kwargs
+	eq=kwargs.pop('eq','Thomas')
+	if 'eq' in kwargs: del kwargs['eq']
+	smoothing=kwargs.pop('smoothing',0)
+	if 'smoothing' in kwargs: del kwargs['smoothing']
+	coordsys=kwargs.pop('coordsys','longitudinal')
+	if 'coordsys' in kwargs: del kwargs['coordsys']
+	assert len(kwargs)==0, 'error, unexpected or misspelled kwargs'
+
+	# some checks
+	if not hasattr(md.results,'strainrate'):
+		raise StandardError('md.results.strainrate not present.  Calculate using md=mechanicalproperties(md,vx,vy)')
+	if not '2d' in md.mesh.__doc__:
+		raise StandardError('only 2d (planview) model supported currently')
+	if any(md.flowequation.element_equation!=2):
+		raise StandardError('Warning: the model has some non-SSA elements.  These will be treated like SSA elements')
+
+	# average element strain rates onto vertices
+	e1=averaging(md,md.results.strainrate.principalvalue1,smoothing)/md.constants.yts # convert to s^-1
+	e2=averaging(md,md.results.strainrate.principalvalue2,smoothing)/md.constants.yts
+	exx=averaging(md,md.results.strainrate.xx,smoothing)/md.constants.yts
+	eyy=averaging(md,md.results.strainrate.yy,smoothing)/md.constants.yts
+	exy=averaging(md,md.results.strainrate.xy,smoothing)/md.constants.yts
+	
+	# checks: any of e1 or e2 equal to zero?
+	pos=npy.nonzero(e1==0)
+	if npy.any(pos==1):
+		print 'WARNING: first principal strain rate equal to zero.  Value set to 1e-13 s^-1'
+		e1[pos]=1.e-13
+	pos=npy.nonzero(e2==0)
+	if npy.any(pos==1):
+		print 'WARNING: second principal strain rate equal to zero.  Value set to 1e-13 s^-1'
+		e2[pos]=1.e-13
+	
+	# rheology
+	n=averaging(md,md.materials.rheology_n,0)
+	B=md.materials.rheology_B
+	
+	if coordsys=='principal':
+		b=npy.zeros((md.mesh.numberofvertices,))
+		ex=e1
+		a=e2/e1
+		pos=npy.nonzero(npy.logical_and(e1<0,e2>0)) # longitudinal compression and lateral tension
+		a[pos]=e1[pos]/e2[pos]
+		ex[pos]=e2[pos]
+		pos2=npy.nonzero(e1<0 & e2<0 & npy.abs(e1)<npy.abs(e2)) # lateral and longitudinal compression
+		a[pos2]=e1[pos2]/e2[pos2]
+		ex[pos2]=e2[pos2]
+		pos3=npy.nonzero(e1>0 & e2>0 & npy.abs(e1)<npy.abs(e2)) # lateral and longitudinal tension
+		a[pos3]=e1[pos3]/e2[pos3]
+		ex[pos3]=e2[pos3]
+		ind=npy.nonzero(e1<0 & e2<0)
+		a[ind]=-a[ind] # where both strain rates are compressive, enforce negative alpha
+		sigxx=(npy.abs(ex)/((1.+a+a**2)**((n-1.)/2.)))**(1./n)*B
+	elif coordsys=='xy':
+		ex=exx
+		a=eyy/exx
+		b=exy/exx
+	elif coordsys=='longitudinal':
+		# using longitudinal strain rates defined by observed velocity vector
+		velangle=npy.arctan(md.initialization.vy/md.initialization.vx)
+		pos=npy.nonzero(md.initialization.vx==0)
+		velangle[pos]=npy.pi/2
+		ex=0.5*(exx+eyy)+0.5*(exx-eyy)*npy.cos(2.*velangle)+exy*npy.sin(2.*velangle)
+		ey=exx+eyy-ex # trace of strain rate tensor is invariant
+		exy=-0.5*(exx-eyy)*npy.sin(2.*velangle)+exy*npy.cos(2.*velangle)
+		a=ey/ex
+		b=exy/ex
+		sigxx=abs(ex)**(1./n-1.)*ex/((1.+a+a**2+b**2)**((n-1.)/(2.*n)))*B
+	else:
+		raise ValueError('argument passed to "coordsys" not valid')
+	
+	# a < -1 in areas of strong lateral compression or longitudinal compression and
+	# theta flips sign at a = -2
+	pos=npy.nonzero(npy.abs((npy.abs(a)-2.))<1.e-3)
+	if len(pos)>0:
+		print 'Warning: ', len(pos), ' vertices have alpha within 1e-3 of -2'
+	a[pos]=-2+1e-3
+
+	if eq=='Weertman1D':
+		theta=1./8
+		a=npy.zeros((md.mesh.numberofvertices,))
+	elif eq=='Weertman2D':
+		theta=1./9
+		a=npy.ones((md.mesh.numberofvertices,1))
+	elif eq=='Thomas':
+		theta=((1.+a+a**2+b**2)**((n-1.)/2.))/(npy.abs(2.+a)**n)
+	else:
+		raise ValueError('argument passed to "eq" not valid')
+
+	alpha=a
+	beta=b
+
+	return alpha,beta,theta,ex
Index: /issm/trunk/src/m/mesh/ComputeHessian.py
===================================================================
--- /issm/trunk/src/m/mesh/ComputeHessian.py	(revision 17805)
+++ /issm/trunk/src/m/mesh/ComputeHessian.py	(revision 17806)
@@ -1,6 +1,6 @@
 import numpy
-from GetNodalFunctionsCoeff import *
-from GetAreas import *
-from MatlabFuncs import *
+from GetNodalFunctionsCoeff import GetNodalFunctionsCoeff
+from GetAreas import GetAreas
+import MatlabFuncs as m
 
 def ComputeHessian(index,x,y,field,type):
@@ -26,5 +26,5 @@
 	if numpy.size(field)!=numberofnodes and numpy.size(field)!=numberofelements:
 		raise TypeError("ComputeHessian error message: the given field size not supported yet")
-	if not strcmpi(type,'node') and not strcmpi(type,'element'):
+	if not m.strcmpi(type,'node') and not m.strcmpi(type,'element'):
 		raise TypeError("ComputeHessian error message: only 'node' or 'element' type supported yet")
 
@@ -38,9 +38,9 @@
 
 	#compute weights that hold the volume of all the element holding the node i
-	weights=sparse(line,numpy.ones((linesize,1)),numpy.tile(areas.reshape(-1,1),(3,1)),numberofnodes,1)
+	weights=m.sparse(line,numpy.ones((linesize,1)),numpy.tile(areas.reshape(-1,1),(3,1)),numberofnodes,1)
 
 	#compute field on nodes if on elements
 	if numpy.size(field,axis=0)==numberofelements:
-		field=sparse(line,numpy.ones((linesize,1)),numpy.tile(areas*field,(3,1)),numberofnodes,1)/weights
+		field=m.sparse(line,numpy.ones((linesize,1)),numpy.tile(areas*field,(3,1)),numberofnodes,1)/weights
 
 	#Compute gradient for each element
@@ -49,6 +49,6 @@
 
 	#Compute gradient for each node (average of the elements around)
-	gradx=sparse(line,numpy.ones((linesize,1)),numpy.tile((areas*grad_elx).reshape(-1,1),(3,1)),numberofnodes,1)
-	grady=sparse(line,numpy.ones((linesize,1)),numpy.tile((areas*grad_ely).reshape(-1,1),(3,1)),numberofnodes,1)
+	gradx=m.sparse(line,numpy.ones((linesize,1)),numpy.tile((areas*grad_elx).reshape(-1,1),(3,1)),numberofnodes,1)
+	grady=m.sparse(line,numpy.ones((linesize,1)),numpy.tile((areas*grad_ely).reshape(-1,1),(3,1)),numberofnodes,1)
 	gradx=gradx/weights
 	grady=grady/weights
@@ -57,9 +57,9 @@
 	hessian=numpy.hstack((numpy.sum(gradx[index-1,0]*alpha,axis=1).reshape(-1,1),numpy.sum(grady[index-1,0]*alpha,axis=1).reshape(-1,1),numpy.sum(grady[index-1,0]*beta,axis=1).reshape(-1,1)))
 
-	if strcmpi(type,'node'):
+	if m.strcmpi(type,'node'):
 		#Compute Hessian on the nodes (average of the elements around)
-		hessian=numpy.hstack((sparse(line,numpy.ones((linesize,1)),numpy.tile((areas*hessian[:,0]).reshape(-1,1),(3,1)),numberofnodes,1)/weights, \
-			sparse(line,numpy.ones((linesize,1)),numpy.tile((areas*hessian[:,1]).reshape(-1,1),(3,1)),numberofnodes,1)/weights, \
-			sparse(line,numpy.ones((linesize,1)),numpy.tile((areas*hessian[:,2]).reshape(-1,1),(3,1)),numberofnodes,1)/weights ))
+		hessian=numpy.hstack((m.sparse(line,numpy.ones((linesize,1)),numpy.tile((areas*hessian[:,0]).reshape(-1,1),(3,1)),numberofnodes,1)/weights, \
+			m.sparse(line,numpy.ones((linesize,1)),numpy.tile((areas*hessian[:,1]).reshape(-1,1),(3,1)),numberofnodes,1)/weights, \
+			m.sparse(line,numpy.ones((linesize,1)),numpy.tile((areas*hessian[:,2]).reshape(-1,1),(3,1)),numberofnodes,1)/weights ))
 
 	return hessian
Index: /issm/trunk/src/m/mesh/ElementsFromEdge.py
===================================================================
--- /issm/trunk/src/m/mesh/ElementsFromEdge.py	(revision 17805)
+++ /issm/trunk/src/m/mesh/ElementsFromEdge.py	(revision 17806)
@@ -1,4 +1,4 @@
 import numpy
-from PythonFuncs import *
+import PythonFuncs as p
 
 def ElementsFromEdge(elements,A,B):
@@ -13,5 +13,5 @@
 
 	edgeelements=numpy.nonzero(\
-		logical_or_n(numpy.logical_and(elements[:,0]==A,elements[:,1]==B), \
+		p.logical_or_n(numpy.logical_and(elements[:,0]==A,elements[:,1]==B), \
 					 numpy.logical_and(elements[:,0]==A,elements[:,2]==B), \
 					 numpy.logical_and(elements[:,1]==A,elements[:,2]==B), \
Index: /issm/trunk/src/m/mesh/argusmesh.m
===================================================================
--- /issm/trunk/src/m/mesh/argusmesh.m	(revision 17805)
+++ /issm/trunk/src/m/mesh/argusmesh.m	(revision 17806)
@@ -77,15 +77,10 @@
 
 %Finally, use model constructor to build a complete model: 
+md.mesh=mesh2d();
 md.mesh.elements=elements;
 md.mesh.x=x;
 md.mesh.y=y;
-md.z=z;
 md.mesh.numberofvertices=size(md.mesh.x,1);
 md.mesh.numberofelements=size(md.mesh.elements,1);
-md.mesh.vertexonbed=ones(md.mesh.numberofvertices,1);
-md.mesh.vertexonsurface=ones(md.mesh.numberofvertices,1);
-md.mesh.elementonbed=ones(md.mesh.numberofelements,1);
-md.mesh.elementonsurface=ones(md.mesh.numberofelements,1);
-md.mesh.dimension=2;
 md=addnote(md,notes);
 
Index: /issm/trunk/src/m/mesh/bamg.m
===================================================================
--- /issm/trunk/src/m/mesh/bamg.m	(revision 17805)
+++ /issm/trunk/src/m/mesh/bamg.m	(revision 17806)
@@ -284,5 +284,5 @@
 %}}}
 % Bamg Mesh parameters {{{
-if (~exist(options,'domain') & md.mesh.numberofvertices~=0 & md.mesh.dimension==2),
+if (~exist(options,'domain') & md.mesh.numberofvertices~=0 & strcmp(elementtype(md.mesh),'Tria')),
 
 	if isstruct(md.private.bamg) & isfield(md.private.bamg,'mesh'),
@@ -325,4 +325,5 @@
 bamg_options.splitcorners=getfieldvalue(options,'splitcorners',1);
 bamg_options.geometricalmetric=getfieldvalue(options,'geometricalmetric',0);
+bamg_options.random=getfieldvalue(options,'rand',true);
 bamg_options.verbose=getfieldvalue(options,'verbose',1);
 %}}}
@@ -332,5 +333,5 @@
 
 if getfieldvalue(options,'vertical',0),
-	md.mesh=mesh2dvertical;
+	md.mesh=mesh2dvertical();
 	md.mesh.x=bamgmesh_out.Vertices(:,1);
 	md.mesh.y=bamgmesh_out.Vertices(:,2);
@@ -349,5 +350,5 @@
 	md.mesh.vertexonboundary=zeros(md.mesh.numberofvertices,1); md.mesh.vertexonboundary(md.mesh.segments(:,1:2))=1;
 else
-	% plug results onto model
+	md.mesh=mesh2d();
 	md.mesh.x=bamgmesh_out.Vertices(:,1);
 	md.mesh.y=bamgmesh_out.Vertices(:,2);
@@ -358,15 +359,11 @@
 
 	%Fill in rest of fields:
-	md.mesh.dimension=2;
 	md.mesh.numberofelements=size(md.mesh.elements,1);
 	md.mesh.numberofvertices=length(md.mesh.x);
 	md.mesh.numberofedges=size(md.mesh.edges,1);
-	md.mesh.z=zeros(md.mesh.numberofvertices,1);
-	md.mesh.vertexonbed=ones(md.mesh.numberofvertices,1);
-	md.mesh.vertexonsurface=ones(md.mesh.numberofvertices,1);
-	md.mesh.elementonbed=ones(md.mesh.numberofelements,1);
-	md.mesh.elementonsurface=ones(md.mesh.numberofelements,1);
 	md.mesh.vertexonboundary=zeros(md.mesh.numberofvertices,1); md.mesh.vertexonboundary(md.mesh.segments(:,1:2))=1;
 end
+
+%Bamg private fields
 md.private.bamg=struct();
 md.private.bamg.mesh=bamgmesh(bamgmesh_out);
@@ -374,5 +371,4 @@
 md.mesh.elementconnectivity=md.private.bamg.mesh.ElementConnectivity;
 md.mesh.elementconnectivity(find(isnan(md.mesh.elementconnectivity)))=0;
-
 
 %Check for orphan
Index: /issm/trunk/src/m/mesh/bamg.py
===================================================================
--- /issm/trunk/src/m/mesh/bamg.py	(revision 17805)
+++ /issm/trunk/src/m/mesh/bamg.py	(revision 17806)
@@ -1,14 +1,15 @@
 import os.path
 import numpy
+from mesh2d import mesh2d
 from collections import OrderedDict
-from pairoptions import *
-from bamggeom import *
-from bamgmesh import *
-from expread import *
-from expwrite import *
-from SegIntersect import *
-from MatlabFuncs import *
-from BamgMesher import *
-from ContourToNodes import *
+from pairoptions import pairoptions
+from bamggeom import bamggeom
+from bamgmesh import bamgmesh
+from expread import expread
+from expwrite import expwrite
+from SegIntersect import SegIntersect
+import MatlabFuncs as m
+from BamgMesher import BamgMesher
+from ContourToNodes import ContourToNodes
 
 def bamg(md,*args):
@@ -245,11 +246,12 @@
 
 			#recover RequiredVertices
-			requiredvertices=float(options.getfieldvalue('RequiredVertices'))    #for some reason, it is of class "single"
+			requiredvertices=options.getfieldvalue('RequiredVertices')    #for some reason, it is of class "single"
 			if numpy.size(requiredvertices,axis=1)==2:
 				requiredvertices=numpy.hstack((requiredvertices,4.*numpy.ones((numpy.size(requiredvertices,axis=0),1))))
-	
+			
+
 			#only keep those inside
-			flags=ContourToNodes(requiredvertices[:,0],domain[0],0)
-			requiredvertices=requiredvertices[numpy.nonzero(flags),:]
+			flags=ContourToNodes(requiredvertices[:,0],requiredvertices[:,1],domainfile,0)[0]
+			requiredvertices=requiredvertices[numpy.nonzero(flags)[0],:]
 
 			#Add all points to bamg_geometry
@@ -270,5 +272,5 @@
 	#}}}
 	# Bamg Mesh parameters {{{
-	if not options.exist('domain') and md.mesh.numberofvertices and md.mesh.dimension==2:
+	if not options.exist('domain') and md.mesh.numberofvertices and m.strcmp(md.mesh.elementtype(),'Tria'):
 
 		if isinstance(md.private.bamg,dict) and 'mesh' in md.private.bamg:
@@ -308,4 +310,5 @@
 	bamg_options['splitcorners']=options.getfieldvalue('splitcorners',1)
 	bamg_options['geometricalmetric']=options.getfieldvalue('geometricalmetric',0)
+	bamg_options['random']=options.getfieldvalue('rand',True)
 	bamg_options['verbose']=options.getfieldvalue('verbose',1)
 	#}}}
@@ -318,4 +321,5 @@
 	md.private.bamg['mesh']=bamgmesh(bamgmesh_out)
 	md.private.bamg['geometry']=bamggeom(bamggeom_out)
+	md.mesh = mesh2d()
 	md.mesh.x=bamgmesh_out['Vertices'][:,0].copy()
 	md.mesh.y=bamgmesh_out['Vertices'][:,1].copy()
@@ -326,13 +330,7 @@
 
 	#Fill in rest of fields:
-	md.mesh.dimension=2
 	md.mesh.numberofelements=numpy.size(md.mesh.elements,axis=0)
 	md.mesh.numberofvertices=numpy.size(md.mesh.x)
 	md.mesh.numberofedges=numpy.size(md.mesh.edges,axis=0)
-	md.mesh.z=numpy.zeros(md.mesh.numberofvertices)
-	md.mesh.vertexonbed=numpy.ones(md.mesh.numberofvertices,bool)
-	md.mesh.vertexonsurface=numpy.ones(md.mesh.numberofvertices,bool)
-	md.mesh.elementonbed=numpy.ones(md.mesh.numberofelements,bool)
-	md.mesh.elementonsurface=numpy.ones(md.mesh.numberofelements,bool)
 	md.mesh.vertexonboundary=numpy.zeros(md.mesh.numberofvertices,bool)
 	md.mesh.vertexonboundary[md.mesh.segments[:,0:2]-1]=True
@@ -372,5 +370,5 @@
 
 			#Skip if the two edges already have a vertex in common
-			if any(ismember(geom.Edges[i,0:2],geom.Edges[j,0:2])):
+			if any(m.ismember(geom.Edges[i,0:2],geom.Edges[j,0:2])):
 				continue
 
@@ -469,5 +467,5 @@
 
 					%update edges
-					posedges=find(ismember(geom.Edges,j));
+					posedges=find(m.ismember(geom.Edges,j));
 					geom.Edges(posedges)=i;
 					posedges=find(geom.Edges>j);
Index: /issm/trunk/src/m/mesh/bamgflowband.m
===================================================================
--- /issm/trunk/src/m/mesh/bamgflowband.m	(revision 17805)
+++ /issm/trunk/src/m/mesh/bamgflowband.m	(revision 17806)
@@ -31,6 +31,6 @@
 
 %Deal with vertices on bed
-md.mesh.vertexonbed=zeros(md.mesh.numberofvertices,1);
-md.mesh.vertexonbed(find(vertexflags(md.mesh,1)))=1;
+md.mesh.vertexonbase=zeros(md.mesh.numberofvertices,1);
+md.mesh.vertexonbase(find(vertexflags(md.mesh,1)))=1;
 md.mesh.vertexonsurface=zeros(md.mesh.numberofvertices,1);
 md.mesh.vertexonsurface(find(vertexflags(md.mesh,3)))=1;
Index: /issm/trunk/src/m/mesh/meshconvert.m
===================================================================
--- /issm/trunk/src/m/mesh/meshconvert.m	(revision 17805)
+++ /issm/trunk/src/m/mesh/meshconvert.m	(revision 17806)
@@ -36,12 +36,6 @@
 
 %Fill in rest of fields:
-md.mesh.dimension        = 2;
 md.mesh.numberofelements = size(md.mesh.elements,1);
 md.mesh.numberofvertices = length(md.mesh.x);
 md.mesh.numberofedges    = size(md.mesh.edges,1);
-md.mesh.z                = zeros(md.mesh.numberofvertices,1);
-md.mesh.vertexonbed      = ones(md.mesh.numberofvertices,1);
-md.mesh.vertexonsurface  = ones(md.mesh.numberofvertices,1);
-md.mesh.elementonbed     = ones(md.mesh.numberofelements,1);
-md.mesh.elementonsurface = ones(md.mesh.numberofelements,1);
 md.mesh.vertexonboundary = zeros(md.mesh.numberofvertices,1); md.mesh.vertexonboundary(md.mesh.segments(:,1:2)) = 1;
Index: /issm/trunk/src/m/mesh/meshconvert.py
===================================================================
--- /issm/trunk/src/m/mesh/meshconvert.py	(revision 17805)
+++ /issm/trunk/src/m/mesh/meshconvert.py	(revision 17806)
@@ -1,7 +1,8 @@
 import numpy
 from collections import OrderedDict
-from BamgConvertMesh import *
-from bamgmesh import *
-from bamggeom import *
+from BamgConvertMesh import BamgConvertMesh 
+from mesh2d   import mesh2d
+from bamgmesh import bamgmesh
+from bamggeom import bamggeom
 
 def meshconvert(md,*args):
@@ -33,4 +34,5 @@
 	md.private.bamg['mesh']     = bamgmesh(bamgmesh_out)
 	md.private.bamg['geometry'] = bamggeom(bamggeom_out)
+	md.mesh                     = mesh2d()
 	md.mesh.x                   = bamgmesh_out['Vertices'][:,0].copy()
 	md.mesh.y                   = bamgmesh_out['Vertices'][:,1].copy()
@@ -41,14 +43,7 @@
 
 	#Fill in rest of fields:
-	md.mesh.dimension          = 2
 	md.mesh.numberofelements   = numpy.size(md.mesh.elements,axis=0)
 	md.mesh.numberofvertices   = numpy.size(md.mesh.x)
 	md.mesh.numberofedges      = numpy.size(md.mesh.edges,axis=0)
-	md.mesh.z                  = numpy.zeros(md.mesh.numberofvertices)
-	md.mesh.vertexonbed        = numpy.ones(md.mesh.numberofvertices,bool)
-	md.mask.vertexonwater      = numpy.zeros(md.mesh.numberofvertices,bool)
-	md.mesh.vertexonsurface    = numpy.ones(md.mesh.numberofvertices,bool)
-	md.mesh.elementonbed       = numpy.ones(md.mesh.numberofelements,bool)
-	md.mesh.elementonsurface   = numpy.ones(md.mesh.numberofelements,bool)
 	md.mesh.vertexonboundary   = numpy.zeros(md.mesh.numberofvertices,bool)
 	md.mesh.vertexonboundary[md.mesh.segments[:,0:2]-1] = True
Index: sm/trunk/src/m/mesh/planet/planetmesher.m
===================================================================
--- /issm/trunk/src/m/mesh/planet/planetmesher.m	(revision 17805)
+++ 	(revision )
@@ -1,35 +1,0 @@
-function md=planetmesher(md,varargin)
-%PLANETMESHER - create planet mesh using several packages
-%
-%   This routine creates a planet mesh using several packages: a custom made 
-%   ISSM mesher (called planetmixedmesh.m, method 'mixed') and the planettrimesh
-%   (method 'tria')
-%   where md is a @planet object, varargin is a list of options
-%
-% Usage: md=planetmesher(md,'method','mixed','radius',6378000,'angleresol',1);
-%        md=planetmesher(md,'method','tria','shape','iso','radius',6378000,'refinement',5);
-%
-%
-
-	%recover options
-	options=pairoptions(varargin{:});
-
-	method=getfieldvalue(options,'method','mixed');
-
-	if strcmpi(method,'mixed'),
-		%recover radius and angleresol: 
-		radius=getfieldvalue(options,'radius',6378000); %earth radius as default
-		angleresol=getfieldvalue(options,'angleresol',10); %10 degree resolution
-
-		%call mixed mesh 
-		md=planetmixedmesh(md,radius,angleresol);
-	else
-		%recover radius, shape and level of refinmenet
-		radius=getfieldvalue(options,'radius',6378000); %earth radius as default
-		refinement=getfieldvalue(options,'refinement',5); %refine 5 times
-		shape=getfieldvalue(options,'shape','ico'); 
-
-		%call triangular mesh
-		md=planettrimesh(md,shape,radius,refinement);
-	end
-end
Index: sm/trunk/src/m/mesh/planet/planetmixedmesh.m
===================================================================
--- /issm/trunk/src/m/mesh/planet/planetmixedmesh.m	(revision 17805)
+++ 	(revision )
@@ -1,97 +1,0 @@
-function md=planetmixedmesh(md,radius,angleresol)
-%PLANETMIXEDMESH: build 2d shell mesh
-%
-% Usage: md=planetmixedshell(md,radius,angleresol)
-%
-
-conv=pi/180;
-
-r=radius;
-theta=(0:angleresol:360)';
-theta=theta*conv;
-phi=(0:angleresol:180)';
-phi=phi(2:end-1)*conv;
-
-nphi=length(phi);
-nthetha=length(theta);
-
-x=zeros(nphi*nthetha,1);
-y=zeros(nphi*nthetha,1);
-z=zeros(nphi*nthetha,1);
-
-for i=1:nphi,
-	phii=phi(i);
-	x((i-1)*nthetha+1:i*nthetha)=r.*cos(theta).*sin(phii);
-	y((i-1)*nthetha+1:i*nthetha)=r.*sin(theta).*sin(phii);
-	z((i-1)*nthetha+1:i*nthetha)=r.*cos(phii);
-end
-
-quads=zeros((nthetha-1)*(nphi-1),4);
-
-%build elements
-for i=1:nphi-1,
-	for j=1:nthetha-1,
-		count=(i-1)*(nthetha-1)+j;
-
-		A=(i-1)*nthetha+j;
-		B=(i-1)*nthetha+j+1;
-		C=(i)*nthetha+j+1;
-		D=(i)*nthetha+j;
-
-		quads(count,:)=[A B C D];
-	end
-end
-
-%now, add polar elements:
-%first north: phi = 0;
-x=[r.*cos(0).*sin(0);x];
-y=[r.*sin(0).*sin(0);y];
-z=[r.*cos(0);z];
-
-%add 1 to quads: 
-quads=quads+1;
-
-%add tria elements:
-trias=zeros(nthetha-1,4);
-
-for i=1:nthetha-1,
-	A=1;
-	B=i+1;
-	C=i+2;
-	trias(i,:)=[A B C NaN];
-end
-
-quads=[trias;quads];
-
-% now add south pole: 
-phii=180*conv;
-x=[x;r.*cos(phii).*sin(phii)];
-y=[y;r.*sin(phii).*sin(phii)];
-z=[z;r.*cos(phii)];
-nods=length(x);
-
-%add tria elements:
-trias=zeros(nthetha-1,4);
-
-start=nods-nthetha;
-for i=1:nthetha-1,
-	A=start+i-1;
-	B=start+i;
-	C=nods;
-	trias(i,:)=[A B C NaN];
-end
-
-quads=[quads;trias];
-
-md.mesh.elements=quads;
-md.mesh.x=x;
-md.mesh.y=y;
-md.mesh.z=z;
-md.mesh.r=sqrt(x.^2+y.^2+z.^2);
-md.mesh.theta=acos(z./md.mesh.r);
-md.mesh.phi=atan2(y,x);
-
-md.mesh.numberofvertices=length(md.mesh.x);
-md.mesh.numberofelements=size(md.mesh.elements,1);
-
-md.mesh.dimension=3;
Index: /issm/trunk/src/m/mesh/planet/planettrimesh.m
===================================================================
--- /issm/trunk/src/m/mesh/planet/planettrimesh.m	(revision 17805)
+++ /issm/trunk/src/m/mesh/planet/planettrimesh.m	(revision 17806)
@@ -6,4 +6,5 @@
 
 results = sphere_tri(shape,refinement,radius);
+md.mesh=meshplanet(); %???
 md.mesh.x=results.vertices(:,1);
 md.mesh.y=results.vertices(:,2);
@@ -17,4 +18,2 @@
 md.mesh.numberofvertices=length(md.mesh.x);
 md.mesh.numberofelements=size(md.mesh.elements,1);
-
-md.mesh.dimension=3;
Index: /issm/trunk/src/m/mesh/rifts/meshaddrifts.m
===================================================================
--- /issm/trunk/src/m/mesh/rifts/meshaddrifts.m	(revision 17805)
+++ /issm/trunk/src/m/mesh/rifts/meshaddrifts.m	(revision 17806)
@@ -80,13 +80,6 @@
 %finish up "a la" mesh.h
 md.mesh.vertexonboundary=zeros(md.mesh.numberofvertices,1); md.mesh.vertexonboundary(md.mesh.segments(:,1:2))=1;
-md.mesh.vertexonbed=ones(md.mesh.numberofvertices,1);
-md.mesh.vertexonsurface=ones(md.mesh.numberofvertices,1);
-md.mesh.elementonbed=ones(md.mesh.numberofelements,1);
-md.mesh.elementonsurface=ones(md.mesh.numberofelements,1);
 
 %Now, build the connectivity tables for this mesh.
 md.mesh.vertexconnectivity=NodeConnectivity(md.mesh.elements,md.mesh.numberofvertices);
 md.mesh.elementconnectivity=ElementConnectivity(md.mesh.elements,md.mesh.vertexconnectivity);
-
-%type of model
-md.mesh.dimension=2;
Index: /issm/trunk/src/m/mesh/rifts/meshprocessoutsiderifts.m
===================================================================
--- /issm/trunk/src/m/mesh/rifts/meshprocessoutsiderifts.m	(revision 17805)
+++ /issm/trunk/src/m/mesh/rifts/meshprocessoutsiderifts.m	(revision 17806)
@@ -82,11 +82,5 @@
 md.mesh.numberofelements=length(md.mesh.elements);
 md.mesh.numberofvertices=length(md.mesh.x);
-md.mesh.z=zeros(md.mesh.numberofvertices,1);
 md.mesh.vertexonboundary=zeros(length(md.mesh.x),1); md.mesh.vertexonboundary(md.mesh.segments(:,1:2))=1;
-md.flowequation.element_equation=3*ones(md.mesh.numberofelements,1);
-md.mesh.vertexonbed=ones(md.mesh.numberofvertices,1);
-md.mesh.vertexonsurface=ones(md.mesh.numberofvertices,1);
-md.mesh.elementonbed=ones(md.mesh.numberofelements,1);
-md.mesh.elementonsurface=ones(md.mesh.numberofelements,1);
 end
 
Index: /issm/trunk/src/m/mesh/rifts/meshprocessoutsiderifts.py
===================================================================
--- /issm/trunk/src/m/mesh/rifts/meshprocessoutsiderifts.py	(revision 17805)
+++ /issm/trunk/src/m/mesh/rifts/meshprocessoutsiderifts.py	(revision 17806)
@@ -1,5 +1,5 @@
 import numpy
-from ElementsFromEdge import *
-from MatlabFuncs import *
+from ElementsFromEdge import ElementsFromEdge
+import MatlabFuncs as m
 
 def meshprocessoutsiderifts(md,domainoutline):
@@ -47,10 +47,10 @@
 				edgeelements=ElementsFromEdge(md.mesh.elements,A,B)
 				#rule out those we already detected
-				already_detected=ismember(edgeelements,elements)
+				already_detected=m.ismember(edgeelements,elements)
 				nextelement=edgeelements(numpy.nonzero(numpy.logical_not(already_detected))[0])
 				#add new detected element to the list of elements we are looking for.
 				elements=numpy.concatenate((elements,nextelement))
 				#new B:
-				B=md.mesh.elements[nextelement-1,numpy.nonzero(numpy.logical_not(ismember(md.mesh.elements[nextelement-1,:],numpy.array([A,B]))))]
+				B=md.mesh.elements[nextelement-1,numpy.nonzero(numpy.logical_not(m.ismember(md.mesh.elements[nextelement-1,:],numpy.array([A,B]))))]
 		
 			#take the list of elements on one side of the rift that connect to the tip, 
@@ -80,13 +80,7 @@
 	md.mesh.numberofelements=numpy.size(md.mesh.elements,axis=0)
 	md.mesh.numberofvertices=numpy.size(md.mesh.x)
-	md.mesh.z=numpy.zeros(md.mesh.numberofvertices)
 	md.mesh.vertexonboundary=numpy.zeros(numpy.size(md.mesh.x),bool)
 	md.mesh.vertexonboundary[md.mesh.segments[:,0:2]-1]=True
 	md.rifts.numrifts=length(md.rifts.riftstruct)
-	md.flowequation.element_equation=3*numpy.ones(md.mesh.numberofelements,int)
-	md.mesh.vertexonbed=numpy.ones(md.mesh.numberofvertices,bool)
-	md.mesh.vertexonsurface=numpy.ones(md.mesh.numberofvertices,bool)
-	md.mesh.elementonbed=numpy.ones(md.mesh.numberofelements,bool)
-	md.mesh.elementonsurface=numpy.ones(md.mesh.numberofelements,bool)
 
 	return md
Index: /issm/trunk/src/m/mesh/rifts/meshprocessrifts.m
===================================================================
--- /issm/trunk/src/m/mesh/rifts/meshprocessrifts.m	(revision 17805)
+++ /issm/trunk/src/m/mesh/rifts/meshprocessrifts.m	(revision 17806)
@@ -34,10 +34,5 @@
 md.mesh.numberofelements=length(md.mesh.elements);
 md.mesh.numberofvertices=length(md.mesh.x);
-md.mesh.z=zeros(md.mesh.numberofvertices,1);
 md.mesh.vertexonboundary=zeros(length(md.mesh.x),1); md.mesh.vertexonboundary(md.mesh.segments(:,1:2))=1;
-md.mesh.vertexonbed=ones(md.mesh.numberofvertices,1);
-md.mesh.vertexonsurface=ones(md.mesh.numberofvertices,1);
-md.mesh.elementonbed=ones(md.mesh.numberofelements,1);
-md.mesh.elementonsurface=ones(md.mesh.numberofelements,1);
 
 %get coordinates of rift tips
Index: /issm/trunk/src/m/mesh/rifts/meshprocessrifts.py
===================================================================
--- /issm/trunk/src/m/mesh/rifts/meshprocessrifts.py	(revision 17805)
+++ /issm/trunk/src/m/mesh/rifts/meshprocessrifts.py	(revision 17806)
@@ -1,7 +1,7 @@
 import numpy
-from TriMeshProcessRifts import *
-from ContourToMesh import *
-from meshprocessoutsiderifts import *
-from GetAreas import *
+from TriMeshProcessRifts import TriMeshProcessRifts
+from ContourToMesh import ContourToMesh
+from meshprocessoutsiderifts import meshprocessoutsiderifts
+from GetAreas import GetAreas
 
 def meshprocessrifts(md,domainoutline):
@@ -35,11 +35,6 @@
 	md.mesh.numberofelements=numpy.size(md.mesh.elements,axis=0)
 	md.mesh.numberofvertices=numpy.size(md.mesh.x)
-	md.mesh.z=numpy.zeros(md.mesh.numberofvertices)
 	md.mesh.vertexonboundary=numpy.zeros(numpy.size(md.mesh.x),bool)
 	md.mesh.vertexonboundary[md.mesh.segments[:,0:2]-1]=True
-	md.mesh.vertexonbed=numpy.ones(md.mesh.numberofvertices,bool)
-	md.mesh.vertexonsurface=numpy.ones(md.mesh.numberofvertices,bool)
-	md.mesh.elementonbed=numpy.ones(md.mesh.numberofelements,bool)
-	md.mesh.elementonsurface=numpy.ones(md.mesh.numberofelements,bool)
 
 	#get coordinates of rift tips
Index: /issm/trunk/src/m/mesh/roundmesh.py
===================================================================
--- /issm/trunk/src/m/mesh/roundmesh.py	(revision 17805)
+++ /issm/trunk/src/m/mesh/roundmesh.py	(revision 17806)
@@ -2,7 +2,6 @@
 import os
 from collections import OrderedDict
-from expwrite import *
-from triangle import *
-#from bamg import *
+from expwrite import expwrite
+from triangle import triangle
 
 def roundmesh(md,radius,resolution):
Index: /issm/trunk/src/m/mesh/squaremesh.m
===================================================================
--- /issm/trunk/src/m/mesh/squaremesh.m	(revision 17805)
+++ /issm/trunk/src/m/mesh/squaremesh.m	(revision 17806)
@@ -55,11 +55,9 @@
 
 %plug coordinates and nodes
+md.mesh=mesh2d();
 md.mesh.x=x;
 md.mesh.y=y;
-md.mesh.z=zeros(nods,1);
 md.mesh.numberofvertices=nods;
 md.mesh.vertexonboundary=zeros(nods,1);md.mesh.vertexonboundary(segments(:,1:2))=1;
-md.mesh.vertexonbed=ones(nods,1);
-md.mesh.vertexonsurface=ones(nods,1);
 
 %plug elements
@@ -67,11 +65,6 @@
 md.mesh.segments=segments;
 md.mesh.numberofelements=nel;
-md.mesh.elementonbed=ones(nel,1);
-md.mesh.elementonsurface=ones(nel,1);
 
 %Now, build the connectivity tables for this mesh.
 md.mesh.vertexconnectivity=NodeConnectivity(md.mesh.elements,md.mesh.numberofvertices);
 md.mesh.elementconnectivity=ElementConnectivity(md.mesh.elements,md.mesh.vertexconnectivity);
-
-%plug other field
-md.mesh.dimension=2;
Index: /issm/trunk/src/m/mesh/squaremesh.py
===================================================================
--- /issm/trunk/src/m/mesh/squaremesh.py	(revision 17805)
+++ /issm/trunk/src/m/mesh/squaremesh.py	(revision 17806)
@@ -1,5 +1,5 @@
 import numpy
-from NodeConnectivity import *
-from ElementConnectivity import *
+from NodeConnectivity import NodeConnectivity
+from ElementConnectivity import ElementConnectivity 
 
 def squaremesh(md,Lx,Ly,nx,ny):
@@ -57,12 +57,10 @@
 
 	#plug coordinates and nodes
+	md.mesh=mesh2d()
 	md.mesh.x=x
 	md.mesh.y=y
-	md.mesh.z=numpy.zeros((nods))
 	md.mesh.numberofvertices=nods
 	md.mesh.vertexonboundary=numpy.zeros((nods),bool)
 	md.mesh.vertexonboundary[segments[:,0:2]-1]=True
-	md.mesh.vertexonbed=numpy.ones((nods),bool)
-	md.mesh.vertexonsurface=numpy.ones((nods),bool)
 
 	#plug elements
@@ -70,6 +68,4 @@
 	md.mesh.segments=segments
 	md.mesh.numberofelements=nel
-	md.mesh.elementonbed=numpy.ones((nel),bool)
-	md.mesh.elementonsurface=numpy.ones((nel),bool)
 
 	#Now, build the connectivity tables for this mesh.
@@ -77,7 +73,3 @@
 	[md.mesh.elementconnectivity]=ElementConnectivity(md.mesh.elements,md.mesh.vertexconnectivity)
 
-	#plug other field
-	md.mesh.dimension=2
-
 	return md
-
Index: /issm/trunk/src/m/mesh/triangle.m
===================================================================
--- /issm/trunk/src/m/mesh/triangle.m	(revision 17805)
+++ /issm/trunk/src/m/mesh/triangle.m	(revision 17806)
@@ -59,4 +59,5 @@
 
 %plug into md
+md.mesh=mesh2d();
 md.mesh.x=x;
 md.mesh.y=y;
@@ -66,17 +67,9 @@
 
 %Fill in rest of fields:
-md.mesh.numberofelements=length(md.mesh.elements);
+md.mesh.numberofelements=size(md.mesh.elements,1);
 md.mesh.numberofvertices=length(md.mesh.x);
-md.mesh.z=zeros(md.mesh.numberofvertices,1);
 md.mesh.vertexonboundary=zeros(md.mesh.numberofvertices,1); md.mesh.vertexonboundary(md.mesh.segments(:,1:2))=1;
-md.mesh.vertexonbed=ones(md.mesh.numberofvertices,1);
-md.mesh.vertexonsurface=ones(md.mesh.numberofvertices,1);
-md.mesh.elementonbed=ones(md.mesh.numberofelements,1);
-md.mesh.elementonsurface=ones(md.mesh.numberofelements,1);
 
 %Now, build the connectivity tables for this mesh.
 md.mesh.vertexconnectivity=NodeConnectivity(md.mesh.elements,md.mesh.numberofvertices);
 md.mesh.elementconnectivity=ElementConnectivity(md.mesh.elements,md.mesh.vertexconnectivity);
-
-%type of model
-md.mesh.dimension=2;
Index: /issm/trunk/src/m/mesh/triangle.py
===================================================================
--- /issm/trunk/src/m/mesh/triangle.py	(revision 17805)
+++ /issm/trunk/src/m/mesh/triangle.py	(revision 17806)
@@ -1,7 +1,8 @@
 import numpy
-from TriMesh import *
-from NodeConnectivity import *
-from ElementConnectivity import *
-from MatlabFuncs import *
+from mesh2d import mesh2d
+from TriMesh import TriMesh
+from NodeConnectivity import NodeConnectivity
+from ElementConnectivity import ElementConnectivity
+import MatlabFuncs as m
 
 def triangle(md,domainname,*args):
@@ -36,5 +37,5 @@
 	if md.mesh.numberofelements:
 		choice = raw_input('This model already has a mesh. Are you sure you want to go ahead? (y/n)')
-		if not strcmp(choice,'y'):
+		if not m.strcmp(choice,'y'):
 			print 'no meshing done ... exiting'
 			return None
@@ -43,4 +44,5 @@
 
 	#Mesh using TriMesh
+	md.mesh=mesh2d()
 	[md.mesh.elements,md.mesh.x,md.mesh.y,md.mesh.segments,md.mesh.segmentmarkers]=TriMesh(domainname,riftname,area)
 	md.mesh.elements=md.mesh.elements.astype(int)
@@ -51,11 +53,6 @@
 	md.mesh.numberofelements = numpy.size(md.mesh.elements,axis=0)
 	md.mesh.numberofvertices = numpy.size(md.mesh.x)
-	md.mesh.z = numpy.zeros(md.mesh.numberofvertices)
 	md.mesh.vertexonboundary = numpy.zeros(md.mesh.numberofvertices,bool)
 	md.mesh.vertexonboundary[md.mesh.segments[:,0:2]-1] = True
-	md.mesh.vertexonbed = numpy.ones(md.mesh.numberofvertices,bool)
-	md.mesh.vertexonsurface = numpy.ones(md.mesh.numberofvertices,bool)
-	md.mesh.elementonbed = numpy.ones(md.mesh.numberofelements,bool)
-	md.mesh.elementonsurface = numpy.ones(md.mesh.numberofelements,bool)
 
 	#Now, build the connectivity tables for this mesh.
@@ -63,7 +60,3 @@
 	[md.mesh.elementconnectivity] = ElementConnectivity(md.mesh.elements, md.mesh.vertexconnectivity)
 
-	#type of model
-	md.mesh.dimension = 2.
-
 	return md
-
Index: /issm/trunk/src/m/mesh/triangle2dvertical.m
===================================================================
--- /issm/trunk/src/m/mesh/triangle2dvertical.m	(revision 17805)
+++ /issm/trunk/src/m/mesh/triangle2dvertical.m	(revision 17806)
@@ -46,5 +46,5 @@
 
 %plug into md
-md.mesh=mesh2dvertical;
+md.mesh=mesh2dvertical();
 md.mesh.x=x;
 md.mesh.z=z;
@@ -54,5 +54,5 @@
 
 %Fill in rest of fields:
-md.mesh.numberofelements=length(md.mesh.elements);
+md.mesh.numberofelements=size(md.mesh.elements,1);
 md.mesh.numberofvertices=length(md.mesh.x);
 md.mesh.vertexonboundary=zeros(md.mesh.numberofvertices,1); md.mesh.vertexonboundary(md.mesh.segments(:,1:2))=1;
Index: /issm/trunk/src/m/miscellaneous/MatlabFuncs.py
===================================================================
--- /issm/trunk/src/m/miscellaneous/MatlabFuncs.py	(revision 17805)
+++ /issm/trunk/src/m/miscellaneous/MatlabFuncs.py	(revision 17806)
@@ -2,5 +2,5 @@
 	import socket
 
-	return socket.gethostname().lower().split('.')[0]
+	return socket.gethostname()
 
 def ispc():
Index: /issm/trunk/src/m/miscellaneous/fielddisplay.py
===================================================================
--- /issm/trunk/src/m/miscellaneous/fielddisplay.py	(revision 17805)
+++ /issm/trunk/src/m/miscellaneous/fielddisplay.py	(revision 17806)
@@ -2,5 +2,5 @@
 import numpy
 from math import isnan
-from MatlabFuncs import *
+import MatlabFuncs as m
 
 def fielddisplay(md,name,comment):
@@ -101,5 +101,5 @@
 				break
 
-	if strcmp(string,sbeg):
+	if m.strcmp(string,sbeg):
 		string="%s%dx1%s" % (sbeg,len(field),send)
 	else:
@@ -117,5 +117,5 @@
 	
 	#take care of characterization
-	if strcmp(characterization,"''") or strcmp(characterization,'""') or strcmpi(characterization,'nan'):
+	if m.strcmp(characterization,"''") or m.strcmp(characterization,'""') or m.strcmpi(characterization,'nan'):
 		characterization="N/A"
 	
Index: /issm/trunk/src/m/miscellaneous/vorticity.m
===================================================================
--- /issm/trunk/src/m/miscellaneous/vorticity.m	(revision 17806)
+++ /issm/trunk/src/m/miscellaneous/vorticity.m	(revision 17806)
@@ -0,0 +1,33 @@
+function rot = vorticity(md,vx,vy)
+%VORTICITY - calculates 2d vorticity
+%
+%   rot = d/dx(vy) - d/dy(vx)
+%
+%   Usage:
+%      rot = vorticity(vx,vy)
+
+
+%load some variables (it is much faster if the variab;es are loaded from md once for all) 
+if ~strcmpi(md.mesh.domaintype(),'3D'),
+	numberofelements=md.mesh.numberofelements;
+	numberofnodes=md.mesh.numberofvertices;
+	index=md.mesh.elements;
+	x=md.mesh.x; y=md.mesh.y;
+else
+	numberofelements=md.mesh.numberofelements2d;
+	numberofnodes=md.mesh.numberofvertices2d;
+	index=md.mesh.elements2d;
+	x=md.mesh.x2d; y=md.mesh.y2d;
+end
+
+%compute nodal functions coefficients N(x,y)=alpha x + beta y + gamma
+[alpha beta]=GetNodalFunctionsCoeff(index,x,y);
+
+summation=[1;1;1];
+dvydx=(vy(index).*alpha)*summation;
+dvxdy=(vx(index).*beta)*summation;
+rot=dvxdy - dvydx;
+
+if strcmpi(meshtype(md.mesh),'3D'),
+	rot=project3d(md,'vector',rot,'type','element');
+end
Index: /issm/trunk/src/m/os/issmdir.py
===================================================================
--- /issm/trunk/src/m/os/issmdir.py	(revision 17805)
+++ /issm/trunk/src/m/os/issmdir.py	(revision 17806)
@@ -1,4 +1,4 @@
 import os
-from MatlabFuncs import *
+import MatlabFuncs as m
 
 def issmdir():
@@ -10,9 +10,9 @@
 	"""
 
-	if not ispc():
+	if not m.ispc():
 		ISSM_DIR =os.environ['ISSM_DIR']
 	else:
 		ISSM_DIR =os.environ['ISSM_DIR_WIN']
-		if strcmpi(ISSM_DIR[-1],'/') or strcmpi(ISSM_DIR[-1],'\\'):
+		if m.strcmpi(ISSM_DIR[-1],'/') or m.strcmpi(ISSM_DIR[-1],'\\'):
 			ISSM_DIR = ISSM_DIR[:-1]    #shave off the last '/'
 
Index: /issm/trunk/src/m/os/issmscpin.py
===================================================================
--- /issm/trunk/src/m/os/issmscpin.py	(revision 17805)
+++ /issm/trunk/src/m/os/issmscpin.py	(revision 17806)
@@ -1,7 +1,7 @@
-import socket
+from socket import gethostname
 import subprocess
 import os
 import shutil
-from MatlabFuncs import *
+import MatlabFuncs as m
 
 def issmscpin(host, login,port,path, packages):
@@ -13,5 +13,5 @@
 
 	#first get hostname
-	hostname=socket.gethostname().lower().split('.')[0]
+	hostname=gethostname()
 
 	#first be sure packages are not in the current directory, this could conflict with pscp on windows. 
@@ -24,5 +24,5 @@
 
 	#if hostname and host are the same, do a simple copy
-	if strcmpi(hostname,host):
+	if m.strcmpi(hostname,host):
 
 		for package in packages:
@@ -34,5 +34,5 @@
 	else:
 
-		if ispc():
+		if m.ispc():
 			#use the putty project pscp.exe: it should be in the path.
 		
Index: /issm/trunk/src/m/os/issmscpout.py
===================================================================
--- /issm/trunk/src/m/os/issmscpout.py	(revision 17805)
+++ /issm/trunk/src/m/os/issmscpout.py	(revision 17806)
@@ -1,6 +1,6 @@
-import socket
+from socket  import gethostname
 import subprocess
 import os
-from MatlabFuncs import *
+import MatlabFuncs as m
 
 def issmscpout(host,path,login,port,packages):
@@ -12,9 +12,9 @@
 
 	#get hostname
-	hostname=socket.gethostname().lower().split('.')[0]
+	hostname=gethostname();
 
 	#if hostname and host are the same, do a simple copy
 
-	if strcmpi(host,hostname):
+	if m.strcmpi(host,hostname):
 		for package in packages:
 			here=os.getcwd()
@@ -27,5 +27,5 @@
 			os.chdir(here)
 	else:
-		if ispc():
+		if m.ispc():
 			#use the putty project pscp.exe: it should be in the path.
 		
Index: /issm/trunk/src/m/os/issmssh.py
===================================================================
--- /issm/trunk/src/m/os/issmssh.py	(revision 17805)
+++ /issm/trunk/src/m/os/issmssh.py	(revision 17806)
@@ -1,6 +1,6 @@
-import socket
+from socket import gethostname
 import subprocess
 import os
-from MatlabFuncs import *
+import MatlabFuncs as m
 
 def issmssh(host,login,port,command):
@@ -13,11 +13,11 @@
 
 	#first get hostname 
-	hostname=socket.gethostname().lower().split('.')[0]
+	hostname=gethostname()
 
 	#if same as host, just run the command. 
-	if strcmpi(host,hostname):
+	if m.strcmpi(host,hostname):
 		subprocess.call(command,shell=True)
 	else:
-		if ispc():
+		if m.ispc():
 			#use the putty project plink.exe: it should be in the path.
 		
Index: /issm/trunk/src/m/os/oshostname.m
===================================================================
--- /issm/trunk/src/m/os/oshostname.m	(revision 17805)
+++ /issm/trunk/src/m/os/oshostname.m	(revision 17806)
@@ -12,9 +12,11 @@
 	end
 else
-	[status,hostname]=system(['hostname -s | sed ''s/-//g''']);
+	%See http://www.mathworks.com/help/matlab/ref/system.html "tips" section
+	%We need to add < /dev/null otherwise what is in the clipboard is added
+	[status,hostname]=system('hostname < /dev/null');
+	hostname = strrep(hostname,'-','');
 	if status, 
 		error('oshostname error message: could not run hostname command on *nix os');
 	end
-
 end
 
Index: /issm/trunk/src/m/parameterization/contourenvelope.m
===================================================================
--- /issm/trunk/src/m/parameterization/contourenvelope.m	(revision 17805)
+++ /issm/trunk/src/m/parameterization/contourenvelope.m	(revision 17806)
@@ -42,5 +42,5 @@
 %get nodes inside profile
 mesh.elementconnectivity=md.mesh.elementconnectivity;
-if md.mesh.dimension==2;
+if dimension(md.mesh)==2,
 	mesh.elements=md.mesh.elements;
 	mesh.x=md.mesh.x;
Index: /issm/trunk/src/m/parameterization/contourenvelope.py
===================================================================
--- /issm/trunk/src/m/parameterization/contourenvelope.py	(revision 17805)
+++ /issm/trunk/src/m/parameterization/contourenvelope.py	(revision 17806)
@@ -2,7 +2,9 @@
 import numpy
 import copy
-from NodeConnectivity import *
-from ElementConnectivity import *
-from mesh import *
+from NodeConnectivity import NodeConnectivity
+from ElementConnectivity import ElementConnectivity
+from mesh2d import mesh2d
+from mesh3dprisms import mesh3dprisms
+import MatlabFuncs as m
 
 def contourenvelope(md,*args):
@@ -44,17 +46,17 @@
 
 	#get nodes inside profile
-	mesh.elementconnectivity=copy.deepcopy(md.mesh.elementconnectivity)
-	if md.mesh.dimension==2:
-		mesh.elements=copy.deepcopy(md.mesh.elements)
-		mesh.x=copy.deepcopy(md.mesh.x)
-		mesh.y=copy.deepcopy(md.mesh.y)
-		mesh.numberofvertices=copy.deepcopy(md.mesh.numberofvertices)
-		mesh.numberofelements=copy.deepcopy(md.mesh.numberofelements)
+	elementconnectivity=copy.deepcopy(md.mesh.elementconnectivity)
+	if md.mesh.dimension()==2:
+		elements=copy.deepcopy(md.mesh.elements)
+		x=copy.deepcopy(md.mesh.x)
+		y=copy.deepcopy(md.mesh.y)
+		numberofvertices=copy.deepcopy(md.mesh.numberofvertices)
+		numberofelements=copy.deepcopy(md.mesh.numberofelements)
 	else:
-		mesh.elements=copy.deepcopy(md.mesh.elements2d)
-		mesh.x=copy.deepcopy(md.mesh.x2d)
-		mesh.y=copy.deepcopy(md.mesh.y2d)
-		mesh.numberofvertices=copy.deepcopy(md.mesh.numberofvertices2d)
-		mesh.numberofelements=copy.deepcopy(md.mesh.numberofelements2d)
+		elements=copy.deepcopy(md.mesh.elements2d)
+		x=copy.deepcopy(md.mesh.x2d)
+		y=copy.deepcopy(md.mesh.y2d)
+		numberofvertices=copy.deepcopy(md.mesh.numberofvertices2d)
+		numberofelements=copy.deepcopy(md.mesh.numberofelements2d)
 
 	if len(args)==1:
@@ -62,27 +64,27 @@
 		if isfile:
 			#get flag list of elements and nodes inside the contour
-			nodein=ContourToMesh(mesh.elements,mesh.x,mesh.y,file,'node',1)
-			elemin=(numpy.sum(nodein(mesh.elements),axis=1)==numpy.size(mesh.elements,axis=1))
+			nodein=ContourToMesh(elements,x,y,file,'node',1)
+			elemin=(numpy.sum(nodein(elements),axis=1)==numpy.size(elements,axis=1))
 			#modify element connectivity
 			elemout=numpy.nonzero(numpy.logical_not(elemin))[0]
-			mesh.elementconnectivity[elemout,:]=0
-			mesh.elementconnectivity[numpy.nonzero(ismember(mesh.elementconnectivity,elemout+1))]=0
+			elementconnectivity[elemout,:]=0
+			elementconnectivity[numpy.nonzero(m.ismember(elementconnectivity,elemout+1))]=0
 		else:
 			#get flag list of elements and nodes inside the contour
-			nodein=numpy.zeros(mesh.numberofvertices)
-			elemin=numpy.zeros(mesh.numberofelements)
+			nodein=numpy.zeros(numberofvertices)
+			elemin=numpy.zeros(numberofelements)
 
 			pos=numpy.nonzero(flags)
 			elemin[pos]=1
-			nodein[mesh.elements[pos,:]-1]=1
+			nodein[elements[pos,:]-1]=1
 
 			#modify element connectivity
 			elemout=numpy.nonzero(numpy.logical_not(elemin))[0]
-			mesh.elementconnectivity[elemout,:]=0
-			mesh.elementconnectivity[numpy.nonzero(ismember(mesh.elementconnectivity,elemout+1))]=0
+			elementconnectivity[elemout,:]=0
+			elementconnectivity[numpy.nonzero(m.ismember(elementconnectivity,elemout+1))]=0
 
 	#Find element on boundary
 	#First: find elements on the boundary of the domain
-	flag=copy.deepcopy(mesh.elementconnectivity)
+	flag=copy.deepcopy(elementconnectivity)
 	if len(args)==1:
 		flag[numpy.nonzero(flag)]=elemin[flag[numpy.nonzero(flag)]]
@@ -96,13 +98,13 @@
 
 	for el1 in pos:
-		els2=mesh.elementconnectivity[el1,numpy.nonzero(mesh.elementconnectivity[el1,:])[0]]-1
+		els2=elementconnectivity[el1,numpy.nonzero(elementconnectivity[el1,:])[0]]-1
 		if numpy.size(els2)>1:
-			flag=numpy.intersect1d(numpy.intersect1d(mesh.elements[els2[0],:],mesh.elements[els2[1],:]),mesh.elements[el1,:])
-			nods1=mesh.elements[el1,:]
+			flag=numpy.intersect1d(numpy.intersect1d(elements[els2[0],:],elements[els2[1],:]),elements[el1,:])
+			nods1=elements[el1,:]
 			nods1=numpy.delete(nods1,numpy.nonzero(nods1==flag))
 			segments[count,:]=[nods1[0],nods1[1],el1+1]
 
-			ord1=numpy.nonzero(nods1[0]==mesh.elements[el1,:])[0][0]
-			ord2=numpy.nonzero(nods1[1]==mesh.elements[el1,:])[0][0]
+			ord1=numpy.nonzero(nods1[0]==elements[el1,:])[0][0]
+			ord2=numpy.nonzero(nods1[1]==elements[el1,:])[0][0]
 
 			#swap segment nodes if necessary
@@ -114,12 +116,12 @@
 			count+=1
 		else:
-			nods1=mesh.elements[el1,:]
-			flag=numpy.setdiff1d(nods1,mesh.elements[els2,:])
+			nods1=elements[el1,:]
+			flag=numpy.setdiff1d(nods1,elements[els2,:])
 			for j in xrange(0,3):
 				nods=numpy.delete(nods1,j)
-				if numpy.any(ismember(flag,nods)):
+				if numpy.any(m.ismember(flag,nods)):
 					segments[count,:]=[nods[0],nods[1],el1+1]
-					ord1=numpy.nonzero(nods[0]==mesh.elements[el1,:])[0][0]
-					ord2=numpy.nonzero(nods[1]==mesh.elements[el1,:])[0][0]
+					ord1=numpy.nonzero(nods[0]==elements[el1,:])[0][0]
+					ord2=numpy.nonzero(nods[1]==elements[el1,:])[0][0]
 					if ( (ord1==0 and ord2==1) or (ord1==1 and ord2==2) or (ord1==2 and ord2==0) ):
 						temp=segments[count,0]
Index: /issm/trunk/src/m/parameterization/setflowequation.m
===================================================================
--- /issm/trunk/src/m/parameterization/setflowequation.m	(revision 17805)
+++ /issm/trunk/src/m/parameterization/setflowequation.m	(revision 17806)
@@ -71,5 +71,5 @@
 
 %Check that no L1L2 or HO or FS for 2d mesh
-if strcmp(meshtype(md.mesh),'2Dhorizontal')
+if strcmp(domaintype(md.mesh),'2Dhorizontal')
 	if any(L1L2flag | FSflag | HOflag)
 		error('FS and HO elements not allowed in 2d mesh, extrude it first')
Index: /issm/trunk/src/m/parameterization/setflowequation.py
===================================================================
--- /issm/trunk/src/m/parameterization/setflowequation.py	(revision 17805)
+++ /issm/trunk/src/m/parameterization/setflowequation.py	(revision 17806)
@@ -1,8 +1,8 @@
 import numpy
-from model import *
-from pairoptions import *
-from MatlabFuncs import *
-from PythonFuncs import *
-from FlagElements import *
+from model import model
+from pairoptions import pairoptions
+import MatlabFuncs as m
+import PythonFuncs as p
+from FlagElements import FlagElements
 
 def setflowequation(md,*args):
@@ -37,5 +37,5 @@
 	#Find_out what kind of coupling to use
 	coupling_method=options.getfieldvalue('coupling','tiling')
-	if not strcmpi(coupling_method,'tiling') and not strcmpi(coupling_method,'penalties'):
+	if not m.strcmpi(coupling_method,'tiling') and not m.strcmpi(coupling_method,'penalties'):
 		raise TypeError("coupling type can only be: tiling or penalties")
 
@@ -49,10 +49,10 @@
 
 	#Flag the elements that have not been flagged as filltype
-	if   strcmpi(filltype,'SIA'):
-		SIAflag[numpy.nonzero(numpy.logical_not(logical_or_n(SSAflag,HOflag)))]=True
-	elif strcmpi(filltype,'SSA'):
-		SSAflag[numpy.nonzero(numpy.logical_not(logical_or_n(SIAflag,HOflag,FSflag)))]=True
-	elif strcmpi(filltype,'HO'):
-		HOflag[numpy.nonzero(numpy.logical_not(logical_or_n(SIAflag,SSAflag,FSflag)))]=True
+	if   m.strcmpi(filltype,'SIA'):
+		SIAflag[numpy.nonzero(numpy.logical_not(p.logical_or_n(SSAflag,HOflag)))]=True
+	elif m.strcmpi(filltype,'SSA'):
+		SSAflag[numpy.nonzero(numpy.logical_not(p.logical_or_n(SIAflag,HOflag,FSflag)))]=True
+	elif m.strcmpi(filltype,'HO'):
+		HOflag[numpy.nonzero(numpy.logical_not(p.logical_or_n(SIAflag,SSAflag,FSflag)))]=True
 
 	#check that each element has at least one flag
@@ -66,9 +66,4 @@
 		SIAflag[numpy.nonzero(numpy.logical_and(SIAflag,HOflag))]=False
 		SSAflag[numpy.nonzero(numpy.logical_and(SSAflag,HOflag))]=False
-
-	#Check that no HO or FS for 2d mesh
-	if md.mesh.dimension==2:
-		if numpy.any(logical_or_n(L1L2flag,FSflag,HOflag)):
-			raise TypeError("FS and HO elements not allowed in 2d mesh, extrude it first")
 
 	#FS can only be used alone for now:
@@ -119,5 +114,5 @@
 	SSAFSflag=numpy.zeros(md.mesh.numberofelements,bool)
 	HOFSflag=numpy.zeros(md.mesh.numberofelements,bool)
-	if   strcmpi(coupling_method,'penalties'):
+	if   m.strcmpi(coupling_method,'penalties'):
 		#Create the border nodes between HO and SSA and extrude them
 		numnodes2d=md.mesh.numberofvertices2d
@@ -132,10 +127,10 @@
 			md.stressbalance.vertex_pairing=penalties
 
-	elif strcmpi(coupling_method,'tiling'):
+	elif m.strcmpi(coupling_method,'tiling'):
 		if   any(SSAflag) and any(HOflag):    #coupling SSA HO
 			#Find node at the border
 			nodeonSSAHO[numpy.nonzero(numpy.logical_and(nodeonSSA,nodeonHO))]=True
 			#SSA elements in contact with this layer become SSAHO elements
-			matrixelements=ismember(md.mesh.elements-1,numpy.nonzero(nodeonSSAHO)[0])
+			matrixelements=m.ismember(md.mesh.elements-1,numpy.nonzero(nodeonSSAHO)[0])
 			commonelements=numpy.sum(matrixelements,axis=1)!=0
 			commonelements[numpy.nonzero(HOflag)]=False    #only one layer: the elements previously in SSA
@@ -169,5 +164,5 @@
 			nodeonHOFS[numpy.nonzero(numpy.logical_and(nodeonHO,nodeonFS))]=True
 			#FS elements in contact with this layer become HOFS elements
-			matrixelements=ismember(md.mesh.elements-1,numpy.nonzero(nodeonHOFS)[0])
+			matrixelements=m.ismember(md.mesh.elements-1,numpy.nonzero(nodeonHOFS)[0])
 			commonelements=numpy.sum(matrixelements,axis=1)!=0
 			commonelements[numpy.nonzero(HOflag)]=False    #only one layer: the elements previously in SSA
@@ -201,5 +196,5 @@
 			nodeonSSAFS[numpy.nonzero(numpy.logical_and(nodeonSSA,nodeonFS))]=True
 			#FS elements in contact with this layer become SSAFS elements
-			matrixelements=ismember(md.mesh.elements-1,numpy.nonzero(nodeonSSAFS)[0])
+			matrixelements=m.ismember(md.mesh.elements-1,numpy.nonzero(nodeonSSAFS)[0])
 			commonelements=numpy.sum(matrixelements,axis=1)!=0
 			commonelements[numpy.nonzero(SSAflag)]=False    #only one layer: the elements previously in SSA
Index: /issm/trunk/src/m/parameterization/setmask.m
===================================================================
--- /issm/trunk/src/m/parameterization/setmask.m	(revision 17805)
+++ /issm/trunk/src/m/parameterization/setmask.m	(revision 17806)
@@ -1,3 +1,3 @@
-function md=setmask(md,floatingicename,groundedicename)
+function md=setmask(md,floatingicename,groundedicename,varargin)
 %SETMASK - establish boundaries between grounded and floating ice.
 %
@@ -15,7 +15,18 @@
 
 %some checks on list of arguments
-if ((nargin~=3) | (nargout~=1)),
+if ((mod(nargin,2)==0) | (nargout~=1)),
 	help mask
 	error('mask error message');
+end
+
+if(nargin>3)
+	if(varargin(1)=='icedomain'),
+		icedomainname=varargin(2);	
+	else
+		error('mask error message: wrong field specified. Only icedomain allowed for now.');
+	end
+	if ~exist(icedomainname),
+        error(['setmask error message: file ' icedomainname ' not found!']);
+	end
 end
 
@@ -42,5 +53,18 @@
 
 %level sets
-md.mask.ice_levelset=ones(md.mesh.numberofvertices,1);
 md.mask.groundedice_levelset=vertexongroundedice;
 md.mask.groundedice_levelset(find(vertexongroundedice==0.))=-1.;
+
+if(nargin>3)
+	if(varargin(1)=='icedomain')
+		md.mask.ice_levelset = 1.*ones(md.mesh.numberofvertices,1);
+		%use contourtomesh to set ice values inside ice domain
+		[vertexinsideicedomain,elementinsideicedomain]=ContourToMesh(elements,x,y,icedomainname,'node',1);
+		pos=find(vertexinsideicedomain==1.);
+		md.mask.ice_levelset(pos) = -1.;
+	end
+else
+	md.mask.ice_levelset = -1.*ones(md.mesh.numberofvertices,1);
+end
+
+
Index: /issm/trunk/src/m/parameterization/setmask.py
===================================================================
--- /issm/trunk/src/m/parameterization/setmask.py	(revision 17805)
+++ /issm/trunk/src/m/parameterization/setmask.py	(revision 17806)
@@ -1,6 +1,10 @@
 import numpy
-from FlagElements import *
+import os
+from model import model
+from FlagElements import FlagElements
+import pairoptions
+from ContourToMesh import ContourToMesh
 
-def setmask(md, floatingicename, groundedicename):
+def setmask(md, floatingicename, groundedicename, *args):
 	"""
 	SETMASK - establish boundaries between grounded and floating ice.
@@ -18,4 +22,13 @@
 	      md=setmask(md,'Iceshelves.exp','Islands.exp');
 	"""
+	#some checks on list of arguments
+	if not isinstance(md,model):
+		raise TypeError("setmask error message")
+
+	if len(args)%2:
+		raise TypeError("odd number of arguments provided in setmask")
+
+	#process options
+	options=pairoptions.pairoptions(*args)
 
 	#Get assigned fields
@@ -42,7 +55,17 @@
 
 	#level sets
-	md.mask.ice_levelset         = numpy.ones(md.mesh.numberofvertices,bool)
 	md.mask.groundedice_levelset = -1.*numpy.ones((md.mesh.numberofvertices,1))
 	md.mask.groundedice_levelset[md.mesh.elements[numpy.nonzero(elementongroundedice),:]-1]=1.
 
+	if(len(args)):
+		md.mask.ice_levelset = 1.*numpy.ones((md.mesh.numberofvertices,1))
+		icedomainfile = options.getfieldvalue('icedomain','none')
+		if not os.path.exists(icedomainfile):
+			raise IOError("setmask error message: ice domain file '%s' not found." % icedomainfile)
+		#use contourtomesh to set ice values inside ice domain
+		[vertexinsideicedomain,elementinsideicedomain]=ContourToMesh(elements,x,y,icedomainfile,'node',1)
+		md.mask.ice_levelset[numpy.nonzero(vertexinsideicedomain)[0]] = -1.
+	else:
+		md.mask.ice_levelset = -1.*numpy.ones((md.mesh.numberofvertices,1))
+
 	return md
Index: /issm/trunk/src/m/partition/AreaAverageOntoPartition.m
===================================================================
--- /issm/trunk/src/m/partition/AreaAverageOntoPartition.m	(revision 17805)
+++ /issm/trunk/src/m/partition/AreaAverageOntoPartition.m	(revision 17806)
@@ -9,5 +9,5 @@
 
 %some checks
-if md.mesh.dimension==3,
+if dimension(md.mesh)==3,
 	if nargin~=3,
 		error('layer should be provided onto which Area Averaging occurs');
@@ -51,5 +51,5 @@
 
 %in 3D, restore 3D model:
-if md.mesh.dimension==3,
+if dimension(md.mesh)==3,
 	md=md3d;
 end
Index: /issm/trunk/src/m/partition/partitioner.m
===================================================================
--- /issm/trunk/src/m/partition/partitioner.m	(revision 17805)
+++ /issm/trunk/src/m/partition/partitioner.m	(revision 17806)
@@ -30,5 +30,5 @@
 recomputeadjacency=getfieldvalue(options,'recomputeadjacency');
 
-if(md.mesh.dimension==3),
+if(dimension(md.mesh)==3),
 	%partitioning essentially happens in 2D. So partition in 2D, then 
 	%extrude the partition vector vertically. 
@@ -69,5 +69,9 @@
 
 	%  partition into nparts
-	part=Chaco(md.qmu.adjacency,weights,[],md.mesh.x, md.mesh.y ,md.mesh.z,method,npart,[])'+1; %index partitions from 1 up. like metis.
+	if isa(md.mesh,'mesh2d'),
+		part=Chaco(md.qmu.adjacency,weights,[],md.mesh.x, md.mesh.y,zeros(md.mesh.numberofvertices,1),method,npart,[])'+1; %index partitions from 1 up. like metis.
+	else
+		part=Chaco(md.qmu.adjacency,weights,[],md.mesh.x, md.mesh.y,md.mesh.z,method,npart,[])'+1; %index partitions from 1 up. like metis.
+	end
 
 elseif strcmpi(package,'scotch'),
@@ -96,5 +100,5 @@
 
 %extrude if we are in 3D:
-if md.mesh.dimension==3,
+if dimension(md.mesh)==3,
 	md3d.qmu.vertex_weight=md.qmu.vertex_weight;
 	md3d.qmu.adjacency=md.qmu.adjacency;
Index: /issm/trunk/src/m/plot/applyoptions.m
===================================================================
--- /issm/trunk/src/m/plot/applyoptions.m	(revision 17805)
+++ /issm/trunk/src/m/plot/applyoptions.m	(revision 17806)
@@ -49,5 +49,5 @@
 
 %view 
-if strcmp(meshtype(md.mesh),'3D') & ~exist(options,'layer'),
+if dimension(md.mesh)==3 & ~exist(options,'layer'),
 	view(getfieldvalue(options,'view',3));
 else
@@ -60,8 +60,16 @@
 	eval(['axis ' getfieldvalue(options,'axis')]);
 else
-	if strcmpi(meshtype(md.mesh),'2Dhorizontal') | exist(options,'layer'),
+	if strcmp(domaintype(md.mesh),'3D'),
+		if ~exist(options,'layer'),
+			axis auto tight
+		else
+			axis tight equal
+		end
+	elseif strcmp(domaintype(md.mesh),'2Dvertical'),
+		axis auto tight
+	elseif strcmp(domaintype(md.mesh),'2Dhorizontal'),
 		axis tight equal;
 	else
-		axis auto tight
+		error('type of domain not supported');
 	end
 end
@@ -429,4 +437,5 @@
 	color=getfieldvalue(options,'cloudcolor','k');
 	set(p,'Color',color);
+	set(p,'MarkerSize',markersize);
 end
 
Index: /issm/trunk/src/m/plot/applyoptions.py
===================================================================
--- /issm/trunk/src/m/plot/applyoptions.py	(revision 17805)
+++ /issm/trunk/src/m/plot/applyoptions.py	(revision 17806)
@@ -1,11 +1,21 @@
+import numpy as npy
+from cmaptools import truncate_colormap
+from plot_contour import plot_contour
+
 try:
 	from matplotlib.ticker import MaxNLocator
+	from mpl_toolkits.axes_grid1 import make_axes_locatable
+	import matplotlib as mpl
 	import pylab as p
+	import matplotlib.pyplot as plt
 except ImportError:
 	print "could not import pylab, matplotlib has not been installed, no plotting capabilities enabled"
 
-def applyoptions(md,data,options):
+def applyoptions(md,data,options,fig,ax):
 	'''
 	APPLYOPTIONS - apply options to current plot
+
+	'plotobj' is the object returned by the specific plot call used to
+	render the data.  This object is used for adding a colorbar.
 
 		Usage:
@@ -19,6 +29,10 @@
 	#	options.addfielddefault('hemisphere',md.mesh.hemisphere)
 
+	# get handle to current figure and axes instance
+	#fig = p.gcf()
+	#ax=p.gca()
+
 	#font {{{
-	fontsize=options.getfieldvalue('fontsize',14)
+	fontsize=options.getfieldvalue('fontsize',8)
 	fontweight=options.getfieldvalue('fontweight','normal')
 	fontfamily=options.getfieldvalue('fontfamily','sans-serif')
@@ -45,5 +59,5 @@
 		titlefont['size']=titlefontsize
 		titlefont['weight']=titlefontweight
-		p.title(title,**titlefont)
+		fig.set_title(title,**titlefont)
 	#}}}
 		
@@ -64,9 +78,9 @@
 
 	if options.exist('xlabel'):
-		p.xlabel(options.getfieldvalue('xlabel'),**labelfont)
+		ax.set_xlabel(options.getfieldvalue('xlabel'),**labelfont)
 	if options.exist('ylabel'):
-		p.ylabel(options.getfieldvalue('ylabel'),**labelfont)
+		ax.set_ylabel(options.getfieldvalue('ylabel'),**labelfont)
 	if options.exist('zlabel'):
-		p.zlabel(options.getfieldvalue('zlabel'),**labelfont)
+		ax.set_zlabel(options.getfieldvalue('zlabel'),**labelfont)
 	#}}}
 
@@ -75,19 +89,19 @@
 		if options.exist('xticklabels'):
 			xticklabels=options.getfieldvalue('xticklabels')
-			p.xticks(options.getfieldvalue('xticks'),xticklabels)
-		else:
-			p.xticks(options.getfieldvalue('xticks'))
+			ax.set_xticks(options.getfieldvalue('xticks'),xticklabels)
+		else:
+			ax.set_xticks(options.getfieldvalue('xticks'))
 	if options.exist('yticks'):
 		if options.exist('yticklabels'):
 			yticklabels=options.getfieldvalue('yticklabels')
-			p.yticks(options.getfieldvalue('yticks'),yticklabels)
-		else:
-			p.yticks(options.getfieldvalue('yticks'))
+			ax.set_yticks(options.getfieldvalue('yticks'),yticklabels)
+		else:
+			ax.set_yticks(options.getfieldvalue('yticks'))
 	if options.exist('zticks'):
 		if options.exist('zticklabels'):
 			zticklabels=options.getfieldvalue('zticklabels')
-			p.zticks(options.getfieldvalue('zticks'),zticklabels)
-		else:
-			p.zticks(options.getfieldvalue('zticks'))
+			ax.set_zticks(options.getfieldvalue('zticks'),zticklabels)
+		else:
+			ax.set_zticks(options.getfieldvalue('zticks'))
 	#}}}
 
@@ -96,22 +110,21 @@
 		xticklabels=options.getfieldvalue('xticklabels')
 		xtickloc=p.xticks()[0]	
-		p.xticks(xtickloc,xticklabels)
+		ax.set_xticks(xtickloc,xticklabels)
 	if options.exist('yticklabels'):
 		yticklabels=options.getfieldvalue('yticklabels')
 		ytickloc=p.yticks()[0]	
-		p.yticks(ytickloc,yticklabels)
+		ax.set_yticks(ytickloc,yticklabels)
 	if options.exist('zticklabels'):
 		zticklabels=options.getfieldvalue('zticklabels')
 		ztickloc=p.zticks()[0]	
-		p.zticks(ztickloc,zticklabels)
+		ax.set_zticks(ztickloc,zticklabels)
 	#}}}
 
 	#ticklabel notation {{{
-	p.gca().ticklabel_format(style='sci',scilimits=(0,0))
+	#ax.ticklabel_format(style='sci',scilimits=(0,0))
 	#}}}
 
 	#ticklabelfontsize {{{
 	if options.exist('ticklabelfontsize'):
-		ax=p.gca()
 		for label in ax.get_xticklabels() + ax.get_yticklabels():
 			label.set_fontsize(options.getfieldvalue('ticklabelfontsize'))
@@ -126,7 +139,7 @@
 	if options.exist('axis'):
 		if options.getfieldvalue('axis',True)=='off':
-			p.gca().ticklabel_format(style='plain')
-			p.setp(p.gca().get_xticklabels(), visible=False)
-			p.setp(p.gca().get_yticklabels(), visible=False)
+			ax.ticklabel_format(style='plain')
+			p.setp(ax.get_xticklabels(), visible=False)
+			p.setp(ax.get_yticklabels(), visible=False)
 	# }}}
 
@@ -135,9 +148,9 @@
 	#xlim, ylim, zlim {{{
 	if options.exist('xlim'):
-		p.xlim(options.getfieldvalue('xlim'))
+		ax.set_xlim(options.getfieldvalue('xlim'))
 	if options.exist('ylim'):
-		p.xlim(options.getfieldvalue('ylim'))
+		ax.set_ylim(options.getfieldvalue('ylim'))
 	if options.exist('zlim'):
-		p.xlim(options.getfieldvalue('zlim'))
+		ax.set_zlim(options.getfieldvalue('zlim'))
 	#}}}
 
@@ -151,8 +164,11 @@
 	if options.exist('clim'):
 		lims=options.getfieldvalue('clim')
-		if len(lims)!=2:
-			print 'WARNING: clim should be passed as a list of length 2'
-		else:
-			p.clim(lims[0],lims[1])
+		assert len(lims)==2, 'error, clim should be passed as a list of length 2'
+	elif options.exist('caxis'):
+		lims=options.getfieldvalue('caxis')
+		assert len(lims)==2, 'error, caxis should be passed as a list of length 2'
+		options.addfielddefault('clim',lims)
+	else:
+		if len(data)>0: lims=[data.min(),data.max()]
 	#}}}
 
@@ -162,8 +178,29 @@
 	if options.exist('grid'):
 		if 'on' in options.getfieldvalue('grid','on'):
-			p.grid()
-	#}}}
-
-	#colormap
+			ax.grid()
+	#}}}
+
+	#colormap {{{
+	# default sequential colormap
+	defaultmap=truncate_colormap(mpl.cm.gnuplot2,0.1,0.9,128)
+	cmap=options.getfieldvalue('colormap',defaultmap)
+	norm = mpl.colors.Normalize(vmin=lims[0], vmax=lims[1])
+	options.addfield('colornorm',norm)
+	cbar_extend=0
+	if options.exist('cmap_set_over'):
+		over=options.getfieldvalue('cmap_set_over','0.5')
+		cmap.set_over(over)
+		cbar_extend+=1
+	if options.exist('cmap_set_under'):
+		under=options.getfieldvalue('cmap_set_under','0.5')
+		cmap.set_under(under)
+		cbar_extend+=2
+	options.addfield('colormap',cmap)
+	#}}}
+
+	#contours {{{
+	if options.exist('contourlevels'):
+		plot_contour(md,data,options,ax)
+	#}}}
 
 	#wrapping
@@ -171,21 +208,27 @@
 	#colorbar {{{
 	if options.getfieldvalue('colorbar',1)==1:
-		if options.exist('clim'):
-			# build custom colorbar (does not yet allow customizing the location)
-			fig = p.gcf()
-			ax = p.gca()
-			divider = make_axes_locatable(ax)
-			cax = divider.new_horizontal("5%", pad=0.05, axes_class=maxes.Axes)
-			fig.add_axes(cax) 
-			cmap = mpl.cm.jet
-			norm = mpl.colors.Normalize(vmin=lims[0], vmax=lims[1])
-			cb = mpl.colorbar.ColorbarBase(cax, cmap=cmap, norm=norm)
-		else:
-			cb=p.colorbar()
+		if cbar_extend==0:
+			extend='neither'
+		elif cbar_extend==1:
+			extend='max'
+		elif cbar_extend==2:
+			extend='min'
+		elif cbar_extend==3:
+			extend='both'
+		cb = mpl.colorbar.ColorbarBase(ax.cax, cmap=cmap, norm=norm, extend=extend)
 		cb.locator=MaxNLocator(nbins=5) # default 5 ticks
-		cb.update_ticks()
+		if options.exist('alpha'):
+			cb.set_alpha(options.getfieldvalue('alpha'))
 		if options.exist('colorbarnumticks'):
 			cb.locator=MaxNLocator(nbins=options.getfieldvalue('colorbarnumticks',5))
-			cb.update_ticks()
+		if options.exist('colorbartickspacing'):
+			locs=npy.arange(lims[0],lims[1]+1,options.getfieldvalue('colorbartickspacing'))
+			cb.set_ticks(locs)
+		if options.exist('colorbarlines'):
+			locs=npy.arange(lims[0],lims[1]+1,options.getfieldvalue('colorbarlines'))
+			cb.add_lines(locs,['k' for i in range(len(locs))],npy.ones_like(locs))
+		if options.exist('colorbartitle'):
+			cb.set_label(options.getfieldvalue('colorbartitle'),fontsize=fontsize)
+		cb.ax.tick_params(labelsize=fontsize)
 	#}}}
 
@@ -202,5 +245,4 @@
 	#streamlines
 
-	#contours
 
 	#axis positions
Index: /issm/trunk/src/m/plot/colormaps/cmaptools.py
===================================================================
--- /issm/trunk/src/m/plot/colormaps/cmaptools.py	(revision 17806)
+++ /issm/trunk/src/m/plot/colormaps/cmaptools.py	(revision 17806)
@@ -0,0 +1,25 @@
+import numpy as npy
+
+try:
+	import matplotlib as mpl
+except ImportError:
+	print 'cannot import matplotlib, no plotting capabilities enabled'
+
+def truncate_colormap(cmap, minval=0.0, maxval=1.0, n=100):
+	'''
+	truncate a colormap within normalized limits [0,1]
+
+	cmap - a matplotlib colormap
+	minval - minimum value, normalized, of cmap to be returned.
+	maxval - maximum value, normalized, of cmap to be returned.
+	n - number of levels to use in constructing the new colormap
+
+	Example:
+		newcmap=truncate_colormap(oldcmap,minval=0.2,maxval=0.8,n=128)
+
+	'''
+
+	new_cmap = mpl.colors.LinearSegmentedColormap.from_list('trunc({n},{a:.2f},{b:.2f})'.format(n=cmap.name,
+		a=minval, b=maxval), cmap(npy.linspace(minval, maxval, n)))
+	
+	return new_cmap
Index: /issm/trunk/src/m/plot/colormaps/getcolormap.m
===================================================================
--- /issm/trunk/src/m/plot/colormaps/getcolormap.m	(revision 17805)
+++ /issm/trunk/src/m/plot/colormaps/getcolormap.m	(revision 17806)
@@ -41,5 +41,5 @@
 elseif strcmpi(map,'Rignot'),
 	alpha=getfieldvalue(options,'alpha',1);
-	map = hsv;
+	map = hsv(128);
 	map = rgb2hsv(map);
 	map(:,2) = max(min( (0.1+map(:,1)).^(1/alpha) ,1),0);
Index: /issm/trunk/src/m/plot/plot_basaldrag.m
===================================================================
--- /issm/trunk/src/m/plot/plot_basaldrag.m	(revision 17805)
+++ /issm/trunk/src/m/plot/plot_basaldrag.m	(revision 17806)
@@ -9,5 +9,5 @@
 
 %check layer
-if md.mesh.dimension==3,
+if dimension(md.mesh)==3,
 	if getfieldvalue(options,'layer',1)~=1;
 		disp('plot_basaldrag warning: basal drag is displayed in the lower layer')
@@ -30,5 +30,5 @@
 
 %compute basal drag
-drag=(max(md.constants.g*(md.materials.rho_ice*md.geometry.thickness+md.materials.rho_water*md.geometry.bed),0)).^r.*(md.friction.coefficient).^2.*ub.^s/1000;
+drag=(max(md.constants.g*(md.materials.rho_ice*md.geometry.thickness+md.materials.rho_water*md.geometry.base),0)).^r.*(md.friction.coefficient).^2.*ub.^s/1000;
 
 %Figure out if this is a Section plot
Index: /issm/trunk/src/m/plot/plot_contour.m
===================================================================
--- /issm/trunk/src/m/plot/plot_contour.m	(revision 17805)
+++ /issm/trunk/src/m/plot/plot_contour.m	(revision 17806)
@@ -230,5 +230,5 @@
 			h=patch('Xdata',[xc;NaN],'Ydata',[yc;NaN],'facecolor','none','edgecolor',color,'linewidth',linewidth);
 			c = horzcat([level, xc'; length(xc), yc']);
-			clabel(c,h,'FontSize',10,'labelspacing',20000,'color',color);
+			%clabel(c,h,'FontSize',10,'labelspacing',20000,'color',color);
 			hold on
 		end
Index: /issm/trunk/src/m/plot/plot_contour.py
===================================================================
--- /issm/trunk/src/m/plot/plot_contour.py	(revision 17806)
+++ /issm/trunk/src/m/plot/plot_contour.py	(revision 17806)
@@ -0,0 +1,38 @@
+from averaging import averaging
+import matplotlib.pyplot as plt
+from processmesh import processmesh
+from processdata import processdata
+
+def plot_contour(md,datain,options,ax):
+	'''
+	plot contours of a given field (called within plotmodel)
+
+	Usage:
+		plot_contour(md,data,options)
+
+	See also: plotmodel
+	'''
+
+	x,y,z,elements,is2d,isplanet=processmesh(md,datain,options)
+	data,datatype=processdata(md,datain,options)
+
+	# process data: must be on nodes
+	if datatype==1: # element data
+		data=averaging(md,data,0)
+	elif datatype==2:
+		pass
+	elif datatype==3: # quiver (vector) data
+		data=npy.sqrt(datain**2)
+	else:
+		raise ValueError('datatype not supported in call to plot_contour')
+
+	# contouronly TODO (cla will also clear an overlay image)
+
+	# retrieve necessary options
+	levels=options.getfieldvalue('contourlevels')
+	colors=options.getfieldvalue('contourcolors')
+	norm=options.getfieldvalue('colornorm')
+	linestyles=options.getfieldvalue('contourlinestyles')
+	linewidths=options.getfieldvalue('contourlinewidths')
+
+	ax.tricontour(x,y,elements,data,levels,colors=colors,norm=norm,linestyles=linestyles,linewidths=linewidths)
Index: /issm/trunk/src/m/plot/plot_edges.m
===================================================================
--- /issm/trunk/src/m/plot/plot_edges.m	(revision 17805)
+++ /issm/trunk/src/m/plot/plot_edges.m	(revision 17806)
@@ -17,5 +17,5 @@
 end
 
-if (md.mesh.dimension==2),
+if dimension(md.mesh)==2,
 	%plot mesh
 	A=elements(:,1); B=elements(:,2); C=elements(:,3); 
Index: /issm/trunk/src/m/plot/plot_elementnumbering.m
===================================================================
--- /issm/trunk/src/m/plot/plot_elementnumbering.m	(revision 17805)
+++ /issm/trunk/src/m/plot/plot_elementnumbering.m	(revision 17806)
@@ -39,10 +39,10 @@
 	%highlight
 	pos=getfieldvalue(options,'highlight',[]);
-	A=elements(pos,1); B=elements(pos,2); C=elements(pos,3);
-	patch( 'Faces', [A B C],  'Vertices', [x y z],'FaceVertexCData', [0.9 0.5 0.5],'FaceColor','none','EdgeColor','black');
-	patch( 'Faces', [D E F],  'Vertices', [x y z],'FaceVertexCData', [0.9 0.5 0.5],'FaceColor','none','EdgeColor','black');
-	patch( 'Faces', [A B E D],'Vertices', [x y z],'FaceVertexCData', [0.9 0.5 0.5],'FaceColor','none','EdgeColor','black');
-	patch( 'Faces', [B E F C],'Vertices', [x y z],'FaceVertexCData', [0.9 0.5 0.5],'FaceColor','none','EdgeColor','black');
-	patch( 'Faces', [C A D F],'Vertices', [x y z],'FaceVertexCData', [0.9 0.5 0.5],'FaceColor','none','EdgeColor','black');
+	A=elements(pos,1); B=elements(pos,2); C=elements(pos,3); D=elements(pos,4); E=elements(pos,5); F=elements(pos,6);
+	patch( 'Faces', [A B C],  'Vertices', [x y z],'FaceVertexCData', [0.9 0.5 0.5],'FaceColor','flat','EdgeColor','black');
+	patch( 'Faces', [D E F],  'Vertices', [x y z],'FaceVertexCData', [0.9 0.5 0.5],'FaceColor','flat','EdgeColor','black');
+	patch( 'Faces', [A B E D],'Vertices', [x y z],'FaceVertexCData', [0.9 0.5 0.5],'FaceColor','flat','EdgeColor','black');
+	patch( 'Faces', [B E F C],'Vertices', [x y z],'FaceVertexCData', [0.9 0.5 0.5],'FaceColor','flat','EdgeColor','black');
+	patch( 'Faces', [C A D F],'Vertices', [x y z],'FaceVertexCData', [0.9 0.5 0.5],'FaceColor','flat','EdgeColor','black');
 
 	%numbering
Index: /issm/trunk/src/m/plot/plot_highlightelements.m
===================================================================
--- /issm/trunk/src/m/plot/plot_highlightelements.m	(revision 17805)
+++ /issm/trunk/src/m/plot/plot_highlightelements.m	(revision 17806)
@@ -15,4 +15,5 @@
 
 %plot
+pos=getfieldvalue(options,'highlight',[]);
 if is2d
 	%plot mesh 
@@ -25,20 +26,35 @@
 	patch( 'Faces', [A B C], 'Vertices', [x y z],'FaceVertexCData', [0.9 0.5 0.5],'FaceColor','flat','EdgeColor','black');
 else
-	%plot mesh 
-	A=elements(:,1); B=elements(:,2); C=elements(:,3); D=elements(:,4); E=elements(:,5); F=elements(:,6);
-	patch( 'Faces', [A B C],  'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
-	patch( 'Faces', [D E F],  'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
-	patch( 'Faces', [A B E D],'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
-	patch( 'Faces', [B E F C],'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
-	patch( 'Faces', [C A D F],'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+	if size(elements,2)==6, %prisms
+		%plot mesh 
+		A=elements(:,1); B=elements(:,2); C=elements(:,3); D=elements(:,4); E=elements(:,5); F=elements(:,6);
+		patch( 'Faces', [A B C],  'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+		patch( 'Faces', [D E F],  'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+		patch( 'Faces', [A B E D],'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+		patch( 'Faces', [B E F C],'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+		patch( 'Faces', [C A D F],'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
 
-	%Highlight
-	pos=getfieldvalue(options,'highlight',[]);
-	A=elements(pos,1); B=elements(pos,2); C=elements(pos,3); D=elements(pos,4); E=elements(pos,5); F=elements(pos,6);
-	patch( 'Faces', [A B C],  'Vertices', [x y z],'FaceVertexCData', [0.9 0.5 0.5],'FaceColor','flat','EdgeColor','black');
-	patch( 'Faces', [D E F],  'Vertices', [x y z],'FaceVertexCData', [0.9 0.5 0.5],'FaceColor','flat','EdgeColor','black');
-	patch( 'Faces', [A B E D],'Vertices', [x y z],'FaceVertexCData', [0.9 0.5 0.5],'FaceColor','flat','EdgeColor','black');
-	patch( 'Faces', [B E F C],'Vertices', [x y z],'FaceVertexCData', [0.9 0.5 0.5],'FaceColor','flat','EdgeColor','black');
-	patch( 'Faces', [C A D F],'Vertices', [x y z],'FaceVertexCData', [0.9 0.5 0.5],'FaceColor','flat','EdgeColor','black');
+		%Highlight
+		A=elements(pos,1); B=elements(pos,2); C=elements(pos,3); D=elements(pos,4); E=elements(pos,5); F=elements(pos,6);
+		patch( 'Faces', [A B C],  'Vertices', [x y z],'FaceVertexCData', [0.9 0.5 0.5],'FaceColor','flat','EdgeColor','black');
+		patch( 'Faces', [D E F],  'Vertices', [x y z],'FaceVertexCData', [0.9 0.5 0.5],'FaceColor','flat','EdgeColor','black');
+		patch( 'Faces', [A B E D],'Vertices', [x y z],'FaceVertexCData', [0.9 0.5 0.5],'FaceColor','flat','EdgeColor','black');
+		patch( 'Faces', [B E F C],'Vertices', [x y z],'FaceVertexCData', [0.9 0.5 0.5],'FaceColor','flat','EdgeColor','black');
+		patch( 'Faces', [C A D F],'Vertices', [x y z],'FaceVertexCData', [0.9 0.5 0.5],'FaceColor','flat','EdgeColor','black');
+	elseif size(elements,2)==4, %tetras
+		A=elements(:,1); B=elements(:,2); C=elements(:,3); D=elements(:,4);
+		patch( 'Faces',[A B C],'Vertices', [x y z],'FaceVertexCData',zeros(size(x)),'FaceColor','none','EdgeColor','black');
+		patch( 'Faces',[A B D],'Vertices', [x y z],'FaceVertexCData',zeros(size(x)),'FaceColor','none','EdgeColor','black');
+		patch( 'Faces',[B C D],'Vertices', [x y z],'FaceVertexCData',zeros(size(x)),'FaceColor','none','EdgeColor','black');
+		patch( 'Faces',[C A D],'Vertices', [x y z],'FaceVertexCData',zeros(size(x)),'FaceColor','none','EdgeColor','black');
+		%Highlight
+		A=elements(pos,1); B=elements(pos,2); C=elements(pos,3); D=elements(pos,4);
+		patch( 'Faces',[A B C],'Vertices', [x y z],'FaceVertexCData',[0.9 0.5 0.5],'FaceColor','flat','EdgeColor','black');
+		patch( 'Faces',[A B D],'Vertices', [x y z],'FaceVertexCData',[0.9 0.5 0.5],'FaceColor','flat','EdgeColor','black');
+		patch( 'Faces',[B C D],'Vertices', [x y z],'FaceVertexCData',[0.9 0.5 0.5],'FaceColor','flat','EdgeColor','black');
+		patch( 'Faces',[C A D],'Vertices', [x y z],'FaceVertexCData',[0.9 0.5 0.5],'FaceColor','flat','EdgeColor','black');
+	else
+		error('Not supported');
+	end
 end
 
Index: /issm/trunk/src/m/plot/plot_icefront.m
===================================================================
--- /issm/trunk/src/m/plot/plot_icefront.m	(revision 17805)
+++ /issm/trunk/src/m/plot/plot_icefront.m	(revision 17806)
@@ -12,6 +12,6 @@
 %process mesh and data
 [x y z elements is2d isplanet]=processmesh(md,[],options);
-ice=(md.mask.ice_levelset>0);
-noice=(md.mask.ice_levelset<=0);
+ice=(md.mask.ice_levelset<0);
+noice=(md.mask.ice_levelset>=0);
 zeroice=(md.mask.ice_levelset==0);
 elementice=sum(ice(md.mesh.elements),2);
@@ -19,5 +19,5 @@
 elementzeroice=sum(zeroice(md.mesh.elements),2);
 
-if (md.mesh.dimension==2),
+if dimension(md.mesh)==2,
 	icefront=(elementice & elementnoice) & ~(elementice==2 & elementzeroice);
 
Index: /issm/trunk/src/m/plot/plot_manager.m
===================================================================
--- /issm/trunk/src/m/plot/plot_manager.m	(revision 17805)
+++ /issm/trunk/src/m/plot/plot_manager.m	(revision 17806)
@@ -112,4 +112,7 @@
 			plot_sarpwr(md,options,subplotwidth,i)
 			return
+		case 'time_dependant' ,
+			plot_vstime(md,options,nlines,ncols,i)
+			return
 		case 'icefront'
 			plot_icefront(md,options,subplotwidth,i,data)
Index: /issm/trunk/src/m/plot/plot_manager.py
===================================================================
--- /issm/trunk/src/m/plot/plot_manager.py	(revision 17805)
+++ /issm/trunk/src/m/plot/plot_manager.py	(revision 17806)
@@ -1,9 +1,8 @@
-
 try:
 	import pylab as p
+	import matplotlib.pyplot as plt
 except ImportError:
 	print "could not import pylab, matplotlib has not been installed, no plotting capabilities enabled"
 
-from pairoptions import *
 from checkplotoptions import checkplotoptions
 from plot_mesh import plot_mesh
@@ -12,21 +11,43 @@
 from plot_unit import plot_unit
 from applyoptions import applyoptions
+from plot_overlay import plot_overlay
 
-def plot_manager(md,options,subplotwidth,nlines,ncols,i):
+def plot_manager(md,options,fig,ax):
 	'''
 	PLOT_MANAGER - distribute the plots called by plotmodel
 
-		Usage:
-			plot_manager(md,options,subplotwidth,i);
+	'fig' is a handle to the figure instance created by plotmodel.
 
-		See also: PLOTMODEL, PLOT_UNIT
+	'ax' is a handle to the axes instance created by plotmodel.  This is
+	currently generated using matplotlib's AxesGrid toolki.
+
+	Usage:
+		plot_manager(md,options,fig,ax);
+
+	See also: PLOTMODEL, PLOT_UNIT
 	'''
 
 	#parse options and get a structure of options
 	options=checkplotoptions(md,options)
-	#print 'options:', options
 
 	#get data to be plotted
 	data=options.getfieldvalue('data');
+
+	#initialize plot handle variable
+	#handle=None
+
+	# initialize subplot
+	#p.subplot(nrows,ncols,i,aspect='equal')
+
+	##basemap plot
+	#if options.exist('basemap'):
+	#	plot_basemap(md,data,options,nrows,ncols,i)
+
+	#overlay plot
+	if options.exist('overlay'):
+		plot_overlay(md,data,options,ax)
+		options.addfielddefault('alpha',0.5)
+		options.addfielddefault('xlim',[min(md.mesh.x),max(md.mesh.x)])
+		options.addfielddefault('ylim',[min(md.mesh.y),max(md.mesh.y)])
 
 	#figure out if this is a special plot
@@ -35,5 +56,8 @@
 		# convert string to lower case for a case-insensitive comparison
 		if data.lower()=='mesh': 
-			plot_mesh(md,options,nlines,ncols,i)
+			plot_mesh(md,options,ax)
+			return
+		elif data.lower()=='none':
+			print 'no data provided to plot (TODO: write plot_none.py)'
 			return
 		else:
@@ -43,6 +67,4 @@
 	#else:
 		#print "'data' not a string, plotting model properties yet to be implemented..."
-
-	#Overlay plot
 
 	#Gridded plot
@@ -57,11 +79,12 @@
 
 	#standard plot
-	p.subplot(nlines,ncols,i,aspect='equal')
+	#if not handle:
+	#	p.subplot(nrows,ncols,i,aspect='equal')
 
 	#plot unit
-	plot_unit(x,y,z,elements,data2,is2d,isplanet,datatype,options)
+	plot_unit(x,y,z,elements,data2,is2d,isplanet,datatype,options,ax)
 
 	#apply all options
-	applyoptions(md,data2,options)
+	applyoptions(md,data2,options,fig,ax)
 	
 	#ground overlay on kml plot_unit
Index: /issm/trunk/src/m/plot/plot_mesh.m
===================================================================
--- /issm/trunk/src/m/plot/plot_mesh.m	(revision 17805)
+++ /issm/trunk/src/m/plot/plot_mesh.m	(revision 17806)
@@ -22,5 +22,5 @@
 	patch( 'Faces', [A B C], 'Vertices', [x y z],'FaceVertexCData',zeros(size(x)),'FaceColor','none','EdgeColor',edgecolor,'linewidth',linewidth);
 else
-	if ~isplanet,
+	if size(elements,2)==6, %prisms
 		A=elements(:,1); B=elements(:,2); C=elements(:,3); D=elements(:,4); E=elements(:,5); F=elements(:,6);
 		patch( 'Faces', [A B C],  'Vertices', [x y z],'FaceVertexCData',zeros(size(x)),'FaceColor','none','EdgeColor',edgecolor,'linewidth',linewidth);
@@ -29,5 +29,11 @@
 		patch( 'Faces', [B E F C],'Vertices', [x y z],'FaceVertexCData',zeros(size(x)),'FaceColor','none','EdgeColor',edgecolor,'linewidth',linewidth);
 		patch( 'Faces', [C A D F],'Vertices', [x y z],'FaceVertexCData',zeros(size(x)),'FaceColor','none','EdgeColor',edgecolor,'linewidth',linewidth);
-	else
+	elseif size(elements,2)==4, %tetras
+		A=elements(:,1); B=elements(:,2); C=elements(:,3); D=elements(:,4);
+		patch( 'Faces',[A B C],'Vertices', [x y z],'FaceVertexCData',zeros(size(x)),'FaceColor','none','EdgeColor',edgecolor,'linewidth',linewidth);
+		patch( 'Faces',[A B D],'Vertices', [x y z],'FaceVertexCData',zeros(size(x)),'FaceColor','none','EdgeColor',edgecolor,'linewidth',linewidth);
+		patch( 'Faces',[B C D],'Vertices', [x y z],'FaceVertexCData',zeros(size(x)),'FaceColor','none','EdgeColor',edgecolor,'linewidth',linewidth);
+		patch( 'Faces',[C A D],'Vertices', [x y z],'FaceVertexCData',zeros(size(x)),'FaceColor','none','EdgeColor',edgecolor,'linewidth',linewidth);
+	else %triangles (planet)
 		A=elements(:,1); B=elements(:,2); C=elements(:,3); 
 		if (size(elements,2)==4), D=elements(:,4); else D=C; end
Index: /issm/trunk/src/m/plot/plot_mesh.py
===================================================================
--- /issm/trunk/src/m/plot/plot_mesh.py	(revision 17805)
+++ /issm/trunk/src/m/plot/plot_mesh.py	(revision 17806)
@@ -1,3 +1,2 @@
-
 try:
 	import pylab as p
Index: /issm/trunk/src/m/plot/plot_overlay.m
===================================================================
--- /issm/trunk/src/m/plot/plot_overlay.m	(revision 17805)
+++ /issm/trunk/src/m/plot/plot_overlay.m	(revision 17806)
@@ -43,4 +43,8 @@
 radar = (md.radaroverlay.pwr).^(contrast);
 radar = radar./max(radar(:));
+if size(radar,3)>1,
+	disp('WARNING: color image converted to greyscale intensity image');
+	radar=sum(radar,3)/3;
+end
 %radar(find(radar==0))=1; %Change background from black to white
 
Index: /issm/trunk/src/m/plot/plot_overlay.py
===================================================================
--- /issm/trunk/src/m/plot/plot_overlay.py	(revision 17806)
+++ /issm/trunk/src/m/plot/plot_overlay.py	(revision 17806)
@@ -0,0 +1,103 @@
+import numpy as npy
+from processmesh import processmesh
+from processdata import processdata
+from osgeo import gdal
+import matplotlib.pyplot as plt
+import matplotlib as mpl
+import os
+
+def plot_overlay(md,data,options,ax):
+	'''
+	Function for plotting a georeferenced image.  This function is called
+	from within the plotmodel code.
+	'''
+
+	x,y,z,elements,is2d,isplanet=processmesh(md,[],options)
+
+	if data=='none' or data==None:
+		imageonly=1
+		data=npy.float('nan')*npy.ones((md.mesh.numberofvertices,))
+		datatype=1
+	else:
+		imageonly=0
+		data,datatype=processdata(md,data,options)
+
+	if not is2d:
+		raise StandardError('overlay plot not supported for 3D meshes, project on a 2D layer first')
+	if datatype==3:
+		raise StandardError('overlay not yet supported for quiver plots')	
+
+	if not options.exist('geotiff_name'):
+		raise StandardError('overlay error: provide geotiff_name with path to geotiff file')
+	geotiff=options.getfieldvalue('geotiff_name')
+
+	xlim=options.getfieldvalue('xlim',[min(md.mesh.x),max(md.mesh.x)])
+	ylim=options.getfieldvalue('ylim',[min(md.mesh.y),max(md.mesh.y)])
+
+	gtif=gdal.Open(geotiff)
+	trans=gtif.GetGeoTransform()
+	xmin=trans[0]
+	xmax=trans[0]+gtif.RasterXSize*trans[1]
+	ymin=trans[3]+gtif.RasterYSize*trans[5]
+	ymax=trans[3]
+	
+	# allow supplied geotiff to have limits smaller than basemap or model limits
+	x0=max(min(xlim),xmin)
+	x1=min(max(xlim),xmax)
+	y0=max(min(ylim),ymin)
+	y1=min(max(ylim),ymax)
+	inputname='temp.tif'
+	os.system('gdal_translate -quiet -projwin ' + str(x0) + ' ' + str(y1) + ' ' + str(x1) + ' ' + str(y0) + ' ' + geotiff + ' ' + inputname)
+	
+	gtif=gdal.Open(inputname)
+	arr=gtif.ReadAsArray()
+	#os.system('rm -rf ./temp.tif')
+	
+	if gtif.RasterCount>=3:  # RGB array
+		r=gtif.GetRasterBand(1).ReadAsArray()
+		g=gtif.GetRasterBand(2).ReadAsArray()
+		b=gtif.GetRasterBand(3).ReadAsArray()
+		arr=0.299*r+0.587*g+0.114*b
+
+	# normalize array
+	arr=arr/npy.float(npy.max(arr.ravel()))
+
+	if options.getfieldvalue('overlayhist',0)==1:
+		ax=plt.gca()
+		num=2
+		while True:
+			if not plt.fignum_exists(num):
+				break
+			else:
+				num+=1
+		plt.figure(num)
+		plt.hist(arr.flatten(),bins=256,range=(0.,1.))
+		plt.title('histogram of overlay image, use for setting overlaylims')
+		plt.sca(ax) # return to original axes/figure
+		
+	# get parameters from cropped geotiff
+	trans=gtif.GetGeoTransform()
+	xmin=trans[0]
+	xmax=trans[0]+gtif.RasterXSize*trans[1]
+	ymin=trans[3]+gtif.RasterYSize*trans[5]
+	ymax=trans[3]
+	dx=trans[1]
+	dy=trans[5]	
+	
+	xarr=npy.arange(xmin,xmax,dx)
+	yarr=npy.arange(ymin,ymax,-dy) # -dy since origin='upper' (not sure how robust this is)
+	xg,yg=npy.meshgrid(xarr,yarr)
+	if options.exist('basemap'):
+		# TODO get handle to or create basemap instance 
+		# create coordinate grid in map projection units (for plotting)
+		lats,lons=xy2ll(xg,yg,-1,0,71)
+		xgmap,ygmap=m(lons,lats) # map projection units returned by basemap instance
+	else:
+		xgmap=xg
+		ygmap=yg
+	
+	overlaylims=options.getfieldvalue('overlaylims',[min(arr.ravel()),max(arr.ravel())])
+
+	norm=mpl.colors.Normalize(vmin=overlaylims[0],vmax=overlaylims[1])
+
+	ax.pcolormesh(xgmap, ygmap, npy.flipud(arr), cmap=mpl.cm.Greys, norm=norm)
Index: /issm/trunk/src/m/plot/plot_penalties.m
===================================================================
--- /issm/trunk/src/m/plot/plot_penalties.m	(revision 17805)
+++ /issm/trunk/src/m/plot/plot_penalties.m	(revision 17806)
@@ -21,5 +21,5 @@
 end
 
-if ~md.mesh.dimension==3,
+if dimension(md.mesh)~=3,
 	error('no penalties to plot for ''2d'' model');
 elseif isempty(md.penalties),
Index: /issm/trunk/src/m/plot/plot_profile.m
===================================================================
--- /issm/trunk/src/m/plot/plot_profile.m	(revision 17805)
+++ /issm/trunk/src/m/plot/plot_profile.m	(revision 17806)
@@ -31,5 +31,5 @@
 	[datai datatype]=processdata(md,data(:,i),options);
 
-	%resolution
+	%resolution[z,data_interp]=ProfileValues(md,datai,xprof,yprof,resolution);
 	if exist(options,'resolution'),
 		resolution=getfieldvalue(options,'resolution');
Index: /issm/trunk/src/m/plot/plot_qmu_mass_flux_segments.m
===================================================================
--- /issm/trunk/src/m/plot/plot_qmu_mass_flux_segments.m	(revision 17805)
+++ /issm/trunk/src/m/plot/plot_qmu_mass_flux_segments.m	(revision 17806)
@@ -13,5 +13,5 @@
 allsegments=md.qmu.mass_flux_segments;
 
-if (md.mesh.dimension==2),
+if dimension(md.mesh)==2,
 
 	%recover segments
Index: /issm/trunk/src/m/plot/plot_referential.m
===================================================================
--- /issm/trunk/src/m/plot/plot_referential.m	(revision 17805)
+++ /issm/trunk/src/m/plot/plot_referential.m	(revision 17806)
@@ -28,5 +28,5 @@
 Yhat=cross(Zhat,Xhat);
 
-if (md.mesh.dimension==2),
+if dimension(md.mesh)==2,
 
 	%plot mesh
Index: /issm/trunk/src/m/plot/plot_section.m
===================================================================
--- /issm/trunk/src/m/plot/plot_section.m	(revision 17805)
+++ /issm/trunk/src/m/plot/plot_section.m	(revision 17806)
@@ -32,5 +32,6 @@
 md3d=md;
 if exist(options,'layer')
-	md.mesh.x=md.mesh.x2d; md.mesh.y=md.mesh.y2d; md.mesh.elements=md.mesh.elements2d; md.mesh.dimension=2;
+	md.mesh.x=md.mesh.x2d; md.mesh.y=md.mesh.y2d; md.mesh.elements=md.mesh.elements2d;
+	md.mesh=mesh2d(md.mesh);
 end
 
@@ -58,4 +59,10 @@
 		%Compute section value
 		[elements,x,y,z,s,data_s]=SectionValues(md,datai,profile,resolution);
+
+		if getfieldvalue(options,'sectionmean',0)==1,
+			disp(['Mean value of data along section: ' num2str(mean(data_s))])
+			disp(['Median value of data along section: ' num2str(median(data_s))])
+			disp(['Standard deviation of data along section: ' num2str(std(data_s))])
+		end
 
 		%units
@@ -189,5 +196,4 @@
 				patch( 'Faces', [A B C D], 'Vertices', [x y z],'FaceVertexCData',data_s,'FaceColor','interp','EdgeColor','none');
 				view(3)
-
 			end
 		end
@@ -197,13 +203,14 @@
 %apply options
 options=addfielddefault(options,'title','Section value');
-if (md.mesh.dimension==2)
+if dimension(md.mesh)==2
 	options=addfielddefault(options,'colorbar',0);
 end
-if ((md.mesh.dimension==2) | getfieldvalue(options,'view')==2 )
+if ((dimension(md.mesh)==2) | getfieldvalue(options,'view',2)==2 )
 	options=addfielddefault(options,'xlabel','Curvilinear coordinate');
 	options=addfielddefault(options,'axis','auto');
 end
-if (md.mesh.dimension==3 & getfieldvalue(options,'view')==2 )
+if (dimension(md.mesh)==3 & getfieldvalue(options,'view',2)==2 )
 	options=addfielddefault(options,'ylabel','z');
-end
-applyoptions(md,[],options);
+	options=addfielddefault(options,'axis','auto');
+end
+applyoptions(md3d,[],options);
Index: /issm/trunk/src/m/plot/plot_segments.m
===================================================================
--- /issm/trunk/src/m/plot/plot_segments.m	(revision 17805)
+++ /issm/trunk/src/m/plot/plot_segments.m	(revision 17806)
@@ -14,5 +14,5 @@
 segments=md.mesh.segments;
 
-if (md.mesh.dimension==2),
+if dimension(md.mesh)==2,
 	%plot mesh
 	A=elements(:,1); B=elements(:,2); C=elements(:,3); 
Index: /issm/trunk/src/m/plot/plot_tensor_components.m
===================================================================
--- /issm/trunk/src/m/plot/plot_tensor_components.m	(revision 17805)
+++ /issm/trunk/src/m/plot/plot_tensor_components.m	(revision 17806)
@@ -10,9 +10,9 @@
 upperplots=fix((i-1)/width);
 if upperplots==0, leftplots=i-1; else leftplots=i-width*upperplots-1; end
-if (md.mesh.dimension==2)%3 components -> 3 indexes
+if dimension(md.mesh)==2 %3 components -> 3 indexes
 	index1=4*width*upperplots+2*leftplots+1;
 	index2=index1+1;
 	index3=index1+width*2;
-elseif md.mesh.dimension==3%6 components -> 6 indexes
+elseif dimension(md.mesh)==3%6 components -> 6 indexes
 	index1=3*3*width*upperplots+3*leftplots+1;
 	index2=index1+1;
@@ -28,5 +28,5 @@
 [tensor.yy datatype]=processdata(md,tensor.yy,options);
 [tensor.xy datatype]=processdata(md,tensor.xy,options);
-if  md.mesh.dimension==3
+if  dimension(md.mesh)==3
 	[tensor.xz datatype]=processdata(md,tensor.xz,options);
 	[tensor.yz datatype]=processdata(md,tensor.yz,options);
@@ -34,5 +34,5 @@
 end
 
-if ((md.mesh.dimension==2)),
+if dimension(md.mesh)==2,
 	subplot(2*width,2*width,index1),
 	plot_unit(x,y,z,elements,tensor.xx,is2d,isplanet,datatype,options)
Index: /issm/trunk/src/m/plot/plot_tensor_principal.m
===================================================================
--- /issm/trunk/src/m/plot/plot_tensor_principal.m	(revision 17805)
+++ /issm/trunk/src/m/plot/plot_tensor_principal.m	(revision 17806)
@@ -10,5 +10,5 @@
 upperplots=fix((i-1)/width);
 if upperplots==0, leftplots=i-1; else leftplots=i-width*upperplots-1; end
-if (md.mesh.dimension==2)%3 components -> 3 indexes
+if (dimension(md.mesh)==2)%3 components -> 3 indexes
 	index1=4*width*upperplots+2*leftplots+1;
 	index2=index1+1;
@@ -16,5 +16,5 @@
 	index4=index3+1;
 	newwidth=2*width;
-elseif md.mesh.dimension==3%6 components -> 6 indexes
+elseif dimension(md.mesh)==3%6 components -> 6 indexes
 	index1=3*3*width*upperplots+3*leftplots+1;
 	index2=index1+1;
@@ -31,5 +31,5 @@
 type2=[type 'axis2'];
 plot_tensor_principalaxis(md,options,newwidth,index2,tensor,type2,plot_options);
-if  md.mesh.dimension==3
+if  dimension(md.mesh)==3
 	type3=[type 'axis3'];
 	plot_tensor_principalaxis(md,options,newwidth,index3,tensor,type3,plot_options);
@@ -40,9 +40,9 @@
 [tensor.principalvalue1 datatype]=processdata(md,tensor.principalvalue1,options);
 [tensor.principalvalue2 datatype]=processdata(md,tensor.principalvalue2,options);
-if  md.mesh.dimension==3
+if  dimension(md.mesh)==3
 	[tensor.principalvalue3 datatype]=processdata(md,tensor.principalvalue3,options);
 end
 
-if ((md.mesh.dimension==2)),
+if dimension(md.mesh)==2,
 	subplot(2*width,2*width,index3)
 	plot_unit(x,y,z,elements,tensor.principalvalue1,is2d,isplanet,datatype,options)
Index: /issm/trunk/src/m/plot/plot_tensor_principalaxis.m
===================================================================
--- /issm/trunk/src/m/plot/plot_tensor_principalaxis.m	(revision 17805)
+++ /issm/trunk/src/m/plot/plot_tensor_principalaxis.m	(revision 17806)
@@ -13,5 +13,5 @@
 [x y z elements is2d isplanet]=processmesh(md,[],options);
 
-if ((md.mesh.dimension==2)),
+if dimension(md.mesh)==2,
 	eval(['Vx=tensor.principalaxis' type(end) '(:,1); Vy=tensor.principalaxis' type(end) '(:,2);'])
 	eval(['value=tensor.principalvalue' type(end) ';']);
@@ -33,5 +33,5 @@
 
 %plot quivers
-if (md.mesh.dimension==2),
+if dimension(md.mesh)==2,
 
 	%density
Index: /issm/trunk/src/m/plot/plot_transient_results.m
===================================================================
--- /issm/trunk/src/m/plot/plot_transient_results.m	(revision 17805)
+++ /issm/trunk/src/m/plot/plot_transient_results.m	(revision 17806)
@@ -41,5 +41,5 @@
 clear string;
 
-if md.mesh.dimension==3,
+if dimension(md.mesh)==3,
 	string='plotmodel(md';
 	for i=1:length(md.results.transient),
@@ -67,5 +67,5 @@
 clear string;
 
-if md.mesh.dimension==3,
+if dimension(md.mesh)==3,
 	string='plotmodel(md';
 	for i=2:length(md.results.transient),
Index: /issm/trunk/src/m/plot/plot_unit.m
===================================================================
--- /issm/trunk/src/m/plot/plot_unit.m	(revision 17805)
+++ /issm/trunk/src/m/plot/plot_unit.m	(revision 17806)
@@ -30,20 +30,20 @@
 	case 2,
 
-		if is2d,
+		if size(elements,2)==6, %prisms
+			A=elements(:,1); B=elements(:,2); C=elements(:,3); D=elements(:,4); E=elements(:,5); F=elements(:,6);
+			patch( 'Faces', [A B C],  'Vertices', [x y z],'FaceVertexCData', data(:),'FaceColor','interp','EdgeColor',edgecolor);
+			patch( 'Faces', [D E F],  'Vertices', [x y z],'FaceVertexCData', data(:),'FaceColor','interp','EdgeColor',edgecolor);
+			patch( 'Faces', [A B E D],'Vertices', [x y z],'FaceVertexCData', data(:),'FaceColor','interp','EdgeColor',edgecolor);
+			patch( 'Faces', [B E F C],'Vertices', [x y z],'FaceVertexCData', data(:),'FaceColor','interp','EdgeColor',edgecolor);
+			patch( 'Faces', [C A D F],'Vertices', [x y z],'FaceVertexCData', data(:),'FaceColor','interp','EdgeColor',edgecolor);
+		elseif size(elements,2)==4, %tetras
+			A=elements(:,1); B=elements(:,2); C=elements(:,3); D=elements(:,4);
+			patch( 'Faces',[A B C],'Vertices', [x y z],'FaceVertexCData',data(:),'FaceColor','interp','EdgeColor',edgecolor);
+			patch( 'Faces',[A B D],'Vertices', [x y z],'FaceVertexCData',data(:),'FaceColor','interp','EdgeColor',edgecolor);
+			patch( 'Faces',[B C D],'Vertices', [x y z],'FaceVertexCData',data(:),'FaceColor','interp','EdgeColor',edgecolor);
+			patch( 'Faces',[C A D],'Vertices', [x y z],'FaceVertexCData',data(:),'FaceColor','interp','EdgeColor',edgecolor);
+		else
 			A=elements(:,1); B=elements(:,2); C=elements(:,3); 
 			patch( 'Faces', [A B C], 'Vertices', [x y z],'FaceVertexCData', data(:),'FaceColor','interp','EdgeColor',edgecolor);
-		else
-			if ~isplanet,
-				A=elements(:,1); B=elements(:,2); C=elements(:,3); D=elements(:,4); E=elements(:,5); F=elements(:,6);
-				patch( 'Faces', [A B C],  'Vertices', [x y z],'FaceVertexCData', data(:),'FaceColor','interp','EdgeColor',edgecolor);
-				patch( 'Faces', [D E F],  'Vertices', [x y z],'FaceVertexCData', data(:),'FaceColor','interp','EdgeColor',edgecolor);
-				patch( 'Faces', [A B E D],'Vertices', [x y z],'FaceVertexCData', data(:),'FaceColor','interp','EdgeColor',edgecolor);
-				patch( 'Faces', [B E F C],'Vertices', [x y z],'FaceVertexCData', data(:),'FaceColor','interp','EdgeColor',edgecolor);
-				patch( 'Faces', [C A D F],'Vertices', [x y z],'FaceVertexCData', data(:),'FaceColor','interp','EdgeColor',edgecolor);
-			else
-				A=elements(:,1); B=elements(:,2); C=elements(:,3); 
-				if size(elements,2)==4, D=elements(:,4); else D=C; end
-				patch( 'Faces', [A B C D],  'Vertices', [x y z],'FaceVertexCData', data(:),'FaceColor','interp','EdgeColor',edgecolor);
-			end
 		end
 
Index: /issm/trunk/src/m/plot/plot_unit.py
===================================================================
--- /issm/trunk/src/m/plot/plot_unit.py	(revision 17805)
+++ /issm/trunk/src/m/plot/plot_unit.py	(revision 17806)
@@ -1,53 +1,79 @@
-
+from cmaptools import truncate_colormap
 try:
 	import pylab as p
+	import matplotlib as mpl
+	import matplotlib.pyplot as plt
 except ImportError:
 	print "could not import pylab, matplotlib has not been installed, no plotting capabilities enabled"
 
-def plot_unit(x,y,z,elements,data,is2d,isplanet,datatype,options):
+def plot_unit(x,y,z,elements,data,is2d,isplanet,datatype,options,ax):
 	"""
 	PLOT_UNIT - unit plot, display data
-
+	
 		Usage:
 			plot_unit(x,y,z,elements,data,is2d,isplanet,datatype,options)
-
+	
 		See also: PLOTMODEL, PLOT_MANAGER
 	"""
-
+	
 	#edgecolor
 	edgecolor=options.getfieldvalue('edgecolor','None')
-
+	
 	#number of colorlevels for plots
-	colorlevels=options.getfieldvalue('colorlevels',256)
-
+	colorlevels=options.getfieldvalue('colorlevels',128)
+	
+	alpha=options.getfieldvalue('alpha',1)
+	
+	#colormap
+	# default sequential colormap
+	defaultmap=truncate_colormap(mpl.cm.gnuplot2,0.1,0.9,128)
+	cmap=options.getfieldvalue('colormap',defaultmap)
+	if options.exist('cmap_set_over'):
+	   over=options.getfieldvalue('cmap_set_over','0.5')
+	   cmap.set_over(over)
+	if options.exist('cmap_set_under'):
+	   under=options.getfieldvalue('cmap_set_under','0.5')
+	   cmap.set_under(under)
+	
+	#normalize colormap if clim/caxis specified
+	if options.exist('clim'):
+	   lims=options.getfieldvalue('clim',[min(data),max(data)])
+	elif options.exist('caxis'):
+	   lims=options.getfieldvalue('caxis',[min(data),max(data)])
+	else:
+	   lims=[min(data),max(data)]
+	norm = mpl.colors.Normalize(vmin=lims[0], vmax=lims[1])
 	if datatype==1:
-		#element plot
+	   #element plot
 		if is2d:
-			p.tripcolor(x,y,elements,data,colorlevels)
+			tri=ax.tripcolor(x,y,elements,data,colorlevels,cmap=cmap,edgecolors=edgecolor)
 		else:
 			raise ValueError('plot_unit error: 3D element plot not supported yet')
-		return
-
+		return 
+	
 	elif datatype==2:
 		#node plot
 		if is2d:
-			p.tricontourf(x,y,elements,data,colorlevels)
+			tri=ax.tricontourf(x,y,elements,data,colorlevels,cmap=cmap,norm=norm,alpha=alpha)
+			if edgecolor != 'None':
+				ax.triplot(x,y,elements,color=edgecolor)
 		else:
 			raise ValueError('plot_unit error: 3D node plot not supported yet')
 		return
-
+	
 	elif datatype==3:
 		print 'plot_unit message: quiver plot not implemented yet'
 		return
-
+	
 	elif datatype==4:
 		#P1 patch plot
 		print 'plot_unit message: P1 patch plot not implemented yet'
 		return
-
+	
 	elif datatype==5:
 		print 'plot_unit message: P0 patch plot not implemented yet'
 		return
-
+	
 	else:
 		raise ValueError('datatype=%d not supported' % datatype)
+
Index: /issm/trunk/src/m/plot/plot_vertexnumbering.m
===================================================================
--- /issm/trunk/src/m/plot/plot_vertexnumbering.m	(revision 17805)
+++ /issm/trunk/src/m/plot/plot_vertexnumbering.m	(revision 17806)
@@ -28,11 +28,19 @@
 		'backgroundcolor',[1 0 0],'HorizontalAlignment','center','VerticalAlignment','middle');
 else
-	%plot mesh 
-	A=elements(:,1); B=elements(:,2); C=elements(:,3); D=elements(:,4); E=elements(:,5); F=elements(:,6);
-	patch( 'Faces', [A B C],  'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
-	patch( 'Faces', [D E F],  'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
-	patch( 'Faces', [A B E D],'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
-	patch( 'Faces', [B E F C],'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
-	patch( 'Faces', [C A D F],'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+	if size(elements,2)==6, %prisms
+		%plot mesh 
+		A=elements(:,1); B=elements(:,2); C=elements(:,3); D=elements(:,4); E=elements(:,5); F=elements(:,6);
+		patch( 'Faces', [A B C],  'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+		patch( 'Faces', [D E F],  'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+		patch( 'Faces', [A B E D],'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+		patch( 'Faces', [B E F C],'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+		patch( 'Faces', [C A D F],'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+	elseif size(elements,2)==4, %tetras
+		A=elements(:,1); B=elements(:,2); C=elements(:,3); D=elements(:,4);
+		patch( 'Faces',[A B C],'Vertices', [x y z],'FaceVertexCData',zeros(size(x)),'FaceColor','none','EdgeColor','black');
+		patch( 'Faces',[A B D],'Vertices', [x y z],'FaceVertexCData',zeros(size(x)),'FaceColor','none','EdgeColor','black');
+		patch( 'Faces',[B C D],'Vertices', [x y z],'FaceVertexCData',zeros(size(x)),'FaceColor','none','EdgeColor','black');
+		patch( 'Faces',[C A D],'Vertices', [x y z],'FaceVertexCData',zeros(size(x)),'FaceColor','none','EdgeColor','black');
+	end
 
 	%numbering
Index: /issm/trunk/src/m/plot/plot_vstime.m
===================================================================
--- /issm/trunk/src/m/plot/plot_vstime.m	(revision 17806)
+++ /issm/trunk/src/m/plot/plot_vstime.m	(revision 17806)
@@ -0,0 +1,55 @@
+function plot_vstime(md,options,nlines,ncols,i)
+
+%plot mesh
+subplot(nlines,ncols,i); 
+
+%getting the variable structure
+datastruct  = getfieldvalue(options,'Input');
+structnames = strsplit(datastruct,'.');
+
+%getting the position of the to be ploted point
+location=getfieldvalue(options,'position');
+if ~isnumeric(location) | numel(location)~=2,
+	error('location provided not supported (should be [x y])');
+end
+xpoint=location(1);
+ypoint=location(2);
+
+%gathering a few time related parameters
+FirstTime=md.timestepping.start_time;
+LastTime=md.timestepping.final_time;
+Dt=md.timestepping.time_step;
+OutputDt=md.settings.output_frequency*Dt;
+%Constructiion of the result structure(one step above variable in
+%the structure tree)
+solstruct = md;
+for i=2:numel(structnames)-1,
+	solstruct=solstruct.(char(structnames(i)));
+end
+
+timesteps   = numel(solstruct);
+%now build a table with the variable needed in the end plot
+Value(1:timesteps)=NaN*ones(timesteps,1);
+time(1:timesteps)=NaN*ones(timesteps,1);
+
+for t=1:timesteps,
+	
+	data=solstruct(t).(char(structnames(numel(structnames))));
+
+	[TimeData datatype]=processdata(md,data,options);
+	clear data
+	Value(t)=PointValues(md,TimeData,xpoint,ypoint);
+	time(t)=FirstTime+(t-1)*OutputDt+Dt;
+end
+
+plot(time,Value);
+clear Value time
+
+options=addfielddefault(options,'title',md.miscellaneous.name);
+options=addfielddefault(options,'ylabel',char(structnames(numel(structnames))));
+options=addfielddefault(options,'xlabel','Time');
+options=addfielddefault(options,'colorbar',0);
+options=addfielddefault(options,'axis','auto');
+options=addfielddefault(options,'xlim',[FirstTime LastTime]);
+options=addfielddefault(options,'view',2);
+applyoptions(md,[],options);
Index: /issm/trunk/src/m/plot/plotmodel.py
===================================================================
--- /issm/trunk/src/m/plot/plotmodel.py	(revision 17805)
+++ /issm/trunk/src/m/plot/plotmodel.py	(revision 17806)
@@ -1,11 +1,12 @@
 import numpy as npy
+from plotoptions import plotoptions
 
 try:
 	import pylab as p
+	import matplotlib.pyplot as plt
+	from mpl_toolkits.axes_grid1 import ImageGrid
 except ImportError:
 	print "could not import pylab, matplotlib has not been installed, no plotting capabilities enabled"
 
-#from pairoptions import *
-from plotoptions import plotoptions
 from plot_manager import plot_manager
 from math import ceil, sqrt
@@ -26,11 +27,14 @@
 	numberofplots=options.numberofplots
 
-	#if nlines and ncols specified, then bypass
-	if options.list[0].exist('nlines'):
-		nlines=options.list[0].getfieldvalue('nlines')
-		nl=True
+	#get hold
+	hold=options.list[0].getfieldvalue('hold',False)
+
+	#if nrows and ncols specified, then bypass
+	if options.list[0].exist('nrows'):
+		nrows=options.list[0].getfieldvalue('nrows')
+		nr=True
 	else:
-		nlines=npy.ceil(numberofplots/subplotwidth)
-		nl=False
+		nrows=npy.ceil(numberofplots/subplotwidth)
+		nr=False
 	
 	if options.list[0].exist('ncols'):
@@ -41,30 +45,40 @@
 		nc=False
 	
-	#check that nlines and ncols were given at the same time!
-	if not nl==nc:
-		raise StandardError('error: nlines and ncols need to be specified together, or not at all')
-	
+	#check that nrows and ncols were given at the same time!
+	if not nr==nc:
+		raise StandardError('error: nrows and ncols need to be specified together, or not at all')
 	
 	#Go through plots
 	if numberofplots:
 		
-		#Create figure
-		#plots will be visible by default if ipython is run in interactive mode (invoked by ipython --pylab)
-		#UNLESS plotmodel is called within a script (e.g. a runme.py file) 
-		#handling the 'visible' option will need some check on whether ipython is currently in interactive or non-interactive mode
+		if not hold: # TODO need to also check whether figurenumber is a new plot so that old plots are not mistakenly cleared
+			plt.cla()
 
 		#if figsize specified
 		if options.list[0].exist('figsize'):
 			figsize=options.list[0].getfieldvalue('figsize')
-			p.figure(figurenumber,figsize=figsize)
+			fig=plt.figure(figurenumber,figsize=figsize,tight_layout=True)
 		else:
-			p.figure(figurenumber)
-			
-		#try:
+			fig=plt.figure(figurenumber,tight_layout=True)
+		fig.clf()
+	
+		# options to pass: axes_pad, share_all, label_mode ("1","L","all"), cbar_mode (none,single,each), cbar_location(right,top)
+		axgrid=ImageGrid(fig, 111,
+				nrows_ncols=(nrows,ncols),
+				direction='row',
+				axes_pad=0.05,
+				add_all=True,
+				share_all=True,
+				label_mode='all',
+				cbar_mode='single',
+				cbar_location='right',
+				cbar_size='5%',
+				cbar_pad=0.05
+				)
+
 		for i in xrange(numberofplots):
-			plot_manager(options.list[i].getfieldvalue('model',md),options.list[i],subplotwidth,nlines,ncols,i+1)
-		#except StandardError:
-		#	print 'error in plot_manager'
-		p.show()
+			plot_manager(options.list[i].getfieldvalue('model',md),options.list[i],fig,axgrid[i])
+
+		plt.show()
 	else:
 		raise StandardError('plotmodel error message: no output data found.')
Index: /issm/trunk/src/m/plot/processdata.m
===================================================================
--- /issm/trunk/src/m/plot/processdata.m	(revision 17805)
+++ /issm/trunk/src/m/plot/processdata.m	(revision 17806)
@@ -22,6 +22,6 @@
 end
 
-%special case for mesg 2dvertical
-if strcmp(meshtype(md.mesh),'2Dvertical'),
+%special case for mesh 2dvertical
+if strcmp(domaintype(md.mesh),'2Dvertical'),
 	[data datatype] = processdata(md.mesh,md,data,options);
 	return;
@@ -56,5 +56,5 @@
 
 %check length
-if datasize(1)~=md.mesh.numberofvertices & datasize(1)~=md.mesh.numberofelements & datasize(1)~=md.mesh.numberofvertices*6 & (md.mesh.dimension==3 & ~(datasize(1)==numberofelements2d | datasize(1)==numberofvertices2d))
+if datasize(1)~=md.mesh.numberofvertices & datasize(1)~=md.mesh.numberofelements & datasize(1)~=md.mesh.numberofvertices*6 & (strcmp(md.mesh.domaintype(),'3D') & ~(datasize(1)==numberofelements2d | datasize(1)==numberofvertices2d))
 	error('plotmodel error message: data not supported yet');
 end
@@ -65,5 +65,5 @@
 
 	%check number of columns, add zeros if necessary,
-	if (md.mesh.dimension==3)
+	if (dimension(md.mesh)==3)
 		if datasize(2)==2,
 			data=[data, zeros(datasize(1),1)];
@@ -71,6 +71,4 @@
 			error('plotmodel error message: data provided should have 2 or 3 columns for quiver plot, and 1 for regular plot');
 		end
-		%elseif ((md.mesh.dimension==2) & datasize(2)~=2),
-		%	error('plotmodel error message: data provided should have 2 columns for quiver plot, and 1 for regular plot');
 	end
 end
@@ -87,5 +85,5 @@
 
 %treat the case datasize(1)=nodes2d
-if (md.mesh.dimension==3 & datasize(1)==numberofvertices2d),
+if (dimension(md.mesh)==3 & datasize(1)==numberofvertices2d),
 	data=project3d(md,'vector',data,'type','node');
 	datasize(1)=md.mesh.numberofvertices;
@@ -94,5 +92,5 @@
 
 %treat the case datasize(1)=nodes2d
-if (md.mesh.dimension==3 & datasize(1)==numberofelements2d),
+if (dimension(md.mesh)==3 & datasize(1)==numberofelements2d),
 	data=project3d(md,'vector',data,'type','element');
 	datasize(1)=md.mesh.numberofelements;
Index: /issm/trunk/src/m/plot/processdata.py
===================================================================
--- /issm/trunk/src/m/plot/processdata.py	(revision 17805)
+++ /issm/trunk/src/m/plot/processdata.py	(revision 17806)
@@ -22,5 +22,5 @@
 
 	#needed later on
-	if md.mesh.numberofvertices2d:
+	if 'numberofvertices2d' in dir(md.mesh):
 		numberofvertices2d=md.mesh.numberofvertices2d
 		numberofelements2d=md.mesh.numberofelements2d
@@ -28,4 +28,6 @@
 		numberofvertices2d=npy.nan
 		numberofelements2d=npy.nan
+
+	procdata=npy.copy(data)
 
 	#process patch
@@ -35,12 +37,16 @@
 
 	#get datasize
-	if npy.ndim(data)==1:
-		datasize=npy.array([len(data),1])
+	if npy.ndim(procdata)==1:
+		datasize=npy.array([len(procdata),1])
 	else:
-		datasize=npy.shape(data)
+		datasize=npy.shape(procdata)
 	
 	#process NaN's if any
-	if options.exist('nan'):
-		data[npy.isnan(data)]=options.getfieldvalue('nan',0)
+	nanfill=options.getfieldvalue('nan',-9999)
+	if npy.any(npy.isnan(procdata)):
+		procdata[npy.isnan(procdata)]=nanfill
+		options.addfielddefault('cmap_set_under','1')
+		options.addfielddefault('clim',[min(data),max(data)])
+		print "WARNING: nan's treated as -9999 by default.  Change using pairoption 'nan',nan_fill_value in plotmodel call"
 
 	#non-patch processing 
@@ -70,6 +76,6 @@
 
 	#convert rank-2 array to rank-1
-	if npy.ndim(data)==2 and npy.shape(data)[1]==1:
-		data=data.reshape(-1,)
+	if npy.ndim(procdata)==2 and npy.shape(procdata)[1]==1:
+		procdata=procdata.reshape(-1,)
 
 	#if datatype is still zero, error out
@@ -77,3 +83,3 @@
 		raise ValueError("processdata error: data provided not recognized or not supported")
 	else:
-		return data, datatype
+		return procdata, datatype
Index: /issm/trunk/src/m/plot/processmesh.m
===================================================================
--- /issm/trunk/src/m/plot/processmesh.m	(revision 17805)
+++ /issm/trunk/src/m/plot/processmesh.m	(revision 17806)
@@ -16,5 +16,5 @@
 
 %special case for mesg 2dvertical
-if strcmp(meshtype(md.mesh),'2Dvertical'),
+if strcmp(domaintype(md.mesh),'2Dvertical'),
 	[x y z elements is2d isplanet] = processmesh(md.mesh,options);
 	return;
@@ -32,11 +32,12 @@
 end
 
-z_field=getfieldvalue(options,'z',md.mesh.z);
-if ischar(z_field),
-	z=md.(z_field);
-elseif isnumeric(z_field),
-	z=z_field;
+if isprop(md.mesh,'z'),
+	z=md.mesh.z;
 else
-	z=md.mesh.z;
+	z=zeros(size(x));
+end
+z=getfieldvalue(options,'z',z);
+if ischar(z),
+	z=md.(z);
 end
 
@@ -45,7 +46,7 @@
 
 %is it a 2d plot?
-if (md.mesh.dimension==2);
+if md.mesh.dimension()==2,
 	is2d=1;
-elseif (md.mesh.dimension==3),
+else
 	if getfieldvalue(options,'layer',0)>=1,
 		is2d=1;
@@ -53,6 +54,4 @@
 		is2d=0;
 	end
-else
-	error(['dim = ' num2str(md.mesh.dimension) ' not supported yet']);
 end
 
Index: /issm/trunk/src/m/plot/processmesh.py
===================================================================
--- /issm/trunk/src/m/plot/processmesh.py	(revision 17805)
+++ /issm/trunk/src/m/plot/processmesh.py	(revision 17806)
@@ -1,3 +1,5 @@
 from math import isnan
+import MatlabFuncs as m
+import numpy as npy
 
 def processmesh(md,data,options):
@@ -21,36 +23,30 @@
 		if 'latlon' not in options.getfieldvalue('coord','xy').lower(): #convert to lower case for comparison
 			x=md.mesh.x
-			if not isnan(md.mesh.x2d): x2d=md.mesh.x2d
+			if 'x2d' in dir(md.mesh): x2d=md.mesh.x2d
 			y=md.mesh.y
-			if not isnan(md.mesh.y2d): y2d=md.mesh.y2d
+			if 'y2d' in dir(md.mesh): y2d=md.mesh.x2d
 		else:
 			x=md.mesh.long
 			y=md.mesh.lat
 
-		z_field=options.getfieldvalue('z',md.mesh.z)
-		#if isinstance(z_field,basestring): # how could z be a string?
-		#	z=md.(z_field)
-		if isinstance(z_field,(int,long,float)):  # isnumeric
-			z=z_field
+		if 'z' in dir(md.mesh):
+			z=md.mesh.z
 		else:
-			z=md.mesh.z
+			z=npy.zeros_like(md.mesh.x)
 		
-		if not isnan(md.mesh.elements2d): 
+		if 'elements2d' in dir(md.mesh): 
 			elements2d=md.mesh.elements2d
-			elements2d=elements2d-1
-		# subtract one since python indexes from zero
+			elements2d=elements2d-1  # subtract one since python indexes from zero
 		elements=md.mesh.elements
 		elements=elements-1
 
 		#is it a 2D plot?
-		if md.mesh.dimension==2:
+		if md.mesh.dimension()==2:
 			is2d=1
-		elif md.mesh.dimension==3:
+		else:
 			if options.getfieldvalue('layer',0)>=1:
 				is2d=1
 			else:
 				is2d=0
-		else:
-			raise ValueError('processmesh error: dim = %d not supported' % md.mesh.dimension)
 
 		#layer projection?
@@ -66,5 +62,5 @@
 	else:
 		#Process mesh for plotting 
-		if md.mesh.dimension==2:
+		if md.mesh.dimension()==2:
 			is2d=1
 		else:
Index: /issm/trunk/src/m/plot/radarpower.m
===================================================================
--- /issm/trunk/src/m/plot/radarpower.m	(revision 17805)
+++ /issm/trunk/src/m/plot/radarpower.m	(revision 17806)
@@ -90,7 +90,14 @@
 		im=imread('temp.tif','TIFF');
 		%adjust contrast and brightness
-		im=imadjust(im,[a b],[c d]);
+		%im=imadjust(im,[a b],[c d]);
 		pixelskip=max(1,ceil(posting/((x1-x0)/(size(im,2)))));
-		md.radaroverlay.pwr=double(flipud(im(1:pixelskip:end,1:pixelskip:end)));
+		if size(im,3)==1,
+			md.radaroverlay.pwr=double(flipud(im(1:pixelskip:end,1:pixelskip:end)));
+		else
+			md.radaroverlay.pwr=double(im(1:pixelskip:end,1:pixelskip:end,1:pixelskip:end));
+			md.radaroverlay.pwr(:,:,1)=flipud(md.radaroverlay.pwr(:,:,1));
+			md.radaroverlay.pwr(:,:,2)=flipud(md.radaroverlay.pwr(:,:,2));
+			md.radaroverlay.pwr(:,:,3)=flipud(md.radaroverlay.pwr(:,:,3));
+		end
 		md.radaroverlay.x=(x0:(x1-x0)/(size(md.radaroverlay.pwr,2)-1):x1);
 		md.radaroverlay.y=(y0:(y1-y0)/(size(md.radaroverlay.pwr,1)-1):y1);
@@ -121,5 +128,5 @@
 		im=imread('temp.tif','TIFF');
 		%adjust contrast and brightness
-		im=imadjust(im,[a b],[c d]);
+		%im=imadjust(im,[a b],[c d]);
 		pixelskip=max(1,ceil(posting/((x1-x0)/(size(im,2)))));
 		md.radaroverlay.pwr=double(flipud(im(1:pixelskip:end,1:pixelskip:end)));
@@ -153,5 +160,5 @@
 	im=imread(overlay_image);
 	%adjust contrast and brightness
-	im=imadjust(im,[a b],[c d]);
+	%im=imadjust(im,[a b],[c d]);
 	im=im(toplefty:toplefty+sizey,topleftx:topleftx+sizex);
 	md.radaroverlay.pwr=double(flipud(im));
Index: /issm/trunk/src/m/print/export_geotiff.m
===================================================================
--- /issm/trunk/src/m/print/export_geotiff.m	(revision 17806)
+++ /issm/trunk/src/m/print/export_geotiff.m	(revision 17806)
@@ -0,0 +1,24 @@
+function export_geotiff(filename,ref)
+%EXPORT_GEOTIF - export geotiff 
+%
+%   Usage:
+%      export_geotif(filename,ref);
+%
+%      This function must be called after plotmodel
+%      filname: no extension
+%      ref:     UPS Greenland  EPSG:3413 (http://www.spatialreference.org/ref/epsg/3413/)
+%               UPS Antarctica EPSG:3031 (http://www.spatialreference.org/ref/epsg/3031/)
+%
+%   Example:
+%      export_geotif('Greenland','EPSG:3413');
+
+%Get axis limits and convert to strings
+XLIM = xlim(); x0 = num2str(XLIM(1)); x1 = num2str(XLIM(2));
+YLIM = ylim(); y0 = num2str(YLIM(1)); y1 = num2str(YLIM(2));
+
+%first export the figure
+export_fig([filename '.jpg']);
+
+%call gdal on this: 
+system(['gdal_translate -a_srs ' ref ' -of GTiff -co "INTERLEAVE=PIXEL" -a_ullr ' x0 ' ' y1 ' ' x1 ' ' y0 ' ' filename '.jpg ' filename '.tif']);
+system(['rm -rf ' filename '.jpg']);
Index: /issm/trunk/src/m/qmu/preqmu.m
===================================================================
--- /issm/trunk/src/m/qmu/preqmu.m	(revision 17805)
+++ /issm/trunk/src/m/qmu/preqmu.m	(revision 17806)
@@ -13,30 +13,32 @@
 %       iparams: same thing for params
 %       overwrite: overwrite qmudir before analysis
-%       keep: keep qmudir after analysis
-%       outfiles: (John?)
-%       rstfile: backup file name
-%       rundakota: (John?)
-%       runmpi: (John?)
 
 disp('preprocessing dakota inputs');
+qmudir    = getfieldvalue(options,'qmudir',['qmu' num2str(feature('GetPid'))]);  % qmudir = ['qmu_' datestr(now,'yyyymmdd_HHMMSS')];
+qmufile   = getfieldvalue(options,'qmufile','qmu');% qmufile cannot be changed unless ????script.sh is also changed
+overwrite = getfieldvalue(options,'overwrite','n');
+ivar      = getfieldvalue(options,'ivar',1);
+iresp     = getfieldvalue(options,'iresp',1);
+imethod   = getfieldvalue(options,'imethod',1);
+iparams   = getfieldvalue(options,'iparams',1);
 
 %first create temporary directory in which we will work
-if strncmpi(options.overwrite,'y',1)
-	system(['rm -rf ' options.qmudir '/*']); 
+if strncmpi(overwrite,'y',1)
+	system(['rm -rf ' qmudir '/*']); 
 else
 	%does the directory exist? if so, then error out
-	if exist(options.qmudir)==7,
+	if exist(qmudir)==7,
 		error('Existing ''%s'' directory, cannot overwrite. Specify ''overwrite'',''y'' option in solve arguments.',options.qmudir);
 	end
 end
-mkdir(options.qmudir)
-cd(options.qmudir)
+mkdir(qmudir)
+cd(qmudir)
 
 %when running in library mode, the in file needs to be called md.miscellaneous.name.qmu.in
-options.qmufile=[md.miscellaneous.name ];
+qmufile=[md.miscellaneous.name ];
 
 %retrieve variables and resposnes for this particular analysis.
-variables=md.qmu.variables(options.ivar);
-responses=md.qmu.responses(options.iresp);
+variables=md.qmu.variables(ivar);
+responses=md.qmu.responses(iresp);
 
 %expand variables and responses
@@ -73,13 +75,13 @@
 
 %create in file for dakota
-dakota_in_data(md.qmu.method(options.imethod),variables,responses,md.qmu.params(options.iparams),options.qmufile);
+dakota_in_data(md.qmu.method(imethod),variables,responses,md.qmu.params(iparams),qmufile);
 system(['rm -rf ' md.miscellaneous.name '.m']);
 
 %build a list of variables and responses descriptors. the list is not expanded. {{{
 variabledescriptors={};
-variable_fieldnames=fieldnames(md.qmu.variables(options.ivar));
+variable_fieldnames=fieldnames(md.qmu.variables(ivar));
 for i=1:length(variable_fieldnames),
 	field_name=variable_fieldnames{i};
-	fieldvariables=md.qmu.variables(options.ivar).(field_name);
+	fieldvariables=md.qmu.variables(ivar).(field_name);
 	for j=1:numel(fieldvariables)
 		variabledescriptors{end+1}=fieldvariables(j).descriptor;
@@ -88,8 +90,8 @@
 
 responsedescriptors={};
-response_fieldnames=fieldnames(md.qmu.responses(options.iresp));
+response_fieldnames=fieldnames(md.qmu.responses(iresp));
 for i=1:length(response_fieldnames),
 	field_name=response_fieldnames{i};
-	fieldresponses=md.qmu.responses(options.iresp).(field_name);
+	fieldresponses=md.qmu.responses(iresp).(field_name);
 	for j=1:numel(fieldresponses)
 		responsedescriptors{end+1}=fieldresponses(j).descriptor;
Index: sm/trunk/src/m/shp/Shp2Exp.m
===================================================================
--- /issm/trunk/src/m/shp/Shp2Exp.m	(revision 17805)
+++ 	(revision )
@@ -1,33 +1,0 @@
-function Shp2Exp(expfilename,shapefilename)
-%SHP2EXP- transform shape file to Argus .exp file
-%
-%   Usage:
-%      Shp2Exp(expfilename,shapefilename);
-%
-%   Example:
-%      Shp2Exp('Domain.exp','Domain.shp');
-%
-%   See also EXPMASTER, EXPDOC
-
-	if ~exist(shapefilename,'file'),
-		error(['Shapefile ' shapefilename ' does not exist']);
-	end
-	shp=shaperead(shapefilename);
-
-	exp=struct([]);
-	for i=1:length(shp),
-		if strcmpi(shp(i).Geometry,'Polygon'),
-			x=shp(i).X; y=shp(i).Y;
-			ids=find(isnan(x));
-			x(ids)=[]; y(ids)=[];
-
-			exp(end+1).x=x;
-			exp(end).y=y;
-			exp(end).nods=length(x);
-			exp(end).density=1;
-			exp(end).closed=1;
-			exp(end).name=num2str(shp(i).id);
-		end
-	end
-
-	expwrite(exp,expfilename);
Index: /issm/trunk/src/m/shp/shp2exp.m
===================================================================
--- /issm/trunk/src/m/shp/shp2exp.m	(revision 17806)
+++ /issm/trunk/src/m/shp/shp2exp.m	(revision 17806)
@@ -0,0 +1,48 @@
+function Shp2Exp(expfilename,shapefilename)
+%SHP2EXP- transform shape file to Argus .exp file
+%
+%   Usage:
+%      Shp2Exp(expfilename,shapefilename);
+%
+%   Example:
+%      Shp2Exp('Domain.exp','Domain.shp');
+%
+%   See also EXPMASTER, EXPDOC
+
+	if ~exist(shapefilename,'file'),
+		error(['Shapefile ' shapefilename ' does not exist']);
+	end
+	shp=shaperead(shapefilename);
+
+	expstruct=struct([]);
+	for i=1:length(shp),
+		if strcmpi(shp(i).Geometry,'Polygon'),
+			x=shp(i).X; y=shp(i).Y;
+			ids=find(isnan(x));
+			x(ids)=[]; y(ids)=[];
+			expstruct(end+1).x=x;
+			expstruct(end).y=y;
+			expstruct(end).nods=length(x);
+			expstruct(end).density=1;
+			expstruct(end).closed=1;
+			expstruct(end).name=num2str(shp(i).id);
+		elseif strcmpi(shp(i).Geometry,'Point'),
+			x=shp(i).X; y=shp(i).Y;
+			expstruct(end+1).x=x;
+			expstruct(end).y=y;
+			expstruct(end).nods=length(x);
+			expstruct(end).density=1;
+			expstruct(end).closed=1;
+			%exp(end).name=num2str(shp(i).id);
+		elseif strcmpi(shp(i).Geometry,'Line'),
+			x=shp(i).X; y=shp(i).Y;
+			x(end)=x(1); y(end)=y(1);
+			expstruct(end+1).x=x;
+			expstruct(end).y=y;
+			expstruct(end).nods=length(x);
+			expstruct(end).density=1;
+			expstruct(end).closed=1;
+		end
+	end
+
+	expwrite(expstruct,expfilename);
Index: /issm/trunk/src/m/shp/shp2exp.py
===================================================================
--- /issm/trunk/src/m/shp/shp2exp.py	(revision 17806)
+++ /issm/trunk/src/m/shp/shp2exp.py	(revision 17806)
@@ -0,0 +1,55 @@
+import shapefile
+import os
+from expwrite import expwrite
+
+def shp2exp(shapefilename,*expfilename):
+	'''
+	Convert a shapefile to an .exp file.  Optionally, expfilename can be
+	specified to give a name for the .exp file to be created, otherwise the
+	.exp file will have the same prefix as the .shp file.
+
+	Usage:
+		shp2exp(shapefilename)
+		shp2exp(shapefilename,expfilename)
+
+	Examples:
+		shp2exp('Domain.shp') % creates Domain.exp
+		shp2exp('Domain.shp','DomainForISSM.exp')
+	'''
+	
+	if not os.path.exists(shapefilename):
+		raise IOError("shp2exp error message: file '%s' not found!" % parametername)
+	if not len(expfilename):
+		expfile=os.path.splitext(shapefilename)[0]+'.exp'
+	else:
+		expfile=expfilename[0]
+
+	shp=shapefile.Reader(shapefilename)
+	expdict=dict(closed=1,density=1)
+
+	x=[]
+	y=[]
+	for i in range(len(shp.shapes())):
+		geom=shp.shapes()[i].shapeType
+		if geom==5: # polygon
+			x=[p[0] for p in shp.shapes()[i].points]
+			y=[q[1] for q in shp.shapes()[i].points]
+			expdict['x']=x
+			expdict['y']=y
+			expdict['nods']=len(x)
+		elif geom==3: # line
+			x=[p[0] for p in shp.shapes()[i].points]
+			y=[q[1] for q in shp.shapes()[i].points]
+			x.append(x[0])
+			y.append(y[0])
+			expdict['x']=x
+			expdict['y']=y
+			expdict['nods']=len(x)
+		elif geom==1: # point
+			x.append(shp.shapes()[i].points[0][0])
+			y.append(shp.shapes()[i].points[0][1])
+			expdict['x']=x
+			expdict['y']=y
+			expdict['nods']=len(x)
+
+	expwrite([expdict],expfile)
Index: /issm/trunk/src/m/shp/shpdisp.m
===================================================================
--- /issm/trunk/src/m/shp/shpdisp.m	(revision 17805)
+++ /issm/trunk/src/m/shp/shpdisp.m	(revision 17806)
@@ -45,8 +45,13 @@
 figure(figurenumber),hold on
 for i=1:length(domain),
-	if (isnumeric(linestyle))
-		plot(domain(i).x*unitmultiplier,domain(i).y*unitmultiplier,'Color',linestyle,'linewidth',linewidth);
+	if(isfield(domain,'nods'))
+		if (isnumeric(linestyle))
+			plot(domain(i).x*unitmultiplier,domain(i).y*unitmultiplier,'Color',linestyle,'linewidth',linewidth);
+		else
+			plot(domain(i).x*unitmultiplier,domain(i).y*unitmultiplier,linestyle,'linewidth',linewidth);
+	  end
 	else
-		plot(domain(i).x*unitmultiplier,domain(i).y*unitmultiplier,linestyle,'linewidth',linewidth);
+		plot(domain(i).x*unitmultiplier,domain(i).y*unitmultiplier,'ro','MarkerSize',5);
 	end
+	
 end
Index: /issm/trunk/src/m/shp/shpread.m
===================================================================
--- /issm/trunk/src/m/shp/shpread.m	(revision 17805)
+++ /issm/trunk/src/m/shp/shpread.m	(revision 17806)
@@ -6,4 +6,6 @@
 %   the shp file, for the density, for the nodes, and a field closed to 
 %   indicate if the domain is closed. 
+%   If this initial shapefile is point only, the fields closed and
+%   points are ommited
 %   The first argument is the .shp file to be read and the second one (optional) 
 %   indicates if the last point shall be read (1 to read it, 0 not to).
@@ -53,4 +55,25 @@
 		end
 	end
+
+	if strcmpi(shp(i).Geometry,'Point'),
+		x=shp(i).X'; y=shp(i).Y';
+		ids=find(isnan(x));
+		x(ids)=[]; y(ids)=[];
+
+		Struct(end+1).x=x;
+		Struct(end).y=y;
+		Struct(end).density=1;
+		if isfield(shp,'id'),
+			Struct(end).name=num2str(shp(i).id);
+		else
+			Struct(end).name='';
+		end
+		for j=1:length(fields),
+			field=fields{j};
+			if ~(strcmpi(field,'X') | strcmpi(field,'Y') | strcmpi(field,'id')),
+				Struct(end).(field)=shp(i).(field);
+			end
+		end
+	end
 end
 
Index: /issm/trunk/src/m/shp/shpwrite.m
===================================================================
--- /issm/trunk/src/m/shp/shpwrite.m	(revision 17805)
+++ /issm/trunk/src/m/shp/shpwrite.m	(revision 17806)
@@ -14,8 +14,11 @@
 count=0;
 
-
 contours=struct([]);
 for i=1:length(shp),
-	contours(i).Geometry='Polygon';
+	if strcmpi(shp(i).Geometry,'Point'),
+		contours(i).Geometry='Point';
+	else strcmpi(shp(i).Geometry,'Polygon'),
+		contours(i).Geometry='Polygon';
+	end
 	contours(i).id=i;
 	contours(i).X=shp(i).x;
Index: /issm/trunk/src/m/solve/WriteData.m
===================================================================
--- /issm/trunk/src/m/solve/WriteData.m	(revision 17805)
+++ /issm/trunk/src/m/solve/WriteData.m	(revision 17806)
@@ -152,5 +152,7 @@
 
 	%first write length of record
-	fwrite(fid,4+4+8*s(1)*s(2)+4+4,'int');  %2 integers (32 bits) + the double matrix + code + matrix type
+	recordlength=4+4+8*s(1)*s(2)+4+4; %2 integers (32 bits) + the double matrix + code + matrix type
+	if recordlength>2^31; error(['field ' EnumToString(enum) ' cannot be marshalled because it is larger than 2^31 bytes!']); end
+	fwrite(fid,recordlength,'int');
 
 	%write data code and matrix type: 
Index: /issm/trunk/src/m/solve/WriteData.py
===================================================================
--- /issm/trunk/src/m/solve/WriteData.py	(revision 17805)
+++ /issm/trunk/src/m/solve/WriteData.py	(revision 17806)
@@ -2,6 +2,6 @@
 import math
 import struct
-from pairoptions import *
-from MatlabFuncs import *
+import pairoptions
+import MatlabFuncs as m
 from EnumDefinitions import *
 from EnumToString import EnumToString
@@ -16,7 +16,5 @@
 
 	#process options
-	#  the import above the function level doesn't work?
-	from pairoptions import pairoptions
-	options=pairoptions(*args)
+	options=pairoptions.pairoptions(*args)
 
 	#Get data properties
@@ -62,5 +60,5 @@
 
 	#Step 2: write the data itself.
-	if   strcmpi(format,'Boolean'):    # {{{
+	if   m.strcmpi(format,'Boolean'):    # {{{
 #		if len(data) !=1:
 #			raise ValueError('field %s cannot be marshalled as it has more than one element!' % EnumToString(enum)[0])
@@ -76,5 +74,5 @@
 		# }}}
 
-	elif strcmpi(format,'Integer'):    # {{{
+	elif m.strcmpi(format,'Integer'):    # {{{
 #		if len(data) !=1:
 #			raise ValueError('field %s cannot be marshalled as it has more than one element!' % EnumToString(enum)[0])
@@ -90,5 +88,5 @@
 		# }}}
 
-	elif strcmpi(format,'Double'):    # {{{
+	elif m.strcmpi(format,'Double'):    # {{{
 #		if len(data) !=1:
 #			raise ValueError('field %s cannot be marshalled as it has more than one element!' % EnumToString(enum)[0])
@@ -104,5 +102,5 @@
 		# }}}
 
-	elif strcmpi(format,'String'):    # {{{
+	elif m.strcmpi(format,'String'):    # {{{
 		#first write length of record
 		fid.write(struct.pack('i',len(data)+4+4))  #string + string size + code
@@ -116,5 +114,5 @@
 		# }}}
 
-	elif strcmpi(format,'BooleanMat'):    # {{{
+	elif m.strcmpi(format,'BooleanMat'):    # {{{
 
 		if   isinstance(data,bool):
@@ -149,5 +147,5 @@
 		# }}}
 
-	elif strcmpi(format,'IntMat'):    # {{{
+	elif m.strcmpi(format,'IntMat'):    # {{{
 
 		if   isinstance(data,(int,long)):
@@ -182,5 +180,5 @@
 		# }}}
 
-	elif strcmpi(format,'DoubleMat'):    # {{{
+	elif m.strcmpi(format,'DoubleMat'):    # {{{
 
 		if   isinstance(data,(bool,int,long,float)):
@@ -201,5 +199,9 @@
 
 		#first write length of record
-		fid.write(struct.pack('i',4+4+8*s[0]*s[1]+4+4))    #2 integers (32 bits) + the double matrix + code + matrix type
+		recordlength=4+4+8*s[0]*s[1]+4+4; #2 integers (32 bits) + the double matrix + code + matrix type
+		if recordlength > 2**31 :
+			raise ValueError('field %s cannot be marshalled because it is larger than 4^31 bytes!' % EnumToString(enum)[0])
+
+		fid.write(struct.pack('i',recordlength))  #2 integers (32 bits) + the double matrix + code + matrix type
 
 		#write data code and matrix type: 
@@ -215,5 +217,5 @@
 		# }}}
 
-	elif strcmpi(format,'MatArray'):    # {{{
+	elif m.strcmpi(format,'MatArray'):    # {{{
 
 		#first get length of record
@@ -259,5 +261,5 @@
 		# }}}
 
-	elif strcmpi(format,'StringArray'):    # {{{
+	elif m.strcmpi(format,'StringArray'):    # {{{
 
 		#first get length of record
@@ -315,21 +317,21 @@
 	"""
 
-	if   strcmpi(format,'Boolean'):
+	if   m.strcmpi(format,'Boolean'):
 		code=1
-	elif strcmpi(format,'Integer'):
+	elif m.strcmpi(format,'Integer'):
 		code=2
-	elif strcmpi(format,'Double'):
+	elif m.strcmpi(format,'Double'):
 		code=3
-	elif strcmpi(format,'String'):
+	elif m.strcmpi(format,'String'):
 		code=4
-	elif strcmpi(format,'BooleanMat'):
+	elif m.strcmpi(format,'BooleanMat'):
 		code=5
-	elif strcmpi(format,'IntMat'):
+	elif m.strcmpi(format,'IntMat'):
 		code=6
-	elif strcmpi(format,'DoubleMat'):
+	elif m.strcmpi(format,'DoubleMat'):
 		code=7
-	elif strcmpi(format,'MatArray'):
+	elif m.strcmpi(format,'MatArray'):
 		code=8
-	elif strcmpi(format,'StringArray'):
+	elif m.strcmpi(format,'StringArray'):
 		code=9
 	else:
Index: /issm/trunk/src/m/solve/convert2str.m
===================================================================
--- /issm/trunk/src/m/solve/convert2str.m	(revision 17806)
+++ /issm/trunk/src/m/solve/convert2str.m	(revision 17806)
@@ -0,0 +1,130 @@
+function str = convert2str(field)
+
+	str = parsedisplay(field);
+
+end %function
+
+function str = parsedisplay(field) % {{{
+
+	%string
+	if ischar(field),
+
+		if length(field)>30;
+			%str = displayunit('not displayed');
+            str=field;
+		else
+			str = displayunit(['''' field '''']);
+		end
+
+	%cell
+    elseif iscell(field),
+		str = cell_display(field),
+
+    %structure
+	elseif isstruct(field),
+		str = struct_display(field),
+        
+	%numeric
+	elseif isnumeric(field)
+
+		%get size
+		fieldsize=size(field);
+
+		%double
+		if max(fieldsize)==1,
+			str = displayunit(num2str(field)),
+			%matrix
+		else
+			str = displayunit(['(' num2str(fieldsize(1)) 'x' num2str(fieldsize(2)) ')']),
+        end
+        
+ 	%logical
+	elseif islogical(field)
+
+		%get size
+		fieldsize=size(field);
+
+		%single value
+		if max(fieldsize)==1,
+			if (field)
+				str = displayunit('true');
+			else
+				str = displayunit('false');
+			end
+		%matrix
+		else
+			str = displayunit(name,['(' num2str(fieldsize(1)) 'x' num2str(fieldsize(2)) ')']);
+        end    
+        
+    %misc/
+    else
+        str = displayunit(field);
+
+    end
+
+end
+
+function str = displayunit(characterization)% {{{
+
+	%take care of characterization
+	if (strcmp(characterization,['''' '''']) || strcmp(characterization,'NaN')),
+		characterization='N/A';
+	end
+	if length(characterization)>15,
+		characterization=[characterization(1:12) '...'];
+    end
+    
+    str = characterization;
+	
+end% }}}
+
+function str = cell_display(field)
+
+	%initialization
+	string='{';
+
+	%go through the cell and fill string
+	if length(field)<5;
+		for i=1:length(field),
+			if ischar(field{i}),
+				string=[string ''''  field{i} ''','];
+			elseif (isnumeric(field{i}) & length(field{i})==1)
+				string=[string num2str(field{i}) ',' ];
+			else
+				string='{';
+				break
+			end
+		end
+	end
+	if strcmp(string,'{'),
+		string=['(' num2str(size(field,1)) 'x' num2str(size(field,2)) ')'];
+	else
+		string=[string(1:end-1) '}'];
+    end
+    str = string;
+    
+    %disp(sprintf(string));
+end
+
+function str = struct_display(field) % {{{
+
+	if ~isempty(fields(field))
+		displayunit('(structure)'),
+
+		structure_fields=fields(field);
+
+		for i=1:length(structure_fields),
+
+			%get current field
+			sfield=field.(structure_fields{i});
+
+			%display value
+			%parsedisplay(sfield);
+            str = sfield;
+		end
+
+	else
+		%displayunit('N/A'),
+        str = 'N/A';
+	end
+end% }}}
Index: /issm/trunk/src/m/solve/createxml.m
===================================================================
--- /issm/trunk/src/m/solve/createxml.m	(revision 17806)
+++ /issm/trunk/src/m/solve/createxml.m	(revision 17806)
@@ -0,0 +1,42 @@
+function createxml(xmlfilename,md)
+%EXTRUDEXML - output an XML file compatible with inishell for automatic gui generation
+%
+%   The routine creates an XML file that list fields from the underlying classes 
+%   in model, and that can be use to render a GUI using the java code inishell
+%
+%   Usage:
+%      createxml(md,xmlfilename)
+
+disp(['creating XML file ' xmlfilename]);
+
+%open file for binary writing
+fid=fopen(xmlfilename,'w');
+if fid==-1,
+	error(['extrudexml error message: could not open ' xmlfilename,' file for ASCII writing']);
+end
+
+%Go through all model fields: check that it is a class and call checkconsistency
+fields=properties('model');
+fprintf(fid, '<inishell_config application="ISSM prototype">\n\n'); % require header for xml file
+for i=1:length(fields), 
+	field=fields{i};
+
+	%Some properties do not need to XML rendered
+	if ismember(field,{'results' 'radaroverlay' 'toolkits' 'private'}),
+		continue;
+	end
+
+	%Check that current field is an object
+	if ~isobject(md.(field))
+		error(['field ''' char(field) ''' is not an object']);
+	end
+
+	%Create XML file for this subclass
+	createxml(md.(field),fid);
+end
+fprintf(fid, '\n\n</inishell_config>'); % require footer for xml file
+%close file
+st=fclose(fid);
+if st==-1,
+	error(['createxml error message: could not close file ' xmlfilename]);
+end
Index: /issm/trunk/src/m/solve/loadresultsfromcluster.py
===================================================================
--- /issm/trunk/src/m/solve/loadresultsfromcluster.py	(revision 17805)
+++ /issm/trunk/src/m/solve/loadresultsfromcluster.py	(revision 17806)
@@ -1,6 +1,6 @@
 import os
 import socket
-from MatlabFuncs import *
-from loadresultsfromdisk import *
+import MatlabFuncs as m
+from loadresultsfromdisk import loadresultsfromdisk
 
 def loadresultsfromcluster(md,runtimename=False):
@@ -41,10 +41,10 @@
 		os.remove(md.miscellaneous.name+'.errlog')
 		os.remove(md.miscellaneous.name+'.outbin')
-		if not ispc():
+		if not m.ispc():
 			os.remove(md.private.runtimename+'.tar.gz')
 
 	#erase input file if run was carried out on same platform.
-	hostname=socket.gethostname().lower().split('.')[0]
-	if strcmpi(hostname,cluster.name):
+	hostname=socket.gethostname()
+	if m.strcmpi(hostname,cluster.name):
 		if md.qmu.isdakota:
 			os.remove(os.path.join('qmu'+str(os.getpid()),md.miscellaneous.name+'.bin'))
@@ -53,5 +53,5 @@
 			os.remove(md.miscellaneous.name+'.bin')
 			os.remove(md.miscellaneous.name+'.toolkits')
-			if not ispc():
+			if not m.ispc():
 				os.remove(md.miscellaneous.name+'.queue')
 			else:
Index: /issm/trunk/src/m/solve/loadresultsfromdisk.py
===================================================================
--- /issm/trunk/src/m/solve/loadresultsfromdisk.py	(revision 17805)
+++ /issm/trunk/src/m/solve/loadresultsfromdisk.py	(revision 17806)
@@ -1,7 +1,7 @@
 import os
-from results import *
-from parseresultsfromdisk import *
+from results import results
+from parseresultsfromdisk import parseresultsfromdisk
 from EnumToString import EnumToString
-from MatlabFuncs import *
+import MatlabFuncs as m
 
 def loadresultsfromdisk(md,filename):
@@ -53,5 +53,5 @@
 
 		#if only one solution, extract it from list for user friendliness
-		if len(structure) == 1 and not strcmp(structure[0].SolutionType,'TransientSolution'):
+		if len(structure) == 1 and not m.strcmp(structure[0].SolutionType,'TransientSolution'):
 			setattr(md.results,structure[0].SolutionType,structure[0])
 
Index: /issm/trunk/src/m/solve/marshall.m
===================================================================
--- /issm/trunk/src/m/solve/marshall.m	(revision 17805)
+++ /issm/trunk/src/m/solve/marshall.m	(revision 17806)
@@ -8,5 +8,7 @@
 %      marshall(md)
 
-disp(['marshalling file ' md.miscellaneous.name '.bin']);
+if md.verbose.solution,
+	disp(['marshalling file ' md.miscellaneous.name '.bin']);
+end
 
 %open file for binary writing
Index: /issm/trunk/src/m/solve/marshall.py
===================================================================
--- /issm/trunk/src/m/solve/marshall.py	(revision 17805)
+++ /issm/trunk/src/m/solve/marshall.py	(revision 17806)
@@ -1,3 +1,3 @@
-from WriteData import *
+from WriteData import WriteData
 from EnumDefinitions import *
 
Index: /issm/trunk/src/m/solve/parseresultsfromdisk.m
===================================================================
--- /issm/trunk/src/m/solve/parseresultsfromdisk.m	(revision 17805)
+++ /issm/trunk/src/m/solve/parseresultsfromdisk.m	(revision 17806)
@@ -26,22 +26,33 @@
 
 %Read fields until the end of the file.
-result=ReadData(fid);
+result  = ReadData(fid);
+if isempty(result), error(['no results found in binary file ' filename]); end
+counter = 1;
+step    = result.step;
 while ~isempty(result), 
-	%Get time and step
-	results(result.step).step=result.step;
-	results(result.step).time=result.time; 
+
+	%Check step, increase counter if this is a new step
+	if(step~=result.step & result.step>1)
+		counter = counter + 1;
+		step    = result.step;
+	end
 
 	%Add result
-	if (length(results)>=result.step & isfield(results,result.fieldname) & ~strcmp(result.fieldname,'SolutionType')),
-			results(result.step).(result.fieldname)=[ results(result.step).(result.fieldname); result.field];
+	if(result.step==1),
+		index = 1;
 	else
-		results(result.step).(result.fieldname)=result.field;
-	end
+		index = counter;
+	end
+	results(index).step=result.step;
+	if result.time~=-9999,
+		results(index).time=result.time; 
+	end
+	results(index).(result.fieldname)=result.field;
 
 	%read next result
 	try,
-		result=ReadData(fid);
+		result  = ReadData(fid);
 	catch me,
-		disp('WARNING: file corrupted, results partial recovery');
+		disp('WARNING: file corrupted, trying partial recovery');
 		result=[];
 	end
@@ -71,5 +82,7 @@
 	%Get time and step
 	results(result.step).step=result.step;
-	results(result.step).time=result.time; 
+	if result.time~=-9999,
+		results(result.step).time=result.time; 
+	end
 
 	%Add result
@@ -95,5 +108,7 @@
 	%Get time and step
 	results(result.step).step=result.step;
-	results(result.step).time=result.time; 
+	if result.time~=-9999,
+		results(result.step).time=result.time; 
+	end
 
 	%Add result
Index: /issm/trunk/src/m/solve/parseresultsfromdisk.py
===================================================================
--- /issm/trunk/src/m/solve/parseresultsfromdisk.py	(revision 17805)
+++ /issm/trunk/src/m/solve/parseresultsfromdisk.py	(revision 17806)
@@ -3,5 +3,5 @@
 from collections import OrderedDict
 import results as resultsclass
-from MatlabFuncs import *
+import MatlabFuncs as m
 
 def parseresultsfromdisk(filename,iosplit):
@@ -50,5 +50,5 @@
 	
 		#Add result
-		if hasattr(results[result['step']-1],result['fieldname']) and not strcmp(result['fieldname'],'SolutionType'):
+		if hasattr(results[result['step']-1],result['fieldname']) and not m.strcmp(result['fieldname'],'SolutionType'):
 			setattr(results[result['step']-1],result['fieldname'],numpy.vstack((getattr(results[result['step']-1],result['fieldname']),result['field'])))
 		else:
@@ -162,25 +162,25 @@
 		#Process units here FIXME: this should not be done here!
 		yts=365.0*24.0*3600.0
-		if strcmp(fieldname,'BalancethicknessThickeningRate'):
-			field = field*yts
-		elif strcmp(fieldname,'Time'):
+		if m.strcmp(fieldname,'BalancethicknessThickeningRate'):
+			field = field*yts
+		elif m.strcmp(fieldname,'Time'):
 			field = field/yts
-		elif strcmp(fieldname,'HydrologyWaterVx'):
-			field = field*yts
-		elif strcmp(fieldname,'HydrologyWaterVy'):
-			field = field*yts
-		elif strcmp(fieldname,'Vx'):
-			field = field*yts
-		elif strcmp(fieldname,'Vy'):
-			field = field*yts
-		elif strcmp(fieldname,'Vz'):
-			field = field*yts
-		elif strcmp(fieldname,'Vel'):
-			field = field*yts
-		elif strcmp(fieldname,'BasalforcingsMeltingRate'):
-			field = field*yts
-		elif strcmp(fieldname,'TotalSmb'):
+		elif m.strcmp(fieldname,'HydrologyWaterVx'):
+			field = field*yts
+		elif m.strcmp(fieldname,'HydrologyWaterVy'):
+			field = field*yts
+		elif m.strcmp(fieldname,'Vx'):
+			field = field*yts
+		elif m.strcmp(fieldname,'Vy'):
+			field = field*yts
+		elif m.strcmp(fieldname,'Vz'):
+			field = field*yts
+		elif m.strcmp(fieldname,'Vel'):
+			field = field*yts
+		elif m.strcmp(fieldname,'BasalforcingsMeltingRate'):
+			field = field*yts
+		elif m.strcmp(fieldname,'TotalSmb'):
 			field = field/10.**12.*yts #(GigaTon/year)
-		elif strcmp(fieldname,'SurfaceforcingsMassBalance'):
+		elif m.strcmp(fieldname,'SurfaceforcingsMassBalance'):
 			field = field*yts
 
Index: sm/trunk/src/m/solve/process_solve_options.m
===================================================================
--- /issm/trunk/src/m/solve/process_solve_options.m	(revision 17805)
+++ 	(revision )
@@ -1,41 +1,0 @@
-function outoptions=process_solve_options(options)
-%DEFAULT_SOLVE_OPTIONS - set up default options for solve phase
-%
-%   Usage:
-%      options=process_solve_options(options)
-%
-%   See also: SOLVE
-
-%solution_type: check on this option, error out otherwise
-solution_type=getfieldvalue(options,'solution_type');
-if ~ismember(solution_type,[StressbalanceSolutionEnum(),MasstransportSolutionEnum(),ThermalSolutionEnum(),...
-		SteadystateSolutionEnum(),TransientSolutionEnum(),...
-		BalancethicknessSolutionEnum(),BalancethicknessSoftSolutionEnum(),...
-		BalancevelocitySolutionEnum(),BedSlopeSolutionEnum(),...
-		SurfaceSlopeSolutionEnum(),HydrologySolutionEnum(),FlaimSolutionEnum(),GiaSolutionEnum(),DamageEvolutionSolutionEnum()]),
-	error(['process_solve_options error message: solution_type ' EnumToString(solution_type) ' not supported yet!']);
-end
-outoptions.solution_type=solution_type;
-
-outoptions.upload=getfieldvalue(options,'upload','off');
-outoptions.batch=getfieldvalue(options,'batch','no');
-outoptions.loadonly=getfieldvalue(options,'loadonly',false);
-outoptions.directory=getfieldvalue(options,'directory','');
-
-%  process qmu arguments
-outoptions.qmudir=getfieldvalue(options,'qmudir',['qmu' num2str(feature('GetPid'))]);  % qmudir =['qmu_' datestr(now,'yyyymmdd_HHMMSS')];
-outoptions.qmufile=getfieldvalue(options,'qmufile','qmu');% qmufile cannot be changed unless ????script.sh is also changed
-outoptions.overwrite=getfieldvalue(options,'overwrite','n');
-outoptions.keep=getfieldvalue(options,'keep','n');
-outoptions.ivar=getfieldvalue(options,'ivar',1);
-outoptions.iresp=getfieldvalue(options,'iresp',1);
-outoptions.imethod=getfieldvalue(options,'imethod',1);
-outoptions.iparams=getfieldvalue(options,'iparams',1);
-outoptions.runmpi=getfieldvalue(options,'runmpi',false);
-
-%  process flaim arguments
-outoptions.fmdir=getfieldvalue(options,'fmdir',['fm' num2str(feature('GetPid'))]);
-outoptions.overwrite=getfieldvalue(options,'overwrite','n');
-outoptions.keep=getfieldvalue(options,'keep','y');
-outoptions.latsgn=getfieldvalue(options,'latsgn',0);
-outoptions.cmap=getfieldvalue(options,'cmap',[]);
Index: sm/trunk/src/m/solve/process_solve_options.py
===================================================================
--- /issm/trunk/src/m/solve/process_solve_options.py	(revision 17805)
+++ 	(revision )
@@ -1,52 +1,0 @@
-import os
-from collections import OrderedDict
-from EnumDefinitions import *
-from EnumToString import EnumToString
-
-def process_solve_options(options):
-	"""
-	DEFAULT_SOLVE_OPTIONS - set up default options for solve phase
- 
-	   Usage:
-	      options=process_solve_options(options)
- 
-	   See also: SOLVE
-	"""
-
-	outoptions=OrderedDict()
-
-	#solution_type: check on this option, error out otherwise
-	solution_type=options.getfieldvalue('solution_type')
-	if solution_type not in (StressbalanceSolutionEnum(),MasstransportSolutionEnum(),ThermalSolutionEnum(),\
-			SteadystateSolutionEnum(),TransientSolutionEnum(),\
-			BalancethicknessSolutionEnum(),BalancevelocitySolutionEnum(),\
-			BedSlopeSolutionEnum(),SurfaceSlopeSolutionEnum(),\
-			HydrologySolutionEnum(),FlaimSolutionEnum(),GiaSolutionEnum()):
-		raise ValueError("process_solve_options error message: solution_type '%s' not supported yet!" % EnumToString(solution_type)[0])
-	outoptions['solution_type']=solution_type
-
-	outoptions['upload']=options.getfieldvalue('upload','off')
-	outoptions['batch']=options.getfieldvalue('batch','no')
-	outoptions['loadonly']=options.getfieldvalue('loadonly',False)
-	outoptions['directory']=options.getfieldvalue('directory','')
-
-	#  process qmu arguments
-	outoptions['qmudir']=options.getfieldvalue('qmudir','qmu'+str(os.getpid()))
-	outoptions['qmufile']=options.getfieldvalue('qmufile','qmu')    # qmufile cannot be changed unless ????script.sh is also changed
-	outoptions['overwrite']=options.getfieldvalue('overwrite','n')
-	outoptions['keep']=options.getfieldvalue('keep','n')
-	outoptions['ivar']=options.getfieldvalue('ivar',1)
-	outoptions['iresp']=options.getfieldvalue('iresp',1)
-	outoptions['imethod']=options.getfieldvalue('imethod',1)
-	outoptions['iparams']=options.getfieldvalue('iparams',1)
-	outoptions['runmpi']=options.getfieldvalue('runmpi',False)
-
-	#  process flaim arguments
-	outoptions['fmdir']=options.getfieldvalue('fmdir','fm'+str(os.getpid()))
-	outoptions['overwrite']=options.getfieldvalue('overwrite','n')
-	outoptions['keep']=options.getfieldvalue('keep','y')
-	outoptions['latsgn']=options.getfieldvalue('latsgn',0)
-	outoptions['cmap']=options.getfieldvalue('cmap',[])
-
-	return outoptions
-
Index: /issm/trunk/src/m/solve/solve.m
===================================================================
--- /issm/trunk/src/m/solve/solve.m	(revision 17805)
+++ /issm/trunk/src/m/solve/solve.m	(revision 17806)
@@ -11,5 +11,5 @@
 %		 - ThermalSolutionEnum
 %		 - SteadystateSolutionEnum
-%		 - TransientSolutionEnum...
+%		 - TransientSolutionEnum
 %		 - BalancethicknessSolutionEnum
 %		 - BedSlopeSolutionEnum
@@ -19,5 +19,6 @@
 %
 %  extra options:
-%      - loadonly : does not solve. only load results
+%      - loadonly    : does not solve. only load results
+%      - runtimename : true or false (default is true), makes name unique
 %
 %   Examples:
@@ -25,13 +26,17 @@
 
 %recover and process solve options
-options=pairoptions(varargin{:},'solution_type',solutionenum);
-options=process_solve_options(options);
+if ~strncmp(fliplr(EnumToString(solutionenum)),fliplr('Solution'),8),
+	error(['solutionenum ' EnumToString(solutionenum) ' not supported!']);
+end
+options=pairoptions(varargin{:},'solutionenum',solutionenum);
 
 %recover some fields
-md.private.solution=options.solution_type;
+md.private.solution=solutionenum;
 cluster=md.cluster;
 
 %check model consistency
-disp('checking model consistency');
+if md.verbose.solution,
+	disp('checking model consistency');
+end
 if (solutionenum == FlaimSolutionEnum())
 	md.private.isconsistent=true;
@@ -46,6 +51,10 @@
 
 %First, build a runtime name that is unique
-c=clock;
-md.private.runtimename=sprintf('%s-%02i-%02i-%04i-%02i-%02i-%02i-%i',md.miscellaneous.name,c(2),c(3),c(1),c(4),c(5),floor(c(6)),feature('GetPid'));
+if getfieldvalue(options,'runtimename',true),
+	c=clock;
+	md.private.runtimename=sprintf('%s-%02i-%02i-%04i-%02i-%02i-%02i-%i',md.miscellaneous.name,c(2),c(3),c(1),c(4),c(5),floor(c(6)),feature('GetPid'));
+else
+	md.private.runtimename=md.miscellaneous.name;
+end
 
 %if running qmu analysis, some preprocessing of dakota files using models
@@ -55,13 +64,18 @@
 end
 
-%flaim analysis
-if (options.solution_type == FlaimSolutionEnum())
+%flaim analysis (To be removed?)
+if (solutionenum == FlaimSolutionEnum())
+	%fmdir     = getfieldvalue(options,'fmdir',['fm' num2str(feature('GetPid'))]);
+	%overwrite = getfieldvalue(options,'overwrite','n');
+	%keep      = getfieldvalue(options,'keep','y');
+	%latsgn    = getfieldvalue(options,'latsgn',0);
+	%cmap      = getfieldvalue(options,'cmap',[]);
 	md=flaim_sol(md,options);
-	md.private.solution=EnumToString(options.solution_type);
+	md.private.solution=EnumToString(solutionenum);
 	return;
 end
 
 %Do we load results only?
-if options.loadonly,  
+if getfieldvalue(options,'loadonly',false),
 	md=loadresultsfromcluster(md);
 	return;
@@ -74,7 +88,9 @@
 
 %Stop here if batch mode
-if strcmpi(options.batch,'yes')
-	disp('batch mode requested: not launching job interactively');
-	disp('launch solution sequence on remote cluster by hand');
+if strcmpi(getfieldvalue(options,'batch','no'),'yes')
+	if md.verbose.solution,
+		disp('batch mode requested: not launching job interactively');
+		disp('launch solution sequence on remote cluster by hand');
+	end
 	return;
 end
@@ -94,10 +110,4 @@
 LaunchQueueJob(cluster,md.miscellaneous.name,md.private.runtimename,filelist);
 
-%did we even try to run? if so, wait on lock
-if strcmpi(options.upload,'on'),
-	disp('solve done uploading test decks');
-	return;
-end
-
 %wait on lock
 if isnan(md.settings.waitonlock),
@@ -113,5 +123,7 @@
 	%we wait for the done file
 	done=waitonlock(md);
-	disp('loading results from cluster');
+	if md.verbose.solution,
+		disp('loading results from cluster');
+	end
 	md=loadresultsfromcluster(md);
 elseif md.settings.waitonlock==0,
@@ -121,5 +133,5 @@
 %post processes qmu results if necessary
 if md.qmu.isdakota,
-	if ~strncmpi(options.keep,'y',1)
+	if ~strncmpi(getfieldvalue(options,'keep','y'),'y',1)
 		system(['rm -rf qmu' num2str(feature('GetPid'))]);
 	end
Index: /issm/trunk/src/m/solve/solve.py
===================================================================
--- /issm/trunk/src/m/solve/solve.py	(revision 17805)
+++ /issm/trunk/src/m/solve/solve.py	(revision 17806)
@@ -2,12 +2,12 @@
 import os
 import shutil
-from pairoptions import *
-from process_solve_options import *
+from pairoptions import pairoptions
 from EnumDefinitions import *
 from EnumToString import EnumToString
-from ismodelselfconsistent import *
-from marshall import *
-from waitonlock import *
-from loadresultsfromcluster import *
+from ismodelselfconsistent import ismodelselfconsistent
+from marshall import marshall
+from waitonlock import waitonlock
+from loadresultsfromcluster import loadresultsfromcluster
+import MatlabFuncs as m
 
 def solve(md,solutionenum,*args):
@@ -24,5 +24,5 @@
 	      - ThermalSolutionEnum
 	      - SteadystateSolutionEnum
-	      - TransientSolutionEnum...
+	      - TransientSolutionEnum
 	      - BalancethicknessSolutionEnum
 	      - BedSlopeSolutionEnum
@@ -39,9 +39,10 @@
 
 	#recover and process solve options
-	options=pairoptions('solution_type',solutionenum,*args)
-	options=process_solve_options(options)
+	if EnumToString(solutionenum)[0][-8:] != 'Solution':
+		raise ValueError("solutionenum '%s' not supported!" % EnumToString(solutionenum)[0])
+	options=pairoptions('solutionenum',solutionenum,*args)
 
 	#recover some fields
-	md.private.solution=options['solution_type']
+	md.private.solution=solutionenum
 	cluster=md.cluster
 
@@ -67,11 +68,11 @@
 
 	#flaim analysis
-	if options['solution_type'] == FlaimSolutionEnum():
+	if solutionenum == FlaimSolutionEnum():
 		md=flaim_sol(md,options)
-		[md.private.solution]=EnumToString(options['solution_type'])
+		[md.private.solution]=EnumToString(solutionenum)
 		return md
 
 	#Do we load results only?
-	if options['loadonly']:  
+	if options.getfieldvalue('loadonly',False):
 		md=loadresultsfromcluster(md)
 		return md
@@ -83,5 +84,5 @@
 
 	#Stop here if batch mode
-	if strcmpi(options['batch'],'yes'):
+	if m.strcmpi(options.getfieldvalue('batch','no'),'yes'):
 		print 'batch mode requested: not launching job interactively'
 		print 'launch solution sequence on remote cluster by hand'
@@ -94,9 +95,4 @@
 		filelist.append(modelname+'.qmu.in')
 	cluster.LaunchQueueJob(md.miscellaneous.name,md.private.runtimename,filelist)
-
-	#did we even try to run? if so, wait on lock
-	if strcmpi(options['upload'],'on'):
-		print 'solve done uploading test decks'
-		return md
 
 	#wait on lock
@@ -116,3 +112,2 @@
 
 	return md
-
Index: /issm/trunk/src/m/solve/waitonlock.m
===================================================================
--- /issm/trunk/src/m/solve/waitonlock.m	(revision 17805)
+++ /issm/trunk/src/m/solve/waitonlock.m	(revision 17806)
@@ -16,6 +16,13 @@
 timelimit     = md.settings.waitonlock;
 cluster       = md.cluster;
-lockfilename  = [executionpath '/' md.private.runtimename '/' md.miscellaneous.name '.lock'];
-logfilename   = [executionpath '/' md.private.runtimename '/' md.miscellaneous.name '.outlog'];
+
+if isa(cluster,'pfe') && cluster.interactive>0
+	lockfilename  = [executionpath '/Interactive' num2str(cluster.interactive) '/' md.miscellaneous.name '.lock'];
+	logfilename   = [executionpath '/Interactive' num2str(cluster.interactive) '/' md.miscellaneous.name '.outlog'];
+else
+	lockfilename  = [executionpath '/' md.private.runtimename '/' md.miscellaneous.name '.lock'];
+	logfilename   = [executionpath '/' md.private.runtimename '/' md.miscellaneous.name '.outlog'];
+end
+
 
 %If we are using the generic cluster in interactive mode, job is already complete
@@ -54,5 +61,5 @@
 		time=etime(clock,time0)/60;
 	else
-		pause(10);
+		pause(5);
 		time=etime(clock,time0);
 		fprintf('\rchecking for job completion (time: %i min %i sec)      ',floor(time/60),floor(rem(time,60)));
Index: /issm/trunk/src/m/solve/waitonlock.py
===================================================================
--- /issm/trunk/src/m/solve/waitonlock.py	(revision 17805)
+++ /issm/trunk/src/m/solve/waitonlock.py	(revision 17806)
@@ -1,6 +1,6 @@
 import os
-import socket
+from socket import gethostname
 import time
-from MatlabFuncs import *
+import MatlabFuncs as m
 
 def waitonlock(md):
@@ -24,9 +24,9 @@
 
 	#waitonlock will work if the lock is on the same machine only: 
-	if not strcmpi(socket.gethostname().lower().split('.')[0],cluster):
+	if not m.strcmpi(gethostname(),cluster):
 
 		print 'solution launched on remote cluster. log in to detect job completion.'
 		choice=raw_input('Is the job successfully completed? (y/n) ')
-		if not strcmp(choice,'y'): 
+		if not m.strcmp(choice,'y'): 
 			print 'Results not loaded... exiting' 
 			flag=0
Index: /issm/trunk/src/m/solvers/asmoptions.py
===================================================================
--- /issm/trunk/src/m/solvers/asmoptions.py	(revision 17805)
+++ /issm/trunk/src/m/solvers/asmoptions.py	(revision 17806)
@@ -1,3 +1,4 @@
-from pairoptions import *
+import pairoptions
+
 def asmoptions(*args):
 	#ASMOPTIONS - return ASM petsc options
@@ -7,5 +8,5 @@
 	
 	#retrieve options provided in varargin
-	arguments=pairoptions(*args) 
+	arguments=pairoptions.pairoptions(*args) 
 	
 	options=[['toolkit','petsc'],['mat_type','aij'],['ksp_type','gmres'],['pc_type','asm'],['sub_pc_type','lu'],['pc_asm_overlap',3],['ksp_max_it',100],['ksp_rtol',1e-30]];
Index: /issm/trunk/src/m/solvers/bcgsasmoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/bcgsasmoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/bcgsasmoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=bcgsasmoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','bcgs');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'asm');
+end
Index: /issm/trunk/src/m/solvers/bcgsbjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/bcgsbjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/bcgsbjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=bcgsbjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','bcgs');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'bjacobi');
+end
Index: /issm/trunk/src/m/solvers/bcgsgamgoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/bcgsgamgoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/bcgsgamgoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=bcgsgamgoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','bcgs');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'gamg');
+end
Index: /issm/trunk/src/m/solvers/bcgsgasmoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/bcgsgasmoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/bcgsgasmoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=bcgsgasmoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','bcgs');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'gasm');
+end
Index: /issm/trunk/src/m/solvers/bcgshypreoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/bcgshypreoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/bcgshypreoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=bcgshypreoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','bcgs');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'hypre');
+end
Index: /issm/trunk/src/m/solvers/bcgsjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/bcgsjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/bcgsjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=bcgsjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','bcgs');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'jacobi');
+end
Index: /issm/trunk/src/m/solvers/bcgslasmoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/bcgslasmoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/bcgslasmoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=bcgslasmoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','bcgsl');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'asm');
+end
Index: /issm/trunk/src/m/solvers/bcgslbjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/bcgslbjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/bcgslbjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=bcgslbjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','bcgsl');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'bjacobi');
+end
Index: /issm/trunk/src/m/solvers/bcgslgamgoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/bcgslgamgoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/bcgslgamgoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=bcgslgamgoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','bcgsl');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'gamg');
+end
Index: /issm/trunk/src/m/solvers/bcgslgasmoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/bcgslgasmoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/bcgslgasmoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=bcgslgasmoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','bcgsl');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'gasm');
+end
Index: /issm/trunk/src/m/solvers/bcgslhypreoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/bcgslhypreoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/bcgslhypreoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=bcgslhypreoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','bcgsl');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'hypre');
+end
Index: /issm/trunk/src/m/solvers/bcgsljacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/bcgsljacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/bcgsljacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=bcgsljacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','bcgsl');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'jacobi');
+end
Index: /issm/trunk/src/m/solvers/bcgslmgoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/bcgslmgoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/bcgslmgoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=bcgslmgoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','bcgsl');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'mg');
+end
Index: /issm/trunk/src/m/solvers/bcgslpbjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/bcgslpbjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/bcgslpbjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=bcgslpbjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','bcgsl');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'pbjacobi');
+end
Index: /issm/trunk/src/m/solvers/bcgslsoroptions.m
===================================================================
--- /issm/trunk/src/m/solvers/bcgslsoroptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/bcgslsoroptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=bcgslsoroptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','bcgsl');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'sor');
+end
Index: /issm/trunk/src/m/solvers/bcgsmgoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/bcgsmgoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/bcgsmgoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=bcgsmgoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','bcgs');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'mg');
+end
Index: /issm/trunk/src/m/solvers/bcgspbjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/bcgspbjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/bcgspbjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=bcgspbjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','bcgs');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'pbjacobi');
+end
Index: /issm/trunk/src/m/solvers/bcgssoroptions.m
===================================================================
--- /issm/trunk/src/m/solvers/bcgssoroptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/bcgssoroptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=bcgssoroptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','bcgs');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'sor');
+end
Index: /issm/trunk/src/m/solvers/bicgasmoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/bicgasmoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/bicgasmoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=bicgasmoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','bicg');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'asm');
+end
Index: /issm/trunk/src/m/solvers/bicgbjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/bicgbjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/bicgbjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=bicgbjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','bicg');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'bjacobi');
+end
Index: /issm/trunk/src/m/solvers/bicggamgoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/bicggamgoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/bicggamgoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=bicggamgoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','bicg');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'gamg');
+end
Index: /issm/trunk/src/m/solvers/bicggasmoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/bicggasmoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/bicggasmoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=bicggasmoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','bicg');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'gasm');
+end
Index: /issm/trunk/src/m/solvers/bicghypreoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/bicghypreoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/bicghypreoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=bicghypreoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','bicg');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'hypre');
+end
Index: /issm/trunk/src/m/solvers/bicgjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/bicgjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/bicgjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=bicgjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','bicg');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'jacobi');
+end
Index: /issm/trunk/src/m/solvers/bicgmgoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/bicgmgoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/bicgmgoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=bicgmgoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','bicg');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'mg');
+end
Index: /issm/trunk/src/m/solvers/bicgpbjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/bicgpbjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/bicgpbjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=bicgpbjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','bicg');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'pbjacobi');
+end
Index: /issm/trunk/src/m/solvers/bicgsoroptions.m
===================================================================
--- /issm/trunk/src/m/solvers/bicgsoroptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/bicgsoroptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=bicgsoroptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','bicg');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'sor');
+end
Index: /issm/trunk/src/m/solvers/cgasmoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/cgasmoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/cgasmoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=cgasmoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','cg');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'asm');
+end
Index: /issm/trunk/src/m/solvers/cgbjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/cgbjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/cgbjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=cgbjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','cg');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'bjacobi');
+end
Index: /issm/trunk/src/m/solvers/cggamgoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/cggamgoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/cggamgoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=cggamgoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','cg');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'gamg');
+end
Index: /issm/trunk/src/m/solvers/cggasmoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/cggasmoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/cggasmoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=cggasmoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','cg');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'gasm');
+end
Index: /issm/trunk/src/m/solvers/cghypreoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/cghypreoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/cghypreoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=cghypreoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','cg');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'hypre');
+end
Index: /issm/trunk/src/m/solvers/cgjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/cgjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/cgjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=cgjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','cg');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'jacobi');
+end
Index: /issm/trunk/src/m/solvers/cgmgoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/cgmgoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/cgmgoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=cgmgoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','cg');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'mg');
+end
Index: /issm/trunk/src/m/solvers/cgneasmoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/cgneasmoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/cgneasmoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=cgneasmoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','cgne');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'asm');
+end
Index: /issm/trunk/src/m/solvers/cgnebjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/cgnebjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/cgnebjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=cgnebjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','cgne');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'bjacobi');
+end
Index: /issm/trunk/src/m/solvers/cgnegamgoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/cgnegamgoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/cgnegamgoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=cgnegamgoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','cgne');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'gamg');
+end
Index: /issm/trunk/src/m/solvers/cgnegasmoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/cgnegasmoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/cgnegasmoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=cgnegasmoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','cgne');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'gasm');
+end
Index: /issm/trunk/src/m/solvers/cgnehypreoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/cgnehypreoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/cgnehypreoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=cgnehypreoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','cgne');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'hypre');
+end
Index: /issm/trunk/src/m/solvers/cgnejacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/cgnejacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/cgnejacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=cgnejacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','cgne');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'jacobi');
+end
Index: /issm/trunk/src/m/solvers/cgnemgoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/cgnemgoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/cgnemgoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=cgnemgoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','cgne');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'mg');
+end
Index: /issm/trunk/src/m/solvers/cgnepbjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/cgnepbjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/cgnepbjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=cgnepbjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','cgne');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'pbjacobi');
+end
Index: /issm/trunk/src/m/solvers/cgnesoroptions.m
===================================================================
--- /issm/trunk/src/m/solvers/cgnesoroptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/cgnesoroptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=cgnesoroptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','cgne');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'sor');
+end
Index: /issm/trunk/src/m/solvers/cgpbjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/cgpbjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/cgpbjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=cgpbjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','cg');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'pbjacobi');
+end
Index: /issm/trunk/src/m/solvers/cgsasmoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/cgsasmoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/cgsasmoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=cgsasmoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','cgs');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'asm');
+end
Index: /issm/trunk/src/m/solvers/cgsbjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/cgsbjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/cgsbjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=cgsbjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','cgs');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'bjacobi');
+end
Index: /issm/trunk/src/m/solvers/cgsgamgoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/cgsgamgoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/cgsgamgoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=cgsgamgoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','cgs');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'gamg');
+end
Index: /issm/trunk/src/m/solvers/cgsgasmoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/cgsgasmoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/cgsgasmoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=cgsgasmoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','cgs');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'gasm');
+end
Index: /issm/trunk/src/m/solvers/cgshypreoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/cgshypreoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/cgshypreoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=cgshypreoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','cgs');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'hypre');
+end
Index: /issm/trunk/src/m/solvers/cgsjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/cgsjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/cgsjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=cgsjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','cgs');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'jacobi');
+end
Index: /issm/trunk/src/m/solvers/cgsmgoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/cgsmgoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/cgsmgoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=cgsmgoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','cgs');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'mg');
+end
Index: /issm/trunk/src/m/solvers/cgsoroptions.m
===================================================================
--- /issm/trunk/src/m/solvers/cgsoroptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/cgsoroptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=cgsoroptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','cg');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'sor');
+end
Index: /issm/trunk/src/m/solvers/cgspbjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/cgspbjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/cgspbjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=cgspbjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','cgs');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'pbjacobi');
+end
Index: /issm/trunk/src/m/solvers/cgssoroptions.m
===================================================================
--- /issm/trunk/src/m/solvers/cgssoroptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/cgssoroptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=cgssoroptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','cgs');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'sor');
+end
Index: /issm/trunk/src/m/solvers/conditionnumberoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/conditionnumberoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/conditionnumberoptions.m	(revision 17806)
@@ -0,0 +1,22 @@
+function cn=conditionnumberoptions(varargin)
+%MULTIGRIDOPTIONS - use Multigrid 
+%
+%   Usage:
+%      options=mgoptions;
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+cn=struct();
+cn..toolkit='petsc';
+
+%default  options
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+	cn.mat_type=getfieldvalue(options,'mat_type','mpiaij');
+	cn.ksp_type=getfieldvalue(options,'ksp_type','gmres');
+	cn.pc_type=getfieldvalue(options,'pc_type','none');
+	cn.ksp_monitor_singular_value=getfieldvalue(options,'ksp_monitor_singular_value','');
+	cn.ksp_gmres_restart=getfieldvalue(options,'ksp_gmres_restart',1000);
+	cn.info=getfieldvalue(options,'info','');
+	cn.log_summary=getfieldvalue(options,'log_summary','');
+end
Index: /issm/trunk/src/m/solvers/crasmoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/crasmoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/crasmoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=crasmoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','cr');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'asm');
+end
Index: /issm/trunk/src/m/solvers/crbjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/crbjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/crbjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=crbjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','cr');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'bjacobi');
+end
Index: /issm/trunk/src/m/solvers/crgamgoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/crgamgoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/crgamgoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=crgamgoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','cr');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'gamg');
+end
Index: /issm/trunk/src/m/solvers/crgasmoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/crgasmoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/crgasmoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=crgasmoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','cr');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'gasm');
+end
Index: /issm/trunk/src/m/solvers/crhypreoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/crhypreoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/crhypreoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=crhypreoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','cr');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'hypre');
+end
Index: /issm/trunk/src/m/solvers/crjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/crjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/crjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=crjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','cr');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'jacobi');
+end
Index: /issm/trunk/src/m/solvers/crmgoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/crmgoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/crmgoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=crmgoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','cr');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'mg');
+end
Index: /issm/trunk/src/m/solvers/crpbjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/crpbjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/crpbjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=crpbjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','cr');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'pbjacobi');
+end
Index: /issm/trunk/src/m/solvers/crsoroptions.m
===================================================================
--- /issm/trunk/src/m/solvers/crsoroptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/crsoroptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=crsoroptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','cr');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'sor');
+end
Index: /issm/trunk/src/m/solvers/dgmresasmoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/dgmresasmoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/dgmresasmoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=dgmresasmoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','dgmres');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'asm');
+end
Index: /issm/trunk/src/m/solvers/dgmresbjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/dgmresbjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/dgmresbjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=dgmresbjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','dgmres');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'bjacobi');
+end
Index: /issm/trunk/src/m/solvers/dgmresgamgoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/dgmresgamgoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/dgmresgamgoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=dgmresgamgoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','dgmres');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'gamg');
+end
Index: /issm/trunk/src/m/solvers/dgmresgasmoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/dgmresgasmoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/dgmresgasmoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=dgmresgasmoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','dgmres');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'gasm');
+end
Index: /issm/trunk/src/m/solvers/dgmreshypreoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/dgmreshypreoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/dgmreshypreoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=dgmreshypreoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','dgmres');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'hypre');
+end
Index: /issm/trunk/src/m/solvers/dgmresjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/dgmresjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/dgmresjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=dgmresjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','dgmres');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'jacobi');
+end
Index: /issm/trunk/src/m/solvers/dgmresmgoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/dgmresmgoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/dgmresmgoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=dgmresmgoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','dgmres');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'mg');
+end
Index: /issm/trunk/src/m/solvers/dgmrespbjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/dgmrespbjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/dgmrespbjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=dgmrespbjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','dgmres');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'pbjacobi');
+end
Index: /issm/trunk/src/m/solvers/dgmressoroptions.m
===================================================================
--- /issm/trunk/src/m/solvers/dgmressoroptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/dgmressoroptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=dgmressoroptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','dgmres');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'sor');
+end
Index: /issm/trunk/src/m/solvers/fgmresasmoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/fgmresasmoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/fgmresasmoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=fgmresasmoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','fgmres');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'asm');
+end
Index: /issm/trunk/src/m/solvers/fgmresbjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/fgmresbjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/fgmresbjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=fgmresbjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','fgmres');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'bjacobi');
+end
Index: /issm/trunk/src/m/solvers/fgmresgamgoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/fgmresgamgoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/fgmresgamgoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=fgmresgamgoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','fgmres');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'gamg');
+end
Index: /issm/trunk/src/m/solvers/fgmresgasmoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/fgmresgasmoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/fgmresgasmoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=fgmresgasmoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','fgmres');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'gasm');
+end
Index: /issm/trunk/src/m/solvers/fgmreshypreoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/fgmreshypreoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/fgmreshypreoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=fgmreshypreoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','fgmres');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'hypre');
+end
Index: /issm/trunk/src/m/solvers/fgmresjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/fgmresjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/fgmresjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=fgmresjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','fgmres');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'jacobi');
+end
Index: /issm/trunk/src/m/solvers/fgmresmgoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/fgmresmgoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/fgmresmgoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=fgmresmgoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','fgmres');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'mg');
+end
Index: /issm/trunk/src/m/solvers/fgmrespbjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/fgmrespbjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/fgmrespbjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=fgmrespbjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','fgmres');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'pbjacobi');
+end
Index: /issm/trunk/src/m/solvers/fgmressoroptions.m
===================================================================
--- /issm/trunk/src/m/solvers/fgmressoroptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/fgmressoroptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=fgmressoroptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','fgmres');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'sor');
+end
Index: /issm/trunk/src/m/solvers/gcrasmoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/gcrasmoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/gcrasmoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=gcrasmoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','gcr');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'asm');
+end
Index: /issm/trunk/src/m/solvers/gcrbjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/gcrbjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/gcrbjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=gcrbjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=IssmConfig('_PETSC_MAJOR_');
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','gcr');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'bjacobi');
+end
Index: /issm/trunk/src/m/solvers/gcrgamgoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/gcrgamgoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/gcrgamgoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=gcrgamgoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','gcr');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'gamg');
+end
Index: /issm/trunk/src/m/solvers/gcrgasmoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/gcrgasmoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/gcrgasmoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=gcrgasmoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','gcr');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'gasm');
+end
Index: /issm/trunk/src/m/solvers/gcrhypreoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/gcrhypreoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/gcrhypreoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=gcrhypreoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','gcr');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'hypre');
+end
Index: /issm/trunk/src/m/solvers/gcrjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/gcrjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/gcrjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=gcrjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','gcr');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'jacobi');
+end
Index: /issm/trunk/src/m/solvers/gcrmgoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/gcrmgoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/gcrmgoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=gcrmgoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','gcr');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'mg');
+end
Index: /issm/trunk/src/m/solvers/gcrpbjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/gcrpbjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/gcrpbjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=gcrpbjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','gcr');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'pbjacobi');
+end
Index: /issm/trunk/src/m/solvers/gcrsoroptions.m
===================================================================
--- /issm/trunk/src/m/solvers/gcrsoroptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/gcrsoroptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=gcrsoroptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','gcr');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'sor');
+end
Index: /issm/trunk/src/m/solvers/gltrasmoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/gltrasmoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/gltrasmoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=gltrasmoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','gltr');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'asm');
+end
Index: /issm/trunk/src/m/solvers/gltrbjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/gltrbjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/gltrbjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=gltrbjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','gltr');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'bjacobi');
+end
Index: /issm/trunk/src/m/solvers/gltrgamgoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/gltrgamgoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/gltrgamgoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=gltrgamgoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','gltr');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'gamg');
+end
Index: /issm/trunk/src/m/solvers/gltrgasmoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/gltrgasmoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/gltrgasmoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=gltrgasmoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','gltr');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'gasm');
+end
Index: /issm/trunk/src/m/solvers/gltrhypreoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/gltrhypreoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/gltrhypreoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=gltrhypreoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','gltr');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'hypre');
+end
Index: /issm/trunk/src/m/solvers/gltrjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/gltrjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/gltrjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=gltrjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','gltr');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'jacobi');
+end
Index: /issm/trunk/src/m/solvers/gltrmgoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/gltrmgoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/gltrmgoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=gltrmgoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','gltr');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'mg');
+end
Index: /issm/trunk/src/m/solvers/gltrpbjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/gltrpbjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/gltrpbjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=gltrpbjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','gltr');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'pbjacobi');
+end
Index: /issm/trunk/src/m/solvers/gltrsoroptions.m
===================================================================
--- /issm/trunk/src/m/solvers/gltrsoroptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/gltrsoroptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=gltrsoroptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','gltr');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'sor');
+end
Index: /issm/trunk/src/m/solvers/gmresasmoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/gmresasmoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/gmresasmoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=gmresasmoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','gmres');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'asm');
+end
Index: /issm/trunk/src/m/solvers/gmresbjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/gmresbjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/gmresbjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=gmresbjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','gmres');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'bjacobi');
+end
Index: /issm/trunk/src/m/solvers/gmresgamgoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/gmresgamgoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/gmresgamgoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=gmresgamgoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','gmres');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'gamg');
+end
Index: /issm/trunk/src/m/solvers/gmresgasmoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/gmresgasmoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/gmresgasmoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=gmresgasmoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','gmres');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'gasm');
+end
Index: /issm/trunk/src/m/solvers/gmreshypreoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/gmreshypreoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/gmreshypreoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=gmreshypreoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','gmres');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'hypre');
+end
Index: /issm/trunk/src/m/solvers/gmresjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/gmresjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/gmresjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=gmresjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=IssmConfig('_PETSC_MAJOR_');
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','gmres');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'jacobi');
+end
Index: /issm/trunk/src/m/solvers/gmresmgoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/gmresmgoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/gmresmgoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=gmresmgoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','gmres');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'mg');
+end
Index: /issm/trunk/src/m/solvers/gmrespbjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/gmrespbjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/gmrespbjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=gmrespbjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','gmres');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'pbjacobi');
+end
Index: /issm/trunk/src/m/solvers/gmressoroptions.m
===================================================================
--- /issm/trunk/src/m/solvers/gmressoroptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/gmressoroptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=gmressoroptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','gmres');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'sor');
+end
Index: /issm/trunk/src/m/solvers/ibcgsasmoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/ibcgsasmoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/ibcgsasmoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=ibcgsasmoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','ibcgs');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'asm');
+end
Index: /issm/trunk/src/m/solvers/ibcgsbjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/ibcgsbjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/ibcgsbjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=ibcgsbjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','ibcgs');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'bjacobi');
+end
Index: /issm/trunk/src/m/solvers/ibcgsgamgoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/ibcgsgamgoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/ibcgsgamgoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=ibcgsgamgoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','ibcgs');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'gamg');
+end
Index: /issm/trunk/src/m/solvers/ibcgsgasmoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/ibcgsgasmoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/ibcgsgasmoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=ibcgsgasmoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','ibcgs');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'gasm');
+end
Index: /issm/trunk/src/m/solvers/ibcgshypreoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/ibcgshypreoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/ibcgshypreoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=ibcgshypreoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','ibcgs');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'hypre');
+end
Index: /issm/trunk/src/m/solvers/ibcgsjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/ibcgsjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/ibcgsjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=ibcgsjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','ibcgs');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'jacobi');
+end
Index: /issm/trunk/src/m/solvers/ibcgsmgoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/ibcgsmgoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/ibcgsmgoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=ibcgsmgoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','ibcgs');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'mg');
+end
Index: /issm/trunk/src/m/solvers/ibcgspbjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/ibcgspbjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/ibcgspbjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=ibcgspbjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','ibcgs');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'pbjacobi');
+end
Index: /issm/trunk/src/m/solvers/ibcgssoroptions.m
===================================================================
--- /issm/trunk/src/m/solvers/ibcgssoroptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/ibcgssoroptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=ibcgssoroptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','ibcgs');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'sor');
+end
Index: /issm/trunk/src/m/solvers/iluasmoptions.py
===================================================================
--- /issm/trunk/src/m/solvers/iluasmoptions.py	(revision 17805)
+++ /issm/trunk/src/m/solvers/iluasmoptions.py	(revision 17806)
@@ -1,4 +1,4 @@
 from collections import OrderedDict
-from pairoptions import *
+import pairoptions
 
 def iluasmoptions(*args):
@@ -11,5 +11,5 @@
 			 
 	#retrieve options provided in varargin
-	options=pairoptions(*args)
+	options=pairoptions.pairoptions(*args)
 	iluasm=OrderedDict()
 
Index: /issm/trunk/src/m/solvers/issmgslsolver.py
===================================================================
--- /issm/trunk/src/m/solvers/issmgslsolver.py	(revision 17805)
+++ /issm/trunk/src/m/solvers/issmgslsolver.py	(revision 17806)
@@ -1,3 +1,4 @@
-from pairoptions import *
+import pairoptions
+
 def issmgslsolver(*args):
 	#ISSMSOLVE - return issm solver options
@@ -7,5 +8,5 @@
 	
 	#retrieve options provided in varargin
-	arguments=pairoptions(*args) 
+	arguments=pairoptions.pairoptions(*args) 
 	
 	options=[['toolkit','issm'],['mat_type','dense'],['vec_type','seq'],['solver_type','gsl']];
Index: /issm/trunk/src/m/solvers/issmmumpssolver.py
===================================================================
--- /issm/trunk/src/m/solvers/issmmumpssolver.py	(revision 17805)
+++ /issm/trunk/src/m/solvers/issmmumpssolver.py	(revision 17806)
@@ -1,3 +1,4 @@
-from pairoptions import *
+import pairoptions
+
 def issmmumpssolver(*args):
 	#ISSMSOLVE - return issm solver options
@@ -7,5 +8,5 @@
 	
 	#retrieve options provided in varargin
-	arguments=pairoptions(*args) 
+	arguments=pairoptions.pairoptions(*args) 
 	
 	options=[['toolkit','issm'],['mat_type','mpidense'],['vec_type','mpi'],['solver_type','mumps']];
Index: /issm/trunk/src/m/solvers/jacobiasmoptions.py
===================================================================
--- /issm/trunk/src/m/solvers/jacobiasmoptions.py	(revision 17805)
+++ /issm/trunk/src/m/solvers/jacobiasmoptions.py	(revision 17806)
@@ -1,3 +1,4 @@
-from pairoptions import *
+import pairoptions
+
 def jacobiasmoptions(*args):
 	#ASMOPTIONS - return Additive Shwartz Method with Jacobi preconditioner petsc options
@@ -7,5 +8,5 @@
 	
 	#retrieve options provided in varargin
-	arguments=pairoptions(*args) 
+	arguments=pairoptions.pairoptions(*args) 
 	
 	options=[['toolkit','petsc'],['mat_type','aij'],['ksp_type','gmres'],['pc_type','asm'],['sub_pc_type','jacobi'],['pc_asm_overlap',3],['ksp_max_it',100],['ksp_rtol',1e-15]];
Index: /issm/trunk/src/m/solvers/jacobicgoptions.py
===================================================================
--- /issm/trunk/src/m/solvers/jacobicgoptions.py	(revision 17805)
+++ /issm/trunk/src/m/solvers/jacobicgoptions.py	(revision 17806)
@@ -1,3 +1,4 @@
-from pairoptions import *
+import pairoptions 
+
 def jacobicgoptions(*args):
 	#ASMOPTIONS - return Additive Shwartz Method with Jacobi preconditioner petsc options
@@ -7,5 +8,5 @@
 	
 	#retrieve options provided in varargin
-	arguments=pairoptions(*args) 
+	arguments=pairoptions.pairoptions(*args) 
 	
 	options=[['toolkit','petsc'],['mat_type','aij'],['ksp_type','cg'],['ksp_max_it',100],['ksp_rtol',1e-15]];
Index: /issm/trunk/src/m/solvers/lcdasmoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/lcdasmoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/lcdasmoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=lcdasmoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','lcd');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'asm');
+end
Index: /issm/trunk/src/m/solvers/lcdbjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/lcdbjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/lcdbjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=lcdbjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','lcd');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'bjacobi');
+end
Index: /issm/trunk/src/m/solvers/lcdgamgoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/lcdgamgoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/lcdgamgoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=lcdgamgoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','lcd');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'gamg');
+end
Index: /issm/trunk/src/m/solvers/lcdgasmoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/lcdgasmoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/lcdgasmoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=lcdgasmoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','lcd');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'gasm');
+end
Index: /issm/trunk/src/m/solvers/lcdhypreoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/lcdhypreoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/lcdhypreoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=lcdhypreoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','lcd');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'hypre');
+end
Index: /issm/trunk/src/m/solvers/lcdjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/lcdjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/lcdjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=lcdjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','lcd');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'jacobi');
+end
Index: /issm/trunk/src/m/solvers/lcdmgoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/lcdmgoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/lcdmgoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=lcdmgoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','lcd');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'mg');
+end
Index: /issm/trunk/src/m/solvers/lcdpbjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/lcdpbjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/lcdpbjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=lcdpbjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','lcd');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'pbjacobi');
+end
Index: /issm/trunk/src/m/solvers/lcdsoroptions.m
===================================================================
--- /issm/trunk/src/m/solvers/lcdsoroptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/lcdsoroptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=lcdsoroptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','lcd');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'sor');
+end
Index: /issm/trunk/src/m/solvers/lsqrasmoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/lsqrasmoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/lsqrasmoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=lsqrasmoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','lsqr');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'asm');
+end
Index: /issm/trunk/src/m/solvers/lsqrbjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/lsqrbjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/lsqrbjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=lsqrbjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','lsqr');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'bjacobi');
+end
Index: /issm/trunk/src/m/solvers/lsqrgamgoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/lsqrgamgoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/lsqrgamgoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=lsqrgamgoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','lsqr');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'gamg');
+end
Index: /issm/trunk/src/m/solvers/lsqrgasmoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/lsqrgasmoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/lsqrgasmoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=lsqrgasmoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','lsqr');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'gasm');
+end
Index: /issm/trunk/src/m/solvers/lsqrhypreoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/lsqrhypreoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/lsqrhypreoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=lsqrhypreoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','lsqr');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'hypre');
+end
Index: /issm/trunk/src/m/solvers/lsqrjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/lsqrjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/lsqrjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=lsqrjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','lsqr');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'jacobi');
+end
Index: /issm/trunk/src/m/solvers/lsqrmgoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/lsqrmgoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/lsqrmgoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=lsqrmgoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','lsqr');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'mg');
+end
Index: /issm/trunk/src/m/solvers/lsqrpbjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/lsqrpbjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/lsqrpbjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=lsqrpbjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','lsqr');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'pbjacobi');
+end
Index: /issm/trunk/src/m/solvers/lsqrsoroptions.m
===================================================================
--- /issm/trunk/src/m/solvers/lsqrsoroptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/lsqrsoroptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=lsqrsoroptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','lsqr');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'sor');
+end
Index: /issm/trunk/src/m/solvers/matlaboptions.py
===================================================================
--- /issm/trunk/src/m/solvers/matlaboptions.py	(revision 17805)
+++ /issm/trunk/src/m/solvers/matlaboptions.py	(revision 17806)
@@ -1,3 +1,4 @@
-from pairoptions import *
+import pairoptions
+
 def matlaboptions(*args):
 	#MATLABOPTIONS - return Matlab petsc options
@@ -7,5 +8,5 @@
 	
 	#retrieve options provided in varargin
-	arguments=pairoptions(*args) 
+	arguments=pairoptions.pairoptions(*args) 
 	
 	options=[['toolkit','petsc'],['ksp_type','matlab']];
Index: /issm/trunk/src/m/solvers/minresasmoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/minresasmoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/minresasmoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=minresasmoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','minres');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'asm');
+end
Index: /issm/trunk/src/m/solvers/minresbjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/minresbjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/minresbjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=minresbjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','minres');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'bjacobi');
+end
Index: /issm/trunk/src/m/solvers/minresgamgoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/minresgamgoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/minresgamgoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=minresgamgoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','minres');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'gamg');
+end
Index: /issm/trunk/src/m/solvers/minresgasmoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/minresgasmoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/minresgasmoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=minresgasmoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','minres');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'gasm');
+end
Index: /issm/trunk/src/m/solvers/minreshypreoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/minreshypreoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/minreshypreoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=minreshypreoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','minres');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'hypre');
+end
Index: /issm/trunk/src/m/solvers/minresjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/minresjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/minresjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=minresjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','minres');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'jacobi');
+end
Index: /issm/trunk/src/m/solvers/minresmgoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/minresmgoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/minresmgoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=minresmgoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','minres');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'mg');
+end
Index: /issm/trunk/src/m/solvers/minrespbjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/minrespbjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/minrespbjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=minrespbjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','minres');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'pbjacobi');
+end
Index: /issm/trunk/src/m/solvers/minressoroptions.m
===================================================================
--- /issm/trunk/src/m/solvers/minressoroptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/minressoroptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=minressoroptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','minres');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'sor');
+end
Index: /issm/trunk/src/m/solvers/mumpsoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/mumpsoptions.m	(revision 17805)
+++ /issm/trunk/src/m/solvers/mumpsoptions.m	(revision 17806)
@@ -27,3 +27,5 @@
 	mumps.mat_mumps_icntl_14=getfieldvalue(options,'mat_mumps_icntl_14',120);
 	mumps.pc_factor_shift_positive_definite=getfieldvalue(options,'pc_factor_shift_positive_definite','true');
+	mumps.mat_mumps_icntl_28=2; %1=serial, 2=parallel
+	mumps.mat_mumps_icntl_29=2; %parallel ordering 1 = ptscotch, 2 = parmetis
 end
Index: /issm/trunk/src/m/solvers/mumpsoptions.py
===================================================================
--- /issm/trunk/src/m/solvers/mumpsoptions.py	(revision 17805)
+++ /issm/trunk/src/m/solvers/mumpsoptions.py	(revision 17806)
@@ -1,5 +1,5 @@
 from collections import OrderedDict
-from pairoptions import *
-from IssmConfig  import *
+import pairoptions
+from IssmConfig import IssmConfig
 
 def mumpsoptions(*args):
@@ -12,5 +12,5 @@
 
 	#retrieve options provided in varargin
-	options=pairoptions(*args)
+	options=pairoptions.pairoptions(*args)
 	mumps=OrderedDict()
 
Index: /issm/trunk/src/m/solvers/richardsonasmoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/richardsonasmoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/richardsonasmoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=richardsonasmoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','richardson');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'asm');
+end
Index: /issm/trunk/src/m/solvers/richardsonbjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/richardsonbjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/richardsonbjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=richardsonbjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','richardson');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'bjacobi');
+end
Index: /issm/trunk/src/m/solvers/richardsongamgoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/richardsongamgoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/richardsongamgoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=richardsongamgoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','richardson');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'gamg');
+end
Index: /issm/trunk/src/m/solvers/richardsongasmoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/richardsongasmoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/richardsongasmoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=richardsongasmoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','richardson');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'gasm');
+end
Index: /issm/trunk/src/m/solvers/richardsonhypreoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/richardsonhypreoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/richardsonhypreoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=richardsonhypreoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','richardson');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'hypre');
+end
Index: /issm/trunk/src/m/solvers/richardsonjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/richardsonjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/richardsonjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=richardsonjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','richardson');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'jacobi');
+end
Index: /issm/trunk/src/m/solvers/richardsonmgoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/richardsonmgoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/richardsonmgoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=richardsonmgoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','richardson');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'mg');
+end
Index: /issm/trunk/src/m/solvers/richardsonpbjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/richardsonpbjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/richardsonpbjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=richardsonpbjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','richardson');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'pbjacobi');
+end
Index: /issm/trunk/src/m/solvers/richardsonsoroptions.m
===================================================================
--- /issm/trunk/src/m/solvers/richardsonsoroptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/richardsonsoroptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=richardsonsoroptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','richardson');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'sor');
+end
Index: /issm/trunk/src/m/solvers/soroptions.py
===================================================================
--- /issm/trunk/src/m/solvers/soroptions.py	(revision 17805)
+++ /issm/trunk/src/m/solvers/soroptions.py	(revision 17806)
@@ -1,3 +1,4 @@
-from pairoptions import *
+import pairoptions
+
 def soroptions(*args):
 	#SOROPTIONS - return Relaxation Solver petsc options
@@ -7,5 +8,5 @@
 	
 	#retrieve options provided in varargin
-	arguments=pairoptions(*args) 
+	arguments=pairoptions.pairoptions(*args) 
 	
 	options=[['toolkit','petsc'],['mat_type','aij'],['ksp_type','cg'],['pc_type','sor'],['pc_sor_omega',1.1],['pc_sor_its',2]];
Index: /issm/trunk/src/m/solvers/stcgasmoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/stcgasmoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/stcgasmoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=stcgasmoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','stcg');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'asm');
+end
Index: /issm/trunk/src/m/solvers/stcgbjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/stcgbjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/stcgbjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=stcgbjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','stcg');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'bjacobi');
+end
Index: /issm/trunk/src/m/solvers/stcggamgoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/stcggamgoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/stcggamgoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=stcggamgoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','stcg');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'gamg');
+end
Index: /issm/trunk/src/m/solvers/stcggasmoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/stcggasmoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/stcggasmoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=stcggasmoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','stcg');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'gasm');
+end
Index: /issm/trunk/src/m/solvers/stcghypreoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/stcghypreoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/stcghypreoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=stcghypreoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','stcg');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'hypre');
+end
Index: /issm/trunk/src/m/solvers/stcgjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/stcgjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/stcgjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=stcgjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','stcg');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'jacobi');
+end
Index: /issm/trunk/src/m/solvers/stcgmgoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/stcgmgoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/stcgmgoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=stcgmgoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','stcg');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'mg');
+end
Index: /issm/trunk/src/m/solvers/stcgpbjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/stcgpbjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/stcgpbjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=stcgpbjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','stcg');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'pbjacobi');
+end
Index: /issm/trunk/src/m/solvers/stcgsoroptions.m
===================================================================
--- /issm/trunk/src/m/solvers/stcgsoroptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/stcgsoroptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=stcgsoroptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','stcg');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'sor');
+end
Index: /issm/trunk/src/m/solvers/stokesoptions.py
===================================================================
--- /issm/trunk/src/m/solvers/stokesoptions.py	(revision 17805)
+++ /issm/trunk/src/m/solvers/stokesoptions.py	(revision 17806)
@@ -1,4 +1,5 @@
-from pairoptions import *
-from IssmConfig  import *
+import pairoptions
+from IssmConfig import IssmConfig
+
 def stokesoptions(*args):
 	#STOKESOPTIONS - return STOKES multi-physics solver petsc options
@@ -8,5 +9,5 @@
 	
 	#retrieve options provided in varargin
-	arguments=pairoptions(*args) 
+	arguments=pairoptions.pairoptions(*args) 
 
 
Index: /issm/trunk/src/m/solvers/symmlqasmoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/symmlqasmoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/symmlqasmoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=symmlqasmoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','symmlq');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'asm');
+end
Index: /issm/trunk/src/m/solvers/symmlqbjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/symmlqbjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/symmlqbjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=symmlqbjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','symmlq');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'bjacobi');
+end
Index: /issm/trunk/src/m/solvers/symmlqgamgoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/symmlqgamgoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/symmlqgamgoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=symmlqgamgoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','symmlq');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'gamg');
+end
Index: /issm/trunk/src/m/solvers/symmlqgasmoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/symmlqgasmoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/symmlqgasmoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=symmlqgasmoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','symmlq');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'gasm');
+end
Index: /issm/trunk/src/m/solvers/symmlqhypreoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/symmlqhypreoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/symmlqhypreoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=symmlqhypreoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','symmlq');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'hypre');
+end
Index: /issm/trunk/src/m/solvers/symmlqjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/symmlqjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/symmlqjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=symmlqjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','symmlq');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'jacobi');
+end
Index: /issm/trunk/src/m/solvers/symmlqmgoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/symmlqmgoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/symmlqmgoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=symmlqmgoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','symmlq');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'mg');
+end
Index: /issm/trunk/src/m/solvers/symmlqpbjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/symmlqpbjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/symmlqpbjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=symmlqpbjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','symmlq');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'pbjacobi');
+end
Index: /issm/trunk/src/m/solvers/symmlqsoroptions.m
===================================================================
--- /issm/trunk/src/m/solvers/symmlqsoroptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/symmlqsoroptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=symmlqsoroptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','symmlq');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'sor');
+end
Index: /issm/trunk/src/m/solvers/tfqmrasmoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/tfqmrasmoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/tfqmrasmoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=tfqmrasmoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','tfqmr');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'asm');
+end
Index: /issm/trunk/src/m/solvers/tfqmrbjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/tfqmrbjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/tfqmrbjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=tfqmrbjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','tfqmr');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'bjacobi');
+end
Index: /issm/trunk/src/m/solvers/tfqmrgamgoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/tfqmrgamgoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/tfqmrgamgoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=tfqmrgamgoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','tfqmr');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'gamg');
+end
Index: /issm/trunk/src/m/solvers/tfqmrgasmoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/tfqmrgasmoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/tfqmrgasmoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=tfqmrgasmoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','tfqmr');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'gasm');
+end
Index: /issm/trunk/src/m/solvers/tfqmrhypreoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/tfqmrhypreoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/tfqmrhypreoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=tfqmrhypreoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','tfqmr');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'hypre');
+end
Index: /issm/trunk/src/m/solvers/tfqmrjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/tfqmrjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/tfqmrjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=tfqmrjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','tfqmr');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'jacobi');
+end
Index: /issm/trunk/src/m/solvers/tfqmrmgoptions.m
===================================================================
--- /issm/trunk/src/m/solvers/tfqmrmgoptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/tfqmrmgoptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=tfqmrmgoptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','tfqmr');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'mg');
+end
Index: /issm/trunk/src/m/solvers/tfqmrpbjacobioptions.m
===================================================================
--- /issm/trunk/src/m/solvers/tfqmrpbjacobioptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/tfqmrpbjacobioptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=tfqmrpbjacobioptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','tfqmr');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'pbjacobi');
+end
Index: /issm/trunk/src/m/solvers/tfqmrsoroptions.m
===================================================================
--- /issm/trunk/src/m/solvers/tfqmrsoroptions.m	(revision 17806)
+++ /issm/trunk/src/m/solvers/tfqmrsoroptions.m	(revision 17806)
@@ -0,0 +1,14 @@
+function solverOptions=tfqmrsoroptions(varargin)
+
+%retrieve options provided in varargin
+options=pairoptions(varargin{:});
+solverOptions=struct();
+solverOptions.toolkit='petsc';
+
+
+PETSC_VERSION=petscversion();
+if PETSC_VERSION==3,
+   solverOptions.mat_type=getfieldvalue(options, 'mat_type','mpiaij');
+   solverOptions.ksp_type=getfieldvalue(options, 'ksp_type','tfqmr');
+   solverOptions.pc_type=getfieldvalue(options, 'pc_type',  'sor');
+end
Index: /issm/trunk/src/wrappers/InterpFromMesh2d/InterpFromMesh2d.cpp
===================================================================
--- /issm/trunk/src/wrappers/InterpFromMesh2d/InterpFromMesh2d.cpp	(revision 17805)
+++ /issm/trunk/src/wrappers/InterpFromMesh2d/InterpFromMesh2d.cpp	(revision 17806)
@@ -93,4 +93,5 @@
 	if(nrhs>=8){
 
+		#ifdef _HAVE_MATLAB_MODULES_
 		/*Call expread on filename to build a contour array in the matlab workspace: */
 		mexCallMATLAB( 1, &matlabstructure, 1, (mxArray**)&FILENAME, "expread");
@@ -109,15 +110,7 @@
 			*(contours+i)=contouri;
 		}
-
-		/* Debugging of contours :{{{1*/
-		/*for(i=0;i<numcontours;i++){
-		  _printf_("\nContour echo: contour number  " << i+1 << " / " << numcontours << "\n");
-		  contouri=*(contours+i);
-		  _printf_("   Number of vertices " << contouri->nods << "\n");
-		  for (j=0;j<contouri->nods;j++){
-		  _printf_("   " << *(contouri->x+j) << "f " << *(contouri->y+j) << "f\n");
-		  }
-		  }*/
-		/*}}}*/
+		#else
+		_error_("not supported");
+		#endif
 	}
 	else{
Index: /issm/trunk/src/wrappers/InterpFromMeshToGrid/InterpFromMeshToGrid.cpp
===================================================================
--- /issm/trunk/src/wrappers/InterpFromMeshToGrid/InterpFromMeshToGrid.cpp	(revision 17805)
+++ /issm/trunk/src/wrappers/InterpFromMeshToGrid/InterpFromMeshToGrid.cpp	(revision 17806)
@@ -46,5 +46,7 @@
 
 	/*checks on arguments on the matlab side: */
+	#ifdef _HAVE_MATLAB_MODULES_
 	CheckNumMatlabArguments(nlhs,NLHS,nrhs,NRHS,__FUNCT__,&InterpFromMeshToGridUsage);
+	#endif
 
 	/*Input datasets: */
Index: /issm/trunk/src/wrappers/InterpFromMeshToGrid/InterpFromMeshToGrid.h
===================================================================
--- /issm/trunk/src/wrappers/InterpFromMeshToGrid/InterpFromMeshToGrid.h	(revision 17805)
+++ /issm/trunk/src/wrappers/InterpFromMeshToGrid/InterpFromMeshToGrid.h	(revision 17806)
@@ -19,6 +19,9 @@
 #include "../bindings.h"
 #include "../../c/main/globals.h"
+#include "../../c/toolkits/toolkits.h"
 #include "../../c/modules/modules.h"
 #include "../../c/shared/shared.h"
+#include "../../c/shared/io/io.h"
+#include "../../c/shared/Enum/Enum.h"
 
 #undef __FUNCT__ 
Index: /issm/trunk/src/wrappers/InterpFromMeshToMesh3d/InterpFromMeshToMesh3d.cpp
===================================================================
--- /issm/trunk/src/wrappers/InterpFromMeshToMesh3d/InterpFromMeshToMesh3d.cpp	(revision 17805)
+++ /issm/trunk/src/wrappers/InterpFromMeshToMesh3d/InterpFromMeshToMesh3d.cpp	(revision 17806)
@@ -66,5 +66,7 @@
 
 	/*checks on arguments on the matlab side: */
+	#ifdef _HAVE_MATLAB_MODULES_
 	CheckNumMatlabArguments(nlhs,NLHS,nrhs,NRHS,__FUNCT__,&InterpFromMeshToMesh3dUsage);
+	#endif
 
 	/*Input datasets: */
Index: /issm/trunk/src/wrappers/MeshPartition/MeshPartition.cpp
===================================================================
--- /issm/trunk/src/wrappers/MeshPartition/MeshPartition.cpp	(revision 17805)
+++ /issm/trunk/src/wrappers/MeshPartition/MeshPartition.cpp	(revision 17806)
@@ -19,5 +19,5 @@
 
 	/* required input: */
-	int  meshtype;
+	int  meshelementtype;
 	int  numberofelements;
 	int  numberofvertices;
@@ -49,6 +49,6 @@
 	FetchData(&elements,NULL,&elements_width,mxGetAssignedField(MESH,0,"elements"));
 
-	if(strcmp(mxGetClassName(MESH),"mesh3d")==0){
-		meshtype = Mesh3DEnum;
+	if(strcmp(mxGetClassName(MESH),"mesh3dprisms")==0){
+		meshelementtype = PentaEnum;
 		FetchData(&numberofelements2d,mxGetAssignedField(MESH,0,"numberofelements2d"));
 		FetchData(&numberofvertices2d,mxGetAssignedField(MESH,0,"numberofvertices2d"));
@@ -57,9 +57,9 @@
 	}
 	else if(strcmp(mxGetClassName(MESH),"mesh2dhorizontal")==0){
-		meshtype = Mesh2DhorizontalEnum;
+		meshelementtype = TriaEnum;
 		numberoflayers=1;
 	}
 	else if(strcmp(mxGetClassName(MESH),"mesh2dvertical")==0){
-		meshtype = Mesh2DverticalEnum;
+		meshelementtype = TriaEnum;
 		numberoflayers=1;
 	}
@@ -71,5 +71,5 @@
 	/*Run partitioning algorithm based on a "clever" use of the Metis partitioner: */
 	MeshPartitionx(&int_element_partitioning,&int_node_partitioning,numberofelements,numberofvertices,elements,
-		numberofelements2d,numberofvertices2d,elements2d,numberoflayers,elements_width,meshtype,numareas);
+		numberofelements2d,numberofvertices2d,elements2d,numberoflayers,elements_width,meshelementtype,numareas);
 
 	/*Post process node_partitioning and element_partitioning to be in double format. Metis needed them in int* format: */
Index: /issm/trunk/src/wrappers/matlab/io/FetchMatlabData.cpp
===================================================================
--- /issm/trunk/src/wrappers/matlab/io/FetchMatlabData.cpp	(revision 17805)
+++ /issm/trunk/src/wrappers/matlab/io/FetchMatlabData.cpp	(revision 17806)
@@ -545,4 +545,5 @@
 	FetchData(&bamgopts->omega,mxGetField(dataref,0,"omega"));
 	FetchData(&bamgopts->power,mxGetField(dataref,0,"power"));
+	FetchData(&bamgopts->random,mxGetField(dataref,0,"random"));
 	FetchData(&bamgopts->verbose,mxGetField(dataref,0,"verbose"));
 
Index: /issm/trunk/src/wrappers/python/Makefile.am
===================================================================
--- /issm/trunk/src/wrappers/python/Makefile.am	(revision 17805)
+++ /issm/trunk/src/wrappers/python/Makefile.am	(revision 17806)
@@ -53,5 +53,7 @@
 						EnumToString.la\
 						InterpFromMeshToMesh2d.la\
+						InterpFromMeshToMesh3d.la\
 						InterpFromGridToMesh.la\
+						InterpFromMeshToGrid.la\
 						IssmConfig.la\
 						MeshProfileIntersection.la\
@@ -143,7 +145,15 @@
 InterpFromMeshToMesh2d_la_LIBADD = ${deps} $(MPILIB) $(PETSCLIB) $(MULTITHREADINGLIB) $(GSLLIB)
 
+InterpFromMeshToMesh3d_la_SOURCES = ../InterpFromMeshToMesh3d/InterpFromMeshToMesh3d.cpp\
+												../InterpFromMeshToMesh3d/InterpFromMeshToMesh3d.h
+InterpFromMeshToMesh3d_la_LIBADD = ${deps} $(MPILIB) $(PETSCLIB) $(MULTITHREADINGLIB) $(GSLLIB)
+
 InterpFromGridToMesh_la_SOURCES = ../InterpFromGridToMesh/InterpFromGridToMesh.cpp\
 												../InterpFromGridToMesh/InterpFromGridToMesh.h
 InterpFromGridToMesh_la_LIBADD = ${deps} $(MPILIB) $(PETSCLIB) $(MULTITHREADINGLIB) $(GSLLIB)
+
+InterpFromMeshToGrid_la_SOURCES = ../InterpFromMeshToGrid/InterpFromMeshToGrid.cpp\
+												../InterpFromMeshToGrid/InterpFromMeshToGrid.h
+InterpFromMeshToGrid_la_LIBADD = ${deps} $(MPILIB) $(PETSCLIB) $(MULTITHREADINGLIB) $(GSLLIB)
 
 IssmConfig_la_SOURCES = ../IssmConfig/IssmConfig.cpp\
Index: /issm/trunk/src/wrappers/python/io/FetchPythonData.cpp
===================================================================
--- /issm/trunk/src/wrappers/python/io/FetchPythonData.cpp	(revision 17805)
+++ /issm/trunk/src/wrappers/python/io/FetchPythonData.cpp	(revision 17806)
@@ -689,4 +689,5 @@
 	FetchData(&bamgopts->omega,PyDict_GetItemString(py_dict,"omega"));
 	FetchData(&bamgopts->power,PyDict_GetItemString(py_dict,"power"));
+	FetchData(&bamgopts->random,PyDict_GetItemString(py_dict,"random"));
 	FetchData(&bamgopts->verbose,PyDict_GetItemString(py_dict,"verbose"));
 
Index: /issm/trunk/test/NightlyRun/IdToName.m
===================================================================
--- /issm/trunk/test/NightlyRun/IdToName.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/IdToName.m	(revision 17806)
@@ -28,4 +28,6 @@
 	case 121, name='SquareShelfConstrainedEnthalpyTran';
 	case 122, name='SquareShelfConstrainedTransHOEnth';
+	case 123, name='SquareShelfConstrainedTranMisfitSurface';
+	case 124, name='SquareShelfConstrainedTranFSFreeSurface';
 	case 201, name='SquareShelfStressSSA2d';
 	case 202, name='SquareShelfStressSSA3d';
@@ -69,4 +71,6 @@
 	case 272, name='SquareShelfCMZSSA2dDamage';
 	case 274, name='SquareShelfStressSSA2dDamageRift';
+	case 275, name='SquareShelfDamageEvolutionSSA2d';
+	case 276, name='SquareShelfDamageEvolutionSSA2dP2';
 	case 280, name='SquareShelfStressSSA2dHigherOrder';
 	case 285, name='SquareShelfStressHOHigherOrder';
@@ -101,5 +105,4 @@
 	case 328, name='SquareSheetConstrainedSmbGradients2d';
 	case 329, name='SquareSheetConstrainedSmbGradients3d';
-	case 331, name='SquareSheetConstrainedHydrologyShreve';
 	case 332, name='SquareSheetConstrainedHydrologyDC';
 	case 333, name='SquareSheetHydrologyDCTwoLayers';
@@ -139,4 +142,5 @@
 	case 433, name='RoundSheetShelfGLMigrationSSA3d';
 	case 434, name='SquareSheetShelfL1L2';
+	case 435, name='MISMIP3DHO';
 	case 450, name='SquareSheetShelfStressSSAHigherOrder';
 	case 455, name='SquareSheetShelfStressHOHigherOrder';
@@ -170,8 +174,13 @@
 	case 610, name='79NorthBalThic3d';
 	case 611, name='79NorthCMBalThic2dCG';
-	case 612, name='79NorthCMBalThic2dDG';
 	case 613, name='79NorthCMBalThicVxVy';
 	case 701, name='FlowbandFSshelf';
 	case 702, name='FlowbandFSsheetshelf';
+	case 703, name='FlowbandFSsheetshelfTrans';
+	case 801, name='ValleyGlacierLevelsetSSA2d';
+	case 802, name='ValleyGlacierLevelsetThermalSSA3d';
+	case 803, name='ValleyGlacierLevelsetEnthalpyHO3d';
+	case 804, name='ValleyGlacierLevelsetCalvingSIA2d';
+	case 805, name='ValleyGlacierLevelsetEnthCalvingHO3d';
 	case 1101, name='ISMIPAHO';
 	case 1102, name='ISMIPAFS';
Index: /issm/trunk/test/NightlyRun/IdToName.py
===================================================================
--- /issm/trunk/test/NightlyRun/IdToName.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/IdToName.py	(revision 17806)
@@ -72,4 +72,6 @@
 	272  : 'SquareShelfCMZSSA2dDamage',
 	274  : 'SquareShelfStressSSA2dDamageRift',
+	275  : 'SquareShelfDamageEvolutionSSA2d',
+	276  : 'SquareShelfDamageEvolutionSSA2dP2',
 	280  : 'SquareShelfStressSSA2dHigherOrder',
 	285  : 'SquareShelfStressHOHigherOrder',
@@ -104,5 +106,4 @@
 	328  : 'SquareSheetConstrainedSmbGradients2d',
 	329  : 'SquareSheetConstrainedSmbGradients3d',
-	331  : 'SquareSheetConstrainedHydrologyShreve',
 	332  : 'SquareSheetConstrainedHydrologyDC',
 	333  : 'SquareSheetHydrologyDCTwoLayers',
@@ -171,6 +172,10 @@
 	610  : '79NorthBalThic3d',
 	611  : '79NorthCMBalThic2dCG',
-	612  : '79NorthCMBalThic2dDG',
 	613  : '79NorthCMBalThicVxVy',
+	801  : 'ValleyGlacierLevelsetSSA2d',	
+	802  : 'ValleyGlacierLevelsetThermalSSA3d',	
+	803  : 'ValleyGlacierLevelsetEnthalpyHO3d',	
+	804  : 'ValleyGlacierLevelsetCalvingSIA2d',	
+	805  : 'ValleyGlacierLevelsetEnthCalvingHO3d',	
 	1101 : 'ISMIPAHO',
 	1102 : 'ISMIPAFS',
@@ -240,4 +245,5 @@
 	3119 : 'SquareShelfConstrainedTherTranAdolcReverseVsForwardMumps',
 	3120 : 'SquareShelfConstrainedTranAdolcReverseVsForwardMumps',
+	3300 : 'SquareSheetHydrologyDCTwoLayersVolumeControl',
 	}
 
Index: /issm/trunk/test/NightlyRun/runme.m
===================================================================
--- /issm/trunk/test/NightlyRun/runme.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/runme.m	(revision 17806)
@@ -13,5 +13,5 @@
 %      'exclude'       ids to be excluded from the test
 %      'benchmark'     'all' (all of them)
-%                      'nightly' (nightly run/ daily run)
+%                      'nightly' (nightly run)
 %                      'ismip'  : validation of ismip-hom tests
 %                      'eismint': validation of eismint tests
@@ -24,4 +24,5 @@
 %                      'update':   update the archive
 %                      'valgrind': check for memory leaks (default value of md.debug.valgrind needs to be changed manually)
+%      'stoponerror'   1 or 0
 %
 %   Usage:
@@ -64,5 +65,5 @@
 %GET output {{{
 output=getfieldvalue(options,'output','none');
-if ~ismember(output,{'nightly','daily','none'})
+if ~ismember(output,{'nightly','none'})
 	disp('runme warning: output not supported, defaulting to test ''none''')
 	output='none';
@@ -133,4 +134,5 @@
 		eval(['cd ' root ]);
 		id_string=IdToName(id);
+		disp(sprintf('%s%i%s','----------------starting:',id,'-----------------------'));
 		eval(['test' num2str(id)]);
 
@@ -221,4 +223,5 @@
 						disp(sprintf(['ERROR   difference: %-7.2g > %7.2g test id: %i test name: %s field: %s'],...
 							error_diff,tolerance,id,id_string,fieldname));
+						if(getfieldvalue(options,'stoponerror',0)), disp('STOP'); return; end
 					else
 						disp(sprintf(['SUCCESS difference: %-7.2g < %7.2g test id: %i test name: %s field: %s'],...
@@ -229,6 +232,6 @@
 
 					%something went wrong, print failure message:
-					directory=strsplit(pwd,'/');
 					message=getReport(me2);
+					fprintf('%s',message);
 					if strcmpi(output,'nightly')
 						fid=fopen([ISSM_DIR '/nightlylog/matlaberror.log'], 'at');
@@ -237,31 +240,23 @@
 						fclose(fid);
 						disp(sprintf(['FAILURE difference: N/A test id: %i test name: %s field: %s'],id,id_string,fieldname));
-					elseif strcmpi(output,'daily');
-						fid=fopen([ISSM_DIR '/dailylog/matlaberror.log'], 'at');
-						fprintf(fid,'%s',message);
-						fprintf(fid,'\n------------------------------------------------------------------\n');
-						fclose(fid);
-						disp(sprintf(['FAILURE difference: N/A test id: %i test name: %s field: %s'],id,id_string,fieldname));
 					else
 						disp(sprintf(['FAILURE difference: N/A test id: %i test name: %s field: %s'],id,id_string,fieldname));
-						rethrow(me2);
+						fprintf('%s',message);
+						if(getfieldvalue(options,'stoponerror',0)), disp('STOP'); return; end
 					end
+					continue;
 				end
 			end
 		end
+		
+		disp(sprintf('%s%i%s','----------------finished:',id,'-----------------------'));
 
 	catch me,
 
 		%something went wrong, print failure message:
-		directory=strsplit(pwd,'/');
 		message=getReport(me);
+		fprintf('%s',message);
 		if strcmpi(output,'nightly')
 			fid=fopen([ISSM_DIR '/nightlylog/matlaberror.log'], 'at');
-			fprintf(fid,'%s',message);
-			fprintf(fid,'\n------------------------------------------------------------------\n');
-			fclose(fid);
-			disp(sprintf(['FAILURE difference: N/A test id: %i test name: %s field: %s'],id,id_string,'N/A'));
-		elseif strcmpi(output,'daily');
-			fid=fopen([ISSM_DIR '/dailylog/matlaberror.log'], 'at');
 			fprintf(fid,'%s',message);
 			fprintf(fid,'\n------------------------------------------------------------------\n');
@@ -271,5 +266,7 @@
 			disp(sprintf(['FAILURE difference: N/A test id: %i test name: %s field: %s'],id,id_string,'N/A'));
 			rethrow(me);
+			if(getfieldvalue(options,'stoponerror',0)), disp('STOP'); return; end
 		end
+		disp(sprintf('%s%i%s','----------------finished:',id,'-----------------------'));
 	end
 end
Index: /issm/trunk/test/NightlyRun/runme.py
===================================================================
--- /issm/trunk/test/NightlyRun/runme.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/runme.py	(revision 17806)
@@ -4,5 +4,4 @@
 import socket
 import numpy
-#import h5py
 import netCDF4
 import sys
@@ -135,4 +134,5 @@
 			os.chdir(root)
 			id_string=IdToName(id)
+			print "----------------starting:%i-----------------------" % id
 			execfile('test'+str(id)+'.py',globals())
 
@@ -140,7 +140,8 @@
 			archive_name='Archive'+str(id)
 			if strcmpi(procedure,'update'):
-
-				os.remove(os.path.join('..','Archives',archive_name+'.nc'))
-				f = netCDF4.Dataset(os.path.join('..','Archives',archive_name+'.nc'),'w',format='NETCDF3_CLASSIC')
+				archive=os.path.join('..','Archives',archive_name+'.nc')
+				if os.path.isfile(archive):
+					os.remove(archive)
+				f = netCDF4.Dataset(archive,'w',format='NETCDF3_CLASSIC')
 				for k,fieldname in enumerate(field_names):
 					field=numpy.array(field_values[k],dtype=float)
@@ -220,4 +221,5 @@
 
 				f.close()
+				print "----------------finished:%i-----------------------" % id
 
 		except Exception as me:
@@ -241,4 +243,5 @@
 				print 'FAILURE difference: N/A test id: %i test name: %s field: %s' % (id,id_string,'N/A')
 				raise RuntimeError(me)
+			print "----------------finished:%i-----------------------" % id
 
 	return
@@ -259,5 +262,5 @@
 	parser = argparse.ArgumentParser(description='RUNME - test deck for ISSM nightly runs')
 	parser.add_argument('-i','--id', nargs='*', type=int, help='followed by the list of ids requested', default=[])
-	parser.add_argument('-e','--exclude', nargs='*', type=int, help='ids to be excluded from the test', default=[])
+	parser.add_argument('-e','--exclude', nargs='+', type=int, help='ids to be excluded from the test', default=[])
 	parser.add_argument('-b','--benchmark', help='nightly/ismip/eismint/thermal/mesh/...', default='nightly')
 	parser.add_argument('-p','--procedure', help='check/update', default='check')
@@ -269,4 +272,5 @@
 	md = runme(args.id, args.exclude, args.benchmark, args.procedure, args.output, args.rank, args.numprocs)
 
+	from MatlabFuncs import strcmpi
 	if strcmpi(args.output,'nightly'):
 		print "PYTHONEXITEDCORRECTLY"
Index: /issm/trunk/test/NightlyRun/temp291.m
===================================================================
--- /issm/trunk/test/NightlyRun/temp291.m	(revision 17806)
+++ /issm/trunk/test/NightlyRun/temp291.m	(revision 17806)
@@ -0,0 +1,8 @@
+md=triangle(model(),'../Exp/Square.exp',150000.);
+md=setmask(md,'all','');
+md=parameterize(md,'../Par/SquareShelf.par');
+md=extrude(md,2,1.);
+md=setflowequation(md,'FS','all');
+md.flowequation.fe_FS='OneLayerP4z';
+md.cluster=generic('name',oshostname(),'np',1);
+md=solve(md,StressbalanceSolutionEnum());
Index: /issm/trunk/test/NightlyRun/temp291.py
===================================================================
--- /issm/trunk/test/NightlyRun/temp291.py	(revision 17806)
+++ /issm/trunk/test/NightlyRun/temp291.py	(revision 17806)
@@ -0,0 +1,18 @@
+from model import *
+from triangle import *
+from setmask import *
+from parameterize import *
+from setflowequation import *
+from EnumDefinitions import *
+from solve import *
+from MatlabFuncs import *
+from ContourToMesh import *
+
+md=triangle(model(),'../Exp/Square.exp',150000.)
+md=setmask(md,'all','')
+md=parameterize(md,'../Par/SquareShelf.py')
+md.extrude(2,1.)
+md=setflowequation(md,'FS','all')
+md.flowequation.fe_FS='OneLayerP4z'
+md.cluster=generic('name',oshostname(),'np',1)
+md=solve(md,StressbalanceSolutionEnum())
Index: /issm/trunk/test/NightlyRun/test101.m
===================================================================
--- /issm/trunk/test/NightlyRun/test101.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test101.m	(revision 17806)
@@ -6,5 +6,5 @@
 
 %output
-md.stressbalance.requested_outputs={'default','StressTensorxx','StressTensoryy','StressTensorxy','MassFlux1','MassFlux2','MassFlux3','MassFlux4','MassFlux5','MassFlux6'};
+md.stressbalance.requested_outputs={'default','DeviatoricStressxx','DeviatoricStressyy','DeviatoricStressxy','MassFlux1','MassFlux2','MassFlux3','MassFlux4','MassFlux5','MassFlux6'};
 md.outputdefinition.definitions={...
 	massfluxatgate('MassFlux1',['../Exp/MassFlux1.exp']),...
@@ -20,6 +20,6 @@
 %Fields and tolerances to track changes
 field_names     ={'Vx','Vy','Vel','Pressure',...
-	'StressTensorxx','StressTensoryy','StressTensorxy','MassFlux1','MassFlux2','MassFlux3','MassFlux4','MassFlux5','MassFlux6'};
-field_tolerances={1e-13,1e-13,1e-13,1e-13,...
+	'DeviatoricStressxx','DeviatoricStressyy','DeviatoricStressxy','MassFlux1','MassFlux2','MassFlux3','MassFlux4','MassFlux5','MassFlux6'};
+field_tolerances={2e-13,1e-13,1e-13,1e-13,...
 	1e-13,1e-13,1e-13,...
 	1e-13, 1e-13, 1e-13, 1e-13, 1e-13, 1e-13 };
@@ -29,7 +29,7 @@
 	(md.results.StressbalanceSolution.Vel),...
 	(md.results.StressbalanceSolution.Pressure),...
-	(md.results.StressbalanceSolution.StressTensorxx),...
-	(md.results.StressbalanceSolution.StressTensoryy),...
-	(md.results.StressbalanceSolution.StressTensorxy),...
+	(md.results.StressbalanceSolution.DeviatoricStressxx),...
+	(md.results.StressbalanceSolution.DeviatoricStressyy),...
+	(md.results.StressbalanceSolution.DeviatoricStressxy),...
 	(md.results.StressbalanceSolution.MassFlux1),...
 	(md.results.StressbalanceSolution.MassFlux2),...
Index: /issm/trunk/test/NightlyRun/test101.py
===================================================================
--- /issm/trunk/test/NightlyRun/test101.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test101.py	(revision 17806)
@@ -8,4 +8,5 @@
 from MatlabFuncs import *
 from massfluxatgate import massfluxatgate
+from generic import generic
 
 md=triangle(model(),'../Exp/Square.exp',50000)
@@ -16,5 +17,5 @@
 
 #outputs
-md.stressbalance.requested_outputs=['default','StressTensorxx','StressTensoryy','StressTensorxy','MassFlux1','MassFlux2','MassFlux3','MassFlux4','MassFlux5','MassFlux6']
+md.stressbalance.requested_outputs=['default','DeviatoricStressxx','DeviatoricStressyy','DeviatoricStressxy','MassFlux1','MassFlux2','MassFlux3','MassFlux4','MassFlux5','MassFlux6']
 md.outputdefinition.definitions=[
 		massfluxatgate('MassFlux1','../Exp/MassFlux1.exp'),
@@ -30,5 +31,5 @@
 #Fields and tolerances to track changes
 field_names     =['Vx','Vy','Vel','Pressure',\
-	'StressTensorxx','StressTensoryy','StressTensorxy','MassFlux1','MassFlux2','MassFlux3','MassFlux4','MassFlux5','MassFlux6']
+	'DeviatoricStressxx','DeviatoricStressyy','DeviatoricStressxy','MassFlux1','MassFlux2','MassFlux3','MassFlux4','MassFlux5','MassFlux6']
 field_tolerances=[1e-13,1e-13,1e-13,1e-13,\
 	1e-13,1e-13,1e-13,\
@@ -39,7 +40,7 @@
 	md.results.StressbalanceSolution.Vel,\
 	md.results.StressbalanceSolution.Pressure,\
-	md.results.StressbalanceSolution.StressTensorxx,\
-	md.results.StressbalanceSolution.StressTensoryy,\
-	md.results.StressbalanceSolution.StressTensorxy,\
+	md.results.StressbalanceSolution.DeviatoricStressxx,\
+	md.results.StressbalanceSolution.DeviatoricStressyy,\
+	md.results.StressbalanceSolution.DeviatoricStressxy,\
 	md.results.StressbalanceSolution.MassFlux1,\
 	md.results.StressbalanceSolution.MassFlux2,\
Index: /issm/trunk/test/NightlyRun/test103.m
===================================================================
--- /issm/trunk/test/NightlyRun/test103.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test103.m	(revision 17806)
@@ -12,5 +12,5 @@
 	'StressTensorxx','StressTensoryy','StressTensorzz','StressTensorxy','StressTensorxz','StressTensoryz'};
 field_tolerances={1e-09,1e-09,1e-09,1e-09,1e-09,...
-	1e-09,1e-09,1e-09,1e-09,1e-09,1e-09};
+	1e-09,1e-09,1e-09,1e-09,1e-09,1e-08};
 field_values={...
 	(md.results.StressbalanceSolution.Vx),...
Index: /issm/trunk/test/NightlyRun/test103.py
===================================================================
--- /issm/trunk/test/NightlyRun/test103.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test103.py	(revision 17806)
@@ -21,5 +21,5 @@
 	'StressTensorxx','StressTensoryy','StressTensorzz','StressTensorxy','StressTensorxz','StressTensoryz']
 field_tolerances=[1e-09,1e-09,1e-09,1e-09,1e-09,\
-	1e-09,1e-09,1e-09,1e-09,1e-09,1e-09]
+	1e-09,1e-09,1e-09,1e-09,1e-09,1e-08]
 field_values=[\
 	md.results.StressbalanceSolution.Vx,\
Index: /issm/trunk/test/NightlyRun/test110.m
===================================================================
--- /issm/trunk/test/NightlyRun/test110.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test110.m	(revision 17806)
@@ -18,5 +18,5 @@
 	(md.results.TransientSolution(1).Vel),...
 	(md.results.TransientSolution(1).Pressure),...
-	(md.results.TransientSolution(1).Bed),...
+	(md.results.TransientSolution(1).Base),...
 	(md.results.TransientSolution(1).Surface),...
 	(md.results.TransientSolution(1).Thickness),...
@@ -26,5 +26,5 @@
 	(md.results.TransientSolution(2).Vel),...
 	(md.results.TransientSolution(2).Pressure),...
-	(md.results.TransientSolution(2).Bed),...
+	(md.results.TransientSolution(2).Base),...
 	(md.results.TransientSolution(2).Surface),...
 	(md.results.TransientSolution(2).Thickness),...
@@ -34,5 +34,5 @@
 	(md.results.TransientSolution(3).Vel),...
 	(md.results.TransientSolution(3).Pressure),...
-	(md.results.TransientSolution(3).Bed),...
+	(md.results.TransientSolution(3).Base),...
 	(md.results.TransientSolution(3).Surface),...
 	(md.results.TransientSolution(3).Thickness),...
Index: /issm/trunk/test/NightlyRun/test110.py
===================================================================
--- /issm/trunk/test/NightlyRun/test110.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test110.py	(revision 17806)
@@ -27,5 +27,5 @@
 	md.results.TransientSolution[0].Vel,\
 	md.results.TransientSolution[0].Pressure,\
-	md.results.TransientSolution[0].Bed,\
+	md.results.TransientSolution[0].Base,\
 	md.results.TransientSolution[0].Surface,\
 	md.results.TransientSolution[0].Thickness,\
@@ -35,5 +35,5 @@
 	md.results.TransientSolution[1].Vel,\
 	md.results.TransientSolution[1].Pressure,\
-	md.results.TransientSolution[1].Bed,\
+	md.results.TransientSolution[1].Base,\
 	md.results.TransientSolution[1].Surface,\
 	md.results.TransientSolution[1].Thickness,\
@@ -43,5 +43,5 @@
 	md.results.TransientSolution[2].Vel,\
 	md.results.TransientSolution[2].Pressure,\
-	md.results.TransientSolution[2].Bed,\
+	md.results.TransientSolution[2].Base,\
 	md.results.TransientSolution[2].Surface,\
 	md.results.TransientSolution[2].Thickness,\
Index: /issm/trunk/test/NightlyRun/test1101.m
===================================================================
--- /issm/trunk/test/NightlyRun/test1101.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test1101.m	(revision 17806)
@@ -25,5 +25,5 @@
 	md.stressbalance.spcvz=NaN*ones(md.mesh.numberofvertices,1);
 
-	pos=find(md.mesh.vertexonbed);
+	pos=find(md.mesh.vertexonbase);
 	md.stressbalance.spcvx(pos)=0.;
 	md.stressbalance.spcvy(pos)=0.;
Index: /issm/trunk/test/NightlyRun/test1101.py
===================================================================
--- /issm/trunk/test/NightlyRun/test1101.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test1101.py	(revision 17806)
@@ -39,5 +39,5 @@
 	md.stressbalance.spcvz=float('NaN')*numpy.ones((md.mesh.numberofvertices,1))
 
-	pos=numpy.nonzero(md.mesh.vertexonbed)
+	pos=numpy.nonzero(md.mesh.vertexonbase)
 	md.stressbalance.spcvx[pos]=0.
 	md.stressbalance.spcvy[pos]=0.
Index: /issm/trunk/test/NightlyRun/test1102.m
===================================================================
--- /issm/trunk/test/NightlyRun/test1102.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test1102.m	(revision 17806)
@@ -28,5 +28,5 @@
 
 	%Create dirichlet on the bed only
-	pos=find(md.mesh.vertexonbed);
+	pos=find(md.mesh.vertexonbase);
 	md.stressbalance.spcvx(pos)=0.;
 	md.stressbalance.spcvy(pos)=0.;
@@ -36,9 +36,9 @@
 %	posx=find(md.mesh.x==0.);
 %	posx2=find(md.mesh.x==max(md.mesh.x));
-%	posx=find(md.mesh.x==0. & md.mesh.y~=0. & md.mesh.y~=max(md.mesh.y) & ~md.mesh.vertexonbed);
-%	posx2=find(md.mesh.x==max(md.mesh.x) &  md.mesh.y~=0. & md.mesh.y~=max(md.mesh.y) & ~md.mesh.vertexonbed);
+%	posx=find(md.mesh.x==0. & md.mesh.y~=0. & md.mesh.y~=max(md.mesh.y) & ~md.mesh.vertexonbase);
+%	posx2=find(md.mesh.x==max(md.mesh.x) &  md.mesh.y~=0. & md.mesh.y~=max(md.mesh.y) & ~md.mesh.vertexonbase);
 
-%	posy=find(md.mesh.y==0. & md.mesh.x~=0. & md.mesh.x~=max(md.mesh.x) & ~md.mesh.vertexonbed); %Don't take the same nodes two times
-%	posy2=find(md.mesh.y==max(md.mesh.y) & md.mesh.x~=0. & md.mesh.x~=max(md.mesh.x) & ~md.mesh.vertexonbed);
+%	posy=find(md.mesh.y==0. & md.mesh.x~=0. & md.mesh.x~=max(md.mesh.x) & ~md.mesh.vertexonbase); %Don't take the same nodes two times
+%	posy2=find(md.mesh.y==max(md.mesh.y) & md.mesh.x~=0. & md.mesh.x~=max(md.mesh.x) & ~md.mesh.vertexonbase);
 
 %	md.stressbalance.vertex_pairing=[posx,posx2;posy,posy2];
Index: /issm/trunk/test/NightlyRun/test1102.py
===================================================================
--- /issm/trunk/test/NightlyRun/test1102.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test1102.py	(revision 17806)
@@ -42,5 +42,5 @@
 
 	#Create dirichlet on the bed only
-	pos=numpy.nonzero(md.mesh.vertexonbed)
+	pos=numpy.nonzero(md.mesh.vertexonbase)
 	md.stressbalance.spcvx[pos]=0.
 	md.stressbalance.spcvy[pos]=0.
@@ -50,9 +50,9 @@
 #	posx=numpy.nonzero(md.mesh.x==0.)[0]
 #	posx2=numpy.nonzero(md.mesh.x==numpy.max(md.mesh.x))[0]
-#	posx=numpy.nonzero(logical_and_n(md.mesh.x==0.,md.mesh.y!=0.,md.mesh.y!=numpy.max(md.mesh.y),numpy.logical_not(md.mesh.vertexonbed)))[0]
-#	posx2=numpy.nonzero(logical_and_n(md.mesh.x==numpy.max(md.mesh.x),md.mesh.y!=0.,md.mesh.y!=numpy.max(md.mesh.y),numpy.logical_not(md.mesh.vertexonbed)))[0]
+#	posx=numpy.nonzero(logical_and_n(md.mesh.x==0.,md.mesh.y!=0.,md.mesh.y!=numpy.max(md.mesh.y),numpy.logical_not(md.mesh.vertexonbase)))[0]
+#	posx2=numpy.nonzero(logical_and_n(md.mesh.x==numpy.max(md.mesh.x),md.mesh.y!=0.,md.mesh.y!=numpy.max(md.mesh.y),numpy.logical_not(md.mesh.vertexonbase)))[0]
 
-#	posy=numpy.nonzero(logical_and_n(md.mesh.y==0.,md.mesh.x!=0.,md.mesh.x!=numpy.max(md.mesh.x),numpy.logical_not(md.mesh.vertexonbed)))[0]    #Don't take the same nodes two times
-#	posy2=numpy.nonzero(logical_and_n(md.mesh.y==numpy.max(md.mesh.y),md.mesh.x!=0.,md.mesh.x!=numpy.max(md.mesh.x),numpy.logical_not(md.mesh.vertexonbed)))[0]
+#	posy=numpy.nonzero(logical_and_n(md.mesh.y==0.,md.mesh.x!=0.,md.mesh.x!=numpy.max(md.mesh.x),numpy.logical_not(md.mesh.vertexonbase)))[0]    #Don't take the same nodes two times
+#	posy2=numpy.nonzero(logical_and_n(md.mesh.y==numpy.max(md.mesh.y),md.mesh.x!=0.,md.mesh.x!=numpy.max(md.mesh.x),numpy.logical_not(md.mesh.vertexonbase)))[0]
 
 #	md.stressbalance.vertex_pairing=numpy.vstack((numpy.hstack((posx.reshape(-1,1)+1,posx2.reshape(-1,1)+1)),numpy.hstack((posy.reshape(-1,1)+1,posy2.reshape(-1,1)+1))))
Index: /issm/trunk/test/NightlyRun/test1103.m
===================================================================
--- /issm/trunk/test/NightlyRun/test1103.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test1103.m	(revision 17806)
@@ -24,5 +24,5 @@
 	md.stressbalance.spcvy=NaN*ones(md.mesh.numberofvertices,1);
 	md.stressbalance.spcvz=NaN*ones(md.mesh.numberofvertices,1);
-	pos=find(md.mesh.vertexonbed);
+	pos=find(md.mesh.vertexonbase);
 	md.stressbalance.spcvx(pos)=0.;
 	md.stressbalance.spcvy(pos)=0.;
Index: /issm/trunk/test/NightlyRun/test1103.py
===================================================================
--- /issm/trunk/test/NightlyRun/test1103.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test1103.py	(revision 17806)
@@ -38,5 +38,5 @@
 	md.stressbalance.spcvy=float('NaN')*numpy.ones((md.mesh.numberofvertices,1))
 	md.stressbalance.spcvz=float('NaN')*numpy.ones((md.mesh.numberofvertices,1))
-	pos=numpy.nonzero(md.mesh.vertexonbed)
+	pos=numpy.nonzero(md.mesh.vertexonbase)
 	md.stressbalance.spcvx[pos]=0.
 	md.stressbalance.spcvy[pos]=0.
Index: /issm/trunk/test/NightlyRun/test1104.m
===================================================================
--- /issm/trunk/test/NightlyRun/test1104.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test1104.m	(revision 17806)
@@ -21,5 +21,5 @@
 	md.stressbalance.spcvz=NaN*ones(md.mesh.numberofvertices,1);
 
-	pos=find(md.mesh.vertexonbed);
+	pos=find(md.mesh.vertexonbase);
 	md.stressbalance.spcvx(pos)=0.;
 	md.stressbalance.spcvy(pos)=0.;
Index: /issm/trunk/test/NightlyRun/test1104.py
===================================================================
--- /issm/trunk/test/NightlyRun/test1104.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test1104.py	(revision 17806)
@@ -33,5 +33,5 @@
 	md.stressbalance.spcvz=float('NaN')*numpy.ones((md.mesh.numberofvertices,1))
 
-	pos=numpy.nonzero(md.mesh.vertexonbed)
+	pos=numpy.nonzero(md.mesh.vertexonbase)
 	md.stressbalance.spcvx[pos]=0.
 	md.stressbalance.spcvy[pos]=0.
Index: /issm/trunk/test/NightlyRun/test1105.m
===================================================================
--- /issm/trunk/test/NightlyRun/test1105.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test1105.m	(revision 17806)
@@ -34,5 +34,5 @@
 
 	%Add spc on the corners
-	pos=find((md.mesh.x==0. | md.mesh.x==L) & (md.mesh.y==0. | md.mesh.y==L) & md.mesh.vertexonbed);
+	pos=find((md.mesh.x==0. | md.mesh.x==L) & (md.mesh.y==0. | md.mesh.y==L) & md.mesh.vertexonbase);
 	md.stressbalance.spcvx(pos)=0.;
 	md.stressbalance.spcvy(pos)=0.;
@@ -58,5 +58,5 @@
 	
 	%Spc the bed at zero for vz
-	pos=find(md.mesh.vertexonbed);
+	pos=find(md.mesh.vertexonbase);
 	md.stressbalance.spcvz(pos)=0.;
 
Index: /issm/trunk/test/NightlyRun/test1105.py
===================================================================
--- /issm/trunk/test/NightlyRun/test1105.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test1105.py	(revision 17806)
@@ -48,5 +48,5 @@
 
 	#Add spc on the corners
-	pos=numpy.nonzero(logical_and_n(numpy.logical_or(md.mesh.x==0.,md.mesh.x==L),numpy.logical_or(md.mesh.y==0.,md.mesh.y==L),md.mesh.vertexonbed))
+	pos=numpy.nonzero(logical_and_n(numpy.logical_or(md.mesh.x==0.,md.mesh.x==L),numpy.logical_or(md.mesh.y==0.,md.mesh.y==L),md.mesh.vertexonbase))
 	md.stressbalance.spcvx[pos]=0.
 	md.stressbalance.spcvy[pos]=0.
@@ -71,5 +71,5 @@
 	
 	#Spc the bed at zero for vz
-	pos=numpy.nonzero(md.mesh.vertexonbed)
+	pos=numpy.nonzero(md.mesh.vertexonbase)
 	md.stressbalance.spcvz[pos]=0.
 
Index: /issm/trunk/test/NightlyRun/test1106.m
===================================================================
--- /issm/trunk/test/NightlyRun/test1106.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test1106.m	(revision 17806)
@@ -66,5 +66,5 @@
 	1e-12,1e-12,1e-12,...
 	1e-12,2e-12,2e-12,...
-	1e-11,2e-12,2e-12,...
+	1e-11,2e-12,3e-12,...
 	1e-11,2e-11,2e-12,...
 };
Index: /issm/trunk/test/NightlyRun/test1107.m
===================================================================
--- /issm/trunk/test/NightlyRun/test1107.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test1107.m	(revision 17806)
@@ -26,6 +26,6 @@
 
 	%Create MPCs to have periodic boundary conditions
-	posx=find(md.mesh.x==0. & ~(md.mesh.y==0. & md.mesh.vertexonbed) & ~(md.mesh.y==L & md.mesh.vertexonbed));
-	posx2=find(md.mesh.x==max(md.mesh.x) & ~(md.mesh.y==0. & md.mesh.vertexonbed) & ~(md.mesh.y==L & md.mesh.vertexonbed));
+	posx=find(md.mesh.x==0. & ~(md.mesh.y==0. & md.mesh.vertexonbase) & ~(md.mesh.y==L & md.mesh.vertexonbase));
+	posx2=find(md.mesh.x==max(md.mesh.x) & ~(md.mesh.y==0. & md.mesh.vertexonbase) & ~(md.mesh.y==L & md.mesh.vertexonbase));
 
 	posy=find(md.mesh.y==0. & md.mesh.x~=0. & md.mesh.x~=max(md.mesh.x)); %Don't take the same nodes two times
@@ -35,5 +35,5 @@
 
 	%Add spc on the corners
-	pos=find((md.mesh.x==0. | md.mesh.x==L) & (md.mesh.y==0. | md.mesh.y==L) & md.mesh.vertexonbed);
+	pos=find((md.mesh.x==0. | md.mesh.x==L) & (md.mesh.y==0. | md.mesh.y==L) & md.mesh.vertexonbase);
 	md.stressbalance.spcvy(:)=0.;
 	md.stressbalance.spcvx(pos)=0.;
@@ -53,5 +53,5 @@
 	
 	%Spc the bed at zero for vz
-	pos=find(md.mesh.vertexonbed);
+	pos=find(md.mesh.vertexonbase);
 	md.stressbalance.spcvz(pos)=0.;
 
Index: /issm/trunk/test/NightlyRun/test1107.py
===================================================================
--- /issm/trunk/test/NightlyRun/test1107.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test1107.py	(revision 17806)
@@ -40,8 +40,8 @@
 
 	#Create MPCs to have periodic boundary conditions
-#	posx=find(md.mesh.x==0. & ~(md.mesh.y==0. & md.mesh.vertexonbed) & ~(md.mesh.y==L & md.mesh.vertexonbed));
-	posx=numpy.nonzero(logical_and_n(md.mesh.x==0.,numpy.logical_not(numpy.logical_and(md.mesh.y==0.,md.mesh.vertexonbed)),numpy.logical_not(numpy.logical_and(md.mesh.y==L,md.mesh.vertexonbed))))[0]
-#	posx2=find(md.mesh.x==max(md.mesh.x) & ~(md.mesh.y==0. & md.mesh.vertexonbed) & ~(md.mesh.y==L & md.mesh.vertexonbed));
-	posx2=numpy.nonzero(logical_and_n(md.mesh.x==numpy.max(md.mesh.x),numpy.logical_not(numpy.logical_and(md.mesh.y==0.,md.mesh.vertexonbed)),numpy.logical_not(numpy.logical_and(md.mesh.y==L,md.mesh.vertexonbed))))[0]
+#	posx=find(md.mesh.x==0. & ~(md.mesh.y==0. & md.mesh.vertexonbase) & ~(md.mesh.y==L & md.mesh.vertexonbase));
+	posx=numpy.nonzero(logical_and_n(md.mesh.x==0.,numpy.logical_not(numpy.logical_and(md.mesh.y==0.,md.mesh.vertexonbase)),numpy.logical_not(numpy.logical_and(md.mesh.y==L,md.mesh.vertexonbase))))[0]
+#	posx2=find(md.mesh.x==max(md.mesh.x) & ~(md.mesh.y==0. & md.mesh.vertexonbase) & ~(md.mesh.y==L & md.mesh.vertexonbase));
+	posx2=numpy.nonzero(logical_and_n(md.mesh.x==numpy.max(md.mesh.x),numpy.logical_not(numpy.logical_and(md.mesh.y==0.,md.mesh.vertexonbase)),numpy.logical_not(numpy.logical_and(md.mesh.y==L,md.mesh.vertexonbase))))[0]
 
 	posy=numpy.nonzero(logical_and_n(md.mesh.y==0.,md.mesh.x!=0.,md.mesh.x!=numpy.max(md.mesh.x)))[0]    #Don't take the same nodes two times
@@ -51,5 +51,5 @@
 
 	#Add spc on the corners
-	pos=numpy.nonzero(logical_and_n(numpy.logical_or(md.mesh.x==0.,md.mesh.x==L),numpy.logical_or(md.mesh.y==0.,md.mesh.y==L),md.mesh.vertexonbed))
+	pos=numpy.nonzero(logical_and_n(numpy.logical_or(md.mesh.x==0.,md.mesh.x==L),numpy.logical_or(md.mesh.y==0.,md.mesh.y==L),md.mesh.vertexonbase))
 	md.stressbalance.spcvy[:]=0.
 	md.stressbalance.spcvx[pos]=0.
@@ -68,5 +68,5 @@
 	
 	#Spc the bed at zero for vz
-	pos=numpy.nonzero(md.mesh.vertexonbed)
+	pos=numpy.nonzero(md.mesh.vertexonbase)
 	md.stressbalance.spcvz[pos]=0.
 
Index: /issm/trunk/test/NightlyRun/test1108.m
===================================================================
--- /issm/trunk/test/NightlyRun/test1108.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test1108.m	(revision 17806)
@@ -22,5 +22,5 @@
 	md.stressbalance.spcvz=NaN*ones(md.mesh.numberofvertices,1);
 	
-	pos=find(md.mesh.vertexonbed & (md.mesh.x==0. | md.mesh.x==max(md.mesh.x)) & (md.mesh.y==0. | md.mesh.y==max(md.mesh.y)));
+	pos=find(md.mesh.vertexonbase & (md.mesh.x==0. | md.mesh.x==max(md.mesh.x)) & (md.mesh.y==0. | md.mesh.y==max(md.mesh.y)));
 	md.stressbalance.spcvx(pos)=0.;
 	md.stressbalance.spcvy(pos)=0.;
@@ -38,5 +38,4 @@
 	%Compute the stressbalance
 	md.cluster=generic('name',oshostname(),'np',8);
-	md.verbose=verbose('convergence',true);
 	md=solve(md,StressbalanceSolutionEnum());
 	md.stressbalance.reltol=NaN;
@@ -73,5 +72,5 @@
 field_tolerances={...
 	1e-07,1e-07,1e-07,...
-	1e-08,1e-08,1e-08,...
+	1e-08,2e-08,1e-08,...
 	1e-08,1e-07,1e-07,...
 	1e-08,1e-08,2e-08,...
Index: /issm/trunk/test/NightlyRun/test1108.py
===================================================================
--- /issm/trunk/test/NightlyRun/test1108.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test1108.py	(revision 17806)
@@ -34,5 +34,5 @@
 	md.stressbalance.spcvz=float('NaN')*numpy.ones((md.mesh.numberofvertices,1))
 	
-	pos=numpy.nonzero(logical_and_n(md.mesh.vertexonbed,numpy.logical_or(md.mesh.x==0.,md.mesh.x==numpy.max(md.mesh.x)),numpy.logical_or(md.mesh.y==0.,md.mesh.y==numpy.max(md.mesh.y))))
+	pos=numpy.nonzero(logical_and_n(md.mesh.vertexonbase,numpy.logical_or(md.mesh.x==0.,md.mesh.x==numpy.max(md.mesh.x)),numpy.logical_or(md.mesh.y==0.,md.mesh.y==numpy.max(md.mesh.y))))
 	md.stressbalance.spcvx[pos]=0.
 	md.stressbalance.spcvy[pos]=0.
Index: /issm/trunk/test/NightlyRun/test1109.m
===================================================================
--- /issm/trunk/test/NightlyRun/test1109.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test1109.m	(revision 17806)
@@ -31,5 +31,5 @@
 
 	%Create spcs on the bed 
-	pos=find(md.mesh.vertexonbed);
+	pos=find(md.mesh.vertexonbase);
 	md.stressbalance.spcvx=NaN*ones(md.mesh.numberofvertices,1);
 	md.stressbalance.spcvy=NaN*ones(md.mesh.numberofvertices,1);
Index: /issm/trunk/test/NightlyRun/test111.m
===================================================================
--- /issm/trunk/test/NightlyRun/test111.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test111.m	(revision 17806)
@@ -23,5 +23,5 @@
 	(md.results.TransientSolution(1).Vel),...
 	(md.results.TransientSolution(1).Pressure),...
-	(md.results.TransientSolution(1).Bed),...
+	(md.results.TransientSolution(1).Base),...
 	(md.results.TransientSolution(1).Surface),...
 	(md.results.TransientSolution(1).Thickness),...
@@ -34,5 +34,5 @@
 	(md.results.TransientSolution(2).Vel),...
 	(md.results.TransientSolution(2).Pressure),...
-	(md.results.TransientSolution(2).Bed),...
+	(md.results.TransientSolution(2).Base),...
 	(md.results.TransientSolution(2).Surface),...
 	(md.results.TransientSolution(2).Thickness),...
@@ -45,5 +45,5 @@
 	(md.results.TransientSolution(3).Vel),...
 	(md.results.TransientSolution(3).Pressure),...
-	(md.results.TransientSolution(3).Bed),...
+	(md.results.TransientSolution(3).Base),...
 	(md.results.TransientSolution(3).Surface),...
 	(md.results.TransientSolution(3).Thickness),...
Index: /issm/trunk/test/NightlyRun/test111.py
===================================================================
--- /issm/trunk/test/NightlyRun/test111.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test111.py	(revision 17806)
@@ -32,5 +32,5 @@
 	md.results.TransientSolution[0].Vel,\
 	md.results.TransientSolution[0].Pressure,\
-	md.results.TransientSolution[0].Bed,\
+	md.results.TransientSolution[0].Base,\
 	md.results.TransientSolution[0].Surface,\
 	md.results.TransientSolution[0].Thickness,\
@@ -43,5 +43,5 @@
 	md.results.TransientSolution[1].Vel,\
 	md.results.TransientSolution[1].Pressure,\
-	md.results.TransientSolution[1].Bed,\
+	md.results.TransientSolution[1].Base,\
 	md.results.TransientSolution[1].Surface,\
 	md.results.TransientSolution[1].Thickness,\
@@ -54,5 +54,5 @@
 	md.results.TransientSolution[2].Vel,\
 	md.results.TransientSolution[2].Pressure,\
-	md.results.TransientSolution[2].Bed,\
+	md.results.TransientSolution[2].Base,\
 	md.results.TransientSolution[2].Surface,\
 	md.results.TransientSolution[2].Thickness,\
Index: /issm/trunk/test/NightlyRun/test1110.m
===================================================================
--- /issm/trunk/test/NightlyRun/test1110.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test1110.m	(revision 17806)
@@ -26,15 +26,15 @@
 	if (i==1 | i==3),
 		%Create dirichlet on the bed if no slip
-		pos=find(md.mesh.vertexonbed);
+		pos=find(md.mesh.vertexonbase);
 		md.stressbalance.spcvx(pos)=0.;
 		md.stressbalance.spcvy(pos)=0.;
 		md.stressbalance.spcvz(pos)=0.;
 	else
-		pos=find(md.mesh.vertexonbed & (md.mesh.x==0. | md.mesh.x==max(md.mesh.x)) & (md.mesh.y==0. | md.mesh.y==max(md.mesh.y)));
+		pos=find(md.mesh.vertexonbase & (md.mesh.x==0. | md.mesh.x==max(md.mesh.x)) & (md.mesh.y==0. | md.mesh.y==max(md.mesh.y)));
 		md.stressbalance.spcvx(pos)=100.; %because we need a dirichlet somewhere
 		md.stressbalance.spcvy(pos)=0.;
 		md.stressbalance.spcvz(pos)=0.;
 	end
-	pos=find(~md.mesh.vertexonbed);
+	pos=find(~md.mesh.vertexonbase);
 	md.thermal.spctemperature(pos)=255.;
 
@@ -116,5 +116,5 @@
 	1e-10,1e-09,1e-09,1e-10,...
 	1e-08,1e-09,1e-08,1e-09,...
-	1e-08,1e-09,1e-08,1e-09,...
+	1e-08,2e-09,1e-08,1e-09,...
 };
 field_values={};
Index: /issm/trunk/test/NightlyRun/test119.m
===================================================================
--- /issm/trunk/test/NightlyRun/test119.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test119.m	(revision 17806)
@@ -1,10 +1,10 @@
 
 %Simple mesh
-md=bamg(model(),'domain','../Exp/Square.exp','hmax',100000.);
+md=bamg(model(),'domain','../Exp/Square.exp','hmax',100000.,'rand',false);
 x1=md.mesh.x;
 y1=md.mesh.y;
 
 %hVertices
-md=bamg(model(),'domain','../Exp/Square.exp','hmax',300000.,'hVertices',[10000. 100000. 400000. 100000.]');
+md=bamg(model(),'domain','../Exp/Square.exp','hmax',300000.,'hVertices',[10000. 100000. 400000. 100000.]','rand',false);
 x2=md.mesh.x;
 y2=md.mesh.y;
@@ -12,14 +12,19 @@
 %big mesh
 t0=clock;
-md=bamg(model(),'domain','../Exp/Square.exp','hmax',3000.);
+md=bamg(model(),'domain','../Exp/Square.exp','hmax',3000.,'rand',false);
 nbelements=md.mesh.numberofelements;
+if nbelements>267895-50 & nbelements<267895+50
+	nbewithinrange = 1.;
+else
+	nbewithinrange = 0.;
+end
 elapsedtime=etime(clock,t0);
 
 %Fields and tolerances to track changes
 field_names     ={'x1','y1','x2','y2','nbelements','elapsed time'};
-field_tolerances={1e-13,1e-13,1e-13,1e-13,1e-13,1.5};
+field_tolerances={2e-9,2e-9,1e-13,1e-13,1e-13,4.};
 field_values={...
 	x1, y1,...
 	x2, y2,...
-	nbelements,elapsedtime...
+	nbewithinrange,elapsedtime...
 	};
Index: /issm/trunk/test/NightlyRun/test119.py
===================================================================
--- /issm/trunk/test/NightlyRun/test119.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test119.py	(revision 17806)
@@ -6,10 +6,10 @@
 
 #Simple mesh
-md=bamg(model(),'domain','../Exp/Square.exp','hmax',100000.)
+md=bamg(model(),'domain','../Exp/Square.exp','hmax',100000.,'rand',False)
 x1=md.mesh.x
 y1=md.mesh.y
 
 #hVertices
-md=bamg(model(),'domain','../Exp/Square.exp','hmax',300000.,'hVertices',numpy.array([10000.,100000.,400000.,100000.]).reshape(-1,1))
+md=bamg(model(),'domain','../Exp/Square.exp','hmax',300000.,'hVertices',numpy.array([10000.,100000.,400000.,100000.]).reshape(-1,1),'rand',False)
 x2=md.mesh.x
 y2=md.mesh.y
@@ -17,14 +17,18 @@
 #big mesh
 t0=time.time()
-md=bamg(model(),'domain','../Exp/Square.exp','hmax',3000.)
+md=bamg(model(),'domain','../Exp/Square.exp','hmax',3000.,'rand',False)
 nbelements=md.mesh.numberofelements
 elapsedtime=time.time()-t0
+if nbelements>267895-50 and nbelements<267895+50:
+	nbewithinrange = 1.
+else:
+	nbewithinrange = 0.
 
 #Fields and tolerances to track changes
 field_names     =['x1','y1','x2','y2','nbelements','elapsed time']
-field_tolerances=[1e-13,1e-13,1e-13,1e-13,1e-13,1.5]
+field_tolerances=[2e-9,2e-9,1e-13,1e-13,1e-13,4.0]
 field_values=[\
 	x1, y1,\
 	x2, y2,\
-	nbelements,elapsedtime,\
+	nbewithinrange,elapsedtime,\
 	]
Index: /issm/trunk/test/NightlyRun/test1205.m
===================================================================
--- /issm/trunk/test/NightlyRun/test1205.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test1205.m	(revision 17806)
@@ -22,5 +22,5 @@
 
 %Spc the nodes on the bed
-pos=find(md.mesh.vertexonbed);
+pos=find(md.mesh.vertexonbase);
 md.stressbalance.spcvx(pos)=0.;
 md.stressbalance.spcvy(pos)=0.;
Index: /issm/trunk/test/NightlyRun/test1205.py
===================================================================
--- /issm/trunk/test/NightlyRun/test1205.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test1205.py	(revision 17806)
@@ -35,5 +35,5 @@
 
 #Spc the nodes on the bed
-pos=numpy.nonzero(md.mesh.vertexonbed)
+pos=numpy.nonzero(md.mesh.vertexonbase)
 md.stressbalance.spcvx[pos]=0.
 md.stressbalance.spcvy[pos]=0.
Index: /issm/trunk/test/NightlyRun/test1206.m
===================================================================
--- /issm/trunk/test/NightlyRun/test1206.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test1206.m	(revision 17806)
@@ -22,5 +22,5 @@
 
 %Spc the nodes on the bed
-pos=find(md.mesh.vertexonbed);
+pos=find(md.mesh.vertexonbase);
 md.stressbalance.spcvx(pos)=0.;
 md.stressbalance.spcvy(pos)=0.;
Index: /issm/trunk/test/NightlyRun/test1206.py
===================================================================
--- /issm/trunk/test/NightlyRun/test1206.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test1206.py	(revision 17806)
@@ -35,5 +35,5 @@
 
 #Spc the nodes on the bed
-pos=numpy.nonzero(md.mesh.vertexonbed)
+pos=numpy.nonzero(md.mesh.vertexonbase)
 md.stressbalance.spcvx[pos]=0.
 md.stressbalance.spcvy[pos]=0.
Index: /issm/trunk/test/NightlyRun/test1207.m
===================================================================
--- /issm/trunk/test/NightlyRun/test1207.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test1207.m	(revision 17806)
@@ -22,5 +22,5 @@
 
 %Spc the nodes on the bed
-pos=find(md.mesh.vertexonbed);
+pos=find(md.mesh.vertexonbase);
 md.stressbalance.spcvx(pos)=0.;
 md.stressbalance.spcvy(pos)=0.;
Index: /issm/trunk/test/NightlyRun/test1207.py
===================================================================
--- /issm/trunk/test/NightlyRun/test1207.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test1207.py	(revision 17806)
@@ -35,5 +35,5 @@
 
 #Spc the nodes on the bed
-pos=numpy.nonzero(md.mesh.vertexonbed)
+pos=numpy.nonzero(md.mesh.vertexonbase)
 md.stressbalance.spcvx[pos]=0.
 md.stressbalance.spcvy[pos]=0.
Index: /issm/trunk/test/NightlyRun/test1208.m
===================================================================
--- /issm/trunk/test/NightlyRun/test1208.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test1208.m	(revision 17806)
@@ -13,5 +13,5 @@
 
 %Spc the nodes on the bed
-pos=find(md.mesh.vertexonbed);
+pos=find(md.mesh.vertexonbase);
 md.stressbalance.spcvx(pos)=0.;
 md.stressbalance.spcvy(pos)=0.;
@@ -30,6 +30,6 @@
 
 %Fields and tolerances to track changes
-field_names     ={'Vx','Vy','Vz','Vel','Pressure','Thickness','Bed','Surface','Temperature','BasalforcingsMeltingRate'};
-field_tolerances={1e-08,1e-08,1e-07,1e-08,1e-08,1e-08,1e-08,1e-08,1e-07,2e-07};
+field_names     ={'Vx','Vy','Vz','Vel','Pressure','Thickness','Base','Surface','Temperature','BasalforcingsMeltingRate'};
+field_tolerances={1e-08,1e-08,1e-07,1e-08,1e-08,1e-08,1e-08,1e-08,1e-07,3e-07};
 field_values={...
 	(md.results.TransientSolution(end).Vx),...
@@ -39,5 +39,5 @@
 	(md.results.TransientSolution(end).Pressure),...
 	(md.results.TransientSolution(end).Thickness),...
-	(md.results.TransientSolution(end).Bed),...
+	(md.results.TransientSolution(end).Base),...
 	(md.results.TransientSolution(end).Surface),...
 	(md.results.TransientSolution(end).Temperature),...
Index: /issm/trunk/test/NightlyRun/test1208.py
===================================================================
--- /issm/trunk/test/NightlyRun/test1208.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test1208.py	(revision 17806)
@@ -26,5 +26,5 @@
 
 #Spc the nodes on the bed
-pos=numpy.nonzero(md.mesh.vertexonbed)
+pos=numpy.nonzero(md.mesh.vertexonbase)
 md.stressbalance.spcvx[pos]=0.
 md.stressbalance.spcvy[pos]=0.
@@ -43,5 +43,5 @@
 
 #Fields and tolerances to track changes
-field_names     =['Vx','Vy','Vz','Vel','Pressure','Thickness','Bed','Surface','Temperature','BasalforcingsMeltingRate']
+field_names     =['Vx','Vy','Vz','Vel','Pressure','Thickness','Base','Surface','Temperature','BasalforcingsMeltingRate']
 field_tolerances=[1e-08,1e-08,1e-07,1e-08,1e-08,1e-08,1e-08,1e-08,1e-07,1e-07]
 field_values=[\
@@ -52,5 +52,5 @@
 	md.results.TransientSolution[-1].Pressure,\
 	md.results.TransientSolution[-1].Thickness,\
-	md.results.TransientSolution[-1].Bed,\
+	md.results.TransientSolution[-1].Base,\
 	md.results.TransientSolution[-1].Surface,\
 	md.results.TransientSolution[-1].Temperature,\
Index: /issm/trunk/test/NightlyRun/test122.m
===================================================================
--- /issm/trunk/test/NightlyRun/test122.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test122.m	(revision 17806)
@@ -26,5 +26,5 @@
 	(md.results.TransientSolution(1).Vel),...
 	(md.results.TransientSolution(1).Pressure),...
-	(md.results.TransientSolution(1).Bed),...
+	(md.results.TransientSolution(1).Base),...
 	(md.results.TransientSolution(1).Surface),...
 	(md.results.TransientSolution(1).Thickness),...
@@ -37,5 +37,5 @@
 	(md.results.TransientSolution(2).Vel),...
 	(md.results.TransientSolution(2).Pressure),...
-	(md.results.TransientSolution(2).Bed),...
+	(md.results.TransientSolution(2).Base),...
 	(md.results.TransientSolution(2).Surface),...
 	(md.results.TransientSolution(2).Thickness),...
@@ -48,5 +48,5 @@
 	(md.results.TransientSolution(3).Vel),...
 	(md.results.TransientSolution(3).Pressure),...
-	(md.results.TransientSolution(3).Bed),...
+	(md.results.TransientSolution(3).Base),...
 	(md.results.TransientSolution(3).Surface),...
 	(md.results.TransientSolution(3).Thickness),...
Index: /issm/trunk/test/NightlyRun/test122.py
===================================================================
--- /issm/trunk/test/NightlyRun/test122.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test122.py	(revision 17806)
@@ -35,5 +35,5 @@
 	md.results.TransientSolution[0].Vel,\
 	md.results.TransientSolution[0].Pressure,\
-	md.results.TransientSolution[0].Bed,\
+	md.results.TransientSolution[0].Base,\
 	md.results.TransientSolution[0].Surface,\
 	md.results.TransientSolution[0].Thickness,\
@@ -46,5 +46,5 @@
 	md.results.TransientSolution[1].Vel,\
 	md.results.TransientSolution[1].Pressure,\
-	md.results.TransientSolution[1].Bed,\
+	md.results.TransientSolution[1].Base,\
 	md.results.TransientSolution[1].Surface,\
 	md.results.TransientSolution[1].Thickness,\
@@ -57,5 +57,5 @@
 	md.results.TransientSolution[2].Vel,\
 	md.results.TransientSolution[2].Pressure,\
-	md.results.TransientSolution[2].Bed,\
+	md.results.TransientSolution[2].Base,\
 	md.results.TransientSolution[2].Surface,\
 	md.results.TransientSolution[2].Thickness,\
Index: /issm/trunk/test/NightlyRun/test123.m
===================================================================
--- /issm/trunk/test/NightlyRun/test123.m	(revision 17806)
+++ /issm/trunk/test/NightlyRun/test123.m	(revision 17806)
@@ -0,0 +1,23 @@
+md=triangle(model(),'../Exp/Square.exp',180000.);
+md=setmask(md,'all','');
+md=parameterize(md,'../Par/SquareShelfConstrained.par');
+md=setflowequation(md,'SSA','all');
+md.cluster=generic('name',oshostname(),'np',3);
+
+fake_surface=[[md.geometry.surface+100;1.1],...
+[md.geometry.surface+200;2.1],...
+[md.geometry.surface+300;2.5]];
+
+md.transient.requested_outputs={'default','SurfaceMisfit'};
+md.outputdefinition.definitions={misfit('name','SurfaceMisfit', 'model_enum',SurfaceEnum,'observation_enum',SurfaceObservationEnum,'observation',fake_surface,'timeinterpolation','nearestneighbor','weights',ones(md.mesh.numberofvertices,1),'weights_enum',WeightsSurfaceObservationEnum)};
+
+md=solve(md,TransientSolutionEnum());
+
+%Fields and tolerances to track changes
+field_names     ={'SurfaceMisfitFirstStep','SurfaceMisfitSecondStep','SurfaceMisfitThirdStep'};
+field_tolerances={1e-13,1e-13,1e-13};
+field_values={...
+	(md.results.TransientSolution(1).SurfaceMisfit),...
+	(md.results.TransientSolution(2).SurfaceMisfit),...
+	(md.results.TransientSolution(3).SurfaceMisfit)
+	};
Index: /issm/trunk/test/NightlyRun/test124.m
===================================================================
--- /issm/trunk/test/NightlyRun/test124.m	(revision 17806)
+++ /issm/trunk/test/NightlyRun/test124.m	(revision 17806)
@@ -0,0 +1,47 @@
+md=triangle(model(),'../Exp/Square.exp',150000.);
+md=setmask(md,'all','');
+md=parameterize(md,'../Par/SquareShelfConstrained.par');
+md=extrude(md,3,1.);
+md=setflowequation(md,'FS','all');
+
+%Free surface
+md.masstransport.isfreesurface=1;
+md.timestepping.time_step=0.00001;
+md.timestepping.final_time=0.00005;
+
+%Go solve
+md.cluster=generic('name',oshostname(),'np',3);
+md=solve(md,TransientSolutionEnum());
+
+%Fields and tolerances to track changes
+field_names     ={...
+	'Vx1','Vy1','Vel1','Pressure1','Bed1','Surface1','Thickness1',...
+	'Vx2','Vy2','Vel2','Pressure2','Bed2','Surface2','Thickness2',...
+	'Vx3','Vy3','Vel3','Pressure3','Bed3','Surface3','Thickness3'};
+field_tolerances={...
+	1e-09,3e-10,3e-10,1e-10,1e-13,1e-13,1e-13,...
+	1e-09,3e-10,3e-10,1e-10,1e-10,1e-10,1e-10,...
+	1e-09,3e-10,3e-10,1e-10,1e-10,1e-10,1e-10};
+field_values={...
+	(md.results.TransientSolution(1).Vx),...
+	(md.results.TransientSolution(1).Vy),...
+	(md.results.TransientSolution(1).Vel),...
+	(md.results.TransientSolution(1).Pressure),...
+	(md.results.TransientSolution(1).Base),...
+	(md.results.TransientSolution(1).Surface),...
+	(md.results.TransientSolution(1).Thickness),...
+	(md.results.TransientSolution(2).Vx),...
+	(md.results.TransientSolution(2).Vy),...
+	(md.results.TransientSolution(2).Vel),...
+	(md.results.TransientSolution(2).Pressure),...
+	(md.results.TransientSolution(2).Base),...
+	(md.results.TransientSolution(2).Surface),...
+	(md.results.TransientSolution(2).Thickness),...
+	(md.results.TransientSolution(3).Vx),...
+	(md.results.TransientSolution(3).Vy),...
+	(md.results.TransientSolution(3).Vel),...
+	(md.results.TransientSolution(3).Pressure),...
+	(md.results.TransientSolution(3).Base),...
+	(md.results.TransientSolution(3).Surface),...
+	(md.results.TransientSolution(3).Thickness),...
+	};
Index: /issm/trunk/test/NightlyRun/test1302.m
===================================================================
--- /issm/trunk/test/NightlyRun/test1302.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test1302.m	(revision 17806)
@@ -12,5 +12,5 @@
 
 %Thermal boundary conditions
-pos1=find(md.mesh.elementonbed);     md.thermal.spctemperature(md.mesh.elements(pos1,1:3))=10.;
+pos1=find(md.mesh.elementonbase);     md.thermal.spctemperature(md.mesh.elements(pos1,1:3))=10.;
 pos2=find(md.mesh.elementonsurface); md.thermal.spctemperature(md.mesh.elements(pos2,4:6))=0.;
 md.initialization.vz=0.1*ones(md.mesh.numberofvertices,1);
Index: /issm/trunk/test/NightlyRun/test1302.py
===================================================================
--- /issm/trunk/test/NightlyRun/test1302.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test1302.py	(revision 17806)
@@ -26,5 +26,5 @@
 
 #Thermal boundary conditions
-pos1=numpy.nonzero(md.mesh.elementonbed)[0]
+pos1=numpy.nonzero(md.mesh.elementonbase)[0]
 md.thermal.spctemperature[md.mesh.elements[pos1,0:3]-1]=10.
 pos2=numpy.nonzero(md.mesh.elementonsurface)[0]
Index: /issm/trunk/test/NightlyRun/test1303.m
===================================================================
--- /issm/trunk/test/NightlyRun/test1303.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test1303.m	(revision 17806)
@@ -12,5 +12,5 @@
 md=setflowequation(md,'HO','all');
 
-pos1=find(md.mesh.elementonbed);     md.thermal.spctemperature(md.mesh.elements(pos1,1:3))=10.;
+pos1=find(md.mesh.elementonbase);     md.thermal.spctemperature(md.mesh.elements(pos1,1:3))=10.;
 pos2=find(md.mesh.elementonsurface); md.thermal.spctemperature(md.mesh.elements(pos2,4:6))=0.;
 md.initialization.pressure=zeros(md.mesh.numberofvertices,1);
Index: /issm/trunk/test/NightlyRun/test1303.py
===================================================================
--- /issm/trunk/test/NightlyRun/test1303.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test1303.py	(revision 17806)
@@ -26,5 +26,5 @@
 md=setflowequation(md,'HO','all')
 
-pos1=numpy.nonzero(md.mesh.elementonbed)[0]
+pos1=numpy.nonzero(md.mesh.elementonbase)[0]
 md.thermal.spctemperature[md.mesh.elements[pos1,0:3]-1]=10.
 pos2=numpy.nonzero(md.mesh.elementonsurface)[0]
Index: /issm/trunk/test/NightlyRun/test1501.m
===================================================================
--- /issm/trunk/test/NightlyRun/test1501.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test1501.m	(revision 17806)
@@ -51,5 +51,5 @@
 	(md.results.TransientSolution(400).Vel),...
 	(md.results.TransientSolution(400).Pressure),...
-	(md.results.TransientSolution(400).Bed),...
+	(md.results.TransientSolution(400).Base),...
 	(md.results.TransientSolution(400).Surface),...
 	(md.results.TransientSolution(400).Thickness),...
@@ -59,5 +59,5 @@
 	(md.results.TransientSolution(800).Vel),...
 	(md.results.TransientSolution(800).Pressure),...
-	(md.results.TransientSolution(800).Bed),...
+	(md.results.TransientSolution(800).Base),...
 	(md.results.TransientSolution(800).Surface),...
 	(md.results.TransientSolution(800).Thickness),...
@@ -67,5 +67,5 @@
 	(md.results.TransientSolution(1200).Vel),...
 	(md.results.TransientSolution(1200).Pressure),...
-	(md.results.TransientSolution(1200).Bed),...
+	(md.results.TransientSolution(1200).Base),...
 	(md.results.TransientSolution(1200).Surface),...
 	(md.results.TransientSolution(1200).Thickness),...
@@ -75,5 +75,5 @@
 	(md.results.TransientSolution(1600).Vel),...
 	(md.results.TransientSolution(1600).Pressure),...
-	(md.results.TransientSolution(1600).Bed),...
+	(md.results.TransientSolution(1600).Base),...
 	(md.results.TransientSolution(1600).Surface),...
 	(md.results.TransientSolution(1600).Thickness),...
@@ -83,5 +83,5 @@
 	(md.results.TransientSolution(2000).Vel),...
 	(md.results.TransientSolution(2000).Pressure),...
-	(md.results.TransientSolution(2000).Bed),...
+	(md.results.TransientSolution(2000).Base),...
 	(md.results.TransientSolution(2000).Surface),...
 	(md.results.TransientSolution(2000).Thickness),...
Index: /issm/trunk/test/NightlyRun/test1501.py
===================================================================
--- /issm/trunk/test/NightlyRun/test1501.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test1501.py	(revision 17806)
@@ -64,5 +64,5 @@
 	md.results.TransientSolution[400-1].Vel,\
 	md.results.TransientSolution[400-1].Pressure,\
-	md.results.TransientSolution[400-1].Bed,\
+	md.results.TransientSolution[400-1].Base,\
 	md.results.TransientSolution[400-1].Surface,\
 	md.results.TransientSolution[400-1].Thickness,\
@@ -72,5 +72,5 @@
 	md.results.TransientSolution[800-1].Vel,\
 	md.results.TransientSolution[800-1].Pressure,\
-	md.results.TransientSolution[800-1].Bed,\
+	md.results.TransientSolution[800-1].Base,\
 	md.results.TransientSolution[800-1].Surface,\
 	md.results.TransientSolution[800-1].Thickness,\
@@ -80,5 +80,5 @@
 	md.results.TransientSolution[1200-1].Vel,\
 	md.results.TransientSolution[1200-1].Pressure,\
-	md.results.TransientSolution[1200-1].Bed,\
+	md.results.TransientSolution[1200-1].Base,\
 	md.results.TransientSolution[1200-1].Surface,\
 	md.results.TransientSolution[1200-1].Thickness,\
@@ -88,5 +88,5 @@
 	md.results.TransientSolution[1600-1].Vel,\
 	md.results.TransientSolution[1600-1].Pressure,\
-	md.results.TransientSolution[1600-1].Bed,\
+	md.results.TransientSolution[1600-1].Base,\
 	md.results.TransientSolution[1600-1].Surface,\
 	md.results.TransientSolution[1600-1].Thickness,\
@@ -96,5 +96,5 @@
 	md.results.TransientSolution[2000-1].Vel,\
 	md.results.TransientSolution[2000-1].Pressure,\
-	md.results.TransientSolution[2000-1].Bed,\
+	md.results.TransientSolution[2000-1].Base,\
 	md.results.TransientSolution[2000-1].Surface,\
 	md.results.TransientSolution[2000-1].Thickness,\
Index: /issm/trunk/test/NightlyRun/test1502.m
===================================================================
--- /issm/trunk/test/NightlyRun/test1502.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test1502.m	(revision 17806)
@@ -1,25 +1,23 @@
 printingflag = false;
 
-md=triangle(model(),'../Exp/Square.exp',450000.);
+md=triangle(model(),'../Exp/Square.exp',350000.);
 md=setmask(md,'all','');
 md=parameterize(md,'../Par/SquareShelf.par');
 md=setflowequation(md,'SSA','all');
-%md=extrude(md,3,1.);
+md=extrude(md,3,1.);
 md.cluster=generic('name',oshostname(),'np',1);
 md.transient.isthermal=0;
 
-%md.timestepping.time_step=1.;
-%md.settings.output_frequency=1;
-%md.timestepping.final_time=2000.;
+md.timestepping.time_step=1.;
+md.settings.output_frequency=1;
+md.timestepping.final_time=2000.;
 
 %Solve for thinning rate -> -1 * surface mass balance
 smb= 2.*ones(md.mesh.numberofvertices,1);
-%md.surfaceforcings.mass_balance= smb;
-%md.basalforcings.melting_rate= smb;
-md.verbose=verbose('all');
+md.surfaceforcings.mass_balance= smb;
+md.basalforcings.melting_rate= smb;
 
 md=solve(md,MasstransportSolutionEnum());
 
-error
 for i=1:10
 	 md=solve(md,MasstransportSolutionEnum());
@@ -55,5 +53,5 @@
 	(md.results.TransientSolution(400).Vel),...
 	(md.results.TransientSolution(400).Pressure),...
-	(md.results.TransientSolution(400).Bed),...
+	(md.results.TransientSolution(400).Base),...
 	(md.results.TransientSolution(400).Surface),...
 	(md.results.TransientSolution(400).Thickness),...
@@ -64,5 +62,5 @@
 	(md.results.TransientSolution(800).Vel),...
 	(md.results.TransientSolution(800).Pressure),...
-	(md.results.TransientSolution(800).Bed),...
+	(md.results.TransientSolution(800).Base),...
 	(md.results.TransientSolution(800).Surface),...
 	(md.results.TransientSolution(800).Thickness),...
@@ -73,5 +71,5 @@
 	(md.results.TransientSolution(1200).Vel),...
 	(md.results.TransientSolution(1200).Pressure),...
-	(md.results.TransientSolution(1200).Bed),...
+	(md.results.TransientSolution(1200).Base),...
 	(md.results.TransientSolution(1200).Surface),...
 	(md.results.TransientSolution(1200).Thickness),...
@@ -82,5 +80,5 @@
 	(md.results.TransientSolution(1600).Vel),...
 	(md.results.TransientSolution(1600).Pressure),...
-	(md.results.TransientSolution(1600).Bed),...
+	(md.results.TransientSolution(1600).Base),...
 	(md.results.TransientSolution(1600).Surface),...
 	(md.results.TransientSolution(1600).Thickness),...
@@ -91,5 +89,5 @@
 	(md.results.TransientSolution(2000).Vel),...
 	(md.results.TransientSolution(2000).Pressure),...
-	(md.results.TransientSolution(2000).Bed),...
+	(md.results.TransientSolution(2000).Base),...
 	(md.results.TransientSolution(2000).Surface),...
 	(md.results.TransientSolution(2000).Thickness),...
Index: /issm/trunk/test/NightlyRun/test1502.py
===================================================================
--- /issm/trunk/test/NightlyRun/test1502.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test1502.py	(revision 17806)
@@ -66,5 +66,5 @@
 	md.results.TransientSolution[400-1].Vel,\
 	md.results.TransientSolution[400-1].Pressure,\
-	md.results.TransientSolution[400-1].Bed,\
+	md.results.TransientSolution[400-1].Base,\
 	md.results.TransientSolution[400-1].Surface,\
 	md.results.TransientSolution[400-1].Thickness,\
@@ -75,5 +75,5 @@
 	md.results.TransientSolution[800-1].Vel,\
 	md.results.TransientSolution[800-1].Pressure,\
-	md.results.TransientSolution[800-1].Bed,\
+	md.results.TransientSolution[800-1].Base,\
 	md.results.TransientSolution[800-1].Surface,\
 	md.results.TransientSolution[800-1].Thickness,\
@@ -84,5 +84,5 @@
 	md.results.TransientSolution[1200-1].Vel,\
 	md.results.TransientSolution[1200-1].Pressure,\
-	md.results.TransientSolution[1200-1].Bed,\
+	md.results.TransientSolution[1200-1].Base,\
 	md.results.TransientSolution[1200-1].Surface,\
 	md.results.TransientSolution[1200-1].Thickness,\
@@ -93,5 +93,5 @@
 	md.results.TransientSolution[1600-1].Vel,\
 	md.results.TransientSolution[1600-1].Pressure,\
-	md.results.TransientSolution[1600-1].Bed,\
+	md.results.TransientSolution[1600-1].Base,\
 	md.results.TransientSolution[1600-1].Surface,\
 	md.results.TransientSolution[1600-1].Thickness,\
@@ -102,5 +102,5 @@
 	md.results.TransientSolution[2000-1].Vel,\
 	md.results.TransientSolution[2000-1].Pressure,\
-	md.results.TransientSolution[2000-1].Bed,\
+	md.results.TransientSolution[2000-1].Base,\
 	md.results.TransientSolution[2000-1].Surface,\
 	md.results.TransientSolution[2000-1].Thickness,\
Index: /issm/trunk/test/NightlyRun/test202.py
===================================================================
--- /issm/trunk/test/NightlyRun/test202.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test202.py	(revision 17806)
@@ -8,4 +8,5 @@
 from setflowequation import *
 from solve import *
+from generic import generic
 
 md=triangle(model(),'../Exp/Square.exp',180000)
Index: /issm/trunk/test/NightlyRun/test203.m
===================================================================
--- /issm/trunk/test/NightlyRun/test203.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test203.m	(revision 17806)
@@ -9,5 +9,5 @@
 %Fields and tolerances to track changes
 field_names     ={'Vx','Vy','Vz','Vel','Pressure'};
-field_tolerances={1e-09,1e-09,1e-09,1e-09,1e-09};
+field_tolerances={2e-09,1e-09,1e-09,1e-09,1e-09};
 field_values={...
 	(md.results.StressbalanceSolution.Vx),...
Index: /issm/trunk/test/NightlyRun/test203.py
===================================================================
--- /issm/trunk/test/NightlyRun/test203.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test203.py	(revision 17806)
@@ -8,4 +8,5 @@
 from setflowequation import *
 from solve import *
+from generic import generic
 
 md=triangle(model(),'../Exp/Square.exp',180000)
@@ -21,5 +22,5 @@
 
 field_names     =['Vx','Vy','Vz','Vel','Pressure']
-field_tolerances=[1e-09,1e-09,1e-09,1e-09,1e-09]
+field_tolerances=[2e-09,1e-09,1e-09,1e-09,1e-09]
 field_values=[\
 	md.results.StressbalanceSolution.Vx,\
Index: /issm/trunk/test/NightlyRun/test204.m
===================================================================
--- /issm/trunk/test/NightlyRun/test204.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test204.m	(revision 17806)
@@ -4,10 +4,14 @@
 md=extrude(md,3,2.);
 md=setflowequation(md,'FS','all');
-md.cluster=generic('name',oshostname(),'np',3);
+md.cluster=generic('name',oshostname(),'np',1);
+md.stressbalance.shelf_dampening=1;
+md.timestepping.time_step=0;
+md1=solve(md,StressbalanceSolutionEnum());
+md.stressbalance.shelf_dampening=0;
 md=solve(md,StressbalanceSolutionEnum());
 
 %Fields and tolerances to track changes
-field_names     ={'Vx','Vy','Vz','Vel','Pressure'};
-field_tolerances={1e-08,1e-08,1e-07,1e-08,1e-08};
+field_names     ={'Vx','Vy','Vz','Vel','Pressure','Vx_damp','Vy_damp','Vz_damp','Vel_damp','Pressure_damp'};
+field_tolerances={1e-08,1e-08,2e-06,1e-08,1e-08,1e-08,1e-08,2e-07,1e-08,1e-08};
 field_values={...
 	(md.results.StressbalanceSolution.Vx),...
@@ -16,3 +20,8 @@
 	(md.results.StressbalanceSolution.Vel),...
 	(md.results.StressbalanceSolution.Pressure),...
+	(md1.results.StressbalanceSolution.Vx),...
+	(md1.results.StressbalanceSolution.Vy),...
+	(md1.results.StressbalanceSolution.Vz),...
+	(md1.results.StressbalanceSolution.Vel),...
+	(md1.results.StressbalanceSolution.Pressure),...
 	};
Index: /issm/trunk/test/NightlyRun/test204.py
===================================================================
--- /issm/trunk/test/NightlyRun/test204.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test204.py	(revision 17806)
@@ -8,4 +8,5 @@
 from setflowequation import *
 from solve import *
+from generic import generic
 
 md=triangle(model(),'../Exp/Square.exp',180000)
@@ -15,4 +16,8 @@
 md=setflowequation(md,'FS','all')
 md.cluster=generic('name',oshostname(),'np',3)
+md.stressbalance.shelf_dampening=1;
+md.timestepping.time_step=0;
+md1=solve(md,StressbalanceSolutionEnum())
+md.stressbalance.shelf_dampening=0;
 md=solve(md,StressbalanceSolutionEnum())
 
@@ -21,5 +26,5 @@
 
 field_names     =['Vx','Vy','Vz','Vel','Pressure']
-field_tolerances=[1e-08,1e-08,1e-07,1e-08,1e-08]
+field_tolerances=[1e-08,1e-08,2e-06,1e-08,1e-08]
 field_values=[\
 	md.results.StressbalanceSolution.Vx,\
Index: /issm/trunk/test/NightlyRun/test205.py
===================================================================
--- /issm/trunk/test/NightlyRun/test205.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test205.py	(revision 17806)
@@ -8,4 +8,5 @@
 from setflowequation import *
 from solve import *
+from generic import generic
 
 md=triangle(model(),'../Exp/Square.exp',150000)
Index: /issm/trunk/test/NightlyRun/test206.m
===================================================================
--- /issm/trunk/test/NightlyRun/test206.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test206.m	(revision 17806)
@@ -10,5 +10,5 @@
 %Fields and tolerances to track changes
 field_names     ={'Temperature','BasalforcingsMeltingRate'};
-field_tolerances={1e-13,1.35e-6};
+field_tolerances={1e-13,5e-6};
 field_values={...
 	(md.results.ThermalSolution.Temperature),...
Index: /issm/trunk/test/NightlyRun/test206.py
===================================================================
--- /issm/trunk/test/NightlyRun/test206.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test206.py	(revision 17806)
@@ -8,4 +8,5 @@
 from setflowequation import *
 from solve import *
+from generic import generic
 
 md=triangle(model(),'../Exp/Square.exp',180000)
@@ -22,5 +23,5 @@
 
 field_names     =['Temperature','BasalforcingsMeltingRate']
-field_tolerances=[1e-13,1.35e-6]
+field_tolerances=[1e-13,5e-6]
 field_values=[\
 	md.results.ThermalSolution.Temperature,\
Index: /issm/trunk/test/NightlyRun/test207.py
===================================================================
--- /issm/trunk/test/NightlyRun/test207.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test207.py	(revision 17806)
@@ -8,4 +8,5 @@
 from setflowequation import *
 from solve import *
+from generic import generic
 
 md=triangle(model(),'../Exp/Square.exp',180000)
Index: /issm/trunk/test/NightlyRun/test208.m
===================================================================
--- /issm/trunk/test/NightlyRun/test208.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test208.m	(revision 17806)
@@ -14,5 +14,5 @@
 	(md.results.TransientSolution(1).Vel),...
 	(md.results.TransientSolution(1).Pressure),...
-	(md.results.TransientSolution(1).Bed),...
+	(md.results.TransientSolution(1).Base),...
 	(md.results.TransientSolution(1).Surface),...
 	(md.results.TransientSolution(1).Thickness),...
@@ -21,5 +21,5 @@
 	(md.results.TransientSolution(2).Vel),...
 	(md.results.TransientSolution(2).Pressure),...
-	(md.results.TransientSolution(2).Bed),...
+	(md.results.TransientSolution(2).Base),...
 	(md.results.TransientSolution(2).Surface),...
 	(md.results.TransientSolution(2).Thickness),...
@@ -28,5 +28,5 @@
 	(md.results.TransientSolution(3).Vel),...
 	(md.results.TransientSolution(3).Pressure),...
-	(md.results.TransientSolution(3).Bed),...
+	(md.results.TransientSolution(3).Base),...
 	(md.results.TransientSolution(3).Surface),...
 	(md.results.TransientSolution(3).Thickness),...
Index: /issm/trunk/test/NightlyRun/test208.py
===================================================================
--- /issm/trunk/test/NightlyRun/test208.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test208.py	(revision 17806)
@@ -8,4 +8,5 @@
 from setflowequation import *
 from solve import *
+from generic import generic
 
 md=triangle(model(),'../Exp/Square.exp',150000)
@@ -26,5 +27,5 @@
 	md.results.TransientSolution[0].Vel,\
 	md.results.TransientSolution[0].Pressure,\
-	md.results.TransientSolution[0].Bed,\
+	md.results.TransientSolution[0].Base,\
 	md.results.TransientSolution[0].Surface,\
 	md.results.TransientSolution[0].Thickness,\
@@ -33,5 +34,5 @@
 	md.results.TransientSolution[1].Vel,\
 	md.results.TransientSolution[1].Pressure,\
-	md.results.TransientSolution[1].Bed,\
+	md.results.TransientSolution[1].Base,\
 	md.results.TransientSolution[1].Surface,\
 	md.results.TransientSolution[1].Thickness,\
@@ -40,5 +41,5 @@
 	md.results.TransientSolution[2].Vel,\
 	md.results.TransientSolution[2].Pressure,\
-	md.results.TransientSolution[2].Bed,\
+	md.results.TransientSolution[2].Base,\
 	md.results.TransientSolution[2].Surface,\
 	md.results.TransientSolution[2].Thickness,\
Index: /issm/trunk/test/NightlyRun/test209.m
===================================================================
--- /issm/trunk/test/NightlyRun/test209.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test209.m	(revision 17806)
@@ -13,6 +13,6 @@
 field_tolerances={...
 	1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-8,...
-	1e-13,1e-13,2e-9,1e-13,3.8e-11,3.85e-11,3.85e-11,3.85e-11,1e-13,1.55e-8,...
-	2.65e-11,2.55e-12,1e-08,2.4e-12,3.9e-11,1e-10,1e-10,1e-10,7.4e-12,1.85e-8};
+	1e-13,1e-13,3e-9,1e-13,3.8e-11,3.85e-11,3.85e-11,3.85e-11,1e-13,2e-8,...
+	5e-11,6e-12,1e-08,6e-12,3.9e-11,1e-10,1e-10,1e-10,9e-12,5e-8};
 field_values={...
 	(md.results.TransientSolution(1).Vx),...
@@ -21,5 +21,5 @@
 	(md.results.TransientSolution(1).Vel),...
 	(md.results.TransientSolution(1).Pressure),...
-	(md.results.TransientSolution(1).Bed),...
+	(md.results.TransientSolution(1).Base),...
 	(md.results.TransientSolution(1).Surface),...
 	(md.results.TransientSolution(1).Thickness),...
@@ -31,5 +31,5 @@
 	(md.results.TransientSolution(2).Vel),...
 	(md.results.TransientSolution(2).Pressure),...
-	(md.results.TransientSolution(2).Bed),...
+	(md.results.TransientSolution(2).Base),...
 	(md.results.TransientSolution(2).Surface),...
 	(md.results.TransientSolution(2).Thickness),...
@@ -41,5 +41,5 @@
 	(md.results.TransientSolution(3).Vel),...
 	(md.results.TransientSolution(3).Pressure),...
-	(md.results.TransientSolution(3).Bed),...
+	(md.results.TransientSolution(3).Base),...
 	(md.results.TransientSolution(3).Surface),...
 	(md.results.TransientSolution(3).Thickness),...
Index: /issm/trunk/test/NightlyRun/test209.py
===================================================================
--- /issm/trunk/test/NightlyRun/test209.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test209.py	(revision 17806)
@@ -8,4 +8,5 @@
 from setflowequation import *
 from solve import *
+from generic import generic
 
 md=triangle(model(),'../Exp/Square.exp',180000)
@@ -25,6 +26,6 @@
 field_tolerances=[\
 	1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-8,\
-	1e-13,1e-13,2e-9,1e-13,3.8e-11,3.85e-11,3.85e-11,3.85e-11,1e-13,1.55e-8,\
-	2.65e-11,2.55e-12,1e-08,2.4e-12,3.9e-11,1e-10,1e-10,1e-10,7.4e-12,1.85e-8]
+	1e-13,1e-13,3e-9,1e-13,3.8e-11,3.85e-11,3.85e-11,3.85e-11,1e-13,2e-8,\
+	5e-11,6e-12,1e-08,6e-12,3.9e-11,1e-10,1e-10,1e-10,9e-12,5e-8]
 
 field_values=[\
@@ -34,5 +35,5 @@
 	md.results.TransientSolution[0].Vel,\
 	md.results.TransientSolution[0].Pressure,\
-	md.results.TransientSolution[0].Bed,\
+	md.results.TransientSolution[0].Base,\
 	md.results.TransientSolution[0].Surface,\
 	md.results.TransientSolution[0].Thickness,\
@@ -44,5 +45,5 @@
 	md.results.TransientSolution[1].Vel,\
 	md.results.TransientSolution[1].Pressure,\
-	md.results.TransientSolution[1].Bed,\
+	md.results.TransientSolution[1].Base,\
 	md.results.TransientSolution[1].Surface,\
 	md.results.TransientSolution[1].Thickness,\
@@ -54,5 +55,5 @@
 	md.results.TransientSolution[2].Vel,\
 	md.results.TransientSolution[2].Pressure,\
-	md.results.TransientSolution[2].Bed,\
+	md.results.TransientSolution[2].Base,\
 	md.results.TransientSolution[2].Surface,\
 	md.results.TransientSolution[2].Thickness,\
Index: /issm/trunk/test/NightlyRun/test210.m
===================================================================
--- /issm/trunk/test/NightlyRun/test210.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test210.m	(revision 17806)
@@ -21,5 +21,5 @@
 	(md.results.TransientSolution(1).Vel),...
 	(md.results.TransientSolution(1).Pressure),...
-	(md.results.TransientSolution(1).Bed),...
+	(md.results.TransientSolution(1).Base),...
 	(md.results.TransientSolution(1).Surface),...
 	(md.results.TransientSolution(1).Thickness),...
@@ -31,5 +31,5 @@
 	(md.results.TransientSolution(2).Vel),...
 	(md.results.TransientSolution(2).Pressure),...
-	(md.results.TransientSolution(2).Bed),...
+	(md.results.TransientSolution(2).Base),...
 	(md.results.TransientSolution(2).Surface),...
 	(md.results.TransientSolution(2).Thickness),...
@@ -41,5 +41,5 @@
 	(md.results.TransientSolution(3).Vel),...
 	(md.results.TransientSolution(3).Pressure),...
-	(md.results.TransientSolution(3).Bed),...
+	(md.results.TransientSolution(3).Base),...
 	(md.results.TransientSolution(3).Surface),...
 	(md.results.TransientSolution(3).Thickness),...
Index: /issm/trunk/test/NightlyRun/test210.py
===================================================================
--- /issm/trunk/test/NightlyRun/test210.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test210.py	(revision 17806)
@@ -8,4 +8,5 @@
 from setflowequation import *
 from solve import *
+from generic import generic
 
 md=triangle(model(),'../Exp/Square.exp',200000)
@@ -33,5 +34,5 @@
 	md.results.TransientSolution[0].Vel,\
 	md.results.TransientSolution[0].Pressure,\
-	md.results.TransientSolution[0].Bed,\
+	md.results.TransientSolution[0].Base,\
 	md.results.TransientSolution[0].Surface,\
 	md.results.TransientSolution[0].Thickness,\
@@ -43,5 +44,5 @@
 	md.results.TransientSolution[1].Vel,\
 	md.results.TransientSolution[1].Pressure,\
-	md.results.TransientSolution[1].Bed,\
+	md.results.TransientSolution[1].Base,\
 	md.results.TransientSolution[1].Surface,\
 	md.results.TransientSolution[1].Thickness,\
@@ -53,5 +54,5 @@
 	md.results.TransientSolution[2].Vel,\
 	md.results.TransientSolution[2].Pressure,\
-	md.results.TransientSolution[2].Bed,\
+	md.results.TransientSolution[2].Base,\
 	md.results.TransientSolution[2].Surface,\
 	md.results.TransientSolution[2].Thickness,\
Index: /issm/trunk/test/NightlyRun/test211.m
===================================================================
--- /issm/trunk/test/NightlyRun/test211.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test211.m	(revision 17806)
@@ -14,7 +14,7 @@
 	'Vx3','Vy3','Vz3','Vel3','Pressure3','Bed3','Surface3','Thickness3','Temperature3','BasalforcingsMeltingRate3'};
 field_tolerances={...
-	1e-08,1e-08,1e-06,1e-08,1e-08,1e-08,1e-08,1e-08,1e-08,1e-08,...
-	2e-08,1e-08,1e-06,1e-08,1e-08,1e-08,1e-08,1e-08,1e-08,1e-06,...
-	1e-07,1e-07,1e-06,2e-08,1e-08,1e-08,1e-08,1e-08,1e-08,1e-06};
+	2e-08,2e-08,1e-06,2e-08,1e-08,1e-08,1e-08,1e-08,1e-08,1e-08,...
+	5e-08,3e-08,1e-06,3e-08,1e-08,1e-08,1e-08,1e-08,2e-08,2e-06,...
+	1e-07,1e-07,1e-05,5e-08,1e-08,1e-08,1e-08,1e-08,2e-08,2e-06};
 field_values={...
 	(md.results.TransientSolution(1).Vx),...
@@ -23,5 +23,5 @@
 	(md.results.TransientSolution(1).Vel),...
 	(md.results.TransientSolution(1).Pressure),...
-	(md.results.TransientSolution(1).Bed),...
+	(md.results.TransientSolution(1).Base),...
 	(md.results.TransientSolution(1).Surface),...
 	(md.results.TransientSolution(1).Thickness),...
@@ -33,5 +33,5 @@
 	(md.results.TransientSolution(2).Vel),...
 	(md.results.TransientSolution(2).Pressure),...
-	(md.results.TransientSolution(2).Bed),...
+	(md.results.TransientSolution(2).Base),...
 	(md.results.TransientSolution(2).Surface),...
 	(md.results.TransientSolution(2).Thickness),...
@@ -43,5 +43,5 @@
 	(md.results.TransientSolution(3).Vel),...
 	(md.results.TransientSolution(3).Pressure),...
-	(md.results.TransientSolution(3).Bed),...
+	(md.results.TransientSolution(3).Base),...
 	(md.results.TransientSolution(3).Surface),...
 	(md.results.TransientSolution(3).Thickness),...
Index: /issm/trunk/test/NightlyRun/test211.py
===================================================================
--- /issm/trunk/test/NightlyRun/test211.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test211.py	(revision 17806)
@@ -8,4 +8,5 @@
 from setflowequation import *
 from solve import *
+from generic import generic
 
 md=triangle(model(),'../Exp/Square.exp',200000)
@@ -26,7 +27,7 @@
 	'Vx3','Vy3','Vz3','Vel3','Pressure3','Bed3','Surface3','Thickness3','Temperature3','BasalforcingsMeltingRate3']
 field_tolerances=[\
-	1e-08,1e-08,1e-06,1e-08,1e-08,1e-08,1e-08,1e-08,1e-08,1e-08,\
-	1e-08,1e-08,1e-06,1e-08,1e-08,1e-08,1e-08,1e-08,1e-08,1e-06,\
-	1e-07,1e-07,1e-06,2e-08,1e-08,1e-08,1e-08,1e-08,1e-08,1e-06]
+	2e-08,2e-08,1e-06,2e-08,1e-08,1e-08,1e-08,1e-08,1e-08,1e-08,\
+	5e-08,3e-08,1e-06,3e-08,1e-08,1e-08,1e-08,1e-08,2e-08,2e-06,\
+	1e-07,1e-07,1e-05,5e-08,1e-08,1e-08,1e-08,1e-08,2e-08,2e-06]
 field_values=[\
 	md.results.TransientSolution[0].Vx,\
@@ -35,5 +36,5 @@
 	md.results.TransientSolution[0].Vel,\
 	md.results.TransientSolution[0].Pressure,\
-	md.results.TransientSolution[0].Bed,\
+	md.results.TransientSolution[0].Base,\
 	md.results.TransientSolution[0].Surface,\
 	md.results.TransientSolution[0].Thickness,\
@@ -45,5 +46,5 @@
 	md.results.TransientSolution[1].Vel,\
 	md.results.TransientSolution[1].Pressure,\
-	md.results.TransientSolution[1].Bed,\
+	md.results.TransientSolution[1].Base,\
 	md.results.TransientSolution[1].Surface,\
 	md.results.TransientSolution[1].Thickness,\
@@ -55,5 +56,5 @@
 	md.results.TransientSolution[2].Vel,\
 	md.results.TransientSolution[2].Pressure,\
-	md.results.TransientSolution[2].Bed,\
+	md.results.TransientSolution[2].Base,\
 	md.results.TransientSolution[2].Surface,\
 	md.results.TransientSolution[2].Thickness,\
Index: /issm/trunk/test/NightlyRun/test212.m
===================================================================
--- /issm/trunk/test/NightlyRun/test212.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test212.m	(revision 17806)
@@ -16,4 +16,5 @@
 md.inversion.step_threshold=0.3*ones(md.inversion.nsteps,1);
 md.inversion.vx_obs=md.initialization.vx; md.inversion.vy_obs=md.initialization.vy;
+md.verbose.control=true;
 
 md.cluster=generic('name',oshostname(),'np',3);
Index: /issm/trunk/test/NightlyRun/test212.py
===================================================================
--- /issm/trunk/test/NightlyRun/test212.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test212.py	(revision 17806)
@@ -8,4 +8,5 @@
 from setflowequation import *
 from solve import *
+from generic import generic
 
 md=triangle(model(),'../Exp/Square.exp',200000)
Index: /issm/trunk/test/NightlyRun/test213.py
===================================================================
--- /issm/trunk/test/NightlyRun/test213.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test213.py	(revision 17806)
@@ -8,4 +8,5 @@
 from setflowequation import *
 from solve import *
+from generic import generic
 
 md=triangle(model(),'../Exp/Square.exp',200000)
Index: /issm/trunk/test/NightlyRun/test214.py
===================================================================
--- /issm/trunk/test/NightlyRun/test214.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test214.py	(revision 17806)
@@ -8,4 +8,5 @@
 from setflowequation import *
 from solve import *
+from generic import generic
 
 md=triangle(model(),'../Exp/Square.exp',200000)
Index: /issm/trunk/test/NightlyRun/test215.m
===================================================================
--- /issm/trunk/test/NightlyRun/test215.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test215.m	(revision 17806)
@@ -23,5 +23,5 @@
 %Fields and tolerances to track changes
 field_names     ={'Gradient','Misfits','MaterialsRheologyBbar','Pressure','Vel','Vx','Vy'};
-field_tolerances={1e-08,1e-09,1e-09,1e-09,1e-09,1e-09,1e-09,1e-09,3e-09,1e-09};
+field_tolerances={1e-08,1e-09,2e-09,1e-09,2e-09,5e-09,2e-09};
 field_values={...
 	(md.results.StressbalanceSolution.Gradient1),...
Index: /issm/trunk/test/NightlyRun/test215.py
===================================================================
--- /issm/trunk/test/NightlyRun/test215.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test215.py	(revision 17806)
@@ -8,4 +8,5 @@
 from setflowequation import *
 from solve import *
+from generic import generic
 
 md=triangle(model(),'../Exp/Square.exp',200000)
@@ -39,5 +40,5 @@
 
 field_names     =['Gradient','Misfits','MaterialsRheologyBbar','Pressure','Vel','Vx','Vy']
-field_tolerances=[1e-08,1e-09,1e-09,1e-09,1e-09,1e-09,1e-09,1e-09,3e-09,1e-09]
+field_tolerances=[1e-08,1e-09,2e-09,1e-09,2e-09,5e-09,2e-09]
 field_values=[\
 	md.results.StressbalanceSolution.Gradient1,\
Index: /issm/trunk/test/NightlyRun/test216.m
===================================================================
--- /issm/trunk/test/NightlyRun/test216.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test216.m	(revision 17806)
@@ -16,5 +16,5 @@
 %Fields and tolerances to track changes
 field_names     ={'Vx','Vy','Vel','Pressure'};
-field_tolerances={4e-11,2e-11,4e-11,2e-11};
+field_tolerances={8e-7,5e-8,7e-8,2e-11};
 field_values={...
 	(md.results.StressbalanceSolution.Vx),...
Index: /issm/trunk/test/NightlyRun/test216.py
===================================================================
--- /issm/trunk/test/NightlyRun/test216.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test216.py	(revision 17806)
@@ -9,4 +9,5 @@
 from setflowequation import *
 from solve import *
+from generic import generic
 
 md=triangle(model(),'../Exp/SquareHole.exp','../Exp/Rifts.exp',50000.)
Index: /issm/trunk/test/NightlyRun/test217.m
===================================================================
--- /issm/trunk/test/NightlyRun/test217.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test217.m	(revision 17806)
@@ -22,6 +22,6 @@
 h=1000;
 md.geometry.thickness=h*ones(md.mesh.numberofvertices,1);
-md.geometry.bed=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness;
-md.geometry.surface=md.geometry.bed+md.geometry.thickness;
+md.geometry.base=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness;
+md.geometry.surface=md.geometry.base+md.geometry.thickness;
 
 %Initial velocity and pressure
@@ -54,5 +54,5 @@
 nodeonicefront=zeros(md.mesh.numberofvertices,1);
 pos=find(md.mesh.y==ymax); nodeonicefront(pos)=1;
-md.mask.ice_levelset=1-nodeonicefront;
+md.mask.ice_levelset=-1+nodeonicefront;
 
 md=solve(md,StressbalanceSolutionEnum());
Index: /issm/trunk/test/NightlyRun/test217.py
===================================================================
--- /issm/trunk/test/NightlyRun/test217.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test217.py	(revision 17806)
@@ -9,4 +9,5 @@
 from paterson import *
 from solve import *
+from generic import generic
 
 md=triangle(model(),'../Exp/Square.exp',150000)
@@ -33,6 +34,6 @@
 h=1000.
 md.geometry.thickness=h*ones((md.mesh.numberofvertices,1))
-md.geometry.bed=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness
-md.geometry.surface=md.geometry.bed+md.geometry.thickness
+md.geometry.base=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness
+md.geometry.surface=md.geometry.base+md.geometry.thickness
 
 # Initial velocity and pressure
@@ -66,5 +67,5 @@
 pos=numpy.nonzero(md.mesh.y==ymax)
 nodeonicefront[pos]=1
-md.mask.ice_levelset=1-nodeonicefront
+md.mask.ice_levelset=-1+nodeonicefront
 
 md=solve(md,StressbalanceSolutionEnum())
Index: /issm/trunk/test/NightlyRun/test218.m
===================================================================
--- /issm/trunk/test/NightlyRun/test218.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test218.m	(revision 17806)
@@ -19,6 +19,6 @@
 h=1000;
 md.geometry.thickness=h*ones(md.mesh.numberofvertices,1);
-md.geometry.bed=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness;
-md.geometry.surface=md.geometry.bed+md.geometry.thickness;
+md.geometry.base=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness;
+md.geometry.surface=md.geometry.base+md.geometry.thickness;
 
 %Initial velocity and pressure
Index: /issm/trunk/test/NightlyRun/test219.py
===================================================================
--- /issm/trunk/test/NightlyRun/test219.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test219.py	(revision 17806)
@@ -8,4 +8,5 @@
 from setflowequation import *
 from solve import *
+from generic import generic
 
 md=triangle(model(),'../Exp/Square.exp',150000.)
Index: /issm/trunk/test/NightlyRun/test220.py
===================================================================
--- /issm/trunk/test/NightlyRun/test220.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test220.py	(revision 17806)
@@ -8,4 +8,5 @@
 from setflowequation import *
 from solve import *
+from generic import generic
 
 md=triangle(model(),'../Exp/Square.exp',120000.)
Index: /issm/trunk/test/NightlyRun/test221.m
===================================================================
--- /issm/trunk/test/NightlyRun/test221.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test221.m	(revision 17806)
@@ -10,5 +10,5 @@
 %Fields and tolerances to track changes
 field_names     ={'Vx','Vy','Vz','Vel','Pressure'};
-field_tolerances={1e-09,1e-09,1e-06,1e-09,1e-09};
+field_tolerances={1e-09,1e-09,5e-06,1e-09,1e-09};
 field_values={...
 	(md.results.StressbalanceSolution.Vx),...
Index: /issm/trunk/test/NightlyRun/test221.py
===================================================================
--- /issm/trunk/test/NightlyRun/test221.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test221.py	(revision 17806)
@@ -19,5 +19,5 @@
 #Fields and tolerances to track changes
 field_names     =['Vx','Vy','Vz','Vel','Pressure']
-field_tolerances=[1e-09,1e-09,1e-06,1e-09,1e-09]
+field_tolerances=[1e-09,1e-09,5e-06,1e-09,1e-09]
 field_values=[\
 	md.results.StressbalanceSolution.Vx,\
Index: /issm/trunk/test/NightlyRun/test222.m
===================================================================
--- /issm/trunk/test/NightlyRun/test222.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test222.m	(revision 17806)
@@ -15,5 +15,5 @@
 	(md.results.TransientSolution(1).Vel),...
 	(md.results.TransientSolution(1).Pressure),...
-	(md.results.TransientSolution(1).Bed),...
+	(md.results.TransientSolution(1).Base),...
 	(md.results.TransientSolution(1).Surface),...
 	(md.results.TransientSolution(1).Thickness),...
@@ -22,5 +22,5 @@
 	(md.results.TransientSolution(2).Vel),...
 	(md.results.TransientSolution(2).Pressure),...
-	(md.results.TransientSolution(2).Bed),...
+	(md.results.TransientSolution(2).Base),...
 	(md.results.TransientSolution(2).Surface),...
 	(md.results.TransientSolution(2).Thickness),...
@@ -29,5 +29,5 @@
 	(md.results.TransientSolution(3).Vel),...
 	(md.results.TransientSolution(3).Pressure),...
-	(md.results.TransientSolution(3).Bed),...
+	(md.results.TransientSolution(3).Base),...
 	(md.results.TransientSolution(3).Surface),...
 	(md.results.TransientSolution(3).Thickness),...
Index: /issm/trunk/test/NightlyRun/test222.py
===================================================================
--- /issm/trunk/test/NightlyRun/test222.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test222.py	(revision 17806)
@@ -24,5 +24,5 @@
 	md.results.TransientSolution[0].Vel,\
 	md.results.TransientSolution[0].Pressure,\
-	md.results.TransientSolution[0].Bed,\
+	md.results.TransientSolution[0].Base,\
 	md.results.TransientSolution[0].Surface,\
 	md.results.TransientSolution[0].Thickness,\
@@ -31,5 +31,5 @@
 	md.results.TransientSolution[1].Vel,\
 	md.results.TransientSolution[1].Pressure,\
-	md.results.TransientSolution[1].Bed,\
+	md.results.TransientSolution[1].Base,\
 	md.results.TransientSolution[1].Surface,\
 	md.results.TransientSolution[1].Thickness,\
@@ -38,5 +38,5 @@
 	md.results.TransientSolution[2].Vel,\
 	md.results.TransientSolution[2].Pressure,\
-	md.results.TransientSolution[2].Bed,\
+	md.results.TransientSolution[2].Base,\
 	md.results.TransientSolution[2].Surface,\
 	md.results.TransientSolution[2].Thickness,\
Index: /issm/trunk/test/NightlyRun/test223.m
===================================================================
--- /issm/trunk/test/NightlyRun/test223.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test223.m	(revision 17806)
@@ -3,5 +3,5 @@
 md=parameterize(md,'../Par/SquareShelf.par');
 md=setflowequation(md,'SSA','all');
-md.geometry.bed=md.geometry.bed+50.; md.geometry.surface=md.geometry.surface+50.;
+md.geometry.base=md.geometry.base+50.; md.geometry.surface=md.geometry.surface+50.;
 md.cluster=generic('name',oshostname(),'np',1);
 md.masstransport.hydrostatic_adjustment='Incremental';
@@ -16,5 +16,5 @@
 	(md.results.TransientSolution(1).Vel),...
 	(md.results.TransientSolution(1).Pressure),...
-	(md.results.TransientSolution(1).Bed),...
+	(md.results.TransientSolution(1).Base),...
 	(md.results.TransientSolution(1).Surface),...
 	(md.results.TransientSolution(1).Thickness),...
@@ -23,5 +23,5 @@
 	(md.results.TransientSolution(2).Vel),...
 	(md.results.TransientSolution(2).Pressure),...
-	(md.results.TransientSolution(2).Bed),...
+	(md.results.TransientSolution(2).Base),...
 	(md.results.TransientSolution(2).Surface),...
 	(md.results.TransientSolution(2).Thickness),...
@@ -30,5 +30,5 @@
 	(md.results.TransientSolution(3).Vel),...
 	(md.results.TransientSolution(3).Pressure),...
-	(md.results.TransientSolution(3).Bed),...
+	(md.results.TransientSolution(3).Base),...
 	(md.results.TransientSolution(3).Surface),...
 	(md.results.TransientSolution(3).Thickness),...
Index: /issm/trunk/test/NightlyRun/test223.py
===================================================================
--- /issm/trunk/test/NightlyRun/test223.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test223.py	(revision 17806)
@@ -12,5 +12,5 @@
 md=parameterize(md,'../Par/SquareShelf.py')
 md=setflowequation(md,'SSA','all')
-md.geometry.bed=md.geometry.bed+50.
+md.geometry.base=md.geometry.base+50.
 md.geometry.surface=md.geometry.surface+50.
 md.cluster=generic('name',oshostname(),'np',1)
@@ -26,5 +26,5 @@
 	md.results.TransientSolution[0].Vel,\
 	md.results.TransientSolution[0].Pressure,\
-	md.results.TransientSolution[0].Bed,\
+	md.results.TransientSolution[0].Base,\
 	md.results.TransientSolution[0].Surface,\
 	md.results.TransientSolution[0].Thickness,\
@@ -33,5 +33,5 @@
 	md.results.TransientSolution[1].Vel,\
 	md.results.TransientSolution[1].Pressure,\
-	md.results.TransientSolution[1].Bed,\
+	md.results.TransientSolution[1].Base,\
 	md.results.TransientSolution[1].Surface,\
 	md.results.TransientSolution[1].Thickness,\
@@ -40,5 +40,5 @@
 	md.results.TransientSolution[2].Vel,\
 	md.results.TransientSolution[2].Pressure,\
-	md.results.TransientSolution[2].Bed,\
+	md.results.TransientSolution[2].Base,\
 	md.results.TransientSolution[2].Surface,\
 	md.results.TransientSolution[2].Thickness,\
Index: /issm/trunk/test/NightlyRun/test224.m
===================================================================
--- /issm/trunk/test/NightlyRun/test224.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test224.m	(revision 17806)
@@ -22,5 +22,5 @@
 	(md.results.TransientSolution(1).Vel),...
 	(md.results.TransientSolution(1).Pressure),...
-	(md.results.TransientSolution(1).Bed),...
+	(md.results.TransientSolution(1).Base),...
 	(md.results.TransientSolution(1).Surface),...
 	(md.results.TransientSolution(1).Thickness),...
@@ -32,5 +32,5 @@
 	(md.results.TransientSolution(2).Vel),...
 	(md.results.TransientSolution(2).Pressure),...
-	(md.results.TransientSolution(2).Bed),...
+	(md.results.TransientSolution(2).Base),...
 	(md.results.TransientSolution(2).Surface),...
 	(md.results.TransientSolution(2).Thickness),...
@@ -42,5 +42,5 @@
 	(md.results.TransientSolution(3).Vel),...
 	(md.results.TransientSolution(3).Pressure),...
-	(md.results.TransientSolution(3).Bed),...
+	(md.results.TransientSolution(3).Base),...
 	(md.results.TransientSolution(3).Surface),...
 	(md.results.TransientSolution(3).Thickness),...
Index: /issm/trunk/test/NightlyRun/test224.py
===================================================================
--- /issm/trunk/test/NightlyRun/test224.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test224.py	(revision 17806)
@@ -31,5 +31,5 @@
 	md.results.TransientSolution[0].Vel,\
 	md.results.TransientSolution[0].Pressure,\
-	md.results.TransientSolution[0].Bed,\
+	md.results.TransientSolution[0].Base,\
 	md.results.TransientSolution[0].Surface,\
 	md.results.TransientSolution[0].Thickness,\
@@ -41,5 +41,5 @@
 	md.results.TransientSolution[1].Vel,\
 	md.results.TransientSolution[1].Pressure,\
-	md.results.TransientSolution[1].Bed,\
+	md.results.TransientSolution[1].Base,\
 	md.results.TransientSolution[1].Surface,\
 	md.results.TransientSolution[1].Thickness,\
@@ -51,5 +51,5 @@
 	md.results.TransientSolution[2].Vel,\
 	md.results.TransientSolution[2].Pressure,\
-	md.results.TransientSolution[2].Bed,\
+	md.results.TransientSolution[2].Base,\
 	md.results.TransientSolution[2].Surface,\
 	md.results.TransientSolution[2].Thickness,\
Index: /issm/trunk/test/NightlyRun/test225.m
===================================================================
--- /issm/trunk/test/NightlyRun/test225.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test225.m	(revision 17806)
@@ -2,5 +2,5 @@
 md=setmask(md,'all','');
 md=parameterize(md,'../Par/SquareShelf.par');
-md.geometry.bed=md.geometry.bed+50.; md.geometry.surface=md.geometry.surface+50.;
+md.geometry.base=md.geometry.base+50.; md.geometry.surface=md.geometry.surface+50.;
 md=extrude(md,3,1.);
 md=setflowequation(md,'HO','all');
@@ -23,5 +23,5 @@
 	(md.results.TransientSolution(1).Vel),...
 	(md.results.TransientSolution(1).Pressure),...
-	(md.results.TransientSolution(1).Bed),...
+	(md.results.TransientSolution(1).Base),...
 	(md.results.TransientSolution(1).Surface),...
 	(md.results.TransientSolution(1).Thickness),...
@@ -33,5 +33,5 @@
 	(md.results.TransientSolution(2).Vel),...
 	(md.results.TransientSolution(2).Pressure),...
-	(md.results.TransientSolution(2).Bed),...
+	(md.results.TransientSolution(2).Base),...
 	(md.results.TransientSolution(2).Surface),...
 	(md.results.TransientSolution(2).Thickness),...
@@ -43,5 +43,5 @@
 	(md.results.TransientSolution(3).Vel),...
 	(md.results.TransientSolution(3).Pressure),...
-	(md.results.TransientSolution(3).Bed),...
+	(md.results.TransientSolution(3).Base),...
 	(md.results.TransientSolution(3).Surface),...
 	(md.results.TransientSolution(3).Thickness),...
Index: /issm/trunk/test/NightlyRun/test225.py
===================================================================
--- /issm/trunk/test/NightlyRun/test225.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test225.py	(revision 17806)
@@ -11,5 +11,5 @@
 md=setmask(md,'all','')
 md=parameterize(md,'../Par/SquareShelf.py')
-md.geometry.bed=md.geometry.bed+50.
+md.geometry.base=md.geometry.base+50.
 md.geometry.surface=md.geometry.surface+50.
 md.extrude(3,1.)
@@ -33,5 +33,5 @@
 	md.results.TransientSolution[0].Vel,\
 	md.results.TransientSolution[0].Pressure,\
-	md.results.TransientSolution[0].Bed,\
+	md.results.TransientSolution[0].Base,\
 	md.results.TransientSolution[0].Surface,\
 	md.results.TransientSolution[0].Thickness,\
@@ -43,5 +43,5 @@
 	md.results.TransientSolution[1].Vel,\
 	md.results.TransientSolution[1].Pressure,\
-	md.results.TransientSolution[1].Bed,\
+	md.results.TransientSolution[1].Base,\
 	md.results.TransientSolution[1].Surface,\
 	md.results.TransientSolution[1].Thickness,\
@@ -53,5 +53,5 @@
 	md.results.TransientSolution[2].Vel,\
 	md.results.TransientSolution[2].Pressure,\
-	md.results.TransientSolution[2].Bed,\
+	md.results.TransientSolution[2].Base,\
 	md.results.TransientSolution[2].Surface,\
 	md.results.TransientSolution[2].Thickness,\
Index: /issm/trunk/test/NightlyRun/test226.m
===================================================================
--- /issm/trunk/test/NightlyRun/test226.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test226.m	(revision 17806)
@@ -16,5 +16,5 @@
 	(md.results.TransientSolution(1).Vel),...
 	(md.results.TransientSolution(1).Pressure),...
-	(md.results.TransientSolution(1).Bed),...
+	(md.results.TransientSolution(1).Base),...
 	(md.results.TransientSolution(1).Surface),...
 	(md.results.TransientSolution(1).Thickness),...
@@ -23,5 +23,5 @@
 	(md.results.TransientSolution(2).Vel),...
 	(md.results.TransientSolution(2).Pressure),...
-	(md.results.TransientSolution(2).Bed),...
+	(md.results.TransientSolution(2).Base),...
 	(md.results.TransientSolution(2).Surface),...
 	(md.results.TransientSolution(2).Thickness),...
@@ -30,5 +30,5 @@
 	(md.results.TransientSolution(3).Vel),...
 	(md.results.TransientSolution(3).Pressure),...
-	(md.results.TransientSolution(3).Bed),...
+	(md.results.TransientSolution(3).Base),...
 	(md.results.TransientSolution(3).Surface),...
 	(md.results.TransientSolution(3).Thickness),...
Index: /issm/trunk/test/NightlyRun/test226.py
===================================================================
--- /issm/trunk/test/NightlyRun/test226.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test226.py	(revision 17806)
@@ -25,5 +25,5 @@
 	md.results.TransientSolution[0].Vel,\
 	md.results.TransientSolution[0].Pressure,\
-	md.results.TransientSolution[0].Bed,\
+	md.results.TransientSolution[0].Base,\
 	md.results.TransientSolution[0].Surface,\
 	md.results.TransientSolution[0].Thickness,\
@@ -32,5 +32,5 @@
 	md.results.TransientSolution[1].Vel,\
 	md.results.TransientSolution[1].Pressure,\
-	md.results.TransientSolution[1].Bed,\
+	md.results.TransientSolution[1].Base,\
 	md.results.TransientSolution[1].Surface,\
 	md.results.TransientSolution[1].Thickness,\
@@ -39,5 +39,5 @@
 	md.results.TransientSolution[2].Vel,\
 	md.results.TransientSolution[2].Pressure,\
-	md.results.TransientSolution[2].Bed,\
+	md.results.TransientSolution[2].Base,\
 	md.results.TransientSolution[2].Surface,\
 	md.results.TransientSolution[2].Thickness,\
Index: /issm/trunk/test/NightlyRun/test227.m
===================================================================
--- /issm/trunk/test/NightlyRun/test227.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test227.m	(revision 17806)
@@ -23,5 +23,5 @@
 	(md.results.TransientSolution(1).Vel),...
 	(md.results.TransientSolution(1).Pressure),...
-	(md.results.TransientSolution(1).Bed),...
+	(md.results.TransientSolution(1).Base),...
 	(md.results.TransientSolution(1).Surface),...
 	(md.results.TransientSolution(1).Thickness),...
@@ -33,5 +33,5 @@
 	(md.results.TransientSolution(2).Vel),...
 	(md.results.TransientSolution(2).Pressure),...
-	(md.results.TransientSolution(2).Bed),...
+	(md.results.TransientSolution(2).Base),...
 	(md.results.TransientSolution(2).Surface),...
 	(md.results.TransientSolution(2).Thickness),...
@@ -43,5 +43,5 @@
 	(md.results.TransientSolution(3).Vel),...
 	(md.results.TransientSolution(3).Pressure),...
-	(md.results.TransientSolution(3).Bed),...
+	(md.results.TransientSolution(3).Base),...
 	(md.results.TransientSolution(3).Surface),...
 	(md.results.TransientSolution(3).Thickness),...
Index: /issm/trunk/test/NightlyRun/test227.py
===================================================================
--- /issm/trunk/test/NightlyRun/test227.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test227.py	(revision 17806)
@@ -32,5 +32,5 @@
 	md.results.TransientSolution[0].Vel,\
 	md.results.TransientSolution[0].Pressure,\
-	md.results.TransientSolution[0].Bed,\
+	md.results.TransientSolution[0].Base,\
 	md.results.TransientSolution[0].Surface,\
 	md.results.TransientSolution[0].Thickness,\
@@ -42,5 +42,5 @@
 	md.results.TransientSolution[1].Vel,\
 	md.results.TransientSolution[1].Pressure,\
-	md.results.TransientSolution[1].Bed,\
+	md.results.TransientSolution[1].Base,\
 	md.results.TransientSolution[1].Surface,\
 	md.results.TransientSolution[1].Thickness,\
@@ -52,5 +52,5 @@
 	md.results.TransientSolution[2].Vel,\
 	md.results.TransientSolution[2].Pressure,\
-	md.results.TransientSolution[2].Bed,\
+	md.results.TransientSolution[2].Base,\
 	md.results.TransientSolution[2].Surface,\
 	md.results.TransientSolution[2].Thickness,\
Index: /issm/trunk/test/NightlyRun/test228.m
===================================================================
--- /issm/trunk/test/NightlyRun/test228.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test228.m	(revision 17806)
@@ -33,5 +33,5 @@
 	(md.results.TransientSolution(1).Vel),...
 	(md.results.TransientSolution(1).Pressure),...
-	(md.results.TransientSolution(1).Bed),...
+	(md.results.TransientSolution(1).Base),...
 	(md.results.TransientSolution(1).Surface),...
 	(md.results.TransientSolution(1).Thickness),...
@@ -41,5 +41,5 @@
 	(md.results.TransientSolution(2).Vel),...
 	(md.results.TransientSolution(2).Pressure),...
-	(md.results.TransientSolution(2).Bed),...
+	(md.results.TransientSolution(2).Base),...
 	(md.results.TransientSolution(2).Surface),...
 	(md.results.TransientSolution(2).Thickness),...
@@ -49,5 +49,5 @@
 	(md.results.TransientSolution(3).Vel),...
 	(md.results.TransientSolution(3).Pressure),...
-	(md.results.TransientSolution(3).Bed),...
+	(md.results.TransientSolution(3).Base),...
 	(md.results.TransientSolution(3).Surface),...
 	(md.results.TransientSolution(3).Thickness),...
@@ -57,5 +57,5 @@
 	(md.results.TransientSolution(4).Vel),...
 	(md.results.TransientSolution(4).Pressure),...
-	(md.results.TransientSolution(4).Bed),...
+	(md.results.TransientSolution(4).Base),...
 	(md.results.TransientSolution(4).Surface),...
 	(md.results.TransientSolution(4).Thickness),...
Index: /issm/trunk/test/NightlyRun/test228.py
===================================================================
--- /issm/trunk/test/NightlyRun/test228.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test228.py	(revision 17806)
@@ -42,5 +42,5 @@
 	md.results.TransientSolution[0].Vel,\
 	md.results.TransientSolution[0].Pressure,\
-	md.results.TransientSolution[0].Bed,\
+	md.results.TransientSolution[0].Base,\
 	md.results.TransientSolution[0].Surface,\
 	md.results.TransientSolution[0].Thickness,\
@@ -50,5 +50,5 @@
 	md.results.TransientSolution[1].Vel,\
 	md.results.TransientSolution[1].Pressure,\
-	md.results.TransientSolution[1].Bed,\
+	md.results.TransientSolution[1].Base,\
 	md.results.TransientSolution[1].Surface,\
 	md.results.TransientSolution[1].Thickness,\
@@ -58,5 +58,5 @@
 	md.results.TransientSolution[2].Vel,\
 	md.results.TransientSolution[2].Pressure,\
-	md.results.TransientSolution[2].Bed,\
+	md.results.TransientSolution[2].Base,\
 	md.results.TransientSolution[2].Surface,\
 	md.results.TransientSolution[2].Thickness,\
@@ -66,5 +66,5 @@
 	md.results.TransientSolution[3].Vel,\
 	md.results.TransientSolution[3].Pressure,\
-	md.results.TransientSolution[3].Bed,\
+	md.results.TransientSolution[3].Base,\
 	md.results.TransientSolution[3].Surface,\
 	md.results.TransientSolution[3].Thickness,\
Index: /issm/trunk/test/NightlyRun/test229.m
===================================================================
--- /issm/trunk/test/NightlyRun/test229.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test229.m	(revision 17806)
@@ -33,5 +33,5 @@
 	(md.results.TransientSolution(1).Vel),...
 	(md.results.TransientSolution(1).Pressure),...
-	(md.results.TransientSolution(1).Bed),...
+	(md.results.TransientSolution(1).Base),...
 	(md.results.TransientSolution(1).Surface),...
 	(md.results.TransientSolution(1).Thickness),...
@@ -41,5 +41,5 @@
 	(md.results.TransientSolution(2).Vel),...
 	(md.results.TransientSolution(2).Pressure),...
-	(md.results.TransientSolution(2).Bed),...
+	(md.results.TransientSolution(2).Base),...
 	(md.results.TransientSolution(2).Surface),...
 	(md.results.TransientSolution(2).Thickness),...
@@ -49,5 +49,5 @@
 	(md.results.TransientSolution(3).Vel),...
 	(md.results.TransientSolution(3).Pressure),...
-	(md.results.TransientSolution(3).Bed),...
+	(md.results.TransientSolution(3).Base),...
 	(md.results.TransientSolution(3).Surface),...
 	(md.results.TransientSolution(3).Thickness),...
@@ -57,5 +57,5 @@
 	(md.results.TransientSolution(4).Vel),...
 	(md.results.TransientSolution(4).Pressure),...
-	(md.results.TransientSolution(4).Bed),...
+	(md.results.TransientSolution(4).Base),...
 	(md.results.TransientSolution(4).Surface),...
 	(md.results.TransientSolution(4).Thickness),...
Index: /issm/trunk/test/NightlyRun/test229.py
===================================================================
--- /issm/trunk/test/NightlyRun/test229.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test229.py	(revision 17806)
@@ -42,5 +42,5 @@
 	md.results.TransientSolution[0].Vel,\
 	md.results.TransientSolution[0].Pressure,\
-	md.results.TransientSolution[0].Bed,\
+	md.results.TransientSolution[0].Base,\
 	md.results.TransientSolution[0].Surface,\
 	md.results.TransientSolution[0].Thickness,\
@@ -50,5 +50,5 @@
 	md.results.TransientSolution[1].Vel,\
 	md.results.TransientSolution[1].Pressure,\
-	md.results.TransientSolution[1].Bed,\
+	md.results.TransientSolution[1].Base,\
 	md.results.TransientSolution[1].Surface,\
 	md.results.TransientSolution[1].Thickness,\
@@ -58,5 +58,5 @@
 	md.results.TransientSolution[2].Vel,\
 	md.results.TransientSolution[2].Pressure,\
-	md.results.TransientSolution[2].Bed,\
+	md.results.TransientSolution[2].Base,\
 	md.results.TransientSolution[2].Surface,\
 	md.results.TransientSolution[2].Thickness,\
@@ -66,5 +66,5 @@
 	md.results.TransientSolution[3].Vel,\
 	md.results.TransientSolution[3].Pressure,\
-	md.results.TransientSolution[3].Bed,\
+	md.results.TransientSolution[3].Base,\
 	md.results.TransientSolution[3].Surface,\
 	md.results.TransientSolution[3].Thickness,\
Index: /issm/trunk/test/NightlyRun/test230.m
===================================================================
--- /issm/trunk/test/NightlyRun/test230.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test230.m	(revision 17806)
@@ -35,5 +35,5 @@
 	(md.results.TransientSolution(1).Vel),...
 	(md.results.TransientSolution(1).Pressure),...
-	(md.results.TransientSolution(1).Bed),...
+	(md.results.TransientSolution(1).Base),...
 	(md.results.TransientSolution(1).Surface),...
 	(md.results.TransientSolution(1).Thickness),...
@@ -44,5 +44,5 @@
 	(md.results.TransientSolution(2).Vel),...
 	(md.results.TransientSolution(2).Pressure),...
-	(md.results.TransientSolution(2).Bed),...
+	(md.results.TransientSolution(2).Base),...
 	(md.results.TransientSolution(2).Surface),...
 	(md.results.TransientSolution(2).Thickness),...
@@ -53,5 +53,5 @@
 	(md.results.TransientSolution(3).Vel),...
 	(md.results.TransientSolution(3).Pressure),...
-	(md.results.TransientSolution(3).Bed),...
+	(md.results.TransientSolution(3).Base),...
 	(md.results.TransientSolution(3).Surface),...
 	(md.results.TransientSolution(3).Thickness),...
@@ -62,5 +62,5 @@
 	(md.results.TransientSolution(4).Vel),...
 	(md.results.TransientSolution(4).Pressure),...
-	(md.results.TransientSolution(4).Bed),...
+	(md.results.TransientSolution(4).Base),...
 	(md.results.TransientSolution(4).Surface),...
 	(md.results.TransientSolution(4).Thickness),...
Index: /issm/trunk/test/NightlyRun/test230.py
===================================================================
--- /issm/trunk/test/NightlyRun/test230.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test230.py	(revision 17806)
@@ -44,5 +44,5 @@
 	md.results.TransientSolution[0].Vel,\
 	md.results.TransientSolution[0].Pressure,\
-	md.results.TransientSolution[0].Bed,\
+	md.results.TransientSolution[0].Base,\
 	md.results.TransientSolution[0].Surface,\
 	md.results.TransientSolution[0].Thickness,\
@@ -53,5 +53,5 @@
 	md.results.TransientSolution[1].Vel,\
 	md.results.TransientSolution[1].Pressure,\
-	md.results.TransientSolution[1].Bed,\
+	md.results.TransientSolution[1].Base,\
 	md.results.TransientSolution[1].Surface,\
 	md.results.TransientSolution[1].Thickness,\
@@ -62,5 +62,5 @@
 	md.results.TransientSolution[2].Vel,\
 	md.results.TransientSolution[2].Pressure,\
-	md.results.TransientSolution[2].Bed,\
+	md.results.TransientSolution[2].Base,\
 	md.results.TransientSolution[2].Surface,\
 	md.results.TransientSolution[2].Thickness,\
@@ -71,5 +71,5 @@
 	md.results.TransientSolution[3].Vel,\
 	md.results.TransientSolution[3].Pressure,\
-	md.results.TransientSolution[3].Bed,\
+	md.results.TransientSolution[3].Base,\
 	md.results.TransientSolution[3].Surface,\
 	md.results.TransientSolution[3].Thickness,\
Index: /issm/trunk/test/NightlyRun/test231.m
===================================================================
--- /issm/trunk/test/NightlyRun/test231.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test231.m	(revision 17806)
@@ -35,5 +35,5 @@
 	(md.results.TransientSolution(1).Vel),...
 	(md.results.TransientSolution(1).Pressure),...
-	(md.results.TransientSolution(1).Bed),...
+	(md.results.TransientSolution(1).Base),...
 	(md.results.TransientSolution(1).Surface),...
 	(md.results.TransientSolution(1).Thickness),...
@@ -44,5 +44,5 @@
 	(md.results.TransientSolution(2).Vel),...
 	(md.results.TransientSolution(2).Pressure),...
-	(md.results.TransientSolution(2).Bed),...
+	(md.results.TransientSolution(2).Base),...
 	(md.results.TransientSolution(2).Surface),...
 	(md.results.TransientSolution(2).Thickness),...
@@ -53,5 +53,5 @@
 	(md.results.TransientSolution(3).Vel),...
 	(md.results.TransientSolution(3).Pressure),...
-	(md.results.TransientSolution(3).Bed),...
+	(md.results.TransientSolution(3).Base),...
 	(md.results.TransientSolution(3).Surface),...
 	(md.results.TransientSolution(3).Thickness),...
@@ -62,5 +62,5 @@
 	(md.results.TransientSolution(4).Vel),...
 	(md.results.TransientSolution(4).Pressure),...
-	(md.results.TransientSolution(4).Bed),...
+	(md.results.TransientSolution(4).Base),...
 	(md.results.TransientSolution(4).Surface),...
 	(md.results.TransientSolution(4).Thickness),...
Index: /issm/trunk/test/NightlyRun/test231.py
===================================================================
--- /issm/trunk/test/NightlyRun/test231.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test231.py	(revision 17806)
@@ -44,5 +44,5 @@
 	md.results.TransientSolution[0].Vel,\
 	md.results.TransientSolution[0].Pressure,\
-	md.results.TransientSolution[0].Bed,\
+	md.results.TransientSolution[0].Base,\
 	md.results.TransientSolution[0].Surface,\
 	md.results.TransientSolution[0].Thickness,\
@@ -53,5 +53,5 @@
 	md.results.TransientSolution[1].Vel,\
 	md.results.TransientSolution[1].Pressure,\
-	md.results.TransientSolution[1].Bed,\
+	md.results.TransientSolution[1].Base,\
 	md.results.TransientSolution[1].Surface,\
 	md.results.TransientSolution[1].Thickness,\
@@ -62,5 +62,5 @@
 	md.results.TransientSolution[2].Vel,\
 	md.results.TransientSolution[2].Pressure,\
-	md.results.TransientSolution[2].Bed,\
+	md.results.TransientSolution[2].Base,\
 	md.results.TransientSolution[2].Surface,\
 	md.results.TransientSolution[2].Thickness,\
@@ -71,5 +71,5 @@
 	md.results.TransientSolution[3].Vel,\
 	md.results.TransientSolution[3].Pressure,\
-	md.results.TransientSolution[3].Bed,\
+	md.results.TransientSolution[3].Base,\
 	md.results.TransientSolution[3].Surface,\
 	md.results.TransientSolution[3].Thickness,\
Index: /issm/trunk/test/NightlyRun/test233.m
===================================================================
--- /issm/trunk/test/NightlyRun/test233.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test233.m	(revision 17806)
@@ -16,5 +16,5 @@
 	'Vx4','Vy4','Vz4','Vel4','Pressure4','Bed4','Surface4','Thickness4','Temperature4','BasalforcingsMeltingRate4'};
 field_tolerances={1e-09,1e-09,1e-09,1e-09,1e-09,1e-09,1e-09,1e-09,1e-09,1e-09, ...
-	1e-09,1e-09,1e-08,1e-09,1e-09,1e-09,1e-09,1e-09,1e-09,1e-07, ...
+	1e-09,1e-09,1e-08,1e-09,1e-09,1e-09,1e-09,1e-09,1e-09,1e-06, ...
 	1e-09,1e-09,1e-08,1e-09,1e-09,1e-09,1e-09,1e-09,1e-09,1e-06, ...
 	1e-09,1e-09,1e-08,1e-09,1e-09,1e-09,1e-09,1e-09,1e-09,1e-06};
@@ -25,5 +25,5 @@
 	(md.results.TransientSolution(1).Vel),...
 	(md.results.TransientSolution(1).Pressure),...
-	(md.results.TransientSolution(1).Bed),...
+	(md.results.TransientSolution(1).Base),...
 	(md.results.TransientSolution(1).Surface),...
 	(md.results.TransientSolution(1).Thickness),...
@@ -35,5 +35,5 @@
 	(md.results.TransientSolution(2).Vel),...
 	(md.results.TransientSolution(2).Pressure),...
-	(md.results.TransientSolution(2).Bed),...
+	(md.results.TransientSolution(2).Base),...
 	(md.results.TransientSolution(2).Surface),...
 	(md.results.TransientSolution(2).Thickness),...
@@ -45,5 +45,5 @@
 	(md.results.TransientSolution(3).Vel),...
 	(md.results.TransientSolution(3).Pressure),...
-	(md.results.TransientSolution(3).Bed),...
+	(md.results.TransientSolution(3).Base),...
 	(md.results.TransientSolution(3).Surface),...
 	(md.results.TransientSolution(3).Thickness),...
@@ -55,5 +55,5 @@
 	(md.results.TransientSolution(4).Vel),...
 	(md.results.TransientSolution(4).Pressure),...
-	(md.results.TransientSolution(4).Bed),...
+	(md.results.TransientSolution(4).Base),...
 	(md.results.TransientSolution(4).Surface),...
 	(md.results.TransientSolution(4).Thickness),...
Index: /issm/trunk/test/NightlyRun/test233.py
===================================================================
--- /issm/trunk/test/NightlyRun/test233.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test233.py	(revision 17806)
@@ -26,5 +26,5 @@
 	'Vx4','Vy4','Vz4','Vel4','Pressure4','Bed4','Surface4','Thickness4','Temperature4','BasalforcingsMeltingRate4']
 field_tolerances=[1e-09,1e-09,1e-09,1e-09,1e-09,1e-09,1e-09,1e-09,1e-09,1e-09, \
-	1e-09,1e-09,1e-08,1e-09,1e-09,1e-09,1e-09,1e-09,1e-09,1e-07, \
+	1e-09,1e-09,1e-08,1e-09,1e-09,1e-09,1e-09,1e-09,1e-09,1e-06, \
 	1e-09,1e-09,1e-08,1e-09,1e-09,1e-09,1e-09,1e-09,1e-09,1e-06, \
 	1e-09,1e-09,1e-08,1e-09,1e-09,1e-09,1e-09,1e-09,1e-09,1e-06]
@@ -35,5 +35,5 @@
 	md.results.TransientSolution[0].Vel,\
 	md.results.TransientSolution[0].Pressure,\
-	md.results.TransientSolution[0].Bed,\
+	md.results.TransientSolution[0].Base,\
 	md.results.TransientSolution[0].Surface,\
 	md.results.TransientSolution[0].Thickness,\
@@ -45,5 +45,5 @@
 	md.results.TransientSolution[1].Vel,\
 	md.results.TransientSolution[1].Pressure,\
-	md.results.TransientSolution[1].Bed,\
+	md.results.TransientSolution[1].Base,\
 	md.results.TransientSolution[1].Surface,\
 	md.results.TransientSolution[1].Thickness,\
@@ -55,5 +55,5 @@
 	md.results.TransientSolution[2].Vel,\
 	md.results.TransientSolution[2].Pressure,\
-	md.results.TransientSolution[2].Bed,\
+	md.results.TransientSolution[2].Base,\
 	md.results.TransientSolution[2].Surface,\
 	md.results.TransientSolution[2].Thickness,\
@@ -65,5 +65,5 @@
 	md.results.TransientSolution[3].Vel,\
 	md.results.TransientSolution[3].Pressure,\
-	md.results.TransientSolution[3].Bed,\
+	md.results.TransientSolution[3].Base,\
 	md.results.TransientSolution[3].Surface,\
 	md.results.TransientSolution[3].Thickness,\
Index: /issm/trunk/test/NightlyRun/test236.m
===================================================================
--- /issm/trunk/test/NightlyRun/test236.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test236.m	(revision 17806)
@@ -1,10 +1,9 @@
 md=triangle(model(),'../Exp/Square.exp',150000.);
 md=setmask(md,'all','');
+md=parameterize(md,'../Par/SquareShelf.par');
 
 % Use of ispdd and isdelta18o methods
-md.surfaceforcings.ispdd=1;
+md.surfaceforcings = SMBpdd();
 md.surfaceforcings.isdelta18o=1;
-
-md=parameterize(md,'../Par/SquareShelf.par');
 
 % Add temperature, precipitation and delta18o needed to measure the surface mass balance
@@ -46,4 +45,5 @@
 
 % 
+md.transient.requested_outputs={'default','SurfaceforcingsMonthlytemperatures'};
 md=setflowequation(md,'SSA','all');
 md.cluster=generic('name',oshostname(),'np',3);
@@ -60,5 +60,5 @@
 	(md.results.TransientSolution(1).Vel),...
 	(md.results.TransientSolution(1).Pressure),...
-	(md.results.TransientSolution(1).Bed),...
+	(md.results.TransientSolution(1).Base),...
 	(md.results.TransientSolution(1).Surface),...
 	(md.results.TransientSolution(1).Thickness),...
@@ -69,5 +69,5 @@
 	(md.results.TransientSolution(2).Vel),...
 	(md.results.TransientSolution(2).Pressure),...
-	(md.results.TransientSolution(2).Bed),...
+	(md.results.TransientSolution(2).Base),...
 	(md.results.TransientSolution(2).Surface),...
 	(md.results.TransientSolution(2).Thickness),...
@@ -78,5 +78,5 @@
 	(md.results.TransientSolution(3).Vel),...
 	(md.results.TransientSolution(3).Pressure),...
-	(md.results.TransientSolution(3).Bed),...
+	(md.results.TransientSolution(3).Base),...
 	(md.results.TransientSolution(3).Surface),...
 	(md.results.TransientSolution(3).Thickness),...
Index: /issm/trunk/test/NightlyRun/test236.py
===================================================================
--- /issm/trunk/test/NightlyRun/test236.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test236.py	(revision 17806)
@@ -11,10 +11,9 @@
 md=triangle(model(),'../Exp/Square.exp',150000.)
 md=setmask(md,'all','')
+md=parameterize(md,'../Par/SquareShelf.py')
 
 # Use of ispdd and isdelta18o methods
-md.surfaceforcings.ispdd=1
+md.surfaceforcings = SMBpdd();
 md.surfaceforcings.isdelta18o=1
-
-md=parameterize(md,'../Par/SquareShelf.py')
 
 # Add temperature, precipitation and delta18o needed to measure the surface mass balance
@@ -57,4 +56,5 @@
 
 # 
+md.transient.requested_outputs=['default','SurfaceforcingsMonthlytemperatures']
 md=setflowequation(md,'SSA','all')
 md.cluster=generic('name',oshostname(),'np',3)
@@ -71,5 +71,5 @@
 	md.results.TransientSolution[0].Vel,\
 	md.results.TransientSolution[0].Pressure,\
-	md.results.TransientSolution[0].Bed,\
+	md.results.TransientSolution[0].Base,\
 	md.results.TransientSolution[0].Surface,\
 	md.results.TransientSolution[0].Thickness,\
@@ -80,5 +80,5 @@
 	md.results.TransientSolution[1].Vel,\
 	md.results.TransientSolution[1].Pressure,\
-	md.results.TransientSolution[1].Bed,\
+	md.results.TransientSolution[1].Base,\
 	md.results.TransientSolution[1].Surface,\
 	md.results.TransientSolution[1].Thickness,\
@@ -89,5 +89,5 @@
 	md.results.TransientSolution[2].Vel,\
 	md.results.TransientSolution[2].Pressure,\
-	md.results.TransientSolution[2].Bed,\
+	md.results.TransientSolution[2].Base,\
 	md.results.TransientSolution[2].Surface,\
 	md.results.TransientSolution[2].Thickness,\
Index: /issm/trunk/test/NightlyRun/test237.m
===================================================================
--- /issm/trunk/test/NightlyRun/test237.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test237.m	(revision 17806)
@@ -3,5 +3,5 @@
 
 % Use of ispdd and isdelta18o methods
-md.surfaceforcings.ispdd=1;
+md.surfaceforcings = SMBpdd();
 md.surfaceforcings.isdelta18o=1;
 
@@ -47,4 +47,5 @@
 
 %
+md.transient.requested_outputs={'default','SurfaceforcingsMonthlytemperatures'};
 md=extrude(md,3,1.);
 md=setflowequation(md,'SSA','all');
@@ -66,5 +67,5 @@
 	(md.results.TransientSolution(1).Vel),...
 	(md.results.TransientSolution(1).Pressure),...
-	(md.results.TransientSolution(1).Bed),...
+	(md.results.TransientSolution(1).Base),...
 	(md.results.TransientSolution(1).Surface),...
 	(md.results.TransientSolution(1).Thickness),...
@@ -78,5 +79,5 @@
 	(md.results.TransientSolution(2).Vel),...
 	(md.results.TransientSolution(2).Pressure),...
-	(md.results.TransientSolution(2).Bed),...
+	(md.results.TransientSolution(2).Base),...
 	(md.results.TransientSolution(2).Surface),...
 	(md.results.TransientSolution(2).Thickness),...
@@ -90,5 +91,5 @@
 	(md.results.TransientSolution(3).Vel),...
 	(md.results.TransientSolution(3).Pressure),...
-	(md.results.TransientSolution(3).Bed),...
+	(md.results.TransientSolution(3).Base),...
 	(md.results.TransientSolution(3).Surface),...
 	(md.results.TransientSolution(3).Thickness),...
Index: /issm/trunk/test/NightlyRun/test237.py
===================================================================
--- /issm/trunk/test/NightlyRun/test237.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test237.py	(revision 17806)
@@ -8,4 +8,5 @@
 from solve import *
 from MatlabFuncs import *
+from generic import generic
 
 md=triangle(model(),'../Exp/Square.exp',600000)    #180000
@@ -13,5 +14,5 @@
 
 # Use of ispdd and isdelta18o methods
-md.surfaceforcings.ispdd=1
+md.surfaceforcings = SMBpdd();
 md.surfaceforcings.isdelta18o=1
 
@@ -44,5 +45,5 @@
 md.thermal.spctemperature=numpy.vstack((md.thermal.spctemperature,itemp.reshape(1,-1)))
 
-md.initialization.temperature=md.surfaceforcings.temperatures_lgm[0:md.mesh.numberofvertices,0]    #*ones(md.mesh.numberofvertices,1)
+md.initialization.temperature=md.surfaceforcings.temperatures_lgm[0:md.mesh.numberofvertices,0].reshape(-1,1)   #*ones(md.mesh.numberofvertices,1)
 
 # creating precipitation
@@ -58,4 +59,5 @@
 
 #
+md.transient.requested_outputs=['default','SurfaceforcingsMonthlytemperatures']
 md.extrude(3,1.)
 md=setflowequation(md,'SSA','all')
@@ -77,5 +79,5 @@
 	md.results.TransientSolution[0].Vel,\
 	md.results.TransientSolution[0].Pressure,\
-	md.results.TransientSolution[0].Bed,\
+	md.results.TransientSolution[0].Base,\
 	md.results.TransientSolution[0].Surface,\
 	md.results.TransientSolution[0].Thickness,\
@@ -89,5 +91,5 @@
 	md.results.TransientSolution[1].Vel,\
 	md.results.TransientSolution[1].Pressure,\
-	md.results.TransientSolution[1].Bed,\
+	md.results.TransientSolution[1].Base,\
 	md.results.TransientSolution[1].Surface,\
 	md.results.TransientSolution[1].Thickness,\
@@ -101,5 +103,5 @@
 	md.results.TransientSolution[2].Vel,\
 	md.results.TransientSolution[2].Pressure,\
-	md.results.TransientSolution[2].Bed,\
+	md.results.TransientSolution[2].Base,\
 	md.results.TransientSolution[2].Surface,\
 	md.results.TransientSolution[2].Thickness,\
Index: /issm/trunk/test/NightlyRun/test270.m
===================================================================
--- /issm/trunk/test/NightlyRun/test270.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test270.m	(revision 17806)
@@ -1,6 +1,9 @@
 md=triangle(model(),'../Exp/Square.exp',150000.);
 md=setmask(md,'all','');
+md.materials=matdamageice();
 md=parameterize(md,'../Par/SquareShelf.par');
+md.damage.isdamage=1;
 md.damage.D=0.5*ones(md.mesh.numberofvertices,1);
+md.damage.spcdamage=NaN*ones(md.mesh.numberofvertices,1);
 md=setflowequation(md,'SSA','all');
 md.cluster=generic('name',oshostname(),'np',3);
Index: /issm/trunk/test/NightlyRun/test270.py
===================================================================
--- /issm/trunk/test/NightlyRun/test270.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test270.py	(revision 17806)
@@ -1,17 +1,21 @@
 import numpy
-from model import *
-from triangle import *
-from setmask import *
-from parameterize import *
-from paterson import *
-from setflowequation import *
-from EnumDefinitions import *
-from solve import *
-from MatlabFuncs import *
+from model import model
+from triangle import triangle
+from setmask import setmask
+from parameterize import parameterize
+from setflowequation import setflowequation
+from EnumDefinitions import StressbalanceSolutionEnum
+from solve import solve
+from matdamageice import matdamageice
+from generic import generic
+from socket import gethostname as oshostname
 
 md=triangle(model(),'../Exp/Square.exp',150000.)
 md=setmask(md,'all','')
+md.materials=matdamageice()
 md=parameterize(md,'../Par/SquareShelf.py')
-md.damage.D=0.5*numpy.ones((md.mesh.numberofvertices,1))
+md.damage.isdamage=1
+md.damage.D=0.5*numpy.ones(md.mesh.numberofvertices)
+md.damage.spcdamage=numpy.nan*numpy.ones(md.mesh.numberofvertices)
 md=setflowequation(md,'SSA','all')
 md.cluster=generic('name',oshostname(),'np',3)
Index: /issm/trunk/test/NightlyRun/test271.m
===================================================================
--- /issm/trunk/test/NightlyRun/test271.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test271.m	(revision 17806)
@@ -1,6 +1,8 @@
 md=triangle(model(),'../Exp/Square.exp',150000.);
 md=setmask(md,'all','');
+md.materials=matdamageice();
 md=parameterize(md,'../Par/SquareShelf.par');
-md.damage.D=0.5*ones(md.mesh.numberofvertices,1);
+md.damage.isdamage=1;
+md.damage.D=zeros(md.mesh.numberofvertices,1);
 md.damage.spcdamage=NaN*ones(md.mesh.numberofvertices,1);
 md.damage.law='pralong';
@@ -10,7 +12,8 @@
 boundary(md.mesh.segments(:,1:2))=1;
 pos=find(~md.mask.ice_levelset==0 & boundary==1);
-md.damage.spcdamage(pos)=0;
+md.damage.spcdamage(pos)=0.5;
+md.damage.stabilization=1;
 
-md.verbose=verbose('solution',true);
+md.damage.requested_outputs={'default','DamageF'};
 
 md=setflowequation(md,'SSA','all');
@@ -19,5 +22,8 @@
 
 %Fields and tolerances to track changes
-field_names     ={'D'};
-field_tolerances={1e-13};
-field_values={md.results.DamageEvolutionSolution.DamageD};
+field_names={'D','F'};
+field_tolerances={1e-13,1e-13};
+field_values={...
+		(md.results.DamageEvolutionSolution.DamageDbar),...
+		(md.results.DamageEvolutionSolution.DamageF),...
+	};
Index: /issm/trunk/test/NightlyRun/test271.py
===================================================================
--- /issm/trunk/test/NightlyRun/test271.py	(revision 17806)
+++ /issm/trunk/test/NightlyRun/test271.py	(revision 17806)
@@ -0,0 +1,38 @@
+import numpy 
+from triangle import triangle
+from model import model
+from setmask import setmask
+from parameterize import parameterize
+from verbose import verbose
+from setflowequation import setflowequation
+from generic import generic
+from socket import gethostname as oshostname
+from solve import solve
+from EnumDefinitions import DamageEvolutionSolutionEnum
+from matdamageice import matdamageice
+
+md=triangle(model(),'../Exp/Square.exp',150000.)
+md=setmask(md,'all','')
+md.materials=matdamageice()
+md=parameterize(md,'../Par/SquareShelf.py')
+md.damage.isdamage=1
+md.damage.D=numpy.zeros(md.mesh.numberofvertices)
+md.damage.spcdamage=numpy.nan*numpy.ones(md.mesh.numberofvertices)
+md.damage.law='pralong'
+md.damage.stabilization=1;
+
+pos=numpy.nonzero(numpy.logical_and(md.mask.ice_levelset[:,0]!=0,md.mesh.vertexonboundary==1))
+md.damage.spcdamage[pos]=0.5;
+
+md.damage.requested_outputs=['default','DamageF']
+
+md=setflowequation(md,'SSA','all')
+md.cluster=generic('name',oshostname(),'np',3)
+md=solve(md,DamageEvolutionSolutionEnum())
+
+field_names=['D','F']
+field_tolerances=[1.e-13,1.e-13]
+field_values=[\
+		md.results.DamageEvolutionSolution.DamageDbar,\
+		md.results.DamageEvolutionSolution.DamageF,\
+		]
Index: /issm/trunk/test/NightlyRun/test272.m
===================================================================
--- /issm/trunk/test/NightlyRun/test272.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test272.m	(revision 17806)
@@ -1,6 +1,9 @@
 md=triangle(model(),'../Exp/Square.exp',150000.);
 md=setmask(md,'all','');
+md.materials=matdamageice();
 md=parameterize(md,'../Par/SquareShelf.par');
+md.damage.isdamage=1;
 md.damage.D=0.5*ones(md.mesh.numberofvertices,1);
+md.damage.spcdamage=NaN*ones(md.mesh.numberofvertices,1);
 md=setflowequation(md,'SSA','all');
 md.verbose=verbose('control',true);
Index: /issm/trunk/test/NightlyRun/test272.py
===================================================================
--- /issm/trunk/test/NightlyRun/test272.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test272.py	(revision 17806)
@@ -1,17 +1,21 @@
 import numpy
-from model import *
-from triangle import *
-from setmask import *
-from parameterize import *
-from paterson import *
-from setflowequation import *
-from EnumDefinitions import *
-from solve import *
-from MatlabFuncs import *
+from model import model
+from triangle import triangle
+from setmask import setmask
+from parameterize import parameterize
+from setflowequation import setflowequation
+from EnumDefinitions import StressbalanceSolutionEnum
+from solve import solve
+from socket import gethostname as oshostname
+from matdamageice import matdamageice
+from generic import generic
 
 md=triangle(model(),'../Exp/Square.exp',150000.)
 md=setmask(md,'all','')
+md.materials=matdamageice()
 md=parameterize(md,'../Par/SquareShelf.py')
-md.damage.D=0.5*numpy.ones((md.mesh.numberofvertices,1))
+md.damage.isdamage=1
+md.damage.D=0.5*numpy.ones(md.mesh.numberofvertices)
+md.damage.spcdamage=numpy.nan*numpy.ones(md.mesh.numberofvertices)
 md=setflowequation(md,'SSA','all')
 
Index: /issm/trunk/test/NightlyRun/test274.m
===================================================================
--- /issm/trunk/test/NightlyRun/test274.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test274.m	(revision 17806)
@@ -2,6 +2,9 @@
 md=meshprocessrifts(md,'../Exp/Square.exp');
 md=setmask(md,'all','');
+md.materials=matdamageice();
 md=parameterize(md,'../Par/SquareShelf2.par');
+md.damage.isdamage=1;
 md.damage.D=0.5*ones(md.mesh.numberofvertices,1);
+md.damage.spcdamage=NaN*ones(md.mesh.numberofvertices,1);
 md=setflowequation(md,'SSA','all');
 
@@ -11,5 +14,5 @@
 %Fields and tolerances to track changes
 field_names     ={'Vx','Vy','Vel','Pressure'};
-field_tolerances={4.5e-8,1.35e-8,1.55e-8,1e-11};
+field_tolerances={5.0e-8,2.0e-8,2.0e-8,1e-11};
 field_values={...
 	   (md.results.StressbalanceSolution.Vx),...
Index: /issm/trunk/test/NightlyRun/test274.py
===================================================================
--- /issm/trunk/test/NightlyRun/test274.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test274.py	(revision 17806)
@@ -1,19 +1,23 @@
 import numpy
-from model import *
-from triangle import *
-from meshprocessrifts import *
-from setmask import *
-from parameterize import *
-from paterson import *
-from setflowequation import *
-from EnumDefinitions import *
-from solve import *
-from MatlabFuncs import *
+from model import model
+from triangle import triangle
+from setmask import setmask
+from parameterize import parameterize
+from setflowequation import setflowequation
+from EnumDefinitions import StressbalanceSolutionEnum
+from solve import solve
+from socket import gethostname as oshostname
+from matdamageice import matdamageice
+from meshprocessrifts import meshprocessrifts
+from generic import generic
 
 md=triangle(model(),'../Exp/SquareHole.exp','../Exp/Rifts.exp',50000.)
 md=meshprocessrifts(md,'../Exp/Square.exp')
 md=setmask(md,'all','')
+md.materials=matdamageice()
 md=parameterize(md,'../Par/SquareShelf2.py')
-md.damage.D=0.5*numpy.ones((md.mesh.numberofvertices,1))
+md.damage.isdamage=1
+md.damage.D=0.5*numpy.ones(md.mesh.numberofvertices)
+md.damage.spcdamage=numpy.nan*numpy.ones(md.mesh.numberofvertices)
 md=setflowequation(md,'SSA','all')
 
Index: /issm/trunk/test/NightlyRun/test275.m
===================================================================
--- /issm/trunk/test/NightlyRun/test275.m	(revision 17806)
+++ /issm/trunk/test/NightlyRun/test275.m	(revision 17806)
@@ -0,0 +1,28 @@
+md=triangle(model(),'../Exp/Square.exp',150000.);
+md=setmask(md,'all','');
+md.materials=matdamageice();
+md=parameterize(md,'../Par/SquareShelf.par');
+md.damage.isdamage=1;
+md.damage.D=0.1*ones(md.mesh.numberofvertices,1);
+md.damage.spcdamage=NaN*ones(md.mesh.numberofvertices,1);
+md.damage.law='pralong';
+
+md.damage.c1=1.e-11;
+md.damage.c2=0.4;
+md.damage.c3=1.e-3;
+md.damage.healing=0.4;
+md.damage.stress_threshold=1e5;
+md.damage.stabilization=1;
+
+md.damage.requested_outputs={'default','DamageF'};
+
+md=setflowequation(md,'SSA','all');
+md.cluster=generic('name',oshostname(),'np',3);
+md=solve(md,DamageEvolutionSolutionEnum());
+
+field_names={'D','F'};
+field_tolerances={1e-13,1e-13};
+field_values={...
+		(md.results.DamageEvolutionSolution.DamageDbar),...
+		(md.results.DamageEvolutionSolution.DamageF),...
+	};
Index: /issm/trunk/test/NightlyRun/test275.py
===================================================================
--- /issm/trunk/test/NightlyRun/test275.py	(revision 17806)
+++ /issm/trunk/test/NightlyRun/test275.py	(revision 17806)
@@ -0,0 +1,41 @@
+import numpy
+from triangle import triangle
+from model import model
+from setmask import setmask
+from parameterize import parameterize
+from verbose import verbose
+from setflowequation import setflowequation
+from generic import generic
+from socket import gethostname as oshostname
+from solve import solve
+from EnumDefinitions import DamageEvolutionSolutionEnum
+from matdamageice import matdamageice
+
+md=triangle(model(),'../Exp/Square.exp',150000.)
+md=setmask(md,'all','')
+md.materials=matdamageice()
+md=parameterize(md,'../Par/SquareShelf.py')
+md.damage.isdamage=1
+md.damage.D=0.1*numpy.ones(md.mesh.numberofvertices)
+md.damage.spcdamage=numpy.nan*numpy.ones(md.mesh.numberofvertices)
+md.damage.law='pralong'
+
+md.damage.c1=1.e-11
+md.damage.c2=0.4
+md.damage.c3=1.e-3
+md.damage.healing=0.4
+md.damage.stress_threshold=1.e5
+md.damage.stabilization=1
+
+md.damage.requested_outputs=['default','DamageF']
+
+md=setflowequation(md,'SSA','all')
+md.cluster=generic('name',oshostname(),'np',3)
+md=solve(md,DamageEvolutionSolutionEnum())
+
+field_names=['D','F']
+field_tolerances=[1.e-13,1.e-13]
+field_values=[\
+		md.results.DamageEvolutionSolution.DamageDbar,\
+		md.results.DamageEvolutionSolution.DamageF,\
+		]
Index: /issm/trunk/test/NightlyRun/test285.m
===================================================================
--- /issm/trunk/test/NightlyRun/test285.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test285.m	(revision 17806)
@@ -9,9 +9,9 @@
 field_tolerances={};
 field_values={};
-for i={'P1bubble','P1bubblecondensed','P1xP2','P2xP1','P2'}
+for i={'P1bubble','P1bubblecondensed','P1xP2','P2xP1','P2','P1xP3','P2xP4'}
 	md.flowequation.fe_HO=i{1};
 	md=solve(md,StressbalanceSolutionEnum());
 	field_names     ={field_names{:},['Vx' i{1}],['Vy' i{1}],['Vz' i{1}],['Vel' i{1}],['Pressure' i{1}]};
-	field_tolerances={field_tolerances{:},1e-08,1e-08,1e-08,1e-08,1e-13};
+	field_tolerances={field_tolerances{:},6e-08,4e-08,2e-08,4e-08,1e-13};
 	field_values={field_values{:},...
 	(md.results.StressbalanceSolution.Vx),...
Index: /issm/trunk/test/NightlyRun/test285.py
===================================================================
--- /issm/trunk/test/NightlyRun/test285.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test285.py	(revision 17806)
@@ -19,9 +19,9 @@
 field_tolerances=[]
 field_values=[]
-for i in ['P1bubble','P1bubblecondensed','P1xP2','P2xP1','P2']:
+for i in ['P1bubble','P1bubblecondensed','P1xP2','P2xP1','P2','P1xP3','P2xP4']:
 	md.flowequation.fe_HO=i
 	md=solve(md,StressbalanceSolutionEnum())
 	field_names     =field_names+['Vx'+i,'Vy'+i,'Vz'+i,'Vel'+i,'Pressure'+i]
-	field_tolerances=field_tolerances+[1e-08,1e-08,1e-08,1e-08,1e-13]
+	field_tolerances=field_tolerances+[6e-08,4e-08,2e-08,4e-08,1e-13]
 	field_values=field_values+[\
 		md.results.StressbalanceSolution.Vx,\
Index: /issm/trunk/test/NightlyRun/test290.m
===================================================================
--- /issm/trunk/test/NightlyRun/test290.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test290.m	(revision 17806)
@@ -10,5 +10,5 @@
 %Fields and tolerances to track changes
 field_names     ={'Vx','Vy','Vz','Vel','Pressure'};
-field_tolerances={1e-7,1e-7,1e-6,1e-7,1e-7};
+field_tolerances={5e-5,5e-5,8e-5,5e-5,1e-7};
 field_values={...
 	(md.results.StressbalanceSolution.Vx),...
Index: /issm/trunk/test/NightlyRun/test290.py
===================================================================
--- /issm/trunk/test/NightlyRun/test290.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test290.py	(revision 17806)
@@ -20,5 +20,5 @@
 #Fields and tolerances to track changes
 field_names     =['Vx', 'Vy', 'Vz', 'Vel','Pressure'];
-field_tolerances=[1e-7,1e-7,2e-7,1e-7,1e-7];
+field_tolerances=[5e-5,5e-5,8e-5,5e-5,1e-7]
 field_values=[\
 	md.results.StressbalanceSolution.Vx,\
Index: /issm/trunk/test/NightlyRun/test3004.m
===================================================================
--- /issm/trunk/test/NightlyRun/test3004.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test3004.m	(revision 17806)
@@ -12,5 +12,5 @@
 %Fields and tolerances to track changes
 field_names     ={'Vx','Vy','Vz','Vel','Pressure'};
-field_tolerances={1e-08,1e-08,1e-07,1e-08,1e-08};
+field_tolerances={1e-08,1e-08,3e-07,1e-08,1e-08};
 field_values={...
 	(md.results.StressbalanceSolution.Vx),...
Index: /issm/trunk/test/NightlyRun/test3004.py
===================================================================
--- /issm/trunk/test/NightlyRun/test3004.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test3004.py	(revision 17806)
@@ -20,5 +20,5 @@
 #Fields and tolerances to track changes
 field_names     =['Vx','Vy','Vz','Vel','Pressure']
-field_tolerances=[1e-08,1e-08,1e-07,1e-08,1e-08]
+field_tolerances=[1e-08,1e-08,3e-07,1e-08,1e-08]
 field_values=[\
 	md.results.StressbalanceSolution.Vx,\
Index: /issm/trunk/test/NightlyRun/test3010.m
===================================================================
--- /issm/trunk/test/NightlyRun/test3010.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test3010.m	(revision 17806)
@@ -21,5 +21,5 @@
 	(md.results.TransientSolution(1).Vel),...
 	(md.results.TransientSolution(1).Pressure),...
-	(md.results.TransientSolution(1).Bed),...
+	(md.results.TransientSolution(1).Base),...
 	(md.results.TransientSolution(1).Surface),...
 	(md.results.TransientSolution(1).Thickness),...
@@ -29,5 +29,5 @@
 	(md.results.TransientSolution(2).Vel),...
 	(md.results.TransientSolution(2).Pressure),...
-	(md.results.TransientSolution(2).Bed),...
+	(md.results.TransientSolution(2).Base),...
 	(md.results.TransientSolution(2).Surface),...
 	(md.results.TransientSolution(2).Thickness),...
@@ -37,5 +37,5 @@
 	(md.results.TransientSolution(3).Vel),...
 	(md.results.TransientSolution(3).Pressure),...
-	(md.results.TransientSolution(3).Bed),...
+	(md.results.TransientSolution(3).Base),...
 	(md.results.TransientSolution(3).Surface),...
 	(md.results.TransientSolution(3).Thickness),...
Index: /issm/trunk/test/NightlyRun/test3010.py
===================================================================
--- /issm/trunk/test/NightlyRun/test3010.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test3010.py	(revision 17806)
@@ -29,5 +29,5 @@
 	md.results.TransientSolution[0].Vel,\
 	md.results.TransientSolution[0].Pressure,\
-	md.results.TransientSolution[0].Bed,\
+	md.results.TransientSolution[0].Base,\
 	md.results.TransientSolution[0].Surface,\
 	md.results.TransientSolution[0].Thickness,\
@@ -37,5 +37,5 @@
 	md.results.TransientSolution[1].Vel,\
 	md.results.TransientSolution[1].Pressure,\
-	md.results.TransientSolution[1].Bed,\
+	md.results.TransientSolution[1].Base,\
 	md.results.TransientSolution[1].Surface,\
 	md.results.TransientSolution[1].Thickness,\
@@ -45,5 +45,5 @@
 	md.results.TransientSolution[2].Vel,\
 	md.results.TransientSolution[2].Pressure,\
-	md.results.TransientSolution[2].Bed,\
+	md.results.TransientSolution[2].Base,\
 	md.results.TransientSolution[2].Surface,\
 	md.results.TransientSolution[2].Thickness,\
Index: /issm/trunk/test/NightlyRun/test3015.m
===================================================================
--- /issm/trunk/test/NightlyRun/test3015.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test3015.m	(revision 17806)
@@ -38,6 +38,6 @@
 md.autodiff.isautodiff=false;
 md.geometry.thickness(index)=h0;
-md.geometry.bed=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness;
-md.geometry.surface=md.geometry.bed+md.geometry.thickness;
+md.geometry.base=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness;
+md.geometry.surface=md.geometry.base+md.geometry.thickness;
 md=SetIceShelfBC(md);
 
@@ -49,6 +49,6 @@
 md.autodiff.isautodiff=false;
 md.geometry.thickness(index)=h2;
-md.geometry.bed=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness;
-md.geometry.surface=md.geometry.bed+md.geometry.thickness;
+md.geometry.base=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness;
+md.geometry.surface=md.geometry.base+md.geometry.thickness;
 md=SetIceShelfBC(md);
 
@@ -63,6 +63,6 @@
 md.autodiff.isautodiff=true;
 md.geometry.thickness(index)=h1;
-md.geometry.bed=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness;
-md.geometry.surface=md.geometry.bed+md.geometry.thickness;
+md.geometry.base=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness;
+md.geometry.surface=md.geometry.base+md.geometry.thickness;
 md=SetIceShelfBC(md);
 
Index: /issm/trunk/test/NightlyRun/test3015.py
===================================================================
--- /issm/trunk/test/NightlyRun/test3015.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test3015.py	(revision 17806)
@@ -52,6 +52,6 @@
 md.autodiff.isautodiff=False
 md.geometry.thickness[index]=h0
-md.geometry.bed=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness
-md.geometry.surface=md.geometry.bed+md.geometry.thickness
+md.geometry.base=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness
+md.geometry.surface=md.geometry.base+md.geometry.thickness
 md=SetIceShelfBC(md)
 
@@ -63,6 +63,6 @@
 md.autodiff.isautodiff=False
 md.geometry.thickness[index]=h2
-md.geometry.bed=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness
-md.geometry.surface=md.geometry.bed+md.geometry.thickness
+md.geometry.base=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness
+md.geometry.surface=md.geometry.base+md.geometry.thickness
 md=SetIceShelfBC(md)
 
@@ -77,6 +77,6 @@
 md.autodiff.isautodiff=True
 md.geometry.thickness[index]=h1
-md.geometry.bed=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness
-md.geometry.surface=md.geometry.bed+md.geometry.thickness
+md.geometry.base=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness
+md.geometry.surface=md.geometry.base+md.geometry.thickness
 md=SetIceShelfBC(md)
 
Index: /issm/trunk/test/NightlyRun/test3020.m
===================================================================
--- /issm/trunk/test/NightlyRun/test3020.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test3020.m	(revision 17806)
@@ -40,6 +40,6 @@
 md.autodiff.isautodiff=false;
 md.geometry.thickness(index)=h0;
-md.geometry.bed=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness;
-md.geometry.surface=md.geometry.bed+md.geometry.thickness;
+md.geometry.base=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness;
+md.geometry.surface=md.geometry.base+md.geometry.thickness;
 md=SetIceShelfBC(md);
 
@@ -52,6 +52,6 @@
 md.autodiff.isautodiff=false;
 md.geometry.thickness(index)=h2;
-md.geometry.bed=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness;
-md.geometry.surface=md.geometry.bed+md.geometry.thickness;
+md.geometry.base=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness;
+md.geometry.surface=md.geometry.base+md.geometry.thickness;
 md=SetIceShelfBC(md);
 
@@ -68,6 +68,6 @@
 md.autodiff.isautodiff=true;
 md.geometry.thickness(index)=h1;
-md.geometry.bed=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness;
-md.geometry.surface=md.geometry.bed+md.geometry.thickness;
+md.geometry.base=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness;
+md.geometry.surface=md.geometry.base+md.geometry.thickness;
 md=SetIceShelfBC(md);
 
Index: /issm/trunk/test/NightlyRun/test3020.py
===================================================================
--- /issm/trunk/test/NightlyRun/test3020.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test3020.py	(revision 17806)
@@ -54,6 +54,6 @@
 md.autodiff.isautodiff=False
 md.geometry.thickness[index]=h0
-md.geometry.bed=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness
-md.geometry.surface=md.geometry.bed+md.geometry.thickness
+md.geometry.base=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness
+md.geometry.surface=md.geometry.base+md.geometry.thickness
 md=SetIceShelfBC(md)
 
@@ -66,6 +66,6 @@
 md.autodiff.isautodiff=False
 md.geometry.thickness[index]=h2
-md.geometry.bed=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness
-md.geometry.surface=md.geometry.bed+md.geometry.thickness
+md.geometry.base=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness
+md.geometry.surface=md.geometry.base+md.geometry.thickness
 md=SetIceShelfBC(md)
 
@@ -82,6 +82,6 @@
 md.autodiff.isautodiff=True
 md.geometry.thickness[index]=h1
-md.geometry.bed=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness
-md.geometry.surface=md.geometry.bed+md.geometry.thickness
+md.geometry.base=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness
+md.geometry.surface=md.geometry.base+md.geometry.thickness
 md=SetIceShelfBC(md)
 
Index: /issm/trunk/test/NightlyRun/test3104.m
===================================================================
--- /issm/trunk/test/NightlyRun/test3104.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test3104.m	(revision 17806)
@@ -12,5 +12,5 @@
 %Fields and tolerances to track changes
 field_names     ={'Vx','Vy','Vz','Vel','Pressure'};
-field_tolerances={1e-08,1e-08,1e-07,1e-08,1e-08};
+field_tolerances={1e-08,1e-08,2.9e-07,1e-08,1e-08};
 field_values={...
 	(md.results.StressbalanceSolution.Vx),...
Index: /issm/trunk/test/NightlyRun/test3104.py
===================================================================
--- /issm/trunk/test/NightlyRun/test3104.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test3104.py	(revision 17806)
@@ -20,5 +20,5 @@
 #Fields and tolerances to track changes
 field_names     =['Vx','Vy','Vz','Vel','Pressure']
-field_tolerances=[1e-08,1e-08,1e-07,1e-08,1e-08]
+field_tolerances=[1e-08,1e-08,2e-07,1e-08,1e-08]
 field_values=[\
 	md.results.StressbalanceSolution.Vx,\
Index: /issm/trunk/test/NightlyRun/test3110.m
===================================================================
--- /issm/trunk/test/NightlyRun/test3110.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test3110.m	(revision 17806)
@@ -21,5 +21,5 @@
 	(md.results.TransientSolution(1).Vel),...
 	(md.results.TransientSolution(1).Pressure),...
-	(md.results.TransientSolution(1).Bed),...
+	(md.results.TransientSolution(1).Base),...
 	(md.results.TransientSolution(1).Surface),...
 	(md.results.TransientSolution(1).Thickness),...
@@ -29,5 +29,5 @@
 	(md.results.TransientSolution(2).Vel),...
 	(md.results.TransientSolution(2).Pressure),...
-	(md.results.TransientSolution(2).Bed),...
+	(md.results.TransientSolution(2).Base),...
 	(md.results.TransientSolution(2).Surface),...
 	(md.results.TransientSolution(2).Thickness),...
@@ -37,5 +37,5 @@
 	(md.results.TransientSolution(3).Vel),...
 	(md.results.TransientSolution(3).Pressure),...
-	(md.results.TransientSolution(3).Bed),...
+	(md.results.TransientSolution(3).Base),...
 	(md.results.TransientSolution(3).Surface),...
 	(md.results.TransientSolution(3).Thickness),...
Index: /issm/trunk/test/NightlyRun/test3110.py
===================================================================
--- /issm/trunk/test/NightlyRun/test3110.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test3110.py	(revision 17806)
@@ -29,5 +29,5 @@
 	md.results.TransientSolution[0].Vel,\
 	md.results.TransientSolution[0].Pressure,\
-	md.results.TransientSolution[0].Bed,\
+	md.results.TransientSolution[0].Base,\
 	md.results.TransientSolution[0].Surface,\
 	md.results.TransientSolution[0].Thickness,\
@@ -37,5 +37,5 @@
 	md.results.TransientSolution[1].Vel,\
 	md.results.TransientSolution[1].Pressure,\
-	md.results.TransientSolution[1].Bed,\
+	md.results.TransientSolution[1].Base,\
 	md.results.TransientSolution[1].Surface,\
 	md.results.TransientSolution[1].Thickness,\
@@ -45,5 +45,5 @@
 	md.results.TransientSolution[2].Vel,\
 	md.results.TransientSolution[2].Pressure,\
-	md.results.TransientSolution[2].Bed,\
+	md.results.TransientSolution[2].Base,\
 	md.results.TransientSolution[2].Surface,\
 	md.results.TransientSolution[2].Thickness,\
Index: /issm/trunk/test/NightlyRun/test314.m
===================================================================
--- /issm/trunk/test/NightlyRun/test314.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test314.m	(revision 17806)
@@ -8,5 +8,5 @@
 %Fields and tolerances to track changes
 field_names     ={'Vx1','Vy1','Vel1','Pressure1','Bed1','Surface1','Thickness1','Vx2','Vy2','Vel2','Pressure2','Bed2','Surface2','Thickness2','Vx3','Vy3','Vel3','Pressure3','Bed3','Surface3','Thickness3'};
-field_tolerances={1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-10,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-10,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13};
+field_tolerances={1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-10,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-10,1.5e-13,1.5e-13,1e-13,1e-13,1e-13,1e-13};
 field_values={...
 	(md.results.TransientSolution(1).Vx),...
@@ -14,5 +14,5 @@
 	(md.results.TransientSolution(1).Vel),...
 	(md.results.TransientSolution(1).Pressure),...
-	(md.results.TransientSolution(1).Bed),...
+	(md.results.TransientSolution(1).Base),...
 	(md.results.TransientSolution(1).Surface),...
 	(md.results.TransientSolution(1).Thickness),...
@@ -21,5 +21,5 @@
 	(md.results.TransientSolution(2).Vel),...
 	(md.results.TransientSolution(2).Pressure),...
-	(md.results.TransientSolution(2).Bed),...
+	(md.results.TransientSolution(2).Base),...
 	(md.results.TransientSolution(2).Surface),...
 	(md.results.TransientSolution(2).Thickness),...
@@ -28,5 +28,5 @@
 	(md.results.TransientSolution(3).Vel),...
 	(md.results.TransientSolution(3).Pressure),...
-	(md.results.TransientSolution(3).Bed),...
+	(md.results.TransientSolution(3).Base),...
 	(md.results.TransientSolution(3).Surface),...
 	(md.results.TransientSolution(3).Thickness),...
Index: /issm/trunk/test/NightlyRun/test314.py
===================================================================
--- /issm/trunk/test/NightlyRun/test314.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test314.py	(revision 17806)
@@ -23,5 +23,5 @@
 	md.results.TransientSolution[0].Vel,\
 	md.results.TransientSolution[0].Pressure,\
-	md.results.TransientSolution[0].Bed,\
+	md.results.TransientSolution[0].Base,\
 	md.results.TransientSolution[0].Surface,\
 	md.results.TransientSolution[0].Thickness,\
@@ -30,5 +30,5 @@
 	md.results.TransientSolution[1].Vel,\
 	md.results.TransientSolution[1].Pressure,\
-	md.results.TransientSolution[1].Bed,\
+	md.results.TransientSolution[1].Base,\
 	md.results.TransientSolution[1].Surface,\
 	md.results.TransientSolution[1].Thickness,\
@@ -37,5 +37,5 @@
 	md.results.TransientSolution[2].Vel,\
 	md.results.TransientSolution[2].Pressure,\
-	md.results.TransientSolution[2].Bed,\
+	md.results.TransientSolution[2].Base,\
 	md.results.TransientSolution[2].Surface,\
 	md.results.TransientSolution[2].Thickness,\
Index: /issm/trunk/test/NightlyRun/test315.m
===================================================================
--- /issm/trunk/test/NightlyRun/test315.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test315.m	(revision 17806)
@@ -13,5 +13,5 @@
 field_tolerances={1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,...,
 	1e-10,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,...
-	1e-10,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13};
+	1e-10,1.5e-13,1.5e-13,1.5e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13};
 field_values={...
 	(md.results.TransientSolution(1).Vx),...
@@ -20,5 +20,5 @@
 	(md.results.TransientSolution(1).Vel),...
 	(md.results.TransientSolution(1).Pressure),...
-	(md.results.TransientSolution(1).Bed),...
+	(md.results.TransientSolution(1).Base),...
 	(md.results.TransientSolution(1).Surface),...
 	(md.results.TransientSolution(1).Thickness),...
@@ -30,5 +30,5 @@
 	(md.results.TransientSolution(2).Vel),...
 	(md.results.TransientSolution(2).Pressure),...
-	(md.results.TransientSolution(2).Bed),...
+	(md.results.TransientSolution(2).Base),...
 	(md.results.TransientSolution(2).Surface),...
 	(md.results.TransientSolution(2).Thickness),...
@@ -40,5 +40,5 @@
 	(md.results.TransientSolution(3).Vel),...
 	(md.results.TransientSolution(3).Pressure),...
-	(md.results.TransientSolution(3).Bed),...
+	(md.results.TransientSolution(3).Base),...
 	(md.results.TransientSolution(3).Surface),...
 	(md.results.TransientSolution(3).Thickness),...
Index: /issm/trunk/test/NightlyRun/test315.py
===================================================================
--- /issm/trunk/test/NightlyRun/test315.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test315.py	(revision 17806)
@@ -29,5 +29,5 @@
 	md.results.TransientSolution[0].Vel,\
 	md.results.TransientSolution[0].Pressure,\
-	md.results.TransientSolution[0].Bed,\
+	md.results.TransientSolution[0].Base,\
 	md.results.TransientSolution[0].Surface,\
 	md.results.TransientSolution[0].Thickness,\
@@ -39,5 +39,5 @@
 	md.results.TransientSolution[1].Vel,\
 	md.results.TransientSolution[1].Pressure,\
-	md.results.TransientSolution[1].Bed,\
+	md.results.TransientSolution[1].Base,\
 	md.results.TransientSolution[1].Surface,\
 	md.results.TransientSolution[1].Thickness,\
@@ -49,5 +49,5 @@
 	md.results.TransientSolution[2].Vel,\
 	md.results.TransientSolution[2].Pressure,\
-	md.results.TransientSolution[2].Bed,\
+	md.results.TransientSolution[2].Base,\
 	md.results.TransientSolution[2].Surface,\
 	md.results.TransientSolution[2].Thickness,\
Index: /issm/trunk/test/NightlyRun/test316.m
===================================================================
--- /issm/trunk/test/NightlyRun/test316.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test316.m	(revision 17806)
@@ -14,5 +14,5 @@
 	(md.results.TransientSolution(1).Vel),...
 	(md.results.TransientSolution(1).Pressure),...
-	(md.results.TransientSolution(1).Bed),...
+	(md.results.TransientSolution(1).Base),...
 	(md.results.TransientSolution(1).Surface),...
 	(md.results.TransientSolution(1).Thickness),...
@@ -21,5 +21,5 @@
 	(md.results.TransientSolution(2).Vel),...
 	(md.results.TransientSolution(2).Pressure),...
-	(md.results.TransientSolution(2).Bed),...
+	(md.results.TransientSolution(2).Base),...
 	(md.results.TransientSolution(2).Surface),...
 	(md.results.TransientSolution(2).Thickness),...
@@ -28,5 +28,5 @@
 	(md.results.TransientSolution(3).Vel),...
 	(md.results.TransientSolution(3).Pressure),...
-	(md.results.TransientSolution(3).Bed),...
+	(md.results.TransientSolution(3).Base),...
 	(md.results.TransientSolution(3).Surface),...
 	(md.results.TransientSolution(3).Thickness),...
Index: /issm/trunk/test/NightlyRun/test316.py
===================================================================
--- /issm/trunk/test/NightlyRun/test316.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test316.py	(revision 17806)
@@ -23,5 +23,5 @@
 	md.results.TransientSolution[0].Vel,\
 	md.results.TransientSolution[0].Pressure,\
-	md.results.TransientSolution[0].Bed,\
+	md.results.TransientSolution[0].Base,\
 	md.results.TransientSolution[0].Surface,\
 	md.results.TransientSolution[0].Thickness,\
@@ -30,5 +30,5 @@
 	md.results.TransientSolution[1].Vel,\
 	md.results.TransientSolution[1].Pressure,\
-	md.results.TransientSolution[1].Bed,\
+	md.results.TransientSolution[1].Base,\
 	md.results.TransientSolution[1].Surface,\
 	md.results.TransientSolution[1].Thickness,\
@@ -37,5 +37,5 @@
 	md.results.TransientSolution[2].Vel,\
 	md.results.TransientSolution[2].Pressure,\
-	md.results.TransientSolution[2].Bed,\
+	md.results.TransientSolution[2].Base,\
 	md.results.TransientSolution[2].Surface,\
 	md.results.TransientSolution[2].Thickness,\
Index: /issm/trunk/test/NightlyRun/test317.m
===================================================================
--- /issm/trunk/test/NightlyRun/test317.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test317.m	(revision 17806)
@@ -20,5 +20,5 @@
 	(md.results.TransientSolution(1).Vel),...
 	(md.results.TransientSolution(1).Pressure),...
-	(md.results.TransientSolution(1).Bed),...
+	(md.results.TransientSolution(1).Base),...
 	(md.results.TransientSolution(1).Surface),...
 	(md.results.TransientSolution(1).Thickness),...
@@ -30,5 +30,5 @@
 	(md.results.TransientSolution(2).Vel),...
 	(md.results.TransientSolution(2).Pressure),...
-	(md.results.TransientSolution(2).Bed),...
+	(md.results.TransientSolution(2).Base),...
 	(md.results.TransientSolution(2).Surface),...
 	(md.results.TransientSolution(2).Thickness),...
@@ -40,5 +40,5 @@
 	(md.results.TransientSolution(3).Vel),...
 	(md.results.TransientSolution(3).Pressure),...
-	(md.results.TransientSolution(3).Bed),...
+	(md.results.TransientSolution(3).Base),...
 	(md.results.TransientSolution(3).Surface),...
 	(md.results.TransientSolution(3).Thickness),...
Index: /issm/trunk/test/NightlyRun/test317.py
===================================================================
--- /issm/trunk/test/NightlyRun/test317.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test317.py	(revision 17806)
@@ -29,5 +29,5 @@
 	md.results.TransientSolution[0].Vel,\
 	md.results.TransientSolution[0].Pressure,\
-	md.results.TransientSolution[0].Bed,\
+	md.results.TransientSolution[0].Base,\
 	md.results.TransientSolution[0].Surface,\
 	md.results.TransientSolution[0].Thickness,\
@@ -39,5 +39,5 @@
 	md.results.TransientSolution[1].Vel,\
 	md.results.TransientSolution[1].Pressure,\
-	md.results.TransientSolution[1].Bed,\
+	md.results.TransientSolution[1].Base,\
 	md.results.TransientSolution[1].Surface,\
 	md.results.TransientSolution[1].Thickness,\
@@ -49,5 +49,5 @@
 	md.results.TransientSolution[2].Vel,\
 	md.results.TransientSolution[2].Pressure,\
-	md.results.TransientSolution[2].Bed,\
+	md.results.TransientSolution[2].Base,\
 	md.results.TransientSolution[2].Surface,\
 	md.results.TransientSolution[2].Thickness,\
Index: /issm/trunk/test/NightlyRun/test318.m
===================================================================
--- /issm/trunk/test/NightlyRun/test318.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test318.m	(revision 17806)
@@ -10,5 +10,5 @@
 %Fields and tolerances to track changes
 field_names     ={'Vx','Vy','Vz','Vel','Pressure','Temperature','BasalforcingsMeltingRate'};
-field_tolerances={1e-13,1e-13,1.5e-10,1e-10,1e-13,1e-11,1e-6};
+field_tolerances={1e-13,1e-13,4e-10,1e-10,1e-13,1e-11,1e-6};
 field_values={...
 	(md.results.SteadystateSolution.Vx),...
Index: /issm/trunk/test/NightlyRun/test322.m
===================================================================
--- /issm/trunk/test/NightlyRun/test322.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test322.m	(revision 17806)
@@ -23,5 +23,5 @@
 %Fields and tolerances to track changes
 field_names     ={'Gradient','Misfits','FrictionCoefficient','Pressure','Vel','Vx','Vy'};
-field_tolerances={1e-06,1e-08,1e-09,1e-09,1e-09,1e-09,1e-09,1e-09,1e-09,1e-09};
+field_tolerances={1e-05,1e-08,1e-09,1e-09,1e-09,1e-09,1e-09,2e-09,2e-09,2e-09};
 field_values={...
 	(md.results.StressbalanceSolution.Gradient1),...
Index: /issm/trunk/test/NightlyRun/test322.py
===================================================================
--- /issm/trunk/test/NightlyRun/test322.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test322.py	(revision 17806)
@@ -35,5 +35,5 @@
 #Fields and tolerances to track changes
 field_names     =['Gradient','Misfits','FrictionCoefficient','Pressure','Vel','Vx','Vy']
-field_tolerances=[1e-06,1e-08,1e-09,1e-09,1e-09,1e-09,1e-09,1e-09,1e-09,1e-09]
+field_tolerances=[1e-05,1e-08,1e-09,1e-09,2e-09,2e-09,2e-09]
 field_values=[\
 	md.results.StressbalanceSolution.Gradient1,\
Index: /issm/trunk/test/NightlyRun/test323.m
===================================================================
--- /issm/trunk/test/NightlyRun/test323.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test323.m	(revision 17806)
@@ -16,5 +16,5 @@
 	(md.results.TransientSolution(1).Vel),...
 	(md.results.TransientSolution(1).Pressure),...
-	(md.results.TransientSolution(1).Bed),...
+	(md.results.TransientSolution(1).Base),...
 	(md.results.TransientSolution(1).Surface),...
 	(md.results.TransientSolution(1).Thickness),...
@@ -23,5 +23,5 @@
 	(md.results.TransientSolution(2).Vel),...
 	(md.results.TransientSolution(2).Pressure),...
-	(md.results.TransientSolution(2).Bed),...
+	(md.results.TransientSolution(2).Base),...
 	(md.results.TransientSolution(2).Surface),...
 	(md.results.TransientSolution(2).Thickness),...
@@ -30,5 +30,5 @@
 	(md.results.TransientSolution(3).Vel),...
 	(md.results.TransientSolution(3).Pressure),...
-	(md.results.TransientSolution(3).Bed),...
+	(md.results.TransientSolution(3).Base),...
 	(md.results.TransientSolution(3).Surface),...
 	(md.results.TransientSolution(3).Thickness),...
Index: /issm/trunk/test/NightlyRun/test323.py
===================================================================
--- /issm/trunk/test/NightlyRun/test323.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test323.py	(revision 17806)
@@ -26,5 +26,5 @@
 	md.results.TransientSolution[0].Vel,\
 	md.results.TransientSolution[0].Pressure,\
-	md.results.TransientSolution[0].Bed,\
+	md.results.TransientSolution[0].Base,\
 	md.results.TransientSolution[0].Surface,\
 	md.results.TransientSolution[0].Thickness,\
@@ -33,5 +33,5 @@
 	md.results.TransientSolution[1].Vel,\
 	md.results.TransientSolution[1].Pressure,\
-	md.results.TransientSolution[1].Bed,\
+	md.results.TransientSolution[1].Base,\
 	md.results.TransientSolution[1].Surface,\
 	md.results.TransientSolution[1].Thickness,\
@@ -40,5 +40,5 @@
 	md.results.TransientSolution[2].Vel,\
 	md.results.TransientSolution[2].Pressure,\
-	md.results.TransientSolution[2].Bed,\
+	md.results.TransientSolution[2].Base,\
 	md.results.TransientSolution[2].Surface,\
 	md.results.TransientSolution[2].Thickness,\
Index: /issm/trunk/test/NightlyRun/test324.m
===================================================================
--- /issm/trunk/test/NightlyRun/test324.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test324.m	(revision 17806)
@@ -14,6 +14,6 @@
 	%'Vx3','Vy3','Vz3','Vel3','Pressure3','Bed3','Surface3','Thickness3','Temperature3','BasalforcingsMeltingRate3'};
 field_tolerances={1e-13,  1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,...,
-	5*1e-11,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,...
-	1e-10,  1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13};
+	5*1e-11,1e-13,1.5e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13};
+	%1e-10,  1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13};
 field_values={...
 	(md.results.TransientSolution(1).Vx),...
@@ -22,5 +22,5 @@
 	(md.results.TransientSolution(1).Vel),...
 	(md.results.TransientSolution(1).Pressure),...
-	(md.results.TransientSolution(1).Bed),...
+	(md.results.TransientSolution(1).Base),...
 	(md.results.TransientSolution(1).Surface),...
 	(md.results.TransientSolution(1).Thickness),...
@@ -32,5 +32,5 @@
 	(md.results.TransientSolution(2).Vel),...
 	(md.results.TransientSolution(2).Pressure),...
-	(md.results.TransientSolution(2).Bed),...
+	(md.results.TransientSolution(2).Base),...
 	(md.results.TransientSolution(2).Surface),...
 	(md.results.TransientSolution(2).Thickness),...
@@ -42,5 +42,5 @@
 %	(md.results.TransientSolution(3).Vel),...
 %	(md.results.TransientSolution(3).Pressure),...
-%	(md.results.TransientSolution(3).Bed),...
+%	(md.results.TransientSolution(3).Base),...
 %	(md.results.TransientSolution(3).Surface),...
 %	(md.results.TransientSolution(3).Thickness),...
Index: /issm/trunk/test/NightlyRun/test324.py
===================================================================
--- /issm/trunk/test/NightlyRun/test324.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test324.py	(revision 17806)
@@ -32,5 +32,5 @@
 	md.results.TransientSolution[0].Vel,\
 	md.results.TransientSolution[0].Pressure,\
-	md.results.TransientSolution[0].Bed,\
+	md.results.TransientSolution[0].Base,\
 	md.results.TransientSolution[0].Surface,\
 	md.results.TransientSolution[0].Thickness,\
@@ -42,5 +42,5 @@
 	md.results.TransientSolution[1].Vel,\
 	md.results.TransientSolution[1].Pressure,\
-	md.results.TransientSolution[1].Bed,\
+	md.results.TransientSolution[1].Base,\
 	md.results.TransientSolution[1].Surface,\
 	md.results.TransientSolution[1].Thickness,\
@@ -52,5 +52,5 @@
 #	md.results.TransientSolution[2].Vel,\
 #	md.results.TransientSolution[2].Pressure,\
-#	md.results.TransientSolution[2].Bed,\
+#	md.results.TransientSolution[2].Base,\
 #	md.results.TransientSolution[2].Surface,\
 #	md.results.TransientSolution[2].Thickness,\
Index: /issm/trunk/test/NightlyRun/test325.m
===================================================================
--- /issm/trunk/test/NightlyRun/test325.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test325.m	(revision 17806)
@@ -15,5 +15,5 @@
 %Fields and tolerances to track changes
 field_names     ={'Enthalpy','Waterfraction','Temperature'};
-field_tolerances={1e-13,1e-13,1e-13};
+field_tolerances={1e-13,5e-13,1e-13};
 field_values={...
 	(md.results.ThermalSolution.Enthalpy),...
Index: /issm/trunk/test/NightlyRun/test325.py
===================================================================
--- /issm/trunk/test/NightlyRun/test325.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test325.py	(revision 17806)
@@ -25,5 +25,5 @@
 #Fields and tolerances to track changes
 field_names     =['Enthalpy','Waterfraction','Temperature']
-field_tolerances=[1e-13,1e-13,1e-13]
+field_tolerances=[1e-13,5e-13,1e-13]
 field_values=[\
 	md.results.ThermalSolution.Enthalpy,\
Index: /issm/trunk/test/NightlyRun/test327.m
===================================================================
--- /issm/trunk/test/NightlyRun/test327.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test327.m	(revision 17806)
@@ -29,5 +29,5 @@
 	(md.results.TransientSolution(1).Vel),...
 	(md.results.TransientSolution(1).Pressure),...
-	(md.results.TransientSolution(1).Bed),...
+	(md.results.TransientSolution(1).Base),...
 	(md.results.TransientSolution(1).Surface),...
 	(md.results.TransientSolution(1).Thickness),...
@@ -40,5 +40,5 @@
 	(md.results.TransientSolution(2).Vel),...
 	(md.results.TransientSolution(2).Pressure),...
-	(md.results.TransientSolution(2).Bed),...
+	(md.results.TransientSolution(2).Base),...
 	(md.results.TransientSolution(2).Surface),...
 	(md.results.TransientSolution(2).Thickness),...
@@ -51,5 +51,5 @@
 	(md.results.TransientSolution(3).Vel),...
 	(md.results.TransientSolution(3).Pressure),...
-	(md.results.TransientSolution(3).Bed),...
+	(md.results.TransientSolution(3).Base),...
 	(md.results.TransientSolution(3).Surface),...
 	(md.results.TransientSolution(3).Thickness),...
Index: /issm/trunk/test/NightlyRun/test327.py
===================================================================
--- /issm/trunk/test/NightlyRun/test327.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test327.py	(revision 17806)
@@ -37,5 +37,5 @@
 	md.results.TransientSolution[0].Vel,\
 	md.results.TransientSolution[0].Pressure,\
-	md.results.TransientSolution[0].Bed,\
+	md.results.TransientSolution[0].Base,\
 	md.results.TransientSolution[0].Surface,\
 	md.results.TransientSolution[0].Thickness,\
@@ -48,5 +48,5 @@
 	md.results.TransientSolution[1].Vel,\
 	md.results.TransientSolution[1].Pressure,\
-	md.results.TransientSolution[1].Bed,\
+	md.results.TransientSolution[1].Base,\
 	md.results.TransientSolution[1].Surface,\
 	md.results.TransientSolution[1].Thickness,\
@@ -59,5 +59,5 @@
 	md.results.TransientSolution[2].Vel,\
 	md.results.TransientSolution[2].Pressure,\
-	md.results.TransientSolution[2].Bed,\
+	md.results.TransientSolution[2].Base,\
 	md.results.TransientSolution[2].Surface,\
 	md.results.TransientSolution[2].Thickness,\
Index: /issm/trunk/test/NightlyRun/test328.m
===================================================================
--- /issm/trunk/test/NightlyRun/test328.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test328.m	(revision 17806)
@@ -3,5 +3,5 @@
 md=parameterize(md,'../Par/SquareSheetConstrained.par');
 md=setflowequation(md,'SSA','all');
-md.surfaceforcings.issmbgradients=1;
+md.surfaceforcings = SMBgradients();
 md.surfaceforcings.b_pos=-100. + 0.00005*md.mesh.x - 0.0001*md.mesh.y;
 md.surfaceforcings.b_neg=250. + 0.000051*md.mesh.x - 0.00011*md.mesh.y;
@@ -14,10 +14,10 @@
 %Fields and tolerances to track changes
 field_names     ={'Vx1','Vy1','Vel1','Bed1','Surface1','Thickness1','SMB1','TotalSmb1','Vx2','Vy2','Vel2','Bed2','Surface2','Thickness2','SMB2','TotalSmb2','Vx3','Vy3','Vel3','Bed3','Surface3','Thickness3','SMB3','TotalSmb3'};
-field_tolerances={1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13};
+field_tolerances={1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1.5e-13,1e-13};
 field_values={...
 	(md.results.TransientSolution(1).Vx),...
 	(md.results.TransientSolution(1).Vy),...
 	(md.results.TransientSolution(1).Vel),...
-	(md.results.TransientSolution(1).Bed),...
+	(md.results.TransientSolution(1).Base),...
 	(md.results.TransientSolution(1).Surface),...
 	(md.results.TransientSolution(1).Thickness),...
@@ -27,5 +27,5 @@
 	(md.results.TransientSolution(2).Vy),...
 	(md.results.TransientSolution(2).Vel),...
-	(md.results.TransientSolution(2).Bed),...
+	(md.results.TransientSolution(2).Base),...
 	(md.results.TransientSolution(2).Surface),...
 	(md.results.TransientSolution(2).Thickness),...
@@ -35,5 +35,5 @@
 	(md.results.TransientSolution(3).Vy),...
 	(md.results.TransientSolution(3).Vel),...
-	(md.results.TransientSolution(3).Bed),...
+	(md.results.TransientSolution(3).Base),...
 	(md.results.TransientSolution(3).Surface),...
 	(md.results.TransientSolution(3).Thickness),...
Index: /issm/trunk/test/NightlyRun/test328.py
===================================================================
--- /issm/trunk/test/NightlyRun/test328.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test328.py	(revision 17806)
@@ -14,5 +14,5 @@
 md=parameterize(md,'../Par/SquareSheetConstrained.py')
 md=setflowequation(md,'SSA','all')
-md.surfaceforcings.issmbgradients=1
+md.surfaceforcings = SMBgradients();
 md.surfaceforcings.b_pos=-100. + 0.00005*md.mesh.x - 0.0001*md.mesh.y
 md.surfaceforcings.b_neg=250. + 0.000051*md.mesh.x - 0.00011*md.mesh.y
@@ -30,5 +30,5 @@
 	md.results.TransientSolution[0].Vy,\
 	md.results.TransientSolution[0].Vel,\
-	md.results.TransientSolution[0].Bed,\
+	md.results.TransientSolution[0].Base,\
 	md.results.TransientSolution[0].Surface,\
 	md.results.TransientSolution[0].Thickness,\
@@ -38,5 +38,5 @@
 	md.results.TransientSolution[1].Vy,\
 	md.results.TransientSolution[1].Vel,\
-	md.results.TransientSolution[1].Bed,\
+	md.results.TransientSolution[1].Base,\
 	md.results.TransientSolution[1].Surface,\
 	md.results.TransientSolution[1].Thickness,\
@@ -46,5 +46,5 @@
 	md.results.TransientSolution[2].Vy,\
 	md.results.TransientSolution[2].Vel,\
-	md.results.TransientSolution[2].Bed,\
+	md.results.TransientSolution[2].Base,\
 	md.results.TransientSolution[2].Surface,\
 	md.results.TransientSolution[2].Thickness,\
Index: /issm/trunk/test/NightlyRun/test329.m
===================================================================
--- /issm/trunk/test/NightlyRun/test329.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test329.m	(revision 17806)
@@ -4,5 +4,5 @@
 md=extrude(md,3,1.);
 md=setflowequation(md,'HO','all');
-md.surfaceforcings.issmbgradients=1;
+md.surfaceforcings = SMBgradients();
 md.surfaceforcings.b_pos=-100. + 0.00005*md.mesh.x - 0.0001*md.mesh.y;
 md.surfaceforcings.b_neg=250. + 0.000051*md.mesh.x - 0.00011*md.mesh.y;
@@ -23,5 +23,5 @@
 	(md.results.TransientSolution(1).Vz),...
 	(md.results.TransientSolution(1).Vel),...
-	(md.results.TransientSolution(1).Bed),...
+	(md.results.TransientSolution(1).Base),...
 	(md.results.TransientSolution(1).Surface),...
 	(md.results.TransientSolution(1).Thickness),...
@@ -33,5 +33,5 @@
 	(md.results.TransientSolution(2).Vz),...
 	(md.results.TransientSolution(2).Vel),...
-	(md.results.TransientSolution(2).Bed),...
+	(md.results.TransientSolution(2).Base),...
 	(md.results.TransientSolution(2).Surface),...
 	(md.results.TransientSolution(2).Thickness),...
@@ -43,5 +43,5 @@
 	(md.results.TransientSolution(3).Vz),...
 	(md.results.TransientSolution(3).Vel),...
-	(md.results.TransientSolution(3).Bed),...
+	(md.results.TransientSolution(3).Base),...
 	(md.results.TransientSolution(3).Surface),...
 	(md.results.TransientSolution(3).Thickness),...
Index: /issm/trunk/test/NightlyRun/test329.py
===================================================================
--- /issm/trunk/test/NightlyRun/test329.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test329.py	(revision 17806)
@@ -15,5 +15,5 @@
 md.extrude(3,1)
 md=setflowequation(md,'HO','all')
-md.surfaceforcings.issmbgradients=1
+md.surfaceforcings = SMBgradients();
 md.surfaceforcings.b_pos=-100. + 0.00005*md.mesh.x - 0.0001*md.mesh.y
 md.surfaceforcings.b_neg=250. + 0.000051*md.mesh.x - 0.00011*md.mesh.y
@@ -34,5 +34,5 @@
 	md.results.TransientSolution[0].Vz,\
 	md.results.TransientSolution[0].Vel,\
-	md.results.TransientSolution[0].Bed,\
+	md.results.TransientSolution[0].Base,\
 	md.results.TransientSolution[0].Surface,\
 	md.results.TransientSolution[0].Thickness,\
@@ -44,5 +44,5 @@
 	md.results.TransientSolution[1].Vz,\
 	md.results.TransientSolution[1].Vel,\
-	md.results.TransientSolution[1].Bed,\
+	md.results.TransientSolution[1].Base,\
 	md.results.TransientSolution[1].Surface,\
 	md.results.TransientSolution[1].Thickness,\
@@ -54,5 +54,5 @@
 	md.results.TransientSolution[2].Vz,\
 	md.results.TransientSolution[2].Vel,\
-	md.results.TransientSolution[2].Bed,\
+	md.results.TransientSolution[2].Base,\
 	md.results.TransientSolution[2].Surface,\
 	md.results.TransientSolution[2].Thickness,\
Index: /issm/trunk/test/NightlyRun/test3300.m
===================================================================
--- /issm/trunk/test/NightlyRun/test3300.m	(revision 17806)
+++ /issm/trunk/test/NightlyRun/test3300.m	(revision 17806)
@@ -0,0 +1,57 @@
+md=triangle(model(),'../Exp/Square.exp',100000.);
+md=setmask(md,'','');
+md=parameterize(md,'../Par/SquareSheetConstrained.par');
+md.transient=deactivateall(md.transient);
+md.transient.ishydrology=1;
+md=setflowequation(md,'SSA','all');
+md.cluster=generic('name',oshostname(),'np',1);
+md.hydrology=(hydrologydc);
+md.hydrology=initialize(md.hydrology,md);
+md.hydrology.isefficientlayer=1;
+md.hydrology.sedimentlimit_flag=1;
+md.hydrology.sedimentlimit=400.0;
+md.hydrology.sediment_thickness=20.0;
+md.initialization.sediment_head=0.0*ones(md.mesh.numberofvertices,1);
+md.hydrology.spcsediment_head=NaN*ones(md.mesh.numberofvertices,1);
+md.basalforcings.melting_rate = 2.0*ones(md.mesh.numberofvertices,1);
+md.hydrology.sediment_transmitivity=1.5e-4*ones(md.mesh.numberofvertices,1);
+
+md.initialization.epl_head=0.0*ones(md.mesh.numberofvertices,1);
+md.initialization.epl_thickness=1.0*ones(md.mesh.numberofvertices,1);
+md.hydrology.spcepl_head=NaN*ones(md.mesh.numberofvertices,1);
+md.hydrology.mask_eplactive_node=0*ones(md.mesh.numberofvertices,1);
+
+md.hydrology.epl_conductivity=1.5e-2;
+md.hydrology.epl_initial_thickness=1.0;
+md.hydrology.epl_max_thickness=5.0;
+
+md.hydrology.transfer_flag=1;
+md.hydrology.leakage_factor=500;
+
+times=0:0.2:8.0;
+md.basalforcings.melting_rate=ones(md.mesh.numberofvertices+1,length(times));
+
+for i=1:length(times)
+	if(times(i)<1.2)
+		md.basalforcings.melting_rate(:,i)=1.0;
+	elseif(times(i)<6.0)
+		md.basalforcings.melting_rate(:,i)=-0.2;
+	else
+		md.basalforcings.melting_rate(:,i)=0.0;
+ end
+end	
+
+md.basalforcings.melting_rate(end,:)=times;
+
+
+md.timestepping.time_step=0.2;
+md.timestepping.final_time=8.0;
+
+md=solve(md,TransientSolutionEnum());
+
+field_names     ={'SedimentWaterHead5','EplWaterHead5','SedimentWaterHead40','EplWaterHead40'};
+field_tolerances={1e-13, 1e-13, 1e-13, 1e-13, 1e-13};
+field_values={md.results.TransientSolution(5).SedimentHead, ...
+							md.results.TransientSolution(5).EplHead,...
+							md.results.TransientSolution(40).SedimentHead,...
+							md.results.TransientSolution(40).EplHead};
Index: sm/trunk/test/NightlyRun/test331.m
===================================================================
--- /issm/trunk/test/NightlyRun/test331.m	(revision 17805)
+++ 	(revision )
@@ -1,25 +1,0 @@
-md=triangle(model(),'../Exp/Square.exp',150000.);
-md=setmask(md,'','');
-md=parameterize(md,'../Par/SquareSheetConstrained.par');
-md=setflowequation(md,'SSA','all');
-md.cluster=generic('name',oshostname(),'np',3);
-md.initialization.watercolumn=10^-3*ones(md.mesh.numberofvertices,1);
-md.hydrology.spcwatercolumn=NaN*ones(md.mesh.numberofvertices,1);
-pos=find(md.mesh.y==0 | md.mesh.x==0);
-md.hydrology.spcwatercolumn(pos)=2*10^-3;
-md=solve(md,HydrologySolutionEnum());
-
-%Fields and tolerances to track changes
-field_names     ={'HydrologyWaterVx1','HydrologyWaterVy1','WaterColumn1', 'HydrologyWaterVx2','HydrologyWaterVy2','WaterColumn2', 'HydrologyWaterVx3','HydrologyWaterVy3','WaterColumn3'};
-field_tolerances={1e-09,1e-01,1e-09, 1e-09,1e-01,1e-09, 1e-09,1e-01,1e-09};
-field_values={...
-	(md.results.HydrologySolution(1).HydrologyWaterVx),...
-	(md.results.HydrologySolution(1).HydrologyWaterVy),...
-	(md.results.HydrologySolution(1).Watercolumn),...
-	(md.results.HydrologySolution(2).HydrologyWaterVx),...
-	(md.results.HydrologySolution(2).HydrologyWaterVy),...
-	(md.results.HydrologySolution(2).Watercolumn),...
-	(md.results.HydrologySolution(3).HydrologyWaterVx),...
-	(md.results.HydrologySolution(3).HydrologyWaterVy),...
-	(md.results.HydrologySolution(3).Watercolumn),...
-	};
Index: sm/trunk/test/NightlyRun/test331.py
===================================================================
--- /issm/trunk/test/NightlyRun/test331.py	(revision 17805)
+++ 	(revision )
@@ -1,36 +1,0 @@
-import numpy
-import copy
-from model import *
-from triangle import *
-from setmask import *
-from parameterize import *
-from setflowequation import *
-from EnumDefinitions import *
-from solve import *
-from MatlabFuncs import *
-
-md=triangle(model(),'../Exp/Square.exp',150000.)
-md=setmask(md,'','')
-md=parameterize(md,'../Par/SquareSheetConstrained.py')
-md=setflowequation(md,'SSA','all')
-md.cluster=generic('name',oshostname(),'np',3)
-md.initialization.watercolumn=1e-3*numpy.ones((md.mesh.numberofvertices,1))
-md.hydrology.spcwatercolumn=float('nan')*numpy.ones((md.mesh.numberofvertices,1))
-pos=numpy.nonzero(numpy.logical_or(md.mesh.y==0.,md.mesh.x==0.))[0]
-md.hydrology.spcwatercolumn[pos]=2e-3
-md=solve(md,HydrologySolutionEnum())
-
-#Fields and tolerances to track changes
-field_names     =['HydrologyWaterVx1','HydrologyWaterVy1','WaterColumn1','HydrologyWaterVx2','HydrologyWaterVy2','WaterColumn2','HydrologyWaterVx3','HydrologyWaterVy3','WaterColumn3']
-field_tolerances=[1e-09,1e-01,1e-09,1e-09,1e-01,1e-09,1e-09,1e-01,1e-09]
-field_values=[\
-	md.results.HydrologySolution[0].HydrologyWaterVx,\
-	md.results.HydrologySolution[0].HydrologyWaterVy,\
-	md.results.HydrologySolution[0].Watercolumn,\
-	md.results.HydrologySolution[1].HydrologyWaterVx,\
-	md.results.HydrologySolution[1].HydrologyWaterVy,\
-	md.results.HydrologySolution[1].Watercolumn,\
-	md.results.HydrologySolution[2].HydrologyWaterVx,\
-	md.results.HydrologySolution[2].HydrologyWaterVy,\
-	md.results.HydrologySolution[2].Watercolumn,\
-	]
Index: /issm/trunk/test/NightlyRun/test332.m
===================================================================
--- /issm/trunk/test/NightlyRun/test332.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test332.m	(revision 17806)
@@ -2,7 +2,10 @@
 md=setmask(md,'','');
 md=parameterize(md,'../Par/SquareSheetConstrained.par');
+md.transient=deactivateall(md.transient);
+md.transient.ishydrology=1;
 md=setflowequation(md,'SSA','all');
 md.cluster=generic('name',oshostname(),'np',1);
 md.hydrology=(hydrologydc);
+md.hydrology=initialize(md.hydrology,md);
 md.hydrology.isefficientlayer=0;
 md.hydrology.sedimentlimit_flag=1;
@@ -13,5 +16,5 @@
 md.hydrology.spcsediment_head(pos)=0.0;
 md.basalforcings.melting_rate = 2.0*ones(md.mesh.numberofvertices,1);
-md.hydrology.sediment_transmitivity=3;
+md.hydrology.sediment_transmitivity=3*ones(md.mesh.numberofvertices,1);
 md.timestepping.time_step=0;
 md.timestepping.final_time=1.0;
@@ -23,4 +26,4 @@
 %analitic=(md.mesh.y.^2-2*md.mesh.y*1.0e6)*(-2.0/(2*md.constants.yts*md.hydrology.sediment_transmitivity))
 field_names     ={'SedimentWaterHead','SedimentHeadResidual'};
-field_tolerances={1e-13, 2.5e-10};
+field_tolerances={1e-13, 3e-10};
 field_values={md.results.HydrologySolution.SedimentHead,md.results.HydrologySolution.SedimentHeadResidual};
Index: /issm/trunk/test/NightlyRun/test333.m
===================================================================
--- /issm/trunk/test/NightlyRun/test333.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test333.m	(revision 17806)
@@ -2,7 +2,10 @@
 md=setmask(md,'','');
 md=parameterize(md,'../Par/SquareSheetConstrained.par');
+md.transient=deactivateall(md.transient);
+md.transient.ishydrology=1;
 md=setflowequation(md,'SSA','all');
 md.cluster=generic('name',oshostname(),'np',1);
 md.hydrology=(hydrologydc);
+md.hydrology=initialize(md.hydrology,md);
 md.hydrology.isefficientlayer=1;
 md.hydrology.sedimentlimit_flag=1;
@@ -11,12 +14,14 @@
 md.hydrology.spcsediment_head=NaN*ones(md.mesh.numberofvertices,1);
 md.basalforcings.melting_rate = 2.0*ones(md.mesh.numberofvertices,1);
-md.hydrology.sediment_transmitivity=3;
+md.hydrology.sediment_transmitivity=3*ones(md.mesh.numberofvertices,1);
 
 md.initialization.epl_head=0.0*ones(md.mesh.numberofvertices,1);
+md.initialization.epl_thickness=1.0*ones(md.mesh.numberofvertices,1);
 md.hydrology.spcepl_head=NaN*ones(md.mesh.numberofvertices,1);
-md.hydrology.mask_eplactive=0*ones(md.mesh.numberofvertices,1);
+md.hydrology.mask_eplactive_node=0*ones(md.mesh.numberofvertices,1);
 md.basalforcings.melting_rate = 2.0*ones(md.mesh.numberofvertices,1);
-md.hydrology.epl_transmitivity=30;
-md.hydrology.epl_thickness=1;
+md.hydrology.epl_conductivity=30;
+md.hydrology.epl_initial_thickness=1;
+md.hydrology.epl_max_thickness=1;
 md.timestepping.time_step=0.2;
 md.timestepping.final_time=2.0;
@@ -24,39 +29,33 @@
 %md.verbose.solution=1;
 
-md=solve(md,HydrologySolutionEnum());
+md=solve(md,TransientSolutionEnum());
 
-%store=md.constants.g*md.hydrology.sediment_porosity* ...
-%			md.materials.rho_freshwater*((md.hydrology.sediment_compressibility/md.hydrology.sediment_porosity)+md.hydrology.water_compressibility)
-
-%sed=ones(1,size(md.results.HydrologySolution,2));
-%epl=ones(1,size(md.results.HydrologySolution,2));
-%res=ones(1,size(md.results.HydrologySolution,2));
-%input=ones(1,size(md.results.HydrologySolution,2));
-%for i= 1:size(md.results.HydrologySolution,2)
-%	sed(i)=mean(md.results.HydrologySolution(i).SedimentHead);
-%	res(i)=mean(md.results.HydrologySolution(i).SedimentHeadResidual);
-%	epl(i)=mean(md.results.HydrologySolution(i).EplHead);
-%	input(i)=2.0*(i*0.2);
+%store=md.constants.g*md.hydrology.sediment_porosity*md.materials.rho_freshwater*((md.hydrology.sediment_compressibility/md.hydrology.sediment_porosity)+md.hydrology.water_compressibility);
+%sedstore=20.0*store;
+%for i=1:10
+%diff=(mean(md.results.HydrologySolution(i).EplHead)*store+ ...
+%			mean(md.results.HydrologySolution(i).SedimentHead)*sedstore-0.4*i)
 %end
 
 %Fields and tolerances to track changes
 field_names     ={'SedimentWaterHead1','EplWaterHead1','SedimentHeadResidual1',...
-								 'SedimentWaterHead4','EplWaterHead4','SedimentHeadResidual4',...
-								 'SedimentWaterHead5','EplWaterHead5','SedimentHeadResidual5',...
-								 'SedimentWaterHead9','EplWaterHead9','SedimentHeadResidual9'};
-field_tolerances={1e-13, 1e-13, 1e-13,...
-								 1e-13, 1e-13, 1e-13,...
-								 1e-13, 1e-13, 1e-13,...
-								 1e-13, 1e-13, 1e-13};
-field_values={md.results.HydrologySolution(1).SedimentHead, ...
-							md.results.HydrologySolution(1).EplHead,...
-							md.results.HydrologySolution(1).SedimentHeadResidual,...
-							md.results.HydrologySolution(4).SedimentHead,...
-							md.results.HydrologySolution(4).EplHead,...
-							md.results.HydrologySolution(4).SedimentHeadResidual, ...
-							md.results.HydrologySolution(5).SedimentHead,...
-							md.results.HydrologySolution(5).EplHead,...
-							md.results.HydrologySolution(5).SedimentHeadResidual, ...
-							md.results.HydrologySolution(9).SedimentHead,...
-							md.results.HydrologySolution(9).EplHead,...
-							md.results.HydrologySolution(9).SedimentHeadResidual};
+						'SedimentWaterHead4','EplWaterHead4','SedimentHeadResidual4',...
+						'SedimentWaterHead5','EplWaterHead5','SedimentHeadResidual5',...
+						'SedimentWaterHead9','EplWaterHead9','SedimentHeadResidual9'};
+field_tolerances={...
+	1e-13, 1e-13, 1e-13,...
+	1e-13, 1e-13, 1e-13,...
+	1e-13, 5e-12, 8e-12,...
+	1e-13, 5e-12, 1e-11};
+field_values={md.results.TransientSolution(1).SedimentHead, ...
+							md.results.TransientSolution(1).EplHead,...
+							md.results.TransientSolution(1).SedimentHeadResidual,...
+							md.results.TransientSolution(4).SedimentHead,...
+							md.results.TransientSolution(4).EplHead,...
+							md.results.TransientSolution(4).SedimentHeadResidual, ...
+							md.results.TransientSolution(5).SedimentHead,...
+							md.results.TransientSolution(5).EplHead,...
+							md.results.TransientSolution(5).SedimentHeadResidual, ...
+							md.results.TransientSolution(9).SedimentHead,...
+							md.results.TransientSolution(9).EplHead,...
+							md.results.TransientSolution(9).SedimentHeadResidual};
Index: /issm/trunk/test/NightlyRun/test334.m
===================================================================
--- /issm/trunk/test/NightlyRun/test334.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test334.m	(revision 17806)
@@ -1,8 +1,11 @@
 md=triangle(model(),'../Exp/Square.exp',100000.);
 md=setmask(md,'','');
+md.transient=deactivateall(md.transient);
+md.transient.ishydrology=1;
 md=parameterize(md,'../Par/SquareSheetConstrained.par');
 md=setflowequation(md,'SSA','all');
 md.cluster=generic('name',oshostname(),'np',1);
 md.hydrology=(hydrologydc);
+md.hydrology=initialize(md.hydrology,md);
 md.hydrology.isefficientlayer=0;
 md.hydrology.sedimentlimit_flag=1;
@@ -13,5 +16,5 @@
 md.hydrology.spcsediment_head(pos)=0.0;
 md.basalforcings.melting_rate = 2.0*ones(md.mesh.numberofvertices,1);
-md.hydrology.sediment_transmitivity=3;
+md.hydrology.sediment_transmitivity= 3.0*ones(md.mesh.numberofvertices,1);
 md.timestepping.time_step=0;
 md.timestepping.final_time=1.0;
@@ -25,4 +28,4 @@
 %analitic=(md.mesh.y.^2-2*md.mesh.y*1.0e6)*(-2.0/(2*md.constants.yts*md.hydrology.sediment_transmitivity))
 field_names     ={'SedimentWaterHead','SedimentHeadResidual'};
-field_tolerances={1e-13, 2.5e-10};
-field_values={md.results.HydrologySolution.SedimentHead,md.results.HydrologySolution.SedimentHeadResidual}
+field_tolerances={1e-13, 3e-10};
+field_values={md.results.HydrologySolution.SedimentHead,md.results.HydrologySolution.SedimentHeadResidual};
Index: /issm/trunk/test/NightlyRun/test335.m
===================================================================
--- /issm/trunk/test/NightlyRun/test335.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test335.m	(revision 17806)
@@ -1,8 +1,11 @@
 md=triangle(model(),'../Exp/Square.exp',100000.);
 md=setmask(md,'','');
+md.transient=deactivateall(md.transient);
+md.transient.ishydrology=1;
 md=parameterize(md,'../Par/SquareSheetConstrained.par');
 md=setflowequation(md,'SSA','all');
 md.cluster=generic('name',oshostname(),'np',1);
 md.hydrology=(hydrologydc);
+md.hydrology=initialize(md.hydrology,md);
 md.hydrology.isefficientlayer=1;
 md.hydrology.sedimentlimit_flag=1;
@@ -11,12 +14,14 @@
 md.hydrology.spcsediment_head=NaN*ones(md.mesh.numberofvertices,1);
 md.basalforcings.melting_rate = 2.0*ones(md.mesh.numberofvertices,1);
-md.hydrology.sediment_transmitivity=3;
+md.hydrology.sediment_transmitivity=3*ones(md.mesh.numberofvertices,1);
 
 md.initialization.epl_head=0.0*ones(md.mesh.numberofvertices,1);
+md.initialization.epl_thickness=1.0*ones(md.mesh.numberofvertices,1);
 md.hydrology.spcepl_head=NaN*ones(md.mesh.numberofvertices,1);
-md.hydrology.mask_eplactive=0*ones(md.mesh.numberofvertices,1);
+md.hydrology.mask_eplactive_node=0*ones(md.mesh.numberofvertices,1);
 md.basalforcings.melting_rate = 2.0*ones(md.mesh.numberofvertices,1);
-md.hydrology.epl_transmitivity=30;
-md.hydrology.epl_thickness=1;
+md.hydrology.epl_conductivity=30;
+md.hydrology.epl_initial_thickness=1;
+md.hydrology.epl_max_thickness=1;
 md.timestepping.time_step=0.2;
 md.timestepping.final_time=2.0;
@@ -24,5 +29,5 @@
 %md.verbose.solution=1;
 md=extrude(md,3,1.1);
-md=solve(md,HydrologySolutionEnum());
+md=solve(md,TransientSolutionEnum());
 
 %store=md.constants.g*md.hydrology.sediment_porosity* ...
@@ -42,21 +47,21 @@
 %Fields and tolerances to track changes
 field_names     ={'SedimentWaterHead1','EplWaterHead1','SedimentHeadResidual1',...
-								 'SedimentWaterHead4','EplWaterHead4','SedimentHeadResidual4',...
-								 'SedimentWaterHead5','EplWaterHead5','SedimentHeadResidual5',...
-								 'SedimentWaterHead9','EplWaterHead9','SedimentHeadResidual9'};
+						'SedimentWaterHead4','EplWaterHead4','SedimentHeadResidual4',...
+						'SedimentWaterHead5','EplWaterHead5','SedimentHeadResidual5',...
+						'SedimentWaterHead9','EplWaterHead9','SedimentHeadResidual9'};
 field_tolerances={1e-13, 1e-13, 1e-13,...
-								 1e-13, 1e-13, 1e-13,...
-								 1e-13, 1e-13, 1e-13,...
-								 1e-13, 1e-13, 1e-13};
-field_values={md.results.HydrologySolution(1).SedimentHead, ...
-							md.results.HydrologySolution(1).EplHead,...
-							md.results.HydrologySolution(1).SedimentHeadResidual,...
-							md.results.HydrologySolution(4).SedimentHead,...
-							md.results.HydrologySolution(4).EplHead,...
-							md.results.HydrologySolution(4).SedimentHeadResidual, ...
-							md.results.HydrologySolution(5).SedimentHead,...
-							md.results.HydrologySolution(5).EplHead,...
-							md.results.HydrologySolution(5).SedimentHeadResidual, ...
-							md.results.HydrologySolution(9).SedimentHead,...
-							md.results.HydrologySolution(9).EplHead,...
-							md.results.HydrologySolution(9).SedimentHeadResidual};
+						1e-13, 1e-13, 1e-13,...
+						1e-13, 5e-12, 9e-12,...
+						1e-13, 5e-12, 1e-11};
+field_values={md.results.TransientSolution(1).SedimentHead, ...
+							md.results.TransientSolution(1).EplHead,...
+							md.results.TransientSolution(1).SedimentHeadResidual,...
+							md.results.TransientSolution(4).SedimentHead,...
+							md.results.TransientSolution(4).EplHead,...
+							md.results.TransientSolution(4).SedimentHeadResidual, ...
+							md.results.TransientSolution(5).SedimentHead,...
+							md.results.TransientSolution(5).EplHead,...
+							md.results.TransientSolution(5).SedimentHeadResidual, ...
+							md.results.TransientSolution(9).SedimentHead,...
+							md.results.TransientSolution(9).EplHead,...
+							md.results.TransientSolution(9).SedimentHeadResidual};
Index: /issm/trunk/test/NightlyRun/test403.m
===================================================================
--- /issm/trunk/test/NightlyRun/test403.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test403.m	(revision 17806)
@@ -9,5 +9,5 @@
 %Fields and tolerances to track changes
 field_names     ={'Vx','Vy','Vz','Vel','Pressure'};
-field_tolerances={1e-09,1e-09,1e-09,1e-09,1e-09};
+field_tolerances={2e-09,1e-09,1e-09,1e-09,1e-09};
 field_values={...
 	(md.results.StressbalanceSolution.Vx),...
Index: /issm/trunk/test/NightlyRun/test404.m
===================================================================
--- /issm/trunk/test/NightlyRun/test404.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test404.m	(revision 17806)
@@ -9,5 +9,5 @@
 %Fields and tolerances to track changes
 field_names     ={'Vx','Vy','Vz','Vel','Pressure'};
-field_tolerances={1.5e-07,1e-07,1e-06,1e-07,1e-07};
+field_tolerances={2e-07,2e-07,2e-06,1e-06,1e-07};
 field_values={...
 	(md.results.StressbalanceSolution.Vx),...
Index: /issm/trunk/test/NightlyRun/test404.py
===================================================================
--- /issm/trunk/test/NightlyRun/test404.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test404.py	(revision 17806)
@@ -19,5 +19,5 @@
 #Fields and tolerances to track changes
 field_names     =['Vx','Vy','Vz','Vel','Pressure']
-field_tolerances=[1.5e-07,1e-07,1e-06,1e-07,1e-07]
+field_tolerances=[2e-07,2e-07,2e-06,1e-06,1e-07]
 field_values=[\
 	md.results.StressbalanceSolution.Vx,\
Index: /issm/trunk/test/NightlyRun/test408.m
===================================================================
--- /issm/trunk/test/NightlyRun/test408.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test408.m	(revision 17806)
@@ -14,5 +14,5 @@
 	(md.results.TransientSolution(1).Vel),...
 	(md.results.TransientSolution(1).Pressure),...
-	(md.results.TransientSolution(1).Bed),...
+	(md.results.TransientSolution(1).Base),...
 	(md.results.TransientSolution(1).Surface),...
 	(md.results.TransientSolution(1).Thickness),...
@@ -21,5 +21,5 @@
 	(md.results.TransientSolution(2).Vel),...
 	(md.results.TransientSolution(2).Pressure),...
-	(md.results.TransientSolution(2).Bed),...
+	(md.results.TransientSolution(2).Base),...
 	(md.results.TransientSolution(2).Surface),...
 	(md.results.TransientSolution(2).Thickness),...
@@ -28,5 +28,5 @@
 	(md.results.TransientSolution(3).Vel),...
 	(md.results.TransientSolution(3).Pressure),...
-	(md.results.TransientSolution(3).Bed),...
+	(md.results.TransientSolution(3).Base),...
 	(md.results.TransientSolution(3).Surface),...
 	(md.results.TransientSolution(3).Thickness),...
Index: /issm/trunk/test/NightlyRun/test408.py
===================================================================
--- /issm/trunk/test/NightlyRun/test408.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test408.py	(revision 17806)
@@ -24,5 +24,5 @@
 	md.results.TransientSolution[0].Vel,\
 	md.results.TransientSolution[0].Pressure,\
-	md.results.TransientSolution[0].Bed,\
+	md.results.TransientSolution[0].Base,\
 	md.results.TransientSolution[0].Surface,\
 	md.results.TransientSolution[0].Thickness,\
@@ -31,5 +31,5 @@
 	md.results.TransientSolution[1].Vel,\
 	md.results.TransientSolution[1].Pressure,\
-	md.results.TransientSolution[1].Bed,\
+	md.results.TransientSolution[1].Base,\
 	md.results.TransientSolution[1].Surface,\
 	md.results.TransientSolution[1].Thickness,\
@@ -38,5 +38,5 @@
 	md.results.TransientSolution[2].Vel,\
 	md.results.TransientSolution[2].Pressure,\
-	md.results.TransientSolution[2].Bed,\
+	md.results.TransientSolution[2].Base,\
 	md.results.TransientSolution[2].Surface,\
 	md.results.TransientSolution[2].Thickness,\
Index: /issm/trunk/test/NightlyRun/test409.m
===================================================================
--- /issm/trunk/test/NightlyRun/test409.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test409.m	(revision 17806)
@@ -21,5 +21,5 @@
 	(md.results.TransientSolution(1).Vel),...
 	(md.results.TransientSolution(1).Pressure),...
-	(md.results.TransientSolution(1).Bed),...
+	(md.results.TransientSolution(1).Base),...
 	(md.results.TransientSolution(1).Surface),...
 	(md.results.TransientSolution(1).Thickness),...
@@ -31,5 +31,5 @@
 	(md.results.TransientSolution(2).Vel),...
 	(md.results.TransientSolution(2).Pressure),...
-	(md.results.TransientSolution(2).Bed),...
+	(md.results.TransientSolution(2).Base),...
 	(md.results.TransientSolution(2).Surface),...
 	(md.results.TransientSolution(2).Thickness),...
@@ -41,5 +41,5 @@
 	(md.results.TransientSolution(3).Vel),...
 	(md.results.TransientSolution(3).Pressure),...
-	(md.results.TransientSolution(3).Bed),...
+	(md.results.TransientSolution(3).Base),...
 	(md.results.TransientSolution(3).Surface),...
 	(md.results.TransientSolution(3).Thickness),...
Index: /issm/trunk/test/NightlyRun/test409.py
===================================================================
--- /issm/trunk/test/NightlyRun/test409.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test409.py	(revision 17806)
@@ -31,5 +31,5 @@
 	md.results.TransientSolution[0].Vel,\
 	md.results.TransientSolution[0].Pressure,\
-	md.results.TransientSolution[0].Bed,\
+	md.results.TransientSolution[0].Base,\
 	md.results.TransientSolution[0].Surface,\
 	md.results.TransientSolution[0].Thickness,\
@@ -41,5 +41,5 @@
 	md.results.TransientSolution[1].Vel,\
 	md.results.TransientSolution[1].Pressure,\
-	md.results.TransientSolution[1].Bed,\
+	md.results.TransientSolution[1].Base,\
 	md.results.TransientSolution[1].Surface,\
 	md.results.TransientSolution[1].Thickness,\
@@ -51,5 +51,5 @@
 	md.results.TransientSolution[2].Vel,\
 	md.results.TransientSolution[2].Pressure,\
-	md.results.TransientSolution[2].Bed,\
+	md.results.TransientSolution[2].Base,\
 	md.results.TransientSolution[2].Surface,\
 	md.results.TransientSolution[2].Thickness,\
Index: /issm/trunk/test/NightlyRun/test410.m
===================================================================
--- /issm/trunk/test/NightlyRun/test410.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test410.m	(revision 17806)
@@ -10,5 +10,5 @@
 %Fields and tolerances to track changes
 field_names     ={'Vx','Vy','Vz','Vel','Pressure','Temperature','BasalforcingsMeltingRate'};
-field_tolerances={1e-09,1e-09,1e-08,2e-10,1e-13,1e-10,1e-06};
+field_tolerances={1e-09,1e-09,1e-08,3e-10,1e-13,3e-10,1e-06};
 field_values={...
 	(md.results.SteadystateSolution.Vx),...
Index: /issm/trunk/test/NightlyRun/test410.py
===================================================================
--- /issm/trunk/test/NightlyRun/test410.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test410.py	(revision 17806)
@@ -20,5 +20,5 @@
 #Fields and tolerances to track changes
 field_names     =['Vx','Vy','Vz','Vel','Pressure','Temperature','BasalforcingsMeltingRate']
-field_tolerances=[1e-09,1e-09,1e-08,1e-09,1e-13,1e-10,1e-06]
+field_tolerances=[1e-09,1e-09,1e-08,1e-09,1e-13,3e-10,1e-06]
 field_values=[\
 	md.results.SteadystateSolution.Vx,\
Index: /issm/trunk/test/NightlyRun/test415.m
===================================================================
--- /issm/trunk/test/NightlyRun/test415.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test415.m	(revision 17806)
@@ -24,5 +24,5 @@
 %Fields and tolerances to track changes
 field_names     ={'Gradient','Misfits','FrictionCoefficient','Pressure','Vel','Vx','Vy','Vz','Temperature','BasalforcingsMeltingRate'};
-field_tolerances={1e-10,1e-9,1e-10,1e-13,1e-09,1e-09,1e-09,1e-8,1e-09,1e-6};
+field_tolerances={9e-10,1e-9,1e-10,1e-13,1e-09,1e-09,1e-09,1e-8,1e-09,1e-6};
 field_values={...
 	(md.results.SteadystateSolution.Gradient1),...
Index: /issm/trunk/test/NightlyRun/test415.py
===================================================================
--- /issm/trunk/test/NightlyRun/test415.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test415.py	(revision 17806)
@@ -36,5 +36,5 @@
 #Fields and tolerances to track changes
 field_names     =['Gradient','Misfits','FrictionCoefficient','Pressure','Vel','Vx','Vy','Vz','Temperature','BasalforcingsMeltingRate']
-field_tolerances=[1e-10,1e-9,1e-10,1e-13,1e-09,1e-09,1e-09,1e-8,1e-09,1e-6]
+field_tolerances=[5e-10,1e-9,1e-10,1e-13,1e-09,1e-09,1e-09,1e-8,1e-09,1e-6]
 field_values=[\
 	md.results.SteadystateSolution.Gradient1,\
Index: /issm/trunk/test/NightlyRun/test419.m
===================================================================
--- /issm/trunk/test/NightlyRun/test419.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test419.m	(revision 17806)
@@ -9,5 +9,5 @@
 %Fields and tolerances to track changes
 field_names     ={'Vx','Vy','Vz','Vel','Pressure'};
-field_tolerances={1e-09,1e-09,1e-09,1e-09,1e-09};
+field_tolerances={2e-09,1e-09,1e-09,1e-09,1e-09};
 field_values={...
 	(md.results.StressbalanceSolution.Vx),...
Index: /issm/trunk/test/NightlyRun/test419.py
===================================================================
--- /issm/trunk/test/NightlyRun/test419.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test419.py	(revision 17806)
@@ -19,5 +19,5 @@
 #Fields and tolerances to track changes
 field_names     =['Vx','Vy','Vz','Vel','Pressure']
-field_tolerances=[1e-09,1e-09,1e-09,1e-09,1e-09]
+field_tolerances=[2e-09,1e-09,1e-09,1e-09,1e-09]
 field_values=[\
 	md.results.StressbalanceSolution.Vx,\
Index: /issm/trunk/test/NightlyRun/test421.m
===================================================================
--- /issm/trunk/test/NightlyRun/test421.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test421.m	(revision 17806)
@@ -9,5 +9,5 @@
 %Fields and tolerances to track changes
 field_names     ={'Vx','Vy','Vz','Vel','Pressure'};
-field_tolerances={1e-07,1e-07,2e-05,1e-07,2e-07};
+field_tolerances={6e-07,6e-07,2e-05,6e-07,6e-07};
 field_values={...
 	(md.results.StressbalanceSolution.Vx),...
Index: /issm/trunk/test/NightlyRun/test421.py
===================================================================
--- /issm/trunk/test/NightlyRun/test421.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test421.py	(revision 17806)
@@ -19,5 +19,5 @@
 #Fields and tolerances to track changes
 field_names     =['Vx','Vy','Vz','Vel','Pressure']
-field_tolerances=[2e-07,1e-07,2e-05,1e-07,2e-07]
+field_tolerances=[6e-07,6e-07,2e-05,6e-07,6e-07]
 field_values=[\
 	md.results.StressbalanceSolution.Vx,\
Index: /issm/trunk/test/NightlyRun/test422.m
===================================================================
--- /issm/trunk/test/NightlyRun/test422.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test422.m	(revision 17806)
@@ -10,5 +10,5 @@
 %Fields and tolerances to track changes
 field_names     ={'Vx','Vy','Vz','Vel','Pressure'};
-field_tolerances={2e-07,2e-07,2e-06,2e-07,5e-07};
+field_tolerances={3e-07,2e-07,2e-06,2e-07,5e-07};
 field_values={...
 	(md.results.StressbalanceSolution.Vx),...
Index: /issm/trunk/test/NightlyRun/test422.py
===================================================================
--- /issm/trunk/test/NightlyRun/test422.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test422.py	(revision 17806)
@@ -20,5 +20,5 @@
 #Fields and tolerances to track changes
 field_names     =['Vx','Vy','Vz','Vel','Pressure']
-field_tolerances=[2e-07,2e-07,2e-06,2e-07,5e-07]
+field_tolerances=[3e-07,2e-07,2e-06,2e-07,5e-07]
 field_values=[\
 	md.results.StressbalanceSolution.Vx,\
Index: /issm/trunk/test/NightlyRun/test423.m
===================================================================
--- /issm/trunk/test/NightlyRun/test423.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test423.m	(revision 17806)
@@ -34,5 +34,5 @@
 vel_soft=(md.results.TransientSolution.Vel);
 
-md.mask.groundedice_levelset=md.geometry.thickness + md.materials.rho_water/md.materials.rho_ice*md.geometry.bathymetry;
+md.mask.groundedice_levelset=md.geometry.thickness + md.materials.rho_water/md.materials.rho_ice*md.geometry.bed;
 md.groundingline.migration='SubelementMigration';
 md=solve(md,TransientSolutionEnum());
@@ -47,4 +47,4 @@
 %Fields and tolerances to track changes
 field_names     ={'ElementOnIceShelfAgressive','VelAgressive','ElementOnIceShelfSoft','VelSoft','ElementOnIceShelfSubelement','VelSubelement','ElementOnIceShelfSubelement2','VelSubelement2'};
-field_tolerances={1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13};
+field_tolerances={1e-13,2e-12,1e-13,2e-12,1e-13,3e-12,1e-13,2e-12};
 field_values={element_on_iceshelf_agressive,vel_agressive,element_on_iceshelf_soft,vel_soft,element_on_iceshelf_subelement,vel_subelement,element_on_iceshelf_subelement2,vel_subelement2};
Index: /issm/trunk/test/NightlyRun/test423.py
===================================================================
--- /issm/trunk/test/NightlyRun/test423.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test423.py	(revision 17806)
@@ -45,5 +45,5 @@
 vel_soft=md.results.TransientSolution[0].Vel
 
-md.mask.groundedice_levelset=md.geometry.thickness + md.materials.rho_water/md.materials.rho_ice*md.geometry.bathymetry
+md.mask.groundedice_levelset=md.geometry.thickness + md.materials.rho_water/md.materials.rho_ice*md.geometry.bed
 md.groundingline.migration='SubelementMigration'
 md=solve(md,TransientSolutionEnum())
@@ -58,4 +58,4 @@
 #Fields and tolerances to track changes
 field_names     =['ElementOnIceShelfAgressive','VelAgressive','ElementOnIceShelfSoft','VelSoft','ElementOnIceShelfSubelement','VelSubelement','ElementOnIceShelfSubelement2','VelSubelement2']
-field_tolerances=[1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13]
+field_tolerances=[1e-13,2e-13,1e-13,2e-13,1e-13,2e-13,1e-13,2e-13]
 field_values=[element_on_iceshelf_agressive,vel_agressive,element_on_iceshelf_soft,vel_soft,element_on_iceshelf_subelement,vel_subelement,element_on_iceshelf_subelement2,vel_subelement2]
Index: /issm/trunk/test/NightlyRun/test424.m
===================================================================
--- /issm/trunk/test/NightlyRun/test424.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test424.m	(revision 17806)
@@ -5,8 +5,8 @@
 md.initialization.vx(:)=0.;
 md.initialization.vy(:)=0.;
-md.geometry.bed=-700.-abs(md.mesh.y-500000.)/1000.;
-md.geometry.bathymetry=-700.-abs(md.mesh.y-500000.)/1000.;
+md.geometry.base=-700.-abs(md.mesh.y-500000.)/1000.;
+md.geometry.bed =-700.-abs(md.mesh.y-500000.)/1000.;
 md.geometry.thickness(:)=1000.;
-md.geometry.surface=md.geometry.bed+md.geometry.thickness;
+md.geometry.surface=md.geometry.base+md.geometry.thickness;
 md.surfaceforcings.mass_balance(:)=100.;
 md.transient.isstressbalance=0;
@@ -26,5 +26,5 @@
 	1e-13,1e-13,1e-13,1e-13,1e-13,1e-13};
 field_values={...
-	(md.results.TransientSolution(1).Bed),...
+	(md.results.TransientSolution(1).Base),...
 	(md.results.TransientSolution(1).Surface),...
 	(md.results.TransientSolution(1).Thickness),...
@@ -32,5 +32,5 @@
 	(md.results.TransientSolution(1).IceVolume),...
 	(md.results.TransientSolution(1).IceVolumeAboveFloatation),...
-	(md.results.TransientSolution(2).Bed),...
+	(md.results.TransientSolution(2).Base),...
 	(md.results.TransientSolution(2).Surface),...
 	(md.results.TransientSolution(2).Thickness),...
@@ -38,5 +38,5 @@
 	(md.results.TransientSolution(2).IceVolume),...
 	(md.results.TransientSolution(2).IceVolumeAboveFloatation),...
-	(md.results.TransientSolution(3).Bed),...
+	(md.results.TransientSolution(3).Base),...
 	(md.results.TransientSolution(3).Surface),...
 	(md.results.TransientSolution(3).Thickness),...
Index: /issm/trunk/test/NightlyRun/test424.py
===================================================================
--- /issm/trunk/test/NightlyRun/test424.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test424.py	(revision 17806)
@@ -15,8 +15,8 @@
 md.initialization.vx[:]=0.
 md.initialization.vy[:]=0.
-md.geometry.bed=-700.-abs(md.mesh.y.reshape(-1,1)-500000.)/1000.
-md.geometry.bathymetry=-700.-abs(md.mesh.y.reshape(-1,1)-500000.)/1000.
+md.geometry.base=-700.-abs(md.mesh.y.reshape(-1,1)-500000.)/1000.
+md.geometry.bed =-700.-abs(md.mesh.y.reshape(-1,1)-500000.)/1000.
 md.geometry.thickness[:]=1000.
-md.geometry.surface=md.geometry.bed+md.geometry.thickness
+md.geometry.surface=md.geometry.base+md.geometry.thickness
 md.surfaceforcings.mass_balance[:]=100.
 md.transient.isstressbalance=False
@@ -36,5 +36,5 @@
 	1e-13,1e-13,1e-13,1e-13,1e-13,1e-13]
 field_values=[\
-	md.results.TransientSolution[0].Bed,\
+	md.results.TransientSolution[0].Base,\
 	md.results.TransientSolution[0].Surface,\
 	md.results.TransientSolution[0].Thickness,\
@@ -42,5 +42,5 @@
 	md.results.TransientSolution[0].IceVolume,\
 	md.results.TransientSolution[0].IceVolumeAboveFloatation,\
-	md.results.TransientSolution[1].Bed,\
+	md.results.TransientSolution[1].Base,\
 	md.results.TransientSolution[1].Surface,\
 	md.results.TransientSolution[1].Thickness,\
@@ -48,5 +48,5 @@
 	md.results.TransientSolution[1].IceVolume,\
 	md.results.TransientSolution[1].IceVolumeAboveFloatation,\
-	md.results.TransientSolution[2].Bed,\
+	md.results.TransientSolution[2].Base,\
 	md.results.TransientSolution[2].Surface,\
 	md.results.TransientSolution[2].Thickness,\
Index: /issm/trunk/test/NightlyRun/test425.m
===================================================================
--- /issm/trunk/test/NightlyRun/test425.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test425.m	(revision 17806)
@@ -5,8 +5,8 @@
 md.initialization.vx(:)=0.;
 md.initialization.vy(:)=0.;
-md.geometry.bed=-700.-abs(md.mesh.y-500000.)/1000.;
-md.geometry.bathymetry=-700.-abs(md.mesh.y-500000.)/1000.;
+md.geometry.base=-700.-abs(md.mesh.y-500000.)/1000.;
+md.geometry.bed =-700.-abs(md.mesh.y-500000.)/1000.;
 md.geometry.thickness(:)=1300.;
-md.geometry.surface=md.geometry.bed+md.geometry.thickness;
+md.geometry.surface=md.geometry.base+md.geometry.thickness;
 md.surfaceforcings.mass_balance(:)=-150.;
 md.transient.isstressbalance=0;
@@ -25,13 +25,13 @@
 	1e-13,1e-13,1e-13,1e-13};
 field_values={...
-	(md.results.TransientSolution(1).Bed),...
+	(md.results.TransientSolution(1).Base),...
 	(md.results.TransientSolution(1).Surface),...
 	(md.results.TransientSolution(1).Thickness),...
 	(md.results.TransientSolution(1).MaskGroundediceLevelset),...
-	(md.results.TransientSolution(2).Bed),...
+	(md.results.TransientSolution(2).Base),...
 	(md.results.TransientSolution(2).Surface),...
 	(md.results.TransientSolution(2).Thickness),...
 	(md.results.TransientSolution(2).MaskGroundediceLevelset),...
-	(md.results.TransientSolution(3).Bed),...
+	(md.results.TransientSolution(3).Base),...
 	(md.results.TransientSolution(3).Surface),...
 	(md.results.TransientSolution(3).Thickness),...
Index: /issm/trunk/test/NightlyRun/test425.py
===================================================================
--- /issm/trunk/test/NightlyRun/test425.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test425.py	(revision 17806)
@@ -15,8 +15,8 @@
 md.initialization.vx[:]=0.
 md.initialization.vy[:]=0.
-md.geometry.bed=-700.-abs(md.mesh.y.reshape(-1,1)-500000.)/1000.
-md.geometry.bathymetry=-700.-abs(md.mesh.y.reshape(-1,1)-500000.)/1000.
+md.geometry.base=-700.-abs(md.mesh.y.reshape(-1,1)-500000.)/1000.
+md.geometry.bed =-700.-abs(md.mesh.y.reshape(-1,1)-500000.)/1000.
 md.geometry.thickness[:]=1300.
-md.geometry.surface=md.geometry.bed+md.geometry.thickness
+md.geometry.surface=md.geometry.base+md.geometry.thickness
 md.surfaceforcings.mass_balance[:]=-150.
 md.transient.isstressbalance=False
@@ -35,13 +35,13 @@
 	1e-13,1e-13,1e-13,1e-13]
 field_values=[\
-	md.results.TransientSolution[0].Bed,\
+	md.results.TransientSolution[0].Base,\
 	md.results.TransientSolution[0].Surface,\
 	md.results.TransientSolution[0].Thickness,\
 	md.results.TransientSolution[0].MaskGroundediceLevelset,\
-	md.results.TransientSolution[1].Bed,\
+	md.results.TransientSolution[1].Base,\
 	md.results.TransientSolution[1].Surface,\
 	md.results.TransientSolution[1].Thickness,\
 	md.results.TransientSolution[1].MaskGroundediceLevelset,\
-	md.results.TransientSolution[2].Bed,\
+	md.results.TransientSolution[2].Base,\
 	md.results.TransientSolution[2].Surface,\
 	md.results.TransientSolution[2].Thickness,\
Index: /issm/trunk/test/NightlyRun/test426.m
===================================================================
--- /issm/trunk/test/NightlyRun/test426.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test426.m	(revision 17806)
@@ -4,8 +4,8 @@
 md.initialization.vx(:)=0.;
 md.initialization.vy(:)=0.;
-md.geometry.bed=-700.-abs(md.mesh.y-500000.)/1000.;
-md.geometry.bathymetry=-700.-abs(md.mesh.y-500000.)/1000.;
+md.geometry.base=-700.-abs(md.mesh.y-500000.)/1000.;
+md.geometry.bed =-700.-abs(md.mesh.y-500000.)/1000.;
 md.geometry.thickness(:)=1000.;
-md.geometry.surface=md.geometry.bed+md.geometry.thickness;
+md.geometry.surface=md.geometry.base+md.geometry.thickness;
 md.surfaceforcings.mass_balance(:)=100.;
 md=extrude(md,3,1.);
@@ -24,8 +24,8 @@
 	'Bed3','Surface3','Thickness3','Floatingice3','IceVolume3','IceVolumeAboveFloatation3'};
 field_tolerances={1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,...
-	1e-11,1e-10,1e-11,1.25e-11,1e-13,1e-13,...
-	1e-10,1e-10,1e-10,1.15e-11,1e-13,1e-13};
+	1e-11,1e-10,1e-11,3e-11,2e-12,5e-12,...
+	1e-10,1e-10,1e-10,5e-11,2e-12,5e-12};
 field_values={...
-	(md.results.TransientSolution(1).Bed),...
+	(md.results.TransientSolution(1).Base),...
 	(md.results.TransientSolution(1).Surface),...
 	(md.results.TransientSolution(1).Thickness),...
@@ -33,5 +33,5 @@
 	(md.results.TransientSolution(1).IceVolume),...
 	(md.results.TransientSolution(1).IceVolumeAboveFloatation),...
-	(md.results.TransientSolution(2).Bed),...
+	(md.results.TransientSolution(2).Base),...
 	(md.results.TransientSolution(2).Surface),...
 	(md.results.TransientSolution(2).Thickness),...
@@ -39,5 +39,5 @@
 	(md.results.TransientSolution(2).IceVolume),...
 	(md.results.TransientSolution(2).IceVolumeAboveFloatation),...
-	(md.results.TransientSolution(3).Bed),...
+	(md.results.TransientSolution(3).Base),...
 	(md.results.TransientSolution(3).Surface),...
 	(md.results.TransientSolution(3).Thickness),...
Index: /issm/trunk/test/NightlyRun/test426.py
===================================================================
--- /issm/trunk/test/NightlyRun/test426.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test426.py	(revision 17806)
@@ -14,8 +14,8 @@
 md.initialization.vx[:]=0.
 md.initialization.vy[:]=0.
-md.geometry.bed=-700.-abs(md.mesh.y.reshape(-1,1)-500000.)/1000.
-md.geometry.bathymetry=-700.-abs(md.mesh.y.reshape(-1,1)-500000.)/1000.
+md.geometry.base=-700.-abs(md.mesh.y.reshape(-1,1)-500000.)/1000.
+md.geometry.bed =-700.-abs(md.mesh.y.reshape(-1,1)-500000.)/1000.
 md.geometry.thickness[:]=1000.
-md.geometry.surface=md.geometry.bed+md.geometry.thickness
+md.geometry.surface=md.geometry.base+md.geometry.thickness
 md.surfaceforcings.mass_balance[:]=100.
 md.extrude(3,1.);
@@ -35,9 +35,9 @@
 
 field_tolerances=[1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,\
-	1e-11,1e-10,1e-11,1.25e-11,1e-13,1e-13,\
-	1e-10,1e-10,1e-10,1.15e-11,1e-13,1e-13]
+	1e-11,1e-10,1e-11,3e-11,2e-12,5e-12,\
+	1e-10,1e-10,1e-10,5e-11,2e-12,5e-12]
 
 field_values=[\
-	md.results.TransientSolution[0].Bed,\
+	md.results.TransientSolution[0].Base,\
 	md.results.TransientSolution[0].Surface,\
 	md.results.TransientSolution[0].Thickness,\
@@ -45,5 +45,5 @@
 	md.results.TransientSolution[0].IceVolume,\
 	md.results.TransientSolution[0].IceVolumeAboveFloatation,\
-	md.results.TransientSolution[1].Bed,\
+	md.results.TransientSolution[1].Base,\
 	md.results.TransientSolution[1].Surface,\
 	md.results.TransientSolution[1].Thickness,\
@@ -51,5 +51,5 @@
 	md.results.TransientSolution[1].IceVolume,\
 	md.results.TransientSolution[1].IceVolumeAboveFloatation,\
-	md.results.TransientSolution[2].Bed,\
+	md.results.TransientSolution[2].Base,\
 	md.results.TransientSolution[2].Surface,\
 	md.results.TransientSolution[2].Thickness,\
Index: /issm/trunk/test/NightlyRun/test427.m
===================================================================
--- /issm/trunk/test/NightlyRun/test427.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test427.m	(revision 17806)
@@ -4,8 +4,8 @@
 md.initialization.vx(:)=0.;
 md.initialization.vy(:)=0.;
-md.geometry.bed=-700.-abs(md.mesh.y-500000.)/1000.;
-md.geometry.bathymetry=-700.-abs(md.mesh.y-500000.)/1000.;
+md.geometry.base=-700.-abs(md.mesh.y-500000.)/1000.;
+md.geometry.bed =-700.-abs(md.mesh.y-500000.)/1000.;
 md.geometry.thickness(:)=1300;
-md.geometry.surface=md.geometry.bed+md.geometry.thickness;
+md.geometry.surface=md.geometry.base+md.geometry.thickness;
 md=setflowequation(md,'SSA','all');
 md=extrude(md,3,1.);
@@ -23,16 +23,16 @@
 	'Bed3','Surface3','Thickness3','Floatingice3'};
 field_tolerances={1e-13,1e-13,1e-13,1e-13,...
-	1e-13,1e-13,1e-13,1e-13,...
-	1e-10,1e-11,1e-10,1e-13};
+	5e-12,3e-12,7e-12,2e-11,...
+	1e-10,3e-11,1e-10,7e-11};
 field_values={...
-	(md.results.TransientSolution(1).Bed),...
+	(md.results.TransientSolution(1).Base),...
 	(md.results.TransientSolution(1).Surface),...
 	(md.results.TransientSolution(1).Thickness),...
 	(md.results.TransientSolution(1).MaskGroundediceLevelset),...
-	(md.results.TransientSolution(2).Bed),...
+	(md.results.TransientSolution(2).Base),...
 	(md.results.TransientSolution(2).Surface),...
 	(md.results.TransientSolution(2).Thickness),...
 	(md.results.TransientSolution(2).MaskGroundediceLevelset),...
-	(md.results.TransientSolution(3).Bed),...
+	(md.results.TransientSolution(3).Base),...
 	(md.results.TransientSolution(3).Surface),...
 	(md.results.TransientSolution(3).Thickness),...
Index: /issm/trunk/test/NightlyRun/test427.py
===================================================================
--- /issm/trunk/test/NightlyRun/test427.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test427.py	(revision 17806)
@@ -14,8 +14,8 @@
 md.initialization.vx[:]=0.
 md.initialization.vy[:]=0.
-md.geometry.bed=-700.-abs(md.mesh.y.reshape(-1,1)-500000.)/1000.
-md.geometry.bathymetry=-700.-abs(md.mesh.y.reshape(-1,1)-500000.)/1000.
+md.geometry.base=-700.-abs(md.mesh.y.reshape(-1,1)-500000.)/1000.
+md.geometry.bed =-700.-abs(md.mesh.y.reshape(-1,1)-500000.)/1000.
 md.geometry.thickness[:]=1300
-md.geometry.surface=md.geometry.bed+md.geometry.thickness
+md.geometry.surface=md.geometry.base+md.geometry.thickness
 md=setflowequation(md,'SSA','all')
 md.extrude(3,1.)
@@ -33,16 +33,16 @@
 	'Bed3','Surface3','Thickness3','Floatingice3']
 field_tolerances=[1e-13,1e-13,1e-13,1e-13,\
-	1e-13,1e-13,1e-13,1e-13,\
+	5e-12,3e-12,7e-12,2e-11,\
 	1e-10,1e-11,1e-10,1e-13]
 field_values=[\
-	md.results.TransientSolution[0].Bed,\
+	md.results.TransientSolution[0].Base,\
 	md.results.TransientSolution[0].Surface,\
 	md.results.TransientSolution[0].Thickness,\
 	md.results.TransientSolution[0].MaskGroundediceLevelset,\
-	md.results.TransientSolution[1].Bed,\
+	md.results.TransientSolution[1].Base,\
 	md.results.TransientSolution[1].Surface,\
 	md.results.TransientSolution[1].Thickness,\
 	md.results.TransientSolution[1].MaskGroundediceLevelset,\
-	md.results.TransientSolution[2].Bed,\
+	md.results.TransientSolution[2].Base,\
 	md.results.TransientSolution[2].Surface,\
 	md.results.TransientSolution[2].Thickness,\
Index: /issm/trunk/test/NightlyRun/test435.m
===================================================================
--- /issm/trunk/test/NightlyRun/test435.m	(revision 17806)
+++ /issm/trunk/test/NightlyRun/test435.m	(revision 17806)
@@ -0,0 +1,77 @@
+md=triangle(model(),'../Exp/Square.exp',100000.);
+md=setmask(md,'../Exp/SquareShelf.exp','');
+md=parameterize(md,'../Par/SquareSheetShelf.par');
+md.initialization.vx(:)=1.;
+md.initialization.vy(:)=1.;
+md.geometry.thickness(:)=500-md.mesh.x/10000;
+md.geometry.bed =-100-md.mesh.x/1000;
+md.geometry.base=-md.geometry.thickness*md.materials.rho_ice/md.materials.rho_water;
+md.mask.groundedice_levelset=md.geometry.thickness+md.materials.rho_water/md.materials.rho_ice*md.geometry.bed;
+pos=find(md.mask.groundedice_levelset>=0);
+md.geometry.base(pos)=md.geometry.bed(pos);
+md.geometry.surface=md.geometry.base+md.geometry.thickness;
+md=extrude(md,4,1.);
+md=setflowequation(md,'HO','all');
+
+%Boundary conditions:
+md.mask.ice_levelset=-ones(md.mesh.numberofvertices,1);
+md.mask.ice_levelset(find(md.mesh.x==max(md.mesh.x)))=0;
+md.stressbalance.spcvx(:)=NaN;
+md.stressbalance.spcvy(:)=NaN;
+md.stressbalance.spcvz(:)=NaN;
+pos=find((md.mesh.y<1000000.1 & md.mesh.y>999999.9) | (md.mesh.y<0.1 & md.mesh.y>-0.1));
+md.stressbalance.spcvy(pos)=0;
+pos2=find(md.mesh.x<0.1 & md.mesh.x>-0.1);
+md.stressbalance.spcvx(pos2)=0;
+md.stressbalance.spcvy(pos2)=0;
+
+md.materials.rheology_B=1/((10^-25)^(1/3))*ones(md.mesh.numberofvertices,1);
+md.materials.rheology_law='None';
+md.friction.coefficient(:)=sqrt(10^7)*ones(md.mesh.numberofvertices,1);
+md.friction.p=3*ones(md.mesh.numberofelements,1);
+md.surfaceforcings.mass_balance(:)=1;
+md.basalforcings.melting_rate(:)=0;
+md.transient.isthermal=0;
+md.transient.isstressbalance=1;
+md.transient.isgroundingline=1;
+md.transient.ismasstransport=1;
+md.groundingline.migration='SubelementMigration';
+md.timestepping.final_time=30;
+md.timestepping.time_step=10;
+
+md.cluster=generic('name',oshostname(),'np',3);
+md=solve(md,TransientSolutionEnum());
+
+%Fields and tolerances to track changes
+field_names     ={'Bed1','Surface1','Thickness1','Floatingice1','Vx1','Vy1','Vz1','Pressure1',...
+	'Bed2','Surface2','Thickness2','Floatingice2','Vx2','Vy2','Vz2','Pressure2',...
+	'Bed3','Surface3','Thickness3','Floatingice3','Vx3','Vy3','Vz3','Pressure3'};
+field_tolerances={2e-11,5e-12,2e-11,1e-11,4e-10,1e-08,6e-10,1e-13,...
+	3e-11,3e-11,9e-10,7e-11,1e-09,1e-08,1e-09,1e-10,...
+	1e-10,3e-11,1e-10,7e-11,1e-09,1e-08,1e-09,1e-10};
+field_values={...
+	(md.results.TransientSolution(1).Base),...
+	(md.results.TransientSolution(1).Surface),...
+	(md.results.TransientSolution(1).Thickness),...
+	(md.results.TransientSolution(1).MaskGroundediceLevelset),...
+	(md.results.TransientSolution(1).Vx),...
+	(md.results.TransientSolution(1).Vy),...
+	(md.results.TransientSolution(1).Vz),...
+	(md.results.TransientSolution(1).Pressure),...
+	(md.results.TransientSolution(2).Base),...
+	(md.results.TransientSolution(2).Surface),...
+	(md.results.TransientSolution(2).Thickness),...
+	(md.results.TransientSolution(2).MaskGroundediceLevelset),...
+	(md.results.TransientSolution(2).Vx),...
+	(md.results.TransientSolution(2).Vy),...
+	(md.results.TransientSolution(2).Vz),...
+	(md.results.TransientSolution(2).Pressure),...
+	(md.results.TransientSolution(3).Base),...
+	(md.results.TransientSolution(3).Surface),...
+	(md.results.TransientSolution(3).Thickness),...
+	(md.results.TransientSolution(3).MaskGroundediceLevelset),...
+	(md.results.TransientSolution(3).Vx),...
+	(md.results.TransientSolution(3).Vy),...
+	(md.results.TransientSolution(3).Vz),...
+	(md.results.TransientSolution(3).Pressure),...
+	};
Index: /issm/trunk/test/NightlyRun/test455.m
===================================================================
--- /issm/trunk/test/NightlyRun/test455.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test455.m	(revision 17806)
@@ -9,9 +9,9 @@
 field_tolerances={};
 field_values={};
-for i={'P1bubble','P1bubblecondensed','P1xP2','P2xP1','P2'}
+for i={'P1bubble','P1bubblecondensed','P1xP2','P2xP1','P2','P1xP3','P2xP4'}
 	md.flowequation.fe_HO=i{1};
 	md=solve(md,StressbalanceSolutionEnum());
 	field_names     ={field_names{:},['Vx' i{1}],['Vy' i{1}],['Vz' i{1}],['Vel' i{1}],['Pressure' i{1}]};
-	field_tolerances={field_tolerances{:},1e-08,1e-08,1e-08,1e-08,1e-13};
+	field_tolerances={field_tolerances{:},5e-08,4e-08,1e-08,4e-08,3e-13};
 	field_values={field_values{:},...
 	(md.results.StressbalanceSolution.Vx),...
Index: /issm/trunk/test/NightlyRun/test455.py
===================================================================
--- /issm/trunk/test/NightlyRun/test455.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test455.py	(revision 17806)
@@ -19,9 +19,9 @@
 field_tolerances=[]
 field_values=[]
-for i in ['P1bubble','P1bubblecondensed','P1xP2','P2xP1','P2']:
+for i in ['P1bubble','P1bubblecondensed','P1xP2','P2xP1','P2','P1xP3','P2xP4']:
 	md.flowequation.fe_HO=i
 	md=solve(md,StressbalanceSolutionEnum())
 	field_names     =field_names+['Vx'+i,'Vy'+i,'Vz'+i,'Vel'+i,'Pressure'+i]
-	field_tolerances=field_tolerances+[1e-08,1e-08,1e-08,1e-08,1e-13]
+	field_tolerances=field_tolerances+[5e-08,4e-08,1e-08,4e-08,3e-13]
 	field_values=field_values+[\
 			md.results.StressbalanceSolution.Vx,\
Index: /issm/trunk/test/NightlyRun/test501.m
===================================================================
--- /issm/trunk/test/NightlyRun/test501.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test501.m	(revision 17806)
@@ -8,5 +8,5 @@
 %Fields and tolerances to track changes
 field_names     ={'Vx','Vy','Vel','Pressure'};
-field_tolerances={1e-13,1e-13,1e-13,1e-13};
+field_tolerances={1e-12,2e-12,2e-12,1e-13};
 field_values={...
 	(md.results.StressbalanceSolution.Vx),...
Index: /issm/trunk/test/NightlyRun/test501.py
===================================================================
--- /issm/trunk/test/NightlyRun/test501.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test501.py	(revision 17806)
@@ -17,5 +17,5 @@
 # Fields and tolerances to track changes
 field_names     =['Vx','Vy','Vel','Pressure']
-field_tolerances=[1e-13,1e-13,1e-13,1e-13]
+field_tolerances=[1e-12,2e-12,2e-12,1e-13]
 field_values=[\
 	md.results.StressbalanceSolution.Vx,\
Index: /issm/trunk/test/NightlyRun/test504.m
===================================================================
--- /issm/trunk/test/NightlyRun/test504.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test504.m	(revision 17806)
@@ -8,5 +8,5 @@
 %Fields and tolerances to track changes
 field_names     ={'Vx1','Vy1','Vel1','Pressure1','Bed1','Surface1','Thickness1','Vx2','Vy2','Vel2','Pressure2','Bed2','Surface2','Thickness2'};
-field_tolerances={1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13};
+field_tolerances={1e-12,2e-12,2e-12,1e-13,1e-13,1e-13,1e-13,1e-12,1e-12,1e-12,1e-13,1e-13,1e-13,1e-13};
 field_values={...
 	(md.results.TransientSolution(1).Vx),...
@@ -14,5 +14,5 @@
 	(md.results.TransientSolution(1).Vel),...
 	(md.results.TransientSolution(1).Pressure),...
-	(md.results.TransientSolution(1).Bed),...
+	(md.results.TransientSolution(1).Base),...
 	(md.results.TransientSolution(1).Surface),...
 	(md.results.TransientSolution(1).Thickness),...
@@ -21,5 +21,5 @@
 	(md.results.TransientSolution(2).Vel),...
 	(md.results.TransientSolution(2).Pressure),...
-	(md.results.TransientSolution(2).Bed),...
+	(md.results.TransientSolution(2).Base),...
 	(md.results.TransientSolution(2).Surface),...
 	(md.results.TransientSolution(2).Thickness),...
Index: /issm/trunk/test/NightlyRun/test504.py
===================================================================
--- /issm/trunk/test/NightlyRun/test504.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test504.py	(revision 17806)
@@ -17,5 +17,5 @@
 # Fields and tolerances to track changes
 field_names     =['Vx1','Vy1','Vel1','Pressure1','Bed1','Surface1','Thickness1','Vx2','Vy2','Vel2','Pressure2','Bed2','Surface2','Thickness2']
-field_tolerances=[1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13]
+field_tolerances=[1e-12,2e-12,2e-12,1e-13,1e-13,1e-13,1e-13,1e-12,1e-12,1e-12,1e-13,1e-13,1e-13,1e-13]
 field_values=[\
 	md.results.TransientSolution[0].Vx,\
@@ -23,5 +23,5 @@
 	md.results.TransientSolution[0].Vel,\
 	md.results.TransientSolution[0].Pressure,\
-	md.results.TransientSolution[0].Bed,\
+	md.results.TransientSolution[0].Base,\
 	md.results.TransientSolution[0].Surface,\
 	md.results.TransientSolution[0].Thickness,\
@@ -30,5 +30,5 @@
 	md.results.TransientSolution[1].Vel,\
 	md.results.TransientSolution[1].Pressure,\
-	md.results.TransientSolution[1].Bed,\
+	md.results.TransientSolution[1].Base,\
 	md.results.TransientSolution[1].Surface,\
 	md.results.TransientSolution[1].Thickness,\
Index: /issm/trunk/test/NightlyRun/test505.m
===================================================================
--- /issm/trunk/test/NightlyRun/test505.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test505.m	(revision 17806)
@@ -10,6 +10,6 @@
 field_names     ={'Vx1','Vy1','Vz1','Vel1','Pressure1','Bed1','Surface1','Thickness1','Temperature1','BasalforcingsMeltingRate1', ...
 				      'Vx2','Vy2','Vz2','Vel2','Pressure2','Bed2','Surface2','Thickness2','Temperature2','BasalforcingsMeltingRate2'};
-field_tolerances={1e-12,1e-12,1e-10,1e-12,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,...
-						1e-13,1e-12,1e-10,1e-12,1e-13,1e-11,1e-11,2e-12,1e-11,1e-8};
+field_tolerances={1e-12,1e-12,3e-10,1e-12,1e-13,1e-11,5e-12,9e-12,1e-13,5e-9,...
+						5e-11,5e-11,1e-10,2e-11,7e-12,1e-11,1e-11,5e-12,1e-11,2e-8};
 field_values={...
 	(md.results.TransientSolution(1).Vx),...
@@ -18,5 +18,5 @@
 	(md.results.TransientSolution(1).Vel),...
 	(md.results.TransientSolution(1).Pressure),...
-	(md.results.TransientSolution(1).Bed),...
+	(md.results.TransientSolution(1).Base),...
 	(md.results.TransientSolution(1).Surface),...
 	(md.results.TransientSolution(1).Thickness),...
@@ -28,5 +28,5 @@
 	(md.results.TransientSolution(2).Vel),...
 	(md.results.TransientSolution(2).Pressure),...
-	(md.results.TransientSolution(2).Bed),...
+	(md.results.TransientSolution(2).Base),...
 	(md.results.TransientSolution(2).Surface),...
 	(md.results.TransientSolution(2).Thickness),...
Index: /issm/trunk/test/NightlyRun/test505.py
===================================================================
--- /issm/trunk/test/NightlyRun/test505.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test505.py	(revision 17806)
@@ -27,5 +27,5 @@
 	md.results.TransientSolution[0].Vel,\
 	md.results.TransientSolution[0].Pressure,\
-	md.results.TransientSolution[0].Bed,\
+	md.results.TransientSolution[0].Base,\
 	md.results.TransientSolution[0].Surface,\
 	md.results.TransientSolution[0].Thickness,\
@@ -37,5 +37,5 @@
 	md.results.TransientSolution[1].Vel,\
 	md.results.TransientSolution[1].Pressure,\
-	md.results.TransientSolution[1].Bed,\
+	md.results.TransientSolution[1].Base,\
 	md.results.TransientSolution[1].Surface,\
 	md.results.TransientSolution[1].Thickness,\
Index: /issm/trunk/test/NightlyRun/test506.m
===================================================================
--- /issm/trunk/test/NightlyRun/test506.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test506.m	(revision 17806)
@@ -18,5 +18,5 @@
 	(md.results.TransientSolution(1).Vel),...
 	(md.results.TransientSolution(1).Pressure),...
-	(md.results.TransientSolution(1).Bed),...
+	(md.results.TransientSolution(1).Base),...
 	(md.results.TransientSolution(1).Surface),...
 	(md.results.TransientSolution(1).Thickness),...
@@ -28,5 +28,5 @@
 	(md.results.TransientSolution(2).Vel),...
 	(md.results.TransientSolution(2).Pressure),...
-	(md.results.TransientSolution(2).Bed),...
+	(md.results.TransientSolution(2).Base),...
 	(md.results.TransientSolution(2).Surface),...
 	(md.results.TransientSolution(2).Thickness),...
Index: /issm/trunk/test/NightlyRun/test506.py
===================================================================
--- /issm/trunk/test/NightlyRun/test506.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test506.py	(revision 17806)
@@ -27,5 +27,5 @@
 	md.results.TransientSolution[0].Vel,\
 	md.results.TransientSolution[0].Pressure,\
-	md.results.TransientSolution[0].Bed,\
+	md.results.TransientSolution[0].Base,\
 	md.results.TransientSolution[0].Surface,\
 	md.results.TransientSolution[0].Thickness,\
@@ -37,5 +37,5 @@
 	md.results.TransientSolution[1].Vel,\
 	md.results.TransientSolution[1].Pressure,\
-	md.results.TransientSolution[1].Bed,\
+	md.results.TransientSolution[1].Base,\
 	md.results.TransientSolution[1].Surface,\
 	md.results.TransientSolution[1].Thickness,\
Index: /issm/trunk/test/NightlyRun/test507.m
===================================================================
--- /issm/trunk/test/NightlyRun/test507.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test507.m	(revision 17806)
@@ -10,5 +10,5 @@
 field_names     ={'Vx1','Vy1','Vz1','Vel1','Pressure1','Bed1','Surface1','Thickness1','Temperature1','BasalforcingsMeltingRate1', ...
 				      'Vx2','Vy2','Vz2','Vel2','Pressure2','Bed2','Surface2','Thickness2','Temperature2','BasalforcingsMeltingRate2'};
-field_tolerances={1e-08,1e-08,1e-08,1e-08,1e-08,1e-08,1e-08,1e-08,1e-08,1e-08,1e-06,1e-06,1e-06,1e-06,1e-06,1e-06,1e-06,1e-06,1e-06,1e-06};
+field_tolerances={1e-08,1e-08,1e-08,1e-08,1e-08,1e-08,1e-08,1e-08,1e-08,1e-08,1e-06,1e-06,1e-06,1e-06,1e-06,1e-06,1e-06,1e-06,3e-06,1e-06};
 field_values={...
 	(md.results.TransientSolution(1).Vx),...
@@ -17,5 +17,5 @@
 	(md.results.TransientSolution(1).Vel),...
 	(md.results.TransientSolution(1).Pressure),...
-	(md.results.TransientSolution(1).Bed),...
+	(md.results.TransientSolution(1).Base),...
 	(md.results.TransientSolution(1).Surface),...
 	(md.results.TransientSolution(1).Thickness),...
@@ -27,5 +27,5 @@
 	(md.results.TransientSolution(2).Vel),...
 	(md.results.TransientSolution(2).Pressure),...
-	(md.results.TransientSolution(2).Bed),...
+	(md.results.TransientSolution(2).Base),...
 	(md.results.TransientSolution(2).Surface),...
 	(md.results.TransientSolution(2).Thickness),...
Index: /issm/trunk/test/NightlyRun/test507.py
===================================================================
--- /issm/trunk/test/NightlyRun/test507.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test507.py	(revision 17806)
@@ -26,5 +26,5 @@
 	md.results.TransientSolution[0].Vel,\
 	md.results.TransientSolution[0].Pressure,\
-	md.results.TransientSolution[0].Bed,\
+	md.results.TransientSolution[0].Base,\
 	md.results.TransientSolution[0].Surface,\
 	md.results.TransientSolution[0].Thickness,\
@@ -36,5 +36,5 @@
 	md.results.TransientSolution[1].Vel,\
 	md.results.TransientSolution[1].Pressure,\
-	md.results.TransientSolution[1].Bed,\
+	md.results.TransientSolution[1].Base,\
 	md.results.TransientSolution[1].Surface,\
 	md.results.TransientSolution[1].Thickness,\
Index: /issm/trunk/test/NightlyRun/test508.m
===================================================================
--- /issm/trunk/test/NightlyRun/test508.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test508.m	(revision 17806)
@@ -10,5 +10,5 @@
 %Fields and tolerances to track changes
 field_names     ={'Vx','Vy','Vz','Vel','Pressure','Temperature','BasalforcingsMeltingRate'};
-field_tolerances={7.85e-09,8.15e-09,1.5e-08,8.5e-09,1e-09,1e-09,1e-07};
+field_tolerances={5e-08,3e-08,5e-08,3e-08,1e-09,2e-07,8e-07};
 field_values={...
 	(md.results.SteadystateSolution.Vx),...
Index: /issm/trunk/test/NightlyRun/test508.py
===================================================================
--- /issm/trunk/test/NightlyRun/test508.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test508.py	(revision 17806)
@@ -19,5 +19,5 @@
 # Fields and tolerances to track changes
 field_names     =['Vx','Vy','Vz','Vel','Pressure','Temperature','BasalforcingsMeltingRate']
-field_tolerances=[7.85e-09,8.15e-09,1.5e-08,8.5e-09,1e-09,1e-09,1e-07]
+field_tolerances=[5e-08,1.6e-08,5e-08,1.6e-08,1e-09,6e-08,5e-07]
 field_values=[\
 	md.results.SteadystateSolution.Vx,\
Index: /issm/trunk/test/NightlyRun/test511.m
===================================================================
--- /issm/trunk/test/NightlyRun/test511.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test511.m	(revision 17806)
@@ -4,6 +4,6 @@
 
 %impose hydrostatic equilibrium (required by Stokes)
-md.geometry.bed=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness;
-md.geometry.surface=md.geometry.bed+md.geometry.thickness;
+md.geometry.base=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness;
+md.geometry.surface=md.geometry.base+md.geometry.thickness;
 md=extrude(md,3,1.);
 md=setflowequation(md,'FS','all');
@@ -23,10 +23,10 @@
 md.inversion.vx_obs=md.initialization.vx; md.inversion.vy_obs=md.initialization.vy;
 
-md.cluster=generic('name',oshostname(),'np',3);
+md.cluster=generic('name',oshostname(),'np',1);
 md=solve(md,StressbalanceSolutionEnum());
 
 %Fields and tolerances to track changes
 field_names     ={'Gradient','Misfits','MaterialsRheologyB','Pressure','Vel','Vx','Vy'};
-field_tolerances={1e-11,1e-12,1e-12,1e-09,1e-12,1e-12,1e-12,1e-12,1e-12,1e-12};
+field_tolerances={1e-11,5e-12,1e-11,1e-09,2e-12,1e-11,1e-11};
 field_values={...
 	(md.results.StressbalanceSolution.Gradient1),...
Index: /issm/trunk/test/NightlyRun/test511.py
===================================================================
--- /issm/trunk/test/NightlyRun/test511.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test511.py	(revision 17806)
@@ -14,6 +14,6 @@
 
 #impose hydrostatic equilibrium (required by Stokes)
-md.geometry.bed=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness
-md.geometry.surface=md.geometry.bed+md.geometry.thickness
+md.geometry.base=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness
+md.geometry.surface=md.geometry.base+md.geometry.thickness
 md.extrude(3,1.)
 md=setflowequation(md,'FS','all')
@@ -39,5 +39,5 @@
 #Fields and tolerances to track changes
 field_names     =['Gradient','Misfits','MaterialsRheologyB','Pressure','Vel','Vx','Vy']
-field_tolerances=[1e-11,1e-12,1e-12,1e-09,1e-12,1e-12,1e-12,1e-12,1e-12,1e-12]
+field_tolerances=[1e-11,5e-12,1e-11,1e-09,2e-12,1e-11,1e-11]
 field_values=[\
 	md.results.StressbalanceSolution.Gradient1,\
Index: /issm/trunk/test/NightlyRun/test513.m
===================================================================
--- /issm/trunk/test/NightlyRun/test513.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test513.m	(revision 17806)
@@ -25,5 +25,5 @@
 %Fields and tolerances to track changes
 field_names     ={'Gradient','Misfits','FrictionCoefficient','Pressure','Vel','Vx','Vy','Vz','Temperature','BasalforcingsMeltingRate'};
-field_tolerances={2e-10,2e-10,1e-10,1e-10,1e-6,1e-6,1e-6,1e-6,1e-6,1e-06};
+field_tolerances={2e-10,2e-10,1e-10,1e-10,2e-6,1e-6,2e-6,2e-6,2e-6,2e-06};
 field_values={...
 	(md.results.SteadystateSolution.Gradient1),...
Index: /issm/trunk/test/NightlyRun/test513.py
===================================================================
--- /issm/trunk/test/NightlyRun/test513.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test513.py	(revision 17806)
@@ -36,5 +36,5 @@
 # Fields and tolerances to track changes
 field_names     =['Gradient','Misfits','FrictionCoefficient','Pressure','Vel','Vx','Vy','Vz','Temperature','BasalforcingsMeltingRate']
-field_tolerances=[2e-10,2e-10,1e-10,1e-10,1e-6,1e-6,1e-6,1e-6,1e-6,1e-06]
+field_tolerances=[2e-10,2e-10,1e-10,1e-10,2e-6,1e-6,2e-6,2e-6,2e-6,2e-06]
 field_values=[\
 	md.results.SteadystateSolution.Gradient1,\
Index: /issm/trunk/test/NightlyRun/test514.m
===================================================================
--- /issm/trunk/test/NightlyRun/test514.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test514.m	(revision 17806)
@@ -45,4 +45,4 @@
 %Fields and tolerances to track changes
 field_names      = {'x1' ,'y1' ,'x2' ,'y2' ,'x3' ,'y3' ,'x4' ,'y4' ,'x5' ,'y5' ,'x6' ,'y6' ,'x7' ,'y7' };
-field_tolerances = {1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13};
+field_tolerances = {2e-10,7e-10,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13};
 field_values     = { x1  ,y1   ,y2   ,y2   ,y3   ,y3   ,y4   ,y4   ,y5   ,y5   ,y6   ,y6   ,y7   ,y7   };
Index: /issm/trunk/test/NightlyRun/test514.py
===================================================================
--- /issm/trunk/test/NightlyRun/test514.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test514.py	(revision 17806)
@@ -55,5 +55,5 @@
 #Fields and tolerances to track changes
 field_names     =['x1','y1','x2','y2','x3','y3','x4','y4','x5','y5','x6','y6','x7','y7']
-field_tolerances=[1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13]
+field_tolerances = [2e-10,7e-10,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13]
 field_values=[\
 	x1, y1,\
Index: /issm/trunk/test/NightlyRun/test515.m
===================================================================
--- /issm/trunk/test/NightlyRun/test515.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test515.m	(revision 17806)
@@ -15,5 +15,5 @@
 field_names     ={'Temperature1','BasalforcingsMeltingRate1', ...
 				      'Temperature2','BasalforcingsMeltingRate2'};
-field_tolerances={1e-13,1e-8,1e-13,1e-8};
+field_tolerances={1e-13,1e-8,1e-13,3e-8};
 field_values={...
 	(md.results.TransientSolution(1).Temperature),...
Index: /issm/trunk/test/NightlyRun/test515.py
===================================================================
--- /issm/trunk/test/NightlyRun/test515.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test515.py	(revision 17806)
@@ -24,5 +24,5 @@
 field_names     =['Temperature1','BasalforcingsMeltingRate1', \
 				      'Temperature2','BasalforcingsMeltingRate2']
-field_tolerances=[1e-13,1e-8,1e-13,1e-8]
+field_tolerances=[1e-13,1e-8,1e-13,2e-8]
 field_values=[\
 	md.results.TransientSolution[0].Temperature,\
Index: /issm/trunk/test/NightlyRun/test608.m
===================================================================
--- /issm/trunk/test/NightlyRun/test608.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test608.m	(revision 17806)
@@ -8,5 +8,5 @@
 %Fields and tolerances to track changes
 field_names     ={'Thickness'};
-field_tolerances={1e-13};
+field_tolerances={1e-12};
 field_values={...
 	(md.results.BalancethicknessSolution.Thickness),...
Index: /issm/trunk/test/NightlyRun/test608.py
===================================================================
--- /issm/trunk/test/NightlyRun/test608.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test608.py	(revision 17806)
@@ -18,5 +18,5 @@
 #Fields and tolerances to track changes
 field_names     =['Thickness']
-field_tolerances=[1e-13]
+field_tolerances=[1e-12]
 field_values=[\
 	md.results.BalancethicknessSolution.Thickness,\
Index: /issm/trunk/test/NightlyRun/test610.m
===================================================================
--- /issm/trunk/test/NightlyRun/test610.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test610.m	(revision 17806)
@@ -9,5 +9,5 @@
 %Fields and tolerances to track changes
 field_names     ={'Thickness'};
-field_tolerances={1e-13};
+field_tolerances={1e-12};
 field_values={...
 	(md.results.BalancethicknessSolution.Thickness),...
Index: /issm/trunk/test/NightlyRun/test610.py
===================================================================
--- /issm/trunk/test/NightlyRun/test610.py	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test610.py	(revision 17806)
@@ -19,5 +19,5 @@
 #Fields and tolerances to track changes
 field_names     =['Thickness']
-field_tolerances=[1e-13]
+field_tolerances=[1e-12]
 field_values=[\
 	md.results.BalancethicknessSolution.Thickness,\
Index: sm/trunk/test/NightlyRun/test612.m
===================================================================
--- /issm/trunk/test/NightlyRun/test612.m	(revision 17805)
+++ 	(revision )
@@ -1,32 +1,0 @@
-md=triangle(model(),'../Exp/79North.exp',10000.);
-md=meshconvert(md);
-md=setmask(md,'../Exp/79NorthShelf.exp','');
-md=parameterize(md,'../Par/79North.par');
-md=setflowequation(md,'SSA','all');
-
-%control parameters
-md.inversion.nsteps=2;
-md.balancethickness.stabilization=3;
-md.inversion.iscontrol=1;
-md.inversion.control_parameters={'BalancethicknessThickeningRate'};
-md.inversion.thickness_obs=md.geometry.thickness;
-md.inversion.min_parameters=-50.*ones(md.mesh.numberofvertices,1);
-md.inversion.max_parameters=50.*ones(md.mesh.numberofvertices,1);
-md.inversion.cost_functions=201;
-md.inversion.cost_functions_coefficients=ones(md.mesh.numberofvertices,1);
-md.inversion.gradient_scaling=10./md.constants.yts*ones(md.inversion.nsteps,1);
-md.inversion.maxiter_per_step=4*ones(md.inversion.nsteps,1);
-md.inversion.step_threshold=0.99*ones(md.inversion.nsteps,1);
-
-md.cluster=generic('name',oshostname(),'np',3);
-md=solve(md,BalancethicknessSolutionEnum());
-
-%Fields and tolerances to track changes
-field_names     ={'Gradient','Misfits','BalancethicknessThickeningRate','Thickness'};
-field_tolerances={1e-12,1e-12,1e-12,1e-12,1e-12,1e-12};
-field_values={...
-	(md.results.BalancethicknessSolution.Gradient1),...
-	md.results.BalancethicknessSolution.J,...
-	(md.results.BalancethicknessSolution.BalancethicknessThickeningRate),...
-	(md.results.BalancethicknessSolution.Thickness)
-};
Index: sm/trunk/test/NightlyRun/test612.py
===================================================================
--- /issm/trunk/test/NightlyRun/test612.py	(revision 17805)
+++ 	(revision )
@@ -1,43 +1,0 @@
-import numpy
-from model import *
-from EnumDefinitions import *
-from MatlabFuncs import *
-from triangle import *
-from meshconvert import *
-from setmask import *
-from parameterize import *
-from setflowequation import *
-from solve import *
-
-md=triangle(model(),'../Exp/79North.exp',10000.)
-md=meshconvert(md)
-md=setmask(md,'../Exp/79NorthShelf.exp','')
-md=parameterize(md,'../Par/79North.py')
-md=setflowequation(md,'SSA','all')
-
-#control parameters
-md.inversion.nsteps=2
-md.balancethickness.stabilization=3
-md.inversion.iscontrol=1
-md.inversion.control_parameters=['BalancethicknessThickeningRate']
-md.inversion.thickness_obs=md.geometry.thickness
-md.inversion.min_parameters=-50.*numpy.ones((md.mesh.numberofvertices,1))
-md.inversion.max_parameters=50.*numpy.ones((md.mesh.numberofvertices,1))
-md.inversion.cost_functions=[201]
-md.inversion.cost_functions_coefficients=numpy.ones((md.mesh.numberofvertices,1))
-md.inversion.gradient_scaling=10./md.constants.yts*numpy.ones((md.inversion.nsteps,1))
-md.inversion.maxiter_per_step=4*numpy.ones((md.inversion.nsteps,1))
-md.inversion.step_threshold=0.99*numpy.ones((md.inversion.nsteps,1))
-
-md.cluster=generic('name',oshostname(),'np',3)
-md=solve(md,BalancethicknessSolutionEnum())
-
-#Fields and tolerances to track changes
-field_names     =['Gradient','Misfits','BalancethicknessThickeningRate','Thickness']
-field_tolerances=[1e-12,1e-12,1e-12,1e-12,1e-12,1e-12]
-field_values=[\
-	md.results.BalancethicknessSolution.Gradient1,\
-	md.results.BalancethicknessSolution.J,\
-	md.results.BalancethicknessSolution.BalancethicknessThickeningRate,\
-	md.results.BalancethicknessSolution.Thickness
-]
Index: /issm/trunk/test/NightlyRun/test701.m
===================================================================
--- /issm/trunk/test/NightlyRun/test701.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test701.m	(revision 17806)
@@ -7,9 +7,9 @@
 %Geometry
 md.geometry.surface   = interp1(x,b+h,md.mesh.x);
-md.geometry.bed       = interp1(x,b,md.mesh.x);
-md.geometry.thickness = md.geometry.surface-md.geometry.bed;
+md.geometry.base       = interp1(x,b,md.mesh.x);
+md.geometry.thickness = md.geometry.surface-md.geometry.base;
 
 %mask
-md.mask.ice_levelset  = ones(md.mesh.numberofvertices,1);
+md.mask.ice_levelset  = - ones(md.mesh.numberofvertices,1);
 md.mask.ice_levelset(find(vertexflags(md.mesh,2))) = 0;
 md.mask.groundedice_levelset = double(md.mesh.x<0)-.5;
@@ -19,6 +19,4 @@
 md.materials.rheology_B=paterson(md.initialization.temperature);
 md.materials.rheology_n=3*ones(md.mesh.numberofelements,1);
-md.damage.D=zeros(md.mesh.numberofvertices,1);
-md.damage.spcdamage=NaN(md.mesh.numberofvertices,1);
 
 %friction
@@ -51,5 +49,5 @@
 %Fields and tolerances to track changes
 field_names     ={'Vx','Vy','Vel','Pressure'};
-field_tolerances={1e-13,1e-13,1e-13,1e-13};
+field_tolerances={5e-10,2e-9,2e-9,1e-10};
 field_values={...
 	(md.results.StressbalanceSolution.Vx),...
Index: /issm/trunk/test/NightlyRun/test702.m
===================================================================
--- /issm/trunk/test/NightlyRun/test702.m	(revision 17805)
+++ /issm/trunk/test/NightlyRun/test702.m	(revision 17806)
@@ -11,7 +11,7 @@
 %parameterize
 md.geometry.surface   = interp1(x,b+h,md.mesh.x);
-md.geometry.bed       = interp1(x,b,md.mesh.x);
-md.geometry.thickness = md.geometry.surface-md.geometry.bed;
-md.mask.ice_levelset = ones(md.mesh.numberofvertices,1);
+md.geometry.base       = interp1(x,b,md.mesh.x);
+md.geometry.thickness = md.geometry.surface-md.geometry.base;
+md.mask.ice_levelset = - ones(md.mesh.numberofvertices,1);
 md.mask.ice_levelset(find(vertexflags(md.mesh,2))) = 0;
 md.mask.groundedice_levelset = double(md.mesh.x<0)-.5;
@@ -46,5 +46,5 @@
 %Fields and tolerances to track changes
 field_names     ={'Vx','Vy','Vel','Pressure'};
-field_tolerances={1e-09,1e-09,1e-09,1e-09};
+field_tolerances={2e-08,2e-08,2e-08,2e-08};
 field_values={...
 	(md.results.StressbalanceSolution.Vx),...
Index: /issm/trunk/test/NightlyRun/test703.m
===================================================================
--- /issm/trunk/test/NightlyRun/test703.m	(revision 17806)
+++ /issm/trunk/test/NightlyRun/test703.m	(revision 17806)
@@ -0,0 +1,123 @@
+%mesh parameters
+x =[-5:.5:5]';
+[b h sea]=NowickiProfile(x);
+x = x*10^3;
+h = h*10^3;
+b = (b-sea)*10^3;
+
+%mesh domain
+md=bamgflowband(model(),x,b+h,b,'hmax',150);
+
+%parameterize
+md.geometry.surface   = interp1(x,b+h,md.mesh.x);
+md.geometry.base       = interp1(x,b,md.mesh.x);
+md.geometry.thickness = md.geometry.surface-md.geometry.base;
+md.mask.ice_levelset  = - ones(md.mesh.numberofvertices,1);
+md.mask.ice_levelset(find(vertexflags(md.mesh,2))) = 0;
+md.mask.groundedice_levelset = double(md.mesh.x<0)-.5;
+
+md.initialization.temperature=(273.-20.)*ones(md.mesh.numberofvertices,1);
+md.materials.rheology_B=paterson(md.initialization.temperature);
+md.materials.rheology_n=3*ones(md.mesh.numberofelements,1);
+md.friction.coefficient=zeros(md.mesh.numberofvertices,1);
+md.friction.coefficient(find(vertexflags(md.mesh,1)))=20;
+md.friction.p=ones(md.mesh.numberofelements,1);
+md.friction.q=ones(md.mesh.numberofelements,1);
+md.stressbalance.spcvx=NaN*ones(md.mesh.numberofvertices,1);
+md.stressbalance.spcvy=NaN*ones(md.mesh.numberofvertices,1);
+md.stressbalance.spcvz=NaN*ones(md.mesh.numberofvertices,1);
+md.stressbalance.referential=NaN*ones(md.mesh.numberofvertices,6);
+md.stressbalance.loadingforce=0*ones(md.mesh.numberofvertices,3);
+md.stressbalance.spcvx(find(vertexflags(md.mesh,4)))=800;
+md.stressbalance.spcvy(find(vertexflags(md.mesh,4)))=0;
+
+%Misc
+md=setflowequation(md,'FS','all');
+md.flowequation.fe_FS='TaylorHood';
+md.stressbalance.abstol=NaN;
+md.miscellaneous.name = 'flowline';
+
+%Transient settings
+md.timestepping.time_step=0.000001;
+md.timestepping.final_time=0.000005;
+md.stressbalance.shelf_dampening=1;
+md.surfaceforcings.mass_balance=zeros(md.mesh.numberofvertices,1);
+md.basalforcings.melting_rate=zeros(md.mesh.numberofvertices,1);
+md.basalforcings.geothermalflux=zeros(md.mesh.numberofvertices,1);
+posb=find((md.mesh.x>0) & md.mesh.vertexonbase);
+md.basalforcings.melting_rate(posb)=18;
+md.initialization.vx=zeros(md.mesh.numberofvertices,1);
+md.initialization.vy=zeros(md.mesh.numberofvertices,1);
+md.initialization.pressure=zeros(md.mesh.numberofvertices,1);
+md.masstransport.spcthickness=NaN*ones(md.mesh.numberofvertices,1);
+md.thermal.spctemperature=NaN*ones(md.mesh.numberofvertices,1);
+md.transient.isthermal=0;
+md.masstransport.isfreesurface=1;
+
+%Go solve
+md.cluster=generic('np',3);
+md.stressbalance.shelf_dampening=1;
+md1=solve(md,TransientSolutionEnum());
+
+md.stressbalance.shelf_dampening=0;
+md=solve(md,TransientSolutionEnum());
+
+%Fields and tolerances to track changes
+field_names     ={...
+	'Vx1','Vy1','Vel1','Pressure1','Bed1','Surface1','Thickness1',...
+	'Vx2','Vy2','Vel2','Pressure2','Bed2','Surface2','Thickness2',...
+	'Vx3','Vy3','Vel3','Pressure3','Bed3','Surface3','Thickness3',...
+	'Vx1_damp','Vy1_damp','Vel1_damp','Pressure1_damp','Bed1_damp','Surface1_damp','Thickness1_damp',...
+	'Vx2_damp','Vy2_damp','Vel2_damp','Pressure2_damp','Bed2_damp','Surface2_damp','Thickness2_damp',...
+	'Vx3_damp','Vy3_damp','Vel3_damp','Pressure3_damp','Bed3_damp','Surface3_damp','Thickness3_damp'};
+field_tolerances={...
+	1e-08,1e-08,1e-08,1e-08,1e-10,1e-10,1e-10,...
+	1e-08,1e-08,1e-08,1e-08,1e-10,1e-10,1e-10,...
+	1e-08,1e-08,1e-08,1e-08,1e-10,1e-10,1e-10,...
+	1e-08,1e-08,1e-08,1e-08,1e-10,1e-10,1e-10,...
+	1e-08,1e-08,1e-08,1e-08,1e-10,1e-10,1e-10,...
+	1e-08,1e-08,1e-08,1e-08,1e-10,1e-10,1e-10};
+field_values={...
+	(md.results.TransientSolution(1).Vx),...
+	(md.results.TransientSolution(1).Vy),...
+	(md.results.TransientSolution(1).Vel),...
+	(md.results.TransientSolution(1).Pressure),...
+	(md.results.TransientSolution(1).Base),...
+	(md.results.TransientSolution(1).Surface),...
+	(md.results.TransientSolution(1).Thickness),...
+	(md.results.TransientSolution(2).Vx),...
+	(md.results.TransientSolution(2).Vy),...
+	(md.results.TransientSolution(2).Vel),...
+	(md.results.TransientSolution(2).Pressure),...
+	(md.results.TransientSolution(2).Base),...
+	(md.results.TransientSolution(2).Surface),...
+	(md.results.TransientSolution(2).Thickness),...
+	(md.results.TransientSolution(3).Vx),...
+	(md.results.TransientSolution(3).Vy),...
+	(md.results.TransientSolution(3).Vel),...
+	(md.results.TransientSolution(3).Pressure),...
+	(md.results.TransientSolution(3).Base),...
+	(md.results.TransientSolution(3).Surface),...
+	(md.results.TransientSolution(3).Thickness),...
+	(md1.results.TransientSolution(1).Vx),...
+	(md1.results.TransientSolution(1).Vy),...
+	(md1.results.TransientSolution(1).Vel),...
+	(md1.results.TransientSolution(1).Pressure),...
+	(md1.results.TransientSolution(1).Base),...
+	(md1.results.TransientSolution(1).Surface),...
+	(md1.results.TransientSolution(1).Thickness),...
+	(md1.results.TransientSolution(2).Vx),...
+	(md1.results.TransientSolution(2).Vy),...
+	(md1.results.TransientSolution(2).Vel),...
+	(md1.results.TransientSolution(2).Pressure),...
+	(md1.results.TransientSolution(2).Base),...
+	(md1.results.TransientSolution(2).Surface),...
+	(md1.results.TransientSolution(2).Thickness),...
+	(md1.results.TransientSolution(3).Vx),...
+	(md1.results.TransientSolution(3).Vy),...
+	(md1.results.TransientSolution(3).Vel),...
+	(md1.results.TransientSolution(3).Pressure),...
+	(md1.results.TransientSolution(3).Base),...
+	(md1.results.TransientSolution(3).Surface),...
+	(md1.results.TransientSolution(3).Thickness),...
+	};
Index: /issm/trunk/test/NightlyRun/test801.m
===================================================================
--- /issm/trunk/test/NightlyRun/test801.m	(revision 17806)
+++ /issm/trunk/test/NightlyRun/test801.m	(revision 17806)
@@ -0,0 +1,46 @@
+md=triangle(model(),'../Exp/Square.exp',50000);
+md=setmask(md,'','');
+md=parameterize(md,'../Par/ValleyGlacierShelf.par');
+md=setflowequation(md,'SSA','all');
+md.cluster=generic('name',oshostname(),'np',3);
+
+%Transient;
+md.transient.isstressbalance=1;
+md.transient.islevelset=1;
+md.transient.ismasstransport=1;
+md.transient.isthermal=0;
+md.transient.isgroundingline=1;
+md.transient.isgia=0;
+
+md=solve(md,TransientSolutionEnum());
+
+%Fields and tolerances to track changes
+field_names     ={'Vx1','Vy1','Vel1','Pressure1','Thickness1','Surface1','MaskIceLevelset1',...
+		'Vx2','Vy2','Vel2','Pressure2','Thickness2','Surface2','MaskIceLevelset2',...
+		'Vx3','Vy3','Vel3','Pressure3','Thickness3','Surface3','MaskIceLevelset3'};
+field_tolerances={1e-12,1e-12,1e-12,1e-12,1e-12,1e-12,1e-12,...
+		1e-12,1e-12,1e-12,1e-12,1e-12,1e-12,1e-12,...
+		1e-12,1e-12,1e-12,1e-12,1e-12,1e-12,1e-12};
+field_values={...
+	md.results.TransientSolution(1).Vx,...
+	md.results.TransientSolution(1).Vy,...
+	md.results.TransientSolution(1).Vel,...
+	md.results.TransientSolution(1).Pressure,...
+	md.results.TransientSolution(1).Thickness,...
+	md.results.TransientSolution(1).Surface,...
+	md.results.TransientSolution(1).MaskIceLevelset,...
+	md.results.TransientSolution(2).Vx,...
+	md.results.TransientSolution(2).Vy,...
+	md.results.TransientSolution(2).Vel,...
+	md.results.TransientSolution(2).Pressure,...
+	md.results.TransientSolution(2).Thickness,...
+	md.results.TransientSolution(2).Surface,...
+	md.results.TransientSolution(2).MaskIceLevelset,...
+	md.results.TransientSolution(3).Vx,...
+	md.results.TransientSolution(3).Vy,...
+	md.results.TransientSolution(3).Vel,...
+	md.results.TransientSolution(3).Pressure,...
+	md.results.TransientSolution(3).Thickness,...
+	md.results.TransientSolution(3).Surface,...
+	md.results.TransientSolution(3).MaskIceLevelset,...
+	};
Index: /issm/trunk/test/NightlyRun/test801.py
===================================================================
--- /issm/trunk/test/NightlyRun/test801.py	(revision 17806)
+++ /issm/trunk/test/NightlyRun/test801.py	(revision 17806)
@@ -0,0 +1,56 @@
+from model import *
+from triangle import *
+from squaremesh import *
+from setmask import *
+from parameterize import *
+from setflowequation import *
+from EnumDefinitions import *
+from solve import *
+from MatlabFuncs import *
+
+md=triangle(model(),'../Exp/Square.exp',50000)
+md=setmask(md,'','')
+md=parameterize(md,'../Par/ValleyGlacierShelf.py')
+md=setflowequation(md,'SSA','all')
+md.cluster=generic('name',oshostname(),'np',3)
+
+#Transient
+md.transient.isstressbalance=True
+md.transient.islevelset=True
+md.transient.ismasstransport=True
+md.transient.isthermal=False
+md.transient.isgroundingline=True
+md.transient.isgia=False
+
+md=solve(md,TransientSolutionEnum())
+
+#Fields and tolerances to track changes
+field_names     =['Vx1','Vy1','Vel1','Pressure1','Thickness1','Surface1','MaskIceLevelset1',\
+		'Vx2','Vy2','Vel2','Pressure2','Thickness2','Surface2','MaskIceLevelset2',\
+		'Vx3','Vy3','Vel3','Pressure3','Thickness3','Surface3','MaskIceLevelset3']
+field_tolerances=[1e-12,1e-12,1e-12,1e-12,1e-12,1e-12,1e-12,\
+		1e-12,1e-12,1e-12,1e-12,1e-12,1e-12,1e-12,\
+		1e-12,1e-12,1e-12,1e-12,1e-12,1e-12,1e-12]
+field_values=[\
+	md.results.TransientSolution[0].Vx,\
+	md.results.TransientSolution[0].Vy,\
+	md.results.TransientSolution[0].Vel,\
+	md.results.TransientSolution[0].Pressure,\
+	md.results.TransientSolution[0].Thickness,\
+	md.results.TransientSolution[0].Surface,\
+	md.results.TransientSolution[0].MaskIceLevelset,\
+	md.results.TransientSolution[1].Vx,\
+	md.results.TransientSolution[1].Vy,\
+	md.results.TransientSolution[1].Vel,\
+	md.results.TransientSolution[1].Pressure,\
+	md.results.TransientSolution[1].Thickness,\
+	md.results.TransientSolution[1].Surface,\
+	md.results.TransientSolution[1].MaskIceLevelset,\
+	md.results.TransientSolution[2].Vx,\
+	md.results.TransientSolution[2].Vy,\
+	md.results.TransientSolution[2].Vel,\
+	md.results.TransientSolution[2].Pressure,\
+	md.results.TransientSolution[2].Thickness,\
+	md.results.TransientSolution[2].Surface,\
+	md.results.TransientSolution[2].MaskIceLevelset,\
+	]
Index: /issm/trunk/test/NightlyRun/test802.m
===================================================================
--- /issm/trunk/test/NightlyRun/test802.m	(revision 17806)
+++ /issm/trunk/test/NightlyRun/test802.m	(revision 17806)
@@ -0,0 +1,54 @@
+md=triangle(model(),'../Exp/Square.exp',50000);
+md=setmask(md,'','');
+md=parameterize(md,'../Par/ValleyGlacierShelf.par');
+md=extrude(md,3,2.);
+md=setflowequation(md,'SSA','all');
+md.cluster=generic('name',oshostname(),'np',3);
+
+%Thermal model
+pos_surf=find(md.mesh.vertexonsurface);
+md.thermal.spctemperature(pos_surf)=md.initialization.temperature(pos_surf);
+
+%Transient
+md.transient.isstressbalance=1;
+md.transient.islevelset=1;
+md.transient.ismasstransport=1;
+md.transient.isthermal=1;
+md.transient.isgroundingline=1;
+md.transient.isgia=0;
+
+md=solve(md,TransientSolutionEnum());
+
+%Fields and tolerances to track changes
+field_names     ={'Vx1','Vy1','Vel1','Pressure1','Thickness1','Surface1','MaskIceLevelset1','Temperature1',...
+		'Vx2','Vy2','Vel2','Pressure2','Thickness2','Surface2','MaskIceLevelset2','Temperature2',...
+		'Vx3','Vy3','Vel3','Pressure3','Thickness3','Surface3','MaskIceLevelset3','Temperature3'};
+field_tolerances={1e-12,1e-12,1e-12,1e-12,1e-12,1e-12,1e-12,1e-12,...
+		1e-10,1e-10,1e-10,1e-10,1e-10,1e-10,1e-10,1e-10,...
+		1e-11,1e-11,1e-11,1e-11,1e-11,1e-11,1e-11,1e-11};
+field_values={...
+	md.results.TransientSolution(1).Vx,...
+	md.results.TransientSolution(1).Vy,...
+	md.results.TransientSolution(1).Vel,...
+	md.results.TransientSolution(1).Pressure,...
+	md.results.TransientSolution(1).Thickness,...
+	md.results.TransientSolution(1).Surface,...
+	md.results.TransientSolution(1).MaskIceLevelset,...
+	md.results.TransientSolution(1).Temperature,...
+	md.results.TransientSolution(2).Vx,...
+	md.results.TransientSolution(2).Vy,...
+	md.results.TransientSolution(2).Vel,...
+	md.results.TransientSolution(2).Pressure,...
+	md.results.TransientSolution(2).Thickness,...
+	md.results.TransientSolution(2).Surface,...
+	md.results.TransientSolution(2).MaskIceLevelset,...
+	md.results.TransientSolution(2).Temperature,...
+	md.results.TransientSolution(3).Vx,...
+	md.results.TransientSolution(3).Vy,...
+	md.results.TransientSolution(3).Vel,...
+	md.results.TransientSolution(3).Pressure,...
+	md.results.TransientSolution(3).Thickness,...
+	md.results.TransientSolution(3).Surface,...
+	md.results.TransientSolution(3).MaskIceLevelset,...
+	md.results.TransientSolution(3).Temperature,...
+	};
Index: /issm/trunk/test/NightlyRun/test802.py
===================================================================
--- /issm/trunk/test/NightlyRun/test802.py	(revision 17806)
+++ /issm/trunk/test/NightlyRun/test802.py	(revision 17806)
@@ -0,0 +1,64 @@
+from model import *
+from triangle import *
+from squaremesh import *
+from setmask import *
+from parameterize import *
+from setflowequation import *
+from EnumDefinitions import *
+from solve import *
+from MatlabFuncs import *
+
+md=triangle(model(),'../Exp/Square.exp',50000)
+md=setmask(md,'','')
+md=parameterize(md,'../Par/ValleyGlacierShelf.py')
+md.extrude(3,2.)
+md=setflowequation(md,'SSA','all')
+md.cluster=generic('name',oshostname(),'np',3)
+
+#Thermal model
+pos_surf=numpy.nonzero(md.mesh.vertexonsurface)[0]
+md.thermal.spctemperature[pos_surf]=md.initialization.temperature[pos_surf]
+
+#Transient
+md.transient.isstressbalance=True
+md.transient.islevelset=True
+md.transient.ismasstransport=True
+md.transient.isthermal=True
+md.transient.isgroundingline=True
+md.transient.isgia=False
+
+md=solve(md,TransientSolutionEnum())
+
+#Fields and tolerances to track changes
+field_names     =['Vx1','Vy1','Vel1','Pressure1','Thickness1','Surface1','MaskIceLevelset1','Temperature1',\
+		'Vx2','Vy2','Vel2','Pressure2','Thickness2','Surface2','MaskIceLevelset2','Temperature2',\
+		'Vx3','Vy3','Vel3','Pressure3','Thickness3','Surface3','MaskIceLevelset3','Temperature3']
+field_tolerances=[1e-12,1e-12,1e-12,1e-12,1e-12,1e-12,1e-12,1e-12,\
+		1e-10,1e-10,1e-10,1e-10,1e-10,1e-10,1e-10,1e-10,\
+		1e-10,1e-10,1e-10,1e-10,1e-10,1e-10,1e-10,1e-10]
+field_values=[\
+	md.results.TransientSolution[0].Vx,\
+	md.results.TransientSolution[0].Vy,\
+	md.results.TransientSolution[0].Vel,\
+	md.results.TransientSolution[0].Pressure,\
+	md.results.TransientSolution[0].Thickness,\
+	md.results.TransientSolution[0].Surface,\
+	md.results.TransientSolution[0].MaskIceLevelset,\
+	md.results.TransientSolution[0].Temperature,\
+	md.results.TransientSolution[1].Vx,\
+	md.results.TransientSolution[1].Vy,\
+	md.results.TransientSolution[1].Vel,\
+	md.results.TransientSolution[1].Pressure,\
+	md.results.TransientSolution[1].Thickness,\
+	md.results.TransientSolution[1].Surface,\
+	md.results.TransientSolution[1].MaskIceLevelset,\
+	md.results.TransientSolution[1].Temperature,\
+	md.results.TransientSolution[2].Vx,\
+	md.results.TransientSolution[2].Vy,\
+	md.results.TransientSolution[2].Vel,\
+	md.results.TransientSolution[2].Pressure,\
+	md.results.TransientSolution[2].Thickness,\
+	md.results.TransientSolution[2].Surface,\
+	md.results.TransientSolution[2].MaskIceLevelset,\
+	md.results.TransientSolution[2].Temperature,\
+	]
Index: /issm/trunk/test/NightlyRun/test803.m
===================================================================
--- /issm/trunk/test/NightlyRun/test803.m	(revision 17806)
+++ /issm/trunk/test/NightlyRun/test803.m	(revision 17806)
@@ -0,0 +1,59 @@
+md=triangle(model(),'../Exp/Square.exp',50000);
+md=setmask(md,'','');
+md=parameterize(md,'../Par/ValleyGlacierShelf.par');
+md=extrude(md,3,2.);
+md=setflowequation(md,'HO','all');
+md.cluster=generic('name',oshostname(),'np',3);
+
+%Thermal model
+pos_surf=find(md.mesh.vertexonsurface);
+md.thermal.spctemperature(pos_surf)=md.initialization.temperature(pos_surf);
+md.thermal.isenthalpy=1;
+md.thermal.isdynamicbasalspc=1;
+
+%Transient
+md.transient.isstressbalance=1;
+md.transient.islevelset=1;
+md.transient.ismasstransport=1;
+md.transient.isthermal=1;
+md.transient.isgroundingline=1;
+md.transient.isgia=0;
+
+md=solve(md,TransientSolutionEnum());
+
+%Fields and tolerances to track changes
+field_names     ={'Vx1','Vy1','Vel1','Pressure1','Thickness1','Surface1','MaskIceLevelset1','Enthalpy1','Watercolumn1',...
+		'Vx2','Vy2','Vel2','Pressure2','Thickness2','Surface2','MaskIceLevelset2','Enthalpy2','Watercolumn2',...
+		'Vx3','Vy3','Vel3','Pressure3','Thickness3','Surface3','MaskIceLevelset3','Enthalpy3','Watercolumn3'};
+field_tolerances={1e-10,1e-10,1e-10,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,...
+		1e-10,1e-10,1e-10,1e-10,1e-10,1e-10,1e-10,1e-10,1e-10,...
+		1e-10,1e-10,1e-10,1e-10,1e-10,1e-10,1e-10,1e-10,1e-10};
+field_values={...
+	md.results.TransientSolution(1).Vx,...
+	md.results.TransientSolution(1).Vy,...
+	md.results.TransientSolution(1).Vel,...
+	md.results.TransientSolution(1).Pressure,...
+	md.results.TransientSolution(1).Thickness,...
+	md.results.TransientSolution(1).Surface,...
+	md.results.TransientSolution(1).MaskIceLevelset,...
+	md.results.TransientSolution(1).Enthalpy,...
+	md.results.TransientSolution(1).Watercolumn,...
+	md.results.TransientSolution(2).Vx,...
+	md.results.TransientSolution(2).Vy,...
+	md.results.TransientSolution(2).Vel,...
+	md.results.TransientSolution(2).Pressure,...
+	md.results.TransientSolution(2).Thickness,...
+	md.results.TransientSolution(2).Surface,...
+	md.results.TransientSolution(2).MaskIceLevelset,...
+	md.results.TransientSolution(2).Enthalpy,...
+	md.results.TransientSolution(2).Watercolumn,...
+	md.results.TransientSolution(3).Vx,...
+	md.results.TransientSolution(3).Vy,...
+	md.results.TransientSolution(3).Vel,...
+	md.results.TransientSolution(3).Pressure,...
+	md.results.TransientSolution(3).Thickness,...
+	md.results.TransientSolution(3).Surface,...
+	md.results.TransientSolution(3).MaskIceLevelset,...
+	md.results.TransientSolution(3).Enthalpy,...
+	md.results.TransientSolution(3).Watercolumn,...
+	};
Index: /issm/trunk/test/NightlyRun/test803.py
===================================================================
--- /issm/trunk/test/NightlyRun/test803.py	(revision 17806)
+++ /issm/trunk/test/NightlyRun/test803.py	(revision 17806)
@@ -0,0 +1,69 @@
+from model import *
+from triangle import *
+from squaremesh import *
+from setmask import *
+from parameterize import *
+from setflowequation import *
+from EnumDefinitions import *
+from solve import *
+from MatlabFuncs import *
+
+md=triangle(model(),'../Exp/Square.exp',50000)
+md=setmask(md,'','')
+md=parameterize(md,'../Par/ValleyGlacierShelf.py')
+md.extrude(3,2.)
+md=setflowequation(md,'HO','all')
+md.cluster=generic('name',oshostname(),'np',3)
+
+#Thermal model
+pos_surf=numpy.nonzero(md.mesh.vertexonsurface)[0]
+md.thermal.spctemperature[pos_surf]=md.initialization.temperature[pos_surf]
+md.thermal.isenthalpy=True
+md.thermal.isdynamicbasalspc=True
+
+#Transient
+md.transient.isstressbalance=True
+md.transient.islevelset=True
+md.transient.ismasstransport=True
+md.transient.isthermal=True
+md.transient.isgroundingline=True
+md.transient.isgia=False
+
+md=solve(md,TransientSolutionEnum())
+
+#Fields and tolerances to track changes
+field_names     =['Vx1','Vy1','Vel1','Pressure1','Thickness1','Surface1','MaskIceLevelset1','Enthalpy1','Watercolumn1',\
+		'Vx2','Vy2','Vel2','Pressure2','Thickness2','Surface2','MaskIceLevelset2','Enthalpy2','Watercolumn2',\
+		'Vx3','Vy3','Vel3','Pressure3','Thickness3','Surface3','MaskIceLevelset3','Enthalpy3','Watercolumn3']
+field_tolerances=[1e-10,1e-10,1e-10,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,\
+		1e-10,1e-10,1e-10,1e-10,1e-10,1e-10,1e-10,1e-10,1e-10,\
+		1e-10,1e-10,1e-10,1e-10,1e-10,1e-10,1e-10,1e-10,1e-10]
+field_values=[\
+	md.results.TransientSolution[0].Vx,\
+	md.results.TransientSolution[0].Vy,\
+	md.results.TransientSolution[0].Vel,\
+	md.results.TransientSolution[0].Pressure,\
+	md.results.TransientSolution[0].Thickness,\
+	md.results.TransientSolution[0].Surface,\
+	md.results.TransientSolution[0].MaskIceLevelset,\
+	md.results.TransientSolution[0].Enthalpy,\
+	md.results.TransientSolution[0].Watercolumn,\
+	md.results.TransientSolution[1].Vx,\
+	md.results.TransientSolution[1].Vy,\
+	md.results.TransientSolution[1].Vel,\
+	md.results.TransientSolution[1].Pressure,\
+	md.results.TransientSolution[1].Thickness,\
+	md.results.TransientSolution[1].Surface,\
+	md.results.TransientSolution[1].MaskIceLevelset,\
+	md.results.TransientSolution[1].Enthalpy,\
+	md.results.TransientSolution[1].Watercolumn,\
+	md.results.TransientSolution[2].Vx,\
+	md.results.TransientSolution[2].Vy,\
+	md.results.TransientSolution[2].Vel,\
+	md.results.TransientSolution[2].Pressure,\
+	md.results.TransientSolution[2].Thickness,\
+	md.results.TransientSolution[2].Surface,\
+	md.results.TransientSolution[2].MaskIceLevelset,\
+	md.results.TransientSolution[2].Enthalpy,\
+	md.results.TransientSolution[2].Watercolumn,\
+	]
Index: /issm/trunk/test/NightlyRun/test804.m
===================================================================
--- /issm/trunk/test/NightlyRun/test804.m	(revision 17806)
+++ /issm/trunk/test/NightlyRun/test804.m	(revision 17806)
@@ -0,0 +1,48 @@
+md=triangle(model(),'../Exp/Square.exp',50000);
+md=setmask(md,'','');
+md=parameterize(md,'../Par/ValleyGlacierShelf.par');
+md=setflowequation(md,'SIA','all');
+md.cluster=generic('name',oshostname(),'np',3);
+
+%Transient
+md.transient.isstressbalance=1;
+md.transient.islevelset=1;
+md.transient.ismasstransport=1;
+md.transient.isthermal=0;
+md.transient.isgroundingline=1;
+md.transient.isgia=0;
+
+md.masstransport.calvingrate=1000.*ones(md.mesh.numberofvertices,1);
+
+md=solve(md,TransientSolutionEnum());
+
+%Fields and tolerances to track changes
+field_names     ={'Vx1','Vy1','Vel1','Pressure1','Thickness1','Surface1','MaskIceLevelset1',...
+		'Vx2','Vy2','Vel2','Pressure2','Thickness2','Surface2','MaskIceLevelset2',...
+		'Vx3','Vy3','Vel3','Pressure3','Thickness3','Surface3','MaskIceLevelset3'};
+field_tolerances={1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,...
+		1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,...
+		2e-13,2e-13,2e-13,1e-13,1e-13,1e-13,1e-13};
+field_values={...
+	md.results.TransientSolution(1).Vx,...
+	md.results.TransientSolution(1).Vy,...
+	md.results.TransientSolution(1).Vel,...
+	md.results.TransientSolution(1).Pressure,...
+	md.results.TransientSolution(1).Thickness,...
+	md.results.TransientSolution(1).Surface,...
+	md.results.TransientSolution(1).MaskIceLevelset,...
+	md.results.TransientSolution(2).Vx,...
+	md.results.TransientSolution(2).Vy,...
+	md.results.TransientSolution(2).Vel,...
+	md.results.TransientSolution(2).Pressure,...
+	md.results.TransientSolution(2).Thickness,...
+	md.results.TransientSolution(2).Surface,...
+	md.results.TransientSolution(2).MaskIceLevelset,...
+	md.results.TransientSolution(3).Vx,...
+	md.results.TransientSolution(3).Vy,...
+	md.results.TransientSolution(3).Vel,...
+	md.results.TransientSolution(3).Pressure,...
+	md.results.TransientSolution(3).Thickness,...
+	md.results.TransientSolution(3).Surface,...
+	md.results.TransientSolution(3).MaskIceLevelset,...
+	};
Index: /issm/trunk/test/NightlyRun/test804.py
===================================================================
--- /issm/trunk/test/NightlyRun/test804.py	(revision 17806)
+++ /issm/trunk/test/NightlyRun/test804.py	(revision 17806)
@@ -0,0 +1,59 @@
+from model import *
+from triangle import *
+from squaremesh import *
+from setmask import *
+from parameterize import *
+from setflowequation import *
+from EnumDefinitions import *
+from solve import *
+from MatlabFuncs import *
+
+md=triangle(model(),'../Exp/Square.exp',50000)
+md=setmask(md,'','')
+md=parameterize(md,'../Par/ValleyGlacierShelf.py')
+md=setflowequation(md,'SIA','all')
+md.cluster=generic('name',oshostname(),'np',3)
+
+#Transient
+md.transient.isstressbalance=True
+md.transient.islevelset=True
+md.transient.ismasstransport=True
+md.transient.isthermal=False
+md.transient.isgroundingline=True
+md.transient.isgia=False
+
+md.masstransport.calvingrate=1000.*numpy.ones((md.mesh.numberofvertices,1))
+
+md=solve(md,TransientSolutionEnum())
+
+#Fields and tolerances to track changes
+field_names     =['Vx1','Vy1','Vel1','Pressure1','Thickness1','Surface1','MaskIceLevelset1',\
+		'Vx2','Vy2','Vel2','Pressure2','Thickness2','Surface2','MaskIceLevelset2',\
+		'Vx3','Vy3','Vel3','Pressure3','Thickness3','Surface3','MaskIceLevelset3']
+field_tolerances=[1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,\
+		1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,\
+		2e-13,2e-13,2e-13,1e-13,1e-13,1e-13,1e-13]
+field_values=[\
+	md.results.TransientSolution[0].Vx,\
+	md.results.TransientSolution[0].Vy,\
+	md.results.TransientSolution[0].Vel,\
+	md.results.TransientSolution[0].Pressure,\
+	md.results.TransientSolution[0].Thickness,\
+	md.results.TransientSolution[0].Surface,\
+	md.results.TransientSolution[0].MaskIceLevelset,\
+	md.results.TransientSolution[1].Vx,\
+	md.results.TransientSolution[1].Vy,\
+	md.results.TransientSolution[1].Vel,\
+	md.results.TransientSolution[1].Pressure,\
+	md.results.TransientSolution[1].Thickness,\
+	md.results.TransientSolution[1].Surface,\
+	md.results.TransientSolution[1].MaskIceLevelset,\
+	md.results.TransientSolution[2].Vx,\
+	md.results.TransientSolution[2].Vy,\
+	md.results.TransientSolution[2].Vel,\
+	md.results.TransientSolution[2].Pressure,\
+	md.results.TransientSolution[2].Thickness,\
+	md.results.TransientSolution[2].Surface,\
+	md.results.TransientSolution[2].MaskIceLevelset,\
+
+	]
Index: /issm/trunk/test/NightlyRun/test805.m
===================================================================
--- /issm/trunk/test/NightlyRun/test805.m	(revision 17806)
+++ /issm/trunk/test/NightlyRun/test805.m	(revision 17806)
@@ -0,0 +1,61 @@
+md=triangle(model(),'../Exp/Square.exp',50000);
+md=setmask(md,'','');
+md=parameterize(md,'../Par/ValleyGlacierShelf.par');
+md=extrude(md,3,2.);
+md=setflowequation(md,'HO','all');
+md.cluster=generic('name',oshostname(),'np',3);
+
+%Thermal model
+pos_surf=find(md.mesh.vertexonsurface);
+md.thermal.spctemperature(pos_surf)=md.initialization.temperature(pos_surf);
+md.thermal.isenthalpy=1;
+md.thermal.isdynamicbasalspc=1;
+
+%Transient
+md.transient.isstressbalance=1;
+md.transient.islevelset=1;
+md.transient.ismasstransport=1;
+md.transient.isthermal=1;
+md.transient.isgroundingline=1;
+md.transient.isgia=0;
+
+md.masstransport.calvingrate=1000.*ones(md.mesh.numberofvertices,1);
+
+md=solve(md,TransientSolutionEnum());
+
+%Fields and tolerances to track changes
+field_names     ={'Vx1','Vy1','Vel1','Pressure1','Thickness1','Surface1','MaskIceLevelset1','Enthalpy1','Watercolumn1',...
+		'Vx2','Vy2','Vel2','Pressure2','Thickness2','Surface2','MaskIceLevelset2','Enthalpy2','Watercolumn2',...
+		'Vx3','Vy3','Vel3','Pressure3','Thickness3','Surface3','MaskIceLevelset3','Enthalpy3','Watercolumn3'};
+field_tolerances={1e-11,1e-11,1e-11,1e-11,1e-11,1e-11,1e-11,1e-11,1e-11,...
+		1e-10,1e-10,1e-10,1e-10,1e-10,1e-10,1e-10,1e-10,1e-10,...
+		1e-10,1e-10,1e-10,1e-10,1e-10,1e-10,1e-10,1e-10,1e-10};
+field_values={...
+	md.results.TransientSolution(1).Vx,...
+	md.results.TransientSolution(1).Vy,...
+	md.results.TransientSolution(1).Vel,...
+	md.results.TransientSolution(1).Pressure,...
+	md.results.TransientSolution(1).Thickness,...
+	md.results.TransientSolution(1).Surface,...
+	md.results.TransientSolution(1).MaskIceLevelset,...
+	md.results.TransientSolution(1).Enthalpy,...
+	md.results.TransientSolution(1).Watercolumn,...
+	md.results.TransientSolution(2).Vx,...
+	md.results.TransientSolution(2).Vy,...
+	md.results.TransientSolution(2).Vel,...
+	md.results.TransientSolution(2).Pressure,...
+	md.results.TransientSolution(2).Thickness,...
+	md.results.TransientSolution(2).Surface,...
+	md.results.TransientSolution(2).MaskIceLevelset,...
+	md.results.TransientSolution(2).Enthalpy,...
+	md.results.TransientSolution(2).Watercolumn,...
+	md.results.TransientSolution(3).Vx,...
+	md.results.TransientSolution(3).Vy,...
+	md.results.TransientSolution(3).Vel,...
+	md.results.TransientSolution(3).Pressure,...
+	md.results.TransientSolution(3).Thickness,...
+	md.results.TransientSolution(3).Surface,...
+	md.results.TransientSolution(3).MaskIceLevelset,...
+	md.results.TransientSolution(3).Enthalpy,...
+	md.results.TransientSolution(3).Watercolumn,...
+	};
Index: /issm/trunk/test/NightlyRun/test805.py
===================================================================
--- /issm/trunk/test/NightlyRun/test805.py	(revision 17806)
+++ /issm/trunk/test/NightlyRun/test805.py	(revision 17806)
@@ -0,0 +1,71 @@
+from model import *
+from triangle import *
+from squaremesh import *
+from setmask import *
+from parameterize import *
+from setflowequation import *
+from EnumDefinitions import *
+from solve import *
+from MatlabFuncs import *
+
+md=triangle(model(),'../Exp/Square.exp',50000)
+md=setmask(md,'','')
+md=parameterize(md,'../Par/ValleyGlacierShelf.py')
+md.extrude(3,2.)
+md=setflowequation(md,'HO','all')
+md.cluster=generic('name',oshostname(),'np',3)
+
+#Thermal model
+pos_surf=numpy.nonzero(md.mesh.vertexonsurface)[0]
+md.thermal.spctemperature[pos_surf]=md.initialization.temperature[pos_surf]
+md.thermal.isenthalpy=True
+md.thermal.isdynamicbasalspc=True
+
+#Transient
+md.transient.isstressbalance=True
+md.transient.islevelset=True
+md.transient.ismasstransport=True
+md.transient.isthermal=True
+md.transient.isgroundingline=True
+md.transient.isgia=False
+
+md.masstransport.calvingrate=1000.*numpy.ones((md.mesh.numberofvertices,1))
+
+md=solve(md,TransientSolutionEnum())
+
+#Fields and tolerances to track changes
+field_names     =['Vx1','Vy1','Vel1','Pressure1','Thickness1','Surface1','MaskIceLevelset1','Enthalpy1','Watercolumn1',\
+		'Vx2','Vy2','Vel2','Pressure2','Thickness2','Surface2','MaskIceLevelset2','Enthalpy2','Watercolumn2',\
+		'Vx3','Vy3','Vel3','Pressure3','Thickness3','Surface3','MaskIceLevelset3','Enthalpy3','Watercolumn3']
+field_tolerances=[1e-11,1e-11,1e-11,1e-11,1e-11,1e-11,1e-11,1e-11,1e-11,\
+		1e-10,1e-10,1e-10,1e-10,1e-10,1e-10,1e-10,1e-10,1e-10,\
+		1e-10,1e-10,1e-10,1e-10,1e-10,1e-10,1e-10,1e-10,1e-10]
+field_values=[\
+	md.results.TransientSolution[0].Vx,\
+	md.results.TransientSolution[0].Vy,\
+	md.results.TransientSolution[0].Vel,\
+	md.results.TransientSolution[0].Pressure,\
+	md.results.TransientSolution[0].Thickness,\
+	md.results.TransientSolution[0].Surface,\
+	md.results.TransientSolution[0].MaskIceLevelset,\
+	md.results.TransientSolution[0].Enthalpy,\
+	md.results.TransientSolution[0].Watercolumn,\
+	md.results.TransientSolution[1].Vx,\
+	md.results.TransientSolution[1].Vy,\
+	md.results.TransientSolution[1].Vel,\
+	md.results.TransientSolution[1].Pressure,\
+	md.results.TransientSolution[1].Thickness,\
+	md.results.TransientSolution[1].Surface,\
+	md.results.TransientSolution[1].MaskIceLevelset,\
+	md.results.TransientSolution[1].Enthalpy,\
+	md.results.TransientSolution[1].Watercolumn,\
+	md.results.TransientSolution[2].Vx,\
+	md.results.TransientSolution[2].Vy,\
+	md.results.TransientSolution[2].Vel,\
+	md.results.TransientSolution[2].Pressure,\
+	md.results.TransientSolution[2].Thickness,\
+	md.results.TransientSolution[2].Surface,\
+	md.results.TransientSolution[2].MaskIceLevelset,\
+	md.results.TransientSolution[2].Enthalpy,\
+	md.results.TransientSolution[2].Watercolumn,\
+	]
Index: sm/trunk/test/NightlyRun/testad.m
===================================================================
--- /issm/trunk/test/NightlyRun/testad.m	(revision 17805)
+++ 	(revision )
@@ -1,28 +1,0 @@
-%test reverse scalar vs forward vectorial drivers in ADOLC, using the test3009 setup, equivalent to test109 setup.
-md=triangle(model(),'../Exp/Square.exp',100000.);
-md=setmask(md,'all','');
-md=parameterize(md,'../Par/SquareShelfConstrained.par');
-md=setflowequation(md,'SSA','all');
-md.cluster=generic('name',oshostname(),'np',3);
-%md.debug.valgrind=true;
-%md.verbose=verbose('11111111')
-md.toolkits.DefaultAnalysis=issmmumpssolver();
-%md.toolkits.DefaultAnalysis.solver_type='gsl';
-
-md.autodiff.isautodiff=true;
-md.verbose.autodiff=true;
-
-%first run scalar reverse mode: 
-md.autodiff.independents={independent('name','Thickness','type','vertex','nods',md.mesh.numberofvertices)};
-md.autodiff.dependents={dependent('name','MaxVel','type','scalar','fos_reverse_index',1)};
-md.autodiff.driver='fos_reverse';
-
-md=solve(md,TransientSolutionEnum());
-
-%recover jacobian: 
-jac_reverse=md.results.TransientSolution(1).AutodiffJacobian;
-
-%Fields and tolerances to track changes
-field_names     ={'Jac Reverse'};
-field_tolerances={1e-8};
-field_values={jac_reverse};
Index: /issm/trunk/test/Par/79North.par
===================================================================
--- /issm/trunk/test/Par/79North.par	(revision 17805)
+++ /issm/trunk/test/Par/79North.par	(revision 17806)
@@ -13,5 +13,5 @@
 md.geometry.surface  =InterpFromMeshToMesh2d(index,x,y,surface,md.mesh.x,md.mesh.y);
 md.geometry.thickness=InterpFromMeshToMesh2d(index,x,y,thickness,md.mesh.x,md.mesh.y);
-md.geometry.bed=md.geometry.surface-md.geometry.thickness;
+md.geometry.base=md.geometry.surface-md.geometry.thickness;
 clear surface thickness vx vy x y index;
 
@@ -20,7 +20,4 @@
 md.materials.rheology_B=paterson(md.initialization.temperature);
 md.materials.rheology_n=3*ones(md.mesh.numberofelements,1);
-
-%Damage
-md.damage.D=zeros(md.mesh.numberofvertices,1);
 
 %Friction
Index: /issm/trunk/test/Par/79North.py
===================================================================
--- /issm/trunk/test/Par/79North.py	(revision 17805)
+++ /issm/trunk/test/Par/79North.py	(revision 17806)
@@ -25,5 +25,5 @@
 [md.geometry.surface]   = InterpFromMeshToMesh2d(index,x,y,surface,md.mesh.x,md.mesh.y)
 [md.geometry.thickness] = InterpFromMeshToMesh2d(index,x,y,thickness,md.mesh.x,md.mesh.y)
-md.geometry.bed         = md.geometry.surface-md.geometry.thickness
+md.geometry.base         = md.geometry.surface-md.geometry.thickness
 
 #Materials
@@ -32,7 +32,4 @@
 md.materials.rheology_n=3.*numpy.ones((md.mesh.numberofelements,1))
 md.initialization.temperature=md.initialization.temperature
-
-#Damage
-md.damage.D=numpy.zeros((md.mesh.numberofvertices,1))
 
 #Friction
Index: /issm/trunk/test/Par/GiaBenchmarksAB.par
===================================================================
--- /issm/trunk/test/Par/GiaBenchmarksAB.par	(revision 17805)
+++ /issm/trunk/test/Par/GiaBenchmarksAB.par	(revision 17806)
@@ -11,6 +11,6 @@
 end
 md.geometry.thickness=md.geometry.thickness';
-md.geometry.bed=zeros(md.mesh.numberofvertices,1); 
-md.geometry.surface=md.geometry.thickness+md.geometry.bed; 
+md.geometry.base=zeros(md.mesh.numberofvertices,1); 
+md.geometry.surface=md.geometry.thickness+md.geometry.base; 
 
 %Ice density used for benchmarking, not 917 kg/m^3
@@ -44,7 +44,4 @@
 md.materials.rheology_n=3.*ones(md.mesh.numberofelements,1);
 
-%Damage
-md.damage.D=zeros(md.mesh.numberofvertices,1);
-
 %Friction
 md.friction.coefficient=20.*ones(md.mesh.numberofvertices,1);
Index: /issm/trunk/test/Par/GiaBenchmarksCD.par
===================================================================
--- /issm/trunk/test/Par/GiaBenchmarksCD.par	(revision 17805)
+++ /issm/trunk/test/Par/GiaBenchmarksCD.par	(revision 17806)
@@ -11,6 +11,6 @@
 end
 md.geometry.thickness=md.geometry.thickness';
-md.geometry.bed=zeros(md.mesh.numberofvertices,1); 
-md.geometry.surface=md.geometry.thickness+md.geometry.bed; 
+md.geometry.base=zeros(md.mesh.numberofvertices,1); 
+md.geometry.surface=md.geometry.thickness+md.geometry.base; 
 
 %Ice density used for benchmarking, not 917 kg/m^3
@@ -43,7 +43,4 @@
 md.materials.rheology_n=3.*ones(md.mesh.numberofelements,1);
 
-%Damage
-md.damage.D=zeros(md.mesh.numberofvertices,1);
-
 %Friction
 md.friction.coefficient=20.*ones(md.mesh.numberofvertices,1);
Index: /issm/trunk/test/Par/ISMIPA.par
===================================================================
--- /issm/trunk/test/Par/ISMIPA.par	(revision 17805)
+++ /issm/trunk/test/Par/ISMIPA.par	(revision 17806)
@@ -3,6 +3,6 @@
 disp('      creating thickness');
 md.geometry.surface=-md.mesh.x*tan(0.5*pi/180.);
-md.geometry.bed=md.geometry.surface-1000.+500.*sin(md.mesh.x*2.*pi/max(md.mesh.x)).*sin(md.mesh.y*2.*pi/max(md.mesh.x));
-md.geometry.thickness=md.geometry.surface-md.geometry.bed;
+md.geometry.base=md.geometry.surface-1000.+500.*sin(md.mesh.x*2.*pi/max(md.mesh.x)).*sin(md.mesh.y*2.*pi/max(md.mesh.x));
+md.geometry.thickness=md.geometry.surface-md.geometry.base;
 
 disp('      creating drag');
@@ -16,7 +16,4 @@
 md.materials.rheology_n=3.*ones(md.mesh.numberofelements,1);
 
-%Damage
-md.damage.D=zeros(md.mesh.numberofvertices,1);
-
 disp('      boundary conditions for stressbalance model');
 %Create node on boundary first (because we cannot use mesh)
Index: /issm/trunk/test/Par/ISMIPA.py
===================================================================
--- /issm/trunk/test/Par/ISMIPA.py	(revision 17805)
+++ /issm/trunk/test/Par/ISMIPA.py	(revision 17806)
@@ -6,6 +6,6 @@
 print "      creating thickness"
 md.geometry.surface=-md.mesh.x.reshape(-1,1)*numpy.tan(0.5*numpy.pi/180.)
-md.geometry.bed=md.geometry.surface-1000.+500.*numpy.sin(md.mesh.x.reshape(-1,1)*2.*numpy.pi/numpy.max(md.mesh.x))*numpy.sin(md.mesh.y.reshape(-1,1)*2.*numpy.pi/numpy.max(md.mesh.x))
-md.geometry.thickness=md.geometry.surface-md.geometry.bed
+md.geometry.base=md.geometry.surface-1000.+500.*numpy.sin(md.mesh.x.reshape(-1,1)*2.*numpy.pi/numpy.max(md.mesh.x))*numpy.sin(md.mesh.y.reshape(-1,1)*2.*numpy.pi/numpy.max(md.mesh.x))
+md.geometry.thickness=md.geometry.surface-md.geometry.base
 
 print "      creating drag"
@@ -19,7 +19,4 @@
 md.materials.rheology_n=3.*numpy.ones((md.mesh.numberofelements,1))
 
-#Damage
-md.damage.D=numpy.zeros((md.mesh.numberofvertices,1))
-
 print "      boundary conditions for stressbalance model"
 #Create node on boundary first (because we cannot use mesh)
Index: /issm/trunk/test/Par/ISMIPB.par
===================================================================
--- /issm/trunk/test/Par/ISMIPB.par	(revision 17805)
+++ /issm/trunk/test/Par/ISMIPB.par	(revision 17806)
@@ -3,6 +3,6 @@
 disp('      creating thickness');
 md.geometry.surface=-md.mesh.x*tan(0.5*pi/180.);
-md.geometry.bed=md.geometry.surface-1000.+500.*sin(md.mesh.x*2.*pi/max(md.mesh.x));
-md.geometry.thickness=md.geometry.surface-md.geometry.bed;
+md.geometry.base=md.geometry.surface-1000.+500.*sin(md.mesh.x*2.*pi/max(md.mesh.x));
+md.geometry.thickness=md.geometry.surface-md.geometry.base;
 
 disp('      creating drag');
@@ -16,7 +16,4 @@
 md.materials.rheology_n=3.*ones(md.mesh.numberofelements,1);
 
-%Damage
-md.damage.D=zeros(md.mesh.numberofvertices,1);
-
 disp('      boundary conditions for stressbalance model');
 %Create node on boundary first (because we cannot use mesh)
Index: /issm/trunk/test/Par/ISMIPB.py
===================================================================
--- /issm/trunk/test/Par/ISMIPB.py	(revision 17805)
+++ /issm/trunk/test/Par/ISMIPB.py	(revision 17806)
@@ -6,6 +6,6 @@
 print "      creating thickness"
 md.geometry.surface=-md.mesh.x.reshape(-1,1)*numpy.tan(0.5*numpy.pi/180.)
-md.geometry.bed=md.geometry.surface-1000.+500.*numpy.sin(md.mesh.x.reshape(-1,1)*2.*numpy.pi/numpy.max(md.mesh.x))
-md.geometry.thickness=md.geometry.surface-md.geometry.bed
+md.geometry.base=md.geometry.surface-1000.+500.*numpy.sin(md.mesh.x.reshape(-1,1)*2.*numpy.pi/numpy.max(md.mesh.x))
+md.geometry.thickness=md.geometry.surface-md.geometry.base
 
 print "      creating drag"
@@ -19,7 +19,4 @@
 md.materials.rheology_n=3.*numpy.ones((md.mesh.numberofelements,1))
 
-#Damage
-md.damage.D=numpy.zeros((md.mesh.numberofvertices,1))
-
 print "      boundary conditions for stressbalance model"
 #Create node on boundary first (because we cannot use mesh)
Index: /issm/trunk/test/Par/ISMIPC.par
===================================================================
--- /issm/trunk/test/Par/ISMIPC.par	(revision 17805)
+++ /issm/trunk/test/Par/ISMIPC.par	(revision 17806)
@@ -3,9 +3,9 @@
 disp('      creating thickness');
 md.geometry.surface=2000.-md.mesh.x*tan(0.1*pi/180.); %to have z>0
-md.geometry.bed=md.geometry.surface-1000.;
-md.geometry.thickness=md.geometry.surface-md.geometry.bed;
+md.geometry.base=md.geometry.surface-1000.;
+md.geometry.thickness=md.geometry.surface-md.geometry.base;
 
 disp('      creating drag');
-%md.friction.coefficient=sqrt(md.constants.yts.*(1000.+1000.*sin(md.mesh.x*2.*pi/max(md.mesh.x/2.)).*sin(md.mesh.y*2.*pi/max(md.mesh.x/2.)))./(md.constants.g*(md.materials.rho_ice*md.geometry.thickness+md.materials.rho_water*md.geometry.bed)));
+%md.friction.coefficient=sqrt(md.constants.yts.*(1000.+1000.*sin(md.mesh.x*2.*pi/max(md.mesh.x/2.)).*sin(md.mesh.y*2.*pi/max(md.mesh.x/2.)))./(md.constants.g*(md.materials.rho_ice*md.geometry.thickness+md.materials.rho_water*md.geometry.base)));
 md.friction.coefficient=sqrt(md.constants.yts.*(1000.+1000.*sin(md.mesh.x*2.*pi/max(md.mesh.x)).*sin(md.mesh.y*2.*pi/max(md.mesh.x))));
 md.friction.coefficient(find(md.mask.groundedice_levelset<0.))=0.;
@@ -17,7 +17,4 @@
 md.materials.rheology_n=3.*ones(md.mesh.numberofelements,1);
 
-%Damage
-md.damage.D=zeros(md.mesh.numberofvertices,1);
-
 disp('      boundary conditions for stressbalance model:');
 %Create node on boundary first (because we can not use mesh)
Index: /issm/trunk/test/Par/ISMIPC.py
===================================================================
--- /issm/trunk/test/Par/ISMIPC.py	(revision 17805)
+++ /issm/trunk/test/Par/ISMIPC.py	(revision 17806)
@@ -6,9 +6,9 @@
 print "      creating thickness"
 md.geometry.surface=2000.-md.mesh.x.reshape(-1,1)*numpy.tan(0.1*numpy.pi/180.)    #to have z>0
-md.geometry.bed=md.geometry.surface-1000.
-md.geometry.thickness=md.geometry.surface-md.geometry.bed
+md.geometry.base=md.geometry.surface-1000.
+md.geometry.thickness=md.geometry.surface-md.geometry.base
 
 print "      creating drag"
-#md.friction.coefficient=sqrt(md.constants.yts.*(1000.+1000.*sin(md.mesh.x*2.*pi/max(md.mesh.x/2.)).*sin(md.mesh.y*2.*pi/max(md.mesh.x/2.)))./(md.constants.g*(md.materials.rho_ice*md.geometry.thickness+md.materials.rho_water*md.geometry.bed)));
+#md.friction.coefficient=sqrt(md.constants.yts.*(1000.+1000.*sin(md.mesh.x*2.*pi/max(md.mesh.x/2.)).*sin(md.mesh.y*2.*pi/max(md.mesh.x/2.)))./(md.constants.g*(md.materials.rho_ice*md.geometry.thickness+md.materials.rho_water*md.geometry.base)));
 md.friction.coefficient=numpy.sqrt(md.constants.yts*(1000.+1000.*numpy.sin(md.mesh.x.reshape(-1,1)*2.*numpy.pi/numpy.max(md.mesh.x))*numpy.sin(md.mesh.y.reshape(-1,1)*2.*numpy.pi/numpy.max(md.mesh.x))))
 md.friction.coefficient[numpy.nonzero(md.mask.groundedice_levelset<0.)[0]]=0.
@@ -20,7 +20,4 @@
 md.materials.rheology_n=3.*numpy.ones((md.mesh.numberofelements,1))
 
-#Damage
-md.damage.D=numpy.zeros((md.mesh.numberofvertices,1))
-
 print "      boundary conditions for stressbalance model:"
 #Create node on boundary first (because we can not use mesh)
Index: /issm/trunk/test/Par/ISMIPD.par
===================================================================
--- /issm/trunk/test/Par/ISMIPD.par	(revision 17805)
+++ /issm/trunk/test/Par/ISMIPD.par	(revision 17806)
@@ -3,6 +3,6 @@
 disp('      creating thickness');
 md.geometry.surface=2000.-md.mesh.x*tan(0.1*pi/180.); %to have z>0
-md.geometry.bed=md.geometry.surface-1000.;
-md.geometry.thickness=md.geometry.surface-md.geometry.bed;
+md.geometry.base=md.geometry.surface-1000.;
+md.geometry.thickness=md.geometry.surface-md.geometry.base;
 
 disp('      creating drag');
@@ -16,7 +16,4 @@
 md.materials.rheology_n=3.*ones(md.mesh.numberofelements,1);
 
-%Damage
-md.damage.D=zeros(md.mesh.numberofvertices,1);
-
 disp('      boundary conditions for stressbalance model:');
 %Create node on boundary first (because we can not use mesh)
Index: /issm/trunk/test/Par/ISMIPD.py
===================================================================
--- /issm/trunk/test/Par/ISMIPD.py	(revision 17805)
+++ /issm/trunk/test/Par/ISMIPD.py	(revision 17806)
@@ -6,6 +6,6 @@
 print "      creating thickness"
 md.geometry.surface=2000.-md.mesh.x.reshape(-1,1)*numpy.tan(0.1*numpy.pi/180.)    #to have z>0
-md.geometry.bed=md.geometry.surface-1000.
-md.geometry.thickness=md.geometry.surface-md.geometry.bed
+md.geometry.base=md.geometry.surface-1000.
+md.geometry.thickness=md.geometry.surface-md.geometry.base
 
 print "      creating drag"
@@ -19,7 +19,4 @@
 md.materials.rheology_n=3.*numpy.ones((md.mesh.numberofelements,1))
 
-#Damage
-md.damage.D=numpy.zeros((md.mesh.numberofvertices,1))
-
 print "      boundary conditions for stressbalance model:"
 #Create node on boundary first (because we can not use mesh)
Index: /issm/trunk/test/Par/ISMIPE.par
===================================================================
--- /issm/trunk/test/Par/ISMIPE.par	(revision 17805)
+++ /issm/trunk/test/Par/ISMIPE.par	(revision 17806)
@@ -4,5 +4,5 @@
 data=transpose(ncread('../Data/ISMIPE.nc','data'));
 md.geometry.surface=zeros(md.mesh.numberofvertices,1);
-md.geometry.bed=zeros(md.mesh.numberofvertices,1);
+md.geometry.base=zeros(md.mesh.numberofvertices,1);
 for i=1:md.mesh.numberofvertices
 	y=md.mesh.y(i);
@@ -10,10 +10,10 @@
 	point2=min(point1+1,51);
 	coeff=(y-(point1-1.)*100.)/100.;
-	md.geometry.bed(i)=(1.-coeff)*data(point1,2)+coeff*data(point2,2);
+	md.geometry.base(i)=(1.-coeff)*data(point1,2)+coeff*data(point2,2);
 	md.geometry.surface(i)=(1.-coeff)*data(point1,3)+coeff*data(point2,3);
 end
-md.geometry.thickness=md.geometry.surface-md.geometry.bed;
+md.geometry.thickness=md.geometry.surface-md.geometry.base;
 md.geometry.thickness(find(~md.geometry.thickness))=0.01;
-md.geometry.bed=md.geometry.surface-md.geometry.thickness;
+md.geometry.base=md.geometry.surface-md.geometry.thickness;
 
 disp('      creating drag');
@@ -26,7 +26,4 @@
 md.materials.rheology_n=3.*ones(md.mesh.numberofelements,1);
 
-%Damage
-md.damage.D=zeros(md.mesh.numberofvertices,1);
-
 disp('      boundary conditions for stressbalance model:');
 %Create node on boundary first (because we can not use mesh)
Index: /issm/trunk/test/Par/ISMIPE.py
===================================================================
--- /issm/trunk/test/Par/ISMIPE.py	(revision 17805)
+++ /issm/trunk/test/Par/ISMIPE.py	(revision 17806)
@@ -10,5 +10,5 @@
 f.close()
 md.geometry.surface=numpy.zeros((md.mesh.numberofvertices,1))
-md.geometry.bed=numpy.zeros((md.mesh.numberofvertices,1))
+md.geometry.base=numpy.zeros((md.mesh.numberofvertices,1))
 for i in xrange(0,md.mesh.numberofvertices):
 	y=md.mesh.y[i]
@@ -16,9 +16,9 @@
 	point2=numpy.minimum(point1+1,50)
 	coeff=(y-(point1-1.)*100.)/100.
-	md.geometry.bed[i]=(1.-coeff)*data[point1,1]+coeff*data[point2,1]
+	md.geometry.base[i]=(1.-coeff)*data[point1,1]+coeff*data[point2,1]
 	md.geometry.surface[i]=(1.-coeff)*data[point1,2]+coeff*data[point2,2]
-md.geometry.thickness=md.geometry.surface-md.geometry.bed
+md.geometry.thickness=md.geometry.surface-md.geometry.base
 md.geometry.thickness[numpy.nonzero(numpy.logical_not(md.geometry.thickness))]=0.01
-md.geometry.bed=md.geometry.surface-md.geometry.thickness
+md.geometry.base=md.geometry.surface-md.geometry.thickness
 
 print "      creating drag"
@@ -31,7 +31,4 @@
 md.materials.rheology_n=3.*numpy.ones((md.mesh.numberofelements,1))
 
-#Damage
-md.damage.D=numpy.zeros((md.mesh.numberofvertices,1))
-
 print "      boundary conditions for stressbalance model:"
 #Create node on boundary first (because we can not use mesh)
Index: /issm/trunk/test/Par/ISMIPF.par
===================================================================
--- /issm/trunk/test/Par/ISMIPF.par	(revision 17805)
+++ /issm/trunk/test/Par/ISMIPF.par	(revision 17806)
@@ -4,7 +4,7 @@
 disp('      creating thickness');
 md.geometry.surface=-md.mesh.x*tan(3.*pi/180.);
-%md.geometry.bed=md.geometry.surface-1000.;
-md.geometry.bed=md.geometry.surface-1000.+100.*exp(-((md.mesh.x-max(md.mesh.x)/2.).^2+(md.mesh.y-max(md.mesh.y)/2.).^2)/(10000.^2));
-md.geometry.thickness=md.geometry.surface-md.geometry.bed;
+%md.geometry.base=md.geometry.surface-1000.;
+md.geometry.base=md.geometry.surface-1000.+100.*exp(-((md.mesh.x-max(md.mesh.x)/2.).^2+(md.mesh.y-max(md.mesh.y)/2.).^2)/(10000.^2));
+md.geometry.thickness=md.geometry.surface-md.geometry.base;
 
 disp('      creating drag');
@@ -17,7 +17,4 @@
 md.materials.rheology_n=1.*ones(md.mesh.numberofelements,1);
 md.materials.rheology_law='None';
-
-%Damage
-md.damage.D=zeros(md.mesh.numberofvertices,1);
 
 disp('      boundary conditions for stressbalance model');
Index: /issm/trunk/test/Par/ISMIPF.py
===================================================================
--- /issm/trunk/test/Par/ISMIPF.py	(revision 17805)
+++ /issm/trunk/test/Par/ISMIPF.py	(revision 17806)
@@ -7,7 +7,7 @@
 print "      creating thickness"
 md.geometry.surface=-md.mesh.x.reshape(-1,1)*numpy.tan(3.*numpy.pi/180.)
-#md.geometry.bed=md.geometry.surface-1000.
-md.geometry.bed=md.geometry.surface-1000.+100.*numpy.exp(-((md.mesh.x.reshape(-1,1)-numpy.max(md.mesh.x)/2.)**2+(md.mesh.y.reshape(-1,1)-numpy.max(md.mesh.y)/2.)**2)/(10000.**2))
-md.geometry.thickness=md.geometry.surface-md.geometry.bed
+#md.geometry.base=md.geometry.surface-1000.
+md.geometry.base=md.geometry.surface-1000.+100.*numpy.exp(-((md.mesh.x.reshape(-1,1)-numpy.max(md.mesh.x)/2.)**2+(md.mesh.y.reshape(-1,1)-numpy.max(md.mesh.y)/2.)**2)/(10000.**2))
+md.geometry.thickness=md.geometry.surface-md.geometry.base
 
 print "      creating drag"
@@ -20,7 +20,4 @@
 md.materials.rheology_n=1.*numpy.ones((md.mesh.numberofelements,1))
 md.materials.rheology_law='None'
-
-#Damage
-md.damage.D=numpy.zeros((md.mesh.numberofvertices,1))
 
 print "      boundary conditions for stressbalance model"
Index: /issm/trunk/test/Par/Pig.par
===================================================================
--- /issm/trunk/test/Par/Pig.par	(revision 17805)
+++ /issm/trunk/test/Par/Pig.par	(revision 17806)
@@ -13,5 +13,5 @@
 md.geometry.surface  =InterpFromMeshToMesh2d(index,x,y,surface,md.mesh.x,md.mesh.y);
 md.geometry.thickness=InterpFromMeshToMesh2d(index,x,y,thickness,md.mesh.x,md.mesh.y);
-md.geometry.bed=md.geometry.surface-md.geometry.thickness;
+md.geometry.base=md.geometry.surface-md.geometry.thickness;
 clear surface thickness vx_obs vy_obs x y index;
 md.initialization.vx=md.inversion.vx_obs;
@@ -25,7 +25,4 @@
 md.materials.rheology_n=3*ones(md.mesh.numberofelements,1);
 md.initialization.temperature=md.initialization.temperature;
-
-%Damage
-md.damage.D=zeros(md.mesh.numberofvertices,1);
 
 %Friction
Index: /issm/trunk/test/Par/Pig.py
===================================================================
--- /issm/trunk/test/Par/Pig.py	(revision 17805)
+++ /issm/trunk/test/Par/Pig.py	(revision 17806)
@@ -25,5 +25,5 @@
 [md.geometry.surface]  =InterpFromMeshToMesh2d(index,x,y,surface,md.mesh.x,md.mesh.y)
 [md.geometry.thickness]=InterpFromMeshToMesh2d(index,x,y,thickness,md.mesh.x,md.mesh.y)
-md.geometry.bed=md.geometry.surface-md.geometry.thickness
+md.geometry.base=md.geometry.surface-md.geometry.thickness
 md.initialization.vx=md.inversion.vx_obs
 md.initialization.vy=md.inversion.vy_obs
@@ -36,7 +36,4 @@
 md.materials.rheology_n=3.*numpy.ones((md.mesh.numberofelements,1))
 md.initialization.temperature=md.initialization.temperature
-
-#Damage
-md.damage.D=numpy.zeros((md.mesh.numberofvertices,1))
 
 #Friction
Index: /issm/trunk/test/Par/RoundSheetEISMINT.par
===================================================================
--- /issm/trunk/test/Par/RoundSheetEISMINT.par	(revision 17805)
+++ /issm/trunk/test/Par/RoundSheetEISMINT.par	(revision 17806)
@@ -2,6 +2,6 @@
 disp('      creating thickness');
 md.geometry.thickness=10.*ones(md.mesh.numberofvertices,1);
-md.geometry.bed=zeros(md.mesh.numberofvertices,1);
-md.geometry.surface=md.geometry.bed+md.geometry.thickness;
+md.geometry.base=zeros(md.mesh.numberofvertices,1);
+md.geometry.surface=md.geometry.base+md.geometry.thickness;
 
 disp('      creating drag');
@@ -20,7 +20,4 @@
 md.materials.rheology_B=6.81*10^7*ones(md.mesh.numberofvertices,1); %to have the same B as the analytical solution 
 md.materials.rheology_n=3.*ones(md.mesh.numberofelements,1);
-
-%Damage
-md.damage.D=zeros(md.mesh.numberofvertices,1);
 
 disp('      creating surface mass balance');
Index: /issm/trunk/test/Par/RoundSheetEISMINT.py
===================================================================
--- /issm/trunk/test/Par/RoundSheetEISMINT.py	(revision 17805)
+++ /issm/trunk/test/Par/RoundSheetEISMINT.py	(revision 17806)
@@ -5,6 +5,6 @@
 print "      creating thickness"
 md.geometry.thickness=10.*numpy.ones((md.mesh.numberofvertices,1))
-md.geometry.bed=numpy.zeros((md.mesh.numberofvertices,1))
-md.geometry.surface=md.geometry.bed+md.geometry.thickness
+md.geometry.base=numpy.zeros((md.mesh.numberofvertices,1))
+md.geometry.surface=md.geometry.base+md.geometry.thickness
 
 print "      creating drag"
@@ -23,7 +23,4 @@
 md.materials.rheology_B=6.81*10**7*numpy.ones((md.mesh.numberofvertices,1))    #to have the same B as the analytical solution 
 md.materials.rheology_n=3.*numpy.ones((md.mesh.numberofelements,1))
-
-#Damage
-md.damage.D=numpy.zeros((md.mesh.numberofvertices,1))
 
 print "      creating surface mass balance"
Index: /issm/trunk/test/Par/RoundSheetShelf.par
===================================================================
--- /issm/trunk/test/Par/RoundSheetShelf.par	(revision 17805)
+++ /issm/trunk/test/Par/RoundSheetShelf.par	(revision 17806)
@@ -11,24 +11,24 @@
 ymax=max(radius);
 md.geometry.thickness=hmax+(hmin-hmax)*(radius-ymin)/(ymax-ymin);
-md.geometry.bed=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness;
+md.geometry.base=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness;
 
 pos=find(md.mask.groundedice_levelset>0.);
-md.geometry.bed(pos)=md.geometry.bed(pos)-300.*(radius(pos)-(rad-shelfextent))/(rad-shelfextent);
-md.geometry.surface=md.geometry.bed+md.geometry.thickness;
+md.geometry.base(pos)=md.geometry.base(pos)-300.*(radius(pos)-(rad-shelfextent))/(rad-shelfextent);
+md.geometry.surface=md.geometry.base+md.geometry.thickness;
 
 pos=find(radius<200000);
 md.geometry.thickness(pos)=100.;
-md.geometry.bed(pos)=-di*md.geometry.thickness(pos)-20.;
-md.geometry.surface(pos)=md.geometry.bed(pos)+md.geometry.thickness(pos);
+md.geometry.base(pos)=-di*md.geometry.thickness(pos)-20.;
+md.geometry.surface(pos)=md.geometry.base(pos)+md.geometry.thickness(pos);
 
 pos=find(md.mesh.x<0.2*1.e6 & md.mesh.x>-0.2*1.e6 & md.mesh.y>0.);
 md.geometry.thickness(pos)=100.;
-md.geometry.bed(pos)=-di*md.geometry.thickness(pos)-20.;
-md.geometry.surface(pos)=md.geometry.bed(pos)+md.geometry.thickness(pos);
+md.geometry.base(pos)=-di*md.geometry.thickness(pos)-20.;
+md.geometry.surface(pos)=md.geometry.base(pos)+md.geometry.thickness(pos);
 
 pos=find(md.mesh.x<0.1*1.e6 & md.mesh.x>-0.1*1.e6 & md.mesh.y<-0.5*1.e6 & md.mesh.y>-0.6*1.e6);
 md.geometry.thickness(pos)=100.;
-md.geometry.bed(pos)=-di*md.geometry.thickness(pos)-20.;
-md.geometry.surface(pos)=md.geometry.bed(pos)+md.geometry.thickness(pos);
+md.geometry.base(pos)=-di*md.geometry.thickness(pos)-20.;
+md.geometry.surface(pos)=md.geometry.base(pos)+md.geometry.thickness(pos);
 
 %plug holes into the ice sheet, to test for grounding line migration. 
@@ -37,16 +37,16 @@
 pos=find(rad<200000.);
 md.geometry.thickness(pos)=100.;
-md.geometry.bed(pos)=-di*md.geometry.thickness(pos)-20.;
-md.geometry.surface(pos)=md.geometry.bed(pos)+md.geometry.thickness(pos);
+md.geometry.base(pos)=-di*md.geometry.thickness(pos)-20.;
+md.geometry.surface(pos)=md.geometry.base(pos)+md.geometry.thickness(pos);
 
 pos=find(md.mesh.x<0.2*1.e6 & md.mesh.x>-0.2*1.e6 & md.mesh.y>0.);
 md.geometry.thickness(pos)=100.;
-md.geometry.bed(pos)=-di*md.geometry.thickness(pos)-20.;
-md.geometry.surface(pos)=md.geometry.bed(pos)+md.geometry.thickness(pos);
+md.geometry.base(pos)=-di*md.geometry.thickness(pos)-20.;
+md.geometry.surface(pos)=md.geometry.base(pos)+md.geometry.thickness(pos);
 
 pos=find(md.mesh.x<0.1*1.e6 & md.mesh.x>-0.1*1.e6 & md.mesh.y<-0.5*1.e6 & md.mesh.y>-0.6*1.e6);
 md.geometry.thickness(pos)=100.;
-md.geometry.bed(pos)=-di*md.geometry.thickness(pos)-20.;
-md.geometry.surface(pos)=md.geometry.bed(pos)+md.geometry.thickness(pos);
+md.geometry.base(pos)=-di*md.geometry.thickness(pos)-20.;
+md.geometry.surface(pos)=md.geometry.base(pos)+md.geometry.thickness(pos);
 
 %Initial velocity 
@@ -60,7 +60,4 @@
 md.materials.rheology_B=paterson(md.initialization.temperature);
 md.materials.rheology_n=3.*ones(md.mesh.numberofelements,1);
-
-%Damage
-md.damage.D=zeros(md.mesh.numberofvertices,1);
 
 %Surface mass balance and basal melting
@@ -98,6 +95,6 @@
 %bathymetry and grounding line migration:
 md.groundingline.migration='AgressiveMigration';
-md.geometry.bathymetry=md.geometry.bed;
-pos=find(md.mask.groundedice_levelset<0.); md.geometry.bathymetry(pos)=md.geometry.bed(pos)-900.;
+md.geometry.bed=md.geometry.base;
+pos=find(md.mask.groundedice_levelset<0.); md.geometry.bed(pos)=md.geometry.base(pos)-900.;
 
 %Deal with boundary conditions:
@@ -112,5 +109,4 @@
 md.mask.ice_levelset(find(md.mesh.vertexonboundary))=0;
 md.balancethickness.spcthickness=NaN*ones(md.mesh.numberofvertices,1);
-md.damage.spcdamage=NaN*ones(md.mesh.numberofvertices,1);
 md.masstransport.spcthickness=NaN*ones(md.mesh.numberofvertices,1);
 md.stressbalance.referential=NaN*ones(md.mesh.numberofvertices,6);
Index: /issm/trunk/test/Par/RoundSheetShelf.py
===================================================================
--- /issm/trunk/test/Par/RoundSheetShelf.py	(revision 17805)
+++ /issm/trunk/test/Par/RoundSheetShelf.py	(revision 17806)
@@ -18,24 +18,24 @@
 ymax=numpy.max(radius)
 md.geometry.thickness=hmax+(hmin-hmax)*(radius-ymin)/(ymax-ymin)
-md.geometry.bed=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness
+md.geometry.base=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness
 
 pos=numpy.nonzero(md.mask.groundedice_levelset>0.)[0]
-md.geometry.bed[pos]=md.geometry.bed[pos]-300.*(radius[pos]-(rad-shelfextent))/(rad-shelfextent)
-md.geometry.surface=md.geometry.bed+md.geometry.thickness
+md.geometry.base[pos]=md.geometry.base[pos]-300.*(radius[pos]-(rad-shelfextent))/(rad-shelfextent)
+md.geometry.surface=md.geometry.base+md.geometry.thickness
 
 pos=numpy.nonzero(radius<200000.)
 md.geometry.thickness[pos]=100.
-md.geometry.bed[pos]=-di*md.geometry.thickness[pos]-20.
-md.geometry.surface[pos]=md.geometry.bed[pos]+md.geometry.thickness[pos]
+md.geometry.base[pos]=-di*md.geometry.thickness[pos]-20.
+md.geometry.surface[pos]=md.geometry.base[pos]+md.geometry.thickness[pos]
 
 pos=numpy.nonzero(numpy.logical_and(numpy.logical_and(md.mesh.x<0.2*1.e6,md.mesh.x>-0.2*1.e6),md.mesh.y>0.))
 md.geometry.thickness[pos]=100.
-md.geometry.bed[pos]=-di*md.geometry.thickness[pos]-20.
-md.geometry.surface[pos]=md.geometry.bed[pos]+md.geometry.thickness[pos]
+md.geometry.base[pos]=-di*md.geometry.thickness[pos]-20.
+md.geometry.surface[pos]=md.geometry.base[pos]+md.geometry.thickness[pos]
 
 pos=numpy.nonzero(numpy.logical_and(numpy.logical_and(md.mesh.x<0.1*1.e6,md.mesh.x>-0.1*1.e6),numpy.logical_and(md.mesh.y<-0.5*1.e6,md.mesh.y>-0.6*1.e6)))
 md.geometry.thickness[pos]=100.
-md.geometry.bed[pos]=-di*md.geometry.thickness[pos]-20.
-md.geometry.surface[pos]=md.geometry.bed[pos]+md.geometry.thickness[pos]
+md.geometry.base[pos]=-di*md.geometry.thickness[pos]-20.
+md.geometry.surface[pos]=md.geometry.base[pos]+md.geometry.thickness[pos]
 
 #plug holes into the ice sheet, to test for grounding line migration. 
@@ -44,16 +44,16 @@
 pos=numpy.nonzero(rad<200000.)
 md.geometry.thickness[pos]=100.
-md.geometry.bed[pos]=-di*md.geometry.thickness[pos]-20.
-md.geometry.surface[pos]=md.geometry.bed[pos]+md.geometry.thickness[pos]
+md.geometry.base[pos]=-di*md.geometry.thickness[pos]-20.
+md.geometry.surface[pos]=md.geometry.base[pos]+md.geometry.thickness[pos]
 
 pos=numpy.nonzero(numpy.logical_and(numpy.logical_and(md.mesh.x<0.2*1.e6,md.mesh.x>-0.2*1.e6),md.mesh.y>0.))
 md.geometry.thickness[pos]=100.
-md.geometry.bed[pos]=-di*md.geometry.thickness[pos]-20.
-md.geometry.surface[pos]=md.geometry.bed[pos]+md.geometry.thickness[pos]
+md.geometry.base[pos]=-di*md.geometry.thickness[pos]-20.
+md.geometry.surface[pos]=md.geometry.base[pos]+md.geometry.thickness[pos]
 
 pos=numpy.nonzero(numpy.logical_and(numpy.logical_and(md.mesh.x<0.1*1.e6,md.mesh.x>-0.1*1.e6),numpy.logical_and(md.mesh.y<-0.5*1.e6,md.mesh.y>-0.6*1.e6)))
 md.geometry.thickness[pos]=100.
-md.geometry.bed[pos]=-di*md.geometry.thickness[pos]-20.
-md.geometry.surface[pos]=md.geometry.bed[pos]+md.geometry.thickness[pos]
+md.geometry.base[pos]=-di*md.geometry.thickness[pos]-20.
+md.geometry.surface[pos]=md.geometry.base[pos]+md.geometry.thickness[pos]
 
 #Initial velocity 
@@ -67,7 +67,4 @@
 md.materials.rheology_B=paterson(md.initialization.temperature)
 md.materials.rheology_n=3.*numpy.ones((md.mesh.numberofelements,1))
-
-#Damage
-md.damage.D=numpy.zeros((md.mesh.numberofvertices,1))
 
 #Surface mass balance and basal melting
@@ -106,7 +103,7 @@
 #bathymetry and grounding line migration:
 md.groundingline.migration='AgressiveMigration'
-md.geometry.bathymetry=copy.deepcopy(md.geometry.bed)
+md.geometry.bed=copy.deepcopy(md.geometry.base)
 pos=numpy.nonzero(md.mask.groundedice_levelset<0.)[0]
-md.geometry.bathymetry[pos]=md.geometry.bed[pos]-900.
+md.geometry.bed[pos]=md.geometry.base[pos]-900.
 
 #Deal with boundary conditions:
@@ -122,5 +119,4 @@
 md.mask.ice_levelset[pos]=0
 md.balancethickness.spcthickness=float('nan')*numpy.ones((md.mesh.numberofvertices,1))
-md.damage.spcdamage=float('nan')*numpy.ones((md.mesh.numberofvertices,1))
 md.masstransport.spcthickness=float('nan')*numpy.ones((md.mesh.numberofvertices,1))
 md.stressbalance.referential=float('nan')*numpy.ones((md.mesh.numberofvertices,6))
Index: /issm/trunk/test/Par/RoundSheetStaticEISMINT.par
===================================================================
--- /issm/trunk/test/Par/RoundSheetStaticEISMINT.par	(revision 17805)
+++ /issm/trunk/test/Par/RoundSheetStaticEISMINT.par	(revision 17806)
@@ -6,6 +6,6 @@
 radius(find(radius>(1.-10^-9)*radiusmax))=radiusmax;    %eliminate roundoff issues in next statement
 md.geometry.thickness=hmin*ones(size(md.mesh.x,1),1)+hmax*(4.*((1./2.)^(4./3.)*ones(size(md.mesh.x,1),1)-((radius)./(2.*radiusmax)).^(4./3.))).^(3./8.);
-md.geometry.bed=0.*md.geometry.thickness;
-md.geometry.surface=md.geometry.bed+md.geometry.thickness;
+md.geometry.base=0.*md.geometry.thickness;
+md.geometry.surface=md.geometry.base+md.geometry.thickness;
 
 disp('      creating drag');
@@ -24,7 +24,4 @@
 md.materials.rheology_B=6.81*10^7*ones(md.mesh.numberofvertices,1); %to have the same B as the analytical solution 
 md.materials.rheology_n=3.*ones(md.mesh.numberofelements,1);
-
-%Damage
-md.damage.D=zeros(md.mesh.numberofvertices,1);
 
 disp('      creating surface mass balance');
Index: /issm/trunk/test/Par/RoundSheetStaticEISMINT.py
===================================================================
--- /issm/trunk/test/Par/RoundSheetStaticEISMINT.py	(revision 17805)
+++ /issm/trunk/test/Par/RoundSheetStaticEISMINT.py	(revision 17806)
@@ -9,6 +9,6 @@
 radius[numpy.nonzero(radius>(1.-10**-9)*radiusmax)]=radiusmax    #eliminate roundoff issues in next statement
 md.geometry.thickness=hmin*numpy.ones((numpy.size(md.mesh.x),1))+hmax*(4.*((1./2.)**(4./3.)*numpy.ones((numpy.size(md.mesh.x),1))-((radius)/(2.*radiusmax))**(4./3.)))**(3./8.)
-md.geometry.bed=0.*md.geometry.thickness
-md.geometry.surface=md.geometry.bed+md.geometry.thickness
+md.geometry.base=0.*md.geometry.thickness
+md.geometry.surface=md.geometry.base+md.geometry.thickness
 
 print "      creating drag"
@@ -27,7 +27,4 @@
 md.materials.rheology_B=6.81*10**7*numpy.ones((md.mesh.numberofvertices,1))    #to have the same B as the analytical solution 
 md.materials.rheology_n=3.*numpy.ones((md.mesh.numberofelements,1))
-
-#Damage
-md.damage.D=numpy.zeros((md.mesh.numberofvertices,1))
 
 print "      creating surface mass balance"
Index: /issm/trunk/test/Par/SquareEISMINT.par
===================================================================
--- /issm/trunk/test/Par/SquareEISMINT.par	(revision 17805)
+++ /issm/trunk/test/Par/SquareEISMINT.par	(revision 17806)
@@ -5,6 +5,6 @@
 ymax=max(md.mesh.y);
 md.geometry.thickness=500.*ones(md.mesh.numberofvertices,1);
-md.geometry.bed=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness;
-md.geometry.surface=md.geometry.bed+md.geometry.thickness;
+md.geometry.base=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness;
+md.geometry.surface=md.geometry.base+md.geometry.thickness;
 
 disp('      creating drag');
@@ -26,7 +26,4 @@
 md.materials.rheology_n=3.*ones(md.mesh.numberofelements,1);
 
-%Damage
-md.damage.D=zeros(md.mesh.numberofvertices,1);
-
 disp('      creating surface mass balance');
 md.surfaceforcings.mass_balance=0.2*ones(md.mesh.numberofvertices,1); %0m/a
Index: /issm/trunk/test/Par/SquareEISMINT.py
===================================================================
--- /issm/trunk/test/Par/SquareEISMINT.py	(revision 17805)
+++ /issm/trunk/test/Par/SquareEISMINT.py	(revision 17806)
@@ -8,6 +8,6 @@
 ymax=numpy.max(md.mesh.y)
 md.geometry.thickness=500.*numpy.ones((md.mesh.numberofvertices,1))
-md.geometry.bed=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness
-md.geometry.surface=md.geometry.bed+md.geometry.thickness
+md.geometry.base=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness
+md.geometry.surface=md.geometry.base+md.geometry.thickness
 
 print "      creating drag"
@@ -29,7 +29,4 @@
 md.materials.rheology_n=3.*numpy.ones((md.mesh.numberofelements,1))
 
-#Damage
-md.damage.D=numpy.zeros((md.mesh.numberofvertices,1))
-
 print "      creating surface mass balance"
 md.surfaceforcings.mass_balance=0.2*numpy.ones((md.mesh.numberofvertices,1))    #0m/a
Index: /issm/trunk/test/Par/SquareSheetConstrained.par
===================================================================
--- /issm/trunk/test/Par/SquareSheetConstrained.par	(revision 17805)
+++ /issm/trunk/test/Par/SquareSheetConstrained.par	(revision 17806)
@@ -9,6 +9,6 @@
 xmax=max(md.mesh.x);
 md.geometry.thickness=hmax+(hmin-hmax)*(md.mesh.y-ymin)/(ymax-ymin)+0.1*(hmin-hmax)*(md.mesh.x-xmin)/(xmax-xmin);
-md.geometry.bed=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness+20.;
-md.geometry.surface=md.geometry.bed+md.geometry.thickness;
+md.geometry.base=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness+20.;
+md.geometry.surface=md.geometry.base+md.geometry.thickness;
 
 %Initial velocity 
@@ -30,6 +30,5 @@
 md.materials.rheology_n=3.*ones(md.mesh.numberofelements,1);
 
-%Damage
-md.damage.D=zeros(md.mesh.numberofvertices,1);
+md.masstransport.calvingrate=zeros(md.mesh.numberofvertices,1);
 
 %Friction
Index: /issm/trunk/test/Par/SquareSheetConstrained.py
===================================================================
--- /issm/trunk/test/Par/SquareSheetConstrained.py	(revision 17805)
+++ /issm/trunk/test/Par/SquareSheetConstrained.py	(revision 17806)
@@ -18,6 +18,6 @@
 xmax=max(md.mesh.x)
 md.geometry.thickness=hmax+(hmin-hmax)*(md.mesh.y.reshape(-1,1)-ymin)/(ymax-ymin)+0.1*(hmin-hmax)*(md.mesh.x.reshape(-1,1)-xmin)/(xmax-xmin)
-md.geometry.bed=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness+20.
-md.geometry.surface=md.geometry.bed+md.geometry.thickness
+md.geometry.base=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness+20.
+md.geometry.surface=md.geometry.base+md.geometry.thickness
 
 #Initial velocity 
@@ -40,6 +40,6 @@
 md.materials.rheology_n=3.*numpy.ones((md.mesh.numberofelements,1))
 
-#Damage
-md.damage.D=numpy.zeros((md.mesh.numberofvertices,1))
+#Masstransport
+md.masstransport.calvingrate=0.*numpy.ones((md.mesh.numberofvertices,1))
 
 #Friction
Index: /issm/trunk/test/Par/SquareSheetShelf.par
===================================================================
--- /issm/trunk/test/Par/SquareSheetShelf.par	(revision 17805)
+++ /issm/trunk/test/Par/SquareSheetShelf.par	(revision 17806)
@@ -9,9 +9,9 @@
 xmax=max(md.mesh.x);
 md.geometry.thickness=hmax+(hmin-hmax)*(md.mesh.y-ymin)/(ymax-ymin)+0.1*(hmin-hmax)*(md.mesh.x-xmin)/(xmax-xmin);
-md.geometry.bed=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness;
+md.geometry.base=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness;
 bed_sheet=-md.materials.rho_ice/md.materials.rho_water*(hmax+(hmin-hmax)*(ymax/2-ymin)/(ymax-ymin));
 pos=find(md.mesh.y<=ymax/2.);
-md.geometry.bed(pos)=bed_sheet;
-md.geometry.surface=md.geometry.bed+md.geometry.thickness;
+md.geometry.base(pos)=bed_sheet;
+md.geometry.surface=md.geometry.base+md.geometry.thickness;
 
 %Initial velocity 
@@ -31,7 +31,4 @@
 md.materials.rheology_B=paterson(md.initialization.temperature);
 md.materials.rheology_n=3.*ones(md.mesh.numberofelements,1);
-
-%Damage
-md.damage.D=zeros(md.mesh.numberofvertices,1);
 
 %Accumulation and melting
Index: /issm/trunk/test/Par/SquareSheetShelf.py
===================================================================
--- /issm/trunk/test/Par/SquareSheetShelf.py	(revision 17805)
+++ /issm/trunk/test/Par/SquareSheetShelf.py	(revision 17806)
@@ -18,9 +18,9 @@
 xmax=max(md.mesh.x)
 md.geometry.thickness=hmax+(hmin-hmax)*(md.mesh.y.reshape(-1,1)-ymin)/(ymax-ymin)+0.1*(hmin-hmax)*(md.mesh.x.reshape(-1,1)-xmin)/(xmax-xmin)
-md.geometry.bed=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness
+md.geometry.base=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness
 bed_sheet=-md.materials.rho_ice/md.materials.rho_water*(hmax+(hmin-hmax)*(ymax/2-ymin)/(ymax-ymin))
 pos=numpy.nonzero(md.mesh.y<=ymax/2.)
-md.geometry.bed[pos]=bed_sheet
-md.geometry.surface=md.geometry.bed+md.geometry.thickness
+md.geometry.base[pos]=bed_sheet
+md.geometry.surface=md.geometry.base+md.geometry.thickness
 
 #Initial velocity 
@@ -42,7 +42,4 @@
 md.materials.rheology_B=paterson(md.initialization.temperature)
 md.materials.rheology_n=3.*numpy.ones((md.mesh.numberofelements,1))
-
-#Damage
-md.damage.D=numpy.zeros((md.mesh.numberofvertices,1))
 
 #Accumulation and melting
Index: /issm/trunk/test/Par/SquareShelf.par
===================================================================
--- /issm/trunk/test/Par/SquareShelf.par	(revision 17805)
+++ /issm/trunk/test/Par/SquareShelf.par	(revision 17806)
@@ -9,6 +9,6 @@
 xmax=max(md.mesh.x);
 md.geometry.thickness=hmax+(hmin-hmax)*(md.mesh.y-ymin)/(ymax-ymin)+0.1*(hmin-hmax)*(md.mesh.x-xmin)/(xmax-xmin);
-md.geometry.bed=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness;
-md.geometry.surface=md.geometry.bed+md.geometry.thickness;
+md.geometry.base=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness;
+md.geometry.surface=md.geometry.base+md.geometry.thickness;
 
 %Initial velocity and pressure
@@ -28,7 +28,4 @@
 md.materials.rheology_B=paterson(md.initialization.temperature);
 md.materials.rheology_n=3*ones(md.mesh.numberofelements,1);
-
-%Damage
-md.damage.D=zeros(md.mesh.numberofvertices,1);
 
 %Friction
Index: /issm/trunk/test/Par/SquareShelf.py
===================================================================
--- /issm/trunk/test/Par/SquareShelf.py	(revision 17805)
+++ /issm/trunk/test/Par/SquareShelf.py	(revision 17806)
@@ -17,6 +17,6 @@
 xmax=max(md.mesh.x)
 md.geometry.thickness=hmax+(hmin-hmax)*(md.mesh.y.reshape(-1,1)-ymin)/(ymax-ymin)+0.1*(hmin-hmax)*(md.mesh.x.reshape(-1,1)-xmin)/(xmax-xmin)
-md.geometry.bed=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness
-md.geometry.surface=md.geometry.bed+md.geometry.thickness
+md.geometry.base=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness
+md.geometry.surface=md.geometry.base+md.geometry.thickness
 
 #Initial velocity and pressure
@@ -59,7 +59,4 @@
 md.materials.rheology_n = 3.*numpy.ones((md.mesh.numberofelements,1))
 
-#Damage
-md.damage.D=numpy.zeros((md.mesh.numberofvertices,1))
-
 #Friction
 md.friction.coefficient = 20.*numpy.ones((md.mesh.numberofvertices,1))
Index: /issm/trunk/test/Par/SquareShelf2.par
===================================================================
--- /issm/trunk/test/Par/SquareShelf2.par	(revision 17805)
+++ /issm/trunk/test/Par/SquareShelf2.par	(revision 17806)
@@ -9,6 +9,6 @@
 xmax=max(md.mesh.x);
 md.geometry.thickness=hmax+(hmin-hmax)*(md.mesh.y-ymin)/(ymax-ymin)+0.1*(hmin-hmax)*(md.mesh.x-xmin)/(xmax-xmin);
-md.geometry.bed=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness;
-md.geometry.surface=md.geometry.bed+md.geometry.thickness;
+md.geometry.base=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness;
+md.geometry.surface=md.geometry.base+md.geometry.thickness;
 
 %Initial velocity and pressure
@@ -28,7 +28,4 @@
 md.materials.rheology_B=paterson(md.initialization.temperature);
 md.materials.rheology_n=3*ones(md.mesh.numberofelements,1);
-
-%Damage
-md.damage.D=zeros(md.mesh.numberofvertices,1);
 
 %Friction
Index: /issm/trunk/test/Par/SquareShelf2.py
===================================================================
--- /issm/trunk/test/Par/SquareShelf2.py	(revision 17805)
+++ /issm/trunk/test/Par/SquareShelf2.py	(revision 17806)
@@ -17,6 +17,6 @@
 xmax=max(md.mesh.x)
 md.geometry.thickness=hmax+(hmin-hmax)*(md.mesh.y.reshape(-1,1)-ymin)/(ymax-ymin)+0.1*(hmin-hmax)*(md.mesh.x.reshape(-1,1)-xmin)/(xmax-xmin)
-md.geometry.bed=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness
-md.geometry.surface=md.geometry.bed+md.geometry.thickness
+md.geometry.base=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness
+md.geometry.surface=md.geometry.base+md.geometry.thickness
 
 #Initial velocity and pressure
@@ -59,7 +59,4 @@
 md.materials.rheology_n = 3.*numpy.ones((md.mesh.numberofelements,1))
 
-#Damage
-md.damage.D=numpy.zeros((md.mesh.numberofvertices,1))
-
 #Friction
 md.friction.coefficient = 20.*numpy.ones((md.mesh.numberofvertices,1))
Index: /issm/trunk/test/Par/SquareShelfConstrained.par
===================================================================
--- /issm/trunk/test/Par/SquareShelfConstrained.par	(revision 17805)
+++ /issm/trunk/test/Par/SquareShelfConstrained.par	(revision 17806)
@@ -9,6 +9,6 @@
 xmax=max(md.mesh.x);
 md.geometry.thickness=hmax+(hmin-hmax)*(md.mesh.y-ymin)/(ymax-ymin)+0.1*(hmin-hmax)*(md.mesh.x-xmin)/(xmax-xmin);
-md.geometry.bed=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness;
-md.geometry.surface=md.geometry.bed+md.geometry.thickness;
+md.geometry.base=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness;
+md.geometry.surface=md.geometry.base+md.geometry.thickness;
 
 %Initial velocity 
@@ -28,7 +28,4 @@
 md.materials.rheology_B=paterson(md.initialization.temperature);
 md.materials.rheology_n=3*ones(md.mesh.numberofelements,1);
-
-%Damage
-md.damage.D=zeros(md.mesh.numberofvertices,1);
 
 %Surface mass balance and basal melting
Index: /issm/trunk/test/Par/SquareShelfConstrained.py
===================================================================
--- /issm/trunk/test/Par/SquareShelfConstrained.py	(revision 17805)
+++ /issm/trunk/test/Par/SquareShelfConstrained.py	(revision 17806)
@@ -17,6 +17,6 @@
 xmax=max(md.mesh.x)
 md.geometry.thickness=hmax+(hmin-hmax)*(md.mesh.y.reshape(-1,1)-ymin)/(ymax-ymin)+0.1*(hmin-hmax)*(md.mesh.x.reshape(-1,1)-xmin)/(xmax-xmin)
-md.geometry.bed=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness
-md.geometry.surface=md.geometry.bed+md.geometry.thickness
+md.geometry.base=-md.materials.rho_ice/md.materials.rho_water*md.geometry.thickness
+md.geometry.surface=md.geometry.base+md.geometry.thickness
 
 #Initial velocity 
@@ -39,7 +39,4 @@
 md.materials.rheology_B=paterson(md.initialization.temperature)
 md.materials.rheology_n=3.*numpy.ones((md.mesh.numberofelements,1))
-
-#Damage
-md.damage.D=numpy.zeros((md.mesh.numberofvertices,1))
 
 #Surface mass balance and basal melting
Index: /issm/trunk/test/Par/SquareThermal.par
===================================================================
--- /issm/trunk/test/Par/SquareThermal.par	(revision 17805)
+++ /issm/trunk/test/Par/SquareThermal.par	(revision 17806)
@@ -6,6 +6,6 @@
 h=1000.;
 md.geometry.thickness=h*ones(md.mesh.numberofvertices,1);
-md.geometry.bed=-1000.*ones(md.mesh.numberofvertices,1);
-md.geometry.surface=md.geometry.bed+md.geometry.thickness;
+md.geometry.base=-1000.*ones(md.mesh.numberofvertices,1);
+md.geometry.surface=md.geometry.base+md.geometry.thickness;
 
 disp('      creating velocities');
@@ -27,7 +27,4 @@
 md.materials.rheology_n=3.*ones(md.mesh.numberofelements,1);
 
-%Damage
-md.damage.D=zeros(md.mesh.numberofvertices,1);
-
 disp('      creating surface mass balance');
 md.surfaceforcings.mass_balance=ones(md.mesh.numberofvertices,1)/md.constants.yts; %1m/a
Index: /issm/trunk/test/Par/SquareThermal.py
===================================================================
--- /issm/trunk/test/Par/SquareThermal.py	(revision 17805)
+++ /issm/trunk/test/Par/SquareThermal.py	(revision 17806)
@@ -10,6 +10,6 @@
 h=1000.
 md.geometry.thickness=h*numpy.ones((md.mesh.numberofvertices,1))
-md.geometry.bed=-1000.*numpy.ones((md.mesh.numberofvertices,1))
-md.geometry.surface=md.geometry.bed+md.geometry.thickness;
+md.geometry.base=-1000.*numpy.ones((md.mesh.numberofvertices,1))
+md.geometry.surface=md.geometry.base+md.geometry.thickness;
 
 print "      creating velocities"
@@ -31,7 +31,4 @@
 md.materials.rheology_n=3.*numpy.ones((md.mesh.numberofelements,1))
 
-#Damage
-md.damage.D=numpy.zeros((md.mesh.numberofvertices,1))
-
 print "      creating surface mass balance"
 md.surfaceforcings.mass_balance=numpy.ones((md.mesh.numberofvertices,1))/md.constants.yts    #1m/a
Index: /issm/trunk/test/Par/ValleyGlacierShelf.par
===================================================================
--- /issm/trunk/test/Par/ValleyGlacierShelf.par	(revision 17806)
+++ /issm/trunk/test/Par/ValleyGlacierShelf.par	(revision 17806)
@@ -0,0 +1,94 @@
+%Start defining model parameters here
+x = md.mesh.x;
+y = md.mesh.y;
+xmin = min(x);
+xmax = max(x);
+ymin = min(y);
+ymax = max(y);
+Lx = (xmax-xmin);
+Ly = (ymax-ymin);
+xm = (xmin+xmax)/2.;
+ym = (ymin+ymax)/2.;
+
+%Geometry: U-shaped valley in y direction
+thk_center = 1000.;
+thk_margin = 0.5*thk_center;
+bmax = 0.;
+bmin = -thk_center*md.materials.rho_ice/md.materials.rho_water;
+
+alpha = 2./3.;
+slope = 0.9*(bmin-bmax)*(x-xmin)/(Lx*alpha) + 0.1*(bmin-bmax)*(y-ymin)/(Ly) + bmax;
+md.geometry.surface = (thk_center+bmax) + slope ;
+md.geometry.base = bmax + slope + 4./Ly^2*(thk_center-thk_margin)*(y-ym).^2;
+md.geometry.thickness = md.geometry.surface - md.geometry.base;
+md.geometry.bed = md.geometry.base;
+
+%Mask
+md.mask.ice_levelset = x - alpha*Lx;
+md.mask.groundedice_levelset = ones(md.mesh.numberofvertices,1);
+
+%Initial velocity 
+md.initialization.vx = zeros(md.mesh.numberofvertices,1);
+md.initialization.vy = zeros(md.mesh.numberofvertices,1);
+md.initialization.vz = zeros(md.mesh.numberofvertices,1);
+md.initialization.pressure = zeros(md.mesh.numberofvertices,1);
+
+%Materials
+md.initialization.temperature = (273.15-5.)*ones(md.mesh.numberofvertices,1);
+md.initialization.waterfraction = zeros(md.mesh.numberofvertices,1);
+md.initialization.watercolumn = zeros(md.mesh.numberofvertices,1);
+md.materials.rheology_B = paterson(md.initialization.temperature);
+md.materials.rheology_n = 3.*ones(md.mesh.numberofelements,1);
+
+%Thermal
+md.thermal.isenthalpy = 0;
+md.thermal.spctemperature = NaN(md.mesh.numberofvertices,1);
+
+%Groundingline
+md.groundingline.migration = 'SubelementMigration';
+
+%Surface mass balance and basal melting
+md.surfaceforcings.mass_balance = 0.3*ones(md.mesh.numberofvertices,1);
+md.basalforcings.melting_rate = md.surfaceforcings.mass_balance;
+
+%Friction
+md.friction.coefficient = 20.*ones(md.mesh.numberofvertices,1);
+md.friction.coefficient(find(md.mask.groundedice_levelset<0.)) = 0.;
+md.friction.p = ones(md.mesh.numberofelements,1);
+md.friction.q = ones(md.mesh.numberofelements,1);
+
+%Transient
+md.transient.isstressbalance = 1;
+md.transient.islevelset = 1;
+md.transient.ismasstransport = 0;
+md.transient.isthermal = 0;
+md.transient.isgroundingline = 1;
+md.transient.isgia = 0;
+
+%Stressbalance
+md.stressbalance.maxiter = 100;
+md.stressbalance.viscosity_overshoot = 0.0;
+md.stressbalance.restol = 0.05;
+md.stressbalance.reltol = 0.05;
+md.stressbalance.abstol = NaN;
+
+%Masstransport;
+md.masstransport.calvingrate = 0.*ones(md.mesh.numberofvertices,1);
+md.masstransport.stabilization = 1.;
+
+%Numerical parameters
+md.thermal.stabilization = 1.;
+md.settings.waitonlock = 30;
+md.steadystate.reltol = 0.05;
+md.timestepping.time_step = 1.;
+md.timestepping.final_time = 3.;
+
+%Verbose
+md.verbose = verbose(0);
+
+%Deal with boundary conditions:
+md = SetIceShelfBC(md);
+
+%Change name so that no test have the same name;
+A = dbstack;
+if (length(A)>2), md.miscellaneous.name=A(3).file(1:end-2); end
Index: /issm/trunk/test/Par/ValleyGlacierShelf.py
===================================================================
--- /issm/trunk/test/Par/ValleyGlacierShelf.py	(revision 17806)
+++ /issm/trunk/test/Par/ValleyGlacierShelf.py	(revision 17806)
@@ -0,0 +1,101 @@
+import os.path
+import netCDF4
+import numpy
+import inspect
+import math
+from verbose import verbose
+from InterpFromMeshToMesh2d import InterpFromMeshToMesh2d
+from paterson import paterson
+from SetIceShelfBC import SetIceShelfBC
+
+#Start defining model parameters here
+x=md.mesh.x.reshape(-1,1)
+y=md.mesh.y.reshape(-1,1)
+xmin, xmax = min(x), max(x)
+ymin, ymax = min(y), max(y)
+Lx=(xmax-xmin)
+Ly=(ymax-ymin)
+xm,ym = (xmin+xmax)/2., (ymin+ymax)/2.
+
+#Geometry: U-shaped valley in y direction
+thk_center = 1000.
+thk_margin = 0.5*thk_center
+bmax=0.
+bmin=-thk_center*md.materials.rho_ice/md.materials.rho_water
+
+alpha=2./3.
+slope = 0.9*(bmin-bmax)*(x-xmin)/(Lx*alpha) + 0.1*(bmin-bmax)*(y-ymin)/(Ly) + bmax
+md.geometry.surface= (thk_center+bmax) + slope 
+md.geometry.base=bmax + slope + 4./Ly**2*(thk_center-thk_margin)*(numpy.power(y-ym,2))
+md.geometry.thickness=md.geometry.surface - md.geometry.base
+md.geometry.bed = md.geometry.base
+
+#Mask
+md.mask.ice_levelset=x - alpha*Lx
+md.mask.groundedice_levelset= numpy.ones((md.mesh.numberofvertices,1))
+
+#Initial velocity 
+md.initialization.vx=numpy.zeros((md.mesh.numberofvertices,1))
+md.initialization.vy=numpy.zeros((md.mesh.numberofvertices,1))
+md.initialization.vz=numpy.zeros((md.mesh.numberofvertices,1))
+md.initialization.pressure=numpy.zeros((md.mesh.numberofvertices,1))
+
+#Materials
+md.initialization.temperature=(273.15-5.)*numpy.ones((md.mesh.numberofvertices,1))
+md.initialization.waterfraction=numpy.zeros((md.mesh.numberofvertices,1))
+md.initialization.watercolumn=numpy.zeros((md.mesh.numberofvertices,1))
+md.materials.rheology_B=paterson(md.initialization.temperature)
+md.materials.rheology_n=3.*numpy.ones((md.mesh.numberofelements,1))
+
+#Thermal
+md.thermal.isenthalpy=False
+md.thermal.spctemperature=float('nan')*numpy.ones((md.mesh.numberofvertices,1))
+
+#Groundingline
+md.groundingline.migration='SubelementMigration'
+
+#Surface mass balance and basal melting
+md.surfaceforcings.mass_balance=0.3*numpy.ones((md.mesh.numberofvertices,1))
+md.basalforcings.melting_rate=md.surfaceforcings.mass_balance
+
+#Friction
+md.friction.coefficient=20.*numpy.ones((md.mesh.numberofvertices,1))
+md.friction.coefficient[numpy.nonzero(md.mask.groundedice_levelset<0.)[0]]=0.
+md.friction.p=numpy.ones((md.mesh.numberofelements,1))
+md.friction.q=numpy.ones((md.mesh.numberofelements,1))
+
+#Transient
+md.transient.isstressbalance=True
+md.transient.islevelset=True
+md.transient.ismasstransport=False
+md.transient.isthermal=False
+md.transient.isgroundingline=True
+md.transient.isgia=False
+
+#Stressbalance
+md.stressbalance.maxiter=100
+md.stressbalance.viscosity_overshoot=0.0
+md.stressbalance.restol=0.05
+md.stressbalance.reltol=0.05
+md.stressbalance.abstol=float('nan')
+
+#Masstransport
+md.masstransport.calvingrate=0.*numpy.ones((md.mesh.numberofvertices,1))
+md.masstransport.stabilization=1.
+
+#Numerical parameters
+md.thermal.stabilization=1.
+md.settings.waitonlock=30
+md.steadystate.reltol=0.05
+md.timestepping.time_step=1.
+md.timestepping.final_time=3.
+
+#Verbose
+md.verbose = verbose(0)
+
+#Deal with boundary conditions:
+md = SetIceShelfBC(md)
+
+#Change name so that no tests have the same name
+if len(inspect.stack()) > 2:
+	md.miscellaneous.name = os.path.basename(inspect.stack()[2][1]).split('.')[0]
