diff --git a/AssemblerLib/ComputeSparsityPattern.cpp b/AssemblerLib/ComputeSparsityPattern.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c45c3b3231666c54b80f642e8f81e5d3b26240f4
--- /dev/null
+++ b/AssemblerLib/ComputeSparsityPattern.cpp
@@ -0,0 +1,57 @@
+/**
+ * \copyright
+ * Copyright (c) 2012-2015, 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 "MeshLib/NodeAdjacencyTable.h"
+#include "LocalToGlobalIndexMap.h"
+
+#include "ComputeSparsityPattern.h"
+
+namespace AssemblerLib
+{
+
+SparsityPattern
+computeSparsityPattern(LocalToGlobalIndexMap const& dof_table,
+        MeshLib::Mesh const& mesh
+        )
+{
+    MeshLib::NodeAdjacencyTable node_adjacency_table;
+    node_adjacency_table.createTable(mesh.getNodes());
+
+    // A mapping   mesh node id -> global indices
+    // It acts as a cache for dof table queries.
+    std::vector<std::vector<GlobalIndexType> > global_idcs;
+
+    global_idcs.reserve(mesh.getNNodes());
+    for (std::size_t n=0; n<mesh.getNNodes(); ++n)
+    {
+        MeshLib::Location l(mesh.getID(), MeshLib::MeshItemType::Node, n);
+        global_idcs.push_back(dof_table.getGlobalIndices(l));
+    }
+
+    SparsityPattern sparsity_pattern(dof_table.dofSize());
+
+    // Map adjacent mesh nodes to "adjacent global indices".
+    for (std::size_t n=0; n<mesh.getNNodes(); ++n)
+    {
+        auto const& node_ids = node_adjacency_table.getAdjacentNodes(n);
+        for (auto an : node_ids) {
+            auto const& row_ids = global_idcs[an];
+            auto const num_components = row_ids.size();
+            for (auto r : row_ids) {
+                // Each component leads to an entry in the row.
+                // For the sparsity pattern only the number of entries are needed.
+                sparsity_pattern[r] += num_components;
+            }
+        }
+    }
+
+    return sparsity_pattern;
+}
+
+}
diff --git a/AssemblerLib/ComputeSparsityPattern.h b/AssemblerLib/ComputeSparsityPattern.h
new file mode 100644
index 0000000000000000000000000000000000000000..766e2c05568624f20bf1545c3dee8d0104e0e24d
--- /dev/null
+++ b/AssemblerLib/ComputeSparsityPattern.h
@@ -0,0 +1,41 @@
+/**
+ * \copyright
+ * Copyright (c) 2012-2015, 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 ASSEMBLERLIB_COMPUTESPARSITYPATTERN_H
+#define ASSEMBLERLIB_COMPUTESPARSITYPATTERN_H
+
+#include <vector>
+
+#include "ProcessLib/NumericsConfig.h"
+
+namespace AssemblerLib
+{
+
+class LocalToGlobalIndexMap;
+
+/// A vector telling how many nonzeros there are in each global matrix row.
+using SparsityPattern = std::vector<GlobalIndexType>;
+
+/**
+ * @brief Computes a sparsity pattern for the given inputs.
+ *
+ * @param dof_table            maps mesh nodes to global indices
+ * @param mesh                 mesh for which the two parameters above are defined
+ *
+ * @return The computed sparsity pattern.
+ */
+SparsityPattern
+computeSparsityPattern(
+        LocalToGlobalIndexMap const& dof_table,
+        MeshLib::Mesh const& mesh
+        );
+}
+
+#endif // ASSEMBLERLIB_COMPUTESPARSITYPATTERN_H
+
diff --git a/AssemblerLib/LocalToGlobalIndexMap.h b/AssemblerLib/LocalToGlobalIndexMap.h
index 4b21e4612038b650ec48a465b7c8ab0018a05e52..ccac55bf7242cc4df6b1e40a05090fef1f7a9985 100644
--- a/AssemblerLib/LocalToGlobalIndexMap.h
+++ b/AssemblerLib/LocalToGlobalIndexMap.h
@@ -88,6 +88,12 @@ public:
         return _mesh_component_map.getGlobalIndex(l, c);
     }
 
+    /// Forwards the respective method from MeshComponentMap.
+    std::vector<GlobalIndexType> getGlobalIndices(const MeshLib::Location &l) const
+    {
+        return _mesh_component_map.getGlobalIndices(l);
+    }
+
 private:
     /// Private constructor used by internally created local-to-global index
     /// maps. The mesh_component_map is passed as argument instead of being
diff --git a/MathLib/LinAlg/Eigen/EigenMatrix.h b/MathLib/LinAlg/Eigen/EigenMatrix.h
index 44e15aff2d1604572bff397e5ee5845fbd5656f9..24396601ebcab395705d619484b8c6a9d2119de6 100644
--- a/MathLib/LinAlg/Eigen/EigenMatrix.h
+++ b/MathLib/LinAlg/Eigen/EigenMatrix.h
@@ -197,13 +197,10 @@ void operator()(EigenMatrix &matrix, SPARSITY_PATTERN const& sparsity_pattern)
     static_assert(EigenMatrix::RawMatrixType::IsRowMajor,
                   "Set matrix sparsity relies on the EigenMatrix to be in "
                   "row-major storage order.");
-    auto const n_rows = matrix.getNRows();
-    Eigen::VectorXi row_sizes(n_rows);
 
-    for (auto i = decltype(n_rows){0}; i < n_rows; i++)
-        row_sizes[i] = sparsity_pattern.getNodeDegree(i);
+    assert(matrix.getNRows() == sparsity_pattern.size());
 
-    matrix.getRawMatrix().reserve(row_sizes);
+    matrix.getRawMatrix().reserve(sparsity_pattern);
 }
 };
 
diff --git a/MathLib/LinAlg/Lis/LisMatrix.h b/MathLib/LinAlg/Lis/LisMatrix.h
index 1756accbde367ad0ce5d07c490cf7a5b934f5c2e..63257364956eb4cff86c250b5b440f82f6148e76 100644
--- a/MathLib/LinAlg/Lis/LisMatrix.h
+++ b/MathLib/LinAlg/Lis/LisMatrix.h
@@ -185,8 +185,7 @@ void operator()(LisMatrix &matrix, SPARSITY_PATTERN const& sparsity_pattern)
     row_sizes.reserve(n_rows);
 
     // LIS needs 1 more entry, otherewise it starts reallocating arrays.
-    for (auto i = decltype(n_rows){0}; i < n_rows; i++)
-        row_sizes.push_back(sparsity_pattern.getNodeDegree(i) + 1);
+    for (auto i : sparsity_pattern) row_sizes.push_back(i+1);
 
     int ierr = lis_matrix_malloc(matrix._AA, 0, row_sizes.data());
     checkLisError(ierr);
diff --git a/MeshLib/NodeAdjacencyTable.h b/MeshLib/NodeAdjacencyTable.h
index f10da9af1a2ade97e756f8509c29d4ce355359b2..e54d4dddaacb394b98ebf0a9c74193530178f368 100644
--- a/MeshLib/NodeAdjacencyTable.h
+++ b/MeshLib/NodeAdjacencyTable.h
@@ -54,6 +54,11 @@ public:
         return _data[node_id].size();
     }
 
+    std::vector<std::size_t> const& getAdjacentNodes(std::size_t const node_id) const
+    {
+        return _data[node_id];
+    }
+
     void createTable(std::vector<Node*> const& nodes)
     {
         if (_data.size() != nodes.size())
diff --git a/ProcessLib/GroundwaterFlowProcess.h b/ProcessLib/GroundwaterFlowProcess.h
index 39623c1b88c78a2a994c53e9e861c12345a1f09b..99a5026f47e1fab044f7a90c81a1065405ba64db 100644
--- a/ProcessLib/GroundwaterFlowProcess.h
+++ b/ProcessLib/GroundwaterFlowProcess.h
@@ -28,6 +28,7 @@
 #include "AssemblerLib/VectorMatrixAssembler.h"
 #include "AssemblerLib/LocalDataInitializer.h"
 #include "AssemblerLib/LocalToGlobalIndexMap.h"
+#include "AssemblerLib/ComputeSparsityPattern.h"
 
 #include "FileIO/VtkIO/VtuInterface.h"
 
@@ -36,7 +37,6 @@
 
 #include "MeshLib/MeshSubset.h"
 #include "MeshLib/MeshSubsets.h"
-#include "MeshLib/NodeAdjacencyTable.h"
 #include "MeshGeoToolsLib/MeshNodeSearcher.h"
 
 #include "UniformDirichletBoundaryCondition.h"
@@ -53,7 +53,7 @@ namespace MeshLib
     class Element;
     class Mesh;
     template <typename PROP_VAL_TYPE> class PropertyVector;
-};
+}
 
 namespace ProcessLib
 {
@@ -238,7 +238,9 @@ public:
         _A.reset(_global_setup.createMatrix(num_unknowns, mat_opt));
 #else
         DBUG("Compute sparsity pattern");
-        _node_adjacency_table.createTable(_mesh.getNodes());
+        _sparsity_pattern = std::move(
+            AssemblerLib::computeSparsityPattern(
+                *_local_to_global_index_map, _mesh));
 
         DBUG("Allocate global matrix, vectors, and linear solver.");
         const std::size_t num_unknowns = _local_to_global_index_map->dofSize();
@@ -282,7 +284,7 @@ public:
         DBUG("Solve GroundwaterFlowProcess.");
 
         _A->setZero();
-        MathLib::setMatrixSparsity(*_A, _node_adjacency_table);
+        MathLib::setMatrixSparsity(*_A, _sparsity_pattern);
         *_rhs = 0;   // This resets the whole vector.
 
         // Call global assembler for each local assembly item.
@@ -430,7 +432,7 @@ private:
 
     std::vector<NeumannBc<GlobalSetup>*> _neumann_bcs;
 
-    MeshLib::NodeAdjacencyTable _node_adjacency_table;
+    AssemblerLib::SparsityPattern _sparsity_pattern;
 };
 
 }   // namespace ProcessLib