/*!\file Mergesolutionfromftogx
 * \brief merge solution back from f set into g set
 */

#include "./Mergesolutionfromftogx.h"

#undef __FUNCT__ 
#define __FUNCT__ "Mergesolutionfromftogx"

void	Mergesolutionfromftogx( Vec* pug, Vec uf, Mat Gmn, Vec ys, NodeSets* nodesets){

	/*output: */
	Vec ug=NULL;
	int  ug_local_size;

	/*intermediary*/
	Vec u_m=NULL;
	Vec u_n=NULL;
	int  u_n_local_size;
	int  Gmn_localm,Gmn_localn;
	
	
	/*Merge f set back into n set: */
	u_n=NewVec(nodesets->GetNSize());
	VecMerge(u_n,uf,nodesets->GetPV_F(),nodesets->GetFSize());

	/*merge single point constraints into n set: */
	if(ys){
		VecMerge(u_n,ys,nodesets->GetPV_S(),nodesets->GetSSize());
	}

	/* Merge n_set and m_set to g_set:*/
	ug=NewVec(nodesets->GetGSize());
	VecMerge(ug,u_n,nodesets->GetPV_N(),nodesets->GetNSize());

	/*Merge m set into g set: */
	if(nodesets->GetMSize()){
		MatGetLocalSize(Gmn,&Gmn_localm,&Gmn_localn);
		u_m=NewVecFromLocalSize(Gmn_localm);
		MatMultPatch(Gmn,u_n,u_m);
		VecMerge(ug,u_m,nodesets->GetPV_M(),nodesets->GetMSize());
	}
	
		
	/*Free ressources:*/
	VecFree(&u_m);
	VecFree(&u_n);

	/*Assign correct pointer*/
	*pug=ug;
}
