Index: /issm/trunk-jpl/src/c/cores/controlm1qn3_core.cpp
===================================================================
--- /issm/trunk-jpl/src/c/cores/controlm1qn3_core.cpp	(revision 17904)
+++ /issm/trunk-jpl/src/c/cores/controlm1qn3_core.cpp	(revision 17905)
@@ -35,6 +35,4 @@
 	IssmDouble  *X  = NULL;
 	IssmDouble  *G  = NULL;
-	IssmDouble  *XL = NULL;
-	IssmDouble  *XU = NULL;
 
 	/*Recover some parameters*/
@@ -139,4 +137,14 @@
 	femmodel->parameters->FindParam(&responses,&num_responses,InversionCostFunctionsEnum);
 
+	/*Constrain input vector*/
+	IssmDouble  *XL = NULL;
+	IssmDouble  *XU = NULL;
+	GetVectorFromControlInputsx(&XL,femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,"lowerbound");
+	GetVectorFromControlInputsx(&XU,femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,"upperbound");
+	for(long i=0;i<*n;i++){
+		if(X[i]>XU[i]) X[i]=XU[i];
+		if(X[i]<XL[i]) X[i]=XL[i];
+	}
+
 	/*Update control input*/
 	SetControlInputsFromVectorx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,X);
@@ -162,5 +170,11 @@
 	_printf0_("\n");
 
-	if(indic==0) return; /*dry run, no gradient required*/
+	if(indic==0){
+		/*dry run, no gradient required*/
+		xDelete<int>(responses);
+		xDelete<IssmDouble>(XU);
+		xDelete<IssmDouble>(XL);
+		return;
+	}
 
 	/*Compute Adjoint*/
@@ -172,8 +186,16 @@
 	Gradjx(&G2,NULL,femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters);
 	for(long i=0;i<*n;i++) G[i] = -G2[i];
+	xDelete<IssmDouble>(G2);
+
+	/*Constrain Gradient*/
+	for(long i=0;i<*n;i++){
+		if(X[i]>=XU[i]) G[i]=0.;
+		if(X[i]<=XL[i]) G[i]=0.;
+	}
 
 	/*Clean-up and return*/
 	xDelete<int>(responses);
-	xDelete<IssmDouble>(G2);
+	xDelete<IssmDouble>(XU);
+	xDelete<IssmDouble>(XL);
 }
 
