/*
 * CreateConstraintsDiagnosticHutter.c:
 */

#include "../../../Container/Container.h"
#include "../../../toolkits/toolkits.h"
#include "../../../io/io.h"
#include "../../../EnumDefinitions/EnumDefinitions.h"
#include "../../../objects/objects.h"
#include "../../../shared/shared.h"
#include "../ModelProcessorx.h"

void	CreateConstraintsDiagnosticHutter(Constraints** pconstraints, IoModel* iomodel){

	/*Intermediary*/
	int i;
	int count;
	double yts;
	int    numberofvertices;
	bool   ishutter;

	/*Output*/
	Constraints* constraints = NULL;
	SpcStatic*    spcstatic  = NULL;

	/*Recover pointer: */
	constraints=*pconstraints;

	/*Fetch parameters: */
	iomodel->Constant(&yts,ConstantsYtsEnum);
	iomodel->Constant(&numberofvertices,MeshNumberofverticesEnum);
	iomodel->Constant(&ishutter,FlowequationIshutterEnum);

	/*Create constraints if they do not exist yet*/
	if(!constraints) constraints = new Constraints();

	/*Now, is the flag ishutter on? otherwise, do nothing: */
	if (!ishutter){
		*pconstraints=constraints;
		return;
	}

	/*Fetch data: */
	iomodel->FetchData(3,DiagnosticSpcvxEnum,DiagnosticSpcvyEnum,FlowequationVertexEquationEnum);

	/*Initialize conunter*/
	count=0;

	/*vx and vy are spc'd if we are not on nodeonhutter: */
	for (i=0;i<numberofvertices;i++){
		/*keep only this partition's nodes:*/
		if((iomodel->my_vertices[i])){
			if (!(int)iomodel->Data(FlowequationVertexEquationEnum)[i]==HutterApproximationEnum){

				constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,1,0,DiagnosticHutterAnalysisEnum));
				count++;

				constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,2,0,DiagnosticHutterAnalysisEnum));
				count++;
			}
			else{
				if (!xIsNan<IssmDouble>(iomodel->Data(DiagnosticSpcvxEnum)[i])){
					constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,1,iomodel->Data(DiagnosticSpcvxEnum)[i]/yts,DiagnosticHutterAnalysisEnum)); //add count'th spc, on node i+1, setting dof 1 to vx.
					count++;
				}

				if (!xIsNan<IssmDouble>(iomodel->Data(DiagnosticSpcvyEnum)[i])){
					constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+i+1,2,iomodel->Data(DiagnosticSpcvyEnum)[i]/yts,DiagnosticHutterAnalysisEnum)); //add count'th spc, on node i+1, setting dof 2 to vy
					count++;
				}
			}
		}
	}

	/*Free data: */
	iomodel->DeleteData(3,DiagnosticSpcvxEnum,DiagnosticSpcvyEnum,FlowequationVertexEquationEnum);
	
	/*Assign output pointer: */
	*pconstraints=constraints;
}
