diff --git a/ProcessLib/ConstantParameter.h b/ProcessLib/ConstantParameter.h
index 4cb66a19d8808fa847cb9a6c2793dbc35e2957d9..54e79a2317ffbc7d03c41ccea5453848fe389ccd 100644
--- a/ProcessLib/ConstantParameter.h
+++ b/ProcessLib/ConstantParameter.h
@@ -18,6 +18,10 @@ namespace ProcessLib
 template <typename T>
 struct ConstantParameter final : public Parameter<T> {
     ConstantParameter(T const& value) : _value{{value}} {}
+
+    // TODO allow for different sizes
+    unsigned getNumberOfComponents() const { return 1; }
+
     std::vector<T> const& getTuple(
         double const /*t*/, SpatialPosition const& /*pos*/) const override
     {
@@ -25,7 +29,7 @@ struct ConstantParameter final : public Parameter<T> {
     }
 
 private:
-    std::vector<T> _value;
+    std::vector<T> const _value;
 };
 
 std::unique_ptr<ParameterBase> createConstantParameter(
diff --git a/ProcessLib/MeshElementParameter.cpp b/ProcessLib/MeshElementParameter.cpp
index f05dab9a44f650428386a4fcdd4c33d102c7ee15..b019c8fed5893bbfad3366d5fdb08685d35b7c04 100644
--- a/ProcessLib/MeshElementParameter.cpp
+++ b/ProcessLib/MeshElementParameter.cpp
@@ -32,7 +32,12 @@ std::unique_ptr<ParameterBase> createMeshElementParameter(
     auto const& property =
         mesh.getProperties().template getPropertyVector<double>(field_name);
     if (!property) {
-        OGS_FATAL("The required property %s is not of the requested type.",
+        OGS_FATAL("The mesh property `%s' is not of the requested type.",
+                  field_name.c_str());
+    }
+
+    if (property->getMeshItemType() != MeshLib::MeshItemType::Cell) {
+        OGS_FATAL("The mesh property `%s' is not an element property.",
                   field_name.c_str());
     }
 
diff --git a/ProcessLib/MeshElementParameter.h b/ProcessLib/MeshElementParameter.h
index bb4f8d6ded38a8e96fc53617d4103560f7ba2650..298065a64c7a8cf3599b64c7b3d787a821d7007a 100644
--- a/ProcessLib/MeshElementParameter.h
+++ b/ProcessLib/MeshElementParameter.h
@@ -25,22 +25,30 @@ template <typename T>
 struct MeshElementParameter final : public Parameter<T> {
     MeshElementParameter(MeshLib::PropertyVector<T> const& property)
         : _property(property)
+        , _cache(_property.getNumberOfComponents())
     {
     }
 
+    unsigned getNumberOfComponents() const override
+    {
+        return _property.getNumberOfComponents();
+    }
+
     std::vector<T> const& getTuple(double const /*t*/,
                                    SpatialPosition const& pos) const override
     {
         auto const e = pos.getElementID();
         assert(e);
-        _cache.front() = _property[*e];
+        auto const num_comp = _property.getNumberOfComponents();
+        for (std::size_t c=0; c<num_comp; ++c) {
+            _cache[c] = _property.getComponent(*e, c);
+        }
         return _cache;
     }
 
 private:
     MeshLib::PropertyVector<T> const& _property;
-    // TODO multi-component
-    mutable std::vector<double> _cache = std::vector<double>(1);
+    mutable std::vector<double> _cache;
 };
 
 std::unique_ptr<ParameterBase> createMeshElementParameter(
diff --git a/ProcessLib/Parameter.h b/ProcessLib/Parameter.h
index 7a464b58763d6d51f3b6d93a0cf8f031e0baf9c6..aec56e55794968995d12eed688988bfd4c284aee 100644
--- a/ProcessLib/Parameter.h
+++ b/ProcessLib/Parameter.h
@@ -36,16 +36,29 @@ struct ParameterBase
     std::string name;
 };
 
+/*! A Parameter is a function \f$ (t, x) \mapsto f(t, x) \in T^n \f$.
+ *
+ * Where \f$ t \f$ is the time and \f$ x \f$ is the SpatialPosition.
+ * \f$ n \f$ is the number of components of \f$f\f$'s results, i.e., 1 for a
+ * scalar parameter and >1 for a vectorial or tensorial parameter.
+ */
 template <typename T>
 struct Parameter : public ParameterBase
 {
     virtual ~Parameter() = default;
 
-    // TODO number of components
+    //! Returns the number of components this Parameter has at every position and
+    //! point in time.
+    virtual unsigned getNumberOfComponents() const = 0;
+
+    //! Returns the parameter value at the given time and position.
     virtual std::vector<T> const& getTuple(
         double const t, SpatialPosition const& pos) const = 0;
 };
 
+//! Constructs a new ParameterBase from the given configuration.
+//!
+//! The \c meshes vector is used to set up parameters from mesh input data.
 std::unique_ptr<ParameterBase> createParameter(
     BaseLib::ConfigTree const& config,
     const std::vector<MeshLib::Mesh*>& meshes);