From a05121c6be1e85e61b5c310ec7d5e301502e4400 Mon Sep 17 00:00:00 2001
From: IvBu <ivan.buntic@iws.uni-stuttgart.de>
Date: Thu, 27 Feb 2025 15:31:21 +0100
Subject: [PATCH] [doc] Add wiki page on custom input data.

---
 doc/doxygen/DoxygenDumuxLayout.xml     |  1 +
 doc/doxygen/pages/custom-input-data.md | 87 ++++++++++++++++++++++++++
 2 files changed, 88 insertions(+)
 create mode 100644 doc/doxygen/pages/custom-input-data.md

diff --git a/doc/doxygen/DoxygenDumuxLayout.xml b/doc/doxygen/DoxygenDumuxLayout.xml
index dc5de16a07..61222ca776 100644
--- a/doc/doxygen/DoxygenDumuxLayout.xml
+++ b/doc/doxygen/DoxygenDumuxLayout.xml
@@ -34,6 +34,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
       <tab type="user" url="@ref developing-dumux" visible="yes" title="Developing Dumux" intro=""/>
       <tab type="user" url="@ref building-the-documentation" visible="yes" title="Build doxygen documentation" intro=""/>
       <tab type="user" url="@ref changing-property-name" visible="yes" title="Changing property name" intro=""/>
+      <tab type="user" url="@ref custom-input-data" visible="yes" title="Custom input data" intro=""/>
     </tab>
     <tab type="user" url="@ref citelist" visible="yes" title="Bibliography" intro=""/>
     <tab type="namespaces" visible="yes" title="">
diff --git a/doc/doxygen/pages/custom-input-data.md b/doc/doxygen/pages/custom-input-data.md
new file mode 100644
index 0000000000..c29f7c17c9
--- /dev/null
+++ b/doc/doxygen/pages/custom-input-data.md
@@ -0,0 +1,87 @@
+# Custom input data
+
+If you want to read custom user data, let's say to read a couple of check point for your time loop from file, here is some recipes of how to achieve that with simple helpers available in DuMu<sup>x</sup>.
+
+## Read an array of numbers
+If you have a simple text file containing a list of numbers
+```
+0.1
+0.2
+0.3
+0.4
+```
+You can read these numbers into a `std::vector<double>` like this
+```cpp
+#include <dumux/io/container.hh>
+
+const auto numbers = Dumux::readFileToContainer<std::vector<double>>("numbers.txt");
+```
+The file extension is arbitrary. The container type `std::vector<>` needs to support `begin()`, `end()`, and `push_back()`. It has to have an alias `value_type` (the type of the element, here `double`) and this type needs to have an overloaded `operator>>` to be constructible from an input stream. With similar code you can also multi-column data like this
+```
+0.1 0.2 0.3
+0.1 0.4 0.5
+```
+for example into a `std::vector<Dune::FieldVector<float, 3>>`
+```cpp
+#include <dune/common/fvector.hh>
+#include <dumux/io/container.hh>
+
+const auto coords = Dumux::readFileToContainer<std::vector<Dune::FieldVector<double, 3>>>("coords.txt");
+```
+
+## Read INI-style config data
+You can read config data (key-value data) using the `Dune::ParameterTreeParser`. This is the same type of file we use for DuMu<sup>x</sup> `input` files. Given a config file like this
+```ini
+[MyData]
+InjectionRate = 0.1 0.2 0.3 0.4
+BoundaryFlags = 3 4 5 6
+
+[Problem]
+EnableGravity = false
+```
+the data can be read into a `Dune::ParameterTree` like this
+```cpp
+#include <dune/common/parametertreeparser.hh>
+
+Dune::ParameterTree config;
+Dune::ParameterTreeParser::readINITree("config.ini", config);
+```
+Again, the file extension is arbitrary. You can retrieve data by casting it into another type like this
+```cpp
+const bool enableGravity = config.get<bool>("Problem.EnableGravity");
+const auto boundaryFlags = config.get<std::vector<int>>("MyData.BoundaryFlags");
+```
+
+## Read XML-formatted config data
+[XML (Extensible Markup Language)](https://en.wikipedia.org/wiki/XML) is a very flexible structured data format. You can read and write XML files using the [TinyXML-2](http://www.grinninglizard.com/tinyxml2/) library contained in DuMu<sup>x</sup>. For example, given an XML file like this
+```xml
+<?xml version="1.0"?>
+<!-- Simple custom data file -->
+<InputData>
+  <!-- Injection rates are in kg/s -->
+  <InjectionRates>
+  0.1 0.2 0.3 0.4
+  </InjectionRates>
+
+  <!-- BoundaryTypes: -1: no boundary, 0: Dirichlet, 1: Noflow, 2: Infiltration, 3: Outflow -->
+  <BoundaryTypes>
+  0 -1 -1 2
+  </BoundaryTypes>
+</InputData>
+```
+You can initialise the file reader like this
+```cpp
+#include <dumux/io/xml/tinyxml2.h>
+
+tinyxml2::XMLDocument xmlData;
+const auto returnCode = xmlData.LoadFile("mydata.xml"); // extension arbitrary
+if (returnCode != tinyxml2::XML_SUCCESS)
+    DUNE_THROW(Dune::IOError, "Couldn't open XML file.");
+```
+and read fields like this
+
+```cpp
+const tinyxml2::XMLElement* inputData = xmlData.FirstChildElement("InputData");
+std::stringstream injectionData(inputData->FirstChildElement("InjectionRates")->GetText());
+const auto injectionRates = readStreamToContainer<std::vector<double>>(injectionData);
+```
\ No newline at end of file
-- 
GitLab