/*!\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;
enum matrixtype{PetscMatType, SeqMatType};

class Matrix{

	public:

		#ifdef _HAVE_PETSC_
		PetscMat *pmatrix;
		#endif
		SeqMat   *smatrix;
		int       type;

		/*Matrix constructors, destructors {{{*/
		Matrix();
		Matrix(int M,int N,int type=PetscMatType);
		Matrix(int M,int N,IssmDouble sparsity,int type=PetscMatType);
		Matrix(IssmDouble* serial_mat,int M,int N,IssmDouble sparsity,int type=PetscMatType);
		Matrix(int M,int N,int connectivity,int numberofdofspernode,int type=PetscMatType);
		~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 newtype);
		/*}}}*/
};

#endif //#ifndef _MATRIX_H_
