Index: /issm/trunk-jpl/src/c/analyses/control_core.cpp
===================================================================
--- /issm/trunk-jpl/src/c/analyses/control_core.cpp	(revision 16477)
+++ /issm/trunk-jpl/src/c/analyses/control_core.cpp	(revision 16478)
@@ -98,5 +98,5 @@
 	/*some results not computed by steadystate_core or stressbalance_core: */
 	if(!dakota_analysis){ //do not save this if we are running the control core from a qmu run!
-		for(i=0;i<num_controls;i++) InputToResultx(femmodel,control_type[i]);
+		femmodel->OutputControlsx(&femmodel->results);
 
 		#ifdef _HAVE_ADOLC_
Index: /issm/trunk-jpl/src/c/analyses/damage_core.cpp
===================================================================
--- /issm/trunk-jpl/src/c/analyses/damage_core.cpp	(revision 16477)
+++ /issm/trunk-jpl/src/c/analyses/damage_core.cpp	(revision 16478)
@@ -34,5 +34,6 @@
 	if(save_results){
 		if(VerboseSolution()) _printf0_("   saving results\n");
-		InputToResultx(femmodel,DamageDEnum);
+		const char* outputs [] = {"DamageD"};
+		femmodel->RequestedOutputsx(&femmodel->results,(char**)&outputs[0],1);
 	}
 }
Index: /issm/trunk-jpl/src/c/analyses/gia_core.cpp
===================================================================
--- /issm/trunk-jpl/src/c/analyses/gia_core.cpp	(revision 16477)
+++ /issm/trunk-jpl/src/c/analyses/gia_core.cpp	(revision 16478)
@@ -50,6 +50,6 @@
 	if(save_results){
 		if(VerboseSolution()) _printf0_("   saving results\n");
-		InputToResultx(femmodel,GiaWEnum);
-		InputToResultx(femmodel,GiadWdtEnum);
+		const char* outputs [] = {"GiaW","GiadWdt"};
+		femmodel->RequestedOutputsx(&femmodel->results,(char**)&outputs[0],2);
 	}
 
Index: /issm/trunk-jpl/src/c/analyses/hydrology_core.cpp
===================================================================
--- /issm/trunk-jpl/src/c/analyses/hydrology_core.cpp	(revision 16477)
+++ /issm/trunk-jpl/src/c/analyses/hydrology_core.cpp	(revision 16478)
@@ -88,6 +88,4 @@
 			if(save_results && ((i+1)%output_frequency==0 || (i+1)==nsteps)){
 				if(VerboseSolution()) _printf0_("   saving results \n");
-				InputToResultx(femmodel,SedimentHeadEnum);
-				InputToResultx(femmodel,SedimentHeadResidualEnum);
 				if(isefficientlayer){
 					const char* outputs [] = {"SedimentHead","SedimentHeadResidual","EplHead","HydrologydcMaskEplactive"};
Index: /issm/trunk-jpl/src/c/analyses/transient_core.cpp
===================================================================
--- /issm/trunk-jpl/src/c/analyses/transient_core.cpp	(revision 16477)
+++ /issm/trunk-jpl/src/c/analyses/transient_core.cpp	(revision 16478)
@@ -162,12 +162,12 @@
 		if(save_results){
 			if(VerboseSolution()) _printf0_("   saving transient results\n");
-			InputToResultx(femmodel,SurfaceforcingsMassBalanceEnum);
-			femmodel->RequestedOutputsx(requested_outputs,numoutputs);
+			femmodel->RequestedOutputsx(&femmodel->results,requested_outputs,numoutputs);
 			if(isdelta18o){
-				InputToResultx(femmodel,SurfaceforcingsMonthlytemperaturesEnum);
-				InputToResultx(femmodel,SurfaceforcingsPrecipitationEnum);
+				const char* outputs [] = {"SurfaceforcingsMonthlytemperatures","SurfaceforcingsPrecipitation"};
+				femmodel->RequestedOutputsx(&femmodel->results,(char**)&outputs[0],2);
 			}
 			if(isgroundingline && (groundingline_migration==SubelementMigrationEnum || groundingline_migration==SubelementMigration2Enum)){
-				InputToResultx(femmodel,MaskGroundediceLevelsetEnum);
+				const char* outputs [] = {"MaskGroundediceLevelset"};
+				femmodel->RequestedOutputsx(&femmodel->results,(char**)&outputs[0],1);
 			}
 			if(VerboseSolution()) _printf0_("   saving temporary results\n");
Index: /issm/trunk-jpl/src/c/classes/Elements/Element.h
===================================================================
--- /issm/trunk-jpl/src/c/classes/Elements/Element.h	(revision 16477)
+++ /issm/trunk-jpl/src/c/classes/Elements/Element.h	(revision 16478)
@@ -121,4 +121,5 @@
 		virtual void   ControlInputSetGradient(IssmDouble* gradient,int enum_type,int control_index)=0;
 		virtual void   ControlInputScaleGradient(int enum_type, IssmDouble scale)=0;
+		virtual void   ControlToVectors(Vector<IssmDouble>* vector_control, Vector<IssmDouble>* vector_gradient,int control_enum)=0;
 		virtual void   GetVectorFromControlInputs(Vector<IssmDouble>* gradient,int control_enum,int control_index,const char* data)=0;
 		virtual void   SetControlInputsFromVector(IssmDouble* vector,int control_enum,int control_index)=0;
Index: /issm/trunk-jpl/src/c/classes/Elements/Penta.cpp
===================================================================
--- /issm/trunk-jpl/src/c/classes/Elements/Penta.cpp	(revision 16477)
+++ /issm/trunk-jpl/src/c/classes/Elements/Penta.cpp	(revision 16478)
@@ -5330,4 +5330,44 @@
 	grad_input=new PentaInput(GradientEnum,grad_list,P1Enum);
 	((ControlInput*)input)->SetGradient(grad_input);
+
+}/*}}}*/
+/*FUNCTION Penta::ControlInputSetGradient{{{*/
+void Penta::ControlToVectors(Vector<IssmDouble>* vector_control, Vector<IssmDouble>* vector_gradient,int control_enum){
+
+	Input* input=NULL;
+
+	if(control_enum==MaterialsRheologyBbarEnum){
+		input=(Input*)material->inputs->GetInput(MaterialsRheologyBEnum);
+	}
+	else if(control_enum==DamageDbarEnum){
+		input=(Input*)material->inputs->GetInput(DamageDEnum);
+	}
+	else{
+		input=inputs->GetInput(control_enum);
+	}
+	if (!input) _error_("Input " << EnumToStringx(control_enum) << " not found");
+	if (input->ObjectEnum()!=ControlInputEnum) _error_("Input " << EnumToStringx(control_enum) << " is not a ControlInput");
+
+	int          sidlist[NUMVERTICES];
+	IssmPDouble   values[NUMVERTICES];
+	IssmPDouble gradients[NUMVERTICES]; 
+	IssmDouble  value,gradient;
+
+	GetVertexSidList(&sidlist[0]);
+
+	GaussPenta* gauss=new GaussPenta();
+	for (int iv=0;iv<NUMVERTICES;iv++){
+		gauss->GaussVertex(iv);
+
+		((ControlInput*)input)->GetInputValue(&value,gauss);
+		((ControlInput*)input)->GetGradientValue(&gradient,gauss);
+
+		values[iv]    = reCast<IssmPDouble>(value);
+		gradients[iv] = reCast<IssmPDouble>(gradient);
+	}
+	delete gauss;
+
+	vector_control->SetValues(NUMVERTICES,&sidlist[0],&values[0],INS_VAL);
+	vector_gradient->SetValues(NUMVERTICES,&sidlist[0],&gradients[0],INS_VAL);
 
 }/*}}}*/
Index: /issm/trunk-jpl/src/c/classes/Elements/Penta.h
===================================================================
--- /issm/trunk-jpl/src/c/classes/Elements/Penta.h	(revision 16477)
+++ /issm/trunk-jpl/src/c/classes/Elements/Penta.h	(revision 16478)
@@ -152,4 +152,5 @@
 		void   ControlInputScaleGradient(int enum_type,IssmDouble scale);
 		void   ControlInputSetGradient(IssmDouble* gradient,int enum_type,int control_index);
+		void   ControlToVectors(Vector<IssmDouble>* vector_control, Vector<IssmDouble>* vector_gradient,int control_enum);
 		IssmDouble RheologyBbarAbsGradient(void);
 		IssmDouble ThicknessAbsMisfit(void);
Index: /issm/trunk-jpl/src/c/classes/Elements/Seg.h
===================================================================
--- /issm/trunk-jpl/src/c/classes/Elements/Seg.h	(revision 16477)
+++ /issm/trunk-jpl/src/c/classes/Elements/Seg.h	(revision 16478)
@@ -172,4 +172,5 @@
 		void       ControlInputScaleGradient(int enum_type,IssmDouble scale){_error_("not implemented yet");};
 		void       ControlInputSetGradient(IssmDouble* gradient,int enum_type,int control_index){_error_("not implemented yet");};
+		void       ControlToVectors(Vector<IssmDouble>* vector_control, Vector<IssmDouble>* vector_gradient,int control_enum){_error_("not implemented yet");};
 		IssmDouble RheologyBbarAbsGradient(void){_error_("not implemented yet");};
 		IssmDouble ThicknessAbsMisfit(void){_error_("not implemented yet");};
Index: /issm/trunk-jpl/src/c/classes/Elements/Tria.cpp
===================================================================
--- /issm/trunk-jpl/src/c/classes/Elements/Tria.cpp	(revision 16477)
+++ /issm/trunk-jpl/src/c/classes/Elements/Tria.cpp	(revision 16478)
@@ -4871,4 +4871,40 @@
 
 	((ControlInput*)input)->SetGradient(grad_input);
+
+}/*}}}*/
+/*FUNCTION Tria::ControlInputSetGradient{{{*/
+void Tria::ControlToVectors(Vector<IssmDouble>* vector_control, Vector<IssmDouble>* vector_gradient,int control_enum){
+
+	Input* input=NULL;
+	if(control_enum==MaterialsRheologyBbarEnum || control_enum==DamageDbarEnum){
+		input=(Input*)material->inputs->GetInput(control_enum);
+	}
+	else{
+		input=inputs->GetInput(control_enum);
+	}
+	if (!input) _error_("Input " << EnumToStringx(control_enum) << " not found");
+	if (input->ObjectEnum()!=ControlInputEnum) _error_("Input " << EnumToStringx(control_enum) << " is not a ControlInput");
+
+	int          sidlist[NUMVERTICES];
+	IssmPDouble   values[NUMVERTICES];
+	IssmPDouble gradients[NUMVERTICES]; 
+	IssmDouble  value,gradient;
+
+	GetVertexSidList(&sidlist[0]);
+
+	GaussTria* gauss=new GaussTria();
+	for (int iv=0;iv<NUMVERTICES;iv++){
+		gauss->GaussVertex(iv);
+
+		((ControlInput*)input)->GetInputValue(&value,gauss);
+		((ControlInput*)input)->GetGradientValue(&gradient,gauss);
+
+		values[iv]    = reCast<IssmPDouble>(value);
+		gradients[iv] = reCast<IssmPDouble>(gradient);
+	}
+	delete gauss;
+
+	vector_control->SetValues(NUMVERTICES,&sidlist[0],&values[0],INS_VAL);
+	vector_gradient->SetValues(NUMVERTICES,&sidlist[0],&gradients[0],INS_VAL);
 
 }/*}}}*/
Index: /issm/trunk-jpl/src/c/classes/Elements/Tria.h
===================================================================
--- /issm/trunk-jpl/src/c/classes/Elements/Tria.h	(revision 16477)
+++ /issm/trunk-jpl/src/c/classes/Elements/Tria.h	(revision 16478)
@@ -161,4 +161,5 @@
 		void       ControlInputScaleGradient(int enum_type,IssmDouble scale);
 		void       ControlInputSetGradient(IssmDouble* gradient,int enum_type,int control_index);
+		void       ControlToVectors(Vector<IssmDouble>* vector_control, Vector<IssmDouble>* vector_gradient,int control_enum);
 		IssmDouble RheologyBbarAbsGradient(void);
 		IssmDouble ThicknessAbsMisfit(void);
Index: /issm/trunk-jpl/src/c/classes/FemModel.cpp
===================================================================
--- /issm/trunk-jpl/src/c/classes/FemModel.cpp	(revision 16477)
+++ /issm/trunk-jpl/src/c/classes/FemModel.cpp	(revision 16478)
@@ -639,4 +639,22 @@
 }
 /*}}}*/
+void FemModel::RequestedOutputsx(Results **presults,int* requested_outputs, int numoutputs){/*{{{*/
+
+	/*Convert list of enums to list of string*/
+	char** enumlist = xNew<char*>(numoutputs);
+	for(int i=0;i<numoutputs;i++){
+		EnumToStringx(&enumlist[i],requested_outputs[i]);
+	}
+
+	/*Call main module*/
+	this->RequestedOutputsx(presults,enumlist,numoutputs);
+
+
+	/*clean up and return*/
+	for(int i=0;i<numoutputs;i++) xDelete<char>(enumlist[i]);
+	xDelete<char*>(enumlist);
+	return;
+}
+/*}}}*/
 void FemModel::RequestedDependentsx(void){/*{{{*/
 
@@ -1207,4 +1225,50 @@
 }
 /*}}}*/
+void FemModel::OutputControlsx(Results **presults){/*{{{*/
+
+	/*parameters: */
+	int         num_controls,step;
+	IssmDouble  time;
+	int        *control_type = NULL;
+
+	/*recover results*/
+	Results* results = *presults;
+	if(!results) results = new Results();
+
+	/*Get list of Controls*/
+	this->parameters->FindParam(&num_controls,InversionNumControlParametersEnum);
+	this->parameters->FindParam(&control_type,NULL,InversionControlParametersEnum);
+	this->parameters->FindParam(&step,StepEnum);
+	this->parameters->FindParam(&time,TimeEnum);
+
+	for(int i=0;i<num_controls;i++){
+
+		int control_enum = control_type[i];
+		int gradient_enum;
+
+		switch(i){
+			case 0: gradient_enum = Gradient1Enum; break;
+			case 1: gradient_enum = Gradient2Enum; break;
+			case 2: gradient_enum = Gradient3Enum; break;
+			default: _error_("more than 3 controls not implemented yet");
+		}
+
+		/*Allocate vector*/
+		Vector<IssmPDouble> *vector_control  = new Vector<IssmPDouble>(this->vertices->NumberOfVertices());
+		Vector<IssmPDouble> *vector_gradient = new Vector<IssmPDouble>(this->vertices->NumberOfVertices());
+
+		/*Fill in vector*/
+		for(int j=0;j<elements->Size();j++){
+			Element* element=(Element*)elements->GetObjectByOffset(j);
+			element->ControlToVectors(vector_control,vector_gradient,control_enum);
+		}
+		vector_control->Assemble();
+		vector_gradient->Assemble();
+
+		results->AddResult(new GenericExternalResult<Vector<IssmPDouble>*>(results->Size()+1,control_enum,vector_control ,step,time));
+		results->AddResult(new GenericExternalResult<Vector<IssmPDouble>*>(results->Size()+1,gradient_enum,vector_gradient,step,time));
+	}
+}
+/*}}}*/
 #endif
 #ifdef  _HAVE_DAKOTA_
Index: /issm/trunk-jpl/src/c/classes/FemModel.h
===================================================================
--- /issm/trunk-jpl/src/c/classes/FemModel.h	(revision 16477)
+++ /issm/trunk-jpl/src/c/classes/FemModel.h	(revision 16478)
@@ -82,4 +82,5 @@
 		void DakotaResponsesx(double* d_responses,char** responses_descriptors,int numresponsedescriptors,int d_numresponses);
 		#endif
+		void RequestedOutputsx(Results **presults,int* requested_outputs,int numoutputs);
 		void RequestedOutputsx(Results **presults,char** requested_outputs, int numoutputs);
 		void RequestedOutputsx(char** requested_outputs, int numoutputs);
@@ -88,4 +89,5 @@
 		void Responsex(IssmDouble* presponse,const char* response_descriptor);
 		#ifdef _HAVE_CONTROL_
+		void OutputControlsx(Results **presults);
 		void CostFunctionx( IssmDouble* pJ);
 		void ThicknessAbsGradientx( IssmDouble* pJ);
Index: /issm/trunk-jpl/src/c/classes/Inputs/ControlInput.cpp
===================================================================
--- /issm/trunk-jpl/src/c/classes/Inputs/ControlInput.cpp	(revision 16477)
+++ /issm/trunk-jpl/src/c/classes/Inputs/ControlInput.cpp	(revision 16478)
@@ -139,4 +139,11 @@
 	//gradient->Extrude();
 }/*}}}*/
+/*FUNCTION ControlInput::GetResultInterpolation{{{*/
+int  ControlInput::GetResultInterpolation(void){
+
+	return values->GetResultInterpolation();
+
+}
+/*}}}*/
 /*FUNCTION ControlInput::GetGradient{{{*/
 void ControlInput::GetGradient(Vector<IssmDouble>* gradient_vec,int* doflist){
@@ -245,4 +252,12 @@
 	values->GetInputValue(pvalue,gauss);
 }/*}}}*/
+/*FUNCTION ControlInput::GetGradientValue(IssmDouble* pvalue,GaussTria* gauss){{{*/
+void ControlInput::GetGradientValue(IssmDouble* pvalue,GaussTria* gauss){
+	gradient->GetInputValue(pvalue,gauss);
+}/*}}}*/
+/*FUNCTION ControlInput::GetGradientValue(IssmDouble* pvalue,GaussPenta* gauss){{{*/
+void ControlInput::GetGradientValue(IssmDouble* pvalue,GaussPenta* gauss){
+	gradient->GetInputValue(pvalue,gauss);
+}/*}}}*/
 /*FUNCTION ControlInput::GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussTria* gauss){{{*/
 void ControlInput::GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, GaussTria* gauss){
Index: /issm/trunk-jpl/src/c/classes/Inputs/ControlInput.h
===================================================================
--- /issm/trunk-jpl/src/c/classes/Inputs/ControlInput.h	(revision 16477)
+++ /issm/trunk-jpl/src/c/classes/Inputs/ControlInput.h	(revision 16478)
@@ -48,4 +48,6 @@
 		/*}}}*/
 		/*numerics: {{{*/
+		void GetGradientValue(IssmDouble* pvalue,GaussTria* gauss);
+		void GetGradientValue(IssmDouble* pvalue,GaussPenta* gauss);
 		void SetInput(Input* in_input);
 		void GetInputValue(bool* pvalue);
@@ -90,5 +92,5 @@
 		void GetVectorFromInputs(Vector<IssmDouble>* vector,int* doflist);
 		ElementResult* SpawnGradient(int step, IssmDouble time);
-		int  GetResultInterpolation(void){_error_("not implemented yet");};
+		int  GetResultInterpolation(void);
 		void GetGradient(Vector<IssmDouble>* gradient_vec,int* doflist);
 		void ScaleGradient(IssmDouble scale);
Index: /issm/trunk-jpl/src/m/classes/transient.m
===================================================================
--- /issm/trunk-jpl/src/m/classes/transient.m	(revision 16477)
+++ /issm/trunk-jpl/src/m/classes/transient.m	(revision 16478)
@@ -26,10 +26,17 @@
 
 			%full analysis: Stressbalance, Masstransport and Thermal but no groundingline migration for now
-			obj.ismasstransport=1;
-			obj.isstressbalance=1;
-			obj.isthermal=1;
-			obj.isgroundingline=0;
-			obj.isgia=0;
-			obj.isdamage=0;
+			obj.ismasstransport = 1;
+			obj.isstressbalance = 1;
+			obj.isthermal       = 1;
+			obj.isgroundingline = 0;
+			obj.isgia           = 0;
+			obj.isdamage        = 0;
+
+			%default output
+			obj.requested_outputs={'default'};
+		end % }}}
+		function list = defaultoutputs(self,md) % {{{
+
+			list = {'SurfaceforcingsMassBalance'};
 
 		end % }}}
@@ -67,5 +74,13 @@
 			WriteData(fid,'object',obj,'fieldname','isgia','format','Boolean');
 			WriteData(fid,'object',obj,'fieldname','isdamage','format','Boolean');
-			WriteData(fid,'object',obj,'fieldname','requested_outputs','format','StringArray');
+
+			%process requested outputs
+			outputs = obj.requested_outputs;
+			pos  = find(ismember(outputs,'default'));
+			if ~isempty(pos),
+				outputs(pos) = [];                         %remove 'default' from outputs
+				outputs      = [outputs defaultoutputs(obj,md)]; %add defaults
+			end
+			WriteData(fid,'data',outputs,'enum',TransientRequestedOutputsEnum,'format','StringArray');
 		end % }}}
 	end
Index: /issm/trunk-jpl/src/m/classes/transient.py
===================================================================
--- /issm/trunk-jpl/src/m/classes/transient.py	(revision 16477)
+++ /issm/trunk-jpl/src/m/classes/transient.py	(revision 16478)
@@ -34,13 +34,20 @@
 		return string
 		#}}}
+	def defaultoutputs(self,md): # {{{
+
+		return ['SurfaceforcingsMassBalance']
+
+	#}}}
 	def setdefaultparameters(self): # {{{
 		
 		#full analysis: Stressbalance, Masstransport and Thermal but no groundingline migration for now
-		self.ismasstransport=True
-		self.isstressbalance=True
-		self.isthermal=True
-		self.isgroundingline=False
-		self.isgia=False
+		self.ismasstransport = True
+		self.isstressbalance = True
+		self.isthermal       = True
+		self.isgroundingline = False
+		self.isgia           = False
 
+		#default output
+		self.requested_outputs=['default']
 		return self
 	#}}}
@@ -66,5 +73,11 @@
 		WriteData(fid,'object',self,'fieldname','isgroundingline','format','Boolean')
 		WriteData(fid,'object',self,'fieldname','isgia','format','Boolean')
-		WriteData(fid,'object',self,'fieldname','requested_outputs','format','StringArray')
+
+		#process requested outputs
+		outputs = self.requested_outputs
+		indices = [i for i, x in enumerate(outputs) if x == 'default']
+		if len(indices) > 0:
+			outputscopy=outputs[0:max(0,indices[0]-1)]+self.defaultoutputs(md)+outputs[indices[0]+1:]
+			outputs    =outputscopy
+		WriteData(fid,'data',outputs,'enum',TransientRequestedOutputsEnum(),'format','StringArray')
 	# }}}
-
