Index: /issm/trunk/src/c/DataSet/Constraints.cpp
===================================================================
--- /issm/trunk/src/c/DataSet/Constraints.cpp	(revision 4218)
+++ /issm/trunk/src/c/DataSet/Constraints.cpp	(revision 4219)
@@ -42,3 +42,25 @@
 /*}}}*/
 
-/*Object management*/
+/*Numerics: */
+/*FUNCTION Constraints::NumberOfLocalRgbs{{{1*/
+int   Constraints::NumberOfLocalRgbs(int analysis_type){
+
+	int i;
+	int  count=0;
+
+	for(i=0;i<this->Size();i++){
+
+		Object* object=(Object*)this->GetObjectByOffset(i);
+
+		/*Check this is a single point constraint (spc): */
+		if (object->Enum()==RgbEnum){
+
+			Rgb* rgb=(Rgb*)object;
+			if(rgb->InAnalysis(analysis_type))count++;
+		}
+	}
+
+	return count;
+}
+/*}}}*/
+
Index: /issm/trunk/src/c/DataSet/DataSet.cpp
===================================================================
--- /issm/trunk/src/c/DataSet/DataSet.cpp	(revision 4218)
+++ /issm/trunk/src/c/DataSet/DataSet.cpp	(revision 4219)
@@ -590,348 +590,4 @@
 	}
 
-}
-/*}}}*/
-/*FUNCTION DataSet::CreatePartitioningVector{{{1*/
-void  DataSet::CreatePartitioningVector(Vec* ppartition,int numberofobjects){
-
-	/*output: */
-	Vec partition=NULL;
-	vector<Object*>::iterator object;
-	DofObject* dofobject=NULL;
-
-	/*Create partition vector: */
-	partition=NewVec(numberofobjects);
-
-	/*Go through all objects, and ask each object to plug its doflist in 
-	 * partition: */
-
-	for ( object=objects.begin() ; object < objects.end(); object++ ){
-
-		dofobject=dynamic_cast<DofObject*>(*object);
-		dofobject->CreatePartition(partition);
-	}
-
-	/*Assemble the petsc vector: */
-	VecAssemblyBegin(partition);
-	VecAssemblyEnd(partition);
-
-	/*Assign output pointers: */
-	*ppartition=partition;
-}
-/*}}}*/
-/*FUNCTION DataSet::DistributeDofs{{{1*/
-void  DataSet::DistributeDofs(int numberofobjects,int numberofdofsperobject){
-
-	extern int num_procs;
-	extern int my_rank;
-
-	int  i;
-	
-	int  dofcount=0;
-	int* alldofcount=NULL;
-	int* truedofs=NULL;
-	int* alltruedofs=NULL;
-	vector<Object*>::iterator object;
-	DofObject* dofobject=NULL;
-
-	/*Go through objects, and distribute dofs locally, from 0 to numberofdofsperobject: */
-	for ( object=objects.begin() ; object < objects.end(); object++ ){
-
-		dofobject=dynamic_cast<DofObject*>(*object);
-		dofobject->DistributeDofs(&dofcount);
-
-	}
-
-	/*Ok, now every object has distributed dofs, but locally, and with a dof count starting from 
-	 *0. This means the dofs between all the cpus are not synchronized! We need to synchronize all 
-	 *dof on all cpus, and use those to update the dofs of every object: */
-
-	alldofcount=(int*)xmalloc(num_procs*sizeof(int));
-	MPI_Gather(&dofcount,1,MPI_INT,alldofcount,1,MPI_INT,0,MPI_COMM_WORLD);
-	MPI_Bcast(alldofcount,num_procs,MPI_INT,0,MPI_COMM_WORLD);
-
-	/*Ok, now every cpu should start its own dof count at the end of the dofcount 
-	 * from cpu-1. : */
-	dofcount=0;
-	if(my_rank==0){
-		dofcount=0;
-	}
-	else{
-		for(i=0;i<my_rank;i++){
-			dofcount+=alldofcount[i];
-		}
-	}
-
-
-	/*Ok, now every cpu knows where his dofs should start. Update the dof count: */
-	for ( object=objects.begin() ; object < objects.end(); object++ ){
-
-		dofobject=dynamic_cast<DofObject*>(*object);
-		dofobject->OffsetDofs(dofcount);
-	
-	}
-
-	/*Finally, remember that cpus may have skipped some objects, because they were clones. For every 
-	 * object that is not a clone, tell them to show their dofs, so that later on, they can get picked 
-	 * up by their clones: */
-	truedofs=(int*)xcalloc(numberofobjects*numberofdofsperobject,sizeof(int));
-	alltruedofs=(int*)xcalloc(numberofobjects*numberofdofsperobject,sizeof(int));
-
-	for ( object=objects.begin() ; object < objects.end(); object++ ){
-			
-		/*Ok, let this object show its true dofs, if is is a true dof: */
-		dofobject=dynamic_cast<DofObject*>(*object);
-		dofobject->ShowTrueDofs(truedofs);
-	}
-	
-	MPI_Allreduce ( (void*)truedofs,(void*)alltruedofs,numberofobjects*numberofdofsperobject,MPI_INT,MPI_MAX,MPI_COMM_WORLD);
-
-	/*Ok, now every cpu knows the true dofs of everyone else that is not a clone. Let the clones recover those true dofs: */
-	for ( object=objects.begin() ; object < objects.end(); object++ ){
-
-		dofobject=dynamic_cast<DofObject*>(*object);
-		dofobject->UpdateCloneDofs(alltruedofs);
-
-	}
-
-	/* Free ressources: */
-	xfree((void**)&alldofcount);
-	xfree((void**)&truedofs);
-	xfree((void**)&alltruedofs);
-
-}
-/*}}}*/
-/*FUNCTION DataSet::FlagClones{{{1*/
-void  DataSet::FlagClones(int numberofobjects){
-
-	int i;
-	extern int num_procs;
-
-	int* ranks=NULL;
-	int* minranks=NULL;
-
-	vector<Object*>::iterator object;
-	DofObject* dofobject=NULL;
-
-	/*Allocate ranks: */
-	ranks=(int*)xmalloc(numberofobjects*sizeof(int));
-	minranks=(int*)xmalloc(numberofobjects*sizeof(int));
-
-	for(i=0;i<numberofobjects;i++)ranks[i]=num_procs; //no cpu can have rank num_procs. This is the maximum limit.
-
-	/*Now go through all our objects and ask them to report to who they belong (which rank): */
-	Ranks(ranks);
-
-	/*We need to take the minimum rank for each vertex, and every cpu needs to get that result. That way, 
-	 * when we start building the dof list for all vertexs, a cpu can check whether its vertex already has been 
-	 * dealt with by another cpu. We take the minimum because we are going to manage dof assignment in increasing 
-	 * order of cpu rank. This is also why we initialized this array to num_procs.*/
-	MPI_Allreduce ( (void*)ranks,(void*)minranks,numberofobjects,MPI_INT,MPI_MIN,MPI_COMM_WORLD);
-
-	/*Now go through all objects, and use minranks to flag which objects are cloned: */
-	for ( object=objects.begin() ; object < objects.end(); object++ ){
-
-		/*For this object, decide whether it is a clone: */
-		dofobject=dynamic_cast<DofObject*>(*object);
-		dofobject->SetClone(minranks);
-	}
-
-	/*Free ressources: */
-	xfree((void**)&ranks); 
-	xfree((void**)&minranks);
-
-}
-/*}}}*/
-/*FUNCTION DataSet::FlagNodeSets{{{1*/
-void DataSet::FlagNodeSets(Vec pv_g, Vec pv_m, Vec pv_n, Vec pv_f, Vec pv_s,int analysis_type){
-
-	vector<Object*>::iterator object;
-	Node* node=NULL;
-
-	for ( object=objects.begin() ; object < objects.end(); object++ ){
-
-		/*Check this is a single point constraint (spc): */
-		if((*object)->Enum()==NodeEnum){
-
-			node=(Node*)(*object);
-
-			if (node->InAnalysis(analysis_type)){
-
-				/*Plug set values intp our 4 set vectors: */
-				node->CreateVecSets(pv_g,pv_m,pv_n,pv_f,pv_s);
-
-			}
-
-		}
-	}
-
-	/*Assemble: */
-	VecAssemblyBegin(pv_g);
-	VecAssemblyEnd(pv_g);
-
-	VecAssemblyBegin(pv_m);
-	VecAssemblyEnd(pv_m);
-
-	VecAssemblyBegin(pv_n);
-	VecAssemblyEnd(pv_n);
-
-	VecAssemblyBegin(pv_f);
-	VecAssemblyEnd(pv_f);
-
-	VecAssemblyBegin(pv_s);
-	VecAssemblyEnd(pv_s);
-
-}
-/*}}}*/
-/*FUNCTION DataSet::MeltingIsPresent{{{1*/
-int   DataSet::MeltingIsPresent(){
-
-	int found=0;
-	int mpi_found=0;
-
-	vector<Object*>::iterator object;
-
-	for ( object=objects.begin() ; object < objects.end(); object++ ){
-
-		if((*object)->Enum()==PengridEnum){
-			found=1;
-			break;
-		}
-	}	
-	
-	#ifdef _PARALLEL_
-	MPI_Reduce (&found,&mpi_found,1,MPI_INT,MPI_SUM,0,MPI_COMM_WORLD );
-	MPI_Bcast(&mpi_found,1,MPI_INT,0,MPI_COMM_WORLD);                
-	found=mpi_found;
-	#endif
-
-	return found;
-}
-/*}}}*/
-/*FUNCTION DataSet::MeltingConstraints{{{1*/
-void  DataSet::MeltingConstraints(int* pconverged, int* pnum_unstable_constraints){
-
-	/* generic object pointer: */
-	vector<Object*>::iterator object;
-	Pengrid* pengrid=NULL;
-
-	int unstable=0;
-	int num_unstable_constraints=0;
-	int converged=0;
-	int sum_num_unstable_constraints=0;
-
-	num_unstable_constraints=0;	
-
-	/*Enforce constraints: */
-	for ( object=objects.begin() ; object < objects.end(); object++ ){
-		
-		if((*object)->Enum()==PengridEnum){
-
-			pengrid=(Pengrid*)(*object);
-
-			pengrid->PenaltyConstrain(&unstable);
-
-			num_unstable_constraints+=unstable;
-		}
-	}
-
-	#ifdef _PARALLEL_
-	MPI_Reduce (&num_unstable_constraints,&sum_num_unstable_constraints,1,MPI_INT,MPI_SUM,0,MPI_COMM_WORLD );
-	MPI_Bcast(&sum_num_unstable_constraints,1,MPI_INT,0,MPI_COMM_WORLD);                
-	num_unstable_constraints=sum_num_unstable_constraints;
-	#endif
-
-	/*Have we converged? : */
-	if (num_unstable_constraints==0) converged=1;
-	else converged=0;
-
-	/*Assign output pointers: */
-	*pconverged=converged;
-	*pnum_unstable_constraints=num_unstable_constraints;
-}
-/*}}}*/
-/*FUNCTION DataSet::NumberOfDofs(int analysis_type){{{1*/
-int   DataSet::NumberOfDofs(int analysis_type){
-
-
-	vector<Object*>::iterator object;
-	Node* node=NULL;
-	int   numdofs=0;
-	int   allnumdofs;
-
-	/*Now go through all nodes, and get how many dofs they own, unless they are clone nodes: */
-	for ( object=objects.begin() ; object < objects.end(); object++ ){
-
-		/*Check this is a node: */
-		if((*object)->Enum()==NodeEnum){
-
-			node=(Node*)(*object);
-
-			/*Check that this node corresponds to our analysis currently being carried out: */
-
-			/*Ok, this object is a node, ask it to plug values into partition: */
-			if (!node->IsClone()){
-
-				numdofs+=node->GetNumberOfDofs();
-
-			}
-		}
-	}
-
-	/*Gather from all cpus: */
-	MPI_Allreduce ( (void*)&numdofs,(void*)&allnumdofs,1,MPI_INT,MPI_SUM,MPI_COMM_WORLD);
-
-	return allnumdofs;
-}
-/*}}}*/
-/*FUNCTION DataSet::NumberOfLocalRgbs{{{1*/
-int   DataSet::NumberOfLocalRgbs(int analysis_type){
-
-	vector<Object*>::iterator object;
-	Rgb* rgb=NULL;
-	int  count=0;
-
-	for ( object=objects.begin() ; object < objects.end(); object++ ){
-
-		/*Check this is a single point constraint (spc): */
-		if((*object)->Enum()==RgbEnum){ //we assume uniqueness of all Rgbs, no error checking here.
-
-			rgb=(Rgb*)(*object);
-			if(rgb->InAnalysis(analysis_type))count++;
-		}
-	}
-
-	return count;
-}
-/*}}}*/
-/*FUNCTION DataSet::NumberOfNodes{{{1*/
-int DataSet::NumberOfNodes(void){
-
-	vector<Object*>::iterator object;
-	int max_sid=0;
-	int sid;
-	int node_max_sid;
-
-	for ( object=objects.begin() ; object < objects.end(); object++ ){
-
-		if((*object)->Enum()==NodeEnum){ 
-
-			Node* node=(Node*)(*object);
-			sid=node->Sid();
-			if (sid>max_sid)max_sid=sid;
-		}
-	}
-
-	#ifdef _PARALLEL_
-	MPI_Reduce (&max_sid,&node_max_sid,1,MPI_INT,MPI_MAX,0,MPI_COMM_WORLD );
-	MPI_Bcast(&node_max_sid,1,MPI_INT,0,MPI_COMM_WORLD);
-	max_sid=node_max_sid;
-	#endif 
-
-	/*sid starts at 0*/
-	max_sid++;
-
-	/*return*/
-	return max_sid;
 }
 /*}}}*/
Index: /issm/trunk/src/c/DataSet/DataSet.h
===================================================================
--- /issm/trunk/src/c/DataSet/DataSet.h	(revision 4218)
+++ /issm/trunk/src/c/DataSet/DataSet.h	(revision 4219)
@@ -59,16 +59,9 @@
 		Object* FindParamObject(char* name);
 		void  Ranks(int* ranks);
-		void  DistributeDofs(int numberofnodes,int numdofspernode);
-		void  CreatePartitioningVector(Vec* ppartition,int numobjects);
-		void  FlagClones(int numberofnodes);
-		int   NumberOfDofs(int analysis_type);
-		int   NumberOfLocalRgbs(int analysis_type);
 		int   NumberOfVertices(void);
-		int   NumberOfNodes(void);
 		int   NumberOfLoads(void);
 		int   NumberOfConstraints(void);
 		void  SetupSpcs(DataSet* nodes,Vec yg,int analysis_type);
 		void  SetupMpcs(Mat Rmg,DataSet* nodes,int analysis_type);
-		void  FlagNodeSets(Vec pv_g, Vec pv_m, Vec pv_n, Vec pv_f, Vec pv_s,int analysis_type);
 		void  clear();
 		void  Configure(Elements* elements,Loads* loads, DataSet* nodes, Vertices* vertices, Materials* materials,Parameters* parameters);
@@ -79,6 +72,4 @@
 		void  Sort();
 		int   RiftIsPresent();
-		int   MeltingIsPresent();
-		void  MeltingConstraints(int* pconverged, int* pnum_unstable_constraints);
 		DataSet* Copy(void);
 		int   DeleteObject(Object* object);
@@ -150,4 +141,9 @@
 		/*}}}*/
 		/*numerics: {{{1*/
+		void  DistributeDofs(int numberofnodes,int numdofspernode);
+		void  FlagClones(int numberofnodes);
+		void  FlagNodeSets(Vec pv_g, Vec pv_m, Vec pv_n, Vec pv_f, Vec pv_s,int analysis_type);
+		int   NumberOfDofs(int analysis_type);
+		int   NumberOfNodes(void);
 		/*}}}*/
 
@@ -167,4 +163,7 @@
 		/*}}}*/
 		/*numerics: {{{1*/
+		void  CreatePartitioningVector(Vec* ppartition,int numobjects);
+		void  DistributeDofs(int numberofnodes,int numdofspernode);
+		void  FlagClones(int numberofnodes);
 		/*}}}*/
 
@@ -184,4 +183,6 @@
 		/*}}}*/
 		/*numerics: {{{1*/
+		int   MeltingIsPresent();
+		void  MeltingConstraints(int* pconverged, int* pnum_unstable_constraints);
 		/*}}}*/
 
@@ -216,4 +217,5 @@
 		/*}}}*/
 		/*numerics: {{{1*/
+		int   NumberOfLocalRgbs(int analysis_type);
 		/*}}}*/
 
Index: /issm/trunk/src/c/DataSet/Loads.cpp
===================================================================
--- /issm/trunk/src/c/DataSet/Loads.cpp	(revision 4218)
+++ /issm/trunk/src/c/DataSet/Loads.cpp	(revision 4219)
@@ -42,3 +42,65 @@
 /*}}}*/
 
-/*Object management*/
+/*Numerics:*/
+/*FUNCTION Loads::MeltingIsPresent{{{1*/
+int   Loads::MeltingIsPresent(){
+
+	int i;
+	int found=0;
+	int mpi_found=0;
+
+	for(i=0;i<this->Size();i++){
+		Object* object=(Object*)this->GetObjectByOffset(i);
+		if (object->Enum()==PengridEnum){
+			found=1;
+			break;
+		}
+	}
+	
+	#ifdef _PARALLEL_
+	MPI_Reduce (&found,&mpi_found,1,MPI_INT,MPI_SUM,0,MPI_COMM_WORLD );
+	MPI_Bcast(&mpi_found,1,MPI_INT,0,MPI_COMM_WORLD);                
+	found=mpi_found;
+	#endif
+
+	return found;
+}
+/*}}}*/
+/*FUNCTION Loads::MeltingConstraints{{{1*/
+void  Loads::MeltingConstraints(int* pconverged, int* pnum_unstable_constraints){
+
+	int i;
+
+	int unstable=0;
+	int num_unstable_constraints=0;
+	int converged=0;
+	int sum_num_unstable_constraints=0;
+
+	num_unstable_constraints=0;	
+
+	/*Enforce constraints: */
+	for(i=0;i<this->Size();i++){
+		Object* object=(Object*)this->GetObjectByOffset(i);
+		if(object->Enum()==PengridEnum){
+
+			Pengrid* pengrid=(Pengrid*)object;
+			pengrid->PenaltyConstrain(&unstable);
+			num_unstable_constraints+=unstable;
+		}
+	}
+
+	#ifdef _PARALLEL_
+	MPI_Reduce (&num_unstable_constraints,&sum_num_unstable_constraints,1,MPI_INT,MPI_SUM,0,MPI_COMM_WORLD );
+	MPI_Bcast(&sum_num_unstable_constraints,1,MPI_INT,0,MPI_COMM_WORLD);                
+	num_unstable_constraints=sum_num_unstable_constraints;
+	#endif
+
+	/*Have we converged? : */
+	if (num_unstable_constraints==0) converged=1;
+	else converged=0;
+
+	/*Assign output pointers: */
+	*pconverged=converged;
+	*pnum_unstable_constraints=num_unstable_constraints;
+}
+/*}}}*/
Index: /issm/trunk/src/c/DataSet/Nodes.cpp
===================================================================
--- /issm/trunk/src/c/DataSet/Nodes.cpp	(revision 4218)
+++ /issm/trunk/src/c/DataSet/Nodes.cpp	(revision 4219)
@@ -42,3 +42,205 @@
 /*}}}*/
 
-/*Object management*/
+/*Numerics*/
+/*FUNCTION Nodes::DistributeDofs{{{1*/
+void  Nodes::DistributeDofs(int numberofobjects,int numberofdofsperobject){
+
+	extern int num_procs;
+	extern int my_rank;
+
+	int  i;
+	
+	int  dofcount=0;
+	int* alldofcount=NULL;
+	int* truedofs=NULL;
+	int* alltruedofs=NULL;
+
+	/*Go through objects, and distribute dofs locally, from 0 to numberofdofsperobject: */
+	for (i=0;i<this->Size();i++){
+		Node* node=(Node*)this->GetObjectByOffset(i);
+		node->DistributeDofs(&dofcount);
+	}
+
+	/*Ok, now every object has distributed dofs, but locally, and with a dof count starting from 
+	 *0. This means the dofs between all the cpus are not synchronized! We need to synchronize all 
+	 *dof on all cpus, and use those to update the dofs of every object: */
+
+	alldofcount=(int*)xmalloc(num_procs*sizeof(int));
+	MPI_Gather(&dofcount,1,MPI_INT,alldofcount,1,MPI_INT,0,MPI_COMM_WORLD);
+	MPI_Bcast(alldofcount,num_procs,MPI_INT,0,MPI_COMM_WORLD);
+
+	/*Ok, now every cpu should start its own dof count at the end of the dofcount 
+	 * from cpu-1. : */
+	dofcount=0;
+	if(my_rank==0){
+		dofcount=0;
+	}
+	else{
+		for(i=0;i<my_rank;i++){
+			dofcount+=alldofcount[i];
+		}
+	}
+
+
+	/*Ok, now every cpu knows where his dofs should start. Update the dof count: */
+	for (i=0;i<this->Size();i++){
+		Node* node=(Node*)this->GetObjectByOffset(i);
+		node->OffsetDofs(dofcount);
+	}
+
+	/*Finally, remember that cpus may have skipped some objects, because they were clones. For every 
+	 * object that is not a clone, tell them to show their dofs, so that later on, they can get picked 
+	 * up by their clones: */
+	truedofs=(int*)xcalloc(numberofobjects*numberofdofsperobject,sizeof(int));
+	alltruedofs=(int*)xcalloc(numberofobjects*numberofdofsperobject,sizeof(int));
+
+	for (i=0;i<this->Size();i++){
+		Node* node=(Node*)this->GetObjectByOffset(i);
+		node->ShowTrueDofs(truedofs);
+	}
+	
+	MPI_Allreduce ( (void*)truedofs,(void*)alltruedofs,numberofobjects*numberofdofsperobject,MPI_INT,MPI_MAX,MPI_COMM_WORLD);
+
+	/*Ok, now every cpu knows the true dofs of everyone else that is not a clone. Let the clones recover those true dofs: */
+	for (i=0;i<this->Size();i++){
+		Node* node=(Node*)this->GetObjectByOffset(i);
+		node->UpdateCloneDofs(alltruedofs);
+	}
+
+	/* Free ressources: */
+	xfree((void**)&alldofcount);
+	xfree((void**)&truedofs);
+	xfree((void**)&alltruedofs);
+
+}
+/*}}}*/
+/*FUNCTION Nodes::FlagClones{{{1*/
+void  Nodes::FlagClones(int numberofobjects){
+
+	int i;
+	extern int num_procs;
+
+	int* ranks=NULL;
+	int* minranks=NULL;
+
+	/*Allocate ranks: */
+	ranks=(int*)xmalloc(numberofobjects*sizeof(int));
+	minranks=(int*)xmalloc(numberofobjects*sizeof(int));
+
+	for(i=0;i<numberofobjects;i++)ranks[i]=num_procs; //no cpu can have rank num_procs. This is the maximum limit.
+
+	/*Now go through all our objects and ask them to report to who they belong (which rank): */
+	Ranks(ranks);
+
+	/*We need to take the minimum rank for each vertex, and every cpu needs to get that result. That way, 
+	 * when we start building the dof list for all vertexs, a cpu can check whether its vertex already has been 
+	 * dealt with by another cpu. We take the minimum because we are going to manage dof assignment in increasing 
+	 * order of cpu rank. This is also why we initialized this array to num_procs.*/
+	MPI_Allreduce ( (void*)ranks,(void*)minranks,numberofobjects,MPI_INT,MPI_MIN,MPI_COMM_WORLD);
+
+	/*Now go through all objects, and use minranks to flag which objects are cloned: */
+	for(i=0;i<this->Size();i++){
+		/*For this object, decide whether it is a clone: */
+		Node* node=(Node*)this->GetObjectByOffset(i);
+		node->SetClone(minranks);
+	}
+
+	/*Free ressources: */
+	xfree((void**)&ranks); 
+	xfree((void**)&minranks);
+
+}
+/*}}}*/
+/*FUNCTION Nodes::FlagNodeSets{{{1*/
+void Nodes::FlagNodeSets(Vec pv_g, Vec pv_m, Vec pv_n, Vec pv_f, Vec pv_s,int analysis_type){
+
+	int i;
+
+	for(i=0;i<this->Size();i++){
+		Node* node=(Node*)this->GetObjectByOffset(i);
+			
+		if (node->InAnalysis(analysis_type)){
+			/*Plug set values intp our 4 set vectors: */
+			node->CreateVecSets(pv_g,pv_m,pv_n,pv_f,pv_s);
+		}
+	}
+
+	/*Assemble: */
+	VecAssemblyBegin(pv_g);
+	VecAssemblyEnd(pv_g);
+
+	VecAssemblyBegin(pv_m);
+	VecAssemblyEnd(pv_m);
+
+	VecAssemblyBegin(pv_n);
+	VecAssemblyEnd(pv_n);
+
+	VecAssemblyBegin(pv_f);
+	VecAssemblyEnd(pv_f);
+
+	VecAssemblyBegin(pv_s);
+	VecAssemblyEnd(pv_s);
+
+}
+/*}}}*/
+/*FUNCTION Nodes::NumberOfDofs(int analysis_type){{{1*/
+int   Nodes::NumberOfDofs(int analysis_type){
+
+	int i;
+	
+	int   numdofs=0;
+	int   allnumdofs;
+
+	/*Now go through all nodes, and get how many dofs they own, unless they are clone nodes: */
+	for(i=0;i<this->Size();i++){
+
+		Node* node=(Node*)this->GetObjectByOffset(i);
+
+		/*Check that this node corresponds to our analysis currently being carried out: */
+		if (node->InAnalysis(analysis_type)){
+
+			/*Ok, this object is a node, ask it to plug values into partition: */
+			if (!node->IsClone()){
+
+				numdofs+=node->GetNumberOfDofs();
+
+			}
+		}
+	}
+
+	/*Gather from all cpus: */
+	MPI_Allreduce ( (void*)&numdofs,(void*)&allnumdofs,1,MPI_INT,MPI_SUM,MPI_COMM_WORLD);
+
+	return allnumdofs;
+}
+/*}}}*/
+/*FUNCTION Nodes::NumberOfNodes{{{1*/
+int Nodes::NumberOfNodes(void){
+
+	int i;
+
+	int max_sid=0;
+	int sid;
+	int node_max_sid;
+
+	for(i=0;i<this->Size();i++){
+
+		Node* node=(Node*)this->GetObjectByOffset(i);
+		sid=node->Sid();
+		if (sid>max_sid)max_sid=sid;
+	}
+
+	#ifdef _PARALLEL_
+	MPI_Reduce (&max_sid,&node_max_sid,1,MPI_INT,MPI_MAX,0,MPI_COMM_WORLD );
+	MPI_Bcast(&node_max_sid,1,MPI_INT,0,MPI_COMM_WORLD);
+	max_sid=node_max_sid;
+	#endif 
+
+	/*sid starts at 0*/
+	max_sid++;
+
+	/*return*/
+	return max_sid;
+}
+/*}}}*/
+
Index: /issm/trunk/src/c/DataSet/Vertices.cpp
===================================================================
--- /issm/trunk/src/c/DataSet/Vertices.cpp	(revision 4218)
+++ /issm/trunk/src/c/DataSet/Vertices.cpp	(revision 4219)
@@ -42,3 +42,139 @@
 /*}}}*/
 
-/*Object management*/
+/*Numerics management*/
+/*FUNCTION Vertices::CreatePartitioningVector{{{1*/
+void  Vertices::CreatePartitioningVector(Vec* ppartition,int numberofobjects){
+
+	int i;
+
+	/*output: */
+	Vec partition=NULL;
+
+	/*Create partition vector: */
+	partition=NewVec(numberofobjects);
+
+	/*Go through all objects, and ask each object to plug its doflist in 
+	 * partition: */
+
+	for(i=0;i<this->Size();i++){
+		Vertex* vertex=(Vertex*)this->GetObjectByOffset(i);
+		vertex->CreatePartition(partition);
+	}
+
+	/*Assemble the petsc vector: */
+	VecAssemblyBegin(partition);
+	VecAssemblyEnd(partition);
+
+	/*Assign output pointers: */
+	*ppartition=partition;
+}
+/*}}}*/
+/*FUNCTION Vertices::DistributeDofs{{{1*/
+void  Vertices::DistributeDofs(int numberofobjects,int numberofdofsperobject){
+
+	extern int num_procs;
+	extern int my_rank;
+
+	int  i;
+	
+	int  dofcount=0;
+	int* alldofcount=NULL;
+	int* truedofs=NULL;
+	int* alltruedofs=NULL;
+
+	/*Go through objects, and distribute dofs locally, from 0 to numberofdofsperobject: */
+	for (i=0;i<this->Size();i++){
+		Vertex* vertex=(Vertex*)this->GetObjectByOffset(i);
+		vertex->DistributeDofs(&dofcount);
+	}
+
+	/*Ok, now every object has distributed dofs, but locally, and with a dof count starting from 
+	 *0. This means the dofs between all the cpus are not synchronized! We need to synchronize all 
+	 *dof on all cpus, and use those to update the dofs of every object: */
+
+	alldofcount=(int*)xmalloc(num_procs*sizeof(int));
+	MPI_Gather(&dofcount,1,MPI_INT,alldofcount,1,MPI_INT,0,MPI_COMM_WORLD);
+	MPI_Bcast(alldofcount,num_procs,MPI_INT,0,MPI_COMM_WORLD);
+
+	/*Ok, now every cpu should start its own dof count at the end of the dofcount 
+	 * from cpu-1. : */
+	dofcount=0;
+	if(my_rank==0){
+		dofcount=0;
+	}
+	else{
+		for(i=0;i<my_rank;i++){
+			dofcount+=alldofcount[i];
+		}
+	}
+
+
+	/*Ok, now every cpu knows where his dofs should start. Update the dof count: */
+	for (i=0;i<this->Size();i++){
+		Vertex* vertex=(Vertex*)this->GetObjectByOffset(i);
+		vertex->OffsetDofs(dofcount);
+	}
+
+	/*Finally, remember that cpus may have skipped some objects, because they were clones. For every 
+	 * object that is not a clone, tell them to show their dofs, so that later on, they can get picked 
+	 * up by their clones: */
+	truedofs=(int*)xcalloc(numberofobjects*numberofdofsperobject,sizeof(int));
+	alltruedofs=(int*)xcalloc(numberofobjects*numberofdofsperobject,sizeof(int));
+
+	for (i=0;i<this->Size();i++){
+		Vertex* vertex=(Vertex*)this->GetObjectByOffset(i);
+		vertex->ShowTrueDofs(truedofs);
+	}
+	
+	MPI_Allreduce ( (void*)truedofs,(void*)alltruedofs,numberofobjects*numberofdofsperobject,MPI_INT,MPI_MAX,MPI_COMM_WORLD);
+
+	/*Ok, now every cpu knows the true dofs of everyone else that is not a clone. Let the clones recover those true dofs: */
+	for (i=0;i<this->Size();i++){
+		Vertex* vertex=(Vertex*)this->GetObjectByOffset(i);
+		vertex->UpdateCloneDofs(alltruedofs);
+	}
+
+	/* Free ressources: */
+	xfree((void**)&alldofcount);
+	xfree((void**)&truedofs);
+	xfree((void**)&alltruedofs);
+
+}
+/*}}}*/
+/*FUNCTION Vertices::FlagClones{{{1*/
+void  Vertices::FlagClones(int numberofobjects){
+
+	int i;
+	extern int num_procs;
+
+	int* ranks=NULL;
+	int* minranks=NULL;
+
+	/*Allocate ranks: */
+	ranks=(int*)xmalloc(numberofobjects*sizeof(int));
+	minranks=(int*)xmalloc(numberofobjects*sizeof(int));
+
+	for(i=0;i<numberofobjects;i++)ranks[i]=num_procs; //no cpu can have rank num_procs. This is the maximum limit.
+
+	/*Now go through all our objects and ask them to report to who they belong (which rank): */
+	Ranks(ranks);
+
+	/*We need to take the minimum rank for each vertex, and every cpu needs to get that result. That way, 
+	 * when we start building the dof list for all vertexs, a cpu can check whether its vertex already has been 
+	 * dealt with by another cpu. We take the minimum because we are going to manage dof assignment in increasing 
+	 * order of cpu rank. This is also why we initialized this array to num_procs.*/
+	MPI_Allreduce ( (void*)ranks,(void*)minranks,numberofobjects,MPI_INT,MPI_MIN,MPI_COMM_WORLD);
+
+	/*Now go through all objects, and use minranks to flag which objects are cloned: */
+	for(i=0;i<this->Size();i++){
+		/*For this object, decide whether it is a clone: */
+		Vertex* vertex=(Vertex*)this->GetObjectByOffset(i);
+		vertex->SetClone(minranks);
+	}
+
+	/*Free ressources: */
+	xfree((void**)&ranks); 
+	xfree((void**)&minranks);
+
+}
+/*}}}*/
Index: sm/trunk/src/c/objects/DofObject.h
===================================================================
--- /issm/trunk/src/c/objects/DofObject.h	(revision 4218)
+++ 	(revision )
@@ -1,24 +1,0 @@
-/*!\file:  DofObject.h
- * \brief abstract class for any object that owns dofs
- */ 
-
-
-#ifndef _DOFOBJECT_H_
-#define _DOFOBJECT_H_
-
-/*Headers:*/
-#include "../toolkits/toolkits.h"
-
-class DofObject{
-
-	public: 
-		virtual void  DistributeDofs(int* pdofcount)=0;
-		virtual void  OffsetDofs(int dofcount)=0;
-		virtual void  ShowTrueDofs(int* borderdofs)=0;
-		virtual void  UpdateCloneDofs(int* allborderdofs)=0;
-		virtual void  SetClone(int* minranks)=0;
-		virtual int   Sid(void)=0;
-		virtual void  CreatePartition(Vec partition)=0;
-
-};
-#endif
Index: /issm/trunk/src/c/objects/Node.h
===================================================================
--- /issm/trunk/src/c/objects/Node.h	(revision 4218)
+++ /issm/trunk/src/c/objects/Node.h	(revision 4219)
@@ -9,5 +9,4 @@
 /*{{{1*/
 #include "./Object.h"
-#include "./DofObject.h"
 #include "../shared/shared.h"
 class  Inputs;
@@ -19,5 +18,5 @@
 /*}}}*/
 
-class Node: public Object,public DofObject{
+class Node: public Object{
 
 	private: 
Index: /issm/trunk/src/c/objects/Vertex.cpp
===================================================================
--- /issm/trunk/src/c/objects/Vertex.cpp	(revision 4218)
+++ /issm/trunk/src/c/objects/Vertex.cpp	(revision 4219)
@@ -321,3 +321,2 @@
 /*}}}*/
 /*}}}*/
-
Index: /issm/trunk/src/c/objects/Vertex.h
===================================================================
--- /issm/trunk/src/c/objects/Vertex.h	(revision 4218)
+++ /issm/trunk/src/c/objects/Vertex.h	(revision 4219)
@@ -9,7 +9,7 @@
 /*{{{1*/
 #include "./Object.h"
-#include "./DofObject.h"
 class IoModel;
 #include "../shared/Exceptions/exceptions.h"
+#include "../toolkits/toolkits.h"
 #include "../include/include.h"
 
@@ -17,5 +17,5 @@
 
 
-class Vertex: public Object,public DofObject{
+class Vertex: public Object{
 
 	public: 
Index: /issm/trunk/src/c/solvers/solver_diagnostic_nonlinear.cpp
===================================================================
--- /issm/trunk/src/c/solvers/solver_diagnostic_nonlinear.cpp	(revision 4218)
+++ /issm/trunk/src/c/solvers/solver_diagnostic_nonlinear.cpp	(revision 4219)
@@ -30,5 +30,4 @@
 	int num_unstable_constraints;
 	int count;
-	int numberofnodes;
 	int min_mechanical_constraints;
 	int max_nonlinear_iterations;
@@ -42,5 +41,4 @@
 	/*Recover parameters: */
 	kflag=1; pflag=1;
-	numberofnodes=femmodel->nodes->NumberOfNodes();
 	femmodel->parameters->FindParam(&solver_string,SolverStringEnum);
 	femmodel->parameters->FindParam(&dim,DimEnum);
Index: /issm/trunk/src/c/solvers/solver_thermal_nonlinear.cpp
===================================================================
--- /issm/trunk/src/c/solvers/solver_thermal_nonlinear.cpp	(revision 4218)
+++ /issm/trunk/src/c/solvers/solver_thermal_nonlinear.cpp	(revision 4219)
@@ -29,5 +29,4 @@
 	int num_unstable_constraints;
 	int count;
-	int numberofnodes;
 	int min_thermal_constraints;
 	bool reset_penalties;
@@ -42,5 +41,4 @@
 	kflag=1; pflag=1;
 
-	numberofnodes=fem->nodes->NumberOfNodes();
 	fem->parameters->FindParam(&solver_string,SolverStringEnum);
 	fem->parameters->FindParam(&verbose,VerboseEnum);
