diff --git a/src/language/modules/BinaryOperatorRegisterForVh.cpp b/src/language/modules/BinaryOperatorRegisterForVh.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8d1dc7f354194adb266aeff16d412e755ffd1688
--- /dev/null
+++ b/src/language/modules/BinaryOperatorRegisterForVh.cpp
@@ -0,0 +1,289 @@
+#include <language/modules/BinaryOperatorRegisterForVh.hpp>
+
+#include <language/modules/SchemeModule.hpp>
+#include <language/utils/BinaryOperatorProcessorBuilder.hpp>
+#include <language/utils/DataHandler.hpp>
+#include <language/utils/DataVariant.hpp>
+#include <language/utils/EmbeddedIDiscreteFunctionOperators.hpp>
+#include <language/utils/OperatorRepository.hpp>
+#include <scheme/IDiscreteFunction.hpp>
+
+void
+BinaryOperatorRegisterForVh::_register_plus()
+{
+  OperatorRepository& repository = OperatorRepository::instance();
+
+  repository.addBinaryOperator<language::plus_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::plus_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    std::shared_ptr<const IDiscreteFunction>,
+                                                    std::shared_ptr<const IDiscreteFunction>>>());
+
+  repository.addBinaryOperator<language::plus_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::plus_op, std::shared_ptr<const IDiscreteFunction>, bool,
+                                                    std::shared_ptr<const IDiscreteFunction>>>());
+
+  repository.addBinaryOperator<language::plus_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::plus_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    int64_t, std::shared_ptr<const IDiscreteFunction>>>());
+
+  repository.addBinaryOperator<language::plus_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::plus_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    uint64_t, std::shared_ptr<const IDiscreteFunction>>>());
+
+  repository.addBinaryOperator<language::plus_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::plus_op, std::shared_ptr<const IDiscreteFunction>, double,
+                                                    std::shared_ptr<const IDiscreteFunction>>>());
+
+  repository.addBinaryOperator<language::plus_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::plus_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    std::shared_ptr<const IDiscreteFunction>, bool>>());
+
+  repository.addBinaryOperator<language::plus_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::plus_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    std::shared_ptr<const IDiscreteFunction>, int64_t>>());
+
+  repository.addBinaryOperator<language::plus_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::plus_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    std::shared_ptr<const IDiscreteFunction>, uint64_t>>());
+
+  repository.addBinaryOperator<language::plus_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::plus_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    std::shared_ptr<const IDiscreteFunction>, double>>());
+
+  repository.addBinaryOperator<language::plus_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::plus_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    TinyVector<1>, std::shared_ptr<const IDiscreteFunction>>>());
+
+  repository.addBinaryOperator<language::plus_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::plus_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    TinyVector<2>, std::shared_ptr<const IDiscreteFunction>>>());
+
+  repository.addBinaryOperator<language::plus_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::plus_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    TinyVector<3>, std::shared_ptr<const IDiscreteFunction>>>());
+
+  repository.addBinaryOperator<language::plus_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::plus_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    TinyMatrix<1>, std::shared_ptr<const IDiscreteFunction>>>());
+
+  repository.addBinaryOperator<language::plus_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::plus_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    TinyMatrix<2>, std::shared_ptr<const IDiscreteFunction>>>());
+
+  repository.addBinaryOperator<language::plus_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::plus_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    TinyMatrix<3>, std::shared_ptr<const IDiscreteFunction>>>());
+
+  repository.addBinaryOperator<language::plus_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::plus_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    std::shared_ptr<const IDiscreteFunction>, TinyVector<1>>>());
+
+  repository.addBinaryOperator<language::plus_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::plus_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    std::shared_ptr<const IDiscreteFunction>, TinyVector<2>>>());
+
+  repository.addBinaryOperator<language::plus_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::plus_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    std::shared_ptr<const IDiscreteFunction>, TinyVector<3>>>());
+
+  repository.addBinaryOperator<language::plus_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::plus_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    std::shared_ptr<const IDiscreteFunction>, TinyMatrix<1>>>());
+
+  repository.addBinaryOperator<language::plus_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::plus_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    std::shared_ptr<const IDiscreteFunction>, TinyMatrix<2>>>());
+
+  repository.addBinaryOperator<language::plus_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::plus_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    std::shared_ptr<const IDiscreteFunction>, TinyMatrix<3>>>());
+}
+
+void
+BinaryOperatorRegisterForVh::_register_minus()
+{
+  OperatorRepository& repository = OperatorRepository::instance();
+
+  repository.addBinaryOperator<language::minus_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::minus_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    std::shared_ptr<const IDiscreteFunction>,
+                                                    std::shared_ptr<const IDiscreteFunction>>>());
+
+  repository.addBinaryOperator<language::minus_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::minus_op, std::shared_ptr<const IDiscreteFunction>, bool,
+                                                    std::shared_ptr<const IDiscreteFunction>>>());
+
+  repository.addBinaryOperator<language::minus_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::minus_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    int64_t, std::shared_ptr<const IDiscreteFunction>>>());
+
+  repository.addBinaryOperator<language::minus_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::minus_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    uint64_t, std::shared_ptr<const IDiscreteFunction>>>());
+
+  repository.addBinaryOperator<language::minus_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::minus_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    double, std::shared_ptr<const IDiscreteFunction>>>());
+
+  repository.addBinaryOperator<language::minus_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::minus_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    std::shared_ptr<const IDiscreteFunction>, bool>>());
+
+  repository.addBinaryOperator<language::minus_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::minus_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    std::shared_ptr<const IDiscreteFunction>, int64_t>>());
+
+  repository.addBinaryOperator<language::minus_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::minus_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    std::shared_ptr<const IDiscreteFunction>, uint64_t>>());
+
+  repository.addBinaryOperator<language::minus_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::minus_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    std::shared_ptr<const IDiscreteFunction>, double>>());
+
+  repository.addBinaryOperator<language::minus_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::minus_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    TinyVector<1>, std::shared_ptr<const IDiscreteFunction>>>());
+
+  repository.addBinaryOperator<language::minus_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::minus_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    TinyVector<2>, std::shared_ptr<const IDiscreteFunction>>>());
+
+  repository.addBinaryOperator<language::minus_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::minus_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    TinyVector<3>, std::shared_ptr<const IDiscreteFunction>>>());
+
+  repository.addBinaryOperator<language::minus_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::minus_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    TinyMatrix<1>, std::shared_ptr<const IDiscreteFunction>>>());
+
+  repository.addBinaryOperator<language::minus_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::minus_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    TinyMatrix<2>, std::shared_ptr<const IDiscreteFunction>>>());
+
+  repository.addBinaryOperator<language::minus_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::minus_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    TinyMatrix<3>, std::shared_ptr<const IDiscreteFunction>>>());
+
+  repository.addBinaryOperator<language::minus_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::minus_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    std::shared_ptr<const IDiscreteFunction>, TinyVector<1>>>());
+
+  repository.addBinaryOperator<language::minus_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::minus_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    std::shared_ptr<const IDiscreteFunction>, TinyVector<2>>>());
+
+  repository.addBinaryOperator<language::minus_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::minus_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    std::shared_ptr<const IDiscreteFunction>, TinyVector<3>>>());
+
+  repository.addBinaryOperator<language::minus_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::minus_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    std::shared_ptr<const IDiscreteFunction>, TinyMatrix<1>>>());
+
+  repository.addBinaryOperator<language::minus_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::minus_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    std::shared_ptr<const IDiscreteFunction>, TinyMatrix<2>>>());
+
+  repository.addBinaryOperator<language::minus_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::minus_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    std::shared_ptr<const IDiscreteFunction>, TinyMatrix<3>>>());
+}
+
+void
+BinaryOperatorRegisterForVh::_register_multiply()
+{
+  OperatorRepository& repository = OperatorRepository::instance();
+
+  repository.addBinaryOperator<language::multiply_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::multiply_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    std::shared_ptr<const IDiscreteFunction>,
+                                                    std::shared_ptr<const IDiscreteFunction>>>());
+
+  repository.addBinaryOperator<language::multiply_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::multiply_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    bool, std::shared_ptr<const IDiscreteFunction>>>());
+
+  repository.addBinaryOperator<language::multiply_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::multiply_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    int64_t, std::shared_ptr<const IDiscreteFunction>>>());
+
+  repository.addBinaryOperator<language::multiply_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::multiply_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    uint64_t, std::shared_ptr<const IDiscreteFunction>>>());
+
+  repository.addBinaryOperator<language::multiply_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::multiply_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    double, std::shared_ptr<const IDiscreteFunction>>>());
+
+  repository.addBinaryOperator<language::multiply_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::multiply_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    TinyMatrix<1>, std::shared_ptr<const IDiscreteFunction>>>());
+
+  repository.addBinaryOperator<language::multiply_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::multiply_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    TinyMatrix<2>, std::shared_ptr<const IDiscreteFunction>>>());
+
+  repository.addBinaryOperator<language::multiply_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::multiply_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    TinyMatrix<3>, std::shared_ptr<const IDiscreteFunction>>>());
+
+  repository.addBinaryOperator<language::multiply_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::multiply_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    std::shared_ptr<const IDiscreteFunction>, TinyVector<1>>>());
+
+  repository.addBinaryOperator<language::multiply_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::multiply_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    std::shared_ptr<const IDiscreteFunction>, TinyVector<2>>>());
+
+  repository.addBinaryOperator<language::multiply_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::multiply_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    std::shared_ptr<const IDiscreteFunction>, TinyVector<3>>>());
+
+  repository.addBinaryOperator<language::multiply_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::multiply_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    std::shared_ptr<const IDiscreteFunction>, TinyMatrix<1>>>());
+
+  repository.addBinaryOperator<language::multiply_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::multiply_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    std::shared_ptr<const IDiscreteFunction>, TinyMatrix<2>>>());
+
+  repository.addBinaryOperator<language::multiply_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::multiply_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    std::shared_ptr<const IDiscreteFunction>, TinyMatrix<3>>>());
+}
+
+void
+BinaryOperatorRegisterForVh::_register_divide()
+{
+  OperatorRepository& repository = OperatorRepository::instance();
+
+  repository.addBinaryOperator<language::divide_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::divide_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    std::shared_ptr<const IDiscreteFunction>,
+                                                    std::shared_ptr<const IDiscreteFunction>>>());
+
+  repository.addBinaryOperator<language::divide_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::divide_op, std::shared_ptr<const IDiscreteFunction>, bool,
+                                                    std::shared_ptr<const IDiscreteFunction>>>());
+
+  repository.addBinaryOperator<language::divide_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::divide_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    int64_t, std::shared_ptr<const IDiscreteFunction>>>());
+
+  repository.addBinaryOperator<language::divide_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::divide_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    uint64_t, std::shared_ptr<const IDiscreteFunction>>>());
+
+  repository.addBinaryOperator<language::divide_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::divide_op, std::shared_ptr<const IDiscreteFunction>,
+                                                    double, std::shared_ptr<const IDiscreteFunction>>>());
+}
+
+BinaryOperatorRegisterForVh::BinaryOperatorRegisterForVh()
+{
+  this->_register_plus();
+  this->_register_minus();
+  this->_register_multiply();
+  this->_register_divide();
+}
diff --git a/src/language/modules/BinaryOperatorRegisterForVh.hpp b/src/language/modules/BinaryOperatorRegisterForVh.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..86848e1b3037418aab36159b78d0c9f2578b4fde
--- /dev/null
+++ b/src/language/modules/BinaryOperatorRegisterForVh.hpp
@@ -0,0 +1,16 @@
+#ifndef BINARY_OPERATOR_REGISTER_FOR_VH_HPP
+#define BINARY_OPERATOR_REGISTER_FOR_VH_HPP
+
+class BinaryOperatorRegisterForVh
+{
+ private:
+  void _register_plus();
+  void _register_minus();
+  void _register_multiply();
+  void _register_divide();
+
+ public:
+  BinaryOperatorRegisterForVh();
+};
+
+#endif   // BINARY_OPERATOR_REGISTER_FOR_VH_HPP
diff --git a/src/language/modules/CMakeLists.txt b/src/language/modules/CMakeLists.txt
index dfc777168d454337ffbd38ef084f37f50924b117..c21c8cb962798579c93ee52f143c6d5de679102a 100644
--- a/src/language/modules/CMakeLists.txt
+++ b/src/language/modules/CMakeLists.txt
@@ -1,6 +1,7 @@
 # ------------------- Source files --------------------
 
 add_library(PugsLanguageModules
+  BinaryOperatorRegisterForVh.cpp
   BuiltinModule.cpp
   CoreModule.cpp
   LinearSolverModule.cpp
diff --git a/src/language/modules/SchemeModule.cpp b/src/language/modules/SchemeModule.cpp
index 7c0d55cf1f23e9f5b186f220fbe2608e2ada7b7f..7b175e0893716318665b4d4b83aa6e011133947a 100644
--- a/src/language/modules/SchemeModule.cpp
+++ b/src/language/modules/SchemeModule.cpp
@@ -1,9 +1,8 @@
 #include <language/modules/SchemeModule.hpp>
 
+#include <language/modules/BinaryOperatorRegisterForVh.hpp>
 #include <language/utils/BinaryOperatorProcessorBuilder.hpp>
 #include <language/utils/BuiltinFunctionEmbedder.hpp>
-#include <language/utils/EmbeddedIDiscreteFunctionOperators.hpp>
-#include <language/utils/OperatorRepository.hpp>
 #include <language/utils/TypeDescriptor.hpp>
 #include <mesh/Mesh.hpp>
 #include <scheme/AcousticSolver.hpp>
@@ -301,77 +300,5 @@ SchemeModule::SchemeModule()
 void
 SchemeModule::registerOperators() const
 {
-  OperatorRepository& repository = OperatorRepository::instance();
-
-  repository.addBinaryOperator<language::plus_op>(
-    std::make_shared<BinaryOperatorProcessorBuilder<language::plus_op, std::shared_ptr<const IDiscreteFunction>,
-                                                    std::shared_ptr<const IDiscreteFunction>,
-                                                    std::shared_ptr<const IDiscreteFunction>>>());
-
-  repository.addBinaryOperator<language::minus_op>(
-    std::make_shared<BinaryOperatorProcessorBuilder<language::minus_op, std::shared_ptr<const IDiscreteFunction>,
-                                                    std::shared_ptr<const IDiscreteFunction>,
-                                                    std::shared_ptr<const IDiscreteFunction>>>());
-
-  repository.addBinaryOperator<language::multiply_op>(
-    std::make_shared<BinaryOperatorProcessorBuilder<language::multiply_op, std::shared_ptr<const IDiscreteFunction>,
-                                                    std::shared_ptr<const IDiscreteFunction>,
-                                                    std::shared_ptr<const IDiscreteFunction>>>());
-
-  repository.addBinaryOperator<language::divide_op>(
-    std::make_shared<BinaryOperatorProcessorBuilder<language::divide_op, std::shared_ptr<const IDiscreteFunction>,
-                                                    std::shared_ptr<const IDiscreteFunction>,
-                                                    std::shared_ptr<const IDiscreteFunction>>>());
-
-  repository.addBinaryOperator<language::multiply_op>(
-    std::make_shared<BinaryOperatorProcessorBuilder<language::multiply_op, std::shared_ptr<const IDiscreteFunction>,
-                                                    bool, std::shared_ptr<const IDiscreteFunction>>>());
-
-  repository.addBinaryOperator<language::multiply_op>(
-    std::make_shared<BinaryOperatorProcessorBuilder<language::multiply_op, std::shared_ptr<const IDiscreteFunction>,
-                                                    int64_t, std::shared_ptr<const IDiscreteFunction>>>());
-
-  repository.addBinaryOperator<language::multiply_op>(
-    std::make_shared<BinaryOperatorProcessorBuilder<language::multiply_op, std::shared_ptr<const IDiscreteFunction>,
-                                                    uint64_t, std::shared_ptr<const IDiscreteFunction>>>());
-
-  repository.addBinaryOperator<language::multiply_op>(
-    std::make_shared<BinaryOperatorProcessorBuilder<language::multiply_op, std::shared_ptr<const IDiscreteFunction>,
-                                                    double, std::shared_ptr<const IDiscreteFunction>>>());
-
-  repository.addBinaryOperator<language::multiply_op>(
-    std::make_shared<BinaryOperatorProcessorBuilder<language::multiply_op, std::shared_ptr<const IDiscreteFunction>,
-                                                    TinyMatrix<1>, std::shared_ptr<const IDiscreteFunction>>>());
-
-  repository.addBinaryOperator<language::multiply_op>(
-    std::make_shared<BinaryOperatorProcessorBuilder<language::multiply_op, std::shared_ptr<const IDiscreteFunction>,
-                                                    TinyMatrix<2>, std::shared_ptr<const IDiscreteFunction>>>());
-
-  repository.addBinaryOperator<language::multiply_op>(
-    std::make_shared<BinaryOperatorProcessorBuilder<language::multiply_op, std::shared_ptr<const IDiscreteFunction>,
-                                                    TinyMatrix<3>, std::shared_ptr<const IDiscreteFunction>>>());
-
-  repository.addBinaryOperator<language::multiply_op>(
-    std::make_shared<BinaryOperatorProcessorBuilder<language::multiply_op, std::shared_ptr<const IDiscreteFunction>,
-                                                    std::shared_ptr<const IDiscreteFunction>, TinyVector<1>>>());
-
-  repository.addBinaryOperator<language::multiply_op>(
-    std::make_shared<BinaryOperatorProcessorBuilder<language::multiply_op, std::shared_ptr<const IDiscreteFunction>,
-                                                    std::shared_ptr<const IDiscreteFunction>, TinyVector<2>>>());
-
-  repository.addBinaryOperator<language::multiply_op>(
-    std::make_shared<BinaryOperatorProcessorBuilder<language::multiply_op, std::shared_ptr<const IDiscreteFunction>,
-                                                    std::shared_ptr<const IDiscreteFunction>, TinyVector<3>>>());
-
-  repository.addBinaryOperator<language::multiply_op>(
-    std::make_shared<BinaryOperatorProcessorBuilder<language::multiply_op, std::shared_ptr<const IDiscreteFunction>,
-                                                    std::shared_ptr<const IDiscreteFunction>, TinyMatrix<1>>>());
-
-  repository.addBinaryOperator<language::multiply_op>(
-    std::make_shared<BinaryOperatorProcessorBuilder<language::multiply_op, std::shared_ptr<const IDiscreteFunction>,
-                                                    std::shared_ptr<const IDiscreteFunction>, TinyMatrix<2>>>());
-
-  repository.addBinaryOperator<language::multiply_op>(
-    std::make_shared<BinaryOperatorProcessorBuilder<language::multiply_op, std::shared_ptr<const IDiscreteFunction>,
-                                                    std::shared_ptr<const IDiscreteFunction>, TinyMatrix<3>>>());
+  BinaryOperatorRegisterForVh{};
 }
diff --git a/src/language/utils/EmbeddedIDiscreteFunctionOperators.cpp b/src/language/utils/EmbeddedIDiscreteFunctionOperators.cpp
index af0ac957a430cecc6bcdd8b643064816a2402b94..ecbc5e15c2ef7e14f606ceb9309642095b439172 100644
--- a/src/language/utils/EmbeddedIDiscreteFunctionOperators.cpp
+++ b/src/language/utils/EmbeddedIDiscreteFunctionOperators.cpp
@@ -8,23 +8,16 @@
 
 template <typename T>
 PUGS_INLINE std::string
-name(const T&)
+operand_type_name(const T& t)
 {
-  return dataTypeName(ast_node_data_type_from<T>);
-}
-
-template <>
-PUGS_INLINE std::string
-name(const IDiscreteFunction& f)
-{
-  return "Vh(" + name(f.descriptor().type()) + ":" + dataTypeName(f.dataType()) + ")";
-}
-
-template <>
-PUGS_INLINE std::string
-name(const std::shared_ptr<const IDiscreteFunction>& f)
-{
-  return "Vh(" + name(f->descriptor().type()) + ":" + dataTypeName(f->dataType()) + ")";
+  if constexpr (is_shared_ptr_v<T>) {
+    Assert(t.use_count() > 0);
+    return operand_type_name(*t);
+  } else if constexpr (std::is_base_of_v<IDiscreteFunction, std::decay_t<T>>) {
+    return "Vh(" + name(t.descriptor().type()) + ':' + dataTypeName(t.dataType()) + ')';
+  } else {
+    return dataTypeName(ast_node_data_type_from<T>);
+  }
 }
 
 PUGS_INLINE
@@ -48,7 +41,7 @@ invalid_operands(const LHS_T& f, const RHS_T& g)
 {
   std::ostringstream os;
   os << "undefined binary operator\n";
-  os << "note: incompatible operand types " << name(f) << " and " << name(g);
+  os << "note: incompatible operand types " << operand_type_name(f) << " and " << operand_type_name(g);
   return os.str();
 }
 
@@ -89,7 +82,7 @@ innerCompositionLaw(const std::shared_ptr<const IDiscreteFunction>& f,
         auto gh = dynamic_cast<const DiscreteFunctionP0Vector<Dimension, double>&>(*g);
 
         if (fh.size() != gh.size()) {
-          throw NormalError(name(f) + " spaces have different sizes");
+          throw NormalError(operand_type_name(f) + " spaces have different sizes");
         }
 
         return innerCompositionLaw<BinOperatorT>(fh, gh);
@@ -221,7 +214,6 @@ applyBinaryOperation(const DiscreteFunctionT& fh, const std::shared_ptr<const ID
                          std::is_same_v<DiscreteFunctionT, DiscreteFunctionP0<Dimension, double>>) {
       if (g->descriptor().type() == DiscreteFunctionType::P0Vector) {
         auto gh = dynamic_cast<const DiscreteFunctionP0Vector<Dimension, double>&>(*g);
-
         return applyBinaryOperation<BinOperatorT>(fh, gh);
       } else {
         throw NormalError(invalid_operands(fh, g));
@@ -413,6 +405,42 @@ applyBinaryOperationWithLeftConstant(const DataType& a, const DiscreteFunctionT&
   using lhs_data_type = std::decay_t<DataType>;
   using rhs_data_type = std::decay_t<typename DiscreteFunctionT::data_type>;
 
+  if constexpr (std::is_same_v<language::multiply_op, BinOperatorT>) {
+    if constexpr (std::is_same_v<lhs_data_type, double>) {
+      return std::make_shared<decltype(BinOp<BinOperatorT>{}.eval(a, f))>(BinOp<BinOperatorT>{}.eval(a, f));
+    } else if constexpr (is_tiny_matrix_v<lhs_data_type> and
+                         (is_tiny_matrix_v<rhs_data_type> or is_tiny_vector_v<rhs_data_type>)) {
+      return std::make_shared<decltype(BinOp<BinOperatorT>{}.eval(a, f))>(BinOp<BinOperatorT>{}.eval(a, f));
+    } else {
+      throw NormalError(invalid_operands(a, f));
+    }
+  } else if constexpr (std::is_same_v<language::plus_op, BinOperatorT> or
+                       std::is_same_v<language::minus_op, BinOperatorT>) {
+    if constexpr (std::is_same_v<lhs_data_type, double> and std::is_arithmetic_v<rhs_data_type>) {
+      return std::make_shared<decltype(BinOp<BinOperatorT>{}.eval(a, f))>(BinOp<BinOperatorT>{}.eval(a, f));
+    } else if constexpr (std::is_same_v<lhs_data_type, rhs_data_type>) {
+      return std::make_shared<decltype(BinOp<BinOperatorT>{}.eval(a, f))>(BinOp<BinOperatorT>{}.eval(a, f));
+    } else {
+      throw NormalError(invalid_operands(a, f));
+    }
+  } else if constexpr (std::is_same_v<language::divide_op, BinOperatorT>) {
+    if constexpr (std::is_same_v<lhs_data_type, double> and std::is_arithmetic_v<rhs_data_type>) {
+      return std::make_shared<decltype(BinOp<BinOperatorT>{}.eval(a, f))>(BinOp<BinOperatorT>{}.eval(a, f));
+    } else {
+      throw NormalError(invalid_operands(a, f));
+    }
+  } else {
+    throw NormalError(invalid_operands(a, f));
+  }
+}
+
+template <typename BinOperatorT, typename DataType, typename DiscreteFunctionT>
+std::shared_ptr<const IDiscreteFunction>
+applyBinaryOperationToVectorWithLeftConstant(const DataType& a, const DiscreteFunctionT& f)
+{
+  using lhs_data_type = std::decay_t<DataType>;
+  using rhs_data_type = std::decay_t<typename DiscreteFunctionT::data_type>;
+
   if constexpr (std::is_same_v<language::multiply_op, BinOperatorT>) {
     if constexpr (std::is_same_v<lhs_data_type, double>) {
       return std::make_shared<decltype(BinOp<BinOperatorT>{}.eval(a, f))>(BinOp<BinOperatorT>{}.eval(a, f));
@@ -441,7 +469,7 @@ applyBinaryOperationWithLeftConstant(const DataType& a, const std::shared_ptr<co
       return applyBinaryOperationWithLeftConstant<BinOperatorT>(a, fh);
     } else if (f->descriptor().type() == DiscreteFunctionType::P0Vector) {
       auto fh = dynamic_cast<const DiscreteFunctionP0Vector<Dimension, double>&>(*f);
-      return applyBinaryOperationWithLeftConstant<BinOperatorT>(a, fh);
+      return applyBinaryOperationToVectorWithLeftConstant<BinOperatorT>(a, fh);
     } else {
       throw NormalError(invalid_operands(a, f));
     }
@@ -692,6 +720,174 @@ applyBinaryOperationWithRightConstant(const std::shared_ptr<const IDiscreteFunct
   }
 }
 
+std::shared_ptr<const IDiscreteFunction>
+operator+(const double& f, const std::shared_ptr<const IDiscreteFunction>& g)
+{
+  return applyBinaryOperationWithLeftConstant<language::plus_op>(f, g);
+}
+
+std::shared_ptr<const IDiscreteFunction>
+operator+(const std::shared_ptr<const IDiscreteFunction>& f, const double& g)
+{
+  return applyBinaryOperationWithRightConstant<language::plus_op>(f, g);
+}
+
+std::shared_ptr<const IDiscreteFunction>
+operator+(const TinyVector<1>& f, const std::shared_ptr<const IDiscreteFunction>& g)
+{
+  return applyBinaryOperationWithLeftConstant<language::plus_op>(f, g);
+}
+
+std::shared_ptr<const IDiscreteFunction>
+operator+(const TinyVector<2>& f, const std::shared_ptr<const IDiscreteFunction>& g)
+{
+  return applyBinaryOperationWithLeftConstant<language::plus_op>(f, g);
+}
+
+std::shared_ptr<const IDiscreteFunction>
+operator+(const TinyVector<3>& f, const std::shared_ptr<const IDiscreteFunction>& g)
+{
+  return applyBinaryOperationWithLeftConstant<language::plus_op>(f, g);
+}
+
+std::shared_ptr<const IDiscreteFunction>
+operator+(const TinyMatrix<1>& f, const std::shared_ptr<const IDiscreteFunction>& g)
+{
+  return applyBinaryOperationWithLeftConstant<language::plus_op>(f, g);
+}
+
+std::shared_ptr<const IDiscreteFunction>
+operator+(const TinyMatrix<2>& f, const std::shared_ptr<const IDiscreteFunction>& g)
+{
+  return applyBinaryOperationWithLeftConstant<language::plus_op>(f, g);
+}
+
+std::shared_ptr<const IDiscreteFunction>
+operator+(const TinyMatrix<3>& f, const std::shared_ptr<const IDiscreteFunction>& g)
+{
+  return applyBinaryOperationWithLeftConstant<language::plus_op>(f, g);
+}
+
+std::shared_ptr<const IDiscreteFunction>
+operator+(const std::shared_ptr<const IDiscreteFunction>& f, const TinyVector<1>& g)
+{
+  return applyBinaryOperationWithRightConstant<language::plus_op>(f, g);
+}
+
+std::shared_ptr<const IDiscreteFunction>
+operator+(const std::shared_ptr<const IDiscreteFunction>& f, const TinyVector<2>& g)
+{
+  return applyBinaryOperationWithRightConstant<language::plus_op>(f, g);
+}
+
+std::shared_ptr<const IDiscreteFunction>
+operator+(const std::shared_ptr<const IDiscreteFunction>& f, const TinyVector<3>& g)
+{
+  return applyBinaryOperationWithRightConstant<language::plus_op>(f, g);
+}
+
+std::shared_ptr<const IDiscreteFunction>
+operator+(const std::shared_ptr<const IDiscreteFunction>& f, const TinyMatrix<1>& g)
+{
+  return applyBinaryOperationWithRightConstant<language::plus_op>(f, g);
+}
+
+std::shared_ptr<const IDiscreteFunction>
+operator+(const std::shared_ptr<const IDiscreteFunction>& f, const TinyMatrix<2>& g)
+{
+  return applyBinaryOperationWithRightConstant<language::plus_op>(f, g);
+}
+
+std::shared_ptr<const IDiscreteFunction>
+operator+(const std::shared_ptr<const IDiscreteFunction>& f, const TinyMatrix<3>& g)
+{
+  return applyBinaryOperationWithRightConstant<language::plus_op>(f, g);
+}
+
+std::shared_ptr<const IDiscreteFunction>
+operator-(const double& f, const std::shared_ptr<const IDiscreteFunction>& g)
+{
+  return applyBinaryOperationWithLeftConstant<language::minus_op>(f, g);
+}
+
+std::shared_ptr<const IDiscreteFunction>
+operator-(const std::shared_ptr<const IDiscreteFunction>& f, const double& g)
+{
+  return applyBinaryOperationWithRightConstant<language::minus_op>(f, g);
+}
+
+std::shared_ptr<const IDiscreteFunction>
+operator-(const TinyVector<1>& f, const std::shared_ptr<const IDiscreteFunction>& g)
+{
+  return applyBinaryOperationWithLeftConstant<language::minus_op>(f, g);
+}
+
+std::shared_ptr<const IDiscreteFunction>
+operator-(const TinyVector<2>& f, const std::shared_ptr<const IDiscreteFunction>& g)
+{
+  return applyBinaryOperationWithLeftConstant<language::minus_op>(f, g);
+}
+
+std::shared_ptr<const IDiscreteFunction>
+operator-(const TinyVector<3>& f, const std::shared_ptr<const IDiscreteFunction>& g)
+{
+  return applyBinaryOperationWithLeftConstant<language::minus_op>(f, g);
+}
+
+std::shared_ptr<const IDiscreteFunction>
+operator-(const TinyMatrix<1>& f, const std::shared_ptr<const IDiscreteFunction>& g)
+{
+  return applyBinaryOperationWithLeftConstant<language::minus_op>(f, g);
+}
+
+std::shared_ptr<const IDiscreteFunction>
+operator-(const TinyMatrix<2>& f, const std::shared_ptr<const IDiscreteFunction>& g)
+{
+  return applyBinaryOperationWithLeftConstant<language::minus_op>(f, g);
+}
+
+std::shared_ptr<const IDiscreteFunction>
+operator-(const TinyMatrix<3>& f, const std::shared_ptr<const IDiscreteFunction>& g)
+{
+  return applyBinaryOperationWithLeftConstant<language::minus_op>(f, g);
+}
+
+std::shared_ptr<const IDiscreteFunction>
+operator-(const std::shared_ptr<const IDiscreteFunction>& f, const TinyVector<1>& g)
+{
+  return applyBinaryOperationWithRightConstant<language::minus_op>(f, g);
+}
+
+std::shared_ptr<const IDiscreteFunction>
+operator-(const std::shared_ptr<const IDiscreteFunction>& f, const TinyVector<2>& g)
+{
+  return applyBinaryOperationWithRightConstant<language::minus_op>(f, g);
+}
+
+std::shared_ptr<const IDiscreteFunction>
+operator-(const std::shared_ptr<const IDiscreteFunction>& f, const TinyVector<3>& g)
+{
+  return applyBinaryOperationWithRightConstant<language::minus_op>(f, g);
+}
+
+std::shared_ptr<const IDiscreteFunction>
+operator-(const std::shared_ptr<const IDiscreteFunction>& f, const TinyMatrix<1>& g)
+{
+  return applyBinaryOperationWithRightConstant<language::minus_op>(f, g);
+}
+
+std::shared_ptr<const IDiscreteFunction>
+operator-(const std::shared_ptr<const IDiscreteFunction>& f, const TinyMatrix<2>& g)
+{
+  return applyBinaryOperationWithRightConstant<language::minus_op>(f, g);
+}
+
+std::shared_ptr<const IDiscreteFunction>
+operator-(const std::shared_ptr<const IDiscreteFunction>& f, const TinyMatrix<3>& g)
+{
+  return applyBinaryOperationWithRightConstant<language::minus_op>(f, g);
+}
+
 std::shared_ptr<const IDiscreteFunction>
 operator*(const double& a, const std::shared_ptr<const IDiscreteFunction>& f)
 {
@@ -751,3 +947,9 @@ operator*(const std::shared_ptr<const IDiscreteFunction>& a, const TinyMatrix<3>
 {
   return applyBinaryOperationWithRightConstant<language::multiply_op>(a, A);
 }
+
+std::shared_ptr<const IDiscreteFunction>
+operator/(const double& a, const std::shared_ptr<const IDiscreteFunction>& f)
+{
+  return applyBinaryOperationWithLeftConstant<language::divide_op>(a, f);
+}
diff --git a/src/language/utils/EmbeddedIDiscreteFunctionOperators.hpp b/src/language/utils/EmbeddedIDiscreteFunctionOperators.hpp
index 7969828000c4440ea9aa9d36014ee18d55d643c1..128746175ccd894957382d13d5a15ce8e8ff7a14 100644
--- a/src/language/utils/EmbeddedIDiscreteFunctionOperators.hpp
+++ b/src/language/utils/EmbeddedIDiscreteFunctionOperators.hpp
@@ -8,20 +8,102 @@
 
 class IDiscreteFunction;
 
+// sum
 std::shared_ptr<const IDiscreteFunction> operator+(const std::shared_ptr<const IDiscreteFunction>&,
                                                    const std::shared_ptr<const IDiscreteFunction>&);
 
+std::shared_ptr<const IDiscreteFunction> operator+(const double&, const std::shared_ptr<const IDiscreteFunction>&);
+
+std::shared_ptr<const IDiscreteFunction> operator+(const std::shared_ptr<const IDiscreteFunction>&, const double&);
+
+std::shared_ptr<const IDiscreteFunction> operator+(const TinyVector<1>&,
+                                                   const std::shared_ptr<const IDiscreteFunction>&);
+
+std::shared_ptr<const IDiscreteFunction> operator+(const TinyVector<2>&,
+                                                   const std::shared_ptr<const IDiscreteFunction>&);
+
+std::shared_ptr<const IDiscreteFunction> operator+(const TinyVector<3>&,
+                                                   const std::shared_ptr<const IDiscreteFunction>&);
+
+std::shared_ptr<const IDiscreteFunction> operator+(const TinyMatrix<1>&,
+                                                   const std::shared_ptr<const IDiscreteFunction>&);
+
+std::shared_ptr<const IDiscreteFunction> operator+(const TinyMatrix<2>&,
+                                                   const std::shared_ptr<const IDiscreteFunction>&);
+
+std::shared_ptr<const IDiscreteFunction> operator+(const TinyMatrix<3>&,
+                                                   const std::shared_ptr<const IDiscreteFunction>&);
+
+std::shared_ptr<const IDiscreteFunction> operator+(const std::shared_ptr<const IDiscreteFunction>&,
+                                                   const TinyVector<1>&);
+
+std::shared_ptr<const IDiscreteFunction> operator+(const std::shared_ptr<const IDiscreteFunction>&,
+                                                   const TinyVector<2>&);
+
+std::shared_ptr<const IDiscreteFunction> operator+(const std::shared_ptr<const IDiscreteFunction>&,
+                                                   const TinyVector<3>&);
+
+std::shared_ptr<const IDiscreteFunction> operator+(const std::shared_ptr<const IDiscreteFunction>&,
+                                                   const TinyMatrix<1>&);
+
+std::shared_ptr<const IDiscreteFunction> operator+(const std::shared_ptr<const IDiscreteFunction>&,
+                                                   const TinyMatrix<2>&);
+
+std::shared_ptr<const IDiscreteFunction> operator+(const std::shared_ptr<const IDiscreteFunction>&,
+                                                   const TinyMatrix<3>&);
+
+// difference
 std::shared_ptr<const IDiscreteFunction> operator-(const std::shared_ptr<const IDiscreteFunction>&,
                                                    const std::shared_ptr<const IDiscreteFunction>&);
 
-std::shared_ptr<const IDiscreteFunction> operator*(const std::shared_ptr<const IDiscreteFunction>&,
+std::shared_ptr<const IDiscreteFunction> operator-(const double&, const std::shared_ptr<const IDiscreteFunction>&);
+
+std::shared_ptr<const IDiscreteFunction> operator-(const std::shared_ptr<const IDiscreteFunction>&, const double&);
+
+std::shared_ptr<const IDiscreteFunction> operator-(const TinyVector<1>&,
                                                    const std::shared_ptr<const IDiscreteFunction>&);
 
-std::shared_ptr<const IDiscreteFunction> operator/(const std::shared_ptr<const IDiscreteFunction>&,
+std::shared_ptr<const IDiscreteFunction> operator-(const TinyVector<2>&,
+                                                   const std::shared_ptr<const IDiscreteFunction>&);
+
+std::shared_ptr<const IDiscreteFunction> operator-(const TinyVector<3>&,
+                                                   const std::shared_ptr<const IDiscreteFunction>&);
+
+std::shared_ptr<const IDiscreteFunction> operator-(const TinyMatrix<1>&,
+                                                   const std::shared_ptr<const IDiscreteFunction>&);
+
+std::shared_ptr<const IDiscreteFunction> operator-(const TinyMatrix<2>&,
+                                                   const std::shared_ptr<const IDiscreteFunction>&);
+
+std::shared_ptr<const IDiscreteFunction> operator-(const TinyMatrix<3>&,
+                                                   const std::shared_ptr<const IDiscreteFunction>&);
+
+std::shared_ptr<const IDiscreteFunction> operator-(const std::shared_ptr<const IDiscreteFunction>&,
+                                                   const TinyVector<1>&);
+
+std::shared_ptr<const IDiscreteFunction> operator-(const std::shared_ptr<const IDiscreteFunction>&,
+                                                   const TinyVector<2>&);
+
+std::shared_ptr<const IDiscreteFunction> operator-(const std::shared_ptr<const IDiscreteFunction>&,
+                                                   const TinyVector<3>&);
+
+std::shared_ptr<const IDiscreteFunction> operator-(const std::shared_ptr<const IDiscreteFunction>&,
+                                                   const TinyMatrix<1>&);
+
+std::shared_ptr<const IDiscreteFunction> operator-(const std::shared_ptr<const IDiscreteFunction>&,
+                                                   const TinyMatrix<2>&);
+
+std::shared_ptr<const IDiscreteFunction> operator-(const std::shared_ptr<const IDiscreteFunction>&,
+                                                   const TinyMatrix<3>&);
+
+// product
+std::shared_ptr<const IDiscreteFunction> operator*(const std::shared_ptr<const IDiscreteFunction>&,
                                                    const std::shared_ptr<const IDiscreteFunction>&);
 
 std::shared_ptr<const IDiscreteFunction> operator*(const double&, const std::shared_ptr<const IDiscreteFunction>&);
 
+std::shared_ptr<const IDiscreteFunction> operator*(const std::shared_ptr<const IDiscreteFunction>&, const double&);
+
 std::shared_ptr<const IDiscreteFunction> operator*(const TinyMatrix<1>&,
                                                    const std::shared_ptr<const IDiscreteFunction>&);
 
@@ -49,4 +131,10 @@ std::shared_ptr<const IDiscreteFunction> operator*(const std::shared_ptr<const I
 std::shared_ptr<const IDiscreteFunction> operator*(const std::shared_ptr<const IDiscreteFunction>&,
                                                    const TinyMatrix<3>&);
 
+// ratio
+std::shared_ptr<const IDiscreteFunction> operator/(const double&, const std::shared_ptr<const IDiscreteFunction>&);
+
+std::shared_ptr<const IDiscreteFunction> operator/(const std::shared_ptr<const IDiscreteFunction>&,
+                                                   const std::shared_ptr<const IDiscreteFunction>&);
+
 #endif   // EMBEDDED_I_DISCRETE_FUNCTION_OPERATORS_HPP