/*!\file Dofx
 * \brief: establish degrees of freedom for all nodes
 */

#include "./Dofx.h"

#undef __FUNCT__ 
#define __FUNCT__ "Dofx"

#include "../shared/shared.h"
#include "../include/macros.h"
#include "../toolkits/toolkits.h"
#include "../EnumDefinitions/EnumDefinitions.h"

int Dofx( Vec* ppartition, Vec* ptpartition,DataSet* elements,DataSet* nodes, DataSet* params) {

	int noerr=1;
	int i;

	int  found=0;
	extern int num_procs;
	extern int my_rank;
	
	/*intermediary: */
	int  numberofnodes;
	int  numberofdofspernode;

	/*output: */
	Vec partition=NULL;
	Vec tpartition=NULL;

	/*First, recover number of grids from parameters: */
	found=params->FindParam((void*)&numberofnodes,"numberofnodes");
	if(!found)throw ErrorException(__FUNCT__," could not find numberofnodes in parameters");

	/*Recover number of dofs per node: */
	found=params->FindParam((void*)&numberofdofspernode,"numberofdofspernode");
	if(!found)throw ErrorException(__FUNCT__," could not find numberofdofspernode in parameters");

	/*Ensure that only for each cpu, the partition border nodes only will be taken into account once 
	 * across the cluster. To do so, we flag all the clone nodes: */
	nodes->FlagClones(numberofnodes);

	/*Go through all nodes, and build degree of freedom lists. Each node gets a fixed number of dofs. When 
	 *a  node has already been distributed dofs on one cpu, all other cpus with the same node cannot distribute it 
	 *anymore. Use clone field to be sure of that: */
	nodes->DistributeDofs(numberofnodes,numberofdofspernode);

	/*Now that dofs have been distributed, create partitioning vector and its transpose: */
	nodes->CreatePartitioningVector(&partition,numberofnodes,numberofdofspernode);

	/*Transpose partition into tpartition: */
	VecTranspose(&tpartition,partition);
	
	/*Assign output pointers: */
	*ppartition=partition;
	*ptpartition=tpartition;
	
	return noerr;
}
