diff --git a/src/language/modules/MeshModule.cpp b/src/language/modules/MeshModule.cpp
index 81ee9b240339766a4899529166fbfe2d45a4d8bb..3fc354faff4170a05b5861454d84a6fc3c7c46be 100644
--- a/src/language/modules/MeshModule.cpp
+++ b/src/language/modules/MeshModule.cpp
@@ -63,42 +63,45 @@ class MeshTransformation<OutputType(InputType...)> : public PugsFunctionAdapter<
 MeshModule::MeshModule()
 {
   this->_addTypeDescriptor(
-    std::make_shared<TypeDescriptor>(ast_node_data_type_from<std::shared_ptr<IMesh>>.typeName()));
-
-  this->_addBuiltinFunction("readGmsh", std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<IMesh>, std::string>>(
-                                          std::function<std::shared_ptr<IMesh>(std::string)>{
-
-                                            [](const std::string& file_name) -> std::shared_ptr<IMesh> {
-                                              GmshReader gmsh_reader(file_name);
-                                              return gmsh_reader.mesh();
-                                            }}
-
-                                          ));
-
-  this->_addBuiltinFunction("transform",
-                            std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<IMesh>, std::shared_ptr<IMesh>,
-                                                                     FunctionSymbolId>>(
-                              std::function<std::shared_ptr<IMesh>(std::shared_ptr<IMesh>, FunctionSymbolId)>{
-                                [](std::shared_ptr<IMesh> p_mesh,
-                                   const FunctionSymbolId& function_id) -> std::shared_ptr<IMesh> {
-                                  switch (p_mesh->dimension()) {
-                                  case 1: {
-                                    using TransformT = TinyVector<1>(TinyVector<1>);
-                                    return MeshTransformation<TransformT>::transform(function_id, p_mesh);
-                                  }
-                                  case 2: {
-                                    using TransformT = TinyVector<2>(TinyVector<2>);
-                                    return MeshTransformation<TransformT>::transform(function_id, p_mesh);
-                                  }
-                                  case 3: {
-                                    using TransformT = TinyVector<3>(TinyVector<3>);
-                                    return MeshTransformation<TransformT>::transform(function_id, p_mesh);
-                                  }
-                                  default: {
-                                    throw UnexpectedError("invalid mesh dimension");
-                                  }
-                                  }
+    std::make_shared<TypeDescriptor>(ast_node_data_type_from<std::shared_ptr<const IMesh>>.typeName()));
+
+  this->_addBuiltinFunction("readGmsh",
+                            std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<const IMesh>, std::string>>(
+                              std::function<std::shared_ptr<const IMesh>(std::string)>{
+
+                                [](const std::string& file_name) -> std::shared_ptr<const IMesh> {
+                                  GmshReader gmsh_reader(file_name);
+                                  return gmsh_reader.mesh();
                                 }}
 
                               ));
+
+  this
+    ->_addBuiltinFunction("transform",
+                          std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<const IMesh>,
+                                                                   std::shared_ptr<const IMesh>, FunctionSymbolId>>(
+                            std::function<std::shared_ptr<const IMesh>(std::shared_ptr<const IMesh>, FunctionSymbolId)>{
+
+                              [](std::shared_ptr<const IMesh> p_mesh,
+                                 const FunctionSymbolId& function_id) -> std::shared_ptr<const IMesh> {
+                                switch (p_mesh->dimension()) {
+                                case 1: {
+                                  using TransformT = TinyVector<1>(TinyVector<1>);
+                                  return MeshTransformation<TransformT>::transform(function_id, p_mesh);
+                                }
+                                case 2: {
+                                  using TransformT = TinyVector<2>(TinyVector<2>);
+                                  return MeshTransformation<TransformT>::transform(function_id, p_mesh);
+                                }
+                                case 3: {
+                                  using TransformT = TinyVector<3>(TinyVector<3>);
+                                  return MeshTransformation<TransformT>::transform(function_id, p_mesh);
+                                }
+                                default: {
+                                  throw UnexpectedError("invalid mesh dimension");
+                                }
+                                }
+                              }}
+
+                            ));
 }
diff --git a/src/language/modules/MeshModule.hpp b/src/language/modules/MeshModule.hpp
index 2fa8ade7479d9248782301af5104dc3c2a5a7f8b..64e6194946b6f6f9ceed019f513730d6fd3de8c0 100644
--- a/src/language/modules/MeshModule.hpp
+++ b/src/language/modules/MeshModule.hpp
@@ -8,7 +8,7 @@
 struct IMesh;
 
 template <>
-inline ASTNodeDataType ast_node_data_type_from<std::shared_ptr<IMesh>> = {ASTNodeDataType::type_id_t, "mesh"};
+inline ASTNodeDataType ast_node_data_type_from<std::shared_ptr<const IMesh>> = {ASTNodeDataType::type_id_t, "mesh"};
 
 class MeshModule : public BuiltinModule
 {
diff --git a/src/language/modules/SchemeModule.cpp b/src/language/modules/SchemeModule.cpp
index 05f6de0539b1c0925a188d116ca27fd2a65299e4..651516402260052ca69947415aaaea281af72f7e 100644
--- a/src/language/modules/SchemeModule.cpp
+++ b/src/language/modules/SchemeModule.cpp
@@ -17,7 +17,7 @@
 #include <output/VTKWriter.hpp>
 
 template <size_t Dimension>
-struct MeshDimensionAdapter
+struct GlaceScheme
 {
   using ConnectivityType = Connectivity<Dimension>;
   using MeshType         = Mesh<ConnectivityType>;
@@ -26,29 +26,27 @@ struct MeshDimensionAdapter
 
   const MeshType& m_mesh;
 
-  MeshDimensionAdapter(const IMesh& mesh) : m_mesh{dynamic_cast<const MeshType&>(mesh)}
+  GlaceScheme(const IMesh& mesh,
+              std::shared_ptr<const IBoundaryConditionDescriptor> boundary_0,
+              std::shared_ptr<const IBoundaryConditionDescriptor> boundary_1,
+              std::shared_ptr<const IBoundaryConditionDescriptor> boundary_2,
+              std::shared_ptr<const IBoundaryConditionDescriptor> boundary_3,
+              std::shared_ptr<const IBoundaryConditionDescriptor> boundary_4,
+              std::shared_ptr<const IBoundaryConditionDescriptor> boundary_5)
+    : m_mesh{dynamic_cast<const MeshType&>(mesh)}
   {
-    std::vector sym_boundary_name_list = [&]() -> std::vector<std::string> {
-      if constexpr (Dimension == 3) {
-        return {"XMIN", "XMAX", "YMIN", "YMAX", "ZMIN", "ZMAX"};
-      } else if constexpr (Dimension == 2) {
-        return {"XMIN", "XMAX", "YMIN", "YMAX"};
-      } else {
-        return {"XMIN", "XMAX"};
-      }
-    }();
-
     MeshDataType mesh_data(m_mesh);
-    std::vector<std::shared_ptr<IBoundaryConditionDescriptor>> bc_descriptor_list;
-    for (const auto& sym_boundary_name : sym_boundary_name_list) {
-      std::shared_ptr<IBoundaryDescriptor> boudary_descriptor =
-        std::shared_ptr<IBoundaryDescriptor>(new NamedBoundaryDescriptor(sym_boundary_name));
-      SymmetryBoundaryConditionDescriptor* sym_bc_descriptor =
-        new SymmetryBoundaryConditionDescriptor(boudary_descriptor);
-
-      bc_descriptor_list.push_back(std::shared_ptr<IBoundaryConditionDescriptor>(sym_bc_descriptor));
+    std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>> bc_descriptor_list;
+    if constexpr (Dimension == 1) {
+      bc_descriptor_list = {boundary_0, boundary_1};
+    } else if constexpr (Dimension == 2) {
+      bc_descriptor_list = {boundary_0, boundary_1, boundary_2, boundary_3};
+    } else if constexpr (Dimension == 3) {
+      bc_descriptor_list = {boundary_0, boundary_1, boundary_2, boundary_3, boundary_4, boundary_5};
     }
 
+    std::cout << "number of bc descr = " << bc_descriptor_list.size() << '\n';
+
     std::vector<BoundaryConditionHandler> bc_list;
     {
       constexpr ItemType FaceType = [] {
@@ -138,51 +136,91 @@ struct MeshDimensionAdapter
 SchemeModule::SchemeModule()
 {
   this->_addTypeDescriptor(
-    std::make_shared<TypeDescriptor>(ast_node_data_type_from<std::shared_ptr<IBoundaryDescriptor>>.typeName()));
+    std::make_shared<TypeDescriptor>(ast_node_data_type_from<std::shared_ptr<const IBoundaryDescriptor>>.typeName()));
 
-  this
-    ->_addBuiltinFunction("boundaryName",
-                          std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<IBoundaryDescriptor>, std::string>>(
-                            std::function<std::shared_ptr<IBoundaryDescriptor>(std::string)>{
+  this->_addTypeDescriptor(std::make_shared<TypeDescriptor>(
+    ast_node_data_type_from<std::shared_ptr<const IBoundaryConditionDescriptor>>.typeName()));
 
-                              [](const std::string& boundary_name) -> std::shared_ptr<IBoundaryDescriptor> {
-                                return std::make_shared<NamedBoundaryDescriptor>(boundary_name);
-                              }}
+  this->_addBuiltinFunction("boundaryName",
+                            std::make_shared<
+                              BuiltinFunctionEmbedder<std::shared_ptr<const IBoundaryDescriptor>, std::string>>(
+                              std::function<std::shared_ptr<const IBoundaryDescriptor>(std::string)>{
 
-                            ));
+                                [](const std::string& boundary_name) -> std::shared_ptr<const IBoundaryDescriptor> {
+                                  return std::make_shared<NamedBoundaryDescriptor>(boundary_name);
+                                }}
+
+                              ));
 
   this->_addBuiltinFunction("boundaryTag",
-                            std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<IBoundaryDescriptor>, int64_t>>(
-                              std::function<std::shared_ptr<IBoundaryDescriptor>(int64_t)>{
+                            std::make_shared<
+                              BuiltinFunctionEmbedder<std::shared_ptr<const IBoundaryDescriptor>, int64_t>>(
+                              std::function<std::shared_ptr<const IBoundaryDescriptor>(int64_t)>{
 
-                                [](int64_t boundary_tag) -> std::shared_ptr<IBoundaryDescriptor> {
+                                [](int64_t boundary_tag) -> std::shared_ptr<const IBoundaryDescriptor> {
                                   return std::make_shared<NumberedBoundaryDescriptor>(boundary_tag);
                                 }}
 
                               ));
 
-  this->_addBuiltinFunction("glace", std::make_shared<BuiltinFunctionEmbedder<void, std::shared_ptr<IMesh>>>(
-                                       std::function<void(std::shared_ptr<IMesh>)>{
-
-                                         [](std::shared_ptr<const IMesh> p_mesh) -> void {
-                                           switch (p_mesh->dimension()) {
-                                           case 1: {
-                                             MeshDimensionAdapter<1>{*p_mesh};
-                                             break;
-                                           }
-                                           case 2: {
-                                             MeshDimensionAdapter<2>{*p_mesh};
-                                             break;
-                                           }
-                                           case 3: {
-                                             MeshDimensionAdapter<3>{*p_mesh};
-                                             break;
-                                           }
-                                           default: {
-                                             throw UnexpectedError("invalid mesh dimension");
-                                           }
-                                           }
-                                         }}
-
-                                       ));
+  this
+    ->_addBuiltinFunction("symmetry",
+                          std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<const IBoundaryConditionDescriptor>,
+                                                                   std::shared_ptr<const IBoundaryDescriptor>>>(
+                            std::function<std::shared_ptr<const IBoundaryConditionDescriptor>(
+                              std::shared_ptr<const IBoundaryDescriptor>)>{
+
+                              [](std::shared_ptr<const IBoundaryDescriptor> boundary)
+                                -> std::shared_ptr<const IBoundaryConditionDescriptor> {
+                                return std::make_shared<SymmetryBoundaryConditionDescriptor>(boundary);
+                              }}
+
+                            ));
+
+  this->_addBuiltinFunction("glace",
+                            std::make_shared<BuiltinFunctionEmbedder<
+                              void, std::shared_ptr<const IMesh>, std::shared_ptr<const IBoundaryConditionDescriptor>,
+                              std::shared_ptr<const IBoundaryConditionDescriptor>,
+                              std::shared_ptr<const IBoundaryConditionDescriptor>,
+                              std::shared_ptr<const IBoundaryConditionDescriptor>,
+                              std::shared_ptr<const IBoundaryConditionDescriptor>,
+                              std::shared_ptr<const IBoundaryConditionDescriptor>>>(
+                              std::function<void(std::shared_ptr<const IMesh>,
+                                                 std::shared_ptr<const IBoundaryConditionDescriptor>,
+                                                 std::shared_ptr<const IBoundaryConditionDescriptor>,
+                                                 std::shared_ptr<const IBoundaryConditionDescriptor>,
+                                                 std::shared_ptr<const IBoundaryConditionDescriptor>,
+                                                 std::shared_ptr<const IBoundaryConditionDescriptor>,
+                                                 std::shared_ptr<const IBoundaryConditionDescriptor>)>{
+
+                                [](std::shared_ptr<const IMesh> p_mesh,
+                                   std::shared_ptr<const IBoundaryConditionDescriptor> boundary_0,
+                                   std::shared_ptr<const IBoundaryConditionDescriptor> boundary_1,
+                                   std::shared_ptr<const IBoundaryConditionDescriptor> boundary_2,
+                                   std::shared_ptr<const IBoundaryConditionDescriptor> boundary_3,
+                                   std::shared_ptr<const IBoundaryConditionDescriptor> boundary_4,
+                                   std::shared_ptr<const IBoundaryConditionDescriptor> boundary_5) -> void {
+                                  switch (p_mesh->dimension()) {
+                                  case 1: {
+                                    GlaceScheme<1>{*p_mesh,    boundary_0, boundary_1, boundary_2,
+                                                   boundary_3, boundary_4, boundary_5};
+                                    break;
+                                  }
+                                  case 2: {
+                                    GlaceScheme<2>{*p_mesh,    boundary_0, boundary_1, boundary_2,
+                                                   boundary_3, boundary_4, boundary_5};
+                                    break;
+                                  }
+                                  case 3: {
+                                    GlaceScheme<3>{*p_mesh,    boundary_0, boundary_1, boundary_2,
+                                                   boundary_3, boundary_4, boundary_5};
+                                    break;
+                                  }
+                                  default: {
+                                    throw UnexpectedError("invalid mesh dimension");
+                                  }
+                                  }
+                                }}
+
+                              ));
 }
diff --git a/src/language/modules/SchemeModule.hpp b/src/language/modules/SchemeModule.hpp
index 94259862493b8a232d9067ad8c26f34615b73f03..3c70be9a2db29d634b71ea96fb60fce38183c85d 100644
--- a/src/language/modules/SchemeModule.hpp
+++ b/src/language/modules/SchemeModule.hpp
@@ -7,8 +7,13 @@
 
 class IBoundaryDescriptor;
 template <>
-inline ASTNodeDataType ast_node_data_type_from<std::shared_ptr<IBoundaryDescriptor>> = {ASTNodeDataType::type_id_t,
-                                                                                        "boundary"};
+inline ASTNodeDataType ast_node_data_type_from<std::shared_ptr<const IBoundaryDescriptor>> =
+  {ASTNodeDataType::type_id_t, "boundary"};
+
+class IBoundaryConditionDescriptor;
+template <>
+inline ASTNodeDataType ast_node_data_type_from<std::shared_ptr<const IBoundaryConditionDescriptor>> =
+  {ASTNodeDataType::type_id_t, "boundary_condition"};
 
 class SchemeModule : public BuiltinModule
 {
diff --git a/src/language/modules/VTKModule.cpp b/src/language/modules/VTKModule.cpp
index 6daa44f65f4d48c9e9154a8e1dc36c5473248fb5..aafe8d2abbe0a8167e96e686ffc54e7184645585 100644
--- a/src/language/modules/VTKModule.cpp
+++ b/src/language/modules/VTKModule.cpp
@@ -10,10 +10,10 @@
 VTKModule::VTKModule()
 {
   this->_addBuiltinFunction("writeVTK",
-                            std::make_shared<BuiltinFunctionEmbedder<void, std::shared_ptr<IMesh>, std::string>>(
-                              std::function<void(std::shared_ptr<IMesh>, std::string)>{
+                            std::make_shared<BuiltinFunctionEmbedder<void, std::shared_ptr<const IMesh>, std::string>>(
+                              std::function<void(std::shared_ptr<const IMesh>, std::string)>{
 
-                                [](std::shared_ptr<IMesh> p_mesh, const std::string& filename) -> void {
+                                [](std::shared_ptr<const IMesh> p_mesh, const std::string& filename) -> void {
                                   VTKWriter writer(filename, 0.1);
 
                                   static double time = 0;
diff --git a/src/language/utils/BuiltinFunctionEmbedder.hpp b/src/language/utils/BuiltinFunctionEmbedder.hpp
index 3a921fb5baf947f1fdbe0510e544fcf9eb121ca7..78efd7d30f96f83b8ff65dced9d56d546fa5409d 100644
--- a/src/language/utils/BuiltinFunctionEmbedder.hpp
+++ b/src/language/utils/BuiltinFunctionEmbedder.hpp
@@ -23,7 +23,7 @@ class IBuiltinFunctionEmbedder
 
   virtual std::vector<ASTNodeDataType> getParameterDataTypes() const = 0;
 
-  virtual DataVariant apply(const std::vector<DataVariant>& x) const = 0;
+  virtual DataVariant apply(const std::vector<DataVariant>&) const = 0;
 
   IBuiltinFunctionEmbedder() = default;
 
@@ -145,7 +145,7 @@ class BuiltinFunctionEmbedder : public IBuiltinFunctionEmbedder
   }
 
   template <typename FX2, typename... Args2>
-  BuiltinFunctionEmbedder(std::function<FX2(Args2...)> f) : m_f(f)
+  BuiltinFunctionEmbedder(std::function<FX2(Args2...)> f) : m_f{f}
   {
     static_assert(std::is_same_v<FX, FX2>, "incorrect return type");
     static_assert(sizeof...(Args) == sizeof...(Args2), "invalid number of arguments");
@@ -194,7 +194,7 @@ class BuiltinFunctionEmbedder<FX, void> : public IBuiltinFunctionEmbedder
     }
   }
 
-  BuiltinFunctionEmbedder(const std::function<void(void)>& f) : m_f(f) {}
+  BuiltinFunctionEmbedder(const std::function<void(void)>& f) : m_f{f} {}
 };
 
 #endif   //  BUILTIN_FUNCTION_EMBEDDER_HPP
diff --git a/src/scheme/SymmetryBoundaryConditionDescriptor.hpp b/src/scheme/SymmetryBoundaryConditionDescriptor.hpp
index cdb35a4f42d0d22f8251a5eb0a2432bcaa7ac8d0..f5657ad58856f38c5d645501a14b62e77039b4c1 100644
--- a/src/scheme/SymmetryBoundaryConditionDescriptor.hpp
+++ b/src/scheme/SymmetryBoundaryConditionDescriptor.hpp
@@ -16,7 +16,7 @@ class SymmetryBoundaryConditionDescriptor : public IBoundaryConditionDescriptor
     return os;
   }
 
-  std::shared_ptr<IBoundaryDescriptor> m_boundary_descriptor;
+  std::shared_ptr<const IBoundaryDescriptor> m_boundary_descriptor;
 
  public:
   const IBoundaryDescriptor&
@@ -31,7 +31,7 @@ class SymmetryBoundaryConditionDescriptor : public IBoundaryConditionDescriptor
     return Type::symmetry;
   }
 
-  SymmetryBoundaryConditionDescriptor(std::shared_ptr<IBoundaryDescriptor> boundary_descriptor)
+  SymmetryBoundaryConditionDescriptor(std::shared_ptr<const IBoundaryDescriptor> boundary_descriptor)
     : m_boundary_descriptor(boundary_descriptor)
   {
     ;