Index: /issm/trunk/src/c/objects/Beam.cpp
===================================================================
--- /issm/trunk/src/c/objects/Beam.cpp	(revision 3401)
+++ /issm/trunk/src/c/objects/Beam.cpp	(revision 3402)
@@ -24,4 +24,34 @@
 }
 /*}}}*/
+/*FUNCTION Beam constructor {{{1*/
+Beam::Beam(int beam_id,int* beam_node_ids, int beam_matice_id, int beam_matpar_id, int beam_numpar_id, ElementProperties* beamproperties): 
+	hnodes(beam_node_ids,2),
+	hmatice(&beam_matice_id,1),
+	hmatpar(&beam_matpar_id,1),
+	hnumpar(&beam_numpar_id,1),
+	properties(beamproperties)
+{
+
+	/*all the initialization has been done by the initializer, just fill in the id: */
+	this->id=beam_id;
+
+	return;
+}
+/*}}}*/
+/*FUNCTION Beam other constructor {{{1*/
+Beam::Beam(int beam_id,Hook* beam_hnodes, Hook* beam_hmatice, Hook* beam_hmatpar, Hook* beam_hnumpar, ElementProperties* beam_properties):
+	hnodes(beam_hnodes),
+	hmatice(beam_hmatice),
+	hmatpar(beam_hmatpar),
+	hnumpar(beam_hnumpar),
+	properties(beam_properties)
+{
+
+	/*all the initialization has been done by the initializer, just fill in the id: */
+	this->id=beam_id;
+
+	return;
+}
+/*}}}*/
 /*FUNCTION Beam destructor {{{1*/
 Beam::~Beam(){
@@ -29,137 +59,200 @@
 }
 /*}}}*/
-/*FUNCTION Beam creation {{{1*/
-Beam::Beam(int beam_id, int beam_mid, int beam_mparid, int beam_numparid, int beam_g[2], double beam_h[2], double beam_s[2],double beam_b[2],double beam_k[2],bool beam_onbed){
+
+/*Object management*/
+/*FUNCTION Beam Configure{{{1*/
+void  Beam::Configure(void* ploadsin,void* pnodesin,void* pmaterialsin,void* pparametersin){
 
 	int i;
 	
-	id=beam_id;
-	mid=beam_mid;
-	mparid=beam_mparid;
-	numparid=beam_numparid;
-	for(i=0;i<2;i++){
-		node_ids[i]=beam_g[i];
-		node_offsets[i]=UNDEF;
-		nodes[i]=NULL;
-		h[i]=beam_h[i];
-		s[i]=beam_s[i];
-		b[i]=beam_b[i];
-		k[i]=beam_k[i];
-	}
-	matice=NULL;
-	matice_offset=UNDEF;
-	matpar=NULL;
-	matpar_offset=UNDEF;
-	numpar=NULL;
-	numpar_offset=UNDEF;
-	onbed=beam_onbed;
-	
+	DataSet* loadsin=NULL;
+	DataSet* nodesin=NULL;
+	DataSet* materialsin=NULL;
+	DataSet* parametersin=NULL;
+
+	/*Recover pointers :*/
+	loadsin=(DataSet*)ploadsin;
+	nodesin=(DataSet*)pnodesin;
+	materialsin=(DataSet*)pmaterialsin;
+	parametersin=(DataSet*)pparametersin;
+
+	/*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);
+	hnumpar.configure(parametersin);
+
+}
+/*}}}*/
+/*FUNCTION Beam copy{{{1*/
+Object* Beam::copy() {
+	
+	return new Beam(this->id,&this->hnodes,&this->hmatice,&this->hmatpar,&this->hnumpar,&this->properties);
+
+}
+/*}}}*/
+/*FUNCTION Beam DeepEcho{{{1*/
+void Beam::DeepEcho(void){
+
+	printf("Beam:\n");
+	printf("   id: %i\n",id);
+	hnodes.DeepEcho();
+	hmatice.DeepEcho();
+	hmatpar.DeepEcho();
+	hnumpar.DeepEcho();
+	properties.DeepEcho();
+
 	return;
 }
 /*}}}*/
-
-/*Object marshall*/
-/*FUNCTION Beam Marshall{{{1*/
-void  Beam::Marshall(char** pmarshalled_dataset){
+/*FUNCTION Beam Demarshall{{{1*/
+void  Beam::Demarshall(char** pmarshalled_dataset){
 
 	char* marshalled_dataset=NULL;
-	int   enum_type=0;
+	int   i;
 
 	/*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);
-	memcpy(marshalled_dataset,&mid,sizeof(mid));marshalled_dataset+=sizeof(mid);
-	memcpy(marshalled_dataset,&mparid,sizeof(mparid));marshalled_dataset+=sizeof(mparid);
-	memcpy(marshalled_dataset,&node_ids,sizeof(node_ids));marshalled_dataset+=sizeof(node_ids);
-	memcpy(marshalled_dataset,&nodes,sizeof(nodes));marshalled_dataset+=sizeof(nodes);
-	memcpy(marshalled_dataset,&node_offsets,sizeof(node_offsets));marshalled_dataset+=sizeof(node_offsets);
-	memcpy(marshalled_dataset,&matice,sizeof(matice));marshalled_dataset+=sizeof(matice);
-	memcpy(marshalled_dataset,&matice_offset,sizeof(matice_offset));marshalled_dataset+=sizeof(matice_offset);
-	memcpy(marshalled_dataset,&matpar,sizeof(matpar));marshalled_dataset+=sizeof(matpar);
-	memcpy(marshalled_dataset,&matpar_offset,sizeof(matpar_offset));marshalled_dataset+=sizeof(matpar_offset);
-	memcpy(marshalled_dataset,&numparid,sizeof(numparid));marshalled_dataset+=sizeof(numparid);
-	memcpy(marshalled_dataset,&numpar,sizeof(numpar));marshalled_dataset+=sizeof(numpar);
-	memcpy(marshalled_dataset,&numpar_offset,sizeof(numpar_offset));marshalled_dataset+=sizeof(numpar_offset);
-	memcpy(marshalled_dataset,&h,sizeof(h));marshalled_dataset+=sizeof(h);
-	memcpy(marshalled_dataset,&s,sizeof(s));marshalled_dataset+=sizeof(s);
-	memcpy(marshalled_dataset,&b,sizeof(b));marshalled_dataset+=sizeof(b);
-	memcpy(marshalled_dataset,&k,sizeof(k));marshalled_dataset+=sizeof(k);
-	memcpy(marshalled_dataset,&onbed,sizeof(onbed));marshalled_dataset+=sizeof(onbed);
-	
-	*pmarshalled_dataset=marshalled_dataset;
-	return;
-}
-/*}}}*/
-/*FUNCTION Beam MarshallSize{{{1*/
-int   Beam::MarshallSize(){
-	return sizeof(id)
-		+sizeof(mid)
-		+sizeof(mparid)
-		+sizeof(node_ids)
-		+sizeof(nodes)
-		+sizeof(node_offsets)
-		+sizeof(matice)
-		+sizeof(matice_offset)
-		+sizeof(matpar)
-		+sizeof(matpar_offset)
-		+sizeof(numparid)
-		+sizeof(numpar)
-		+sizeof(numpar_offset)
-		+sizeof(h)
-		+sizeof(s)
-		+sizeof(b)
-		+sizeof(k)
-		+sizeof(onbed)
-		+sizeof(int); //sizeof(int) for enum type
-}
-/*}}}*/
-/*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);
-	memcpy(&mid,marshalled_dataset,sizeof(mid));marshalled_dataset+=sizeof(mid);
-	memcpy(&mparid,marshalled_dataset,sizeof(mparid));marshalled_dataset+=sizeof(mparid);
-	memcpy(&node_ids,marshalled_dataset,sizeof(node_ids));marshalled_dataset+=sizeof(node_ids);
-	memcpy(&nodes,marshalled_dataset,sizeof(nodes));marshalled_dataset+=sizeof(nodes);
-	memcpy(&node_offsets,marshalled_dataset,sizeof(node_offsets));marshalled_dataset+=sizeof(node_offsets);
-	memcpy(&matice,marshalled_dataset,sizeof(matice));marshalled_dataset+=sizeof(matice);
-	memcpy(&matice_offset,marshalled_dataset,sizeof(matice_offset));marshalled_dataset+=sizeof(matice_offset);
-	memcpy(&matpar,marshalled_dataset,sizeof(matpar));marshalled_dataset+=sizeof(matpar);
-	memcpy(&matpar_offset,marshalled_dataset,sizeof(matpar_offset));marshalled_dataset+=sizeof(matpar_offset);
-	memcpy(&numparid,marshalled_dataset,sizeof(numparid));marshalled_dataset+=sizeof(numparid);
-	memcpy(&numpar,marshalled_dataset,sizeof(numpar));marshalled_dataset+=sizeof(numpar);
-	memcpy(&numpar_offset,marshalled_dataset,sizeof(numpar_offset));marshalled_dataset+=sizeof(numpar_offset);
-	memcpy(&h,marshalled_dataset,sizeof(h));marshalled_dataset+=sizeof(h);
-	memcpy(&s,marshalled_dataset,sizeof(s));marshalled_dataset+=sizeof(s);
-	memcpy(&b,marshalled_dataset,sizeof(b));marshalled_dataset+=sizeof(b);
-	memcpy(&k,marshalled_dataset,sizeof(k));marshalled_dataset+=sizeof(k);
-	memcpy(&onbed,marshalled_dataset,sizeof(onbed));marshalled_dataset+=sizeof(onbed);
-
-	/*nodes and materials are not pointing to correct objects anymore:*/
-	for(i=0;i<2;i++)nodes[i]=NULL;
-	matice=NULL;
-	matpar=NULL;
-	numpar=NULL;
+
+	/*demarshall hooks: */
+	hnodes.Demarshall(&marshalled_dataset);
+	hmatice.Demarshall(&marshalled_dataset);
+	hmatpar.Demarshall(&marshalled_dataset);
+	hnumpar.Demarshall(&marshalled_dataset);
+
+	/*demarshall properties: */
+	properties.Demarshall(&marshalled_dataset);
 
 	/*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();
+	hnumpar.Echo();
+	properties.Echo();
+
+	return;
+}
+/*}}}*/
+/*FUNCTION Beam Marshall{{{1*/
+void  Beam::Marshall(char** pmarshalled_dataset){
+
+	char* marshalled_dataset=NULL;
+	int   enum_type=0;
+
+	/*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);
+	hnumpar.Marshall(&marshalled_dataset);
+
+	/*Marshall properties: */
+	properties.Marshall(&marshalled_dataset);
+
+	*pmarshalled_dataset=marshalled_dataset;
+	return;
+}
+/*}}}*/
+/*FUNCTION Beam MarshallSize{{{1*/
+int   Beam::MarshallSize(){
+	
+	return sizeof(id)
+		+hnodes.MarshallSize()
+		+hmatice.MarshallSize()
+		+hmatpar.MarshallSize()
+		+hnumpar.MarshallSize()
+		+properties.MarshallSize()
+		+sizeof(int); //sizeof(int) for enum type
+}
+/*}}}*/
+/*FUNCTION Beam UpdateFromInputs{{{1*/
+void  Beam::UpdateFromInputs(void* vinputs){
+
+	int     dofs[1]={0};
+	double  temperature_list[2];
+	double  temperature_average;
+	double  B_list[2];
+	double  B_average;
+
+	/*dynamic objects pointed to by hooks: */
+	Node**  nodes=NULL;
+	Matpar* matpar=NULL;
+	Matice* matice=NULL;
+	Numpar* numpar=NULL;
+
+	ParameterInputs* inputs=NULL;
+
+	/*recover pointers: */
+	inputs=(ParameterInputs*)vinputs;
+
+	/*recover objects from hooks: */
+	nodes=(Node**)hnodes.deliverp();
+	matpar=(Matpar*)hmatpar.delivers();
+	matice=(Matice*)hmatice.delivers();
+	numpar=(Numpar*)hnumpar.delivers();
+
+	/*Update internal data if inputs holds new values: */
+	//if (id==1) printf("WARNING if QMU: no hydrostatic equilibrium is applied here (conflict with prognostic, which does not have matpar)\n");
+	//For now
+	if(this->properties.h) inputs->Recover("thickness",&this->properties.h[0],1,dofs,2,(void**)nodes);
+	//Later
+	/*
+		if(inputs->Recover("thickness",&new_h[0],1,dofs,2,(void**)nodes)){
+	//density, needed later:
+	double di=(this->matpar->GetRhoIce()/this->matpar->GetRhoWater());
+	//Go through grids:
+	for (i=0;i<2;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];
+	}
+	}
+	*/
+	if (this->properties.s)              inputs->Recover("surface",&this->properties.s[0],1,dofs,2,(void**)nodes);
+	if (this->properties.b)              inputs->Recover("bed",&this->properties.b[0],1,dofs,2,(void**)nodes);
+	if (this->properties.k)              inputs->Recover("drag",&this->properties.k[0],1,dofs,2,(void**)nodes);
+	if (this->properties.melting)        inputs->Recover("melting",&this->properties.melting[0],1,dofs,2,(void**)nodes);
+	if (this->properties.accumulation)   inputs->Recover("accumulation",&this->properties.accumulation[0],1,dofs,2,(void**)nodes);
+	if (this->properties.geothermalflux) inputs->Recover("geothermalflux",&this->properties.geothermalflux[0],1,dofs,2,(void**)nodes);
+	
+	//Update material if necessary
+	if(inputs->Recover("temperature_average",&temperature_list[0],1,dofs,2,(void**)nodes)){
+		temperature_average=(temperature_list[0]+temperature_list[1])/2.0;
+		B_average=Paterson(temperature_average);
+		matice->SetB(B_average);
+	}
+	
+	if(inputs->Recover("B",&B_list[0],1,dofs,2,(void**)nodes)){
+		B_average=(B_list[0]+B_list[1])/2.0;
+		matice->SetB(B_average);
+	}
+
 }
 /*}}}*/
@@ -176,4 +269,20 @@
 	double xyz_list[numgrids][3];
 
+	/*dynamic objects pointed to by hooks: */
+	Node**  nodes=NULL;
+	Matpar* matpar=NULL;
+	Matice* matice=NULL;
+	Numpar* numpar=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();
+	numpar=(Numpar*)hnumpar.delivers();
+
 	/*Get node data: */
 	GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
@@ -186,44 +295,9 @@
 	g=matpar->GetG();
 	for(i=0;i<numgrids;i++){
-		pressure[i]=rho_ice*g*(s[i]-xyz_list[i][2]);
+		pressure[i]=rho_ice*g*(this->properties.s[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 Configure{{{1*/
-void  Beam::Configure(void* ploadsin,void* pnodesin,void* pmaterialsin,void* pparametersin){
-
-	int i;
-	
-	DataSet* loadsin=NULL;
-	DataSet* nodesin=NULL;
-	DataSet* materialsin=NULL;
-	DataSet* parametersin=NULL;
-
-	/*Recover pointers :*/
-	loadsin=(DataSet*)ploadsin;
-	nodesin=(DataSet*)pnodesin;
-	materialsin=(DataSet*)pmaterialsin;
-	parametersin=(DataSet*)pparametersin;
-
-	/*Link this element with its nodes, ie find pointers to the nodes in the nodes dataset.: */
-	ResolvePointers((Object**)nodes,node_ids,node_offsets,2,nodesin);
-	
-	/*Same for materials: */
-	ResolvePointers((Object**)&matice,&mid,&matice_offset,1,materialsin);
-	ResolvePointers((Object**)&matpar,&mparid,&matpar_offset,1,materialsin);
-
-	/*Same for numpar: */
-	ResolvePointers((Object**)&numpar,&numparid,&numpar_offset,1,parametersin);
-
-}
-/*}}}*/
-/*FUNCTION Beam copy{{{1*/
-Object* Beam::copy() {
-	
-	return new Beam(*this); 
 
 }
@@ -268,5 +342,5 @@
 	GetDofList(&doflist[0],&numberofdofspernode);
 
-	if (onbed){
+	if (this->properties.onbed){
 		Ke_gg[0][0]=1;
 		Ke_gg[1][1]=1;
@@ -340,8 +414,20 @@
 	double   ub,vb;
 
+	/*dynamic objects pointed to by hooks: */
+	Node**  nodes=NULL;
+	Matpar* matpar=NULL;
+	Matice* matice=NULL;
+	Numpar* numpar=NULL;
+
 	ParameterInputs* inputs=NULL;
 
 	/*recover pointers: */
 	inputs=(ParameterInputs*)vinputs;
+
+	/*recover objects from hooks: */
+	nodes=(Node**)hnodes.deliverp();
+	matpar=(Matpar*)hmatpar.delivers();
+	matice=(Matice*)hmatice.delivers();
+	numpar=(Numpar*)hnumpar.delivers();
 
 	/*recover doflist: */
@@ -389,5 +475,5 @@
 		
 		for(j=0;j<NDOF2;j++){
-			pe_g_gaussian[NDOF2+j]=constant_part*pow((s[0]-z_g)/B,n)*slope[j]*Jdet*gauss_weight;
+			pe_g_gaussian[NDOF2+j]=constant_part*pow((this->properties.s[0]-z_g)/B,n)*slope[j]*Jdet*gauss_weight;
 		}
 		
@@ -399,8 +485,8 @@
 
 	//Deal with lower surface
-	if (onbed){
+	if (this->properties.onbed){
 
 		//compute ub
-		constant_part=-1.58*pow((double)10.0,-(double)10.0)*rho_ice*gravity*h[0];
+		constant_part=-1.58*pow((double)10.0,-(double)10.0)*rho_ice*gravity*this->properties.h[0];
 		ub=constant_part*slope[0];
 		vb=constant_part*slope[1];
@@ -419,57 +505,7 @@
 }
 /*}}}*/
-/*FUNCTION Beam DeepEcho{{{1*/
-void Beam::DeepEcho(void){
-
-	printf("Beam:\n");
-	printf("   id: %i\n",id);
-	printf("   mid: %i\n",mid);
-	printf("   mparid: %i\n",mparid);
-	printf("   node_ids=[%i,%i]\n",node_ids[0],node_ids[1]);
-	printf("   node_offsets=[%i,%i]\n",node_offsets[0],node_offsets[1]);
-	printf("   matice_offset=%i\n",matice_offset);
-	printf("   matpar_offset=%i\n",matpar_offset);
-	printf("   h=[%g,%g]\n",h[0],h[1]);
-	printf("   s=[%g,%g]\n",s[0],s[1]);
-	printf("   b=[%g,%g]\n",b[0],b[1]);
-	printf("   k=[%g,%g]\n",k[0],k[1]);
-	printf("   onbed=%i\n",onbed);
-	printf("   nodes: \n");
-	if(nodes[0])nodes[0]->Echo();
-	if(nodes[1])nodes[1]->Echo();
-	if(matice)matice->Echo();
-	if(matpar)matpar->Echo();
-
-	return;
-}
-/*}}}*/
 /*FUNCTION Beam Du{{{1*/
 void  Beam::Du(_p_Vec*,void*,int,int){
 	ISSMERROR(" not supported yet!");
-}
-/*}}}*/
-/*FUNCTION Beam Echo {{{1*/
-void Beam::Echo(void){
-
-	printf("Beam:\n");
-	printf("   id: %i\n",id);
-	printf("   mid: %i\n",mid);
-	printf("   mparid: %i\n",mparid);
-	printf("   node_ids=[%i,%i]\n",node_ids[0],node_ids[1]);
-	printf("   node_offsets=[%i,%i]\n",node_offsets[0],node_offsets[1]);
-	printf("   matice_offset=%i\n",matice_offset);
-	printf("   matpar_offset=%i\n",matpar_offset);
-	printf("   h=[%g,%g]\n",h[0],h[1]);
-	printf("   s=[%g,%g]\n",s[0],s[1]);
-	printf("   b=[%g,%g]\n",b[0],b[1]);
-	printf("   k=[%g,%g]\n",k[0],k[1]);
-	printf("   onbed=%i\n",onbed);
-	printf("   nodes: \n");
-	if(nodes[0])nodes[0]->Echo();
-	if(nodes[1])nodes[1]->Echo();
-	if(matice)matice->Echo();
-	if(matpar)matpar->Echo();
-
-	return;
 }
 /*}}}*/
@@ -492,4 +528,10 @@
 	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++){
@@ -508,4 +550,10 @@
 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++){
@@ -535,4 +583,11 @@
 /*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;
 }
@@ -558,6 +613,15 @@
 void  Beam::GetNodes(void** vpnodes){
 	int i;
-	Node** pnodes=(Node**)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();
+	
 	for(i=0;i<3;i++){
 		pnodes[i]=nodes[i];
@@ -612,6 +676,15 @@
 /*FUNCTION Beam MaticeConfiguration{{{1*/
 void  Beam::MaticeConfiguration(Matice* beam_matice,int beam_matice_offset){
-	matice=beam_matice;
-	matice_offset=beam_matice_offset;
+
+	/*dynamic objects pointed to by hooks: */
+	Matice* matice=NULL;
+
+	/*recover objects from hooks: */
+	matice=(Matice*)hmatice.delivers();
+	
+	ISSMERROR("not supported yet!");
+
+	/*matice=beam_matice;
+	matice_offset=beam_matice_offset;*/
 }
 /*}}}*/
@@ -619,6 +692,14 @@
 void  Beam::MatparConfiguration(Matpar* beam_matpar,int beam_matpar_offset){
 
-	matpar=beam_matpar;
-	matpar_offset=beam_matpar_offset;
+	/*dynamic objects pointed to by hooks: */
+	Matpar* matpar=NULL;
+
+	/*recover objects from hooks: */
+	matpar=(Matpar*)hmatpar.delivers();
+
+	ISSMERROR("not supported yet!");
+
+	/*matpar=beam_matpar;
+	matpar_offset=beam_matpar_offset;*/
 
 }
@@ -638,10 +719,18 @@
 void  Beam::NodeConfiguration(int* beam_node_ids,Node* beam_nodes[2],int* beam_node_offsets){
 
-	int i;
+	/*dynamic objects pointed to by hooks: */
+	Node**  nodes=NULL;
+
+	/*recover objects from hooks: */
+	nodes=(Node**)hnodes.deliverp();
+
+	ISSMERROR("not supported yet!");
+
+	/*int i;
 	for(i=0;i<2;i++){
 		node_ids[i]=beam_node_ids[i];
 		nodes[i]=beam_nodes[i];
 		node_offsets[i]=beam_node_offsets[i];
-	}
+	}*/
 
 }
@@ -652,41 +741,2 @@
 }
 /*}}}*/
-/*FUNCTION Beam UpdateFromInputs{{{1*/
-void  Beam::UpdateFromInputs(void* vinputs){
-
-	int     dofs[1]={0};
-	double  temperature_list[2];
-	double  temperature_average;
-	double  B_list[2];
-	double  B_average;
-
-	ParameterInputs* inputs=NULL;
-
-	/*recover pointers: */
-	inputs=(ParameterInputs*)vinputs;
-
-	/*Update internal data if inputs holds new values: */
-	inputs->Recover("thickness",&h[0],1,dofs,2,(void**)nodes);
-	inputs->Recover("surface",&s[0],1,dofs,2,(void**)nodes);
-	inputs->Recover("bed",&b[0],1,dofs,2,(void**)nodes);
-	inputs->Recover("drag",&k[0],1,dofs,2,(void**)nodes);
-	
-	//Update material if necessary
-	if(inputs->Recover("temperature_average",&temperature_list[0],1,dofs,2,(void**)nodes)){
-		temperature_average=(temperature_list[0]+temperature_list[1])/2.0;
-		B_average=Paterson(temperature_average);
-		matice->SetB(B_average);
-	}
-	if(inputs->Recover("temperature",&temperature_list[0],1,dofs,2,(void**)nodes)){
-		temperature_average=(temperature_list[0]+temperature_list[1])/2.0;
-		B_average=Paterson(temperature_average);
-		matice->SetB(B_average);
-	}
-	
-	if(inputs->Recover("B",&B_list[0],1,dofs,2,(void**)nodes)){
-		B_average=(B_list[0]+B_list[1])/2.0;
-		matice->SetB(B_average);
-	}
-
-}
-/*}}}*/
Index: /issm/trunk/src/c/objects/Beam.h
===================================================================
--- /issm/trunk/src/c/objects/Beam.h	(revision 3401)
+++ /issm/trunk/src/c/objects/Beam.h	(revision 3402)
@@ -12,4 +12,9 @@
 #include "./Matpar.h"
 #include "./ParameterInputs.h"
+#include "./ElementProperties.h"
+#include "./Hook.h"
+
+class Object;
+class DataSet;
 
 class Beam: public Element{
@@ -20,33 +25,16 @@
 		int id;
 
-		/*nodes: */
-		int   node_ids[2]; //node ids
-		Node* nodes[2]; //node pointers
-		int   node_offsets[2]; //node offsets in nodes dataset
+		Hook hnodes;  //hook to 2 nodes
+		Hook hmatice; //hook to 1 matice
+		Hook hmatpar; //hook to 1 matpar
+		Hook hnumpar; //hook to 1 numpar
 
-		/*materials: */
-		int   mid;
-		Matice* matice; 
-		int   matice_offset;
-		
-		int mparid;
-		Matpar* matpar; 
-		int   matpar_offset;
-
-		int numparid;
-		Numpar* numpar; 
-		int   numpar_offset;
-					
-		double h[2];
-		double s[2];
-		double b[2];
-		double k[2];
-
-		bool onbed;
-
+		ElementProperties properties;
+	
 	public:
 
 		Beam();
-		Beam(int beam_id, int beam_mid, int beam_mparid, int beam_numparid,int beam_g[2], double beam_h[2], double beam_s[2],double beam_b[2],double beam_k[2],bool beam_onbed);
+		Beam(int beam_id,int* beam_node_ids, int beam_matice_id, int beam_matpar_id, int beam_numpar_id, ElementProperties* beam_properties);
+		Beam(int beam_id,Hook* beam_hnodes, Hook* beam_hmatice, Hook* beam_hmatpar, Hook* beam_hnumpar, ElementProperties* beam_properties);
 		~Beam();
 
Index: /issm/trunk/src/c/objects/Sing.cpp
===================================================================
--- /issm/trunk/src/c/objects/Sing.cpp	(revision 3401)
+++ /issm/trunk/src/c/objects/Sing.cpp	(revision 3402)
@@ -24,4 +24,34 @@
 }
 /*}}}*/
+/*FUNCTION Sing constructor {{{1*/
+Sing::Sing(int sing_id,int* sing_node_ids, int sing_matice_id, int sing_matpar_id, int sing_numpar_id, ElementProperties* singproperties): 
+	hnodes(sing_node_ids,1),
+	hmatice(&sing_matice_id,1),
+	hmatpar(&sing_matpar_id,1),
+	hnumpar(&sing_numpar_id,1),
+	properties(singproperties)
+{
+
+	/*all the initialization has been done by the initializer, just fill in the id: */
+	this->id=sing_id;
+
+	return;
+}
+/*}}}*/
+/*FUNCTION Sing other constructor {{{1*/
+Sing::Sing(int sing_id,Hook* sing_hnodes, Hook* sing_hmatice, Hook* sing_hmatpar, Hook* sing_hnumpar, ElementProperties* sing_properties):
+	hnodes(sing_hnodes),
+	hmatice(sing_hmatice),
+	hmatpar(sing_hmatpar),
+	hnumpar(sing_hnumpar),
+	properties(sing_properties)
+{
+
+	/*all the initialization has been done by the initializer, just fill in the id: */
+	this->id=sing_id;
+
+	return;
+}
+/*}}}*/
 /*FUNCTION Sing::destructor {{{1*/
 Sing::~Sing(){
@@ -29,35 +59,94 @@
 }
 /*}}}*/
-/*FUNCTION Sing::creation {{{1*/
-Sing::Sing(int sing_id, int sing_mid, int sing_mparid, int sing_numparid,int sing_g, double sing_h, double sing_k){
-
-	id=sing_id;
-	mid=sing_mid;
-	mparid=sing_mparid;
-	numparid=sing_numparid;
-
-	node_id=sing_g;
-	node_offset=UNDEF;
-	node=NULL;
-
-	numpar=NULL;
-	numpar_offset=UNDEF;
-	
-	h=sing_h;
-	k=sing_k;
-	
-	matice=NULL;
-	matice_offset=UNDEF;
-	matpar=NULL;
-	matpar_offset=UNDEF;
-
-	numpar=NULL;
-	numpar_offset=UNDEF;
-
-	return;
-}
-/*}}}*/
-
-/*Object marshall*/
+
+/*Object management*/
+/*FUNCTION Sing::Configure {{{1*/
+void  Sing::Configure(void* ploadsin, void* pnodesin,void* pmaterialsin,void* pparametersin){
+
+	int i;
+	
+	DataSet* loadsin=NULL;
+	DataSet* nodesin=NULL;
+	DataSet* materialsin=NULL;
+	DataSet* parametersin=NULL;
+
+	/*Recover pointers :*/
+	loadsin=(DataSet*)ploadsin;
+	nodesin=(DataSet*)pnodesin;
+	materialsin=(DataSet*)pmaterialsin;
+	parametersin=(DataSet*)pparametersin;
+
+	/*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);
+	hnumpar.configure(parametersin);
+
+}
+/*}}}*/
+/*FUNCTION Sing::copy {{{1*/
+Object* Sing::copy() {
+	
+	return new Sing(*this); 
+
+}
+/*}}}*/
+/*FUNCTION Sing::DeepEcho {{{1*/
+void Sing::DeepEcho(void){
+
+	printf("Sing:\n");
+	printf("   id: %i\n",id);
+	hnodes.DeepEcho();
+	hmatice.DeepEcho();
+	hmatpar.DeepEcho();
+	hnumpar.DeepEcho();
+	properties.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);
+	hnumpar.Demarshall(&marshalled_dataset);
+
+	/*demarshall properties: */
+	properties.Demarshall(&marshalled_dataset);
+
+	/*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();
+	hnumpar.Echo();
+	properties.Echo();
+
+	return;
+}
+/*}}}*/
 /*FUNCTION Sing::Marshall {{{1*/
 void  Sing::Marshall(char** pmarshalled_dataset){
@@ -77,19 +166,14 @@
 	/*marshall Sing data: */
 	memcpy(marshalled_dataset,&id,sizeof(id));marshalled_dataset+=sizeof(id);
-	memcpy(marshalled_dataset,&mid,sizeof(mid));marshalled_dataset+=sizeof(mid);
-	memcpy(marshalled_dataset,&mparid,sizeof(mparid));marshalled_dataset+=sizeof(mparid);
-	memcpy(marshalled_dataset,&node_id,sizeof(node_id));marshalled_dataset+=sizeof(node_id);
-	memcpy(marshalled_dataset,&node,sizeof(node));marshalled_dataset+=sizeof(node);
-	memcpy(marshalled_dataset,&node_offset,sizeof(node_offset));marshalled_dataset+=sizeof(node_offset);
-	memcpy(marshalled_dataset,&matice,sizeof(matice));marshalled_dataset+=sizeof(matice);
-	memcpy(marshalled_dataset,&matice_offset,sizeof(matice_offset));marshalled_dataset+=sizeof(matice_offset);
-	memcpy(marshalled_dataset,&matpar,sizeof(matpar));marshalled_dataset+=sizeof(matpar);
-	memcpy(marshalled_dataset,&matpar_offset,sizeof(matpar_offset));marshalled_dataset+=sizeof(matpar_offset);
-	memcpy(marshalled_dataset,&numparid,sizeof(numparid));marshalled_dataset+=sizeof(numparid);
-	memcpy(marshalled_dataset,&numpar,sizeof(numpar));marshalled_dataset+=sizeof(numpar);
-	memcpy(marshalled_dataset,&numpar_offset,sizeof(numpar_offset));marshalled_dataset+=sizeof(numpar_offset);
-	memcpy(marshalled_dataset,&h,sizeof(h));marshalled_dataset+=sizeof(h);
-	memcpy(marshalled_dataset,&k,sizeof(k));marshalled_dataset+=sizeof(k);
-	
+	
+	/*Marshall hooks: */
+	hnodes.Marshall(&marshalled_dataset);
+	hmatice.Marshall(&marshalled_dataset);
+	hmatpar.Marshall(&marshalled_dataset);
+	hnumpar.Marshall(&marshalled_dataset);
+
+	/*Marshall properties: */
+	properties.Marshall(&marshalled_dataset);
+
 	*pmarshalled_dataset=marshalled_dataset;
 	return;
@@ -98,59 +182,68 @@
 /*FUNCTION Sing::MashallSize {{{1*/
 int   Sing::MarshallSize(){
+
 	return sizeof(id)
-		+sizeof(mid)
-		+sizeof(mparid)
-		+sizeof(node_id)
-		+sizeof(node)
-		+sizeof(node_offset)
-		+sizeof(matice)
-		+sizeof(matice_offset)
-		+sizeof(matpar)
-		+sizeof(matpar_offset)
-		+sizeof(numparid)
-		+sizeof(numpar)
-		+sizeof(numpar_offset)
-		+sizeof(h)
-		+sizeof(k)
+		+hnodes.MarshallSize()
+		+hmatice.MarshallSize()
+		+hmatpar.MarshallSize()
+		+hnumpar.MarshallSize()
+		+properties.MarshallSize()
 		+sizeof(int); //sizeof(int) for enum type
 }
 /*}}}*/
-/*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);
-	memcpy(&mid,marshalled_dataset,sizeof(mid));marshalled_dataset+=sizeof(mid);
-	memcpy(&mparid,marshalled_dataset,sizeof(mparid));marshalled_dataset+=sizeof(mparid);
-	memcpy(&node_id,marshalled_dataset,sizeof(node_id));marshalled_dataset+=sizeof(node_id);
-	memcpy(&node,marshalled_dataset,sizeof(node));marshalled_dataset+=sizeof(node);
-	memcpy(&node_offset,marshalled_dataset,sizeof(node_offset));marshalled_dataset+=sizeof(node_offset);
-	memcpy(&matice,marshalled_dataset,sizeof(matice));marshalled_dataset+=sizeof(matice);
-	memcpy(&matice_offset,marshalled_dataset,sizeof(matice_offset));marshalled_dataset+=sizeof(matice_offset);
-	memcpy(&matpar,marshalled_dataset,sizeof(matpar));marshalled_dataset+=sizeof(matpar);
-	memcpy(&matpar_offset,marshalled_dataset,sizeof(matpar_offset));marshalled_dataset+=sizeof(matpar_offset);
-	memcpy(&numparid,marshalled_dataset,sizeof(numparid));marshalled_dataset+=sizeof(numparid);
-	memcpy(&numpar,marshalled_dataset,sizeof(numpar));marshalled_dataset+=sizeof(numpar);
-	memcpy(&numpar_offset,marshalled_dataset,sizeof(numpar_offset));marshalled_dataset+=sizeof(numpar_offset);
-	memcpy(&h,marshalled_dataset,sizeof(h));marshalled_dataset+=sizeof(h);
-	memcpy(&k,marshalled_dataset,sizeof(k));marshalled_dataset+=sizeof(k);
-
-	/*nodes and materials are not pointing to correct objects anymore:*/
-	node=NULL;
-	matice=NULL;
-	matpar=NULL;
-	numpar=NULL;
-
-	/*return: */
-	*pmarshalled_dataset=marshalled_dataset;
-	return;
+/*FUNCTION Sing::UpdateFromInputs {{{1*/
+void  Sing::UpdateFromInputs(void* vinputs){
+
+	int     dofs[1]={0};
+	double  temperature;
+	double  B;
+	double  B_average;
+
+	/*dynamic objects pointed to by hooks: */
+	Node**  nodes=NULL;
+	Matpar* matpar=NULL;
+	Matice* matice=NULL;
+	Numpar* numpar=NULL;
+
+	ParameterInputs* inputs=NULL;
+
+	/*recover pointers: */
+	inputs=(ParameterInputs*)vinputs;
+
+	/*Update internal data if inputs holds new values: */
+	//if (id==1) printf("WARNING if QMU: no hydrostatic equilibrium is applied here (conflict with prognostic, which does not have matpar)\n");
+	//For now
+	if(this->properties.h) inputs->Recover("thickness",&this->properties.h[0],1,dofs,1,(void**)nodes);
+	//Later
+	/*
+		if(inputs->Recover("thickness",&new_h[0],1,dofs,1,(void**)nodes)){
+	//density, needed later:
+	double di=(this->matpar->GetRhoIce()/this->matpar->GetRhoWater());
+	//Go through grids:
+	for (i=0;i<1;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];
+	}
+	}
+	*/
+	if (this->properties.k) inputs->Recover("drag",&this->properties.k[0],1,dofs,1,(void**)nodes);
+	
+	//Update material if necessary
+	if(inputs->Recover("temperature_average",&temperature,1,dofs,1,(void**)nodes)){
+		B_average=Paterson(temperature);
+		matice->SetB(B_average);
+	}
+	else if(inputs->Recover("temperature",&temperature,1,dofs,1,(void**)nodes)){
+		B=Paterson(temperature);
+		matice->SetB(B);
+	}
+	
+	if(inputs->Recover("B",&B,1,dofs,1,(void**)nodes)){
+		matice->SetB(B);
+	}
+
 }
 /*}}}*/
@@ -166,4 +259,10 @@
 	double rho_ice,g;
 
+	/*dynamic objects pointed to by hooks: */
+	Node**  nodes=NULL;
+	Matpar* matpar=NULL;
+	Matice* matice=NULL;
+	Numpar* numpar=NULL;
+
 	/*Get dof list on which we will plug the pressure values: */
 	GetDofList1(&doflist[0]);
@@ -172,41 +271,8 @@
 	rho_ice=matpar->GetRhoIce();
 	g=matpar->GetG();
-	pressure[0]=rho_ice*g*h;
+	pressure[0]=rho_ice*g*this->properties.h[0];
 	
 	/*plug local pressure values into global pressure vector: */
 	VecSetValues(p_g,numgrids,doflist,(const double*)pressure,INSERT_VALUES);
-
-}
-/*}}}*/
-/*FUNCTION Sing::Configure {{{1*/
-void  Sing::Configure(void* ploadsin, void* pnodesin,void* pmaterialsin,void* pparametersin){
-
-	int i;
-	
-	DataSet* nodesin=NULL;
-	DataSet* materialsin=NULL;
-	DataSet* parametersin=NULL;
-
-	/*Recover pointers :*/
-	nodesin=(DataSet*)pnodesin;
-	materialsin=(DataSet*)pmaterialsin;
-	parametersin=(DataSet*)pparametersin;
-
-	/*Link this element with its nodes, ie find pointers to the nodes in the nodes dataset.: */
-	ResolvePointers((Object**)&node,&node_id,&node_offset,1,nodesin);
-	
-	/*Same for materials: */
-	ResolvePointers((Object**)&matice,&mid,&matice_offset,1,materialsin);
-	ResolvePointers((Object**)&matpar,&mparid,&matpar_offset,1,materialsin);
-
-	/*Same for numpar: */
-	ResolvePointers((Object**)&numpar,&numparid,&numpar_offset,1,parametersin);
-
-}
-/*}}}*/
-/*FUNCTION Sing::copy {{{1*/
-Object* Sing::copy() {
-	
-	return new Sing(*this); 
 
 }
@@ -278,5 +344,5 @@
 	const int NDOF2=2;
 	const int numdofs=NDOF2*numgrids;
-	int    doflist[numdofs];
+	int       doflist[numdofs];
 	int       dofs[1]={0};
 	int       found=0;
@@ -288,4 +354,11 @@
 	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;
+	Numpar* numpar=NULL;
 
 	ParameterInputs* inputs=NULL;
@@ -309,38 +382,18 @@
 	n=matice->GetN();
 	B=matice->GetB();
-
-	ub=-1.58*pow((double)10.0,(double)-10.0)*rho_ice*gravity*h*slope[0];
-	vb=-1.58*pow((double)10.0,(double)-10.0)*rho_ice*gravity*h*slope[1];
+	thickness=this->properties.h[0];
+
+	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(h,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(h,n)/(pow(B,n)*(n+1))*slope[1];
+	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::DeepEcho {{{1*/
-void Sing::DeepEcho(void){
-
-	printf("Sing:\n");
-	printf("   id: %i\n",id);
-	printf("   mid: %i\n",mid);
-	printf("   mparid: %i\n",mparid);
-	printf("   node_id=[%i]\n",node_id);
-	printf("   node_offset=[%i]\n",node_offset);
-	printf("   matice_offset=%i\n",matice_offset);
-	printf("   matpar_offset=%i\n",matpar_offset);
-	printf("   h=[%g]\n",h);
-	printf("   k=[%g]\n",h);
-	printf("   node: \n");
-	if(node)node->Echo();
-	if(matice)matice->Echo();
-	if(matpar)matpar->Echo();
-
-	return;
 }
 /*}}}*/
@@ -348,26 +401,4 @@
 void  Sing::Du(_p_Vec*,void*,int,int){
 	ISSMERROR(" not supported yet!");
-}
-/*}}}*/
-/*FUNCTION Sing::Echo{{{1*/
-
-void Sing::Echo(void){
-
-	printf("Sing:\n");
-	printf("   id: %i\n",id);
-	printf("   mid: %i\n",mid);
-	printf("   mparid: %i\n",mparid);
-	printf("   node_id=[%i]\n",node_id);
-	printf("   node_offset=[%i]\n",node_offset);
-	printf("   matice_offset=%i\n",matice_offset);
-	printf("   matpar_offset=%i\n",matpar_offset);
-	printf("   h=[%g]\n",h);
-	printf("   k=[%g]\n",h);
-	printf("   node: \n");
-	if(node)node->Echo();
-	if(matice)matice->Echo();
-	if(matpar)matpar->Echo();
-
-	return;
 }
 /*}}}*/
@@ -391,5 +422,11 @@
 	int numberofdofspernode;
 	
-	node->GetDofList(&doflist_per_node[0],&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];
@@ -404,6 +441,12 @@
 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]=node->GetDofList1();
+	doflist[0]=nodes[0]->GetDofList1();
 
 }
@@ -414,4 +457,11 @@
 /*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;
 }
@@ -425,7 +475,16 @@
 void  Sing::GetNodes(void** vpnodes){
 	
-	Node** pnodes=(Node**)vpnodes;
-
-	pnodes[0]=node;
+	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];
 }
 /*}}}*/
@@ -467,6 +526,15 @@
 /*FUNCTION Sing::MaticeConfiguration {{{1*/
 void  Sing::MaticeConfiguration(Matice* sing_matice,int sing_matice_offset){
-	matice=sing_matice;
-	matice_offset=sing_matice_offset;
+
+	/*dynamic objects pointed to by hooks: */
+	Matice* matice=NULL;
+
+	/*recover objects from hooks: */
+	matice=(Matice*)hmatice.delivers();
+	
+	ISSMERROR("not supported yet!");
+
+	/*matice=sing_matice;
+	matice_offset=sing_matice_offset;*/
 }
 /*}}}*/
@@ -474,6 +542,14 @@
 void  Sing::MatparConfiguration(Matpar* sing_matpar,int sing_matpar_offset){
 
-	matpar=sing_matpar;
-	matpar_offset=sing_matpar_offset;
+	/*dynamic objects pointed to by hooks: */
+	Matpar* matpar=NULL;
+
+	/*recover objects from hooks: */
+	matpar=(Matpar*)hmatpar.delivers();
+
+	ISSMERROR("not supported yet!");
+
+	/*matpar=sing_matpar;
+	matpar_offset=sing_matpar_offset;*/
 
 }
@@ -495,34 +571,2 @@
 }
 /*}}}*/
-/*FUNCTION Sing::UpdateFromInputs {{{1*/
-void  Sing::UpdateFromInputs(void* vinputs){
-
-	int     dofs[1]={0};
-	double  temperature;
-	double  B;
-
-	ParameterInputs* inputs=NULL;
-
-	/*recover pointers: */
-	inputs=(ParameterInputs*)vinputs;
-
-	/*Update internal data if inputs holds new values: */
-	inputs->Recover("thickness",&h,1,dofs,1,(void**)&node);
-	inputs->Recover("drag",&k,1,dofs,1,(void**)&node);
-	
-	//Update material if necessary
-	if(inputs->Recover("temperature_average",&temperature,1,dofs,1,(void**)&node)){
-		B=Paterson(temperature);
-		matice->SetB(B);
-	}
-	if(inputs->Recover("temperature",&temperature,1,dofs,1,(void**)&node)){
-		B=Paterson(temperature);
-		matice->SetB(B);
-	}
-	
-	if(inputs->Recover("B",&B,1,dofs,1,(void**)&node)){
-		matice->SetB(B);
-	}
-
-}
-/*}}}*/
Index: /issm/trunk/src/c/objects/Sing.h
===================================================================
--- /issm/trunk/src/c/objects/Sing.h	(revision 3401)
+++ /issm/trunk/src/c/objects/Sing.h	(revision 3402)
@@ -11,4 +11,6 @@
 #include "./Matpar.h"
 #include "./ParameterInputs.h"
+#include "./ElementProperties.h"
+#include "./Hook.h"
 
 class Sing: public Element{
@@ -16,32 +18,19 @@
 	private: 
 
-		/*id:*/
+		/*ids:*/
 		int id;
 
-		/*node: */
-		int   node_id; //node id
-		Node* node; //node pointer
-		int   node_offset; //node offset in nodes dataset
+		Hook hnodes;  //hook to 2 nodes
+		Hook hmatice; //hook to 1 matice
+		Hook hmatpar; //hook to 1 matpar
+		Hook hnumpar; //hook to 1 numpar
 
-		/*material: */
-		int   mid;
-		Matice* matice; 
-		int   matice_offset;
-		
-		int mparid;
-		Matpar* matpar; 
-		int   matpar_offset;
-
-		int numparid;
-		Numpar* numpar; 
-		int   numpar_offset;
-	
-		double h;
-		double k;
+		ElementProperties properties;
 
 	public:
 
 		Sing();
-		Sing(int sing_id, int sing_mid, int sing_mparid, int sing_numparid,int sing_g, double sing_h, double sing_k);
+		Sing(int sing_id,int* sing_node_ids, int sing_matice_id, int sing_matpar_id, int sing_numpar_id, ElementProperties* sing_properties);
+		Sing(int sing_id,Hook* sing_hnodes, Hook* sing_hmatice, Hook* sing_hmatpar, Hook* sing_hnumpar, ElementProperties* sing_properties);
 		~Sing();
 
Index: /issm/trunk/src/c/objects/Tria.h
===================================================================
--- /issm/trunk/src/c/objects/Tria.h	(revision 3401)
+++ /issm/trunk/src/c/objects/Tria.h	(revision 3402)
@@ -19,7 +19,4 @@
 
 class Object;
-class Hook;
-class ElementProperties;
-class DataSet;
 
 class Tria: public Element{
