diff --git a/Base/quicksort.h b/Base/quicksort.h
index 0650d485d43ba06777922311220462d1c333d710..78f69f558560b2bbd54d4b31e202508b929e9982 100644
--- a/Base/quicksort.h
+++ b/Base/quicksort.h
@@ -14,6 +14,36 @@
 // Base
 #include "swap.h"
 
+template <class T>
+void quickSort(T* array, unsigned beg, unsigned end)
+{
+  if (beg < end) {
+    unsigned p = partition_(array, beg, end);
+    quickSort(array, beg, p);
+    quickSort(array, p+1, end);
+  }
+}
+
+template <class T>
+unsigned partition_(T* array, unsigned beg, unsigned end)
+{
+  unsigned i = beg+1;
+  unsigned j = end-1;
+  T m = array[beg];
+
+  for (;;) {
+    while ((i<end) && (array[i] < m)) i++;
+    while ((j>beg) && !(array[j] < m)) j--;
+
+    if (i >= j) break;
+    BASELIB::swap(array[i], array[j]);
+  }
+
+  BASELIB::swap(array[beg], array[j]);
+  return j;
+}
+
+
 /**
  * version of partition_ that additional updates the permutation vector
  * */
diff --git a/MathLib/CMakeLists.txt b/MathLib/CMakeLists.txt
index 9dfbbeaeb47d70763f13318d993b46f7e695a25e..cc426573501a7564ecb86a9465baaecbe0c9ac64 100644
--- a/MathLib/CMakeLists.txt
+++ b/MathLib/CMakeLists.txt
@@ -1,49 +1,53 @@
 # Source files
-SET( HEADERS
-	AnalyticalGeometry.h        
-	LinearInterpolation.h  
-	MathTools.h
-	Vector3.h
-	EarClippingTriangulation.h  
-	max.h
-        sparse.h
-	vector_io.h
-	LinAlg/MatrixBase.h
-	LinAlg/VectorNorms.h
-	LinAlg/Dense/Matrix.h
-        LinAlg/Preconditioner/generateDiagPrecond.h
-        LinAlg/Solvers/LinearSolver.h
-        LinAlg/Solvers/DirectLinearSolver.h
-        LinAlg/Solvers/DenseDirectLinearSolver.h
-        LinAlg/Solvers/GaussAlgorithm.h
-        LinAlg/Solvers/TriangularSolve.h
-        LinAlg/Solvers/IterativeLinearSolver.h
-        LinAlg/Solvers/solver.h
-        LinAlg/Solvers/BiCGStab.h
-        LinAlg/Solvers/CG.h
-        LinAlg/Solvers/GMRes.h
-	LinAlg/Sparse/amuxCRS.h
-        LinAlg/Sparse/CRSMatrix.h
-        LinAlg/Sparse/CRSMatrixPThreads.h
-        LinAlg/Sparse/CRSMatrixOpenMP.h
-        LinAlg/Sparse/CRSSymMatrix.h
-        LinAlg/Sparse/SparseMatrixBase.h
-)
+#SET( HEADERS
+#	AnalyticalGeometry.h        
+#	LinearInterpolation.h  
+#	MathTools.h
+#	Vector3.h
+#	EarClippingTriangulation.h  
+#	max.h
+#       sparse.h
+#	vector_io.h
+#	LinAlg/MatrixBase.h
+#	LinAlg/VectorNorms.h
+#	LinAlg/Dense/Matrix.h
+#       LinAlg/Preconditioner/generateDiagPrecond.h
+#       LinAlg/Solvers/LinearSolver.h
+#       LinAlg/Solvers/DirectLinearSolver.h
+#       LinAlg/Solvers/DenseDirectLinearSolver.h
+#       LinAlg/Solvers/GaussAlgorithm.h
+#       LinAlg/Solvers/TriangularSolve.h
+#       LinAlg/Solvers/IterativeLinearSolver.h
+#       LinAlg/Solvers/solver.h
+#       LinAlg/Solvers/BiCGStab.h
+#       LinAlg/Solvers/CG.h
+#       LinAlg/Solvers/GMRes.h
+#	LinAlg/Sparse/amuxCRS.h
+#       LinAlg/Sparse/CRSMatrix.h
+#       LinAlg/Sparse/CRSMatrixPThreads.h
+#       LinAlg/Sparse/CRSMatrixOpenMP.h
+#       LinAlg/Sparse/CRSSymMatrix.h
+#       LinAlg/Sparse/SparseMatrixBase.h
+#)
 
-SET( SOURCES
-	AnalyticalGeometry.cpp        
-	LinearInterpolation.cpp  
-	MathTools.cpp
-	EarClippingTriangulation.cpp  
-        LinAlg/Sparse/amuxCRS.cpp
-        LinAlg/Solvers/BiCGStab.cpp
-        LinAlg/Solvers/CG.cpp
-        LinAlg/Solvers/CGParallel.cpp
-        LinAlg/Solvers/GMRes.cpp
-	LinAlg/Solvers/GaussAlgorithm.cpp
-        LinAlg/Solvers/TriangularSolve.cpp
-	LinAlg/Preconditioner/generateDiagPrecond.cpp
-)
+FILE(GLOB_RECURSE HEADERS . *.h)
+
+#SET( SOURCES
+#	AnalyticalGeometry.cpp        
+#	LinearInterpolation.cpp  
+#	MathTools.cpp
+#	EarClippingTriangulation.cpp  
+#       LinAlg/Sparse/amuxCRS.cpp
+#       LinAlg/Solvers/BiCGStab.cpp
+#       LinAlg/Solvers/CG.cpp
+#       LinAlg/Solvers/CGParallel.cpp
+#       LinAlg/Solvers/GMRes.cpp
+#	LinAlg/Solvers/GaussAlgorithm.cpp
+#       LinAlg/Solvers/TriangularSolve.cpp
+#	LinAlg/Preconditioner/generateDiagPrecond.cpp
+#)
+
+FILE(GLOB_RECURSE SOURCES . *.cpp)
 
 INCLUDE_DIRECTORIES (
 	.
diff --git a/MathLib/LinAlg/Sparse/NestedDissectionPermutation/AdjMat.cpp b/MathLib/LinAlg/Sparse/NestedDissectionPermutation/AdjMat.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9280eb5bdf118e0ad18946b11ec43b70566b0f5f
--- /dev/null
+++ b/MathLib/LinAlg/Sparse/NestedDissectionPermutation/AdjMat.cpp
@@ -0,0 +1,203 @@
+/*
+ * AdjMat.cpp
+ *
+ *  Created on: 02.01.2012
+ *      Author: TF
+ */
+
+// Base
+#include "swap.h"
+#include "quicksort.h"
+
+#include "LinAlg/Sparse/NestedDissectionPermutation/AdjMat.h"
+
+namespace MathLib {
+
+AdjMat* AdjMat::getMat(unsigned beg, unsigned end,
+		const unsigned* const op_perm, const unsigned* const po_perm) const
+{
+	const unsigned nsize(end - beg); // size of new matrix
+	unsigned i, c; // row and col idx in permuted matrix
+	unsigned j, idx; // pointer in jA
+	unsigned r; // row idx in original matrix
+
+	unsigned *iAn(new unsigned[nsize + 1]);
+	iAn[0] = 0;
+
+	unsigned *pos(new unsigned[nsize + 1]);
+	for (i = 0; i <= nsize; i++)
+		pos[i] = 0;
+
+	for (i = beg; i < end; i++) {
+		r = op_perm[i];
+		idx = _row_ptr[r + 1];
+		for (j = _row_ptr[r]; j < idx; j++) {
+			c = po_perm[_col_idx[j]];
+			if (beg <= c && c < end)
+				++pos[i - beg];
+		}
+	}
+	for (i = 0; i < nsize; i++)
+		iAn[i + 1] = iAn[i] + pos[i];
+	for (i = 0; i < nsize; i++)
+		pos[i] = iAn[i];
+
+	unsigned *jAn(new unsigned[iAn[nsize]]);
+	for (i = beg; i < end; i++) {
+		r = op_perm[i];
+		idx = _row_ptr[r + 1];
+		for (j = _row_ptr[r]; j < idx; j++) {
+			c = po_perm[_col_idx[j]];
+			if (beg <= c && c < end)
+				jAn[pos[i - beg]++] = c - beg;
+		}
+	}
+
+	delete[] pos;
+	for (i = 0; i < nsize; ++i)
+		quickSort(jAn, iAn[i], iAn[i + 1]);
+	return new AdjMat(nsize, iAn, jAn, NULL);
+}
+
+/**
+ * generate an adjacency matrix (the upper triangle part)
+ * @param n number of nodes of matrix graph / number of rows/columns of the adjacency matrix
+ * @param iA array of size of the number of rows/columns + 1, array contains pointer into jA array
+ * @param jA array of the length of the number of non-zero entries (edges in the matrix graph)
+ */
+void genAdjMat(unsigned n, unsigned* &iA, unsigned* &jA)
+{
+	unsigned i;
+	// count entries of each row
+	unsigned* iAn = new unsigned[n + 1];
+	for (i = 0; i <= n; ++i)
+		iAn[i] = 0;
+
+	// go through all strictly lower triangular entries (i,j) and check
+	// whether (j,i) exists in the upper triangular part
+
+	// set n pointers to the beginning of each row
+	unsigned* co = new unsigned[n];
+	for (i = 0; i < n; ++i)
+		co[i] = iA[i];
+
+	for (i = 0; i < n; ++i)
+		for (unsigned k = iA[i]; k < iA[i + 1]; ++k) {
+			unsigned j = jA[k];
+			if (i < j)
+				++iAn[i + 1]; // upper triangular entries count
+			else { // lower triangular only if there is no counter part
+				unsigned k1 = iA[j], k2 = iA[j + 1];
+				if (i < jA[k1] || i > jA[k2 - 1])
+					++iAn[j + 1]; // i is out of bounds
+				else { // go through all uninspected entries in the jth row
+					while (co[j] < k2 && i > jA[co[j]])
+						++co[j];
+					if (co[j] == k2 || i < jA[co[j]])
+						++iAn[j + 1];
+				}
+			}
+		}
+
+	// construct array iAn by summing up the contents of iAn
+	// con is a set of pointer refering to iAn
+	unsigned* con = new unsigned[n];
+	co[0] = con[0] = 0;
+	for (i = 1; i < n; ++i) {
+		co[i] = iA[i];
+		con[i] = iAn[i];
+		iAn[i + 1] += iAn[i];
+	}
+
+	unsigned *jAn = new unsigned[iAn[n]];
+	for (i = 1; i < n; ++i)
+		for (unsigned k = iA[i]; k < iA[i + 1]; ++k) {
+			unsigned j = jA[k];
+			// copy all transposed lower triangular entries and all upper
+			// triangular elements up to that position
+			if (j < i) {
+				while (co[j] < iA[j + 1] && i > jA[co[j]]) {
+					if (jA[co[j]] > j)
+						jAn[con[j]++] = jA[co[j]];
+					++co[j];
+				}
+
+				if (co[j] == iA[j + 1] || i <= jA[co[j]]) {
+					jAn[con[j]++] = i;
+					++co[i];
+					if (i == jA[co[j]])
+						++co[j];
+				}
+			}
+		}
+
+	// finish rows
+	for (i = 0; i < n; ++i)
+		for (unsigned k = co[i]; k < iA[i + 1]; ++k)
+			if (i < jA[k])
+				jAn[con[i]++] = jA[k];
+
+	BASELIB::swap(jA, jAn);
+	BASELIB::swap(iA, iAn);
+
+	delete[] jAn;
+	delete[] con;
+	delete[] co;
+	delete[] iAn;
+}
+
+void genFullAdjMat(unsigned n, unsigned* &iA, unsigned* &jA)
+{
+	unsigned i;
+	// count entries of each column
+	unsigned* cnt = new unsigned[n];
+	for (i = 0; i < n; ++i)
+		cnt[i] = 0;
+
+	for (i = 0; i < n; ++i) {
+		unsigned j = iA[i], idx = iA[i + 1];
+		while (j < idx) {
+			cnt[jA[j]]++;
+			j++;
+		}
+	}
+
+	// summing up entries
+	for (i = 2; i < n; ++i)
+		cnt[i] += cnt[i - 1];
+
+	unsigned* iAn = new unsigned[n + 1]; // VALGRIND meldet hier Fehler
+	iAn[0] = 0;
+	for (i = 1; i <= n; ++i)
+		iAn[i] = iA[i] + cnt[i - 1];
+
+	unsigned *jAn = new unsigned[iAn[n]];
+	for (unsigned k = 0; k < n; k++)
+		cnt[k] = iAn[k];
+
+	for (i = 0; i < n; ++i) {
+		unsigned j = iA[i], idx = iA[i + 1];
+		while (j < idx) {
+			jAn[cnt[i]++] = jA[j];
+			jAn[cnt[jA[j]]++] = i;
+			j++;
+		}
+	}
+
+	BASELIB::swap(jA, jAn);
+	BASELIB::swap(iA, iAn);
+
+	delete[] jAn;
+	delete[] iAn;
+	delete[] cnt;
+}
+
+void AdjMat::makeSymmetric()
+{
+	// store upper triangular mat values
+	genAdjMat(MatrixBase::_n_rows, _row_ptr, _col_idx);
+	// mirror the upper triangular part into lower
+	genFullAdjMat(MatrixBase::_n_rows, _row_ptr, _col_idx);
+}
+
+} // end namespace MathLib
diff --git a/MathLib/LinAlg/Sparse/NestedDissectionPermutation/AdjMat.h b/MathLib/LinAlg/Sparse/NestedDissectionPermutation/AdjMat.h
new file mode 100644
index 0000000000000000000000000000000000000000..91c8ad7c56bba097e01fe234449341d810bca084
--- /dev/null
+++ b/MathLib/LinAlg/Sparse/NestedDissectionPermutation/AdjMat.h
@@ -0,0 +1,76 @@
+/*
+ * AdjMat.h
+ *
+ *  Created on: 02.01.2012
+ *      Author: TF
+ */
+
+#ifndef ADJMAT_H_
+#define ADJMAT_H_
+
+#include "LinAlg/Sparse/CRSMatrix.h"
+
+namespace MathLib {
+
+/** AdjMat implements an adjacency matrix used to represent the (possible
+   weighted) edges of a graph. Due to adjacency matrix are mostly sparse
+   the implementation makes use of compressed row storage format.
+*/
+class AdjMat: public CRSMatrix<unsigned, unsigned>
+{
+public:
+	/** constructor with data elements in A
+	 * @param s size of the quadratic matrix
+	 * @param iA array of length s+1 which holds pointers in jA,
+	 * iA[k] points to the first non-zero column-entry of row k,
+	 * iA[k]-1 points accordingly to the last non-zero column-entry of row k,
+	 * the last entry of iA (iA[s]) takes the number of non zero entries(nnz)
+	 * @param jA array of length nnz, each entry is a colum-index
+	 * @param A  data-array of length nnz of type unsigned (weights)
+	 */
+	AdjMat(unsigned s, unsigned *iA, unsigned *jA, unsigned *A = NULL) :
+		CRSMatrix<unsigned, unsigned> (s, iA, jA, A)
+	{}
+
+	/**
+	 * destructor
+	 */
+	virtual ~AdjMat()
+	{}
+
+	/**
+	 * The
+	 */
+	void makeSymmetric();
+
+	/** getMat returns the (possibly reducible) block [beg,end-1] x [beg,end-1]
+	 * respecting the permutation.
+	 * @param beg index of first row/column, it is supposed that 0 <= beg <= n
+	 * @param end index one after last row/column, it is supposed that beg <= end <= n
+	 * @param op_perm permutation -> original
+	 * @param po_perm original -> permutation
+	 * @return pointer to an AdjMat object
+	 */
+	AdjMat* getMat(unsigned beg, unsigned end, unsigned const* const op_perm,
+			unsigned const* const po_perm) const;
+
+private:
+	/**
+	 * copy constructor
+	 * @param src another AdjMat with data for initializiation
+	 */
+	AdjMat(const AdjMat&);
+
+	/**
+	 * assignment operator
+	 * @param rhs a instance of AdjacencyCRSMatrix
+	 */
+	AdjMat& operator=(AdjMat&)
+	{
+		return *this;
+	}
+};
+
+}
+
+#endif /* ADJMAT_H_ */
diff --git a/MathLib/LinAlg/Sparse/NestedDissectionPermutation/Cluster.cpp b/MathLib/LinAlg/Sparse/NestedDissectionPermutation/Cluster.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..dadbb3920e1a13c44967a81d09896f24920de1ad
--- /dev/null
+++ b/MathLib/LinAlg/Sparse/NestedDissectionPermutation/Cluster.cpp
@@ -0,0 +1,174 @@
+/*
+ * Cluster.cpp
+ *
+ *  Created on: 02.01.2012
+ *      Author: TF
+ */
+
+// BaseLib
+#include "swap.h"
+
+#include "LinAlg/Sparse/NestedDissectionPermutation/Cluster.h"
+//#include "blas.h"
+#include "Cluster.h"
+#include "Separator.h"
+#include "AdjMat.h"
+
+
+namespace MathLib {
+
+// METIS function
+extern "C" void METIS_NodeComputeSeparator(unsigned*, unsigned*, unsigned*,
+					   unsigned*, unsigned*, unsigned*,
+					   unsigned*, unsigned*);
+
+Cluster::Cluster (unsigned n, unsigned* iA, unsigned* jA)
+  : ClusterBase (n, iA, jA)
+{}
+
+
+Cluster::Cluster(ClusterBase* father, unsigned beg, unsigned end,
+                         unsigned* op_perm, unsigned* po_perm,
+                         AdjMat* global_mat, AdjMat* local_mat)
+  : ClusterBase(father, beg, end, op_perm, po_perm, global_mat, local_mat)
+{}
+
+void Cluster::subdivide(unsigned bmin)
+{
+	const unsigned size(_end - _beg);
+	if (size > bmin) {
+
+		unsigned n_rows(_l_adj_mat->getNRows());
+		unsigned *xadj(const_cast<unsigned*>(_l_adj_mat->getRowPtrArray()));
+		unsigned *adjncy(const_cast<unsigned*>(_l_adj_mat->getColIdxArray()));
+//		unsigned nparts = 2;
+		unsigned options = 0; // for METIS
+		unsigned sepsize(0); // for METIS
+		unsigned *vwgt(new unsigned[n_rows + 1]);
+		const unsigned nnz(xadj[n_rows]);
+		unsigned *adjwgt(new unsigned[nnz]);
+		for (unsigned k(0); k < n_rows + 1; k++)
+			vwgt[k] = 1;
+		for (unsigned k(0); k < nnz; k++)
+			adjwgt[k] = 1;
+		unsigned *part(new unsigned[n_rows + 1]);
+
+		// subdivide the index set into three parts employing METIS
+		METIS_NodeComputeSeparator(&n_rows, xadj, adjncy, vwgt, adjwgt, &options,
+				&sepsize, part);
+
+		// create and init local permutations
+		unsigned *l_op_perm(new unsigned[size]);
+		unsigned *l_po_perm(new unsigned[size]);
+		for (unsigned i = 0; i < size; ++i)
+			l_op_perm[i] = l_po_perm[i] = i;
+
+		unsigned isep1, isep2;
+		updatePerm(part, isep1, isep2, l_op_perm, l_po_perm);
+		delete[] part;
+
+		// update global permutation
+		unsigned *t_op_perm = new unsigned[size];
+		for (unsigned k = 0; k < size; ++k)
+			t_op_perm[k] = _g_op_perm[_beg + l_op_perm[k]];
+
+		for (unsigned k = _beg; k < _end; ++k) {
+			_g_op_perm[k] = t_op_perm[k - _beg];
+			_g_po_perm[_g_op_perm[k]] = k;
+		}
+		delete[] t_op_perm;
+
+		// next recursion step
+		if ((isep1 >= bmin) && (isep2 - isep1 >= bmin)) {
+			// construct adj matrices for [0, isep1), [isep1,isep2), [isep2, _end)
+			AdjMat *l_adj0(_l_adj_mat->getMat(0, isep1, l_op_perm, l_po_perm));
+			AdjMat *l_adj1(_l_adj_mat->getMat(isep1, isep2, l_op_perm, l_po_perm));
+			AdjMat *l_adj2(_l_adj_mat->getMat(isep2, size, l_op_perm, l_po_perm));
+
+			delete[] l_op_perm;
+			delete[] l_po_perm;
+			delete _l_adj_mat;
+			_l_adj_mat = NULL;
+
+			_n_sons = 3;
+			_sons = new ClusterBase*[_n_sons];
+
+			isep1 += _beg;
+			isep2 += _beg;
+
+			// constructing child nodes for index cluster tree
+			_sons[0] = new Cluster(this, _beg, isep1, _g_op_perm, _g_po_perm, _g_adj_mat, l_adj0);
+			_sons[1] = new Cluster(this, isep1, isep2, _g_op_perm, _g_po_perm, _g_adj_mat, l_adj1);
+			_sons[2] = new Separator(this, isep2, _end, _g_op_perm,	_g_po_perm, _g_adj_mat, l_adj2);
+
+			dynamic_cast<Cluster*>(_sons[0])->subdivide(bmin);
+			dynamic_cast<Cluster*>(_sons[1])->subdivide(bmin);
+
+		} else {
+			delete _l_adj_mat;
+			_l_adj_mat = NULL;
+		} // end if next recursion step
+	} // end if ( connected && size () > bmin )
+}
+
+
+void Cluster::updatePerm(unsigned* reordering, unsigned &isep0,
+		unsigned &isep1, unsigned* l_op_perm, unsigned* l_po_perm)
+{
+	unsigned beg = 0, end = _end - _beg;
+	while (beg < end) {
+		if (reordering[beg] >= 1) {
+			--end;
+			while (beg < end && reordering[end] >= 1)
+				--end;
+			// local permutation
+			BASELIB::swap(l_op_perm[beg], l_op_perm[end]);
+			BASELIB::swap(l_po_perm[l_op_perm[beg]], l_po_perm[l_op_perm[end]]);
+			BASELIB::swap(reordering[beg], reordering[end]);
+		}
+		++beg;
+	}
+	if (beg > end)
+		isep0 = beg - 1;
+	else
+		isep0 = end;
+
+	beg = isep0, end = _end - _beg;
+	while (beg < end) {
+		if (reordering[beg] == 2) {
+			--end;
+			while (beg < end && reordering[end] == 2)
+				--end;
+			// local permutation
+			BASELIB::swap(l_op_perm[beg], l_op_perm[end]);
+			BASELIB::swap(l_po_perm[l_op_perm[beg]], l_po_perm[l_op_perm[end]]);
+			BASELIB::swap(reordering[beg], reordering[end]);
+		}
+		++beg;
+	}
+	if (beg > end)
+		isep1 = beg - 1;
+	else
+		isep1 = end;
+}
+
+
+void Cluster::createClusterTree(unsigned* op_perm, unsigned* po_perm,
+		unsigned bmin)
+{
+	_g_op_perm = op_perm;
+	_g_po_perm = po_perm;
+
+	// *** 1 create local problem
+	unsigned n = _g_adj_mat->getNRows();
+	unsigned *l_op_perm = new unsigned[n];
+	unsigned *l_po_perm = new unsigned[n];
+	for (unsigned k = 0; k < n; ++k)
+		l_op_perm[k] = l_po_perm[k] = k;
+	_l_adj_mat = _l_adj_mat->getMat(0, n, l_op_perm, l_po_perm);
+
+	// *** 2 create cluster tree
+	subdivide(bmin);
+}
+
+} // end namespace MathLib
diff --git a/MathLib/LinAlg/Sparse/NestedDissectionPermutation/Cluster.h b/MathLib/LinAlg/Sparse/NestedDissectionPermutation/Cluster.h
new file mode 100644
index 0000000000000000000000000000000000000000..1ee767c2b454e4e8dba4afad2e43c589cc068eb5
--- /dev/null
+++ b/MathLib/LinAlg/Sparse/NestedDissectionPermutation/Cluster.h
@@ -0,0 +1,79 @@
+/*
+ * Cluster.h
+ *
+ *  Created on: 02.01.2012
+ *      Author: TF
+ */
+
+#ifndef CLUSTER_H_
+#define CLUSTER_H_
+
+#include "ClusterBase.h"
+
+namespace MathLib {
+
+/** \brief class for storing clusters of degrees of freedom without
+    geometric information. This class stores clusters (not separators).
+*/
+
+class Cluster: public ClusterBase
+{
+public:
+	/**
+	 * Constructor creates the root of the cluster tree
+	 * @param n
+	 * @param jA
+	 * @param iA
+	 * @return
+	 */
+	Cluster(unsigned n, unsigned* iA, unsigned* jA);
+
+	virtual void subdivide(unsigned bmin);
+
+	/** Method returns the status of this ClusterBase object. In this case
+	 * instances of this class are "normal" Clusters.
+	 * @return false
+	 */
+	virtual bool isSeparator() const
+	{
+		return false;
+	}
+
+	/** Destructor. */
+	virtual ~Cluster() {}
+
+	/**
+	 * Method creates recursively the cluster tree, i.e. changes the permutation
+	 * op_perm and po_perm and create child cluster trees. For this task only the
+	 * adjacency matrix is used.
+	 * @param op_perm permutation: original_idx = op_perm[permutated_idx]
+	 * @param po_perm reverse permutation: permutated_idx = po_perm[original_idx]
+	 * @param bmin threshold value for stopping further refinement
+	 * @return a cluster tree
+	 */
+	virtual void createClusterTree(unsigned* op_perm, unsigned* po_perm,
+			unsigned bmin = 50);
+
+protected:
+	/** \brief Constructor
+	 \param father parent node in cluster tree
+	 \param beg beginning index of the cluster
+	 \param end beginning index of the next cluster
+	 \param op_perm permutation
+	 \param po_perm permutation
+	 \param global_mat reference to adjacency matrix of the matrix graph in
+	 crs format
+	 \param local_mat pointer to the local adjacency matrix of the matrix
+	 graph in crs format
+	 */
+	Cluster(ClusterBase* father, unsigned beg, unsigned end, unsigned* op_perm,
+			unsigned* po_perm, AdjMat* global_mat, AdjMat* local_mat);
+
+private:
+	/** update perm */
+	void updatePerm(unsigned* reordering, unsigned &isep0, unsigned &isep1, unsigned* l_op_perm, unsigned* l_po_perm);
+};
+
+} // end namespace MathLib
+
+#endif /* CLUSTER_H_ */
diff --git a/MathLib/LinAlg/Sparse/NestedDissectionPermutation/ClusterBase.cpp b/MathLib/LinAlg/Sparse/NestedDissectionPermutation/ClusterBase.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..215672da6d6f443b4f3717ea0065fadaef71ff64
--- /dev/null
+++ b/MathLib/LinAlg/Sparse/NestedDissectionPermutation/ClusterBase.cpp
@@ -0,0 +1,48 @@
+/*
+ * ClusterBase.cpp
+ *
+ *  Created on: 02.01.2012
+ *      Author: TF
+ */
+
+//#include "blas.h"
+#include "AdjMat.h"
+#include "LinAlg/Sparse/NestedDissectionPermutation/ClusterBase.h"
+
+namespace MathLib {
+
+ClusterBase::ClusterBase(unsigned n, unsigned const* const iA,
+		unsigned const*const jA) :
+	_beg(0), _end(n), _n_sons(0), _sons(NULL), _parent(NULL), _g_op_perm(NULL),
+	_g_po_perm(NULL), _l_adj_mat(NULL)
+{
+	const unsigned nnz = iA[n];
+
+	// create adjacency matrix
+	unsigned *row_ptr = new unsigned[n + 1];
+	for (unsigned k = 0; k <= n; ++k)
+		row_ptr[k] = iA[k];
+	unsigned *col_idx = new unsigned[nnz];
+	for (unsigned k = 0; k < nnz; ++k)
+		col_idx[k] = jA[k];
+
+	_l_adj_mat = new AdjMat(n, row_ptr, col_idx);
+	_l_adj_mat->makeSymmetric();
+}
+
+ClusterBase::ClusterBase(ClusterBase *father, unsigned beg, unsigned end,
+		unsigned* op_perm, unsigned* po_perm, AdjMat* global_mat, AdjMat* local_mat) :
+	_beg(beg), _end(end), _n_sons(0), _sons(NULL), _parent(father),
+	_g_op_perm(op_perm), _g_po_perm(po_perm), _g_adj_mat(global_mat),
+	_l_adj_mat(local_mat)
+{
+}
+
+ClusterBase::~ClusterBase()
+{
+	if (_parent == NULL)
+		delete _g_adj_mat;
+	delete _l_adj_mat;
+}
+
+} // end namespace MathLib
diff --git a/MathLib/LinAlg/Sparse/NestedDissectionPermutation/ClusterBase.h b/MathLib/LinAlg/Sparse/NestedDissectionPermutation/ClusterBase.h
new file mode 100644
index 0000000000000000000000000000000000000000..291df29ab15faa4e8cc9c843403d0589d2aa656b
--- /dev/null
+++ b/MathLib/LinAlg/Sparse/NestedDissectionPermutation/ClusterBase.h
@@ -0,0 +1,102 @@
+/*
+ * ClusterBase.h
+ *
+ *  Created on: 02.01.2012
+ *      Author: TF
+ */
+
+#ifndef CLUSTERBASE_H_
+#define CLUSTERBASE_H_
+
+namespace MathLib {
+
+class AdjMat;
+
+/** \brief Base class for storing clusters of degrees of freedom without
+ geometric information.
+ */
+class ClusterBase
+{
+public:
+	/**
+	 * Constructor creates the root of the cluster tree
+	 * @param n number of rows/columns
+	 * @param iA row pointer array
+	 * @param jA column index array
+	 * @return
+	 */
+	ClusterBase(unsigned n, unsigned const*const iA, unsigned const*const jA);
+	/*!
+	 \brief Constructor
+	 \param father parent node in cluster tree
+	 \param beg beginning index of the cluster
+	 \param end beginning index of the next cluster
+	 \param op_perm global permutation array (original_idx = op_perm[permuted_idx])
+	 \param po_perm global permutation array (permuted_idx = po_perm[original_idx])
+	 \param global_mat reference to the global adjacency matrix of the matrix graph in crs format
+	 \param local_mat pointer to the local adjacency matrix of the matrix graph in crs format
+	 */
+	ClusterBase(ClusterBase* father, unsigned beg, unsigned end,
+			unsigned* op_perm, unsigned* po_perm, AdjMat* global_mat, AdjMat* local_mat);
+
+	/** \brief Destructor.
+	 * Destructor frees all form the objects allocated memory.
+	 * */
+	virtual ~ClusterBase();
+
+	virtual bool isSeparator() const = 0;
+
+protected:
+	/** \brief Method returns the pointer to the parent cluster.
+	 \returns parent cluster */
+	ClusterBase* getParent() const
+	{
+		return _parent;
+	}
+	/**
+	 * beginning index in the global permutation arrays
+	 */
+	const unsigned _beg;
+
+	/**
+	 * beginning index of next next cluster in the global permutation arrays
+	 */
+	const unsigned _end;
+
+	/**
+	 * number of sons, _n_sons==0 iff this is a leaf
+	 */
+	unsigned _n_sons;
+
+	/**
+	 * the array of sons of this cluster in the cluster tree
+	 */
+	ClusterBase** _sons;
+
+	/**
+	 * pointer to parent
+	 */
+	ClusterBase *_parent;
+	/**
+	 * pointer global permutation array (original_idx = op_perm[permuted_idx])
+	 */
+	unsigned* _g_op_perm;
+	/**
+	 * global permutation: permutation <- po_perm <- original
+	 */
+	unsigned* _g_po_perm;
+	/**
+	 * pointer to global adjacency matrix
+	 * The attribute _g_adj_mat stores the set of edges of the matrix graph $G = (V,E)$.
+	 * (see class AdjMat)
+	 */
+	AdjMat* _g_adj_mat;
+	/**
+	 * local adjacency matrix
+	 */
+	AdjMat* _l_adj_mat;
+};
+
+} // end namespace MathLib
+
+#endif /* CLUSTERBASE_H_ */
diff --git a/MathLib/LinAlg/Sparse/NestedDissectionPermutation/Separator.cpp b/MathLib/LinAlg/Sparse/NestedDissectionPermutation/Separator.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7d7d211ab0b67f51cc7cb7d6763d0e6e8db18998
--- /dev/null
+++ b/MathLib/LinAlg/Sparse/NestedDissectionPermutation/Separator.cpp
@@ -0,0 +1,45 @@
+/*
+ * Separator.cpp
+ *
+ *  Created on: 02.01.2012
+ *      Author: TF
+ */
+
+// BaseLib
+#include "swap.h"
+
+#include "LinAlg/Sparse/NestedDissectionPermutation/Separator.h"
+
+namespace MathLib {
+
+extern "C" void METIS_PartGraphRecursive(unsigned*, unsigned*, unsigned*,
+					 unsigned*, unsigned*, unsigned*,
+					 unsigned*, unsigned*, unsigned*,
+					 unsigned*, unsigned*);
+
+Separator::Separator(ClusterBase* father, unsigned beg, unsigned end,
+                     unsigned* op_perm, unsigned* po_perm,
+                     AdjMat* global_mat, AdjMat* local_mat)
+  : ClusterBase (father, beg, end, op_perm, po_perm, global_mat, local_mat)
+{}
+
+Separator::~Separator()
+{}
+
+unsigned Separator::updatePerm(unsigned* reordering, unsigned* l_op_perm, unsigned* l_po_perm)
+{
+  unsigned beg = 0, end = _end-_beg;
+  while (beg < end) {
+    if (reordering[beg] == 1) {
+      --end;
+      while (beg < end && reordering[end] == 1) --end;
+      // local permutation
+      BASELIB::swap(l_op_perm [beg], l_op_perm[end]);
+      BASELIB::swap(l_po_perm[l_op_perm [beg]], l_po_perm[l_op_perm[end]]);
+    }
+    ++beg;
+  }
+  return ((beg>end) ? beg-1 : end);
+}
+
+} // end namespace MathLib
diff --git a/MathLib/LinAlg/Sparse/NestedDissectionPermutation/Separator.h b/MathLib/LinAlg/Sparse/NestedDissectionPermutation/Separator.h
new file mode 100644
index 0000000000000000000000000000000000000000..a90ba000139b037cb21646eb461d06b685ce963e
--- /dev/null
+++ b/MathLib/LinAlg/Sparse/NestedDissectionPermutation/Separator.h
@@ -0,0 +1,57 @@
+/*
+ * Separator.h
+ *
+ *  Created on: 02.01.2012
+ *      Author: TF
+ */
+
+#ifndef SEPARATOR_H_
+#define SEPARATOR_H_
+
+#include "LinAlg/Sparse/NestedDissectionPermutation/ClusterBase.h"
+
+namespace MathLib {
+
+class Cluster;
+class AdjMat;
+
+/** \brief class for storing clusters of degrees of freedom without
+ geometric information.
+*/
+class Separator: public ClusterBase
+{
+public:
+	/** brief Constructor builds a initial object for clustering
+	 \param father pointer to the father node in cluster tree
+	 \param beg index in op_perm and po_perm which describes the begin of the index set of the Separator
+	 \param end index in op_perm and po_perm which describes the begin of the index set of the next
+	 ClusterBase
+	 \param op_perm permutation
+	 \param po_perm inverse permutation
+	 \param global_mat reference to adjacency matrix of the matrix graph in crs format
+	 \param local_mat reference to the local adjacency matrix of the matrix graph in crs format
+	 */
+	Separator(ClusterBase* father, unsigned beg, unsigned end,
+			unsigned* op_perm, unsigned* po_perm, AdjMat* global_mat,
+			AdjMat* local_mat);
+
+	/** Destructor. */
+	virtual ~Separator();
+
+	/** Method returns the status of this ClusterAlg object. Instances
+	 of this class are Separators.
+	 \returns true
+	 */
+	virtual bool isSeparator() const
+	{
+		return true;
+	}
+
+private:
+	/** update perm */
+	unsigned updatePerm(unsigned *reordering, unsigned* l_op_perm, unsigned* l_po_perm);
+};
+
+} // end namespace MathLib
+
+#endif /* SEPARATOR_H_ */
diff --git a/MathLib/LinAlg/Sparse/SparseMatrixBase.h b/MathLib/LinAlg/Sparse/SparseMatrixBase.h
index 57f16b088b65e7b79f9086aa6e9c6b901489eee6..6607f9d8ec9589a36f2dfb0da07b96021a7a7856 100644
--- a/MathLib/LinAlg/Sparse/SparseMatrixBase.h
+++ b/MathLib/LinAlg/Sparse/SparseMatrixBase.h
@@ -10,7 +10,13 @@ template<typename FP_TYPE, typename IDX_TYPE> class SparseMatrixBase : public Ma
 public:
 	SparseMatrixBase(IDX_TYPE n1, IDX_TYPE n2) : MatrixBase (n1,n2) {}
 	SparseMatrixBase() : MatrixBase () {}
-	virtual void amux(FP_TYPE d, FP_TYPE const * const __restrict__ x, FP_TYPE * __restrict__ y) const = 0;         // y +=d*Ax
+	/**
+	 * y = d * A * x
+	 * @param d scalar factor
+	 * @param x vector to multiply with
+	 * @param y result vector
+	 */
+	virtual void amux(FP_TYPE d, FP_TYPE const * const __restrict__ x, FP_TYPE * __restrict__ y) const = 0;
 	virtual ~SparseMatrixBase() {};
 };