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

#ifndef _MATRIX_H_
#define _MATRIX_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;

/*}}}*/

class Matrix{

	public:
	
		#ifdef _HAVE_PETSC_
		Mat matrix; 
		#else
		SeqMat* matrix; 
		#endif
		#ifdef _HAVE_ADOLC_
		IssmDouble* amatrix;
		#endif

		/*Matrix constructors, destructors {{{*/
		Matrix();
		Matrix(int M,int N);
		Matrix(int M,int N,IssmDouble sparsity);
		Matrix(IssmDouble* serial_mat,int M,int N,IssmDouble sparsity);
		Matrix(int M,int N,int connectivity,int numberofdofspernode);
		~Matrix();
		/*}}}*/
		/*Matrix specific routines {{{*/
		void Echo(void);
		void Assemble(void);
		IssmDouble Norm(NormMode norm_type);
		void GetSize(int* pM,int* pN);
		void GetLocalSize(int* pM,int* pN);
		void MatMult(Vector* X,Vector* AX);
		Matrix* Duplicate(void);
		IssmDouble* ToSerial(void);
		void SetValues(int m,int* idxm,int n,int* idxn,IssmDouble* values,InsMode mode);
		void Convert(MatrixType type);
		/*}}}*/

};

#endif //#ifndef _MATRIX_H_
