Index: /issm/trunk/src/c/EnumDefinitions/EnumDefinitions.h
===================================================================
--- /issm/trunk/src/c/EnumDefinitions/EnumDefinitions.h	(revision 6259)
+++ /issm/trunk/src/c/EnumDefinitions/EnumDefinitions.h	(revision 6260)
@@ -321,4 +321,7 @@
 	AdjointEnum,
 	GradientEnum,
+	Gradient1Enum,
+	Gradient2Enum,
+	Gradient3Enum,
 	OldGradientEnum,
 	ConnectivityEnum,
Index: /issm/trunk/src/c/EnumDefinitions/EnumToString.cpp
===================================================================
--- /issm/trunk/src/c/EnumDefinitions/EnumToString.cpp	(revision 6259)
+++ /issm/trunk/src/c/EnumDefinitions/EnumToString.cpp	(revision 6260)
@@ -283,4 +283,7 @@
 		case AdjointEnum : return "Adjoint";
 		case GradientEnum : return "Gradient";
+		case Gradient1Enum : return "Gradient1";
+		case Gradient2Enum : return "Gradient2";
+		case Gradient3Enum : return "Gradient3";
 		case OldGradientEnum : return "OldGradient";
 		case ConnectivityEnum : return "Connectivity";
Index: /issm/trunk/src/c/EnumDefinitions/StringToEnum.cpp
===================================================================
--- /issm/trunk/src/c/EnumDefinitions/StringToEnum.cpp	(revision 6259)
+++ /issm/trunk/src/c/EnumDefinitions/StringToEnum.cpp	(revision 6260)
@@ -281,4 +281,7 @@
 	else if (strcmp(name,"Adjoint")==0) return AdjointEnum;
 	else if (strcmp(name,"Gradient")==0) return GradientEnum;
+	else if (strcmp(name,"Gradient1")==0) return Gradient1Enum;
+	else if (strcmp(name,"Gradient2")==0) return Gradient2Enum;
+	else if (strcmp(name,"Gradient3")==0) return Gradient3Enum;
 	else if (strcmp(name,"OldGradient")==0) return OldGradientEnum;
 	else if (strcmp(name,"Connectivity")==0) return ConnectivityEnum;
Index: /issm/trunk/src/c/objects/Elements/Penta.cpp
===================================================================
--- /issm/trunk/src/c/objects/Elements/Penta.cpp	(revision 6259)
+++ /issm/trunk/src/c/objects/Elements/Penta.cpp	(revision 6260)
@@ -583,5 +583,5 @@
 					if (iomodel->dhdt){
 						for(j=0;j<6;j++)nodeinputs[j]=iomodel->dhdt[penta_vertex_ids[j]-1]/iomodel->yts;
-						this->inputs->AddInput(new ControlInput(DhDtEnum,PentaVertexInputEnum,nodeinputs));
+						this->inputs->AddInput(new ControlInput(DhDtEnum,PentaVertexInputEnum,nodeinputs,i+1));
 					}
 					break;
@@ -589,5 +589,5 @@
 					if (iomodel->vx){
 						for(j=0;j<6;j++)nodeinputs[j]=iomodel->vx[penta_vertex_ids[j]-1]/iomodel->yts;
-						this->inputs->AddInput(new ControlInput(VxEnum,PentaVertexInputEnum,nodeinputs));
+						this->inputs->AddInput(new ControlInput(VxEnum,PentaVertexInputEnum,nodeinputs,i+1));
 					}
 					break;
@@ -595,5 +595,5 @@
 					if (iomodel->vy){
 						for(j=0;j<6;j++)nodeinputs[j]=iomodel->vy[penta_vertex_ids[j]-1]/iomodel->yts;
-						this->inputs->AddInput(new ControlInput(VyEnum,PentaVertexInputEnum,nodeinputs));
+						this->inputs->AddInput(new ControlInput(VyEnum,PentaVertexInputEnum,nodeinputs,i+1));
 					}
 					break;
@@ -601,5 +601,5 @@
 					if (iomodel->drag_coefficient){
 						for(j=0;j<6;j++)nodeinputs[j]=iomodel->drag_coefficient[penta_vertex_ids[j]-1];
-						this->inputs->AddInput(new ControlInput(DragCoefficientEnum,PentaVertexInputEnum,nodeinputs));
+						this->inputs->AddInput(new ControlInput(DragCoefficientEnum,PentaVertexInputEnum,nodeinputs,i+1));
 					}
 					break;
Index: /issm/trunk/src/c/objects/Elements/Tria.cpp
===================================================================
--- /issm/trunk/src/c/objects/Elements/Tria.cpp	(revision 6259)
+++ /issm/trunk/src/c/objects/Elements/Tria.cpp	(revision 6260)
@@ -649,5 +649,5 @@
 					if (iomodel->dhdt){
 						for(j=0;j<3;j++)nodeinputs[j]=iomodel->dhdt[tria_vertex_ids[j]-1]/iomodel->yts;
-						this->inputs->AddInput(new ControlInput(DhDtEnum,TriaVertexInputEnum,nodeinputs));
+						this->inputs->AddInput(new ControlInput(DhDtEnum,TriaVertexInputEnum,nodeinputs,i+1));
 					}
 					break;
@@ -655,5 +655,5 @@
 					if (iomodel->vx){
 						for(j=0;j<3;j++)nodeinputs[j]=iomodel->vx[tria_vertex_ids[j]-1]/iomodel->yts;
-						this->inputs->AddInput(new ControlInput(VxEnum,TriaVertexInputEnum,nodeinputs));
+						this->inputs->AddInput(new ControlInput(VxEnum,TriaVertexInputEnum,nodeinputs,i+1));
 					}
 					break;
@@ -661,5 +661,5 @@
 					if (iomodel->vy){
 						for(j=0;j<3;j++)nodeinputs[j]=iomodel->vy[tria_vertex_ids[j]-1]/iomodel->yts;
-						this->inputs->AddInput(new ControlInput(VyEnum,TriaVertexInputEnum,nodeinputs));
+						this->inputs->AddInput(new ControlInput(VyEnum,TriaVertexInputEnum,nodeinputs,i+1));
 					}
 					break;
@@ -667,5 +667,5 @@
 					if (iomodel->drag_coefficient){
 						for(j=0;j<3;j++)nodeinputs[j]=iomodel->drag_coefficient[tria_vertex_ids[j]-1];
-						this->inputs->AddInput(new ControlInput(DragCoefficientEnum,TriaVertexInputEnum,nodeinputs));
+						this->inputs->AddInput(new ControlInput(DragCoefficientEnum,TriaVertexInputEnum,nodeinputs,i+1));
 					}
 					break;
Index: /issm/trunk/src/c/objects/Inputs/ControlInput.cpp
===================================================================
--- /issm/trunk/src/c/objects/Inputs/ControlInput.cpp	(revision 6259)
+++ /issm/trunk/src/c/objects/Inputs/ControlInput.cpp	(revision 6260)
@@ -20,12 +20,16 @@
 /*FUNCTION ControlInput::ControlInput(){{{1*/
 ControlInput::ControlInput(){
-	values     =NULL;
-	savedvalues =NULL;
-	gradient   =NULL;
-}
-/*}}}*/
-/*FUNCTION ControlInput::ControlInput(int enum_type,int enum_input,double* pvalues){{{1*/
-ControlInput::ControlInput(int in_enum_type,int enum_input,double* pvalues){
+	control_id  = 0;
+	values      = NULL;
+	savedvalues = NULL;
+	gradient    = NULL;
+}
+/*}}}*/
+/*FUNCTION ControlInput::ControlInput(int enum_type,int enum_input,double* pvalues,int id){{{1*/
+ControlInput::ControlInput(int in_enum_type,int enum_input,double* pvalues,int id){
+
+	control_id=id;
 	enum_type=in_enum_type;
+
 	switch(enum_input){
 		case TriaVertexInputEnum:
@@ -94,4 +98,5 @@
 	/*marshall enum_type: */
 	memcpy(marshalled_dataset,&enum_type,sizeof(enum_type));marshalled_dataset+=sizeof(enum_type);
+	memcpy(marshalled_dataset,&control_id,sizeof(control_id));marshalled_dataset+=sizeof(control_id);
 
 	/*marshal values*/
@@ -138,4 +143,5 @@
 
 	size=sizeof(enum_type)+
+	  +sizeof(control_id)
 	  +3*sizeof(int) //3 flags
 	  +sizeof(int); //sizeof(int) for enum value
@@ -159,4 +165,5 @@
 	 *object data (thanks to DataSet::Demarshall):*/
 	memcpy(&enum_type,marshalled_dataset,sizeof(enum_type));marshalled_dataset+=sizeof(enum_type);
+	memcpy(&control_id,marshalled_dataset,sizeof(control_id));marshalled_dataset+=sizeof(control_id);
 
 	/*Demarshal values*/
@@ -233,4 +240,5 @@
 	output = new ControlInput();
 	output->enum_type=this->enum_type;
+	output->control_id=this->control_id;
 
 	if(values)      output->values=(Input*)this->values->copy();
@@ -273,6 +281,24 @@
 /*FUNCTION ControlInput::SetGradient{{{1*/
 void ControlInput::SetGradient(Input* gradient_in){
+
+	/*Get enum for current gradient*/
+	switch(this->control_id){
+		case 1:
+			gradient_in->ChangeEnum(Gradient1Enum);
+			break;
+		case 2:
+			gradient_in->ChangeEnum(Gradient2Enum);
+			break;
+		case 3:
+			gradient_in->ChangeEnum(Gradient3Enum);
+			break;
+		default:
+			ISSMERROR("more than 3 controls not implemented yet (Gradient %i was requested). EnumDefinitions.h needs to be updated.",this->control_id);
+	}
+
+	/*Delete old gradient and assign new gradient*/
 	if(gradient) delete gradient;
 	gradient=gradient_in;
+
 }/*}}}*/
 /*FUNCTION ControlInput::SpawnResult{{{1*/
@@ -286,5 +312,5 @@
 /*FUNCTION ControlInput::SpawnGradient{{{1*/
 ElementResult* ControlInput::SpawnGradient(int step, double time){
-	gradient->SpawnResult(step,time);
+	return gradient->SpawnResult(step,time);
 }/*}}}*/
 /*FUNCTION ControlInput::GetParameterAverage(double* pvalue){{{1*/
Index: /issm/trunk/src/c/objects/Inputs/ControlInput.h
===================================================================
--- /issm/trunk/src/c/objects/Inputs/ControlInput.h	(revision 6259)
+++ /issm/trunk/src/c/objects/Inputs/ControlInput.h	(revision 6260)
@@ -18,4 +18,5 @@
 	public:
 		int    enum_type;
+		int    control_id;
 		Input* values;
 		Input* savedvalues;
@@ -24,5 +25,5 @@
 		/*ControlInput constructors, destructors: {{{1*/
 		ControlInput();
-		ControlInput(int enum_type,int enum_input,double* pvalues);
+		ControlInput(int enum_type,int enum_input,double* pvalues,int id);
 		~ControlInput();
 		/*}}}*/
Index: /issm/trunk/src/c/objects/Materials/Matice.cpp
===================================================================
--- /issm/trunk/src/c/objects/Materials/Matice.cpp	(revision 6259)
+++ /issm/trunk/src/c/objects/Materials/Matice.cpp	(revision 6260)
@@ -37,75 +37,6 @@
 	this->inputs=new Inputs();
 
-	/*if 2d*/
-	if(iomodel->dim==2){
-
-		/*Intermediaries*/
-		const int num_vertices = 3; //Tria has 3 vertices
-		double    nodeinputs[num_vertices];
-
-		/*Get B*/
-		if (iomodel->rheology_B) {
-			for(i=0;i<num_vertices;i++) nodeinputs[i]=iomodel->rheology_B[int(iomodel->elements[num_vertices*index+i]-1)];
-			this->inputs->AddInput(new TriaVertexInput(RheologyBbarEnum,nodeinputs));
-		}
-
-		/*Get n*/
-		if (iomodel->rheology_n) {
-			for(i=0;i<num_vertices;i++) nodeinputs[i]=iomodel->rheology_n[index];
-			this->inputs->AddInput(new TriaVertexInput(RheologyNEnum,nodeinputs));
-		}
-
-		/*Control Inputs*/
-		if (iomodel->control_analysis && iomodel->control_type){
-			for(i=0;i<iomodel->num_control_type;i++){
-				switch((int)iomodel->control_type[i]){
-					case RheologyBbarEnum:
-						if (iomodel->rheology_B){
-							for(i=0;i<num_vertices;i++)nodeinputs[i]=iomodel->rheology_B[int(iomodel->elements[num_vertices*index+i]-1)];
-							this->inputs->AddInput(new ControlInput(RheologyBbarEnum,TriaVertexInputEnum,nodeinputs));
-						}
-						break;
-				}
-			}
-		}
-	}
-
-	/*if 3d*/
-	else if(iomodel->dim==3){
-
-		/*Intermediaries*/
-		const int num_vertices = 6; //Penta has 6 vertices
-		double    nodeinputs[num_vertices];
-
-		/*Get B*/
-		if (iomodel->rheology_B) {
-			for(i=0;i<num_vertices;i++) nodeinputs[i]=iomodel->rheology_B[int(iomodel->elements[num_vertices*index+i]-1)];
-			this->inputs->AddInput(new PentaVertexInput(RheologyBEnum,nodeinputs));
-		}
-
-		/*Get n*/
-		if (iomodel->rheology_n) {
-			for(i=0;i<num_vertices;i++) nodeinputs[i]=iomodel->rheology_n[index];
-			this->inputs->AddInput(new PentaVertexInput(RheologyNEnum,nodeinputs));
-		}
-
-		/*Control Inputs*/
-		if (iomodel->control_analysis && iomodel->control_type){
-			for(i=0;i<iomodel->num_control_type;i++){
-				switch((int)iomodel->control_type[i]){
-					case RheologyBbarEnum:
-						if (iomodel->rheology_B){
-							for(i=0;i<num_vertices;i++)nodeinputs[i]=iomodel->rheology_B[int(iomodel->elements[num_vertices*index+i]-1)];
-							this->inputs->AddInput(new ControlInput(RheologyBEnum,PentaVertexInputEnum,nodeinputs));
-						}
-						break;
-				}
-			}
-		}
-	}
-	else{
-		ISSMERROR(" Mesh type not supported yet!");
-	}
-
+	/*Initialize inputs from IoModel*/
+	this->InputUpdateFromIoModel(index,iomodel);
 
 	/*Hooks: */
@@ -678,4 +609,16 @@
 		double    nodeinputs[num_vertices];
 
+		/*Get B*/
+		if (iomodel->rheology_B) {
+			for(i=0;i<num_vertices;i++) nodeinputs[i]=iomodel->rheology_B[int(iomodel->elements[num_vertices*index+i]-1)];
+			this->inputs->AddInput(new TriaVertexInput(RheologyBbarEnum,nodeinputs));
+		}
+
+		/*Get n*/
+		if (iomodel->rheology_n) {
+			for(i=0;i<num_vertices;i++) nodeinputs[i]=iomodel->rheology_n[index];
+			this->inputs->AddInput(new TriaVertexInput(RheologyNEnum,nodeinputs));
+		}
+
 		/*Control Inputs*/
 		if (iomodel->control_analysis && iomodel->control_type){
@@ -685,5 +628,5 @@
 						if (iomodel->rheology_B){
 							for(j=0;j<num_vertices;j++)nodeinputs[j]=iomodel->rheology_B[int(iomodel->elements[num_vertices*index+j]-1)];
-							this->inputs->AddInput(new ControlInput(RheologyBbarEnum,TriaVertexInputEnum,nodeinputs));
+							this->inputs->AddInput(new ControlInput(RheologyBbarEnum,TriaVertexInputEnum,nodeinputs,i+1));
 						}
 						break;
@@ -699,4 +642,16 @@
 		const int num_vertices = 6; //Penta has 6 vertices
 		double    nodeinputs[num_vertices];
+
+		/*Get B*/
+		if (iomodel->rheology_B) {
+			for(i=0;i<num_vertices;i++) nodeinputs[i]=iomodel->rheology_B[int(iomodel->elements[num_vertices*index+i]-1)];
+			this->inputs->AddInput(new PentaVertexInput(RheologyBEnum,nodeinputs));
+		}
+
+		/*Get n*/
+		if (iomodel->rheology_n) {
+			for(i=0;i<num_vertices;i++) nodeinputs[i]=iomodel->rheology_n[index];
+			this->inputs->AddInput(new PentaVertexInput(RheologyNEnum,nodeinputs));
+		}
 
 		/*Control Inputs*/
@@ -707,5 +662,5 @@
 						if (iomodel->rheology_B){
 							for(j=0;j<num_vertices;j++)nodeinputs[j]=iomodel->rheology_B[int(iomodel->elements[num_vertices*index+j]-1)];
-							this->inputs->AddInput(new ControlInput(RheologyBEnum,PentaVertexInputEnum,nodeinputs));
+							this->inputs->AddInput(new ControlInput(RheologyBEnum,PentaVertexInputEnum,nodeinputs,i+1));
 						}
 						break;
Index: /issm/trunk/src/c/objects/Params/DoubleVecParam.cpp
===================================================================
--- /issm/trunk/src/c/objects/Params/DoubleVecParam.cpp	(revision 6259)
+++ /issm/trunk/src/c/objects/Params/DoubleVecParam.cpp	(revision 6260)
@@ -146,5 +146,5 @@
 
 /*DoubleVecParam virtual functions definitions: */
-/*FUNCTION DoubleVecParam::GetParameterValue{{{1*/
+/*FUNCTION DoubleVecParam::GetParameterValue(double** pdoublearray,int* pM){{{1*/
 void  DoubleVecParam::GetParameterValue(double** pdoublearray,int* pM){
 	double* output=NULL;
@@ -158,4 +158,22 @@
 	if(pM) *pM=M;
 	*pdoublearray=output;
+}
+/*}}}*/
+/*FUNCTION DoubleVecParam::GetParameterValue(int** pintarray,int* pM){{{1*/
+void  DoubleVecParam::GetParameterValue(int** pintarray,int* pM){
+#ifdef _SERIAL_
+	int* output=NULL;
+	int i;
+
+	/*Cast values into integers*/
+	output=(int*)xmalloc(M*sizeof(int));
+	for(i=0;i<M;i++) output[i]=(int)values[i];
+
+	/*Assign output pointers:*/
+	if(pM) *pM=M;
+	*pintarray=output;
+#else
+	ISSMERROR("Double param of enum %i (%s) cannot return an array of double",enum_type,EnumToString(enum_type));
+#endif
 }
 /*}}}*/
Index: /issm/trunk/src/c/objects/Params/DoubleVecParam.h
===================================================================
--- /issm/trunk/src/c/objects/Params/DoubleVecParam.h	(revision 6259)
+++ /issm/trunk/src/c/objects/Params/DoubleVecParam.h	(revision 6260)
@@ -52,5 +52,5 @@
 		void  GetParameterValue(bool* pbool){ISSMERROR("DoubleVec param of enum %i (%s) cannot return a bool",enum_type,EnumToString(enum_type));}
 		void  GetParameterValue(int* pinteger){ISSMERROR("DoubleVec param of enum %i (%s) cannot return an integer",enum_type,EnumToString(enum_type));}
-		void  GetParameterValue(int** pintarray,int* pM){ISSMERROR("DoubleVec param of enum %i (%s) cannot return an array of integers",enum_type,EnumToString(enum_type));}
+		void  GetParameterValue(int** pintarray,int* pM);
 		void  GetParameterValue(double* pdouble){ISSMERROR("DoubleVec param of enum %i (%s) cannot return a double",enum_type,EnumToString(enum_type));}
 		void  GetParameterValue(char** pstring){ISSMERROR("DoubleVec param of enum %i (%s) cannot return a string",enum_type,EnumToString(enum_type));}
