Index: /issm/trunk-jpl/src/c/Makefile.am
===================================================================
--- /issm/trunk-jpl/src/c/Makefile.am	(revision 22624)
+++ /issm/trunk-jpl/src/c/Makefile.am	(revision 22625)
@@ -223,4 +223,5 @@
 					./modules/InputUpdateFromVectorx/InputUpdateFromVectorx.cpp\
 					./modules/FloatingiceMeltingRatex/FloatingiceMeltingRatex.cpp\
+					./modules/FloatingiceMeltingRatePicox/FloatingiceMeltingRatePicox.cpp\
 					./modules/ConfigureObjectsx/ConfigureObjectsx.cpp\
 					./modules/SpcNodesx/SpcNodesx.cpp\
Index: /issm/trunk-jpl/src/c/classes/Elements/Element.cpp
===================================================================
--- /issm/trunk-jpl/src/c/classes/Elements/Element.cpp	(revision 22624)
+++ /issm/trunk-jpl/src/c/classes/Elements/Element.cpp	(revision 22625)
@@ -2341,29 +2341,4 @@
 }
 /*}}}*/
-void       Element::PicoFloatingiceMeltingRate(){/*{{{*/
-
-	int numvertices      = this->GetNumberOfVertices();
-	IssmDouble  deepwaterel,upperwaterel,deepwatermelt;
-	IssmDouble* base     = xNew<IssmDouble>(numvertices);
-	IssmDouble* values   = xNew<IssmDouble>(numvertices);
-	IssmDouble time;
-
-	parameters->FindParam(&time,TimeEnum);
-	parameters->FindParam(&deepwaterel,BasalforcingsDeepwaterElevationEnum,time);
-	parameters->FindParam(&upperwaterel,BasalforcingsUpperwaterElevationEnum,time);
-	parameters->FindParam(&deepwatermelt,BasalforcingsDeepwaterMeltingRateEnum,time);
-
-	this->GetInputListOnVertices(base,BaseEnum);
-	for(int i=0;i<numvertices;i++){
-		if(base[i]>upperwaterel)      values[i]=0;
-		else if (base[i]<deepwaterel) values[i]=deepwatermelt;
-		else values[i]=deepwatermelt*(base[i]-upperwaterel)/(deepwaterel-upperwaterel);
-	}
-
-	this->AddInput(BasalforcingsFloatingiceMeltingRateEnum,values,P1Enum);
-	xDelete<IssmDouble>(base);
-	xDelete<IssmDouble>(values);
-
-}/*}}}*/
 void       Element::PositiveDegreeDay(IssmDouble* pdds,IssmDouble* pds,IssmDouble signorm,bool ismungsm,bool issetpddfac){/*{{{*/
 
Index: /issm/trunk-jpl/src/c/classes/Elements/Element.h
===================================================================
--- /issm/trunk-jpl/src/c/classes/Elements/Element.h	(revision 22624)
+++ /issm/trunk-jpl/src/c/classes/Elements/Element.h	(revision 22625)
@@ -142,5 +142,4 @@
 		ElementMatrix*     NewElementMatrixCoupling(int number_nodes,int approximation_enum=NoneApproximationEnum);
 		ElementVector*     NewElementVector(int approximation_enum=NoneApproximationEnum);
-		void					 PicoFloatingiceMeltingRate();
 		void               PositiveDegreeDay(IssmDouble* pdds,IssmDouble* pds,IssmDouble signorm,bool ismungsm,bool issetpddfac);
 		IssmDouble         PureIceEnthalpy(IssmDouble pressure);
@@ -213,4 +212,5 @@
 		virtual Element*   GetBasalElement(void)=0;
 		virtual int        GetElementType(void)=0;
+		virtual IssmDouble GetHorizontalSurfaceArea(void){_error_("not implemented");};
 		virtual void       GetGroundedPart(int* point1,IssmDouble* fraction1,IssmDouble* fraction2, bool* mainlyfloating)=0;
 		virtual IssmDouble GetGroundedPortion(IssmDouble* xyz_list)=0;
@@ -278,5 +278,6 @@
 		virtual int        NumberofNodesVelocity(void)=0;
 		virtual void       PicoUpdateBoxid(int* pmax_boxid_basin)=0;
-		virtual void       PicoUpdateFirstBox(void){_error_("not implemented");};
+		virtual void       PicoUpdateFirstBox()=0;
+		virtual void       PicoUpdateNextBox(int loopboxid)=0;
 		virtual void       PotentialUngrounding(Vector<IssmDouble>* potential_sheet_ungrounding)=0;
 		virtual int        PressureInterpolation()=0;
Index: /issm/trunk-jpl/src/c/classes/Elements/Penta.h
===================================================================
--- /issm/trunk-jpl/src/c/classes/Elements/Penta.h	(revision 22624)
+++ /issm/trunk-jpl/src/c/classes/Elements/Penta.h	(revision 22625)
@@ -140,4 +140,6 @@
 		int            NumberofNodesVelocity(void);
 		void				PicoUpdateBoxid(int* pmax_boxid_basin){_error_("not implemented yet");};
+		void				PicoUpdateFirstBox(){_error_("not implemented yet");};
+		void				PicoUpdateNextBox(int loopboxid){_error_("not implemented yet");};
 		void           PotentialUngrounding(Vector<IssmDouble>* potential_sheet_ungrounding);
 		int            PressureInterpolation();
Index: /issm/trunk-jpl/src/c/classes/Elements/Seg.h
===================================================================
--- /issm/trunk-jpl/src/c/classes/Elements/Seg.h	(revision 22624)
+++ /issm/trunk-jpl/src/c/classes/Elements/Seg.h	(revision 22625)
@@ -129,4 +129,6 @@
 		int         NumberofNodesVelocity(void){_error_("not implemented yet");};
 		void        PicoUpdateBoxid(int* pmax_boxid_basin){_error_("not implemented yet");};
+		void			PicoUpdateFirstBox(){_error_("not implemented yet");};
+		void			PicoUpdateNextBox(int loopboxid){_error_("not implemented yet");};
 		void        PotentialUngrounding(Vector<IssmDouble>* potential_sheet_ungrounding){_error_("not implemented yet");};
 		int         PressureInterpolation(void){_error_("not implemented yet");};
Index: /issm/trunk-jpl/src/c/classes/Elements/Tetra.h
===================================================================
--- /issm/trunk-jpl/src/c/classes/Elements/Tetra.h	(revision 22624)
+++ /issm/trunk-jpl/src/c/classes/Elements/Tetra.h	(revision 22625)
@@ -137,4 +137,6 @@
 		int         NumberofNodesVelocity(void);
 		void			PicoUpdateBoxid(int* pmax_boxid_basin){_error_("not implemented yet");};	
+		void			PicoUpdateFirstBox(){_error_("not implemented yet");};
+		void			PicoUpdateNextBox(int loopboxid){_error_("not implemented yet");};
 		void        PotentialUngrounding(Vector<IssmDouble>* potential_sheet_ungrounding){_error_("not implemented yet");};
 		int         PressureInterpolation(void);
Index: /issm/trunk-jpl/src/c/classes/Elements/Tria.cpp
===================================================================
--- /issm/trunk-jpl/src/c/classes/Elements/Tria.cpp	(revision 22624)
+++ /issm/trunk-jpl/src/c/classes/Elements/Tria.cpp	(revision 22625)
@@ -1107,4 +1107,9 @@
 	_assert_(x2*y3 - y2*x3 + x1*y2 - y1*x2 + x3*y1 - y3*x1>0);
 	return (x2*y3 - y2*x3 + x1*y2 - y1*x2 + x3*y1 - y3*x1)/2;
+}
+/*}}}*/
+IssmDouble Tria::GetHorizontalSurfaceArea(void){/*{{{*/
+
+	return this->GetArea();
 }
 /*}}}*/
@@ -2776,32 +2781,36 @@
 	if(!this->IsIceInElement() || !this->IsFloating()) return;
 
-	//Load inputs and params
-	int i, boxid;
-	int basin_id, boxid_max;
-	IssmDouble dist_gl;
-	IssmDouble dist_cf;
-	IssmDouble rel_dist_gl;
+	int i,boxid,basin_id,boxid_max;
+	IssmDouble dist_gl,dist_cf,rel_dist_gl,lowbound,highbound;
 
 	inputs->GetInputValue(&basin_id,BasalforcingsPicoBasinIdEnum);
-	boxid_max=pmax_boxid_basin[basin_id]; //0-based
-
-	Input* dist_gl_input=NULL;
-	Input* dist_cf_input=NULL;
-	dist_gl_input=inputs->GetInput(DistanceToGroundinglineEnum); _assert_(dist_gl_input);
-	dist_cf_input=inputs->GetInput(DistanceToCalvingfrontEnum); _assert_(dist_cf_input);
-
+	boxid_max=pmax_boxid_basin[basin_id]; 
+
+	Input* dist_gl_input=inputs->GetInput(DistanceToGroundinglineEnum); _assert_(dist_gl_input);
+	Input* dist_cf_input=inputs->GetInput(DistanceToCalvingfrontEnum); _assert_(dist_cf_input);
+
+	/*Get dist_gl and dist_cf at center of element*/
 	Gauss* gauss=this->NewGauss(1); gauss->GaussPoint(0);
 	dist_gl_input->GetInputValue(&dist_gl,gauss);
 	dist_cf_input->GetInputValue(&dist_cf,gauss);
-
+	
+	/*Ensure values are positive for floating ice*/
+	if(dist_gl<0){dist_gl=dist_gl*(-1);}
+	if(dist_cf<0){dist_cf=dist_cf*(-1);}
+
+	/*Compute relative distance to grounding line*/
 	rel_dist_gl=dist_gl/(dist_gl+dist_cf);
 
+	/*Assign box numbers based on rel_dist_gl*/
 	boxid=-1;
 	for(i=0;i<boxid_max;i++){
-		if(rel_dist_gl>=(1-sqrt((boxid_max-i)/boxid_max)) && rel_dist_gl<=(1-sqrt((boxid_max-i-1)/boxid_max))){
-			boxid=i; break;
-		}
-	}
-	if(boxid==-1){_error_("no boxid found for element" << this->Sid());}
+		lowbound = 1-sqrt((boxid_max-i-0.0)/boxid_max);
+		highbound = 1-sqrt((boxid_max-i-1.0)/boxid_max);
+		if(rel_dist_gl>=lowbound && rel_dist_gl<=highbound){
+			boxid=i;
+			break;
+		}
+	}
+	if(boxid==-1){_error_("No boxid found for element " << this->Sid() << "!");}
 
 	this->inputs->AddInput(new IntInput(BasalforcingsPicoBoxIdEnum, boxid));	
@@ -2813,58 +2822,177 @@
 void       Tria::PicoUpdateFirstBox(){/*{{{*/
 
-	IssmDouble rhoi, rhow, earth_grav, rho_star, nu, latentheat, c_p_ocean, lambda, a, b, c;
-	IssmDouble alpha, Beta, gamma_T, overturning_coeff, t_farocean, s_farocean;
-	IssmDouble basinid, boxid, thickness, toc_farocean, soc_farocean, area_box1;
-	IssmDouble pressure, T_star, g1, s1, p_coeff, q_coeff, Toc, Soc, potential_pressure_melting_point;
-	IssmDouble basalmeltrate_shelf, overturning, maxbox;
-
-	//Get variables
+	if(!this->IsIceInElement() || !this->IsFloating()) return;
+
+	int boxid;
+	this->inputs->GetInputValue(&boxid,BasalforcingsPicoBoxIdEnum);
+	if(!boxid==0) return;
+
+	int basinid, maxbox, num_basins, numnodes, M;
+	IssmDouble time, rhoi, rhow, earth_grav, rho_star, nu, latentheat, c_p_ocean, lambda, a, b, c;
+	IssmDouble alpha, Beta, gamma_T, overturning_coeff;
+	IssmDouble thickness, toc_farocean, soc_farocean, area_box1;
+	IssmDouble pressure, T_star, g1, s1, p_coeff, q_coeff;
+	IssmDouble* boxareas=NULL;
+	IssmDouble* t_farocean=NULL;
+	IssmDouble* s_farocean=NULL;
+
+	/*Get variables*/
 	rhoi			= this->GetMaterialParameter(MaterialsRhoIceEnum);
 	rhow			= this->GetMaterialParameter(MaterialsRhoSeawaterEnum);
 	earth_grav  = this->GetMaterialParameter(ConstantsGEnum);
-	rho_star		= 1033.;             //kg/m^3
+	rho_star		= 1033.;             // kg/m^3
 	nu				= rhoi/rhow;
 	latentheat	= this->GetMaterialParameter(MaterialsLatentheatEnum);
-	c_p_ocean	= this->GetMaterialParameter(MaterialsThermalExchangeVelocityEnum);
+	c_p_ocean	= this->GetMaterialParameter(MaterialsMixedLayerCapacityEnum);
 	lambda		= latentheat/c_p_ocean;
-	a				= -0.0572;          //K/psu
+	a				= -0.0572;           // K/psu
 	b				= 0.0788 + this->GetMaterialParameter(MaterialsMeltingpointEnum);  //K
-	c				= this->GetMaterialParameter(MaterialsBetaEnum);
-	alpha			= 0.000075;         //1/K
-	Beta			= 0.00077;          //K
-
+	c           = 7.77e-4;
+	alpha			= 7.5e-5;            // 1/K
+	Beta			= 7.7e-4;            // K
+
+	/* Get parameters and inputs */
+	this->parameters->FindParam(&time,TimeEnum);
+	this->parameters->FindParam(&num_basins, BasalforcingsPicoNumBasinsEnum);
 	this->parameters->FindParam(&gamma_T,BasalforcingsPicoGammaTEnum);
 	this->parameters->FindParam(&overturning_coeff,BasalforcingsPicoOverturningCoeffEnum);
-	this->parameters->FindParam(&t_farocean,BasalforcingsPicoFarOceansalinityEnum);
-	this->parameters->FindParam(&s_farocean,BasalforcingsPicoFarOceansalinityEnum);
-
+	this->parameters->FindParam(&t_farocean, &num_basins, time, BasalforcingsPicoFarOceantemperatureEnum);
+	this->parameters->FindParam(&s_farocean, &num_basins, time, BasalforcingsPicoFarOceansalinityEnum);
+	this->parameters->FindParam(&maxbox,BasalforcingsPicoMaxboxcountEnum);
+	M = num_basins*maxbox;
+	this->parameters->FindParam(&boxareas,&M,BasalforcingsPicoBoxAreaEnum);
 	this->inputs->GetInputValue(&basinid,BasalforcingsPicoBasinIdEnum);
+	
+	Input* thickness_input=this->GetInput(ThicknessEnum); _assert_(thickness_input);
+
+	toc_farocean							= t_farocean[basinid];
+	soc_farocean							= s_farocean[basinid];
+	area_box1								= boxareas[basinid*maxbox+boxid];
+	g1											= area_box1*gamma_T;
+	s1											= soc_farocean/(nu*lambda);
+
+   IssmDouble basalmeltrates_shelf[NUMVERTICES];
+	IssmDouble potential_pressure_melting_point[NUMVERTICES];   
+	IssmDouble Tocs[NUMVERTICES];							
+   IssmDouble Socs[NUMVERTICES];
+   IssmDouble overturnings[NUMVERTICES];
+
+	/* Start looping on the number of nodes and calculate ocean vars */
+	Gauss* gauss=this->NewGauss();
+	for (int i=0;i<NUMVERTICES;i++){
+		gauss->GaussVertex(i);
+		thickness_input->GetInputValue(&thickness,gauss);
+		pressure = (rhoi*earth_grav*1e-4)*thickness;
+		T_star = a*soc_farocean+b-c*pressure-toc_farocean;
+		p_coeff = g1/(overturning_coeff*rho_star*(Beta*s1-alpha));
+		q_coeff = T_star*(g1/(overturning_coeff*rho_star*(Beta*s1-alpha)));
+
+		/* To avoid negatives under the square root */
+		if ((0.25*pow(p_coeff,2)-q_coeff)<0){
+			q_coeff = (0.25*pow(p_coeff,2));
+		}
+
+		Tocs[i] = toc_farocean-(-0.5*p_coeff+sqrt(0.25*pow(p_coeff,2)-q_coeff));
+		Socs[i] = soc_farocean-(soc_farocean/(nu*lambda))*(toc_farocean-Tocs[i]);
+		potential_pressure_melting_point[i] = a*Socs[i]+b-c*pressure;
+		basalmeltrates_shelf[i] = (-gamma_T/(nu*lambda))*(potential_pressure_melting_point[i]-Tocs[i]);
+		overturnings[i] = overturning_coeff*rho_star*(Beta*(soc_farocean-Socs[i])-alpha*(toc_farocean-Tocs[i]));
+	}
+
+	this->AddInput(BasalforcingsFloatingiceMeltingRateEnum,basalmeltrates_shelf,P1Enum);
+	this->AddInput(BasalforcingsPicoSubShelfOceanTempEnum,Tocs,P1Enum);
+	this->AddInput(BasalforcingsPicoSubShelfOceanSalinityEnum,Socs,P1Enum);
+	this->AddInput(BasalforcingsPicoSubShelfOceanOverturningEnum,overturnings,P1Enum);
+
+	/*Cleanup and return */
+	delete gauss;
+	xDelete<IssmDouble>(t_farocean);
+	xDelete<IssmDouble>(s_farocean);
+	xDelete<IssmDouble>(boxareas);
+}
+/*}}}*/
+void       Tria::PicoUpdateNextBox(int loopboxid){/*{{{*/	
+
+	if(!this->IsIceInElement() || !this->IsFloating()) return;
+	
+	int boxid;
 	this->inputs->GetInputValue(&boxid,BasalforcingsPicoBoxIdEnum);
-	this->inputs->GetInputValue(&maxbox,BasalforcingsPicoMaxboxcountEnum);
-	this->inputs->GetInputValue(&thickness,ThicknessEnum);
-
-	_error_("to be continued");
-	/*
-
-	toc_farocean = t_farocean[basinid];
-	soc_farocean = s_farocean[basinid];
-	area_box1 = areas[basinid*maxbox+boxid];
-	pressure = (rhoi*earth_grav)*thickness;
-	T_star = a*soc_farocean+b-c*pressure-toc_farocean;
-	g1 = area_box1*gamma_T;
-	s1 = soc_farocean/(nu*lambda);
-	p_coeff = g1/(overturning_coeff*rho_star*(Beta*s1-alpha));
-	q_coeff = T_star*(g1/(overturning_coeff*rho_star*(Beta*s1-alpha)));
-	if ((0.25*(p_coeff)^(2) - q_coeff) < 0)
-	  {q_coeff = (0.25*(p_coeff)^(2))}
-	Toc = toc_farocean-(-0.5*p_coeff+sqrt(0.25*p_coeff^(2)-q_coeff));
-	Soc = soc_farocean-(soc_farocean/(nu*lambda))*(toc_farocean-Toc);
-	potential_pressure_melting_point = a*Soc+b-c*pressure;
-	basalmeltrate_shelf = (-gamma_T/(nu*lambda))*(potential_pressure_melting_point-Toc);
-	overturning = overturning_coeff*rho_star*(Beta*(soc_farocean-Soc)-alpha*(toc_farocean-Toc));
-
-	this->AddInput(BasalforcingsGroundediceMeltingRateEnum,basalmeltingrates,this->GetElementType());
-	*/
-
+	if(loopboxid!=boxid) return;
+
+	int basinid, maxbox, num_basins, numnodes,M;
+	IssmDouble rhoi, rhow, earth_grav, rho_star, nu, latentheat, c_p_ocean, lambda, a, b, c;
+	IssmDouble alpha, Beta, gamma_T, overturning_coeff;
+	IssmDouble thickness, toc_farocean, soc_farocean, area_boxi;
+	IssmDouble mean_toc,mean_soc,mean_overturning;
+	IssmDouble pressure, T_star, g1, g2, p_coeff, q_coeff;
+	IssmDouble* toc_weighted_avg=NULL;
+	IssmDouble* soc_weighted_avg=NULL;
+	IssmDouble* overturning_weighted_avg=NULL;
+	IssmDouble* boxareas=NULL;
+
+	/*Get variables*/
+	rhoi        = this->GetMaterialParameter(MaterialsRhoIceEnum);
+	rhow        = this->GetMaterialParameter(MaterialsRhoSeawaterEnum);
+	earth_grav  = this->GetMaterialParameter(ConstantsGEnum);
+	rho_star    = 1033.;             // kg/m^3
+	nu          = rhoi/rhow;
+	latentheat  = this->GetMaterialParameter(MaterialsLatentheatEnum);
+	c_p_ocean   = this->GetMaterialParameter(MaterialsMixedLayerCapacityEnum);
+	lambda      = latentheat/c_p_ocean;
+	a           = -0.0572;          // K/psu
+	b           = 0.0788 + this->GetMaterialParameter(MaterialsMeltingpointEnum);  //K
+	c           = 7.77e-4;
+	alpha       = 7.5e-5;           // 1/K
+	Beta        = 7.7e-4;           // K
+
+	/* Get parameters and inputs */
+	this->parameters->FindParam(&num_basins, BasalforcingsPicoNumBasinsEnum);
+	this->parameters->FindParam(&gamma_T,BasalforcingsPicoGammaTEnum);
+	this->parameters->FindParam(&overturning_coeff,BasalforcingsPicoOverturningCoeffEnum);
+	this->parameters->FindParam(&maxbox,BasalforcingsPicoMaxboxcountEnum);
+	this->parameters->FindParam(&toc_weighted_avg,&num_basins,BasalforcingsPicoAverageTemperatureEnum);
+	this->parameters->FindParam(&soc_weighted_avg,&num_basins,BasalforcingsPicoAverageSalinityEnum);
+	this->parameters->FindParam(&overturning_weighted_avg,&num_basins,BasalforcingsPicoAverageOverturningEnum);
+	M=num_basins*maxbox;
+	this->parameters->FindParam(&boxareas,&M,BasalforcingsPicoBoxAreaEnum);
+	this->inputs->GetInputValue(&basinid,BasalforcingsPicoBasinIdEnum);
+
+   Input* thickness_input=this->GetInput(ThicknessEnum); _assert_(thickness_input);
+
+	area_boxi								= boxareas[basinid*maxbox+boxid];
+   mean_toc									= toc_weighted_avg[basinid];
+	mean_soc									= soc_weighted_avg[basinid];
+	mean_overturning						= overturning_weighted_avg[basinid];
+	g1											= area_boxi*gamma_T;
+   g2											= g2/(nu*lambda);
+
+	IssmDouble basalmeltrates_shelf[NUMVERTICES];
+	IssmDouble potential_pressure_melting_point[NUMVERTICES];   
+	IssmDouble Tocs[NUMVERTICES];							
+   IssmDouble Socs[NUMVERTICES];
+
+	/* Start looping on the number of nodes and calculate ocean vars */
+	Gauss* gauss=this->NewGauss();
+	for (int i=0;i<NUMVERTICES;i++){
+		gauss->GaussVertex(i);
+		thickness_input->GetInputValue(&thickness,gauss);
+		pressure = (rhoi*earth_grav*1e-4)*thickness;
+		T_star = a*mean_soc+b-c*pressure-mean_toc;
+		Tocs[i] = mean_toc+T_star*(g1/(mean_overturning+g1-g2*a*mean_soc));
+		Socs[i] = mean_soc-mean_soc*((mean_toc-Tocs[i])/(nu*lambda));
+		potential_pressure_melting_point[i] = a*Socs[i]+b-c*pressure;
+		basalmeltrates_shelf[i] = (-gamma_T/(nu*lambda))*(potential_pressure_melting_point[i]-Tocs[i]);
+	}
+
+	this->AddInput(BasalforcingsFloatingiceMeltingRateEnum,basalmeltrates_shelf,P1Enum);
+	this->AddInput(BasalforcingsPicoSubShelfOceanTempEnum,Tocs,P1Enum);
+	this->AddInput(BasalforcingsPicoSubShelfOceanSalinityEnum,Socs,P1Enum);
+
+	/*Cleanup and return */
+	delete gauss;
+	xDelete<IssmDouble>(boxareas);
+	xDelete<IssmDouble>(toc_weighted_avg);
+	xDelete<IssmDouble>(soc_weighted_avg);
+	xDelete<IssmDouble>(overturning_weighted_avg);
 }
 /*}}}*/
@@ -3720,4 +3848,10 @@
 	if(minvalue>fieldvalue || maxvalue<fieldvalue) return;
 
+	/* check #2: If only one vertex is on fieldvalue, there is no segment here */
+	IssmDouble lsf[NUMVERTICES];
+	this->GetInputListOnVertices(&lsf[0],fieldenum);
+	int nrice=0;       
+	for(int i=0;i<NUMVERTICES;i++) if(lsf[i]==fieldvalue) nrice++;
+	if(nrice==1) return;
 
 	/*2. Write segments*/
Index: /issm/trunk-jpl/src/c/classes/Elements/Tria.h
===================================================================
--- /issm/trunk-jpl/src/c/classes/Elements/Tria.h	(revision 22624)
+++ /issm/trunk-jpl/src/c/classes/Elements/Tria.h	(revision 22625)
@@ -111,5 +111,6 @@
 		int         NumberofNodesVelocity(void);
 		void        PicoUpdateBoxid(int* pmax_boxid_basin);
-		void        PicoUpdateFirstBox(void);
+		void        PicoUpdateFirstBox();
+		void        PicoUpdateNextBox(int loopboxid);
 		void        PotentialUngrounding(Vector<IssmDouble>* potential_sheet_ungrounding);
 		int         PressureInterpolation();
@@ -165,4 +166,5 @@
 		void           DatasetInputCreate(IssmDouble* array,int M,int N,int* individual_enums,int num_inputs,IoModel* iomodel,int input_enum);
 		IssmDouble     GetArea(void);
+		IssmDouble     GetHorizontalSurfaceArea(void);
 		IssmDouble 	   GetArea3D(void);
 		IssmDouble 	   GetAreaIce(void);
Index: /issm/trunk-jpl/src/c/classes/Params/BoolParam.h
===================================================================
--- /issm/trunk-jpl/src/c/classes/Params/BoolParam.h	(revision 22624)
+++ /issm/trunk-jpl/src/c/classes/Params/BoolParam.h	(revision 22625)
@@ -45,4 +45,5 @@
 		void  GetParameterValue(IssmDouble* pIssmDouble){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a IssmDouble");}
 		void  GetParameterValue(IssmDouble* pdouble,IssmDouble time){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a IssmDouble for a given time");}
+		void  GetParameterValue(IssmDouble** pIssmDoublearray,int* pM, IssmDouble time){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a IssmDoubleArray for a given time");}
 		void  GetParameterValue(char** pstring){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a string");}
 		void  GetParameterValue(char*** pstringarray,int* pM){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a string array");}
Index: /issm/trunk-jpl/src/c/classes/Params/DataSetParam.h
===================================================================
--- /issm/trunk-jpl/src/c/classes/Params/DataSetParam.h	(revision 22624)
+++ /issm/trunk-jpl/src/c/classes/Params/DataSetParam.h	(revision 22625)
@@ -46,4 +46,5 @@
 		void  GetParameterValue(IssmDouble* pIssmDouble){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a IssmDouble");}
 		void  GetParameterValue(IssmDouble* pdouble,IssmDouble time){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a IssmDouble for a given time");}
+		void  GetParameterValue(IssmDouble** pIssmDoublearray,int* pM, IssmDouble time){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a IssmDoubleArray for a given time");}
 		void  GetParameterValue(FILE** pfile){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a file pointer");}
 		void  GetParameterValue(char** pstring){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a string");}
Index: /issm/trunk-jpl/src/c/classes/Params/DoubleMatArrayParam.h
===================================================================
--- /issm/trunk-jpl/src/c/classes/Params/DoubleMatArrayParam.h	(revision 22624)
+++ /issm/trunk-jpl/src/c/classes/Params/DoubleMatArrayParam.h	(revision 22625)
@@ -48,4 +48,5 @@
 		void  GetParameterValue(IssmDouble* pIssmDouble){_error_("Param "<< EnumToStringx(enum_type) << "cannot return a IssmDouble");}
 		void  GetParameterValue(IssmDouble* pdouble,IssmDouble time){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a IssmDouble for a given time");}
+		void  GetParameterValue(IssmDouble** pIssmDoublearray,int* pM, IssmDouble time){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a IssmDoubleArray for a given time");}
 		void  GetParameterValue(char** pstring){_error_("Param "<< EnumToStringx(enum_type) << "cannot return a string");}
 		void  GetParameterValue(char*** pstringarray,int* pM){_error_("Param "<< EnumToStringx(enum_type) << "cannot return a string array");}
Index: /issm/trunk-jpl/src/c/classes/Params/DoubleMatParam.h
===================================================================
--- /issm/trunk-jpl/src/c/classes/Params/DoubleMatParam.h	(revision 22624)
+++ /issm/trunk-jpl/src/c/classes/Params/DoubleMatParam.h	(revision 22625)
@@ -48,4 +48,5 @@
 		void  GetParameterValue(IssmDouble* pIssmDouble){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a IssmDouble");}
 		void  GetParameterValue(IssmDouble* pdouble,IssmDouble time){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a IssmDouble for a given time");}
+		void  GetParameterValue(IssmDouble** pIssmDoublearray,int* pM, IssmDouble time){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a IssmDoubleArray for a given time");}
 		void  GetParameterValue(char** pstring){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a string");}
 		void  GetParameterValue(char*** pstringarray,int* pM){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a string array");}
Index: /issm/trunk-jpl/src/c/classes/Params/DoubleParam.h
===================================================================
--- /issm/trunk-jpl/src/c/classes/Params/DoubleParam.h	(revision 22624)
+++ /issm/trunk-jpl/src/c/classes/Params/DoubleParam.h	(revision 22625)
@@ -45,6 +45,7 @@
 		void  GetParameterValue(int** pintarray,int* pM,int* pN);
 		void  GetParameterValue(IssmDouble* pIssmDouble){*pIssmDouble=value;}
+		void  GetParameterValue(IssmDouble* pdouble,IssmDouble time){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a IssmDouble for a given time");}
+		void  GetParameterValue(IssmDouble** pIssmDoublearray,int* pM, IssmDouble time){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a IssmDoubleArray for a given time");}
 		void  GetParameterValue(char** pstring){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a string");}
-		void  GetParameterValue(IssmDouble* pdouble,IssmDouble time){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a IssmDouble for a given time");}
 		void  GetParameterValue(char*** pstringarray,int* pM){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a string array");}
 		void  GetParameterValue(IssmDouble** pIssmDoublearray,int* pM);
Index: /issm/trunk-jpl/src/c/classes/Params/DoubleVecParam.h
===================================================================
--- /issm/trunk-jpl/src/c/classes/Params/DoubleVecParam.h	(revision 22624)
+++ /issm/trunk-jpl/src/c/classes/Params/DoubleVecParam.h	(revision 22625)
@@ -46,4 +46,5 @@
 		void  GetParameterValue(IssmDouble* pIssmDouble){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a IssmDouble");}
 		void  GetParameterValue(IssmDouble* pdouble,IssmDouble time){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a IssmDouble for a given time");}
+		void  GetParameterValue(IssmDouble** pIssmDoublearray,int* pM, IssmDouble time){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a IssmDoubleArray for a given time");}
 		void  GetParameterValue(char** pstring){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a string");}
 		void  GetParameterValue(char*** pstringarray,int* pM){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a string array");}
Index: /issm/trunk-jpl/src/c/classes/Params/FileParam.h
===================================================================
--- /issm/trunk-jpl/src/c/classes/Params/FileParam.h	(revision 22624)
+++ /issm/trunk-jpl/src/c/classes/Params/FileParam.h	(revision 22625)
@@ -45,4 +45,5 @@
 		void  GetParameterValue(IssmDouble* pIssmDouble){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a IssmDouble");}
 		void  GetParameterValue(IssmDouble* pdouble,IssmDouble time){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a IssmDouble for a given time");}
+		void  GetParameterValue(IssmDouble** pIssmDoublearray,int* pM, IssmDouble time){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a IssmDoubleArray for a given time");}
 		void  GetParameterValue(char** pstring){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a string");}
 		void  GetParameterValue(char*** pstringarray,int* pM){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a string array");}
Index: /issm/trunk-jpl/src/c/classes/Params/GenericParam.h
===================================================================
--- /issm/trunk-jpl/src/c/classes/Params/GenericParam.h	(revision 22624)
+++ /issm/trunk-jpl/src/c/classes/Params/GenericParam.h	(revision 22625)
@@ -71,4 +71,5 @@
                 void  GetParameterValue(IssmDouble* pIssmDouble){_error_("Param "<< EnumToStringx(myEnumVal) << " cannot return a IssmDouble");}
                 void  GetParameterValue(IssmDouble* pdouble,IssmDouble time){_error_("Param "<< EnumToStringx(myEnumVal) << " cannot return a IssmDouble for a given time");}
+					 void  GetParameterValue(IssmDouble** pIssmDoublearray,int* pM, IssmDouble time){_error_("Param "<< EnumToStringx(myEnumVal) << " cannot return a IssmDoubleArray for a given time");}
                 void  GetParameterValue(char** pstring){_error_("Param "<< EnumToStringx(myEnumVal) << " cannot return a string");}
                 void  GetParameterValue(char*** pstringarray,int* pM){_error_("Param "<< EnumToStringx(myEnumVal) << " cannot return a string array");}
Index: /issm/trunk-jpl/src/c/classes/Params/IntMatParam.h
===================================================================
--- /issm/trunk-jpl/src/c/classes/Params/IntMatParam.h	(revision 22624)
+++ /issm/trunk-jpl/src/c/classes/Params/IntMatParam.h	(revision 22625)
@@ -47,4 +47,5 @@
 		void  GetParameterValue(IssmDouble* pIssmDouble){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a IssmDouble");}
 		void  GetParameterValue(IssmDouble* pdouble,IssmDouble time){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a IssmDouble for a given time");}
+		void  GetParameterValue(IssmDouble** pIssmDoublearray,int* pM, IssmDouble time){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a IssmDoubleArray for a given time");}
 		void  GetParameterValue(char** pstring){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a string");}
 		void  GetParameterValue(char*** pstringarray,int* pM){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a string array");}
Index: /issm/trunk-jpl/src/c/classes/Params/IntParam.h
===================================================================
--- /issm/trunk-jpl/src/c/classes/Params/IntParam.h	(revision 22624)
+++ /issm/trunk-jpl/src/c/classes/Params/IntParam.h	(revision 22625)
@@ -39,5 +39,5 @@
 		int   ObjectEnum();
 		/*}}}*/
-		/*Param vritual function definitions: {{{*/
+		/*Param virtual function definitions: {{{*/
 		void  GetParameterValue(bool* pbool){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a bool");}
 		void  GetParameterValue(int* pinteger){*pinteger=value;}
@@ -46,4 +46,5 @@
 		void  GetParameterValue(IssmDouble* pIssmDouble){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a IssmDouble");}
 		void  GetParameterValue(IssmDouble* pdouble,IssmDouble time){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a IssmDouble for a given time");}
+		void  GetParameterValue(IssmDouble** pIssmDoublearray,int* pM, IssmDouble time){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a IssmDoubleArray for a given time");}
 		void  GetParameterValue(char** pstring){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a string");}
 		void  GetParameterValue(char*** pstringarray,int* pM){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a string array");}
Index: /issm/trunk-jpl/src/c/classes/Params/IntVecParam.h
===================================================================
--- /issm/trunk-jpl/src/c/classes/Params/IntVecParam.h	(revision 22624)
+++ /issm/trunk-jpl/src/c/classes/Params/IntVecParam.h	(revision 22625)
@@ -47,4 +47,5 @@
 		void  GetParameterValue(IssmDouble* pIssmDouble){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a IssmDouble");}
 		void  GetParameterValue(IssmDouble* pdouble,IssmDouble time){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a IssmDouble for a given time");}
+		void  GetParameterValue(IssmDouble** pIssmDoublearray,int* pM, IssmDouble time){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a IssmDoubleArray for a given time");}
 		void  GetParameterValue(char** pstring){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a string");}
 		void  GetParameterValue(char*** pstringarray,int* pM){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a string array");}
Index: /issm/trunk-jpl/src/c/classes/Params/MatrixParam.h
===================================================================
--- /issm/trunk-jpl/src/c/classes/Params/MatrixParam.h	(revision 22624)
+++ /issm/trunk-jpl/src/c/classes/Params/MatrixParam.h	(revision 22625)
@@ -46,4 +46,5 @@
 		void  GetParameterValue(IssmDouble* pIssmDouble){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a IssmDouble");}
 		void  GetParameterValue(IssmDouble* pdouble,IssmDouble time){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a IssmDouble for a given time");}
+		void  GetParameterValue(IssmDouble** pIssmDoublearray,int* pM, IssmDouble time){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a IssmDoubleArray for a given time");}
 		void  GetParameterValue(char** pstring){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a string");}
 		void  GetParameterValue(char*** pstringarray,int* pM){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a string array");}
Index: /issm/trunk-jpl/src/c/classes/Params/Param.h
===================================================================
--- /issm/trunk-jpl/src/c/classes/Params/Param.h	(revision 22624)
+++ /issm/trunk-jpl/src/c/classes/Params/Param.h	(revision 22625)
@@ -34,4 +34,5 @@
 		virtual void  GetParameterValue(IssmDouble* pIssmDouble)=0;
 		virtual void  GetParameterValue(IssmDouble* pdouble,IssmDouble time)=0;
+		virtual void  GetParameterValue(IssmDouble** pIssmDoublearray,int* pM, IssmDouble time)=0;
 		virtual void  GetParameterValue(char** pstring)=0;
 		virtual void  GetParameterValue(char*** pstringarray,int* pM)=0;
Index: /issm/trunk-jpl/src/c/classes/Params/Parameters.cpp
===================================================================
--- /issm/trunk-jpl/src/c/classes/Params/Parameters.cpp	(revision 22624)
+++ /issm/trunk-jpl/src/c/classes/Params/Parameters.cpp	(revision 22625)
@@ -300,4 +300,14 @@
 }
 /*}}}*/
+void Parameters::FindParam(IssmDouble** pIssmDoublearray, int* pM, IssmDouble time, int param_enum){ _assert_(this);/*{{{*/
+
+	_assert_(param_enum>ParametersSTARTEnum);
+	_assert_(param_enum<ParametersENDEnum);
+
+	int index = param_enum - ParametersSTARTEnum -1;
+	if(!this->params[index]) _error_("Parameter " << EnumToStringx(param_enum) <<" not set");
+	this->params[index]->GetParameterValue(pIssmDoublearray, pM, time);
+}
+/*}}}*/
 void Parameters::FindParam(char** pstring,int param_enum){ _assert_(this);/*{{{*/
 
@@ -349,6 +359,8 @@
 
 	int index = param_enum - ParametersSTARTEnum -1;
+
 	if(!this->params[index]) _error_("Parameter " << EnumToStringx(param_enum) <<" not set");
 	this->params[index]->GetParameterValue(pIssmDoublearray,pM);
+
 }
 /*}}}*/
Index: /issm/trunk-jpl/src/c/classes/Params/Parameters.h
===================================================================
--- /issm/trunk-jpl/src/c/classes/Params/Parameters.h	(revision 22624)
+++ /issm/trunk-jpl/src/c/classes/Params/Parameters.h	(revision 22625)
@@ -40,4 +40,5 @@
 		void  FindParam(IssmDouble* pscalar, int enum_type);
 		void  FindParam(IssmDouble* pscalar, int enum_type,IssmDouble time);
+		void	FindParam(IssmDouble** pIssmDoublearray, int* pM, IssmDouble time, int enum_type);
 		void  FindParam(char** pstring,int enum_type);
 		void  FindParam(char*** pstringarray,int* pM,int enum_type);
Index: /issm/trunk-jpl/src/c/classes/Params/StringArrayParam.h
===================================================================
--- /issm/trunk-jpl/src/c/classes/Params/StringArrayParam.h	(revision 22624)
+++ /issm/trunk-jpl/src/c/classes/Params/StringArrayParam.h	(revision 22625)
@@ -46,4 +46,5 @@
 		void  GetParameterValue(IssmDouble* pIssmDouble){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a IssmDouble");}
 		void  GetParameterValue(IssmDouble* pdouble,IssmDouble time){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a IssmDouble for a given time");}
+		void  GetParameterValue(IssmDouble** pIssmDoublearray,int* pM, IssmDouble time){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a IssmDoubleArray for a given time");}
 		void  GetParameterValue(char** pstring){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a string");}
 		void  GetParameterValue(char*** pstringarray,int* pM);
Index: /issm/trunk-jpl/src/c/classes/Params/StringParam.h
===================================================================
--- /issm/trunk-jpl/src/c/classes/Params/StringParam.h	(revision 22624)
+++ /issm/trunk-jpl/src/c/classes/Params/StringParam.h	(revision 22625)
@@ -46,4 +46,5 @@
 		void  GetParameterValue(IssmDouble* pIssmDouble){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a IssmDouble");}
 		void  GetParameterValue(IssmDouble* pdouble,IssmDouble time){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a IssmDouble for a given time");}
+		void  GetParameterValue(IssmDouble** pIssmDoublearray,int* pM, IssmDouble time){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a IssmDoubleArray for a given time");}
 		void  GetParameterValue(char** pstring);
 		void  GetParameterValue(char*** pstringarray,int* pM){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a string array");}
Index: /issm/trunk-jpl/src/c/classes/Params/TransientArrayParam.cpp
===================================================================
--- /issm/trunk-jpl/src/c/classes/Params/TransientArrayParam.cpp	(revision 22624)
+++ /issm/trunk-jpl/src/c/classes/Params/TransientArrayParam.cpp	(revision 22625)
@@ -142,2 +142,57 @@
 }
 /*}}}*/
+void  TransientArrayParam::GetParameterValue(IssmDouble** pIssmDoubleArray, int* pM, IssmDouble time){/*{{{*/
+
+	IssmDouble* output=NULL;
+	bool   found;
+	int M=*pM;
+
+	output=xNew<IssmDouble>(M);
+
+	/*Ok, we have the time, go through the timesteps, and figure out which interval we 
+	 *fall within. Then interpolate the values on this interval: */
+	if(time<this->timesteps[0]){
+		/*get values for the first time: */
+		for(int k=0; k<M;k++){
+			output[k]=this->values[k*this->N];
+			found=true;
+		}
+	}
+	else if(time>this->timesteps[this->N-1]){
+		/*get values for the last time: */
+		for(int k=0; k<M;k++){
+			output[k]=this->values[(k+1)*this->N-1];
+			found=true;
+		}
+	}
+	else{
+		/*Find which interval we fall within: */
+		for(int i=0;i<this->N;i++){
+			if(time==this->timesteps[i]){
+				/*We are right on one step time: */
+				for(int k=0; k<M;k++){
+					output[k]=this->values[k*this->N+i];
+				}
+				found=true;
+				break; //we are done with the time interpolation.
+			}
+			else{
+				if(this->timesteps[i]<time && time<this->timesteps[i+1]){
+					/*ok, we have the interval ]i:i+1[. Interpolate linearly for now: */
+					IssmDouble deltat=this->timesteps[i+1]-this->timesteps[i];
+					IssmDouble alpha=(time-this->timesteps[i])/deltat;
+					for(int k=0; k<M;k++){
+						if(interpolation==true) output[k]=(1.0-alpha)*this->values[k*this->N+i] + alpha*this->values[k*this->N+i+1];
+						else output[k]=this->values[k*this->N+i];
+					}
+					found=true;
+					break;
+				}
+				else continue; //keep looking on the next interval
+			}
+		}
+	}
+	if(!found)_error_("did not find time interval on which to interpolate values");
+	*pIssmDoubleArray=output;
+
+}/*}}}*/
Index: /issm/trunk-jpl/src/c/classes/Params/TransientArrayParam.h
===================================================================
--- /issm/trunk-jpl/src/c/classes/Params/TransientArrayParam.h	(revision 22624)
+++ /issm/trunk-jpl/src/c/classes/Params/TransientArrayParam.h	(revision 22625)
@@ -49,4 +49,5 @@
 		void  GetParameterValue(IssmDouble* pIssmDouble){_error_("Parameter " <<EnumToStringx(enum_type) << " cannot return a IssmDouble");}
 		void  GetParameterValue(IssmDouble* pdouble,IssmDouble time,int row);
+		void  GetParameterValue(IssmDouble** pIssmDoublearray,int* pM, IssmDouble time);
 		void  GetParameterValue(IssmDouble* pdouble,IssmDouble time){_error_("Parameter " <<EnumToStringx(enum_type) << " needs row to be specified");}
 		void  GetParameterValue(char** pstring){_error_("Parameter " <<EnumToStringx(enum_type) << " cannot return a string");}
Index: /issm/trunk-jpl/src/c/classes/Params/TransientParam.h
===================================================================
--- /issm/trunk-jpl/src/c/classes/Params/TransientParam.h	(revision 22624)
+++ /issm/trunk-jpl/src/c/classes/Params/TransientParam.h	(revision 22625)
@@ -48,4 +48,5 @@
 		void  GetParameterValue(IssmDouble* pIssmDouble){_error_("Parameter " <<EnumToStringx(enum_type) << " cannot return a IssmDouble");}
 		void  GetParameterValue(IssmDouble* pdouble,IssmDouble time);
+		void  GetParameterValue(IssmDouble** pIssmDoublearray,int* pM, IssmDouble time){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a IssmDoubleArray for a given time");}
 		void  GetParameterValue(char** pstring){_error_("Parameter " <<EnumToStringx(enum_type) << " cannot return a string");}
 		void  GetParameterValue(char*** pstringarray,int* pM){_error_("Parameter " <<EnumToStringx(enum_type) << " cannot return a string array");}
Index: /issm/trunk-jpl/src/c/classes/Params/VectorParam.h
===================================================================
--- /issm/trunk-jpl/src/c/classes/Params/VectorParam.h	(revision 22624)
+++ /issm/trunk-jpl/src/c/classes/Params/VectorParam.h	(revision 22625)
@@ -46,4 +46,5 @@
 		void  GetParameterValue(IssmDouble* pIssmDouble){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a IssmDouble");}
 		void  GetParameterValue(IssmDouble* pdouble,IssmDouble time){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a IssmDouble for a given time");}
+		void  GetParameterValue(IssmDouble** pIssmDoublearray,int* pM, IssmDouble time){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a IssmDoubleArray for a given time");}
 		void  GetParameterValue(char** pstring){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a string");}
 		void  GetParameterValue(char*** pstringarray,int* pM){_error_("Param "<< EnumToStringx(enum_type) << " cannot return a string array");}
Index: /issm/trunk-jpl/src/c/modules/FloatingiceMeltingRatePicox/FloatingiceMeltingRatePicox.cpp
===================================================================
--- /issm/trunk-jpl/src/c/modules/FloatingiceMeltingRatePicox/FloatingiceMeltingRatePicox.cpp	(revision 22625)
+++ /issm/trunk-jpl/src/c/modules/FloatingiceMeltingRatePicox/FloatingiceMeltingRatePicox.cpp	(revision 22625)
@@ -0,0 +1,226 @@
+/*!\file FloatingiceMeltingRatePicox
+ * \brief: calculates Floating ice melting rate following the PICO model (Reese et al., 2017)
+ */
+
+#include "./FloatingiceMeltingRatePicox.h"
+#include "../../shared/shared.h"
+#include "../../toolkits/toolkits.h"
+
+void FloatingiceMeltingRatePicox(FemModel* femmodel){/*{{{*/
+
+	int maxbox;
+
+	/*First, reset all melt to 0 */
+	for(int i=0;i<femmodel->elements->Size();i++){
+		Element* element=xDynamicCast<Element*>(femmodel->elements->GetObjectByOffset(i));
+		int numvertices = element->GetNumberOfVertices();
+		IssmDouble* values = xNewZeroInit<IssmDouble>(numvertices);
+		element->AddInput(BasalforcingsFloatingiceMeltingRateEnum,values,P1Enum);
+		xDelete<IssmDouble>(values);
+	}
+
+	femmodel->parameters->FindParam(&maxbox,BasalforcingsPicoMaxboxcountEnum);
+	UpdateBoxIdsPico(femmodel);
+	ComputeBoxAreasPico(femmodel);
+	UpdateFirstBoxPico(femmodel);
+	for(int i=1;i<maxbox;i++){
+		ComputeAverageOceanvarsPico(femmodel, i-1);
+		UpdateNextBoxPico(femmodel, i);
+	}
+}/*}}}*/
+
+void UpdateBoxIdsPico(FemModel* femmodel){/*{{{*/
+
+	int i,k,numvertices,num_basins,maxbox,basinid;
+	IssmDouble dist_max,val;
+	int* nd=NULL;
+	IssmDouble* dmax_basin=NULL;
+	IssmDouble* distances=NULL;
+
+	femmodel->parameters->FindParam(&num_basins,BasalforcingsPicoNumBasinsEnum);
+	femmodel->parameters->FindParam(&maxbox,BasalforcingsPicoMaxboxcountEnum);
+	dmax_basin=xNew<IssmDouble>(num_basins);
+
+	femmodel->elements->InputDuplicate(MaskGroundediceLevelsetEnum,DistanceToGroundinglineEnum);
+	femmodel->DistanceToFieldValue(MaskGroundediceLevelsetEnum,0.,DistanceToGroundinglineEnum);
+	
+	femmodel->elements->InputDuplicate(MaskIceLevelsetEnum,DistanceToCalvingfrontEnum);
+	femmodel->DistanceToFieldValue(MaskIceLevelsetEnum,0.,DistanceToCalvingfrontEnum);
+
+	/*find maximum distance to grounding line per domain and per basin*/
+	dist_max=-1.;
+	for(i=0;i<num_basins;i++){dmax_basin[i]=-1;}
+	for(i=0;i<femmodel->elements->Size();i++){
+		Element* element=xDynamicCast<Element*>(femmodel->elements->GetObjectByOffset(i));
+		if(!element->IsIceInElement() || !element->IsFloating()) continue;
+		numvertices = element->GetNumberOfVertices();
+		distances=xNew<IssmDouble>(numvertices);
+		element->GetInputListOnVertices(&distances[0],DistanceToGroundinglineEnum);
+		element->inputs->GetInputValue(&basinid,BasalforcingsPicoBasinIdEnum);
+		for(k=0; k<numvertices; k++){
+			if(fabs(distances[k])>dist_max){dist_max=fabs(distances[k]);}
+			if(fabs(distances[k])>dmax_basin[basinid]){dmax_basin[basinid]=fabs(distances[k]);}
+		}
+		xDelete<IssmDouble>(distances);
+	}
+
+	/*Define maximum number of boxes per basin*/
+	nd=xNew<int>(num_basins);
+	for(i=0; i<num_basins;i++){
+		val=sqrt(dmax_basin[i]/dist_max)*(maxbox-1);
+		k=0;
+		while(k<val+.5){k++;}
+		nd[i]=k;
+	} 
+
+	/*Assign box numbers*/
+	for(i=0;i<femmodel->elements->Size();i++){
+		Element* element=xDynamicCast<Element*>(femmodel->elements->GetObjectByOffset(i));
+		element->PicoUpdateBoxid(nd);
+	}
+
+	/*Cleanup and return */
+	xDelete<int>(nd);
+	xDelete<IssmDouble>(dmax_basin);
+
+}/*}}}*/
+void ComputeBoxAreasPico(FemModel* femmodel){/*{{{*/
+
+	int num_basins,maxbox,basinid,boxid;
+	IssmDouble dist_max,area;
+
+	femmodel->parameters->FindParam(&num_basins,BasalforcingsPicoNumBasinsEnum);
+	femmodel->parameters->FindParam(&maxbox,BasalforcingsPicoMaxboxcountEnum);
+	
+	IssmDouble* boxareas=xNewZeroInit<IssmDouble>(num_basins*maxbox);
+	for(int i=0;i<femmodel->elements->Size();i++){
+		Element* element=xDynamicCast<Element*>(femmodel->elements->GetObjectByOffset(i));
+		if(!element->IsIceInElement() || !element->IsFloating()) continue;
+		element->inputs->GetInputValue(&boxid,BasalforcingsPicoBoxIdEnum);
+		element->inputs->GetInputValue(&basinid,BasalforcingsPicoBasinIdEnum);
+		boxareas[basinid*maxbox+boxid]+=element->GetHorizontalSurfaceArea();
+	}
+
+	/*Synchronize across cpus*/
+	IssmDouble* sumareas =xNew<IssmDouble>(num_basins*maxbox);
+	ISSM_MPI_Allreduce(boxareas,sumareas,num_basins*maxbox,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,IssmComm::GetComm());
+
+	/*Update parameters to keep track of the new areas in future calculations*/
+	femmodel->parameters->AddObject(new DoubleVecParam(BasalforcingsPicoBoxAreaEnum,sumareas,maxbox*num_basins));
+
+	/*Cleanup and return */
+	xDelete<IssmDouble>(boxareas);
+	xDelete<IssmDouble>(sumareas);
+
+}/*}}}*/
+void UpdateFirstBoxPico(FemModel* femmodel){/*{{{*/
+
+	for(int i=0;i<femmodel->elements->Size();i++){
+		Element* element=xDynamicCast<Element*>(femmodel->elements->GetObjectByOffset(i));
+		element->PicoUpdateFirstBox();
+	}
+
+}/*}}}*/
+void ComputeAverageOceanvarsPico(FemModel* femmodel, int boxid){/*{{{*/
+
+	int i,k,p, num_basins, basinid, maxbox, M;
+	IssmDouble area, toc, soc, overturning;
+	IssmDouble* boxareas=NULL;
+	IssmDouble* overturning_weighted_avg=NULL;
+	Element* element;
+   Gauss* gauss;
+
+	femmodel->parameters->FindParam(&num_basins,BasalforcingsPicoNumBasinsEnum);
+	femmodel->parameters->FindParam(&maxbox,BasalforcingsPicoMaxboxcountEnum);
+	M=maxbox*num_basins;
+	femmodel->parameters->FindParam(&boxareas,&M, BasalforcingsPicoBoxAreaEnum);
+	IssmDouble* toc_weighted_avg=xNewZeroInit<IssmDouble>(num_basins);
+	IssmDouble* soc_weighted_avg=xNewZeroInit<IssmDouble>(num_basins);
+	IssmDouble* toc_sumweightedavg =xNewZeroInit<IssmDouble>(num_basins);
+	IssmDouble* soc_sumweightedavg =xNewZeroInit<IssmDouble>(num_basins);
+	IssmDouble* overturning_sumweightedavg =xNewZeroInit<IssmDouble>(num_basins);
+
+	/* Compute Toc and Soc weighted avg (boxes 0 to n-1) */
+	for(i=0;i<femmodel->elements->Size();i++){
+		element=xDynamicCast<Element*>(femmodel->elements->GetObjectByOffset(i));
+		if(!element->IsIceInElement() || !element->IsFloating()) continue;
+		int el_boxid;
+		element->inputs->GetInputValue(&el_boxid,BasalforcingsPicoBoxIdEnum);
+		if(el_boxid!=boxid) continue;
+
+		Input* tocs_input=element->GetInput(BasalforcingsPicoSubShelfOceanTempEnum); _assert_(tocs_input); 
+		Input* socs_input=element->GetInput(BasalforcingsPicoSubShelfOceanSalinityEnum); _assert_(socs_input);
+
+		element->inputs->GetInputValue(&basinid,BasalforcingsPicoBasinIdEnum);
+		gauss=element->NewGauss(1); gauss->GaussPoint(0);
+		tocs_input->GetInputValue(&toc,gauss);
+		socs_input->GetInputValue(&soc,gauss);
+		delete gauss;
+		area=element->GetHorizontalSurfaceArea();
+		toc_weighted_avg[basinid]+=toc*area;
+		soc_weighted_avg[basinid]+=soc*area;
+	}
+
+	/*Syncronize across cpus*/
+	ISSM_MPI_Allreduce(toc_weighted_avg,toc_sumweightedavg,num_basins,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,IssmComm::GetComm());
+	ISSM_MPI_Allreduce(soc_weighted_avg,soc_sumweightedavg,num_basins,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,IssmComm::GetComm());
+
+	for(k=0;k<num_basins;k++){
+		p=k*maxbox+boxid; 
+		if(boxareas[p]==0) continue;	
+		toc_sumweightedavg[k] = toc_sumweightedavg[k]/boxareas[p];
+		soc_sumweightedavg[k] = soc_sumweightedavg[k]/boxareas[p];
+	}
+
+	femmodel->parameters->AddObject(new DoubleVecParam(BasalforcingsPicoAverageTemperatureEnum,toc_sumweightedavg,num_basins));
+	femmodel->parameters->AddObject(new DoubleVecParam(BasalforcingsPicoAverageSalinityEnum,soc_sumweightedavg,num_basins));
+
+	/* Compute overturning weighted avg (box 0 only) */
+	if(boxid==0){ 
+		overturning_weighted_avg=xNewZeroInit<IssmDouble>(num_basins);
+		for(i=0;i<femmodel->elements->Size();i++){
+			element=xDynamicCast<Element*>(femmodel->elements->GetObjectByOffset(i));
+			if(!element->IsIceInElement() || !element->IsFloating()) continue;
+			int el_boxid;
+			element->inputs->GetInputValue(&el_boxid,BasalforcingsPicoBoxIdEnum);
+			if(el_boxid!=boxid) continue;
+
+	     	Input* overturnings_input=element->GetInput(BasalforcingsPicoSubShelfOceanOverturningEnum); _assert_(overturnings_input);
+
+			element->inputs->GetInputValue(&basinid,BasalforcingsPicoBasinIdEnum);
+			gauss=element->NewGauss(1); gauss->GaussPoint(0);
+			overturnings_input->GetInputValue(&overturning,gauss);
+			delete gauss;
+			area=element->GetHorizontalSurfaceArea();
+			overturning_weighted_avg[basinid]+=overturning*area;
+		}
+
+		/*Syncronize across cpus*/
+		ISSM_MPI_Allreduce(overturning_weighted_avg,overturning_sumweightedavg,num_basins,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,IssmComm::GetComm());
+
+		for(k=0;k<num_basins;k++){
+			element->inputs->GetInputValue(&basinid,BasalforcingsPicoBasinIdEnum);
+			p=k*maxbox+boxid;
+			if(boxareas[p]==0) continue;
+			overturning_sumweightedavg[k] = overturning_sumweightedavg[k]/boxareas[p];
+		}
+		femmodel->parameters->AddObject(new DoubleVecParam(BasalforcingsPicoAverageOverturningEnum,overturning_sumweightedavg,num_basins));
+	}
+
+	/*Cleanup and return */
+	xDelete<IssmDouble>(overturning_sumweightedavg);
+	xDelete<IssmDouble>(toc_sumweightedavg);
+	xDelete<IssmDouble>(soc_sumweightedavg);
+	xDelete<IssmDouble>(overturning_weighted_avg);
+	xDelete<IssmDouble>(toc_weighted_avg);
+	xDelete<IssmDouble>(soc_weighted_avg);
+	xDelete<IssmDouble>(boxareas);
+
+}/*}}}*/
+void UpdateNextBoxPico(FemModel* femmodel, int loopboxid){/*{{{*/
+	for(int i=0;i<femmodel->elements->Size();i++){
+		Element* element=xDynamicCast<Element*>(femmodel->elements->GetObjectByOffset(i));
+		element->PicoUpdateNextBox(loopboxid);	
+	}
+
+}/*}}}*/
Index: /issm/trunk-jpl/src/c/modules/FloatingiceMeltingRatePicox/FloatingiceMeltingRatePicox.h
===================================================================
--- /issm/trunk-jpl/src/c/modules/FloatingiceMeltingRatePicox/FloatingiceMeltingRatePicox.h	(revision 22625)
+++ /issm/trunk-jpl/src/c/modules/FloatingiceMeltingRatePicox/FloatingiceMeltingRatePicox.h	(revision 22625)
@@ -0,0 +1,19 @@
+/*!\file:  FloatingiceMeltingRatePicox.h
+ * \brief header file for Floatingice melting rate
+ */ 
+
+#ifndef _FloatingiceMeltingRatePicox_H
+#define _FloatingiceMeltingRatePicox_H
+
+#include "../../classes/classes.h"
+
+/* local prototypes: */
+void FloatingiceMeltingRatePicox(FemModel* femmodel);
+
+void UpdateBoxIdsPico(FemModel* femmodel);
+void ComputeBoxAreasPico(FemModel* femmodel);
+void UpdateFirstBoxPico(FemModel* femmodel);
+void ComputeAverageOceanvarsPico(FemModel* femmodel, int boxid);
+void UpdateNextBoxPico(FemModel* femmodel, int loopboxid);
+
+#endif  /* _FloatingiceMeltingRatePicox_H*/
Index: /issm/trunk-jpl/src/c/modules/FloatingiceMeltingRatex/FloatingiceMeltingRatex.cpp
===================================================================
--- /issm/trunk-jpl/src/c/modules/FloatingiceMeltingRatex/FloatingiceMeltingRatex.cpp	(revision 22624)
+++ /issm/trunk-jpl/src/c/modules/FloatingiceMeltingRatex/FloatingiceMeltingRatex.cpp	(revision 22625)
@@ -31,5 +31,5 @@
 		case BasalforcingsPicoEnum:
 			if(VerboseSolution())_printf0_(" call Pico Floating melting rate module\n");
-			PicoFloatingiceMeltingRatex(femmodel);
+			FloatingiceMeltingRatePicox(femmodel);
 			break;
 		default:
@@ -56,90 +56,2 @@
 /*}}}*/
 
-void PicoFloatingiceMeltingRatex(FemModel* femmodel){/*{{{*/
-
-	int i,k,p,numvertices;
-	int num_basins,maxbox,basinid,boxid;
-	IssmDouble dist_max,area,earth_grav,rhoi,rhow,rho_star,nu,latentheat;
-	IssmDouble c_p_ocean,lambda,a,b,c,alpha,Beta,gamma_T,overturning_coeff;
-	IssmDouble g1,g2,s1,p_coeff,tavg,savg,overturning_avg;
-	IssmDouble mean_toc,mean_soc,mean_overturning,pressure,T_star;
-	IssmDouble q_coeff,potential_pressure_melting_point,T_pressure_melting,overturning;
-	IssmDouble thickness,toc_farocean,soc_farocean,area_box1,Toc,Soc,basalmeltrate_shelf;
-	int* nd=NULL;
-	IssmDouble* dmax_basin=NULL;
-	IssmDouble* t_farocean=NULL;
-	IssmDouble* s_farocean=NULL;
-	IssmDouble* distances=NULL;
-	IssmDouble* boxareas=NULL;
-	Element* element=NULL;
-
-	femmodel->parameters->FindParam(&num_basins,BasalforcingsPicoNumBasinsEnum);
-	femmodel->parameters->FindParam(&maxbox,BasalforcingsPicoMaxboxcountEnum);
-	dmax_basin=xNew<IssmDouble>(num_basins);
-	femmodel->DistanceToFieldValue(MaskGroundediceLevelsetEnum,0.,DistanceToGroundinglineEnum);
-	femmodel->DistanceToFieldValue(MaskIceLevelsetEnum,0.,DistanceToCalvingfrontEnum);
-	// find maximum distance to grounding line
-	dist_max=-1.;
-	for(i=0;i<num_basins;i++){
-		dmax_basin[i]=-1;
-	}
-	for(i=0;i<femmodel->elements->Size();i++){
-		element=xDynamicCast<Element*>(femmodel->elements->GetObjectByOffset(i));
-		if(!element->IsFloating()) continue;
-		numvertices = element->GetNumberOfVertices();
-		distances=xNew<IssmDouble>(numvertices);
-		element->GetInputListOnVertices(&distances[0],DistanceToGroundinglineEnum);
-		element->inputs->GetInputValue(&basinid,BasalforcingsPicoBasinIdEnum);
-		for(k=0; k<numvertices; k++){
-			if(fabs(distances[k])>dist_max){dist_max=fabs(distances[k]);}
-			if(fabs(distances[k])>dmax_basin[basinid]){dmax_basin[basinid]=fabs(distances[k]);}
-		}
-	}
-	//1 Define pico boxes
-	nd=xNew<int>(num_basins);
-	#ifndef _HAVE_ADOLC_ //we want to avoid the round operation at all cost. Not differentiable.
-	for(i=0; i<num_basins;i++){
-		nd[i] = round(sqrt(dmax_basin[i]/dist_max)*(maxbox-1)); //0-based
-	}
-	#else
-	_error_("Don't know how to call round with AD on (present in other parts of the code as well");
-	#endif
-	for(int i=0;i<femmodel->elements->Size();i++){
-		Element* element=xDynamicCast<Element*>(femmodel->elements->GetObjectByOffset(i));
-		element->PicoUpdateBoxid(nd);
-	}
-
-	//2 Get area of the boxes
-	boxareas=xNew<IssmDouble>(num_basins*maxbox);
-	for(i=0;i<num_basins*maxbox;i++){boxareas[i]=0.;}
-	for(i=0;i<femmodel->elements->Size();i++){
-		element=xDynamicCast<Element*>(femmodel->elements->GetObjectByOffset(i));
-		if(!element->IsFloating()) continue;
-		element->inputs->GetInputValue(&basinid,BasalforcingsPicoBasinIdEnum);
-		element->inputs->GetInputValue(&boxid,BasalforcingsPicoBoxIdEnum);
-		_error_("fix thi");
-		//boxareas[basinid*maxbox+boxid]+=element->GetArea();
-	}
-
-	//3 Compute variables in first box
-	for(int p=0;p<femmodel->elements->Size();p++){
-		element=xDynamicCast<Element*>(femmodel->elements->GetObjectByOffset(p));
-		element->PicoUpdateFirstBox();
-		//Need to save the box1 average of temp, sal, and overt for input into next box.
-	}
-
-
-	//4 Compute variables of all other boxes
-
-// 	for(int i=0;i<femmodel->elements->Size();i++){
-// 		Element* element=xDynamicCast<Element*>(femmodel->elements->GetObjectByOffset(i));
-// 		element->PicoFloatingiceMeltingRate();
-// 	}
-	/*Cleanup and return */
-	xDelete<int>(nd);
-	xDelete<IssmDouble>(dmax_basin);
-	xDelete<IssmDouble>(distances);
-	xDelete<IssmDouble>(boxareas);
-	xDelete<IssmDouble>(t_farocean);
-   xDelete<IssmDouble>(s_farocean);
-}/*}}}*/
Index: /issm/trunk-jpl/src/c/modules/FloatingiceMeltingRatex/FloatingiceMeltingRatex.h
===================================================================
--- /issm/trunk-jpl/src/c/modules/FloatingiceMeltingRatex/FloatingiceMeltingRatex.h	(revision 22624)
+++ /issm/trunk-jpl/src/c/modules/FloatingiceMeltingRatex/FloatingiceMeltingRatex.h	(revision 22625)
@@ -7,4 +7,5 @@
 
 #include "../../classes/classes.h"
+#include "../FloatingiceMeltingRatePicox/FloatingiceMeltingRatePicox.h"
 
 /* local prototypes: */
@@ -12,5 +13,4 @@
 void LinearFloatingiceMeltingRatex(FemModel* femmodel);
 void MismipFloatingiceMeltingRatex(FemModel* femmodel);
-void PicoFloatingiceMeltingRatex(FemModel* femmodel);
 
 #endif  /* _FloatingiceMeltingRatex_H*/
Index: /issm/trunk-jpl/src/c/modules/ModelProcessorx/CreateParameters.cpp
===================================================================
--- /issm/trunk-jpl/src/c/modules/ModelProcessorx/CreateParameters.cpp	(revision 22624)
+++ /issm/trunk-jpl/src/c/modules/ModelProcessorx/CreateParameters.cpp	(revision 22625)
@@ -211,6 +211,8 @@
 				iomodel->FetchData(&transparam,&N,&M,"md.basalforcings.farocean_temperature");
 				parameters->AddObject(new TransientArrayParam(BasalforcingsPicoFarOceantemperatureEnum,&transparam[0],&transparam[M*(N-1)],interp,M,N));
+				xDelete<IssmDouble>(transparam);
 				iomodel->FetchData(&transparam,&N,&M,"md.basalforcings.farocean_salinity");
 				parameters->AddObject(new TransientArrayParam(BasalforcingsPicoFarOceansalinityEnum,&transparam[0],&transparam[M*(N-1)],interp,M,N));
+				xDelete<IssmDouble>(transparam);
 			break;
 		default:
Index: /issm/trunk-jpl/src/c/modules/modules.h
===================================================================
--- /issm/trunk-jpl/src/c/modules/modules.h	(revision 22624)
+++ /issm/trunk-jpl/src/c/modules/modules.h	(revision 22625)
@@ -60,4 +60,5 @@
 #include "./Krigingx/Krigingx.h"
 #include "./FloatingiceMeltingRatex/FloatingiceMeltingRatex.h"
+#include "./FloatingiceMeltingRatePicox/FloatingiceMeltingRatePicox.h"
 #include "./Mergesolutionfromftogx/Mergesolutionfromftogx.h"
 #include "./MeshPartitionx/MeshPartitionx.h"
Index: /issm/trunk-jpl/src/c/shared/Enum/EnumDefinitions.h
===================================================================
--- /issm/trunk-jpl/src/c/shared/Enum/EnumDefinitions.h	(revision 22624)
+++ /issm/trunk-jpl/src/c/shared/Enum/EnumDefinitions.h	(revision 22625)
@@ -66,6 +66,12 @@
 	BasalforcingsMeltrateFactorEnum,
 	BasalforcingsNusseltEnum,
+	BasalforcingsPicoAverageOverturningEnum,
+	BasalforcingsPicoAverageSalinityEnum,
+	BasalforcingsPicoAverageTemperatureEnum,
+	BasalforcingsPicoBoxAreaEnum,
 	BasalforcingsPicoFarOceansalinityEnum,
+	BasalforcingsPicoFarOceantemperatureEnum,
 	BasalforcingsPicoGammaTEnum,
+	BasalforcingsPicoMaxboxcountEnum,
 	BasalforcingsPicoNumBasinsEnum,
 	BasalforcingsPicoOverturningCoeffEnum,
@@ -357,5 +363,7 @@
 	BasalforcingsPicoBasinIdEnum,
 	BasalforcingsPicoBoxIdEnum,
-	BasalforcingsPicoMaxboxcountEnum,
+	BasalforcingsPicoSubShelfOceanOverturningEnum,
+	BasalforcingsPicoSubShelfOceanSalinityEnum,
+	BasalforcingsPicoSubShelfOceanTempEnum,
 	BaseEnum,
 	BedEnum,
@@ -624,5 +632,4 @@
 	BasalCrevasseEnum,
 	BasalforcingsPicoEnum,
-	BasalforcingsPicoFarOceantemperatureEnum,
 	BedSlopeSolutionEnum,
 	BoolExternalResultEnum,
Index: /issm/trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp
===================================================================
--- /issm/trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp	(revision 22624)
+++ /issm/trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp	(revision 22625)
@@ -74,6 +74,12 @@
 		case BasalforcingsMeltrateFactorEnum : return "BasalforcingsMeltrateFactor";
 		case BasalforcingsNusseltEnum : return "BasalforcingsNusselt";
+		case BasalforcingsPicoAverageOverturningEnum : return "BasalforcingsPicoAverageOverturning";
+		case BasalforcingsPicoAverageSalinityEnum : return "BasalforcingsPicoAverageSalinity";
+		case BasalforcingsPicoAverageTemperatureEnum : return "BasalforcingsPicoAverageTemperature";
+		case BasalforcingsPicoBoxAreaEnum : return "BasalforcingsPicoBoxArea";
 		case BasalforcingsPicoFarOceansalinityEnum : return "BasalforcingsPicoFarOceansalinity";
+		case BasalforcingsPicoFarOceantemperatureEnum : return "BasalforcingsPicoFarOceantemperature";
 		case BasalforcingsPicoGammaTEnum : return "BasalforcingsPicoGammaT";
+		case BasalforcingsPicoMaxboxcountEnum : return "BasalforcingsPicoMaxboxcount";
 		case BasalforcingsPicoNumBasinsEnum : return "BasalforcingsPicoNumBasins";
 		case BasalforcingsPicoOverturningCoeffEnum : return "BasalforcingsPicoOverturningCoeff";
@@ -363,5 +369,7 @@
 		case BasalforcingsPicoBasinIdEnum : return "BasalforcingsPicoBasinId";
 		case BasalforcingsPicoBoxIdEnum : return "BasalforcingsPicoBoxId";
-		case BasalforcingsPicoMaxboxcountEnum : return "BasalforcingsPicoMaxboxcount";
+		case BasalforcingsPicoSubShelfOceanOverturningEnum : return "BasalforcingsPicoSubShelfOceanOverturning";
+		case BasalforcingsPicoSubShelfOceanSalinityEnum : return "BasalforcingsPicoSubShelfOceanSalinity";
+		case BasalforcingsPicoSubShelfOceanTempEnum : return "BasalforcingsPicoSubShelfOceanTemp";
 		case BaseEnum : return "Base";
 		case BedEnum : return "Bed";
@@ -628,5 +636,4 @@
 		case BasalCrevasseEnum : return "BasalCrevasse";
 		case BasalforcingsPicoEnum : return "BasalforcingsPico";
-		case BasalforcingsPicoFarOceantemperatureEnum : return "BasalforcingsPicoFarOceantemperature";
 		case BedSlopeSolutionEnum : return "BedSlopeSolution";
 		case BoolExternalResultEnum : return "BoolExternalResult";
Index: /issm/trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp
===================================================================
--- /issm/trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp	(revision 22624)
+++ /issm/trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp	(revision 22625)
@@ -74,6 +74,12 @@
 	      else if (strcmp(name,"BasalforcingsMeltrateFactor")==0) return BasalforcingsMeltrateFactorEnum;
 	      else if (strcmp(name,"BasalforcingsNusselt")==0) return BasalforcingsNusseltEnum;
+	      else if (strcmp(name,"BasalforcingsPicoAverageOverturning")==0) return BasalforcingsPicoAverageOverturningEnum;
+	      else if (strcmp(name,"BasalforcingsPicoAverageSalinity")==0) return BasalforcingsPicoAverageSalinityEnum;
+	      else if (strcmp(name,"BasalforcingsPicoAverageTemperature")==0) return BasalforcingsPicoAverageTemperatureEnum;
+	      else if (strcmp(name,"BasalforcingsPicoBoxArea")==0) return BasalforcingsPicoBoxAreaEnum;
 	      else if (strcmp(name,"BasalforcingsPicoFarOceansalinity")==0) return BasalforcingsPicoFarOceansalinityEnum;
+	      else if (strcmp(name,"BasalforcingsPicoFarOceantemperature")==0) return BasalforcingsPicoFarOceantemperatureEnum;
 	      else if (strcmp(name,"BasalforcingsPicoGammaT")==0) return BasalforcingsPicoGammaTEnum;
+	      else if (strcmp(name,"BasalforcingsPicoMaxboxcount")==0) return BasalforcingsPicoMaxboxcountEnum;
 	      else if (strcmp(name,"BasalforcingsPicoNumBasins")==0) return BasalforcingsPicoNumBasinsEnum;
 	      else if (strcmp(name,"BasalforcingsPicoOverturningCoeff")==0) return BasalforcingsPicoOverturningCoeffEnum;
@@ -131,5 +137,8 @@
 	      else if (strcmp(name,"GroundinglineMigration")==0) return GroundinglineMigrationEnum;
 	      else if (strcmp(name,"HydrologydcEplflipLock")==0) return HydrologydcEplflipLockEnum;
-	      else if (strcmp(name,"HydrologydcEplThickComp")==0) return HydrologydcEplThickCompEnum;
+         else stage=2;
+   }
+   if(stage==2){
+	      if (strcmp(name,"HydrologydcEplThickComp")==0) return HydrologydcEplThickCompEnum;
 	      else if (strcmp(name,"HydrologydcIsefficientlayer")==0) return HydrologydcIsefficientlayerEnum;
 	      else if (strcmp(name,"HydrologydcLeakageFactor")==0) return HydrologydcLeakageFactorEnum;
@@ -137,8 +146,5 @@
 	      else if (strcmp(name,"HydrologydcPenaltyFactor")==0) return HydrologydcPenaltyFactorEnum;
 	      else if (strcmp(name,"HydrologydcPenaltyLock")==0) return HydrologydcPenaltyLockEnum;
-         else stage=2;
-   }
-   if(stage==2){
-	      if (strcmp(name,"HydrologydcRelTol")==0) return HydrologydcRelTolEnum;
+	      else if (strcmp(name,"HydrologydcRelTol")==0) return HydrologydcRelTolEnum;
 	      else if (strcmp(name,"HydrologydcSedimentlimit")==0) return HydrologydcSedimentlimitEnum;
 	      else if (strcmp(name,"HydrologydcSedimentlimitFlag")==0) return HydrologydcSedimentlimitFlagEnum;
@@ -254,5 +260,8 @@
 	      else if (strcmp(name,"SettingsSolverResidueThreshold")==0) return SettingsSolverResidueThresholdEnum;
 	      else if (strcmp(name,"SettingsWaitonlock")==0) return SettingsWaitonlockEnum;
-	      else if (strcmp(name,"SmbAdThresh")==0) return SmbAdThreshEnum;
+         else stage=3;
+   }
+   if(stage==3){
+	      if (strcmp(name,"SmbAdThresh")==0) return SmbAdThreshEnum;
 	      else if (strcmp(name,"SmbAIce")==0) return SmbAIceEnum;
 	      else if (strcmp(name,"SmbAIdx")==0) return SmbAIdxEnum;
@@ -260,8 +269,5 @@
 	      else if (strcmp(name,"SmbCldFrac")==0) return SmbCldFracEnum;
 	      else if (strcmp(name,"SmbDelta18o")==0) return SmbDelta18oEnum;
-         else stage=3;
-   }
-   if(stage==3){
-	      if (strcmp(name,"SmbDelta18oSurface")==0) return SmbDelta18oSurfaceEnum;
+	      else if (strcmp(name,"SmbDelta18oSurface")==0) return SmbDelta18oSurfaceEnum;
 	      else if (strcmp(name,"SmbDenIdx")==0) return SmbDenIdxEnum;
 	      else if (strcmp(name,"SmbDt")==0) return SmbDtEnum;
@@ -369,5 +375,7 @@
 	      else if (strcmp(name,"BasalforcingsPicoBasinId")==0) return BasalforcingsPicoBasinIdEnum;
 	      else if (strcmp(name,"BasalforcingsPicoBoxId")==0) return BasalforcingsPicoBoxIdEnum;
-	      else if (strcmp(name,"BasalforcingsPicoMaxboxcount")==0) return BasalforcingsPicoMaxboxcountEnum;
+	      else if (strcmp(name,"BasalforcingsPicoSubShelfOceanOverturning")==0) return BasalforcingsPicoSubShelfOceanOverturningEnum;
+	      else if (strcmp(name,"BasalforcingsPicoSubShelfOceanSalinity")==0) return BasalforcingsPicoSubShelfOceanSalinityEnum;
+	      else if (strcmp(name,"BasalforcingsPicoSubShelfOceanTemp")==0) return BasalforcingsPicoSubShelfOceanTempEnum;
 	      else if (strcmp(name,"Base")==0) return BaseEnum;
 	      else if (strcmp(name,"Bed")==0) return BedEnum;
@@ -375,5 +383,8 @@
 	      else if (strcmp(name,"BedSlopeY")==0) return BedSlopeYEnum;
 	      else if (strcmp(name,"CalvingCalvingrate")==0) return CalvingCalvingrateEnum;
-	      else if (strcmp(name,"CalvingHabFraction")==0) return CalvingHabFractionEnum;
+         else stage=4;
+   }
+   if(stage==4){
+	      if (strcmp(name,"CalvingHabFraction")==0) return CalvingHabFractionEnum;
 	      else if (strcmp(name,"CalvinglevermannCoeff")==0) return CalvinglevermannCoeffEnum;
 	      else if (strcmp(name,"CalvinglevermannMeltingrate")==0) return CalvinglevermannMeltingrateEnum;
@@ -383,8 +394,5 @@
 	      else if (strcmp(name,"CalvingrateyAverage")==0) return CalvingrateyAverageEnum;
 	      else if (strcmp(name,"Calvingratey")==0) return CalvingrateyEnum;
-         else stage=4;
-   }
-   if(stage==4){
-	      if (strcmp(name,"CalvingStressThresholdFloatingice")==0) return CalvingStressThresholdFloatingiceEnum;
+	      else if (strcmp(name,"CalvingStressThresholdFloatingice")==0) return CalvingStressThresholdFloatingiceEnum;
 	      else if (strcmp(name,"CalvingStressThresholdGroundedice")==0) return CalvingStressThresholdGroundediceEnum;
 	      else if (strcmp(name,"Converged")==0) return ConvergedEnum;
@@ -498,5 +506,8 @@
 	      else if (strcmp(name,"SmbAini")==0) return SmbAiniEnum;
 	      else if (strcmp(name,"SmbAValue")==0) return SmbAValueEnum;
-	      else if (strcmp(name,"SmbBMax")==0) return SmbBMaxEnum;
+         else stage=5;
+   }
+   if(stage==5){
+	      if (strcmp(name,"SmbBMax")==0) return SmbBMaxEnum;
 	      else if (strcmp(name,"SmbBMin")==0) return SmbBMinEnum;
 	      else if (strcmp(name,"SmbBNeg")==0) return SmbBNegEnum;
@@ -506,8 +517,5 @@
 	      else if (strcmp(name,"SmbDini")==0) return SmbDiniEnum;
 	      else if (strcmp(name,"SmbDlwrf")==0) return SmbDlwrfEnum;
-         else stage=5;
-   }
-   if(stage==5){
-	      if (strcmp(name,"SmbDswrf")==0) return SmbDswrfEnum;
+	      else if (strcmp(name,"SmbDswrf")==0) return SmbDswrfEnum;
 	      else if (strcmp(name,"SmbDz")==0) return SmbDzEnum;
 	      else if (strcmp(name,"SmbDzini")==0) return SmbDziniEnum;
@@ -621,5 +629,8 @@
 	      else if (strcmp(name,"AdjointBalancethicknessAnalysis")==0) return AdjointBalancethicknessAnalysisEnum;
 	      else if (strcmp(name,"AdjointHorizAnalysis")==0) return AdjointHorizAnalysisEnum;
-	      else if (strcmp(name,"Adjointp")==0) return AdjointpEnum;
+         else stage=6;
+   }
+   if(stage==6){
+	      if (strcmp(name,"Adjointp")==0) return AdjointpEnum;
 	      else if (strcmp(name,"AggressiveMigration")==0) return AggressiveMigrationEnum;
 	      else if (strcmp(name,"AmrBamg")==0) return AmrBamgEnum;
@@ -629,8 +640,5 @@
 	      else if (strcmp(name,"AutodiffJacobian")==0) return AutodiffJacobianEnum;
 	      else if (strcmp(name,"Balancethickness2Analysis")==0) return Balancethickness2AnalysisEnum;
-         else stage=6;
-   }
-   if(stage==6){
-	      if (strcmp(name,"Balancethickness2Solution")==0) return Balancethickness2SolutionEnum;
+	      else if (strcmp(name,"Balancethickness2Solution")==0) return Balancethickness2SolutionEnum;
 	      else if (strcmp(name,"BalancethicknessAnalysis")==0) return BalancethicknessAnalysisEnum;
 	      else if (strcmp(name,"BalancethicknessApparentMassbalance")==0) return BalancethicknessApparentMassbalanceEnum;
@@ -643,5 +651,4 @@
 	      else if (strcmp(name,"BasalCrevasse")==0) return BasalCrevasseEnum;
 	      else if (strcmp(name,"BasalforcingsPico")==0) return BasalforcingsPicoEnum;
-	      else if (strcmp(name,"BasalforcingsPicoFarOceantemperature")==0) return BasalforcingsPicoFarOceantemperatureEnum;
 	      else if (strcmp(name,"BedSlopeSolution")==0) return BedSlopeSolutionEnum;
 	      else if (strcmp(name,"BoolExternalResult")==0) return BoolExternalResultEnum;
@@ -745,5 +752,8 @@
 	      else if (strcmp(name,"GroundedAreaScaled")==0) return GroundedAreaScaledEnum;
 	      else if (strcmp(name,"GroundingOnly")==0) return GroundingOnlyEnum;
-	      else if (strcmp(name,"Gset")==0) return GsetEnum;
+         else stage=7;
+   }
+   if(stage==7){
+	      if (strcmp(name,"Gset")==0) return GsetEnum;
 	      else if (strcmp(name,"Gsl")==0) return GslEnum;
 	      else if (strcmp(name,"HOApproximation")==0) return HOApproximationEnum;
@@ -752,8 +762,5 @@
 	      else if (strcmp(name,"HydrologyBasalFlux")==0) return HydrologyBasalFluxEnum;
 	      else if (strcmp(name,"HydrologyDCEfficientAnalysis")==0) return HydrologyDCEfficientAnalysisEnum;
-         else stage=7;
-   }
-   if(stage==7){
-	      if (strcmp(name,"Hydrologydc")==0) return HydrologydcEnum;
+	      else if (strcmp(name,"Hydrologydc")==0) return HydrologydcEnum;
 	      else if (strcmp(name,"HydrologydcEplColapseThickness")==0) return HydrologydcEplColapseThicknessEnum;
 	      else if (strcmp(name,"HydrologydcEplCompressibility")==0) return HydrologydcEplCompressibilityEnum;
@@ -868,5 +875,8 @@
 	      else if (strcmp(name,"MinVx")==0) return MinVxEnum;
 	      else if (strcmp(name,"MinVy")==0) return MinVyEnum;
-	      else if (strcmp(name,"MinVz")==0) return MinVzEnum;
+         else stage=8;
+   }
+   if(stage==8){
+	      if (strcmp(name,"MinVz")==0) return MinVzEnum;
 	      else if (strcmp(name,"MismipFloatingMeltRate")==0) return MismipFloatingMeltRateEnum;
 	      else if (strcmp(name,"Moulin")==0) return MoulinEnum;
@@ -875,8 +885,5 @@
 	      else if (strcmp(name,"MpiSparse")==0) return MpiSparseEnum;
 	      else if (strcmp(name,"Mumps")==0) return MumpsEnum;
-         else stage=8;
-   }
-   if(stage==8){
-	      if (strcmp(name,"NewDamage")==0) return NewDamageEnum;
+	      else if (strcmp(name,"NewDamage")==0) return NewDamageEnum;
 	      else if (strcmp(name,"Nodal")==0) return NodalEnum;
 	      else if (strcmp(name,"Nodalvalue")==0) return NodalvalueEnum;
@@ -991,5 +998,8 @@
 	      else if (strcmp(name,"Outputdefinition100")==0) return Outputdefinition100Enum;
 	      else if (strcmp(name,"P0Array")==0) return P0ArrayEnum;
-	      else if (strcmp(name,"P1bubblecondensed")==0) return P1bubblecondensedEnum;
+         else stage=9;
+   }
+   if(stage==9){
+	      if (strcmp(name,"P1bubblecondensed")==0) return P1bubblecondensedEnum;
 	      else if (strcmp(name,"P1bubble")==0) return P1bubbleEnum;
 	      else if (strcmp(name,"P1DG")==0) return P1DGEnum;
@@ -998,8 +1008,5 @@
 	      else if (strcmp(name,"P1xP2")==0) return P1xP2Enum;
 	      else if (strcmp(name,"P1xP3")==0) return P1xP3Enum;
-         else stage=9;
-   }
-   if(stage==9){
-	      if (strcmp(name,"P1xP4")==0) return P1xP4Enum;
+	      else if (strcmp(name,"P1xP4")==0) return P1xP4Enum;
 	      else if (strcmp(name,"P2bubblecondensed")==0) return P2bubblecondensedEnum;
 	      else if (strcmp(name,"P2bubble")==0) return P2bubbleEnum;
@@ -1114,5 +1121,8 @@
 	      else if (strcmp(name,"Water")==0) return WaterEnum;
 	      else if (strcmp(name,"WorldComm")==0) return WorldCommEnum;
-	      else if (strcmp(name,"XTaylorHood")==0) return XTaylorHoodEnum;
+         else stage=10;
+   }
+   if(stage==10){
+	      if (strcmp(name,"XTaylorHood")==0) return XTaylorHoodEnum;
 	      else if (strcmp(name,"XY")==0) return XYEnum;
 	      else if (strcmp(name,"XYZ")==0) return XYZEnum;
@@ -1121,8 +1131,5 @@
 	      else if (strcmp(name,"BilinearInterp")==0) return BilinearInterpEnum;
 	      else if (strcmp(name,"CalvingdevCoeff")==0) return CalvingdevCoeffEnum;
-         else stage=10;
-   }
-   if(stage==10){
-	      if (strcmp(name,"DeviatoricStress")==0) return DeviatoricStressEnum;
+	      else if (strcmp(name,"DeviatoricStress")==0) return DeviatoricStressEnum;
 	      else if (strcmp(name,"EtaAbsGradient")==0) return EtaAbsGradientEnum;
 	      else if (strcmp(name,"MeshZ")==0) return MeshZEnum;
Index: /issm/trunk-jpl/src/m/classes/basalforcingspico.m
===================================================================
--- /issm/trunk-jpl/src/m/classes/basalforcingspico.m	(revision 22624)
+++ /issm/trunk-jpl/src/m/classes/basalforcingspico.m	(revision 22625)
@@ -11,7 +11,8 @@
 		overturning_coeff         = 0.;
 		gamma_T                   = 0.;
-		box0temperature           = NaN;
-		box0salinity              = NaN;
+		farocean_temperature      = NaN;
+		farocean_salinity         = NaN;
 		geothermalflux            = NaN;
+		groundedice_melting_rate  = NaN;
 	end
 	methods
@@ -19,4 +20,5 @@
 			self.basin_id=project3d(md,'vector',self.basin_id,'type','element','layer',1);
 			self.geothermalflux=project3d(md,'vector',self.geothermalflux,'type','element','layer',1); %bedrock only gets geothermal flux
+			self.groundedice_melting_rate=project3d(md,'vector',self.groundedice_melting_rate,'type','node','layer',1);
 		end % }}}
 		function self = basalforcingspico(varargin) % {{{
@@ -46,4 +48,9 @@
 				disp('      no turbulent temperature exchange velocity set, setting value to 2e-5');
 			end
+			if isnan(self.groundedice_melting_rate),
+				self.groundedice_melting_rate=zeros(md.mesh.numberofvertices,1);
+				disp('      no basalforcings.groundedice_melting_rate specified: values set as zero');
+			end
+
 		end % }}}
 		function self = setdefaultparameters(self) % {{{
@@ -57,11 +64,12 @@
 
 				md = checkfield(md,'fieldname','basalforcings.num_basins','numel',1,'NaN',1,'Inf',1,'>',0);
-				md = checkfield(md,'fieldname','basalforcings.basin_id','Inf',1,'>',0,'<=',md.basalforcings.num_basins,'size',[md.mesh.numberofelements 1]);
+				md = checkfield(md,'fieldname','basalforcings.basin_id','Inf',1,'>=',0,'<=',md.basalforcings.num_basins,'size',[md.mesh.numberofelements 1]);
 				md = checkfield(md,'fieldname','basalforcings.maxboxcount','numel',1,'NaN',1,'Inf',1,'>',0);
 				md = checkfield(md,'fieldname','basalforcings.overturning_coeff','numel',1,'NaN',1,'Inf',1,'>',0);
 				md = checkfield(md,'fieldname','basalforcings.gamma_T','numel',1,'NaN',1,'Inf',1,'>',0);
-				md = checkfield(md,'fieldname','basalforcings.box0temperature','NaN',1,'Inf',1,'>',0);
-				md = checkfield(md,'fieldname','basalforcings.box0salinity','NaN',1,'Inf',1,'>',0);
+				md = checkfield(md,'fieldname','basalforcings.farocean_temperature','NaN',1,'Inf',1,'>',0);
+				md = checkfield(md,'fieldname','basalforcings.farocean_salinity','NaN',1,'Inf',1,'>',0);
 				md = checkfield(md,'fieldname','basalforcings.geothermalflux','NaN',1,'Inf',1,'>=',0,'timeseries',1);
+				md = checkfield(md,'fieldname','basalforcings.groundedice_melting_rate','NaN',1,'Inf',1,'timeseries',1);
 
 		end % }}}
@@ -73,7 +81,8 @@
 			fielddisplay(self,'overturning_coeff','Overturning strength [m^3/s]');
 			fielddisplay(self,'gamma_T','Turbulent temperature exchange velocity [m/s]');
-			fielddisplay(self,'box0temperature','depth averaged ocean temperature in front of the ice shelf for basin i [K]');
-			fielddisplay(self,'box0salinity','depth averaged ocean salinity in front of the ice shelf for basin i [psu]');
+			fielddisplay(self,'farocean_temperature','depth averaged ocean temperature in front of the ice shelf for basin i [K]');
+			fielddisplay(self,'farocean_salinity','depth averaged ocean salinity in front of the ice shelf for basin i [psu]');
 			fielddisplay(self,'geothermalflux','geothermal heat flux [W/m^2]');
+			fielddisplay(self,'groundedice_melting_rate','basal melting rate (positive if melting) [m/yr]');
 
 		end % }}}
@@ -87,8 +96,10 @@
 			WriteData(fid,prefix,'object',self,'fieldname','overturning_coeff','format','Double');
 			WriteData(fid,prefix,'object',self,'fieldname','gamma_T','format','Double');
-			WriteData(fid,prefix,'object',self,'fieldname','box0temperature','format','DoubleMat','name','md.basalforcings.box0temperature','timeserieslength',md.basalforcings.num_basins+1,'yts',md.constants.yts);
-			WriteData(fid,prefix,'object',self,'fieldname','box0salinity','format','DoubleMat','name','md.basalforcings.box0salinity','timeserieslength',md.basalforcings.num_basins+1,'yts',md.constants.yts);
-			WriteData(fid,prefix,'object',self,'fieldname','basin_id','format','DoubleMat','name','md.basalforcings.basin_id','mattype',2);
+			WriteData(fid,prefix,'object',self,'fieldname','farocean_temperature','format','DoubleMat','name','md.basalforcings.farocean_temperature','timeserieslength',md.basalforcings.num_basins+1,'yts',md.constants.yts);
+			WriteData(fid,prefix,'object',self,'fieldname','farocean_salinity','format','DoubleMat','name','md.basalforcings.farocean_salinity','timeserieslength',md.basalforcings.num_basins+1,'yts',md.constants.yts);
+			%WriteData(fid,prefix,'object',self,'fieldname','basin_id','format','DoubleMat','name','md.basalforcings.basin_id','mattype',2);
+			WriteData(fid,prefix,'object',self,'fieldname','basin_id','data',self.basin_id-1,'name','md.basalforcings.basin_id','format','IntMat','mattype',2);   %Change to 0-indexing
 			WriteData(fid,prefix,'object',self,'fieldname','geothermalflux','format','DoubleMat','name','md.basalforcings.geothermalflux','mattype',1,'timeserieslength',md.mesh.numberofelements+1,'yts',md.constants.yts);
+			WriteData(fid,prefix,'object',self,'fieldname','groundedice_melting_rate','format','DoubleMat','mattype',1,'scale',1./yts,'timeserieslength',md.mesh.numberofvertices+1,'yts',md.constants.yts);
 
 		end % }}}
Index: /issm/trunk-jpl/test/NightlyRun/test470.m
===================================================================
--- /issm/trunk-jpl/test/NightlyRun/test470.m	(revision 22625)
+++ /issm/trunk-jpl/test/NightlyRun/test470.m	(revision 22625)
@@ -0,0 +1,76 @@
+%Test Name: PicoMeltRate
+md=triangle(model(),'../Exp/Square.exp',100000.);
+md=setmask(md,'../Exp/SquareShelf.exp','');
+md=parameterize(md,'../Par/SquareSheetShelf.par');
+md.initialization.vx(:)=1.;
+md.initialization.vy(:)=1.;
+md.geometry.thickness(:)=500-md.mesh.x/10000;
+md.geometry.bed =-100-md.mesh.x/1000;
+md.geometry.base=-md.geometry.thickness*md.materials.rho_ice/md.materials.rho_water;
+md.mask.groundedice_levelset=md.geometry.thickness+md.materials.rho_water/md.materials.rho_ice*md.geometry.bed;
+pos=find(md.mask.groundedice_levelset>=0);
+md.geometry.base(pos)=md.geometry.bed(pos);
+md.geometry.surface=md.geometry.base+md.geometry.thickness;
+md=setflowequation(md,'SSA','all');
+
+%Set Pico Parameters
+md.basalforcings = basalforcingspico(md.basalforcings);
+md.basalforcings.basin_id = zeros(md.mesh.numberofelements,1);
+yE = mean(md.mesh.y(md.mesh.elements),2);
+pos1 = find(yE>=5e5);	 md.basalforcings.basin_id(pos1)=1;
+pos2 = find(yE<5e5);     md.basalforcings.basin_id(pos2)=2;
+md.basalforcings.num_basins = 2;
+md.basalforcings.farocean_temperature = [271.15 272.15 273.15; 274.15 275.15 276.15; 0.5 1 1.5]; %K
+md.basalforcings.farocean_salinity    = [31 32 33; 34 35 36; 0.5 1 1.5]; %PSU                
+md.basalforcings.maxboxcount=5;
+
+%Boundary conditions:
+md.mask.ice_levelset=-ones(md.mesh.numberofvertices,1);
+md.mask.ice_levelset(find(md.mesh.x==max(md.mesh.x)))=0;
+
+%Model conditions
+md.transient.isthermal=0;
+md.transient.isstressbalance=1;
+md.transient.isgroundingline=1;
+md.transient.ismasstransport=1;
+md.transient.issmb=1;
+md.transient.requested_outputs={'default','BasalforcingsFloatingiceMeltingRate'};
+md.groundingline.migration='SubelementMigration';
+md.timestepping.final_time=1.5;
+md.timestepping.time_step=0.5;
+
+md.cluster=generic('name',oshostname(),'np',3);
+md=solve(md,'Transient');
+
+field_names     ={'Bed1','Surface1','Thickness1','Floatingice1','Vx1','Vy1','Pressure1','FloatingiceMeltingrate1',...
+	   'Bed2','Surface2','Thickness2','Floatingice2','Vx2','Vy2','Pressure2','FloatingiceMeltingrate2',...
+	   'Bed3','Surface3','Thickness3','Floatingice3','Vx3','Vy3','Pressure3','FloatingiceMeltingrate3'};
+field_tolerances={2e-11,5e-12,2e-11,1e-11,5e-10,1e-08,1e-13,1e-13,...
+	   3e-11,3e-11,9e-10,7e-11,1e-09,5e-08,1e-10,1e-13,...
+	   1e-10,3e-11,1e-10,7e-11,1e-09,5e-08,1e-10,1e-13};
+field_values={...
+	   (md.results.TransientSolution(1).Base),...
+	   (md.results.TransientSolution(1).Surface),...
+	   (md.results.TransientSolution(1).Thickness),...
+	   (md.results.TransientSolution(1).MaskGroundediceLevelset),...
+	   (md.results.TransientSolution(1).Vx),...
+	   (md.results.TransientSolution(1).Vy),...
+	   (md.results.TransientSolution(1).Pressure),...
+	   (md.results.TransientSolution(1).BasalforcingsFloatingiceMeltingRate),...
+	   (md.results.TransientSolution(2).Base),...
+	   (md.results.TransientSolution(2).Surface),...
+	   (md.results.TransientSolution(2).Thickness),...
+	   (md.results.TransientSolution(2).MaskGroundediceLevelset),...
+	   (md.results.TransientSolution(2).Vx),...
+	   (md.results.TransientSolution(2).Vy),...
+	   (md.results.TransientSolution(2).Pressure),...
+	   (md.results.TransientSolution(2).BasalforcingsFloatingiceMeltingRate),...
+	   (md.results.TransientSolution(3).Base),...
+	   (md.results.TransientSolution(3).Surface),...
+	   (md.results.TransientSolution(3).Thickness),...
+	   (md.results.TransientSolution(3).MaskGroundediceLevelset),...
+	   (md.results.TransientSolution(3).Vx),...
+	   (md.results.TransientSolution(3).Vy),...
+	   (md.results.TransientSolution(3).Pressure),...
+	   (md.results.TransientSolution(3).BasalforcingsFloatingiceMeltingRate),...
+	   };
