/*!\file:  Vector.h
 * \brief wrapper to vector objects. The goal is to control which API (PETSc,Scalpack, Plapack?) 
 * implements our underlying vector format.
 */ 

#ifndef _VECTOR_H_
#define _VECTOR_H_

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

/*}}}*/

enum vectortype { PetscVecType, SeqVecType };

class Vector{

	public:

		#ifdef _HAVE_PETSC_
		PetscVec* pvector;
		#endif
		SeqVec* svector; 
		int     type;
	

		/*Vector constructors, destructors {{{*/
		Vector();
		Vector(int M,bool fromlocalsize=false,int type=PetscVecType);
		Vector(IssmDouble* serial_vec,int pM,int type=PetscVecType);
		~Vector();
		/*}}}*/
		/*Vector specific routines {{{*/
		void    Echo(void);
		void    AXPY(Vector *X, IssmDouble a);
		void    AYPX(Vector *X, IssmDouble a);
		void    Assemble(void);
		void    Copy(Vector *to);
		IssmDouble  Dot(Vector *vector);
		Vector *Duplicate(void);
		void    GetValue(IssmDouble *pvalue, int dof);
		void    GetSize(int *pM);
		void    GetLocalSize(int *pM);
		bool    IsEmpty(void);
		IssmDouble  Norm(NormMode norm_type);
		void    PointwiseDivide(Vector  *x,Vector*y);
		void    Scale(IssmDouble scale_factor);
		void    Set(IssmDouble value);
		void    SetValues(int ssize, int *list, IssmDouble*values, InsMode mode);
		void    SetValue(int dof, IssmDouble value, InsMode mode);
		IssmDouble *ToMPISerial(void);
		/*}}}*/
};


#endif //#ifndef _VECTOR_H_
