/*!\file:  GetLocalDofList.cpp
 * \brief create new element matrix
 */ 
#include "./elements.h"

int* GetLocalDofList(Node** nodes,int numnodes,int setenum,int approximation){

	int  i,j,count,numdof,numgdof;
	int* ndof_list=NULL;
	int* ngdof_list_cumulative=NULL;
	int *doflist = NULL;

	if(numnodes){
		/*allocate: */
		ndof_list=xNew<int>(numnodes);
		ngdof_list_cumulative=xNew<int>(numnodes);

		/*Get number of dofs per node, and total for this given set*/
		numdof=0;
		numgdof=0;
		for(i=0;i<numnodes;i++){

			/*Cumulative list= number of dofs before node i*/
			ngdof_list_cumulative[i]=numgdof;

			/*Number of dofs for node i for given set and for the g set*/
			ndof_list[i]=nodes[i]->GetNumberOfDofs(approximation,setenum);
			numgdof    +=nodes[i]->GetNumberOfDofs(approximation,GsetEnum);
			numdof     +=ndof_list[i];
		}

		if(numdof){
			/*Allocate: */
			doflist=xNew<int>(numdof);

			/*Populate: */
			count=0;
			for(i=0;i<numnodes;i++){
				nodes[i]->GetLocalDofList(&doflist[count],approximation,setenum);
				count+=ndof_list[i];
			}

			/*We now have something like: [0 1 0 2 1 2]. Offset by gsize, to get something like: [0 1 2 4 6 7]:*/
			count=0;
			for(i=0;i<numnodes;i++){
				for(j=0;j<ndof_list[i];j++){
					doflist[count+j]+=ngdof_list_cumulative[i];
				}
				count+=ndof_list[i];
			}
		}
		else doflist=NULL;
	}

	/*Free ressources:*/
	xDelete<int>(ndof_list);
	xDelete<int>(ngdof_list_cumulative);

	/*CLean-up and return*/
	return doflist;
}
