Index: /issm/trunk/src/c/modules/ModelProcessorx/DiagnosticHoriz/CreateConstraintsDiagnosticHoriz.cpp
===================================================================
--- /issm/trunk/src/c/modules/ModelProcessorx/DiagnosticHoriz/CreateConstraintsDiagnosticHoriz.cpp	(revision 4886)
+++ /issm/trunk/src/c/modules/ModelProcessorx/DiagnosticHoriz/CreateConstraintsDiagnosticHoriz.cpp	(revision 4887)
@@ -65,23 +65,23 @@
 	count=0;
 
-	if(iomodel->numpenalties){
-
-		for (i=0;i<iomodel->numpenalties;i++){
-
-			for(j=1;j<iomodel->numlayers;j++){
-	
-				/*We are pairing nodes along a vertical profile.*/
-				node1=(int)*(iomodel->penalties+iomodel->numlayers*i)+iomodel->nodecounter;
-				node2=(int)*(iomodel->penalties+iomodel->numlayers*i+j)+iomodel->nodecounter;
-
-				constraints->AddObject(new Rgb(iomodel->constraintcounter+count+1,node1,node2,1,DiagnosticHorizAnalysisEnum));  //add count'th Rgb on dof 1 between node1 and node2
-				
-				count++;
-				
-				constraints->AddObject(new Rgb(iomodel->constraintcounter+count+1,node1,node2,2,DiagnosticHorizAnalysisEnum));  //add count'th Rgb on dof 1 between node1 and node2
-
-			}
-		}
-	}
+//	if(iomodel->numpenalties){
+//
+//		for (i=0;i<iomodel->numpenalties;i++){
+//
+//			for(j=1;j<iomodel->numlayers;j++){
+//	
+//				/*We are pairing nodes along a vertical profile.*/
+//				node1=(int)*(iomodel->penalties+iomodel->numlayers*i)+iomodel->nodecounter;
+//				node2=(int)*(iomodel->penalties+iomodel->numlayers*i+j)+iomodel->nodecounter;
+//
+//				constraints->AddObject(new Rgb(iomodel->constraintcounter+count+1,node1,node2,1,DiagnosticHorizAnalysisEnum));  //add count'th Rgb on dof 1 between node1 and node2
+//				
+//				count++;
+//				
+//				constraints->AddObject(new Rgb(iomodel->constraintcounter+count+1,node1,node2,2,DiagnosticHorizAnalysisEnum));  //add count'th Rgb on dof 1 between node1 and node2
+//
+//			}
+//		}
+//	}
 
 	/*Free data: */
Index: /issm/trunk/src/c/modules/ModelProcessorx/DiagnosticHoriz/CreateLoadsDiagnosticHoriz.cpp
===================================================================
--- /issm/trunk/src/c/modules/ModelProcessorx/DiagnosticHoriz/CreateLoadsDiagnosticHoriz.cpp	(revision 4886)
+++ /issm/trunk/src/c/modules/ModelProcessorx/DiagnosticHoriz/CreateLoadsDiagnosticHoriz.cpp	(revision 4887)
@@ -23,4 +23,5 @@
 	int i;
 	int count=0;
+	int penpair_ids[2];
 
 	/*Recover pointer: */
@@ -69,4 +70,23 @@
 	xfree((void**)&iomodel->bed);
 
+	/*Create Penpair for penalties: */
+	IoModelFetchData(&iomodel->penalties,&iomodel->numpenalties,NULL,iomodel_handle,"penalties");
+	
+	if(iomodel->numpenalties){
+		for(i=0;i<iomodel->numpenalties;i++){
+				
+			//if((iomodel->my_vertices[iomodel->penalties[2*i+0]]==1)){
+				penpair_ids[0]=(int)iomodel->penalties[2*i+0];
+				penpair_ids[1]=(int)iomodel->penalties[2*i+1];
+
+				loads->AddObject(new Penpair(iomodel->loadcounter+count+1,&penpair_ids[0],DiagnosticHorizAnalysisEnum));
+				count++;
+			//}
+		}
+	}
+
+	/*free ressources: */
+	xfree((void**)&iomodel->penalties);
+
 	/*Create Riffront loads for rifts: */
 	IoModelFetchData(&iomodel->riftinfo,&iomodel->numrifts,NULL,iomodel_handle,"riftinfo");
Index: /issm/trunk/src/c/objects/Loads/Penpair.cpp
===================================================================
--- /issm/trunk/src/c/objects/Loads/Penpair.cpp	(revision 4886)
+++ /issm/trunk/src/c/objects/Loads/Penpair.cpp	(revision 4887)
@@ -22,4 +22,5 @@
 
 	this->hnodes=NULL;
+	this->parameters=NULL;
 	return;
 }
@@ -27,20 +28,9 @@
 /*FUNCTION Penpair::creation {{{1*/
 Penpair::Penpair(int penpair_id, int* penpair_node_ids,int in_analysis_type){
-
 	
 	this->id=penpair_id;
 	this->analysis_type=in_analysis_type;
 	this->hnodes=new Hook(penpair_node_ids,2);
-	
-	return;
-}
-/*}}}1*/
-/*FUNCTION Penpair::creation {{{1*/
-Penpair::Penpair(int penpair_id, Hook* penpair_hnodes,int in_analysis_type){
-
-	/*all the initialization has been done by the initializer, just fill in the id: */
-	this->id=penpair_id;
-	this->analysis_type=in_analysis_type;
-	this->hnodes=penpair_hnodes;
+	this->parameters=NULL;
 	
 	return;
@@ -140,4 +130,7 @@
 	hnodes=new Hook(); hnodes->Demarshall(&marshalled_dataset);
 
+	/*parameters: may not exist even yet, so let Configure handle it: */
+	this->parameters=NULL;
+
 	/*return: */
 	*pmarshalled_dataset=marshalled_dataset;
@@ -164,4 +157,7 @@
 	/*now deal with hooks and objects: */
 	penpair->hnodes=(Hook*)this->hnodes->copy();
+
+	/*point parameters: */
+	penpair->parameters=this->parameters;
 
 	return penpair;
@@ -177,4 +173,6 @@
 	 * datasets, using internal ids and offsets hidden in hooks: */
 	hnodes->configure(nodesin);
+	/*point parameters to real dataset: */
+	this->parameters=parametersin;
 
 }
@@ -187,9 +185,11 @@
 	hnodes->configure(nodesin);
 
+	/*point parameters to real dataset: */
+	this->parameters=parametersin;
 }
 /*}}}1*/
 /*FUNCTION Penpair::CreateKMatrix {{{1*/
 void  Penpair::CreateKMatrix(Mat Kgg){
-
+	/*If you code this piece, don't forget that a penalty will be inactive if it is dealing with clone nodes*/
 	/*No loads applied, do nothing: */
 	return;
@@ -207,8 +207,15 @@
 /*FUNCTION Penpair::PenaltyCreateKMatrix {{{1*/
 void  Penpair::PenaltyCreateKMatrix(Mat Kgg,double kmax){
-	
-	/*If you code this piece, don't forget that a penalty will be inactive if it is dealing with clone nodes*/
-	/*No loads applied, do nothing: */
-	return;
+	int analysis_type;
+
+	/*Retrieve parameters: */
+	this->parameters->FindParam(&analysis_type,AnalysisTypeEnum);
+
+	if (analysis_type==DiagnosticHorizAnalysisEnum){
+		PenaltyCreateKMatrixDiagnosticHoriz(Kgg,kmax);
+	}
+	else{
+		ISSMERROR("analysis %i (%s) not supported yet",analysis_type,EnumAsString(analysis_type));
+	}
 }
 /*}}}1*/
@@ -225,2 +232,91 @@
 }
 /*}}}*/
+
+/*Update virtual functions definitions:*/
+/*FUNCTION Penpair::InputUpdateFromConstant(double constant, int name) {{{1*/
+void  Penpair::InputUpdateFromConstant(double constant, int name){
+	/*Nothing updated yet*/
+}
+/*}}}*/
+/*FUNCTION Penpair::InputUpdateFromConstant(int constant, int name) {{{1*/
+void  Penpair::InputUpdateFromConstant(int constant, int name){
+	/*Nothing updated yet*/
+}
+/*}}}*/
+/*FUNCTION Penpair::InputUpdateFromConstant(bool constant, int name) {{{1*/
+void  Penpair::InputUpdateFromConstant(bool constant, int name){
+	/*Nothing updated yet*/
+}
+/*}}}*/
+
+/*Penpair management:*/
+/*FUNCTION Penpair::PenaltyCreateKMatrixDiagnosticHoriz {{{1*/
+void  Penpair::PenaltyCreateKMatrixDiagnosticHoriz(Mat Kgg,double kmax){
+	
+	const int numgrids=2;
+	const int NDOF2=2;
+	const int numdof=numgrids*NDOF2;
+	int       doflist[numdof];
+	int       numberofdofspernode;
+
+	double Ke[4][4]={0.0};
+	double penalty_offset;
+
+	/*pointers: */
+	Node** nodes=NULL;
+
+	/*Get dof list: */
+	GetDofList(&doflist[0],&numberofdofspernode);
+
+	/*recover pointers: */
+	nodes=(Node**)hnodes->deliverp();
+
+	/*recover parameters: */
+	parameters->FindParam(&penalty_offset,PenaltyOffsetEnum);
+
+	//Create elementary matrix: add penalty to 
+	Ke[0][0]=kmax*pow((double)10.0,penalty_offset);
+	Ke[0][2]=-kmax*pow((double)10.0,penalty_offset);
+	Ke[2][0]=-kmax*pow((double)10.0,penalty_offset);
+	Ke[2][2]=kmax*pow((double)10.0,penalty_offset);
+
+	Ke[1][1]=kmax*pow((double)10.0,penalty_offset);
+	Ke[1][3]=-kmax*pow((double)10.0,penalty_offset);
+	Ke[3][1]=-kmax*pow((double)10.0,penalty_offset);
+	Ke[3][3]=kmax*pow((double)10.0,penalty_offset);
+	
+	/*Add Ke to global matrix Kgg: */
+	MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)Ke,ADD_VALUES);
+}
+/*}}}1*/
+/*FUNCTION Penpair::GetDofList {{{1*/
+void  Penpair::GetDofList(int* doflist,int* pnumberofdofspernode){
+
+	int i,j;
+	int doflist_per_node[MAXDOFSPERNODE];
+	int numberofdofspernode;
+
+	/*pointers: */
+	Node** nodes=NULL;
+
+	/*recover pointers: */
+	nodes=(Node**)hnodes->deliverp();
+
+	/*Some checks for debugging*/
+	ISSMASSERT(doflist);
+	ISSMASSERT(pnumberofdofspernode);
+	ISSMASSERT(nodes);
+
+	/*Build doflist from nodes*/
+	for(i=0;i<2;i++){
+		nodes[i]->GetDofList(&doflist_per_node[0],&numberofdofspernode);
+		for(j=0;j<numberofdofspernode;j++){
+			doflist[i*numberofdofspernode+j]=doflist_per_node[j];
+		}
+	}
+
+	/*Assign output pointers:*/
+	*pnumberofdofspernode=numberofdofspernode;
+
+}
+/*}}}*/
Index: /issm/trunk/src/c/objects/Loads/Penpair.h
===================================================================
--- /issm/trunk/src/c/objects/Loads/Penpair.h	(revision 4886)
+++ /issm/trunk/src/c/objects/Loads/Penpair.h	(revision 4887)
@@ -22,4 +22,6 @@
 		Hook* hnodes;  //hook to 2 nodes
 
+		Parameters* parameters; //pointer to solution parameters
+
 	public:
 
@@ -27,5 +29,4 @@
 		Penpair();
 		Penpair(int penpair_id,int* penpair_node_ids,int analysis_type);
-		Penpair(int penpair_id,Hook* penpair_hnodes,int analysis_type);
 		~Penpair();
 		/*}}}*/
@@ -45,7 +46,7 @@
 		void  InputUpdateFromVector(int* vector, int name, int type){ISSMERROR("Not implemented yet!");}
 		void  InputUpdateFromVector(bool* vector, int name, int type){ISSMERROR("Not implemented yet!");}
-		void  InputUpdateFromConstant(double constant, int name){ISSMERROR("Not implemented yet!");}
-		void  InputUpdateFromConstant(int constant, int name){ISSMERROR("Not implemented yet!");}
-		void  InputUpdateFromConstant(bool constant, int name){ISSMERROR("Not implemented yet!");}
+		void  InputUpdateFromConstant(double constant, int name);
+		void  InputUpdateFromConstant(int constant, int name);
+		void  InputUpdateFromConstant(bool constant, int name);
 		void  InputUpdateFromSolution(double* solution){ISSMERROR("Not implemented yet!");}
 		/*}}}*/
@@ -59,4 +60,8 @@
 		bool  InAnalysis(int analysis_type);
 		/*}}}*/
+			/*Penpair management: {{{1*/
+		void  PenaltyCreateKMatrixDiagnosticHoriz(Mat Kgg,double kmax);
+		void  GetDofList(int* doflist,int* pnumberofdofspernode);
+		/*}}}*/
 };
 
