diff --git a/ProcessLib/BoundaryCondition/BoundaryCondition.cpp b/ProcessLib/BoundaryCondition/BoundaryCondition.cpp
index a30b6d7ddc2752b52fb204a4de23b3321b4a68e2..389f371d8c499b9d8e98a8f575e9fd160f66d158 100644
--- a/ProcessLib/BoundaryCondition/BoundaryCondition.cpp
+++ b/ProcessLib/BoundaryCondition/BoundaryCondition.cpp
@@ -16,6 +16,7 @@
 #include "NonuniformNeumannBoundaryCondition.h"
 #include "NormalTractionBoundaryCondition.h"
 #include "PhaseFieldIrreversibleDamageOracleBoundaryCondition.h"
+#include "ProcessLib/Process.h"
 #include "RobinBoundaryCondition.h"
 
 namespace ProcessLib
@@ -26,11 +27,18 @@ BoundaryConditionBuilder::createBoundaryCondition(
     const NumLib::LocalToGlobalIndexMap& dof_table, const MeshLib::Mesh& mesh,
     const int variable_id, const unsigned integration_order,
     const unsigned shapefunction_order,
-    const std::vector<std::unique_ptr<ProcessLib::ParameterBase>>& parameters)
+    const std::vector<std::unique_ptr<ProcessLib::ParameterBase>>& parameters,
+    Process const& process)
 {
     //! \ogs_file_param{prj__process_variables__process_variable__boundary_conditions__boundary_condition__type}
     auto const type = config.config.peekConfigParameter<std::string>("type");
 
+    if (type == "ConstraintDirichlet")
+    {
+        return createConstraintDirichletBoundaryCondition(
+            config, dof_table, mesh, variable_id, integration_order,
+            parameters, process);
+    }
     if (type == "Dirichlet")
     {
         return createDirichletBoundaryCondition(
diff --git a/ProcessLib/BoundaryCondition/BoundaryCondition.h b/ProcessLib/BoundaryCondition/BoundaryCondition.h
index 762b0b19b1dc83283d6e97117da7256b0f3f9de4..43fc1db7f3816bec3e1ac2ab0f863e7cc91d7aa3 100644
--- a/ProcessLib/BoundaryCondition/BoundaryCondition.h
+++ b/ProcessLib/BoundaryCondition/BoundaryCondition.h
@@ -27,6 +27,7 @@ namespace ProcessLib
 {
 struct BoundaryConditionConfig;
 struct ParameterBase;
+class Process;
 
 class BoundaryCondition
 {
@@ -65,11 +66,11 @@ public:
     virtual std::unique_ptr<BoundaryCondition> createBoundaryCondition(
         const BoundaryConditionConfig& config,
         const NumLib::LocalToGlobalIndexMap& dof_table,
-        const MeshLib::Mesh& mesh,
-        const int variable_id, const unsigned integration_order,
-        const unsigned shapefunction_order,
+        const MeshLib::Mesh& mesh, const int variable_id,
+        const unsigned integration_order, const unsigned shapefunction_order,
         const std::vector<std::unique_ptr<ProcessLib::ParameterBase>>&
-            parameters);
+            parameters,
+        Process const& process);
 
 protected:
     virtual std::unique_ptr<BoundaryCondition> createDirichletBoundaryCondition(
diff --git a/ProcessLib/BoundaryCondition/BoundaryConditionCollection.cpp b/ProcessLib/BoundaryCondition/BoundaryConditionCollection.cpp
index d2c6d1783f8fa0b4b763412f06da72eeb0f7b3f4..63293a99ab7efe5da2acb545b45f7fd6c6549afc 100644
--- a/ProcessLib/BoundaryCondition/BoundaryConditionCollection.cpp
+++ b/ProcessLib/BoundaryCondition/BoundaryConditionCollection.cpp
@@ -24,15 +24,15 @@ void BoundaryConditionCollection::addBCsForProcessVariables(
     std::vector<std::reference_wrapper<ProcessVariable>> const&
         process_variables,
     NumLib::LocalToGlobalIndexMap const& dof_table,
-    unsigned const integration_order)
+    unsigned const integration_order, Process const& process)
 {
     for (int variable_id = 0;
          variable_id < static_cast<int>(process_variables.size());
          ++variable_id)
     {
         ProcessVariable& pv = process_variables[variable_id];
-        auto bcs = pv.createBoundaryConditions(dof_table, variable_id,
-                                               integration_order, _parameters);
+        auto bcs = pv.createBoundaryConditions(
+            dof_table, variable_id, integration_order, _parameters, process);
 
         std::move(bcs.begin(), bcs.end(),
                   std::back_inserter(_boundary_conditions));
diff --git a/ProcessLib/BoundaryCondition/BoundaryConditionCollection.h b/ProcessLib/BoundaryCondition/BoundaryConditionCollection.h
index 679f76579600208e9c06ea9d56425fb3bfa7ce2d..b511506028c9900542f20d89cc72ae225fb67468 100644
--- a/ProcessLib/BoundaryCondition/BoundaryConditionCollection.h
+++ b/ProcessLib/BoundaryCondition/BoundaryConditionCollection.h
@@ -42,7 +42,7 @@ public:
         std::vector<std::reference_wrapper<ProcessVariable>> const&
             process_variables,
         NumLib::LocalToGlobalIndexMap const& dof_table,
-        unsigned const integration_order);
+        unsigned const integration_order, Process const& process);
 
     void preTimestep(const double t, GlobalVector const& x)
     {
diff --git a/ProcessLib/Process.cpp b/ProcessLib/Process.cpp
index 1dfeac7f53628f8c6390a76e9e89551ea1d3a4b8..7debb42fcfbdc5fea92bdcaad9f7da432aa399b3 100644
--- a/ProcessLib/Process.cpp
+++ b/ProcessLib/Process.cpp
@@ -38,11 +38,11 @@ Process::Process(
       _coupled_solutions(nullptr),
       _integration_order(integration_order),
       _process_variables(std::move(process_variables)),
-      _boundary_conditions([&](const std::size_t number_of_processes)
+      _boundary_conditions([&](const std::size_t number_of_process_variables)
                                -> std::vector<BoundaryConditionCollection> {
           std::vector<BoundaryConditionCollection> pcs_BCs;
-          pcs_BCs.reserve(number_of_processes);
-          for (std::size_t i = 0; i < number_of_processes; i++)
+          pcs_BCs.reserve(number_of_process_variables);
+          for (std::size_t i = 0; i < number_of_process_variables; i++)
           {
               pcs_BCs.emplace_back(BoundaryConditionCollection(parameters));
           }
@@ -68,7 +68,7 @@ void Process::initializeProcessBoundaryConditionsAndSourceTerms(
     auto& per_process_BCs = _boundary_conditions[process_id];
 
     per_process_BCs.addBCsForProcessVariables(per_process_variables, dof_table,
-                                              _integration_order);
+                                              _integration_order, *this);
 
     auto& per_process_sts = _source_term_collections[process_id];
     per_process_sts.addSourceTermsForProcessVariables(
diff --git a/ProcessLib/ProcessVariable.cpp b/ProcessLib/ProcessVariable.cpp
index fcb7c71bb62b6071ac858e8acd24b0110bdaf6e5..87a84d7d38b89b430b700bdb17637cd9c80f7e71 100644
--- a/ProcessLib/ProcessVariable.cpp
+++ b/ProcessLib/ProcessVariable.cpp
@@ -173,7 +173,8 @@ ProcessVariable::createBoundaryConditions(
     const NumLib::LocalToGlobalIndexMap& dof_table,
     const int variable_id,
     unsigned const integration_order,
-    std::vector<std::unique_ptr<ParameterBase>> const& parameters)
+    std::vector<std::unique_ptr<ParameterBase>> const& parameters,
+    Process const& process)
 {
     std::vector<std::unique_ptr<BoundaryCondition>> bcs;
     bcs.reserve(_bc_configs.size());
@@ -182,7 +183,7 @@ ProcessVariable::createBoundaryConditions(
     {
         auto bc = _bc_builder->createBoundaryCondition(
             config, dof_table, _mesh, variable_id, integration_order,
-            _shapefunction_order, parameters);
+            _shapefunction_order, parameters, process);
         bcs.push_back(std::move(bc));
     }
 
diff --git a/ProcessLib/ProcessVariable.h b/ProcessLib/ProcessVariable.h
index d079cb1002122b9c6e00a91e6b6f65ec6451ad6e..9cd33a18caa6ab1fe2a219235012f80f54518064 100644
--- a/ProcessLib/ProcessVariable.h
+++ b/ProcessLib/ProcessVariable.h
@@ -53,7 +53,8 @@ public:
     std::vector<std::unique_ptr<BoundaryCondition>> createBoundaryConditions(
         const NumLib::LocalToGlobalIndexMap& dof_table, const int variable_id,
         unsigned const integration_order,
-        std::vector<std::unique_ptr<ParameterBase>> const& parameters);
+        std::vector<std::unique_ptr<ParameterBase>> const& parameters,
+        Process const& process);
 
     std::vector<std::unique_ptr<NodalSourceTerm>> createSourceTerms(
         const NumLib::LocalToGlobalIndexMap& dof_table, const int variable_id,