diff --git a/MeshLib/MeshSubset.h b/MeshLib/MeshSubset.h
index 6323599928fbb07ff50b609b6a1e2072cd1dd301..49f7291d718cf0c6fe56692178eb2e118cc475ec 100644
--- a/MeshLib/MeshSubset.h
+++ b/MeshLib/MeshSubset.h
@@ -125,6 +125,12 @@ public:
         return _msh.getElements().cend();
     }
 
+    std::vector<Node*> const& getNodes() const
+    {
+        assert(_nodes);
+        return *_nodes;
+    }
+
     /// Constructs a new mesh subset which is a set intersection of the current
     /// nodes and the provided vector of nodes.
     /// An empty mesh subset may be returned, not a nullptr, in case of empty
diff --git a/NumLib/DOF/LocalToGlobalIndexMap.cpp b/NumLib/DOF/LocalToGlobalIndexMap.cpp
index aed289d168388ef050ed63b2acef9b032778d6e0..6dcfd18a79f6b64b0c31a32d948d45afdf220132 100644
--- a/NumLib/DOF/LocalToGlobalIndexMap.cpp
+++ b/NumLib/DOF/LocalToGlobalIndexMap.cpp
@@ -16,6 +16,7 @@ template <typename ElementIterator>
 void
 LocalToGlobalIndexMap::findGlobalIndices(
     ElementIterator first, ElementIterator last,
+    std::vector<MeshLib::Node*> const& nodes,
     std::size_t const mesh_id,
     const unsigned comp_id, const unsigned comp_id_write)
 {
@@ -26,16 +27,16 @@ LocalToGlobalIndexMap::findGlobalIndices(
     std::size_t elem_id = 0;
     for (ElementIterator e = first; e != last; ++e, ++elem_id)
     {
-        std::size_t const nnodes = (*e)->getNumberOfNodes();
-
         LineIndex indices;
-        indices.reserve(nnodes);
 
-        for (unsigned n = 0; n < nnodes; n++)
+        for (auto* n = (*e)->getNodes(); n < (*e)->getNodes()+(*e)->getNumberOfNodes(); ++n)
         {
+            // Check if the element's node is in the given list of nodes.
+            if (std::find(std::begin(nodes), std::end(nodes), *n) == std::end(nodes))
+                continue;
             MeshLib::Location l(mesh_id,
                                 MeshLib::MeshItemType::Node,
-                                (*e)->getNode(n)->getID());
+                                (*n)->getID());
             indices.push_back(_mesh_component_map.getGlobalIndex(l, comp_id));
         }
 
@@ -70,8 +71,8 @@ LocalToGlobalIndexMap::LocalToGlobalIndexMap(
             auto const global_component_id =
                 getGlobalComponent(variable_id, component_id);
 
-            findGlobalIndices(ms.elementsBegin(), ms.elementsEnd(), mesh_id,
-                              global_component_id, global_component_id);
+            findGlobalIndices(ms.elementsBegin(), ms.elementsEnd(), ms.getNodes(),
+                              mesh_id, global_component_id, global_component_id);
         }
 
         // increase by number of components of that variable
@@ -98,7 +99,7 @@ LocalToGlobalIndexMap::LocalToGlobalIndexMap(
     {
         std::size_t const mesh_id = ms->getMeshID();
 
-        findGlobalIndices(elements.cbegin(), elements.cend(), mesh_id,
+        findGlobalIndices(elements.cbegin(), elements.cend(), ms->getNodes(), mesh_id,
                           component_id, 0);  // There is only one component to
                                              // write out, therefore the zero
                                              // parameter.
diff --git a/NumLib/DOF/LocalToGlobalIndexMap.h b/NumLib/DOF/LocalToGlobalIndexMap.h
index 6fab44ea25fd646b114cca7b4085082bbb193ab1..2b71d267357190beb5d4e6380e5bfac9929c17d1 100644
--- a/NumLib/DOF/LocalToGlobalIndexMap.h
+++ b/NumLib/DOF/LocalToGlobalIndexMap.h
@@ -130,6 +130,7 @@ private:
     template <typename ElementIterator>
     void
     findGlobalIndices(ElementIterator first, ElementIterator last,
+        std::vector<MeshLib::Node*> const& nodes,
         std::size_t const mesh_id,
         const unsigned component_id, const unsigned comp_id_write);
 
diff --git a/ProcessLib/BoundaryCondition/BoundaryCondition.cpp b/ProcessLib/BoundaryCondition/BoundaryCondition.cpp
index 4365f48f8328824344c95310da63293da6755fa7..270433a5725e896e8ded14746dc265291edfbf13 100644
--- a/ProcessLib/BoundaryCondition/BoundaryCondition.cpp
+++ b/ProcessLib/BoundaryCondition/BoundaryCondition.cpp
@@ -56,6 +56,26 @@ std::unique_ptr<BoundaryCondition> createBoundaryCondition(
         // is defined.
         std::vector<std::size_t> ids =
             mesh_node_searcher.getMeshNodeIDs(config.geometry);
+        // Filter out ids, which are not part of mesh subsets corresponding to
+        // the variable_id and component_id.
+        auto const& mesh_subsets =
+            dof_table.getMeshSubsets(variable_id, config.component_id);
+        auto ids_new_end_iterator = std::end(ids);
+        for (auto const& mesh_subset : mesh_subsets)
+        {
+            auto const& nodes = mesh_subset->getNodes();
+            ids_new_end_iterator = std::remove_if(std::begin(ids), ids_new_end_iterator,
+                    [&nodes](std::size_t const node_id)
+                    {
+                        return std::end(nodes) == std::find_if(
+                                std::begin(nodes), std::end(nodes),
+                                    [&node_id](MeshLib::Node* const node)
+                                    {
+                                        return node->getID() == node_id;
+                                    });
+                    });
+        }
+        ids.erase(ids_new_end_iterator, std::end(ids));
 
         return createDirichletBoundaryCondition(
             config.config, std::move(ids), dof_table, mesh.getID(), variable_id,
diff --git a/ProcessLib/Process.cpp b/ProcessLib/Process.cpp
index 407b6e12fb2f4415df17de06cdf9dd55f0eec4b0..9feda0c3284979bb8c5123fa92db36d330fbe516 100644
--- a/ProcessLib/Process.cpp
+++ b/ProcessLib/Process.cpp
@@ -60,7 +60,6 @@ void Process::initialize()
 void Process::setInitialConditions(double const t, GlobalVector& x)
 {
     DBUG("Set initial conditions.");
-    std::size_t const n_nodes = _mesh.getNumberOfNodes();
 
     SpatialPosition pos;
 
@@ -73,31 +72,38 @@ void Process::setInitialConditions(double const t, GlobalVector& x)
 
         auto const num_comp = pv.getNumberOfComponents();
 
-        for (std::size_t node_id = 0; node_id < n_nodes; ++node_id)
+        for (int component_id = 0; component_id < num_comp; ++component_id)
         {
-            MeshLib::Location const l(_mesh.getID(),
-                                      MeshLib::MeshItemType::Node, node_id);
-
-            pos.setNodeID(node_id);
-            auto const& ic_value = ic(t, pos);
-
-            for (int comp_id = 0; comp_id < num_comp; ++comp_id)
+            auto const& mesh_subsets =
+                _local_to_global_index_map->getMeshSubsets(variable_id,
+                                                           component_id);
+            for (auto const& mesh_subset : mesh_subsets)
             {
-                auto global_index =
-                    std::abs(_local_to_global_index_map->getGlobalIndex(
-                        l, variable_id, comp_id));
+                auto const mesh_id = mesh_subset->getMeshID();
+                for (auto const* node : mesh_subset->getNodes())
+                {
+                    MeshLib::Location const l(
+                        mesh_id, MeshLib::MeshItemType::Node, node->getID());
+
+                    pos.setNodeID(node->getID());
+                    auto const& ic_value = ic(t, pos);
+
+                    auto global_index =
+                        std::abs(_local_to_global_index_map->getGlobalIndex(
+                            l, variable_id, component_id));
 #ifdef USE_PETSC
-                // The global indices of the ghost entries of the global matrix
-                // or the global vectors need to be set as negative values for
-                // equation assembly, however the global indices start from
-                // zero. Therefore, any ghost entry with zero index is assigned
-                // an negative value of the vector size or the matrix dimension.
-                // To assign the initial value for the ghost entries, the
-                // negative indices of the ghost entries are restored to zero.
-                if (global_index == x.size())
-                    global_index = 0;
+                    // The global indices of the ghost entries of the global matrix
+                    // or the global vectors need to be set as negative values for
+                    // equation assembly, however the global indices start from
+                    // zero. Therefore, any ghost entry with zero index is assigned
+                    // an negative value of the vector size or the matrix dimension.
+                    // To assign the initial value for the ghost entries, the
+                    // negative indices of the ghost entries are restored to zero.
+                    if (global_index == x.size())
+                        global_index = 0;
 #endif
-                x.set(global_index, ic_value[comp_id]);
+                    x.set(global_index, ic_value[component_id]);
+                }
             }
         }
     }
diff --git a/ProcessLib/ProcessOutput.cpp b/ProcessLib/ProcessOutput.cpp
index f57906d55806ae39537fccc2dcbba194eb6296b9..0bac1d2701bea3abd2c252b3b593e95a630a1e96 100644
--- a/ProcessLib/ProcessOutput.cpp
+++ b/ProcessLib/ProcessOutput.cpp
@@ -67,13 +67,15 @@ void doProcessOutput(
     auto const& output_variables = process_output.output_variables;
     std::set<std::string> already_output;
 
-    std::size_t const n_nodes = mesh.getNumberOfNodes();
     int global_component_offset = 0;
     int global_component_offset_next = 0;
 
     // primary variables
-    for (ProcessVariable& pv : process_variables)
+    for (int variable_id = 0;
+         variable_id < static_cast<int>(process_variables.size());
+         ++variable_id)
     {
+        ProcessVariable& pv = process_variables[variable_id];
         int const n_components = pv.getNumberOfComponents();
         global_component_offset = global_component_offset_next;
         global_component_offset_next += n_components;
@@ -87,22 +89,30 @@ void doProcessOutput(
 
         auto& output_data = pv.getOrCreateMeshProperty();
 
-        for (std::size_t node_id = 0; node_id < n_nodes; ++node_id)
+        auto const num_comp = pv.getNumberOfComponents();
+
+        for (int component_id = 0; component_id < num_comp; ++component_id)
         {
-            MeshLib::Location const l(mesh.getID(),
-                                      MeshLib::MeshItemType::Node, node_id);
-            // TODO extend component ids to multiple process variables.
-            for (int component_id = 0; component_id < n_components;
-                 ++component_id)
+            auto const& mesh_subsets =
+                dof_table.getMeshSubsets(variable_id,
+                                                           component_id);
+            for (auto const& mesh_subset : mesh_subsets)
             {
+                auto const mesh_id = mesh_subset->getMeshID();
+                for (auto const* node : mesh_subset->getNodes())
+                {
+                    MeshLib::Location const l(
+                        mesh_id, MeshLib::MeshItemType::Node, node->getID());
+
                 auto const global_component_id = global_component_offset + component_id;
                 auto const index =
                         dof_table.getLocalIndex(
                             l, global_component_id, x.getRangeBegin(),
                             x.getRangeEnd());
 
-                output_data[node_id * n_components + component_id] =
+                output_data[node->getID() * n_components + component_id] =
                         x_copy[index];
+                }
             }
         }
     }