diff --git a/Applications/CMakeLists.txt b/Applications/CMakeLists.txt
index 07dd8e2895db7d981471265a0d01159980be19bd..38907f9f81ff5d74a304efadffda83c6d9abcb68 100644
--- a/Applications/CMakeLists.txt
+++ b/Applications/CMakeLists.txt
@@ -1,3 +1,5 @@
+include(${PROJECT_SOURCE_DIR}/scripts/cmake/OGSEnabledElements.cmake)
+
 add_subdirectory(ApplicationsLib)
 
 if(OGS_BUILD_UTILS AND NOT IS_SUBPROJECT)
diff --git a/AssemblerLib/CMakeLists.txt b/AssemblerLib/CMakeLists.txt
index ff62c445190b7a274db79f79b2fc446e3e08b1ea..bf04b9b5ede969a54418e5779886b31a7b6ba150 100644
--- a/AssemblerLib/CMakeLists.txt
+++ b/AssemblerLib/CMakeLists.txt
@@ -1,3 +1,5 @@
+include(${PROJECT_SOURCE_DIR}/scripts/cmake/OGSEnabledElements.cmake)
+
 #Source files grouped by a directory
 GET_SOURCE_FILES(SOURCES_ASSEMBLERLIB)
 set(SOURCES ${SOURCES_ASSEMBLERLIB})
diff --git a/AssemblerLib/LocalDataInitializer.h b/AssemblerLib/LocalDataInitializer.h
index 2a3bde8026e6e1e57671cfabb7f38d0ed27f5108..46f69d426960b4194af1976edd1956cff138b14a 100644
--- a/AssemblerLib/LocalDataInitializer.h
+++ b/AssemblerLib/LocalDataInitializer.h
@@ -19,22 +19,97 @@
 
 #include "NumLib/Fem/Integration/GaussIntegrationPolicy.h"
 
-#include "NumLib/Fem/ShapeFunction/ShapeHex20.h"
-#include "NumLib/Fem/ShapeFunction/ShapeHex8.h"
+#ifndef OGS_MAX_ELEMENT_DIM
+static_assert(false, "The macro OGS_MAX_ELEMENT_DIM is undefined.");
+#endif
+
+#ifndef OGS_MAX_ELEMENT_ORDER
+static_assert(false, "The macro OGS_MAX_ELEMENT_ORDER is undefined.");
+#endif
+
+// The following macros decide which element types will be compiled, i.e.
+// which element types will be available for use in simulations.
+
+#ifdef OGS_ENABLE_ELEMENT_SIMPLEX
+#define ENABLED_ELEMENT_TYPE_SIMPLEX 1u
+#else
+#define ENABLED_ELEMENT_TYPE_SIMPLEX 0u
+#endif
+
+#ifdef OGS_ENABLE_ELEMENT_CUBOID
+#define ENABLED_ELEMENT_TYPE_CUBOID 1u << 1
+#else
+#define ENABLED_ELEMENT_TYPE_CUBOID 0u
+#endif
+
+#ifdef OGS_ENABLE_ELEMENT_PRISM
+#define ENABLED_ELEMENT_TYPE_PRISM 1u << 2
+#else
+#define ENABLED_ELEMENT_TYPE_PRISM   0u
+#endif
+
+#ifdef OGS_ENABLE_ELEMENT_PYRAMID
+#define ENABLED_ELEMENT_TYPE_PYRAMID 1u << 3
+#else
+#define ENABLED_ELEMENT_TYPE_PYRAMID 0u
+#endif
+
+// Dependent element types.
+// Faces of tets, pyramids and prisms are triangles
+#define ENABLED_ELEMENT_TYPE_TRI  ((ENABLED_ELEMENT_TYPE_SIMPLEX) | (ENABLED_ELEMENT_TYPE_PYRAMID) \
+                                  |(ENABLED_ELEMENT_TYPE_PRISM))
+// Faces of hexes, pyramids and prisms are quads
+#define ENABLED_ELEMENT_TYPE_QUAD ((ENABLED_ELEMENT_TYPE_CUBOID) | (ENABLED_ELEMENT_TYPE_PYRAMID) \
+                                  |(ENABLED_ELEMENT_TYPE_PRISM))
+// Faces of triangles and quads are lines
+#define ENABLED_ELEMENT_TYPE_LINE ((ENABLED_ELEMENT_TYPE_TRI) | (ENABLED_ELEMENT_TYPE_QUAD))
+
+// All enabled element types
+#define OGS_ENABLED_ELEMENTS \
+    ( (ENABLED_ELEMENT_TYPE_SIMPLEX) \
+    | (ENABLED_ELEMENT_TYPE_CUBOID ) \
+    | (ENABLED_ELEMENT_TYPE_PYRAMID) \
+    | (ENABLED_ELEMENT_TYPE_PRISM  ) )
+
+
+// Include only what is needed (Well, the conditions are not sharp).
+#if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_LINE) != 0
 #include "NumLib/Fem/ShapeFunction/ShapeLine2.h"
 #include "NumLib/Fem/ShapeFunction/ShapeLine3.h"
 #include "NumLib/Fem/ShapeFunction/ShapePoint1.h"
-#include "NumLib/Fem/ShapeFunction/ShapePrism15.h"
-#include "NumLib/Fem/ShapeFunction/ShapePrism6.h"
-#include "NumLib/Fem/ShapeFunction/ShapePyra13.h"
-#include "NumLib/Fem/ShapeFunction/ShapePyra5.h"
-#include "NumLib/Fem/ShapeFunction/ShapeQuad4.h"
-#include "NumLib/Fem/ShapeFunction/ShapeQuad8.h"
-#include "NumLib/Fem/ShapeFunction/ShapeQuad9.h"
+#endif
+
+#if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_SIMPLEX) != 0
 #include "NumLib/Fem/ShapeFunction/ShapeTet10.h"
 #include "NumLib/Fem/ShapeFunction/ShapeTet4.h"
+#endif
+
+#if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_TRI) != 0
 #include "NumLib/Fem/ShapeFunction/ShapeTri3.h"
 #include "NumLib/Fem/ShapeFunction/ShapeTri6.h"
+#endif
+
+#if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_CUBOID) != 0
+#include "NumLib/Fem/ShapeFunction/ShapeHex20.h"
+#include "NumLib/Fem/ShapeFunction/ShapeHex8.h"
+#endif
+
+#if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_QUAD) != 0
+#include "NumLib/Fem/ShapeFunction/ShapeQuad4.h"
+#include "NumLib/Fem/ShapeFunction/ShapeQuad8.h"
+#include "NumLib/Fem/ShapeFunction/ShapeQuad9.h"
+#endif
+
+#if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_PRISM) != 0
+#include "NumLib/Fem/ShapeFunction/ShapePrism15.h"
+#include "NumLib/Fem/ShapeFunction/ShapePrism6.h"
+#endif
+
+#if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_PYRAMID) != 0
+#include "NumLib/Fem/ShapeFunction/ShapePyra13.h"
+#include "NumLib/Fem/ShapeFunction/ShapePyra5.h"
+#endif
+
 
 namespace AssemblerLib
 {
@@ -66,38 +141,110 @@ class LocalDataInitializer
 public:
     LocalDataInitializer()
     {
-        _builder[std::type_index(typeid(MeshLib::Hex20))] =
-            [](){ return new LAData<NumLib::ShapeHex20>; };
-        _builder[std::type_index(typeid(MeshLib::Hex))] =
-            [](){ return new LAData<NumLib::ShapeHex8>; };
+        // /// Lines and points ///////////////////////////////////
+
+#if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_LINE) != 0 \
+    && OGS_MAX_ELEMENT_DIM >= 0 && OGS_MAX_ELEMENT_ORDER >= 1
+        _builder[std::type_index(typeid(MeshLib::Point))] =
+            [](){ return new LAData<NumLib::ShapePoint1>; };
+#endif
+
+#if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_LINE) != 0 \
+        && OGS_MAX_ELEMENT_DIM >= 1 && OGS_MAX_ELEMENT_ORDER >= 1
         _builder[std::type_index(typeid(MeshLib::Line))] =
             [](){ return new LAData<NumLib::ShapeLine2>; };
+#endif
+
+#if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_LINE) != 0 \
+    && OGS_MAX_ELEMENT_DIM >= 1 && OGS_MAX_ELEMENT_ORDER >= 2
         _builder[std::type_index(typeid(MeshLib::Line3))] =
             [](){ return new LAData<NumLib::ShapeLine3>; };
-        _builder[std::type_index(typeid(MeshLib::Point))] =
-            [](){ return new LAData<NumLib::ShapePoint1>; };
-        _builder[std::type_index(typeid(MeshLib::Prism15))] =
-            [](){ return new LAData<NumLib::ShapePrism15>; };
-        _builder[std::type_index(typeid(MeshLib::Prism))] =
-            [](){ return new LAData<NumLib::ShapePrism6>; };
-        _builder[std::type_index(typeid(MeshLib::Pyramid13))] =
-            [](){ return new LAData<NumLib::ShapePyra13>; };
-        _builder[std::type_index(typeid(MeshLib::Pyramid))] =
-            [](){ return new LAData<NumLib::ShapePyra5>; };
+#endif
+
+
+        // /// Quads and Hexahedra ///////////////////////////////////
+
+#if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_QUAD) != 0 \
+    && OGS_MAX_ELEMENT_DIM >= 2 && OGS_MAX_ELEMENT_ORDER >= 1
         _builder[std::type_index(typeid(MeshLib::Quad))] =
             [](){ return new LAData<NumLib::ShapeQuad4>; };
+#endif
+
+#if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_CUBOID) != 0 \
+    && OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 1
+        _builder[std::type_index(typeid(MeshLib::Hex))] =
+            [](){ return new LAData<NumLib::ShapeHex8>; };
+#endif
+
+#if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_QUAD) != 0 \
+    && OGS_MAX_ELEMENT_DIM >= 2 && OGS_MAX_ELEMENT_ORDER >= 2
         _builder[std::type_index(typeid(MeshLib::Quad8))] =
             [](){ return new LAData<NumLib::ShapeQuad8>; };
         _builder[std::type_index(typeid(MeshLib::Quad9))] =
             [](){ return new LAData<NumLib::ShapeQuad9>; };
-        _builder[std::type_index(typeid(MeshLib::Tet10))] =
-            [](){ return new LAData<NumLib::ShapeTet10>; };
-        _builder[std::type_index(typeid(MeshLib::Tet))] =
-            [](){ return new LAData<NumLib::ShapeTet4>; };
+#endif
+
+#if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_CUBOID) != 0 \
+    && OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 2
+        _builder[std::type_index(typeid(MeshLib::Hex20))] =
+            [](){ return new LAData<NumLib::ShapeHex20>; };
+#endif
+
+
+        // /// Simplices ////////////////////////////////////////////////
+
+#if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_TRI) != 0 \
+    && OGS_MAX_ELEMENT_DIM >= 2 && OGS_MAX_ELEMENT_ORDER >= 1
         _builder[std::type_index(typeid(MeshLib::Tri))] =
             [](){ return new LAData<NumLib::ShapeTri3>; };
+#endif
+
+#if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_SIMPLEX) != 0 \
+    && OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 1
+        _builder[std::type_index(typeid(MeshLib::Tet))] =
+            [](){ return new LAData<NumLib::ShapeTet4>; };
+#endif
+
+#if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_TRI) != 0 \
+    && OGS_MAX_ELEMENT_DIM >= 2 && OGS_MAX_ELEMENT_ORDER >= 2
         _builder[std::type_index(typeid(MeshLib::Tri6))] =
             [](){ return new LAData<NumLib::ShapeTri6>; };
+#endif
+
+#if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_SIMPLEX) != 0 \
+    && OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 2
+        _builder[std::type_index(typeid(MeshLib::Tet10))] =
+            [](){ return new LAData<NumLib::ShapeTet10>; };
+#endif
+
+
+        // /// Prisms ////////////////////////////////////////////////////
+
+#if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_PRISM) != 0 \
+    && OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 1
+        _builder[std::type_index(typeid(MeshLib::Prism))] =
+            [](){ return new LAData<NumLib::ShapePrism6>; };
+#endif
+
+#if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_PRISM) != 0 \
+    && OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 2
+        _builder[std::type_index(typeid(MeshLib::Prism15))] =
+            [](){ return new LAData<NumLib::ShapePrism15>; };
+#endif
+
+        // /// Pyramids //////////////////////////////////////////////////
+
+#if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_PYRAMID) != 0 \
+    && OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 1
+        _builder[std::type_index(typeid(MeshLib::Pyramid))] =
+            [](){ return new LAData<NumLib::ShapePyra5>; };
+#endif
+
+#if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_PYRAMID) != 0 \
+    && OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 2
+        _builder[std::type_index(typeid(MeshLib::Pyramid13))] =
+            [](){ return new LAData<NumLib::ShapePyra13>; };
+#endif
     }
 
     /// Sets the provided data_ptr to the newly created local assembler data and
@@ -106,8 +253,18 @@ public:
     void operator()(const MeshLib::Element& e,
         LocalAssemblerDataInterface_<GlobalMatrix_, GlobalVector_>*& data_ptr, Args_&&... args)
     {
-        data_ptr = _builder[std::type_index(typeid(e))]();
-        data_ptr->init(e, std::forward<Args_>(args)...);
+        auto const type_idx = std::type_index(typeid(e));
+        auto it = _builder.find(type_idx);
+
+        if (it != _builder.end()) {
+            data_ptr = it->second();
+            data_ptr->init(e, std::forward<Args_>(args)...);
+        } else {
+            ERR("You are trying to build a local assembler for an unknown mesh element type (%s)."
+                " Maybe you have disabled this mesh element type in your build configuration.",
+                type_idx.name());
+            std::abort();
+        }
     }
 
 private:
@@ -120,4 +277,14 @@ private:
 
 }   // namespace AssemblerLib
 
+
+#undef ENABLED_ELEMENT_TYPE_SIMPLEX
+#undef ENABLED_ELEMENT_TYPE_CUBOID
+#undef ENABLED_ELEMENT_TYPE_PYRAMID
+#undef ENABLED_ELEMENT_TYPE_PRISM
+#undef ENABLED_ELEMENT_TYPE_LINE
+#undef ENABLED_ELEMENT_TYPE_TRI
+#undef ENABLED_ELEMENT_TYPE_QUAD
+#undef OGS_ENABLED_ELEMENTS
+
 #endif  // ASSEMBLER_LIB_LOCALDATAINITIALIZER_H_
diff --git a/CMakeLists.txt b/CMakeLists.txt
index aded93597f610ef468250d9551beb44c129115c5..d3ac9ed761922d197531513d7dd983a1774eca9e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -107,6 +107,14 @@ set_property(CACHE
 	OGS_LIB_EIGEN
 	PROPERTY STRINGS "Default" "System" "Local")
 
+# Options controlling which FEM elements will be compiled
+set(OGS_MAX_ELEMENT_DIM   3 CACHE STRING "Maximum dimension of FEM elements to be built.")
+set(OGS_MAX_ELEMENT_ORDER 2 CACHE STRING "Maximum order of FEM elements to be built.")
+option(OGS_ENABLE_ELEMENT_SIMPLEX "Build FEM elements for simplices (triangles, tetrahedra)." ON)
+option(OGS_ENABLE_ELEMENT_CUBOID  "Build FEM elements for cuboids (quads, hexahedra)." ON)
+option(OGS_ENABLE_ELEMENT_PRISM   "Build FEM elements for prisms." ON)
+option(OGS_ENABLE_ELEMENT_PYRAMID "Build FEM elements for pyramids." ON)
+
 ###################
 ### Definitions ###
 ###################
diff --git a/FileIO/CMakeLists.txt b/FileIO/CMakeLists.txt
index 0b680154fd2fcdbd813a610c67074fb4ce0f4554..9ebfdfb669cd194a59433c1edecdd4a1f7e411b6 100644
--- a/FileIO/CMakeLists.txt
+++ b/FileIO/CMakeLists.txt
@@ -49,6 +49,8 @@ if(OGS_USE_PETSC)
 	set(SOURCES ${SOURCES} ${SOURCES_MPI_IO})
 endif()
 
+include(${PROJECT_SOURCE_DIR}/scripts/cmake/OGSEnabledElements.cmake)
+
 # Create the library
 add_library(FileIO STATIC ${SOURCES})
 
diff --git a/ProcessLib/CMakeLists.txt b/ProcessLib/CMakeLists.txt
index af6c480143a09351b371ecabb7cdf922a8459fc4..d9c60892dc0031b347a11b4ee421f989d4835e92 100644
--- a/ProcessLib/CMakeLists.txt
+++ b/ProcessLib/CMakeLists.txt
@@ -1,3 +1,5 @@
+include(${PROJECT_SOURCE_DIR}/scripts/cmake/OGSEnabledElements.cmake)
+
 # Source files
 GET_SOURCE_FILES(SOURCES)
 
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 33e6b3514974137da0e68473111a26286a0b4cb9..f0880be09ecd2830194c0b53948a9411f2fe7eca 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -1,3 +1,5 @@
+include(${PROJECT_SOURCE_DIR}/scripts/cmake/OGSEnabledElements.cmake)
+
 # VS2012 doesn't support correctly the tuples yet
 # See http://code.google.com/p/googletest/issues/detail?id=412
 if(MSVC)
diff --git a/scripts/cmake/OGSEnabledElements.cmake b/scripts/cmake/OGSEnabledElements.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..c805f16b38ba86562602b9142073b88ca244a181
--- /dev/null
+++ b/scripts/cmake/OGSEnabledElements.cmake
@@ -0,0 +1,24 @@
+# Definitions controlling which FEM elements will be compiled
+if(NOT OGS_MAX_ELEMENT_DIM MATCHES "^[0-3]$")
+  message(FATAL_ERROR "OGS_MAX_ELEMENT_DIM must be an integer between 0 and 3.")
+endif()
+add_definitions(-DOGS_MAX_ELEMENT_DIM=${OGS_MAX_ELEMENT_DIM})
+
+if(NOT OGS_MAX_ELEMENT_ORDER MATCHES "^[0-9]$")
+  message(FATAL_ERROR "OGS_MAX_ELEMENT_ORDER must be an integer.")
+endif()
+add_definitions(-DOGS_MAX_ELEMENT_ORDER=${OGS_MAX_ELEMENT_ORDER})
+
+
+if(OGS_ENABLE_ELEMENT_SIMPLEX)
+	add_definitions(-DOGS_ENABLE_ELEMENT_SIMPLEX)
+endif()
+if(OGS_ENABLE_ELEMENT_CUBOID)
+	add_definitions(-DOGS_ENABLE_ELEMENT_CUBOID)
+endif()
+if(OGS_ENABLE_ELEMENT_PRISM)
+	add_definitions(-DOGS_ENABLE_ELEMENT_PRISM)
+endif()
+if(OGS_ENABLE_ELEMENT_PYRAMID)
+	add_definitions(-DOGS_ENABLE_ELEMENT_PYRAMID)
+endif()