Index: /issm/trunk-jpl/src/c/classes/Elements/Penta.cpp
===================================================================
--- /issm/trunk-jpl/src/c/classes/Elements/Penta.cpp	(revision 27723)
+++ /issm/trunk-jpl/src/c/classes/Elements/Penta.cpp	(revision 27724)
@@ -3498,7 +3498,4 @@
 		if(!IsOnBase()) return;
 	}
-
-	/*Get out if this is not an element input*/
-	if(!IsInputEnum(control_enum)) return;
 
 	/*Prepare index list*/
Index: /issm/trunk-jpl/src/c/classes/Elements/Tria.cpp
===================================================================
--- /issm/trunk-jpl/src/c/classes/Elements/Tria.cpp	(revision 27723)
+++ /issm/trunk-jpl/src/c/classes/Elements/Tria.cpp	(revision 27724)
@@ -5032,7 +5032,4 @@
 		}
 	}
-
-	/*Get out if this is not an element input*/
-	if(!IsInputEnum(control_enum)) return;
 
 	/*Get list of ids for this element and this control*/
Index: /issm/trunk-jpl/src/c/classes/Params/ControlParam.cpp
===================================================================
--- /issm/trunk-jpl/src/c/classes/Params/ControlParam.cpp	(revision 27723)
+++ /issm/trunk-jpl/src/c/classes/Params/ControlParam.cpp	(revision 27724)
@@ -62,5 +62,5 @@
 	
 		savedvalue=NULL;
-		gradient=NULL;
+		gradient=xNewZeroInit<IssmDouble>(M);
 	}
 	else{
@@ -78,4 +78,6 @@
 	xDelete<IssmDouble>(minvalue);
 	xDelete<IssmDouble>(maxvalue);
+	xDelete<IssmDouble>(gradient);
+	xDelete<IssmDouble>(savedvalue);
 	return;
 }
@@ -201,4 +203,6 @@
 void  ControlParam::SetGradient(IssmDouble* poutput, int in_M){/*{{{*/
 
+	_assert_(in_M==this->M);
+
 	/*avoid leak: */
 	xDelete<IssmDouble>(this->gradient);
Index: /issm/trunk-jpl/src/c/classes/Params/Parameters.cpp
===================================================================
--- /issm/trunk-jpl/src/c/classes/Params/Parameters.cpp	(revision 27723)
+++ /issm/trunk-jpl/src/c/classes/Params/Parameters.cpp	(revision 27724)
@@ -649,12 +649,21 @@
 }
 /*}}}*/
-void   Parameters::SetControlParam(IssmDouble* IssmDoublearray,int M, int enum_type){/*{{{*/
-
-	Param* param=NULL;
-
-	/*first, figure out if the param has already been created: */
-	param=xDynamicCast<Param*>(this->FindParamObject(enum_type));
-
-	if(param) param->SetValue(IssmDoublearray,M); //already exists, just set it.
+void   Parameters::SetControlFromVector(IssmDouble* vector, int enum_type, int M, int N, int offset){/*{{{*/
+
+	/*first, figure out if the param has already been created: */
+	Param* param=NULL;
+	param=xDynamicCast<Param*>(this->FindParamObject(enum_type));
+
+	if(param) param->SetValue(&vector[offset], M);
+	else _error_("Param "<< EnumToStringx(enum_type) << " cannot setValue");
+}
+/*}}}*/
+void   Parameters::SetGradientFromVector(IssmDouble* vector, int enum_type, int M, int N, int offset){/*{{{*/
+
+	/*first, figure out if the param has already been created: */
+	Param* param=NULL;
+	param=xDynamicCast<Param*>(this->FindParamObject(enum_type));
+
+	if(param) param->SetGradient(&vector[offset], M);
 	else _error_("Param "<< EnumToStringx(enum_type) << " cannot setValue");
 }
Index: /issm/trunk-jpl/src/c/classes/Params/Parameters.h
===================================================================
--- /issm/trunk-jpl/src/c/classes/Params/Parameters.h	(revision 27723)
+++ /issm/trunk-jpl/src/c/classes/Params/Parameters.h	(revision 27724)
@@ -74,5 +74,6 @@
 		void  SetParam(FILE* fid,int enum_type);
 		void  SetParam(DataSet* dataset,int enum_type);
-		void  SetControlParam(IssmDouble* IssmDoublearray,int M, int enum_type);
+		void  SetControlFromVector(IssmDouble* array, int enum_type, int M, int N, int offset);
+		void  SetGradientFromVector(IssmDouble* array, int enum_type, int M, int N, int offset);
 		void  ControlParamSetGradient(IssmDouble* IssmDoublearray, int M, int enum_type);
 		void  GetVectorFromControl(Vector<IssmDouble>* vector,int control_enum,int control_index,int N,const char* data,int offset);
Index: /issm/trunk-jpl/src/c/cores/controladm1qn3_core.cpp
===================================================================
--- /issm/trunk-jpl/src/c/cores/controladm1qn3_core.cpp	(revision 27723)
+++ /issm/trunk-jpl/src/c/cores/controladm1qn3_core.cpp	(revision 27724)
@@ -251,18 +251,5 @@
 	#ifdef _HAVE_CODIPACK_
 	if(checkpoint_frequency && solution_type == TransientSolutionEnum){
-		if(IsParamEnum(control_enum[0])){
-#ifdef _HAVE_AD_
-			IssmDouble* aX=xNew<IssmDouble>(intn,"t");
-#else
-			IssmDouble* aX=xNew<IssmDouble>(intn);
-#endif
-			for(int i=0;i<intn;i++) {
-				aX[i]=X[i];
-			}
-			femmodel->parameters->SetControlParam(aX,M[0],control_enum[0]);	
-		}
-		else{
-			SetControlInputsFromVectorx(femmodel,X);
-		}
+		SetControlInputsFromVectorx(femmodel,X);
 		*pf = transient_ad(femmodel, G, &Jlist[(*Jlisti)*JlistN]);
 	}
@@ -317,10 +304,5 @@
 
 		ISSM_MPI_Bcast(aX,intn,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
-		if(IsParamEnum(control_enum[0])){
-			femmodel->parameters->SetControlParam(aX,M[0],control_enum[0]);
-		}
-		else{
-			SetControlInputsFromVectorx(femmodel,aX);
-		}
+		SetControlInputsFromVectorx(femmodel,aX);
 		xDelete<IssmDouble>(aX);
 
@@ -673,12 +655,6 @@
 	}
 	
-	if(IsParamEnum(control_enum[0])){
-		//femmodel->parameters->ControlParamSetGradient(aG,M[0],control_enum[0]);
-		femmodel->parameters->SetControlParam(aX,M[0],control_enum[0]);	
-	}
-	else{
-		ControlInputSetGradientx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,aG);
-		SetControlInputsFromVectorx(femmodel,aX);
-	}
+	ControlInputSetGradientx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,aG);
+	SetControlInputsFromVectorx(femmodel,aX);
 	xDelete(aX);
 
Index: /issm/trunk-jpl/src/c/cores/transient_core.cpp
===================================================================
--- /issm/trunk-jpl/src/c/cores/transient_core.cpp	(revision 27723)
+++ /issm/trunk-jpl/src/c/cores/transient_core.cpp	(revision 27724)
@@ -392,11 +392,5 @@
 	delete hdl_regin;
 	if(my_rank==0) for(int i=0; i < Xsize; i++) tape_codi.registerInput(X[i]);
-	
-	if(IsParamEnum(control_enum[0])){
-		femmodel->parameters->SetControlParam(X,M[0],control_enum[0]);
-	}
-	else{
-		SetControlInputsFromVectorx(femmodel,X);
-	}
+	SetControlInputsFromVectorx(femmodel,X);
 	
 	IssmDouble J     = 0.;
@@ -461,11 +455,5 @@
 		/*Tell codipack that X is the independent*/
 		for(int i=0; i<Xsize; i++) tape_codi.registerInput(X[i]);
-		
-		if(IsParamEnum(control_enum[0])){
-			femmodel->parameters->SetControlParam(X,M[0],control_enum[0]);
-		}
-		else{
-			SetControlInputsFromVectorx(femmodel,X);
-		}
+		SetControlInputsFromVectorx(femmodel,X);
 
 		/*Get New state*/
Index: /issm/trunk-jpl/src/c/modules/ControlInputSetGradientx/ControlInputSetGradientx.cpp
===================================================================
--- /issm/trunk-jpl/src/c/modules/ControlInputSetGradientx/ControlInputSetGradientx.cpp	(revision 27723)
+++ /issm/trunk-jpl/src/c/modules/ControlInputSetGradientx/ControlInputSetGradientx.cpp	(revision 27724)
@@ -25,7 +25,16 @@
 	int offset = 0;
 	for(int i=0;i<num_controls;i++){
-		for(Object* & object : elements->objects){
-			Element* element=xDynamicCast<Element*>(object);
-			element->ControlInputSetGradient(gradient,control_type[i],i,offset,M_all[i],N_all[i],interp_all[i]);
+		/*Is the control a Param?*/
+		if(IsParamEnum(control_type[i])){
+			parameters->SetGradientFromVector(gradient, control_type[i], M_all[i], N_all[i], offset);
+		}
+		else if(IsInputEnum(control_type[i])){
+			for(Object* & object : elements->objects){
+				Element* element=xDynamicCast<Element*>(object);
+				element->ControlInputSetGradient(gradient,control_type[i],i,offset,M_all[i],N_all[i],interp_all[i]);
+			}
+		}
+		else{
+			_error_("not supported yet");
 		}
 		offset+=M_all[i]*N_all[i];
Index: /issm/trunk-jpl/src/c/modules/SetControlInputsFromVectorx/SetControlInputsFromVectorx.cpp
===================================================================
--- /issm/trunk-jpl/src/c/modules/SetControlInputsFromVectorx/SetControlInputsFromVectorx.cpp	(revision 27723)
+++ /issm/trunk-jpl/src/c/modules/SetControlInputsFromVectorx/SetControlInputsFromVectorx.cpp	(revision 27724)
@@ -22,7 +22,16 @@
 	int offset = 0;
 	for(int i=0;i<num_controls;i++){
-		for(Object* & object : femmodel->elements->objects){
-			Element* element=xDynamicCast<Element*>(object);
-			element->SetControlInputsFromVector(vector,control_type[i],i,offset,M[i],N[i]);
+		/*Is the control a Param?*/
+		if(IsParamEnum(control_type[i])){
+			femmodel->parameters->SetControlFromVector(vector,control_type[i],M[i],N[i],offset);
+		}
+		else if(IsInputEnum(control_type[i])){
+			for(Object* & object : femmodel->elements->objects){
+				Element* element=xDynamicCast<Element*>(object);
+				element->SetControlInputsFromVector(vector,control_type[i],i,offset,M[i],N[i]);
+			}
+		}
+		else{
+			_error_("not supported yet");
 		}
 		offset += M[i]*N[i]; 
