Index: /issm/trunk/src/c/Container/DataSet.cpp
===================================================================
--- /issm/trunk/src/c/Container/DataSet.cpp	(revision 8128)
+++ /issm/trunk/src/c/Container/DataSet.cpp	(revision 8129)
@@ -123,5 +123,5 @@
 	 * because this is a nasty error: */
 	if (marshalled_dataset!=old_marshalled_dataset){
-		_error_("final marshalled dataset is different from initial one!"); 
+		_error_("final marshalled dataset \"%s\" is different from initial one!",EnumToString(enum_type)); 
 		abort();
 	}
Index: /issm/trunk/src/c/modules/ModelProcessorx/Control/CreateParametersControl.cpp
===================================================================
--- /issm/trunk/src/c/modules/ModelProcessorx/Control/CreateParametersControl.cpp	(revision 8128)
+++ /issm/trunk/src/c/modules/ModelProcessorx/Control/CreateParametersControl.cpp	(revision 8129)
@@ -49,6 +49,4 @@
 		IoModelFetchData(&iomodel->cm_responses,NULL,NULL,iomodel_handle,"cm_responses");
 		IoModelFetchData(&iomodel->cm_jump,NULL,NULL,iomodel_handle,"cm_jump");
-		IoModelFetchData(&iomodel->cm_min,NULL,NULL,iomodel_handle,"cm_min");
-		IoModelFetchData(&iomodel->cm_max,NULL,NULL,iomodel_handle,"cm_max");
 		IoModelFetchData(&iomodel->optscal,NULL,NULL,iomodel_handle,"optscal");
 		IoModelFetchData(&iomodel->maxiter,NULL,NULL,iomodel_handle,"maxiter");
@@ -57,12 +55,8 @@
 		parameters->AddObject(new DoubleVecParam(CmJumpEnum,iomodel->cm_jump,iomodel->nsteps));
 		parameters->AddObject(new DoubleMatParam(OptScalEnum,iomodel->optscal,iomodel->nsteps,iomodel->num_control_type));
-		parameters->AddObject(new DoubleVecParam(CmMinEnum,iomodel->cm_min,iomodel->num_control_type));
-		parameters->AddObject(new DoubleVecParam(CmMaxEnum,iomodel->cm_max,iomodel->num_control_type));
 		parameters->AddObject(new DoubleVecParam(MaxIterEnum,iomodel->maxiter,iomodel->nsteps));
 
 		xfree((void**)&iomodel->cm_responses);
 		xfree((void**)&iomodel->cm_jump);
-		xfree((void**)&iomodel->cm_min);
-		xfree((void**)&iomodel->cm_max);
 		xfree((void**)&iomodel->optscal);
 		xfree((void**)&iomodel->maxiter);
Index: /issm/trunk/src/c/modules/ModelProcessorx/Control/UpdateElementsAndMaterialsControl.cpp
===================================================================
--- /issm/trunk/src/c/modules/ModelProcessorx/Control/UpdateElementsAndMaterialsControl.cpp	(revision 8128)
+++ /issm/trunk/src/c/modules/ModelProcessorx/Control/UpdateElementsAndMaterialsControl.cpp	(revision 8129)
@@ -28,4 +28,6 @@
 	IoModelFetchData(&iomodel->control_type,NULL,NULL,iomodel_handle,"control_type");
 	IoModelFetchData(&iomodel->weights,NULL,NULL,iomodel_handle,"weights");
+	IoModelFetchData(&iomodel->cm_min,NULL,NULL,iomodel_handle,"cm_min");
+	IoModelFetchData(&iomodel->cm_max,NULL,NULL,iomodel_handle,"cm_max");
 	IoModelFetchData(&iomodel->vx_obs,NULL,NULL,iomodel_handle,"vx_obs");
 	IoModelFetchData(&iomodel->vy_obs,NULL,NULL,iomodel_handle,"vy_obs");
@@ -69,4 +71,6 @@
 	xfree((void**)&iomodel->elements);
 	xfree((void**)&iomodel->weights);
+	xfree((void**)&iomodel->cm_min);
+	xfree((void**)&iomodel->cm_max);
 	xfree((void**)&iomodel->control_type);
 	xfree((void**)&iomodel->vx_obs);
Index: /issm/trunk/src/c/modules/ModelProcessorx/CreateElementsVerticesAndMaterials.cpp
===================================================================
--- /issm/trunk/src/c/modules/ModelProcessorx/CreateElementsVerticesAndMaterials.cpp	(revision 8128)
+++ /issm/trunk/src/c/modules/ModelProcessorx/CreateElementsVerticesAndMaterials.cpp	(revision 8129)
@@ -42,4 +42,6 @@
 	IoModelFetchData(&iomodel->rheology_n,NULL,NULL,iomodel_handle,"rheology_n");
 	IoModelFetchData(&iomodel->control_type,NULL,NULL,iomodel_handle,"control_type");
+	IoModelFetchData(&iomodel->cm_min,NULL,NULL,iomodel_handle,"cm_min");
+	IoModelFetchData(&iomodel->cm_max,NULL,NULL,iomodel_handle,"cm_max");
 	
 	/*Create elements and materials: */
@@ -65,4 +67,6 @@
 	xfree((void**)&iomodel->rheology_n);
 	xfree((void**)&iomodel->control_type);
+	xfree((void**)&iomodel->cm_min);
+	xfree((void**)&iomodel->cm_max);
 
 	/*Add new constrant material property tgo materials, at the end: */
Index: /issm/trunk/src/c/objects/Elements/Penta.cpp
===================================================================
--- /issm/trunk/src/c/objects/Elements/Penta.cpp	(revision 8128)
+++ /issm/trunk/src/c/objects/Elements/Penta.cpp	(revision 8129)
@@ -3710,10 +3710,6 @@
 	int*   control_type=NULL;
 	Input* input=NULL;
-	double *cm_min=NULL;
-	double *cm_max=NULL;
 
 	/*retrieve some parameters: */
-	this->parameters->FindParam(&cm_min,NULL,CmMinEnum);
-	this->parameters->FindParam(&cm_max,NULL,CmMaxEnum);
 	this->parameters->FindParam(&num_controls,NumControlsEnum);
 	this->parameters->FindParam(&control_type,NULL,ControlTypeEnum);
@@ -3732,5 +3728,5 @@
 
 		((ControlInput*)input)->UpdateValue(scalar);
-		input->Constrain(cm_min[i],cm_max[i]);
+		((ControlInput*)input)->Constrain();
 		if (save_parameter) ((ControlInput*)input)->SaveValue();
 
@@ -3742,6 +3738,4 @@
 	/*Clean up and return*/
 	xfree((void**)&control_type);
-	xfree((void**)&cm_min);
-	xfree((void**)&cm_max);
 }
 /*}}}*/
@@ -3970,4 +3964,6 @@
 	int     penta_vertex_ids[6];
 	double  nodeinputs[6];
+	double  cmmininputs[6];
+	double  cmmaxinputs[6];
 
 	/*Checks if debuging*/
@@ -4074,5 +4070,7 @@
 					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,i+1));
+						for(j=0;j<6;j++)cmmininputs[j]=iomodel->cm_min[(penta_vertex_ids[j]-1)*iomodel->num_control_type+i]/iomodel->yts;
+						for(j=0;j<6;j++)cmmaxinputs[j]=iomodel->cm_max[(penta_vertex_ids[j]-1)*iomodel->num_control_type+i]/iomodel->yts;
+						this->inputs->AddInput(new ControlInput(DhDtEnum,PentaVertexInputEnum,nodeinputs,cmmininputs,cmmaxinputs,i+1));
 					}
 					break;
@@ -4080,5 +4078,7 @@
 					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,i+1));
+						for(j=0;j<6;j++)cmmininputs[j]=iomodel->cm_min[(penta_vertex_ids[j]-1)*iomodel->num_control_type+i]/iomodel->yts;
+						for(j=0;j<6;j++)cmmaxinputs[j]=iomodel->cm_max[(penta_vertex_ids[j]-1)*iomodel->num_control_type+i]/iomodel->yts;
+						this->inputs->AddInput(new ControlInput(VxEnum,PentaVertexInputEnum,nodeinputs,cmmininputs,cmmaxinputs,i+1));
 					}
 					break;
@@ -4086,5 +4086,7 @@
 					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,i+1));
+						for(j=0;j<6;j++)cmmininputs[j]=iomodel->cm_min[(penta_vertex_ids[j]-1)*iomodel->num_control_type+i]/iomodel->yts;
+						for(j=0;j<6;j++)cmmaxinputs[j]=iomodel->cm_max[(penta_vertex_ids[j]-1)*iomodel->num_control_type+i]/iomodel->yts;
+						this->inputs->AddInput(new ControlInput(VyEnum,PentaVertexInputEnum,nodeinputs,cmmininputs,cmmaxinputs,i+1));
 					}
 					break;
@@ -4092,5 +4094,7 @@
 					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,i+1));
+						for(j=0;j<6;j++)cmmininputs[j]=iomodel->cm_min[(penta_vertex_ids[j]-1)*iomodel->num_control_type+i];
+						for(j=0;j<6;j++)cmmaxinputs[j]=iomodel->cm_max[(penta_vertex_ids[j]-1)*iomodel->num_control_type+i];
+						this->inputs->AddInput(new ControlInput(DragCoefficientEnum,PentaVertexInputEnum,nodeinputs,cmmininputs,cmmaxinputs,i+1));
 					}
 					break;
Index: /issm/trunk/src/c/objects/Elements/Tria.cpp
===================================================================
--- /issm/trunk/src/c/objects/Elements/Tria.cpp	(revision 8128)
+++ /issm/trunk/src/c/objects/Elements/Tria.cpp	(revision 8129)
@@ -3662,10 +3662,6 @@
 	int*   control_type=NULL;
 	Input* input=NULL;
-	double *cm_min=NULL;
-	double *cm_max=NULL;
 
 	/*retrieve some parameters: */
-	this->parameters->FindParam(&cm_min,NULL,CmMinEnum);
-	this->parameters->FindParam(&cm_max,NULL,CmMaxEnum);
 	this->parameters->FindParam(&num_controls,NumControlsEnum);
 	this->parameters->FindParam(&control_type,NULL,ControlTypeEnum);
@@ -3685,5 +3681,5 @@
 
 		((ControlInput*)input)->UpdateValue(scalar);
-		input->Constrain(cm_min[i],cm_max[i]);
+		((ControlInput*)input)->Constrain();
 		if (save_parameter) ((ControlInput*)input)->SaveValue();
 
@@ -3692,6 +3688,4 @@
 	/*Clean up and return*/
 	xfree((void**)&control_type);
-	xfree((void**)&cm_min);
-	xfree((void**)&cm_max);
 }
 /*}}}*/
@@ -3827,4 +3821,6 @@
 	int    tria_vertex_ids[3];
 	double nodeinputs[3];
+	double cmmininputs[3];
+	double cmmaxinputs[3];
 
 	/*Checks if debuging*/
@@ -3952,5 +3948,7 @@
 					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,i+1));
+						for(j=0;j<3;j++)cmmininputs[j]=iomodel->cm_min[(tria_vertex_ids[j]-1)*iomodel->num_control_type+i]/iomodel->yts;
+						for(j=0;j<3;j++)cmmaxinputs[j]=iomodel->cm_max[(tria_vertex_ids[j]-1)*iomodel->num_control_type+i]/iomodel->yts;
+						this->inputs->AddInput(new ControlInput(DhDtEnum,TriaVertexInputEnum,nodeinputs,cmmininputs,cmmaxinputs,i+1));
 					}
 					break;
@@ -3958,5 +3956,7 @@
 					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,i+1));
+						for(j=0;j<3;j++)cmmininputs[j]=iomodel->cm_min[(tria_vertex_ids[j]-1)*iomodel->num_control_type+i]/iomodel->yts;
+						for(j=0;j<3;j++)cmmaxinputs[j]=iomodel->cm_max[(tria_vertex_ids[j]-1)*iomodel->num_control_type+i]/iomodel->yts;
+						this->inputs->AddInput(new ControlInput(VxEnum,TriaVertexInputEnum,nodeinputs,cmmininputs,cmmaxinputs,i+1));
 					}
 					break;
@@ -3964,5 +3964,7 @@
 					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,i+1));
+						for(j=0;j<3;j++)cmmininputs[j]=iomodel->cm_min[(tria_vertex_ids[j]-1)*iomodel->num_control_type+i]/iomodel->yts;
+						for(j=0;j<3;j++)cmmaxinputs[j]=iomodel->cm_max[(tria_vertex_ids[j]-1)*iomodel->num_control_type+i]/iomodel->yts;
+						this->inputs->AddInput(new ControlInput(VyEnum,TriaVertexInputEnum,nodeinputs,cmmininputs,cmmaxinputs,i+1));
 					}
 					break;
@@ -3970,5 +3972,7 @@
 					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,i+1));
+						for(j=0;j<3;j++)cmmininputs[j]=iomodel->cm_min[(tria_vertex_ids[j]-1)*iomodel->num_control_type+i];
+						for(j=0;j<3;j++)cmmaxinputs[j]=iomodel->cm_max[(tria_vertex_ids[j]-1)*iomodel->num_control_type+i];
+						this->inputs->AddInput(new ControlInput(DragCoefficientEnum,TriaVertexInputEnum,nodeinputs,cmmininputs,cmmaxinputs,i+1));
 					}
 					break;
Index: /issm/trunk/src/c/objects/Inputs/BoolInput.h
===================================================================
--- /issm/trunk/src/c/objects/Inputs/BoolInput.h	(revision 8128)
+++ /issm/trunk/src/c/objects/Inputs/BoolInput.h	(revision 8129)
@@ -41,4 +41,6 @@
 		Input* SpawnTriaInput(int* indices);
 		Input* PointwiseDivide(Input* inputB){_error_("not implemented yet");};
+		Input* PointwiseMin(Input* inputB){_error_("not implemented yet");};
+		Input* PointwiseMax(Input* inputB){_error_("not implemented yet");};
 		ElementResult* SpawnResult(int step, double time);
 		/*}}}*/
Index: /issm/trunk/src/c/objects/Inputs/ControlInput.cpp
===================================================================
--- /issm/trunk/src/c/objects/Inputs/ControlInput.cpp	(revision 8128)
+++ /issm/trunk/src/c/objects/Inputs/ControlInput.cpp	(revision 8129)
@@ -23,9 +23,11 @@
 	values      = NULL;
 	savedvalues = NULL;
+	minvalues   = NULL;
+	maxvalues   = 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){
+/*FUNCTION ControlInput::ControlInput(int enum_type,int enum_input,double* pvalues,double* pmin,double* pmax,int id){{{1*/
+ControlInput::ControlInput(int in_enum_type,int enum_input,double* pvalues,double* pmin,double* pmax,int id){
 
 	control_id=id;
@@ -36,8 +38,12 @@
 			values     =new TriaVertexInput(enum_type,pvalues);
 			savedvalues=new TriaVertexInput(enum_type,pvalues);
+			minvalues  =new TriaVertexInput(enum_type,pmin);
+			maxvalues  =new TriaVertexInput(enum_type,pmax);
 			break;
 		case PentaVertexInputEnum:
 			values     =new PentaVertexInput(enum_type,pvalues);
 			savedvalues=new PentaVertexInput(enum_type,pvalues);
+			minvalues  =new PentaVertexInput(enum_type,pmin);
+			maxvalues  =new PentaVertexInput(enum_type,pmax);
 			break;
 		default:
@@ -51,4 +57,6 @@
 	delete values;
 	delete savedvalues;
+	delete minvalues;
+	delete maxvalues;
 	delete gradient;
 }
@@ -66,7 +74,9 @@
 	printf("ControlInput:\n");
 	printf("   enum: %i (%s)\n",this->enum_type,EnumToString(this->enum_type));
-	printf("---values: \n");      if (values)      values->Echo();
-	printf("---savedvalues: \n"); if (savedvalues) savedvalues->Echo();
-	printf("---gradient: \n");    if (gradient)    gradient->Echo();
+	printf("---values: \n");     if (values)      values->Echo();
+	printf("---savedvalues: \n");if (savedvalues) savedvalues->Echo();
+	printf("---minvalues: \n");  if (minvalues)   minvalues->Echo();
+	printf("---maxvalues: \n");  if (maxvalues)   maxvalues->Echo();
+	printf("---gradient: \n");   if (gradient)    gradient->Echo();
 }
 /*}}}*/
@@ -122,4 +132,26 @@
 	}
 
+	/*marshal minvalues*/
+	if(!minvalues){
+		flag=0;
+		memcpy(marshalled_dataset,&flag,sizeof(flag));marshalled_dataset+=sizeof(flag);
+	}
+	else{
+		flag=1;
+		memcpy(marshalled_dataset,&flag,sizeof(flag));marshalled_dataset+=sizeof(flag);
+		this->minvalues->Marshall(&marshalled_dataset);
+	}
+
+	/*marshal maxvalues*/
+	if(!maxvalues){
+		flag=0;
+		memcpy(marshalled_dataset,&flag,sizeof(flag));marshalled_dataset+=sizeof(flag);
+	}
+	else{
+		flag=1;
+		memcpy(marshalled_dataset,&flag,sizeof(flag));marshalled_dataset+=sizeof(flag);
+		this->maxvalues->Marshall(&marshalled_dataset);
+	}
+
 	/*marshal gradient*/
 	if(!gradient){
@@ -144,9 +176,11 @@
 	size=sizeof(enum_type)+
 	  +sizeof(control_id)
-	  +3*sizeof(int) //3 flags
+	  +5*sizeof(int) //5 flags
 	  +sizeof(int); //sizeof(int) for enum value
 
 	if(values)     size+=values->MarshallSize();
 	if(savedvalues)size+=savedvalues->MarshallSize();
+	if(minvalues)size+=minvalues->MarshallSize();
+	if(maxvalues)size+=maxvalues->MarshallSize();
 	if(gradient)   size+=gradient->MarshallSize();
 	return size;
@@ -203,4 +237,40 @@
 	}
 
+	/*Demarshal minvalues*/
+	memcpy(&flag,marshalled_dataset,sizeof(int));marshalled_dataset+=sizeof(int);
+	if(flag){
+		memcpy(&input_enum_type,marshalled_dataset,sizeof(int)); marshalled_dataset+=sizeof(int);
+		if(input_enum_type==PentaVertexInputEnum){
+			minvalues=new PentaVertexInput();
+			minvalues->Demarshall(&marshalled_dataset);
+		}
+		else if(input_enum_type==TriaVertexInputEnum){
+			minvalues=new TriaVertexInput();
+			minvalues->Demarshall(&marshalled_dataset);
+		}
+		else _error_("Not supported yet");
+	}
+	else{
+		minvalues=NULL;
+	}
+
+	/*Demarshal maxvalues*/
+	memcpy(&flag,marshalled_dataset,sizeof(int));marshalled_dataset+=sizeof(int);
+	if(flag){
+		memcpy(&input_enum_type,marshalled_dataset,sizeof(int)); marshalled_dataset+=sizeof(int);
+		if(input_enum_type==PentaVertexInputEnum){
+			maxvalues=new PentaVertexInput();
+			maxvalues->Demarshall(&marshalled_dataset);
+		}
+		else if(input_enum_type==TriaVertexInputEnum){
+			maxvalues=new TriaVertexInput();
+			maxvalues->Demarshall(&marshalled_dataset);
+		}
+		else _error_("Not supported yet");
+	}
+	else{
+		maxvalues=NULL;
+	}
+
 	/*Demarshal gradient*/
 	memcpy(&flag,marshalled_dataset,sizeof(int));marshalled_dataset+=sizeof(int);
@@ -244,4 +314,6 @@
 	if(values)      output->values=(Input*)this->values->copy();
 	if(savedvalues) output->savedvalues=(Input*)this->savedvalues->copy();
+	if(minvalues)   output->minvalues=(Input*)this->minvalues->copy();
+	if(maxvalues)   output->maxvalues=(Input*)this->maxvalues->copy();
 	if(gradient)    output->gradient=(Input*)this->gradient->copy();
 
@@ -260,7 +332,17 @@
 
 /*Object functions*/
-/*FUNCTION ControlInput::Constrain{{{1*/
-void ControlInput::Constrain(double cm_min, double cm_max){
-	values->Constrain(cm_min,cm_max);
+/*FUNCTION ControlInput::Constrain(){{{1*/
+void ControlInput::Constrain(void){
+
+	Input* newvalues=NULL;
+
+	newvalues=this->values->PointwiseMin(maxvalues);
+	delete values; this->values=newvalues;
+	newvalues=this->values->PointwiseMax(minvalues);
+	delete values; this->values=newvalues;
+}/*}}}*/
+/*FUNCTION ControlInput::Constrain(double min, double max){{{1*/
+void ControlInput::Constrain(double min, double max){
+	   values->Constrain(min,max);
 }/*}}}*/
 /*FUNCTION ControlInput::Extrude{{{1*/
Index: /issm/trunk/src/c/objects/Inputs/ControlInput.h
===================================================================
--- /issm/trunk/src/c/objects/Inputs/ControlInput.h	(revision 8128)
+++ /issm/trunk/src/c/objects/Inputs/ControlInput.h	(revision 8129)
@@ -21,9 +21,11 @@
 		Input* values;
 		Input* savedvalues;
+		Input* minvalues;
+		Input* maxvalues;
 		Input* gradient;
 
 		/*ControlInput constructors, destructors: {{{1*/
 		ControlInput();
-		ControlInput(int enum_type,int enum_input,double* pvalues,int id);
+		ControlInput(int enum_type,int enum_input,double* pvalues,double* pmin,double* pmax,int id);
 		~ControlInput();
 		/*}}}*/
@@ -43,4 +45,6 @@
 		Input* SpawnTriaInput(int* indices);
 		Input* PointwiseDivide(Input* inputB){_error_("not implemented yet");};
+		Input* PointwiseMin(Input* inputB){_error_("not implemented yet");};
+		Input* PointwiseMax(Input* inputB){_error_("not implemented yet");};
 		ElementResult* SpawnResult(int step, double time);
 		/*}}}*/
@@ -67,5 +71,6 @@
 		void ArtificialNoise(double min,double max){_error_("not implemented yet");};
 		void AXPY(Input* xinput,double scalar){_error_("not implemented yet");};
-		void Constrain(double cm_min, double cm_max);
+		void Constrain(void);
+		void Constrain(double min,double max);
 		double InfinityNorm(void){_error_("not implemented yet");};
 		double Max(void){_error_("not implemented yet");};
Index: /issm/trunk/src/c/objects/Inputs/DoubleInput.cpp
===================================================================
--- /issm/trunk/src/c/objects/Inputs/DoubleInput.cpp	(revision 8128)
+++ /issm/trunk/src/c/objects/Inputs/DoubleInput.cpp	(revision 8129)
@@ -313,5 +313,4 @@
 
 	/*Intermediaries*/
-	double       AdotBvalue;
 	double       Bvalue;
 
@@ -327,2 +326,44 @@
 }
 /*}}}*/
+/*FUNCTION DoubleInput::PointwiseMin{{{1*/
+Input* DoubleInput::PointwiseMin(Input* input){
+
+	/*Ouput*/
+	DoubleInput* outinput=NULL;
+
+	/*Intermediaries*/
+	double       min;
+
+	/*Check that inputB is of the same type*/
+	if (input->Min() < this->Min()) min=input->Min();
+	else min=this->Min();
+
+	/*Create new DoubleInput*/
+	outinput=new DoubleInput(this->enum_type,min);
+
+	/*Return output pointer*/
+	return outinput;
+
+}
+/*}}}*/
+/*FUNCTION DoubleInput::PointwiseMax{{{1*/
+Input* DoubleInput::PointwiseMax(Input* input){
+
+	/*Ouput*/
+	DoubleInput* outinput=NULL;
+
+	/*Intermediaries*/
+	double       max;
+
+	/*Check that inputB is of the same type*/
+	if (input->Max() > this->Max()) max=input->Max();
+	else max=this->Max();
+
+	/*Create new DoubleInput*/
+	outinput=new DoubleInput(this->enum_type,max);
+
+	/*Return output pointer*/
+	return outinput;
+
+}
+/*}}}*/
Index: /issm/trunk/src/c/objects/Inputs/DoubleInput.h
===================================================================
--- /issm/trunk/src/c/objects/Inputs/DoubleInput.h	(revision 8128)
+++ /issm/trunk/src/c/objects/Inputs/DoubleInput.h	(revision 8129)
@@ -40,4 +40,6 @@
 		Input* SpawnTriaInput(int* indices);
 		Input* PointwiseDivide(Input* inputB);
+		Input* PointwiseMin(Input* inputB);
+		Input* PointwiseMax(Input* inputB);
 		ElementResult* SpawnResult(int step, double time);
 		/*}}}*/
Index: /issm/trunk/src/c/objects/Inputs/Input.h
===================================================================
--- /issm/trunk/src/c/objects/Inputs/Input.h	(revision 8128)
+++ /issm/trunk/src/c/objects/Inputs/Input.h	(revision 8129)
@@ -57,4 +57,6 @@
 		virtual Input* SpawnTriaInput(int* indices)=0;
 		virtual Input* PointwiseDivide(Input* inputB)=0;
+		virtual Input* PointwiseMax(Input* inputmax)=0;
+		virtual Input* PointwiseMin(Input* inputmin)=0;
 		virtual ElementResult* SpawnResult(int step, double time)=0;
 
Index: /issm/trunk/src/c/objects/Inputs/IntInput.h
===================================================================
--- /issm/trunk/src/c/objects/Inputs/IntInput.h	(revision 8128)
+++ /issm/trunk/src/c/objects/Inputs/IntInput.h	(revision 8129)
@@ -41,4 +41,6 @@
 		Input* SpawnTriaInput(int* indices);
 		Input* PointwiseDivide(Input* inputB){_error_("not implemented yet");};
+		Input* PointwiseMin(Input* inputB){_error_("not implemented yet");};
+		Input* PointwiseMax(Input* inputB){_error_("not implemented yet");};
 		ElementResult* SpawnResult(int step, double time);
 		/*}}}*/
Index: /issm/trunk/src/c/objects/Inputs/PentaVertexInput.cpp
===================================================================
--- /issm/trunk/src/c/objects/Inputs/PentaVertexInput.cpp	(revision 8128)
+++ /issm/trunk/src/c/objects/Inputs/PentaVertexInput.cpp	(revision 8129)
@@ -575,5 +575,4 @@
 	PentaVertexInput *xinputB     = NULL;
 	int               B_numvalues;
-	double           *B_values    = NULL;
 	const int         numgrids    = 6;
 	double            AdotBvalues[numgrids];
@@ -597,4 +596,66 @@
 }
 /*}}}*/
+/*FUNCTION PentaVertexInput::PointwiseMin{{{1*/
+Input* PentaVertexInput::PointwiseMin(Input* inputB){
+
+	/*Ouput*/
+	PentaVertexInput* outinput=NULL;
+
+	/*Intermediaries*/
+	int               i;
+	PentaVertexInput *xinputB     = NULL;
+	int               B_numvalues;
+	const int         numgrids    = 6;
+	double            minvalues[numgrids];
+
+	/*Check that inputB is of the same type*/
+	if (inputB->Enum()!=PentaVertexInputEnum) _error_("Operation not permitted because inputB is of type %s",EnumToString(inputB->Enum()));
+	xinputB=(PentaVertexInput*)inputB;
+
+	/*Create point wise min*/
+	for(i=0;i<numgrids;i++){
+		if(this->values[i] > xinputB->values[i]) minvalues[i]=xinputB->values[i];
+		else minvalues[i]=this->values[i];
+	}
+
+	/*Create new Penta vertex input (copy of current input)*/
+	outinput=new PentaVertexInput(this->enum_type,&minvalues[0]);
+
+	/*Return output pointer*/
+	return outinput;
+
+}
+/*}}}*/
+/*FUNCTION PentaVertexInput::PointwiseMax{{{1*/
+Input* PentaVertexInput::PointwiseMax(Input* inputB){
+
+	/*Ouput*/
+	PentaVertexInput* outinput=NULL;
+
+	/*Intermediaries*/
+	int               i;
+	PentaVertexInput *xinputB     = NULL;
+	int               B_numvalues;
+	const int         numgrids    = 6;
+	double            maxvalues[numgrids];
+
+	/*Check that inputB is of the same type*/
+	if (inputB->Enum()!=PentaVertexInputEnum) _error_("Operation not permitted because inputB is of type %s",EnumToString(inputB->Enum()));
+	xinputB=(PentaVertexInput*)inputB;
+
+	/*Create point wise max*/
+	for(i=0;i<numgrids;i++){
+		if(this->values[i] < xinputB->values[i]) maxvalues[i]=xinputB->values[i];
+		else maxvalues[i]=this->values[i];
+	}
+
+	/*Create new Penta vertex input (copy of current input)*/
+	outinput=new PentaVertexInput(this->enum_type,&maxvalues[0]);
+
+	/*Return output pointer*/
+	return outinput;
+
+}
+/*}}}*/
 /*FUNCTION PentaVertexInput::GetVectorFromInputs{{{1*/
 void PentaVertexInput::GetVectorFromInputs(Vec vector,int* doflist){
Index: /issm/trunk/src/c/objects/Inputs/PentaVertexInput.h
===================================================================
--- /issm/trunk/src/c/objects/Inputs/PentaVertexInput.h	(revision 8128)
+++ /issm/trunk/src/c/objects/Inputs/PentaVertexInput.h	(revision 8129)
@@ -41,4 +41,6 @@
 		Input* SpawnTriaInput(int* indices);
 		Input* PointwiseDivide(Input* inputB);
+		Input* PointwiseMin(Input* inputB);
+		Input* PointwiseMax(Input* inputB);
 		ElementResult* SpawnResult(int step, double time);
 		/*}}}*/
Index: /issm/trunk/src/c/objects/Inputs/TriaVertexInput.cpp
===================================================================
--- /issm/trunk/src/c/objects/Inputs/TriaVertexInput.cpp	(revision 8128)
+++ /issm/trunk/src/c/objects/Inputs/TriaVertexInput.cpp	(revision 8129)
@@ -403,2 +403,64 @@
 }
 /*}}}*/
+/*FUNCTION TriaVertexInput::PointwiseMin{{{1*/
+Input* TriaVertexInput::PointwiseMin(Input* inputB){
+
+	/*Ouput*/
+	TriaVertexInput* outinput=NULL;
+
+	/*Intermediaries*/
+	int               i;
+	TriaVertexInput *xinputB     = NULL;
+	int               B_numvalues;
+	const int         numgrids    = 3;
+	double            minvalues[numgrids];
+
+	/*Check that inputB is of the same type*/
+	if (inputB->Enum()!=TriaVertexInputEnum) _error_("Operation not permitted because inputB is of type %s",EnumToString(inputB->Enum()));
+	xinputB=(TriaVertexInput*)inputB;
+
+	/*Create point wise min*/
+	for(i=0;i<numgrids;i++){
+		if(this->values[i] > xinputB->values[i]) minvalues[i]=xinputB->values[i];
+		else minvalues[i]=this->values[i];
+	}
+
+	/*Create new Tria vertex input (copy of current input)*/
+	outinput=new TriaVertexInput(this->enum_type,&minvalues[0]);
+
+	/*Return output pointer*/
+	return outinput;
+
+}
+/*}}}*/
+/*FUNCTION TriaVertexInput::PointwiseMax{{{1*/
+Input* TriaVertexInput::PointwiseMax(Input* inputB){
+
+	/*Ouput*/
+	TriaVertexInput* outinput=NULL;
+
+	/*Intermediaries*/
+	int               i;
+	TriaVertexInput *xinputB     = NULL;
+	int               B_numvalues;
+	const int         numgrids    = 3;
+	double            maxvalues[numgrids];
+
+	/*Check that inputB is of the same type*/
+	if (inputB->Enum()!=TriaVertexInputEnum) _error_("Operation not permitted because inputB is of type %s",EnumToString(inputB->Enum()));
+	xinputB=(TriaVertexInput*)inputB;
+
+	/*Create point wise max*/
+	for(i=0;i<numgrids;i++){
+		if(this->values[i] < xinputB->values[i]) maxvalues[i]=xinputB->values[i];
+		else maxvalues[i]=this->values[i];
+	}
+
+	/*Create new Tria vertex input (copy of current input)*/
+	outinput=new TriaVertexInput(this->enum_type,&maxvalues[0]);
+
+	/*Return output pointer*/
+	return outinput;
+
+}
+/*}}}*/
Index: /issm/trunk/src/c/objects/Inputs/TriaVertexInput.h
===================================================================
--- /issm/trunk/src/c/objects/Inputs/TriaVertexInput.h	(revision 8128)
+++ /issm/trunk/src/c/objects/Inputs/TriaVertexInput.h	(revision 8129)
@@ -41,4 +41,6 @@
 		Input* SpawnTriaInput(int* indices);
 		Input* PointwiseDivide(Input* inputB){_error_("not implemented yet");};
+		Input* PointwiseMin(Input* inputB);
+		Input* PointwiseMax(Input* inputB);
 		ElementResult* SpawnResult(int step, double time);
 		/*}}}*/
Index: /issm/trunk/src/c/objects/Materials/Matice.cpp
===================================================================
--- /issm/trunk/src/c/objects/Materials/Matice.cpp	(revision 8128)
+++ /issm/trunk/src/c/objects/Materials/Matice.cpp	(revision 8129)
@@ -608,4 +608,6 @@
 		const int num_vertices = 3; //Tria has 3 vertices
 		double    nodeinputs[num_vertices];
+		double    cmmininputs[num_vertices];
+		double    cmmaxinputs[num_vertices];
 
 		/*Get B*/
@@ -627,6 +629,9 @@
 					case RheologyBbarEnum:
 						if (iomodel->rheology_B){
+							_assert_(iomodel->rheology_B);_assert_(iomodel->cm_min); _assert_(iomodel->cm_max); 
 							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,i+1));
+							for(j=0;j<num_vertices;j++)cmmininputs[j]=iomodel->cm_min[int(iomodel->elements[num_vertices*index+j]-1)*iomodel->num_control_type+i];
+							for(j=0;j<num_vertices;j++)cmmaxinputs[j]=iomodel->cm_max[int(iomodel->elements[num_vertices*index+j]-1)*iomodel->num_control_type+i];
+							this->inputs->AddInput(new ControlInput(RheologyBbarEnum,TriaVertexInputEnum,nodeinputs,cmmininputs,cmmaxinputs,i+1));
 						}
 						break;
@@ -642,4 +647,6 @@
 		const int num_vertices = 6; //Penta has 6 vertices
 		double    nodeinputs[num_vertices];
+		double    cmmininputs[num_vertices];
+		double    cmmaxinputs[num_vertices];
 
 		/*Get B*/
@@ -661,6 +668,9 @@
 					case RheologyBbarEnum:
 						if (iomodel->rheology_B){
+							_assert_(iomodel->rheology_B);_assert_(iomodel->cm_min); _assert_(iomodel->cm_max); 
 							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,i+1));
+							for(j=0;j<num_vertices;j++)cmmininputs[j]=iomodel->cm_min[int(iomodel->elements[num_vertices*index+j]-1)*iomodel->num_control_type+i];
+							for(j=0;j<num_vertices;j++)cmmaxinputs[j]=iomodel->cm_max[int(iomodel->elements[num_vertices*index+j]-1)*iomodel->num_control_type+i];
+							this->inputs->AddInput(new ControlInput(RheologyBEnum,PentaVertexInputEnum,nodeinputs,cmmininputs,cmmaxinputs,i+1));
 						}
 						break;
