Index: /issm/oecreview/Archive/27230-27343/Date.tex
===================================================================
--- /issm/oecreview/Archive/27230-27343/Date.tex	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/Date.tex	(revision 27344)
@@ -0,0 +1,1 @@
+27-Oct-PM
Index: /issm/oecreview/Archive/27230-27343/ISSM-27233-27234.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27233-27234.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27233-27234.diff	(revision 27344)
@@ -0,0 +1,13 @@
+Index: ../trunk-jpl/configure.ac
+===================================================================
+--- ../trunk-jpl/configure.ac	(revision 27233)
++++ ../trunk-jpl/configure.ac	(revision 27234)
+@@ -1,7 +1,7 @@
+ # Process this file with autoconf to produce a configure script.
+ 
+ #AUTOCONF
+-AC_INIT([Ice-sheet and Sea-level System Model (ISSM)],[4.21],[issm@jpl.nasa.gov],[issm],[http://issm.jpl.nasa.gov]) #Initializing configure
++AC_INIT([Ice-sheet and Sea-level System Model (ISSM)],[4.22],[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
+ m4_include([m4/issm_options.m4])
Index: /issm/oecreview/Archive/27230-27343/ISSM-27236-27237.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27236-27237.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27236-27237.diff	(revision 27344)
@@ -0,0 +1,35 @@
+Index: ../trunk-jpl/src/c/modules/SurfaceMassBalancex/Gembx.cpp
+===================================================================
+--- ../trunk-jpl/src/c/modules/SurfaceMassBalancex/Gembx.cpp	(revision 27236)
++++ ../trunk-jpl/src/c/modules/SurfaceMassBalancex/Gembx.cpp	(revision 27237)
+@@ -704,7 +704,7 @@
+ 	*padiff=adiff;
+ 
+ }  /*}}}*/
+-void thermo(IssmDouble* pshf, IssmDouble* plhf, IssmDouble* pEC, IssmDouble** pT, IssmDouble* pulwrf, IssmDouble* re, IssmDouble* dz, IssmDouble* d, IssmDouble* swf, IssmDouble dlwrf, IssmDouble Ta, IssmDouble V, IssmDouble eAir, IssmDouble pAir, IssmDouble tcIdx, IssmDouble eIdx, IssmDouble teValue, IssmDouble dulwrfValue, IssmDouble teThresh, IssmDouble Ws, IssmDouble dt0, IssmDouble dzMin, int m, IssmDouble Vz, IssmDouble Tz, IssmDouble thermo_scaling, IssmDouble dIce, int sid, bool isconstrainsurfaceT, bool isdeltaLWup) { /*{{{*/
++void thermo(IssmDouble* pshf, IssmDouble* plhf, IssmDouble* pEC, IssmDouble** pT, IssmDouble* pulwrf, IssmDouble* re, IssmDouble* dz, IssmDouble* d, IssmDouble* swf, IssmDouble dlwrf, IssmDouble Ta, IssmDouble V, IssmDouble eAir, IssmDouble pAir, int tcIdx, int eIdx, IssmDouble teValue, IssmDouble dulwrfValue, IssmDouble teThresh, IssmDouble Ws, IssmDouble dt0, IssmDouble dzMin, int m, IssmDouble Vz, IssmDouble Tz, IssmDouble thermo_scaling, IssmDouble dIce, int sid, bool isconstrainsurfaceT, bool isdeltaLWup) { /*{{{*/
+ 
+ 	/* ENGLACIAL THERMODYNAMICS*/
+ 
+@@ -1166,7 +1166,7 @@
+ 		if(isdeltaLWup) deltaULW = dulwrfValue;
+ 		//If user wants to directly set emissivity, or grain radius is larger than the
+ 		// threshold, or eIdx is 2 and we have wet snow or ice, use prescribed emissivity
+-		if(eIdx==0 || (teThresh - re[0])<Gdntol || (eIdx==2 && z0>0.001)) emissivity = teValue;
++		if(eIdx==0 || (teThresh - re[0])<Gdntol || (eIdx==2 && z0>(0.001+Gdntol))) emissivity = teValue;
+ 		ulw = - (SB * pow(Ts,4.0)* emissivity + deltaULW) * dt; 
+ 		ulwrf = ulwrf - ulw/dt0;
+ 
+Index: ../trunk-jpl/src/c/modules/SurfaceMassBalancex/SurfaceMassBalancex.h
+===================================================================
+--- ../trunk-jpl/src/c/modules/SurfaceMassBalancex/SurfaceMassBalancex.h	(revision 27236)
++++ ../trunk-jpl/src/c/modules/SurfaceMassBalancex/SurfaceMassBalancex.h	(revision 27237)
+@@ -33,7 +33,7 @@
+ void grainGrowth(IssmDouble** pre, IssmDouble** pgdn, IssmDouble** pgsp, IssmDouble* T,IssmDouble* dz,IssmDouble* d, IssmDouble* W,IssmDouble smb_dt,int m,int aIdx, int sid);
+ void albedo(IssmDouble** a, IssmDouble** adiff, int aIdx, IssmDouble* re, IssmDouble* dz, IssmDouble* d, IssmDouble cldFrac, IssmDouble aIce, IssmDouble aSnow, IssmDouble aValue, IssmDouble adThresh, IssmDouble* T, IssmDouble* W, IssmDouble P, IssmDouble EC, IssmDouble Msurf, IssmDouble clabSnow, IssmDouble clabIce, IssmDouble SZA, IssmDouble COT, IssmDouble t0wet, IssmDouble t0dry, IssmDouble K, IssmDouble dt, IssmDouble dIce, int m, int sid);
+ void shortwave(IssmDouble** pswf, int swIdx, int aIdx, IssmDouble dsw, IssmDouble dswdiff, IssmDouble as, IssmDouble asdiff, IssmDouble* d, IssmDouble* dz, IssmDouble* re, IssmDouble dIce, int m, int sid);
+-void thermo(IssmDouble* pshf, IssmDouble* plhf, IssmDouble* pEC, IssmDouble** T, IssmDouble* pulwrf, IssmDouble* re, IssmDouble* dz, IssmDouble* d, IssmDouble* swf, IssmDouble dlw, IssmDouble Ta, IssmDouble V, IssmDouble eAir, IssmDouble pAir, IssmDouble tcIdx, IssmDouble eIdx, IssmDouble teValue, IssmDouble dulwrfValue, IssmDouble teThresh, IssmDouble Ws, IssmDouble dt0, IssmDouble dzMin, int m, IssmDouble Vz, IssmDouble Tz, IssmDouble thermo_scaling, IssmDouble dIce, int sid, bool isconstrainsurfaceT, bool isdeltaLWup);
++void thermo(IssmDouble* pshf, IssmDouble* plhf, IssmDouble* pEC, IssmDouble** T, IssmDouble* pulwrf, IssmDouble* re, IssmDouble* dz, IssmDouble* d, IssmDouble* swf, IssmDouble dlw, IssmDouble Ta, IssmDouble V, IssmDouble eAir, IssmDouble pAir, int tcIdx, int eIdx, IssmDouble teValue, IssmDouble dulwrfValue, IssmDouble teThresh, IssmDouble Ws, IssmDouble dt0, IssmDouble dzMin, int m, IssmDouble Vz, IssmDouble Tz, IssmDouble thermo_scaling, IssmDouble dIce, int sid, bool isconstrainsurfaceT, bool isdeltaLWup);
+ void accumulation(IssmDouble** pT, IssmDouble** pdz, IssmDouble** pd, IssmDouble** pW, IssmDouble** pa, IssmDouble** padiff, IssmDouble** pre, IssmDouble** pgdn, IssmDouble** pgsp, IssmDouble* pRa, int* pm, int aIdx, int dsnowIdx, IssmDouble Tmean, IssmDouble Ta, IssmDouble P, IssmDouble dzMin, IssmDouble aSnow, IssmDouble C, IssmDouble V, IssmDouble Vmean, IssmDouble dIce, int sid);
+ void melt(IssmDouble* pM, IssmDouble* pMs, IssmDouble* pR, IssmDouble* pF, IssmDouble* pmAdd, IssmDouble* pdz_add, IssmDouble** pT, IssmDouble** pd, IssmDouble** pdz, IssmDouble** pW, IssmDouble** pa, IssmDouble** padiff, IssmDouble** pre, IssmDouble** pgdn, IssmDouble** pgsp, int* pn, IssmDouble Ra, IssmDouble dzMin, IssmDouble zMax, IssmDouble zMin, IssmDouble zTop, IssmDouble zY, IssmDouble dIce, int sid);
+ void managelayers(IssmDouble* pmAdd, IssmDouble* pdz_add, IssmDouble* paddE, IssmDouble** pm, IssmDouble** pEI, IssmDouble** pEW, IssmDouble** pT, IssmDouble** pd, IssmDouble** pdz, IssmDouble** pW, IssmDouble** pa, IssmDouble** padiff, IssmDouble** pre, IssmDouble** pgdn, IssmDouble** pgsp, int* pn, IssmDouble dzMin, IssmDouble zMax, IssmDouble zMin, IssmDouble zTop, IssmDouble zY);
Index: /issm/oecreview/Archive/27230-27343/ISSM-27237-27238.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27237-27238.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27237-27238.diff	(revision 27344)
@@ -0,0 +1,13 @@
+Index: ../trunk-jpl/src/c/modules/SurfaceMassBalancex/Gembx.cpp
+===================================================================
+--- ../trunk-jpl/src/c/modules/SurfaceMassBalancex/Gembx.cpp	(revision 27237)
++++ ../trunk-jpl/src/c/modules/SurfaceMassBalancex/Gembx.cpp	(revision 27238)
+@@ -1852,7 +1852,7 @@
+ 				break;
+ 			}
+ 			// if reaches impermeable ice layer all liquid water runs off (R)
+-			else if (d[i] >= dIce-Dtol || (d[i] >= dPHC-Dtol && depthice>0.1)){  // dPHC = pore hole close off [kg m-3]
++			else if (d[i] >= dIce-Dtol || (d[i] >= dPHC-Dtol && depthice>0.1+Dtol)){  // dPHC = pore hole close off [kg m-3]
+ 				// _printf_("ICE LAYER");
+ 				// no water freezes in this cell
+ 				// no water percolates to lower cell
Index: /issm/oecreview/Archive/27230-27343/ISSM-27240-27241.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27240-27241.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27240-27241.diff	(revision 27344)
@@ -0,0 +1,239 @@
+Index: ../trunk-jpl/src/c/modules/SurfaceMassBalancex/Gembx.cpp
+===================================================================
+--- ../trunk-jpl/src/c/modules/SurfaceMassBalancex/Gembx.cpp	(revision 27240)
++++ ../trunk-jpl/src/c/modules/SurfaceMassBalancex/Gembx.cpp	(revision 27241)
+@@ -100,7 +100,7 @@
+ 		_error_("top grid cell structure length does not go evenly into specified top structure depth, adjust dzTop or zTop\n");
+ 	}
+ 	#endif
+-	if(dzTop < 0.05){
++	if(dzTop < 0.05-Dtol){
+ 		_printf_("initial top grid cell length (dzTop) is < 0.05 m\n");
+ 	}
+ 	gpTop=reCast<int,IssmDouble>(dgpTop);
+@@ -107,7 +107,7 @@
+ 
+ 	//initialize top grid depth vector
+ 	dzT = xNew<IssmDouble>(gpTop); 
+-	for (i=0;i<gpTop;i++)dzT[i]=dzTop;
++	for (i=0;i<gpTop-Dtol;i++)dzT[i]=dzTop;
+ 
+ 	//bottom grid cell depth = x*zY^(cells from to structure)
+ 	//figure out the number of grid points in the bottom vector (not known a priori)
+@@ -114,7 +114,7 @@
+ 	gp0 = dzTop;
+ 	z0 = zTop;
+ 	gpBottom = 0;
+-	while (zMax > z0){
++	while (zMax > z0+Dtol){
+ 		gp0= gp0 * zY;
+ 		z0 = z0 + gp0;
+ 		gpBottom++;
+@@ -130,7 +130,7 @@
+ 
+ 	//combine top and bottom dz vectors
+ 	dz = xNew<IssmDouble>(gpTop+gpBottom);
+-	for(i=0;i<gpTop;i++){
++	for(i=0;i<gpTop-Dtol;i++){
+ 		dz[i]=dzT[i];
+ 	}
+ 	for(i=0;i<gpBottom;i++){
+@@ -214,8 +214,8 @@
+ 	IssmDouble S1 = 3.0 / (0.091 * re[0]);
+ 
+ 	//effective solar zenith angle
+-	IssmDouble x = min(pow(t/(3*cos(Pi*SZA/180.0)),0.5), 1.0);
+-	IssmDouble u = 0.64*x + (1-x)*cos(Pi*SZA/180.0);
++	IssmDouble x = min(pow(t/(3.0*cos(Pi*SZA/180.0)),0.5), 1.0);
++	IssmDouble u = 0.64*x + (1.0-x)*cos(Pi*SZA/180.0);
+ 
+ 	// pure snow albedo
+ 	IssmDouble as = 1.48 - pow(S1,-0.07);
+@@ -242,16 +242,16 @@
+ 		IssmDouble dac2 = max(0.04 - as2, pow(-c2,0.55)/(0.16 + 0.6*pow(S1,0.5) + (1.8*pow(c2,0.6))*pow(S2,-0.25)));
+ 
+ 		// determine the effective change due to finite depth and soot loading
+-		IssmDouble A = min(1.0, (2.1 * pow(z1,1.35*(1-as) - 0.1*c1 - 0.13)));
++		IssmDouble A = min(1.0, (2.1 * pow(z1,1.35*(1.0-as) - 0.1*c1 - 0.13)));
+ 
+ 		dac =  (as2 + dac2 - as) + A*((as + dac) - (as2 + dac2));
+ 	}
+ 
+ 	// change in albedo due to solar zenith angle
+-	IssmDouble dasz = 0.53*as*(1 - (as + dac))*pow(1 - u,1.2);
++	IssmDouble dasz = 0.53*as*(1.0 - (as + dac))*pow(1.0 - u,1.2);
+ 
+ 	// change in albedo due to cloud (apart from change in diffuse fraction)
+-	IssmDouble dat = (0.1*t*pow(as + dac,1.3)) / (pow(1 + 1.5*t,as));
++	IssmDouble dat = (0.1*t*pow(as + dac,1.3)) / (pow(1.0 + 1.5*t,as));
+ 
+ 	// Broadband albedo
+ 	a = as + dac + dasz + dat;
+@@ -550,8 +550,8 @@
+ 	adiff=*padiff;
+ 
+ 	//some constants:
+-	const IssmDouble dSnow = 300;   // density of fresh snow [kg m-3]       
+-	const IssmDouble dPHC = 830;  //Pore closeoff density
++	const IssmDouble dSnow = 300.0;   // density of fresh snow [kg m-3]       
++	const IssmDouble dPHC = 830.0;  //Pore closeoff density
+ 	const IssmDouble ai_max = 0.58;  //maximum ice albedo, from Lefebre,2003
+ 	const IssmDouble ai_min = aIce;  //minimum ice albedo
+ 	const IssmDouble as_min = 0.65;  //minimum snow albedo, from Alexander 2014
+@@ -564,7 +564,7 @@
+ 			//function of effective grain radius
+ 			// clabSnow, IssmDouble clabIce, IssmDouble SZA, IssmDouble COT, int m
+ 			a[0]=gardnerAlb(re, dz, d, clabSnow, clabIce, SZA, COT, dPHC, m);
+-			adiff[0]=gardnerAlb(re, dz, d, clabSnow, clabIce, 50, COT, dPHC, m);
++			adiff[0]=gardnerAlb(re, dz, d, clabSnow, clabIce, 50.0, COT, dPHC, m);
+ 		}
+ 		else if(aIdx==2){
+ 
+@@ -687,7 +687,7 @@
+ 					//Msw(t) is the time-dependent accumulated amount of excessive surface meltwater
+ 					//  before run-off in kg m^-2 (melt per GEMB timestep, i.e. 3 hourly)
+ 					IssmDouble M = Msurf+W[0];
+-					a[0]=max(ai_min + (ai_max - ai_min)*exp(-1*(M/200)), ai_min);
++					a[0]=max(ai_min + (ai_max - ai_min)*exp(-1.0*(M/200.0)), ai_min);
+ 
+ 				}
+ 			}
+@@ -695,8 +695,8 @@
+ 	}
+ 
+ 	// Check for erroneous values
+-	if (a[0] > 1) _printf_("albedo > 1.0\n");
+-	else if (a[0] < 0) _printf_("albedo is negative\n");
++	if (a[0] > 1.0+Ttol) _printf_("albedo > 1.0\n");
++	else if (a[0] < 0.0-Dtol) _printf_("albedo is negative\n");
+ 	else if (xIsNan(a[0])) _error_("albedo == NAN\n");
+ 
+ 	/*Assign output pointers:*/
+@@ -958,7 +958,7 @@
+ 	Td=xNew<IssmDouble>(m);
+ 
+ 	/* CALCULATE ENERGY SOURCES AND DIFFUSION FOR EVERY TIME STEP [dt]*/
+-	for (IssmDouble i=1;i<=dt0;i+=dt){
++	for (IssmDouble i=1.0;i<=dt0;i+=dt){
+ 
+ 		// PART OF ENERGY CONSERVATION CHECK
+ 		// store initial temperature
+@@ -1067,8 +1067,8 @@
+                zL=Ri;
+             }
+             //zL = min(zL, 0.5); //Sjoblom, 2014
+-            zLM=max(zL/Vz*z0,1.e-3);
+-            zLT=max(zL/Tz*zT,1.e-3);
++            zLM=max(zL/Vz*z0,1e-3);
++            zLT=max(zL/Tz*zT,1e-3);
+ 
+             //Ding et al. 2020, from Beljaars and Holtslag (1991)
+             PhiMz=-1.*(a1*zL + b1*(zL-c1/d1)*exp(-1.*d1*zL) + b1*c1/d1);
+@@ -1465,7 +1465,7 @@
+ 
+ 	// MAIN FUNCTION
+ 	// specify constants
+-	IssmDouble dSnow = 150;    // density of snow [kg m-3]
++	IssmDouble dSnow = 150.0;    // density of snow [kg m-3]
+ 	IssmDouble reNew = 0.05;    // new snow grain size [mm]
+ 	IssmDouble gdnNew = 1.0;     // new snow dendricity 
+ 	IssmDouble gspNew = 0.5;   // new snow sphericity 
+@@ -1473,9 +1473,9 @@
+ 	/*intermediary: */
+ 	IssmDouble* mInit=NULL;
+ 	bool        top=true;
+-	IssmDouble  mass=0;
+-	IssmDouble  massinit=0;
+-	IssmDouble  mass_diff=0;
++	IssmDouble  mass=0.0;
++	IssmDouble  massinit=0.0;
++	IssmDouble  mass_diff=0.0;
+ 
+ 	/*output: */
+ 	IssmDouble* T=NULL;
+@@ -1511,12 +1511,12 @@
+ 			break;
+ 
+ 		case 1: // Density of Antarctica snow
+-			dSnow = 350;
+-			//dSnow = 360; //FirnMICE Lundin et al., 2017
++			dSnow = 350.0;
++			//dSnow = 360.0; //FirnMICE Lundin et al., 2017
+ 			break;
+ 
+ 		case 2: // Density of Greenland snow, Fausto et al., 2018
+-			dSnow = 315;
++			dSnow = 315.0;
+ 			//From Vionnet et al., 2012 (Crocus)
+ 			gdnNew = min(max(1.29 - 0.17*V,0.20),1.0);
+ 			gspNew = min(max(0.08*V + 0.38,0.5),0.9);
+@@ -1526,7 +1526,7 @@
+ 		case 3: //Surface snow accumulation density from Kaspers et al., 2004, Antarctica
+ 			//dSnow = alpha1 + beta1*T + delta1*C + epsilon1*W
+ 			//     7.36x10-2  1.06x10-3  6.69x10-2  4.77x10-3 
+-			dSnow=(7.36e-2 + 1.06e-3*min(Tmean,CtoK-Ttol) + 6.69e-2*C/1000 + 4.77e-3*Vmean)*1000;
++			dSnow=(7.36e-2 + 1.06e-3*min(Tmean,CtoK-Ttol) + 6.69e-2*C/1000. + 4.77e-3*Vmean)*1000.;
+ 			break;
+ 
+ 		case 4: // Kuipers Munneke and others (2015), Greenland
+@@ -1727,11 +1727,11 @@
+ 
+ 	// specify irreducible water content saturation [fraction]
+ 	const IssmDouble Swi = 0.07;                     // assumed constant after Colbeck, 1974
+-	const IssmDouble dPHC = 830;                     //Pore closeoff density
++	const IssmDouble dPHC = 830.0;                     //Pore closeoff density
+ 
+ 	//// REFREEZE PORE WATER
+ 	// check if any pore water
+-	if (cellsum(W,n) >0.0+Wtol){
++	if (cellsum(W,n) > 0.0+Wtol){
+ 		if(VerboseSmb() && sid==0 && IssmComm::GetRank()==0)_printf0_("      pore water refreeze\n");
+ 		// calculate maximum freeze amount, maxF [kg]
+ 		for(int i=0;i<n;i++) maxF[i] = max(0.0, -((T[i] - CtoK) * m[i] * CI) / LF);
+@@ -1895,7 +1895,7 @@
+ 				if (dW[i] < 0.0-Wtol){                         // excess pore water
+ 					dMax = (dIce - d[i])*dz_0;          // maximum refreeze                                             
+ 					IssmDouble maxF2 = min(dMax, maxF[i]-F1);      // maximum refreeze
+-					F2 = min(-1*dW[i], maxF2);            // pore water refreeze
++					F2 = min(-1.0*dW[i], maxF2);            // pore water refreeze
+ 					m[i] = m[i] + F2;                   // mass after refreeze
+ 					d[i] = m[i]/dz_0;
+ 				}
+@@ -2155,16 +2155,16 @@
+ 	Zcum[0]=dz[0]; // Compute a cumulative depth vector
+ 	for (int i=0;i<n;i++){
+ 		if (i==0){
+-			dzMax2[i]=dzMin*2;
++			dzMax2[i]=dzMin*2.0;
+ 		}
+ 		else{
+ 			Zcum[i]=Zcum[i-1]+dz[i];
+ 			if (Zcum[i]<=zTop+Dtol){
+-				dzMax2[i]=dzMin*2;
++				dzMax2[i]=dzMin*2.0;
+ 				X=i;
+ 			}
+ 			else{
+-				dzMax2[i]=max(zY2*dzMin2[i-1],dzMin*2);
++				dzMax2[i]=max(zY2*dzMin2[i-1],dzMin*2.0);
+ 			}
+ 		}
+ 	}
+@@ -2415,7 +2415,7 @@
+ 				//M1 = max(2.7950 - (0.3318 * log(C)),0.25);
+ 				// ERA5 new aIdx=1, swIdx=0
+ 				if (aIdx==1 && swIdx==0){
+-					if (fabs(adThresh - 820) < Dtol){
++					if (fabs(adThresh - 820.0) < Dtol){
+                   // ERA5 v4
+                   M0 = max(1.5131 - (0.1317 * log(C)),0.25);
+                   M1 = max(1.8819 - (0.2158 * log(C)),0.25);
+@@ -2460,7 +2460,7 @@
+ 				//M1 = max(2.8901 - (0.3014 * log(C)),0.25);
+ 				// ERA5 new aIdx=1, swIdx=0
+ 				if (aIdx==1 && swIdx==0){
+-					if (fabs(adThresh - 820) < Dtol){
++					if (fabs(adThresh - 820.0) < Dtol){
+ 						// ERA5 v4
+ 						M0 = max(1.3566 - (0.1350 * log(C)),0.25);
+ 						M1 = max(1.8705 - (0.2290 * log(C)),0.25);
Index: /issm/oecreview/Archive/27230-27343/ISSM-27241-27242.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27241-27242.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27241-27242.diff	(revision 27344)
@@ -0,0 +1,82 @@
+Index: ../trunk-jpl/test/NightlyRun/test244.m
+===================================================================
+--- ../trunk-jpl/test/NightlyRun/test244.m	(revision 27241)
++++ ../trunk-jpl/test/NightlyRun/test244.m	(revision 27242)
+@@ -115,7 +115,7 @@
+ 	md.results.dakota.moments=[md.results.dakota.moments md.results.dakota.dresp_out(i).stddev];
+ end
+ field_names     ={'moments'};
+-field_tolerances={1e-11};
++field_tolerances={2e-9};
+ field_values={...
+ 	md.results.dakota.moments,...
+ 	};
+Index: ../trunk-jpl/test/NightlyRun/test244.py
+===================================================================
+--- ../trunk-jpl/test/NightlyRun/test244.py	(revision 27241)
++++ ../trunk-jpl/test/NightlyRun/test244.py	(revision 27242)
+@@ -142,5 +142,5 @@
+     md.results.dakota.moments.append(md.results.dakota.dresp_out[i].stddev)
+ 
+ field_names = ['moments']
+-field_tolerances = [1e-11]
++field_tolerances = [2e-9]
+ field_values = [md.results.dakota.moments]
+Index: ../trunk-jpl/test/NightlyRun/test252.m
+===================================================================
+--- ../trunk-jpl/test/NightlyRun/test252.m	(revision 27241)
++++ ../trunk-jpl/test/NightlyRun/test252.m	(revision 27242)
+@@ -67,8 +67,8 @@
+ 	'SmbDz4','SmbT4' ,'SmbD4' ,'SmbRe4','SmbGdn4','SmbGsp4','SmbA4' ,'SmbEC4','SmbMassBalance4','SmbMAdd4','SmbDzAdd4','SmbFAC4'};
+ 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-11,1e-10,2e-11,1e-11,1e-12,1e-11,1e-12,1e-12,1e-12,1e-11,...
+-                   1e-12,1e-12,2e-12,2e-11,4e-11,1e-11,1e-12,1e-11,1e-11,1e-12,1e-12,1e-11,...
+-                   1e-11,1e-11,4e-11,4e-11,1e-12,4e-11,1e-12,3e-12,1e-10,1e-12,1e-12,2e-11};
++                   1e-12,1e-12,2e-12,2e-11,4e-11,1e-11,1e-12,2e-11,2e-11,1e-12,1e-12,1e-11,...
++                   1e-11,1e-11,4e-11,4e-11,2e-11,4e-11,1e-12,3e-12,1e-10,1e-12,1e-12,2e-11};
+ 
+ field_values={...
+ 	(nlayers)...
+Index: ../trunk-jpl/test/NightlyRun/test252.py
+===================================================================
+--- ../trunk-jpl/test/NightlyRun/test252.py	(revision 27241)
++++ ../trunk-jpl/test/NightlyRun/test252.py	(revision 27242)
+@@ -82,8 +82,8 @@
+                'SmbDz4', 'SmbT4', 'SmbD4', 'SmbRe4', 'SmbGdn4', 'SmbGsp4', 'SmbA4', 'SmbEC4', 'SmbMassBalance4', 'SmbMAdd4', 'SmbDzAdd4', 'SmbFAC4']
+ 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-11, 1e-10, 2e-11, 1e-11, 1e-12, 1e-11, 1e-12, 1e-12, 1e-12, 1e-11,
+-                    1e-12, 1e-12, 2e-12, 2e-11, 4e-11, 1e-11, 1e-12, 1e-11, 1e-11, 1e-12, 1e-12, 1e-11,
+-                    1e-11, 1e-11, 4e-11, 4e-11, 1e-12, 4e-11, 1e-12, 3e-12, 1e-10, 1e-12, 1e-12, 2e-11]
++                    1e-12, 1e-12, 2e-12, 2e-11, 4e-11, 1e-11, 1e-12, 2e-11, 2e-11, 1e-12, 1e-12, 1e-11,
++                    1e-11, 1e-11, 4e-11, 4e-11, 2e-11, 4e-11, 1e-12, 3e-12, 1e-10, 1e-12, 1e-12, 2e-11]
+ # Shape is different in python solution (fixed using reshape) which can cause test failure
+ field_values = [nlayers,
+                 md.results.TransientSolution[0].SmbDz[0, 0:nlayers].reshape(1, -1),
+Index: ../trunk-jpl/test/NightlyRun/test243.m
+===================================================================
+--- ../trunk-jpl/test/NightlyRun/test243.m	(revision 27241)
++++ ../trunk-jpl/test/NightlyRun/test243.m	(revision 27242)
+@@ -56,7 +56,7 @@
+ 
+ %Fields and tolerances to track changes
+ field_names      ={'Layers','SmbDz','SmbT','SmbD','SmbRe','SmbGdn','SmbGsp','SmbA' ,'SmbEC','SmbMassBalance','SmbMAdd','SmbDzAdd','SmbFAC','SmbMeanSHF','SmbMeanLHF','SmbMeanULW','SmbNetLW','SmbNetSW','SmbAccumulatedMassBalance','SmbAccumulatedRunoff','SmbAccumulatedMelt','SmbAccumulatedEC','SmbAccumulatedPrecipitation','SmbAccumulatedRain','SmbAccumulatedRefreeze','SmbRunoff','SmbMelt','SmbEC','SmbPrecipitation','SmbRain','SmbRefreeze','SmbWAdd'};
+-field_tolerances ={1e-12,2e-12,1e-12,2e-11,1e-11,2e-11,1e-11,1e-12,1e-11,1e-12,1e-12,1e-12,1e-11,2e-11,2e-11,1e-11,9e-10,2e-11,1e-11,9e-10,2e-11,1e-11,1e-11,1e-11,1e-11,1e-11,1e-11,1e-11,1e-11,1e-11,1e-11,1e-11};
++field_tolerances ={1e-12,2e-12,1e-12,2e-11,1e-11,2e-11,2e-11,1e-12,1e-11,1e-12,1e-12,1e-12,1e-11,2e-11,2e-11,1e-11,9e-10,2e-11,1e-11,9e-10,2e-11,3e-11,1e-11,1e-11,1e-11,5e-11,2e-11,1e-11,1e-11,1e-11,1e-11,1e-11};
+ 
+ field_values={...
+ 	(nlayers),...
+Index: ../trunk-jpl/test/NightlyRun/test243.py
+===================================================================
+--- ../trunk-jpl/test/NightlyRun/test243.py	(revision 27241)
++++ ../trunk-jpl/test/NightlyRun/test243.py	(revision 27242)
+@@ -69,9 +69,8 @@
+ 
+ #Fields and tolerances to track changes
+ field_names = ['Layers', 'SmbDz', 'SmbT', 'SmbD', 'SmbRe', 'SmbGdn', 'SmbGsp', 'SmbA', 'SmbEC', 'SmbMassBalance', 'SmbMAdd', 'SmbDzAdd', 'SmbFAC', 'SmbMeanSHF', 'SmbMeanLHF', 'SmbMeanULW', 'SmbNetLW', 'SmbNetSW', 'SmbAccumulatedMassBalance', 'SmbAccumulatedRunoff', 'SmbAccumulatedMelt', 'SmbAccumulatedEC', 'SmbAccumulatedPrecipitation', 'SmbAccumulatedRain', 'SmbAccumulatedRefreeze', 'SmbRunoff', 'SmbMelt', 'SmbEC', 'SmbPrecipitation', 'SmbRain', 'SmbRefreeze', 'SmbWAdd']
+-field_tolerances = [1e-12, 2e-12, 1e-12, 2e-11, 1e-11, 2e-11, 1e-11, 1e-12, 1e-11, 1e-12, 1e-12, 1e-12, 1e-11, 2e-11, 2e-11, 1e-11, 9e-10, 2e-11, 1e-11, 9e-10, 2e-11, 1e-11, 1e-11, 1e-11, 1e-11, 1e-11, 1e-11, 1e-11, 1e-11, 1e-11, 1e-11, 1e-11]
++field_tolerances = [1e-12, 2e-12, 1e-12, 2e-11, 1e-11, 2e-11, 2e-11, 1e-12, 1e-11, 1e-12, 1e-12, 1e-12, 1e-11, 2e-11, 2e-11, 1e-11, 9e-10, 2e-11, 1e-11, 9e-10, 2e-11, 3e-11, 1e-11, 1e-11, 1e-11, 5e-11, 2e-11, 1e-11, 1e-11, 1e-11, 1e-11, 1e-11]
+ 
+-
+ # Shape is different in python solution (fixed using reshape) which can cause test failure
+ field_values = [
+     nlayers,
Index: /issm/oecreview/Archive/27230-27343/ISSM-27242-27243.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27242-27243.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27242-27243.diff	(revision 27344)
@@ -0,0 +1,26 @@
+Index: ../trunk-jpl/test/NightlyRun/test243.m
+===================================================================
+--- ../trunk-jpl/test/NightlyRun/test243.m	(revision 27242)
++++ ../trunk-jpl/test/NightlyRun/test243.m	(revision 27243)
+@@ -56,7 +56,7 @@
+ 
+ %Fields and tolerances to track changes
+ field_names      ={'Layers','SmbDz','SmbT','SmbD','SmbRe','SmbGdn','SmbGsp','SmbA' ,'SmbEC','SmbMassBalance','SmbMAdd','SmbDzAdd','SmbFAC','SmbMeanSHF','SmbMeanLHF','SmbMeanULW','SmbNetLW','SmbNetSW','SmbAccumulatedMassBalance','SmbAccumulatedRunoff','SmbAccumulatedMelt','SmbAccumulatedEC','SmbAccumulatedPrecipitation','SmbAccumulatedRain','SmbAccumulatedRefreeze','SmbRunoff','SmbMelt','SmbEC','SmbPrecipitation','SmbRain','SmbRefreeze','SmbWAdd'};
+-field_tolerances ={1e-12,2e-12,1e-12,2e-11,1e-11,2e-11,2e-11,1e-12,1e-11,1e-12,1e-12,1e-12,1e-11,2e-11,2e-11,1e-11,9e-10,2e-11,1e-11,9e-10,2e-11,3e-11,1e-11,1e-11,1e-11,5e-11,2e-11,1e-11,1e-11,1e-11,1e-11,1e-11};
++field_tolerances ={1e-12,2e-11,2e-11,2e-11,3e-11,3e-11,3e-11,1e-12,2e-11,1e-12,1e-12,1e-12,2e-11,2e-11,2e-11,1e-11,9e-10,2e-11,1e-11,9e-10,2e-11,5e-10,1e-11,1e-11,1e-11,2e-10,2e-11,1e-11,1e-11,1e-11,1e-11,1e-11};
+ 
+ field_values={...
+ 	(nlayers),...
+Index: ../trunk-jpl/test/NightlyRun/test243.py
+===================================================================
+--- ../trunk-jpl/test/NightlyRun/test243.py	(revision 27242)
++++ ../trunk-jpl/test/NightlyRun/test243.py	(revision 27243)
+@@ -69,7 +69,7 @@
+ 
+ #Fields and tolerances to track changes
+ field_names = ['Layers', 'SmbDz', 'SmbT', 'SmbD', 'SmbRe', 'SmbGdn', 'SmbGsp', 'SmbA', 'SmbEC', 'SmbMassBalance', 'SmbMAdd', 'SmbDzAdd', 'SmbFAC', 'SmbMeanSHF', 'SmbMeanLHF', 'SmbMeanULW', 'SmbNetLW', 'SmbNetSW', 'SmbAccumulatedMassBalance', 'SmbAccumulatedRunoff', 'SmbAccumulatedMelt', 'SmbAccumulatedEC', 'SmbAccumulatedPrecipitation', 'SmbAccumulatedRain', 'SmbAccumulatedRefreeze', 'SmbRunoff', 'SmbMelt', 'SmbEC', 'SmbPrecipitation', 'SmbRain', 'SmbRefreeze', 'SmbWAdd']
+-field_tolerances = [1e-12, 2e-12, 1e-12, 2e-11, 1e-11, 2e-11, 2e-11, 1e-12, 1e-11, 1e-12, 1e-12, 1e-12, 1e-11, 2e-11, 2e-11, 1e-11, 9e-10, 2e-11, 1e-11, 9e-10, 2e-11, 3e-11, 1e-11, 1e-11, 1e-11, 5e-11, 2e-11, 1e-11, 1e-11, 1e-11, 1e-11, 1e-11]
++field_tolerances = [1e-12, 2e-11, 2e-11, 2e-11, 3e-11, 3e-11, 3e-11, 1e-12, 2e-11, 1e-12, 1e-12, 1e-12, 2e-11, 2e-11, 2e-11, 1e-11, 9e-10, 2e-11, 1e-11, 9e-10, 2e-11, 5e-10, 1e-11, 1e-11, 1e-11, 2e-10, 2e-11, 1e-11, 1e-11, 1e-11, 1e-11, 1e-11]
+ 
+ # Shape is different in python solution (fixed using reshape) which can cause test failure
+ field_values = [
Index: /issm/oecreview/Archive/27230-27343/ISSM-27246-27247.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27246-27247.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27246-27247.diff	(revision 27344)
@@ -0,0 +1,13 @@
+Index: ../trunk-jpl/src/m/classes/frontalforcingsrignotautoregression.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/frontalforcingsrignotautoregression.m	(revision 27246)
++++ ../trunk-jpl/src/m/classes/frontalforcingsrignotautoregression.m	(revision 27247)
+@@ -11,7 +11,7 @@
+ 		ar_order             = 0;
+ 		ar_initialtime       = 0;
+ 		ar_timestep          = 0;
+-		arlag_coef s         = NaN;
++		arlag_coefs          = NaN;
+ 		basin_id             = NaN;
+ 		subglacial_discharge = NaN;
+ 	end
Index: /issm/oecreview/Archive/27230-27343/ISSM-27250-27251.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27250-27251.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27250-27251.diff	(revision 27344)
@@ -0,0 +1,334 @@
+Index: ../trunk-jpl/src/m/classes/stochasticforcing.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/stochasticforcing.m	(revision 27250)
++++ ../trunk-jpl/src/m/classes/stochasticforcing.m	(revision 27251)
+@@ -51,7 +51,7 @@
+ 			structstoch		= structstochforcing();
+ 			for field=self.fields
+ 				%Checking agreement of classes
+-				if(contains(field,'SMBautoregression'))
++				if(contains(field,'SMBarma'))
+ 					mdname = structstoch.mdnames(find(strcmp(structstoch.fields,char(field))));
+ 					if~(isequal(class(md.smb),char(mdname)))
+ 						error('md.smb does not agree with stochasticforcing field %s', char(field));
+@@ -87,7 +87,7 @@
+ 						error('md.basalforcings does not agree with stochasticforcing field %s', char(field));
+ 					end
+ 				end
+-				if(contains(field,'BasalforcingsDeepwaterMeltingRateAutoregression'))
++				if(contains(field,'BasalforcingsDeepwaterMeltingRatearma'))
+ 					mdname = structstoch.mdnames(find(strcmp(structstoch.fields,char(field))));
+ 					if~(isequal(class(md.basalforcings),char(mdname)))
+ 						error('md.basalforcings does not agree with stochasticforcing field %s', char(field));
+@@ -110,7 +110,7 @@
+ 					end
+             end
+ 				%Checking for specific dimensions
+-				if ~(strcmp(field,'SMBautoregression') || strcmp(field,'FrontalForcingsRignotAutoregression') || strcmp(field,'BasalforcingsDeepwaterMeltingRateAutoregression'))
++				if ~(strcmp(field,'SMBarma') || strcmp(field,'FrontalForcingsRignotarma') || strcmp(field,'BasalforcingsDeepwaterMeltingRatearma'))
+ 					checkdefaults = true; %field with non-specific dimensionality
+ 				end
+ 			end
+@@ -117,53 +117,53 @@
+ 
+ 			%Retrieve all the field dimensionalities
+ 			dimensions = self.defaultdimension*ones(1,num_fields);
+-			indSMBar   = -1; %about to check for index of SMBautoregression
+-			indTFar	  = -1; %about to check for index of FrontalForcingsRignotAutoregression
+-			indBDWar	  = -1; %about to check for index of BasalforcingsDeepwaterMeltingRateAutoregression
+-			if any(contains(self.fields,'SMBautoregression'))
+-				indSMBar = find(contains(self.fields,'SMBautoregression')); %index of SMBar, now check for consistency with other ar timesteps 
+-				dimensions(indSMBar) = md.smb.num_basins;
+-				if(md.smb.ar_timestep<self.stochastictimestep)
+-					error('SMBautoregression cannot have a timestep shorter than stochastictimestep');
++			indSMBarma = -1; %about to check for index of SMBarma
++			indTFarma  = -1; %about to check for index of FrontalForcingsRignotarma
++			indBDWarma  = -1; %about to check for index of BasalforcingsDeepwaterMeltingRatearma
++			if any(contains(self.fields,'SMBarma'))
++				indSMBarma = find(contains(self.fields,'SMBarma')); %index of SMBarma, now check for consistency with other arma timesteps 
++				dimensions(indSMBarma) = md.smb.num_basins;
++				if(md.smb.arma_timestep<self.stochastictimestep)
++					error('SMBarma cannot have a timestep shorter than stochastictimestep');
+ 				end
+ 			end
+-			if any(contains(self.fields,'FrontalForcingsRignotAutoregression'))
+-				indTFar	= find(contains(self.fields,'FrontalForcingsRignotAutoregression')); %index of TFar, now check for consistency with other ar timesteps 
+-				dimensions(indTFar) = md.frontalforcings.num_basins;
+-				if(md.frontalforcings.ar_timestep<self.stochastictimestep)
+-					error('FrontalForcingsRignotAutoregression cannot have a timestep shorter than stochastictimestep');
++			if any(contains(self.fields,'FrontalForcingsRignotarma'))
++				indTFarma	= find(contains(self.fields,'FrontalForcingsRignotarma')); %index of TFarma, now check for consistency with other arma timesteps 
++				dimensions(indTFarma) = md.frontalforcings.num_basins;
++				if(md.frontalforcings.arma_timestep<self.stochastictimestep)
++					error('FrontalForcingsRignotarma cannot have a timestep shorter than stochastictimestep');
+ 				end
+ 			end
+-			if any(contains(self.fields,'BasalforcingsDeepwaterMeltingRateAutoregression'))
+-				indBDWar	= find(contains(self.fields,'BasalforcingsDeepwaterMeltingRateAutoregression')); %index of BDWar, now check for consistency with other ar timesteps 
+-				dimensions(indBDWar) = md.basalforcings.num_basins;
+-				if(md.basalforcings.ar_timestep<self.stochastictimestep)
+-					error('BasalforcingsDeepwaterMeltingRateAutoregression cannot have a timestep shorter than stochastictimestep');
++			if any(contains(self.fields,'BasalforcingsDeepwaterMeltingRatearma'))
++				indBDWarma	= find(contains(self.fields,'BasalforcingsDeepwaterMeltingRatearma')); %index of BDWarma, now check for consistency with other arma timesteps 
++				dimensions(indBDWarma) = md.basalforcings.num_basins;
++				if(md.basalforcings.arma_timestep<self.stochastictimestep)
++					error('BasalforcingsDeepwaterMeltingRatearma cannot have a timestep shorter than stochastictimestep');
+ 				end
+ 			end
+ 			size_tot = sum(dimensions);
+ 
+-			if(indSMBar~=-1 && indTFar~=-1) %both autoregressive models are used: check autoregressive time step consistency
+-				if(md.smb.ar_timestep~=md.frontalforcings.ar_timestep)
+-					crossentries = reshape(self.covariance(1+sum(dimensions(1:indSMBar-1)):sum(dimensions(1:indSMBar)),1+sum(dimensions(1:indTFar-1)):sum(dimensions(1:indTFar))),1,[]);
++			if(indSMBarma~=-1 && indTFarma~=-1) %both ARMA models are used: check ARMA time step consistency
++				if(md.smb.arma_timestep~=md.frontalforcings.arma_timestep)
++					crossentries = reshape(self.covariance(1+sum(dimensions(1:indSMBarma-1)):sum(dimensions(1:indSMBarma)),1+sum(dimensions(1:indTFarma-1)):sum(dimensions(1:indTFarma))),1,[]);
+ 					if any(crossentries~=0)
+-						error('SMBautoregression and FrontalForcingsRignotAutoregression have different ar_timestep and non-zero covariance');
++						error('SMBarma and FrontalForcingsRignotarma have different arma_timestep and non-zero covariance');
+ 					end
+ 				end
+ 			end
+-			if(indSMBar~=-1 && indBDWar~=-1) %both autoregressive models are used: check autoregressive time step consistency
+-				if(md.smb.ar_timestep~=md.basalforcings.ar_timestep)
+-					crossentries = reshape(self.covariance(1+sum(dimensions(1:indSMBar-1)):sum(dimensions(1:indSMBar)),1+sum(dimensions(1:indBDWar-1)):sum(dimensions(1:indBDWar))),1,[]);
++			if(indSMBarma~=-1 && indBDWarma~=-1) %both ARMA models are used: check ARMA time step consistency
++				if(md.smb.arma_timestep~=md.basalforcings.arma_timestep)
++					crossentries = reshape(self.covariance(1+sum(dimensions(1:indSMBarma-1)):sum(dimensions(1:indSMBarma)),1+sum(dimensions(1:indBDWarma-1)):sum(dimensions(1:indBDWarma))),1,[]);
+ 					if any(crossentries~=0)
+-						error('SMBautoregression and BasalforcingsDeepwaterMeltingRateAutoregression have different ar_timestep and non-zero covariance');
++						error('SMBarma and BasalforcingsDeepwaterMeltingRatearma have different arma_timestep and non-zero covariance');
+ 					end
+ 				end
+ 			end
+-			if(indTFar~=-1 && indBDWar~=-1) %both autoregressive models are used: check autoregressive time step consistency
+-				if(md.frontalforcings.ar_timestep~=md.basalforcings.ar_timestep)
+-					crossentries = reshape(self.covariance(1+sum(dimensions(1:indTFar-1)):sum(dimensions(1:indTFar)),1+sum(dimensions(1:indBDWar-1)):sum(dimensions(1:indBDWar))),1,[]);
++			if(indTFarma~=-1 && indBDWarma~=-1) %both ARMA models are used: check ARMA time step consistency
++				if(md.frontalforcings.arma_timestep~=md.basalforcings.arma_timestep)
++					crossentries = reshape(self.covariance(1+sum(dimensions(1:indTFarma-1)):sum(dimensions(1:indTFarma)),1+sum(dimensions(1:indBDWarma-1)):sum(dimensions(1:indBDWarma))),1,[]);
+ 					if any(crossentries~=0)
+-						error('FrontalForcingsRignotAutoregression and BasalforcingsDeepwaterMeltingRateAutoregression have different ar_timestep and non-zero covariance');
++						error('FrontalForcingsRignotarma and BasalforcingsDeepwaterMeltingRatearma have different arma_timestep and non-zero covariance');
+ 					end
+ 				end
+ 			end
+@@ -180,7 +180,7 @@
+ 		function disp(self) % {{{
+ 			disp(sprintf('   stochasticforcing parameters:'));
+ 			fielddisplay(self,'isstochasticforcing','is stochasticity activated?');
+-			fielddisplay(self,'fields','fields with stochasticity applied, ex: [{''SMBautoregression''}], or [{''SMBforcing''},{''DefaultCalving''}]');
++			fielddisplay(self,'fields','fields with stochasticity applied, ex: [{''SMBarma''}], or [{''SMBforcing''},{''DefaultCalving''}]');
+ 			fielddisplay(self,'defaultdimension','dimensionality of the noise terms (does not apply to fields with their specific dimension)');
+ 			fielddisplay(self,'default_id','id of each element for partitioning of the noise terms (does not apply to fields with their specific partition)');
+ 			fielddisplay(self,'covariance','covariance matrix for within- and between-fields covariance (units must be squared field units)');
+@@ -211,13 +211,13 @@
+ 				ind = 1;
+ 				for field=self.fields
+ 					%Checking for specific dimensions
+-					if(strcmp(field,'SMBautoregression'))
++					if(strcmp(field,'SMBarma'))
+ 						dimensions(ind) = md.smb.num_basins;
+ 					end
+-					if(strcmp(field,'FrontalForcingsRignotAutoregression'))
++					if(strcmp(field,'FrontalForcingsRignotarma'))
+ 						dimensions(ind) = md.frontalforcings.num_basins;
+ 					end
+-					if(strcmp(field,'BasalforcingsDeepwaterMeltingRateAutoregression'))
++					if(strcmp(field,'BasalforcingsDeepwaterMeltingRatearma'))
+ 						dimensions(ind) = md.basalforcings.num_basins;
+ 					end
+ 					ind = ind+1;
+@@ -224,7 +224,7 @@
+ 				end
+ 
+ 				%Scaling covariance matrix (scale column-by-column and row-by-row)
+-				scaledfields = {'BasalforcingsDeepwaterMeltingRateAutoregression','BasalforcingsSpatialDeepwaterMeltingRate','DefaultCalving','FloatingMeltRate','SMBautoregression','SMBforcing'}; %list of fields that need scaling *1/yts
++				scaledfields = {'BasalforcingsDeepwaterMeltingRatearma','BasalforcingsSpatialDeepwaterMeltingRate','DefaultCalving','FloatingMeltRate','SMBarma','SMBforcing'}; %list of fields that need scaling *1/yts
+ 				tempcovariance = self.covariance; %copy of covariance to avoid writing back in member variable
+ 				for i=1:num_fields
+ 					if any(strcmp(scaledfields,self.fields(i)))
+@@ -265,7 +265,7 @@
+ 	% Defines structure with list of fields
+ 	% supported and corresponding md names
+ 	structure.fields = {...
+-		'BasalforcingsDeepwaterMeltingRateAutoregression',...
++		'BasalforcingsDeepwaterMeltingRatearma',...
+ 		'BasalforcingsSpatialDeepwaterMeltingRate',...
+ 		'DefaultCalving',...
+ 		'FloatingMeltRate',...
+@@ -272,12 +272,12 @@
+ 		'FrictionWaterPressure',...
+ 		'FrictionCoulombWaterPressure',...
+ 		'FrictionSchoofWaterPressure',...
+-		'FrontalForcingsRignotAutoregression',...
+-		'SMBautoregression',...
++		'FrontalForcingsRignotarma',...
++		'SMBarma',...
+ 		'SMBforcing'
+ 		};
+ 	structure.mdnames = {...
+-		'autoregressionlinearbasalforcings',...
++		'linearbasalforcingsarma',...
+ 		'spatiallinearbasalforcings',...
+ 		'calving',...
+ 		'basalforcings',...
+@@ -284,8 +284,8 @@
+ 		'friction',...
+ 		'frictioncoulomb',...
+ 		'frictionschoof',...
+-		'frontalforcingsrignotautoregression',...
+-		'SMBautoregression',...
++		'frontalforcingsrignotarma',...
++		'SMBarma',...
+ 		'SMBforcing'
+ 	};
+ end % }}}
+Index: ../trunk-jpl/src/m/classes/stochasticforcing.py
+===================================================================
+--- ../trunk-jpl/src/m/classes/stochasticforcing.py	(revision 27250)
++++ ../trunk-jpl/src/m/classes/stochasticforcing.py	(revision 27251)
+@@ -39,8 +39,8 @@
+         s += '   DefaultCalving\n'
+         s += '   FloatingMeltRate\n'
+         s += '   FrictionWaterPressure\n'
+-        s += '   FrontalForcingsRignotAutoregression (thermal forcing)\n'
+-        s += '   SMBautoregression\n'
++        s += '   FrontalForcingsRignotarma (thermal forcing)\n'
++        s += '   SMBarma\n'
+         s += '   SMBforcing\n'
+         return s
+     #}}}
+@@ -74,7 +74,7 @@
+         structstoch = self.structstochforcing()
+         for field in self.fields:
+             # Checking agreement of classes
+-            if 'SMBautoregression' in field:
++            if 'SMBarma' in field:
+                 mdname = structstoch[field]
+                 if (type(md.smb).__name__ != mdname):
+                     raise TypeError('md.smb does not agree with stochasticforcing field {}'.format(field))
+@@ -98,7 +98,7 @@
+                 mdname = structstoch[field]
+                 if (type(md.basalforcings).__name__ != mdname):
+                     raise TypeError('md.basalforcings does not agree with stochasticforcing field {}'.format(field))
+-            if 'BasalforcingsDeepwaterMeltingRateAutoregression' in field:
++            if 'BasalforcingsDeepwaterMeltingRatearma' in field:
+                 mdname = structstoch[field]
+                 if (type(md.basalforcings).__name__ != mdname):
+                     raise TypeError('md.basalforcings does not agree with stochasticforcing field {}'.format(field))
+@@ -114,43 +114,43 @@
+                         raise TypeError('stochasticforcing field {} requires non-zero q exponent'.format(field))
+ 
+             # Checking for specific dimensions
+-            if field not in['SMBautoregression', 'FrontalForcingsRignotAutoregression','BasalforcingsDeepwaterMeltingRateAutoregression']:
++            if field not in['SMBarma', 'FrontalForcingsRignotarma','BasalforcingsDeepwaterMeltingRatearma']:
+                 checkdefaults = True  # field with non-specific dimensionality
+ 
+         # Retrieve sum of all the field dimensionalities
+         dimensions = self.defaultdimension*np.ones((num_fields))
+-        indSMBar   = -1  # About to check for index of SMBautoregression
+-        indTFar    = -1  # About to check for index of FrontalForcingsRignotAutoregression
+-        indBDWar   = -1  # About to check for index of BasalforcingsDeepwaterMeltingRateAutoregression
+-        if ('SMBautoregression' in self.fields):
+-            indSMBar = self.fields.index('SMBautoregression')  # Index of SMBar, now check for consistency with other timesteps
+-            dimensions[indSMBar] = md.smb.num_basins
+-            if(md.smb.ar_timestep<self.stochastictimestep):
+-                raise TypeError('SMBautoregression cannot have a timestep shorter than stochastictimestep')
+-        if ('FrontalForcingsRignotAutoregression' in self.fields):
+-            indTFar = self.fields.index('FrontalForcingsRignotAutoregression')  # Index of TFar, now check for consistency with other timesteps
+-            dimensions[indTFar] = md.frontalforcings.num_basins
+-            if(md.frontalforcings.ar_timestep<self.stochastictimestep):
+-                raise TypeError('FrontalForcingsRignotAutoregression cannot have a timestep shorter than stochastictimestep')
+-        if ('BasalforcingsDeepwaterMeltingRateAutoregression' in self.fields):
+-            indBDWar = self.fields.index('BasalforcingsDeepwaterMeltingRateAutoregression')  # Index of BDWar, now check for consistency with other timesteps
+-            dimensions[indTFar] = md.basalforcings.num_basins
+-            if(md.basalforcings.ar_timestep<self.stochastictimestep):
+-                raise TypeError('BasalforcingsDeepwaterMeltingRateAutoregression cannot have a timestep shorter than stochastictimestep')
++        indSMBarma   = -1  # About to check for index of SMBarma
++        indTFarma    = -1  # About to check for index of FrontalForcingsRignotarma
++        indBDWarma   = -1  # About to check for index of BasalforcingsDeepwaterMeltingRatearma
++        if ('SMBarma' in self.fields):
++            indSMBarma = self.fields.index('SMBarma')  # Index of SMBarma, now check for consistency with other timesteps
++            dimensions[indSMBarma] = md.smb.num_basins
++            if(md.smb.arma_timestep<self.stochastictimestep):
++                raise TypeError('SMBarma cannot have a timestep shorter than stochastictimestep')
++        if ('FrontalForcingsRignotarma' in self.fields):
++            indTFarma = self.fields.index('FrontalForcingsRignotarma')  # Index of TFarma, now check for consistency with other timesteps
++            dimensions[indTFarma] = md.frontalforcings.num_basins
++            if(md.frontalforcings.arma_timestep<self.stochastictimestep):
++                raise TypeError('FrontalForcingsRignotarma cannot have a timestep shorter than stochastictimestep')
++        if ('BasalforcingsDeepwaterMeltingRatearma' in self.fields):
++            indBDWarma = self.fields.index('BasalforcingsDeepwaterMeltingRatearma')  # Index of BDWarma, now check for consistency with other timesteps
++            dimensions[indTFarma] = md.basalforcings.num_basins
++            if(md.basalforcings.arma_timestep<self.stochastictimestep):
++                raise TypeError('BasalforcingsDeepwaterMeltingRatearma cannot have a timestep shorter than stochastictimestep')
+         size_tot = np.sum(dimensions)
+ 
+-        if (indSMBar != -1 and indTFar != -1):  # Both autoregressive models are used: check autoregressive time step consistency
+-            covsum = self.covariance[np.sum(dimensions[0:indSMBar]).astype(int):np.sum(dimensions[0:indSMBar + 1]).astype(int), np.sum(dimensions[0:indTFar]).astype(int):np.sum(dimensions[0:indTFar + 1]).astype(int)]
+-            if((md.smb.ar_timestep != md.frontalforcings.ar_timestep) and np.any(covsum != 0)):
+-                raise IOError('SMBautoregression and FrontalForcingsRignotAutoregression have different ar_timestep and non-zero covariance')
+-        if (indSMBar != -1 and indBDWar != -1):  # Both autoregressive models are used: check autoregressive time step consistency
+-            covsum = self.covariance[np.sum(dimensions[0:indSMBar]).astype(int):np.sum(dimensions[0:indSMBar + 1]).astype(int), np.sum(dimensions[0:indBDWar]).astype(int):np.sum(dimensions[0:indBDWar + 1]).astype(int)]
+-            if((md.smb.ar_timestep != md.basalforcings.ar_timestep) and np.any(covsum != 0)):
+-                raise IOError('SMBautoregression and BasalforcingsDeepwaterMeltingRateAutoregression have different ar_timestep and non-zero covariance')
+-        if (indTFar != -1 and indBDWar != -1):  # Both autoregressive models are used: check autoregressive time step consistency
+-            covsum = self.covariance[np.sum(dimensions[0:indTFar]).astype(int):np.sum(dimensions[0:indTFar + 1]).astype(int), np.sum(dimensions[0:indBDWar]).astype(int):np.sum(dimensions[0:indBDWar + 1]).astype(int)]
+-            if((md.frontalforcings.ar_timestep != md.basalforcings.ar_timestep) and np.any(covsum != 0)):
+-                raise IOError('FrontalForcingsRignotAutoregression and BasalforcingsDeepwaterMeltingRateAutoregression have different ar_timestep and non-zero covariance')
++        if (indSMBarma != -1 and indTFarma != -1):  # Both ARMA models are used: check ARMA time step consistency
++            covsum = self.covariance[np.sum(dimensions[0:indSMBarma]).astype(int):np.sum(dimensions[0:indSMBarma + 1]).astype(int), np.sum(dimensions[0:indTFarma]).astype(int):np.sum(dimensions[0:indTFarma + 1]).astype(int)]
++            if((md.smb.arma_timestep != md.frontalforcings.arma_timestep) and np.any(covsum != 0)):
++                raise IOError('SMBarma and FrontalForcingsRignotarma have different arma_timestep and non-zero covariance')
++        if (indSMBarma != -1 and indBDWarma != -1):  # Both ARMA models are used: check ARMA time step consistency
++            covsum = self.covariance[np.sum(dimensions[0:indSMBarma]).astype(int):np.sum(dimensions[0:indSMBarma + 1]).astype(int), np.sum(dimensions[0:indBDWarma]).astype(int):np.sum(dimensions[0:indBDWarma + 1]).astype(int)]
++            if((md.smb.arma_timestep != md.basalforcings.arma_timestep) and np.any(covsum != 0)):
++                raise IOError('SMBarma and BasalforcingsDeepwaterMeltingRatearma have different arma_timestep and non-zero covariance')
++        if (indTFarma != -1 and indBDWarma != -1):  # Both ARMA models are used: check ARMA time step consistency
++            covsum = self.covariance[np.sum(dimensions[0:indTFarma]).astype(int):np.sum(dimensions[0:indTFarma + 1]).astype(int), np.sum(dimensions[0:indBDWarma]).astype(int):np.sum(dimensions[0:indBDWarma + 1]).astype(int)]
++            if((md.frontalforcings.arma_timestep != md.basalforcings.arma_timestep) and np.any(covsum != 0)):
++                raise IOError('FrontalForcingsRignotarma and BasalforcingsDeepwaterMeltingRatearma have different arma_timestep and non-zero covariance')
+ 
+         md = checkfield(md, 'fieldname', 'stochasticforcing.isstochasticforcing', 'values', [0, 1])
+         md = checkfield(md, 'fieldname', 'stochasticforcing.fields', 'numel', num_fields, 'cell', 1, 'values', self.supportedstochforcings())
+@@ -183,15 +183,15 @@
+             dimensions = self.defaultdimension * np.ones((num_fields))
+             for ind, field in enumerate(self.fields):
+                 # Checking for specific dimensions
+-                if (field == 'SMBautoregression'):
++                if (field == 'SMBarma'):
+                     dimensions[ind] = md.smb.num_basins
+-                if (field == 'FrontalForcingsRignotAutoregression'):
++                if (field == 'FrontalForcingsRignotarma'):
+                     dimensions[ind] = md.frontalforcings.num_basins
+-                if (field == 'BasalforcingsDeepwaterMeltingRateAutoregression'):
++                if (field == 'BasalforcingsDeepwaterMeltingRatearma'):
+                     dimensions[ind] = md.basalforcings.num_basins
+ 
+             # Scaling covariance matrix (scale column-by-column and row-by-row)
+-            scaledfields = ['BasalforcingsDeepwaterMeltingRateAutoregression','BasalforcingsSpatialDeepwaterMeltingRate','DefaultCalving', 'FloatingMeltRate', 'SMBautoregression', 'SMBforcing']  # list of fields that need scaling * 1/yts
++            scaledfields = ['BasalforcingsDeepwaterMeltingRatearma','BasalforcingsSpatialDeepwaterMeltingRate','DefaultCalving', 'FloatingMeltRate', 'SMBarma', 'SMBforcing']  # list of fields that need scaling * 1/yts
+             tempcovariance = np.copy(self.covariance)
+             for i in range(num_fields):
+                 if self.fields[i] in scaledfields:
+@@ -228,7 +228,7 @@
+         """Defines dictionary with list of fields
+            supported and corresponding md names
+         """
+-        structure = {'BasalforcingsDeepwaterMeltingRateAutoregression': 'autoregressionlinearbasalforcings',
++        structure = {'BasalforcingsDeepwaterMeltingRatearma': 'linearbasalforcingsarma',
+                      'BasalforcingsSpatialDeepwaterMeltingRate': 'spatiallinearbasalforcings',
+                      'DefaultCalving': 'calving',
+                      'FloatingMeltRate': 'basalforcings',
+@@ -235,8 +235,8 @@
+                      'FrictionWaterPressure': 'friction',
+                      'FrictionCoulombWaterPressure': 'frictioncoulomb',
+                      'FrictionSchoofWaterPressure': 'frictionschoof',
+-                     'FrontalForcingsRignotAutoregression': 'frontalforcingsrignotautoregression',
+-                     'SMBautoregression': 'SMBautoregression',
++                     'FrontalForcingsRignotarma': 'frontalforcingsrignotarma',
++                     'SMBarma': 'SMBarma',
+                      'SMBforcing': 'SMBforcing'}
+         return structure
+     # }}}
Index: /issm/oecreview/Archive/27230-27343/ISSM-27251-27252.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27251-27252.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27251-27252.diff	(revision 27344)
@@ -0,0 +1,146 @@
+Index: ../trunk-jpl/src/m/classes/calvingparameterization.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/calvingparameterization.m	(revision 27251)
++++ ../trunk-jpl/src/m/classes/calvingparameterization.m	(revision 27252)
+@@ -11,7 +11,8 @@
+ 		alpha = 0;
+ 		xoffset = 0;
+ 		yoffset = 0;
+-		vel_upperbound = 6000;
++		vel_upperbound = 8000;
++		vel_threshold = 6000;
+ 		vel_lowerbound = 0;
+ 	end
+ 	methods
+@@ -67,6 +68,7 @@
+ 			md = checkfield(md,'fieldname','calving.xoffset','NaN',1,'Inf',1,'numel',1);
+ 			md = checkfield(md,'fieldname','calving.yoffset','NaN',1,'Inf',1,'numel',1);
+ 			md = checkfield(md,'fieldname','calving.vel_lowerbound','NaN',1,'Inf',1,'numel',1);
++			md = checkfield(md,'fieldname','calving.vel_threshold','NaN',1,'Inf',1,'numel',1);
+ 			md = checkfield(md,'fieldname','calving.vel_upperbound','NaN',1,'Inf',1,'numel',1);
+ 		end % }}}
+ 		function disp(self) % {{{
+@@ -78,6 +80,7 @@
+ 			fielddisplay(self,'xoffset','offset in x-axis');
+ 			fielddisplay(self,'yoffset','offset in y-axis');
+ 			fielddisplay(self,'vel_lowerbound','lowerbound of ice velocity to reduce the calving rate [m/a]');
++			fielddisplay(self,'vel_threshold','threshold of ice velocity to reduce the calving rate [m/a]');
+ 			fielddisplay(self,'vel_upperbound','upperbound of ice velocity to reduce the calving rate [m/a]');
+ 		end % }}}
+ 		function marshall(self,prefix,md,fid) % {{{
+@@ -90,6 +93,7 @@
+ 			WriteData(fid,prefix,'object',self,'fieldname','xoffset','format','Double');
+ 			WriteData(fid,prefix,'object',self,'fieldname','yoffset','format','Double');
+ 			WriteData(fid,prefix,'object',self,'fieldname','vel_lowerbound','format','Double','scale', 1./yts);
++			WriteData(fid,prefix,'object',self,'fieldname','vel_threshold','format','Double','scale', 1./yts);
+ 			WriteData(fid,prefix,'object',self,'fieldname','vel_upperbound','format','Double','scale', 1./yts);
+ 		end % }}}
+ 	end
+Index: ../trunk-jpl/src/c/analyses/LevelsetAnalysis.cpp
+===================================================================
+--- ../trunk-jpl/src/c/analyses/LevelsetAnalysis.cpp	(revision 27251)
++++ ../trunk-jpl/src/c/analyses/LevelsetAnalysis.cpp	(revision 27252)
+@@ -225,6 +225,7 @@
+ 			parameters->AddObject(iomodel->CopyConstantObject("md.calving.xoffset",CalvingXoffsetEnum));
+ 			parameters->AddObject(iomodel->CopyConstantObject("md.calving.yoffset",CalvingYoffsetEnum));
+ 			parameters->AddObject(iomodel->CopyConstantObject("md.calving.vel_lowerbound",CalvingVelLowerboundEnum));
++			parameters->AddObject(iomodel->CopyConstantObject("md.calving.vel_threshold",CalvingVelThresholdEnum));
+ 			parameters->AddObject(iomodel->CopyConstantObject("md.calving.vel_upperbound",CalvingVelUpperboundEnum));
+ 			break;
+ 		default:
+Index: ../trunk-jpl/src/c/classes/Elements/Tria.cpp
+===================================================================
+--- ../trunk-jpl/src/c/classes/Elements/Tria.cpp	(revision 27251)
++++ ../trunk-jpl/src/c/classes/Elements/Tria.cpp	(revision 27252)
+@@ -844,7 +844,7 @@
+ 	IssmDouble  arate, rho_ice, rho_water, thickness;
+ 	int			use_parameter=-1;
+ 	IssmDouble  gamma, theta, alpha, xoffset, yoffset;
+-	IssmDouble  vel_lower, vel_upper, vrate, truncateVrate;
++	IssmDouble  vel_lower, vel_upper, vel_threshold, vrate, truncateVrate;
+ 
+ 	/* Get node coordinates and dof list: */
+ 	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+@@ -872,6 +872,7 @@
+ 	this->FindParam(&yoffset, CalvingYoffsetEnum);
+ 	this->FindParam(&vel_lower, CalvingVelLowerboundEnum);
+ 	this->FindParam(&vel_upper, CalvingVelUpperboundEnum);
++	this->FindParam(&vel_threshold, CalvingVelThresholdEnum);
+ 
+ 	/* Start looping on the number of vertices: */
+ 	GaussTria* gauss=new GaussTria();
+@@ -890,7 +891,7 @@
+ 		sl_input->GetInputValue(&sealevel,gauss);
+ 		arate_input->GetInputValue(&arate,gauss);
+ 		vrate = 1.0;
+-		if (vel < vel_upper) vrate = vel / vel_upper;
++		if (vel < vel_threshold) vrate = vel / vel_threshold;
+ 
+ 		/*Compute strain rate and viscosity: */
+ 		this->StrainRateSSA(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input);
+@@ -923,12 +924,12 @@
+ 				break;
+ 			case 3:
+ 				/* 3 tanh(normal vel): f(x)=y_{o}-\frac{\theta}{2}\tanh(\alpha(x+x_{o})) */
+-				_error_("The normalized velocity is not supported yet!");
+-				gamma = yoffset -  0.5*theta*tanh(alpha*(vel+xoffset));
++				truncateVrate = (min(vel_upper, max(vel_lower, vel))-vel_lower) / (vel_upper - vel_lower);
++				gamma = yoffset -  0.5*theta*tanh(alpha*(truncateVrate+xoffset));
+ 				break;
+ 			case 4:
+-				/* 4 tanh(truncated vel): f(x)=y_{o}-\frac{\theta}{2}\tanh(\alpha(x+x_{o})) */
+-				truncateVrate = (min(vel_upper, max(vel_lower, vel))-vel_lower) / vel_upper;
++				/* 4 tanh(normal vel), cross (0,0): f(x)=y_{o}-\frac{\theta}{2}\tanh(\alpha(x+x_{o})) */
++				truncateVrate = (min(vel_upper, max(vel_lower, vel))-vel_lower) / (vel_upper - vel_lower);
+ 				gamma = 0.5*theta*(tanh(alpha*xoffset) - tanh(alpha*(truncateVrate+xoffset)));
+ 				break;
+ 			case -1:
+@@ -945,12 +946,7 @@
+ 		if (bed >= sealevel) gamma = 0.0;
+ 
+ 		/*-------------------------------------------*/
+-		if (use_parameter < 3) {
+-			calvingrate[iv] = arate*gamma*vrate;
+-		} 
+-		else {
+-			calvingrate[iv] = arate*gamma;
+-		}
++		calvingrate[iv] = arate*gamma*vrate;
+ 	}
+ 	/*Add input*/
+ 	this->AddInput(CalvingCalvingrateEnum,&calvingrate[0],P1DGEnum);
+Index: ../trunk-jpl/src/c/cores/movingfront_core.cpp
+===================================================================
+--- ../trunk-jpl/src/c/cores/movingfront_core.cpp	(revision 27251)
++++ ../trunk-jpl/src/c/cores/movingfront_core.cpp	(revision 27252)
+@@ -19,6 +19,7 @@
+ 	int  domaintype, num_extrapol_vars, index,reinit_frequency,step;
+ 	int* extrapol_vars=NULL;
+ 	Analysis  *analysis=NULL;
++	IssmDouble maxVel;
+ 
+ 	/* recover parameters */
+ 	femmodel->parameters->FindParam(&domaintype,DomainTypeEnum);
+@@ -50,6 +51,10 @@
+ 	/* smoothen slope of lsf for computation of normal on ice domain*/
+ 	levelsetfunctionslope_core(femmodel);
+ 
++	/* compute the maximal velocity over the whole domain */
++	femmodel->MaxVelx(&maxVel);
++	femmodel->parameters->SetParam(maxVel, CalvingVelThresholdEnum);
++
+ 	/* start the work from here */
+ 	if(VerboseSolution()) _printf0_("   computing calving and undercutting\n");
+ 	Calvingx(femmodel);
+Index: ../trunk-jpl/src/c/shared/Enum/EnumDefinitions.h
+===================================================================
+--- ../trunk-jpl/src/c/shared/Enum/EnumDefinitions.h	(revision 27251)
++++ ../trunk-jpl/src/c/shared/Enum/EnumDefinitions.h	(revision 27252)
+@@ -118,6 +118,7 @@
+ 	CalvingXoffsetEnum,
+ 	CalvingYoffsetEnum,
+ 	CalvingVelLowerboundEnum,
++	CalvingVelThresholdEnum,
+ 	CalvingVelUpperboundEnum,
+ 	ConfigurationTypeEnum,
+ 	ConstantsGEnum,
Index: /issm/oecreview/Archive/27230-27343/ISSM-27252-27253.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27252-27253.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27252-27253.diff	(revision 27344)
@@ -0,0 +1,76 @@
+Index: ../trunk-jpl/src/c/classes/Elements/Tria.cpp
+===================================================================
+--- ../trunk-jpl/src/c/classes/Elements/Tria.cpp	(revision 27252)
++++ ../trunk-jpl/src/c/classes/Elements/Tria.cpp	(revision 27253)
+@@ -844,7 +844,7 @@
+ 	IssmDouble  arate, rho_ice, rho_water, thickness;
+ 	int			use_parameter=-1;
+ 	IssmDouble  gamma, theta, alpha, xoffset, yoffset;
+-	IssmDouble  vel_lower, vel_upper, vel_threshold, vrate, truncateVrate;
++	IssmDouble  vel_lower, vel_upper, vel_threshold, vrate, truncateVrate, vel_max;
+ 
+ 	/* Get node coordinates and dof list: */
+ 	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+@@ -873,6 +873,7 @@
+ 	this->FindParam(&vel_lower, CalvingVelLowerboundEnum);
+ 	this->FindParam(&vel_upper, CalvingVelUpperboundEnum);
+ 	this->FindParam(&vel_threshold, CalvingVelThresholdEnum);
++	this->FindParam(&vel_max, CalvingVelMaxEnum);
+ 
+ 	/* Start looping on the number of vertices: */
+ 	GaussTria* gauss=new GaussTria();
+@@ -890,8 +891,16 @@
+ 		vel=sqrt(vx*vx+vy*vy)+1.e-14;
+ 		sl_input->GetInputValue(&sealevel,gauss);
+ 		arate_input->GetInputValue(&arate,gauss);
++		/* reduce the arate by a factor depends on a fixed velocity threshold */
+ 		vrate = 1.0;
+ 		if (vel < vel_threshold) vrate = vel / vel_threshold;
++		/* parameter used in the calving law: real time max vel, or predefined vel range*/
++		if (vel_upper <= vel_lower) {
++			truncateVrate = vel / vel_max;
++		}
++		else {
++			truncateVrate = (min(vel_upper, max(vel_lower, vel))-vel_lower) / (vel_upper - vel_lower);
++		}
+ 
+ 		/*Compute strain rate and viscosity: */
+ 		this->StrainRateSSA(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input);
+@@ -924,12 +933,10 @@
+ 				break;
+ 			case 3:
+ 				/* 3 tanh(normal vel): f(x)=y_{o}-\frac{\theta}{2}\tanh(\alpha(x+x_{o})) */
+-				truncateVrate = (min(vel_upper, max(vel_lower, vel))-vel_lower) / (vel_upper - vel_lower);
+ 				gamma = yoffset -  0.5*theta*tanh(alpha*(truncateVrate+xoffset));
+ 				break;
+ 			case 4:
+ 				/* 4 tanh(normal vel), cross (0,0): f(x)=y_{o}-\frac{\theta}{2}\tanh(\alpha(x+x_{o})) */
+-				truncateVrate = (min(vel_upper, max(vel_lower, vel))-vel_lower) / (vel_upper - vel_lower);
+ 				gamma = 0.5*theta*(tanh(alpha*xoffset) - tanh(alpha*(truncateVrate+xoffset)));
+ 				break;
+ 			case -1:
+Index: ../trunk-jpl/src/c/cores/movingfront_core.cpp
+===================================================================
+--- ../trunk-jpl/src/c/cores/movingfront_core.cpp	(revision 27252)
++++ ../trunk-jpl/src/c/cores/movingfront_core.cpp	(revision 27253)
+@@ -53,7 +53,7 @@
+ 
+ 	/* compute the maximal velocity over the whole domain */
+ 	femmodel->MaxVelx(&maxVel);
+-	femmodel->parameters->SetParam(maxVel, CalvingVelThresholdEnum);
++	femmodel->parameters->SetParam(maxVel, CalvingVelMaxEnum);
+ 
+ 	/* start the work from here */
+ 	if(VerboseSolution()) _printf0_("   computing calving and undercutting\n");
+Index: ../trunk-jpl/src/c/shared/Enum/EnumDefinitions.h
+===================================================================
+--- ../trunk-jpl/src/c/shared/Enum/EnumDefinitions.h	(revision 27252)
++++ ../trunk-jpl/src/c/shared/Enum/EnumDefinitions.h	(revision 27253)
+@@ -118,6 +118,7 @@
+ 	CalvingXoffsetEnum,
+ 	CalvingYoffsetEnum,
+ 	CalvingVelLowerboundEnum,
++	CalvingVelMaxEnum,
+ 	CalvingVelThresholdEnum,
+ 	CalvingVelUpperboundEnum,
+ 	ConfigurationTypeEnum,
Index: /issm/oecreview/Archive/27230-27343/ISSM-27253-27254.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27253-27254.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27253-27254.diff	(revision 27344)
@@ -0,0 +1,17 @@
+Index: ../trunk-jpl/src/c/cores/movingfront_core.cpp
+===================================================================
+--- ../trunk-jpl/src/c/cores/movingfront_core.cpp	(revision 27253)
++++ ../trunk-jpl/src/c/cores/movingfront_core.cpp	(revision 27254)
+@@ -52,8 +52,10 @@
+ 	levelsetfunctionslope_core(femmodel);
+ 
+ 	/* compute the maximal velocity over the whole domain */
+-	femmodel->MaxVelx(&maxVel);
+-	femmodel->parameters->SetParam(maxVel, CalvingVelMaxEnum);
++	if(isstressbalance){
++		femmodel->MaxVelx(&maxVel);
++		femmodel->parameters->SetParam(maxVel, CalvingVelMaxEnum);
++	}
+ 
+ 	/* start the work from here */
+ 	if(VerboseSolution()) _printf0_("   computing calving and undercutting\n");
Index: /issm/oecreview/Archive/27230-27343/ISSM-27260-27261.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27260-27261.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27260-27261.diff	(revision 27344)
@@ -0,0 +1,100 @@
+Index: ../trunk-jpl/src/c/analyses/LevelsetAnalysis.cpp
+===================================================================
+--- ../trunk-jpl/src/c/analyses/LevelsetAnalysis.cpp	(revision 27260)
++++ ../trunk-jpl/src/c/analyses/LevelsetAnalysis.cpp	(revision 27261)
+@@ -241,6 +241,7 @@
+ 		case FrontalForcingsRignotarmaEnum:
+ 			/*Retrieve autoregressive parameters*/
+          parameters->AddObject(iomodel->CopyConstantObject("md.frontalforcings.ar_order",FrontalForcingsARMAarOrderEnum));
++         parameters->AddObject(iomodel->CopyConstantObject("md.frontalforcings.ma_order",FrontalForcingsARMAmaOrderEnum));
+          parameters->AddObject(iomodel->CopyConstantObject("md.frontalforcings.arma_initialtime",FrontalForcingsARMAInitialTimeEnum));
+          parameters->AddObject(iomodel->CopyConstantObject("md.frontalforcings.arma_timestep",FrontalForcingsARMATimestepEnum));
+ 			iomodel->FetchData(&transparam,&M,&N,"md.frontalforcings.const");
+Index: ../trunk-jpl/src/c/modules/FrontalForcingsx/FrontalForcingsx.cpp
+===================================================================
+--- ../trunk-jpl/src/c/modules/FrontalForcingsx/FrontalForcingsx.cpp	(revision 27260)
++++ ../trunk-jpl/src/c/modules/FrontalForcingsx/FrontalForcingsx.cpp	(revision 27261)
+@@ -52,7 +52,7 @@
+ 	int M,N,Narlagcoefs,Nmalagcoefs,arorder,maorder,numbasins,my_rank;
+    femmodel->parameters->FindParam(&numbasins,FrontalForcingsNumberofBasinsEnum);
+    femmodel->parameters->FindParam(&arorder,FrontalForcingsARMAarOrderEnum);
+-   femmodel->parameters->FindParam(&maorder,FrontalForcingsARMAarOrderEnum);
++   femmodel->parameters->FindParam(&maorder,FrontalForcingsARMAmaOrderEnum);
+    IssmDouble tinit_arma;
+    IssmDouble* termconstant  = NULL;
+    IssmDouble* trend         = NULL;
+Index: ../trunk-jpl/src/m/classes/linearbasalforcingsarma.py
+===================================================================
+--- ../trunk-jpl/src/m/classes/linearbasalforcingsarma.py	(revision 27260)
++++ ../trunk-jpl/src/m/classes/linearbasalforcingsarma.py	(revision 27261)
+@@ -128,7 +128,6 @@
+     # }}}
+ 
+     def marshall(self, prefix, md, fid):  # {{{
+-        print('ARMA is still under development')
+         yts = md.constants.yts
+ 
+         WriteData(fid, prefix, 'name', 'md.basalforcings.model', 'data', 9, 'format', 'Integer')
+Index: ../trunk-jpl/test/Archives/Archive543.arch
+===================================================================
+Cannot display: file marked as a binary type.
+svn:mime-type = application/octet-stream
+Index: ../trunk-jpl/test/NightlyRun/test543.m
+===================================================================
+--- ../trunk-jpl/test/NightlyRun/test543.m	(revision 27260)
++++ ../trunk-jpl/test/NightlyRun/test543.m	(revision 27261)
+@@ -48,7 +48,7 @@
+ md.frontalforcings.num_basins           = nb_tf;
+ md.frontalforcings.basin_id             = idb_tf;
+ md.frontalforcings.subglacial_discharge = 0.01*ones(md.mesh.numberofvertices,1);
+-md.frontalforcings.const                = [0.005,0.001]; %intercept values of TF in basins [C]
++md.frontalforcings.const                = [0.05,0.01]; %intercept values of TF in basins [C]
+ md.frontalforcings.trend                = [0.0001,0.00001]; %trend values of TF in basins [C/yr]
+ md.frontalforcings.arma_initialtime     = md.timestepping.start_time; %initial time in the AR model parameterization [yr]
+ md.frontalforcings.ar_order             = 4;
+@@ -61,7 +61,7 @@
+ md.basalforcings.floatingice_melting_rate = 0.1*ones(md.mesh.numberofvertices,1);
+ 
+ % Covariance matrix
+-covtf       = 1e-5*eye(nb_tf);
++covtf       = 1e-4*eye(nb_tf);
+ covclv      = 1e-1*eye(nb_clv);
+ covclv(1,1) = 1/10*covclv(1,1);
+ covflmlt    = 0.05*eye(nb_flmlt);
+Index: ../trunk-jpl/test/NightlyRun/test543.py
+===================================================================
+--- ../trunk-jpl/test/NightlyRun/test543.py	(revision 27260)
++++ ../trunk-jpl/test/NightlyRun/test543.py	(revision 27261)
+@@ -53,7 +53,7 @@
+ md.frontalforcings.num_basins = nb_tf
+ md.frontalforcings.basin_id = idb_tf
+ md.frontalforcings.subglacial_discharge = 0.01 * np.ones((md.mesh.numberofvertices,))
+-md.frontalforcings.const = np.array([[0.005, 0.001]])  # intercept values of TF in basins [C]
++md.frontalforcings.const = np.array([[0.05, 0.01]])  # intercept values of TF in basins [C]
+ md.frontalforcings.trend = np.array([[0.0001, 0.00001]])  # trend values of TF in basins [C/yr]
+ md.frontalforcings.arma_initialtime = md.timestepping.start_time  # initial time in the AR model parameterization [yr]
+ md.frontalforcings.ar_order = 4
+@@ -75,8 +75,8 @@
+ #covglob[4:6,4:6] = covflmlt
+ 
+ #Hard-coding covariance matrix because python is complaining
+-covglob = np.array([[1e-5, 0., 0., 0., 0., 0.],
+-                    [0., 1e-5, 0., 0., 0., 0.],
++covglob = np.array([[1e-4, 0., 0., 0., 0., 0.],
++                    [0., 1e-4, 0., 0., 0., 0.],
+                     [0., 0., 1e-2, 0., 0., 0.],
+                     [0., 0., 0., 1e-1, 0., 0.],
+                     [0., 0., 0., 0., 0.05, 0.],
+Index: ../trunk-jpl/test/NightlyRun/test544.py
+===================================================================
+--- ../trunk-jpl/test/NightlyRun/test544.py	(revision 27260)
++++ ../trunk-jpl/test/NightlyRun/test544.py	(revision 27261)
+@@ -63,7 +63,7 @@
+ md.basalforcings.ma_order  = 1
+ md.basalforcings.arma_timestep  = 1.0  # timestep of the ARMA model [yr]
+ md.basalforcings.arlag_coefs  = np.array([[0.0], [0.1]])  # autoregressive parameters
+-md.basalforcings.malag_coefs  = np.array([[0.0], [0.0]])  # moving-average parameters
++md.basalforcings.malag_coefs  = np.array([[0.55], [0.34]])  # moving-average parameters
+ md.basalforcings.deepwater_elevation = np.array([[-1000, -1520]])
+ md.basalforcings.upperwater_elevation = np.array([[0, -50]])
+ md.basalforcings.upperwater_melting_rate = np.array([[0,0]])
Index: /issm/oecreview/Archive/27230-27343/ISSM-27261-27262.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27261-27262.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27261-27262.diff	(revision 27344)
@@ -0,0 +1,889 @@
+Index: ../trunk-jpl/src/m/classes/clusters/acenet.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/clusters/acenet.m	(revision 27261)
++++ ../trunk-jpl/src/m/classes/clusters/acenet.m	(revision 27262)
+@@ -142,7 +142,7 @@
+ 			end
+ 			system(compressstring);
+ 
+-			disp('uploading input file and queueing script');
++			disp('uploading input file and queuing script');
+ 			issmscpout(cluster.name,cluster.executionpath,cluster.login,cluster.port,{[dirname '.tar.gz']});
+ 
+ 		end %}}}
+Index: ../trunk-jpl/src/m/classes/clusters/aci.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/clusters/aci.m	(revision 27261)
++++ ../trunk-jpl/src/m/classes/clusters/aci.m	(revision 27262)
+@@ -91,7 +91,7 @@
+ 			end
+ 			system(compressstring);
+ 
+-			disp('uploading input file and queueing script');
++			disp('uploading input file and queuing script');
+ 			issmscpout(cluster.name,cluster.executionpath,cluster.login,cluster.port,{[dirname '.tar.gz']});
+ 
+ 		end %}}}
+Index: ../trunk-jpl/src/m/classes/clusters/aurora.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/clusters/aurora.m	(revision 27261)
++++ ../trunk-jpl/src/m/classes/clusters/aurora.m	(revision 27262)
+@@ -109,7 +109,7 @@
+ 			end
+ 			system(compressstring);
+ 
+-			disp('uploading input file and queueing script');
++			disp('uploading input file and queuing script');
+ 			issmscpout(cluster.name,cluster.executionpath,cluster.login,cluster.port,{[dirname '.tar.gz']});
+ 
+ 		end %}}}
+Index: ../trunk-jpl/src/m/classes/clusters/aws_issm_solution_server.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/clusters/aws_issm_solution_server.m	(nonexistent)
++++ ../trunk-jpl/src/m/classes/clusters/aws_issm_solution_server.m	(revision 27262)
+@@ -0,0 +1,236 @@
++%AWS_ISSM_SOLUTION_SERVER cluster class definition
++%
++%   Usage:
++%      cluster=aws_issm_solution_server();
++%      cluster=aws_issm_solution_server('np',3);
++%      cluster=aws_issm_solution_server('np',3,'login','username');
++%
++%   TODO:
++%   - Modify src/m/os/issmscp* with idfile parameter
++
++classdef aws_issm_solution_server
++	properties (SetAccess=public)
++		% {{{
++		name           = '54.67.123.214';
++		login          = '';
++		idfile         = '';
++		modules        = {};
++		numnodes       = 1;
++		cpuspernode    = 8;
++		queue          = '';
++		time           = 12*60*60;
++		srcpath        = '/usr/local/repos/issm/trunk-jpl-head';
++		extpkgpath     = '/usr/local/issm-ext';
++		codepath       = '/usr/local/repos/issm/trunk-jpl-head/bin';
++		executionpath  = '';
++		interactive    = 0;
++		numstreams     = 1;
++		hyperthreading = 0;
++		email          = '';
++	end
++	%}}}
++	methods
++		function cluster=aws_issm_solution_server(varargin) % {{{
++
++			%initialize cluster using default settings if provided
++			if (exist('aws_issm_solution_server_settings')==2), aws_issm_solution_server_settings; end
++
++			%use provided options to change fields
++			cluster=AssignObjectFields(pairoptions(varargin{:}),cluster);
++		end
++		%}}}
++		function disp(cluster) % {{{
++			% display the object
++			disp(sprintf('class ''%s'' object ''%s'' = ',class(cluster),inputname(1)));
++			disp(sprintf('    name: %s',cluster.name));
++			disp(sprintf('    login: %s',cluster.login));
++			disp(sprintf('    idfile: %s',cluster.idfile));
++			disp(sprintf('    modules: %s',strjoin(cluster.modules,', ')));
++			disp(sprintf('    numnodes: %i',cluster.numnodes));
++			disp(sprintf('    cpuspernode: %i',cluster.cpuspernode));
++			disp(sprintf('    np: %i',cluster.nprocs()));
++			disp(sprintf('    time: %i',cluster.time));
++			disp(sprintf('    processor: %i',cluster.processor));
++			disp(sprintf('    srcpath: %s',cluster.srcpath));
++			disp(sprintf('    extpkgpath: %s',cluster.extpkgpath));
++			disp(sprintf('    codepath: %s',cluster.codepath));
++			disp(sprintf('    executionpath: %s',cluster.executionpath));
++			disp(sprintf('    grouplist: %s',cluster.grouplist));
++			disp(sprintf('    interactive: %i',cluster.interactive));
++			disp(sprintf('    numstreams: %s',cluster.numstreams));
++			disp(sprintf('    hyperthreading: %s',cluster.hyperthreading));
++			disp(sprintf('    email: %s',cluster.email));
++		end
++		%}}}
++		function numprocs=nprocs(cluster) % {{{
++			%compute number of processors
++			numprocs=cluster.numnodes*cluster.cpuspernode;
++		end
++		%}}}
++		function md = checkconsistency(cluster,md,solution,analyses) % {{{
++
++			if ((cluster.numnodes>1 ) | (cluster.numnodes<1)),
++				md = checkmessage(md,'only 1 node is currently available');
++			end
++
++			if ((cluster.cpuspernode>8 ) | (cluster.cpuspernode<1)),
++				md = checkmessage(md,'cpuspernode should be between 1 and 8');
++			end
++
++			%Miscellaneous
++			if isempty(cluster.login), md = checkmessage(md,'login empty'); end
++			if isempty(cluster.srcpath), md = checkmessage(md,'srcpath empty'); end
++			if isempty(cluster.extpkgpath), md = checkmessage(md,'extpkgpath empty'); end
++			if isempty(cluster.codepath), md = checkmessage(md,'codepath empty'); end
++			if isempty(cluster.executionpath), md = checkmessage(md,'executionpath empty'); end
++
++		end
++		%}}}
++		function BuildQueueScript(cluster,dirname,modelname,solution,io_gather,isvalgrind,isgprof,isdakota,isoceancoupling) % {{{
++
++			if(isgprof),    disp('gprof not supported by cluster, ignoring...'); end
++
++			executable='issm.exe';
++			if isdakota,
++				version=IssmConfig('_DAKOTA_VERSION_'); version=str2num(version(1:3));
++				if (version>=6),
++					executable='issm_dakota.exe';
++				end
++			end
++			if isoceancoupling,
++				executable='issm_ocean.exe';
++			end
++
++			%write queuing script 
++			fid=fopen([modelname '.queue'],'w');
++			fprintf(fid,'#!/bin/bash\n');
++			fprintf(fid,'export PATH="${PATH}:."\n');
++			fprintf(fid,'export MPI_LAUNCH_TIMEOUT=520\n');
++			fprintf(fid,'export MPI_GROUP_MAX=64\n');
++			fprintf(fid,'export ISSM_DIR="%s"\n',cluster.srcpath);
++			if cluster.extpkgpath
++				fprintf(fid,'export ISSM_EXT_DIR="%s"\n',cluster.extpkgpath);
++			end
++			fprintf(fid,'source $ISSM_DIR/etc/environment.sh\n\n');
++			if cluster.interactive
++				if IssmConfig('_HAVE_MPI_'),
++					fprintf(fid,'mpiexec -np %i %s/%s %s %s %s\n',cluster.nprocs(),cluster.codepath,executable,solution,[cluster.executionpath '/' dirname],modelname);
++				else
++					fprintf(fid,'%s/%s %s %s %s\n',cluster.codepath,executable,solution,[cluster.executionpath '/' dirname],modelname);
++				end
++			else
++				if IssmConfig('_HAVE_MPI_'),
++					fprintf(fid,'mpiexec -np %i %s/%s %s %s %s 2> %s.errlog > %s.outlog &\n',cluster.nprocs(),cluster.codepath,executable,solution,[cluster.executionpath '/' dirname],modelname,modelname,modelname);
++				else
++					fprintf(fid,'%s/%s %s %s %s 2> %s.errlog > %s.outlog &\n',cluster.codepath,executable,solution,[cluster.executionpath '/' dirname],modelname,modelname,modelname);
++				end
++			end
++			if ~io_gather, %concatenate the output files:
++				fprintf(fid,'cat %s.outbin.* > %s.outbin',modelname,modelname);
++			end
++			fclose(fid);
++
++			%in interactive mode, create a run file, and errlog and outlog file
++			if cluster.interactive,
++				fid=fopen([modelname '.errlog'],'w'); fclose(fid);
++				fid=fopen([modelname '.outlog'],'w'); fclose(fid);
++			end
++		end %}}}
++		function UploadQueueJob(cluster,modelname,dirname,filelist) % {{{
++
++			%compress the files into one zip.
++			compressstring=['tar -zcf ' dirname '.tar.gz'];
++			for i=1:numel(filelist),
++				compressstring = [compressstring ' ' filelist{i}];
++			end
++			if cluster.interactive,
++				compressstring = [compressstring ' ' modelname '.run '  modelname '.errlog ' modelname '.outlog '];
++			end
++			system(compressstring);
++
++			disp('uploading input file and queuing script');
++			if cluster.interactive==10,
++				directory=[pwd() '/run/'];
++			elseif cluster.interactive,
++				directory=[cluster.executionpath '/Interactive' num2str(cluster.interactive)];
++			else 
++				directory=cluster.executionpath;
++			end
++
++			%NOTE: Replacement for issmscpout(cluster.name,directory,cluster.login,cluster.port,{[dirname '.tar.gz']});
++			uploadstring=['scp -i ' cluster.idfile ' ' dirname '.tar.gz ' cluster.login '@' cluster.name ':' directory];
++			[status,result]=system(uploadstring);
++			if status, 
++				error(['cluster.UploadQueueJob error message: ' status]);
++			end
++		end
++		%}}}
++		function LaunchQueueJob(cluster,modelname,dirname,filelist,restart,batch) % {{{
++
++			%launch command, to be executed via ssh
++			if cluster.interactive,
++				if ~isempty(restart)
++					launchcommand=['cd ' cluster.executionpath '/Interactive' num2str(cluster.interactive)];
++				else
++					if cluster.interactive==10,
++						launchcommand=['cd ' pwd() '/run && tar -zxf ' dirname '.tar.gz'];
++					else
++						launchcommand=['cd ' cluster.executionpath '/Interactive' num2str(cluster.interactive) ' && tar -zxf ' dirname '.tar.gz'];
++					end
++				end
++			else
++				if ~isempty(restart)
++					launchcommand=['cd ' cluster.executionpath ' && cd ' dirname ' && ./' modelname '.queue'];
++				else
++					launchcommand=['cd ' cluster.executionpath ' && rm -rf ./' dirname ' && mkdir ' dirname ...
++						' && cd ' dirname ' && mv ../' dirname '.tar.gz . && tar -zxf ' dirname '.tar.gz && chmod +x ./' modelname '.queue && ./' modelname '.queue'];
++				end
++			end
++
++			disp('launching solution sequence on remote cluster');
++			%NOTE: Replacement for issmssh(cluster.name,cluster.login,cluster.port,launchcommand);
++			launchstring=['ssh -l ' cluster.login ' -i ' cluster.idfile ' ' cluster.name ' "' launchcommand '"'];
++			[status,result]=system(launchstring);
++			if status,
++				error(['cluster.LaunchQueueJob error message: ' status]);
++			end
++		end
++		%}}}
++		function Download(cluster,dirname,filelist) % {{{
++
++			%copy files from cluster to current directory
++			if cluster.interactive==10,
++				directory=[pwd() '/run/'];
++			elseif ~cluster.interactive,
++				directory=[cluster.executionpath '/' dirname '/'];
++			else
++				directory=[cluster.executionpath '/Interactive' num2str(cluster.interactive) '/'];
++			end
++
++			%NOTE: Replacement for issmscpin(cluster.name,cluster.login,cluster.port,directory,filelist);
++			if numel(filelist)==1,
++				filestring=filelist{1};
++			else
++				filestring='\{';
++				for i=1:numel(filelist)-1,
++					filestring=[filestring filelist{i} ','];
++				end
++				filestring=[filestring filelist{end} '\}'];
++			end
++
++			downloadstring=['scp -i ' cluster.idfile ' ' cluster.login '@' cluster.name ':' directory '/' filestring ' ./'];
++			[status,result]=system(downloadstring);
++			if status, 
++				error(['cluster.Download error message: ' status]);
++			end
++
++			%check scp worked
++			for i=1:numel(filelist),
++				if ~exist(['./' filelist{i}]),
++					warning(['cluster.Download error message: could not scp ' filelist{i}]);
++				end
++			end
++
++		end %}}}
++	end
++end
+Index: ../trunk-jpl/src/m/classes/clusters/camhpc.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/clusters/camhpc.m	(revision 27261)
++++ ../trunk-jpl/src/m/classes/clusters/camhpc.m	(revision 27262)
+@@ -123,7 +123,7 @@
+ 			end
+ 			system(compressstring);
+ 
+-			disp('uploading input file and queueing script');
++			disp('uploading input file and queuing script');
+ 			issmscpout(cluster.name,cluster.executionpath,cluster.login,cluster.port,{[dirname '.tar.gz']});
+ 
+ 		end %}}}
+Index: ../trunk-jpl/src/m/classes/clusters/castor.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/clusters/castor.m	(revision 27261)
++++ ../trunk-jpl/src/m/classes/clusters/castor.m	(revision 27262)
+@@ -81,7 +81,7 @@
+ 			end
+ 			system(compressstring);
+ 
+-			disp('uploading input file and queueing script');
++			disp('uploading input file and queuing script');
+ 			issmscpout(cluster.name,cluster.executionpath,cluster.login,cluster.port,{[dirname '.tar.gz']});
+ 
+ 		end %}}}
+Index: ../trunk-jpl/src/m/classes/clusters/cloud.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/clusters/cloud.m	(revision 27261)
++++ ../trunk-jpl/src/m/classes/clusters/cloud.m	(revision 27262)
+@@ -69,7 +69,7 @@
+ 			if isempty(cluster.login),
+ 				error('cloud BuildQueueScript: login should be supplied!');
+ 			end
+-			disp('uploading input file and queueing script');
++			disp('uploading input file and queuing script');
+ 			issmstscpout(cluster.name,cluster.executionpath,cluster.login,{[dirname '.tar.gz']});
+ 
+ 		end %}}}
+Index: ../trunk-jpl/src/m/classes/clusters/cloud.py
+===================================================================
+--- ../trunk-jpl/src/m/classes/clusters/cloud.py	(revision 27261)
++++ ../trunk-jpl/src/m/classes/clusters/cloud.py	(revision 27262)
+@@ -74,7 +74,7 @@
+         if isempty(self.login):
+             raise Exception('cloud BuildQueueScript: login should be supplied!')
+ 
+-        print('uploading input file and queueing script')
++        print('uploading input file and queuing script')
+         issmstscpout(self.name, self.executionpath, self.login, '{}.tar.gz'.format(dirname))
+     # }}}
+ 
+Index: ../trunk-jpl/src/m/classes/clusters/computecanada.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/clusters/computecanada.m	(revision 27261)
++++ ../trunk-jpl/src/m/classes/clusters/computecanada.m	(revision 27262)
+@@ -107,7 +107,7 @@
+ 			 end
+ 			 system(compressstring);
+ 
+-			 disp('uploading input file and queueing script');
++			 disp('uploading input file and queuing script');
+ 			 issmscpout(cluster.name,cluster.executionpath,cluster.login,cluster.port,{[dirname '.tar.gz']});
+ 
+ 		 end %}}}
+Index: ../trunk-jpl/src/m/classes/clusters/cosmos.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/clusters/cosmos.m	(revision 27261)
++++ ../trunk-jpl/src/m/classes/clusters/cosmos.m	(revision 27262)
+@@ -81,7 +81,7 @@
+ 			end
+ 			system(compressstring);
+ 
+-			disp('uploading input file and queueing script');
++			disp('uploading input file and queuing script');
+ 			issmscpout(cluster.name,cluster.executionpath,cluster.login,cluster.port,{[dirname '.tar.gz']});
+ 
+ 		end %}}}
+Index: ../trunk-jpl/src/m/classes/clusters/cyclone.py
+===================================================================
+--- ../trunk-jpl/src/m/classes/clusters/cyclone.py	(revision 27261)
++++ ../trunk-jpl/src/m/classes/clusters/cyclone.py	(revision 27262)
+@@ -92,7 +92,7 @@
+             compressstring += ' {}'.format(file)
+         subprocess.call(compressstring, shell=True)
+ 
+-        print('uploading input file and queueing script')
++        print('uploading input file and queuing script')
+         issmscpout(self.name, self.executionpath, self.login, self.port, [dirname + '.tar.gz'])
+     # }}}
+     def LaunchQueueJob(self, modelname, dirname, filelist, restart, batch):  # {{{
+Index: ../trunk-jpl/src/m/classes/clusters/discover.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/clusters/discover.m	(revision 27261)
++++ ../trunk-jpl/src/m/classes/clusters/discover.m	(revision 27262)
+@@ -172,7 +172,7 @@
+ 			end
+ 			system(compressstring);
+ 
+-			disp('uploading input file and queueing script');
++			disp('uploading input file and queuing script');
+ 			if cluster.interactive,
+ 				directory=[cluster.executionpath '/Interactive' num2str(cluster.interactive)];
+ 			else 
+Index: ../trunk-jpl/src/m/classes/clusters/discover.py
+===================================================================
+--- ../trunk-jpl/src/m/classes/clusters/discover.py	(revision 27261)
++++ ../trunk-jpl/src/m/classes/clusters/discover.py	(revision 27262)
+@@ -180,7 +180,7 @@
+             compressstring += ' {}.run {}.errlog {}.outlog'.format(modelname, modelname, modelname)
+         subprocess.call(compressstring, shell=True)
+ 
+-        print('uploading input file and queueing script')
++        print('uploading input file and queuing script')
+         if self.interactive:
+             directory = '{}/Interactive{}'.format(self.executionpath, self.interactive)
+         else:
+Index: ../trunk-jpl/src/m/classes/clusters/discovery.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/clusters/discovery.m	(revision 27261)
++++ ../trunk-jpl/src/m/classes/clusters/discovery.m	(revision 27262)
+@@ -144,7 +144,7 @@
+ 			end
+ 			system(compressstring);
+ 
+-			disp('uploading input file and queueing script');
++			disp('uploading input file and queuing script');
+ 			issmscpout(cluster.name,cluster.executionpath,cluster.login,0,{[dirname '.tar.gz']});
+ 
+ 		end %}}}
+Index: ../trunk-jpl/src/m/classes/clusters/fram.py
+===================================================================
+--- ../trunk-jpl/src/m/classes/clusters/fram.py	(revision 27261)
++++ ../trunk-jpl/src/m/classes/clusters/fram.py	(revision 27262)
+@@ -143,7 +143,7 @@
+             compressstring += ' {}'.format(file)
+         subprocess.call(compressstring, shell=True)
+ 
+-        print('uploading input file and queueing script')
++        print('uploading input file and queuing script')
+         issmscpout(self.name, self.executionpath, self.login, self.port, [dirname + '.tar.gz'])
+ 
+     # }}}
+Index: ../trunk-jpl/src/m/classes/clusters/frontera.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/clusters/frontera.m	(revision 27261)
++++ ../trunk-jpl/src/m/classes/clusters/frontera.m	(revision 27262)
+@@ -176,7 +176,7 @@
+ 			end
+ 			system(compressstring);
+ 
+-			disp('uploading input file and queueing script');
++			disp('uploading input file and queuing script');
+ 			issmscpout(cluster.name,cluster.executionpath,cluster.login,cluster.port,{[dirname '.tar.gz']});
+ 
+ 		end %}}}
+Index: ../trunk-jpl/src/m/classes/clusters/gemini.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/clusters/gemini.m	(revision 27261)
++++ ../trunk-jpl/src/m/classes/clusters/gemini.m	(revision 27262)
+@@ -82,7 +82,7 @@
+ 			end
+ 			system(compressstring);
+ 
+-			disp('uploading input file and queueing script');
++			disp('uploading input file and queuing script');
+ 			issmscpout(cluster.name,cluster.executionpath,cluster.login,cluster.port,{[dirname '.tar.gz']});
+ 
+ 		end %}}}
+Index: ../trunk-jpl/src/m/classes/clusters/generic.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/clusters/generic.m	(revision 27261)
++++ ../trunk-jpl/src/m/classes/clusters/generic.m	(revision 27262)
+@@ -306,7 +306,7 @@
+ 				end
+ 				system(compressstring);
+ 
+-				if cluster.verbose, disp('uploading input file and queueing script'); end
++				if cluster.verbose, disp('uploading input file and queuing script'); end
+ 				issmscpout(cluster.name,cluster.executionpath,cluster.login,cluster.port,{[dirname '.tar.gz']});
+ 			end
+ 		end %}}}
+Index: ../trunk-jpl/src/m/classes/clusters/generic.py
+===================================================================
+--- ../trunk-jpl/src/m/classes/clusters/generic.py	(revision 27261)
++++ ../trunk-jpl/src/m/classes/clusters/generic.py	(revision 27262)
+@@ -97,7 +97,7 @@
+         if isoceancoupling:
+             executable = 'issm_ocean.exe'
+ 
+-        # Write queueing script
++        # Write queuing script
+         if not ispc():
+             fid = open(modelname + '.queue', 'w')
+             fid.write('#!/bin/sh\n')
+@@ -199,7 +199,7 @@
+             compressstring += ' {}.errlog {}.outlog '.format(modelname, modelname)
+         call(compressstring, shell=True)
+ 
+-        print('uploading input file and queueing script')
++        print('uploading input file and queuing script')
+         issmscpout(self.name, self.executionpath, self.login, self.port, [dirname + '.tar.gz'])
+ 
+     # }}}
+Index: ../trunk-jpl/src/m/classes/clusters/generic_static.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/clusters/generic_static.m	(revision 27261)
++++ ../trunk-jpl/src/m/classes/clusters/generic_static.m	(revision 27262)
+@@ -76,7 +76,7 @@
+ 			% Process codepath and prepend empty spaces with \ to avoid errors in queuing script
+ 			codepath=strrep(cluster.codepath,' ','\ ');
+ 
+-			% Write queueing script
++			% Write queuing script
+ 			fid=fopen([modelname '.queue'],'w');
+ 			fprintf(fid,'#!%s\n',cluster.shell);
+ 			fprintf(fid,['%s/mpiexec -np %i %s/%s %s %s %s \n'],codepath,cluster.np,codepath,executable,solution,'./',modelname);
+Index: ../trunk-jpl/src/m/classes/clusters/generic_static.py
+===================================================================
+--- ../trunk-jpl/src/m/classes/clusters/generic_static.py	(revision 27261)
++++ ../trunk-jpl/src/m/classes/clusters/generic_static.py	(revision 27262)
+@@ -84,7 +84,7 @@
+         # Process codepath and prepend empty spaces with \ to avoid errors in queuing script
+         codepath = self.codepath.replace(' ', '\ ')
+ 
+-        # Write queueing script
++        # Write queuing script
+         fid = open(modelname + '.queue', 'w')
+         fid.write('#!{}'.format(self.shell) + '\n')
+         fid.write('{}/mpiexec -np {} {}/{} {} {} {}'.format(codepath, self.np, codepath, executable, solution, './', modelname))
+@@ -119,7 +119,7 @@
+         # Process codepath and prepend empty spaces with \ to avoid errors in queuing script
+         codepath = self.codepath.replace(' ', '\ ')
+ 
+-        # Write queueing script
++        # Write queuing script
+         fid = open(modelname + '.queue', 'w')
+         fid.write('#!{}'.format(self.shell) + '\n')
+         fid.write('{}/mpiexec -np {} {}/{} {} {} {}'.format(codepath, self.np, codepath, executable, solution, './', modelname) + '\n')
+Index: ../trunk-jpl/src/m/classes/clusters/greenplanet.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/clusters/greenplanet.m	(revision 27261)
++++ ../trunk-jpl/src/m/classes/clusters/greenplanet.m	(revision 27262)
+@@ -151,7 +151,7 @@
+ 			end
+ 			system(compressstring);
+ 
+-			disp('uploading input file and queueing script');
++			disp('uploading input file and queuing script');
+ 			issmscpout(cluster.name,cluster.executionpath,cluster.login,cluster.port,{[dirname '.tar.gz']});
+ 
+ 		end %}}}
+Index: ../trunk-jpl/src/m/classes/clusters/hpc.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/clusters/hpc.m	(revision 27261)
++++ ../trunk-jpl/src/m/classes/clusters/hpc.m	(revision 27262)
+@@ -139,7 +139,7 @@
+ 			end
+ 			system(compressstring);
+ 
+-			disp('uploading input file and queueing script');
++			disp('uploading input file and queuing script');
+ 			issmscpout(cluster.name,cluster.executionpath,cluster.login,cluster.port,{[dirname '.tar.gz']});
+ 
+ 		end %}}}
+Index: ../trunk-jpl/src/m/classes/clusters/hpc_simba.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/clusters/hpc_simba.m	(revision 27261)
++++ ../trunk-jpl/src/m/classes/clusters/hpc_simba.m	(revision 27262)
+@@ -151,7 +151,7 @@
+ 			end
+ 			system(compressstring);
+ 
+-			disp('uploading input file and queueing script');
++			disp('uploading input file and queuing script');
+ 			issmscpout(cluster.name,cluster.executionpath,cluster.login,cluster.port,{[dirname '.tar.gz']});
+ 
+ 		end %}}}
+Index: ../trunk-jpl/src/m/classes/clusters/localpfe.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/clusters/localpfe.m	(revision 27261)
++++ ../trunk-jpl/src/m/classes/clusters/localpfe.m	(revision 27262)
+@@ -227,7 +227,7 @@
+ 				end
+ 				system(compressstring);
+ 
+-				if cluster.verbose, disp('uploading input file and queueing script'); end
++				if cluster.verbose, disp('uploading input file and queuing script'); end
+ 				issmscpout(cluster.name,cluster.executionpath,cluster.login,cluster.port,{[dirname '.tar.gz']});
+ 			end
+ 		end %}}}
+Index: ../trunk-jpl/src/m/classes/clusters/lonestar.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/clusters/lonestar.m	(revision 27261)
++++ ../trunk-jpl/src/m/classes/clusters/lonestar.m	(revision 27262)
+@@ -175,7 +175,7 @@
+ 			end
+ 			system(compressstring);
+ 
+-			disp('uploading input file and queueing script');
++			disp('uploading input file and queuing script');
+ 			issmscpout(cluster.name,cluster.executionpath,cluster.login,cluster.port,{[dirname '.tar.gz']});
+ 
+ 		end %}}}
+Index: ../trunk-jpl/src/m/classes/clusters/maui.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/clusters/maui.m	(revision 27261)
++++ ../trunk-jpl/src/m/classes/clusters/maui.m	(revision 27262)
+@@ -126,7 +126,7 @@
+ 			end
+ 			system(compressstring);
+ 
+-			disp('uploading input file and queueing script');
++			disp('uploading input file and queuing script');
+ 			issmscpout(cluster.name,cluster.executionpath,cluster.login,cluster.port,{[dirname '.tar.gz']});
+ 
+ 		end %}}}
+Index: ../trunk-jpl/src/m/classes/clusters/pace.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/clusters/pace.m	(revision 27261)
++++ ../trunk-jpl/src/m/classes/clusters/pace.m	(revision 27262)
+@@ -88,7 +88,7 @@
+ 			end
+ 			system(compressstring);
+ 
+-			disp('uploading input file and queueing script');
++			disp('uploading input file and queuing script');
+ 			issmscpout(cluster.name,cluster.executionpath,cluster.login,cluster.port,{[dirname '.tar.gz']});
+ 
+ 		end %}}}
+Index: ../trunk-jpl/src/m/classes/clusters/pfe.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/clusters/pfe.m	(revision 27261)
++++ ../trunk-jpl/src/m/classes/clusters/pfe.m	(revision 27262)
+@@ -175,7 +175,7 @@
+ 			fprintf(fid,'export MPI_GROUP_MAX=64\n\n');
+ 			fprintf(fid,'export ISSM_DIR="%s"\n',cluster.srcpath); %FIXME
+ 			if cluster.extpkgpath
+-				fprintf(fid,'export ISSM_EXT_PKG="%s"\n',cluster.extpkgpath); 
++				fprintf(fid,'export ISSM_EXT_DIR="%s"\n',cluster.extpkgpath); 
+ 			end
+ 			fprintf(fid,'source $ISSM_DIR/etc/environment.sh\n');       %FIXME
+ 			fprintf(fid,'cd %s/%s/\n\n',cluster.executionpath,dirname);
+Index: ../trunk-jpl/src/m/classes/clusters/pfe.py
+===================================================================
+--- ../trunk-jpl/src/m/classes/clusters/pfe.py	(revision 27261)
++++ ../trunk-jpl/src/m/classes/clusters/pfe.py	(revision 27262)
+@@ -179,7 +179,7 @@
+         fid.write('export MPI_GROUP_MAX=64\n\n')
+         fid.write('export ISSM_DIR="{}"\n'.format(self.srcpath)) # FIXME
+         if self.extpkgpath:
+-            fid.write('export ISSM_EXT_PKG="{}"\n'.format(self.extpkgpath)) 
++            fid.write('export ISSM_EXT_DIR="{}"\n'.format(self.extpkgpath)) 
+         fid.write('source $ISSM_DIR/etc/environment.sh\n') # FIXME
+         fid.write('cd {}/{}/\n\n'.format(self.executionpath, dirname))
+         fid.write('mpiexec -np {} {}/{} {} {}/{} {}\n'.format(self.nprocs(), self.codepath, executable, solution, self.executionpath, dirname, modelname))
+Index: ../trunk-jpl/src/m/classes/clusters/raijin.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/clusters/raijin.m	(revision 27261)
++++ ../trunk-jpl/src/m/classes/clusters/raijin.m	(revision 27262)
+@@ -101,7 +101,7 @@
+ 			end
+ 			system(compressstring);
+ 
+-			disp('uploading input file and queueing script');
++			disp('uploading input file and queuing script');
+ 			issmscpout(cluster.name,cluster.executionpath,cluster.login,cluster.port,{[dirname '.tar.gz']});
+ 
+ 		end %}}}
+Index: ../trunk-jpl/src/m/classes/clusters/saga.py
+===================================================================
+--- ../trunk-jpl/src/m/classes/clusters/saga.py	(revision 27261)
++++ ../trunk-jpl/src/m/classes/clusters/saga.py	(revision 27262)
+@@ -152,7 +152,7 @@
+             compressstring += ' {}'.format(file)
+         subprocess.call(compressstring, shell=True)
+ 
+-        print('uploading input file and queueing script')
++        print('uploading input file and queuing script')
+         issmscpout(self.name, self.executionpath, self.login, self.port, [dirname + '.tar.gz'])
+     # }}}
+ 
+Index: ../trunk-jpl/src/m/classes/clusters/sherlock.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/clusters/sherlock.m	(revision 27261)
++++ ../trunk-jpl/src/m/classes/clusters/sherlock.m	(revision 27262)
+@@ -134,7 +134,7 @@
+ 			end
+ 			system(compressstring);
+ 
+-			disp('uploading input file and queueing script');
++			disp('uploading input file and queuing script');
+ 			issmscpout(cluster.name,cluster.executionpath,cluster.login,cluster.port,{[dirname '.tar.gz']});
+ 
+ 		end %}}}
+Index: ../trunk-jpl/src/m/classes/clusters/smce_eis.py
+===================================================================
+--- ../trunk-jpl/src/m/classes/clusters/smce_eis.py	(revision 27261)
++++ ../trunk-jpl/src/m/classes/clusters/smce_eis.py	(revision 27262)
+@@ -176,7 +176,7 @@
+             compressstring += ' {}.run {}.errlog {}.outlog'.format(modelname, modelname, modelname)
+         subprocess.call(compressstring, shell=True)
+ 
+-        print('uploading input file and queueing script')
++        print('uploading input file and queuing script')
+         if self.interactive:
+             directory = '{}/Interactive{}'.format(self.executionpath, self.interactive)
+         else:
+Index: ../trunk-jpl/src/m/classes/clusters/tetralith.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/clusters/tetralith.m	(revision 27261)
++++ ../trunk-jpl/src/m/classes/clusters/tetralith.m	(revision 27262)
+@@ -191,7 +191,7 @@
+ 				compressstring = [compressstring ' ' filelist{i}];
+ 			end
+ 			system(compressstring);
+-			disp('uploading input file and queueing script');
++			disp('uploading input file and queuing script');
+ 			directory=cluster.executionpath;
+ % 			issmbbftpout(cluster.name,directory,cluster.login,cluster.port,cluster.numstreams,{[dirname '.tar.gz']});
+ 			issmscpout(cluster.name,directory,cluster.login,cluster.port,{[dirname '.tar.gz']});
+Index: ../trunk-jpl/src/m/classes/clusters/yellowstone.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/clusters/yellowstone.m	(revision 27261)
++++ ../trunk-jpl/src/m/classes/clusters/yellowstone.m	(revision 27262)
+@@ -127,7 +127,7 @@
+ 			end
+ 			system(compressstring);
+ 
+-			disp('uploading input file and queueing script');
++			disp('uploading input file and queuing script');
+ 			directory=cluster.executionpath;
+ 
+ 			issmscpout(cluster.name,directory,cluster.login,cluster.port,{[dirname '.tar.gz']});
+Index: ../trunk-jpl/src/m/solve/waitonlock.m
+===================================================================
+--- ../trunk-jpl/src/m/solve/waitonlock.m	(revision 27261)
++++ ../trunk-jpl/src/m/solve/waitonlock.m	(revision 27262)
+@@ -42,18 +42,21 @@
+ 
+ %prepare command if the job is not running on the local machine
+ if ~strcmpi(oshostname(),cluster.name),
+-	login = cluster.login;
+-	port  = 0;
+-	if isprop(cluster,'port') 
+-		port = cluster.port;
+-	end
+-	if port,
+-		command = ['ssh -l ' login ' -p ' num2str(port) ' localhost "[ -f ' lockfilename ' ] && [ -f ' logfilename ' ]" 2>/dev/null'];
+-	elseif isa(cluster,'cloud')
++	if isa(cluster,'cloud'),
+ 		command = [' [ -f ' lockfilename ' ] && [ -f ' logfilename ' ] 2>/dev/null'];
+ 		command = [starcluster() ' sshmaster ' cluster.name ' --user ' cluster.login ' ''' command ''''];
+ 	else
+-		command = ['ssh -l ' login ' ' cluster.name ' "[ -f ' lockfilename ' ] && [ -f ' logfilename ' ]" 2>/dev/null'];
++		command = ['ssh -l ' cluster.login];
++		if isprop(cluster,'idfile') && ~strcmp(cluster.idfile,''),
++			command = [command ' -i ' cluster.idfile];
++		end
++		port=0;
++		if isprop(cluster,'port') && cluster.port,
++			command = [command ' -p ' num2str(port) ' localhost'];
++		else,
++			command = [command ' ' cluster.name];
++		end
++		command = [command ' "[ -f ' lockfilename ' ] && [ -f ' logfilename ' ]" 2>/dev/null'];
+ 	end
+ end
+ 
+Index: ../trunk-jpl/test/NightlyRun/runme.m
+===================================================================
+--- ../trunk-jpl/test/NightlyRun/runme.m	(revision 27261)
++++ ../trunk-jpl/test/NightlyRun/runme.m	(revision 27262)
+@@ -234,7 +234,7 @@
+ 					%our output is in the correct order (n,1) or (1,1), so we do not need to transpose again
+ 					archive_cell=archread(['../Archives/' archive_name '.arch'],[archive_name '_field' num2str(k)]);
+ 					archive=archive_cell{1};
+-					error_diff=full(max(abs(archive(:)-field(:)))/(max(abs(archive(:)))+eps));					%disp test result
++					error_diff=full(max(abs(archive(:)-field(:)))/(max(abs(archive(:)))+eps)); %disp test result
+ 					if (error_diff>tolerance | isnan(error_diff));
+ 						disp(sprintf(['ERROR   difference: %-7.2g > %7.2g test id: %i test name: %s field: %s'],...
+ 							error_diff,tolerance,id,id_string,fieldname));
+Index: ../trunk-jpl/test/NightlyRun/test101awsissmsolutionserver.m
+===================================================================
+--- ../trunk-jpl/test/NightlyRun/test101awsissmsolutionserver.m	(nonexistent)
++++ ../trunk-jpl/test/NightlyRun/test101awsissmsolutionserver.m	(revision 27262)
+@@ -0,0 +1,94 @@
++%Test Name: SquareShelfConstrainedStressSSA2d
++md=triangle(model(),'../Exp/Square.exp',50000.);
++md=setmask(md,'all','');
++md=parameterize(md,'../Par/SquareShelfConstrained.par');
++md=setflowequation(md,'SSA','all');
++md.cluster=generic('name',oshostname(),'np',2);
++
++if true
++	cluster=aws_issm_solution_server;
++	cluster.login='';
++	cluster.idfile='';
++	cluster.executionpath='~/issm-exec';
++	md.cluster=cluster;
++end
++
++%output
++md.stressbalance.requested_outputs={'default','DeviatoricStressxx','DeviatoricStressyy','DeviatoricStressxy','MassFlux1','MassFlux2','MassFlux3','MassFlux4','MassFlux5','MassFlux6'};
++md.outputdefinition.definitions={...
++	massfluxatgate('name','MassFlux1','profilename',['../Exp/MassFlux1.exp'],'definitionstring','Outputdefinition1'),...
++	massfluxatgate('name','MassFlux2','profilename',['../Exp/MassFlux2.exp'],'definitionstring','Outputdefinition2'),...
++	massfluxatgate('name','MassFlux3','profilename',['../Exp/MassFlux3.exp'],'definitionstring','Outputdefinition3'),...
++	massfluxatgate('name','MassFlux4','profilename',['../Exp/MassFlux4.exp'],'definitionstring','Outputdefinition4'),...
++	massfluxatgate('name','MassFlux5','profilename',['../Exp/MassFlux5.exp'],'definitionstring','Outputdefinition5'),...
++	massfluxatgate('name','MassFlux6','profilename',['../Exp/MassFlux6.exp'],'definitionstring','Outputdefinition6')...
++	};
++
++md=solve(md,'Stressbalance');
++
++%Fields and tolerances to track changes
++field_names     ={'Vx','Vy','Vel','Pressure',...
++	'DeviatoricStressxx','DeviatoricStressyy','DeviatoricStressxy','MassFlux1','MassFlux2','MassFlux3','MassFlux4','MassFlux5','MassFlux6'};
++field_tolerances={3e-13,1e-13,1e-13,1e-13,...
++	2e-13,1e-13,2e-13,...
++	1e-13, 1e-13, 1e-13, 1e-13, 1e-13, 1e-13 };
++field_values={...
++	(md.results.StressbalanceSolution.Vx),...
++	(md.results.StressbalanceSolution.Vy),...
++	(md.results.StressbalanceSolution.Vel),...
++	(md.results.StressbalanceSolution.Pressure),...
++	(md.results.StressbalanceSolution.DeviatoricStressxx),...
++	(md.results.StressbalanceSolution.DeviatoricStressyy),...
++	(md.results.StressbalanceSolution.DeviatoricStressxy),...
++	(md.results.StressbalanceSolution.MassFlux1),...
++	(md.results.StressbalanceSolution.MassFlux2),...
++	(md.results.StressbalanceSolution.MassFlux3),...
++	(md.results.StressbalanceSolution.MassFlux4),...
++	(md.results.StressbalanceSolution.MassFlux5),...
++	(md.results.StressbalanceSolution.MassFlux6)...
++	};
++
++id=101;
++id_string='test101';
++archive_name=['Archive101'];
++for k=1:length(field_names),
++
++	try,
++		%Get field and tolerance
++		field=field_values{k};
++		fieldname=field_names{k};
++		tolerance=field_tolerances{k};
++
++		%compare to archive
++		%our output is in the correct order (n,1) or (1,1), so we do not need to transpose again
++		archive_cell=archread(['../Archives/' archive_name '.arch'],[archive_name '_field' num2str(k)]);
++		archive=archive_cell{1};
++		error_diff=full(max(abs(archive(:)-field(:)))/(max(abs(archive(:)))+eps)); %disp test result
++		if (error_diff>tolerance | isnan(error_diff));
++			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'],...
++				error_diff,tolerance,id,id_string,fieldname));
++		end
++
++	catch me2
++
++		%something went wrong, print failure message:
++		message=getReport(me2);
++		fprintf('%s',message);
++		if strcmpi(output,'nightly')
++			fid=fopen([issmdir() '/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,fieldname));
++		else
++			disp(sprintf(['FAILURE difference: N/A test id: %i test name: %s field: %s'],id,id_string,fieldname));
++			fprintf('%s',message);
++			if(getfieldvalue(options,'stoponerror',0)), disp('STOP'); return; end
++		end
++		continue;
++	end
++end
+Index: ../trunk-jpl/src/m/solve/waitonlock.py
+===================================================================
+--- ../trunk-jpl/src/m/solve/waitonlock.py	(revision 27261)
++++ ../trunk-jpl/src/m/solve/waitonlock.py	(revision 27262)
+@@ -60,10 +60,8 @@
+             if isprop(cluster, 'idfile') and cluster.idfile != '':
+                 command += ' -i {}'.format(cluster.idfile)
+             port = 0
+-            if isprop(cluster, 'port'):
+-                port = cluster.port
+-            if port: # Check if port is non-zero
+-                command += ' -p {} localhost'.format(port)
++            if isprop(cluster, 'port') && cluster.port:
++                command += ' -p {} localhost'.format(port);
+             else:
+                 command += ' {}'.format(cluster.name)
+             command += ' "[ -f {} ] && [ -f {} ]" 2>/dev/null'.format(lockfilename, logfilename)
+@@ -81,10 +79,6 @@
+             subproc = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
+             outs, errs = subproc.communicate()  # NOTE: Need to consume output before checking return code
+ 
+-            # TODO: Debug the following check under Linux (exits after first iteration with errs = "b")
+-            # UPDATE: Works in testing under Debian Linux system. Leaving comment for now so that it is easier to backtrace this issue if someone else encounters it.
+-            # FIXED: comunicates returns stuff in bytes in Python 3 unless you set "universal_newlines=True"
+-            #
+             if errs != '':
+                raise Exception('waitonlock: check for existence of files failed: {}'.format(errs))
+             ispresent = not subproc.returncode
Index: /issm/oecreview/Archive/27230-27343/ISSM-27262-27263.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27262-27263.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27262-27263.diff	(revision 27344)
@@ -0,0 +1,13 @@
+Index: ../trunk-jpl/src/m/solve/waitonlock.py
+===================================================================
+--- ../trunk-jpl/src/m/solve/waitonlock.py	(revision 27262)
++++ ../trunk-jpl/src/m/solve/waitonlock.py	(revision 27263)
+@@ -60,7 +60,7 @@
+             if isprop(cluster, 'idfile') and cluster.idfile != '':
+                 command += ' -i {}'.format(cluster.idfile)
+             port = 0
+-            if isprop(cluster, 'port') && cluster.port:
++            if isprop(cluster, 'port') and cluster.port:
+                 command += ' -p {} localhost'.format(port);
+             else:
+                 command += ' {}'.format(cluster.name)
Index: /issm/oecreview/Archive/27230-27343/ISSM-27263-27264.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27263-27264.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27263-27264.diff	(revision 27344)
@@ -0,0 +1,314 @@
+Index: ../trunk-jpl/src/m/contrib/defleurian/netCDF/export_netCDF.m
+===================================================================
+--- ../trunk-jpl/src/m/contrib/defleurian/netCDF/export_netCDF.m	(revision 27263)
++++ ../trunk-jpl/src/m/contrib/defleurian/netCDF/export_netCDF.m	(revision 27264)
+@@ -40,13 +40,20 @@
+ 	[DimSize(2).name,DimSize(2).value]=netcdf.inqDim(ncid,DimSize(2).index);
+ 	DimValue(2)=DimSize(2).value;
+ 	% adding mesh related dimensions
+-	dimlist=[2,40,md.mesh.numberofelements,md.mesh.numberofvertices,size(md.mesh.elements,2)];
++	dimlist=[2 40 md.mesh.numberofelements md.mesh.numberofvertices size(md.mesh.elements,2)];
+ 	dimnames=["DictDummy" "StringLength" "EltNum" "VertNum" "VertPerElt"];
++	if isprop(md.mesh, 'edges'),
++		dimlist(end+1)=md.mesh.numberofedges;
++		dimnames(end+1)="EdgeNum";
++	else
++		dimlist(end+1)=0;
++		dimnames(end+1)="EdgeNum";
++	end
+ 	if verbose > 0,
+ 		disp('===Creating dimensions ===');
+ 	end
+ 	%define netcdf dimensions
+-	for i=1:5
++	for i=1:length(dimlist)
+ 		% do not add the dimension if it exists already
+ 		if sum(dimlist(i) == DimValue) == 0
+ 			DimSize(i+2).index=netcdf.defDim(ncid,dimnames(i),dimlist(i));
+@@ -60,10 +67,14 @@
+ 		  ,'uint64','logical','char','string'};  %all malab types that are 0D
+ 
+ 	for cl=1:length(issmclasses),
+-		subclasses=fieldnames(md.(issmclasses{cl}))';
+-		for sc=1:length(subclasses),
+-			if sum(strcmp(class(md.(issmclasses{cl}).(subclasses{sc})), typelist)) == 0,
+-				issmclasses = [issmclasses class(md.(issmclasses{cl}).(subclasses{sc}))];
++		if isempty(md.(issmclasses{cl})),
++			disp(sprintf("md.%s is empty and will be left as default",issmclasses{cl}));
++		else
++			subclasses=fieldnames(md.(issmclasses{cl}))';
++			for sc=1:length(subclasses),
++				if sum(strcmp(class(md.(issmclasses{cl}).(subclasses{sc})), typelist)) == 0,
++					issmclasses = [issmclasses class(md.(issmclasses{cl}).(subclasses{sc}))];
++				end
+ 			end
+ 		end
+ 	end
+@@ -82,6 +93,10 @@
+ 		end
+ 		groupID=netcdf.defGrp(ncid,groups{i});
+ 		%In each group gather the fields of the class
++		if isempty(md.(groups{i})),
++			disp(sprintf("WARNING: md.%s is empty, we skip it.",groups{i}))
++			continue
++		end
+ 		fields=fieldnames(md.(groups{i}));
+ 		if isempty(fields),
+ 			disp(sprintf("WARNING: md.%s as no fields, we skip it.",groups{i}))
+@@ -168,7 +183,7 @@
+ 
+ 			elseif isa(Var,'struct')  % structures need special treatment
+ 				if strcmp(groups{i}, 'results'),
+-					klasstring='results.results';
++					klasstring=strcat(groups{i} ,'.', groups{i});
+ 					netcdf.putAtt(groupID,netcdf.getConstant('NC_GLOBAL'),'classtype',klasstring);
+ 					Listsize= length(md.(groups{i}).(fields{j}));
+ 					subgroupname=fields{j};
+@@ -211,6 +226,18 @@
+ 
+ 						end
+ 					end
++				elseif strcmp(groups{i}, 'toolkits'),
++					klasstring=strcat(groups{i} ,'.', groups{i});
++					netcdf.putAtt(groupID,netcdf.getConstant('NC_GLOBAL'),'classtype',klasstring);
++					if verbose > 4,
++						disp(sprintf("=}{=creating var for %s.%s",groups{i}, fields{j}));
++					end
++
++					[DimSize,DimValue,varid]=CreateVar(ncid,Var,groupID,fields{j},DimSize,DimValue);
++					if ~isempty(varid),
++						FillVar(Var,groupID,varid);
++					end
++
+ 				elseif isempty(fieldnames(md.(groups{i}).(fields{j}))) % this is an empty struct, jus treat it as normal
+ 					klass=class(md.(groups{i}));
+ 					klasstring = strcat(klass, '.',klass);
+@@ -398,28 +425,29 @@
+ 		end
+ 	elseif isa(Var,'struct'),
+ 		%Start by getting the structure fields and size
+-		locfields=fieldnames(Var)
++		locfields=fieldnames(Var);
+ 		for i=1:length(locfields),
+ 			for j=1:2,
+ 				if j==1,
+-					CharVar=locfields{i};
++					CharVar=locfields{i}';
++					disp(size(CharVar))
+ 					if length(CharVar)==0
+ 						CharVar='emptystruct';
+ 					end
+-					startpoint=[i-1,0,0];
++					startpoint=[0,0,i-1]
+ 				else
+ 					if isa(Var.(locfields{i}),'char'),
+-						CharVar=Var.(locfields{i});
++						CharVar=Var.(locfields{i})';
+ 					else
+-						CharVar=num2str(Var.(locfields{i}));
++						CharVar=num2str(Var.(locfields{i}))';
+ 					end
+ 					if length(CharVar)==0
+ 						CharVar='emptystruct';
+ 					end
+-					startpoint=[i-1,1,0];
++					startpoint=[0,1,i-1]
+ 				end
+ 
+-				extent=[1,1,min(length(CharVar),40)];
++				extent=[min(length(CharVar),40), 1, 1]
+ 				if length(CharVar)>40,
+ 					netcdf.putVar(groupID,varid,startpoint,extent,CharVar(1:40));
+ 					disp(sprintf('some variable have been truncated'));
+@@ -457,7 +485,7 @@
+ 	alldim=length(varsize);
+ 	if dim>0,
+ 		for i=1:alldim,
+-			if size(Var, i)>1 || i>dim,  %we skip dimensions with zero lenght but want to add dimensions from cells
++			if size(Var, i)>1 || i>dim || isa(Var, 'struct'),  %we skip dimensions with zero lenght but want to add dimensions from cells
+ 				indsize=find(varsize(i)==DimValue);
+ 				if length(indsize)>0
+ 					dims=[dims DimSize(indsize).index];
+@@ -477,6 +505,6 @@
+ 	end
+ 	% struct also need an extra dimension 2, but only if non empty
+ 	if isa(Var,'struct'),
+-		dims=[dims DimSize(3).index DimSize(4).index];
++		dims=[DimSize(4).index DimSize(3).index, dims];
+ 	end
+ end
+Index: ../trunk-jpl/src/m/contrib/defleurian/netCDF/export_netCDF.py
+===================================================================
+--- ../trunk-jpl/src/m/contrib/defleurian/netCDF/export_netCDF.py	(revision 27263)
++++ ../trunk-jpl/src/m/contrib/defleurian/netCDF/export_netCDF.py	(revision 27264)
+@@ -98,6 +98,13 @@
+     #add mesh related dimension that we know are needed
+     dimlist = [2, 40, md.mesh.numberofelements, md.mesh.numberofvertices, np.shape(md.mesh.elements)[1]]
+     dimnames = ['DictDummy', 'StringLength', 'EltNum', 'VertNum', 'VertPerElt']
++    try:
++        dimlist = dimlist + [md.mesh.numberofedges]
++        dimnames = dimnames + ['EdgeNum']
++    except AttributeError:
++        #no edges on this mesh, we fix it at 0
++        dimlist += [0]
++        dimnames += ['EdgeNum']
+     if verbose > 0:
+         print('===Creating dimensions ===')
+     for i, newdim in enumerate(dimlist):
+@@ -314,7 +321,6 @@
+         val_type = str(var.dtype)
+         if val_type.startswith('<U'):
+             val_type = 'stringarray'
+-            print(var)
+     except AttributeError:
+         val_type = type(var)
+ 
+Index: ../trunk-jpl/src/m/io/loadvars.py
+===================================================================
+--- ../trunk-jpl/src/m/io/loadvars.py	(revision 27263)
++++ ../trunk-jpl/src/m/io/loadvars.py	(revision 27264)
+@@ -54,6 +54,7 @@
+         raise TypeError("Unrecognized input arguments.")
+ 
+     timeindex = False
++    SteadySols = ['ThermalSolution', 'HydrologySolution', 'StressbalanceSolution']
+ 
+     for key, value in kwargs.items():
+         if key == 'singletime':
+@@ -104,8 +105,12 @@
+                     #that is the current treatment
+                     #here we have a more NC approach with time being a dimension
+                     listtype = split(r'\.', classtype[mod][0])[1]
+-                    print(listtype)
+-                    if len(NCFile.dimensions['Time']) == 1:
++                    try:
++                        soltype = str(getattr(curclass, 'SolutionType'))
++                    except AttributeError:
++                        #might be an older format try that instead :
++                        soltype = str(getattr(curclass, 'sOLUTIONtYPE'))
++                    if len(NCFile.dimensions['Time']) == 1 or soltype in SteadySols:
+                         nvdict['md'].__dict__[classtree[mod][0]].__dict__[classtree[mod][1]] = getattr(classtype[mod][1], listtype)()
+                         Tree = nvdict['md'].__dict__[classtree[mod][0]].__dict__[classtree[mod][1]]
+                     else:
+@@ -147,6 +152,9 @@
+                     nvdict['md'].__dict__[classtree[mod][0]].__dict__[defname].append(getattr(classtype[mod][1], outdeftype)())
+                     Tree = nvdict['md'].__dict__[classtree[mod][0]].__dict__[defname][defindex - 1]
+                 #}}}
++                elif classtype[mod][0] == 'collections.OrderedDict':  #Treating multiple toolkits {{{
++                    nvdict['md'].__dict__[classtree[mod][0]].__dict__[classtree[mod][1]] = getattr(classtype[mod][1], 'OrderedDict')
++                    Tree = nvdict['md'].__dict__[classtree[mod][0]].__dict__[classtree[mod][1]]
+                 else:
+                     if verbose > 0:
+                         print("    Using the default for md.{}.{}, is that right??".format(classtree[mod][0], classtree[mod][1]))
+@@ -183,8 +191,12 @@
+                     groupclass = [curclass.groups[key] for key in keylist]
+             else:
+                 groupclass = [curclass]
+-            #==== We deal with Variables {{{
+             for groupindex, listclass in enumerate(groupclass):
++                try:
++                    soltype = str(getattr(listclass, 'SolutionType'))
++                except AttributeError:
++                    soltype = 'NoSol'
++                #==== We deal with Variables {{{
+                 for var in listclass.variables:
+                     if not resname or var == resname:
+                         if var not in ['errlog', 'outlog']:
+@@ -216,11 +228,13 @@
+                                             Tree[0].__dict__[str(var)] = varval[timeindex, :, :].data
+                                         else:
+                                             print('table dimension greater than 3 not implemented yet')
++                                    elif soltype in SteadySols:
++                                        Tree.__dict__[str(var)] = varval[:].data
+                                     else:  #old format had step sorted in difeerent group so last group is last time
+                                         Tree[0].__dict__[str(var)] = varval[:].data
+                                 else:
+                                     if NewFormat:
+-                                        incomplete = 'Time' not in varval.dimensions
++                                        incomplete = 'Time' not in varval.dimensions and soltype not in SteadySols
+                                         if incomplete:
+                                             try:
+                                                 chosendim = varval.dimensions[0]
+@@ -229,24 +243,29 @@
+                                             except IndexError:
+                                                 #just one step, so no dimension, we just put it on the first solutionstep
+                                                 timelist = [0]
++                                        elif soltype in SteadySols:
++                                            timelist = [0]
+                                         else:
+                                             timelist = np.arange(0, len(NCFile.dimensions['Time']))
+-                                        for t in timelist:
+-                                            if verbose > 5:
+-                                                print("filing step {} for {}".format(t, var))
+-                                            if vardim == 0:
+-                                                Tree[t].__dict__[str(var)] = varval[:].data
+-                                            elif vardim == 1:
+-                                                stepval = ma.masked_array(varval[t].data, mask=np.where(np.isnan(varval[t]), 1, 0))
+-                                                Tree[t].__dict__[str(var)] = ma.compressed(stepval)
+-                                            elif vardim == 2:
+-                                                stepval = ma.masked_array(varval[t, :].data, mask=np.where(np.isnan(varval[t, :]), 1, 0))
+-                                                Tree[t].__dict__[str(var)] = ma.compressed(stepval)
+-                                            elif vardim == 3:
+-                                                stepval = ma.masked_array(varval[t, :, :].data, mask=np.where(np.isnan(varval[t, :, :]), 1, 0))
+-                                                Tree[t].__dict__[str(var)] = ma.compressed(stepval).reshape((stepval.count(0)[0], stepval.count(1)[0]))
+-                                            else:
+-                                                print('table dimension greater than 3 not implemented yet')
++                                        if soltype in SteadySols:
++                                            Tree.__dict__[str(var)] = varval[:].data
++                                        else:
++                                            for t in timelist:
++                                                if verbose > 5:
++                                                    print("filing step {} for {}".format(t, var))
++                                                if vardim == 0:
++                                                    Tree[t].__dict__[str(var)] = varval[:].data
++                                                elif vardim == 1:
++                                                    stepval = ma.masked_array(varval[t].data, mask=np.where(np.isnan(varval[t]), 1, 0))
++                                                    Tree[t].__dict__[str(var)] = ma.compressed(stepval)
++                                                elif vardim == 2:
++                                                    stepval = ma.masked_array(varval[t, :].data, mask=np.where(np.isnan(varval[t, :]), 1, 0))
++                                                    Tree[t].__dict__[str(var)] = ma.compressed(stepval)
++                                                elif vardim == 3:
++                                                    stepval = ma.masked_array(varval[t, :, :].data, mask=np.where(np.isnan(varval[t, :, :]), 1, 0))
++                                                    Tree[t].__dict__[str(var)] = ma.compressed(stepval).reshape((stepval.count(0)[0], stepval.count(1)[0]))
++                                                else:
++                                                    print('table dimension greater than 3 not implemented yet')
+                                     else:
+                                         if verbose > 0:
+                                             print("filing step {} for {}".format(groupindex, var))
+@@ -314,7 +333,19 @@
+                                         else:
+                                             Tree.__dict__[str(var)] = varval[:, :].data
+                                 elif vardim == 3:
+-                                    Tree.__dict__[str(var)] = varval[:, :, :].data
++                                    if varval.dtype == "|S1":  #that is for matlab chararcter arrays
++                                        #most likely that is a toolkit dictionar so should be treated as such
++                                        #first we convert the character table to strings
++                                        stringtable = []
++                                        for i in range(np.shape(varval)[0]):
++                                            stringtable.append([chartostring(varval[i, 0, :]), chartostring(varval[i, 1, :])])
++                                        stringtable = np.asarray(stringtable, dtype=str)
++                                        Tree.__dict__[str(var)] = OrderedDict([('toolkit', str(varval[np.where(stringtable[:, 0] == 'toolkit')[0][0], 1]))])
++                                        strings1 = [str(arg[0]) for arg in stringtable if arg[0] != 'toolkits']
++                                        strings2 = [str(arg[1]) for arg in stringtable if arg[0] != 'toolkits']
++                                        Tree.__dict__[str(var)].update(list(zip(strings1, strings2)))
++                                    else:
++                                        Tree.__dict__[str(var)] = varval[:, :, :].data
+                                 else:
+                                     print('table dimension greater than 3 not implemented yet')
+                 # }}}
+@@ -386,11 +417,12 @@
+                 class_dict[classe] = [str(getattr(NCData.groups[group], 'classtype')), ]
+                 if class_dict[classe][0] not in ['dict', 'list', 'cell']:
+                     modulename = split(r'\.', class_dict[classe][0])[0]
+-                    if modulename == "giaivins":
+-                        print("WARNING: module {} does not exist anymore and is skipped".format(modulename))
+-                    else:
++                    try:
+                         class_dict[classe].append(import_module(modulename))
+                         class_tree[classe] = [group, ]
++                    except ModuleNotFoundError:
++                        print("WARNING: module {} does not exist anymore and is skipped".format(modulename))
++
+             except AttributeError:
+                 print(('group {} is empty'.format(group)))
+     NCData.close()
Index: /issm/oecreview/Archive/27230-27343/ISSM-27271-27272.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27271-27272.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27271-27272.diff	(revision 27344)
@@ -0,0 +1,8 @@
+Index: ../trunk-jpl/test/Archives/Archive806.arch
+===================================================================
+Cannot display: file marked as a binary type.
+svn:mime-type = application/octet-stream
+Index: ../trunk-jpl/test/Archives/Archive812.arch
+===================================================================
+Cannot display: file marked as a binary type.
+svn:mime-type = application/octet-stream
Index: /issm/oecreview/Archive/27230-27343/ISSM-27276-27277.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27276-27277.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27276-27277.diff	(revision 27344)
@@ -0,0 +1,54 @@
+Index: ../trunk-jpl/src/m/contrib/morlighem/modeldata/interpBedmachineGreenland.m
+===================================================================
+--- ../trunk-jpl/src/m/contrib/morlighem/modeldata/interpBedmachineGreenland.m	(revision 27276)
++++ ../trunk-jpl/src/m/contrib/morlighem/modeldata/interpBedmachineGreenland.m	(revision 27277)
+@@ -44,7 +44,6 @@
+ 		['/totten_1/ModelData/Greenland/BedMachine/' basename '-' ncdate '.nc'],...
+ 		['/Users/larour/ModelData/BedMachine/' basename '-' ncdate '.nc'],...
+ 		['./' basename '-' ncdate '.nc'],...
+-		'/media/vincent/TOSH4TB/GeorgiaTech/DataSearch/BedMachine/BedMachineGreenland-2021-04-20.nc',...
+ 		};
+ 
+ 	found = 0;
+@@ -89,11 +88,9 @@
+ disp(['       -- Interpolation method: ' method]);
+ if strcmp(string,'mask') | strcmp(string,'source'),
+ 	%Need nearest neighbor to avoid interpolation between 0 and 2
+-	%output = InterpFromGrid(xdata,ydata,data,double(X),double(Y),'nearest');
+-	output = InterpFromGridToMesh(xdata,flipud(ydata),flipud(data),double(X),double(Y),NaN); %VV
++	output = InterpFromGrid(xdata,ydata,data,double(X),double(Y),'nearest');
+ else
+-	%output = InterpFromGrid(xdata,ydata,data,double(X),double(Y));
+-	output = InterpFromGridToMesh(xdata,flipud(ydata),flipud(data),double(X),double(Y),NaN); %VV
++	output = InterpFromGrid(xdata,ydata,data,double(X),double(Y));
+ end
+ 
+ end
+Index: ../trunk-jpl/src/m/contrib/morlighem/modeldata/interpSeaRISE.m
+===================================================================
+--- ../trunk-jpl/src/m/contrib/morlighem/modeldata/interpSeaRISE.m	(revision 27276)
++++ ../trunk-jpl/src/m/contrib/morlighem/modeldata/interpSeaRISE.m	(revision 27277)
+@@ -57,10 +57,6 @@
+ 		elseif hemisphere==-1,
+ 			searisenc='/totten_1/ModelData/SeaRISE/Antarctica_5km_dev1.0.nc';
+ 		end
+-   case {'vincentxps159500'}
+-		if hemisphere==1
+-			searisenc = '/media/vincent/TOSH4TB/GeorgiaTech/ISSM/fromSeroussi/GrIS04Feb2022/seariseData/Greenland_5km_dev1.2.nc';
+-		end
+ 	otherwise
+ 		error('hostname not supported yet');
+ end
+@@ -83,10 +79,8 @@
+ 
+ if verbose, disp(['   -- SeaRISE: interpolating ' string]); end
+ if strcmpi(string,'LandMask');
+-	%dataout = InterpFromGrid(xdata,ydata,data,xproj,yproj,'nearest');
+-	dataout = InterpFromGridToMesh(xdata,ydata,data,xproj,yproj,NaN); %VV
++	dataout = InterpFromGrid(xdata,ydata,data,xproj,yproj,'nearest');
+ else
+-	%dataout = InterpFromGrid(xdata,ydata,data,xproj,yproj);
+-	dataout = InterpFromGridToMesh(xdata,ydata,data,xproj,yproj,NaN); %VV
++	dataout = InterpFromGrid(xdata,ydata,data,xproj,yproj);
+ end
+ dataout = reshape(dataout,size(X,1),size(X,2));
Index: /issm/oecreview/Archive/27230-27343/ISSM-27277-27278.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27277-27278.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27277-27278.diff	(revision 27344)
@@ -0,0 +1,609 @@
+Index: ../trunk-jpl/src/c/analyses/LevelsetAnalysis.cpp
+===================================================================
+--- ../trunk-jpl/src/c/analyses/LevelsetAnalysis.cpp	(revision 27277)
++++ ../trunk-jpl/src/c/analyses/LevelsetAnalysis.cpp	(revision 27278)
+@@ -149,7 +149,7 @@
+ 			break;
+ 		case FrontalForcingsRignotEnum:
+          /*Retrieve thermal forcing only in the case of non-arma FrontalForcingsRignot*/
+-         iomodel->FetchDataToInput(inputs,elements,"md.frontalforcings.thermalforcing",FrontalForcingsThermalForcingEnum);
++         iomodel->FetchDataToInput(inputs,elements,"md.frontalforcings.thermalforcing",FrontalForcingsAndBasalforcingsThermalForcingEnum);
+          /* Do not break here, still retrieve basin_ID,subglacial_discharge, etc.*/
+       case FrontalForcingsRignotarmaEnum:
+          iomodel->FetchDataToInput(inputs,elements,"md.frontalforcings.basin_id",FrontalForcingsBasinIdEnum);
+Index: ../trunk-jpl/src/c/classes/Elements/Element.cpp
+===================================================================
+--- ../trunk-jpl/src/c/classes/Elements/Element.cpp	(revision 27277)
++++ ../trunk-jpl/src/c/classes/Elements/Element.cpp	(revision 27278)
+@@ -85,7 +85,7 @@
+          maenum_type    = ThermalforcingValuesMovingaverageEnum;
+          basinenum_type = FrontalForcingsBasinIdEnum;
+          noiseenum_type = ThermalforcingARMANoiseEnum;
+-         outenum_type   = FrontalForcingsThermalForcingEnum;
++         outenum_type   = FrontalForcingsAndBasalforcingsThermalForcingEnum;
+          break;
+ 		case(BasalforcingsDeepwaterMeltingRatearmaEnum):
+          arenum_type    = BasalforcingsDeepwaterMeltingRateValuesAutoregressionEnum;
+@@ -194,7 +194,7 @@
+          arenum_type    = ThermalforcingValuesAutoregressionEnum;
+          basinenum_type = FrontalForcingsBasinIdEnum;
+          noiseenum_type = ThermalforcingARMANoiseEnum;
+-         outenum_type   = FrontalForcingsThermalForcingEnum;
++         outenum_type   = FrontalForcingsAndBasalforcingsThermalForcingEnum;
+          break;
+ 		case(BasalforcingsDeepwaterMeltingRatearmaEnum):
+          arenum_type    = BasalforcingsDeepwaterMeltingRateValuesAutoregressionEnum;
+@@ -2776,11 +2776,13 @@
+ }/*}}}*/
+ void       Element::BeckmannGoosseFloatingiceMeltingRate(){/*{{{*/
+ 
+-	int numvertices      = this->GetNumberOfVertices();
+-	IssmDouble T_f,ocean_heat_flux;
+-	IssmDouble rho_water    = this->FindParam(MaterialsRhoSeawaterEnum);
+-	IssmDouble rho_ice      = this->FindParam(MaterialsRhoIceEnum);
+-	IssmDouble latentheat   = this->FindParam(MaterialsLatentheatEnum);
++	bool isthermalforcing;       
++	int numvertices                 = this->GetNumberOfVertices();
++	IssmDouble T_fr,T_forcing,ocean_heat_flux;
++	/*Material properties*/
++	IssmDouble rho_water            = this->FindParam(MaterialsRhoSeawaterEnum);
++	IssmDouble rho_ice              = this->FindParam(MaterialsRhoIceEnum);
++	IssmDouble latentheat           = this->FindParam(MaterialsLatentheatEnum);
+ 	IssmDouble mixed_layer_capacity = this->FindParam(MaterialsMixedLayerCapacityEnum);
+ 	IssmDouble thermal_exchange_vel = this->FindParam(MaterialsThermalExchangeVelocityEnum);
+ 
+@@ -2788,26 +2790,38 @@
+ 	IssmDouble values[MAXVERTICES];
+ 	IssmDouble oceansalinity [MAXVERTICES];
+ 	IssmDouble oceantemp[MAXVERTICES];
++	IssmDouble oceanthermalforcing[MAXVERTICES];
+ 	IssmDouble meltratefactor[MAXVERTICES];
+ 
++	/*Determine if we use temperature-and-salinity or thermal forcing*/
++	this->parameters->FindParam(&isthermalforcing,BasalforcingsIsThermalForcingEnum);
++	/*Retrieve Inputs*/
+ 	this->GetInputListOnVertices(base,BaseEnum);
+-	this->GetInputListOnVertices(oceansalinity,BasalforcingsOceanSalinityEnum);
+-	this->GetInputListOnVertices(oceantemp,BasalforcingsOceanTempEnum);
+ 	this->GetInputListOnVertices(meltratefactor,BasalforcingsMeltrateFactorEnum);
++	if(isthermalforcing==false){
++		this->GetInputListOnVertices(oceansalinity,BasalforcingsOceanSalinityEnum);
++		this->GetInputListOnVertices(oceantemp,BasalforcingsOceanTempEnum);
++	}
++	else{
++		this->GetInputListOnVertices(oceanthermalforcing,FrontalForcingsAndBasalforcingsThermalForcingEnum);
++	}
+ 
+ 	Gauss* gauss=this->NewGauss();
+ 	for(int i=0;i<numvertices;i++){
+-		T_f=(0.0939 - 0.057 * oceansalinity[i] + 7.64e-4 * base[i]); //degC
+-
+-		// compute ocean_heat_flux according to beckmann_goosse2003
+-		// positive, if T_oc > T_ice ==> heat flux FROM ocean TO ice
+-		ocean_heat_flux = meltratefactor[i] * rho_water * mixed_layer_capacity * thermal_exchange_vel * (oceantemp[i] - T_f); // in W/m^2
+-
+-		// shelfbmassflux is positive if ice is freezing on; here it is always negative:
+-		// same sign as ocean_heat_flux (positive if massflux FROM ice TO ocean)
+-		values[i] = ocean_heat_flux / (latentheat * rho_ice); // m s-1
++		/*Case of temperature-and-salinity inputs*/
++		if(isthermalforcing==false){
++			T_fr       = (0.0939-0.057*oceansalinity[i]+7.64e-4*base[i]); //freezing point [degC]
++			T_forcing  = oceantemp[i]-T_fr; //thermal forcing [K]
++		}
++		/*Case of thermal forcing input*/
++		else{
++			T_forcing  = oceanthermalforcing[i]; 
++		}
++		/*Compute heat flux from (Beckmann and Goosse, 2003) (>0 means heat flux from ocean to ice)*/
++		ocean_heat_flux = meltratefactor[i]*rho_water*mixed_layer_capacity*thermal_exchange_vel*T_forcing; // ocean-to-ice heat flux [W/m^2]
++		/*Save melt values [m/s]*/
++		values[i]       = ocean_heat_flux/(latentheat*rho_ice);
+ 	}
+-
+ 	this->AddInput(BasalforcingsFloatingiceMeltingRateEnum,values,P1Enum);
+ 	delete gauss;
+ }/*}}}*/
+@@ -3798,7 +3812,7 @@
+ 	this->GetInputValue(&basinid,FrontalForcingsBasinIdEnum);
+ 	Input* bed_input = this->GetInput(BedEnum);                     _assert_(bed_input);
+    Input* qsg_input = this->GetInput(FrontalForcingsSubglacialDischargeEnum);     _assert_(qsg_input);
+-   Input* TF_input  = this->GetInput(FrontalForcingsThermalForcingEnum);          _assert_(TF_input);
++   Input* TF_input  = this->GetInput(FrontalForcingsAndBasalforcingsThermalForcingEnum);          _assert_(TF_input);
+ 
+ 	this->FindParam(&yts, ConstantsYtsEnum);
+    this->parameters->FindParam(&numbasins,FrontalForcingsNumberofBasinsEnum);
+Index: ../trunk-jpl/src/c/modules/ModelProcessorx/CreateParameters.cpp
+===================================================================
+--- ../trunk-jpl/src/c/modules/ModelProcessorx/CreateParameters.cpp	(revision 27277)
++++ ../trunk-jpl/src/c/modules/ModelProcessorx/CreateParameters.cpp	(revision 27278)
+@@ -252,6 +252,7 @@
+ 			xDelete<IssmDouble>(transparam);
+ 			break;
+ 		case BeckmannGoosseFloatingMeltRateEnum:
++			parameters->AddObject(iomodel->CopyConstantObject("md.basalforcings.isthermalforcing",BasalforcingsIsThermalForcingEnum));
+ 			break;
+ 		case LinearFloatingMeltRatearmaEnum:
+ 			/*Add parameters that are not in standard nbvertices format*/
+Index: ../trunk-jpl/src/c/shared/Enum/Enum.vim
+===================================================================
+--- ../trunk-jpl/src/c/shared/Enum/Enum.vim	(revision 27277)
++++ ../trunk-jpl/src/c/shared/Enum/Enum.vim	(revision 27278)
+@@ -91,6 +91,7 @@
+ syn keyword cConstant BasalforcingsNusseltEnum
+ syn keyword cConstant BasalforcingsARMAarlagcoefsEnum
+ syn keyword cConstant BasalforcingsARMAmalagcoefsEnum
++syn keyword cConstant BasalforcingsIsThermalForcingEnum
+ syn keyword cConstant BasalforcingsPicoAverageOverturningEnum
+ syn keyword cConstant BasalforcingsPicoAverageSalinityEnum
+ syn keyword cConstant BasalforcingsPicoAverageTemperatureEnum
+@@ -774,7 +775,7 @@
+ syn keyword cConstant FrictionfEnum
+ syn keyword cConstant FrontalForcingsBasinIdEnum
+ syn keyword cConstant FrontalForcingsSubglacialDischargeEnum
+-syn keyword cConstant FrontalForcingsThermalForcingEnum
++syn keyword cConstant FrontalForcingsAndBasalforcingsThermalForcingEnum
+ syn keyword cConstant GeometryHydrostaticRatioEnum
+ syn keyword cConstant NGiaEnum
+ syn keyword cConstant NGiaRateEnum
+Index: ../trunk-jpl/src/c/shared/Enum/EnumDefinitions.h
+===================================================================
+--- ../trunk-jpl/src/c/shared/Enum/EnumDefinitions.h	(revision 27277)
++++ ../trunk-jpl/src/c/shared/Enum/EnumDefinitions.h	(revision 27278)
+@@ -85,6 +85,7 @@
+ 	BasalforcingsNusseltEnum,
+ 	BasalforcingsARMAarlagcoefsEnum,
+ 	BasalforcingsARMAmalagcoefsEnum,
++	BasalforcingsIsThermalForcingEnum,
+ 	BasalforcingsPicoAverageOverturningEnum,
+ 	BasalforcingsPicoAverageSalinityEnum,
+ 	BasalforcingsPicoAverageTemperatureEnum,
+@@ -770,7 +771,7 @@
+ 	FrictionfEnum,
+ 	FrontalForcingsBasinIdEnum,
+ 	FrontalForcingsSubglacialDischargeEnum,
+-	FrontalForcingsThermalForcingEnum,
++	FrontalForcingsAndBasalforcingsThermalForcingEnum,
+ 	GeometryHydrostaticRatioEnum,
+ 	NGiaEnum,
+ 	NGiaRateEnum,
+Index: ../trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp
+===================================================================
+--- ../trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp	(revision 27277)
++++ ../trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp	(revision 27278)
+@@ -93,6 +93,7 @@
+ 		case BasalforcingsNusseltEnum : return "BasalforcingsNusselt";
+ 		case BasalforcingsARMAarlagcoefsEnum : return "BasalforcingsARMAarlagcoefs";
+ 		case BasalforcingsARMAmalagcoefsEnum : return "BasalforcingsARMAmalagcoefs";
++		case BasalforcingsIsThermalForcingEnum : return "BasalforcingsIsThermalForcing";
+ 		case BasalforcingsPicoAverageOverturningEnum : return "BasalforcingsPicoAverageOverturning";
+ 		case BasalforcingsPicoAverageSalinityEnum : return "BasalforcingsPicoAverageSalinity";
+ 		case BasalforcingsPicoAverageTemperatureEnum : return "BasalforcingsPicoAverageTemperature";
+@@ -776,7 +777,7 @@
+ 		case FrictionfEnum : return "Frictionf";
+ 		case FrontalForcingsBasinIdEnum : return "FrontalForcingsBasinId";
+ 		case FrontalForcingsSubglacialDischargeEnum : return "FrontalForcingsSubglacialDischarge";
+-		case FrontalForcingsThermalForcingEnum : return "FrontalForcingsThermalForcing";
++		case FrontalForcingsAndBasalforcingsThermalForcingEnum : return "FrontalForcingsAndBasalforcingsThermalForcing";
+ 		case GeometryHydrostaticRatioEnum : return "GeometryHydrostaticRatio";
+ 		case NGiaEnum : return "NGia";
+ 		case NGiaRateEnum : return "NGiaRate";
+Index: ../trunk-jpl/src/c/shared/Enum/Enumjl.vim
+===================================================================
+--- ../trunk-jpl/src/c/shared/Enum/Enumjl.vim	(revision 27277)
++++ ../trunk-jpl/src/c/shared/Enum/Enumjl.vim	(revision 27278)
+@@ -84,6 +84,7 @@
+ syn keyword juliaConstC BasalforcingsNusseltEnum
+ syn keyword juliaConstC BasalforcingsARMAarlagcoefsEnum
+ syn keyword juliaConstC BasalforcingsARMAmalagcoefsEnum
++syn keyword juliaConstC BasalforcingsIsThermalForcingEnum
+ syn keyword juliaConstC BasalforcingsPicoAverageOverturningEnum
+ syn keyword juliaConstC BasalforcingsPicoAverageSalinityEnum
+ syn keyword juliaConstC BasalforcingsPicoAverageTemperatureEnum
+@@ -767,7 +768,7 @@
+ syn keyword juliaConstC FrictionfEnum
+ syn keyword juliaConstC FrontalForcingsBasinIdEnum
+ syn keyword juliaConstC FrontalForcingsSubglacialDischargeEnum
+-syn keyword juliaConstC FrontalForcingsThermalForcingEnum
++syn keyword juliaConstC FrontalForcingsAndBasalforcingsThermalForcingEnum
+ syn keyword juliaConstC GeometryHydrostaticRatioEnum
+ syn keyword juliaConstC NGiaEnum
+ syn keyword juliaConstC NGiaRateEnum
+Index: ../trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp
+===================================================================
+--- ../trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp	(revision 27277)
++++ ../trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp	(revision 27278)
+@@ -93,6 +93,7 @@
+ 	      else if (strcmp(name,"BasalforcingsNusselt")==0) return BasalforcingsNusseltEnum;
+ 	      else if (strcmp(name,"BasalforcingsARMAarlagcoefs")==0) return BasalforcingsARMAarlagcoefsEnum;
+ 	      else if (strcmp(name,"BasalforcingsARMAmalagcoefs")==0) return BasalforcingsARMAmalagcoefsEnum;
++	      else if (strcmp(name,"BasalforcingsIsThermalForcing")==0) return BasalforcingsIsThermalForcingEnum;
+ 	      else if (strcmp(name,"BasalforcingsPicoAverageOverturning")==0) return BasalforcingsPicoAverageOverturningEnum;
+ 	      else if (strcmp(name,"BasalforcingsPicoAverageSalinity")==0) return BasalforcingsPicoAverageSalinityEnum;
+ 	      else if (strcmp(name,"BasalforcingsPicoAverageTemperature")==0) return BasalforcingsPicoAverageTemperatureEnum;
+@@ -135,11 +136,11 @@
+ 	      else if (strcmp(name,"ConstantsReferencetemperature")==0) return ConstantsReferencetemperatureEnum;
+ 	      else if (strcmp(name,"ConstantsYts")==0) return ConstantsYtsEnum;
+ 	      else if (strcmp(name,"ControlInputSizeM")==0) return ControlInputSizeMEnum;
+-	      else if (strcmp(name,"ControlInputSizeN")==0) return ControlInputSizeNEnum;
+          else stage=2;
+    }
+    if(stage==2){
+-	      if (strcmp(name,"ControlInputInterpolation")==0) return ControlInputInterpolationEnum;
++	      if (strcmp(name,"ControlInputSizeN")==0) return ControlInputSizeNEnum;
++	      else if (strcmp(name,"ControlInputInterpolation")==0) return ControlInputInterpolationEnum;
+ 	      else if (strcmp(name,"CumBslc")==0) return CumBslcEnum;
+ 	      else if (strcmp(name,"CumBslcIce")==0) return CumBslcIceEnum;
+ 	      else if (strcmp(name,"CumBslcHydro")==0) return CumBslcHydroEnum;
+@@ -258,11 +259,11 @@
+ 	      else if (strcmp(name,"HydrologyStepAdapt")==0) return HydrologyStepAdaptEnum;
+ 	      else if (strcmp(name,"HydrologydcTransferFlag")==0) return HydrologydcTransferFlagEnum;
+ 	      else if (strcmp(name,"HydrologydcUnconfinedFlag")==0) return HydrologydcUnconfinedFlagEnum;
+-	      else if (strcmp(name,"HydrologyshreveStabilization")==0) return HydrologyshreveStabilizationEnum;
+          else stage=3;
+    }
+    if(stage==3){
+-	      if (strcmp(name,"IcecapToEarthComm")==0) return IcecapToEarthCommEnum;
++	      if (strcmp(name,"HydrologyshreveStabilization")==0) return HydrologyshreveStabilizationEnum;
++	      else if (strcmp(name,"IcecapToEarthComm")==0) return IcecapToEarthCommEnum;
+ 	      else if (strcmp(name,"Index")==0) return IndexEnum;
+ 	      else if (strcmp(name,"InputFileName")==0) return InputFileNameEnum;
+ 	      else if (strcmp(name,"DirectoryName")==0) return DirectoryNameEnum;
+@@ -381,11 +382,11 @@
+ 	      else if (strcmp(name,"QmuVariableDescriptors")==0) return QmuVariableDescriptorsEnum;
+ 	      else if (strcmp(name,"QmuVariablePartitions")==0) return QmuVariablePartitionsEnum;
+ 	      else if (strcmp(name,"QmuVariablePartitionsNpart")==0) return QmuVariablePartitionsNpartEnum;
+-	      else if (strcmp(name,"QmuVariablePartitionsNt")==0) return QmuVariablePartitionsNtEnum;
+          else stage=4;
+    }
+    if(stage==4){
+-	      if (strcmp(name,"QmuResponsePartitions")==0) return QmuResponsePartitionsEnum;
++	      if (strcmp(name,"QmuVariablePartitionsNt")==0) return QmuVariablePartitionsNtEnum;
++	      else if (strcmp(name,"QmuResponsePartitions")==0) return QmuResponsePartitionsEnum;
+ 	      else if (strcmp(name,"QmuResponsePartitionsNpart")==0) return QmuResponsePartitionsNpartEnum;
+ 	      else if (strcmp(name,"QmuStatistics")==0) return QmuStatisticsEnum;
+ 	      else if (strcmp(name,"QmuNumstatistics")==0) return QmuNumstatisticsEnum;
+@@ -504,11 +505,11 @@
+ 	      else if (strcmp(name,"SmbCldFrac")==0) return SmbCldFracEnum;
+ 	      else if (strcmp(name,"SmbDelta18o")==0) return SmbDelta18oEnum;
+ 	      else if (strcmp(name,"SmbDelta18oSurface")==0) return SmbDelta18oSurfaceEnum;
+-	      else if (strcmp(name,"SmbDenIdx")==0) return SmbDenIdxEnum;
+          else stage=5;
+    }
+    if(stage==5){
+-	      if (strcmp(name,"SmbDt")==0) return SmbDtEnum;
++	      if (strcmp(name,"SmbDenIdx")==0) return SmbDenIdxEnum;
++	      else if (strcmp(name,"SmbDt")==0) return SmbDtEnum;
+ 	      else if (strcmp(name,"Smb")==0) return SmbEnum;
+ 	      else if (strcmp(name,"SmbEIdx")==0) return SmbEIdxEnum;
+ 	      else if (strcmp(name,"SmbF")==0) return SmbFEnum;
+@@ -627,11 +628,11 @@
+ 	      else if (strcmp(name,"Xxe")==0) return XxeEnum;
+ 	      else if (strcmp(name,"Yye")==0) return YyeEnum;
+ 	      else if (strcmp(name,"Zze")==0) return ZzeEnum;
+-	      else if (strcmp(name,"Areae")==0) return AreaeEnum;
+          else stage=6;
+    }
+    if(stage==6){
+-	      if (strcmp(name,"WorldComm")==0) return WorldCommEnum;
++	      if (strcmp(name,"Areae")==0) return AreaeEnum;
++	      else if (strcmp(name,"WorldComm")==0) return WorldCommEnum;
+ 	      else if (strcmp(name,"ParametersEND")==0) return ParametersENDEnum;
+ 	      else if (strcmp(name,"InputsSTART")==0) return InputsSTARTEnum;
+ 	      else if (strcmp(name,"AccumulatedDeltaBottomPressure")==0) return AccumulatedDeltaBottomPressureEnum;
+@@ -750,11 +751,11 @@
+ 	      else if (strcmp(name,"DrivingStressX")==0) return DrivingStressXEnum;
+ 	      else if (strcmp(name,"DrivingStressY")==0) return DrivingStressYEnum;
+ 	      else if (strcmp(name,"Dummy")==0) return DummyEnum;
+-	      else if (strcmp(name,"EffectivePressure")==0) return EffectivePressureEnum;
+          else stage=7;
+    }
+    if(stage==7){
+-	      if (strcmp(name,"EffectivePressureSubstep")==0) return EffectivePressureSubstepEnum;
++	      if (strcmp(name,"EffectivePressure")==0) return EffectivePressureEnum;
++	      else if (strcmp(name,"EffectivePressureSubstep")==0) return EffectivePressureSubstepEnum;
+ 	      else if (strcmp(name,"EffectivePressureTransient")==0) return EffectivePressureTransientEnum;
+ 	      else if (strcmp(name,"Enthalpy")==0) return EnthalpyEnum;
+ 	      else if (strcmp(name,"EnthalpyPicard")==0) return EnthalpyPicardEnum;
+@@ -794,7 +795,7 @@
+ 	      else if (strcmp(name,"Frictionf")==0) return FrictionfEnum;
+ 	      else if (strcmp(name,"FrontalForcingsBasinId")==0) return FrontalForcingsBasinIdEnum;
+ 	      else if (strcmp(name,"FrontalForcingsSubglacialDischarge")==0) return FrontalForcingsSubglacialDischargeEnum;
+-	      else if (strcmp(name,"FrontalForcingsThermalForcing")==0) return FrontalForcingsThermalForcingEnum;
++	      else if (strcmp(name,"FrontalForcingsAndBasalforcingsThermalForcing")==0) return FrontalForcingsAndBasalforcingsThermalForcingEnum;
+ 	      else if (strcmp(name,"GeometryHydrostaticRatio")==0) return GeometryHydrostaticRatioEnum;
+ 	      else if (strcmp(name,"NGia")==0) return NGiaEnum;
+ 	      else if (strcmp(name,"NGiaRate")==0) return NGiaRateEnum;
+@@ -873,11 +874,11 @@
+ 	      else if (strcmp(name,"Misfit")==0) return MisfitEnum;
+ 	      else if (strcmp(name,"MovingFrontalVx")==0) return MovingFrontalVxEnum;
+ 	      else if (strcmp(name,"MovingFrontalVy")==0) return MovingFrontalVyEnum;
+-	      else if (strcmp(name,"Neumannflux")==0) return NeumannfluxEnum;
+          else stage=8;
+    }
+    if(stage==8){
+-	      if (strcmp(name,"NewDamage")==0) return NewDamageEnum;
++	      if (strcmp(name,"Neumannflux")==0) return NeumannfluxEnum;
++	      else if (strcmp(name,"NewDamage")==0) return NewDamageEnum;
+ 	      else if (strcmp(name,"Node")==0) return NodeEnum;
+ 	      else if (strcmp(name,"OmegaAbsGradient")==0) return OmegaAbsGradientEnum;
+ 	      else if (strcmp(name,"OceantransportSpcbottompressure")==0) return OceantransportSpcbottompressureEnum;
+@@ -996,11 +997,11 @@
+ 	      else if (strcmp(name,"SmbCciceValue")==0) return SmbCciceValueEnum;
+ 	      else if (strcmp(name,"SmbCotValue")==0) return SmbCotValueEnum;
+ 	      else if (strcmp(name,"SmbD")==0) return SmbDEnum;
+-	      else if (strcmp(name,"SmbDailyairdensity")==0) return SmbDailyairdensityEnum;
+          else stage=9;
+    }
+    if(stage==9){
+-	      if (strcmp(name,"SmbDailyairhumidity")==0) return SmbDailyairhumidityEnum;
++	      if (strcmp(name,"SmbDailyairdensity")==0) return SmbDailyairdensityEnum;
++	      else if (strcmp(name,"SmbDailyairhumidity")==0) return SmbDailyairhumidityEnum;
+ 	      else if (strcmp(name,"SmbDailydlradiation")==0) return SmbDailydlradiationEnum;
+ 	      else if (strcmp(name,"SmbDailydsradiation")==0) return SmbDailydsradiationEnum;
+ 	      else if (strcmp(name,"SmbDailypressure")==0) return SmbDailypressureEnum;
+@@ -1119,11 +1120,11 @@
+ 	      else if (strcmp(name,"Surface")==0) return SurfaceEnum;
+ 	      else if (strcmp(name,"SurfaceOld")==0) return SurfaceOldEnum;
+ 	      else if (strcmp(name,"SurfaceLogVelMisfit")==0) return SurfaceLogVelMisfitEnum;
+-	      else if (strcmp(name,"SurfaceLogVxVyMisfit")==0) return SurfaceLogVxVyMisfitEnum;
+          else stage=10;
+    }
+    if(stage==10){
+-	      if (strcmp(name,"SurfaceObservation")==0) return SurfaceObservationEnum;
++	      if (strcmp(name,"SurfaceLogVxVyMisfit")==0) return SurfaceLogVxVyMisfitEnum;
++	      else if (strcmp(name,"SurfaceObservation")==0) return SurfaceObservationEnum;
+ 	      else if (strcmp(name,"SurfaceRelVelMisfit")==0) return SurfaceRelVelMisfitEnum;
+ 	      else if (strcmp(name,"SurfaceSlopeX")==0) return SurfaceSlopeXEnum;
+ 	      else if (strcmp(name,"SurfaceSlopeY")==0) return SurfaceSlopeYEnum;
+@@ -1242,11 +1243,11 @@
+ 	      else if (strcmp(name,"Outputdefinition69")==0) return Outputdefinition69Enum;
+ 	      else if (strcmp(name,"Outputdefinition6")==0) return Outputdefinition6Enum;
+ 	      else if (strcmp(name,"Outputdefinition70")==0) return Outputdefinition70Enum;
+-	      else if (strcmp(name,"Outputdefinition71")==0) return Outputdefinition71Enum;
+          else stage=11;
+    }
+    if(stage==11){
+-	      if (strcmp(name,"Outputdefinition72")==0) return Outputdefinition72Enum;
++	      if (strcmp(name,"Outputdefinition71")==0) return Outputdefinition71Enum;
++	      else if (strcmp(name,"Outputdefinition72")==0) return Outputdefinition72Enum;
+ 	      else if (strcmp(name,"Outputdefinition73")==0) return Outputdefinition73Enum;
+ 	      else if (strcmp(name,"Outputdefinition74")==0) return Outputdefinition74Enum;
+ 	      else if (strcmp(name,"Outputdefinition75")==0) return Outputdefinition75Enum;
+@@ -1365,11 +1366,11 @@
+ 	      else if (strcmp(name,"ElementHook")==0) return ElementHookEnum;
+ 	      else if (strcmp(name,"ElementSId")==0) return ElementSIdEnum;
+ 	      else if (strcmp(name,"EnthalpyAnalysis")==0) return EnthalpyAnalysisEnum;
+-	      else if (strcmp(name,"EsaAnalysis")==0) return EsaAnalysisEnum;
+          else stage=12;
+    }
+    if(stage==12){
+-	      if (strcmp(name,"EsaSolution")==0) return EsaSolutionEnum;
++	      if (strcmp(name,"EsaAnalysis")==0) return EsaAnalysisEnum;
++	      else if (strcmp(name,"EsaSolution")==0) return EsaSolutionEnum;
+ 	      else if (strcmp(name,"EsaTransitions")==0) return EsaTransitionsEnum;
+ 	      else if (strcmp(name,"ExternalResult")==0) return ExternalResultEnum;
+ 	      else if (strcmp(name,"ExtrapolationAnalysis")==0) return ExtrapolationAnalysisEnum;
+@@ -1488,11 +1489,11 @@
+ 	      else if (strcmp(name,"Massfluxatgate")==0) return MassfluxatgateEnum;
+ 	      else if (strcmp(name,"MasstransportAnalysis")==0) return MasstransportAnalysisEnum;
+ 	      else if (strcmp(name,"MasstransportSolution")==0) return MasstransportSolutionEnum;
+-	      else if (strcmp(name,"Matdamageice")==0) return MatdamageiceEnum;
+          else stage=13;
+    }
+    if(stage==13){
+-	      if (strcmp(name,"Matenhancedice")==0) return MatenhancediceEnum;
++	      if (strcmp(name,"Matdamageice")==0) return MatdamageiceEnum;
++	      else if (strcmp(name,"Matenhancedice")==0) return MatenhancediceEnum;
+ 	      else if (strcmp(name,"Materials")==0) return MaterialsEnum;
+ 	      else if (strcmp(name,"Matestar")==0) return MatestarEnum;
+ 	      else if (strcmp(name,"Matice")==0) return MaticeEnum;
+@@ -1611,11 +1612,11 @@
+ 	      else if (strcmp(name,"SoftMigration")==0) return SoftMigrationEnum;
+ 	      else if (strcmp(name,"SpatialLinearFloatingMeltRate")==0) return SpatialLinearFloatingMeltRateEnum;
+ 	      else if (strcmp(name,"SpcDynamic")==0) return SpcDynamicEnum;
+-	      else if (strcmp(name,"SpcStatic")==0) return SpcStaticEnum;
+          else stage=14;
+    }
+    if(stage==14){
+-	      if (strcmp(name,"SpcTransient")==0) return SpcTransientEnum;
++	      if (strcmp(name,"SpcStatic")==0) return SpcStaticEnum;
++	      else if (strcmp(name,"SpcTransient")==0) return SpcTransientEnum;
+ 	      else if (strcmp(name,"Sset")==0) return SsetEnum;
+ 	      else if (strcmp(name,"StatisticsSolution")==0) return StatisticsSolutionEnum;
+ 	      else if (strcmp(name,"SteadystateSolution")==0) return SteadystateSolutionEnum;
+Index: ../trunk-jpl/src/m/classes/basalforcingsbeckmanngoosse.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/basalforcingsbeckmanngoosse.m	(revision 27277)
++++ ../trunk-jpl/src/m/classes/basalforcingsbeckmanngoosse.m	(revision 27278)
+@@ -10,6 +10,8 @@
+ 		meltrate_factor           = 0.;
+ 		ocean_temp                = 0.;
+ 		ocean_salinity            = NaN;
++		ocean_thermalforcing      = NaN;
++		isthermalforcing          = 0;
+ 	end
+ 	methods
+ 		function createxml(self,fid) % {{{
+@@ -19,6 +21,7 @@
+ 			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="melting_rate" type="',class(self.melting_rate),'" default="',num2str(self.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 ="ocean_temp" type="',class(self.ocean_temp),'" default="',num2str(self.ocean_temp),'">','     <section name="basalforcings" />','     <help> ocean_temp [degC] </help>','</parameter>');
+ 		        fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="ocean_salinity" type="',class(self.ocean_salinity),'" default="',num2str(self.ocean_salinity),'">','     <section name="basalforcings" />','     <help> ocean_salinity [psu] </help>','</parameter>');
++		        fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="ocean_thermalforcing" type="',class(self.ocean_thermalforcing),'" default="',num2str(self.ocean_thermalforcing),'">','     <section name="basalforcings" />','     <help> ocean_thermalforcing [K] </help>','</parameter>');
+         	end % }}}
+ 		function self = extrude(self,md) % {{{
+ 			self.groundedice_melting_rate=project3d(md,'vector',self.groundedice_melting_rate,'type','node','layer',1); 
+@@ -59,17 +62,44 @@
+ 		end % }}}
+ 		function md = checkconsistency(self,md,solution,analyses) % {{{
+ 
++			if(self.isthermalforcing==0)
++				if(any(~isnan(self.ocean_thermalforcing)))
++					error('basalforcingsbeckmanngoosse has isthermalforcing=0 but has specified entries for ocean_thermalforcing (should be unused)');
++				end
++			elseif(self.isthermalforcing==1)
++				if(any(self.ocean_temp~=0) || any(~isnan(self.ocean_salinity)))
++					error('basalforcingsbeckmanngoosse has isthermalforcing=1 but has specified entries for ocean_temp or ocean_salinity (should be unused)');
++				end
++				if(strcmp(class(md.frontalforcings),'frontalforcingsrignot') && ~isequal(md.frontalforcings.thermalforcing,self.ocean_thermalforcing))
++					error('basalforcing.ocean_thermalforcing is not consistent with frontalforcings.thermalforcing')
++				end
++				if(strcmp(class(md.frontalforcings),'frontalforcingsrignotarma') && any(~isnan(self.ocean_thermalforcing)))
++					error('basalforcings has specified entries for ocean_thermalforcing, but frontalforcingsrignotarma already calculates thermalforcing internally')
++				end
++			end
++
++
+ 			if ismember('MasstransportAnalysis',analyses) & ~(solution=='TransientSolution' & md.transient.ismasstransport==0),
+ 				md = checkfield(md,'fieldname','basalforcings.groundedice_melting_rate','NaN',1,'Inf',1,'timeseries',1);
+-				md = checkfield(md,'fieldname','basalforcings.ocean_temp','NaN',1,'Inf',1,'timeseries',1);
+-				md = checkfield(md,'fieldname','basalforcings.ocean_salinity','NaN',1,'Inf',1,'timeseries',1);	
+ 				md = checkfield(md,'fieldname','basalforcings.meltrate_factor','>=',0,'universal',1,'NaN',1,'Inf',1);
++				md = checkfield(md,'fieldname','basalforcings.isthermalforcing','values',[0 1]);
++				if(self.isthermalforcing==0)
++					md = checkfield(md,'fieldname','basalforcings.ocean_temp','NaN',1,'Inf',1,'timeseries',1);
++					md = checkfield(md,'fieldname','basalforcings.ocean_salinity','NaN',1,'Inf',1,'timeseries',1);	
++				elseif(self.isthermalforcing==1 && ~strcmp(class(md.frontalforcings),'frontalforcingsrignotarma'))
++					md = checkfield(md,'fieldname','basalforcings.ocean_thermalforcing','NaN',1,'Inf',1,'timeseries',1);	
++				end
+ 			end
+ 			if ismember('BalancethicknessAnalysis',analyses),
+ 				md = checkfield(md,'fieldname','basalforcings.groundedice_melting_rate','NaN',1,'Inf',1,'size',[md.mesh.numberofvertices 1]);
+-				md = checkfield(md,'fieldname','basalforcings.ocean_temp','NaN',1,'Inf',1,'timeseries',1);
+-				md = checkfield(md,'fieldname','basalforcings.ocean_salinity','NaN',1,'Inf',1,'timeseries',1);
+ 				md = checkfield(md,'fieldname','basalforcings.meltrate_factor','>=',0,'universal',1,'NaN',1,'Inf',1);
++				md = checkfield(md,'fieldname','basalforcings.isthermalforcing','values',[0 1]);
++				if(self.isthermalforcing==0)
++					md = checkfield(md,'fieldname','basalforcings.ocean_temp','NaN',1,'Inf',1,'timeseries',1);
++					md = checkfield(md,'fieldname','basalforcings.ocean_salinity','NaN',1,'Inf',1,'timeseries',1);	
++				elseif(self.isthermalforcing==1 && ~strcmp(class(md.frontalforcings),'frontalforcingsrignotarma'))
++					md = checkfield(md,'fieldname','basalforcings.ocean_thermalforcing','NaN',1,'Inf',1,'timeseries',1);	
++				end
+ 			end
+ 			if ismember('ThermalAnalysis',analyses) & ~(solution=='TransientSolution' & md.transient.isthermal==0),
+ 				md = checkfield(md,'fieldname','basalforcings.groundedice_melting_rate','NaN',1,'Inf',1,'timeseries',1);
+@@ -83,8 +113,10 @@
+ 			fielddisplay(self,'groundedice_melting_rate','basal melting rate (positive if melting) (m/yr)');
+ 			fielddisplay(self,'geothermalflux','geothermal heat flux (W/m^2)');
+ 			fielddisplay(self,'meltrate_factor','Melt-rate rate factor');
++			fielddisplay(self,'isthermalforcing','whether to use ocean_temp and ocean_salinity (0) or ocean_thermalforcing (1) (default:0)');
+ 			fielddisplay(self,'ocean_temp','ocean temperature (degC)');
+-			fielddisplay(self,'ocean_salinity','ocean ocean_salinity (psu)');
++			fielddisplay(self,'ocean_salinity','ocean salinity (psu)');
++			fielddisplay(self,'ocean_thermalforcing','ocean thermalforcing (K)');
+ 
+ 		end % }}}
+ 		function marshall(self,prefix,md,fid) % {{{
+@@ -98,13 +130,16 @@
+ 
+ 
+ 			WriteData(fid,prefix,'name','md.basalforcings.model','data',8,'format','Integer');
+-			WriteData(fid,prefix,'data',floatingice_melting_rate,'format','DoubleMat','name','md.basalforcings.floatingice_melting_rate','mattype',1,'scale',1./yts,'timeserieslength',md.mesh.numberofvertices+1)
+ 			WriteData(fid,prefix,'object',self,'fieldname','groundedice_melting_rate','format','DoubleMat','name','md.basalforcings.groundedice_melting_rate','mattype',1,'scale',1./yts,'timeserieslength',md.mesh.numberofvertices+1)
+ 			WriteData(fid,prefix,'object',self,'fieldname','geothermalflux','name','md.basalforcings.geothermalflux','format','DoubleMat','mattype',1,'timeserieslength',md.mesh.numberofvertices+1);
+ 			WriteData(fid,prefix,'object',self,'fieldname','meltrate_factor','format','DoubleMat','mattype',1,'name','md.basalforcings.meltrate_factor');
+-			WriteData(fid,prefix,'object',self,'fieldname','ocean_temp','format','DoubleMat','name','md.basalforcings.ocean_temp','mattype',1,'timeserieslength',md.mesh.numberofvertices+1);
+-			WriteData(fid,prefix,'object',self,'fieldname','ocean_salinity','format','DoubleMat','name','md.basalforcings.ocean_salinity','mattype',1,'timeserieslength',md.mesh.numberofvertices+1);
+-
++			WriteData(fid,prefix,'object',self,'fieldname','isthermalforcing','format','Boolean');
++			if(self.isthermalforcing==0)
++				WriteData(fid,prefix,'object',self,'fieldname','ocean_temp','format','DoubleMat','name','md.basalforcings.ocean_temp','mattype',1,'timeserieslength',md.mesh.numberofvertices+1);
++				WriteData(fid,prefix,'object',self,'fieldname','ocean_salinity','format','DoubleMat','name','md.basalforcings.ocean_salinity','mattype',1,'timeserieslength',md.mesh.numberofvertices+1);
++			elseif(self.isthermalforcing==1)
++				WriteData(fid,prefix,'object',self,'fieldname','ocean_thermalforcing','format','DoubleMat','name','md.basalforcings.ocean_thermalforcing','mattype',1,'timeserieslength',md.mesh.numberofvertices+1);
++			end
+ 		end % }}}
+ 	end
+ end
+Index: ../trunk-jpl/src/c/analyses/FreeSurfaceBaseAnalysis.cpp
+===================================================================
+--- ../trunk-jpl/src/c/analyses/FreeSurfaceBaseAnalysis.cpp	(revision 27277)
++++ ../trunk-jpl/src/c/analyses/FreeSurfaceBaseAnalysis.cpp	(revision 27278)
+@@ -124,9 +124,16 @@
+ 			iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.basin_id",BasalforcingsIsmip6BasinIdEnum);
+ 			break;
+ 		case BeckmannGoosseFloatingMeltRateEnum:
++			bool isthermalforcing;
++         iomodel->FindConstant(&isthermalforcing,"md.basalforcings.isthermalforcing");
+ 			iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.meltrate_factor",BasalforcingsMeltrateFactorEnum);
+-			iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.ocean_salinity",BasalforcingsOceanSalinityEnum);
+-			iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.ocean_temp",BasalforcingsOceanTempEnum);
++         if(isthermalforcing==0){
++            iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.ocean_salinity",BasalforcingsOceanSalinityEnum);
++            iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.ocean_temp",BasalforcingsOceanTempEnum);
++         }
++         else{
++            iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.ocean_thermalforcing",FrontalForcingsAndBasalforcingsThermalForcingEnum);
++         }
+ 			break;
+ 		default:
+ 			_error_("Basal forcing model "<<EnumToStringx(basalforcing_model)<<" not supported yet");
+Index: ../trunk-jpl/src/c/analyses/MasstransportAnalysis.cpp
+===================================================================
+--- ../trunk-jpl/src/c/analyses/MasstransportAnalysis.cpp	(revision 27277)
++++ ../trunk-jpl/src/c/analyses/MasstransportAnalysis.cpp	(revision 27278)
+@@ -214,9 +214,16 @@
+ 			}
+ 			break;
+ 		case BeckmannGoosseFloatingMeltRateEnum:
++			bool isthermalforcing;
++			iomodel->FindConstant(&isthermalforcing,"md.basalforcings.isthermalforcing");
+ 			iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.meltrate_factor",BasalforcingsMeltrateFactorEnum);
+-			iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.ocean_salinity",BasalforcingsOceanSalinityEnum);
+-			iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.ocean_temp",BasalforcingsOceanTempEnum);
++			if(isthermalforcing==0){
++				iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.ocean_salinity",BasalforcingsOceanSalinityEnum);
++				iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.ocean_temp",BasalforcingsOceanTempEnum);
++			}
++			else{
++				iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.ocean_thermalforcing",FrontalForcingsAndBasalforcingsThermalForcingEnum);
++			}
+ 			break;
+ 		case LinearFloatingMeltRatearmaEnum:
+ 			iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.basin_id",BasalforcingsLinearBasinIdEnum);
+Index: ../trunk-jpl/src/c/analyses/StressbalanceAnalysis.cpp
+===================================================================
+--- ../trunk-jpl/src/c/analyses/StressbalanceAnalysis.cpp	(revision 27277)
++++ ../trunk-jpl/src/c/analyses/StressbalanceAnalysis.cpp	(revision 27278)
+@@ -852,9 +852,16 @@
+ 				iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.basin_id",BasalforcingsIsmip6BasinIdEnum);
+ 				break;
+ 			case BeckmannGoosseFloatingMeltRateEnum:
+-				iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.basin_id",BasalforcingsIsmip6BasinIdEnum);
+-				iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.ocean_salinity",BasalforcingsOceanSalinityEnum);
+-				iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.ocean_temp",BasalforcingsOceanTempEnum);
++				bool isthermalforcing;
++				iomodel->FindConstant(&isthermalforcing,"md.basalforcings.isthermalforcing");
++      	   iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.meltrate_factor",BasalforcingsMeltrateFactorEnum);
++      	   if(isthermalforcing==0){
++      	      iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.ocean_salinity",BasalforcingsOceanSalinityEnum);
++      	      iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.ocean_temp",BasalforcingsOceanTempEnum);
++      	   }
++      	   else{
++      	      iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.ocean_thermalforcing",FrontalForcingsAndBasalforcingsThermalForcingEnum);
++      	   }
+ 				break;
+ 			default:
+ 				_error_("Basal forcing model "<<EnumToStringx(basalforcing_model)<<" not supported yet");
+Index: ../trunk-jpl/src/c/analyses/StressbalanceVerticalAnalysis.cpp
+===================================================================
+--- ../trunk-jpl/src/c/analyses/StressbalanceVerticalAnalysis.cpp	(revision 27277)
++++ ../trunk-jpl/src/c/analyses/StressbalanceVerticalAnalysis.cpp	(revision 27278)
+@@ -154,9 +154,16 @@
+ 			iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.basin_id",BasalforcingsIsmip6BasinIdEnum);
+ 			break;
+ 		case BeckmannGoosseFloatingMeltRateEnum:
++			bool isthermalforcing;
++         iomodel->FindConstant(&isthermalforcing,"md.basalforcings.isthermalforcing");
+ 			iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.meltrate_factor",BasalforcingsMeltrateFactorEnum);
+-			iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.ocean_salinity",BasalforcingsOceanSalinityEnum);
+-			iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.ocean_temp",BasalforcingsOceanTempEnum);
++         if(isthermalforcing==0){
++            iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.ocean_salinity",BasalforcingsOceanSalinityEnum);
++            iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.ocean_temp",BasalforcingsOceanTempEnum);
++         }
++         else{
++            iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.ocean_thermalforcing",FrontalForcingsAndBasalforcingsThermalForcingEnum);
++         }
+ 			break;
+ 		default:
+ 			_error_("Basal forcing model "<<EnumToStringx(basalforcing_model)<<" not supported yet");
Index: /issm/oecreview/Archive/27230-27343/ISSM-27278-27279.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27278-27279.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27278-27279.diff	(revision 27344)
@@ -0,0 +1,108 @@
+Index: ../trunk-jpl/src/c/analyses/FreeSurfaceBaseAnalysis.cpp
+===================================================================
+--- ../trunk-jpl/src/c/analyses/FreeSurfaceBaseAnalysis.cpp	(revision 27278)
++++ ../trunk-jpl/src/c/analyses/FreeSurfaceBaseAnalysis.cpp	(revision 27279)
+@@ -88,9 +88,11 @@
+ 
+ 	/*Get what we need for ocean-induced basal melting*/
+ 	bool isstochastic;
+-	int basalforcing_model;
+-	iomodel->FindConstant(&basalforcing_model,"md.basalforcings.model");
+-	iomodel->FindConstant(&isstochastic,"md.stochasticforcing.isstochasticforcing");
++   int basalforcing_model;
++   int melt_parameterization;
++   iomodel->FindConstant(&basalforcing_model,"md.basalforcings.model");
++   iomodel->FindConstant(&isstochastic,"md.stochasticforcing.isstochasticforcing");
++   iomodel->FindConstant(&melt_parameterization,"md.frontalforcings.parameterization");
+ 	switch(basalforcing_model){
+ 		case FloatingMeltRateEnum:
+ 			iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.floatingice_melting_rate",BasalforcingsFloatingiceMeltingRateEnum);
+@@ -131,7 +133,7 @@
+             iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.ocean_salinity",BasalforcingsOceanSalinityEnum);
+             iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.ocean_temp",BasalforcingsOceanTempEnum);
+          }
+-         else{
++         else if(melt_parameterization!=FrontalForcingsRignotarmaEnum){
+             iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.ocean_thermalforcing",FrontalForcingsAndBasalforcingsThermalForcingEnum);
+          }
+ 			break;
+Index: ../trunk-jpl/src/c/analyses/MasstransportAnalysis.cpp
+===================================================================
+--- ../trunk-jpl/src/c/analyses/MasstransportAnalysis.cpp	(revision 27278)
++++ ../trunk-jpl/src/c/analyses/MasstransportAnalysis.cpp	(revision 27279)
+@@ -162,8 +162,10 @@
+ 	/*Get what we need for ocean-induced basal melting*/
+ 	bool isstochastic;
+ 	int basalforcing_model;
++	int melt_parameterization;
+ 	iomodel->FindConstant(&basalforcing_model,"md.basalforcings.model");
+ 	iomodel->FindConstant(&isstochastic,"md.stochasticforcing.isstochasticforcing");
++	iomodel->FindConstant(&melt_parameterization,"md.frontalforcings.parameterization");
+ 	switch(basalforcing_model){
+ 		case FloatingMeltRateEnum:
+ 			iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.floatingice_melting_rate",BasalforcingsFloatingiceMeltingRateEnum);
+@@ -221,7 +223,7 @@
+ 				iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.ocean_salinity",BasalforcingsOceanSalinityEnum);
+ 				iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.ocean_temp",BasalforcingsOceanTempEnum);
+ 			}
+-			else{
++			else if(melt_parameterization!=FrontalForcingsRignotarmaEnum){
+ 				iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.ocean_thermalforcing",FrontalForcingsAndBasalforcingsThermalForcingEnum);
+ 			}
+ 			break;
+Index: ../trunk-jpl/src/c/analyses/StressbalanceAnalysis.cpp
+===================================================================
+--- ../trunk-jpl/src/c/analyses/StressbalanceAnalysis.cpp	(revision 27278)
++++ ../trunk-jpl/src/c/analyses/StressbalanceAnalysis.cpp	(revision 27279)
+@@ -816,9 +816,11 @@
+ 
+ 		/*Add basal forcings to compute melt rate*/
+ 		bool isstochastic;
+-		int basalforcing_model;
+-		iomodel->FindConstant(&basalforcing_model,"md.basalforcings.model");
+-		iomodel->FindConstant(&isstochastic,"md.stochasticforcing.isstochasticforcing");
++	   int basalforcing_model;
++	   int melt_parameterization;
++	   iomodel->FindConstant(&basalforcing_model,"md.basalforcings.model");
++	   iomodel->FindConstant(&isstochastic,"md.stochasticforcing.isstochasticforcing");
++	   iomodel->FindConstant(&melt_parameterization,"md.frontalforcings.parameterization");
+ 		switch(basalforcing_model){
+ 			case FloatingMeltRateEnum:
+ 				iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.floatingice_melting_rate",BasalforcingsFloatingiceMeltingRateEnum);
+@@ -859,7 +861,7 @@
+       	      iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.ocean_salinity",BasalforcingsOceanSalinityEnum);
+       	      iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.ocean_temp",BasalforcingsOceanTempEnum);
+       	   }
+-      	   else{
++      	   else if(melt_parameterization!=FrontalForcingsRignotarmaEnum){
+       	      iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.ocean_thermalforcing",FrontalForcingsAndBasalforcingsThermalForcingEnum);
+       	   }
+ 				break;
+Index: ../trunk-jpl/src/c/analyses/StressbalanceVerticalAnalysis.cpp
+===================================================================
+--- ../trunk-jpl/src/c/analyses/StressbalanceVerticalAnalysis.cpp	(revision 27278)
++++ ../trunk-jpl/src/c/analyses/StressbalanceVerticalAnalysis.cpp	(revision 27279)
+@@ -119,9 +119,11 @@
+ 
+ 	/*Add basal forcings to compute melt rate*/
+ 	bool isstochastic;
+-	int basalforcing_model;
+-	iomodel->FindConstant(&basalforcing_model,"md.basalforcings.model");
+-	iomodel->FindConstant(&isstochastic,"md.stochasticforcing.isstochasticforcing");
++   int basalforcing_model;
++   int melt_parameterization;
++   iomodel->FindConstant(&basalforcing_model,"md.basalforcings.model");
++   iomodel->FindConstant(&isstochastic,"md.stochasticforcing.isstochasticforcing");
++   iomodel->FindConstant(&melt_parameterization,"md.frontalforcings.parameterization");
+ 	switch(basalforcing_model){
+ 		case FloatingMeltRateEnum:
+ 			iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.floatingice_melting_rate",BasalforcingsFloatingiceMeltingRateEnum);
+@@ -161,7 +163,7 @@
+             iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.ocean_salinity",BasalforcingsOceanSalinityEnum);
+             iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.ocean_temp",BasalforcingsOceanTempEnum);
+          }
+-         else{
++         else if(melt_parameterization!=FrontalForcingsRignotarmaEnum){
+             iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.ocean_thermalforcing",FrontalForcingsAndBasalforcingsThermalForcingEnum);
+          }
+ 			break;
Index: /issm/oecreview/Archive/27230-27343/ISSM-27279-27280.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27279-27280.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27279-27280.diff	(revision 27344)
@@ -0,0 +1,46 @@
+Index: ../trunk-jpl/src/c/classes/Elements/Tria.cpp
+===================================================================
+--- ../trunk-jpl/src/c/classes/Elements/Tria.cpp	(revision 27279)
++++ ../trunk-jpl/src/c/classes/Elements/Tria.cpp	(revision 27280)
+@@ -909,7 +909,7 @@
+ 		switch (use_parameter) { 
+ 			case 0:
+ 				/* 0 Linear: f(x) = y_{o} + \alpha (x+x_{o}) */
+-				gamma = yoffset = alpha * (bed+xoffset);
++				gamma = yoffset + alpha * (bed+xoffset);
+ 				break;
+ 			case 1:
+ 				/* 1 tanh: f(x)=y_{o}-\frac{\theta}{2}\tanh(\alpha(x+x_{o})) */
+@@ -927,6 +927,10 @@
+ 				/* 4 tanh(normal vel), cross (0,0): f(x)=y_{o}-\frac{\theta}{2}\tanh(\alpha(x+x_{o})) */
+ 				gamma = 0.5*theta*(tanh(alpha*xoffset) - tanh(alpha*(truncateVrate+xoffset)));
+ 				break;
++			case 5:
++				/* 5 Linear: f(x) = y_{o} + \alpha (x+x_{o}) */
++				gamma = yoffset + alpha * (truncateVrate+xoffset);
++				break;
+ 			case -1:
+ 				/* nothing, just the arate*/
+ 				gamma = 1;
+Index: ../trunk-jpl/src/m/classes/calvingparameterization.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/calvingparameterization.m	(revision 27279)
++++ ../trunk-jpl/src/m/classes/calvingparameterization.m	(revision 27280)
+@@ -62,7 +62,7 @@
+ 			if (~strcmp(solution,'TransientSolution') | md.transient.ismovingfront==0), return; end
+ 
+ 			md = checkfield(md,'fieldname','calving.min_thickness','>=',0,'NaN',1,'Inf',1,'numel',1);
+-			md = checkfield(md,'fieldname','calving.use_param','values',[-1, 0, 1, 2, 3, 4]);
++			md = checkfield(md,'fieldname','calving.use_param','values',[-1, 0, 1, 2, 3, 4, 5]);
+ 			md = checkfield(md,'fieldname','calving.theta','NaN',1,'Inf',1,'numel',1);
+ 			md = checkfield(md,'fieldname','calving.alpha','NaN',1,'Inf',1,'numel',1);
+ 			md = checkfield(md,'fieldname','calving.xoffset','NaN',1,'Inf',1,'numel',1);
+@@ -74,7 +74,7 @@
+ 		function disp(self) % {{{
+ 			disp(sprintf('   Calving test parameters:'));
+ 			fielddisplay(self,'min_thickness','minimum thickness below which no ice is allowed [m]');
+-			fielddisplay(self,'use_param','-1 - just use frontal ablation rate, 0 - f(x) = y_{o} + \alpha (x+x_{o}), 1 - f(x)=y_{o}-\frac{\theta}{2}\tanh(\alpha(x+x_{o})), 2 - tanh(thickness), 3 - tanh(normalized vel), 4 - tanh(truncated vel)');
++			fielddisplay(self,'use_param','-1 - just use frontal ablation rate, 0 - f(x) = y_{o} + \alpha (x+x_{o}), 1 - f(x)=y_{o}-\frac{\theta}{2}\tanh(\alpha(x+x_{o})), 2 - tanh(thickness), 3 - tanh(normalized vel), 4 - tanh(truncated vel), 5 - linear(truncated vel)');
+ 			fielddisplay(self,'theta','the amplifier');
+ 			fielddisplay(self,'alpha','the slope');
+ 			fielddisplay(self,'xoffset','offset in x-axis');
Index: /issm/oecreview/Archive/27230-27343/ISSM-27280-27281.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27280-27281.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27280-27281.diff	(revision 27344)
@@ -0,0 +1,13 @@
+Index: ../trunk-jpl/src/m/classes/frontalforcingsrignot.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/frontalforcingsrignot.m	(revision 27280)
++++ ../trunk-jpl/src/m/classes/frontalforcingsrignot.m	(revision 27281)
+@@ -53,7 +53,7 @@
+ 			disp(sprintf('   Frontalforcings parameters:'));
+ 			fielddisplay(self,'basin_id','basin ID for elements');
+ 			fielddisplay(self,'num_basins', 'number of basins');
+-			fielddisplay(self,'subglacial_discharge','sum of subglacial discharge for each basin [m/d]');
++			fielddisplay(self,'subglacial_discharge','sum of subglacial discharge for each basin [m^3/d]');
+ 			fielddisplay(self,'thermalforcing','thermal forcing [∘C]');
+ 		end % }}}
+ 		function marshall(self,prefix,md,fid) % {{{
Index: /issm/oecreview/Archive/27230-27343/ISSM-27281-27282.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27281-27282.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27281-27282.diff	(revision 27344)
@@ -0,0 +1,538 @@
+Index: ../trunk-jpl/src/c/analyses/HydrologyGlaDSAnalysis.cpp
+===================================================================
+--- ../trunk-jpl/src/c/analyses/HydrologyGlaDSAnalysis.cpp	(revision 27281)
++++ ../trunk-jpl/src/c/analyses/HydrologyGlaDSAnalysis.cpp	(revision 27282)
+@@ -233,6 +233,9 @@
+ }/*}}}*/
+ ElementMatrix* HydrologyGlaDSAnalysis::CreateKMatrix(Element* element){/*{{{*/
+ 
++	/*Skip if water or ice shelf element*/
++	if(element->IsAllFloating() || !element->IsIceInElement()) return NULL;
++
+ 	/*Intermediaries */
+ 	IssmDouble  Jdet,dphi[3],h,k;
+ 	IssmDouble  A,B,n,phi_old,phi,phi_0,H,b,v1;
+@@ -331,7 +334,7 @@
+ ElementVector* HydrologyGlaDSAnalysis::CreatePVector(Element* element){/*{{{*/
+ 
+ 	/*Skip if water or ice shelf element*/
+-	if(element->IsAllFloating()) return NULL;
++	if(element->IsAllFloating() || !element->IsIceInElement()) return NULL;
+ 
+ 	/*Intermediaries */
+ 	bool        meltflag;
+@@ -442,7 +445,47 @@
+ 	element->InputUpdateFromSolutionOneDof(solution,HydraulicPotentialEnum);
+ }/*}}}*/
+ void           HydrologyGlaDSAnalysis::UpdateConstraints(FemModel* femmodel){/*{{{*/
+-	SetActiveNodesLSMx(femmodel);
++
++	/*Update active elements based on ice levelset and ocean levelset*/
++	GetMaskOfIceVerticesLSMx(femmodel,true);
++	SetActiveNodesLSMx(femmodel,true);
++
++	IssmDouble rho_ice   = femmodel->parameters->FindParam(MaterialsRhoIceEnum);
++	IssmDouble rho_water = femmodel->parameters->FindParam(MaterialsRhoFreshwaterEnum);
++	IssmDouble g         = femmodel->parameters->FindParam(ConstantsGEnum);
++
++	/*Constrain all nodes that are grounded and unconstrain the ones that float*/
++	for(Object* & object : femmodel->elements->objects){
++		Element    *element  = xDynamicCast<Element*>(object);
++		int         numnodes  = element->GetNumberOfNodes();
++		IssmDouble *mask      = xNew<IssmDouble>(numnodes);
++		IssmDouble *bed       = xNew<IssmDouble>(numnodes);
++		IssmDouble *thickness = xNew<IssmDouble>(numnodes);
++		IssmDouble *ls_active = xNew<IssmDouble>(numnodes);
++
++		element->GetInputListOnNodes(&mask[0],MaskOceanLevelsetEnum);
++		element->GetInputListOnNodes(&bed[0],BaseEnum);
++		element->GetInputListOnNodes(&thickness[0],BaseEnum);
++		element->GetInputListOnNodes(&ls_active[0],HydrologyMaskNodeActivationEnum);
++
++		for(int in=0;in<numnodes;in++){
++			Node* node=element->GetNode(in);
++			if(mask[in]>0. && ls_active[in]==1.){
++				node->Activate(); //Not sure if we need this!
++			}
++			else{
++				IssmDouble phi =  rho_ice*g*thickness[in] + rho_water*g*bed[in]; //FIXME this is correct!
++				node->Deactivate();// Not sure if we need this
++				node->ApplyConstraint(0,phi);
++			}
++		}
++		xDelete<IssmDouble>(mask);
++		xDelete<IssmDouble>(bed);
++		xDelete<IssmDouble>(thickness);
++		xDelete<IssmDouble>(ls_active);
++	}
++
++	return;
+ }/*}}}*/
+ 
+ /*GlaDS specifics*/
+@@ -470,9 +513,6 @@
+ }/*}}}*/
+ void HydrologyGlaDSAnalysis::UpdateSheetThickness(Element* element){/*{{{*/
+ 
+-	/*Skip if water or ice shelf element*/
+-	//if(element->IsAllFloating()) return;
+-
+ 	/*Intermediaries */
+ 	IssmDouble  Jdet,vx,vy,ub,h_old,N,h_r,H,b;
+ 	IssmDouble  A,B,n,phi,phi_0;
+@@ -484,6 +524,14 @@
+ 	/*Initialize new sheet thickness*/
+ 	IssmDouble* h_new = xNew<IssmDouble>(numvertices);
+ 
++	/*Set to 0 if inactive element*/
++	if(element->IsAllFloating() || !element->IsIceInElement()){
++		for(int iv=0;iv<numvertices;iv++) h_new[iv] = 0.;
++		element->AddInput(HydrologySheetThicknessEnum,h_new,P1Enum);
++		xDelete<IssmDouble>(h_new);
++		return;
++	}
++
+ 	/*Retrieve all inputs and parameters*/
+ 	IssmDouble  dt       = element->FindParam(TimesteppingTimeStepEnum);
+ 	IssmDouble  l_r      = element->FindParam(HydrologyCavitySpacingEnum);
+@@ -544,7 +592,7 @@
+ 	}
+ 	
+ 	/*Force floating ice to have zero sheet thickness*/
+-	if(element->IsAllFloating()){
++	if(element->IsAllFloating() || !element->IsIceInElement()){
+ 		for(int iv=0;iv<numvertices;iv++) h_new[iv] = 0.;
+ 	}
+ 
+@@ -564,9 +612,6 @@
+ }/*}}}*/
+ void HydrologyGlaDSAnalysis::UpdateEffectivePressure(Element* element){/*{{{*/
+ 
+-	/*Skip if water or ice shelf element*/
+-	//if(element->IsAllFloating()) return;
+-
+ 	/*Intermediary*/
+ 	IssmDouble phi_0, phi_m, p_i;
+ 	IssmDouble H,b,phi;
+@@ -582,6 +627,14 @@
+ 	Input* b_input   = element->GetInput(BedEnum); _assert_(b_input);
+ 	Input* phi_input = element->GetInput(HydraulicPotentialEnum); _assert_(phi_input);
+ 
++	/*Set to 0 if inactive element*/
++	if(element->IsAllFloating() || !element->IsIceInElement()){
++		for(int iv=0;iv<numnodes;iv++) N[iv] = 0.;
++		element->AddInput(EffectivePressureEnum,N,P1Enum);
++		xDelete<IssmDouble>(N);
++		return;
++	}
++
+ 	/* Start  looping on the number of gaussian points: */
+ 	Gauss* gauss=element->NewGauss();
+ 	for(int iv=0;iv<numnodes;iv++){
+@@ -608,11 +661,6 @@
+ 		if(xIsInf<IssmDouble>(N[iv])) _error_("Inf found in solution vector");
+ 	}
+ 
+-   /*Force floating ice to have zero effective pressure*/
+-   if(element->IsAllFloating()){
+-		for(int iv=0;iv<numnodes;iv++) N[iv] = 0.;
+-	}
+-
+ 	element->AddInput(EffectivePressureEnum,N,element->FiniteElement());
+ 	
+ 	/*Clean up and return*/
+Index: ../trunk-jpl/src/c/classes/Elements/Element.cpp
+===================================================================
+--- ../trunk-jpl/src/c/classes/Elements/Element.cpp	(revision 27281)
++++ ../trunk-jpl/src/c/classes/Elements/Element.cpp	(revision 27282)
+@@ -2365,6 +2365,7 @@
+ 	}
+ }/*}}}*/
+ bool       Element::IsGrounded(){/*{{{*/
++	/*At least ONE node is grounded (partially grounded returns true)*/
+ 
+ 	Input* input=this->GetInput(MaskOceanLevelsetEnum); _assert_(input);
+ 	if(input->GetInputMax() > 0.){
+Index: ../trunk-jpl/src/c/classes/Loads/Channel.cpp
+===================================================================
+--- ../trunk-jpl/src/c/classes/Loads/Channel.cpp	(revision 27281)
++++ ../trunk-jpl/src/c/classes/Loads/Channel.cpp	(revision 27282)
+@@ -602,14 +602,28 @@
+ 
+ 	/*Initialize Element matrix and return if necessary*/
+ 	Tria*  tria=(Tria*)element;
+-	if(!tria->IsIceInElement() || tria->IsAllFloating() || this->boundary){
++	if(this->boundary){
+ 		this->S = 0.;
+ 		return;
+ 	}
+ 	_assert_(tria->FiniteElement()==P1Enum); 
++
++	/*Evaluate all fields on center of edge*/
+ 	int index1=tria->GetVertexIndex(vertices[0]);
+ 	int index2=tria->GetVertexIndex(vertices[1]);
++	GaussTria* gauss=new GaussTria();
++	gauss->GaussEdgeCenter(index1,index2);
+ 
++	/*Set to 0 if inactive*/
++	IssmDouble active;
++	Input* active_input = element->GetInput(HydrologyMaskNodeActivationEnum); _assert_(active_input);
++	active_input->GetInputValue(&active,gauss);
++	if(active!=1.){
++		this->S = 0.;
++		delete gauss;
++		return;
++	}
++
+ 	/*Intermediaries */
+ 	IssmDouble  A,B,n,phi,phi_0,ks,Ngrad;
+ 	IssmDouble  H,h,b,dphi[2],dphids,dphimds,db[2],dbds;
+@@ -644,10 +658,6 @@
+ 	tx = tx/Lt;
+ 	ty = ty/Lt;
+ 
+-	/*Evaluate fields on center of edge*/
+-	GaussTria* gauss=new GaussTria();
+-	gauss->GaussEdgeCenter(index1,index2);
+-
+ 	/*Get input values at gauss points*/
+ 	phi_input->GetInputValue(&phi,gauss);
+ 	phi_input->GetInputDerivativeValue(&dphi[0],&xyz_list_tria[0][0],gauss);
+Index: ../trunk-jpl/src/c/modules/SetActiveNodesLSMx/SetActiveNodesLSMx.cpp
+===================================================================
+--- ../trunk-jpl/src/c/modules/SetActiveNodesLSMx/SetActiveNodesLSMx.cpp	(revision 27281)
++++ ../trunk-jpl/src/c/modules/SetActiveNodesLSMx/SetActiveNodesLSMx.cpp	(revision 27282)
+@@ -9,13 +9,14 @@
+ #include "../../toolkits/toolkits.h"
+ #include "../modules.h"
+ 
+-void SetActiveNodesLSMx(FemModel* femmodel){/*{{{*/
++void SetActiveNodesLSMx(FemModel* femmodel,bool ishydrology){/*{{{*/
+ 	/* activate/deactivate nodes for levelset method according to IceMaskNodeActivation */
+ 
+-	/* find parameters */
+-	int domaintype;
+-	femmodel->parameters->FindParam(&domaintype,DomainTypeEnum);
++	/*Determine which node activation mask to pull from*/
++	int nodeactivationmask = IceMaskNodeActivationEnum;
++	if(ishydrology) nodeactivationmask = HydrologyMaskNodeActivationEnum;
+ 
++
+ 	for(Object* & object : femmodel->elements->objects){
+ 		Element    *element  = xDynamicCast<Element*>(object);
+ 		int         numnodes = element->GetNumberOfNodes();
+@@ -27,8 +28,8 @@
+ 			case MINIEnum:case MINIcondensedEnum:
+ 			case TaylorHoodEnum:case XTaylorHoodEnum:case LATaylorHoodEnum:
+ 			case CrouzeixRaviartEnum:case LACrouzeixRaviartEnum:case OneLayerP4zEnum:{
+-				Input* input=element->GetInput(IceMaskNodeActivationEnum);
+-				if(!input) _error_("Input " << EnumToStringx(IceMaskNodeActivationEnum) << " not found in element");
++				Input* input=element->GetInput(nodeactivationmask);
++				if(!input) _error_("Input " << EnumToStringx(nodeactivationmask) << " not found in element");
+ 
+ 				/* Start looping on the number of vertices: */
+ 				Gauss* gauss=element->NewGauss();
+@@ -44,7 +45,7 @@
+ 				break;
+ 			}
+ 			default:
+-				element->GetInputListOnNodes(&mask[0],IceMaskNodeActivationEnum);
++				element->GetInputListOnNodes(&mask[0],nodeactivationmask);
+ 				break;
+ 		}
+ 
+@@ -57,8 +58,12 @@
+ 	}
+ }/*}}}*/
+ 
+-void GetMaskOfIceVerticesLSMx0(FemModel* femmodel){/*{{{*/
++void GetMaskOfIceVerticesLSMx0(FemModel* femmodel,bool ishydrology){/*{{{*/
+ 
++	/*Determine which node activation to construct*/
++	int nodeactivationmask = IceMaskNodeActivationEnum;
++	if(ishydrology) nodeactivationmask = HydrologyMaskNodeActivationEnum;
++
+ 	/*Initialize vector with number of vertices*/
+ 	int numvertices=femmodel->vertices->NumberOfVertices();
+ 	if(numvertices==0)  return;
+@@ -67,25 +72,49 @@
+ 	Vector<IssmDouble>* vec_mask_ice=new Vector<IssmDouble>(numvert_local,numvertices);
+ 
+ 	/*Fill vector with values: */
+-	for(Object* & object : femmodel->elements->objects){
+-		Element* element=xDynamicCast<Element*>(object);
+-		if(element->IsIceInElement()){
+-			int nbv = element->GetNumberOfVertices();
+-			for(int iv=0;iv<nbv;iv++){
+-				vec_mask_ice->SetValue(element->vertices[iv]->Pid(),1.,INS_VAL);
++	if(ishydrology){
++		for(Object* & object : femmodel->elements->objects){
++			Element* element=xDynamicCast<Element*>(object);
++			if(element->IsIceInElement()){
++				int nbv = element->GetNumberOfVertices();
++				for(int iv=0;iv<nbv;iv++){
++					vec_mask_ice->SetValue(element->vertices[iv]->Pid(),1.,INS_VAL);
++				}
+ 			}
+ 		}
+ 	}
++	else{
++		for(Object* & object : femmodel->elements->objects){
++			Element* element=xDynamicCast<Element*>(object);
++			if(element->IsIceInElement() && element->IsGrounded()){
++				int nbv = element->GetNumberOfVertices();
++				for(int iv=0;iv<nbv;iv++){
++					vec_mask_ice->SetValue(element->vertices[iv]->Pid(),1.,INS_VAL);
++				}
++			}
++		}
++	}
+ 
+ 	/*Assemble vector and serialize */
+ 	vec_mask_ice->Assemble();
+-	InputUpdateFromVectorx(femmodel,vec_mask_ice,IceMaskNodeActivationEnum,VertexPIdEnum);
++	InputUpdateFromVectorx(femmodel,vec_mask_ice,nodeactivationmask,VertexPIdEnum);
+ 	delete vec_mask_ice;
+ }/*}}}*/
+-void GetMaskOfIceVerticesLSMx(FemModel* femmodel){/*{{{*/
++void GetMaskOfIceVerticesLSMx(FemModel* femmodel,bool ishydrology){/*{{{*/
+ 
+-	femmodel->SetCurrentConfiguration(LevelsetAnalysisEnum);
++	/*Set configuration to levelset*/
++	if(ishydrology){
++		/*We may not be running with ismovingfront so we can't assume LevelsetAnalysis is active*/
++		femmodel->SetCurrentConfiguration(HydrologyGlaDSAnalysisEnum);
++	}
++	else{
++		femmodel->SetCurrentConfiguration(LevelsetAnalysisEnum);
++	}
+ 
++	/*Determine which node activation to construct*/
++	int nodeactivationmask = IceMaskNodeActivationEnum;
++	if(ishydrology) nodeactivationmask = HydrologyMaskNodeActivationEnum;
++
+ 	/*Create vector on gset*/
+ 	int gsize              = femmodel->nodes->NumberOfDofs(GsetEnum);
+ 	int glocalsize_masters = femmodel->nodes->NumberOfDofsLocal(GsetEnum);
+@@ -96,16 +125,30 @@
+ 	for(Object* & object : femmodel->elements->objects){
+ 		Element* element=xDynamicCast<Element*>(object);
+ 
+-		if(element->IsIceInElement()){
+-			int numnodes = element->GetNumberOfNodes();
+-			int  gsize_local=GetNumberOfDofs(element->nodes,numnodes,GsetEnum,NoneEnum);
+-			int* glist_local=GetGlobalDofList(element->nodes,numnodes,GsetEnum,NoneEnum);
+-			IssmDouble* ones = xNew<IssmDouble>(gsize_local);
+-			for(int n=0;n<gsize_local;n++) ones[n] = 1.;
+-			vec_mask_ice->SetValues(gsize_local,glist_local,ones,INS_VAL);
+-			xDelete<IssmDouble>(ones);
+-			xDelete<int>(glist_local);
++		if(ishydrology){
++			if(element->IsIceInElement() && element->IsGrounded()){
++				int numnodes = element->GetNumberOfNodes();
++				int  gsize_local=GetNumberOfDofs(element->nodes,numnodes,GsetEnum,NoneEnum);
++				int* glist_local=GetGlobalDofList(element->nodes,numnodes,GsetEnum,NoneEnum);
++				IssmDouble* ones = xNew<IssmDouble>(gsize_local);
++				for(int n=0;n<gsize_local;n++) ones[n] = 1.;
++				vec_mask_ice->SetValues(gsize_local,glist_local,ones,INS_VAL);
++				xDelete<IssmDouble>(ones);
++				xDelete<int>(glist_local);
++			}
+ 		}
++		else{
++			if(element->IsIceInElement()){
++				int numnodes = element->GetNumberOfNodes();
++				int  gsize_local=GetNumberOfDofs(element->nodes,numnodes,GsetEnum,NoneEnum);
++				int* glist_local=GetGlobalDofList(element->nodes,numnodes,GsetEnum,NoneEnum);
++				IssmDouble* ones = xNew<IssmDouble>(gsize_local);
++				for(int n=0;n<gsize_local;n++) ones[n] = 1.;
++				vec_mask_ice->SetValues(gsize_local,glist_local,ones,INS_VAL);
++				xDelete<IssmDouble>(ones);
++				xDelete<int>(glist_local);
++			}
++		}
+ 	}
+ 
+ 	/*Assemble vector and serialize */
+@@ -119,7 +162,7 @@
+ 	/*Now update inputs (analysis specific)*/
+ 	for(Object* & object : femmodel->elements->objects){
+ 		Element* element=xDynamicCast<Element*>(object);
+-		element->InputUpdateFromSolutionOneDof(local_ug,IceMaskNodeActivationEnum);
++		element->InputUpdateFromSolutionOneDof(local_ug,nodeactivationmask);
+ 	}
+ 
+ 	/*cleanup and return*/
+Index: ../trunk-jpl/src/c/modules/SetActiveNodesLSMx/SetActiveNodesLSMx.h
+===================================================================
+--- ../trunk-jpl/src/c/modules/SetActiveNodesLSMx/SetActiveNodesLSMx.h	(revision 27281)
++++ ../trunk-jpl/src/c/modules/SetActiveNodesLSMx/SetActiveNodesLSMx.h	(revision 27282)
+@@ -7,7 +7,7 @@
+ 
+ #include "../../classes/classes.h"
+ 
+-void SetActiveNodesLSMx(FemModel* femmodel);
+-void GetMaskOfIceVerticesLSMx0(FemModel* femmodel);
+-void GetMaskOfIceVerticesLSMx(FemModel* femmodel);
++void SetActiveNodesLSMx(FemModel* femmodel,bool ishydrology=false);
++void GetMaskOfIceVerticesLSMx0(FemModel* femmodel,bool ishydrology=false);
++void GetMaskOfIceVerticesLSMx(FemModel* femmodel,bool ishydrology=false);
+ #endif  /* _SETACTIVENODESLSMX_H*/
+Index: ../trunk-jpl/src/c/shared/Enum/Enum.vim
+===================================================================
+--- ../trunk-jpl/src/c/shared/Enum/Enum.vim	(revision 27281)
++++ ../trunk-jpl/src/c/shared/Enum/Enum.vim	(revision 27282)
+@@ -819,6 +819,7 @@
+ syn keyword cConstant HydrologyWatercolumnMaxEnum
+ syn keyword cConstant HydrologyWaterVxEnum
+ syn keyword cConstant HydrologyWaterVyEnum
++syn keyword cConstant HydrologyMaskNodeActivationEnum
+ syn keyword cConstant IceEnum
+ syn keyword cConstant IceMaskNodeActivationEnum
+ syn keyword cConstant InputEnum
+Index: ../trunk-jpl/src/c/shared/Enum/EnumDefinitions.h
+===================================================================
+--- ../trunk-jpl/src/c/shared/Enum/EnumDefinitions.h	(revision 27281)
++++ ../trunk-jpl/src/c/shared/Enum/EnumDefinitions.h	(revision 27282)
+@@ -815,6 +815,7 @@
+ 	HydrologyWatercolumnMaxEnum,
+ 	HydrologyWaterVxEnum,
+ 	HydrologyWaterVyEnum,
++	HydrologyMaskNodeActivationEnum,
+ 	IceEnum,
+ 	IceMaskNodeActivationEnum,
+ 	InputEnum,
+Index: ../trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp
+===================================================================
+--- ../trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp	(revision 27281)
++++ ../trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp	(revision 27282)
+@@ -821,6 +821,7 @@
+ 		case HydrologyWatercolumnMaxEnum : return "HydrologyWatercolumnMax";
+ 		case HydrologyWaterVxEnum : return "HydrologyWaterVx";
+ 		case HydrologyWaterVyEnum : return "HydrologyWaterVy";
++		case HydrologyMaskNodeActivationEnum : return "HydrologyMaskNodeActivation";
+ 		case IceEnum : return "Ice";
+ 		case IceMaskNodeActivationEnum : return "IceMaskNodeActivation";
+ 		case InputEnum : return "Input";
+Index: ../trunk-jpl/src/c/shared/Enum/Enumjl.vim
+===================================================================
+--- ../trunk-jpl/src/c/shared/Enum/Enumjl.vim	(revision 27281)
++++ ../trunk-jpl/src/c/shared/Enum/Enumjl.vim	(revision 27282)
+@@ -812,6 +812,7 @@
+ syn keyword juliaConstC HydrologyWatercolumnMaxEnum
+ syn keyword juliaConstC HydrologyWaterVxEnum
+ syn keyword juliaConstC HydrologyWaterVyEnum
++syn keyword juliaConstC HydrologyMaskNodeActivationEnum
+ syn keyword juliaConstC IceEnum
+ syn keyword juliaConstC IceMaskNodeActivationEnum
+ syn keyword juliaConstC InputEnum
+Index: ../trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp
+===================================================================
+--- ../trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp	(revision 27281)
++++ ../trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp	(revision 27282)
+@@ -839,6 +839,7 @@
+ 	      else if (strcmp(name,"HydrologyWatercolumnMax")==0) return HydrologyWatercolumnMaxEnum;
+ 	      else if (strcmp(name,"HydrologyWaterVx")==0) return HydrologyWaterVxEnum;
+ 	      else if (strcmp(name,"HydrologyWaterVy")==0) return HydrologyWaterVyEnum;
++	      else if (strcmp(name,"HydrologyMaskNodeActivation")==0) return HydrologyMaskNodeActivationEnum;
+ 	      else if (strcmp(name,"Ice")==0) return IceEnum;
+ 	      else if (strcmp(name,"IceMaskNodeActivation")==0) return IceMaskNodeActivationEnum;
+ 	      else if (strcmp(name,"Input")==0) return InputEnum;
+@@ -873,11 +874,11 @@
+ 	      else if (strcmp(name,"MeshVertexonsurface")==0) return MeshVertexonsurfaceEnum;
+ 	      else if (strcmp(name,"Misfit")==0) return MisfitEnum;
+ 	      else if (strcmp(name,"MovingFrontalVx")==0) return MovingFrontalVxEnum;
+-	      else if (strcmp(name,"MovingFrontalVy")==0) return MovingFrontalVyEnum;
+          else stage=8;
+    }
+    if(stage==8){
+-	      if (strcmp(name,"Neumannflux")==0) return NeumannfluxEnum;
++	      if (strcmp(name,"MovingFrontalVy")==0) return MovingFrontalVyEnum;
++	      else if (strcmp(name,"Neumannflux")==0) return NeumannfluxEnum;
+ 	      else if (strcmp(name,"NewDamage")==0) return NewDamageEnum;
+ 	      else if (strcmp(name,"Node")==0) return NodeEnum;
+ 	      else if (strcmp(name,"OmegaAbsGradient")==0) return OmegaAbsGradientEnum;
+@@ -996,11 +997,11 @@
+ 	      else if (strcmp(name,"SmbCcsnowValue")==0) return SmbCcsnowValueEnum;
+ 	      else if (strcmp(name,"SmbCciceValue")==0) return SmbCciceValueEnum;
+ 	      else if (strcmp(name,"SmbCotValue")==0) return SmbCotValueEnum;
+-	      else if (strcmp(name,"SmbD")==0) return SmbDEnum;
+          else stage=9;
+    }
+    if(stage==9){
+-	      if (strcmp(name,"SmbDailyairdensity")==0) return SmbDailyairdensityEnum;
++	      if (strcmp(name,"SmbD")==0) return SmbDEnum;
++	      else if (strcmp(name,"SmbDailyairdensity")==0) return SmbDailyairdensityEnum;
+ 	      else if (strcmp(name,"SmbDailyairhumidity")==0) return SmbDailyairhumidityEnum;
+ 	      else if (strcmp(name,"SmbDailydlradiation")==0) return SmbDailydlradiationEnum;
+ 	      else if (strcmp(name,"SmbDailydsradiation")==0) return SmbDailydsradiationEnum;
+@@ -1119,11 +1120,11 @@
+ 	      else if (strcmp(name,"SurfaceCrevasse")==0) return SurfaceCrevasseEnum;
+ 	      else if (strcmp(name,"Surface")==0) return SurfaceEnum;
+ 	      else if (strcmp(name,"SurfaceOld")==0) return SurfaceOldEnum;
+-	      else if (strcmp(name,"SurfaceLogVelMisfit")==0) return SurfaceLogVelMisfitEnum;
+          else stage=10;
+    }
+    if(stage==10){
+-	      if (strcmp(name,"SurfaceLogVxVyMisfit")==0) return SurfaceLogVxVyMisfitEnum;
++	      if (strcmp(name,"SurfaceLogVelMisfit")==0) return SurfaceLogVelMisfitEnum;
++	      else if (strcmp(name,"SurfaceLogVxVyMisfit")==0) return SurfaceLogVxVyMisfitEnum;
+ 	      else if (strcmp(name,"SurfaceObservation")==0) return SurfaceObservationEnum;
+ 	      else if (strcmp(name,"SurfaceRelVelMisfit")==0) return SurfaceRelVelMisfitEnum;
+ 	      else if (strcmp(name,"SurfaceSlopeX")==0) return SurfaceSlopeXEnum;
+@@ -1242,11 +1243,11 @@
+ 	      else if (strcmp(name,"Outputdefinition68")==0) return Outputdefinition68Enum;
+ 	      else if (strcmp(name,"Outputdefinition69")==0) return Outputdefinition69Enum;
+ 	      else if (strcmp(name,"Outputdefinition6")==0) return Outputdefinition6Enum;
+-	      else if (strcmp(name,"Outputdefinition70")==0) return Outputdefinition70Enum;
+          else stage=11;
+    }
+    if(stage==11){
+-	      if (strcmp(name,"Outputdefinition71")==0) return Outputdefinition71Enum;
++	      if (strcmp(name,"Outputdefinition70")==0) return Outputdefinition70Enum;
++	      else if (strcmp(name,"Outputdefinition71")==0) return Outputdefinition71Enum;
+ 	      else if (strcmp(name,"Outputdefinition72")==0) return Outputdefinition72Enum;
+ 	      else if (strcmp(name,"Outputdefinition73")==0) return Outputdefinition73Enum;
+ 	      else if (strcmp(name,"Outputdefinition74")==0) return Outputdefinition74Enum;
+@@ -1365,11 +1366,11 @@
+ 	      else if (strcmp(name,"Element")==0) return ElementEnum;
+ 	      else if (strcmp(name,"ElementHook")==0) return ElementHookEnum;
+ 	      else if (strcmp(name,"ElementSId")==0) return ElementSIdEnum;
+-	      else if (strcmp(name,"EnthalpyAnalysis")==0) return EnthalpyAnalysisEnum;
+          else stage=12;
+    }
+    if(stage==12){
+-	      if (strcmp(name,"EsaAnalysis")==0) return EsaAnalysisEnum;
++	      if (strcmp(name,"EnthalpyAnalysis")==0) return EnthalpyAnalysisEnum;
++	      else if (strcmp(name,"EsaAnalysis")==0) return EsaAnalysisEnum;
+ 	      else if (strcmp(name,"EsaSolution")==0) return EsaSolutionEnum;
+ 	      else if (strcmp(name,"EsaTransitions")==0) return EsaTransitionsEnum;
+ 	      else if (strcmp(name,"ExternalResult")==0) return ExternalResultEnum;
+@@ -1488,11 +1489,11 @@
+ 	      else if (strcmp(name,"Massconaxpby")==0) return MassconaxpbyEnum;
+ 	      else if (strcmp(name,"Massfluxatgate")==0) return MassfluxatgateEnum;
+ 	      else if (strcmp(name,"MasstransportAnalysis")==0) return MasstransportAnalysisEnum;
+-	      else if (strcmp(name,"MasstransportSolution")==0) return MasstransportSolutionEnum;
+          else stage=13;
+    }
+    if(stage==13){
+-	      if (strcmp(name,"Matdamageice")==0) return MatdamageiceEnum;
++	      if (strcmp(name,"MasstransportSolution")==0) return MasstransportSolutionEnum;
++	      else if (strcmp(name,"Matdamageice")==0) return MatdamageiceEnum;
+ 	      else if (strcmp(name,"Matenhancedice")==0) return MatenhancediceEnum;
+ 	      else if (strcmp(name,"Materials")==0) return MaterialsEnum;
+ 	      else if (strcmp(name,"Matestar")==0) return MatestarEnum;
+@@ -1611,11 +1612,11 @@
+ 	      else if (strcmp(name,"SmoothAnalysis")==0) return SmoothAnalysisEnum;
+ 	      else if (strcmp(name,"SoftMigration")==0) return SoftMigrationEnum;
+ 	      else if (strcmp(name,"SpatialLinearFloatingMeltRate")==0) return SpatialLinearFloatingMeltRateEnum;
+-	      else if (strcmp(name,"SpcDynamic")==0) return SpcDynamicEnum;
+          else stage=14;
+    }
+    if(stage==14){
+-	      if (strcmp(name,"SpcStatic")==0) return SpcStaticEnum;
++	      if (strcmp(name,"SpcDynamic")==0) return SpcDynamicEnum;
++	      else if (strcmp(name,"SpcStatic")==0) return SpcStaticEnum;
+ 	      else if (strcmp(name,"SpcTransient")==0) return SpcTransientEnum;
+ 	      else if (strcmp(name,"Sset")==0) return SsetEnum;
+ 	      else if (strcmp(name,"StatisticsSolution")==0) return StatisticsSolutionEnum;
Index: /issm/oecreview/Archive/27230-27343/ISSM-27282-27283.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27282-27283.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27282-27283.diff	(revision 27344)
@@ -0,0 +1,22 @@
+Index: ../trunk-jpl/src/c/modules/SetActiveNodesLSMx/SetActiveNodesLSMx.cpp
+===================================================================
+--- ../trunk-jpl/src/c/modules/SetActiveNodesLSMx/SetActiveNodesLSMx.cpp	(revision 27282)
++++ ../trunk-jpl/src/c/modules/SetActiveNodesLSMx/SetActiveNodesLSMx.cpp	(revision 27283)
+@@ -75,7 +75,7 @@
+ 	if(ishydrology){
+ 		for(Object* & object : femmodel->elements->objects){
+ 			Element* element=xDynamicCast<Element*>(object);
+-			if(element->IsIceInElement()){
++			if(element->IsIceInElement() && element->IsGrounded()){
+ 				int nbv = element->GetNumberOfVertices();
+ 				for(int iv=0;iv<nbv;iv++){
+ 					vec_mask_ice->SetValue(element->vertices[iv]->Pid(),1.,INS_VAL);
+@@ -86,7 +86,7 @@
+ 	else{
+ 		for(Object* & object : femmodel->elements->objects){
+ 			Element* element=xDynamicCast<Element*>(object);
+-			if(element->IsIceInElement() && element->IsGrounded()){
++			if(element->IsIceInElement()){
+ 				int nbv = element->GetNumberOfVertices();
+ 				for(int iv=0;iv<nbv;iv++){
+ 					vec_mask_ice->SetValue(element->vertices[iv]->Pid(),1.,INS_VAL);
Index: /issm/oecreview/Archive/27230-27343/ISSM-27283-27284.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27283-27284.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27283-27284.diff	(revision 27344)
@@ -0,0 +1,247 @@
+Index: ../trunk-jpl/src/c/analyses/FreeSurfaceBaseAnalysis.cpp
+===================================================================
+--- ../trunk-jpl/src/c/analyses/FreeSurfaceBaseAnalysis.cpp	(revision 27283)
++++ ../trunk-jpl/src/c/analyses/FreeSurfaceBaseAnalysis.cpp	(revision 27284)
+@@ -134,7 +134,7 @@
+             iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.ocean_temp",BasalforcingsOceanTempEnum);
+          }
+          else if(melt_parameterization!=FrontalForcingsRignotarmaEnum){
+-            iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.ocean_thermalforcing",FrontalForcingsAndBasalforcingsThermalForcingEnum);
++            iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.ocean_thermalforcing",ThermalForcingEnum);
+          }
+ 			break;
+ 		default:
+Index: ../trunk-jpl/src/c/analyses/MasstransportAnalysis.cpp
+===================================================================
+--- ../trunk-jpl/src/c/analyses/MasstransportAnalysis.cpp	(revision 27283)
++++ ../trunk-jpl/src/c/analyses/MasstransportAnalysis.cpp	(revision 27284)
+@@ -224,7 +224,7 @@
+ 				iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.ocean_temp",BasalforcingsOceanTempEnum);
+ 			}
+ 			else if(melt_parameterization!=FrontalForcingsRignotarmaEnum){
+-				iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.ocean_thermalforcing",FrontalForcingsAndBasalforcingsThermalForcingEnum);
++				iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.ocean_thermalforcing",ThermalForcingEnum);
+ 			}
+ 			break;
+ 		case LinearFloatingMeltRatearmaEnum:
+Index: ../trunk-jpl/src/c/analyses/StressbalanceAnalysis.cpp
+===================================================================
+--- ../trunk-jpl/src/c/analyses/StressbalanceAnalysis.cpp	(revision 27283)
++++ ../trunk-jpl/src/c/analyses/StressbalanceAnalysis.cpp	(revision 27284)
+@@ -862,7 +862,7 @@
+       	      iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.ocean_temp",BasalforcingsOceanTempEnum);
+       	   }
+       	   else if(melt_parameterization!=FrontalForcingsRignotarmaEnum){
+-      	      iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.ocean_thermalforcing",FrontalForcingsAndBasalforcingsThermalForcingEnum);
++      	      iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.ocean_thermalforcing",ThermalForcingEnum);
+       	   }
+ 				break;
+ 			default:
+Index: ../trunk-jpl/src/c/analyses/StressbalanceVerticalAnalysis.cpp
+===================================================================
+--- ../trunk-jpl/src/c/analyses/StressbalanceVerticalAnalysis.cpp	(revision 27283)
++++ ../trunk-jpl/src/c/analyses/StressbalanceVerticalAnalysis.cpp	(revision 27284)
+@@ -164,7 +164,7 @@
+             iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.ocean_temp",BasalforcingsOceanTempEnum);
+          }
+          else if(melt_parameterization!=FrontalForcingsRignotarmaEnum){
+-            iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.ocean_thermalforcing",FrontalForcingsAndBasalforcingsThermalForcingEnum);
++            iomodel->FetchDataToInput(inputs,elements,"md.basalforcings.ocean_thermalforcing",ThermalForcingEnum);
+          }
+ 			break;
+ 		default:
+Index: ../trunk-jpl/src/c/analyses/LevelsetAnalysis.cpp
+===================================================================
+--- ../trunk-jpl/src/c/analyses/LevelsetAnalysis.cpp	(revision 27283)
++++ ../trunk-jpl/src/c/analyses/LevelsetAnalysis.cpp	(revision 27284)
+@@ -149,7 +149,7 @@
+ 			break;
+ 		case FrontalForcingsRignotEnum:
+          /*Retrieve thermal forcing only in the case of non-arma FrontalForcingsRignot*/
+-         iomodel->FetchDataToInput(inputs,elements,"md.frontalforcings.thermalforcing",FrontalForcingsAndBasalforcingsThermalForcingEnum);
++         iomodel->FetchDataToInput(inputs,elements,"md.frontalforcings.thermalforcing",ThermalForcingEnum);
+          /* Do not break here, still retrieve basin_ID,subglacial_discharge, etc.*/
+       case FrontalForcingsRignotarmaEnum:
+          iomodel->FetchDataToInput(inputs,elements,"md.frontalforcings.basin_id",FrontalForcingsBasinIdEnum);
+Index: ../trunk-jpl/src/c/classes/Elements/Element.cpp
+===================================================================
+--- ../trunk-jpl/src/c/classes/Elements/Element.cpp	(revision 27283)
++++ ../trunk-jpl/src/c/classes/Elements/Element.cpp	(revision 27284)
+@@ -85,7 +85,7 @@
+          maenum_type    = ThermalforcingValuesMovingaverageEnum;
+          basinenum_type = FrontalForcingsBasinIdEnum;
+          noiseenum_type = ThermalforcingARMANoiseEnum;
+-         outenum_type   = FrontalForcingsAndBasalforcingsThermalForcingEnum;
++         outenum_type   = ThermalForcingEnum;
+          break;
+ 		case(BasalforcingsDeepwaterMeltingRatearmaEnum):
+          arenum_type    = BasalforcingsDeepwaterMeltingRateValuesAutoregressionEnum;
+@@ -194,7 +194,7 @@
+          arenum_type    = ThermalforcingValuesAutoregressionEnum;
+          basinenum_type = FrontalForcingsBasinIdEnum;
+          noiseenum_type = ThermalforcingARMANoiseEnum;
+-         outenum_type   = FrontalForcingsAndBasalforcingsThermalForcingEnum;
++         outenum_type   = ThermalForcingEnum;
+          break;
+ 		case(BasalforcingsDeepwaterMeltingRatearmaEnum):
+          arenum_type    = BasalforcingsDeepwaterMeltingRateValuesAutoregressionEnum;
+@@ -2804,7 +2804,7 @@
+ 		this->GetInputListOnVertices(oceantemp,BasalforcingsOceanTempEnum);
+ 	}
+ 	else{
+-		this->GetInputListOnVertices(oceanthermalforcing,FrontalForcingsAndBasalforcingsThermalForcingEnum);
++		this->GetInputListOnVertices(oceanthermalforcing,ThermalForcingEnum);
+ 	}
+ 
+ 	Gauss* gauss=this->NewGauss();
+@@ -3813,7 +3813,7 @@
+ 	this->GetInputValue(&basinid,FrontalForcingsBasinIdEnum);
+ 	Input* bed_input = this->GetInput(BedEnum);                     _assert_(bed_input);
+    Input* qsg_input = this->GetInput(FrontalForcingsSubglacialDischargeEnum);     _assert_(qsg_input);
+-   Input* TF_input  = this->GetInput(FrontalForcingsAndBasalforcingsThermalForcingEnum);          _assert_(TF_input);
++   Input* TF_input  = this->GetInput(ThermalForcingEnum);          _assert_(TF_input);
+ 
+ 	this->FindParam(&yts, ConstantsYtsEnum);
+    this->parameters->FindParam(&numbasins,FrontalForcingsNumberofBasinsEnum);
+Index: ../trunk-jpl/src/c/shared/Enum/Enum.vim
+===================================================================
+--- ../trunk-jpl/src/c/shared/Enum/Enum.vim	(revision 27283)
++++ ../trunk-jpl/src/c/shared/Enum/Enum.vim	(revision 27284)
+@@ -775,7 +775,6 @@
+ syn keyword cConstant FrictionfEnum
+ syn keyword cConstant FrontalForcingsBasinIdEnum
+ syn keyword cConstant FrontalForcingsSubglacialDischargeEnum
+-syn keyword cConstant FrontalForcingsAndBasalforcingsThermalForcingEnum
+ syn keyword cConstant GeometryHydrostaticRatioEnum
+ syn keyword cConstant NGiaEnum
+ syn keyword cConstant NGiaRateEnum
+@@ -1105,6 +1104,7 @@
+ syn keyword cConstant TemperaturePicardEnum
+ syn keyword cConstant TemperatureSEMICEnum
+ syn keyword cConstant ThermalforcingARMANoiseEnum
++syn keyword cConstant ThermalForcingEnum
+ syn keyword cConstant ThermalforcingValuesAutoregressionEnum
+ syn keyword cConstant ThermalforcingValuesMovingaverageEnum
+ syn keyword cConstant ThermalSpctemperatureEnum
+Index: ../trunk-jpl/src/c/shared/Enum/EnumDefinitions.h
+===================================================================
+--- ../trunk-jpl/src/c/shared/Enum/EnumDefinitions.h	(revision 27283)
++++ ../trunk-jpl/src/c/shared/Enum/EnumDefinitions.h	(revision 27284)
+@@ -771,7 +771,6 @@
+ 	FrictionfEnum,
+ 	FrontalForcingsBasinIdEnum,
+ 	FrontalForcingsSubglacialDischargeEnum,
+-	FrontalForcingsAndBasalforcingsThermalForcingEnum,
+ 	GeometryHydrostaticRatioEnum,
+ 	NGiaEnum,
+ 	NGiaRateEnum,
+@@ -1102,6 +1101,7 @@
+ 	TemperaturePicardEnum,
+ 	TemperatureSEMICEnum,
+    ThermalforcingARMANoiseEnum,
++	ThermalForcingEnum,
+ 	ThermalforcingValuesAutoregressionEnum,
+ 	ThermalforcingValuesMovingaverageEnum,
+ 	ThermalSpctemperatureEnum,
+Index: ../trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp
+===================================================================
+--- ../trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp	(revision 27283)
++++ ../trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp	(revision 27284)
+@@ -777,7 +777,6 @@
+ 		case FrictionfEnum : return "Frictionf";
+ 		case FrontalForcingsBasinIdEnum : return "FrontalForcingsBasinId";
+ 		case FrontalForcingsSubglacialDischargeEnum : return "FrontalForcingsSubglacialDischarge";
+-		case FrontalForcingsAndBasalforcingsThermalForcingEnum : return "FrontalForcingsAndBasalforcingsThermalForcing";
+ 		case GeometryHydrostaticRatioEnum : return "GeometryHydrostaticRatio";
+ 		case NGiaEnum : return "NGia";
+ 		case NGiaRateEnum : return "NGiaRate";
+@@ -1107,6 +1106,7 @@
+ 		case TemperaturePicardEnum : return "TemperaturePicard";
+ 		case TemperatureSEMICEnum : return "TemperatureSEMIC";
+ 		case ThermalforcingARMANoiseEnum : return "ThermalforcingARMANoise";
++		case ThermalForcingEnum : return "ThermalForcing";
+ 		case ThermalforcingValuesAutoregressionEnum : return "ThermalforcingValuesAutoregression";
+ 		case ThermalforcingValuesMovingaverageEnum : return "ThermalforcingValuesMovingaverage";
+ 		case ThermalSpctemperatureEnum : return "ThermalSpctemperature";
+Index: ../trunk-jpl/src/c/shared/Enum/Enumjl.vim
+===================================================================
+--- ../trunk-jpl/src/c/shared/Enum/Enumjl.vim	(revision 27283)
++++ ../trunk-jpl/src/c/shared/Enum/Enumjl.vim	(revision 27284)
+@@ -768,7 +768,6 @@
+ syn keyword juliaConstC FrictionfEnum
+ syn keyword juliaConstC FrontalForcingsBasinIdEnum
+ syn keyword juliaConstC FrontalForcingsSubglacialDischargeEnum
+-syn keyword juliaConstC FrontalForcingsAndBasalforcingsThermalForcingEnum
+ syn keyword juliaConstC GeometryHydrostaticRatioEnum
+ syn keyword juliaConstC NGiaEnum
+ syn keyword juliaConstC NGiaRateEnum
+@@ -1098,6 +1097,7 @@
+ syn keyword juliaConstC TemperaturePicardEnum
+ syn keyword juliaConstC TemperatureSEMICEnum
+ syn keyword juliaConstC ThermalforcingARMANoiseEnum
++syn keyword juliaConstC ThermalForcingEnum
+ syn keyword juliaConstC ThermalforcingValuesAutoregressionEnum
+ syn keyword juliaConstC ThermalforcingValuesMovingaverageEnum
+ syn keyword juliaConstC ThermalSpctemperatureEnum
+Index: ../trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp
+===================================================================
+--- ../trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp	(revision 27283)
++++ ../trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp	(revision 27284)
+@@ -795,7 +795,6 @@
+ 	      else if (strcmp(name,"Frictionf")==0) return FrictionfEnum;
+ 	      else if (strcmp(name,"FrontalForcingsBasinId")==0) return FrontalForcingsBasinIdEnum;
+ 	      else if (strcmp(name,"FrontalForcingsSubglacialDischarge")==0) return FrontalForcingsSubglacialDischargeEnum;
+-	      else if (strcmp(name,"FrontalForcingsAndBasalforcingsThermalForcing")==0) return FrontalForcingsAndBasalforcingsThermalForcingEnum;
+ 	      else if (strcmp(name,"GeometryHydrostaticRatio")==0) return GeometryHydrostaticRatioEnum;
+ 	      else if (strcmp(name,"NGia")==0) return NGiaEnum;
+ 	      else if (strcmp(name,"NGiaRate")==0) return NGiaRateEnum;
+@@ -874,11 +873,11 @@
+ 	      else if (strcmp(name,"MeshVertexonsurface")==0) return MeshVertexonsurfaceEnum;
+ 	      else if (strcmp(name,"Misfit")==0) return MisfitEnum;
+ 	      else if (strcmp(name,"MovingFrontalVx")==0) return MovingFrontalVxEnum;
++	      else if (strcmp(name,"MovingFrontalVy")==0) return MovingFrontalVyEnum;
+          else stage=8;
+    }
+    if(stage==8){
+-	      if (strcmp(name,"MovingFrontalVy")==0) return MovingFrontalVyEnum;
+-	      else if (strcmp(name,"Neumannflux")==0) return NeumannfluxEnum;
++	      if (strcmp(name,"Neumannflux")==0) return NeumannfluxEnum;
+ 	      else if (strcmp(name,"NewDamage")==0) return NewDamageEnum;
+ 	      else if (strcmp(name,"Node")==0) return NodeEnum;
+ 	      else if (strcmp(name,"OmegaAbsGradient")==0) return OmegaAbsGradientEnum;
+@@ -997,11 +996,11 @@
+ 	      else if (strcmp(name,"SmbCcsnowValue")==0) return SmbCcsnowValueEnum;
+ 	      else if (strcmp(name,"SmbCciceValue")==0) return SmbCciceValueEnum;
+ 	      else if (strcmp(name,"SmbCotValue")==0) return SmbCotValueEnum;
++	      else if (strcmp(name,"SmbD")==0) return SmbDEnum;
+          else stage=9;
+    }
+    if(stage==9){
+-	      if (strcmp(name,"SmbD")==0) return SmbDEnum;
+-	      else if (strcmp(name,"SmbDailyairdensity")==0) return SmbDailyairdensityEnum;
++	      if (strcmp(name,"SmbDailyairdensity")==0) return SmbDailyairdensityEnum;
+ 	      else if (strcmp(name,"SmbDailyairhumidity")==0) return SmbDailyairhumidityEnum;
+ 	      else if (strcmp(name,"SmbDailydlradiation")==0) return SmbDailydlradiationEnum;
+ 	      else if (strcmp(name,"SmbDailydsradiation")==0) return SmbDailydsradiationEnum;
+@@ -1120,11 +1119,11 @@
+ 	      else if (strcmp(name,"SurfaceCrevasse")==0) return SurfaceCrevasseEnum;
+ 	      else if (strcmp(name,"Surface")==0) return SurfaceEnum;
+ 	      else if (strcmp(name,"SurfaceOld")==0) return SurfaceOldEnum;
++	      else if (strcmp(name,"SurfaceLogVelMisfit")==0) return SurfaceLogVelMisfitEnum;
+          else stage=10;
+    }
+    if(stage==10){
+-	      if (strcmp(name,"SurfaceLogVelMisfit")==0) return SurfaceLogVelMisfitEnum;
+-	      else if (strcmp(name,"SurfaceLogVxVyMisfit")==0) return SurfaceLogVxVyMisfitEnum;
++	      if (strcmp(name,"SurfaceLogVxVyMisfit")==0) return SurfaceLogVxVyMisfitEnum;
+ 	      else if (strcmp(name,"SurfaceObservation")==0) return SurfaceObservationEnum;
+ 	      else if (strcmp(name,"SurfaceRelVelMisfit")==0) return SurfaceRelVelMisfitEnum;
+ 	      else if (strcmp(name,"SurfaceSlopeX")==0) return SurfaceSlopeXEnum;
+@@ -1134,6 +1133,7 @@
+ 	      else if (strcmp(name,"TemperaturePicard")==0) return TemperaturePicardEnum;
+ 	      else if (strcmp(name,"TemperatureSEMIC")==0) return TemperatureSEMICEnum;
+ 	      else if (strcmp(name,"ThermalforcingARMANoise")==0) return ThermalforcingARMANoiseEnum;
++	      else if (strcmp(name,"ThermalForcing")==0) return ThermalForcingEnum;
+ 	      else if (strcmp(name,"ThermalforcingValuesAutoregression")==0) return ThermalforcingValuesAutoregressionEnum;
+ 	      else if (strcmp(name,"ThermalforcingValuesMovingaverage")==0) return ThermalforcingValuesMovingaverageEnum;
+ 	      else if (strcmp(name,"ThermalSpctemperature")==0) return ThermalSpctemperatureEnum;
Index: /issm/oecreview/Archive/27230-27343/ISSM-27284-27285.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27284-27285.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27284-27285.diff	(revision 27344)
@@ -0,0 +1,409 @@
+Index: ../trunk-jpl/src/c/analyses/LevelsetAnalysis.cpp
+===================================================================
+--- ../trunk-jpl/src/c/analyses/LevelsetAnalysis.cpp	(revision 27284)
++++ ../trunk-jpl/src/c/analyses/LevelsetAnalysis.cpp	(revision 27285)
+@@ -256,6 +256,9 @@
+          iomodel->FetchData(&transparam,&M,&N,"md.frontalforcings.malag_coefs");
+          parameters->AddObject(new DoubleMatParam(FrontalForcingsARMAmalagcoefsEnum,transparam,M,N));
+          xDelete<IssmDouble>(transparam);
++			iomodel->FetchData(&transparam,&M,&N,"md.frontalforcings.monthly_effects");
++         parameters->AddObject(new DoubleMatParam(ThermalForcingMonthlyEffectsEnum,transparam,M,N));
++         xDelete<IssmDouble>(transparam);
+ 			/*Do not break here, generic FrontalForcingsRignot parameters still to be retrieved*/
+ 		case FrontalForcingsRignotEnum:
+ 			parameters->AddObject(iomodel->CopyConstantObject("md.frontalforcings.num_basins",FrontalForcingsNumberofBasinsEnum));
+Index: ../trunk-jpl/src/c/classes/Elements/Element.cpp
+===================================================================
+--- ../trunk-jpl/src/c/classes/Elements/Element.cpp	(revision 27284)
++++ ../trunk-jpl/src/c/classes/Elements/Element.cpp	(revision 27285)
+@@ -2775,6 +2775,54 @@
+ 	this->AddInput(BasalforcingsFloatingiceMeltingRateEnum,values,P1Enum);
+ 
+ }/*}}}*/
++void       Element::MonthlyEffectBasin(IssmDouble* monthlyeff, int enum_type){/*{{{*/
++	
++	/*Variable declaration*/
++   const int numvertices = this->GetNumberOfVertices();
++	int basinid,mindex,basinenum_type,varenum_type;
++   IssmDouble time,fracyear,yts; 
++   IssmDouble monthsteps[12] = {0.,1./12,2./12,3./12,4./12,5./12,6./12,7./12,8./12,9./12,10./12,11./12};
++	IssmDouble* monthlyeff_b = xNew<IssmDouble>(12);
++   IssmDouble* varlist      = xNew<IssmDouble>(numvertices);
++
++	/*Get field-specific enums*/
++   switch(enum_type){
++      case(FrontalForcingsRignotarmaEnum):
++         basinenum_type = FrontalForcingsBasinIdEnum;
++         varenum_type   = ThermalForcingEnum;
++         break;
++	}
++	
++	/*Evaluate the month index*/
++	this->parameters->FindParam(&yts,ConstantsYtsEnum);
++	this->parameters->FindParam(&time,TimeEnum);
++	fracyear = time/yts-floor(time/yts);
++	for(int i=1;i<12;i++){
++		if(fracyear>=monthsteps[i-1]) mindex = i-1;
++	}
++	if(fracyear>=monthsteps[11])     mindex = 11;
++
++	/*Get basin-specific parameters of the element*/
++   this->GetInputValue(&basinid,basinenum_type);
++	for(int ii=0;ii<12;ii++){
++		monthlyeff_b[ii] = monthlyeff[basinid*12+ii];
++	}
++
++	/*Retrieve values non-adjusted for monthly effects*/
++   this->GetInputListOnVertices(varlist,varenum_type);
++
++	/*Adjust values using monthly effects*/
++	for(int v=0;v<numvertices;v++){
++		varlist[v] = varlist[v]+monthlyeff_b[mindex];
++	}
++
++	/*Add input to element*/
++   this->AddInput(varenum_type,varlist,P1Enum);
++
++	/*Clean-up*/
++   xDelete<IssmDouble>(monthlyeff_b);
++	xDelete<IssmDouble>(varlist);
++}/*}}}*/
+ void       Element::BeckmannGoosseFloatingiceMeltingRate(){/*{{{*/
+ 
+ 	bool isthermalforcing;       
+Index: ../trunk-jpl/src/c/classes/Elements/Element.h
+===================================================================
+--- ../trunk-jpl/src/c/classes/Elements/Element.h	(revision 27284)
++++ ../trunk-jpl/src/c/classes/Elements/Element.h	(revision 27285)
+@@ -163,6 +163,7 @@
+ 		void               MarshallElement2(MarshallHandle* marshallhandle,int numanalyses);
+ 		void               MigrateGroundingLine(IssmDouble* sheet_ungrounding);
+ 		void               MismipFloatingiceMeltingRate();
++		void               MonthlyEffectBasin(IssmDouble* monthlyeff, int enum_type); 
+ 		void               BeckmannGoosseFloatingiceMeltingRate();
+ 		void               MungsmtpParameterization(void);
+ 		ElementMatrix*     NewElementMatrix(int approximation_enum=NoneApproximationEnum);
+Index: ../trunk-jpl/src/c/modules/FrontalForcingsx/FrontalForcingsx.cpp
+===================================================================
+--- ../trunk-jpl/src/c/modules/FrontalForcingsx/FrontalForcingsx.cpp	(revision 27284)
++++ ../trunk-jpl/src/c/modules/FrontalForcingsx/FrontalForcingsx.cpp	(revision 27285)
+@@ -58,6 +58,7 @@
+    IssmDouble* trend         = NULL;
+    IssmDouble* arlagcoefs    = NULL;
+    IssmDouble* malagcoefs    = NULL;
++   IssmDouble* monthlyeff    = NULL;
+ 
+ 	femmodel->parameters->FindParam(&tinit_arma,FrontalForcingsARMAInitialTimeEnum);
+    femmodel->parameters->FindParam(&termconstant,&M,FrontalForcingsARMAconstEnum);                  _assert_(M==numbasins);
+@@ -64,6 +65,7 @@
+    femmodel->parameters->FindParam(&trend,&M,FrontalForcingsARMAtrendEnum);                         _assert_(M==numbasins);
+    femmodel->parameters->FindParam(&arlagcoefs,&M,&Narlagcoefs,FrontalForcingsARMAarlagcoefsEnum);  _assert_(M==numbasins); _assert_(Narlagcoefs==arorder);
+    femmodel->parameters->FindParam(&malagcoefs,&M,&Nmalagcoefs,FrontalForcingsARMAmalagcoefsEnum);  _assert_(M==numbasins); _assert_(Nmalagcoefs==maorder);
++   femmodel->parameters->FindParam(&monthlyeff,&M,&N,ThermalForcingMonthlyEffectsEnum);             _assert_(M==numbasins); _assert_(N==12); 
+ 
+ 	femmodel->parameters->FindParam(&isstochastic,StochasticForcingIsStochasticForcingEnum);
+ 	if(isstochastic){
+@@ -82,8 +84,11 @@
+    /*Loop over each element to compute Thermal Forcing at vertices*/
+    for(Object* &object:femmodel->elements->objects){
+       Element* element = xDynamicCast<Element*>(object);
++		/*Compute ARMA*/
+       element->ArmaProcess(isstepforarma,arorder,maorder,telapsed_arma,tstep_arma,termconstant,trend,arlagcoefs,malagcoefs,istfstochastic,FrontalForcingsRignotarmaEnum);
+-   }
++		/*Compute monthly effects*/
++		element->MonthlyEffectBasin(monthlyeff,FrontalForcingsRignotarmaEnum);
++	}
+ 
+    /*Cleanup*/
+    xDelete<IssmDouble>(termconstant);
+@@ -90,4 +95,5 @@
+    xDelete<IssmDouble>(trend);
+    xDelete<IssmDouble>(arlagcoefs);
+    xDelete<IssmDouble>(malagcoefs);
++   xDelete<IssmDouble>(monthlyeff);
+ }/*}}}*/
+Index: ../trunk-jpl/src/c/shared/Enum/Enum.vim
+===================================================================
+--- ../trunk-jpl/src/c/shared/Enum/Enum.vim	(revision 27284)
++++ ../trunk-jpl/src/c/shared/Enum/Enum.vim	(revision 27285)
+@@ -563,6 +563,7 @@
+ syn keyword cConstant StressbalanceRestolEnum
+ syn keyword cConstant StressbalanceRiftPenaltyThresholdEnum
+ syn keyword cConstant StressbalanceShelfDampeningEnum
++syn keyword cConstant ThermalForcingMonthlyEffectsEnum
+ syn keyword cConstant ThermalIsdrainicecolumnEnum
+ syn keyword cConstant ThermalIsdynamicbasalspcEnum
+ syn keyword cConstant ThermalIsenthalpyEnum
+Index: ../trunk-jpl/src/c/shared/Enum/EnumDefinitions.h
+===================================================================
+--- ../trunk-jpl/src/c/shared/Enum/EnumDefinitions.h	(revision 27284)
++++ ../trunk-jpl/src/c/shared/Enum/EnumDefinitions.h	(revision 27285)
+@@ -557,6 +557,7 @@
+ 	StressbalanceRestolEnum,
+ 	StressbalanceRiftPenaltyThresholdEnum,
+ 	StressbalanceShelfDampeningEnum,
++   ThermalForcingMonthlyEffectsEnum,
+ 	ThermalIsdrainicecolumnEnum,
+ 	ThermalIsdynamicbasalspcEnum,
+ 	ThermalIsenthalpyEnum,
+Index: ../trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp
+===================================================================
+--- ../trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp	(revision 27284)
++++ ../trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp	(revision 27285)
+@@ -565,6 +565,7 @@
+ 		case StressbalanceRestolEnum : return "StressbalanceRestol";
+ 		case StressbalanceRiftPenaltyThresholdEnum : return "StressbalanceRiftPenaltyThreshold";
+ 		case StressbalanceShelfDampeningEnum : return "StressbalanceShelfDampening";
++		case ThermalForcingMonthlyEffectsEnum : return "ThermalForcingMonthlyEffects";
+ 		case ThermalIsdrainicecolumnEnum : return "ThermalIsdrainicecolumn";
+ 		case ThermalIsdynamicbasalspcEnum : return "ThermalIsdynamicbasalspc";
+ 		case ThermalIsenthalpyEnum : return "ThermalIsenthalpy";
+Index: ../trunk-jpl/src/c/shared/Enum/Enumjl.vim
+===================================================================
+--- ../trunk-jpl/src/c/shared/Enum/Enumjl.vim	(revision 27284)
++++ ../trunk-jpl/src/c/shared/Enum/Enumjl.vim	(revision 27285)
+@@ -556,6 +556,7 @@
+ syn keyword juliaConstC StressbalanceRestolEnum
+ syn keyword juliaConstC StressbalanceRiftPenaltyThresholdEnum
+ syn keyword juliaConstC StressbalanceShelfDampeningEnum
++syn keyword juliaConstC ThermalForcingMonthlyEffectsEnum
+ syn keyword juliaConstC ThermalIsdrainicecolumnEnum
+ syn keyword juliaConstC ThermalIsdynamicbasalspcEnum
+ syn keyword juliaConstC ThermalIsenthalpyEnum
+Index: ../trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp
+===================================================================
+--- ../trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp	(revision 27284)
++++ ../trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp	(revision 27285)
+@@ -577,6 +577,7 @@
+ 	      else if (strcmp(name,"StressbalanceRestol")==0) return StressbalanceRestolEnum;
+ 	      else if (strcmp(name,"StressbalanceRiftPenaltyThreshold")==0) return StressbalanceRiftPenaltyThresholdEnum;
+ 	      else if (strcmp(name,"StressbalanceShelfDampening")==0) return StressbalanceShelfDampeningEnum;
++	      else if (strcmp(name,"ThermalForcingMonthlyEffects")==0) return ThermalForcingMonthlyEffectsEnum;
+ 	      else if (strcmp(name,"ThermalIsdrainicecolumn")==0) return ThermalIsdrainicecolumnEnum;
+ 	      else if (strcmp(name,"ThermalIsdynamicbasalspc")==0) return ThermalIsdynamicbasalspcEnum;
+ 	      else if (strcmp(name,"ThermalIsenthalpy")==0) return ThermalIsenthalpyEnum;
+@@ -627,11 +628,11 @@
+ 	      else if (strcmp(name,"Velocity")==0) return VelocityEnum;
+ 	      else if (strcmp(name,"Xxe")==0) return XxeEnum;
+ 	      else if (strcmp(name,"Yye")==0) return YyeEnum;
+-	      else if (strcmp(name,"Zze")==0) return ZzeEnum;
+          else stage=6;
+    }
+    if(stage==6){
+-	      if (strcmp(name,"Areae")==0) return AreaeEnum;
++	      if (strcmp(name,"Zze")==0) return ZzeEnum;
++	      else if (strcmp(name,"Areae")==0) return AreaeEnum;
+ 	      else if (strcmp(name,"WorldComm")==0) return WorldCommEnum;
+ 	      else if (strcmp(name,"ParametersEND")==0) return ParametersENDEnum;
+ 	      else if (strcmp(name,"InputsSTART")==0) return InputsSTARTEnum;
+@@ -750,11 +751,11 @@
+ 	      else if (strcmp(name,"DragCoefficientAbsGradient")==0) return DragCoefficientAbsGradientEnum;
+ 	      else if (strcmp(name,"DrivingStressX")==0) return DrivingStressXEnum;
+ 	      else if (strcmp(name,"DrivingStressY")==0) return DrivingStressYEnum;
+-	      else if (strcmp(name,"Dummy")==0) return DummyEnum;
+          else stage=7;
+    }
+    if(stage==7){
+-	      if (strcmp(name,"EffectivePressure")==0) return EffectivePressureEnum;
++	      if (strcmp(name,"Dummy")==0) return DummyEnum;
++	      else if (strcmp(name,"EffectivePressure")==0) return EffectivePressureEnum;
+ 	      else if (strcmp(name,"EffectivePressureSubstep")==0) return EffectivePressureSubstepEnum;
+ 	      else if (strcmp(name,"EffectivePressureTransient")==0) return EffectivePressureTransientEnum;
+ 	      else if (strcmp(name,"Enthalpy")==0) return EnthalpyEnum;
+@@ -873,11 +874,11 @@
+ 	      else if (strcmp(name,"MeshVertexonsurface")==0) return MeshVertexonsurfaceEnum;
+ 	      else if (strcmp(name,"Misfit")==0) return MisfitEnum;
+ 	      else if (strcmp(name,"MovingFrontalVx")==0) return MovingFrontalVxEnum;
+-	      else if (strcmp(name,"MovingFrontalVy")==0) return MovingFrontalVyEnum;
+          else stage=8;
+    }
+    if(stage==8){
+-	      if (strcmp(name,"Neumannflux")==0) return NeumannfluxEnum;
++	      if (strcmp(name,"MovingFrontalVy")==0) return MovingFrontalVyEnum;
++	      else if (strcmp(name,"Neumannflux")==0) return NeumannfluxEnum;
+ 	      else if (strcmp(name,"NewDamage")==0) return NewDamageEnum;
+ 	      else if (strcmp(name,"Node")==0) return NodeEnum;
+ 	      else if (strcmp(name,"OmegaAbsGradient")==0) return OmegaAbsGradientEnum;
+@@ -996,11 +997,11 @@
+ 	      else if (strcmp(name,"SmbCcsnowValue")==0) return SmbCcsnowValueEnum;
+ 	      else if (strcmp(name,"SmbCciceValue")==0) return SmbCciceValueEnum;
+ 	      else if (strcmp(name,"SmbCotValue")==0) return SmbCotValueEnum;
+-	      else if (strcmp(name,"SmbD")==0) return SmbDEnum;
+          else stage=9;
+    }
+    if(stage==9){
+-	      if (strcmp(name,"SmbDailyairdensity")==0) return SmbDailyairdensityEnum;
++	      if (strcmp(name,"SmbD")==0) return SmbDEnum;
++	      else if (strcmp(name,"SmbDailyairdensity")==0) return SmbDailyairdensityEnum;
+ 	      else if (strcmp(name,"SmbDailyairhumidity")==0) return SmbDailyairhumidityEnum;
+ 	      else if (strcmp(name,"SmbDailydlradiation")==0) return SmbDailydlradiationEnum;
+ 	      else if (strcmp(name,"SmbDailydsradiation")==0) return SmbDailydsradiationEnum;
+@@ -1119,11 +1120,11 @@
+ 	      else if (strcmp(name,"SurfaceCrevasse")==0) return SurfaceCrevasseEnum;
+ 	      else if (strcmp(name,"Surface")==0) return SurfaceEnum;
+ 	      else if (strcmp(name,"SurfaceOld")==0) return SurfaceOldEnum;
+-	      else if (strcmp(name,"SurfaceLogVelMisfit")==0) return SurfaceLogVelMisfitEnum;
+          else stage=10;
+    }
+    if(stage==10){
+-	      if (strcmp(name,"SurfaceLogVxVyMisfit")==0) return SurfaceLogVxVyMisfitEnum;
++	      if (strcmp(name,"SurfaceLogVelMisfit")==0) return SurfaceLogVelMisfitEnum;
++	      else if (strcmp(name,"SurfaceLogVxVyMisfit")==0) return SurfaceLogVxVyMisfitEnum;
+ 	      else if (strcmp(name,"SurfaceObservation")==0) return SurfaceObservationEnum;
+ 	      else if (strcmp(name,"SurfaceRelVelMisfit")==0) return SurfaceRelVelMisfitEnum;
+ 	      else if (strcmp(name,"SurfaceSlopeX")==0) return SurfaceSlopeXEnum;
+@@ -1242,11 +1243,11 @@
+ 	      else if (strcmp(name,"Outputdefinition67")==0) return Outputdefinition67Enum;
+ 	      else if (strcmp(name,"Outputdefinition68")==0) return Outputdefinition68Enum;
+ 	      else if (strcmp(name,"Outputdefinition69")==0) return Outputdefinition69Enum;
+-	      else if (strcmp(name,"Outputdefinition6")==0) return Outputdefinition6Enum;
+          else stage=11;
+    }
+    if(stage==11){
+-	      if (strcmp(name,"Outputdefinition70")==0) return Outputdefinition70Enum;
++	      if (strcmp(name,"Outputdefinition6")==0) return Outputdefinition6Enum;
++	      else if (strcmp(name,"Outputdefinition70")==0) return Outputdefinition70Enum;
+ 	      else if (strcmp(name,"Outputdefinition71")==0) return Outputdefinition71Enum;
+ 	      else if (strcmp(name,"Outputdefinition72")==0) return Outputdefinition72Enum;
+ 	      else if (strcmp(name,"Outputdefinition73")==0) return Outputdefinition73Enum;
+@@ -1365,11 +1366,11 @@
+ 	      else if (strcmp(name,"DoubleVecParam")==0) return DoubleVecParamEnum;
+ 	      else if (strcmp(name,"Element")==0) return ElementEnum;
+ 	      else if (strcmp(name,"ElementHook")==0) return ElementHookEnum;
+-	      else if (strcmp(name,"ElementSId")==0) return ElementSIdEnum;
+          else stage=12;
+    }
+    if(stage==12){
+-	      if (strcmp(name,"EnthalpyAnalysis")==0) return EnthalpyAnalysisEnum;
++	      if (strcmp(name,"ElementSId")==0) return ElementSIdEnum;
++	      else if (strcmp(name,"EnthalpyAnalysis")==0) return EnthalpyAnalysisEnum;
+ 	      else if (strcmp(name,"EsaAnalysis")==0) return EsaAnalysisEnum;
+ 	      else if (strcmp(name,"EsaSolution")==0) return EsaSolutionEnum;
+ 	      else if (strcmp(name,"EsaTransitions")==0) return EsaTransitionsEnum;
+@@ -1488,11 +1489,11 @@
+ 	      else if (strcmp(name,"Masscon")==0) return MassconEnum;
+ 	      else if (strcmp(name,"Massconaxpby")==0) return MassconaxpbyEnum;
+ 	      else if (strcmp(name,"Massfluxatgate")==0) return MassfluxatgateEnum;
+-	      else if (strcmp(name,"MasstransportAnalysis")==0) return MasstransportAnalysisEnum;
+          else stage=13;
+    }
+    if(stage==13){
+-	      if (strcmp(name,"MasstransportSolution")==0) return MasstransportSolutionEnum;
++	      if (strcmp(name,"MasstransportAnalysis")==0) return MasstransportAnalysisEnum;
++	      else if (strcmp(name,"MasstransportSolution")==0) return MasstransportSolutionEnum;
+ 	      else if (strcmp(name,"Matdamageice")==0) return MatdamageiceEnum;
+ 	      else if (strcmp(name,"Matenhancedice")==0) return MatenhancediceEnum;
+ 	      else if (strcmp(name,"Materials")==0) return MaterialsEnum;
+@@ -1611,11 +1612,11 @@
+ 	      else if (strcmp(name,"SmbSolution")==0) return SmbSolutionEnum;
+ 	      else if (strcmp(name,"SmoothAnalysis")==0) return SmoothAnalysisEnum;
+ 	      else if (strcmp(name,"SoftMigration")==0) return SoftMigrationEnum;
+-	      else if (strcmp(name,"SpatialLinearFloatingMeltRate")==0) return SpatialLinearFloatingMeltRateEnum;
+          else stage=14;
+    }
+    if(stage==14){
+-	      if (strcmp(name,"SpcDynamic")==0) return SpcDynamicEnum;
++	      if (strcmp(name,"SpatialLinearFloatingMeltRate")==0) return SpatialLinearFloatingMeltRateEnum;
++	      else if (strcmp(name,"SpcDynamic")==0) return SpcDynamicEnum;
+ 	      else if (strcmp(name,"SpcStatic")==0) return SpcStaticEnum;
+ 	      else if (strcmp(name,"SpcTransient")==0) return SpcTransientEnum;
+ 	      else if (strcmp(name,"Sset")==0) return SsetEnum;
+Index: ../trunk-jpl/src/m/classes/frontalforcingsrignotarma.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/frontalforcingsrignotarma.m	(revision 27284)
++++ ../trunk-jpl/src/m/classes/frontalforcingsrignotarma.m	(revision 27285)
+@@ -14,6 +14,7 @@
+ 		arma_timestep        = 0;
+ 		arlag_coefs          = NaN;
+ 		malag_coefs          = NaN;
++		monthly_effects      = NaN;
+ 		basin_id             = NaN;
+ 		subglacial_discharge = NaN;
+ 	end
+@@ -63,6 +64,12 @@
+          md = checkfield(md,'fieldname','frontalforcings.arma_timestep','numel',1,'NaN',1,'Inf',1,'>=',md.timestepping.time_step); %ARMA time step cannot be finer than ISSM timestep
+ 			md = checkfield(md,'fieldname','frontalforcings.arlag_coefs','NaN',1,'Inf',1,'size',[md.frontalforcings.num_basins,md.frontalforcings.ar_order]);
+ 			md = checkfield(md,'fieldname','frontalforcings.malag_coefs','NaN',1,'Inf',1,'size',[md.frontalforcings.num_basins,md.frontalforcings.ma_order]);
++			if(any(~isnan(md.frontalforcings.monthly_effects)))
++				md = checkfield(md,'fieldname','frontalforcings.monthly_effects','NaN',1,'Inf',1,'size',[md.frontalforcings.num_basins,12]);
++				if(md.timestepping.time_step>=1)
++					error('md.frontalforcings.monthly_effects are provided but md.timestepping.time_step>=1');
++				end
++			end
+ 
+ 		end % }}}
+ 		function disp(self) % {{{
+@@ -78,9 +85,16 @@
+          fielddisplay(self,'arma_timestep','time resolution of the autoregressive model [yr]');
+          fielddisplay(self,'arlag_coefs','basin-specific vectors of AR lag coefficients [unitless]');
+          fielddisplay(self,'malag_coefs','basin-specific vectors of MA lag coefficients [unitless]');
++         fielddisplay(self,'monthly_effects','basin-specific monthly values of TF added at corresponding month (default: all 0) [°C]');
+ 		end % }}}
+ 		function marshall(self,prefix,md,fid) % {{{
+ 			yts=md.constants.yts;
++			if(any(isnan(md.frontalforcings.monthly_effects))) %monthly effects not provided, set to 0
++				meffects = zeros(md.frontalforcings.num_basins,12);
++			else
++				meffects = md.frontalforcings.monthly_effects;
++			end
++
+ 			WriteData(fid,prefix,'name','md.frontalforcings.parameterization','data',3,'format','Integer');
+ 			WriteData(fid,prefix,'object',self,'class','frontalforcings','fieldname','num_basins','format','Integer');
+ 			WriteData(fid,prefix,'object',self,'class','frontalforcings','fieldname','subglacial_discharge','format','DoubleMat','mattype',1,'timeserieslength',md.mesh.numberofvertices+1,'yts',yts);
+@@ -93,6 +107,7 @@
+          WriteData(fid,prefix,'object',self,'class','frontalforcings','fieldname','trend','format','DoubleMat','name','md.frontalforcings.trend','scale',1./yts,'yts',yts);
+          WriteData(fid,prefix,'object',self,'class','frontalforcings','fieldname','arlag_coefs','format','DoubleMat','name','md.frontalforcings.arlag_coefs','yts',yts);
+          WriteData(fid,prefix,'object',self,'class','frontalforcings','fieldname','malag_coefs','format','DoubleMat','name','md.frontalforcings.malag_coefs','yts',yts);
++         WriteData(fid,prefix,'data',meffects,'name','md.frontalforcings.monthly_effects','format','DoubleMat');
+ 		end % }}}
+ 	end
+ end
+Index: ../trunk-jpl/src/m/classes/frontalforcingsrignotarma.py
+===================================================================
+--- ../trunk-jpl/src/m/classes/frontalforcingsrignotarma.py	(revision 27284)
++++ ../trunk-jpl/src/m/classes/frontalforcingsrignotarma.py	(revision 27285)
+@@ -21,6 +21,8 @@
+         self.arma_initialtime = 0
+         self.arma_timestep = 0
+         self.arlag_coefs = np.nan
++        self.malag_coefs = np.nan
++        self.monthly_effects = np.nan
+         self.basin_id = np.nan
+         self.subglacial_discharge = np.nan
+ 
+@@ -42,6 +44,7 @@
+         s += '{}\n'.format(fielddisplay(self, 'arma_timestep', 'time resolution of the ARMA model [yr]'))
+         s += '{}\n'.format(fielddisplay(self, 'arlag_coefs', 'basin-specific vectors of AR lag coefficients [unitless]'))
+         s += '{}\n'.format(fielddisplay(self, 'malag_coefs', 'basin-specific vectors of MA lag coefficients [unitless]'))
++        s += '{}\n'.format(fielddisplay(self, 'monthly_effects', 'basin-specific monthly values of TF added at corresponding month (default: all 0) [°C]'))
+         return s
+     #}}}
+ 
+@@ -73,6 +76,10 @@
+         md = checkfield(md, 'fieldname', 'frontalforcings.arma_timestep', 'numel', 1, 'NaN', 1, 'Inf', 1, '>=', md.timestepping.time_step) # ARMA time step cannot be finer than ISSM timestep
+         md = checkfield(md, 'fieldname', 'frontalforcings.arlag_coefs', 'NaN', 1, 'Inf', 1, 'size', [md.frontalforcings.num_basins, md.frontalforcings.ar_order])
+         md = checkfield(md, 'fieldname', 'frontalforcings.malag_coefs', 'NaN', 1, 'Inf', 1, 'size', [md.frontalforcings.num_basins, md.frontalforcings.ma_order])
++        if(np.any(np.isnan(md.frontalforcings.monthly_effects)==False)):
++            md = checkfield(md, 'fieldname', 'frontalforcings.monthly_effects', 'NaN', 1, 'Inf', 1, 'size', [md.frontalforcings.num_basins, 12])
++            if(md.timestepping.time_step>=1):
++                raise RuntimeError('md.frontalforcings.monthly_effects are provided but md.timestepping.time_step>=1')
+         return md
+     # }}}
+ 
+@@ -83,6 +90,10 @@
+ 
+     def marshall(self, prefix, md, fid):  # {{{
+         yts = md.constants.yts
++        if(np.any(np.isnan(md.frontalforcings.monthly_effects))): #monthly effects not provided, set to 0
++            meffects = np.zeros((md.frontalforcings.num_basins,12))
++        else:
++            meffects = 1*md.frontalforcings.monthly_effects
+         WriteData(fid, prefix, 'name', 'md.frontalforcings.parameterization', 'data', 3, 'format', 'Integer')
+         WriteData(fid, prefix, 'object', self, 'class', 'frontalforcings', 'fieldname', 'num_basins', 'format', 'Integer')
+         WriteData(fid, prefix, 'object', self, 'class', 'frontalforcings', 'fieldname', 'subglacial_discharge', 'format', 'DoubleMat', 'mattype', 1, 'timeserieslength', md.mesh.numberofvertices + 1, 'yts', yts)
+@@ -95,4 +106,5 @@
+         WriteData(fid, prefix, 'object', self, 'class', 'frontalforcings', 'fieldname', 'trend', 'format', 'DoubleMat', 'name', 'md.frontalforcings.trend', 'scale', 1 / yts, 'yts', yts)
+         WriteData(fid, prefix, 'object', self, 'class', 'frontalforcings', 'fieldname', 'arlag_coefs', 'format', 'DoubleMat', 'name', 'md.frontalforcings.arlag_coefs', 'yts', yts)
+         WriteData(fid, prefix, 'object', self, 'class', 'frontalforcings', 'fieldname', 'malag_coefs', 'format', 'DoubleMat', 'name', 'md.frontalforcings.malag_coefs', 'yts', yts)
++        WriteData(fid, prefix, 'data', meffects, 'name', 'md.frontalforcings.monthly_effects', 'format', 'DoubleMat')
+     # }}}
Index: /issm/oecreview/Archive/27230-27343/ISSM-27285-27286.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27285-27286.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27285-27286.diff	(revision 27344)
@@ -0,0 +1,57 @@
+Index: ../trunk-jpl/src/m/classes/calvingpollard.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/calvingpollard.m	(nonexistent)
++++ ../trunk-jpl/src/m/classes/calvingpollard.m	(revision 27286)
+@@ -0,0 +1,52 @@
++%CALVINGPOLLARD class definition
++%
++%   Usage:
++%      calvingpollard=calvingpollard();
++
++classdef calvingpollard
++	properties (SetAccess=public) 
++		rc = 0.;
++	end
++	methods
++		function self = calvingpollard(varargin) % {{{
++			switch nargin
++				case 0
++					self=setdefaultparameters(self);
++				case 1
++					inputstruct=varargin{1};
++					list1 = properties('calvingpollard');
++					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 self = extrude(self,md) % {{{
++			return;
++		end % }}}
++		function self = setdefaultparameters(self) % {{{
++
++			%Default from Pollard and DeConto 2015
++			self.rc = .75;
++		end % }}}
++		function md = checkconsistency(self,md,solution,analyses) % {{{
++			%Early return
++			if (~strcmp(solution,'TransientSolution') | md.transient.ismovingfront==0), return; end
++
++			md = checkfield(md,'fieldname','calving.rc','>',0,'<=',1,'numel',1);
++		end % }}}
++		function disp(self) % {{
++			disp(sprintf('   Calving Pollard and DeConto parameters:'));
++			fielddisplay(self,'rc','critical depth/thickness ratio (default is 0.75) ');
++		end % }}}
++		function marshall(self,prefix,md,fid) % {{{
++			WriteData(fid,prefix,'name','md.calving.law','data',10,'format','Integer');
++			WriteData(fid,prefix,'object',self,'fieldname','rc','format','Double');
++		end % }}}
++	end
++end
Index: /issm/oecreview/Archive/27230-27343/ISSM-27286-27287.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27286-27287.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27286-27287.diff	(revision 27344)
@@ -0,0 +1,584 @@
+Index: ../trunk-jpl/src/c/analyses/LevelsetAnalysis.cpp
+===================================================================
+--- ../trunk-jpl/src/c/analyses/LevelsetAnalysis.cpp	(revision 27286)
++++ ../trunk-jpl/src/c/analyses/LevelsetAnalysis.cpp	(revision 27287)
+@@ -132,6 +132,8 @@
+ 			iomodel->ConstantToInput(inputs,elements,0.,CalvingratexEnum,P1Enum);
+ 			iomodel->ConstantToInput(inputs,elements,0.,CalvingrateyEnum,P1Enum);
+ 			break;
++		case CalvingPollardEnum:
++			break;
+ 
+ 		default:
+ 			_error_("Calving law "<<EnumToStringx(calvinglaw)<<" not supported yet");
+@@ -228,6 +230,9 @@
+ 			parameters->AddObject(iomodel->CopyConstantObject("md.calving.vel_threshold",CalvingVelThresholdEnum));
+ 			parameters->AddObject(iomodel->CopyConstantObject("md.calving.vel_upperbound",CalvingVelUpperboundEnum));
+ 			break;
++		case CalvingPollardEnum:
++			parameters->AddObject(iomodel->CopyConstantObject("md.calving.rc",CalvingRcEnum));
++			break;
+ 		default:
+ 			_error_("Calving law "<<EnumToStringx(calvinglaw)<<" not supported yet");
+ 	}
+Index: ../trunk-jpl/src/c/classes/Elements/Element.cpp
+===================================================================
+--- ../trunk-jpl/src/c/classes/Elements/Element.cpp	(revision 27286)
++++ ../trunk-jpl/src/c/classes/Elements/Element.cpp	(revision 27287)
+@@ -296,7 +296,7 @@
+ 
+    this->AddInput(BasalforcingsFloatingiceMeltingRateEnum,&values[0],P1Enum);
+ }/*}}}*/
+-void       Element::CalvingFromRate(){/*{{{*/
++void       Element::CalvingRateToVector(){/*{{{*/
+ 
+ 	/*We are provided a calving rate, figure out the x/y components*/
+ 	int         dim,domaintype;
+@@ -3694,6 +3694,9 @@
+ 													  case CalvingLevermannEnum:
+ 														  this->CalvingRateLevermann();
+ 														  break;
++													  case CalvingPollardEnum:
++														  this->CalvingPollard();
++														  break;
+ 													  case CalvingVonmisesEnum:
+ 													  case CalvingDev2Enum:
+ 														  this->CalvingRateVonmises();
+Index: ../trunk-jpl/src/c/classes/Elements/Element.h
+===================================================================
+--- ../trunk-jpl/src/c/classes/Elements/Element.h	(revision 27286)
++++ ../trunk-jpl/src/c/classes/Elements/Element.h	(revision 27287)
+@@ -71,7 +71,7 @@
+       void               Autoregression(bool isstepforar,int arorder,IssmDouble telapsed_ar,IssmDouble tstep_ar,IssmDouble* termconstant,IssmDouble* trend,IssmDouble* lagcoefs,bool isfieldstochastic,int enum_type);
+ 		void               BasinLinearFloatingiceMeltingRate(IssmDouble* deepwaterel,IssmDouble* upperwatermelt,IssmDouble* upperwaterel,IssmDouble* perturbation);
+ 		void               CalvingSetZeroRate(void);
+-		void               CalvingFromRate(void);
++		void               CalvingRateToVector(void);
+ 		void               ComputeLambdaS(void);
+ 		void               ComputeNewDamage();
+ 		void               ComputeStrainRate();
+@@ -237,6 +237,7 @@
+ 		virtual void       CalvingRateTest(void){_error_("not implemented yet");};
+ 		virtual void       CalvingCrevasseDepth(void){_error_("not implemented yet");};
+ 		virtual void	    CalvingRateLevermann(void)=0;
++		virtual void	    CalvingPollard(void){_error_("not implemented yet");};
+ 		virtual void       CalvingFluxLevelset(void){_error_("not implemented yet");};
+ 		virtual void       CalvingMeltingFluxLevelset(void){_error_("not implemented yet");};
+ 		virtual IssmDouble CharacteristicLength(void)=0;
+Index: ../trunk-jpl/src/c/classes/Elements/Penta.cpp
+===================================================================
+--- ../trunk-jpl/src/c/classes/Elements/Penta.cpp	(revision 27286)
++++ ../trunk-jpl/src/c/classes/Elements/Penta.cpp	(revision 27287)
+@@ -323,7 +323,7 @@
+ 
+ 	/*Add input*/
+ 	this->AddBasalInput(CalvingCalvingrateEnum,&calvingrate[0],P1DGEnum);
+-	this->CalvingFromRate();
++	this->CalvingRateToVector();
+ 
+ 	/*Extrude*/
+ 	this->InputExtrude(CalvingCalvingrateEnum,-1);
+@@ -364,7 +364,7 @@
+ 
+ 	/*Add input*/
+ 	this->AddBasalInput(CalvingCalvingrateEnum,&calvingrate[0],P1DGEnum);
+-	this->CalvingFromRate();
++	this->CalvingRateToVector();
+ }/*}}}*/
+ void       Penta::CalvingFluxLevelset(){/*{{{*/
+ 
+Index: ../trunk-jpl/src/c/classes/Elements/Tria.cpp
+===================================================================
+--- ../trunk-jpl/src/c/classes/Elements/Tria.cpp	(revision 27286)
++++ ../trunk-jpl/src/c/classes/Elements/Tria.cpp	(revision 27287)
+@@ -363,7 +363,7 @@
+ 
+ 	/*Add input*/
+ 	this->AddInput(CalvingCalvingrateEnum,&calvingrate[0],P1DGEnum);
+-   this->CalvingFromRate();
++   this->CalvingRateToVector();
+ }
+ /*}}}*/
+ void       Tria::CalvingRateTest(){/*{{{*/
+@@ -557,8 +557,96 @@
+ 
+ 	/*Add input*/
+ 	this->AddInput(CalvingCalvingrateEnum,&calvingrate[0],P1DGEnum);
+-	this->CalvingFromRate();
++	this->CalvingRateToVector();
+ }/*}}}*/
++void       Tria::CalvingPollard(){/*{{{*/
++
++	/*Intermediaries*/
++	IssmDouble calvingrate[NUMVERTICES];
++	IssmDouble xyz_list[NUMVERTICES][3];
++	IssmDouble dvx[2], dvy[2];
++	IssmDouble B, n, H, bed, vx, vy, vel, smb;
++	IssmDouble ds, db, da, dt, dw, r, R;
++
++	/*Retrieve all inputs and parameters we will need*/
++	IssmDouble rc        = FindParam(CalvingRcEnum);
++	IssmDouble rho_ice   = FindParam(MaterialsRhoIceEnum);
++	IssmDouble rho_water = FindParam(MaterialsRhoSeawaterEnum);
++	IssmDouble gravity   = FindParam(ConstantsGEnum);
++   IssmDouble mig_max   = FindParam(MigrationMaxEnum);
++
++	/*Retrieve all inputs and parameters we will need */
++	Input *bs_input  = this->GetInput(BaseEnum);                  _assert_(bs_input);
++	Input *vx_input  = this->GetInput(VxEnum);                    _assert_(vx_input);
++	Input *vy_input  = this->GetInput(VyEnum);                    _assert_(vy_input);
++	Input *B_input   = this->GetInput(MaterialsRheologyBbarEnum); _assert_(B_input);
++	Input *n_input   = this->GetInput(MaterialsRheologyNEnum);    _assert_(n_input);
++	Input *H_input   = this->GetInput(ThicknessEnum);             _assert_(H_input);
++	Input *smb_input = this->GetInput(SmbMassBalanceEnum);        _assert_(smb_input);
++
++	/* Start looping on the number of vertices: */
++	GaussTria gauss;
++	for (int iv=0;iv<NUMVERTICES;iv++){
++		gauss.GaussVertex(iv);
++
++		/* Get the value we need*/
++		bs_input->GetInputValue(&bed,&gauss);
++
++		/*Only calve if bed is below sea level, as always*/
++		if(bed<=0.){
++
++			/*Get Triangle node coordinates*/
++			::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
++
++			/*Get strain rates*/
++			vx_input->GetInputDerivativeValue(&dvx[0],&xyz_list[0][0],&gauss);
++			vy_input->GetInputDerivativeValue(&dvy[0],&xyz_list[0][0],&gauss);
++
++			/*Get other inputs*/
++			B_input->GetInputValue(&B,&gauss);
++         n_input->GetInputValue(&n,&gauss);
++         H_input->GetInputValue(&H,&gauss);
++         vx_input->GetInputValue(&vx,&gauss);
++         vy_input->GetInputValue(&vy,&gauss);
++         smb_input->GetInputValue(&smb,&gauss);
++
++			/*1. with surface crevasses, ds*/
++			ds = 2./(rho_ice*gravity) * B * pow( max(0.,dvx[0]) + max(0.,dvy[1]) , 1./n);
++
++         /*2. basal crevasses*/
++         db = (rho_ice)/(rho_water - rho_ice) * ds;
++
++         /*3. "Additional" crevasse opening*/
++         vel = sqrt(vx*vx + vy*vy)/(365.25*24*3600);
++         da = H* max(0., log(vel/1600.))/log(1.2);
++
++         /*4. deal with shallow ice*/
++         dt = H* max(0., min(1., (150. - H)/50.));
++
++         /*5. water induced opening*/
++         dw = 0.;
++         R = smb*365.25*24*3600; //convert from m/s to m/yr
++         if(R>1.5 && R<=3.){
++            dw = 4*1.5*(R - 1.5);
++         }
++         else if(R>3.){
++            dw = R*R;
++         }
++
++         /*Total calving rate*/
++         r = (ds+db+da+dt+dw)/H;
++			calvingrate[iv]= mig_max * max(0., min(1., (r - rc)/(1 - rc))); //P&DC: mig_max = 3000 m/yr
++			_assert_(!xIsNan<IssmDouble>(calvingrate[iv]));
++			_assert_(!xIsInf<IssmDouble>(calvingrate[iv]));
++		}
++		else
++		 calvingrate[iv]=0.;
++	}
++
++	/*Add input*/
++	this->AddInput(CalvingCalvingrateEnum,&calvingrate[0],P1DGEnum);
++	this->CalvingRateToVector();
++}/*}}}*/
+ void       Tria::CalvingFluxLevelset(){/*{{{*/
+ 
+ 	/*Make sure there is an ice front here*/
+@@ -950,7 +1038,7 @@
+ 	/*Add input*/
+ 	this->AddInput(CalvingCalvingrateEnum,&calvingrate[0],P1DGEnum);
+ 	this->AddInput(SigmaVMEnum,&sigma_vm[0],P1DGEnum);
+-	this->CalvingFromRate();
++	this->CalvingRateToVector();
+ 
+ 	/*Clean up and return*/
+ 	delete gauss;
+@@ -4311,6 +4399,7 @@
+ 		case DefaultCalvingEnum:
+ 		case CalvingVonmisesEnum:
+ 		case CalvingLevermannEnum:
++		case CalvingPollardEnum:
+ 		case CalvingTestEnum:
+ 		case CalvingParameterizationEnum:
+ 			calvingratex_input=this->GetInput(CalvingratexEnum); _assert_(calvingratex_input);
+@@ -4356,6 +4445,7 @@
+ 			case CalvingTestEnum:
+ 			case CalvingParameterizationEnum:
+ 			case CalvingLevermannEnum:
++			case CalvingPollardEnum:
+ 				calvingratex_input->GetInputValue(&c[0],&gauss);
+ 				calvingratey_input->GetInputValue(&c[1],&gauss);
+ 				meltingrate_input->GetInputValue(&meltingrate,&gauss);
+Index: ../trunk-jpl/src/c/classes/Elements/Tria.h
+===================================================================
+--- ../trunk-jpl/src/c/classes/Elements/Tria.h	(revision 27286)
++++ ../trunk-jpl/src/c/classes/Elements/Tria.h	(revision 27287)
+@@ -57,6 +57,7 @@
+ 		void			CalvingRateTest();
+ 		void        CalvingCrevasseDepth();
+ 		void			CalvingRateLevermann();
++		void			CalvingPollard();
+ 		void			CalvingFluxLevelset();
+ 		void			CalvingMeltingFluxLevelset();
+ 		void			CalvingRateParameterization();
+Index: ../trunk-jpl/src/c/modules/Calvingx/Calvingx.cpp
+===================================================================
+--- ../trunk-jpl/src/c/modules/Calvingx/Calvingx.cpp	(revision 27286)
++++ ../trunk-jpl/src/c/modules/Calvingx/Calvingx.cpp	(revision 27287)
+@@ -19,7 +19,7 @@
+ 			femmodel->ElementOperationx(&Element::CalvingSetZeroRate);
+ 			break;
+ 		case DefaultCalvingEnum:
+-			femmodel->ElementOperationx(&Element::CalvingFromRate);
++			femmodel->ElementOperationx(&Element::CalvingRateToVector);
+ 			break;
+ 		case CalvingCrevasseDepthEnum:
+ 			femmodel->ElementOperationx(&Element::CalvingSetZeroRate);
+@@ -30,7 +30,6 @@
+ 			femmodel->ElementOperationx(&Element::CalvingCrevasseDepth);
+ 			break;
+ 		case CalvingLevermannEnum:
+-			if(VerboseModule()) _printf0_("   computing Levermann's calving rate\n");
+ 			femmodel->StrainRateparallelx();
+ 			femmodel->StrainRateperpendicularx();
+ 			femmodel->CalvingRateLevermannx();
+@@ -45,6 +44,9 @@
+ 		case CalvingParameterizationEnum:
+ 			femmodel->ElementOperationx(&Element::CalvingRateParameterization);
+ 			break;
++		case CalvingPollardEnum:
++			femmodel->ElementOperationx(&Element::CalvingPollard);
++			break;
+ 		default:
+ 			_error_("Caving law "<<EnumToStringx(calvinglaw)<<" not supported yet");
+ 	}
+Index: ../trunk-jpl/src/c/shared/Enum/Enum.vim
+===================================================================
+--- ../trunk-jpl/src/c/shared/Enum/Enum.vim	(revision 27286)
++++ ../trunk-jpl/src/c/shared/Enum/Enum.vim	(revision 27287)
+@@ -128,6 +128,7 @@
+ syn keyword cConstant CalvingVelMaxEnum
+ syn keyword cConstant CalvingVelThresholdEnum
+ syn keyword cConstant CalvingVelUpperboundEnum
++syn keyword cConstant CalvingRcEnum
+ syn keyword cConstant ConfigurationTypeEnum
+ syn keyword cConstant ConstantsGEnum
+ syn keyword cConstant ConstantsNewtonGravityEnum
+@@ -1288,6 +1289,7 @@
+ syn keyword cConstant CalvingTestEnum
+ syn keyword cConstant CalvingParameterizationEnum
+ syn keyword cConstant CalvingVonmisesEnum
++syn keyword cConstant CalvingPollardEnum
+ syn keyword cConstant CfdragcoeffabsgradEnum
+ syn keyword cConstant CfsurfacelogvelEnum
+ syn keyword cConstant CfsurfacesquareEnum
+Index: ../trunk-jpl/src/c/shared/Enum/EnumDefinitions.h
+===================================================================
+--- ../trunk-jpl/src/c/shared/Enum/EnumDefinitions.h	(revision 27286)
++++ ../trunk-jpl/src/c/shared/Enum/EnumDefinitions.h	(revision 27287)
+@@ -122,6 +122,7 @@
+ 	CalvingVelMaxEnum,
+ 	CalvingVelThresholdEnum,
+ 	CalvingVelUpperboundEnum,
++	CalvingRcEnum,
+ 	ConfigurationTypeEnum,
+ 	ConstantsGEnum,
+ 	ConstantsNewtonGravityEnum,
+@@ -1287,6 +1288,7 @@
+ 	CalvingTestEnum,
+ 	CalvingParameterizationEnum,
+ 	CalvingVonmisesEnum,
++	CalvingPollardEnum,
+ 	CfdragcoeffabsgradEnum,
+ 	CfsurfacelogvelEnum,
+ 	CfsurfacesquareEnum,
+Index: ../trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp
+===================================================================
+--- ../trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp	(revision 27286)
++++ ../trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp	(revision 27287)
+@@ -130,6 +130,7 @@
+ 		case CalvingVelMaxEnum : return "CalvingVelMax";
+ 		case CalvingVelThresholdEnum : return "CalvingVelThreshold";
+ 		case CalvingVelUpperboundEnum : return "CalvingVelUpperbound";
++		case CalvingRcEnum : return "CalvingRc";
+ 		case ConfigurationTypeEnum : return "ConfigurationType";
+ 		case ConstantsGEnum : return "ConstantsG";
+ 		case ConstantsNewtonGravityEnum : return "ConstantsNewtonGravity";
+@@ -1290,6 +1291,7 @@
+ 		case CalvingTestEnum : return "CalvingTest";
+ 		case CalvingParameterizationEnum : return "CalvingParameterization";
+ 		case CalvingVonmisesEnum : return "CalvingVonmises";
++		case CalvingPollardEnum : return "CalvingPollard";
+ 		case CfdragcoeffabsgradEnum : return "Cfdragcoeffabsgrad";
+ 		case CfsurfacelogvelEnum : return "Cfsurfacelogvel";
+ 		case CfsurfacesquareEnum : return "Cfsurfacesquare";
+Index: ../trunk-jpl/src/c/shared/Enum/Enumjl.vim
+===================================================================
+--- ../trunk-jpl/src/c/shared/Enum/Enumjl.vim	(revision 27286)
++++ ../trunk-jpl/src/c/shared/Enum/Enumjl.vim	(revision 27287)
+@@ -121,6 +121,7 @@
+ syn keyword juliaConstC CalvingVelMaxEnum
+ syn keyword juliaConstC CalvingVelThresholdEnum
+ syn keyword juliaConstC CalvingVelUpperboundEnum
++syn keyword juliaConstC CalvingRcEnum
+ syn keyword juliaConstC ConfigurationTypeEnum
+ syn keyword juliaConstC ConstantsGEnum
+ syn keyword juliaConstC ConstantsNewtonGravityEnum
+@@ -1281,6 +1282,7 @@
+ syn keyword juliaConstC CalvingTestEnum
+ syn keyword juliaConstC CalvingParameterizationEnum
+ syn keyword juliaConstC CalvingVonmisesEnum
++syn keyword juliaConstC CalvingPollardEnum
+ syn keyword juliaConstC CfdragcoeffabsgradEnum
+ syn keyword juliaConstC CfsurfacelogvelEnum
+ syn keyword juliaConstC CfsurfacesquareEnum
+Index: ../trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp
+===================================================================
+--- ../trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp	(revision 27286)
++++ ../trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp	(revision 27287)
+@@ -130,16 +130,17 @@
+ 	      else if (strcmp(name,"CalvingVelMax")==0) return CalvingVelMaxEnum;
+ 	      else if (strcmp(name,"CalvingVelThreshold")==0) return CalvingVelThresholdEnum;
+ 	      else if (strcmp(name,"CalvingVelUpperbound")==0) return CalvingVelUpperboundEnum;
++	      else if (strcmp(name,"CalvingRc")==0) return CalvingRcEnum;
+ 	      else if (strcmp(name,"ConfigurationType")==0) return ConfigurationTypeEnum;
+ 	      else if (strcmp(name,"ConstantsG")==0) return ConstantsGEnum;
+ 	      else if (strcmp(name,"ConstantsNewtonGravity")==0) return ConstantsNewtonGravityEnum;
+ 	      else if (strcmp(name,"ConstantsReferencetemperature")==0) return ConstantsReferencetemperatureEnum;
+ 	      else if (strcmp(name,"ConstantsYts")==0) return ConstantsYtsEnum;
+-	      else if (strcmp(name,"ControlInputSizeM")==0) return ControlInputSizeMEnum;
+          else stage=2;
+    }
+    if(stage==2){
+-	      if (strcmp(name,"ControlInputSizeN")==0) return ControlInputSizeNEnum;
++	      if (strcmp(name,"ControlInputSizeM")==0) return ControlInputSizeMEnum;
++	      else if (strcmp(name,"ControlInputSizeN")==0) return ControlInputSizeNEnum;
+ 	      else if (strcmp(name,"ControlInputInterpolation")==0) return ControlInputInterpolationEnum;
+ 	      else if (strcmp(name,"CumBslc")==0) return CumBslcEnum;
+ 	      else if (strcmp(name,"CumBslcIce")==0) return CumBslcIceEnum;
+@@ -258,11 +259,11 @@
+ 	      else if (strcmp(name,"HydrologydcSedimentThickness")==0) return HydrologydcSedimentThicknessEnum;
+ 	      else if (strcmp(name,"HydrologyStepAdapt")==0) return HydrologyStepAdaptEnum;
+ 	      else if (strcmp(name,"HydrologydcTransferFlag")==0) return HydrologydcTransferFlagEnum;
+-	      else if (strcmp(name,"HydrologydcUnconfinedFlag")==0) return HydrologydcUnconfinedFlagEnum;
+          else stage=3;
+    }
+    if(stage==3){
+-	      if (strcmp(name,"HydrologyshreveStabilization")==0) return HydrologyshreveStabilizationEnum;
++	      if (strcmp(name,"HydrologydcUnconfinedFlag")==0) return HydrologydcUnconfinedFlagEnum;
++	      else if (strcmp(name,"HydrologyshreveStabilization")==0) return HydrologyshreveStabilizationEnum;
+ 	      else if (strcmp(name,"IcecapToEarthComm")==0) return IcecapToEarthCommEnum;
+ 	      else if (strcmp(name,"Index")==0) return IndexEnum;
+ 	      else if (strcmp(name,"InputFileName")==0) return InputFileNameEnum;
+@@ -381,11 +382,11 @@
+ 	      else if (strcmp(name,"QmuResponsedescriptors")==0) return QmuResponsedescriptorsEnum;
+ 	      else if (strcmp(name,"QmuVariableDescriptors")==0) return QmuVariableDescriptorsEnum;
+ 	      else if (strcmp(name,"QmuVariablePartitions")==0) return QmuVariablePartitionsEnum;
+-	      else if (strcmp(name,"QmuVariablePartitionsNpart")==0) return QmuVariablePartitionsNpartEnum;
+          else stage=4;
+    }
+    if(stage==4){
+-	      if (strcmp(name,"QmuVariablePartitionsNt")==0) return QmuVariablePartitionsNtEnum;
++	      if (strcmp(name,"QmuVariablePartitionsNpart")==0) return QmuVariablePartitionsNpartEnum;
++	      else if (strcmp(name,"QmuVariablePartitionsNt")==0) return QmuVariablePartitionsNtEnum;
+ 	      else if (strcmp(name,"QmuResponsePartitions")==0) return QmuResponsePartitionsEnum;
+ 	      else if (strcmp(name,"QmuResponsePartitionsNpart")==0) return QmuResponsePartitionsNpartEnum;
+ 	      else if (strcmp(name,"QmuStatistics")==0) return QmuStatisticsEnum;
+@@ -504,11 +505,11 @@
+ 	      else if (strcmp(name,"SmbElevationBins")==0) return SmbElevationBinsEnum;
+ 	      else if (strcmp(name,"SmbCldFrac")==0) return SmbCldFracEnum;
+ 	      else if (strcmp(name,"SmbDelta18o")==0) return SmbDelta18oEnum;
+-	      else if (strcmp(name,"SmbDelta18oSurface")==0) return SmbDelta18oSurfaceEnum;
+          else stage=5;
+    }
+    if(stage==5){
+-	      if (strcmp(name,"SmbDenIdx")==0) return SmbDenIdxEnum;
++	      if (strcmp(name,"SmbDelta18oSurface")==0) return SmbDelta18oSurfaceEnum;
++	      else if (strcmp(name,"SmbDenIdx")==0) return SmbDenIdxEnum;
+ 	      else if (strcmp(name,"SmbDt")==0) return SmbDtEnum;
+ 	      else if (strcmp(name,"Smb")==0) return SmbEnum;
+ 	      else if (strcmp(name,"SmbEIdx")==0) return SmbEIdxEnum;
+@@ -627,11 +628,11 @@
+ 	      else if (strcmp(name,"TransientRequestedOutputs")==0) return TransientRequestedOutputsEnum;
+ 	      else if (strcmp(name,"Velocity")==0) return VelocityEnum;
+ 	      else if (strcmp(name,"Xxe")==0) return XxeEnum;
+-	      else if (strcmp(name,"Yye")==0) return YyeEnum;
+          else stage=6;
+    }
+    if(stage==6){
+-	      if (strcmp(name,"Zze")==0) return ZzeEnum;
++	      if (strcmp(name,"Yye")==0) return YyeEnum;
++	      else if (strcmp(name,"Zze")==0) return ZzeEnum;
+ 	      else if (strcmp(name,"Areae")==0) return AreaeEnum;
+ 	      else if (strcmp(name,"WorldComm")==0) return WorldCommEnum;
+ 	      else if (strcmp(name,"ParametersEND")==0) return ParametersENDEnum;
+@@ -750,11 +751,11 @@
+ 	      else if (strcmp(name,"Domain3D")==0) return Domain3DEnum;
+ 	      else if (strcmp(name,"DragCoefficientAbsGradient")==0) return DragCoefficientAbsGradientEnum;
+ 	      else if (strcmp(name,"DrivingStressX")==0) return DrivingStressXEnum;
+-	      else if (strcmp(name,"DrivingStressY")==0) return DrivingStressYEnum;
+          else stage=7;
+    }
+    if(stage==7){
+-	      if (strcmp(name,"Dummy")==0) return DummyEnum;
++	      if (strcmp(name,"DrivingStressY")==0) return DrivingStressYEnum;
++	      else if (strcmp(name,"Dummy")==0) return DummyEnum;
+ 	      else if (strcmp(name,"EffectivePressure")==0) return EffectivePressureEnum;
+ 	      else if (strcmp(name,"EffectivePressureSubstep")==0) return EffectivePressureSubstepEnum;
+ 	      else if (strcmp(name,"EffectivePressureTransient")==0) return EffectivePressureTransientEnum;
+@@ -873,11 +874,11 @@
+ 	      else if (strcmp(name,"MeshVertexonboundary")==0) return MeshVertexonboundaryEnum;
+ 	      else if (strcmp(name,"MeshVertexonsurface")==0) return MeshVertexonsurfaceEnum;
+ 	      else if (strcmp(name,"Misfit")==0) return MisfitEnum;
+-	      else if (strcmp(name,"MovingFrontalVx")==0) return MovingFrontalVxEnum;
+          else stage=8;
+    }
+    if(stage==8){
+-	      if (strcmp(name,"MovingFrontalVy")==0) return MovingFrontalVyEnum;
++	      if (strcmp(name,"MovingFrontalVx")==0) return MovingFrontalVxEnum;
++	      else if (strcmp(name,"MovingFrontalVy")==0) return MovingFrontalVyEnum;
+ 	      else if (strcmp(name,"Neumannflux")==0) return NeumannfluxEnum;
+ 	      else if (strcmp(name,"NewDamage")==0) return NewDamageEnum;
+ 	      else if (strcmp(name,"Node")==0) return NodeEnum;
+@@ -996,11 +997,11 @@
+ 	      else if (strcmp(name,"SmbC")==0) return SmbCEnum;
+ 	      else if (strcmp(name,"SmbCcsnowValue")==0) return SmbCcsnowValueEnum;
+ 	      else if (strcmp(name,"SmbCciceValue")==0) return SmbCciceValueEnum;
+-	      else if (strcmp(name,"SmbCotValue")==0) return SmbCotValueEnum;
+          else stage=9;
+    }
+    if(stage==9){
+-	      if (strcmp(name,"SmbD")==0) return SmbDEnum;
++	      if (strcmp(name,"SmbCotValue")==0) return SmbCotValueEnum;
++	      else if (strcmp(name,"SmbD")==0) return SmbDEnum;
+ 	      else if (strcmp(name,"SmbDailyairdensity")==0) return SmbDailyairdensityEnum;
+ 	      else if (strcmp(name,"SmbDailyairhumidity")==0) return SmbDailyairhumidityEnum;
+ 	      else if (strcmp(name,"SmbDailydlradiation")==0) return SmbDailydlradiationEnum;
+@@ -1119,11 +1120,11 @@
+ 	      else if (strcmp(name,"SurfaceAverageVelMisfit")==0) return SurfaceAverageVelMisfitEnum;
+ 	      else if (strcmp(name,"SurfaceCrevasse")==0) return SurfaceCrevasseEnum;
+ 	      else if (strcmp(name,"Surface")==0) return SurfaceEnum;
+-	      else if (strcmp(name,"SurfaceOld")==0) return SurfaceOldEnum;
+          else stage=10;
+    }
+    if(stage==10){
+-	      if (strcmp(name,"SurfaceLogVelMisfit")==0) return SurfaceLogVelMisfitEnum;
++	      if (strcmp(name,"SurfaceOld")==0) return SurfaceOldEnum;
++	      else if (strcmp(name,"SurfaceLogVelMisfit")==0) return SurfaceLogVelMisfitEnum;
+ 	      else if (strcmp(name,"SurfaceLogVxVyMisfit")==0) return SurfaceLogVxVyMisfitEnum;
+ 	      else if (strcmp(name,"SurfaceObservation")==0) return SurfaceObservationEnum;
+ 	      else if (strcmp(name,"SurfaceRelVelMisfit")==0) return SurfaceRelVelMisfitEnum;
+@@ -1242,11 +1243,11 @@
+ 	      else if (strcmp(name,"Outputdefinition66")==0) return Outputdefinition66Enum;
+ 	      else if (strcmp(name,"Outputdefinition67")==0) return Outputdefinition67Enum;
+ 	      else if (strcmp(name,"Outputdefinition68")==0) return Outputdefinition68Enum;
+-	      else if (strcmp(name,"Outputdefinition69")==0) return Outputdefinition69Enum;
+          else stage=11;
+    }
+    if(stage==11){
+-	      if (strcmp(name,"Outputdefinition6")==0) return Outputdefinition6Enum;
++	      if (strcmp(name,"Outputdefinition69")==0) return Outputdefinition69Enum;
++	      else if (strcmp(name,"Outputdefinition6")==0) return Outputdefinition6Enum;
+ 	      else if (strcmp(name,"Outputdefinition70")==0) return Outputdefinition70Enum;
+ 	      else if (strcmp(name,"Outputdefinition71")==0) return Outputdefinition71Enum;
+ 	      else if (strcmp(name,"Outputdefinition72")==0) return Outputdefinition72Enum;
+@@ -1320,6 +1321,7 @@
+ 	      else if (strcmp(name,"CalvingTest")==0) return CalvingTestEnum;
+ 	      else if (strcmp(name,"CalvingParameterization")==0) return CalvingParameterizationEnum;
+ 	      else if (strcmp(name,"CalvingVonmises")==0) return CalvingVonmisesEnum;
++	      else if (strcmp(name,"CalvingPollard")==0) return CalvingPollardEnum;
+ 	      else if (strcmp(name,"Cfdragcoeffabsgrad")==0) return CfdragcoeffabsgradEnum;
+ 	      else if (strcmp(name,"Cfsurfacelogvel")==0) return CfsurfacelogvelEnum;
+ 	      else if (strcmp(name,"Cfsurfacesquare")==0) return CfsurfacesquareEnum;
+@@ -1364,12 +1366,12 @@
+ 	      else if (strcmp(name,"DoubleMatParam")==0) return DoubleMatParamEnum;
+ 	      else if (strcmp(name,"DoubleParam")==0) return DoubleParamEnum;
+ 	      else if (strcmp(name,"DoubleVecParam")==0) return DoubleVecParamEnum;
+-	      else if (strcmp(name,"Element")==0) return ElementEnum;
+-	      else if (strcmp(name,"ElementHook")==0) return ElementHookEnum;
+          else stage=12;
+    }
+    if(stage==12){
+-	      if (strcmp(name,"ElementSId")==0) return ElementSIdEnum;
++	      if (strcmp(name,"Element")==0) return ElementEnum;
++	      else if (strcmp(name,"ElementHook")==0) return ElementHookEnum;
++	      else if (strcmp(name,"ElementSId")==0) return ElementSIdEnum;
+ 	      else if (strcmp(name,"EnthalpyAnalysis")==0) return EnthalpyAnalysisEnum;
+ 	      else if (strcmp(name,"EsaAnalysis")==0) return EsaAnalysisEnum;
+ 	      else if (strcmp(name,"EsaSolution")==0) return EsaSolutionEnum;
+@@ -1487,12 +1489,12 @@
+ 	      else if (strcmp(name,"MantlePlumeGeothermalFlux")==0) return MantlePlumeGeothermalFluxEnum;
+ 	      else if (strcmp(name,"MassFlux")==0) return MassFluxEnum;
+ 	      else if (strcmp(name,"Masscon")==0) return MassconEnum;
+-	      else if (strcmp(name,"Massconaxpby")==0) return MassconaxpbyEnum;
+-	      else if (strcmp(name,"Massfluxatgate")==0) return MassfluxatgateEnum;
+          else stage=13;
+    }
+    if(stage==13){
+-	      if (strcmp(name,"MasstransportAnalysis")==0) return MasstransportAnalysisEnum;
++	      if (strcmp(name,"Massconaxpby")==0) return MassconaxpbyEnum;
++	      else if (strcmp(name,"Massfluxatgate")==0) return MassfluxatgateEnum;
++	      else if (strcmp(name,"MasstransportAnalysis")==0) return MasstransportAnalysisEnum;
+ 	      else if (strcmp(name,"MasstransportSolution")==0) return MasstransportSolutionEnum;
+ 	      else if (strcmp(name,"Matdamageice")==0) return MatdamageiceEnum;
+ 	      else if (strcmp(name,"Matenhancedice")==0) return MatenhancediceEnum;
+@@ -1610,12 +1612,12 @@
+ 	      else if (strcmp(name,"Seq")==0) return SeqEnum;
+ 	      else if (strcmp(name,"SmbAnalysis")==0) return SmbAnalysisEnum;
+ 	      else if (strcmp(name,"SmbSolution")==0) return SmbSolutionEnum;
+-	      else if (strcmp(name,"SmoothAnalysis")==0) return SmoothAnalysisEnum;
+-	      else if (strcmp(name,"SoftMigration")==0) return SoftMigrationEnum;
+          else stage=14;
+    }
+    if(stage==14){
+-	      if (strcmp(name,"SpatialLinearFloatingMeltRate")==0) return SpatialLinearFloatingMeltRateEnum;
++	      if (strcmp(name,"SmoothAnalysis")==0) return SmoothAnalysisEnum;
++	      else if (strcmp(name,"SoftMigration")==0) return SoftMigrationEnum;
++	      else if (strcmp(name,"SpatialLinearFloatingMeltRate")==0) return SpatialLinearFloatingMeltRateEnum;
+ 	      else if (strcmp(name,"SpcDynamic")==0) return SpcDynamicEnum;
+ 	      else if (strcmp(name,"SpcStatic")==0) return SpcStaticEnum;
+ 	      else if (strcmp(name,"SpcTransient")==0) return SpcTransientEnum;
+Index: ../trunk-jpl/src/c/shared/io/Marshalling/IoCodeConversions.cpp
+===================================================================
+--- ../trunk-jpl/src/c/shared/io/Marshalling/IoCodeConversions.cpp	(revision 27286)
++++ ../trunk-jpl/src/c/shared/io/Marshalling/IoCodeConversions.cpp	(revision 27287)
+@@ -260,15 +260,16 @@
+ }/*}}}*/
+ int IoCodeToEnumCalving(int enum_in){/*{{{*/
+ 	switch(enum_in){
+-		case 1: return DefaultCalvingEnum;
+-		case 2: return CalvingVonmisesEnum;
+-		case 3: return CalvingLevermannEnum;
+-		case 4: return CalvingMinthicknessEnum;
+-		case 5: return CalvingHabEnum;
+-		case 6: return CalvingCrevasseDepthEnum;
+-		case 7: return CalvingDev2Enum;
+-		case 9: return CalvingParameterizationEnum;
+-		case 8: return CalvingTestEnum;
++		case 1:  return DefaultCalvingEnum;
++		case 2:  return CalvingVonmisesEnum;
++		case 3:  return CalvingLevermannEnum;
++		case 4:  return CalvingMinthicknessEnum;
++		case 5:  return CalvingHabEnum;
++		case 6:  return CalvingCrevasseDepthEnum;
++		case 7:  return CalvingDev2Enum;
++		case 8:  return CalvingTestEnum;
++		case 9:  return CalvingParameterizationEnum;
++		case 10: return CalvingPollardEnum;
+ 		default: _error_("Marshalled Calving law code \""<<enum_in<<"\" not supported yet");
+ 	}
+ }/*}}}*/
Index: /issm/oecreview/Archive/27230-27343/ISSM-27287-27288.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27287-27288.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27287-27288.diff	(revision 27344)
@@ -0,0 +1,67 @@
+Index: ../trunk-jpl/src/c/cores/movingfront_core.cpp
+===================================================================
+--- ../trunk-jpl/src/c/cores/movingfront_core.cpp	(revision 27287)
++++ ../trunk-jpl/src/c/cores/movingfront_core.cpp	(revision 27288)
+@@ -16,8 +16,7 @@
+ 
+ 	/* intermediaries */
+ 	bool save_results,isstressbalance,ismasstransport,isthermal,isenthalpy,islevelset,ismovingfront,killicebergs;
+-	int  domaintype, num_extrapol_vars, index,reinit_frequency,step;
+-	int* extrapol_vars=NULL;
++	int  domaintype, reinit_frequency,step;
+ 	Analysis  *analysis=NULL;
+ 	IssmDouble maxVel;
+ 
+@@ -64,44 +63,24 @@
+ 	if(VerboseSolution()) _printf0_("   computing new ice front position\n");
+ 
+ 	/* determine variables for extrapolation */
+-	num_extrapol_vars=0;
++	std::vector<int>  extrapol_vars;
+ 	if(isstressbalance){
+-		if(domaintype==Domain3DEnum)
+-		 num_extrapol_vars+=3;
+-		else
+-		 num_extrapol_vars+=2;
++		extrapol_vars.push_back(VxEnum);
++		extrapol_vars.push_back(VyEnum);
++		if(domaintype==Domain3DEnum) extrapol_vars.push_back(VzEnum);
+ 	}
+-	if(ismasstransport) num_extrapol_vars+=1;
+-	if(isthermal && domaintype==Domain3DEnum) num_extrapol_vars+=1;
+-	extrapol_vars=xNew<int>(num_extrapol_vars);
+-	index=0;
+-	if(isstressbalance){
+-		extrapol_vars[index]=VxEnum; index++;
+-		extrapol_vars[index]=VyEnum; index++;
+-		if(domaintype==Domain3DEnum){
+-			extrapol_vars[index]=VzEnum; index++;
+-		}
+-	}
+-	if(ismasstransport){
+-		extrapol_vars[index]=ThicknessEnum; index++;
+-	}
++	if(ismasstransport) extrapol_vars.push_back(ThicknessEnum);
+ 	if(isthermal && domaintype==Domain3DEnum){
+-		if(isenthalpy){
+-			extrapol_vars[index]=EnthalpyEnum;
+-		}
+-		else{
+-			extrapol_vars[index]=TemperatureEnum;
+-		}
+-		index++;
++		if(isenthalpy) extrapol_vars.push_back(EnthalpyEnum);
++		else           extrapol_vars.push_back(TemperatureEnum);
+ 	}
+ 
+ 	/* extrapolate */
+ 	analysis = new ExtrapolationAnalysis();
+-	for(int iv=0;iv<num_extrapol_vars;iv++){
++	for(int iv=0;iv<extrapol_vars.size();iv++){
+ 		femmodel->parameters->SetParam(extrapol_vars[iv],ExtrapolationVariableEnum); 
+ 		analysis->Core(femmodel);
+ 	}
+-	xDelete<int>(extrapol_vars);
+ 	delete analysis;	
+ 
+ 	/* Need to do it again after extrapolation! */
Index: /issm/oecreview/Archive/27230-27343/ISSM-27288-27289.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27288-27289.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27288-27289.diff	(revision 27344)
@@ -0,0 +1,92 @@
+Index: ../trunk-jpl/src/c/analyses/HydrologyGlaDSAnalysis.cpp
+===================================================================
+--- ../trunk-jpl/src/c/analyses/HydrologyGlaDSAnalysis.cpp	(revision 27288)
++++ ../trunk-jpl/src/c/analyses/HydrologyGlaDSAnalysis.cpp	(revision 27289)
+@@ -517,6 +517,7 @@
+ 	IssmDouble  Jdet,vx,vy,ub,h_old,N,h_r,H,b;
+ 	IssmDouble  A,B,n,phi,phi_0;
+ 	IssmDouble  alpha,beta;
++	IssmDouble  oceanLS,iceLS;
+ 
+ 	/*Fetch number vertices for this element*/
+ 	int numvertices = element->GetNumberOfVertices();
+@@ -547,7 +548,10 @@
+ 	Input* B_input  = element->GetInput(MaterialsRheologyBEnum);         _assert_(B_input);
+ 	Input* n_input  = element->GetInput(MaterialsRheologyNEnum);         _assert_(n_input);
+ 	Input* phi_input = element->GetInput(HydraulicPotentialEnum);         _assert_(phi_input);
++	Input* oceanLS_input = element->GetInput(MaskOceanLevelsetEnum); _assert_(oceanLS_input);
++	Input* iceLS_input = element->GetInput(MaskIceLevelsetEnum); _assert_(iceLS_input);
+ 
++
+ 	/* Start  looping on the number of gaussian points: */
+ 	Gauss* gauss=element->NewGauss();
+ 	for(int iv=0;iv<numvertices;iv++){
+@@ -563,7 +567,15 @@
+ 		hr_input->GetInputValue(&h_r,gauss);
+ 		b_input->GetInputValue(&b,gauss);
+ 		H_input->GetInputValue(&H,gauss);
++		oceanLS_input->GetInputValue(&oceanLS,gauss);
++		iceLS_input->GetInputValue(&iceLS,gauss);
+ 
++		/*Set sheet thickness to zero if floating or no ice*/
++		if(oceanLS<0. || iceLS>0.){
++			h_new[iv] = 0.;
++		}
++		else{
++
+ 		/*Get values for a few potentials*/
+ 		phi_0 = rho_water*g*b + rho_ice*g*H;
+ 		N = phi_0 - phi;
+@@ -590,11 +602,12 @@
+ 		/*Make sure it is positive*/
+ 		if(h_new[iv]<AEPS) h_new[iv] = AEPS;
+ 	}
+-	
++	}
++
+ 	/*Force floating ice to have zero sheet thickness*/
+-	if(element->IsAllFloating() || !element->IsIceInElement()){
++	/*if(!element->IsAllGrounded() || !element->IsIceInElement()){
+ 		for(int iv=0;iv<numvertices;iv++) h_new[iv] = 0.;
+-	}
++	}*/
+ 
+ 	element->AddInput(HydrologySheetThicknessEnum,h_new,P1Enum);
+ 
+@@ -615,6 +628,7 @@
+ 	/*Intermediary*/
+ 	IssmDouble phi_0, phi_m, p_i;
+ 	IssmDouble H,b,phi;
++	IssmDouble oceanLS,iceLS;
+ 
+ 	int numnodes = element->GetNumberOfNodes();
+ 
+@@ -626,6 +640,8 @@
+ 	Input* H_input   = element->GetInput(ThicknessEnum); _assert_(H_input);
+ 	Input* b_input   = element->GetInput(BedEnum); _assert_(b_input);
+ 	Input* phi_input = element->GetInput(HydraulicPotentialEnum); _assert_(phi_input);
++	Input* oceanLS_input = element->GetInput(MaskOceanLevelsetEnum); _assert_(oceanLS_input);
++	Input* iceLS_input = element->GetInput(MaskIceLevelsetEnum); _assert_(iceLS_input);
+ 
+ 	/*Set to 0 if inactive element*/
+ 	if(element->IsAllFloating() || !element->IsIceInElement()){
+@@ -644,6 +660,8 @@
+ 		H_input->GetInputValue(&H,gauss);
+ 		b_input->GetInputValue(&b,gauss);
+ 		phi_input->GetInputValue(&phi,gauss);
++		oceanLS_input->GetInputValue(&oceanLS,gauss);
++		iceLS_input->GetInputValue(&iceLS,gauss);
+ 
+ 		/*Elevation potential*/
+ 		phi_m = rho_water*g*b;
+@@ -657,6 +675,10 @@
+ 		/*Calculate effective pressure*/
+ 		N[iv] = phi_0 - phi;
+ 
++		/*Make sure that all floating ice and ice free areas have zero effective pressure*/
++		if(oceanLS<0.0) N[iv] = 0.0;
++		if(iceLS>0.0) N[iv] = 0.0;
++
+ 		if(xIsNan<IssmDouble>(N[iv])) _error_("NaN found in solution vector");
+ 		if(xIsInf<IssmDouble>(N[iv])) _error_("Inf found in solution vector");
+ 	}
Index: /issm/oecreview/Archive/27230-27343/ISSM-27289-27290.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27289-27290.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27289-27290.diff	(revision 27344)
@@ -0,0 +1,290 @@
+Index: ../trunk-jpl/src/m/classes/clusters/hpc_simba2.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/clusters/hpc_simba2.m	(nonexistent)
++++ ../trunk-jpl/src/m/classes/clusters/hpc_simba2.m	(revision 27290)
+@@ -0,0 +1,278 @@
++%HPC class definition
++%
++%   Usage:
++%      cluster=hpc_simba();
++%      cluster=hpc_simba('np',3);
++%      cluster=hpc_simba('np',3,'login','username');
++
++classdef hpc_simba2
++    properties (SetAccess=public)  
++		 % {{{
++		 name='simba20'
++		 login='inwoo';
++		 numnodes=18;    % number of nodes at 2019-11 installation
++		 cpuspernode=36; % default number of cpus at each node
++		 node=1;         % number of nodes for calculating 
++		 np=4;           % number of cpus for calculating at each node
++		 port=0;        % not know open port
++		 queue='pub64';
++		 codepath= [];
++		 executionpath=[];
++		 interactive=0;
++		 verbose=0;     % show process of downloading
++		 isqsub=1;
++	 end
++	 %}}}
++	 methods
++		 function cluster=hpc_simba2(varargin) % {{{
++
++			 %initialize cluster using default settings if provided
++			 if (exist('hpc_settings')==2), hpc_settings; end
++
++			 %use provided options to change fields
++			 cluster=AssignObjectFields(pairoptions(varargin{:}),cluster);
++
++			 % where is "ISSM_DIR"?
++			 if strcmpi(cluster.name,'simba00')
++				 ISSM_DIR=getenv('ISSM_DIR');
++			 elseif strcmpi(cluster.name,'simba20')
++				 ISSM_DIR='/home/inwoo/issm/trunk-jpl/';
++			 else
++				 error(sprintf('ERROR: %s is not supported cluster name...'))
++			 end
++			 cluster.codepath=sprintf('%s/bin',ISSM_DIR);
++
++			 % define specific user
++			 [~, s] = system('whoami'); % get user name
++			 s = s(1:end-1);
++			 cluster.login=s;
++			 if strcmpi(s,'inwoo'),
++				 %cluster.executionpath=sprintf('%s/execution/',ISSM_DIR);
++				 cluster.executionpath='/data2/inwoo/execution';
++			 elseif strcmpi(s,'emilia'),
++				 cluster.executionpath='/home/DATA/emilia-model/executionlog';
++			 end
++		 end
++		 %}}}
++		 function disp(cluster) % {{{
++			 %  display the object
++			 disp(sprintf('class ''%s'' object ''%s'' = ',class(cluster),inputname(1)));
++			 disp(sprintf('    name: %s',cluster.name));
++			 disp(sprintf('    login: %s',cluster.login));
++			 disp(sprintf('    port: %i',cluster.port));
++			 disp(sprintf('    numnodes: %i',cluster.numnodes));
++			 disp(sprintf('    node: %i',cluster.node));
++			 disp(sprintf('    cpuspernode: %i',cluster.cpuspernode));
++			 disp(sprintf('    np: %i',cluster.np));
++			 disp(sprintf('    queue: %s',cluster.queue));
++			 disp(sprintf('    codepath: %s',cluster.codepath));
++			 disp(sprintf('    executionpath: %s',cluster.executionpath));
++			 disp(sprintf('    interactive: %i',cluster.interactive));
++			 disp(sprintf('    isqub: %i',cluster.isqsub));
++		 end
++		 %}}}
++		 function md = checkconsistency(cluster,md,solution,analyses) % {{{
++
++			 available_queues={'pub64','free64','free48','free*,pub64','free*'};
++			 queue_requirements_time=[Inf Inf Inf Inf Inf];
++			 queue_requirements_np=[64 64 48 48 48];
++
++			 QueueRequirements(available_queues,queue_requirements_time,queue_requirements_np,cluster.queue,cluster.np,1)
++
++			 %Miscelaneous
++			 if isempty(cluster.login), md = checkmessage(md,'login empty'); end
++			 if isempty(cluster.codepath), md = checkmessage(md,'codepath empty'); end
++			 if isempty(cluster.executionpath), md = checkmessage(md,'executionpath empty'); end
++
++		 end
++		 %}}}
++		 function BuildKrigingQueueScript(cluster,modelname,solution,io_gather,isvalgrind,isgprof) % {{{
++
++			 if(isvalgrind), disp('valgrind not supported by cluster, ignoring...'); end
++			 if(isgprof),    disp('gprof not supported by cluster, ignoring...'); end
++
++			 %write queuing script 
++			 fid=fopen([modelname '.queue'],'w');
++			 fprintf(fid,'#!/bin/bash\n');
++			 fprintf(fid,'#$ -N %s\n',modelname);
++			 fprintf(fid,'#$ -q %s \n',cluster.queue);
++			 fprintf(fid,'#$ -pe one-node-mpi 2-64\n');
++			 fprintf(fid,'#$ -R y\n');
++			 fprintf(fid,'#$ -m beas\n');
++			 fprintf(fid,'#$ -o %s.outlog \n',modelname);
++			 fprintf(fid,'#$ -e %s.errlog \n\n',modelname);
++			 fprintf(fid,'export ISSM_DIR="%s/../"\n',cluster.codepath); %FIXME
++			 fprintf(fid,'source $ISSM_DIR/etc/environment.sh\n');       %FIXME
++			 fprintf(fid,'cd %s/%s\n\n',cluster.executionpath,modelname);
++			 fprintf(fid,'mpiexec -np %i %s/kriging.exe %s %s\n',cluster.np,cluster.codepath,[cluster.executionpath '/' modelname],modelname);
++			 if ~io_gather, %concatenate the output files:
++				 fprintf(fid,'cat %s.outbin.* > %s.outbin',modelname,modelname);
++			 end
++			 fclose(fid);
++		 end
++		 %}}}
++		 function BuildQueueScript(cluster,dirname,modelname,solution,io_gather,isvalgrind,isgprof,isdakota,isoceancoupling) % {{{
++
++			 if(isvalgrind), disp('valgrind not supported by cluster, ignoring...'); end
++			 if(isgprof),    disp('gprof not supported by cluster, ignoring...'); end
++
++			 %write queuing script 
++			 fid=fopen([modelname '.queue'],'w');
++			 %fprintf(fid,'#PBS -q workq\n');
++			 fprintf(fid,'#PBS -S /bin/bash\n');      % set shell name
++			 fprintf(fid,'#PBS -N %s\n',modelname);   % set job name
++			 % 8 node is available at simba
++			 if (cluster.node >= cluster.numnodes),
++				 fprintf('cluster node   : simba%02\n', cluster.node);
++				 fprintf('number of node : %d\n', cluster.numnodes);
++				 error('ERROR: cluster node is higher than number of nodes');
++			 end
++			 % node             -> how many nodes do you use?
++			 % ppn (cluster.np) -> how many cpus do you use? 
++			 fprintf(fid,'#PBS -l nodes=%d:ppn=%d\n',cluster.node,cluster.np);
++			 fprintf(fid,'#PBS -o %s.outlog \n',modelname);
++			 fprintf(fid,'#PBS -e %s.errlog \n',modelname);
++			 fprintf(fid,'\n');
++			 fprintf(fid,'source ~/.bashrc\n');                          % FIXME
++			 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,'module load intel18/compiler-18\n');
++			 fprintf(fid,'module load intel18/mvapich2-2.2\n');
++			 fprintf(fid,'\n');
++			 fprintf(fid,'cd %s/%s\n\n',cluster.executionpath,dirname);
++
++			 if true, % HACK
++				 % NOTE: old version
++				 % fprintf(fid,'mpiexec -genv MV2_ENABLE_AFFINITY 0 -np %i %s/issm.exe %s %s %s\n',cluster.np*cluster.node,cluster.codepath,solution,[cluster.executionpath '/' dirname],modelname);
++				 % NOTE: new version 
++				 % not requires np processor and machine file. Execution of ISSM is operated under PBS. 
++				 fprintf(fid,'mpiexec -genv MV2_ENABLE_AFFINITY 0 -np %d %s/issm.exe %s %s %s\n',...
++					 cluster.np,cluster.codepath,solution,[cluster.executionpath '/' dirname],modelname);
++			 else
++				 % use machine file for obtaining cluster nodes
++				 fprintf(fid,'mpiexec -machinefile %s -np %i %s/issm.exe %s %s %s\n',[cluster.executionpath '/' dirname '/simba.host'],cluster.np*cluster.node,cluster.codepath,solution,[cluster.executionpath '/' dirname],modelname);
++			 end 
++			 if ~io_gather, %concatenate the output files:
++				 fprintf(fid,'cat %s.outbin.* > %s.outbin',modelname,modelname);
++			 end
++			 fclose(fid);
++
++			 %% generate machinefile "simba.host" file for SIMBA
++			 %fid = fopen('simba.host','w');
++			 %nodeorder = [1:cluster.numnodes, 0];
++
++			 %% generate host of simba 
++			 %for i = 1:cluster.numnodes-1,
++			 %   fprintf(fid,'simba%02d:%2d\n',nodeorder(i),cluster.cpuspernode);
++			 %end
++			 %fclose(fid);
++
++			 %in interactive mode, create a run file, and errlog and outlog file
++			 if cluster.interactive,
++				 fid=fopen([modelname '.run'],'w');
++				 fprintf(fid,'mpiexec -np %i %s/issm.exe %s %s %s\n',cluster.np,cluster.codepath,solution,[cluster.executionpath '/' dirname],modelname);
++				 if ~io_gather, %concatenate the output files:
++					 fprintf(fid,'cat %s.outbin.* > %s.outbin',modelname,modelname);
++				 end
++				 fclose(fid);
++				 fid=fopen([modelname '.errlog'],'w');
++				 fclose(fid);
++				 fid=fopen([modelname '.outlog'],'w');
++				 fclose(fid);
++			 end
++		 end %}}}
++		 function UploadQueueJob(cluster,modelname,dirname,filelist)% {{{
++			 %compress the files into one zip.
++			 compressstring=['tar -zcf ' dirname '.tar.gz '];
++			 for i=1:numel(filelist),
++				 compressstring = [compressstring ' ' filelist{i}];
++			 end
++			 if cluster.interactive,
++				 compressstring = [compressstring ' ' modelname '.errlog ' modelname '.outlog '];
++			 end
++
++			 % add machine file for SIMBA operation
++			 %compressstring = [compressstring ' ' 'simba.host'];
++			 system(compressstring);
++
++			 if cluster.verbose
++				 disp('hpc_simba2: uploading input file and queueing script');
++				 if exist(sprintf('%s.tar.gz',dirname))
++					fprintf('hpc_simba2: -- we find %s.tar.gz\n',dirname);
++				 end
++				 fprintf('hpc_simba2: -- remote hostname: %s\n',cluster.name);
++			 end
++			 
++			 % use rclone for upload model.
++			 isrclone = 0;
++			 if isrclone,
++				 command = ['ssh simba20 "rclone copy simba00:' pwd '/' dirname '.tar.gz ' cluster.executionpath '"'];
++				 system(command);
++			 else
++				 if strfind(cluster.executionpath,'/data2/')
++					 launchcommand = ['cp ' pwd '/' dirname '.tar.gz ' cluster.executionpath];
++					 issmssh(oshostname,cluster.login,cluster.port,launchcommand);
++				 else % using scpout for exporting data...
++					 issmscpout(cluster.name,cluster.executionpath,cluster.login,cluster.port,{[dirname '.tar.gz']});
++				 end
++			 end
++		 end %}}}
++		 function LaunchQueueJob(cluster,modelname,dirname,filelist,restart,batch)% {{{
++			 disp('launching solution sequence on remote cluster: simba20');
++			 if ~isempty(restart)
++				 if cluster.isqsub 
++					 launchcommand=['cd ' cluster.executionpath ' && cd ' dirname ' && hostname && qsub ' modelname '.queue '];
++				 else
++					 launchcommand=['cd ' cluster.executionpath ' && cd ' dirname ' && hostname && source' modelname '.queue '];
++				 end
++			 else
++				 if cluster.isqsub 
++					 launchcommand=['cd ' cluster.executionpath ' && rm -rf ./' dirname ' && mkdir ' dirname ...
++						 ' && cd ' dirname ' && mv ../' dirname '.tar.gz ./ && tar -zxf ' dirname '.tar.gz  && hostname && qsub ' modelname '.queue '];
++				 else
++					 launchcommand=['cd ' cluster.executionpath ' && rm -rf ./' dirname ' && mkdir ' dirname ...
++						 ' && cd ' dirname ' && mv ../' dirname '.tar.gz ./ && tar -zxf ' dirname '.tar.gz  && hostname && source ' modelname '.queue '];
++				 end
++			 end
++			 
++			 if cluster.verbose
++				 fprintf('check simulation at\n');
++				 fprintf('%s/%s\n',cluster.executionpath,dirname);
++			 end
++
++			 % launch simulation
++			 issmssh(cluster.name,cluster.login,cluster.port,launchcommand);
++		 end %}}}
++		 function Download(cluster,dirname,filelist)% {{{
++			 %copy files from cluster to current directory
++			 directory=[cluster.executionpath '/' dirname '/'];
++			
++			 isrclone = 0;
++			 if isrclone,
++				 command = ['ssh simba20 "rclone copy ' directory ' simba00:' pwd '/'];
++				 for i = 1:length(filelist)
++					 command = [command ' --include ' filelist{i}];
++				 end
++				 if cluster.verbose,
++					 command = [command ' --progress '];
++				 end
++				 command = [command '"'];
++				 %assignin('base','command',command); 
++
++				 disp('download outputs....');
++				 system(command);
++				 disp('download outputs.... done...');
++			 else
++				 % In case of "SIMBA" machine, it shares the data storage. If following directory is set we do not need to download load file with using "issmscpin". Directly read file...
++				 if 1==strfind(cluster.executionpath,'/data2/')
++					 % tricky part for assign "cluster.name" as "simba00".
++					 disp('hpc_simba2: download file from /data2/ directory!!! Not use scpin.');
++					 issmscpin('simba00',cluster.login,cluster.port,directory,filelist);
++				 else
++					 issmscpin(cluster.name,cluster.login,cluster.port,directory,filelist);
++				 end
++			 end
++		 end %}}}
++	end
++end
+
+Property changes on: ../trunk-jpl/src/m/classes/clusters/hpc_simba2.m
+___________________________________________________________________
+Added: svn:executable
+## -0,0 +1 ##
++*
+\ No newline at end of property
Index: /issm/oecreview/Archive/27230-27343/ISSM-27290-27291.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27290-27291.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27290-27291.diff	(revision 27344)
@@ -0,0 +1,81 @@
+Index: ../trunk-jpl/src/m/plot/plotmodel.m
+===================================================================
+--- ../trunk-jpl/src/m/plot/plotmodel.m	(revision 27290)
++++ ../trunk-jpl/src/m/plot/plotmodel.m	(revision 27291)
+@@ -9,7 +9,7 @@
+ numberofplots=options.numberofplots;
+ 
+ %get number of subplots
+-subplotwidth=ceil(sqrt(numberofplots));
++subplotwidth=ceil(sqrt(options.numberofplots));
+ 
+ %if nlines and ncols specified, then bypass.
+ if ~exist(options.list{1},'nlines') & ~exist(options.list{1},'ncols')
+@@ -23,30 +23,15 @@
+ end
+ 
+ %check that nlines and ncols were given at the same time!
+-if ((exist(options.list{1},'ncols') & ~exist(options.list{1},'ncols')) | (~exist(options.list{1},'ncols') & exist(options.list{1},'ncols')))
++if ((exist(options.list{1},'ncols') & ~exist(options.list{1},'ncols')) | (~exist(options.list{1},'ncols') & exist(options.list{1},'nicols')))
+ 	error('plotmodel error message: nlines and ncols  need to be specified together, or not at all');
+ end
+ 
+-% Add option for subplot, only support one subplot per one plotmodel call
+-subindex = 0;
+-if (exist(options.list{1},'subplot'))
+-    subops = getfieldvalue(options.list{1},'subplot',NaN);
+-    nlines = subops(1);
+-    ncols = subops(2);
+-    subindex = subops(3);
+-    % change the width
+-    subplotwidth = ncols;
+-    % Turn off new figure option for subplot
+-    options.list{1}=addfield(options.list{1},'figurestatement','off');
+-    % Turn off clf option for subplot
+-    options.list{1}=addfield(options.list{1},'clf','off');
+-end
+-
+ %go through subplots
+ if numberofplots,
+ 
+ 	%Create figure 
+-	if (strcmpi(getfieldvalue(options.list{1},'figurestatement','on'),'on'))
++	if strcmpi(getfieldvalue(options.list{1},'figurestatement','on'),'on'),
+ 		f=figure(figurenumber); 
+ 	else
+ 		f=gcf;
+@@ -100,21 +85,19 @@
+ 			end
+ 		else
+ 			set(gcf,'Position',figposition);
+-		end
++        end
++   elseif strcmpi(getenv('USER'),'inwoo')
++        set(gcf,'Position',[910 242 560 420]);
+ 	end % }}}
+ 
+-	%Use zbuffer renderer (smoother colors) and white background
++	%Use zbuffer renderer (snoother colors) and white background
+ 	set(f,'Renderer','zbuffer','color',getfieldvalue(options.list{1},'figurebackgroundcolor','w'));
+ 
+ 	%Go through all data plottable and close window if an error occurs
+ 	try,
+ 		for i=1:numberofplots,
+-            if subindex
+-                plot_manager(getfieldvalue(options.list{i},'model',md),options.list{i},subplotwidth,nlines,ncols,subindex);
+-            else
+-                plot_manager(getfieldvalue(options.list{i},'model',md),options.list{i},subplotwidth,nlines,ncols,i);
+-            end
+-            %List all unused options
++			plot_manager(getfieldvalue(options.list{i},'model',md),options.list{i},subplotwidth,nlines,ncols,i);
++			%List all unused options
+ 			if getfieldvalue(options.list{i},'displayunused',1),
+ 				displayunused(options.list{i})
+ 			end
+@@ -124,5 +107,5 @@
+ 		rethrow(me);
+ 	end
+ else
+-	error('plotmodel error message: no output data found.');
++	error('plotmodel error message: no output data found. ');
+ end
Index: /issm/oecreview/Archive/27230-27343/ISSM-27291-27292.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27291-27292.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27291-27292.diff	(revision 27344)
@@ -0,0 +1,83 @@
+Index: ../trunk-jpl/src/m/plot/plotmodel.m
+===================================================================
+--- ../trunk-jpl/src/m/plot/plotmodel.m	(revision 27291)
++++ ../trunk-jpl/src/m/plot/plotmodel.m	(revision 27292)
+@@ -9,7 +9,7 @@
+ numberofplots=options.numberofplots;
+ 
+ %get number of subplots
+-subplotwidth=ceil(sqrt(options.numberofplots));
++subplotwidth=ceil(sqrt(numberofplots));
+ 
+ %if nlines and ncols specified, then bypass.
+ if ~exist(options.list{1},'nlines') & ~exist(options.list{1},'ncols')
+@@ -23,15 +23,30 @@
+ end
+ 
+ %check that nlines and ncols were given at the same time!
+-if ((exist(options.list{1},'ncols') & ~exist(options.list{1},'ncols')) | (~exist(options.list{1},'ncols') & exist(options.list{1},'nicols')))
++if ((exist(options.list{1},'ncols') & ~exist(options.list{1},'ncols')) | (~exist(options.list{1},'ncols') & exist(options.list{1},'ncols')))
+ 	error('plotmodel error message: nlines and ncols  need to be specified together, or not at all');
+ end
+ 
++% Add option for subplot, only support one subplot per one plotmodel call
++subindex = 0;
++if (exist(options.list{1},'subplot'))
++    subops = getfieldvalue(options.list{1},'subplot',NaN);
++    nlines = subops(1);
++    ncols = subops(2);
++    subindex = subops(3);
++    % change the width
++    subplotwidth = ncols;
++    % Turn off new figure option for subplot
++    options.list{1}=addfield(options.list{1},'figurestatement','off');
++    % Turn off clf option for subplot
++    options.list{1}=addfield(options.list{1},'clf','off');
++end
++
+ %go through subplots
+ if numberofplots,
+ 
+ 	%Create figure 
+-	if strcmpi(getfieldvalue(options.list{1},'figurestatement','on'),'on'),
++	if (strcmpi(getfieldvalue(options.list{1},'figurestatement','on'),'on'))
+ 		f=figure(figurenumber); 
+ 	else
+ 		f=gcf;
+@@ -85,19 +100,23 @@
+ 			end
+ 		else
+ 			set(gcf,'Position',figposition);
+-        end
+-   elseif strcmpi(getenv('USER'),'inwoo')
+-        set(gcf,'Position',[910 242 560 420]);
++		end
++	elseif strcmpi(getenv('USER'),'inwoo')
++		set(gcf,'Position',[910 242 560 420]);
+ 	end % }}}
+ 
+-	%Use zbuffer renderer (snoother colors) and white background
++	%Use zbuffer renderer (smoother colors) and white background
+ 	set(f,'Renderer','zbuffer','color',getfieldvalue(options.list{1},'figurebackgroundcolor','w'));
+ 
+ 	%Go through all data plottable and close window if an error occurs
+ 	try,
+ 		for i=1:numberofplots,
+-			plot_manager(getfieldvalue(options.list{i},'model',md),options.list{i},subplotwidth,nlines,ncols,i);
+-			%List all unused options
++            if subindex
++                plot_manager(getfieldvalue(options.list{i},'model',md),options.list{i},subplotwidth,nlines,ncols,subindex);
++            else
++                plot_manager(getfieldvalue(options.list{i},'model',md),options.list{i},subplotwidth,nlines,ncols,i);
++            end
++            %List all unused options
+ 			if getfieldvalue(options.list{i},'displayunused',1),
+ 				displayunused(options.list{i})
+ 			end
+@@ -107,5 +126,5 @@
+ 		rethrow(me);
+ 	end
+ else
+-	error('plotmodel error message: no output data found. ');
++	error('plotmodel error message: no output data found.');
+ end
Index: /issm/oecreview/Archive/27230-27343/ISSM-27292-27293.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27292-27293.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27292-27293.diff	(revision 27344)
@@ -0,0 +1,88 @@
+Index: ../trunk-jpl/src/c/analyses/HydrologyGlaDSAnalysis.cpp
+===================================================================
+--- ../trunk-jpl/src/c/analyses/HydrologyGlaDSAnalysis.cpp	(revision 27292)
++++ ../trunk-jpl/src/c/analyses/HydrologyGlaDSAnalysis.cpp	(revision 27293)
+@@ -443,6 +443,83 @@
+ }/*}}}*/
+ void           HydrologyGlaDSAnalysis::InputUpdateFromSolution(IssmDouble* solution,Element* element){/*{{{*/
+ 	element->InputUpdateFromSolutionOneDof(solution,HydraulicPotentialEnum);
++
++	/*Compute Hydrology Vx and Vy for time stepping purposes (These inputs do not affect GlaDS)*/
++
++	/*Intermediaries*/
++   IssmDouble  dphi[3],h,k,phi;
++	IssmDouble  oceanLS,iceLS;
++	IssmDouble* xyz_list = NULL;
++
++	/*Hard coded coefficients*/
++	const IssmPDouble alpha = 5./4.;
++	const IssmPDouble beta  = 3./2.;
++
++	/*Fetch number vertices for this element*/
++	int numvertices = element->GetNumberOfVertices();
++
++	/*Initialize new sheet thickness*/
++	IssmDouble* vx = xNew<IssmDouble>(numvertices);
++	IssmDouble* vy = xNew<IssmDouble>(numvertices);
++
++	/*Set to 0 if inactive element*/
++	if(element->IsAllFloating() || !element->IsIceInElement()){
++		for(int iv=0;iv<numvertices;iv++) vx[iv] = 0.;
++		for(int iv=0;iv<numvertices;iv++) vy[iv] = 0.;
++		element->AddInput(HydrologyWaterVxEnum,vx,P1DGEnum);
++		element->AddInput(HydrologyWaterVyEnum,vy,P1DGEnum);
++		xDelete<IssmDouble>(vx);
++		xDelete<IssmDouble>(vy);
++		return;
++	}
++
++	/*Retrieve all inputs and parameters*/
++	element->GetVerticesCoordinates(&xyz_list);
++	Input *k_input       = element->GetInput(HydrologySheetConductivityEnum); _assert_(k_input);
++	Input *phi_input     = element->GetInput(HydraulicPotentialEnum);         _assert_(phi_input);
++	Input *h_input       = element->GetInput(HydrologySheetThicknessEnum);    _assert_(h_input);
++	Input *oceanLS_input = element->GetInput(MaskOceanLevelsetEnum);          _assert_(oceanLS_input);
++	Input *iceLS_input   = element->GetInput(MaskIceLevelsetEnum);            _assert_(iceLS_input);
++
++	/* Start  looping on the number of gaussian points: */
++	Gauss* gauss=element->NewGauss();
++	for(int iv=0;iv<numvertices;iv++){
++		gauss->GaussVertex(iv);
++
++		/*Get input values at gauss points*/
++      phi_input->GetInputDerivativeValue(&dphi[0],xyz_list,gauss);
++      phi_input->GetInputValue(&phi,gauss);
++      h_input->GetInputValue(&h,gauss);
++      k_input->GetInputValue(&k,gauss);
++		oceanLS_input->GetInputValue(&oceanLS,gauss);
++		iceLS_input->GetInputValue(&iceLS,gauss);
++
++		/*Set sheet thickness to zero if floating or no ice*/
++		if(oceanLS<0. || iceLS>0.){
++			vx[iv] = 0.;
++         vy[iv] = 0.;
++		}
++		else{
++
++         /*Get norm of gradient of hydraulic potential and make sure it is >0*/
++         IssmDouble normgradphi = sqrt(dphi[0]*dphi[0] + dphi[1]*dphi[1]);
++         if(normgradphi < AEPS) normgradphi = AEPS;
++
++         IssmDouble coeff = k*pow(h,alpha)*pow(normgradphi,beta-2.)/max(AEPS,h); // divide by h to get speed instead of discharge
++
++			vx[iv] = -coeff*dphi[0];
++			vy[iv] = -coeff*dphi[1];
++		}
++	}
++
++	element->AddInput(HydrologyWaterVxEnum,vx,P1DGEnum);
++	element->AddInput(HydrologyWaterVyEnum,vy,P1DGEnum);
++
++	/*Clean up and return*/
++	xDelete<IssmDouble>(xyz_list);
++	xDelete<IssmDouble>(vx);
++	xDelete<IssmDouble>(vy);
++	delete gauss;
+ }/*}}}*/
+ void           HydrologyGlaDSAnalysis::UpdateConstraints(FemModel* femmodel){/*{{{*/
+ 
Index: /issm/oecreview/Archive/27230-27343/ISSM-27293-27294.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27293-27294.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27293-27294.diff	(revision 27344)
@@ -0,0 +1,76 @@
+Index: ../trunk-jpl/src/c/classes/Elements/Penta.cpp
+===================================================================
+--- ../trunk-jpl/src/c/classes/Elements/Penta.cpp	(revision 27293)
++++ ../trunk-jpl/src/c/classes/Elements/Penta.cpp	(revision 27294)
+@@ -3900,11 +3900,13 @@
+ IssmDouble Penta::TimeAdapt(void){/*{{{*/
+ 
+ 	/*intermediary: */
++	bool       ishydro;
+ 	IssmDouble C;
+ 	IssmDouble xyz_list[NUMVERTICES][3];
+ 
+ 	/*get CFL coefficient:*/
+ 	this->parameters->FindParam(&C,TimesteppingCflCoefficientEnum);
++	this->parameters->FindParam(&ishydro,TransientIshydrologyEnum);
+ 
+ 	/*Get for Vx and Vy, the max of abs value: */
+ 	Input* vx_input = this->GetInput(VxEnum); _assert_(vx_input);
+@@ -3939,6 +3941,20 @@
+ 	/*CFL criterion: */
+ 	IssmDouble dt = C/(maxabsvx/dx+maxabsvy/dy+maxabsvz/dz + 1.e-18);
+ 
++	/*Check hydro timestep also and take the minimum*/
++	if(ishydro){
++		if(IsOnBase()){
++			Input* vx_input = this->GetInput(HydrologyWaterVxEnum); _assert_(vx_input);
++			Input* vy_input = this->GetInput(HydrologyWaterVyEnum); _assert_(vy_input);
++			IssmDouble maxabsvx = vx_input->GetInputMaxAbs();
++			IssmDouble maxabsvy = vy_input->GetInputMaxAbs();
++
++			/*CFL criterion: */
++			IssmDouble dt2 = C/(maxabsvx/dx+maxabsvy/dy + 1.e-18);
++			if(dt2<dt) dt = dt2;
++		}
++	}
++
+ 	return dt;
+ }/*}}}*/
+ IssmDouble Penta::TotalCalvingFluxLevelset(bool scaled){/*{{{*/
+Index: ../trunk-jpl/src/c/classes/Elements/Tria.cpp
+===================================================================
+--- ../trunk-jpl/src/c/classes/Elements/Tria.cpp	(revision 27293)
++++ ../trunk-jpl/src/c/classes/Elements/Tria.cpp	(revision 27294)
+@@ -5252,11 +5252,13 @@
+ IssmDouble Tria::TimeAdapt(void){/*{{{*/
+ 
+ 	/*intermediary: */
++	bool       ishydro;
+ 	IssmDouble C;
+ 	IssmDouble xyz_list[NUMVERTICES][3];
+ 
+ 	/*get CFL coefficient:*/
+ 	this->parameters->FindParam(&C,TimesteppingCflCoefficientEnum);
++	this->parameters->FindParam(&ishydro,TransientIshydrologyEnum);
+ 
+ 	/*Get for Vx and Vy, the max of abs value: */
+ 	Input* vx_input = this->GetInput(VxEnum); _assert_(vx_input);
+@@ -5284,6 +5286,18 @@
+ 	/*CFL criterion: */
+ 	IssmDouble dt = C/(maxabsvx/dx+maxabsvy/dy + 1.e-18);
+ 
++	/*Check hydro timestep also and take the minimum*/
++	if(ishydro){
++		Input* vx_input = this->GetInput(HydrologyWaterVxEnum); _assert_(vx_input);
++		Input* vy_input = this->GetInput(HydrologyWaterVyEnum); _assert_(vy_input);
++		IssmDouble maxabsvx = vx_input->GetInputMaxAbs();
++		IssmDouble maxabsvy = vy_input->GetInputMaxAbs();
++
++		/*CFL criterion: */
++		IssmDouble dt2 = C/(maxabsvx/dx+maxabsvy/dy + 1.e-18);
++		if(dt2<dt) dt = dt2;
++	}
++
+ 	return dt;
+ }
+ /*}}}*/
Index: /issm/oecreview/Archive/27230-27343/ISSM-27294-27295.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27294-27295.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27294-27295.diff	(revision 27344)
@@ -0,0 +1,13 @@
+Index: ../trunk-jpl/src/c/analyses/HydrologyGlaDSAnalysis.cpp
+===================================================================
+--- ../trunk-jpl/src/c/analyses/HydrologyGlaDSAnalysis.cpp	(revision 27294)
++++ ../trunk-jpl/src/c/analyses/HydrologyGlaDSAnalysis.cpp	(revision 27295)
+@@ -144,6 +144,8 @@
+ 	iomodel->FetchDataToInput(inputs,elements,"md.initialization.watercolumn",HydrologySheetThicknessEnum);
+ 	iomodel->FetchDataToInput(inputs,elements,"md.initialization.hydraulic_potential",HydraulicPotentialEnum);
+ 	if(iomodel->domaintype==Domain2DhorizontalEnum){
++		iomodel->FetchDataToInput(inputs,elements,"md.initialization.vx",VxEnum);
++		iomodel->FetchDataToInput(inputs,elements,"md.initialization.vy",VyEnum);
+ 		iomodel->FetchDataToInput(inputs,elements,"md.initialization.vx",VxBaseEnum);
+ 		iomodel->FetchDataToInput(inputs,elements,"md.initialization.vy",VyBaseEnum);
+ 		iomodel->FindConstant(&frictionlaw,"md.friction.law");
Index: /issm/oecreview/Archive/27230-27343/ISSM-27295-27296.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27295-27296.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27295-27296.diff	(revision 27344)
@@ -0,0 +1,21 @@
+Index: ../trunk-jpl/src/c/classes/Elements/Tria.cpp
+===================================================================
+--- ../trunk-jpl/src/c/classes/Elements/Tria.cpp	(revision 27295)
++++ ../trunk-jpl/src/c/classes/Elements/Tria.cpp	(revision 27296)
+@@ -5288,10 +5288,12 @@
+ 
+ 	/*Check hydro timestep also and take the minimum*/
+ 	if(ishydro){
+-		Input* vx_input = this->GetInput(HydrologyWaterVxEnum); _assert_(vx_input);
+-		Input* vy_input = this->GetInput(HydrologyWaterVyEnum); _assert_(vy_input);
+-		IssmDouble maxabsvx = vx_input->GetInputMaxAbs();
+-		IssmDouble maxabsvy = vy_input->GetInputMaxAbs();
++		Input* vx_input = this->GetInput(HydrologyWaterVxEnum);
++		Input* vy_input = this->GetInput(HydrologyWaterVyEnum);
++		IssmDouble maxabsvx = 0.03;
++		IssmDouble maxabsvy = 0.03;
++		if(vx_input) maxabsvx = vx_input->GetInputMaxAbs();
++		if(vy_input) maxabsvy = vy_input->GetInputMaxAbs();
+ 
+ 		/*CFL criterion: */
+ 		IssmDouble dt2 = C/(maxabsvx/dx+maxabsvy/dy + 1.e-18);
Index: /issm/oecreview/Archive/27230-27343/ISSM-27296-27297.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27296-27297.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27296-27297.diff	(revision 27344)
@@ -0,0 +1,581 @@
+Index: ../trunk-jpl/src/c/analyses/SmbAnalysis.cpp
+===================================================================
+--- ../trunk-jpl/src/c/analyses/SmbAnalysis.cpp	(revision 27296)
++++ ../trunk-jpl/src/c/analyses/SmbAnalysis.cpp	(revision 27297)
+@@ -418,6 +418,9 @@
+ 		case SMBsemicEnum:
+ 			/*Nothing to add to parameters*/
+ 			break;
++		case SMBdebrisMLEnum:
++			/*Nothing to add to parameters*/
++			break;
+ 		default:
+ 			_error_("Surface mass balance model "<<EnumToStringx(smb_model)<<" not supported yet");
+ 	}
+@@ -483,9 +486,9 @@
+ 			SmbGradientsElax(femmodel);
+ 			break;
+ 		case SMBarmaEnum:
+-         if(VerboseSolution())_printf0_("    call smb arma module\n");
+-         Smbarmax(femmodel);
+-         break;
++			if(VerboseSolution())_printf0_("    call smb arma module\n");
++			Smbarmax(femmodel);
++			break;
+ 		case SMBhenningEnum:
+ 			if(VerboseSolution())_printf0_("  call smb Henning module\n");
+ 			SmbHenningx(femmodel);
+@@ -513,6 +516,10 @@
+ 			_error_("SEMIC not installed");
+ 			#endif //_HAVE_SEMIC_
+ 			break;
++		case SMBdebrisMLEnum:
++			if(VerboseSolution())_printf0_("        call smb debris Mayer & Liculli module\n");
++			SmbDebrisMLx(femmodel);
++			break;
+ 		default:
+ 			_error_("Surface mass balance model "<<EnumToStringx(smb_model)<<" not supported yet");
+ 	}
+Index: ../trunk-jpl/src/c/modules/SurfaceMassBalancex/SurfaceMassBalancex.cpp
+===================================================================
+--- ../trunk-jpl/src/c/modules/SurfaceMassBalancex/SurfaceMassBalancex.cpp	(revision 27296)
++++ ../trunk-jpl/src/c/modules/SurfaceMassBalancex/SurfaceMassBalancex.cpp	(revision 27297)
+@@ -505,6 +505,134 @@
+ 	}
+ 
+ }/*}}}*/
++void SmbDebrisMLx(FemModel* femmodel){/*{{{*/
++
++	//      The function is based on:
++	//      Evatt GW, Abrahams ID, Heil M, Mayer C, Kingslake J, Mitchell SL, et al. Glacial melt under a porous debris layer. Journal of Glaciology 61 (2015) 825–836, doi:10.3189/2
++	//      Constants/Values are taken from Mayer, Licciulli (2021): https://www.frontiersin.org/articles/10.3389/feart.2021.710276/full#B7
++	//      function taken from https://github.com/carlolic/DebrisExp/blob/main/USFs/USF_DebrisCoverage.f90
++
++	/*Intermediaries*/
++	// altitude gradients of the crucial parameters (radiation from Marty et al., TaAClimat; 2002)
++	IssmDouble LW=2.9;          // W/m^2 /100m                       2.9
++	IssmDouble SW=1.3;          // W/m^2 /100m                       1.3
++	IssmDouble HumidityG=0;     // % /100m         rough estimate
++	IssmDouble AirTemp=0.7;     // C /100m
++	IssmDouble WindSpeed=0.02;  // m/s /100m       rough estimate    0.2
++
++	// accumulation follows a linear increase above the ELA up to a plateau
++	IssmDouble AccG=0.1;                    // m w.e. /100m
++	IssmDouble AccMax=1.;                    // m w.e.
++	IssmDouble ReferenceElevation=2200.;     // m M&L
++	IssmDouble AblationDays=120.;            //
++
++	IssmDouble In=100.;                 // Wm^-2        incoming long wave
++	IssmDouble Q=500.;                  // Wm^-2        incoming short wave
++	IssmDouble K=0.585;                // Wm^-1K^-1    thermal conductivity          0.585
++	IssmDouble Qm=0.0012;              // kg m^-3      measured humiditiy level
++	IssmDouble Qh=0.006 ;              // kg m^-3      saturated humidity level
++	IssmDouble Tm=2.;                   // C            air temperature
++	IssmDouble Rhoaa=1.22;             // kgm^-3       air densitiy
++	IssmDouble Um=1.5;                 // ms^-1        measured wind speed
++	IssmDouble Xm=1.5;                 // ms^-1        measurement height
++        IssmDouble Xr=0.01;                // ms^-1        surface roughness             0.01
++        IssmDouble Alphad=0.07;            //              debris albedo                 0.07
++        IssmDouble Alphai=0.4;             //              ice ablbedo
++        IssmDouble Ustar=0.16;             // ms^-1        friction velocity             0.16
++        IssmDouble Ca=1000.;                // jkg^-1K^-1   specific heat capacity of air
++        IssmDouble Lm;//=3.34E+05;            // jkg^-1K^-1   latent heat of ice melt
++        IssmDouble Lv=2.50E+06;            // jkg^-1K^-1   latent heat of evaporation
++        IssmDouble Tf=273.;                 // K            water freeezing temperature
++        IssmDouble Eps=0.95;               //              thermal emissivity
++        IssmDouble Rhoi=900.;               // kgm^-3       ice density
++        IssmDouble Sigma=5.67E-08;         // Wm^-2K^-4    Stefan Boltzmann constant
++        IssmDouble Kstar=0.4;              //              von kármán constant
++        IssmDouble Gamma=180.;              // m^-1         wind speed attenuation        234
++	IssmDouble PhiD;//=0.005;              //              debris packing fraction       0.01
++	IssmDouble Humidity=0.2;           //              relative humidity
++
++	IssmDouble smb,yts,z,debris;
++	IssmDouble MassBalanceCmDayDebris,MassBalanceMYearDebris;
++
++	/*Get material parameters and constants */
++	//femmodel->parameters->FindParam(&Rhoi,MaterialsRhoIceEnum); // Note Carlo's model used as  benchmark was run with different densities for debris and FS
++	femmodel->parameters->FindParam(&Lm,MaterialsLatentheatEnum);
++	femmodel->parameters->FindParam(&yts,ConstantsYtsEnum); 
++	PhiD=0.;
++	//if(isdebris) femmodel->parameters->FindParam(&PhiD,DebrisPackingFractionEnum);
++
++	/* Loop over all the elements of this partition */
++	for(Object* & object : femmodel->elements->objects){
++		Element* element=xDynamicCast<Element*>(object);
++
++		/* Allocate all arrays */
++		int         numvertices=element->GetNumberOfVertices();
++		IssmDouble* surfacelist=xNew<IssmDouble>(numvertices);
++		IssmDouble* smb=xNew<IssmDouble>(numvertices);
++		IssmDouble* debriscover=xNew<IssmDouble>(numvertices);
++		element->GetInputListOnVertices(surfacelist,SurfaceEnum);
++
++		/* Get inputs */
++		element->GetInputListOnVertices(debriscover,DebrisThicknessEnum);
++
++		/*Loop over all vertices of element and calculate SMB as function of Debris Cover and z */
++		for(int v=0;v<numvertices;v++){
++
++                        /*Get vertex elevation */
++                        z=surfacelist[v];
++
++                        /* Get debris cover */
++                        debris=debriscover[v];
++
++                        /*IssmDouble dk=1e-5; // TODO make Alphad and Alphai a user input
++                        IssmDouble n=debris/dk;
++                        IssmDouble nmax=1000;
++                        IssmDouble Alphaeff;
++                        if(n>nmax){
++                                Alphaeff=Alphad;
++                        } else {
++                                Alphaeff=Alphai+n*(Alphad-Alphai)/nmax;
++                        }*/
++
++                        // M&L
++                       IssmDouble Alphaeff=Alphad;
++
++                        /* compute smb */
++                        for (int ismb=0;ismb<2;ismb++){
++                                if(ismb==0){
++                                        // calc a reference smb to identify accum and melt region; debris only develops in ablation area
++                                        debris=0.;
++                                }else{
++                                	// only in the meltregime debris develops
++                                        if(-MassBalanceCmDayDebris<0) debris=debriscover[v]; 
++                                }
++                                MassBalanceCmDayDebris=(((In-(z-ReferenceElevation)*LW/100.)-(Eps*Sigma*(Tf*Tf*Tf*Tf))+ 
++                                    (Q+(z-ReferenceElevation)*SW/100.)*(1.-Alphaeff)+ 
++                                    (Rhoaa*Ca*Ustar*Ustar)/((Um-(z-ReferenceElevation)* 
++                                    WindSpeed/100.)-Ustar*(2.-(exp(Gamma*Xr))))*(Tm-(z- 
++                                    ReferenceElevation)*AirTemp/100.))/((1-PhiD)*Rhoi*Lm)/(1.+ 
++                                    ((Rhoaa*Ca*Ustar*Ustar)/((Um-(z-ReferenceElevation)* 
++                                    WindSpeed/100.)-Ustar*(2.-(exp(Gamma*Xr))))+4.*Eps*Sigma*(Tf*Tf*Tf))/ 
++                                    K*debris)-(Lv*Ustar*Ustar*(Qh-(Qh*(Humidity-(z- 
++                                    ReferenceElevation)*HumidityG/100.)))*(exp(-Gamma*Xr)))/((1.-PhiD)* 
++                                    Rhoi*Lm*Ustar)/((((Um-(z-ReferenceElevation)*WindSpeed/100.) 
++                                    -2.*Ustar)*exp(-Gamma*Xr))/Ustar+exp(Gamma*debris)))*100.*24.*60.*60.;
++                        }
++
++                        /* account form ablation days, and convert to m/s */
++			MassBalanceMYearDebris=-MassBalanceCmDayDebris/100.*AblationDays/yts;
++
++			/*Update array accordingly*/
++			smb[v]=MassBalanceMYearDebris;
++		}
++
++		/*Add input to element and Free memory*/
++		element->AddInput(SmbMassBalanceEnum,smb,P1Enum);
++		xDelete<IssmDouble>(surfacelist);
++		xDelete<IssmDouble>(smb);
++		xDelete<IssmDouble>(debriscover);
++	}
++}/*}}}*/
+ void SmbGradientsComponentsx(FemModel* femmodel){/*{{{*/
+ 
+ 	for(Object* & object : femmodel->elements->objects){
+Index: ../trunk-jpl/src/c/modules/SurfaceMassBalancex/SurfaceMassBalancex.h
+===================================================================
+--- ../trunk-jpl/src/c/modules/SurfaceMassBalancex/SurfaceMassBalancex.h	(revision 27296)
++++ ../trunk-jpl/src/c/modules/SurfaceMassBalancex/SurfaceMassBalancex.h	(revision 27297)
+@@ -22,6 +22,7 @@
+ void SmbComponentsx(FemModel* femmodel);
+ void SmbMeltComponentsx(FemModel* femmodel);
+ void SmbGradientsComponentsx(FemModel* femmodel);
++void SmbDebrisMLx(FemModel* femmodel);
+ /* SEMIC: */
+ void SmbSemicx(FemModel* femmodel);
+ /*GEMB: */
+Index: ../trunk-jpl/src/c/shared/io/Marshalling/IoCodeConversions.cpp
+===================================================================
+--- ../trunk-jpl/src/c/shared/io/Marshalling/IoCodeConversions.cpp	(revision 27296)
++++ ../trunk-jpl/src/c/shared/io/Marshalling/IoCodeConversions.cpp	(revision 27297)
+@@ -239,8 +239,9 @@
+ 		case 9: return SMBgradientselaEnum;
+ 		case 10: return SMBpddSicopolisEnum;
+ 		case 11: return SMBgradientscomponentsEnum;
+-		case 12: return SMBsemicEnum;	
++		case 12: return SMBsemicEnum;	 
+ 		case 13: return SMBarmaEnum;
++		case 14: return SMBdebrisMLEnum;
+ 		default: _error_("Marshalled SMB code \""<<enum_in<<"\" not supported yet");
+ 	}
+ }/*}}}*/
+Index: ../trunk-jpl/src/m/classes/SMBdebrisML.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/SMBdebrisML.m	(nonexistent)
++++ ../trunk-jpl/src/m/classes/SMBdebrisML.m	(revision 27297)
+@@ -0,0 +1,73 @@
++%SMBdebriscover Class definition
++%
++%   Usage:
++%      SMBdebriscover=SMBdebriscover();
++
++classdef SMBdebriscover
++	properties (SetAccess=public)
++		steps_per_step=1;
++		averaging=0;
++		requested_outputs      = {};
++	end
++	methods
++		function self = SMBhenning(varargin) % {{{
++			switch nargin
++				case 0
++				case 1
++					inputstruct=varargin{1};
++					list1 = properties('SMBdebriscover');
++						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 self = extrude(self,md) % {{{
++
++		end % }}}
++		function list = defaultoutputs(self,md) % {{{
++			list = {''};
++		end % }}}
++		function self = initialize(self,md) % {{{
++
++		end % }}}
++		function md = checkconsistency(self,md,solution,analyses) % {{{
++
++			md = checkfield(md,'fieldname','smb.steps_per_step','>=',1,'numel',[1]);
++			md = checkfield(md,'fieldname','smb.averaging','numel',[1],'values',[0 1 2]);
++			md = checkfield(md,'fieldname','smb.requested_outputs','stringrow',1);
++		end % }}}
++		function disp(self) % {{{
++			disp(sprintf('   surface forcings parameters:'));
++			fielddisplay(self, 'steps_per_step', 'number of smb steps per time step');
++			fielddisplay(self, 'averaging', 'averaging methods from short to long steps');
++			disp(sprintf('%51s  0: Arithmetic (default)',' '));
++			disp(sprintf('%51s  1: Geometric',' '));
++			disp(sprintf('%51s  2: Harmonic',' '));
++			fielddisplay(self,'requested_outputs','additional outputs requested');
++		end % }}}
++		function marshall(self,prefix,md,fid) % {{{
++
++			yts=md.constants.yts;
++
++			WriteData(fid,prefix,'name','md.smb.model','data',14,'format','Integer');
++			WriteData(fid, prefix, 'object', self, 'fieldname', 'steps_per_step', 'format', 'Integer');
++			WriteData(fid, prefix, 'object', self, 'fieldname', 'averaging', 'format', 'Integer');
++
++			%process requested outputs
++			outputs = self.requested_outputs;
++			pos  = find(ismember(outputs,'default'));
++			if ~isempty(pos),
++				outputs(pos) = [];                         %remove 'default' from outputs
++				outputs      = [outputs defaultoutputs(self,md)]; %add defaults
++			end
++			WriteData(fid,prefix,'data',outputs,'name','md.smb.requested_outputs','format','StringArray');
++
++		end % }}}
++	end
++end
+Index: ../trunk-jpl/src/m/classes/initialization.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/initialization.m	(revision 27296)
++++ ../trunk-jpl/src/m/classes/initialization.m	(revision 27297)
+@@ -24,6 +24,7 @@
+ 		dsl                 = NaN;
+ 		str                 = NaN;
+ 		sample              = NaN;
++                debris              = NaN;
+ 	end
+ 	methods
+ 		function self = initialization(varargin) % {{{
+@@ -122,6 +123,11 @@
+ 					md = checkfield(md,'fieldname','initialization.sample','NaN',1,'Inf',1,'size',[md.mesh.numberofvertices 1]);
+ 				end
+ 			end
++			if ismember('DebrisAnalysis',analyses),
++				if ~isnan(md.initialization.debris)
++					md = checkfield(md,'fieldname','initialization.debris','NaN',1,'Inf',1,'size',[md.mesh.numberofvertices 1]);
++				end
++			end
+ 		end % }}}
+ 		function disp(self) % {{{
+ 			disp(sprintf('   initial field values:'));
+@@ -144,6 +150,7 @@
+ 			fielddisplay(self,'bottompressure','Bottom pressures');
+ 			fielddisplay(self,'dsl','Dynamic sea level.');
+ 			fielddisplay(self,'str','Steric sea level.');
++			fielddisplay(self,'debris','Surface debris layer [m]');
+ 		end % }}}
+ 		function marshall(self,prefix,md,fid) % {{{
+ 
+@@ -166,6 +173,7 @@
+ 			WriteData(fid,prefix,'object',self,'fieldname','channelarea','format','DoubleMat','mattype',1);
+ 			WriteData(fid,prefix,'object',self,'fieldname','hydraulic_potential','format','DoubleMat','mattype',1);
+ 			WriteData(fid,prefix,'object',self,'fieldname','sample','format','DoubleMat','mattype',1);
++			WriteData(fid,prefix,'object',self,'fieldname','debris','format','DoubleMat','mattype',1);
+ 
+ 			if md.thermal.isenthalpy,
+ 				if numel(self.enthalpy) <= 1,
+@@ -196,6 +204,7 @@
+ 			self.bottompressure=project3d(md,'vector',self.bottompressure,'type','node','layer',1);
+ 			self.dsl=project3d(md,'vector',self.dsl,'type','node','layer',1);
+ 			self.str=project3d(md,'vector',self.str,'type','node','layer',1);
++			self.str=project3d(md,'vector',self.debris,'type','node','layer',1);
+ 
+ 			%Lithostatic pressure by default
+ 			self.pressure=md.constants.g*md.materials.rho_ice*(md.geometry.surface-md.mesh.z);
+@@ -217,6 +226,7 @@
+ 			writejs1Darray(fid,[modelname '.initialization.hydraulic_potential'],self.hydraulic_potential);
+ 			writejs1Darray(fid,[modelname '.initialization.channel'],self.channelarea);
+ 			writejs1Darray(fid,[modelname '.initialization.sample'],self.sample);
++			writejs1Darray(fid,[modelname '.initialization.debris'],self.debris);
+ 
+ 		end % }}}
+ 	end
+Index: ../trunk-jpl/src/c/modules/ModelProcessorx/CreateParameters.cpp
+===================================================================
+--- ../trunk-jpl/src/c/modules/ModelProcessorx/CreateParameters.cpp	(revision 27296)
++++ ../trunk-jpl/src/c/modules/ModelProcessorx/CreateParameters.cpp	(revision 27297)
+@@ -484,6 +484,8 @@
+ 			parameters->AddObject(iomodel->CopyConstantObject("md.smb.rlaps",SmbRlapsEnum));
+ 			parameters->AddObject(iomodel->CopyConstantObject("md.smb.rdl",SmbRdlEnum));
+ 			break;
++		case SMBdebrisMLEnum:
++			break;
+ 		default:
+ 			_error_("Surface mass balance model "<<EnumToStringx(smb_model)<<" not supported yet");
+ 	}
+Index: ../trunk-jpl/src/c/shared/Enum/EnumDefinitions.h
+===================================================================
+--- ../trunk-jpl/src/c/shared/Enum/EnumDefinitions.h	(revision 27296)
++++ ../trunk-jpl/src/c/shared/Enum/EnumDefinitions.h	(revision 27297)
+@@ -156,6 +156,7 @@
+ 	DamageStressThresholdEnum,
+ 	DamageStressUBoundEnum,
+ 	DebugProfilingEnum,
++	DebrisThicknessEnum,
+ 	DomainDimensionEnum,
+ 	DomainTypeEnum,
+ 	DslModelEnum,
+@@ -1540,6 +1541,7 @@
+ 	SIAApproximationEnum,
+ 	SMBarmaEnum,
+ 	SMBcomponentsEnum,
++	SMBdebrisMLEnum,
+ 	SMBd18opddEnum,
+ 	SMBforcingEnum,
+ 	SMBgcmEnum,
+Index: ../trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp
+===================================================================
+--- ../trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp	(revision 27296)
++++ ../trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp	(revision 27297)
+@@ -164,6 +164,7 @@
+ 		case DamageStressThresholdEnum : return "DamageStressThreshold";
+ 		case DamageStressUBoundEnum : return "DamageStressUBound";
+ 		case DebugProfilingEnum : return "DebugProfiling";
++		case DebrisThicknessEnum : return "DebrisThickness";
+ 		case DomainDimensionEnum : return "DomainDimension";
+ 		case DomainTypeEnum : return "DomainType";
+ 		case DslModelEnum : return "DslModel";
+@@ -1543,6 +1544,7 @@
+ 		case SIAApproximationEnum : return "SIAApproximation";
+ 		case SMBarmaEnum : return "SMBarma";
+ 		case SMBcomponentsEnum : return "SMBcomponents";
++		case SMBdebrisMLEnum : return "SMBdebrisML";
+ 		case SMBd18opddEnum : return "SMBd18opdd";
+ 		case SMBforcingEnum : return "SMBforcing";
+ 		case SMBgcmEnum : return "SMBgcm";
+Index: ../trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp
+===================================================================
+--- ../trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp	(revision 27296)
++++ ../trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp	(revision 27297)
+@@ -167,6 +167,7 @@
+ 	      else if (strcmp(name,"DamageStressThreshold")==0) return DamageStressThresholdEnum;
+ 	      else if (strcmp(name,"DamageStressUBound")==0) return DamageStressUBoundEnum;
+ 	      else if (strcmp(name,"DebugProfiling")==0) return DebugProfilingEnum;
++	      else if (strcmp(name,"DebrisThickness")==0) return DebrisThicknessEnum;
+ 	      else if (strcmp(name,"DomainDimension")==0) return DomainDimensionEnum;
+ 	      else if (strcmp(name,"DomainType")==0) return DomainTypeEnum;
+ 	      else if (strcmp(name,"DslModel")==0) return DslModelEnum;
+@@ -258,11 +259,11 @@
+ 	      else if (strcmp(name,"HydrologydcSedimentPorosity")==0) return HydrologydcSedimentPorosityEnum;
+ 	      else if (strcmp(name,"HydrologydcSedimentThickness")==0) return HydrologydcSedimentThicknessEnum;
+ 	      else if (strcmp(name,"HydrologyStepAdapt")==0) return HydrologyStepAdaptEnum;
+-	      else if (strcmp(name,"HydrologydcTransferFlag")==0) return HydrologydcTransferFlagEnum;
+          else stage=3;
+    }
+    if(stage==3){
+-	      if (strcmp(name,"HydrologydcUnconfinedFlag")==0) return HydrologydcUnconfinedFlagEnum;
++	      if (strcmp(name,"HydrologydcTransferFlag")==0) return HydrologydcTransferFlagEnum;
++	      else if (strcmp(name,"HydrologydcUnconfinedFlag")==0) return HydrologydcUnconfinedFlagEnum;
+ 	      else if (strcmp(name,"HydrologyshreveStabilization")==0) return HydrologyshreveStabilizationEnum;
+ 	      else if (strcmp(name,"IcecapToEarthComm")==0) return IcecapToEarthCommEnum;
+ 	      else if (strcmp(name,"Index")==0) return IndexEnum;
+@@ -381,11 +382,11 @@
+ 	      else if (strcmp(name,"QmuNsample")==0) return QmuNsampleEnum;
+ 	      else if (strcmp(name,"QmuResponsedescriptors")==0) return QmuResponsedescriptorsEnum;
+ 	      else if (strcmp(name,"QmuVariableDescriptors")==0) return QmuVariableDescriptorsEnum;
+-	      else if (strcmp(name,"QmuVariablePartitions")==0) return QmuVariablePartitionsEnum;
+          else stage=4;
+    }
+    if(stage==4){
+-	      if (strcmp(name,"QmuVariablePartitionsNpart")==0) return QmuVariablePartitionsNpartEnum;
++	      if (strcmp(name,"QmuVariablePartitions")==0) return QmuVariablePartitionsEnum;
++	      else if (strcmp(name,"QmuVariablePartitionsNpart")==0) return QmuVariablePartitionsNpartEnum;
+ 	      else if (strcmp(name,"QmuVariablePartitionsNt")==0) return QmuVariablePartitionsNtEnum;
+ 	      else if (strcmp(name,"QmuResponsePartitions")==0) return QmuResponsePartitionsEnum;
+ 	      else if (strcmp(name,"QmuResponsePartitionsNpart")==0) return QmuResponsePartitionsNpartEnum;
+@@ -504,11 +505,11 @@
+ 	      else if (strcmp(name,"SmbDsnowIdx")==0) return SmbDsnowIdxEnum;
+ 	      else if (strcmp(name,"SmbElevationBins")==0) return SmbElevationBinsEnum;
+ 	      else if (strcmp(name,"SmbCldFrac")==0) return SmbCldFracEnum;
+-	      else if (strcmp(name,"SmbDelta18o")==0) return SmbDelta18oEnum;
+          else stage=5;
+    }
+    if(stage==5){
+-	      if (strcmp(name,"SmbDelta18oSurface")==0) return SmbDelta18oSurfaceEnum;
++	      if (strcmp(name,"SmbDelta18o")==0) return SmbDelta18oEnum;
++	      else if (strcmp(name,"SmbDelta18oSurface")==0) return SmbDelta18oSurfaceEnum;
+ 	      else if (strcmp(name,"SmbDenIdx")==0) return SmbDenIdxEnum;
+ 	      else if (strcmp(name,"SmbDt")==0) return SmbDtEnum;
+ 	      else if (strcmp(name,"Smb")==0) return SmbEnum;
+@@ -627,11 +628,11 @@
+ 	      else if (strcmp(name,"TransientNumRequestedOutputs")==0) return TransientNumRequestedOutputsEnum;
+ 	      else if (strcmp(name,"TransientRequestedOutputs")==0) return TransientRequestedOutputsEnum;
+ 	      else if (strcmp(name,"Velocity")==0) return VelocityEnum;
+-	      else if (strcmp(name,"Xxe")==0) return XxeEnum;
+          else stage=6;
+    }
+    if(stage==6){
+-	      if (strcmp(name,"Yye")==0) return YyeEnum;
++	      if (strcmp(name,"Xxe")==0) return XxeEnum;
++	      else if (strcmp(name,"Yye")==0) return YyeEnum;
+ 	      else if (strcmp(name,"Zze")==0) return ZzeEnum;
+ 	      else if (strcmp(name,"Areae")==0) return AreaeEnum;
+ 	      else if (strcmp(name,"WorldComm")==0) return WorldCommEnum;
+@@ -750,11 +751,11 @@
+ 	      else if (strcmp(name,"Domain2Dvertical")==0) return Domain2DverticalEnum;
+ 	      else if (strcmp(name,"Domain3D")==0) return Domain3DEnum;
+ 	      else if (strcmp(name,"DragCoefficientAbsGradient")==0) return DragCoefficientAbsGradientEnum;
+-	      else if (strcmp(name,"DrivingStressX")==0) return DrivingStressXEnum;
+          else stage=7;
+    }
+    if(stage==7){
+-	      if (strcmp(name,"DrivingStressY")==0) return DrivingStressYEnum;
++	      if (strcmp(name,"DrivingStressX")==0) return DrivingStressXEnum;
++	      else if (strcmp(name,"DrivingStressY")==0) return DrivingStressYEnum;
+ 	      else if (strcmp(name,"Dummy")==0) return DummyEnum;
+ 	      else if (strcmp(name,"EffectivePressure")==0) return EffectivePressureEnum;
+ 	      else if (strcmp(name,"EffectivePressureSubstep")==0) return EffectivePressureSubstepEnum;
+@@ -873,11 +874,11 @@
+ 	      else if (strcmp(name,"MeshVertexonbase")==0) return MeshVertexonbaseEnum;
+ 	      else if (strcmp(name,"MeshVertexonboundary")==0) return MeshVertexonboundaryEnum;
+ 	      else if (strcmp(name,"MeshVertexonsurface")==0) return MeshVertexonsurfaceEnum;
+-	      else if (strcmp(name,"Misfit")==0) return MisfitEnum;
+          else stage=8;
+    }
+    if(stage==8){
+-	      if (strcmp(name,"MovingFrontalVx")==0) return MovingFrontalVxEnum;
++	      if (strcmp(name,"Misfit")==0) return MisfitEnum;
++	      else if (strcmp(name,"MovingFrontalVx")==0) return MovingFrontalVxEnum;
+ 	      else if (strcmp(name,"MovingFrontalVy")==0) return MovingFrontalVyEnum;
+ 	      else if (strcmp(name,"Neumannflux")==0) return NeumannfluxEnum;
+ 	      else if (strcmp(name,"NewDamage")==0) return NewDamageEnum;
+@@ -996,11 +997,11 @@
+ 	      else if (strcmp(name,"SmbBPos")==0) return SmbBPosEnum;
+ 	      else if (strcmp(name,"SmbC")==0) return SmbCEnum;
+ 	      else if (strcmp(name,"SmbCcsnowValue")==0) return SmbCcsnowValueEnum;
+-	      else if (strcmp(name,"SmbCciceValue")==0) return SmbCciceValueEnum;
+          else stage=9;
+    }
+    if(stage==9){
+-	      if (strcmp(name,"SmbCotValue")==0) return SmbCotValueEnum;
++	      if (strcmp(name,"SmbCciceValue")==0) return SmbCciceValueEnum;
++	      else if (strcmp(name,"SmbCotValue")==0) return SmbCotValueEnum;
+ 	      else if (strcmp(name,"SmbD")==0) return SmbDEnum;
+ 	      else if (strcmp(name,"SmbDailyairdensity")==0) return SmbDailyairdensityEnum;
+ 	      else if (strcmp(name,"SmbDailyairhumidity")==0) return SmbDailyairhumidityEnum;
+@@ -1119,11 +1120,11 @@
+ 	      else if (strcmp(name,"SurfaceArea")==0) return SurfaceAreaEnum;
+ 	      else if (strcmp(name,"SurfaceAverageVelMisfit")==0) return SurfaceAverageVelMisfitEnum;
+ 	      else if (strcmp(name,"SurfaceCrevasse")==0) return SurfaceCrevasseEnum;
+-	      else if (strcmp(name,"Surface")==0) return SurfaceEnum;
+          else stage=10;
+    }
+    if(stage==10){
+-	      if (strcmp(name,"SurfaceOld")==0) return SurfaceOldEnum;
++	      if (strcmp(name,"Surface")==0) return SurfaceEnum;
++	      else if (strcmp(name,"SurfaceOld")==0) return SurfaceOldEnum;
+ 	      else if (strcmp(name,"SurfaceLogVelMisfit")==0) return SurfaceLogVelMisfitEnum;
+ 	      else if (strcmp(name,"SurfaceLogVxVyMisfit")==0) return SurfaceLogVxVyMisfitEnum;
+ 	      else if (strcmp(name,"SurfaceObservation")==0) return SurfaceObservationEnum;
+@@ -1242,11 +1243,11 @@
+ 	      else if (strcmp(name,"Outputdefinition65")==0) return Outputdefinition65Enum;
+ 	      else if (strcmp(name,"Outputdefinition66")==0) return Outputdefinition66Enum;
+ 	      else if (strcmp(name,"Outputdefinition67")==0) return Outputdefinition67Enum;
+-	      else if (strcmp(name,"Outputdefinition68")==0) return Outputdefinition68Enum;
+          else stage=11;
+    }
+    if(stage==11){
+-	      if (strcmp(name,"Outputdefinition69")==0) return Outputdefinition69Enum;
++	      if (strcmp(name,"Outputdefinition68")==0) return Outputdefinition68Enum;
++	      else if (strcmp(name,"Outputdefinition69")==0) return Outputdefinition69Enum;
+ 	      else if (strcmp(name,"Outputdefinition6")==0) return Outputdefinition6Enum;
+ 	      else if (strcmp(name,"Outputdefinition70")==0) return Outputdefinition70Enum;
+ 	      else if (strcmp(name,"Outputdefinition71")==0) return Outputdefinition71Enum;
+@@ -1365,11 +1366,11 @@
+ 	      else if (strcmp(name,"DoubleMatExternalResult")==0) return DoubleMatExternalResultEnum;
+ 	      else if (strcmp(name,"DoubleMatParam")==0) return DoubleMatParamEnum;
+ 	      else if (strcmp(name,"DoubleParam")==0) return DoubleParamEnum;
+-	      else if (strcmp(name,"DoubleVecParam")==0) return DoubleVecParamEnum;
+          else stage=12;
+    }
+    if(stage==12){
+-	      if (strcmp(name,"Element")==0) return ElementEnum;
++	      if (strcmp(name,"DoubleVecParam")==0) return DoubleVecParamEnum;
++	      else if (strcmp(name,"Element")==0) return ElementEnum;
+ 	      else if (strcmp(name,"ElementHook")==0) return ElementHookEnum;
+ 	      else if (strcmp(name,"ElementSId")==0) return ElementSIdEnum;
+ 	      else if (strcmp(name,"EnthalpyAnalysis")==0) return EnthalpyAnalysisEnum;
+@@ -1488,11 +1489,11 @@
+ 	      else if (strcmp(name,"MINIcondensed")==0) return MINIcondensedEnum;
+ 	      else if (strcmp(name,"MantlePlumeGeothermalFlux")==0) return MantlePlumeGeothermalFluxEnum;
+ 	      else if (strcmp(name,"MassFlux")==0) return MassFluxEnum;
+-	      else if (strcmp(name,"Masscon")==0) return MassconEnum;
+          else stage=13;
+    }
+    if(stage==13){
+-	      if (strcmp(name,"Massconaxpby")==0) return MassconaxpbyEnum;
++	      if (strcmp(name,"Masscon")==0) return MassconEnum;
++	      else if (strcmp(name,"Massconaxpby")==0) return MassconaxpbyEnum;
+ 	      else if (strcmp(name,"Massfluxatgate")==0) return MassfluxatgateEnum;
+ 	      else if (strcmp(name,"MasstransportAnalysis")==0) return MasstransportAnalysisEnum;
+ 	      else if (strcmp(name,"MasstransportSolution")==0) return MasstransportSolutionEnum;
+@@ -1579,6 +1580,7 @@
+ 	      else if (strcmp(name,"SIAApproximation")==0) return SIAApproximationEnum;
+ 	      else if (strcmp(name,"SMBarma")==0) return SMBarmaEnum;
+ 	      else if (strcmp(name,"SMBcomponents")==0) return SMBcomponentsEnum;
++	      else if (strcmp(name,"SMBdebrisML")==0) return SMBdebrisMLEnum;
+ 	      else if (strcmp(name,"SMBd18opdd")==0) return SMBd18opddEnum;
+ 	      else if (strcmp(name,"SMBforcing")==0) return SMBforcingEnum;
+ 	      else if (strcmp(name,"SMBgcm")==0) return SMBgcmEnum;
+@@ -1610,12 +1612,12 @@
+ 	      else if (strcmp(name,"SegmentRiftfront")==0) return SegmentRiftfrontEnum;
+ 	      else if (strcmp(name,"Separate")==0) return SeparateEnum;
+ 	      else if (strcmp(name,"Seq")==0) return SeqEnum;
+-	      else if (strcmp(name,"SmbAnalysis")==0) return SmbAnalysisEnum;
+-	      else if (strcmp(name,"SmbSolution")==0) return SmbSolutionEnum;
+          else stage=14;
+    }
+    if(stage==14){
+-	      if (strcmp(name,"SmoothAnalysis")==0) return SmoothAnalysisEnum;
++	      if (strcmp(name,"SmbAnalysis")==0) return SmbAnalysisEnum;
++	      else if (strcmp(name,"SmbSolution")==0) return SmbSolutionEnum;
++	      else if (strcmp(name,"SmoothAnalysis")==0) return SmoothAnalysisEnum;
+ 	      else if (strcmp(name,"SoftMigration")==0) return SoftMigrationEnum;
+ 	      else if (strcmp(name,"SpatialLinearFloatingMeltRate")==0) return SpatialLinearFloatingMeltRateEnum;
+ 	      else if (strcmp(name,"SpcDynamic")==0) return SpcDynamicEnum;
Index: /issm/oecreview/Archive/27230-27343/ISSM-27297-27298.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27297-27298.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27297-27298.diff	(revision 27344)
@@ -0,0 +1,1938 @@
+Index: ../trunk-jpl/src/c/Makefile.am
+===================================================================
+--- ../trunk-jpl/src/c/Makefile.am	(revision 27297)
++++ ../trunk-jpl/src/c/Makefile.am	(revision 27298)
+@@ -283,6 +283,7 @@
+ 	./cores/thermal_core.cpp \
+ 	./cores/smb_core.cpp \
+ 	./cores/bmb_core.cpp \
++	./cores/debris_core.cpp \
+ 	./solutionsequences/solutionsequence_thermal_nonlinear.cpp \
+ 	./modules/ControlInputSetGradientx/ControlInputSetGradientx.cpp \
+ 	./modules/GetVectorFromControlInputsx/GetVectorFromControlInputsx.cpp \
+@@ -442,6 +443,9 @@
+ issm_sources += ./analyses/DamageEvolutionAnalysis.cpp
+ issm_sources += ./modules/Damagex/Damagex.cpp
+ endif
++if DEBRIS
++issm_sources += ./analyses/DebrisAnalysis.cpp
++endif
+ if STRESSBALANCE
+ issm_sources += ./analyses/StressbalanceAnalysis.cpp
+ endif
+Index: ../trunk-jpl/src/c/analyses/DebrisAnalysis.cpp
+===================================================================
+--- ../trunk-jpl/src/c/analyses/DebrisAnalysis.cpp	(nonexistent)
++++ ../trunk-jpl/src/c/analyses/DebrisAnalysis.cpp	(revision 27298)
+@@ -0,0 +1,905 @@
++#include "./DebrisAnalysis.h"
++#include "../toolkits/toolkits.h"
++#include "../classes/classes.h"
++#include "../shared/shared.h"
++#include "../modules/modules.h"
++#include "../classes/Inputs/TransientInput.h"
++#include "../solutionsequences/solutionsequences.h"
++#include "../cores/cores.h"
++#include <math.h>
++
++#define FINITEELEMENT P1Enum
++
++/*Model processing*/
++void DebrisAnalysis::CreateConstraints(Constraints* constraints,IoModel* iomodel){/*{{{*/
++
++	/*add constraints*/
++	IoModelToConstraintsx(constraints,iomodel,"md.debris.spcthickness",DebrisAnalysisEnum,FINITEELEMENT);
++
++}/*}}}*/
++void DebrisAnalysis::CreateLoads(Loads* loads, IoModel* iomodel){/*{{{*/
++
++	/*Intermediaries*/
++	int penpair_ids[2];
++	int count=0;
++	int numvertex_pairing;
++
++	/*Create Penpair for vertex_pairing: */
++	IssmDouble *vertex_pairing=NULL;
++	IssmDouble *nodeonsurface=NULL;
++	iomodel->FetchData(&vertex_pairing,&numvertex_pairing,NULL,"md.debris.vertex_pairing");
++	if(iomodel->domaintype!=Domain2DhorizontalEnum) iomodel->FetchData(&nodeonsurface,NULL,NULL,"md.mesh.vertexonsurface");
++	for(int i=0;i<numvertex_pairing;i++){
++
++		if(iomodel->my_vertices[reCast<int>(vertex_pairing[2*i+0])-1]){
++
++			/*In debugging mode, check that the second node is in the same cpu*/
++			_assert_(iomodel->my_vertices[reCast<int>(vertex_pairing[2*i+1])-1]);
++
++			/*Skip if one of the two is not on the bed*/
++			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*/
++			penpair_ids[0]=reCast<int>(vertex_pairing[2*i+0]);
++			penpair_ids[1]=reCast<int>(vertex_pairing[2*i+1]);
++
++			/*Create Load*/
++			loads->AddObject(new Penpair(count+1,&penpair_ids[0]));
++			count++;
++		}
++	}
++
++	/*free ressources: */
++	iomodel->DeleteData(vertex_pairing,"md.debris.vertex_pairing");
++	iomodel->DeleteData(nodeonsurface,"md.mesh.vertexonsurface");
++}/*}}}*/
++void DebrisAnalysis::CreateNodes(Nodes* nodes,IoModel* iomodel,bool isamr){/*{{{*/
++
++	if(iomodel->domaintype!=Domain2DhorizontalEnum) iomodel->FetchData(2,"md.mesh.vertexonbase","md.mesh.vertexonsurface");
++	::CreateNodes(nodes,iomodel,DebrisAnalysisEnum,FINITEELEMENT);
++	iomodel->DeleteData(2,"md.mesh.vertexonbase","md.mesh.vertexonsurface");
++
++}/*}}}*/
++int  DebrisAnalysis::DofsPerNode(int** doflist,int domaintype,int approximation){/*{{{*/
++	return 1;
++}/*}}}*/
++void DebrisAnalysis::UpdateElements(Elements* elements,Inputs* inputs,IoModel* iomodel,int analysis_counter,int analysis_type){/*{{{*/
++
++	/*Now, is the model 3d? otherwise, do nothing: */
++	if (iomodel->domaintype==Domain2DhorizontalEnum)return;
++
++	int smb_model;
++
++	/*Fetch data needed: */
++	iomodel->FindConstant(&smb_model,"md.smb.model");
++
++	/*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(inputs,i,iomodel,analysis_counter,analysis_type,FINITEELEMENT);
++			counter++;
++		}
++	}
++
++	iomodel->FetchDataToInput(inputs,elements,"md.initialization.debris",DebrisThicknessEnum);
++	iomodel->FetchDataToInput(inputs,elements,"md.initialization.vx",VxDebrisEnum);
++	iomodel->FetchDataToInput(inputs,elements,"md.initialization.vy",VyDebrisEnum);
++	if(iomodel->domaintype!=Domain2DhorizontalEnum){
++		iomodel->FetchDataToInput(inputs,elements,"md.mesh.vertexonsurface",MeshVertexonsurfaceEnum);
++		iomodel->FetchDataToInput(inputs,elements,"md.mesh.vertexonbase",MeshVertexonbaseEnum);
++	}
++
++	switch(smb_model){
++		case SMBforcingEnum:
++			iomodel->FetchDataToInput(inputs,elements,"md.smb.mass_balance",SmbMassBalanceEnum,0.);
++			break;
++		default:
++			/*Nothing for now*/
++			;
++	}
++
++}/*}}}*/
++void DebrisAnalysis::UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum){/*{{{*/
++
++	int     numoutputs;
++	char**  requestedoutputs = NULL;
++
++	parameters->AddObject(iomodel->CopyConstantObject("md.debris.stabilization",DebrisStabilizationEnum));
++	parameters->AddObject(iomodel->CopyConstantObject("md.debris.removalmodel",DebrisRemovalmodelEnum));
++	parameters->AddObject(iomodel->CopyConstantObject("md.debris.displacementmodel",DebrisDisplacementmodelEnum));
++	parameters->AddObject(iomodel->CopyConstantObject("md.debris.min_thickness",DebrisMinThicknessEnum));
++	parameters->AddObject(iomodel->CopyConstantObject("md.debris.packingfraction",DebrisPackingFractionEnum));
++	parameters->AddObject(iomodel->CopyConstantObject("md.debris.removal_slope_threshold",DebrisRemovalSlopeThresholdEnum));
++	parameters->AddObject(iomodel->CopyConstantObject("md.debris.removal_stress_threshold",DebrisRemovalStressThresholdEnum));
++
++	iomodel->FindConstant(&requestedoutputs,&numoutputs,"md.debris.requested_outputs");
++	parameters->AddObject(new IntParam(DebrisNumRequestedOutputsEnum,numoutputs));
++	if(numoutputs)parameters->AddObject(new StringArrayParam(DebrisRequestedOutputsEnum,requestedoutputs,numoutputs));
++	iomodel->DeleteData(&requestedoutputs,numoutputs,"md.debris.requested_outputs");
++
++}/*}}}*/
++
++/*Finite Element Analysis*/
++void           DebrisAnalysis::Core(FemModel* femmodel){/*{{{*/
++
++
++	Element* element= NULL;
++	for(Object* & object : femmodel->elements->objects){
++		element=xDynamicCast<Element*>(object);
++
++
++		int numvertices = element->GetNumberOfNodes();
++
++		IssmDouble* vx = xNew<IssmDouble>(numvertices);
++		IssmDouble* debristhickness = xNew<IssmDouble>(numvertices);
++		IssmDouble* slopex         = xNew<IssmDouble>(numvertices);
++		IssmDouble* onsurface      = xNew<IssmDouble>(numvertices);
++		IssmDouble* icethickness      = xNew<IssmDouble>(numvertices);
++
++		element->GetInputListOnVertices(&debristhickness[0],DebrisThicknessEnum);
++		element->GetInputListOnVertices(&vx[0],VxEnum);
++		element->GetInputListOnVertices(&slopex[0],SurfaceSlopeXEnum);
++		element->GetInputListOnVertices(&onsurface[0],MeshVertexonsurfaceEnum);
++		element->GetInputListOnVertices(&icethickness[0],ThicknessEnum);
++
++		IssmDouble slope,rad2deg=180./M_PI; //=57.2958
++		IssmDouble vslipx,rhod=1900.;
++		IssmDouble gravity=element->FindParam(ConstantsGEnum);
++		IssmDouble slope_threshold=element->FindParam(DebrisRemovalSlopeThresholdEnum);
++		IssmDouble iceminthickness=element->FindParam(MasstransportMinThicknessEnum);
++
++		int step;
++		IssmDouble dt, maxv;
++		IssmDouble yts=31536000.;
++		femmodel->parameters->FindParam(&step,StepEnum);
++		femmodel->parameters->FindParam(&dt,TimesteppingTimeStepEnum);
++
++		bool isminthicknessinelement=false;
++		for(int i=0;i<numvertices;i++){
++			if(icethickness[i]<=(iceminthickness+0.01)) isminthicknessinelement=true;
++		}
++		if(isminthicknessinelement){
++			//do nothing
++			for(int i=0;i<numvertices;i++){
++				if(icethickness[i]<=(iceminthickness+0.01)) vx[i]=0.;                         
++			}
++		}else{
++			for(int i=0;i<numvertices;i++){
++				//if(onsurface[i]){
++				slope=fabs(slopex[i]);
++				if((atan(slope)*rad2deg)>25.){
++					//if(debristhickness[i]>0.01){
++					vslipx=slope_threshold/yts;
++					//maxv=10.0/2./dt;
++					//vslipx=-slope_threshold*rhod*gravity*debristhickness[i]*slopex[i]/yts;
++					vx[i]=vx[i]+vslipx;
++					//debristhickness[i]=debristhickness[i];
++					//if(vx[i]>maxv) vx[i]=maxv;
++					//}
++				} 
++				//}
++			}
++		}
++		//if(step%100==0)   
++		element->AddInput(VxDebrisEnum,vx,P1Enum);
++		//element->AddInput(DebrisThicknessEnum,debristhickness,P1Enum);
++
++		/* Free resources */
++		xDelete<IssmDouble>(debristhickness);
++		xDelete<IssmDouble>(icethickness);
++		xDelete<IssmDouble>(vx);
++		xDelete<IssmDouble>(slopex);
++		xDelete<IssmDouble>(onsurface);
++	}
++
++	//if(step%7==0) 
++	//PreProcessing(femmodel);
++	//femmodel->parameters->SetParam(VxDebrisEnum,InputToExtrudeEnum);
++	//extrudefromtop_core(femmodel);
++
++	femmodel->SetCurrentConfiguration(DebrisAnalysisEnum);        
++	solutionsequence_linear(femmodel);
++
++	int step;
++	femmodel->parameters->FindParam(&step,StepEnum);
++	//if(step%7==0) PreProcessing(femmodel);
++	PostProcessing(femmodel);
++
++}/*}}}*/
++void           DebrisAnalysis::PreCore(FemModel* femmodel){/*{{{*/
++	_error_("not implemented");
++}/*}}}*/
++ElementVector* DebrisAnalysis::CreateDVector(Element* element){/*{{{*/
++	/*Default, return NULL*/
++	return NULL;
++}/*}}}*/
++ElementMatrix* DebrisAnalysis::CreateJacobianMatrix(Element* element){/*{{{*/
++	_error_("Not implemented");
++}/*}}}*/
++ElementMatrix* DebrisAnalysis::CreateKMatrix(Element* element){/*{{{*/
++
++	/* Check if ice in element */
++	if(!element->IsIceInElement()) return NULL;
++
++	/*Intermediaries */
++	int        stabilization,domaintype,dim;
++	IssmDouble Jdet,D_scalar,dt,h;
++	IssmDouble vel,vx,vy,dvxdx,dvydy;
++	IssmDouble xi,tau;
++	IssmDouble dvx[2],dvy[2];
++	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*/
++	ElementMatrix* Ke     = topelement->NewElementMatrix(NoneApproximationEnum);
++	IssmDouble*   	basis  = xNew<IssmDouble>(numnodes);
++	IssmDouble* 	dbasis = 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,DebrisStabilizationEnum);
++	Input* vx_input=topelement->GetInput(VxDebrisEnum); _assert_(vx_input);
++	Input* vy_input=NULL;
++	if(dim>1){vy_input = topelement->GetInput(VyDebrisEnum); _assert_(vy_input);}
++	h = topelement->CharacteristicLength();
++
++	/* Start  looping on the number of gaussian points: */
++	Gauss* gauss=topelement->NewGauss(2);
++	while(gauss->next()){
++
++		topelement->JacobianDeterminant(&Jdet,xyz_list,gauss);
++		topelement->NodalFunctions(basis,gauss);
++		topelement->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
++
++		vx_input->GetInputValue(&vx,gauss);
++		if(dim==2) vy_input->GetInputValue(&vy,gauss);
++
++		D_scalar=gauss->weight*Jdet;
++		for(int i=0;i<numnodes;i++) for(int j=0;j<numnodes;j++) Ke->values[i*numnodes+j] += D_scalar*basis[i]*basis[j];
++
++		/*Advection terms*/
++		vx_input->GetInputDerivativeValue(&dvx[0],xyz_list,gauss);
++		D_scalar=dt*gauss->weight*Jdet;
++		if(dim==2){
++			vy_input->GetInputDerivativeValue(&dvy[0],xyz_list,gauss);
++			dvxdx=dvx[0];
++			dvydy=dvy[1];
++			for(int i=0;i<numnodes;i++){
++				for(int j=0;j<numnodes;j++){
++					/*\phi_i \phi_j \nabla\cdot v*/
++					Ke->values[i*numnodes+j] += D_scalar*basis[i]*basis[j]*(dvxdx+dvydy);
++					/*\phi_i v\cdot\nabla\phi_j*/
++					Ke->values[i*numnodes+j] += D_scalar*basis[i]*(vx*dbasis[0*numnodes+j] + vy*dbasis[1*numnodes+j]);
++				}
++			}
++		}
++		else{
++			dvxdx=dvx[0];
++			for(int i=0;i<numnodes;i++){
++				for(int j=0;j<numnodes;j++){
++					Ke->values[i*numnodes+j] += D_scalar*dvxdx*basis[i]*basis[j];
++					Ke->values[i*numnodes+j] += D_scalar*vx*dbasis[0*numnodes+j]*basis[i];
++				}
++			}
++		}
++
++		/*******************************************************************/
++		/* Diffusion */
++		bool isdisplacement=false;
++		int step;
++		topelement->FindParam(&step,StepEnum);
++		IssmDouble slope_threshold;
++		topelement->FindParam(&slope_threshold,DebrisRemovalSlopeThresholdEnum);
++		IssmDouble kappa,f,smb,debristhickness,slopex;
++		IssmDouble Diff,fraction,M=1,C;
++		IssmDouble rad2deg=180./M_PI;
++		Diff=3.2/3e7;
++		Input* slopex_input=topelement->GetInput(SurfaceSlopeXEnum); _assert_(slopex_input);
++		Input* smb_input=topelement->GetInput(SmbMassBalanceEnum); _assert_(smb_input);
++		Input* debristhickness_input=topelement->GetInput(DebrisThicknessEnum); _assert_(debristhickness_input);
++
++		if(isdisplacement){
++
++			slopex_input->GetInputValue(&slopex, gauss);
++			smb_input->GetInputValue(&smb, gauss);
++			debristhickness_input->GetInputValue(&debristhickness, gauss);
++			if((atan(fabs(slopex))*rad2deg)>30.){
++				f=1.;
++			}else{
++				f=0.;
++			}
++			//f=1;
++			//kappa=-5.6e16*smb*debristhickness*f;
++			//kappa=debristhickness/h*4e9*f;
++			//kappa=14.2809e8*f; // 25°
++			kappa=slope_threshold*1e8*f;
++			if(dim==2){
++				for(int i=0;i<numnodes;i++){
++					for(int j=0;j<numnodes;j++){
++						Ke->values[i*numnodes+j] +=  D_scalar*kappa*(
++								dbasis[0*numnodes+j]*dbasis[0*numnodes+i] + dbasis[1*numnodes+j]*dbasis[1*numnodes+i] + dbasis[2*numnodes+j]*dbasis[2*numnodes+i]
++								);
++					}
++				}
++			}else{
++				for(int i=0;i<numnodes;i++){
++					for(int j=0;j<numnodes;j++){
++						Ke->values[i*numnodes+j] += D_scalar*kappa*(dbasis[0*numnodes+j]*dbasis[0*numnodes+i]);
++					}
++				}
++			}                
++		}
++
++		/*******************************************************************/                
++
++		IssmDouble rho;
++		if(FINITEELEMENT==P1Enum){
++			rho=2;
++		}else if(FINITEELEMENT==P2Enum){
++			rho=4.;
++		}
++		if(stabilization==2){
++			/*Streamline upwinding*/
++			if(dim==1){
++				vx_input->GetInputValue(&vx,gauss);
++				vel=fabs(vx)+1.e-10;
++				D[0] = h/(rho*vel)*vx*vx;
++			}
++			else{
++				vx_input->GetInputAverage(&vx);
++				vy_input->GetInputAverage(&vy);
++				vel=sqrt(vx*vx+vy*vy)+1.e-10;
++				D[0*dim+0]=h/(rho*vel)*vx*vx;
++				D[1*dim+0]=h/(rho*vel)*vy*vx;
++				D[0*dim+1]=h/(rho*vel)*vx*vy;
++				D[1*dim+1]=h/(rho*vel)*vy*vy;
++			}
++		}
++		else if(stabilization==1){  
++			/*SSA*/
++			if(dim==1){
++				vx_input->GetInputAverage(&vx);
++				D[0]=h/rho*fabs(vx);
++			}
++			else{
++				vx_input->GetInputAverage(&vx);
++				vy_input->GetInputAverage(&vy);
++				D[0*dim+0]=h/rho*fabs(vx);
++				D[1*dim+1]=h/rho*fabs(vy);
++			}
++		}
++		else if(stabilization==3){  
++			/*SUPG*/
++			if(dim==1){
++				vx_input->GetInputAverage(&vx);
++				tau=h/(rho*fabs(vx)+1e-10);
++			}
++			else{
++				vx_input->GetInputAverage(&vx);
++				vy_input->GetInputAverage(&vy);
++				tau=1*h/(rho*sqrt(vx*vx+vy*vy)+1e-10);
++			}
++		}
++		if(stabilization==1 || stabilization==2){
++			for(int i=0;i<dim*dim;i++) D[i]=D_scalar*D[i];
++			if(dim==2){
++				for(int i=0;i<numnodes;i++){
++					for(int j=0;j<numnodes;j++){
++						Ke->values[i*numnodes+j] += (
++								dbasis[0*numnodes+i] *(D[0*dim+0]*dbasis[0*numnodes+j] + D[0*dim+1]*dbasis[1*numnodes+j]) +
++								dbasis[1*numnodes+i] *(D[1*dim+0]*dbasis[0*numnodes+j] + D[1*dim+1]*dbasis[1*numnodes+j]) 
++								);
++					}   
++				}
++			}
++			else{
++				for(int i=0;i<numnodes;i++) for(int j=0;j<numnodes;j++) Ke->values[i*numnodes+j] += dbasis[0*numnodes+i]*D[0]*dbasis[0*numnodes+j];
++			}
++		}else if(stabilization==3){ 
++			/*Mass matrix - part 2*/
++			if(dim==1){
++				for(int i=0;i<numnodes;i++){
++					for(int j=0;j<numnodes;j++){
++						Ke->values[i*numnodes+j]+=gauss->weight*Jdet*tau*basis[j]*vx*dbasis[0*numnodes+i];
++					}
++				}
++				/*Mass matrix - part 3*/
++				for(int i=0;i<numnodes;i++){
++					for(int j=0;j<numnodes;j++){
++						Ke->values[i*numnodes+j]+=gauss->weight*Jdet*tau*basis[j]*basis[i]*dvxdx;
++					}
++				}
++
++				/*Advection matrix - part 2, A*/
++				for(int i=0;i<numnodes;i++){
++					for(int j=0;j<numnodes;j++){
++						Ke->values[i*numnodes+j]+=dt*gauss->weight*Jdet*tau*(vx*dbasis[0*numnodes+j])*(vx*dbasis[0*numnodes+i]);
++					}
++				}
++
++				/*Advection matrix - part 3, A*/
++				for(int i=0;i<numnodes;i++){
++					for(int j=0;j<numnodes;j++){
++						Ke->values[i*numnodes+j]+=dt*gauss->weight*Jdet*tau*(vx*dbasis[0*numnodes+j])*(basis[i]*dvxdx);
++					}
++				}
++
++				/*Advection matrix - part 2, B*/
++				for(int i=0;i<numnodes;i++){
++					for(int j=0;j<numnodes;j++){
++						Ke->values[i*numnodes+j]+=dt*gauss->weight*Jdet*tau*(basis[j]*dvxdx)*(vx*dbasis[0*numnodes+i]);
++					}
++				}
++
++				/*Advection matrix - part 3, B*/
++				for(int i=0;i<numnodes;i++){
++					for(int j=0;j<numnodes;j++){
++						Ke->values[i*numnodes+j]+=dt*gauss->weight*Jdet*tau*(basis[j]*dvxdx+basis[j]*dvydy)*(basis[i]*dvxdx);
++					}
++				}
++			}
++		}
++	}
++
++	/*Clean up and return*/
++	xDelete<IssmDouble>(xyz_list);
++	xDelete<IssmDouble>(basis);
++	xDelete<IssmDouble>(dbasis);
++	delete gauss;
++	if(topelement->IsSpawnedElement()){topelement->DeleteMaterials(); delete topelement;};
++	return Ke;
++}/*}}}*/
++ElementVector* DebrisAnalysis::CreatePVector(Element* element){/*{{{*/
++
++	/* Check if ice in element */
++	if(!element->IsIceInElement()) return NULL;
++
++	/*Intermediaries */
++	int	stabilization,dim,domaintype;
++	IssmDouble  Jdet,dt;
++	IssmDouble  smb,thickness;
++	IssmDouble  vx,vy,vel,dvxdx,dvydy,xi,h,tau,pf;
++	IssmDouble  dvx[2],dvy[2];
++	IssmDouble* xyz_list = NULL;
++	Element*    topelement = NULL;
++
++	/*Get problem dimension*/
++	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);
++	IssmDouble*    dbasis= xNew<IssmDouble>(dim*numnodes);
++
++	/*Retrieve all inputs and parameters*/
++	topelement->GetVerticesCoordinates(&xyz_list);
++	topelement->FindParam(&dt,TimesteppingTimeStepEnum);
++	topelement->FindParam(&pf,DebrisPackingFractionEnum);
++	topelement->FindParam(&stabilization,DebrisStabilizationEnum);
++	Input* smb_input      	= topelement->GetInput(SmbMassBalanceEnum);  _assert_(smb_input);
++	Input* thickness_input  = topelement->GetInput(DebrisThicknessEnum); _assert_(thickness_input);
++	Input* vx_input  = topelement->GetInput(VxDebrisEnum);  _assert_(vx_input);
++	Input* vy_input=NULL;
++	if(dim==2){
++		vy_input=topelement->GetInput(VyDebrisEnum); _assert_(vy_input);
++	}
++
++	IssmDouble rho;
++	if(FINITEELEMENT==P1Enum){
++		rho=2.;
++	}else if(FINITEELEMENT==P2Enum){
++		rho=4.;
++	}
++
++	/* Start  looping on the number of gaussian points: */
++	Gauss* gauss=topelement->NewGauss(2);
++	while(gauss->next()){
++
++		topelement->JacobianDeterminant(&Jdet,xyz_list,gauss);
++		topelement->NodalFunctions(basis,gauss);
++
++		smb_input->GetInputValue(&smb,gauss);
++		thickness_input->GetInputValue(&thickness,gauss);
++
++		if(smb>0.){
++			for(int i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*(thickness-0.*dt*smb*pf)*basis[i];
++		} else {
++			for(int i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*(thickness-dt*smb*pf)*basis[i]; // take the negative of melt, because it is a debris production term here
++		}
++
++		if(stabilization==3){
++			/*SUPG*/
++			topelement->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
++			if(dim==1){
++
++				vx_input->GetInputValue(&vx,gauss);
++				vx_input->GetInputDerivativeValue(&dvx[0],xyz_list,gauss);
++				dvxdx=dvx[0];
++				tau=h/(rho*fabs(vx)+1e-10);
++				IssmDouble psi;
++				if(smb>0.){
++					psi=thickness;
++				} else {
++					psi=thickness-dt*smb*pf;
++				}
++				/*Force vector - part 2*/
++				for(int i=0;i<numnodes;i++){
++					pe->values[i]+=Jdet*gauss->weight*psi*tau*(vx*dbasis[0*numnodes+i]);
++				}
++				/*Force vector - part 3*/
++				for(int i=0;i<numnodes;i++){
++					pe->values[i]+=Jdet*gauss->weight*psi*tau*(basis[i]*dvxdx);
++				}
++
++			}
++		}
++	}
++
++	/*Clean up and return*/
++	xDelete<IssmDouble>(xyz_list);
++	xDelete<IssmDouble>(basis);
++	xDelete<IssmDouble>(dbasis);
++	delete gauss;
++	if(topelement->IsSpawnedElement()){topelement->DeleteMaterials(); delete topelement;};
++	return pe;
++}/*}}}*/
++void           DebrisAnalysis::GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element){/*{{{*/
++	_error_("not implemented yet");
++}/*}}}*/
++void           DebrisAnalysis::GradientJ(Vector<IssmDouble>* gradient,Element*  element,int control_type,int control_interp,int control_index){/*{{{*/
++	_error_("Not implemented yet");
++}/*}}}*/
++void           DebrisAnalysis::InputUpdateFromSolution(IssmDouble* solution,Element* element){/*{{{*/
++	//element->InputUpdateFromSolutionOneDof(solution,DebrisThicknessEnum);
++	int*         ddoflist=NULL;
++
++	int numnodes = element->GetNumberOfNodes();
++	IssmDouble* thickness    = xNew<IssmDouble>(numnodes);
++	IssmDouble* thicknessold    = xNew<IssmDouble>(numnodes);
++	IssmDouble* newthickness = xNew<IssmDouble>(numnodes);
++	IssmDouble* icethickness    = xNew<IssmDouble>(numnodes);
++	IssmDouble* bedslopex    = xNew<IssmDouble>(numnodes);
++	IssmDouble* surfaceslopex    = xNew<IssmDouble>(numnodes);
++
++	/*Use the dof list to index into the solution vector: */
++	IssmDouble minthickness = element->FindParam(DebrisMinThicknessEnum);
++	IssmDouble iceminthickness = element->FindParam(MasstransportMinThicknessEnum);
++	element->GetInputListOnVertices(&thickness[0],DebrisThicknessEnum);   
++	element->GetInputListOnVertices(&icethickness[0],ThicknessEnum);
++	element->GetInputListOnVertices(&bedslopex[0],BedSlopeXEnum);
++	element->GetInputListOnVertices(&surfaceslopex[0],SurfaceSlopeXEnum);
++	element->GetDofListLocal(&ddoflist,NoneApproximationEnum,GsetEnum);
++
++	for(int i=0;i<numnodes;i++){
++		newthickness[i] = solution[ddoflist[i]];
++		if(xIsNan<IssmDouble>(newthickness[i])) _error_("NaN found in solution vector");
++		if(xIsInf<IssmDouble>(newthickness[i])) _error_("Inf found in solution vector");
++
++		/* check for thickness<minthickness */
++		if(thickness[i]<minthickness) newthickness[i]=minthickness;
++
++		/* Carlos model sets all values below Hmin to zero */
++		if(icethickness[i]<=(iceminthickness+0.0001) & fabs((fabs(surfaceslopex[i])-fabs(bedslopex[i])))<1e-3 ) newthickness[i]=0;
++		//if(icethickness[i]<=(iceminthickness+0.01)) newthickness[i]=0;
++	}
++
++	/* update inputs */
++	element->AddInput(DebrisThicknessEnum,newthickness,P1Enum);
++
++	/* Free resources */
++	xDelete<IssmDouble>(newthickness);
++	xDelete<IssmDouble>(thickness);
++	xDelete<IssmDouble>(icethickness);
++	xDelete<IssmDouble>(bedslopex);
++	xDelete<IssmDouble>(surfaceslopex);
++	xDelete<int>(ddoflist);
++}/*}}}*/
++void           DebrisAnalysis::UpdateConstraints(FemModel* femmodel){/*{{{*/
++	//        return;
++	SetActiveNodesLSMx(femmodel);
++}/*}}}*/
++void           DebrisAnalysis::PostProcessing(FemModel* femmodel){/*{{{*/
++
++	if(VerboseSolution()) _printf0_("   Debris postprocessing\n");
++
++	/*Intermediaries*/
++	int removalmodel;
++	int k,numnodes;
++	int domaintype,dim;
++	femmodel->parameters->FindParam(&domaintype,DomainTypeEnum);
++	femmodel->parameters->FindParam(&removalmodel,DebrisRemovalmodelEnum);
++	Element* element= NULL;
++	Element*    topelement = NULL;
++
++	if(removalmodel==0){
++		// no removal, do nothing
++	}else{
++		// slope or driving stress removal
++
++		for(Object* & object : femmodel->elements->objects){
++			element=xDynamicCast<Element*>(object);
++
++			numnodes=element->GetNumberOfNodes();
++			element->FindParam(&domaintype,DomainTypeEnum);
++			IssmDouble* icethickness   = xNew<IssmDouble>(numnodes);
++			IssmDouble* debristhickness= xNew<IssmDouble>(numnodes);
++			IssmDouble* slopex	   = xNew<IssmDouble>(numnodes);
++			IssmDouble* slopey	   = xNew<IssmDouble>(numnodes); 
++			IssmDouble* onsurface	   = xNew<IssmDouble>(numnodes); 
++			element->GetInputListOnNodes(debristhickness,DebrisThicknessEnum);
++			element->GetInputListOnNodes(icethickness,ThicknessEnum);
++			element->GetInputListOnNodes(onsurface,MeshVertexonsurfaceEnum);
++			dim=1;
++			element->GetInputListOnNodes(slopex,SurfaceSlopeXEnum);
++			if(domaintype!=Domain2DverticalEnum){
++				element->GetInputListOnNodes(slopey,SurfaceSlopeYEnum);
++				dim=2;
++			}
++			IssmDouble slope,rad2deg=180./M_PI; //=57.2958
++			bool isminthicknessinelement=false;
++			bool remove_debris=false;
++
++			IssmDouble iceminthickness=element->FindParam(MasstransportMinThicknessEnum);                        
++
++			switch(removalmodel){
++				case 1:
++					IssmDouble slope_threshold=element->FindParam(DebrisRemovalSlopeThresholdEnum);
++
++					for(k=0; k<numnodes;k++){
++						if(icethickness[k]<=(iceminthickness+0.01)) isminthicknessinelement=true;
++					}
++					isminthicknessinelement=true;
++					if(isminthicknessinelement){
++						for(k=0; k<numnodes;k++){
++							if(onsurface[k]){
++								slope=fabs(slopex[k]);
++								if(dim==2) slope=pow(pow(slopex[k],2)+pow(slopey[k],2),0.5);
++								if((atan(slope)*rad2deg)>slope_threshold) debristhickness[k]=remove_debris=true;
++							}
++						}
++						if(remove_debris){
++							for(k=0; k<numnodes;k++){
++								if(icethickness[k]<=(iceminthickness+0.01)) debristhickness[k]=0.;
++							}
++						}
++					}
++					//int finite_element = element->GetElementType(); 
++					//element->AddInput(DebrisThicknessEnum,debristhickness,FINITEELEMENT);
++					element->AddInput(DebrisThicknessEnum,debristhickness,P1Enum);
++
++					xDelete<IssmDouble>(debristhickness);
++					xDelete<IssmDouble>(icethickness);
++					xDelete<IssmDouble>(slopex);
++					xDelete<IssmDouble>(slopey);
++					break;
++
++				case 2:
++					IssmDouble stress_threshold = element->FindParam(DebrisRemovalStressThresholdEnum);
++					IssmDouble gravity = element->FindParam(ConstantsGEnum);
++					IssmDouble stress,rhod=1900.;
++
++					for(k=0; k<numnodes;k++){
++						if(icethickness[k]<=(iceminthickness+0.01)) isminthicknessinelement=true;
++					}
++					isminthicknessinelement=true;
++					if(isminthicknessinelement){
++						//stress=0;
++						int kk=0;
++						for(k=0; k<numnodes;k++){
++							if(onsurface[k]){
++								slope=fabs(slopex[k]);
++								if(dim==2) slope=pow(pow(slopex[k],2)+pow(slopey[k],2),0.5);
++								stress=rhod*gravity*debristhickness[k]*slope;//pow(slope*slope/(slope*slope+1),0.5);//sin(slope/rad2deg);
++								if(stress>stress_threshold) debristhickness[k]=0.;
++								//kk++;
++							}
++						}
++						/*if((stress/double(kk))>stress_threshold) remove_debris=true;
++						  if(remove_debris){
++						  for(k=0; k<numnodes;k++){
++						  debristhickness[k]=0.;
++						  }
++						  }*/
++					}
++					//int finite_element = element->GetElementType(); 
++					//element->AddInput(DebrisThicknessEnum,debristhickness,FINITEELEMENT);
++					element->AddInput(DebrisThicknessEnum,debristhickness,P1Enum);
++
++					xDelete<IssmDouble>(debristhickness);
++					xDelete<IssmDouble>(icethickness);
++					xDelete<IssmDouble>(slopex);
++					xDelete<IssmDouble>(slopey);
++					break;
++
++				default: _error_("removalmodel "<<EnumToStringx(removalmodel)<<" not implemented yet");
++			}
++		}
++	}
++
++}/*}}}*/
++void           DebrisAnalysis::PreProcessing(FemModel* femmodel){/*{{{*/
++
++	if(VerboseSolution()) _printf0_("   Debris preprocessing\n");
++
++	/*Intermediaries*/
++	bool isdebrisdisplacement=true;
++	int displacementmodel=1;
++	int k,numnodes;
++	int domaintype,dim;
++	femmodel->parameters->FindParam(&domaintype,DomainTypeEnum);
++	//femmodel->parameters->FindParam(&displacementmodel,DebrisDisplacementmodelEnum);
++	Element* element= NULL;
++	IssmDouble *xyz_list = NULL;
++	//IssmDouble top_normal[2];
++
++	if(isdebrisdisplacement){
++
++		//if(displacementmodel==0){
++		// no displacement, do nothing
++		//}else{
++		// deterministic or random displacement
++
++		for(Object* & object : femmodel->elements->objects){
++			element=xDynamicCast<Element*>(object);
++
++			numnodes=element->GetNumberOfNodes();
++			IssmDouble* debristhickness= xNew<IssmDouble>(numnodes);
++			IssmDouble* icethickness= xNew<IssmDouble>(numnodes);
++			IssmDouble* slopex	   = xNew<IssmDouble>(numnodes);
++			IssmDouble* slopey	   = xNew<IssmDouble>(numnodes); 
++			IssmDouble* vx 		   = xNew<IssmDouble>(numnodes);
++			IssmDouble* vy 		   = xNew<IssmDouble>(numnodes);
++			IssmDouble* surface        = xNew<IssmDouble>(numnodes);
++			IssmDouble* onsurface  	   = xNew<IssmDouble>(numnodes);
++			element->GetInputListOnNodes(vx,VxDebrisEnum);
++			element->GetInputListOnNodes(debristhickness,DebrisThicknessEnum);
++			element->GetInputListOnNodes(icethickness,ThicknessEnum);
++			element->GetInputListOnNodes(surface,SurfaceEnum);
++			element->GetInputListOnNodes(onsurface,MeshVertexonsurfaceEnum);
++			element->GetVerticesCoordinates(&xyz_list);
++
++			dim=1;
++			element->GetInputListOnNodes(slopex,SurfaceSlopeXEnum);
++			if(domaintype!=Domain2DverticalEnum){
++				element->GetInputListOnNodes(slopey,SurfaceSlopeYEnum);
++				element->GetInputListOnNodes(vy,VyDebrisEnum);
++				dim=2;
++			}
++			IssmDouble slope,rad2deg=180./M_PI; //=57.2958
++			IssmDouble h=10.,f;
++			IssmDouble debrissum;
++			IssmDouble dt = element->FindParam(TimesteppingTimeStepEnum);
++			bool displacedebris;
++
++			switch(displacementmodel){
++				case 1:
++					IssmDouble slope_threshold = element->FindParam(DebrisRemovalSlopeThresholdEnum);
++					IssmDouble iceminthickness=element->FindParam(MasstransportMinThicknessEnum);
++
++					bool isminthicknessinelement=false;
++					for(k=0; k<numnodes;k++){
++						if(icethickness[k]<=(iceminthickness+0.01)) isminthicknessinelement=true;
++					}
++					if(isminthicknessinelement){
++						//do nothing
++					}else{
++						debrissum=0.;
++						int test;
++						test=0;
++						for(k=0; k<numnodes;k++){
++							if(onsurface[k]){
++								slope=pow(slopex[k]*slopex[k],0.5);
++								if(dim==2) slope=pow(pow(slopex[k],2)+pow(slopey[k],2),0.5);
++								if((atan(slope)*rad2deg)>30.){
++									f=0.5;
++									test=test+0;
++									debrissum=debrissum+debristhickness[k]*f;
++									//displacedebris=true;
++									//if(debristhickness[k]>1.e-6) vx[k]=vx[k]+10./31536000.;//*vx[k]/pow(pow(vx[k],2),0.5);
++									//debristhickness[k]=debristhickness[k]*(1.-f);
++								}
++							}
++						}
++						if(test>1){
++							test=test;
++						}else{
++							test=1;
++						}
++						//if(displacedebris){
++						int index=-1;
++						IssmDouble min=1e14;
++						for(k=0; k<numnodes;k++){
++							if(onsurface[k]){
++								if(surface[k]<min){
++									index=k;
++									min=surface[k];
++								} 
++							}
++						}
++						for(k=0; k<numnodes;k++){
++							if(onsurface[k]){
++								if(k==index){
++									debristhickness[k]=debristhickness[k]+debrissum;
++								}else{
++									debristhickness[k]=debristhickness[k]-debrissum;
++									if(debristhickness[k]<=0) debristhickness[k]=0;
++								}
++								//if(debristhickness[k]>10.) debristhickness[k]=10.;
++							}
++						}
++						//}
++					}
++
++					int finite_element = element->GetElementType(); 
++					//element->AddInput(DebrisThicknessEnum,debristhickness,finite_element);
++					//element->AddInput(VxDebrisEnum,vx,P1Enum);
++					element->AddInput(DebrisThicknessEnum,debristhickness,P1Enum);
++
++					xDelete<IssmDouble>(debristhickness);
++					xDelete<IssmDouble>(icethickness);
++					xDelete<IssmDouble>(vx);
++					xDelete<IssmDouble>(vy); 
++					xDelete<IssmDouble>(slopex);
++					xDelete<IssmDouble>(slopey);
++					xDelete<IssmDouble>(surface);
++					break;
++
++				case 2:
++
++					// Do nothing
++
++				default: _error_("Debris displacement model "<<EnumToStringx(displacementmodel)<<" not implemented yet");
++			}
++		}
++	}
++	//}
++}/*}}}*/        
+Index: ../trunk-jpl/src/c/analyses/analyses.h
+===================================================================
+--- ../trunk-jpl/src/c/analyses/analyses.h	(revision 27297)
++++ ../trunk-jpl/src/c/analyses/analyses.h	(revision 27298)
+@@ -16,6 +16,7 @@
+ #include "./BalancethicknessSoftAnalysis.h"
+ #include "./BalancevelocityAnalysis.h"
+ #include "./DamageEvolutionAnalysis.h"
++#include "./DebrisAnalysis.h"
+ #include "./DepthAverageAnalysis.h"
+ #include "./EnthalpyAnalysis.h"
+ #include "./ExtrudeFromBaseAnalysis.h"
+Index: ../trunk-jpl/src/c/classes/FemModel.cpp
+===================================================================
+--- ../trunk-jpl/src/c/classes/FemModel.cpp	(revision 27297)
++++ ../trunk-jpl/src/c/classes/FemModel.cpp	(revision 27298)
+@@ -850,7 +850,7 @@
+ 
+ 		case TransientSolutionEnum:{
+ 			/*We have multiple analyses here, process one by one*/
+-			bool isSIA,isFS,isthermal,isenthalpy,ismasstransport,isoceantransport,isgroundingline,isstressbalance,ismovingfront,ishydrology,isdamage,issmb,isslc,isesa,issampling;
++			bool isSIA,isFS,isthermal,isenthalpy,ismasstransport,isoceantransport,isgroundingline,isstressbalance,ismovingfront,ishydrology,isdamage,issmb,isslc,isesa,isdebris,issampling;
+ 			iomodel->FindConstant(&isthermal,"md.transient.isthermal");
+ 			iomodel->FindConstant(&ismovingfront,"md.transient.ismovingfront");
+ 			iomodel->FindConstant(&ismasstransport,"md.transient.ismasstransport");
+@@ -862,6 +862,7 @@
+ 			iomodel->FindConstant(&issmb,"md.transient.issmb");
+ 			iomodel->FindConstant(&isslc,"md.transient.isslc");
+ 			iomodel->FindConstant(&isesa,"md.transient.isesa");
++			iomodel->FindConstant(&isdebris,"md.transient.isdebris");
+ 			iomodel->FindConstant(&issampling,"md.transient.issampling");
+       int* analyses_iter     = NULL;
+       int  num_analyses_iter = 0;
+@@ -909,6 +910,9 @@
+ 			if(isesa){
+ 				analyses_temp[numanalyses++]=EsaAnalysisEnum;
+ 			}
++			if(isdebris){
++				analyses_temp[numanalyses++]=DebrisAnalysisEnum;
++			}
+ 			if(issampling){
+ 				analyses_temp[numanalyses++]=SamplingAnalysisEnum;
+ 			}
+@@ -992,6 +996,7 @@
+ 		if(profiler->Used(SMBCORE)) _printf0_("   "<<setw(40)<<left<<"SMB core elapsed time:"<<setw(7)<<setprecision(6)<<profiler->TotalTime(SMBCORE) << " sec\n");
+ 		if(profiler->Used(GROUNDINGLINECORE)) _printf0_("   "<<setw(40)<<left<<"Groundingline migration core elapsed time:"<<setw(7)<<setprecision(6)<<profiler->TotalTime(GROUNDINGLINECORE) << " sec\n");
+ 		if(profiler->Used(ESACORE)) _printf0_("   "<<setw(40)<<left<<"ESA core elapsed time:"<<setw(7)<<setprecision(6)<<profiler->TotalTime(ESACORE) << " sec\n");
++		if(profiler->Used(DEBRISCORE)) _printf0_("   "<<setw(40)<<left<<"DEBRIS core elapsed time:"<<setw(7)<<setprecision(6)<<profiler->TotalTime(SLRCORE) << " sec\n");
+ 		if(profiler->Used(SLRCORE)) _printf0_("   "<<setw(40)<<left<<"SLR core elapsed time:"<<setw(7)<<setprecision(6)<<profiler->TotalTime(SLRCORE) << " sec\n");
+ 		if(profiler->Used(MPISERIAL)) _printf0_("   "<<setw(40)<<left<<"MPISERIAL elapsed time:"<<setw(7)<<setprecision(6)<<profiler->TotalTime(MPISERIAL) << " sec\n");
+ 
+Index: ../trunk-jpl/src/c/classes/Node.cpp
+===================================================================
+--- ../trunk-jpl/src/c/classes/Node.cpp	(revision 27297)
++++ ../trunk-jpl/src/c/classes/Node.cpp	(revision 27298)
+@@ -158,7 +158,8 @@
+ 		}
+ 	}
+ 	if(
+-				analysis_enum==FreeSurfaceTopAnalysisEnum
++			analysis_enum==FreeSurfaceTopAnalysisEnum ||
++			analysis_enum==DebrisAnalysisEnum
+ 	  ){
+ 		if(iomodel->domaintype!=Domain2DhorizontalEnum){
+ 			/*On a 3d mesh, we may have collapsed elements, hence dead nodes. Freeze them out: */
+Index: ../trunk-jpl/src/c/classes/Profiler.h
+===================================================================
+--- ../trunk-jpl/src/c/classes/Profiler.h	(revision 27297)
++++ ../trunk-jpl/src/c/classes/Profiler.h	(revision 27298)
+@@ -26,16 +26,17 @@
+ #define GROUNDINGLINECORE	13 /*Profiling GROUDINGLINE MIGRATION */
+ #define ESACORE				14 /*Profiling ESA */
+ #define SLRCORE				15 /*Profiling SLR */
+-#define SAMPLINGCORE	16 /*Profiling SAMPLING */
+-#define MPISERIAL				17 /*Profiling MPISerial */
+-#define SEDLOOP				18 /*Profiling MPISerial */
+-#define SEDMatrix				19 /*Profiling MPISerial */
+-#define SEDUpdate				20 /*Profiling MPISerial */
+-#define EPLLOOP				21 /*Profiling MPISerial */
+-#define EPLMasking			22 /*Profiling MPISerial */
+-#define EPLMatrices			23 /*Profiling MPISerial */
+-#define EPLUpdate				24 /*Profiling MPISerial */
+-#define MAXPROFSIZE			25 /*Used to initialize static arrays*/
++#define DEBRISCORE                              16 /*Profiling DEBRIS */
++#define SAMPLINGCORE	17 /*Profiling SAMPLING */
++#define MPISERIAL				18 /*Profiling MPISerial */
++#define SEDLOOP				19 /*Profiling MPISerial */
++#define SEDMatrix				20 /*Profiling MPISerial */
++#define SEDUpdate				21 /*Profiling MPISerial */
++#define EPLLOOP				22 /*Profiling MPISerial */
++#define EPLMasking			23 /*Profiling MPISerial */
++#define EPLMatrices			24 /*Profiling MPISerial */
++#define EPLUpdate				25 /*Profiling MPISerial */
++#define MAXPROFSIZE			26 /*Used to initialize static arrays*/
+ 
+ class Profiler: public Object{
+ 
+Index: ../trunk-jpl/src/c/cores/cores.h
+===================================================================
+--- ../trunk-jpl/src/c/cores/cores.h	(revision 27297)
++++ ../trunk-jpl/src/c/cores/cores.h	(revision 27298)
+@@ -56,6 +56,7 @@
+ void bmb_core(FemModel* femmodel);
+ void damage_core(FemModel* femmodel);
+ void sampling_core(FemModel* femmodel);
++void debris_core(FemModel* femmodel);
+ 
+ /*sealevel change cores:*/
+ #ifdef _HAVE_SEALEVELCHANGE_
+Index: ../trunk-jpl/src/c/cores/debris_core.cpp
+===================================================================
+--- ../trunk-jpl/src/c/cores/debris_core.cpp	(nonexistent)
++++ ../trunk-jpl/src/c/cores/debris_core.cpp	(revision 27298)
+@@ -0,0 +1,67 @@
++/*!\file: debris_core.cpp
++ * \brief: core of the debris solution 
++ */ 
++
++#include "./cores.h"
++#include "../toolkits/toolkits.h"
++#include "../classes/classes.h"
++#include "../shared/shared.h"
++#include "../modules/modules.h"
++#include "../solutionsequences/solutionsequences.h"
++#include "../classes/Inputs/TransientInput.h"
++
++void debris_core(FemModel* femmodel){ /*{{{*/
++
++	/*Start profiler*/
++	femmodel->profiler->Start(DEBRISCORE);
++
++	/*parameters: */
++	int    numoutputs,domaintype;
++	bool   save_results;
++	int    solution_type,stabilization;
++	char** requested_outputs = NULL;
++	DebrisAnalysis * debris_analysis = NULL;
++
++	/*activate configuration*/
++	femmodel->SetCurrentConfiguration(DebrisAnalysisEnum);
++
++	/*recover parameters: */
++	femmodel->parameters->FindParam(&save_results,SaveResultsEnum);
++	femmodel->parameters->FindParam(&solution_type,SolutionTypeEnum);
++	femmodel->parameters->FindParam(&numoutputs,DebrisNumRequestedOutputsEnum);
++	if(numoutputs) femmodel->parameters->FindParam(&requested_outputs,&numoutputs,DebrisRequestedOutputsEnum);
++
++	if(VerboseSolution()) _printf0_("   computing debris transport\n");
++
++	// We need surface and bed slopes for removal model
++	surfaceslope_core(femmodel);
++	bedslope_core(femmodel);
++
++	/*Transport Debris*/
++	if(VerboseSolution()) _printf0_("   call computational core\n");
++	//InputDuplicatex(femmodel,VxEnum,VxDebrisEnum);
++	femmodel->inputs->DuplicateInput(VxEnum,VxDebrisEnum);
++	//InputDuplicatex(femmodel,VyEnum,VyDebrisEnum);
++	debris_analysis = new DebrisAnalysis();
++	//debris_analysis->PreCore(femmodel);
++	//femmodel->parameters->SetParam(VxDebrisEnum,InputToExtrudeEnum);
++	//extrudefromtop_core(femmodel);	
++
++	debris_analysis->Core(femmodel);
++	delete debris_analysis;
++
++	femmodel->parameters->SetParam(DebrisThicknessEnum,InputToExtrudeEnum);
++	extrudefromtop_core(femmodel);	
++	//femmodel->parameters->SetParam(VxDebrisEnum,InputToExtrudeEnum);
++	//extrudefromtop_core(femmodel);
++
++	if(save_results) femmodel->RequestedOutputsx(&femmodel->results,requested_outputs,numoutputs);
++
++	if(solution_type==DebrisSolutionEnum)femmodel->RequestedDependentsx();
++
++	/*Free ressources:*/
++	if(numoutputs){for(int i=0;i<numoutputs;i++){xDelete<char>(requested_outputs[i]);} xDelete<char*>(requested_outputs);}
++
++	/*profiler*/
++	femmodel->profiler->Stop(DEBRISCORE);
++} /*}}}*/
+Index: ../trunk-jpl/src/c/cores/transient_core.cpp
+===================================================================
+--- ../trunk-jpl/src/c/cores/transient_core.cpp	(revision 27297)
++++ ../trunk-jpl/src/c/cores/transient_core.cpp	(revision 27298)
+@@ -77,7 +77,7 @@
+ 
+ 		if(VerboseSolution()){
+ 			_printf0_("iteration " << step << "/" << ceil((finaltime-time)/dt)+step << \
+-						"  time [yr]: " <<std::fixed<<setprecision(2)<< time/yts << " (time step: " << dt/yts << ")\n");
++					"  time [yr]: " <<std::fixed<<setprecision(2)<< time/yts << " (time step: " << dt/yts << ")\n");
+ 		}
+ 		bool save_results=false;
+ 		if(step%output_frequency==0 || (time >= finaltime - (yts*DBL_EPSILON)) || step==1) save_results=true;
+@@ -100,7 +100,7 @@
+ 		/*Adaptive mesh refinement*/
+ 		if(amr_frequency){
+ 
+-			#if !defined(_HAVE_AD_)
++#if !defined(_HAVE_AD_)
+ 			if(save_results) femmodel->WriteMeshInResults();
+ 			if(step%amr_frequency==0 && time<finaltime){
+ 				if(VerboseSolution()) _printf0_("   refining mesh\n");
+@@ -107,9 +107,9 @@
+ 				femmodel->ReMesh();//Do not refine the last step
+ 			}
+ 
+-			#else
++#else
+ 			_error_("AMR not suppored with AD");
+-			#endif
++#endif
+ 		}
+ 
+ 		if(iscontrol && isautodiff){
+@@ -131,6 +131,7 @@
+ 	/*parameters: */
+ 	bool isstressbalance,ismasstransport,isage,isoceantransport,issmb,isthermal,isgroundingline,isesa,issampling;
+ 	bool isslc,ismovingfront,isdamageevolution,ishydrology,isoceancoupling,isstochasticforcing,save_results;
++	bool isdebris;
+ 	int  step,sb_coupling_frequency;
+ 	int  domaintype,numoutputs;
+ 
+@@ -152,13 +153,14 @@
+ 	femmodel->parameters->FindParam(&isoceancoupling,TransientIsoceancouplingEnum);
+ 	femmodel->parameters->FindParam(&isdamageevolution,TransientIsdamageevolutionEnum);
+ 	femmodel->parameters->FindParam(&ishydrology,TransientIshydrologyEnum);
++	femmodel->parameters->FindParam(&isdebris,TransientIsdebrisEnum);
+ 	femmodel->parameters->FindParam(&issampling,TransientIssamplingEnum);
+ 	femmodel->parameters->FindParam(&numoutputs,TransientNumRequestedOutputsEnum);
+ 	femmodel->parameters->FindParam(&isstochasticforcing,StochasticForcingIsStochasticForcingEnum);
+ 
+-	#if defined(_HAVE_OCEAN_ )
++#if defined(_HAVE_OCEAN_ )
+ 	if(isoceancoupling) OceanExchangeDatax(femmodel,false);
+-	#endif
++#endif
+ 
+ 	if(isstochasticforcing){
+ 		StochasticForcingx(femmodel);
+@@ -207,6 +209,10 @@
+ 		movingfront_core(femmodel);
+ 	}
+ 
++	if(isdebris){
++		debris_core(femmodel);
++	}
++
+ 	/* from here on, prepare geometry for next time step*/
+ 
+ 	if(ismasstransport){
+@@ -228,11 +234,11 @@
+ 
+ 	/*Sea level change: */
+ 	if(isslc){
+-		#ifdef _HAVE_SEALEVELCHANGE_
++#ifdef _HAVE_SEALEVELCHANGE_
+ 		sealevelchange_core(femmodel);
+-		#else
++#else
+ 		_error_("Compiled with SeaLevelChange capability");
+-		#endif
++#endif
+ 	}
+ 
+ 	/*Sampling: */
+@@ -262,20 +268,20 @@
+ 	femmodel->parameters->FindParam(&amr_frequency,TransientAmrFrequencyEnum);
+ 	femmodel->parameters->FindParam(&isslc,TransientIsslcEnum);
+ 
+-	#if defined(_HAVE_BAMG_) && !defined(_HAVE_AD_)
++#if defined(_HAVE_BAMG_) && !defined(_HAVE_AD_)
+ 	if(amr_frequency){
+ 		femmodel->parameters->FindParam(&amr_restart,AmrRestartEnum);
+ 		if(amr_restart) femmodel->ReMesh();
+ 	}
+-	#endif
++#endif
+ 
+-	#if defined(_HAVE_OCEAN_ )
++#if defined(_HAVE_OCEAN_ )
+ 	if(isoceancoupling) OceanExchangeDatax(femmodel,true);
+-	#endif
++#endif
+ 
+-	#if defined(_HAVE_SEALEVELCHANGE_)
++#if defined(_HAVE_SEALEVELCHANGE_)
+ 	if(isslc) sealevelchange_initialgeometry(femmodel);
+-	#endif
++#endif
+ }/*}}}*/
+ 
+ #ifdef _HAVE_CODIPACK_
+@@ -334,7 +340,7 @@
+ 
+ 		if(VerboseSolution()){
+ 			_printf0_("iteration " << step << "/" << ceil((finaltime-time)/dt)+step << \
+-						"  time [yr]: " <<std::fixed<<setprecision(2)<< time/yts << " (time step: " << dt/yts << ")\n");
++					"  time [yr]: " <<std::fixed<<setprecision(2)<< time/yts << " (time step: " << dt/yts << ")\n");
+ 		}
+ 
+ 		/*Store Model State at the beginning of the step*/
+@@ -382,13 +388,13 @@
+ 	delete hdl_countdoubles;
+ 
+ 	/*Start tracing*/
+-	#if _CODIPACK_MAJOR_==2
++#if _CODIPACK_MAJOR_==2
+ 	auto& tape_codi = IssmDouble::getTape();
+-	#elif _CODIPACK_MAJOR_==1
++#elif _CODIPACK_MAJOR_==1
+ 	auto& tape_codi = IssmDouble::getGlobalTape();
+-	#else
+-	#error "_CODIPACK_MAJOR_ not supported"
+-	#endif
++#else
++#error "_CODIPACK_MAJOR_ not supported"
++#endif
+ 	tape_codi.setActive();
+ 
+ 	/*Reverse dependent (f)*/
+@@ -409,17 +415,17 @@
+ 		J += output_value;
+ 
+ 		tape_codi.registerOutput(J);
+-		#if _CODIPACK_MAJOR_==2
++#if _CODIPACK_MAJOR_==2
+ 		codi_global.output_indices.push_back(J.getIdentifier());
+-		#elif _CODIPACK_MAJOR_==1
++#elif _CODIPACK_MAJOR_==1
+ 		codi_global.output_indices.push_back(J.getGradientData());
+-		#else
+-		#error "_CODIPACK_MAJOR_ not supported"
+-		#endif
++#else
++#error "_CODIPACK_MAJOR_ not supported"
++#endif
+ 
+ 		/*Keep track of output for printing*/
+ 		Jlist[count] = output_value.getValue();
+-      count++;
++		count++;
+ 	}
+ 	Jlist[count] = J.getValue();
+ 	_assert_(count == num_responses);
+@@ -472,7 +478,7 @@
+ 
+ 			if(VerboseSolution()){
+ 				_printf0_("step "<<thisstep<<" ("<<ii+1<<"/"<<checkpoint_frequency<<") time [yr]: "\
+-							<<std::fixed<<std::setprecision(2)<<thistime/yts<< " (time step: " << thisdt/yts << ")\n");
++						<<std::fixed<<std::setprecision(2)<<thistime/yts<< " (time step: " << thisdt/yts << ")\n");
+ 			}
+ 
+ 			transient_step(femmodel);
+@@ -523,6 +529,6 @@
+ 	xDelete<double>(Xb);
+ 	xDelete<double>(Yb);
+ 	xDelete<int>(Yin);
+-   return J.getValue();
++	return J.getValue();
+ }/*}}}*/
+ #endif
+Index: ../trunk-jpl/src/c/modules/ModelProcessorx/CreateNodes.cpp
+===================================================================
+--- ../trunk-jpl/src/c/modules/ModelProcessorx/CreateNodes.cpp	(revision 27297)
++++ ../trunk-jpl/src/c/modules/ModelProcessorx/CreateNodes.cpp	(revision 27298)
+@@ -617,7 +617,7 @@
+ 		}
+ 		xDelete<int>(vertex_pairing);
+ 	}
+-	if(!isamr && (analysis==MasstransportAnalysisEnum || analysis==FreeSurfaceBaseAnalysisEnum || analysis==FreeSurfaceTopAnalysisEnum)){
++	if(!isamr && (analysis==MasstransportAnalysisEnum || analysis==FreeSurfaceBaseAnalysisEnum || analysis==FreeSurfaceTopAnalysisEnum || analysis==DebrisAnalysisEnum)){
+ 		int *vertex_pairing = NULL;
+ 		int  numvertex_pairing;
+ 		iomodel->FetchData(&vertex_pairing,&numvertex_pairing,NULL,"md.masstransport.vertex_pairing");
+Index: ../trunk-jpl/src/c/modules/ModelProcessorx/CreateParameters.cpp
+===================================================================
+--- ../trunk-jpl/src/c/modules/ModelProcessorx/CreateParameters.cpp	(revision 27297)
++++ ../trunk-jpl/src/c/modules/ModelProcessorx/CreateParameters.cpp	(revision 27298)
+@@ -89,6 +89,7 @@
+ 		parameters->AddObject(iomodel->CopyConstantObject("md.transient.isslc",TransientIsslcEnum));
+ 		parameters->AddObject(iomodel->CopyConstantObject("md.transient.isoceancoupling",TransientIsoceancouplingEnum));
+ 		parameters->AddObject(iomodel->CopyConstantObject("md.transient.amr_frequency",TransientAmrFrequencyEnum));
++		parameters->AddObject(iomodel->CopyConstantObject("md.transient.isdebris",TransientIsdebrisEnum));
+ 		parameters->AddObject(iomodel->CopyConstantObject("md.transient.issampling",TransientIssamplingEnum));
+ 		parameters->AddObject(iomodel->CopyConstantObject("md.stochasticforcing.isstochasticforcing",StochasticForcingIsStochasticForcingEnum));
+ 
+Index: ../trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp
+===================================================================
+--- ../trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp	(revision 27297)
++++ ../trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp	(revision 27298)
+@@ -163,6 +163,16 @@
+ 		case DamageStabilizationEnum : return "DamageStabilization";
+ 		case DamageStressThresholdEnum : return "DamageStressThreshold";
+ 		case DamageStressUBoundEnum : return "DamageStressUBound";
++		case DebrisMinThicknessEnum : return "DebrisMinThickness";
++		case DebrisNumRequestedOutputsEnum : return "DebrisNumRequestedOutputs";
++		case DebrisPenaltyFactorEnum : return "DebrisPenaltyFactor";
++		case DebrisRequestedOutputsEnum : return "DebrisRequestedOutputs";
++		case DebrisStabilizationEnum : return "DebrisStabilization";
++		case DebrisRemovalmodelEnum : return "DebrisRemovalmodel";
++		case DebrisDisplacementmodelEnum : return "DebrisDisplacementmodel";
++		case DebrisRemovalSlopeThresholdEnum : return "DebrisRemovalSlopeThreshold";
++		case DebrisRemovalStressThresholdEnum : return "DebrisRemovalStressThreshold";
++		case DebrisPackingFractionEnum : return "DebrisPackingFraction";
+ 		case DebugProfilingEnum : return "DebugProfiling";
+ 		case DebrisThicknessEnum : return "DebrisThickness";
+ 		case DomainDimensionEnum : return "DomainDimension";
+@@ -600,6 +610,7 @@
+ 		case TransientAmrFrequencyEnum : return "TransientAmrFrequency";
+ 		case TransientIsageEnum : return "TransientIsage";
+ 		case TransientIsdamageevolutionEnum : return "TransientIsdamageevolution";
++		case TransientIsdebrisEnum : return "TransientIsdebris";
+ 		case TransientIsesaEnum : return "TransientIsesa";
+ 		case TransientIsgiaEnum : return "TransientIsgia";
+ 		case TransientIsgroundinglineEnum : return "TransientIsgroundingline";
+@@ -1125,6 +1136,7 @@
+ 		case VelEnum : return "Vel";
+ 		case VxAverageEnum : return "VxAverage";
+ 		case VxBaseEnum : return "VxBase";
++		case VxDebrisEnum : return "VxDebris";
+ 		case VxEnum : return "Vx";
+ 		case VxMeshEnum : return "VxMesh";
+ 		case VxObsEnum : return "VxObs";
+@@ -1132,6 +1144,7 @@
+ 		case VxSurfaceEnum : return "VxSurface";
+ 		case VyAverageEnum : return "VyAverage";
+ 		case VyBaseEnum : return "VyBase";
++		case VyDebrisEnum : return "VyDebris";
+ 		case VyEnum : return "Vy";
+ 		case VyMeshEnum : return "VyMesh";
+ 		case VyObsEnum : return "VyObs";
+@@ -1320,6 +1333,8 @@
+ 		case DataSetEnum : return "DataSet";
+ 		case DataSetParamEnum : return "DataSetParam";
+ 		case DatasetInputEnum : return "DatasetInput";
++		case DebrisAnalysisEnum : return "DebrisAnalysis";
++		case DebrisSolutionEnum : return "DebrisSolution";
+ 		case DefaultAnalysisEnum : return "DefaultAnalysis";
+ 		case DefaultCalvingEnum : return "DefaultCalving";
+ 		case DenseEnum : return "Dense";
+Index: ../trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp
+===================================================================
+--- ../trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp	(revision 27297)
++++ ../trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp	(revision 27298)
+@@ -166,6 +166,16 @@
+ 	      else if (strcmp(name,"DamageStabilization")==0) return DamageStabilizationEnum;
+ 	      else if (strcmp(name,"DamageStressThreshold")==0) return DamageStressThresholdEnum;
+ 	      else if (strcmp(name,"DamageStressUBound")==0) return DamageStressUBoundEnum;
++	      else if (strcmp(name,"DebrisMinThickness")==0) return DebrisMinThicknessEnum;
++	      else if (strcmp(name,"DebrisNumRequestedOutputs")==0) return DebrisNumRequestedOutputsEnum;
++	      else if (strcmp(name,"DebrisPenaltyFactor")==0) return DebrisPenaltyFactorEnum;
++	      else if (strcmp(name,"DebrisRequestedOutputs")==0) return DebrisRequestedOutputsEnum;
++	      else if (strcmp(name,"DebrisStabilization")==0) return DebrisStabilizationEnum;
++	      else if (strcmp(name,"DebrisRemovalmodel")==0) return DebrisRemovalmodelEnum;
++	      else if (strcmp(name,"DebrisDisplacementmodel")==0) return DebrisDisplacementmodelEnum;
++	      else if (strcmp(name,"DebrisRemovalSlopeThreshold")==0) return DebrisRemovalSlopeThresholdEnum;
++	      else if (strcmp(name,"DebrisRemovalStressThreshold")==0) return DebrisRemovalStressThresholdEnum;
++	      else if (strcmp(name,"DebrisPackingFraction")==0) return DebrisPackingFractionEnum;
+ 	      else if (strcmp(name,"DebugProfiling")==0) return DebugProfilingEnum;
+ 	      else if (strcmp(name,"DebrisThickness")==0) return DebrisThicknessEnum;
+ 	      else if (strcmp(name,"DomainDimension")==0) return DomainDimensionEnum;
+@@ -249,7 +259,10 @@
+ 	      else if (strcmp(name,"HydrologydcIsefficientlayer")==0) return HydrologydcIsefficientlayerEnum;
+ 	      else if (strcmp(name,"HydrologydcLeakageFactor")==0) return HydrologydcLeakageFactorEnum;
+ 	      else if (strcmp(name,"HydrologydcMaxIter")==0) return HydrologydcMaxIterEnum;
+-	      else if (strcmp(name,"HydrologydcPenaltyFactor")==0) return HydrologydcPenaltyFactorEnum;
++         else stage=3;
++   }
++   if(stage==3){
++	      if (strcmp(name,"HydrologydcPenaltyFactor")==0) return HydrologydcPenaltyFactorEnum;
+ 	      else if (strcmp(name,"HydrologydcPenaltyLock")==0) return HydrologydcPenaltyLockEnum;
+ 	      else if (strcmp(name,"HydrologydcRelTol")==0) return HydrologydcRelTolEnum;
+ 	      else if (strcmp(name,"HydrologydcSedimentlimit")==0) return HydrologydcSedimentlimitEnum;
+@@ -259,10 +272,7 @@
+ 	      else if (strcmp(name,"HydrologydcSedimentPorosity")==0) return HydrologydcSedimentPorosityEnum;
+ 	      else if (strcmp(name,"HydrologydcSedimentThickness")==0) return HydrologydcSedimentThicknessEnum;
+ 	      else if (strcmp(name,"HydrologyStepAdapt")==0) return HydrologyStepAdaptEnum;
+-         else stage=3;
+-   }
+-   if(stage==3){
+-	      if (strcmp(name,"HydrologydcTransferFlag")==0) return HydrologydcTransferFlagEnum;
++	      else if (strcmp(name,"HydrologydcTransferFlag")==0) return HydrologydcTransferFlagEnum;
+ 	      else if (strcmp(name,"HydrologydcUnconfinedFlag")==0) return HydrologydcUnconfinedFlagEnum;
+ 	      else if (strcmp(name,"HydrologyshreveStabilization")==0) return HydrologyshreveStabilizationEnum;
+ 	      else if (strcmp(name,"IcecapToEarthComm")==0) return IcecapToEarthCommEnum;
+@@ -372,7 +382,10 @@
+ 	      else if (strcmp(name,"OutputBufferSizePointer")==0) return OutputBufferSizePointerEnum;
+ 	      else if (strcmp(name,"OutputFileName")==0) return OutputFileNameEnum;
+ 	      else if (strcmp(name,"OutputFilePointer")==0) return OutputFilePointerEnum;
+-	      else if (strcmp(name,"Outputdefinition")==0) return OutputdefinitionEnum;
++         else stage=4;
++   }
++   if(stage==4){
++	      if (strcmp(name,"Outputdefinition")==0) return OutputdefinitionEnum;
+ 	      else if (strcmp(name,"QmuErrName")==0) return QmuErrNameEnum;
+ 	      else if (strcmp(name,"QmuInName")==0) return QmuInNameEnum;
+ 	      else if (strcmp(name,"QmuIsdakota")==0) return QmuIsdakotaEnum;
+@@ -382,10 +395,7 @@
+ 	      else if (strcmp(name,"QmuNsample")==0) return QmuNsampleEnum;
+ 	      else if (strcmp(name,"QmuResponsedescriptors")==0) return QmuResponsedescriptorsEnum;
+ 	      else if (strcmp(name,"QmuVariableDescriptors")==0) return QmuVariableDescriptorsEnum;
+-         else stage=4;
+-   }
+-   if(stage==4){
+-	      if (strcmp(name,"QmuVariablePartitions")==0) return QmuVariablePartitionsEnum;
++	      else if (strcmp(name,"QmuVariablePartitions")==0) return QmuVariablePartitionsEnum;
+ 	      else if (strcmp(name,"QmuVariablePartitionsNpart")==0) return QmuVariablePartitionsNpartEnum;
+ 	      else if (strcmp(name,"QmuVariablePartitionsNt")==0) return QmuVariablePartitionsNtEnum;
+ 	      else if (strcmp(name,"QmuResponsePartitions")==0) return QmuResponsePartitionsEnum;
+@@ -495,7 +505,10 @@
+ 	      else if (strcmp(name,"SmbAdThresh")==0) return SmbAdThreshEnum;
+ 	      else if (strcmp(name,"SmbARMAInitialTime")==0) return SmbARMAInitialTimeEnum;
+ 	      else if (strcmp(name,"SmbARMATimestep")==0) return SmbARMATimestepEnum;
+-	      else if (strcmp(name,"SmbARMAarOrder")==0) return SmbARMAarOrderEnum;
++         else stage=5;
++   }
++   if(stage==5){
++	      if (strcmp(name,"SmbARMAarOrder")==0) return SmbARMAarOrderEnum;
+ 	      else if (strcmp(name,"SmbARMAmaOrder")==0) return SmbARMAmaOrderEnum;
+ 	      else if (strcmp(name,"SmbAveraging")==0) return SmbAveragingEnum;
+ 	      else if (strcmp(name,"SmbARMAconst")==0) return SmbARMAconstEnum;
+@@ -505,10 +518,7 @@
+ 	      else if (strcmp(name,"SmbDsnowIdx")==0) return SmbDsnowIdxEnum;
+ 	      else if (strcmp(name,"SmbElevationBins")==0) return SmbElevationBinsEnum;
+ 	      else if (strcmp(name,"SmbCldFrac")==0) return SmbCldFracEnum;
+-         else stage=5;
+-   }
+-   if(stage==5){
+-	      if (strcmp(name,"SmbDelta18o")==0) return SmbDelta18oEnum;
++	      else if (strcmp(name,"SmbDelta18o")==0) return SmbDelta18oEnum;
+ 	      else if (strcmp(name,"SmbDelta18oSurface")==0) return SmbDelta18oSurfaceEnum;
+ 	      else if (strcmp(name,"SmbDenIdx")==0) return SmbDenIdxEnum;
+ 	      else if (strcmp(name,"SmbDt")==0) return SmbDtEnum;
+@@ -612,12 +622,16 @@
+ 	      else if (strcmp(name,"TransientAmrFrequency")==0) return TransientAmrFrequencyEnum;
+ 	      else if (strcmp(name,"TransientIsage")==0) return TransientIsageEnum;
+ 	      else if (strcmp(name,"TransientIsdamageevolution")==0) return TransientIsdamageevolutionEnum;
++	      else if (strcmp(name,"TransientIsdebris")==0) return TransientIsdebrisEnum;
+ 	      else if (strcmp(name,"TransientIsesa")==0) return TransientIsesaEnum;
+ 	      else if (strcmp(name,"TransientIsgia")==0) return TransientIsgiaEnum;
+ 	      else if (strcmp(name,"TransientIsgroundingline")==0) return TransientIsgroundinglineEnum;
+ 	      else if (strcmp(name,"TransientIshydrology")==0) return TransientIshydrologyEnum;
+ 	      else if (strcmp(name,"TransientIsmasstransport")==0) return TransientIsmasstransportEnum;
+-	      else if (strcmp(name,"TransientIsoceantransport")==0) return TransientIsoceantransportEnum;
++         else stage=6;
++   }
++   if(stage==6){
++	      if (strcmp(name,"TransientIsoceantransport")==0) return TransientIsoceantransportEnum;
+ 	      else if (strcmp(name,"TransientIsmovingfront")==0) return TransientIsmovingfrontEnum;
+ 	      else if (strcmp(name,"TransientIsoceancoupling")==0) return TransientIsoceancouplingEnum;
+ 	      else if (strcmp(name,"TransientIssampling")==0) return TransientIssamplingEnum;
+@@ -628,10 +642,7 @@
+ 	      else if (strcmp(name,"TransientNumRequestedOutputs")==0) return TransientNumRequestedOutputsEnum;
+ 	      else if (strcmp(name,"TransientRequestedOutputs")==0) return TransientRequestedOutputsEnum;
+ 	      else if (strcmp(name,"Velocity")==0) return VelocityEnum;
+-         else stage=6;
+-   }
+-   if(stage==6){
+-	      if (strcmp(name,"Xxe")==0) return XxeEnum;
++	      else if (strcmp(name,"Xxe")==0) return XxeEnum;
+ 	      else if (strcmp(name,"Yye")==0) return YyeEnum;
+ 	      else if (strcmp(name,"Zze")==0) return ZzeEnum;
+ 	      else if (strcmp(name,"Areae")==0) return AreaeEnum;
+@@ -740,7 +751,10 @@
+ 	      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 stage=7;
++   }
++   if(stage==7){
++	      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,"DeviatoricStress1")==0) return DeviatoricStress1Enum;
+@@ -751,10 +765,7 @@
+ 	      else if (strcmp(name,"Domain2Dvertical")==0) return Domain2DverticalEnum;
+ 	      else if (strcmp(name,"Domain3D")==0) return Domain3DEnum;
+ 	      else if (strcmp(name,"DragCoefficientAbsGradient")==0) return DragCoefficientAbsGradientEnum;
+-         else stage=7;
+-   }
+-   if(stage==7){
+-	      if (strcmp(name,"DrivingStressX")==0) return DrivingStressXEnum;
++	      else if (strcmp(name,"DrivingStressX")==0) return DrivingStressXEnum;
+ 	      else if (strcmp(name,"DrivingStressY")==0) return DrivingStressYEnum;
+ 	      else if (strcmp(name,"Dummy")==0) return DummyEnum;
+ 	      else if (strcmp(name,"EffectivePressure")==0) return EffectivePressureEnum;
+@@ -863,7 +874,10 @@
+ 	      else if (strcmp(name,"MasstransportSpcthickness")==0) return MasstransportSpcthicknessEnum;
+ 	      else if (strcmp(name,"MaterialsRheologyB")==0) return MaterialsRheologyBEnum;
+ 	      else if (strcmp(name,"MaterialsRheologyBbar")==0) return MaterialsRheologyBbarEnum;
+-	      else if (strcmp(name,"MaterialsRheologyE")==0) return MaterialsRheologyEEnum;
++         else stage=8;
++   }
++   if(stage==8){
++	      if (strcmp(name,"MaterialsRheologyE")==0) return MaterialsRheologyEEnum;
+ 	      else if (strcmp(name,"MaterialsRheologyEbar")==0) return MaterialsRheologyEbarEnum;
+ 	      else if (strcmp(name,"MaterialsRheologyEc")==0) return MaterialsRheologyEcEnum;
+ 	      else if (strcmp(name,"MaterialsRheologyEcbar")==0) return MaterialsRheologyEcbarEnum;
+@@ -874,10 +888,7 @@
+ 	      else if (strcmp(name,"MeshVertexonbase")==0) return MeshVertexonbaseEnum;
+ 	      else if (strcmp(name,"MeshVertexonboundary")==0) return MeshVertexonboundaryEnum;
+ 	      else if (strcmp(name,"MeshVertexonsurface")==0) return MeshVertexonsurfaceEnum;
+-         else stage=8;
+-   }
+-   if(stage==8){
+-	      if (strcmp(name,"Misfit")==0) return MisfitEnum;
++	      else if (strcmp(name,"Misfit")==0) return MisfitEnum;
+ 	      else if (strcmp(name,"MovingFrontalVx")==0) return MovingFrontalVxEnum;
+ 	      else if (strcmp(name,"MovingFrontalVy")==0) return MovingFrontalVyEnum;
+ 	      else if (strcmp(name,"Neumannflux")==0) return NeumannfluxEnum;
+@@ -986,7 +997,10 @@
+ 	      else if (strcmp(name,"SmbA")==0) return SmbAEnum;
+ 	      else if (strcmp(name,"SmbAdiff")==0) return SmbAdiffEnum;
+ 	      else if (strcmp(name,"SmbAValue")==0) return SmbAValueEnum;
+-	      else if (strcmp(name,"SmbAccumulation")==0) return SmbAccumulationEnum;
++         else stage=9;
++   }
++   if(stage==9){
++	      if (strcmp(name,"SmbAccumulation")==0) return SmbAccumulationEnum;
+ 	      else if (strcmp(name,"SmbAdiffini")==0) return SmbAdiffiniEnum;
+ 	      else if (strcmp(name,"SmbAini")==0) return SmbAiniEnum;
+ 	      else if (strcmp(name,"SmbARMANoise")==0) return SmbARMANoiseEnum;
+@@ -997,10 +1011,7 @@
+ 	      else if (strcmp(name,"SmbBPos")==0) return SmbBPosEnum;
+ 	      else if (strcmp(name,"SmbC")==0) return SmbCEnum;
+ 	      else if (strcmp(name,"SmbCcsnowValue")==0) return SmbCcsnowValueEnum;
+-         else stage=9;
+-   }
+-   if(stage==9){
+-	      if (strcmp(name,"SmbCciceValue")==0) return SmbCciceValueEnum;
++	      else if (strcmp(name,"SmbCciceValue")==0) return SmbCciceValueEnum;
+ 	      else if (strcmp(name,"SmbCotValue")==0) return SmbCotValueEnum;
+ 	      else if (strcmp(name,"SmbD")==0) return SmbDEnum;
+ 	      else if (strcmp(name,"SmbDailyairdensity")==0) return SmbDailyairdensityEnum;
+@@ -1109,7 +1120,10 @@
+ 	      else if (strcmp(name,"StressMaxPrincipal")==0) return StressMaxPrincipalEnum;
+ 	      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=10;
++   }
++   if(stage==10){
++	      if (strcmp(name,"StressTensorxz")==0) return StressTensorxzEnum;
+ 	      else if (strcmp(name,"StressTensoryy")==0) return StressTensoryyEnum;
+ 	      else if (strcmp(name,"StressTensoryz")==0) return StressTensoryzEnum;
+ 	      else if (strcmp(name,"StressTensorzz")==0) return StressTensorzzEnum;
+@@ -1120,10 +1134,7 @@
+ 	      else if (strcmp(name,"SurfaceArea")==0) return SurfaceAreaEnum;
+ 	      else if (strcmp(name,"SurfaceAverageVelMisfit")==0) return SurfaceAverageVelMisfitEnum;
+ 	      else if (strcmp(name,"SurfaceCrevasse")==0) return SurfaceCrevasseEnum;
+-         else stage=10;
+-   }
+-   if(stage==10){
+-	      if (strcmp(name,"Surface")==0) return SurfaceEnum;
++	      else if (strcmp(name,"Surface")==0) return SurfaceEnum;
+ 	      else if (strcmp(name,"SurfaceOld")==0) return SurfaceOldEnum;
+ 	      else if (strcmp(name,"SurfaceLogVelMisfit")==0) return SurfaceLogVelMisfitEnum;
+ 	      else if (strcmp(name,"SurfaceLogVxVyMisfit")==0) return SurfaceLogVxVyMisfitEnum;
+@@ -1152,6 +1163,7 @@
+ 	      else if (strcmp(name,"Vel")==0) return VelEnum;
+ 	      else if (strcmp(name,"VxAverage")==0) return VxAverageEnum;
+ 	      else if (strcmp(name,"VxBase")==0) return VxBaseEnum;
++	      else if (strcmp(name,"VxDebris")==0) return VxDebrisEnum;
+ 	      else if (strcmp(name,"Vx")==0) return VxEnum;
+ 	      else if (strcmp(name,"VxMesh")==0) return VxMeshEnum;
+ 	      else if (strcmp(name,"VxObs")==0) return VxObsEnum;
+@@ -1159,6 +1171,7 @@
+ 	      else if (strcmp(name,"VxSurface")==0) return VxSurfaceEnum;
+ 	      else if (strcmp(name,"VyAverage")==0) return VyAverageEnum;
+ 	      else if (strcmp(name,"VyBase")==0) return VyBaseEnum;
++	      else if (strcmp(name,"VyDebris")==0) return VyDebrisEnum;
+ 	      else if (strcmp(name,"Vy")==0) return VyEnum;
+ 	      else if (strcmp(name,"VyMesh")==0) return VyMeshEnum;
+ 	      else if (strcmp(name,"VyObs")==0) return VyObsEnum;
+@@ -1230,7 +1243,10 @@
+ 	      else if (strcmp(name,"Outputdefinition53")==0) return Outputdefinition53Enum;
+ 	      else if (strcmp(name,"Outputdefinition54")==0) return Outputdefinition54Enum;
+ 	      else if (strcmp(name,"Outputdefinition55")==0) return Outputdefinition55Enum;
+-	      else if (strcmp(name,"Outputdefinition56")==0) return Outputdefinition56Enum;
++         else stage=11;
++   }
++   if(stage==11){
++	      if (strcmp(name,"Outputdefinition56")==0) return Outputdefinition56Enum;
+ 	      else if (strcmp(name,"Outputdefinition57")==0) return Outputdefinition57Enum;
+ 	      else if (strcmp(name,"Outputdefinition58")==0) return Outputdefinition58Enum;
+ 	      else if (strcmp(name,"Outputdefinition59")==0) return Outputdefinition59Enum;
+@@ -1243,10 +1259,7 @@
+ 	      else if (strcmp(name,"Outputdefinition65")==0) return Outputdefinition65Enum;
+ 	      else if (strcmp(name,"Outputdefinition66")==0) return Outputdefinition66Enum;
+ 	      else if (strcmp(name,"Outputdefinition67")==0) return Outputdefinition67Enum;
+-         else stage=11;
+-   }
+-   if(stage==11){
+-	      if (strcmp(name,"Outputdefinition68")==0) return Outputdefinition68Enum;
++	      else if (strcmp(name,"Outputdefinition68")==0) return Outputdefinition68Enum;
+ 	      else if (strcmp(name,"Outputdefinition69")==0) return Outputdefinition69Enum;
+ 	      else if (strcmp(name,"Outputdefinition6")==0) return Outputdefinition6Enum;
+ 	      else if (strcmp(name,"Outputdefinition70")==0) return Outputdefinition70Enum;
+@@ -1350,8 +1363,13 @@
+ 	      else if (strcmp(name,"DataSet")==0) return DataSetEnum;
+ 	      else if (strcmp(name,"DataSetParam")==0) return DataSetParamEnum;
+ 	      else if (strcmp(name,"DatasetInput")==0) return DatasetInputEnum;
++	      else if (strcmp(name,"DebrisAnalysis")==0) return DebrisAnalysisEnum;
++	      else if (strcmp(name,"DebrisSolution")==0) return DebrisSolutionEnum;
+ 	      else if (strcmp(name,"DefaultAnalysis")==0) return DefaultAnalysisEnum;
+-	      else if (strcmp(name,"DefaultCalving")==0) return DefaultCalvingEnum;
++         else stage=12;
++   }
++   if(stage==12){
++	      if (strcmp(name,"DefaultCalving")==0) return DefaultCalvingEnum;
+ 	      else if (strcmp(name,"Dense")==0) return DenseEnum;
+ 	      else if (strcmp(name,"DependentObject")==0) return DependentObjectEnum;
+ 	      else if (strcmp(name,"DepthAverageAnalysis")==0) return DepthAverageAnalysisEnum;
+@@ -1366,10 +1384,7 @@
+ 	      else if (strcmp(name,"DoubleMatExternalResult")==0) return DoubleMatExternalResultEnum;
+ 	      else if (strcmp(name,"DoubleMatParam")==0) return DoubleMatParamEnum;
+ 	      else if (strcmp(name,"DoubleParam")==0) return DoubleParamEnum;
+-         else stage=12;
+-   }
+-   if(stage==12){
+-	      if (strcmp(name,"DoubleVecParam")==0) return DoubleVecParamEnum;
++	      else if (strcmp(name,"DoubleVecParam")==0) return DoubleVecParamEnum;
+ 	      else if (strcmp(name,"Element")==0) return ElementEnum;
+ 	      else if (strcmp(name,"ElementHook")==0) return ElementHookEnum;
+ 	      else if (strcmp(name,"ElementSId")==0) return ElementSIdEnum;
+@@ -1474,7 +1489,10 @@
+ 	      else if (strcmp(name,"LoveKernelsImag")==0) return LoveKernelsImagEnum;
+ 	      else if (strcmp(name,"LoveKernelsReal")==0) return LoveKernelsRealEnum;
+ 	      else if (strcmp(name,"LoveKf")==0) return LoveKfEnum;
+-	      else if (strcmp(name,"LoveKt")==0) return LoveKtEnum;
++         else stage=13;
++   }
++   if(stage==13){
++	      if (strcmp(name,"LoveKt")==0) return LoveKtEnum;
+ 	      else if (strcmp(name,"LoveLf")==0) return LoveLfEnum;
+ 	      else if (strcmp(name,"LoveLt")==0) return LoveLtEnum;
+ 	      else if (strcmp(name,"LoveTidalHt")==0) return LoveTidalHtEnum;
+@@ -1489,10 +1507,7 @@
+ 	      else if (strcmp(name,"MINIcondensed")==0) return MINIcondensedEnum;
+ 	      else if (strcmp(name,"MantlePlumeGeothermalFlux")==0) return MantlePlumeGeothermalFluxEnum;
+ 	      else if (strcmp(name,"MassFlux")==0) return MassFluxEnum;
+-         else stage=13;
+-   }
+-   if(stage==13){
+-	      if (strcmp(name,"Masscon")==0) return MassconEnum;
++	      else if (strcmp(name,"Masscon")==0) return MassconEnum;
+ 	      else if (strcmp(name,"Massconaxpby")==0) return MassconaxpbyEnum;
+ 	      else if (strcmp(name,"Massfluxatgate")==0) return MassfluxatgateEnum;
+ 	      else if (strcmp(name,"MasstransportAnalysis")==0) return MasstransportAnalysisEnum;
+@@ -1597,7 +1612,10 @@
+ 	      else if (strcmp(name,"SSAFSApproximation")==0) return SSAFSApproximationEnum;
+ 	      else if (strcmp(name,"SSAHOApproximation")==0) return SSAHOApproximationEnum;
+ 	      else if (strcmp(name,"Scaled")==0) return ScaledEnum;
+-	      else if (strcmp(name,"SealevelAbsolute")==0) return SealevelAbsoluteEnum;
++         else stage=14;
++   }
++   if(stage==14){
++	      if (strcmp(name,"SealevelAbsolute")==0) return SealevelAbsoluteEnum;
+ 	      else if (strcmp(name,"SealevelEmotion")==0) return SealevelEmotionEnum;
+ 	      else if (strcmp(name,"SealevelchangePolarMotionX")==0) return SealevelchangePolarMotionXEnum;
+ 	      else if (strcmp(name,"SealevelchangePolarMotionY")==0) return SealevelchangePolarMotionYEnum;
+@@ -1612,10 +1630,7 @@
+ 	      else if (strcmp(name,"SegmentRiftfront")==0) return SegmentRiftfrontEnum;
+ 	      else if (strcmp(name,"Separate")==0) return SeparateEnum;
+ 	      else if (strcmp(name,"Seq")==0) return SeqEnum;
+-         else stage=14;
+-   }
+-   if(stage==14){
+-	      if (strcmp(name,"SmbAnalysis")==0) return SmbAnalysisEnum;
++	      else if (strcmp(name,"SmbAnalysis")==0) return SmbAnalysisEnum;
+ 	      else if (strcmp(name,"SmbSolution")==0) return SmbSolutionEnum;
+ 	      else if (strcmp(name,"SmoothAnalysis")==0) return SmoothAnalysisEnum;
+ 	      else if (strcmp(name,"SoftMigration")==0) return SoftMigrationEnum;
+Index: ../trunk-jpl/src/m/classes/debris.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/debris.m	(nonexistent)
++++ ../trunk-jpl/src/m/classes/debris.m	(revision 27298)
+@@ -0,0 +1,172 @@
++%DEBRIS class definition
++%
++%   Usage:
++%      debris=debris();
++
++classdef debris
++	properties (SetAccess=public)
++		 spcthickness           = NaN;
++		 min_thickness          = 0;
++		 stabilization          = 0;
++		 packingfraction	= 0;
++		 removalmodel		= 0;
++		 displacementmodel	= 0;
++		 removal_slope_threshold= 0;
++		 removal_stress_threshold=0;
++		 vertex_pairing         = NaN;
++		 requested_outputs      = {};
++	end
++	methods (Static)
++		function self = loadobj(self) % {{{
++			% This function is directly called by matlab when a model object is
++			% loaded. If the input is a struct it is an old version of this class and
++			% old fields must be recovered (make sure they are in the deprecated
++			% model properties)
++
++
++
++			if verLessThan('matlab','7.9'),
++				disp('Warning: your matlab version is old and there is a risk that load does not work correctly');
++				disp('         if the model is not loaded correctly, rename temporarily loadobj so that matlab does not use it');
++
++				% This is a Matlab bug: all the fields of md have their default value
++				% Example of error message:
++				% Warning: Error loading an object of class 'model':
++				% Undefined function or method 'exist' for input arguments of type 'cell'
++				%
++				% This has been fixed in MATLAB 7.9 (R2009b) and later versions
++			end
++
++			if isstruct(self)
++				disp('Recovering debris from older version');
++				self = structtoobj(debris(),self);
++			end
++		end% }}}
++	end
++	methods
++		function self = debris(varargin) % {{{
++			switch nargin
++				case 0
++					self=setdefaultparameters(self);
++				case 1
++					inputstruct=varargin{1};
++					list1 = properties('debris');
++					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 self = extrude(self,md) % {{{
++			self.spcthickness=project3d(md,'vector',self.spcthickness,'type','node');
++		end % }}}
++		function list = defaultoutputs(self,md) % {{{
++
++			list = {'DebrisThickness'};
++
++		end % }}}
++		function self = setdefaultparameters(self) % {{{
++
++			%Type of stabilization to use 0:nothing 1:artificial_diffusivity 3:Discontinuous Galerkin
++			self.stabilization=2;
++
++			%Minimum debris thickness that can be used
++			self.min_thickness=0;
++
++			%Fraction of debris covered in the ice
++			self.packingfraction=0.01;
++
++			%Type of frontal debris removal
++			self.removalmodel=0;
++
++			%Type of debris displacement
++			self.displacementmodel=0;
++
++			%Slope threshold for removalmodel (1)
++                 	self.removal_slope_threshold=0;
++                 	
++			%Stress threshold for removalmodel (2)
++			self.removal_stress_threshold=0;
++
++			%default output
++			self.requested_outputs={'default'};
++		end % }}}
++		function md = checkconsistency(self,md,solution,analyses) % {{{
++
++			%Early return
++			if ~ismember('MasstransportAnalysis',analyses) |  (strcmp(solution,'TransientSolution') & md.transient.isdebris==0), return; end
++
++			md = checkfield(md,'fieldname','debris.spcthickness','Inf',1,'timeseries',1);
++			md = checkfield(md,'fieldname','debris.stabilization','values',[0 1 2 3]);
++			md = checkfield(md,'fieldname','debris.min_thickness','>=',0);
++			md = checkfield(md,'fieldname','debris.packingfraction','>=',0);
++			md = checkfield(md,'fieldname','debris.removalmodel','values',[0 1 2]);
++			md = checkfield(md,'fieldname','debris.displacementmodel','values',[0 1 2]);
++			md = checkfield(md,'fieldname','debris.removal_slope_threshold','>=',0);
++			md = checkfield(md,'fieldname','debris.removal_stress_threshold','>=',0);
++			md = checkfield(md,'fieldname','debris.requested_outputs','stringrow',1);
++			if ~any(isnan(md.stressbalance.vertex_pairing)),
++				md = checkfield(md,'fieldname','stressbalance.vertex_pairing','>',0);
++			end
++		end % }}}
++		function disp(self) % {{{
++			disp(sprintf('   Debris solution parameters:'));
++			fielddisplay(self,'spcthickness','thickness constraints (NaN means no constraint) [m]');
++			fielddisplay(self,'min_thickness','minimum ice thickness allowed [m]');
++			fielddisplay(self,'packingfraction','fraction of debris covered in the ice');
++			fielddisplay(self,'stabilization','0: no stabilization, 1: artificial diffusion, 2: streamline upwinding, 3: streamline upwind Petrov-Galerkin (SUPG)');
++			fielddisplay(self,'removalmodel','frontal removal of debris. 0: no removal, 1: Slope-triggered debris removal, 2: driving-stress triggered debris removal');
++			fielddisplay(self,'displacementmodel','debris displacement. 0: no displacement, 1: ...');
++			fielddisplay(self,'removal_slope_threshold','critical slope (degrees) for removalmodel (1)');
++			fielddisplay(self,'removal_stress_threshold','critical stress (Pa) for removalmodel (2)');
++
++			disp(sprintf('\n      %s','Penalty options:'));
++			fielddisplay(self,'vertex_pairing','pairs of vertices that are penalized');
++			fielddisplay(self,'requested_outputs','additional outputs requested');
++
++		end % }}}
++		function marshall(self,prefix,md,fid) % {{{
++
++			yts=md.constants.yts;
++
++			WriteData(fid,prefix,'object',self,'fieldname','spcthickness','format','DoubleMat','mattype',1,'timeserieslength',md.mesh.numberofvertices+1,'yts',md.constants.yts);
++			WriteData(fid,prefix,'object',self,'fieldname','min_thickness','format','Double');
++			WriteData(fid,prefix,'object',self,'fieldname','stabilization','format','Integer');
++			WriteData(fid,prefix,'object',self,'fieldname','removalmodel','format','Integer');
++			WriteData(fid,prefix,'object',self,'fieldname','displacementmodel','format','Integer');
++			WriteData(fid,prefix,'object',self,'fieldname','removal_slope_threshold','format','Double');
++			WriteData(fid,prefix,'object',self,'fieldname','removal_stress_threshold','format','Double');
++			WriteData(fid,prefix,'object',self,'fieldname','packingfraction','format','Double');
++			WriteData(fid,prefix,'object',self,'fieldname','vertex_pairing','format','DoubleMat','mattype',3);
++
++			%process requested outputs
++			outputs = self.requested_outputs;
++			pos  = find(ismember(outputs,'default'));
++			if ~isempty(pos),
++				outputs(pos) = [];                         %remove 'default' from outputs
++				outputs      = [outputs defaultoutputs(self,md)]; %add defaults
++			end
++			WriteData(fid,prefix,'data',outputs,'name','md.debris.requested_outputs','format','StringArray');
++		end % }}}
++		function savemodeljs(self,fid,modelname) % {{{
++
++			writejs1Darray(fid,[modelname '.debris.spcthickness'],self.spcthickness);
++			writejsdouble(fid,[modelname '.debris.min_thickness'],self.min_thickness);
++			writejsdouble(fid,[modelname '.debris.stabilization'],self.stabilization);
++			writejsdouble(fid,[modelname '.debris.removalmodel'],self.removalmodel);
++			writejsdouble(fid,[modelname '.debris.displacementmodel'],self.displacementmodel);
++			writejsdouble(fid,[modelname '.debris.removal_slope_threshold'],self.removal_slope_threshold);
++			writejsdouble(fid,[modelname '.debris.removal_stress_threshold'],self.removal_stress_threshold);
++			writejsdouble(fid,[modelname '.debris.packingfraction'],self.packingfraction);
++			writejs2Darray(fid,[modelname '.debris.vertex_pairing'],self.vertex_pairing);
++			writejsdouble(fid,[modelname '.debris.penalty_factor'],self.penalty_factor);
++			writejscellstring(fid,[modelname '.debris.requested_outputs'],self.requested_outputs);
++
++		end % }}}
++	end
++end
+Index: ../trunk-jpl/src/c/shared/Enum/EnumDefinitions.h
+===================================================================
+--- ../trunk-jpl/src/c/shared/Enum/EnumDefinitions.h	(revision 27297)
++++ ../trunk-jpl/src/c/shared/Enum/EnumDefinitions.h	(revision 27298)
+@@ -155,6 +155,16 @@
+ 	DamageStabilizationEnum,
+ 	DamageStressThresholdEnum,
+ 	DamageStressUBoundEnum,
++	DebrisMinThicknessEnum,
++        DebrisNumRequestedOutputsEnum,
++        DebrisPenaltyFactorEnum,
++        DebrisRequestedOutputsEnum,
++        DebrisStabilizationEnum,
++        DebrisRemovalmodelEnum,
++        DebrisDisplacementmodelEnum,
++        DebrisRemovalSlopeThresholdEnum,
++        DebrisRemovalStressThresholdEnum,
++        DebrisPackingFractionEnum,
+ 	DebugProfilingEnum,
+ 	DebrisThicknessEnum,
+ 	DomainDimensionEnum,
+@@ -592,6 +602,7 @@
+ 	TransientAmrFrequencyEnum,
+ 	TransientIsageEnum,
+ 	TransientIsdamageevolutionEnum,
++	TransientIsdebrisEnum,
+ 	TransientIsesaEnum,
+ 	TransientIsgiaEnum,
+ 	TransientIsgroundinglineEnum,
+@@ -1120,6 +1131,7 @@
+ 	VelEnum,
+ 	VxAverageEnum,
+ 	VxBaseEnum,
++	VxDebrisEnum,
+ 	VxEnum,
+ 	VxMeshEnum,
+ 	VxObsEnum,
+@@ -1127,6 +1139,7 @@
+ 	VxSurfaceEnum,
+ 	VyAverageEnum,
+ 	VyBaseEnum,
++	VyDebrisEnum,
+ 	VyEnum,
+ 	VyMeshEnum,
+ 	VyObsEnum,
+@@ -1317,6 +1330,8 @@
+ 	DataSetEnum,
+ 	DataSetParamEnum,
+ 	DatasetInputEnum,
++	DebrisAnalysisEnum,
++	DebrisSolutionEnum,
+ 	DefaultAnalysisEnum,
+ 	DefaultCalvingEnum,
+ 	DenseEnum,
Index: /issm/oecreview/Archive/27230-27343/ISSM-27298-27299.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27298-27299.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27298-27299.diff	(revision 27344)
@@ -0,0 +1,291 @@
+Index: ../trunk-jpl/m4/analyses.m4
+===================================================================
+--- ../trunk-jpl/m4/analyses.m4	(revision 27298)
++++ ../trunk-jpl/m4/analyses.m4	(revision 27299)
+@@ -149,6 +149,20 @@
+ AM_CONDITIONAL([DAMAGEEVOLUTION], [test x$HAVE_DAMAGEEVOLUTION = xyes])
+ AC_MSG_RESULT($HAVE_DAMAGEEVOLUTION)
+ dnl }}}
++dnl with-Debris{{{
++AC_ARG_WITH([Debris],
++	AS_HELP_STRING([--with-Debris = YES], [compile with Debris capabilities (default is yes)]),
++	[DEBRIS=$withval],[DEBRIS=yes])
++AC_MSG_CHECKING(for Debris capability compilation)
++
++HAVE_DEBRIS=no 
++if test "x$DEBRIS" = "xyes"; then
++	HAVE_DEBRIS=yes
++	AC_DEFINE([_HAVE_DEBRIS_],[1],[with Debris capability])
++fi
++AM_CONDITIONAL([DEBRIS], [test x$HAVE_DEBRIS = xyes])
++AC_MSG_RESULT($HAVE_DEBRIS)
++dnl }}}
+ dnl with-DepthAverage{{{
+ AC_ARG_WITH([DepthAverage],
+ 	AS_HELP_STRING([--with-DepthAverage = YES], [compile with DepthAverage capabilities (default is yes)]),
+Index: ../trunk-jpl/src/c/analyses/EnumToAnalysis.cpp
+===================================================================
+--- ../trunk-jpl/src/c/analyses/EnumToAnalysis.cpp	(revision 27298)
++++ ../trunk-jpl/src/c/analyses/EnumToAnalysis.cpp	(revision 27299)
+@@ -43,6 +43,9 @@
+ 		#ifdef _HAVE_DAMAGEEVOLUTION_
+ 		case DamageEvolutionAnalysisEnum : return new DamageEvolutionAnalysis();
+ 		#endif
++		#ifdef _HAVE_DEBRIS_
++		case DebrisAnalysisEnum : return new DebrisAnalysis();
++		#endif
+ 		#ifdef _HAVE_DEPTHAVERAGE_
+ 		case DepthAverageAnalysisEnum : return new DepthAverageAnalysis();
+ 		#endif
+Index: ../trunk-jpl/src/c/shared/Enum/Enum.vim
+===================================================================
+--- ../trunk-jpl/src/c/shared/Enum/Enum.vim	(revision 27298)
++++ ../trunk-jpl/src/c/shared/Enum/Enum.vim	(revision 27299)
+@@ -161,7 +161,18 @@
+ syn keyword cConstant DamageStabilizationEnum
+ syn keyword cConstant DamageStressThresholdEnum
+ syn keyword cConstant DamageStressUBoundEnum
++syn keyword cConstant DebrisMinThicknessEnum
++syn keyword cConstant DebrisNumRequestedOutputsEnum
++syn keyword cConstant DebrisPenaltyFactorEnum
++syn keyword cConstant DebrisRequestedOutputsEnum
++syn keyword cConstant DebrisStabilizationEnum
++syn keyword cConstant DebrisRemovalmodelEnum
++syn keyword cConstant DebrisDisplacementmodelEnum
++syn keyword cConstant DebrisRemovalSlopeThresholdEnum
++syn keyword cConstant DebrisRemovalStressThresholdEnum
++syn keyword cConstant DebrisPackingFractionEnum
+ syn keyword cConstant DebugProfilingEnum
++syn keyword cConstant DebrisThicknessEnum
+ syn keyword cConstant DomainDimensionEnum
+ syn keyword cConstant DomainTypeEnum
+ syn keyword cConstant DslModelEnum
+@@ -597,6 +608,7 @@
+ syn keyword cConstant TransientAmrFrequencyEnum
+ syn keyword cConstant TransientIsageEnum
+ syn keyword cConstant TransientIsdamageevolutionEnum
++syn keyword cConstant TransientIsdebrisEnum
+ syn keyword cConstant TransientIsesaEnum
+ syn keyword cConstant TransientIsgiaEnum
+ syn keyword cConstant TransientIsgroundinglineEnum
+@@ -1122,6 +1134,7 @@
+ syn keyword cConstant VelEnum
+ syn keyword cConstant VxAverageEnum
+ syn keyword cConstant VxBaseEnum
++syn keyword cConstant VxDebrisEnum
+ syn keyword cConstant VxEnum
+ syn keyword cConstant VxMeshEnum
+ syn keyword cConstant VxObsEnum
+@@ -1129,6 +1142,7 @@
+ syn keyword cConstant VxSurfaceEnum
+ syn keyword cConstant VyAverageEnum
+ syn keyword cConstant VyBaseEnum
++syn keyword cConstant VyDebrisEnum
+ syn keyword cConstant VyEnum
+ syn keyword cConstant VyMeshEnum
+ syn keyword cConstant VyObsEnum
+@@ -1317,6 +1331,8 @@
+ syn keyword cConstant DataSetEnum
+ syn keyword cConstant DataSetParamEnum
+ syn keyword cConstant DatasetInputEnum
++syn keyword cConstant DebrisAnalysisEnum
++syn keyword cConstant DebrisSolutionEnum
+ syn keyword cConstant DefaultAnalysisEnum
+ syn keyword cConstant DefaultCalvingEnum
+ syn keyword cConstant DenseEnum
+@@ -1541,6 +1557,7 @@
+ syn keyword cConstant SIAApproximationEnum
+ syn keyword cConstant SMBarmaEnum
+ syn keyword cConstant SMBcomponentsEnum
++syn keyword cConstant SMBdebrisMLEnum
+ syn keyword cConstant SMBd18opddEnum
+ syn keyword cConstant SMBforcingEnum
+ syn keyword cConstant SMBgcmEnum
+@@ -1662,7 +1679,6 @@
+ syn keyword cType Cfsurfacelogvel
+ syn keyword cType Cfsurfacesquare
+ syn keyword cType Channel
+-syn keyword cType classes
+ syn keyword cType Constraint
+ syn keyword cType Constraints
+ syn keyword cType Contour
+@@ -1669,8 +1685,8 @@
+ syn keyword cType Contours
+ syn keyword cType ControlInput
+ syn keyword cType Covertree
++syn keyword cType DataSetParam
+ syn keyword cType DatasetInput
+-syn keyword cType DataSetParam
+ syn keyword cType Definition
+ syn keyword cType DependentObject
+ syn keyword cType DoubleInput
+@@ -1683,8 +1699,8 @@
+ syn keyword cType ElementHook
+ syn keyword cType ElementInput
+ syn keyword cType ElementMatrix
++syn keyword cType ElementVector
+ syn keyword cType Elements
+-syn keyword cType ElementVector
+ syn keyword cType ExponentialVariogram
+ syn keyword cType ExternalResult
+ syn keyword cType FemModel
+@@ -1691,12 +1707,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
+ syn keyword cType GenericParam
+@@ -1713,7 +1728,6 @@
+ syn keyword cType IoModel
+ syn keyword cType IssmDirectApplicInterface
+ syn keyword cType IssmParallelDirectApplicInterface
+-syn keyword cType krigingobjects
+ syn keyword cType Load
+ syn keyword cType Loads
+ syn keyword cType Masscon
+@@ -1724,7 +1738,6 @@
+ syn keyword cType Matestar
+ syn keyword cType Matice
+ syn keyword cType Matlitho
+-syn keyword cType matrixobjects
+ syn keyword cType MatrixParam
+ syn keyword cType Misfit
+ syn keyword cType Moulin
+@@ -1737,8 +1750,8 @@
+ syn keyword cType Observation
+ syn keyword cType Observations
+ syn keyword cType Option
++syn keyword cType OptionUtilities
+ syn keyword cType Options
+-syn keyword cType OptionUtilities
+ syn keyword cType Param
+ syn keyword cType Parameters
+ syn keyword cType Pengrid
+@@ -1752,13 +1765,13 @@
+ syn keyword cType Radar
+ syn keyword cType Regionaloutput
+ syn keyword cType Results
++syn keyword cType RiftStruct
+ syn keyword cType Riftfront
+-syn keyword cType RiftStruct
+ syn keyword cType SealevelGeometry
+ syn keyword cType Seg
+ syn keyword cType SegInput
++syn keyword cType SegRef
+ syn keyword cType Segment
+-syn keyword cType SegRef
+ syn keyword cType SpcDynamic
+ syn keyword cType SpcStatic
+ syn keyword cType SpcTransient
+@@ -1777,6 +1790,10 @@
+ syn keyword cType VectorParam
+ 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 AdjointBalancethickness2Analysis
+ syn keyword cType AdjointBalancethicknessAnalysis
+ syn keyword cType AdjointHorizAnalysis
+Index: ../trunk-jpl/src/c/shared/Enum/EnumDefinitions.h
+===================================================================
+--- ../trunk-jpl/src/c/shared/Enum/EnumDefinitions.h	(revision 27298)
++++ ../trunk-jpl/src/c/shared/Enum/EnumDefinitions.h	(revision 27299)
+@@ -156,15 +156,15 @@
+ 	DamageStressThresholdEnum,
+ 	DamageStressUBoundEnum,
+ 	DebrisMinThicknessEnum,
+-        DebrisNumRequestedOutputsEnum,
+-        DebrisPenaltyFactorEnum,
+-        DebrisRequestedOutputsEnum,
+-        DebrisStabilizationEnum,
+-        DebrisRemovalmodelEnum,
+-        DebrisDisplacementmodelEnum,
+-        DebrisRemovalSlopeThresholdEnum,
+-        DebrisRemovalStressThresholdEnum,
+-        DebrisPackingFractionEnum,
++	DebrisNumRequestedOutputsEnum,
++	DebrisPenaltyFactorEnum,
++	DebrisRequestedOutputsEnum,
++	DebrisStabilizationEnum,
++	DebrisRemovalmodelEnum,
++	DebrisDisplacementmodelEnum,
++	DebrisRemovalSlopeThresholdEnum,
++	DebrisRemovalStressThresholdEnum,
++	DebrisPackingFractionEnum,
+ 	DebugProfilingEnum,
+ 	DebrisThicknessEnum,
+ 	DomainDimensionEnum,
+Index: ../trunk-jpl/src/c/shared/Enum/Enumjl.vim
+===================================================================
+--- ../trunk-jpl/src/c/shared/Enum/Enumjl.vim	(revision 27298)
++++ ../trunk-jpl/src/c/shared/Enum/Enumjl.vim	(revision 27299)
+@@ -154,7 +154,18 @@
+ syn keyword juliaConstC DamageStabilizationEnum
+ syn keyword juliaConstC DamageStressThresholdEnum
+ syn keyword juliaConstC DamageStressUBoundEnum
++syn keyword juliaConstC DebrisMinThicknessEnum
++syn keyword juliaConstC DebrisNumRequestedOutputsEnum
++syn keyword juliaConstC DebrisPenaltyFactorEnum
++syn keyword juliaConstC DebrisRequestedOutputsEnum
++syn keyword juliaConstC DebrisStabilizationEnum
++syn keyword juliaConstC DebrisRemovalmodelEnum
++syn keyword juliaConstC DebrisDisplacementmodelEnum
++syn keyword juliaConstC DebrisRemovalSlopeThresholdEnum
++syn keyword juliaConstC DebrisRemovalStressThresholdEnum
++syn keyword juliaConstC DebrisPackingFractionEnum
+ syn keyword juliaConstC DebugProfilingEnum
++syn keyword juliaConstC DebrisThicknessEnum
+ syn keyword juliaConstC DomainDimensionEnum
+ syn keyword juliaConstC DomainTypeEnum
+ syn keyword juliaConstC DslModelEnum
+@@ -590,6 +601,7 @@
+ syn keyword juliaConstC TransientAmrFrequencyEnum
+ syn keyword juliaConstC TransientIsageEnum
+ syn keyword juliaConstC TransientIsdamageevolutionEnum
++syn keyword juliaConstC TransientIsdebrisEnum
+ syn keyword juliaConstC TransientIsesaEnum
+ syn keyword juliaConstC TransientIsgiaEnum
+ syn keyword juliaConstC TransientIsgroundinglineEnum
+@@ -1115,6 +1127,7 @@
+ syn keyword juliaConstC VelEnum
+ syn keyword juliaConstC VxAverageEnum
+ syn keyword juliaConstC VxBaseEnum
++syn keyword juliaConstC VxDebrisEnum
+ syn keyword juliaConstC VxEnum
+ syn keyword juliaConstC VxMeshEnum
+ syn keyword juliaConstC VxObsEnum
+@@ -1122,6 +1135,7 @@
+ syn keyword juliaConstC VxSurfaceEnum
+ syn keyword juliaConstC VyAverageEnum
+ syn keyword juliaConstC VyBaseEnum
++syn keyword juliaConstC VyDebrisEnum
+ syn keyword juliaConstC VyEnum
+ syn keyword juliaConstC VyMeshEnum
+ syn keyword juliaConstC VyObsEnum
+@@ -1310,6 +1324,8 @@
+ syn keyword juliaConstC DataSetEnum
+ syn keyword juliaConstC DataSetParamEnum
+ syn keyword juliaConstC DatasetInputEnum
++syn keyword juliaConstC DebrisAnalysisEnum
++syn keyword juliaConstC DebrisSolutionEnum
+ syn keyword juliaConstC DefaultAnalysisEnum
+ syn keyword juliaConstC DefaultCalvingEnum
+ syn keyword juliaConstC DenseEnum
+@@ -1534,6 +1550,7 @@
+ syn keyword juliaConstC SIAApproximationEnum
+ syn keyword juliaConstC SMBarmaEnum
+ syn keyword juliaConstC SMBcomponentsEnum
++syn keyword juliaConstC SMBdebrisMLEnum
+ syn keyword juliaConstC SMBd18opddEnum
+ syn keyword juliaConstC SMBforcingEnum
+ syn keyword juliaConstC SMBgcmEnum
Index: /issm/oecreview/Archive/27230-27343/ISSM-27299-27300.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27299-27300.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27299-27300.diff	(revision 27344)
@@ -0,0 +1,41 @@
+Index: ../trunk-jpl/src/c/analyses/DebrisAnalysis.h
+===================================================================
+--- ../trunk-jpl/src/c/analyses/DebrisAnalysis.h	(nonexistent)
++++ ../trunk-jpl/src/c/analyses/DebrisAnalysis.h	(revision 27300)
+@@ -0,0 +1,36 @@
++/*! \file DebrisAnalysis.h 
++ *  \brief: header file for generic external result object
++ */
++
++#ifndef _DebrisAnalysis_
++#define _DebrisAnalysis_
++
++/*Headers*/
++#include "./Analysis.h"
++
++class DebrisAnalysis: public Analysis{
++
++	public:
++		/*Model processing*/
++		void CreateConstraints(Constraints* constraints,IoModel* iomodel);
++		void CreateLoads(Loads* loads, IoModel* iomodel);
++		void CreateNodes(Nodes* nodes,IoModel* iomodel,bool isamr=false);
++		int  DofsPerNode(int** doflist,int domaintype,int approximation);
++		void UpdateElements(Elements* elements,Inputs* inputs,IoModel* iomodel,int analysis_counter,int analysis_type);
++		void UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum);
++
++		/*Finite element Analysis*/
++		void           Core(FemModel* femmodel);
++		void           PreCore(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           GradientJ(Vector<IssmDouble>* gradient,Element*  element,int control_type,int control_interp,int control_index);
++		void           InputUpdateFromSolution(IssmDouble* solution,Element* element);
++		void           UpdateConstraints(FemModel* femmodel);
++		void           PostProcessing(FemModel* femmodel);
++		void           PreProcessing(FemModel* femmodel);
++};
++#endif
Index: /issm/oecreview/Archive/27230-27343/ISSM-27300-27301.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27300-27301.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27300-27301.diff	(revision 27344)
@@ -0,0 +1,53 @@
+Index: ../trunk-jpl/src/c/analyses/DebrisAnalysis.cpp
+===================================================================
+--- ../trunk-jpl/src/c/analyses/DebrisAnalysis.cpp	(revision 27300)
++++ ../trunk-jpl/src/c/analyses/DebrisAnalysis.cpp	(revision 27301)
+@@ -691,7 +691,7 @@
+ 			IssmDouble iceminthickness=element->FindParam(MasstransportMinThicknessEnum);                        
+ 
+ 			switch(removalmodel){
+-				case 1:
++				case 1:{
+ 					IssmDouble slope_threshold=element->FindParam(DebrisRemovalSlopeThresholdEnum);
+ 
+ 					for(k=0; k<numnodes;k++){
+@@ -721,8 +721,8 @@
+ 					xDelete<IssmDouble>(slopex);
+ 					xDelete<IssmDouble>(slopey);
+ 					break;
+-
+-				case 2:
++						 }
++				case 2:{
+ 					IssmDouble stress_threshold = element->FindParam(DebrisRemovalStressThresholdEnum);
+ 					IssmDouble gravity = element->FindParam(ConstantsGEnum);
+ 					IssmDouble stress,rhod=1900.;
+@@ -759,7 +759,7 @@
+ 					xDelete<IssmDouble>(slopex);
+ 					xDelete<IssmDouble>(slopey);
+ 					break;
+-
++						 }
+ 				default: _error_("removalmodel "<<EnumToStringx(removalmodel)<<" not implemented yet");
+ 			}
+ 		}
+@@ -821,7 +821,7 @@
+ 			bool displacedebris;
+ 
+ 			switch(displacementmodel){
+-				case 1:
++				case 1:{
+ 					IssmDouble slope_threshold = element->FindParam(DebrisRemovalSlopeThresholdEnum);
+ 					IssmDouble iceminthickness=element->FindParam(MasstransportMinThicknessEnum);
+ 
+@@ -892,9 +892,8 @@
+ 					xDelete<IssmDouble>(slopey);
+ 					xDelete<IssmDouble>(surface);
+ 					break;
+-
++						 }
+ 				case 2:
+-
+ 					// Do nothing
+ 
+ 				default: _error_("Debris displacement model "<<EnumToStringx(displacementmodel)<<" not implemented yet");
Index: /issm/oecreview/Archive/27230-27343/ISSM-27301-27302.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27301-27302.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27301-27302.diff	(revision 27344)
@@ -0,0 +1,32 @@
+Index: ../trunk-jpl/src/c/analyses/DebrisAnalysis.cpp
+===================================================================
+--- ../trunk-jpl/src/c/analyses/DebrisAnalysis.cpp	(revision 27301)
++++ ../trunk-jpl/src/c/analyses/DebrisAnalysis.cpp	(revision 27302)
+@@ -603,12 +603,12 @@
+ 	int*         ddoflist=NULL;
+ 
+ 	int numnodes = element->GetNumberOfNodes();
+-	IssmDouble* thickness    = xNew<IssmDouble>(numnodes);
+-	IssmDouble* thicknessold    = xNew<IssmDouble>(numnodes);
+-	IssmDouble* newthickness = xNew<IssmDouble>(numnodes);
+-	IssmDouble* icethickness    = xNew<IssmDouble>(numnodes);
+-	IssmDouble* bedslopex    = xNew<IssmDouble>(numnodes);
+-	IssmDouble* surfaceslopex    = xNew<IssmDouble>(numnodes);
++	IssmDouble* thickness     = xNew<IssmDouble>(numnodes);
++	IssmDouble* thicknessold  = xNew<IssmDouble>(numnodes);
++	IssmDouble* newthickness  = xNew<IssmDouble>(numnodes);
++	IssmDouble* icethickness  = xNew<IssmDouble>(numnodes);
++	IssmDouble* bedslopex     = xNew<IssmDouble>(numnodes);
++	IssmDouble* surfaceslopex = xNew<IssmDouble>(numnodes);
+ 
+ 	/*Use the dof list to index into the solution vector: */
+ 	IssmDouble minthickness = element->FindParam(DebrisMinThicknessEnum);
+@@ -700,7 +700,7 @@
+ 					isminthicknessinelement=true;
+ 					if(isminthicknessinelement){
+ 						for(k=0; k<numnodes;k++){
+-							if(onsurface[k]){
++							if(onsurface[k]>0.5){
+ 								slope=fabs(slopex[k]);
+ 								if(dim==2) slope=pow(pow(slopex[k],2)+pow(slopey[k],2),0.5);
+ 								if((atan(slope)*rad2deg)>slope_threshold) debristhickness[k]=remove_debris=true;
Index: /issm/oecreview/Archive/27230-27343/ISSM-27302-27303.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27302-27303.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27302-27303.diff	(revision 27344)
@@ -0,0 +1,60 @@
+Index: ../trunk-jpl/src/m/classes/transient.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/transient.m	(revision 27302)
++++ ../trunk-jpl/src/m/classes/transient.m	(revision 27303)
+@@ -16,6 +16,7 @@
+ 		isdamageevolution = 0;
+ 		ismovingfront     = 0;
+ 		ishydrology       = 0;
++		isdebris          = 0;
+ 		issampling        = 0;
+ 		isslc             = 0;
+ 		amr_frequency     = 0;
+@@ -45,6 +46,7 @@
+ 			self.isdamageevolution = 0;
+ 			self.ismovingfront     = 0;
+ 			self.ishydrology       = 0;
++			self.isdebris          = 0;
+ 			self.issampling        = 0;
+ 			self.isslc             = 0;
+ 			self.isoceancoupling   = 0;
+@@ -67,6 +69,7 @@
+ 			self.isdamageevolution = 0;
+ 			self.ismovingfront     = 0;
+ 			self.ishydrology       = 0;
++			self.isdebris= 0;
+ 			self.issampling        = 0;
+ 			self.isslc             = 0;
+ 			self.isoceancoupling   = 0;
+@@ -98,6 +101,7 @@
+ 			md = checkfield(md,'fieldname','transient.isdamageevolution','numel',[1],'values',[0 1]);
+ 			md = checkfield(md,'fieldname','transient.ismovingfront','numel',[1],'values',[0 1]);
+ 			md = checkfield(md,'fieldname','transient.ishydrology','numel',[1],'values',[0 1]);
++			md = checkfield(md,'fieldname','transient.isdebris','numel',[1],'values',[0 1]);
+ 			md = checkfield(md,'fieldname','transient.requested_outputs','stringrow',1);
+ 			md = checkfield(md,'fieldname','transient.isslc','numel',[1],'values',[0 1]);
+ 			md = checkfield(md,'fieldname','transient.isoceancoupling','numel',[1],'values',[0 1]);
+@@ -125,6 +129,7 @@
+ 			fielddisplay(self,'isdamageevolution','indicates whether damage evolution is used in the transient');
+ 			fielddisplay(self,'ismovingfront','indicates whether a moving front capability is used in the transient');
+ 			fielddisplay(self,'ishydrology','indicates whether an hydrology model is used');
++			fielddisplay(self,'isdebris','indicates whether a debris model is used');
+ 			fielddisplay(self,'issampling','indicates whether sampling is used in the transient')
+ 			fielddisplay(self,'isslc','indicates whether a sea-level change solution is used in the transient');
+ 			fielddisplay(self,'isoceancoupling','indicates whether a coupling with an ocean model is used in the transient');
+@@ -143,6 +148,7 @@
+ 			WriteData(fid,prefix,'object',self,'fieldname','isesa','format','Boolean');
+ 			WriteData(fid,prefix,'object',self,'fieldname','isdamageevolution','format','Boolean');
+ 			WriteData(fid,prefix,'object',self,'fieldname','ishydrology','format','Boolean');
++			WriteData(fid,prefix,'object',self,'fieldname','isdebris','format','Boolean');
+ 			WriteData(fid,prefix,'object',self,'fieldname','ismovingfront','format','Boolean');
+ 			WriteData(fid,prefix,'object',self,'fieldname','issampling','format','Boolean'); 
+ 			WriteData(fid,prefix,'object',self,'fieldname','isslc','format','Boolean');
+@@ -171,6 +177,7 @@
+ 			writejsdouble(fid,[modelname '.trans.isdamageevolution'],self.isdamageevolution);
+ 			writejsdouble(fid,[modelname '.trans.ismovingfront'],self.ismovingfront);
+ 			writejsdouble(fid,[modelname '.trans.ishydrology'],self.ishydrology);
++			writejsdouble(fid,[modelname '.trans.isdebris'],self.isdebris);
+ 			writejsdouble(fid,[modelname '.trans.issampling'],self.issampling); 
+ 			writejsdouble(fid,[modelname '.trans.isslc'],self.isslc);
+ 			writejsdouble(fid,[modelname '.trans.isoceancoupling'],self.isoceancoupling);
Index: /issm/oecreview/Archive/27230-27343/ISSM-27303-27304.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27303-27304.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27303-27304.diff	(revision 27344)
@@ -0,0 +1,49 @@
+Index: ../trunk-jpl/src/c/analyses/DebrisAnalysis.cpp
+===================================================================
+--- ../trunk-jpl/src/c/analyses/DebrisAnalysis.cpp	(revision 27303)
++++ ../trunk-jpl/src/c/analyses/DebrisAnalysis.cpp	(revision 27304)
+@@ -169,7 +169,7 @@
+ 			}
+ 		}else{
+ 			for(int i=0;i<numvertices;i++){
+-				//if(onsurface[i]){
++				//if(onsurface[i]>.5){
+ 				slope=fabs(slopex[i]);
+ 				if((atan(slope)*rad2deg)>25.){
+ 					//if(debristhickness[i]>0.01){
+@@ -735,7 +735,7 @@
+ 						//stress=0;
+ 						int kk=0;
+ 						for(k=0; k<numnodes;k++){
+-							if(onsurface[k]){
++							if(onsurface[k]>0.5){
+ 								slope=fabs(slopex[k]);
+ 								if(dim==2) slope=pow(pow(slopex[k],2)+pow(slopey[k],2),0.5);
+ 								stress=rhod*gravity*debristhickness[k]*slope;//pow(slope*slope/(slope*slope+1),0.5);//sin(slope/rad2deg);
+@@ -836,7 +836,7 @@
+ 						int test;
+ 						test=0;
+ 						for(k=0; k<numnodes;k++){
+-							if(onsurface[k]){
++							if(onsurface[k]>.5){
+ 								slope=pow(slopex[k]*slopex[k],0.5);
+ 								if(dim==2) slope=pow(pow(slopex[k],2)+pow(slopey[k],2),0.5);
+ 								if((atan(slope)*rad2deg)>30.){
+@@ -858,7 +858,7 @@
+ 						int index=-1;
+ 						IssmDouble min=1e14;
+ 						for(k=0; k<numnodes;k++){
+-							if(onsurface[k]){
++							if(onsurface[k]>.5){
+ 								if(surface[k]<min){
+ 									index=k;
+ 									min=surface[k];
+@@ -866,7 +866,7 @@
+ 							}
+ 						}
+ 						for(k=0; k<numnodes;k++){
+-							if(onsurface[k]){
++							if(onsurface[k]>.5){
+ 								if(k==index){
+ 									debristhickness[k]=debristhickness[k]+debrissum;
+ 								}else{
Index: /issm/oecreview/Archive/27230-27343/ISSM-27304-27305.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27304-27305.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27304-27305.diff	(revision 27344)
@@ -0,0 +1,73 @@
+Index: ../trunk-jpl/src/m/classes/transient.js
+===================================================================
+--- ../trunk-jpl/src/m/classes/transient.js	(revision 27304)
++++ ../trunk-jpl/src/m/classes/transient.js	(revision 27305)
+@@ -19,6 +19,8 @@
+ 		this.isdamageevolution = 0;
+ 		this.ismovingfront     = 0;
+ 		this.ishydrology       = 0;
++		this.isdebris          = 0;
++		this.issampling        = 0;
+ 		this.isslr             = 0;
+ 		this.isoceancoupling   = 0;
+ 		this.iscoupler         = 0;
+@@ -90,6 +92,7 @@
+ 			WriteData(fid,prefix,'object',this,'fieldname','isdamageevolution','format','Boolean');
+ 			WriteData(fid,prefix,'object',this,'fieldname','ishydrology','format','Boolean');
+ 			WriteData(fid,prefix,'object',this,'fieldname','ismovingfront','format','Boolean');
++			WriteData(fid,prefix,'object',this,'fieldname','isdebris','format','Boolean');
+ 			WriteData(fid,prefix,'object',this,'fieldname','issampling','format','Boolean');
+ 			WriteData(fid,prefix,'object',this,'fieldname','isslc','format','Boolean');
+ 			WriteData(fid,prefix,'object',this,'fieldname','isoceancoupling','format','Boolean');
+Index: ../trunk-jpl/src/m/classes/transient.py
+===================================================================
+--- ../trunk-jpl/src/m/classes/transient.py	(revision 27304)
++++ ../trunk-jpl/src/m/classes/transient.py	(revision 27305)
+@@ -22,6 +22,7 @@
+         self.isdamageevolution = 0
+         self.ismovingfront = 0
+         self.ishydrology = 0
++        self.isdebris = 0
+         self.issampling = 0
+         self.isslc = 0
+         self.amr_frequency = 0
+@@ -44,6 +45,7 @@
+         s += '{}\n'.format(fielddisplay(self, 'isdamageevolution', 'indicates whether damage evolution is used in the transient'))
+         s += '{}\n'.format(fielddisplay(self, 'ismovingfront', 'indicates whether a moving front capability is used in the transient'))
+         s += '{}\n'.format(fielddisplay(self, 'ishydrology', 'indicates whether an hydrology model is used'))
++        s += '{}\n'.format(fielddisplay(self, 'isdebris', 'indicates whether a debris model is used'))
+         s += '{}\n'.format(fielddisplay(self, 'issampling', 'indicates whether sampling is used in the transient'))
+         s += '{}\n'.format(fielddisplay(self, 'isslc', 'indicates if a sea level change solution is used in the transient'))
+         s += '{}\n'.format(fielddisplay(self, 'isoceancoupling', 'indicates whether coupling with an ocean model is used in the transient'))
+@@ -71,6 +73,7 @@
+         self.isdamageevolution = 0
+         self.ismovingfront = 0
+         self.ishydrology = 0
++        self.isdebris = 0
+         self.issampling = 0
+         self.isslc = 0
+         self.isoceancoupling = 0
+@@ -95,6 +98,7 @@
+         self.isdamageevolution = 0
+         self.ismovingfront = 0
+         self.ishydrology = 0
++        self.isdebris = 0
+         self.issampling = 0
+         self.isslc = 0
+         self.isoceancoupling = 0
+@@ -120,6 +124,7 @@
+         md = checkfield(md, 'fieldname', 'transient.isesa', 'numel', [1], 'values', [0, 1])
+         md = checkfield(md, 'fieldname', 'transient.isdamageevolution', 'numel', [1], 'values', [0, 1])
+         md = checkfield(md, 'fieldname', 'transient.ishydrology', 'numel', [1], 'values', [0, 1])
++        md = checkfield(md, 'fieldname', 'transient.isdebris', 'numel', [1], 'values', [0, 1])
+         md = checkfield(md, 'fieldname', 'transient.issampling', 'numel', [1], 'values', [0, 1])
+         md = checkfield(md, 'fieldname', 'transient.ismovingfront', 'numel', [1], 'values', [0, 1])
+         md = checkfield(md, 'fieldname', 'transient.isslc', 'numel', [1], 'values', [0, 1])
+@@ -145,6 +150,7 @@
+         WriteData(fid, prefix, 'object', self, 'fieldname', 'isdamageevolution', 'format', 'Boolean')
+         WriteData(fid, prefix, 'object', self, 'fieldname', 'ishydrology', 'format', 'Boolean')
+         WriteData(fid, prefix, 'object', self, 'fieldname', 'ismovingfront', 'format', 'Boolean')
++        WriteData(fid, prefix, 'object', self, 'fieldname', 'isdebris', 'format', 'Boolean')
+         WriteData(fid, prefix, 'object', self, 'fieldname', 'issampling', 'format', 'Boolean')
+         WriteData(fid, prefix, 'object', self, 'fieldname', 'isslc', 'format', 'Boolean')
+         WriteData(fid, prefix, 'object', self, 'fieldname', 'isoceancoupling', 'format', 'Boolean')
Index: /issm/oecreview/Archive/27230-27343/ISSM-27305-27306.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27305-27306.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27305-27306.diff	(revision 27344)
@@ -0,0 +1,30 @@
+Index: ../trunk-jpl/src/c/classes/FemModel.cpp
+===================================================================
+--- ../trunk-jpl/src/c/classes/FemModel.cpp	(revision 27305)
++++ ../trunk-jpl/src/c/classes/FemModel.cpp	(revision 27306)
+@@ -980,13 +980,14 @@
+ 		solution_flops=profiler->TotalFlops(CORE);
+ 		solution_memory=profiler->Memory(CORE);
+ 
+-		_printf0_("\nCore solution profiling\n");
++		_printf0_("\n======================================================\n");
++		_printf0_("Core solution profiling\n");
+ 		_printf0_("   elapsed time    : " << solution_time   << " Seconds\n");
+ 		_printf0_("   number of flops : " << solution_flops  << " Flops\n");
+ 		_printf0_("   memory used     : " << solution_memory << " Bytes\n");
+ 
+ 		/*Individual cores*/
+-		_printf0_("Individual core profiling\n");
++		_printf0_("\nIndividual core profiling\n");
+ 		if(profiler->Used(THERMALCORE)) _printf0_("   "<<setw(40)<<left<<"Thermal core elapsed time:"<<setw(7)<<setprecision(6)<<profiler->TotalTime(THERMALCORE) << " sec\n");
+ 		if(profiler->Used(HYDROLOGYCORE)) _printf0_("   "<<setw(40)<<left<<"Hydrology core elapsed time:"<<setw(7)<<setprecision(6)<<profiler->TotalTime(HYDROLOGYCORE) << " sec\n");
+ 		if(profiler->Used(STRESSBALANCECORE)) _printf0_("   "<<setw(40)<<left<<"Stress balance core elapsed time:"<<setw(7)<<setprecision(6)<<profiler->TotalTime(STRESSBALANCECORE) << " sec\n");
+@@ -1023,7 +1024,7 @@
+ 		_printf0_("   number of flops : " << solution_flops  << " Flops\n");
+ 		_printf0_("   memory used     : " << solution_memory << " Bytes\n");
+ 		#endif
+-		_printf0_("\n");
++		_printf0_("======================================================\n");
+ 	}
+ }
+ /*}}}*/
Index: /issm/oecreview/Archive/27230-27343/ISSM-27306-27307.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27306-27307.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27306-27307.diff	(revision 27344)
@@ -0,0 +1,52 @@
+Index: ../trunk-jpl/externalpackages/petsc/install-3.16-linux.sh
+===================================================================
+--- ../trunk-jpl/externalpackages/petsc/install-3.16-linux.sh	(revision 27306)
++++ ../trunk-jpl/externalpackages/petsc/install-3.16-linux.sh	(revision 27307)
+@@ -24,7 +24,7 @@
+ 
+ # Configure
+ cd ${PETSC_DIR}
+-./config/configure.py \
++./configure \
+ 	--prefix="${PREFIX}" \
+ 	--PETSC_DIR="${PETSC_DIR}" \
+ 	-COPTFLAGS="-g -O2" -CXXOPTFLAGS="-g -O2" -FOPTFLAGS="-g -O2" \
+Index: ../trunk-jpl/externalpackages/petsc/install-3.16-mac.sh
+===================================================================
+--- ../trunk-jpl/externalpackages/petsc/install-3.16-mac.sh	(revision 27306)
++++ ../trunk-jpl/externalpackages/petsc/install-3.16-mac.sh	(revision 27307)
+@@ -36,7 +36,7 @@
+ #	for gfortran 10 or later (may need to remove it for earlier versions).
+ #
+ cd ${PETSC_DIR}
+-./config/configure.py \
++./configure \
+ 	--prefix="${PREFIX}" \
+ 	--PETSC_DIR="${PETSC_DIR}" \
+ 	--CFLAGS="-Wno-error=implicit-function-declaration" \
+Index: ../trunk-jpl/externalpackages/petsc/install-3.17-mac-m1-static.sh
+===================================================================
+--- ../trunk-jpl/externalpackages/petsc/install-3.17-mac-m1-static.sh	(revision 27306)
++++ ../trunk-jpl/externalpackages/petsc/install-3.17-mac-m1-static.sh	(revision 27307)
+@@ -39,7 +39,7 @@
+ #
+ #	for gfortran 10 or later (may need to remove it for earlier versions).
+ cd ${PETSC_DIR}
+-./config/configure.py \
++./configure \
+ 	--prefix="${PREFIX}" \
+ 	--PETSC_DIR="${PETSC_DIR}" \
+ 	--LDFLAGS="-Wl,-no_compact_unwind" \
+Index: ../trunk-jpl/externalpackages/petsc/install-3.17-mac-m1.sh
+===================================================================
+--- ../trunk-jpl/externalpackages/petsc/install-3.17-mac-m1.sh	(revision 27306)
++++ ../trunk-jpl/externalpackages/petsc/install-3.17-mac-m1.sh	(revision 27307)
+@@ -25,7 +25,7 @@
+ 
+ # Configure
+ cd ${PETSC_DIR}
+-./config/configure.py \
++./configure \
+ 	--prefix="${PREFIX}" \
+ 	--PETSC_DIR="${PETSC_DIR}" \
+ 	--LDFLAGS="-Wl,-no_compact_unwind" \
Index: /issm/oecreview/Archive/27230-27343/ISSM-27307-27308.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27307-27308.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27307-27308.diff	(revision 27344)
@@ -0,0 +1,4450 @@
+Index: ../trunk-jpl/src/c/analyses/HydrologyTwsAnalysis.cpp
+===================================================================
+--- ../trunk-jpl/src/c/analyses/HydrologyTwsAnalysis.cpp	(revision 27307)
++++ ../trunk-jpl/src/c/analyses/HydrologyTwsAnalysis.cpp	(revision 27308)
+@@ -34,7 +34,7 @@
+ 	}
+ 
+ 	/*Plug inputs into element:*/
+-	iomodel->FetchDataToInput(inputs,elements,"md.hydrology.spcwatercolum", HydrologyTwsSpcEnum);
++	iomodel->FetchDataToInput(inputs,elements,"md.hydrology.spcwatercolumn", HydrologyTwsSpcEnum);
+ 
+ 	/*Initialize sea level cumulated sea level loads :*/
+ 	iomodel->ConstantToInput(inputs,elements,0.,AccumulatedDeltaTwsEnum,P1Enum);
+@@ -52,7 +52,6 @@
+ 
+ 	/*Now, do we really want Tws?*/
+ 	if(hydrology_model!=HydrologyTwsEnum) return;
+-
+ 	parameters->AddObject(new IntParam(HydrologyModelEnum,hydrology_model));
+ 
+ 	/*Requested outputs*/
+Index: ../trunk-jpl/src/c/analyses/LoveAnalysis.cpp
+===================================================================
+--- ../trunk-jpl/src/c/analyses/LoveAnalysis.cpp	(revision 27307)
++++ ../trunk-jpl/src/c/analyses/LoveAnalysis.cpp	(revision 27308)
+@@ -19,11 +19,27 @@
+ }/*}}}*/
+ void LoveAnalysis::UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum){/*{{{*/
+ 	IssmDouble* frequencies = NULL;
+-	int         nfreq;
++	IssmDouble* hypergeom_z = NULL;
++	IssmDouble* hypergeom_table1 = NULL;
++	IssmDouble* hypergeom_table2 = NULL;
++	int         nfreq,nz, nalpha;
+ 	iomodel->FetchData(&nfreq,"md.love.nfreq");
++	iomodel->FetchData(&nz,"md.love.hypergeom_nz");
++	iomodel->FetchData(&nalpha,"md.love.hypergeom_nalpha");
+ 	iomodel->FetchData(&frequencies,NULL,NULL,"md.love.frequencies");
++	iomodel->FetchData(&hypergeom_z,NULL,NULL,"md.love.hypergeom_z");
++	iomodel->FetchData(&hypergeom_table1,NULL,NULL,"md.love.hypergeom_table1");
++	iomodel->FetchData(&hypergeom_table2,NULL,NULL,"md.love.hypergeom_table2");
++
+ 	parameters->AddObject(new DoubleVecParam(LoveFrequenciesEnum,frequencies,nfreq));
++	parameters->AddObject(new DoubleVecParam(LoveHypergeomZEnum,hypergeom_z,nz));
++	parameters->AddObject(new DoubleMatParam(LoveHypergeomTable1Enum,hypergeom_table1,nz,nalpha));
++	parameters->AddObject(new DoubleMatParam(LoveHypergeomTable2Enum,hypergeom_table2,nz,nalpha));
++
+ 	xDelete<IssmDouble>(frequencies);
++	xDelete<IssmDouble>(hypergeom_z);
++	xDelete<IssmDouble>(hypergeom_table1);
++	xDelete<IssmDouble>(hypergeom_table2);
+ 
+ 	parameters->AddObject(iomodel->CopyConstantObject("md.love.nfreq",LoveNfreqEnum));
+ 	parameters->AddObject(iomodel->CopyConstantObject("md.love.sh_nmax",LoveShNmaxEnum));
+@@ -36,7 +52,9 @@
+ 	parameters->AddObject(iomodel->CopyConstantObject("md.love.allow_layer_deletion",LoveAllowLayerDeletionEnum));
+ 	parameters->AddObject(iomodel->CopyConstantObject("md.love.underflow_tol",LoveUnderflowTolEnum));
+ 	parameters->AddObject(iomodel->CopyConstantObject("md.love.pw_threshold",LovePostWidderThresholdEnum));
+-	parameters->AddObject(iomodel->CopyConstantObject("md.love.integration_steps_per_layer",LoveIntStepsPerLayerEnum));
++	parameters->AddObject(iomodel->CopyConstantObject("md.love.min_integration_steps",LoveMinIntegrationStepsEnum));
++	parameters->AddObject(iomodel->CopyConstantObject("md.love.max_integration_dr",LoveMaxIntegrationdrEnum));
++	parameters->AddObject(iomodel->CopyConstantObject("md.love.integration_scheme",LoveIntegrationSchemeEnum));
+ 	parameters->AddObject(iomodel->CopyConstantObject("md.love.istemporal",LoveIsTemporalEnum));
+ 	parameters->AddObject(iomodel->CopyConstantObject("md.love.n_temporal_iterations",LoveNTemporalIterationsEnum));
+ 	parameters->AddObject(iomodel->CopyConstantObject("md.love.love_kernels",LoveKernelsEnum));
+@@ -44,10 +62,14 @@
+ 	parameters->AddObject(iomodel->CopyConstantObject("md.love.inner_core_boundary",LoveInnerCoreBoundaryEnum));
+ 	parameters->AddObject(iomodel->CopyConstantObject("md.love.core_mantle_boundary",LoveCoreMantleBoundaryEnum));
+ 	parameters->AddObject(iomodel->CopyConstantObject("md.love.complex_computation",LoveComplexComputationEnum));
++	parameters->AddObject(iomodel->CopyConstantObject("md.love.quad_precision",LoveQuadPrecisionEnum));
++	parameters->AddObject(iomodel->CopyConstantObject("md.love.debug",LoveDebugEnum));
+ 	parameters->AddObject(iomodel->CopyConstantObject("md.solidearth.rotational.equatorialmoi",RotationalEquatorialMoiEnum));
+ 	parameters->AddObject(iomodel->CopyConstantObject("md.solidearth.rotational.polarmoi",RotationalPolarMoiEnum));
+ 	parameters->AddObject(iomodel->CopyConstantObject("md.solidearth.rotational.angularvelocity",RotationalAngularVelocityEnum));
+ 	parameters->AddObject(iomodel->CopyConstantObject("md.solidearth.lovenumbers.tk2secular",TidalLoveK2SecularEnum));
++	parameters->AddObject(iomodel->CopyConstantObject("md.love.hypergeom_nz",LoveHypergeomNZEnum));
++	parameters->AddObject(iomodel->CopyConstantObject("md.love.hypergeom_nalpha",LoveHypergeomNAlphaEnum));
+ }/*}}}*/
+ void LoveAnalysis::UpdateConstraints(FemModel* femmodel){/*{{{*/
+ 	/*Default, do nothing*/
+Index: ../trunk-jpl/src/c/analyses/SealevelchangeAnalysis.cpp
+===================================================================
+--- ../trunk-jpl/src/c/analyses/SealevelchangeAnalysis.cpp	(revision 27307)
++++ ../trunk-jpl/src/c/analyses/SealevelchangeAnalysis.cpp	(revision 27308)
+@@ -48,6 +48,8 @@
+ 	iomodel->FetchDataToInput(inputs,elements,"md.mask.ice_levelset",MaskIceLevelsetEnum);
+ 	iomodel->FetchDataToInput(inputs,elements,"md.geometry.bed",BedEnum);
+ 
++	iomodel->FetchDataToInput(inputs,elements,"md.solidearth.transfercount",CouplingTransferCountEnum);
++
+ 	/*external solidearthsolution: solid-Earth model*/
+ 	iomodel->FetchData(&isexternal,"md.solidearth.isexternal");
+ 
+@@ -58,7 +60,7 @@
+ 		iomodel->FetchDataToInput(inputs,elements,"md.solidearth.external.geoid",SolidearthExternalGeoidRateEnum);
+ 
+ 		/*Resolve Mmes using the modelid, if necessary:*/
+-		if (inputs->GetInputObjectEnum(SolidearthExternalDisplacementEastRateEnum)==DatasetInputEnum){
++		if (inputs->GetInputObjectEnum(SolidearthExternalDisplacementUpRateEnum)==DatasetInputEnum){
+ 			int modelid;
+ 
+ 			/*retrieve model id: */
+Index: ../trunk-jpl/src/c/classes/Elements/Element.h
+===================================================================
+--- ../trunk-jpl/src/c/classes/Elements/Element.h	(revision 27307)
++++ ../trunk-jpl/src/c/classes/Elements/Element.h	(revision 27308)
+@@ -405,7 +405,7 @@
+ 
+ 		virtual void       SealevelchangeGeometrySubElementKernel(SealevelGeometry* slgeom)=0;
+ 		virtual void       SealevelchangeShift(GrdLoads* loads, IssmDouble offset, SealevelGeometry* slgeom)=0;
+-		virtual void       SealevelchangeGeometryInitial(IssmDouble* xxe, IssmDouble* yye, IssmDouble* zze, IssmDouble* areae, int* lids)=0;
++		virtual void       SealevelchangeGeometryInitial(IssmDouble* xxe, IssmDouble* yye, IssmDouble* zze, IssmDouble* areae, int* lids, int* vcount)=0;
+ 		virtual void       SealevelchangeGeometryCentroidLoads(SealevelGeometry* slgeom, IssmDouble* xxe, IssmDouble* yye, IssmDouble* zze, IssmDouble* areae)=0;
+ 		virtual void       SealevelchangeGeometrySubElementLoads(SealevelGeometry* slgeom, IssmDouble* areae)=0;
+ 		virtual void       SealevelchangeBarystaticLoads(GrdLoads* loads, BarystaticContributions* barycontrib, SealevelGeometry* slgeom)=0;
+Index: ../trunk-jpl/src/c/classes/Elements/Penta.h
+===================================================================
+--- ../trunk-jpl/src/c/classes/Elements/Penta.h	(revision 27307)
++++ ../trunk-jpl/src/c/classes/Elements/Penta.h	(revision 27308)
+@@ -226,7 +226,7 @@
+ 		void       GiaDeflection(Vector<IssmDouble>* wg,Vector<IssmDouble>* dwgdt,Matlitho* litho, IssmDouble* x,IssmDouble* y){_error_("not implemented yet");};
+ 		void       SealevelchangeGeometrySubElementKernel(SealevelGeometry* slgeom){_error_("not implemented yet");};
+ 		void       SealevelchangeShift(GrdLoads* loads,  IssmDouble offset, SealevelGeometry* slgeom){_error_("not implemented yet");};
+-		void       SealevelchangeGeometryInitial(IssmDouble* xxe, IssmDouble* yye, IssmDouble* zze, IssmDouble* areae, int* lids){_error_("not implemented yet");};
++		void       SealevelchangeGeometryInitial(IssmDouble* xxe, IssmDouble* yye, IssmDouble* zze, IssmDouble* areae, int* lids,int* vcount){_error_("not implemented yet");};
+ 		void       SealevelchangeGeometryCentroidLoads(SealevelGeometry* slgeom, IssmDouble* xxe, IssmDouble* yye, IssmDouble* zze, IssmDouble* areae){_error_("not implemented yet");};
+ 		void       SealevelchangeGeometrySubElementLoads(SealevelGeometry* slgeom, IssmDouble* areae){_error_("not implemented yet");};
+ 		void       SealevelchangeBarystaticLoads(GrdLoads* loads,  BarystaticContributions* barycontrib, SealevelGeometry* slgeom){_error_("not implemented yet");};
+Index: ../trunk-jpl/src/c/classes/Elements/Seg.h
+===================================================================
+--- ../trunk-jpl/src/c/classes/Elements/Seg.h	(revision 27307)
++++ ../trunk-jpl/src/c/classes/Elements/Seg.h	(revision 27308)
+@@ -179,7 +179,7 @@
+ 		void       GiaDeflection(Vector<IssmDouble>* wg,Vector<IssmDouble>* dwgdt,Matlitho* litho, IssmDouble* x,IssmDouble* y){_error_("not implemented yet");};
+ 		void       SealevelchangeGeometrySubElementKernel(SealevelGeometry* slgeom){_error_("not implemented yet");};
+ 		void       SealevelchangeShift(GrdLoads* loads, IssmDouble offset, SealevelGeometry* slgeom){_error_("not implemented yet");};
+-		void       SealevelchangeGeometryInitial(IssmDouble* xxe, IssmDouble* yye, IssmDouble* zze, IssmDouble* areae, int* lids){_error_("not implemented yet");};
++		void       SealevelchangeGeometryInitial(IssmDouble* xxe, IssmDouble* yye, IssmDouble* zze, IssmDouble* areae, int* lids,int* vcount){_error_("not implemented yet");};
+ 		void       SealevelchangeGeometryCentroidLoads(SealevelGeometry* slgeom, IssmDouble* xxe, IssmDouble* yye, IssmDouble* zze, IssmDouble* areae){_error_("not implemented yet");};
+ 		void       SealevelchangeGeometrySubElementLoads(SealevelGeometry* slgeom, IssmDouble* areae){_error_("not implemented yet");};
+ 		void       SealevelchangeBarystaticLoads(GrdLoads* loads,  BarystaticContributions* barycontrib, SealevelGeometry* slgeom){_error_("not implemented yet");};
+Index: ../trunk-jpl/src/c/classes/Elements/Tetra.h
+===================================================================
+--- ../trunk-jpl/src/c/classes/Elements/Tetra.h	(revision 27307)
++++ ../trunk-jpl/src/c/classes/Elements/Tetra.h	(revision 27308)
+@@ -186,7 +186,7 @@
+ 		void       GiaDeflection(Vector<IssmDouble>* wg,Vector<IssmDouble>* dwgdt, Matlitho* litho, IssmDouble* x,IssmDouble* y){_error_("not implemented yet");};
+ 		void       SealevelchangeGeometrySubElementKernel(SealevelGeometry* slgeom){_error_("not implemented yet");};
+ 		void       SealevelchangeShift(GrdLoads* loads,  IssmDouble offset, SealevelGeometry* slgeom){_error_("not implemented yet");};
+-		void       SealevelchangeGeometryInitial(IssmDouble* xxe, IssmDouble* yye, IssmDouble* zze, IssmDouble* areae, int* lids){_error_("not implemented yet");};
++		void       SealevelchangeGeometryInitial(IssmDouble* xxe, IssmDouble* yye, IssmDouble* zze, IssmDouble* areae, int* lids, int* vcount){_error_("not implemented yet");};
+ 		void       SealevelchangeGeometryCentroidLoads(SealevelGeometry* slgeom, IssmDouble* xxe, IssmDouble* yye, IssmDouble* zze, IssmDouble* areae){_error_("not implemented yet");};
+ 		void       SealevelchangeGeometrySubElementLoads(SealevelGeometry* slgeom, IssmDouble* areae){_error_("not implemented yet");};
+ 		void       SealevelchangeBarystaticLoads(GrdLoads* loads, BarystaticContributions* barycontrib, SealevelGeometry* slgeom){_error_("not implemented yet");};
+Index: ../trunk-jpl/src/c/classes/Elements/Tria.h
+===================================================================
+--- ../trunk-jpl/src/c/classes/Elements/Tria.h	(revision 27307)
++++ ../trunk-jpl/src/c/classes/Elements/Tria.h	(revision 27308)
+@@ -171,7 +171,7 @@
+ 		#endif
+ 		#ifdef _HAVE_SEALEVELCHANGE_
+ 		void       GiaDeflection(Vector<IssmDouble>* wg,Vector<IssmDouble>* dwgdt,Matlitho* litho, IssmDouble* x,IssmDouble* y);
+-		void       SealevelchangeGeometryInitial(IssmDouble* xxe, IssmDouble* yye, IssmDouble* zze, IssmDouble* areae, int* lids);
++		void       SealevelchangeGeometryInitial(IssmDouble* xxe, IssmDouble* yye, IssmDouble* zze, IssmDouble* areae, int* lids, int* vcount);
+ 		void       SealevelchangeGeometrySubElementKernel(SealevelGeometry* slgeom);
+ 		void       SealevelchangeGeometrySubElementLoads(SealevelGeometry* slgeom, IssmDouble* areae);
+ 		void       SealevelchangeGeometryCentroidLoads(SealevelGeometry* slgeom, IssmDouble* xxe, IssmDouble* yye, IssmDouble* zze, IssmDouble* areae);
+@@ -244,7 +244,9 @@
+ 		void           StabilizationParameterAnisotropic(IssmDouble* tau_parameter_ansiotropic, IssmDouble u, IssmDouble v, IssmDouble w, IssmDouble hx, IssmDouble hy, IssmDouble hz, IssmDouble kappa){_error_("not implemented yet");};
+ 		void           UpdateConstraintsExtrudeFromBase(void);
+ 		void           UpdateConstraintsExtrudeFromTop(void);
+-		void           SealevelchangeGxL(IssmDouble* grdfieldout, int spatial_component, int* AlphaIndex, int** AlphaIndexsub, int* AzimIndex, int**AzimIndexsub, IssmDouble* G, IssmDouble* Grot, GrdLoads* loads, IssmDouble* polarmotionvector, SealevelGeometry* slgeom, int nel, bool percpu, int viscousenum, bool computefuture);
++		IssmDouble*    SealevelchangeGxL(IssmDouble* G, IssmDouble* Grot, GrdLoads* loads, IssmDouble* polarmotionvector, SealevelGeometry* slgeom, int nel, bool computefuture);
++		IssmDouble*    SealevelchangeHorizGxL(int spatial_component, IssmDouble* G, IssmDouble* Grot, GrdLoads* loads, IssmDouble* polarmotionvector, SealevelGeometry* slgeom, int nel, bool computefuture);
++		void	       SealevelchangeCollectGrdfield(IssmDouble* grdfieldout, IssmDouble* grdfield, SealevelGeometry* slgeom, int nel, bool percpu, int viscousenum, bool computefuture);
+ 		/*}}}*/
+ 
+ };
+Index: ../trunk-jpl/src/c/classes/FemModel.cpp
+===================================================================
+--- ../trunk-jpl/src/c/classes/FemModel.cpp	(revision 27307)
++++ ../trunk-jpl/src/c/classes/FemModel.cpp	(revision 27308)
+@@ -784,6 +784,9 @@
+ 			if(hydrology_model==HydrologypismEnum){
+ 				analyses_temp[numanalyses++]=HydrologyPismAnalysisEnum;
+ 			}
++			if(hydrology_model==HydrologyTwsEnum){
++				analyses_temp[numanalyses++]=HydrologyTwsAnalysisEnum;
++			}
+ 			if(hydrology_model==HydrologydcEnum){
+ 				analyses_temp[numanalyses++]=HydrologyDCInefficientAnalysisEnum;
+ 				analyses_temp[numanalyses++]=HydrologyDCEfficientAnalysisEnum;
+Index: ../trunk-jpl/src/c/classes/GrdLoads.cpp
+===================================================================
+--- ../trunk-jpl/src/c/classes/GrdLoads.cpp	(revision 27307)
++++ ../trunk-jpl/src/c/classes/GrdLoads.cpp	(revision 27308)
+@@ -19,8 +19,13 @@
+ GrdLoads::GrdLoads(int nel,SealevelGeometry* slgeom){ /*{{{*/
+ 
+ 	/*allocate:*/
++	nactiveloads=0;
++
+ 	vloads=new Vector<IssmDouble>(nel);
+-	for (int i=0;i<SLGEOM_NUMLOADS;i++) vsubloads[i]=new Vector<IssmDouble>(slgeom->nbar[i]);
++	for (int i=0;i<SLGEOM_NUMLOADS;i++) {
++		vsubloads[i]=new Vector<IssmDouble>(slgeom->nbar[i]);
++		combined_subloads[i]=xNewZeroInit<IssmDouble>(slgeom->nbar[i]);
++	}
+ 
+ 	vsealevelloads=new Vector<IssmDouble>(nel);
+ 	vsealevelloads->Set(0);vsealevelloads->Assemble();
+@@ -27,6 +32,14 @@
+ 
+ 	vsubsealevelloads=new Vector<IssmDouble>(slgeom->nbar[SLGEOM_OCEAN]);
+ 
++	combined_loads=NULL;
++	combined_loads_index=NULL;
++	for (int i=0;i<SLGEOM_NUMLOADS;i++) {
++		nactivesubloads[i]=0;
++		combined_subloads[i]=NULL;
++		combined_subloads_index[i]=NULL;
++	}
++
+ 	/*make sure all pointers that are not allocated are NULL:*/
+ 	loads=NULL;
+ 	for (int i=0;i<SLGEOM_NUMLOADS;i++)subloads[i]=NULL;
+@@ -39,14 +52,20 @@
+ 
+ 	delete vloads;
+ 	xDelete<IssmDouble>(loads);
++	delete vsealevelloads;
++	xDelete<IssmDouble>(sealevelloads);
++	delete vsubsealevelloads;
++	xDelete<IssmDouble>(subsealevelloads);
++	if (combined_loads) xDelete<IssmDouble>(combined_loads);
++	if (combined_loads_index) xDelete<int>(combined_loads_index);
+ 	for(int i=0;i<SLGEOM_NUMLOADS;i++){
+ 		delete vsubloads[i];
+ 		xDelete<IssmDouble>(subloads[i]);
++		if (combined_subloads[i]) xDelete<IssmDouble>(combined_subloads[i]);
++		if (combined_subloads_index[i]) xDelete<int>(combined_subloads_index[i]);
+ 	}
+-	delete vsealevelloads;
+-	xDelete<IssmDouble>(sealevelloads);
+-	delete vsubsealevelloads;
+-	xDelete<IssmDouble>(subsealevelloads);
++
++
+ }; /*}}}*/
+ 
+ void GrdLoads::BroadcastLoads(void){ /*{{{*/
+@@ -138,4 +157,106 @@
+ 	ISSM_MPI_Reduce (&deg2coeff_local[2],&deg2coeff[2],1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
+ 	ISSM_MPI_Bcast(&deg2coeff[2],1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
+ 
+-} /*}}}*/ 
++}; /*}}}*/ 
++void GrdLoads::Combineloads(int nel,SealevelGeometry* slgeom){ /*{{{*/
++
++	int e,l, nbar, ae;
++	//Determine loads /*{{{*/
++	nactiveloads=0;
++
++	if (combined_loads) xDelete<IssmDouble>(combined_loads);
++	if (combined_loads_index) xDelete<int>(combined_loads_index);
++
++	//find non zero centroid loads, combine with sealevelloads
++	if(sealevelloads){
++		for (e=0;e<nel;e++){
++			if (loads[e]+sealevelloads[e]!=0) nactiveloads++;
++		}
++	}
++	else { 
++		for (e=0;e<nel;e++){
++			if (loads[e]!=0) nactiveloads++;
++		}
++	}
++
++	combined_loads=xNewZeroInit<IssmDouble>(nactiveloads);
++	combined_loads_index=xNewZeroInit<int>(nactiveloads);
++
++	ae=0;
++	if(sealevelloads){
++		for (e=0;e<nel;e++){
++			if (loads[e]+sealevelloads[e]!=0){
++				combined_loads[ae]=loads[e]+sealevelloads[e];
++				combined_loads_index[ae]=e;
++				ae++;
++			}
++		}
++	}
++	else { 
++		for (e=0;e<nel;e++){
++			if (loads[e]!=0){
++				combined_loads[ae]=loads[e];
++				combined_loads_index[ae]=e;
++				ae++;			
++			}
++		}
++	}
++
++
++	//subloads
++	for(l=0;l<SLGEOM_NUMLOADS;l++){
++		nactivesubloads[l]=0;
++		nbar=slgeom->nbar[l];
++		if (combined_subloads[l]) xDelete<IssmDouble>(combined_subloads[l]);
++		if (combined_subloads_index[l]) xDelete<int>(combined_subloads_index[l]);
++
++		//find non zero subelement loads, combine with subsealevelloads
++		if(subsealevelloads && l==SLGEOM_OCEAN){
++			for (e=0;e<nbar;e++){
++				if (subloads[l][e]+subsealevelloads[e]!=0) nactivesubloads[l]++;
++			}
++		}
++		else { 
++			for (e=0;e<nbar;e++){
++				if (subloads[l][e]!=0) nactivesubloads[l]++;;
++			}
++		}
++
++		combined_subloads[l]=xNewZeroInit<IssmDouble>(nactivesubloads[l]);
++		combined_subloads_index[l]=xNewZeroInit<int>(nactivesubloads[l]);
++
++		ae=0;
++		if(subsealevelloads && l==SLGEOM_OCEAN){
++			for (e=0;e<nbar;e++){
++				if (subloads[l][e]+sealevelloads[e]!=0){
++					combined_subloads[l][ae]=subloads[l][e]+sealevelloads[e];
++					combined_subloads_index[l][ae]=e;
++					ae++;
++				}
++			}
++		}
++		else { 
++			for (e=0;e<nbar;e++){
++				if (subloads[l][e]!=0){
++					combined_subloads[l][ae]=subloads[l][e];
++					combined_subloads_index[l][ae]=e;
++					ae++;			
++				}
++			}
++		}
++
++
++		/*for(l=0;l<SLGEOM_NUMLOADS;l++){
++			nbar=slgeom->nbar[l];
++			for (e=0;e<nbar;e++){
++				combined_subloads[l][e]=(subloads[l][e]);
++			}
++		}
++		if(sealevelloads){
++			nbar=slgeom->nbar[SLGEOM_OCEAN];
++			for (e=0;e<nbar;e++){
++				combined_subloads[SLGEOM_OCEAN][e]+=(subsealevelloads[e]);
++			}
++		}*/
++	}
++}; /*}}}*/
+Index: ../trunk-jpl/src/c/classes/GrdLoads.h
+===================================================================
+--- ../trunk-jpl/src/c/classes/GrdLoads.h	(revision 27307)
++++ ../trunk-jpl/src/c/classes/GrdLoads.h	(revision 27308)
+@@ -13,6 +13,8 @@
+ 
+ 	public: 
+ 
++		int nactiveloads=0;
++		int nactivesubloads[SLGEOM_NUMLOADS];
+ 		Vector<IssmDouble>* vloads=NULL;
+ 		IssmDouble*         loads=NULL;
+ 		Vector<IssmDouble>* vsubloads[SLGEOM_NUMLOADS];
+@@ -21,6 +23,10 @@
+ 		IssmDouble*         sealevelloads=NULL;
+ 		Vector<IssmDouble>* vsubsealevelloads=NULL;
+ 		IssmDouble*         subsealevelloads=NULL;
++		int*         	    combined_loads_index=NULL;
++		int*         	    combined_subloads_index[SLGEOM_NUMLOADS];
++		IssmDouble*         combined_loads=NULL;
++		IssmDouble*         combined_subloads[SLGEOM_NUMLOADS];
+ 
+ 		GrdLoads(int nel, SealevelGeometry* slgeom);
+ 		~GrdLoads();
+@@ -29,5 +35,6 @@
+ 		void BroadcastLoads(void);
+ 		void BroadcastSealevelLoads(void);
+ 		void SHDegree2Coefficients(IssmDouble* deg2coeff, FemModel* femmodel, SealevelGeometry* slgeom);
++		void Combineloads(int nel, SealevelGeometry* slgeom);
+ };
+ #endif  /* _SEALEVELGRDLOADS_H_ */
+Index: ../trunk-jpl/src/c/classes/Inputs/ArrayInput.cpp
+===================================================================
+--- ../trunk-jpl/src/c/classes/Inputs/ArrayInput.cpp	(revision 27307)
++++ ../trunk-jpl/src/c/classes/Inputs/ArrayInput.cpp	(revision 27308)
+@@ -43,10 +43,8 @@
+ 
+ 	ArrayInput* output = new ArrayInput(this->numberofelements_local);
+ 
+-	output->N = xNew<int>(this->numberofelements_local);
+ 	xMemCpy<int>(output->N,this->N,this->numberofelements_local);
+ 
+-	output->values = xNew<IssmDouble*>(this->numberofelements_local);
+ 	for(int i=0;i<this->numberofelements_local;i++){
+ 		if(this->values[i]){
+ 			_assert_(this->N[i]>0);
+Index: ../trunk-jpl/src/c/classes/Inputs/IntArrayInput.cpp
+===================================================================
+--- ../trunk-jpl/src/c/classes/Inputs/IntArrayInput.cpp	(revision 27307)
++++ ../trunk-jpl/src/c/classes/Inputs/IntArrayInput.cpp	(revision 27308)
+@@ -43,10 +43,8 @@
+ 
+ 	IntArrayInput* output = new IntArrayInput(this->numberofelements_local);
+ 
+-	output->N = xNew<int>(this->numberofelements_local);
+ 	xMemCpy<int>(output->N,this->N,this->numberofelements_local);
+ 
+-	output->values = xNew<int*>(this->numberofelements_local);
+ 	for(int i=0;i<this->numberofelements_local;i++){
+ 		if(this->values[i]){
+ 			_assert_(this->N[i]>0);
+Index: ../trunk-jpl/src/c/cores/sealevelchange_core.cpp
+===================================================================
+--- ../trunk-jpl/src/c/cores/sealevelchange_core.cpp	(revision 27307)
++++ ../trunk-jpl/src/c/cores/sealevelchange_core.cpp	(revision 27308)
+@@ -21,7 +21,7 @@
+ /*support routines local definitions:{{{*/
+ void TransferForcing(FemModel* femmodel,int forcingenum);
+ void TransferSealevel(FemModel* femmodel,int forcingenum);
+-bool slcconvergence(Vector<IssmDouble>* RSLg,Vector<IssmDouble>* RSLg_old,IssmDouble eps_rel,IssmDouble eps_abs);
++bool slcconvergence(IssmDouble* RSLg,IssmDouble* RSLg_old,IssmDouble eps_rel,IssmDouble eps_abs, IssmDouble totaloceanarea,FemModel* femmodel);
+ IssmDouble  SealevelloadsOceanAverage(GrdLoads* loads, Vector<IssmDouble>* oceanareas, Vector<IssmDouble>* subelementoceanareas, IssmDouble totaloceanarea);
+ void PolarMotion(IssmDouble* m, FemModel* femmodel,GrdLoads* loads, SealevelGeometry* slgeom, bool computefuture);
+ void SealevelchangeUpdateViscousTimeSeries(FemModel* femmodel);
+@@ -51,6 +51,9 @@
+ 	/*set SLR configuration: */
+ 	femmodel->SetCurrentConfiguration(SealevelchangeAnalysisEnum);
+ 
++	/*Run coupler input transfer:*/
++	couplerinput_core(femmodel);
++
+ 	/*run geometry core: */
+ 	slgeom=sealevelchange_geometry(femmodel);
+ 
+@@ -57,9 +60,6 @@
+ 	/*any external forcings?:*/
+ 	solidearthexternal_core(femmodel);
+ 
+-	/*Run coupler input transfer:*/
+-	couplerinput_core(femmodel);
+-
+ 	/*Run geodetic:*/
+ 	grd_core(femmodel,slgeom);
+ 
+@@ -183,11 +183,14 @@
+ 
+ 	/*if we are carrying loads but are not yet computing grd core, accumulate them and skip 
+ 	 * the rest: */
+-	if (count<frequency){
+-		count++; 
+-		femmodel->parameters->SetParam(count,SealevelchangeRunCountEnum); 
++	if (count!=frequency){
++		if (count>frequency){
++			count=1;
++			femmodel->parameters->SetParam(count,SealevelchangeRunCountEnum); 
++		}
+ 		return;
+ 	}
++	
+ 
+ 	/*Basins are supposed to accumulate loads and hand them over to the Earth
+ 	  for slr computations every "frequency" time steps. If we are here, we
+@@ -207,6 +210,8 @@
+ 		TransferForcing(femmodel,DeltaIceThicknessEnum);
+ 		TransferForcing(femmodel,DeltaBottomPressureEnum);
+ 		TransferForcing(femmodel,DeltaTwsEnum);
++		TransferForcing(femmodel,MaskOceanLevelsetEnum);
++		TransferForcing(femmodel,MaskIceLevelsetEnum);
+ 
+ 		/*transfer external forcings back to Earth:*/
+ 		TransferSealevel(femmodel,BedEnum);
+@@ -227,7 +232,7 @@
+ 	IssmDouble polarmotionvector[3]={0};
+ 
+ 	GrdLoads*              loads=NULL;
+-	Vector<IssmDouble>*    oldsealevelloads=NULL;
++	IssmDouble*    oldsealevelloads=NULL;
+ 	Vector<IssmDouble>*    oceanareas=NULL;
+ 	IssmDouble             totaloceanarea;
+ 	Vector<IssmDouble>*    subelementoceanareas=NULL;
+@@ -248,6 +253,7 @@
+ 	int  grd=0;
+ 	int  grdmodel; 
+ 	int  sealevelloading=0;
++	bool sal=false;
+ 	bool viscous=false;
+ 	bool rotation=false;
+ 	bool planethasocean=false;
+@@ -256,9 +262,6 @@
+ 
+ 	/*}}}*/
+ 
+-	/*Verbose: */
+-	if(VerboseSolution()) _printf0_("	  computing GRD patterns\n");
+-
+ 	/*retrieve parameters:{{{*/
+ 	femmodel->parameters->FindParam(&grd,SolidearthSettingsGRDEnum); 
+ 	femmodel->parameters->FindParam(&grdmodel,GrdModelEnum);
+@@ -289,6 +292,10 @@
+ 		return;
+ 	}
+ 
++	/*Verbose: */
++	if(VerboseSolution()) _printf0_("	  computing GRD patterns\n");
++
++
+ 	/*retrieve parameters: {{{*/ 
+ 	femmodel->parameters->FindParam(&scaleoceanarea,SolidearthSettingsOceanAreaScalingEnum);
+ 	barycontribparam = xDynamicCast<GenericParam<BarystaticContributions*>*>(femmodel->parameters->FindParamObject(BarystaticContributionsEnum));
+@@ -297,6 +304,7 @@
+ 	femmodel->parameters->FindParam(&eps_rel,SolidearthSettingsReltolEnum);
+ 	femmodel->parameters->FindParam(&eps_abs,SolidearthSettingsAbstolEnum);
+ 	femmodel->parameters->FindParam(&horiz,SolidearthSettingsHorizEnum);
++	femmodel->parameters->FindParam(&sal,SolidearthSettingsSelfAttractionEnum);
+ 	/*}}}*/
+ 
+ 	/*initialize loads and sea level loads:*/
+@@ -335,9 +343,14 @@
+ 		//compute polar motion:
+ 		PolarMotion(&polarmotionvector[0],femmodel,loads,slgeom,computefuture=false);
+ 
+-		oldsealevelloads=loads->vsealevelloads->Duplicate(); loads->vsealevelloads->Copy(oldsealevelloads);
++		oldsealevelloads=xNewZeroInit<IssmDouble>(nel);
++		if (loads->sealevelloads){
++			xMemCpy<IssmDouble>(oldsealevelloads,loads->sealevelloads,nel);
++		}
+ 
++
+ 		/*convolve load and sealevel loads on oceans:*/
++		loads->Combineloads(nel,slgeom); //This combines loads and sealevelloads into a single vector 
+ 		for(Object* & object : femmodel->elements->objects){
+ 			Element* element = xDynamicCast<Element*>(object);
+ 			element->SealevelchangeConvolution(sealevelpercpu, loads, polarmotionvector,slgeom);
+@@ -366,17 +379,19 @@
+ 		//broadcast sea level loads 
+ 		loads->BroadcastSealevelLoads();
+ 
++		if (!sal) xDelete<IssmDouble>(oldsealevelloads); break;
++
+ 		//convergence?
+-		if(slcconvergence(loads->vsealevelloads,oldsealevelloads,eps_rel,eps_abs)){
+-			delete oldsealevelloads; break;
++		if(slcconvergence(loads->sealevelloads,oldsealevelloads,eps_rel,eps_abs,totaloceanarea,femmodel)){
++			xDelete<IssmDouble>(oldsealevelloads); break;
+ 		}
+ 
+ 		//early return?
+ 		if(iterations>=max_nonlinear_iterations){
+-			delete oldsealevelloads; break;
++			xDelete<IssmDouble>(oldsealevelloads); break;
+ 		}
+ 		iterations++;
+-		delete oldsealevelloads;
++		xDelete<IssmDouble>(oldsealevelloads);
+ 	}
+ 
+ 	//recompute polar motion one final time, this time updating viscous stacks for future time steps
+@@ -387,6 +402,7 @@
+ 	if(VerboseSolution()) _printf0_("	  deformation GRD convolutions\n");
+ 
+ 	/*convolve loads and sea level loads to get the deformation:*/
++	loads->Combineloads(nel,slgeom); //This combines loads and sealevelloads into a single vector 
+ 	for(Object* & object : femmodel->elements->objects){
+ 		Element* element = xDynamicCast<Element*>(object);
+ 		element->SealevelchangeDeformationConvolution(sealevelpercpu, loads, polarmotionvector,slgeom);
+@@ -511,11 +527,17 @@
+ 	/*parameters:*/
+ 	int iscoupling;
+ 	int horiz=0;
++	int count, frequency;
+ 
+ 	/*retrieve more parameters:*/
+ 	femmodel->parameters->FindParam(&iscoupling,IsSlcCouplingEnum);
+ 	femmodel->parameters->FindParam(&horiz,SolidearthSettingsHorizEnum);
++	femmodel->parameters->FindParam(&count,SealevelchangeRunCountEnum);
++	femmodel->parameters->FindParam(&frequency,SolidearthSettingsRunFrequencyEnum);
+ 
++	count++;
++	femmodel->parameters->SetParam(count,SealevelchangeRunCountEnum); 
++	
+ 	if(iscoupling){
+ 		/*transfer sea level back to ice caps:*/
+ 		TransferSealevel(femmodel,SealevelEnum);
+@@ -525,6 +547,7 @@
+ 			TransferSealevel(femmodel,BedEastEnum);
+ 		}
+ 	}
++
+ }; /*}}}*/
+ void              ivins_deformation_core(FemModel* femmodel){ /*{{{*/
+ 
+@@ -587,7 +610,8 @@
+ 	IssmDouble *zze    = NULL;
+ 	IssmDouble* areae  = NULL;
+ 	int  nel;
+-	int* lids;
++	int* lids=NULL;
++	int* n_activevertices=NULL;
+ 	int  grdmodel=0;
+ 
+ 	/*retrieve parameters:*/
+@@ -595,7 +619,7 @@
+ 	nel=femmodel->elements->NumberOfElements();
+ 
+ 	/*early return?:*/
+-	if(grdmodel==IvinsEnum) return;
++	if(grdmodel!=ElasticEnum) return;
+ 
+ 	/*Verbose: */
+ 	if(VerboseSolution()) _printf0_("	  computing initial sea level geometrical kernels and weights.\n");
+@@ -606,10 +630,19 @@
+ 
+ 	/*Compute element ids, used to speed up computations in convolution phase:{{{*/
+ 	lids=xNew<int>(femmodel->vertices->Size());
++	n_activevertices = xNew<int>(nel);
++	//initialize lids to -1, vertex count to 3
++	for (int v=0; v<femmodel->vertices->Size();v++) lids[v]=-1;
++	for (int e=0; e<nel;e++) n_activevertices[e]=3;
+ 
+ 	for(Object* & object : femmodel->elements->objects){
+ 		Element*   element=xDynamicCast<Element*>(object);
+ 		for(int i=0;i<3;i++){
++			// if lids where we are looking points to an element id (.i.e. not -1) then we are about to claim that element's vertex
++			// and need to lower the number of vertices it is in charge of
++			if (lids[element->vertices[i]->lid] !=-1){
++				n_activevertices[lids[element->vertices[i]->lid]]-=1;
++			}
+ 			lids[element->vertices[i]->lid]=element->lid;
+ 		}
+ 	}
+@@ -619,7 +652,7 @@
+ 	/*Run sealevel geometry routine in elements:*/
+ 	for(Object* & object : femmodel->elements->objects){
+ 		Element*   element=xDynamicCast<Element*>(object);
+-		element->SealevelchangeGeometryInitial(xxe,yye,zze,areae,lids);
++		element->SealevelchangeGeometryInitial(xxe,yye,zze,areae,lids,n_activevertices);
+ 	}
+ 
+ 	femmodel->parameters->AddObject(new DoubleVecParam(XxeEnum,xxe,nel));
+@@ -638,7 +671,8 @@
+ 	xDelete<IssmDouble>(yye);
+ 	xDelete<IssmDouble>(zze);
+ 	xDelete<IssmDouble>(areae);
+-	xDelete(lids);
++	xDelete<int>(lids);
++	xDelete<int>(n_activevertices);
+ 
+ 	return;
+ 
+@@ -657,12 +691,16 @@
+ 	int nel;
+ 	int  grdmodel=0;
+ 	int isgrd=0;
++	int count, frequency;
+ 	SealevelGeometry* slgeom=NULL;
+ 
+ 	/*early return?:*/
+ 	femmodel->parameters->FindParam(&grdmodel,GrdModelEnum);
+ 	femmodel->parameters->FindParam(&isgrd,SolidearthSettingsGRDEnum);
++	femmodel->parameters->FindParam(&count,SealevelchangeRunCountEnum);
++	femmodel->parameters->FindParam(&frequency,SolidearthSettingsRunFrequencyEnum);
+ 	if(grdmodel!=ElasticEnum || !isgrd) return NULL;
++	if(count!=frequency)return NULL;
+ 
+ 	/*retrieve parameters:*/
+ 	femmodel->parameters->FindParam(&xxe,&nel,XxeEnum);
+@@ -721,12 +759,16 @@
+ 	int  grdmodel=0;
+ 	int isgrd=0;
+ 	int horiz=0;
++	int count, frequency;
+ 
+ 	/*early return?:*/
+ 	femmodel->parameters->FindParam(&grdmodel,GrdModelEnum);
+ 	femmodel->parameters->FindParam(&isgrd,SolidearthSettingsGRDEnum);
+ 	femmodel->parameters->FindParam(&horiz,SolidearthSettingsHorizEnum);
++	femmodel->parameters->FindParam(&count,SealevelchangeRunCountEnum);
++	femmodel->parameters->FindParam(&frequency,SolidearthSettingsRunFrequencyEnum);
+ 	if(grdmodel!=ElasticEnum || !isgrd) return;
++	if(count!=frequency)return;
+ 
+ 	for (int l=0;l<SLGEOM_NUMLOADS;l++){
+ 		femmodel->inputs->DeleteInput(slgeom->AlphaIndexEnum(l));
+@@ -737,27 +779,42 @@
+ } /*}}}*/
+ 
+ /*subroutines:*/
+-bool slcconvergence(Vector<IssmDouble>* RSLg,Vector<IssmDouble>* RSLg_old,IssmDouble eps_rel,IssmDouble eps_abs){ /*{{{*/
++bool slcconvergence(IssmDouble* RSLg,IssmDouble* RSLg_old,IssmDouble eps_rel,IssmDouble eps_abs, IssmDouble totaloceanarea, FemModel* femmodel){ /*{{{*/
+ 
++	int nel;
+ 	bool converged=true;
+-	IssmDouble ndS,nS; 
+-	Vector<IssmDouble> *dRSLg    = NULL;
++	IssmDouble ndS,nS, nS_old; 
++	IssmDouble* dRSLg    = NULL;
++	IssmDouble rho_water =0;
+ 
++	femmodel->parameters->FindParam(&nel,MeshNumberofelementsEnum);
++	femmodel->parameters->FindParam(&rho_water,MaterialsRhoSeawaterEnum);
++
+ 	//compute norm(du) and norm(u) if requested
+-	dRSLg=RSLg_old->Duplicate(); RSLg_old->Copy(dRSLg); dRSLg->AYPX(RSLg,-1.0);
+-	ndS=dRSLg->Norm(NORM_TWO); 
++	dRSLg=xNewZeroInit<IssmDouble>(nel);
+ 
++	ndS=0;
++	nS=0;
++	nS_old=0;
++
++	for (int e=0;e<nel;e++){
++		dRSLg[e]=(RSLg[e]-RSLg_old[e])/rho_water/totaloceanarea;
++		ndS+=pow(dRSLg[e],2.0);
++		nS+=pow(RSLg[e]/rho_water/totaloceanarea,2.0);
++		nS_old+=pow(RSLg_old[e]/rho_water/totaloceanarea,2.0);
++	}
++	
++
+ 	if (xIsNan<IssmDouble>(ndS)){
+-		_error_("convergence criterion is NaN (RSL_old=" << RSLg_old->Norm(NORM_TWO) << " RSL=" << RSLg->Norm(NORM_TWO) << ")");
++		_error_("convergence criterion is NaN (RSL_old=" << nS_old << " RSL=" << nS << ")");
+ 	}
+ 
+ 	if(!xIsNan<IssmDouble>(eps_rel)){
+-		nS=RSLg_old->Norm(NORM_TWO);
+-		if (xIsNan<IssmDouble>(nS)) _error_("convergence criterion is NaN! (check the initial RSL)");
++		if (xIsNan<IssmDouble>(nS_old)) _error_("convergence criterion is NaN! (check the initial RSL)");
+ 	}
+ 
+ 	//clean up
+-	delete dRSLg;
++	xDelete<IssmDouble>(dRSLg);
+ 
+ 	//print
+ 	if(!xIsNan<IssmDouble>(eps_rel)){
+@@ -1047,6 +1104,7 @@
+ 	IssmDouble** forcings=NULL;
+ 	IssmDouble*  forcing=NULL; 
+ 	Vector<IssmDouble>* forcingglobal=NULL; 
++	IssmDouble* transfercount=NULL; 
+ 	int*         nvs=NULL;
+ 
+ 	/*transition vectors:*/
+@@ -1087,7 +1145,11 @@
+ 	if(modelid!=earthid){
+ 		nv=femmodel->vertices->NumberOfVertices();
+ 		existforcing=reCast<int>(femmodel->inputs->Exist(forcingenum));
+-		if(existforcing)GetVectorFromInputsx(&forcing,femmodel,forcingenum,VertexSIdEnum);
++		if(existforcing){
++			GetVectorFromInputsx(&forcing,femmodel,forcingenum,VertexSIdEnum);
++			GetVectorFromInputsx(&transfercount,femmodel,CouplingTransferCountEnum,VertexSIdEnum);
++			for (int i=0;i<nv;i++) forcing[i]/=transfercount[i]; //Divide forcing at this vertex by the number of icecaps that share it. This way we average the forcing when adding it into the earth model.
++		}
+ 	}
+ 
+ 	/*Send the forcing to the earth model:{{{*/
+@@ -1126,6 +1188,8 @@
+ 		nv=femmodel->vertices->NumberOfVertices();
+ 		GetVectorFromInputsx(&forcingglobal,femmodel,forcingenum,VertexSIdEnum);
+ 
++		forcingglobal->Set(0.0);
++
+ 		/*Retrieve transition vectors, used to plug from each ice cap into the global forcing:*/
+ 		femmodel->parameters->FindParam(&transitions,&ntransitions,&transitions_m,&transitions_n,SealevelchangeTransitionsEnum);
+ 
+@@ -1145,6 +1209,7 @@
+ 
+ 					/*We are going to plug this vector into the earth model, at the right vertices corresponding to this particular 
+ 					 * ice cap: */
++
+ 					forcingglobal->SetValues(M,index,forcingfromcap,ADD_VAL);
+ 					xDelete<int>(index);
+ 				}
+Index: ../trunk-jpl/src/c/shared/Enum/EnumDefinitions.h
+===================================================================
+--- ../trunk-jpl/src/c/shared/Enum/EnumDefinitions.h	(revision 27307)
++++ ../trunk-jpl/src/c/shared/Enum/EnumDefinitions.h	(revision 27308)
+@@ -311,6 +311,7 @@
+ 	LoveIntStepsPerLayerEnum,
+ 	LoveMinIntegrationStepsEnum,
+ 	LoveMaxIntegrationdrEnum,
++	LoveIntegrationSchemeEnum,
+ 	LoveKernelsEnum,
+ 	LoveMu0Enum,
+ 	LoveNfreqEnum,
+@@ -934,6 +935,7 @@
+ 	SealevelUEastEsaEnum,
+ 	SealevelUNorthEsaEnum,
+ 	SealevelchangeIndicesEnum,
++	SealevelchangeConvolutionVerticesEnum,
+ 	SealevelchangeAlphaIndexEnum,
+ 	SealevelchangeAzimuthIndexEnum,
+ 	SealevelchangeGrotEnum,
+@@ -952,6 +954,7 @@
+ 	SealevelchangeViscousUEnum,
+ 	SealevelchangeViscousNEnum,
+ 	SealevelchangeViscousEEnum,
++	CouplingTransferCountEnum,
+ 	SedimentHeadEnum,
+ 	SedimentHeadOldEnum,
+ 	SedimentHeadSubstepEnum,
+Index: ../trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp
+===================================================================
+--- ../trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp	(revision 27307)
++++ ../trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp	(revision 27308)
+@@ -319,6 +319,7 @@
+ 		case LoveIntStepsPerLayerEnum : return "LoveIntStepsPerLayer";
+ 		case LoveMinIntegrationStepsEnum : return "LoveMinIntegrationSteps";
+ 		case LoveMaxIntegrationdrEnum : return "LoveMaxIntegrationdr";
++		case LoveIntegrationSchemeEnum : return "LoveIntegrationScheme";
+ 		case LoveKernelsEnum : return "LoveKernels";
+ 		case LoveMu0Enum : return "LoveMu0";
+ 		case LoveNfreqEnum : return "LoveNfreq";
+@@ -940,6 +941,7 @@
+ 		case SealevelUEastEsaEnum : return "SealevelUEastEsa";
+ 		case SealevelUNorthEsaEnum : return "SealevelUNorthEsa";
+ 		case SealevelchangeIndicesEnum : return "SealevelchangeIndices";
++		case SealevelchangeConvolutionVerticesEnum : return "SealevelchangeConvolutionVertices";
+ 		case SealevelchangeAlphaIndexEnum : return "SealevelchangeAlphaIndex";
+ 		case SealevelchangeAzimuthIndexEnum : return "SealevelchangeAzimuthIndex";
+ 		case SealevelchangeGrotEnum : return "SealevelchangeGrot";
+@@ -958,6 +960,7 @@
+ 		case SealevelchangeViscousUEnum : return "SealevelchangeViscousU";
+ 		case SealevelchangeViscousNEnum : return "SealevelchangeViscousN";
+ 		case SealevelchangeViscousEEnum : return "SealevelchangeViscousE";
++		case CouplingTransferCountEnum : return "CouplingTransferCount";
+ 		case SedimentHeadEnum : return "SedimentHead";
+ 		case SedimentHeadOldEnum : return "SedimentHeadOld";
+ 		case SedimentHeadSubstepEnum : return "SedimentHeadSubstep";
+Index: ../trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp
+===================================================================
+--- ../trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp	(revision 27307)
++++ ../trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp	(revision 27308)
+@@ -325,6 +325,7 @@
+ 	      else if (strcmp(name,"LoveIntStepsPerLayer")==0) return LoveIntStepsPerLayerEnum;
+ 	      else if (strcmp(name,"LoveMinIntegrationSteps")==0) return LoveMinIntegrationStepsEnum;
+ 	      else if (strcmp(name,"LoveMaxIntegrationdr")==0) return LoveMaxIntegrationdrEnum;
++	      else if (strcmp(name,"LoveIntegrationScheme")==0) return LoveIntegrationSchemeEnum;
+ 	      else if (strcmp(name,"LoveKernels")==0) return LoveKernelsEnum;
+ 	      else if (strcmp(name,"LoveMu0")==0) return LoveMu0Enum;
+ 	      else if (strcmp(name,"LoveNfreq")==0) return LoveNfreqEnum;
+@@ -381,11 +382,11 @@
+ 	      else if (strcmp(name,"OutputBufferPointer")==0) return OutputBufferPointerEnum;
+ 	      else if (strcmp(name,"OutputBufferSizePointer")==0) return OutputBufferSizePointerEnum;
+ 	      else if (strcmp(name,"OutputFileName")==0) return OutputFileNameEnum;
+-	      else if (strcmp(name,"OutputFilePointer")==0) return OutputFilePointerEnum;
+          else stage=4;
+    }
+    if(stage==4){
+-	      if (strcmp(name,"Outputdefinition")==0) return OutputdefinitionEnum;
++	      if (strcmp(name,"OutputFilePointer")==0) return OutputFilePointerEnum;
++	      else if (strcmp(name,"Outputdefinition")==0) return OutputdefinitionEnum;
+ 	      else if (strcmp(name,"QmuErrName")==0) return QmuErrNameEnum;
+ 	      else if (strcmp(name,"QmuInName")==0) return QmuInNameEnum;
+ 	      else if (strcmp(name,"QmuIsdakota")==0) return QmuIsdakotaEnum;
+@@ -504,11 +505,11 @@
+ 	      else if (strcmp(name,"SmbAccuref")==0) return SmbAccurefEnum;
+ 	      else if (strcmp(name,"SmbAdThresh")==0) return SmbAdThreshEnum;
+ 	      else if (strcmp(name,"SmbARMAInitialTime")==0) return SmbARMAInitialTimeEnum;
+-	      else if (strcmp(name,"SmbARMATimestep")==0) return SmbARMATimestepEnum;
+          else stage=5;
+    }
+    if(stage==5){
+-	      if (strcmp(name,"SmbARMAarOrder")==0) return SmbARMAarOrderEnum;
++	      if (strcmp(name,"SmbARMATimestep")==0) return SmbARMATimestepEnum;
++	      else if (strcmp(name,"SmbARMAarOrder")==0) return SmbARMAarOrderEnum;
+ 	      else if (strcmp(name,"SmbARMAmaOrder")==0) return SmbARMAmaOrderEnum;
+ 	      else if (strcmp(name,"SmbAveraging")==0) return SmbAveragingEnum;
+ 	      else if (strcmp(name,"SmbARMAconst")==0) return SmbARMAconstEnum;
+@@ -627,11 +628,11 @@
+ 	      else if (strcmp(name,"TransientIsgia")==0) return TransientIsgiaEnum;
+ 	      else if (strcmp(name,"TransientIsgroundingline")==0) return TransientIsgroundinglineEnum;
+ 	      else if (strcmp(name,"TransientIshydrology")==0) return TransientIshydrologyEnum;
+-	      else if (strcmp(name,"TransientIsmasstransport")==0) return TransientIsmasstransportEnum;
+          else stage=6;
+    }
+    if(stage==6){
+-	      if (strcmp(name,"TransientIsoceantransport")==0) return TransientIsoceantransportEnum;
++	      if (strcmp(name,"TransientIsmasstransport")==0) return TransientIsmasstransportEnum;
++	      else if (strcmp(name,"TransientIsoceantransport")==0) return TransientIsoceantransportEnum;
+ 	      else if (strcmp(name,"TransientIsmovingfront")==0) return TransientIsmovingfrontEnum;
+ 	      else if (strcmp(name,"TransientIsoceancoupling")==0) return TransientIsoceancouplingEnum;
+ 	      else if (strcmp(name,"TransientIssampling")==0) return TransientIssamplingEnum;
+@@ -750,11 +751,11 @@
+ 	      else if (strcmp(name,"DeviatoricStresseffective")==0) return DeviatoricStresseffectiveEnum;
+ 	      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 stage=7;
+    }
+    if(stage==7){
+-	      if (strcmp(name,"DeviatoricStressyy")==0) return DeviatoricStressyyEnum;
++	      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,"DeviatoricStress1")==0) return DeviatoricStress1Enum;
+@@ -873,11 +874,11 @@
+ 	      else if (strcmp(name,"MaskIceRefLevelset")==0) return MaskIceRefLevelsetEnum;
+ 	      else if (strcmp(name,"MasstransportSpcthickness")==0) return MasstransportSpcthicknessEnum;
+ 	      else if (strcmp(name,"MaterialsRheologyB")==0) return MaterialsRheologyBEnum;
+-	      else if (strcmp(name,"MaterialsRheologyBbar")==0) return MaterialsRheologyBbarEnum;
+          else stage=8;
+    }
+    if(stage==8){
+-	      if (strcmp(name,"MaterialsRheologyE")==0) return MaterialsRheologyEEnum;
++	      if (strcmp(name,"MaterialsRheologyBbar")==0) return MaterialsRheologyBbarEnum;
++	      else if (strcmp(name,"MaterialsRheologyE")==0) return MaterialsRheologyEEnum;
+ 	      else if (strcmp(name,"MaterialsRheologyEbar")==0) return MaterialsRheologyEbarEnum;
+ 	      else if (strcmp(name,"MaterialsRheologyEc")==0) return MaterialsRheologyEcEnum;
+ 	      else if (strcmp(name,"MaterialsRheologyEcbar")==0) return MaterialsRheologyEcbarEnum;
+@@ -961,6 +962,7 @@
+ 	      else if (strcmp(name,"SealevelUEastEsa")==0) return SealevelUEastEsaEnum;
+ 	      else if (strcmp(name,"SealevelUNorthEsa")==0) return SealevelUNorthEsaEnum;
+ 	      else if (strcmp(name,"SealevelchangeIndices")==0) return SealevelchangeIndicesEnum;
++	      else if (strcmp(name,"SealevelchangeConvolutionVertices")==0) return SealevelchangeConvolutionVerticesEnum;
+ 	      else if (strcmp(name,"SealevelchangeAlphaIndex")==0) return SealevelchangeAlphaIndexEnum;
+ 	      else if (strcmp(name,"SealevelchangeAzimuthIndex")==0) return SealevelchangeAzimuthIndexEnum;
+ 	      else if (strcmp(name,"SealevelchangeGrot")==0) return SealevelchangeGrotEnum;
+@@ -979,6 +981,7 @@
+ 	      else if (strcmp(name,"SealevelchangeViscousU")==0) return SealevelchangeViscousUEnum;
+ 	      else if (strcmp(name,"SealevelchangeViscousN")==0) return SealevelchangeViscousNEnum;
+ 	      else if (strcmp(name,"SealevelchangeViscousE")==0) return SealevelchangeViscousEEnum;
++	      else if (strcmp(name,"CouplingTransferCount")==0) return CouplingTransferCountEnum;
+ 	      else if (strcmp(name,"SedimentHead")==0) return SedimentHeadEnum;
+ 	      else if (strcmp(name,"SedimentHeadOld")==0) return SedimentHeadOldEnum;
+ 	      else if (strcmp(name,"SedimentHeadSubstep")==0) return SedimentHeadSubstepEnum;
+@@ -994,13 +997,13 @@
+ 	      else if (strcmp(name,"SmbAccumulatedRain")==0) return SmbAccumulatedRainEnum;
+ 	      else if (strcmp(name,"SmbAccumulatedRefreeze")==0) return SmbAccumulatedRefreezeEnum;
+ 	      else if (strcmp(name,"SmbAccumulatedRunoff")==0) return SmbAccumulatedRunoffEnum;
+-	      else if (strcmp(name,"SmbA")==0) return SmbAEnum;
+-	      else if (strcmp(name,"SmbAdiff")==0) return SmbAdiffEnum;
+-	      else if (strcmp(name,"SmbAValue")==0) return SmbAValueEnum;
+          else stage=9;
+    }
+    if(stage==9){
+-	      if (strcmp(name,"SmbAccumulation")==0) return SmbAccumulationEnum;
++	      if (strcmp(name,"SmbA")==0) return SmbAEnum;
++	      else if (strcmp(name,"SmbAdiff")==0) return SmbAdiffEnum;
++	      else if (strcmp(name,"SmbAValue")==0) return SmbAValueEnum;
++	      else if (strcmp(name,"SmbAccumulation")==0) return SmbAccumulationEnum;
+ 	      else if (strcmp(name,"SmbAdiffini")==0) return SmbAdiffiniEnum;
+ 	      else if (strcmp(name,"SmbAini")==0) return SmbAiniEnum;
+ 	      else if (strcmp(name,"SmbARMANoise")==0) return SmbARMANoiseEnum;
+@@ -1117,13 +1120,13 @@
+ 	      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,"StressMaxPrincipal")==0) return StressMaxPrincipalEnum;
+-	      else if (strcmp(name,"StressTensorxx")==0) return StressTensorxxEnum;
+-	      else if (strcmp(name,"StressTensorxy")==0) return StressTensorxyEnum;
+          else stage=10;
+    }
+    if(stage==10){
+-	      if (strcmp(name,"StressTensorxz")==0) return StressTensorxzEnum;
++	      if (strcmp(name,"StressMaxPrincipal")==0) return StressMaxPrincipalEnum;
++	      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 if (strcmp(name,"StressTensoryy")==0) return StressTensoryyEnum;
+ 	      else if (strcmp(name,"StressTensoryz")==0) return StressTensoryzEnum;
+ 	      else if (strcmp(name,"StressTensorzz")==0) return StressTensorzzEnum;
+@@ -1240,13 +1243,13 @@
+ 	      else if (strcmp(name,"Outputdefinition50")==0) return Outputdefinition50Enum;
+ 	      else if (strcmp(name,"Outputdefinition51")==0) return Outputdefinition51Enum;
+ 	      else if (strcmp(name,"Outputdefinition52")==0) return Outputdefinition52Enum;
+-	      else if (strcmp(name,"Outputdefinition53")==0) return Outputdefinition53Enum;
+-	      else if (strcmp(name,"Outputdefinition54")==0) return Outputdefinition54Enum;
+-	      else if (strcmp(name,"Outputdefinition55")==0) return Outputdefinition55Enum;
+          else stage=11;
+    }
+    if(stage==11){
+-	      if (strcmp(name,"Outputdefinition56")==0) return Outputdefinition56Enum;
++	      if (strcmp(name,"Outputdefinition53")==0) return Outputdefinition53Enum;
++	      else if (strcmp(name,"Outputdefinition54")==0) return Outputdefinition54Enum;
++	      else if (strcmp(name,"Outputdefinition55")==0) return Outputdefinition55Enum;
++	      else if (strcmp(name,"Outputdefinition56")==0) return Outputdefinition56Enum;
+ 	      else if (strcmp(name,"Outputdefinition57")==0) return Outputdefinition57Enum;
+ 	      else if (strcmp(name,"Outputdefinition58")==0) return Outputdefinition58Enum;
+ 	      else if (strcmp(name,"Outputdefinition59")==0) return Outputdefinition59Enum;
+@@ -1363,13 +1366,13 @@
+ 	      else if (strcmp(name,"DataSet")==0) return DataSetEnum;
+ 	      else if (strcmp(name,"DataSetParam")==0) return DataSetParamEnum;
+ 	      else if (strcmp(name,"DatasetInput")==0) return DatasetInputEnum;
+-	      else if (strcmp(name,"DebrisAnalysis")==0) return DebrisAnalysisEnum;
+-	      else if (strcmp(name,"DebrisSolution")==0) return DebrisSolutionEnum;
+-	      else if (strcmp(name,"DefaultAnalysis")==0) return DefaultAnalysisEnum;
+          else stage=12;
+    }
+    if(stage==12){
+-	      if (strcmp(name,"DefaultCalving")==0) return DefaultCalvingEnum;
++	      if (strcmp(name,"DebrisAnalysis")==0) return DebrisAnalysisEnum;
++	      else if (strcmp(name,"DebrisSolution")==0) return DebrisSolutionEnum;
++	      else if (strcmp(name,"DefaultAnalysis")==0) return DefaultAnalysisEnum;
++	      else if (strcmp(name,"DefaultCalving")==0) return DefaultCalvingEnum;
+ 	      else if (strcmp(name,"Dense")==0) return DenseEnum;
+ 	      else if (strcmp(name,"DependentObject")==0) return DependentObjectEnum;
+ 	      else if (strcmp(name,"DepthAverageAnalysis")==0) return DepthAverageAnalysisEnum;
+@@ -1486,13 +1489,13 @@
+ 	      else if (strcmp(name,"LoveAnalysis")==0) return LoveAnalysisEnum;
+ 	      else if (strcmp(name,"LoveHf")==0) return LoveHfEnum;
+ 	      else if (strcmp(name,"LoveHt")==0) return LoveHtEnum;
+-	      else if (strcmp(name,"LoveKernelsImag")==0) return LoveKernelsImagEnum;
+-	      else if (strcmp(name,"LoveKernelsReal")==0) return LoveKernelsRealEnum;
+-	      else if (strcmp(name,"LoveKf")==0) return LoveKfEnum;
+          else stage=13;
+    }
+    if(stage==13){
+-	      if (strcmp(name,"LoveKt")==0) return LoveKtEnum;
++	      if (strcmp(name,"LoveKernelsImag")==0) return LoveKernelsImagEnum;
++	      else if (strcmp(name,"LoveKernelsReal")==0) return LoveKernelsRealEnum;
++	      else if (strcmp(name,"LoveKf")==0) return LoveKfEnum;
++	      else if (strcmp(name,"LoveKt")==0) return LoveKtEnum;
+ 	      else if (strcmp(name,"LoveLf")==0) return LoveLfEnum;
+ 	      else if (strcmp(name,"LoveLt")==0) return LoveLtEnum;
+ 	      else if (strcmp(name,"LoveTidalHt")==0) return LoveTidalHtEnum;
+@@ -1609,13 +1612,13 @@
+ 	      else if (strcmp(name,"SMBpddSicopolis")==0) return SMBpddSicopolisEnum;
+ 	      else if (strcmp(name,"SMBsemic")==0) return SMBsemicEnum;
+ 	      else if (strcmp(name,"SSAApproximation")==0) return SSAApproximationEnum;
+-	      else if (strcmp(name,"SSAFSApproximation")==0) return SSAFSApproximationEnum;
+-	      else if (strcmp(name,"SSAHOApproximation")==0) return SSAHOApproximationEnum;
+-	      else if (strcmp(name,"Scaled")==0) return ScaledEnum;
+          else stage=14;
+    }
+    if(stage==14){
+-	      if (strcmp(name,"SealevelAbsolute")==0) return SealevelAbsoluteEnum;
++	      if (strcmp(name,"SSAFSApproximation")==0) return SSAFSApproximationEnum;
++	      else if (strcmp(name,"SSAHOApproximation")==0) return SSAHOApproximationEnum;
++	      else if (strcmp(name,"Scaled")==0) return ScaledEnum;
++	      else if (strcmp(name,"SealevelAbsolute")==0) return SealevelAbsoluteEnum;
+ 	      else if (strcmp(name,"SealevelEmotion")==0) return SealevelEmotionEnum;
+ 	      else if (strcmp(name,"SealevelchangePolarMotionX")==0) return SealevelchangePolarMotionXEnum;
+ 	      else if (strcmp(name,"SealevelchangePolarMotionY")==0) return SealevelchangePolarMotionYEnum;
+Index: ../trunk-jpl/src/m/classes/love.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/love.m	(nonexistent)
++++ ../trunk-jpl/src/m/classes/love.m	(revision 27308)
+@@ -0,0 +1,237 @@
++%love class definition
++%
++%   Usage:
++%      md.love=love();
++
++classdef love
++	properties (SetAccess=public) 
++		nfreq						= 0;
++		frequencies					= 0;
++		sh_nmax						= 0;
++		sh_nmin						= 0;
++		g0							= 0;
++		r0							= 0;
++		mu0							= 0;
++		Gravitational_Constant		= 0;
++		chandler_wobble				= 0;
++		allow_layer_deletion		= 0;
++		underflow_tol				= 0;
++		pw_threshold				= 0;
++		min_integration_steps	= 0;
++		max_integration_dr	= 0;
++		integration_scheme	= 0;
++		istemporal					= 0;
++		n_temporal_iterations		= 0;
++		time						= 0;
++		love_kernels				= 0;
++		forcing_type				= 0;
++		inner_core_boundary			= 0;
++		core_mantle_boundary		= 0;
++		complex_computation			= 0;
++		quad_precision			= 0;
++		debug=0;
++		hypergeom_table1=0;
++		hypergeom_table2=0;
++		hypergeom_nalpha=0;
++		hypergeom_nz=0;
++		hypergeom_z=0;
++	end
++	methods (Static)
++		function self = loadobj(self) % {{{
++			% This function is directly called by matlab when a model object is
++			% loaded. Update old properties here
++		self.min_integration_steps	= self.int_steps_per_layers;
++		end% }}}
++	end
++	methods
++		function self = love(varargin) % {{{
++			switch nargin
++				case 0
++					self=setdefaultparameters(self);
++				otherwise
++					error('constructor not supported');
++			end
++		end % }}}
++		function self = setdefaultparameters(self) % {{{
++			%we setup an elastic love number computation by default.
++			self.nfreq=1; 
++			self.frequencies=[0]; %Hz
++			self.sh_nmax=256; % .35 degree, 40 km at the equator.
++			self.sh_nmin=1;
++			% work on matlab script for computing g0 for given Earth's structure. 
++			self.g0=9.81; % m/s^2; 
++			self.r0=6371*1e3; %m;
++			self.mu0=1e11; % Pa
++			self.Gravitational_Constant=6.67259e-11; % m^3 kg^-1 s^-2
++			self.chandler_wobble=0;
++			self.allow_layer_deletion=1;
++			self.underflow_tol=1e-16; %threshold of deep to surface love number ratio to trigger the deletion of layer 
++			self.pw_threshold=1e-3; %if relative variation across frequencies is smaller than this ratio, the post-widder transform for time-dependent love numbers is bypassed 
++			self.min_integration_steps	= 50;
++			self.max_integration_dr	= 10e3;
++			self.integration_scheme=1;
++			self.istemporal=0;
++			self.n_temporal_iterations=8;
++			self.time=[0]; %s
++			self.love_kernels=0; 
++			self.forcing_type = 11; % surface loading
++			self.inner_core_boundary=1;
++			self.core_mantle_boundary=2;
++			self.complex_computation=0;
++			self.quad_precision=0;
++			self.debug=0;
++			self.hypergeom_table1=1;
++			self.hypergeom_table2=1;
++			self.hypergeom_nalpha=1;
++			self.hypergeom_nz=1;
++			self.hypergeom_z=0;
++		end % }}}
++		function disp(self) % {{{
++			fielddisplay(self,'nfreq','number of frequencies sampled (default: 1, elastic) [Hz]');
++			fielddisplay(self,'frequencies','frequencies sampled (convention defaults to 0 for the elastic case) [Hz]');
++			fielddisplay(self,'sh_nmax','maximum spherical harmonic degree (default: 256, .35 deg, or 40 km at equator)');
++			fielddisplay(self,'sh_nmin','minimum spherical harmonic degree (default: 1)');
++			fielddisplay(self,'g0','adimensioning constant for gravity (default: 10) [m/s^2]');
++			fielddisplay(self,'r0','adimensioning constant for radius (default: 6371*10^3) [m]');
++			fielddisplay(self,'mu0','adimensioning constant for stress (default: 10^11) [Pa]');
++			fielddisplay(self,'Gravitational_Constant','Newtonian constant of gravitation (default: 6.67259e-11 [m^3 kg^-1 s^-2])');
++			fielddisplay(self,'chandler_wobble','includes the inertial terms for the chandler wobble in the rotational feedback love numbers, only for forcing_type=11 (default: 0) (/!\ 1 is untested yet)');
++			fielddisplay(self,'allow_layer_deletion','allow for migration of the integration boundary with increasing spherical harmonics degree (default: 1)');			
++			fielddisplay(self,'underflow_tol','threshold of deep to surface love number ratio to trigger the deletion of layers (default: 1e-16)');
++			fielddisplay(self,'pw_threshold','if relative variation across frequencies is smaller than this ratio, the post-widder transform for time-dependent love numbers is bypassed (default (1e-3)');
++			fielddisplay(self,'min_integration_steps','minimum number of radial steps to propagate the yi system from the bottom to the top of each layer (default: 50)');
++			fielddisplay(self,'max_integration_dr','maximum length of radial steps to propagate the yi system from the bottom to the top of each layer (default: 10e3) [m]');
++			fielddisplay(self,'integration_scheme','0: Euler, 1: Midpoint aka Runge-Kutta 2, 2: Runge-Kutta 4 (default: 1)');
++			fielddisplay(self,'istemporal',{'1 for time-dependent love numbers, 0 for frequency-dependent or elastic love numbers (default: 0)', 'If 1: use love class function build_frequencies_from_time to meet consistency'});
++			fielddisplay(self,'n_temporal_iterations','max number of iterations in the inverse Laplace transform. Also the number of spectral samples per time step requested (default: 8)');
++			fielddisplay(self,'time','time vector for deformation if istemporal (default: 0) [s]');
++			fielddisplay(self,'love_kernels','compute love numbers at depth? (default: 0)');
++			fielddisplay(self,'forcing_type',{'integer indicating the nature and depth of the forcing for the Love number calculation (default: 11):','1:  Inner core boundary -- Volumic Potential','2:  Inner core boundary -- Pressure','3:  Inner core boundary -- Loading','4:  Inner core boundary -- Tangential traction','5:  Core mantle boundary -- Volumic Potential','6:  Core mantle boundary -- Pressure','7:  Core mantle boundary -- Loading','8:  Core mantle boundary -- Tangential traction','9:  Surface -- Volumic Potential','10: Surface -- Pressure','11: Surface -- Loading','12: Surface -- Tangential traction '});
++			fielddisplay(self,'inner_core_boundary','interface index in materials.radius locating forcing. Only used for forcing_type 1--4 (default: 1)');
++			fielddisplay(self,'core_mantle_boundary','interface index in materials.radius locating forcing. Only used for forcing_type 5--8 (default: 2)'); 
++			fielddisplay(self,'complex_computation','return love numbers as 0: real (useful for elastic or temporal forms), 1: complex numbers (useful for Fourier spectral form) (default: 0)'); 
++			fielddisplay(self,'quad_precision','toogle computation love numbers and post-widder transform with 32 digit precision, useful for temporal form (default: 1)'); 
++			fielddisplay(self,'debug','outputs yi system matrix prior to solving (default: 0)'); 
++			fielddisplay(self,'hypergeom_table1','table 1 for hypergeometric function, only for EBM rheology (default: [1])'); 
++			fielddisplay(self,'hypergeom_table2','table 2 for hypergeometric function, only for EBM rheology (default: [1])'); 
++			fielddisplay(self,'hypergeom_nalpha','length of hypergeometric table, only for EBM rheology (default: 1)'); 
++			fielddisplay(self,'hypergeom_nz','width of hypergeometric table, only for EBM rheology (default: 1)'); 
++			fielddisplay(self,'hypergeom_z','abscissa for hypergeometric table, only for EBM rheology (default: [0])'); 
++
++		end % }}}
++		function md = checkconsistency(self,md,solution,analyses) % {{{
++
++			if ~ismember('LoveAnalysis',analyses), return; end
++
++			md = checkfield(md,'fieldname','love.nfreq','NaN',1,'Inf',1,'numel',1,'>',0);
++			md = checkfield(md,'fieldname','love.frequencies','NaN',1,'Inf',1,'numel',md.love.nfreq);
++			md = checkfield(md,'fieldname','love.sh_nmax','NaN',1,'Inf',1,'numel',1,'>',0);
++			md = checkfield(md,'fieldname','love.sh_nmin','NaN',1,'Inf',1,'numel',1,'>',0);
++			md = checkfield(md,'fieldname','love.g0','NaN',1,'Inf',1,'numel',1,'>',0);
++			md = checkfield(md,'fieldname','love.r0','NaN',1,'Inf',1,'numel',1,'>',0);
++			md = checkfield(md,'fieldname','love.mu0','NaN',1,'Inf',1,'numel',1,'>',0);
++			md = checkfield(md,'fieldname','love.Gravitational_Constant','NaN',1,'Inf',1,'numel',1,'>',0);
++			md = checkfield(md,'fieldname','love.chandler_wobble','values',[0 1]);
++			md = checkfield(md,'fieldname','love.allow_layer_deletion','values',[0 1]);
++			md = checkfield(md,'fieldname','love.underflow_tol','NaN',1,'Inf',1,'numel',1,'>',0);
++			md = checkfield(md,'fieldname','love.pw_threshold','NaN',1,'Inf',1,'numel',1,'>',0);
++			md = checkfield(md,'fieldname','love.min_integration_steps','NaN',1,'Inf',1,'numel',1,'>',0);
++			md = checkfield(md,'fieldname','love.max_integration_dr','NaN',1,'Inf',1,'numel',1,'>',0);
++			md = checkfield(md,'fieldname','love.integration_scheme','NaN',1,'Inf',1,'numel',1,'>=',0,'<=',2);
++			md = checkfield(md,'fieldname','love.love_kernels','values',[0 1]);
++			md = checkfield(md,'fieldname','love.forcing_type','NaN',1,'Inf',1,'numel',1,'>',0, '<=', 12);
++			md = checkfield(md,'fieldname','love.complex_computation','NaN',1,'Inf',1,'numel',1,'values',[0 1]);
++			md = checkfield(md,'fieldname','love.quad_precision','NaN',1,'Inf',1,'numel',1,'values',[0 1]);
++			md = checkfield(md,'fieldname','love.debug','NaN',1,'Inf',1,'numel',1,'values',[0 1]);
++
++			md = checkfield(md,'fieldname','love.istemporal','values',[0 1]);
++
++			md = checkfield(md,'fieldname','love.hypergeom_nalpha','NaN',1,'Inf',1,'numel',1,'>',0);
++			md = checkfield(md,'fieldname','love.hypergeom_nz','NaN',1,'Inf',1,'numel',1,'>',0);
++			md = checkfield(md,'fieldname','love.hypergeom_z','NaN',1,'Inf',1,'numel',md.love.hypergeom_nz);
++			md = checkfield(md,'fieldname','love.hypergeom_table1','NaN',1,'Inf',1,'numel',md.love.hypergeom_nz*md.love.hypergeom_nalpha);
++			md = checkfield(md,'fieldname','love.hypergeom_table2','NaN',1,'Inf',1,'numel',md.love.hypergeom_nz*md.love.hypergeom_nalpha);
++
++			if md.love.istemporal==1
++				md = checkfield(md,'fieldname','love.n_temporal_iterations','NaN',1,'Inf',1,'numel',1,'>',0);
++				md = checkfield(md,'fieldname','love.time','NaN',1,'Inf',1,'numel',md.love.nfreq/2/md.love.n_temporal_iterations);
++			end
++			if md.love.sh_nmin<=1 & (md.love.forcing_type==1 || md.love.forcing_type==5 || md.love.forcing_type==9)
++				error(['Degree 1 not supported for forcing type ' num2str(md.love.forcing_type) '. Use sh_min>=2 for this kind of calculation.'])
++			end
++
++			if md.love.chandler_wobble==1
++				disp('Warning, Chandler Wobble in Love number calculator has not been validated yet');
++			end
++
++			%need 'litho' material: 
++			if ~isa(md.materials,'materials') | ~sum(strcmpi(md.materials.nature,'litho'))
++				error('Need a ''litho'' material to run a Fourier Love number analysis');
++			end
++
++			mat=find(strcmpi(md.materials.nature,'litho'));
++			if md.love.forcing_type<=4
++				md = checkfield(md,'fieldname','love.inner_core_boundary','NaN',1,'Inf',1,'numel',1,'>',0, '<=', md.materials(mat).numlayers);
++			elseif md.love.forcing_type<=8
++				md = checkfield(md,'fieldname','love.core_mantle_boundary','NaN',1,'Inf',1,'numel',1,'>',0, '<=', md.materials(mat).numlayers);
++			end
++
++		end % }}}
++		function marshall(self,prefix,md,fid) % {{{
++
++			WriteData(fid,prefix,'object',self,'fieldname','nfreq','format','Integer');
++			WriteData(fid,prefix,'object',self,'fieldname','frequencies','format','DoubleMat','mattype',3);
++			WriteData(fid,prefix,'object',self,'fieldname','sh_nmax','format','Integer');
++			WriteData(fid,prefix,'object',self,'fieldname','sh_nmin','format','Integer');
++			WriteData(fid,prefix,'object',self,'fieldname','g0','format','Double');
++			WriteData(fid,prefix,'object',self,'fieldname','r0','format','Double');
++			WriteData(fid,prefix,'object',self,'fieldname','mu0','format','Double');
++			WriteData(fid,prefix,'object',self,'fieldname','Gravitational_Constant','format','Double');
++			WriteData(fid,prefix,'object',self,'fieldname','chandler_wobble','format','Boolean');
++			WriteData(fid,prefix,'object',self,'fieldname','allow_layer_deletion','format','Boolean');
++			WriteData(fid,prefix,'object',self,'fieldname','underflow_tol','format','Double');
++			WriteData(fid,prefix,'object',self,'fieldname','pw_threshold','format','Double');
++			WriteData(fid,prefix,'object',self,'fieldname','min_integration_steps','format','Integer');
++			WriteData(fid,prefix,'object',self,'fieldname','max_integration_dr','format','Double');
++			WriteData(fid,prefix,'object',self,'fieldname','integration_scheme','format','Integer');
++			WriteData(fid,prefix,'object',self,'fieldname','istemporal','format','Boolean');
++			WriteData(fid,prefix,'object',self,'fieldname','n_temporal_iterations','format','Integer');
++			WriteData(fid,prefix,'object',self,'fieldname','complex_computation','format','Boolean');
++			WriteData(fid,prefix,'object',self,'fieldname','quad_precision','format','Boolean');
++			%note: no need to marshall the time vector, we have frequencies
++			WriteData(fid,prefix,'object',self,'fieldname','love_kernels','format','Boolean');
++			WriteData(fid,prefix,'object',self,'fieldname','forcing_type','format','Integer');
++			WriteData(fid,prefix,'object',self,'fieldname','inner_core_boundary','format','Integer');
++			WriteData(fid,prefix,'object',self,'fieldname','core_mantle_boundary','format','Integer');
++			WriteData(fid,prefix,'object',self,'fieldname','debug','format','Boolean');
++			WriteData(fid,prefix,'object',self,'fieldname','hypergeom_table1','format','DoubleMat','mattype',1);
++			WriteData(fid,prefix,'object',self,'fieldname','hypergeom_table2','format','DoubleMat','mattype',1);
++			WriteData(fid,prefix,'object',self,'fieldname','hypergeom_nalpha','format','Integer');
++			WriteData(fid,prefix,'object',self,'fieldname','hypergeom_nz','format','Integer');
++			WriteData(fid,prefix,'object',self,'fieldname','hypergeom_z','format','DoubleMat','mattype',3);
++
++		end % }}}
++		function self = extrude(self,md) % {{{
++		end % }}}
++		function savemodeljs(self,fid,modelname) % {{{
++			error('not implemented yet!');
++		end % }}}
++		function self=build_frequencies_from_time(self) % {{{
++			if ~self.istemporal
++				error('cannot build frequencies for temporal love numbers if love.istemporal==0')
++			end
++			disp('Temporal love numbers: Overriding md.love.nfreq and md.love.frequencies');
++			self.nfreq=length(self.time)*2*self.n_temporal_iterations;
++			self.frequencies=zeros(self.nfreq,1);
++			for i=1:length(self.time)
++				for j=1:2*self.n_temporal_iterations
++					if self.time(i)==0
++						self.frequencies((i-1)*2*self.n_temporal_iterations +j) =0; % convention to avoid marshalling infinite numbers
++					else
++						self.frequencies((i-1)*2*self.n_temporal_iterations +j) = j*log(2)/self.time(i)/2/pi;
++					end
++				end
++			end
++		end % }}}
++	end
++end
+Index: ../trunk-jpl/src/m/classes/model.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/model.m	(revision 27307)
++++ ../trunk-jpl/src/m/classes/model.m	(revision 27308)
+@@ -136,7 +136,7 @@
+ 			%2017 May 4th
+ 			if isa(md.amr,'double'); md.amr=amr(); end
+ 			%2017 Aug 29th
+-			if isa(md.love,'double'); md.love=fourierlove(); end
++			if isa(md.love,'double'); md.love=love(); end
+ 			%2017 Oct 26th
+ 			if isa(md.calving,'calvingdev')
+ 				disp('Warning: calvingdev is now calvingvonmises');
+@@ -288,7 +288,7 @@
+ 			md.levelset         = levelset();
+ 			md.calving          = calving();
+ 			md.frontalforcings  = frontalforcings();
+-			md.love             = fourierlove();
++			md.love             = love();
+ 			md.esa              = esa();
+ 			md.sampling         = sampling();
+ 			md.autodiff         = autodiff();
+Index: ../trunk-jpl/src/m/classes/sealevelmodel.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/sealevelmodel.m	(revision 27307)
++++ ../trunk-jpl/src/m/classes/sealevelmodel.m	(revision 27308)
+@@ -47,14 +47,20 @@
+ 		function checkconsistency(slm,solutiontype) % {{{
+ 
+ 			%is the coupler turned on?
+-			for i=1:length(slm.icecaps),
+-				if slm.icecaps{i}.transient.iscoupler==0,
+-					warning(sprintf('sealevelmodel.m::checkconsistency: icecap model %s should have the transient coupler option turned on!',slm.icecaps{i}.miscellaneous.name));
+-				end
+-			end
++			%for i=1:length(slm.icecaps),
++			%	if slm.icecaps{i}.transient.iscoupler==0,
++			%		warning(sprintf('sealevelmodel.m::checkconsistency: icecap model %s should have the transient coupler option turned on!',slm.icecaps{i}.miscellaneous.name));
++			%	end
++			%end
+ 				
+-			if slm.earth.transient.iscoupler==0,
+-				warning('sealevelmodel.m::checkconsistency: earth model should have the transient coupler option turned on!');
++			%if slm.earth.transient.iscoupler==0,
++			%	warning('sealevelmodel.m::checkconsistency: earth model should have the transient coupler option turned on!');
++			%end
++
++			%check that the transition vectors have the right size:
++
++			if slm.earth.mesh.numberofvertices ~= length(slm.earth.solidearth.transfercount)
++				error('sealevelmodel.m::checkconsistency: earth.solidearth.transfercount should be of size earth.mesh.numberofvertices') 
+ 			end
+ 
+ 			%check that the transition vectors have the right size:
+@@ -74,7 +80,7 @@
+ 			%make sure steric_rate is the same everywhere:
+ 			for i=1:length(slm.icecaps),
+ 				md= slm.icecaps{i};
+-				if ~isempty(find(md.dsl.steric_rate - slm.earth.dsl.steric_rate(slm.earth.dsl.transitions{i}))),
++				if ~isempty(find(md.dsl.sea_surface_height_above_geoid - slm.earth.dsl.sea_surface_height_above_geoid(slm.transitions{i}))),
+ 					error(sprintf('sealevelmodel.m::checkconsistency: steric rate on ice cap %s is not the same as for the earth\n',md.miscellaneous.name));
+ 				end
+ 			end
+@@ -82,7 +88,7 @@
+ 			%make sure grd is the same everywhere:
+ 			for i=1:length(slm.icecaps),
+ 				md= slm.icecaps{i};
+-				if md.solidearthsettings.isgrd~=slm.earth.solidearthsettings.isgrd
++				if md.solidearth.settings.isgrd~=slm.earth.solidearth.settings.isgrd
+ 					error(sprintf('sealevelmodel.m::checkconsistency: isgrd on ice cap %s is not the same as for the earth\n',md.miscellaneous.name));
+ 				end
+ 			end
+@@ -227,6 +233,7 @@
+ 			%initialize, to avoid issues of having more transitions than meshes.
+ 			self.transitions={};
+ 			self.eltransitions={};
++			self.earth.solidearth.transfercount=zeros(self.earth.mesh.numberofvertices,1);
+ 
+ 			%for elements:
+ 			xe=self.earth.mesh.x(self.earth.mesh.elements)*[1;1;1]/3;
+@@ -247,7 +254,13 @@
+ 				self.transitions{end+1}=meshintersect3d(self.earth.mesh.x,self.earth.mesh.y,self.earth.mesh.z,mdi.mesh.x,mdi.mesh.y,mdi.mesh.z,'force',force);
+ 
+ 				self.eltransitions{end+1}=meshintersect3d(xe,ye,ze,xei,yei,zei,'force',force);
++
++				self.earth.solidearth.transfercount(self.transitions{i})=self.earth.solidearth.transfercount(self.transitions{i})+1;
+ 			end
++
++			for i=1:length(self.icecaps),
++				self.icecaps{i}.solidearth.transfercount=self.earth.solidearth.transfercount(self.transitions{i});
++			end
+ 		end % }}}
+ 		function checkintersections(self) % {{{
+ 			flags=zeros(self.earth.mesh.numberofvertices,1);
+@@ -254,7 +267,7 @@
+ 			for i=1:length(self.basins),
+ 				flags(self.transitions{i})=i;
+ 			end
+-			plotmodel(self.earth,'data',flags,'coastline','on');
++			plotmodel(self.earth,'data',flags,'coastlines','on');
+ 
+ 		end % }}}
+ 		function checkbasinconsistency(self) % {{{
+Index: ../trunk-jpl/src/m/classes/solidearth.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/solidearth.m	(revision 27307)
++++ ../trunk-jpl/src/m/classes/solidearth.m	(revision 27308)
+@@ -13,6 +13,7 @@
+ 		planetradius           = planetradius('earth');
+ 		requested_outputs      = {};
+ 		transitions            = {};
++		transfercount	 	= [];
+ 		partitionice           = [];
+ 		partitionhydro         = [];
+ 		partitionocean         = [];
+@@ -50,6 +51,7 @@
+ 
+ 			fielddisplay(self,'planetradius','planet radius [m]');
+ 			fielddisplay(self,'transitions','indices into parts of the mesh that will be icecaps');
++			fielddisplay(self,'transfercount','number of icecaps vertices are part of');
+ 			fielddisplay(self,'requested_outputs','additional outputs requested');
+ 			fielddisplay(self,'partitionice','ice partition vector for barystatic contribution');
+ 			fielddisplay(self,'partitionhydro','hydro partition vector for barystatic contribution');
+@@ -70,6 +72,7 @@
+ 
+ 			%transitions should be a cell array of vectors:
+ 			self.transitions={};
++			self.transfercount=[0];
+ 
+ 			%no partitions requested for barystatic contribution:
+ 			self.partitionice=[];
+@@ -109,6 +112,9 @@
+ 
+ 			WriteData(fid,prefix,'object',self,'fieldname','planetradius','format','Double');
+ 			WriteData(fid,prefix,'object',self,'fieldname','transitions','format','MatArray');
++			%WriteData(fid,prefix,'object',self,'fieldname','transfercount','data',self.transfercount,'format','DoubleMat','name', 'md.solidearth.transfercount','mattype',1);
++			%WriteData(fid,prefix,'data',self.transfercount,'format','DoubleMat','name', 'md.solidearth.transfercount');
++			WriteData(fid,prefix,'object',self,'fieldname','transfercount','format','DoubleMat','mattype',1);
+ 
+ 			if ~isempty(self.partitionice),
+ 				npartice=max(self.partitionice)+2;
+Index: ../trunk-jpl/src/m/solve/solveslm.m
+===================================================================
+--- ../trunk-jpl/src/m/solve/solveslm.m	(revision 27307)
++++ ../trunk-jpl/src/m/solve/solveslm.m	(revision 27308)
+@@ -67,7 +67,7 @@
+ miscellaneousnames{end+1}=slm.earth.miscellaneous.name;
+ nps{end+1}=slm.earth.cluster.np;
+ 
+-BuildQueueScriptMultipleModels(cluster,slm.private.runtimename,slm.miscellaneous.name,slm.private.solution,valgrind,privateruntimenames,miscellaneousnames,nps);
++BuildQueueScriptMultipleModels(cluster,slm.private.runtimename,slm.miscellaneous.name,slm.private.solution,privateruntimenames,miscellaneousnames,nps);
+ 
+ %Upload all required files, given that each individual solution for icecaps and earth model already did:
+ filelist={[slm.miscellaneous.name '.queue']};
+Index: ../trunk-jpl/test/NightlyRun/test2013.m
+===================================================================
+--- ../trunk-jpl/test/NightlyRun/test2013.m	(revision 27307)
++++ ../trunk-jpl/test/NightlyRun/test2013.m	(revision 27308)
+@@ -1,6 +1,6 @@
+ %Test Name: EarthSlc_Geometry
+ 
+-step=[1 2];
++step=[1];
+ if any(step==1)
+ %mesh earth:
+ md=model;
+Index: ../trunk-jpl/test/NightlyRun/test2070.m
+===================================================================
+--- ../trunk-jpl/test/NightlyRun/test2070.m	(revision 27307)
++++ ../trunk-jpl/test/NightlyRun/test2070.m	(revision 27308)
+@@ -39,7 +39,7 @@
+ md.love.underflow_tol=1e-20;
+ md.love.pw_threshold=1e-3;
+ md.love.Gravitational_Constant=6.6732e-11;
+-md.love.integration_steps_per_layer=100;
++md.love.min_integration_steps=100;
+ md.love.allow_layer_deletion=1;
+ md.love.forcing_type=11;
+ md.love.chandler_wobble=0;
+Index: ../trunk-jpl/test/NightlyRun/test2073.m
+===================================================================
+--- ../trunk-jpl/test/NightlyRun/test2073.m	(nonexistent)
++++ ../trunk-jpl/test/NightlyRun/test2073.m	(revision 27308)
+@@ -0,0 +1,66 @@
++%Test Name: YiSystemDebug
++%Forward Love number solution for a viscoelastic earth, model M3-L70-V01 from
++%Spada, G., Barletta, V. R., Klemann, V., Riva, R. E. M., Martinec, Z.,
++%Gasperini, P., Lund, B., Wolf, D., Vermeersen, L. L. A. and King, M. A.
++%(2011), A benchmark study for glacial isostatic adjustment codes. Geophysical
++%Journal International, 185: 106--132. doi:10.1111/j.1365-246X.2011.04952.x
++
++md=model();
++md.cluster=generic('name',oshostname(),'np',2);
++
++md.materials=materials('litho');
++md.miscellaneous.name='test2073';
++md.groundingline.migration='None';
++
++md.verbose=verbose('all');
++md.verbose=verbose('1111111111111111');
++cst=365.25*24*3600*1000;
++
++md.materials.numlayers=6;
++md.materials.radius =  [10 1222.5 3.4800e+03   5.7010e+03   5.9510e+03   6.3010e+03   6.3710e+03]'*1e3;
++md.materials.density=  [1.0750e4 1.0750e+04   4.9780e+03   3.8710e+03   3.4380e+03   3.0370e+03]';
++md.materials.lame_mu=  [1e-5         0   2.2834e+00   1.0549e+00   7.0363e-01   5.0605e-01]'*1e11;
++md.materials.viscosity=[0            0   2.0000e+00   1.0000e+00   1.0000e+00   1.0000e+25]'*1e21;
++md.materials.lame_lambda=md.materials.lame_mu*0+5e17;
++md.materials.issolid=[1 0 1 1 1 1]';
++md.materials.rheologymodel=zeros(md.materials.numlayers,1);
++md.materials.burgers_mu=md.materials.lame_mu/3;
++md.materials.burgers_viscosity=md.materials.viscosity/10;
++md.materials.ebm_alpha= ones(md.materials.numlayers,1)*.9;
++md.materials.ebm_delta= ones(md.materials.numlayers,1)*0.2;
++md.materials.ebm_taul= ones(md.materials.numlayers,1)*54*60; %54min
++md.materials.ebm_tauh= ones(md.materials.numlayers,1)*18.6*cst/1e3; %18.6yr
++
++md.love.allow_layer_deletion=1;
++md.love.frequencies=[0];
++md.love.nfreq=length(md.love.frequencies);
++md.love.sh_nmin=2;
++md.love.sh_nmax=2;
++md.love.underflow_tol=1e-20;
++md.love.pw_threshold=1e-3;
++md.love.Gravitational_Constant=6.6732e-11;
++md.love.allow_layer_deletion=1;
++md.love.forcing_type=11;
++md.love.chandler_wobble=0;
++md.love.complex_computation=0;
++md.love.istemporal=0;
++
++md.love.debug=1;
++%make sure we only have one step per layer in the propagator
++md.love.max_integration_dr=md.materials.radius(end);
++md.love.min_integration_steps=1;
++
++md.love.love_kernels=1;
++
++md=solve(md,'lv');
++
++yi=md.results.LoveSolution.LoveYi;
++rhs=md.results.LoveSolution.LoveRhs;
++
++
++%Fields and tolerances to track changes
++
++field_names     ={'LoveYi_loading_elastic','LoveRhs_loading_elastic'};
++field_tolerances={1.0e-13,1.0e-13,1.0e-13};
++field_values={yi,rhs};
++
+Index: ../trunk-jpl/test/NightlyRun/test2084.m
+===================================================================
+--- ../trunk-jpl/test/NightlyRun/test2084.m	(revision 27307)
++++ ../trunk-jpl/test/NightlyRun/test2084.m	(revision 27308)
+@@ -43,7 +43,6 @@
+ md.love.underflow_tol=1e-20;
+ md.love.pw_threshold=1e-3;
+ md.love.Gravitational_Constant=6.6732e-11;
+-md.love.integration_steps_per_layer=100;
+ md.love.allow_layer_deletion=1;
+ md.love.forcing_type=11;
+ md.love.chandler_wobble=0;
+Index: ../trunk-jpl/src/c/classes/Elements/Tria.cpp
+===================================================================
+--- ../trunk-jpl/src/c/classes/Elements/Tria.cpp	(revision 27307)
++++ ../trunk-jpl/src/c/classes/Elements/Tria.cpp	(revision 27308)
+@@ -2197,6 +2197,10 @@
+ 
+ 	//compute sea level load weights
+ 	this->GetFractionGeometry(loadweights,&phi,&point1,&fraction1,&fraction2,&istrapeze1,levelset);
++
++	//failsafe for phi so small that GetFractionGeometry returns 0	
++	if (phi==0) phi=1e-16;
++
+ 	for (int i=0;i<NUMVERTICES;i++) loadweights[i]/=phi;
+ 	this->GetBarycenterFromLevelset(platbar,plongbar, phi, fraction1, fraction2, late, longe, point1,istrapeze1,planetradius);
+ 
+@@ -6404,7 +6408,7 @@
+ 	return;
+ }
+ /*}}}*/
+-void       Tria::SealevelchangeGeometryInitial(IssmDouble* xxe, IssmDouble* yye, IssmDouble* zze, IssmDouble* areae, int* lids){ /*{{{*/
++void       Tria::SealevelchangeGeometryInitial(IssmDouble* xxe, IssmDouble* yye, IssmDouble* zze, IssmDouble* areae, int* lids, int* n_activevertices){ /*{{{*/
+ 
+ 	/*Declarations:{{{*/
+ 	int nel;
+@@ -6554,13 +6558,17 @@
+ 		nt=1; //in elastic, or if we run only selfattraction, we need only one step
+ 	}
+ 
+-	AlphaIndex=xNewZeroInit<int>(3*nel);
+-	if (horiz) AzimuthIndex=xNewZeroInit<int>(3*nel);
++	AlphaIndex=xNewZeroInit<int>(n_activevertices[this->lid]*nel);
++	if (horiz) AzimuthIndex=xNewZeroInit<int>(n_activevertices[this->lid]*nel);
+ 	int intmax=pow(2,16)-1;
+ 
++	int* activevertices=xNew<int>(n_activevertices[this->lid]);
++	
++	int av=0;
+ 
+ 	for (int i=0;i<3;i++){
+ 		if(lids[this->vertices[i]->lid]==this->lid){
++			activevertices[av]=i;
+ 			for(int e=0;e<nel;e++){
+ 				IssmDouble alpha;
+ 				IssmDouble delPhi,delLambda;
+@@ -6584,16 +6592,18 @@
+ 					dx=cos(lati)*sin(late)-sin(lati)*cos(late)*cos(longe-longi);
+ 					dy=sin(longe-longi)*cos(late);
+ 					//angle between horiz motion and North, remapped from a double on [0,2*pi] to a int [0,intmax]
+-					AzimuthIndex[i*nel+e]=reCast<int,IssmDouble>(intmax*(atan2(dy,dx)/2/M_PI));
++					AzimuthIndex[av*nel+e]=reCast<int,IssmDouble>(intmax*(atan2(dy,dx)/2/M_PI));
+ 				}
+-				AlphaIndex[i*nel+e]=index;
+-			}			
++				AlphaIndex[av*nel+e]=index;
++			}
++			av+=1;			
+ 		} //for (int i=0;i<3;i++)
+ 	} //for(int e=0;e<nel;e++)
+ 
+ 	/*Add in inputs:*/
+-	this->inputs->SetIntArrayInput(SealevelchangeAlphaIndexEnum,this->lid,AlphaIndex,nel*3);
+-	if(horiz) this->inputs->SetIntArrayInput(SealevelchangeAzimuthIndexEnum,this->lid,AzimuthIndex,nel*3);
++	this->inputs->SetIntArrayInput(SealevelchangeConvolutionVerticesEnum,this->lid,activevertices,n_activevertices[this->lid]);
++	this->inputs->SetIntArrayInput(SealevelchangeAlphaIndexEnum,this->lid,AlphaIndex,nel*n_activevertices[this->lid]);
++	if(horiz) this->inputs->SetIntArrayInput(SealevelchangeAzimuthIndexEnum,this->lid,AzimuthIndex,nel*n_activevertices[this->lid]);
+ 
+ 	/*}}}*/
+ 	/*Compute rotation kernel:{{{*/
+@@ -6712,6 +6722,7 @@
+ 
+ 	/*Free allocations:{{{*/
+ 	#ifdef _HAVE_RESTRICT_
++	delete activevertices;
+ 	delete AlphaIndex;
+ 	if(horiz) AzimuthIndex;
+ 
+@@ -6725,6 +6736,7 @@
+ 	}
+ 
+ 	#else
++	xDelete<int>(activevertices);
+ 	xDelete<int>(AlphaIndex);
+ 	if(horiz){
+ 		xDelete<int>(AzimuthIndex);
+@@ -6756,6 +6768,8 @@
+ 	IssmDouble longitude[NUMVERTICES];
+ 	IssmDouble x,y,z,dx,dy,dz,N_azim,E_azim;
+ 	IssmDouble xyz_list[NUMVERTICES][3];
++	int* activevertices = NULL;
++	int n_activevertices, av;
+ 
+ 	#ifdef _HAVE_RESTRICT_
+ 	int** __restrict__ AlphaIndex=NULL;
+@@ -6830,57 +6844,62 @@
+ 	AlphaIndex=xNew<int*>(SLGEOM_NUMLOADS);
+ 	if(horiz) AzimIndex=xNew<int*>(SLGEOM_NUMLOADS);
+ 
++	this->inputs->GetIntArrayPtr(SealevelchangeConvolutionVerticesEnum,this->lid,&activevertices,&n_activevertices);
++	// 0<=n_activevertices<=3 is the number of vertices this element is in charge of computing fields in during the sea level convolutions
++	// activevertices contains the vertex indices (1,2 and/or 3) in case debugging is required, they are supposed to appear in the same order as slgeom->lids
+ 
+ 	//Allocate: 
+ 	for(int l=0;l<SLGEOM_NUMLOADS;l++){
+ 		int nbar=slgeom->nbar[l];
+-		AlphaIndex[l]=xNewZeroInit<int>(3*nbar);
+-		if(horiz) AzimIndex[l]=xNewZeroInit<int>(3*nbar);
++		AlphaIndex[l]=xNewZeroInit<int>(n_activevertices*nbar);
++		if(horiz) AzimIndex[l]=xNewZeroInit<int>(n_activevertices*nbar);
+ 
+-
+-		for (int i=0;i<3;i++){
+-			if(slgeom->lids[this->vertices[i]->lid]==this->lid){
+-				for(int e=0;e<nbar;e++){
+-					IssmDouble alpha;
+-					IssmDouble delPhi,delLambda;
+-					/*recover info for this element and vertex:*/
+-					IssmDouble late= slgeom->latbarycentre[l][e]; 
+-					IssmDouble longe= slgeom->longbarycentre[l][e]; 
+-					late=late/180*M_PI;
+-					longe=longe/180*M_PI;
+-
+-					lati=latitude[i];
+-					longi=longitude[i];
+-
++		//av=0;
++		//for (int i=0;i<3;i++){
++		for (int av=0;av<n_activevertices;av++){
++			//if(slgeom->lids[this->vertices[i]->lid]==this->lid){
++			int i=activevertices[av];
++			for(int e=0;e<nbar;e++){
++				IssmDouble alpha;
++				IssmDouble delPhi,delLambda;
++				/*recover info for this element and vertex:*/
++				IssmDouble late= slgeom->latbarycentre[l][e]; 
++				IssmDouble longe= slgeom->longbarycentre[l][e]; 
++				late=late/180*M_PI;
++				longe=longe/180*M_PI;
++				lati=latitude[i];
++				longi=longitude[i];
+ 					if(horiz){
+-						/*Compute azimuths*/
++					/*Compute azimuths*/
+ 						dx=cos(lati)*sin(late)-sin(lati)*cos(late)*cos(longe-longi);
+ 						dy=sin(longe-longi)*cos(late);
+ 						//angle between horiz motion and North, remapped from a double on [0,2*pi] to a int [0,intmax]
+-						AzimIndex[l][i*nbar+e]=reCast<int,IssmDouble>(intmax*(atan2(dy,dx)/2/M_PI));
++						AzimIndex[l][av*nbar+e]=reCast<int,IssmDouble>(intmax*(atan2(dy,dx)/2/M_PI));
+ 					}
+ 
+-					/*Compute alpha angle between centroid and current vertex and index into precomputed tables: */
+-					delPhi=fabs(lati-late); delLambda=fabs(longi-longe); if (delLambda>M_PI)delLambda=2*M_PI-delLambda;
+-					alpha=2.*asin(sqrt(pow(sin(delPhi/2.0),2.0)+cos(lati)*cos(late)*pow(sin(delLambda/2.0),2.0)));
+-					doubleindex=alpha/M_PI*reCast<IssmDouble,int>(M-1); //maps 0<alpha<PI on [0:M-1]
+-					index=reCast<int,IssmDouble>(doubleindex); //truncates doubleindex to integer part
++				/*Compute alpha angle between centroid and current vertex and index into precomputed tables: */
++				delPhi=fabs(lati-late); delLambda=fabs(longi-longe); if (delLambda>M_PI)delLambda=2*M_PI-delLambda;
++				alpha=2.*asin(sqrt(pow(sin(delPhi/2.0),2.0)+cos(lati)*cos(late)*pow(sin(delLambda/2.0),2.0)));
++				doubleindex=alpha/M_PI*reCast<IssmDouble,int>(M-1); //maps 0<alpha<PI on [0:M-1]
++				index=reCast<int,IssmDouble>(doubleindex); //truncates doubleindex to integer part
+ 
+-					if ((doubleindex-index)>=0.5) index+=1; //nearest neighbour
+-					if (index==M-1){ //avoids out of bound case
+-						index-=1;
+-						lincoef=1;
+-					}
+-					AlphaIndex[l][i*nbar+e]=index;
++				if ((doubleindex-index)>=0.5) index+=1; //nearest neighbour
++				if (index==M-1){ //avoids out of bound case
++					index-=1;
++					lincoef=1;
+ 				}
++				AlphaIndex[l][av*nbar+e]=index;
++			//}
++			//av+=1;
+ 			}
++
+ 		}
+ 	}
+ 
+ 	/*Save all these arrayins for each element:*/
+ 	for (int l=0;l<SLGEOM_NUMLOADS;l++){
+-		this->inputs->SetIntArrayInput(slgeom->AlphaIndexEnum(l),this->lid,AlphaIndex[l],slgeom->nbar[l]*3);
+-		if(horiz) this->inputs->SetIntArrayInput(slgeom->AzimuthIndexEnum(l),this->lid,AzimIndex[l],slgeom->nbar[l]*3);
++		this->inputs->SetIntArrayInput(slgeom->AlphaIndexEnum(l),this->lid,AlphaIndex[l],slgeom->nbar[l]*n_activevertices);
++		if(horiz) this->inputs->SetIntArrayInput(slgeom->AzimuthIndexEnum(l),this->lid,AzimIndex[l],slgeom->nbar[l]*n_activevertices);
+ 	}
+ 	/*}}}*/
+ 	/*Free memory:{{{*/
+@@ -7226,6 +7245,7 @@
+ 		slgeom->vlongbarycentre[SLGEOM_OCEAN]->SetValue(intj,longbar,INS_VAL);
+ 
+ 		for(int i=0;i<NUMVERTICES;i++) slgeom->LoadWeigths[SLGEOM_OCEAN][i][this->lid]=loadweightsocean[i];
++
+ 		#ifdef _ISSM_DEBUG_ /*{{{*/
+ 		/*Inform mask: */
+ 		constant=loadareaocean/area;
+@@ -7336,19 +7356,22 @@
+ 	for(int i=0;i<NUMVERTICES;i++){
+ 		oceanaverage+=sealevelpercpu[this->vertices[i]->lid]*slgeom->LoadWeigths[SLGEOM_OCEAN][i][this->lid];
+ 	}
+-	#ifdef _ISSM_DEBUG_ 
+-	this->AddInput(SealevelBarystaticOceanLoadEnum,&oceanaverage,P0Enum);
+-	#endif
++
+ 	oceanarea=slgeom->LoadArea[SLGEOM_OCEAN][this->lid];
++	oceanaverage*=rho_water*oceanarea;
+ 
+ 	/*add ocean average in the global sealevelloads vector:*/
+ 	if(slgeom->issubelement[SLGEOM_OCEAN][this->lid]){
+ 		int intj=slgeom->subelementmapping[SLGEOM_OCEAN][this->lid];
+-		loads->vsubsealevelloads->SetValue(intj,oceanaverage*rho_water*oceanarea,INS_VAL);
++		loads->vsubsealevelloads->SetValue(intj,oceanaverage,INS_VAL);
+ 		loads->vsealevelloads->SetValue(this->sid,0.,INS_VAL);
+ 	}
+-	else loads->vsealevelloads->SetValue(this->sid,oceanaverage*rho_water*oceanarea,INS_VAL);
++	else loads->vsealevelloads->SetValue(this->sid,oceanaverage,INS_VAL);
+ 
++	#ifdef _ISSM_DEBUG_ 
++	this->AddInput(SealevelBarystaticOceanLoadEnum,&oceanaverage,P0Enum);
++	#endif
++
+ 	/*add ocean area into a global oceanareas vector:*/
+ 	if(!loads->sealevelloads){
+ 		oceanareas->SetValue(this->sid,oceanarea,INS_VAL);
+@@ -7366,9 +7389,9 @@
+ 	int* AlphaIndexsub[SLGEOM_NUMLOADS];
+ 	IssmDouble* G=NULL;
+ 	IssmDouble* Grot=NULL;
++	IssmDouble* rslfield=NULL;
+ 	DoubleVecParam* parameter;
+ 	bool computefuture=false;
+-	int spatial_component=0;
+ 
+ 	bool sal = false;
+ 	bool viscous = false;
+@@ -7387,11 +7410,11 @@
+ 		parameter = static_cast<DoubleVecParam*>(this->parameters->FindParamObject(SealevelchangeGViscoElasticEnum)); _assert_(parameter);
+ 		parameter->GetParameterValueByPointer((IssmDouble**)&G,NULL);
+ 
+-		this->inputs->GetIntArrayPtr(SealevelchangeAlphaIndexEnum,this->lid,&AlphaIndex,&size);
+-		for (int l=0;l<SLGEOM_NUMLOADS;l++) this->inputs->GetIntArrayPtr(slgeom->AlphaIndexEnum(l),this->lid,&AlphaIndexsub[l],&size);
+ 		if (rotation)	this->inputs->GetArrayPtr(SealevelchangeGrotEnum,this->lid,&Grot,&size);
+ 
+-		this->SealevelchangeGxL(sealevelpercpu, spatial_component=0,AlphaIndex, AlphaIndexsub, NULL, NULL, G, Grot, loads, polarmotionvector, slgeom, nel,percpu=true,SealevelchangeViscousRSLEnum,computefuture=false);
++		rslfield=this->SealevelchangeGxL(G,Grot,loads,polarmotionvector,slgeom,nel,computefuture=false);
++		this->SealevelchangeCollectGrdfield(sealevelpercpu,rslfield,slgeom,nel,percpu=true,SealevelchangeViscousRSLEnum,computefuture=false);
++
+ 	}
+ 
+ 	return;
+@@ -7405,10 +7428,6 @@
+ 	IssmDouble EGrd[3]={0,0,0};
+ 	int nel,nbar;
+ 	bool sal = false;
+-	int* AlphaIndex=NULL;
+-	int* AzimIndex=NULL;
+-	int* AlphaIndexsub[SLGEOM_NUMLOADS];
+-	int* AzimIndexsub[SLGEOM_NUMLOADS];
+ 	int spatial_component=0;
+ 	IssmDouble* G=NULL;
+ 	IssmDouble* GU=NULL;
+@@ -7417,6 +7436,7 @@
+ 	IssmDouble* GUrot=NULL;
+ 	IssmDouble* GNrot=NULL;
+ 	IssmDouble* GErot=NULL;
++	IssmDouble* grdfield=NULL;
+ 
+ 	DoubleVecParam* parameter;
+ 	bool computefuture=false;
+@@ -7437,9 +7457,6 @@
+ 	this->parameters->FindParam(&planethasocean,SolidearthSettingsGrdOceanEnum);
+ 
+ 	if(sal){
+-		this->inputs->GetIntArrayPtr(SealevelchangeAlphaIndexEnum,this->lid,&AlphaIndex,&size);
+-		for (int l=0;l<SLGEOM_NUMLOADS;l++) this->inputs->GetIntArrayPtr(slgeom->AlphaIndexEnum(l),this->lid,&AlphaIndexsub[l],&size);
+-
+ 		parameter = static_cast<DoubleVecParam*>(this->parameters->FindParamObject(SealevelchangeGViscoElasticEnum)); _assert_(parameter);
+ 		parameter->GetParameterValueByPointer((IssmDouble**)&G,NULL);
+ 
+@@ -7448,9 +7465,6 @@
+ 			parameter->GetParameterValueByPointer((IssmDouble**)&GU,NULL);
+ 
+ 			if(horiz){
+-				this->inputs->GetIntArrayPtr(SealevelchangeAzimuthIndexEnum,this->lid,&AzimIndex,&size);
+-				for (int l=0;l<SLGEOM_NUMLOADS;l++) this->inputs->GetIntArrayPtr(slgeom->AzimuthIndexEnum(l),this->lid,&AzimIndexsub[l],&size);
+-
+ 				parameter = static_cast<DoubleVecParam*>(this->parameters->FindParamObject(SealevelchangeHViscoElasticEnum)); _assert_(parameter);
+ 				parameter->GetParameterValueByPointer((IssmDouble**)&GH,NULL);
+ 			}
+@@ -7463,14 +7477,23 @@
+ 				}
+ 			}
+ 		}
++		//Relative sea level convolution
++		grdfield=this->SealevelchangeGxL(G,Grot,loads,polarmotionvector,slgeom,nel,computefuture=true);
++		this->SealevelchangeCollectGrdfield(&RSLGrd[0],grdfield,slgeom,nel,percpu=false,SealevelchangeViscousRSLEnum,computefuture=true);
+ 
+-		this->SealevelchangeGxL(&RSLGrd[0],spatial_component=0, AlphaIndex, AlphaIndexsub,NULL, NULL,G, Grot, loads, polarmotionvector, slgeom, nel,percpu=false,SealevelchangeViscousRSLEnum,computefuture=true);
++		if(elastic){
++			//Bedrock Uplift
++			grdfield=this->SealevelchangeGxL(GU,GUrot,loads,polarmotionvector,slgeom,nel,computefuture=true);
++			this->SealevelchangeCollectGrdfield(&UGrd[0],grdfield,slgeom,nel,percpu=false,SealevelchangeViscousUEnum,computefuture=true);
+ 
+-		if(elastic){
+-			this->SealevelchangeGxL(&UGrd[0],spatial_component=0, AlphaIndex, AlphaIndexsub,NULL, NULL, GU, GUrot, loads, polarmotionvector, slgeom, nel,percpu=false,SealevelchangeViscousUEnum,computefuture=true);
+ 			if(horiz){
+-				this->SealevelchangeGxL(&NGrd[0],spatial_component=1,AlphaIndex, AlphaIndexsub,AzimIndex,AzimIndexsub,GH, GNrot, loads, polarmotionvector, slgeom, nel,percpu=false,SealevelchangeViscousNEnum,computefuture=true);
+-				this->SealevelchangeGxL(&EGrd[0],spatial_component=2,AlphaIndex, AlphaIndexsub,AzimIndex,AzimIndexsub,GH, GErot, loads, polarmotionvector, slgeom, nel,percpu=false,SealevelchangeViscousEEnum,computefuture=true);
++				//Bedrock North displacement
++				grdfield=this->SealevelchangeHorizGxL(spatial_component=1,GH,GNrot,loads,polarmotionvector,slgeom,nel,computefuture=true);
++				this->SealevelchangeCollectGrdfield(&NGrd[0],grdfield,slgeom,nel,percpu=false,SealevelchangeViscousNEnum,computefuture=true);
++
++				//Bedrock East displacement
++				grdfield=this->SealevelchangeHorizGxL(spatial_component=2,GH,GErot,loads,polarmotionvector,slgeom,nel,computefuture=true);
++				this->SealevelchangeCollectGrdfield(&EGrd[0],grdfield,slgeom,nel,percpu=false,SealevelchangeViscousEEnum,computefuture=true);
+ 			}
+ 		}
+ 	}
+@@ -7495,45 +7518,37 @@
+ 	}
+ 
+ } /*}}}*/
+-void       Tria::SealevelchangeGxL(IssmDouble* grdfieldout, int spatial_component, int* AlphaIndex, int** AlphaIndexsub, int* AzimIndex, int**AzimIndexsub, IssmDouble* G, IssmDouble* Grot, GrdLoads* loads, IssmDouble* polarmotionvector, SealevelGeometry* slgeom, int nel, bool percpu, int viscousenum, bool computefuture) { /*{{{*/
++IssmDouble*       Tria::SealevelchangeGxL(IssmDouble* G, IssmDouble* Grot, GrdLoads* loads, IssmDouble* polarmotionvector, SealevelGeometry* slgeom, int nel, bool computefuture) { /*{{{*/
+ 
+ 	//This function performs the actual convolution between Green functions and surface Loads for a particular grd field
+-
++	int* AlphaIndex=NULL;
++	int* AlphaIndexsub[SLGEOM_NUMLOADS];
++	int* activevertices=NULL;
+ 	IssmDouble* grdfield=NULL;
+-	int i,e,l,t,a, index, nbar;
++	int i,e,l,t,a, index, nbar, size, av,ae,b,c;
+ 	bool rotation=false;
+-	IssmDouble* Centroid_loads=NULL;
+-	IssmDouble* Centroid_loads_copy=NULL;
+-	IssmDouble* Subelement_loads[SLGEOM_NUMLOADS];
+-	IssmDouble* Subelement_loads_copy[SLGEOM_NUMLOADS];
+-	IssmDouble* horiz_projection=NULL;
+-	IssmDouble* horiz_projectionsub[SLGEOM_NUMLOADS];
+ 	int nt=1; //important, ensures there is a defined value if computeviscous is false
++	int n_activevertices=0;
+ 
+ 	//viscous
+ 	bool computeviscous=false;
+ 	int viscousindex=0; //important
+ 	int viscousnumsteps=1; //important
+-	IssmDouble* viscousfield=NULL;
+-	IssmDouble* grdfieldinterp=NULL;
+-	IssmDouble* viscoustimes=NULL;
+-	IssmDouble  final_time;
+-	IssmDouble  lincoeff;
+-	IssmDouble  timeacc;
+ 
+ 	this->parameters->FindParam(&computeviscous,SolidearthSettingsViscousEnum);
+ 	this->parameters->FindParam(&rotation,SolidearthSettingsRotationEnum);
++
++	//Get green functions indexing & geometry
++	this->inputs->GetIntArrayPtr(SealevelchangeConvolutionVerticesEnum,this->lid,&activevertices,&n_activevertices); //the order in which the vertices appear here should be the same as in slgeom->lids
++	this->inputs->GetIntArrayPtr(SealevelchangeAlphaIndexEnum,this->lid,&AlphaIndex,&size);
++	for (int l=0;l<SLGEOM_NUMLOADS;l++) this->inputs->GetIntArrayPtr(slgeom->AlphaIndexEnum(l),this->lid,&AlphaIndexsub[l],&size);
++
+ 	if(computeviscous){
+ 		this->parameters->FindParam(&viscousnumsteps,SealevelchangeViscousNumStepsEnum);
+ 		this->parameters->FindParam(&viscousindex,SealevelchangeViscousIndexEnum);
+-		this->parameters->FindParam(&viscoustimes,NULL,SealevelchangeViscousTimesEnum);
+-		this->parameters->FindParam(&final_time,TimesteppingFinalTimeEnum);
+-		this->parameters->FindParam(&timeacc,SolidearthSettingsTimeAccEnum);
+-		this->inputs->GetArrayPtr(viscousenum,this->lid,&viscousfield,NULL);
+ 		if(computefuture) {
+ 			nt=viscousnumsteps-viscousindex+2; //number of time steps remaining to reach final_time, +1 is sufficient with no adaptative time stepping, +2 necessary otherwise; we assume the safe choice here for the sake of simplicity
+ 			if (nt>viscousnumsteps) nt=viscousnumsteps;
+-			grdfieldinterp=xNewZeroInit<IssmDouble>(3*viscousnumsteps); 
+ 		}
+ 		else nt=1;
+ 	}
+@@ -7540,199 +7555,330 @@
+ 	//allocate
+ 	grdfield=xNewZeroInit<IssmDouble>(3*nt);
+ 
++	//early return
++	if (n_activevertices==0) return grdfield;
++
+ 	if(rotation){ //add rotational feedback
+-		for(int i=0;i<NUMVERTICES;i++){ //vertices
+-			if(slgeom->lids[this->vertices[i]->lid]==this->lid){
+-				for (int m=0;m<3;m++){ //polar motion components
+-					for(t=0;t<nt;t++){ //time
+-						int index=m*3*viscousnumsteps+i*viscousnumsteps+t;
+-						grdfield[i*nt+t]+=Grot[index]*polarmotionvector[m];
+-					}
++		for(av=0;av<n_activevertices;av++) { //vertices
++			i=activevertices[av];
++			//if(slgeom->lids[this->vertices[i]->lid]!=this->lid)continue;
++			b=i*nt;
++			for (int m=0;m<3;m++){ //polar motion components
++				for(t=0;t<nt;t++){ //time
++					int index=m*3*viscousnumsteps+i*viscousnumsteps+t;
++					grdfield[b+t]+=Grot[index]*polarmotionvector[m];
+ 				}
+ 			}
+ 		}
+ 	}
+ 
+-	//Determine loads /*{{{*/
+-	Centroid_loads=xNewZeroInit<IssmDouble>(nel);
+-	for (e=0;e<nel;e++){
+-		Centroid_loads[e]=loads->loads[e];
+-	}
+-	for(l=0;l<SLGEOM_NUMLOADS;l++){
+-		nbar=slgeom->nbar[l];
+-		Subelement_loads[l]=xNewZeroInit<IssmDouble>(nbar);
+-		for (e=0;e<nbar;e++){
+-			Subelement_loads[l][e]=(loads->subloads[l][e]);
++	//Convolution
++	for(av=0;av<n_activevertices;av++) { /*{{{*/
++		i=activevertices[av];
++		//if(slgeom->lids[this->vertices[i]->lid]!=this->lid)continue;
++		b=i*nt;
++		c=av*nel;
++		for (int ae=0;ae<loads->nactiveloads;ae++){
++			e=loads->combined_loads_index[ae];
++			a=AlphaIndex[c+e]*viscousnumsteps;
++			for(t=0;t<nt;t++){
++				grdfield[b+t]+=G[a+t]*loads->combined_loads[ae];
++			}
+ 		}
+-	}
+-	if(loads->sealevelloads){
+-		for (e=0;e<nel;e++){
+-			Centroid_loads[e]+=(loads->sealevelloads[e]);
++		for(l=0;l<SLGEOM_NUMLOADS;l++){
++			nbar=slgeom->nbar[l];
++			c=av*nbar;
++			for (ae=0;ae<loads->nactivesubloads[l];ae++){
++				e=loads->combined_subloads_index[l][ae];
++				a=AlphaIndexsub[l][c+e]*viscousnumsteps;
++				for(t=0;t<nt;t++){
++					grdfield[b+t]+=G[a+t]*loads->combined_subloads[l][ae];
++				}
++			}
+ 		}
+-		nbar=slgeom->nbar[SLGEOM_OCEAN];
+-		for (e=0;e<nbar;e++){
+-			Subelement_loads[SLGEOM_OCEAN][e]+=(loads->subsealevelloads[e]);
++		//av+=1;
++	} /*}}}*/
++
++	return grdfield;
++
++} /*}}}*/
++IssmDouble*       Tria::SealevelchangeHorizGxL(int spatial_component, IssmDouble* G, IssmDouble* Grot, GrdLoads* loads, IssmDouble* polarmotionvector, SealevelGeometry* slgeom, int nel, bool computefuture) { /*{{{*/
++
++	//This function performs the actual convolution between Green functions and surface Loads for a particular grd field
++	int* AlphaIndex=NULL;
++	int* AzimIndex=NULL;
++	int* AlphaIndexsub[SLGEOM_NUMLOADS];
++	int* AzimIndexsub[SLGEOM_NUMLOADS];
++	int* activevertices = NULL;
++	IssmDouble* grdfield=NULL;
++	int i,e,l,t,a,b,c, index, nbar, av, ae,n_activevertices, size;
++	bool rotation=false;
++	IssmDouble* projected_loads=NULL;
++	IssmDouble* projected_subloads[SLGEOM_NUMLOADS];
++	IssmDouble* horiz_projection=NULL;
++	IssmDouble* horiz_projectionsub[SLGEOM_NUMLOADS];
++	int nt=1; //important, ensures there is a defined value if computeviscous is false
++
++	//viscous
++	bool computeviscous=false;
++	int viscousindex=0; //important
++	int viscousnumsteps=1; //important
++
++	//Get green functions indexing & geometry
++	this->inputs->GetIntArrayPtr(SealevelchangeConvolutionVerticesEnum,this->lid,&activevertices,&n_activevertices);
++	this->inputs->GetIntArrayPtr(SealevelchangeAlphaIndexEnum,this->lid,&AlphaIndex,&size);
++	for (int l=0;l<SLGEOM_NUMLOADS;l++) this->inputs->GetIntArrayPtr(slgeom->AlphaIndexEnum(l),this->lid,&AlphaIndexsub[l],&size);
++	this->inputs->GetIntArrayPtr(SealevelchangeAzimuthIndexEnum,this->lid,&AzimIndex,&size);
++	for (int l=0;l<SLGEOM_NUMLOADS;l++) this->inputs->GetIntArrayPtr(slgeom->AzimuthIndexEnum(l),this->lid,&AzimIndexsub[l],&size);
++
++	//First, figure out how many time steps to compute grdfield for
++	this->parameters->FindParam(&computeviscous,SolidearthSettingsViscousEnum);
++	this->parameters->FindParam(&rotation,SolidearthSettingsRotationEnum);
++	if(computeviscous){
++		this->parameters->FindParam(&viscousnumsteps,SealevelchangeViscousNumStepsEnum);
++		this->parameters->FindParam(&viscousindex,SealevelchangeViscousIndexEnum);
++		if(computefuture) {
++			nt=viscousnumsteps-viscousindex+2; //number of time steps remaining to reach final_time, +1 is sufficient with no adaptative time stepping, +2 necessary otherwise; we assume the safe choice here for the sake of simplicity
++			if (nt>viscousnumsteps) nt=viscousnumsteps;
+ 		}
++		else nt=1;
+ 	}
++	//allocate
++	grdfield=xNewZeroInit<IssmDouble>(3*nt);
++	if (n_activevertices==0) return grdfield;
+ 
+-	//Copy loads if dealing with a horizontal component: the result will need to be projected against the North or East axis for each vertex
+-	if (spatial_component!=0){
+-		horiz_projection=xNewZeroInit<IssmDouble>(3*nel);
+-		Centroid_loads_copy=xNewZeroInit<IssmDouble>(nel);
+-		for (e=0;e<nel;e++){
+-			Centroid_loads_copy[e]=Centroid_loads[e];
+-		}
+-
+-		for(l=0;l<SLGEOM_NUMLOADS;l++){
+-			nbar=slgeom->nbar[l];
+-			Subelement_loads_copy[l]=xNewZeroInit<IssmDouble>(nbar);
+-			horiz_projectionsub[l]=xNewZeroInit<IssmDouble>(3*nbar);
+-			for (e=0;e<nbar;e++){
+-				Subelement_loads_copy[l][e]=Subelement_loads[l][e];
++	if(rotation){ //add rotational feedback
++		for(av=0;av<n_activevertices;av++) { //vertices
++			i=activevertices[av];
++			//if(slgeom->lids[this->vertices[i]->lid]!=this->lid)continue;
++			for (int m=0;m<3;m++){ //polar motion components
++				for(t=0;t<nt;t++){ //time
++					int index=m*3*viscousnumsteps+i*viscousnumsteps+t;
++					grdfield[i*nt+t]+=Grot[index]*polarmotionvector[m];
++				}
+ 			}
++			//}
+ 		}
+ 	}
+-	/*}}}*/
+ 
++	//Initialize projection vectors
++	horiz_projection=xNewZeroInit<IssmDouble>(loads->nactiveloads);
++	projected_loads=xNewZeroInit<IssmDouble>(loads->nactiveloads);
++	for(l=0;l<SLGEOM_NUMLOADS;l++){
++		//nbar=slgeom->nbar[l];
++		projected_subloads[l]=xNewZeroInit<IssmDouble>(loads->nactivesubloads[l]);
++		horiz_projectionsub[l]=xNewZeroInit<IssmDouble>(loads->nactivesubloads[l]);
++	}
++
++
+ 	//Convolution
+-	for(i=0;i<NUMVERTICES;i++) { /*{{{*/
+-		if(slgeom->lids[this->vertices[i]->lid]!=this->lid)continue;
++	//av=0;
++	for(av=0;av<n_activevertices;av++) { //vertices
++		i=activevertices[av];
++		//if(slgeom->lids[this->vertices[i]->lid]!=this->lid)continue;
++		b=i*nt;
+ 
+-		if (spatial_component!=0){ //horizontals /*{{{*/
+-			//GxL needs to be projected on the right axis before summation into the grd field
+-			//here we apply the projection scalar to the load prior to the actual convolution loop for more efficiency
+-			if (spatial_component==1){ //north
+-				for (e=0;e<nel;e++){
+-					horiz_projection[i*nel+e]=cos(2.0*M_PI*reCast<IssmDouble,int>(AzimIndex[i*nel+e])/65535.0); // 65535=2^16-1 = max value of 16 bits unsigned int
+-				}
+-				for(l=0;l<SLGEOM_NUMLOADS;l++){
+-					nbar=slgeom->nbar[l];
+-					for (e=0;e<nbar;e++){
+-						horiz_projectionsub[l][i*nbar+e]=cos(2.0*M_PI*reCast<IssmDouble,int>(AzimIndexsub[l][i*nbar+e])/65535.0);;
+-					}
+-				}
++		//GxL needs to be projected on the right axis before summation into the grd field
++		//here we apply the projection scalar to the load prior to the actual convolution loop for more efficiency
++
++		//get projection
++		if (spatial_component==1){ //north
++			for (int ae=0;ae<loads->nactiveloads;ae++){
++				e=loads->combined_loads_index[ae];
++				horiz_projection[ae]=cos(2.0*M_PI*reCast<IssmDouble,int>(AzimIndex[av*nel+e])/65535.0); // 65535=2^16-1 = max value of 16 bits unsigned int
+ 			}
+-			else if (spatial_component==2){ //east
+-				for (e=0;e<nel;e++){
+-					horiz_projection[i*nel+e]=sin(2.0*M_PI*reCast<IssmDouble,int>(AzimIndex[i*nel+e])/65535.0);
++			for(l=0;l<SLGEOM_NUMLOADS;l++){
++				nbar=slgeom->nbar[l];
++				for (ae=0;ae<loads->nactivesubloads[l];ae++){
++					e=loads->combined_subloads_index[l][ae];
++					horiz_projectionsub[l][ae]=cos(2.0*M_PI*reCast<IssmDouble,int>(AzimIndexsub[l][av*nbar+e])/65535.0);
+ 				}
+-				for(l=0;l<SLGEOM_NUMLOADS;l++){
+-					nbar=slgeom->nbar[l];
+-					for (e=0;e<nbar;e++){
+-						horiz_projectionsub[l][i*nbar+e]=sin(2.0*M_PI*reCast<IssmDouble,int>(AzimIndexsub[l][i*nbar+e])/65535.0);;
+-					}
+-				}
+ 			}
+-			for (e=0;e<nel;e++) Centroid_loads[e]=Centroid_loads_copy[e]*horiz_projection[i*nel+e];
++		}
++		else if (spatial_component==2){ //east
++			for (int ae=0;ae<loads->nactiveloads;ae++){
++				e=loads->combined_loads_index[ae];
++				horiz_projection[ae]=sin(2.0*M_PI*reCast<IssmDouble,int>(AzimIndex[av*nel+e])/65535.0);
++			}
+ 			for(l=0;l<SLGEOM_NUMLOADS;l++){
+ 				nbar=slgeom->nbar[l];
+-				for (e=0;e<nbar;e++){
+-					Subelement_loads[l][e]=Subelement_loads_copy[l][e]*horiz_projectionsub[l][i*nbar+e];
++				for (ae=0;ae<loads->nactivesubloads[l];ae++){
++					e=loads->combined_subloads_index[l][ae];
++					horiz_projectionsub[l][ae]=sin(2.0*M_PI*reCast<IssmDouble,int>(AzimIndexsub[l][av*nbar+e])/65535.0);
+ 				}
+ 			}
+-		} /*}}}*/
++		}
+ 
+-		for (e=0;e<nel;e++){
++		//project load in the right direction 
++		for (int ae=0;ae<loads->nactiveloads;ae++){
++			projected_loads[ae]=loads->combined_loads[ae]*horiz_projection[ae];
++		}
++		for(l=0;l<SLGEOM_NUMLOADS;l++){
++			nbar=slgeom->nbar[l];
++			for (ae=0;ae<loads->nactivesubloads[l];ae++){
++				projected_subloads[l][ae]=loads->combined_subloads[l][ae]*horiz_projectionsub[l][ae];
++			}
++		}
++
++		//do the convolution
++		c=av*nel;
++		for (int ae=0;ae<loads->nactiveloads;ae++){
++			e=loads->combined_loads_index[ae];
++			a=AlphaIndex[c+e]*viscousnumsteps;
+ 			for(t=0;t<nt;t++){
+-				a=AlphaIndex[i*nel+e];
+-				grdfield[i*nt+t]+=G[a*viscousnumsteps+t]*Centroid_loads[e];
++				grdfield[b+t]+=G[a+t]*projected_loads[ae];
+ 			}
+ 		}
+ 		for(l=0;l<SLGEOM_NUMLOADS;l++){
+ 			nbar=slgeom->nbar[l];
+-			for (e=0;e<nbar;e++){
++			c=av*nbar;
++			for (ae=0;ae<loads->nactivesubloads[l];ae++){
++				e=loads->combined_subloads_index[l][ae];
++				a=AlphaIndexsub[l][c+e]*viscousnumsteps;
+ 				for(t=0;t<nt;t++){
+-					a=AlphaIndexsub[l][i*nbar+e];
+-					grdfield[i*nt+t]+=G[a*viscousnumsteps+t]*Subelement_loads[l][e];
++					grdfield[b+t]+=G[a+t]*projected_subloads[l][ae];
+ 				}
+ 			}
+ 		}
++		//av+=1;
+ 	} /*}}}*/
+ 
+ 
++	//free resources
+ 
+-	if(computeviscous){ /*{{{*/
++	xDelete<IssmDouble>(horiz_projection);
++	xDelete<IssmDouble>(projected_loads);
++	for(l=0;l<SLGEOM_NUMLOADS;l++) {
++		xDelete<IssmDouble>(projected_subloads[l]);
++		xDelete<IssmDouble>(horiz_projectionsub[l]);
++	}
++	return grdfield;
++
++} /*}}}*/
++
++
++void       Tria::SealevelchangeCollectGrdfield(IssmDouble* grdfieldout, IssmDouble* grdfield, SealevelGeometry* slgeom, int nel, bool percpu, int viscousenum, bool computefuture) { /*{{{*/
++
++	//This function aligns grdfield with the requested output format: in a size 3 vector or in a size numberofvertices vector
++	// if compute viscous is on, we also interpolate the field timewise given the current timestepping as well as collect viscous deformation and update the viscous deformation time series for future time steps
++	int i,e,l,t,a, index, nbar, av, n_activevertices;
++	int nt=1;
++
++
++	//viscous
++	bool computeviscous=false;
++	int viscousindex=0; //important
++	int viscousnumsteps=1; //important
++	int* activevertices = NULL;
++	IssmDouble* viscousfield=NULL;
++	IssmDouble* grdfieldinterp=NULL;
++	IssmDouble* viscoustimes=NULL;
++	IssmDouble  final_time;
++	IssmDouble  lincoeff;
++	IssmDouble  timeacc;
++
++	//parameters & initialization
++	this->parameters->FindParam(&computeviscous,SolidearthSettingsViscousEnum);
++	this->inputs->GetIntArrayPtr(SealevelchangeConvolutionVerticesEnum,this->lid,&activevertices,&n_activevertices);
++
++	if(computeviscous){
++		this->parameters->FindParam(&viscousnumsteps,SealevelchangeViscousNumStepsEnum);
++		this->parameters->FindParam(&viscousindex,SealevelchangeViscousIndexEnum);
++		this->parameters->FindParam(&viscoustimes,NULL,SealevelchangeViscousTimesEnum);
++		this->parameters->FindParam(&final_time,TimesteppingFinalTimeEnum);
++		this->parameters->FindParam(&timeacc,SolidearthSettingsTimeAccEnum);
++		this->inputs->GetArrayPtr(viscousenum,this->lid,&viscousfield,NULL);
++		if(computefuture) {
++			nt=viscousnumsteps-viscousindex+2; //number of time steps remaining to reach final_time, +1 is sufficient with no adaptative time stepping, +2 necessary otherwise; we assume the safe choice here for the sake of simplicity
++			if (nt>viscousnumsteps) nt=viscousnumsteps;
++			grdfieldinterp=xNewZeroInit<IssmDouble>(3*viscousnumsteps); 
++		}
++		else nt=1;
++	}
++	
++
++	if(!computeviscous){ /*{{{*/
++		/*elastic or self attraction only case
++		/*store values computed on vertices, but don't repeat the computation if another element already computed it!:*/
++		if(percpu){
++			for(av=0;av<n_activevertices;av++) { //vertices
++				i=activevertices[av];
++				//if(slgeom->lids[this->vertices[i]->lid]!=this->lid)continue;
++				grdfieldout[this->vertices[i]->lid]=grdfield[i];
++				//}
++			}
++		}
++		else{
++			for(i=0;i<NUMVERTICES;i++) grdfieldout[i]=grdfield[i];
++		}
++		//free resources
++		xDelete<IssmDouble>(grdfield);
++		return;
++	}
++	else { //viscous case
+ 		// we need to do up to 3 things (* = only if computefuture)
+-		// 1*: add new grdfield contribution to the viscous stack for future time steps
+-		// 2: collect viscous grdfield from past loads due at present-day and add it to grdfield[current_time]
++		// 1: collect viscous grdfield from past loads due at present-day and add it to grdfield[current_time]
++		// 2*: add new grdfield contribution to the viscous stack for future time steps
+ 		// 3*: subtract from viscous stack the grdfield that has already been accounted for so we don't add it again at the next time step
+ 
++		/*update grdfield at present time using viscous stack at present time: */
++		for(av=0;av<n_activevertices;av++) { //vertices
++			i=activevertices[av];
++			//if(slgeom->lids[this->vertices[i]->lid]!=this->lid)continue;
++			grdfield[i*nt+0]+=viscousfield[i*viscousnumsteps+viscousindex]; 
++		}
++
++
+ 		/* Map new grdfield generated by present-day loads onto viscous time vector*/
+ 		if(computefuture){
+ 			//viscousindex time and first time step of grdfield coincide, so just copy that value
+-			for(int i=0;i<NUMVERTICES;i++){
+-				if(slgeom->lids[this->vertices[i]->lid]!=this->lid)continue;
+-				grdfieldinterp[i*viscousnumsteps+viscousindex]=  grdfield[i*nt+0];
++			for(av=0;av<n_activevertices;av++) { //vertices
++				i=activevertices[av];
++				//if(slgeom->lids[this->vertices[i]->lid]!=this->lid)continue;
++				grdfieldinterp[i*viscousnumsteps+viscousindex]=grdfield[i*nt+0];
+ 			}
+ 			if(viscoustimes[viscousindex]<final_time){
+ 				//And interpolate the rest of the points in the future
+ 				lincoeff=(viscoustimes[viscousindex+1]-viscoustimes[viscousindex])/timeacc;
+-				for(int t=viscousindex+1;t<viscousnumsteps;t++){
+-					for(int i=0;i<NUMVERTICES;i++){
+-						if(slgeom->lids[this->vertices[i]->lid]!=this->lid)continue;
+-						grdfieldinterp[i*viscousnumsteps+t] = (1-lincoeff)*grdfield[i*nt+(t-viscousindex-1)]
+-											 +lincoeff*grdfield[i*nt+(t-viscousindex)];
++				for(av=0;av<n_activevertices;av++) { //vertices
++					i=activevertices[av];
++					//if(slgeom->lids[this->vertices[i]->lid]!=this->lid)continue;
++					int i_time1= i*nt-viscousindex;
++					int i_time2= i*viscousnumsteps;
++					for(int t=viscousindex+1;t<viscousnumsteps;t++){
++						grdfieldinterp[i_time2+t] = (1-lincoeff)*grdfield[i_time1+t-1]
++									  +    lincoeff *grdfield[i_time1+t]
++									  +          viscousfield[i_time2+t];
++						/*update viscous stack with future deformation from present load: */
++						viscousfield[i_time2+t]=grdfieldinterp[i_time2+t]
++								       -grdfieldinterp[i_time2+viscousindex];
+ 					}
+ 				}
+ 			}
+-		}
+-
+-		/*update grdfield at present time using viscous stack at present time: */
+-		for(int i=0;i<NUMVERTICES;i++){
+-			if(slgeom->lids[this->vertices[i]->lid]!=this->lid)continue;
+-			grdfield[i*nt+0]+=viscousfield[i*viscousnumsteps+viscousindex]; 
+-		}
+-
+-		/*update viscous stack with future deformation from present load: */
+-		if(computefuture){
+-			for(int t=viscousnumsteps-1;t>=viscousindex;t--){ //we need to go backwards so as not to zero out viscousfield[i*viscousnumsteps+viscousindex] until the end
+-				for(int i=0;i<NUMVERTICES;i++){
+-					if(slgeom->lids[this->vertices[i]->lid]!=this->lid)continue;
+-					//offset viscousfield to remove all deformation that has already been added
+-					viscousfield[i*viscousnumsteps+t]+=grdfieldinterp[i*viscousnumsteps+t]
+-									  -grdfieldinterp[i*viscousnumsteps+viscousindex]
+-									  -viscousfield[i*viscousnumsteps+viscousindex];
+-				}
+-			}
+ 			/*Save viscous stack now that we updated the values:*/
+ 			this->inputs->SetArrayInput(viscousenum,this->lid,viscousfield,3*viscousnumsteps);
+-
+-			/*Free resources:*/
+-			xDelete<IssmDouble>(grdfieldinterp);
+ 		}
+-	} 
+-	/*}}}*/
+ 
+-	/*store values computed on vertices, but don't repeat the computation if another element already computed it!:*/
+-	if(percpu){
+-		for(i=0;i<NUMVERTICES;i++){
+-			if(slgeom->lids[this->vertices[i]->lid]==this->lid){
++		/*store values computed on vertices*/
++		if(percpu){
++			for(av=0;av<n_activevertices;av++) { //vertices
++				i=activevertices[av];
++				//if(slgeom->lids[this->vertices[i]->lid]!=this->lid)continue;
+ 				grdfieldout[this->vertices[i]->lid]=grdfield[i*nt+0];
++				//}
+ 			}
+ 		}
+-	}
+-	else{
+-		for(i=0;i<NUMVERTICES;i++) grdfieldout[i]=grdfield[i*nt+0];
+-	}
+-	//free resources
+-	xDelete<IssmDouble>(grdfield);
+-	xDelete<IssmDouble>(Centroid_loads);
+-	for(l=0;l<SLGEOM_NUMLOADS;l++) xDelete<IssmDouble>(Subelement_loads[l]);
+-	if (spatial_component!=0){
+-		xDelete<IssmDouble>(horiz_projection);
+-		xDelete<IssmDouble>(Centroid_loads_copy);
+-		for(l=0;l<SLGEOM_NUMLOADS;l++) {
+-			xDelete<IssmDouble>(Subelement_loads_copy[l]);
+-			xDelete<IssmDouble>(horiz_projectionsub[l]);
++		else{
++			for(i=0;i<NUMVERTICES;i++) grdfieldout[i]=grdfield[i*nt+0];
+ 		}
+-	}
+-	if (computeviscous){
++		//free resources
++		xDelete<IssmDouble>(grdfield);
+ 		xDelete<IssmDouble>(viscoustimes);
+ 		if (computefuture){
+ 			xDelete<IssmDouble>(grdfieldinterp);
+ 		}
++		/*}}}*/
+ 	}
+-
+ } /*}}}*/
+ 
+ void       Tria::SealevelchangeShift(GrdLoads* loads,  IssmDouble offset, SealevelGeometry* slgeom){ /*{{{*/
+Index: ../trunk-jpl/src/c/cores/love_core.cpp
+===================================================================
+--- ../trunk-jpl/src/c/cores/love_core.cpp	(revision 27307)
++++ ../trunk-jpl/src/c/cores/love_core.cpp	(revision 27308)
+@@ -11,34 +11,71 @@
+ #include "petscblaslapack.h"
+ #ifdef _HAVE_MPLAPACK_
+ #include <quadmath.h>
++#include <iostream>
+ #include "mpblas__Float128.h"
+ #include "mplapack__Float128.h"
++#include "mplapack_utils__Float128.h"
+ #endif
+ 
++template<typename doubletype> IssmDouble DownCastVarToDouble(doubletype var); // pure declaration
++
++template <> IssmDouble DownCastVarToDouble<IssmDouble>(IssmDouble var){
++	return var;
++}
++template <> IssmDouble DownCastVarToDouble<IssmComplex>(IssmComplex var){
++	return std::real(var);
++}
+ #ifdef _HAVE_MPLAPACK_
+-_Float128 a = 0.2345234534512079875620048770134538q;
++template <> IssmDouble DownCastVarToDouble<__float128>(__float128 var){
++	return static_cast<IssmDouble>(var);
++}
++__float128 pow(__float128 x, int y){
++	return powq(x,y);
++}
++__float128 pow(__float128 x, double y){
++	return powq(x,y);
++}
++__float128 pow(double x, __float128 y){
++	return powq(x,y);
++}
++
++ostream& operator<<(ostream& os, __float128 x){
++	char buf[128];
++	quadmath_snprintf(buf, sizeof(buf), "%.34Qf", x);
++
++    	os << buf;
++    	return os;
++}
+ #endif
+ 
+ /*local definitions:*/
+-class LoveVariables{  /*{{{*/
++template <class doubletype> class LoveVariables{  /*{{{*/
+ 
+ 	public: 
+-		IssmDouble g0; 
+-		IssmDouble r0;
+-		IssmDouble* EarthMass; 
+-		int nyi; 
++		doubletype g0; 
++		doubletype r0;
++		doubletype* EarthMass; 
++		int nyi, ifreq, nfreq; 
+ 		int starting_layer;
+ 		int* deg_layer_delete;
++		int* nstep;
++		doubletype* mu;
++		doubletype* la;
+ 
+ 		LoveVariables(){  /*{{{*/
+ 			g0=0;
+ 			r0=0;
+ 			EarthMass=NULL;
++			mu=NULL;
++			la=NULL;
+ 			nyi=0;
++			nfreq=0;
++			ifreq=0;
+ 			starting_layer=0;
++			nstep=NULL;
+ 			deg_layer_delete=NULL;
+ 		} /*}}}*/
+-		LoveVariables(IssmDouble* EarthMassin,IssmDouble g0in,IssmDouble r0in,int nyiin,int starting_layerin, int* deg_layer_deletein){  /*{{{*/
++		LoveVariables(doubletype* EarthMassin,doubletype g0in,doubletype r0in,int nyiin,int starting_layerin, int* deg_layer_deletein, int* nstepin){  /*{{{*/
+ 			EarthMass=EarthMassin;
+ 			g0=g0in;
+ 			r0=r0in;
+@@ -45,8 +82,18 @@
+ 			nyi=nyiin;
+ 			starting_layer=starting_layerin;
+ 			deg_layer_delete=deg_layer_deletein;
++			nstep=nstepin;
++			mu=NULL;
++			la=NULL;
++			nfreq=0;
++			ifreq=0;
+ 		} /*}}}*/
+-		~LoveVariables(){};
++		~LoveVariables(){
++			xDelete<int>(deg_layer_delete);
++			xDelete<int>(nstep);
++			if(mu)	xDelete<doubletype>(mu);
++			if(la)	xDelete<doubletype>(la);
++		};
+ }; /*}}}*/
+ 
+ template <class doubletype> class LoveNumbers{  /*{{{*/
+@@ -56,7 +103,7 @@
+ 		doubletype* K;
+ 		doubletype* L;
+ 		doubletype* Kernels;
+-		int sh_nmin, sh_nmax, nfreq, nkernels; 
++		int sh_nmin, sh_nmax, nfreq, nkernels, lower_row, nfreqtotal; 
+ 
+ 		LoveNumbers(){  /*{{{*/
+ 			H=NULL;
+@@ -68,10 +115,12 @@
+ 			nfreq=0;
+ 			nkernels=0;
+ 		} /*}}}*/
+-		LoveNumbers(int sh_nminin, int sh_nmaxin, int nfreqin, Matlitho* matlitho){  /*{{{*/
++		LoveNumbers(int sh_nminin, int sh_nmaxin, int nfreqin, int lower_rowin,int nfreqtotalin,Matlitho* matlitho){  /*{{{*/
+ 			sh_nmax=sh_nmaxin;
+ 			sh_nmin=sh_nminin;
+ 			nfreq=nfreqin;
++			lower_row=lower_rowin;
++			nfreqtotal=nfreqtotalin;
+ 			nkernels=(sh_nmax+1)*(matlitho->numlayers+1)*6;
+ 			H=xNewZeroInit<doubletype>(nfreq*(sh_nmax+1));
+ 			K=xNewZeroInit<doubletype>(nfreq*(sh_nmax+1));
+@@ -80,10 +129,14 @@
+ 		} /*}}}*/
+ 		void DownCastToDouble(LoveNumbers<IssmDouble>* LoveDouble){
+ 			for(int i=0;i<(sh_nmax+1)*nfreq;i++){
+-				LoveDouble->H[i]=std::real(H[i]);
+-				LoveDouble->K[i]=std::real(K[i]);
+-				LoveDouble->L[i]=std::real(L[i]);
++				LoveDouble->H[i]=DownCastVarToDouble<doubletype>(H[i]);
++				LoveDouble->K[i]=DownCastVarToDouble<doubletype>(K[i]);
++				LoveDouble->L[i]=DownCastVarToDouble<doubletype>(L[i]);
+ 			}
++			for(int i=0;i<nkernels*nfreq;i++){
++				LoveDouble->Kernels[i]=DownCastVarToDouble<doubletype>(Kernels[i]);
++			}
++
+ 		}
+ 		void LoveMPI_Gather(LoveNumbers<doubletype>* Love_local, int lower_row){
+ 			int* recvcounts=xNew<int>(IssmComm::GetSize());
+@@ -111,6 +164,44 @@
+ 			xDelete<int>(recvcounts);
+ 			xDelete<int>(displs);
+ 		}
++		void Broadcast(void){
++			//Intended only for IssmDouble type
++			Vector<IssmDouble>* vH;
++			Vector<IssmDouble>* vK;
++			Vector<IssmDouble>* vL;
++
++			vH= new Vector<IssmDouble>((sh_nmax+1)*nfreqtotal);
++			for(int i=0;i<(sh_nmax+1)*nfreq;i++) vH->SetValue(lower_row*(sh_nmax+1)+i,DownCastVarToDouble<doubletype>(H[i]),INS_VAL);
++			xDelete(H);
++			vH->Assemble();
++			H=vH->ToMPISerial();
++			delete vH;
++
++			vK= new Vector<IssmDouble>((sh_nmax+1)*nfreqtotal);
++			for(int i=0;i<(sh_nmax+1)*nfreq;i++) vK->SetValue(lower_row*(sh_nmax+1)+i,DownCastVarToDouble<doubletype>(K[i]),INS_VAL);
++			xDelete(K);
++			vK->Assemble();
++			K=vK->ToMPISerial();
++			delete vK;
++
++			vL= new Vector<IssmDouble>((sh_nmax+1)*nfreqtotal);
++			for(int i=0;i<(sh_nmax+1)*nfreq;i++) vL->SetValue(lower_row*(sh_nmax+1)+i,DownCastVarToDouble<doubletype>(L[i]),INS_VAL);
++			xDelete(L);
++			vL->Assemble();
++			L=vL->ToMPISerial();
++			delete vL;
++		}
++		void KernelBroadcast(void){
++			Vector<IssmDouble>* vKernels;
++			vKernels= new Vector<IssmDouble>(nkernels*nfreqtotal);
++			for(int i=0;i<nkernels*nfreq;i++){
++				vKernels->SetValue(lower_row*nkernels+i,DownCastVarToDouble<doubletype>(Kernels[i]),INS_VAL);
++			}
++			xDelete(Kernels);
++			vKernels->Assemble();
++			Kernels=vKernels->ToMPISerial();
++			delete vKernels;
++		}
+ 		void Copy(LoveNumbers<doubletype>* LoveDup){
+ 			for(int i=0;i<(sh_nmax+1)*nfreq;i++){
+ 				H[i]=LoveDup->H[i];
+@@ -127,8 +218,10 @@
+ 			xDelete<doubletype>(L);
+ 			xDelete<doubletype>(Kernels);
+ 		};
+-}; /*}}}*/
++};
+ 
++ /*}}}*/
++
+ /*self contained support routines used by cores below:*/
+ template<typename doubletype> doubletype                 angular_frequency(IssmDouble frequency); //pure declaration
+ template <> IssmDouble                     angular_frequency<IssmDouble>(IssmDouble frequency){ /*{{{*/
+@@ -138,6 +231,11 @@
+ 	IssmComplex value=reCast<IssmComplex>(complex<double>(0,1))*2.0*PI*reCast<IssmComplex>(frequency);
+ 	return value;
+ } /*}}}*/
++#ifdef _HAVE_MPLAPACK_
++template <> __float128                     angular_frequency<__float128>(IssmDouble frequency){ /*{{{*/
++	return 2.0*PI*frequency;
++} /*}}}*/
++#endif
+ template<typename doubletype> void                       allgesv(int* pnyi, int* pnrhs, doubletype* yilocal, int* plda, int* ipiv, doubletype* rhslocal, int* pldb, int* pinfo);
+ template <> void                           allgesv<IssmDouble>(int* pnyi, int* pnrhs, IssmDouble* yilocal, int* plda, int* ipiv, IssmDouble* rhslocal, int* pldb, int* pinfo){ /*{{{*/
+ 	dgesv_(pnyi, pnrhs, yilocal, plda, ipiv, rhslocal, pldb, pinfo);
+@@ -146,6 +244,24 @@
+ 	_error_("zgesv_ not linked correctly yet! ");
+ 	//zgesv_(pnyi, pnrhs, yilocal, plda, ipiv, rhslocal, pldb, pinfo);
+ } /*}}}*/
++#ifdef _HAVE_MPLAPACK_
++template <> void                           allgesv<__float128>(int* pnyi, int* pnrhs, __float128* yilocal, int* plda, int* ipiv, __float128* rhslocal, int* pldb, int* pinfo){ /*{{{*/
++	mplapackint nyi=*pnyi;
++	mplapackint nrhs=*pnrhs;
++	mplapackint lda=*plda;
++	mplapackint* qipiv=NULL;
++	mplapackint ldb=*pldb;
++	mplapackint info=0;
++	qipiv=xNewZeroInit<mplapackint>(*pnyi);
++	
++	Rgesv(nyi, nrhs, yilocal, lda, qipiv, rhslocal, ldb, info);
++
++	for (int i;i=0;i<*pnyi) ipiv[i]=qipiv[i];
++	*pinfo=info;
++	xDelete<mplapackint>(qipiv);
++} /*}}}*/
++#endif
++
+ template<typename doubletype> doubletype   factorial(int n){ /*{{{*/
+ 	doubletype prod=1;
+ 	for (int i=2;i<n+1;i++) prod*=i;
+@@ -218,7 +334,7 @@
+ 	//Computes Lovet for time step t and degree d from the PW coefficients xi and the corresponding 2*NTit frequency samples in Lovef
+ 
+ 	int indxi, indf;
+-	IssmDouble PW_test;
++	doubletype PW_test;
+ 	IssmDouble PW_threshold;
+ 	femmodel->parameters->FindParam(&PW_threshold,LovePostWidderThresholdEnum);
+ 
+@@ -260,53 +376,227 @@
+ 	}
+ 	Lovet[t*(sh_nmax+1)+d]=LoveM[NTit-1];
+ }/*}}}*/
+-template <typename doubletype> void        GetEarthRheology(doubletype* pla, doubletype* pmu, int layer_index, doubletype omega,  Matlitho* matlitho){ /*{{{*/
+ 
++template <typename doubletype> doubletype HypergeomTableLookup(doubletype z1, doubletype alpha, IssmDouble* h1, IssmDouble* z, int nz, int nalpha){/*{{{*/
++	int iz1, iz2, ialpha;	
++	doubletype lincoef;
++	doubletype hf,h00,h10, h01, h11, za, zd, ha, hb,hc,hd, m0,m1,t;
++	doubletype dalpha=1.0/(nalpha-1); // alpha table resolution given 0 <= alpha <= 1
++	ialpha= static_cast<int>(DownCastVarToDouble(alpha/dalpha));
++	lincoef=alpha/dalpha-ialpha;//linear fraction in [0;1] for alpha interpolation
++	iz1=nz;
++	for (int i=0;i<nz;i++){
++		if (abs(z[i])>abs(z1)) {
++			iz1=i-1;
++			break;
++		}
++	}
++
++	if (iz1<0){
++		//1-hf for very small abs(z) tends to 0, and is very log-linear with respect to log(z), so we can simply extrapolate the value of hf via the loglog slope
++		hf=(1.0-lincoef)*h1[ialpha*nz+0]+lincoef*h1[(ialpha+1)*nz+0];
++		hf=1.0- (1.0-hf)*pow(10.0,(log10(abs(z1))-log10(abs(z[0]))));
++		//hf[0]=1.0;
++	}
++	else if (iz1==nz){
++		//hf for very large abs(z) tends to 0, and is very log-linear with respect to log(z), so we can simply extrapolate the value of hf via the loglog slope
++		hf=(1.0-lincoef)*h1[ialpha*nz+nz-1]+lincoef*h1[(ialpha+1)*nz+nz-1];
++		hf=hf *pow(10.0,-(log10(abs(z1))-log10(abs(z[nz-1]))));
++		//hf[0]=0;
++	}
++	else{ //cubic spline interpolation
++		//edge cases: extrapolate 1 point
++		if (iz1==0){
++			za=2.0*z[0]-z[1];
++			ha=(1.0-lincoef)*h1[ialpha*nz+0]+lincoef*h1[(ialpha+1)*nz+0];
++			ha=1.0- (1.0-ha) *pow(10.0,log10(abs(za))-log10(abs(z[0])));
++		} 
++		else {
++			za=z[iz1-1];
++			ha=(1.0-lincoef)*h1[ialpha*nz+iz1-1] + lincoef*h1[(ialpha+1)*nz+iz1-1];
++		}
++
++		if (iz1==nz-2){
++			zd=2.0*z[nz-1]-z[nz-2];
++			hd=(1.0-lincoef)*h1[ialpha*nz+nz-1]+lincoef*h1[(ialpha+1)*nz+nz-1];
++			hd=hd *pow(10.0,-(log10(abs(zd))-log10(abs(z[nz-1]))));
++		} 
++		else {
++			zd=z[iz1+2];
++			hd=(1.0-lincoef)*h1[ialpha*nz+iz1+2]+lincoef*h1[(ialpha+1)*nz+iz1+2];
++		}
++
++		hb=(1.0-lincoef)*h1[ialpha*nz+iz1] +lincoef*h1[(ialpha+1)*nz+iz1];
++		hc=(1.0-lincoef)*h1[ialpha*nz+iz1+1] +lincoef*h1[(ialpha+1)*nz+iz1+1];
++
++		//left derivative
++		m0= 0.5*(z[iz1+1]-z[iz1])*((hc-hb)/(z[iz1+1]-z[iz1]) + (hb-ha)/(z[iz1]-za));
++		//right derivative
++		m1= 0.5*(z[iz1+1]-z[iz1])*((hd-hc)/(zd-z[iz1+1]) + (hc-hb)/(z[iz1+1]-z[iz1]));
++
++		//interpolation abscissa
++		t=(z1-z[iz1])/(z[iz1+1]-z[iz1]);
++		
++		//cubic spline functions
++		h00=2*pow(t,3)-3*pow(t,2)+1;
++		h10=pow(t,3)-2*pow(t,2)+t;
++		h01=-2*pow(t,3)+3*pow(t,2);
++		h11=pow(t,3)-pow(t,2);
++
++		hf=h00*hb + h10*m0 + h01*hc + h11*m1;
++	}
++	return hf;
++
++}/*}}}*/
++
++template <typename doubletype> doubletype muEBM(int layer_index, doubletype omega, Matlitho* matlitho, FemModel* femmodel); //pure declaration
++template <> IssmComplex muEBM<IssmComplex>(int layer_index, IssmComplex omega, Matlitho* matlitho, FemModel* femmodel){/*{{{*/
++	// Initialization
++	int nz, nalpha, dummy1, dummy2;
++	IssmComplex mu;
++	IssmDouble* z=NULL;
++	IssmDouble* h1=NULL;
++	IssmDouble* h2=NULL;
++	IssmComplex hf11, hf12, hf21, hf22;
++	IssmDouble  factor=0;
++	IssmComplex z1, z2;
++	IssmComplex U1, U2;
++	IssmComplex j=1i;
++	//Matlitho parameters
++	IssmDouble alpha=matlitho->ebm_alpha[layer_index];
++	IssmDouble delta=matlitho->ebm_delta[layer_index];
++	IssmDouble taul=matlitho->ebm_taul[layer_index];
++	IssmDouble tauh=matlitho->ebm_tauh[layer_index];
++	IssmDouble vi=matlitho->viscosity[layer_index];
++	IssmDouble mu0=matlitho->lame_mu[layer_index];
++	//fetch hypergeometric function tables and parameters
++	femmodel->parameters->FindParam(&nz,LoveHypergeomNZEnum);
++	femmodel->parameters->FindParam(&nalpha,LoveHypergeomNAlphaEnum);
++	femmodel->parameters->FindParam(&z,&dummy1,LoveHypergeomZEnum);
++	femmodel->parameters->FindParam(&h1,&dummy1,&dummy2,LoveHypergeomTable1Enum);
++	femmodel->parameters->FindParam(&h2,&dummy1,&dummy2,LoveHypergeomTable2Enum);
++	omega=omega/j;
++
++	z1= -pow(omega*tauh,2.0);
++	z2= -pow(omega*taul,2.0);
++	//Table1 h1 should be 2F1([1 1+alpha], [2+alpha/2], z)
++	//Table2 h2 should be 2F1([1 0.5+alpha], [1.5+alpha/2], z)
++	hf11=HypergeomTableLookup<IssmComplex>(z1, alpha, h1, z, nz, nalpha);
++	hf21=HypergeomTableLookup<IssmComplex>(z1, alpha, h2, z, nz, nalpha);
++	hf12=HypergeomTableLookup<IssmComplex>(z2, alpha, h1, z, nz, nalpha);
++	hf22=HypergeomTableLookup<IssmComplex>(z2, alpha, h2, z, nz, nalpha);
++
++
++	//Ivins et al (2020) p11
++	U1=(pow(tauh,alpha)-pow(taul,alpha))/alpha-pow(omega,2.0)/(2.0+alpha)*(pow(tauh,2.0+alpha)*hf11-pow(taul,2.0+alpha)*hf12);
++	U2=(pow(tauh,1.0+alpha)*hf21-pow(taul,1.0+alpha)*hf22)/(1.0+alpha);
++
++	factor= alpha*delta/(pow(tauh,alpha)-pow(taul,alpha));
++	U1=(1.0+factor) *U1;
++	U2=factor*omega*U2 +mu0/vi/omega;
++	mu=mu0*(U1+j*U2)/(pow(U1,2.0)+pow(U2,2.0));
++	omega=omega*j;
++
++	xDelete<IssmDouble>(z);
++	xDelete<IssmDouble>(h1);
++	xDelete<IssmDouble>(h2);
++	return mu;
++}/*}}}*/
++
++template <> IssmDouble muEBM<IssmDouble>(int layer_index, IssmDouble omega, Matlitho* matlitho, FemModel* femmodel){/*{{{*/
++	// Initialization
++	int nz, nalpha, dummy1, dummy2;
++	IssmDouble mu;
++	IssmDouble* z=NULL;
++	IssmDouble* h1=NULL;
++	IssmDouble hf11, hf12;
++	IssmDouble  factor, B, D, z1, z2;
++	//Matlitho parameters
++	IssmDouble alpha=matlitho->ebm_alpha[layer_index];
++	IssmDouble delta=matlitho->ebm_delta[layer_index];
++	IssmDouble taul=matlitho->ebm_taul[layer_index];
++	IssmDouble tauh=matlitho->ebm_tauh[layer_index];
++	IssmDouble vi=matlitho->viscosity[layer_index];
++	IssmDouble mu0=matlitho->lame_mu[layer_index];
++	//fetch hypergeometric function tables and parameters
++	femmodel->parameters->FindParam(&nz,LoveHypergeomNZEnum);
++	femmodel->parameters->FindParam(&nalpha,LoveHypergeomNAlphaEnum);
++	femmodel->parameters->FindParam(&z,&dummy1,LoveHypergeomZEnum);
++	femmodel->parameters->FindParam(&h1,&dummy1,&dummy2,LoveHypergeomTable1Enum);
++
++	z1=-omega*tauh;
++	z2=-omega*taul;
++	//Table1 h1 should be 2F1([1 1+alpha], [2+alpha], z)
++	hf11=HypergeomTableLookup<IssmDouble>(z1, alpha, h1, z, nz, nalpha);
++	hf12=HypergeomTableLookup<IssmDouble>(z2, alpha, h1, z, nz, nalpha);
++
++	//Ivins et al. (2022) p1979
++	factor= alpha*delta/(pow(tauh,alpha)-pow(taul,alpha));
++	B= factor/(1.0+alpha) *mu0/vi * (pow(tauh,1.0+alpha)*hf11 - pow(taul,1.0+alpha)*hf12);
++	D= omega*vi/mu0* 1.0/(1.0+omega*vi/mu0*(1.0+delta) -pow(omega*vi/mu0,2.0)*B);
++
++	xDelete<IssmDouble>(z);
++	xDelete<IssmDouble>(h1);
++	return mu=mu0*D;
++}/*}}}*/
++#ifdef _HAVE_MPLAPACK_
++template <> __float128 muEBM<__float128>(int layer_index, __float128 omega, Matlitho* matlitho, FemModel* femmodel){/*{{{*/
++	// Initialization
++	int nz, nalpha, dummy1, dummy2;
++	IssmDouble* z=NULL;
++	IssmDouble* h1=NULL;
++	__float128 mu;
++	__float128 hf11, hf12;
++	__float128  factor, B, D, z1, z2;
++	//Matlitho parameters
++	__float128 alpha=matlitho->ebm_alpha[layer_index];
++	__float128 delta=matlitho->ebm_delta[layer_index];
++	__float128 taul=matlitho->ebm_taul[layer_index];
++	__float128 tauh=matlitho->ebm_tauh[layer_index];
++	__float128 vi=matlitho->viscosity[layer_index];
++	__float128 mu0=matlitho->lame_mu[layer_index];
++	//fetch hypergeometric function tables and parameters
++	femmodel->parameters->FindParam(&nz,LoveHypergeomNZEnum);
++	femmodel->parameters->FindParam(&nalpha,LoveHypergeomNAlphaEnum);
++	femmodel->parameters->FindParam(&z,&dummy1,LoveHypergeomZEnum);
++	femmodel->parameters->FindParam(&h1,&dummy1,&dummy2,LoveHypergeomTable1Enum);
++
++	z1=-(omega*tauh);
++	z2=-(omega*taul);
++	//Table1 h1 should be 2F1([1 1+alpha], [2+alpha], z)
++	hf11=HypergeomTableLookup<__float128>(z1, alpha, h1, z, nz, nalpha);
++	hf12=HypergeomTableLookup<__float128>(z2, alpha, h1, z, nz, nalpha);
++
++	//Ivins et al. (2022) p1979
++	//Note: therein, mu(s') = s'*mu~(s'); s'=omega*tauM=omega*vi/mu0
++	factor= alpha*delta/(pow(tauh,alpha)-pow(taul,alpha));
++	B= factor/(1.0q+alpha) *mu0/vi * (pow(tauh,1.0q+alpha)*hf11 - pow(taul,1.0q+alpha)*hf12);
++	D= omega*vi/mu0* 1.0q/(1.0q+omega*vi/mu0*(1.0q+delta) -pow(omega*vi/mu0,2.0q)*B);
++
++	xDelete<IssmDouble>(z);
++	xDelete<IssmDouble>(h1);
++	return mu=mu0*D;
++}/*}}}*/
++#endif
++template <typename doubletype> void        GetEarthRheology(doubletype* pla, doubletype* pmu, int layer_index, doubletype omega,  Matlitho* matlitho, FemModel* femmodel){ /*{{{*/
++
+ 	//returns lame parameters (material rigity) lambda and mu for the right frequency and layer
+ 	doubletype mu,la;
+ 
+-	IssmDouble vi=matlitho->viscosity[layer_index];
+-	IssmDouble mu0=matlitho->lame_mu[layer_index];
+-	IssmDouble la0=matlitho->lame_lambda[layer_index];
++	doubletype vi=matlitho->viscosity[layer_index];
++	doubletype mu0=matlitho->lame_mu[layer_index];
++	doubletype la0=matlitho->lame_lambda[layer_index];
+ 	int rheo=matlitho->rheologymodel[layer_index];
+ 
+ 	if (vi!=0 && omega!=0.0){ //take into account viscosity in the rigidity if the material isn't a perfect fluid
+-		IssmDouble ka=la0 + 2.0/3.0*mu0; //Bulk modulus
++		doubletype ka=la0 + 2.0/3.0*mu0; //Bulk modulus
+ 		if (rheo==2){//EBM
+-			IssmDouble alpha=matlitho->ebm_alpha[layer_index];
+-			IssmDouble delta=matlitho->ebm_delta[layer_index];
+-			IssmDouble taul=matlitho->ebm_taul[layer_index];
+-			IssmDouble tauh=matlitho->ebm_tauh[layer_index];
+-			IssmDouble hf1,hf2;
+-			doubletype U1,U2;
+-			IssmDouble* a=xNew<IssmDouble>(2);
+-			IssmDouble* b=xNew<IssmDouble>(1);
+-
+-			a[0]=1.0;a[1]=1.0+alpha/2.0;
+-			b[0]=2.0+alpha/2.0;
+-			//hf1=HypergeometricFunctionx(a, b, 2, 1, -pow(omega*tauh,2.0), 0, 0, 15);
+-			//hf2=HypergeometricFunctionx(a, b, 2, 1, -pow(omega*taul,2.0), 0, 0, 15);
+-			//hf1=hypergeometric_pFq({a[0], a[1]}, {b[0]},-pow(omega*tauh,2.0));
+-			//hf2=hypergeometric_pFq_({a[0], a[1]}, {b[0]},-pow(omega*taul,2.0));
+-			U1=(pow(tauh,alpha)-pow(taul,alpha))/alpha-pow(omega,2.0)/(2.0+alpha)*(pow(tauh,2.0+alpha)*hf1-pow(taul,2.0+alpha)*hf2);
+-
+-			a[0]=1.0;a[1]=.5+alpha/2.0;
+-			b[0]=1.5+alpha/2.0;
+-			//hf1=HypergeometricFunctionx(a, b, 2, 1, -pow(omega*tauh,2.0), 0, 0, 15);
+-			//hf2=HypergeometricFunctionx(a, b, 2, 1, -pow(omega*taul,2.0), 0, 0, 15);
+-			//hf1=hypergeometric_pFq({a[0], a[1]}, {b[0]},-pow(omega*tauh,2.0));
+-			//hf2=hypergeometric_pFq({a[0], a[1]}, {b[0]},-pow(omega*taul,2.0));
+-			U2=(pow(tauh,1.0+alpha)*hf1-pow(taul,1.0+alpha)*hf2)/(1.0+alpha);
+-
+-			mu=mu/(1.0+ alpha*delta/(pow(tauh,alpha)-pow(taul,alpha))*(U1 + omega*U2) -mu/vi/omega);
++			mu=muEBM<doubletype>(layer_index, omega, matlitho, femmodel);
+ 			la=ka-2.0/3.0*mu;
+-
+-			xDelete<IssmDouble>(a);
+-			xDelete<IssmDouble>(b);
+ 		} 
+ 		else if (rheo==1){//Burgers
+-			IssmDouble vi2=matlitho->burgers_viscosity[layer_index];
+-			IssmDouble mu2=matlitho->burgers_mu[layer_index];
++			doubletype vi2=matlitho->burgers_viscosity[layer_index];
++			doubletype mu2=matlitho->burgers_mu[layer_index];
+ 
+ 			mu=mu0*omega*(omega+mu2/vi2)/((omega+mu2/vi2)*(omega+mu0/vi)+mu0/vi2*omega);
+ 			la=ka-2.0/3.0*mu;
+@@ -320,20 +610,42 @@
+ 	la=la0;
+ 	mu=mu0;
+ 	}
++
+ 	*pla=la;
+ 	*pmu=mu;
+ 
+ } /*}}}*/
+-IssmDouble                                 GetGravity(IssmDouble r2, int layer_index, FemModel* femmodel, Matlitho* matlitho,LoveVariables* vars){ /*{{{*/
++
++template <typename doubletype> void        EarthRheology(LoveVariables<doubletype>* vars, IssmDouble* frequencies, int nfreq,  Matlitho* matlitho, FemModel* femmodel){/*{{{*/
++	doubletype omega;
++	//reset pointers to NULL if this function was previously called
++	if(vars->mu)	xDelete<doubletype>(vars->mu);
++	if(vars->la)	xDelete<doubletype>(vars->la);
++	//precompute rheology at the requested frequencies
++	vars->mu=xNewZeroInit<doubletype>(nfreq*matlitho->numlayers);
++	vars->la=xNewZeroInit<doubletype>(nfreq*matlitho->numlayers);
++	vars->nfreq=nfreq;
++	for (int i=0;i<matlitho->numlayers;i++){
++		for (int fr=0;fr<nfreq;fr++){
++			omega=angular_frequency<doubletype>(frequencies[fr]);
++			GetEarthRheology<doubletype>(&vars->la[i*nfreq+fr], &vars->mu[i*nfreq+fr], i,omega,matlitho, femmodel);
++			//cout << i << " " << fr << " " << vars->mu[i*nfreq+fr] << "\n";
++		}
++	}
++}/*}}}*/
++
++template <typename doubletype> doubletype	GetGravity(doubletype r2, int layer_index, FemModel* femmodel, Matlitho* matlitho,LoveVariables<doubletype>* vars){ /*{{{*/
+ 	//computes gravity at radius r2
+-	IssmDouble* EarthMass;
+-	IssmDouble g, GG;
++	doubletype* EarthMass;
++	doubletype g, GG;
++	IssmDouble GGp;
+ 
+ 	EarthMass=vars->EarthMass;
+-	femmodel->parameters->FindParam(&GG,LoveGravitationalConstantEnum);
+-	IssmDouble ro=matlitho->density[layer_index];
+-	IssmDouble M=0;
+-	IssmDouble r1=0;
++	femmodel->parameters->FindParam(&GGp,LoveGravitationalConstantEnum);
++	GG=GGp;
++	doubletype ro=matlitho->density[layer_index];
++	doubletype M=0;
++	doubletype r1=0;
+ 	if (layer_index==0){
+ 		M=4.0/3.0*PI*ro*pow(r2,3.0);
+ 	}
+@@ -343,23 +655,25 @@
+ 	}
+ 	return	g= GG*M/pow(r2,2.0);
+ }/*}}}*/
+-template <typename doubletype> void        fill_yi_prefactor(doubletype* yi_prefactor, int* pdeg, doubletype* pomega, FemModel* femmodel, Matlitho* matlitho, LoveVariables* vars){ /*{{{*/
++template <typename doubletype> void        fill_yi_prefactor(doubletype* yi_prefactor, int* pdeg, doubletype* pomega, FemModel* femmodel, Matlitho* matlitho, LoveVariables<doubletype>* vars){ /*{{{*/
+ 	//precalculates partial derivative factors for function yi_derivatives
+-	IssmDouble ra=matlitho->radius[matlitho->numlayers];
+-	IssmDouble  g0,r0,mu0, GG;
+-	int nstep,nindex, starting_layer;
++	doubletype ra=matlitho->radius[matlitho->numlayers];
++	doubletype  g0,r0,mu0;
++	IssmDouble mu0p, GG;
++	int nstep,nsteps,nindex, starting_layer;
+ 
+-	femmodel->parameters->FindParam(&mu0,LoveMu0Enum);
++	femmodel->parameters->FindParam(&mu0p,LoveMu0Enum);
+ 	femmodel->parameters->FindParam(&GG,LoveGravitationalConstantEnum);
+-	femmodel->parameters->FindParam(&nstep,LoveIntStepsPerLayerEnum);
++	//femmodel->parameters->FindParam(&nstep,LoveIntStepsPerLayerEnum);
+ 
+ 	g0=vars->g0;
+ 	r0=vars->r0;
++	mu0=mu0p;
+ 	starting_layer=vars->starting_layer;
+ 
+ 	doubletype frh,frhg0,fgr0,fgr,fn,rm0,rlm,flm;
+-	IssmDouble xmin,xmax,x,dr;
+-	IssmDouble g,ro, issolid;
++	doubletype xmin,xmax,x,dr;
++	doubletype g,ro, issolid;
+ 
+ 	if (pomega) { //frequency and degree dependent terms /*{{{*/
+ 		doubletype la,mu;
+@@ -369,11 +683,16 @@
+ 		fn=deg*(deg+1.0);
+ 
+ 		for (int layer_index=starting_layer;layer_index<matlitho->numlayers;layer_index++){
++			nstep=vars->nstep[layer_index];
++			nsteps=0;
++			for (int i=0;i<layer_index;i++)	nsteps+=vars->nstep[i];
+ 
+ 			ro=matlitho->density[layer_index];
+ 			issolid=matlitho->issolid[layer_index];
+ 			if(issolid==1){
+-				GetEarthRheology<doubletype>(&la, &mu,layer_index,omega,matlitho);   
++				//GetEarthRheology<doubletype>(&la, &mu,layer_index,omega,matlitho);   
++				mu=vars->mu[layer_index*vars->nfreq+vars->ifreq];
++				la=vars->la[layer_index*vars->nfreq+vars->ifreq];
+ 
+ 				/*_______Expressions*/
+ 				flm=(la+2.0*mu);
+@@ -385,7 +704,7 @@
+ 				f[1]=mu0/flm;
+ 				f[2]=(la*fn/flm);
+ 				f[3]=rm0*rlm;
+-				f[4]=ro*pow(omega,2.0)*ra/mu0;
++				f[4]=-ro*pow(omega,2.0)*ra*ra/mu0;
+ 				f[5]=(-4.0*mu/flm);
+ 				f[6]=fn*frh;
+ 				f[7]=-(2.0*rm0*rlm)*fn;
+@@ -398,10 +717,14 @@
+ 				xmax=(matlitho->radius[layer_index+1])/ra;
+ 				dr = (xmax -xmin)/nstep;
+ 				x=xmin;
++
++				//fixme
++				g=GetGravity<doubletype>((xmin+xmax)/2*ra,layer_index,femmodel,matlitho,vars);
++
+ 				for (int n=0;n<nstep;n++){
+-					g=GetGravity(x*ra,layer_index,femmodel,matlitho,vars);
+ 
+-					nindex=layer_index*nstep*36+n*36;
++					g=GetGravity<doubletype>(x*ra,layer_index,femmodel,matlitho,vars);
++					nindex=nsteps*36+n*36;
+ 					yi_prefactor[nindex+ 0*6+0]= f[0]/x;                      // in dy[0*6+0]
+ 					yi_prefactor[nindex+ 0*6+1]= f[1];                        // in dy[0*6+1]
+ 					yi_prefactor[nindex+ 0*6+2]= f[2]/x;                      // in dy[0*6+2]
+@@ -422,6 +745,10 @@
+ 		fn=(deg*(deg+1.0));
+ 
+ 		for (int layer_index=starting_layer;layer_index<matlitho->numlayers;layer_index++){
++			nstep=vars->nstep[layer_index];
++			nsteps=0;
++			for (int i=0;i<layer_index;i++)	nsteps+=vars->nstep[i];
++
+ 			ro=matlitho->density[layer_index];
+ 			issolid=matlitho->issolid[layer_index];
+ 
+@@ -432,9 +759,14 @@
+ 			xmax=(matlitho->radius[layer_index+1])/ra;
+ 			dr = (xmax -xmin)/nstep;
+ 			x=xmin;
++
++
++				//fixme
++				g=GetGravity<doubletype>((xmin+xmax)/2*ra,layer_index,femmodel,matlitho,vars);
++
+ 			for (int n=0;n<nstep;n++){
+-				nindex=layer_index*nstep*36+n*36;
+-				g=GetGravity(x*ra,layer_index,femmodel,matlitho,vars);
++				nindex=nsteps*36+n*36;
++				g=GetGravity<doubletype>(x*ra,layer_index,femmodel,matlitho,vars);
+ 
+ 				if(issolid==1){
+ 					yi_prefactor[nindex+ 1*6+3]= fn/x;                  // in dy[1*6+3]
+@@ -449,6 +781,10 @@
+ 		/*}}}*/
+ 	} else { // static terms /*{{{*/
+ 		for (int layer_index=starting_layer;layer_index<matlitho->numlayers;layer_index++){
++			nstep=vars->nstep[layer_index];
++			nsteps=0;
++			for (int i=0;i<layer_index;i++)	nsteps+=vars->nstep[i];
++
+ 			ro=matlitho->density[layer_index];
+ 			issolid=matlitho->issolid[layer_index];
+ 
+@@ -460,9 +796,11 @@
+ 			xmax=(matlitho->radius[layer_index+1])/ra;
+ 			dr = (xmax -xmin)/nstep;
+ 			x=xmin;
++				//fixme
++				g=GetGravity<doubletype>((xmin+xmax)/2*ra,layer_index,femmodel,matlitho,vars);
+ 			for (int n=0;n<nstep;n++){
+-				g=GetGravity(x*ra,layer_index,femmodel,matlitho,vars);
+-				nindex=layer_index*nstep*36+n*36;
++				g=GetGravity<doubletype>(x*ra,layer_index,femmodel,matlitho,vars);
++				nindex=nsteps*36+n*36;
+ 				if(issolid==1){
+ 					yi_prefactor[nindex+ 1*6+5]= -frhg0;       // in dy[1*6+5]
+ 					yi_prefactor[nindex+ 2*6+0]= -1.0/x;       // in dy[2*6+0]
+@@ -483,13 +821,17 @@
+ 		/*}}}*/
+ 	}
+ }/*}}}*/
+-template <typename doubletype> void        yi_derivatives(doubletype* dydx, doubletype* y, int layer_index, int n, doubletype* yi_prefactor, FemModel* femmodel, Matlitho* matlitho){ /*{{{*/
++template <typename doubletype> void        yi_derivatives(doubletype* dydx, doubletype* y, int layer_index, int n, doubletype* yi_prefactor, FemModel* femmodel, Matlitho* matlitho, LoveVariables<doubletype>* vars){ /*{{{*/
+ 	//computes yi derivatives at r=radius[layer_index]+ n/nstep*(radius[layer_index+1]-radius[layer_index])
+ 
+-	IssmDouble issolid=matlitho->issolid[layer_index];
+-	int iy,id,ny, nindex, nstep;
+-	femmodel->parameters->FindParam(&nstep,LoveIntStepsPerLayerEnum);
++	int issolid=matlitho->issolid[layer_index];
++	int iy,id,ny, nindex, nstep, nsteps;
++	//femmodel->parameters->FindParam(&nstep,LoveIntStepsPerLayerEnum);
+ 
++	nstep=vars->nstep[layer_index];
++	nsteps=0;
++	for (int i=0;i<layer_index;i++) nsteps+=vars->nstep[i];
++
+ 	/*{{{*/ /* For reference:
+ 			   flm=(la+2.0*mu);
+ 			   rlm=(3.0*la+2.0*mu)/(la+2.0*mu);
+@@ -551,8 +893,10 @@
+ 			   dy[0*6+1]= 1.0;
+ 			   dy[1*6+0]= (-4.0*(fgr/rg0)+fn/x)/x;
+ 			   dy[1*6+1]= -2.0/x-fgr/rg0;
++
+ 			   }
+ 	*/ /*}}}*/
++	nindex=nsteps*36+n*36;
+ 
+ 	if(issolid==1){
+ 		ny = 6;
+@@ -563,23 +907,24 @@
+ 	for (id=0;id<ny;id++){
+ 		dydx[id]=0.0;
+ 		for (iy=0;iy<ny;iy++){
+-			nindex=layer_index*nstep*36+n*36;
+ 			dydx[id]+=yi_prefactor[nindex+id*6+iy]*y[iy];
+ 		}
+ 	}
+ 	return;
+ }/*}}}*/
+-template <typename doubletype> void        propagate_yi_euler(doubletype* y, IssmDouble xmin, IssmDouble xmax, int layer_index, doubletype* yi_prefactor, FemModel* femmodel, Matlitho* matlitho){ /*{{{*/
+-	//yields this: if we have y[j]=1.0 and y[!j]=0.0 at the bottom of the layer, what is y at the top of the layer?
++template <typename doubletype> void        propagate_yi_euler(doubletype* y, doubletype xmin, doubletype xmax, int layer_index, doubletype* yi_prefactor, FemModel* femmodel, Matlitho* matlitho, LoveVariables<doubletype>* vars){ /*{{{*/
++	//computes this: if we have y[j]=1.0 and y[!j]=0.0 at the bottom of the layer, what is y at the top of the layer?
+ 	//euler method
+ 	int nstep;
+-	femmodel->parameters->FindParam(&nstep,LoveIntStepsPerLayerEnum); 
++	//femmodel->parameters->FindParam(&nstep,LoveIntStepsPerLayerEnum); 
++	nstep=vars->nstep[layer_index];
+ 
++
+ 	doubletype* dydx=xNewZeroInit<doubletype>(6);
+-	IssmDouble dr = (xmax -xmin)/nstep;
+-	IssmDouble x=xmin;
++	doubletype dr = (xmax -xmin)/nstep;
++	doubletype x=xmin;
+ 	for(int i = 0;i<nstep;i++){
+-		yi_derivatives<doubletype>(dydx,y,layer_index, i,yi_prefactor,femmodel,matlitho);
++		yi_derivatives<doubletype>(dydx,y,layer_index, i,yi_prefactor,femmodel,matlitho,vars);
+ 		for (int j=0;j<6;j++){
+ 			y[j]+=dydx[j]*dr;
+ 		}
+@@ -587,11 +932,12 @@
+ 	}
+ 	xDelete<doubletype>(dydx);
+ }/*}}}*/
+-template <typename doubletype> void        propagate_yi_RK2(doubletype* y, IssmDouble xmin, IssmDouble xmax, int layer_index, doubletype* yi_prefactor, FemModel* femmodel, Matlitho* matlitho){ /*{{{*/
+-	//yields this: if we have y[j]=1.0 and y[!j]=0.0 at the bottom of the layer, what is y at the top of the layer?
++template <typename doubletype> void        propagate_yi_RK2(doubletype* y, doubletype xmin, doubletype xmax, int layer_index, doubletype* yi_prefactor, FemModel* femmodel, Matlitho* matlitho, LoveVariables<doubletype>* vars){ /*{{{*/
++	//computes this: if we have y[j]=1.0 and y[!j]=0.0 at the bottom of the layer, what is y at the top of the layer?
+ 	//Implements Runge-Kutta 2nd order (midpoint method)
+ 	int nstep;
+-	femmodel->parameters->FindParam(&nstep,LoveIntStepsPerLayerEnum); 
++	//femmodel->parameters->FindParam(&nstep,LoveIntStepsPerLayerEnum); 
++	nstep=vars->nstep[layer_index];
+ 
+ 	doubletype k1[6]={0};
+ 	doubletype k2[6]={0};
+@@ -601,13 +947,13 @@
+ 	doubletype y2[6]={0};
+ 	doubletype y3[6]={0};
+ 
+-	IssmDouble dr = (xmax -xmin)/nstep;
+-	IssmDouble x=xmin;
++	doubletype dr = (xmax -xmin)/nstep;
++	doubletype x=xmin;
+ 
+ 	for(int i = 0;i<nstep/2;i++){
+-		yi_derivatives<doubletype>(k1,y,layer_index, 2*i,yi_prefactor,femmodel,matlitho);
++		yi_derivatives<doubletype>(k1,y,layer_index, 2*i,yi_prefactor,femmodel,matlitho,vars);
+ 		for (int j=0;j<6;j++) {y1[j]=y[j]+k1[j]*dr;}
+-		yi_derivatives<doubletype>(k2,y1,layer_index, 2*i+1,yi_prefactor,femmodel,matlitho);		
++		yi_derivatives<doubletype>(k2,y1,layer_index, 2*i+1,yi_prefactor,femmodel,matlitho,vars);		
+ 
+ 		for (int j=0;j<6;j++){
+ 			y[j]+=k2[j]*2.0*dr;
+@@ -615,30 +961,31 @@
+ 		x = x + 2.0*dr;
+ 	}
+ }/*}}}*/
+-template <typename doubletype> void        propagate_yi_RK4(IssmDouble* y, IssmDouble xmin, IssmDouble xmax, int layer_index, IssmDouble* yi_prefactor, FemModel* femmodel, Matlitho* matlitho){ /*{{{*/
+-	//yields this: if we have y[j]=1.0 and y[!j]=0.0 at the bottom of the layer, what is y at the top of the layer?
++	template <typename doubletype> void        propagate_yi_RK4(doubletype* y, doubletype xmin, doubletype xmax, int layer_index, doubletype* yi_prefactor, FemModel* femmodel, Matlitho* matlitho,LoveVariables<doubletype>* vars){ /*{{{*/
++	//computes this: if we have y[j]=1.0 and y[!j]=0.0 at the bottom of the layer, what is y at the top of the layer?
+ 	//Implements Runge-Kutta 4th order
+ 	int nstep;
+-	femmodel->parameters->FindParam(&nstep,LoveIntStepsPerLayerEnum); 
++	//femmodel->parameters->FindParam(&nstep,LoveIntStepsPerLayerEnum); 
++	nstep=vars->nstep[layer_index];
+ 
+-	IssmDouble* k1=xNewZeroInit<IssmDouble>(6);
+-	IssmDouble* k2=xNewZeroInit<IssmDouble>(6);
+-	IssmDouble* k3=xNewZeroInit<IssmDouble>(6);
+-	IssmDouble* k4=xNewZeroInit<IssmDouble>(6);
+-	IssmDouble* y1=xNewZeroInit<IssmDouble>(6);
+-	IssmDouble* y2=xNewZeroInit<IssmDouble>(6);
+-	IssmDouble* y3=xNewZeroInit<IssmDouble>(6);
++	doubletype k1[6]={0};
++	doubletype k2[6]={0};
++	doubletype k3[6]={0};
++	doubletype k4[6]={0};
++	doubletype y1[6]={0};
++	doubletype y2[6]={0};
++	doubletype y3[6]={0};
+ 
+-	IssmDouble dr = (xmax -xmin)/nstep;
+-	IssmDouble x=xmin;
++	doubletype dr = (xmax -xmin)/nstep;
++	doubletype x=xmin;
+ 	for(int i = 0;i<nstep/2-1;i++){
+-		yi_derivatives<doubletype>(k1,y,layer_index, 2*i,yi_prefactor,femmodel,matlitho);
++		yi_derivatives<doubletype>(k1,y,layer_index, 2*i,yi_prefactor,femmodel,matlitho,vars);
+ 		for (int j=0;j<6;j++) {y1[j]=y[j]+k1[j]*dr;}
+-		yi_derivatives<doubletype>(k2,y1,layer_index, 2*i+1,yi_prefactor,femmodel,matlitho);
++		yi_derivatives<doubletype>(k2,y1,layer_index, 2*i+1,yi_prefactor,femmodel,matlitho,vars);
+ 		for (int j=0;j<6;j++) {y2[j]=y[j]+k2[j]*dr;}
+-		yi_derivatives<doubletype>(k3,y2,layer_index, 2*i+1,yi_prefactor,femmodel,matlitho);
++		yi_derivatives<doubletype>(k3,y2,layer_index, 2*i+1,yi_prefactor,femmodel,matlitho,vars);
+ 		for (int j=0;j<6;j++) {y3[j]=y[j]+k3[j]*2.0*dr;}
+-		yi_derivatives<doubletype>(k4,y3,layer_index, 2*i+2,yi_prefactor,femmodel,matlitho);		
++		yi_derivatives<doubletype>(k4,y3,layer_index, 2*i+2,yi_prefactor,femmodel,matlitho,vars);		
+ 
+ 		for (int j=0;j<6;j++){
+ 			y[j]+=(k1[j]+2.0*k2[j]+2.0*k3[j]+k4[j])/3.0*dr;		
+@@ -648,13 +995,13 @@
+ 
+ 	//Last step: we don't know the derivative at xmax, so we will assume the values at xmax-dr
+ 	int i=nstep/2;
+-	yi_derivatives<doubletype>(k1,y,layer_index, 2*i,yi_prefactor,femmodel,matlitho);
++	yi_derivatives<doubletype>(k1,y,layer_index, 2*i,yi_prefactor,femmodel,matlitho,vars);
+ 	for (int j=0;j<6;j++) {y1[j]=y[j]+k1[j]*dr;}
+-	yi_derivatives<doubletype>(k2,y1,layer_index, 2*i+1,yi_prefactor,femmodel,matlitho);
++	yi_derivatives<doubletype>(k2,y1,layer_index, 2*i+1,yi_prefactor,femmodel,matlitho,vars);
+ 	for (int j=0;j<6;j++) {y2[j]=y[j]+k2[j]*dr;}
+-	yi_derivatives<doubletype>(k3,y2,layer_index, 2*i+1,yi_prefactor,femmodel,matlitho);
++	yi_derivatives<doubletype>(k3,y2,layer_index, 2*i+1,yi_prefactor,femmodel,matlitho,vars);
+ 	for (int j=0;j<6;j++) {y3[j]=y[j]+k3[j]*2.0*dr;}
+-	yi_derivatives<doubletype>(k4,y3,layer_index, 2*i+1,yi_prefactor,femmodel,matlitho);		
++	yi_derivatives<doubletype>(k4,y3,layer_index, 2*i+1,yi_prefactor,femmodel,matlitho,vars);		
+ 
+ 	for (int j=0;j<6;j++){
+ 		y[j]+=(k1[j]+2.0*k2[j]+2.0*k3[j]+k4[j])/3.0*dr;		
+@@ -662,44 +1009,52 @@
+ 
+ 	x = x + 2.0*dr;
+ 
+-	xDelete<IssmDouble>(k1);
+-	xDelete<IssmDouble>(k2);
+-	xDelete<IssmDouble>(k3);
+-	xDelete<IssmDouble>(k4);
+-	xDelete<IssmDouble>(y1);
+-	xDelete<IssmDouble>(y2);
+-	xDelete<IssmDouble>(y3);
+ }/*}}}*/
+-template <typename doubletype> void        Innersphere_boundaryconditions(doubletype* yi, int layer_index, int deg, doubletype omega, FemModel* femmodel, Matlitho* matlitho, LoveVariables* vars){ /*{{{*/
++template <typename doubletype> void        Innersphere_boundaryconditions(doubletype* yi, int layer_index, int deg, doubletype omega, FemModel* femmodel, Matlitho* matlitho, LoveVariables<doubletype>* vars){ /*{{{*/
+ 	//fills the boundary conditions at the bottom of layer[layer_index] in yi[0:2][0:5]
+ 
+-	IssmDouble r = matlitho->radius[layer_index];
+-	IssmDouble ra=matlitho->radius[matlitho->numlayers];
+-	IssmDouble  g0,r0,mu0, GG;
+ 	int nyi;
++	doubletype r = matlitho->radius[layer_index];
++	doubletype ra=matlitho->radius[matlitho->numlayers];
++	doubletype  g0,r0,mu0, GG;
++	IssmDouble mu0p, GGp;
+ 
+-	femmodel->parameters->FindParam(&mu0,LoveMu0Enum);
+-	femmodel->parameters->FindParam(&GG,LoveGravitationalConstantEnum);
+ 
++	femmodel->parameters->FindParam(&mu0p,LoveMu0Enum);
++	femmodel->parameters->FindParam(&GGp,LoveGravitationalConstantEnum);
++
+ 	g0=vars->g0;
+ 	r0=vars->r0;
++	mu0=mu0p;
++	GG=GGp;
+ 	nyi=vars->nyi;
+ 
+-	IssmDouble ro=matlitho->density[layer_index];
+-	IssmDouble issolid=matlitho->issolid[layer_index];
+-	IssmDouble g=GetGravity(r,layer_index,femmodel,matlitho,vars);
+-	doubletype la,mu;
+ 
+-	if (layer_index==0){
+-		// radius[0] cannot be 0 for numerical reasons, but below our first interface at radius[0] would in reality be the same material as in the first layer
+-		GetEarthRheology<doubletype>(&la, &mu,layer_index,omega,matlitho);   
+-	} else {
+-		GetEarthRheology<doubletype>(&la, &mu,layer_index-1,omega,matlitho);   
+-	}    
++	doubletype g=GetGravity<doubletype>(r,layer_index,femmodel,matlitho,vars);
++	doubletype la,mu,ro;
++	
++	int i=layer_index-1;
++	if (layer_index==0) i=layer_index;
+ 
+-	IssmDouble cst = 4.0*PI*GG*ro;
+-	IssmDouble r2=pow(r,2.0);
++	ro=matlitho->density[i];
+ 
++	//elastic values
++	la=matlitho->lame_lambda[i];
++	mu=matlitho->lame_mu[i];
++	doubletype Kappa=(la+2.0/3.0*mu);
++
++	//update to viscoelastic values
++	mu=vars->mu[i*vars->nfreq+vars->ifreq];
++	la = Kappa-2.0/3.0*mu; 
++
++	doubletype cst = 4.0*PI*GG*ro;
++	doubletype r2=pow(r,2.0);
++
++	//Greff-Lefftz and Legros 1997, p701, analytical solution for incompressible elastic layer for y3, y4, y5 ensuring they =0 at r=0
++	//These equations are then divided by r^n for numerical stability at higher degrees
++
++	//all terms in y1 y2 y6 are 0 in that layer because they are of the type r^l with l<0 and would diverge at the origin, that's why we only need 3 equations
++
+ 	yi[0+nyi*0]=1.0*r/ra;
+ 	yi[0+nyi*1]=1.0/(r*ra);
+ 	yi[0+nyi*2]=0.0;
+@@ -724,24 +1079,114 @@
+ 	yi[5+nyi*1]=-cst/(r*g0);
+ 	yi[5+nyi*2]=deg/(r*g0);
+ 
++
++	/*doubletype vp2 = (la + 2.0*mu)/ro;
++	yi[0+nyi*0]=1.0*r/ra;
++	yi[0+nyi*1]=1.0/(r*ra);
++	yi[0+nyi*2]=0.0;
++
++	yi[1+nyi*0]=(2.0*mu*(deg-1.0-3.0/deg) + cst/3.0*ro*r2)/mu0;
++	yi[1+nyi*1]=(2.0*mu*(deg-1.0)/r2 + cst/3.0*ro)/mu0;
++	yi[1+nyi*2]=-ro/mu0;
++
++	yi[2+nyi*0]=(deg+3.0)/(deg*(deg+1.0))*r/ra;
++	yi[2+nyi*1]=1.0/(deg*r*ra);
++	yi[2+nyi*2]=0.0;
++
++	yi[3+nyi*0]=2.0*mu*(deg+2.0)/((deg+1.0)*mu0);
++	yi[3+nyi*1]=2.0*mu*(deg-1.0)/(deg*r2*mu0);
++	yi[3+nyi*2]=0.0;
++
++	yi[4+nyi*0]=0.0;
++	yi[4+nyi*1]=0.0;
++	yi[4+nyi*2]=1.0/(g0*ra);
++
++	yi[5+nyi*0]=-cst*r/g0;
++	yi[5+nyi*1]=-cst/(r*g0);
++	yi[5+nyi*2]=deg/(r*g0);*/
++
++
++
+ }/*}}}*/
+-template <typename doubletype> void        build_yi_system(doubletype* yi, int deg, doubletype omega, doubletype* yi_prefactor, FemModel* femmodel, Matlitho* matlitho,LoveVariables* vars) { /*{{{*/
++template <typename doubletype> void        Coremantle_boundaryconditions(doubletype* yi, int layer_index, int deg, doubletype omega, FemModel* femmodel, Matlitho* matlitho, LoveVariables<doubletype>* vars){ /*{{{*/
++	//fills the boundary conditions at the bottom of layer[layer_index] in yi[0:2][0:5]
+ 
+-	IssmDouble  g0,r0,mu0,x,ro1, GG;
+-	int nyi,starting_layer, nstep;
++	int nyi;
++	doubletype r = matlitho->radius[layer_index];
++	doubletype ra=matlitho->radius[matlitho->numlayers];
++	doubletype  g0,r0,mu0, GG;
++	IssmDouble mu0p, GGp;
+ 
++
++	femmodel->parameters->FindParam(&mu0p,LoveMu0Enum);
++	femmodel->parameters->FindParam(&GGp,LoveGravitationalConstantEnum);
++
+ 	g0=vars->g0;
+ 	r0=vars->r0;
++	mu0=mu0p;
++	GG=GGp;
+ 	nyi=vars->nyi;
+-	starting_layer=vars->starting_layer;
+ 
+-	femmodel->parameters->FindParam(&mu0,LoveMu0Enum);
+-	femmodel->parameters->FindParam(&GG,LoveGravitationalConstantEnum);
+-	femmodel->parameters->FindParam(&nstep,LoveIntStepsPerLayerEnum);
++	doubletype ro=matlitho->density[layer_index-1];
+ 
+-	IssmDouble xmin,xmax,one,ro,g;
+-	IssmDouble ra=matlitho->radius[matlitho->numlayers];
++	
++	if (!matlitho->issolid[layer_index]) _error_("Love core error: CMB conditions requested but layer " << layer_index << " (mantle side) is not solid");
++	if (matlitho->issolid[layer_index-1]) _error_("Love core error: CMB conditions requested but layer " << layer_index-1 << " (outer core) is solid");
+ 
++	doubletype cst = 4.0/3.0*PI*GG*ro;
++	doubletype rl1=pow(r,deg-1);
++
++	yi[0+nyi*0]=-rl1/cst/ra;
++	yi[0+nyi*1]=1.0/ra;
++	yi[0+nyi*2]=0.0;
++
++	yi[1+nyi*0]=0.0;
++	yi[1+nyi*1]=ro*cst*r/mu0;
++	yi[1+nyi*2]=0.0;
++
++	yi[2+nyi*0]=0.0;
++	yi[2+nyi*1]=0.0;
++	yi[2+nyi*2]=1.0/ra;
++
++	yi[3+nyi*0]=0.0;
++	yi[3+nyi*1]=0.0;
++	yi[3+nyi*2]=0.0;
++
++	yi[4+nyi*0]=r*rl1/(g0*ra);
++	yi[4+nyi*1]=0.0;
++	yi[4+nyi*2]=0.0;
++
++	yi[5+nyi*0]=2.0*(deg-1)*rl1/g0;
++	yi[5+nyi*1]=3.0*cst/g0;
++	yi[5+nyi*2]=0.0;
++
++}/*}}}*/
++template <typename doubletype> void        build_yi_system(doubletype* yi, int deg, doubletype omega, doubletype* yi_prefactor, FemModel* femmodel, Matlitho* matlitho,LoveVariables<doubletype>* vars) { /*{{{*/
++
++	doubletype	g0,r0,mu0,x,ro1, GG;
++	int		nyi,starting_layer, nstep;
++	doubletype 	xmin,xmax,one,ro,g, ra;
++	IssmDouble 	mu0p, GGp;
++	bool 		debug;
++	int ny,is,ii,jj;
++	int scheme;
++	int ici = 0;   // Index of current interface 
++	int cmb=0;
++
++	femmodel->parameters->FindParam(&cmb,LoveCoreMantleBoundaryEnum);
++	femmodel->parameters->FindParam(&mu0p,LoveMu0Enum);
++	femmodel->parameters->FindParam(&GGp,LoveGravitationalConstantEnum);
++	femmodel->parameters->FindParam(&debug,LoveDebugEnum);
++	femmodel->parameters->FindParam(&scheme,LoveIntegrationSchemeEnum);
++
++	g0=vars->g0;
++	r0=vars->r0;
++	nyi=vars->nyi;
++	starting_layer=vars->starting_layer;
++	mu0=mu0p;
++	GG=GGp;
++	ra=matlitho->radius[matlitho->numlayers];
++
+ 	for (int i=0;i<6*(matlitho->numlayers+1);i++){
+ 		for(int j=0;j<6*(matlitho->numlayers+1);j++){
+ 			yi[i+6*(matlitho->numlayers+1)*j]=0.0;
+@@ -748,13 +1193,13 @@
+ 		}
+ 	}
+ 
+-	int ny,is,ii,jj;
+ 	doubletype ystart[6];
+ 	for (int k=0;k<6;k++) ystart[k]=0.0;		
+ 
+-	int ici = 0;   // Index of current interface 
++
++
+ 	for (int i = starting_layer; i<matlitho->numlayers;i++){ 
+-
++		ici=i-starting_layer;
+ 		xmin=matlitho->radius[i]/ra;
+ 		xmax=(matlitho->radius[i+1])/ra;
+ 
+@@ -773,9 +1218,13 @@
+ 			ystart[j]= 1.0;
+ 
+ 			// Numerical Integration 
+-			//propagate_yi_euler(&ystart[0], xmin, xmax, i, yi_prefactor,femmodel, matlitho);
+-			propagate_yi_RK2<doubletype>(&ystart[0], xmin, xmax, i, yi_prefactor,femmodel, matlitho);
+-			//propagate_yi_RK4(&ystart[0], xmin, xmax, i, yi_prefactor,femmodel, matlitho);
++			if (debug) propagate_yi_euler<doubletype>(&ystart[0], xmin, xmax, i, yi_prefactor,femmodel, matlitho, vars);
++			else {
++				if (scheme==0) propagate_yi_euler<doubletype>(&ystart[0], xmin, xmax, i, yi_prefactor,femmodel, matlitho, vars);
++				else if (scheme==1) propagate_yi_RK2<doubletype>(&ystart[0], xmin, xmax, i, yi_prefactor,femmodel, matlitho, vars);
++				else if (scheme==2) propagate_yi_RK4<doubletype>(&ystart[0], xmin, xmax, i, yi_prefactor,femmodel, matlitho, vars);
++				else _error_("Love core error: integration scheme not found");
++			}
+ 			// Boundary Condition matrix - propagation part 
+ 			ii = 6*(ici+1)+is;
+ 			jj = 6*(ici+1)+j+is-3;
+@@ -793,29 +1242,34 @@
+ 			}
+ 		} else { // Boundary Condition matrix - liquid regions
+ 			ro1=matlitho->density[i];
+-			g=GetGravity(matlitho->radius[i], i, femmodel,matlitho,vars);
++			g=GetGravity<doubletype>(matlitho->radius[i], i, femmodel,matlitho,vars);
+ 			ii = 6*ici;
+-			yi[ii+nyi*(ii+3)] = -1.0;
+-			yi[ii+nyi*(ii+4+3)] = -g0/g;
+-			yi[(ii+1)+nyi*(ii+3)]=-ro1*g*ra/mu0;
+-			yi[(ii+2)+nyi*(ii+1+3)]=-1.0;
+-			yi[(ii+5)+nyi*(ii+3)]= 4.0*PI*GG*ro1*ra/g0;
+-			yi[(ii+4)+nyi*(ii+4+3)]=-1.0;
+-			yi[(ii+5)+nyi*(ii+5+3)]=-1.0;
+-			g=GetGravity(matlitho->radius[i+1], i,femmodel,matlitho,vars);
++			jj = 6*ici+3;
++			yi[ii+nyi*(jj)] = -1.0;
++			yi[ii+nyi*(jj+4)] = -g0/g;
++			yi[(ii+1)+nyi*(jj)]=-ro1*g*ra/mu0;
++			yi[(ii+2)+nyi*(jj+1)]=-1.0;
++			yi[(ii+5)+nyi*(jj)]= 4.0*PI*GG*ro1*ra/g0;
++			yi[(ii+4)+nyi*(jj+4)]=-1.0;
++			yi[(ii+5)+nyi*(jj+5)]=-1.0;
++			g=GetGravity<doubletype>(matlitho->radius[i+1], i,femmodel,matlitho,vars);
+ 			ii = 6*(ici+1);
+-			yi[ii+nyi*(ii-1)]=-1.0;
+-			yi[ii+nyi*(ii+1)]=yi[(ii+4)+nyi*(ii+1)]*g0/g; // yi(17,14) solution integration 1 of z5 CMB
+-			yi[ii+nyi*(ii+2)]=yi[(ii+4)+nyi*(ii+2)]*g0/g; // yi(17,15) solution integration 2 of z5 CMB
++
++			yi[ii+nyi*(jj+2)]=-1.0;
++			yi[ii+nyi*(jj+4)]=yi[(ii+4)+nyi*(jj+4)]*g0/g; // yi(17,14) solution integration 1 of z5 CMB
++			yi[ii+nyi*(jj+5)]=yi[(ii+4)+nyi*(jj+5)]*g0/g; // yi(17,15) solution integration 2 of z5 CMB
+ 			// yi(13,..) y1 CMB
+-			yi[(ii+1)+nyi*(ii-1)]=-ro1*g*ra/mu0;
+-			yi[(ii+2)+nyi*(ii)]=-1.0;
+-			yi[(ii+5)+nyi*(ii-1)]= 4.0*PI*GG*ro1*ra/g0;
++			yi[(ii+1)+nyi*(jj+2)]=-ro1*g*ra/mu0;
++			yi[(ii+2)+nyi*(jj+3)]=-1.0;
++			yi[(ii+5)+nyi*(jj+2)]= 4.0*PI*GG*ro1*ra/g0;
+ 		}	
+ 		ici = ici+1;
+ 	}
+ 
+ 	//-- Internal sphere: integration starts here rather than r=0 for numerical reasons
++	/*if (starting_layer==cmb) Coremantle_boundaryconditions<doubletype>(yi, starting_layer, deg, omega, femmodel, matlitho,vars);
++	else Innersphere_boundaryconditions<doubletype>(yi, starting_layer, deg, omega, femmodel, matlitho,vars);*/
++
+ 	Innersphere_boundaryconditions<doubletype>(yi, starting_layer, deg, omega, femmodel, matlitho,vars);
+ 
+ 	//-- Surface conditions
+@@ -833,11 +1287,12 @@
+ 	}
+ 
+ }/*}}}*/
+-template <typename doubletype> void        yi_boundary_conditions(doubletype* yi_righthandside, int deg, FemModel* femmodel, Matlitho* matlitho,LoveVariables* vars, int forcing_type){ /*{{{*/
++template <typename doubletype> void        yi_boundary_conditions(doubletype* yi_righthandside, int deg, FemModel* femmodel, Matlitho* matlitho,LoveVariables<doubletype>* vars, int forcing_type){ /*{{{*/
+ 
+-	IssmDouble  g0,r0,mu0,ra,rb,rc;
++	doubletype  g0,r0,mu0,ra,rb,rc;
+ 	int nyi,icb,cmb,starting_layer;
+-	IssmDouble* EarthMass;
++	doubletype* EarthMass;
++	IssmDouble mu0p;
+ 
+ 	g0=vars->g0;
+ 	r0=vars->r0;
+@@ -845,10 +1300,11 @@
+ 	starting_layer=vars->starting_layer;
+ 	EarthMass=vars->EarthMass;
+ 
+-	femmodel->parameters->FindParam(&mu0,LoveMu0Enum);
++	femmodel->parameters->FindParam(&mu0p,LoveMu0Enum);
+ 	femmodel->parameters->FindParam(&icb,LoveInnerCoreBoundaryEnum);
+ 	femmodel->parameters->FindParam(&cmb,LoveCoreMantleBoundaryEnum);
+ 
++	mu0=mu0p;
+ 	// In Case of a Inner Core - Outer Core - Mantle planet and Boundary conditions on these 3 interfaces
+ 	ra=matlitho->radius[matlitho->numlayers];	
+ 	rb=0;
+@@ -860,7 +1316,7 @@
+ 		rb=matlitho->radius[cmb];
+ 	}
+ 
+-	IssmDouble ro_mean=EarthMass[matlitho->numlayers-1]/(4.0/3.0*PI*pow(ra,3.0));
++	doubletype ro_mean=EarthMass[matlitho->numlayers-1]/(4.0/3.0*PI*pow(ra,3.0));
+ 
+ 	for (int i=0;i<(matlitho->numlayers+1)*6;i++) yi_righthandside[i]=0.0;
+ 
+@@ -916,13 +1372,14 @@
+ 			_error_("love core error: forcing_type not supported yet");
+ 	}
+ }/*}}}*/
+-template <typename doubletype> void        solve_yi_system(doubletype* loveh, doubletype* lovel, doubletype* lovek, int deg, doubletype omega, IssmDouble* frequencies, doubletype* yi, doubletype* rhs, FemModel* femmodel, Matlitho* matlitho, LoveVariables* vars, bool verbosecpu){ /*{{{*/
++template <typename doubletype> void        solve_yi_system(doubletype* loveh, doubletype* lovel, doubletype* lovek, int deg, doubletype omega, IssmDouble* frequencies, doubletype* yi, doubletype* rhs, FemModel* femmodel, Matlitho* matlitho, LoveVariables<doubletype>* vars, bool verbosecpu){ /*{{{*/
+ 
+-	IssmDouble  g0,r0,mu0,loveratio,underflow_tol;
++	doubletype  g0,r0,mu0;
+ 	//IssmDouble* frequencies;
+-	int nyi,starting_layer, dummy;
+-	bool allow_layer_deletion;
+-	IssmDouble* EarthMass=NULL;
++	int nyi,starting_layer, dummy,cmb;
++	bool allow_layer_deletion, debug;
++	doubletype* EarthMass=NULL;
++	IssmDouble mu0p,loveratio,underflow_tol;
+ 
+ 	g0=vars->g0;
+ 	r0=vars->r0;
+@@ -930,11 +1387,14 @@
+ 	starting_layer=vars->starting_layer;
+ 	EarthMass=vars->EarthMass;
+ 
+-	femmodel->parameters->FindParam(&mu0,LoveMu0Enum);
++	femmodel->parameters->FindParam(&mu0p,LoveMu0Enum);
+ 	femmodel->parameters->FindParam(&allow_layer_deletion,LoveAllowLayerDeletionEnum);
+ 	femmodel->parameters->FindParam(&underflow_tol,LoveUnderflowTolEnum);
++	femmodel->parameters->FindParam(&debug,LoveDebugEnum);
++	femmodel->parameters->FindParam(&cmb,LoveCoreMantleBoundaryEnum);
+ 	//femmodel->parameters->FindParam(&frequencies,&dummy,LoveFrequenciesEnum);
+-	IssmDouble ra=matlitho->radius[matlitho->numlayers];
++	mu0=mu0p;
++	doubletype ra=matlitho->radius[matlitho->numlayers];
+ 	bool exit=false;
+ 	int lda,ldb;
+ 
+@@ -952,6 +1412,22 @@
+ 				yilocal[i+j*nyi]=yi[i+j*nyi];
+ 			}
+ 		}
++		
++		if (debug){
++			IssmDouble*  yidebug=xNew<IssmDouble>(nyi*nyi);
++			IssmDouble*  rhsdebug=xNew<IssmDouble>(nyi);
++			for (int i=0;i<nyi;i++){ 
++				rhsdebug[i]=DownCastVarToDouble(rhs[i]);
++				for (int j=0;j<nyi;j++){
++					yidebug[i+j*nyi]=DownCastVarToDouble(yi[i+j*nyi]);
++				}
++			}
++			femmodel->results->AddObject(new GenericExternalResult<IssmDouble*>(femmodel->results->Size()+1,LoveYiEnum,yidebug,nyi,nyi,0,0));
++			femmodel->results->AddObject(new GenericExternalResult<IssmDouble*>(femmodel->results->Size()+1,LoveRhsEnum,rhsdebug,nyi,1,0,0));
++			xDelete<IssmDouble>(yidebug);
++			xDelete<IssmDouble>(rhsdebug);
++		}
++
+ 		//-- Resolution
+ 		int* ipiv=xNewZeroInit<int>(nyi); //pivot index vector
+ 		int info = 0;// error checker
+@@ -973,16 +1449,17 @@
+ 			}
+ 			_error_("love core warning in DGESV : LAPACK linear equation solver couldn't resolve the system");*/
+ 
+-		if(VerboseSolution() && info!=0){ 
+-			_printf_("i j yi[i+nyi*j] rhs[i]");
++		if(VerboseSolution() && verbosecpu && info!=0){ 
++			_printf_("i j yi[i+nyi*j] rhs[i]\n");
+ 			for (int i=0;i<nyi;i++){
+ 				for (int j=0;j<nyi;j++){
+ 					_printf_(i<<" "<<j<<" "<<yi[i+nyi*j]<<" "<<rhs[i]<<"\n");
+ 				}
+ 			}
+-			_error_("love core warning in DGESV : LAPACK linear equation solver couldn't resolve the system");
++			_error_("love core error in DGESV : LAPACK linear equation solver couldn't resolve the system");
+ 		}
+ 
++
+ 		*loveh = rhslocal[nyi-3]*ra*g0;
+ 		*lovel = rhslocal[nyi-2]*ra*g0;
+ 		*lovek = rhslocal[nyi-1]*ra*g0;
+@@ -999,7 +1476,7 @@
+ 		if (abs(lovel1/lovel1s) < loveratio) loveratio = abs(lovel1/lovel1s); 
+ 		if (abs(lovek1/lovek1s) < loveratio) loveratio = abs(lovek1/lovek1s);
+ 
+-		
++		if (debug) goto save_results;
+ 
+ 		if (!allow_layer_deletion || nyi<=12 || omega!=angular_frequency<doubletype>(frequencies[0]) || deg==0){ 
+ 			goto save_results;
+@@ -1021,7 +1498,7 @@
+ 		}
+ 
+ 		if (deg==vars->deg_layer_delete[starting_layer]){ // if we are at the degree where we should delete the current layer, proceed to delete the bottom layer
+-			if (omega!=0 && VerboseSolution()  && verbosecpu) _printf_(", deleting layer " << starting_layer << "\n");
++			//if (omega!=0 && VerboseSolution()  && verbosecpu) _printf_(", deleting layer " << starting_layer << "\n");
+ 			nyi-=6;
+ 			starting_layer+=1;
+ 			vars->nyi=nyi;
+@@ -1034,7 +1511,10 @@
+ 				}
+ 			}
+ 
+-			Innersphere_boundaryconditions<doubletype>(yi, starting_layer, deg, omega, femmodel, matlitho,vars); //we move the first interface to the new starting layer. yi[0:2,0:5] will be different
++	/*if (starting_layer==cmb) Coremantle_boundaryconditions<doubletype>(yi, starting_layer, deg, omega, femmodel, matlitho,vars);
++	else Innersphere_boundaryconditions<doubletype>(yi, starting_layer, deg, omega, femmodel, matlitho,vars); //we move the first interface to the new starting layer. yi[0:2,0:5] will be different
++	*/
++	Innersphere_boundaryconditions<doubletype>(yi, starting_layer, deg, omega, femmodel, matlitho,vars);
+ 		} else { //we are ready to save the outputs and break the main loop
+ 
+ save_results:
+@@ -1133,27 +1613,31 @@
+ 			postwidder_transform<doubletype>(pmtf_colineart,pmtf_colinearf,2,t,2,NTit,xi,femmodel);
+ 			postwidder_transform<doubletype>(pmtf_orthot,pmtf_orthof,2,t,2,NTit,xi,femmodel);
+ 		}
++		xDelete<doubletype>(pmtf_colinearf);
++		xDelete<doubletype>(pmtf_orthof);
+ 		if(VerboseSolution() && verbosecpu) _printf_("done!\n");
+ 	}
+ 
+ 	xDelete<doubletype>(xi);
+-	xDelete<doubletype>(pmtf_colinearf);
+-	xDelete<doubletype>(pmtf_orthof);
+ }/*}}}*/
+ 
+-template <typename doubletype> void        compute_love_numbers(LoveNumbers<doubletype>* Lovef, LoveNumbers<doubletype>* Elastic, int forcing_type, int sh_cutoff, IssmDouble* frequencies, FemModel* femmodel, Matlitho* matlitho, LoveVariables* vars, bool verbosecpu){
++template <typename doubletype> void        compute_love_numbers(LoveNumbers<doubletype>* Lovef, LoveNumbers<doubletype>* Elastic, int forcing_type, int sh_cutoff, IssmDouble* frequencies, FemModel* femmodel, Matlitho* matlitho, LoveVariables<doubletype>* vars, bool verbosecpu){
+ 
+-	int nstep, kernel_index,kernel_indexe,deleted_layer_offset, deg, sh_nmin, sh_nmax, nfreq;
++	int nsteps, kernel_index,kernel_indexe,deleted_layer_offset, deg, sh_nmin, sh_nmax, nfreq;
+ 	doubletype  lovek, loveh, lovel, loveratio;
+ 	doubletype  omega;
+ 	doubletype* yi_prefactor=NULL;
+ 	doubletype* yi_righthandside=NULL;
+ 	doubletype* yi=NULL;
+-	IssmDouble  underflow_tol;
++	doubletype  underflow_tol;
++	IssmDouble dr;
+ 	bool freq_skip, istemporal;
++	int cmb=0;
++	int nyi_init=0;
+ 
+-	femmodel->parameters->FindParam(&nstep,LoveIntStepsPerLayerEnum);
++	//femmodel->parameters->FindParam(&nstep,LoveIntStepsPerLayerEnum);
+ 	femmodel->parameters->FindParam(&istemporal,LoveIsTemporalEnum);
++	femmodel->parameters->FindParam(&cmb,LoveCoreMantleBoundaryEnum);
+ 
+ 	nfreq=Lovef->nfreq;
+ 	sh_nmin=Lovef->sh_nmin;
+@@ -1161,19 +1645,23 @@
+ 	if (Elastic==NULL) sh_cutoff=sh_nmax;
+ 
+ 	// reset deleted layers in case we have called this function before;
+-	vars->starting_layer=0; 
+-	vars->nyi=6*(matlitho->numlayers+1);
++	vars->starting_layer=0;
++	vars->nyi=6*(matlitho->numlayers-vars->starting_layer+1);
++	nyi_init=6*(matlitho->numlayers+1);
++	nsteps=0;
++	for (int i=0;i<matlitho->numlayers;i++)	nsteps+=vars->nstep[i];
+ 
+-	yi_prefactor=xNewZeroInit<doubletype>(6*6*nstep*matlitho->numlayers);
+-	yi_righthandside=xNewZeroInit<doubletype>(vars->nyi);
+-	yi=xNewZeroInit<doubletype>(vars->nyi*vars->nyi);
++	//yi_prefactor=xNewZeroInit<doubletype>(6*6*nstep*matlitho->numlayers);
++	yi_prefactor=xNewZeroInit<doubletype>(6*6*nsteps);
++	yi_righthandside=xNewZeroInit<doubletype>(nyi_init);
++	yi=xNewZeroInit<doubletype>(nyi_init*nyi_init);
+ 
+-	//precalculate yi coefficients that do not depend on degree or frequency
+-	fill_yi_prefactor<doubletype>(yi_prefactor, NULL, NULL,femmodel, matlitho,vars); 
++	//precompute yi coefficients that do not depend on degree or frequency
++	fill_yi_prefactor<doubletype>(yi_prefactor, NULL, NULL,femmodel, matlitho,vars);
+ 
+ 	if (VerboseSolution() && Elastic  && verbosecpu) _printf_("\n");
+ 
+-	for(int deg=0;deg<2;deg++){ // calculation is in the center of mass reference frame, neutralize degree 0 and 1 mass changes
++	for(int deg=0;deg<2;deg++){ // calculation is in the center of mass reference frame, neutralize degree 0 and 1 mass changes, i.e 1+k=0
+ 		for (int fr=0;fr<nfreq;fr++){
+ 			Lovef->K[fr*(sh_nmax+1)+deg]=-1.0;
+ 		}
+@@ -1184,19 +1672,21 @@
+ 			_printf_("\r   Degree: " << deg << "/" << sh_nmax << "    ");
+ 		}
+ 
+-		//precalculate yi coefficients that depend on degree but not frequency
++		//precompute yi coefficients that depend on degree but not frequency
+ 		fill_yi_prefactor<doubletype>(yi_prefactor, &deg, NULL,femmodel, matlitho,vars); 
+ 
+ 		for (int fr=0;fr<nfreq;fr++){
+ 			omega=angular_frequency<doubletype>(frequencies[fr]);
++			vars->ifreq=fr;
+ 			
+-			//precalculate yi coefficients that depend on degree and frequency
++			//precompute yi coefficients that depend on degree and frequency
+ 			fill_yi_prefactor<doubletype>(yi_prefactor, &deg,&omega,femmodel, matlitho,vars);
+ 
+ 			//solve the system
+-			yi_boundary_conditions<doubletype>(yi_righthandside,deg,femmodel,matlitho,vars,forcing_type); 
++			yi_boundary_conditions<doubletype>(yi_righthandside,deg,femmodel,matlitho,vars,forcing_type);
+ 			build_yi_system<doubletype>(yi,deg,omega,yi_prefactor,femmodel,matlitho,vars);
+-			solve_yi_system<doubletype>(&loveh,&lovel,&lovek, deg, omega, frequencies, yi, yi_righthandside,femmodel, matlitho,vars,verbosecpu);
++			solve_yi_system<doubletype>(&loveh,&lovel,&lovek, deg, omega, frequencies, yi, yi_righthandside,femmodel, matlitho,vars,verbosecpu && !Elastic);
++
+ 			Lovef->H[fr*(sh_nmax+1)+deg]=loveh;
+ 			Lovef->K[fr*(sh_nmax+1)+deg]=lovek-1.0;
+ 			Lovef->L[fr*(sh_nmax+1)+deg]=lovel;
+@@ -1208,7 +1698,7 @@
+ 		}
+ 	}
+ 
+-	if (Elastic) { // if elastic values were provided, we copy elastic love numbers above the cutoff degree instead of calculating them
++	if (Elastic) { // if elastic values were provided, we copy elastic love numbers above the cutoff degree instead of computing them
+ 		for(int deg=sh_cutoff+1;deg<sh_nmax+1;deg++){
+ 			if (VerboseSolution() && Elastic  && verbosecpu) {
+ 				if (deg==sh_nmax || deg%100==0)	_printf_("\r   Degree: " << deg << "/" << Lovef->sh_nmax << "    ");
+@@ -1228,6 +1718,8 @@
+ 		}
+ 	}
+ 
++
++
+ 	if (VerboseSolution() && Elastic  && verbosecpu) _printf_("\n");
+ 	xDelete<doubletype>(yi);
+ 	xDelete<doubletype>(yi_righthandside);
+@@ -1235,25 +1727,45 @@
+ }/*}}}*/
+ 
+ /*templated cores:*/
+-LoveVariables*                             love_init(FemModel* femmodel, Matlitho* matlitho){/*{{{*/
++template <typename doubletype> LoveVariables<doubletype>*	love_init(FemModel* femmodel, Matlitho* matlitho, bool verbosecpu){/*{{{*/
+ 
+ 	/*initialize Planet_Mass(r) for efficient computation of gravity, value of surface gravity and inital size of the yi equation system*/
+ 
+ 	bool        verbosemod = (int)VerboseModule();
+ 	int         numlayers  = matlitho->numlayers;
+-	IssmDouble* r          = matlitho->radius;
+-	IssmDouble  r1,r2,ro, GG;
++	int 	    minsteps;
++	doubletype* r=NULL;
++	doubletype  r1,r2,ro, GG;
++	IssmDouble GGp;
++	IssmDouble dr;
+ 
+ 	/*outputs:*/
+-	IssmDouble* EarthMass=NULL;
+-	IssmDouble  g0,r0;
+-	int         nyi,starting_layer;
++	doubletype* EarthMass=NULL;
++	doubletype  g0,r0;
++	int         nyi,starting_layer,cmb;
+ 	int*	    deg_layer_delete;
++	int*	    nstep;
+ 
+-	femmodel->parameters->FindParam(&GG,LoveGravitationalConstantEnum);
+-	EarthMass=xNewZeroInit<IssmDouble>(numlayers+1);
++	
++	femmodel->parameters->FindParam(&GGp,LoveGravitationalConstantEnum);
++	femmodel->parameters->FindParam(&minsteps, LoveMinIntegrationStepsEnum);
++	femmodel->parameters->FindParam(&dr, LoveMaxIntegrationdrEnum);
++	femmodel->parameters->FindParam(&cmb,LoveCoreMantleBoundaryEnum);
++	GG=GGp;
++	EarthMass=xNewZeroInit<doubletype>(numlayers+1);
+ 	deg_layer_delete=xNewZeroInit<int>(numlayers);
+ 
++	r=xNewZeroInit<doubletype>(numlayers+1);
++	nstep=xNewZeroInit<int>(numlayers);
++	for (int i=0;i<numlayers+1;i++){
++		r[i] = matlitho->radius[i];
++		if (i<numlayers) {
++			// nstep[i] is the largest even integer such that (radius[i+1]-radius[i])/nstep[i]<dr
++			nstep[i]=ceil((matlitho->radius[i+1]-matlitho->radius[i])/dr/2)*2;
++			if (nstep[i]<minsteps) nstep[i]=minsteps;
++		}
++	}
++
+ 	for (int i=0;i<numlayers;i++){
+ 		r2 = r[i+1];
+ 		ro = matlitho->density[i];
+@@ -1264,18 +1776,19 @@
+ 			EarthMass[i] = EarthMass[i-1] + ro*(pow(r2,3.0)-pow(r1,3.0))*4.0*PI/3.0;;
+ 		}
+ 	}
+-
+ 	g0=EarthMass[numlayers-1]*GG/pow(r[numlayers],2.0);
+ 	r0=r[numlayers];
+-	nyi=6*(numlayers+1);
+ 	starting_layer=0;
++	nyi=6*(numlayers-starting_layer+1);
+ 
+-	if(VerboseSolution()){
++
++	if(VerboseSolution() && verbosecpu){
+ 		_printf_("     Surface gravity: " << g0 << " m.s^-2\n");
+ 		_printf_("     Mean density: " << EarthMass[numlayers-1]/(4.0/3.0*PI*pow(r0,3.0)) << " kg.m^-3\n");
+ 	}
+ 
+-	return new LoveVariables(EarthMass,g0,r0,nyi,starting_layer,deg_layer_delete);
++	xDelete<doubletype>(r);
++	return new LoveVariables<doubletype>(EarthMass,g0,r0,nyi,starting_layer,deg_layer_delete,nstep);
+ 
+ } /*}}}*/
+ template <typename doubletype> void        love_core_template(FemModel* femmodel){ /*{{{*/
+@@ -1289,6 +1802,7 @@
+ 	IssmDouble *frequencies_local=NULL;
+ 	bool        save_results;
+ 	bool        complex_computation;
++	bool	    quad_precision;
+ 	bool	    verbosecpu=false;
+ 
+ 	doubletype  omega;
+@@ -1295,9 +1809,6 @@
+ 	doubletype  lovek, loveh, lovel, loveratio;
+ 	IssmDouble pw_threshold, pw_test_h, pw_test_l,pw_test_k;
+ 
+-	LoveNumbers<doubletype>* Lovef=NULL;
+-	LoveNumbers<doubletype>* Tidalf=NULL;
+-
+ 	/* parallel computing */
+ 	LoveNumbers<doubletype>* Lovef_local=NULL;
+ 	LoveNumbers<doubletype>* Tidalf_local=NULL;
+@@ -1308,7 +1819,7 @@
+ 	LoveNumbers<doubletype>* Fluid=NULL;
+ 	IssmDouble* frequencies_fluid=NULL;
+ 
+-	LoveVariables* vars=NULL;
++	LoveVariables<doubletype>* vars=NULL;
+ 
+ 	/*recover materials parameters: there is only one Matlitho, chase it down the hard way:*/
+ 	for (Object* & object: femmodel->materials->objects){
+@@ -1331,18 +1842,12 @@
+ 	femmodel->parameters->FindParam(&forcing_type,LoveForcingTypeEnum);
+ 	femmodel->parameters->FindParam(&istemporal,LoveIsTemporalEnum);
+ 	femmodel->parameters->FindParam(&complex_computation,LoveComplexComputationEnum);
++	femmodel->parameters->FindParam(&quad_precision,LoveQuadPrecisionEnum);
+ 	femmodel->parameters->FindParam(&pw_threshold,LovePostWidderThresholdEnum);
+ 	if (istemporal)	femmodel->parameters->FindParam(&NTit,LoveNTemporalIterationsEnum);
+ 
+-	/*Initialize three love matrices: geoid, vertical and horizontal displacement*/
+-	Lovef= new LoveNumbers<doubletype>(sh_nmin,sh_nmax,nfreq, matlitho);
+-	Tidalf= new LoveNumbers<doubletype>(2,2,nfreq, matlitho);
+-	Elastic= new LoveNumbers<doubletype>(sh_nmin,sh_nmax,1,matlitho);
+-	Fluid= new LoveNumbers<doubletype>(sh_nmin,sh_nmax,1,matlitho);
+-
+-	/*Initialize love kernels (real and imaginary parts): */
+-	vars=love_init(femmodel,matlitho);
+-
++	Elastic= new LoveNumbers<doubletype>(sh_nmin,sh_nmax,1,1,1,matlitho);
++	Fluid= new LoveNumbers<doubletype>(sh_nmin,sh_nmax,1,1,1,matlitho);
+ 	//distribute frequencies for parallel computation /*{{{*/
+ 	int nt_local, nf_local, lower_row, upper_row;
+ 	if (istemporal){ 
+@@ -1363,12 +1868,13 @@
+ 
+ 	if (lower_row==0) verbosecpu=true; //let only cpu1 be verbose
+ 	if(VerboseSolution() && verbosecpu) _printf0_("   computing LOVE numbers\n");
++	vars=love_init<doubletype>(femmodel,matlitho,verbosecpu);
+ 
+ 	frequencies_local=xNewZeroInit<IssmDouble>(nf_local);
+ 	for (int fr=0;fr<nf_local;fr++)	frequencies_local[fr]=frequencies[lower_row+fr];
+ 
+-	Lovef_local= new LoveNumbers<doubletype>(sh_nmin,sh_nmax,nf_local, matlitho);
+-	Tidalf_local= new LoveNumbers<doubletype>(2,2,nf_local, matlitho);
++	Lovef_local= new LoveNumbers<doubletype>(sh_nmin,sh_nmax,nf_local,lower_row,nfreq, matlitho);
++	Tidalf_local= new LoveNumbers<doubletype>(2,2,nf_local,lower_row,nfreq, matlitho);
+ 
+ 	/*}}}*/
+ 	frequencies_elastic=xNewZeroInit<IssmDouble>(1);
+@@ -1380,9 +1886,11 @@
+ 
+ 	// run elastic and fluid love numbers
+ 	if(VerboseSolution() && verbosecpu) _printf_("     elastic\n");
++	EarthRheology<doubletype>(vars,frequencies_elastic,1,matlitho,femmodel);
+ 	compute_love_numbers<doubletype>(Elastic, NULL, forcing_type, sh_nmax,frequencies_elastic, femmodel, matlitho, vars,verbosecpu);
+ 
+ 	if (nfreq>1){
++		EarthRheology<doubletype>(vars,frequencies_fluid,1,matlitho,femmodel);
+ 		compute_love_numbers<doubletype>(Fluid, NULL, forcing_type, sh_nmax,frequencies_fluid, femmodel, matlitho, vars,verbosecpu);
+ 		sh_cutoff=sh_nmax;
+ 		for (int deg=100;deg<sh_nmax+1;deg++){
+@@ -1401,18 +1909,10 @@
+ 		}
+ 	} 
+ 	else sh_cutoff=sh_nmax; 
+-		
+ 
++	delete Fluid;
+ 
+-	//Take care of rotationnal feedback love numbers first, if relevant /*{{{*/
+-	if (forcing_type==11 && sh_nmin<=2 && sh_nmax>=2){ // if forcing is surface loading and we have degree 2
+-		if(VerboseSolution() && verbosecpu) _printf_("     tidal\n");
+-		int tidal_forcing_type=9;
+-		compute_love_numbers<doubletype>(Tidalf_local, NULL,tidal_forcing_type=9, 2,frequencies_local, femmodel, matlitho, vars,verbosecpu);
+-	}
+-	/*}}}*/
+-
+-	//Resume requested forcing_type
++	//Requested forcing_type
+ 	if (nfreq>1){ // if we are not running just elastic love numbers
+ 		if(VerboseSolution() && verbosecpu){
+ 			if (forcing_type==11) _printf_("     loading\n");
+@@ -1419,6 +1919,7 @@
+ 			else if(forcing_type==9) _printf_("     tidal\n");
+ 			else _printf_("     love\n");
+ 		}
++		EarthRheology<doubletype>(vars,frequencies_local,nf_local,matlitho,femmodel);
+ 		compute_love_numbers<doubletype>(Lovef_local, Elastic, forcing_type, sh_cutoff, frequencies_local, femmodel, matlitho, vars,verbosecpu);
+ 	}
+ 	else{
+@@ -1426,132 +1927,169 @@
+ 	}
+ 	/*}}}*/
+ 
++	//Take care of rotationnal feedback love numbers, if relevant /*{{{*/
++	if (forcing_type==11 && sh_nmin<=2 && sh_nmax>=2){ // if forcing is surface loading and we have degree 2
++		if(VerboseSolution() && verbosecpu) _printf_("     tidal\n");
++		int tidal_forcing_type=9;
++		//no need to call EarthRheology, we already have the right one
++		compute_love_numbers<doubletype>(Tidalf_local, NULL,tidal_forcing_type=9, 2,frequencies_local, femmodel, matlitho, vars,verbosecpu);
++	}
++	/*}}}*/
+ 
++
+ 	//Temporal love numbers
+ 	if (istemporal && !complex_computation){
+ 		/*Initialize*/
+-		doubletype*  pmtf_colineart=NULL;
+-		doubletype*  pmtf_orthot=NULL;
+-		LoveNumbers<doubletype>* Lovet=NULL;
+-		LoveNumbers<doubletype>* Tidalt=NULL;
+ 		/*Downcast arrays to be exported in parameters*/
+-		LoveNumbers<IssmDouble>* LovetDouble=NULL;
+-		LoveNumbers<IssmDouble>* TidaltDouble=NULL;
+ 		IssmDouble*  pmtf_colineartDouble=NULL;
+ 		IssmDouble*  pmtf_orthotDouble=NULL;
++
+ 		/* parallel computing */
++		LoveNumbers<IssmDouble>* LovefDouble_local=NULL;
++		LoveNumbers<IssmDouble>* LovetDouble_local=NULL;
++		LoveNumbers<IssmDouble>* TidaltDouble_local=NULL;
++		IssmDouble*  pmtf_colineartDouble_local=NULL;
++		IssmDouble*  pmtf_orthotDouble_local=NULL;
++
+ 		doubletype*  pmtf_colineart_local=NULL;
+ 		doubletype*  pmtf_orthot_local=NULL;	
+ 		LoveNumbers<doubletype>* Lovet_local=NULL;
+ 		LoveNumbers<doubletype>* Tidalt_local=NULL;	
+ 
+-		Lovet= new LoveNumbers<doubletype>(sh_nmin,sh_nmax,nt,matlitho);
+-		Tidalt= new LoveNumbers<doubletype>(2,2,nt,matlitho);
+-		pmtf_colineart=xNewZeroInit<doubletype>(3*nt);
+-		pmtf_orthot=xNewZeroInit<doubletype>(3*nt);	
+-
+-		Lovet_local= new LoveNumbers<doubletype>(sh_nmin,sh_nmax,nt_local,matlitho);
+-		Tidalt_local= new LoveNumbers<doubletype>(2,2,nt_local,matlitho);	
++		Lovet_local= new LoveNumbers<doubletype>(sh_nmin,sh_nmax,nt_local,lower_row/2/NTit,nt,matlitho);
++		Tidalt_local= new LoveNumbers<doubletype>(2,2,nt_local,lower_row/2/NTit,nt,matlitho);	
+ 		pmtf_colineart_local=xNewZeroInit<doubletype>(3*nt_local);
+ 		pmtf_orthot_local=xNewZeroInit<doubletype>(3*nt_local);
+ 
+ 		love_freq_to_temporal<doubletype>(Lovet_local,Tidalt_local,pmtf_colineart_local,pmtf_orthot_local,Lovef_local,Tidalf_local,frequencies_local,femmodel,verbosecpu);
+ 
+-		/* MPI Gather */ /*{{{*/
+-		Lovef->LoveMPI_Gather(Lovef_local, lower_row);
+-		if (forcing_type==11 && sh_nmin<=2 && sh_nmax>=2){
+-			Tidalf->LoveMPI_Gather(Tidalf_local, lower_row);		
++
++		if(VerboseSolution() && verbosecpu) _printf_("   Assembling parralel vectors...");
++
++		//delete Lovef_local;
++		delete Tidalf_local;
++		//Lovet
++		LovetDouble_local= new LoveNumbers<IssmDouble>(sh_nmin,sh_nmax,nt_local,lower_row/2/NTit,nt,matlitho);
++		Lovet_local->DownCastToDouble(LovetDouble_local);
++		delete Lovet_local;
++		LovetDouble_local->Broadcast();
++
++		//Lovef
++		LovefDouble_local= new LoveNumbers<IssmDouble>(sh_nmin,sh_nmax,nf_local,lower_row,nfreq,matlitho);
++		Lovef_local->DownCastToDouble(LovefDouble_local);
++		delete Lovef_local;
++		LovefDouble_local->Broadcast();	
++
++		if (forcing_type==11 && sh_nmin<=2 && sh_nmax>=2){			
++			TidaltDouble_local= new LoveNumbers<IssmDouble>(2,2,nt_local,lower_row,nfreq,matlitho);
++			Tidalt_local->DownCastToDouble(TidaltDouble_local);
++			delete Tidalt_local;
++			TidaltDouble_local->Broadcast();
+ 		}
+-		Lovet->LoveMPI_Gather(Lovet_local, lower_row/2/NTit);
+-		Tidalt->LoveMPI_Gather(Tidalt_local, lower_row/2/NTit);	
++
+ 		//pmtf:
++		pmtf_colineartDouble_local=xNew<IssmDouble>(nt_local);
++		pmtf_orthotDouble_local=xNew<IssmDouble>(nt_local);
++		/*Downcast*/ /*{{{*/
++		for(int i=0;i<nt_local;i++){
++			pmtf_colineartDouble_local[i]=DownCastVarToDouble<doubletype>(pmtf_colineart_local[i*3+2]);
++			pmtf_orthotDouble_local[i]=DownCastVarToDouble<doubletype>(pmtf_orthot_local[i*3+2]);
++		}
++		/*}}}*/	
++		xDelete<doubletype>(pmtf_colineart_local);
++		xDelete<doubletype>(pmtf_orthot_local);
++		pmtf_colineartDouble=xNew<IssmDouble>(nt);
++		pmtf_orthotDouble=xNew<IssmDouble>(nt);
++
+ 		int* recvcounts=xNew<int>(IssmComm::GetSize());
+ 		int* displs=xNew<int>(IssmComm::GetSize());
+ 		int  rc;
+ 		int  offset;
+-		rc=3*nt_local;
+-		offset=3*lower_row/2/NTit;
++		rc=nt_local;
++		offset=lower_row/2/NTit;
+ 		ISSM_MPI_Allgather(&rc,1,ISSM_MPI_INT,recvcounts,1,ISSM_MPI_INT,IssmComm::GetComm());
+ 		ISSM_MPI_Allgather(&offset,1,ISSM_MPI_INT,displs,1,ISSM_MPI_INT,IssmComm::GetComm());
+-		ISSM_MPI_Allgatherv(pmtf_colineart_local, rc, ISSM_MPI_DOUBLE, pmtf_colineart, recvcounts, displs, ISSM_MPI_DOUBLE,IssmComm::GetComm());
+-		ISSM_MPI_Allgatherv(pmtf_orthot_local, rc, ISSM_MPI_DOUBLE, pmtf_orthot, recvcounts, displs, ISSM_MPI_DOUBLE,IssmComm::GetComm());
++		ISSM_MPI_Allgatherv(pmtf_colineartDouble_local, rc, ISSM_MPI_DOUBLE, pmtf_colineartDouble, recvcounts, displs, ISSM_MPI_DOUBLE,IssmComm::GetComm());
++		ISSM_MPI_Allgatherv(pmtf_orthotDouble_local, rc, ISSM_MPI_DOUBLE, pmtf_orthotDouble, recvcounts, displs, ISSM_MPI_DOUBLE,IssmComm::GetComm());
+ 		xDelete<int>(recvcounts);
+ 		xDelete<int>(displs);
++
++		xDelete<IssmDouble>(pmtf_colineartDouble_local);
++		xDelete<IssmDouble>(pmtf_orthotDouble_local);
+ 		/*}}}*/	
+ 
+-		/*Downcast and add into parameters:*/ /*{{{*/
+-		LovetDouble= new LoveNumbers<IssmDouble>(sh_nmin,sh_nmax,nt,matlitho);
+-		TidaltDouble= new LoveNumbers<IssmDouble>(2,2,nt,matlitho);	
++		if(VerboseSolution() && verbosecpu) _printf_("done\n");
++		if(VerboseSolution() && verbosecpu) _printf_("   saving results\n");
+ 
+-		pmtf_colineartDouble=xNew<IssmDouble>(nt);
+-		pmtf_orthotDouble=xNew<IssmDouble>(nt);
+-
+-		Lovet->DownCastToDouble(LovetDouble);
+-		Tidalt->DownCastToDouble(TidaltDouble);
+-		for(int i=0;i<nt;i++){
+-			pmtf_colineartDouble[i]=std::real(pmtf_colineart[2*nt+i]);
+-			pmtf_orthotDouble[i]=std::real(pmtf_orthot[2*nt+i]);
+-		}
+-
++		/* Add to parameters */ /*{{{*/
+ 		if(forcing_type==9){ //tidal loading
+-			femmodel->parameters->AddObject(new DoubleMatParam(TidalLoveHEnum,LovetDouble->H,(sh_nmax+1)*nt,1));
+-			femmodel->parameters->AddObject(new DoubleMatParam(TidalLoveKEnum,LovetDouble->K,(sh_nmax+1)*nt,1));
+-			femmodel->parameters->AddObject(new DoubleMatParam(TidalLoveLEnum,LovetDouble->L,(sh_nmax+1)*nt,1));
+-		}
++			femmodel->parameters->AddObject(new DoubleMatParam(TidalLoveHEnum,LovetDouble_local->H,(sh_nmax+1)*nt,1));
++			femmodel->parameters->AddObject(new DoubleMatParam(TidalLoveKEnum,LovetDouble_local->K,(sh_nmax+1)*nt,1));
++			femmodel->parameters->AddObject(new DoubleMatParam(TidalLoveLEnum,LovetDouble_local->L,(sh_nmax+1)*nt,1));
++				}
+ 		else if(forcing_type==11){ //surface loading
+-			femmodel->parameters->AddObject(new DoubleMatParam(LoadLoveHEnum,LovetDouble->H,(sh_nmax+1)*nt,1));
+-			femmodel->parameters->AddObject(new DoubleMatParam(LoadLoveKEnum,LovetDouble->K,(sh_nmax+1)*nt,1));
+-			femmodel->parameters->AddObject(new DoubleMatParam(LoadLoveLEnum,LovetDouble->L,(sh_nmax+1)*nt,1));
+-			femmodel->parameters->AddObject(new DoubleMatParam(TidalLoveHEnum,TidaltDouble->H,3*nt,1));
+-			femmodel->parameters->AddObject(new DoubleMatParam(TidalLoveKEnum,TidaltDouble->K,3*nt,1));
+-			femmodel->parameters->AddObject(new DoubleMatParam(TidalLoveLEnum,TidaltDouble->L,3*nt,1));
++			femmodel->parameters->AddObject(new DoubleMatParam(LoadLoveHEnum,LovetDouble_local->H,(sh_nmax+1)*nt,1));
++			femmodel->parameters->AddObject(new DoubleMatParam(LoadLoveKEnum,LovetDouble_local->K,(sh_nmax+1)*nt,1));
++			femmodel->parameters->AddObject(new DoubleMatParam(LoadLoveLEnum,LovetDouble_local->L,(sh_nmax+1)*nt,1));
++			femmodel->parameters->AddObject(new DoubleMatParam(TidalLoveHEnum,TidaltDouble_local->H,3*nt,1));
++			femmodel->parameters->AddObject(new DoubleMatParam(TidalLoveKEnum,TidaltDouble_local->K,3*nt,1));
++			femmodel->parameters->AddObject(new DoubleMatParam(TidalLoveLEnum,TidaltDouble_local->L,3*nt,1));
+ 			femmodel->parameters->AddObject(new DoubleMatParam(LovePolarMotionTransferFunctionColinearEnum,pmtf_colineartDouble,nt,1));
+ 			femmodel->parameters->AddObject(new DoubleMatParam(LovePolarMotionTransferFunctionOrthogonalEnum,pmtf_orthotDouble,nt,1));
+ 		}
+-
+-		xDelete<IssmDouble>(pmtf_colineartDouble);
+-		xDelete<IssmDouble>(pmtf_orthotDouble);
+ 		/*}}}*/	
+ 	
+-		/*Add into external results, no need to downcast, we can handle complexes/quad precision: */
+-		femmodel->results->AddObject(new GenericExternalResult<doubletype*>(femmodel->results->Size()+1,LoveKtEnum,Lovet->K,nt,sh_nmax+1,0,0));
+-		femmodel->results->AddObject(new GenericExternalResult<doubletype*>(femmodel->results->Size()+1,LoveHtEnum,Lovet->H,nt,sh_nmax+1,0,0));
+-		femmodel->results->AddObject(new GenericExternalResult<doubletype*>(femmodel->results->Size()+1,LoveLtEnum,Lovet->L,nt,sh_nmax+1,0,0));
++		/*Add into external results*/
++		femmodel->results->AddObject(new GenericExternalResult<IssmDouble*>(femmodel->results->Size()+1,LoveKtEnum,LovetDouble_local->K,nt,sh_nmax+1,0,0));
++		femmodel->results->AddObject(new GenericExternalResult<IssmDouble*>(femmodel->results->Size()+1,LoveHtEnum,LovetDouble_local->H,nt,sh_nmax+1,0,0));
++		femmodel->results->AddObject(new GenericExternalResult<IssmDouble*>(femmodel->results->Size()+1,LoveLtEnum,LovetDouble_local->L,nt,sh_nmax+1,0,0));
++		femmodel->results->AddObject(new GenericExternalResult<IssmDouble*>(femmodel->results->Size()+1,LoveKfEnum,LovefDouble_local->K,nfreq,sh_nmax+1,0,0));
++		femmodel->results->AddObject(new GenericExternalResult<IssmDouble*>(femmodel->results->Size()+1,LoveHfEnum,LovefDouble_local->H,nfreq,sh_nmax+1,0,0));
++		femmodel->results->AddObject(new GenericExternalResult<IssmDouble*>(femmodel->results->Size()+1,LoveLfEnum,LovefDouble_local->L,nfreq,sh_nmax+1,0,0));
+ 
+-		femmodel->results->AddObject(new GenericExternalResult<doubletype*>(femmodel->results->Size()+1,LoveTidalKtEnum,Tidalt->K,nt,3,0,0));
+-		femmodel->results->AddObject(new GenericExternalResult<doubletype*>(femmodel->results->Size()+1,LoveTidalHtEnum,Tidalt->H,nt,3,0,0));
+-		femmodel->results->AddObject(new GenericExternalResult<doubletype*>(femmodel->results->Size()+1,LoveTidalLtEnum,Tidalt->L,nt,3,0,0));
+-		femmodel->results->AddObject(new GenericExternalResult<doubletype*>(femmodel->results->Size()+1,LovePMTF1tEnum,pmtf_colineart,nt,3,0,0));
+-		femmodel->results->AddObject(new GenericExternalResult<doubletype*>(femmodel->results->Size()+1,LovePMTF2tEnum,pmtf_orthot,nt,3,0,0));
++		femmodel->results->AddObject(new GenericExternalResult<IssmDouble*>(femmodel->results->Size()+1,LoveTidalKtEnum,TidaltDouble_local->K,nt,3,0,0));
++		femmodel->results->AddObject(new GenericExternalResult<IssmDouble*>(femmodel->results->Size()+1,LoveTidalHtEnum,TidaltDouble_local->H,nt,3,0,0));
++		femmodel->results->AddObject(new GenericExternalResult<IssmDouble*>(femmodel->results->Size()+1,LoveTidalLtEnum,TidaltDouble_local->L,nt,3,0,0));
++		femmodel->results->AddObject(new GenericExternalResult<IssmDouble*>(femmodel->results->Size()+1,LovePMTF1tEnum,pmtf_colineartDouble,nt,1,0,0));
++		femmodel->results->AddObject(new GenericExternalResult<IssmDouble*>(femmodel->results->Size()+1,LovePMTF2tEnum,pmtf_orthotDouble,nt,1,0,0));
++		/*Only when love_kernels is on*/
++		if (love_kernels==1) {
++		//	femmodel->results->AddObject(new GenericExternalResult<IssmDouble*>(femmodel->results->Size()+1,LoveKernelsEnum,LovefDouble_local->Kernels,nfreq,(sh_nmax+1)*(matlitho->numlayers+1)*6,0,0));
++		}
+ 
+-		delete Lovet;
+-		delete Tidalt;
+-		delete Lovet_local;
+-		delete Tidalt_local;
+-		delete LovetDouble;
+-		delete TidaltDouble;
++		xDelete<IssmDouble>(pmtf_colineartDouble);
++		xDelete<IssmDouble>(pmtf_orthotDouble);
++		delete LovetDouble_local;
++		delete TidaltDouble_local;
+ 
+-		xDelete<doubletype>(pmtf_colineart);
+-		xDelete<doubletype>(pmtf_orthot);
+ 	}
+ 	else{
+ 		LoveNumbers<IssmDouble>* LovefDouble=NULL;
+-		LovefDouble= new LoveNumbers<IssmDouble>(sh_nmin,sh_nmax,nfreq,matlitho);
++		LoveNumbers<IssmDouble>* LovefDouble_local=NULL;
++		LovefDouble= new LoveNumbers<IssmDouble>(sh_nmin,sh_nmax,nfreq,lower_row,nfreq,matlitho);
++		LovefDouble_local= new LoveNumbers<IssmDouble>(sh_nmin,sh_nmax,nf_local,lower_row,nfreq,matlitho);
+ 
++		LoveNumbers<IssmDouble>* TidalfDouble=NULL;
++		LoveNumbers<IssmDouble>* TidalfDouble_local=NULL;
++		TidalfDouble= new LoveNumbers<IssmDouble>(2,2,nfreq,lower_row,nfreq,matlitho);
++		TidalfDouble_local= new LoveNumbers<IssmDouble>(2,2,nf_local,lower_row,nfreq,matlitho);
++
++		Lovef_local->DownCastToDouble(LovefDouble_local);
++		Tidalf_local->DownCastToDouble(TidalfDouble_local);
++
+ 		/*MPI_Gather*/
+ 		if (nfreq>1){
+-			Lovef->LoveMPI_Gather(Lovef_local, lower_row);
++			LovefDouble->LoveMPI_Gather(LovefDouble_local, lower_row);
+ 			if (forcing_type==11 && sh_nmin<=2 && sh_nmax>=2){
+-				Tidalf->LoveMPI_Gather(Tidalf_local, lower_row);		
++				TidalfDouble->LoveMPI_Gather(TidalfDouble_local, lower_row);		
+ 			}
+ 		}
+ 		else{
+-			Lovef->Copy(Elastic);
+-			Tidalf->Copy(Tidalf_local);
++			Elastic->DownCastToDouble(LovefDouble);
++			Tidalf_local->DownCastToDouble(TidalfDouble);
+ 		}
+ 
+ 		/*Add into parameters:*/
+-		Lovef->DownCastToDouble(LovefDouble);
+ 		if(forcing_type==9){ //tidal loading
+ 			femmodel->parameters->AddObject(new DoubleMatParam(TidalLoveHEnum,LovefDouble->H,(sh_nmax+1)*nfreq,1));
+ 			femmodel->parameters->AddObject(new DoubleMatParam(TidalLoveKEnum,LovefDouble->K,(sh_nmax+1)*nfreq,1));
+@@ -1562,112 +2100,126 @@
+ 			femmodel->parameters->AddObject(new DoubleMatParam(LoadLoveKEnum,LovefDouble->K,(sh_nmax+1)*nfreq,1));
+ 			femmodel->parameters->AddObject(new DoubleMatParam(LoadLoveLEnum,LovefDouble->L,(sh_nmax+1)*nfreq,1));
+ 		}
++
++		/*Add into external results:*/
++		if (complex_computation){
++			//FIXME: complex external result not supported yet
++			//femmodel->results->AddObject(new GenericExternalResult<IssmComplex*>(femmodel->results->Size()+1,LoveKfEnum,Lovef->K,nfreq,sh_nmax+1,0,0));
++			//femmodel->results->AddObject(new GenericExternalResult<IssmComplex*>(femmodel->results->Size()+1,LoveHfEnum,Lovef->H,nfreq,sh_nmax+1,0,0));
++			//femmodel->results->AddObject(new GenericExternalResult<IssmComplex*>(femmodel->results->Size()+1,LoveLfEnum,Lovef->L,nfreq,sh_nmax+1,0,0));
++			///*Only when love_kernels is on*/
++			//if (love_kernels==1) {
++			//	femmodel->results->AddObject(new GenericExternalResult<IssmComplex*>(femmodel->results->Size()+1,LoveKernelsEnum,Lovef->Kernels,nfreq,(sh_nmax+1)*(matlitho->numlayers+1)*6,0,0));
++			//}
++		}
++		else{
++			femmodel->results->AddObject(new GenericExternalResult<IssmDouble*>(femmodel->results->Size()+1,LoveKfEnum,LovefDouble->K,nfreq,sh_nmax+1,0,0));
++			femmodel->results->AddObject(new GenericExternalResult<IssmDouble*>(femmodel->results->Size()+1,LoveHfEnum,LovefDouble->H,nfreq,sh_nmax+1,0,0));
++			femmodel->results->AddObject(new GenericExternalResult<IssmDouble*>(femmodel->results->Size()+1,LoveLfEnum,LovefDouble->L,nfreq,sh_nmax+1,0,0));
++			/*Only when love_kernels is on*/
++			if (love_kernels==1) {
++				femmodel->results->AddObject(new GenericExternalResult<IssmDouble*>(femmodel->results->Size()+1,LoveKernelsEnum,LovefDouble->Kernels,nfreq,(sh_nmax+1)*(matlitho->numlayers+1)*6,0,0));
++			}
++		}
++
++
++		delete Lovef_local;
+ 		delete LovefDouble;
++		delete LovefDouble_local;
++		delete Tidalf_local;
++		delete TidalfDouble;
++		delete TidalfDouble_local;
+ 	}
+-
+-	/*Add into external results:*/
+-	femmodel->results->AddObject(new GenericExternalResult<doubletype*>(femmodel->results->Size()+1,LoveKfEnum,Lovef->K,nfreq,sh_nmax+1,0,0));
+-	femmodel->results->AddObject(new GenericExternalResult<doubletype*>(femmodel->results->Size()+1,LoveHfEnum,Lovef->H,nfreq,sh_nmax+1,0,0));
+-	femmodel->results->AddObject(new GenericExternalResult<doubletype*>(femmodel->results->Size()+1,LoveLfEnum,Lovef->L,nfreq,sh_nmax+1,0,0));
+-	/*Only when love_kernels is on*/
+-	if (love_kernels==1) {
+-		femmodel->results->AddObject(new GenericExternalResult<doubletype*>(femmodel->results->Size()+1,LoveKernelsEnum,Lovef->Kernels,nfreq,(sh_nmax+1)*(matlitho->numlayers+1)*6,0,0));
+-	}
+ 	/*Free resources:*/
+ 	xDelete<IssmDouble>(frequencies);
+ 	xDelete<IssmDouble>(frequencies_local);
+ 	xDelete<IssmDouble>(frequencies_elastic);
+-	delete Lovef;
+-	delete Lovef_local;
+-	delete Tidalf;
+-	delete Tidalf_local;
++
+ 	delete Elastic;
+-	/* Legacy for fortran core, to be removed after complete validation */
+ 
+-	//IssmDouble g0,r0;
+-	//femmodel->parameters->FindParam(&g0,LoveG0Enum);
+-	//femmodel->parameters->FindParam(&r0,LoveR0Enum);
+-	//IssmDouble* LoveKr = xNewZeroInit<IssmDouble>(nfreq*(sh_nmax+1));
+-	//IssmDouble* LoveHr = xNewZeroInit<IssmDouble>(nfreq*(sh_nmax+1));
+-	//IssmDouble* LoveLr = xNewZeroInit<IssmDouble>(nfreq*(sh_nmax+1));
+-	//IssmDouble* LoveKi = xNewZeroInit<IssmDouble>(nfreq*(sh_nmax+1));
+-	//IssmDouble* LoveHi = xNewZeroInit<IssmDouble>(nfreq*(sh_nmax+1));
+-	//IssmDouble* LoveLi = xNewZeroInit<IssmDouble>(nfreq*(sh_nmax+1));
+-
+-	/*Initialize love kernels (real and imaginary parts): */
+-	//IssmDouble* LoveKernelsr= xNewZeroInit<IssmDouble>(nfreq*(sh_nmax+1)*(matlitho->numlayers+1)*6);
+-	//IssmDouble* LoveKernelsi= xNewZeroInit<IssmDouble>(nfreq*(sh_nmax+1)*(matlitho->numlayers+1)*6);
+-
+-	/*call the main module: */
+-	//if (false){
+-	//FourierLoveCorex(LoveKr,LoveKi,LoveHr,LoveHr,LoveLr,LoveLi,LoveKernelsr,LoveKernelsi,  //output
+-	//		nfreq,frequencies,sh_nmax,sh_nmin,g0,r0,mu0,allow_layer_deletion,forcing_type,verbosemod, //parameter inputs
+-	//		matlitho->numlayers, matlitho->radius, matlitho->viscosity, matlitho->lame_lambda, matlitho->lame_mu,
+-	//		matlitho->burgers_viscosity, matlitho->burgers_mu, matlitho->density, matlitho->rheologymodel, matlitho->issolid //matlitho inputs
+-	//		);
+-
+-	/*Only when love_kernels is on*/
+-	//if (love_kernels==1) {
+-		//femmodel->results->AddObject(new GenericExternalResult<IssmDouble*>(femmodel->results->Size()+1,LoveKernelsEnum,LoveKernelsr,(sh_nmax+1)*(matlitho->numlayers+1)*6,nfreq,0,0));
+-		//femmodel->results->AddObject(new GenericExternalResult<IssmDouble*>(femmodel->results->Size()+1,LoveKernelsImagEnum,LoveKernelsImag,(sh_nmax+1)*(matlitho->numlayers+1)*6,nfreq,0,0));
+-	//}
+-
+-	/*Add love matrices to results:*/
+-	//femmodel->results->AddObject(new GenericExternalResult<IssmDouble*>(femmodel->results->Size()+1,LoveKtEnum,LoveKr,sh_nmax+1,nfreq,0,0));
+-	//femmodel->results->AddObject(new GenericExternalResult<IssmDouble*>(femmodel->results->Size()+1,LoveHtEnum,LoveHr,sh_nmax+1,nfreq,0,0));
+-	//femmodel->results->AddObject(new GenericExternalResult<IssmDouble*>(femmodel->results->Size()+1,LoveLtEnum,LoveLr,sh_nmax+1,nfreq,0,0));
+-	//femmodel->results->AddObject(new GenericExternalResult<IssmDouble*>(femmodel->results->Size()+1,LoveKfEnum,LoveKi,sh_nmax+1,nfreq,0,0));
+-	//femmodel->results->AddObject(new GenericExternalResult<IssmDouble*>(femmodel->results->Size()+1,LoveHfEnum,LoveHi,sh_nmax+1,nfreq,0,0));
+-	//femmodel->results->AddObject(new GenericExternalResult<IssmDouble*>(femmodel->results->Size()+1,LoveLfEnum,LoveLi,sh_nmax+1,nfreq,0,0));
+-
+-	//xDelete<IssmDouble>(LoveKr);
+-	//xDelete<IssmDouble>(LoveHr);
+-	//xDelete<IssmDouble>(LoveLr);
+-	//xDelete<IssmDouble>(LoveKernelsr);
+-	//xDelete<IssmDouble>(LoveKi);
+-	//xDelete<IssmDouble>(LoveHi);
+-	//xDelete<IssmDouble>(LoveLi);
+-	//xDelete<IssmDouble>(LoveKernelsi);
+-
+ } /*}}}*/
+ 
+ /*cores and template instantiations:*/
+ /*template instantiations :{{{*/
++// IssmDouble
+ template void love_core_template<IssmDouble>(FemModel* femmodel);
+-template void love_core_template<IssmComplex>(FemModel* femmodel);
+-template void        fill_yi_prefactor<IssmDouble>(IssmDouble* yi_prefactor, int* pdeg, IssmDouble* pomega, FemModel* femmodel, Matlitho* matlitho, LoveVariables* vars);
+-template void        fill_yi_prefactor<IssmComplex>(IssmComplex* yi_prefactor, int* pdeg, IssmComplex* pomega, FemModel* femmodel, Matlitho* matlitho, LoveVariables* vars);
+-template void        GetEarthRheology<IssmDouble>(IssmDouble* pla, IssmDouble* pmu, int layer_index, IssmDouble omega,  Matlitho* matlitho);
+-template void        GetEarthRheology<IssmComplex>(IssmComplex* pla, IssmComplex* pmu, int layer_index, IssmComplex omega,  Matlitho* matlitho);
+-template void        yi_boundary_conditions<IssmDouble>(IssmDouble* yi_righthandside, int deg, FemModel* femmodel, Matlitho* matlitho,LoveVariables* vars, int forcing_type);
+-template void        yi_boundary_conditions<IssmComplex>(IssmComplex* yi_righthandside, int deg, FemModel* femmodel, Matlitho* matlitho,LoveVariables* vars, int forcing_type);
+-template void        yi_derivatives<IssmDouble>(IssmDouble* dydx, IssmDouble* y, int layer_index, int n, IssmDouble* yi_prefactor, FemModel* femmodel, Matlitho* matlitho);
+-template void        yi_derivatives<IssmComplex>(IssmComplex* dydx, IssmComplex* y, int layer_index, int n, IssmComplex* yi_prefactor, FemModel* femmodel, Matlitho* matlitho);
+-template void        propagate_yi_RK2<IssmDouble>(IssmDouble* y, IssmDouble xmin, IssmDouble xmax, int layer_index, IssmDouble* yi_prefactor, FemModel* femmodel, Matlitho* matlitho);
+-template void        propagate_yi_RK2<IssmComplex>(IssmComplex* y, IssmDouble xmin, IssmDouble xmax, int layer_index, IssmComplex* yi_prefactor, FemModel* femmodel, Matlitho* matlitho);
+-template void        propagate_yi_euler<IssmDouble>(IssmDouble* y, IssmDouble xmin, IssmDouble xmax, int layer_index, IssmDouble* yi_prefactor, FemModel* femmodel, Matlitho* matlitho);
+-template void        propagate_yi_euler<IssmComplex>(IssmComplex* y, IssmDouble xmin, IssmDouble xmax, int layer_index, IssmComplex* yi_prefactor, FemModel* femmodel, Matlitho* matlitho);
+-template void        Innersphere_boundaryconditions<IssmDouble>(IssmDouble* yi, int layer_index, int deg, IssmDouble omega, FemModel* femmodel, Matlitho* matlitho, LoveVariables* vars);
+-template void        Innersphere_boundaryconditions<IssmComplex>(IssmComplex* yi, int layer_index, int deg, IssmComplex omega, FemModel* femmodel, Matlitho* matlitho, LoveVariables* vars);
+-template void        build_yi_system<IssmDouble>(IssmDouble* yi, int deg, IssmDouble omega, IssmDouble* yi_prefactor, FemModel* femmodel, Matlitho* matlitho,LoveVariables* vars);
+-template void        build_yi_system<IssmComplex>(IssmComplex* yi, int deg, IssmComplex omega, IssmComplex* yi_prefactor, FemModel* femmodel, Matlitho* matlitho,LoveVariables* vars);
+-template void        solve_yi_system<IssmDouble>(IssmDouble* loveh, IssmDouble* lovel, IssmDouble* lovek, int deg, IssmDouble omega, IssmDouble* frequencies, IssmDouble* yi, IssmDouble* rhs, FemModel* femmodel, Matlitho* matlitho, LoveVariables* vars,bool verbosecpu);
+-template void        solve_yi_system<IssmComplex>(IssmComplex* loveh, IssmComplex* lovel, IssmComplex* lovek, int deg, IssmComplex omega, IssmDouble* frequencies, IssmComplex* yi, IssmComplex* rhs, FemModel* femmodel, Matlitho* matlitho, LoveVariables* vars,bool verbosecpu);
+-template void	     compute_love_numbers<IssmDouble>(LoveNumbers<IssmDouble>* Lovef, LoveNumbers<IssmDouble>* Elastic, int forcing_type, int sh_cutoff,IssmDouble* frequencies, FemModel* femmodel, Matlitho* matlitho, LoveVariables* vars, bool verbosecpu);
+-template void	     compute_love_numbers<IssmComplex>(LoveNumbers<IssmComplex>* Lovef, LoveNumbers<IssmComplex>* Elastic, int forcing_type, int sh_cutoff, IssmDouble* frequencies, FemModel* femmodel, Matlitho* matlitho, LoveVariables* vars, bool verbosecpu);
++template LoveVariables<IssmDouble>*	love_init<IssmDouble>(FemModel* femmodel, Matlitho* matlitho,bool verbosecpu);
++template void        fill_yi_prefactor<IssmDouble>(IssmDouble* yi_prefactor, int* pdeg, IssmDouble* pomega, FemModel* femmodel, Matlitho* matlitho, LoveVariables<IssmDouble>* vars);
++template void        GetEarthRheology<IssmDouble>(IssmDouble* pla, IssmDouble* pmu, int layer_index, IssmDouble omega,  Matlitho* matlitho, FemModel* femmodel);
++template IssmDouble	GetGravity<IssmDouble>(IssmDouble r2, int layer_index, FemModel* femmodel, Matlitho* matlitho,LoveVariables<IssmDouble>* vars);
++template void        yi_boundary_conditions<IssmDouble>(IssmDouble* yi_righthandside, int deg, FemModel* femmodel, Matlitho* matlitho,LoveVariables<IssmDouble>* vars, int forcing_type);
++template void        yi_derivatives<IssmDouble>(IssmDouble* dydx, IssmDouble* y, int layer_index, int n, IssmDouble* yi_prefactor, FemModel* femmodel, Matlitho* matlitho, LoveVariables<IssmDouble>* vars);
++template void        propagate_yi_RK2<IssmDouble>(IssmDouble* y, IssmDouble xmin, IssmDouble xmax, int layer_index, IssmDouble* yi_prefactor, FemModel* femmodel, Matlitho* matlitho, LoveVariables<IssmDouble>* vars);
++template void        propagate_yi_RK4<IssmDouble>(IssmDouble* y, IssmDouble xmin, IssmDouble xmax, int layer_index, IssmDouble* yi_prefactor, FemModel* femmodel, Matlitho* matlitho, LoveVariables<IssmDouble>* vars);
++template void        propagate_yi_euler<IssmDouble>(IssmDouble* y, IssmDouble xmin, IssmDouble xmax, int layer_index, IssmDouble* yi_prefactor, FemModel* femmodel, Matlitho* matlitho, LoveVariables<IssmDouble>* vars);
++template void        Innersphere_boundaryconditions<IssmDouble>(IssmDouble* yi, int layer_index, int deg, IssmDouble omega, FemModel* femmodel, Matlitho* matlitho, LoveVariables<IssmDouble>* vars);
++template void	     Coremantle_boundaryconditions<IssmDouble>(IssmDouble* yi, int layer_index, int deg, IssmDouble omega, FemModel* femmodel, Matlitho* matlitho, LoveVariables<IssmDouble>* vars);
++template void        build_yi_system<IssmDouble>(IssmDouble* yi, int deg, IssmDouble omega, IssmDouble* yi_prefactor, FemModel* femmodel, Matlitho* matlitho,LoveVariables<IssmDouble>* vars);
++template void        solve_yi_system<IssmDouble>(IssmDouble* loveh, IssmDouble* lovel, IssmDouble* lovek, int deg, IssmDouble omega, IssmDouble* frequencies, IssmDouble* yi, IssmDouble* rhs, FemModel* femmodel, Matlitho* matlitho, LoveVariables<IssmDouble>* vars,bool verbosecpu);
++template void	     compute_love_numbers<IssmDouble>(LoveNumbers<IssmDouble>* Lovef, LoveNumbers<IssmDouble>* Elastic, int forcing_type, int sh_cutoff,IssmDouble* frequencies, FemModel* femmodel, Matlitho* matlitho, LoveVariables<IssmDouble>* vars, bool verbosecpu);
+ template IssmDouble  factorial<IssmDouble>(int n);
+ template IssmDouble* postwidder_coef<IssmDouble>(int NTit);
+ template IssmDouble  n_C_r<IssmDouble>(int n, int r);
+ template void         postwidder_transform<IssmDouble>(IssmDouble* Lovet, IssmDouble* Lovef,int d, int t, int sh_nmax,int NTit, IssmDouble* xi, FemModel* femmodel);
++template void        EarthRheology<IssmDouble>(LoveVariables<IssmDouble>* vars, IssmDouble* frequencies, int nfreq,  Matlitho* matlitho, FemModel* femmodel);
++template IssmDouble HypergeomTableLookup(IssmDouble z1, IssmDouble alpha, IssmDouble* h1, IssmDouble* z, int nz, int nalpha);
+ 
++//IssmComplex
++template void love_core_template<IssmComplex>(FemModel* femmodel);
++template LoveVariables<IssmComplex>*	love_init<IssmComplex>(FemModel* femmodel, Matlitho* matlitho,bool verboscpu);
++template void        fill_yi_prefactor<IssmComplex>(IssmComplex* yi_prefactor, int* pdeg, IssmComplex* pomega, FemModel* femmodel, Matlitho* matlitho, LoveVariables<IssmComplex>* vars);
++template void        GetEarthRheology<IssmComplex>(IssmComplex* pla, IssmComplex* pmu, int layer_index, IssmComplex omega,  Matlitho* matlitho, FemModel* femmodel);
++template IssmComplex	GetGravity<IssmComplex>(IssmComplex r2, int layer_index, FemModel* femmodel, Matlitho* matlitho,LoveVariables<IssmComplex>* vars);
++template void        yi_boundary_conditions<IssmComplex>(IssmComplex* yi_righthandside, int deg, FemModel* femmodel, Matlitho* matlitho,LoveVariables<IssmComplex>* vars, int forcing_type);
++template void        yi_derivatives<IssmComplex>(IssmComplex* dydx, IssmComplex* y, int layer_index, int n, IssmComplex* yi_prefactor, FemModel* femmodel, Matlitho* matlitho, LoveVariables<IssmComplex>* vars);
++template void        propagate_yi_RK2<IssmComplex>(IssmComplex* y, IssmComplex xmin, IssmComplex xmax, int layer_index, IssmComplex* yi_prefactor, FemModel* femmodel, Matlitho* matlitho, LoveVariables<IssmComplex>* vars);
++template void        propagate_yi_RK4<IssmComplex>(IssmComplex* y, IssmComplex xmin, IssmComplex xmax, int layer_index, IssmComplex* yi_prefactor, FemModel* femmodel, Matlitho* matlitho, LoveVariables<IssmComplex>* vars);
++template void        propagate_yi_euler<IssmComplex>(IssmComplex* y, IssmComplex xmin, IssmComplex xmax, int layer_index, IssmComplex* yi_prefactor, FemModel* femmodel, Matlitho* matlitho, LoveVariables<IssmComplex>* vars);
++template void        Innersphere_boundaryconditions<IssmComplex>(IssmComplex* yi, int layer_index, int deg, IssmComplex omega, FemModel* femmodel, Matlitho* matlitho, LoveVariables<IssmComplex>* vars);
++template void	     Coremantle_boundaryconditions<IssmComplex>(IssmComplex* yi, int layer_index, int deg, IssmComplex omega, FemModel* femmodel, Matlitho* matlitho, LoveVariables<IssmComplex>* vars);
++template void        build_yi_system<IssmComplex>(IssmComplex* yi, int deg, IssmComplex omega, IssmComplex* yi_prefactor, FemModel* femmodel, Matlitho* matlitho,LoveVariables<IssmComplex>* vars);
++template void        solve_yi_system<IssmComplex>(IssmComplex* loveh, IssmComplex* lovel, IssmComplex* lovek, int deg, IssmComplex omega, IssmDouble* frequencies, IssmComplex* yi, IssmComplex* rhs, FemModel* femmodel, Matlitho* matlitho, LoveVariables<IssmComplex>* vars,bool verbosecpu);
++template void	     compute_love_numbers<IssmComplex>(LoveNumbers<IssmComplex>* Lovef, LoveNumbers<IssmComplex>* Elastic, int forcing_type, int sh_cutoff, IssmDouble* frequencies, FemModel* femmodel, Matlitho* matlitho, LoveVariables<IssmComplex>* vars, bool verbosecpu);
++template void        EarthRheology<IssmComplex>(LoveVariables<IssmComplex>* vars, IssmDouble* frequencies, int nfreq,  Matlitho* matlitho, FemModel* femmodel);
++template IssmComplex HypergeomTableLookup(IssmComplex z1, IssmComplex alpha, IssmDouble* h1, IssmDouble* z, int nz, int nalpha);
++
++//__float128
++#ifdef _HAVE_MPLAPACK_
++template void love_core_template<__float128>(FemModel* femmodel);
++template LoveVariables<__float128>*	love_init<__float128>(FemModel* femmodel, Matlitho* matlitho, bool verbosecpu);
++template void        fill_yi_prefactor<__float128>(__float128* yi_prefactor, int* pdeg, __float128* pomega, FemModel* femmodel, Matlitho* matlitho, LoveVariables<__float128>* vars);
++template void        GetEarthRheology<__float128>(__float128* pla, __float128* pmu, int layer_index, __float128 omega,  Matlitho* matlitho, FemModel* femmodel);
++template __float128	GetGravity<__float128>(__float128 r2, int layer_index, FemModel* femmodel, Matlitho* matlitho,LoveVariables<__float128>* vars);
++template void        yi_boundary_conditions<__float128>(__float128* yi_righthandside, int deg, FemModel* femmodel, Matlitho* matlitho,LoveVariables<__float128>* vars, int forcing_type);
++template void        yi_derivatives<__float128>(__float128* dydx, __float128* y, int layer_index, int n, __float128* yi_prefactor, FemModel* femmodel, Matlitho* matlitho, LoveVariables<__float128>* vars);
++template void        propagate_yi_RK2<__float128>(__float128* y, __float128 xmin, __float128 xmax, int layer_index, __float128* yi_prefactor, FemModel* femmodel, Matlitho* matlitho, LoveVariables<__float128>* vars);
++template void        propagate_yi_RK4<__float128>(__float128* y, __float128 xmin, __float128 xmax, int layer_index, __float128* yi_prefactor, FemModel* femmodel, Matlitho* matlitho, LoveVariables<__float128>* vars);
++template void        propagate_yi_euler<__float128>(__float128* y, __float128 xmin, __float128 xmax, int layer_index, __float128* yi_prefactor, FemModel* femmodel, Matlitho* matlitho, LoveVariables<__float128>* vars);
++template void        Innersphere_boundaryconditions<__float128>(__float128* yi, int layer_index, int deg, __float128 omega, FemModel* femmodel, Matlitho* matlitho, LoveVariables<__float128>* vars);
++template void 	     Coremantle_boundaryconditions<__float128>(__float128* yi, int layer_index, int deg, __float128 omega, FemModel* femmodel, Matlitho* matlitho, LoveVariables<__float128>* vars);
++template void        build_yi_system<__float128>(__float128* yi, int deg, __float128 omega, __float128* yi_prefactor, FemModel* femmodel, Matlitho* matlitho,LoveVariables<__float128>* vars);
++template void        solve_yi_system<__float128>(__float128* loveh, __float128* lovel, __float128* lovek, int deg, __float128 omega, IssmDouble* frequencies, __float128* yi, __float128* rhs, FemModel* femmodel, Matlitho* matlitho, LoveVariables<__float128>* vars,bool verbosecpu);
++template void	     compute_love_numbers<__float128>(LoveNumbers<__float128>* Lovef, LoveNumbers<__float128>* Elastic, int forcing_type, int sh_cutoff, IssmDouble* frequencies, FemModel* femmodel, Matlitho* matlitho, LoveVariables<__float128>* vars, bool verbosecpu);
++template __float128  factorial<__float128>(int n);
++template __float128* postwidder_coef<__float128>(int NTit);
++template __float128  n_C_r<__float128>(int n, int r);
++template void        postwidder_transform<__float128>(__float128* Lovet, __float128* Lovef,int d, int t, int sh_nmax,int NTit, __float128* xi, FemModel* femmodel);
++template void        EarthRheology<__float128>(LoveVariables<__float128>* vars, IssmDouble* frequencies, int nfreq,  Matlitho* matlitho, FemModel* femmodel);
++template __float128 HypergeomTableLookup(__float128 z1, __float128 alpha, IssmDouble* h1, IssmDouble* z, int nz, int nalpha);
++#endif
++
+ /*}}}*/
+ void           love_core(FemModel* femmodel){ /*{{{*/
+-
+ 	bool        complex_computation;
++	bool        quad_precision;
+ 
+ 	femmodel->parameters->FindParam(&complex_computation,LoveComplexComputationEnum);
++	femmodel->parameters->FindParam(&quad_precision,LoveQuadPrecisionEnum);
+ 
+ 	if(complex_computation) love_core_template<IssmComplex>(femmodel);
++#ifdef _HAVE_MPLAPACK_
++	else if(quad_precision) love_core_template<__float128>(femmodel);
++#endif
+ 	else                    love_core_template<IssmDouble>(femmodel);
+ 
+ } /*}}}*/
+Index: ../trunk-jpl/test/NightlyRun/test2071.m
+===================================================================
+--- ../trunk-jpl/test/NightlyRun/test2071.m	(revision 27307)
++++ ../trunk-jpl/test/NightlyRun/test2071.m	(revision 27308)
+@@ -39,7 +39,7 @@
+ md.love.underflow_tol=1e-20;
+ md.love.pw_threshold=1e-3;
+ md.love.Gravitational_Constant=6.6732e-11;
+-md.love.integration_steps_per_layer=100;
++md.love.min_integration_steps=100;
+ md.love.allow_layer_deletion=1;
+ md.love.forcing_type=11;
+ md.love.chandler_wobble=0;
+Index: ../trunk-jpl/test/NightlyRun/test2072.m
+===================================================================
+--- ../trunk-jpl/test/NightlyRun/test2072.m	(revision 27307)
++++ ../trunk-jpl/test/NightlyRun/test2072.m	(revision 27308)
+@@ -43,7 +43,7 @@
+ md.love.underflow_tol=1e-20;
+ md.love.pw_threshold=1e-3;
+ md.love.Gravitational_Constant=6.6732e-11;
+-md.love.integration_steps_per_layer=100;
++md.love.min_integration_steps=100;
+ md.love.allow_layer_deletion=1;
+ md.love.forcing_type=11;
+ md.love.chandler_wobble=0;
Index: /issm/oecreview/Archive/27230-27343/ISSM-27308-27309.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27308-27309.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27308-27309.diff	(revision 27344)
@@ -0,0 +1,13 @@
+Index: ../trunk-jpl/src/c/cores/love_core.cpp
+===================================================================
+--- ../trunk-jpl/src/c/cores/love_core.cpp	(revision 27308)
++++ ../trunk-jpl/src/c/cores/love_core.cpp	(revision 27309)
+@@ -461,7 +461,7 @@
+ 	IssmDouble  factor=0;
+ 	IssmComplex z1, z2;
+ 	IssmComplex U1, U2;
+-	IssmComplex j=1i;
++	IssmComplex j=reCast<IssmComplex>(complex<double>(0,1));
+ 	//Matlitho parameters
+ 	IssmDouble alpha=matlitho->ebm_alpha[layer_index];
+ 	IssmDouble delta=matlitho->ebm_delta[layer_index];
Index: /issm/oecreview/Archive/27230-27343/ISSM-27309-27310.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27309-27310.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27309-27310.diff	(revision 27344)
@@ -0,0 +1,16 @@
+Index: ../trunk-jpl/test/Archives/Archive2002.arch
+===================================================================
+Cannot display: file marked as a binary type.
+svn:mime-type = application/octet-stream
+Index: ../trunk-jpl/test/Archives/Archive2005.arch
+===================================================================
+Cannot display: file marked as a binary type.
+svn:mime-type = application/octet-stream
+Index: ../trunk-jpl/test/Archives/Archive2008.arch
+===================================================================
+Cannot display: file marked as a binary type.
+svn:mime-type = application/octet-stream
+Index: ../trunk-jpl/test/Archives/Archive2090.arch
+===================================================================
+Cannot display: file marked as a binary type.
+svn:mime-type = application/octet-stream
Index: /issm/oecreview/Archive/27230-27343/ISSM-27310-27311.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27310-27311.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27310-27311.diff	(revision 27344)
@@ -0,0 +1,39 @@
+Index: ../trunk-jpl/test/Archives/Archive2002.arch
+===================================================================
+Cannot display: file marked as a binary type.
+svn:mime-type = application/octet-stream
+Index: ../trunk-jpl/test/Archives/Archive2005.arch
+===================================================================
+Cannot display: file marked as a binary type.
+svn:mime-type = application/octet-stream
+Index: ../trunk-jpl/test/Archives/Archive2008.arch
+===================================================================
+Cannot display: file marked as a binary type.
+svn:mime-type = application/octet-stream
+Index: ../trunk-jpl/test/Archives/Archive2070.arch
+===================================================================
+Cannot display: file marked as a binary type.
+svn:mime-type = application/octet-stream
+Index: ../trunk-jpl/test/Archives/Archive2071.arch
+===================================================================
+Cannot display: file marked as a binary type.
+svn:mime-type = application/octet-stream
+Index: ../trunk-jpl/test/Archives/Archive2072.arch
+===================================================================
+Cannot display: file marked as a binary type.
+svn:mime-type = application/octet-stream
+Index: ../trunk-jpl/test/Archives/Archive2073.arch
+===================================================================
+Cannot display: file marked as a binary type.
+svn:mime-type = application/octet-stream
+
+Property changes on: ../trunk-jpl/test/Archives/Archive2073.arch
+___________________________________________________________________
+Added: svn:mime-type
+## -0,0 +1 ##
++application/octet-stream
+\ No newline at end of property
+Index: ../trunk-jpl/test/Archives/Archive2090.arch
+===================================================================
+Cannot display: file marked as a binary type.
+svn:mime-type = application/octet-stream
Index: /issm/oecreview/Archive/27230-27343/ISSM-27311-27312.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27311-27312.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27311-27312.diff	(revision 27344)
@@ -0,0 +1,25 @@
+Index: ../trunk-jpl/test/NightlyRun/test2071.m
+===================================================================
+--- ../trunk-jpl/test/NightlyRun/test2071.m	(revision 27311)
++++ ../trunk-jpl/test/NightlyRun/test2071.m	(revision 27312)
+@@ -63,7 +63,7 @@
+ 
+ %Fields and tolerances to track changes
+ field_names     ={'LoveH_loading_temporal','LoveK_loading_temporal','LoveL_loading_temporal'};
+-field_tolerances={3.0e-7,3.0e-7,8.0e-8};
++field_tolerances={4.0e-7,3.0e-7,8.0e-8};
+ field_values={h,k,l};
+ 
+ spada=0;
+Index: ../trunk-jpl/test/NightlyRun/test2072.m
+===================================================================
+--- ../trunk-jpl/test/NightlyRun/test2072.m	(revision 27311)
++++ ../trunk-jpl/test/NightlyRun/test2072.m	(revision 27312)
+@@ -65,6 +65,6 @@
+ %Fields and tolerances to track changes
+ 
+ field_names     ={'LoveH_loading_elastic','LoveK_loading_elastic','LoveL_loading_elastic'};
+-field_tolerances={3.0e-6,1.0e-5,5.0e-7};
++field_tolerances={3.0e-6,1.0e-5,6.0e-7};
+ field_values={h,k,l};
+ 
Index: /issm/oecreview/Archive/27230-27343/ISSM-27312-27313.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27312-27313.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27312-27313.diff	(revision 27344)
@@ -0,0 +1,49 @@
+Index: ../trunk-jpl/src/c/classes/Elements/Tria.cpp
+===================================================================
+--- ../trunk-jpl/src/c/classes/Elements/Tria.cpp	(revision 27312)
++++ ../trunk-jpl/src/c/classes/Elements/Tria.cpp	(revision 27313)
+@@ -568,6 +568,13 @@
+ 	IssmDouble B, n, H, bed, vx, vy, vel, smb;
+ 	IssmDouble ds, db, da, dt, dw, r, R;
+ 
++	if(!IsIceInElement()){
++		for (int iv=0;iv<NUMVERTICES;iv++) calvingrate[iv]=0.;
++		this->AddInput(CalvingCalvingrateEnum,&calvingrate[0],P1DGEnum);
++		this->CalvingRateToVector();
++		return;
++	}
++
+ 	/*Retrieve all inputs and parameters we will need*/
+ 	IssmDouble rc        = FindParam(CalvingRcEnum);
+ 	IssmDouble rho_ice   = FindParam(MaterialsRhoIceEnum);
+@@ -617,8 +624,8 @@
+          db = (rho_ice)/(rho_water - rho_ice) * ds;
+ 
+          /*3. "Additional" crevasse opening*/
+-         vel = sqrt(vx*vx + vy*vy)/(365.25*24*3600);
+-         da = H* max(0., log(vel/1600.))/log(1.2);
++			vel = sqrt(vx*vx + vy*vy);
++			da = H* max(0., log(vel*365*24*3600/1600.))/log(1.2);
+ 
+          /*4. deal with shallow ice*/
+          dt = H* max(0., min(1., (150. - H)/50.));
+@@ -626,7 +633,7 @@
+          /*5. water induced opening*/
+          dw = 0.;
+          R = smb*365.25*24*3600; //convert from m/s to m/yr
+-         if(R>1.5 && R<=3.){
++			if(R>1.5 && R<=3.){
+             dw = 4*1.5*(R - 1.5);
+          }
+          else if(R>3.){
+@@ -635,6 +642,10 @@
+ 
+          /*Total calving rate*/
+          r = (ds+db+da+dt+dw)/H;
++			//if(this->Id()==1){
++			//	printf("rc = %g\n",rc);
++			//	printf("ds = %g\n",ds);
++			//}
+ 			calvingrate[iv]= mig_max * max(0., min(1., (r - rc)/(1 - rc))); //P&DC: mig_max = 3000 m/yr
+ 			_assert_(!xIsNan<IssmDouble>(calvingrate[iv]));
+ 			_assert_(!xIsInf<IssmDouble>(calvingrate[iv]));
Index: /issm/oecreview/Archive/27230-27343/ISSM-27313-27314.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27313-27314.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27313-27314.diff	(revision 27344)
@@ -0,0 +1,92 @@
+Index: ../trunk-jpl/src/c/cores/transient_core.cpp
+===================================================================
+--- ../trunk-jpl/src/c/cores/transient_core.cpp	(revision 27313)
++++ ../trunk-jpl/src/c/cores/transient_core.cpp	(revision 27314)
+@@ -158,13 +158,11 @@
+ 	femmodel->parameters->FindParam(&numoutputs,TransientNumRequestedOutputsEnum);
+ 	femmodel->parameters->FindParam(&isstochasticforcing,StochasticForcingIsStochasticForcingEnum);
+ 
+-#if defined(_HAVE_OCEAN_ )
++#if defined(_HAVE_OCEAN_)
+ 	if(isoceancoupling) OceanExchangeDatax(femmodel,false);
+ #endif
+ 
+-	if(isstochasticforcing){
+-		StochasticForcingx(femmodel);
+-	}
++	if(isstochasticforcing) StochasticForcingx(femmodel);
+ 
+ 	if(isthermal && domaintype==Domain3DEnum){
+ 		if(issmb){
+@@ -189,29 +187,17 @@
+ 	}
+ 
+ 	/* Using Hydrology dc  coupled we need to compute smb in the hydrology inner time loop*/
+-	if(issmb) {
+-		smb_core(femmodel);
+-	}
++	if(issmb) smb_core(femmodel);
+ 
+-	if(ishydrology){
+-		hydrology_core(femmodel);
+-	}
++	if(ishydrology) hydrology_core(femmodel);
+ 
+-	if(isstressbalance && (step%sb_coupling_frequency==0 || step==1) ) {
+-		stressbalance_core(femmodel);
+-	}
++	if(isstressbalance && (step%sb_coupling_frequency==0 || step==1)) stressbalance_core(femmodel);
+ 
+-	if(isdamageevolution) {
+-		damage_core(femmodel);
+-	}
++	if(isdamageevolution) damage_core(femmodel);
+ 
+-	if(ismovingfront)	{
+-		movingfront_core(femmodel);
+-	}
++	if(ismovingfront)	movingfront_core(femmodel);
+ 
+-	if(isdebris){
+-		debris_core(femmodel);
+-	}
++	if(isdebris) debris_core(femmodel);
+ 
+ 	/* from here on, prepare geometry for next time step*/
+ 
+@@ -218,18 +204,15 @@
+ 	if(ismasstransport){
+ 		bmb_core(femmodel);
+ 		masstransport_core(femmodel);
+-		femmodel->UpdateVertexPositionsx();
+ 	}
+ 
+-	if(isoceantransport){
+-		oceantransport_core(femmodel);
+-	}
++	if(isoceantransport) oceantransport_core(femmodel);
+ 
+-	if(isgroundingline){
+-		groundingline_core(femmodel);
+-	}
++	if(isgroundingline) groundingline_core(femmodel);
+ 
+-	/*esa: */
++	/*Update mesh vertices now that we have changed the geometry*/
++	if(ismasstransport || isgroundingline) femmodel->UpdateVertexPositionsx();
++
+ 	if(isesa) esa_core(femmodel);
+ 
+ 	/*Sea level change: */
+@@ -242,10 +225,7 @@
+ 	}
+ 
+ 	/*Sampling: */
+-	if(issampling){
+-		if(VerboseSolution()) _printf0_("   computing Gaussian random field\n");
+-		sampling_core(femmodel);
+-	}
++	if(issampling) sampling_core(femmodel);
+ 
+ 	/*Any requested output that needs to be saved?*/
+ 	if(numoutputs){
Index: /issm/oecreview/Archive/27230-27343/ISSM-27314-27315.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27314-27315.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27314-27315.diff	(revision 27344)
@@ -0,0 +1,193 @@
+Index: ../trunk-jpl/src/c/analyses/HydrologyGlaDSAnalysis.cpp
+===================================================================
+--- ../trunk-jpl/src/c/analyses/HydrologyGlaDSAnalysis.cpp	(revision 27314)
++++ ../trunk-jpl/src/c/analyses/HydrologyGlaDSAnalysis.cpp	(revision 27315)
+@@ -157,17 +157,108 @@
+ 	}
+ 
+ 	/*Friction law variables*/
++	int FrictionCoupling;
+ 	switch(frictionlaw){
+ 		case 1:
++			iomodel->FindConstant(&FrictionCoupling,"md.friction.coupling");
+ 			iomodel->FetchDataToInput(inputs,elements,"md.friction.coefficient",FrictionCoefficientEnum);
+ 			iomodel->FetchDataToInput(inputs,elements,"md.friction.p",FrictionPEnum);
+ 			iomodel->FetchDataToInput(inputs,elements,"md.friction.q",FrictionQEnum);
++			if(FrictionCoupling==3){
++				iomodel->FetchDataToInput(inputs,elements,"md.friction.effective_pressure",FrictionEffectivePressureEnum);}
++			else if(FrictionCoupling==4){
++				iomodel->FetchDataToInput(inputs,elements,"md.friction.effective_pressure",EffectivePressureEnum);
++			}
+ 			break;
+-		case 8:
++		case 2:
++			iomodel->FetchDataToInput(inputs,elements,"md.friction.C",FrictionCEnum);
++			iomodel->FetchDataToInput(inputs,elements,"md.friction.m",FrictionMEnum);
++			break;
++		case 3:
++			iomodel->FindConstant(&FrictionCoupling,"md.friction.coupling");
++			iomodel->FetchDataToInput(inputs,elements,"md.friction.C",FrictionCEnum);
++			iomodel->FetchDataToInput(inputs,elements,"md.friction.As",FrictionAsEnum);
++			iomodel->FetchDataToInput(inputs,elements,"md.friction.q",FrictionQEnum);
++			if(FrictionCoupling==3){
++				iomodel->FetchDataToInput(inputs,elements,"md.friction.effective_pressure",FrictionEffectivePressureEnum);}
++			else if(FrictionCoupling==4){
++				iomodel->FetchDataToInput(inputs,elements,"md.friction.effective_pressure",EffectivePressureEnum);
++			}
++			break;
++		case 4:
+ 			iomodel->FetchDataToInput(inputs,elements,"md.friction.coefficient",FrictionCoefficientEnum);
++			iomodel->FetchDataToInput(inputs,elements,"md.friction.p",FrictionPEnum);
++			iomodel->FetchDataToInput(inputs,elements,"md.friction.q",FrictionQEnum);
++			iomodel->FetchDataToInput(inputs,elements,"md.initialization.pressure",PressureEnum);
++			iomodel->FetchDataToInput(inputs,elements,"md.initialization.temperature",TemperatureEnum);
++			iomodel->FindConstant(&FrictionCoupling,"md.friction.coupling");
+ 			break;
++		case 5:
++			iomodel->FetchDataToInput(inputs,elements,"md.friction.coefficient",FrictionCoefficientEnum);
++			iomodel->FetchDataToInput(inputs,elements,"md.friction.p",FrictionPEnum);
++			iomodel->FetchDataToInput(inputs,elements,"md.friction.q",FrictionQEnum);
++			iomodel->FetchDataToInput(inputs,elements,"md.friction.water_layer",FrictionWaterLayerEnum);
++			break;
++		case 6:
++			iomodel->FetchDataToInput(inputs,elements,"md.friction.C",FrictionCEnum);
++			iomodel->FetchDataToInput(inputs,elements,"md.friction.m",FrictionMEnum);
++			iomodel->FetchDataToInput(inputs,elements,"md.initialization.pressure",PressureEnum);
++			iomodel->FetchDataToInput(inputs,elements,"md.initialization.temperature",TemperatureEnum);
++			break;
++		case 7:
++			iomodel->FindConstant(&FrictionCoupling,"md.friction.coupling");
++			iomodel->FetchDataToInput(inputs,elements,"md.friction.coefficient",FrictionCoefficientEnum);
++			iomodel->FetchDataToInput(inputs,elements,"md.friction.coefficientcoulomb",FrictionCoefficientcoulombEnum);
++			iomodel->FetchDataToInput(inputs,elements,"md.friction.p",FrictionPEnum);
++			iomodel->FetchDataToInput(inputs,elements,"md.friction.q",FrictionQEnum);
++			if(FrictionCoupling==3){
++				iomodel->FetchDataToInput(inputs,elements,"md.friction.effective_pressure",FrictionEffectivePressureEnum);}
++			else if(FrictionCoupling==4){
++				iomodel->FetchDataToInput(inputs,elements,"md.friction.effective_pressure",EffectivePressureEnum);
++
++			}
++			break;
++		case 9:
++			iomodel->FetchDataToInput(inputs,elements,"md.initialization.temperature",TemperatureEnum);
++			iomodel->FetchDataToInput(inputs,elements,"md.friction.coefficient",FrictionCoefficientEnum);
++			iomodel->FetchDataToInput(inputs,elements,"md.friction.pressure_adjusted_temperature",FrictionPressureAdjustedTemperatureEnum);
++			InputUpdateFromConstantx(inputs,elements,1.,FrictionPEnum);
++			InputUpdateFromConstantx(inputs,elements,1.,FrictionQEnum);
++			break;
++		case 10:
++			iomodel->FetchDataToInput(inputs,elements,"md.friction.till_friction_angle",FrictionTillFrictionAngleEnum);
++			iomodel->FetchDataToInput(inputs,elements,"md.friction.sediment_compressibility_coefficient",FrictionSedimentCompressibilityCoefficientEnum);
++			iomodel->FetchDataToInput(inputs,elements,"md.hydrology.watercolumn_max",HydrologyWatercolumnMaxEnum);
++			iomodel->FetchDataToInput(inputs,elements,"md.initialization.watercolumn",WatercolumnEnum,0.);
++			break;
++		case 11:
++			iomodel->FindConstant(&FrictionCoupling,"md.friction.coupling");
++			iomodel->FetchDataToInput(inputs,elements,"md.friction.m",FrictionMEnum);
++			iomodel->FetchDataToInput(inputs,elements,"md.friction.C",FrictionCEnum);
++			iomodel->FetchDataToInput(inputs,elements,"md.friction.Cmax",FrictionCmaxEnum);
++			if(FrictionCoupling==3){
++				iomodel->FetchDataToInput(inputs,elements,"md.friction.effective_pressure",FrictionEffectivePressureEnum);}
++			else if(FrictionCoupling==4){
++				iomodel->FetchDataToInput(inputs,elements,"md.friction.effective_pressure",EffectivePressureEnum);
++			}
++			break;
++		case 12:
++			iomodel->FetchDataToInput(inputs,elements,"md.friction.m",FrictionMEnum);
++			iomodel->FetchDataToInput(inputs,elements,"md.friction.C",FrictionCEnum);
++			iomodel->FetchDataToInput(inputs,elements,"md.friction.f",FrictionfEnum);
++			break;
++		case 13:
++			iomodel->FindConstant(&FrictionCoupling,"md.friction.coupling");
++			iomodel->FetchDataToInput(inputs,elements,"md.friction.C",FrictionCEnum);
++			iomodel->FetchDataToInput(inputs,elements,"md.friction.m",FrictionMEnum);
++			if(FrictionCoupling==3){
++				iomodel->FetchDataToInput(inputs,elements,"md.friction.effective_pressure",FrictionEffectivePressureEnum);}
++			else if(FrictionCoupling==4){
++				iomodel->FetchDataToInput(inputs,elements,"md.friction.effective_pressure",EffectivePressureEnum);
++			}
++			break;
+ 		default:
+-			_error_("Friction law "<< frictionlaw <<" not supported");
++			_error_("friction law "<< frictionlaw <<" not supported");
+ 	}
+ }/*}}}*/
+ void HydrologyGlaDSAnalysis::UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum){/*{{{*/
+@@ -194,23 +285,61 @@
+ 	/*Deal with friction parameters*/
+ 	int frictionlaw;
+ 	iomodel->FindConstant(&frictionlaw,"md.friction.law");
+-	if(frictionlaw==6){
+-		parameters->AddObject(iomodel->CopyConstantObject("md.friction.gamma",FrictionGammaEnum));
++	switch(frictionlaw){
++		case 1:
++			parameters->AddObject(iomodel->CopyConstantObject("md.friction.coupling",FrictionCouplingEnum));
++			parameters->AddObject(iomodel->CopyConstantObject("md.friction.effective_pressure_limit",FrictionEffectivePressureLimitEnum));
++			break;
++		case 2:
++			break;
++		case 3:
++			parameters->AddObject(iomodel->CopyConstantObject("md.friction.coupling",FrictionCouplingEnum));
++			parameters->AddObject(iomodel->CopyConstantObject("md.friction.effective_pressure_limit",FrictionEffectivePressureLimitEnum));
++			break;
++		case 4:
++			parameters->AddObject(iomodel->CopyConstantObject("md.friction.gamma",FrictionGammaEnum));
++			parameters->AddObject(iomodel->CopyConstantObject("md.friction.coupling",FrictionCouplingEnum));
++			parameters->AddObject(iomodel->CopyConstantObject("md.friction.effective_pressure_limit",FrictionEffectivePressureLimitEnum));
++			break;
++		case 5:
++			parameters->AddObject(iomodel->CopyConstantObject("md.friction.f",FrictionFEnum));
++			break;
++		case 6:
++			parameters->AddObject(iomodel->CopyConstantObject("md.friction.gamma",FrictionGammaEnum));
++			break;
++		case 7:
++			parameters->AddObject(iomodel->CopyConstantObject("md.friction.coupling",FrictionCouplingEnum));
++			parameters->AddObject(iomodel->CopyConstantObject("md.friction.effective_pressure_limit",FrictionEffectivePressureLimitEnum));
++			break;
++		case 8:
++			break;
++		case 9:
++			parameters->AddObject(iomodel->CopyConstantObject("md.friction.gamma",FrictionGammaEnum));
++			parameters->AddObject(iomodel->CopyConstantObject("md.friction.effective_pressure_limit",FrictionEffectivePressureLimitEnum));
++			parameters->AddObject(new IntParam(FrictionCouplingEnum,0));
++			break;
++		case 10:
++			parameters->AddObject(new IntParam(FrictionCouplingEnum,2)); /*comment this line to use effective pressure from Beuler and Pelt (2015)*/
++			parameters->AddObject(new DoubleParam(FrictionEffectivePressureLimitEnum,0.));
++			parameters->AddObject(iomodel->CopyConstantObject("md.friction.pseudoplasticity_exponent",FrictionPseudoplasticityExponentEnum));
++			parameters->AddObject(iomodel->CopyConstantObject("md.friction.threshold_speed",FrictionThresholdSpeedEnum));
++			parameters->AddObject(iomodel->CopyConstantObject("md.friction.delta",FrictionDeltaEnum));
++			parameters->AddObject(iomodel->CopyConstantObject("md.friction.void_ratio",FrictionVoidRatioEnum));
++			break;
++		case 11:
++			parameters->AddObject(iomodel->CopyConstantObject("md.friction.coupling",FrictionCouplingEnum));
++			parameters->AddObject(iomodel->CopyConstantObject("md.friction.effective_pressure_limit",FrictionEffectivePressureLimitEnum));
++			break;
++		case 12:
++			parameters->AddObject(new IntParam(FrictionCouplingEnum,2));
++			parameters->AddObject(iomodel->CopyConstantObject("md.friction.effective_pressure_limit",FrictionEffectivePressureLimitEnum));
++			break;
++		case 13:
++			parameters->AddObject(iomodel->CopyConstantObject("md.friction.coupling",FrictionCouplingEnum));
++			parameters->AddObject(iomodel->CopyConstantObject("md.friction.effective_pressure_limit",FrictionEffectivePressureLimitEnum));
++			break;
++		default: _error_("Friction law "<<frictionlaw<<" not implemented yet");
+ 	}
+-	if(frictionlaw==4){
+-		parameters->AddObject(iomodel->CopyConstantObject("md.friction.gamma",FrictionGammaEnum));
+-		parameters->AddObject(iomodel->CopyConstantObject("md.friction.coupling",FrictionCouplingEnum));
+-		parameters->AddObject(iomodel->CopyConstantObject("md.friction.effective_pressure_limit",FrictionEffectivePressureLimitEnum));
+-	}
+-	if(frictionlaw==1 || frictionlaw==3 || frictionlaw==7){
+-		parameters->AddObject(iomodel->CopyConstantObject("md.friction.coupling",FrictionCouplingEnum));
+-		parameters->AddObject(iomodel->CopyConstantObject("md.friction.effective_pressure_limit",FrictionEffectivePressureLimitEnum));
+-	}
+-	if(frictionlaw==9){
+-		parameters->AddObject(iomodel->CopyConstantObject("md.friction.gamma",FrictionGammaEnum));
+-		parameters->AddObject(iomodel->CopyConstantObject("md.friction.effective_pressure_limit",FrictionEffectivePressureLimitEnum));
+-		parameters->AddObject(new IntParam(FrictionCouplingEnum,0));
+-	}
+ 
+ 	/*Requested outputs*/
+ 	iomodel->FindConstant(&requestedoutputs,&numoutputs,"md.hydrology.requested_outputs");
Index: /issm/oecreview/Archive/27230-27343/ISSM-27315-27316.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27315-27316.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27315-27316.diff	(revision 27344)
@@ -0,0 +1,13 @@
+Index: ../trunk-jpl/src/m/classes/timesteppingadaptive.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/timesteppingadaptive.m	(revision 27315)
++++ ../trunk-jpl/src/m/classes/timesteppingadaptive.m	(revision 27316)
+@@ -12,7 +12,7 @@
+ 		cfl_coefficient = 0.;
+ 		interp_forcing  = 1;
+ 		average_forcing = 0;
+-		cycle_forcing   = 1;
++		cycle_forcing   = 0;
+ 		coupling_time   = 0.;
+ 	end
+ 	methods
Index: /issm/oecreview/Archive/27230-27343/ISSM-27318-27319.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27318-27319.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27318-27319.diff	(revision 27344)
@@ -0,0 +1,39 @@
+Index: ../trunk-jpl/src/c/modules/FloatingiceMeltingRatex/FloatingiceMeltingRatex.cpp
+===================================================================
+--- ../trunk-jpl/src/c/modules/FloatingiceMeltingRatex/FloatingiceMeltingRatex.cpp	(revision 27318)
++++ ../trunk-jpl/src/c/modules/FloatingiceMeltingRatex/FloatingiceMeltingRatex.cpp	(revision 27319)
+@@ -247,7 +247,7 @@
+ 
+ 	/*Get autoregressive parameters*/
+    femmodel->parameters->FindParam(&datebreaks,&M,&N,BasalforcingsARMAdatebreaksEnum);  _assert_(M==numbasins); _assert_(N==numbreaks);
+-   femmodel->parameters->FindParam(&polyparams,&M,&N,BasalforcingsARMApolyparamsEnum);  _assert_(M==numbasins); _assert_(N==numbreaks*numparams);
++   femmodel->parameters->FindParam(&polyparams,&M,&N,BasalforcingsARMApolyparamsEnum);  _assert_(M==numbasins); _assert_(N==(numbreaks+1)*numparams);
+ 	femmodel->parameters->FindParam(&arlagcoefs,&M,&N,BasalforcingsARMAarlagcoefsEnum);  _assert_(M==numbasins); _assert_(N==arorder);
+    femmodel->parameters->FindParam(&malagcoefs,&M,&N,BasalforcingsARMAmalagcoefsEnum);  _assert_(M==numbasins); _assert_(N==maorder);
+ 
+Index: ../trunk-jpl/src/c/modules/FrontalForcingsx/FrontalForcingsx.cpp
+===================================================================
+--- ../trunk-jpl/src/c/modules/FrontalForcingsx/FrontalForcingsx.cpp	(revision 27318)
++++ ../trunk-jpl/src/c/modules/FrontalForcingsx/FrontalForcingsx.cpp	(revision 27319)
+@@ -62,7 +62,7 @@
+ 	IssmDouble* polyparams    = NULL;
+ 
+    femmodel->parameters->FindParam(&datebreaks,&M,&N,FrontalForcingsARMAdatebreaksEnum); _assert_(M==numbasins); _assert_(N==numbreaks);        
+-   femmodel->parameters->FindParam(&polyparams,&M,&N,FrontalForcingsARMApolyparamsEnum); _assert_(M==numbasins); _assert_(N==numbreaks*numparams);        
++   femmodel->parameters->FindParam(&polyparams,&M,&N,FrontalForcingsARMApolyparamsEnum); _assert_(M==numbasins); _assert_(N==(numbreaks+1)*numparams);        
+    femmodel->parameters->FindParam(&arlagcoefs,&M,&N,FrontalForcingsARMAarlagcoefsEnum); _assert_(M==numbasins); _assert_(N==arorder);
+    femmodel->parameters->FindParam(&malagcoefs,&M,&N,FrontalForcingsARMAmalagcoefsEnum); _assert_(M==numbasins); _assert_(N==maorder);
+    femmodel->parameters->FindParam(&monthlyeff,&M,&N,ThermalForcingMonthlyEffectsEnum);  _assert_(M==numbasins); _assert_(N==12); 
+Index: ../trunk-jpl/src/c/modules/SurfaceMassBalancex/SurfaceMassBalancex.cpp
+===================================================================
+--- ../trunk-jpl/src/c/modules/SurfaceMassBalancex/SurfaceMassBalancex.cpp	(revision 27318)
++++ ../trunk-jpl/src/c/modules/SurfaceMassBalancex/SurfaceMassBalancex.cpp	(revision 27319)
+@@ -183,7 +183,7 @@
+    IssmDouble* refelevation  = NULL;
+ 
+    femmodel->parameters->FindParam(&datebreaks,&M,&N,SmbARMAdatebreaksEnum);             _assert_(M==numbasins); _assert_(N==numbreaks);
+-   femmodel->parameters->FindParam(&polyparams,&M,&N,SmbARMApolyparamsEnum);             _assert_(M==numbasins); _assert_(N==numbreaks*numparams);
++   femmodel->parameters->FindParam(&polyparams,&M,&N,SmbARMApolyparamsEnum);             _assert_(M==numbasins); _assert_(N==(numbreaks+1)*numparams);
+ 	femmodel->parameters->FindParam(&arlagcoefs,&M,&N,SmbARMAarlagcoefsEnum);             _assert_(M==numbasins); _assert_(N==arorder);
+    femmodel->parameters->FindParam(&malagcoefs,&M,&N,SmbARMAmalagcoefsEnum);             _assert_(M==numbasins); _assert_(N==maorder);
+    femmodel->parameters->FindParam(&lapserates,&M,&N,SmbLapseRatesEnum);                 _assert_(M==numbasins); _assert_(N==numelevbins);
Index: /issm/oecreview/Archive/27230-27343/ISSM-27319-27320.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27319-27320.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27319-27320.diff	(revision 27344)
@@ -0,0 +1,39 @@
+Index: ../trunk-jpl/src/c/modules/FloatingiceMeltingRatex/FloatingiceMeltingRatex.cpp
+===================================================================
+--- ../trunk-jpl/src/c/modules/FloatingiceMeltingRatex/FloatingiceMeltingRatex.cpp	(revision 27319)
++++ ../trunk-jpl/src/c/modules/FloatingiceMeltingRatex/FloatingiceMeltingRatex.cpp	(revision 27320)
+@@ -246,7 +246,7 @@
+    IssmDouble* perturbation   = NULL;
+ 
+ 	/*Get autoregressive parameters*/
+-   femmodel->parameters->FindParam(&datebreaks,&M,&N,BasalforcingsARMAdatebreaksEnum);  _assert_(M==numbasins); _assert_(N==numbreaks);
++   femmodel->parameters->FindParam(&datebreaks,&M,&N,BasalforcingsARMAdatebreaksEnum);  _assert_(M==numbasins); _assert_(N==max(numbreaks,1));
+    femmodel->parameters->FindParam(&polyparams,&M,&N,BasalforcingsARMApolyparamsEnum);  _assert_(M==numbasins); _assert_(N==(numbreaks+1)*numparams);
+ 	femmodel->parameters->FindParam(&arlagcoefs,&M,&N,BasalforcingsARMAarlagcoefsEnum);  _assert_(M==numbasins); _assert_(N==arorder);
+    femmodel->parameters->FindParam(&malagcoefs,&M,&N,BasalforcingsARMAmalagcoefsEnum);  _assert_(M==numbasins); _assert_(N==maorder);
+Index: ../trunk-jpl/src/c/modules/FrontalForcingsx/FrontalForcingsx.cpp
+===================================================================
+--- ../trunk-jpl/src/c/modules/FrontalForcingsx/FrontalForcingsx.cpp	(revision 27319)
++++ ../trunk-jpl/src/c/modules/FrontalForcingsx/FrontalForcingsx.cpp	(revision 27320)
+@@ -61,7 +61,7 @@
+    IssmDouble* monthlyeff    = NULL;
+ 	IssmDouble* polyparams    = NULL;
+ 
+-   femmodel->parameters->FindParam(&datebreaks,&M,&N,FrontalForcingsARMAdatebreaksEnum); _assert_(M==numbasins); _assert_(N==numbreaks);        
++   femmodel->parameters->FindParam(&datebreaks,&M,&N,FrontalForcingsARMAdatebreaksEnum); _assert_(M==numbasins); _assert_(N==max(numbreaks,1));        
+    femmodel->parameters->FindParam(&polyparams,&M,&N,FrontalForcingsARMApolyparamsEnum); _assert_(M==numbasins); _assert_(N==(numbreaks+1)*numparams);        
+    femmodel->parameters->FindParam(&arlagcoefs,&M,&N,FrontalForcingsARMAarlagcoefsEnum); _assert_(M==numbasins); _assert_(N==arorder);
+    femmodel->parameters->FindParam(&malagcoefs,&M,&N,FrontalForcingsARMAmalagcoefsEnum); _assert_(M==numbasins); _assert_(N==maorder);
+Index: ../trunk-jpl/src/c/modules/SurfaceMassBalancex/SurfaceMassBalancex.cpp
+===================================================================
+--- ../trunk-jpl/src/c/modules/SurfaceMassBalancex/SurfaceMassBalancex.cpp	(revision 27319)
++++ ../trunk-jpl/src/c/modules/SurfaceMassBalancex/SurfaceMassBalancex.cpp	(revision 27320)
+@@ -182,7 +182,7 @@
+    IssmDouble* elevbins      = NULL;
+    IssmDouble* refelevation  = NULL;
+ 
+-   femmodel->parameters->FindParam(&datebreaks,&M,&N,SmbARMAdatebreaksEnum);             _assert_(M==numbasins); _assert_(N==numbreaks);
++   femmodel->parameters->FindParam(&datebreaks,&M,&N,SmbARMAdatebreaksEnum);             _assert_(M==numbasins); _assert_(N==max(numbreaks,1));
+    femmodel->parameters->FindParam(&polyparams,&M,&N,SmbARMApolyparamsEnum);             _assert_(M==numbasins); _assert_(N==(numbreaks+1)*numparams);
+ 	femmodel->parameters->FindParam(&arlagcoefs,&M,&N,SmbARMAarlagcoefsEnum);             _assert_(M==numbasins); _assert_(N==arorder);
+    femmodel->parameters->FindParam(&malagcoefs,&M,&N,SmbARMAmalagcoefsEnum);             _assert_(M==numbasins); _assert_(N==maorder);
Index: /issm/oecreview/Archive/27230-27343/ISSM-27320-27321.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27320-27321.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27320-27321.diff	(revision 27344)
@@ -0,0 +1,52 @@
+Index: ../trunk-jpl/test/Archives/Archive355.arch
+===================================================================
+Cannot display: file marked as a binary type.
+svn:mime-type = application/octet-stream
+Index: ../trunk-jpl/test/Archives/Archive426.arch
+===================================================================
+Cannot display: file marked as a binary type.
+svn:mime-type = application/octet-stream
+Index: ../trunk-jpl/test/Archives/Archive427.arch
+===================================================================
+Cannot display: file marked as a binary type.
+svn:mime-type = application/octet-stream
+Index: ../trunk-jpl/test/Archives/Archive435.arch
+===================================================================
+Cannot display: file marked as a binary type.
+svn:mime-type = application/octet-stream
+Index: ../trunk-jpl/test/Archives/Archive442.arch
+===================================================================
+Cannot display: file marked as a binary type.
+svn:mime-type = application/octet-stream
+Index: ../trunk-jpl/test/Archives/Archive443.arch
+===================================================================
+Cannot display: file marked as a binary type.
+svn:mime-type = application/octet-stream
+Index: ../trunk-jpl/test/Archives/Archive473.arch
+===================================================================
+Cannot display: file marked as a binary type.
+svn:mime-type = application/octet-stream
+Index: ../trunk-jpl/test/Archives/Archive474.arch
+===================================================================
+Cannot display: file marked as a binary type.
+svn:mime-type = application/octet-stream
+Index: ../trunk-jpl/test/Archives/Archive475.arch
+===================================================================
+Cannot display: file marked as a binary type.
+svn:mime-type = application/octet-stream
+Index: ../trunk-jpl/test/Archives/Archive476.arch
+===================================================================
+Cannot display: file marked as a binary type.
+svn:mime-type = application/octet-stream
+Index: ../trunk-jpl/test/Archives/Archive802.arch
+===================================================================
+Cannot display: file marked as a binary type.
+svn:mime-type = application/octet-stream
+Index: ../trunk-jpl/test/Archives/Archive803.arch
+===================================================================
+Cannot display: file marked as a binary type.
+svn:mime-type = application/octet-stream
+Index: ../trunk-jpl/test/Archives/Archive805.arch
+===================================================================
+Cannot display: file marked as a binary type.
+svn:mime-type = application/octet-stream
Index: /issm/oecreview/Archive/27230-27343/ISSM-27321-27322.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27321-27322.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27321-27322.diff	(revision 27344)
@@ -0,0 +1,4 @@
+Index: ../trunk-jpl/test/Archives/Archive355.arch
+===================================================================
+Cannot display: file marked as a binary type.
+svn:mime-type = application/octet-stream
Index: /issm/oecreview/Archive/27230-27343/ISSM-27322-27323.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27322-27323.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27322-27323.diff	(revision 27344)
@@ -0,0 +1,217 @@
+Index: ../trunk-jpl/src/c/analyses/SmbAnalysis.cpp
+===================================================================
+--- ../trunk-jpl/src/c/analyses/SmbAnalysis.cpp	(revision 27322)
++++ ../trunk-jpl/src/c/analyses/SmbAnalysis.cpp	(revision 27323)
+@@ -217,6 +217,9 @@
+ 			iomodel->FetchDataToInput(inputs,elements,"md.smb.dailyairhumidity",SmbDailyairhumidityEnum);
+ 			iomodel->FetchDataToInput(inputs,elements,"md.smb.dailytemperature",SmbDailytemperatureEnum);
+ 			break;
++		case SMBdebrisMLEnum:
++			iomodel->FetchDataToInput(inputs,elements,"md.initialization.debris",DebrisThicknessEnum);
++			break;
+ 		default:
+ 			_error_("Surface mass balance model "<<EnumToStringx(smb_model)<<" not supported yet");
+ 	}
+Index: ../trunk-jpl/src/m/classes/SMBdebrisML.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/SMBdebrisML.m	(revision 27322)
++++ ../trunk-jpl/src/m/classes/SMBdebrisML.m	(revision 27323)
+@@ -1,9 +1,9 @@
+-%SMBdebriscover Class definition
++%SMBdebrisML Class definition
+ %
+ %   Usage:
+-%      SMBdebriscover=SMBdebriscover();
++%      SMBdebrisML=SMBdebrisML();
+ 
+-classdef SMBdebriscover
++classdef SMBdebrisML
+ 	properties (SetAccess=public)
+ 		steps_per_step=1;
+ 		averaging=0;
+@@ -15,7 +15,7 @@
+ 				case 0
+ 				case 1
+ 					inputstruct=varargin{1};
+-					list1 = properties('SMBdebriscover');
++					list1 = properties('SMBdebrisML');
+ 						list2 = fieldnames(inputstruct);
+ 						for i=1:length(list1)
+ 							fieldname = list1{i};
+Index: ../trunk-jpl/src/m/classes/model.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/model.m	(revision 27322)
++++ ../trunk-jpl/src/m/classes/model.m	(revision 27323)
+@@ -34,6 +34,7 @@
+ 		stressbalance    = 0;
+ 		groundingline    = 0;
+ 		hydrology        = 0;
++		debris		 = 0;
+ 		masstransport    = 0;
+ 		thermal          = 0;
+ 		steadystate      = 0;
+@@ -234,6 +235,7 @@
+ 			disp(sprintf('%19s: %-22s -- %s','stressbalance'   ,['[1x1 ' class(self.stressbalance) ']'],'parameters for stressbalance solution'));
+ 			disp(sprintf('%19s: %-22s -- %s','groundingline'   ,['[1x1 ' class(self.groundingline) ']'],'parameters for groundingline solution'));
+ 			disp(sprintf('%19s: %-22s -- %s','hydrology'       ,['[1x1 ' class(self.hydrology) ']'],'parameters for hydrology solution'));
++			disp(sprintf('%19s: %-22s -- %s','debris' 	   ,['[1x1 ' class(self.debris) ']'],'parameters for debris solution'));
+ 			disp(sprintf('%19s: %-22s -- %s','masstransport'   ,['[1x1 ' class(self.masstransport) ']'],'parameters for masstransport solution'));
+ 			disp(sprintf('%19s: %-22s -- %s','thermal'         ,['[1x1 ' class(self.thermal) ']'],'parameters for thermal solution'));
+ 			disp(sprintf('%19s: %-22s -- %s','steadystate'     ,['[1x1 ' class(self.steadystate) ']'],'parameters for steadystate solution'));
+@@ -281,6 +283,7 @@
+ 			md.balancethickness = balancethickness();
+ 			md.stressbalance    = stressbalance();
+ 			md.hydrology        = hydrologyshreve();
++			md.debris	    = debris();
+ 			md.masstransport    = masstransport();
+ 			md.thermal          = thermal();
+ 			md.steadystate      = steadystate();
+@@ -424,6 +427,9 @@
+ 			if ~isnan(md.initialization.watercolumn),
+ 				md.initialization.watercolumn=project2d(md,md.initialization.watercolumn,1);
+ 			end
++			if ~isnan(md.initialization.debris),
++				md.initialization.debris=project2d(md,md.initialization.debris,1);
++			end
+ 
+ 
+ 			%elementstype
+@@ -1184,6 +1190,7 @@
+ 			md.calving=extrude(md.calving,md);
+ 			md.frontalforcings=extrude(md.frontalforcings,md);
+ 			md.hydrology = extrude(md.hydrology,md);
++			md.debris = extrude(md.debris,md);
+ 			md.solidearth = extrude(md.solidearth,md);
+ 			md.dsl = extrude(md.dsl,md);
+ 
+Index: ../trunk-jpl/src/c/shared/Enum/EnumDefinitions.h
+===================================================================
+--- ../trunk-jpl/src/c/shared/Enum/EnumDefinitions.h	(revision 27322)
++++ ../trunk-jpl/src/c/shared/Enum/EnumDefinitions.h	(revision 27323)
+@@ -167,7 +167,6 @@
+ 	DebrisRemovalStressThresholdEnum,
+ 	DebrisPackingFractionEnum,
+ 	DebugProfilingEnum,
+-	DebrisThicknessEnum,
+ 	DomainDimensionEnum,
+ 	DomainTypeEnum,
+ 	DslModelEnum,
+@@ -719,6 +718,7 @@
+ 	DamageDbarEnum,
+ 	DamageDbarOldEnum,
+ 	DamageFEnum,
++	DebrisThicknessEnum,
+ 	DegreeOfChannelizationEnum,
+ 	DepthBelowSurfaceEnum,
+ 	DeltaIceThicknessEnum,
+Index: ../trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp
+===================================================================
+--- ../trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp	(revision 27322)
++++ ../trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp	(revision 27323)
+@@ -175,7 +175,6 @@
+ 		case DebrisRemovalStressThresholdEnum : return "DebrisRemovalStressThreshold";
+ 		case DebrisPackingFractionEnum : return "DebrisPackingFraction";
+ 		case DebugProfilingEnum : return "DebugProfiling";
+-		case DebrisThicknessEnum : return "DebrisThickness";
+ 		case DomainDimensionEnum : return "DomainDimension";
+ 		case DomainTypeEnum : return "DomainType";
+ 		case DslModelEnum : return "DslModel";
+@@ -725,6 +724,7 @@
+ 		case DamageDbarEnum : return "DamageDbar";
+ 		case DamageDbarOldEnum : return "DamageDbarOld";
+ 		case DamageFEnum : return "DamageF";
++		case DebrisThicknessEnum : return "DebrisThickness";
+ 		case DegreeOfChannelizationEnum : return "DegreeOfChannelization";
+ 		case DepthBelowSurfaceEnum : return "DepthBelowSurface";
+ 		case DeltaIceThicknessEnum : return "DeltaIceThickness";
+Index: ../trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp
+===================================================================
+--- ../trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp	(revision 27322)
++++ ../trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp	(revision 27323)
+@@ -178,7 +178,6 @@
+ 	      else if (strcmp(name,"DebrisRemovalStressThreshold")==0) return DebrisRemovalStressThresholdEnum;
+ 	      else if (strcmp(name,"DebrisPackingFraction")==0) return DebrisPackingFractionEnum;
+ 	      else if (strcmp(name,"DebugProfiling")==0) return DebugProfilingEnum;
+-	      else if (strcmp(name,"DebrisThickness")==0) return DebrisThicknessEnum;
+ 	      else if (strcmp(name,"DomainDimension")==0) return DomainDimensionEnum;
+ 	      else if (strcmp(name,"DomainType")==0) return DomainTypeEnum;
+ 	      else if (strcmp(name,"DslModel")==0) return DslModelEnum;
+@@ -259,11 +258,11 @@
+ 	      else if (strcmp(name,"HydrologydcEplThickComp")==0) return HydrologydcEplThickCompEnum;
+ 	      else if (strcmp(name,"HydrologydcEplflipLock")==0) return HydrologydcEplflipLockEnum;
+ 	      else if (strcmp(name,"HydrologydcIsefficientlayer")==0) return HydrologydcIsefficientlayerEnum;
++	      else if (strcmp(name,"HydrologydcLeakageFactor")==0) return HydrologydcLeakageFactorEnum;
+          else stage=3;
+    }
+    if(stage==3){
+-	      if (strcmp(name,"HydrologydcLeakageFactor")==0) return HydrologydcLeakageFactorEnum;
+-	      else if (strcmp(name,"HydrologydcMaxIter")==0) return HydrologydcMaxIterEnum;
++	      if (strcmp(name,"HydrologydcMaxIter")==0) return HydrologydcMaxIterEnum;
+ 	      else if (strcmp(name,"HydrologydcPenaltyFactor")==0) return HydrologydcPenaltyFactorEnum;
+ 	      else if (strcmp(name,"HydrologydcPenaltyLock")==0) return HydrologydcPenaltyLockEnum;
+ 	      else if (strcmp(name,"HydrologydcRelTol")==0) return HydrologydcRelTolEnum;
+@@ -382,11 +381,11 @@
+ 	      else if (strcmp(name,"OceanGridX")==0) return OceanGridXEnum;
+ 	      else if (strcmp(name,"OceanGridY")==0) return OceanGridYEnum;
+ 	      else if (strcmp(name,"OutputBufferPointer")==0) return OutputBufferPointerEnum;
++	      else if (strcmp(name,"OutputBufferSizePointer")==0) return OutputBufferSizePointerEnum;
+          else stage=4;
+    }
+    if(stage==4){
+-	      if (strcmp(name,"OutputBufferSizePointer")==0) return OutputBufferSizePointerEnum;
+-	      else if (strcmp(name,"OutputFileName")==0) return OutputFileNameEnum;
++	      if (strcmp(name,"OutputFileName")==0) return OutputFileNameEnum;
+ 	      else if (strcmp(name,"OutputFilePointer")==0) return OutputFilePointerEnum;
+ 	      else if (strcmp(name,"Outputdefinition")==0) return OutputdefinitionEnum;
+ 	      else if (strcmp(name,"QmuErrName")==0) return QmuErrNameEnum;
+@@ -505,11 +504,11 @@
+ 	      else if (strcmp(name,"SmbAccualti")==0) return SmbAccualtiEnum;
+ 	      else if (strcmp(name,"SmbAccugrad")==0) return SmbAccugradEnum;
+ 	      else if (strcmp(name,"SmbAccuref")==0) return SmbAccurefEnum;
++	      else if (strcmp(name,"SmbAdThresh")==0) return SmbAdThreshEnum;
+          else stage=5;
+    }
+    if(stage==5){
+-	      if (strcmp(name,"SmbAdThresh")==0) return SmbAdThreshEnum;
+-	      else if (strcmp(name,"SmbARMATimestep")==0) return SmbARMATimestepEnum;
++	      if (strcmp(name,"SmbARMATimestep")==0) return SmbARMATimestepEnum;
+ 	      else if (strcmp(name,"SmbARMAarOrder")==0) return SmbARMAarOrderEnum;
+ 	      else if (strcmp(name,"SmbARMAmaOrder")==0) return SmbARMAmaOrderEnum;
+ 	      else if (strcmp(name,"SmbAveraging")==0) return SmbAveragingEnum;
+@@ -628,11 +627,11 @@
+ 	      else if (strcmp(name,"TransientIsdamageevolution")==0) return TransientIsdamageevolutionEnum;
+ 	      else if (strcmp(name,"TransientIsdebris")==0) return TransientIsdebrisEnum;
+ 	      else if (strcmp(name,"TransientIsesa")==0) return TransientIsesaEnum;
++	      else if (strcmp(name,"TransientIsgia")==0) return TransientIsgiaEnum;
+          else stage=6;
+    }
+    if(stage==6){
+-	      if (strcmp(name,"TransientIsgia")==0) return TransientIsgiaEnum;
+-	      else if (strcmp(name,"TransientIsgroundingline")==0) return TransientIsgroundinglineEnum;
++	      if (strcmp(name,"TransientIsgroundingline")==0) return TransientIsgroundinglineEnum;
+ 	      else if (strcmp(name,"TransientIshydrology")==0) return TransientIshydrologyEnum;
+ 	      else if (strcmp(name,"TransientIsmasstransport")==0) return TransientIsmasstransportEnum;
+ 	      else if (strcmp(name,"TransientIsoceantransport")==0) return TransientIsoceantransportEnum;
+@@ -740,6 +739,7 @@
+ 	      else if (strcmp(name,"DamageDbar")==0) return DamageDbarEnum;
+ 	      else if (strcmp(name,"DamageDbarOld")==0) return DamageDbarOldEnum;
+ 	      else if (strcmp(name,"DamageF")==0) return DamageFEnum;
++	      else if (strcmp(name,"DebrisThickness")==0) return DebrisThicknessEnum;
+ 	      else if (strcmp(name,"DegreeOfChannelization")==0) return DegreeOfChannelizationEnum;
+ 	      else if (strcmp(name,"DepthBelowSurface")==0) return DepthBelowSurfaceEnum;
+ 	      else if (strcmp(name,"DeltaIceThickness")==0) return DeltaIceThicknessEnum;
+Index: ../trunk-jpl/src/m/classes/debris.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/debris.m	(revision 27322)
++++ ../trunk-jpl/src/m/classes/debris.m	(revision 27323)
+@@ -116,8 +116,8 @@
+ 		end % }}}
+ 		function disp(self) % {{{
+ 			disp(sprintf('   Debris solution parameters:'));
+-			fielddisplay(self,'spcthickness','thickness constraints (NaN means no constraint) [m]');
+-			fielddisplay(self,'min_thickness','minimum ice thickness allowed [m]');
++			fielddisplay(self,'spcthickness','debris thickness constraints (NaN means no constraint) [m]');
++			fielddisplay(self,'min_thickness','minimum debris thickness allowed [m]');
+ 			fielddisplay(self,'packingfraction','fraction of debris covered in the ice');
+ 			fielddisplay(self,'stabilization','0: no stabilization, 1: artificial diffusion, 2: streamline upwinding, 3: streamline upwind Petrov-Galerkin (SUPG)');
+ 			fielddisplay(self,'removalmodel','frontal removal of debris. 0: no removal, 1: Slope-triggered debris removal, 2: driving-stress triggered debris removal');
Index: /issm/oecreview/Archive/27230-27343/ISSM-27323-27324.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27323-27324.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27323-27324.diff	(revision 27344)
@@ -0,0 +1,13 @@
+Index: ../trunk-jpl/src/m/classes/debris.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/debris.m	(revision 27323)
++++ ../trunk-jpl/src/m/classes/debris.m	(revision 27324)
+@@ -101,7 +101,7 @@
+ 			%Early return
+ 			if ~ismember('MasstransportAnalysis',analyses) |  (strcmp(solution,'TransientSolution') & md.transient.isdebris==0), return; end
+ 
+-			md = checkfield(md,'fieldname','debris.spcthickness','Inf',1,'timeseries',1);
++			md = checkfield(md,'fieldname','debris.spcthickness');
+ 			md = checkfield(md,'fieldname','debris.stabilization','values',[0 1 2 3]);
+ 			md = checkfield(md,'fieldname','debris.min_thickness','>=',0);
+ 			md = checkfield(md,'fieldname','debris.packingfraction','>=',0);
Index: /issm/oecreview/Archive/27230-27343/ISSM-27324-27325.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27324-27325.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27324-27325.diff	(revision 27344)
@@ -0,0 +1,54 @@
+Index: ../trunk-jpl/externalpackages/petsc/install-3.16-linux.sh
+===================================================================
+--- ../trunk-jpl/externalpackages/petsc/install-3.16-linux.sh	(revision 27324)
++++ ../trunk-jpl/externalpackages/petsc/install-3.16-linux.sh	(revision 27325)
+@@ -1,9 +1,10 @@
+ #!/bin/bash
+ set -eu
+ 
++
+ ## Constants
+ #
+-VER="3.16.0"
++VER="3.16.6"
+ 
+ PETSC_DIR="${ISSM_DIR}/externalpackages/petsc/src" # DO NOT CHANGE THIS
+ PREFIX="${ISSM_DIR}/externalpackages/petsc/install" # Set to location where external package should be installed
+@@ -23,11 +24,23 @@
+ rm -rf petsc-${VER}
+ 
+ # Configure
++#
++# NOTE:
++# - Added -Wno-error=implicit-function-declaration to CFLAGS for Clang >= 12. 
++#	(may need to remove it for earlier versions not using the C99 standard).
++# - Added -fallow-argument-mismatch to FFLAGS in order to clear,
++#
++#		error: The Fortran compiler gfortran will not compile files that call 
++#		the same routine with arguments of different types.
++#
++#	for gfortran 10 or later (may need to remove it for earlier versions).
++#
+ cd ${PETSC_DIR}
+ ./configure \
+ 	--prefix="${PREFIX}" \
+ 	--PETSC_DIR="${PETSC_DIR}" \
+-	-COPTFLAGS="-g -O2" -CXXOPTFLAGS="-g -O2" -FOPTFLAGS="-g -O2" \
++	--CFLAGS="-Wno-error=implicit-function-declaration" \
++	--FFLAGS="-fallow-argument-mismatch" \
+ 	--with-debugging=0 \
+ 	--with-valgrind=0 \
+ 	--with-x=0 \
+Index: ../trunk-jpl/externalpackages/petsc/install-3.16-pleiades.sh
+===================================================================
+--- ../trunk-jpl/externalpackages/petsc/install-3.16-pleiades.sh	(revision 27324)
++++ ../trunk-jpl/externalpackages/petsc/install-3.16-pleiades.sh	(revision 27325)
+@@ -4,7 +4,7 @@
+ 
+ ## Constants
+ #
+-VER="3.16.4"
++VER="3.16.6"
+ 
+ PETSC_DIR="${ISSM_DIR}/externalpackages/petsc/src" # DO NOT CHANGE THIS
+ PREFIX="${ISSM_DIR}/externalpackages/petsc/install" # Set to location where external package should be installed
Index: /issm/oecreview/Archive/27230-27343/ISSM-27325-27326.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27325-27326.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27325-27326.diff	(revision 27344)
@@ -0,0 +1,105 @@
+Index: ../trunk-jpl/src/m/classes/solidearth.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/solidearth.m	(revision 27325)
++++ ../trunk-jpl/src/m/classes/solidearth.m	(revision 27326)
+@@ -6,17 +6,17 @@
+ 
+ classdef solidearth
+ 	properties (SetAccess=public) 
+-		settings               = solidearthsettings(); 
+-		external               = [];
+-		lovenumbers            = lovenumbers();
+-		rotational             = rotational();
+-		planetradius           = planetradius('earth');
+-		requested_outputs      = {};
+-		transitions            = {};
+-		transfercount	 	= [];
+-		partitionice           = [];
+-		partitionhydro         = [];
+-		partitionocean         = [];
++		settings          = solidearthsettings();
++		external          = [];
++		lovenumbers       = lovenumbers();
++		rotational        = rotational();
++		planetradius      = planetradius('earth');
++		requested_outputs = {};
++		transitions       = {};
++		transfercount     = [];
++		partitionice      = [];
++		partitionhydro    = [];
++		partitionocean    = [];
+ 	end
+ 	methods (Static)
+ 		function self = loadobj(self) % {{{
+@@ -84,7 +84,6 @@
+ 
+ 			%planet radius
+ 			self.planetradius= planetradius(planet);
+-
+ 		end % }}}
+ 		function md = checkconsistency(self,md,solution,analyses) % {{{
+ 
+@@ -112,8 +111,6 @@
+ 
+ 			WriteData(fid,prefix,'object',self,'fieldname','planetradius','format','Double');
+ 			WriteData(fid,prefix,'object',self,'fieldname','transitions','format','MatArray');
+-			%WriteData(fid,prefix,'object',self,'fieldname','transfercount','data',self.transfercount,'format','DoubleMat','name', 'md.solidearth.transfercount','mattype',1);
+-			%WriteData(fid,prefix,'data',self.transfercount,'format','DoubleMat','name', 'md.solidearth.transfercount');
+ 			WriteData(fid,prefix,'object',self,'fieldname','transfercount','format','DoubleMat','mattype',1);
+ 
+ 			if ~isempty(self.partitionice),
+Index: ../trunk-jpl/src/m/classes/solidearth.py
+===================================================================
+--- ../trunk-jpl/src/m/classes/solidearth.py	(revision 27325)
++++ ../trunk-jpl/src/m/classes/solidearth.py	(revision 27326)
+@@ -22,16 +22,17 @@
+     """
+ 
+     def __init__(self, *args):  # {{{
+-        self.settings  = solidearthsettings()
+-        self.external  = None
+-        self.lovenumbers = lovenumbers()
+-        self.rotational = rotational()
+-        self.planetradius = planetradius('earth')
++        self.settings          = solidearthsettings()
++        self.external          = None
++        self.lovenumbers       = lovenumbers()
++        self.rotational        = rotational()
++        self.planetradius      = planetradius('earth')
+         self.requested_outputs = []
+-        self.transitions = []
+-        self.partitionice = []
+-        self.partitionhydro = []
+-        self.partitionocean = []
++        self.transfercount     = []
++        self.transitions       = []
++        self.partitionice      = []
++        self.partitionhydro    = []
++        self.partitionocean    = []
+ 
+         nargs = len(args)
+         if nargs == 0:
+@@ -46,6 +47,7 @@
+         s = '   solidearthinputs, forcings and settings:\n'
+         s += '{}\n'.format(fielddisplay(self, 'planetradius', 'planet radius [m]'))
+         s += '{}\n'.format(fielddisplay(self, 'transitions', 'indices into parts of the mesh that will be icecaps'))
++        s += '{}\n'.format(fielddisplay(self, 'transfercount', 'number of icecaps vertices are part of'))
+         s += '{}\n'.format(fielddisplay(self, 'requested_outputs', 'additional outputs requested'))
+         s += '{}\n'.format(fielddisplay(self, 'partitionice', 'ice partition vector for barystatic contribution'))
+         s += '{}\n'.format(fielddisplay(self, 'partitionhydro', 'hydro partition vector for barystatic contribution'))
+@@ -68,6 +70,7 @@
+ 
+         # Transitions should be a list
+         self.transitions = []
++        self.transfercount = [0]
+ 
+         # No partitions requested for barystatic contribution
+         self.partitionice = []
+@@ -104,6 +107,7 @@
+     def marshall(self, prefix, md, fid):  # {{{
+         WriteData(fid, prefix, 'object', self, 'fieldname', 'planetradius', 'format', 'Double')
+         WriteData(fid, prefix, 'object', self, 'fieldname', 'transitions', 'format', 'MatArray')
++        WriteData(fid, prefix, 'object', self, 'fieldname', 'transfercount', 'format', 'DoubleMat', 'mattype', 1)
+ 
+         if len(self.partitionice):
+             npartice = np.max(self.partitionice) + 2
Index: /issm/oecreview/Archive/27230-27343/ISSM-27326-27327.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27326-27327.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27326-27327.diff	(revision 27344)
@@ -0,0 +1,464 @@
+Index: ../trunk-jpl/src/m/classes/fourierlove.py
+===================================================================
+--- ../trunk-jpl/src/m/classes/fourierlove.py	(revision 27326)
++++ ../trunk-jpl/src/m/classes/fourierlove.py	(revision 27327)
+@@ -1,7 +1,7 @@
+ import numpy as np
+ 
++from checkfield import checkfield
+ from fielddisplay import fielddisplay
+-from checkfield import checkfield
+ from WriteData import WriteData
+ 
+ 
+@@ -42,8 +42,7 @@
+         # TODO:
+         # - Correct display to match MATLAB
+         #
+-        s = '   Fourier Love class:\n'
+-        s += '{}\n'.format(fielddisplay(self, 'nfreq', 'number of frequencies sampled (default: 1, elastic) [Hz]'))
++        s = '{}\n'.format(fielddisplay(self, 'nfreq', 'number of frequencies sampled (default: 1, elastic) [Hz]'))
+         s += '{}\n'.format(fielddisplay(self, 'frequencies', 'frequencies sampled (convention defaults to 0 for the elastic case) [Hz]'))
+         s += '{}\n'.format(fielddisplay(self, 'sh_nmax', 'maximum spherical harmonic degree (default: 256, .35 deg, or 40 km at equator)'))
+         s += '{}\n'.format(fielddisplay(self, 'sh_nmin', 'minimum spherical harmonic degree (default: 1)'))
+@@ -63,17 +62,17 @@
+         s += '{}\n'.format(fielddisplay(self, 'love_kernels', 'compute love numbers at depth? (default: 0)'))
+         s += '{}\n'.format(fielddisplay(self, 'forcing_type', 'integer indicating the nature and depth of the forcing for the Love number calculation (default: 11):'))
+         s += '{}\n'.format('                                                     1:  Inner core boundary -- Volumic Potential')
+-        s += '{}\n'.format('                                                     2:  Inner core boundary --  Pressure')
+-        s += '{}\n'.format('                                                     3:  Inner core boundary --  Loading')
+-        s += '{}\n'.format('                                                     4:  Inner core boundary --  Tangential traction')
+-        s += '{}\n'.format('                                                     5:  Core mantle boundary --  Volumic Potential')
+-        s += '{}\n'.format('                                                     6:  Core mantle boundary --  Pressure')
+-        s += '{}\n'.format('                                                     7:  Core mantle boundary --  Loading')
+-        s += '{}\n'.format('                                                     8:  Core mantle boundary --  Tangential traction')
+-        s += '{}\n'.format('                                                     9:  Surface--  Volumic Potential')
+-        s += '{}\n'.format('                                                     10: Surface--  Pressure')
+-        s += '{}\n'.format('                                                     11: Surface--  Loading')
+-        s += '{}\n'.format('                                                     12: Surface--  Tangential traction ')
++        s += '{}\n'.format('                                                     2:  Inner core boundary -- Pressure')
++        s += '{}\n'.format('                                                     3:  Inner core boundary -- Loading')
++        s += '{}\n'.format('                                                     4:  Inner core boundary -- Tangential traction')
++        s += '{}\n'.format('                                                     5:  Core mantle boundary -- Volumic Potential')
++        s += '{}\n'.format('                                                     6:  Core mantle boundary -- Pressure')
++        s += '{}\n'.format('                                                     7:  Core mantle boundary -- Loading')
++        s += '{}\n'.format('                                                     8:  Core mantle boundary -- Tangential traction')
++        s += '{}\n'.format('                                                     9:  Surface -- Volumic Potential')
++        s += '{}\n'.format('                                                     10: Surface -- Pressure')
++        s += '{}\n'.format('                                                     11: Surface -- Loading')
++        s += '{}\n'.format('                                                     12: Surface -- Tangential traction ')
+         s += '{}\n'.format(fielddisplay(self, 'inner_core_boundary', 'interface index in materials.radius locating forcing. Only used for forcing_type 1--4 (default: 1)'))
+         s += '{}\n'.format(fielddisplay(self, 'core_mantle_boundary', 'interface index in materials.radius locating forcing. Only used for forcing_type 5--8 (default: 2)'))
+ 
+@@ -86,7 +85,7 @@
+         self.frequencies = [0] # Hz
+         self.sh_nmax = 256 # .35 degree, 40 km at the equator
+         self.sh_nmin = 1
+-        # Work on matlab script for computing g0 for given Earth's structure
++        # Work on Python script for computing g0 for given Earth's structure
+         self.g0 = 9.81 # m/s^2
+         self.r0 = 6371 * 1e3 # m
+         self.mu0 = 1e11 # Pa
+@@ -128,10 +127,11 @@
+         md = checkfield(md, 'fieldname', 'love.complex_computation', 'NaN', 1, 'Inf', 1, 'numel', 1, 'values', [0, 1])
+ 
+         md = checkfield(md, 'fieldname', 'love.istemporal', 'values', [0, 1])
++
+         if md.love.istemporal:
+             md = checkfield(md, 'fieldname', 'love.n_temporal_iterations', 'NaN', 1, 'Inf', 1, 'numel', 1, '>', 0)
+             md = checkfield(md, 'fieldname', 'love.time', 'NaN', 1, 'Inf', 1, 'numel', md.love.nfreq / 2 / md.love.n_temporal_iterations)
+-        if md.love.sh_nmin <= 1 and (md.love.forcing_type == 9 or md.love.forcing_type == 5 or md.love.forcing_type == 1):
++        if md.love.sh_nmin <= 1 and (md.love.forcing_type == 1 or md.love.forcing_type == 5 or md.love.forcing_type == 9):
+             raise RuntimeError('Degree 1 not supported for forcing type {}. Use sh_min >= 2 for this kind of calculation.'.format(md.love.forcing_type))
+ 
+         if md.love.chandler_wobble  == 1:
+Index: ../trunk-jpl/src/m/classes/sealevelmodel.py
+===================================================================
+--- ../trunk-jpl/src/m/classes/sealevelmodel.py	(revision 27326)
++++ ../trunk-jpl/src/m/classes/sealevelmodel.py	(revision 27327)
+@@ -87,17 +87,16 @@
+     @staticmethod
+     def checkconsistency(slm, solutiontype):  # {{{
+         # Is the coupler turned on?
+-        for i in range(len(slm.icecaps)):
+-            if not slm.icecaps[i].transient.iscoupler:
+-                print('Warning: sealevelmodel.py::checkconsistency: icecap model {} should have the transient coupler option turned on!'.format(slm.icecaps[i].miscellaneous.name))
++        #for i in range(len(slm.icecaps)):
++        #    if not slm.icecaps[i].transient.iscoupler:
++        #        print('Warning: sealevelmodel.py::checkconsistency: icecap model {} should have the transient coupler option turned on!'.format(slm.icecaps[i].miscellaneous.name))
+ 
+-        if not slm.earth.transient.iscoupler:
+-            print('Warning: sealevelmodel.py::checkconsistency: earth model should have the transient coupler option turned on!')
++        #if not slm.earth.transient.iscoupler:
++        #    print('Warning: sealevelmodel.py::checkconsistency: earth model should have the transient coupler option turned on!')
+ 
+         # Check that the transition vectors have the right size
+-        for i in range(len(slm.icecaps)):
+-            if slm.icecaps[i].mesh.numberofvertices != len(slm.earth.slr.transitions[i]):
+-                raise Exception('sealevelmodel.py::checkconsistency: issue with size of transition vector for ice cap: {} name: {}'.format(i, slm.icecaps[i].miscellaneous.name))
++        if slm.earth.mesh.numberofvertices != len(slm.earth.solidearth.transfercount):
++            raise Exception('sealevelmodel.py::checkconsistency: earth.solidearth.transfercount should be of size earth.mesh.numberofvertices')
+ 
+         # Check that run frequency is the same everywhere
+         for i in range(len(slm.icecaps)):
+@@ -107,13 +106,13 @@
+         # Make sure steric_rate is the same everywhere
+         for i in range(len(slm.icecaps)):
+             md = slm.icecaps[i]
+-            if np.nonzero(md.dsl.steric_rate - slm.earth.dsl.steric_rate[slm.earth.dsl.transitions[i]]) != []:
++            if np.nonzero(md.dsl.sea_surface_height_above_geoid - slm.earth.dsl.sea_surface_height_above_geoid[slm.transitions[i]]) != []:
+                 raise Exception('sealevelmodel.py::checkconsistency: steric rate on ice cap {} is not the same as for the earth'.format(md.miscellaneous.name))
+ 
+         # Make sure grd is the same everywhere
+         for i in range(len(slm.icecaps)):
+             md = slm.icecaps[i]
+-            if md.solidearthsettings.isgrd != slm.earth.solidearthsettings.isgrd:
++            if md.solidearth.settings.isgrd != slm.earth.solidearth.settings.isgrd:
+                 raise RuntimeError('sealevelmodel.py::checkconsistency: isgrd on ice cap {} is not the same as for the earth\n'.format(md.miscellaneous.name))
+ 
+         # Make sure that there is no solid earth external forcing on the basins
+@@ -220,6 +219,7 @@
+         # Initialize, to avoid issues of having more transitions than meshes
+         self.transitions = []
+         self.eltransitions = []
++        self.earth.solidearth.transfercount = np.zeros(self.earth.mesh.numberofvertices)
+ 
+         # For elements
+         xe = np.mean(self.earth.mesh.x[self.earth.mesh.elements - 1], axis=1)
+@@ -239,6 +239,11 @@
+ 
+             self.transitions.append(meshintersect3d(self.earth.mesh.x, self.earth.mesh.y, self.earth.mesh.z, mdi.mesh.x, mdi.mesh.y, mdi.mesh.z, 'force', force))
+             self.eltransitions.append(meshintersect3d(xe, ye, ze, xei, yei, zei, 'force', force))
++
++            self.earth.solidearth.transfercount[self.transitions[i]] = self.earth.solidearth/transfercount[self.transitions[i]] + 1
++
++        for i in range(len(self.icecaps)):
++            self.icecaps[i].solidearth.transfercount = self.earth.solidearth.transfercount[self.transitions[i]]
+     # }}}
+ 
+     def checkintersections(self):  # {{{
+@@ -245,7 +250,7 @@
+         flags = np.zeros(self.earth.mesh.numberofvertices, 1)
+         for i in range(len(self.basins)):
+             flags[self.transitions[i]] = i
+-        plotmodel(self.earth, 'data', flags, 'coastline', 'on')
++        plotmodel(self.earth, 'data', flags, 'coastlines', 'on')
+     # }}}
+ 
+     def checkbasinconsistency(self):  # {{{
+Index: ../trunk-jpl/src/m/solve/solveslm.py
+===================================================================
+--- ../trunk-jpl/src/m/solve/solveslm.py	(revision 27326)
++++ ../trunk-jpl/src/m/solve/solveslm.py	(revision 27327)
+@@ -76,7 +76,7 @@
+         miscellaneousnames.append(slm.earth.miscellaneous.name)
+         nps.append(slm.earth.cluster.np)
+ 
+-    BuildQueueScriptMultipleModels(cluster, slm.private.runtimename, slm.miscellaneous.name, slm.private.solution, valgrind, privateruntimenames, miscellaneousnames, nps)
++    BuildQueueScriptMultipleModels(cluster, slm.private.runtimename, slm.miscellaneous.name, slm.private.solution, privateruntimenames, miscellaneousnames, nps)
+ 
+     # Upload all required files, given that each individual solution for icecaps and earth model already did
+     filelist = [slm.miscellaneous.name + '.queue']
+Index: ../trunk-jpl/test/NightlyRun/test2084.py
+===================================================================
+--- ../trunk-jpl/test/NightlyRun/test2084.py	(revision 27326)
++++ ../trunk-jpl/test/NightlyRun/test2084.py	(revision 27327)
+@@ -55,7 +55,6 @@
+ md.love.underflow_tol = 1e-20
+ md.love.pw_threshold = 1e-3
+ md.love.Gravitational_Constant = 6.6732e-11
+-md.love.integration_steps_per_layer = 100
+ md.love.allow_layer_deletion = 1
+ md.love.forcing_type = 11
+ md.love.chandler_wobble = 0
+Index: ../trunk-jpl/src/m/classes/love.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/love.m	(revision 27326)
++++ ../trunk-jpl/src/m/classes/love.m	(revision 27327)
+@@ -32,7 +32,7 @@
+ 		debug=0;
+ 		hypergeom_table1=0;
+ 		hypergeom_table2=0;
+-		hypergeom_nalpha=0;
++		hypergeom_table1=0;
+ 		hypergeom_nz=0;
+ 		hypergeom_z=0;
+ 	end
+@@ -67,8 +67,8 @@
+ 			self.allow_layer_deletion=1;
+ 			self.underflow_tol=1e-16; %threshold of deep to surface love number ratio to trigger the deletion of layer 
+ 			self.pw_threshold=1e-3; %if relative variation across frequencies is smaller than this ratio, the post-widder transform for time-dependent love numbers is bypassed 
+-			self.min_integration_steps	= 50;
+-			self.max_integration_dr	= 10e3;
++			self.min_integration_steps=50;
++			self.max_integration_dr=1e4;
+ 			self.integration_scheme=1;
+ 			self.istemporal=0;
+ 			self.n_temporal_iterations=8;
+@@ -95,7 +95,7 @@
+ 			fielddisplay(self,'r0','adimensioning constant for radius (default: 6371*10^3) [m]');
+ 			fielddisplay(self,'mu0','adimensioning constant for stress (default: 10^11) [Pa]');
+ 			fielddisplay(self,'Gravitational_Constant','Newtonian constant of gravitation (default: 6.67259e-11 [m^3 kg^-1 s^-2])');
+-			fielddisplay(self,'chandler_wobble','includes the inertial terms for the chandler wobble in the rotational feedback love numbers, only for forcing_type=11 (default: 0) (/!\ 1 is untested yet)');
++			fielddisplay(self,'chandler_wobble','includes the inertial terms for the chandler wobble in the rotational feedback love numbers, only for forcing_type=11 (default: 0) (/!\ 1 has not been validated yet)');
+ 			fielddisplay(self,'allow_layer_deletion','allow for migration of the integration boundary with increasing spherical harmonics degree (default: 1)');			
+ 			fielddisplay(self,'underflow_tol','threshold of deep to surface love number ratio to trigger the deletion of layers (default: 1e-16)');
+ 			fielddisplay(self,'pw_threshold','if relative variation across frequencies is smaller than this ratio, the post-widder transform for time-dependent love numbers is bypassed (default (1e-3)');
+@@ -110,7 +110,7 @@
+ 			fielddisplay(self,'inner_core_boundary','interface index in materials.radius locating forcing. Only used for forcing_type 1--4 (default: 1)');
+ 			fielddisplay(self,'core_mantle_boundary','interface index in materials.radius locating forcing. Only used for forcing_type 5--8 (default: 2)'); 
+ 			fielddisplay(self,'complex_computation','return love numbers as 0: real (useful for elastic or temporal forms), 1: complex numbers (useful for Fourier spectral form) (default: 0)'); 
+-			fielddisplay(self,'quad_precision','toogle computation love numbers and post-widder transform with 32 digit precision, useful for temporal form (default: 1)'); 
++			fielddisplay(self,'quad_precision','toggle computation love numbers and post-widder transform with 32 digit precision, useful for temporal form (default: 1)'); 
+ 			fielddisplay(self,'debug','outputs yi system matrix prior to solving (default: 0)'); 
+ 			fielddisplay(self,'hypergeom_table1','table 1 for hypergeometric function, only for EBM rheology (default: [1])'); 
+ 			fielddisplay(self,'hypergeom_table2','table 2 for hypergeometric function, only for EBM rheology (default: [1])'); 
+Index: ../trunk-jpl/src/m/classes/love.py
+===================================================================
+--- ../trunk-jpl/src/m/classes/love.py	(nonexistent)
++++ ../trunk-jpl/src/m/classes/love.py	(revision 27327)
+@@ -0,0 +1,231 @@
++import numpy as np
++
++from checkfield import checkfield
++from fielddisplay import fielddisplay
++from WriteData import WriteData
++
++class love(object):
++    """LOVE - class definition
++
++    Usage:
++        md.love = love()
++    """
++
++    def __init__(self): #{{{
++        self.nfreq = 0
++        self.frequencies = 0
++        self.sh_nmax = 0
++        self.sh_nmin = 0
++        self.g0 = 0
++        self.r0 = 0
++        self.mu0 = 0
++        self.Gravitational_Constant = 0
++        self.chandler_wobble = 0
++        self.allow_layer_deletion = 0
++        self.underflow_tol = 0
++        self.pw_threshold = 0
++        self.min_integration_steps = 0
++        self.max_integration_dr = 0
++        self.integration_scheme = 0
++        self.istemporal = 0
++        self.n_temporal_iterations = 0
++        self.time = 0
++        self.love_kernels = 0
++        self.forcing_type = 0
++        self.inner_core_boundary = 0
++        self.core_mantle_boundary = 0
++        self.complex_computation = 0
++        self.quad_precision = 0
++        self.hypergeom_table1 = 0
++        self.hypergeom_table2 = 0
++        self.hypergeom_table1 = 0
++        self.hypergeom_nz = 0
++        self.hypergeom_z = 0
++
++        self.setdefaultparameters()
++    #}}}
++
++    def __repr__(self): #{{{
++        s = '{}\n'.format(fielddisplay(self, 'nfreq', 'number of frequencies sampled (default: 1, elastic) [Hz]'))
++        s += '{}\n'.format(fielddisplay(self, 'frequencies', 'frequencies sampled (convention defaults to 0 for the elastic case) [Hz]'))
++        s += '{}\n'.format(fielddisplay(self, 'sh_nmax', 'maximum spherical harmonic degree (default: 256, .35 deg, or 40 km at equator)'))
++        s += '{}\n'.format(fielddisplay(self, 'sh_nmin', 'minimum spherical harmonic degree (default: 1)'))
++        s += '{}\n'.format(fielddisplay(self, 'g0', 'adimensioning constant for gravity (default: 10) [m/s^2]'))
++        s += '{}\n'.format(fielddisplay(self, 'r0', 'adimensioning constant for radius (default: 6371*10^3) [m]'))
++        s += '{}\n'.format(fielddisplay(self, 'mu0', 'adimensioning constant for stress (default: 10^11) [Pa]'))
++        s += '{}\n'.format(fielddisplay(self, 'Gravitational_Constant', 'Newtonian constant of gravitation (default: 6.67259e-11 [m^3 kg^-1 s^-2])'))
++        s += '{}\n'.format(fielddisplay(self, 'chandler_wobble', 'includes the inertial terms for the chandler wobble in the rotational feedback love numbers, only for forcing_type=11 (default: 0) (/!\\ 1 has not been validated yet)'))
++        s += '{}\n'.format(fielddisplay(self, 'allow_layer_deletion', 'allow for migration of the integration boundary with increasing spherical harmonics degree (default: 1)'))
++        s += '{}\n'.format(fielddisplay(self, 'underflow_tol', 'threshold of deep to surface love number ratio to trigger the deletion of layers (default: 1e-16)'))
++        s += '{}\n'.format(fielddisplay(self, 'pw_threshold', 'if relative variation across frequencies is smaller than this ratio, the post-widder transform for time-dependent love numbers is bypassed (default (1e-3)'))
++        s += '{}\n'.format(fielddisplay(self, 'min_integration_steps', 'minimum number of radial steps to propagate the yi system from the bottom to the top of each layer (default: 50)'))
++        s += '{}\n'.format(fielddisplay(self, 'max_integration_dr', 'maximum length of radial steps to propagate the yi system from the bottom to the top of each layer (default: 10e3) [m]'))
++        s += '{}\n'.format(fielddisplay(self, 'istemporal', ['1 for time-dependent love numbers, 0 for frequency-dependent or elastic love numbers (default: 0)', 'If 1: use fourierlove function build_frequencies_from_time to meet consistency']))
++        s += '{}\n'.format(fielddisplay(self, 'n_temporal_iterations', 'max number of iterations in the inverse Laplace transform. Also the number of spectral samples per time step requested (default: 8)'))
++        s += '{}\n'.format(fielddisplay(self, 'time', 'time vector for deformation if istemporal (default: 0) [s]'))
++        s += '{}\n'.format(fielddisplay(self, 'love_kernels', 'compute love numbers at depth? (default: 0)'))
++        s += '{}\n'.format(fielddisplay(self, 'forcing_type', 'integer indicating the nature and depth of the forcing for the Love number calculation (default: 11):'))
++        s += '{}\n'.format('                                                     1:  Inner core boundary -- Volumic Potential')
++        s += '{}\n'.format('                                                     2:  Inner core boundary -- Pressure')
++        s += '{}\n'.format('                                                     3:  Inner core boundary -- Loading')
++        s += '{}\n'.format('                                                     4:  Inner core boundary -- Tangential traction')
++        s += '{}\n'.format('                                                     5:  Core mantle boundary -- Volumic Potential')
++        s += '{}\n'.format('                                                     6:  Core mantle boundary -- Pressure')
++        s += '{}\n'.format('                                                     7:  Core mantle boundary -- Loading')
++        s += '{}\n'.format('                                                     8:  Core mantle boundary -- Tangential traction')
++        s += '{}\n'.format('                                                     9:  Surface -- Volumic Potential')
++        s += '{}\n'.format('                                                     10: Surface -- Pressure')
++        s += '{}\n'.format('                                                     11: Surface -- Loading')
++        s += '{}\n'.format('                                                     12: Surface -- Tangential traction ')
++        s += '{}\n'.format(fielddisplay(self, 'inner_core_boundary', 'interface index in materials.radius locating forcing. Only used for forcing_type 1--4 (default: 1)'))
++        s += '{}\n'.format(fielddisplay(self, 'core_mantle_boundary', 'interface index in materials.radius locating forcing. Only used for forcing_type 5--8 (default: 2)'))
++        s += '{}\n'.format(fielddisplay(self, 'complex_computation', 'return love numbers as 0: real (useful for elastic or temporal forms), 1: complex numbers (useful for Fourier spectral form) (default: 0)'))
++        s += '{}\n'.format(fielddisplay(self, 'quad_precision', 'toggle computation love numbers and post-widder transform with 32 digit precision, useful for temporal form (default: 1)'))
++        s += '{}\n'.format(fielddisplay(self, 'debug', 'outputs yi system matrix prior to solving (default: 0)'))
++        s += '{}\n'.format(fielddisplay(self, 'hypergeom_table1', 'table 1 for hypergeometric function, only for EBM rheology (default: [1])'))
++        s += '{}\n'.format(fielddisplay(self, 'hypergeom_table2', 'table 2 for hypergeometric function, only for EBM rheology (default: [1])'))
++        s += '{}\n'.format(fielddisplay(self, 'hypergeom_nalpha', 'length of hypergeometric table, only for EBM rheology (default: 1)'))
++        s += '{}\n'.format(fielddisplay(self, 'hypergeom_nz', 'width of hypergeometric table, only for EBM rheology (default: 1)'))
++        s += '{}\n'.format(fielddisplay(self, 'hypergeom_z', 'abscissa for hypergeometric table, only for EBM rheology (default: [0])'))
++
++        return s
++    #}}}
++
++    def setdefaultparameters(self): #{{{
++        # We setup an elastic love number computation by default
++        self.nfreq = 1
++        self.frequencies = [0] # Hz
++        self.sh_nmax = 256 # .35 degree, 40 km at the equator
++        self.sh_nmin = 1
++        # Work on Python script for computing g0 for given Earth's structure
++        self.g0 = 9.81 # m/s^2
++        self.r0 = 6371 * 1e3 # m
++        self.mu0 = 1e11 # Pa
++        self.Gravitational_Constant = 6.67259e-11 # m^3 kg^-1 s^-2
++        self.chandler_wobble = 0
++        self.allow_layer_deletion = 1
++        self.underflow_tol = 1e-16 # Threshold of deep to surface love number ratio to trigger the deletion of layer
++        self.pw_threshold = 1e-3 # If relative variation across frequencies is smaller than this ratio, the post-widder transform for time-dependent love numbers is bypassed 
++        self.min_integration_steps=50
++        self.max_integration_dr=1e4
++        self.integration_scheme=1
++        self.istemporal = 0
++        self.n_temporal_iterations = 8
++        self.time = [0] # s
++        self.love_kernels = 0
++        self.forcing_type = 11 # Surface loading
++        self.inner_core_boundary = 1
++        self.core_mantle_boundary = 2
++        self.complex_computation = 0
++        self.quad_precision = 0
++        self.hypergeom_table1 = 1
++        self.hypergeom_table2 = 1
++        self.hypergeom_nalpha = 1
++        self.hypergeom_nz = 1
++        self.hypergeom_z = 0
++    #}}}
++
++    def checkconsistency(self, md, solution, analyses): #{{{
++        if 'LoveAnalysis' not in analyses:
++            return md
++
++        md = checkfield(md, 'fieldname', 'love.nfreq', 'NaN', 1, 'Inf', 1, 'numel', 1, '>', 0)
++        md = checkfield(md, 'fieldname', 'love.frequencies', 'NaN', 1, 'Inf', 1, 'numel', md.love.nfreq)
++        md = checkfield(md, 'fieldname', 'love.sh_nmax', 'NaN', 1, 'Inf', 1, 'numel', 1, '>', 0)
++        md = checkfield(md, 'fieldname', 'love.sh_nmin', 'NaN', 1, 'Inf', 1, 'numel', 1, '>', 0)
++        md = checkfield(md, 'fieldname', 'love.g0', 'NaN', 1, 'Inf', 1, 'numel', 1, '>', 0)
++        md = checkfield(md, 'fieldname', 'love.r0', 'NaN', 1, 'Inf', 1, 'numel', 1, '>', 0)
++        md = checkfield(md, 'fieldname', 'love.mu0', 'NaN', 1, 'Inf', 1, 'numel', 1, '>', 0)
++        md = checkfield(md, 'fieldname', 'love.Gravitational_Constant', 'NaN', 1, 'Inf', 1, 'numel', 1, '>', 0)
++        md = checkfield(md, 'fieldname', 'love.chandler_wobble', 'values', [0, 1])
++        md = checkfield(md, 'fieldname', 'love.allow_layer_deletion', 'values', [0, 1])
++        md = checkfield(md, 'fieldname', 'love.underflow_tol', 'NaN', 1, 'Inf', 1, 'numel', 1, '>', 0)
++        md = checkfield(md, 'fieldname', 'love.pw_threshold', 'NaN', 1, 'Inf', 1, 'numel', 1, '>', 0)
++        md = checkfield(md, 'fieldname', 'love.min_integration_steps', 'NaN', 1, 'Inf', 1, 'numel', 1, '>', 0)
++        md = checkfield(md, 'fieldname', 'love.max_integration_dr', 'NaN', 1, 'Inf', 1, 'numel', 1, '>', 0)
++        md = checkfield(md, 'fieldname', 'love.integration_scheme', 'NaN', 1, 'Inf', 1, 'numel', 1, '>=', 0, '<=', 2)
++        md = checkfield(md, 'fieldname', 'love.love_kernels', 'values', [0, 1])
++        md = checkfield(md, 'fieldname', 'love.forcing_type', 'NaN', 1, 'Inf', 1, 'numel', 1, '>', 0, '<=', 12)
++        md = checkfield(md, 'fieldname', 'love.complex_computation', 'NaN', 1, 'Inf', 1, 'numel', 1, 'values', [0, 1])
++
++        md = checkfield(md, 'fieldname', 'love.istemporal', 'values', [0, 1])
++
++        md = checkfield(md, 'fieldname', 'love.hypergeom_nalpha', 'NaN', 1, 'Inf', 1, 'numel', 1, '>', 0)
++        md = checkfield(md, 'fieldname', 'love.hypergeom_nz', 'NaN', 1, 'Inf', 1, 'numel', 1, '>', 0)
++        md = checkfield(md, 'fieldname', 'love.hypergeom_z', 'NaN', 1, 'Inf', 1, 'numel', md.love.hypergeom_nz)
++        md = checkfield(md, 'fieldname', 'love.hypergeom_table1', 'NaN', 1, 'Inf', 1, 'numel', md.love.hypergeom_nz * md.love.hypergeom_nalpha)
++        md = checkfield(md, 'fieldname', 'love.hypergeom_table2', 'NaN', 1, 'Inf', 1, 'numel', md.love.hypergeom_nz * md.love.hypergeom_nalpha)
++
++        if md.love.istemporal:
++            md = checkfield(md, 'fieldname', 'love.n_temporal_iterations', 'NaN', 1, 'Inf', 1, 'numel', 1, '>', 0)
++            md = checkfield(md, 'fieldname', 'love.time', 'NaN', 1, 'Inf', 1, 'numel', md.love.nfreq / 2 / md.love.n_temporal_iterations)
++        if md.love.sh_nmin <= 1 and (md.love.forcing_type == 1 or md.love.forcing_type == 5 or md.love.forcing_type == 9):
++            raise RuntimeError('Degree 1 not supported for forcing type {}. Use sh_min >= 2 for this kind of calculation.'.format(md.love.forcing_type))
++
++        if md.love.chandler_wobble  == 1:
++            print('Warning: Chandler wobble in Love number calculator has not been validated yet')
++
++        # Need 'litho' material
++        if md.materials.__class__.__name__ != 'materials' or 'litho' not in md.materials.nature:
++            raise RuntimeError('Need a \'litho\' material to run a Fourier Love number analysis')
++
++        mat = np.where(np.array(md.materials.nature) == 'litho')[0]
++        if md.love.forcing_type <= 4:
++            md = checkfield(md, 'fieldname', 'love.inner_core_boundary', 'NaN', 1, 'Inf', 1, 'numel', 1, '>', 0, '<=', md.materials[mat].numlayers)
++        elif md.love.forcing_type <= 8:
++            md = checkfield(md, 'fieldname', 'love.core_mantle_boundary', 'NaN', 1, 'Inf', 1, 'numel', 1, '>', 0, '<=', md.materials[mat].numlayers)
++
++        return md
++    #}}}
++
++    def marshall(self, prefix, md, fid): #{{{
++        WriteData(fid, prefix, 'object', self, 'fieldname', 'nfreq', 'format', 'Integer')
++        WriteData(fid, prefix, 'object', self, 'fieldname', 'frequencies', 'format', 'DoubleMat', 'mattype',3)
++        WriteData(fid, prefix, 'object', self, 'fieldname', 'sh_nmax', 'format', 'Integer')
++        WriteData(fid, prefix, 'object', self, 'fieldname', 'sh_nmin', 'format', 'Integer')
++        WriteData(fid, prefix, 'object', self, 'fieldname', 'g0', 'format', 'Double')
++        WriteData(fid, prefix, 'object', self, 'fieldname', 'r0', 'format', 'Double')
++        WriteData(fid, prefix, 'object', self, 'fieldname', 'mu0', 'format', 'Double')
++        WriteData(fid, prefix, 'object', self, 'fieldname', 'Gravitational_Constant', 'format', 'max_integration_dr')
++        WriteData(fid, prefix, 'object', self, 'fieldname', 'chandler_wobble', 'format', 'Boolean')
++        WriteData(fid, prefix, 'object', self, 'fieldname', 'allow_layer_deletion', 'format', 'Boolean')
++        WriteData(fid, prefix, 'object', self, 'fieldname', 'underflow_tol', 'format', 'Double')
++        WriteData(fid, prefix, 'object', self, 'fieldname', 'pw_threshold', 'format', 'Double')
++        WriteData(fid, prefix, 'object', self, 'fieldname', 'min_integration_steps', 'format', 'Integer')
++        WriteData(fid, prefix, 'object', self, 'fieldname', 'max_integration_dr', 'format', 'Double')
++        WriteData(fid, prefix, 'object', self, 'fieldname', 'integration_scheme', 'format', 'Integer')
++        WriteData(fid, prefix, 'object', self, 'fieldname', 'istemporal', 'format', 'Boolean')
++        WriteData(fid, prefix, 'object', self, 'fieldname', 'n_temporal_iterations', 'format', 'Integer')
++        WriteData(fid, prefix, 'object', self, 'fieldname', 'complex_computation', 'format', 'Boolean')
++        WriteData(fid, prefix, 'object', self, 'fieldname', 'quad_precision', 'format', 'Boolean')
++        # Note: no need to marshall the time vector, we have frequencies
++        WriteData(fid, prefix, 'object', self, 'fieldname', 'love_kernels', 'format', 'Boolean')
++        WriteData(fid, prefix, 'object', self, 'fieldname', 'forcing_type', 'format', 'Integer')
++        WriteData(fid, prefix, 'object', self, 'fieldname', 'inner_core_boundary', 'format', 'Integer')
++        WriteData(fid, prefix, 'object', self, 'fieldname', 'core_mantle_boundary', 'format', 'Integer')
++        WriteData(fid, prefix, 'object', self, 'fieldname', 'debug', 'format', 'Boolean')
++        WriteData(fid, prefix, 'object', self, 'fieldname', 'hypergeom_table1', 'format', 'DoubleMat', 'mattype', 1)
++        WriteData(fid, prefix, 'object', self, 'fieldname', 'hypergeom_table2', 'format', 'DoubleMat', 'mattype', 1)
++        WriteData(fid, prefix, 'object', self, 'fieldname', 'hypergeom_nalpha', 'format', 'Integer')
++        WriteData(fid, prefix, 'object', self, 'fieldname', 'hypergeom_nz', 'format', 'Integer')
++        WriteData(fid, prefix, 'object', self, 'fieldname', 'hypergeom_z', 'format', 'DoubleMat' 'mattype', 1)
++    #}}}
++
++    def extrude(self, md): #{{{
++        return self
++    #}}}
++
++    def build_frequencies_from_time(self): #{{{
++        if not self.istemporal:
++            raise RuntimeError('cannot build frequencies for temporal love numbers if love.istemporal==0')
++        print('Temporal love numbers: Overriding md.love.nfreq and md.love.frequencies')
++        self.nfreq = len(self.time) * 2 * self.n_temporal_iterations
++        self.frequencies = np.zeros((self.nfreq,))
++        for i in range(len(self.time)):
++            for j in range(2 * self.n_temporal_iterations):
++                if self.time[i] == 0:
++                    self.frequencies[(i - 1) * 2 * self.n_temporal_iterations + j] = 0 # Convention to avoid marshalling infinite numbers
++                else:
++                    self.frequencies[(i - 1) * 2 * self.n_temporal_iterations + j] = j * np.log(2) / self.time[i] / 2 / np.pi
++        return self
++    #}}}
+Index: ../trunk-jpl/src/m/classes/model.py
+===================================================================
+--- ../trunk-jpl/src/m/classes/model.py	(revision 27326)
++++ ../trunk-jpl/src/m/classes/model.py	(revision 27327)
+@@ -270,7 +270,7 @@
+         self.levelset = levelset()
+         self.calving = calving()
+         self.frontalforcings = frontalforcings()
+-        self.love = fourierlove()
++        self.love = love()
+         self.esa = esa()
+         self.sampling = sampling()
+         self.autodiff = autodiff()
Index: /issm/oecreview/Archive/27230-27343/ISSM-27327-27328.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27327-27328.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27327-27328.diff	(revision 27344)
@@ -0,0 +1,13 @@
+Index: ../trunk-jpl/src/m/classes/love.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/love.m	(revision 27327)
++++ ../trunk-jpl/src/m/classes/love.m	(revision 27328)
+@@ -32,7 +32,7 @@
+ 		debug=0;
+ 		hypergeom_table1=0;
+ 		hypergeom_table2=0;
+-		hypergeom_table1=0;
++		hypergeom_nalpha=0;
+ 		hypergeom_nz=0;
+ 		hypergeom_z=0;
+ 	end
Index: /issm/oecreview/Archive/27230-27343/ISSM-27328-27329.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27328-27329.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27328-27329.diff	(revision 27344)
@@ -0,0 +1,13 @@
+Index: ../trunk-jpl/src/m/classes/model.py
+===================================================================
+--- ../trunk-jpl/src/m/classes/model.py	(revision 27328)
++++ ../trunk-jpl/src/m/classes/model.py	(revision 27329)
+@@ -18,7 +18,7 @@
+ from matice import matice
+ from levelset import levelset
+ from calving import calving
+-from fourierlove import fourierlove
++from love import love
+ from calvinglevermann import calvinglevermann
+ #from calvingpi import calvingpi
+ from frontalforcings import frontalforcings
Index: /issm/oecreview/Archive/27230-27343/ISSM-27329-27330.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27329-27330.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27329-27330.diff	(revision 27344)
@@ -0,0 +1,13 @@
+Index: ../trunk-jpl/src/m/classes/love.py
+===================================================================
+--- ../trunk-jpl/src/m/classes/love.py	(revision 27329)
++++ ../trunk-jpl/src/m/classes/love.py	(revision 27330)
+@@ -186,7 +186,7 @@
+         WriteData(fid, prefix, 'object', self, 'fieldname', 'g0', 'format', 'Double')
+         WriteData(fid, prefix, 'object', self, 'fieldname', 'r0', 'format', 'Double')
+         WriteData(fid, prefix, 'object', self, 'fieldname', 'mu0', 'format', 'Double')
+-        WriteData(fid, prefix, 'object', self, 'fieldname', 'Gravitational_Constant', 'format', 'max_integration_dr')
++        WriteData(fid, prefix, 'object', self, 'fieldname', 'Gravitational_Constant', 'format', 'Double')
+         WriteData(fid, prefix, 'object', self, 'fieldname', 'chandler_wobble', 'format', 'Boolean')
+         WriteData(fid, prefix, 'object', self, 'fieldname', 'allow_layer_deletion', 'format', 'Boolean')
+         WriteData(fid, prefix, 'object', self, 'fieldname', 'underflow_tol', 'format', 'Double')
Index: /issm/oecreview/Archive/27230-27343/ISSM-27330-27331.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27330-27331.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27330-27331.diff	(revision 27344)
@@ -0,0 +1,12 @@
+Index: ../trunk-jpl/src/m/classes/love.py
+===================================================================
+--- ../trunk-jpl/src/m/classes/love.py	(revision 27330)
++++ ../trunk-jpl/src/m/classes/love.py	(revision 27331)
+@@ -118,6 +118,7 @@
+         self.core_mantle_boundary = 2
+         self.complex_computation = 0
+         self.quad_precision = 0
++        self.debug = 0
+         self.hypergeom_table1 = 1
+         self.hypergeom_table2 = 1
+         self.hypergeom_nalpha = 1
Index: /issm/oecreview/Archive/27230-27343/ISSM-27331-27332.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27331-27332.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27331-27332.diff	(revision 27344)
@@ -0,0 +1,13 @@
+Index: ../trunk-jpl/src/m/classes/love.py
+===================================================================
+--- ../trunk-jpl/src/m/classes/love.py	(revision 27331)
++++ ../trunk-jpl/src/m/classes/love.py	(revision 27332)
+@@ -209,7 +209,7 @@
+         WriteData(fid, prefix, 'object', self, 'fieldname', 'hypergeom_table2', 'format', 'DoubleMat', 'mattype', 1)
+         WriteData(fid, prefix, 'object', self, 'fieldname', 'hypergeom_nalpha', 'format', 'Integer')
+         WriteData(fid, prefix, 'object', self, 'fieldname', 'hypergeom_nz', 'format', 'Integer')
+-        WriteData(fid, prefix, 'object', self, 'fieldname', 'hypergeom_z', 'format', 'DoubleMat' 'mattype', 1)
++        WriteData(fid, prefix, 'object', self, 'fieldname', 'hypergeom_z', 'format', 'DoubleMat' 'mattype', 3)
+     #}}}
+ 
+     def extrude(self, md): #{{{
Index: /issm/oecreview/Archive/27230-27343/ISSM-27332-27333.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27332-27333.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27332-27333.diff	(revision 27344)
@@ -0,0 +1,13 @@
+Index: ../trunk-jpl/src/m/classes/love.py
+===================================================================
+--- ../trunk-jpl/src/m/classes/love.py	(revision 27332)
++++ ../trunk-jpl/src/m/classes/love.py	(revision 27333)
+@@ -209,7 +209,7 @@
+         WriteData(fid, prefix, 'object', self, 'fieldname', 'hypergeom_table2', 'format', 'DoubleMat', 'mattype', 1)
+         WriteData(fid, prefix, 'object', self, 'fieldname', 'hypergeom_nalpha', 'format', 'Integer')
+         WriteData(fid, prefix, 'object', self, 'fieldname', 'hypergeom_nz', 'format', 'Integer')
+-        WriteData(fid, prefix, 'object', self, 'fieldname', 'hypergeom_z', 'format', 'DoubleMat' 'mattype', 3)
++        WriteData(fid, prefix, 'object', self, 'fieldname', 'hypergeom_z', 'format', 'DoubleMat', 'mattype', 3)
+     #}}}
+ 
+     def extrude(self, md): #{{{
Index: /issm/oecreview/Archive/27230-27343/ISSM-27333-27334.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27333-27334.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27333-27334.diff	(revision 27344)
@@ -0,0 +1,1123 @@
+Index: ../trunk-jpl/src/c/analyses/LevelsetAnalysis.cpp
+===================================================================
+--- ../trunk-jpl/src/c/analyses/LevelsetAnalysis.cpp	(revision 27333)
++++ ../trunk-jpl/src/c/analyses/LevelsetAnalysis.cpp	(revision 27334)
+@@ -247,6 +247,7 @@
+ 			/*Retrieve autoregressive parameters*/
+ 			parameters->AddObject(iomodel->CopyConstantObject("md.frontalforcings.num_params",FrontalForcingsNumberofParamsEnum));
+ 			parameters->AddObject(iomodel->CopyConstantObject("md.frontalforcings.num_breaks",FrontalForcingsNumberofBreaksEnum));
++			parameters->AddObject(iomodel->CopyConstantObject("md.frontalforcings.monthlyvals_numbreaks",FrontalForcingsNumberofMonthBreaksEnum));
+          parameters->AddObject(iomodel->CopyConstantObject("md.frontalforcings.ar_order",FrontalForcingsARMAarOrderEnum));
+          parameters->AddObject(iomodel->CopyConstantObject("md.frontalforcings.ma_order",FrontalForcingsARMAmaOrderEnum));
+          parameters->AddObject(iomodel->CopyConstantObject("md.frontalforcings.arma_timestep",FrontalForcingsARMATimestepEnum));
+@@ -262,9 +263,15 @@
+          iomodel->FetchData(&transparam,&M,&N,"md.frontalforcings.malag_coefs");
+          parameters->AddObject(new DoubleMatParam(FrontalForcingsARMAmalagcoefsEnum,transparam,M,N));
+          xDelete<IssmDouble>(transparam);
+-			iomodel->FetchData(&transparam,&M,&N,"md.frontalforcings.monthly_effects");
+-         parameters->AddObject(new DoubleMatParam(ThermalForcingMonthlyEffectsEnum,transparam,M,N));
++			iomodel->FetchData(&transparam,&M,&N,"md.frontalforcings.monthlyvals_datebreaks");
++         parameters->AddObject(new DoubleMatParam(FrontalForcingsARMAmonthdatebreaksEnum,transparam,M,N));
+          xDelete<IssmDouble>(transparam);
++			iomodel->FetchData(&transparam,&M,&N,"md.frontalforcings.monthlyvals_intercepts");
++         parameters->AddObject(new DoubleMatParam(FrontalForcingsARMAmonthinterceptsEnum,transparam,M,N));
++         xDelete<IssmDouble>(transparam);
++			iomodel->FetchData(&transparam,&M,&N,"md.frontalforcings.monthlyvals_trends");
++         parameters->AddObject(new DoubleMatParam(FrontalForcingsARMAmonthtrendsEnum,transparam,M,N));
++         xDelete<IssmDouble>(transparam);
+ 			/*Do not break here, generic FrontalForcingsRignot parameters still to be retrieved*/
+ 		case FrontalForcingsRignotEnum:
+ 			parameters->AddObject(iomodel->CopyConstantObject("md.frontalforcings.num_basins",FrontalForcingsNumberofBasinsEnum));
+Index: ../trunk-jpl/src/c/classes/Elements/Element.h
+===================================================================
+--- ../trunk-jpl/src/c/classes/Elements/Element.h	(revision 27333)
++++ ../trunk-jpl/src/c/classes/Elements/Element.h	(revision 27334)
+@@ -163,7 +163,7 @@
+ 		void               MarshallElement2(MarshallHandle* marshallhandle,int numanalyses);
+ 		void               MigrateGroundingLine(IssmDouble* sheet_ungrounding);
+ 		void               MismipFloatingiceMeltingRate();
+-		void               MonthlyEffectBasin(IssmDouble* monthlyeff, int enum_type); 
++		void               MonthlyPiecewiseLinearEffectBasin(int nummonthbreaks,IssmDouble* monthlyintercepts,IssmDouble* monthlytrends,IssmDouble* monthlydatebreaks,int enum_type); 
+ 		void               BeckmannGoosseFloatingiceMeltingRate();
+ 		void               MungsmtpParameterization(void);
+ 		ElementMatrix*     NewElementMatrix(int approximation_enum=NoneApproximationEnum);
+Index: ../trunk-jpl/src/c/shared/Enum/Enum.vim
+===================================================================
+--- ../trunk-jpl/src/c/shared/Enum/Enum.vim	(revision 27333)
++++ ../trunk-jpl/src/c/shared/Enum/Enum.vim	(revision 27334)
+@@ -173,7 +173,6 @@
+ syn keyword cConstant DebrisRemovalStressThresholdEnum
+ syn keyword cConstant DebrisPackingFractionEnum
+ syn keyword cConstant DebugProfilingEnum
+-syn keyword cConstant DebrisThicknessEnum
+ syn keyword cConstant DomainDimensionEnum
+ syn keyword cConstant DomainTypeEnum
+ syn keyword cConstant DslModelEnum
+@@ -217,9 +216,13 @@
+ syn keyword cConstant FrontalForcingsARMAarOrderEnum
+ syn keyword cConstant FrontalForcingsARMAmaOrderEnum
+ syn keyword cConstant FrontalForcingsARMAdatebreaksEnum
++syn keyword cConstant FrontalForcingsARMAmonthdatebreaksEnum
++syn keyword cConstant FrontalForcingsARMAmonthinterceptsEnum
++syn keyword cConstant FrontalForcingsARMAmonthtrendsEnum
+ syn keyword cConstant FrontalForcingsARMApolyparamsEnum
+ syn keyword cConstant FrontalForcingsNumberofBasinsEnum
+ syn keyword cConstant FrontalForcingsNumberofBreaksEnum
++syn keyword cConstant FrontalForcingsNumberofMonthBreaksEnum
+ syn keyword cConstant FrontalForcingsNumberofParamsEnum
+ syn keyword cConstant FrontalForcingsParamEnum
+ syn keyword cConstant FrontalForcingsARMAarlagcoefsEnum
+@@ -723,6 +726,7 @@
+ syn keyword cConstant DamageDbarEnum
+ syn keyword cConstant DamageDbarOldEnum
+ syn keyword cConstant DamageFEnum
++syn keyword cConstant DebrisThicknessEnum
+ syn keyword cConstant DegreeOfChannelizationEnum
+ syn keyword cConstant DepthBelowSurfaceEnum
+ syn keyword cConstant DeltaIceThicknessEnum
+Index: ../trunk-jpl/src/c/shared/Enum/EnumDefinitions.h
+===================================================================
+--- ../trunk-jpl/src/c/shared/Enum/EnumDefinitions.h	(revision 27333)
++++ ../trunk-jpl/src/c/shared/Enum/EnumDefinitions.h	(revision 27334)
+@@ -210,9 +210,13 @@
+    FrontalForcingsARMAarOrderEnum,
+    FrontalForcingsARMAmaOrderEnum,
+    FrontalForcingsARMAdatebreaksEnum,
++	FrontalForcingsARMAmonthdatebreaksEnum,
++   FrontalForcingsARMAmonthinterceptsEnum,
++   FrontalForcingsARMAmonthtrendsEnum,
+    FrontalForcingsARMApolyparamsEnum,
+ 	FrontalForcingsNumberofBasinsEnum,
+ 	FrontalForcingsNumberofBreaksEnum,
++	FrontalForcingsNumberofMonthBreaksEnum,
+ 	FrontalForcingsNumberofParamsEnum,
+ 	FrontalForcingsParamEnum,
+    FrontalForcingsARMAarlagcoefsEnum,
+Index: ../trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp
+===================================================================
+--- ../trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp	(revision 27333)
++++ ../trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp	(revision 27334)
+@@ -218,9 +218,13 @@
+ 		case FrontalForcingsARMAarOrderEnum : return "FrontalForcingsARMAarOrder";
+ 		case FrontalForcingsARMAmaOrderEnum : return "FrontalForcingsARMAmaOrder";
+ 		case FrontalForcingsARMAdatebreaksEnum : return "FrontalForcingsARMAdatebreaks";
++		case FrontalForcingsARMAmonthdatebreaksEnum : return "FrontalForcingsARMAmonthdatebreaks";
++		case FrontalForcingsARMAmonthinterceptsEnum : return "FrontalForcingsARMAmonthintercepts";
++		case FrontalForcingsARMAmonthtrendsEnum : return "FrontalForcingsARMAmonthtrends";
+ 		case FrontalForcingsARMApolyparamsEnum : return "FrontalForcingsARMApolyparams";
+ 		case FrontalForcingsNumberofBasinsEnum : return "FrontalForcingsNumberofBasins";
+ 		case FrontalForcingsNumberofBreaksEnum : return "FrontalForcingsNumberofBreaks";
++		case FrontalForcingsNumberofMonthBreaksEnum : return "FrontalForcingsNumberofMonthBreaks";
+ 		case FrontalForcingsNumberofParamsEnum : return "FrontalForcingsNumberofParams";
+ 		case FrontalForcingsParamEnum : return "FrontalForcingsParam";
+ 		case FrontalForcingsARMAarlagcoefsEnum : return "FrontalForcingsARMAarlagcoefs";
+Index: ../trunk-jpl/src/c/shared/Enum/Enumjl.vim
+===================================================================
+--- ../trunk-jpl/src/c/shared/Enum/Enumjl.vim	(revision 27333)
++++ ../trunk-jpl/src/c/shared/Enum/Enumjl.vim	(revision 27334)
+@@ -166,7 +166,6 @@
+ syn keyword juliaConstC DebrisRemovalStressThresholdEnum
+ syn keyword juliaConstC DebrisPackingFractionEnum
+ syn keyword juliaConstC DebugProfilingEnum
+-syn keyword juliaConstC DebrisThicknessEnum
+ syn keyword juliaConstC DomainDimensionEnum
+ syn keyword juliaConstC DomainTypeEnum
+ syn keyword juliaConstC DslModelEnum
+@@ -210,9 +209,13 @@
+ syn keyword juliaConstC FrontalForcingsARMAarOrderEnum
+ syn keyword juliaConstC FrontalForcingsARMAmaOrderEnum
+ syn keyword juliaConstC FrontalForcingsARMAdatebreaksEnum
++syn keyword juliaConstC FrontalForcingsARMAmonthdatebreaksEnum
++syn keyword juliaConstC FrontalForcingsARMAmonthinterceptsEnum
++syn keyword juliaConstC FrontalForcingsARMAmonthtrendsEnum
+ syn keyword juliaConstC FrontalForcingsARMApolyparamsEnum
+ syn keyword juliaConstC FrontalForcingsNumberofBasinsEnum
+ syn keyword juliaConstC FrontalForcingsNumberofBreaksEnum
++syn keyword juliaConstC FrontalForcingsNumberofMonthBreaksEnum
+ syn keyword juliaConstC FrontalForcingsNumberofParamsEnum
+ syn keyword juliaConstC FrontalForcingsParamEnum
+ syn keyword juliaConstC FrontalForcingsARMAarlagcoefsEnum
+@@ -716,6 +719,7 @@
+ syn keyword juliaConstC DamageDbarEnum
+ syn keyword juliaConstC DamageDbarOldEnum
+ syn keyword juliaConstC DamageFEnum
++syn keyword juliaConstC DebrisThicknessEnum
+ syn keyword juliaConstC DegreeOfChannelizationEnum
+ syn keyword juliaConstC DepthBelowSurfaceEnum
+ syn keyword juliaConstC DeltaIceThicknessEnum
+Index: ../trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp
+===================================================================
+--- ../trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp	(revision 27333)
++++ ../trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp	(revision 27334)
+@@ -221,9 +221,13 @@
+ 	      else if (strcmp(name,"FrontalForcingsARMAarOrder")==0) return FrontalForcingsARMAarOrderEnum;
+ 	      else if (strcmp(name,"FrontalForcingsARMAmaOrder")==0) return FrontalForcingsARMAmaOrderEnum;
+ 	      else if (strcmp(name,"FrontalForcingsARMAdatebreaks")==0) return FrontalForcingsARMAdatebreaksEnum;
++	      else if (strcmp(name,"FrontalForcingsARMAmonthdatebreaks")==0) return FrontalForcingsARMAmonthdatebreaksEnum;
++	      else if (strcmp(name,"FrontalForcingsARMAmonthintercepts")==0) return FrontalForcingsARMAmonthinterceptsEnum;
++	      else if (strcmp(name,"FrontalForcingsARMAmonthtrends")==0) return FrontalForcingsARMAmonthtrendsEnum;
+ 	      else if (strcmp(name,"FrontalForcingsARMApolyparams")==0) return FrontalForcingsARMApolyparamsEnum;
+ 	      else if (strcmp(name,"FrontalForcingsNumberofBasins")==0) return FrontalForcingsNumberofBasinsEnum;
+ 	      else if (strcmp(name,"FrontalForcingsNumberofBreaks")==0) return FrontalForcingsNumberofBreaksEnum;
++	      else if (strcmp(name,"FrontalForcingsNumberofMonthBreaks")==0) return FrontalForcingsNumberofMonthBreaksEnum;
+ 	      else if (strcmp(name,"FrontalForcingsNumberofParams")==0) return FrontalForcingsNumberofParamsEnum;
+ 	      else if (strcmp(name,"FrontalForcingsParam")==0) return FrontalForcingsParamEnum;
+ 	      else if (strcmp(name,"FrontalForcingsARMAarlagcoefs")==0) return FrontalForcingsARMAarlagcoefsEnum;
+@@ -255,14 +259,14 @@
+ 	      else if (strcmp(name,"HydrologydcEplLayerCompressibility")==0) return HydrologydcEplLayerCompressibilityEnum;
+ 	      else if (strcmp(name,"HydrologydcEplMaxThickness")==0) return HydrologydcEplMaxThicknessEnum;
+ 	      else if (strcmp(name,"HydrologydcEplPoreWaterMass")==0) return HydrologydcEplPoreWaterMassEnum;
+-	      else if (strcmp(name,"HydrologydcEplThickComp")==0) return HydrologydcEplThickCompEnum;
++         else stage=3;
++   }
++   if(stage==3){
++	      if (strcmp(name,"HydrologydcEplThickComp")==0) return HydrologydcEplThickCompEnum;
+ 	      else if (strcmp(name,"HydrologydcEplflipLock")==0) return HydrologydcEplflipLockEnum;
+ 	      else if (strcmp(name,"HydrologydcIsefficientlayer")==0) return HydrologydcIsefficientlayerEnum;
+ 	      else if (strcmp(name,"HydrologydcLeakageFactor")==0) return HydrologydcLeakageFactorEnum;
+-         else stage=3;
+-   }
+-   if(stage==3){
+-	      if (strcmp(name,"HydrologydcMaxIter")==0) return HydrologydcMaxIterEnum;
++	      else if (strcmp(name,"HydrologydcMaxIter")==0) return HydrologydcMaxIterEnum;
+ 	      else if (strcmp(name,"HydrologydcPenaltyFactor")==0) return HydrologydcPenaltyFactorEnum;
+ 	      else if (strcmp(name,"HydrologydcPenaltyLock")==0) return HydrologydcPenaltyLockEnum;
+ 	      else if (strcmp(name,"HydrologydcRelTol")==0) return HydrologydcRelTolEnum;
+@@ -378,14 +382,14 @@
+ 	      else if (strcmp(name,"NumModels")==0) return NumModelsEnum;
+ 	      else if (strcmp(name,"OceanGridNx")==0) return OceanGridNxEnum;
+ 	      else if (strcmp(name,"OceanGridNy")==0) return OceanGridNyEnum;
+-	      else if (strcmp(name,"OceanGridX")==0) return OceanGridXEnum;
++         else stage=4;
++   }
++   if(stage==4){
++	      if (strcmp(name,"OceanGridX")==0) return OceanGridXEnum;
+ 	      else if (strcmp(name,"OceanGridY")==0) return OceanGridYEnum;
+ 	      else if (strcmp(name,"OutputBufferPointer")==0) return OutputBufferPointerEnum;
+ 	      else if (strcmp(name,"OutputBufferSizePointer")==0) return OutputBufferSizePointerEnum;
+-         else stage=4;
+-   }
+-   if(stage==4){
+-	      if (strcmp(name,"OutputFileName")==0) return OutputFileNameEnum;
++	      else if (strcmp(name,"OutputFileName")==0) return OutputFileNameEnum;
+ 	      else if (strcmp(name,"OutputFilePointer")==0) return OutputFilePointerEnum;
+ 	      else if (strcmp(name,"Outputdefinition")==0) return OutputdefinitionEnum;
+ 	      else if (strcmp(name,"QmuErrName")==0) return QmuErrNameEnum;
+@@ -501,14 +505,14 @@
+ 	      else if (strcmp(name,"SmbAIce")==0) return SmbAIceEnum;
+ 	      else if (strcmp(name,"SmbAIdx")==0) return SmbAIdxEnum;
+ 	      else if (strcmp(name,"SmbASnow")==0) return SmbASnowEnum;
+-	      else if (strcmp(name,"SmbAccualti")==0) return SmbAccualtiEnum;
++         else stage=5;
++   }
++   if(stage==5){
++	      if (strcmp(name,"SmbAccualti")==0) return SmbAccualtiEnum;
+ 	      else if (strcmp(name,"SmbAccugrad")==0) return SmbAccugradEnum;
+ 	      else if (strcmp(name,"SmbAccuref")==0) return SmbAccurefEnum;
+ 	      else if (strcmp(name,"SmbAdThresh")==0) return SmbAdThreshEnum;
+-         else stage=5;
+-   }
+-   if(stage==5){
+-	      if (strcmp(name,"SmbARMATimestep")==0) return SmbARMATimestepEnum;
++	      else if (strcmp(name,"SmbARMATimestep")==0) return SmbARMATimestepEnum;
+ 	      else if (strcmp(name,"SmbARMAarOrder")==0) return SmbARMAarOrderEnum;
+ 	      else if (strcmp(name,"SmbARMAmaOrder")==0) return SmbARMAmaOrderEnum;
+ 	      else if (strcmp(name,"SmbAveraging")==0) return SmbAveragingEnum;
+@@ -624,14 +628,14 @@
+ 	      else if (strcmp(name,"ToolkitsTypes")==0) return ToolkitsTypesEnum;
+ 	      else if (strcmp(name,"TransientAmrFrequency")==0) return TransientAmrFrequencyEnum;
+ 	      else if (strcmp(name,"TransientIsage")==0) return TransientIsageEnum;
+-	      else if (strcmp(name,"TransientIsdamageevolution")==0) return TransientIsdamageevolutionEnum;
++         else stage=6;
++   }
++   if(stage==6){
++	      if (strcmp(name,"TransientIsdamageevolution")==0) return TransientIsdamageevolutionEnum;
+ 	      else if (strcmp(name,"TransientIsdebris")==0) return TransientIsdebrisEnum;
+ 	      else if (strcmp(name,"TransientIsesa")==0) return TransientIsesaEnum;
+ 	      else if (strcmp(name,"TransientIsgia")==0) return TransientIsgiaEnum;
+-         else stage=6;
+-   }
+-   if(stage==6){
+-	      if (strcmp(name,"TransientIsgroundingline")==0) return TransientIsgroundinglineEnum;
++	      else if (strcmp(name,"TransientIsgroundingline")==0) return TransientIsgroundinglineEnum;
+ 	      else if (strcmp(name,"TransientIshydrology")==0) return TransientIshydrologyEnum;
+ 	      else if (strcmp(name,"TransientIsmasstransport")==0) return TransientIsmasstransportEnum;
+ 	      else if (strcmp(name,"TransientIsoceantransport")==0) return TransientIsoceantransportEnum;
+@@ -747,14 +751,14 @@
+ 	      else if (strcmp(name,"DeltaBottomPressure")==0) return DeltaBottomPressureEnum;
+ 	      else if (strcmp(name,"DeltaDsl")==0) return DeltaDslEnum;
+ 	      else if (strcmp(name,"DslOld")==0) return DslOldEnum;
+-	      else if (strcmp(name,"Dsl")==0) return DslEnum;
++         else stage=7;
++   }
++   if(stage==7){
++	      if (strcmp(name,"Dsl")==0) return DslEnum;
+ 	      else if (strcmp(name,"DeltaStr")==0) return DeltaStrEnum;
+ 	      else if (strcmp(name,"StrOld")==0) return StrOldEnum;
+ 	      else if (strcmp(name,"Str")==0) return StrEnum;
+-         else stage=7;
+-   }
+-   if(stage==7){
+-	      if (strcmp(name,"DeviatoricStresseffective")==0) return DeviatoricStresseffectiveEnum;
++	      else if (strcmp(name,"DeviatoricStresseffective")==0) return DeviatoricStresseffectiveEnum;
+ 	      else if (strcmp(name,"DeviatoricStressxx")==0) return DeviatoricStressxxEnum;
+ 	      else if (strcmp(name,"DeviatoricStressxy")==0) return DeviatoricStressxyEnum;
+ 	      else if (strcmp(name,"DeviatoricStressxz")==0) return DeviatoricStressxzEnum;
+@@ -870,14 +874,14 @@
+ 	      else if (strcmp(name,"LevelsetfunctionSlopeY")==0) return LevelsetfunctionSlopeYEnum;
+ 	      else if (strcmp(name,"LevelsetObservation")==0) return LevelsetObservationEnum;
+ 	      else if (strcmp(name,"LoadingforceX")==0) return LoadingforceXEnum;
+-	      else if (strcmp(name,"LoadingforceY")==0) return LoadingforceYEnum;
++         else stage=8;
++   }
++   if(stage==8){
++	      if (strcmp(name,"LoadingforceY")==0) return LoadingforceYEnum;
+ 	      else if (strcmp(name,"LoadingforceZ")==0) return LoadingforceZEnum;
+ 	      else if (strcmp(name,"MaskOceanLevelset")==0) return MaskOceanLevelsetEnum;
+ 	      else if (strcmp(name,"MaskIceLevelset")==0) return MaskIceLevelsetEnum;
+-         else stage=8;
+-   }
+-   if(stage==8){
+-	      if (strcmp(name,"MaskIceRefLevelset")==0) return MaskIceRefLevelsetEnum;
++	      else if (strcmp(name,"MaskIceRefLevelset")==0) return MaskIceRefLevelsetEnum;
+ 	      else if (strcmp(name,"MasstransportSpcthickness")==0) return MasstransportSpcthicknessEnum;
+ 	      else if (strcmp(name,"MaterialsRheologyB")==0) return MaterialsRheologyBEnum;
+ 	      else if (strcmp(name,"MaterialsRheologyBbar")==0) return MaterialsRheologyBbarEnum;
+@@ -993,14 +997,14 @@
+ 	      else if (strcmp(name,"SedimentHeadStacked")==0) return SedimentHeadStackedEnum;
+ 	      else if (strcmp(name,"SigmaNN")==0) return SigmaNNEnum;
+ 	      else if (strcmp(name,"SigmaVM")==0) return SigmaVMEnum;
+-	      else if (strcmp(name,"SmbAccumulatedEC")==0) return SmbAccumulatedECEnum;
++         else stage=9;
++   }
++   if(stage==9){
++	      if (strcmp(name,"SmbAccumulatedEC")==0) return SmbAccumulatedECEnum;
+ 	      else if (strcmp(name,"SmbAccumulatedMassBalance")==0) return SmbAccumulatedMassBalanceEnum;
+ 	      else if (strcmp(name,"SmbAccumulatedMelt")==0) return SmbAccumulatedMeltEnum;
+ 	      else if (strcmp(name,"SmbAccumulatedPrecipitation")==0) return SmbAccumulatedPrecipitationEnum;
+-         else stage=9;
+-   }
+-   if(stage==9){
+-	      if (strcmp(name,"SmbAccumulatedRain")==0) return SmbAccumulatedRainEnum;
++	      else if (strcmp(name,"SmbAccumulatedRain")==0) return SmbAccumulatedRainEnum;
+ 	      else if (strcmp(name,"SmbAccumulatedRefreeze")==0) return SmbAccumulatedRefreezeEnum;
+ 	      else if (strcmp(name,"SmbAccumulatedRunoff")==0) return SmbAccumulatedRunoffEnum;
+ 	      else if (strcmp(name,"SmbA")==0) return SmbAEnum;
+@@ -1116,14 +1120,14 @@
+ 	      else if (strcmp(name,"StochasticForcingDefaultId")==0) return StochasticForcingDefaultIdEnum;
+ 	      else if (strcmp(name,"StrainRateeffective")==0) return StrainRateeffectiveEnum;
+ 	      else if (strcmp(name,"StrainRateparallel")==0) return StrainRateparallelEnum;
+-	      else if (strcmp(name,"StrainRateperpendicular")==0) return StrainRateperpendicularEnum;
++         else stage=10;
++   }
++   if(stage==10){
++	      if (strcmp(name,"StrainRateperpendicular")==0) return StrainRateperpendicularEnum;
+ 	      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 stage=10;
+-   }
+-   if(stage==10){
+-	      if (strcmp(name,"StrainRateyy")==0) return StrainRateyyEnum;
++	      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,"StressMaxPrincipal")==0) return StressMaxPrincipalEnum;
+@@ -1239,14 +1243,14 @@
+ 	      else if (strcmp(name,"Outputdefinition44")==0) return Outputdefinition44Enum;
+ 	      else if (strcmp(name,"Outputdefinition45")==0) return Outputdefinition45Enum;
+ 	      else if (strcmp(name,"Outputdefinition46")==0) return Outputdefinition46Enum;
+-	      else if (strcmp(name,"Outputdefinition47")==0) return Outputdefinition47Enum;
++         else stage=11;
++   }
++   if(stage==11){
++	      if (strcmp(name,"Outputdefinition47")==0) return Outputdefinition47Enum;
+ 	      else if (strcmp(name,"Outputdefinition48")==0) return Outputdefinition48Enum;
+ 	      else if (strcmp(name,"Outputdefinition49")==0) return Outputdefinition49Enum;
+ 	      else if (strcmp(name,"Outputdefinition4")==0) return Outputdefinition4Enum;
+-         else stage=11;
+-   }
+-   if(stage==11){
+-	      if (strcmp(name,"Outputdefinition50")==0) return Outputdefinition50Enum;
++	      else if (strcmp(name,"Outputdefinition50")==0) return Outputdefinition50Enum;
+ 	      else if (strcmp(name,"Outputdefinition51")==0) return Outputdefinition51Enum;
+ 	      else if (strcmp(name,"Outputdefinition52")==0) return Outputdefinition52Enum;
+ 	      else if (strcmp(name,"Outputdefinition53")==0) return Outputdefinition53Enum;
+@@ -1362,14 +1366,14 @@
+ 	      else if (strcmp(name,"ControlInputMins")==0) return ControlInputMinsEnum;
+ 	      else if (strcmp(name,"ControlInputValues")==0) return ControlInputValuesEnum;
+ 	      else if (strcmp(name,"CrouzeixRaviart")==0) return CrouzeixRaviartEnum;
+-	      else if (strcmp(name,"Cuffey")==0) return CuffeyEnum;
++         else stage=12;
++   }
++   if(stage==12){
++	      if (strcmp(name,"Cuffey")==0) return CuffeyEnum;
+ 	      else if (strcmp(name,"CuffeyTemperate")==0) return CuffeyTemperateEnum;
+ 	      else if (strcmp(name,"DamageEvolutionAnalysis")==0) return DamageEvolutionAnalysisEnum;
+ 	      else if (strcmp(name,"DamageEvolutionSolution")==0) return DamageEvolutionSolutionEnum;
+-         else stage=12;
+-   }
+-   if(stage==12){
+-	      if (strcmp(name,"DataSet")==0) return DataSetEnum;
++	      else if (strcmp(name,"DataSet")==0) return DataSetEnum;
+ 	      else if (strcmp(name,"DataSetParam")==0) return DataSetParamEnum;
+ 	      else if (strcmp(name,"DatasetInput")==0) return DatasetInputEnum;
+ 	      else if (strcmp(name,"DebrisAnalysis")==0) return DebrisAnalysisEnum;
+@@ -1485,14 +1489,14 @@
+ 	      else if (strcmp(name,"LambdaS")==0) return LambdaSEnum;
+ 	      else if (strcmp(name,"LevelsetAnalysis")==0) return LevelsetAnalysisEnum;
+ 	      else if (strcmp(name,"LevelsetfunctionPicard")==0) return LevelsetfunctionPicardEnum;
+-	      else if (strcmp(name,"LinearFloatingMeltRate")==0) return LinearFloatingMeltRateEnum;
++         else stage=13;
++   }
++   if(stage==13){
++	      if (strcmp(name,"LinearFloatingMeltRate")==0) return LinearFloatingMeltRateEnum;
+ 	      else if (strcmp(name,"LinearFloatingMeltRatearma")==0) return LinearFloatingMeltRatearmaEnum;
+ 	      else if (strcmp(name,"LliboutryDuval")==0) return LliboutryDuvalEnum;
+ 	      else if (strcmp(name,"Loads")==0) return LoadsEnum;
+-         else stage=13;
+-   }
+-   if(stage==13){
+-	      if (strcmp(name,"LoveAnalysis")==0) return LoveAnalysisEnum;
++	      else if (strcmp(name,"LoveAnalysis")==0) return LoveAnalysisEnum;
+ 	      else if (strcmp(name,"LoveHf")==0) return LoveHfEnum;
+ 	      else if (strcmp(name,"LoveHt")==0) return LoveHtEnum;
+ 	      else if (strcmp(name,"LoveKernelsImag")==0) return LoveKernelsImagEnum;
+@@ -1608,14 +1612,14 @@
+ 	      else if (strcmp(name,"SMBgemb")==0) return SMBgembEnum;
+ 	      else if (strcmp(name,"SMBgradients")==0) return SMBgradientsEnum;
+ 	      else if (strcmp(name,"SMBgradientscomponents")==0) return SMBgradientscomponentsEnum;
+-	      else if (strcmp(name,"SMBgradientsela")==0) return SMBgradientselaEnum;
++         else stage=14;
++   }
++   if(stage==14){
++	      if (strcmp(name,"SMBgradientsela")==0) return SMBgradientselaEnum;
+ 	      else if (strcmp(name,"SMBhenning")==0) return SMBhenningEnum;
+ 	      else if (strcmp(name,"SMBmeltcomponents")==0) return SMBmeltcomponentsEnum;
+ 	      else if (strcmp(name,"SMBpdd")==0) return SMBpddEnum;
+-         else stage=14;
+-   }
+-   if(stage==14){
+-	      if (strcmp(name,"SMBpddSicopolis")==0) return SMBpddSicopolisEnum;
++	      else if (strcmp(name,"SMBpddSicopolis")==0) return SMBpddSicopolisEnum;
+ 	      else if (strcmp(name,"SMBsemic")==0) return SMBsemicEnum;
+ 	      else if (strcmp(name,"SSAApproximation")==0) return SSAApproximationEnum;
+ 	      else if (strcmp(name,"SSAFSApproximation")==0) return SSAFSApproximationEnum;
+Index: ../trunk-jpl/src/m/classes/frontalforcingsrignotarma.m
+===================================================================
+--- ../trunk-jpl/src/m/classes/frontalforcingsrignotarma.m	(revision 27333)
++++ ../trunk-jpl/src/m/classes/frontalforcingsrignotarma.m	(revision 27334)
+@@ -5,19 +5,22 @@
+ 
+ classdef frontalforcingsrignotarma
+ 	properties (SetAccess=public) 
+-		num_basins           = 0;
+-		num_params           = 0;
+-		num_breaks           = 0;
+-		polynomialparams     = NaN;
+-		datebreaks           = NaN;
+-		ar_order             = 0;
+-		ma_order             = 0;
+-		arma_timestep        = 0;
+-		arlag_coefs          = NaN;
+-		malag_coefs          = NaN;
+-		monthly_effects      = NaN;
+-		basin_id             = NaN;
+-		subglacial_discharge = NaN;
++		num_basins               = 0;
++		num_params               = 0;
++		num_breaks               = 0;
++		polynomialparams         = NaN;
++		datebreaks               = NaN;
++		ar_order                 = 0;
++		ma_order                 = 0;
++		arma_timestep            = 0;
++		arlag_coefs              = NaN;
++		malag_coefs              = NaN;
++		monthlyvals_intercepts   = NaN;
++		monthlyvals_trends       = NaN;
++		monthlyvals_numbreaks    = 0;
++		monthlyvals_datebreaks   = NaN;
++		basin_id                 = NaN;
++		subglacial_discharge     = NaN;
+ 	end
+ 	methods
+ 		function self = frontalforcingsrignotarma(varargin) % {{{
+@@ -51,46 +54,79 @@
+ 
+ 		end % }}}
+ 		function md = checkconsistency(self,md,solution,analyses) % {{{
+-			%Early return
+-			if (~strcmp(solution,'TransientSolution') | md.transient.ismovingfront==0), return; end
++         %Early return
++         if (~strcmp(solution,'TransientSolution') | md.transient.ismovingfront==0), return; end
+ 
+-			nbas = md.frontalforcings.num_basins;
+-			nprm = md.frontalforcings.num_params;
+-			nbrk = md.frontalforcings.num_breaks;
+-			md = checkfield(md,'fieldname','frontalforcings.num_basins','numel',1,'NaN',1,'Inf',1,'>',0);
+-			md = checkfield(md,'fieldname','frontalforcings.num_params','numel',1,'NaN',1,'Inf',1,'>',0);
+-			md = checkfield(md,'fieldname','frontalforcings.num_breaks','numel',1,'NaN',1,'Inf',1,'>=',0);
++         nbas  = md.frontalforcings.num_basins;
++         nprm  = md.frontalforcings.num_params;
++         nbrk  = md.frontalforcings.num_breaks;
++         nMbrk = md.frontalforcings.monthlyvals_numbreaks;
++         md = checkfield(md,'fieldname','frontalforcings.num_basins','numel',1,'NaN',1,'Inf',1,'>',0);
++         md = checkfield(md,'fieldname','frontalforcings.num_params','numel',1,'NaN',1,'Inf',1,'>',0);
++         md = checkfield(md,'fieldname','frontalforcings.num_breaks','numel',1,'NaN',1,'Inf',1,'>=',0);
+          md = checkfield(md,'fieldname','frontalforcings.basin_id','Inf',1,'>=',0,'<=',md.frontalforcings.num_basins,'size',[md.mesh.numberofelements 1]);
+-			md = checkfield(md,'fieldname','frontalforcings.subglacial_discharge','>=',0,'NaN',1,'Inf',1,'timeseries',1);
+-			if(nbas>1 && nbrk>=1 && nprm>1)
+-			   md = checkfield(md,'fieldname','frontalforcings.polynomialparams','NaN',1,'Inf',1,'size',[nbas,nbrk+1,nprm],'numel',nbas*(nbrk+1)*nprm); 
+-			elseif(nbas==1)
+-				md = checkfield(md,'fieldname','frontalforcings.polynomialparams','NaN',1,'Inf',1,'size',[nprm,nbrk+1],'numel',nbas*(nbrk+1)*nprm);
+-			elseif(nbrk==0)
+-				md = checkfield(md,'fieldname','frontalforcings.polynomialparams','NaN',1,'Inf',1,'size',[nbas,nprm],'numel',nbas*(nbrk+1)*nprm);
+-			elseif(nprm==1)
+-				md = checkfield(md,'fieldname','frontalforcings.polynomialparams','NaN',1,'Inf',1,'size',[nbas,nbrk+1],'numel',nbas*(nbrk+1)*nprm);
+-			end
+-			md = checkfield(md,'fieldname','frontalforcings.ar_order','numel',1,'NaN',1,'Inf',1,'>=',0);
++         md = checkfield(md,'fieldname','frontalforcings.subglacial_discharge','>=',0,'NaN',1,'Inf',1,'timeseries',1);
++         if(nbas>1 && nbrk>=1 && nprm>1)
++            md = checkfield(md,'fieldname','frontalforcings.polynomialparams','NaN',1,'Inf',1,'size',[nbas,nbrk+1,nprm],'numel',nbas*(nbrk+1)*nprm);
++         elseif(nbas==1)
++            md = checkfield(md,'fieldname','frontalforcings.polynomialparams','NaN',1,'Inf',1,'size',[nprm,nbrk+1],'numel',nbas*(nbrk+1)*nprm);
++         elseif(nbrk==0)
++            md = checkfield(md,'fieldname','frontalforcings.polynomialparams','NaN',1,'Inf',1,'size',[nbas,nprm],'numel',nbas*(nbrk+1)*nprm);
++         elseif(nprm==1)
++            md = checkfield(md,'fieldname','frontalforcings.polynomialparams','NaN',1,'Inf',1,'size',[nbas,nbrk+1],'numel',nbas*(nbrk+1)*nprm);
++         end
++         md = checkfield(md,'fieldname','frontalforcings.ar_order','numel',1,'NaN',1,'Inf',1,'>=',0);
+          md = checkfield(md,'fieldname','frontalforcings.ma_order','numel',1,'NaN',1,'Inf',1,'>=',0);
+          md = checkfield(md,'fieldname','frontalforcings.arma_timestep','numel',1,'NaN',1,'Inf',1,'>=',md.timestepping.time_step); %ARMA time step cannot be finer than ISSM timestep
+-			md = checkfield(md,'fieldname','frontalforcings.arlag_coefs','NaN',1,'Inf',1,'size',[md.frontalforcings.num_basins,md.frontalforcings.ar_order]);
+-			md = checkfield(md,'fieldname','frontalforcings.malag_coefs','NaN',1,'Inf',1,'size',[md.frontalforcings.num_basins,md.frontalforcings.ma_order]);
+-			if(nbrk>0)
+-				md = checkfield(md,'fieldname','frontalforcings.datebreaks','NaN',1,'Inf',1,'size',[nbas,nbrk]);
+-			elseif(numel(md.frontalforcings.datebreaks)==0 || all(isnan(md.frontalforcings.datebreaks)))
+-				;
++         md = checkfield(md,'fieldname','frontalforcings.arlag_coefs','NaN',1,'Inf',1,'size',[md.frontalforcings.num_basins,md.frontalforcings.ar_order]);
++         md = checkfield(md,'fieldname','frontalforcings.malag_coefs','NaN',1,'Inf',1,'size',[md.frontalforcings.num_basins,md.frontalforcings.ma_order]);
++         if(nbrk>0)
++            md = checkfield(md,'fieldname','frontalforcings.datebreaks','NaN',1,'Inf',1,'size',[nbas,nbrk]);
++         elseif(numel(md.frontalforcings.datebreaks)==0 || all(isnan(md.frontalforcings.datebreaks)))
++            ;
++         else
++            error('md.frontalforcings.num_breaks is 0 but md.frontalforcings.datebreaks is not empty');
++         end
++
++			%%% Check if some monthly forcings are provided %%%
++			if((numel(md.frontalforcings.monthlyvals_intercepts)>1 || ~isnan(md.frontalforcings.monthlyvals_intercepts)) || (numel(md.frontalforcings.monthlyvals_trends)>1 || ~isnan(md.frontalforcings.monthlyvals_trends)) || (numel(md.frontalforcings.monthlyvals_datebreaks)>1 || ~isnan(md.frontalforcings.monthlyvals_datebreaks)))
++				isMonthly = true;
+ 			else
+-				error('md.frontalforcings.num_breaks is 0 but md.frontalforcings.datebreaks is not empty');
++				isMonthly = false;
+ 			end
+-			if(any(~isnan(md.frontalforcings.monthly_effects)))
+-				md = checkfield(md,'fieldname','frontalforcings.monthly_effects','NaN',1,'Inf',1,'size',[md.frontalforcings.num_basins,12]);
+-				if(md.timestepping.time_step>=1)
+-					error('md.frontalforcings.monthly_effects are provided but md.timestepping.time_step>=1');
+-				end
++			if(numel(md.frontalforcings.monthlyvals_trends)>1 || ~isnan(md.frontalforcings.monthlyvals_trends))
++				isMonthlyTrend = true;
++			else
++				isMonthlyTrend = false;
+ 			end
++			if(isMonthly)
++            md = checkfield(md,'fieldname','frontalforcings.monthlyvals_numbreaks','numel',1,'NaN',1,'Inf',1,'>=',0);
++			   if(nbas>1 && nMbrk>=1)
++               md = checkfield(md,'fieldname','frontalforcings.monthlyvals_intercepts','NaN',1,'Inf',1,'size',[nbas,12,nMbrk+1],'numel',nbas*(nMbrk+1)*12);
++			   	if(isMonthlyTrend)
++			   		md = checkfield(md,'fieldname','frontalforcings.monthlyvals_trends','NaN',1,'Inf',1,'size',[nbas,12,nMbrk+1],'numel',nbas*(nMbrk+1)*12);
++			   	end
++			   elseif(nbas==1)
++               md = checkfield(md,'fieldname','frontalforcings.monthlyvals_intercepts','NaN',1,'Inf',1,'size',[nMbrk+1,12],'numel',nbas*(nMbrk+1)*12);
++			   	if(isMonthlyTrend)
++			   		md = checkfield(md,'fieldname','frontalforcings.monthlyvals_trends','NaN',1,'Inf',1,'size',[nMbrk+1,12],'numel',nbas*(nMbrk+1)*12);
++               end
++			   elseif(nMbrk==0)
++               md = checkfield(md,'fieldname','frontalforcings.monthlyvals_intercepts','NaN',1,'Inf',1,'size',[nbas,12],'numel',nbas*(nMbrk+1)*12);
++			   	if(isMonthlyTrend)
++			   		md = checkfield(md,'fieldname','frontalforcings.monthlyvals_trends','NaN',1,'Inf',1,'size',[nbas,12],'numel',nbas*(nMbrk+1)*12);
++               end
++			   end
++			   if(nMbrk>0)
++               md = checkfield(md,'fieldname','frontalforcings.monthlyvals_datebreaks','NaN',1,'Inf',1,'size',[nbas,nMbrk]);
++            elseif(numel(md.frontalforcings.monthlyvals_datebreaks)==0 || all(isnan(md.frontalforcings.monthlyvals_datebreaks)))
++               ;
++            else
++               error('md.frontalforcings.monthlyvals_numbreaks is 0 but md.frontalforcings.monthlyvals_datebreaks is not empty');
++            end
++		   end
+ 
+-		end % }}}
++      end % }}}
+ 		function disp(self) % {{{
+ 			disp(sprintf('   Frontalforcings parameters:'));
+ 			fielddisplay(self,'num_basins','number of different basins');
+@@ -106,13 +142,17 @@
+          fielddisplay(self,'arma_timestep','time resolution of the autoregressive model [yr]');
+          fielddisplay(self,'arlag_coefs','basin-specific vectors of AR lag coefficients [unitless]');
+          fielddisplay(self,'malag_coefs','basin-specific vectors of MA lag coefficients [unitless]');
+-         fielddisplay(self,'monthly_effects','basin-specific monthly values of TF added at corresponding month (default: all 0) [°C]');
++         fielddisplay(self,'monthlyvals_intercepts','intercept of basin-specific piecewise-linear monthly values of TF added at corresponding month (default: all 0) [°C]');
++         fielddisplay(self,'monthlyvals_trends','trends in basin-specific piecewise-linear monthly values of TF added at corresponding month (default: all 0) [°C/yr]');
++         fielddisplay(self,'monthlyvals_numbreaks','number of breakpoints in the piecewise-linear functions of monthly values');
++         fielddisplay(self,'monthlyvals_datebreaks','dates at which the breakpoints in the piecewise-linear monthly values occur (1 row per basin)');
+ 		end % }}}
+ 		function marshall(self,prefix,md,fid) % {{{
+ 			yts=md.constants.yts;
+-			nbas = md.frontalforcings.num_basins;
+-			nprm = md.frontalforcings.num_params;
+-			nper = md.frontalforcings.num_breaks+1;
++			%%% Deal with polynomial %%%
++			nbas  = md.frontalforcings.num_basins;
++			nprm  = md.frontalforcings.num_params;
++			nper  = md.frontalforcings.num_breaks+1;
+ 			% Scale the parameters %
+ 			polyparamsScaled   = md.frontalforcings.polynomialparams;
+ 			polyparams2dScaled = zeros(nbas,nper*nprm);
+@@ -149,11 +189,6 @@
+ 				% 2D array is already in correct format and no need for scaling %
+ 				polyparams2dScaled = polyparamsScaled;
+ 			end
+-			if(any(isnan(md.frontalforcings.monthly_effects))) %monthly effects not provided, set to 0
+-				meffects = zeros(md.frontalforcings.num_basins,12);
+-			else
+-				meffects = md.frontalforcings.monthly_effects;
+-			end
+ 			if(nper==1) %a single period (no break date)
+ 				dbreaks = zeros(nbas,1); %dummy
+ 			else
+@@ -160,6 +195,38 @@
+ 				dbreaks = md.frontalforcings.datebreaks;
+ 			end
+ 
++			%%% Deal with monthly effects %%%
++			nMper = md.frontalforcings.monthlyvals_numbreaks+1;
++			if((numel(md.frontalforcings.monthlyvals_intercepts)<=1 && isnan(md.frontalforcings.monthlyvals_intercepts)))
++				interceptsM = zeros(nbas,12); %monthly intercepts not provided, set to 0
++				trendsM     = zeros(nbas,12); %set monthly trends also to 0
++			else
++				interceptsM3d = md.frontalforcings.monthlyvals_intercepts;
++				if((numel(md.frontalforcings.monthlyvals_trends)<=1 && isnan(md.frontalforcings.monthlyvals_trends)))
++					trendsM3d = 0*interceptsM3d; %monthly trends not provided, set to 0
++				else
++					trendsM3d = md.frontalforcings.monthlyvals_trends;
++				end
++			end
++			% Create 2D arrays from 3D arrays if needed %
++			if(nMper>1 && (numel(md.frontalforcings.monthlyvals_intercepts)>1 || ~isnan(md.frontalforcings.monthlyvals_intercepts)))
++				interceptsM = zeros(nbas,12*nMper);
++				trendsM     = zeros(nbas,12*nMper);
++				for(ii=[1:nMper])
++					jj = 1+(ii-1)*12;
++					interceptsM(:,jj:jj+12-1) = interceptsM3d(:,:,ii);
++					trendsM(:,jj:jj+12-1)     = trendsM3d(:,:,ii);
++				end
++			elseif(nMper==1 && (numel(md.frontalforcings.monthlyvals_intercepts)>1 || ~isnan(md.frontalforcings.monthlyvals_intercepts))) 
++				interceptsM = interceptsM3d;
++				trendsM     = trendsM3d;
++			end
++			if(nMper==1) %a single period (no break date)
++				dMbreaks = zeros(nbas,1); %dummy
++			else
++				dMbreaks = md.frontalforcings.monthlyvals_datebreaks;
++			end
++
+ 			WriteData(fid,prefix,'name','md.frontalforcings.parameterization','data',3,'format','Integer');
+ 			WriteData(fid,prefix,'object',self,'class','frontalforcings','fieldname','num_basins','format','Integer');
+ 			WriteData(fid,prefix,'object',self,'class','frontalforcings','fieldname','num_breaks','format','Integer');
+@@ -173,7 +240,10 @@
+          WriteData(fid,prefix,'object',self,'class','frontalforcings','fieldname','arlag_coefs','format','DoubleMat','name','md.frontalforcings.arlag_coefs','yts',yts);
+          WriteData(fid,prefix,'object',self,'class','frontalforcings','fieldname','malag_coefs','format','DoubleMat','name','md.frontalforcings.malag_coefs','yts',yts);
+          WriteData(fid,prefix,'data',dbreaks,'name','md.frontalforcings.datebreaks','format','DoubleMat','scale',yts);
+-         WriteData(fid,prefix,'data',meffects,'name','md.frontalforcings.monthly_effects','format','DoubleMat');
++			WriteData(fid,prefix,'object',self,'class','frontalforcings','fieldname','monthlyvals_numbreaks','format','Integer');
++         WriteData(fid,prefix,'data',dMbreaks,'name','md.frontalforcings.monthlyvals_datebreaks','format','DoubleMat','scale',yts);
++         WriteData(fid,prefix,'data',interceptsM,'name','md.frontalforcings.monthlyvals_intercepts','format','DoubleMat');
++         WriteData(fid,prefix,'data',trendsM,'name','md.frontalforcings.monthlyvals_trends','format','DoubleMat','scale',1/yts);
+ 		end % }}}
+ 	end
+ end
+Index: ../trunk-jpl/src/m/classes/frontalforcingsrignotarma.py
+===================================================================
+--- ../trunk-jpl/src/m/classes/frontalforcingsrignotarma.py	(revision 27333)
++++ ../trunk-jpl/src/m/classes/frontalforcingsrignotarma.py	(revision 27334)
+@@ -24,7 +24,10 @@
+         self.arma_timestep = 0
+         self.arlag_coefs = np.nan
+         self.malag_coefs = np.nan
+-        self.monthly_effects = np.nan
++        self.monthlyvals_intercepts = np.nan
++        self.monthlyvals_trends = np.nan
++        self.monthlyvals_numbreaks = 0
++        self.monthlyvals_datebreaks = np.nan
+         self.basin_id = np.nan
+         self.subglacial_discharge = np.nan
+ 
+@@ -47,7 +50,6 @@
+         s += '{}\n'.format(fielddisplay(self, 'arma_timestep', 'time resolution of the ARMA model [yr]'))
+         s += '{}\n'.format(fielddisplay(self, 'arlag_coefs', 'basin-specific vectors of AR lag coefficients [unitless]'))
+         s += '{}\n'.format(fielddisplay(self, 'malag_coefs', 'basin-specific vectors of MA lag coefficients [unitless]'))
+-        s += '{}\n'.format(fielddisplay(self, 'monthly_effects', 'basin-specific monthly values of TF added at corresponding month (default: all 0) [°C]'))
+         return s
+     #}}}
+ 
+@@ -65,9 +67,10 @@
+         if not (solution == 'TransientSolution') or not md.transient.ismovingfront:
+             return md
+ 
+-        nbas = md.frontalforcings.num_basins;
+-        nprm = md.frontalforcings.num_params;
+-        nbrk = md.frontalforcings.num_breaks;
++        nbas  = md.frontalforcings.num_basins;
++        nprm  = md.frontalforcings.num_params;
++        nbrk  = md.frontalforcings.num_breaks;
++        nMbrk = md.frontalforcings.monthlyvals_numbreaks;
+         md = checkfield(md, 'fieldname', 'frontalforcings.num_basins', 'numel', 1, 'NaN', 1, 'Inf', 1, '>', 0)
+         md = checkfield(md, 'fieldname', 'frontalforcings.num_params', 'numel', 1, 'NaN', 1, 'Inf', 1, '>', 0)
+         md = checkfield(md, 'fieldname', 'frontalforcings.num_breaks', 'numel', 1, 'NaN', 1, 'Inf', 1, '>=', 0)
+@@ -94,10 +97,38 @@
+             pass
+         else:
+             raise RuntimeError('md.frontalforcings.num_breaks is 0 but md.frontalforcings.datebreaks is not empty')
+-        if(np.any(np.isnan(md.frontalforcings.monthly_effects)==False)):
+-            md = checkfield(md, 'fieldname', 'frontalforcings.monthly_effects', 'NaN', 1, 'Inf', 1, 'size', [md.frontalforcings.num_basins, 12])
+-            if(md.timestepping.time_step>=1):
+-                raise RuntimeError('md.frontalforcings.monthly_effects are provided but md.timestepping.time_step>=1')
++        
++
++        ### Check if some monthly forcings are provided ###
++        if(np.all(np.isnan(md.frontalforcings.monthlyvals_intercepts))==False or np.all(np.isnan(md.frontalforcings.monthlyvals_trends))==False or np.all(np.isnan(md.frontalforcings.monthlyvals_datebreaks))==False):
++            isMonthly = True
++        else:
++            isMonthly = False
++        if(np.all(np.isnan(md.frontalforcings.monthlyvals_datebreaks))):
++            isMonthlyTrend = True
++        else:
++            isMonthlyTrend = False
++        if(isMonthly):
++            md = checkfield(md, 'fieldname', 'frontalforcings.monthlyvals_numbreaks', 'numel', 1, 'NaN', 1, 'Inf', 1, '>=', 0)
++            if(nbas>1 and nMbrk>=1):
++                md = checkfield(md,'fieldname','frontalforcings.monthlyvals_intercepts','NaN',1,'Inf',1,'size',[nbas,12,nMbrk+1],'numel',nbas*(nMbrk+1)*12)
++                if(isMonthlyTrend):
++                    md = checkfield(md,'fieldname','frontalforcings.monthlyvals_trends','NaN',1,'Inf',1,'size',[nbas,12,nMbrk+1],'numel',nbas*(nMbrk+1)*12)
++            elif(nbas==1):
++               md = checkfield(md,'fieldname','frontalforcings.monthlyvals_intercepts','NaN',1,'Inf',1,'size',[nMbrk+1,12],'numel',nbas*(nMbrk+1)*12)
++               if(isMonthlyTrend):
++                  md = checkfield(md,'fieldname','frontalforcings.monthlyvals_trends','NaN',1,'Inf',1,'size',[nMbrk+1,12],'numel',nbas*(nMbrk+1)*12)
++            elif(nMbrk==0):
++               md = checkfield(md,'fieldname','frontalforcings.monthlyvals_intercepts','NaN',1,'Inf',1,'size',[nbas,12],'numel',nbas*(nMbrk+1)*12)
++               if(isMonthlyTrend):
++                  md = checkfield(md,'fieldname','frontalforcings.monthlyvals_trends','NaN',1,'Inf',1,'size',[nbas,12],'numel',nbas*(nMbrk+1)*12)
++        if(nMbrk>0):
++            md = checkfield(md, 'fieldname', 'frontalforcings.monthlyvals_datebreaks', 'NaN', 1, 'Inf', 1, 'size', [nbas,nMbrk])
++        elif(np.size(md.frontalforcings.monthlyvals_datebreaks)==0 or np.all(np.isnan(md.frontalforcings.monthlyvals_datebreaks))):
++            pass
++        else:
++            raise RuntimeError('md.frontalforcings.monthlyvals_numbreaks is 0 but md.frontalforcings.monthlyvals_datebreaks is not empty')
++
+         return md
+     # }}}
+ 
+@@ -138,15 +169,37 @@
+         else:
+             # 2D array is already in correct format and no need for scaling #
+             polyparams2dScaled = np.copy(polyparamsScaled)
+-        if(np.any(np.isnan(md.frontalforcings.monthly_effects))): #monthly effects not provided, set to 0
+-            meffects = np.zeros((md.frontalforcings.num_basins,12))
+-        else:
+-            meffects = 1*md.frontalforcings.monthly_effects
+         if(nper==1):
+             dbreaks = np.zeros((nbas,1))
+         else:
+             dbreaks = np.copy(md.frontalforcings.datebreaks)
+ 
++        ### Deal with montly effects ###
++        nMper = md.frontalforcings.monthlyvals_numbreaks+1
++        if(np.any(np.isnan(md.frontalforcings.monthlyvals_intercepts))):
++            interceptsM = np.zeros((nbas,12)) #monthly intercepts not provided, set to 0
++            trendsM     = np.zeros((nbas,12)) #set monthly trends also to 0
++        else:
++            interceptsM3d = md.frontalforcings.monthlyvals_intercepts
++            if(np.any(np.isnan(md.frontalforcings.monthlyvals_trends))):
++                trendsM3d = 0*interceptsM3d #monthly trends not provided, set to 0
++            else:
++                trendsM3d = md.frontalforcings.monthlyvals_trends
++        # Create 2D arrays from 3D arrays if needed #
++        if(nMper>1 and np.all(np.isnan(md.frontalforcings.monthlyvals_intercepts))==False):
++            interceptsM = np.zeros((nbas,12*nMper)) 
++            trendsM     = np.zeros((nbas,12*nMper))
++            for ii in range(nMper):
++                interceptsM[:,ii*12:(ii+1)*12] = 1*interceptsM3d[:,:,ii]
++                trendsM[:,ii*12:(ii+1)*12] = 1*trendsM3d[:,:,ii]
++        elif(nMper==1 and np.all(np.isnan(md.frontalforcings.monthlyvals_intercepts))==False):
++            interceptsM = 1*interceptsM3d
++            trendsM     = 1*trendsM3d
++        if(nMper==1):
++            dMbreaks = np.zeros((nbas,1))
++        else:
++            dMbreaks = np.copy(md.frontalforcings.monthlyvals_datebreaks)
++
+         WriteData(fid, prefix, 'name', 'md.frontalforcings.parameterization', 'data', 3, 'format', 'Integer')
+         WriteData(fid, prefix, 'object', self, 'class', 'frontalforcings', 'fieldname', 'num_basins', 'format', 'Integer')
+         WriteData(fid, prefix, 'object', self, 'class', 'frontalforcings', 'fieldname', 'num_breaks', 'format', 'Integer')
+@@ -160,5 +213,10 @@
+         WriteData(fid, prefix, 'object', self, 'class', 'frontalforcings', 'fieldname', 'arlag_coefs', 'format', 'DoubleMat', 'name', 'md.frontalforcings.arlag_coefs', 'yts', yts)
+         WriteData(fid, prefix, 'object', self, 'class', 'frontalforcings', 'fieldname', 'malag_coefs', 'format', 'DoubleMat', 'name', 'md.frontalforcings.malag_coefs', 'yts', yts)
+         WriteData(fid, prefix, 'data', dbreaks, 'name', 'md.frontalforcings.datebreaks', 'format', 'DoubleMat','scale',yts)
+-        WriteData(fid, prefix, 'data', meffects, 'name', 'md.frontalforcings.monthly_effects', 'format', 'DoubleMat')
++        WriteData(fid,prefix,'object',self,'class','frontalforcings','fieldname','monthlyvals_numbreaks','format','Integer')
++        WriteData(fid,prefix,'data',dMbreaks,'name','md.frontalforcings.monthlyvals_datebreaks','format','DoubleMat','scale',yts)
++        WriteData(fid,prefix,'data',interceptsM,'name','md.frontalforcings.monthlyvals_intercepts','format','DoubleMat')
++        WriteData(fid,prefix,'data',trendsM,'name','md.frontalforcings.monthlyvals_trends','format','DoubleMat','scale',1/yts)
+     # }}}
++
++
+Index: ../trunk-jpl/test/Archives/Archive543.arch
+===================================================================
+Cannot display: file marked as a binary type.
+svn:mime-type = application/octet-stream
+Index: ../trunk-jpl/test/NightlyRun/test543.m
+===================================================================
+--- ../trunk-jpl/test/NightlyRun/test543.m	(revision 27333)
++++ ../trunk-jpl/test/NightlyRun/test543.m	(revision 27334)
+@@ -4,8 +4,8 @@
+ md=parameterize(md,'../Par/Pig.par');
+ md=setflowequation(md,'SSA','all');
+ md.timestepping.start_time = 0;
+-md.timestepping.time_step  = 1;
+-md.timestepping.final_time = 10;
++md.timestepping.time_step  = 0.05;
++md.timestepping.final_time = 2;
+ 
+ %Basin separation TF
+ idb_tf  = zeros(md.mesh.numberofelements,1);
+@@ -51,22 +51,38 @@
+ intercept        = [2.5,2.0,0.1;0.5,0.5,1.5];
+ trendlin         = [-0.5,-0.2,0.1;0,0,0];
+ trendquad        = [0,0.0,0;0.1,0.1,0.1];
+-datebreaks       = [4,7;4,7];
++datebreaks       = [0.5,1.5;0.5,1.5];
+ polynomialparams = cat(numparams,intercept,trendlin,trendquad);
++% Monthly effects params %
++numbreaksM       = 1;
++intcpsMp0        = [-0.5,-0.5,0,0,0,0,0.5,0.5,0,0,0,0;
++                    -1.0,-1.0,0,0,0,0,1.0,1.0,0,0,0,0];
++intcpsMp1        = [-0.25,-0.25,0,0,0,0,0.,0.,0,0,0,0;
++                    -0.1,-0.1,0,0,0,0,0.1,0.1,0,0,0,0];
++intcpsM          = cat(3,intcpsMp0,intcpsMp1);
++trendsMp0        = [0,0,0,0,0,0,0.,0.0,0,0,0,0;
++                    0.0,0.0,0,-0.0,0,0,0.0,0.0,0,0,0,0];
++trendsMp1        = [0,-0.12,0,0,0,0,0.,0.0,0,0.0,0,0;
++                    0.0,-0.1,0,-0.0,0,0,0.0,0.0,0,0,0,0];
++trendsM          = cat(3,trendsMp0,trendsMp1);
++datebreaksM      = [1;1];
+ 
+-md.frontalforcings.num_basins           = nb_tf;
+-md.frontalforcings.basin_id             = idb_tf;
+-md.frontalforcings.num_params           = numparams; %number of parameters in the polynomial
+-md.frontalforcings.num_breaks           = numbreaks; %number of breakpoints
+-md.frontalforcings.subglacial_discharge = 0.01*ones(md.mesh.numberofvertices,1);
+-md.frontalforcings.polynomialparams     = polynomialparams;
+-md.frontalforcings.datebreaks           = datebreaks;
+-md.frontalforcings.ar_order             = 4;
+-md.frontalforcings.ma_order             = 2;
+-md.frontalforcings.arma_timestep        = 2; %timestep of the ARMA model [yr]
+-md.frontalforcings.arlag_coefs          = [[0.1,-0.1,0.01,-0.01];[0.2,-0.2,0.1,0.0]]; %autoregressive parameters
+-md.frontalforcings.malag_coefs          = [[0.1,0.0];[0.0,0.1]]; %moving-average parameters
+-
++md.frontalforcings.num_basins              = nb_tf;
++md.frontalforcings.basin_id                = idb_tf;
++md.frontalforcings.num_params              = numparams; %number of parameters in the polynomial
++md.frontalforcings.num_breaks              = numbreaks; %number of breakpoints
++md.frontalforcings.subglacial_discharge    = 0.01*ones(md.mesh.numberofvertices,1);
++md.frontalforcings.polynomialparams        = polynomialparams;
++md.frontalforcings.datebreaks              = datebreaks;
++md.frontalforcings.ar_order                = 4;
++md.frontalforcings.ma_order                = 2;
++md.frontalforcings.arma_timestep           = 2; %timestep of the ARMA model [yr]
++md.frontalforcings.arlag_coefs             = [[0.1,-0.1,0.01,-0.01];[0.2,-0.2,0.1,0.0]]; %autoregressive parameters
++md.frontalforcings.malag_coefs             = [[0.1,0.0];[0.0,0.1]]; %moving-average parameters
++md.frontalforcings.monthlyvals_numbreaks   = numbreaksM;
++md.frontalforcings.monthlyvals_intercepts  = intcpsM;
++md.frontalforcings.monthlyvals_trends      = trendsM;
++md.frontalforcings.monthlyvals_datebreaks  = datebreaksM;
+ % Floating Ice Melt parameters
+ md.basalforcings.floatingice_melting_rate = 0.1*ones(md.mesh.numberofvertices,1);
+ 
+@@ -101,7 +117,7 @@
+ field_tolerances={...
+    1e-11,2e-11,2e-11,1e-11,1e-9,1e-10,1e-10,1e-10,...
+    2e-11,1e-11,1e-11,9e-11,2e-9,1e-10,1e-10,1e-10,...
+-   2e-10,1e-10,1e-10,1e-10,5e-9,1e-10,1e-10,1e-10,...
++   2e-6,1e-6,1e-6,1e-6,5e-6,1e-6,1e-6,1e-6,...
+    };
+ field_values={...
+    (md.results.TransientSolution(1).Vx),...
+@@ -112,20 +128,20 @@
+    (md.results.TransientSolution(1).CalvingCalvingrate),...
+    (md.results.TransientSolution(1).CalvingMeltingrate),...
+    (md.results.TransientSolution(1).BasalforcingsFloatingiceMeltingRate),...
+-   (md.results.TransientSolution(5).Vx),...
+-   (md.results.TransientSolution(5).Vy),...
+-   (md.results.TransientSolution(5).Vel),...
+-   (md.results.TransientSolution(5).Thickness),...
+-   (md.results.TransientSolution(5).MaskIceLevelset),...
+-   (md.results.TransientSolution(5).CalvingCalvingrate),...
+-   (md.results.TransientSolution(5).CalvingMeltingrate),...
+-   (md.results.TransientSolution(5).BasalforcingsFloatingiceMeltingRate),...
+-	(md.results.TransientSolution(10).Vx),...
+-	(md.results.TransientSolution(10).Vy),...
+-	(md.results.TransientSolution(10).Vel),...
+-	(md.results.TransientSolution(10).Thickness),...
+-	(md.results.TransientSolution(10).MaskIceLevelset),...
+-	(md.results.TransientSolution(10).CalvingCalvingrate),...
+-	(md.results.TransientSolution(10).CalvingMeltingrate),...
+-	(md.results.TransientSolution(10).BasalforcingsFloatingiceMeltingRate),...
++   (md.results.TransientSolution(20).Vx),...
++   (md.results.TransientSolution(20).Vy),...
++   (md.results.TransientSolution(20).Vel),...
++   (md.results.TransientSolution(20).Thickness),...
++   (md.results.TransientSolution(20).MaskIceLevelset),...
++   (md.results.TransientSolution(20).CalvingCalvingrate),...
++   (md.results.TransientSolution(20).CalvingMeltingrate),...
++   (md.results.TransientSolution(20).BasalforcingsFloatingiceMeltingRate),...
++	(md.results.TransientSolution(40).Vx),...
++	(md.results.TransientSolution(40).Vy),...
++	(md.results.TransientSolution(40).Vel),...
++	(md.results.TransientSolution(40).Thickness),...
++	(md.results.TransientSolution(40).MaskIceLevelset),...
++	(md.results.TransientSolution(40).CalvingCalvingrate),...
++	(md.results.TransientSolution(40).CalvingMeltingrate),...
++	(md.results.TransientSolution(40).BasalforcingsFloatingiceMeltingRate),...
+ 	};
+Index: ../trunk-jpl/test/NightlyRun/test543.py
+===================================================================
+--- ../trunk-jpl/test/NightlyRun/test543.py	(revision 27333)
++++ ../trunk-jpl/test/NightlyRun/test543.py	(revision 27334)
+@@ -15,8 +15,8 @@
+ md = parameterize(md, '../Par/Pig.py')
+ md = setflowequation(md, 'SSA', 'all')
+ md.timestepping.start_time = 0
+-md.timestepping.time_step = 1
+-md.timestepping.final_time = 10
++md.timestepping.time_step = 0.05
++md.timestepping.final_time = 2
+ 
+ # Basin separation TF
+ idb_tf = np.zeros((md.mesh.numberofelements,))
+@@ -56,8 +56,21 @@
+ intercept        = np.array([[2.5,2.0,0.1],[0.5,0.5,1.5]])
+ trendlin         = np.array([[-0.5,-0.2,0.1],[0,0,0]])
+ trendquad        = np.array([[0,0.0,0],[0.1,0.1,0.1]])
+-datebreaks       = np.array([[4,7],[4,7]])
++datebreaks       = np.array([[0.5,1.5],[0.5,1.5]])
+ polynomialparams = np.transpose(np.stack((intercept,trendlin,trendquad)),(1,2,0))
++# Monthly effects params #
++numbreaksM       = 1;
++intcpsMp0        = np.array([[-0.5,-0.5,0,0,0,0,0.5,0.5,0,0,0,0],
++                    [-1.0,-1.0,0,0,0,0,1.0,1.0,0,0,0,0]])
++intcpsMp1        = np.array([[-0.25,-0.25,0,0,0,0,0.,0.,0,0,0,0],
++                    [-0.1,-0.1,0,0,0,0,0.1,0.1,0,0,0,0]])
++intcpsM          = np.transpose(np.stack((intcpsMp0,intcpsMp1)),(1,2,0)) 
++trendsMp0        = np.array([[0,0,0,0,0,0,0.,0.0,0,0,0,0],
++                    [0.0,0.0,0,-0.0,0,0,0.0,0.0,0,0,0,0]])
++trendsMp1        = np.array([[0,-0.12,0,0,0,0,0.,0.0,0,0.0,0,0],
++                    [0.0,-0.1,0,-0.0,0,0,0.0,0.0,0,0,0,0]])
++trendsM          = np.transpose(np.stack((trendsMp0,trendsMp1)),(1,2,0)) 
++datebreaksM      = np.array([[1],[1]]) 
+ 
+ md.frontalforcings.num_basins = nb_tf
+ md.frontalforcings.basin_id = idb_tf
+@@ -71,6 +84,10 @@
+ md.frontalforcings.arma_timestep = 2  # timestep of the ARMA model [yr]
+ md.frontalforcings.arlag_coefs = np.array([[0.1, -0.1, 0.01, -0.01], [0.2, -0.2, 0.1, 0.0]])  # autoregressive parameters
+ md.frontalforcings.malag_coefs = np.array([[0.1, 0.0], [0.0, 0.1]])  # moving-average parameters
++md.frontalforcings.monthlyvals_numbreaks   = numbreaksM
++md.frontalforcings.monthlyvals_intercepts  = intcpsM
++md.frontalforcings.monthlyvals_trends      = trendsM
++md.frontalforcings.monthlyvals_datebreaks  = datebreaksM
+ #Floating Ice Melt parameters
+ md.basalforcings.floatingice_melting_rate = 0.1 * np.ones((md.mesh.numberofvertices,))
+ 
+@@ -118,7 +135,7 @@
+ field_tolerances = [
+     1e-11, 2e-11, 2e-11, 1e-11, 1e-9, 1e-10, 1e-10, 1e-10,
+     2e-11, 1e-11, 1e-11, 9e-11, 2e-9, 1e-10, 1e-10, 1e-10,
+-    2e-10, 1e-10, 1e-10, 1e-10, 5e-9, 1e-10, 1e-10, 1e-10]
++    2e-6, 1e-6, 1e-6, 1e-6, 5e-6, 1e-6, 1e-6, 1e-6]
+ field_values = [
+     md.results.TransientSolution[0].Vx,
+     md.results.TransientSolution[0].Vy,
+@@ -128,19 +145,19 @@
+     md.results.TransientSolution[0].CalvingCalvingrate,
+     md.results.TransientSolution[0].CalvingMeltingrate,
+     md.results.TransientSolution[0].BasalforcingsFloatingiceMeltingRate,
+-    md.results.TransientSolution[4].Vx,
+-    md.results.TransientSolution[4].Vy,
+-    md.results.TransientSolution[4].Vel,
+-    md.results.TransientSolution[4].Thickness,
+-    md.results.TransientSolution[4].MaskIceLevelset,
+-    md.results.TransientSolution[4].CalvingCalvingrate,
+-    md.results.TransientSolution[4].CalvingMeltingrate,
+-    md.results.TransientSolution[4].BasalforcingsFloatingiceMeltingRate,
+-    md.results.TransientSolution[9].Vx,
+-    md.results.TransientSolution[9].Vy,
+-    md.results.TransientSolution[9].Vel,
+-    md.results.TransientSolution[9].Thickness,
+-    md.results.TransientSolution[9].MaskIceLevelset,
+-    md.results.TransientSolution[9].CalvingCalvingrate,
+-    md.results.TransientSolution[9].CalvingMeltingrate,
+-    md.results.TransientSolution[9].BasalforcingsFloatingiceMeltingRate]
++    md.results.TransientSolution[19].Vx,
++    md.results.TransientSolution[19].Vy,
++    md.results.TransientSolution[19].Vel,
++    md.results.TransientSolution[19].Thickness,
++    md.results.TransientSolution[19].MaskIceLevelset,
++    md.results.TransientSolution[19].CalvingCalvingrate,
++    md.results.TransientSolution[19].CalvingMeltingrate,
++    md.results.TransientSolution[19].BasalforcingsFloatingiceMeltingRate,
++    md.results.TransientSolution[39].Vx,
++    md.results.TransientSolution[39].Vy,
++    md.results.TransientSolution[39].Vel,
++    md.results.TransientSolution[39].Thickness,
++    md.results.TransientSolution[39].MaskIceLevelset,
++    md.results.TransientSolution[39].CalvingCalvingrate,
++    md.results.TransientSolution[39].CalvingMeltingrate,
++    md.results.TransientSolution[39].BasalforcingsFloatingiceMeltingRate]
+Index: ../trunk-jpl/src/c/classes/Elements/Element.cpp
+===================================================================
+--- ../trunk-jpl/src/c/classes/Elements/Element.cpp	(revision 27333)
++++ ../trunk-jpl/src/c/classes/Elements/Element.cpp	(revision 27334)
+@@ -2713,15 +2713,18 @@
+ 	this->AddInput(BasalforcingsFloatingiceMeltingRateEnum,values,P1Enum);
+ 
+ }/*}}}*/
+-void       Element::MonthlyEffectBasin(IssmDouble* monthlyeff, int enum_type){/*{{{*/
++void       Element::MonthlyPiecewiseLinearEffectBasin(int nummonthbreaks,IssmDouble* monthlyintercepts,IssmDouble* monthlytrends,IssmDouble* monthlydatebreaks,int enum_type){/*{{{*/
+ 	
+ 	/*Variable declaration*/
+    const int numvertices = this->GetNumberOfVertices();
+-	int basinid,mindex,basinenum_type,varenum_type;
++	int basinid,mindex,basinenum_type,varenum_type,indperiod;
++	int numperiods = nummonthbreaks+1;
+    IssmDouble time,fracyear,yts; 
+    IssmDouble monthsteps[12] = {0.,1./12,2./12,3./12,4./12,5./12,6./12,7./12,8./12,9./12,10./12,11./12};
+-	IssmDouble* monthlyeff_b = xNew<IssmDouble>(12);
+-   IssmDouble* varlist      = xNew<IssmDouble>(numvertices);
++   IssmDouble* datebreaks_b  = xNew<IssmDouble>(nummonthbreaks);
++	IssmDouble* intercepts_b  = xNew<IssmDouble>(nummonthbreaks*12);
++	IssmDouble* trends_b      = xNew<IssmDouble>(nummonthbreaks*12);
++	IssmDouble* varlist       = xNew<IssmDouble>(numvertices);
+ 
+ 	/*Get field-specific enums*/
+    switch(enum_type){
+@@ -2742,25 +2745,45 @@
+ 
+ 	/*Get basin-specific parameters of the element*/
+    this->GetInputValue(&basinid,basinenum_type);
+-	for(int ii=0;ii<12;ii++){
+-		monthlyeff_b[ii] = monthlyeff[basinid*12+ii];
++	if(nummonthbreaks>0){
++      for(int i=0;i<nummonthbreaks;i++) datebreaks_b[i] = monthlydatebreaks[basinid*nummonthbreaks+i];
++   }
++	for(int i=0;i<numperiods;i++){
++		intercepts_b[i]  = monthlyintercepts[basinid*12*numperiods+mindex+12*i];
++		trends_b[i]      = monthlytrends[basinid*12*numperiods+mindex+12*i];
+ 	}
+ 
++	/*Compute piecewise-linear function*/
++	IssmDouble telapsed_break,piecewiselin;
++	if(nummonthbreaks>0){
++		/*Find index of time compared to the breakpoints*/
++		indperiod = 0;
++		for(int i=0;i<nummonthbreaks;i++){
++			if(time>datebreaks_b[i]) indperiod = i+1;
++		}
++		/*Compute intercept+trend terms with parameters of indperiod*/
++      if(indperiod==0) telapsed_break = time;
++      else             telapsed_break = time-datebreaks_b[indperiod];
++      piecewiselin = intercepts_b[indperiod]+trends_b[indperiod]*telapsed_break;
++	}
++   else piecewiselin = intercepts_b[indperiod]+trends_b[indperiod]*time;
++
+ 	/*Retrieve values non-adjusted for monthly effects*/
+    this->GetInputListOnVertices(varlist,varenum_type);
+ 
+ 	/*Adjust values using monthly effects*/
+-	for(int v=0;v<numvertices;v++){
+-		varlist[v] = varlist[v]+monthlyeff_b[mindex];
+-	}
++	for(int v=0;v<numvertices;v++) varlist[v] = varlist[v]+piecewiselin;
+ 
+ 	/*Add input to element*/
+    this->AddInput(varenum_type,varlist,P1Enum);
+ 
+ 	/*Clean-up*/
+-   xDelete<IssmDouble>(monthlyeff_b);
++   xDelete<IssmDouble>(datebreaks_b);
++   xDelete<IssmDouble>(intercepts_b);
++   xDelete<IssmDouble>(trends_b);
+ 	xDelete<IssmDouble>(varlist);
+-}/*}}}*/
++}
++/*}}}*/
+ void       Element::BeckmannGoosseFloatingiceMeltingRate(){/*{{{*/
+ 
+ 	bool isthermalforcing;       
+Index: ../trunk-jpl/src/c/modules/FrontalForcingsx/FrontalForcingsx.cpp
+===================================================================
+--- ../trunk-jpl/src/c/modules/FrontalForcingsx/FrontalForcingsx.cpp	(revision 27333)
++++ ../trunk-jpl/src/c/modules/FrontalForcingsx/FrontalForcingsx.cpp	(revision 27334)
+@@ -49,23 +49,29 @@
+    /*Load parameters*/
+ 	bool isstochastic;
+    bool istfstochastic = false;
+-	int M,N,arorder,maorder,numbasins,numparams,numbreaks,my_rank;
++	int M,N,arorder,maorder,numbasins,numparams,numbreaks,nummonthbreaks,my_rank;
+    femmodel->parameters->FindParam(&numbasins,FrontalForcingsNumberofBasinsEnum);
+    femmodel->parameters->FindParam(&numparams,FrontalForcingsNumberofParamsEnum);
+    femmodel->parameters->FindParam(&numbreaks,FrontalForcingsNumberofBreaksEnum);
++   femmodel->parameters->FindParam(&nummonthbreaks,FrontalForcingsNumberofMonthBreaksEnum);
+    femmodel->parameters->FindParam(&arorder,FrontalForcingsARMAarOrderEnum);
+    femmodel->parameters->FindParam(&maorder,FrontalForcingsARMAmaOrderEnum);
+-   IssmDouble* datebreaks    = NULL;
+-   IssmDouble* arlagcoefs    = NULL;
+-   IssmDouble* malagcoefs    = NULL;
+-   IssmDouble* monthlyeff    = NULL;
+-	IssmDouble* polyparams    = NULL;
++   IssmDouble* datebreaks        = NULL;
++   IssmDouble* arlagcoefs        = NULL;
++   IssmDouble* malagcoefs        = NULL;
++   IssmDouble* monthlyeff        = NULL;
++	IssmDouble* polyparams        = NULL;
++	IssmDouble* monthdatebreaks   = NULL;
++	IssmDouble* monthintercepts   = NULL;
++	IssmDouble* monthtrends       = NULL;
+ 
+-   femmodel->parameters->FindParam(&datebreaks,&M,&N,FrontalForcingsARMAdatebreaksEnum); _assert_(M==numbasins); _assert_(N==max(numbreaks,1));        
+-   femmodel->parameters->FindParam(&polyparams,&M,&N,FrontalForcingsARMApolyparamsEnum); _assert_(M==numbasins); _assert_(N==(numbreaks+1)*numparams);        
+-   femmodel->parameters->FindParam(&arlagcoefs,&M,&N,FrontalForcingsARMAarlagcoefsEnum); _assert_(M==numbasins); _assert_(N==arorder);
+-   femmodel->parameters->FindParam(&malagcoefs,&M,&N,FrontalForcingsARMAmalagcoefsEnum); _assert_(M==numbasins); _assert_(N==maorder);
+-   femmodel->parameters->FindParam(&monthlyeff,&M,&N,ThermalForcingMonthlyEffectsEnum);  _assert_(M==numbasins); _assert_(N==12); 
++   femmodel->parameters->FindParam(&datebreaks,&M,&N,FrontalForcingsARMAdatebreaksEnum);            _assert_(M==numbasins); _assert_(N==max(numbreaks,1));        
++   femmodel->parameters->FindParam(&polyparams,&M,&N,FrontalForcingsARMApolyparamsEnum);            _assert_(M==numbasins); _assert_(N==(numbreaks+1)*numparams);        
++   femmodel->parameters->FindParam(&arlagcoefs,&M,&N,FrontalForcingsARMAarlagcoefsEnum);            _assert_(M==numbasins); _assert_(N==arorder);
++   femmodel->parameters->FindParam(&malagcoefs,&M,&N,FrontalForcingsARMAmalagcoefsEnum);            _assert_(M==numbasins); _assert_(N==maorder);
++   femmodel->parameters->FindParam(&monthdatebreaks,&M,&N,FrontalForcingsARMAmonthdatebreaksEnum);  _assert_(M==numbasins); _assert_(N==max(numbreaks,1));        
++   femmodel->parameters->FindParam(&monthintercepts,&M,&N,FrontalForcingsARMAmonthinterceptsEnum);  _assert_(M==numbasins); _assert_(N==12*(nummonthbreaks+1)); 
++   femmodel->parameters->FindParam(&monthtrends,&M,&N,FrontalForcingsARMAmonthtrendsEnum);          _assert_(M==numbasins); _assert_(N==12*(nummonthbreaks+1)); 
+ 
+ 	femmodel->parameters->FindParam(&isstochastic,StochasticForcingIsStochasticForcingEnum);
+ 	if(isstochastic){
+@@ -85,7 +91,7 @@
+ 		/*Compute ARMA*/
+       element->ArmaProcess(isstepforarma,arorder,maorder,numparams,numbreaks,tstep_arma,polyparams,arlagcoefs,malagcoefs,datebreaks,istfstochastic,FrontalForcingsRignotarmaEnum);
+ 		/*Compute monthly effects*/
+-		element->MonthlyEffectBasin(monthlyeff,FrontalForcingsRignotarmaEnum);
++		element->MonthlyPiecewiseLinearEffectBasin(nummonthbreaks,monthintercepts,monthtrends,monthdatebreaks,FrontalForcingsRignotarmaEnum);
+ 	}
+ 
+    /*Cleanup*/
Index: /issm/oecreview/Archive/27230-27343/ISSM-27334-27335.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27334-27335.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27334-27335.diff	(revision 27344)
@@ -0,0 +1,13 @@
+Index: ../trunk-jpl/src/c/modules/FrontalForcingsx/FrontalForcingsx.cpp
+===================================================================
+--- ../trunk-jpl/src/c/modules/FrontalForcingsx/FrontalForcingsx.cpp	(revision 27334)
++++ ../trunk-jpl/src/c/modules/FrontalForcingsx/FrontalForcingsx.cpp	(revision 27335)
+@@ -69,7 +69,7 @@
+    femmodel->parameters->FindParam(&polyparams,&M,&N,FrontalForcingsARMApolyparamsEnum);            _assert_(M==numbasins); _assert_(N==(numbreaks+1)*numparams);        
+    femmodel->parameters->FindParam(&arlagcoefs,&M,&N,FrontalForcingsARMAarlagcoefsEnum);            _assert_(M==numbasins); _assert_(N==arorder);
+    femmodel->parameters->FindParam(&malagcoefs,&M,&N,FrontalForcingsARMAmalagcoefsEnum);            _assert_(M==numbasins); _assert_(N==maorder);
+-   femmodel->parameters->FindParam(&monthdatebreaks,&M,&N,FrontalForcingsARMAmonthdatebreaksEnum);  _assert_(M==numbasins); _assert_(N==max(numbreaks,1));        
++   femmodel->parameters->FindParam(&monthdatebreaks,&M,&N,FrontalForcingsARMAmonthdatebreaksEnum);  _assert_(M==numbasins); _assert_(N==max(nummonthbreaks,1));        
+    femmodel->parameters->FindParam(&monthintercepts,&M,&N,FrontalForcingsARMAmonthinterceptsEnum);  _assert_(M==numbasins); _assert_(N==12*(nummonthbreaks+1)); 
+    femmodel->parameters->FindParam(&monthtrends,&M,&N,FrontalForcingsARMAmonthtrendsEnum);          _assert_(M==numbasins); _assert_(N==12*(nummonthbreaks+1)); 
+ 
Index: /issm/oecreview/Archive/27230-27343/ISSM-27335-27336.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27335-27336.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27335-27336.diff	(revision 27344)
@@ -0,0 +1,698 @@
+Index: ../trunk-jpl/etc/environment.sh
+===================================================================
+--- ../trunk-jpl/etc/environment.sh	(revision 27335)
++++ ../trunk-jpl/etc/environment.sh	(revision 27336)
+@@ -380,6 +380,7 @@
+ PETSC_ROOT="${ISSM_EXT_DIR}/petsc/install"
+ if [ -d "${PETSC_ROOT}" ]; then
+ 	export PETSC_ROOT # Used in installation of Gmsh
++	cpath_prepend "${PETSC_ROOT}/include"
+ 	library_path_prepend "${PETSC_ROOT}/lib"
+ 	ld_library_path_prepend "${PETSC_ROOT}/lib"
+ 
+@@ -518,6 +519,7 @@
+ 
+ SQLITE_ROOT="${ISSM_EXT_DIR}/sqlite/install"
+ if [ -d "${SQLITE_ROOT}" ]; then
++	export SQLITE_ROOT # Used in installation of GDAL
+ 	path_prepend "${SQLITE_ROOT}/bin"
+ 	cpath_prepend "${SQLITE_ROOT}/include"
+ 	library_path_prepend "${SQLITE_ROOT}/lib"
+Index: ../trunk-jpl/jenkins/eis-daskhub-python-nodules
+===================================================================
+--- ../trunk-jpl/jenkins/eis-daskhub-python-nodules	(nonexistent)
++++ ../trunk-jpl/jenkins/eis-daskhub-python-nodules	(revision 27336)
+@@ -0,0 +1,83 @@
++# NOTE: This configuration adds solid earth and Dakota capabilities to the 
++#		basic build.
++
++#--------------------#
++# ISSM Configuration #
++#--------------------#
++
++ISSM_CONFIG='\
++	--prefix="${ISSM_DIR}" \
++	--disable-static \
++	--enable-development \
++	--enable-debugging \
++	--with-numthreads=4 \
++	--with-python-dir="/srv/conda/envs/notebook" \
++	--with-python-version="3.9" \
++	--with-python-numpy-dir="/srv/conda/envs/notebook/lib/python3.9/site-packages/numpy/core/include/numpy" \
++	--with-fortran-lib="-L/usr/lib/x86_64-linux-gnu -lgfortran" \
++	--with-mpi-include="${ISSM_EXT_DIR}/petsc/install/include" \
++	--with-mpi-libflags="-L${ISSM_EXT_DIR}/petsc/install/lib -lmpi -lmpicxx -lmpifort" \
++	--with-blas-lapack-dir="${ISSM_EXT_DIR}/petsc/install" \
++	--with-metis-dir="${ISSM_EXT_DIR}/petsc/install" \
++	--with-parmetis-dir="${ISSM_EXT_DIR}/petsc/install" \
++	--with-scalapack-dir="${ISSM_EXT_DIR}/petsc/install" \
++	--with-mumps-dir="${ISSM_EXT_DIR}/petsc/install" \
++	--with-hdf5-dir="${ISSM_EXT_DIR}/petsc/install" \
++	--with-petsc-dir="${ISSM_EXT_DIR}/petsc/install" \
++	--with-gsl-dir="${ISSM_EXT_DIR}/gsl/install" \
++	--with-boost-dir="${ISSM_EXT_DIR}/boost/install" \
++	--with-dakota-dir="${ISSM_EXT_DIR}/dakota/install" \
++	--with-proj-dir="${ISSM_EXT_DIR}/proj/install" \
++	--with-triangle-dir="${ISSM_EXT_DIR}/triangle/install" \
++	--with-chaco-dir="${ISSM_EXT_DIR}/chaco/install" \
++	--with-m1qn3-dir="${ISSM_EXT_DIR}/m1qn3/install" \
++	--with-semic-dir="${ISSM_EXT_DIR}/semic/install" \
++'
++
++#-------------------#
++# External Packages #
++#-------------------#
++
++EXTERNALPACKAGES="
++	autotools	install-linux.sh
++	cmake		install.sh
++	petsc		install-3.16-linux.sh
++	gsl			install.sh
++	boost		install-1.7-linux.sh
++	dakota		install-6.2-linux.sh
++	curl		install-7-linux.sh
++	netcdf		install-4.7-parallel.sh
++	proj		install-6.sh
++	gdal		install-3-python.sh
++	gshhg		install.sh
++	gmt			install-6-linux.sh
++	gmsh		install-4-linux.sh
++	triangle	install-linux.sh
++	chaco		install.sh
++	m1qn3		install.sh
++	semic		install.sh
++"
++
++#---------#
++# Testing #
++#---------#
++
++# Test suites
++MATLAB_TEST=0
++PYTHON_TEST=0
++JAVASCRIPT_TEST=0
++EXAMPLES_TEST=0
++
++# Number of CPUs used in ISSM compilation
++#
++# NOTE: 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
++MATLAB_NROPTIONS=""
++PYTHON_NROPTIONS=""
+Index: ../trunk-jpl/jenkins/eis-smce-binaries
+===================================================================
+--- ../trunk-jpl/jenkins/eis-smce-binaries	(nonexistent)
++++ ../trunk-jpl/jenkins/eis-smce-binaries	(revision 27336)
+@@ -0,0 +1,82 @@
++# NOTE: This configuration adds solid earth and Dakota capabilities to the 
++#		basic build.
++
++#--------------------#
++# ISSM Configuration #
++#--------------------#
++
++ISSM_CONFIG='\
++	--prefix="${ISSM_DIR}" \
++	--disable-static \
++	--with-wrappers=no \
++	--enable-development \
++	--enable-debugging \
++	--with-numthreads=48 \
++	--with-fortran-lib="-L/usr/lib/gcc/x86_64-linux-gnu/9 -lgfortran" \
++	--with-mpi-include="/opt/intel/mpi/2021.4.0/include" \
++	--with-mpi-libflags="-L/opt/intel/mpi/2021.4.0/lib -lmpi -lmpicxx -lmpifort" \
++	--with-blas-lapack-dir="${ISSM_EXT_DIR}/petsc/install" \
++	--with-metis-dir="${ISSM_EXT_DIR}/petsc/install" \
++	--with-parmetis-dir="${ISSM_EXT_DIR}/petsc/install" \
++	--with-scalapack-dir="${ISSM_EXT_DIR}/petsc/install" \
++	--with-mumps-dir="${ISSM_EXT_DIR}/petsc/install" \
++	--with-hdf5-dir="${ISSM_EXT_DIR}/petsc/install" \
++	--with-petsc-dir="${ISSM_EXT_DIR}/petsc/install" \
++	--with-gsl-dir="${ISSM_EXT_DIR}/gsl/install" \
++	--with-boost-dir="${ISSM_EXT_DIR}/boost/install" \
++	--with-dakota-dir="${ISSM_EXT_DIR}/dakota/install" \
++	--with-proj-dir="${ISSM_EXT_DIR}/proj/install" \
++	--with-triangle-dir="${ISSM_EXT_DIR}/triangle/install" \
++	--with-chaco-dir="${ISSM_EXT_DIR}/chaco/install" \
++	--with-m1qn3-dir="${ISSM_EXT_DIR}/m1qn3/install" \
++	--with-semic-dir="${ISSM_EXT_DIR}/semic/install"
++'
++
++#-------------------#
++# External Packages #
++#-------------------#
++
++EXTERNALPACKAGES="
++	autotools	install-linux.sh
++	cmake		install.sh
++	petsc		install-3.12-linux.sh
++	gsl			install.sh
++	boost		install-1.7-linux.sh
++	dakota		install-6.2-linux.sh
++	curl		install-7-linux.sh
++	netcdf		install-4.7-parallel.sh
++	sqlite		install.sh
++	proj		install-6.sh
++	gdal		install-3-python.sh
++	gshhg		install.sh
++	gmt			install-6-linux.sh
++	gmsh		install-4.sh
++	triangle	install-linux.sh
++	chaco		install.sh
++	m1qn3		install.sh
++	semic		install.sh
++"
++
++#---------#
++# Testing #
++#---------#
++
++# Test suites
++MATLAB_TEST=0
++PYTHON_TEST=0
++JAVASCRIPT_TEST=0
++EXAMPLES_TEST=0
++
++# Number of CPUs used in ISSM compilation
++#
++# NOTE: 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
++MATLAB_NROPTIONS=""
++PYTHON_NROPTIONS=""
+Index: ../trunk-jpl/src/m/classes/clusters/smce_eis.py
+===================================================================
+--- ../trunk-jpl/src/m/classes/clusters/smce_eis.py	(revision 27335)
++++ ../trunk-jpl/src/m/classes/clusters/smce_eis.py	(nonexistent)
+@@ -1,216 +0,0 @@
+-import os
+-import shutil
+-import subprocess
+-
+-try:
+-    from smce_eis_settings import smce_eis_settings
+-except ImportError:
+-    print('You need smce_eis_settings.py to proceed, check presence and sys.path')
+-from fielddisplay import fielddisplay
+-from helpers import *
+-from IssmConfig import IssmConfig
+-from issmssh import issmssh
+-from MatlabFuncs import *
+-from pairoptions import pairoptions
+-
+-class smce_eis(object):
+-    """SMCE_EIS cluster class definition
+-
+-    Usage:
+-        cluster = smce_eis()
+-        cluster = smce_eis('np', 3)
+-        cluster = smce_eis('np', 3, 'login', 'username')
+-    """
+-
+-    def __init__(self, *args):  # {{{
+-        self.name = '52.54.75.45'
+-        self.login = 'jdquinn1'
+-        self.idfile = '~/.ssh/smce-aws-eis-pilot'
+-        self.modules = []
+-        self.numnodes = 8
+-        self.cpuspernode = 1
+-        self.port = 0
+-        self.time = 12 * 60 * 60
+-        self.processor = 'skylake'
+-        self.srcpath = '/shared/issm/issm/trunk-jpl'
+-        self.codepath = '/shared/issm/issm/trunk-jpl/bin'
+-        self.executionpath = '/home/jdquinn1/issm-exec'
+-        self.interactive = 0
+-        self.numstreams = 1
+-        self.hyperthreading = 0
+-        self.email = ''
+-
+-        # Use provided options to change fields
+-        options = pairoptions(*args)
+-
+-        # Initialize cluster using user settings if provided
+-        try:
+-            self = smce_eis_settings(self)
+-        except NameError:
+-            print('smce_eis_settings.py not found, using default settings')
+-
+-        # OK get other fields
+-        self = options.AssignObjectFields(self)
+-    # }}}
+-
+-    def __repr__(self):  # {{{
+-        # Display the object
+-        s = 'class smce_eis object\n'
+-        s += '    name: {}\n'.format(self.name)
+-        s += '    login: {}\n'.format(self.login)
+-        s += '    idfile: {}\n'.format(self.idfile)
+-        s += '    modules: {}\n'.format(strjoin(self.modules, ', '))
+-        s += '    numnodes: {}\n'.format(self.numnodes)
+-        s += '    cpuspernode: {}\n'.format(self.cpuspernode)
+-        s += '    np: {}\n'.format(self.nprocs())
+-        s += '    port: {}\n'.format(self.port)
+-        s += '    time: {}\n'.format(self.time)
+-        s += '    processor: {}\n'.format(self.processor)
+-        s += '    srcpath: {}\n'.format(self.srcpath)
+-        s += '    codepath: {}\n'.format(self.codepath)
+-        s += '    executionpath: {}\n'.format(self.executionpath)
+-        s += '    interactive: {}\n'.format(self.interactive)
+-        s += '    numstreams: {}\n'.format(self.numstreams)
+-        s += '    hyperthreading: {}\n'.format(self.hyperthreading)
+-        return s
+-    # }}}
+-
+-    def nprocs(self):  # {{{
+-        return self.numnodes * self.cpuspernode
+-    # }}}
+-
+-    def checkconsistency(self, md, solution, analyses):  # {{{
+-        # Now, check cluster.cpuspernode according to processor type
+-        if self.processor == 'skylake':
+-            if self.cpuspernode > 14 or self.cpuspernode < 1:
+-                md = md.checkmessage('cpuspernode should be between 1 and 14 for \'skyw\' processors in hyperthreading mode')
+-        else:
+-            md = md.checkmessage('unknown processor type, should be \'skylake\'')
+-
+-        # Miscellaneous
+-        if not self.login:
+-            md = md.checkmessage('login empty')
+-        if self.port:
+-            md = md.checkmessage('port must be set to 0 as we do not have an SSH tunnel')
+-        if not self.codepath:
+-            md = md.checkmessage('codepath empty')
+-        if not self.executionpath:
+-            md = md.checkmessage('executionpath empty')
+-
+-        return self
+-    # }}}
+-
+-    def BuildQueueScript(self, dirname, modelname, solution, io_gather, isvalgrind, isgprof, isdakota, isoceancoupling):  # {{{
+-        if isgprof:
+-            print('gprof not supported by cluster, ignoring...')
+-
+-        executable = 'issm.exe'
+-        if isdakota:
+-            version = IssmConfig('_DAKOTA_VERSION_')[0:2]
+-            version = float(str(version[0]))
+-            if version >= 6:
+-                executable = 'issm_dakota.exe'
+-        if isoceancoupling:
+-            executable = 'issm_ocean.exe'
+-
+-        # Write queuing script
+-        fid = open(modelname + '.queue', 'w')
+-
+-        fid.write('#!/bin/bash\n')
+-        fid.write('#SBATCH --partition=hpc-spot \n')
+-        fid.write('#SBATCH -J {} \n'.format(modelname))
+-        fid.write('#SBATCH -o {}.outlog \n'.format(modelname))
+-        fid.write('#SBATCH -e {}.errlog \n'.format(modelname))
+-        fid.write('#SBATCH --nodes={} \n'.format(self.numnodes))
+-        fid.write('#SBATCH --ntasks-per-node={} \n'.format(self.cpuspernode))
+-        fid.write('#SBATCH --cpus-per-task={} \n'.format(self.numstreams))
+-        fid.write('#SBATCH -t {:02d}:{:02d}:00 \n'.format(int(floor(self.time / 3600)), int(floor(self.time % 3600) / 60)))
+-        if (self.email.find('@')>-1):
+-            fid.write('#SBATCH --mail-user={} \n'.format(self.email))
+-            fid.write('#SBATCH --mail-type=BEGIN,END,FAIL \n\n')
+-        # for i in range(len(self.modules)):
+-        #     fid.write('module load {}\n'.format(self.modules[i]))
+-        fid.write('export MPI_GROUP_MAX=64\n\n')
+-        fid.write('export MPI_UNBUFFERED_STDIO=true\n\n')
+-        fid.write('export PATH="$PATH:/opt/slurm/bin"\n') # TODO: Figure out how to add this to PATH by sourcing environment script
+-        fid.write('export PATH="$PATH:."\n\n')
+-        fid.write('export ISSM_DIR="{}"\n'.format(self.srcpath)) # FIXME
+-        fid.write('export HYDRA_HOST_FILE={}/{}/'.format(self.executionpath, dirname))
+-        fid.write('${USER}-hydranodes-sj:${SLURM_JOB_ID}\n')
+-        #fid.write('source /usr/share/modules/init/bash\n')
+-        #fid.write('source /efs/spack-justin/share/spack/setup-env.sh\n')
+-        #fid.write('module load gcc-9.3.0-gcc-9.3.0-ug2hqa3\n')
+-        fid.write('touch ${HYDRA_HOST_FILE}\n')
+-        fid.write('/efs/mrilee/snodelist/build/snodelist -m -f "%h%[:]c" >> ${HYDRA_HOST_FILE}\n')
+-        fid.write('source $ISSM_DIR/etc/environment.sh\n') # FIXME
+-        fid.write('cd {}/{}/\n\n'.format(self.executionpath, dirname))
+-
+-        fid.write('mpiexec -np {} {}/{} {} {}/{} {}\n'.format(self.nprocs(), self.codepath, executable, solution, self.executionpath, dirname, modelname))
+-
+-        if not io_gather: # concatenate the output files
+-            fid.write('cat {}.outbin.* > {}.outbin'.format(modelname, modelname))
+-        fid.close()
+-
+-        # In interactive mode, create a run file, and errlog and outlog file
+-        if self.interactive:
+-            fid = open(modelname + '.run', 'w')
+-            if not isvalgrind:
+-                fid.write('mpiexec -np {} {}/{} {} {}/{} {}\n'.format(self.nprocs(), self.codepath, executable, solution, self.executionpath, dirname, modelname))
+-            else:
+-                fid.write('mpiexec -np {} valgrind --leak-check=full {}/{} {} {}/{} {}\n'.format(self.nprocs(), self.codepath, executable, solution, self.executionpath, dirname, modelname))
+-            if not io_gather: # concatenate the output files
+-                fid.write('cat {}.outbin.* > {}.outbin'.format(modelname, modelname))
+-            fid.close()
+-            fid = open(modelname + '.errlog', 'w') # TODO: Change this to system call (touch <file>)?
+-            fid.close()
+-            fid = open(modelname + '.outlog', 'w') # TODO: Change this to system call (touch <file>)?
+-            fid.close()
+-    # }}}
+-
+-    def UploadQueueJob(self, modelname, dirname, filelist):  # {{{
+-        # Compress the files into one zip
+-        compressstring = 'tar -zcf {}.tar.gz'.format(dirname)
+-        for file in filelist:
+-            compressstring += ' {}'.format(file)
+-        if self.interactive:
+-            compressstring += ' {}.run {}.errlog {}.outlog'.format(modelname, modelname, modelname)
+-        subprocess.call(compressstring, shell=True)
+-
+-        print('uploading input file and queuing script')
+-        if self.interactive:
+-            directory = '{}/Interactive{}'.format(self.executionpath, self.interactive)
+-        else:
+-            directory = self.executionpath
+-
+-        # NOTE: Replacement for issmscpout(self.name, directory, self.login, self.port, ['{}.tar.gz'.format(dirname)])
+-        copystring = 'cp {}.tar.gz /efs/issm-tmp/'.format(dirname, dirname)
+-        subprocess.call(copystring, shell=True)
+-    # }}}
+-
+-    def LaunchQueueJob(self, modelname, dirname, filelist, restart, batch):  # {{{
+-        if self.interactive:
+-            if not isempty(restart):
+-                launchcommand = 'cd {}/Interactive{}'.format(self.executionpath, self.interactive)
+-            else:
+-                launchcommand = 'cd {}/Interactive{} && tar -zxf {}.tar.gz'.format(self.executionpath, self.interactive, dirname)
+-        else:
+-            if not isempty(restart):
+-                launchcommand = 'cd {} && cd {} && /opt/slurm/bin/sbatch {}.queue'.format(self.executionpath, dirname, modelname)
+-            else:
+-                launchcommand = 'cd {} && rm -rf ./{} && mkdir {} && cd {} && cp /efs/issm-tmp/{}.tar.gz ./ && tar -zxf {}.tar.gz && /opt/slurm/bin/sbatch {}.queue'.format(self.executionpath, dirname, dirname, dirname, dirname, dirname, modelname)
+-
+-        print('launching solution sequence on remote cluster')
+-
+-        # NOTE: Replacement for issmssh(self.name, self.login, self.port, launchcommand)
+-        subprocess.call('ssh -l {} -i {} {} "{}"'.format(self.login, self.idfile, self.name, launchcommand), shell=True)
+-    # }}}
+-
+-    def Download(self, dirname, filelist):  # {{{
+-        # Copy files from cluster to current directory
+-    
+-        # NOTE: Replacement for issmscpin(self.name, self.login, self.port, directory, filelist)
+-        directory = '{}/{}/'.format(self.executionpath, dirname)
+-        fileliststr = "'{" + ','.join([str(x) for x in filelist]) + "}'"
+-        downloadcommand = 'scp -T -i {} {}@{}:{} {}/.'.format(self.idfile, self.login, self.name, os.path.join(directory, fileliststr), os.getcwd())
+-        subprocess.call(downloadcommand, shell=True) 
+-    # }}}
+Index: ../trunk-jpl/src/m/classes/clusters/eis_nasa_smce.py
+===================================================================
+--- ../trunk-jpl/src/m/classes/clusters/eis_nasa_smce.py	(nonexistent)
++++ ../trunk-jpl/src/m/classes/clusters/eis_nasa_smce.py	(revision 27336)
+@@ -0,0 +1,217 @@
++import os
++import shutil
++import subprocess
++
++try:
++    from eis_nasa_smce_settings import eis_nasa_smce_settings
++except ImportError:
++    print('You need eis_nasa_smce_settings.py to proceed, check presence and sys.path')
++from fielddisplay import fielddisplay
++from helpers import *
++from IssmConfig import IssmConfig
++from issmssh import issmssh
++from MatlabFuncs import *
++from pairoptions import pairoptions
++
++class eis_nasa_smce(object):
++    """EIS_NASA_SMCE cluster class definition
++
++    Usage:
++        cluster = eis_nasa_smce()
++        cluster = eis_nasa_smce('np', 3)
++        cluster = eis_nasa_scme('np', 3, 'login', 'username')
++    """
++
++    def __init__(self, *args):  # {{{
++        self.name = '52.10.233.96'
++        self.login = 'jdquinn1'
++        self.idfile = '~/.ssh/eis-nasa-smce'
++        self.modules = ['intelmpi']
++        self.numnodes = 4
++        self.cpuspernode = 1
++        self.port = 0
++        self.time = 12 * 60 * 60
++        self.processor = 'skylake'
++        self.partition = 'sealevel-c5xl-spot'
++        self.srcpath = '/efs/issm-new/binaries/repos/trunk-jpl-working'
++        self.extpkgpath = '/efs/issm-new/binaries/ext'
++        self.codepath = '/efs/issm-new/binaries/repos/trunk-jpl-working/bin'
++        self.executionpath = '~/issm-exec'
++        self.interactive = 0
++        self.numstreams = 1
++        self.hyperthreading = 0
++        self.email = ''
++
++        # Use provided options to change fields
++        options = pairoptions(*args)
++
++        # Initialize cluster using user settings if provided
++        try:
++            self = eis_nasa_smce_settings(self)
++        except NameError:
++            print('eis_nasa_smce_settings.py not found, using default settings')
++
++        # OK get other fields
++        self = options.AssignObjectFields(self)
++    # }}}
++
++    def __repr__(self):  # {{{
++        # Display the object
++        s = 'class eis_nasa_smce object\n'
++        s += '    name: {}\n'.format(self.name)
++        s += '    login: {}\n'.format(self.login)
++        s += '    idfile: {}\n'.format(self.idfile)
++        s += '    modules: {}\n'.format(strjoin(self.modules, ', '))
++        s += '    numnodes: {}\n'.format(self.numnodes)
++        s += '    cpuspernode: {}\n'.format(self.cpuspernode)
++        s += '    np: {}\n'.format(self.nprocs())
++        s += '    port: {}\n'.format(self.port)
++        s += '    time: {}\n'.format(self.time)
++        s += '    processor: {}\n'.format(self.processor)
++        s += '    partition: {}\n'.format(self.partition)
++        s += '    srcpath: {}\n'.format(self.srcpath)
++        s += '    extpkgpath: {}\n'.format(self.extpkgpath)
++        s += '    codepath: {}\n'.format(self.codepath)
++        s += '    executionpath: {}\n'.format(self.executionpath)
++        s += '    interactive: {}\n'.format(self.interactive)
++        s += '    numstreams: {}\n'.format(self.numstreams)
++        s += '    hyperthreading: {}\n'.format(self.hyperthreading)
++        return s
++    # }}}
++
++    def nprocs(self):  # {{{
++        return self.numnodes * self.cpuspernode
++    # }}}
++
++    def checkconsistency(self, md, solution, analyses):  # {{{
++        # Now, check cluster.cpuspernode according to processor type
++        if self.processor == 'skylake':
++            if self.cpuspernode > 14 or self.cpuspernode < 1:
++                md = md.checkmessage('cpuspernode should be between 1 and 14 for \'skyw\' processors in hyperthreading mode')
++        else:
++            md = md.checkmessage('unknown processor type, should be \'skylake\'')
++
++        # Miscellaneous
++        if not self.login:
++            md = md.checkmessage('login empty')
++        if self.port:
++            md = md.checkmessage('port must be set to 0 as we do not have an SSH tunnel')
++        if not self.codepath:
++            md = md.checkmessage('codepath empty')
++        if not self.executionpath:
++            md = md.checkmessage('executionpath empty')
++
++        return self
++    # }}}
++
++    def BuildQueueScript(self, dirname, modelname, solution, io_gather, isvalgrind, isgprof, isdakota, isoceancoupling):  # {{{
++        if isgprof:
++            print('gprof not supported by cluster, ignoring...')
++
++        issmexec = 'issm.exe'
++        mpiexec = 'mpiexec' # Set to alternative mpiexec if desired
++
++        if isdakota:
++            version = IssmConfig('_DAKOTA_VERSION_')[0:2]
++            version = float(str(version[0]))
++            if version >= 6:
++                issmexec = 'issm_dakota.exe'
++        if isoceancoupling:
++            issmexec = 'issm_ocean.exe'
++
++        # Write queuing script
++        fid = open(modelname + '.queue', 'w')
++
++        fid.write('#!/bin/bash\n')
++        fid.write('#SBATCH --partition={} \n'.format(self.partition))
++        fid.write('#SBATCH -J {} \n'.format(modelname))
++        fid.write('#SBATCH -o {}.outlog \n'.format(modelname))
++        fid.write('#SBATCH -e {}.errlog \n'.format(modelname))
++        fid.write('#SBATCH --nodes={} \n'.format(self.numnodes))
++        fid.write('#SBATCH --ntasks-per-node={} \n'.format(self.cpuspernode))
++        fid.write('#SBATCH --cpus-per-task={} \n'.format(self.numstreams))
++        fid.write('#SBATCH -t {:02d}:{:02d}:00 \n'.format(int(floor(self.time / 3600)), int(floor(self.time % 3600) / 60)))
++        if (self.email.find('@')>-1):
++            fid.write('#SBATCH --mail-user={} \n'.format(self.email))
++            fid.write('#SBATCH --mail-type=BEGIN,END,FAIL \n\n')
++        fid.write('source /etc/profile\n')
++        fid.write('source /shared/spack/share/spack/setup-env.sh\n')
++        for i in range(len(self.modules)):
++             fid.write('module load {} &> /dev/null\n'.format(self.modules[i]))
++        fid.write('export MPI_GROUP_MAX=64\n\n')
++        fid.write('export MPI_UNBUFFERED_STDIO=true\n\n')
++        fid.write('export PATH="$PATH:/opt/slurm/bin"\n')
++        fid.write('export PATH="$PATH:."\n\n')
++        fid.write('export ISSM_DIR="{}"\n'.format(self.srcpath))
++        fid.write('export ISSM_EXT_DIR="{}"\n'.format(self.extpkgpath))
++        fid.write('source $ISSM_DIR/etc/environment.sh\n')
++        fid.write('cd {}/{}/\n\n'.format(self.executionpath, dirname))
++        fid.write('{} -n {} {}/{} {} {}/{} {}\n'.format(mpiexec, self.nprocs(), self.codepath, issmexec, solution, self.executionpath, dirname, modelname))
++
++        if not io_gather: # concatenate the output files
++            fid.write('cat {}.outbin.* > {}.outbin'.format(modelname, modelname))
++        fid.close()
++
++        # In interactive mode, create a run file, and errlog and outlog file
++        if self.interactive:
++            fid = open(modelname + '.run', 'w')
++            if not isvalgrind:
++                fid.write('{} -np {} {}/{} {} {}/{} {}\n'.format(mpiexec, self.nprocs(), self.codepath, issmexec, solution, self.executionpath, dirname, modelname))
++            else:
++                fid.write('{} -np {} valgrind --leak-check=full {}/{} {} {}/{} {}\n'.format(mpiexec, self.nprocs(), self.codepath, issmexec, solution, self.executionpath, dirname, modelname))
++            if not io_gather: # concatenate the output files
++                fid.write('cat {}.outbin.* > {}.outbin'.format(modelname, modelname))
++            fid.close()
++            fid = open(modelname + '.errlog', 'w') # TODO: Change this to system call (touch <file>)?
++            fid.close()
++            fid = open(modelname + '.outlog', 'w') # TODO: Change this to system call (touch <file>)?
++            fid.close()
++    # }}}
++
++    def UploadQueueJob(self, modelname, dirname, filelist):  # {{{
++        # Compress the files into one zip
++        compressstring = 'tar -zcf {}.tar.gz'.format(dirname)
++        for file in filelist:
++            compressstring += ' {}'.format(file)
++        if self.interactive:
++            compressstring += ' {}.run {}.errlog {}.outlog'.format(modelname, modelname, modelname)
++        subprocess.call(compressstring, shell=True)
++
++        print('uploading input file and queueing script')
++        if self.interactive:
++            directory = '{}/Interactive{}'.format(self.executionpath, self.interactive)
++        else:
++            directory = self.executionpath
++
++        # NOTE: Replacement for issmscpout(self.name, directory, self.login, self.port, ['{}.tar.gz'.format(dirname)])
++        copystring = 'cp {}.tar.gz /efs/issm/tmp'.format(dirname)
++        subprocess.call(copystring, shell=True)
++    # }}}
++
++    def LaunchQueueJob(self, modelname, dirname, filelist, restart, batch):  # {{{
++        if self.interactive:
++            if not isempty(restart):
++                launchcommand = 'cd {}/Interactive{}'.format(self.executionpath, self.interactive)
++            else:
++                launchcommand = 'cd {}/Interactive{} && tar -zxf {}.tar.gz'.format(self.executionpath, self.interactive, dirname)
++        else:
++            if not isempty(restart):
++                launchcommand = 'cd {} && cd {} && sbatch {}.queue'.format(self.executionpath, dirname, modelname)
++            else:
++                launchcommand = 'cd {} && rm -rf {} && mkdir {} && cd {} && cp /efs/issm/tmp/{}.tar.gz . && tar -zxf {}.tar.gz && /opt/slurm/bin/sbatch {}.queue'.format(self.executionpath, dirname, dirname, dirname, dirname, dirname, modelname)
++
++        print('launching solution sequence on remote cluster')
++
++        # NOTE: Replacement for issmssh(self.name, self.login, self.port, launchcommand)
++        subprocess.call('ssh -l {} -i {} {} "{}"'.format(self.login, self.idfile, self.name, launchcommand), shell=True)
++    # }}}
++
++    def Download(self, dirname, filelist):  # {{{
++        # Copy files from cluster to current directory
++    
++        # NOTE: Replacement for issmscpin(self.name, self.login, self.port, directory, filelist)
++        directory = '{}/{}/'.format(self.executionpath, dirname)
++        fileliststr = '{' + ','.join([str(x) for x in filelist]) + '}'
++        downloadcommand = 'scp -i {} {}@{}:{} {}/.'.format(self.idfile, self.login, self.name, os.path.join(directory, fileliststr), os.getcwd())
++        subprocess.call(downloadcommand, shell=True) 
++    # }}}
+Index: ../trunk-jpl/test/NightlyRun/test101eisnasasmce.py
+===================================================================
+--- ../trunk-jpl/test/NightlyRun/test101eisnasasmce.py	(nonexistent)
++++ ../trunk-jpl/test/NightlyRun/test101eisnasasmce.py	(revision 27336)
+@@ -0,0 +1,55 @@
++#Test Name: SquareShelfConstrainedStressSSA2d
++from model import *
++from socket import gethostname
++from triangle import triangle
++from setmask import setmask
++from parameterize import parameterize
++from setflowequation import setflowequation
++from solve import solve
++from massfluxatgate import massfluxatgate
++from generic import generic
++from eis_nasa_smce import eis_nasa_smce
++
++md = triangle(model(), '../Exp/Square.exp', 50000)
++md = setmask(md, 'all', '')
++md = parameterize(md, '../Par/SquareShelfConstrained.py')
++md = setflowequation(md, 'SSA', 'all')
++md.cluster = generic('name', gethostname(), 'np', 2)
++
++if True:
++    cluster = eis_nasa_smce()
++    cluster.partition = 'sealevel-c5xl-spot'
++    md.cluster = cluster
++
++#outputs
++md.stressbalance.requested_outputs = ['default', 'DeviatoricStressxx', 'DeviatoricStressyy', 'DeviatoricStressxy', 'MassFlux1', 'MassFlux2', 'MassFlux3', 'MassFlux4', 'MassFlux5', 'MassFlux6']
++md.outputdefinition.definitions = [massfluxatgate('name', 'MassFlux1', 'profilename', '../Exp/MassFlux1.exp', 'definitionstring', 'Outputdefinition1'),
++                                   massfluxatgate('name', 'MassFlux2', 'profilename', '../Exp/MassFlux2.exp', 'definitionstring', 'Outputdefinition2'),
++                                   massfluxatgate('name', 'MassFlux3', 'profilename', '../Exp/MassFlux3.exp', 'definitionstring', 'Outputdefinition3'),
++                                   massfluxatgate('name', 'MassFlux4', 'profilename', '../Exp/MassFlux4.exp', 'definitionstring', 'Outputdefinition4'),
++                                   massfluxatgate('name', 'MassFlux5', 'profilename', '../Exp/MassFlux5.exp', 'definitionstring', 'Outputdefinition5'),
++                                   massfluxatgate('name', 'MassFlux6', 'profilename', '../Exp/MassFlux6.exp', 'definitionstring', 'Outputdefinition6')]
++
++md = solve(md, 'Stressbalance')
++
++#Fields and tolerances to track changes
++field_names = ['Vx', 'Vy', 'Vel', 'Pressure',
++               'DeviatoricStressxx', 'DeviatoricStressyy', 'DeviatoricStressxy',
++               'MassFlux1', 'MassFlux2', 'MassFlux3', 'MassFlux4', 'MassFlux5', 'MassFlux6']
++field_tolerances = [3e-13, 1e-13, 1e-13, 1e-13,
++                    2e-13, 1e-13, 2e-13,
++                    1e-13, 1e-13, 1e-13,
++                    1e-13, 1e-13, 1e-13]
++field_values = [md.results.StressbalanceSolution.Vx,
++                md.results.StressbalanceSolution.Vy,
++                md.results.StressbalanceSolution.Vel,
++                md.results.StressbalanceSolution.Pressure,
++                md.results.StressbalanceSolution.DeviatoricStressxx,
++                md.results.StressbalanceSolution.DeviatoricStressyy,
++                md.results.StressbalanceSolution.DeviatoricStressxy,
++                md.results.StressbalanceSolution.MassFlux1,
++                md.results.StressbalanceSolution.MassFlux2,
++                md.results.StressbalanceSolution.MassFlux3,
++                md.results.StressbalanceSolution.MassFlux4,
++                md.results.StressbalanceSolution.MassFlux5,
++                md.results.StressbalanceSolution.MassFlux6]
Index: /issm/oecreview/Archive/27230-27343/ISSM-27336-27337.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27336-27337.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27336-27337.diff	(revision 27344)
@@ -0,0 +1,97 @@
+Index: ../trunk-jpl/test/NightlyRun/runme.py
+===================================================================
+--- ../trunk-jpl/test/NightlyRun/runme.py	(revision 27336)
++++ ../trunk-jpl/test/NightlyRun/runme.py	(revision 27337)
+@@ -1,4 +1,4 @@
+-#!/usr/bin/env python
++#!/usr/bin/env python3
+ #
+ # NOTE: Switch to,
+ #
+@@ -7,9 +7,8 @@
+ # when making Python 3 default
+ #
+ import argparse
+-from glob import glob
+ import os
+-from re import search, split
++import re
+ from sys import float_info
+ from traceback import format_exc
+ 
+@@ -89,6 +88,9 @@
+     - Check for failures that do not raise exceptions (for example, 'Standard
+     exception'; see also jenkins/jenkins.sh). These should be counted as
+     failures.
++    - Figure out why the following changes allow for correct partitioning of 
++    test set, but cause an error with ADOL-C build (some test logs are parsed 
++    twice).
+     """
+ 
+     #Get ISSM_DIR variable
+@@ -115,10 +117,9 @@
+         numprocs = 1
+     # }}}
+     #GET ids  {{{
+-    flist = glob('test*.py')  #File name must start with 'test' and must end by '.py' and must be different than 'test.py'
+-    list_ids = [int(search(r'\d+',file.split('.')[0]).group()) for file in flist if not file == 'test.py'] # Keep test id only (skip 'test' and '.py')
+-
+-    i1, i2 = parallelrange(rank, numprocs, len(list_ids))  #Get tests for this cpu only
++    flist = [f for f in os.listdir('.') if re.match('test[0-9]+.py', f)] # File name must follow the format "test<integer>.py"
++    list_ids = [int(re.search(r'\d+',f.split('.')[0]).group()) for f in flist] # Retrieve test IDs
++    i1, i2 = parallelrange(rank, numprocs, len(list_ids))  # Get tests for this CPU only
+     list_ids = list_ids[i1:i2 + 1]
+     if np.size(id) > 0 and id is not None:
+         test_ids = set(GetIds(id)).intersection(set(list_ids))
+@@ -171,6 +172,8 @@
+         test_ids = test_ids.intersection(set((218, 234, 235, 417, 418, 420)).union(set(range(412, 414))))
+     test_ids = list(test_ids)
+     test_ids.sort()
++    print(test_ids)
++    exit()
+     # }}}
+ 
+     #Loop over tests and launch sequence
+@@ -212,7 +215,7 @@
+                 mdl = loadmodel('test{}ma.nc'.format(id))
+                 for key in mdl.results.__dict__.keys():
+                     if 'Solution' in key:
+-                        solvetype = split('Solution', key)[0]
++                        solvetype = re.split('Solution', key)[0]
+ 
+                 #we save the results, scrap them and solve.
+                 loaded_res = mdl.results
+@@ -223,18 +226,18 @@
+                 for k, fieldname in enumerate(Tmod.field_names):
+                     try:
+                         #first look for indexing
+-                        if search(r'\d+$', fieldname):
+-                            index = int(search(r'\d+$', fieldname).group()) - 1
+-                            fieldname = fieldname[:search(r'\d+$', fieldname).start()]
++                        if re.search(r'\d+$', fieldname):
++                            index = int(re.search(r'\d+$', fieldname).group()) - 1
++                            fieldname = fieldname[:re.search(r'\d+$', fieldname).start()]
+                         elif 'FirstStep' in fieldname:
+                             index = 0
+-                            fieldname = fieldname[:search('FirstStep', fieldname).start()]
++                            fieldname = fieldname[:re.search('FirstStep', fieldname).start()]
+                         elif 'SecondStep' in fieldname:
+                             index = 1
+-                            fieldname = fieldname[:search('SecondStep', fieldname).start()]
++                            fieldname = fieldname[:re.search('SecondStep', fieldname).start()]
+                         elif 'ThirdStep' in fieldname:
+                             index = 2
+-                            fieldname = fieldname[:search('ThirdStep', fieldname).start()]
++                            fieldname = fieldname[:re.search('ThirdStep', fieldname).start()]
+                         else:
+                             index = 0
+ 
+@@ -269,7 +272,7 @@
+                                 except TypeError:
+                                     #probably severalmatches, we take the last one which should be the good one (Needs to be controled in the list above)
+                                     sufix = sufixes[np.squeeze(np.where([suf in fieldname for suf in sufixes]))[-1]]
+-                                fieldname = fieldname[:search(sufix, fieldname).start()]
++                                fieldname = fieldname[:re.search(sufix, fieldname).start()]
+                             elif fieldname.endswith("P") and index == 1:
+                                 #we are looking for P2 but 2 as been considered as an index and so shifted by -1
+                                 fieldname = fieldname[:-1]
Index: /issm/oecreview/Archive/27230-27343/ISSM-27337-27338.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27337-27338.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27337-27338.diff	(revision 27344)
@@ -0,0 +1,10 @@
+Index: ../trunk-jpl/test/NightlyRun/runme.py
+===================================================================
+--- ../trunk-jpl/test/NightlyRun/runme.py	(revision 27337)
++++ ../trunk-jpl/test/NightlyRun/runme.py	(revision 27338)
+@@ -1,4 +1,4 @@
+-#!/usr/bin/env python3
++#!/usr/bin/env python
+ #
+ # NOTE: Switch to,
+ #
Index: /issm/oecreview/Archive/27230-27343/ISSM-27338-27339.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27338-27339.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27338-27339.diff	(revision 27344)
@@ -0,0 +1,13 @@
+Index: ../trunk-jpl/src/c/classes/Elements/Tria.cpp
+===================================================================
+--- ../trunk-jpl/src/c/classes/Elements/Tria.cpp	(revision 27338)
++++ ../trunk-jpl/src/c/classes/Elements/Tria.cpp	(revision 27339)
+@@ -7810,7 +7810,7 @@
+ 
+ 	if(!computeviscous){ /*{{{*/
+ 		/*elastic or self attraction only case
+-		/*store values computed on vertices, but don't repeat the computation if another element already computed it!:*/
++		  store values computed on vertices, but don't repeat the computation if another element already computed it!:*/
+ 		if(percpu){
+ 			for(av=0;av<n_activevertices;av++) { //vertices
+ 				i=activevertices[av];
Index: /issm/oecreview/Archive/27230-27343/ISSM-27339-27340.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27339-27340.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27339-27340.diff	(revision 27344)
@@ -0,0 +1,16 @@
+Index: ../trunk-jpl/src/c/cores/controltao_core.cpp
+===================================================================
+--- ../trunk-jpl/src/c/cores/controltao_core.cpp	(revision 27339)
++++ ../trunk-jpl/src/c/cores/controltao_core.cpp	(revision 27340)
+@@ -106,7 +106,11 @@
+ 
+ 	user.J=xNewZeroInit<double>(maxiter+5);
+ 	user.femmodel=femmodel;
++	#if PETSC_VERSION_LT(3,17,0)
+ 	TaoSetObjectiveAndGradientRoutine(tao,FormFunctionGradient,(void*)&user); 
++	#else
++	TaoSetObjectiveAndGradient(tao,G->pvector->vector, FormFunctionGradient, (void*)&user);
++	#endif
+ 
+ 	/*Solver optimization problem*/
+ 	if(VerboseControl()) _printf0_("   Starting optimization\n");
Index: /issm/oecreview/Archive/27230-27343/ISSM-27340-27341.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27340-27341.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27340-27341.diff	(revision 27344)
@@ -0,0 +1,14 @@
+Index: ../trunk-jpl/src/c/classes/Elements/Element.cpp
+===================================================================
+--- ../trunk-jpl/src/c/classes/Elements/Element.cpp	(revision 27340)
++++ ../trunk-jpl/src/c/classes/Elements/Element.cpp	(revision 27341)
+@@ -230,6 +230,9 @@
+          alpha = (base[i]-upperwaterel[basinid])/(deepwaterel[basinid]-upperwaterel[basinid]);
+          values[i]=deepwatermelt[i]*alpha+(1.-alpha)*upperwatermelt[basinid];
+       }
++		if(xIsNan<IssmDouble>(values[i])) _error_("NaN found in melt");
++		if(xIsInf<IssmDouble>(values[i])) _error_("Inf found in melt");
++		if(fabs(values[i])>1.e+10) _error_("melt exceeds 1.e+10");
+    }
+ 
+    this->AddInput(BasalforcingsFloatingiceMeltingRateEnum,&values[0],P1Enum);
Index: /issm/oecreview/Archive/27230-27343/ISSM-27341-27342.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27341-27342.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27341-27342.diff	(revision 27344)
@@ -0,0 +1,34 @@
+Index: ../trunk-jpl/src/c/classes/Elements/Element.cpp
+===================================================================
+--- ../trunk-jpl/src/c/classes/Elements/Element.cpp	(revision 27341)
++++ ../trunk-jpl/src/c/classes/Elements/Element.cpp	(revision 27342)
+@@ -129,7 +129,7 @@
+ 			}
+ 			/*Compute polynomial with parameters of indperiod*/
+ 			if(indperiod==0) telapsed_break = tatstep;
+-			else             telapsed_break = tatstep-datebreaks_basin[indperiod];
++			else             telapsed_break = tatstep-datebreaks_basin[indperiod-1];
+ 			for(int j=0;j<numparams;j++)   sumpoly[s] = sumpoly[s]+polyparams_basin[indperiod+j*numperiods]*pow(telapsed_break,j);
+ 		}
+ 		else for(int j=0;j<numparams;j++) sumpoly[s] = sumpoly[s]+polyparams_basin[j*numperiods]*pow(tatstep,j);
+@@ -2766,7 +2766,7 @@
+ 		}
+ 		/*Compute intercept+trend terms with parameters of indperiod*/
+       if(indperiod==0) telapsed_break = time;
+-      else             telapsed_break = time-datebreaks_b[indperiod];
++      else             telapsed_break = time-datebreaks_b[indperiod-1];
+       piecewiselin = intercepts_b[indperiod]+trends_b[indperiod]*telapsed_break;
+ 	}
+    else piecewiselin = intercepts_b[indperiod]+trends_b[indperiod]*time;
+Index: ../trunk-jpl/src/c/modules/FrontalForcingsx/FrontalForcingsx.cpp
+===================================================================
+--- ../trunk-jpl/src/c/modules/FrontalForcingsx/FrontalForcingsx.cpp	(revision 27341)
++++ ../trunk-jpl/src/c/modules/FrontalForcingsx/FrontalForcingsx.cpp	(revision 27342)
+@@ -100,4 +100,7 @@
+    xDelete<IssmDouble>(monthlyeff);
+    xDelete<IssmDouble>(polyparams);
+    xDelete<IssmDouble>(datebreaks);
++   xDelete<IssmDouble>(monthdatebreaks);
++   xDelete<IssmDouble>(monthintercepts);
++   xDelete<IssmDouble>(monthtrends);
+ }/*}}}*/
Index: /issm/oecreview/Archive/27230-27343/ISSM-27342-27343.diff
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-27342-27343.diff	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-27342-27343.diff	(revision 27344)
@@ -0,0 +1,12 @@
+Index: ../trunk-jpl/test/Archives/Archive257.arch
+===================================================================
+Cannot display: file marked as a binary type.
+svn:mime-type = application/octet-stream
+Index: ../trunk-jpl/test/Archives/Archive543.arch
+===================================================================
+Cannot display: file marked as a binary type.
+svn:mime-type = application/octet-stream
+Index: ../trunk-jpl/test/Archives/Archive544.arch
+===================================================================
+Cannot display: file marked as a binary type.
+svn:mime-type = application/octet-stream
Index: /issm/oecreview/Archive/27230-27343/ISSM-DocReview-27230-27343.tex
===================================================================
--- /issm/oecreview/Archive/27230-27343/ISSM-DocReview-27230-27343.tex	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/ISSM-DocReview-27230-27343.tex	(revision 27344)
@@ -0,0 +1,67 @@
+\documentclass[]{report}   % list options between brackets
+\usepackage{graphicx}              % list packages between braces
+
+% type user-defined commands here
+
+\begin{document}
+
+\title{JPL EXPORT ADMINISTRATION \\ DOCUMENT REVIEW RECORD}   % type title between braces
+\author{Tom Scavo}         % type author(s) between braces
+\date{October 27, 1995}    % type date between braces
+%\maketitle
+
+
+\begin{center}
+\begin{tabular}{ |c|c| }
+\hline
+JPL EXPORT ADMINISTRATION \\
+\textit{ DOCUMENT REVIEW RECORD} \\
+\hline
+\end{tabular}
+\end{center}
+
+\hfill Log \#: \underline{\input{LogNumber}}
+
+\vspace{1cm}
+\noindent (Note: This form and process do not replace the procedures described in JPL Policy relating to review and approval of proposals and contractual 
+documents. This process is intended to document the review and coordination of requests to ascertain the export control ramifications relating to specific 
+documents. Export Administration signature does not convey authority to export or release the "Exporter of Record" from any export laws or regulations.)\\
+
+\noindent \textbf{Program:} \underline{ISSM: Ice Sheet System Model} \\ \\
+\noindent \textbf{Person Requesting or Initiating Export}: \underline{Dr. Eric Larour}\\ \\
+\noindent \textbf{Date Received}: \underline{\input{Date}}\\ \\
+\noindent \textbf{Document Title/Description}: ISSM changes from revision \input{r1} to revision \input{r2} \\ \\
+\noindent \textbf{Release to:} \underline{http://issm.ess.uci.edu/svn/issm/issm/trunk on ISSM svn repository}\\ \\
+\noindent \textbf{JPL Intranet:} \underline{murdo.jpl.nasa.gov/proj/ice/larour/issm-uci/trunk-jpl}\\ \\
+
+\noindent \textbf{Disposition: 6 } 
+Does not contain export-controlled information. May be released/disclosed as requested subject to 
+Company guidelines on protection of proprietary information (if applicable). \\
+
+\noindent \textbf{Comments:}  see table of changes below. \\ \\
+\noindent \textbf{Reviewed by ISSM Export Transfer Liaison:} Dr. Eric Larour \hfill \textbf{Date:} \input{Date} \\ 
+\includegraphics[scale=1]{signature}
+
+\noindent JPL Export Administration Form TBS – June 29, 2011
+
+\begin{center}
+\line(1,0){250}
+\end{center}
+
+\noindent \textbf{Disposition:} \\
+1:	  Public Domain Information (Ref ITAR Section 120.11) \\
+2:	  Qualifies for ITAR Exemption				 \\
+3:	  Covered by Department of State License/Agreement Number					  \\
+4:	  Covered by Department of Commerce validated license or exception				 \\
+5:	  New License Required \\
+6:	  Does not contain export-controlled information.  May be released/disclosed as requested subject
+   to Company guidelines on protection of proprietary information (if applicable). \\
+7:	 Other (specify)   
+\begin{center}
+\line(1,0){250}
+\end{center}
+
+
+\input{log}
+
+\end{document}
Index: /issm/oecreview/Archive/27230-27343/LogNumber.tex
===================================================================
--- /issm/oecreview/Archive/27230-27343/LogNumber.tex	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/LogNumber.tex	(revision 27344)
@@ -0,0 +1,1 @@
+27230-27343
Index: /issm/oecreview/Archive/27230-27343/Makefile
===================================================================
--- /issm/oecreview/Archive/27230-27343/Makefile	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/Makefile	(revision 27344)
@@ -0,0 +1,8 @@
+TARGET=ISSM-DocReview-27230-27343
+
+all: 
+	pdflatex -interaction=errorstopmode -file-line-error -halt-on-error $(TARGET).tex
+	rm -rf *.log *.aux 
+
+clean:
+	rm -rf *.log *.aux
Index: /issm/oecreview/Archive/27230-27343/log.tex
===================================================================
--- /issm/oecreview/Archive/27230-27343/log.tex	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/log.tex	(revision 27344)
@@ -0,0 +1,644 @@
+\noindent \textbf{Change \#1} with diff file ISSM-27231-27232.diff: \\
+Function name: \\
+M /issm/trunk-jpl\\
+Export determination: 6. \\
+Rationale: merged trunk and trunk-jpl\\
+\vspace{3em}
+
+\noindent \textbf{Change \#2} with diff file ISSM-27233-27234.diff: \\
+Function name: \\
+M /issm/trunk-jpl M /issm/trunk-jpl/src M /issm/trunk-jpl/test\\
+Export determination: 6. \\
+Rationale: Block revision 27232 from being merged into trunk-jpl\\
+\vspace{3em}
+
+\noindent \textbf{Change \#3} with diff file ISSM-27234-27235.diff: \\
+Function name: \\
+M /issm/trunk-jpl/configure.ac\\
+Export determination: 6. \\
+Rationale: CHG: new issm version\\
+\vspace{3em}
+
+\noindent \textbf{Change \#4} with diff file ISSM-27236-27237.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/m/classes/SMBgemb.m M /issm/trunk-jpl/src/m/classes/SMBgemb.py\\
+Export determination: 6. \\
+Rationale: CHG: new GEMB class for manuscript\\
+\vspace{3em}
+
+\noindent \textbf{Change \#5} with diff file ISSM-27237-27238.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/c/modules/SurfaceMassBalancex/Gembx.cpp M /issm/trunk-jpl/src/c/modules/SurfaceMassBalancex/SurfaceMassBalancex.h\\
+Export determination: 6. \\
+Rationale: CHG: some GEMB cleanup\\
+\vspace{3em}
+
+\noindent \textbf{Change \#6} with diff file ISSM-27238-27239.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/c/modules/SurfaceMassBalancex/Gembx.cpp\\
+Export determination: 6. \\
+Rationale: CHG: tighten GEMB constraints on ice depth\\
+\vspace{3em}
+
+\noindent \textbf{Change \#7} with diff file ISSM-27240-27241.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/c/modules/SurfaceMassBalancex/Gembx.cpp M /issm/trunk-jpl/src/c/modules/SurfaceMassBalancex/SurfaceMassBalancex.h M /issm/trunk-jpl/test/Archives/Archive243.arch M /issm/trunk-jpl/test/Archives/Archive244.arch M /issm/trunk-jpl/test/Archives/Archive252.arch\\
+Export determination: 6. \\
+Rationale: CHG: more GEMB cleanup of ints to floats\\
+\vspace{3em}
+
+\noindent \textbf{Change \#8} with diff file ISSM-27241-27242.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/c/modules/SurfaceMassBalancex/Gembx.cpp\\
+Export determination: 6. \\
+Rationale: CHG: incorporate some tolerances into GEMB initial layering\\
+\vspace{3em}
+
+\noindent \textbf{Change \#9} with diff file ISSM-27242-27243.diff: \\
+Function name: \\
+M /issm/trunk-jpl/test/NightlyRun/test243.m M /issm/trunk-jpl/test/NightlyRun/test243.py M /issm/trunk-jpl/test/NightlyRun/test244.m M /issm/trunk-jpl/test/NightlyRun/test244.py M /issm/trunk-jpl/test/NightlyRun/test252.m M /issm/trunk-jpl/test/NightlyRun/test252.py\\
+Export determination: 6. \\
+Rationale: CHG: loosen tols for GEMB runs\\
+\vspace{3em}
+
+\noindent \textbf{Change \#10} with diff file ISSM-27243-27244.diff: \\
+Function name: \\
+M /issm/trunk-jpl/test/NightlyRun/test243.m M /issm/trunk-jpl/test/NightlyRun/test243.py\\
+Export determination: 6. \\
+Rationale: CHG: update tols for GEMB windows\\
+\vspace{3em}
+
+\noindent \textbf{Change \#11} with diff file ISSM-27246-27247.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/c/analyses/LevelsetAnalysis.cpp M /issm/trunk-jpl/src/c/classes/Elements/Element.cpp M /issm/trunk-jpl/src/c/classes/Elements/Element.h M /issm/trunk-jpl/src/c/modules/FloatingiceMeltingRatex/FloatingiceMeltingRatex.cpp M /issm/trunk-jpl/src/c/modules/FloatingiceMeltingRatex/FloatingiceMeltingRatex.h M /issm/trunk-jpl/src/c/modules/FrontalForcingsx/FrontalForcingsx.cpp M /issm/trunk-jpl/src/c/modules/FrontalForcingsx/FrontalForcingsx.h M /issm/trunk-jpl/src/c/modules/ModelProcessorx/CreateParameters.cpp M /issm/trunk-jpl/src/c/modules/SurfaceMassBalancex/SurfaceMassBalancex.cpp M /issm/trunk-jpl/src/c/modules/SurfaceMassBalancex/SurfaceMassBalancex.h M /issm/trunk-jpl/src/c/shared/Enum/Enum.vim M /issm/trunk-jpl/src/c/shared/Enum/EnumDefinitions.h M /issm/trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp M /issm/trunk-jpl/src/c/shared/Enum/Enumjl.vim M /issm/trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp M /issm/trunk-jpl/src/m/classes/SMBautoregression.m M /issm/trunk-jpl/src/m/classes/SMBautoregression.py M /issm/trunk-jpl/src/m/classes/autoregressionlinearbasalforcings.m M /issm/trunk-jpl/src/m/classes/autoregressionlinearbasalforcings.py M /issm/trunk-jpl/src/m/classes/frontalforcingsrignotautoregression.m M /issm/trunk-jpl/src/m/classes/frontalforcingsrignotautoregression.py M /issm/trunk-jpl/test/Archives/Archive257.arch M /issm/trunk-jpl/test/Archives/Archive543.arch M /issm/trunk-jpl/test/Archives/Archive544.arch M /issm/trunk-jpl/test/NightlyRun/test257.m M /issm/trunk-jpl/test/NightlyRun/test257.py M /issm/trunk-jpl/test/NightlyRun/test543.m M /issm/trunk-jpl/test/NightlyRun/test543.py M /issm/trunk-jpl/test/NightlyRun/test544.m M /issm/trunk-jpl/test/NightlyRun/test544.py\\
+Export determination: 6. \\
+Rationale: CHG: clean-up of autoregression method\\
+\vspace{3em}
+
+\noindent \textbf{Change \#12} with diff file ISSM-27247-27248.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/m/classes/frontalforcingsrignotautoregression.m\\
+Export determination: 6. \\
+Rationale: BUG: fixing typo\\
+\vspace{3em}
+
+\noindent \textbf{Change \#13} with diff file ISSM-27250-27251.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/c/analyses/LevelsetAnalysis.cpp M /issm/trunk-jpl/src/c/analyses/MasstransportAnalysis.cpp M /issm/trunk-jpl/src/c/analyses/SmbAnalysis.cpp M /issm/trunk-jpl/src/c/classes/Elements/Element.cpp M /issm/trunk-jpl/src/c/classes/Elements/Element.h M /issm/trunk-jpl/src/c/modules/FloatingiceMeltingRatex/FloatingiceMeltingRatex.cpp M /issm/trunk-jpl/src/c/modules/FloatingiceMeltingRatex/FloatingiceMeltingRatex.h M /issm/trunk-jpl/src/c/modules/FrontalForcingsx/FrontalForcingsx.cpp M /issm/trunk-jpl/src/c/modules/FrontalForcingsx/FrontalForcingsx.h M /issm/trunk-jpl/src/c/modules/ModelProcessorx/CreateParameters.cpp M /issm/trunk-jpl/src/c/modules/StochasticForcingx/StochasticForcingx.cpp M /issm/trunk-jpl/src/c/modules/SurfaceMassBalancex/SurfaceMassBalancex.cpp M /issm/trunk-jpl/src/c/modules/SurfaceMassBalancex/SurfaceMassBalancex.h M /issm/trunk-jpl/src/c/shared/Enum/Enum.vim M /issm/trunk-jpl/src/c/shared/Enum/EnumDefinitions.h M /issm/trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp M /issm/trunk-jpl/src/c/shared/Enum/Enumjl.vim M /issm/trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp M /issm/trunk-jpl/src/c/shared/io/Marshalling/IoCodeConversions.cpp A /issm/trunk-jpl/src/m/classes/SMBarma.m A /issm/trunk-jpl/src/m/classes/SMBarma.py A /issm/trunk-jpl/src/m/classes/frontalforcingsrignotarma.m A /issm/trunk-jpl/src/m/classes/frontalforcingsrignotarma.py A /issm/trunk-jpl/src/m/classes/linearbasalforcingsarma.m A /issm/trunk-jpl/src/m/classes/linearbasalforcingsarma.py M /issm/trunk-jpl/test/NightlyRun/test257.m M /issm/trunk-jpl/test/NightlyRun/test257.py M /issm/trunk-jpl/test/NightlyRun/test543.m M /issm/trunk-jpl/test/NightlyRun/test543.py M /issm/trunk-jpl/test/NightlyRun/test544.m M /issm/trunk-jpl/test/NightlyRun/test544.py\\
+Export determination: 6. \\
+Rationale: CHG Changing autoregression schemes towards ARMA schemes: work is ongoing\\
+\vspace{3em}
+
+\noindent \textbf{Change \#14} with diff file ISSM-27251-27252.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/m/classes/stochasticforcing.m M /issm/trunk-jpl/src/m/classes/stochasticforcing.py\\
+Export determination: 6. \\
+Rationale: CHG Changing autoregression schemes towards ARMA schemes: work is ongoing (forgot two files)\\
+\vspace{3em}
+
+\noindent \textbf{Change \#15} with diff file ISSM-27252-27253.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/c/analyses/LevelsetAnalysis.cpp M /issm/trunk-jpl/src/c/classes/Elements/Tria.cpp M /issm/trunk-jpl/src/c/cores/movingfront\_core.cpp M /issm/trunk-jpl/src/c/shared/Enum/EnumDefinitions.h M /issm/trunk-jpl/src/m/classes/calvingparameterization.m\\
+Export determination: 6. \\
+Rationale: CHG: use max Vel to normalize the parameterization of the frontal ablation rate\\
+\vspace{3em}
+
+\noindent \textbf{Change \#16} with diff file ISSM-27253-27254.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/c/classes/Elements/Tria.cpp M /issm/trunk-jpl/src/c/cores/movingfront\_core.cpp M /issm/trunk-jpl/src/c/shared/Enum/EnumDefinitions.h\\
+Export determination: 6. \\
+Rationale: CHG: separate velmax and velthreshold for calving parameterization\\
+\vspace{3em}
+
+\noindent \textbf{Change \#17} with diff file ISSM-27254-27255.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/c/cores/movingfront\_core.cpp\\
+Export determination: 6. \\
+Rationale: BUG: only calculate maxvel in movingfront when stressbalance is solved\\
+\vspace{3em}
+
+\noindent \textbf{Change \#18} with diff file ISSM-27256-27257.diff: \\
+Function name: \\
+A /issm/trunk-jpl/src/m/classes/clusters/pace.m\\
+Export determination: 6. \\
+Rationale: NEW adding a cluster script for PACE\\
+\vspace{3em}
+
+\noindent \textbf{Change \#19} with diff file ISSM-27260-27261.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/c/classes/Elements/Element.cpp M /issm/trunk-jpl/src/c/classes/Elements/Element.h M /issm/trunk-jpl/src/c/modules/FloatingiceMeltingRatex/FloatingiceMeltingRatex.cpp M /issm/trunk-jpl/src/c/modules/FrontalForcingsx/FrontalForcingsx.cpp M /issm/trunk-jpl/src/c/modules/SurfaceMassBalancex/SurfaceMassBalancex.cpp M /issm/trunk-jpl/src/c/shared/Enum/Enum.vim M /issm/trunk-jpl/src/c/shared/Enum/EnumDefinitions.h M /issm/trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp M /issm/trunk-jpl/src/c/shared/Enum/Enumjl.vim M /issm/trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp M /issm/trunk-jpl/src/m/classes/SMBarma.m M /issm/trunk-jpl/src/m/classes/SMBarma.py M /issm/trunk-jpl/src/m/classes/frontalforcingsrignotarma.m M /issm/trunk-jpl/src/m/classes/frontalforcingsrignotarma.py M /issm/trunk-jpl/src/m/classes/linearbasalforcingsarma.m M /issm/trunk-jpl/test/Archives/Archive257.arch M /issm/trunk-jpl/test/Archives/Archive543.arch M /issm/trunk-jpl/test/Archives/Archive544.arch M /issm/trunk-jpl/test/NightlyRun/test257.m M /issm/trunk-jpl/test/NightlyRun/test257.py M /issm/trunk-jpl/test/NightlyRun/test543.m M /issm/trunk-jpl/test/NightlyRun/test543.py M /issm/trunk-jpl/test/NightlyRun/test544.m M /issm/trunk-jpl/test/NightlyRun/test544.py\\
+Export determination: 6. \\
+Rationale: NEW arma process fully implemented\\
+\vspace{3em}
+
+\noindent \textbf{Change \#20} with diff file ISSM-27261-27262.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/c/analyses/LevelsetAnalysis.cpp M /issm/trunk-jpl/src/c/modules/FrontalForcingsx/FrontalForcingsx.cpp M /issm/trunk-jpl/src/m/classes/linearbasalforcingsarma.py M /issm/trunk-jpl/test/Archives/Archive543.arch M /issm/trunk-jpl/test/NightlyRun/test543.m M /issm/trunk-jpl/test/NightlyRun/test543.py M /issm/trunk-jpl/test/NightlyRun/test544.py\\
+Export determination: 6. \\
+Rationale: BUG fixing bugs in arma scripts\\
+\vspace{3em}
+
+\noindent \textbf{Change \#21} with diff file ISSM-27262-27263.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/m/classes/clusters/acenet.m M /issm/trunk-jpl/src/m/classes/clusters/aci.m M /issm/trunk-jpl/src/m/classes/clusters/aurora.m A /issm/trunk-jpl/src/m/classes/clusters/aws\_issm\_solution\_server.m M /issm/trunk-jpl/src/m/classes/clusters/camhpc.m M /issm/trunk-jpl/src/m/classes/clusters/castor.m M /issm/trunk-jpl/src/m/classes/clusters/cloud.m M /issm/trunk-jpl/src/m/classes/clusters/cloud.py M /issm/trunk-jpl/src/m/classes/clusters/computecanada.m M /issm/trunk-jpl/src/m/classes/clusters/cosmos.m M /issm/trunk-jpl/src/m/classes/clusters/cyclone.py M /issm/trunk-jpl/src/m/classes/clusters/discover.m M /issm/trunk-jpl/src/m/classes/clusters/discover.py M /issm/trunk-jpl/src/m/classes/clusters/discovery.m M /issm/trunk-jpl/src/m/classes/clusters/fram.py M /issm/trunk-jpl/src/m/classes/clusters/frontera.m M /issm/trunk-jpl/src/m/classes/clusters/gemini.m M /issm/trunk-jpl/src/m/classes/clusters/generic.m M /issm/trunk-jpl/src/m/classes/clusters/generic.py M /issm/trunk-jpl/src/m/classes/clusters/generic\_static.m M /issm/trunk-jpl/src/m/classes/clusters/generic\_static.py M /issm/trunk-jpl/src/m/classes/clusters/greenplanet.m M /issm/trunk-jpl/src/m/classes/clusters/hpc.m M /issm/trunk-jpl/src/m/classes/clusters/hpc\_simba.m M /issm/trunk-jpl/src/m/classes/clusters/localpfe.m M /issm/trunk-jpl/src/m/classes/clusters/lonestar.m M /issm/trunk-jpl/src/m/classes/clusters/maui.m M /issm/trunk-jpl/src/m/classes/clusters/pace.m M /issm/trunk-jpl/src/m/classes/clusters/pfe.m M /issm/trunk-jpl/src/m/classes/clusters/pfe.py M /issm/trunk-jpl/src/m/classes/clusters/raijin.m M /issm/trunk-jpl/src/m/classes/clusters/saga.py M /issm/trunk-jpl/src/m/classes/clusters/sherlock.m M /issm/trunk-jpl/src/m/classes/clusters/smce\_eis.py M /issm/trunk-jpl/src/m/classes/clusters/tetralith.m M /issm/trunk-jpl/src/m/classes/clusters/yellowstone.m M /issm/trunk-jpl/src/m/solve/waitonlock.m M /issm/trunk-jpl/src/m/solve/waitonlock.py M /issm/trunk-jpl/test/NightlyRun/runme.m A /issm/trunk-jpl/test/NightlyRun/test101awsissmsolutionserver.m\\
+Export determination: 6. \\
+Rationale: CHG: Custom cluster class for AWS ISSM solution server instance; typos; clean up\\
+\vspace{3em}
+
+\noindent \textbf{Change \#22} with diff file ISSM-27263-27264.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/m/solve/waitonlock.py\\
+Export determination: 6. \\
+Rationale: BUG: Syntax\\
+\vspace{3em}
+
+\noindent \textbf{Change \#23} with diff file ISSM-27264-27265.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/m/contrib/defleurian/netCDF/export\_netCDF.m M /issm/trunk-jpl/src/m/contrib/defleurian/netCDF/export\_netCDF.py M /issm/trunk-jpl/src/m/io/loadvars.py\\
+Export determination: 6. \\
+Rationale: CHG:Some netCDF IO modifications\\
+\vspace{3em}
+
+\noindent \textbf{Change \#24} with diff file ISSM-27271-27272.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/c/classes/Elements/Penta.cpp M /issm/trunk-jpl/src/c/classes/Elements/Tria.cpp\\
+Export determination: 6. \\
+Rationale: CHG: use CalvingFromRate to determine the direction of calving so that Levermann is consistent with other calving laws\\
+\vspace{3em}
+
+\noindent \textbf{Change \#25} with diff file ISSM-27272-27273.diff: \\
+Function name: \\
+M /issm/trunk-jpl/test/Archives/Archive806.arch M /issm/trunk-jpl/test/Archives/Archive812.arch\\
+Export determination: 6. \\
+Rationale: CHG: updating archives based on new Levermann direction\\
+\vspace{3em}
+
+\noindent \textbf{Change \#26} with diff file ISSM-27274-27275.diff: \\
+Function name: \\
+M /issm/trunk-jpl/test/Archives/Archive3203.arch\\
+Export determination: 6. \\
+Rationale: CHG: new archive now that levermann is fixed\\
+\vspace{3em}
+
+\noindent \textbf{Change \#27} with diff file ISSM-27276-27277.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/c/shared/Random/random.cpp D /issm/trunk-jpl/src/m/classes/SMBautoregression.m D /issm/trunk-jpl/src/m/classes/SMBautoregression.py D /issm/trunk-jpl/src/m/classes/autoregressionlinearbasalforcings.m D /issm/trunk-jpl/src/m/classes/autoregressionlinearbasalforcings.py D /issm/trunk-jpl/src/m/classes/frontalforcingsrignotautoregression.m D /issm/trunk-jpl/src/m/classes/frontalforcingsrignotautoregression.py M /issm/trunk-jpl/src/m/contrib/morlighem/modeldata/interpBedmachineGreenland.m M /issm/trunk-jpl/src/m/contrib/morlighem/modeldata/interpSeaRISE.m\\
+Export determination: 6. \\
+Rationale: CHG: deleting old autoregression scripts\\
+\vspace{3em}
+
+\noindent \textbf{Change \#28} with diff file ISSM-27277-27278.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/m/contrib/morlighem/modeldata/interpBedmachineGreenland.m M /issm/trunk-jpl/src/m/contrib/morlighem/modeldata/interpSeaRISE.m\\
+Export determination: 6. \\
+Rationale: BUG reverting files that should not have been modified\\
+\vspace{3em}
+
+\noindent \textbf{Change \#29} with diff file ISSM-27278-27279.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/c/analyses/FreeSurfaceBaseAnalysis.cpp M /issm/trunk-jpl/src/c/analyses/LevelsetAnalysis.cpp M /issm/trunk-jpl/src/c/analyses/MasstransportAnalysis.cpp M /issm/trunk-jpl/src/c/analyses/StressbalanceAnalysis.cpp M /issm/trunk-jpl/src/c/analyses/StressbalanceVerticalAnalysis.cpp M /issm/trunk-jpl/src/c/classes/Elements/Element.cpp M /issm/trunk-jpl/src/c/modules/ModelProcessorx/CreateParameters.cpp M /issm/trunk-jpl/src/c/shared/Enum/Enum.vim M /issm/trunk-jpl/src/c/shared/Enum/EnumDefinitions.h M /issm/trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp M /issm/trunk-jpl/src/c/shared/Enum/Enumjl.vim M /issm/trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp M /issm/trunk-jpl/src/m/classes/basalforcingsbeckmanngoosse.m\\
+Export determination: 6. \\
+Rationale: NEW: added possibility to use thermal forcing in basalforcingsbeckmanngoosse and ensures compatibility with thermal forcing of frontalforcingsrignot\\
+\vspace{3em}
+
+\noindent \textbf{Change \#30} with diff file ISSM-27279-27280.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/c/analyses/FreeSurfaceBaseAnalysis.cpp M /issm/trunk-jpl/src/c/analyses/MasstransportAnalysis.cpp M /issm/trunk-jpl/src/c/analyses/StressbalanceAnalysis.cpp M /issm/trunk-jpl/src/c/analyses/StressbalanceVerticalAnalysis.cpp\\
+Export determination: 6. \\
+Rationale: CHG: compatibility of basalforcingsbeckmanngoosse with frontalforcingsrignotarma\\
+\vspace{3em}
+
+\noindent \textbf{Change \#31} with diff file ISSM-27280-27281.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/c/classes/Elements/Tria.cpp M /issm/trunk-jpl/src/m/classes/calvingparameterization.m\\
+Export determination: 6. \\
+Rationale: CHG: add linear relationship in calving parameterization using normalized vel\\
+\vspace{3em}
+
+\noindent \textbf{Change \#32} with diff file ISSM-27281-27282.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/m/classes/frontalforcingsrignot.m\\
+Export determination: 6. \\
+Rationale: CHG: correct the unit for subglacial\_discharge\\
+\vspace{3em}
+
+\noindent \textbf{Change \#33} with diff file ISSM-27282-27283.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/c/analyses/HydrologyGlaDSAnalysis.cpp M /issm/trunk-jpl/src/c/classes/Elements/Element.cpp M /issm/trunk-jpl/src/c/classes/Loads/Channel.cpp M /issm/trunk-jpl/src/c/modules/SetActiveNodesLSMx/SetActiveNodesLSMx.cpp M /issm/trunk-jpl/src/c/modules/SetActiveNodesLSMx/SetActiveNodesLSMx.h M /issm/trunk-jpl/src/c/shared/Enum/Enum.vim M /issm/trunk-jpl/src/c/shared/Enum/EnumDefinitions.h M /issm/trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp M /issm/trunk-jpl/src/c/shared/Enum/Enumjl.vim M /issm/trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp\\
+Export determination: 6. \\
+Rationale: CHG: preparing ground for GlaDS bigger domain\\
+\vspace{3em}
+
+\noindent \textbf{Change \#34} with diff file ISSM-27283-27284.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/c/modules/SetActiveNodesLSMx/SetActiveNodesLSMx.cpp\\
+Export determination: 6. \\
+Rationale: BUG: inverted hydro and non hydro run!\\
+\vspace{3em}
+
+\noindent \textbf{Change \#35} with diff file ISSM-27284-27285.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/c/analyses/FreeSurfaceBaseAnalysis.cpp M /issm/trunk-jpl/src/c/analyses/LevelsetAnalysis.cpp M /issm/trunk-jpl/src/c/analyses/MasstransportAnalysis.cpp M /issm/trunk-jpl/src/c/analyses/StressbalanceAnalysis.cpp M /issm/trunk-jpl/src/c/analyses/StressbalanceVerticalAnalysis.cpp M /issm/trunk-jpl/src/c/classes/Elements/Element.cpp M /issm/trunk-jpl/src/c/shared/Enum/Enum.vim M /issm/trunk-jpl/src/c/shared/Enum/EnumDefinitions.h M /issm/trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp M /issm/trunk-jpl/src/c/shared/Enum/Enumjl.vim M /issm/trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp\\
+Export determination: 6. \\
+Rationale: CHG: changed Enum name from FrontalForcingsAndBasalforcingsThermalForcingEnum to ThermalForcingEnum\\
+\vspace{3em}
+
+\noindent \textbf{Change \#36} with diff file ISSM-27285-27286.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/c/analyses/LevelsetAnalysis.cpp M /issm/trunk-jpl/src/c/classes/Elements/Element.cpp M /issm/trunk-jpl/src/c/classes/Elements/Element.h M /issm/trunk-jpl/src/c/modules/FrontalForcingsx/FrontalForcingsx.cpp M /issm/trunk-jpl/src/c/shared/Enum/Enum.vim M /issm/trunk-jpl/src/c/shared/Enum/EnumDefinitions.h M /issm/trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp M /issm/trunk-jpl/src/c/shared/Enum/Enumjl.vim M /issm/trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp M /issm/trunk-jpl/src/m/classes/frontalforcingsrignotarma.m M /issm/trunk-jpl/src/m/classes/frontalforcingsrignotarma.py\\
+Export determination: 6. \\
+Rationale: NEW: added monthly effect capabilities to frontalforcingsrignotarma\\
+\vspace{3em}
+
+\noindent \textbf{Change \#37} with diff file ISSM-27286-27287.diff: \\
+Function name: \\
+A /issm/trunk-jpl/src/m/classes/calvingpollard.m\\
+Export determination: 6. \\
+Rationale: CHG: added matlab class for Pollard and DeConto calving parameterization\\
+\vspace{3em}
+
+\noindent \textbf{Change \#38} with diff file ISSM-27287-27288.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/c/analyses/LevelsetAnalysis.cpp M /issm/trunk-jpl/src/c/classes/Elements/Element.cpp M /issm/trunk-jpl/src/c/classes/Elements/Element.h M /issm/trunk-jpl/src/c/classes/Elements/Penta.cpp M /issm/trunk-jpl/src/c/classes/Elements/Tria.cpp M /issm/trunk-jpl/src/c/classes/Elements/Tria.h M /issm/trunk-jpl/src/c/modules/Calvingx/Calvingx.cpp M /issm/trunk-jpl/src/c/shared/Enum/Enum.vim M /issm/trunk-jpl/src/c/shared/Enum/EnumDefinitions.h M /issm/trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp M /issm/trunk-jpl/src/c/shared/Enum/Enumjl.vim M /issm/trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp M /issm/trunk-jpl/src/c/shared/io/Marshalling/IoCodeConversions.cpp\\
+Export determination: 6. \\
+Rationale: NEW: Implemented Pollard and DeContol magical calving law\\
+\vspace{3em}
+
+\noindent \textbf{Change \#39} with diff file ISSM-27288-27289.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/c/cores/movingfront\_core.cpp\\
+Export determination: 6. \\
+Rationale: CHG: simplifying how variables are extrapolated\\
+\vspace{3em}
+
+\noindent \textbf{Change \#40} with diff file ISSM-27289-27290.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/c/analyses/HydrologyGlaDSAnalysis.cpp\\
+Export determination: 6. \\
+Rationale: partially floating and part no ice elements have zero sheet thickness and zero N\\
+\vspace{3em}
+
+\noindent \textbf{Change \#41} with diff file ISSM-27290-27291.diff: \\
+Function name: \\
+A /issm/trunk-jpl/src/m/classes/clusters/hpc\_simba2.m\\
+Export determination: 6. \\
+Rationale: NEW: cluster for SIMBA at KOPRI.\\
+\vspace{3em}
+
+\noindent \textbf{Change \#42} with diff file ISSM-27291-27292.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/m/plot/plotmodel.m\\
+Export determination: 6. \\
+Rationale: CHG: fix minor - specify figure position for inwoo.\\
+\vspace{3em}
+
+\noindent \textbf{Change \#43} with diff file ISSM-27292-27293.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/m/plot/plotmodel.m\\
+Export determination: 6. \\
+Rationale: BUG: fixing Inwoo's commit\\
+\vspace{3em}
+
+\noindent \textbf{Change \#44} with diff file ISSM-27293-27294.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/c/analyses/HydrologyGlaDSAnalysis.cpp\\
+Export determination: 6. \\
+Rationale: NEW: added hydro speed as output\\
+\vspace{3em}
+
+\noindent \textbf{Change \#45} with diff file ISSM-27294-27295.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/c/classes/Elements/Penta.cpp M /issm/trunk-jpl/src/c/classes/Elements/Tria.cpp\\
+Export determination: 6. \\
+Rationale: CHG: added CFL for hydro models\\
+\vspace{3em}
+
+\noindent \textbf{Change \#46} with diff file ISSM-27295-27296.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/c/analyses/HydrologyGlaDSAnalysis.cpp\\
+Export determination: 6. \\
+Rationale: CHG: time stepping may be looking for vx/vy\\
+\vspace{3em}
+
+\noindent \textbf{Change \#47} with diff file ISSM-27296-27297.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/c/classes/Elements/Tria.cpp\\
+Export determination: 6. \\
+Rationale: CHG: time stepping may be looking for vxhydro/vyhydro\\
+\vspace{3em}
+
+\noindent \textbf{Change \#48} with diff file ISSM-27297-27298.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/c/analyses/SmbAnalysis.cpp M /issm/trunk-jpl/src/c/modules/ModelProcessorx/CreateParameters.cpp M /issm/trunk-jpl/src/c/modules/SurfaceMassBalancex/SurfaceMassBalancex.cpp M /issm/trunk-jpl/src/c/modules/SurfaceMassBalancex/SurfaceMassBalancex.h M /issm/trunk-jpl/src/c/shared/Enum/EnumDefinitions.h M /issm/trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp M /issm/trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp M /issm/trunk-jpl/src/c/shared/io/Marshalling/IoCodeConversions.cpp A /issm/trunk-jpl/src/m/classes/SMBdebrisML.m M /issm/trunk-jpl/src/m/classes/initialization.m\\
+Export determination: 6. \\
+Rationale: NEW: SMB debris model based on Mayer \& Licuilli 2021\\
+\vspace{3em}
+
+\noindent \textbf{Change \#49} with diff file ISSM-27298-27299.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/c/Makefile.am A /issm/trunk-jpl/src/c/analyses/DebrisAnalysis.cpp M /issm/trunk-jpl/src/c/analyses/analyses.h M /issm/trunk-jpl/src/c/classes/FemModel.cpp M /issm/trunk-jpl/src/c/classes/Node.cpp M /issm/trunk-jpl/src/c/classes/Profiler.h M /issm/trunk-jpl/src/c/cores/cores.h A /issm/trunk-jpl/src/c/cores/debris\_core.cpp M /issm/trunk-jpl/src/c/cores/transient\_core.cpp M /issm/trunk-jpl/src/c/modules/ModelProcessorx/CreateNodes.cpp M /issm/trunk-jpl/src/c/modules/ModelProcessorx/CreateParameters.cpp M /issm/trunk-jpl/src/c/shared/Enum/EnumDefinitions.h M /issm/trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp M /issm/trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp A /issm/trunk-jpl/src/m/classes/debris.m\\
+Export determination: 6. \\
+Rationale: NEW: Debris Analysis\\
+\vspace{3em}
+
+\noindent \textbf{Change \#50} with diff file ISSM-27299-27300.diff: \\
+Function name: \\
+M /issm/trunk-jpl/m4/analyses.m4 M /issm/trunk-jpl/src/c/analyses/EnumToAnalysis.cpp M /issm/trunk-jpl/src/c/shared/Enum/Enum.vim M /issm/trunk-jpl/src/c/shared/Enum/EnumDefinitions.h M /issm/trunk-jpl/src/c/shared/Enum/Enumjl.vim\\
+Export determination: 6. \\
+Rationale: BUG: forgot to update Analysis/m4 for Debris\\
+\vspace{3em}
+
+\noindent \textbf{Change \#51} with diff file ISSM-27300-27301.diff: \\
+Function name: \\
+A /issm/trunk-jpl/src/c/analyses/DebrisAnalysis.h\\
+Export determination: 6. \\
+Rationale: CHG: added DebrisAnalysis.h\\
+\vspace{3em}
+
+\noindent \textbf{Change \#52} with diff file ISSM-27301-27302.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/c/analyses/DebrisAnalysis.cpp\\
+Export determination: 6. \\
+Rationale: BUG: declarations in switch must be within {}\\
+\vspace{3em}
+
+\noindent \textbf{Change \#53} with diff file ISSM-27302-27303.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/c/analyses/DebrisAnalysis.cpp\\
+Export determination: 6. \\
+Rationale: CHG: minor AD\\
+\vspace{3em}
+
+\noindent \textbf{Change \#54} with diff file ISSM-27303-27304.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/m/classes/transient.m\\
+Export determination: 6. \\
+Rationale: CHG: Fixing errors with isdebris in transient simulations\\
+\vspace{3em}
+
+\noindent \textbf{Change \#55} with diff file ISSM-27304-27305.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/c/analyses/DebrisAnalysis.cpp\\
+Export determination: 6. \\
+Rationale: BUG: fixing AD\\
+\vspace{3em}
+
+\noindent \textbf{Change \#56} with diff file ISSM-27305-27306.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/m/classes/transient.js M /issm/trunk-jpl/src/m/classes/transient.py\\
+Export determination: 6. \\
+Rationale: CHG: fixing python\\
+\vspace{3em}
+
+\noindent \textbf{Change \#57} with diff file ISSM-27306-27307.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/c/classes/FemModel.cpp\\
+Export determination: 6. \\
+Rationale: CHG: estetics\\
+\vspace{3em}
+
+\noindent \textbf{Change \#58} with diff file ISSM-27307-27308.diff: \\
+Function name: \\
+M /issm/trunk-jpl/externalpackages/petsc/install-3.16-linux.sh M /issm/trunk-jpl/externalpackages/petsc/install-3.16-mac.sh M /issm/trunk-jpl/externalpackages/petsc/install-3.17-mac-m1-static.sh M /issm/trunk-jpl/externalpackages/petsc/install-3.17-mac-m1.sh\\
+Export determination: 6. \\
+Rationale: BUG: do not call config/configure.py but configure to avoid python error messages\\
+\vspace{3em}
+
+\noindent \textbf{Change \#59} with diff file ISSM-27308-27309.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/c/analyses/HydrologyTwsAnalysis.cpp M /issm/trunk-jpl/src/c/analyses/LoveAnalysis.cpp M /issm/trunk-jpl/src/c/analyses/SealevelchangeAnalysis.cpp M /issm/trunk-jpl/src/c/classes/Elements/Element.h M /issm/trunk-jpl/src/c/classes/Elements/Penta.h M /issm/trunk-jpl/src/c/classes/Elements/Seg.h M /issm/trunk-jpl/src/c/classes/Elements/Tetra.h M /issm/trunk-jpl/src/c/classes/Elements/Tria.cpp M /issm/trunk-jpl/src/c/classes/Elements/Tria.h M /issm/trunk-jpl/src/c/classes/FemModel.cpp M /issm/trunk-jpl/src/c/classes/GrdLoads.cpp M /issm/trunk-jpl/src/c/classes/GrdLoads.h M /issm/trunk-jpl/src/c/classes/Inputs/ArrayInput.cpp M /issm/trunk-jpl/src/c/classes/Inputs/IntArrayInput.cpp M /issm/trunk-jpl/src/c/cores/love\_core.cpp M /issm/trunk-jpl/src/c/cores/sealevelchange\_core.cpp M /issm/trunk-jpl/src/c/shared/Enum/EnumDefinitions.h M /issm/trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp M /issm/trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp A /issm/trunk-jpl/src/m/classes/love.m M /issm/trunk-jpl/src/m/classes/model.m M /issm/trunk-jpl/src/m/classes/sealevelmodel.m M /issm/trunk-jpl/src/m/classes/solidearth.m M /issm/trunk-jpl/src/m/solve/solveslm.m M /issm/trunk-jpl/test/NightlyRun/test2013.m M /issm/trunk-jpl/test/NightlyRun/test2070.m M /issm/trunk-jpl/test/NightlyRun/test2071.m M /issm/trunk-jpl/test/NightlyRun/test2072.m A /issm/trunk-jpl/test/NightlyRun/test2073.m M /issm/trunk-jpl/test/NightlyRun/test2084.m\\
+Export determination: 6. \\
+Rationale: CHG: sea-level change core optimization (runtime and memory use). NEW: love number core, added support for parallelization, quad precision and EBM rheology. CHG: class fourierlove renamed to just love\\
+\vspace{3em}
+
+\noindent \textbf{Change \#60} with diff file ISSM-27309-27310.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/c/cores/love\_core.cpp\\
+Export determination: 6. \\
+Rationale: BUG: complex number declaration compatibility with older gcc versions\\
+\vspace{3em}
+
+\noindent \textbf{Change \#61} with diff file ISSM-27310-27311.diff: \\
+Function name: \\
+M /issm/trunk-jpl/test/Archives/Archive2002.arch M /issm/trunk-jpl/test/Archives/Archive2005.arch M /issm/trunk-jpl/test/Archives/Archive2008.arch M /issm/trunk-jpl/test/Archives/Archive2090.arch\\
+Export determination: 6. \\
+Rationale: CHG: Updated archives\\
+\vspace{3em}
+
+\noindent \textbf{Change \#62} with diff file ISSM-27311-27312.diff: \\
+Function name: \\
+M /issm/trunk-jpl/test/Archives/Archive2002.arch M /issm/trunk-jpl/test/Archives/Archive2005.arch M /issm/trunk-jpl/test/Archives/Archive2008.arch M /issm/trunk-jpl/test/Archives/Archive2070.arch M /issm/trunk-jpl/test/Archives/Archive2071.arch M /issm/trunk-jpl/test/Archives/Archive2072.arch A /issm/trunk-jpl/test/Archives/Archive2073.arch M /issm/trunk-jpl/test/Archives/Archive2090.arch\\
+Export determination: 6. \\
+Rationale: CHG: Updated archives\\
+\vspace{3em}
+
+\noindent \textbf{Change \#63} with diff file ISSM-27312-27313.diff: \\
+Function name: \\
+M /issm/trunk-jpl/test/NightlyRun/test2071.m M /issm/trunk-jpl/test/NightlyRun/test2072.m\\
+Export determination: 6. \\
+Rationale: CHG: Eased tolerances\\
+\vspace{3em}
+
+\noindent \textbf{Change \#64} with diff file ISSM-27313-27314.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/c/classes/Elements/Tria.cpp\\
+Export determination: 6. \\
+Rationale: NEW: set calving rate to 0 where there is no ice\\
+\vspace{3em}
+
+\noindent \textbf{Change \#65} with diff file ISSM-27314-27315.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/c/cores/transient\_core.cpp\\
+Export determination: 6. \\
+Rationale: BUG: call UpdateVertexPosition AFTER grounding line migration\\
+\vspace{3em}
+
+\noindent \textbf{Change \#66} with diff file ISSM-27315-27316.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/c/analyses/HydrologyGlaDSAnalysis.cpp\\
+Export determination: 6. \\
+Rationale: CHG: added more friction laws to GlaDS\\
+\vspace{3em}
+
+\noindent \textbf{Change \#67} with diff file ISSM-27316-27317.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/m/classes/timesteppingadaptive.m\\
+Export determination: 6. \\
+Rationale: CHG: turn cycle forcing off by default\\
+\vspace{3em}
+
+\noindent \textbf{Change \#68} with diff file ISSM-27318-27319.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/c/analyses/LevelsetAnalysis.cpp M /issm/trunk-jpl/src/c/classes/Elements/Element.cpp M /issm/trunk-jpl/src/c/classes/Elements/Element.h M /issm/trunk-jpl/src/c/modules/FloatingiceMeltingRatex/FloatingiceMeltingRatex.cpp M /issm/trunk-jpl/src/c/modules/FrontalForcingsx/FrontalForcingsx.cpp M /issm/trunk-jpl/src/c/modules/ModelProcessorx/CreateParameters.cpp M /issm/trunk-jpl/src/c/modules/SurfaceMassBalancex/SurfaceMassBalancex.cpp M /issm/trunk-jpl/src/c/shared/Enum/Enum.vim M /issm/trunk-jpl/src/c/shared/Enum/EnumDefinitions.h M /issm/trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp M /issm/trunk-jpl/src/c/shared/Enum/Enumjl.vim M /issm/trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp M /issm/trunk-jpl/src/m/classes/SMBarma.m M /issm/trunk-jpl/src/m/classes/SMBarma.py M /issm/trunk-jpl/src/m/classes/frontalforcingsrignotarma.m M /issm/trunk-jpl/src/m/classes/frontalforcingsrignotarma.py M /issm/trunk-jpl/src/m/classes/linearbasalforcingsarma.m M /issm/trunk-jpl/src/m/classes/linearbasalforcingsarma.py M /issm/trunk-jpl/test/Archives/Archive257.arch M /issm/trunk-jpl/test/Archives/Archive543.arch M /issm/trunk-jpl/test/Archives/Archive544.arch M /issm/trunk-jpl/test/NightlyRun/test257.m M /issm/trunk-jpl/test/NightlyRun/test257.py M /issm/trunk-jpl/test/NightlyRun/test543.m M /issm/trunk-jpl/test/NightlyRun/test543.py M /issm/trunk-jpl/test/NightlyRun/test544.m M /issm/trunk-jpl/test/NightlyRun/test544.py\\
+Export determination: 6. \\
+Rationale: NEW piecewise polynomials implemented in ARMA model schemes\\
+\vspace{3em}
+
+\noindent \textbf{Change \#69} with diff file ISSM-27319-27320.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/c/modules/FloatingiceMeltingRatex/FloatingiceMeltingRatex.cpp M /issm/trunk-jpl/src/c/modules/FrontalForcingsx/FrontalForcingsx.cpp M /issm/trunk-jpl/src/c/modules/SurfaceMassBalancex/SurfaceMassBalancex.cpp\\
+Export determination: 6. \\
+Rationale: BUG: fixed the assert column number for the ARMApolyparams arrays\\
+\vspace{3em}
+
+\noindent \textbf{Change \#70} with diff file ISSM-27320-27321.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/c/modules/FloatingiceMeltingRatex/FloatingiceMeltingRatex.cpp M /issm/trunk-jpl/src/c/modules/FrontalForcingsx/FrontalForcingsx.cpp M /issm/trunk-jpl/src/c/modules/SurfaceMassBalancex/SurfaceMassBalancex.cpp\\
+Export determination: 6. \\
+Rationale: BUG: fixed the assert column number for the ARMA datebreaks arrays\\
+\vspace{3em}
+
+\noindent \textbf{Change \#71} with diff file ISSM-27321-27322.diff: \\
+Function name: \\
+M /issm/trunk-jpl/test/Archives/Archive355.arch M /issm/trunk-jpl/test/Archives/Archive426.arch M /issm/trunk-jpl/test/Archives/Archive427.arch M /issm/trunk-jpl/test/Archives/Archive435.arch M /issm/trunk-jpl/test/Archives/Archive442.arch M /issm/trunk-jpl/test/Archives/Archive443.arch M /issm/trunk-jpl/test/Archives/Archive473.arch M /issm/trunk-jpl/test/Archives/Archive474.arch M /issm/trunk-jpl/test/Archives/Archive475.arch M /issm/trunk-jpl/test/Archives/Archive476.arch M /issm/trunk-jpl/test/Archives/Archive802.arch M /issm/trunk-jpl/test/Archives/Archive803.arch M /issm/trunk-jpl/test/Archives/Archive805.arch\\
+Export determination: 6. \\
+Rationale: CHG: updating archives for models that involve thermal models and GL as mesh velocity has changed slightly\\
+\vspace{3em}
+
+\noindent \textbf{Change \#72} with diff file ISSM-27322-27323.diff: \\
+Function name: \\
+M /issm/trunk-jpl/test/Archives/Archive355.arch\\
+Export determination: 6. \\
+Rationale: CHG: undo changes to SHAKTI arvhive\\
+\vspace{3em}
+
+\noindent \textbf{Change \#73} with diff file ISSM-27323-27324.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/c/analyses/SmbAnalysis.cpp M /issm/trunk-jpl/src/c/shared/Enum/EnumDefinitions.h M /issm/trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp M /issm/trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp M /issm/trunk-jpl/src/m/classes/SMBdebrisML.m M /issm/trunk-jpl/src/m/classes/debris.m M /issm/trunk-jpl/src/m/classes/model.m\\
+Export determination: 6. \\
+Rationale: CHG: some minor fixes for debris stuff\\
+\vspace{3em}
+
+\noindent \textbf{Change \#74} with diff file ISSM-27324-27325.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/m/classes/debris.m\\
+Export determination: 6. \\
+Rationale: CHG: adjust checkfield for debris spcthickness\\
+\vspace{3em}
+
+\noindent \textbf{Change \#75} with diff file ISSM-27325-27326.diff: \\
+Function name: \\
+M /issm/trunk-jpl/externalpackages/petsc/install-3.16-linux.sh M /issm/trunk-jpl/externalpackages/petsc/install-3.16-pleiades.sh\\
+Export determination: 6. \\
+Rationale: CHG: PETSc version\\
+\vspace{3em}
+
+\noindent \textbf{Change \#76} with diff file ISSM-27326-27327.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/m/classes/solidearth.m M /issm/trunk-jpl/src/m/classes/solidearth.py\\
+Export determination: 6. \\
+Rationale: CHG: python translation\\
+\vspace{3em}
+
+\noindent \textbf{Change \#77} with diff file ISSM-27327-27328.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/m/classes/fourierlove.py M /issm/trunk-jpl/src/m/classes/love.m A /issm/trunk-jpl/src/m/classes/love.py M /issm/trunk-jpl/src/m/classes/model.py M /issm/trunk-jpl/src/m/classes/sealevelmodel.py M /issm/trunk-jpl/src/m/solve/solveslm.py M /issm/trunk-jpl/test/NightlyRun/test2084.py\\
+Export determination: 6. \\
+Rationale: CHG: Python translations; cleanup\\
+\vspace{3em}
+
+\noindent \textbf{Change \#78} with diff file ISSM-27328-27329.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/m/classes/love.m\\
+Export determination: 6. \\
+Rationale: BUG: Bad copy/paste\\
+\vspace{3em}
+
+\noindent \textbf{Change \#79} with diff file ISSM-27329-27330.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/m/classes/model.py\\
+Export determination: 6. \\
+Rationale: BUG: Need to import love class\\
+\vspace{3em}
+
+\noindent \textbf{Change \#80} with diff file ISSM-27330-27331.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/m/classes/love.py\\
+Export determination: 6. \\
+Rationale: BUG: Type check\\
+\vspace{3em}
+
+\noindent \textbf{Change \#81} with diff file ISSM-27331-27332.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/m/classes/love.py\\
+Export determination: 6. \\
+Rationale: BUG: Missing attribute\\
+\vspace{3em}
+
+\noindent \textbf{Change \#82} with diff file ISSM-27332-27333.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/m/classes/love.py\\
+Export determination: 6. \\
+Rationale: BUG: Wrong mattype\\
+\vspace{3em}
+
+\noindent \textbf{Change \#83} with diff file ISSM-27333-27334.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/m/classes/love.py\\
+Export determination: 6. \\
+Rationale: BUG: Typo\\
+\vspace{3em}
+
+\noindent \textbf{Change \#84} with diff file ISSM-27334-27335.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/c/analyses/LevelsetAnalysis.cpp M /issm/trunk-jpl/src/c/classes/Elements/Element.cpp M /issm/trunk-jpl/src/c/classes/Elements/Element.h M /issm/trunk-jpl/src/c/modules/FrontalForcingsx/FrontalForcingsx.cpp M /issm/trunk-jpl/src/c/shared/Enum/Enum.vim M /issm/trunk-jpl/src/c/shared/Enum/EnumDefinitions.h M /issm/trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp M /issm/trunk-jpl/src/c/shared/Enum/Enumjl.vim M /issm/trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp M /issm/trunk-jpl/src/m/classes/frontalforcingsrignotarma.m M /issm/trunk-jpl/src/m/classes/frontalforcingsrignotarma.py M /issm/trunk-jpl/test/Archives/Archive543.arch M /issm/trunk-jpl/test/NightlyRun/test543.m M /issm/trunk-jpl/test/NightlyRun/test543.py\\
+Export determination: 6. \\
+Rationale: NEW: added seasonal capabilities in frontalforcingsrignotarma\\
+\vspace{3em}
+
+\noindent \textbf{Change \#85} with diff file ISSM-27335-27336.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/c/modules/FrontalForcingsx/FrontalForcingsx.cpp\\
+Export determination: 6. \\
+Rationale: BUG: fixing assert error\\
+\vspace{3em}
+
+\noindent \textbf{Change \#86} with diff file ISSM-27336-27337.diff: \\
+Function name: \\
+M /issm/trunk-jpl/etc/environment.sh A /issm/trunk-jpl/jenkins/eis-daskhub-python-nodules A /issm/trunk-jpl/jenkins/eis-smce-binaries A /issm/trunk-jpl/src/m/classes/clusters/eis\_nasa\_smce.py D /issm/trunk-jpl/src/m/classes/clusters/smce\_eis.py A /issm/trunk-jpl/test/NightlyRun/test101eisnasasmce.py\\
+Export determination: 6. \\
+Rationale: CHG: EIS-related commits\\
+\vspace{3em}
+
+\noindent \textbf{Change \#87} with diff file ISSM-27337-27338.diff: \\
+Function name: \\
+M /issm/trunk-jpl/test/NightlyRun/runme.py\\
+Export determination: 6. \\
+Rationale: CHG: Run with Python 3; better pattern matching for test<integer>.py\\
+\vspace{3em}
+
+\noindent \textbf{Change \#88} with diff file ISSM-27338-27339.diff: \\
+Function name: \\
+M /issm/trunk-jpl/test/NightlyRun/runme.py\\
+Export determination: 6. \\
+Rationale: CHG: Run with Python 2 for now\\
+\vspace{3em}
+
+\noindent \textbf{Change \#89} with diff file ISSM-27339-27340.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/c/classes/Elements/Tria.cpp\\
+Export determination: 6. \\
+Rationale: CHG: minor cosmetics\\
+\vspace{3em}
+
+\noindent \textbf{Change \#90} with diff file ISSM-27340-27341.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/c/cores/controltao\_core.cpp\\
+Export determination: 6. \\
+Rationale: CHG: updating TAO for new PETSc 3.18+ (untested)\\
+\vspace{3em}
+
+\noindent \textbf{Change \#91} with diff file ISSM-27341-27342.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/c/classes/Elements/Element.cpp\\
+Export determination: 6. \\
+Rationale: CHG: added error message so that anomalous values in melt rates are caught earlier\\
+\vspace{3em}
+
+\noindent \textbf{Change \#92} with diff file ISSM-27342-27343.diff: \\
+Function name: \\
+M /issm/trunk-jpl/src/c/classes/Elements/Element.cpp M /issm/trunk-jpl/src/c/modules/FrontalForcingsx/FrontalForcingsx.cpp\\
+Export determination: 6. \\
+Rationale: BUG: fixing indexing in Armaprocess\\
+\vspace{3em}
+
Index: /issm/oecreview/Archive/27230-27343/r1.tex
===================================================================
--- /issm/oecreview/Archive/27230-27343/r1.tex	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/r1.tex	(revision 27344)
@@ -0,0 +1,1 @@
+27230
Index: /issm/oecreview/Archive/27230-27343/r2.tex
===================================================================
--- /issm/oecreview/Archive/27230-27343/r2.tex	(revision 27344)
+++ /issm/oecreview/Archive/27230-27343/r2.tex	(revision 27344)
@@ -0,0 +1,1 @@
+27343
