diff --git a/MathLib/LinAlg/Lis/LisMatrix.cpp b/MathLib/LinAlg/Lis/LisMatrix.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2e88de19d1606682c20c43c148f12e91ca482405
--- /dev/null
+++ b/MathLib/LinAlg/Lis/LisMatrix.cpp
@@ -0,0 +1,70 @@
+/**
+ * \file
+ * \author Norihiro Watanabe
+ * \date   2013-04-16
+ * \brief  Implementation of the LisMatrix class.
+ *
+ * \copyright
+ * Copyright (c) 2013, OpenGeoSys Community (http://www.opengeosys.org)
+ *            Distributed under a Modified BSD License.
+ *              See accompanying file LICENSE.txt or
+ *              http://www.opengeosys.org/project/license
+ *
+ */
+
+#include "LisMatrix.h"
+
+#include "LisVector.h"
+#include "LisCheck.h"
+
+namespace MathLib
+{
+
+LisMatrix::LisMatrix(std::size_t dimension, LisOption::MatrixType mat_type)
+: _n_rows(dimension), _max_diag_coeff(.0), _mat_type(mat_type)
+{
+    int ierr = 0;
+    ierr = lis_matrix_create(0, &_AA); checkLisError(ierr);
+    ierr = lis_matrix_set_size(_AA, 0, dimension); checkLisError(ierr);
+    lis_matrix_get_range(_AA, &_is, &_ie);
+}
+
+LisMatrix::~LisMatrix()
+{
+    int ierr = 0;
+    ierr = lis_matrix_destroy(_AA); checkLisError(ierr);
+}
+
+void LisMatrix::setZero()
+{
+    int ierr = 0;
+    // A matrix has to be destroyed and created again because Lis doesn't provide a
+    // function to set matrix entries to zero
+    ierr = lis_matrix_destroy(_AA); checkLisError(ierr);
+    ierr = lis_matrix_create(0, &_AA); checkLisError(ierr);
+    ierr = lis_matrix_set_size(_AA, 0, _n_rows); checkLisError(ierr);
+
+    _max_diag_coeff = .0;
+}
+
+void LisMatrix::write(const std::string &filename) const
+{
+    lis_output_matrix(_AA, LIS_FMT_MM, const_cast<char*>(filename.c_str()));
+}
+
+void LisMatrix::matvec (const LisVector &x, LisVector &y) const
+{
+    int ierr = lis_matvec(_AA, const_cast<LisVector*>(&x)->getRawVector(), y.getRawVector()); checkLisError(ierr);
+}
+
+bool finalizeMatrixAssembly(LisMatrix &mat)
+{
+    if (!lis_matrix_is_assembled(mat.getRawMatrix())) {
+        int ierr = lis_matrix_set_type(mat.getRawMatrix(), static_cast<int>(mat.getMatrixType())); checkLisError(ierr);
+        ierr = lis_matrix_assemble(mat.getRawMatrix()); checkLisError(ierr);
+    }
+    return true;
+};
+
+
+} //MathLib
diff --git a/MathLib/LinAlg/Lis/LisMatrix.h b/MathLib/LinAlg/Lis/LisMatrix.h
new file mode 100644
index 0000000000000000000000000000000000000000..a0592c13077e911e0f75bb03a5287284e66467aa
--- /dev/null
+++ b/MathLib/LinAlg/Lis/LisMatrix.h
@@ -0,0 +1,139 @@
+/**
+ * \file
+ * \author Norihiro Watanabe
+ * \date   2013-04-16
+ * \brief  Definition of the LisMatrix class.
+ *
+ * \copyright
+ * Copyright (c) 2013, OpenGeoSys Community (http://www.opengeosys.org)
+ *            Distributed under a Modified BSD License.
+ *              See accompanying file LICENSE.txt or
+ *              http://www.opengeosys.org/project/license
+ *
+ */
+
+#ifndef LISMATRIX_H_
+#define LISMATRIX_H_
+
+#include <iostream>
+#include <cmath>
+#include <vector>
+
+#include "lis.h"
+
+#include "LisOption.h"
+
+namespace MathLib
+{
+class LisVector;
+
+/**
+ * \brief Lis matrix wrapper class
+ *
+ * Lis matrix only supports a regular matrix, i.e. the number of
+ * rows should equal to the number of columns.
+ */
+class LisMatrix
+{
+public:
+    /**
+     * constructor
+     * @param length
+     * @param mat_type default 1 CRS
+     */
+    LisMatrix(std::size_t length, LisOption::MatrixType mat_type = LisOption::MatrixType::CRS);
+
+    /**
+     *
+     */
+    virtual ~LisMatrix();
+
+    /// return the number of rows
+    std::size_t getNRows() const { return _n_rows; };
+
+    /// return the number of columns
+    std::size_t getNCols() const { return getNRows(); };
+
+    /// return a start index of the active data range
+    std::size_t getRangeBegin() const { return _is; }
+
+    /// return an end index of the active data range
+    std::size_t getRangeEnd() const { return _ie; }
+
+    /// reset this matrix with keeping its original dimension
+    void setZero();
+
+    /// set entry
+    int setValue(std::size_t rowId, std::size_t colId, double v)
+    {
+        if (rowId==colId)
+            _max_diag_coeff = std::max(_max_diag_coeff, std::abs(v));
+        lis_matrix_set_value(LIS_INS_VALUE, rowId, colId, v, _AA);
+        return 0;
+    }
+
+    /// add value
+    int addValue(std::size_t rowId, std::size_t colId, double v)
+    {
+        if (rowId==colId)
+            _max_diag_coeff = std::max(_max_diag_coeff, std::abs(v));
+        lis_matrix_set_value(LIS_ADD_VALUE, rowId, colId, v, _AA);
+        return 0;
+    }
+
+    /// printout this equation for debugging
+    void write(const std::string &filename) const;
+
+    /// get a maximum value in diagonal entries
+    double getMaxDiagCoeff() const { return _max_diag_coeff; };
+
+    /// return a raw Lis matrix object
+    LIS_MATRIX& getRawMatrix() { return _AA; };
+
+    /// y = mat * x
+    void matvec ( const LisVector &x, LisVector &y) const;
+
+    ///
+    template <class T_DENSE_MATRIX>
+    void addSubMatrix(std::vector<std::size_t> const& row_pos,
+            std::vector<std::size_t> const& col_pos, const T_DENSE_MATRIX &sub_matrix,
+            double fkt = 1.0);
+
+    /// get this matrix type
+    LisOption::MatrixType getMatrixType() const { return _mat_type; };
+
+private:
+    std::size_t _n_rows;
+    double _max_diag_coeff;
+    LisOption::MatrixType _mat_type;
+    LIS_MATRIX _AA;
+    int _is;
+    int _ie;
+};
+
+template<class T_DENSE_MATRIX>
+void
+LisMatrix::addSubMatrix(std::vector<std::size_t> const& row_pos, std::vector<std::size_t> const& col_pos,
+        const T_DENSE_MATRIX &sub_matrix, double fkt)
+{
+    if (row_pos.size() != sub_matrix.getNRows() || col_pos.size() != sub_matrix.getNCols())
+        return;
+
+    const std::size_t n_rows = row_pos.size();
+    const std::size_t n_cols = col_pos.size();
+    for (std::size_t i = 0; i < n_rows; i++) {
+        const std::size_t row = row_pos[i];
+        for (std::size_t j = 0; j < n_cols; j++) {
+            const std::size_t col = col_pos[j];
+            addValue(row, col, fkt * sub_matrix(i, j));
+        }
+    }
+};
+
+/// finish assembly to make this matrix be ready for use
+bool finalizeMatrixAssembly(LisMatrix &mat);
+
+} // MathLib
+
+#endif //LISMATRIX_H_
+