diff --git a/src/main.cpp b/src/main.cpp
index 5a333d3b925672954ad2ea250c1503adb2dfd375..c12e2c9773d131547a54dd60ed0a6ffc39323f94 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -21,6 +21,8 @@
 #include <TinyVector.hpp>
 #include <TinyMatrix.hpp>
 
+#include <BoundaryConditionDescriptor.hpp>
+
 #include <GmshReader.hpp>
 
 #include <CLI/CLI.hpp>
@@ -211,6 +213,18 @@ int main(int argc, char *argv[])
           break;
         }
         case 2: {
+          // test case boundary condition description
+          std::vector<std::string> sym_boundary_name_list = {"XMIN", "XMAX", "YMIN", "YMAX"};
+          std::vector<std::shared_ptr<BoundaryConditionDescriptor>> bc_descriptor_list;
+          for (auto sym_boundary_name : sym_boundary_name_list){
+            std::shared_ptr<BoundaryDescriptor> boudary_descriptor
+                = std::shared_ptr<BoundaryDescriptor>(new NamedBoundaryDescriptor(sym_boundary_name));
+            SymmetryBoundaryConditionDescriptor* sym_bc_descriptor
+                = new SymmetryBoundaryConditionDescriptor(boudary_descriptor);
+
+            bc_descriptor_list.push_back(std::shared_ptr<BoundaryConditionDescriptor>(sym_bc_descriptor));
+          }
+
           typedef Connectivity2D ConnectivityType;
           typedef Mesh<ConnectivityType> MeshType;
           typedef MeshData<MeshType> MeshDataType;
@@ -222,8 +236,10 @@ int main(int argc, char *argv[])
           timer.reset();
           MeshDataType mesh_data(mesh);
 
+
           std::vector<BoundaryConditionHandler> bc_list;
           {
+
             for (size_t i_ref_face_list=0; i_ref_face_list<mesh.connectivity().numberOfRefFaceList();
                  ++i_ref_face_list) {
               const RefFaceList& ref_face_list = mesh.connectivity().refFaceList(i_ref_face_list);
diff --git a/src/scheme/BoundaryConditionDescriptor.hpp b/src/scheme/BoundaryConditionDescriptor.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..3e69e13d6a9c5c28bcfb175eeb0072e27d1a69e7
--- /dev/null
+++ b/src/scheme/BoundaryConditionDescriptor.hpp
@@ -0,0 +1,104 @@
+#ifndef BOUNDARY_CONDITION_DESCRIPTOR_HPP
+#define BOUNDARY_CONDITION_DESCRIPTOR_HPP
+
+#include <RefId.hpp>
+#include <memory>
+
+class BoundaryDescriptor
+{
+ public:
+  enum class Type
+  {
+    named,
+    numbered
+  };
+
+  virtual Type type() const = 0;
+  BoundaryDescriptor(const BoundaryDescriptor&) = default;
+  BoundaryDescriptor() = default;
+  virtual ~BoundaryDescriptor() = default;
+};
+
+class NamedBoundaryDescriptor
+    : public BoundaryDescriptor
+{
+ private:
+  std::string m_name;
+
+ public:
+  Type type() const
+  {
+    return Type::named;
+  }
+
+  NamedBoundaryDescriptor(const NamedBoundaryDescriptor&) = default;
+  NamedBoundaryDescriptor(const std::string& name)
+      : m_name(name)
+  {
+    ;
+  }
+  virtual ~NamedBoundaryDescriptor() = default;
+};
+
+class NumberedBoundaryDescriptor
+    : public BoundaryDescriptor
+{
+ public:
+  Type type() const
+  {
+    return Type::numbered;
+  }
+
+  NumberedBoundaryDescriptor(const NumberedBoundaryDescriptor&) = default;
+  NumberedBoundaryDescriptor() = default;
+  virtual ~NumberedBoundaryDescriptor() = default;
+};
+
+
+class BoundaryConditionDescriptor
+{
+ public:
+  enum class Type
+  {
+    symmetry
+  };
+ private:
+  std::shared_ptr<BoundaryDescriptor> m_boundary_descriptor;
+ public:
+  virtual Type type() const = 0;
+
+  const BoundaryDescriptor& boundaryDescriptor() const
+  {
+    return *m_boundary_descriptor;
+  }
+
+  BoundaryConditionDescriptor(std::shared_ptr<BoundaryDescriptor> boundary_descriptor)
+      : m_boundary_descriptor(boundary_descriptor)
+  {
+    ;
+  }
+
+  virtual ~BoundaryConditionDescriptor() = default;
+};
+
+
+class SymmetryBoundaryConditionDescriptor
+    : public BoundaryConditionDescriptor
+{
+ public:
+  Type type() const
+  {
+    return Type::symmetry;
+  }
+
+  SymmetryBoundaryConditionDescriptor(std::shared_ptr<BoundaryDescriptor> boundary_descriptor)
+      : BoundaryConditionDescriptor(boundary_descriptor)
+  {
+    ;
+  }
+
+  SymmetryBoundaryConditionDescriptor(const SymmetryBoundaryConditionDescriptor&) = default;
+  ~SymmetryBoundaryConditionDescriptor() = default;
+};
+
+#endif // BOUNDARY_CONDITION_DESCRIPTOR_HPP