Index: /issm/trunk/src/c/objects/Loads/Numericalflux.cpp
===================================================================
--- /issm/trunk/src/c/objects/Loads/Numericalflux.cpp	(revision 6025)
+++ /issm/trunk/src/c/objects/Loads/Numericalflux.cpp	(revision 6026)
@@ -330,25 +330,19 @@
 void  Numericalflux::CreateKMatrix(Mat Kgg,Mat Kff, Mat Kfs){
 
-	int type;
+	/*recover some parameters*/
+	ElementMatrix* Ke=NULL;
 	int analysis_type;
-	ElementMatrix* Ke=NULL;
-
-	/*recover some parameters*/
-	inputs->GetParameterValue(&type,TypeEnum);
 	this->parameters->FindParam(&analysis_type,AnalysisTypeEnum);
 
 	/*Just branch to the correct element stiffness matrix generator, according to the type of analysis we are carrying out: */
 	switch(analysis_type){
-		case PrognosticAnalysisEnum: case BalancedthicknessAnalysisEnum: case AdjointBalancedthicknessAnalysisEnum:
-			switch(type){
-				case InternalEnum:
-					Ke=CreateKMatrixInternal();
-					break;
-				case BoundaryEnum:
-					Ke=CreateKMatrixBoundary();
-					break;
-				default:
-					ISSMERROR("type not supported yet");
-			}
+		case PrognosticAnalysisEnum:
+			Ke=CreateKMatrixPrognostic();
+			break;
+		case BalancedthicknessAnalysisEnum:
+			Ke=CreateKMatrixBalancedthickness();
+			break;
+		case AdjointBalancedthicknessAnalysisEnum:
+			Ke=CreateKMatrixAdjointBalancedthickness();
 			break;
 		default:
@@ -367,24 +361,18 @@
 void  Numericalflux::CreatePVector(Vec pg,Vec pf){
 
-	int type;
+	/*recover some parameters*/
+	ElementVector* pe=NULL;
 	int analysis_type;
-	ElementVector* pe=NULL;
-
-	/*recover some parameters*/
-	inputs->GetParameterValue(&type,TypeEnum);
 	this->parameters->FindParam(&analysis_type,AnalysisTypeEnum);
 
 	switch(analysis_type){
-		case PrognosticAnalysisEnum: case BalancedthicknessAnalysisEnum: case AdjointBalancedthicknessAnalysisEnum:
-			switch(type){
-				case InternalEnum:
-					pe=CreatePVectorInternal();
-					break;
-				case BoundaryEnum:
-					pe=CreatePVectorBoundary();
-					break;
-				default:
-					ISSMERROR("type not supported yet");
-			}
+		case PrognosticAnalysisEnum:
+			pe=CreatePVectorPrognostic();
+			break;
+		case BalancedthicknessAnalysisEnum:
+			pe=CreatePVectorBalancedthickness();
+			break;
+		case AdjointBalancedthicknessAnalysisEnum:
+			pe=CreatePVectorAdjointBalancedthickness();
 			break;
 		default:
@@ -424,6 +412,22 @@
 
 /*Numericalflux management*/
-/*FUNCTION Numericalflux::CreateKMatrixInternal {{{1*/
-ElementMatrix* Numericalflux::CreateKMatrixInternal(void){
+/*FUNCTION Numericalflux::CreateKMatrixPrognostic{{{1*/
+ElementMatrix* Numericalflux::CreateKMatrixPrognostic(void){
+
+	int type;
+	inputs->GetParameterValue(&type,TypeEnum);
+
+	switch(type){
+		case InternalEnum:
+			return CreateKMatrixPrognosticInternal();
+		case BoundaryEnum:
+			return CreateKMatrixPrognosticBoundary();
+		default:
+			ISSMERROR("type not supported yet");
+	}
+}
+/*}}}*/
+/*FUNCTION Numericalflux::CreateKMatrixPrognosticInternal {{{1*/
+ElementMatrix* Numericalflux::CreateKMatrixPrognosticInternal(void){
 
 	/* constants*/
@@ -431,5 +435,5 @@
 
 	/* Intermediaries*/
-	int        i,j,ig,index1,index2,analysis_type;
+	int        i,j,ig,index1,index2;
 	double     DL1,DL2,Jdet,dt,vx,vy,UdotN;
 	double     xyz_list[NUMVERTICES_INTERNAL][3];
@@ -448,16 +452,8 @@
 	/*Retrieve all inputs and parameters*/
 	GetVerticesCoordinates(&xyz_list[0][0], nodes,NUMVERTICES_INTERNAL);
+	parameters->FindParam(&dt,DtEnum);
 	Input* vxaverage_input=tria->inputs->GetInput(VxEnum);
 	Input* vyaverage_input=tria->inputs->GetInput(VyEnum);
-	this->parameters->FindParam(&analysis_type,AnalysisTypeEnum);
 	GetNormal(&normal[0],xyz_list);
-	switch(analysis_type){
-		case PrognosticAnalysisEnum:
-			parameters->FindParam(&dt,DtEnum); break;
-		case BalancedthicknessAnalysisEnum: case AdjointBalancedthicknessAnalysisEnum:
-			dt=1; break;/*No transient term is involved*/
-		default:
-			ISSMERROR("analysis_type %s not supported yet",EnumToString(analysis_type));
-	}
 
 	/* Start  looping on the number of gaussian points: */
@@ -497,6 +493,6 @@
 }
 /*}}}*/
-/*FUNCTION Numericalflux::CreateKMatrixBoundary {{{1*/
-ElementMatrix* Numericalflux::CreateKMatrixBoundary(void){
+/*FUNCTION Numericalflux::CreateKMatrixPrognosticBoundary {{{1*/
+ElementMatrix* Numericalflux::CreateKMatrixPrognosticBoundary(void){
 
 	/* constants*/
@@ -504,5 +500,5 @@
 
 	/* Intermediaries*/
-	int        i,j,ig,index1,index2,analysis_type;
+	int        i,j,ig,index1,index2;
 	double     DL,Jdet,dt,vx,vy,mean_vx,mean_vy,UdotN;
 	double     xyz_list[NUMVERTICES_BOUNDARY][3];
@@ -519,16 +515,8 @@
 	/*Retrieve all inputs and parameters*/
 	GetVerticesCoordinates(&xyz_list[0][0],nodes,NUMVERTICES_BOUNDARY);
+	parameters->FindParam(&dt,DtEnum);
 	Input* vxaverage_input=tria->inputs->GetInput(VxEnum);
 	Input* vyaverage_input=tria->inputs->GetInput(VyEnum);
-	this->parameters->FindParam(&analysis_type,AnalysisTypeEnum);
 	GetNormal(&normal[0],xyz_list);
-	switch(analysis_type){
-		case PrognosticAnalysisEnum:
-			parameters->FindParam(&dt,DtEnum); break;
-		case BalancedthicknessAnalysisEnum: case AdjointBalancedthicknessAnalysisEnum:
-			dt=1; break;/*No transient term is involved*/
-		default:
-			ISSMERROR("analysis_type %s not supported yet",EnumToString(analysis_type));
-	}
 
 	/*Check wether it is an inflow or outflow BC (0 is the middle of the segment)*/
@@ -575,6 +563,199 @@
 }
 /*}}}*/
-/*FUNCTION Numericalflux::CreatePVectorInternal{{{1*/
-ElementVector* Numericalflux::CreatePVectorInternal(void){
+/*FUNCTION Numericalflux::CreateKMatrixBalancedthickness{{{1*/
+ElementMatrix* Numericalflux::CreateKMatrixBalancedthickness(void){
+
+	int type;
+	inputs->GetParameterValue(&type,TypeEnum);
+
+	switch(type){
+		case InternalEnum:
+			return CreateKMatrixBalancedthicknessInternal();
+		case BoundaryEnum:
+			return CreateKMatrixBalancedthicknessBoundary();
+		default:
+			ISSMERROR("type not supported yet");
+	}
+}
+/*}}}*/
+/*FUNCTION Numericalflux::CreateKMatrixBalancedthicknessInternal {{{1*/
+ElementMatrix* Numericalflux::CreateKMatrixBalancedthicknessInternal(void){
+
+	/* constants*/
+	const int numdof=NDOF1*NUMVERTICES_INTERNAL;
+
+	/* Intermediaries*/
+	int        i,j,ig,index1,index2;
+	double     DL1,DL2,Jdet,vx,vy,UdotN;
+	double     xyz_list[NUMVERTICES_INTERNAL][3];
+	double     normal[2];
+	double     B[numdof];
+	double     Bprime[numdof];
+	double     Ke_g1[numdof][numdof];
+	double     Ke_g2[numdof][numdof];
+	GaussTria *gauss;
+
+	/*Initialize Element matrix and return if necessary*/
+	Tria*  tria=(Tria*)element;
+	if(tria->IsOnWater()) return NULL;
+	ElementMatrix* Ke=new ElementMatrix(nodes,NUMVERTICES_INTERNAL,this->parameters);
+
+	/*Retrieve all inputs and parameters*/
+	GetVerticesCoordinates(&xyz_list[0][0], nodes,NUMVERTICES_INTERNAL);
+	Input* vxaverage_input=tria->inputs->GetInput(VxEnum);
+	Input* vyaverage_input=tria->inputs->GetInput(VyEnum);
+	GetNormal(&normal[0],xyz_list);
+
+	/* Start  looping on the number of gaussian points: */
+	index1=tria->GetNodeIndex(nodes[0]);
+	index2=tria->GetNodeIndex(nodes[1]);
+	gauss=new GaussTria(index1,index2,2);
+	for(ig=gauss->begin();ig<gauss->end();ig++){
+
+		gauss->GaussPoint(ig);
+
+		tria->GetSegmentBFlux(&B[0],gauss,index1,index2);
+		tria->GetSegmentBprimeFlux(&Bprime[0],gauss,index1,index2);
+
+		vxaverage_input->GetParameterValue(&vx,gauss);
+		vyaverage_input->GetParameterValue(&vy,gauss);
+		UdotN=vx*normal[0]+vy*normal[1];
+		tria->GetSegmentJacobianDeterminant(&Jdet,&xyz_list[0][0],gauss);
+		DL1=gauss->weight*Jdet*UdotN/2;
+		DL2=gauss->weight*Jdet*fabs(UdotN)/2;
+
+		TripleMultiply(&B[0],1,numdof,1,
+					&DL1,1,1,0,
+					&Bprime[0],1,numdof,0,
+					&Ke_g1[0][0],0);
+		TripleMultiply(&B[0],1,numdof,1,
+					&DL2,1,1,0,
+					&B[0],1,numdof,0,
+					&Ke_g2[0][0],0);
+
+		for(i=0;i<numdof;i++) for(j=0;j<numdof;j++) Ke->values[i*numdof+j]+=Ke_g1[i][j];
+		for(i=0;i<numdof;i++) for(j=0;j<numdof;j++) Ke->values[i*numdof+j]+=Ke_g2[i][j];
+	}
+
+	/*Clean up and return*/
+	delete gauss;
+	return Ke;
+}
+/*}}}*/
+/*FUNCTION Numericalflux::CreateKMatrixBalancedthicknessBoundary {{{1*/
+ElementMatrix* Numericalflux::CreateKMatrixBalancedthicknessBoundary(void){
+
+	/* constants*/
+	const int numdof=NDOF1*NUMVERTICES_BOUNDARY;
+
+	/* Intermediaries*/
+	int        i,j,ig,index1,index2;
+	double     DL,Jdet,vx,vy,mean_vx,mean_vy,UdotN;
+	double     xyz_list[NUMVERTICES_BOUNDARY][3];
+	double     normal[2];
+	double     L[numdof];
+	double     Ke_g[numdof][numdof];
+	GaussTria *gauss;
+
+	/*Initialize Element matrix and return if necessary*/
+	Tria*  tria=(Tria*)element;
+	if(tria->IsOnWater()) return NULL;
+	ElementMatrix* Ke=new ElementMatrix(nodes,NUMVERTICES_BOUNDARY,this->parameters);
+
+	/*Retrieve all inputs and parameters*/
+	GetVerticesCoordinates(&xyz_list[0][0],nodes,NUMVERTICES_BOUNDARY);
+	Input* vxaverage_input=tria->inputs->GetInput(VxEnum);
+	Input* vyaverage_input=tria->inputs->GetInput(VyEnum);
+	GetNormal(&normal[0],xyz_list);
+
+	/*Check wether it is an inflow or outflow BC (0 is the middle of the segment)*/
+	index1=tria->GetNodeIndex(nodes[0]);
+	index2=tria->GetNodeIndex(nodes[1]);
+
+	gauss=new GaussTria();
+	gauss->GaussEdgeCenter(index1,index2);
+	vxaverage_input->GetParameterValue(&mean_vx,gauss);
+	vyaverage_input->GetParameterValue(&mean_vy,gauss);
+	delete gauss;
+
+	UdotN=mean_vx*normal[0]+mean_vy*normal[1];
+	if (UdotN<=0){
+		/*(u,n)<0 -> inflow, PenaltyCreatePVector will take care of it*/
+		return NULL;
+	}
+
+	/* Start  looping on the number of gaussian points: */
+	gauss=new GaussTria(index1,index2,2);
+	for(ig=gauss->begin();ig<gauss->end();ig++){
+
+		gauss->GaussPoint(ig);
+
+		tria->GetSegmentNodalFunctions(&L[0],gauss,index1,index2);
+
+		vxaverage_input->GetParameterValue(&vx,gauss);
+		vyaverage_input->GetParameterValue(&vy,gauss);
+		UdotN=vx*normal[0]+vy*normal[1];
+		tria->GetSegmentJacobianDeterminant(&Jdet,&xyz_list[0][0],gauss);
+		DL=gauss->weight*Jdet*UdotN;
+
+		TripleMultiply(&L[0],1,numdof,1,
+					&DL,1,1,0,
+					&L[0],1,numdof,0,
+					&Ke_g[0][0],0);
+
+		for(i=0;i<numdof;i++) for(j=0;j<numdof;j++) Ke->values[i*numdof+j]+=Ke_g[i][j];
+	} 
+
+	/*Clean up and return*/
+	delete gauss;
+	return Ke;
+}
+/*}}}*/
+/*FUNCTION Numericalflux::CreateKMatrixAdjointBalancedthickness{{{1*/
+ElementMatrix* Numericalflux::CreateKMatrixAdjointBalancedthickness(void){
+
+	int type;
+	inputs->GetParameterValue(&type,TypeEnum);
+
+	switch(type){
+		case InternalEnum:
+			return CreateKMatrixAdjointBalancedthicknessInternal();
+		case BoundaryEnum:
+			return CreateKMatrixAdjointBalancedthicknessBoundary();
+		default:
+			ISSMERROR("type not supported yet");
+	}
+}
+/*}}}*/
+/*FUNCTION Numericalflux::CreateKMatrixAdjointBalancedthicknessInternal {{{1*/
+ElementMatrix* Numericalflux::CreateKMatrixAdjointBalancedthicknessInternal(void){
+
+	return CreateKMatrixBalancedthicknessInternal();
+}
+/*}}}*/
+/*FUNCTION Numericalflux::CreateKMatrixAdjointBalancedthicknessBoundary {{{1*/
+ElementMatrix* Numericalflux::CreateKMatrixAdjointBalancedthicknessBoundary(void){
+
+	return CreateKMatrixBalancedthicknessBoundary();
+}
+/*}}}*/
+/*FUNCTION Numericalflux::CreatePVectorPrognostic{{{1*/
+ElementVector* Numericalflux::CreatePVectorPrognostic(void){
+
+	int type;
+	inputs->GetParameterValue(&type,TypeEnum);
+
+	switch(type){
+		case InternalEnum:
+			return CreatePVectorPrognosticInternal();
+		case BoundaryEnum:
+			return CreatePVectorPrognosticBoundary();
+		default:
+			ISSMERROR("type not supported yet");
+	}
+}
+/*}}}*/
+/*FUNCTION Numericalflux::CreatePVectorPrognosticInternal{{{1*/
+ElementVector* Numericalflux::CreatePVectorPrognosticInternal(void){
 
 	/*Nothing added to PVector*/
@@ -583,6 +764,6 @@
 }
 /*}}}*/
-/*FUNCTION Numericalflux::CreatePVectorBoundary{{{1*/
-ElementVector* Numericalflux::CreatePVectorBoundary(void){
+/*FUNCTION Numericalflux::CreatePVectorPrognosticBoundary{{{1*/
+ElementVector* Numericalflux::CreatePVectorPrognosticBoundary(void){
 
 	/* constants*/
@@ -590,5 +771,5 @@
 
 	/* Intermediaries*/
-	int        i,j,ig,index1,index2,analysis_type;
+	int        i,j,ig,index1,index2;
 	double     DL,Jdet,dt,vx,vy,mean_vx,mean_vy,UdotN,thickness;
 	double     xyz_list[NUMVERTICES_BOUNDARY][3];
@@ -597,5 +778,5 @@
 	GaussTria *gauss;
 
-	/*Initialize Load Vectorand return if necessary*/
+	/*Initialize Load Vector and return if necessary*/
 	Tria*  tria=(Tria*)element;
 	if(tria->IsOnWater()) return NULL;
@@ -604,23 +785,9 @@
 	/*Retrieve all inputs and parameters*/
 	GetVerticesCoordinates(&xyz_list[0][0],nodes,NUMVERTICES_BOUNDARY);
+	parameters->FindParam(&dt,DtEnum);
 	Input* vxaverage_input=tria->inputs->GetInput(VxEnum); ISSMASSERT(vxaverage_input); 
 	Input* vyaverage_input=tria->inputs->GetInput(VyEnum); ISSMASSERT(vyaverage_input);
-	Input* thickness_input=tria->inputs->GetInput(ThicknessObsEnum);
-
-	/*Here, as it is a forcing, we have H=Hobs by default (for control methods)*/
-	if (!thickness_input){
-		thickness_input=tria->inputs->GetInput(ThicknessEnum); ISSMASSERT(thickness_input);
-	}
-
-	this->parameters->FindParam(&analysis_type,AnalysisTypeEnum);
+	Input* thickness_input=tria->inputs->GetInput(ThicknessEnum); ISSMASSERT(thickness_input);
 	GetNormal(&normal[0],xyz_list);
-	switch(analysis_type){
-		case PrognosticAnalysisEnum:
-			parameters->FindParam(&dt,DtEnum); break;
-		case BalancedthicknessAnalysisEnum: case AdjointBalancedthicknessAnalysisEnum:
-			dt=1; break;/*No transient term is involved*/
-		default:
-			ISSMERROR("analysis_type %s not supported yet",EnumToString(analysis_type));
-	}
 
 	/*Check wether it is an inflow or outflow BC (0 is the middle of the segment)*/
@@ -662,4 +829,185 @@
 }
 /*}}}*/
+/*FUNCTION Numericalflux::CreatePVectorBalancedthickness{{{1*/
+ElementVector* Numericalflux::CreatePVectorBalancedthickness(void){
+
+	int type;
+	inputs->GetParameterValue(&type,TypeEnum);
+
+	switch(type){
+		case InternalEnum:
+			return CreatePVectorBalancedthicknessInternal();
+		case BoundaryEnum:
+			return CreatePVectorBalancedthicknessBoundary();
+		default:
+			ISSMERROR("type not supported yet");
+	}
+}
+/*}}}*/
+/*FUNCTION Numericalflux::CreatePVectorBalancedthicknessInternal{{{1*/
+ElementVector* Numericalflux::CreatePVectorBalancedthicknessInternal(void){
+
+	/*Nothing added to PVector*/
+	return NULL;
+
+}
+/*}}}*/
+/*FUNCTION Numericalflux::CreatePVectorBalancedthicknessBoundary{{{1*/
+ElementVector* Numericalflux::CreatePVectorBalancedthicknessBoundary(void){
+
+	/* constants*/
+	const int numdof=NDOF1*NUMVERTICES_BOUNDARY;
+
+	/* Intermediaries*/
+	int        i,j,ig,index1,index2;
+	double     DL,Jdet,vx,vy,mean_vx,mean_vy,UdotN,thickness;
+	double     xyz_list[NUMVERTICES_BOUNDARY][3];
+	double     normal[2];
+	double     L[numdof];
+	GaussTria *gauss;
+
+	/*Initialize Load Vector and return if necessary*/
+	Tria*  tria=(Tria*)element;
+	if(tria->IsOnWater()) return NULL;
+	ElementVector* pe=new ElementVector(nodes,NUMVERTICES_BOUNDARY,this->parameters);
+
+	/*Retrieve all inputs and parameters*/
+	GetVerticesCoordinates(&xyz_list[0][0],nodes,NUMVERTICES_BOUNDARY);
+	Input* vxaverage_input=tria->inputs->GetInput(VxEnum); ISSMASSERT(vxaverage_input); 
+	Input* vyaverage_input=tria->inputs->GetInput(VyEnum); ISSMASSERT(vyaverage_input);
+	Input* thickness_input=tria->inputs->GetInput(ThicknessObsEnum);
+
+	/*Here, as it is a forcing, we have H=Hobs by default (for control methods)*/
+	if (!thickness_input){
+		thickness_input=tria->inputs->GetInput(ThicknessEnum); ISSMASSERT(thickness_input);
+	}
+	GetNormal(&normal[0],xyz_list);
+
+	/*Check wether it is an inflow or outflow BC (0 is the middle of the segment)*/
+	index1=tria->GetNodeIndex(nodes[0]);
+	index2=tria->GetNodeIndex(nodes[1]);
+
+	gauss=new GaussTria();
+	gauss->GaussEdgeCenter(index1,index2);
+	vxaverage_input->GetParameterValue(&mean_vx,gauss);
+	vyaverage_input->GetParameterValue(&mean_vy,gauss);
+	delete gauss;
+	UdotN=mean_vx*normal[0]+mean_vy*normal[1];
+	if (UdotN>0){
+		/*(u,n)>0 -> outflow, PenaltyCreateKMatrix will take care of it*/
+		return NULL;
+	}
+
+	/* Start  looping on the number of gaussian points: */
+	gauss=new GaussTria(index1,index2,2);
+	for(ig=gauss->begin();ig<gauss->end();ig++){
+
+		gauss->GaussPoint(ig);
+
+		tria->GetSegmentNodalFunctions(&L[0],gauss,index1,index2);
+
+		vxaverage_input->GetParameterValue(&vx,gauss);
+		vyaverage_input->GetParameterValue(&vy,gauss);
+		thickness_input->GetParameterValue(&thickness,gauss);
+		UdotN=vx*normal[0]+vy*normal[1];
+		tria->GetSegmentJacobianDeterminant(&Jdet,&xyz_list[0][0],gauss);
+		DL= - gauss->weight*Jdet*UdotN*thickness;
+
+		for(i=0;i<numdof;i++) pe->values[i] += DL*L[i];
+	}
+
+	/*Clean up and return*/
+	delete gauss;
+	return pe;
+}
+/*}}}*/
+/*FUNCTION Numericalflux::CreatePVectorAdjointBalancedthickness{{{1*/
+ElementVector* Numericalflux::CreatePVectorAdjointBalancedthickness(void){
+
+	int type;
+	inputs->GetParameterValue(&type,TypeEnum);
+
+	switch(type){
+		case InternalEnum:
+			return CreatePVectorAdjointBalancedthicknessInternal();
+		case BoundaryEnum:
+			return CreatePVectorAdjointBalancedthicknessBoundary();
+		default:
+			ISSMERROR("type not supported yet");
+	}
+}
+/*}}}*/
+/*FUNCTION Numericalflux::CreatePVectorAdjointBalancedthicknessInternal{{{1*/
+ElementVector* Numericalflux::CreatePVectorAdjointBalancedthicknessInternal(void){
+
+	/*Nothing added to PVector*/
+	return NULL;
+
+}
+/*}}}*/
+/*FUNCTION Numericalflux::CreatePVectorAdjointBalancedthicknessBoundary{{{1*/
+ElementVector* Numericalflux::CreatePVectorAdjointBalancedthicknessBoundary(void){
+
+	/* constants*/
+	const int numdof=NDOF1*NUMVERTICES_BOUNDARY;
+
+	/* Intermediaries*/
+	int        i,j,ig,index1,index2;
+	double     DL,Jdet,vx,vy,mean_vx,mean_vy,UdotN,thickness;
+	double     xyz_list[NUMVERTICES_BOUNDARY][3];
+	double     normal[2];
+	double     L[numdof];
+	GaussTria *gauss;
+
+	/*Initialize Load Vector and return if necessary*/
+	Tria*  tria=(Tria*)element;
+	if(tria->IsOnWater()) return NULL;
+	ElementVector* pe=new ElementVector(nodes,NUMVERTICES_BOUNDARY,this->parameters);
+
+	/*Retrieve all inputs and parameters*/
+	GetVerticesCoordinates(&xyz_list[0][0],nodes,NUMVERTICES_BOUNDARY);
+	Input* vxaverage_input=tria->inputs->GetInput(VxEnum);           ISSMASSERT(vxaverage_input); 
+	Input* vyaverage_input=tria->inputs->GetInput(VyEnum);           ISSMASSERT(vyaverage_input);
+	Input* thickness_input=tria->inputs->GetInput(ThicknessObsEnum); ISSMASSERT(thickness_input);
+	GetNormal(&normal[0],xyz_list);
+
+	/*Check wether it is an inflow or outflow BC (0 is the middle of the segment)*/
+	index1=tria->GetNodeIndex(nodes[0]);
+	index2=tria->GetNodeIndex(nodes[1]);
+
+	gauss=new GaussTria();
+	gauss->GaussEdgeCenter(index1,index2);
+	vxaverage_input->GetParameterValue(&mean_vx,gauss);
+	vyaverage_input->GetParameterValue(&mean_vy,gauss);
+	delete gauss;
+	UdotN=mean_vx*normal[0]+mean_vy*normal[1];
+	if (UdotN>0){
+		/*(u,n)>0 -> outflow, PenaltyCreateKMatrix will take care of it*/
+		return NULL;
+	}
+
+	/* Start  looping on the number of gaussian points: */
+	gauss=new GaussTria(index1,index2,2);
+	for(ig=gauss->begin();ig<gauss->end();ig++){
+
+		gauss->GaussPoint(ig);
+
+		tria->GetSegmentNodalFunctions(&L[0],gauss,index1,index2);
+
+		vxaverage_input->GetParameterValue(&vx,gauss);
+		vyaverage_input->GetParameterValue(&vy,gauss);
+		thickness_input->GetParameterValue(&thickness,gauss);
+		UdotN=vx*normal[0]+vy*normal[1];
+		tria->GetSegmentJacobianDeterminant(&Jdet,&xyz_list[0][0],gauss);
+		DL= - gauss->weight*Jdet*UdotN*thickness;
+
+		for(i=0;i<numdof;i++) pe->values[i] += DL*L[i];
+	}
+
+	/*Clean up and return*/
+	delete gauss;
+	return pe;
+}
+/*}}}*/
 /*FUNCTION Numericalflux::GetNormal {{{1*/
 void Numericalflux:: GetNormal(double* normal,double xyz_list[4][3]){
Index: /issm/trunk/src/c/objects/Loads/Numericalflux.h
===================================================================
--- /issm/trunk/src/c/objects/Loads/Numericalflux.h	(revision 6025)
+++ /issm/trunk/src/c/objects/Loads/Numericalflux.h	(revision 6026)
@@ -74,8 +74,22 @@
 		/*Numericalflux management:{{{1*/
 		void  GetNormal(double* normal,double xyz_list[4][3]);
-		ElementMatrix* CreateKMatrixInternal(void);
-		ElementMatrix* CreateKMatrixBoundary(void);
-		ElementVector* CreatePVectorInternal(void);
-		ElementVector* CreatePVectorBoundary(void);
+		ElementMatrix* CreateKMatrixPrognostic(void);
+		ElementMatrix* CreateKMatrixPrognosticInternal(void);
+		ElementMatrix* CreateKMatrixPrognosticBoundary(void);
+		ElementMatrix* CreateKMatrixBalancedthickness(void);
+		ElementMatrix* CreateKMatrixBalancedthicknessInternal(void);
+		ElementMatrix* CreateKMatrixBalancedthicknessBoundary(void);
+		ElementMatrix* CreateKMatrixAdjointBalancedthickness(void);
+		ElementMatrix* CreateKMatrixAdjointBalancedthicknessInternal(void);
+		ElementMatrix* CreateKMatrixAdjointBalancedthicknessBoundary(void);
+		ElementVector* CreatePVectorPrognostic(void);
+		ElementVector* CreatePVectorPrognosticInternal(void);
+		ElementVector* CreatePVectorPrognosticBoundary(void);
+		ElementVector* CreatePVectorBalancedthickness(void);
+		ElementVector* CreatePVectorBalancedthicknessInternal(void);
+		ElementVector* CreatePVectorBalancedthicknessBoundary(void);
+		ElementVector* CreatePVectorAdjointBalancedthickness(void);
+		ElementVector* CreatePVectorAdjointBalancedthicknessInternal(void);
+		ElementVector* CreatePVectorAdjointBalancedthicknessBoundary(void);
 		/*}}}*/
 
