From 5e9466dcdbcbe8093f50d4974691f18f0719161b Mon Sep 17 00:00:00 2001
From: Pietro Incardona <i-bird@private-incardon-3.mpi-cbg.de>
Date: Thu, 2 Jun 2016 16:33:09 +0200
Subject: [PATCH] Adding missing files

---
 m4/ax_petsc_lib.m4                |   4 +-
 src/Matrix/SparseMatrix_petsc.hpp | 314 ++++++++++++++++++++++++++++++
 2 files changed, 316 insertions(+), 2 deletions(-)
 create mode 100644 src/Matrix/SparseMatrix_petsc.hpp

diff --git a/m4/ax_petsc_lib.m4 b/m4/ax_petsc_lib.m4
index 1213bf30..ed14c831 100755
--- a/m4/ax_petsc_lib.m4
+++ b/m4/ax_petsc_lib.m4
@@ -102,8 +102,8 @@ AC_DEFUN([AX_LIB_PETSC], [
                         old_CC=$CC
                         old_CFLAGS=$CFLAGS
                         old_LDFLAGS=$LDFLAGS
-                        CFLAGS="-I$with_petsc/include"
-                        LDFLAGS="-L$with_petsc/lib "
+                        CFLAGS="-I$with_petsc/include $HDF5_INCLUDE $METIS_INCLUDE "
+                        LDFLAGS="-L$with_petsc/lib $HDF5_LDFLAGS  $HDF5_LIBS $METIS_LIB -lmetis "
 			CC=$CXX
 
                         AC_LANG_SAVE
diff --git a/src/Matrix/SparseMatrix_petsc.hpp b/src/Matrix/SparseMatrix_petsc.hpp
new file mode 100644
index 00000000..2df1c56b
--- /dev/null
+++ b/src/Matrix/SparseMatrix_petsc.hpp
@@ -0,0 +1,314 @@
+/*
+ * SparseMatrix_petsc.hpp
+ *
+ *  Created on: Apr 26, 2016
+ *      Author: i-bird
+ */
+
+#ifndef OPENFPM_NUMERICS_SRC_MATRIX_SPARSEMATRIX_PETSC_HPP_
+#define OPENFPM_NUMERICS_SRC_MATRIX_SPARSEMATRIX_PETSC_HPP_
+
+
+#include "Vector/map_vector.hpp"
+#include <boost/mpl/int.hpp>
+#include <petscmat.h>
+
+#define PETSC_BASE 2
+
+/*! \brief It store one non-zero element in the sparse matrix
+ *
+ * Given a row, and a column, store a value
+ *
+ *
+ */
+template<typename T>
+class triplet<T,PETSC_BASE>
+{
+	PetscInt row_;
+	PetscInt col_;
+	PetscScalar val_;
+
+public:
+
+	PetscInt & row()
+	{
+		return row_;
+	}
+
+	PetscInt & col()
+	{
+		return col_;
+	}
+
+	PetscScalar & value()
+	{
+		return val_;
+	}
+
+	/*! \brief Constructor from row, colum and value
+	 *
+	 * \param i row
+	 * \param j colum
+	 * \param val value
+	 *
+	 */
+	triplet(long int i, long int j, T val)
+	{
+		row_ = i;
+		col_ = j;
+		val_ = val;
+	}
+
+	// Default constructor
+	triplet()	{};
+};
+
+/* ! \brief Sparse Matrix implementation, that map over Eigen
+ *
+ * \tparam T Type of the sparse Matrix store on each row,colums
+ * \tparam id_t type of id
+ * \tparam impl implementation
+ *
+ */
+template<typename T, typename id_t>
+class SparseMatrix<T,id_t, PETSC_BASE>
+{
+public:
+
+	//! Triplet implementation id
+	typedef boost::mpl::int_<PETSC_BASE> triplet_impl;
+
+	//! Triplet type
+	typedef triplet<T,PETSC_BASE> triplet_type;
+
+private:
+
+	// Size of the matrix
+	size_t g_row;
+	size_t g_col;
+
+	// Local size of the matrix
+	size_t l_row;
+	size_t l_col;
+
+	// starting row for this processor
+	size_t start_row;
+
+	// PETSC Matrix
+	Mat mat;
+	openfpm::vector<triplet_type> trpl;
+	openfpm::vector<triplet_type> trpl_recv;
+
+	// temporary list of values
+	mutable openfpm::vector<PetscScalar> vals;
+	// temporary list of colums
+	mutable openfpm::vector<PetscInt> cols;
+	// PETSC d_nnz and o_nnz
+	mutable openfpm::vector<PetscInt> d_nnz;
+	mutable openfpm::vector<PetscInt> o_nnz;
+
+	/*! \brief Fill the petsc Matrix
+	 *
+	 *
+	 */
+	void fill_petsc()
+	{
+		d_nnz.resize(l_row);
+		o_nnz.resize(l_row);
+
+		d_nnz.fill(0);
+		o_nnz.fill(0);
+
+		// Here we explore every row to count how many non zero we have in the diagonal matrix part,
+		// and the non diagonal matrix part, needed by MatMPIAIJSetPreallocation
+
+		size_t i = 0;
+
+		// Set the Matrix from triplet
+		while (i < trpl.size())
+		{
+			PetscInt row = trpl.get(i).row();
+
+			while(row == trpl.get(i).row() && i < trpl.size())
+			{
+				if ((size_t)trpl.get(i).col() >= start_row && (size_t)trpl.get(i).col() < start_row + l_row)
+					d_nnz.get(row - start_row)++;
+				else
+					o_nnz.get(row - start_row)++;
+				i++;
+			}
+		}
+
+		PETSC_SAFE_CALL(MatMPIAIJSetPreallocation(mat,0,static_cast<const PetscInt*>(d_nnz.getPointer()),0,
+														static_cast<const PetscInt*>(o_nnz.getPointer())));
+
+		// Counter i is zero
+		i = 0;
+
+		// Set the Matrix from triplet
+		while (i < trpl.size())
+		{
+			vals.clear();
+			cols.clear();
+
+			PetscInt row = trpl.get(i).row();
+
+			while(row == trpl.get(i).row() && i < trpl.size())
+			{
+				vals.add(trpl.get(i).value());
+				cols.add(trpl.get(i).col());
+				i++;
+			}
+			PETSC_SAFE_CALL(MatSetValues(mat,1,&row,cols.size(),static_cast<const PetscInt*>(cols.getPointer()),
+					                                            static_cast<const PetscScalar *>(vals.getPointer()),
+					                                            INSERT_VALUES));
+		}
+
+		PETSC_SAFE_CALL(MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY));
+		PETSC_SAFE_CALL(MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY));
+	}
+
+
+public:
+
+	/*! \brief Create an empty Matrix
+	 *
+	 * \param N1 number of row
+	 * \param N2 number of colums
+	 * \param N1_loc number of local row
+	 *
+	 */
+	SparseMatrix(size_t N1, size_t N2, size_t n_row_local)
+	:l_row(n_row_local),l_col(n_row_local)
+	{
+		PETSC_SAFE_CALL(MatCreate(PETSC_COMM_WORLD,&mat));
+		PETSC_SAFE_CALL(MatSetType(mat,MATMPIAIJ));
+		PETSC_SAFE_CALL(MatSetSizes(mat,n_row_local,n_row_local,N1,N2));
+
+		Vcluster & v_cl = create_vcluster();
+
+		openfpm::vector<size_t> vn_row_local;
+		v_cl.allGather(l_row,vn_row_local);
+		v_cl.execute();
+
+		// Calculate the starting row for this processor
+
+		start_row = 0;
+		for (size_t i = 0 ; i < v_cl.getProcessUnitID() ; i++)
+			start_row += vn_row_local.get(i);
+	}
+
+	/*! \brief Create an empty Matrix
+	 *
+	 */
+	SparseMatrix()
+	{
+		PETSC_SAFE_CALL(MatCreate(PETSC_COMM_WORLD,&mat));
+		PETSC_SAFE_CALL(MatSetType(mat,MATMPIAIJ));
+	}
+
+	/*! \brief Get the Matrix triplets bugger
+	 *
+	 * It return a buffer that can be filled with triplets
+	 *
+	 * \return Petsc Matrix
+	 *
+	 */
+	openfpm::vector<triplet_type> & getMatrixTriplets()
+	{
+		return this->trpl;
+	}
+
+	/*! \brief Get the Patsc Matrix object
+	 *
+	 * \return the Eigen Matrix
+	 *
+	 */
+	const Mat & getMat() const
+	{
+		fill_petsc();
+
+		return mat;
+	}
+
+	/*! \brief Get the Petsc Matrix object
+	 *
+	 * \return the Petsc Matrix
+	 *
+	 */
+	Mat & getMat()
+	{
+		fill_petsc();
+
+		return mat;
+	}
+
+	/*! \brief Resize the Sparse Matrix
+	 *
+	 * \param row number for row
+	 * \param col number of colums
+	 * \param local number of row
+	 * \param local number of colums
+	 *
+	 */
+	void resize(size_t row, size_t col, size_t l_row, size_t l_col)
+	{
+		this->g_row = row;
+		this->g_col = col;
+
+		this->l_row = l_row;
+		this->l_col = l_col;
+
+		PETSC_SAFE_CALL(MatSetSizes(mat,l_row,l_col,g_row,g_col));
+
+		Vcluster & v_cl = create_vcluster();
+
+		openfpm::vector<size_t> vn_row_local;
+		v_cl.allGather(l_row,vn_row_local);
+		v_cl.execute();
+
+		// Calculate the starting row for this processor
+
+		start_row = 0;
+		for (size_t i = 0 ; i < v_cl.getProcessUnitID() ; i++)
+			start_row += vn_row_local.get(i);
+	}
+
+	/*! \brief Get the row i and the colum j of the Matrix
+	 *
+	 * \warning it is slow, consider to get blocks of the matrix
+	 *
+	 * \return the value of the matrix at row i colum j
+	 *
+	 */
+	T operator()(id_t i, id_t j)
+	{
+		T v;
+
+		MatGetValues(mat,1,&i,1,&j,&v);
+
+		return v;
+	}
+
+	/*! \brief Get the value from triplet
+	 *
+	 * \warning It is extremly slow because it do a full search across the triplets elements
+	 *
+	 * \param r row
+	 * \param c colum
+	 *
+	 */
+	T getValue(size_t r, size_t c)
+	{
+		for (size_t i = 0 ; i < trpl.size() ; i++)
+		{
+			if (r == (size_t)trpl.get(i).row() && c == (size_t)trpl.get(i).col())
+				return trpl.get(i).value();
+		}
+
+		return 0;
+	}
+};
+
+
+#endif /* OPENFPM_NUMERICS_SRC_MATRIX_SPARSEMATRIX_PETSC_HPP_ */
-- 
GitLab