/*!\file Pengrid.h
 * \brief: header file for pengrid object */

#ifndef _PENGRID_H_
#define _PENGRID_H_

/*Headers:*/
/*{{{*/
#include "./Load.h"
class Hook;
class Inputs;
class Parameters;
class IoModel;
/*}}}*/

class Pengrid: public Load{

	private: 

		int		id;
		int analysis_type;

		/*Hooks*/
		Hook* hnode;  //hook to 1 node
		Hook* helement;  //hook to 1 element
		Hook* hmatpar; //hook to 1 matpar

		/*Corresponding fields*/
		Node    *node;
		Element *element;
		Matpar  *matpar;

		Parameters* parameters; //pointer to solution parameters
		Inputs*  inputs;

		/*internals: */
		int active;
		int zigzag_counter;

	public:

		/*Pengrid constructors, destructors {{{*/
		Pengrid();
		Pengrid(int index, int id, IoModel* iomodel,int analysis_type);
		~Pengrid();
		/*}}}*/
		/*Object virtual functions definitions:{{{ */
		void  Echo();
		void  DeepEcho();
		int   Id(); 
		int   ObjectEnum();
		Object* copy();
		/*}}}*/
		/*Update virtual functions resolution: {{{*/
		void  InputUpdateFromVector(IssmDouble* vector, int name, int type);
		void  InputUpdateFromVector(int* vector, int name, int type);
		void  InputUpdateFromVector(bool* vector, int name, int type);
		void  InputUpdateFromMatrixDakota(IssmDouble* matrix ,int nrows, int ncols, int name, int type);
		void  InputUpdateFromVectorDakota(IssmDouble* vector, int name, int type);
		void  InputUpdateFromVectorDakota(int* vector, int name, int type);
		void  InputUpdateFromVectorDakota(bool* vector, int name, int type);
		void  InputUpdateFromConstant(IssmDouble constant, int name);
		void  InputUpdateFromConstant(int constant, int name);
		void  InputUpdateFromConstant(bool constant, int name);
		void  InputUpdateFromSolution(IssmDouble* solution);
		void  InputUpdateFromIoModel(int index, IoModel* iomodel){_error_("not implemented yet");};
		/*}}}*/
		/*Load virtual functions definitions: {{{*/
		void  Configure(Elements* elements,Loads* loads,Nodes* nodes,Vertices* vertices,Materials* materials,Parameters* parameters);
		void  SetCurrentConfiguration(Elements* elements,Loads* loads,Nodes* nodes,Vertices* vertices,Materials* materials,Parameters* parameters);
		void  CreateKMatrix(Matrix<IssmDouble>* Kff, Matrix<IssmDouble>* Kfs);
		void  CreatePVector(Vector<IssmDouble>* pf);
		void  CreateJacobianMatrix(Matrix<IssmDouble>* Jff){_error_("Not implemented yet");};
		void  GetNodesSidList(int* sidlist);
		int   GetNumberOfNodes(void);
		bool  IsPenalty(void);
		void  PenaltyCreateJacobianMatrix(Matrix<IssmDouble>* Jff,IssmDouble kmax){_error_("Not implemented yet");};
		void  PenaltyCreateKMatrix(Matrix<IssmDouble>* Kff, Matrix<IssmDouble>* kfs, IssmDouble kmax);
		void  PenaltyCreatePVector(Vector<IssmDouble>* pf, IssmDouble kmax);
		void  SetwiseNodeConnectivity(int* d_nz,int* o_nz,Node* node,bool* flags,int set1_enum,int set2_enum);
		bool  InAnalysis(int analysis_type);
		/*}}}*/
		/*Pengrid management {{{*/
		#ifdef _HAVE_DIAGNOSTIC_
		ElementMatrix* PenaltyCreateKMatrixDiagnosticStokes(IssmDouble kmax);
		#endif
		#ifdef _HAVE_THERMAL_
		ElementMatrix* PenaltyCreateKMatrixThermal(IssmDouble kmax);
		ElementMatrix* PenaltyCreateKMatrixMelting(IssmDouble kmax);
		ElementVector* PenaltyCreatePVectorThermal(IssmDouble kmax);
		ElementVector* PenaltyCreatePVectorMelting(IssmDouble kmax);
		#endif
		void  ConstraintActivate(int* punstable);
		void  ConstraintActivateThermal(int* punstable);
		void  UpdateInputs(IssmDouble* solution);
		void  ResetConstraint(void);
		/*}}}*/

};

#endif  /* _PENGRID_H_ */
