From 1621528ae7dc7bf9550a5d8eff8cc044090ab5a1 Mon Sep 17 00:00:00 2001
From: Christoph Lehmann <christoph.lehmann@ufz.de>
Date: Tue, 16 Aug 2016 17:02:31 +0200
Subject: [PATCH] [PL] added mesh node parameter

---
 ProcessLib/MeshElementParameter.cpp |  4 +-
 ProcessLib/MeshNodeParameter.cpp    | 48 +++++++++++++++++++++++
 ProcessLib/MeshNodeParameter.h      | 59 +++++++++++++++++++++++++++++
 ProcessLib/Parameter.cpp            |  8 ++++
 4 files changed, 117 insertions(+), 2 deletions(-)
 create mode 100644 ProcessLib/MeshNodeParameter.cpp
 create mode 100644 ProcessLib/MeshNodeParameter.h

diff --git a/ProcessLib/MeshElementParameter.cpp b/ProcessLib/MeshElementParameter.cpp
index b019c8fed58..98702d3c5f5 100644
--- a/ProcessLib/MeshElementParameter.cpp
+++ b/ProcessLib/MeshElementParameter.cpp
@@ -18,8 +18,8 @@ std::unique_ptr<ParameterBase> createMeshElementParameter(
     BaseLib::ConfigTree const& config, MeshLib::Mesh const& mesh)
 {
     //! \ogs_file_param{parameter__type}
-    config.checkConfigParameter("type", "MeshProperty");
-    //! \ogs_file_param{parameter__MeshProperty__field_name}
+    config.checkConfigParameter("type", "MeshElement");
+    //! \ogs_file_param{parameter__MeshElement__field_name}
     auto field_name = config.getConfigParameter<std::string>("field_name");
     DBUG("Using field_name %s", field_name.c_str());
 
diff --git a/ProcessLib/MeshNodeParameter.cpp b/ProcessLib/MeshNodeParameter.cpp
new file mode 100644
index 00000000000..db925c2bd1f
--- /dev/null
+++ b/ProcessLib/MeshNodeParameter.cpp
@@ -0,0 +1,48 @@
+/**
+ * \copyright
+ * Copyright (c) 2012-2016, OpenGeoSys Community (http://www.opengeosys.org)
+ *            Distributed under a Modified BSD License.
+ *              See accompanying file LICENSE.txt or
+ *              http://www.opengeosys.org/project/license
+ *
+ */
+
+#include "MeshNodeParameter.h"
+#include "BaseLib/ConfigTree.h"
+#include "BaseLib/Error.h"
+#include "MeshLib/Mesh.h"
+
+namespace ProcessLib
+{
+std::unique_ptr<ParameterBase> createMeshNodeParameter(
+    BaseLib::ConfigTree const& config, MeshLib::Mesh const& mesh)
+{
+    //! \ogs_file_param{parameter__type}
+    config.checkConfigParameter("type", "MeshNode");
+    //! \ogs_file_param{parameter__MeshNode__field_name}
+    auto field_name = config.getConfigParameter<std::string>("field_name");
+    DBUG("Using field_name %s", field_name.c_str());
+
+    if (!mesh.getProperties().hasPropertyVector(field_name)) {
+        OGS_FATAL("The required property %s does not exists in the mesh.",
+                  field_name.c_str());
+    }
+
+    // TODO other data types than only double
+    auto const& property =
+        mesh.getProperties().template getPropertyVector<double>(field_name);
+    if (!property) {
+        OGS_FATAL("The mesh property `%s' is not of the requested type.",
+                  field_name.c_str());
+    }
+
+    if (property->getMeshItemType() != MeshLib::MeshItemType::Node) {
+        OGS_FATAL("The mesh property `%s' is not a nodal property.",
+                  field_name.c_str());
+    }
+
+    return std::unique_ptr<ParameterBase>(
+        new MeshNodeParameter<double>(*property));
+}
+
+}  // ProcessLib
diff --git a/ProcessLib/MeshNodeParameter.h b/ProcessLib/MeshNodeParameter.h
new file mode 100644
index 00000000000..ccdf933a6a8
--- /dev/null
+++ b/ProcessLib/MeshNodeParameter.h
@@ -0,0 +1,59 @@
+/**
+ * \copyright
+ * Copyright (c) 2012-2016, OpenGeoSys Community (http://www.opengeosys.org)
+ *            Distributed under a Modified BSD License.
+ *              See accompanying file LICENSE.txt or
+ *              http://www.opengeosys.org/project/license
+ *
+ */
+
+#ifndef PROCESSLIB_MESHNODEPARAMETER_H
+#define PROCESSLIB_MESHNODEPARAMETER_H
+
+#include "Parameter.h"
+
+namespace MeshLib
+{
+template <typename T>
+class PropertyVector;
+}  // MeshLib
+
+namespace ProcessLib
+{
+/// A parameter represented by a mesh property vector.
+template <typename T>
+struct MeshNodeParameter final : public Parameter<T> {
+    MeshNodeParameter(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.getNodeID();
+        assert(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;
+    mutable std::vector<double> _cache;
+};
+
+std::unique_ptr<ParameterBase> createMeshNodeParameter(
+    BaseLib::ConfigTree const& config, MeshLib::Mesh const& mesh);
+
+}  // ProcessLib
+
+#endif  // PROCESSLIB_MESHNODEPARAMETER_H
diff --git a/ProcessLib/Parameter.cpp b/ProcessLib/Parameter.cpp
index 48b217a50ac..a7fcc2b63c7 100644
--- a/ProcessLib/Parameter.cpp
+++ b/ProcessLib/Parameter.cpp
@@ -13,6 +13,7 @@
 
 #include "ConstantParameter.h"
 #include "MeshElementParameter.h"
+#include "MeshNodeParameter.h"
 
 namespace ProcessLib
 {
@@ -41,6 +42,13 @@ std::unique_ptr<ParameterBase> createParameter(
         param->name = name;
         return param;
     }
+    else if (type == "MeshNode")
+    {
+        INFO("MeshElementParameter: %s", name.c_str());
+        auto param = createMeshNodeParameter(config, *meshes.front());
+        param->name = name;
+        return param;
+    }
     else
     {
         OGS_FATAL("Cannot construct property of given type \'%s\'.",
-- 
GitLab