Index: /issm/trunk-jpl/src/c/classes/Loads/Loads.cpp
===================================================================
--- /issm/trunk-jpl/src/c/classes/Loads/Loads.cpp	(revision 24629)
+++ /issm/trunk-jpl/src/c/classes/Loads/Loads.cpp	(revision 24630)
@@ -19,4 +19,6 @@
 #include "../../shared/Enum/EnumDefinitions.h"
 #include "../../shared/Exceptions/exceptions.h"
+#include "../../shared/MemOps/MemOps.h"
+#include "../../shared/io/Marshalling/Marshalling.h"
 #include "./Loads.h"
 #include "./Load.h"
@@ -27,5 +29,7 @@
 /*Object constructors and destructor*/
 Loads::Loads(){/*{{{*/
-	enum_type=LoadsEnum;
+	this->enum_type=LoadsEnum;
+	this->numrifts     = 0;
+	this->numpenalties = 0;
 	return;
 }
@@ -36,16 +40,83 @@
 /*}}}*/
 
+Loads* Loads::Copy() {/*{{{*/
+
+	int num_proc = IssmComm::GetSize();
+
+	/*Copy dataset*/
+	Loads* output=new Loads();
+	output->sorted=this->sorted;
+	output->numsorted=this->numsorted;
+	output->presorted=this->presorted;
+	for(vector<Object*>::iterator obj=this->objects.begin() ; obj < this->objects.end(); obj++ ){
+		output->AddObject((*obj)->copy());
+	}
+
+	/*Build id_offsets and sorted_ids*/
+	int objsize = this->numsorted;
+	output->id_offsets=NULL;
+	output->sorted_ids=NULL;
+	if(this->sorted && objsize>0 && this->id_offsets){	
+		output->id_offsets=xNew<int>(objsize);
+		xMemCpy<int>(output->id_offsets,this->id_offsets,objsize);
+	}
+	if(this->sorted && objsize>0 && this->sorted_ids){
+		output->sorted_ids=xNew<int>(objsize);
+		xMemCpy<int>(output->sorted_ids,this->sorted_ids,objsize);
+	}
+
+	/*Copy other fields*/
+	output->numrifts = this->numrifts;
+	output->numpenalties = this->numpenalties;
+
+	return output;
+}
+/*}}}*/
+void  Loads::Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction){ /*{{{*/
+
+	int num_procs=IssmComm::GetSize();
+	int test = num_procs;
+	MARSHALLING_ENUM(LoadsEnum);
+	MARSHALLING(numrifts);
+	MARSHALLING(numpenalties);
+
+	DataSet::Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction);
+}
+/*}}}*/
+
 /*Numerics:*/
 void Loads::Configure(Elements* elements,Loads* loads, Nodes* nodes, Vertices* vertices, Materials* materials,Parameters* parameters){/*{{{*/
 
 	vector<Object*>::iterator object;
-	Load* load=NULL;
+	for(object=objects.begin() ; object < objects.end(); object++){
+		Load* load=xDynamicCast<Load*>(*object);
+		load->Configure(elements,loads,nodes,vertices,materials,parameters);
+	}
+}
+/*}}}*/
+void Loads::Finalize(){/*{{{*/
 
-	for ( object=objects.begin() ; object < objects.end(); object++ ){
+	/*Count Rifts and penalties*/
+	int ispenalty=0;
+	int isrift=0;
+	int allcount;
 
-		load=xDynamicCast<Load*>(*object);
-		load->Configure(elements,loads,nodes,vertices,materials,parameters);
+	/*Now go through all loads, and get how many nodes they own, unless they are clone nodes: */
+	for(int i=0;i<this->Size();i++){
+		Load* load=xDynamicCast<Load*>(this->GetObjectByOffset(i));
+		if(load->IsPenalty()){
+			ispenalty++;
+		}
+      if(load->ObjectEnum()==RiftfrontEnum){
+         isrift++;
+      }
+	}
 
-	}
+	/*Grab sum of all cpus: */
+	ISSM_MPI_Allreduce((void*)&ispenalty,(void*)&allcount,1,ISSM_MPI_INT,ISSM_MPI_SUM,IssmComm::GetComm());
+	this->numpenalties = allcount;
+
+	ISSM_MPI_Allreduce((void*)&isrift,(void*)&allcount,1,ISSM_MPI_INT,ISSM_MPI_SUM,IssmComm::GetComm());
+	this->numrifts= allcount;
 
 }
@@ -53,18 +124,5 @@
 bool Loads::IsPenalty(){/*{{{*/
 
-	int ispenalty=0;
-	int allispenalty=0;
-
-	/*Now go through all loads, and get how many nodes they own, unless they are clone nodes: */
-	for(int i=0;i<this->Size();i++){
-		Load* load=xDynamicCast<Load*>(this->GetObjectByOffset(i));
-		if(load->IsPenalty()) ispenalty++;
-	}
-
-	/*Grab sum of all cpus: */
-	ISSM_MPI_Allreduce((void*)&ispenalty,(void*)&allispenalty,1,ISSM_MPI_INT,ISSM_MPI_SUM,IssmComm::GetComm());
-	ispenalty=allispenalty;
-
-	if(ispenalty)
+	if(this->numpenalties>0)
 	 return true;
 	else
Index: /issm/trunk-jpl/src/c/classes/Loads/Loads.h
===================================================================
--- /issm/trunk-jpl/src/c/classes/Loads/Loads.h	(revision 24629)
+++ /issm/trunk-jpl/src/c/classes/Loads/Loads.h	(revision 24630)
@@ -18,11 +18,19 @@
 	public:
 
+		int numrifts;
+		int numpenalties;
+
 		/*constructors, destructors*/
 		Loads();
 		~Loads();
 
+		/*Objects virtual functions*/
+		Loads* Copy();
+		void   Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction);
+
 		/*numerics*/
 		void  Configure(Elements* elements,Loads* loads, Nodes* nodes, Vertices* vertices, Materials* materials,Parameters* parameters);
 		bool  IsPenalty();
+		void  Finalize();
 		int   MaxNumNodes();
 		int   NumberOfLoads();
Index: /issm/trunk-jpl/src/c/modules/ConstraintsStatex/ConstraintsStatex.cpp
===================================================================
--- /issm/trunk-jpl/src/c/modules/ConstraintsStatex/ConstraintsStatex.cpp	(revision 24629)
+++ /issm/trunk-jpl/src/c/modules/ConstraintsStatex/ConstraintsStatex.cpp	(revision 24630)
@@ -10,10 +10,17 @@
 void ConstraintsStatex(int* pconverged, int* pnum_unstable_constraints,FemModel* femmodel){
 
+	/*Early return if no rift and no penalties*/
+	if(femmodel->loads->numrifts == 0 && femmodel->loads->numpenalties == 0){
+		*pconverged                = 0;
+		*pnum_unstable_constraints = 0;
+		return;
+	}
+
 	/*output: */
-	int converged                     = 1;
-	int num_unstable_constraints      = 0;
-	int min_mechanical_constraints    = 0;
-	int  unstable                     = 0;
-	int  sum_num_unstable_constraints = 0;
+	int converged                    = 1;
+	int num_unstable_constraints     = 0;
+	int min_mechanical_constraints   = 0;
+	int unstable                     = 0;
+	int sum_num_unstable_constraints = 0;
 	int analysis_type;
 
@@ -26,17 +33,20 @@
 
 	/*Rift penalties first*/
-	if(RiftIsPresent(femmodel->loads,analysis_type)){
+	if(femmodel->loads->numrifts){
 		RiftConstraintsState(&converged,&num_unstable_constraints,femmodel->loads,min_mechanical_constraints,analysis_type);
 	}
 
 	/*Deal with pengrid*/
-	for(int i=0;i<femmodel->loads->Size();i++){
-		Load* load=(Load*)femmodel->loads->GetObjectByOffset(i);
-		if(load->ObjectEnum()==PengridEnum){
-			Pengrid* pengrid=(Pengrid*)load;
-			pengrid->ConstraintActivate(&unstable);
-			num_unstable_constraints += unstable;
+	if(femmodel->loads->numpenalties){
+		for(int i=0;i<femmodel->loads->Size();i++){
+			Load* load=(Load*)femmodel->loads->GetObjectByOffset(i);
+			if(load->ObjectEnum()==PengridEnum){
+				Pengrid* pengrid=(Pengrid*)load;
+				pengrid->ConstraintActivate(&unstable);
+				num_unstable_constraints += unstable;
+			}
 		}
 	}
+
 	ISSM_MPI_Reduce(&num_unstable_constraints,&sum_num_unstable_constraints,1,ISSM_MPI_INT,ISSM_MPI_SUM,0,IssmComm::GetComm() );
 	ISSM_MPI_Bcast(&sum_num_unstable_constraints,1,ISSM_MPI_INT,0,IssmComm::GetComm());                
Index: /issm/trunk-jpl/src/c/modules/ConstraintsStatex/ConstraintsStatex.h
===================================================================
--- /issm/trunk-jpl/src/c/modules/ConstraintsStatex/ConstraintsStatex.h	(revision 24629)
+++ /issm/trunk-jpl/src/c/modules/ConstraintsStatex/ConstraintsStatex.h	(revision 24630)
@@ -9,5 +9,4 @@
 
 /* local prototypes: */
-int  RiftIsPresent(Loads* loads,int analysis_type);
 void ConstraintsStatex(int* pconverged, int* pnum_unstable_constraints,FemModel* femmodel);
 
Index: /issm/trunk-jpl/src/c/modules/ConstraintsStatex/RiftConstraintsState.cpp
===================================================================
--- /issm/trunk-jpl/src/c/modules/ConstraintsStatex/RiftConstraintsState.cpp	(revision 24629)
+++ /issm/trunk-jpl/src/c/modules/ConstraintsStatex/RiftConstraintsState.cpp	(revision 24630)
@@ -6,28 +6,4 @@
 
 /*current module: */
-/*RiftIsPresent(Loads* loads,int configuration_type){{{*/
-int RiftIsPresent(Loads* loads,int configuration_type){
-
-	int i;
-
-	int found=0;
-	int mpi_found=0;
-
-	/*go though loads, and figure out if one of the loads is a Riftfront: */
-	for (i=0;i<loads->Size();i++){
-		Load* load=(Load*)loads->GetObjectByOffset(i);
-		if(RiftfrontEnum==loads->GetEnum(i)){
-			found=1;
-			break;
-		}
-	}
-
-	ISSM_MPI_Reduce (&found,&mpi_found,1,ISSM_MPI_INT,ISSM_MPI_SUM,0,IssmComm::GetComm() );
-	ISSM_MPI_Bcast(&mpi_found,1,ISSM_MPI_INT,0,IssmComm::GetComm());                
-	found=mpi_found;
-
-	return found;
-}
-/*}}}*/
 /*RiftConstraintsState(int* pconverged, int* pnum_unstable_constraints,Loads* loads,int min_mechanical_constraints,int configuration_type){{{*/
 void RiftConstraintsState(int* pconverged, int* pnum_unstable_constraints,Loads* loads,int min_mechanical_constraints,int configuration_type){
Index: /issm/trunk-jpl/src/c/modules/ModelProcessorx/ModelProcessorx.cpp
===================================================================
--- /issm/trunk-jpl/src/c/modules/ModelProcessorx/ModelProcessorx.cpp	(revision 24629)
+++ /issm/trunk-jpl/src/c/modules/ModelProcessorx/ModelProcessorx.cpp	(revision 24630)
@@ -69,4 +69,7 @@
 		loads[i]->Presort();
 		nodes[i]->Presort();
+
+		/*Finalize loads (count pengrids,penpairs,rifts,etc)*/
+		loads[i]->Finalize();
 	}
 
Index: /issm/trunk-jpl/src/c/modules/ResetConstraintsx/ResetConstraintsx.cpp
===================================================================
--- /issm/trunk-jpl/src/c/modules/ResetConstraintsx/ResetConstraintsx.cpp	(revision 24629)
+++ /issm/trunk-jpl/src/c/modules/ResetConstraintsx/ResetConstraintsx.cpp	(revision 24630)
@@ -24,5 +24,5 @@
 
 	/*Deal with rift first*/
-	if(RiftIsPresent(femmodel->loads,analysis_type)){
+	if(femmodel->loads->numrifts){
 		_error_("rift constraints reset not supported yet!");
 	}
@@ -43,5 +43,5 @@
 
 	/*Deal with rift first*/
-	if(RiftIsPresent(femmodel->loads,femmodel->analysis_type_list[femmodel->analysis_counter])){
+	if(femmodel->loads->numrifts){
 		_error_("rift constraints reset not supported yet!");
 	}
