/*!\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"

/*}}}*/

class Vector{

	public:
	
		#ifdef _HAVE_PETSC_
			Vec vector; 
		#else
			SeqVec* vector;
		#endif
		#ifdef _HAVE_ADOLC_
			IssmDouble* avector;
		#endif

		/*Vector constructors, destructors {{{*/
		Vector();
		Vector(int M,bool fromlocalsize=false);
		Vector(IssmDouble* serial_vec,int pM);
		#ifdef _HAVE_PETSC_
		Vector(Vec petsc_vec);
		#endif
		#if defined(_HAVE_GSL_) && !defined(_HAVE_PETSC_)
		Vector(SeqVec*  seq_vec);
		#endif
		~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_
