Index: /issm/trunk-jpl/src/c/classes/Node.cpp
===================================================================
--- /issm/trunk-jpl/src/c/classes/Node.cpp	(revision 23629)
+++ /issm/trunk-jpl/src/c/classes/Node.cpp	(revision 23630)
@@ -866,46 +866,30 @@
 }
 /*}}}*/
-void Node::VecReduce(Vector<IssmDouble>* vector, IssmDouble* ug_serial,int setenum){/*{{{*/
-
-	IssmDouble* values=NULL;
-	int     count=0;
-	int     i;
-
-	if(setenum==FsetEnum){
-		if(this->fsize){
- 			values=xNew<IssmDouble>(this->fsize);
-
-			for(i=0;i<this->gsize;i++){
-				if(this->f_set[i]){
-					_assert_(ug_serial);
-					values[count]=ug_serial[this->gdoflist[i]];
-					count++;
-				}
-			}
-
-			/*Add values into ug: */
-			vector->SetValues(this->fsize,this->fdoflist,values,INS_VAL);
-		}
-	}
-	else if(setenum==SsetEnum){
-		if(this->ssize){
-			values=xNew<IssmDouble>(this->ssize);
-
-			for(i=0;i<this->gsize;i++){
-				if(this->s_set[i]){
-					_assert_(ug_serial);
-					values[count]=ug_serial[this->gdoflist[i]];
-					count++;
-				}
-			}
-
-			/*Add values into ug: */
-			vector->SetValues(this->ssize,this->sdoflist,values,INS_VAL);
-		}
-	}
-	else _error_("VecReduce can only merge from the s or f-set onto the g-set!");
-
-	/*Free ressources:*/
-	xDelete<IssmDouble>(values);
+void Node::VecReduce(Vector<IssmDouble>* uf, IssmDouble* local_ug,int* indices_ug){/*{{{*/
+
+
+	/*Only perform operation if not clone*/
+	if(this->IsClone()) return;
+
+	if(this->fsize){
+		int*        indices = xNew<int>(this->fsize);
+		IssmDouble* values  = xNew<IssmDouble>(this->fsize);
+
+		int count = 0;
+		for(int i=0;i<this->gsize;i++){
+			if(this->f_set[i]){
+				_assert_(local_ug);
+				_assert_(this->gdoflist[i]==indices_ug[this->gdoflist_local[i]]);
+
+				values[count] =local_ug[this->gdoflist_local[i]];
+				indices[count]=this->fdoflist[count];
+				count++;
+			}
+		}
+		uf->SetValues(this->fsize,indices,values,INS_VAL);
+
+		xDelete<IssmDouble>(values);
+		xDelete<int>(indices);
+	}
 }
 /*}}}*/
Index: /issm/trunk-jpl/src/c/classes/Node.h
===================================================================
--- /issm/trunk-jpl/src/c/classes/Node.h	(revision 23629)
+++ /issm/trunk-jpl/src/c/classes/Node.h	(revision 23630)
@@ -107,5 +107,5 @@
 		void  UpdateCloneDofs(int* alltruerows,int setenum);
 		void  VecMerge(Vector<IssmDouble>* ug,IssmDouble* local_uf,int* indices_uf,IssmDouble* local_ys,int* indices_ys);
-		void  VecReduce(Vector<IssmDouble>* vector, IssmDouble* ug_serial,int setnum);
+		void  VecReduce(Vector<IssmDouble>* uf, IssmDouble* local_ug,int* indices_ug);
 		void  SetApproximation(int in_approximation);
 };
Index: /issm/trunk-jpl/src/c/modules/Mergesolutionfromftogx/Mergesolutionfromftogx.cpp
===================================================================
--- /issm/trunk-jpl/src/c/modules/Mergesolutionfromftogx/Mergesolutionfromftogx.cpp	(revision 23629)
+++ /issm/trunk-jpl/src/c/modules/Mergesolutionfromftogx/Mergesolutionfromftogx.cpp	(revision 23630)
@@ -41,5 +41,5 @@
 	ug->Assemble();
 
-	/*Cleanup and assounf output pointer*/
+	/*Cleanup and assign output pointer*/
 	xDelete<int>(indices_uf);
 	xDelete<int>(indices_ys);
Index: /issm/trunk-jpl/src/c/modules/Reducevectorgtofx/Reducevectorgtofx.cpp
===================================================================
--- /issm/trunk-jpl/src/c/modules/Reducevectorgtofx/Reducevectorgtofx.cpp	(revision 23629)
+++ /issm/trunk-jpl/src/c/modules/Reducevectorgtofx/Reducevectorgtofx.cpp	(revision 23630)
@@ -8,11 +8,4 @@
 void Reducevectorgtofx(Vector<IssmDouble>** puf, Vector<IssmDouble>* ug, Nodes* nodes,Parameters* parameters){
 
-	/*output: */
-	Vector<IssmDouble>* uf=NULL;
-
-	/*variables: */
-	IssmDouble *ug_serial = NULL;
-	bool        oldalloc  = false;
-
 	if(VerboseModule()) _printf0_("   Reduce vector from g to f set\n");
 
@@ -21,35 +14,30 @@
 	int flocalsize = nodes->NumberOfDofsLocal(FsetEnum);
 
+	/*If fsize is 0, return NULL vector*/
 	if(fsize==0){
-		uf=NULL;
-	}
-	else{
-		/*allocate: */
-		if(oldalloc)
-		 uf=new Vector<IssmDouble>(fsize);
-		else
-		 uf=new Vector<IssmDouble>(flocalsize,fsize);
-
-		if(nodes->NumberOfNodes()){ 
-
-			/*serialize ug, so nodes can index into it: */
-			ug_serial=ug->ToMPISerial();
-
-			/*Go through all nodes, and ask them to retrieve values from ug, and plug them into uf: */
-			for(int i=0;i<nodes->Size();i++){
-				Node* node=(Node*)nodes->GetObjectByOffset(i);
-
-				/*For this object, reduce values for enum set Fset: */
-				node->VecReduce(uf,ug_serial,FsetEnum);
-			}
-		}
-		/*Assemble vector: */
-		uf->Assemble();
+		*puf=NULL;
+		return;
 	}
 
-	/*Free ressources:*/
-	xDelete<IssmDouble>(ug_serial);
+	/*Get local vectors ug*/
+	int        *indices_ug = NULL;
+	IssmDouble *local_ug   = NULL;
+	ug->GetLocalVector(&local_ug,&indices_ug);
 
-	/*Assign output pointers:*/
+	/*Allocate output*/
+	Vector<IssmDouble>* uf=new Vector<IssmDouble>(flocalsize,fsize);
+
+	/*Let nodes figure it out*/
+	for(int i=0;i<nodes->Size();i++){
+		Node* node=(Node*)nodes->GetObjectByOffset(i);
+		node->VecReduce(uf,local_ug,indices_ug);
+	}
+
+	/*Assemble vector: */
+	uf->Assemble();
+
+	/*Cleanup and assing output pointer*/
+	xDelete<int>(indices_ug);
+	xDelete<IssmDouble>(local_ug);
 	*puf=uf;
 }
