/*!\file:  PetscVec.h
 * \brief wrapper to our own PetscVec object, which is needed to add AD capabilities (using ADOLC) 
 * to a C-coded Petsc API. We are just wrapping the Petsc objects into C++ equivalent, so that 
 * later, we can map all of the Petsc routines into Adolc equivalents.
 */ 

#ifndef _PETSCVEC_H_
#define _PETSCVEC_H_

/*Headers:*/
/*{{{*/
#ifdef HAVE_CONFIG_H
	#include <config.h>
#else
#error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
#endif

#include "../petscincludes.h"
#include "../../../include/include.h"

/*}}}*/

class PetscVec{

	public:
		Vec vector;

		#ifdef _HAVE_ADOLC_
		IssmDouble* avector;
		#endif

		/*PetscVec constructors, destructors*/
		PetscVec();
		PetscVec(int M,bool fromlocalsize=false);
		PetscVec(int m,int M);
		PetscVec(IssmDouble* buffer, int M);
		PetscVec(Vec petsc_vec);
		~PetscVec();

		/*PetscVec specific routines*/
		void Echo(void);
		void Assemble(void);
		void SetValues(int ssize, int* list, IssmDouble* values, InsMode mode);
		void SetValue(int dof, IssmDouble value, InsMode  mode);
		void GetValue(IssmDouble* pvalue, int dof);
		void GetSize(int* pM);
		void GetLocalSize(int* pM);
		PetscVec* Duplicate(void);
		void Set(IssmDouble value);
		void AXPY(PetscVec* X, IssmDouble a);
		void AYPX(PetscVec* X, IssmDouble a);
		IssmDouble* ToMPISerial(void);
		void Copy(PetscVec* to);
		IssmDouble Norm(NormMode norm_type);
		void Scale(IssmDouble scale_factor);
		void PointwiseDivide(PetscVec* x,PetscVec* y);
		IssmDouble Dot(PetscVec* vector);
};

#endif //#ifndef _PETSCVEC_H_
