Index: sm/trunk/src/c/objects/BamgGeom.cpp
===================================================================
--- /issm/trunk/src/c/objects/BamgGeom.cpp	(revision 3680)
+++ 	(revision )
@@ -1,18 +1,0 @@
-#include "stdio.h"
-#include "./BamgGeom.h"
-
-void BamgGeomInit(BamgGeom* bamggeom){
-
-	bamggeom->VerticesSize[0]=0,  bamggeom->VerticesSize[1]=0;  bamggeom->Vertices=NULL;
-	bamggeom->EdgesSize[0]=0,     bamggeom->EdgesSize[1]=0;     bamggeom->Edges=NULL;
-	bamggeom->hVertices=NULL;
-	bamggeom->MetricVertices=NULL;
-	bamggeom->h1h2VpVertices=NULL;
-	bamggeom->TangentAtEdgesSize[0]=0,    bamggeom->TangentAtEdgesSize[1]=0;    bamggeom->TangentAtEdges=NULL;
-	bamggeom->CornersSize[0]=0,           bamggeom->CornersSize[1]=0;           bamggeom->Corners=NULL;
-	bamggeom->RequiredVerticesSize[0]=0,  bamggeom->RequiredVerticesSize[1]=0;  bamggeom->RequiredVertices=NULL;
-	bamggeom->RequiredEdgesSize[0]=0,     bamggeom->RequiredEdgesSize[1]=0;     bamggeom->RequiredEdges=NULL;
-	bamggeom->CrackedEdgesSize[0]=0,      bamggeom->CrackedEdgesSize[1]=0;      bamggeom->CrackedEdges=NULL;
-	bamggeom->SubDomainsSize[0]=0,        bamggeom->SubDomainsSize[1]=0;        bamggeom->SubDomains=NULL;
-
-}
Index: sm/trunk/src/c/objects/BamgGeom.h
===================================================================
--- /issm/trunk/src/c/objects/BamgGeom.h	(revision 3680)
+++ 	(revision )
@@ -1,40 +1,0 @@
-/*!\file:  BamgGeom.h
- */ 
-
-#ifndef _BAMGGEOM_H_
-#define _BAMGGEOM_H_
-
-struct BamgGeom{
-
-	int     VerticesSize[2];
-	double* Vertices;
-
-	int     EdgesSize[2];
-	double* Edges;
-
-	double* hVertices;
-	double* MetricVertices;
-	double* h1h2VpVertices;
-
-	int     TangentAtEdgesSize[2];
-	double* TangentAtEdges;
-
-	int     CornersSize[2];
-	double* Corners;
-
-	int     RequiredVerticesSize[2];
-	double* RequiredVertices;
-
-	int     RequiredEdgesSize[2];
-	double* RequiredEdges;
-
-	int     CrackedEdgesSize[2];
-	double* CrackedEdges;
-
-	int     SubDomainsSize[2];
-	double* SubDomains;
-};
-
-void BamgGeomInit(BamgGeom* bamggeom);
-
-#endif
Index: sm/trunk/src/c/objects/BamgMesh.cpp
===================================================================
--- /issm/trunk/src/c/objects/BamgMesh.cpp	(revision 3680)
+++ 	(revision )
@@ -1,24 +1,0 @@
-#include "stdio.h"
-#include "./BamgMesh.h"
-
-void BamgMeshInit(BamgMesh* bamgmesh){
-
-	bamgmesh->TrianglesSize[0]=0,     bamgmesh->TrianglesSize[1]=0;      bamgmesh->Triangles=NULL;
-	bamgmesh->VerticesSize[0]=0,      bamgmesh->VerticesSize[1]=0;       bamgmesh->Vertices=NULL;
-	bamgmesh->EdgesSize[0]=0,         bamgmesh->EdgesSize[1]=0;          bamgmesh->Edges=NULL;
-	bamgmesh->ElementEdgesSize[0]=0,  bamgmesh->ElementEdgesSize[1]=0;   bamgmesh->ElementEdges=NULL;
-	bamgmesh->SegmentsSize[0]=0,      bamgmesh->SegmentsSize[1]=0;       bamgmesh->Segments=NULL;
-	bamgmesh->QuadrilateralsSize[0]=0,bamgmesh->QuadrilateralsSize[1]=0; bamgmesh->Quadrilaterals=NULL;
-	bamgmesh->VerticesOnGeometricVertexSize[0]=0, bamgmesh->VerticesOnGeometricVertexSize[1]=0;bamgmesh->VerticesOnGeometricVertex=NULL;
-	bamgmesh->VerticesOnGeometricEdgeSize[0]=0,   bamgmesh->VerticesOnGeometricEdgeSize[1]=0;  bamgmesh->VerticesOnGeometricEdge=NULL;
-	bamgmesh->EdgesOnGeometricEdgeSize[0]=0,      bamgmesh->EdgesOnGeometricEdgeSize[1]=0;     bamgmesh->EdgesOnGeometricEdge=NULL;
-	bamgmesh->SubDomainsSize[0]=0,         bamgmesh->SubDomainsSize[1]=0;          bamgmesh->SubDomains=NULL;
-	bamgmesh->SubDomainsFromGeomSize[0]=0, bamgmesh->SubDomainsFromGeomSize[1]=0;  bamgmesh->SubDomainsFromGeom=NULL;
-	bamgmesh->hVertices=NULL;
-	bamgmesh->ElementConnectivitySize[0]=0,      bamgmesh->ElementConnectivitySize[1]=0;      bamgmesh->ElementConnectivity=NULL;
-	bamgmesh->NodalConnectivitySize[0]=0,        bamgmesh->NodalConnectivitySize[1]=0;        bamgmesh->NodalConnectivity=NULL;
-	bamgmesh->NodalElementConnectivitySize[0]=0, bamgmesh->NodalElementConnectivitySize[1]=0; bamgmesh->NodalElementConnectivity=NULL;
-	bamgmesh->CrackedVerticesSize[0]=0, bamgmesh->CrackedVerticesSize[1]=0; bamgmesh->CrackedVertices=NULL;
-	bamgmesh->CrackedEdgesSize[0]=0, bamgmesh->CrackedEdgesSize[1]=0; bamgmesh->CrackedEdges=NULL;
-
-}
Index: sm/trunk/src/c/objects/BamgMesh.h
===================================================================
--- /issm/trunk/src/c/objects/BamgMesh.h	(revision 3680)
+++ 	(revision )
@@ -1,62 +1,0 @@
-/*!\file:  BamgMesh.h
- */ 
-
-#ifndef _BAMGMESH_H_
-#define _BAMGMESH_H_
-
-struct BamgMesh{
-
-	int     TrianglesSize[2];
-	double* Triangles;
-
-	int     VerticesSize[2];
-	double* Vertices;
-
-	int     EdgesSize[2];
-	double* Edges;
-
-	int     ElementEdgesSize[2];
-	double* ElementEdges;
-
-	int     SegmentsSize[2];
-	double* Segments;
-
-	int     QuadrilateralsSize[2];
-	double* Quadrilaterals;
-
-	int     VerticesOnGeometricVertexSize[2];
-	double* VerticesOnGeometricVertex;
-
-	int     VerticesOnGeometricEdgeSize[2];
-	double* VerticesOnGeometricEdge;
-
-	int     EdgesOnGeometricEdgeSize[2];
-	double* EdgesOnGeometricEdge;
-
-	int     SubDomainsSize[2];
-	double* SubDomains;
-
-	int     SubDomainsFromGeomSize[2];
-	double* SubDomainsFromGeom;
-
-	double* hVertices;
-
-	int     ElementConnectivitySize[2];
-	double* ElementConnectivity;
-
-	int     NodalConnectivitySize[2];
-	double* NodalConnectivity;
-
-	int     NodalElementConnectivitySize[2];
-	double* NodalElementConnectivity;
-
-	int     CrackedVerticesSize[2];
-	double* CrackedVertices;
-
-	int     CrackedEdgesSize[2];
-	double* CrackedEdges;
-};
-
-void BamgMeshInit(BamgMesh* bamgmesh);
-
-#endif
Index: sm/trunk/src/c/objects/BamgOpts.cpp
===================================================================
--- /issm/trunk/src/c/objects/BamgOpts.cpp	(revision 3680)
+++ 	(revision )
@@ -1,60 +1,0 @@
-#include "stdio.h"
-#include "../shared/shared.h"
-#include "../include/macros.h"
-#include "./BamgOpts.h"
-
-void BamgOptsInit(BamgOpts* bamgopts){
-
-	bamgopts->iso=0;
-	bamgopts->maxnbv=0;
-	bamgopts->MaximalAngleOfCorner=0;
-	bamgopts->Hessiantype=0;
-	bamgopts->Metrictype=0;
-	bamgopts->KeepVertices=0;
-	bamgopts->Crack=0;
-	bamgopts->maxsubdiv=0;
-	bamgopts->power=0;
-	bamgopts->anisomax=0;
-	bamgopts->NbSmooth=0;
-	bamgopts->nbjacobi=0;
-	bamgopts->omega=0;
-	bamgopts->hmin=0;
-	bamgopts->hmax=0;
-	bamgopts->hminVertices=NULL;
-	bamgopts->hmaxVertices=NULL;
-	bamgopts->gradation=0;
-	bamgopts->cutoff=0;
-	bamgopts->splitcorners=0;
-	bamgopts->geometricalmetric=0;
-	bamgopts->verbose=0;
-	bamgopts->err=NULL;
-	bamgopts->errg=0;
-	bamgopts->coef=0;
-	bamgopts->metric=NULL;
-	bamgopts->field=NULL;
-	bamgopts->numfields=0;
-
-}
-
-void BamgOptsCheck(BamgOpts* bamgopts){
-
-	int i;
-
-	if (bamgopts->coef==0) ISSMERROR("'coef' should be positive");
-	if (bamgopts->maxsubdiv<=1) ISSMERROR("'maxsubdiv' should be >1");
-	if (bamgopts->Crack!=0  && bamgopts->Crack!=1) ISSMERROR("'Crack' supported options are 0 and 1");
-	if (bamgopts->Hessiantype!=0  && bamgopts->Hessiantype!=1) ISSMERROR("'Hessiantype' supported options are 0 and 1");
-	if (bamgopts->Metrictype!=0   && bamgopts->Metrictype!=1 && bamgopts->Metrictype!=2) ISSMERROR("'Metrictype' supported options are 0, 1 and 2");
-	if (bamgopts->KeepVertices!=0 && bamgopts->KeepVertices!=1) ISSMERROR("'KeepVertices' supported options are 0 and 1");
-	if (bamgopts->errg<0) ISSMERROR("'errg' option should be >0");
-	if (bamgopts->nbjacobi<=0) ISSMERROR("'nbjacobi' option should be >0");
-	if (bamgopts->geometricalmetric!=0  && bamgopts->geometricalmetric!=1) ISSMERROR("'geometricalmetric' supported options are 0 and 1");
-	if (bamgopts->NbSmooth<=0) ISSMERROR("'NbSmooth' option should be >0");
-	if (bamgopts->maxnbv<3) ISSMERROR("'maxnbv' option should be >3");
-	if (bamgopts->hmin<=0) ISSMERROR("'hmin' option should be >0");
-	if (bamgopts->hmax<=0 || bamgopts->hmax<bamgopts->hmin) ISSMERROR("'hmax' option should be between 0 and hmin=%g",bamgopts->hmin);
-	if (bamgopts->anisomax<1) ISSMERROR("'anisomax' option should be >=1");
-	if (bamgopts->gradation<1) ISSMERROR("'gradation' option should be >=1");
-	for (i=0;i<bamgopts->numfields;i++) {if (bamgopts->err[i]<=0) ISSMERROR("'err' option should be >0");};
-
-}
Index: sm/trunk/src/c/objects/BamgOpts.h
===================================================================
--- /issm/trunk/src/c/objects/BamgOpts.h	(revision 3680)
+++ 	(revision )
@@ -1,45 +1,0 @@
-/*!\file:  BamgOpts.h
- * \brief place holder for optimization function arguments
- */ 
-
-#ifndef _BAMGOPTS_H_
-#define _BAMGOPTS_H_
-
-struct BamgOpts{
-
-	int     iso;
-	int     maxnbv;
-	double  MaximalAngleOfCorner;
-	int     Crack;
-	int     Hessiantype;
-	int     Metrictype;
-	int     KeepVertices;
-	double  maxsubdiv;
-	double  power;
-	double  anisomax;
-	int     NbSmooth;
-	int     nbjacobi;
-	double  omega;
-	double  hmin;
-	double  hmax;
-	double* hminVertices;
-	double* hmaxVertices;
-	double  gradation;
-	double  cutoff;
-	int     splitcorners;
-	int     geometricalmetric;
-	int     verbose;
-	double* err;
-	double  errg;
-	double  coef;
-	double* metric;
-	double* field;
-	int     numfields;
-
-};
-
-void BamgOptsInit(BamgOpts* bamgopts);
-
-void BamgOptsCheck(BamgOpts* bamgopts);
-
-#endif
Index: sm/trunk/src/c/objects/Beam.cpp
===================================================================
--- /issm/trunk/src/c/objects/Beam.cpp	(revision 3680)
+++ 	(revision )
@@ -1,716 +1,0 @@
-/*!\file Beam.c
- * \brief: implementation of the Beam object
- */
-
-#ifdef HAVE_CONFIG_H
-	#include "config.h"
-#else
-#error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
-#endif
-
-#include "stdio.h"
-#include "./Beam.h"
-#include "./BeamVertexInput.h"
-#include <string.h>
-#include "../EnumDefinitions/EnumDefinitions.h"
-#include "../shared/shared.h"
-#include "../DataSet/DataSet.h"
-#include "../include/typedefs.h"
-#include "../include/macros.h"
-
-/*Object constructors and destructor*/
-/*FUNCTION Beam::Beam(){{{1*/
-Beam::Beam(){
-	this->inputs=NULL;
-	this->parameters=NULL;
-	return;
-}
-/*}}}*/
-/*FUNCTION Beam::Beam(int id, int* node_ids, int matice_id, int matpar_id){{{1*/
-Beam::Beam(int beam_id,int* beam_node_ids, int beam_matice_id, int beam_matpar_id):
-	hnodes(beam_node_ids,2),
-	hmatice(&beam_matice_id,1),
-	hmatpar(&beam_matpar_id,1)
-{
-
-	/*all the initialization has been done by the initializer, just fill in the id: */
-	this->id=beam_id;
-	this->parameters=NULL;
-	this->inputs=new Inputs();
-}
-/*}}}*/
-/*FUNCTION Beam::Beam(int id, Hook* hnodes, Hook* hmatice, Hook* hmatpar, Parameters* beam_parameters, ElementProperties* properties){{{1*/
-Beam::Beam(int beam_id,Hook* beam_hnodes, Hook* beam_hmatice, Hook* beam_hmatpar, Parameters* beam_parameters, Inputs* beam_inputs):
-	hnodes(beam_hnodes),
-	hmatice(beam_hmatice),
-	hmatpar(beam_hmatpar)
-{
-
-	/*all the initialization has been done by the initializer, just fill in the id: */
-	this->id=beam_id;
-	if(beam_inputs){
-		this->inputs=(Inputs*)beam_inputs->Copy();
-	}
-	else{
-		this->inputs=new Inputs();
-	}
-	/*point parameters: */
-	this->parameters=beam_parameters;
-}
-/*}}}*/
-/*FUNCTION Beam::Beam(int id, int i, IoModel* iomodel){{{1*/
-Beam::Beam(int beam_id, int index,IoModel* iomodel){
-
-	int i;
-
-	/*beam constructor input: */
-	int   beam_matice_id;
-	int   beam_matpar_id;
-	int   beam_node_ids[2];
-	double nodeinputs[2];
-
-	/*id: */
-	this->id=beam_id;
-
-	/*hooks: */
-	beam_matice_id=index+1; //refers to the corresponding material property card
-	beam_matpar_id=iomodel->numberofvertices2d*(iomodel->numlayers-1)+1;//refers to the corresponding matpar property card
-	beam_node_ids[0]=index+1;
-	beam_node_ids[1]=(int)iomodel->uppernodes[index]; //grid that lays right on top
-	
-	this->hnodes.Init(beam_node_ids,2);
-	this->hmatice.Init(&beam_matice_id,1);
-	this->hmatpar.Init(&beam_matpar_id,1);
-
-	//intialize inputs, and add as many inputs per element as requested: 
-	this->inputs=new Inputs();
-
-	if (iomodel->thickness) {
-		nodeinputs[0]=iomodel->thickness[index];
-		nodeinputs[1]=iomodel->thickness[(int)(iomodel->uppernodes[index]-1)];
-		this->inputs->AddInput(new BeamVertexInput(ThicknessEnum,nodeinputs));
-	}
-	if (iomodel->surface) {
-		nodeinputs[0]=iomodel->surface[index];
-		nodeinputs[1]=iomodel->surface[(int)(iomodel->uppernodes[index]-1)];
-		this->inputs->AddInput(new BeamVertexInput(SurfaceEnum,nodeinputs));
-	}	
-	if (iomodel->bed) {
-		nodeinputs[0]=iomodel->bed[index];
-		nodeinputs[1]=iomodel->bed[(int)(iomodel->uppernodes[index]-1)];
-		this->inputs->AddInput(new BeamVertexInput(BedEnum,nodeinputs));
-	}	
-	if (iomodel->drag_coefficient) {
-		nodeinputs[0]=iomodel->drag_coefficient[index];
-		nodeinputs[1]=iomodel->drag_coefficient[(int)(iomodel->uppernodes[index]-1)];
-		this->inputs->AddInput(new BeamVertexInput(DragCoefficientEnum,nodeinputs));
-	}	
-	if (iomodel->gridonbed) this->inputs->AddInput(new BoolInput(ElementOnBedEnum,(IssmBool)iomodel->gridonbed[index]));
-
-	//this->parameters: we still can't point to it, it may not even exist. Configure will handle this.
-	this->parameters=NULL;
-
-
-}
-/*}}}*/
-/*FUNCTION Beam::~Beam(){{{1*/
-Beam::~Beam(){
-	delete inputs;
-	this->parameters=NULL;
-}
-/*}}}*/
-
-/*Object management*/
-/*FUNCTION Beam::Configure{{{1*/
-void  Beam::Configure(DataSet* loadsin, DataSet* nodesin, DataSet* materialsin, Parameters* parametersin){
-
-	int i;
-	
-	/*Take care of hooking up all objects for this element, ie links the objects in the hooks to their respective 
-	 * datasets, using internal ids and offsets hidden in hooks: */
-	hnodes.configure(nodesin);
-	hmatice.configure(materialsin);
-	hmatpar.configure(materialsin);
-
-	/*point parameters to real dataset: */
-	this->parameters=parametersin;
-
-}
-/*}}}*/
-/*FUNCTION Beam::copy{{{1*/
-Object* Beam::copy() {
-	
-	return new Beam(this->id,&this->hnodes,&this->hmatice,&this->hmatpar,this->parameters,this->inputs);
-
-}
-/*}}}*/
-/*FUNCTION Beam::DeepEcho{{{1*/
-void Beam::DeepEcho(void){
-
-	printf("Beam:\n");
-	printf("   id: %i\n",id);
-	hnodes.DeepEcho();
-	hmatice.DeepEcho();
-	hmatpar.DeepEcho();
-	printf("   parameters\n");
-	parameters->DeepEcho();
-	printf("   inputs\n");
-	inputs->DeepEcho();
-
-	return;
-}
-/*}}}*/
-/*FUNCTION Beam::Demarshall{{{1*/
-void  Beam::Demarshall(char** pmarshalled_dataset){
-
-	char* marshalled_dataset=NULL;
-	int   i;
-
-	/*recover marshalled_dataset: */
-	marshalled_dataset=*pmarshalled_dataset;
-
-	/*this time, no need to get enum type, the pointer directly points to the beginning of the 
-	 *object data (thanks to DataSet::Demarshall):*/
-	memcpy(&id,marshalled_dataset,sizeof(id));marshalled_dataset+=sizeof(id);
-
-	/*demarshall hooks: */
-	hnodes.Demarshall(&marshalled_dataset);
-	hmatice.Demarshall(&marshalled_dataset);
-	hmatpar.Demarshall(&marshalled_dataset);
-
-	/*demarshall inputs: */
-	inputs=(Inputs*)DataSetDemarshallRaw(&marshalled_dataset); 
-
-	/*parameters: may not exist even yet, so let Configure handle it: */
-	this->parameters=NULL;
-
-	/*return: */
-	*pmarshalled_dataset=marshalled_dataset;
-	return;
-}
-/*}}}*/
-/*FUNCTION Beam::Echo {{{1*/
-void Beam::Echo(void){
-
-	printf("Beam:\n");
-	printf("   id: %i\n",id);
-	hnodes.Echo();
-	hmatice.Echo();
-	hmatpar.Echo();
-	printf("   parameters\n");
-	parameters->Echo();
-	printf("   inputs\n");
-	inputs->Echo();
-
-	return;
-}
-/*}}}*/
-/*FUNCTION Beam::Marshall{{{1*/
-void  Beam::Marshall(char** pmarshalled_dataset){
-
-	char* marshalled_dataset=NULL;
-	int   enum_type=0;
-	char* marshalled_inputs=NULL;
-	int   marshalled_inputs_size;
-
-	/*recover marshalled_dataset: */
-	marshalled_dataset=*pmarshalled_dataset;
-
-	/*get enum type of Beam: */
-	enum_type=BeamEnum;
-	
-	/*marshall enum: */
-	memcpy(marshalled_dataset,&enum_type,sizeof(enum_type));marshalled_dataset+=sizeof(enum_type);
-	
-	/*marshall Beam data: */
-	memcpy(marshalled_dataset,&id,sizeof(id));marshalled_dataset+=sizeof(id);
-
-	/*Marshall hooks: */
-	hnodes.Marshall(&marshalled_dataset);
-	hmatice.Marshall(&marshalled_dataset);
-	hmatpar.Marshall(&marshalled_dataset);
-
-	/*Marshall inputs: */
-	marshalled_inputs_size=inputs->MarshallSize();
-	marshalled_inputs=inputs->Marshall();
-	memcpy(marshalled_dataset,marshalled_inputs,marshalled_inputs_size*sizeof(char));
-	marshalled_dataset+=marshalled_inputs_size;
-	
-	/*parameters: don't do anything about it. parameters are marshalled somewhere else!*/
-
-	xfree((void**)&marshalled_inputs);
-
-	*pmarshalled_dataset=marshalled_dataset;
-	return;
-}
-/*}}}*/
-/*FUNCTION Beam::MarshallSize{{{1*/
-int   Beam::MarshallSize(){
-	
-	return sizeof(id)
-		+hnodes.MarshallSize()
-		+hmatice.MarshallSize()
-		+hmatpar.MarshallSize()
-		+inputs->MarshallSize()
-		+sizeof(int); //sizeof(int) for enum type
-}
-/*}}}*/
-/*FUNCTION Beam::UpdateInputs {{{1*/
-void  Beam::UpdateInputs(double* solution, int analysis_type, int sub_analysis_type){
-	ISSMERROR(" not supported yet!");
-}
-/*}}}*/
-
-/*Object functions*/
-/*FUNCTION Beam::ComputeBasalStress{{{1*/
-void  Beam::ComputeBasalStress(Vec eps,int analysis_type,int sub_analysis_type){
-
-	ISSMERROR("Not implemented yet");
-
-}
-/*}}}*/
-/*FUNCTION Beam::ComputePressure{{{1*/
-void  Beam::ComputePressure(Vec p_g,int analysis_type,int sub_analysis_type){
-
-	int i;
-	const int numgrids=2;
-	int doflist[numgrids];
-	double pressure[numgrids];
-	double surface[numgrids];
-	double rho_ice,g;
-	double xyz_list[numgrids][3];
-	double gauss[numgrids][numgrids]={{1,0},{0,1}};
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-	Matpar* matpar=NULL;
-	Matice* matice=NULL;
-	
-	/*Get dof list on which we will plug the pressure values: */
-	GetDofList1(&doflist[0]);
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	matpar=(Matpar*)hmatpar.delivers();
-	matice=(Matice*)hmatice.delivers();
-
-	/*Get node data: */
-	GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
-        
-	/*Get dof list on which we will plug the pressure values: */
-	GetDofList1(&doflist[0]);
-
-	/*pressure is lithostatic: */
-	rho_ice=matpar->GetRhoIce();
-	g=matpar->GetG();
-
-	/*recover value of surface at gauss points (0,1) and (1,0): */
-	inputs->GetParameterValues(&surface[0],&gauss[0][0],2,SurfaceEnum);
-	for(i=0;i<numgrids;i++){
-		pressure[i]=rho_ice*g*(surface[i]-xyz_list[i][2]);
-	}
-
-	/*plug local pressure values into global pressure vector: */
-	VecSetValues(p_g,numgrids,doflist,(const double*)pressure,INSERT_VALUES);
-
-}
-/*}}}*/
-/*FUNCTION Beam::ComputeStrainRate{{{1*/
-void  Beam::ComputeStrainRate(Vec eps,int analysis_type,int sub_analysis_type){
-
-	ISSMERROR("Not implemented yet");
-
-}
-/*}}}*/
-/*FUNCTION Beam::CostFunction{{{1*/
-double Beam::CostFunction(int,int){
-	ISSMERROR(" not supported yet!");
-}
-/*}}}*/
-/*FUNCTION Beam::CreateKMatrix{{{1*/
-
-void  Beam::CreateKMatrix(Mat Kgg,int analysis_type,int sub_analysis_type){
-
-	/*Just branch to the correct element stiffness matrix generator, according to the type of analysis we are carrying out: */
-	if (analysis_type==DiagnosticAnalysisEnum) {
-	
-		if (sub_analysis_type==HutterAnalysisEnum) {
-
-			CreateKMatrixDiagnosticHutter( Kgg,analysis_type,sub_analysis_type);
-		}
-		else 
-			ISSMERROR("%s%i%s\n","sub_analysis_type: ",sub_analysis_type," not supported yet");
-	}
-	else{
-		ISSMERROR("%s%i%s\n","analysis: ",analysis_type," not supported yet");
-	}
-
-}
-/*}}}*/
-/*FUNCTION Beam::CreateKMatrixDiagnosticHutter{{{1*/
-
-void  Beam::CreateKMatrixDiagnosticHutter(Mat Kgg,int analysis_type,int sub_analysis_type){
-	
-	
-	const int numgrids=2;
-	const int NDOF2=2;
-	const int numdofs=NDOF2*numgrids;
-	int       doflist[numdofs];
-	double    Ke_gg[numdofs][numdofs]={{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}};
-	int       numberofdofspernode;
-	bool onbed;
-	
-	
-	inputs->GetParameterValue(&onbed,ElementOnBedEnum);
-
-	GetDofList(&doflist[0],&numberofdofspernode);
-
-	if (onbed){
-		Ke_gg[0][0]=1;
-		Ke_gg[1][1]=1;
-		Ke_gg[2][0]=-1;
-		Ke_gg[2][2]=1;
-		Ke_gg[3][1]=-1;
-		Ke_gg[3][3]=1;
-	}
-	else{
-		Ke_gg[2][0]=-1;
-		Ke_gg[2][2]=1;
-		Ke_gg[3][1]=-1;
-		Ke_gg[3][3]=1;
-	}
-
-	/*Add Ke_gg to global matrix Kgg: */
-	MatSetValues(Kgg,numdofs,doflist,numdofs,doflist,(const double*)Ke_gg,ADD_VALUES);
-
-}
-/*}}}*/
-/*FUNCTION Beam::CreatePVector{{{1*/
-void  Beam::CreatePVector(Vec pg,int analysis_type,int sub_analysis_type){
-	
-	/*Just branch to the correct load generator, according to the type of analysis we are carrying out: */
-	if (analysis_type==DiagnosticAnalysisEnum) {
-		if (sub_analysis_type==HutterAnalysisEnum) {
-			CreatePVectorDiagnosticHutter( pg,analysis_type,sub_analysis_type);
-		}
-		else
-			ISSMERROR("%s%i%s"," analysis ",analysis_type," not supported yet");
-	}
-	else{
-		ISSMERROR("%s%i%s"," analysis ",analysis_type," not supported yet");
-	}
-
-}
-/*}}}*/
-/*FUNCTION Beam::CreatePVectorDiagnosticHutter{{{1*/
-
-void Beam::CreatePVectorDiagnosticHutter( Vec pg,  int analysis_type,int sub_analysis_type){
-
-	int i,j,k;
-	
-	const int numgrids=2;
-	const int NDOF2=2;
-	const int numdofs=NDOF2*numgrids;
-	int       doflist[numdofs];
-	double    pe_g[4]={0,0,0,0};
-	double    pe_g_gaussian[4]={0,0,0,0};
-	int       found=0;
-	int       dofs[1]={0};
-	double    xyz_list[numgrids][3];
-	double    z_list[numgrids];
-	double    constant_part;
-	int       numberofdofspernode;
-
-	/*gaussian points: */
-	int      num_gauss;
-	double*  segment_gauss_coord=NULL;
-	double   gauss_coord;
-	double*  gauss_weights=NULL;
-	double   gauss_weight;
-	double   gauss1[2]={1,0};
-	int      ig;
-	double   l1l2[2];
-	double   slope[2];
-	double   slope2;
-
-	double   z_g;
-	double   rho_ice,gravity,n,B;
-	double   Jdet;
-	double   ub,vb;
-	double   surface,thickness;
-	
-	bool onbed;
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-	Matpar* matpar=NULL;
-	Matice* matice=NULL;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	matpar=(Matpar*)hmatpar.delivers();
-	matice=(Matice*)hmatice.delivers();
-
-	/*recover doflist: */
-	GetDofList(&doflist[0],&numberofdofspernode);
-
-	/*recover some inputs: */
-	inputs->GetParameterValue(&onbed,ElementOnBedEnum);
-
-	/*recover parameters: */
-	rho_ice=matpar->GetRhoIce();
-	gravity=matpar->GetG();
-	n=matice->GetN();
-	B=matice->GetB();
-
-	//recover extra inputs
-	inputs->GetParameterValue(&slope[0],&gauss1[0],SurfaceSlopexEnum);
-	inputs->GetParameterValue(&slope[1],&gauss1[0],SurfaceSlopeyEnum);
-	inputs->GetParameterValue(&surface,&gauss1[0],SurfaceEnum);
-	inputs->GetParameterValue(&thickness,&gauss1[0],ThicknessEnum);
-
-	//Get all element grid data:
-	GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
-	for(i=0;i<numgrids;i++)z_list[i]=xyz_list[i][2];
-	
-	//compute slope2 slopex and slopy
-	slope2=pow(slope[0],2)+pow(slope[1],2);
-
-	//%compute constant_part
-	constant_part=-2*pow(rho_ice*gravity,n)*pow(slope2,((n-1)/2));
-
-	//Get gaussian points and weights. order 2 since we have a product of 2 nodal functions
-	num_gauss=3;
-	GaussSegment(&segment_gauss_coord, &gauss_weights, num_gauss);
-
-	//Start  looping on the number of gaussian points:
-	for(ig=0;ig<num_gauss;ig++){
-
-		//Pick up the gaussian point and its weight:
-		gauss_weight=gauss_weights[ig];
-		gauss_coord=segment_gauss_coord[ig];
-
-		//compute constant_part
-		GetParameterValue(&z_g, &z_list[0],gauss_coord);
-
-		//Get Jacobian determinant:
-		GetJacobianDeterminant(&Jdet, &z_list[0],gauss_coord);
-		
-		for(j=0;j<NDOF2;j++){
-			pe_g_gaussian[NDOF2+j]=constant_part*pow((surface-z_g)/B,n)*slope[j]*Jdet*gauss_weight;
-		}
-		
-		//add pe_gaussian vector to pe:
-		for(j=0;j<numdofs;j++){
-			pe_g[j]+=pe_g_gaussian[j];
-		}
-	} //for(ig=0;ig<num_gauss;ig++)
-
-	//Deal with lower surface
-	if (onbed){
-
-		//compute ub
-		constant_part=-1.58*pow((double)10.0,-(double)10.0)*rho_ice*gravity*thickness;
-		ub=constant_part*slope[0];
-		vb=constant_part*slope[1];
-
-		//Add to pe: 
-		pe_g[0]+=ub;
-		pe_g[1]+=vb;
-	}
-
-	/*Add pe_g to global vector pg: */
-	VecSetValues(pg,numdofs,doflist,(const double*)pe_g,ADD_VALUES);
-
-	cleanup_and_return: 
-	xfree((void**)&segment_gauss_coord);
-	xfree((void**)&gauss_weights);
-}
-/*}}}*/
-/*FUNCTION Beam::Du{{{1*/
-void  Beam::Du(Vec,int,int){
-	ISSMERROR(" not supported yet!");
-}
-/*}}}*/
-/*FUNCTION Beam::Enum{{{1*/
-int Beam::Enum(void){
-
-	return BeamEnum;
-
-}
-/*}}}*/
-/*FUNCTION Beam::GetBedList{{{1*/
-void  Beam::GetBedList(double*){
-	ISSMERROR(" not supported yet!");
-}
-/*}}}*/
-/*FUNCTION Beam::GetDofList{{{1*/
-void  Beam::GetDofList(int* doflist,int* pnumberofdofspernode){
-
-	int i,j;
-	int doflist_per_node[MAXDOFSPERNODE];
-	int numberofdofspernode;
-	
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	
-	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;
-
-}
-/*}}}*/
-/*FUNCTION Beam::GetDofList1{{{1*/
-void  Beam::GetDofList1(int* doflist){
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	
-	int i;
-	for(i=0;i<2;i++){
-		doflist[i]=nodes[i]->GetDofList1();
-	}
-
-}
-/*}}}*/
-/*FUNCTION Beam::Id{{{1*/
-int    Beam::Id(void){ return id; }
-/*}}}*/
-/*FUNCTION Beam::GetJacobianDeterminant{{{1*/
-void Beam::GetJacobianDeterminant(double* pJdet,double* z_list, double gauss_coord){
-
-
-	double Jdet;
-
-	Jdet=1.0/2.0*(z_list[1]-z_list[0]);
-
-	if(Jdet<0){
-		ISSMERROR(" negative jacobian determinant!");
-	}
-	
-	*pJdet=Jdet;
-}
-/*}}}*/
-/*FUNCTION Beam::GetMatPar{{{1*/
-void* Beam::GetMatPar(){
-
-	/*dynamic objects pointed to by hooks: */
-	Matpar* matpar=NULL;
-
-	/*recover objects from hooks: */
-	matpar=(Matpar*)hmatpar.delivers();
-
-	return matpar;
-}
-/*}}}*/
-/*FUNCTION Beam::GetNodalFunctions{{{1*/
-void Beam::GetNodalFunctions(double* l1l2, double gauss_coord){
-	
-	/*This routine returns the values of the nodal functions  at the gaussian point.*/
-
-	/*First nodal function: */
-	l1l2[0]=.5*gauss_coord+.5;
-
-	/*Second nodal function: */
-	l1l2[1]=-.5*gauss_coord+.5;
-}
-/*}}}*/
-/*FUNCTION Beam::GetNodes{{{1*/
-void  Beam::GetNodes(void** vpnodes){
-	int i;
-	Node** pnodes=NULL;
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-	
-	/*recover nodes: */
-	pnodes=(Node**)vpnodes;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	
-	for(i=0;i<3;i++){
-		pnodes[i]=nodes[i];
-	}
-}
-/*}}}*/
-/*FUNCTION Beam::GetOnBed{{{1*/
-bool   Beam::GetOnBed(){
-	ISSMERROR(" not supported yet!");
-}
-/*}}}*/
-/*FUNCTION Beam::GetParameterValue{{{1*/
-void Beam::GetParameterValue(double* pvalue, double* value_list,double gauss_coord){
-
-	double l1l2[2];
-	
-	GetNodalFunctions(&l1l2[0],gauss_coord);
-
-	*pvalue=l1l2[0]*value_list[0]+l1l2[1]*value_list[1];
-}
-/*}}}*/
-/*FUNCTION Beam::GetShelf{{{1*/
-bool   Beam::GetShelf(){
-	ISSMERROR(" not supported yet!");
-}
-/*}}}*/
-/*FUNCTION Beam::GetThicknessList{{{1*/
-void  Beam::GetThicknessList(double* thickness_list){
-	ISSMERROR(" not supported yet!");
-}
-/*}}}*/
-/*FUNCTION Beam::Gradj{{{1*/
-void  Beam::Gradj(Vec, int, int,char*){
-	ISSMERROR(" not supported yet!");
-}
-/*}}}*/
-/*FUNCTION Beam::GradjB{{{1*/
-void  Beam::GradjB(Vec, int, int){
-	ISSMERROR(" not supported yet!");
-}
-/*}}}*/
-/*FUNCTION Beam::GradjDrag{{{1*/
-void  Beam::GradjDrag(Vec, int,int ){
-	ISSMERROR(" not supported yet!");
-}
-/*}}}*/
-/*FUNCTION Beam::MassFlux{{{1*/
-double Beam::MassFlux( double* segment,double* ug){
-	ISSMERROR(" not supported yet!");
-}
-/*}}}*/
-/*FUNCTION Beam::Misfit{{{1*/
-double Beam::Misfit(int,int){
-	ISSMERROR(" not supported yet!");
-}
-/*}}}*/
-/*FUNCTION Beam::MyRank{{{1*/
-int    Beam::MyRank(void){ 
-	extern int my_rank;
-	return my_rank; 
-}
-/*}}}*/
-/*FUNCTION Beam::SurfaceArea{{{1*/
-double Beam::SurfaceArea(int,int){
-	ISSMERROR(" not supported yet!");
-}
-/*}}}*/
-//*FUNCTION Beam::SetClone {{{1*/
-void  Beam::SetClone(int* minranks){
-
-	ISSMERROR("not implemented yet");
-}
-/*}}}1*/
-
Index: sm/trunk/src/c/objects/Beam.h
===================================================================
--- /issm/trunk/src/c/objects/Beam.h	(revision 3680)
+++ 	(revision )
@@ -1,101 +1,0 @@
-/*! \file Beam.h 
- *  \brief: header file for beam object
- */
-
-#ifndef _BEAM_H_
-#define _BEAM_H_
-
-/*Headers:*/
-/*{{{1*/
-
-#include "./Element.h"
-#include "./Node.h"
-#include "./Matice.h"
-#include "./Matpar.h"
-#include "../shared/Exceptions/exceptions.h"
-#include "../include/macros.h"
-#include "../ModelProcessorx/IoModel.h"
-#include "../DataSet/Inputs.h"
-#include "../DataSet/DataSet.h"
-#include "../DataSet/Parameters.h"
-#include "./Hook.h"
-
-class Object;
-class DataSet;
-class Element;
-class Hook;
-/*}}}*/
-
-class Beam: public Element{
-
-	public:
-
-		/*ids:*/
-		int id;
-
-		Hook hnodes;  //hook to 2 nodes
-		Hook hmatice; //hook to 1 matice
-		Hook hmatpar; //hook to 1 matpar
-		
-		Parameters* parameters; //pointer to solution parameters
-		Inputs* inputs;
-	
-
-		/*constructors, destructors: {{{1*/
-		Beam();
-		Beam(int beam_id,int* beam_node_ids, int beam_matice_id, int beam_matpar_id);
-		Beam(int beam_id,Hook* beam_hnodes, Hook* beam_hmatice, Hook* beam_hmatpar, Parameters* beam_parameters, Inputs* beam_inputs);
-		Beam(int beam_id,int i, IoModel* iomodel);
-		~Beam();
-		/*}}}*/
-		/*object management: {{{1*/
-		void  Echo();
-		void  DeepEcho();
-		void  Marshall(char** pmarshalled_dataset);
-		int   MarshallSize();
-		void  Demarshall(char** pmarshalled_dataset);
-		int   Enum();
-		int   Id(); 
-		int   MyRank();
-		void  Configure(DataSet* loads,DataSet* nodes,DataSet* materials,Parameters* parameters);
-		Object* copy();
-		void  SetClone(int* minranks);
-
-		/*}}}*/
-		/*numerics: {{{1*/
-		void  CreateKMatrix(Mat Kgg,int analysis_type,int sub_analysis_type);
-		void  CreatePVector(Vec pg,  int analysis_type,int sub_analysis_type);
-		void  UpdateInputs(double* solution, int analysis_type, int sub_analysis_type);
-		void  GetDofList(int* doflist,int* pnumberofdofs);
-		void  GetDofList1(int* doflist);
-		void  CreateKMatrixDiagnosticHutter(Mat Kgg,int analysis_type,int sub_analysis_type);
-		void  GetParameterValue(double* pp, double* plist, double* gauss_l1l2l3);
-		void  CreatePVectorDiagnosticHutter(Vec pg,int analysis_type,int sub_analysis_type);
-		void* GetMatPar();
-
-		void  ComputeBasalStress(Vec sigma_b,int analysis_type,int sub_analysis_type);
-		void  ComputePressure(Vec p_g,int analysis_type,int sub_analysis_type);
-		void  ComputeStrainRate(Vec eps,int analysis_type,int sub_analysis_type);
-		void  GetNodes(void** vpnodes);
-		/*}}}*/
-		/*not implemented: {{{1*/
-		bool  GetShelf();
-		bool  GetOnBed();
-		void  GetBedList(double*);
-		void  GetThicknessList(double* thickness_list);
-		void  Du(Vec, int,int);
-		void  Gradj(Vec,  int, int,char*);
-		void  GradjDrag(Vec,  int,int );
-		void  GradjB(Vec,  int,int );
-		double Misfit(int,int);
-		double SurfaceArea(int,int);
-		double CostFunction(int,int);
-		void  GetNodalFunctions(double* l1l2, double gauss_coord);
-		void  GetParameterValue(double* pvalue, double* value_list,double gauss_coord);
-		void  GetJacobianDeterminant(double* pJdet,double* z_list, double gauss_coord);
-		double MassFlux(double* segment,double* ug);
-		void AddInput(double value, int enum_type){ISSMERROR("not supporte yet!");}
-		/*}}}*/
-
-};
-#endif  /* _BEAM_H */
Index: /issm/trunk/src/c/objects/Contour.cpp
===================================================================
--- /issm/trunk/src/c/objects/Contour.cpp	(revision 3680)
+++ /issm/trunk/src/c/objects/Contour.cpp	(revision 3681)
@@ -9,5 +9,5 @@
 #endif
 
-#include "./Contour.h"
+#include "./objects.h"
 #include "../include/macros.h"
 #include "../shared/Matlab/matlabshared.h"
Index: /issm/trunk/src/c/objects/DofIndexing.cpp
===================================================================
--- /issm/trunk/src/c/objects/DofIndexing.cpp	(revision 3680)
+++ /issm/trunk/src/c/objects/DofIndexing.cpp	(revision 3681)
@@ -10,5 +10,5 @@
 
 #include "stdio.h"
-#include "./DofIndexing.h"
+#include "./objects.h"
 #include <string.h>
 #include "../EnumDefinitions/EnumDefinitions.h"
Index: /issm/trunk/src/c/objects/DofObject.h
===================================================================
--- /issm/trunk/src/c/objects/DofObject.h	(revision 3680)
+++ /issm/trunk/src/c/objects/DofObject.h	(revision 3681)
@@ -8,8 +8,5 @@
 
 /*Headers:*/
-/*{{{1*/
-#include "./Object.h"
 #include "../toolkits/toolkits.h"
-/*}}}*/
 
 class DofObject{
Index: /issm/trunk/src/c/objects/DofVec.cpp
===================================================================
--- /issm/trunk/src/c/objects/DofVec.cpp	(revision 3680)
+++ /issm/trunk/src/c/objects/DofVec.cpp	(revision 3681)
@@ -9,5 +9,5 @@
 #endif
 
-#include "./DofVec.h"
+#include "./objects.h"
 #include "../shared/shared.h"
 #include "../include/macros.h"
Index: sm/trunk/src/c/objects/Element.h
===================================================================
--- /issm/trunk/src/c/objects/Element.h	(revision 3680)
+++ 	(revision )
@@ -1,51 +1,0 @@
-/*!\file:  Element.h
- * \brief abstract class for Element object
- * This class is a place holder for the Tria and the Penta elements. 
- * It is derived from Element, so DataSets can contain them.
- */ 
-
-
-#ifndef _ELEMENT_H_
-#define _ELEMENT_H_
-
-/*Headers:*/
-/*{{{1*/
-#include "./Object.h"
-#include "../DataSet/DataSet.h"
-#include "../DataSet/Parameters.h"
-#include "../toolkits/toolkits.h"
-/*}}}*/
-
-class Element: public Object{
-
-	public: 
-		
-		virtual        ~Element(){};
-		virtual void   Configure(DataSet* loads,DataSet* nodes,DataSet* materials,Parameters* parameters)=0;
-		
-		virtual void   CreateKMatrix(Mat Kgg,int analysis_type,int sub_analysis_type)=0;
-		virtual void   CreatePVector(Vec pg,  int analysis_type,int sub_analysis_type)=0;
-		virtual void   UpdateInputs(double* solution, int analysis_type, int sub_analysis_type)=0;
-		virtual void   GetNodes(void** nodes)=0;
-		virtual void*  GetMatPar()=0;
-		virtual bool   GetShelf()=0; 
-		virtual bool   GetOnBed()=0;
-		virtual void   GetThicknessList(double* thickness_list)=0;
-		virtual void   GetBedList(double* bed_list)=0;
-		virtual void   Du(Vec du_g,int analysis_type,int sub_analysis_type)=0;
-		virtual void   Gradj(Vec grad_g,int analysis_type,int sub_analysis_type,char* control_type)=0;
-		virtual void   GradjDrag(Vec grad_g,int analysis_type,int sub_analysis_type)=0;
-		virtual void   GradjB(Vec grad_g,int analysis_type,int sub_analysis_type)=0;
-		virtual double Misfit(int analysis_type,int sub_analysis_type)=0;
-		virtual double CostFunction(int analysis_type,int sub_analysis_type)=0;
-		virtual double SurfaceArea(int analysis_type,int sub_analysis_type)=0;
-		virtual void   ComputeBasalStress(Vec sigma_b,int analysis_type,int sub_analysis_type)=0;
-		virtual void   ComputePressure(Vec p_g,       int analysis_type,int sub_analysis_type)=0;
-		virtual void   ComputeStrainRate(Vec eps,     int analysis_type,int sub_analysis_type)=0;
-		virtual double MassFlux(double* segment,double* ug)=0;
-		virtual void   AddInput(double value, int enum_type)=0;
-
-		/*Implementation: */
-
-};
-#endif
Index: /issm/trunk/src/c/objects/FemModel.cpp
===================================================================
--- /issm/trunk/src/c/objects/FemModel.cpp	(revision 3680)
+++ /issm/trunk/src/c/objects/FemModel.cpp	(revision 3681)
@@ -12,5 +12,5 @@
 #include "../shared/shared.h"
 #include "../include/macros.h"
-#include "./FemModel.h"
+#include "./objects.h"
 
 /*constructors/destructors*/
Index: /issm/trunk/src/c/objects/FemModel.h
===================================================================
--- /issm/trunk/src/c/objects/FemModel.h	(revision 3680)
+++ /issm/trunk/src/c/objects/FemModel.h	(revision 3681)
@@ -8,12 +8,10 @@
 /*Headers:*/
 /*{{{1*/
+#include "./Object.h"
+#include "../toolkits/toolkits.h"
 class DataSet;
+class Parameters;
 class DofVec;
-#include "./Object.h"
-#include "../DataSet/DataSet.h"
-#include "../DataSet/Parameters.h"
-#include "./DofVec.h"
-#include "../toolkits/toolkits.h"
-#include "../parallel/parallel.h"
+class NodeSets;
 /*}}}*/
 
Index: sm/trunk/src/c/objects/Friction.cpp
===================================================================
--- /issm/trunk/src/c/objects/Friction.cpp	(revision 3680)
+++ 	(revision )
@@ -1,195 +1,0 @@
-/*!\file: Friction.cpp
- * \brief: wrapper for all friction parameters
- */ 
-
-#include "./Friction.h"
-#include "../shared/shared.h"
-#include "../include/typedefs.h"
-
-/*--------------------------------------------------
-	NewFriction
-  --------------------------------------------------*/
-
-/*FUNCTION NewFriction{{{1*/
-Friction* NewFriction(void)
-{
-	/* create a new Friction object */
-
-	return (Friction*)xmalloc(sizeof(Friction));
-}
-/*}}}*/
-/*FUNCTION FrictionEcho{{{1*/
-void  FrictionEcho(Friction* friction){
-
-	int i;
-	
-	printf("Friction echo: \n");
-	printf("   element_type: %s\n",friction->element_type);
-	printf("   gravity: %g\n",friction->gravity);
-	printf("   rho_ice: %g\n",friction->rho_ice);
-	printf("   rho_water: %g\n",friction->rho_water);
-	printf("   p: %g\n",friction->p);
-	printf("   q: %g\n",friction->q);
-	printf("   analysis_type: %i\n",friction->analysis_type);
-
-	printf("K: ");
-	for(i=0;i<3;i++)printf("%g ",friction->K[i]);
-	printf("\n");
-
-	printf("bed: ");
-	for(i=0;i<3;i++)printf("%g ",friction->bed[i]);
-	printf("\n");
-
-	printf("thickness: ");
-	for(i=0;i<3;i++)printf("%g ",friction->thickness[i]);
-	printf("\n");
-
-	printf("vx: ");
-	for(i=0;i<3;i++)printf("%g ",friction->vx[i]);
-	printf("\n            ");
-	printf("vy: ");
-	for(i=0;i<3;i++)printf("%g ",friction->vy[i]);
-	printf("\n");
-	if(friction->vz){
-		printf("vz: ");
-		for(i=0;i<3;i++)printf("%g ",friction->vz[i]);
-		printf("\n");
-	}
-
-}
-/*}}}*/
-/*FUNCTION FrictionInit {{{1*/
-/*--------------------------------------------------
-	FrictionInit
-  --------------------------------------------------*/
-
-int FrictionInit(Friction* friction)
-{
-	friction->element_type=NULL;
-	friction->gravity=UNDEF;
-	friction->rho_ice=UNDEF;
-	friction->rho_water=UNDEF;
-	friction->K=NULL; 
-	friction->bed=NULL;
-	friction->thickness=NULL;
-	friction->vx=NULL;
-	friction->vy=NULL;
-	friction->vz=NULL;
-	friction->p=UNDEF;
-	friction->q=UNDEF;
-	friction->analysis_type=UNDEF;
-	
-	return 1;
-}
-/*}}}*/
-/*FUNCTION DeleteFriction {{{1*/
-/*--------------------------------------------------
-	DeleteFriction
-  --------------------------------------------------*/
-
-void DeleteFriction(Friction** pfriction)
-{
-	Friction* friction = *pfriction;
-
-	/*Just  erase element_type: */
-	xfree((void**)&friction->element_type);
-
-	/*Erase entire structure: */
-	xfree((void**)pfriction);
-}
-/*}}}*/
-/*FUNCTION FrictionGetAlpha2 {{{1*/
-/*--------------------------------------------------
-	FrictionGetAlpha2
-  --------------------------------------------------*/
-void  FrictionGetAlpha2(double* alpha2, Friction* friction){
-
-	/*This routine calculates the basal friction coefficient 
-	alpha2= drag^2 * Neff ^r * vel ^s, with Neff=rho_ice*g*thickness+rho_ice*g*bed, r=q/p and s=1/p*
-	alpha2 is assumed to be double[3]: */
-
-	/*diverse: */
-	int     i;
-	const int     numgrids=3;
-	double  Neff[numgrids];
-	double  r,s;
-	double  velocity_x[numgrids];
-	double  velocity_y[numgrids];
-	double  velocity_z[numgrids];
-	double  velocity_mag[numgrids];
-
-	//compute r and q coefficients: */
-	r=friction->q/friction->p;
-	s=1./friction->p;
-		
-	//From bed and thickness, compute effective pressure when drag is viscous:
-	for(i=0;i<numgrids;i++){
-
-		Neff[i]=friction->gravity*(friction->rho_ice*friction->thickness[i]+friction->rho_water*friction->bed[i]);
-
-		/*If effective pressure becomes negative, sliding becomes unstable (Paterson 4th edition p 148). This is because 
-		the water pressure is so high, the ice sheet elevates over its ice bumps and slides. But the limit behaviour 
-		for friction should be an ice shelf sliding (no basal drag). Therefore, for any effective pressure Neff < 0, we should 
-		replace it by Neff=0 (ie, equival it to an ice shelf)*/
-		if (Neff[i]<0)Neff[i]=0;
-
-		//We need the velocity magnitude to evaluate the basal stress:
-		if(strcmp(friction->element_type,"2d")){
-			velocity_x[i]=friction->vx[i];//velocities of size numgridsx2
-			velocity_y[i]=friction->vy[i];
-			velocity_mag[i]=sqrt(pow(velocity_x[i],2)+pow(velocity_y[i],2));
-		}
-		else{
-			velocity_x[i]=friction->vx[i]; //velocities of size numgridsx3
-			velocity_y[i]=friction->vy[i];
-			velocity_z[i]=friction->vz[i];
-			velocity_mag[i]=sqrt(pow(velocity_x[i],2)+pow(velocity_y[i],2)+pow(velocity_z[i],2));
-		}
-	
-		alpha2[i]=pow(friction->K[i],2)*pow(Neff[i],r)*pow(velocity_mag[i],(s-1));
-	}
-}
-/*}}}*/
-/*FUNCTION FrictionGetAlphaComplement {{{1*/
-/*--------------------------------------------------
-	FrictionGetAlphaComplement
-  --------------------------------------------------*/
-void  FrictionGetAlphaComplement(double* alpha_complement, Friction* friction){
-
-	/* FrictionGetAlpha2 computes alpha2= drag^2 * Neff ^r * vel ^s, with Neff=rho_ice*g*thickness+rho_ice*g*bed, r=q/p and s=1/p. 
-	 * FrictionGetAlphaComplement is used in control methods on drag, and it computes: 
-	 * alpha_complement= Neff ^r * vel ^s*/
-
-	/*diverse: */
-	int     i;
-	const int     numgrids=3;
-	double  Neff[numgrids];
-	double  r,s;
-	double  velocity_x[numgrids];
-	double  velocity_y[numgrids];
-	double  velocity_mag[numgrids];
-
-	//compute r and q coefficients: */
-	r=friction->q/friction->p;
-	s=1./friction->p;
-		
-	//From bed and thickness, compute effective pressure when drag is viscous:
-	for(i=0;i<numgrids;i++){
-
-		Neff[i]=friction->gravity*(friction->rho_ice*friction->thickness[i]+friction->rho_water*friction->bed[i]);
-
-		/*If effective pressure becomes negative, sliding becomes unstable (Paterson 4th edition p 148). This is because 
-		the water pressure is so high, the ice sheet elevates over its ice bumps and slides. But the limit behaviour 
-		for friction should be an ice shelf sliding (no basal drag). Therefore, for any effective pressure Neff < 0, we should 
-		replace it by Neff=0 (ie, equival it to an ice shelf)*/
-		if (Neff[i]<0)Neff[i]=0;
-
-		//We need the velocity magnitude to evaluate the basal stress:
-		velocity_x[i]=friction->vx[i]; //velocities of size numgridsx2
-		velocity_y[i]=friction->vy[i];
-		velocity_mag[i]=sqrt(pow(velocity_x[i],2)+pow(velocity_y[i],2));
-	
-		alpha_complement[i]=pow(Neff[i],r)*pow(velocity_mag[i],(s-1));
-	}
-}
-/*}}}*/
Index: sm/trunk/src/c/objects/Friction.h
===================================================================
--- /issm/trunk/src/c/objects/Friction.h	(revision 3680)
+++ 	(revision )
@@ -1,38 +1,0 @@
-/*! \file Friction.h
- *  \brief Friction object, interface, declaration
- */
-
-#ifndef _FRICTION_H
-#define _FRICTION_H
-
-/*!Friction declaration: */
-struct Friction {
-
-	char*   element_type;
-	double  gravity;
-	double  rho_ice;
-	double  rho_water;
-	double* K;
-	double* bed;
-	double* thickness;
-	double* vx;
-	double* vy;
-	double* vz;
-	double  p;
-	double  q;
-	int     analysis_type;
-
-};
-
-
-/* creation, initialisation: */
-
-	Friction*	NewFriction(void);
-	int	FrictionInit(Friction* friction);
-	void  DeleteFriction(Friction** pfriction);
-	void  FrictionGetAlpha2(double* alpha2, Friction* friction);
-	void  FrictionGetAlphaComplement(double* alpha_complement, Friction* friction);
-	void  FrictionEcho(Friction* friction);
-
-#endif  /* _FRICTION_H */
-
Index: /issm/trunk/src/c/objects/Hook.cpp
===================================================================
--- /issm/trunk/src/c/objects/Hook.cpp	(revision 3680)
+++ /issm/trunk/src/c/objects/Hook.cpp	(revision 3681)
@@ -12,7 +12,6 @@
 #include "stdio.h"
 #include <string.h>
-#include "./Object.h"
+#include "./objects.h"
 #include "../DataSet/DataSet.h"
-#include "./Hook.h"
 #include "../EnumDefinitions/EnumDefinitions.h"
 #include "../shared/shared.h"
Index: /issm/trunk/src/c/objects/Hook.h
===================================================================
--- /issm/trunk/src/c/objects/Hook.h	(revision 3680)
+++ /issm/trunk/src/c/objects/Hook.h	(revision 3681)
@@ -11,9 +11,6 @@
 /*Headers:*/
 /*{{{1*/
+#include "./Object.h"
 class DataSet;
-class Object;
-#include "./Object.h"
-#include "../DataSet/DataSet.h"
-#include "../toolkits/toolkits.h"
 /*}}}*/
 
Index: sm/trunk/src/c/objects/Icefront.cpp
===================================================================
--- /issm/trunk/src/c/objects/Icefront.cpp	(revision 3680)
+++ 	(revision )
@@ -1,1342 +1,0 @@
-/*!\file Icefront.c
- * \brief: implementation of the Icefront object
- */
-
-/*Headers:*/
-/*{{{1*/
-#ifdef HAVE_CONFIG_H
-	#include "config.h"
-#else
-#error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
-#endif
-
-#include "stdio.h"
-#include <string.h>
-#include "../EnumDefinitions/EnumDefinitions.h"
-#include "../shared/shared.h"
-#include "../include/typedefs.h"
-#include "../include/macros.h"
-#include "./Icefront.h"
-/*}}}*/	
-
-/*Object constructors and destructor*/
-/*FUNCTION Icefront::Icefront() {{{1*/
-Icefront::Icefront(){
-	this->inputs=NULL;
-	this->parameters=NULL;
-}
-/*}}}*/
-/*FUNCTION Icefront::Icefront(int id, int* node_ids, int numnodes, int element_id, int matpar_id){{{1*/
-Icefront::Icefront(int icefront_id,int* icefront_node_ids, int icefront_numnodes, int icefront_element_id, int icefront_matpar_id): 
-	hnodes(icefront_node_ids,icefront_numnodes),
-	helement(&icefront_element_id,1),
-	hmatpar(&icefront_matpar_id,1)
-{
-
-	/*all the initialization has been done by the initializer, just fill in the id : */
-	this->id=icefront_id;
-	this->parameters=NULL;
-	this->inputs=new Inputs();
-
-}
-/*}}}*/
-/*FUNCTION Icefront::Icefront(int id, Hook* hnodes, Hook* helement, Hook* hmatpar, Parameters* parameters, Inputs* icefront_inputs) {{{1*/
-Icefront::Icefront(int icefront_id,Hook* icefront_hnodes, Hook* icefront_helement, Hook* icefront_hmatpar, Parameters* icefront_parameters, Inputs* icefront_inputs):
-	hnodes(icefront_hnodes),
-	helement(icefront_helement),
-	hmatpar(icefront_hmatpar)
-{
-
-	/*all the initialization has been done by the initializer, just fill in the id: */
-	this->id=icefront_id;
-	if(icefront_inputs){
-		this->inputs=(Inputs*)icefront_inputs->Copy();
-	}
-	else{
-		this->inputs=new Inputs();
-	}
-	/*point parameters: */
-	this->parameters=icefront_parameters;
-}
-/*}}}*/
-/*FUNCTION Icefront::Icefront(int id, int i, IoModel* iomodel) {{{1*/
-Icefront::Icefront(int icefront_id,int i, IoModel* iomodel){
-
-	int segment_width;
-	int element;
-	int num_nodes;
-
-	/*icefront constructor data: */
-	int  icefront_eid;
-	int  icefront_mparid;
-	int  icefront_node_ids[MAX_ICEFRONT_GRIDS];
-	int  icefront_fill;
-	int  icefront_type;
-
-	/*First, retrieve element index and element type: */
-	if (strcmp(iomodel->meshtype,"2d")==0){
-		segment_width=4;
-	}
-	else{
-		segment_width=6;
-	}
-	element=(int)(*(iomodel->pressureload+segment_width*i+segment_width-2)-1); //element is in the penultimate column (grid1 grid2 ... elem fill)
-
-	/*Build ids for hook constructors: */
-	icefront_eid=(int) *(iomodel->pressureload+segment_width*i+segment_width-2); //matlab indexing
-	icefront_mparid=iomodel->numberofelements+1; //matlab indexing
-
-	icefront_node_ids[0]=(int)*(iomodel->pressureload+segment_width*i+0);
-	icefront_node_ids[1]=(int)*(iomodel->pressureload+segment_width*i+1);
-
-	if (iomodel->sub_analysis_type==HorizAnalysisEnum){
-		if ((int)*(iomodel->elements_type+2*element+0)==MacAyealFormulationEnum){ //this is a collapsed 3d element, icefront will be 2d
-			icefront_type=SegmentIcefrontEnum;
-		}
-		else if ((int)*(iomodel->elements_type+2*element+0)==PattynFormulationEnum){ //this is a real 3d element, icefront will be 3d.
-			icefront_type=QuadIceFrontEnum;
-			icefront_node_ids[2]=(int)*(iomodel->pressureload+segment_width*i+2);
-			icefront_node_ids[3]=(int)*(iomodel->pressureload+segment_width*i+3);
-		}
-		else ISSMERROR(" element type %i not supported yet",(int)*(iomodel->elements_type+2*element+0));
-	}
-	else if (iomodel->sub_analysis_type==StokesAnalysisEnum){
-		//We have a Stokes element, so we need a 3d Icefront
-		icefront_type=QuadIceFrontEnum;
-		icefront_node_ids[2]=(int)*(iomodel->pressureload+segment_width*i+2);
-		icefront_node_ids[3]=(int)*(iomodel->pressureload+segment_width*i+3);
-	}
-	else ISSMERROR("Not supported yet!");
-
-	if (icefront_type==QuadIceFrontEnum) num_nodes=4;
-	else num_nodes=2;
-	icefront_fill=(int)*(iomodel->pressureload+segment_width*i+segment_width-1); 
-	
-	/*Ok, we have everything to build the object: */
-	this->id=icefront_id;
-
-	/*Hooks: */
-	this->hnodes.Init(icefront_node_ids,num_nodes);
-	this->helement.Init(&icefront_eid,1);
-	this->hmatpar.Init(&icefront_mparid,1);
-
-	//intialize  and add as many inputs per element as requested: 
-	this->inputs=new Inputs();
-	this->inputs->AddInput(new IntInput(FillEnum,icefront_fill));
-	this->inputs->AddInput(new IntInput(TypeEnum,icefront_type));
-	
-	//this->parameters: we still can't point to it, it may not even exist. Configure will handle this.
-	this->parameters=NULL;
-}
-
-
-/*}}}*/
-/*FUNCTION Icefront::~Icefront() {{{1*/
-Icefront::~Icefront(){
-	delete inputs;
-	this->parameters=NULL;
-}
-/*}}}*/
-
-/*Object marshall*/
-/*FUNCTION Icefront Configure {{{1*/
-void  Icefront::Configure(DataSet* elementsin,DataSet* loadsin,DataSet* nodesin,DataSet* verticesin,DataSet* materialsin,Parameters* parametersin){
-
-	/*Take care of hooking up all objects for this element, ie links the objects in the hooks to their respective 
-	 * datasets, using internal ids and offsets hidden in hooks: */
-	hnodes.configure(nodesin);
-	helement.configure(elementsin);
-	hmatpar.configure(materialsin);
-
-	/*point parameters to real dataset: */
-	this->parameters=parametersin;
-}
-/*}}}*/
-/*FUNCTION Icefront copy {{{1*/
-Object* Icefront::copy() {
-	return new Icefront(this->id,&this->hnodes,&this->helement,&this->hmatpar,this->parameters,this->inputs);
-}
-/*}}}*/
-/*FUNCTION Icefront::DeepEcho{{{1*/
-void Icefront::DeepEcho(void){
-
-	printf("Icefront:\n");
-	printf("   id: %i\n",id);
-	hnodes.DeepEcho();
-	helement.DeepEcho();
-	hmatpar.DeepEcho();
-	printf("   parameters\n");
-	parameters->DeepEcho();
-	printf("   inputs\n");
-	inputs->DeepEcho();
-}
-/*}}}*/
-/*FUNCTION Icefront::Demarshall {{{1*/
-void  Icefront::Demarshall(char** pmarshalled_dataset){
-
-	char* marshalled_dataset=NULL;
-	int   i;
-
-	/*recover marshalled_dataset: */
-	marshalled_dataset=*pmarshalled_dataset;
-
-	/*this time, no need to get enum type, the pointer directly points to the beginning of the 
-	 *object data (thanks to DataSet::Demarshall):*/
-
-	memcpy(&id,marshalled_dataset,sizeof(id));marshalled_dataset+=sizeof(id);
-
-	/*demarshall hooks: */
-	hnodes.Demarshall(&marshalled_dataset);
-	helement.Demarshall(&marshalled_dataset);
-	hmatpar.Demarshall(&marshalled_dataset);
-	
-	/*demarshall inputs: */
-	inputs=(Inputs*)DataSetDemarshallRaw(&marshalled_dataset); 
-
-	/*parameters: may not exist even yet, so let Configure handle it: */
-	this->parameters=NULL;
-
-	/*return: */
-	*pmarshalled_dataset=marshalled_dataset;
-	return;
-}
-/*}}}*/
-/*FUNCTION Icefront Echo {{{1*/
-void Icefront::Echo(void){
-	this->DeepEcho();
-}
-/*}}}*/
-/*FUNCTION Icefront Enum {{{1*/
-int Icefront::Enum(void){
-
-	return IcefrontEnum;
-
-}
-/*}}}*/
-/*FUNCTION Icefront Id {{{1*/
-int    Icefront::Id(void){ return id; }
-/*}}}*/
-/*FUNCTION Icefront::Marshall {{{1*/
-void  Icefront::Marshall(char** pmarshalled_dataset){
-
-	char* marshalled_dataset=NULL;
-	int   enum_type=0;
-	char* marshalled_inputs=NULL;
-	int   marshalled_inputs_size;
-
-	/*recover marshalled_dataset: */
-	marshalled_dataset=*pmarshalled_dataset;
-
-	/*get enum type of Icefront: */
-	enum_type=IcefrontEnum;
-
-	/*marshall enum: */
-	memcpy(marshalled_dataset,&enum_type,sizeof(enum_type));marshalled_dataset+=sizeof(enum_type);
-
-	/*marshall Icefront data: */
-	memcpy(marshalled_dataset,&id,sizeof(id));marshalled_dataset+=sizeof(id);
-
-	/*Marshall hooks: */
-	hnodes.Marshall(&marshalled_dataset);
-	helement.Marshall(&marshalled_dataset);
-	hmatpar.Marshall(&marshalled_dataset);
-
-	/*Marshall inputs: */
-	marshalled_inputs_size=inputs->MarshallSize();
-	marshalled_inputs=inputs->Marshall();
-	memcpy(marshalled_dataset,marshalled_inputs,marshalled_inputs_size*sizeof(char));
-	marshalled_dataset+=marshalled_inputs_size;
-
-	/*parameters: don't do anything about it. parameters are marshalled somewhere else!*/
-
-	xfree((void**)&marshalled_inputs);
-
-	*pmarshalled_dataset=marshalled_dataset;
-}
-/*}}}*/
-/*FUNCTION Icefront::MarshallSize {{{1*/
-int   Icefront::MarshallSize(){
-	
-	return sizeof(id)
-		+hnodes.MarshallSize()
-		+helement.MarshallSize()
-		+hmatpar.MarshallSize()
-		+inputs->MarshallSize()
-		+sizeof(int); //sizeof(int) for enum type
-}
-/*}}}*/
-/*FUNCTION Icefront MyRank {{{1*/
-int    Icefront::MyRank(void){ 
-	extern int my_rank;
-	return my_rank; 
-}
-/*}}}*/
-
-/*Object functions*/
-/*FUNCTION Icefront CreateKMatrix {{{1*/
-
-void  Icefront::CreateKMatrix(Mat Kgg,int analysis_type,int sub_analysis_type){
-
-	/*No stiffness loads applied, do nothing: */
-
-	return;
-
-}
-/*}}}*/
-/*FUNCTION Icefront CreatePVector {{{1*/
-void  Icefront::CreatePVector(Vec pg, int analysis_type,int sub_analysis_type){
-
-	/*Just branch to the correct element icefront vector generator, according to the type of analysis we are carrying out: */
-	if (analysis_type==ControlAnalysisEnum){
-		
-		CreatePVectorDiagnosticHoriz( pg,analysis_type,sub_analysis_type);
-
-	}
-	else if (analysis_type==DiagnosticAnalysisEnum){
-	
-		if (sub_analysis_type==HorizAnalysisEnum){
-		
-			CreatePVectorDiagnosticHoriz( pg,analysis_type,sub_analysis_type);
-
-		}
-		else if (sub_analysis_type==StokesAnalysisEnum){
-			
-			CreatePVectorDiagnosticStokes( pg,analysis_type,sub_analysis_type);
-
-		}
-		else ISSMERROR("%s%i%s"," sub_analysis_type: ",sub_analysis_type," not supported yet");
-
-	}
-	else{
-		ISSMERROR("%s%i%s"," analysis ",analysis_type," not supported yet");
-	}
-}
-/*}}}*/
-/*FUNCTION Icefront CreatePVectorDiagnosticHoriz {{{1*/
-void Icefront::CreatePVectorDiagnosticHoriz( Vec pg,  int analysis_type,int sub_analysis_type){
-	
-	int type;
-	inputs->GetParameterValue(&type,TypeEnum);
-
-	/*Branck on the type of icefront: */
-	if (type==SegmentIcefrontEnum){
-		CreatePVectorDiagnosticHorizSegment(pg,analysis_type,sub_analysis_type);
-	}
-	else{
-		CreatePVectorDiagnosticHorizQuad(pg,analysis_type,sub_analysis_type);
-	}
-}	
-/*}}}*/
-/*FUNCTION Icefront CreatePVectorDiagnosticHorizSegment{{{1*/
-void Icefront::CreatePVectorDiagnosticHorizSegment( Vec pg,int analysis_type,int sub_analysis_type){
-
-	int i,j;
-	
-	const int numgrids=2;
-	const int NDOF2=2;
-	int   numberofdofspernode;
-	const int numdofs=numgrids*NDOF2;
-	int   doflist[numdofs];
-	double xyz_list[numgrids][3];
-
-	double x1,y1,x2,y2;
-
-	/* input parameters: */
-	double thickness_list_element[6];
-	double thickness_list[2];
-	double bed_list_element[6];
-	double bed_list[2];
-	
-	int    grid1,grid2;
-	double normal[2];
-	double length;
-	int    element_type;
-
-	/*Objects: */
-	double  pe_g[numdofs]={0.0};
-	Matpar*  matpar=NULL;
-	Node**   element_nodes=NULL;
-	Node**   nodes=NULL;
-	Element* element=NULL;
-
-	/*Recover hook objects: */
-	matpar=(Matpar*)hmatpar.delivers();
-	element=(Element*)helement.delivers();
-	nodes=(Node**)hnodes.deliverp();
-
-	element_type=element->Enum();
-
-	//check that the element is onbed (collapsed formulation) otherwise:pe=0
-	if(element_type==PentaEnum){
-		if  (!element->GetOnBed()){
-			return;
-		}
-	}
-		
-	/*Identify which grids are comprised in the segment. */
-	if(element_type==TriaEnum)element_nodes=(Node**)xmalloc(3*sizeof(Node*));
-	if(element_type==PentaEnum)element_nodes=(Node**)xmalloc(6*sizeof(Node*));
-	element->GetNodes((void**)element_nodes);
-
-	/*go through first 3 grids (all grids for tria, bed grids for penta) and identify 1st and 2nd grid: */
-	for(i=0;i<3;i++){
-		if (nodes[0]==element_nodes[i])grid1=i;
-		if (nodes[1]==element_nodes[i])grid2=i;
-	}
-	
-	/* Get dof list and node coordinates: */
-	GetDofList(&doflist[0],&numberofdofspernode);
-	GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
-	
-	/*Now build thickness_list_element and bed_list_element: */
-	element->GetThicknessList(&thickness_list_element[0]);
-	element->GetBedList(&bed_list_element[0]);
-		
-	/*Build thickness_list and bed_list: */
-	thickness_list[0]=thickness_list_element[grid1];
-	thickness_list[1]=thickness_list_element[grid2];
-	bed_list[0]=bed_list_element[grid1];
-	bed_list[1]=bed_list_element[grid2];
-
-	//Recover grid coordinates
-	x1=xyz_list[0][0];
-	y1=xyz_list[0][1];
-	x2=xyz_list[1][0];
-	y2=xyz_list[1][1];
-
-	//Compute length and normal of segment
-	normal[0]=cos(atan2(x1-x2,y2-y1));
-	normal[1]=sin(atan2(x1-x2,y2-y1));
-	length=sqrt(pow(x2-x1,2)+pow(y2-y1,2));
-
-	//Compute load contribution for this segment:
-	SegmentPressureLoad(pe_g,matpar->GetRhoWater(),matpar->GetRhoIce(),matpar->GetG(),thickness_list,bed_list,normal,length);
-		
-	/*Plug pe_g into vector: */
-	VecSetValues(pg,numdofs,doflist,pe_g,ADD_VALUES);
-
-	/*Free ressources:*/
-	xfree((void**)&element_nodes);
-
-}
-/*}}}*/
-/*FUNCTION Icefront CreatePVectorDiagnosticHorizQuad {{{1*/
-void Icefront::CreatePVectorDiagnosticHorizQuad( Vec pg,int analysis_type,int sub_analysis_type){
-
-	int i,j;
-
-	const int numgrids=4;
-	const int NDOF2=2;
-	const int numdofs=numgrids*NDOF2;
-	int   numberofdofspernode;
-	int   doflist[numdofs];
-
-	double xyz_list[numgrids][3];
-	double xyz_list_quad[numgrids+1][3]; //center node
-
-	double thickness_list[6]; //from penta element
-	double thickness_list_quad[6]; //selection of 4 thickness from penta elements
-
-	double bed_list[6]; //from penta element
-	double bed_list_quad[6]; //selection of 4 beds from penta elements
-
-	/*Objects: */
-	double  pe_g[numdofs]={0.0};
-	Matpar* matpar=NULL;
-	Node**  element_nodes=NULL;
-	Node**   nodes=NULL;
-	Element* element=NULL;
-	int    element_type;
-		
-	/*quad grids: */
-	int grid1,grid2,grid3,grid4;
-
-	/*normals: */
-	double normal1[3];
-	double normal2[3];
-	double normal3[3];
-	double normal4[3];
-	double normal_norm;
-	double v15[3];
-	double v25[3];
-	double v35[3];
-	double v45[3];
-
-	/*Recover hook objects: */
-	matpar=(Matpar*)hmatpar.delivers();
-	element=(Element*)helement.delivers();
-	nodes=(Node**)hnodes.deliverp();
-
-	element_type=element->Enum();
-
-	/*check icefront is associated to a pentaelem: */
-	if(element_type!=PentaEnum){
-		ISSMERROR(" quad icefront is associated to a TriaElem!");
-	}
-
-	/* Get dof list and node coordinates: */
-	GetDofList(&doflist[0],&numberofdofspernode);
-	GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
-	
-	//Identify which grids are comprised in the quad: 
-	if(element_type==PentaEnum)element_nodes=(Node**)xmalloc(6*sizeof(Node*));
-	element->GetNodes((void**)element_nodes);
-
-	grid1=-1; grid2=-1; grid3=-1; grid4=-1;
-	for(i=0;i<6;i++){
-		if (nodes[0]==element_nodes[i])grid1=i;
-		if (nodes[1]==element_nodes[i])grid2=i;
-		if (nodes[2]==element_nodes[i])grid3=i;
-		if (nodes[3]==element_nodes[i])grid4=i;
-	}
-	
-	if((grid1==-1) || (grid2==-1)|| (grid3==-1)||(grid4==-1)){
-		ISSMERROR("could not find element grids corresponding to quad icefront!");
-	}
-
-	/*Build new xyz, bed and thickness lists for grids 1 to 4: */
-	for(i=0;i<4;i++){
-		for(j=0;j<3;j++){
-			xyz_list_quad[i][j]=xyz_list[i][j];
-		}
-	}
-
-	element->GetThicknessList(&thickness_list[0]);
-	element->GetBedList(&bed_list[0]);
-
-	thickness_list_quad[0]=thickness_list[grid1];
-	thickness_list_quad[1]=thickness_list[grid2];
-	thickness_list_quad[2]=thickness_list[grid3];
-	thickness_list_quad[3]=thickness_list[grid4];
-
-	bed_list_quad[0]=bed_list[grid1];
-	bed_list_quad[1]=bed_list[grid2];
-	bed_list_quad[2]=bed_list[grid3];
-	bed_list_quad[3]=bed_list[grid4];
-
-	//Create a new grid in the midle of the quad and add it at the end of the list
-	xyz_list_quad[4][0] = (xyz_list_quad[0][0]+xyz_list_quad[1][0]+xyz_list_quad[2][0]+xyz_list_quad[3][0])/4.0;
-	xyz_list_quad[4][1] = (xyz_list_quad[0][1]+xyz_list_quad[1][1]+xyz_list_quad[2][1]+xyz_list_quad[3][1])/4.0;
-	xyz_list_quad[4][2] = (xyz_list_quad[0][2]+xyz_list_quad[1][2]+xyz_list_quad[2][2]+xyz_list_quad[3][2])/4.0;
-
-	//Compute four normals (the quad is divided into four triangles)
-	v15[0]=xyz_list_quad[0][0]-xyz_list_quad[4][0];
-	v15[1]=xyz_list_quad[0][1]-xyz_list_quad[4][1];
-	v15[2]=xyz_list_quad[0][2]-xyz_list_quad[4][2];
-	
-	v25[0]=xyz_list_quad[1][0]-xyz_list_quad[4][0];
-	v25[1]=xyz_list_quad[1][1]-xyz_list_quad[4][1];
-	v25[2]=xyz_list_quad[1][2]-xyz_list_quad[4][2];
-	
-	v35[0]=xyz_list_quad[2][0]-xyz_list_quad[4][0];
-	v35[1]=xyz_list_quad[2][1]-xyz_list_quad[4][1];
-	v35[2]=xyz_list_quad[2][2]-xyz_list_quad[4][2];
-	
-	v45[0]=xyz_list_quad[3][0]-xyz_list_quad[4][0];
-	v45[1]=xyz_list_quad[3][1]-xyz_list_quad[4][1];
-	v45[2]=xyz_list_quad[3][2]-xyz_list_quad[4][2];
-
-	cross(normal1,v15,v25); 
-	cross(normal2,v25,v35);
-	cross(normal3,v35,v45);
-	cross(normal4,v45,v15);
-
-	normal_norm=norm(normal1);normal1[0]=normal1[0]/normal_norm;normal1[1]=normal1[1]/normal_norm;normal1[2]=normal1[2]/normal_norm;
-	normal_norm=norm(normal2);normal2[0]=normal2[0]/normal_norm;normal2[1]=normal2[1]/normal_norm;normal2[2]=normal2[2]/normal_norm;
-	normal_norm=norm(normal3);normal3[0]=normal3[0]/normal_norm;normal3[1]=normal3[1]/normal_norm;normal3[2]=normal3[2]/normal_norm;
-	normal_norm=norm(normal4);normal4[0]=normal4[0]/normal_norm;normal4[1]=normal4[1]/normal_norm;normal4[2]=normal4[2]/normal_norm;
-
-
-	//Compute load contribution for this quad:
-	QuadPressureLoad(pe_g,matpar->GetRhoWater(),matpar->GetRhoIce(),matpar->GetG(),thickness_list_quad,bed_list_quad,normal1,normal2,normal3,normal4,&xyz_list_quad[0][0]);
-
-	/*Plug pe_g into vector: */
-	VecSetValues(pg,numdofs,doflist,pe_g,ADD_VALUES);
-
-	/*Free ressources:*/
-	xfree((void**)&element_nodes);
-
-}
-/*}}}*/
-/*FUNCTION Icefront CreatePVectorDiagnosticStokes {{{1*/
-void Icefront::CreatePVectorDiagnosticStokes( Vec pg,int analysis_type,int sub_analysis_type){
-
-	int i,j;
-
-	const int numgrids=4;
-	const int NDOF4=4;
-	const int numdofs=numgrids*NDOF4;
-	int   numberofdofspernode;
-	int   doflist[numdofs];
-
-	double xyz_list[numgrids][3];
-	double xyz_list_quad[numgrids+1][3]; //center node
-
-	double thickness_list[6]; //from penta element
-	double thickness_list_quad[6]; //selection of 4 thickness from penta elements
-
-	double bed_list[6]; //from penta element
-	double bed_list_quad[6]; //selection of 4 beds from penta elements
-
-	/*Objects: */
-	double  pe_g[numdofs]={0.0};
-	Matpar* matpar=NULL;
-	Node**  element_nodes=NULL;
-	Node**   nodes=NULL;
-	Element* element=NULL;
-	int     element_type;
-		
-
-	/*quad grids: */
-	int grid1,grid2,grid3,grid4;
-
-	/*normals: */
-	double normal1[3];
-	double normal2[3];
-	double normal3[3];
-	double normal4[3];
-	double normal_norm;
-	double v15[3];
-	double v25[3];
-	double v35[3];
-	double v45[3];
-
-	/*Recover hook objects: */
-	matpar=(Matpar*)hmatpar.delivers();
-	element=(Element*)helement.delivers();
-	nodes=(Node**)hnodes.deliverp();
-	
-	/*check icefront is associated to a pentaelem: */
-	if(element_type!=PentaEnum){
-		ISSMERROR(" quad icefront is associated to a TriaElem!");
-	}
-
-	/* Get dof list and node coordinates: */
-	GetDofList(&doflist[0],&numberofdofspernode);
-	GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
-	
-	//Identify which grids are comprised in the quad: 
-	if(element_type==PentaEnum)element_nodes=(Node**)xmalloc(6*sizeof(Node*));
-	element->GetNodes((void**)element_nodes);
-
-	grid1=-1; grid2=-1; grid3=-1; grid4=-1;
-	for(i=0;i<6;i++){
-		if (nodes[0]==element_nodes[i])grid1=i;
-		if (nodes[1]==element_nodes[i])grid2=i;
-		if (nodes[2]==element_nodes[i])grid3=i;
-		if (nodes[3]==element_nodes[i])grid4=i;
-	}
-	
-	if((grid1==-1) || (grid2==-1)|| (grid3==-1)||(grid4==-1)){
-		ISSMERROR("could not find element grids corresponding to quad icefront!");
-	}
-
-	/*Build new xyz, bed and thickness lists for grids 1 to 4: */
-	for(i=0;i<4;i++){
-		for(j=0;j<3;j++){
-			xyz_list_quad[i][j]=xyz_list[i][j];
-		}
-	}
-
-	element->GetThicknessList(&thickness_list[0]);
-	element->GetBedList(&bed_list[0]);
-
-	thickness_list_quad[0]=thickness_list[grid1];
-	thickness_list_quad[1]=thickness_list[grid2];
-	thickness_list_quad[2]=thickness_list[grid3];
-	thickness_list_quad[3]=thickness_list[grid4];
-
-	bed_list_quad[0]=bed_list[grid1];
-	bed_list_quad[1]=bed_list[grid2];
-	bed_list_quad[2]=bed_list[grid3];
-	bed_list_quad[3]=bed_list[grid4];
-
-	//Create a new grid in the midle of the quad and add it at the end of the list
-	xyz_list_quad[4][0] = (xyz_list_quad[0][0]+xyz_list_quad[1][0]+xyz_list_quad[2][0]+xyz_list_quad[3][0])/4.0;
-	xyz_list_quad[4][1] = (xyz_list_quad[0][1]+xyz_list_quad[1][1]+xyz_list_quad[2][1]+xyz_list_quad[3][1])/4.0;
-	xyz_list_quad[4][2] = (xyz_list_quad[0][2]+xyz_list_quad[1][2]+xyz_list_quad[2][2]+xyz_list_quad[3][2])/4.0;
-
-	//Compute four normals (the quad is divided into four triangles)
-	v15[0]=xyz_list_quad[0][0]-xyz_list_quad[4][0];
-	v15[1]=xyz_list_quad[0][1]-xyz_list_quad[4][1];
-	v15[2]=xyz_list_quad[0][2]-xyz_list_quad[4][2];
-	
-	v25[0]=xyz_list_quad[1][0]-xyz_list_quad[4][0];
-	v25[1]=xyz_list_quad[1][1]-xyz_list_quad[4][1];
-	v25[2]=xyz_list_quad[1][2]-xyz_list_quad[4][2];
-	
-	v35[0]=xyz_list_quad[2][0]-xyz_list_quad[4][0];
-	v35[1]=xyz_list_quad[2][1]-xyz_list_quad[4][1];
-	v35[2]=xyz_list_quad[2][2]-xyz_list_quad[4][2];
-	
-	v45[0]=xyz_list_quad[3][0]-xyz_list_quad[4][0];
-	v45[1]=xyz_list_quad[3][1]-xyz_list_quad[4][1];
-	v45[2]=xyz_list_quad[3][2]-xyz_list_quad[4][2];
-
-	cross(normal1,v15,v25); 
-	cross(normal2,v25,v35);
-	cross(normal3,v35,v45);
-	cross(normal4,v45,v15);
-
-	normal_norm=norm(normal1);normal1[0]=normal1[0]/normal_norm;normal1[1]=normal1[1]/normal_norm;normal1[2]=normal1[2]/normal_norm;
-	normal_norm=norm(normal2);normal2[0]=normal2[0]/normal_norm;normal2[1]=normal2[1]/normal_norm;normal2[2]=normal2[2]/normal_norm;
-	normal_norm=norm(normal3);normal3[0]=normal3[0]/normal_norm;normal3[1]=normal3[1]/normal_norm;normal3[2]=normal3[2]/normal_norm;
-	normal_norm=norm(normal4);normal4[0]=normal4[0]/normal_norm;normal4[1]=normal4[1]/normal_norm;normal4[2]=normal4[2]/normal_norm;
-
-
-	//Compute load contribution for this quad:
-	QuadPressureLoadStokes(pe_g,matpar->GetRhoWater(),matpar->GetRhoIce(),matpar->GetG(),thickness_list_quad,bed_list_quad,normal1,normal2,normal3,normal4,&xyz_list_quad[0][0]);
-
-	/*Plug pe_g into vector: */
-	VecSetValues(pg,numdofs,doflist,pe_g,ADD_VALUES);
-
-	/*Free ressources:*/
-	xfree((void**)&element_nodes);
-
-}
-/*}}}*/
-/*FUNCTION Icefront DistributeNumDofs {{{1*/
-void  Icefront::DistributeNumDofs(int* numdofspernode,int analysis_type,int sub_analysis_type){return;}
-		
-/*}}}*/
-/*FUNCTION Icefront GetDofList{{{1*/
-
-void  Icefront::GetDofList(int* doflist,int* pnumberofdofspernode){
-
-	int i,j;
-	int doflist_per_node[MAXDOFSPERNODE];
-	int numberofdofspernode;
-	int type;
-
-	Node**   nodes=NULL;
-	nodes=(Node**)hnodes.deliverp();
-	inputs->GetParameterValue(&type,TypeEnum);
-	
-	if(type==SegmentIcefrontEnum){
-		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];
-			}
-		}
-	}
-	else{
-		for(i=0;i<4;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;
-
-}
-/*}}}*/
-/*FUNCTION Icefront PenaltyCreateKMatrix {{{1*/
-void  Icefront::PenaltyCreateKMatrix(Mat Kgg,double kmax,int analysis_type,int sub_analysis_type){
-	/*do nothing: */
-}
-/*}}}*/
-/*FUNCTION Icefront PenaltyCreatePVector{{{1*/
-void  Icefront::PenaltyCreatePVector(Vec pg,double kmax,int analysis_type,int sub_analysis_type){
-	/*do nothing: */
-}
-/*}}}*/
-/*FUNCTION Icefront QuadPressureLoad {{{1*/
-void Icefront::QuadPressureLoad(double* pe_g,double rho_water,double rho_ice,double gravity, double* thickness_list, double* bed_list, 
-		                              double* normal1,double* normal2,double* normal3,double* normal4,double* xyz_list){
-	
-	
-	//The quad is divided into four triangles tria1 tria2 tria3 and tria4 as follows
-	//
-	//   grid 4 +-----------------+ grid 3
-	//          |\2            1 /|
-	//          |1\    tria3    /2|
-	//          |  \           /  |
-	//          |   \         /   |
-	//          |    \       /    |
-	//          |     \     /     |
-	//          |      \ 3 /      |
-	//          |tria4  \ / 3     |
-	//          |      3 \grid5   |
-	//          |       / \       | 
-	//          |      / 3 \ tria2|
-	//          |     /     \     |
-	//          |    /       \    |
-	//          |   /         \   |
-	//          |  /   tria1   \  |
-	//          |2/1           2\1|
-	//   grid1  +-----------------+ grid 2
-	//
-	//
-
-	int      i,j;
-
-	double nx[4];
-	double ny[4];
-
-	/* gaussian points: */
-	int     num_gauss,ig;
-	double* first_gauss_area_coord  =  NULL;
-	double* second_gauss_area_coord =  NULL;
-	double* third_gauss_area_coord  =  NULL;
-	double* gauss_weights           =  NULL;
-	double  gauss_weight;
-	double  gauss_coord[3];
-
-	double  surface_list[5];
-	double  x[5];
-	double  y[5];
-	double  z[5];
-	double l12,l14,l15,l23,l25,l34,l35,l45;
-	double cos_theta_triangle1,cos_theta_triangle2,cos_theta_triangle3,cos_theta_triangle4;
-
-	double xyz_tria[12][2];
-	double l1l2l3_tria[3];
-	double r_tria,s_tria;
-	double r_quad[4];
-	double s_quad[4];
-	double l1l4_tria[4][4];
-
-	double J[4];
-	double z_g[4];
-	double ice_pressure_tria[4];
-	double air_pressure_tria;
-	double water_level_above_g_tria;
-	double water_pressure_tria;
-	double pressure_tria[4];
-	int    fill;
-
-
-	/*To use tria functionalities: */
-	Tria* tria=NULL;
-	
-	/*Recover inputs: */
-	inputs->GetParameterValue(&fill,FillEnum);
-
-	/*Initialize fake tria: */
-	tria=new Tria();
-
-	//Build the four normal vectors 
-	nx[0]=normal1[0]; nx[1]=normal2[0]; nx[2]=normal3[0]; nx[3]=normal4[0];
-	ny[0]=normal1[1]; ny[1]=normal2[1]; ny[2]=normal3[1]; ny[3]=normal4[1];
-
-	/* Get gaussian points and weights (make this a statically initialized list of points? fstd): */
-	GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2);
-	
-	//Recover the surface of the four nodes
-	for(i=0;i<4;i++){
-		surface_list[i]=thickness_list[i]+bed_list[i];
-	}
-	//Add surface sor the fifth point (average of the surfaces)
-	surface_list[4]=(surface_list[0]+surface_list[1]+surface_list[2]+surface_list[3])/4.0;
-
-	//Recover grid coordinates
-	for(i=0;i<5;i++){
-		x[i]=*(xyz_list+3*i+0);
-		y[i]=*(xyz_list+3*i+1);
-		z[i]=*(xyz_list+3*i+2);
-	}
-	
-	//Build triangles in a 2D plan before using reference elements
-	l12=pow((x[1]-x[0]),2)+pow((y[1]-y[0]),2)+pow((z[1]-z[0]),2);
-	l14=pow((x[3]-x[0]),2)+pow((y[3]-y[0]),2)+pow((z[3]-z[0]),2);
-	l15=pow((x[4]-x[0]),2)+pow((y[4]-y[0]),2)+pow((z[4]-z[0]),2);
-	l23=pow((x[2]-x[1]),2)+pow((y[2]-y[1]),2)+pow((z[2]-z[1]),2);
-	l25=pow((x[4]-x[1]),2)+pow((y[4]-y[1]),2)+pow((z[4]-z[1]),2);
-	l34=pow((x[3]-x[2]),2)+pow((y[3]-y[2]),2)+pow((z[3]-z[2]),2);
-	l35=pow((x[4]-x[2]),2)+pow((y[4]-y[2]),2)+pow((z[4]-z[2]),2);
-	l45=pow((x[4]-x[3]),2)+pow((y[4]-y[3]),2)+pow((z[4]-z[3]),2);
-
-	cos_theta_triangle1=(l15+l12-l25)/(2*sqrt(l12*l15));
-	cos_theta_triangle2=(l25+l23-l35)/(2*sqrt(l23*l25));
-	cos_theta_triangle3=(l35+l34-l45)/(2*sqrt(l34*l35));
-	cos_theta_triangle4=(l45+l14-l15)/(2*sqrt(l14*l45));
-
-	//First triangle : nodes 1, 2 and 5
-	xyz_tria[0][0]=0;
-	xyz_tria[0][1]=0;
-	xyz_tria[1][0]=sqrt(l12);
-	xyz_tria[1][1]=0;
-	xyz_tria[2][0]=cos_theta_triangle1*sqrt(l15);
-	xyz_tria[2][1]=sqrt(1-pow(cos_theta_triangle1,2))*sqrt(l15);
-
-	//Second triangle : nodes 2, 3 and 5
-	xyz_tria[3][0]=0;
-	xyz_tria[3][1]=0;
-	xyz_tria[4][0]=sqrt(l23);
-	xyz_tria[4][1]=0;
-	xyz_tria[5][0]=cos_theta_triangle2*sqrt(l25);
-	xyz_tria[5][1]=sqrt(1-pow(cos_theta_triangle2,2))*sqrt(l25);
-	
-	//Third triangle : nodes 3, 4 and 5
-	xyz_tria[6][0]=0;
-	xyz_tria[6][1]=0;
-	xyz_tria[7][0]=sqrt(l34);
-	xyz_tria[7][1]=0;
-	xyz_tria[8][0]=cos_theta_triangle3*sqrt(l35);
-	xyz_tria[8][1]=sqrt(1-pow(cos_theta_triangle3,2))*sqrt(l35);
-
-	//Fourth triangle : nodes 4, 1 and 5
-	xyz_tria[9][0]=0;
-	xyz_tria[9][1]=0;
-	xyz_tria[10][0]=sqrt(l14);
-	xyz_tria[10][1]=0;
-	xyz_tria[11][0]=cos_theta_triangle4*sqrt(l45);
-	xyz_tria[11][1]=sqrt(1-pow(cos_theta_triangle4,2))*sqrt(l45);
-
-	
-
-	//Start  looping on the triangle's gaussian points: 
-	for(ig=0;ig<num_gauss;ig++){
-
-		/*Pick up the gaussian point: */
-		gauss_weight=*(gauss_weights+ig);
-		gauss_coord[0]=*(first_gauss_area_coord+ig);
-		gauss_coord[1]=*(second_gauss_area_coord+ig);
-		gauss_coord[2]=*(third_gauss_area_coord+ig);
-        
-		tria->GetNodalFunctions(l1l2l3_tria,gauss_coord);
-
-		//Get the coordinates of gauss point for each triangle in penta/quad
-		r_tria=gauss_coord[1]-gauss_coord[0];
-		s_tria=-3/sqrt((double)3)*(gauss_coord[0]+gauss_coord[1]-2/3);
-
-		//Coordinates of gauss points in the reference triangle
-		r_quad[0]=r_tria;
-		s_quad[0]=1/sqrt((double)3)*s_tria-2/3;
-		r_quad[1]=-1/sqrt((double)3)*s_tria+2/3;
-		s_quad[1]=r_tria;
-		r_quad[2]=-r_tria;
-		s_quad[2]=-1/sqrt((double)3)*s_tria+2/3;
-		r_quad[3]=1/sqrt((double)3)*s_tria-2/3;
-		s_quad[3]=-r_tria;
-
-		//Get the nodal function of the quad for the gauss points of each triangle
-		for(i=0;i<4;i++){
-			l1l4_tria[i][0]=1.0/4.0*(
-					(r_quad[i]-1.0)*(s_quad[i]-1.0) 
-					); 
-			
-			l1l4_tria[i][1]=1.0/4.0*(
-					 -(r_quad[i]+1.0)*(s_quad[i]-1.0)
-					); 
-
-			l1l4_tria[i][2]=1.0/4.0*(
-					(r_quad[i]+1.0)*(s_quad[i]+1.0) 
-					);
-			
-			l1l4_tria[i][3]=1.0/4.0*(
-					 -(r_quad[i]-1.0)*(s_quad[i]+1.0)
-					);
-
-		} //for(i=0;i<4;i++)
-		
-		
-		//Compute jacobian of each triangle
-		for (i=0;i<4;i++){
-			double complete_list[3][3]; //a third coordinate is needed for the jacobian determinant calculation, here it is zero
-			for(j=0;j<3;j++){
-				complete_list[j][0]=xyz_tria[3*i+j][0];
-				complete_list[j][1]=xyz_tria[3*i+j][1];
-				complete_list[j][2]=0;
-			}
-			tria->GetJacobianDeterminant2d(&J[i],&complete_list[0][0],l1l2l3_tria);
-		}
-
-		//Calculation of the z coordinate for the gaussian point ig for each triangle
-		z_g[0]=z[0]*l1l2l3_tria[0]+z[1]*l1l2l3_tria[1]+z[4]*l1l2l3_tria[2];
-		z_g[1]=z[1]*l1l2l3_tria[0]+z[2]*l1l2l3_tria[1]+z[4]*l1l2l3_tria[2];
-		z_g[2]=z[2]*l1l2l3_tria[0]+z[3]*l1l2l3_tria[1]+z[4]*l1l2l3_tria[2];
-		z_g[3]=z[3]*l1l2l3_tria[0]+z[0]*l1l2l3_tria[1]+z[4]*l1l2l3_tria[2];
-		
-		//Loop on the triangles
-		for(i=0;i<4;i++){
-
-			//Loop on the grids of the quad
-			//Calculate the ice pressure
-			for(j=0;j<4;j++){
-				ice_pressure_tria[j]=gravity*rho_ice*(surface_list[j]-z_g[i]);
-			}
-			air_pressure_tria=0;
-
-			//Now deal with water pressure: 
-			if(fill==WaterEnum){ //icefront ends in water
-				water_level_above_g_tria=min(0,z_g[i]);//0 if the gaussian point is above water level
-				water_pressure_tria=rho_water*gravity*water_level_above_g_tria;
-			}
-			else if(fill==AirEnum){
-				water_pressure_tria=0;
-			}
-			else{
-				ISSMERROR("QuadPressureLoad error message: unknow fill type for icefront boundary condition");
-			}
-
-			//Add pressure from triangle i
-			//Loop on the grids of the quad
-			for(j=0;j<4;j++){
-				pressure_tria[j] = ice_pressure_tria[j] + water_pressure_tria + air_pressure_tria;
-			}
-
-
-			pe_g[0]+= J[i]*gauss_weight* pressure_tria[0]*l1l4_tria[i][0]*nx[i];
-			pe_g[1]+= J[i]*gauss_weight* pressure_tria[0]*l1l4_tria[i][0]*ny[i];
-			pe_g[2]+= J[i]*gauss_weight* pressure_tria[1]*l1l4_tria[i][1]*nx[i];
-			pe_g[3]+= J[i]*gauss_weight* pressure_tria[1]*l1l4_tria[i][1]*ny[i];
-			pe_g[4]+= J[i]*gauss_weight* pressure_tria[2]*l1l4_tria[i][2]*nx[i];
-			pe_g[5]+= J[i]*gauss_weight* pressure_tria[2]*l1l4_tria[i][2]*ny[i];
-			pe_g[6]+= J[i]*gauss_weight* pressure_tria[3]*l1l4_tria[i][3]*nx[i];
-			pe_g[7]+= J[i]*gauss_weight* pressure_tria[3]*l1l4_tria[i][3]*ny[i];
-
-			
-
-		} //for(i=0;i<4;i++)
-	} //for(ig=0;ig<num_gauss;ig++)
-	
-	/*Free ressources: */
-	xfree((void**)&first_gauss_area_coord);
-	xfree((void**)&second_gauss_area_coord);
-	xfree((void**)&third_gauss_area_coord);
-	xfree((void**)&gauss_weights);
-
-	/*Delete fake tria: */
-	delete tria;
-}
-/*}}}*/
-/*FUNCTION Icefront QuadPressureLoadStokes {{{1*/
-void Icefront::QuadPressureLoadStokes(double* pe_g,double rho_water,double rho_ice,double gravity, double* thickness_list, double* bed_list, 
-		                              double* normal1,double* normal2,double* normal3,double* normal4,double* xyz_list){
-	
-	
-	//The quad is divided into four triangles tria1 tria2 tria3 and tria4 as follows
-	//
-	//   grid 4 +-----------------+ grid 3
-	//          |\2            1 /|
-	//          |1\    tria3    /2|
-	//          |  \           /  |
-	//          |   \         /   |
-	//          |    \       /    |
-	//          |     \     /     |
-	//          |      \ 3 /      |
-	//          |tria4  \ / 3     |
-	//          |      3 \grid5   |
-	//          |       / \       | 
-	//          |      / 3 \ tria2|
-	//          |     /     \     |
-	//          |    /       \    |
-	//          |   /         \   |
-	//          |  /   tria1   \  |
-	//          |2/1           2\1|
-	//   grid1  +-----------------+ grid 2
-	//
-	//
-
-	int      i,j;
-
-	double nx[4];
-	double ny[4];
-	double nz[4];
-
-	/* gaussian points: */
-	int     num_gauss,ig;
-	double* first_gauss_area_coord  =  NULL;
-	double* second_gauss_area_coord =  NULL;
-	double* third_gauss_area_coord  =  NULL;
-	double* gauss_weights           =  NULL;
-	double  gauss_weight;
-	double  gauss_coord[3];
-
-	double  surface_list[5];
-	double  x[5];
-	double  y[5];
-	double  z[5];
-	double l12,l14,l15,l23,l25,l34,l35,l45;
-	double cos_theta_triangle1,cos_theta_triangle2,cos_theta_triangle3,cos_theta_triangle4;
-
-	double xyz_tria[12][2];
-	double l1l2l3_tria[3];
-	double r_tria,s_tria;
-	double r_quad[4];
-	double s_quad[4];
-	double l1l4_tria[4][4];
-
-	double J[4];
-	double z_g[4];
-	double air_pressure_tria;
-	double water_level_above_g_tria;
-	double water_pressure_tria;
-	double pressure_tria;
-	int    fill;
-
-	/*To use tria functionalities: */
-	Tria* tria=NULL;
-
-	/*Recover inputs: */
-	inputs->GetParameterValue(&fill,FillEnum);
-
-	/*Initialize fake tria: */
-	tria=new Tria();
-
-	//Build the four normal vectors 
-	nx[0]=normal1[0]; nx[1]=normal2[0]; nx[2]=normal3[0]; nx[3]=normal4[0];
-	ny[0]=normal1[1]; ny[1]=normal2[1]; ny[2]=normal3[1]; ny[3]=normal4[1];
-	nz[0]=normal1[2]; nz[1]=normal2[2]; nz[2]=normal3[2]; nz[3]=normal4[2];
-
-	/* Get gaussian points and weights (make this a statically initialized list of points? fstd): */
-	GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2);
-	
-	//Recover the surface of the four nodes
-	for(i=0;i<4;i++){
-		surface_list[i]=thickness_list[i]+bed_list[i];
-	}
-	//Add surface sor the fifth point (average of the surfaces)
-	surface_list[4]=(surface_list[0]+surface_list[1]+surface_list[2]+surface_list[3])/4.0;
-
-	//Recover grid coordinates
-	for(i=0;i<5;i++){
-		x[i]=*(xyz_list+3*i+0);
-		y[i]=*(xyz_list+3*i+1);
-		z[i]=*(xyz_list+3*i+2);
-	}
-	
-	//Build triangles in a 2D plan before using reference elements
-	l12=pow((x[1]-x[0]),2)+pow((y[1]-y[0]),2)+pow((z[1]-z[0]),2);
-	l14=pow((x[3]-x[0]),2)+pow((y[3]-y[0]),2)+pow((z[3]-z[0]),2);
-	l15=pow((x[4]-x[0]),2)+pow((y[4]-y[0]),2)+pow((z[4]-z[0]),2);
-	l23=pow((x[2]-x[1]),2)+pow((y[2]-y[1]),2)+pow((z[2]-z[1]),2);
-	l25=pow((x[4]-x[1]),2)+pow((y[4]-y[1]),2)+pow((z[4]-z[1]),2);
-	l34=pow((x[3]-x[2]),2)+pow((y[3]-y[2]),2)+pow((z[3]-z[2]),2);
-	l35=pow((x[4]-x[2]),2)+pow((y[4]-y[2]),2)+pow((z[4]-z[2]),2);
-	l45=pow((x[4]-x[3]),2)+pow((y[4]-y[3]),2)+pow((z[4]-z[3]),2);
-
-	cos_theta_triangle1=(l15+l12-l25)/(2*sqrt(l12*l15));
-	cos_theta_triangle2=(l25+l23-l35)/(2*sqrt(l23*l25));
-	cos_theta_triangle3=(l35+l34-l45)/(2*sqrt(l34*l35));
-	cos_theta_triangle4=(l45+l14-l15)/(2*sqrt(l14*l45));
-
-	//First triangle : nodes 1, 2 and 5
-	xyz_tria[0][0]=0;
-	xyz_tria[0][1]=0;
-	xyz_tria[1][0]=sqrt(l12);
-	xyz_tria[1][1]=0;
-	xyz_tria[2][0]=cos_theta_triangle1*sqrt(l15);
-	xyz_tria[2][1]=sqrt(1-pow(cos_theta_triangle1,2))*sqrt(l15);
-
-	//Second triangle : nodes 2, 3 and 5
-	xyz_tria[3][0]=0;
-	xyz_tria[3][1]=0;
-	xyz_tria[4][0]=sqrt(l23);
-	xyz_tria[4][1]=0;
-	xyz_tria[5][0]=cos_theta_triangle2*sqrt(l25);
-	xyz_tria[5][1]=sqrt(1-pow(cos_theta_triangle2,2))*sqrt(l25);
-	
-	//Third triangle : nodes 3, 4 and 5
-	xyz_tria[6][0]=0;
-	xyz_tria[6][1]=0;
-	xyz_tria[7][0]=sqrt(l34);
-	xyz_tria[7][1]=0;
-	xyz_tria[8][0]=cos_theta_triangle3*sqrt(l35);
-	xyz_tria[8][1]=sqrt(1-pow(cos_theta_triangle3,2))*sqrt(l35);
-
-	//Fourth triangle : nodes 4, 1 and 5
-	xyz_tria[9][0]=0;
-	xyz_tria[9][1]=0;
-	xyz_tria[10][0]=sqrt(l14);
-	xyz_tria[10][1]=0;
-	xyz_tria[11][0]=cos_theta_triangle4*sqrt(l45);
-	xyz_tria[11][1]=sqrt(1-pow(cos_theta_triangle4,2))*sqrt(l45);
-
-	
-
-	//Start  looping on the triangle's gaussian points: 
-	for(ig=0;ig<num_gauss;ig++){
-
-		/*Pick up the gaussian point: */
-		gauss_weight=*(gauss_weights+ig);
-		gauss_coord[0]=*(first_gauss_area_coord+ig);
-		gauss_coord[1]=*(second_gauss_area_coord+ig);
-		gauss_coord[2]=*(third_gauss_area_coord+ig);
-        
-		tria->GetNodalFunctions(l1l2l3_tria,gauss_coord);
-
-		//Get the coordinates of gauss point for each triangle in penta/quad
-		r_tria=gauss_coord[1]-gauss_coord[0];
-		s_tria=-3/sqrt((double)3)*(gauss_coord[0]+gauss_coord[1]-2/3);
-
-		//Coordinates of gauss points in the reference triangle
-		r_quad[0]=r_tria;
-		s_quad[0]=1/sqrt((double)3)*s_tria-2/3;
-		r_quad[1]=-1/sqrt((double)3)*s_tria+2/3;
-		s_quad[1]=r_tria;
-		r_quad[2]=-r_tria;
-		s_quad[2]=-1/sqrt((double)3)*s_tria+2/3;
-		r_quad[3]=1/sqrt((double)3)*s_tria-2/3;
-		s_quad[3]=-r_tria;
-
-		//Get the nodal function of the quad for the gauss points of each triangle
-		for(i=0;i<4;i++){
-			l1l4_tria[i][0]=1.0/4.0*(
-					(r_quad[i]-1.0)*(s_quad[i]-1.0) 
-					); 
-			
-			l1l4_tria[i][1]=1.0/4.0*(
-					 -(r_quad[i]+1.0)*(s_quad[i]-1.0)
-					); 
-
-			l1l4_tria[i][2]=1.0/4.0*(
-					(r_quad[i]+1.0)*(s_quad[i]+1.0) 
-					);
-			
-			l1l4_tria[i][3]=1.0/4.0*(
-					 -(r_quad[i]-1.0)*(s_quad[i]+1.0)
-					);
-
-		} //for(i=0;i<4;i++)
-		
-		
-		//Compute jacobian of each triangle
-		for (i=0;i<4;i++){
-			double complete_list[3][3]; //a third coordinate is needed for the jacobian determinant calculation, here it is zero
-			for(j=0;j<3;j++){
-				complete_list[j][0]=xyz_tria[3*i+j][0];
-				complete_list[j][1]=xyz_tria[3*i+j][1];
-				complete_list[j][2]=0;
-			}
-			tria->GetJacobianDeterminant2d(&J[i],&complete_list[0][0],l1l2l3_tria);
-		}
-
-		//Calculation of the z coordinate for the gaussian point ig for each triangle
-		z_g[0]=z[0]*l1l2l3_tria[0]+z[1]*l1l2l3_tria[1]+z[4]*l1l2l3_tria[2];
-		z_g[1]=z[1]*l1l2l3_tria[0]+z[2]*l1l2l3_tria[1]+z[4]*l1l2l3_tria[2];
-		z_g[2]=z[2]*l1l2l3_tria[0]+z[3]*l1l2l3_tria[1]+z[4]*l1l2l3_tria[2];
-		z_g[3]=z[3]*l1l2l3_tria[0]+z[0]*l1l2l3_tria[1]+z[4]*l1l2l3_tria[2];
-		
-		//Loop on the triangles
-		for(i=0;i<4;i++){
-
-			//Loop on the grids of the quad
-			//Calculate the ice pressure
-			air_pressure_tria=0;
-
-			//Now deal with water pressure: 
-			if(fill==WaterEnum){ //icefront ends in water
-				water_level_above_g_tria=min(0,z_g[i]);//0 if the gaussian point is above water level
-				water_pressure_tria=rho_water*gravity*water_level_above_g_tria;
-			}
-			else if(fill==AirEnum){
-				water_pressure_tria=0;
-			}
-			else{
-				ISSMERROR("QuadPressureLoadStokes error message: unknow fill type for icefront boundary condition");
-			}
-
-			//Add pressure 
-			pressure_tria = water_pressure_tria + air_pressure_tria;
-
-			pe_g[0]+= J[i]*gauss_weight* pressure_tria*l1l4_tria[i][0]*nx[i];
-			pe_g[1]+= J[i]*gauss_weight* pressure_tria*l1l4_tria[i][0]*ny[i];
-			pe_g[2]+= J[i]*gauss_weight* pressure_tria*l1l4_tria[i][0]*nz[i];
-			pe_g[3]+= 0;
-			pe_g[4]+= J[i]*gauss_weight* pressure_tria*l1l4_tria[i][1]*nx[i];
-			pe_g[5]+= J[i]*gauss_weight* pressure_tria*l1l4_tria[i][1]*ny[i];
-			pe_g[6]+= J[i]*gauss_weight* pressure_tria*l1l4_tria[i][1]*nz[i];
-			pe_g[7]+= 0;
-			pe_g[8]+= J[i]*gauss_weight* pressure_tria*l1l4_tria[i][2]*nx[i];
-			pe_g[9]+= J[i]*gauss_weight* pressure_tria*l1l4_tria[i][2]*ny[i];
-			pe_g[10]+= J[i]*gauss_weight* pressure_tria*l1l4_tria[i][2]*nz[i];
-			pe_g[11]+= 0;
-			pe_g[12]+= J[i]*gauss_weight* pressure_tria*l1l4_tria[i][3]*nx[i];
-			pe_g[13]+= J[i]*gauss_weight* pressure_tria*l1l4_tria[i][3]*ny[i];
-			pe_g[14]+= J[i]*gauss_weight* pressure_tria*l1l4_tria[i][3]*nz[i];
-			pe_g[15]+= 0;
-
-		} //for(i=0;i<4;i++)
-	} //for(ig=0;ig<num_gauss;ig++)
-	
-	/*Free ressources: */
-	xfree((void**)&first_gauss_area_coord);
-	xfree((void**)&second_gauss_area_coord);
-	xfree((void**)&third_gauss_area_coord);
-	xfree((void**)&gauss_weights);
-
-	/*Delete fake tria: */
-	delete tria;
-}
-/*}}}*/
-/*FUNCTION Icefront SegmentPressureLoad {{{1*/
-
-void Icefront::SegmentPressureLoad(double* pe_g,double rho_water,double rho_ice,double gravity, double* thickness_list, double* bed_list, double* normal,double length){
-
-	double   nx,ny;
-	double   h1,h2,b1,b2;
-	int      num_gauss;
-	double*  segment_gauss_coord=NULL;
-	double*  gauss_weights=NULL;
-	int      ig;
-	double   Jdet;
-	double   thickness,bed;
-	double   ice_pressure,water_pressure,air_pressure;
-	double   surface_under_water,base_under_water;
-	double   pressure;
-	int    fill;
-
-	/*Recover inputs: */
-	inputs->GetParameterValue(&fill,FillEnum);
-
-	nx=normal[0];
-	ny=normal[1];
-
-
-	//Get gaussian points and weights. order 2 since we have a product of 2 nodal functions
-	num_gauss=3;
-	GaussSegment(&segment_gauss_coord, &gauss_weights, num_gauss);
-
-	//recover thickness and bed at two grids
-	h1=thickness_list[0];
-	h2=thickness_list[1];
-	b1=bed_list[0];
-	b2=bed_list[1];
-
-	//compute Jacobian of segment
-	Jdet=1./2.*length;
-
-	for(ig=0;ig<num_gauss;ig++){
-
-		thickness=h1*(1+segment_gauss_coord[ig])/2+h2*(1-segment_gauss_coord[ig])/2;
-		bed=b1*(1+segment_gauss_coord[ig])/2+b2*(1-segment_gauss_coord[ig])/2;
-
-		if (fill==WaterEnum){
-			//icefront ends in water: 
-			ice_pressure=1.0/2.0*gravity*rho_ice*pow(thickness,2);
-			air_pressure=0;
-
-			//Now deal with water pressure
-			surface_under_water=min(0,thickness+bed); // 0 if the top of the glacier is above water level
-			base_under_water=min(0,bed);              // 0 if the bottom of the glacier is above water level
-			water_pressure=1.0/2.0*gravity*rho_water*(pow(surface_under_water,2) - pow(base_under_water,2));
-		}
-		else if (fill==AirEnum){
-			ice_pressure=1.0/2.0*gravity*rho_ice*pow(thickness,2);
-			air_pressure=0;
-			water_pressure=0;
-		}
-		else{
-			ISSMERROR("fill type %i not supported yet",fill);
-		}
-
-		pressure = ice_pressure + water_pressure + air_pressure;
-
-		pe_g[2*0+0]+= pressure*Jdet*gauss_weights[ig]*(1+segment_gauss_coord[ig])/2*nx;
-		pe_g[2*0+1]+= pressure*Jdet*gauss_weights[ig]*(1+segment_gauss_coord[ig])/2*ny;
-		pe_g[2*1+0]+= pressure*Jdet*gauss_weights[ig]*(1-segment_gauss_coord[ig])/2*nx;
-		pe_g[2*1+1]+= pressure*Jdet*gauss_weights[ig]*(1-segment_gauss_coord[ig])/2*ny;
-
-	} //for(ig=0;ig<num_gauss;ig++)
-
-	xfree((void**)&segment_gauss_coord);
-	xfree((void**)&gauss_weights);
-}
-/*}}}*/
Index: sm/trunk/src/c/objects/Icefront.h
===================================================================
--- /issm/trunk/src/c/objects/Icefront.h	(revision 3680)
+++ 	(revision )
@@ -1,79 +1,0 @@
-/*!\file Icefront.h
- * \brief: header file for icefront object
- */
-
-#ifndef _ICEFRONT_H_
-#define _ICEFRONT_H_
-
-/*Headers:*/
-/*{{{1*/
-class Element;
-class Load;
-class Matpar;
-class Element;
-class Node;
-
-#include "./Load.h"
-#include "./Matpar.h"
-#include "./Element.h"
-#include "./Node.h"
-#include "../ModelProcessorx/IoModel.h"
-
-#define MAX_ICEFRONT_GRIDS 4 //max number of grids for a certain load
-#define ICEFRONTSTRING 20 //max string length
-/*}}}*/
-
-class Icefront: public Load {
-
-	public:
-		int id;
-
-		/*hooks: */
-		Hook hnodes;
-		Hook helement;
-		Hook hmatpar;
-
-		/*inputs and parameters: */
-		Inputs* inputs;
-		Parameters* parameters;
-
-		/*constructors: {{{1*/
-		Icefront();
-		Icefront(int icefront_id,int* icefront_node_ids, int icefront_numnodes, int icefront_element_id,int icefront_matpar_id);
-		Icefront(int icefront_id, Hook* icefront_hnodes, Hook* icefront_helement, Hook* icefront_hmatpar, Parameters* parameters, Inputs* icefront_inputs);
-		Icefront(int icefront_id,int i, IoModel* iomodel);
-		~Icefront();
-		/*}}}*/
-		/*object management: {{{1*/
-		void  Configure(DataSet* elementsin,DataSet* loadsin,DataSet* nodesin,DataSet* verticesin,DataSet* materialsin,Parameters* parametersin);
-		Object* copy();
-		void  DeepEcho();
-		void  Demarshall(char** pmarshalled_dataset);
-		void  Echo();
-		int   Enum();
-		int   Id(); 
-		void  Marshall(char** pmarshalled_dataset);
-		int   MarshallSize();
-		int   MyRank();
-
-		/*}}}*/
-		/*numerics: {{{1*/
-		void  DistributeNumDofs(int* numdofspernode,int analysis_type,int sub_analysis_type);
-		void  CreateKMatrix(Mat Kgg,int analysis_type,int sub_analysis_type);
-		void  CreatePVector(Vec pg, int analysis_type,int sub_analysis_type);
-		void  CreatePVectorDiagnosticHoriz( Vec pg,  int analysis_type,int sub_analysis_type);
-		void  CreatePVectorDiagnosticHorizSegment( Vec pg, int analysis_type,int sub_analysis_type);
-		void  CreatePVectorDiagnosticHorizQuad( Vec pg, int analysis_type,int sub_analysis_type);
-		void  CreatePVectorDiagnosticStokes( Vec pg, int analysis_type,int sub_analysis_type);
-		void  GetDofList(int* doflist,int* pnumberofdofs);
-		void  SegmentPressureLoad(double* pe_g,double rho_water,double rho_ice,double gravity, double* thickness_list, double* bed_list, double* normal,double length);
-		void  QuadPressureLoad(double* pe_g,double rho_water,double rho_ice,double gravity, double* thickness_list, double* bed_list, 
-		                              double* normal1,double* normal2,double* normal3,double* normal4,double* xyz_list);
-		void  QuadPressureLoadStokes(double* pe_g,double rho_water,double rho_ice,double gravity, double* thickness_list, double* bed_list, 
-		                              double* normal1,double* normal2,double* normal3,double* normal4,double* xyz_list);
-		void  PenaltyCreateKMatrix(Mat Kgg,double kmax,int analysis_type,int sub_analysis_type);
-		void  PenaltyCreatePVector(Vec pg,double kmax,int analysis_type,int sub_analysis_type);
-		/*}}}*/
-};
-
-#endif  /* _ICEFRONT_H_ */
Index: sm/trunk/src/c/objects/Load.cpp
===================================================================
--- /issm/trunk/src/c/objects/Load.cpp	(revision 3680)
+++ 	(revision )
@@ -1,15 +1,0 @@
-/*!\file: Load.cpp 
- * \brief: implementation of the Enum routine, which is the only non-virtual routine from 
- * the Object derived class Load.
- */ 
-
-
-#include "./Load.h"
-#include "../EnumDefinitions/EnumDefinitions.h"
-
-int Load::Enum(void){
-
-	return LoadEnum;
-}
-		
-
Index: sm/trunk/src/c/objects/Load.h
===================================================================
--- /issm/trunk/src/c/objects/Load.h	(revision 3680)
+++ 	(revision )
@@ -1,41 +1,0 @@
-/*!\file:  Load.h
- * \brief abstract class for Load object
- * This class is a place holder for the Icefront  and the Penpair loads.
- * It is derived from Load, so DataSets can contain them.
- */ 
-
-
-#ifndef _LOAD_H_
-#define _LOAD_H_
-
-/*Headers:*/
-/*{{{1*/
-class Object;
-
-#include "./Object.h"
-#include "../toolkits/toolkits.h"
-#include "../DataSet/DataSet.h"
-#include "../DataSet/Parameters.h"
-/*}}}*/
-
-class Load: public Object{
-
-	public: 
-		virtual       ~Load(){};
-		virtual void  Echo()=0;
-		virtual void  DeepEcho()=0;
-		virtual int   Id()=0;
-		virtual int   MyRank()=0;
-		virtual void  Marshall(char** pmarshalled_dataset)=0;
-		virtual int   MarshallSize()=0;
-		virtual void  Demarshall(char** pmarshalled_dataset)=0;
-		virtual void  Configure(DataSet* elements,DataSet* loads,DataSet* nodes,DataSet* vertices,DataSet* materials,Parameters* parameters)=0;
-		virtual void  CreateKMatrix(Mat Kgg,int analysis_type,int sub_analysis_type)=0;
-		virtual void  CreatePVector(Vec pg, int analysis_type,int sub_analysis_type)=0;
-		virtual void  PenaltyCreateKMatrix(Mat Kgg,double kmax,int analysis_type,int sub_analysis_type)=0;
-		virtual void  PenaltyCreatePVector(Vec pg,double kmax,int analysis_type,int sub_analysis_type)=0;
-
-		int           Enum();
-
-};
-#endif
Index: sm/trunk/src/c/objects/Material.cpp
===================================================================
--- /issm/trunk/src/c/objects/Material.cpp	(revision 3680)
+++ 	(revision )
@@ -1,15 +1,0 @@
-/*!\file: Material.cpp 
- * \brief: implementation of the Enum routine, which is the only non-virtual routine from 
- * the Object derived class Material.
- */ 
-
-
-#include "./Material.h"
-#include "../EnumDefinitions/EnumDefinitions.h"
-
-int Material::Enum(void){
-
-	return MaterialEnum;
-}
-		
-
Index: sm/trunk/src/c/objects/Material.h
===================================================================
--- /issm/trunk/src/c/objects/Material.h	(revision 3680)
+++ 	(revision )
@@ -1,31 +1,0 @@
-/*!\file:  Material.h
- * \brief abstract class for Material object
- */ 
-
-
-#ifndef _MATERIAL_H_
-#define _MATERIAL_H_
-
-/*Headers:*/
-/*{{{1*/
-class Object;
-#include "./Object.h"
-#include "../toolkits/toolkits.h"
-/*}}}*/
-
-class Material: public Object{
-
-	public: 
-		virtual       ~Material(){};
-		virtual void  Echo()=0;
-		virtual void  DeepEcho()=0;
-		virtual int   Id()=0;
-		virtual int   MyRank()=0;
-		virtual void  Marshall(char** pmarshalled_dataset)=0;
-		virtual int   MarshallSize()=0;
-		virtual void  Demarshall(char** pmarshalled_dataset)=0;
-		virtual void  UpdateFromInputs(void* inputs)=0;
-		int           Enum();
-		
-};
-#endif
Index: sm/trunk/src/c/objects/Matice.cpp
===================================================================
--- /issm/trunk/src/c/objects/Matice.cpp	(revision 3680)
+++ 	(revision )
@@ -1,440 +1,0 @@
-/*!\file Matice.c
- * \brief: implementation of the Matice object
- */
-
-#ifdef HAVE_CONFIG_H
-	#include "config.h"
-#else
-#error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
-#endif
-
-#include "stdio.h"
-#include "./Matice.h"
-#include <string.h>
-#include "../EnumDefinitions/EnumDefinitions.h"
-#include "../shared/shared.h"
-#include "../include/macros.h"
-#include "../include/typedefs.h"
-		
-/*Object constructors and destructor*/
-/*FUNCTION Matice::Matice(){{{1*/
-Matice::Matice(){
-	return;
-}
-/*}}}*/
-/*FUNCTION Matice::Matice(int in_mid,double in_B,double in_n){{{1*/
-Matice::Matice(int in_mid,double in_B,double in_n){
-	this->Init(in_mid,in_B,in_n);
-}
-/*}}}*/
-/*FUNCTION Matice::Init {{{1*/
-void Matice::Init(int in_mid,double in_B,double in_n){
-	this->mid=in_mid;
-	this->B=in_B;
-	this->n=in_n;
-}
-/*}}}*/
-/*FUNCTION Matice::Matice(int id, int i, IoModel* iomodel, int num_vertices){{{1*/
-Matice::Matice(int matice_mid,int i, IoModel* iomodel, int num_vertices){
-
-	int j;
-	
-	/*needed for Init routine:*/
-	double matice_B;
-	double matice_n;
-
-	/*intermediary: */
-	double B_avg;
- 
-	/*Compute B on the element if provided*/
-	if (num_vertices==3 || num_vertices==6){
-		if (iomodel->rheology_B){
-			B_avg=0;
-			for(j=0;j<num_vertices;j++){
-				B_avg+=*(iomodel->rheology_B+((int)*(iomodel->elements+num_vertices*i+j)-1));
-			}
-			B_avg=B_avg/num_vertices;
-		}
-	}
-	else if (num_vertices==1 || num_vertices==2){
-		if (iomodel->rheology_B){
-			B_avg=*(iomodel->rheology_B+i);
-		}
-	}
-	else ISSMERROR("num_vertices = %i not supported yet",num_vertices);
-	
-	if (iomodel->rheology_B) matice_B=B_avg;
-	else            matice_B=UNDEF;
-	if (iomodel->rheology_n){
-		if (num_vertices==3 || num_vertices==6){
-			matice_n=(double)*(iomodel->rheology_n+i);
-		}
-		else if (num_vertices==1 || num_vertices==2){
-			/*n is on the elements for now, so just take the first one*/
-			matice_n=(double)*(iomodel->rheology_n);
-		}
-		else ISSMERROR("num_vertices = %i not supported yet",num_vertices);
-	}
-	else            matice_n=UNDEF;
-
-	this->Init(matice_mid,matice_B,matice_n);
-}
-/*}}}*/
-/*FUNCTION Matice::~Matice(){{{1*/
-Matice::~Matice(){
-	return;
-}
-/*}}}*/
-
-/*Object marshall*/
-/*FUNCTION Matice::Marshall {{{1*/
-void  Matice::Marshall(char** pmarshalled_dataset){
-
-	char* marshalled_dataset=NULL;
-	int   enum_type=0;
-
-	/*recover marshalled_dataset: */
-	marshalled_dataset=*pmarshalled_dataset;
-
-	/*get enum type of Matice: */
-	enum_type=MaticeEnum;
-	
-	/*marshall enum: */
-	memcpy(marshalled_dataset,&enum_type,sizeof(enum_type));marshalled_dataset+=sizeof(enum_type);
-	
-	/*marshall Matice data: */
-	memcpy(marshalled_dataset,&mid,sizeof(mid));marshalled_dataset+=sizeof(mid);
-	memcpy(marshalled_dataset,&B,sizeof(B));marshalled_dataset+=sizeof(B);
-	memcpy(marshalled_dataset,&n,sizeof(n));marshalled_dataset+=sizeof(n);
-
-	*pmarshalled_dataset=marshalled_dataset;
-	return;
-}
-/*}}}*/
-/*FUNCTION Matice::MarshallSize{{{1*/
-int   Matice::MarshallSize(){
-
-	return sizeof(mid)+sizeof(B)+sizeof(n)+sizeof(int); //sizeof(int) for enum type
-}
-/*}}}*/
-/*FUNCTION Matice::Demarshall {{{1*/
-void  Matice::Demarshall(char** pmarshalled_dataset){
-
-	char* marshalled_dataset=NULL;
-
-	/*recover marshalled_dataset: */
-	marshalled_dataset=*pmarshalled_dataset;
-
-	/*this time, no need to get enum type, the pointer directly points to the beginning of the 
-	 *object data (thanks to DataSet::Demarshall):*/
-
-	memcpy(&mid,marshalled_dataset,sizeof(mid));marshalled_dataset+=sizeof(mid);
-	memcpy(&B,marshalled_dataset,sizeof(B));marshalled_dataset+=sizeof(B);
-	memcpy(&n,marshalled_dataset,sizeof(n));marshalled_dataset+=sizeof(n);
-
-	/*return: */
-	*pmarshalled_dataset=marshalled_dataset;
-	return;
-}
-/*}}}*/
-
-/*Object functions*/
-/*FUNCTION Matice::copy {{{1*/
-Object* Matice::copy() {
-	return new Matice(*this); 
-}
-/*}}}*/
-/*FUNCTION Matice::DeepEcho {{{1*/
-void Matice::DeepEcho(void){
-
-	printf("Matice:\n");
-	printf("   mid: %i\n",mid);
-	printf("   B: %g\n",B);
-	printf("   n: %g\n",n);
-	return;
-}		
-/*}}}*/
-/*FUNCTION Matice::DistributeNumDofs {{{1*/
-void  Matice::DistributeNumDofs(int* numdofspernode,int analysis_type){return;}
-/*}}}*/
-/*FUNCTION Matice::Echo {{{1*/
-void Matice::Echo(void){
-
-	printf("Matice:\n");
-	printf("   mid: %i\n",mid);
-	printf("   B: %g\n",B);
-	printf("   n: %g\n",n);
-	return;
-}
-/*}}}*/
-/*FUNCTION Matice::Enum {{{1*/
-int Matice::Enum(void){
-
-	return MaticeEnum;
-
-}
-/*}}}*/
-/*FUNCTION Matice::GetB {{{1*/
-double Matice::GetB(){
-	return B;
-}
-/*}}}*/
-/*FUNCTION Matice::Id {{{1*/
-int    Matice::Id(void){ return mid; }
-/*}}}*/
-/*FUNCTION Matice::GetN {{{1*/
-double Matice::GetN(){
-	return n;
-}
-/*}}}*/
-/*FUNCTION Matice::GetViscosity2d {{{1*/
-void  Matice::GetViscosity2d(double* pviscosity, double* epsilon){
-
-
-	/*From a string tensor and a material object, return viscosity, using Glen's flow law.
-	                                  2*B
-	  viscosity= -------------------------------------------------------------------
-	      2[ exx^2+eyy^2+exx*eyy+exy^2+exz^2+eyz^2 ]^[(n-1)/2n]
-	 
-	      where viscosity is the viscotiy, B the flow law parameter , (u,v) the velocity 
-	      vector, and n the flow law exponent.
-	 
-	  If epsilon is NULL, it means this is the first time SystemMatrices is being run, and we 
-	  return 10^14, initial viscosity.
-*/
-
-
-
-	/*output: */
-	double viscosity;
-
-	/*input strain rate: */
-	double exx,eyy,exy;
-
-	/*Intermediary value A and exponent e: */
-	double A,e;
-
-	if (n==1){
-		/*Viscous behaviour! viscosity=B: */
-		viscosity=B;
-	}
-	else{
-		if((epsilon[0]==0) && (epsilon[1]==0) && (epsilon[2]==0)){
-			viscosity=pow((double)10,(double)14);
-		}
-		else{
-			/*Retrive strain rate components: */
-			exx=*(epsilon+0);
-			eyy=*(epsilon+1);
-			exy=*(epsilon+2);
-
-			/*Build viscosity: viscosity=2*B/(2*A^e) */
-			A=pow(exx,2)+pow(eyy,2)+pow(exy,2)+exx*eyy;
-			if(A==0){
-				/*Maxiviscositym viscosity for 0 shear areas: */
-				viscosity=4.5*pow((double)10,(double)17);
-			}
-			else{
-				e=(n-1)/2/n;
-				viscosity=2*B/(2*pow(A,e));
-			}
-		}
-	}
-
-	/*Return: */
-	*pviscosity=viscosity;
-}
-/*}}}*/
-/*FUNCTION Matice::GetViscosity3d {{{1*/
-void  Matice::GetViscosity3d(double* pviscosity3d, double* epsilon){
-
-	/*Return viscosity accounting for steady state power law creep [Thomas and MacAyeal, 1982]: 
-	 *
-	 *                                 2*B
-	 * viscosity3d= -------------------------------------------------------------------
-	 *     2[ exx^2+eyy^2+exx*eyy+exy^2+exz^2+eyz^2 ]^[(n-1)/2n]
-	 *
-	 *     where mu is the viscotiy, B the flow law parameter , (u,v) the velocity 
-	 *     vector, and n the flow law exponent.
-	 *
-	 * If epsilon is NULL, it means this is the first time Emg is being run, and we 
-	 * return g, initial viscosity.
-	 */
-	
-	/*output: */
-	double viscosity3d;
-
-	/*input strain rate: */
-	double exx,eyy,exy,exz,eyz;
-
-	/*Intermediary value A and exponent e: */
-	double A,e;
-
-	if (n==1){
-		/*Viscous behaviour! viscosity3d=B: */
-		viscosity3d=B;
-	}
-	else{
-		if((epsilon[0]==0) && (epsilon[1]==0) && (epsilon[2]==0) && 
-				(epsilon[3]==0) && (epsilon[4]==0)){
-			viscosity3d=pow((double)10,(double)14);
-		}
-		else{
-
-			/*Retrive strain rate components: */
-			exx=*(epsilon+0);
-			eyy=*(epsilon+1);
-			exy=*(epsilon+2);
-			exz=*(epsilon+3);
-			eyz=*(epsilon+4);
-
-			/*Build viscosity: viscosity3d=2*B/(2*A^e) */
-			A=pow(exx,2)+pow(eyy,2)+pow(exy,2)+pow(exz,2)+pow(eyz,2)+exx*eyy;
-			if(A==0){
-				/*Maxiviscosity3dm viscosity for 0 shear areas: */
-				viscosity3d=4.5*pow((double)10,(double)17);
-			}
-			else{
-				e=(n-1)/2/n;
-			
-				viscosity3d=2*B/(2*pow(A,e));
-			}
-		}
-	}
-
-	/*Assign output pointers:*/
-	*pviscosity3d=viscosity3d;
-}
-/*}}}*/
-/*FUNCTION Matice::GetViscosity3dStokes {{{1*/
-void  Matice::GetViscosity3dStokes(double* pviscosity3d, double* epsilon){
-
-	/*Return viscosity accounting for steady state power law creep [Thomas and MacAyeal, 1982]: 
-	 *
-	 *                                 2*B
-	 * viscosity3d= -------------------------------------------------------------------
-	 *     2[ exx^2+eyy^2+exx*eyy+exy^2+exz^2+eyz^2 ]^[(n-1)/2n]
-	 *
-	 *     where mu is the viscotiy, B the flow law parameter , (u,v) the velocity 
-	 *     vector, and n the flow law exponent.
-	 *
-	 * If epsilon is NULL, it means this is the first time Emg is being run, and we 
-	 * return g, initial viscosity.
-	 */
-	
-	/*output: */
-	double viscosity3d;
-
-	/*input strain rate: */
-	double exx,eyy,exy,exz,eyz,ezz;
-
-	/*Intermediary value A and exponent e: */
-	double A,e;
-	double eps0;
-
-	eps0=pow((double)10,(double)-27);
-	
-	if (n==1){
-		/*Viscous behaviour! viscosity3d=B: */
-		viscosity3d=B;
-	}
-	else{
-		if((epsilon[0]==0) && (epsilon[1]==0) && (epsilon[2]==0) && 
-				(epsilon[3]==0) && (epsilon[4]==0) && (epsilon[5]==0)){
-			viscosity3d=pow((double)10,(double)14);
-		}
-		else{
-
-			/*Retrive strain rate components: */
-			exx=*(epsilon+0);
-			eyy=*(epsilon+1);
-			ezz=*(epsilon+2); //not used
-			exy=*(epsilon+3);
-			exz=*(epsilon+4);
-			eyz=*(epsilon+5);
-
-			/*Build viscosity: viscosity3d=2*B/(2*A^e) */
-			A=pow(exx,2)+pow(eyy,2)+pow(exy,2)+pow(exz,2)+pow(eyz,2)+exx*eyy+pow(eps0,2);
-			if(A==0){
-				/*Maxiviscosity3dm viscosity for 0 shear areas: */
-				viscosity3d=4.5*pow((double)10,(double)17);
-			}
-			else{
-				e=(n-1)/2/n;
-				viscosity3d=2*B/(2*pow(A,e));
-			}
-		}
-	}
-
-	/*Assign output pointers:*/
-	*pviscosity3d=viscosity3d;
-}
-/*}}}*/
-/*FUNCTION Matice::GetViscosityComplement {{{1*/
-void  Matice::GetViscosityComplement(double* pviscosity_complement, double* epsilon){
-
-	/*Return viscosity accounting for steady state power law creep [Thomas and MacAyeal, 1982]: 
-	 *
-	 *                                  2* (1-n)/2n
-	 * mu2= -------------------------------------------------------------------
-	 *     2[ (du/dx)^2+(dv/dy)^2+1/4*(du/dy+dv/dx)^2+du/dx*dv/dy ]^[(3n-1)/2n]
-	 *
-	 *     where mu2 is the second viscosity, (u,v) the velocity 
-	 *     vector, and n the flow law exponent.
-	 *
-	 * If epsilon is NULL, it means this is the first time Gradjb is being run, and we 
-	 * return mu20, initial viscosity.
-	 */
-	
-	/*output: */
-	double viscosity_complement;
-
-	/*input strain rate: */
-	double exx,eyy,exy;
-
-	/*Intermediary value A and exponent e: */
-	double A,e;
-
-	if(epsilon){
-		exx=*(epsilon+0);
-		eyy=*(epsilon+1);
-		exy=*(epsilon+2);
-
-		/*Build viscosity: mu2=B/(2*A^e) */
-		A=pow(exx,2)+pow(eyy,2)+pow(exy,2)+exx*eyy;
-		if(A==0){
-			/*Maximum viscosity_complement for 0 shear areas: */
-			viscosity_complement=4.5*pow((double)10,(double)17);
-		}
-		else{
-			e=(n-1)/2/n;
-		
-			viscosity_complement=1/(2*pow(A,e));
-		}
-	}
-	else{
-		viscosity_complement=4.5*pow((double)10,(double)17);
-	}
-		
-	/*Return: */
-	*pviscosity_complement=viscosity_complement;
-}
-/*}}}*/
-/*FUNCTION Matice::MyRank {{{1*/
-int    Matice::MyRank(void){ 
-	extern int my_rank;
-	return my_rank; 
-}
-/*}}}*/
-/*FUNCTION Matice::SetB {{{1*/
-void  Matice::SetB(double B_param){
-	B=B_param;
-}
-/*}}}*/
-/*FUNCTION Matice::UpdateFromInputs {{{1*/
-void  Matice::UpdateFromInputs(void* inputs){
-	
-	//ISSMERROR(" not supported yet!");
-
-}
-/*}}}*/
Index: sm/trunk/src/c/objects/Matice.h
===================================================================
--- /issm/trunk/src/c/objects/Matice.h	(revision 3680)
+++ 	(revision )
@@ -1,51 +1,0 @@
-/*!\file Matice.h
- * \brief: header file for matice object
- */
-
-#ifndef MATICE_H_
-#define MATICE_H_
-
-/*Headers:*/
-/*{{{1*/
-struct IoModel;
-#include "./Material.h"
-#include "../ModelProcessorx/IoModel.h"
-/*}}}*/
-
-class Matice: public Material{
-
-	private: 
-		int	   mid;
-		double B;
-		double n;
-
-	public:
-
-		Matice();
-		Matice(int mid,double B,double n);
-		Matice(int mid,int i, IoModel* iomodel, int num_vertices);
-		void Init(int mid,double B,double n);
-		~Matice();
-
-		void  Echo();
-		void  DeepEcho();
-		void  Marshall(char** pmarshalled_dataset);
-		int   MarshallSize();
-		void  Demarshall(char** pmarshalled_dataset);
-		int   Enum();
-		int   Id(); 
-		int   MyRank();
-		void  DistributeNumDofs(int* numdofspernode,int analysis_type);
-		void  UpdateFromInputs(void* inputs);
-		void  SetB(double B_param);
-		void  GetViscosity2d(double* pviscosity, double* pepsilon);
-		void  GetViscosity3d(double* pviscosity3d, double* pepsilon);
-		void  GetViscosity3dStokes(double* pviscosity3d, double* epsilon);
-		void  GetViscosityComplement(double* pviscosity_complement, double* pepsilon);
-		Object* copy();
-		double GetB();
-		double GetN();
-
-};
-
-#endif  /* _MATICE_H_ */
Index: sm/trunk/src/c/objects/Matpar.cpp
===================================================================
--- /issm/trunk/src/c/objects/Matpar.cpp	(revision 3680)
+++ 	(revision )
@@ -1,283 +1,0 @@
-/*!\file Matpar.c
- * \brief: implementation of the Matpar object
- */
-
-
-#ifdef HAVE_CONFIG_H
-	#include "config.h"
-#else
-#error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
-#endif
-
-#include "stdio.h"
-#include "../shared/shared.h"
-#include "../include/macros.h"
-#include "./Matpar.h"
-#include <string.h>
-#include "../EnumDefinitions/EnumDefinitions.h"
-
-		
-/*Object constructors and destructor*/
-/*FUNCTION Matpar::Matpar() {{{1*/
-Matpar::Matpar(){
-	return;
-}
-/*}}}1*/
-/*FUNCTION Matpar::Matpar(int matpar_mid, double matpar_rho_ice, double matpar_rho_water, double matpar_heatcapacity, ...){{{1*/
-Matpar::Matpar(int	matpar_mid, double	matpar_rho_ice, double	matpar_rho_water, double  matpar_heatcapacity, double  matpar_thermalconductivity, double  matpar_latentheat, double  matpar_beta, double  matpar_meltingpoint, double  matpar_mixed_layer_capacity, double  matpar_thermal_exchange_velocity, double  matpar_g){
-
-	this->Init(matpar_mid, matpar_rho_ice, matpar_rho_water, matpar_heatcapacity, matpar_thermalconductivity, matpar_latentheat, matpar_beta, matpar_meltingpoint, matpar_mixed_layer_capacity, matpar_thermal_exchange_velocity, matpar_g);
-
-}
-/*}}}1*/
-/*FUNCTION Matpar::Matpar(int matpar_mid,IoModel* iomodel){{{1*/
-Matpar::Matpar(int matpar_mid, IoModel* iomodel){
-
-	double  matpar_rho_ice;
-	double  matpar_rho_water;
-	double  matpar_heatcapacity;
-	double  matpar_thermalconductivity;
-	double  matpar_latentheat;
-	double  matpar_beta;
-	double  matpar_meltingpoint;
-	double  matpar_mixed_layer_capacity;
-	double  matpar_thermal_exchange_velocity;
-	double  matpar_g;
-
-	matpar_g=iomodel->g; 
-	matpar_rho_ice=iomodel->rho_ice; 
-	matpar_rho_water=iomodel->rho_water; 
-	matpar_thermalconductivity=iomodel->thermalconductivity; 
-	matpar_heatcapacity=iomodel->heatcapacity; 
-	matpar_latentheat=iomodel->latentheat; 
-	matpar_beta=iomodel->beta; 
-	matpar_meltingpoint=iomodel->meltingpoint; 
-	matpar_mixed_layer_capacity=iomodel->mixed_layer_capacity; 
-	matpar_thermal_exchange_velocity=iomodel->thermal_exchange_velocity; 
-
-	this->Init(matpar_mid, matpar_rho_ice, matpar_rho_water, matpar_heatcapacity, matpar_thermalconductivity, matpar_latentheat, matpar_beta, matpar_meltingpoint, matpar_mixed_layer_capacity, matpar_thermal_exchange_velocity, matpar_g);
-
-}
-/*}}}1*/
-/*FUNCTION Matpar::Init {{{1*/
-void Matpar::Init(int	matpar_mid, double	matpar_rho_ice, double	matpar_rho_water, double  matpar_heatcapacity, double  matpar_thermalconductivity, double  matpar_latentheat, double  matpar_beta, double  matpar_meltingpoint, double  matpar_mixed_layer_capacity, double  matpar_thermal_exchange_velocity, double  matpar_g){
-
-	this->mid=matpar_mid; 
-	this->rho_ice=matpar_rho_ice; 
-	this->rho_water=matpar_rho_water; 
-	this->heatcapacity=matpar_heatcapacity; 
-	this->thermalconductivity=matpar_thermalconductivity; 
-	this->latentheat=matpar_latentheat; 
-	this->beta=matpar_beta; 
-	this->meltingpoint=matpar_meltingpoint; 
-	this->mixed_layer_capacity=matpar_mixed_layer_capacity; 
-	this->thermal_exchange_velocity=matpar_thermal_exchange_velocity; 
-	this->g=matpar_g; 
-
-	return;
-}
-/*}}}1*/
-/*FUNCTION Matpar::~Matpar() {{{1*/
-Matpar::~Matpar(){
-	return;
-}
-/*}}}1*/
-
-/*Object marshall*/
-/*FUNCTION Matpar::Demarshall {{{1*/
-void  Matpar::Demarshall(char** pmarshalled_dataset){
-
-	char* marshalled_dataset=NULL;
-
-	/*recover marshalled_dataset: */
-	marshalled_dataset=*pmarshalled_dataset;
-
-	/*this time, no need to get enum type, the pointer directly points to the beginning of the 
-	 *object data (thanks to DataSet::Demarshall):*/
-
-	memcpy(&mid,marshalled_dataset,sizeof(mid));marshalled_dataset+=sizeof(mid);
-	memcpy(&rho_ice,marshalled_dataset,sizeof(rho_ice));marshalled_dataset+=sizeof(rho_ice);
-	memcpy(&rho_water,marshalled_dataset,sizeof(rho_water));marshalled_dataset+=sizeof(rho_water);
-	memcpy(&heatcapacity,marshalled_dataset,sizeof(heatcapacity));marshalled_dataset+=sizeof(heatcapacity);
-	memcpy(&thermalconductivity,marshalled_dataset,sizeof(thermalconductivity));marshalled_dataset+=sizeof(thermalconductivity);
-	memcpy(&latentheat,marshalled_dataset,sizeof(latentheat));marshalled_dataset+=sizeof(latentheat);
-	memcpy(&beta,marshalled_dataset,sizeof(beta));marshalled_dataset+=sizeof(beta);
-	memcpy(&meltingpoint,marshalled_dataset,sizeof(meltingpoint));marshalled_dataset+=sizeof(meltingpoint);
-	memcpy(&mixed_layer_capacity,marshalled_dataset,sizeof(mixed_layer_capacity));marshalled_dataset+=sizeof(mixed_layer_capacity);
-	memcpy(&thermal_exchange_velocity,marshalled_dataset,sizeof(thermal_exchange_velocity));marshalled_dataset+=sizeof(thermal_exchange_velocity);
-	memcpy(&g,marshalled_dataset,sizeof(g));marshalled_dataset+=sizeof(g);
-
-	/*return: */
-	*pmarshalled_dataset=marshalled_dataset;
-	return;
-}
-/*}}}1*/
-/*FUNCTION Matpar::Marshall {{{1*/
-void  Matpar::Marshall(char** pmarshalled_dataset){
-
-	char* marshalled_dataset=NULL;
-	int   enum_type=0;
-
-	/*recover marshalled_dataset: */
-	marshalled_dataset=*pmarshalled_dataset;
-
-	/*get enum type of Matpar: */
-	enum_type=MatparEnum;
-	
-	/*marshall enum: */
-	memcpy(marshalled_dataset,&enum_type,sizeof(enum_type));marshalled_dataset+=sizeof(enum_type);
-	
-	/*marshall Matpar data: */
-	memcpy(marshalled_dataset,&mid,sizeof(mid));marshalled_dataset+=sizeof(mid);
-	memcpy(marshalled_dataset,&rho_ice,sizeof(rho_ice));marshalled_dataset+=sizeof(rho_ice);
-	memcpy(marshalled_dataset,&rho_water,sizeof(rho_water));marshalled_dataset+=sizeof(rho_water);
-	memcpy(marshalled_dataset,&heatcapacity,sizeof(heatcapacity));marshalled_dataset+=sizeof(heatcapacity);
-	memcpy(marshalled_dataset,&thermalconductivity,sizeof(thermalconductivity));marshalled_dataset+=sizeof(thermalconductivity);
-	memcpy(marshalled_dataset,&latentheat,sizeof(latentheat));marshalled_dataset+=sizeof(latentheat);
-	memcpy(marshalled_dataset,&beta,sizeof(beta));marshalled_dataset+=sizeof(beta);
-	memcpy(marshalled_dataset,&meltingpoint,sizeof(meltingpoint));marshalled_dataset+=sizeof(meltingpoint);
-	memcpy(marshalled_dataset,&mixed_layer_capacity,sizeof(mixed_layer_capacity));marshalled_dataset+=sizeof(mixed_layer_capacity);
-	memcpy(marshalled_dataset,&thermal_exchange_velocity,sizeof(thermal_exchange_velocity));marshalled_dataset+=sizeof(thermal_exchange_velocity);
-	memcpy(marshalled_dataset,&g,sizeof(g));marshalled_dataset+=sizeof(g);
-
-	*pmarshalled_dataset=marshalled_dataset;
-	return;
-}
-/*}}}1*/
-/*FUNCTION Matpar::MarshallSize {{{1*/
-int   Matpar::MarshallSize(){
-
-	return sizeof(mid)+
-		sizeof(rho_ice)+
-		sizeof(rho_water)+
-		sizeof(heatcapacity)+
-		sizeof(thermalconductivity)+
-		sizeof(latentheat)+
-		sizeof(beta)+
-		sizeof(meltingpoint)+
-		sizeof(mixed_layer_capacity)+
-		sizeof(thermal_exchange_velocity)+
-		sizeof(g)+
-		sizeof(int); //sizeof(int) for enum type
-}
-/*}}}1*/
-
-/*Object functions*/
-/*FUNCTION Matpar::copy {{{1*/
-Object* Matpar::copy() {
-	return new Matpar(*this); 
-}
-/*}}}1*/
-/*FUNCTION Matpar::DeepEcho {{{1*/
-void Matpar::DeepEcho(void){
-
-	printf("Matpar:\n");
-	printf("   mid: %i\n",mid);
-	printf("   rho_ice: %g\n",rho_ice);
-	printf("   rho_water: %g\n",rho_water);
-	printf("   heatcapacity: %g\n",heatcapacity);
-	printf("   thermalconductivity: %g\n",thermalconductivity);
-	printf("   latentheat: %g\n",latentheat);
-	printf("   beta: %g\n",beta);
-	printf("   meltingpoint: %g\n",meltingpoint);
-	printf("   mixed_layer_capacity: %g\n",mixed_layer_capacity);
-	printf("   thermal_exchange_velocity: %g\n",thermal_exchange_velocity);
-	printf("   g: %g\n",g);
-	return;
-}		
-/*}}}1*/
-/*FUNCTION Matpar::DistributeNumDofs {{{1*/
-void  Matpar::DistributeNumDofs(int* numdofspernode,int analysis_type){return;}
-/*}}}1*/
-/*FUNCTION Matpar::Echo {{{1*/
-void Matpar::Echo(void){
-
-	printf("Matpar:\n");
-	printf("   mid: %i\n",mid);
-	printf("   rho_ice: %g\n",rho_ice);
-	printf("   rho_water: %g\n",rho_water);
-	printf("   heatcapacity: %g\n",heatcapacity);
-	printf("   thermalconductivity: %g\n",thermalconductivity);
-	printf("   latentheat: %g\n",latentheat);
-	printf("   beta: %g\n",beta);
-	printf("   meltingpoint: %g\n",meltingpoint);
-	printf("   mixed_layer_capacity: %g\n",mixed_layer_capacity);
-	printf("   thermal_exchange_velocity: %g\n",thermal_exchange_velocity);
-	printf("   g: %g\n",g);
-	return;
-}
-/*}}}1*/
-/*FUNCTION Matpar::Enum {{{1*/
-int Matpar::Enum(void){
-
-	return MatparEnum;
-
-}
-/*}}}1*/
-/*FUNCTION Matpar::GetBeta {{{1*/
-double Matpar::GetBeta(){
-	return beta;
-}
-/*}}}1*/
-/*FUNCTION Matpar::GetG {{{1*/
-double Matpar::GetG(){
-	return g;
-}
-/*}}}1*/
-/*FUNCTION Matpar::GetHeatCapacity {{{1*/
-double Matpar::GetHeatCapacity(){
-	return heatcapacity;
-}
-/*}}}1*/
-/*FUNCTION Matpar::Id {{{1*/
-int    Matpar::Id(void){ return mid; }
-/*}}}1*/
-/*FUNCTION Matpar::GetLatentHeat {{{1*/
-double Matpar::GetLatentHeat(){
-	return latentheat;
-}
-/*}}}1*/
-/*FUNCTION Matpar::GetMeltingPoint {{{1*/
-double Matpar::GetMeltingPoint(){
-	return meltingpoint;
-}
-/*}}}1*/
-/*FUNCTION Matpar::GetMixedLayerCapacity {{{1*/
-double Matpar::GetMixedLayerCapacity(){
-	return mixed_layer_capacity;
-}
-/*}}}1*/
-/*FUNCTION Matpar::GetRhoIce {{{1*/
-double Matpar::GetRhoIce(){
-	
-	return rho_ice;
-}
-/*}}}1*/
-/*FUNCTION Matpar::GetRhoWater {{{1*/
-double Matpar::GetRhoWater(){
-	return rho_water;
-}
-/*}}}1*/
-/*FUNCTION Matpar::GetThermalConductivity {{{1*/
-double Matpar::GetThermalConductivity(){
-	return thermalconductivity;
-}
-/*}}}1*/
-/*FUNCTION Matpar::GetThermalExchangeVelocity {{{1*/
-double Matpar::GetThermalExchangeVelocity(){
-	return thermal_exchange_velocity;
-}
-/*}}}1*/
-/*FUNCTION Matpar::MyRank {{{1*/
-int    Matpar::MyRank(void){ 
-	extern int my_rank;
-	return my_rank; 
-}
-/*}}}1*/
-/*FUNCTION Matpar::UpdateFromInputs {{{1*/
-void  Matpar::UpdateFromInputs(void* inputs){
-	
-	//ISSMERROR(" not supported yet!");
-
-}
-/*}}}1*/
Index: sm/trunk/src/c/objects/Matpar.h
===================================================================
--- /issm/trunk/src/c/objects/Matpar.h	(revision 3680)
+++ 	(revision )
@@ -1,63 +1,0 @@
-/*!\file Matpar.h
- * \brief: header file for matpar object
- */
-
-#ifndef _MATPAR_H_
-#define _MATPAR_H_
-
-/*Headers:*/
-/*{{{1*/
-struct IoModel;
-#include "./Material.h"
-#include "../ModelProcessorx/IoModel.h"
-/*}}}*/
-
-class Matpar: public Material{
-
-	private: 
-		int	mid;
-		double	rho_ice; 
-		double	rho_water;
-		double  heatcapacity;
-		double  thermalconductivity;
-		double  latentheat;
-		double  beta;
-		double  meltingpoint;
-		double  mixed_layer_capacity;
-		double  thermal_exchange_velocity;
-		double  g;
-
-	public:
-
-		Matpar();
-	
-		Matpar(int	mid, double	rho_ice, double	rho_water, double  heatcapacity, double  thermalconductivity, double  latentheat, double  beta, double  meltingpoint, double  mixed_layer_capacity, double  thermal_exchange_velocity, double  g);
-		void Init(int	mid, double	rho_ice, double	rho_water, double  heatcapacity, double  thermalconductivity, double  latentheat, double  beta, double  meltingpoint, double  mixed_layer_capacity, double  thermal_exchange_velocity, double  g);
-		Matpar(int matpar_id, IoModel* iomodel);
-		~Matpar();
-
-		void  Echo();
-		void  DeepEcho();
-		void  Marshall(char** pmarshalled_dataset);
-		int   MarshallSize();
-		void  Demarshall(char** pmarshalled_dataset);
-		int   Enum();
-		int   Id(); 
-		int   MyRank();
-		void  DistributeNumDofs(int* numdofspernode,int analysis_type);
-		void  UpdateFromInputs(void* inputs);
-		double GetG();
-		double GetRhoIce();
-		double GetRhoWater();
-		double GetMixedLayerCapacity();
-		double GetThermalExchangeVelocity();
-		double GetHeatCapacity();
-		double GetThermalConductivity();
-		double GetLatentHeat();
-		double GetBeta();
-		double GetMeltingPoint();
-		Object* copy();
-
-};
-
-#endif  /* _MATPAR_H_ */
Index: /issm/trunk/src/c/objects/Model.cpp
===================================================================
--- /issm/trunk/src/c/objects/Model.cpp	(revision 3680)
+++ /issm/trunk/src/c/objects/Model.cpp	(revision 3681)
@@ -3,5 +3,4 @@
  */
 
-#include "../issm.h"
 
 #ifdef HAVE_CONFIG_H
@@ -11,7 +10,12 @@
 #endif
 
-#include "./Model.h"
+#include "stdio.h"
+#include "../DataSet/DataSet.h"
+#include "../ModelProcessorx/ModelProcessorx.h"
+#include "./objects.h"
+#include "../include/types.h"
 #include "../EnumDefinitions/EnumDefinitions.h"
-#include "stdio.h"
+#include "../modules.h"
+
 
 /*Object constructors and destructor*/
Index: /issm/trunk/src/c/objects/Node.cpp
===================================================================
--- /issm/trunk/src/c/objects/Node.cpp	(revision 3680)
+++ /issm/trunk/src/c/objects/Node.cpp	(revision 3681)
@@ -11,9 +11,7 @@
 
 #include "stdio.h"
-#include "./Vertex.h"
-#include "./Node.h"
-#include "./Hook.h"
-#include "./DofIndexing.h"
 #include <string.h>
+#include "./objects.h"
+#include "../DataSet/DataSet.h"
 #include "../EnumDefinitions/EnumDefinitions.h"
 #include "../shared/shared.h"
Index: /issm/trunk/src/c/objects/Node.h
===================================================================
--- /issm/trunk/src/c/objects/Node.h	(revision 3680)
+++ /issm/trunk/src/c/objects/Node.h	(revision 3681)
@@ -8,11 +8,11 @@
 /*Headers:*/
 /*{{{1*/
-/*indefinitions: */
 #include "./Object.h"
 #include "./DofObject.h"
-#include "../DataSet/Inputs.h"
-#include "./Hook.h"
-#include "./DofIndexing.h"
-#include "../ModelProcessorx/IoModel.h"
+class  Inputs;
+class  Hook;
+class  DofIndexing;
+class IoModel;
+class  DataSet;
 /*}}}*/
 
Index: /issm/trunk/src/c/objects/NodeSets.h
===================================================================
--- /issm/trunk/src/c/objects/NodeSets.h	(revision 3680)
+++ /issm/trunk/src/c/objects/NodeSets.h	(revision 3681)
@@ -8,5 +8,4 @@
 /*Headers:*/
 /*{{{1*/
-#include "../toolkits/toolkits.h"
 /*}}}*/
 
Index: sm/trunk/src/c/objects/Numericalflux.cpp
===================================================================
--- /issm/trunk/src/c/objects/Numericalflux.cpp	(revision 3680)
+++ 	(revision )
@@ -1,844 +1,0 @@
-/*!\file Numericalflux.c
- * \brief: implementation of the Numericalflux object
- */
-
-#ifdef HAVE_CONFIG_H
-	#include "config.h"
-#else
-#error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
-#endif
-
-#include "stdio.h"
-#include <string.h>
-#include "../EnumDefinitions/EnumDefinitions.h"
-#include "../shared/shared.h"
-#include "../include/typedefs.h"
-#include "../include/macros.h"
-#include "./objects.h"
-
-extern int my_rank;
-
-/*Object constructors and destructor*/
-/*FUNCTION Numericalflux::Numericalflux(){{{1*/
-Numericalflux::Numericalflux(){
-	this->inputs=NULL;
-	this->parameters=NULL;
-}
-/*}}}*/
-/*FUNCTION Numericalflux::Numericalflux(int numericalflux_id,int* numericalflux_node_ids,...){{{1*/
-Numericalflux::Numericalflux(int numericalflux_id,int* numericalflux_node_ids,int numnodes,int* numericalflux_element_ids, int numelements):
-	hnodes(numericalflux_node_ids,numnodes),
-	helements(numericalflux_element_ids,numelements)
-{
-
-	id=numericalflux_id;
-	this->parameters=NULL;
-	this->inputs=new Inputs();
-}
-/*}}}*/
-/*FUNCTION Numericalflux::Numericalflux(int id, Hook* hnodes, Hook* helements, Parameters* parameters, Inputs* numericalflux_inputs) {{{1*/
-Numericalflux::Numericalflux(int numericalflux_id,Hook* numericalflux_hnodes, Hook* numericalflux_helements, Parameters* numericalflux_parameters, Inputs* numericalflux_inputs):
-	hnodes(numericalflux_hnodes),
-	helements(numericalflux_helements)
-{
-
-	/*all the initialization has been done by the initializer, just fill in the id: */
-	this->id=numericalflux_id;
-	if(numericalflux_inputs){
-		this->inputs=(Inputs*)numericalflux_inputs->Copy();
-	}
-	else{
-		this->inputs=new Inputs();
-	}
-	/*point parameters: */
-	this->parameters=numericalflux_parameters;
-}
-/*}}}*//*FUNCTION Numericalflux::Numericalflux(int id, int i, IoModel* iomodel) {{{1*/
-Numericalflux::Numericalflux(int numericalflux_id,int i, IoModel* iomodel){
-
-	/* Intermediary */
-	int  e1,e2;
-	int  i1,i2;
-	int  j;
-	int  pos1,pos2;
-	int  num_nodes;
-	int  num_elems;
-
-	/*numericalflux constructor data: */
-	int   numericalflux_elem_ids[2];
-	int   numericalflux_mparid;
-	int   numericalflux_node_ids[4];
-	int   numericalflux_type;
-
-	/* Get MatPar id */
-	numericalflux_mparid=iomodel->numberofelements+1; //matlab indexing
-
-	/*Get left and right elements*/
-	e1=(int)iomodel->edges[4*i+2]; //edges are [node1 node2 elem1 elem2]
-	e2=(int)iomodel->edges[4*i+3]; //edges are [node1 node2 elem1 elem2]
-	if (isnan(e2)){
-		/* Boundary edge, only one element */
-		num_elems=1;
-		num_nodes=2;
-		numericalflux_type=BoundaryEnum;
-		numericalflux_elem_ids[0]=(int)e1;
-	}
-	else{
-		/* internal edge: connected to 2 elements */
-		num_elems=2;
-		num_nodes=4;
-		numericalflux_type=InternalEnum;
-		numericalflux_elem_ids[0]=(int)e1;
-		numericalflux_elem_ids[1]=(int)e2;
-	}
-
-	/*1: Get vertices ids*/
-	i1=(int)iomodel->edges[4*i+0];
-	i2=(int)iomodel->edges[4*i+1];
-
-	if (numericalflux_type==InternalEnum){
-
-		/*Now, we must get the nodes of the 4 nodes located on the edge*/
-
-		/*2: Get the column where these ids are located in the index*/
-		pos1=pos2=UNDEF;
-		for(j=0;j<3;j++){
-			if (iomodel->elements[3*(int)e1+j]==i1) pos1=j+1;
-			if (iomodel->elements[3*(int)e2+j]==i1) pos2=j+1;
-		}
-		ISSMASSERT(pos1!=UNDEF && pos2!=UNDEF);
-
-		/*3: We have the id of the elements and the position of the vertices in the index
-		 * we can compute their dofs!*/
-		numericalflux_node_ids[0]=3*(int)e1+pos1;       //ex: 1 2 3
-		numericalflux_node_ids[1]=3*(int)e1+(pos1%3)+1; //ex: 2 3 1
-		numericalflux_node_ids[2]=3*(int)e2+pos2;           //ex: 1 2 3
-		numericalflux_node_ids[3]=3*(int)e2+((pos2+1)%3)+1; //ex: 3 1 2
-	}
-	else{
-
-		/*2: Get the column where these ids are located in the index*/
-		pos1==UNDEF;
-		for(j=0;j<3;j++){
-			if (iomodel->elements[3*(int)e1+j]==i1) pos1=j+1;
-		}
-		ISSMASSERT(pos1!=UNDEF);
-
-		/*3: We have the id of the elements and the position of the vertices in the index
-		 * we can compute their dofs!*/
-		numericalflux_node_ids[0]=3*(int)e1+pos1;
-		numericalflux_node_ids[1]=3*(int)e1+(pos1%3)+1;
-
-	}
-
-	/*Ok, we have everything to build the object: */
-	this->id=numericalflux_id;
-
-	/*Hooks: */
-	this->hnodes.Init(numericalflux_node_ids,num_nodes);
-	this->helements.Init(numericalflux_elem_ids,num_elems);
-
-	//intialize  and add as many inputs per element as requested: 
-	this->inputs=new Inputs();
-	this->inputs->AddInput(new IntInput(TypeEnum,numericalflux_type));
-
-	//this->parameters: we still can't point to it, it may not even exist. Configure will handle this.
-	this->parameters=NULL;
-}
-/*}}}*/
-
-/*FUNCTION Numericalflux::~Numericalflux(){{{1*/
-Numericalflux::~Numericalflux(){
-	delete inputs;
-	this->parameters=NULL;
-}
-/*}}}*/
-
-/*Object marshall*/
-/*FUNCTION Numericalflux::Configure {{{1*/
-void  Numericalflux::Configure(DataSet* elementsin,DataSet* loadsin,DataSet* nodesin,DataSet* verticesin,DataSet* materialsin,Parameters* parametersin){
-
-	/*Take care of hooking up all objects for this element, ie links the objects in the hooks to their respective 
-	 * datasets, using internal ids and offsets hidden in hooks: */
-	hnodes.configure(nodesin);
-	helements.configure(elementsin);
-
-	/*point parameters to real dataset: */
-	this->parameters=parametersin;
-
-}
-/*}}}*/
-/*FUNCTION Numericalflux::copy {{{1*/
-Object* Numericalflux::copy() {
-	return new Numericalflux(this->id,&this->hnodes,&this->helements,this->parameters,this->inputs);
-}
-/*}}}*/
-/*FUNCTION Numericalflux::DeepEcho {{{1*/
-void Numericalflux::DeepEcho(void){
-
-	printf("Numericalflux:\n");
-	printf("   id: %i\n",id);
-	hnodes.DeepEcho();
-	helements.DeepEcho();
-	printf("   parameters\n");
-	parameters->DeepEcho();
-	printf("   inputs\n");
-	inputs->DeepEcho();
-	
-}		
-/*}}}*/
-/*FUNCTION Numericalflux::Demarshall {{{1*/
-void  Numericalflux::Demarshall(char** pmarshalled_dataset){
-
-	char* marshalled_dataset=NULL;
-	int   i;
-
-	/*recover marshalled_dataset: */
-	marshalled_dataset=*pmarshalled_dataset;
-
-	/*this time, no need to get enum type, the pointer directly points to the beginning of the 
-	 *object data (thanks to DataSet::Demarshall):*/
-
-	memcpy(&id,marshalled_dataset,sizeof(id));marshalled_dataset+=sizeof(id);
-
-	/*demarshall hooks: */
-	hnodes.Demarshall(&marshalled_dataset);
-	helements.Demarshall(&marshalled_dataset);
-	
-	/*demarshall inputs: */
-	inputs=(Inputs*)DataSetDemarshallRaw(&marshalled_dataset); 
-
-	/*parameters: may not exist even yet, so let Configure handle it: */
-	this->parameters=NULL;
-
-	/*return: */
-	*pmarshalled_dataset=marshalled_dataset;
-	return;
-}
-/*}}}*/
-/*FUNCTION Numericalflux::Echo {{{1*/
-void Numericalflux::Echo(void){
-	this->DeepEcho();
-}
-/*}}}*/
-/*FUNCTION Numericalflux::Enum {{{1*/
-int Numericalflux::Enum(void){
-
-	return NumericalfluxEnum;
-
-}
-/*}}}*/
-/*FUNCTION Numericalflux::Marshall {{{1*/
-void  Numericalflux::Marshall(char** pmarshalled_dataset){
-
-	char* marshalled_dataset=NULL;
-	int   enum_type=0;
-	char* marshalled_inputs=NULL;
-	int   marshalled_inputs_size;
-
-	/*recover marshalled_dataset: */
-	marshalled_dataset=*pmarshalled_dataset;
-
-	/*get enum type of Numericalflux: */
-	enum_type=NumericalfluxEnum;
-
-	/*marshall enum: */
-	memcpy(marshalled_dataset,&enum_type,sizeof(enum_type));marshalled_dataset+=sizeof(enum_type);
-
-	/*marshall Numericalflux data: */
-	memcpy(marshalled_dataset,&id,sizeof(id));marshalled_dataset+=sizeof(id);
-
-	/*Marshall hooks: */
-	hnodes.Marshall(&marshalled_dataset);
-	helements.Marshall(&marshalled_dataset);
-
-	/*Marshall inputs: */
-	marshalled_inputs_size=inputs->MarshallSize();
-	marshalled_inputs=inputs->Marshall();
-	memcpy(marshalled_dataset,marshalled_inputs,marshalled_inputs_size*sizeof(char));
-	marshalled_dataset+=marshalled_inputs_size;
-
-	/*parameters: don't do anything about it. parameters are marshalled somewhere else!*/
-
-	xfree((void**)&marshalled_inputs);
-
-	*pmarshalled_dataset=marshalled_dataset;
-	return;
-}
-/*}}}*/
-/*FUNCTION Numericalflux::MarshallSize{{{1*/
-int   Numericalflux::MarshallSize(){
-
-	return sizeof(id)
-		+hnodes.MarshallSize()
-		+helements.MarshallSize()
-		+inputs->MarshallSize()
-		+sizeof(int); //sizeof(int) for enum type
-}
-/*}}}*/
-/*FUNCTION Numericalflux::MyRank {{{1*/
-int    Numericalflux::MyRank(void){ 
-	extern int my_rank;
-	return my_rank; 
-}
-/*}}}*/
-
-/*Object functions*/
-/*FUNCTION Numericalflux::CreateKMatrix {{{1*/
-void  Numericalflux::CreateKMatrix(Mat Kgg,int analysis_type,int sub_analysis_type){
-
-	int type;
-
-	/*recover type: */
-	inputs->GetParameterValue(&type,TypeEnum);
-
-	if (type==InternalEnum){
-
-		CreateKMatrixInternal(Kgg,analysis_type,sub_analysis_type);
-	}
-	else if (type==BoundaryEnum){
-
-		CreateKMatrixBoundary(Kgg,analysis_type,sub_analysis_type);
-	}
-	else ISSMERROR("type not supported yet");
-
-}
-/*}}}*/
-/*FUNCTION Numericalflux::CreateKMatrixInternal {{{1*/
-void  Numericalflux::CreateKMatrixInternal(Mat Kgg,int analysis_type,int sub_analysis_type){
-
-	/* local declarations */
-	int             i,j;
-
-	/* node data: */
-	const int numgrids=4;
-	const int NDOF1=1;
-	const int numdof=NDOF1*numgrids;
-	double    xyz_list[numgrids][3];
-	double    normal[2];
-	int       doflist[numdof];
-	int       numberofdofspernode;
-
-	/* gaussian points: */
-	int     num_gauss,ig;
-	double* gauss_coords =NULL;
-	double  gauss_coord;
-	double* gauss_weights=NULL;
-	double  gauss_weight;
-
-	/* matrices: */
-	double B[numgrids];
-	double L[numgrids];
-	double DL1,DL2;
-	double Ke_gg1[numdof][numdof];
-	double Ke_gg2[numdof][numdof];
-	double Ke_gg[numdof][numdof]={0.0};
-	double Jdet;
-
-	/*input parameters for structural analysis (diagnostic): */
-	double vx,vy;
-	double UdotN;
-	double dt;
-	int    found;
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-	Tria**  trias=NULL;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	trias=(Tria**)helements.deliverp();
-
-	/*recover parameters: */
-	if (analysis_type==Prognostic2AnalysisEnum){
-		parameters->FindParam(&dt,DtEnum);
-	}
-	else if (analysis_type==Balancedthickness2AnalysisEnum){
-		/*No transient term is involved*/
-		dt=1;
-	}
-	else{
-		ISSMERROR("analysis_type %i not supported yet");
-	}
-
-	/* Get node coordinates, dof list and normal vector: */
-	GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
-	GetDofList(&doflist[0],&numberofdofspernode);
-	GetNormal(&normal[0],xyz_list);
-
-	/* Get gaussian points and weights (make this a statically initialized list of points? fstd): */
-	num_gauss=2;
-	GaussSegment(&gauss_coords, &gauss_weights,num_gauss);
-
-	/* Start  looping on the number of gaussian points: */
-	for (ig=0; ig<num_gauss; ig++){
-
-		/*Pick up the gaussian point: */
-		gauss_weight=gauss_weights[ig];
-		gauss_coord =gauss_coords[ig];
-
-		/* Get Jacobian determinant: */
-		GetJacobianDeterminant(&Jdet,xyz_list,gauss_coord);
-
-		//Get vx, vy and v.n
-		trias[0]->inputs->GetParameterValue(&vx, nodes[0],nodes[1],gauss_coord,VxAverageEnum);
-		trias[0]->inputs->GetParameterValue(&vy, nodes[0],nodes[1],gauss_coord,VyAverageEnum);
-		
-		UdotN=vx*normal[0]+vy*normal[1];
-		if (fabs(UdotN)<1.0e-9 && analysis_type==Balancedthickness2AnalysisEnum) printf("Edge number %i has a flux very small (u.n = %g ), which could lead to unaccurate results\n",id,UdotN);
-
-		/*Get L and B: */
-		GetL(&L[0],gauss_coord,numdof);
-		GetB(&B[0],gauss_coord);
-
-		/*Compute DLs*/
-		DL1=gauss_weight*Jdet*dt*UdotN/2;
-		DL2=gauss_weight*Jdet*dt*fabs(UdotN)/2;
-
-		/*  Do the triple products: */
-		TripleMultiply(&B[0],1,numdof,1,
-					&DL1,1,1,0,
-					&L[0],1,numdof,0,
-					&Ke_gg1[0][0],0);
-		TripleMultiply(&B[0],1,numdof,1,
-					&DL2,1,1,0,
-					&B[0],1,numdof,0,
-					&Ke_gg2[0][0],0);
-
-		/* Add the Ke_gg_gaussian, and optionally Ke_gg_drag_gaussian onto Ke_gg: */
-		for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg1[i][j];
-		for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg2[i][j];
-
-	} // for (ig=0; ig<num_gauss; ig++)
-
-	/*Add Ke_gg to global matrix Kgg: */
-	MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)Ke_gg,ADD_VALUES);
-
-	xfree((void**)&gauss_coords);
-	xfree((void**)&gauss_weights);
-}
-/*}}}*/
-/*FUNCTION Numericalflux::CreateKMatrixBoundary {{{1*/
-void  Numericalflux::CreateKMatrixBoundary(Mat Kgg,int analysis_type,int sub_analysis_type){
-
-	/* local declarations */
-	int             i,j;
-
-	/* node data: */
-	const int numgrids=2;
-	const int NDOF1=1;
-	const int numdof=NDOF1*numgrids;
-	double    xyz_list[numgrids][3];
-	double    normal[2];
-	int       doflist[numdof];
-	int       numberofdofspernode;
-
-	/* gaussian points: */
-	int     num_gauss,ig;
-	double* gauss_coords =NULL;
-	double  gauss_coord;
-	double* gauss_weights=NULL;
-	double  gauss_weight;
-
-	/* matrices: */
-	double L[numgrids];
-	double DL;
-	double Ke_gg[numdof][numdof]={0.0};
-	double Ke_gg_gaussian[numdof][numdof];
-	double Jdet;
-
-	/*input parameters for structural analysis (diagnostic): */
-	double vx,vy;
-	double mean_vx;
-	double mean_vy;
-	double UdotN;
-	double dt;
-	int    dofs[1]={0};
-	int    found;
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-	Tria**  trias=NULL;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	trias=(Tria**)helements.deliverp();
-
-	/*recover parameters: */
-	if (analysis_type==Prognostic2AnalysisEnum){
-		parameters->FindParam(&dt,DtEnum);
-	}
-	else if (analysis_type==Balancedthickness2AnalysisEnum){
-		/*No transient term is involved*/
-		dt=1;
-	}
-	else{
-		ISSMERROR("analysis_type %i not supported yet");
-	}
-	
-	/* Get node coordinates, dof list and normal vector: */
-	GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
-	GetDofList(&doflist[0],&numberofdofspernode);
-	GetNormal(&normal[0],xyz_list);
-
-	/*Check wether it is an inflow or outflow BC*/
-	trias[0]->inputs->GetParameterValue(&mean_vx, nodes[0],nodes[1],.5,VxAverageEnum);
-	trias[0]->inputs->GetParameterValue(&mean_vy, nodes[0],nodes[1],.5,VyAverageEnum);
-	UdotN=mean_vx*normal[0]+mean_vy*normal[1];
-	if (UdotN<=0){
-		/*(u,n)<0 -> inflow, PenaltyCreatePVector will take care of it*/
-		return;
-	}
-
-	/* Get gaussian points and weights (make this a statically initialized list of points? fstd): */
-	num_gauss=2;
-	GaussSegment(&gauss_coords, &gauss_weights,num_gauss);
-
-	/* Start  looping on the number of gaussian points: */
-	for (ig=0; ig<num_gauss; ig++){
-
-		/*Pick up the gaussian point: */
-		gauss_weight=gauss_weights[ig];
-		gauss_coord =gauss_coords[ig];
-
-		/* Get Jacobian determinant: */
-		GetJacobianDeterminant(&Jdet,xyz_list,gauss_coord);
-
-		//Get vx, vy and v.n
-		trias[0]->inputs->GetParameterValue(&vx, nodes[0],nodes[1],gauss_coord,VxAverageEnum);
-		trias[0]->inputs->GetParameterValue(&vy, nodes[0],nodes[1],gauss_coord,VyAverageEnum);
-
-		UdotN=vx*normal[0]+vy*normal[1];
-
-		/*Get L*/
-		GetL(&L[0],gauss_coord,numdof);
-
-		/*Compute DLs*/
-		DL=gauss_weight*Jdet*dt*UdotN;
-
-		/*Do triple product*/
-		TripleMultiply(&L[0],1,numdof,1,
-					&DL,1,1,0,
-					&L[0],1,numdof,0,
-					&Ke_gg_gaussian[0][0],0);
-
-		/* Add the Ke_gg_gaussian, and optionally Ke_gg_drag_gaussian onto Ke_gg: */
-		for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg_gaussian[i][j];
-
-	} // for (ig=0; ig<num_gauss; ig++)
-
-	/*Add Ke_gg to global matrix Kgg: */
-	MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)Ke_gg,ADD_VALUES);
-
-	xfree((void**)&gauss_coords);
-	xfree((void**)&gauss_weights);
-
-}
-/*}}}*/
-/*FUNCTION Numericalflux::CreatePVector {{{1*/
-void  Numericalflux::CreatePVector(Vec pg,  int analysis_type,int sub_analysis_type){
-
-	int type;
-
-	/*recover type: */
-	inputs->GetParameterValue(&type,TypeEnum);
-
-	if (type==InternalEnum){
-
-		CreatePVectorInternal(pg,analysis_type,sub_analysis_type);
-	}
-	else if (type==BoundaryEnum){
-
-		CreatePVectorBoundary(pg,analysis_type,sub_analysis_type);
-	}
-	else ISSMERROR("type not supported yet");
-
-}
-/*}}}*/
-/*FUNCTION Numericalflux::CreatePVectorInternal{{{1*/
-void  Numericalflux::CreatePVectorInternal(Vec pg,int analysis_type,int sub_analysis_type){
-
-	/*Nothing added to PVector*/
-	return;
-
-}
-/*}}}*/
-/*FUNCTION Numericalflux::CreatePVectorBoundary{{{1*/
-void  Numericalflux::CreatePVectorBoundary(Vec pg,int analysis_type,int sub_analysis_type){
-
-	/* local declarations */
-	int             i,j;
-
-	/* node data: */
-	const int numgrids=2;
-	const int NDOF1=1;
-	const int numdof=NDOF1*numgrids;
-	double    xyz_list[numgrids][3];
-	double    normal[2];
-	int       doflist[numdof];
-	int       numberofdofspernode;
-
-	/* gaussian points: */
-	int     num_gauss,ig;
-	double* gauss_coords =NULL;
-	double  gauss_coord;
-	double* gauss_weights=NULL;
-	double  gauss_weight;
-
-	/* matrices: */
-	double L[numgrids];
-	double DL;
-	double pe_g[numdof]={0.0};
-	double Jdet;
-
-	/*input parameters for structural analysis (diagnostic): */
-	double vx,vy;
-	double mean_vx;
-	double mean_vy;
-	double UdotN;
-	double thickness;
-	double dt;
-	int    dofs[1]={0};
-	int    found;
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-	Tria**  trias=NULL;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	trias=(Tria**)helements.deliverp();
-
-	/*recover parameters: */
-	if (analysis_type==Prognostic2AnalysisEnum){
-		parameters->FindParam(&dt,DtEnum);
-	}
-	else if (analysis_type==Balancedthickness2AnalysisEnum){
-		/*No transient term is involved*/
-		dt=1;
-	}
-	else{
-		ISSMERROR("analysis_type %i not supported yet");
-	}
-	
-	/* Get node coordinates, dof list and normal vector: */
-	GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
-	GetDofList(&doflist[0],&numberofdofspernode);
-	GetNormal(&normal[0],xyz_list);
-
-	/*Check wether it is an inflow or outflow BC*/
-	trias[0]->inputs->GetParameterValue(&mean_vx, nodes[0],nodes[1],.5,VxAverageEnum);
-	trias[0]->inputs->GetParameterValue(&mean_vy, nodes[0],nodes[1],.5,VyAverageEnum);
-	UdotN=mean_vx*normal[0]+mean_vy*normal[1];
-	if (UdotN>0){
-		/*(u,n)>0 -> outflow, PenaltyCreateKMatrix will take care of it*/
-		return;
-	}
-
-	/* Get gaussian points and weights (make this a statically initialized list of points? fstd): */
-	num_gauss=2;
-	GaussSegment(&gauss_coords, &gauss_weights,num_gauss);
-
-	/* Start  looping on the number of gaussian points: */
-	for (ig=0; ig<num_gauss; ig++){
-
-		/*Pick up the gaussian point: */
-		gauss_weight=gauss_weights[ig];
-		gauss_coord =gauss_coords[ig];
-
-		/* Get Jacobian determinant: */
-		GetJacobianDeterminant(&Jdet,xyz_list,gauss_coord);
-
-		//Get vx, vy and v.n
-		trias[0]->inputs->GetParameterValue(&vx, nodes[0],nodes[1],gauss_coord,VxAverageEnum);
-		trias[0]->inputs->GetParameterValue(&vy, nodes[0],nodes[1],gauss_coord,VyAverageEnum);
-		trias[0]->inputs->GetParameterValue(&thickness, nodes[0],nodes[1],gauss_coord,ThicknessEnum);
-
-		UdotN=vx*normal[0]+vy*normal[1];
-
-		/*Get L*/
-		GetL(&L[0],gauss_coord,numdof);
-
-		/*Compute DL*/
-		DL= - gauss_weight*Jdet*dt*UdotN*thickness;
-
-		/* Add value into pe_g: */
-		for( i=0; i<numdof; i++) pe_g[i] += DL* L[i];
-
-	} // for (ig=0; ig<num_gauss; ig++)
-
-	/*Add pe_g to global matrix Kgg: */
-	VecSetValues(pg,numdof,doflist,(const double*)pe_g,ADD_VALUES);
-
-	xfree((void**)&gauss_coords);
-	xfree((void**)&gauss_weights);
-
-}
-/*}}}*/
-/*FUNCTION Numericalflux::DistributeNumDofs {{{1*/
-void  Numericalflux::DistributeNumDofs(int* numdofspernode,int analysis_type,int sub_analysis_type){
-	return;
-}
-/*}}}*/
-/*FUNCTION Numericalflux::GetB {{{1*/
-void Numericalflux::GetB(double* B, double gauss_coord){
-
-	const int numgrids=4;
-	double l1l4[numgrids];
-
-	/*Get nodal functions: */
-	GetNodalFunctions(&l1l4[0],gauss_coord);
-
-	/*Build B: */
-	B[0] = +l1l4[0];
-	B[1] = +l1l4[1];
-	B[2] = -l1l4[0];
-	B[3] = -l1l4[1];
-}
-/*}}}*/
-/*FUNCTION Numericalflux::GetDofList{{{1*/
-
-void  Numericalflux::GetDofList(int* doflist,int* pnumberofdofspernode){
-
-	int i,j;
-	int doflist_per_node[MAXDOFSPERNODE];
-	int numberofdofspernode;
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-	int type;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	
-	/*recover type: */
-	inputs->GetParameterValue(&type,TypeEnum);
-
-	if (type==InternalEnum){
-		for(i=0;i<4;i++){
-			nodes[i]->GetDofList(&doflist_per_node[0],&numberofdofspernode);
-			for(j=0;j<numberofdofspernode;j++){
-				doflist[i*numberofdofspernode+j]=doflist_per_node[j];
-			}
-		}
-	}
-	else if (type==BoundaryEnum){
-		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];
-			}
-		}
-	}
-	else ISSMERROR("type %s not supported yet",type);
-
-	/*Assign output pointers:*/
-	*pnumberofdofspernode=numberofdofspernode;
-}
-/*}}}*/
-/*FUNCTION Numericalflux::Id {{{1*/
-int    Numericalflux::Id(void){
-	return id;
-}
-/*}}}*/
-/*FUNCTION Numericalflux::GetJacobianDeterminant{{{1*/
-void Numericalflux::GetJacobianDeterminant(double* pJdet,double xyz_list[4][3], double gauss_coord){
-
-	double Jdet,length;
-
-	length=sqrt(pow(xyz_list[1][0] - xyz_list[0][0],2.0) + pow(xyz_list[1][1] - xyz_list[0][1],2.0));
-	Jdet=1.0/2.0*length;
-
-	if(Jdet<0){
-		ISSMERROR(" negative jacobian determinant!");
-	}
-
-	*pJdet=Jdet;
-}
-/*}}}*/
-/*FUNCTION Numericalflux::GetL {{{1*/
-void Numericalflux::GetL(double* L, double gauss_coord, int numdof){
-
-	const int numgrids=4;
-	double l1l4[numgrids];
-
-	/*Check numdof*/
-	ISSMASSERT(numdof==2 || numdof==4);
-
-	/*Get nodal functions: */
-	GetNodalFunctions(&l1l4[0],gauss_coord);
-
-	/*Luild L: */
-	L[0] = l1l4[0];
-	L[1] = l1l4[1];
-	if (numdof==4){
-		L[2] = l1l4[2];
-		L[3] = l1l4[3];
-	}
-}
-/*}}}*/
-/*FUNCTION Numericalflux::GetNodalFunctions{{{1*/
-void Numericalflux::GetNodalFunctions(double* l1l4, double gauss_coord){
-
-	/*This routine returns the values of the nodal functions  at the gaussian point.*/
-
-	l1l4[0]=-0.5*gauss_coord+0.5;
-	l1l4[1]=+0.5*gauss_coord+0.5;
-	l1l4[2]=-0.5*gauss_coord+0.5;
-	l1l4[3]=+0.5*gauss_coord+0.5;
-
-}
-/*}}}*/
-/*FUNCTION Numericalflux::GetNormal {{{1*/
-void Numericalflux:: GetNormal(double* normal,double xyz_list[4][3]){
-
-	/*Build unit outward pointing vector*/
-	const int numgrids=4;
-	double vector[2];
-	double norm;
-
-	vector[0]=xyz_list[1][0] - xyz_list[0][0];
-	vector[1]=xyz_list[1][1] - xyz_list[0][1];
-
-	norm=sqrt(pow(vector[0],2.0)+pow(vector[1],2.0));
-
-	normal[0]= + vector[1]/norm;
-	normal[1]= - vector[0]/norm;
-}
-/*}}}*/
-/*FUNCTION Numericalflux::GetParameterValue {{{1*/
-void Numericalflux::GetParameterValue(double* pp, double* plist, double gauss_coord){
-
-	/*From node values of parameter p (plist[0],plist[1],plist[2]), return parameter value at gaussian 
-	 * point specifie by gauss_l1l2l3: */
-
-	/*nodal functions: */
-	double l1l4[4];
-
-	/*output: */
-	double p;
-
-	GetNodalFunctions(&l1l4[0],gauss_coord);
-
-	p=l1l4[0]*plist[0]+l1l4[1]*plist[1];
-
-	/*Assign output pointers:*/
-	*pp=p;
-}
-/*}}}*/
-/*FUNCTION Numericalflux::PenaltyCreateKMatrix {{{1*/
-void  Numericalflux::PenaltyCreateKMatrix(Mat Kgg,double kmax,int analysis_type,int sub_analysis_type){
-
-	/*No stiffness loads applied, do nothing: */
-	return;
-
-}
-/*}}}*/
-/*FUNCTION Numericalflux::PenaltyCreatePVector{{{1*/
-void  Numericalflux::PenaltyCreatePVector(Vec pg,double kmax,int analysis_type,int sub_analysis_type){
-
-	/*No penalty loads applied, do nothing: */
-	return;
-
-}
-/*}}}*/
Index: sm/trunk/src/c/objects/Numericalflux.h
===================================================================
--- /issm/trunk/src/c/objects/Numericalflux.h	(revision 3680)
+++ 	(revision )
@@ -1,68 +1,0 @@
-/*!\file Numericalflux.h
- * \brief: header file for icefront object
- */
-
-#ifndef _NUMERICALFLUX_H_
-#define _NUMERICALFLUX_H_
-
-/*Headers:*/
-/*{{{1*/
-#include "./Load.h"
-#include "./Matpar.h"
-#include "./Hook.h"
-/*}}}*/
-
-class Numericalflux: public Load {
-
-	public: 
-		int         id;
-
-		Hook        helements;
-		Hook        hnodes;
-		Parameters *parameters;
-		Inputs     *inputs;
-
-
-		/*Constructors {{{1*/
-		Numericalflux();
-		Numericalflux(int numericalflux_id,int* numericalflux_node_ids,int numnodes, int* numericalflux_element_ids, int numelements);
-		Numericalflux(int numericalflux_id,Hook* numericalflux_hnodes, Hook* numericalflux_helements, Parameters* parameters, Inputs* numericalflux_inputs);
-		Numericalflux(int numericalflux_id,int i, IoModel* iomodel);
-		~Numericalflux();
-		/*}}}*/
-		/*Object management: {{{1*/
-		Object* copy();
-		void  Configure(DataSet* elements,DataSet* loads,DataSet* nodes,DataSet* vertices,DataSet* materials,Parameters* parameters);
-		void  DeepEcho();
-		void  Demarshall(char** pmarshalled_dataset);
-		void  Echo();
-		int   Enum();
-		int   Id(); 
-		void  Marshall(char** pmarshalled_dataset);
-		int   MarshallSize();
-		int   MyRank();
-		/*}}}*/
-		/*Numerics: {{{1*/
-		void  GetJacobianDeterminant(double* pJdet,double xyz_list[4][3], double gauss_coord);
-		void  GetNodalFunctions(double* l1l4, double gauss_coord);
-		void  DistributeNumDofs(int* numdofspernode,int analysis_type,int sub_analysis_type);
-		void  GetB(double* B, double gauss_coord);
-		void  GetL(double* L, double gauss_coord,int numdof);
-		void  GetDofList(int* doflist,int* pnumberofdofs);
-		void  GetNormal(double* normal,double xyz_list[4][3]);
-		void  GetParameterValue(double* pp, double* plist, double gauss_coord);
-		void  UpdateFromInputs(void* inputs);
-		
-		void  CreateKMatrix(Mat Kgg,int analysis_type,int sub_analysis_type);
-		void  CreateKMatrixInternal(Mat Kgg,int analysis_type,int sub_analysis_type);
-		void  CreateKMatrixBoundary(Mat Kgg,int analysis_type,int sub_analysis_type);
-		void  CreatePVector(Vec pg,  int analysis_type,int sub_analysis_type);
-		void  CreatePVectorInternal(Vec pg,int analysis_type,int sub_analysis_type);
-		void  CreatePVectorBoundary(Vec pg,int analysis_type,int sub_analysis_type);
-		void  PenaltyCreateKMatrix(Mat Kgg,double kmax,int analysis_type,int sub_analysis_type);
-		void  PenaltyCreatePVector(Vec pg,double kmax,int analysis_type,int sub_analysis_type);
-		/*}}}*/
-
-};
-
-#endif  /* _NUMERICALFLUX_H_ */
Index: /issm/trunk/src/c/objects/OptArgs.h
===================================================================
--- /issm/trunk/src/c/objects/OptArgs.h	(revision 3680)
+++ /issm/trunk/src/c/objects/OptArgs.h	(revision 3681)
@@ -3,6 +3,6 @@
  */ 
 
-#ifndef OPTARGS_H_
-#define OPTARGS_H_
+#ifndef _OPTARGS_H_
+#define _OPTARGS_H_
 
 #ifdef _SERIAL_
@@ -23,5 +23,5 @@
 };
 #else
-
+class Model;
 struct OptArgs{
 	Model* model;
Index: sm/trunk/src/c/objects/Pengrid.cpp
===================================================================
--- /issm/trunk/src/c/objects/Pengrid.cpp	(revision 3680)
+++ 	(revision )
@@ -1,712 +1,0 @@
-/*!\file Pengrid.c
- * \brief: implementation of the Pengrid object
- */
-
-
-#ifdef HAVE_CONFIG_H
-	#include "config.h"
-#else
-#error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
-#endif
-
-#include "stdio.h"
-#include "./Pengrid.h"
-#include <string.h>
-#include "../EnumDefinitions/EnumDefinitions.h"
-#include "../include/macros.h"
-#include "../shared/shared.h"
-#include "../include/typedefs.h"
-#include "../include/macros.h"
-#include "../DataSet/DataSet.h"
-#include "../DataSet/Inputs.h"
-	
-/*Object constructors and destructor*/
-/*FUNCTION Pengrid::constructor {{{1*/
-Pengrid::Pengrid(){
-	this->inputs=NULL;
-	this->parameters=NULL;
-	
-	/*not active, not zigzagging: */
-	active=0;
-	zigzag_counter=0;
-
-}
-/*}}}1*/
-/*FUNCTION Pengrid::Pengrid(int id, int node_ids int matpar_id){{{1*/
-Pengrid::Pengrid(int pengrid_id,int pengrid_node_id, int pengrid_element_id,int pengrid_matpar_id): 
-	hnode(&pengrid_node_id,1),
-	helement(&pengrid_element_id,1),
-	hmatpar(&pengrid_matpar_id,1)
-{
-
-	/*all the initialization has been done by the initializer, just fill in the id: */
-	this->id=pengrid_id;
-	this->parameters=NULL;
-	this->inputs=new Inputs();
-
-	/*not active, not zigzagging: */
-	active=0;
-	zigzag_counter=0;
-
-}
-/*}}}*/
-/*FUNCTION Pengrid::Pengrid(int id, Hook* hnodes, Hook* hmatice, Hook* hmatpar, Parameters* parameters, Inputs* pengrid_inputs) {{{1*/
-Pengrid::Pengrid(int pengrid_id,Hook* pengrid_hnode, Hook* pengrid_helement,Hook* pengrid_hmatpar, Parameters* pengrid_parameters, Inputs* pengrid_inputs):
-	hnode(pengrid_hnode),
-	helement(pengrid_helement),
-	hmatpar(pengrid_hmatpar)
-{
-
-	/*all the initialization has been done by the initializer, just fill in the id: */
-	this->id=pengrid_id;
-	if(pengrid_inputs){
-		this->inputs=(Inputs*)pengrid_inputs->Copy();
-	}
-	else{
-		this->inputs=new Inputs();
-	}
-	/*point parameters: */
-	this->parameters=pengrid_parameters;
-	
-	/*not active, not zigzagging: */
-	active=0;
-	zigzag_counter=0;
-
-}
-/*}}}*/
-/*FUNCTION Pengrid::Pengrid(int index, int id, IoModel* iomodel){{{1*/
-Pengrid::Pengrid(int id, int index, IoModel* iomodel){ //i is the element index
-
-	int i,j;
-	int pengrid_node_id;
-	int pengrid_matpar_id;
-	int pengrid_element_id;
-
-	/*id: */
-	this->id=id;
-	
-	/*hooks: */
-	pengrid_node_id=index+1;
-	pengrid_element_id=iomodel->singlenodetoelementconnectivity[index];
-	pengrid_matpar_id=iomodel->numberofelements+1; //refers to the constant material parameters object
-
-	this->hnode.Init(&pengrid_node_id,1);
-	this->helement.Init(&pengrid_element_id,1);
-	this->hmatpar.Init(&pengrid_matpar_id,1);
-
-	//initialize inputs: none needed
-	this->inputs=new Inputs();
-
-	//this->parameters: we still can't point to it, it may not even exist. Configure will handle this.
-	this->parameters=NULL;
-
-	//let's not forget internals
-	this->active=0;
-	this->zigzag_counter=0;
-
-}
-/*}}}*/
-/*FUNCTION Pengrid::destructor {{{1*/
-Pengrid::~Pengrid(){
-	return;
-}
-/*}}}1*/
-		
-/*Object management*/
-/*FUNCTION Pengrid::Configure {{{1*/
-void  Pengrid::Configure(DataSet* elementsin,DataSet* loadsin,DataSet* nodesin,DataSet* verticesin,DataSet* materialsin,Parameters* parametersin){
-
-	/*Take care of hooking up all objects for this load, ie links the objects in the hooks to their respective 
-	 * datasets, using internal ids and offsets hidden in hooks: */
-	hnode.configure(nodesin);
-	helement.configure(elementsin);
-	hmatpar.configure(materialsin);
-
-	/*point parameters to real dataset: */
-	this->parameters=parametersin;
-}
-/*}}}1*/
-/*FUNCTION Pengrid::copy {{{1*/
-Object* Pengrid::copy() {
-	return new Pengrid(this->id,&this->hnode,&this->helement,&this->hmatpar,this->parameters,this->inputs);
-}
-/*}}}1*/
-/*FUNCTION Pengrid::DeepEcho{{{1*/
-void Pengrid::DeepEcho(void){
-
-	printf("Pengrid:\n");
-	printf("   id: %i\n",id);
-	hnode.DeepEcho();
-	helement.DeepEcho();
-	hmatpar.DeepEcho();
-	printf("   active %i\n",this->active);
-	printf("   zigzag_counter %i\n",this->zigzag_counter);
-	printf("   parameters\n");
-	parameters->DeepEcho();
-	printf("   inputs\n");
-	inputs->DeepEcho();
-}
-/*}}}*/
-/*FUNCTION Pengrid::Demarshall {{{1*/
-void  Pengrid::Demarshall(char** pmarshalled_dataset){
-
-	char* marshalled_dataset=NULL;
-	int   i;
-
-	/*recover marshalled_dataset: */
-	marshalled_dataset=*pmarshalled_dataset;
-
-	/*this time, no need to get enum type, the pointer directly points to the beginning of the 
-	 *object data (thanks to DataSet::Demarshall):*/
-
-	memcpy(&id,marshalled_dataset,sizeof(id));marshalled_dataset+=sizeof(id);
-	memcpy(&active,marshalled_dataset,sizeof(active));marshalled_dataset+=sizeof(active);
-	memcpy(&zigzag_counter,marshalled_dataset,sizeof(zigzag_counter));marshalled_dataset+=sizeof(zigzag_counter);
-
-	/*demarshall hooks: */
-	hnode.Demarshall(&marshalled_dataset);
-	helement.Demarshall(&marshalled_dataset);
-	hmatpar.Demarshall(&marshalled_dataset);
-	
-	/*demarshall inputs: */
-	inputs=(Inputs*)DataSetDemarshallRaw(&marshalled_dataset); 
-
-	/*parameters: may not exist even yet, so let Configure handle it: */
-	this->parameters=NULL;
-
-	/*return: */
-	*pmarshalled_dataset=marshalled_dataset;
-	return;
-}
-/*}}}*/
-/*FUNCTION Pengrid::Echo {{{1*/
-void Pengrid::Echo(void){
-	this->DeepEcho();
-}
-/*}}}1*/
-/*FUNCTION Pengrid::Enum {{{1*/
-int Pengrid::Enum(void){
-
-	return PengridEnum;
-}
-/*}}}1*/
-/*FUNCTION Pengrid::Id {{{1*/
-int    Pengrid::Id(void){ return id; }
-/*}}}1*/
-/*FUNCTION Pengrid::Marshall {{{1*/
-void  Pengrid::Marshall(char** pmarshalled_dataset){
-
-	char* marshalled_dataset=NULL;
-	int   enum_type=0;
-	char* marshalled_inputs=NULL;
-	int   marshalled_inputs_size;
-
-	/*recover marshalled_dataset: */
-	marshalled_dataset=*pmarshalled_dataset;
-
-	/*get enum type of Tria: */
-	enum_type=PengridEnum;
-
-	/*marshall enum: */
-	memcpy(marshalled_dataset,&enum_type,sizeof(enum_type));marshalled_dataset+=sizeof(enum_type);
-
-	/*marshall Tria data: */
-	memcpy(marshalled_dataset,&id,sizeof(id));marshalled_dataset+=sizeof(id);
-	memcpy(marshalled_dataset,&active,sizeof(active));marshalled_dataset+=sizeof(active);
-	memcpy(marshalled_dataset,&zigzag_counter,sizeof(zigzag_counter));marshalled_dataset+=sizeof(zigzag_counter);
-
-	/*Marshall hooks: */
-	hnode.Marshall(&marshalled_dataset);
-	helement.Marshall(&marshalled_dataset);
-	hmatpar.Marshall(&marshalled_dataset);
-
-	/*Marshall inputs: */
-	marshalled_inputs_size=inputs->MarshallSize();
-	marshalled_inputs=inputs->Marshall();
-	memcpy(marshalled_dataset,marshalled_inputs,marshalled_inputs_size*sizeof(char));
-	marshalled_dataset+=marshalled_inputs_size;
-
-	/*parameters: don't do anything about it. parameters are marshalled somewhere else!*/
-
-	xfree((void**)&marshalled_inputs);
-
-	*pmarshalled_dataset=marshalled_dataset;
-	return;
-}
-/*}}}*/
-/*FUNCTION Pengrid::MarshallSize {{{1*/
-int   Pengrid::MarshallSize(){
-	
-	return sizeof(id)
-		+sizeof(active)
-		+sizeof(zigzag_counter)
-		+hnode.MarshallSize()
-		+helement.MarshallSize()
-		+hmatpar.MarshallSize()
-		+inputs->MarshallSize()
-		+sizeof(int); //sizeof(int) for enum type
-}
-/*}}}*/
-/*FUNCTION Pengrid::MyRank {{{1*/
-int    Pengrid::MyRank(void){ 
-	extern int my_rank;
-	return my_rank; 
-}
-/*}}}1*/
-
-/*Object functions*/
-/*FUNCTION Pengrid::CreateKMatrix {{{1*/
-
-void  Pengrid::CreateKMatrix(Mat Kgg,int analysis_type,int sub_analysis_type){
-
-	/*No loads applied, do nothing: */
-	return;
-
-}
-/*}}}1*/
-/*FUNCTION Pengrid::CreatePVector {{{1*/
-void  Pengrid::CreatePVector(Vec pg,  int analysis_type,int sub_analysis_type){
-
-	/*No loads applied, do nothing: */
-	return;
-
-}
-/*}}}1*/
-/*FUNCTION Pengrid::DistributenumDofs {{{1*/
-void  Pengrid::DistributeNumDofs(int* numdofpernode,int analysis_type,int sub_analysis_type){return;}
-/*}}}1*/
-/*FUNCTION Pengrid::GetDofList {{{1*/
-void  Pengrid::GetDofList(int* doflist,int* pnumberofdofspernode){
-
-	int i,j;
-	int doflist_per_node[MAXDOFSPERNODE];
-	int numberofdofspernode;
-
-	/*dynamic objects pointed to by hooks: */
-	Node* node=NULL;
-
-	/*recover objects from hooks: */
-	node=(Node*)hnode.delivers();
-	
-	node->GetDofList(&doflist_per_node[0],&numberofdofspernode);
-	for(j=0;j<numberofdofspernode;j++){
-		doflist[j]=doflist_per_node[j];
-	}
-
-	/*Assign output pointers:*/
-	*pnumberofdofspernode=numberofdofspernode;
-
-}
-/*}}}*/
-/*FUNCTION Pengrid::PenaltyConstrain {{{1*/
-void  Pengrid::PenaltyConstrain(int* punstable,int analysis_type,int sub_analysis_type){
-
-	if ((analysis_type==DiagnosticAnalysisEnum) && ((sub_analysis_type==StokesAnalysisEnum))){
-
-		/*No penalty to check*/
-		return;
-
-	}
-	else if (analysis_type==ThermalAnalysisEnum){
-		
-		PenaltyConstrainThermal(punstable,analysis_type,sub_analysis_type);
-		
-	}
-	else if (analysis_type==MeltingAnalysisEnum){
-			
-		/*No penalty to check*/
-		return;
-
-	}
-	else{
-		ISSMERROR("%s%i%s%i%s","analysis: ",analysis_type," and sub_analysis_type: ",sub_analysis_type," not supported yet");
-	}
-
-}
-/*}}}1*/
-/*FUNCTION Pengrid::PenaltyConstrainThermal {{{1*/
-void  Pengrid::PenaltyConstrainThermal(int* punstable,int analysis_type,int sub_analysis_type){
-
-	//   The penalty is stable if it doesn't change during to successive iterations.   
-
-	int    found=0;
-	const int numgrids=1;
-	double pressure;
-	double temperature;
-	double beta,t_pmp;
-	double meltingpoint;
-	int    new_active;
-	int    unstable=0;
-	int    reset_penalties=0;
-	int    stabilize_constraints;
-
-	/*pointers: */
-	Node* node=NULL;
-	Penta* penta=NULL;
-	Matpar*  matpar=NULL;
-	
-	/*check that pengrid is not a clone (penalty to be added only once)*/
-	if (node->IsClone()){
-		unstable=0;
-		*punstable=unstable;
-		return;
-	}
-
-	/*recover pointers: */
-	node=(Node*)hnode.delivers();
-	penta=(Penta*)helement.delivers();
-	matpar=(Matpar*)hmatpar.delivers();
-
-	//First recover pressure and temperature values, using the element: */
-	penta->inputs->GetParameterValue(&pressure,node,PressureEnum);
-	penta->inputs->GetParameterValue(&temperature,node,TemperatureEnum);
-
-	//Recover our data:
-	inputs->GetParameterValue(&reset_penalties,ResetPenaltiesEnum);
-	meltingpoint=matpar->GetMeltingPoint();
-	beta=matpar->GetBeta();
-	parameters->FindParam(&stabilize_constraints,StabilizeConstraintsEnum);
-	
-	if(reset_penalties)zigzag_counter=0;
-
-	//Compute pressure melting point
-	t_pmp=meltingpoint-beta*pressure;
-
-	//Figure out if temperature is over melting_point, in which case, this penalty needs to be activated.
-
-	if (temperature>t_pmp){
-		new_active=1;
-	}
-	else{
-		new_active=0;
-	}
-
-
-	//Figure out stability of this penalty
-	if (active==new_active){
-		unstable=0;
-	}
-	else{
-		unstable=1;
-		if(stabilize_constraints)zigzag_counter++;
-	}
-
-	/*If penalty keeps zigzagging more than 5 times: */
-	if(stabilize_constraints){
-		if(zigzag_counter>stabilize_constraints){
-			unstable=0;
-			active=1;
-		}
-	}
-
-	//Set penalty flag
-	active=new_active;
-
-	//*Assign output pointers:*/
-	*punstable=unstable;
-}
-/*}}}1*/
-/*FUNCTION Pengrid::PenaltyCreateMatrix {{{1*/
-void  Pengrid::PenaltyCreateKMatrix(Mat Kgg,double kmax,int analysis_type,int sub_analysis_type){
-
-	if ((analysis_type==DiagnosticAnalysisEnum) && ((sub_analysis_type==StokesAnalysisEnum))){
-
-		PenaltyCreateKMatrixDiagnosticStokes( Kgg,kmax,analysis_type,sub_analysis_type);
-	}
-	else if (analysis_type==ThermalAnalysisEnum){
-		
-		PenaltyCreateKMatrixThermal( Kgg,kmax,analysis_type,sub_analysis_type);
-		
-	}
-	else if (analysis_type==MeltingAnalysisEnum){
-			
-		PenaltyCreateKMatrixMelting( Kgg,kmax,analysis_type,sub_analysis_type);
-
-	}
-	else{
-		ISSMERROR("%s%i%s%i%s","analysis: ",analysis_type," and sub_analysis_type: ",sub_analysis_type," not supported yet");
-	}
-
-}
-/*}}}1*/
-/*FUNCTION Pengrid::PenaltyCreateKMatrixDiagnosticStokes {{{1*/
-void  Pengrid::PenaltyCreateKMatrixDiagnosticStokes(Mat Kgg,double kmax,int analysis_type,int sub_analysis_type){
-	
-	const int numgrids=1;
-	const int NDOF4=4;
-	const int numdof=numgrids*NDOF4;
-	int       doflist[numdof];
-	int       numberofdofspernode;
-
-	int dofs1[1]={0};
-	int dofs2[1]={1};
-	double slope[2];
-	int found=0;
-	double Ke[4][4]={0.0};
-	double penalty_offset;
-
-	/*pointers: */
-	Node* node=NULL;
-	Penta* penta=NULL;
-
-	/*Get dof list: */
-	GetDofList(&doflist[0],&numberofdofspernode);
-
-	/*recover pointers: */
-	node=(Node*)hnode.delivers();
-	penta=(Penta*)helement.delivers();
-
-	//recover slope: */
-	penta->inputs->GetParameterValue(&slope[0],node,BedSlopexEnum);
-	penta->inputs->GetParameterValue(&slope[1],node,BedSlopeyEnum);
-	
-	/*recover parameters: */
-	parameters->FindParam(&penalty_offset,PenaltyOffsetEnum);
-
-	//Create elementary matrix: add penalty to contrain wb (wb=ub*db/dx+vb*db/dy)
-	Ke[2][0]=-slope[0]*kmax*pow((double)10.0,penalty_offset);
-	Ke[2][1]=-slope[1]*kmax*pow((double)10.0,penalty_offset);
-	Ke[2][2]=kmax*pow((double)10,penalty_offset);
-	
-	/*Add Ke to global matrix Kgg: */
-	MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)Ke,ADD_VALUES);
-}
-/*}}}1*/
-/*FUNCTION Pengrid::PenaltyCreateKMatrixMelting {{{1*/
-void  Pengrid::PenaltyCreateKMatrixMelting(Mat Kgg,double kmax,int analysis_type,int sub_analysis_type){
-
-
-	int found=0;
-	const int numgrids=1;
-	const int NDOF1=1;
-	const int numdof=numgrids*NDOF1;
-	double Ke[numdof][numdof]={0.0};
-	int     dofs1[1]={0};
-	int       doflist[numdof];
-	int      numberofdofspernode;
-	double  meltingpoint;
-
-	double pressure;
-	double temperature;
-	double beta,t_pmp;
-	double penalty_offset;
-
-	/*pointers: */
-	Node* node=NULL;
-	Penta* penta=NULL;
-	Matpar*  matpar=NULL;
-
-	/*recover pointers: */
-	node=(Node*)hnode.delivers();
-	penta=(Penta*)helement.delivers();
-	matpar=(Matpar*)hmatpar.delivers();
-
-	/*check that pengrid is not a clone (penalty to be added only once)*/
-	if (node->IsClone()) return;
-
-	//First recover pressure and temperature values, using the element: */
-	penta->inputs->GetParameterValue(&pressure,node,PressureEnum);
-	penta->inputs->GetParameterValue(&temperature,node,TemperatureEnum);
-
-	/*recover parameters: */
-	parameters->FindParam(&penalty_offset,PenaltyOffsetEnum);
-
-	/*Get dof list: */
-	GetDofList(&doflist[0],&numberofdofspernode);
-	
-	//Compute pressure melting point
-	meltingpoint=matpar->GetMeltingPoint();
-	beta=matpar->GetBeta();
-	t_pmp=meltingpoint-beta*pressure;
-
-	//Add penalty load
-	if (temperature<t_pmp){ //If T<Tpmp, there must be no melting. Therefore, melting should be  constrained to 0 when T<Tpmp, instead of using spcs, use penalties
-		Ke[0][0]=kmax*pow((double)10,penalty_offset);
-	}
-	
-	MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)Ke,ADD_VALUES);
-}
-/*}}}1*/
-/*FUNCTION Pengrid::PenaltyCreateKMatrixThermal {{{1*/
-void  Pengrid::PenaltyCreateKMatrixThermal(Mat Kgg,double kmax,int analysis_type,int sub_analysis_type){
-
-	int found=0;
-	
-	const int numgrids=1;
-	const int NDOF1=1;
-	const int numdof=numgrids*NDOF1;
-	double Ke[numdof][numdof];
-	int       doflist[numdof];
-	int       numberofdofspernode;
-	double    penalty_offset;
-
-	if(!this->active)return;
-
-	/*recover parameters: */
-	parameters->FindParam(&penalty_offset,PenaltyOffsetEnum);
-
-	/*Get dof list: */
-	GetDofList(&doflist[0],&numberofdofspernode);
-
-	Ke[0][0]=kmax*pow((double)10,penalty_offset);
-	
-	/*Add Ke to global matrix Kgg: */
-	MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)Ke,ADD_VALUES);
-}
-/*}}}1*/
-/*FUNCTION Pengrid::PenaltyCreatePVector {{{1*/
-void  Pengrid::PenaltyCreatePVector(Vec pg,double kmax,int analysis_type,int sub_analysis_type){
-
-	if (analysis_type==ThermalAnalysisEnum){
-		
-		PenaltyCreatePVectorThermal( pg,kmax,analysis_type,sub_analysis_type);
-		
-	}
-	else if (analysis_type==MeltingAnalysisEnum){
-			
-		PenaltyCreatePVectorMelting( pg,kmax,analysis_type,sub_analysis_type);
-
-	}
-	else if (analysis_type==DiagnosticAnalysisEnum){
-
-		/*No loads applied, do nothing: */
-		return;
-
-	}
-	else{
-		ISSMERROR("%s%i%s%i%s","analysis: ",analysis_type," and sub_analysis_type: ",sub_analysis_type," not supported yet");
-	}
-
-}
-/*}}}1*/
-/*FUNCTION Pengrid::PenaltyCreatePVectorMelting {{{1*/
-void  Pengrid::PenaltyCreatePVectorMelting(Vec pg, double kmax,int analysis_type,int sub_analysis_type){
-	
-	const int numgrids=1;
-	const int NDOF1=1;
-	const int numdof=numgrids*NDOF1;
-	int    doflist[numdof];
-	double P_terms[numdof]={0.0};
-	int    numberofdofspernode;
-	int    found=0;
-	int    dofs1[1]={0};
-	double pressure;
-	double temperature;
-	double melting_offset;
-	double meltingpoint;
-	double beta, heatcapacity;
-	double latentheat;
-	double t_pmp;
-	double dt,penalty_offset;
-
-	/*pointers: */
-	Node* node=NULL;
-	Penta* penta=NULL;
-	Matpar*  matpar=NULL;
-
-	/*recover pointers: */
-	node=(Node*)hnode.delivers();
-	penta=(Penta*)helement.delivers();
-	matpar=(Matpar*)hmatpar.delivers();
-
-	/*check that pengrid is not a clone (penalty to be added only once)*/
-	if (node->IsClone()) return;
-
-	/*Get dof list: */
-	GetDofList(&doflist[0],&numberofdofspernode);
-
-	//First recover pressure and temperature values, using the element: */
-	penta->inputs->GetParameterValue(&pressure,node,PressureEnum);
-	penta->inputs->GetParameterValue(&temperature,node,TemperatureEnum);
-	inputs->GetParameterValue(&melting_offset,MeltingOffsetEnum);
-	parameters->FindParam(&dt,DtEnum);
-	parameters->FindParam(&penalty_offset,PenaltyOffsetEnum);
-
-	meltingpoint=matpar->GetMeltingPoint();
-	beta=matpar->GetBeta();
-	heatcapacity=matpar->GetHeatCapacity();
-	latentheat=matpar->GetLatentHeat();
-
-	//Compute pressure melting point
-	t_pmp=meltingpoint-beta*pressure;
-
-	//Add penalty load
-	//This time, the penalty must have the same value as the one used for the thermal computation
-	//so that the corresponding melting can be computed correctly
-	//In the thermal computation, we used kmax=melting_offset, and the same penalty_offset
-	if (temperature<t_pmp){ //%no melting
-		P_terms[0]=0;
-	}
-	else{
-		if (dt){
-			P_terms[0]=melting_offset*pow((double)10,penalty_offset)*(temperature-t_pmp)/dt;
-		}
-		else{
-			P_terms[0]=melting_offset*pow((double)10,penalty_offset)*(temperature-t_pmp);
-		}
-	}
-
-	/*Add P_terms to global vector pg: */
-	VecSetValues(pg,numdof,doflist,(const double*)P_terms,ADD_VALUES);
-}
-/*}}}1*/
-/*FUNCTION Pengrid::PenaltyCreatePVectorThermal {{{1*/
-void  Pengrid::PenaltyCreatePVectorThermal(Vec pg,  double kmax,int analysis_type,int sub_analysis_type){
-
-	const int numgrids=1;
-	const int NDOF1=1;
-	const int numdof=numgrids*NDOF1;
-	int       doflist[numdof];
-	double  P_terms[numdof]={0.0};
-	int    numberofdofspernode;
-	int    found=0;
-	double pressure;
-	int dofs1[1]={0};
-	double meltingpoint;
-	double beta;
-	double t_pmp;
-	double penalty_offset;
-
-	/*pointers: */
-	Node* node=NULL;
-	Penta* penta=NULL;
-	Matpar*  matpar=NULL;
-
-	/*recover pointers: */
-	node=(Node*)hnode.delivers();
-	penta=(Penta*)helement.delivers();
-	matpar=(Matpar*)hmatpar.delivers();
-
-	if(!this->active)return;
-
-	/*Get dof list: */
-	GetDofList(&doflist[0],&numberofdofspernode);
-
-	//First recover pressure  and penalty_offset
-	penta->inputs->GetParameterValue(&pressure,node,PressureEnum);
-	parameters->FindParam(&penalty_offset,PenaltyOffsetEnum);
-
-	//Compute pressure melting point
-	meltingpoint=matpar->GetMeltingPoint();
-	beta=matpar->GetBeta();
-	t_pmp=meltingpoint-beta*pressure;
-
-	//Add penalty load
-	P_terms[0]=kmax*pow((double)10,penalty_offset)*t_pmp;
-
-	/*Add P_terms to global vector pg: */
-	VecSetValues(pg,numdof,doflist,(const double*)P_terms,ADD_VALUES);
-}
-/*}}}1*/
-
-/*Updates: */
-/*FUNCTION Pengrid::UpdateFromDakota {{{1*/
-void  Pengrid::UpdateFromDakota(void* inputs){
-	ISSMERROR("not supported yet!");
-}
-/*}}}1*/
-/*FUNCTION Pengrid::UpdateInputs {{{1*/
-void  Pengrid::UpdateInputs(double* solution, int analysis_type, int sub_analysis_type){
-	ISSMERROR("not supported yet!");
-}
-/*}}}1*/
Index: sm/trunk/src/c/objects/Pengrid.h
===================================================================
--- /issm/trunk/src/c/objects/Pengrid.h	(revision 3680)
+++ 	(revision )
@@ -1,80 +1,0 @@
-/*!\file Pengrid.h
- * \brief: header file for pengrid object */
-
-#ifndef _PENGRID_H_
-#define _PENGRID_H_
-
-/*Headers:*/
-/*{{{1*/
-#include "./Load.h"
-#include "./Node.h"
-#include "./Element.h"
-#include "./Matpar.h"
-
-class Element;
-/*}}}*/
-
-class Pengrid: public Load{
-
-	private: 
-
-		int		id;
-		
-		Hook hnode;  //hook to 1 node
-		Hook helement;  //hook to 1 element
-		Hook hmatpar; //hook to 1 matpar
-
-		Parameters* parameters; //pointer to solution parameters
-		Inputs*  inputs;
-	
-		/*internals: */
-		int active;
-		int zigzag_counter;
-
-	public:
-
-		/*FUNCTION constructors, destructors {{{1*/
-		Pengrid();
-		Pengrid(int pengrid_id,int pengrid_node_id, int pengrid_element_id,int pengrid_matpar_id);
-		Pengrid(int pengrid_id,Hook* pengrid_hnode, Hook* pengrid_helement,Hook* pengrid_hmatpar, Parameters* pengrid_parameters, Inputs* pengrid_inputs);
-		Pengrid(int index, int id, IoModel* iomodel);
-		~Pengrid();
-		/*}}}*/
-		/*FUNCTION object management {{{1*/
-		void  Configure(DataSet* elementsin,DataSet* loadsin,DataSet* nodesin,DataSet* verticesin,DataSet* materialsin,Parameters* parametersin);
-		Object* copy();
-		void  DeepEcho();
-		void  Demarshall(char** pmarshalled_dataset);
-		void  Echo();
-		int   Enum();
-		int   Id(); 
-		void  Marshall(char** pmarshalled_dataset);
-		int   MarshallSize();
-		int   MyRank();
-		/*}}}*/
-		/*FUNCTION element numerical routines {{{1*/
-		void  DistributeNumDofs(int* numdofspernode,int analysis_type,int sub_analysis_type);
-		void  CreateKMatrix(Mat Kgg,int analysis_type,int sub_analysis_type);
-		void  CreatePVector(Vec pg, int analysis_type,int sub_analysis_type);
-		void  PenaltyCreateKMatrix(Mat Kgg,double kmax,int analysis_type,int sub_analysis_type);
-		void  PenaltyCreatePVector(Vec pg,double kmax,int analysis_type,int sub_analysis_type);
-		void  PenaltyCreateKMatrixDiagnosticStokes(Mat Kgg,double kmax,int analysis_type,int sub_analysis_type);
-		void  GetDofList(int* doflist,int* pnumberofdofspernode);
-		void  PenaltyCreateKMatrixThermal(Mat Kgg,double kmax,int analysis_type,int sub_analysis_type);
-		void  PenaltyCreateKMatrixMelting(Mat Kgg,double kmax,int analysis_type,int sub_analysis_type);
-		void  MatparConfiguration(Matpar* matpar,int matpar_offset);
-		void  PenaltyCreatePVectorThermal(Vec pg, double kmax,int analysis_type,int sub_analysis_type);
-		void  PenaltyCreatePVectorMelting(Vec pg, double kmax,int analysis_type,int sub_analysis_type);
-		void  PenaltyConstrain(int* punstable,int analysis_type,int sub_analysis_type);
-		void  PenaltyConstrainThermal(int* punstable,int analysis_type,int sub_analysis_type);
-		
-		/*updates:*/
-		void  UpdateFromDakota(void* inputs);
-		void  UpdateInputs(double* solution, int analysis_type, int sub_analysis_type);
-		/*}}}*/
-
-};
-
-#endif  /* _PENGRID_H_ */
-
-
Index: sm/trunk/src/c/objects/Penpair.cpp
===================================================================
--- /issm/trunk/src/c/objects/Penpair.cpp	(revision 3680)
+++ 	(revision )
@@ -1,194 +1,0 @@
-/*!\file Penpair.c
- * \brief: implementation of the Penpair object
- */
-
-
-#ifdef HAVE_CONFIG_H
-	#include "config.h"
-#else
-#error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
-#endif
-
-#include "stdio.h"
-#include "./Penpair.h"
-#include <string.h>
-#include "../EnumDefinitions/EnumDefinitions.h"
-#include "../include/macros.h"
-#include "../shared/shared.h"
-#include "../include/typedefs.h"
-
-		
-/*Object constructors and destructor*/
-/*FUNCTION Penpair::constructor {{{1*/
-Penpair::Penpair(){
-	return;
-}
-/*}}}1*/
-/*FUNCTION Penpair::creation {{{1*/
-Penpair::Penpair(int penpair_id, int* penpair_node_ids):
-	hnodes(penpair_node_ids,2)
-{
-
-	/*all the initialization has been done by the initializer, just fill in the id: */
-	this->id=penpair_id;
-	
-	return;
-}
-/*}}}1*/
-/*FUNCTION Penpair::creation {{{1*/
-Penpair::Penpair(int penpair_id, Hook* penpair_hnodes):
-	hnodes(penpair_hnodes)
-{
-
-	/*all the initialization has been done by the initializer, just fill in the id: */
-	this->id=penpair_id;
-	
-	return;
-}
-/*}}}1*/
-/*FUNCTION Penpair::destructor {{{1*/
-Penpair::~Penpair(){
-	return;
-}
-/*}}}1*/
-		
-/*Object marshall*/
-/*FUNCTION Penpair::Configure {{{1*/
-void  Penpair::Configure(DataSet* elementsin,DataSet* loadsin,DataSet* nodesin,DataSet* verticesin,DataSet* materialsin,Parameters* parametersin){
-
-	/*Take care of hooking up all objects for this element, ie links the objects in the hooks to their respective 
-	 * datasets, using internal ids and offsets hidden in hooks: */
-	hnodes.configure(nodesin);
-
-}
-/*}}}1*/
-/*FUNCTION Penpair::copy {{{1*/
-Object* Penpair::copy() {
-	return new Penpair(this->id,&this->hnodes); 
-}
-/*}}}1*/
-/*FUNCTION Penpair::DeepEcho {{{1*/
-void Penpair::DeepEcho(void){
-
-	printf("Penpair:\n");
-	printf("   id: %i\n",id);
-	hnodes.DeepEcho();
-
-	return;
-}		
-/*}}}1*/
-/*FUNCTION Penpair::Echo {{{1*/
-void Penpair::Echo(void){
-
-	int i;
-
-	printf("Penpair:\n");
-	printf("   id: %i\n",id);
-	hnodes.Echo();
-	
-	return;
-}
-/*}}}1*/
-/*FUNCTION Penpair::Marshall {{{1*/
-void  Penpair::Marshall(char** pmarshalled_dataset){
-
-	char* marshalled_dataset=NULL;
-	int   enum_type=0;
-
-	/*recover marshalled_dataset: */
-	marshalled_dataset=*pmarshalled_dataset;
-
-	/*get enum type of Penpair: */
-	enum_type=PenpairEnum;
-	
-	/*marshall enum: */
-	memcpy(marshalled_dataset,&enum_type,sizeof(enum_type));marshalled_dataset+=sizeof(enum_type);
-	
-	/*marshall Penpair data: */
-	memcpy(marshalled_dataset,&id,sizeof(id));marshalled_dataset+=sizeof(id);
-
-	/*Marshall hooks*/
-	hnodes.Marshall(&marshalled_dataset);
-
-	*pmarshalled_dataset=marshalled_dataset;
-	return;
-}
-/*}}}1*/
-/*FUNCTION Penpair::MarshallSize {{{1*/
-int   Penpair::MarshallSize(){
-
-	return sizeof(id)+
-		+hnodes.MarshallSize()
-		+sizeof(int); //sizeof(int) for enum type
-}
-/*}}}1*/
-/*FUNCTION Penpair::Demarshall {{{1*/
-void  Penpair::Demarshall(char** pmarshalled_dataset){
-
-	int i;
-	char* marshalled_dataset=NULL;
-
-	/*recover marshalled_dataset: */
-	marshalled_dataset=*pmarshalled_dataset;
-
-	/*this time, no need to get enum type, the pointer directly points to the beginning of the 
-	 *object data (thanks to DataSet::Demarshall):*/
-
-	memcpy(&id,marshalled_dataset,sizeof(id));marshalled_dataset+=sizeof(id);
-
-	/*demarshall hooks: */
-	hnodes.Demarshall(&marshalled_dataset);
-
-	/*return: */
-	*pmarshalled_dataset=marshalled_dataset;
-	return;
-}
-/*}}}1*/
-
-/*Object functions*/
-/*FUNCTION Penpair::CreateKMatrix {{{1*/
-
-void  Penpair::CreateKMatrix(Mat Kgg,int analysis_type,int sub_analysis_type){
-
-	/*No loads applied, do nothing: */
-	return;
-
-}
-/*}}}1*/
-/*FUNCTION Penpair::CreatePVector {{{1*/
-void  Penpair::CreatePVector(Vec pg, int analysis_type,int sub_analysis_type){
-
-	/*No loads applied, do nothing: */
-	return;
-
-}
-/*}}}1*/
-/*FUNCTION Penpair::Enum {{{1*/
-int Penpair::Enum(void){
-
-	return PenpairEnum;
-}
-/*}}}1*/
-/*FUNCTION Penpair::Id {{{1*/
-int    Penpair::Id(void){ return id; }
-/*}}}1*/
-/*FUNCTION Penpair::MyRank {{{1*/
-int    Penpair::MyRank(void){ 
-	extern int my_rank;
-	return my_rank; 
-}
-/*}}}1*/
-/*FUNCTION Penpair::PenaltyCreateKMatrix {{{1*/
-void  Penpair::PenaltyCreateKMatrix(Mat Kgg,double kmax,int analysis_type,int sub_analysis_type){
-	
-	/*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;
-}
-/*}}}1*/
-/*FUNCTION Penpair::PenaltyCreatePVector {{{1*/
-void  Penpair::PenaltyCreatePVector(Vec pg,double kmax,int analysis_type,int sub_analysis_type){
-	/*No loads applied, do nothing: */
-	return;
-}
-/*}}}1*/
Index: sm/trunk/src/c/objects/Penpair.h
===================================================================
--- /issm/trunk/src/c/objects/Penpair.h	(revision 3680)
+++ 	(revision )
@@ -1,50 +1,0 @@
-/*!\file Penpair.h
- * \brief: header file for penpair object */
-
-#ifndef _PENPAIR_H_
-#define _PENPAIR_H_
-
-/*Headers:*/
-/*{{{1*/
-#include "./Load.h"
-#include "./Node.h"
-#include "./Element.h"
-
-class Element;
-/*}}}*/
-
-class Penpair: public Load{
-
-	private: 
-
-		int		id;
-		
-		Hook hnodes;  //hook to 2 nodes
-
-	public:
-
-		Penpair();
-		Penpair(int penpair_id,int* penpair_node_ids);
-		Penpair(int penpair_id,Hook* penpair_hnodes);
-		~Penpair();
-
-		void  Echo();
-		void  DeepEcho();
-		void  Marshall(char** pmarshalled_dataset);
-		int   MarshallSize();
-		void  Demarshall(char** pmarshalled_dataset);
-		int   Enum();
-		int   Id(); 
-		int   MyRank();
-		void  Configure(DataSet* elements,DataSet* loads,DataSet* nodes,DataSet* vertices,DataSet* materials,Parameters* parameters);
-		void  CreateKMatrix(Mat Kgg,int analysis_type,int sub_analysis_type);
-		void  CreatePVector(Vec pg, int analysis_type,int sub_analysis_type);
-		void  PenaltyCreateKMatrix(Mat Kgg,double kmax,int analysis_type,int sub_analysis_type);
-		void  PenaltyCreatePVector(Vec pg,double kmax,int analysis_type,int sub_analysis_type);
-		Object* copy();
-
-};
-
-#endif  /* _PENPAIR_H_ */
-
-
Index: sm/trunk/src/c/objects/Penta.cpp
===================================================================
--- /issm/trunk/src/c/objects/Penta.cpp	(revision 3680)
+++ 	(revision )
@@ -1,4419 +1,0 @@
-/*!\file Penta.cpp
- * \brief: implementation of the Penta object
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#else
-#error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
-#endif
-
-#include "stdio.h"
-#include "./PentaVertexInput.h"
-#include "./Penta.h"
-#include <string.h>
-#include "../EnumDefinitions/EnumDefinitions.h"
-#include "../shared/shared.h"
-#include "../include/typedefs.h"
-#include "../include/macros.h"
-#include "../DataSet/DataSet.h"
-#include "../DataSet/Inputs.h"
-
-/*Object constructors and destructor*/
-/*FUNCTION Penta::Penta(){{{1*/
-Penta::Penta(){
-	this->inputs=NULL;
-	this->parameters=NULL;
-}
-/*}}}*/
-/*FUNCTION Penta::Penta(int penta_id,int* penta_node_ids, int penta_matice_id, int penta_matpar_id) {{{1*/
-Penta::Penta(int penta_id,int* penta_node_ids, int penta_matice_id, int penta_matpar_id):
-	hnodes(penta_node_ids,6),
-	hmatice(&penta_matice_id,1),
-	hmatpar(&penta_matpar_id,1)
-{
-
-	/*all the initialization has been done by the initializer, just fill in the id: */
-	this->id=penta_id;
-	this->parameters=NULL;
-	this->inputs=new Inputs();
-
-}
-/*}}}*/
-/*FUNCTION Penta::Penta(int id, Hook* hnodes, Hook* hmatice, Hook* hmatpar, Parameters* parameters, Inputs* penta_inputs) {{{1*/
-Penta::Penta(int penta_id,Hook* penta_hnodes, Hook* penta_hmatice, Hook* penta_hmatpar, Parameters* penta_parameters, Inputs* penta_inputs):
-	hnodes(penta_hnodes),
-	hmatice(penta_hmatice),
-	hmatpar(penta_hmatpar)
-{
-
-	/*all the initialization has been done by the initializer, just fill in the id: */
-	this->id=penta_id;
-	if(penta_inputs){
-		this->inputs=(Inputs*)penta_inputs->Copy();
-	}
-	else{
-		this->inputs=new Inputs();
-	}
-	/*point parameters: */
-	this->parameters=penta_parameters;
-}
-/*}}}*/
-/*FUNCTION Penta::Penta(int id, int index, IoModel* iomodel) {{{1*/
-Penta::Penta(int penta_id, int index, IoModel* iomodel){ //i is the element index
-
-	IssmInt i;
-	int penta_node_ids[6];
-	int penta_matice_id;
-	int penta_matpar_id;
-	double nodeinputs[6];
-	bool collapse;
-
-	/*id: */
-	this->id=penta_id;
-
-	/*hooks: */
-	for(i=0;i<6;i++){ //go recover node ids, needed to initialize the node hook.
-		penta_node_ids[i]=(int)*(iomodel->elements+6*index+i); //ids for vertices are in the elements array from Matlab
-	}
-	penta_matice_id=index+1; //refers to the corresponding ice material object
-	penta_matpar_id=iomodel->numberofelements+1; //refers to the constant material parameters object
-
-	this->hnodes.Init(&penta_node_ids[0],6);
-	this->hmatice.Init(&penta_matice_id,1);
-	this->hmatpar.Init(&penta_matpar_id,1);
-
-	//intialize inputs, and add as many inputs per element as requested: 
-	this->inputs=new Inputs();
-
-	if (iomodel->thickness) {
-		for(i=0;i<6;i++)nodeinputs[i]=iomodel->thickness[penta_node_ids[i]-1];
-		this->inputs->AddInput(new PentaVertexInput(ThicknessEnum,nodeinputs));
-	}
-	if (iomodel->surface) {
-		for(i=0;i<6;i++)nodeinputs[i]=iomodel->surface[penta_node_ids[i]-1];
-		this->inputs->AddInput(new PentaVertexInput(SurfaceEnum,nodeinputs));
-	}
-	if (iomodel->bed) {
-		for(i=0;i<6;i++)nodeinputs[i]=iomodel->bed[penta_node_ids[i]-1];
-		this->inputs->AddInput(new PentaVertexInput(BedEnum,nodeinputs));
-	}
-	if (iomodel->drag_coefficient) {
-		for(i=0;i<6;i++)nodeinputs[i]=iomodel->drag_coefficient[penta_node_ids[i]-1];
-		this->inputs->AddInput(new PentaVertexInput(DragCoefficientEnum,nodeinputs));
-
-		if (iomodel->drag_p) this->inputs->AddInput(new DoubleInput(DragPEnum,iomodel->drag_p[index]));
-		if (iomodel->drag_q) this->inputs->AddInput(new DoubleInput(DragQEnum,iomodel->drag_q[index]));
-		this->inputs->AddInput(new IntInput(DragTypeEnum,iomodel->drag_type));
-
-	}
-	if (iomodel->melting_rate) {
-		for(i=0;i<6;i++)nodeinputs[i]=iomodel->melting_rate[penta_node_ids[i]-1];
-		this->inputs->AddInput(new PentaVertexInput(MeltingRateEnum,nodeinputs));
-	}
-	if (iomodel->accumulation_rate) {
-		for(i=0;i<6;i++)nodeinputs[i]=iomodel->accumulation_rate[penta_node_ids[i]-1];
-		this->inputs->AddInput(new PentaVertexInput(AccumulationRateEnum,nodeinputs));
-	}
-	if (iomodel->geothermalflux) {
-		for(i=0;i<6;i++)nodeinputs[i]=iomodel->geothermalflux[penta_node_ids[i]-1];
-		this->inputs->AddInput(new PentaVertexInput(GeothermalFluxEnum,nodeinputs));
-	}	
-
-	if (iomodel->elementoniceshelf) this->inputs->AddInput(new BoolInput(ElementOnIceShelfEnum,(IssmBool)iomodel->elementoniceshelf[index]));
-	if (iomodel->elementonbed) this->inputs->AddInput(new BoolInput(ElementOnBedEnum,(IssmBool)iomodel->elementonbed[index]));
-	if (iomodel->elementonwater) this->inputs->AddInput(new BoolInput(ElementOnWaterEnum,(IssmBool)iomodel->elementonwater[index]));
-	if (iomodel->elementonsurface) this->inputs->AddInput(new BoolInput(ElementOnSurfaceEnum,(IssmBool)iomodel->elementonsurface[index]));
-
-	//elements of type 3 are macayeal type penta. we collapse the formulation on their base.
-	if(iomodel->elements_type){
-		if (*(iomodel->elements_type+2*i+0)==MacAyealFormulationEnum){ 
-			collapse=1;
-		}
-		else{
-			collapse=0;
-		}
-	}
-	this->inputs->AddInput(new BoolInput(CollapseEnum,(IssmBool)collapse));
-
-}
-/*}}}*/
-/*FUNCTION Penta::~Penta(){{{1*/
-Penta::~Penta(){
-	delete inputs;
-	this->parameters=NULL;
-}
-/*}}}*/
-
-/*Object management: */
-/*FUNCTION Penta::Configure {{{1*/
-void  Penta::Configure(DataSet* loadsin, DataSet* nodesin, DataSet* materialsin, Parameters* parametersin){
-
-	int i;
-
-	/*Take care of hooking up all objects for this element, ie links the objects in the hooks to their respective 
-	 * datasets, using internal ids and offsets hidden in hooks: */
-	hnodes.configure(nodesin);
-	hmatice.configure(materialsin);
-	hmatpar.configure(materialsin);
-
-	/*point parameters to real dataset: */
-	this->parameters=parametersin;
-
-}
-/*}}}*/
-/*FUNCTION copy {{{1*/
-Object* Penta::copy() {
-	return new Penta(this->id,&this->hnodes,&this->hmatice,&this->hmatpar,this->parameters,this->inputs);
-}
-/*}}}*/
-/*FUNCTION Demarshall {{{1*/
-void  Penta::Demarshall(char** pmarshalled_dataset){
-
-	char* marshalled_dataset=NULL;
-	int   i;
-
-	/*recover marshalled_dataset: */
-	marshalled_dataset=*pmarshalled_dataset;
-
-	/*this time, no need to get enum type, the pointer directly points to the beginning of the 
-	 *object data (thanks to DataSet::Demarshall):*/
-
-	memcpy(&id,marshalled_dataset,sizeof(id));marshalled_dataset+=sizeof(id);
-
-	/*demarshall hooks: */
-	hnodes.Demarshall(&marshalled_dataset);
-	hmatice.Demarshall(&marshalled_dataset);
-	hmatpar.Demarshall(&marshalled_dataset);
-
-	/*demarshall inputs: */
-	inputs=(Inputs*)DataSetDemarshallRaw(&marshalled_dataset); 
-
-	/*parameters: may not exist even yet, so let Configure handle it: */
-	this->parameters=NULL;
-
-	/*return: */
-	*pmarshalled_dataset=marshalled_dataset;
-	return;
-}
-/*}}}*/
-/*FUNCTION DeepEcho{{{1*/
-
-void Penta::DeepEcho(void){
-
-	printf("Penta:\n");
-	printf("   id: %i\n",id);
-	hnodes.DeepEcho();
-	hmatice.DeepEcho();
-	hmatpar.DeepEcho();
-	printf("   parameters\n");
-	parameters->DeepEcho();
-	printf("   inputs\n");
-	inputs->DeepEcho();
-
-	return;
-}
-/*}}}*/
-/*FUNCTION Echo{{{1*/
-
-void Penta::Echo(void){
-
-	printf("Penta:\n");
-	printf("   id: %i\n",id);
-	hnodes.Echo();
-	hmatice.Echo();
-	hmatpar.Echo();
-	printf("   parameters\n");
-	parameters->Echo();
-	printf("   inputs\n");
-	inputs->Echo();
-
-}
-/*}}}*/
-/*FUNCTION Enum {{{1*/
-int Penta::Enum(void){
-
-	return PentaEnum;
-
-}
-/*}}}*/
-/*FUNCTION Marshall {{{1*/
-void  Penta::Marshall(char** pmarshalled_dataset){
-
-	char* marshalled_dataset=NULL;
-	int   enum_type=0;
-	char* marshalled_inputs=NULL;
-	int   marshalled_inputs_size;
-
-	/*recover marshalled_dataset: */
-	marshalled_dataset=*pmarshalled_dataset;
-
-	/*get enum type of Penta: */
-	enum_type=PentaEnum;
-
-	/*marshall enum: */
-	memcpy(marshalled_dataset,&enum_type,sizeof(enum_type));marshalled_dataset+=sizeof(enum_type);
-
-	/*marshall Penta data: */
-	memcpy(marshalled_dataset,&id,sizeof(id));marshalled_dataset+=sizeof(id);
-
-	/*Marshall hooks: */
-	hnodes.Marshall(&marshalled_dataset);
-	hmatice.Marshall(&marshalled_dataset);
-	hmatpar.Marshall(&marshalled_dataset);
-
-	/*Marshall inputs: */
-	marshalled_inputs_size=inputs->MarshallSize();
-	marshalled_inputs=inputs->Marshall();
-	memcpy(marshalled_dataset,marshalled_inputs,marshalled_inputs_size*sizeof(char));
-	marshalled_dataset+=marshalled_inputs_size;
-
-	/*parameters: don't do anything about it. parameters are marshalled somewhere else!*/
-
-	xfree((void**)&marshalled_inputs);
-
-	*pmarshalled_dataset=marshalled_dataset;
-	return;
-}
-/*}}}*/
-/*FUNCTION MarshallSize {{{1*/
-int   Penta::MarshallSize(){
-	
-	return sizeof(id)
-		+hnodes.MarshallSize()
-		+hmatice.MarshallSize()
-		+hmatpar.MarshallSize()
-		+inputs->MarshallSize()
-		+sizeof(int); //sizeof(int) for enum type
-}
-/*}}}*/
-/*FUNCTION SpawnTria {{{1*/
-void*  Penta::SpawnTria(int g0, int g1, int g2){
-
-	/*out of grids g0,g1 and g2 from Penta, build a tria element: */
-	Tria* tria=NULL;
-	int indices[3];
-	int zero=0;
-	Hook* tria_hnodes=NULL;
-	Hook* tria_hmatice=NULL;
-	Hook* tria_hmatpar=NULL;
-	Parameters* tria_parameters=NULL;
-	Inputs* tria_inputs=NULL;
-
-	indices[0]=g0;
-	indices[1]=g1;
-	indices[2]=g2;
-
-	tria_hnodes =this->hnodes.Spawn(indices,3);
-	tria_hmatice=this->hmatice.Spawn(&zero,1);
-	tria_hmatpar=this->hmatpar.Spawn(&zero,1);
-	tria_parameters=this->parameters;
-	tria_inputs=(Inputs*)this->inputs->Spawn(indices,3);
-
-	tria=new Tria(this->id,tria_hnodes,tria_hmatice,tria_hmatpar,tria_parameters,tria_inputs);
-
-	delete tria_hnodes;
-	delete tria_hmatice;
-	delete tria_hmatpar;
-	delete tria_inputs;
-
-	return tria;
-}
-/*}}}*/
-
-/*updates: */
-/*FUNCTION UpdateFromDakota {{{1*/
-void  Penta::UpdateFromDakota(void* vinputs){
-
-	ISSMERROR("not supported yet!");
-
-}
-/*}}}*/
-/*FUNCTION Penta::UpdateInputs {{{1*/
-void  Penta::UpdateInputs(double* solution, int analysis_type, int sub_analysis_type){
-
-	/*Just branch to the correct UpdateInputs generator, according to the type of analysis we are carrying out: */
-	if (analysis_type==ControlAnalysisEnum){
-		
-		UpdateInputsDiagnosticHoriz( solution,analysis_type,sub_analysis_type);
-	}
-	else if (analysis_type==DiagnosticAnalysisEnum){
-	
-		if (sub_analysis_type==HorizAnalysisEnum){
-
-			UpdateInputsDiagnosticHoriz( solution,analysis_type,sub_analysis_type);
-		}
-		else ISSMERROR("%s%i%s\n","sub_analysis: ",sub_analysis_type," not supported yet");
-
-	}
-	else if (analysis_type==SlopecomputeAnalysisEnum){
-
-		UpdateInputsSlopeCompute( solution,analysis_type,sub_analysis_type);
-	}
-	else if (analysis_type==PrognosticAnalysisEnum){
-
-		UpdateInputsPrognostic( solution,analysis_type,sub_analysis_type);
-	}
-	else if (analysis_type==Prognostic2AnalysisEnum){
-
-		UpdateInputsPrognostic2(solution,analysis_type,sub_analysis_type);
-	}
-	else if (analysis_type==BalancedthicknessAnalysisEnum){
-
-		UpdateInputsBalancedthickness( solution,analysis_type,sub_analysis_type);
-	}
-	else if (analysis_type==Balancedthickness2AnalysisEnum){
-
-		UpdateInputsBalancedthickness2( solution,analysis_type,sub_analysis_type);
-	}
-	else if (analysis_type==BalancedvelocitiesAnalysisEnum){
-
-		UpdateInputsBalancedvelocities( solution,analysis_type,sub_analysis_type);
-	}
-	else{
-
-		ISSMERROR("%s%i%s\n","analysis: ",analysis_type," not supported yet");
-	}
-}
-/*Object functions*/
-/*FUNCTION Penta::UpdateInputsDiagnosticHoriz {{{1*/
-void  Penta::UpdateInputsDiagnosticHoriz(double* solution, int analysis_type, int sub_analysis_type){
-	
-	
-	int i;
-
-	const int    numvertices=6;
-	const int    numdofpervertex=2;
-	const int    numdof=numdofpervertex*numvertices;
-	
-	int          doflist[numdof];
-	double       values[numdof];
-	double       vx[numvertices];
-	double       vy[numvertices];
-
-	int          dummy;
-	
-	/*Get dof list: */
-	GetDofList(&doflist[0],&dummy);
-
-	/*Use the dof list to index into the solution vector: */
-	for(i=0;i<numdof;i++){
-		values[i]=solution[doflist[i]];
-	}
-
-	/*Ok, we have vx and vy in values, fill in vx and vy arrays: */
-	for(i=0;i<numvertices;i++){
-		vx[i]=values[i*numdofpervertex+0];
-		vy[i]=values[i*numdofpervertex+1];
-	}
-
-	/*Add vx and vy as inputs to the tria element: */
-	this->inputs->AddInput(new PentaVertexInput(VxEnum,vx));
-	this->inputs->AddInput(new PentaVertexInput(VyEnum,vy));
-}
-
-/*}}}*/
-/*FUNCTION Penta::UpdateInputsSlopeCompute {{{1*/
-void  Penta::UpdateInputsSlopeCompute(double* solution, int analysis_type, int sub_analysis_type){
-	ISSMERROR(" not supported yet!");
-}
-/*}}}*/
-/*FUNCTION Penta::UpdateInputsPrognostic {{{1*/
-void  Penta::UpdateInputsPrognostic(double* solution, int analysis_type, int sub_analysis_type){
-	ISSMERROR(" not supported yet!");
-}
-/*}}}*/
-/*FUNCTION Penta::UpdateInputsPrognostic2 {{{1*/
-void  Penta::UpdateInputsPrognostic2(double* solution, int analysis_type, int sub_analysis_type){
-	ISSMERROR(" not supported yet!");
-}
-/*}}}*/
-/*FUNCTION Penta::UpdateInputsBalancedthickness {{{1*/
-void  Penta::UpdateInputsBalancedthickness(double* solution, int analysis_type, int sub_analysis_type){
-	ISSMERROR(" not supported yet!");
-}
-/*}}}*/
-/*FUNCTION Penta::UpdateInputsBalancedthickness2 {{{1*/
-void  Penta::UpdateInputsBalancedthickness2(double* solution, int analysis_type, int sub_analysis_type){
-	ISSMERROR(" not supported yet!");
-}
-/*}}}*/
-/*FUNCTION Penta::UpdateInputsBalancedvelocities {{{1*/
-void  Penta::UpdateInputsBalancedvelocities(double* solution, int analysis_type, int sub_analysis_type){
-	ISSMERROR(" not supported yet!");
-}
-/*}}}*/
-
-/*Object functions*/
-/*FUNCTION ComputeBasalStress {{{1*/
-void  Penta::ComputeBasalStress(Vec sigma_b,int analysis_type,int sub_analysis_type){
-
-	int i,j;
-	const int numgrids=6;
-	int    doflist[numgrids];
-	double xyz_list[numgrids][3];
-	double xyz_list_tria[3][3];
-
-	/*Parameters*/
-	double rho_ice,gravity;
-	double surface_normal[3];
-	double bed_normal[3];
-	double bed;
-	double basalforce[3];
-	double epsilon[6]; /* epsilon=[exx,eyy,ezz,exy,exz,eyz];*/
-	double devstresstensor[6]; /* epsilon=[exx,eyy,ezz,exy,exz,eyz];*/
-	double stresstensor[6]={0.0};
-	double viscosity;
-
-	int  dofv[3]={0,1,2};
-	int  dofp[1]={3};
-	double Jdet2d;
-	Tria* tria=NULL;
-
-	/*Gauss*/
-	int     num_gauss,ig;
-	double* first_gauss_area_coord  =  NULL;
-	double* second_gauss_area_coord =  NULL;
-	double* third_gauss_area_coord  =  NULL;
-	double* gauss_weights           =  NULL;
-	double  gauss_weight;
-	double  gauss_coord[4];
-
-	/*Output*/
-	double pressure;
-	double sigma_xx,sigma_yy,sigma_zz;
-	double sigma_xy,sigma_xz,sigma_yz;
-	double surface=0;
-	double value=0;
-	
-	/*flags: */
-	bool onbed;
-
-	/*parameters: */
-	double stokesreconditioning;
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-	Matpar* matpar=NULL;
-	Matice* matice=NULL;
-
-	/*Check analysis_types*/
-	if (analysis_type!=DiagnosticAnalysisEnum || sub_analysis_type!=StokesAnalysisEnum) ISSMERROR("Not supported yet!");
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	matpar=(Matpar*)hmatpar.delivers();
-	matice=(Matice*)hmatice.delivers();
-
-	/*recover some inputs: */
-	inputs->GetParameterValue(&onbed,ElementOnBedEnum);
-
-	/*retrieve some parameters: */
-	this->parameters->FindParam(&stokesreconditioning,StokesReconditioningEnum);
-	
-	if(!onbed){
-		//put zero
-		VecSetValue(sigma_b,id-1,0.0,INSERT_VALUES);
-		return;
-	}
-
-	/*recovre material parameters: */
-	rho_ice=matpar->GetRhoIce();
-	gravity=matpar->GetG();
-
-	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
-	for(i=0;i<3;i++){
-		for(j=0;j<3;j++){
-			xyz_list_tria[i][j]=xyz_list[i][j];
-		}
-	}
-
-	/* Get gaussian points and weights (make this a statically initialized list of points? fstd): */
-	GaussTria(&num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights,2);
-
-	/* Start  looping on the number of gaussian points: */
-	for (ig=0; ig<num_gauss; ig++){
-
-			/*Pick up the gaussian point: */
-			gauss_weight=*(gauss_weights+ig);
-			gauss_coord[0]=*(first_gauss_area_coord+ig); 
-			gauss_coord[1]=*(second_gauss_area_coord+ig);
-			gauss_coord[2]=*(third_gauss_area_coord+ig);
-			gauss_coord[3]=-1.0; //take the base
-
-			/*Compute strain rate viscosity and pressure: */
-			inputs->GetStrainRateStokes(&epsilon[0],&xyz_list[0][0],gauss_coord,VxEnum,VyEnum,VzEnum);
-			matice->GetViscosity3dStokes(&viscosity,&epsilon[0]);
-			inputs->GetParameterValue(&pressure, &gauss_coord[0],PressureEnum);
-
-			/*Compute Stress*/
-			sigma_xx=viscosity*epsilon[0]-pressure*stokesreconditioning; // sigma = nu eps - pressure
-			sigma_yy=viscosity*epsilon[1]-pressure*stokesreconditioning;
-			sigma_zz=viscosity*epsilon[2]-pressure*stokesreconditioning;
-			sigma_xy=viscosity*epsilon[3];
-			sigma_xz=viscosity*epsilon[4];
-			sigma_yz=viscosity*epsilon[5];
-
-			/*Get normal vector to the bed */
-			SurfaceNormal(&surface_normal[0],xyz_list_tria);
-			bed_normal[0] = - surface_normal[0]; //Program is for surface, so the normal to the bed is the opposite of the result
-			bed_normal[1] = - surface_normal[1];
-			bed_normal[2] = - surface_normal[2];
-
-			/*basalforce*/
-			basalforce[0] += sigma_xx*bed_normal[0] + sigma_xy*bed_normal[1] + sigma_xz*bed_normal[2];
-			basalforce[1] += sigma_xy*bed_normal[0] + sigma_yy*bed_normal[1] + sigma_yz*bed_normal[2];
-			basalforce[2] += sigma_xz*bed_normal[0] + sigma_yz*bed_normal[1] + sigma_zz*bed_normal[2];
-
-			/*Get the Jacobian determinant */
-			tria->GetJacobianDeterminant3d(&Jdet2d, &xyz_list_tria[0][0],gauss_coord);
-			value+=sigma_zz*Jdet2d*gauss_weight;
-			surface+=Jdet2d*gauss_weight;
-	}
-	value=value/surface;
-
-	/*Add value to output*/
-	VecSetValue(sigma_b,id-1,(const double)value,INSERT_VALUES);
-}
-/*}}}*/
-/*FUNCTION ComputePressure {{{1*/
-void  Penta::ComputePressure(Vec pg,int analysis_type,int sub_analysis_type){
-
-	int i;
-	const int numgrids=6;
-	int    doflist[numgrids];
-	double pressure[numgrids];
-	double rho_ice,g;
-	double surface[numgrids];
-	double xyz_list[numgrids][3];
-	double gauss[numgrids][numgrids]={{1,0,0,0},{0,1,0,0},{0,0,1,0},{1,0,0,1},{0,1,0,1},{0,0,1,1}};
-
-	/*inputs: */
-	bool onwater;
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-	Matpar* matpar=NULL;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	matpar=(Matpar*)hmatpar.delivers();
-
-	/*retrieve inputs :*/
-	inputs->GetParameterValue(&onwater,ElementOnWaterEnum);
-
-	/*If on water, skip: */
-	if(onwater)return;
-
-	/*Get node data: */
-	GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
-
-	/*pressure is lithostatic: */
-	//md.pressure=md.rho_ice*md.g*(md.surface-md.z); a la matlab
-
-	/*Get dof list on which we will plug the pressure values: */
-	GetDofList1(&doflist[0]);
-
-	/*recover value of surface at grids: */
-	inputs->GetParameterValues(&surface[0],&gauss[0][0],6,SurfaceEnum);
-
-	/*pressure is lithostatic: */
-	rho_ice=matpar->GetRhoIce();
-	g=matpar->GetG();
-	for(i=0;i<numgrids;i++){
-		pressure[i]=rho_ice*g*(surface[i]-xyz_list[i][2]);
-	}
-
-	/*plug local pressure values into global pressure vector: */
-	VecSetValues(pg,numgrids,doflist,(const double*)pressure,INSERT_VALUES);
-
-}
-/*}}}*/
-/*FUNCTION ComputeStrainRate {{{1*/
-void  Penta::ComputeStrainRate(Vec eps,int analysis_type,int sub_analysis_type){
-
-	ISSMERROR("Not implemented yet");
-
-}
-/*}}}*/
-/*FUNCTION CostFunction {{{1*/
-double Penta::CostFunction(int analysis_type,int sub_analysis_type){
-
-	double J;
-	Tria* tria=NULL;
-
-	/*flags: */
-	bool onbed;
-	bool onwater;
-	bool collapse;
-	bool onsurface;
-
-	/*recover some inputs: */
-	inputs->GetParameterValue(&onbed,ElementOnBedEnum);
-	inputs->GetParameterValue(&onwater,ElementOnWaterEnum);
-	inputs->GetParameterValue(&collapse,CollapseEnum);
-	inputs->GetParameterValue(&onsurface,ElementOnSurfaceEnum);
-
-	/*If on water, return 0: */
-	if(onwater)return 0;
-
-	/*Bail out if this element if:
-	 * -> Non collapsed and not on the surface
-	 * -> collapsed (2d model) and not on bed) */
-	if ((!collapse && !onsurface) || (collapse && !onbed)){
-		return 0;
-	}
-	else if (collapse){
-
-		/*This element should be collapsed into a tria element at its base. Create this tria element, 
-		 * and compute CostFunction*/
-		tria=(Tria*)SpawnTria(0,1,2); //grids 0, 1 and 2 make the new tria (lower face).
-		J=tria->CostFunction(analysis_type,sub_analysis_type);
-		delete tria;
-		return J;
-	}
-	else{
-
-		tria=(Tria*)SpawnTria(3,4,5); //grids 3, 4 and 5 make the new tria (upper face).
-		J=tria->CostFunction(analysis_type,sub_analysis_type);
-		delete tria;
-		return J;
-	}
-}
-/*}}}*/
-/*FUNCTION CreateKMatrix {{{1*/
-
-void  Penta::CreateKMatrix(Mat Kgg,int analysis_type,int sub_analysis_type){
-
-	/*Just branch to the correct element stiffness matrix generator, according to the type of analysis we are carrying out: */
-	if (analysis_type==ControlAnalysisEnum){
-
-		CreateKMatrixDiagnosticHoriz( Kgg,analysis_type,sub_analysis_type);
-
-	}
-	else if (analysis_type==DiagnosticAnalysisEnum){
-
-		if (sub_analysis_type==HorizAnalysisEnum){
-
-			CreateKMatrixDiagnosticHoriz( Kgg,analysis_type,sub_analysis_type);
-		}
-		else if (sub_analysis_type==VertAnalysisEnum){
-
-			CreateKMatrixDiagnosticVert( Kgg,analysis_type,sub_analysis_type);
-		}
-		else if (sub_analysis_type==StokesAnalysisEnum){
-
-			CreateKMatrixDiagnosticStokes( Kgg,analysis_type,sub_analysis_type);
-
-		}
-		else ISSMERROR("%s%i%s\n","sub_analysis: ",sub_analysis_type," not supported yet");
-	}
-	else if (analysis_type==SlopecomputeAnalysisEnum){
-
-		CreateKMatrixSlopeCompute( Kgg,analysis_type,sub_analysis_type);
-	}
-	else if (analysis_type==PrognosticAnalysisEnum){
-
-		CreateKMatrixPrognostic( Kgg,analysis_type,sub_analysis_type);
-	}
-	else if (analysis_type==BalancedthicknessAnalysisEnum){
-
-		CreateKMatrixBalancedthickness( Kgg,analysis_type,sub_analysis_type);
-	}
-	else if (analysis_type==BalancedvelocitiesAnalysisEnum){
-
-		CreateKMatrixBalancedvelocities( Kgg,analysis_type,sub_analysis_type);
-	}
-	else if (analysis_type==ThermalAnalysisEnum){
-
-		CreateKMatrixThermal( Kgg,analysis_type,sub_analysis_type);
-	}
-	else if (analysis_type==MeltingAnalysisEnum){
-
-		CreateKMatrixMelting( Kgg,analysis_type,sub_analysis_type);
-	}
-	else{
-		ISSMERROR("%s%i%s\n","analysis: ",analysis_type," not supported yet");
-	}
-
-}
-/*}}}*/
-/*FUNCTION CreateKMatrixBalancedthickness {{{1*/
-
-void  Penta::CreateKMatrixBalancedthickness(Mat Kgg,int analysis_type,int sub_analysis_type){
-
-	/*Collapsed formulation: */
-	Tria*  tria=NULL;
-
-	/*flags: */
-	bool onwater;
-	bool onbed;
-
-	/*recover some inputs: */
-	inputs->GetParameterValue(&onwater,ElementOnWaterEnum);
-	inputs->GetParameterValue(&onbed,ElementOnBedEnum);
-
-	/*If on water, skip: */
-	if(onwater)return;
-
-	/*Is this element on the bed? :*/
-	if(!onbed)return;
-
-	/*Spawn Tria element from the base of the Penta: */
-	tria=(Tria*)SpawnTria(0,1,2); //grids 0, 1 and 2 make the new tria.
-	tria->CreateKMatrix(Kgg, analysis_type,sub_analysis_type);
-	delete tria;
-	return;
-
-}
-/*}}}*/
-/*FUNCTION CreateKMatrixBalancedvelocities {{{1*/
-
-void  Penta::CreateKMatrixBalancedvelocities(Mat Kgg,int analysis_type,int sub_analysis_type){
-
-	/*Collapsed formulation: */
-	Tria*  tria=NULL;
-
-	/*flags: */
-	bool onbed;
-	bool onwater;
-
-	/*recover some inputs: */
-	inputs->GetParameterValue(&onbed,ElementOnBedEnum);
-	inputs->GetParameterValue(&onwater,ElementOnWaterEnum);
-
-	/*If on water, skip: */
-	if(onwater)return;
-
-	/*Is this element on the bed? :*/
-	if(!onbed)return;
-
-	/*Spawn Tria element from the base of the Penta: */
-	tria=(Tria*)SpawnTria(0,1,2); //grids 0, 1 and 2 make the new tria.
-	tria->CreateKMatrix(Kgg,analysis_type,sub_analysis_type);
-	delete tria;
-	return;
-
-}
-/*}}}*/
-/*FUNCTION CreateKMatrixDiagnosticHoriz {{{1*/
-void Penta::CreateKMatrixDiagnosticHoriz( Mat Kgg,  int analysis_type,int sub_analysis_type){
-
-
-	/* local declarations */
-	int             i,j;
-
-	/* node data: */
-	const int    numgrids=6;
-	const int    numdof=2*numgrids;
-	double       xyz_list[numgrids][3];
-	int          doflist[numdof];
-	int          numberofdofspernode;
-
-
-	/* 3d gaussian points: */
-	int     num_gauss,ig;
-	double* first_gauss_area_coord  =  NULL;
-	double* second_gauss_area_coord =  NULL;
-	double* third_gauss_area_coord  =  NULL;
-	double* fourth_gauss_vert_coord  =  NULL;
-	double* area_gauss_weights           =  NULL;
-	double* vert_gauss_weights           =  NULL;
-	int     ig1,ig2;
-	double  gauss_weight1,gauss_weight2;
-	double  gauss_coord[4];
-	int     order_area_gauss;
-	int     num_vert_gauss;
-	int     num_area_gauss;
-	double  gauss_weight;
-
-	/* 2d gaussian point: */
-	int     num_gauss2d;
-	double* first_gauss_area_coord2d  =  NULL;
-	double* second_gauss_area_coord2d =  NULL;
-	double* third_gauss_area_coord2d  =  NULL;
-	double* gauss_weights2d=NULL;
-	double  gauss_l1l2l3[3];
-
-	/* material data: */
-	double viscosity; //viscosity
-	double oldviscosity; //viscosity
-	double newviscosity; //viscosity
-
-	/* strain rate: */
-	double epsilon[5]; /* epsilon=[exx,eyy,exy,exz,eyz];*/
-	double oldepsilon[5]; /* epsilon=[exx,eyy,exy,exz,eyz];*/
-
-	/* matrices: */
-	double B[5][numdof];
-	double Bprime[5][numdof];
-	double L[2][numdof];
-	double D[5][5]={0.0};            // material matrix, simple scalar matrix.
-	double D_scalar;
-	double DL[2][2]={0.0}; //for basal drag
-	double DL_scalar;
-
-	/* local element matrices: */
-	double Ke_gg[numdof][numdof]={0.0}; //local element stiffness matrix 
-
-	double Ke_gg_gaussian[numdof][numdof]; //stiffness matrix evaluated at the gaussian point.
-	double Ke_gg_drag_gaussian[numdof][numdof]; //stiffness matrix contribution from drag
-	double Jdet;
-
-	/*slope: */
-	double  slope[2]={0.0};
-	double  slope_magnitude;
-
-	/*friction: */
-	double  alpha2_list[3];
-	double  alpha2;
-
-	double MAXSLOPE=.06; // 6 %
-	double MOUNTAINKEXPONENT=10;
-
-	/*parameters: */
-	double viscosity_overshoot;
-
-	/*Collapsed formulation: */
-	Tria*  tria=NULL;
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-	Matice* matice=NULL;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	matice=(Matice*)hmatice.delivers();
-
-	/*inputs: */
-	bool onwater;
-	bool collapse;
-	bool onbed;
-	bool shelf;
-
-	/*retrieve inputs :*/
-	inputs->GetParameterValue(&onwater,ElementOnWaterEnum);
-	inputs->GetParameterValue(&collapse,CollapseEnum);
-	inputs->GetParameterValue(&onbed,ElementOnBedEnum);
-	inputs->GetParameterValue(&shelf,ElementOnIceShelfEnum);
-
-	/*retrieve some parameters: */
-	this->parameters->FindParam(&viscosity_overshoot,ViscosityOvershootEnum);
-
-	/*If on water, skip stiffness: */
-	if(onwater)return;
-
-	/*Figure out if this pentaelem is collapsed. If so, then bailout, except if it is at the 
-	  bedrock, in which case we spawn a tria element using the 3 first grids, and use it to build 
-	  the stiffness matrix. */
-
-
-	if ((collapse==1) && (onbed==0)){
-		/*This element should be collapsed, but this element is not on the bedrock, therefore all its 
-		 * dofs have already been frozen! Do nothing: */
-		return;
-	}
-	else if ((collapse==1) && (onbed==1)){
-
-		/*This element should be collapsed into a tria element at its base. Create this tria element, 
-		 *and use its CreateKMatrix functionality to fill the global stiffness matrix: */
-		tria=(Tria*)SpawnTria(0,1,2); //grids 0, 1 and 2 make the new tria.
-		tria->CreateKMatrix(Kgg, analysis_type,sub_analysis_type);
-		delete tria;
-		return;
-	}
-	else{
-
-		/*Implement standard penta element: */
-
-		/* Get node coordinates and dof list: */
-		GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
-		GetDofList(&doflist[0],&numberofdofspernode);
-
-
-		/*Get gaussian points and weights. Penta is an extrusion of a Tria, we therefore 
-		  get tria gaussian points as well as segment gaussian points. For tria gaussian 
-		  points, order of integration is 2, because we need to integrate the product tB*D*B' 
-		  which is a polynomial of degree 3 (see GaussTria for more details). For segment gaussian 
-		  points, same deal, which yields 3 gaussian points.*/
-
-		order_area_gauss=5;
-		num_vert_gauss=5;
-
-		GaussPenta( &num_area_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &area_gauss_weights, &fourth_gauss_vert_coord,&vert_gauss_weights,order_area_gauss,num_vert_gauss);
-
-		/* Start  looping on the number of gaussian points: */
-		for (ig1=0; ig1<num_area_gauss; ig1++){
-			for (ig2=0; ig2<num_vert_gauss; ig2++){
-
-				/*Pick up the gaussian point: */
-				gauss_weight1=*(area_gauss_weights+ig1);
-				gauss_weight2=*(vert_gauss_weights+ig2);
-				gauss_weight=gauss_weight1*gauss_weight2;
-
-
-				gauss_coord[0]=*(first_gauss_area_coord+ig1); 
-				gauss_coord[1]=*(second_gauss_area_coord+ig1);
-				gauss_coord[2]=*(third_gauss_area_coord+ig1);
-				gauss_coord[3]=*(fourth_gauss_vert_coord+ig2);
-
-
-				/*Get strain rate from velocity: */
-				inputs->GetStrainRate(&epsilon[0],&xyz_list[0][0],gauss_coord,VxEnum,VyEnum);
-				inputs->GetStrainRate(&oldepsilon[0],&xyz_list[0][0],gauss_coord,VxOldEnum,VyOldEnum);
-
-				/*Get viscosity: */
-				matice->GetViscosity3d(&viscosity, &epsilon[0]);
-				matice->GetViscosity3d(&oldviscosity, &oldepsilon[0]);
-
-				/*Get B and Bprime matrices: */
-				GetB(&B[0][0], &xyz_list[0][0], gauss_coord);
-				GetBPrime(&Bprime[0][0], &xyz_list[0][0], gauss_coord);
-
-				/* Get Jacobian determinant: */
-				GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss_coord);
-
-				/*Build the D matrix: we plug the gaussian weight, the viscosity, and the jacobian determinant 
-				  onto this scalar matrix, so that we win some computational time: */
-
-				newviscosity=viscosity+viscosity_overshoot*(viscosity-oldviscosity);
-				D_scalar=newviscosity*gauss_weight*Jdet;
-				for (i=0;i<5;i++){
-					D[i][i]=D_scalar;
-				}
-
-				/*  Do the triple product tB*D*Bprime: */
-				TripleMultiply( &B[0][0],5,numdof,1,
-							&D[0][0],5,5,0,
-							&Bprime[0][0],5,numdof,0,
-							&Ke_gg_gaussian[0][0],0);
-
-				/* Add the Ke_gg_gaussian, and optionally Ke_gg_gaussian onto Ke_gg: */
-				for( i=0; i<numdof; i++){
-					for(j=0;j<numdof;j++){
-						Ke_gg[i][j]+=Ke_gg_gaussian[i][j];
-					}
-				}
-			} //for (ig2=0; ig2<num_vert_gauss; ig2++)
-		} //for (ig1=0; ig1<num_area_gauss; ig1++)
-
-
-		/*Add Ke_gg to global matrix Kgg: */
-		MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)Ke_gg,ADD_VALUES);
-
-		//Deal with 2d friction at the bedrock interface
-		if((onbed && !shelf)){
-
-			/*Build a tria element using the 3 grids of the base of the penta. Then use 
-			 * the tria functionality to build a friction stiffness matrix on these 3
-			 * grids: */
-
-			tria=(Tria*)SpawnTria(0,1,2); //grids 0, 1 and 2 make the new tria.
-			tria->CreateKMatrixDiagnosticHorizFriction(Kgg,analysis_type,sub_analysis_type);
-			delete tria;
-		}
-
-	} 
-
-	xfree((void**)&first_gauss_area_coord);
-	xfree((void**)&second_gauss_area_coord);
-	xfree((void**)&third_gauss_area_coord);
-	xfree((void**)&fourth_gauss_vert_coord);
-	xfree((void**)&area_gauss_weights);
-	xfree((void**)&vert_gauss_weights);
-	xfree((void**)&first_gauss_area_coord2d);
-	xfree((void**)&second_gauss_area_coord2d);
-	xfree((void**)&third_gauss_area_coord2d);
-	xfree((void**)&gauss_weights2d);
-
-}
-/*}}}*/
-/*FUNCTION CreateKMatrixDiagnosticStokes {{{1*/
-void Penta::CreateKMatrixDiagnosticStokes( Mat Kgg,  int analysis_type,int sub_analysis_type){
-
-	int i,j;
-
-	const int numgrids=6;
-	const int DOFPERGRID=4;
-	const int numdof=numgrids*DOFPERGRID;
-	int doflist[numdof];
-	int numberofdofspernode;
-
-	const int numgrids2d=3;
-	const int numdof2d=numgrids2d*DOFPERGRID;
-
-	int   dofs[3]={0,1,2};
-
-	double K_terms[numdof][numdof]={0.0};
-
-	/*Material properties: */
-	double         gravity,rho_ice,rho_water;
-
-	/*Collapsed formulation: */
-	Tria*  tria=NULL;
-
-	/*Grid data: */
-	double        xyz_list[numgrids][3];
-
-	/*parameters: */
-	double		   xyz_list_tria[numgrids2d][3];
-	double		   surface_normal[3];
-	double		   bed_normal[3];
-	double         thickness;
-
-	/*matrices: */
-	double     Ke_temp[27][27]={0.0}; //for the six nodes and the bubble 
-	double     Ke_reduced[numdof][numdof]; //for the six nodes only
-	double     Ke_gaussian[27][27];
-	double     Ke_drag_gaussian[numdof2d][numdof2d];
-	double     B[8][27];
-	double     B_prime[8][27];
-	double     LStokes[14][numdof2d];
-	double     LprimeStokes[14][numdof2d];
-	double     Jdet;
-	double     Jdet2d;
-	double     D[8][8]={0.0};
-	double     D_scalar;
-	double     tBD[27][8];
-	double     DLStokes[14][14]={0.0};
-	double     tLDStokes[numdof2d][14];
-
-	/* gaussian points: */
-	int     num_area_gauss;
-	int     igarea,igvert;
-	double* first_gauss_area_coord  =  NULL;
-	double* second_gauss_area_coord =  NULL;
-	double* third_gauss_area_coord  =  NULL;
-	double* vert_gauss_coord = NULL;
-	double* area_gauss_weights  =  NULL;
-	double* vert_gauss_weights  =  NULL;
-	double  gaussgrids[numgrids][numgrids]={{1,0,0,0},{0,1,0,0},{0,0,1,0},{1,0,0,1},{0,1,0,1},{0,0,1,1}};
-
-	/* specific gaussian point: */
-	double  gauss_weight,area_gauss_weight,vert_gauss_weight;
-	double  gauss_coord[4];
-	double  gauss_coord_tria[3];
-	int area_order=5;
-	int	num_vert_gauss=5;
-
-	double  epsilon[6]; /* epsilon=[exx,eyy,ezz,exy,exz,eyz];*/
-	double  viscosity;
-	double  alpha2_list[numgrids2d];
-	double  alpha2_gauss;
-
-	double  vx_list[numgrids];
-	double  vy_list[numgrids];
-	double  vz_list[numgrids];
-	double  thickness_list[numgrids];
-	double  bed_list[numgrids];
-	double  dragcoefficient_list[numgrids];
-	double  drag_p,drag_q;
-
-	/*parameters: */
-	double stokesreconditioning;
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-	Matpar* matpar=NULL;
-	Matice* matice=NULL;
-
-	/*inputs: */
-	bool onwater;
-	bool onbed;
-	bool shelf;
-
-	/*retrieve inputs :*/
-	inputs->GetParameterValue(&onwater,ElementOnWaterEnum);
-	inputs->GetParameterValue(&onbed,ElementOnBedEnum);
-	inputs->GetParameterValue(&shelf,ElementOnIceShelfEnum);
-
-	/*If on water, skip stiffness: */
-	if(onwater)return;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	matpar=(Matpar*)hmatpar.delivers();
-	matice=(Matice*)hmatice.delivers();
-
-
-	/*recovre material parameters: */
-	rho_water=matpar->GetRhoWater();
-	rho_ice=matpar->GetRhoIce();
-	gravity=matpar->GetG();
-
-	/*retrieve some parameters: */
-	this->parameters->FindParam(&stokesreconditioning,StokesReconditioningEnum);
-
-	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
-	GetDofList(&doflist[0],&numberofdofspernode);
-
-	/* Get gaussian points and weights. Penta is an extrusion of a Tria, we therefore 
-		get tria gaussian points as well as segment gaussian points. For tria gaussian 
-		points, order of integration is 2, because we need to integrate the product tB*D*B' 
-		which is a polynomial of degree 3 (see GaussTria for more details). For segment gaussian 
-		points, same deal, which yields 3 gaussian points.*/
-
-	area_order=5;
-	num_vert_gauss=5;
-
-	/* Get gaussian points and weights (make this a statically initialized list of points? fstd): */
-	GaussPenta( &num_area_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &area_gauss_weights,&vert_gauss_coord, &vert_gauss_weights, area_order, num_vert_gauss);
-
-	/* Start  looping on the number of gaussian points: */
-	for (igarea=0; igarea<num_area_gauss; igarea++){
-		for (igvert=0; igvert<num_vert_gauss; igvert++){
-			/*Pick up the gaussian point: */
-			area_gauss_weight=*(area_gauss_weights+igarea);
-			vert_gauss_weight=*(vert_gauss_weights+igvert);
-			gauss_weight=area_gauss_weight*vert_gauss_weight;
-			gauss_coord[0]=*(first_gauss_area_coord+igarea); 
-			gauss_coord[1]=*(second_gauss_area_coord+igarea);
-			gauss_coord[2]=*(third_gauss_area_coord+igarea);
-			gauss_coord[3]=*(vert_gauss_coord+igvert);
-
-			/*Compute strain rate: */
-			inputs->GetStrainRateStokes(&epsilon[0],&xyz_list[0][0],gauss_coord,VxEnum,VyEnum,VzEnum);
-
-			/*Get viscosity: */
-			matice->GetViscosity3dStokes(&viscosity,&epsilon[0]);
-
-			/*Get B and Bprime matrices: */
-			GetBStokes(&B[0][0],&xyz_list[0][0],gauss_coord); 
-			GetBprimeStokes(&B_prime[0][0],&xyz_list[0][0], gauss_coord); 
-
-			/* Get Jacobian determinant: */
-			GetJacobianDeterminant(&Jdet, &xyz_list[0][0],&gauss_coord[0]);
-
-			/* Build the D matrix: we plug the gaussian weight, the thickness, the viscosity, and the jacobian determinant 
-			 * onto this scalar matrix, so that we win some computational time: */
-			D_scalar=gauss_weight*Jdet;
-			for (i=0;i<6;i++){
-				D[i][i]=D_scalar*viscosity;
-			}
-			for (i=6;i<8;i++){
-				D[i][i]=-D_scalar*stokesreconditioning;
-			}
-
-			/*  Do the triple product tB*D*Bprime: */
-			MatrixMultiply(&B[0][0],8,27,1,&D[0][0],8,8,0,&tBD[0][0],0);
-			MatrixMultiply(&tBD[0][0],27,8,0,&B_prime[0][0],8,27,0,&Ke_gaussian[0][0],0);
-
-			/*Add Ke_gaussian and Ke_gaussian to terms in pKe. Watch out for column orientation from matlab: */
-			for(i=0;i<27;i++){
-				for(j=0;j<27;j++){
-					Ke_temp[i][j]+=Ke_gaussian[i][j];
-				}
-			}
-		}
-	}
-
-	if((onbed==1) && (shelf==0)){
-
-		/*Build alpha2_list used by drag stiffness matrix*/
-		Friction* friction=NewFriction();
-
-		/*Initialize all fields: */
-		friction->element_type=(char*)xmalloc((strlen("2d")+1)*sizeof(char));
-		strcpy(friction->element_type,"2d");
-
-		inputs->GetParameterValues(&vx_list[0],&gaussgrids[0][0],6,VxEnum);
-		inputs->GetParameterValues(&vy_list[0],&gaussgrids[0][0],6,VyEnum);
-		inputs->GetParameterValues(&vz_list[0],&gaussgrids[0][0],6,VzEnum);
-		inputs->GetParameterValues(&dragcoefficient_list[0],&gaussgrids[0][0],6,DragCoefficientEnum);
-		inputs->GetParameterValues(&bed_list[0],&gaussgrids[0][0],6,BedEnum);
-		inputs->GetParameterValues(&thickness_list[0],&gaussgrids[0][0],6,ThicknessEnum);
-		inputs->GetParameterValue(&drag_p,DragPEnum);
-		inputs->GetParameterValue(&drag_q,DragQEnum);
-
-		friction->gravity=matpar->GetG();
-		friction->rho_ice=matpar->GetRhoIce();
-		friction->rho_water=matpar->GetRhoWater();
-		friction->K=&dragcoefficient_list[0];
-		friction->bed=&bed_list[0];
-		friction->thickness=&thickness_list[0];
-		friction->vx=&vx_list[0];
-		friction->vy=&vy_list[0];
-		friction->vz=&vz_list[0];
-		friction->p=drag_p;
-		friction->q=drag_q;
-
-		/*Compute alpha2_list: */
-		FrictionGetAlpha2(&alpha2_list[0],friction);
-
-		/*Erase friction object: */
-		DeleteFriction(&friction);
-
-		for(i=0;i<numgrids2d;i++){
-			for(j=0;j<3;j++){
-				xyz_list_tria[i][j]=xyz_list[i][j];
-			}
-		}
-
-		xfree((void**)&first_gauss_area_coord); xfree((void**)&second_gauss_area_coord); xfree((void**)&third_gauss_area_coord); xfree((void**)&area_gauss_weights);
-		GaussTria (&num_area_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &area_gauss_weights, 2);
-
-		/* Start looping on the number of gauss 2d (nodes on the bedrock) */
-		for (igarea=0; igarea<num_area_gauss; igarea++){
-			gauss_weight=*(area_gauss_weights+igarea);
-			gauss_coord[0]=*(first_gauss_area_coord+igarea); 
-			gauss_coord[1]=*(second_gauss_area_coord+igarea);
-			gauss_coord[2]=*(third_gauss_area_coord+igarea);
-			gauss_coord[3]=-1;
-
-			gauss_coord_tria[0]=*(first_gauss_area_coord+igarea); 
-			gauss_coord_tria[1]=*(second_gauss_area_coord+igarea);
-			gauss_coord_tria[2]=*(third_gauss_area_coord+igarea);
-
-			/*Get the Jacobian determinant */
-			tria->GetJacobianDeterminant3d(&Jdet2d, &xyz_list_tria[0][0], gauss_coord_tria);
-
-			/*Get L matrix if viscous basal drag present: */
-			GetLStokes(&LStokes[0][0],  gauss_coord_tria);
-			GetLprimeStokes(&LprimeStokes[0][0], &xyz_list[0][0], gauss_coord_tria, gauss_coord);
-
-			/*Compute strain rate: */
-			inputs->GetStrainRateStokes(&epsilon[0],&xyz_list[0][0],gauss_coord,VxEnum,VyEnum,VzEnum);
-
-			/*Get viscosity at last iteration: */
-			matice->GetViscosity3dStokes(&viscosity,&epsilon[0]);
-
-			/*Get normal vecyor to the bed */
-			SurfaceNormal(&surface_normal[0],xyz_list_tria);
-
-			bed_normal[0]=-surface_normal[0]; //Program is for surface, so the normal to the bed is the opposite of the result
-			bed_normal[1]=-surface_normal[1];
-			bed_normal[2]=-surface_normal[2];
-
-			/*Calculate DL on gauss point */
-			tria->GetParameterValue(&alpha2_gauss,&alpha2_list[0],gauss_coord_tria);
-
-			DLStokes[0][0]=alpha2_gauss*gauss_weight*Jdet2d;
-			DLStokes[1][1]=alpha2_gauss*gauss_weight*Jdet2d;
-			DLStokes[2][2]=-alpha2_gauss*gauss_weight*Jdet2d*bed_normal[0]*bed_normal[2];
-			DLStokes[3][3]=-alpha2_gauss*gauss_weight*Jdet2d*bed_normal[1]*bed_normal[2];
-			DLStokes[4][4]=-alpha2_gauss*gauss_weight*Jdet2d*bed_normal[0]*bed_normal[2];
-			DLStokes[5][5]=-alpha2_gauss*gauss_weight*Jdet2d*bed_normal[1]*bed_normal[2];
-			DLStokes[6][6]=-viscosity*gauss_weight*Jdet2d*bed_normal[0];
-			DLStokes[7][7]=-viscosity*gauss_weight*Jdet2d*bed_normal[1];
-			DLStokes[8][8]=-viscosity*gauss_weight*Jdet2d*bed_normal[2];
-			DLStokes[9][8]=-viscosity*gauss_weight*Jdet2d*bed_normal[0]/2.0;
-			DLStokes[10][10]=-viscosity*gauss_weight*Jdet2d*bed_normal[1]/2.0;
-			DLStokes[11][11]=stokesreconditioning*gauss_weight*Jdet2d*bed_normal[0];
-			DLStokes[12][12]=stokesreconditioning*gauss_weight*Jdet2d*bed_normal[1];
-			DLStokes[13][13]=stokesreconditioning*gauss_weight*Jdet2d*bed_normal[2];
-
-			/*  Do the triple product tL*D*L: */
-			MatrixMultiply(&LStokes[0][0],14,numdof2d,1,&DLStokes[0][0],14,14,0,&tLDStokes[0][0],0);
-			MatrixMultiply(&tLDStokes[0][0],numdof2d,14,0,&LprimeStokes[0][0],14,numdof2d,0,&Ke_drag_gaussian[0][0],0);
-
-			for(i=0;i<numdof2d;i++){
-				for(j=0;j<numdof2d;j++){
-					Ke_temp[i][j]+=Ke_drag_gaussian[i][j];
-				}
-			}
-		}
-	} //if ( (onbed==1) && (shelf==0))
-
-	/*Reduce the matrix */
-	ReduceMatrixStokes(&Ke_reduced[0][0], &Ke_temp[0][0]);
-
-	for(i=0;i<numdof;i++){
-		for(j=0;j<numdof;j++){
-			K_terms[i][j]+=Ke_reduced[i][j];
-		}
-	}
-
-	/*Add Ke_gg to global matrix Kgg: */
-	MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)K_terms,ADD_VALUES);
-
-
-	/*Free ressources:*/
-	xfree((void**)&first_gauss_area_coord);
-	xfree((void**)&second_gauss_area_coord);
-	xfree((void**)&third_gauss_area_coord);
-	xfree((void**)&area_gauss_weights);
-	xfree((void**)&vert_gauss_coord);
-	xfree((void**)&vert_gauss_weights);
-
-	return;
-}
-/*}}}*/
-/*FUNCTION CreateKMatrixDiagnosticVert {{{1*/
-void Penta::CreateKMatrixDiagnosticVert( Mat Kgg,  int analysis_type,int sub_analysis_type){
-
-	/* local declarations */
-	int             i,j;
-
-	/* node data: */
-	const int    numgrids=6;
-	const int    NDOF1=1;
-	const int    numdof=NDOF1*numgrids;
-	double       xyz_list[numgrids][3];
-	int          doflist[numdof];
-	int          numberofdofspernode;
-
-	/* 3d gaussian points: */
-	int     num_gauss,ig;
-	double* first_gauss_area_coord  =  NULL;
-	double* second_gauss_area_coord =  NULL;
-	double* third_gauss_area_coord  =  NULL;
-	double* fourth_gauss_vert_coord  =  NULL;
-	double* area_gauss_weights           =  NULL;
-	double* vert_gauss_weights           =  NULL;
-	int     ig1,ig2;
-	double  gauss_weight1,gauss_weight2;
-	double  gauss_coord[4];
-	int     order_area_gauss;
-	int     num_vert_gauss;
-	int     num_area_gauss;
-	double  gauss_weight;
-
-	/* matrices: */
-	double  Ke_gg[numdof][numdof]={0.0};
-	double  Ke_gg_gaussian[numdof][numdof];
-	double  Jdet;
-	double  B[NDOF1][numgrids];
-	double  Bprime[NDOF1][numgrids];
-	double  DL_scalar;
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-
-	/*Collapsed formulation: */
-	Tria*  tria=NULL;
-
-	/*inputs: */
-	bool onwater; 
-	bool onsurface;
-
-	/*retrieve inputs :*/
-	inputs->GetParameterValue(&onwater,ElementOnWaterEnum);
-	inputs->GetParameterValue(&onsurface,ElementOnSurfaceEnum);
-
-	/*If on water, skip stiffness: */
-	if(onwater)return;
-
-	/*If this element  is on the surface, we have a dynamic boundary condition that applies, as a stiffness 
-	 * matrix: */
-	if(onsurface){
-		tria=(Tria*)SpawnTria(3,4,5); //nodes 3,4 and 5 are on the surface
-		tria->CreateKMatrixDiagnosticSurfaceVert(Kgg, analysis_type,sub_analysis_type);
-		delete tria;
-	}
-
-	/*Now, onto the formulation for the vertical velocity: */
-
-	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
-	GetDofList(&doflist[0],&numberofdofspernode);
-
-
-	/*Get gaussian points and weights. Penta is an extrusion of a Tria, we therefore 
-	  get tria gaussian points as well as segment gaussian points. For tria gaussian 
-	  points, order of integration is 2, because we need to integrate the product tB*D*B' 
-	  which is a polynomial of degree 3 (see GaussTria for more details). For segment gaussian 
-	  points, same deal, which yields 3 gaussian points.*/
-
-	order_area_gauss=2;
-	num_vert_gauss=2;
-
-	GaussPenta( &num_area_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &area_gauss_weights, &fourth_gauss_vert_coord,&vert_gauss_weights,order_area_gauss,num_vert_gauss);
-
-	/* Start  looping on the number of gaussian points: */
-	for (ig1=0; ig1<num_area_gauss; ig1++){
-		for (ig2=0; ig2<num_vert_gauss; ig2++){
-
-			/*Pick up the gaussian point: */
-			gauss_weight1=*(area_gauss_weights+ig1);
-			gauss_weight2=*(vert_gauss_weights+ig2);
-			gauss_weight=gauss_weight1*gauss_weight2;
-
-			gauss_coord[0]=*(first_gauss_area_coord+ig1); 
-			gauss_coord[1]=*(second_gauss_area_coord+ig1);
-			gauss_coord[2]=*(third_gauss_area_coord+ig1);
-			gauss_coord[3]=*(fourth_gauss_vert_coord+ig2);
-
-			/*Get B and Bprime matrices: */
-			GetB_vert(&B[0][0], &xyz_list[0][0], gauss_coord);
-			GetBPrime_vert(&Bprime[0][0], &xyz_list[0][0], gauss_coord);
-
-			/* Get Jacobian determinant: */
-			GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss_coord);
-			DL_scalar=gauss_weight*Jdet;
-
-			/*  Do the triple product tB*D*Bprime: */
-			TripleMultiply( &B[0][0],1,numgrids,1,
-						&DL_scalar,1,1,0,
-						&Bprime[0][0],1,numgrids,0,
-						&Ke_gg_gaussian[0][0],0);
-
-			/* Add the Ke_gg_gaussian, and optionally Ke_gg_drag_gaussian onto Ke_gg: */
-			for( i=0; i<numdof; i++){
-				for(j=0;j<numdof;j++){
-					Ke_gg[i][j]+=Ke_gg_gaussian[i][j];
-				}
-			}	
-		} //for (ig2=0; ig2<num_vert_gauss; ig2++)
-	} //for (ig1=0; ig1<num_area_gauss; ig1++)
-
-	/*Add Ke_gg to global matrix Kgg: */
-	MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)Ke_gg,ADD_VALUES);
-
-	xfree((void**)&first_gauss_area_coord);
-	xfree((void**)&second_gauss_area_coord);
-	xfree((void**)&third_gauss_area_coord);
-	xfree((void**)&fourth_gauss_vert_coord);
-	xfree((void**)&area_gauss_weights);
-	xfree((void**)&vert_gauss_weights);
-}
-/*}}}*/
-/*FUNCTION CreateKMatrixMelting {{{1*/
-void  Penta::CreateKMatrixMelting(Mat Kgg,int analysis_type,int sub_analysis_type){
-
-	Tria* tria=NULL;
-
-	/*inputs: */
-	bool onwater;
-	bool onbed;
-
-	/*retrieve inputs :*/
-	inputs->GetParameterValue(&onwater,ElementOnWaterEnum);
-	inputs->GetParameterValue(&onbed,ElementOnBedEnum);
-
-	/*If on water, skip: */
-	if(onwater)return;
-
-	if (!onbed){
-		return;
-	}
-	else{
-
-		tria=(Tria*)SpawnTria(0,1,2); //grids 0, 1 and 2 make the new tria.
-		tria->CreateKMatrixMelting(Kgg, analysis_type,sub_analysis_type);
-		delete tria;
-		return;
-	}
-}
-/*}}}*/
-/*FUNCTION CreateKMatrixPrognostic {{{1*/
-
-void  Penta::CreateKMatrixPrognostic(Mat Kgg,int analysis_type,int sub_analysis_type){
-
-	/*Collapsed formulation: */
-	Tria*  tria=NULL;
-
-	/*inputs: */
-	bool onwater;
-	bool onbed;
-
-	/*retrieve inputs :*/
-	inputs->GetParameterValue(&onwater,ElementOnWaterEnum);
-	inputs->GetParameterValue(&onbed,ElementOnBedEnum);
-
-	/*If on water, skip: */
-	if(onwater)return;
-
-	/*Is this element on the bed? :*/
-	if(!onbed)return;
-
-	/*Spawn Tria element from the base of the Penta: */
-	tria=(Tria*)SpawnTria(0,1,2); //grids 0, 1 and 2 make the new tria.
-	tria->CreateKMatrix(Kgg, analysis_type,sub_analysis_type);
-	delete tria;
-	return;
-
-}
-/*}}}*/
-/*FUNCTION CreateKMatrixSlopeCompute {{{1*/
-
-void  Penta::CreateKMatrixSlopeCompute(Mat Kgg,int analysis_type,int sub_analysis_type){
-
-	/*Collapsed formulation: */
-	Tria*  tria=NULL;
-
-	/*inputs: */
-	bool onwater;
-	bool onbed;
-
-	/*retrieve inputs :*/
-	inputs->GetParameterValue(&onwater,ElementOnWaterEnum);
-	inputs->GetParameterValue(&onbed,ElementOnBedEnum);
-
-
-	/*If on water, skip: */
-	if(onwater)return;
-
-	/*Is this element on the bed? :*/
-	if(!onbed)return;
-
-	/*Spawn Tria element from the base of the Penta: */
-	tria=(Tria*)SpawnTria(0,1,2); //grids 0, 1 and 2 make the new tria.
-	tria->CreateKMatrix(Kgg, analysis_type,sub_analysis_type);
-	delete tria;
-	return;
-
-}
-/*}}}*/
-/*FUNCTION CreateKMatrixThermal {{{1*/
-void  Penta::CreateKMatrixThermal(Mat Kgg,int analysis_type,int sub_analysis_type){
-
-	/* local declarations */
-	int i,j;
-	int found=0;
-
-	/* node data: */
-	const int    numgrids=6;
-	const int    NDOF1=1;
-	const int    numdof=NDOF1*numgrids;
-	double xyz_list[numgrids][3];
-	int    doflist[numdof];
-	int    numberofdofspernode;
-
-	/* gaussian points: */
-	int     num_area_gauss,igarea,igvert;
-	double* first_gauss_area_coord  =  NULL;
-	double* second_gauss_area_coord =  NULL;
-	double* third_gauss_area_coord  =  NULL;
-	double* vert_gauss_coord = NULL;
-	double* area_gauss_weights  =  NULL;
-	double* vert_gauss_weights  =  NULL;
-	double  gauss_weight,area_gauss_weight,vert_gauss_weight;
-	double  gauss_coord[4];
-	double  gauss_l1l2l3[3];
-
-	int area_order=5;
-	int num_vert_gauss=5;
-
-	int     dofs[3]={0,1,2};
-	double  K[2][2]={0.0};
-
-	double  u,v,w;
-
-	/*matrices: */
-	double     K_terms[numdof][numdof]={0.0};
-	double     Ke_gaussian_conduct[numdof][numdof];
-	double     Ke_gaussian_advec[numdof][numdof];
-	double     Ke_gaussian_artdiff[numdof][numdof];
-	double     Ke_gaussian_transient[numdof][numdof];
-	double     B[3][numdof];
-	double     Bprime[3][numdof];
-	double     B_conduct[3][numdof];
-	double     B_advec[3][numdof];
-	double     B_artdiff[2][numdof];
-	double     Bprime_advec[3][numdof];
-	double     L[numdof];
-	double     D_scalar;
-	double     D[3][3];
-	double     l1l2l3[3];
-	double     tl1l2l3D[3];
-	double     tBD[3][numdof];
-	double     tBD_conduct[3][numdof];
-	double     tBD_advec[3][numdof];
-	double     tBD_artdiff[3][numdof];
-	double     tLD[numdof];
-
-	double     Jdet;
-
-	/*Material properties: */
-	double     gravity,rho_ice,rho_water;
-	double     heatcapacity,thermalconductivity;
-	double     mixed_layer_capacity,thermal_exchange_velocity;
-
-	/*parameters: */
-	double dt,artdiff,epsvel;
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-	Matpar* matpar=NULL;
-
-	/*Collapsed formulation: */
-	Tria*  tria=NULL;
-
-
-	/*inputs: */
-	bool onwater;
-	bool onbed;
-	bool shelf;
-
-	/*retrieve inputs :*/
-	inputs->GetParameterValue(&onwater,ElementOnWaterEnum);
-	inputs->GetParameterValue(&onbed,ElementOnBedEnum);
-	inputs->GetParameterValue(&shelf,ElementOnIceShelfEnum);
-
-	/*If on water, skip: */
-	if(onwater)return;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	matpar=(Matpar*)hmatpar.delivers();
-
-	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
-	GetDofList(&doflist[0],&numberofdofspernode);
-
-	// /*recovre material parameters: */
-	rho_water=matpar->GetRhoWater();
-	rho_ice=matpar->GetRhoIce();
-	gravity=matpar->GetG();
-	heatcapacity=matpar->GetHeatCapacity();
-	thermalconductivity=matpar->GetThermalConductivity();
-
-	/*retrieve some parameters: */
-	this->parameters->FindParam(&dt,DtEnum);
-	this->parameters->FindParam(&artdiff,ArtDiffEnum);
-	this->parameters->FindParam(&epsvel,EpsVelEnum);
-
-	/* Get gaussian points and weights. Penta is an extrusion of a Tria, we therefore 
-		get tria gaussian points as well as segment gaussian points. For tria gaussian 
-		points, order of integration is 2, because we need to integrate the product tB*D*B' 
-		which is a polynomial of degree 3 (see GaussTria for more details). For segment gaussian 
-		points, same deal, which yields 3 gaussian points.: */
-
-	/*Get gaussian points: */
-	area_order=2;
-	num_vert_gauss=2;
-
-	GaussPenta( &num_area_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &area_gauss_weights,&vert_gauss_coord, &vert_gauss_weights, area_order, num_vert_gauss);
-
-	/* Start  looping on the number of gaussian points: */
-	for (igarea=0; igarea<num_area_gauss; igarea++){
-		for (igvert=0; igvert<num_vert_gauss; igvert++){
-			/*Pick up the gaussian point: */
-			area_gauss_weight=*(area_gauss_weights+igarea);
-			vert_gauss_weight=*(vert_gauss_weights+igvert);
-			gauss_weight=area_gauss_weight*vert_gauss_weight;
-			gauss_coord[0]=*(first_gauss_area_coord+igarea); 
-			gauss_coord[1]=*(second_gauss_area_coord+igarea);
-			gauss_coord[2]=*(third_gauss_area_coord+igarea);
-			gauss_coord[3]=*(vert_gauss_coord+igvert);
-
-			/* Get Jacobian determinant: */
-			GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss_coord);
-
-			/*Conduction: */
-
-			/*Get B_conduct matrix: */
-			GetB_conduct(&B_conduct[0][0],&xyz_list[0][0],gauss_coord); 
-
-			/*Build D: */
-			D_scalar=gauss_weight*Jdet*(thermalconductivity/(rho_ice*heatcapacity));
-
-			if(dt){
-				D_scalar=D_scalar*dt;
-			}
-
-			D[0][0]=D_scalar; D[0][1]=0; D[0][2]=0;
-			D[1][0]=0; D[1][1]=D_scalar; D[1][2]=0;
-			D[2][0]=0; D[2][1]=0; D[2][2]=D_scalar;
-
-			/*  Do the triple product B'*D*B: */
-			MatrixMultiply(&B_conduct[0][0],3,numdof,1,&D[0][0],3,3,0,&tBD_conduct[0][0],0);
-			MatrixMultiply(&tBD_conduct[0][0],numdof,3,0,&B_conduct[0][0],3,numdof,0,&Ke_gaussian_conduct[0][0],0);
-
-			/*Advection: */
-
-			/*Get B_advec and Bprime_advec matrices: */
-			GetB_advec(&B_advec[0][0],&xyz_list[0][0],gauss_coord); 
-			GetBprime_advec(&Bprime_advec[0][0],&xyz_list[0][0],gauss_coord); 
-
-			//Build the D matrix
-			inputs->GetParameterValue(&u, gauss_coord,VxEnum);
-			inputs->GetParameterValue(&v, gauss_coord,VyEnum);
-			inputs->GetParameterValue(&w, gauss_coord,VzEnum);
-
-			D_scalar=gauss_weight*Jdet;
-
-			if(dt){
-				D_scalar=D_scalar*dt;
-			}
-
-			D[0][0]=D_scalar*u;D[0][1]=0;         D[0][2]=0;
-			D[1][0]=0;         D[1][1]=D_scalar*v;D[1][2]=0;
-			D[2][0]=0;         D[2][1]=0;         D[2][2]=D_scalar*w;
-
-			/*  Do the triple product B'*D*Bprime: */
-			MatrixMultiply(&B_advec[0][0],3,numdof,1,&D[0][0],3,3,0,&tBD_advec[0][0],0);
-			MatrixMultiply(&tBD_advec[0][0],numdof,3,0,&Bprime_advec[0][0],3,numdof,0,&Ke_gaussian_advec[0][0],0);
-
-			/*Transient: */
-			if(dt){
-				GetNodalFunctions(&L[0], gauss_coord);
-				D_scalar=gauss_weight*Jdet;
-				D_scalar=D_scalar;
-
-				/*  Do the triple product L'*D*L: */
-				MatrixMultiply(&L[0],numdof,1,0,&D_scalar,1,1,0,&tLD[0],0);
-				MatrixMultiply(&tLD[0],numdof,1,0,&L[0],1,numdof,0,&Ke_gaussian_transient[0][0],0);
-			}
-			else{
-				for(i=0;i<numdof;i++){
-					for(j=0;j<numdof;j++){
-						Ke_gaussian_transient[i][j]=0;
-					}
-				}
-			}
-
-			/*Artifficial diffusivity*/
-			if(artdiff){
-				/*Build K: */
-				D_scalar=gauss_weight*Jdet/(pow(u,2)+pow(v,2)+epsvel);
-				if(dt){
-					D_scalar=D_scalar*dt;
-				}
-				K[0][0]=D_scalar*pow(u,2);       K[0][1]=D_scalar*fabs(u)*fabs(v);
-				K[1][0]=D_scalar*fabs(u)*fabs(v);K[1][1]=D_scalar*pow(v,2);
-
-				/*Get B_artdiff: */
-				GetB_artdiff(&B_artdiff[0][0],&xyz_list[0][0],gauss_coord); 
-
-				/*  Do the triple product B'*K*B: */
-				MatrixMultiply(&B_artdiff[0][0],2,numdof,1,&K[0][0],2,2,0,&tBD_artdiff[0][0],0);
-				MatrixMultiply(&tBD_artdiff[0][0],numdof,2,0,&B_artdiff[0][0],2,numdof,0,&Ke_gaussian_artdiff[0][0],0);
-			}
-			else{
-				for(i=0;i<numdof;i++){
-					for(j=0;j<numdof;j++){
-						Ke_gaussian_artdiff[i][j]=0;
-					}
-				}
-			}
-
-			/*Add Ke_gaussian to pKe: */
-			for(i=0;i<numdof;i++){
-				for(j=0;j<numdof;j++){
-					K_terms[i][j]+=Ke_gaussian_conduct[i][j]+Ke_gaussian_advec[i][j]+Ke_gaussian_transient[i][j]+Ke_gaussian_artdiff[i][j];
-				}
-			}
-		}
-	}
-
-
-	/*Add Ke_gg to global matrix Kgg: */
-	MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)K_terms,ADD_VALUES);
-
-	xfree((void**)&first_gauss_area_coord);
-	xfree((void**)&second_gauss_area_coord);
-	xfree((void**)&third_gauss_area_coord);
-	xfree((void**)&area_gauss_weights);
-	xfree((void**)&vert_gauss_weights);
-	xfree((void**)&vert_gauss_coord);
-
-	//Ice/ocean heat exchange flux on ice shelf base 
-	if(onbed && shelf){
-
-		tria=(Tria*)SpawnTria(0,1,2); //grids 0, 1 and 2 make the new tria.
-		tria->CreateKMatrixThermal(Kgg, analysis_type,sub_analysis_type);
-		delete tria;
-	}
-}
-/*}}}*/
-/*FUNCTION CreatePVector {{{1*/
-void  Penta::CreatePVector(Vec pg,  int analysis_type,int sub_analysis_type){
-
-	/*Just branch to the correct element stiffness matrix generator, according to the type of analysis we are carrying out: */
-	if (analysis_type==ControlAnalysisEnum){
-
-		CreatePVectorDiagnosticHoriz( pg,analysis_type,sub_analysis_type);
-	}
-	else if (analysis_type==DiagnosticAnalysisEnum){
-
-		if (sub_analysis_type==HorizAnalysisEnum){
-
-			CreatePVectorDiagnosticHoriz( pg,analysis_type,sub_analysis_type);
-		}
-		else if (sub_analysis_type==VertAnalysisEnum){
-
-			CreatePVectorDiagnosticVert( pg,analysis_type,sub_analysis_type);
-		}
-		else if (sub_analysis_type==StokesAnalysisEnum){
-
-			CreatePVectorDiagnosticStokes( pg,analysis_type,sub_analysis_type);
-		}
-		else ISSMERROR("%s%i%s\n","sub_analysis: ",sub_analysis_type," not supported yet");
-	}
-	else if (analysis_type==SlopecomputeAnalysisEnum){
-
-		CreatePVectorSlopeCompute( pg,analysis_type,sub_analysis_type);
-	}
-	else if (analysis_type==PrognosticAnalysisEnum){
-
-		CreatePVectorPrognostic( pg,analysis_type,sub_analysis_type);
-	}
-	else if (analysis_type==BalancedthicknessAnalysisEnum){
-
-		CreatePVectorBalancedthickness( pg,analysis_type,sub_analysis_type);
-	}
-	else if (analysis_type==BalancedvelocitiesAnalysisEnum){
-
-		CreatePVectorBalancedvelocities( pg,analysis_type,sub_analysis_type);
-	}
-	else if (analysis_type==ThermalAnalysisEnum){
-
-		CreatePVectorThermal( pg,analysis_type,sub_analysis_type);
-	}
-	else if (analysis_type==MeltingAnalysisEnum){
-
-		CreatePVectorMelting( pg,analysis_type,sub_analysis_type);
-	}
-	else{
-		ISSMERROR("%s%i%s\n","analysis: ",analysis_type," not supported yet");
-	}	
-
-}
-/*}}}*/
-/*FUNCTION CreatePVectorBalancedthickness {{{1*/
-void Penta::CreatePVectorBalancedthickness( Vec pg, int analysis_type,int sub_analysis_type){
-
-	/*Collapsed formulation: */
-	Tria*  tria=NULL;
-
-	/*flags: */
-	bool onbed;
-	bool onwater;
-
-	/*recover some inputs: */
-	inputs->GetParameterValue(&onbed,ElementOnBedEnum);
-	inputs->GetParameterValue(&onwater,ElementOnWaterEnum);
-
-	/*If on water, skip: */
-	if(onwater)return;
-
-	/*Is this element on the bed? :*/
-	if(!onbed)return;
-
-	/*Spawn Tria element from the base of the Penta: */
-	tria=(Tria*)SpawnTria(0,1,2); //grids 0, 1 and 2 make the new tria.
-	tria->CreatePVector(pg, analysis_type,sub_analysis_type);
-	delete tria;
-	return;
-}
-/*}}}*/
-/*FUNCTION CreatePVectorBalancedvelocities {{{1*/
-void Penta::CreatePVectorBalancedvelocities( Vec pg, int analysis_type,int sub_analysis_type){
-
-	/*Collapsed formulation: */
-	Tria*  tria=NULL;
-
-	/*flags: */
-	bool onbed;
-	bool onwater;
-
-	/*recover some inputs: */
-	inputs->GetParameterValue(&onbed,ElementOnBedEnum);
-	inputs->GetParameterValue(&onwater,ElementOnWaterEnum);
-
-	/*If on water, skip: */
-	if(onwater)return;
-
-	/*Is this element on the bed? :*/
-	if(!onbed)return;
-
-	/*Spawn Tria element from the base of the Penta: */
-	tria=(Tria*)SpawnTria(0,1,2); //grids 0, 1 and 2 make the new tria.
-	tria->CreatePVector(pg, analysis_type,sub_analysis_type);
-	delete tria;
-	return;
-}
-/*}}}*/
-/*FUNCTION CreatePVectorDiagnosticHoriz {{{1*/
-void Penta::CreatePVectorDiagnosticHoriz( Vec pg, int analysis_type,int sub_analysis_type){
-
-	int i,j;
-
-	/* node data: */
-	const int    numgrids=6;
-	const int    NDOF2=2;
-	const int    numdof=NDOF2*numgrids;
-	double       xyz_list[numgrids][3];
-	int          doflist[numdof];
-	int          numberofdofspernode;
-
-	/* parameters: */
-	double  slope[3]; //do not put 2! this goes into GetParameterDerivativeValue, which addresses slope[3] also!
-	double  driving_stress_baseline;
-	double  thickness;
-
-	/* gaussian points: */
-	int     num_gauss,ig;
-	double* first_gauss_area_coord  =  NULL;
-	double* second_gauss_area_coord =  NULL;
-	double* third_gauss_area_coord  =  NULL;
-	double* fourth_gauss_vert_coord  =  NULL;
-	double* area_gauss_weights      =  NULL;
-	double* vert_gauss_weights      =  NULL;
-	double  gauss_coord[4];
-	int     order_area_gauss;
-	int     num_vert_gauss;
-	int     num_area_gauss;
-	int     ig1,ig2;
-	double  gauss_weight1,gauss_weight2;
-	double  gauss_weight;
-
-	/* Jacobian: */
-	double Jdet;
-
-	/*nodal functions: */
-	double l1l6[6];
-
-	/*element vector at the gaussian points: */
-	double  pe_g[numdof]={0.0};
-	double  pe_g_gaussian[numdof];
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-	Matpar* matpar=NULL;
-
-	/*Spawning: */
-	Tria* tria=NULL;
-
-	/*inputs: */
-	bool onwater;
-	bool collapse;
-	bool onbed;
-
-	/*retrieve inputs :*/
-	inputs->GetParameterValue(&onwater,ElementOnWaterEnum);
-	inputs->GetParameterValue(&collapse,CollapseEnum);
-	inputs->GetParameterValue(&onbed,ElementOnBedEnum);
-
-	/*If on water, skip load: */
-	if(onwater)return;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	matpar=(Matpar*)hmatpar.delivers();
-
-
-	/*Figure out if this pentaelem is collapsed. If so, then bailout, except if it is at the 
-	  bedrock, in which case we spawn a tria element using the 3 first grids, and use it to build 
-	  the load vector. */
-
-	if ((collapse==1) && (onbed==0)){
-		/*This element should be collapsed, but this element is not on the bedrock, therefore all its 
-		 * dofs have already been frozen! Do nothing: */
-		return;
-	}
-	else if ((collapse==1) && (onbed==1)){
-
-		/*This element should be collapsed into a tria element at its base. Create this tria element, 
-		 *and use its CreatePVector functionality to return an elementary load vector: */
-		tria=(Tria*)SpawnTria(0,1,2); //grids 0, 1 and 2 make the new tria.
-		tria->CreatePVector(pg, analysis_type,sub_analysis_type);
-		delete tria;
-		return;
-	}
-	else{
-
-		/*Implement standard penta element: */
-
-		/* Get node coordinates and dof list: */
-		GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
-		GetDofList(&doflist[0],&numberofdofspernode);
-
-		/*Get gaussian points and weights :*/
-		order_area_gauss=2;
-		num_vert_gauss=3;
-
-		GaussPenta( &num_area_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &area_gauss_weights, &fourth_gauss_vert_coord,&vert_gauss_weights,order_area_gauss,num_vert_gauss);
-
-		/* Start  looping on the number of gaussian points: */
-		for (ig1=0; ig1<num_area_gauss; ig1++){
-			for (ig2=0; ig2<num_vert_gauss; ig2++){
-
-				/*Pick up the gaussian point: */
-				gauss_weight1=*(area_gauss_weights+ig1);
-				gauss_weight2=*(vert_gauss_weights+ig2);
-				gauss_weight=gauss_weight1*gauss_weight2;
-
-				gauss_coord[0]=*(first_gauss_area_coord+ig1); 
-				gauss_coord[1]=*(second_gauss_area_coord+ig1);
-				gauss_coord[2]=*(third_gauss_area_coord+ig1);
-				gauss_coord[3]=*(fourth_gauss_vert_coord+ig2);
-
-				/*Compute thickness at gaussian point: */
-				inputs->GetParameterValue(&thickness, gauss_coord,ThicknessEnum);
-
-				/*Compute slope at gaussian point: */
-				inputs->GetParameterDerivativeValue(&slope[0],&xyz_list[0][0],gauss_coord,SurfaceEnum);
-
-				/* Get Jacobian determinant: */
-				GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss_coord);
-
-				/*Get nodal functions: */
-				GetNodalFunctions(l1l6, gauss_coord);
-
-				/*Compute driving stress: */
-				driving_stress_baseline=matpar->GetRhoIce()*matpar->GetG();
-
-				/*Build pe_g_gaussian vector: */
-				for (i=0;i<numgrids;i++){
-					for (j=0;j<NDOF2;j++){
-						pe_g_gaussian[i*NDOF2+j]=-driving_stress_baseline*slope[j]*Jdet*gauss_weight*l1l6[i];
-					}
-				}
-
-				/*Add pe_g_gaussian vector to pe_g: */
-				for( i=0; i<numdof; i++)pe_g[i]+=pe_g_gaussian[i];
-
-			} //for (ig2=0; ig2<num_vert_gauss; ig2++)
-		} //for (ig1=0; ig1<num_area_gauss; ig1++)
-
-	} //else if ((collapse==1) && (onbed==1))
-
-	/*Add pe_g to global vector pg: */
-	VecSetValues(pg,numdof,doflist,(const double*)pe_g,ADD_VALUES);
-
-	xfree((void**)&first_gauss_area_coord);
-	xfree((void**)&second_gauss_area_coord);
-	xfree((void**)&third_gauss_area_coord);
-	xfree((void**)&fourth_gauss_vert_coord);
-	xfree((void**)&area_gauss_weights);
-	xfree((void**)&vert_gauss_weights);
-
-}
-/*}}}*/
-/*FUNCTION CreatePVectorDiagnosticStokes {{{1*/
-void Penta::CreatePVectorDiagnosticStokes( Vec pg, int analysis_type,int sub_analysis_type){
-
-	/*indexing: */
-	int i,j;
-
-	const int numgrids=6;
-	const int DOFPERGRID=4;
-	const int numdof=numgrids*DOFPERGRID;
-	const int numgrids2d=3;
-	int numdof2d=numgrids2d*DOFPERGRID;
-	int doflist[numdof];
-	int numberofdofspernode;
-
-	/*Material properties: */
-	double         gravity,rho_ice,rho_water;
-
-	/*parameters: */
-	double		   xyz_list_tria[numgrids2d][3];
-	double         xyz_list[numgrids][3];
-	double		   surface_normal[3];
-	double		   bed_normal[3];
-	double         bed;
-
-	/* gaussian points: */
-	int     num_area_gauss;
-	int     igarea,igvert;
-	double* first_gauss_area_coord  =  NULL;
-	double* second_gauss_area_coord =  NULL;
-	double* third_gauss_area_coord  =  NULL;
-	double* vert_gauss_coord = NULL;
-	double* area_gauss_weights  =  NULL;
-	double* vert_gauss_weights  =  NULL;
-
-	/* specific gaussian point: */
-	double  gauss_weight,area_gauss_weight,vert_gauss_weight;
-	double  gauss_coord[4];
-	double  gauss_coord_tria[3];
-
-	int     area_order=5;
-	int	  num_vert_gauss=5;
-
-	double  epsilon[6]; /* epsilon=[exx,eyy,ezz,exy,exz,eyz];*/
-	double  viscosity;
-	double  water_pressure;
-	int     dofs[3]={0,1,2};
-
-	/*matrices: */
-	double     Pe_temp[27]={0.0}; //for the six nodes and the bubble 
-	double     Pe_gaussian[27]={0.0}; //for the six nodes and the bubble 
-	double     Ke_temp[27][3]={0.0}; //for the six nodes and the bubble 
-	double     Pe_reduced[numdof]; //for the six nodes only
-	double     Ke_gaussian[27][3];
-	double     L[3]; //for the three nodes of the bed
-	double     l1l7[7]; //for the six nodes and the bubble 
-	double     B[8][27];
-	double     B_prime[8][27];
-	double     B_prime_bubble[8][3];
-	double     Jdet;
-	double     Jdet2d;
-	double     D[8][8]={0.0};
-	double     D_scalar;
-	double     tBD[27][8];
-	double     P_terms[numdof]={0.0};
-
-	Tria*            tria=NULL;
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-	Matpar* matpar=NULL;
-	Matice* matice=NULL;
-
-	/*parameters: */
-	double stokesreconditioning;
-
-	/*inputs: */
-	bool onwater;
-	bool onbed;
-	bool shelf;
-
-	/*retrieve inputs :*/
-	inputs->GetParameterValue(&onwater,ElementOnWaterEnum);
-	inputs->GetParameterValue(&onbed,ElementOnBedEnum);
-	inputs->GetParameterValue(&shelf,ElementOnIceShelfEnum);
-
-	/*retrieve some parameters: */
-	this->parameters->FindParam(&stokesreconditioning,StokesReconditioningEnum);
-
-	/*If on water, skip load: */
-	if(onwater)return;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	matpar=(Matpar*)hmatpar.delivers();
-	matice=(Matice*)hmatice.delivers();
-
-
-	/*recovre material parameters: */
-	rho_water=matpar->GetRhoWater();
-	rho_ice=matpar->GetRhoIce();
-	gravity=matpar->GetG();
-
-	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
-	GetDofList(&doflist[0],&numberofdofspernode);
-
-	/* Get gaussian points and weights. Penta is an extrusion of a Tria, we therefore 
-		get tria gaussian points as well as segment gaussian points. For tria gaussian 
-		points, order of integration is 2, because we need to integrate the product tB*D*B' 
-		which is a polynomial of degree 3 (see GaussTria for more details). For segment gaussian 
-		points, same deal, which yields 3 gaussian points.*/
-
-	/* Get gaussian points and weights (make this a statically initialized list of points? fstd): */
-	GaussPenta( &num_area_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &area_gauss_weights,&vert_gauss_coord, &vert_gauss_weights, area_order, num_vert_gauss);
-
-	/* Start  looping on the number of gaussian points: */
-	for (igarea=0; igarea<num_area_gauss; igarea++){
-		for (igvert=0; igvert<num_vert_gauss; igvert++){
-			/*Pick up the gaussian point: */
-			area_gauss_weight=*(area_gauss_weights+igarea);
-			vert_gauss_weight=*(vert_gauss_weights+igvert);
-			gauss_weight=area_gauss_weight*vert_gauss_weight;
-			gauss_coord[0]=*(first_gauss_area_coord+igarea); 
-			gauss_coord[1]=*(second_gauss_area_coord+igarea);
-			gauss_coord[2]=*(third_gauss_area_coord+igarea);
-			gauss_coord[3]=*(vert_gauss_coord+igvert);
-
-			/*Compute strain rate and viscosity: */
-			inputs->GetStrainRateStokes(&epsilon[0],&xyz_list[0][0],gauss_coord,VxEnum,VyEnum,VzEnum);
-			matice->GetViscosity3dStokes(&viscosity,&epsilon[0]);
-
-			/* Get Jacobian determinant: */
-			GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss_coord);
-
-			/* Get nodal functions */
-			GetNodalFunctionsStokes(&l1l7[0], gauss_coord);
-
-			/* Build gaussian vector */
-			for(i=0;i<numgrids+1;i++){
-				Pe_gaussian[i*DOFPERGRID+2]=-rho_ice*gravity*Jdet*gauss_weight*l1l7[i];
-			}
-
-			/*Add Pe_gaussian to terms in Pe_temp. Watch out for column orientation from matlab: */
-			for(i=0;i<27;i++){
-				Pe_temp[i]+=Pe_gaussian[i];
-			}
-
-			/*Get B and Bprime matrices: */
-			GetBStokes(&B[0][0],&xyz_list[0][0],gauss_coord); 
-			GetBprimeStokes(&B_prime[0][0],&xyz_list[0][0], gauss_coord); 
-
-			/*Get bubble part of Bprime */
-			for(i=0;i<8;i++){
-				for(j=0;j<3;j++){
-					B_prime_bubble[i][j]=B_prime[i][j+24];
-				}
-			}
-
-			/* Build the D matrix: we plug the gaussian weight, the thickness, the viscosity, and the jacobian determinant 
-			 * onto this scalar matrix, so that we win some computational time: */
-			D_scalar=gauss_weight*Jdet;
-			for (i=0;i<6;i++){
-				D[i][i]=D_scalar*viscosity;
-			}
-			for (i=6;i<8;i++){
-				D[i][i]=-D_scalar*stokesreconditioning;
-			}
-
-			/*  Do the triple product tB*D*Bprime: */
-			MatrixMultiply(&B[0][0],8,27,1,&D[0][0],8,8,0,&tBD[0][0],0);
-			MatrixMultiply(&tBD[0][0],27,8,0,&B_prime_bubble[0][0],8,3,0,&Ke_gaussian[0][0],0);
-
-			/*Add Ke_gaussian and Ke_gaussian to terms in pKe. Watch out for column orientation from matlab: */
-			for(i=0;i<27;i++){
-				for(j=0;j<3;j++){
-					Ke_temp[i][j]+=Ke_gaussian[i][j];
-				}
-			}
-		}
-	}
-
-	/*Deal with 2d friction at the bedrock interface: */
-	if ( (onbed==1) && (shelf==1)){
-
-		for(i=0;i<numgrids2d;i++){
-			for(j=0;j<3;j++){
-				xyz_list_tria[i][j]=xyz_list[i][j];
-			}
-		}
-
-		xfree((void**)&first_gauss_area_coord); xfree((void**)&second_gauss_area_coord); xfree((void**)&third_gauss_area_coord); xfree((void**)&area_gauss_weights);
-		GaussTria (&num_area_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &area_gauss_weights, 2);
-
-		/* Start looping on the number of gauss 2d (nodes on the bedrock) */
-		for (igarea=0; igarea<num_area_gauss; igarea++){
-			gauss_weight=*(area_gauss_weights+igarea);
-			gauss_coord[0]=*(first_gauss_area_coord+igarea); 
-			gauss_coord[1]=*(second_gauss_area_coord+igarea);
-			gauss_coord[2]=*(third_gauss_area_coord+igarea);
-			gauss_coord[3]=-1;
-
-			gauss_coord_tria[0]=*(first_gauss_area_coord+igarea); 
-			gauss_coord_tria[1]=*(second_gauss_area_coord+igarea);
-			gauss_coord_tria[2]=*(third_gauss_area_coord+igarea);
-
-			/*Get the Jacobian determinant */
-			tria->GetJacobianDeterminant3d(&Jdet2d, &xyz_list_tria[0][0], gauss_coord_tria);
-
-			/* Get bed at gaussian point */
-			inputs->GetParameterValue(&bed, gauss_coord,BedEnum);
-
-			/*Get L matrix : */
-			tria->GetL(&L[0], &xyz_list[0][0], gauss_coord_tria,1);
-
-			/*Get water_pressure at gaussian point */
-			water_pressure=gravity*rho_water*bed;
-
-			/*Get normal vecyor to the bed */
-			SurfaceNormal(&surface_normal[0],xyz_list_tria);
-
-			bed_normal[0]=-surface_normal[0]; //Program is for surface, so the normal to the bed is the opposite of the result
-			bed_normal[1]=-surface_normal[1];
-			bed_normal[2]=-surface_normal[2];
-
-			for(i=0;i<numgrids2d;i++){
-				for(j=0;j<3;j++){
-					Pe_temp[i*DOFPERGRID+j]+=water_pressure*gauss_weight*Jdet2d*L[i]*bed_normal[j];
-				}
-			}
-		}
-	} //if ( (onbed==1) && (shelf==1))
-
-	/*Reduce the matrix */
-	ReduceVectorStokes(&Pe_reduced[0], &Ke_temp[0][0], &Pe_temp[0]);
-
-	for(i=0;i<numdof;i++){
-		P_terms[i]+=Pe_reduced[i];
-	}
-
-	/*Add P_terms to global vector pg: */
-	VecSetValues(pg,numdof,doflist,(const double*)P_terms,ADD_VALUES);
-
-	/*Free ressources:*/
-	xfree((void**)&first_gauss_area_coord);
-	xfree((void**)&second_gauss_area_coord);
-	xfree((void**)&third_gauss_area_coord);
-	xfree((void**)&area_gauss_weights);
-	xfree((void**)&vert_gauss_coord);
-	xfree((void**)&vert_gauss_weights);
-
-}
-/*}}}*/
-/*FUNCTION CreatePVectorDiagnosticVert {{{1*/
-void  Penta::CreatePVectorDiagnosticVert( Vec pg, int analysis_type,int sub_analysis_type){
-
-	int i;
-
-
-	/* node data: */
-	const int    numgrids=6;
-	const int    NDOF1=1;
-	const int    numdof=NDOF1*numgrids;
-	double       xyz_list[numgrids][3];
-	int          doflist[numdof];
-	int          numberofdofspernode;
-
-	/* gaussian points: */
-	int     num_gauss,ig;
-	double* first_gauss_area_coord  =  NULL;
-	double* second_gauss_area_coord =  NULL;
-	double* third_gauss_area_coord  =  NULL;
-	double* fourth_gauss_vert_coord  =  NULL;
-	double* area_gauss_weights      =  NULL;
-	double* vert_gauss_weights      =  NULL;
-	double  gauss_coord[4];
-	int     order_area_gauss;
-	int     num_vert_gauss;
-	int     num_area_gauss;
-	int     ig1,ig2;
-	double  gauss_weight1,gauss_weight2;
-	double  gauss_weight;
-
-	/* Jacobian: */
-	double Jdet;
-
-	/*element vector at the gaussian points: */
-	double  pe_g[numdof]={0.0};
-	double  pe_g_gaussian[numdof];
-	double l1l6[6];
-
-	/*Spawning: */
-	Tria* tria=NULL;
-
-	/*input parameters for structural analysis (diagnostic): */
-	double du[3];
-	double dv[3];
-	double dudx,dvdy;
-	int     dofs1[1]={0};
-	int     dofs2[1]={1};
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-
-	/*inputs: */
-	bool onwater;
-	bool onbed;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-
-	/*retrieve inputs :*/
-	inputs->GetParameterValue(&onwater,ElementOnWaterEnum);
-	inputs->GetParameterValue(&onbed,ElementOnBedEnum);
-
-	
-	/*If on water, skip: */
-	if(onwater)return;
-
-	/*If we are on the bedrock, spawn a tria on the bedrock, and use it to build the 
-	 *diagnostic base vertical stifness: */
-	if(onbed){
-		tria=(Tria*)SpawnTria(0,1,2); //nodes 0, 1 and 2 are on the bedrock
-		tria->CreatePVectorDiagnosticBaseVert(pg, analysis_type,sub_analysis_type);
-		delete tria;
-	}
-
-	/*Now, handle the standard penta element: */
-	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
-	GetDofList(&doflist[0],&numberofdofspernode);
-
-	/*Get gaussian points and weights :*/
-	order_area_gauss=2;
-	num_vert_gauss=2;
-
-	GaussPenta( &num_area_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &area_gauss_weights, &fourth_gauss_vert_coord,&vert_gauss_weights,order_area_gauss,num_vert_gauss);
-
-	/* Start  looping on the number of gaussian points: */
-	for (ig1=0; ig1<num_area_gauss; ig1++){
-		for (ig2=0; ig2<num_vert_gauss; ig2++){
-
-			/*Pick up the gaussian point: */
-			gauss_weight1=*(area_gauss_weights+ig1);
-			gauss_weight2=*(vert_gauss_weights+ig2);
-			gauss_weight=gauss_weight1*gauss_weight2;
-
-			gauss_coord[0]=*(first_gauss_area_coord+ig1); 
-			gauss_coord[1]=*(second_gauss_area_coord+ig1);
-			gauss_coord[2]=*(third_gauss_area_coord+ig1);
-			gauss_coord[3]=*(fourth_gauss_vert_coord+ig2);
-
-			/*Get velocity derivative, with respect to x and y: */
-
-			inputs->GetParameterDerivativeValue(&du[0],&xyz_list[0][0],gauss_coord,VxEnum);
-			inputs->GetParameterDerivativeValue(&du[0],&xyz_list[0][0],gauss_coord,VyEnum);
-			dudx=du[0];
-			dvdy=dv[1];
-
-
-			/* Get Jacobian determinant: */
-			GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss_coord);
-
-			/*Get nodal functions: */
-			GetNodalFunctions(l1l6, gauss_coord);
-
-			/*Build pe_g_gaussian vector: */
-			for (i=0;i<numgrids;i++){
-				pe_g_gaussian[i]=(dudx+dvdy)*Jdet*gauss_weight*l1l6[i];
-			}
-
-			/*Add pe_g_gaussian vector to pe_g: */
-			for( i=0; i<numdof; i++)pe_g[i]+=pe_g_gaussian[i];
-
-		} //for (ig2=0; ig2<num_vert_gauss; ig2++)
-	} //for (ig1=0; ig1<num_area_gauss; ig1++)
-
-	/*Add pe_g to global vector pg: */
-	VecSetValues(pg,numdof,doflist,(const double*)pe_g,ADD_VALUES);
-
-	xfree((void**)&first_gauss_area_coord);
-	xfree((void**)&second_gauss_area_coord);
-	xfree((void**)&third_gauss_area_coord);
-	xfree((void**)&fourth_gauss_vert_coord);
-	xfree((void**)&area_gauss_weights);
-	xfree((void**)&vert_gauss_weights);
-}
-/*}}}*/
-/*FUNCTION CreatePVectorMelting {{{1*/
-void Penta::CreatePVectorMelting( Vec pg, int analysis_type,int sub_analysis_type){
-	return;
-}
-/*}}}*/
-/*FUNCTION CreatePVectorPrognostic {{{1*/
-
-void Penta::CreatePVectorPrognostic( Vec pg,  int analysis_type,int sub_analysis_type){
-
-	/*Collapsed formulation: */
-	Tria*  tria=NULL;
-
-	/*inputs: */
-	bool onwater;
-	bool onbed;
-
-	/*retrieve inputs :*/
-	inputs->GetParameterValue(&onwater,ElementOnWaterEnum);
-	inputs->GetParameterValue(&onbed,ElementOnBedEnum);
-	
-	/*If on water, skip: */
-	if(onwater)return;
-
-	/*Is this element on the bed? :*/
-	if(!onbed)return;
-
-	/*Spawn Tria element from the base of the Penta: */
-	tria=(Tria*)SpawnTria(0,1,2); //grids 0, 1 and 2 make the new tria.
-	tria->CreatePVector(pg, analysis_type,sub_analysis_type);
-	delete tria;
-	return;
-}
-/*}}}*/
-/*FUNCTION CreatePVectorSlopeCompute {{{1*/
-
-void Penta::CreatePVectorSlopeCompute( Vec pg,  int analysis_type,int sub_analysis_type){
-
-	/*Collapsed formulation: */
-	Tria*  tria=NULL;
-
-	/*inputs: */
-	bool onwater;
-	bool onbed;
-
-	/*retrieve inputs :*/
-	inputs->GetParameterValue(&onwater,ElementOnWaterEnum);
-	inputs->GetParameterValue(&onbed,ElementOnBedEnum);
-
-	/*If on water, skip: */
-	if(onwater)return;
-
-	/*Is this element on the bed? :*/
-	if(!onbed)return;
-
-	/*Spawn Tria element from the base of the Penta: */
-	tria=(Tria*)SpawnTria(0,1,2); //grids 0, 1 and 2 make the new tria.
-	tria->CreatePVector(pg, analysis_type,sub_analysis_type);
-	delete tria;
-	return;
-}
-/*}}}*/
-/*FUNCTION CreatePVectorThermal {{{1*/
-void Penta::CreatePVectorThermal( Vec pg, int analysis_type,int sub_analysis_type){
-
-
-	/*indexing: */
-	int i,j;
-	int found=0;
-
-	const int  numgrids=6;
-	const int  NDOF1=1;
-	const int  numdof=numgrids*NDOF1;
-	int        doflist[numdof];
-	int        numberofdofspernode;
-
-	/*Grid data: */
-	double        xyz_list[numgrids][3];
-
-	/* gaussian points: */
-	int     num_area_gauss,igarea,igvert;
-	double* first_gauss_area_coord  =  NULL;
-	double* second_gauss_area_coord =  NULL;
-	double* third_gauss_area_coord  =  NULL;
-	double* vert_gauss_coord = NULL;
-	double* area_gauss_weights  =  NULL;
-	double* vert_gauss_weights  =  NULL;
-	double  gauss_weight,area_gauss_weight,vert_gauss_weight;
-	double  gauss_coord[4];
-	int     area_order=2;
-	int	  num_vert_gauss=3;
-
-	double temperature_list[numgrids];
-	double temperature;
-
-	/*Material properties: */
-	double gravity,rho_ice,rho_water;
-	double mixed_layer_capacity,heatcapacity;
-	double beta,meltingpoint,thermal_exchange_velocity;
-
-	/* element parameters: */
-	int    friction_type;
-
-	int    dofs[3]={0,1,2};
-	int    dofs1[1]={0};
-
-	/*matrices: */
-	double P_terms[numdof]={0.0};
-	double L[numdof];
-	double l1l2l3[3];
-	double alpha2_list[3];
-	double basalfriction_list[3]={0.0};
-	double basalfriction;
-	double epsilon[6];
-	double epsilon_sqr[3][3];
-	double epsilon_matrix[3][3];
-
-	double Jdet;
-	double viscosity;
-	double epsilon_eff;
-	double phi;
-	double t_pmp;
-	double scalar;
-	double scalar_def;
-	double scalar_ocean;
-	double scalar_transient;
-
-	/*Collapsed formulation: */
-	Tria*  tria=NULL;
-
-	/*parameters: */
-	double dt;
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-	Matpar* matpar=NULL;
-	Matice* matice=NULL;
-
-	/*inputs: */
-	bool onwater;
-	bool onbed;
-	bool shelf;
-
-	/*retrieve inputs :*/
-	inputs->GetParameterValue(&onwater,ElementOnWaterEnum);
-	inputs->GetParameterValue(&onbed,ElementOnBedEnum);
-	inputs->GetParameterValue(&shelf,ElementOnIceShelfEnum);
-
-	/*retrieve some parameters: */
-	this->parameters->FindParam(&dt,DtEnum);
-
-	/*If on water, skip: */
-	if(onwater)return;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	matpar=(Matpar*)hmatpar.delivers();
-	matice=(Matice*)hmatice.delivers();
-
-	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
-	GetDofList(&doflist[0],&numberofdofspernode);
-
-	/*recovre material parameters: */
-	rho_water=matpar->GetRhoWater();
-	rho_ice=matpar->GetRhoIce();
-	gravity=matpar->GetG();
-	heatcapacity=matpar->GetHeatCapacity();
-	beta=matpar->GetBeta();
-	meltingpoint=matpar->GetMeltingPoint();
-
-	/* Get gaussian points and weights. Penta is an extrusion of a Tria, we therefore 
-		get tria gaussian points as well as segment gaussian points. For tria gaussian 
-		points, order of integration is 2, because we need to integrate the product tB*D*B' 
-		which is a polynomial of degree 3 (see GaussTria for more details). For segment gaussian 
-		points, same deal, which yields 3 gaussian points.: */
-
-	/*Get gaussian points: */
-	GaussPenta( &num_area_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &area_gauss_weights,&vert_gauss_coord, &vert_gauss_weights, area_order, num_vert_gauss);
-
-	/* Start  looping on the number of gaussian points: */
-	for (igarea=0; igarea<num_area_gauss; igarea++){
-		for (igvert=0; igvert<num_vert_gauss; igvert++){
-			/*Pick up the gaussian point: */
-			area_gauss_weight=*(area_gauss_weights+igarea);
-			vert_gauss_weight=*(vert_gauss_weights+igvert);
-			gauss_weight=area_gauss_weight*vert_gauss_weight;
-			gauss_coord[0]=*(first_gauss_area_coord+igarea); 
-			gauss_coord[1]=*(second_gauss_area_coord+igarea);
-			gauss_coord[2]=*(third_gauss_area_coord+igarea);
-			gauss_coord[3]=*(vert_gauss_coord+igvert);
-
-			/*Compute strain rate and viscosity: */
-			inputs->GetStrainRateStokes(&epsilon[0],&xyz_list[0][0],gauss_coord,VxEnum,VyEnum,VzEnum);
-			matice->GetViscosity3dStokes(&viscosity,&epsilon[0]);
-
-			/* Get Jacobian determinant: */
-			GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss_coord);
-
-			/* Get nodal functions */
-			GetNodalFunctions(&L[0], gauss_coord);
-
-			/*Build deformational heating: */
-			GetPhi(&phi, &epsilon[0], viscosity);
-
-			/*Build pe_gaussian */
-			scalar_def=phi/(rho_ice*heatcapacity)*Jdet*gauss_weight;
-			if(dt){
-				scalar_def=scalar_def*dt;
-			}
-
-			for(i=0;i<numgrids;i++){
-				P_terms[i]+=scalar_def*L[i];
-			}
-
-			/* Build transient now */
-			if(dt){
-				inputs->GetParameterValue(&temperature, gauss_coord,TemperatureEnum);
-				scalar_transient=temperature*Jdet*gauss_weight;
-				for(i=0;i<numgrids;i++){
-					P_terms[i]+=scalar_transient*L[i];
-				}
-			}
-		}
-	}
-
-	/*Add pe_g to global vector pg: */
-	VecSetValues(pg,numdof,doflist,(const double*)P_terms,ADD_VALUES);
-
-	/* Ice/ocean heat exchange flux on ice shelf base */
-	if(onbed && shelf){
-
-		tria=(Tria*)SpawnTria(0,1,2); //grids 0, 1 and 2 make the new tria.
-		tria->CreatePVectorThermalShelf(pg, analysis_type,sub_analysis_type);
-		delete tria;
-	}
-
-	/* Geothermal flux on ice sheet base and basal friction */
-	if(onbed && !shelf){
-
-		tria=(Tria*)SpawnTria(0,1,2); //grids 0, 1 and 2 make the new tria.
-		tria->CreatePVectorThermalSheet(pg, analysis_type,sub_analysis_type);
-		delete tria;
-	}
-	extern int my_rank;
-
-	xfree((void**)&first_gauss_area_coord);
-	xfree((void**)&second_gauss_area_coord);
-	xfree((void**)&third_gauss_area_coord);
-	xfree((void**)&vert_gauss_coord);
-	xfree((void**)&area_gauss_weights);
-	xfree((void**)&vert_gauss_weights);
-
-}
-/*}}}*/
-/*FUNCTION Du {{{1*/
-void  Penta::Du(Vec du_g,int analysis_type,int sub_analysis_type){
-
-	int i;
-	Tria* tria=NULL;
-
-	/*inputs: */
-	bool onwater;
-	bool collapse;
-	bool onsurface;
-	bool onbed;
-
-	/*retrieve inputs :*/
-	inputs->GetParameterValue(&onwater,ElementOnWaterEnum);
-	inputs->GetParameterValue(&collapse,CollapseEnum);
-	inputs->GetParameterValue(&onbed,ElementOnBedEnum);
-	inputs->GetParameterValue(&onsurface,ElementOnSurfaceEnum);
-
-	/*If on water, skip: */
-	if(onwater)return;
-
-	/*Bail out if this element if:
-	 * -> Non collapsed and not on the surface
-	 * -> collapsed (2d model) and not on bed) */
-	if ((!collapse && !onsurface) || (collapse && !onbed)){
-		return;
-	}
-	else if (collapse){
-
-		/*This element should be collapsed into a tria element at its base. Create this tria element, 
-		 * and compute Du*/
-		tria=(Tria*)SpawnTria(0,1,2); //grids 0, 1 and 2 make the new tria (lower face).
-		tria->Du(du_g,analysis_type,sub_analysis_type);
-		delete tria;
-		return;
-	}
-	else{
-
-		tria=(Tria*)SpawnTria(3,4,5); //grids 3, 4 and 5 make the new tria (upper face).
-		tria->Du(du_g,analysis_type,sub_analysis_type);
-		delete tria;
-		return;
-	}
-}
-/*}}}*/
-/*FUNCTION FieldExtrude {{{1*/
-void  Penta::FieldExtrude(Vec field,double* field_serial,char* field_name, int iscollapsed){
-
-	/* node data: */
-	const int    numgrids=6;
-	int          numberofdofspernode;
-	Node* node=NULL;
-	int   i;
-	int   extrude=0;
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-
-	/*inputs: */
-	bool collapse;
-	bool onbed;
-
-	/*retrieve inputs :*/
-	inputs->GetParameterValue(&collapse,CollapseEnum);
-	inputs->GetParameterValue(&onbed,ElementOnBedEnum);
-
-	/*Figure out if we should extrude for this element: */
-	if (iscollapsed){
-		/*From higher level, we are told to extrude only elements that have the collapse flag on: */
-		if (collapse)extrude=1;
-		else extrude=0;
-	}
-	else{
-		/*From higher level, we are told to extrude all elements: */
-		extrude=1;
-	}
-
-	/*Now, extrusion starts from the bed on, so double check this element is on 
-	 * the bedrock: */
-	if(onbed==0)extrude=0;
-
-	/*Go on and extrude field: */
-	if (extrude){
-
-		if (strcmp(field_name,"velocity")==0){
-
-			/* node data: */
-			const int    numdof=2*numgrids;
-			int          doflist[numdof];
-			int          nodedofs[2];
-			double       fieldel[2];
-
-
-			GetDofList(&doflist[0],&numberofdofspernode);
-
-			/*this penta is a collapsed macayeal. For each node on the base of this penta, 
-			 * we grab the field. Once we know the field, we follow the upper nodes, 
-			 * inserting the same field value into field, until we reach the surface: */
-			for(i=0;i<3;i++){
-
-				node=nodes[i]; //base nodes
-
-				/*get field for this base node: */
-				fieldel[0]=field_serial[doflist[numberofdofspernode*i+0]];
-				fieldel[1]=field_serial[doflist[numberofdofspernode*i+1]];
-
-				//go throfieldn all nodes which sit on top of this node, until we reach the surface, 
-				//and plfield  field in field
-				for(;;){
-
-					node->GetDofList(&nodedofs[0],&numberofdofspernode);
-					VecSetValues(field,1,&nodedofs[0],&fieldel[0],INSERT_VALUES);
-					VecSetValues(field,1,&nodedofs[1],&fieldel[1],INSERT_VALUES);
-
-					if (node->IsOnSurface())break;
-					/*get next node: */
-					node=node->GetUpperNode();
-				}
-			}
-		} //if (strcmp(field_name,"velocity")==0)
-		else if (strcmp(field_name,"gradj")==0){
-
-			/* node data: */
-			int          dof1;
-			double       fieldel;
-
-			/*this penta is a collapsed macayeal. For each node on the base of this penta, 
-			 * we grab the field. Once we know the field, we follow the upper nodes, 
-			 * inserting the same field value into field, until we reach the surface: */
-			for(i=0;i<3;i++){
-
-				node=nodes[i]; //base nodes
-				dof1=node->GetDofList1();
-
-				/*get field for this base node: */
-				fieldel=field_serial[dof1];
-
-				//go throfieldn all nodes which sit on top of this node, until we reach the surface, 
-				//and plfield  field in field
-				for(;;){
-
-					dof1=node->GetDofList1();
-					VecSetValues(field,1,&dof1,&fieldel,INSERT_VALUES);
-
-					if (node->IsOnSurface())break;
-					/*get next node: */
-					node=node->GetUpperNode();
-				}
-			}
-		}
-		else if ( 
-					(strcmp(field_name,"thickness")==0) ||
-					(strcmp(field_name,"surface")==0)  ||
-					(strcmp(field_name,"bed")==0)  ||
-					(strcmp(field_name,"slopex")==0)  ||
-					(strcmp(field_name,"slopey")==0)
-				  ){
-
-			/* node data: */
-			const int    numdof=1*numgrids;
-			int          doflist[numdof];
-			int          nodedofs;
-			double       fieldel;
-
-			GetDofList(&doflist[0],&numberofdofspernode);
-
-			/*this penta is on the bed. For each node on the base of this penta, 
-			 * we grab the thickness. Once we know the thickness, we follow the upper nodes, 
-			 * inserting the same thickness value into tg, until we reach the surface: */
-			for(i=0;i<3;i++){
-
-				node=nodes[i]; //base nodes
-
-				/*get velocity for this base node: */
-				fieldel=field_serial[doflist[numberofdofspernode*i+0]];
-
-				//go through all nodes which sit on top of this node, until we reach the surface, 
-				//and pltg  fieldel in field:
-				for(;;){
-
-					node->GetDofList(&nodedofs,&numberofdofspernode);
-					VecSetValues(field,1,&nodedofs,&fieldel,INSERT_VALUES);
-
-					if (node->IsOnSurface())break;
-					/*get next node: */
-					node=node->GetUpperNode();
-				}
-			}
-
-		}
-		else ISSMERROR("%s%s%s"," field ",field_name," not supported yet!");
-
-	} //if (extrude)
-}
-/*}}}*/
-/*FUNCTION GetB {{{1*/
-void Penta::GetB(double* B, double* xyz_list, double* gauss_coord){
-
-	/*Compute B  matrix. B=[B1 B2 B3 B4 B5 B6] where Bi is of size 5*NDOF2. 
-	 * For grid i, Bi can be expressed in the actual coordinate system
-	 * by: 
-	 *       Bi=[ dh/dx          0      ]
-	 *                [   0           dh/dy   ]
-	 *                [ 1/2*dh/dy  1/2*dh/dx  ]
-	 *                [ 1/2*dh/dz      0      ]
-	 *                [  0         1/2*dh/dz  ]
-	 * where h is the interpolation function for grid i.
-	 *
-	 * We assume B has been allocated already, of size: 5x(NDOF2*numgrids)
-	 */
-
-	int i;
-	const int numgrids=6;
-	const int NDOF3=3;
-	const int NDOF2=2;
-
-	double dh1dh6[NDOF3][numgrids];
-
-	/*Get dh1dh6 in actual coordinate system: */
-	GetNodalFunctionsDerivatives(&dh1dh6[0][0],xyz_list, gauss_coord);
-
-	/*Build B: */
-	for (i=0;i<numgrids;i++){
-		*(B+NDOF2*numgrids*0+NDOF2*i)=dh1dh6[0][i]; 
-		*(B+NDOF2*numgrids*0+NDOF2*i+1)=0.0;
-
-		*(B+NDOF2*numgrids*1+NDOF2*i)=0.0;
-		*(B+NDOF2*numgrids*1+NDOF2*i+1)=dh1dh6[1][i];
-
-		*(B+NDOF2*numgrids*2+NDOF2*i)=(float).5*dh1dh6[1][i]; 
-		*(B+NDOF2*numgrids*2+NDOF2*i+1)=(float).5*dh1dh6[0][i]; 
-
-		*(B+NDOF2*numgrids*3+NDOF2*i)=(float).5*dh1dh6[2][i]; 
-		*(B+NDOF2*numgrids*3+NDOF2*i+1)=0.0;
-
-		*(B+NDOF2*numgrids*4+NDOF2*i)=0.0;
-		*(B+NDOF2*numgrids*4+NDOF2*i+1)=(float).5*dh1dh6[2][i]; 
-	}
-
-}
-/*}}}*/
-/*FUNCTION GetB_artdiff {{{1*/
-void Penta::GetB_artdiff(double* B_artdiff, double* xyz_list, double* gauss_coord){
-
-	/*Compute B  matrix. B=[B1 B2 B3 B4 B5 B6] where Bi is of size 5*DOFPERGRID. 
-	 * For grid i, Bi' can be expressed in the actual coordinate system
-	 * by: 
-	 *       Bi_artdiff=[ dh/dx ]
-	 *                       [ dh/dy ]
-	 * where h is the interpolation function for grid i.
-	 *
-	 * We assume B has been allocated already, of size: 2x(DOFPERGRID*numgrids)
-	 */
-
-	int i;
-	const int calculationdof=3;
-	const int numgrids=6;
-	int DOFPERGRID=1;
-
-	/*Same thing in the actual coordinate system: */
-	double dh1dh6[calculationdof][numgrids];
-
-	/*Get dh1dh2dh3 in actual coordinates system : */
-	GetNodalFunctionsDerivatives(&dh1dh6[0][0],xyz_list,gauss_coord);
-
-	/*Build B': */
-	for (i=0;i<numgrids;i++){
-		*(B_artdiff+DOFPERGRID*numgrids*0+DOFPERGRID*i)=dh1dh6[0][i]; 
-		*(B_artdiff+DOFPERGRID*numgrids*1+DOFPERGRID*i)=dh1dh6[1][i]; 
-	}
-}
-/*}}}*/
-/*FUNCTION GetB_advec {{{1*/
-void Penta::GetB_advec(double* B_advec, double* xyz_list, double* gauss_coord){
-
-	/*Compute B  matrix. B=[B1 B2 B3 B4 B5 B6] where Bi is of size 5*DOFPERGRID. 
-	 * For grid i, Bi' can be expressed in the actual coordinate system
-	 * by: 
-	 *       Bi_advec =[ h ]
-	 *                       [ h ]
-	 *                       [ h ]
-	 * where h is the interpolation function for grid i.
-	 *
-	 * We assume B has been allocated already, of size: 3x(DOFPERGRID*numgrids)
-	 */
-
-	int i;
-	int calculationdof=3;
-	int numgrids=6;
-	int DOFPERGRID=1;
-
-	/*Same thing in the actual coordinate system: */
-	double l1l6[6];
-
-	/*Get dh1dh2dh3 in actual coordinates system : */
-	GetNodalFunctions(l1l6, gauss_coord);
-
-	/*Build B': */
-	for (i=0;i<numgrids;i++){
-		*(B_advec+DOFPERGRID*numgrids*0+DOFPERGRID*i)=l1l6[i]; 
-		*(B_advec+DOFPERGRID*numgrids*1+DOFPERGRID*i)=l1l6[i]; 
-		*(B_advec+DOFPERGRID*numgrids*2+DOFPERGRID*i)=l1l6[i]; 
-	}
-}
-/*}}}*/
-/*FUNCTION GetB_conduct {{{1*/
-void Penta::GetB_conduct(double* B_conduct, double* xyz_list, double* gauss_coord){
-
-	/*Compute B  matrix. B=[B1 B2 B3 B4 B5 B6] where Bi is of size 5*DOFPERGRID. 
-	 * For grid i, Bi' can be expressed in the actual coordinate system
-	 * by: 
-	 *       Bi_conduct=[ dh/dx ]
-	 *                       [ dh/dy ]
-	 *                       [ dh/dz ]
-	 * where h is the interpolation function for grid i.
-	 *
-	 * We assume B has been allocated already, of size: 3x(DOFPERGRID*numgrids)
-	 */
-
-	int i;
-	const int calculationdof=3;
-	const int numgrids=6;
-	int DOFPERGRID=1;
-
-	/*Same thing in the actual coordinate system: */
-	double dh1dh6[calculationdof][numgrids];
-
-	/*Get dh1dh2dh3 in actual coordinates system : */
-	GetNodalFunctionsDerivatives(&dh1dh6[0][0],xyz_list,gauss_coord);
-
-	/*Build B': */
-	for (i=0;i<numgrids;i++){
-		*(B_conduct+DOFPERGRID*numgrids*0+DOFPERGRID*i)=dh1dh6[0][i]; 
-		*(B_conduct+DOFPERGRID*numgrids*1+DOFPERGRID*i)=dh1dh6[1][i]; 
-		*(B_conduct+DOFPERGRID*numgrids*2+DOFPERGRID*i)=dh1dh6[2][i]; 
-	}
-}
-/*}}}*/
-/*FUNCTION GetB_vert {{{1*/
-void Penta::GetB_vert(double* B, double* xyz_list, double* gauss_coord){
-
-
-	/*	Compute B  matrix. B=[dh1/dz dh2/dz dh3/dz dh4/dz dh5/dz dh6/dz];
-		where hi is the interpolation function for grid i.*/
-
-	int i;
-	const int NDOF3=3;
-	const int numgrids=6;
-	double dh1dh6[NDOF3][numgrids];
-
-	/*Get dh1dh6 in actual coordinate system: */
-	GetNodalFunctionsDerivatives(&dh1dh6[0][0],xyz_list, gauss_coord);
-
-	/*Build B: */
-	for (i=0;i<numgrids;i++){
-		B[i]=dh1dh6[2][i];  
-	}
-
-}
-/*}}}*/
-/*FUNCTION GetBedList {{{1*/
-void Penta::GetBedList(double* bedlist){
-
-	const int numgrids=6;
-	double  gaussgrids[numgrids][numgrids]={{1,0,0,0},{0,1,0,0},{0,0,1,0},{1,0,0,1},{0,1,0,1},{0,0,1,1}};
-	
-	inputs->GetParameterValues(bedlist,&gaussgrids[0][0],6,BedEnum);
-
-}
-/*}}}*/
-/*FUNCTION GetBPrime {{{1*/
-void Penta::GetBPrime(double* B, double* xyz_list, double* gauss_coord){
-
-	/*Compute B  prime matrix. B=[B1 B2 B3 B4 B5 B6] where Bi is of size 5*NDOF2. 
-	 * For grid i, Bi can be expressed in the actual coordinate system
-	 * by: 
-	 *       Bi=[ 2*dh/dx     dh/dy   ]
-	 *                [   dh/dx    2*dh/dy  ]
-	 *                [ dh/dy      dh/dx    ]
-	 *                [ dh/dz         0     ]
-	 *                [  0         dh/dz    ]
-	 * where h is the interpolation function for grid i.
-	 *
-	 * We assume B has been allocated already, of size: 5x(NDOF2*numgrids)
-	 */
-
-	int i;
-	const int NDOF3=3;
-	const int NDOF2=2;
-	const int numgrids=6;
-
-	double dh1dh6[NDOF3][numgrids];
-
-	/*Get dh1dh6 in actual coordinate system: */
-	GetNodalFunctionsDerivatives(&dh1dh6[0][0],xyz_list, gauss_coord);
-
-	/*Build BPrime: */
-	for (i=0;i<numgrids;i++){
-		*(B+NDOF2*numgrids*0+NDOF2*i)=2.0*dh1dh6[0][i]; 
-		*(B+NDOF2*numgrids*0+NDOF2*i+1)=dh1dh6[1][i];
-
-		*(B+NDOF2*numgrids*1+NDOF2*i)=dh1dh6[0][i];
-		*(B+NDOF2*numgrids*1+NDOF2*i+1)=2.0*dh1dh6[1][i];
-
-		*(B+NDOF2*numgrids*2+NDOF2*i)=dh1dh6[1][i]; 
-		*(B+NDOF2*numgrids*2+NDOF2*i+1)=dh1dh6[0][i]; 
-
-		*(B+NDOF2*numgrids*3+NDOF2*i)=dh1dh6[2][i]; 
-		*(B+NDOF2*numgrids*3+NDOF2*i+1)=0.0;
-
-		*(B+NDOF2*numgrids*4+NDOF2*i)=0.0;
-		*(B+NDOF2*numgrids*4+NDOF2*i+1)=dh1dh6[2][i]; 
-	}
-}
-/*}}}*/
-/*FUNCTION GetBprime_advec {{{1*/
-void Penta::GetBprime_advec(double* Bprime_advec, double* xyz_list, double* gauss_coord){
-
-
-	/*Compute B  matrix. B=[B1 B2 B3 B4 B5 B6] where Bi is of size 5*DOFPERGRID. 
-	 * For grid i, Bi' can be expressed in the actual coordinate system
-	 * by: 
-	 *       Biprime_advec=[ dh/dx ]
-	 *                       [ dh/dy ]
-	 *                       [ dh/dz ]
-	 * where h is the interpolation function for grid i.
-	 *
-	 * We assume B has been allocated already, of size: 3x(DOFPERGRID*numgrids)
-	 */
-
-	int i;
-	const int calculationdof=3;
-	const int numgrids=6;
-	int DOFPERGRID=1;
-
-	/*Same thing in the actual coordinate system: */
-	double dh1dh6[calculationdof][numgrids];
-
-	/*Get dh1dh2dh3 in actual coordinates system : */
-	GetNodalFunctionsDerivatives(&dh1dh6[0][0],xyz_list,gauss_coord);
-
-	/*Build B': */
-	for (i=0;i<numgrids;i++){
-		*(Bprime_advec+DOFPERGRID*numgrids*0+DOFPERGRID*i)=dh1dh6[0][i]; 
-		*(Bprime_advec+DOFPERGRID*numgrids*1+DOFPERGRID*i)=dh1dh6[1][i]; 
-		*(Bprime_advec+DOFPERGRID*numgrids*2+DOFPERGRID*i)=dh1dh6[2][i]; 
-	}
-}
-/*}}}*/
-/*FUNCTION GetBPrime_vert {{{1*/
-void Penta::GetBPrime_vert(double* B, double* xyz_list, double* gauss_coord){
-
-	// Compute Bprime  matrix. Bprime=[L1 L2 L3 L4 L5 L6] where Li is the nodal function for grid i
-
-	int i;
-
-	GetNodalFunctions(B, gauss_coord);
-
-}
-/*}}}*/
-/*FUNCTION GetBprimeStokes {{{1*/
-void Penta::GetBprimeStokes(double* B_prime, double* xyz_list, double* gauss_coord){
-
-	/*	Compute B'  matrix. B'=[B1' B2' B3' B4' B5' B6' Bb'] where Bi' is of size 3*NDOF2. 
-	 *	For grid i, Bi' can be expressed in the actual coordinate system
-	 *	by: 
-	 *				Bi'=[ dh/dx   0          0       0]
-	 *					 [   0      dh/dy      0       0]
-	 *					 [   0      0         dh/dz    0]
-	 *					 [  dh/dy   dh/dx      0       0]
-	 *					 [  dh/dz   0        dh/dx     0]
-	 *					 [   0      dh/dz    dh/dy     0]
-	 *					 [  dh/dx   dh/dy    dh/dz     0]
-	 *					 [   0      0          0       h]
-	 *	where h is the interpolation function for grid i.
-	 *
-	 * 	Same thing for the bubble fonction except that there is no fourth column
-	 */
-
-	int i;
-	const int calculationdof=3;
-	const int numgrids=6;
-	int DOFPERGRID=4;
-
-	double dh1dh7[calculationdof][numgrids+1];
-	double l1l6[numgrids];
-
-	/*Get dh1dh7 in actual coordinate system: */
-	GetNodalFunctionsDerivativesStokes(&dh1dh7[0][0],xyz_list, gauss_coord);
-
-	GetNodalFunctions(l1l6, gauss_coord);
-
-	/*B_primeuild B_prime: */
-	for (i=0;i<numgrids+1;i++){
-		*(B_prime+(DOFPERGRID*numgrids+3)*0+DOFPERGRID*i)=dh1dh7[0][i]; //B_prime[0][DOFPERGRID*i]=dh1dh6[0][i];
-		*(B_prime+(DOFPERGRID*numgrids+3)*0+DOFPERGRID*i+1)=0;
-		*(B_prime+(DOFPERGRID*numgrids+3)*0+DOFPERGRID*i+2)=0;
-		*(B_prime+(DOFPERGRID*numgrids+3)*1+DOFPERGRID*i)=0;
-		*(B_prime+(DOFPERGRID*numgrids+3)*1+DOFPERGRID*i+1)=dh1dh7[1][i];
-		*(B_prime+(DOFPERGRID*numgrids+3)*1+DOFPERGRID*i+2)=0;
-		*(B_prime+(DOFPERGRID*numgrids+3)*2+DOFPERGRID*i)=0;
-		*(B_prime+(DOFPERGRID*numgrids+3)*2+DOFPERGRID*i+1)=0;
-		*(B_prime+(DOFPERGRID*numgrids+3)*2+DOFPERGRID*i+2)=dh1dh7[2][i];
-		*(B_prime+(DOFPERGRID*numgrids+3)*3+DOFPERGRID*i)=dh1dh7[1][i]; 
-		*(B_prime+(DOFPERGRID*numgrids+3)*3+DOFPERGRID*i+1)=dh1dh7[0][i]; 
-		*(B_prime+(DOFPERGRID*numgrids+3)*3+DOFPERGRID*i+2)=0;
-		*(B_prime+(DOFPERGRID*numgrids+3)*4+DOFPERGRID*i)=dh1dh7[2][i];
-		*(B_prime+(DOFPERGRID*numgrids+3)*4+DOFPERGRID*i+1)=0;
-		*(B_prime+(DOFPERGRID*numgrids+3)*4+DOFPERGRID*i+2)=dh1dh7[0][i];
-		*(B_prime+(DOFPERGRID*numgrids+3)*5+DOFPERGRID*i)=0;
-		*(B_prime+(DOFPERGRID*numgrids+3)*5+DOFPERGRID*i+1)=dh1dh7[2][i];
-		*(B_prime+(DOFPERGRID*numgrids+3)*5+DOFPERGRID*i+2)=dh1dh7[1][i];
-		*(B_prime+(DOFPERGRID*numgrids+3)*6+DOFPERGRID*i)=dh1dh7[0][i];
-		*(B_prime+(DOFPERGRID*numgrids+3)*6+DOFPERGRID*i+1)=dh1dh7[1][i];
-		*(B_prime+(DOFPERGRID*numgrids+3)*6+DOFPERGRID*i+2)=dh1dh7[2][i];
-		*(B_prime+(DOFPERGRID*numgrids+3)*7+DOFPERGRID*i)=0;
-		*(B_prime+(DOFPERGRID*numgrids+3)*7+DOFPERGRID*i+1)=0;
-		*(B_prime+(DOFPERGRID*numgrids+3)*7+DOFPERGRID*i+2)=0;
-	}
-
-	for (i=0;i<numgrids;i++){ //last column not for the bubble function
-		*(B_prime+(DOFPERGRID*numgrids+3)*0+DOFPERGRID*i+3)=0;
-		*(B_prime+(DOFPERGRID*numgrids+3)*1+DOFPERGRID*i+3)=0;
-		*(B_prime+(DOFPERGRID*numgrids+3)*2+DOFPERGRID*i+3)=0;
-		*(B_prime+(DOFPERGRID*numgrids+3)*3+DOFPERGRID*i+3)=0;
-		*(B_prime+(DOFPERGRID*numgrids+3)*4+DOFPERGRID*i+3)=0;
-		*(B_prime+(DOFPERGRID*numgrids+3)*5+DOFPERGRID*i+3)=0;
-		*(B_prime+(DOFPERGRID*numgrids+3)*6+DOFPERGRID*i+3)=0;
-		*(B_prime+(DOFPERGRID*numgrids+3)*7+DOFPERGRID*i+3)=l1l6[i];
-	}
-
-}
-/*}}}*/
-/*FUNCTION GetBStokes {{{1*/
-void Penta::GetBStokes(double* B, double* xyz_list, double* gauss_coord){
-
-	/*Compute B  matrix. B=[B1 B2 B3 B4 B5 B6] where Bi is of size 3*DOFPERGRID. 
-	 * For grid i, Bi can be expressed in the actual coordinate system
-	 * by: 				Bi=[ dh/dx          0             0       0  ]
-	 *					[   0           dh/dy           0       0  ]
-	 *					[   0             0           dh/dy     0  ]
-	 *					[ 1/2*dh/dy    1/2*dh/dx        0       0  ]
-	 *					[ 1/2*dh/dz       0         1/2*dh/dx   0  ]
-	 *					[   0          1/2*dh/dz    1/2*dh/dy   0  ]
-	 *					[   0             0             0       h  ]
-	 *					[ dh/dx         dh/dy         dh/dz     0  ]
-	 *	where h is the interpolation function for grid i.
-	 *	Same thing for Bb except the last column that does not exist.
-	 */
-
-	int i;
-	const int calculationdof=3;
-	const int numgrids=6;
-	int DOFPERGRID=4;
-
-	double dh1dh7[calculationdof][numgrids+1];
-	double l1l6[numgrids];
-
-
-	/*Get dh1dh7 in actual coordinate system: */
-	GetNodalFunctionsDerivativesStokes(&dh1dh7[0][0],xyz_list, gauss_coord);
-
-	GetNodalFunctions(l1l6, gauss_coord);
-
-	/*Build B: */
-	for (i=0;i<numgrids+1;i++){
-		*(B+(DOFPERGRID*numgrids+3)*0+DOFPERGRID*i)=dh1dh7[0][i]; //B[0][DOFPERGRID*i]=dh1dh6[0][i];
-		*(B+(DOFPERGRID*numgrids+3)*0+DOFPERGRID*i+1)=0;
-		*(B+(DOFPERGRID*numgrids+3)*0+DOFPERGRID*i+2)=0;
-		*(B+(DOFPERGRID*numgrids+3)*1+DOFPERGRID*i)=0;
-		*(B+(DOFPERGRID*numgrids+3)*1+DOFPERGRID*i+1)=dh1dh7[1][i];
-		*(B+(DOFPERGRID*numgrids+3)*1+DOFPERGRID*i+2)=0;
-		*(B+(DOFPERGRID*numgrids+3)*2+DOFPERGRID*i)=0;
-		*(B+(DOFPERGRID*numgrids+3)*2+DOFPERGRID*i+1)=0;
-		*(B+(DOFPERGRID*numgrids+3)*2+DOFPERGRID*i+2)=dh1dh7[2][i];
-		*(B+(DOFPERGRID*numgrids+3)*3+DOFPERGRID*i)=(float).5*dh1dh7[1][i]; 
-		*(B+(DOFPERGRID*numgrids+3)*3+DOFPERGRID*i+1)=(float).5*dh1dh7[0][i]; 
-		*(B+(DOFPERGRID*numgrids+3)*3+DOFPERGRID*i+2)=0;
-		*(B+(DOFPERGRID*numgrids+3)*4+DOFPERGRID*i)=(float).5*dh1dh7[2][i];
-		*(B+(DOFPERGRID*numgrids+3)*4+DOFPERGRID*i+1)=0;
-		*(B+(DOFPERGRID*numgrids+3)*4+DOFPERGRID*i+2)=(float).5*dh1dh7[0][i];
-		*(B+(DOFPERGRID*numgrids+3)*5+DOFPERGRID*i)=0;
-		*(B+(DOFPERGRID*numgrids+3)*5+DOFPERGRID*i+1)=(float).5*dh1dh7[2][i];
-		*(B+(DOFPERGRID*numgrids+3)*5+DOFPERGRID*i+2)=(float).5*dh1dh7[1][i];
-		*(B+(DOFPERGRID*numgrids+3)*6+DOFPERGRID*i)=0;
-		*(B+(DOFPERGRID*numgrids+3)*6+DOFPERGRID*i+1)=0;
-		*(B+(DOFPERGRID*numgrids+3)*6+DOFPERGRID*i+2)=0;
-		*(B+(DOFPERGRID*numgrids+3)*7+DOFPERGRID*i)=dh1dh7[0][i];
-		*(B+(DOFPERGRID*numgrids+3)*7+DOFPERGRID*i+1)=dh1dh7[1][i];
-		*(B+(DOFPERGRID*numgrids+3)*7+DOFPERGRID*i+2)=dh1dh7[2][i];
-	}
-
-	for (i=0;i<numgrids;i++){ //last column not for the bubble function
-		*(B+(DOFPERGRID*numgrids+3)*0+DOFPERGRID*i+3)=0;
-		*(B+(DOFPERGRID*numgrids+3)*1+DOFPERGRID*i+3)=0;
-		*(B+(DOFPERGRID*numgrids+3)*2+DOFPERGRID*i+3)=0;
-		*(B+(DOFPERGRID*numgrids+3)*3+DOFPERGRID*i+3)=0;
-		*(B+(DOFPERGRID*numgrids+3)*4+DOFPERGRID*i+3)=0;
-		*(B+(DOFPERGRID*numgrids+3)*5+DOFPERGRID*i+3)=0;
-		*(B+(DOFPERGRID*numgrids+3)*6+DOFPERGRID*i+3)=l1l6[i];
-		*(B+(DOFPERGRID*numgrids+3)*7+DOFPERGRID*i+3)=0;
-	}
-
-}
-/*}}}*/
-/*FUNCTION GetDofList {{{1*/
-void  Penta::GetDofList(int* doflist,int* pnumberofdofspernode){
-
-	int i,j;
-	int doflist_per_node[MAXDOFSPERNODE];
-	int numberofdofspernode;
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-
-	for(i=0;i<6;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;
-
-}
-/*}}}*/
-/*FUNCTION GetDofList1 {{{1*/
-void  Penta::GetDofList1(int* doflist){
-	
-	int i;
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-
-	for(i=0;i<6;i++){
-		doflist[i]=nodes[i]->GetDofList1();
-	}
-
-}
-/*}}}*/
-/*FUNCTION Id {{{1*/
-int    Penta::Id(void){
-	return id; 
-}
-/*}}}*/
-/*FUNCTION GetJacobian {{{1*/
-void Penta::GetJacobian(double* J, double* xyz_list,double* gauss_coord){
-
-	const int NDOF3=3;
-	int i,j;
-
-	/*The Jacobian is constant over the element, discard the gaussian points. 
-	 * J is assumed to have been allocated of size NDOF2xNDOF2.*/
-
-	double A1,A2,A3; //area coordinates
-	double xi,eta,zi; //parametric coordinates
-
-	double x1,x2,x3,x4,x5,x6;
-	double y1,y2,y3,y4,y5,y6;
-	double z1,z2,z3,z4,z5,z6;
-
-	/*Figure out xi,eta and zi (parametric coordinates), for this gaussian point: */
-	A1=gauss_coord[0];
-	A2=gauss_coord[1];
-	A3=gauss_coord[2];
-
-	xi=A2-A1;
-	eta=SQRT3*A3;
-	zi=gauss_coord[3];
-
-	x1=*(xyz_list+3*0+0);
-	x2=*(xyz_list+3*1+0);
-	x3=*(xyz_list+3*2+0);
-	x4=*(xyz_list+3*3+0);
-	x5=*(xyz_list+3*4+0);
-	x6=*(xyz_list+3*5+0);
-
-	y1=*(xyz_list+3*0+1);
-	y2=*(xyz_list+3*1+1);
-	y3=*(xyz_list+3*2+1);
-	y4=*(xyz_list+3*3+1);
-	y5=*(xyz_list+3*4+1);
-	y6=*(xyz_list+3*5+1);
-
-	z1=*(xyz_list+3*0+2);
-	z2=*(xyz_list+3*1+2);
-	z3=*(xyz_list+3*2+2);
-	z4=*(xyz_list+3*3+2);
-	z5=*(xyz_list+3*4+2);
-	z6=*(xyz_list+3*5+2);
-
-
-	*(J+NDOF3*0+0)=0.25*(x1-x2-x4+x5)*zi+0.25*(-x1+x2-x4+x5);
-	*(J+NDOF3*1+0)=SQRT3/12.0*(x1+x2-2*x3-x4-x5+2*x6)*zi+SQRT3/12.0*(-x1-x2+2*x3-x4-x5+2*x6);
-	*(J+NDOF3*2+0)=SQRT3/12.0*(x1+x2-2*x3-x4-x5+2*x6)*eta+1/4*(x1-x2-x4+x5)*xi +0.25*(-x1+x5-x2+x4);
-
-	*(J+NDOF3*0+1)=0.25*(y1-y2-y4+y5)*zi+0.25*(-y1+y2-y4+y5);
-	*(J+NDOF3*1+1)=SQRT3/12.0*(y1+y2-2*y3-y4-y5+2*y6)*zi+SQRT3/12.0*(-y1-y2+2*y3-y4-y5+2*y6);
-	*(J+NDOF3*2+1)=SQRT3/12.0*(y1+y2-2*y3-y4-y5+2*y6)*eta+0.25*(y1-y2-y4+y5)*xi+0.25*(y4-y1+y5-y2);
-
-	*(J+NDOF3*0+2)=0.25*(z1-z2-z4+z5)*zi+0.25*(-z1+z2-z4+z5);
-	*(J+NDOF3*1+2)=SQRT3/12.0*(z1+z2-2*z3-z4-z5+2*z6)*zi+SQRT3/12.0*(-z1-z2+2*z3-z4-z5+2*z6);
-	*(J+NDOF3*2+2)=SQRT3/12.0*(z1+z2-2*z3-z4-z5+2*z6)*eta+0.25*(z1-z2-z4+z5)*xi+0.25*(-z1+z5-z2+z4);
-
-}
-/*}}}*/
-/*FUNCTION GetJacobianDeterminant {{{1*/
-void Penta::GetJacobianDeterminant(double*  Jdet, double* xyz_list,double* gauss_coord){
-
-	/*On a penta, Jacobian varies according to coordinates. We need to get the Jacobian, and take 
-	 * the determinant of it: */
-	const int NDOF3=3;
-
-	double J[NDOF3][NDOF3];
-
-	GetJacobian(&J[0][0],xyz_list,gauss_coord);
-
-	*Jdet= J[0][0]*J[1][1]*J[2][2]-J[0][0]*J[1][2]*J[2][1]-J[1][0]*J[0][1]*J[2][2]+J[1][0]*J[0][2]*J[2][1]+J[2][0]*J[0][1]*J[1][2]-J[2][0]*J[0][2]*J[1][1];
-
-	if(*Jdet<0){
-		ISSMERROR("%s%i","negative jacobian determinant on element ",id); 
-	}
-}
-/*}}}*/
-/*FUNCTION GetJacobianInvert {{{1*/
-void Penta::GetJacobianInvert(double*  Jinv, double* xyz_list,double* gauss_coord){
-
-	double Jdet;
-	const int NDOF3=3;
-
-	/*Call Jacobian routine to get the jacobian:*/
-	GetJacobian(Jinv, xyz_list, gauss_coord);
-
-	/*Invert Jacobian matrix: */
-	MatrixInverse(Jinv,NDOF3,NDOF3,NULL,0,&Jdet);
-}
-/*}}}*/
-/*FUNCTION GetLStokes {{{1*/
-void Penta::GetLStokes(double* LStokes, double* gauss_coord_tria){
-
-	/*
-	 * Compute L  matrix. L=[L1 L2 L3] where Li is square and of size numdof. 
-	 * For grid i, Li can be expressed in the actual coordinate system
-	 * by: 
-	 *       Li=[ h    0    0   0]
-	 *	 	 [ 0    h    0   0]
-	 *		 [ 0    0    h   0]
-	 *		 [ 0    0    h   0]
-	 *	 	 [ h    0    0   0]
-	 *	 	 [ 0    h    0   0]
-	 *	 	 [ h    0    0   0]
-	 *	 	 [ 0    h    0   0]
-	 *		 [ 0    0    h   0]
-	 *		 [ 0    0    h   0]
-	 *		 [ 0    0    h   0]
-	 *	 	 [ h    0    0   0]
-	 *	 	 [ 0    h    0   0]
-	 *		 [ 0    0    h   0]
-	 * where h is the interpolation function for grid i.
-	 */
-
-	int i;
-	const int numgrids2d=3;
-	int num_dof=4;
-
-	double l1l2l3[numgrids2d];
-
-
-	/*Get l1l2l3 in actual coordinate system: */
-	l1l2l3[0]=gauss_coord_tria[0];
-	l1l2l3[1]=gauss_coord_tria[1];
-	l1l2l3[2]=gauss_coord_tria[2];
-
-	/*Build LStokes: */
-	for (i=0;i<3;i++){
-		*(LStokes+num_dof*numgrids2d*0+num_dof*i)=l1l2l3[i]; //LStokes[0][NDOF2*i]=dh1dh3[0][i];
-		*(LStokes+num_dof*numgrids2d*0+num_dof*i+1)=0;
-		*(LStokes+num_dof*numgrids2d*0+num_dof*i+2)=0;
-		*(LStokes+num_dof*numgrids2d*0+num_dof*i+3)=0;
-		*(LStokes+num_dof*numgrids2d*1+num_dof*i)=0;
-		*(LStokes+num_dof*numgrids2d*1+num_dof*i+1)=l1l2l3[i];
-		*(LStokes+num_dof*numgrids2d*1+num_dof*i+2)=0;
-		*(LStokes+num_dof*numgrids2d*1+num_dof*i+3)=0;
-		*(LStokes+num_dof*numgrids2d*2+num_dof*i)=0;
-		*(LStokes+num_dof*numgrids2d*2+num_dof*i+1)=0;
-		*(LStokes+num_dof*numgrids2d*2+num_dof*i+2)=l1l2l3[i];
-		*(LStokes+num_dof*numgrids2d*2+num_dof*i+3)=0;
-		*(LStokes+num_dof*numgrids2d*3+num_dof*i)=0;
-		*(LStokes+num_dof*numgrids2d*3+num_dof*i+1)=0;
-		*(LStokes+num_dof*numgrids2d*3+num_dof*i+2)=l1l2l3[i];
-		*(LStokes+num_dof*numgrids2d*3+num_dof*i+3)=0;
-		*(LStokes+num_dof*numgrids2d*4+num_dof*i)=l1l2l3[i];
-		*(LStokes+num_dof*numgrids2d*4+num_dof*i+1)=0;
-		*(LStokes+num_dof*numgrids2d*4+num_dof*i+2)=0;
-		*(LStokes+num_dof*numgrids2d*4+num_dof*i+3)=0;
-		*(LStokes+num_dof*numgrids2d*5+num_dof*i)=0;
-		*(LStokes+num_dof*numgrids2d*5+num_dof*i+1)=l1l2l3[i];
-		*(LStokes+num_dof*numgrids2d*5+num_dof*i+2)=0;
-		*(LStokes+num_dof*numgrids2d*5+num_dof*i+3)=0;
-		*(LStokes+num_dof*numgrids2d*6+num_dof*i)=l1l2l3[i];
-		*(LStokes+num_dof*numgrids2d*6+num_dof*i+1)=0;
-		*(LStokes+num_dof*numgrids2d*6+num_dof*i+2)=0;
-		*(LStokes+num_dof*numgrids2d*6+num_dof*i+3)=0;
-		*(LStokes+num_dof*numgrids2d*7+num_dof*i)=0;
-		*(LStokes+num_dof*numgrids2d*7+num_dof*i+1)=l1l2l3[i];
-		*(LStokes+num_dof*numgrids2d*7+num_dof*i+2)=0;
-		*(LStokes+num_dof*numgrids2d*7+num_dof*i+3)=0;
-		*(LStokes+num_dof*numgrids2d*8+num_dof*i)=0;
-		*(LStokes+num_dof*numgrids2d*8+num_dof*i+1)=0;
-		*(LStokes+num_dof*numgrids2d*8+num_dof*i+2)=l1l2l3[i];
-		*(LStokes+num_dof*numgrids2d*8+num_dof*i+3)=0;
-		*(LStokes+num_dof*numgrids2d*9+num_dof*i)=0;
-		*(LStokes+num_dof*numgrids2d*9+num_dof*i+1)=0;
-		*(LStokes+num_dof*numgrids2d*9+num_dof*i+2)=l1l2l3[i];
-		*(LStokes+num_dof*numgrids2d*9+num_dof*i+3)=0;
-		*(LStokes+num_dof*numgrids2d*10+num_dof*i)=0;
-		*(LStokes+num_dof*numgrids2d*10+num_dof*i+1)=0;
-		*(LStokes+num_dof*numgrids2d*10+num_dof*i+2)=l1l2l3[i];
-		*(LStokes+num_dof*numgrids2d*10+num_dof*i+3)=0;
-		*(LStokes+num_dof*numgrids2d*11+num_dof*i)=l1l2l3[i];
-		*(LStokes+num_dof*numgrids2d*11+num_dof*i+1)=0;
-		*(LStokes+num_dof*numgrids2d*11+num_dof*i+2)=0;
-		*(LStokes+num_dof*numgrids2d*11+num_dof*i+3)=0;
-		*(LStokes+num_dof*numgrids2d*12+num_dof*i)=0;
-		*(LStokes+num_dof*numgrids2d*12+num_dof*i+1)=l1l2l3[i];
-		*(LStokes+num_dof*numgrids2d*12+num_dof*i+2)=0;
-		*(LStokes+num_dof*numgrids2d*12+num_dof*i+3)=0;
-		*(LStokes+num_dof*numgrids2d*13+num_dof*i)=0;
-		*(LStokes+num_dof*numgrids2d*13+num_dof*i+1)=0;
-		*(LStokes+num_dof*numgrids2d*13+num_dof*i+2)=l1l2l3[i];
-		*(LStokes+num_dof*numgrids2d*13+num_dof*i+3)=0;
-
-	}
-}
-/*}}}*/
-/*FUNCTION GetLprimeStokes {{{1*/
-void Penta::GetLprimeStokes(double* LprimeStokes, double* xyz_list, double* gauss_coord_tria, double* gauss_coord){
-
-	/*
-	 * Compute Lprime  matrix. Lprime=[Lp1 Lp2 Lp3] where Lpi is square and of size numdof. 
-	 * For grid i, Lpi can be expressed in the actual coordinate system
-	 * by: 
-	 *       Lpi=[ h    0    0   0]
-	 *		 [ 0    h    0   0]
-	 *		 [ h    0    0   0]
-	 *		 [ 0    h    0   0]
-	 *		 [ 0    0    h   0]
-	 *		 [ 0    0    h   0]
-	 *		 [ 0    0  dh/dz 0]
-	 *		 [ 0    0  dh/dz 0]
-	 *		 [ 0    0  dh/dz 0]
-	 *		 [dh/dz 0  dh/dx 0]
-	 *		 [ 0 dh/dz dh/dy 0]
-	 * 		 [ 0    0    0   h]
-	 * 		 [ 0    0    0   h]
-	 * 		 [ 0    0    0   h]
-	 * where h is the interpolation function for grid i.
-	 */
-
-	int i;
-	const int numgrids2d=3;
-	int num_dof=4;
-
-	double l1l2l3[numgrids2d];
-	double dh1dh6[3][6];
-
-
-	/*Get l1l2l3 in actual coordinate system: */
-	l1l2l3[0]=gauss_coord_tria[0];
-	l1l2l3[1]=gauss_coord_tria[1];
-	l1l2l3[2]=gauss_coord_tria[2];
-
-	GetNodalFunctionsDerivatives(&dh1dh6[0][0],xyz_list,gauss_coord);
-
-	/*Build LprimeStokes: */
-	for (i=0;i<3;i++){
-		*(LprimeStokes+num_dof*numgrids2d*0+num_dof*i)=l1l2l3[i]; //LprimeStokes[0][NDOF2*i]=dh1dh3[0][i];
-		*(LprimeStokes+num_dof*numgrids2d*0+num_dof*i+1)=0;
-		*(LprimeStokes+num_dof*numgrids2d*0+num_dof*i+2)=0;
-		*(LprimeStokes+num_dof*numgrids2d*0+num_dof*i+3)=0;
-		*(LprimeStokes+num_dof*numgrids2d*1+num_dof*i)=0;
-		*(LprimeStokes+num_dof*numgrids2d*1+num_dof*i+1)=l1l2l3[i];
-		*(LprimeStokes+num_dof*numgrids2d*1+num_dof*i+2)=0;
-		*(LprimeStokes+num_dof*numgrids2d*1+num_dof*i+3)=0;
-		*(LprimeStokes+num_dof*numgrids2d*2+num_dof*i)=l1l2l3[i];
-		*(LprimeStokes+num_dof*numgrids2d*2+num_dof*i+1)=0;
-		*(LprimeStokes+num_dof*numgrids2d*2+num_dof*i+2)=0;
-		*(LprimeStokes+num_dof*numgrids2d*2+num_dof*i+3)=0;
-		*(LprimeStokes+num_dof*numgrids2d*3+num_dof*i)=0;
-		*(LprimeStokes+num_dof*numgrids2d*3+num_dof*i+1)=l1l2l3[i];
-		*(LprimeStokes+num_dof*numgrids2d*3+num_dof*i+2)=0;
-		*(LprimeStokes+num_dof*numgrids2d*3+num_dof*i+3)=0;
-		*(LprimeStokes+num_dof*numgrids2d*4+num_dof*i)=0;
-		*(LprimeStokes+num_dof*numgrids2d*4+num_dof*i+1)=0;
-		*(LprimeStokes+num_dof*numgrids2d*4+num_dof*i+2)=l1l2l3[i];
-		*(LprimeStokes+num_dof*numgrids2d*4+num_dof*i+3)=0;
-		*(LprimeStokes+num_dof*numgrids2d*5+num_dof*i)=0;
-		*(LprimeStokes+num_dof*numgrids2d*5+num_dof*i+1)=0;
-		*(LprimeStokes+num_dof*numgrids2d*5+num_dof*i+2)=l1l2l3[i];
-		*(LprimeStokes+num_dof*numgrids2d*5+num_dof*i+3)=0;
-		*(LprimeStokes+num_dof*numgrids2d*6+num_dof*i)=0;
-		*(LprimeStokes+num_dof*numgrids2d*6+num_dof*i+1)=0;
-		*(LprimeStokes+num_dof*numgrids2d*6+num_dof*i+2)=dh1dh6[2][i];
-		*(LprimeStokes+num_dof*numgrids2d*6+num_dof*i+3)=0;
-		*(LprimeStokes+num_dof*numgrids2d*7+num_dof*i)=0;
-		*(LprimeStokes+num_dof*numgrids2d*7+num_dof*i+1)=0;
-		*(LprimeStokes+num_dof*numgrids2d*7+num_dof*i+2)=dh1dh6[2][i];
-		*(LprimeStokes+num_dof*numgrids2d*7+num_dof*i+3)=0;
-		*(LprimeStokes+num_dof*numgrids2d*8+num_dof*i)=0;
-		*(LprimeStokes+num_dof*numgrids2d*8+num_dof*i+1)=0;
-		*(LprimeStokes+num_dof*numgrids2d*8+num_dof*i+2)=dh1dh6[2][i];
-		*(LprimeStokes+num_dof*numgrids2d*8+num_dof*i+3)=0;
-		*(LprimeStokes+num_dof*numgrids2d*9+num_dof*i)=dh1dh6[2][i];
-		*(LprimeStokes+num_dof*numgrids2d*9+num_dof*i+1)=0;
-		*(LprimeStokes+num_dof*numgrids2d*9+num_dof*i+2)=dh1dh6[0][i];
-		*(LprimeStokes+num_dof*numgrids2d*9+num_dof*i+3)=0;
-		*(LprimeStokes+num_dof*numgrids2d*10+num_dof*i)=0;
-		*(LprimeStokes+num_dof*numgrids2d*10+num_dof*i+1)=dh1dh6[2][i];
-		*(LprimeStokes+num_dof*numgrids2d*10+num_dof*i+2)=dh1dh6[1][i];
-		*(LprimeStokes+num_dof*numgrids2d*10+num_dof*i+3)=0;
-		*(LprimeStokes+num_dof*numgrids2d*11+num_dof*i)=0;
-		*(LprimeStokes+num_dof*numgrids2d*11+num_dof*i+1)=0;
-		*(LprimeStokes+num_dof*numgrids2d*11+num_dof*i+2)=0;
-		*(LprimeStokes+num_dof*numgrids2d*11+num_dof*i+3)=l1l2l3[i];
-		*(LprimeStokes+num_dof*numgrids2d*12+num_dof*i)=0;
-		*(LprimeStokes+num_dof*numgrids2d*12+num_dof*i+1)=0;
-		*(LprimeStokes+num_dof*numgrids2d*12+num_dof*i+2)=0;
-		*(LprimeStokes+num_dof*numgrids2d*12+num_dof*i+3)=l1l2l3[i];
-		*(LprimeStokes+num_dof*numgrids2d*13+num_dof*i)=0;
-		*(LprimeStokes+num_dof*numgrids2d*13+num_dof*i+1)=0;
-		*(LprimeStokes+num_dof*numgrids2d*13+num_dof*i+2)=0;
-		*(LprimeStokes+num_dof*numgrids2d*13+num_dof*i+3)=l1l2l3[i];
-
-	}
-}
-/*}}}*/
-/*FUNCTION GetMatPar {{{1*/
-void* Penta::GetMatPar(){
-
-	/*dynamic objects pointed to by hooks: */
-	Matpar* matpar=NULL;
-
-	/*recover objects from hooks: */
-	matpar=(Matpar*)hmatpar.delivers();
-
-	return matpar;
-}
-/*}}}*/
-/*FUNCTION GetMatrixInvert {{{1*/
-void Penta::GetMatrixInvert(double*  Ke_invert, double* Ke){
-	/*Inverse a 3 by 3 matrix only */
-
-	double a,b,c,d,e,f,g,h,i;
-	double det;
-	int calculationdof=3;
-
-	/*Take the matrix components: */
-	a=*(Ke+calculationdof*0+0);
-	b=*(Ke+calculationdof*0+1);
-	c=*(Ke+calculationdof*0+2);
-	d=*(Ke+calculationdof*1+0);
-	e=*(Ke+calculationdof*1+1);
-	f=*(Ke+calculationdof*1+2);
-	g=*(Ke+calculationdof*2+0);
-	h=*(Ke+calculationdof*2+1);
-	i=*(Ke+calculationdof*2+2);
-
-	det=a*(e*i-f*h)-b*(d*i-f*g)+c*(d*h-e*g);
-
-	*(Ke_invert+calculationdof*0+0)=(e*i-f*h)/det;
-	*(Ke_invert+calculationdof*0+1)=(c*h-b*i)/det;
-	*(Ke_invert+calculationdof*0+2)=(b*f-c*e)/det;
-	*(Ke_invert+calculationdof*1+0)=(f*g-d*i)/det;
-	*(Ke_invert+calculationdof*1+1)=(a*i-c*g)/det;
-	*(Ke_invert+calculationdof*1+2)=(c*d-a*f)/det;
-	*(Ke_invert+calculationdof*2+0)=(d*h-e*g)/det;
-	*(Ke_invert+calculationdof*2+1)=(b*g-a*h)/det;
-	*(Ke_invert+calculationdof*2+2)=(a*e-b*d)/det;
-
-}
-/*}}}*/
-/*FUNCTION GetNodalFunctions {{{1*/
-void Penta::GetNodalFunctions(double* l1l6, double* gauss_coord){
-
-	/*This routine returns the values of the nodal functions  at the gaussian point.*/
-
-	l1l6[0]=gauss_coord[0]*(1-gauss_coord[3])/2.0;
-
-	l1l6[1]=gauss_coord[1]*(1-gauss_coord[3])/2.0;
-
-	l1l6[2]=gauss_coord[2]*(1-gauss_coord[3])/2.0;
-
-	l1l6[3]=gauss_coord[0]*(1+gauss_coord[3])/2.0;
-
-	l1l6[4]=gauss_coord[1]*(1+gauss_coord[3])/2.0;
-
-	l1l6[5]=gauss_coord[2]*(1+gauss_coord[3])/2.0;
-
-}
-/*}}}*/
-/*FUNCTION GetNodalFunctionsDerivatives {{{1*/
-void Penta::GetNodalFunctionsDerivatives(double* dh1dh6,double* xyz_list, double* gauss_coord){
-
-	/*This routine returns the values of the nodal functions derivatives  (with respect to the actual coordinate system: */
-
-
-	int i;
-	const int NDOF3=3;
-	const int numgrids=6;
-
-	double dh1dh6_ref[NDOF3][numgrids];
-	double Jinv[NDOF3][NDOF3];
-
-	/*Get derivative values with respect to parametric coordinate system: */
-	GetNodalFunctionsDerivativesReference(&dh1dh6_ref[0][0], gauss_coord); 
-
-	/*Get Jacobian invert: */
-	GetJacobianInvert(&Jinv[0][0], xyz_list, gauss_coord);
-
-	/*Build dh1dh3: 
-	 *
-	 * [dhi/dx]= Jinv*[dhi/dr]
-	 * [dhi/dy]       [dhi/ds]
-	 * [dhi/dz]       [dhi/dn]
-	 */
-
-	for (i=0;i<numgrids;i++){
-		*(dh1dh6+numgrids*0+i)=Jinv[0][0]*dh1dh6_ref[0][i]+Jinv[0][1]*dh1dh6_ref[1][i]+Jinv[0][2]*dh1dh6_ref[2][i];
-		*(dh1dh6+numgrids*1+i)=Jinv[1][0]*dh1dh6_ref[0][i]+Jinv[1][1]*dh1dh6_ref[1][i]+Jinv[1][2]*dh1dh6_ref[2][i];
-		*(dh1dh6+numgrids*2+i)=Jinv[2][0]*dh1dh6_ref[0][i]+Jinv[2][1]*dh1dh6_ref[1][i]+Jinv[2][2]*dh1dh6_ref[2][i];
-	}
-
-}
-/*}}}*/
-/*FUNCTION GetNodalFunctionsDerivativesStokes {{{1*/
-void Penta::GetNodalFunctionsDerivativesStokes(double* dh1dh7,double* xyz_list, double* gauss_coord){
-
-	/*This routine returns the values of the nodal functions derivatives  (with respect to the 
-	 * actual coordinate system: */
-
-	int i;
-
-	const  int numgrids=7;
-	double dh1dh7_ref[3][numgrids];
-	double Jinv[3][3];
-
-
-	/*Get derivative values with respect to parametric coordinate system: */
-	GetNodalFunctionsDerivativesReferenceStokes(&dh1dh7_ref[0][0], gauss_coord); 
-
-	/*Get Jacobian invert: */
-	GetJacobianInvert(&Jinv[0][0], xyz_list, gauss_coord);
-
-	/*Build dh1dh6: 
-	 *
-	 * [dhi/dx]= Jinv'*[dhi/dr]
-	 * [dhi/dy]        [dhi/ds]
-	 * [dhi/dz]        [dhi/dzeta]
-	 */
-
-	for (i=0;i<numgrids;i++){
-		*(dh1dh7+numgrids*0+i)=Jinv[0][0]*dh1dh7_ref[0][i]+Jinv[0][1]*dh1dh7_ref[1][i]+Jinv[0][2]*dh1dh7_ref[2][i];
-		*(dh1dh7+numgrids*1+i)=Jinv[1][0]*dh1dh7_ref[0][i]+Jinv[1][1]*dh1dh7_ref[1][i]+Jinv[1][2]*dh1dh7_ref[2][i];
-		*(dh1dh7+numgrids*2+i)=Jinv[2][0]*dh1dh7_ref[0][i]+Jinv[2][1]*dh1dh7_ref[1][i]+Jinv[2][2]*dh1dh7_ref[2][i];
-	}
-
-}
-/*}}}*/
-/*FUNCTION GetNodalFunctionsDerivativesReference {{{1*/
-void Penta::GetNodalFunctionsDerivativesReference(double* dl1dl6,double* gauss_coord){
-
-	/*This routine returns the values of the nodal functions derivatives  (with respect to the 
-	 * natural coordinate system) at the gaussian point. Those values vary along xi,eta,z */
-
-	const int numgrids=6;
-	double A1,A2,A3,z;
-
-	A1=gauss_coord[0]; //first area coordinate value. In term of xi and eta: A1=(1-xi)/2-eta/(2*SQRT3);
-	A2=gauss_coord[1]; //second area coordinate value In term of xi and eta: A2=(1+xi)/2-eta/(2*SQRT3);
-	A3=gauss_coord[2]; //third area coordinate value  In term of xi and eta: A3=y/SQRT3;
-	z=gauss_coord[3]; //fourth vertical coordinate value. Corresponding nodal function: (1-z)/2 and (1+z)/2
-
-
-	/*First nodal function derivatives. The corresponding nodal function is N=A1*(1-z)/2. Its derivatives follow*/
-	*(dl1dl6+numgrids*0+0)=-0.5*(1.0-z)/2.0;
-	*(dl1dl6+numgrids*1+0)=-0.5/SQRT3*(1.0-z)/2.0;
-	*(dl1dl6+numgrids*2+0)=-0.5*A1;
-
-	/*Second nodal function: The corresponding nodal function is N=A2*(1-z)/2. Its derivatives follow*/
-	*(dl1dl6+numgrids*0+1)=0.5*(1.0-z)/2.0;
-	*(dl1dl6+numgrids*1+1)=-0.5/SQRT3*(1.0-z)/2.0;
-	*(dl1dl6+numgrids*2+1)=-0.5*A2;
-
-	/*Third nodal function: The corresponding nodal function is N=A3*(1-z)/2. Its derivatives follow*/
-	*(dl1dl6+numgrids*0+2)=0.0;
-	*(dl1dl6+numgrids*1+2)=1.0/SQRT3*(1.0-z)/2.0;
-	*(dl1dl6+numgrids*2+2)=-0.5*A3;
-
-	/*Fourth nodal function: The corresponding nodal function is N=A1*(1+z)/2. Its derivatives follow*/
-	*(dl1dl6+numgrids*0+3)=-0.5*(1.0+z)/2.0;
-	*(dl1dl6+numgrids*1+3)=-0.5/SQRT3*(1.0+z)/2.0;
-	*(dl1dl6+numgrids*2+3)=0.5*A1;
-
-	/*Fifth nodal function: The corresponding nodal function is N=A2*(1+z)/2. Its derivatives follow*/
-	*(dl1dl6+numgrids*0+4)=0.5*(1.0+z)/2.0;
-	*(dl1dl6+numgrids*1+4)=-0.5/SQRT3*(1.0+z)/2.0;
-	*(dl1dl6+numgrids*2+4)=0.5*A2;
-
-	/*Sixth nodal function: The corresponding nodal function is N=A3*(1+z)/2. Its derivatives follow*/
-	*(dl1dl6+numgrids*0+5)=0.0;
-	*(dl1dl6+numgrids*1+5)=1.0/SQRT3*(1.0+z)/2.0;
-	*(dl1dl6+numgrids*2+5)=0.5*A3;
-}
-/*}}}*/
-/*FUNCTION GetNodalFunctionsDerivativesReferenceStokes {{{1*/
-void Penta::GetNodalFunctionsDerivativesReferenceStokes(double* dl1dl7,double* gauss_coord){
-
-	/*This routine returns the values of the nodal functions derivatives  (with respect to the 
-	 * natural coordinate system) at the gaussian point. */
-
-	int    numgrids=7; //six plus bubble grids
-
-	double r=gauss_coord[1]-gauss_coord[0];
-	double s=-3.0/SQRT3*(gauss_coord[0]+gauss_coord[1]-2.0/3.0);
-	double zeta=gauss_coord[3];
-
-	/*First nodal function: */
-	*(dl1dl7+numgrids*0+0)=-0.5*(1.0-zeta)/2.0;
-	*(dl1dl7+numgrids*1+0)=-SQRT3/6.0*(1.0-zeta)/2.0;
-	*(dl1dl7+numgrids*2+0)=-0.5*(-0.5*r-SQRT3/6.0*s+ONETHIRD);
-
-	/*Second nodal function: */
-	*(dl1dl7+numgrids*0+1)=0.5*(1.0-zeta)/2.0;
-	*(dl1dl7+numgrids*1+1)=-SQRT3/6.0*(1.0-zeta)/2.0;
-	*(dl1dl7+numgrids*2+1)=-0.5*(0.5*r-SQRT3/6.0*s+ONETHIRD);
-
-	/*Third nodal function: */
-	*(dl1dl7+numgrids*0+2)=0;
-	*(dl1dl7+numgrids*1+2)=SQRT3/3.0*(1.0-zeta)/2.0;
-	*(dl1dl7+numgrids*2+2)=-0.5*(SQRT3/3.0*s+ONETHIRD);
-
-	/*Fourth nodal function: */
-	*(dl1dl7+numgrids*0+3)=-0.5*(1.0+zeta)/2.0;
-	*(dl1dl7+numgrids*1+3)=-SQRT3/6.0*(1.0+zeta)/2.0;
-	*(dl1dl7+numgrids*2+3)=0.5*(-0.5*r-SQRT3/6.0*s+ONETHIRD);
-
-	/*Fith nodal function: */
-	*(dl1dl7+numgrids*0+4)=0.5*(1.0+zeta)/2.0;
-	*(dl1dl7+numgrids*1+4)=-SQRT3/6.0*(1.0+zeta)/2.0;
-	*(dl1dl7+numgrids*2+4)=0.5*(0.5*r-SQRT3/6.0*s+ONETHIRD);
-
-	/*Sixth nodal function: */
-	*(dl1dl7+numgrids*0+5)=0;
-	*(dl1dl7+numgrids*1+5)=SQRT3/3.0*(1.0+zeta)/2.0;
-	*(dl1dl7+numgrids*2+5)=0.5*(SQRT3/3.0*s+ONETHIRD);
-
-	/*Seventh nodal function: */
-	*(dl1dl7+numgrids*0+6)=9.0/2.0*r*(1.0+zeta)*(zeta-1.0)*(SQRT3*s+1.0);
-	*(dl1dl7+numgrids*1+6)=9.0/4.0*(1+zeta)*(1-zeta)*(SQRT3*pow(s,2.0)-2.0*s-SQRT3*pow(r,2.0));
-	*(dl1dl7+numgrids*2+6)=27*gauss_coord[0]*gauss_coord[1]*gauss_coord[2]*(-2.0*zeta);
-
-}
-/*}}}*/
-/*FUNCTION GetNodalFunctionsStokes {{{1*/
-void Penta::GetNodalFunctionsStokes(double* l1l7, double* gauss_coord){
-
-	/*This routine returns the values of the nodal functions  at the gaussian point.*/
-
-	/*First nodal function: */
-	l1l7[0]=gauss_coord[0]*(1.0-gauss_coord[3])/2.0;
-
-	/*Second nodal function: */
-	l1l7[1]=gauss_coord[1]*(1.0-gauss_coord[3])/2.0;
-
-	/*Third nodal function: */
-	l1l7[2]=gauss_coord[2]*(1.0-gauss_coord[3])/2.0;
-
-	/*Fourth nodal function: */
-	l1l7[3]=gauss_coord[0]*(1.0+gauss_coord[3])/2.0;
-
-	/*Fifth nodal function: */
-	l1l7[4]=gauss_coord[1]*(1.0+gauss_coord[3])/2.0;
-
-	/*Sixth nodal function: */
-	l1l7[5]=gauss_coord[2]*(1.0+gauss_coord[3])/2.0;
-
-	/*Seventh nodal function: */
-	l1l7[6]=27*gauss_coord[0]*gauss_coord[1]*gauss_coord[2]*(1.0+gauss_coord[3])*(1.0-gauss_coord[3]);
-
-}
-/*}}}*/
-/*FUNCTION GetNodes {{{1*/
-void  Penta::GetNodes(void** vpnodes){
-
-	int i;
-	Node** pnodes=NULL;
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-	
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	
-	/*virtual object: */
-	pnodes=(Node**)vpnodes;
-
-	for(i=0;i<6;i++){
-		pnodes[i]=nodes[i];
-	}
-}
-/*}}}*/
-/*FUNCTION GetOnBed {{{1*/
-bool Penta::GetOnBed(){
-	
-	bool onbed;
-
-	inputs->GetParameterValue(&onbed,ElementOnBedEnum);
-
-	return onbed;
-}
-/*}}}*/
-/*FUNCTION GetParameterDerivativeValue {{{1*/
-void Penta::GetParameterDerivativeValue(double* p, double* p_list,double* xyz_list, double* gauss_coord){
-
-	/*From grid values of parameter p (p_list[0], p_list[1], p_list[2], p_list[3], p_list[4] and p_list[4]), return parameter derivative value at gaussian point specified by gauss_coord:
-	 *   dp/dx=p_list[0]*dh1/dx+p_list[1]*dh2/dx+p_list[2]*dh3/dx+p_list[3]*dh4/dx+p_list[4]*dh5/dx+p_list[5]*dh6/dx;
-	 *   dp/dy=p_list[0]*dh1/dy+p_list[1]*dh2/dy+p_list[2]*dh3/dy+p_list[3]*dh4/dy+p_list[4]*dh5/dy+p_list[5]*dh6/dy;
-	 *   dp/dz=p_list[0]*dh1/dz+p_list[1]*dh2/dz+p_list[2]*dh3/dz+p_list[3]*dh4/dz+p_list[4]*dh5/dz+p_list[5]*dh6/dz;
-	 *
-	 *   p is a vector of size 3x1 already allocated.
-	 */
-
-	const int NDOF3=3;
-	const int numgrids=6;
-	double dh1dh6[NDOF3][numgrids];
-
-	/*Get dh1dh6 in actual coordinate system: */
-	GetNodalFunctionsDerivatives(&dh1dh6[0][0],xyz_list, gauss_coord);
-
-	*(p+0)=p_list[0]*dh1dh6[0][0]+p_list[1]*dh1dh6[0][1]+p_list[2]*dh1dh6[0][2]+p_list[3]*dh1dh6[0][3]+p_list[4]*dh1dh6[0][4]+p_list[5]*dh1dh6[0][5];
-	;
-	*(p+1)=p_list[0]*dh1dh6[1][0]+p_list[1]*dh1dh6[1][1]+p_list[2]*dh1dh6[1][2]+p_list[3]*dh1dh6[1][3]+p_list[4]*dh1dh6[1][4]+p_list[5]*dh1dh6[1][5];
-
-	*(p+2)=p_list[0]*dh1dh6[2][0]+p_list[1]*dh1dh6[2][1]+p_list[2]*dh1dh6[2][2]+p_list[3]*dh1dh6[2][3]+p_list[4]*dh1dh6[2][4]+p_list[5]*dh1dh6[2][5];
-
-}
-/*}}}*/
-/*FUNCTION GetParameterValue {{{1*/
-void Penta::GetParameterValue(double* pvalue, double* v_list,double* gauss_coord){
-
-	const int numgrids=6;
-	double l1l6[numgrids];
-
-	GetNodalFunctions(&l1l6[0], gauss_coord);
-
-	*pvalue=l1l6[0]*v_list[0]+l1l6[1]*v_list[1]+l1l6[2]*v_list[2]+l1l6[3]*v_list[3]+l1l6[4]*v_list[4]+l1l6[5]*v_list[5];
-}
-/*}}}*/
-/*FUNCTION GetPhi {{{1*/
-void Penta::GetPhi(double* phi, double*  epsilon, double viscosity){
-	/*Compute deformational heating from epsilon and viscosity */
-
-	double epsilon_matrix[3][3];
-	double epsilon_eff;
-	double epsilon_sqr[3][3];
-
-	/* Build epsilon matrix */
-	epsilon_matrix[0][0]=*(epsilon+0);
-	epsilon_matrix[1][0]=*(epsilon+3);
-	epsilon_matrix[2][0]=*(epsilon+4);
-	epsilon_matrix[0][1]=*(epsilon+3);
-	epsilon_matrix[1][1]=*(epsilon+1);
-	epsilon_matrix[2][1]=*(epsilon+5);
-	epsilon_matrix[0][2]=*(epsilon+4);
-	epsilon_matrix[1][2]=*(epsilon+5);
-	epsilon_matrix[2][2]=*(epsilon+2);
-
-	/* Effective value of epsilon_matrix */
-	epsilon_sqr[0][0]=pow(epsilon_matrix[0][0],2);
-	epsilon_sqr[1][0]=pow(epsilon_matrix[1][0],2);
-	epsilon_sqr[2][0]=pow(epsilon_matrix[2][0],2);
-	epsilon_sqr[0][1]=pow(epsilon_matrix[0][1],2);
-	epsilon_sqr[1][1]=pow(epsilon_matrix[1][1],2);
-	epsilon_sqr[2][1]=pow(epsilon_matrix[2][1],2);
-	epsilon_sqr[0][2]=pow(epsilon_matrix[0][2],2);
-	epsilon_sqr[1][2]=pow(epsilon_matrix[1][2],2);
-	epsilon_sqr[2][2]=pow(epsilon_matrix[2][2],2);
-
-	epsilon_eff=1/pow(2,0.5)*pow((epsilon_sqr[0][0]+epsilon_sqr[0][1]+ epsilon_sqr[0][2]+ epsilon_sqr[1][0]+ epsilon_sqr[1][1]+ epsilon_sqr[1][2]+ epsilon_sqr[2][0]+ epsilon_sqr[2][1]+ epsilon_sqr[2][2]),0.5);
-	*phi=2*pow(epsilon_eff,2.0)*viscosity;
-}
-/*}}}*/
-/*FUNCTION GetShelf {{{1*/
-bool   Penta::GetShelf(){
-	bool onshelf;
-
-	/*retrieve inputs :*/
-	inputs->GetParameterValue(&onshelf,ElementOnIceShelfEnum);
-
-	return onshelf;
-}
-/*}}}*/
-/*FUNCTION GetStrainRate {{{1*/
-void Penta::GetStrainRate(double* epsilon, double* velocity, double* xyz_list, double* gauss_coord){
-
-	int i;
-	const int numgrids=6;
-	const int NDOF2=2;
-
-	double B[5][NDOF2*numgrids];
-
-	/*Get B matrix: */
-	GetB(&B[0][0], xyz_list, gauss_coord);
-
-	/*Multiply B by velocity, to get strain rate: */
-	MatrixMultiply( &B[0][0],5,NDOF2*numgrids,0,
-				velocity,NDOF2*numgrids,1,0,
-				epsilon,0);
-
-}
-/*}}}*/
-/*FUNCTION GetStrainRateStokes {{{1*/
-void Penta::GetStrainRateStokes(double* epsilon, double* velocity, double* xyz_list, double* gauss_coord){
-
-	int i,j;
-
-	const int numgrids=6;
-	const int DOFVELOCITY=3;
-	double B[8][27];
-	double B_reduced[numgrids][DOFVELOCITY*numgrids];
-
-	/*Get B matrix: */
-	GetBStokes(&B[0][0], xyz_list, gauss_coord);
-
-	/*Create a reduced matrix of B to get rid of pressure */
-	for (i=0;i<6;i++){
-		for (j=0;j<3;j++){
-			B_reduced[i][j]=B[i][j];
-		}
-		for (j=4;j<7;j++){
-			B_reduced[i][j-1]=B[i][j];
-		}
-		for (j=8;j<11;j++){
-			B_reduced[i][j-2]=B[i][j];
-		}
-		for (j=12;j<15;j++){
-			B_reduced[i][j-3]=B[i][j];
-		}
-		for (j=16;j<19;j++){
-			B_reduced[i][j-4]=B[i][j];
-		}
-		for (j=20;j<23;j++){
-			B_reduced[i][j-5]=B[i][j];
-		}
-	}
-	/*Multiply B by velocity, to get strain rate: */
-	MatrixMultiply( &B_reduced[0][0],6,DOFVELOCITY*numgrids, 0, velocity,DOFVELOCITY*numgrids,1,0,epsilon, 0);
-}
-/*}}}*/
-/*FUNCTION GetThicknessList {{{1*/
-void Penta::GetThicknessList(double* thickness_list){
-
-	const int numgrids=6;
-	double  gaussgrids[numgrids][numgrids]={{1,0,0,0},{0,1,0,0},{0,0,1,0},{1,0,0,1},{0,1,0,1},{0,0,1,1}};
-	inputs->GetParameterValues(thickness_list,&gaussgrids[0][0],6,ThicknessEnum);
-
-}
-/*}}}*/
-/*FUNCTION Gradj {{{1*/
-void  Penta::Gradj(Vec grad_g,int analysis_type,int sub_analysis_type,char* control_type){
-
-	/*inputs: */
-	bool onwater;
-
-	/*retrieve inputs :*/
-	inputs->GetParameterValue(&onwater,ElementOnWaterEnum);
-
-	/*If on water, skip grad (=0): */
-	if(onwater)return;
-
-	if (strcmp(control_type,"drag")==0){
-		GradjDrag( grad_g,analysis_type,sub_analysis_type);
-	}
-	else if (strcmp(control_type,"B")==0){
-		GradjB( grad_g, analysis_type,sub_analysis_type);
-	}
-	else ISSMERROR("%s%s","control type not supported yet: ",control_type);
-}
-/*}}}*/
-/*FUNCTION GradjDrag {{{1*/
-void  Penta::GradjDrag(Vec grad_g,int analysis_type,int sub_analysis_type){
-
-	Tria* tria=NULL;
-
-	/*inputs: */
-	bool onwater;
-	bool onbed;
-	bool shelf;
-
-	/*retrieve inputs :*/
-	inputs->GetParameterValue(&onwater,ElementOnWaterEnum);
-	inputs->GetParameterValue(&onbed,ElementOnBedEnum);
-	inputs->GetParameterValue(&shelf,ElementOnIceShelfEnum);
-
-	/*If on water, skip: */
-	if(onwater)return;
-
-	/*If on shelf, skip: */
-	if(shelf)return;
-
-	/*Bail out if this element does not touch the bedrock: */
-	if (!onbed) return;
-
-	if (sub_analysis_type==HorizAnalysisEnum){
-
-		/*MacAyeal or Pattyn*/
-		tria=(Tria*)SpawnTria(0,1,2); //grids 0, 1 and 2 make the new tria.
-		tria->GradjDrag( grad_g,analysis_type,sub_analysis_type);
-		delete tria;
-		return;
-	}
-	else if (sub_analysis_type==StokesAnalysisEnum){
-
-		/*Stokes*/
-		tria=(Tria*)SpawnTria(0,1,2); //grids 0, 1 and 2 make the new tria.
-		tria->GradjDragStokes( grad_g,analysis_type,sub_analysis_type);
-		delete tria;
-		return;
-	}
-	else ISSMERROR("%s%i%s\n","sub_analysis: ",sub_analysis_type," not supported yet");
-}
-/*}}}*/
-/*FUNCTION GradjB {{{1*/
-void  Penta::GradjB(Vec grad_g,int analysis_type,int sub_analysis_type){
-
-	Tria* tria=NULL;
-
-	/*inputs: */
-	bool onwater;
-	bool collapse;
-	bool onbed;
-
-	/*retrieve inputs :*/
-	inputs->GetParameterValue(&onwater,ElementOnWaterEnum);
-	inputs->GetParameterValue(&collapse,CollapseEnum);
-	inputs->GetParameterValue(&onbed,ElementOnBedEnum);
-
-	/*If on water, skip: */
-	if(onwater)return;
-
-	if (collapse){
-		/*Bail out element if collapsed (2d) and not on bed*/
-		if (!onbed) return;
-
-		/*This element should be collapsed into a tria element at its base. Create this tria element, 
-		 * and compute gardj*/
-		tria=(Tria*)SpawnTria(0,1,2); //grids 0, 1 and 2 make the new tria (lower face).
-		tria->GradjB(grad_g,analysis_type,sub_analysis_type);
-		delete tria;
-		return;
-	}
-	else{
-		/*B is a 2d field, use MacAyeal(2d) gradient even if it is Stokes or Pattyn*/
-		tria=(Tria*)SpawnTria(0,1,2); //grids 0, 1 and 2 make the new tria (lower face).
-		tria->GradjB(grad_g,analysis_type,sub_analysis_type);
-		delete tria;
-		return;
-	}
-}
-/*}}}*/
-/*FUNCTION MassFlux {{{1*/
-double Penta::MassFlux( double* segment,double* ug){
-	ISSMERROR(" not supported yet!");
-}
-/*}}}*/
-/*FUNCTION Misfit {{{1*/
-double Penta::Misfit(int analysis_type,int sub_analysis_type){
-
-	double J;
-	Tria* tria=NULL;
-
-	/*inputs: */
-	bool onwater;
-	bool collapse;
-	bool onsurface;
-	bool onbed;
-
-	/*retrieve inputs :*/
-	inputs->GetParameterValue(&onwater,ElementOnWaterEnum);
-	inputs->GetParameterValue(&collapse,CollapseEnum);
-	inputs->GetParameterValue(&onbed,ElementOnBedEnum);
-	inputs->GetParameterValue(&onsurface,ElementOnSurfaceEnum);
-
-	/*If on water, return 0: */
-	if(onwater)return 0;
-
-	/*Bail out if this element if:
-	 * -> Non collapsed and not on the surface
-	 * -> collapsed (2d model) and not on bed) */
-	if ((!collapse && !onsurface) || (collapse && !onbed)){
-		return 0;
-	}
-	else if (collapse){
-
-		/*This element should be collapsed into a tria element at its base. Create this tria element, 
-		 * and compute Misfit*/
-		tria=(Tria*)SpawnTria(0,1,2); //grids 0, 1 and 2 make the new tria (lower face).
-		J=tria->Misfit(analysis_type,sub_analysis_type);
-		delete tria;
-		return J;
-	}
-	else{
-
-		tria=(Tria*)SpawnTria(3,4,5); //grids 3, 4 and 5 make the new tria (upper face).
-		J=tria->Misfit(analysis_type,sub_analysis_type);
-		delete tria;
-		return J;
-	}
-}
-/*}}}*/
-/*FUNCTION MyRank {{{1*/
-int    Penta::MyRank(void){ 
-	extern int my_rank;
-	return my_rank; 
-}
-/*}}}*/
-/*FUNCTION ReduceMatrixStokes {{{1*/
-void Penta::ReduceMatrixStokes(double* Ke_reduced, double* Ke_temp){
-
-	int i,j;
-
-	double Kii[24][24];
-	double Kib[24][3];
-	double Kbb[3][3];
-	double Kbi[3][24];
-	double Kbbinv[3][3];
-	double KibKbbinv[24][3];
-	double Kright[24][24];
-
-	/*Create the four matrices used for reduction */
-	for(i=0;i<24;i++){
-		for(j=0;j<24;j++){
-			Kii[i][j]=*(Ke_temp+27*i+j);
-		}
-		for(j=0;j<3;j++){
-			Kib[i][j]=*(Ke_temp+27*i+j+24);
-		}
-	}
-	for(i=0;i<3;i++){
-		for(j=0;j<24;j++){
-			Kbi[i][j]=*(Ke_temp+27*(i+24)+j);
-		}
-		for(j=0;j<3;j++){
-			Kbb[i][j]=*(Ke_temp+27*(i+24)+j+24);
-		}
-	}
-
-	/*Inverse the matrix corresponding to bubble part Kbb */
-	GetMatrixInvert(&Kbbinv[0][0], &Kbb[0][0]);
-
-	/*Multiply matrices to create the reduce matrix Ke_reduced */
-	MatrixMultiply(&Kib[0][0],24,3,0,&Kbbinv[0][0],3,3,0,&KibKbbinv[0][0],0);
-	MatrixMultiply(&KibKbbinv[0][0],24,3,0,&Kbi[0][0],3,24,0,&Kright[0][0],0);
-
-	/*Affect value to the reduced matrix */
-	for(i=0;i<24;i++){
-		for(j=0;j<24;j++){
-			*(Ke_reduced+24*i+j)=Kii[i][j]-Kright[i][j];
-		}
-	}
-}
-/*}}}*/
-/*FUNCTION ReduceVectorStokes {{{1*/
-void Penta::ReduceVectorStokes(double* Pe_reduced, double* Ke_temp, double* Pe_temp){
-
-	int i,j;
-
-	double Pi[24];
-	double Pb[3];
-	double Kbb[3][3];
-	double Kib[24][3];
-	double Kbbinv[3][3];
-	double KibKbbinv[24][3];
-	double Pright[24];
-
-	/*Create the four matrices used for reduction */
-	for(i=0;i<24;i++){
-		Pi[i]=*(Pe_temp+i);
-	}
-	for(i=0;i<3;i++){
-		Pb[i]=*(Pe_temp+i+24);
-	}
-	for(j=0;j<3;j++){
-		for(i=0;i<24;i++){
-			Kib[i][j]=*(Ke_temp+3*i+j);
-		}
-		for(i=0;i<3;i++){
-			Kbb[i][j]=*(Ke_temp+3*(i+24)+j);
-		}
-	}
-
-	/*Inverse the matrix corresponding to bubble part Kbb */
-	GetMatrixInvert(&Kbbinv[0][0], &Kbb[0][0]);
-
-	/*Multiply matrices to create the reduce matrix Ke_reduced */
-	MatrixMultiply(&Kib[0][0],24,3,0,&Kbbinv[0][0],3,3,0,&KibKbbinv[0][0],0);
-	MatrixMultiply(&KibKbbinv[0][0],24,3,0,&Pb[0],3,1,0,&Pright[0],0);
-
-	/*Affect value to the reduced matrix */
-	for(i=0;i<24;i++){
-		*(Pe_reduced+i)=Pi[i]-Pright[i];
-	}
-}
-/*}}}*/
-/*FUNCTION SetClone {{{1*/
-void  Penta::SetClone(int* minranks){
-
-	ISSMERROR("not implemented yet");
-}
-/*}}}1*/
-/*FUNCTION SurfaceArea {{{1*/
-double Penta::SurfaceArea(int analysis_type,int sub_analysis_type){
-
-	double S;
-	Tria* tria=NULL;
-
-	/*inputs: */
-	bool onwater;
-	bool collapse;
-	bool onsurface;
-	bool onbed;
-
-	/*retrieve inputs :*/
-	inputs->GetParameterValue(&onwater,ElementOnWaterEnum);
-	inputs->GetParameterValue(&collapse,CollapseEnum);
-	inputs->GetParameterValue(&onbed,ElementOnBedEnum);
-	inputs->GetParameterValue(&onsurface,ElementOnSurfaceEnum);
-
-	/*If on water, return 0: */
-	if(onwater)return 0;
-
-	/*Bail out if this element if:
-	 * -> Non collapsed and not on the surface
-	 * -> collapsed (2d model) and not on bed) */
-	if ((!collapse && !onsurface) || (collapse && !onbed)){
-		return 0;
-	}
-	else if (collapse){
-
-		/*This element should be collapsed into a tria element at its base. Create this tria element, 
-		 * and compute SurfaceArea*/
-		tria=(Tria*)SpawnTria(0,1,2); //grids 0, 1 and 2 make the new tria (lower face).
-		S=tria->SurfaceArea(analysis_type,sub_analysis_type);
-		delete tria;
-		return S;
-	}
-	else{
-
-		tria=(Tria*)SpawnTria(3,4,5); //grids 3, 4 and 5 make the new tria (upper face).
-		S=tria->SurfaceArea(analysis_type,sub_analysis_type);
-		delete tria;
-		return S;
-	}
-}
-/*}}}*/
-/*FUNCTION SurfaceNormal {{{1*/
-void Penta::SurfaceNormal(double* surface_normal, double xyz_list[3][3]){
-
-	int i;
-	double v13[3];
-	double v23[3];
-	double normal[3];
-	double normal_norm;
-
-	for (i=0;i<3;i++){
-		v13[i]=xyz_list[0][i]-xyz_list[2][i];
-		v23[i]=xyz_list[1][i]-xyz_list[2][i];
-	}
-
-	normal[0]=v13[1]*v23[2]-v13[2]*v23[1];
-	normal[1]=v13[2]*v23[0]-v13[0]*v23[2];
-	normal[2]=v13[0]*v23[1]-v13[1]*v23[0];
-
-	normal_norm=sqrt( pow(normal[0],2)+pow(normal[1],2)+pow(normal[2],2) );
-
-	*(surface_normal)=normal[0]/normal_norm;
-	*(surface_normal+1)=normal[1]/normal_norm;
-	*(surface_normal+2)=normal[2]/normal_norm;
-
-}
-/*}}}*/
Index: sm/trunk/src/c/objects/Penta.h
===================================================================
--- /issm/trunk/src/c/objects/Penta.h	(revision 3680)
+++ 	(revision )
@@ -1,156 +1,0 @@
-/*! \file Penta.h 
- *  \brief: header file for penta object
- */
-
-#ifndef _PENTA_H
-#define _PENTA_H
-
-/*Headers:*/
-/*{{{1*/
-class Object;
-class Node;
-class Hook;
-class DataSet;
-struct IoModel;
-
-
-#include "./Object.h"
-#include "./Element.h"
-#include "./Matpar.h"
-#include "./Matice.h"
-#include "./Tria.h"
-#include "../shared/Exceptions/exceptions.h"
-#include "../include/macros.h"
-#include "./Hook.h"
-#include "../ModelProcessorx/IoModel.h"
-#include "./Node.h"
-#include "../DataSet/DataSet.h"
-#include "../DataSet/Parameters.h"
-#include "../DataSet/Inputs.h"
-/*}}}*/
-
-class Penta: public Element{
-
-	public:
-
-		int id;
-		Hook hnodes;  //hook to 6 nodes
-		Hook hmatice; //hook to 1 matice
-		Hook hmatpar; //hook to 1 matpar
-
-		Parameters* parameters; //pointer to solution parameters
-		Inputs* inputs;
-
-		/*FUNCTION constructors, destructors {{{1*/
-		Penta();
-		Penta(int penta_id,int* penta_node_ids, int penta_matice_id, int penta_matpar_id);
-		Penta(int penta_id,Hook* penta_hnodes, Hook* penta_hmatice, Hook* penta_hmatpar, Parameters* penta_parameters, Inputs* inputs);
-		Penta(int penta_id,int i, IoModel* iomodel);
-		~Penta();
-		/*}}}*/
-		/*FUNCTION object management {{{1*/
-		void  Configure(DataSet* loads,DataSet* nodes,DataSet* materials,Parameters* parameters);
-		Object* copy();
-		void  DeepEcho();
-		void  Demarshall(char** pmarshalled_dataset);
-		void  Echo();
-		int   Enum();
-		int   Id(); 
-		void  Marshall(char** pmarshalled_dataset);
-		int   MarshallSize();
-		int   MyRank();
-		void*  SpawnTria(int g0, int g1, int g2);
-		void  SetClone(int* minranks);
-
-		/*}}}*/
-		/*FUNCTION element numerical routines {{{1*/
-		void  CreateKMatrix(Mat Kgg,int analysis_type,int sub_analysis_type);
-		void  CreateKMatrixDiagnosticHoriz( Mat Kgg,  int analysis_type,int sub_analysis_type);
-		void  CreateKMatrixDiagnosticVert( Mat Kgg,  int analysis_type,int sub_analysis_type);
-		void  CreatePVector(Vec pg,  int analysis_type,int sub_analysis_type);
-		void  GetDofList(int* doflist,int* pnumberofdofs);
-		void  GetDofList1(int* doflist);
-		void* GetMatPar();
-		bool   GetShelf();
-		void  GetNodes(void** nodes);
-		bool   GetOnBed();
-		void  Du(Vec du_g,int analysis_type,int sub_analysis_type);
-		void  Gradj(Vec grad_g,int analysis_type,int sub_analysis_type,char* control_type);
-		void  GradjDrag(Vec grad_g,int analysis_type,int sub_analysis_type);
-		void  GradjB(Vec grad_g,int analysis_type,int sub_analysis_type);
-		double Misfit(int analysis_type,int sub_analysis_type);
-		double SurfaceArea(int analysis_type,int sub_analysis_type);
-		double CostFunction(int analysis_type,int sub_analysis_type);
-		
-		void          GetThicknessList(double* thickness_list);
-		void          GetBedList(double* bed_list);
-
-		void  GetStrainRate(double* epsilon, double* velocity, double* xyz_list, double* gauss_coord);
-		void  GetB(double* pB, double* xyz_list, double* gauss_coord);
-		void  GetBPrime(double* B, double* xyz_list, double* gauss_coord);
-		void  GetB_vert(double* B, double* xyz_list, double* gauss_coord);
-		void  GetBPrime_vert(double* B, double* xyz_list, double* gauss_coord);
-		void  GetJacobianDeterminant(double*  Jdet, double* xyz_list,double* gauss_coord);
-		void  GetNodalFunctionsDerivatives(double* dh1dh6,double* xyz_list, double* gauss_coord);
-		void  GetJacobian(double* J, double* xyz_list,double* gauss_coord);
-		void  GetNodalFunctionsDerivativesReference(double* dl1dl6,double* gauss_coord);
-		void  GetJacobianInvert(double*  Jinv, double* xyz_list,double* gauss_coord);
-		void  CreatePVectorDiagnosticHoriz( Vec pg, int analysis_type,int sub_analysis_type);
-		void  CreatePVectorDiagnosticVert( Vec pg, int analysis_type,int sub_analysis_type);
-		void  GetParameterValue(double* pvalue, double* v_list,double* gauss_coord);
-		void  GetParameterDerivativeValue(double* p, double* p_list,double* xyz_list, double* gauss_coord);
-		void  GetNodalFunctions(double* l1l6, double* gauss_coord);
-		void  FieldExtrude(Vec field,double* field_serial,char* field_name, int iscollapsed);
-		void  ComputeBasalStress(Vec sigma_b,int analysis_type,int sub_analysis_type);
-		void  ComputePressure(Vec p_g,int analysis_type,int sub_analysis_type);
-		void  ComputeStrainRate(Vec eps,int analysis_type,int sub_analysis_type);
-		void  CreateKMatrixSlopeCompute(Mat Kgg,int analysis_type,int sub_analysis_type);
-		void  CreatePVectorSlopeCompute( Vec pg,  int analysis_type,int sub_analysis_type);
-		void  CreateKMatrixPrognostic(Mat Kgg,int analysis_type,int sub_analysis_type);
-		void  CreatePVectorPrognostic( Vec pg,  int analysis_type,int sub_analysis_type);
-		void  CreateKMatrixBalancedthickness(Mat Kgg,int analysis_type,int sub_analysis_type);
-		void  CreateKMatrixBalancedvelocities(Mat Kgg,int analysis_type,int sub_analysis_type);
-		void  CreateKMatrixDiagnosticStokes( Mat Kgg,  int analysis_type,int sub_analysis_type);
-		void  CreatePVectorBalancedthickness( Vec pg, int analysis_type,int sub_analysis_type);
-		void  CreatePVectorBalancedvelocities( Vec pg, int analysis_type,int sub_analysis_type);
-		void  CreatePVectorDiagnosticStokes( Vec pg, int analysis_type,int sub_analysis_type);
-		void  ReduceMatrixStokes(double* Ke_reduced, double* Ke_temp);
-		void  GetMatrixInvert(double*  Ke_invert, double* Ke);
-		void  SurfaceNormal(double* surface_normal, double xyz_list[3][3]);
-		void  GetStrainRateStokes(double* epsilon, double* velocity, double* xyz_list, double* gauss_coord);
-		void  GetBStokes(double* B, double* xyz_list, double* gauss_coord);
-		void  GetBprimeStokes(double* B_prime, double* xyz_list, double* gauss_coord);
-		void  GetLStokes(double* LStokes, double* gauss_coord_tria);
-		void  GetLprimeStokes(double* LprimeStokes, double* xyz_list, double* gauss_coord_tria, double* gauss_coord);
-		void  GetNodalFunctionsDerivativesStokes(double* dh1dh7,double* xyz_list, double* gauss_coord);
-		void  GetNodalFunctionsDerivativesReferenceStokes(double* dl1dl7,double* gauss_coord);
-		void  ReduceVectorStokes(double* Pe_reduced, double* Ke_temp, double* Pe_temp);
-		void  GetNodalFunctionsStokes(double* l1l7, double* gauss_coord);
-		void  CreateKMatrixThermal(Mat Kgg,int analysis_type,int sub_analysis_type);
-		void  GetB_conduct(double* B_conduct, double* xyz_list, double* gauss_coord);
-		void  GetB_advec(double* B_advec, double* xyz_list, double* gauss_coord);
-		void  GetBprime_advec(double* Bprime_advec, double* xyz_list, double* gauss_coord);
-		void  GetB_artdiff(double* B_artdiff, double* xyz_list, double* gauss_coord);
-		void  CreateKMatrixMelting(Mat Kgg,int analysis_type,int sub_analysis_type);
-		void  CreatePVectorThermal( Vec pg, int analysis_type,int sub_analysis_type);
-		void  CreatePVectorMelting( Vec pg, int analysis_type,int sub_analysis_type);
-		void  GetPhi(double* phi, double*  epsilon, double viscosity);
-		double MassFlux(double* segment,double* ug);
-
-		/*updates: */
-		void  UpdateFromDakota(void* inputs);
-		void  UpdateInputs(double* solution, int analysis_type, int sub_analysis_type);
-		void  UpdateInputsDiagnosticHoriz( double* solution,int analysis_type,int sub_analysis_type);
-		void  UpdateInputsSlopeCompute( double* solution,int analysis_type,int sub_analysis_type);
-		void  UpdateInputsPrognostic( double* solution,int analysis_type,int sub_analysis_type);
-		void  UpdateInputsPrognostic2(double* solution,int analysis_type,int sub_analysis_type);
-		void  UpdateInputsBalancedthickness( double* solution,int analysis_type,int sub_analysis_type);
-		void  UpdateInputsBalancedthickness2( double* solution,int analysis_type,int sub_analysis_type);
-		void  UpdateInputsBalancedvelocities( double* solution,int analysis_type,int sub_analysis_type);
-		void AddInput(double value, int enum_type){ISSMERROR("not supporte yet!");}
-
-		/*}}}*/
-
-
-};
-#endif  /* _PENTA_H */
Index: /issm/trunk/src/c/objects/Result.cpp
===================================================================
--- /issm/trunk/src/c/objects/Result.cpp	(revision 3680)
+++ /issm/trunk/src/c/objects/Result.cpp	(revision 3681)
@@ -11,6 +11,6 @@
 
 #include "stdio.h"
-#include "./Result.h"
 #include <string.h>
+#include "./objects.h"
 #include "../EnumDefinitions/EnumDefinitions.h"
 #include "../include/macros.h"
Index: sm/trunk/src/c/objects/Rgb.cpp
===================================================================
--- /issm/trunk/src/c/objects/Rgb.cpp	(revision 3680)
+++ 	(revision )
@@ -1,161 +1,0 @@
-/*!\file Rgb.c
- * \brief: implementation of the Rgb object
- */
-
-
-#ifdef HAVE_CONFIG_H
-	#include "config.h"
-#else
-#error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
-#endif
-
-#include "stdio.h"
-#include <string.h>
-#include "../EnumDefinitions/EnumDefinitions.h"
-#include "../DataSet/DataSet.h"
-#include "../shared/shared.h"
-#include "../include/macros.h"
-#include "./objects.h"
-
-/*Object constructors and destructor*/
-/*FUNCTION Rgb::constructor {{{1*/
-Rgb::Rgb(){
-	return;
-}
-/*}}}1*/
-/*FUNCTION Rgb::creation {{{1*/
-Rgb::Rgb(int rgb_id,int rgb_nodeid1,int rgb_nodeid2, int rgb_dof){
-
-	id=rgb_id;
-	nodeid1=rgb_nodeid1;
-	nodeid2=rgb_nodeid2;
-	dof=rgb_dof;
-
-	return;
-}
-/*}}}1*/
-/*FUNCTION Rgb::destructor {{{1*/
-Rgb::~Rgb(){
-	return;
-}
-/*}}}1*/
-		
-/*Object marshall*/
-/*FUNCTION Rgb::Marshall {{{1*/
-void  Rgb::Marshall(char** pmarshalled_dataset){
-
-	char* marshalled_dataset=NULL;
-	int   enum_type=0;
-
-	/*recover marshalled_dataset: */
-	marshalled_dataset=*pmarshalled_dataset;
-
-	/*get enum type of Rgb: */
-	enum_type=RgbEnum;
-	
-	/*marshall enum: */
-	memcpy(marshalled_dataset,&enum_type,sizeof(enum_type));marshalled_dataset+=sizeof(enum_type);
-	
-	/*marshall Rgb data: */
-	memcpy(marshalled_dataset,&id,sizeof(id));marshalled_dataset+=sizeof(id);
-	memcpy(marshalled_dataset,&nodeid1,sizeof(nodeid1));marshalled_dataset+=sizeof(nodeid1);
-	memcpy(marshalled_dataset,&nodeid2,sizeof(nodeid2));marshalled_dataset+=sizeof(nodeid2);
-	memcpy(marshalled_dataset,&dof,sizeof(dof));marshalled_dataset+=sizeof(dof);
-
-	*pmarshalled_dataset=marshalled_dataset;
-	return;
-}
-/*}}}1*/
-/*FUNCTION Rgb::MarshallSize {{{1*/
-int   Rgb::MarshallSize(){
-
-	return sizeof(id)+
-		sizeof(nodeid1)+
-		sizeof(nodeid2)+
-		sizeof(dof)+
-		sizeof(int); //sizeof(int) for enum type
-}
-/*}}}1*/
-/*FUNCTION Rgb::Demarshall {{{1*/
-void  Rgb::Demarshall(char** pmarshalled_dataset){
-
-	char* marshalled_dataset=NULL;
-
-	/*recover marshalled_dataset: */
-	marshalled_dataset=*pmarshalled_dataset;
-
-	/*this time, no need to get enum type, the pointer directly points to the beginning of the 
-	 *object data (thanks to DataSet::Demarshall):*/
-
-	memcpy(&id,marshalled_dataset,sizeof(id));marshalled_dataset+=sizeof(id);
-	memcpy(&nodeid1,marshalled_dataset,sizeof(nodeid1));marshalled_dataset+=sizeof(nodeid1);
-	memcpy(&nodeid2,marshalled_dataset,sizeof(nodeid2));marshalled_dataset+=sizeof(nodeid2);
-	memcpy(&dof,marshalled_dataset,sizeof(dof));marshalled_dataset+=sizeof(dof);
-
-	/*return: */
-	*pmarshalled_dataset=marshalled_dataset;
-	return;
-}
-/*}}}1*/
-
-/*Object functions*/
-/*FUNCTION Rgb::copy {{{1*/
-Object* Rgb::copy() {
-	return new Rgb(*this); 
-}
-/*}}}1*/
-/*FUNCTION Rgb::DeepEcho {{{1*/
-void Rgb::DeepEcho(void){
-
-	printf("Rgb:\n");
-	printf("   id: %i\n",id);
-	printf("   nodeid1: %i\n",nodeid1);
-	printf("   nodeid2: %i\n",nodeid2);
-	printf("   dof: %i\n",dof);
-	return;
-}		
-/*}}}1*/
-/*FUNCTION Rgb::Echo {{{1*/
-void Rgb::Echo(void){
-
-	printf("Rgb:\n");
-	printf("   id: %i\n",id);
-	printf("   nodeid1: %i\n",nodeid1);
-	printf("   nodeid2: %i\n",nodeid2);
-	printf("   dof: %i\n",dof);
-	return;
-}
-/*}}}1*/
-/*FUNCTION Rgb::Enum {{{1*/
-int Rgb::Enum(void){
-
-	return RgbEnum;
-
-}
-/*}}}1*/
-/*FUNCTION Rgb::Id {{{1*/
-int    Rgb::Id(void){ return id; }
-/*}}}1*/
-/*FUNCTION Rgb::GetNodeId1{{{1*/
-int   Rgb::GetNodeId1(){
-	
-	return nodeid1;
-}
-/*}}}1*/
-/*FUNCTION Rgb::GetNodeId2 {{{1*/
-int   Rgb::GetNodeId2(){
-	
-	return nodeid2;
-}
-/*}}}1*/
-/*FUNCTION Rgb::GetDof {{{1*/
-int Rgb::GetDof(){
-	return dof;
-}
-/*}}}1*/
-/*FUNCTION Rgb::MyRank {{{1*/
-int    Rgb::MyRank(void){ 
-	extern int my_rank;
-	return my_rank; 
-}
-/*}}}1*/
Index: sm/trunk/src/c/objects/Rgb.h
===================================================================
--- /issm/trunk/src/c/objects/Rgb.h	(revision 3680)
+++ 	(revision )
@@ -1,45 +1,0 @@
-/*!\file Rgb.h
- * \brief: header file for rgb object
- */
-
-#ifndef _RGB_H_
-#define _RGB_H_
-
-/*Headers:*/
-/*{{{1*/
-#include "./Object.h"
-#include "../DataSet/DataSet.h"
-/*}}}*/
-
-class Rgb: public Object{
-
-	private: 
-		int	id; /*! id, to track it*/
-		int	nodeid1; 
-		int	nodeid2; 
-		int dof; /*!component*/
-
-	public:
-
-		Rgb();
-		Rgb(int rgb_id,int rgb_nodeid1,int rgb_nodeid2, int rgb_dof);
-		~Rgb();
-
-		void   Echo();
-		void   DeepEcho();
-		void   Marshall(char** pmarshalled_dataset);
-		int    MarshallSize();
-		void   Demarshall(char** pmarshalled_dataset);
-		int    Enum();
-		int    Id(); 
-		int    MyRank();
-
-		/*non virtual: */
-		int    GetNodeId1();
-		int    GetNodeId2();
-		int    GetDof();
-		Object* copy();
-
-};
-
-#endif  /* _RGB_H_ */
Index: sm/trunk/src/c/objects/Riftfront.cpp
===================================================================
--- /issm/trunk/src/c/objects/Riftfront.cpp	(revision 3680)
+++ 	(revision )
@@ -1,931 +1,0 @@
-/*!\file Riftfront.cpp
- * \brief: implementation of the Riftfront object
- */
-
-/*Headers:*/
-/*{{{1*/
-#ifdef HAVE_CONFIG_H
-	#include "config.h"
-#else
-#error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
-#endif
-
-#include "stdio.h"
-#include <string.h>
-#include "../EnumDefinitions/EnumDefinitions.h"
-#include "../shared/shared.h"
-#include "../include/typedefs.h"
-#include "../include/macros.h"
-#include "../ModelProcessorx/ModelProcessorx.h"
-#include "./objects.h"
-/*}}}*/
-
-/*Object constructors and destructor*/
-/*FUNCTION Riftfront::Riftfront(){{{1*/
-Riftfront::Riftfront(){
-	this->inputs=NULL;
-	this->parameters=NULL;
-}
-/*}}}*/
-/*FUNCTION Riftfront::Riftfront(int id, int* node_ids, int matice_id, int matpar_id){{{1*/
-Riftfront::Riftfront(int riftfront_id,int* riftfront_node_ids, int riftfront_matpar_id): 
-	hnodes(riftfront_node_ids,2),
-	hmatpar(&riftfront_matpar_id,1)
-{
-
-	/*all the initialization has been done by the initializer, just fill in the id: */
-	this->id=riftfront_id;
-	this->parameters=NULL;
-	this->inputs=new Inputs();
-
-}
-/*}}}*/
-/*FUNCTION Riftfront::Riftfront(int id, Hook* hnodes, Hook* hmatice, Hook* hmatpar, Parameters* parameters, Inputs* riftfront_inputs) {{{1*/
-Riftfront::Riftfront(int riftfront_id,Hook* riftfront_hnodes, Hook* riftfront_hmatpar, Parameters* riftfront_parameters, Inputs* riftfront_inputs):
-	hnodes(riftfront_hnodes),
-	hmatpar(riftfront_hmatpar)
-{
-
-	/*all the initialization has been done by the initializer, just fill in the id: */
-	this->id=riftfront_id;
-	if(riftfront_inputs){
-		this->inputs=(Inputs*)riftfront_inputs->Copy();
-	}
-	else{
-		this->inputs=new Inputs();
-	}
-	/*point parameters: */
-	this->parameters=riftfront_parameters;
-}
-/*}}}*/
-/*FUNCTION Riftfront::Riftfront(int id, int i, IoModel* iomodel){{{1*/
-Riftfront::Riftfront(int riftfront_id,int i, IoModel* iomodel){
-
-	/*data: */
-	int    riftfront_node_ids[2];
-	int    riftfront_matpar_id;
-	int    riftfront_type;
-	double riftfront_fill;
-	double riftfront_friction;
-	double riftfront_fractionincrement;
-	bool   riftfront_shelf;
-
-	/*intermediary: */
-	int el1    ,el2;
-	int grid1  ,grid2;
-
-	/*Ok, retrieve all the data needed to add a penalty between the two grids: */
-	el1=(int)*(iomodel->riftinfo+RIFTINFOSIZE*i+2);
-	el2=(int)*(iomodel->riftinfo+RIFTINFOSIZE*i+3); 
-
-	grid1=(int)*(iomodel->riftinfo+RIFTINFOSIZE*i+0); 
-	grid2=(int)*(iomodel->riftinfo+RIFTINFOSIZE*i+1);
-
-	/*id: */
-	this->id=riftfront_id;
-
-	/*hooks: */
-	riftfront_node_ids[0]=grid1;
-	riftfront_node_ids[1]=grid2;
-	riftfront_matpar_id=iomodel->numberofelements+1; //matlab indexing
-
-	this->hnodes.Init(riftfront_node_ids,2);
-	this->hmatpar.Init(&riftfront_matpar_id,1);
-
-	/*computational parameters: */
-	this->active=0;
-	this->frozen=0;
-	this->counter=0;
-	this->prestable=0;
-	this->penalty_lock=0;
-	this->material_converged=0;
-	this->normal[0]=*(iomodel->riftinfo+RIFTINFOSIZE*i+4);
-	this->normal[1]=*(iomodel->riftinfo+RIFTINFOSIZE*i+5);
-	this->length=*(iomodel->riftinfo+RIFTINFOSIZE*i+6);
-	this->fraction=*(iomodel->riftinfo+RIFTINFOSIZE*i+9);
-
-	//intialize inputs, and add as many inputs per element as requested: 
-	this->inputs=new Inputs();
-		
-	riftfront_type=SegmentRiftfrontEnum;
-	riftfront_fill = (int)*(iomodel->riftinfo+RIFTINFOSIZE*i+7);
-	riftfront_friction=*(iomodel->riftinfo+RIFTINFOSIZE*i+8);
-	riftfront_fractionincrement=*(iomodel->riftinfo+RIFTINFOSIZE*i+10);
-	riftfront_shelf=(bool)iomodel->gridoniceshelf[grid1-1];
-
-	this->inputs->AddInput(new IntInput(TypeEnum,riftfront_type));
-	this->inputs->AddInput(new DoubleInput(FillEnum,riftfront_fill));
-	this->inputs->AddInput(new DoubleInput(FrictionEnum,riftfront_friction));
-	this->inputs->AddInput(new DoubleInput(FractionIncrementEnum,riftfront_fractionincrement));
-	this->inputs->AddInput(new BoolInput(SegmentOnIceShelfEnum,riftfront_shelf));
-	
-	//this->parameters: we still can't point to it, it may not even exist. Configure will handle this.
-	this->parameters=NULL;
-		
-}
-/*}}}1*/
-/*FUNCTION Riftfront::~Riftfront(){{{1*/
-Riftfront::~Riftfront(){
-	delete inputs;
-	this->parameters=NULL;
-}
-/*}}}*/
-
-/*Object marshall*/
-/*FUNCTION Riftfront::copy {{{1*/
-Object* Riftfront::copy() {
-	return new Riftfront(*this); 
-}
-/*}}}1*/
-/*FUNCTION Riftfront::Configure {{{1*/
-void  Riftfront::Configure(DataSet* elementsin,DataSet* loadsin,DataSet* nodesin,DataSet* verticesin,DataSet* materialsin,Parameters* parametersin){
-
-	/*Take care of hooking up all objects for this element, ie links the objects in the hooks to their respective 
-	 * datasets, using internal ids and offsets hidden in hooks: */
-	hnodes.configure(nodesin);
-	hmatpar.configure(materialsin);
-
-	/*point parameters to real dataset: */
-	this->parameters=parametersin;
-
-}
-/*}}}*/
-/*FUNCTION Riftfront::DeepEcho{{{1*/
-void Riftfront::DeepEcho(void){
-
-	printf("Riftfront:\n");
-	printf("   id: %i\n",id);
-	hnodes.DeepEcho();
-	hmatpar.DeepEcho();
-	printf("   parameters\n");
-	parameters->DeepEcho();
-	printf("   inputs\n");
-	inputs->DeepEcho();
-}
-/*}}}*/
-/*FUNCTION Riftfront::Demarshall {{{1*/
-void  Riftfront::Demarshall(char** pmarshalled_dataset){
-
-	char* marshalled_dataset=NULL;
-	int   i;
-
-	/*recover marshalled_dataset: */
-	marshalled_dataset=*pmarshalled_dataset;
-
-	/*this time, no need to get enum type, the pointer directly points to the beginning of the 
-	 *object data (thanks to DataSet::Demarshall):*/
-
-	memcpy(&id,marshalled_dataset,sizeof(id));marshalled_dataset+=sizeof(id);
-	memcpy(&active,marshalled_dataset,sizeof(active));marshalled_dataset+=sizeof(active);
-	memcpy(&normal,marshalled_dataset,sizeof(normal));marshalled_dataset+=sizeof(normal);
-	memcpy(&length,marshalled_dataset,sizeof(length));marshalled_dataset+=sizeof(length);
-	memcpy(&fraction,marshalled_dataset,sizeof(fraction));marshalled_dataset+=sizeof(fraction);
-	memcpy(&frozen,marshalled_dataset,sizeof(frozen));marshalled_dataset+=sizeof(frozen);
-	memcpy(&counter,marshalled_dataset,sizeof(counter));marshalled_dataset+=sizeof(counter);
-	memcpy(&prestable,marshalled_dataset,sizeof(prestable));marshalled_dataset+=sizeof(prestable);
-	memcpy(&penalty_lock,marshalled_dataset,sizeof(penalty_lock));marshalled_dataset+=sizeof(penalty_lock);
-	memcpy(&material_converged,marshalled_dataset,sizeof(material_converged));marshalled_dataset+=sizeof(material_converged);
-
-	/*demarshall hooks: */
-	hnodes.Demarshall(&marshalled_dataset);
-	hmatpar.Demarshall(&marshalled_dataset);
-	
-	/*demarshall inputs: */
-	inputs=(Inputs*)DataSetDemarshallRaw(&marshalled_dataset); 
-
-	/*parameters: may not exist even yet, so let Configure handle it: */
-	this->parameters=NULL;
-
-	/*return: */
-	*pmarshalled_dataset=marshalled_dataset;
-}
-/*}}}*/
-/*FUNCTION Riftfront::Echo {{{1*/
-void Riftfront::Echo(void){
-	this->DeepEcho();
-}
-/*}}}1*/
-/*FUNCTION Riftfront::Enum {{{1*/
-int Riftfront::Enum(void){
-
-	return RiftfrontEnum;
-
-}
-/*}}}1*/
-/*FUNCTION Riftfront::Id {{{1*/
-int    Riftfront::Id(void){ return id; }
-/*}}}1*/
-/*FUNCTION Riftfront::Marshall {{{1*/
-void  Riftfront::Marshall(char** pmarshalled_dataset){
-
-	char* marshalled_dataset=NULL;
-	int   enum_type=0;
-	char* marshalled_inputs=NULL;
-	int   marshalled_inputs_size;
-
-	/*recover marshalled_dataset: */
-	marshalled_dataset=*pmarshalled_dataset;
-
-	/*get enum type of Riftfront: */
-	enum_type=RiftfrontEnum;
-
-	/*marshall enum: */
-	memcpy(marshalled_dataset,&enum_type,sizeof(enum_type));marshalled_dataset+=sizeof(enum_type);
-
-	/*marshall Riftfront data: */
-	memcpy(marshalled_dataset,&id,sizeof(id));marshalled_dataset+=sizeof(id);
-	memcpy(marshalled_dataset,&active,sizeof(active));marshalled_dataset+=sizeof(active);
-	memcpy(marshalled_dataset,&normal,sizeof(normal));marshalled_dataset+=sizeof(normal);
-	memcpy(marshalled_dataset,&length,sizeof(length));marshalled_dataset+=sizeof(length);
-	memcpy(marshalled_dataset,&fraction,sizeof(fraction));marshalled_dataset+=sizeof(fraction);
-	memcpy(marshalled_dataset,&frozen,sizeof(frozen));marshalled_dataset+=sizeof(frozen);
-	memcpy(marshalled_dataset,&counter,sizeof(counter));marshalled_dataset+=sizeof(counter);
-	memcpy(marshalled_dataset,&prestable,sizeof(prestable));marshalled_dataset+=sizeof(prestable);
-	memcpy(marshalled_dataset,&penalty_lock,sizeof(penalty_lock));marshalled_dataset+=sizeof(penalty_lock);
-
-	/*Marshall hooks: */
-	hnodes.Marshall(&marshalled_dataset);
-	hmatpar.Marshall(&marshalled_dataset);
-
-	/*Marshall inputs: */
-	marshalled_inputs_size=inputs->MarshallSize();
-	marshalled_inputs=inputs->Marshall();
-	memcpy(marshalled_dataset,marshalled_inputs,marshalled_inputs_size*sizeof(char));
-	marshalled_dataset+=marshalled_inputs_size;
-
-	/*parameters: don't do anything about it. parameters are marshalled somewhere else!*/
-
-	xfree((void**)&marshalled_inputs);
-
-	*pmarshalled_dataset=marshalled_dataset;
-	return;
-}
-/*}}}*/
-/*FUNCTION Riftfront::MarshallSize {{{1*/
-int   Riftfront::MarshallSize(){
-	
-	return sizeof(id)
-		+sizeof(active)
-		+sizeof(normal)
-		+sizeof(length)
-		+sizeof(fraction)
-		+sizeof(frozen)
-		+sizeof(counter)
-		+sizeof(prestable)
-		+sizeof(penalty_lock)
-		+hnodes.MarshallSize()
-		+hmatpar.MarshallSize()
-		+inputs->MarshallSize()
-		+sizeof(int); //sizeof(int) for enum type
-}
-/*}}}*/
-/*FUNCTION Riftfront::MyRank {{{1*/
-int    Riftfront::MyRank(void){ 
-	extern int my_rank;
-	return my_rank; 
-}
-/*}}}1*/
-
-/*Object functions*/
-/*FUNCTION Riftfront::Constrain {{{1*/
-#define _ZIGZAGCOUNTER_
-
-int   Riftfront::Constrain(int* punstable,  int analysis_type){
-
-	const int   numgrids        = 2;
-	double      max_penetration;
-	double      penetration;
-	int         activate;
-	int         found;
-	int         unstable;
-	double      vx1;
-	double      vy1;
-	double      vx2;
-	double      vy2;
-	double      fractionincrement;
-
-
-	/*Objects: */
-	Element   **elements        = NULL;
-	Node      **nodes           = NULL;
-	Tria       *tria1           = NULL;
-	Tria       *tria2           = NULL;
-
-	/*Recover hook objects: */
-	elements=(Element**)helements.deliverp();
-	nodes=(Node**)hnodes.deliverp();
-
-	/*enum of element? */
-	if(elements[0]->Enum()!=TriaEnum)ISSMERROR(" only Tria element allowed for Riftfront load!");
-
-	/*recover elements on both side of rift: */
-	tria1=(Tria*)elements[0];
-	tria2=(Tria*)elements[1];
-
-	/*Is this constraint frozen? In which case we don't touch: */
-	if (this->frozen){
-		*punstable=0;
-		return 1;
-	}
-
-	/*recover parameters: */
-	this->inputs->GetParameterValue(&fractionincrement,FractionIncrementEnum);
-
-	/*First recover velocity: */
-	tria1->inputs->GetParameterValue(&vx1,nodes[0],VxEnum);
-	tria2->inputs->GetParameterValue(&vx2,nodes[1],VxEnum);
-	tria1->inputs->GetParameterValue(&vy1,nodes[0],VyEnum);
-	tria2->inputs->GetParameterValue(&vy2,nodes[1],VyEnum);
-
-	/*Node 1 faces node 2, compute penetration of 2 into 1 (V2-V1).N (with N normal vector, and V velocity vector: */
-	penetration=(vx2-vx1)*normal[0]+(vy2-vy1)*normal[1];
-
-	/*activation: */
-	if(penetration<0)activate=1;
-	else  activate=0;
-
-	/*Here, we try to avoid zigzaging. When a penalty activates and deactivates for more than penalty_lock times, 
-	 * we increase the fraction of melange:*/
-	if(this->counter>this->penalty_lock){
-		/*reset counter: */
-		this->counter=0;
-		/*increase melange fraction: */
-		this->fraction+=fractionincrement;
-		if (this->fraction>1)this->fraction=(double)1.0;
-		//printf("riftfront %i fraction: %g\n",this->Id(),this->fraction);
-	}
-
-	//Figure out stability of this penalty
-	if(this->active==activate){
-		unstable=0;
-	}
-	else{
-		unstable=1;
-		this->counter++;
-	}
-
-	//Set penalty flag
-	this->active=activate;
-
-	//if ((penetration>0) & (this->active==1))printf("Riftfront %i wants to be released\n",Id());
-
-	/*assign output pointer: */
-	*punstable=unstable;
-}
-/*}}}1*/
-/*FUNCTION Riftfront::CreateKMatrix {{{1*/
-void  Riftfront::CreateKMatrix(Mat Kgg,int analysis_type,int sub_analysis_type){
-	/*do nothing: */
-}
-/*}}}1*/
-/*FUNCTION Riftfront::CreatePVector {{{1*/
-void  Riftfront::CreatePVector(Vec pg,  int analysis_type,int sub_analysis_type){
-	/*do nothing: */
-}
-/*}}}1*/
-/*FUNCTION Riftfront::FreezeConstraints{{{1*/
-void   Riftfront::FreezeConstraints( int analysis_type){
-
-	/*Just set frozen flag to 1: */
-	this->frozen=1;
-
-}
-/*}}}1*/
-/*FUNCTION Riftfront::GetDofList {{{1*/
-
-void  Riftfront::GetDofList(int* doflist,int* pnumberofdofspernode){
-
-	int i,j;
-	int doflist_per_node[MAXDOFSPERNODE];
-	int numberofdofspernode;
-	Node      **nodes           = NULL;
-	
-	nodes=(Node**)hnodes.deliverp();
-
-	for(i=0;i<MAX_RIFTFRONT_GRIDS;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;
-}
-/*}}}1*/
-/*FUNCTION Riftfront::IsFrozen{{{1*/
-bool   Riftfront::IsFrozen(void){
-
-	/*Just set frozen flag to 1: */
-	if(this->frozen)return 1;
-	else return 0;
-}
-/*}}}1*/
-/*FUNCTION Riftfront::IsMaterialStable {{{1*/
-int   Riftfront::IsMaterialStable( int analysis_type){
-
-	int found=0;
-	double converged=0;
-
-	this->inputs->GetParameterValue(&converged,ConvergedEnum);
-
-	if(converged){
-		/*ok, material non-linearity has converged. If that was already the case, we keep 
-		 * constraining the rift front. If it was not, and this is the first time the material 
-		 * has converged, we start constraining now!: */
-		this->material_converged=1;
-	}
-
-	return this->material_converged;
-}
-/*}}}1*/
-/*FUNCTION Riftfront::MaxPenetration {{{1*/
-int   Riftfront::MaxPenetration(double* ppenetration,  int analysis_type){
-
-	const int     numgrids=2;
-	double        max_penetration;
-	double        penetration=0;
-	int           found;
-	double      vx1;
-	double      vy1;
-	double      vx2;
-	double      vy2;
-
-	/*Objects: */
-	Element   **elements        = NULL;
-	Node      **nodes           = NULL;
-	Tria       *tria1           = NULL;
-	Tria       *tria2           = NULL;
-
-	/*Recover hook objects: */
-	elements=(Element**)helements.deliverp();
-	nodes=(Node**)hnodes.deliverp();
-
-	/*enum of element? */
-	if(elements[0]->Enum()!=TriaEnum)ISSMERROR(" only Tria element allowed for Riftfront load!");
-
-	/*recover elements on both side of rift: */
-	tria1=(Tria*)elements[0];
-	tria2=(Tria*)elements[1];
-
-	//initialize: 
-	penetration=-1;
-
-	/*recover velocity: */
-	tria1->inputs->GetParameterValue(&vx1,nodes[0],VxEnum);
-	tria2->inputs->GetParameterValue(&vx2,nodes[1],VxEnum);
-	tria1->inputs->GetParameterValue(&vy1,nodes[0],VyEnum);
-	tria2->inputs->GetParameterValue(&vy2,nodes[1],VyEnum);
-
-	/*Grid 1 faces grid2, compute penetration of 2 into 1 (V2-V1).N (with N normal vector, and V velocity vector: */
-	penetration=(vx2-vx1)*normal[0]+(vy2-vy1)*normal[1];
-
-	/*Now, we return penetration only if we are active!: */
-	if(this->active==0)penetration=-1;
-
-	/*If we are zigzag locked, same thing: */
-	if(this->counter>this->penalty_lock)penetration=-1;
-	
-	/*assign output pointer: */
-	*ppenetration=penetration;
-
-}
-/*}}}1*/
-/*FUNCTION Riftfront::OutputProperties {{{1*/
-void  Riftfront::OutputProperties(Vec riftproperties){
-
-	int row_id=0;
-	double value;
-
-	/*recover id of penalty: */
-	row_id=this->Id()-1; //c indexing, ids were matlab indexed
-	value=(double)this->fraction;
-
-	/*Plug id and fraction  into riftproperties matrix: */
-	VecSetValues(riftproperties,1,&row_id,&value,INSERT_VALUES);
-}
-/*}}}1*/
-/*FUNCTION Riftfront::PenaltyCreateKMatrix {{{1*/
-void  Riftfront::PenaltyCreateKMatrix(Mat Kgg,double kmax,int analysis_type,int sub_analysis_type){
-
-	int         i;
-	int         j;
-	const int   numgrids            = MAX_RIFTFRONT_GRIDS;
-	int         dofs[1]             = {0};
-	double      Ke_gg[4][4];
-	const int   numdof              = 2 *numgrids;
-	int         doflist[numdof];
-	int         numberofdofspernode;
-	double      thickness;
-	double      h[2];
-	double      penalty_offset;
-	double      friction;
-
-	/*Objects: */
-	Element   **elements            = NULL;
-	Node      **nodes               = NULL;
-	Tria       *tria1               = NULL;
-	Tria       *tria2               = NULL;
-
-	/*Recover hook objects: */
-	elements=(Element**)helements.deliverp();
-	nodes=(Node**)hnodes.deliverp();
-
-	/*enum of element? */
-	if(elements[0]->Enum()!=TriaEnum)ISSMERROR(" only Tria element allowed for Riftfront load!");
-
-	/*recover elements on both side of rift: */
-	tria1=(Tria*)elements[0];
-	tria2=(Tria*)elements[1];
-
-	
-	/* Get node coordinates and dof list: */
-	GetDofList(&doflist[0],&numberofdofspernode);
-
-	/* Set Ke_gg to 0: */
-	for(i=0;i<numdof;i++) for(j=0;j<numdof;j++) Ke_gg[i][j]=0.0;
-
-	/*Get some parameters: */
-	this->parameters->FindParam(&penalty_offset,PenaltyOffsetEnum);
-	this->inputs->GetParameterValue(&friction,FrictionEnum);
-
-	if(this->active){
-	
-		/*There is contact, we need to constrain the normal velocities (zero penetration), and the 
-		 *contact slip friction. */
-		  
-		/*Recover thickness: */
-		tria1->inputs->GetParameterValue(&h[0],nodes[0],ThicknessEnum);
-		tria2->inputs->GetParameterValue(&h[1],nodes[1],ThicknessEnum);
-
-		if (h[0]!=h[1])ISSMERROR(" different thicknesses not supported for rift fronts");
-		thickness=h[0];
-
-		/*From Peter Wriggers book (Computational Contact Mechanics, p191): */
-		//First line:
-		Ke_gg[0][0]+=pow(normal[0],2)*kmax*pow(10,penalty_offset);
-		Ke_gg[0][1]+=normal[0]*normal[1]*kmax*pow(10,penalty_offset);
-		Ke_gg[0][2]+=-pow(normal[0],2)*kmax*pow(10,penalty_offset);
-		Ke_gg[0][3]+=-normal[0]*normal[1]*kmax*pow(10,penalty_offset);
-		//Second line:
-		Ke_gg[1][0]+=normal[0]*normal[1]*kmax*pow(10,penalty_offset);
-		Ke_gg[1][1]+=pow(normal[1],2)*kmax*pow(10,penalty_offset);
-		Ke_gg[1][2]+=-normal[0]*normal[1]*kmax*pow(10,penalty_offset);
-		Ke_gg[1][3]+=-pow(normal[1],2)*kmax*pow(10,penalty_offset);
-		//Third line:
-		Ke_gg[2][0]+=-pow(normal[0],2)*kmax*pow(10,penalty_offset);
-		Ke_gg[2][1]+=-normal[0]*normal[1]*kmax*pow(10,penalty_offset);
-		Ke_gg[2][2]+=pow(normal[0],2)*kmax*pow(10,penalty_offset);
-		Ke_gg[2][3]+=normal[0]*normal[1]*kmax*pow(10,penalty_offset);
-		//Fourth line:
-		Ke_gg[3][0]+=-normal[0]*normal[1]*kmax*pow(10,penalty_offset);
-		Ke_gg[3][1]+=-pow(normal[1],2)*kmax*pow(10,penalty_offset);
-		Ke_gg[3][2]+=normal[0]*normal[1]*kmax*pow(10,penalty_offset);
-		Ke_gg[3][3]+=pow(normal[1],2)*kmax*pow(10,penalty_offset);
-
-		/*Now take care of the friction: of type sigma=frictiontangent_velocity2-tangent_velocity1)*/
-		
-		//First line:
-		Ke_gg[0][0]+=pow(normal[1],2)*thickness*length*friction;
-		Ke_gg[0][1]+=-normal[0]*normal[1]*thickness*length*friction;
-		Ke_gg[0][2]+=-pow(normal[1],2)*thickness*length*friction;
-		Ke_gg[0][3]+=normal[0]*normal[1]*thickness*length*friction;
-		//Second line:
-		Ke_gg[1][0]+=-normal[0]*normal[1]*thickness*length*friction;
-		Ke_gg[1][1]+=pow(normal[0],2)*thickness*length*friction;
-		Ke_gg[1][2]+=normal[0]*normal[1]*thickness*length*friction;
-		Ke_gg[1][3]+=-pow(normal[0],2)*thickness*length*friction;
-		//Third line:
-		Ke_gg[2][0]+=-pow(normal[1],2)*thickness*length*friction;
-		Ke_gg[2][1]+=normal[0]*normal[1]*thickness*length*friction;
-		Ke_gg[2][2]+=pow(normal[1],2)*thickness*length*friction;
-		Ke_gg[2][3]+=-normal[0]*normal[1]*thickness*length*friction;
-		//Fourth line:
-		Ke_gg[3][0]+=normal[0]*normal[1]*thickness*length*friction;
-		Ke_gg[3][1]+=-pow(normal[0],2)*thickness*length*friction;
-		Ke_gg[3][2]+=-normal[0]*normal[1]*thickness*length*friction;
-		Ke_gg[3][3]+=pow(normal[0],2)*thickness*length*friction;
-
-		/*Add Ke_gg to global matrix Kgg: */
-		MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)Ke_gg,ADD_VALUES);
-	}
-	else{
-		/*the grids on both sides of the rift do not penetrate.  PenaltyCreatePVector will 
-		 *take care of adding point loads to simulate pressure on the rift flanks. But as far as stiffness, 
-		 there is none (0 stiffness implies decoupling of the flank rifts, which is exactly what we want): */
-	}
-
-}
-/*}}}1*/
-/*FUNCTION Riftfront::PenaltyCreatePVector {{{1*/
-void  Riftfront::PenaltyCreatePVector(Vec pg,double kmax,int analysis_type,int sub_analysis_type){
-
-	int         i                     ,j;
-	const int   numgrids            = MAX_RIFTFRONT_GRIDS;
-	double      pe_g[4]={0.0};
-	const int   numdof              = 2 *numgrids;
-	int         doflist[numdof];
-	int         numberofdofspernode;
-
-	double      rho_ice;
-	double      rho_water;
-	double      gravity;
-	double      thickness;
-	double      h[2];
-	double      bed;
-	double      b[2];
-	double      pressure;
-	double      pressure_litho;
-	double      pressure_air;
-	double      pressure_melange;
-	double      pressure_water;
-	double      fill;
-	bool        shelf;
-
-
-	/*Objects: */
-	Element   **elements            = NULL;
-	Node      **nodes               = NULL;
-	Tria       *tria1               = NULL;
-	Tria       *tria2               = NULL;
-	Matpar     *matpar              = NULL;
-
-	
-	/*Recover hook objects: */
-	elements=(Element**)helements.deliverp();
-	nodes=(Node**)hnodes.deliverp();
-	matpar=(Matpar*)hmatpar.delivers();
-
-	/*enum of element? */
-	if(elements[0]->Enum()!=TriaEnum)ISSMERROR(" only Tria element allowed for Riftfront load!");
-
-	/*recover elements on both side of rift: */
-	tria1=(Tria*)elements[0];
-	tria2=(Tria*)elements[1];
-
-	/* Get node coordinates and dof list: */
-	GetDofList(&doflist[0],&numberofdofspernode);
-
-	/*Get some inputs: */
-	this->inputs->GetParameterValue(&fill,FillEnum);
-	this->inputs->GetParameterValue(&shelf,SegmentOnIceShelfEnum);
-
-	if(!this->active){
-		/*Ok, this rift is opening. We should put loads on both sides of the rift flanks. Because we are dealing with contact mechanics, 
-		 * and we want to avoid zigzagging of the loads, we want lump the loads onto grids, not onto surfaces between grids.:*/
-	
-		/*Ok, to compute the pressure, we are going to need material properties, thickness and bed for the two grids. We assume those properties to 
-		 * be the same across the rift.: */
-
-		rho_ice=matpar->GetRhoIce();
-		rho_water=matpar->GetRhoWater();
-		gravity=matpar->GetG();
-
-		/*get thickness: */
-		tria1->inputs->GetParameterValue(&h[0],nodes[0],ThicknessEnum);
-		tria2->inputs->GetParameterValue(&h[1],nodes[1],ThicknessEnum);
-
-		if (h[0]!=h[1])ISSMERROR(" different thicknesses not supported for rift fronts");
-		thickness=h[0];
-
-		tria1->inputs->GetParameterValue(&b[0],nodes[0],BedEnum);
-		tria2->inputs->GetParameterValue(&b[1],nodes[1],BedEnum);
-
-		if (b[0]!=b[1])ISSMERROR(" different beds not supported for rift fronts");
-		bed=b[0];
-
-		/*Ok, now compute the pressure (in norm) that is being applied to the flanks, depending on the type of fill: */
-		if(fill==WaterEnum){
-			if(shelf){
-				/*We are on an ice shelf, hydrostatic equilibrium is used to determine the pressure for water fill: */
-				pressure=rho_ice*gravity*pow(thickness,(double)2)/(double)2  - rho_water*gravity*pow(bed,(double)2)/(double)2; 
-			}
-			else{
-				//We are on an icesheet, we assume the water column fills the entire front: */
-				pressure=rho_ice*gravity*pow(thickness,(double)2)/(double)2  - rho_water*gravity*pow(thickness,(double)2)/(double)2; 
-			}
-		}
-		else if(fill==AirEnum){
-			pressure=rho_ice*gravity*pow(thickness,(double)2)/(double)2;   //icefront on an ice sheet, pressure imbalance ice vs air.
-		}
-		else if(fill==IceEnum){ //icefront finding itself against another icefront (pressure imbalance is fully compensated, ice vs ice)
-			pressure=0;
-		}
-		else if(fill==MelangeEnum){ //icefront finding itself against another icefront (pressure imbalance is fully compensated, ice vs ice)
-			
-			if(!shelf) ISSMERROR("%s%i%s","fill type ",fill," not supported on ice sheets yet.");
-
-			pressure_litho=rho_ice*gravity*pow(thickness,(double)2)/(double)2;
-			pressure_air=0;
-			pressure_melange=rho_ice*gravity*pow(fraction*thickness,(double)2)/(double)2;
-			pressure_water=1.0/2.0*rho_water*gravity*  ( pow(bed,2.0)-pow(rho_ice/rho_water*fraction*thickness,2.0) );
-
-			pressure=pressure_litho-pressure_air-pressure_melange-pressure_water;
-		}
-		else{
-			ISSMERROR("%s%i%s","fill type ",fill," not supported yet.");
-		}
-
-		/*Ok, add contribution to first grid, along the normal i==0: */
-		for (j=0;j<2;j++){
-			pe_g[j]+=pressure*normal[j]*length;
-		}
-	
-		/*Add contribution to second grid, along the opposite normal: i==1 */
-		for (j=0;j<2;j++){
-			pe_g[2+j]+= -pressure*normal[j]*length;
-		}	
-		/*Add pe_g to global vector pg; */
-		VecSetValues(pg,numdof,doflist,(const double*)pe_g,ADD_VALUES);
-
-	}
-	else{
-		/*The penalty is active. No loads implied here.*/
-	}
-}
-/*}}}1*/
-/*FUNCTION Riftfront::Penetration {{{1*/
-int   Riftfront::Penetration(double* ppenetration,  int analysis_type){
-
-	double    vx1;
-	double    vy1;
-	double    vx2;
-	double    vy2;
-
-	double    penetration;
-	int       found;
-
-	/*Objects: */
-	Element **elements    = NULL;
-	Node    **nodes       = NULL;
-	Tria     *tria1       = NULL;
-	Tria     *tria2       = NULL;
-
-	/*Recover hook objects: */
-	elements=(Element**)helements.deliverp();
-	nodes=(Node**)hnodes.deliverp();
-
-	/*enum of element? */
-	if(elements[0]->Enum()!=TriaEnum)ISSMERROR(" only Tria element allowed for Riftfront load!");
-
-	/*recover elements on both side of rift: */
-	tria1=(Tria*)elements[0];
-	tria2=(Tria*)elements[1];
-
-	/*First recover velocity: */
-	tria1->inputs->GetParameterValue(&vx1,nodes[0],VxEnum);
-	tria2->inputs->GetParameterValue(&vx2,nodes[1],VxEnum);
-	tria1->inputs->GetParameterValue(&vy1,nodes[0],VyEnum);
-	tria2->inputs->GetParameterValue(&vy2,nodes[1],VyEnum);
-
-	/*Node 1 faces node 2, compute penetration of 2 into 1 (V2-V1).N (with N normal vector, and V velocity vector: */
-	penetration=(vx2-vx1)*normal[0]+(vy2-vy1)*normal[1];
-
-	/*Now, we return penetration only if we are active!: */
-	if(this->active==0)penetration=0;
-	
-	/*assign output pointer: */
-	*ppenetration=penetration;
-
-}
-/*}}}1*/
-/*FUNCTION Riftfront::PotentialUnstableConstraint {{{1*/
-int   Riftfront::PotentialUnstableConstraint(int* punstable,  int analysis_type){
-
-
-	const int   numgrids        = 2;
-	double      max_penetration;
-	double      penetration;
-	int         activate;
-	int         unstable;
-	int         found;
-	double      vx1;
-	double      vy1;
-	double      vx2;
-	double      vy2;
-
-
-	/*Objects: */
-	Element   **elements        = NULL;
-	Node      **nodes           = NULL;
-	Tria       *tria1           = NULL;
-	Tria       *tria2           = NULL;
-
-	/*Recover hook objects: */
-	elements=(Element**)helements.deliverp();
-	nodes=(Node**)hnodes.deliverp();
-
-	/*enum of element? */
-	if(elements[0]->Enum()!=TriaEnum)ISSMERROR(" only Tria element allowed for Riftfront load!");
-
-	/*recover elements on both side of rift: */
-	tria1=(Tria*)elements[0];
-	tria2=(Tria*)elements[1];
-
-	/*First recover velocity: */
-	tria1->inputs->GetParameterValue(&vx1,nodes[0],VxEnum);
-	tria2->inputs->GetParameterValue(&vx2,nodes[1],VxEnum);
-	tria1->inputs->GetParameterValue(&vy1,nodes[0],VyEnum);
-	tria2->inputs->GetParameterValue(&vy2,nodes[1],VyEnum);
-
-	/*Node 1 faces node 2, compute penetration of 2 into 1 (V2-V1).N (with N normal vector, and V velocity vector: */
-	penetration=(vx2-vx1)*normal[0]+(vy2-vy1)*normal[1];
-
-	/*Ok, we are looking for positive penetration in an active constraint: */
-	if(this->active){
-		if (penetration>=0){
-			unstable=1;
-		}
-		else{
-			unstable=0;
-		}
-	}
-	else{
-		unstable=0;
-	}
-
-	/*assign output pointer: */
-	*punstable=unstable;
-}
-/*}}}1*/
-/*FUNCTION Riftfront::PreConstrain {{{1*/
-int   Riftfront::PreConstrain(int* punstable,  int analysis_type){
-
-	const int   numgrids    = 2;
-	double      penetration;
-	int         unstable;
-	int         found;
-	double      vx1;
-	double      vy1;
-	double      vx2;
-	double      vy2;
-
-
-	/*Objects: */
-	Element   **elements    = NULL;
-	Node      **nodes       = NULL;
-	Tria       *tria1       = NULL;
-	Tria       *tria2       = NULL;
-
-	/*Recover hook objects: */
-	elements=(Element**)helements.deliverp();
-	nodes=(Node**)hnodes.deliverp();
-
-	/*enum of element? */
-	if(elements[0]->Enum()!=TriaEnum)ISSMERROR(" only Tria element allowed for Riftfront load!");
-
-	/*recover elements on both side of rift: */
-	tria1=(Tria*)elements[0];
-	tria2=(Tria*)elements[1];
-
-	/*First recover velocity: */
-	tria1->inputs->GetParameterValue(&vx1,nodes[0],VxEnum);
-	tria2->inputs->GetParameterValue(&vx2,nodes[1],VxEnum);
-	tria1->inputs->GetParameterValue(&vy1,nodes[0],VyEnum);
-	tria2->inputs->GetParameterValue(&vy2,nodes[1],VyEnum);
-
-	/*Node 1 faces node 2, compute penetration of 2 into 1 (V2-V1).N (with N normal vector, and V velocity vector: */
-	penetration=(vx2-vx1)*normal[0]+(vy2-vy1)*normal[1];
-
-	/*Ok, we are preconstraining here. Ie, anything that penetrates is constrained until stability of the entire set 
-	 * of constraints is reached.: */
-	if(penetration<0){
-		if (!this->active){
-			/*This is the first time penetration happens: */
-			this->active=1;
-			unstable=1;
-		}
-		else{
-			/*This constraint was already active: */
-			this->active=1;
-			unstable=0;
-		}
-	}
-	else{
-		/*No penetration happening. : */
-		if (!this->active){
-			/*This penalty was not active, and no penetration happening. Do nonthing: */
-			this->active=0;
-			unstable=0; 
-		}
-		else{
-			/*Ok, this penalty wants to get released. But not now, this is preconstraint, not constraint: */
-			this->active=1;
-			unstable=0;
-		}
-	}
-
-	/*assign output pointer: */
-	*punstable=unstable;
-}
-/*}}}1*/
-/*FUNCTION Riftfront::PreStable {{{1*/
-bool  Riftfront::PreStable(){
-	return prestable;
-}
-/*}}}1*/
-/*FUNCTION Riftfront::SetPreStable {{{1*/
-void Riftfront::SetPreStable(){
-	prestable=1;
-}
-/*}}}1*/
Index: sm/trunk/src/c/objects/Riftfront.h
===================================================================
--- /issm/trunk/src/c/objects/Riftfront.h	(revision 3680)
+++ 	(revision )
@@ -1,85 +1,0 @@
-/*!\file Riftfront.h
- * \brief: header file for riftfront object
- */
-
-#ifndef _RIFTFRONT_H_
-#define _RIFTFRONT_H_
-
-/*Headers:*/
-/*{{{1*/
-#include "./Load.h"
-#include "./Matpar.h"
-#include "./Element.h"
-#include "./Node.h"
-
-#define MAX_RIFTFRONT_GRIDS 2 //max number of grids on a rift flank, only 2 because 2d for now.
-#define RIFTFRONTSTRING 20 //max string length
-
-class Element;
-/*}}}*/
-
-class Riftfront: public Load {
-
-	public:
-		int		id;
-
-		Hook hnodes; //2 nodes
-		Hook helements; //2 elements
-		Hook hmatpar;
-		
-		/*computational: */
-		int      penalty_lock;
-		bool     active;
-		bool     frozen;
-		int      counter;
-		bool     prestable;
-		bool     material_converged;
-		double   normal[2];
-		double   length;
-		double   fraction;
-		
-		Parameters* parameters; //pointer to solution parameters
-		Inputs*  inputs;
-
-
-		/*constructors,destructors: {{{1*/
-		Riftfront();
-		Riftfront(int riftfront_id,int* riftfront_node_ids, int riftfront_matpar_id);
-		Riftfront(int riftfront_id,Hook* riftfront_hnodes, Hook* riftfront_hmatpar, Parameters* parameters, Inputs* riftfront_inputs);
-		Riftfront(int riftfront_id,int i, IoModel* iomodel);
-		~Riftfront();
-		/*}}}*/
-		/*object management: {{{1*/
-		void  Configure(DataSet* elements,DataSet* loads,DataSet* nodes,DataSet* vertices,DataSet* materials,Parameters* parameters);
-		Object* copy();
-		void  DeepEcho();
-		void  Demarshall(char** pmarshalled_dataset);
-		void  Echo();
-		int   Enum();
-		int   Id(); 
-		void  Marshall(char** pmarshalled_dataset);
-		int   MarshallSize();
-		int   MyRank();
-
-		/*}}}*/
-		/*numerics: {{{1*/
-		void  GetDofList(int* doflist,int* pnumberofdofs);
-		void  CreateKMatrix(Mat Kgg,int analysis_type,int sub_analysis_type);
-		void  CreatePVector(Vec pg,  int analysis_type,int sub_analysis_type);
-		void  PenaltyCreateKMatrix(Mat Kgg,double kmax,int analysis_type,int sub_analysis_type);
-		void  PenaltyCreatePVector(Vec pg,double kmax,int analysis_type,int sub_analysis_type);
-		bool  PreStable();
-		void  SetPreStable();
-		int   PreConstrain(int* punstable,  int analysis_type);
-		int   Constrain(int* punstable,  int analysis_type);
-		void  FreezeConstraints( int analysis_type);
-		bool  IsFrozen(void);
-		int   Penetration(double* ppenetration,  int analysis_type);
-		int   MaxPenetration(double* ppenetration,  int analysis_type);
-		int   PotentialUnstableConstraint(int* punstable,  int analysis_type);
-		int   IsMaterialStable( int analysis_type);
-		void  OutputProperties(Vec riftproperties);
-		/*}}}*/
-};
-
-#endif  /* _RIFTFRONT_H_ */
Index: sm/trunk/src/c/objects/Sing.cpp
===================================================================
--- /issm/trunk/src/c/objects/Sing.cpp	(revision 3680)
+++ 	(revision )
@@ -1,541 +1,0 @@
-/*!\file Sing.c
- * \brief: implementation of the Sing object
- */
-
-#ifdef HAVE_CONFIG_H
-	#include "config.h"
-#else
-#error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
-#endif
-
-#include "stdio.h"
-#include "./Sing.h"
-#include "./SingVertexInput.h"
-#include <string.h>
-#include "../EnumDefinitions/EnumDefinitions.h"
-#include "../shared/shared.h"
-#include "../DataSet/DataSet.h"
-#include "../DataSet/Parameters.h"
-#include "../DataSet/Inputs.h"
-#include "../include/typedefs.h"
-#include "../include/macros.h"
-
-/*Object constructors and destructor*/
-/*FUNCTION Sing::Sing(){{{1*/
-Sing::Sing(){
-	this->inputs=NULL;
-	this->parameters=NULL;
-	return;
-}
-/*}}}*/
-/*FUNCTION Sing::Sing(int sing_id,int* sing_node_ids, int sing_matice_id, int sing_matpar_id, int sing_numpar_id) {{{1*/
-Sing::Sing(int sing_id,int* sing_node_ids, int sing_matice_id, int sing_matpar_id):
-	hnodes(sing_node_ids,1),
-	hmatice(&sing_matice_id,1),
-	hmatpar(&sing_matpar_id,1)
-{
-
-	/*all the initialization has been done by the initializer, just fill in the id: */
-	this->id=sing_id;
-	this->parameters=NULL;
-	this->inputs=new Inputs();
-
-	return;
-}
-/*}}}*/
-/*FUNCTION Sing::Sing(int sing_id,Hook* sing_hnodes, Hook* sing_hmatice, Hook* sing_hmatpar, Hook* sing_hnumpar, Inputs* sing_inputs) {{{1*/
-Sing::Sing(int sing_id,Hook* sing_hnodes, Hook* sing_hmatice, Hook* sing_hmatpar, Parameters* sing_parameters,Inputs* sing_inputs):
-	hnodes(sing_hnodes),
-	hmatice(sing_hmatice),
-	hmatpar(sing_hmatpar)
-{
-
-	/*all the initialization has been done by the initializer, just fill in the id: */
-	this->id=sing_id;
-	if(sing_inputs){
-		this->inputs=(Inputs*)sing_inputs->Copy();
-	}
-	else{
-		this->inputs=new Inputs();
-	}
-	/*point parameters: */
-	this->parameters=sing_parameters;
-}
-/*}}}*/
-/*FUNCTION Sing::Sing(int sing_id, int i, IoModel* iomodel) {{{1*/
-Sing::Sing(int sing_id, int i, IoModel* iomodel){
-
-	int sing_matice_id;
-	int sing_matpar_id;
-	
-	int sing_g;
-	double sing_h;
-	double sing_k;
-
-	/*id: */
-	this->id=sing_id;
-
-	/*hooks: */
-	sing_matice_id=i+1;                        //refers to the corresponding material property card
-	sing_matpar_id=iomodel->numberofvertices+1;//refers to the corresponding matpar property card
-	sing_g=i+1;
-
-	this->hnodes.Init(&sing_g,1);
-	this->hmatice.Init(&sing_matice_id,1);
-	this->hmatpar.Init(&sing_matpar_id,1);
-
-	//intialize inputs, and add as many inputs per element as requested: 
-	this->inputs=new Inputs();
-
-	if (iomodel->thickness) this->inputs->AddInput(new SingVertexInput(ThicknessEnum,iomodel->thickness[i]));
-	if (iomodel->drag_coefficient) this->inputs->AddInput(new SingVertexInput(DragCoefficientEnum,iomodel->drag_coefficient[i]));
-
-	//this->parameters: we still can't point to it, it may not even exist. Configure will handle this.
-	this->parameters=NULL;
-
-}
-/*}}}*/
-/*FUNCTION Sing::~Sing(){{{1*/
-Sing::~Sing(){
-	delete inputs;
-	this->parameters=NULL;
-}
-/*}}}*/
-
-/*Object management*/
-/*FUNCTION Sing::Configure {{{1*/
-void  Sing::Configure(DataSet* loadsin, DataSet* nodesin, DataSet* materialsin, Parameters* parametersin){
-
-	int i;
-	
-	/*Take care of hooking up all objects for this element, ie links the objects in the hooks to their respective 
-	 * datasets, using internal ids and offsets hidden in hooks: */
-	hnodes.configure(nodesin);
-	hmatice.configure(materialsin);
-	hmatpar.configure(materialsin);
-
-	/*point parameters to real dataset: */
-	this->parameters=parametersin;
-
-}
-/*}}}*/
-/*FUNCTION Sing::copy {{{1*/
-Object* Sing::copy() {
-	
-	return new Sing(this->id,&this->hnodes,&this->hmatice,&this->hmatpar,this->parameters,this->inputs);
-
-}
-/*}}}*/
-/*FUNCTION Sing::DeepEcho {{{1*/
-void Sing::DeepEcho(void){
-
-	printf("Sing:\n");
-	printf("   id: %i\n",id);
-	hnodes.DeepEcho();
-	hmatice.DeepEcho();
-	hmatpar.DeepEcho();
-	printf("   parameters\n");
-	parameters->DeepEcho();
-	printf("   inputs\n");
-	inputs->DeepEcho();
-
-	return;
-}
-/*}}}*/
-/*FUNCTION Sing::Demarshall {{{1*/
-void  Sing::Demarshall(char** pmarshalled_dataset){
-
-	char* marshalled_dataset=NULL;
-	int   i;
-
-	/*recover marshalled_dataset: */
-	marshalled_dataset=*pmarshalled_dataset;
-
-	/*this time, no need to get enum type, the pointer directly points to the beginning of the 
-	 *object data (thanks to DataSet::Demarshall):*/
-	memcpy(&id,marshalled_dataset,sizeof(id));marshalled_dataset+=sizeof(id);
-
-	/*demarshall hooks: */
-	hnodes.Demarshall(&marshalled_dataset);
-	hmatice.Demarshall(&marshalled_dataset);
-	hmatpar.Demarshall(&marshalled_dataset);
-
-	/*parameters: may not exist even yet, so let Configure handle it: */
-	this->parameters=NULL;
-
-	/*return: */
-	*pmarshalled_dataset=marshalled_dataset;
-	return;
-}
-/*}}}*/
-/*FUNCTION Sing::Echo{{{1*/
-
-void Sing::Echo(void){
-
-	printf("Sing:\n");
-	printf("   id: %i\n",id);
-	hnodes.Echo();
-	hmatice.Echo();
-	hmatpar.Echo();
-	printf("   parameters\n");
-	parameters->Echo();
-	printf("   inputs\n");
-	inputs->Echo();
-}
-/*}}}*/
-/*FUNCTION Sing::Marshall {{{1*/
-void  Sing::Marshall(char** pmarshalled_dataset){
-
-	char* marshalled_dataset=NULL;
-	int   enum_type=0;
-	char* marshalled_inputs=NULL;
-	int   marshalled_inputs_size;
-
-	/*recover marshalled_dataset: */
-	marshalled_dataset=*pmarshalled_dataset;
-
-	/*get enum type of Sing: */
-	enum_type=SingEnum;
-	
-	/*marshall enum: */
-	memcpy(marshalled_dataset,&enum_type,sizeof(enum_type));marshalled_dataset+=sizeof(enum_type);
-	
-	/*marshall Sing data: */
-	memcpy(marshalled_dataset,&id,sizeof(id));marshalled_dataset+=sizeof(id);
-	
-	/*Marshall hooks: */
-	hnodes.Marshall(&marshalled_dataset);
-	hmatice.Marshall(&marshalled_dataset);
-	hmatpar.Marshall(&marshalled_dataset);
-
-	/*Marshall inputs: */
-	marshalled_inputs_size=inputs->MarshallSize();
-	marshalled_inputs=inputs->Marshall();
-	memcpy(marshalled_dataset,marshalled_inputs,marshalled_inputs_size*sizeof(char));
-	marshalled_dataset+=marshalled_inputs_size;
-
-	/*parameters: don't do anything about it. parameters are marshalled somewhere else!*/
-
-	
-	xfree((void**)&marshalled_inputs);
-
-	*pmarshalled_dataset=marshalled_dataset;
-	return;
-}
-/*}}}*/
-/*FUNCTION Sing::MashallSize {{{1*/
-int   Sing::MarshallSize(){
-
-	return sizeof(id)
-		+hnodes.MarshallSize()
-		+hmatice.MarshallSize()
-		+hmatpar.MarshallSize()
-		+sizeof(int); //sizeof(int) for enum type
-}
-/*}}}*/
-/*FUNCTION Sing::UpdateInputs {{{1*/
-void  Sing::UpdateInputs(double* solution, int analysis_type, int sub_analysis_type){
-	ISSMERROR(" not supported yet!");
-}
-/*}}}*/
-		
-/*Object functions*/
-/*FUNCTION Sing::ComputeBasalStress {{{1*/
-void  Sing::ComputeBasalStress(Vec p_g,int analysis_type,int sub_analysis_type){
-
-	ISSMERROR("Not implemented yet");
-
-}
-/*}}}*/
-/*FUNCTION Sing::ComputePressure {{{1*/
-void  Sing::ComputePressure(Vec p_g,int analysis_type,int sub_analysis_type){
-
-	int    dof;
-	double pressure;
-	double thickness;
-	double rho_ice,g;
-
-	/*dynamic objects pointed to by hooks: */
-	Matpar* matpar=NULL;
-	Matice* matice=NULL;
-
-	/*Get dof list on which we will plug the pressure values: */
-	GetDofList1(&dof);
-
-	/*recover objects from hooks: */
-	matpar=(Matpar*)hmatpar.delivers();
-	matice=(Matice*)hmatice.delivers();
-
-	/*pressure is lithostatic: */
-	rho_ice=matpar->GetRhoIce();
-	g=matpar->GetG();
-	inputs->GetParameterValue(&thickness,ThicknessEnum);
-	pressure=rho_ice*g*thickness;
-	
-	/*plug local pressure values into global pressure vector: */
-	VecSetValue(p_g,dof,pressure,INSERT_VALUES);
-
-}
-/*}}}*/
-/*FUNCTION Sing::ComputeStrainRate {{{1*/
-void  Sing::ComputeStrainRate(Vec p_g,int analysis_type,int sub_analysis_type){
-
-	ISSMERROR("Not implemented yet");
-
-}
-/*}}}*/
-/*FUNCTION Sing::CostFunction {{{1*/
-double Sing::CostFunction( int,int){
-	ISSMERROR(" not supported yet!");
-}
-/*}}}*/
-/*FUNCTION Sing::CreateKMatrix {{{1*/
-
-void  Sing::CreateKMatrix(Mat Kgg,int analysis_type,int sub_analysis_type){
-
-	/*Just branch to the correct element stiffness matrix generator, according to the type of analysis we are carrying out: */
-	if ((analysis_type==DiagnosticAnalysisEnum) && (sub_analysis_type==HutterAnalysisEnum)){
-
-		CreateKMatrixDiagnosticHutter( Kgg,analysis_type,sub_analysis_type);
-
-	}
-	else{
-		ISSMERROR("%s%i%s%i%s\n","analysis: ",analysis_type," and sub_analysis_type: ",sub_analysis_type," not supported yet");
-	}
-
-}
-/*}}}*/
-/*FUNCTION Sing::CreateKMatrixDiagnosticHutter {{{1*/
-
-void  Sing::CreateKMatrixDiagnosticHutter(Mat Kgg,int analysis_type,int sub_analysis_type){
-	
-	const int numgrids=1;
-	const int NDOF2=2;
-	const int numdofs=numgrids*NDOF2;
-	double Ke_gg[numdofs][numdofs]={{1,0},{0,1}};
-	int    doflist[numdofs];
-	int    numberofdofspernode;
-
-	GetDofList(&doflist[0],&numberofdofspernode);
-
-	MatSetValues(Kgg,numdofs,doflist,numdofs,doflist,(const double*)Ke_gg,ADD_VALUES);
-
-}
-/*}}}*/
-/*FUNCTION Sing::CreatePVector {{{1*/
-void  Sing::CreatePVector(Vec pg,int analysis_type,int sub_analysis_type){
-	
-	/*Just branch to the correct load generator, according to the type of analysis we are carrying out: */
-	if ((analysis_type==DiagnosticAnalysisEnum) && (sub_analysis_type==HutterAnalysisEnum)){
-	
-			CreatePVectorDiagnosticHutter( pg,analysis_type,sub_analysis_type);
-
-	}
-	else{
-		ISSMERROR("%s%i%s"," analysis ",analysis_type," not supported yet");
-	}
-
-}
-/*}}}*/
-/*FUNCTION Sing::CreatePVectorDiagnosticHutter {{{1*/
-
-void Sing::CreatePVectorDiagnosticHutter( Vec pg,  int analysis_type,int sub_analysis_type){
-	
-	
-	const int numgrids=1;
-	const int NDOF2=2;
-	const int numdofs=NDOF2*numgrids;
-	int       doflist[numdofs];
-	int       dofs[1]={0};
-	int       found=0;
-	double    slope[2];
-	double    slope2;
-	double    pe_g[numdofs]={0,0};
-	double    ub,vb;
-	double    constant_part;
-	int       numberofdofspernode;
-	double    rho_ice,gravity,n,B;
-	double    thickness;
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  node=NULL;
-	Matpar* matpar=NULL;
-	Matice* matice=NULL;
-
-	/*recover objects from hooks: */
-	node=(Node**)hnodes.deliverp();
-	matpar=(Matpar*)hmatpar.delivers();
-	matice=(Matice*)hmatice.delivers();
-
-	inputs->GetParameterValue(&slope[0],SurfaceSlopexEnum);
-	inputs->GetParameterValue(&slope[1],SurfaceSlopeyEnum);
-
-	GetDofList(&doflist[0],&numberofdofspernode);
-
-	//compute slope2 
-	slope2=pow(slope[0],2)+pow(slope[1],2);
-
-	//compute ub
-	rho_ice=matpar->GetRhoIce();
-	gravity=matpar->GetG();
-	n=matice->GetN();
-	B=matice->GetB();
-	inputs->GetParameterValue(&thickness,ThicknessEnum);
-
-	ub=-1.58*pow((double)10.0,(double)-10.0)*rho_ice*gravity*thickness*slope[0];
-	vb=-1.58*pow((double)10.0,(double)-10.0)*rho_ice*gravity*thickness*slope[1];
-
-	//compute constant_part
-	constant_part=-2*pow(rho_ice*gravity,n)*pow(slope2,((n-1)/2));
-
-	pe_g[0]=ub-2.0*pow(rho_ice*gravity,n)*pow(slope2,((n-1)/2.0))*pow(thickness,n)/(pow(B,n)*(n+1))*slope[0];
-	pe_g[1]=vb-2.0*pow(rho_ice*gravity,n)*pow(slope2,((n-1)/2.0))*pow(thickness,n)/(pow(B,n)*(n+1))*slope[1];
-
-	VecSetValues(pg,numdofs,doflist,(const double*)pe_g,ADD_VALUES);
-
-
-}
-/*}}}*/
-/*FUNCTION Sing::Du {{{1*/
-void  Sing::Du(Vec,int,int){
-	ISSMERROR(" not supported yet!");
-}
-/*}}}*/
-/*FUNCTION Sing::Enum {{{1*/
-int Sing::Enum(void){
-
-	return SingEnum;
-
-}
-/*}}}*/
-/*FUNCTION Sing::GetBedList {{{1*/
-void  Sing::GetBedList(double*){
-	ISSMERROR(" not supported yet!");
-}
-/*}}}*/
-/*FUNCTION Sing::GetDofList {{{1*/
-void  Sing::GetDofList(int* doflist,int* pnumberofdofspernode){
-
-	int i;
-	int doflist_per_node[MAXDOFSPERNODE];
-	int numberofdofspernode;
-	
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	
-	nodes[0]->GetDofList(&doflist_per_node[0],&numberofdofspernode);
-	for(i=0;i<numberofdofspernode;i++){
-		doflist[i]=doflist_per_node[i];
-	}
-
-	/*Assign output pointers:*/
-	*pnumberofdofspernode=numberofdofspernode;
-
-}
-/*}}}*/
-/*FUNCTION Sing::GetDofList1 {{{1*/
-void  Sing::GetDofList1(int* doflist){
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	
-	int i;
-	doflist[0]=nodes[0]->GetDofList1();
-
-}
-/*}}}*/
-/*FUNCTION Sing::Id {{{1*/
-int    Sing::Id(void){ return id; }
-/*}}}*/
-/*FUNCTION Sing::GetMatPar {{{1*/
-void* Sing::GetMatPar(){
-
-	/*dynamic objects pointed to by hooks: */
-	Matpar* matpar=NULL;
-
-	/*recover objects from hooks: */
-	matpar=(Matpar*)hmatpar.delivers();
-
-	return matpar;
-}
-/*}}}*/
-/*FUNCTION Sing::GetNodes {{{1*/
-void  Sing::GetNodes(void** vpnodes){
-	
-	Node** pnodes=NULL;
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-	
-	/*recover nodes: */
-	pnodes=(Node**)vpnodes;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	
-	pnodes[0]=nodes[0];
-}
-/*}}}*/
-/*FUNCTION Sing::GetOnBed {{{1*/
-bool   Sing::GetOnBed(){
-	ISSMERROR(" not supported yet!");
-}
-/*}}}*/
-/*FUNCTION Sing::GetShelf {{{1*/
-bool   Sing::GetShelf(){
-	ISSMERROR(" not supported yet!");
-}
-/*}}}*/
-/*FUNCTION Sing::GetThicknessList {{{1*/
-void  Sing::GetThicknessList(double* thickness_list){
-	ISSMERROR(" not supported yet!");
-}
-/*}}}*/
-/*FUNCTION Sing::Gradj {{{1*/
-void  Sing::Gradj(Vec,  int, int ,char*){
-	ISSMERROR(" not supported yet!");
-}
-/*}}}*/
-/*FUNCTION Sing::GradB {{{1*/
-void  Sing::GradjB(Vec,  int,int){
-	ISSMERROR(" not supported yet!");
-}
-/*}}}*/
-/*FUNCTION Sing::GradjDrag {{{1*/
-void  Sing::GradjDrag(Vec,  int,int){
-	ISSMERROR(" not supported yet!");
-}
-/*}}}*/
-/*FUNCTION Sing::MassFlux {{{1*/
-double Sing::MassFlux( double* segment,double* ug){
-	ISSMERROR(" not supported yet!");
-}
-/*}}}*/
-/*FUNCTION Sing::Misfit {{{1*/
-double Sing::Misfit( int,int){
-	ISSMERROR(" not supported yet!");
-}
-/*}}}*/
-/*FUNCTION Sing::MyRank {{{1*/
-int    Sing::MyRank(void){ 
-	extern int my_rank;
-	return my_rank; 
-}
-/*}}}*/
-/*FUNCTION Sing::SurfaceArea {{{1*/
-double Sing::SurfaceArea( int,int){
-	ISSMERROR(" not supported yet!");
-}
-/*}}}*/
-/*FUNCTION Sing::SetClone {{{1*/
-void  Sing::SetClone(int* minranks){
-
-	ISSMERROR("not implemented yet");
-}
-/*}}}1*/
Index: sm/trunk/src/c/objects/Sing.h
===================================================================
--- /issm/trunk/src/c/objects/Sing.h	(revision 3680)
+++ 	(revision )
@@ -1,93 +1,0 @@
-/*!\file: Sing.h
- * \brief prototypes for Sing element
- */ 
-
-#ifndef _SING_H_
-#define  _SING_H_
-
-/*Headers:*/
-/*{{{1*/
-#include "./Element.h"
-#include "./Node.h"
-#include "./Matice.h"
-#include "./Matpar.h"
-#include "../ModelProcessorx/IoModel.h"
-#include "../include/macros.h"
-#include "../shared/Exceptions/exceptions.h"
-#include "./Hook.h"
-#include "../DataSet/Inputs.h"
-#include "../DataSet/DataSet.h"
-#include "../DataSet/Parameters.h"
-/*}}}*/
-
-class Sing: public Element{
-
-	public:
-
-		/*ids:*/
-		int id;
-
-		Hook hnodes;  //hook to 2 nodes
-		Hook hmatice; //hook to 1 matice
-		Hook hmatpar; //hook to 1 matpar
-		
-		Parameters* parameters; //pointer to solution parameters
-		Inputs* inputs;
-
-
-		/*constructors, destructors: {{{1*/
-		Sing();
-		Sing(int sing_id,int* sing_node_ids, int sing_matice_id, int sing_matpar_id);
-		Sing(int sing_id,Hook* sing_hnodes, Hook* sing_hmatice, Hook* sing_hmatpar, Parameters* sing_parameters,Inputs* sing_inputs);
-		Sing(int sing_id, int i, IoModel* iomodel);
-		~Sing();
-		/*}}}*/
-		/*object management: {{{1*/
-		void  Configure(DataSet* loads,DataSet* nodes,DataSet* materials,Parameters* parameters);
-		Object* copy();
-		void  DeepEcho();
-		void  Demarshall(char** pmarshalled_dataset);
-		void  Echo();
-		int   Enum();
-		int   Id(); 
-		void  Marshall(char** pmarshalled_dataset);
-		int   MarshallSize();
-		void  SetClone(int* minranks);
-		int   MyRank();
-		/*}}}*/
-		/*numerics: {{{1*/
-		void  CreateKMatrix(Mat Kgg,int analysis_type,int sub_analysis_type);
-		void  CreatePVector(Vec pg,  int analysis_type,int sub_analysis_type);
-		void  UpdateInputs(double* solution, int analysis_type, int sub_analysis_type);
-		void  GetDofList(int* doflist,int* pnumberofdofs);
-		void  GetDofList1(int* doflist);
-		void  CreateKMatrixDiagnosticHutter(Mat Kgg,int analysis_type,int sub_analysis_type);
-		void  GetParameterValue(double* pp, double* plist, double* gauss_l1l2l3);
-		void  CreatePVectorDiagnosticHutter(Vec pg,int analysis_type,int sub_analysis_type);
-		void* GetMatPar();
-		void  ComputeBasalStress(Vec sigma_b,int analysis_type,int sub_analysis_type);
-		void  ComputePressure(Vec p_g,int analysis_type,int sub_analysis_type);
-		void  ComputeStrainRate(Vec eps,int analysis_type,int sub_analysis_type);
-		void  GetNodes(void** vpnodes);
-		/*}}}*/
-		/*not implemented: {{{1*/
-		bool   GetShelf();
-		bool   GetOnBed();
-		void  GetBedList(double*);
-		void  GetThicknessList(double* thickness_list);
-		void  Du(Vec,int,int);
-		void  Gradj(Vec, int, int,char*);
-		void  GradjDrag(Vec , int,int);
-		void  GradjB(Vec,  int,int);
-		double Misfit(int,int);
-		double SurfaceArea(int,int);
-		double CostFunction(int,int);
-		double MassFlux(double* segment,double* ug);
-		void AddInput(double value, int enum_type){ISSMERROR("not supporte yet!");}
-		/*}}}*/
-
-
-
-};
-#endif //ifndef _SING_H_
-
Index: sm/trunk/src/c/objects/Spc.cpp
===================================================================
--- /issm/trunk/src/c/objects/Spc.cpp	(revision 3680)
+++ 	(revision )
@@ -1,160 +1,0 @@
-/*!\file Spc.c
- * \brief: implementation of the Spc object
- */
-
-
-#ifdef HAVE_CONFIG_H
-	#include "config.h"
-#else
-#error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
-#endif
-
-#include "stdio.h"
-#include <string.h>
-#include "../include/macros.h"
-#include "../shared/shared.h"
-#include "../EnumDefinitions/EnumDefinitions.h"
-#include "../DataSet/DataSet.h"
-#include "./objects.h"
-
-		
-/*Object constructors and destructor*/
-/*FUNCTION Spc::constructor {{{1*/
-Spc::Spc(){
-	return;
-}
-/*}}}1*/
-/*FUNCTION Spc::creation {{{1*/
-Spc::Spc(int spc_sid,int spc_nodeid, int spc_dof,double spc_value){
-
-	sid=spc_sid;
-	nodeid=spc_nodeid;
-	dof=spc_dof;
-	value=spc_value;
-
-	return;
-}
-/*}}}1*/
-/*FUNCTION Spc::destructor {{{1*/
-Spc::~Spc(){
-	return;
-}
-/*}}}1*/
-		
-/*Object marshall*/
-/*FUNCTION Spc::Marshall {{{1*/
-void  Spc::Marshall(char** pmarshalled_dataset){
-
-	char* marshalled_dataset=NULL;
-	int   enum_type=0;
-
-	/*recover marshalled_dataset: */
-	marshalled_dataset=*pmarshalled_dataset;
-
-	/*get enum type of Spc: */
-	enum_type=SpcEnum;
-	
-	/*marshall enum: */
-	memcpy(marshalled_dataset,&enum_type,sizeof(enum_type));marshalled_dataset+=sizeof(enum_type);
-	
-	/*marshall Spc data: */
-	memcpy(marshalled_dataset,&sid,sizeof(sid));marshalled_dataset+=sizeof(sid);
-	memcpy(marshalled_dataset,&nodeid,sizeof(nodeid));marshalled_dataset+=sizeof(nodeid);
-	memcpy(marshalled_dataset,&dof,sizeof(dof));marshalled_dataset+=sizeof(dof);
-	memcpy(marshalled_dataset,&value,sizeof(value));marshalled_dataset+=sizeof(value);
-
-	*pmarshalled_dataset=marshalled_dataset;
-	return;
-}
-/*}}}1*/
-/*FUNCTION Spc::MarshallSize {{{1*/
-int   Spc::MarshallSize(){
-
-	return sizeof(sid)+sizeof(nodeid)+sizeof(dof)+sizeof(value)+sizeof(int); //sizeof(int) for enum type
-}
-/*}}}1*/
-/*FUNCTION Spc::Demarshall {{{1*/
-void  Spc::Demarshall(char** pmarshalled_dataset){
-
-	char* marshalled_dataset=NULL;
-
-	/*recover marshalled_dataset: */
-	marshalled_dataset=*pmarshalled_dataset;
-
-	/*this time, no need to get enum type, the pointer directly points to the beginning of the 
-	 *object data (thanks to DataSet::Demarshall):*/
-
-	memcpy(&sid,marshalled_dataset,sizeof(sid));marshalled_dataset+=sizeof(sid);
-	memcpy(&nodeid,marshalled_dataset,sizeof(nodeid));marshalled_dataset+=sizeof(nodeid);
-	memcpy(&dof,marshalled_dataset,sizeof(dof));marshalled_dataset+=sizeof(dof);
-	memcpy(&value,marshalled_dataset,sizeof(value));marshalled_dataset+=sizeof(value);
-
-	/*return: */
-	*pmarshalled_dataset=marshalled_dataset;
-	return;
-}
-/*}}}1*/
-
-/*Object functions*/
-/*FUNCTION Spc::copy {{{1*/
-Object* Spc::copy() {
-	return new Spc(*this); 
-}
-/*}}}1*/
-/*FUNCTION Spc::DeepEcho {{{1*/
-void Spc::DeepEcho(void){
-
-	printf("Spc:\n");
-	printf("   sid: %i\n",sid);
-	printf("   nodeid: %i\n",nodeid);
-	printf("   dof: %i\n",dof);
-	printf("   value: %g\n",value);
-	return;
-}		
-/*}}}1*/
-/*FUNCTION Spc::DistributeNumDofs {{{1*/
-void  Spc::DistributeNumDofs(int* numdofspernode,int analysis_type){return;}
-/*}}}1*/
-/*FUNCTION Spc::Echo {{{1*/
-void Spc::Echo(void){
-
-	printf("Spc:\n");
-	printf("   sid: %i\n",sid);
-	printf("   nodeid: %i\n",nodeid);
-	printf("   dof: %i\n",dof);
-	printf("   value: %g\n",value);
-	return;
-}
-/*}}}1*/
-/*FUNCTION Spc::Enum {{{1*/
-int Spc::Enum(void){
-
-	return SpcEnum;
-
-}
-/*}}}1*/
-/*FUNCTION Spc::GetDof {{{1*/
-int Spc::GetDof(){
-	return dof;
-}
-/*}}}1*/
-/*FUNCTION Spc::Id {{{1*/
-int    Spc::Id(void){ return sid; }
-/*}}}1*/
-/*FUNCTION Spc::GetNodeId {{{1*/
-int   Spc::GetNodeId(){
-	
-	return nodeid;
-}
-/*}}}1*/
-/*FUNCTION Spc::GetValue {{{1*/
-double Spc::GetValue(){
-	return value;
-}
-/*}}}1*/
-/*FUNCTION Spc::MyRank {{{1*/
-int    Spc::MyRank(void){ 
-	extern int my_rank;
-	return my_rank; 
-}
-/*}}}1*/
Index: sm/trunk/src/c/objects/Spc.h
===================================================================
--- /issm/trunk/src/c/objects/Spc.h	(revision 3680)
+++ 	(revision )
@@ -1,44 +1,0 @@
-/*!\file Spc.h
- * \brief: header file for spc object
- */
-
-#ifndef _SPC_H_
-#define _SPC_H_
-
-/*Headers:*/
-/*{{{1*/
-#include "./Object.h"
-#include "../DataSet/DataSet.h"
-/*}}}*/
-
-class Spc: public Object{
-
-	private: 
-		int	sid; /*! id, to track it*/
-		int	nodeid; /*!node id*/
-		int dof; /*!component*/
-		double value; /*value*/
-
-	public:
-
-		Spc();
-		Spc(int sid,int nodeid, int dof,double value);
-		~Spc();
-
-		void   Echo();
-		void   DeepEcho();
-		void   Marshall(char** pmarshalled_dataset);
-		int    MarshallSize();
-		void   Demarshall(char** pmarshalled_dataset);
-		int    Enum();
-		int    Id(); 
-		int    MyRank();
-		void   DistributeNumDofs(int* numdofspernode,int analysis_type);
-		int    GetNodeId();
-		int    GetDof();
-		double GetValue();
-		Object* copy();
-
-};
-
-#endif  /* _SPC_H_ */
Index: sm/trunk/src/c/objects/Tria.cpp
===================================================================
--- /issm/trunk/src/c/objects/Tria.cpp	(revision 3680)
+++ 	(revision )
@@ -1,5114 +1,0 @@
-/*!\file Tria.c
- * \brief: implementation of the Tria object
- */
-
-/*Headers:*/
-/*{{{1*/
-#ifdef HAVE_CONFIG_H
-	#include "config.h"
-#else
-#error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
-#endif
-
-#include "stdio.h"
-#include "./TriaVertexInput.h"
-#include "./Object.h"
-#include "./Hook.h"
-#include "./Tria.h"
-#include "./Hook.h"
-#include <string.h>
-#include "../EnumDefinitions/EnumDefinitions.h"
-#include "../shared/shared.h"
-#include "../DataSet/DataSet.h"
-#include "../DataSet/Inputs.h"
-#include "../include/typedefs.h"
-#include "../include/macros.h"
-/*}}}*/
-
-/*Object constructors and destructor*/
-/*FUNCTION Tria::Tria(){{{1*/
-Tria::Tria(){
-	this->inputs=NULL;
-	this->parameters=NULL;
-}
-/*}}}*/
-/*FUNCTION Tria::Tria(int id, int* node_ids, int matice_id, int matpar_id){{{1*/
-Tria::Tria(int tria_id,int* tria_node_ids, int tria_matice_id, int tria_matpar_id): 
-	hnodes(tria_node_ids,3),
-	hmatice(&tria_matice_id,1),
-	hmatpar(&tria_matpar_id,1)
-{
-
-	/*all the initialization has been done by the initializer, just fill in the id: */
-	this->id=tria_id;
-	this->parameters=NULL;
-	this->inputs=new Inputs();
-
-}
-/*}}}*/
-/*FUNCTION Tria::Tria(int id, Hook* hnodes, Hook* hmatice, Hook* hmatpar, Parameters* parameters, Inputs* tria_inputs) {{{1*/
-Tria::Tria(int tria_id,Hook* tria_hnodes, Hook* tria_hmatice, Hook* tria_hmatpar, Parameters* tria_parameters, Inputs* tria_inputs):
-	hnodes(tria_hnodes),
-	hmatice(tria_hmatice),
-	hmatpar(tria_hmatpar)
-{
-
-	/*all the initialization has been done by the initializer, just fill in the id: */
-	this->id=tria_id;
-	if(tria_inputs){
-		this->inputs=(Inputs*)tria_inputs->Copy();
-	}
-	else{
-		this->inputs=new Inputs();
-	}
-	/*point parameters: */
-	this->parameters=tria_parameters;
-}
-/*}}}*/
-/*FUNCTION Tria::Tria(int id, int index, IoModel* iomodel){{{1*/
-Tria::Tria(int tria_id, int index, IoModel* iomodel){ //i is the element index
-
-	int    i;
-	int    j;
-	int    tria_node_ids[3];
-	int    tria_matice_id;
-	int    tria_matpar_id;
-	double nodeinputs[3];
-
-	/*id: */
-	this->id=tria_id;
-	
-	/*hooks: */
-	//go recover node ids, needed to initialize the node hook.
-	if (iomodel->analysis_type==Prognostic2AnalysisEnum || iomodel->analysis_type==Balancedthickness2AnalysisEnum){
-		/*Discontinuous Galerkin*/
-		tria_node_ids[0]=3*index+1;
-		tria_node_ids[1]=3*index+2;
-		tria_node_ids[2]=3*index+3;
-	}
-	else{
-		/*Continuous Galerkin*/
-		for(i=0;i<3;i++){ 
-			tria_node_ids[i]=(int)*(iomodel->elements+3*index+i); //ids for vertices are in the elements array from Matlab
-		}
-	}
-	tria_matice_id=index+1; //refers to the corresponding ice material object
-	tria_matpar_id=iomodel->numberofelements+1; //refers to the constant material parameters object
-
-	this->hnodes.Init(tria_node_ids,3);
-	this->hmatice.Init(&tria_matice_id,1);
-	this->hmatpar.Init(&tria_matpar_id,1);
-
-	//intialize inputs, and add as many inputs per element as requested: 
-	this->inputs=new Inputs();
-	
-	if (iomodel->thickness) {
-		for(i=0;i<3;i++)nodeinputs[i]=iomodel->thickness[tria_node_ids[i]-1];
-		this->inputs->AddInput(new TriaVertexInput(ThicknessEnum,nodeinputs));
-	}
-	if (iomodel->surface) {
-		for(i=0;i<3;i++)nodeinputs[i]=iomodel->surface[tria_node_ids[i]-1];
-		this->inputs->AddInput(new TriaVertexInput(SurfaceEnum,nodeinputs));
-	}
-	if (iomodel->bed) {
-		for(i=0;i<3;i++)nodeinputs[i]=iomodel->bed[tria_node_ids[i]-1];
-		this->inputs->AddInput(new TriaVertexInput(BedEnum,nodeinputs));
-	}
-	if (iomodel->drag_coefficient) {
-		for(i=0;i<3;i++)nodeinputs[i]=iomodel->drag_coefficient[tria_node_ids[i]-1];
-		this->inputs->AddInput(new TriaVertexInput(DragCoefficientEnum,nodeinputs));
-
-		if (iomodel->drag_p) this->inputs->AddInput(new DoubleInput(DragPEnum,iomodel->drag_p[index]));
-		if (iomodel->drag_q) this->inputs->AddInput(new DoubleInput(DragQEnum,iomodel->drag_q[index]));
-		this->inputs->AddInput(new IntInput(DragTypeEnum,iomodel->drag_type));
-
-	}
-	if (iomodel->melting_rate) {
-		for(i=0;i<3;i++)nodeinputs[i]=iomodel->melting_rate[tria_node_ids[i]-1];
-		this->inputs->AddInput(new TriaVertexInput(MeltingRateEnum,nodeinputs));
-	}
-	if (iomodel->accumulation_rate) {
-		for(i=0;i<3;i++)nodeinputs[i]=iomodel->accumulation_rate[tria_node_ids[i]-1];
-		this->inputs->AddInput(new TriaVertexInput(AccumulationRateEnum,nodeinputs));
-	}
-	if (iomodel->geothermalflux) {
-		for(i=0;i<3;i++)nodeinputs[i]=iomodel->geothermalflux[tria_node_ids[i]-1];
-		this->inputs->AddInput(new TriaVertexInput(GeothermalFluxEnum,nodeinputs));
-	}	
-
-	if (iomodel->elementoniceshelf) this->inputs->AddInput(new BoolInput(ElementOnIceShelfEnum,(IssmBool)iomodel->elementoniceshelf[index]));
-	if (iomodel->elementonbed) this->inputs->AddInput(new BoolInput(ElementOnBedEnum,(IssmBool)iomodel->elementonbed[index]));
-	if (iomodel->elementonwater) this->inputs->AddInput(new BoolInput(ElementOnWaterEnum,(IssmBool)iomodel->elementonwater[index]));
-	if (iomodel->elementonsurface) this->inputs->AddInput(new BoolInput(ElementOnSurfaceEnum,(IssmBool)iomodel->elementonsurface[index]));
-
-	//this->parameters: we still can't point to it, it may not even exist. Configure will handle this.
-	this->parameters=NULL;
-
-
-}
-/*}}}*/
-/*FUNCTION Tria::~Tria(){{{1*/
-Tria::~Tria(){
-	delete inputs;
-	this->parameters=NULL;
-}
-/*}}}*/
-
-/*Object management: */
-/*FUNCTION Tria::Configure {{{1*/
-void  Tria::Configure(DataSet* loadsin, DataSet* nodesin, DataSet* materialsin, Parameters* parametersin){
-
-	/*Take care of hooking up all objects for this element, ie links the objects in the hooks to their respective 
-	 * datasets, using internal ids and offsets hidden in hooks: */
-	hnodes.configure(nodesin);
-	hmatice.configure(materialsin);
-	hmatpar.configure(materialsin);
-
-	/*point parameters to real dataset: */
-	this->parameters=parametersin;
-
-}
-/*}}}*/
-/*FUNCTION Tria::copy {{{1*/
-Object* Tria::copy() {
-
-	return new Tria(this->id,&this->hnodes,&this->hmatice,&this->hmatpar,this->parameters,this->inputs);
-
-}
-
-/*}}}*/
-/*FUNCTION Tria::Demarshall {{{1*/
-void  Tria::Demarshall(char** pmarshalled_dataset){
-
-	char* marshalled_dataset=NULL;
-	int   i;
-
-	/*recover marshalled_dataset: */
-	marshalled_dataset=*pmarshalled_dataset;
-
-	/*this time, no need to get enum type, the pointer directly points to the beginning of the 
-	 *object data (thanks to DataSet::Demarshall):*/
-
-	memcpy(&id,marshalled_dataset,sizeof(id));marshalled_dataset+=sizeof(id);
-
-	/*demarshall hooks: */
-	hnodes.Demarshall(&marshalled_dataset);
-	hmatice.Demarshall(&marshalled_dataset);
-	hmatpar.Demarshall(&marshalled_dataset);
-	
-	/*demarshall inputs: */
-	inputs=(Inputs*)DataSetDemarshallRaw(&marshalled_dataset); 
-
-	/*parameters: may not exist even yet, so let Configure handle it: */
-	this->parameters=NULL;
-
-	/*return: */
-	*pmarshalled_dataset=marshalled_dataset;
-	return;
-}
-/*}}}*/
-/*FUNCTION Tria::DeepEcho{{{1*/
-
-void Tria::DeepEcho(void){
-
-	printf("Tria:\n");
-	printf("   id: %i\n",id);
-	hnodes.DeepEcho();
-	hmatice.DeepEcho();
-	hmatpar.DeepEcho();
-	printf("   parameters\n");
-	parameters->DeepEcho();
-	printf("   inputs\n");
-	inputs->DeepEcho();
-	
-	return;
-}
-/*}}}*/
-/*FUNCTION Tria::Echo{{{1*/
-
-void Tria::Echo(void){
-
-	printf("Tria:\n");
-	printf("   id: %i\n",id);
-	hnodes.Echo();
-	hmatice.Echo();
-	hmatpar.Echo();
-	printf("   parameters\n");
-	parameters->Echo();
-	printf("   inputs\n");
-	inputs->Echo();
-}
-/*}}}*/
-/*FUNCTION Tria::Marshall {{{1*/
-void  Tria::Marshall(char** pmarshalled_dataset){
-
-	char* marshalled_dataset=NULL;
-	int   enum_type=0;
-	char* marshalled_inputs=NULL;
-	int   marshalled_inputs_size;
-
-	/*recover marshalled_dataset: */
-	marshalled_dataset=*pmarshalled_dataset;
-
-	/*get enum type of Tria: */
-	enum_type=TriaEnum;
-
-	/*marshall enum: */
-	memcpy(marshalled_dataset,&enum_type,sizeof(enum_type));marshalled_dataset+=sizeof(enum_type);
-
-	/*marshall Tria data: */
-	memcpy(marshalled_dataset,&id,sizeof(id));marshalled_dataset+=sizeof(id);
-
-	/*Marshall hooks: */
-	hnodes.Marshall(&marshalled_dataset);
-	hmatice.Marshall(&marshalled_dataset);
-	hmatpar.Marshall(&marshalled_dataset);
-
-	/*Marshall inputs: */
-	marshalled_inputs_size=inputs->MarshallSize();
-	marshalled_inputs=inputs->Marshall();
-	memcpy(marshalled_dataset,marshalled_inputs,marshalled_inputs_size*sizeof(char));
-	marshalled_dataset+=marshalled_inputs_size;
-
-	/*parameters: don't do anything about it. parameters are marshalled somewhere else!*/
-
-	xfree((void**)&marshalled_inputs);
-
-	*pmarshalled_dataset=marshalled_dataset;
-	return;
-}
-/*}}}*/
-/*FUNCTION Tria::MarshallSize {{{1*/
-int   Tria::MarshallSize(){
-	
-	return sizeof(id)
-		+hnodes.MarshallSize()
-		+hmatice.MarshallSize()
-		+hmatpar.MarshallSize()
-		+inputs->MarshallSize()
-		+sizeof(int); //sizeof(int) for enum type
-}
-/*}}}*/
-
-/*Updates: */
-/*FUNCTION Tria::UpdateFromDakota {{{1*/
-void  Tria::UpdateFromDakota(void* vinputs){
-
-	int     i;
-	int     dofs[1]={0};
-	double  temperature_list[3];
-	double  temperature_average;
-	double  B_list[3];
-	double  B_average;
-	double  new_h[3];
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-	Matpar* matpar=NULL;
-	Matice* matice=NULL;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	matpar=(Matpar*)hmatpar.delivers();
-	matice=(Matice*)hmatice.delivers();
-
-	/*Update internal data if inputs holds new values: */
-	/*inputs->Recover("thickness",&this->properties.h[0],1,dofs,3,(void**)nodes);
-	if(inputs->Recover("thickness",&new_h[0],1,dofs,3,(void**)nodes)){
-	//density, needed later:
-	double di=(this->matpar->GetRhoIce()/this->matpar->GetRhoWater());
-	//Go through grids:
-	for (i=0;i<3;i++){
-	if(nodes[i]->IsOnShelf()){
-	this->b[i]=this->b[i]-di*(new_h[i]-h[i]); //hydrostatic equilibrium;
-	}
-	this->s[i]=this->b[i]+new_h[i];
-	this->h[i]=new_h[i];
-	}
-	}*/
-
-	ISSMERROR("not supported yet!");
-
-}
-/*}}}*/
-/*FUNCTION Tria::UpdateInputs {{{1*/
-void  Tria::UpdateInputs(double* solution, int analysis_type, int sub_analysis_type){
-
-	/*Just branch to the correct UpdateInputs generator, according to the type of analysis we are carrying out: */
-	if (analysis_type==ControlAnalysisEnum){
-		
-		UpdateInputsDiagnosticHoriz( solution,analysis_type,sub_analysis_type);
-	}
-	else if (analysis_type==DiagnosticAnalysisEnum){
-	
-		if (sub_analysis_type==HorizAnalysisEnum){
-
-			UpdateInputsDiagnosticHoriz( solution,analysis_type,sub_analysis_type);
-		}
-		else ISSMERROR("%s%i%s\n","sub_analysis: ",sub_analysis_type," not supported yet");
-
-	}
-	else if (analysis_type==SlopecomputeAnalysisEnum){
-
-		UpdateInputsSlopeCompute( solution,analysis_type,sub_analysis_type);
-	}
-	else if (analysis_type==PrognosticAnalysisEnum){
-
-		UpdateInputsPrognostic( solution,analysis_type,sub_analysis_type);
-	}
-	else if (analysis_type==Prognostic2AnalysisEnum){
-
-		UpdateInputsPrognostic2(solution,analysis_type,sub_analysis_type);
-	}
-	else if (analysis_type==BalancedthicknessAnalysisEnum){
-
-		UpdateInputsBalancedthickness( solution,analysis_type,sub_analysis_type);
-	}
-	else if (analysis_type==Balancedthickness2AnalysisEnum){
-
-		UpdateInputsBalancedthickness2( solution,analysis_type,sub_analysis_type);
-	}
-	else if (analysis_type==BalancedvelocitiesAnalysisEnum){
-
-		UpdateInputsBalancedvelocities( solution,analysis_type,sub_analysis_type);
-	}
-	else{
-
-		ISSMERROR("%s%i%s\n","analysis: ",analysis_type," not supported yet");
-	}
-}
-/*}}}*/
-/*FUNCTION Tria::UpdateInputsDiagnosticHoriz {{{1*/
-void  Tria::UpdateInputsDiagnosticHoriz(double* solution, int analysis_type, int sub_analysis_type){
-	
-	
-	int i;
-
-	const int    numvertices=3;
-	const int    numdofpervertex=2;
-	const int    numdof=numdofpervertex*numvertices;
-	
-	int          doflist[numdof];
-	double       values[numdof];
-	double       vx[numvertices];
-	double       vy[numvertices];
-
-	int          dummy;
-	
-	/*Get dof list: */
-	GetDofList(&doflist[0],&dummy);
-
-	/*Use the dof list to index into the solution vector: */
-	for(i=0;i<numdof;i++){
-		values[i]=solution[doflist[i]];
-	}
-
-	/*Ok, we have vx and vy in values, fill in vx and vy arrays: */
-	for(i=0;i<numvertices;i++){
-		vx[i]=values[i*numdofpervertex+0];
-		vy[i]=values[i*numdofpervertex+1];
-	}
-
-	/*Add vx and vy as inputs to the tria element: */
-	this->inputs->AddInput(new TriaVertexInput(VxEnum,vx));
-	this->inputs->AddInput(new TriaVertexInput(VyEnum,vy));
-}
-
-/*}}}*/
-/*FUNCTION Tria::UpdateInputsSlopeCompute {{{1*/
-void  Tria::UpdateInputsSlopeCompute(double* solution, int analysis_type, int sub_analysis_type){
-	ISSMERROR(" not supported yet!");
-}
-/*}}}*/
-/*FUNCTION Tria::UpdateInputsPrognostic {{{1*/
-void  Tria::UpdateInputsPrognostic(double* solution, int analysis_type, int sub_analysis_type){
-	ISSMERROR(" not supported yet!");
-}
-/*}}}*/
-/*FUNCTION Tria::UpdateInputsPrognostic2 {{{1*/
-void  Tria::UpdateInputsPrognostic2(double* solution, int analysis_type, int sub_analysis_type){
-	ISSMERROR(" not supported yet!");
-}
-/*}}}*/
-/*FUNCTION Tria::UpdateInputsBalancedthickness {{{1*/
-void  Tria::UpdateInputsBalancedthickness(double* solution, int analysis_type, int sub_analysis_type){
-	ISSMERROR(" not supported yet!");
-}
-/*}}}*/
-/*FUNCTION Tria::UpdateInputsBalancedthickness2 {{{1*/
-void  Tria::UpdateInputsBalancedthickness2(double* solution, int analysis_type, int sub_analysis_type){
-	ISSMERROR(" not supported yet!");
-}
-/*}}}*/
-/*FUNCTION Tria::UpdateInputsBalancedvelocities {{{1*/
-void  Tria::UpdateInputsBalancedvelocities(double* solution, int analysis_type, int sub_analysis_type){
-	ISSMERROR(" not supported yet!");
-}
-/*}}}*/
-
-/*Object functions*/
-/*FUNCTION Tria::ComputeBasalStress {{{1*/
-void  Tria::ComputeBasalStress(Vec eps,int analysis_type,int sub_analysis_type){
-
-	int i;
-	const int numgrids=3;
-	int doflist[numgrids];
-	double value;
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-	Matpar* matpar=NULL;
-	Matice* matice=NULL;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	matpar=(Matpar*)hmatpar.delivers();
-	matice=(Matice*)hmatice.delivers();
-
-	/*plug local pressure values into global pressure vector: */
-	ISSMERROR("Not Implemented yet");
-	//VecSetValues(eps,1,2,(const double*)&value,INSERT_VALUES);
-
-}
-/*}}}*/
-/*FUNCTION Tria::ComputePressure {{{1*/
-void  Tria::ComputePressure(Vec pg,int analysis_type,int sub_analysis_type){
-
-	int i;
-	const int numvertices=3;
-	int doflist[numvertices];
-	double pressure[numvertices];
-	double thickness[numvertices];
-	double rho_ice,g;
-	double gauss[numvertices][numvertices]={{1,0,0},{0,1,0},{0,0,1}};
-	
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-	Matpar* matpar=NULL;
-	Matice* matice=NULL;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	matpar=(Matpar*)hmatpar.delivers();
-	matice=(Matice*)hmatice.delivers();
-
-	/*Get dof list on which we will plug the pressure values: */
-	GetDofList1(&doflist[0]);
-
-	/*pressure is lithostatic: */
-	rho_ice=matpar->GetRhoIce();
-	g=matpar->GetG();
-
-	/*recover value of thickness at gauss points (0,0,1), (0,1,0),(1,0,0): */
-	inputs->GetParameterValues(&thickness[0],&gauss[0][0],3,ThicknessEnum);
-
-	for(i=0;i<numvertices;i++){
-		pressure[i]=rho_ice*g*thickness[i];
-	}
-
-	/*plug local pressure values into global pressure vector: */
-	VecSetValues(pg,numvertices,doflist,(const double*)pressure,INSERT_VALUES);
-
-}
-/*}}}*/
-/*FUNCTION Tria::ComputeStrainRate {{{1*/
-void  Tria::ComputeStrainRate(Vec eps,int analysis_type,int sub_analysis_type){
-
-	int i;
-	const int numgrids=3;
-	int doflist[numgrids];
-	double value;
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=   NULL;
-	Matpar* matpar    =NULL;
-	Matice* matice= NULL;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	matpar=(Matpar*)hmatpar.delivers();
-	matice=(Matice*)hmatice.delivers();
-
-	/*plug local pressure values into global pressure vector: */
-	ISSMERROR("Not Implemented yet");
-	//VecSetValues(eps,1,2,(const double*)&value,INSERT_VALUES);
-
-}
-/*}}}*/
-/*FUNCTION Tria::CostFunction {{{1*/
-double Tria::CostFunction(int analysis_type,int sub_analysis_type){
-
-	int i;
-
-	/* output: */
-	double Jelem;
-
-	/* node data: */
-	const int    numgrids=3;
-	const int    numdof=2*numgrids;
-	const int    NDOF2=2;
-	int          dofs1[1]={0};
-	int          dofs2[2]={0,1};
-	double       xyz_list[numgrids][3];
-
-	/* grid data: */
-	double B[numgrids];
-
-	/* gaussian points: */
-	int     num_gauss,ig;
-	double* first_gauss_area_coord  =  NULL;
-	double* second_gauss_area_coord =  NULL;
-	double* third_gauss_area_coord  =  NULL;
-	double* gauss_weights           =  NULL;
-	double  gauss_weight;
-	double  gauss_l1l2l3[3];
-	double  k_gauss;
-	double  B_gauss;
-
-	/* parameters: */
-	double  dk[NDOF2]; 
-	double  dB[NDOF2]; 
-	char*   control_type=NULL;
-	double  cm_noisedmp;
-
-	/* Jacobian: */
-	double Jdet;
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-	Matpar* matpar=NULL;
-	Matice* matice=NULL;
-
-	/*inputs: */
-	bool onwater;
-	bool shelf;
-
-	/*retrieve inputs :*/
-	inputs->GetParameterValue(&onwater,ElementOnWaterEnum);
-	inputs->GetParameterValue(&shelf,ElementOnIceShelfEnum);
-
-	/*If on water, return 0: */
-	if(onwater)return 0;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	matpar=(Matpar*)hmatpar.delivers();
-	matice=(Matice*)hmatice.delivers();
-
-	/*retrieve some parameters: */
-	this->parameters->FindParam(&control_type,ControlTypeEnum);
-	this->parameters->FindParam(&cm_noisedmp,CmNoiseDmpEnum);
-
-	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
-
-	/*First, get Misfit*/
-	Jelem=Misfit(analysis_type,sub_analysis_type);
-
-	  /* Get gaussian points and weights (make this a statically initialized list of points? fstd): */
-	  GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2);
-
-	/* Start  looping on the number of gaussian points: */
-	for (ig=0; ig<num_gauss; ig++){
-		/*Pick up the gaussian point: */
-		gauss_weight=*(gauss_weights+ig);
-		gauss_l1l2l3[0]=*(first_gauss_area_coord+ig); 
-		gauss_l1l2l3[1]=*(second_gauss_area_coord+ig);
-		gauss_l1l2l3[2]=*(third_gauss_area_coord+ig);
-
-		/* Get Jacobian determinant: */
-		GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss_l1l2l3);
-
-		/*Add Tikhonov regularization term to misfit*/
-		if (strcmp(control_type,"drag")==0){
-			if (shelf){
-				inputs->GetParameterDerivativeValue(&dk[0],&xyz_list[0][0],&gauss_l1l2l3[0],DragCoefficientEnum);
-				Jelem+=cm_noisedmp*1/2*(pow(dk[0],2)+pow(dk[1],2))*Jdet*gauss_weight;
-
-			}
-		}
-		else if (strcmp(control_type,"B")==0){
-			inputs->GetParameterDerivativeValue(&dB[0], &xyz_list[0][0], &gauss_l1l2l3[0],RheologyBEnum);
-			Jelem+=cm_noisedmp*1/2*(pow(dB[0],2)+pow(dB[1],2))*Jdet*gauss_weight;
-		}
-		else{
-			ISSMERROR("%s%s","unsupported control type: ",control_type);
-		}
-
-	}
-
-	xfree((void**)&first_gauss_area_coord);
-	xfree((void**)&second_gauss_area_coord);
-	xfree((void**)&third_gauss_area_coord);
-	xfree((void**)&gauss_weights);
-	xfree((void**)&control_type);
-
-	/*Return: */
-	return Jelem;
-}
-/*}}}*/
-/*FUNCTION Tria::CreateKMatrix {{{1*/
-
-void  Tria::CreateKMatrix(Mat Kgg,int analysis_type,int sub_analysis_type){
-
-	/*Just branch to the correct element stiffness matrix generator, according to the type of analysis we are carrying out: */
-	if (analysis_type==ControlAnalysisEnum){
-		
-		CreateKMatrixDiagnosticHoriz( Kgg,analysis_type,sub_analysis_type);
-	}
-	else if (analysis_type==DiagnosticAnalysisEnum){
-	
-		if (sub_analysis_type==HorizAnalysisEnum){
-
-			CreateKMatrixDiagnosticHoriz( Kgg,analysis_type,sub_analysis_type);
-		}
-		else ISSMERROR("%s%i%s\n","sub_analysis: ",sub_analysis_type," not supported yet");
-
-	}
-	else if (analysis_type==SlopecomputeAnalysisEnum){
-
-		CreateKMatrixSlopeCompute( Kgg,analysis_type,sub_analysis_type);
-	}
-	else if (analysis_type==PrognosticAnalysisEnum){
-
-		CreateKMatrixPrognostic( Kgg,analysis_type,sub_analysis_type);
-	}
-	else if (analysis_type==Prognostic2AnalysisEnum){
-
-		CreateKMatrixPrognostic2(Kgg,analysis_type,sub_analysis_type);
-	}
-	else if (analysis_type==BalancedthicknessAnalysisEnum){
-
-		CreateKMatrixBalancedthickness( Kgg,analysis_type,sub_analysis_type);
-	}
-	else if (analysis_type==Balancedthickness2AnalysisEnum){
-
-		CreateKMatrixBalancedthickness2( Kgg,analysis_type,sub_analysis_type);
-	}
-	else if (analysis_type==BalancedvelocitiesAnalysisEnum){
-
-		CreateKMatrixBalancedvelocities( Kgg,analysis_type,sub_analysis_type);
-	}
-	else{
-
-		ISSMERROR("%s%i%s\n","analysis: ",analysis_type," not supported yet");
-	}
-
-}
-/*}}}*/
-/*FUNCTION Tria::CreateKMatrixBalancedthickness {{{1*/
-void  Tria::CreateKMatrixBalancedthickness(Mat Kgg,int analysis_type,int sub_analysis_type){
-
-	/* local declarations */
-	int             i,j;
-
-	/* node data: */
-	const int    numgrids=3;
-	const int    NDOF1=1;
-	const int    numdof=NDOF1*numgrids;
-	double       xyz_list[numgrids][3];
-	int          doflist[numdof];
-	int          numberofdofspernode;
-
-	/* gaussian points: */
-	int     num_gauss,ig;
-	double* first_gauss_area_coord  =  NULL;
-	double* second_gauss_area_coord =  NULL;
-	double* third_gauss_area_coord  =  NULL;
-	double* gauss_weights           =  NULL;
-	double  gauss_weight;
-	double  gauss_l1l2l3[3];
-	double  gaussgrids[numgrids][numgrids]={{1,0,0},{0,1,0},{0,0,1}};
-
-	/* matrices: */
-	double L[numgrids];
-	double B[2][numgrids];
-	double Bprime[2][numgrids];
-	double DL[2][2]={0.0};
-	double DLprime[2][2]={0.0};
-	double DL_scalar;
-	double Ke_gg[numdof][numdof]={0.0};//local element stiffness matrix 
-	double Ke_gg_gaussian[numdof][numdof]={0.0}; //stiffness matrix evaluated at the gaussian point.
-	double Ke_gg_thickness1[numdof][numdof]={0.0}; //stiffness matrix evaluated at the gaussian point.
-	double Ke_gg_thickness2[numdof][numdof]={0.0}; //stiffness matrix evaluated at the gaussian point.
-
-	double Jdettria;
-
-	/*input parameters for structural analysis (diagnostic): */
-	double  vx_list[numgrids];
-	double  vy_list[numgrids];
-	double  dvx[2];
-	double  dvy[2];
-	double  vx,vy;
-	double  dvxdx,dvydy;
-	double  v_gauss[2]={0.0};
-
-
-	double  K[2][2]={0.0};
-	double  KDL[2][2]={0.0};
-	int     dofs[2]={0,1};
-	int     found=0;
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-	Matpar* matpar=NULL;
-	Matice* matice=NULL;
-
-	/*parameters: */
-	double artdiff;
-
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	matpar=(Matpar*)hmatpar.delivers();
-	matice=(Matice*)hmatice.delivers();
-
-	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
-	GetDofList(&doflist[0],&numberofdofspernode);
-
-	/*Recover velocity: */
-	inputs->GetParameterValues(&vx_list[0],&gaussgrids[0][0],3,VxAverageEnum);
-	inputs->GetParameterValues(&vy_list[0],&gaussgrids[0][0],3,VyAverageEnum);
-
-	/*retrieve some parameters: */
-	this->parameters->FindParam(&artdiff,ArtDiffEnum);
-
-	//Create Artificial diffusivity once for all if requested
-	if(artdiff){
-		//Get the Jacobian determinant
-		gauss_l1l2l3[0]=ONETHIRD; gauss_l1l2l3[1]=ONETHIRD; gauss_l1l2l3[2]=ONETHIRD;
-		GetJacobianDeterminant2d(&Jdettria, &xyz_list[0][0],gauss_l1l2l3);
-
-		//Build K matrix (artificial diffusivity matrix)
-		v_gauss[0]=ONETHIRD*(vx_list[0]+vx_list[1]+vx_list[2]);
-		v_gauss[1]=ONETHIRD*(vy_list[0]+vy_list[1]+vy_list[2]);
-
-		K[0][0]=pow(Jdettria,(double).5)/2.0*fabs(v_gauss[0]);
-		K[1][1]=pow(Jdettria,(double).5)/2.0*fabs(v_gauss[1]);
-	}
-
-	/* Get gaussian points and weights (make this a statically initialized list of points? fstd): */
-	GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2);
-
-	/* Start  looping on the number of gaussian points: */
-	for (ig=0; ig<num_gauss; ig++){
-		/*Pick up the gaussian point: */
-		gauss_weight=*(gauss_weights+ig);
-		gauss_l1l2l3[0]=*(first_gauss_area_coord+ig); 
-		gauss_l1l2l3[1]=*(second_gauss_area_coord+ig);
-		gauss_l1l2l3[2]=*(third_gauss_area_coord+ig);
-
-		/* Get Jacobian determinant: */
-		GetJacobianDeterminant2d(&Jdettria, &xyz_list[0][0],gauss_l1l2l3);
-
-		/*Get B  and B prime matrix: */
-		GetB_prog(&B[0][0], &xyz_list[0][0], gauss_l1l2l3);
-		GetBPrime_prog(&Bprime[0][0], &xyz_list[0][0], gauss_l1l2l3);
-
-		//Get vx, vy and their derivatives at gauss point
-		this->GetParameterValue(&vx, &vx_list[0],gauss_l1l2l3);
-		this->GetParameterValue(&vy, &vy_list[0],gauss_l1l2l3);
-
-		this->GetParameterDerivativeValue(&dvx[0], &vx_list[0],&xyz_list[0][0], gauss_l1l2l3);
-		this->GetParameterDerivativeValue(&dvy[0], &vy_list[0],&xyz_list[0][0], gauss_l1l2l3);
-
-		dvxdx=dvx[0];
-		dvydy=dvy[1];
-
-		DL_scalar=gauss_weight*Jdettria;
-
-		//Create DL and DLprime matrix
-		DL[0][0]=DL_scalar*dvxdx;
-		DL[1][1]=DL_scalar*dvydy;
-
-		DLprime[0][0]=DL_scalar*vx;
-		DLprime[1][1]=DL_scalar*vy;
-
-		//Do the triple product tL*D*L. 
-		//Ke_gg_thickness=B'*DLprime*Bprime;
-
-		TripleMultiply( &B[0][0],2,numdof,1,
-					&DL[0][0],2,2,0,
-					&B[0][0],2,numdof,0,
-					&Ke_gg_thickness1[0][0],0);
-
-		TripleMultiply( &B[0][0],2,numdof,1,
-					&DLprime[0][0],2,2,0,
-					&Bprime[0][0],2,numdof,0,
-					&Ke_gg_thickness2[0][0],0);
-
-		/* Add the Ke_gg_gaussian, and optionally Ke_gg_drag_gaussian onto Ke_gg: */
-		for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg_thickness1[i][j];
-		for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg_thickness2[i][j];
-
-		if(artdiff){
-
-			/* Compute artificial diffusivity */
-			KDL[0][0]=DL_scalar*K[0][0];
-			KDL[1][1]=DL_scalar*K[1][1];
-
-			TripleMultiply( &Bprime[0][0],2,numdof,1,
-						&KDL[0][0],2,2,0,
-						&Bprime[0][0],2,numdof,0,
-						&Ke_gg_gaussian[0][0],0);
-
-			/* Add artificial diffusivity matrix */
-			for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg_gaussian[i][j];
-
-		}
-	} // for (ig=0; ig<num_gauss; ig++)
-
-	/*Add Ke_gg to global matrix Kgg: */
-	MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)Ke_gg,ADD_VALUES);
-
-cleanup_and_return: 
-	xfree((void**)&first_gauss_area_coord);
-	xfree((void**)&second_gauss_area_coord);
-	xfree((void**)&third_gauss_area_coord);
-	xfree((void**)&gauss_weights);
-
-}
-/*}}}*/
-/*FUNCTION Tria::CreateKMatrixBalancedthickness2 {{{1*/
-void  Tria::CreateKMatrixBalancedthickness2(Mat Kgg,int analysis_type,int sub_analysis_type){
-
-	/* local declarations */
-	int             i,j;
-
-	/* node data: */
-	const int    numgrids=3;
-	const int    NDOF1=1;
-	const int    numdof=NDOF1*numgrids;
-	double       xyz_list[numgrids][3];
-	int          doflist[numdof];
-	int          numberofdofspernode;
-
-	/* gaussian points: */
-	int     num_gauss,ig;
-	double* first_gauss_area_coord  =  NULL;
-	double* second_gauss_area_coord =  NULL;
-	double* third_gauss_area_coord  =  NULL;
-	double* gauss_weights           =  NULL;
-	double  gauss_weight;
-	double  gauss_l1l2l3[3];
-
-	/* matrices: */
-	double B[2][numgrids];
-	double Bprime[2][numgrids];
-	double DL[2][2]={0.0};
-	double DLprime[2][2]={0.0};
-	double DL_scalar;
-	double Ke_gg[numdof][numdof]={0.0};
-	double Ke_gg2[numdof][numdof]={0.0};
-	double Jdettria;
-
-	/*input parameters for structural analysis (diagnostic): */
-	double  vx,vy;
-	int     dofs[1]={0};
-	int     found;
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-	Matpar* matpar=NULL;
-	Matice* matice=NULL;
-
-
-	/*recover objects from hooks: */
-	nodes=(Node**)   hnodes.deliverp();
-	matpar=(Matpar*)hmatpar.delivers();
-	matice=(Matice*)hmatice.delivers();
-
-	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
-	GetDofList(&doflist[0],&numberofdofspernode);
-
-	/* Get gaussian points and weights (make this a statically initialized list of points? fstd): */
-	GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2);
-
-	/* Start  looping on the number of gaussian points: */
-	for (ig=0; ig<num_gauss; ig++){
-		/*Pick up the gaussian point: */
-		gauss_weight=*(gauss_weights+ig);
-		gauss_l1l2l3[0]=*(first_gauss_area_coord+ig); 
-		gauss_l1l2l3[1]=*(second_gauss_area_coord+ig);
-		gauss_l1l2l3[2]=*(third_gauss_area_coord+ig);
-
-		/* Get Jacobian determinant: */
-		GetJacobianDeterminant2d(&Jdettria, &xyz_list[0][0],gauss_l1l2l3);
-
-		/*Get B  and B prime matrix: */
-		/*WARNING: B and Bprime are inverted compared to usual prognostic!!!!*/
-		GetB_prog(&Bprime[0][0], &xyz_list[0][0], gauss_l1l2l3);
-		GetBPrime_prog(&B[0][0], &xyz_list[0][0], gauss_l1l2l3);
-
-		//Get vx, vy and their derivatives at gauss point
-		inputs->GetParameterValue(&vx, &gauss_l1l2l3[0],VxEnum);
-		inputs->GetParameterValue(&vy, &gauss_l1l2l3[0],VyEnum);
-
-		DL_scalar=-gauss_weight*Jdettria;
-
-		DLprime[0][0]=DL_scalar*vx;
-		DLprime[1][1]=DL_scalar*vy;
-
-		//Do the triple product tL*D*L. 
-		TripleMultiply( &B[0][0],2,numdof,1,
-					&DLprime[0][0],2,2,0,
-					&Bprime[0][0],2,numdof,0,
-					&Ke_gg2[0][0],0);
-
-		/* Add the Ke_gg_gaussian, and optionally Ke_gg_drag_gaussian onto Ke_gg: */
-		for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg2[i][j];
-
-	} // for (ig=0; ig<num_gauss; ig++)
-
-	/*Add Ke_gg to global matrix Kgg: */
-	MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)Ke_gg,ADD_VALUES);
-
-cleanup_and_return: 
-	xfree((void**)&first_gauss_area_coord);
-	xfree((void**)&second_gauss_area_coord);
-	xfree((void**)&third_gauss_area_coord);
-	xfree((void**)&gauss_weights);
-
-}
-/*}}}*/
-/*FUNCTION Tria::CreateKMatrixBalancedvelocities {{{1*/
-void  Tria::CreateKMatrixBalancedvelocities(Mat Kgg,int analysis_type,int sub_analysis_type){
-
-	/* local declarations */
-	int             i,j;
-
-	/* node data: */
-	const int    numgrids=3;
-	const int    NDOF1=1;
-	const int    numdof=NDOF1*numgrids;
-	double       xyz_list[numgrids][3];
-	int          doflist[numdof];
-	int          numberofdofspernode;
-
-	/* gaussian points: */
-	int     num_gauss,ig;
-	double* first_gauss_area_coord  =  NULL;
-	double* second_gauss_area_coord =  NULL;
-	double* third_gauss_area_coord  =  NULL;
-	double* gauss_weights           =  NULL;
-	double  gauss_weight;
-	double  gauss_l1l2l3[3];
-	double  gaussgrids[numgrids][numgrids]={{1,0,0},{0,1,0},{0,0,1}};
-
-	/* matrices: */
-	double L[numgrids];
-	double B[2][numgrids];
-	double Bprime[2][numgrids];
-	double DL[2][2]={0.0};
-	double DLprime[2][2]={0.0};
-	double DL_scalar;
-	double Ke_gg[numdof][numdof]={0.0};//local element stiffness matrix 
-	double Ke_gg_gaussian[numdof][numdof]={0.0}; //stiffness matrix evaluated at the gaussian point.
-	double Ke_gg_velocities1[numdof][numdof]={0.0}; //stiffness matrix evaluated at the gaussian point.
-	double Ke_gg_velocities2[numdof][numdof]={0.0}; //stiffness matrix evaluated at the gaussian point.
-	double Jdettria;
-
-	/*input parameters for structural analysis (diagnostic): */
-	double  surface_normal[3];
-	double  surface_list[3];
-	double  nx,ny,norm;
-	double  vx_list[numgrids]={0.0};
-	double  vy_list[numgrids]={0.0};
-	double  dvx[2];
-	double  dvy[2];
-	double  vx,vy;
-	double  dvxdx,dvydy;
-	double  v_gauss[2]={0.0};
-	double  K[2][2]={0.0};
-	double  KDL[2][2]={0.0};
-	int     dofs[2]={0,1};
-	int     found=0;
-
-	/*parameters: */
-	double artdiff;
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-	Matpar* matpar=NULL;
-	Matice* matice=NULL;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	matpar=(Matpar*)hmatpar.delivers();
-	matice=(Matice*)hmatice.delivers();
-
-	/*Recover velocity: */
-	inputs->GetParameterValues(&vx_list[0],&gaussgrids[0][0],3,VxAverageEnum);
-	inputs->GetParameterValues(&vy_list[0],&gaussgrids[0][0],3,VyAverageEnum);
-
-	/*retrieve some parameters: */
-	this->parameters->FindParam(&artdiff,ArtDiffEnum);
-
-	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
-	GetDofList(&doflist[0],&numberofdofspernode);
-
-	/*Modify z so that it reflects the surface*/
-	inputs->GetParameterValues(&surface_list[0],&gaussgrids[0][0],3,SurfaceEnum);
-	for(i=0;i<numgrids;i++) xyz_list[i][2]=surface_list[i];
-
-	/*Get normal vector to the surface*/
-	nx=(vx_list[0]+vx_list[1]+vx_list[2])/3;
-	ny=(vy_list[0]+vy_list[1]+vy_list[2])/3;
-	if(nx==0 && ny==0){
-		SurfaceNormal(&surface_normal[0],xyz_list);
-		nx=surface_normal[0];
-		ny=surface_normal[1];
-	}
-	if(nx==0 && ny==0){
-		nx=0;
-		ny=1;
-	}
-	norm=pow( pow(nx,2)+pow(ny,2) , (double).5);
-	nx=nx/norm;
-	ny=ny/norm;
-
-	//Create Artificial diffusivity once for all if requested
-	if(artdiff){
-		//Get the Jacobian determinant
-		gauss_l1l2l3[0]=ONETHIRD; gauss_l1l2l3[1]=ONETHIRD; gauss_l1l2l3[2]=ONETHIRD;
-		GetJacobianDeterminant2d(&Jdettria, &xyz_list[0][0],gauss_l1l2l3);
-
-		//Build K matrix (artificial diffusivity matrix)
-		v_gauss[0]=ONETHIRD*(vx_list[0]+vx_list[1]+vx_list[2]);
-		v_gauss[1]=ONETHIRD*(vy_list[0]+vy_list[1]+vy_list[2]);
-
-		K[0][0]=pow(10,2)*pow(Jdettria,(double).5)/2.0*fabs(v_gauss[0]); //pow should be zero!!
-		K[1][1]=pow(10,2)*pow(Jdettria,(double).5)/2.0*fabs(v_gauss[1]);
-	}
-
-	/* Get gaussian points and weights (make this a statically initialized list of points? fstd): */
-	GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2);
-
-	/* Start  looping on the number of gaussian points: */
-	for (ig=0; ig<num_gauss; ig++){
-		/*Pick up the gaussian point: */
-		gauss_weight=*(gauss_weights+ig);
-		gauss_l1l2l3[0]=*(first_gauss_area_coord+ig); 
-		gauss_l1l2l3[1]=*(second_gauss_area_coord+ig);
-		gauss_l1l2l3[2]=*(third_gauss_area_coord+ig);
-
-		/* Get Jacobian determinant: */
-		GetJacobianDeterminant2d(&Jdettria, &xyz_list[0][0],gauss_l1l2l3);
-
-		/*Get B  and B prime matrix: */
-		GetB_prog(&B[0][0], &xyz_list[0][0], gauss_l1l2l3);
-		GetBPrime_prog(&Bprime[0][0], &xyz_list[0][0], gauss_l1l2l3);
-
-		//Get vx, vy and their derivatives at gauss point
-		GetParameterValue(&vx, &vx_list[0],gauss_l1l2l3);
-		GetParameterValue(&vy, &vy_list[0],gauss_l1l2l3);
-
-		GetParameterDerivativeValue(&dvx[0], &vx_list[0],&xyz_list[0][0], gauss_l1l2l3);
-		GetParameterDerivativeValue(&dvy[0], &vy_list[0],&xyz_list[0][0], gauss_l1l2l3);
-
-		dvxdx=dvx[0];
-		dvydy=dvy[1];
-
-		DL_scalar=gauss_weight*Jdettria;
-
-		DLprime[0][0]=DL_scalar*nx;
-		DLprime[1][1]=DL_scalar*ny;
-
-		//Do the triple product tL*D*L. 
-		//Ke_gg_velocities=B'*DLprime*Bprime;
-		TripleMultiply( &B[0][0],2,numdof,1,
-					&DLprime[0][0],2,2,0,
-					&Bprime[0][0],2,numdof,0,
-					&Ke_gg_velocities2[0][0],0);
-
-		/* Add the Ke_gg_gaussian, and optionally Ke_gg_drag_gaussian onto Ke_gg: */
-		for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg_velocities2[i][j];
-
-		if(artdiff){
-
-			/* Compute artificial diffusivity */
-			KDL[0][0]=DL_scalar*K[0][0];
-			KDL[1][1]=DL_scalar*K[1][1];
-
-			TripleMultiply( &Bprime[0][0],2,numdof,1,
-						&KDL[0][0],2,2,0,
-						&Bprime[0][0],2,numdof,0,
-						&Ke_gg_gaussian[0][0],0);
-
-			/* Add artificial diffusivity matrix */
-			for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg_gaussian[i][j];
-
-		}
-
-	} // for (ig=0; ig<num_gauss; ig++)
-
-	/*Add Ke_gg to global matrix Kgg: */
-	MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)Ke_gg,ADD_VALUES);
-
-
-cleanup_and_return: 
-	xfree((void**)&first_gauss_area_coord);
-	xfree((void**)&second_gauss_area_coord);
-	xfree((void**)&third_gauss_area_coord);
-	xfree((void**)&gauss_weights);
-
-}
-/*}}}*/
-/*FUNCTION Tria::CreateKMatrixDiagnosticHoriz {{{1*/
-void  Tria::CreateKMatrixDiagnosticHoriz(Mat Kgg,int analysis_type,int sub_analysis_type){
-
-	/* local declarations */
-	int             i,j;
-
-	/* node data: */
-	const int    numgrids=3;
-	const int    numdof=2*numgrids;
-	double       xyz_list[numgrids][3];
-	int          doflist[numdof];
-	int          numberofdofspernode;
-
-	/* gaussian points: */
-	int     num_gauss,ig;
-	double* first_gauss_area_coord  =  NULL;
-	double* second_gauss_area_coord =  NULL;
-	double* third_gauss_area_coord  =  NULL;
-	double* gauss_weights           =  NULL;
-	double  gauss_weight;
-	double  gauss_l1l2l3[3];
-
-	/* material data: */
-	double viscosity; //viscosity
-	double newviscosity; //viscosity
-	double oldviscosity; //viscosity
-
-	/* strain rate: */
-	double epsilon[3]; /* epsilon=[exx,eyy,exy];*/
-	double oldepsilon[3]; /* oldepsilon=[exx,eyy,exy];*/
-
-	/* matrices: */
-	double B[3][numdof];
-	double Bprime[3][numdof];
-	double D[3][3]={0.0};  // material matrix, simple scalar matrix.
-	double D_scalar;
-
-	/*parameters: */
-	double viscosity_overshoot;
-
-	/* local element matrices: */
-	double Ke_gg[numdof][numdof]={0.0};
-	double Ke_gg_gaussian[numdof][numdof]; //stiffness matrix evaluated at the gaussian point.
-
-	double Jdet;
-
-	/*input parameters for structural analysis (diagnostic): */
-	double  thickness;
-	int     dofs[2]={0,1};
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-	Matpar* matpar=NULL;
-	Matice* matice=NULL;
-
-	/*inputs: */
-	bool onwater,shelf;
-
-	/*retrieve inputs :*/
-	inputs->GetParameterValue(&onwater,ElementOnWaterEnum);
-	inputs->GetParameterValue(&shelf,ElementOnIceShelfEnum);
-
-	/*retrieve some parameters: */
-	this->parameters->FindParam(&viscosity_overshoot,ViscosityOvershootEnum);
-
-	/*First, if we are on water, return empty matrix: */
-	if(onwater) return;
-
-	/*recover objects from hooks: */
-	nodes =(Node**) hnodes.deliverp();
-	matpar=(Matpar*)hmatpar.delivers();
-	matice=(Matice*)hmatice.delivers();
-
-	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
-	GetDofList(&doflist[0],&numberofdofspernode);
-
-	/* Get gaussian points and weights (make this a statically initialized list of points? fstd): */
-	GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2);
-
-	/* Start  looping on the number of gaussian points: */
-	for (ig=0; ig<num_gauss; ig++){
-		/*Pick up the gaussian point: */
-		gauss_weight=*(gauss_weights+ig);
-		gauss_l1l2l3[0]=*(first_gauss_area_coord+ig); 
-		gauss_l1l2l3[1]=*(second_gauss_area_coord+ig);
-		gauss_l1l2l3[2]=*(third_gauss_area_coord+ig);
-
-
-		/*Compute thickness at gaussian point: */
-		inputs->GetParameterValue(&thickness, gauss_l1l2l3,ThicknessEnum);
-
-		/*Get strain rate from velocity: */
-		inputs->GetStrainRate(&epsilon[0],&xyz_list[0][0],gauss_l1l2l3,VxEnum,VyEnum);
-		inputs->GetStrainRate(&oldepsilon[0],&xyz_list[0][0],gauss_l1l2l3,VxOldEnum,VyOldEnum);
-
-		/*Get viscosity: */
-		matice->GetViscosity2d(&viscosity, &epsilon[0]);
-		matice->GetViscosity2d(&oldviscosity, &oldepsilon[0]);
-
-		/* Get Jacobian determinant: */
-		GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss_l1l2l3);
-
-		/* Build the D matrix: we plug the gaussian weight, the thickness, the viscosity, and the jacobian determinant 
-			onto this scalar matrix, so that we win some computational time: */
-		newviscosity=viscosity+viscosity_overshoot*(viscosity-oldviscosity);
-		D_scalar=newviscosity*thickness*gauss_weight*Jdet;
-
-		for (i=0;i<3;i++){
-			D[i][i]=D_scalar;
-		}
-
-		/*Get B and Bprime matrices: */
-		GetB(&B[0][0], &xyz_list[0][0], gauss_l1l2l3);
-		GetBPrime(&Bprime[0][0], &xyz_list[0][0], gauss_l1l2l3);
-
-		/*  Do the triple product tB*D*Bprime: */
-		TripleMultiply( &B[0][0],3,numdof,1,
-					&D[0][0],3,3,0,
-					&Bprime[0][0],3,numdof,0,
-					&Ke_gg_gaussian[0][0],0);
-
-		/* Add the Ke_gg_gaussian, and optionally Ke_gg_drag_gaussian onto Ke_gg: */
-		for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg_gaussian[i][j];
-
-	} // for (ig=0; ig<num_gauss; ig++)
-
-	/*Add Ke_gg to global matrix Kgg: */
-	MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)Ke_gg,ADD_VALUES);
-
-	/*Do not forget to include friction: */
-	if(!shelf){
-		CreateKMatrixDiagnosticHorizFriction(Kgg,analysis_type,sub_analysis_type);
-	}
-
-cleanup_and_return: 
-	xfree((void**)&first_gauss_area_coord);
-	xfree((void**)&second_gauss_area_coord);
-	xfree((void**)&third_gauss_area_coord);
-	xfree((void**)&gauss_weights);
-
-}
-/*}}}*/
-/*FUNCTION Tria::CreateKMatrixDiagnosticHorizFriction {{{1*/
-void  Tria::CreateKMatrixDiagnosticHorizFriction(Mat Kgg,int analysis_type,int sub_analysis_type){
-
-
-	/* local declarations */
-	int             i,j;
-
-	/* node data: */
-	const int    numgrids=3;
-	const int    numdof=2*numgrids;
-	double       xyz_list[numgrids][3];
-	int          doflist[numdof];
-	int          numberofdofspernode;
-	
-	/* gaussian points: */
-	int     num_gauss,ig;
-	double* first_gauss_area_coord  =  NULL;
-	double* second_gauss_area_coord =  NULL;
-	double* third_gauss_area_coord  =  NULL;
-	double* gauss_weights           =  NULL;
-	double  gauss_weight;
-	double  gauss_l1l2l3[3];
-	double  gaussgrids[numgrids][numgrids]={{1,0,0},{0,1,0},{0,0,1}};
-
-	/* matrices: */
-	double L[2][numdof];
-	double DL[2][2]={{ 0,0 },{0,0}}; //for basal drag
-	double DL_scalar;
-
-	/* local element matrices: */
-	double Ke_gg[numdof][numdof]={0.0};
-	double Ke_gg_gaussian[numdof][numdof]; //stiffness matrix contribution from drag
-	
-	double Jdet;
-	
-	/*slope: */
-	double  slope[2]={0.0,0.0};
-	double  slope_magnitude;
-
-	/*input parameters for structural analysis (diagnostic): */
-	double  vx_list[numgrids];
-	double  vy_list[numgrids];
-	double  thickness_list[numgrids];
-	double  bed_list[numgrids];
-	double  dragcoefficient_list[numgrids];
-	double  drag_p,drag_q;
-
-	/*friction: */
-	double alpha2_list[numgrids]={0.0,0.0,0.0};
-	double alpha2;
-
-	double MAXSLOPE=.06; // 6 %
-	double MOUNTAINKEXPONENT=10;
-
-	/*inputs: */
-	bool shelf;
-	int  drag_type;
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-	Matpar* matpar=NULL;
-	Matice* matice=NULL;
-
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	matpar=(Matpar*)hmatpar.delivers();
-	matice=(Matice*)hmatice.delivers();
-
-	/*retrieve inputs :*/
-	inputs->GetParameterValue(&shelf,ElementOnIceShelfEnum);
-	inputs->GetParameterValue(&drag_type,DragTypeEnum);
-	
-	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
-	GetDofList(&doflist[0],&numberofdofspernode);
-
-	if (shelf){
-		/*no friction, do nothing*/
-		return;
-	}
-
-	if (drag_type!=2)ISSMERROR(" non-viscous friction not supported yet!");
-
-	/*Recover inputs: */
-	inputs->GetParameterValues(&vx_list[0],&gaussgrids[0][0],3,VxAverageEnum);
-	inputs->GetParameterValues(&vy_list[0],&gaussgrids[0][0],3,VyAverageEnum);
-	inputs->GetParameterValues(&dragcoefficient_list[0],&gaussgrids[0][0],3,DragCoefficientEnum);
-	inputs->GetParameterValues(&bed_list[0],&gaussgrids[0][0],3,BedEnum);
-	inputs->GetParameterValues(&thickness_list[0],&gaussgrids[0][0],3,ThicknessEnum);
-	inputs->GetParameterValue(&drag_p,DragPEnum);
-	inputs->GetParameterValue(&drag_q,DragQEnum);
-
-	/*Build alpha2_list used by drag stiffness matrix*/
-	Friction* friction=NewFriction();
-	
-	/*Initialize all fields: */
-	friction->element_type=(char*)xmalloc((strlen("2d")+1)*sizeof(char));
-	strcpy(friction->element_type,"2d");
-	
-	friction->gravity=matpar->GetG();
-	friction->rho_ice=matpar->GetRhoIce();
-	friction->rho_water=matpar->GetRhoWater();
-	friction->K=&dragcoefficient_list[0];
-	friction->bed=&bed_list[0];
-	friction->thickness=&thickness_list[0];
-	friction->vx=&vx_list[0];
-	friction->vy=&vy_list[0];
-	friction->p=drag_p;
-	friction->q=drag_q;
-
-	/*Compute alpha2_list: */
-	FrictionGetAlpha2(&alpha2_list[0],friction);
-
-	/*Erase friction object: */
-	DeleteFriction(&friction);
-
-	/* Get gaussian points and weights (make this a statically initialized list of points? fstd): */
-	GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2);
-
-	/* Start  looping on the number of gaussian points: */
-	for (ig=0; ig<num_gauss; ig++){
-		/*Pick up the gaussian point: */
-		gauss_weight=*(gauss_weights+ig);
-		gauss_l1l2l3[0]=*(first_gauss_area_coord+ig); 
-		gauss_l1l2l3[1]=*(second_gauss_area_coord+ig);
-		gauss_l1l2l3[2]=*(third_gauss_area_coord+ig);
-
-
-		// If we have a slope > 6% for this element,  it means  we are on a mountain. In this particular case, 
-		//velocity should be = 0. To achieve this result, we set alpha2_list to a very high value: */
-		inputs->GetParameterDerivativeValue(&slope[0],&xyz_list[0][0],&gauss_l1l2l3[0],SurfaceEnum);
-		slope_magnitude=sqrt(pow(slope[0],2)+pow(slope[1],2));
-
-		if (slope_magnitude>MAXSLOPE){
-			alpha2_list[0]=pow((double)10,MOUNTAINKEXPONENT);
-			alpha2_list[1]=pow((double)10,MOUNTAINKEXPONENT);
-			alpha2_list[2]=pow((double)10,MOUNTAINKEXPONENT);
-		}
-
-		/* Get Jacobian determinant: */
-		GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss_l1l2l3);
-
-		/*Get L matrix: */
-		GetL(&L[0][0], &xyz_list[0][0], gauss_l1l2l3,numberofdofspernode);
-
-		/*Now, take care of the basal friction if there is any: */
-		GetParameterValue(&alpha2, &alpha2_list[0],gauss_l1l2l3);
-
-		DL_scalar=alpha2*gauss_weight*Jdet;
-		for (i=0;i<2;i++){
-			DL[i][i]=DL_scalar;
-		}
-		
-		/*  Do the triple producte tL*D*L: */
-		TripleMultiply( &L[0][0],2,numdof,1,
-					&DL[0][0],2,2,0,
-					&L[0][0],2,numdof,0,
-					&Ke_gg_gaussian[0][0],0);
-
-		for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg_gaussian[i][j];
-
-	} // for (ig=0; ig<num_gauss; ig++)
-
-	/*Add Ke_gg to global matrix Kgg: */
-	MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)Ke_gg,ADD_VALUES);
-
-	cleanup_and_return: 
-	xfree((void**)&first_gauss_area_coord);
-	xfree((void**)&second_gauss_area_coord);
-	xfree((void**)&third_gauss_area_coord);
-	xfree((void**)&gauss_weights);
-
-}	
-/*}}}*/
-/*FUNCTION Tria::CreateKMatrixDiagnosticSurfaceVert {{{1*/
-void  Tria::CreateKMatrixDiagnosticSurfaceVert(Mat Kgg,int analysis_type,int sub_analysis_type){
-
-	int i,j;
-
-	/* node data: */
-	const int    numgrids=3;
-	const int    NDOF1=1;
-	const int    numdof=NDOF1*numgrids;
-	double       xyz_list[numgrids][3];
-	int          doflist[numdof];
-	int          numberofdofspernode;
-
-	/* gaussian points: */
-	int     num_gauss,ig;
-	double* first_gauss_area_coord  =  NULL;
-	double* second_gauss_area_coord =  NULL;
-	double* third_gauss_area_coord  =  NULL;
-	double* gauss_weights           =  NULL;
-	double  gauss_weight;
-	double  gauss_l1l2l3[3];
-
-
-	/* surface normal: */
-	double x4,y4,z4;
-	double x5,y5,z5;
-	double x6,y6,z6;
-	double v46[3];
-	double v56[3];
-	double normal[3];
-	double norm_normal;
-	double nz;
-
-	/*Matrices: */
-	double DL_scalar;
-	double L[3];
-	double Jdet;
-
-	/* local element matrices: */
-	double Ke_gg[numdof][numdof]={0.0}; //local element stiffness matrix 
-	double Ke_gg_gaussian[numdof][numdof]; //stiffness matrix evaluated at the gaussian point.
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-	Matpar* matpar=NULL;
-	Matice* matice=NULL;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	matpar=(Matpar*)hmatpar.delivers();
-	matice=(Matice*)hmatice.delivers();
-
-	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
-	GetDofList(&doflist[0],&numberofdofspernode);
-
-	/* Get gaussian points and weights (make this a statically initialized list of points? fstd): */
-	GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2);
-
-	/*Build normal vector to the surface:*/
-
-	x4=xyz_list[0][0];
-	y4=xyz_list[0][1];
-	z4=xyz_list[0][2];
-
-	x5=xyz_list[1][0];
-	y5=xyz_list[1][1];
-	z5=xyz_list[1][2];
-
-	x6=xyz_list[2][0];
-	y6=xyz_list[2][1];
-	z6=xyz_list[2][2];
-
-	v46[0]=x4-x6;
-	v46[1]=y4-y6;
-	v46[2]=z4-z6;
-
-	v56[0]=x5-x6;
-	v56[1]=y5-y6;
-	v56[2]=z5-z6;
-
-	normal[0]=(y4-y6)*(z5-z6)-(z4-z6)*(y5-y6);
-	normal[1]=(z4-z6)*(x5-x6)-(x4-x6)*(z5-z6);
-	normal[2]=(x4-x6)*(y5-y6)-(y4-y6)*(x5-x6);
-
-	norm_normal=sqrt(pow(normal[0],(double)2)+pow(normal[1],(double)2)+pow(normal[2],(double)2));
-	nz=1.0/norm_normal*normal[2];
-
-	/* Start  looping on the number of gaussian points: */
-	for (ig=0; ig<num_gauss; ig++){
-		/*Pick up the gaussian point: */
-		gauss_weight=*(gauss_weights+ig);
-		gauss_l1l2l3[0]=*(first_gauss_area_coord+ig); 
-		gauss_l1l2l3[1]=*(second_gauss_area_coord+ig);
-		gauss_l1l2l3[2]=*(third_gauss_area_coord+ig);
-
-		/* Get Jacobian determinant: */
-		GetJacobianDeterminant3d(&Jdet, &xyz_list[0][0],gauss_l1l2l3);
-
-		//Get L matrix if viscous basal drag present:
-		GetL(&L[0], &xyz_list[0][0], gauss_l1l2l3,NDOF1);
-
-		/**********************Do not forget the sign**********************************/
-		DL_scalar=- gauss_weight*Jdet*nz; 
-		/******************************************************************************/
-
-		/*  Do the triple producte tL*D*L: */
-		TripleMultiply( L,1,3,1,
-					&DL_scalar,1,1,0,
-					L,1,3,0,
-					&Ke_gg_gaussian[0][0],0);
-
-		/* Add the Ke_gg_gaussian, onto Ke_gg: */
-		for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg_gaussian[i][j];
-
-
-	} //for (ig=0; ig<num_gauss; ig++)
-
-	/*Add Ke_gg to global matrix Kgg: */
-	MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)Ke_gg,ADD_VALUES);
-
-cleanup_and_return: 
-	xfree((void**)&first_gauss_area_coord);
-	xfree((void**)&second_gauss_area_coord);
-	xfree((void**)&third_gauss_area_coord);
-	xfree((void**)&gauss_weights);
-}
-/*}}}*/
-/*FUNCTION Tria::CreateKMatrixMelting {{{1*/
-void  Tria::CreateKMatrixMelting(Mat Kgg,int analysis_type,int sub_analysis_type){
-
-	/*indexing: */
-	int i,j;
-
-	const int  numgrids=3;
-	const int  NDOF1=1;
-	const int  numdof=numgrids*NDOF1;
-	int        doflist[numdof];
-	int        numberofdofspernode;
-
-	/*Grid data: */
-	double     xyz_list[numgrids][3];
-
-	/*Material constants */
-	double     heatcapacity,latentheat;
-
-	/* gaussian points: */
-	int     num_area_gauss,ig;
-	double* gauss_weights  =  NULL;
-	double* first_gauss_area_coord  =  NULL;
-	double* second_gauss_area_coord =  NULL;
-	double* third_gauss_area_coord  =  NULL;
-	double  gauss_weight;
-	double  gauss_coord[3];
-
-	/*matrices: */
-	double     Jdet;
-	double     D_scalar;
-	double     K_terms[numdof][numdof]={0.0};
-	double     L[3];
-	double     tLD[3];
-	double     Ke_gaussian[numdof][numdof]={0.0};
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-	Matpar* matpar=NULL;
-	Matice* matice=NULL;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	matpar=(Matpar*)hmatpar.delivers();
-	matice=(Matice*)hmatice.delivers();
-
-	/*Recover constants of ice */
-	latentheat=matpar->GetLatentHeat();
-	heatcapacity=matpar->GetHeatCapacity();
-
-	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
-	GetDofList(&doflist[0],&numberofdofspernode);
-
-	/* Get gaussian points and weights: */
-	GaussTria (&num_area_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2);
-
-	/* Start looping on the number of gauss  (nodes on the bedrock) */
-	for (ig=0; ig<num_area_gauss; ig++){
-		gauss_weight=*(gauss_weights+ig);
-		gauss_coord[0]=*(first_gauss_area_coord+ig); 
-		gauss_coord[1]=*(second_gauss_area_coord+ig);
-		gauss_coord[2]=*(third_gauss_area_coord+ig);
-
-		//Get the Jacobian determinant
-		GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0], gauss_coord);
-
-		/*Get L matrix : */
-		GetL(&L[0], &xyz_list[0][0], gauss_coord,NDOF1);
-
-		/*Calculate DL on gauss point */
-		D_scalar=latentheat/heatcapacity*gauss_weight*Jdet;
-
-		/*  Do the triple product tL*D*L: */
-		MatrixMultiply(&L[0],numdof,1,0,&D_scalar,1,1,0,&tLD[0],0);
-		MatrixMultiply(&tLD[0],numdof,1,0,&L[0],1,numdof,0,&Ke_gaussian[0][0],0);
-
-		for(i=0;i<numgrids;i++){
-			for(j=0;j<numgrids;j++){
-				K_terms[i][j]+=Ke_gaussian[i][j];
-			}
-		}
-	}
-
-	/*Add Ke_gg to global matrix Kgg: */
-	MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)K_terms,ADD_VALUES);
-
-cleanup_and_return:
-	xfree((void**)&first_gauss_area_coord);
-	xfree((void**)&second_gauss_area_coord);
-	xfree((void**)&third_gauss_area_coord);
-	xfree((void**)&gauss_weights);
-
-}
-/*}}}*/
-/*FUNCTION Tria::CreateKMatrixPrognostic {{{1*/
-void  Tria::CreateKMatrixPrognostic(Mat Kgg,int analysis_type,int sub_analysis_type){
-
-	/* local declarations */
-	int             i,j;
-
-	/* node data: */
-	const int    numgrids=3;
-	const int    NDOF1=1;
-	const int    numdof=NDOF1*numgrids;
-	double       xyz_list[numgrids][3];
-	int          doflist[numdof];
-	int          numberofdofspernode;
-
-	/* gaussian points: */
-	int     num_gauss,ig;
-	double* first_gauss_area_coord  =  NULL;
-	double* second_gauss_area_coord =  NULL;
-	double* third_gauss_area_coord  =  NULL;
-	double* gauss_weights           =  NULL;
-	double  gauss_weight;
-	double  gauss_l1l2l3[3];
-	double  gaussgrids[numgrids][numgrids]={{1,0,0},{0,1,0},{0,0,1}};
-
-	/* matrices: */
-	double L[numgrids];
-	double B[2][numgrids];
-	double Bprime[2][numgrids];
-	double DL[2][2]={0.0};
-	double DLprime[2][2]={0.0};
-	double DL_scalar;
-	double Ke_gg[numdof][numdof]={0.0};
-	double Ke_gg_gaussian[numdof][numdof]={0.0};
-	double Ke_gg_thickness1[numdof][numdof]={0.0};
-	double Ke_gg_thickness2[numdof][numdof]={0.0};
-	double Jdettria;
-
-	/*input parameters for structural analysis (diagnostic): */
-	double  vx_list[numgrids]={0.0};
-	double  vy_list[numgrids]={0.0};
-	double  dvx[2];
-	double  dvy[2];
-	double  vx,vy;
-	double  dvxdx,dvydy;
-	double  v_gauss[2]={0.0};
-	double  K[2][2]={0.0};
-	double  KDL[2][2]={0.0};
-	int     dofs[2]={0,1};
-	int     found;
-
-	/*parameters: */
-	double dt;
-	double artdiff;
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-	Matpar* matpar=NULL;
-	Matice* matice=NULL;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	matpar=(Matpar*)hmatpar.delivers();
-	matice=(Matice*)hmatice.delivers();
-
-	/*retrieve some parameters: */
-	this->parameters->FindParam(&dt,DtEnum);
-	this->parameters->FindParam(&artdiff,ArtDiffEnum);
-
-	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
-	GetDofList(&doflist[0],&numberofdofspernode);
-
-	/*Recover velocity: */
-	inputs->GetParameterValues(&vx_list[0],&gaussgrids[0][0],3,VxAverageEnum);
-	inputs->GetParameterValues(&vy_list[0],&gaussgrids[0][0],3,VyAverageEnum);
-
-	//Create Artificial diffusivity once for all if requested
-	if(artdiff==1){
-		//Get the Jacobian determinant
-		gauss_l1l2l3[0]=ONETHIRD; gauss_l1l2l3[1]=ONETHIRD; gauss_l1l2l3[2]=ONETHIRD;
-		GetJacobianDeterminant2d(&Jdettria, &xyz_list[0][0],gauss_l1l2l3);
-
-		//Build K matrix (artificial diffusivity matrix)
-		v_gauss[0]=ONETHIRD*(vx_list[0]+vx_list[1]+vx_list[2]);
-		v_gauss[1]=ONETHIRD*(vy_list[0]+vy_list[1]+vy_list[2]);
-
-		K[0][0]=pow(Jdettria,(double).5)/2.0*fabs(v_gauss[0]);
-		K[1][1]=pow(Jdettria,(double).5)/2.0*fabs(v_gauss[1]);
-	}
-
-	/* Get gaussian points and weights (make this a statically initialized list of points? fstd): */
-	GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2);
-
-	/* Start  looping on the number of gaussian points: */
-	for (ig=0; ig<num_gauss; ig++){
-
-		/*Pick up the gaussian point: */
-		gauss_weight=*(gauss_weights+ig);
-		gauss_l1l2l3[0]=*(first_gauss_area_coord+ig); 
-		gauss_l1l2l3[1]=*(second_gauss_area_coord+ig);
-		gauss_l1l2l3[2]=*(third_gauss_area_coord+ig);
-
-		/* Get Jacobian determinant: */
-		GetJacobianDeterminant2d(&Jdettria, &xyz_list[0][0],gauss_l1l2l3);
-
-		/*Get L matrix: */
-		GetL(&L[0], &xyz_list[0][0], gauss_l1l2l3,numberofdofspernode);
-
-		DL_scalar=gauss_weight*Jdettria;
-
-		/*  Do the triple product tL*D*L: */
-		TripleMultiply( &L[0],1,numdof,1,
-					&DL_scalar,1,1,0,
-					&L[0],1,numdof,0,
-					&Ke_gg_gaussian[0][0],0);
-
-		/*Get B  and B prime matrix: */
-		GetB_prog(&B[0][0], &xyz_list[0][0], gauss_l1l2l3);
-		GetBPrime_prog(&Bprime[0][0], &xyz_list[0][0], gauss_l1l2l3);
-
-		//Get vx, vy and their derivatives at gauss point
-		GetParameterValue(&vx, &vx_list[0],gauss_l1l2l3);
-		GetParameterValue(&vy, &vy_list[0],gauss_l1l2l3);
-
-		GetParameterDerivativeValue(&dvx[0], &vx_list[0],&xyz_list[0][0], gauss_l1l2l3);
-		GetParameterDerivativeValue(&dvy[0], &vy_list[0],&xyz_list[0][0], gauss_l1l2l3);
-
-		dvxdx=dvx[0];
-		dvydy=dvy[1];
-
-		DL_scalar=dt*gauss_weight*Jdettria;
-
-		//Create DL and DLprime matrix
-		DL[0][0]=DL_scalar*dvxdx;
-		DL[1][1]=DL_scalar*dvydy;
-
-		DLprime[0][0]=DL_scalar*vx;
-		DLprime[1][1]=DL_scalar*vy;
-
-		//Do the triple product tL*D*L. 
-		//Ke_gg_thickness=B'*DL*B+B'*DLprime*Bprime;
-
-		TripleMultiply( &B[0][0],2,numdof,1,
-					&DL[0][0],2,2,0,
-					&B[0][0],2,numdof,0,
-					&Ke_gg_thickness1[0][0],0);
-
-		TripleMultiply( &B[0][0],2,numdof,1,
-					&DLprime[0][0],2,2,0,
-					&Bprime[0][0],2,numdof,0,
-					&Ke_gg_thickness2[0][0],0);
-
-		/* Add the Ke_gg_gaussian, and optionally Ke_gg_drag_gaussian onto Ke_gg: */
-		for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg_gaussian[i][j];
-		for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg_thickness1[i][j];
-		for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg_thickness2[i][j];
-
-		if(artdiff==1){
-
-			/* Compute artificial diffusivity */
-			KDL[0][0]=DL_scalar*K[0][0];
-			KDL[1][1]=DL_scalar*K[1][1];
-
-			TripleMultiply( &Bprime[0][0],2,numdof,1,
-						&KDL[0][0],2,2,0,
-						&Bprime[0][0],2,numdof,0,
-						&Ke_gg_gaussian[0][0],0);
-
-			/* Add artificial diffusivity matrix */
-			for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg_gaussian[i][j];
-
-		}
-
-	} // for (ig=0; ig<num_gauss; ig++)
-
-	/*Add Ke_gg to global matrix Kgg: */
-	MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)Ke_gg,ADD_VALUES);
-
-
-cleanup_and_return: 
-	xfree((void**)&first_gauss_area_coord);
-	xfree((void**)&second_gauss_area_coord);
-	xfree((void**)&third_gauss_area_coord);
-	xfree((void**)&gauss_weights);
-
-}
-/*}}}*/
-/*FUNCTION Tria::CreateKMatrixPrognostic2 {{{1*/
-void  Tria::CreateKMatrixPrognostic2(Mat Kgg,int analysis_type,int sub_analysis_type){
-
-	/* local declarations */
-	int             i,j;
-
-	/* node data: */
-	const int    numgrids=3;
-	const int    NDOF1=1;
-	const int    numdof=NDOF1*numgrids;
-	double       xyz_list[numgrids][3];
-	int          doflist[numdof];
-	int          numberofdofspernode;
-
-	/* gaussian points: */
-	int     num_gauss,ig;
-	double* first_gauss_area_coord  =  NULL;
-	double* second_gauss_area_coord =  NULL;
-	double* third_gauss_area_coord  =  NULL;
-	double* gauss_weights           =  NULL;
-	double  gauss_weight;
-	double  gauss_l1l2l3[3];
-
-	/* matrices: */
-	double L[numgrids];
-	double B[2][numgrids];
-	double Bprime[2][numgrids];
-	double DL[2][2]={0.0};
-	double DLprime[2][2]={0.0};
-	double DL_scalar;
-	double Ke_gg[numdof][numdof]={0.0};
-	double Ke_gg1[numdof][numdof]={0.0};
-	double Ke_gg2[numdof][numdof]={0.0};
-	double Jdettria;
-
-	/*input parameters for structural analysis (diagnostic): */
-	double  vx,vy;
-	int     dofs[1]={0};
-	int     found;
-
-	/*parameters: */
-	double dt;
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-	Matpar* matpar=NULL;
-	Matice* matice=NULL;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)   hnodes.deliverp();
-	matpar=(Matpar*)hmatpar.delivers();
-	matice=(Matice*)hmatice.delivers();
-
-	/*retrieve some parameters: */
-	this->parameters->FindParam(&dt,DtEnum);
-
-	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
-	GetDofList(&doflist[0],&numberofdofspernode);
-
-	/* Get gaussian points and weights (make this a statically initialized list of points? fstd): */
-	GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2);
-
-	/* Start  looping on the number of gaussian points: */
-	for (ig=0; ig<num_gauss; ig++){
-
-		/*Pick up the gaussian point: */
-		gauss_weight=*(gauss_weights+ig);
-		gauss_l1l2l3[0]=*(first_gauss_area_coord+ig); 
-		gauss_l1l2l3[1]=*(second_gauss_area_coord+ig);
-		gauss_l1l2l3[2]=*(third_gauss_area_coord+ig);
-
-		/* Get Jacobian determinant: */
-		GetJacobianDeterminant2d(&Jdettria, &xyz_list[0][0],gauss_l1l2l3);
-
-		/*Get L matrix: */
-		GetL(&L[0], &xyz_list[0][0], gauss_l1l2l3,numberofdofspernode);
-
-		DL_scalar=gauss_weight*Jdettria;
-
-		/*  Do the triple product tL*D*L: */
-		TripleMultiply( &L[0],1,numdof,1,
-					&DL_scalar,1,1,0,
-					&L[0],1,numdof,0,
-					&Ke_gg1[0][0],0);
-
-		/*Get B  and B prime matrix: */
-		/*WARNING: B and Bprime are inverted compared to usual prognostic!!!!*/
-		GetB_prog(&Bprime[0][0], &xyz_list[0][0], gauss_l1l2l3);
-		GetBPrime_prog(&B[0][0], &xyz_list[0][0], gauss_l1l2l3);
-
-		//Get vx, vy and their derivatives at gauss point
-		inputs->GetParameterValue(&vx,&gauss_l1l2l3[0],VxAverageEnum);
-		inputs->GetParameterValue(&vy,&gauss_l1l2l3[0],VyAverageEnum);
-
-		DL_scalar=-dt*gauss_weight*Jdettria;
-
-		DLprime[0][0]=DL_scalar*vx;
-		DLprime[1][1]=DL_scalar*vy;
-
-		//Do the triple product tL*D*L. 
-		TripleMultiply( &B[0][0],2,numdof,1,
-					&DLprime[0][0],2,2,0,
-					&Bprime[0][0],2,numdof,0,
-					&Ke_gg2[0][0],0);
-
-		/* Add the Ke_gg_gaussian, and optionally Ke_gg_drag_gaussian onto Ke_gg: */
-		for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg1[i][j];
-		for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg2[i][j];
-
-	} // for (ig=0; ig<num_gauss; ig++)
-
-	/*Add Ke_gg to global matrix Kgg: */
-	MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)Ke_gg,ADD_VALUES);
-
-
-cleanup_and_return: 
-	xfree((void**)&first_gauss_area_coord);
-	xfree((void**)&second_gauss_area_coord);
-	xfree((void**)&third_gauss_area_coord);
-	xfree((void**)&gauss_weights);
-
-}
-/*}}}*/
-/*FUNCTION Tria::CreateKMatrixSlopeCompute {{{1*/
-
-void  Tria::CreateKMatrixSlopeCompute(Mat Kgg,int analysis_type,int sub_analysis_type){
-
-	/* local declarations */
-	int             i,j;
-
-	/* node data: */
-	const int    numgrids=3;
-	const int    NDOF1=1;
-	const int    numdof=NDOF1*numgrids;
-	double       xyz_list[numgrids][3];
-	int          doflist[numdof];
-	int          numberofdofspernode;
-	
-	/* gaussian points: */
-	int     num_gauss,ig;
-	double* first_gauss_area_coord  =  NULL;
-	double* second_gauss_area_coord =  NULL;
-	double* third_gauss_area_coord  =  NULL;
-	double* gauss_weights           =  NULL;
-	double  gauss_weight;
-	double  gauss_l1l2l3[3];
-
-	/* matrices: */
-	double L[1][3];
-	double DL_scalar;
-
-	/* local element matrices: */
-	double Ke_gg[numdof][numdof]={0.0}; //local element stiffness matrix 
-	double Ke_gg_gaussian[numdof][numdof]; //stiffness matrix evaluated at the gaussian point.
-	
-	double Jdet;
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-	Matpar* matpar=NULL;
-	Matice* matice=NULL;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	matpar=(Matpar*)hmatpar.delivers();
-	matice=(Matice*)hmatice.delivers();
-
-	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
-	GetDofList(&doflist[0],&numberofdofspernode);
-
-	/* Get gaussian points and weights (make this a statically initialized list of points? fstd): */
-	GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2);
-
-	/* Start  looping on the number of gaussian points: */
-	for (ig=0; ig<num_gauss; ig++){
-		/*Pick up the gaussian point: */
-		gauss_weight=*(gauss_weights+ig);
-		gauss_l1l2l3[0]=*(first_gauss_area_coord+ig); 
-		gauss_l1l2l3[1]=*(second_gauss_area_coord+ig);
-		gauss_l1l2l3[2]=*(third_gauss_area_coord+ig);
-
-		
-		/*Get L matrix: */
-		GetL(&L[0][0], &xyz_list[0][0], gauss_l1l2l3,NDOF1);
-
-		/* Get Jacobian determinant: */
-		GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss_l1l2l3);
-		
-		DL_scalar=gauss_weight*Jdet;
-
-		/*  Do the triple producte tL*D*L: */
-		TripleMultiply( &L[0][0],1,3,1,
-					&DL_scalar,1,1,0,
-					&L[0][0],1,3,0,
-					&Ke_gg_gaussian[0][0],0);
-
-		/* Add the Ke_gg_gaussian, and optionally Ke_gg_drag_gaussian onto Ke_gg: */
-		for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg_gaussian[i][j];
-	} //for (ig=0; ig<num_gauss; ig++
-
-	/*Add Ke_gg to global matrix Kgg: */
-	MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)Ke_gg,ADD_VALUES);
-		
-	cleanup_and_return: 
-	xfree((void**)&first_gauss_area_coord);
-	xfree((void**)&second_gauss_area_coord);
-	xfree((void**)&third_gauss_area_coord);
-	xfree((void**)&gauss_weights);
-}
-/*}}}*/
-/*FUNCTION Tria::CreateKMatrixThermal {{{1*/
-void  Tria::CreateKMatrixThermal(Mat Kgg,int analysis_type,int sub_analysis_type){
-
-	int i,j;
-	int found=0;
-	
-	/* node data: */
-	const int    numgrids=3;
-	const int    NDOF1=1;
-	const int    numdof=NDOF1*numgrids;
-	double       xyz_list[numgrids][3];
-	int          doflist[numdof];
-	int          numberofdofspernode;
-
-	double mixed_layer_capacity;
-	double thermal_exchange_velocity;
-	double rho_water;
-	double rho_ice;
-	double heatcapacity;
-
-	int     num_gauss,ig;
-	double* first_gauss_area_coord  =  NULL;
-	double* second_gauss_area_coord =  NULL;
-	double* third_gauss_area_coord  =  NULL;
-	double* gauss_weights           =  NULL;
-	double  gauss_weight;
-	double  gauss_coord[3];
-
-	/*matrices: */
-	double  Jdet;
-	double  K_terms[numdof][numdof]={0.0};
-	double  Ke_gaussian[numdof][numdof]={0.0};
-	double  l1l2l3[numgrids];
-	double     tl1l2l3D[3];
-	double  D_scalar;
-
-	/*parameters: */
-	double dt;
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-	Matpar* matpar=NULL;
-	Matice* matice=NULL;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	matpar=(Matpar*)hmatpar.delivers();
-	matice=(Matice*)hmatice.delivers();
-
-	/*retrieve some parameters: */
-	this->parameters->FindParam(&dt,DtEnum);
-
-	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
-	GetDofList(&doflist[0],&numberofdofspernode);
-
-	//recover material parameters
-	mixed_layer_capacity=matpar->GetMixedLayerCapacity();
-	thermal_exchange_velocity=matpar->GetThermalExchangeVelocity();
-	rho_water=matpar->GetRhoWater();
-	rho_ice=matpar->GetRhoIce();
-	heatcapacity=matpar->GetHeatCapacity();
-
-
-	GaussTria (&num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2);
-
-	/* Start looping on the number of gauss (nodes on the bedrock) */
-	for (ig=0; ig<num_gauss; ig++){
-		gauss_weight=*(gauss_weights+ig);
-		gauss_coord[0]=*(first_gauss_area_coord+ig); 
-		gauss_coord[1]=*(second_gauss_area_coord+ig);
-		gauss_coord[2]=*(third_gauss_area_coord+ig);
-		
-		//Get the Jacobian determinant
-		GetJacobianDeterminant3d(&Jdet, &xyz_list[0][0], gauss_coord);
-		
-		/*Get nodal functions values: */
-		GetNodalFunctions(&l1l2l3[0], gauss_coord);
-				
-		/*Calculate DL on gauss point */
-		D_scalar=gauss_weight*Jdet*rho_water*mixed_layer_capacity*thermal_exchange_velocity/(heatcapacity*rho_ice);
-		if(dt){
-			D_scalar=dt*D_scalar;
-		}
-
-		/*  Do the triple product tL*D*L: */
-		MatrixMultiply(&l1l2l3[0],numdof,1,0,&D_scalar,1,1,0,&tl1l2l3D[0],0);
-		MatrixMultiply(&tl1l2l3D[0],numdof,1,0,&l1l2l3[0],1,numdof,0,&Ke_gaussian[0][0],0);
-
-		for(i=0;i<3;i++){
-			for(j=0;j<3;j++){
-				K_terms[i][j]+=Ke_gaussian[i][j];
-			}
-		}
-	}
-	
-	/*Add Ke_gg to global matrix Kgg: */
-	MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)K_terms,ADD_VALUES);
-
-	cleanup_and_return:
-	xfree((void**)&first_gauss_area_coord);
-	xfree((void**)&second_gauss_area_coord);
-	xfree((void**)&third_gauss_area_coord);
-	xfree((void**)&gauss_weights);
-
-}
-/*}}}*/
-/*FUNCTION Tria::CreatePVector {{{1*/
-void  Tria::CreatePVector(Vec pg,int analysis_type,int sub_analysis_type){
-	
-	/*Just branch to the correct load generator, according to the type of analysis we are carrying out: */
-	if (analysis_type==ControlAnalysisEnum){
-		
-		CreatePVectorDiagnosticHoriz( pg,analysis_type,sub_analysis_type);
-	
-	}
-	else if (analysis_type==DiagnosticAnalysisEnum){
-		if (sub_analysis_type==HorizAnalysisEnum){
-		
-			CreatePVectorDiagnosticHoriz( pg,analysis_type,sub_analysis_type);
-		}
-		else ISSMERROR("%s%i%s\n","sub_analysis: ",sub_analysis_type," not supported yet");
-	}
-	else if (analysis_type==SlopecomputeAnalysisEnum){
-		
-		CreatePVectorSlopeCompute( pg,analysis_type,sub_analysis_type);
-	}
-	else if (analysis_type==PrognosticAnalysisEnum){
-
-		CreatePVectorPrognostic( pg,analysis_type,sub_analysis_type);
-	}
-	else if (analysis_type==Prognostic2AnalysisEnum){
-
-		CreatePVectorPrognostic2( pg,analysis_type,sub_analysis_type);
-	}
-	else if (analysis_type==BalancedthicknessAnalysisEnum){
-
-		CreatePVectorBalancedthickness( pg,analysis_type,sub_analysis_type);
-	}
-	else if (analysis_type==Balancedthickness2AnalysisEnum){
-
-		CreatePVectorBalancedthickness2( pg,analysis_type,sub_analysis_type);
-	}
-	else if (analysis_type==BalancedvelocitiesAnalysisEnum){
-
-		CreatePVectorBalancedvelocities( pg,analysis_type,sub_analysis_type);
-	}
-	else{
-		ISSMERROR("%s%i%s"," analysis ",analysis_type," not supported yet");
-	}
-
-}
-/*}}}*/
-/*FUNCTION Tria::CreatePVectorBalancedthickness {{{1*/
-void  Tria::CreatePVectorBalancedthickness(Vec pg ,int analysis_type,int sub_analysis_type){
-
-
-	/* local declarations */
-	int             i,j;
-
-	/* node data: */
-	const int    numgrids=3;
-	const int    NDOF1=1;
-	const int    numdof=NDOF1*numgrids;
-	double       xyz_list[numgrids][3];
-	int          doflist[numdof];
-	int          numberofdofspernode;
-
-	/* gaussian points: */
-	int     num_gauss,ig;
-	double* first_gauss_area_coord  =  NULL;
-	double* second_gauss_area_coord =  NULL;
-	double* third_gauss_area_coord  =  NULL;
-	double* gauss_weights           =  NULL;
-	double  gauss_weight;
-	double  gauss_l1l2l3[3];
-
-	/* matrix */
-	double pe_g[numgrids]={0.0};
-	double L[numgrids];
-	double Jdettria;
-
-	/*input parameters for structural analysis (diagnostic): */
-	double  accumulation_g;
-	double  melting_g;
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-	Matpar* matpar=NULL;
-	Matice* matice=NULL;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	matpar=(Matpar*)hmatpar.delivers();
-	matice=(Matice*)hmatice.delivers();
-
-	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
-	GetDofList(&doflist[0],&numberofdofspernode);
-
-	/* Get gaussian points and weights (make this a statically initialized list of points? fstd): */
-	GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2);
-
-	/* Start  looping on the number of gaussian points: */
-	for (ig=0; ig<num_gauss; ig++){
-		/*Pick up the gaussian point: */
-		gauss_weight=*(gauss_weights+ig);
-		gauss_l1l2l3[0]=*(first_gauss_area_coord+ig); 
-		gauss_l1l2l3[1]=*(second_gauss_area_coord+ig);
-		gauss_l1l2l3[2]=*(third_gauss_area_coord+ig);
-
-		/* Get Jacobian determinant: */
-		GetJacobianDeterminant2d(&Jdettria, &xyz_list[0][0],gauss_l1l2l3);
-
-		/*Get L matrix: */
-		GetL(&L[0], &xyz_list[0][0], gauss_l1l2l3,numberofdofspernode);
-
-		/* Get accumulation, melting at gauss point */
-		inputs->GetParameterValue(&accumulation_g, &gauss_l1l2l3[0],AccumulationRateEnum);
-		inputs->GetParameterValue(&melting_g, &gauss_l1l2l3[0],MeltingRateEnum);
-
-		/* Add value into pe_g: */
-		for( i=0; i<numdof; i++) pe_g[i]+=Jdettria*gauss_weight*(accumulation_g-melting_g)*L[i];
-
-	} // for (ig=0; ig<num_gauss; ig++)
-
-	/*Add pe_g to global matrix Kgg: */
-	VecSetValues(pg,numdof,doflist,(const double*)pe_g,ADD_VALUES);
-
-cleanup_and_return: 
-	xfree((void**)&first_gauss_area_coord);
-	xfree((void**)&second_gauss_area_coord);
-	xfree((void**)&third_gauss_area_coord);
-	xfree((void**)&gauss_weights);
-
-}
-/*}}}*/
-/*FUNCTION Tria::CreatePVectorBalancedthickness2 {{{1*/
-void  Tria::CreatePVectorBalancedthickness2(Vec pg ,int analysis_type,int sub_analysis_type){
-
-
-	/* local declarations */
-	int             i,j;
-
-	/* node data: */
-	const int    numgrids=3;
-	const int    NDOF1=1;
-	const int    numdof=NDOF1*numgrids;
-	double       xyz_list[numgrids][3];
-	int          doflist[numdof];
-	int          numberofdofspernode;
-
-	/* gaussian points: */
-	int     num_gauss,ig;
-	double* first_gauss_area_coord  =  NULL;
-	double* second_gauss_area_coord =  NULL;
-	double* third_gauss_area_coord  =  NULL;
-	double* gauss_weights           =  NULL;
-	double  gauss_weight;
-	double  gauss_l1l2l3[3];
-
-	/* matrix */
-	double pe_g[numgrids]={0.0};
-	double L[numgrids];
-	double Jdettria;
-
-	/*input parameters for structural analysis (diagnostic): */
-	double  accumulation_g;
-	double  melting_g;
-	double  dhdt_g;
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-	Matpar* matpar=NULL;
-	Matice* matice=NULL;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)   hnodes.deliverp();
-	matpar=(Matpar*)hmatpar.delivers();
-	matice=(Matice*)hmatice.delivers();
-
-	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
-	GetDofList(&doflist[0],&numberofdofspernode);
-
-	/* Get gaussian points and weights (make this a statically initialized list of points? fstd): */
-	GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2);
-
-	/* Start  looping on the number of gaussian points: */
-	for (ig=0; ig<num_gauss; ig++){
-		/*Pick up the gaussian point: */
-		gauss_weight=*(gauss_weights+ig);
-		gauss_l1l2l3[0]=*(first_gauss_area_coord+ig); 
-		gauss_l1l2l3[1]=*(second_gauss_area_coord+ig);
-		gauss_l1l2l3[2]=*(third_gauss_area_coord+ig);
-
-		/* Get Jacobian determinant: */
-		GetJacobianDeterminant2d(&Jdettria, &xyz_list[0][0],gauss_l1l2l3);
-
-		/*Get L matrix: */
-		GetL(&L[0], &xyz_list[0][0], gauss_l1l2l3,numberofdofspernode);
-
-		/* Get accumulation, melting and thickness at gauss point */
-		inputs->GetParameterValue(&accumulation_g, &gauss_l1l2l3[0],AccumulationRateEnum);
-		inputs->GetParameterValue(&melting_g, &gauss_l1l2l3[0],MeltingRateEnum);
-		inputs->GetParameterValue(&dhdt_g, &gauss_l1l2l3[0],DhDtEnum);
-
-		/* Add value into pe_g: */
-		for( i=0; i<numdof; i++) pe_g[i]+=Jdettria*gauss_weight*(accumulation_g-melting_g+dhdt_g)*L[i];
-
-	} // for (ig=0; ig<num_gauss; ig++)
-
-	/*Add pe_g to global matrix Kgg: */
-	VecSetValues(pg,numdof,doflist,(const double*)pe_g,ADD_VALUES);
-
-cleanup_and_return: 
-	xfree((void**)&first_gauss_area_coord);
-	xfree((void**)&second_gauss_area_coord);
-	xfree((void**)&third_gauss_area_coord);
-	xfree((void**)&gauss_weights);
-
-}
-/*}}}*/
-/*FUNCTION Tria::CreatePVectorBalancedvelocities {{{1*/
-void  Tria::CreatePVectorBalancedvelocities(Vec pg ,int analysis_type,int sub_analysis_type){
-
-
-	/* local declarations */
-	int             i,j;
-
-	/* node data: */
-	const int    numgrids=3;
-	const int    NDOF1=1;
-	const int    numdof=NDOF1*numgrids;
-	double       xyz_list[numgrids][3];
-	int          doflist[numdof];
-	int          numberofdofspernode;
-
-	/* gaussian points: */
-	int     num_gauss,ig;
-	double* first_gauss_area_coord  =  NULL;
-	double* second_gauss_area_coord =  NULL;
-	double* third_gauss_area_coord  =  NULL;
-	double* gauss_weights           =  NULL;
-	double  gauss_weight;
-	double  gauss_l1l2l3[3];
-
-	/* matrix */
-	double pe_g[numgrids]={0.0};
-	double L[numgrids];
-	double Jdettria;
-
-	/*input parameters for structural analysis (diagnostic): */
-	double  accumulation_g;
-	double  melting_g;
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-	Matpar* matpar=NULL;
-	Matice* matice=NULL;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	matpar=(Matpar*)hmatpar.delivers();
-	matice=(Matice*)hmatice.delivers();
-
-	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
-	GetDofList(&doflist[0],&numberofdofspernode);
-
-	/* Get gaussian points and weights (make this a statically initialized list of points? fstd): */
-	GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2);
-
-	/* Start  looping on the number of gaussian points: */
-	for (ig=0; ig<num_gauss; ig++){
-		/*Pick up the gaussian point: */
-		gauss_weight=*(gauss_weights+ig);
-		gauss_l1l2l3[0]=*(first_gauss_area_coord+ig); 
-		gauss_l1l2l3[1]=*(second_gauss_area_coord+ig);
-		gauss_l1l2l3[2]=*(third_gauss_area_coord+ig);
-
-		/* Get Jacobian determinant: */
-		GetJacobianDeterminant2d(&Jdettria, &xyz_list[0][0],gauss_l1l2l3);
-
-		/*Get L matrix: */
-		GetL(&L[0], &xyz_list[0][0], gauss_l1l2l3,numberofdofspernode);
-
-		/* Get accumulation, melting at gauss point */
-		inputs->GetParameterValue(&accumulation_g, &gauss_l1l2l3[0],AccumulationRateEnum);
-		inputs->GetParameterValue(&melting_g, &gauss_l1l2l3[0],MeltingRateEnum);
-
-		/* Add value into pe_g: */
-		for( i=0; i<numdof; i++) pe_g[i]+=Jdettria*gauss_weight*(accumulation_g-melting_g)*L[i];
-
-	} // for (ig=0; ig<num_gauss; ig++)
-
-	/*Add pe_g to global matrix Kgg: */
-	VecSetValues(pg,numdof,doflist,(const double*)pe_g,ADD_VALUES);
-
-cleanup_and_return: 
-	xfree((void**)&first_gauss_area_coord);
-	xfree((void**)&second_gauss_area_coord);
-	xfree((void**)&third_gauss_area_coord);
-	xfree((void**)&gauss_weights);
-
-}
-/*}}}*/
-/*FUNCTION Tria::CreatePVectorDiagnosticBaseVert {{{1*/
-void  Tria::CreatePVectorDiagnosticBaseVert(Vec pg,int analysis_type,int sub_analysis_type){
-
-	int             i,j;
-
-	/* node data: */
-	const int    numgrids=3;
-	const int    NDOF1=1;
-	const int    numdof=NDOF1*numgrids;
-	double       xyz_list[numgrids][3];
-	int          doflist[numdof];
-	int          numberofdofspernode;
-
-	/* gaussian points: */
-	int     num_gauss,ig;
-	double* first_gauss_area_coord  =  NULL;
-	double* second_gauss_area_coord =  NULL;
-	double* third_gauss_area_coord  =  NULL;
-	double* gauss_weights           =  NULL;
-	double  gauss_weight;
-	double  gauss_l1l2l3[3];
-
-	/* Jacobian: */
-	double Jdet;
-
-	/*nodal functions: */
-	double l1l2l3[3];
-
-	/*element vector at the gaussian points: */
-	double  pe_g[numdof]={0.0};
-	double  pe_g_gaussian[numdof];
-
-	/* matrices: */
-	double L[numgrids];
-
-	/*input parameters for structural analysis (diagnostic): */
-	double  vx,vy;
-	double  meltingvalue;
-	double  slope[2];
-	double  dbdx,dbdy;
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-	Matpar* matpar=NULL;
-	Matice* matice=NULL;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	matpar=(Matpar*)hmatpar.delivers();
-	matice=(Matice*)hmatice.delivers();
-
-	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
-	GetDofList(&doflist[0],&numberofdofspernode);
-
-	/* Get gaussian points and weights (make this a statically initialized list of points? fstd): */
-	GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2);
-
-	/*For icesheets: */
-	/* Start  looping on the number of gaussian points: */
-	for (ig=0; ig<num_gauss; ig++){
-
-		/*Pick up the gaussian point: */
-		gauss_weight=*(gauss_weights+ig);
-		gauss_l1l2l3[0]=*(first_gauss_area_coord+ig); 
-		gauss_l1l2l3[1]=*(second_gauss_area_coord+ig);
-		gauss_l1l2l3[2]=*(third_gauss_area_coord+ig);
-
-		/*Get melting at gaussian point: */
-		inputs->GetParameterValue(&meltingvalue, &gauss_l1l2l3[0],MeltingRateEnum);
-
-		/*Get velocity at gaussian point: */
-		inputs->GetParameterValue(&vx, &gauss_l1l2l3[0],VxEnum);
-		inputs->GetParameterValue(&vy, &gauss_l1l2l3[0],VyEnum);
-
-		/*Get bed slope: */
-		inputs->GetParameterDerivativeValue(&slope[0],&xyz_list[0][0],&gauss_l1l2l3[0],BedEnum);
-		dbdx=slope[0];
-		dbdy=slope[1];
-
-		/* Get Jacobian determinant: */
-		GetJacobianDeterminant3d(&Jdet, &xyz_list[0][0],gauss_l1l2l3);
-
-		//Get L matrix if viscous basal drag present:
-		GetL(&L[0], &xyz_list[0][0], gauss_l1l2l3,NDOF1);
-
-
-		/*Build gaussian vector: */
-		for(i=0;i<numgrids;i++){
-			pe_g_gaussian[i]=-Jdet*gauss_weight*(vx*dbdx+vy*dbdy-meltingvalue)*L[i];
-		}
-
-		/*Add pe_g_gaussian vector to pe_g: */
-		for( i=0; i<numdof; i++)pe_g[i]+=pe_g_gaussian[i];
-
-	}
-
-	/*Add pe_g to global vector pg: */
-	VecSetValues(pg,numdof,doflist,(const double*)pe_g,ADD_VALUES);
-
-cleanup_and_return: 
-	xfree((void**)&first_gauss_area_coord);
-	xfree((void**)&second_gauss_area_coord);
-	xfree((void**)&third_gauss_area_coord);
-	xfree((void**)&gauss_weights);
-
-}
-/*}}}*/
-/*FUNCTION Tria::CreatePVectorDiagnosticHoriz {{{1*/
-void Tria::CreatePVectorDiagnosticHoriz( Vec pg,  int analysis_type,int sub_analysis_type){
-
-	int             i,j;
-
-	/* node data: */
-	const int    numgrids=3;
-	const int    numdof=2*numgrids;
-	const int    NDOF2=2;
-	double       xyz_list[numgrids][3];
-	int          doflist[numdof];
-	int          numberofdofspernode;
-	
-	/* parameters: */
-	double  plastic_stress; 
-	double  slope[NDOF2];
-	double  driving_stress_baseline;
-
-	/* gaussian points: */
-	int     num_gauss,ig;
-	double* first_gauss_area_coord  =  NULL;
-	double* second_gauss_area_coord =  NULL;
-	double* third_gauss_area_coord  =  NULL;
-	double* gauss_weights           =  NULL;
-	double  gauss_weight;
-	double  gauss_l1l2l3[3];
-
-	/* Jacobian: */
-	double Jdet;
-
-	/*nodal functions: */
-	double l1l2l3[3];
-
-	/*element vector at the gaussian points: */
-	double  pe_g[numdof]={0.0};
-	double  pe_g_gaussian[numdof];
-
-	/*input parameters for structural analysis (diagnostic): */
-	double  thickness;
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-	Matpar* matpar=NULL;
-	Matice* matice=NULL;
-
-	/*inputs: */
-	bool onwater;
-	int  drag_type;
-
-	/*retrieve inputs :*/
-	inputs->GetParameterValue(&onwater,ElementOnWaterEnum);
-	inputs->GetParameterValue(&drag_type,DragTypeEnum);
-
-	/*First, if we are on water, return empty vector: */
-	if(onwater)return;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	matpar=(Matpar*)hmatpar.delivers();
-	matice=(Matice*)hmatice.delivers();
-
-	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
-	GetDofList(&doflist[0],&numberofdofspernode);
-
-
-	/* Get gaussian points and weights: */
-	GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2); /*We need higher order because our load is order 2*/
-
-	/* Start  looping on the number of gaussian points: */
-	for (ig=0; ig<num_gauss; ig++){
-		/*Pick up the gaussian point: */
-		gauss_weight=*(gauss_weights+ig);
-		gauss_l1l2l3[0]=*(first_gauss_area_coord+ig); 
-		gauss_l1l2l3[1]=*(second_gauss_area_coord+ig);
-		gauss_l1l2l3[2]=*(third_gauss_area_coord+ig);
-
-		/*Compute thickness at gaussian point: */
-		inputs->GetParameterValue(&thickness, &gauss_l1l2l3[0],ThicknessEnum);
-		inputs->GetParameterDerivativeValue(&slope[0],&xyz_list[0][0],&gauss_l1l2l3[0],SurfaceEnum);
-		
-		/*In case we have plastic basal drag, compute plastic stress at gaussian point from k1, k2 and k3 fields in the 
-		 * element itself: */
-		if(drag_type==1){
-			inputs->GetParameterValue(&plastic_stress, &gauss_l1l2l3[0],DragCoefficientEnum);
-		}
-
-		/* Get Jacobian determinant: */
-		GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss_l1l2l3);
-		
-		 /*Get nodal functions: */
-		GetNodalFunctions(l1l2l3, gauss_l1l2l3);
-
-		/*Compute driving stress: */
-		driving_stress_baseline=matpar->GetRhoIce()*matpar->GetG()*thickness;
-
-		/*Build pe_g_gaussian vector: */
-		if(drag_type==1){
-			for (i=0;i<numgrids;i++){
-				for (j=0;j<NDOF2;j++){
-					pe_g_gaussian[i*NDOF2+j]=(-driving_stress_baseline*slope[j]-plastic_stress)*Jdet*gauss_weight*l1l2l3[i]; 
-				}
-			}
-		}
-		else {
-			for (i=0;i<numgrids;i++){
-				for (j=0;j<NDOF2;j++){
-					pe_g_gaussian[i*NDOF2+j]=-driving_stress_baseline*slope[j]*Jdet*gauss_weight*l1l2l3[i];
-				}
-			}
-		}
-
-		/*Add pe_g_gaussian vector to pe_g: */
-		for( i=0; i<numdof; i++)pe_g[i]+=pe_g_gaussian[i];
-
-	} //for (ig=0; ig<num_gauss; ig++)
-
-	/*Add pe_g to global vector pg: */
-	VecSetValues(pg,numdof,doflist,(const double*)pe_g,ADD_VALUES);
-
-	cleanup_and_return: 
-	xfree((void**)&first_gauss_area_coord);
-	xfree((void**)&second_gauss_area_coord);
-	xfree((void**)&third_gauss_area_coord);
-	xfree((void**)&gauss_weights);
-
-}
-/*}}}*/
-/*FUNCTION Tria::CreatePVectorPrognostic {{{1*/
-void  Tria::CreatePVectorPrognostic(Vec pg ,int analysis_type,int sub_analysis_type){
-
-
-	/* local declarations */
-	int             i,j;
-
-	/* node data: */
-	const int    numgrids=3;
-	const int    NDOF1=1;
-	const int    numdof=NDOF1*numgrids;
-	double       xyz_list[numgrids][3];
-	int          doflist[numdof];
-	int          numberofdofspernode;
-
-	/* gaussian points: */
-	int     num_gauss,ig;
-	double* first_gauss_area_coord  =  NULL;
-	double* second_gauss_area_coord =  NULL;
-	double* third_gauss_area_coord  =  NULL;
-	double* gauss_weights           =  NULL;
-	double  gauss_weight;
-	double  gauss_l1l2l3[3];
-
-	/* matrix */
-	double pe_g[numgrids]={0.0};
-	double L[numgrids];
-	double Jdettria;
-
-	/*input parameters for structural analysis (diagnostic): */
-	double  accumulation_g;
-	double  melting_g;
-	double  thickness_g;
-
-	/*parameters: */
-	double  dt;
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-	Matpar* matpar=NULL;
-	Matice* matice=NULL;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	matpar=(Matpar*)hmatpar.delivers();
-	matice=(Matice*)hmatice.delivers();
-
-	/*retrieve some parameters: */
-	this->parameters->FindParam(&dt,DtEnum);
-
-	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
-	GetDofList(&doflist[0],&numberofdofspernode);
-
-	/* Get gaussian points and weights (make this a statically initialized list of points? fstd): */
-	GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2);
-
-	/* Start  looping on the number of gaussian points: */
-	for (ig=0; ig<num_gauss; ig++){
-		/*Pick up the gaussian point: */
-		gauss_weight=*(gauss_weights+ig);
-		gauss_l1l2l3[0]=*(first_gauss_area_coord+ig); 
-		gauss_l1l2l3[1]=*(second_gauss_area_coord+ig);
-		gauss_l1l2l3[2]=*(third_gauss_area_coord+ig);
-
-		/* Get Jacobian determinant: */
-		GetJacobianDeterminant2d(&Jdettria, &xyz_list[0][0],gauss_l1l2l3);
-
-		/*Get L matrix: */
-		GetL(&L[0], &xyz_list[0][0], gauss_l1l2l3,numberofdofspernode);
-
-		/* Get accumulation, melting and thickness at gauss point */
-		inputs->GetParameterValue(&accumulation_g, &gauss_l1l2l3[0],AccumulationRateEnum);
-		inputs->GetParameterValue(&melting_g, &gauss_l1l2l3[0],MeltingRateEnum);
-		inputs->GetParameterValue(&thickness_g, &gauss_l1l2l3[0],ThicknessEnum);
-
-		/* Add value into pe_g: */
-		for( i=0; i<numdof; i++) pe_g[i]+=Jdettria*gauss_weight*(thickness_g+dt*(accumulation_g-melting_g))*L[i];
-
-	} // for (ig=0; ig<num_gauss; ig++)
-
-	/*Add pe_g to global matrix Kgg: */
-	VecSetValues(pg,numdof,doflist,(const double*)pe_g,ADD_VALUES);
-
-cleanup_and_return: 
-	xfree((void**)&first_gauss_area_coord);
-	xfree((void**)&second_gauss_area_coord);
-	xfree((void**)&third_gauss_area_coord);
-	xfree((void**)&gauss_weights);
-
-}
-/*}}}*/
-/*FUNCTION Tria::CreatePVectorPrognostic2 {{{1*/
-void  Tria::CreatePVectorPrognostic2(Vec pg ,int analysis_type,int sub_analysis_type){
-
-	/* local declarations */
-	int             i,j;
-
-	/* node data: */
-	const int    numgrids=3;
-	const int    NDOF1=1;
-	const int    numdof=NDOF1*numgrids;
-	double       xyz_list[numgrids][3];
-	int          doflist[numdof];
-	int          numberofdofspernode;
-
-	/* gaussian points: */
-	int     num_gauss,ig;
-	double* first_gauss_area_coord  =  NULL;
-	double* second_gauss_area_coord =  NULL;
-	double* third_gauss_area_coord  =  NULL;
-	double* gauss_weights           =  NULL;
-	double  gauss_weight;
-	double  gauss_l1l2l3[3];
-
-	/* matrix */
-	double pe_g[numgrids]={0.0};
-	double L[numgrids];
-	double Jdettria;
-
-	/*input parameters for structural analysis (diagnostic): */
-	double  accumulation_g;
-	double  melting_g;
-	double  thickness_g;
-	double  dt;
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-	Matpar* matpar=NULL;
-	Matice* matice=NULL;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	matpar=(Matpar*)hmatpar.delivers();
-	matice=(Matice*)hmatice.delivers();
-
-	/*retrieve some parameters: */
-	this->parameters->FindParam(&dt,DtEnum);
-
-	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
-	GetDofList(&doflist[0],&numberofdofspernode);
-
-	/* Get gaussian points and weights (make this a statically initialized list of points? fstd): */
-	GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2);
-
-	/* Start  looping on the number of gaussian points: */
-	for (ig=0; ig<num_gauss; ig++){
-		/*Pick up the gaussian point: */
-		gauss_weight=*(gauss_weights+ig);
-		gauss_l1l2l3[0]=*(first_gauss_area_coord+ig); 
-		gauss_l1l2l3[1]=*(second_gauss_area_coord+ig);
-		gauss_l1l2l3[2]=*(third_gauss_area_coord+ig);
-
-		/* Get Jacobian determinant: */
-		GetJacobianDeterminant2d(&Jdettria, &xyz_list[0][0],gauss_l1l2l3);
-
-		/*Get L matrix: */
-		GetL(&L[0], &xyz_list[0][0], gauss_l1l2l3,numberofdofspernode);
-
-		/* Get accumulation, melting and thickness at gauss point */
-		inputs->GetParameterValue(&accumulation_g, &gauss_l1l2l3[0],AccumulationRateEnum);
-		inputs->GetParameterValue(&melting_g, &gauss_l1l2l3[0],MeltingRateEnum);
-		inputs->GetParameterValue(&thickness_g, &gauss_l1l2l3[0],ThicknessEnum);
-
-		/* Add value into pe_g: */
-		for( i=0; i<numdof; i++) pe_g[i]+=Jdettria*gauss_weight*(thickness_g+dt*(accumulation_g-melting_g))*L[i];
-
-	} // for (ig=0; ig<num_gauss; ig++)
-
-	/*Add pe_g to global matrix Kgg: */
-	VecSetValues(pg,numdof,doflist,(const double*)pe_g,ADD_VALUES);
-
-cleanup_and_return: 
-	xfree((void**)&first_gauss_area_coord);
-	xfree((void**)&second_gauss_area_coord);
-	xfree((void**)&third_gauss_area_coord);
-	xfree((void**)&gauss_weights);
-
-}
-/*}}}*/
-/*FUNCTION Tria::CreatePVectorSlopeCompute {{{1*/
-
-void Tria::CreatePVectorSlopeCompute( Vec pg,  int analysis_type,int sub_analysis_type){
-
-	int             i,j;
-
-	/* node data: */
-	const int    numgrids=3;
-	const int    NDOF1=1;
-	const int    numdof=NDOF1*numgrids;
-	double       xyz_list[numgrids][3];
-	int          doflist[numdof];
-	int          numberofdofspernode;
-	
-	/* gaussian points: */
-	int     num_gauss,ig;
-	double* first_gauss_area_coord  =  NULL;
-	double* second_gauss_area_coord =  NULL;
-	double* third_gauss_area_coord  =  NULL;
-	double* gauss_weights           =  NULL;
-	double  gauss_weight;
-	double  gauss_l1l2l3[3];
-
-	/* Jacobian: */
-	double Jdet;
-
-	/*nodal functions: */
-	double l1l2l3[3];
-
-	/*element vector at the gaussian points: */
-	double  pe_g[numdof]={0.0};
-	double  pe_g_gaussian[numdof];
-	double  slope[2];
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-	Matpar* matpar=NULL;
-	Matice* matice=NULL;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	matpar=(Matpar*)hmatpar.delivers();
-	matice=(Matice*)hmatice.delivers();
-
-	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
-	GetDofList(&doflist[0],&numberofdofspernode);
-
-
-	/* Get gaussian points and weights: */
-	GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2); /*We need higher order because our load is order 2*/
-
-
-	/* Start  looping on the number of gaussian points: */
-	for (ig=0; ig<num_gauss; ig++){
-		/*Pick up the gaussian point: */
-		gauss_weight=*(gauss_weights+ig);
-		gauss_l1l2l3[0]=*(first_gauss_area_coord+ig); 
-		gauss_l1l2l3[1]=*(second_gauss_area_coord+ig);
-		gauss_l1l2l3[2]=*(third_gauss_area_coord+ig);
-
-		if ( (sub_analysis_type==SurfaceXAnalysisEnum) || (sub_analysis_type==SurfaceYAnalysisEnum)){
-			inputs->GetParameterDerivativeValue(&slope[0],&xyz_list[0][0],&gauss_l1l2l3[0],SurfaceEnum);
-		}
-		if ( (sub_analysis_type==BedXAnalysisEnum) || (sub_analysis_type==BedYAnalysisEnum)){
-			inputs->GetParameterDerivativeValue(&slope[0],&xyz_list[0][0],&gauss_l1l2l3[0],BedEnum);
-		}
-
-		/* Get Jacobian determinant: */
-		GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss_l1l2l3);
-		
-		 /*Get nodal functions: */
-		GetNodalFunctions(l1l2l3, gauss_l1l2l3);
-
-		/*Build pe_g_gaussian vector: */
-		if ( (sub_analysis_type==SurfaceXAnalysisEnum) || (sub_analysis_type==BedXAnalysisEnum)){
-			for(i=0;i<numdof;i++) pe_g_gaussian[i]=Jdet*gauss_weight*slope[0]*l1l2l3[i];
-		}
-		if ( (sub_analysis_type==SurfaceYAnalysisEnum) || (sub_analysis_type==BedYAnalysisEnum)){
-			for(i=0;i<numdof;i++) pe_g_gaussian[i]=Jdet*gauss_weight*slope[1]*l1l2l3[i];
-		}
-
-		/*Add pe_g_gaussian vector to pe_g: */
-		for( i=0; i<numdof; i++)pe_g[i]+=pe_g_gaussian[i];
-
-	} //for (ig=0; ig<num_gauss; ig++)
-
-	/*Add pe_g to global vector pg: */
-	VecSetValues(pg,numdof,doflist,(const double*)pe_g,ADD_VALUES);
-
-	cleanup_and_return: 
-	xfree((void**)&first_gauss_area_coord);
-	xfree((void**)&second_gauss_area_coord);
-	xfree((void**)&third_gauss_area_coord);
-	xfree((void**)&gauss_weights);
-
-}
-/*}}}*/
-/*FUNCTION Tria::CreatePVectorThermalShelf {{{1*/
-void Tria::CreatePVectorThermalShelf( Vec pg,  int analysis_type,int sub_analysis_type){
-
-	int i,found;
-	
-	const int  numgrids=3;
-	const int  NDOF1=1;
-	const int  numdof=numgrids*NDOF1;
-	int        doflist[numdof];
-	int        numberofdofspernode;
-	double       xyz_list[numgrids][3];
-
-	double mixed_layer_capacity;
-	double thermal_exchange_velocity;
-	double rho_water;
-	double rho_ice;
-	double heatcapacity;
-	double beta;
-	double meltingpoint;
-
-	/*inputs: */
-	double dt;
-	double pressure;
-
-	/* gaussian points: */
-	int     num_area_gauss,ig;
-	double* gauss_weights  =  NULL;
-	double* first_gauss_area_coord  =  NULL;
-	double* second_gauss_area_coord =  NULL;
-	double* third_gauss_area_coord  =  NULL;
-	double  gauss_weight;
-	double  gauss_coord[3];
-	int     dofs1[1]={0};
-
-	/*matrices: */
-	double  Jdet;
-	double  P_terms[numdof]={0.0};
-	double  l1l2l3[numgrids];
-
-	double  t_pmp;
-	double  scalar_ocean;
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-	Matpar* matpar=NULL;
-	Matice* matice=NULL;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	matpar=(Matpar*)hmatpar.delivers();
-	matice=(Matice*)hmatice.delivers();
-	
-	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
-	GetDofList(&doflist[0],&numberofdofspernode);
-
-	//recover material parameters
-	mixed_layer_capacity=matpar->GetMixedLayerCapacity();
-	thermal_exchange_velocity=matpar->GetThermalExchangeVelocity();
-	rho_water=matpar->GetRhoWater();
-	rho_ice=matpar->GetRhoIce();
-	heatcapacity=matpar->GetHeatCapacity();
-	beta=matpar->GetBeta();
-	meltingpoint=matpar->GetMeltingPoint();
-	
-	/*retrieve some solution parameters: */
-	this->parameters->FindParam(&dt,DtEnum);
-
-	/* Ice/ocean heat exchange flux on ice shelf base */
-
-	GaussTria (&num_area_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2);
-
-	/* Start looping on the number of gauss 2d (nodes on the bedrock) */
-	for (ig=0; ig<num_area_gauss; ig++){
-		gauss_weight=*(gauss_weights+ig);
-		gauss_coord[0]=*(first_gauss_area_coord+ig); 
-		gauss_coord[1]=*(second_gauss_area_coord+ig);
-		gauss_coord[2]=*(third_gauss_area_coord+ig);
-
-		//Get the Jacobian determinant
-		GetJacobianDeterminant3d(&Jdet, &xyz_list[0][0], gauss_coord);
-
-		/*Get nodal functions values: */
-		GetNodalFunctions(&l1l2l3[0], gauss_coord);
-
-		/*Get geothermal flux and basal friction */
-		inputs->GetParameterValue(&pressure, &gauss_coord[0],PressureEnum);
-		t_pmp=meltingpoint-beta*pressure;
-
-		/*Calculate scalar parameter*/
-		scalar_ocean=gauss_weight*Jdet*rho_water*mixed_layer_capacity*thermal_exchange_velocity*(t_pmp)/(heatcapacity*rho_ice);
-		if(dt){
-			scalar_ocean=dt*scalar_ocean;
-		}
-
-		for(i=0;i<3;i++){
-			P_terms[i]+=scalar_ocean*l1l2l3[i];
-		}
-	}
-
-	/*Add pe_g to global vector pg: */
-	VecSetValues(pg,numdof,doflist,(const double*)P_terms,ADD_VALUES);
-
-	cleanup_and_return: 
-	xfree((void**)&first_gauss_area_coord);
-	xfree((void**)&second_gauss_area_coord);
-	xfree((void**)&third_gauss_area_coord);
-	xfree((void**)&gauss_weights);
-
-}
-/*}}}*/
-/*FUNCTION Tria::CreatePVectorThermalSheet {{{1*/
-void Tria::CreatePVectorThermalSheet( Vec pg,  int analysis_type,int sub_analysis_type){
-
-	int i,found;
-	
-	const int  numgrids=3;
-	const int  NDOF1=1;
-	const int  numdof=numgrids*NDOF1;
-	int        doflist[numdof];
-	int        numberofdofspernode;
-	double       xyz_list[numgrids][3];
-
-	double rho_ice;
-	double heatcapacity;
-
-	/*inputs: */
-	double dt;
-	double pressure_list[3];
-	double pressure;
-	double alpha2_list[3];
-	double basalfriction_list[3];
-	double basalfriction;
-	double geothermalflux_value;
-
-	double  vx_list[numgrids];
-	double  vy_list[numgrids];
-	double  thickness_list[numgrids];
-	double  bed_list[numgrids];
-	double  dragcoefficient_list[numgrids];
-	double  drag_p,drag_q;
-	int     drag_type;
-
-	/* gaussian points: */
-	int     num_area_gauss,ig;
-	double* gauss_weights  =  NULL;
-	double* first_gauss_area_coord  =  NULL;
-	double* second_gauss_area_coord =  NULL;
-	double* third_gauss_area_coord  =  NULL;
-	double  gauss_weight;
-	double  gauss_coord[3];
-	double  gaussgrids[numgrids][numgrids]={{1,0,0},{0,1,0},{0,0,1}};
-
-	/*matrices: */
-	double  Jdet;
-	double  P_terms[numdof]={0.0};
-	double  l1l2l3[numgrids];
-	double  scalar;
-
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-	Matpar* matpar=NULL;
-	Matice* matice=NULL;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	matpar=(Matpar*)hmatpar.delivers();
-	matice=(Matice*)hmatice.delivers();
-
-	/*retrieve inputs :*/
-	inputs->GetParameterValue(&drag_type,DragTypeEnum);
-	
-	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
-	GetDofList(&doflist[0],&numberofdofspernode);
-
-	//recover material parameters
-	rho_ice=matpar->GetRhoIce();
-	heatcapacity=matpar->GetHeatCapacity();
-
-	/*retrieve some parameters: */
-	this->parameters->FindParam(&dt,DtEnum);
-
-
-	/*Recover inputs: */
-	inputs->GetParameterValues(&vx_list[0],&gaussgrids[0][0],3,VxAverageEnum);
-	inputs->GetParameterValues(&vy_list[0],&gaussgrids[0][0],3,VyAverageEnum);
-	inputs->GetParameterValues(&dragcoefficient_list[0],&gaussgrids[0][0],3,DragCoefficientEnum);
-	inputs->GetParameterValues(&bed_list[0],&gaussgrids[0][0],3,BedEnum);
-	inputs->GetParameterValues(&thickness_list[0],&gaussgrids[0][0],3,ThicknessEnum);
-	inputs->GetParameterValue(&drag_p,DragPEnum);
-	inputs->GetParameterValue(&drag_q,DragQEnum);
-
-	/*Build alpha2_list used by drag stiffness matrix*/
-	Friction* friction=NewFriction();
-	
-	/*Initialize all fields: */
-	if (drag_type!=2)ISSMERROR(" non-viscous friction not supported yet!");
-	
-	friction->element_type=(char*)xmalloc((strlen("3d")+1)*sizeof(char));
-	strcpy(friction->element_type,"3d");
-
-	friction->gravity=matpar->GetG();
-	friction->rho_ice=matpar->GetRhoIce();
-	friction->rho_water=matpar->GetRhoWater();
-	friction->K=&dragcoefficient_list[0];
-	friction->bed=&bed_list[0];
-	friction->thickness=&thickness_list[0];
-	friction->vx=&vx_list[0];
-	friction->vy=&vy_list[0];
-	friction->p=drag_p;
-	friction->q=drag_q;
-
-	/*Compute alpha2_list: */
-	FrictionGetAlpha2(&alpha2_list[0],friction);
-
-	/*Erase friction object: */
-	DeleteFriction(&friction);
-
-	/* Compute basal friction */
-	for(i=0;i<numgrids;i++){
-		basalfriction_list[i]= alpha2_list[i]*(pow(vx_list[i],(double)2.0)+pow(vy_list[i],(double)2.0));
-	}
-	
-	/* Ice/ocean heat exchange flux on ice shelf base */
-	GaussTria (&num_area_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2);
-
-	/* Start looping on the number of gauss 2d (nodes on the bedrock) */
-	for (ig=0; ig<num_area_gauss; ig++){
-		gauss_weight=*(gauss_weights+ig);
-		gauss_coord[0]=*(first_gauss_area_coord+ig); 
-		gauss_coord[1]=*(second_gauss_area_coord+ig);
-		gauss_coord[2]=*(third_gauss_area_coord+ig);
-
-		//Get the Jacobian determinant
-		GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0], gauss_coord);
-
-		/*Get nodal functions values: */
-		GetNodalFunctions(&l1l2l3[0], gauss_coord);
-
-		/*Get geothermal flux and basal friction */
-		inputs->GetParameterValue(&geothermalflux_value, &gauss_coord[0],GeothermalFluxEnum);
-		GetParameterValue(&basalfriction,&basalfriction_list[0],gauss_coord);
-
-		/*Calculate scalar parameter*/
-		scalar=gauss_weight*Jdet*(basalfriction+geothermalflux_value)/(heatcapacity*rho_ice);
-		if(dt){
-			scalar=dt*scalar;
-		}
-
-		for(i=0;i<3;i++){
-			P_terms[i]+=scalar*l1l2l3[i];
-		}
-	}
-
-	/*Add pe_g to global vector pg: */
-	VecSetValues(pg,numdof,doflist,(const double*)P_terms,ADD_VALUES);
-
-	cleanup_and_return: 
-	xfree((void**)&first_gauss_area_coord);
-	xfree((void**)&second_gauss_area_coord);
-	xfree((void**)&third_gauss_area_coord);
-	xfree((void**)&gauss_weights);
-
-}
-/*}}}*/
-/*FUNCTION Tria::Du {{{1*/
-void Tria::Du(Vec du_g,int analysis_type,int sub_analysis_type){
-
-	int i;
-
-	/* node data: */
-	const int    numgrids=3;
-	const int    numdof=2*numgrids;
-	const int    NDOF2=2;
-	double       xyz_list[numgrids][3];
-	int          doflist[numdof];
-	int          numberofdofspernode;
-	double  gaussgrids[numgrids][numgrids]={{1,0,0},{0,1,0},{0,0,1}};
-
-	/* grid data: */
-	double vx_list[numgrids];
-	double vy_list[numgrids];
-	double obs_vx_list[numgrids];
-	double obs_vy_list[numgrids];
-	double dux_list[numgrids];
-	double duy_list[numgrids];
-	double weights_list[numgrids];
-
-	/* gaussian points: */
-	int     num_gauss,ig;
-	double* first_gauss_area_coord  =  NULL;
-	double* second_gauss_area_coord =  NULL;
-	double* third_gauss_area_coord  =  NULL;
-	double* gauss_weights           =  NULL;
-	double  gauss_weight;
-	double  gauss_l1l2l3[3];
-
-	/* parameters: */
-	double  obs_velocity_mag,velocity_mag;
-	double  dux,duy;
-	double  meanvel, epsvel;
-
-	/*element vector : */
-	double  due_g[numdof]={0.0};
-	double  due_g_gaussian[numdof];
-
-	/* Jacobian: */
-	double Jdet;
-
-	/*nodal functions: */
-	double l1l2l3[3];
-
-	/*relative and algorithmic fitting: */
-	double scalex=0;
-	double scaley=0;
-	double scale=0;
-	double S=0;
-	double fit=-1;
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-	Matpar* matpar=NULL;
-	Matice* matice=NULL;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	matpar=(Matpar*)hmatpar.delivers();
-	matice=(Matice*)hmatice.delivers();
-
-	/*retrieve some parameters: */
-	this->parameters->FindParam(&meanvel,MeanVelEnum);
-	this->parameters->FindParam(&epsvel,EpsVelEnum);
-
-	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
-	GetDofList(&doflist[0],&numberofdofspernode);
-
-	/* Recover input data: */
-	inputs->GetParameterValues(&obs_vx_list[0],&gaussgrids[0][0],3,VxObsEnum);
-	inputs->GetParameterValues(&obs_vy_list[0],&gaussgrids[0][0],3,VyObsEnum);
-
-	inputs->GetParameterValues(&vx_list[0],&gaussgrids[0][0],3,VxEnum);
-	inputs->GetParameterValues(&vy_list[0],&gaussgrids[0][0],3,VyEnum);
-	
-	inputs->GetParameterValues(&weights_list[0],&gaussgrids[0][0],3,WeightsEnum);
-	
-	inputs->GetParameterValue(&fit,FitEnum);
-	if(fit==3){
-		inputs->GetParameterValue(&S,SurfaceAreaEnum);
-	}
-
-	/*Get Du at the 3 nodes (integration of the linearized function)
-	 * Here we integrate linearized functions:
-	 *               
-	 * J(E) = int_E   sum_{i=1}^3  J_i Phi_i
-	 *
-	 *       d J                  dJ_i
-	 * DU= - --- = sum_{i=1}^3  - ---  Phi_i = sum_{i=1}^3 DU_i Phi_i
-	 *       d u                  du_i
-	 *
-	 * where J_i are the misfits at the 3 nodes of the triangle
-	 *       Phi_i is the nodal function (P1) with respect to 
-	 *       the vertex i
-	 */
-	if(fit==0){
-		/*We are using an absolute misfit:
-		 *
-		 *      1  [           2              2 ]
-		 * J = --- | (u - u   )  +  (v - v   )  |
-		 *      2  [       obs            obs   ]
-		 *
-		 *        dJ             2
-		 * DU = - -- = (u   - u )
-		 *        du     obs
-		 */
-		for (i=0;i<numgrids;i++){
-			dux_list[i]=obs_vx_list[i]-vx_list[i];
-			duy_list[i]=obs_vy_list[i]-vy_list[i];
-		}
-	}
-	else if(fit==1){
-		/*We are using a relative misfit: 
-		 *                        
-		 *      1  [     \bar{v}^2             2   \bar{v}^2              2 ]
-		 * J = --- | -------------  (u - u   ) + -------------  (v - v   )  |
-		 *      2  [  (u   + eps)^2       obs    (v   + eps)^2       obs    ]
-		 *              obs                        obs                      
-		 *
-		 *        dJ     \bar{v}^2
-		 * DU = - -- = ------------- (u   - u )
-		 *        du   (u   + eps)^2    obs
-		 *               obs
-		 */
-		for (i=0;i<numgrids;i++){
-			scalex=pow(meanvel/(obs_vx_list[i]+epsvel),2);
-			scaley=pow(meanvel/(obs_vy_list[i]+epsvel),2);
-			if(obs_vx_list[i]==0)scalex=0;
-			if(obs_vy_list[i]==0)scaley=0;
-			dux_list[i]=scalex*(obs_vx_list[i]-vx_list[i]);
-			duy_list[i]=scaley*(obs_vy_list[i]-vy_list[i]);
-		}
-	}
-	else if(fit==2){
-		/*We are using a logarithmic misfit:
-		 *                        
-		 *                 [        vel + eps     ] 2
-		 * J = 4 \bar{v}^2 | log ( -----------  ) |  
-		 *                 [       vel   + eps    ]
-		 *                            obs
-		 *
-		 *        dJ                 2 * log(...)
-		 * DU = - -- = - 4 \bar{v}^2 -------------  u
-		 *        du                 vel^2 + eps
-		 *            
-		 */
-		for (i=0;i<numgrids;i++){
-			velocity_mag=sqrt(pow(vx_list[i],2)+pow(vy_list[i],2))+epsvel; //epsvel to avoid velocity being nil.
-			obs_velocity_mag=sqrt(pow(obs_vx_list[i],2)+pow(obs_vy_list[i],2))+epsvel; //epsvel to avoid observed velocity being nil.
-			scale=-8*pow(meanvel,2)/pow(velocity_mag,2)*log(velocity_mag/obs_velocity_mag);
-			dux_list[i]=scale*vx_list[i];
-			duy_list[i]=scale*vy_list[i];
-		}
-	}
-	else if(fit==3){
-		/*We are using an spacially average absolute misfit:
-		 *
-		 *      1                    2              2
-		 * J = ---  sqrt(  (u - u   )  +  (v - v   )  )
-		 *      S                obs            obs
-		 *
-		 *        dJ      1       1 
-		 * DU = - -- = - --- ----------- * 2 (u - u   )
-		 *        du      S  2 sqrt(...)           obs
-		 */
-		for (i=0;i<numgrids;i++){
-			scale=1.0/(S*sqrt(pow(vx_list[i]-obs_vx_list[i],2)+pow(vy_list[i]-obs_vx_list[i],2))+epsvel);
-			dux_list[i]=scale*(obs_vx_list[i]-vx_list[i]);
-			duy_list[i]=scale*(obs_vy_list[i]-vy_list[i]);
-		}
-	}
-	else if(fit==4){
-		/*We are using an logarithmic 2 misfit:
-		 *
-		 *      1            [        |u| + eps     2          |v| + eps     2  ]
-		 * J = --- \bar{v}^2 | log ( -----------  )   +  log ( -----------  )   |  
-		 *      2            [       |u    |+ eps              |v    |+ eps     ]
-		 *                              obs                       obs
-		 *        dJ                              1      u                             1
-		 * DU = - -- = - \bar{v}^2 log(u...) --------- ----  ~ - \bar{v}^2 log(u...) ------
-		 *        du                         |u| + eps  |u|                           u + eps
-		 */
-		for (i=0;i<numgrids;i++){
-			dux_list[i] = - pow(meanvel,(double)2)*(
-						log((fabs(vx_list[i])+epsvel)/(fabs(obs_vx_list[i])+epsvel)) * 1/(vx_list[i]+epsvel));
-			duy_list[i] = - pow(meanvel,(double)2)*(
-						log((fabs(vy_list[i])+epsvel)/(fabs(obs_vy_list[i])+epsvel)) * 1/(vy_list[i]+epsvel));
-		}
-	}
-	else{
-		/*Not supported yet! : */
-		ISSMERROR("%s%g","unsupported type of fit: ",fit);
-	}
-
-	/*Apply weights to DU*/
-	for (i=0;i<numgrids;i++){
-		dux_list[i]=weights_list[i]*dux_list[i];
-		duy_list[i]=weights_list[i]*duy_list[i];
-	}
-
-	/* Get gaussian points and weights (make this a statically initialized list of points? fstd): */
-	GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2);
-
-	/* Start  looping on the number of gaussian points: */
-	for (ig=0; ig<num_gauss; ig++){
-		/*Pick up the gaussian point: */
-		gauss_weight=*(gauss_weights+ig);
-		gauss_l1l2l3[0]=*(first_gauss_area_coord+ig); 
-		gauss_l1l2l3[1]=*(second_gauss_area_coord+ig);
-		gauss_l1l2l3[2]=*(third_gauss_area_coord+ig);
-
-		/* Get Jacobian determinant: */
-		GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss_l1l2l3);
-
-		/* Get nodal functions value at gaussian point:*/
-		GetNodalFunctions(l1l2l3, gauss_l1l2l3);
-
-		/*Build due_g_gaussian vector: we have three cases here, according to which type of misfit we are using. */
-
-		/*Compute absolute(x/y) at gaussian point: */
-		GetParameterValue(&dux, &dux_list[0],gauss_l1l2l3);
-		GetParameterValue(&duy, &duy_list[0],gauss_l1l2l3);
-
-		/*compute Du*/
-		for (i=0;i<numgrids;i++){
-			due_g_gaussian[i*NDOF2+0]=dux*Jdet*gauss_weight*l1l2l3[i]; 
-			due_g_gaussian[i*NDOF2+1]=duy*Jdet*gauss_weight*l1l2l3[i]; 
-		}
-
-		/*Add due_g_gaussian vector to due_g: */
-		for( i=0; i<numdof; i++){
-			due_g[i]+=due_g_gaussian[i];
-		}
-	}
-
-	/*Add due_g to global vector du_g: */
-	VecSetValues(du_g,numdof,doflist,(const double*)due_g,ADD_VALUES);
-
-	xfree((void**)&first_gauss_area_coord);
-	xfree((void**)&second_gauss_area_coord);
-	xfree((void**)&third_gauss_area_coord);
-	xfree((void**)&gauss_weights);
-
-}
-/*}}}*/
-/*FUNCTION Tria::Enum {{{1*/
-int Tria::Enum(void){
-
-	return TriaEnum;
-
-}
-/*}}}*/
-/*FUNCTION Tria::GetArea {{{1*/
-double Tria::GetArea(void){
-
-	double area=0;
-	const int    numgrids=3;
-	double xyz_list[numgrids][3];
-	double x1,y1,x2,y2,x3,y3;
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-
-	/*Get xyz list: */
-	GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
-	x1=xyz_list[0][0]; y1=xyz_list[0][1];
-	x2=xyz_list[1][0]; y2=xyz_list[1][1];
-	x3=xyz_list[2][0]; y3=xyz_list[2][1];
- 
-	return x2*y3 - y2*x3 + x1*y2 - y1*x2 + x3*y1 - y3*x1;
-}
-/*}}}*/
-/*FUNCTION Tria::GetAreaCoordinate {{{1*/
-double Tria::GetAreaCoordinate(double x, double y, int which_one){
-
-	double area=0;
-	const int    numgrids=3;
-	double xyz_list[numgrids][3];
-	double x1,y1,x2,y2,x3,y3;
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-
-	/*Get area: */
-	area=this->GetArea();
-
-	/*Get xyz list: */
-	GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
-	x1=xyz_list[0][0]; y1=xyz_list[0][1];
-	x2=xyz_list[1][0]; y2=xyz_list[1][1];
-	x3=xyz_list[2][0]; y3=xyz_list[2][1];
-
-	if(which_one==1){
-		/*Get first area coordinate = det(x-x3  x2-x3 ; y-y3   y2-y3)/area*/
-		return ((x-x3)*(y2-y3)-(x2-x3)*(y-y3))/area;
-	}
-	else if(which_one==2){
-		/*Get second area coordinate = det(x1-x3  x-x3 ; y1-y3   y-y3)/area*/
-		return ((x1-x3)*(y-y3)-(x-x3)*(y1-y3))/area;
-	}
-	else if(which_one==3){
-		/*Get third  area coordinate 1-area1-area2: */
-		return 1-((x-x3)*(y2-y3)-(x2-x3)*(y-y3))/area -((x1-x3)*(y-y3)-(x-x3)*(y1-y3))/area;
-	}
-	else ISSMERROR("%s%i%s\n"," error message: area coordinate ",which_one," done not exist!");
-}
-/*}}}*/
-/*FUNCTION Tria::GetB {{{1*/
-
-void Tria::GetB(double* B, double* xyz_list, double* gauss_l1l2l3){
-
-	/*Compute B  matrix. B=[B1 B2 B3] where Bi is of size 3*NDOF2. 
-	 * For grid i, Bi can be expressed in the actual coordinate system
-	 * by: 
-	 *       Bi=[ dh/dx    0    ]
-	 *                [   0    dh/dy  ]
-	 *                [ 1/2*dh/dy  1/2*dh/dx  ]
-	 * where h is the interpolation function for grid i.
-	 *
-	 * We assume B has been allocated already, of size: 3x(NDOF2*numgrids)
-	 */
-	
-	int i;
-	const int NDOF2=2;
-	const int numgrids=3;
-
-	double dh1dh3[NDOF2][numgrids];
-
-
-	/*Get dh1dh2dh3 in actual coordinate system: */
-	GetNodalFunctionsDerivatives(&dh1dh3[0][0],xyz_list, gauss_l1l2l3);
-
-	/*Build B: */
-	for (i=0;i<numgrids;i++){
-		*(B+NDOF2*numgrids*0+NDOF2*i)=dh1dh3[0][i]; //B[0][NDOF2*i]=dh1dh3[0][i];
-		*(B+NDOF2*numgrids*0+NDOF2*i+1)=0;
-		*(B+NDOF2*numgrids*1+NDOF2*i)=0;
-		*(B+NDOF2*numgrids*1+NDOF2*i+1)=dh1dh3[1][i];
-		*(B+NDOF2*numgrids*2+NDOF2*i)=(float).5*dh1dh3[1][i]; 
-		*(B+NDOF2*numgrids*2+NDOF2*i+1)=(float).5*dh1dh3[0][i]; 
-	}
-}
-/*}}}*/
-/*FUNCTION Tria::GetB_prog {{{1*/
-
-void Tria::GetB_prog(double* B_prog, double* xyz_list, double* gauss_l1l2l3){
-
-	/*Compute B  matrix. B=[B1 B2 B3] where Bi is of size 3*NDOF2. 
-	 * For grid i, Bi can be expressed in the actual coordinate system
-	 * by: 
-	 *       Bi=[ h ]
-	 *                [ h ]
-	 * where h is the interpolation function for grid i.
-	 *
-	 * We assume B_prog has been allocated already, of size: 2x(NDOF1*numgrids)
-	 */
-
-	int i;
-	const int NDOF1=1;
-	const int numgrids=3;
-
-	double l1l2l3[numgrids];
-
-
-	/*Get dh1dh2dh3 in actual coordinate system: */
-	GetNodalFunctions(&l1l2l3[0],gauss_l1l2l3);
-
-	/*Build B_prog: */
-	for (i=0;i<numgrids;i++){
-		*(B_prog+NDOF1*numgrids*0+NDOF1*i)=l1l2l3[i];
-		*(B_prog+NDOF1*numgrids*1+NDOF1*i)=l1l2l3[i];
-	}
-}
-/*}}}*/
-/*FUNCTION Tria::GetBedList {{{1*/
-void  Tria::GetBedList(double* bedlist){
-	
-	const int numgrids=3;
-	double  gaussgrids[numgrids][numgrids]={{1,0,0},{0,1,0},{0,0,1}};
-	
-	inputs->GetParameterValues(bedlist,&gaussgrids[0][0],3,BedEnum);
-
-}
-/*}}}*/
-/*FUNCTION Tria::GetBPrime {{{1*/
-
-void Tria::GetBPrime(double* Bprime, double* xyz_list, double* gauss_l1l2l3){
-
-	/*Compute B'  matrix. B'=[B1' B2' B3'] where Bi' is of size 3*NDOF2. 
-	 * For grid i, Bi' can be expressed in the actual coordinate system
-	 * by: 
-	 *       Bi_prime=[ 2*dh/dx dh/dy ]
-	 *                       [ dh/dx  2*dh/dy]
-	 *                       [dh/dy dh/dx]
-	 * where h is the interpolation function for grid i.
-	 *
-	 * We assume B' has been allocated already, of size: 3x(NDOF2*numgrids)
-	 */
-	
-	int i;
-	const int NDOF2=2;
-	const int numgrids=3;
-
-	/*Same thing in the actual coordinate system: */
-	double dh1dh3[NDOF2][numgrids];
-
-
-	/*Get dh1dh2dh3 in actual coordinates system : */
-	GetNodalFunctionsDerivatives(&dh1dh3[0][0],xyz_list,gauss_l1l2l3);
-
-	/*Build B': */
-	for (i=0;i<numgrids;i++){
-		*(Bprime+NDOF2*numgrids*0+NDOF2*i)=2*dh1dh3[0][i]; 
-		*(Bprime+NDOF2*numgrids*0+NDOF2*i+1)=dh1dh3[1][i]; 
-		*(Bprime+NDOF2*numgrids*1+NDOF2*i)=dh1dh3[0][i]; 
-		*(Bprime+NDOF2*numgrids*1+NDOF2*i+1)=2*dh1dh3[1][i]; 
-		*(Bprime+NDOF2*numgrids*2+NDOF2*i)=dh1dh3[1][i]; 
-		*(Bprime+NDOF2*numgrids*2+NDOF2*i+1)=dh1dh3[0][i]; 
-	}
-}
-/*}}}*/
-/*FUNCTION Tria::GetBPrime_prog {{{1*/
-
-void Tria::GetBPrime_prog(double* Bprime_prog, double* xyz_list, double* gauss_l1l2l3){
-
-	/*Compute B'  matrix. B'=[B1' B2' B3'] where Bi' is of size 3*NDOF2. 
-	 * For grid i, Bi' can be expressed in the actual coordinate system
-	 * by: 
-	 *       Bi_prime=[ dh/dx ]
-	 *                       [ dh/dy ]
-	 * where h is the interpolation function for grid i.
-	 *
-	 * We assume B' has been allocated already, of size: 3x(NDOF2*numgrids)
-	 */
-
-	int i;
-	const int NDOF1=1;
-	const int NDOF2=2;
-	const int numgrids=3;
-
-	/*Same thing in the actual coordinate system: */
-	double dh1dh3[NDOF2][numgrids];
-
-	/*Get dh1dh2dh3 in actual coordinates system : */
-	GetNodalFunctionsDerivatives(&dh1dh3[0][0],xyz_list,gauss_l1l2l3);
-
-	/*Build B': */
-	for (i=0;i<numgrids;i++){
-		*(Bprime_prog+NDOF1*numgrids*0+NDOF1*i)=dh1dh3[0][i]; 
-		*(Bprime_prog+NDOF1*numgrids*1+NDOF1*i)=dh1dh3[1][i]; 
-	}
-}
-/*}}}*/
-/*FUNCTION Tria::GetDofList {{{1*/
-void  Tria::GetDofList(int* doflist,int* pnumberofdofspernode){
-
-	int i,j;
-	int doflist_per_node[MAXDOFSPERNODE];
-	int numberofdofspernode;
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	
-	for(i=0;i<3;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;
-
-}
-/*}}}*/
-/*FUNCTION Tria::GetDofList1 {{{1*/
-void  Tria::GetDofList1(int* doflist){
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	
-	int i;
-	for(i=0;i<3;i++){
-		doflist[i]=nodes[i]->GetDofList1();
-	}
-
-}
-/*}}}*/
-/*FUNCTION Tria::Id {{{1*/
-int    Tria::Id(){ return id; }
-/*}}}*/
-/*FUNCTION Tria::GetJacobian {{{1*/
-void Tria::GetJacobian(double* J, double* xyz_list,double* gauss_l1l2l3){
-
-	/*The Jacobian is constant over the element, discard the gaussian points. 
-	 * J is assumed to have been allocated of size NDOF2xNDOF2.*/
-
-	const int NDOF2=2;
-	const int numgrids=3;
-	double x1,y1,x2,y2,x3,y3;
-	
-	x1=*(xyz_list+numgrids*0+0);
-	y1=*(xyz_list+numgrids*0+1);
-	x2=*(xyz_list+numgrids*1+0);
-	y2=*(xyz_list+numgrids*1+1);
-	x3=*(xyz_list+numgrids*2+0);
-	y3=*(xyz_list+numgrids*2+1);
-
-
-	*(J+NDOF2*0+0)=0.5*(x2-x1);
-	*(J+NDOF2*1+0)=SQRT3/6.0*(2*x3-x1-x2);
-	*(J+NDOF2*0+1)=0.5*(y2-y1);
-	*(J+NDOF2*1+1)=SQRT3/6.0*(2*y3-y1-y2);
-}
-/*}}}*/
-/*FUNCTION Tria::GetJacobianDeterminant2d {{{1*/
-void Tria::GetJacobianDeterminant2d(double*  Jdet, double* xyz_list,double* gauss_l1l2l3){
-
-	/*The Jacobian determinant is constant over the element, discard the gaussian points. 
-	 * J is assumed to have been allocated of size NDOF2xNDOF2.*/
-
-	double x1,x2,x3,y1,y2,y3;
-	
-	x1=*(xyz_list+3*0+0);
-	y1=*(xyz_list+3*0+1);
-	x2=*(xyz_list+3*1+0);
-	y2=*(xyz_list+3*1+1);
-	x3=*(xyz_list+3*2+0);
-	y3=*(xyz_list+3*2+1);
-
-
-	*Jdet=SQRT3/6.0*((x2-x1)*(y3-y1)-(y2-y1)*(x3-x1));
-
-
-	if(Jdet<0){
-		ISSMERROR("negative jacobian determinant!");
-	}
-	
-}
-/*}}}*/
-/*FUNCTION Tria::GetJacobianDeterminant3d {{{1*/
-void Tria::GetJacobianDeterminant3d(double*  Jdet, double* xyz_list,double* gauss_l1l2l3){
-
-	/*The Jacobian determinant is constant over the element, discard the gaussian points. 
-	 * J is assumed to have been allocated of size NDOF2xNDOF2.*/
-
-	double x1,x2,x3,y1,y2,y3,z1,z2,z3;
-	
-	x1=*(xyz_list+3*0+0);
-	y1=*(xyz_list+3*0+1);
-	z1=*(xyz_list+3*0+2);
-	x2=*(xyz_list+3*1+0);
-	y2=*(xyz_list+3*1+1);
-	z2=*(xyz_list+3*1+2);
-	x3=*(xyz_list+3*2+0);
-	y3=*(xyz_list+3*2+1);
-	z3=*(xyz_list+3*2+2);
-
-
-	*Jdet=SQRT3/6.0*pow(pow(((y2-y1)*(z3-z1)-(z2-z1)*(y3-y1)),2.0)+pow(((z2-z1)*(x3-x1)-(x2-x1)*(z3-z1)),2.0)+pow(((x2-x1)*(y3-y1)-(y2-y1)*(x3-x1)),2.0),0.5);
-
-	if(Jdet<0){
-		ISSMERROR("negative jacobian determinant!");
-	}
-	
-}
-/*}}}*/
-/*FUNCTION Tria::GetJacobianInvert {{{1*/
-void Tria::GetJacobianInvert(double*  Jinv, double* xyz_list,double* gauss_l1l2l3){
-
-	double Jdet;
-	const int NDOF2=2;
-	const int numgrids=3;
-
-	/*Call Jacobian routine to get the jacobian:*/
-	GetJacobian(Jinv, xyz_list, gauss_l1l2l3);
-
-	/*Invert Jacobian matrix: */
-	MatrixInverse(Jinv,NDOF2,NDOF2,NULL,0,&Jdet);
-
-}
-/*}}}*/
-/*FUNCTION Tria::GetL {{{1*/
-
-void Tria::GetL(double* L, double* xyz_list, double* gauss_l1l2l3,int numdof){
-
-	/*Compute L  matrix. L=[L1 L2 L3] where Li is square and of size numdof. 
-	 * For grid i, Li can be expressed in the actual coordinate system
-	 * by: 
-	 *       numdof=1: 
-	 *       Li=h;
-	 *       numdof=2:
-	 *       Li=[ h    0    ]
-	 *                [   0   h  ]
-	 * where h is the interpolation function for grid i.
-	 *
-	 * We assume L has been allocated already, of size: numgrids (numdof=1), or numdofx(numdof*numgrids) (numdof=2)
-	 */
-
-	int i;
-	const int NDOF2=2;
-	const int numgrids=3;
-
-	double l1l2l3[3];
-
-
-	/*Get l1l2l3 in actual coordinate system: */
-	GetNodalFunctions(l1l2l3, gauss_l1l2l3);
-
-#ifdef _DELUG_ 
-	for (i=0;i<3;i++){
-		printf("Node %i  h=%lf \n",i,l1l2l3[i]);
-	}
-#endif
-
-	/*Build L: */
-	if(numdof==1){
-		for (i=0;i<numgrids;i++){
-			L[i]=l1l2l3[i]; 
-		}
-	}
-	else{
-		for (i=0;i<numgrids;i++){
-			*(L+numdof*numgrids*0+numdof*i)=l1l2l3[i]; //L[0][NDOF2*i]=dh1dh3[0][i];
-			*(L+numdof*numgrids*0+numdof*i+1)=0;
-			*(L+numdof*numgrids*1+numdof*i)=0;
-			*(L+numdof*numgrids*1+numdof*i+1)=l1l2l3[i];
-		}
-	}
-}
-/*}}}*/
-/*FUNCTION Tria::GetMatPar {{{1*/
-void* Tria::GetMatPar(){
-
-	/*dynamic objects pointed to by hooks: */
-	Matpar* matpar=NULL;
-
-	/*recover objects from hooks: */
-	matpar=(Matpar*)hmatpar.delivers();
-
-	return matpar;
-}
-/*}}}*/
-/*FUNCTION Tria::GetNodalFunctions {{{1*/
-void Tria::GetNodalFunctions(double* l1l2l3, double* gauss_l1l2l3){
-	
-	/*This routine returns the values of the nodal functions  at the gaussian point.*/
-
-	/*First nodal function: */
-	l1l2l3[0]=gauss_l1l2l3[0];
-
-	/*Second nodal function: */
-	l1l2l3[1]=gauss_l1l2l3[1];
-
-	/*Third nodal function: */
-	l1l2l3[2]=gauss_l1l2l3[2];
-
-}
-/*}}}*/
-/*FUNCTION Tria::GetNodalFunctionsDerivatives {{{1*/
-void Tria::GetNodalFunctionsDerivatives(double* dh1dh3,double* xyz_list, double* gauss_l1l2l3){
-	
-	/*This routine returns the values of the nodal functions derivatives  (with respect to the 
-	 * actual coordinate system: */
-
-	int i;
-	const int NDOF2=2;
-	const int numgrids=3;
-
-	double dh1dh3_ref[NDOF2][numgrids];
-	double Jinv[NDOF2][NDOF2];
-
-
-	/*Get derivative values with respect to parametric coordinate system: */
-	GetNodalFunctionsDerivativesReference(&dh1dh3_ref[0][0], gauss_l1l2l3); 
-
-	/*Get Jacobian invert: */
-	GetJacobianInvert(&Jinv[0][0], xyz_list, gauss_l1l2l3);
-
-	/*Build dh1dh3: 
-	 *
-	 * [dhi/dx]= Jinv*[dhi/dr]
-	 * [dhi/dy]       [dhi/ds]
-	 */
-
-	for (i=0;i<numgrids;i++){
-		*(dh1dh3+numgrids*0+i)=Jinv[0][0]*dh1dh3_ref[0][i]+Jinv[0][1]*dh1dh3_ref[1][i];
-		*(dh1dh3+numgrids*1+i)=Jinv[1][0]*dh1dh3_ref[0][i]+Jinv[1][1]*dh1dh3_ref[1][i];
-	}
-
-}
-/*}}}*/
-/*FUNCTION Tria::GetNodalFunctionsDerivativesReference {{{1*/
-void Tria::GetNodalFunctionsDerivativesReference(double* dl1dl3,double* gauss_l1l2l3){
-	
-	/*This routine returns the values of the nodal functions derivatives  (with respect to the 
-	 * natural coordinate system) at the gaussian point. */
-
-	const int NDOF2=2;
-	const int numgrids=3;
-
-	/*First nodal function: */
-	*(dl1dl3+numgrids*0+0)=-0.5; 
-	*(dl1dl3+numgrids*1+0)=-1.0/(2.0*SQRT3);
-
-	/*Second nodal function: */
-	*(dl1dl3+numgrids*0+1)=0.5;
-	*(dl1dl3+numgrids*1+1)=-1.0/(2.0*SQRT3);
-
-	/*Third nodal function: */
-	*(dl1dl3+numgrids*0+2)=0;
-	*(dl1dl3+numgrids*1+2)=1.0/SQRT3;
-
-}
-/*}}}*/
-/*FUNCTION Tria::GetNodes {{{1*/
-void  Tria::GetNodes(void** vpnodes){
-	int i;
-	Node** pnodes=NULL;
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-	
-	/*recover nodes: */
-	pnodes=(Node**)vpnodes;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	
-	for(i=0;i<3;i++){
-		pnodes[i]=nodes[i];
-	}
-}
-/*}}}*/
-/*FUNCTION Tria::GetOnBed {{{1*/
-bool Tria::GetOnBed(){
-	
-	bool onbed;
-	inputs->GetParameterValue(&onbed,ElementOnBedEnum);
-
-	return onbed;
-}
-/*}}}*/
-/*FUNCTION Tria::GetParameterDerivativeValue {{{1*/
-void Tria::GetParameterDerivativeValue(double* p, double* plist,double* xyz_list, double* gauss_l1l2l3){
-	 
-	const int NDOF2=2;
-	const int numgrids=3;
-	/*From node values of parameter p (plist[0],plist[1],plist[2]), return parameter derivative value at gaussian 
-	 * point specified by gauss_l1l2l3:
-	 *   dp/dx=plist[0]*dh1/dx+plist[1]*dh2/dx+plist[2]*dh3/dx
-	 *   dp/dx=plist[0]*dh1/dx+plist[1]*dh2/dx+plist[2]*dh3/dx
-	 *
-	 * p is a vector of size 2x1 already allocated.
-	 */
-	
-	double dh1dh3[NDOF2][numgrids]; //nodal derivative functions in actual coordinate system.
-
-	/*Get dh1dh2dh3 in actual coordinate system: */
-	GetNodalFunctionsDerivatives(&dh1dh3[0][0],xyz_list, gauss_l1l2l3);
-
-	*(p+0)=plist[0]*dh1dh3[0][0]+plist[1]*dh1dh3[0][1]+plist[2]*dh1dh3[0][2];
-	*(p+1)=plist[0]*dh1dh3[1][0]+plist[1]*dh1dh3[1][1]+plist[2]*dh1dh3[1][2];
-
-}
-/*}}}*/
-/*FUNCTION Tria::GetParameterValue {{{1*/
-void Tria::GetParameterValue(double* pp, double* plist, double* gauss_l1l2l3){
-	
-	/*From node values of parameter p (plist[0],plist[1],plist[2]), return parameter value at gaussian 
-	 * point specifie by gauss_l1l2l3: */
-	
-	/*nodal functions: */
-	double l1l2l3[3];
-
-	/*output: */
-	double p;
-
-	GetNodalFunctions(l1l2l3, gauss_l1l2l3);
-
-	p=l1l2l3[0]*plist[0]+l1l2l3[1]*plist[1]+l1l2l3[2]*plist[2];
-
-	/*Assign output pointers:*/
-	*pp=p;
-}
-/*}}}*/
-/*FUNCTION Tria::GetShelf {{{1*/
-bool   Tria::GetShelf(){
-	/*inputs: */
-	bool shelf;
-
-	/*retrieve inputs :*/
-	inputs->GetParameterValue(&shelf,ElementOnIceShelfEnum);
-
-	return shelf;
-}
-/*}}}*/
-/*FUNCTION Tria::GetStrainRate {{{1*/
-void Tria::GetStrainRate(double* epsilon, double* velocity, double* xyz_list, double* gauss_l1l2l3){
-
-	int i;
-	const int NDOF2=2;
-	const int numgrids=3;
-
-	double B[3][NDOF2*numgrids];
-
-	/*Get B matrix: */
-	GetB(&B[0][0], xyz_list, gauss_l1l2l3);
-
-	/*Multiply B by velocity, to get strain rate: */
-	MatrixMultiply( &B[0][0],3,NDOF2*numgrids,0,
-			              velocity,NDOF2*numgrids,1,0,
-						  epsilon,0);
-
-}
-/*}}}*/
-/*FUNCTION Tria::GetThicknessList {{{1*/
-void Tria::GetThicknessList(double* thickness_list){
-
-	const int numgrids=3;
-	double  gaussgrids[numgrids][numgrids]={{1,0,0},{0,1,0},{0,0,1}};
-	inputs->GetParameterValues(thickness_list,&gaussgrids[0][0],3,ThicknessEnum);
-
-}
-/*}}}*/
-/*FUNCTION Tria::Gradj {{{1*/
-void  Tria::Gradj(Vec grad_g,int analysis_type,int sub_analysis_type,char* control_type){
-
-	/*inputs: */
-	bool onwater;
-
-	/*retrieve inputs :*/
-	inputs->GetParameterValue(&onwater,ElementOnWaterEnum);
-
-	/*If on water, grad = 0: */
-	if(onwater)return;
-
-	if (strcmp(control_type,"drag")==0){
-		GradjDrag( grad_g,analysis_type,sub_analysis_type);
-	}
-	else if (strcmp(control_type,"B")==0){
-		GradjB( grad_g,analysis_type,sub_analysis_type);
-	}
-	else ISSMERROR("%s%s","control type not supported yet: ",control_type);
-}
-/*}}}*/
-/*FUNCTION Tria::GradjB{{{1*/
-void  Tria::GradjB(Vec grad_g,int analysis_type,int sub_analysis_type){
-
-	int i;
-
-	/* node data: */
-	const int    numgrids=3;
-	const int    NDOF1=1;
-	const int    NDOF2=2;
-	const int    numdof=NDOF2*numgrids;
-	double       xyz_list[numgrids][3];
-	int          doflist1[numgrids];
-	double       dh1dh3[NDOF2][numgrids];
-
-	/* grid data: */
-	double B[numgrids];
-
-	int    dofs1[1]={0};
-	int    dofs2[2]={0,1};
-
-	/* gaussian points: */
-	int     num_gauss,ig;
-	double* first_gauss_area_coord  =  NULL;
-	double* second_gauss_area_coord =  NULL;
-	double* third_gauss_area_coord  =  NULL;
-	double* gauss_weights           =  NULL;
-	double  gauss_weight;
-	double  gauss_l1l2l3[3];
-
-	/*element vector at the gaussian points: */
-	double  grade_g[numgrids]={0.0};
-	double  grade_g_gaussian[numgrids];
-
-	/* Jacobian: */
-	double Jdet;
-
-	/*nodal functions: */
-	double l1l2l3[3];
-
-	/* strain rate: */
-	double epsilon[3]; /* epsilon=[exx,eyy,exy];*/
-
-	/* parameters: */
-	double  viscosity_complement;
-	double  dvx[NDOF2];
-	double  dvy[NDOF2]; 
-	double  dadjx[NDOF2];
-	double  dadjy[NDOF2];
-	double  vx,vy;
-	double  lambda,mu;
-	double  thickness;
-	int     dofs[1]={0};
-	double  dB[NDOF2]; 
-	double  B_gauss;
-	
-	/*parameters: */
-	double  cm_noisedmp;
-	double  cm_mindmp_slope;
-	double  cm_mindmp_value;
-	double  cm_maxdmp_value;
-	double  cm_maxdmp_slope;
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-	Matpar* matpar=NULL;
-	Matice* matice=NULL;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	matpar=(Matpar*)hmatpar.delivers();
-	matice=(Matice*)hmatice.delivers();
-
-	/*retrieve some parameters: */
-	this->parameters->FindParam(&cm_noisedmp,CmNoiseDmpEnum);
-	this->parameters->FindParam(&cm_mindmp_value,CmMinDmpValueEnum);
-	this->parameters->FindParam(&cm_mindmp_slope,CmMinDmpSlopeEnum);
-	this->parameters->FindParam(&cm_maxdmp_value,CmMaxDmpValueEnum);
-	this->parameters->FindParam(&cm_maxdmp_slope,CmMaxDmpSlopeEnum);
-
-	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
-	GetDofList1(&doflist1[0]);
-
-	/* Get gaussian points and weights (make this a statically initialized list of points? fstd): */
-	GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 4);
-
-	/* Start  looping on the number of gaussian points: */
-	for (ig=0; ig<num_gauss; ig++){
-		/*Pick up the gaussian point: */
-		gauss_weight=*(gauss_weights+ig);
-		gauss_l1l2l3[0]=*(first_gauss_area_coord+ig); 
-		gauss_l1l2l3[1]=*(second_gauss_area_coord+ig);
-		gauss_l1l2l3[2]=*(third_gauss_area_coord+ig);
-
-		/*Get thickness: */
-		inputs->GetParameterValue(&thickness, gauss_l1l2l3,ThicknessEnum);
-
-		/*Get strain rate, if velocity has been supplied: */
-		inputs->GetStrainRate(&epsilon[0],&xyz_list[0][0],gauss_l1l2l3,VxEnum,VyEnum);
-
-		/*Get viscosity complement: */
-		matice->GetViscosityComplement(&viscosity_complement, &epsilon[0]);
-
-		/*Get dvx, dvy, dadjx and dadjx: */
-		inputs->GetParameterDerivativeValue(&dvx[0],&xyz_list[0][0],&gauss_l1l2l3[0],VxEnum);
-		inputs->GetParameterDerivativeValue(&dvy[0],&xyz_list[0][0],&gauss_l1l2l3[0],VyEnum);
-		inputs->GetParameterDerivativeValue(&dadjx[0],&xyz_list[0][0],&gauss_l1l2l3[0],AdjointxEnum);
-		inputs->GetParameterDerivativeValue(&dadjy[0],&xyz_list[0][0],&gauss_l1l2l3[0],AdjointyEnum);
-
-		/* Get Jacobian determinant: */
-		GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss_l1l2l3);
-
-		/* Get nodal functions value at gaussian point:*/
-		GetNodalFunctions(l1l2l3, gauss_l1l2l3);
-
-		/*Get nodal functions derivatives*/
-		GetNodalFunctionsDerivatives(&dh1dh3[0][0],&xyz_list[0][0],gauss_l1l2l3);
-
-		/*Get B derivative: dB/dx */
-		inputs->GetParameterDerivativeValue(&dB[0],&xyz_list[0][0],&gauss_l1l2l3[0],RheologyBEnum);
-		inputs->GetParameterValue(&B_gauss, gauss_l1l2l3,RheologyBEnum);
-
-		/*Build gradje_g_gaussian vector (actually -dJ/dB): */
-		for (i=0;i<numgrids;i++){
-			//standard gradient dJ/dki
-			grade_g_gaussian[i]=-viscosity_complement*thickness*( (2*dvx[0]+dvy[1])*2*dadjx[0]+(dvx[1]+dvy[0])*(dadjx[1]+dadjy[0])+(2*dvy[1]+dvx[0])*2*dadjy[1])*Jdet*gauss_weight*l1l2l3[i]; 
-
-			//Add regularization term
-			grade_g_gaussian[i]-=cm_noisedmp*Jdet*gauss_weight*(dh1dh3[0][i]*dB[0]+dh1dh3[1][i]*dB[1]);
-
-			//min dampening
-			if(B_gauss<cm_mindmp_value){ 
-				grade_g_gaussian[i]+= cm_mindmp_slope*Jdet*gauss_weight*l1l2l3[i];
-			}
-
-			//max dampening
-			if(B_gauss>cm_maxdmp_value){ 
-				grade_g_gaussian[i]+= - cm_maxdmp_slope*Jdet*gauss_weight*l1l2l3[i];
-			}
-
-		}
-
-		/*Add grade_g_gaussian to grade_g: */
-		for( i=0; i<numgrids;i++) grade_g[i]+=grade_g_gaussian[i];
-	}
-
-	/*Add grade_g to global vector grad_g: */
-	VecSetValues(grad_g,numgrids,doflist1,(const double*)grade_g,ADD_VALUES);
-
-cleanup_and_return: 
-	xfree((void**)&first_gauss_area_coord);
-	xfree((void**)&second_gauss_area_coord);
-	xfree((void**)&third_gauss_area_coord);
-	xfree((void**)&gauss_weights);
-}
-/*}}}*/
-/*FUNCTION Tria::GradjDrag {{{1*/
-void  Tria::GradjDrag(Vec grad_g,int analysis_type,int sub_analysis_type){
-
-
-	int i;
-
-	/* node data: */
-	const int    numgrids=3;
-	const int    NDOF2=2;
-	const int    numdof=NDOF2*numgrids;
-	double       xyz_list[numgrids][3];
-	int          doflist1[numgrids];
-	double       dh1dh3[NDOF2][numgrids];
-
-	/* grid data: */
-	double vx_list[numgrids];
-	double vy_list[numgrids];
-	double adjx_list[numgrids];
-	double adjy_list[numgrids];
-	double thickness_list[numgrids];
-	double bed_list[numgrids];
-	double dragcoefficient_list[numgrids];
-	double drag_p;
-	double drag_q;
-	int    drag_type;
-
-	double drag;
-
-	/* gaussian points: */
-	int     num_gauss,ig;
-	double* first_gauss_area_coord  =  NULL;
-	double* second_gauss_area_coord =  NULL;
-	double* third_gauss_area_coord  =  NULL;
-	double* gauss_weights           =  NULL;
-	double  gauss_weight;
-	double  gauss_l1l2l3[3];
-	double  gaussgrids[numgrids][numgrids]={{1,0,0},{0,1,0},{0,0,1}};
-
-	/* parameters: */
-	double  dk[NDOF2]; 
-	double  vx,vy;
-	double  lambda,mu;
-	double  bed,thickness,Neff;
-	
-	/*drag: */
-	double alpha_complement_list[numgrids];
-	double alpha_complement;
-
-	/*element vector at the gaussian points: */
-	double  grade_g[numgrids]={0.0};
-	double  grade_g_gaussian[numgrids];
-
-	/* Jacobian: */
-	double Jdet;
-
-	/*nodal functions: */
-	double l1l2l3[3];
-
-	/* strain rate: */
-	double epsilon[3]; /* epsilon=[exx,eyy,exy];*/
-
-	/*inputs: */
-	bool shelf;
-
-	/*parameters: */
-	double  cm_noisedmp;
-	double  cm_mindmp_slope;
-	double  cm_mindmp_value;
-	double  cm_maxdmp_value;
-	double  cm_maxdmp_slope;
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-	Matpar* matpar=NULL;
-	Matice* matice=NULL;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	matpar=(Matpar*)hmatpar.delivers();
-	matice=(Matice*)hmatice.delivers();
-
-	/*retrieve inputs :*/
-	inputs->GetParameterValue(&shelf,ElementOnIceShelfEnum);
-
-	/*retrieve some parameters: */
-	this->parameters->FindParam(&cm_noisedmp,CmNoiseDmpEnum);
-	this->parameters->FindParam(&cm_mindmp_value,CmMinDmpValueEnum);
-	this->parameters->FindParam(&cm_mindmp_slope,CmMinDmpSlopeEnum);
-	this->parameters->FindParam(&cm_maxdmp_value,CmMaxDmpValueEnum);
-	this->parameters->FindParam(&cm_maxdmp_slope,CmMaxDmpSlopeEnum);
-
-
-	/*Get out if shelf*/
-	if(shelf)return;
-
-	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
-	GetDofList1(&doflist1[0]);
-
-	/*Recover inputs: */
-	inputs->GetParameterValues(&vx_list[0],&gaussgrids[0][0],3,VxAverageEnum);
-	inputs->GetParameterValues(&vy_list[0],&gaussgrids[0][0],3,VyAverageEnum);
-	inputs->GetParameterValues(&thickness_list[0],&gaussgrids[0][0],3,ThicknessEnum);
-	inputs->GetParameterValues(&bed_list[0],&gaussgrids[0][0],3,BedEnum);
-	inputs->GetParameterValues(&dragcoefficient_list[0],&gaussgrids[0][0],3,DragCoefficientEnum);
-	inputs->GetParameterValue(&drag_p,DragPEnum);
-	inputs->GetParameterValue(&drag_q,DragQEnum);
-	inputs->GetParameterValue(&drag_type,DragTypeEnum);
-
-	/* Get gaussian points and weights (make this a statically initialized list of points? fstd): */
-	GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 4);
-
-	/* Start  looping on the number of gaussian points: */
-	for (ig=0; ig<num_gauss; ig++){
-		/*Pick up the gaussian point: */
-		gauss_weight=*(gauss_weights+ig);
-		gauss_l1l2l3[0]=*(first_gauss_area_coord+ig); 
-		gauss_l1l2l3[1]=*(second_gauss_area_coord+ig);
-		gauss_l1l2l3[2]=*(third_gauss_area_coord+ig);
-
-		/*Build alpha_complement_list: */
-		if (drag_type==2){
-		
-			/*Allocate friction object: */
-			Friction* friction=NewFriction();
-			
-			/*Initialize all fields: */
-			friction->element_type=(char*)xmalloc((strlen("2d")+1)*sizeof(char));
-			strcpy(friction->element_type,"2d");
-			
-			
-			friction->gravity=matpar->GetG();
-			friction->rho_ice=matpar->GetRhoIce();
-			friction->rho_water=matpar->GetRhoWater();
-			friction->K=&dragcoefficient_list[0];
-			friction->bed=&bed_list[0];
-			friction->thickness=&thickness_list[0];
-			friction->vx=&vx_list[0];
-			friction->vy=&vy_list[0];
-			friction->p=drag_p;
-			friction->q=drag_q;
-
-			
-			if(friction->p!=1) ISSMERROR("non-linear friction not supported yet in control methods!");
-
-			/*Compute alpha complement: */
-			FrictionGetAlphaComplement(&alpha_complement_list[0],friction);
-
-			/*Erase friction object: */
-			DeleteFriction(&friction);
-		}
-		else{
-			alpha_complement_list[0]=0;
-			alpha_complement_list[1]=0;
-			alpha_complement_list[2]=0;
-		}
-	
-		/*Recover alpha_complement and k: */
-		GetParameterValue(&alpha_complement, &alpha_complement_list[0],gauss_l1l2l3);
-		inputs->GetParameterValue(&drag, gauss_l1l2l3,DragCoefficientEnum);
-
-		/*recover lambda and mu: */
-		inputs->GetParameterValue(&lambda, gauss_l1l2l3,AdjointxEnum);
-		inputs->GetParameterValue(&mu, gauss_l1l2l3,AdjointyEnum);
-			
-		/*recover vx and vy: */
-		inputs->GetParameterValue(&vx, gauss_l1l2l3,VxEnum);
-		inputs->GetParameterValue(&vy, gauss_l1l2l3,VyEnum);
-
-		/* Get Jacobian determinant: */
-		GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss_l1l2l3);
-		
-		/* Get nodal functions value at gaussian point:*/
-		GetNodalFunctions(l1l2l3, gauss_l1l2l3);
-
-		/*Get nodal functions derivatives*/
-		GetNodalFunctionsDerivatives(&dh1dh3[0][0],&xyz_list[0][0],gauss_l1l2l3);
-
-		/*Get k derivative: dk/dx */
-		inputs->GetParameterDerivativeValue(&dk[0],&xyz_list[0][0],&gauss_l1l2l3[0],DragCoefficientEnum);
-
-		/*Build gradje_g_gaussian vector (actually -dJ/ddrag): */
-		for (i=0;i<numgrids;i++){
-
-			//standard term dJ/dki
-			grade_g_gaussian[i]=-2*drag*alpha_complement*((lambda*vx+mu*vy))*Jdet*gauss_weight*l1l2l3[i];
-
-			//noise dampening d/dki(1/2*(dk/dx)^2)
-			grade_g_gaussian[i]+=-cm_noisedmp*Jdet*gauss_weight*(dh1dh3[0][i]*dk[0]+dh1dh3[1][i]*dk[1]);
-			
-			//min dampening
-			if(drag<cm_mindmp_value){ 
-				grade_g_gaussian[i]+=cm_mindmp_slope*Jdet*gauss_weight*l1l2l3[i];
-			}
-
-			//max dampening
-			if(drag>cm_maxdmp_value){ 
-				grade_g_gaussian[i]+= - cm_maxdmp_slope*Jdet*gauss_weight*l1l2l3[i];
-			}
-		}
-		
-		/*Add gradje_g_gaussian vector to gradje_g: */
-		for( i=0; i<numgrids; i++)grade_g[i]+=grade_g_gaussian[i];
-	}
-
-	/*Add grade_g to global vector grad_g: */
-	VecSetValues(grad_g,numgrids,doflist1,(const double*)grade_g,ADD_VALUES);
-	
-	cleanup_and_return: 
-	xfree((void**)&first_gauss_area_coord);
-	xfree((void**)&second_gauss_area_coord);
-	xfree((void**)&third_gauss_area_coord);
-	xfree((void**)&gauss_weights);
-
-}
-/*}}}*/
-/*FUNCTION Tria::GradjDragStokes {{{1*/
-void  Tria::GradjDragStokes(Vec grad_g,int analysis_type,int sub_analysis_type){
-
-	int i;
-
-	/* node data: */
-	const int    numgrids=3;
-	const int    NDOF2=2;
-	double       xyz_list[numgrids][3];
-	int          doflist1[numgrids];
-	double       dh1dh3[NDOF2][numgrids];
-
-	/* grid data: */
-	double vx_list[numgrids];
-	double vy_list[numgrids];
-	double vz_list[numgrids];
-	double drag;
-	double  thickness_list[numgrids];
-	double  bed_list[numgrids];
-	double  dragcoefficient_list[numgrids];
-	double  drag_p,drag_q;
-	double alpha_complement_list[numgrids];
-	double alpha_complement;
-
-	/* gaussian points: */
-	int     num_gauss,ig;
-	double* first_gauss_area_coord  =  NULL;
-	double* second_gauss_area_coord =  NULL;
-	double* third_gauss_area_coord  =  NULL;
-	double* gauss_weights           =  NULL;
-	double  gauss_weight;
-	double  gauss_l1l2l3[3];
-	double  gaussgrids[numgrids][numgrids]={{1,0,0},{0,1,0},{0,0,1}};
-
-	/* parameters: */
-	double  vx,vy,vz;
-	double  lambda,mu,xi;
-	double  bed,thickness,Neff;
-	double  surface_normal[3];
-	double  bed_normal[3];
-	double  dk[NDOF2]; 
-
-	/*element vector at the gaussian points: */
-	double  grade_g[numgrids]={0.0};
-	double  grade_g_gaussian[numgrids];
-
-	/* Jacobian: */
-	double Jdet;
-
-	/*nodal functions: */
-	double l1l2l3[3];
-
-	/* strain rate: */
-	double epsilon[3]; /* epsilon=[exx,eyy,exy];*/
-
-	/*inputs: */
-	bool shelf;
-	int  drag_type;
-
-	/*parameters: */
-	double  cm_noisedmp;
-	double  cm_mindmp_slope;
-	double  cm_mindmp_value;
-	double  cm_maxdmp_value;
-	double  cm_maxdmp_slope;
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-	Matpar* matpar=NULL;
-	Matice* matice=NULL;
-
-	/*retrieve inputs :*/
-	inputs->GetParameterValue(&shelf,ElementOnIceShelfEnum);
-	inputs->GetParameterValue(&drag_type,DragTypeEnum);
-
-	/*retrieve some parameters: */
-	this->parameters->FindParam(&cm_noisedmp,CmNoiseDmpEnum);
-	this->parameters->FindParam(&cm_mindmp_value,CmMinDmpValueEnum);
-	this->parameters->FindParam(&cm_mindmp_slope,CmMinDmpSlopeEnum);
-	this->parameters->FindParam(&cm_maxdmp_value,CmMaxDmpValueEnum);
-	this->parameters->FindParam(&cm_maxdmp_slope,CmMaxDmpSlopeEnum);
-
-	/*Get out if shelf*/
-	if(shelf)return;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	matpar=(Matpar*)hmatpar.delivers();
-	matice=(Matice*)hmatice.delivers();
-
-	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
-	GetDofList1(&doflist1[0]);
-
-	/*Build alpha_complement_list: */
-	if (drag_type==2){
-
-		/*Allocate friction object: */
-		Friction* friction=NewFriction();
-
-		inputs->GetParameterValues(&vx_list[0],&gaussgrids[0][0],3,VxAverageEnum);
-		inputs->GetParameterValues(&vy_list[0],&gaussgrids[0][0],3,VyAverageEnum);
-		inputs->GetParameterValues(&vz_list[0],&gaussgrids[0][0],3,VzAverageEnum);
-		inputs->GetParameterValues(&dragcoefficient_list[0],&gaussgrids[0][0],3,DragCoefficientEnum);
-		inputs->GetParameterValues(&bed_list[0],&gaussgrids[0][0],3,BedEnum);
-		inputs->GetParameterValues(&thickness_list[0],&gaussgrids[0][0],3,ThicknessEnum);
-		inputs->GetParameterValue(&drag_p,DragPEnum);
-		inputs->GetParameterValue(&drag_q,DragQEnum);
-
-
-		/*Initialize all fields: */
-		friction->element_type=(char*)xmalloc((strlen("2d")+1)*sizeof(char));
-		strcpy(friction->element_type,"2d");
-
-		friction->gravity=matpar->GetG();
-		friction->rho_ice=matpar->GetRhoIce();
-		friction->rho_water=matpar->GetRhoWater();
-		friction->K=&dragcoefficient_list[0];
-		friction->bed=&bed_list[0];
-		friction->thickness=&thickness_list[0];
-		friction->vx=&vx_list[0];
-		friction->vy=&vy_list[0];
-		friction->p=drag_p;
-		friction->q=drag_q;
-
-
-		if(friction->p!=1) ISSMERROR("non-linear friction not supported yet in control methods!");
-
-		/*Compute alpha complement: */
-		FrictionGetAlphaComplement(&alpha_complement_list[0],friction);
-
-		/*Erase friction object: */
-		DeleteFriction(&friction);
-	}
-	else{
-		alpha_complement_list[0]=0;
-		alpha_complement_list[1]=0;
-		alpha_complement_list[2]=0;
-	}
-
-	/* Get gaussian points and weights (make this a statically initialized list of points? fstd): */
-	GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 4);
-
-	/* Start  looping on the number of gaussian points: */
-	for (ig=0; ig<num_gauss; ig++){
-		/*Pick up the gaussian point: */
-		gauss_weight=*(gauss_weights+ig);
-		gauss_l1l2l3[0]=*(first_gauss_area_coord+ig); 
-		gauss_l1l2l3[1]=*(second_gauss_area_coord+ig);
-		gauss_l1l2l3[2]=*(third_gauss_area_coord+ig);
-
-		/*Recover alpha_complement and k: */
-		GetParameterValue(&alpha_complement, &alpha_complement_list[0],gauss_l1l2l3);
-		inputs->GetParameterValue(&drag, &gauss_l1l2l3[0],DragCoefficientEnum);
-
-		/*recover lambda mu and xi: */
-		inputs->GetParameterValue(&lambda, &gauss_l1l2l3[0],AdjointxEnum);
-		inputs->GetParameterValue(&mu, &gauss_l1l2l3[0],AdjointyEnum);
-		inputs->GetParameterValue(&xi, &gauss_l1l2l3[0],AdjointzEnum);
-
-		/*recover vx vy and vz: */
-		inputs->GetParameterValue(&vx, &gauss_l1l2l3[0],VxEnum);
-		inputs->GetParameterValue(&vy, &gauss_l1l2l3[0],VyEnum);
-		inputs->GetParameterValue(&vz, &gauss_l1l2l3[0],VzEnum);
-
-		/*Get normal vector to the bed */
-		SurfaceNormal(&surface_normal[0],xyz_list);
-
-		bed_normal[0]=-surface_normal[0]; //Program is for surface, so the normal to the bed is the opposite of the result
-		bed_normal[1]=-surface_normal[1];
-		bed_normal[2]=-surface_normal[2];
-
-		/* Get Jacobian determinant: */
-		GetJacobianDeterminant3d(&Jdet, &xyz_list[0][0],gauss_l1l2l3);
-
-		/* Get nodal functions value at gaussian point:*/
-		GetNodalFunctions(l1l2l3, gauss_l1l2l3);
-
-		/*Get nodal functions derivatives*/
-		GetNodalFunctionsDerivatives(&dh1dh3[0][0],&xyz_list[0][0],gauss_l1l2l3);
-
-		/*Get k derivative: dk/dx */
-		inputs->GetParameterDerivativeValue(&dk[0],&xyz_list[0][0],&gauss_l1l2l3[0],DragCoefficientEnum);
-
-		/*Build gradje_g_gaussian vector (actually -dJ/ddrag): */
-		for (i=0;i<numgrids;i++){
-			//standard gradient dJ/dki
-			grade_g_gaussian[i]=(
-						-lambda*(2*drag*alpha_complement*(vx - vz*bed_normal[0]*bed_normal[2]))
-						-mu    *(2*drag*alpha_complement*(vy - vz*bed_normal[1]*bed_normal[2]))
-						-xi    *(2*drag*alpha_complement*(-vx*bed_normal[0]*bed_normal[2]-vy*bed_normal[1]*bed_normal[2]))
-						)*Jdet*gauss_weight*l1l2l3[i]; 
-
-			//Add regularization term
-			grade_g_gaussian[i]+= - cm_noisedmp*Jdet*gauss_weight*(dh1dh3[0][i]*dk[0]+dh1dh3[1][i]*dk[1]);
-
-			//min dampening
-			if(drag<cm_mindmp_value){ 
-				grade_g_gaussian[i]+= cm_mindmp_slope*Jdet*gauss_weight*l1l2l3[i];
-			}
-
-			//max dampening
-			if(drag>cm_maxdmp_value){ 
-				grade_g_gaussian[i]+= - cm_maxdmp_slope*Jdet*gauss_weight*l1l2l3[i];
-			}
-		}
-
-		/*Add gradje_g_gaussian vector to gradje_g: */
-		for( i=0; i<numgrids; i++)grade_g[i]+=grade_g_gaussian[i];
-	}
-
-	/*Add grade_g to global vector grad_g: */
-	VecSetValues(grad_g,numgrids,doflist1,(const double*)grade_g,ADD_VALUES);
-
-cleanup_and_return: 
-	xfree((void**)&first_gauss_area_coord);
-	xfree((void**)&second_gauss_area_coord);
-	xfree((void**)&third_gauss_area_coord);
-	xfree((void**)&gauss_weights);
-
-}
-/*}}}*/
-/*FUNCTION Tria::MassFlux {{{1*/
-double Tria::MassFlux( double* segment,double* ug){
-
-	int i;
-
-	const int    numgrids=3;
-	const int    numdofs=2;
-	int          numberofdofspernode;
-	double mass_flux=0;
-	int    doflist[numgrids*numdofs];
-	double vx_list[3];
-	double vy_list[3];
-	double xyz_list[numgrids][3];
-	double gauss_1[3];
-	double gauss_2[3];
-	double normal[2];
-	double length;
-	double x1,y1,x2,y2;
-	double h1,h2;
-	double vx1,vx2,vy1,vy2;
-	double rho_ice;
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-	Matpar* matpar=NULL;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	matpar=(Matpar*)hmatpar.delivers();
-
-	/*Get material parameters :*/
-	rho_ice=matpar->GetRhoIce();
-
-	/*First off, check that this segment belongs to this element: */
-	if ((int)*(segment+4)!=this->id)ISSMERROR("%s%i%s%i","error message: segment with id ",(int)*(segment+4)," does not belong to element with id:",this->id);
-
-	/*Recover segment node locations: */
-	x1=*(segment+0); y1=*(segment+1); x2=*(segment+2); y2=*(segment+3);
-
-	/*Get xyz list: */
-	GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
-
-	/*recover velocity at three element nodes: */
-	this->GetDofList(&doflist[0],&numberofdofspernode);
-	for(i=0;i<3;i++){
-		vx_list[i]=ug[doflist[numberofdofspernode*i+0]];
-		vy_list[i]=ug[doflist[numberofdofspernode*i+1]];
-	}
-
-	/*get area coordinates of 0 and 1 locations: */
-	for(i=0;i<3;i++){
-		gauss_1[i]=this->GetAreaCoordinate(x1,y1,i+1);
-		gauss_2[i]=this->GetAreaCoordinate(x2,y2,i+1);
-	}
-
-	/*get normal of segment: */
-	normal[0]=cos(atan2(x1-x2,y2-y1));
-	normal[1]=sin(atan2(x1-x2,y2-y1));
-
-	/*get length of segment: */
-	length=sqrt(pow(x2-x1,2.0)+pow(y2-y1,2));
-
-	/*get thickness and velocity at two segment extremities: */
-	inputs->GetParameterValue(&h1, &gauss_1[0],ThicknessEnum);
-	inputs->GetParameterValue(&h2, &gauss_2[0],ThicknessEnum);
-	inputs->GetParameterValue(&vx1, &gauss_1[0],VxEnum);
-	inputs->GetParameterValue(&vx2, &gauss_2[0],VxEnum);
-	inputs->GetParameterValue(&vy1, &gauss_1[0],VyEnum);
-	inputs->GetParameterValue(&vy2, &gauss_2[0],VyEnum);
-
-	mass_flux= rho_ice*length*(  
-				(ONETHIRD*(h1-h2)*(vx1-vx2)+0.5*h2*(vx1-vx2)+0.5*(h1-h2)*vx2+h2*vx2)*normal[0]+
-				(ONETHIRD*(h1-h2)*(vy1-vy2)+0.5*h2*(vy1-vy2)+0.5*(h1-h2)*vy2+h2*vy2)*normal[1]
-				);
-	return mass_flux;
-}
-/*}}}*/
-/*FUNCTION Tria::Misfit {{{1*/
-double Tria::Misfit(int analysis_type,int sub_analysis_type){
-
-	int i;
-
-	/* output: */
-	double Jelem=0;
-
-	/* node data: */
-	const int    numgrids=3;
-	const int    numdof=2*numgrids;
-	const int    NDOF2=2;
-	int          dofs1[1]={0};
-	int          dofs2[2]={0,1};
-	double       xyz_list[numgrids][3];
-
-	/* grid data: */
-	double vx_list[numgrids];
-	double vy_list[numgrids];
-	double obs_vx_list[numgrids];
-	double obs_vy_list[numgrids];
-	double misfit_list[numgrids];
-	double weights_list[numgrids];
-
-	/* gaussian points: */
-	int     num_gauss,ig;
-	double* first_gauss_area_coord  =  NULL;
-	double* second_gauss_area_coord =  NULL;
-	double* third_gauss_area_coord  =  NULL;
-	double* gauss_weights           =  NULL;
-	double  gauss_weight;
-	double  gauss_l1l2l3[3];
-	double  gaussgrids[numgrids][numgrids]={{1,0,0},{0,1,0},{0,0,1}};
-
-	/* parameters: */
-	double  velocity_mag,obs_velocity_mag;
-	double  misfit;
-
-	/* Jacobian: */
-	double Jdet;
-
-	/*relative and logarithmic control method :*/
-	double scalex=1;
-	double scaley=1;
-	double S=0;
-	double fit=-1;
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-	Matpar* matpar=NULL;
-	Matice* matice=NULL;
-
-	/*inputs: */
-	bool onwater;
-	
-	double  meanvel, epsvel;
-
-	/*retrieve inputs :*/
-	inputs->GetParameterValue(&onwater,ElementOnWaterEnum);
-
-	/*If on water, return 0: */
-	if(onwater)return 0;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-	matpar=(Matpar*)hmatpar.delivers();
-	matice=(Matice*)hmatice.delivers();
-
-	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
-
-	/* Recover input data: */
-	inputs->GetParameterValue(&fit,FitEnum);
-	if(fit==3){
-		inputs->GetParameterValue(&S,SurfaceAreaEnum);
-	}
-	inputs->GetParameterValues(&obs_vx_list[0],&gaussgrids[0][0],3,VxObsEnum);
-	inputs->GetParameterValues(&obs_vy_list[0],&gaussgrids[0][0],3,VyObsEnum);
-	inputs->GetParameterValues(&vx_list[0],&gaussgrids[0][0],3,VxEnum);
-	inputs->GetParameterValues(&vy_list[0],&gaussgrids[0][0],3,VyEnum);
-	inputs->GetParameterValues(&weights_list[0],&gaussgrids[0][0],3,WeightsEnum);
-
-	/*retrieve some parameters: */
-	this->parameters->FindParam(&meanvel,MeanVelEnum);
-	this->parameters->FindParam(&epsvel,EpsVelEnum);
-	
-	/* Compute Misfit at the 3 nodes
-	 * Here we integrate linearized functions:
-	 *               
-	 * J(E) = int_E   sum_{i=1}^3  J_i Phi_i
-	 *
-	 * where J_i are the misfits at the 3 nodes of the triangle
-	 *       Phi_i is the nodal function (P1) with respect to 
-	 *       the vertex i
-	 */
-	if(fit==0){
-		/*We are using an absolute misfit:
-		 *
-		 *      1  [           2              2 ]
-		 * J = --- | (u - u   )  +  (v - v   )  |
-		 *      2  [       obs            obs   ]
-		 *
-		 */
-		for (i=0;i<numgrids;i++){
-			misfit_list[i]=0.5*(pow((vx_list[i]-obs_vx_list[i]),(double)2)+pow((vy_list[i]-obs_vy_list[i]),(double)2));
-		}
-	}
-	else if(fit==1){
-		/*We are using a relative misfit: 
-		 *                        
-		 *      1  [     \bar{v}^2             2   \bar{v}^2              2 ]
-		 * J = --- | -------------  (u - u   ) + -------------  (v - v   )  |
-		 *      2  [  (u   + eps)^2       obs    (v   + eps)^2       obs    ]
-		 *              obs                        obs                      
-		 */
-		for (i=0;i<numgrids;i++){
-			scalex=pow(meanvel/(obs_vx_list[i]+epsvel),(double)2);
-			scaley=pow(meanvel/(obs_vy_list[i]+epsvel),(double)2);
-			if(obs_vx_list[i]==0)scalex=0;
-			if(obs_vy_list[i]==0)scaley=0;
-			misfit_list[i]=0.5*(scalex*pow((vx_list[i]-obs_vx_list[i]),2)+scaley*pow((vy_list[i]-obs_vy_list[i]),2));
-		}
-	}
-	else if(fit==2){
-		/*We are using a logarithmic misfit:
-		*                        
-		*                 [        vel + eps     ] 2
-		* J = 4 \bar{v}^2 | log ( -----------  ) |  
-		*                 [       vel   + eps    ]
-		*                            obs
-		*/
-		for (i=0;i<numgrids;i++){
-			velocity_mag=sqrt(pow(vx_list[i],(double)2)+pow(vy_list[i],(double)2))+epsvel; //epsvel to avoid velocity being nil.
-			obs_velocity_mag=sqrt(pow(obs_vx_list[i],(double)2)+pow(obs_vy_list[i],(double)2))+epsvel; //epsvel to avoid observed velocity being nil.
-			misfit_list[i]=4*pow(meanvel,(double)2)*pow(log(velocity_mag/obs_velocity_mag),(double)2);
-		}
-	}
-	else if(fit==3){
-		/*We are using an spacially average absolute misfit:
-		 *
-		 *      1                    2              2
-		 * J = ---  sqrt(  (u - u   )  +  (v - v   )  )
-		 *      S                obs            obs
-		 */
-		for (i=0;i<numgrids;i++){
-			misfit_list[i]=sqrt(pow(vx_list[i]-obs_vx_list[i],2)+pow(vy_list[i]-obs_vx_list[i],2))/S;
-		}
-	}
-	else if(fit==4){
-		/*We are using an logarithmic 2 misfit:
-		 *
-		 *      1            [        |u| + eps     2          |v| + eps     2  ]
-		 * J = --- \bar{v}^2 | log ( -----------  )   +  log ( -----------  )   |  
-		 *      2            [       |u    |+ eps              |v    |+ eps     ]
-		 *                              obs                       obs
-		 */
-		for (i=0;i<numgrids;i++){
-			misfit_list[i]=0.5*pow(meanvel,(double)2)*(
-			  pow(log((fabs(vx_list[i])+epsvel)/(fabs(obs_vx_list[i])+epsvel)),(double)2) +
-			  pow(log((fabs(vy_list[i])+epsvel)/(fabs(obs_vy_list[i])+epsvel)),(double)2) );
-		}
-	}
-	else{
-		/*Not supported yet! : */
-		ISSMERROR("%s%g","unsupported type of fit: ",fit);
-	}
-
-	/*Apply weights to misfits*/
-	for (i=0;i<numgrids;i++){
-		misfit_list[i]=weights_list[i]*misfit_list[i];
-	}
-
-	/* Get gaussian points and weights (make this a statically initialized list of points? fstd): */
-	GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2);
-
-	/* Start  looping on the number of gaussian points: */
-	for (ig=0; ig<num_gauss; ig++){
-		/*Pick up the gaussian point: */
-		gauss_weight=*(gauss_weights+ig);
-		gauss_l1l2l3[0]=*(first_gauss_area_coord+ig); 
-		gauss_l1l2l3[1]=*(second_gauss_area_coord+ig);
-		gauss_l1l2l3[2]=*(third_gauss_area_coord+ig);
-
-		/* Get Jacobian determinant: */
-		GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss_l1l2l3);
-
-		/*Compute misfit at gaussian point: */
-		GetParameterValue(&misfit, &misfit_list[0],gauss_l1l2l3);
-
-		/*compute Misfit*/
-		Jelem+=misfit*Jdet*gauss_weight;
-	}
-
-	xfree((void**)&first_gauss_area_coord);
-	xfree((void**)&second_gauss_area_coord);
-	xfree((void**)&third_gauss_area_coord);
-	xfree((void**)&gauss_weights);
-		
-	/*Return: */
-	return Jelem;
-}
-/*}}}*/
-/*FUNCTION Tria::MyRank {{{1*/
-int    Tria::MyRank(void){ 
-	extern int my_rank;
-	return my_rank; 
-}
-/*}}}*/
-/*FUNCTION Tria::Tria::SetClone {{{1*/
-void  Tria::SetClone(int* minranks){
-
-	ISSMERROR("not implemented yet");
-}
-/*}}}1*/
-/*FUNCTION Tria::SurfaceNormal{{{1*/
-
-void Tria::SurfaceNormal(double* surface_normal, double xyz_list[3][3]){
-
-	int i;
-	double v13[3];
-	double v23[3];
-	double normal[3];
-	double normal_norm;
-
-	for (i=0;i<3;i++){
-		v13[i]=xyz_list[0][i]-xyz_list[2][i];
-		v23[i]=xyz_list[1][i]-xyz_list[2][i];
-	}
-
-	normal[0]=v13[1]*v23[2]-v13[2]*v23[1];
-	normal[1]=v13[2]*v23[0]-v13[0]*v23[2];
-	normal[2]=v13[0]*v23[1]-v13[1]*v23[0];
-
-	normal_norm=sqrt( pow(normal[0],(double)2)+pow(normal[1],(double)2)+pow(normal[2],(double)2) );
-
-	*(surface_normal)=normal[0]/normal_norm;
-	*(surface_normal+1)=normal[1]/normal_norm;
-	*(surface_normal+2)=normal[2]/normal_norm;
-
-}
-/*}}}*/
-/*FUNCTION Tria::SurfaceArea {{{1*/
-double Tria::SurfaceArea(int analysis_type,int sub_analysis_type){
-
-	int i;
-
-	/* output: */
-	double S;
-
-	/* node data: */
-	int numgrids=3;
-	double xyz_list[numgrids][3];
-	double v13[3];
-	double v23[3];
-	double normal[3];
-
-	/*dynamic objects pointed to by hooks: */
-	Node**  nodes=NULL;
-
-	/*inputs: */
-	bool onwater;
-	int  fit;
-
-	/*retrieve inputs :*/
-	inputs->GetParameterValue(&fit,FitEnum);
-	inputs->GetParameterValue(&onwater,ElementOnWaterEnum);
-
-	/*If fit!=3, do not compute surface: */
-	if(fit!=3)return 0;
-
-	/*recover objects from hooks: */
-	nodes=(Node**)hnodes.deliverp();
-
-	/*If on water, return 0: */
-	if(onwater)return 0;
-
-	/* Get node coordinates and dof list: */
-	GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
-
-	for (i=0;i<3;i++){
-		v13[i]=xyz_list[0][i]-xyz_list[2][i];
-		v23[i]=xyz_list[1][i]-xyz_list[2][i];
-	}
-
-	normal[0]=v13[1]*v23[2]-v13[2]*v23[1];
-	normal[1]=v13[2]*v23[0]-v13[0]*v23[2];
-	normal[2]=v13[0]*v23[1]-v13[1]*v23[0];
-
-	S = 0.5 * sqrt(pow(normal[0],(double)2)+pow(normal[1],(double)2)+pow(normal[2],(double)2));
-
-	/*Return: */
-	return S;
-}
-/*}}}*/
Index: sm/trunk/src/c/objects/Tria.h
===================================================================
--- /issm/trunk/src/c/objects/Tria.h	(revision 3680)
+++ 	(revision )
@@ -1,134 +1,0 @@
-/*! \file Tria.h 
- *  \brief: header file for tria object
- */
-
-#ifndef _TRIA_H_
-#define _TRIA_H_
-
-/*Headers:*/
-/*{{{1*/
-#include "./Object.h"
-#include "./Element.h"
-#include "../include/macros.h"
-#include "../shared/Exceptions/exceptions.h"
-#include "./Hook.h"
-#include "./Node.h"
-#include "../ModelProcessorx/IoModel.h"
-#include "../DataSet/DataSet.h"
-#include "../DataSet/Parameters.h"
-#include "../DataSet/Inputs.h"
-/*}}}*/
-
-class Tria: public Element{
-
-	public:
-
-		int  id;
-
-		Hook hnodes;  //hook to 3 nodes
-		Hook hmatice; //hook to 1 matice
-		Hook hmatpar; //hook to 1 matpar
-
-		Parameters* parameters; //pointer to solution parameters
-		Inputs*  inputs;
-
-		/*FUNCTION constructors, destructors {{{1*/
-		Tria();
-		Tria(int tria_id,int* tria_node_ids, int tria_matice_id, int tria_matpar_id);
-		Tria(int tria_id,Hook* tria_hnodes, Hook* tria_hmatice, Hook* tria_hmatpar, Parameters* parameters, Inputs* tria_inputs);
-		Tria(int tria_id,int i, IoModel* iomodel);
-		~Tria();
-		/*}}}*/
-		/*FUNCTION object management {{{1*/
-		void  Configure(DataSet* loads,DataSet* nodes,DataSet* materials,Parameters* parameters);
-		Object* copy();
-		void  DeepEcho();
-		void  Demarshall(char** pmarshalled_dataset);
-		void  Echo();
-		int   Enum();
-		int   Id(); 
-		void  Marshall(char** pmarshalled_dataset);
-		int   MarshallSize();
-		int   MyRank();
-		void  SetClone(int* minranks);
-		/*}}}*/
-		/*FUNCTION element numerical routines {{{1*/
-		void  CreateKMatrix(Mat Kgg,int analysis_type,int sub_analysis_type);
-		void  CreatePVector(Vec pg,  int analysis_type,int sub_analysis_type);
-				void  GetDofList(int* doflist,int* pnumberofdofs);
-		void  GetDofList1(int* doflist);
-		void  CreateKMatrixDiagnosticHoriz(Mat Kgg,int analysis_type,int sub_analysis_type);
-		void  CreateKMatrixDiagnosticHorizFriction(Mat Kgg,int analysis_type,int sub_analysis_type);
-		void  CreateKMatrixDiagnosticSurfaceVert(Mat Kgg,int analysis_type,int sub_analysis_type);
-		void  CreateKMatrixSlopeCompute(Mat Kgg,int analysis_type,int sub_analysis_type);
-		void  GetParameterValue(double* pp, double* plist, double* gauss_l1l2l3);
-		void  GetParameterDerivativeValue(double* p, double* plist,double* xyz_list, double* gauss_l1l2l3);
-		void  GetStrainRate(double* epsilon, double* velocity, double* xyz_list, double* gauss_l1l2l3);
-		void  GetJacobianDeterminant2d(double*  Jdet, double* xyz_list,double* gauss_l1l2l3);
-		void  GetJacobianDeterminant3d(double*  Jdet, double* xyz_list,double* gauss_l1l2l3);
-		void  GetB(double* B, double* xyz_list, double* gauss_l1l2l3);
-		void  GetBPrime(double* Bprime, double* xyz_list, double* gauss_l1l2l3);
-		void  GetL(double* L, double* xyz_list, double* gauss_l1l2l3,int numdof);
-		void  GetB_prog(double* B_prog, double* xyz_list, double* gauss_l1l2l3);
-		void  GetBPrime_prog(double* Bprime_prog, double* xyz_list, double* gauss_l1l2l3);
-		void  GetNodalFunctions(double* l1l2l3, double* gauss_l1l2l3);
-		void  GetNodalFunctionsDerivatives(double* dh1dh3,double* xyz_list, double* gauss_l1l2l3);
-		void  GetNodalFunctionsDerivativesReference(double* dl1dl3,double* gauss_l1l2l3);
-		void  GetJacobianInvert(double*  Jinv, double* xyz_list,double* gauss_l1l2l3);
-		void  GetJacobian(double* J, double* xyz_list,double* gauss_l1l2l3);
-		void  Du(Vec du_g,int analysis_type,int sub_analysis_type);
-		void  Gradj(Vec grad_g,int analysis_type,int sub_analysis_type,char* control_type);
-		void  GradjDrag(Vec grad_g,int analysis_type,int sub_analysis_type);
-		void  GradjDragStokes(Vec grad_g,int analysis_type,int sub_analysis_type);
-		void  SurfaceNormal(double* surface_normal, double xyz_list[3][3]);
-		void  GradjB(Vec grad_g,int analysis_type,int sub_analysis_type);
-		double Misfit(int analysis_type,int sub_analysis_type);
-		double SurfaceArea(int analysis_type,int sub_analysis_type);
-		double CostFunction(int analysis_type,int sub_analysis_type);
-
-		void  CreatePVectorDiagnosticHoriz(Vec pg,int analysis_type,int sub_analysis_type);
-		void  CreatePVectorDiagnosticBaseVert(Vec pg,int analysis_type,int sub_analysis_type);
-		void  CreatePVectorSlopeCompute( Vec pg,  int analysis_type,int sub_analysis_type);
-		void* GetMatPar();
-		bool  GetShelf();
-		void  GetNodes(void** nodes);
-		bool  GetOnBed();
-		void  GetThicknessList(double* thickness_list);
-		void  GetBedList(double* bed_list);
-		void  ComputeBasalStress(Vec sigma_b,int analysis_type,int sub_analysis_type);
-		void  ComputePressure(Vec p_g,int analysis_type,int sub_analysis_type);
-		void  ComputeStrainRate(Vec eps,int analysis_type,int sub_analysis_type);
-		void  CreateKMatrixThermal(Mat Kgg,int analysis_type,int sub_analysis_type);
-		void  CreateKMatrixMelting(Mat Kgg,int analysis_type,int sub_analysis_type);
-		void  CreatePVectorThermalShelf( Vec pg,  int analysis_type,int sub_analysis_type);
-		void  CreatePVectorThermalSheet( Vec pg,  int analysis_type,int sub_analysis_type);
-		void  CreateKMatrixPrognostic(Mat Kgg,int analysis_type,int sub_analysis_type);
-		void  CreatePVectorPrognostic(Vec pg,int analysis_type,int sub_analysis_type);
-		void  CreateKMatrixPrognostic2(Mat Kgg,int analysis_type,int sub_analysis_type);
-		void  CreatePVectorPrognostic2(Vec pg,int analysis_type,int sub_analysis_type);
-		void  CreateKMatrixBalancedthickness(Mat Kgg,int analysis_type,int sub_analysis_type);
-		void  CreatePVectorBalancedthickness(Vec pg,int analysis_type,int sub_analysis_type);
-		void  CreateKMatrixBalancedthickness2(Mat Kgg,int analysis_type,int sub_analysis_type);
-		void  CreatePVectorBalancedthickness2(Vec pg,int analysis_type,int sub_analysis_type);
-		void  CreateKMatrixBalancedvelocities(Mat Kgg,int analysis_type,int sub_analysis_type);
-		void  CreatePVectorBalancedvelocities(Vec pg,int analysis_type,int sub_analysis_type);
-		double MassFlux(double* segment,double* ug);
-		double GetArea(void);
-		double GetAreaCoordinate(double x, double y, int which_one);
-
-		/*updates:*/
-		void  UpdateFromDakota(void* inputs);
-		void  UpdateInputs(double* solution, int analysis_type, int sub_analysis_type);
-		void  UpdateInputsDiagnosticHoriz( double* solution,int analysis_type,int sub_analysis_type);
-		void  UpdateInputsSlopeCompute( double* solution,int analysis_type,int sub_analysis_type);
-		void  UpdateInputsPrognostic( double* solution,int analysis_type,int sub_analysis_type);
-		void  UpdateInputsPrognostic2(double* solution,int analysis_type,int sub_analysis_type);
-		void  UpdateInputsBalancedthickness( double* solution,int analysis_type,int sub_analysis_type);
-		void  UpdateInputsBalancedthickness2( double* solution,int analysis_type,int sub_analysis_type);
-		void  UpdateInputsBalancedvelocities( double* solution,int analysis_type,int sub_analysis_type);
-		void  AddInput(double value, int enum_type){ISSMERROR("not supporte yet!");}
-
-		/*}}}*/
-
-};
-#endif  /* _TRIA_H */
Index: /issm/trunk/src/c/objects/Vertex.cpp
===================================================================
--- /issm/trunk/src/c/objects/Vertex.cpp	(revision 3680)
+++ /issm/trunk/src/c/objects/Vertex.cpp	(revision 3681)
@@ -11,5 +11,5 @@
 
 #include <string.h>
-#include "./Vertex.h"
+#include "./objects.h"
 #include "../EnumDefinitions/EnumDefinitions.h"
 #include "../include/macros.h"
@@ -17,5 +17,4 @@
 #include "../include/typedefs.h"
 #include "../include/macros.h"
-#include "../ModelProcessorx/IoModel.h"
 /*}}}*/
 
Index: /issm/trunk/src/c/objects/Vertex.h
===================================================================
--- /issm/trunk/src/c/objects/Vertex.h	(revision 3680)
+++ /issm/trunk/src/c/objects/Vertex.h	(revision 3681)
@@ -8,10 +8,7 @@
 /*Headers:*/
 /*{{{1*/
-class Object;
-class DofObject;
-
-#include "../ModelProcessorx/IoModel.h"
 #include "./Object.h"
 #include "./DofObject.h"
+class IoModel;
 /*}}}*/
 
Index: /issm/trunk/src/c/objects/objects.h
===================================================================
--- /issm/trunk/src/c/objects/objects.h	(revision 3680)
+++ /issm/trunk/src/c/objects/objects.h	(revision 3681)
@@ -6,46 +6,77 @@
 #define ALL_OBJECTS_H_
 
-/*Abstract class: */
+/*Abstract classes: */
 #include "./Object.h"
 
-/*C++ Objects: */
-#include "./Material.h"
-#include "./Matice.h"
-#include "./Matpar.h"
+
+/*Objects: */
+#include "./Hook.h"
+#include "./DofIndexing.h"
+#include "./Vertex.h"
 #include "./Node.h"
-#include "./Penta.h"
-#include "./Tria.h"
-#include "./Sing.h"
-#include "./Beam.h"
-#include "./Spc.h"
-#include "./Result.h"
-#include "./Rgb.h"
-#include "./Icefront.h"
-#include "./Riftfront.h"
-#include "./Penpair.h"
-#include "./Pengrid.h"
-#include "./Numericalflux.h"
-#include "./Param.h"
-#include "./DoubleParam.h"
-#include "./Element.h" 
 #include "./NodeSets.h"
 #include "./Model.h"
-#include "./Input.h"
-#include "./TriaVertexInput.h"
-#include "./Vertex.h"
-#include "./BoolInput.h"
-#include "./IntInput.h"
-#include "./DoubleInput.h"
+#include "./Result.h"
+#include "./IoModel.h"
+
+/*Constraints: */
+#include "./Constraints/Spc.h"
+#include "./Constraints/Rgb.h"
+
+/*Loads: */
+#include "./Loads/Friction.h"
+#include "./Loads/Icefront.h"
+#include "./Loads/Numericalflux.h"
+#include "./Loads/Riftfront.h"
+#include "./Loads/Penpair.h"
+#include "./Loads/Pengrid.h"
+
+/*Elements: */
+#include "./Elements/Beam.h"
+#include "./Elements/Element.h"
+#include "./Elements/Penta.h"
+#include "./Elements/Tria.h"
+#include "./Elements/Sing.h"
+
+/*Inputs: */
+#include "./Inputs/Input.h"
+#include "./Inputs/BoolInput.h"
+#include "./Inputs/DoubleInput.h"
+#include "./Inputs/IntInput.h"
+#include "./Inputs/BeamVertexInput.h"
+#include "./Inputs/PentaVertexInput.h"
+#include "./Inputs/SingVertexInput.h"
+#include "./Inputs/TriaVertexInput.h"
+
+/*Materials: */
+#include "./Materials/Material.h"
+#include "./Materials/Matice.h"
+#include "./Materials/Matpar.h"
+
+
+/*Params: */
+#include "./Params/BoolParam.h"
+#include "./Params/DoubleMatParam.h"
+#include "./Params/DoubleParam.h"
+#include "./Params/DoubleVecParam.h"
+#include "./Params/IntParam.h"
+#include "./Params/Param.h"
+#include "./Params/PetscMatParam.h"
+#include "./Params/PetscVecParam.h"
+#include "./Params/StringArrayParam.h"
+#include "./Params/StringParam.h"
 
 /*C objects: */
 #include "./Contour.h"
-#include "./Friction.h"
 #include "./SolverEnum.h"
 #include "./FemModel.h"
 #include "./OptArgs.h"
 #include "./OptPars.h"
-#include "./BamgGeom.h"
-#include "./BamgMesh.h"
-#include "./BamgOpts.h"
+#include "./DofVec.h"
+
+/*Bamg: */
+#include "./Bamg/BamgGeom.h"
+#include "./Bamg/BamgMesh.h"
+#include "./Bamg/BamgOpts.h"
 
 #endif
