diff --git a/src/scheme/AxisBoundaryConditionDescriptor.hpp b/src/scheme/AxisBoundaryConditionDescriptor.hpp
index 07ab3be487f30af021fb51ceae84892091e3ae8b..1dbbf98997a380e05d2681e17962ab4181ce5d47 100644
--- a/src/scheme/AxisBoundaryConditionDescriptor.hpp
+++ b/src/scheme/AxisBoundaryConditionDescriptor.hpp
@@ -2,11 +2,11 @@
 #define AXIS_BOUNDARY_CONDITION_DESCRIPTOR_HPP
 
 #include <mesh/IBoundaryDescriptor.hpp>
-#include <scheme/IBoundaryConditionDescriptor.hpp>
+#include <scheme/BoundaryConditionDescriptorBase.hpp>
 
 #include <memory>
 
-class AxisBoundaryConditionDescriptor : public IBoundaryConditionDescriptor
+class AxisBoundaryConditionDescriptor : public BoundaryConditionDescriptorBase
 {
  private:
   std::ostream&
@@ -16,23 +16,15 @@ class AxisBoundaryConditionDescriptor : public IBoundaryConditionDescriptor
     return os;
   }
 
-  std::shared_ptr<const IBoundaryDescriptor> m_boundary_descriptor;
-
  public:
-  const IBoundaryDescriptor&
-  boundaryDescriptor() const final
-  {
-    return *m_boundary_descriptor;
-  }
-
   Type
   type() const final
   {
     return Type::axis;
   }
 
-  AxisBoundaryConditionDescriptor(std::shared_ptr<const IBoundaryDescriptor> boundary_descriptor)
-    : m_boundary_descriptor(boundary_descriptor)
+  AxisBoundaryConditionDescriptor(const std::shared_ptr<const IBoundaryDescriptor>& boundary_descriptor)
+    : BoundaryConditionDescriptorBase{boundary_descriptor}
   {
     ;
   }
diff --git a/src/scheme/BoundaryConditionDescriptorBase.hpp b/src/scheme/BoundaryConditionDescriptorBase.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..d05dfd6713e1f8026254567c9859dba8dc287785
--- /dev/null
+++ b/src/scheme/BoundaryConditionDescriptorBase.hpp
@@ -0,0 +1,34 @@
+#ifndef BOUNDARY_CONDITION_DESCRIPTOR_BASE_HPP
+#define BOUNDARY_CONDITION_DESCRIPTOR_BASE_HPP
+
+#include <scheme/IBoundaryConditionDescriptor.hpp>
+
+class BoundaryConditionDescriptorBase : public IBoundaryConditionDescriptor
+{
+ protected:
+  std::shared_ptr<const IBoundaryDescriptor> m_boundary_descriptor;
+
+ public:
+  const std::shared_ptr<const IBoundaryDescriptor>&
+  boundaryDescriptor_shared() const final
+  {
+    return m_boundary_descriptor;
+  }
+
+  const IBoundaryDescriptor&
+  boundaryDescriptor() const final
+  {
+    return *m_boundary_descriptor;
+  }
+
+  BoundaryConditionDescriptorBase(std::shared_ptr<const IBoundaryDescriptor> boundary_descriptor)
+    : m_boundary_descriptor{boundary_descriptor}
+  {}
+
+  BoundaryConditionDescriptorBase(const BoundaryConditionDescriptorBase&) = delete;
+  BoundaryConditionDescriptorBase(BoundaryConditionDescriptorBase&&)      = delete;
+
+  virtual ~BoundaryConditionDescriptorBase() = default;
+};
+
+#endif   // BOUNDARY_CONDITION_DESCRIPTOR_BASE_HPP
diff --git a/src/scheme/DirichletBoundaryConditionDescriptor.hpp b/src/scheme/DirichletBoundaryConditionDescriptor.hpp
index 36f95df0d0ae02ea9c5b49fcd33fa8640dc7ebf1..3b80103cb0314a1b2db51fed18c9d1dd88d5a486 100644
--- a/src/scheme/DirichletBoundaryConditionDescriptor.hpp
+++ b/src/scheme/DirichletBoundaryConditionDescriptor.hpp
@@ -3,11 +3,11 @@
 
 #include <language/utils/FunctionSymbolId.hpp>
 #include <mesh/IBoundaryDescriptor.hpp>
-#include <scheme/IBoundaryConditionDescriptor.hpp>
+#include <scheme/BoundaryConditionDescriptorBase.hpp>
 
 #include <memory>
 
-class DirichletBoundaryConditionDescriptor : public IBoundaryConditionDescriptor
+class DirichletBoundaryConditionDescriptor : public BoundaryConditionDescriptorBase
 {
  private:
   std::ostream&
@@ -19,7 +19,6 @@ class DirichletBoundaryConditionDescriptor : public IBoundaryConditionDescriptor
 
   const std::string_view m_name;
 
-  std::shared_ptr<const IBoundaryDescriptor> m_boundary_descriptor;
   const FunctionSymbolId m_rhs_symbol_id;
 
  public:
@@ -35,12 +34,6 @@ class DirichletBoundaryConditionDescriptor : public IBoundaryConditionDescriptor
     return m_rhs_symbol_id;
   }
 
-  const IBoundaryDescriptor&
-  boundaryDescriptor() const final
-  {
-    return *m_boundary_descriptor;
-  }
-
   Type
   type() const final
   {
@@ -48,9 +41,9 @@ class DirichletBoundaryConditionDescriptor : public IBoundaryConditionDescriptor
   }
 
   DirichletBoundaryConditionDescriptor(const std::string_view name,
-                                       std::shared_ptr<const IBoundaryDescriptor> boundary_descriptor,
+                                       const std::shared_ptr<const IBoundaryDescriptor>& boundary_descriptor,
                                        const FunctionSymbolId& rhs_symbol_id)
-    : m_name{name}, m_boundary_descriptor(boundary_descriptor), m_rhs_symbol_id{rhs_symbol_id}
+    : BoundaryConditionDescriptorBase{boundary_descriptor}, m_name{name}, m_rhs_symbol_id{rhs_symbol_id}
   {
     ;
   }
diff --git a/src/scheme/ExternalBoundaryConditionDescriptor.hpp b/src/scheme/ExternalBoundaryConditionDescriptor.hpp
index 056592931b1ce1cf6801f7455d5e8ab3f785dc9f..eb915db373d47f2ae5bb8bbc6d0de2fa004b3261 100644
--- a/src/scheme/ExternalBoundaryConditionDescriptor.hpp
+++ b/src/scheme/ExternalBoundaryConditionDescriptor.hpp
@@ -2,12 +2,12 @@
 #define EXTERNAL_BOUNDARY_CONDITION_DESCRIPTOR_HPP
 
 #include <mesh/IBoundaryDescriptor.hpp>
-#include <scheme/IBoundaryConditionDescriptor.hpp>
+#include <scheme/BoundaryConditionDescriptorBase.hpp>
 #include <utils/Socket.hpp>
 
 #include <memory>
 
-class ExternalBoundaryConditionDescriptor : public IBoundaryConditionDescriptor
+class ExternalBoundaryConditionDescriptor : public BoundaryConditionDescriptorBase
 {
  private:
   std::ostream&
@@ -19,7 +19,6 @@ class ExternalBoundaryConditionDescriptor : public IBoundaryConditionDescriptor
 
   const std::string_view m_name;
 
-  std::shared_ptr<const IBoundaryDescriptor> m_boundary_descriptor;
   const std::shared_ptr<const Socket> m_socket;
 
  public:
@@ -35,12 +34,6 @@ class ExternalBoundaryConditionDescriptor : public IBoundaryConditionDescriptor
     return m_socket;
   }
 
-  const IBoundaryDescriptor&
-  boundaryDescriptor() const final
-  {
-    return *m_boundary_descriptor;
-  }
-
   Type
   type() const final
   {
@@ -48,9 +41,9 @@ class ExternalBoundaryConditionDescriptor : public IBoundaryConditionDescriptor
   }
 
   ExternalBoundaryConditionDescriptor(const std::string_view name,
-                                      std::shared_ptr<const IBoundaryDescriptor> boundary_descriptor,
+                                      const std::shared_ptr<const IBoundaryDescriptor>& boundary_descriptor,
                                       const std::shared_ptr<const Socket>& socket)
-    : m_name{name}, m_boundary_descriptor(boundary_descriptor), m_socket{socket}
+    : BoundaryConditionDescriptorBase{boundary_descriptor}, m_name{name}, m_socket{socket}
   {}
 
   ExternalBoundaryConditionDescriptor(const ExternalBoundaryConditionDescriptor&) = delete;
diff --git a/src/scheme/FixedBoundaryConditionDescriptor.hpp b/src/scheme/FixedBoundaryConditionDescriptor.hpp
index b69648e38364f80ef34552f10f7de41ceebf8f57..010d427c3336c5ffa5c83ffdd3f90e587aa99ec7 100644
--- a/src/scheme/FixedBoundaryConditionDescriptor.hpp
+++ b/src/scheme/FixedBoundaryConditionDescriptor.hpp
@@ -3,11 +3,11 @@
 
 #include <language/utils/FunctionSymbolId.hpp>
 #include <mesh/IBoundaryDescriptor.hpp>
-#include <scheme/IBoundaryConditionDescriptor.hpp>
+#include <scheme/BoundaryConditionDescriptorBase.hpp>
 
 #include <memory>
 
-class FixedBoundaryConditionDescriptor : public IBoundaryConditionDescriptor
+class FixedBoundaryConditionDescriptor : public BoundaryConditionDescriptorBase
 {
  private:
   std::ostream&
@@ -19,23 +19,15 @@ class FixedBoundaryConditionDescriptor : public IBoundaryConditionDescriptor
 
   const std::string_view m_name;
 
-  std::shared_ptr<const IBoundaryDescriptor> m_boundary_descriptor;
-
  public:
-  const IBoundaryDescriptor&
-  boundaryDescriptor() const final
-  {
-    return *m_boundary_descriptor;
-  }
-
   Type
   type() const final
   {
     return Type::fixed;
   }
 
-  FixedBoundaryConditionDescriptor(std::shared_ptr<const IBoundaryDescriptor> boundary_descriptor)
-    : m_boundary_descriptor(boundary_descriptor)
+  FixedBoundaryConditionDescriptor(const std::shared_ptr<const IBoundaryDescriptor>& boundary_descriptor)
+    : BoundaryConditionDescriptorBase{boundary_descriptor}
   {}
 
   FixedBoundaryConditionDescriptor(const FixedBoundaryConditionDescriptor&) = delete;
diff --git a/src/scheme/FourierBoundaryConditionDescriptor.hpp b/src/scheme/FourierBoundaryConditionDescriptor.hpp
index c9d75883dc9c8a57685db4f3477f2de67c4098ad..7c539f0538b0418350e722b3bdd601d21b9b0550 100644
--- a/src/scheme/FourierBoundaryConditionDescriptor.hpp
+++ b/src/scheme/FourierBoundaryConditionDescriptor.hpp
@@ -3,11 +3,11 @@
 
 #include <language/utils/FunctionSymbolId.hpp>
 #include <mesh/IBoundaryDescriptor.hpp>
-#include <scheme/IBoundaryConditionDescriptor.hpp>
+#include <scheme/BoundaryConditionDescriptorBase.hpp>
 
 #include <memory>
 
-class FourierBoundaryConditionDescriptor : public IBoundaryConditionDescriptor
+class FourierBoundaryConditionDescriptor : public BoundaryConditionDescriptorBase
 {
  private:
   std::ostream&
@@ -19,7 +19,6 @@ class FourierBoundaryConditionDescriptor : public IBoundaryConditionDescriptor
 
   const std::string_view m_name;
 
-  std::shared_ptr<const IBoundaryDescriptor> m_boundary_descriptor;
   const FunctionSymbolId m_mass_symbol_id;
   const FunctionSymbolId m_rhs_symbol_id;
 
@@ -42,12 +41,6 @@ class FourierBoundaryConditionDescriptor : public IBoundaryConditionDescriptor
     return m_rhs_symbol_id;
   }
 
-  const IBoundaryDescriptor&
-  boundaryDescriptor() const final
-  {
-    return *m_boundary_descriptor;
-  }
-
   Type
   type() const final
   {
@@ -55,11 +48,11 @@ class FourierBoundaryConditionDescriptor : public IBoundaryConditionDescriptor
   }
 
   FourierBoundaryConditionDescriptor(const std::string_view name,
-                                     std::shared_ptr<const IBoundaryDescriptor> boundary_descriptor,
+                                     const std::shared_ptr<const IBoundaryDescriptor>& boundary_descriptor,
                                      const FunctionSymbolId& mass_symbol_id,
                                      const FunctionSymbolId& rhs_symbol_id)
-    : m_name{name},
-      m_boundary_descriptor(boundary_descriptor),
+    : BoundaryConditionDescriptorBase{boundary_descriptor},
+      m_name{name},
       m_mass_symbol_id{mass_symbol_id},
       m_rhs_symbol_id{rhs_symbol_id}
   {
diff --git a/src/scheme/FreeBoundaryConditionDescriptor.hpp b/src/scheme/FreeBoundaryConditionDescriptor.hpp
index 2d46f2a36a04cbaca0abc5b83c9ad1983e844841..8b6df26f7bbd155d610cf6bb5de0a47817a86830 100644
--- a/src/scheme/FreeBoundaryConditionDescriptor.hpp
+++ b/src/scheme/FreeBoundaryConditionDescriptor.hpp
@@ -2,11 +2,11 @@
 #define FREE_BOUNDARY_CONDITION_DESCRIPTOR_HPP
 
 #include <mesh/IBoundaryDescriptor.hpp>
-#include <scheme/IBoundaryConditionDescriptor.hpp>
+#include <scheme/BoundaryConditionDescriptorBase.hpp>
 
 #include <memory>
 
-class FreeBoundaryConditionDescriptor : public IBoundaryConditionDescriptor
+class FreeBoundaryConditionDescriptor : public BoundaryConditionDescriptorBase
 {
  private:
   std::ostream&
@@ -16,15 +16,7 @@ class FreeBoundaryConditionDescriptor : public IBoundaryConditionDescriptor
     return os;
   }
 
-  std::shared_ptr<const IBoundaryDescriptor> m_boundary_descriptor;
-
  public:
-  const IBoundaryDescriptor&
-  boundaryDescriptor() const final
-  {
-    return *m_boundary_descriptor;
-  }
-
   Type
   type() const final
   {
@@ -32,7 +24,7 @@ class FreeBoundaryConditionDescriptor : public IBoundaryConditionDescriptor
   }
 
   FreeBoundaryConditionDescriptor(std::shared_ptr<const IBoundaryDescriptor> boundary_descriptor)
-    : m_boundary_descriptor(boundary_descriptor)
+    : BoundaryConditionDescriptorBase{boundary_descriptor}
   {
     ;
   }
diff --git a/src/scheme/IBoundaryConditionDescriptor.hpp b/src/scheme/IBoundaryConditionDescriptor.hpp
index 1350aa4dba4f7f6739b7de6689c10554ceec6971..58e8b6076ff2c363049de6f107e6a949966d6c72 100644
--- a/src/scheme/IBoundaryConditionDescriptor.hpp
+++ b/src/scheme/IBoundaryConditionDescriptor.hpp
@@ -2,6 +2,7 @@
 #define I_BOUNDARY_CONDITION_DESCRIPTOR_HPP
 
 #include <iostream>
+#include <memory>
 
 class IBoundaryDescriptor;
 
@@ -32,7 +33,8 @@ class IBoundaryConditionDescriptor
     return bcd._write(os);
   }
 
-  virtual const IBoundaryDescriptor& boundaryDescriptor() const = 0;
+  virtual const std::shared_ptr<const IBoundaryDescriptor>& boundaryDescriptor_shared() const = 0;
+  virtual const IBoundaryDescriptor& boundaryDescriptor() const                               = 0;
 
   virtual Type type() const = 0;
 
diff --git a/src/scheme/InflowBoundaryConditionDescriptor.hpp b/src/scheme/InflowBoundaryConditionDescriptor.hpp
index e648c1593cb4316f0cc77a4f18946b0457d65b5e..0b460846983946468d4161672fbc1e9aeb3912be 100644
--- a/src/scheme/InflowBoundaryConditionDescriptor.hpp
+++ b/src/scheme/InflowBoundaryConditionDescriptor.hpp
@@ -3,11 +3,11 @@
 
 #include <language/utils/FunctionSymbolId.hpp>
 #include <mesh/IBoundaryDescriptor.hpp>
-#include <scheme/IBoundaryConditionDescriptor.hpp>
+#include <scheme/BoundaryConditionDescriptorBase.hpp>
 
 #include <memory>
 
-class InflowBoundaryConditionDescriptor : public IBoundaryConditionDescriptor
+class InflowBoundaryConditionDescriptor : public BoundaryConditionDescriptorBase
 {
  private:
   std::ostream&
@@ -17,7 +17,6 @@ class InflowBoundaryConditionDescriptor : public IBoundaryConditionDescriptor
     return os;
   }
 
-  std::shared_ptr<const IBoundaryDescriptor> m_boundary_descriptor;
   const FunctionSymbolId m_function_symbol_id;
 
  public:
@@ -27,21 +26,15 @@ class InflowBoundaryConditionDescriptor : public IBoundaryConditionDescriptor
     return m_function_symbol_id;
   }
 
-  const IBoundaryDescriptor&
-  boundaryDescriptor() const final
-  {
-    return *m_boundary_descriptor;
-  }
-
   Type
   type() const final
   {
     return Type::inflow;
   }
 
-  InflowBoundaryConditionDescriptor(std::shared_ptr<const IBoundaryDescriptor> boundary_descriptor,
+  InflowBoundaryConditionDescriptor(const std::shared_ptr<const IBoundaryDescriptor>& boundary_descriptor,
                                     const FunctionSymbolId& function_symbol_id)
-    : m_boundary_descriptor(boundary_descriptor), m_function_symbol_id{function_symbol_id}
+    : BoundaryConditionDescriptorBase{boundary_descriptor}, m_function_symbol_id{function_symbol_id}
   {
     ;
   }
diff --git a/src/scheme/NeumannBoundaryConditionDescriptor.hpp b/src/scheme/NeumannBoundaryConditionDescriptor.hpp
index 597ab95e7eb5e1f61f637d840c873ba8aeb30f84..ae591a38f987d7b906e26c3fc8015f0035e9eefc 100644
--- a/src/scheme/NeumannBoundaryConditionDescriptor.hpp
+++ b/src/scheme/NeumannBoundaryConditionDescriptor.hpp
@@ -3,11 +3,11 @@
 
 #include <language/utils/FunctionSymbolId.hpp>
 #include <mesh/IBoundaryDescriptor.hpp>
-#include <scheme/IBoundaryConditionDescriptor.hpp>
+#include <scheme/BoundaryConditionDescriptorBase.hpp>
 
 #include <memory>
 
-class NeumannBoundaryConditionDescriptor : public IBoundaryConditionDescriptor
+class NeumannBoundaryConditionDescriptor : public BoundaryConditionDescriptorBase
 {
  private:
   std::ostream&
@@ -19,7 +19,6 @@ class NeumannBoundaryConditionDescriptor : public IBoundaryConditionDescriptor
 
   const std::string_view m_name;
 
-  std::shared_ptr<const IBoundaryDescriptor> m_boundary_descriptor;
   const FunctionSymbolId m_rhs_symbol_id;
 
  public:
@@ -35,12 +34,6 @@ class NeumannBoundaryConditionDescriptor : public IBoundaryConditionDescriptor
     return m_rhs_symbol_id;
   }
 
-  const IBoundaryDescriptor&
-  boundaryDescriptor() const final
-  {
-    return *m_boundary_descriptor;
-  }
-
   Type
   type() const final
   {
@@ -48,9 +41,9 @@ class NeumannBoundaryConditionDescriptor : public IBoundaryConditionDescriptor
   }
 
   NeumannBoundaryConditionDescriptor(const std::string_view name,
-                                     std::shared_ptr<const IBoundaryDescriptor> boundary_descriptor,
+                                     const std::shared_ptr<const IBoundaryDescriptor>& boundary_descriptor,
                                      const FunctionSymbolId& rhs_symbol_id)
-    : m_name{name}, m_boundary_descriptor(boundary_descriptor), m_rhs_symbol_id{rhs_symbol_id}
+    : BoundaryConditionDescriptorBase{boundary_descriptor}, m_name{name}, m_rhs_symbol_id{rhs_symbol_id}
   {
     ;
   }
diff --git a/src/scheme/OutflowBoundaryConditionDescriptor.hpp b/src/scheme/OutflowBoundaryConditionDescriptor.hpp
index 83ef7a775a81269a5d3930ed2e07d5634d99959a..bc999c501f1e4d539736e06a6ac59c76e39a170e 100644
--- a/src/scheme/OutflowBoundaryConditionDescriptor.hpp
+++ b/src/scheme/OutflowBoundaryConditionDescriptor.hpp
@@ -2,11 +2,11 @@
 #define OUTFLOW_BOUNDARY_CONDITION_DESCRIPTOR_HPP
 
 #include <mesh/IBoundaryDescriptor.hpp>
-#include <scheme/IBoundaryConditionDescriptor.hpp>
+#include <scheme/BoundaryConditionDescriptorBase.hpp>
 
 #include <memory>
 
-class OutflowBoundaryConditionDescriptor : public IBoundaryConditionDescriptor
+class OutflowBoundaryConditionDescriptor : public BoundaryConditionDescriptorBase
 {
  private:
   std::ostream&
@@ -16,23 +16,15 @@ class OutflowBoundaryConditionDescriptor : public IBoundaryConditionDescriptor
     return os;
   }
 
-  std::shared_ptr<const IBoundaryDescriptor> m_boundary_descriptor;
-
  public:
-  const IBoundaryDescriptor&
-  boundaryDescriptor() const final
-  {
-    return *m_boundary_descriptor;
-  }
-
   Type
   type() const final
   {
     return Type::outflow;
   }
 
-  OutflowBoundaryConditionDescriptor(std::shared_ptr<const IBoundaryDescriptor> boundary_descriptor)
-    : m_boundary_descriptor(boundary_descriptor)
+  OutflowBoundaryConditionDescriptor(const std::shared_ptr<const IBoundaryDescriptor>& boundary_descriptor)
+    : BoundaryConditionDescriptorBase{boundary_descriptor}
   {
     ;
   }
diff --git a/src/scheme/SymmetryBoundaryConditionDescriptor.hpp b/src/scheme/SymmetryBoundaryConditionDescriptor.hpp
index 9364090dde18490a4803662c7eb770d9f6354b1c..1172bf7e40c5b2565dd82f216617298addda1e34 100644
--- a/src/scheme/SymmetryBoundaryConditionDescriptor.hpp
+++ b/src/scheme/SymmetryBoundaryConditionDescriptor.hpp
@@ -2,11 +2,11 @@
 #define SYMMETRY_BOUNDARY_CONDITION_DESCRIPTOR_HPP
 
 #include <mesh/IBoundaryDescriptor.hpp>
-#include <scheme/IBoundaryConditionDescriptor.hpp>
+#include <scheme/BoundaryConditionDescriptorBase.hpp>
 
 #include <memory>
 
-class SymmetryBoundaryConditionDescriptor : public IBoundaryConditionDescriptor
+class SymmetryBoundaryConditionDescriptor : public BoundaryConditionDescriptorBase
 {
  private:
   std::ostream&
@@ -16,23 +16,15 @@ class SymmetryBoundaryConditionDescriptor : public IBoundaryConditionDescriptor
     return os;
   }
 
-  std::shared_ptr<const IBoundaryDescriptor> m_boundary_descriptor;
-
  public:
-  const IBoundaryDescriptor&
-  boundaryDescriptor() const final
-  {
-    return *m_boundary_descriptor;
-  }
-
   Type
   type() const final
   {
     return Type::symmetry;
   }
 
-  SymmetryBoundaryConditionDescriptor(std::shared_ptr<const IBoundaryDescriptor> boundary_descriptor)
-    : m_boundary_descriptor(boundary_descriptor)
+  SymmetryBoundaryConditionDescriptor(const std::shared_ptr<const IBoundaryDescriptor>& boundary_descriptor)
+    : BoundaryConditionDescriptorBase{boundary_descriptor}
   {
     ;
   }