/*!\file: CreateFemModel.cpp
 * \brief: create all the datasets, vectors and matrices needed to run the finite element analysis.
 */ 

#undef __FUNCT__ 
#define __FUNCT__ "CreateFemModel"

#include "../objects/objects.h"
#include "../io/io.h"
#include "../issm.h"

void CreateFemModel(FemModel* femmodel,ConstDataHandle MODEL,char* analysis_type){

	/*Model output: */
	DataSet*            elements;
	DataSet*            nodes;
	DataSet*            constraints;
	DataSet*            loads;
	DataSet*            materials;
	DataSet*            parameters;
	Vec                 partition;
	Vec                 tpartition;
	Vec                 yg;
	Mat                 Rmg;
	Mat                 Gmn;
	NodeSets*           nodesets;
	Vec                 ys;
	Vec                 ys0;

	/*intermediary: */
	Model* model=NULL;
	

	_printf_("   fill model with matlab workspace data\n");
	ModelInit(&model,MODEL); 

	_printf_("   create elements, nodes and materials:\n");
	ModelCreateElementsNodesAndMaterials(&elements,&nodes,&materials,model,MODEL);

	_printf_("   create constraints: \n");
	ModelCreateConstraints(&constraints,model,MODEL);
	
	_printf_("   create loads: \n");
	ModelCreateLoads(&loads,model,MODEL);

	_printf_("   create parameters: \n");
	ModelCreateParameters(&parameters,model,MODEL);

	_printf_("   create degrees of freedom: \n");
	Dofx( &partition,&tpartition,elements,nodes, parameters);
	
	_printf_("   create single point constraints: \n");
	SpcNodesx( &yg, nodes,constraints); 
	
	_printf_("   create rigid body constraints:\n");
	MpcNodesx( &Rmg, nodes,constraints); 
	
	_printf_("   create node sets:\n");
	BuildNodeSetsx(&nodesets, nodes);

	_printf_("   reducing single point constraints vector:\n");
	Reducevectorgtosx(&ys,&ys0, yg,nodesets);
	
	_printf_("   normalizing rigid body constraints matrix:\n");
	NormalizeConstraintsx(&Gmn, Rmg,nodesets);
	
	_printf_("   configuring element and loads:\n");
	ConfigureObjectsx(elements, loads, nodes, materials);
	
	_printf_("   free ressources:\n");
	DeleteModel(&model);

	/*Assign output pointers:*/
	femmodel->elements=elements;
	femmodel->nodes=nodes;
	femmodel->constraints=constraints;
	femmodel->loads=loads;
	femmodel->materials=materials;
	femmodel->parameters=parameters;
	femmodel->partition=partition;
	femmodel->tpartition=tpartition;
	femmodel->yg=yg;
	femmodel->Rmg=Rmg;
	femmodel->Gmn=Gmn;
	femmodel->nodesets=nodesets;
	femmodel->ys=ys;
	femmodel->ys0=ys0;
	
}
