/*! \file Penta.h 
 *  \brief: header file for penta object
 */

#ifndef _PENTA_H
#define _PENTA_H

#include "./Object.h"
#include "./Element.h"
#include "./Matpar.h"
#include "./Matice.h"
#include "./Node.h"

class Penta: public Element{

	private: 
		int id;
		
		/*nodes: */
		int   node_ids[6]; //node ids
		Node* nodes[6]; //node pointers
		int   node_offsets[6]; //node offsets in nodes dataset

		/*materials: */
		int   mid;
		Matice* matice; 
		int   matice_offset;
		
		int mparid;
		Matpar* matpar; 
		int   matpar_offset;
	

		double h[6];
		double s[6];
		double b[6];
		double k[6];
		int    friction_type;
		double p;
		double q;
		int    shelf;
		int    onbed;
		int    onsurface;
		double fit;
		double meanvel;/*!scaling ratio for velocities*/
		double epsvel; /*!minimum velocity to avoid infinite velocity ratios*/
		int    acceleration;
		int    collapse;
		double melting[6];
		double accumulation[6];
		double geothermalflux[6];
		int    artdiff;
		int    thermal_steadystate;
	
	
	public:

		Penta();
		Penta( int id, int mid, int mparid, int g[6], double h[6], double s[6], double b[6], double k[6], int    friction_type, 
				double p, double q, int    shelf, int    onbed, int    onsurface, double fit, double meanvel,double epsvel, 
				int    acceleration, int    collapse, double melting[6], double accumulation[6], double geothermalflux[6], 
				int    artdiff, int    thermal_steadystate);
		~Penta();

		void  Echo();
		void  Marshall(char** pmarshalled_dataset);
		int   MarshallSize();
		char* GetName();
		void  Demarshall(char** pmarshalled_dataset);
		int   Enum();
		int   GetId(); 
		int   MyRank();
		void  Configure(void* loads,void* nodes,void* materials);
		void  CreateKMatrix(Mat Kgg,ParameterInputs* inputs,int analysis_type);
		void  CreatePVector(Vec pg, ParameterInputs* inputs, int analysis_type);
		void  UpdateFromInputs(ParameterInputs* inputs);
		Matpar* GetMatPar();
		int   GetShelf();
		void  GetNodes(Node** nodes);
		int   GetOnBed();
		void  Du(Vec du_g,double* u_g,double* u_g_obs,ParameterInputs* inputs,int analysis_type);
		void  Gradj(Vec grad_g,double* u_g,double* lambda_g,ParameterInputs* inputs,int analysis_type,char* control_type);
		void  GradjDrag(Vec grad_g,double* u_g,double* lambda_g,ParameterInputs* inputs,int analysis_type);
		void  GradjB(Vec grad_g,double* u_g,double* lambda_g,ParameterInputs* inputs,int analysis_type);
        double Misfit(double* u_g,double* u_g_obs,ParameterInputs* inputs,int analysis_type);
		
		void          GetThicknessList(double* thickness_list);
		void          GetBedList(double* bed_list);
		Object* copy();



};
#endif  /* _PENTA_H */
