diff --git a/ProcessLib/CreateTimeLoop.cpp b/ProcessLib/CreateTimeLoop.cpp
index 1a7b6923fc79e1908646a95cacde1cbf5b1fe596..0b22415787a7e8e2df50f860c3480879ea5d8b83 100644
--- a/ProcessLib/CreateTimeLoop.cpp
+++ b/ProcessLib/CreateTimeLoop.cpp
@@ -10,9 +10,13 @@
 
 #include "CreateTimeLoop.h"
 
+#include <algorithm>
 #include <range/v3/algorithm/any_of.hpp>
+#include <string>
 
 #include "BaseLib/ConfigTree.h"
+#include "NumLib/StaggeredCoupling/CreateStaggeredCoupling.h"
+#include "NumLib/StaggeredCoupling/StaggeredCoupling.h"
 #include "ProcessLib/CreateProcessData.h"
 #include "ProcessLib/Output/CreateOutput.h"
 #include "ProcessLib/Output/Output.h"
@@ -29,78 +33,6 @@ std::unique_ptr<TimeLoop> createTimeLoop(
     std::vector<std::unique_ptr<MeshLib::Mesh>>& meshes,
     bool const compensate_non_equilibrium_initial_residuum)
 {
-    auto const& coupling_config
-        //! \ogs_file_param{prj__time_loop__global_process_coupling}
-        = config.getConfigSubtreeOptional("global_process_coupling");
-
-    std::vector<std::unique_ptr<NumLib::ConvergenceCriterion>>
-        global_coupling_conv_criteria;
-    std::map<std::string, int> local_coupling_processes;
-    int max_coupling_iterations = 1;
-    if (coupling_config)
-    {
-        max_coupling_iterations
-            //! \ogs_file_param{prj__time_loop__global_process_coupling__max_iter}
-            = coupling_config->getConfigParameter<int>("max_iter");
-
-        auto const& coupling_convergence_criteria_config =
-            //! \ogs_file_param{prj__time_loop__global_process_coupling__convergence_criteria}
-            coupling_config->getConfigSubtree("convergence_criteria");
-
-        auto coupling_convergence_criterion_config =
-            //! \ogs_file_param{prj__time_loop__global_process_coupling__convergence_criteria__convergence_criterion}
-            coupling_convergence_criteria_config.getConfigSubtreeList(
-                "convergence_criterion");
-        std::transform(coupling_convergence_criterion_config.begin(),
-                       coupling_convergence_criterion_config.end(),
-                       std::back_inserter(global_coupling_conv_criteria),
-                       [](BaseLib::ConfigTree const& c)
-                       { return NumLib::createConvergenceCriterion(c); });
-
-        auto const& local_coupling_processes_config =
-            coupling_config
-                //! \ogs_file_param{prj__time_loop__global_process_coupling__local_coupling_processes}
-                ->getConfigSubtreeOptional("local_coupling_processes");
-        if (local_coupling_processes_config)
-        {
-            for (
-                auto name :
-                local_coupling_processes_config
-                    //! \ogs_file_param{prj__time_loop__global_process_coupling__local_coupling_processes__process_name}
-                    ->getConfigParameterList<std::string>("process_name"))
-            {
-                BaseLib::insertIfKeyUniqueElseError(
-                    local_coupling_processes, name, -1,
-                    "The name of locally coupled process is not unique.");
-            }
-
-            static std::string const error_info =
-                "Please check the number of elements in the tag "
-                "'time_loop/global_process_coupling/"
-                "local_coupling_processes' in the project file.";
-            if (local_coupling_processes.size() >
-                global_coupling_conv_criteria.size() - 1)
-            {
-                OGS_FATAL(
-                    "The number of the locally coupled processes is greater "
-                    "than or equal to the number of total coupled processes. "
-                    "{}",
-                    error_info);
-            }
-
-            INFO("There are {:d} locally coupled processes.",
-                 local_coupling_processes.size());
-
-            if (local_coupling_processes.size() < 2)
-            {
-                OGS_FATAL(
-                    "At least two locally coupled processes are required for "
-                    "the local iteration solution! {} ",
-                    error_info);
-            }
-        }
-    }
-
     //! \ogs_file_param{prj__time_loop__output}
     auto output_config_tree = config.getConfigSubtreeOptional("output");
     if (!output_config_tree)
@@ -157,25 +89,22 @@ std::unique_ptr<TimeLoop> createTimeLoop(
                        [](auto const& process)
                        { return !(process->isMonolithicSchemeUsed()); });
 
-    if (!use_staggered_scheme && per_process_data.size() > 1)
+    std::unique_ptr<NumLib::StaggeredCoupling> staggered_coupling = nullptr;
+    if (use_staggered_scheme)
     {
-        OGS_FATAL(
-            "The monolithic scheme is used. However more than one process data "
-            "tags (by name \"process\") inside tag \"time_loop\" are defined "
-            "for the staggered scheme. If you want to use staggered scheme, "
-            "please set the element of tag \"<coupling_scheme>\" to "
-            "\"staggered\".");
+        staggered_coupling = NumLib::createStaggeredCoupling<ProcessData>(
+            config, per_process_data);
     }
-
-    if (coupling_config)
+    else
     {
-        if (global_coupling_conv_criteria.size() != per_process_data.size())
+        if (per_process_data.size() > 1)
         {
             OGS_FATAL(
-                "The number of convergence criteria of the global staggered "
-                "coupling loop is not identical to the number of the "
-                "processes! Please check the element by tag "
-                "global_process_coupling in the project file.");
+                "The monolithic scheme is used. However more than one "
+                "process data tags (by name \"process\") inside tag "
+                "\"time_loop\" are defined for the staggered scheme. If you "
+                "want to use staggered scheme, please set the element of tag "
+                "\"<coupling_scheme>\" to \"staggered\".");
         }
     }
 
@@ -196,7 +125,6 @@ std::unique_ptr<TimeLoop> createTimeLoop(
 
     return std::make_unique<TimeLoop>(
         std::move(outputs), std::move(per_process_data),
-        max_coupling_iterations, std::move(global_coupling_conv_criteria),
-        std::move(local_coupling_processes), start_time, end_time);
+        std::move(staggered_coupling), start_time, end_time);
 }
 }  // namespace ProcessLib