/*! \file Tria.h 
 *  \brief: header file for tria object
 */

#ifndef _TRIA_H
#define _TRIA_H

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

class Tria: public Element{

	private: 

		/*ids:*/
		int id;

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

		/*materials: */
		int   mid;
		Matice* matice; 
		int   matice_offset;
		
		int mparid;
		Matpar* matpar; 
		int   matpar_offset;
	
		double h[3];
		double s[3];
		double b[3];
		double k[3];
		int    friction_type;
		double p;
		double q;
		int    shelf;
		double fit;
		double meanvel;/*!scaling ratio for velocities*/
		double epsvel; /*!minimum velocity to avoid infinite velocity ratios*/
		int    acceleration;
		int    onbed;
	
	public:

		Tria();
		Tria(int id,int mid,int mparid,int node_ids[3],double h[3],double s[3],double b[3],double k[3],
				int friction_type,double p,double q,int shelf,double fit,double meanvel,double epsvel,int acceleration);
		~Tria();

		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);
		void  GetDofList(int* doflist,int* pnumberofdofs);
		
		void  CreateKMatrixDiagnosticHoriz(Mat Kgg,ParameterInputs* inputs,int analysis_type);
		void  GetParameterValue(double* pp, double* plist, double* gauss_l1l2l3);
		void  GetParameterDerivativeValue(double* p, double* plist,double* xyz_list, double* gauss_l1l2l3);
		void  GetStrainRate(double* epsilon, double* velocity, double* xyz_list, double* gauss_l1l2l3);
		void  GetJacobianDeterminant(double*  Jdet, double* xyz_list,double* gauss_l1l2l3);
		void  GetB(double* B, double* xyz_list, double* gauss_l1l2l3);
		void  GetBPrime(double* Bprime, double* xyz_list, double* gauss_l1l2l3);
		void  GetL(double* L, double* xyz_list, double* gauss_l1l2l3,int numdof);
		void  GetNodalFunctions(double* l1l2l3, double* gauss_l1l2l3);
		void  GetNodalFunctionsDerivativesBasic(double* dh1dh2dh3_basic,double* xyz_list, double* gauss_l1l2l3);
		void  GetNodalFunctionsDerivativesParams(double* dl1dl2dl3,double* gauss_l1l2l3);
		void  GetJacobianInvert(double*  Jinv, double* xyz_list,double* gauss_l1l2l3);
		void  GetJacobian(double* J, double* xyz_list,double* gauss_l1l2l3);
		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  CreatePVectorDiagnosticHoriz(Vec pg,ParameterInputs* inputs,int analysis_type);
		Matpar* GetMatPar();
		int   GetShelf();
		void  GetNodes(Node** nodes);
		int   GetOnBed();

		void          GetThicknessList(double* thickness_list);
		void          GetBedList(double* bed_list);
		Object* copy();


};
#endif  /* _TRIA_H */

