From 3d956fbc296f8fd21e0cee86828cf140e8476886 Mon Sep 17 00:00:00 2001
From: Kilian Weishaupt <kilian.weishaupt@iws.uni-stuttgart.de>
Date: Thu, 10 Jun 2021 15:53:32 +0200
Subject: [PATCH] [python] Add gridvars

---
 dumux/python/discretization/gridvariables.hh | 112 +++++++++++++++++++
 python/dumux/discretization/__init__.py      |  28 ++++-
 2 files changed, 139 insertions(+), 1 deletion(-)
 create mode 100644 dumux/python/discretization/gridvariables.hh

diff --git a/dumux/python/discretization/gridvariables.hh b/dumux/python/discretization/gridvariables.hh
new file mode 100644
index 0000000000..2973015288
--- /dev/null
+++ b/dumux/python/discretization/gridvariables.hh
@@ -0,0 +1,112 @@
+// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+// vi: set et ts=4 sw=4 sts=4:
+/****************************************************************************
+ *   See the file COPYING for full copying permissions.                      *
+ *                                                                           *
+ *   This program is free software: you can redistribute it and/or modify    *
+ *   it under the terms of the GNU General Public License as published by    *
+ *   the Free Software Foundation, either version 3 of the License, or       *
+ *   (at your option) any later version.                                     *
+ *                                                                           *
+ *   This program is distributed in the hope that it will be useful,         *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the            *
+ *   GNU General Public License for more details.                            *
+ *                                                                           *
+ *   You should have received a copy of the GNU General Public License       *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.   *
+ *****************************************************************************/
+/*!
+ * \file
+ * \brief TODO: docme!
+ */
+
+#ifndef DUMUX_PYTHON_DISCRETIZATION_GRIDVARIABLES_HH
+#define DUMUX_PYTHON_DISCRETIZATION_GRIDVARIABLES_HH
+
+#include <memory>
+#include <dune/istl/bvector.hh>
+#include <dune/python/pybind11/pybind11.h>
+#include <dune/python/common/typeregistry.hh>
+#include <dumux/discretization/elementsolution.hh>
+
+namespace Dumux::Python {
+
+namespace Impl {
+
+template<class ElementSolution>
+void registerElementSolution(pybind11::handle scope)
+{
+    using namespace Dune::Python;
+
+    auto [cls, addedToRegistry] = insertClass<ElementSolution>(
+        scope, "ElementSolution",
+        GenerateTypeName(Dune::className<ElementSolution>()),
+        IncludeFiles{"dumux/discretization/elementsolution.hh"}
+    );
+
+    if (addedToRegistry)
+    {
+        using pybind11::operator""_a;
+
+        cls.def("__getitem__",
+                [](const ElementSolution& self, std::size_t i)
+                {
+                    if (i >= self.size())
+                        throw pybind11::index_error();
+                    return self[i];
+                });
+
+        cls.def_property_readonly("size", &ElementSolution::size);
+    }
+}
+
+} // end namespace Impl
+
+
+// see python/dumux/discretization/__init__.py for how this is used for JIT compilation
+template <class GV, class... Options>
+void registerGridVariables(pybind11::handle scope, pybind11::class_<GV, Options...> cls)
+{
+    using pybind11::operator""_a;
+
+    using Problem = typename GV::GridVolumeVariables::Problem;
+    using PrimaryVariables = typename GV::GridVolumeVariables::VolumeVariables::PrimaryVariables;
+    using GridGeometry = typename GV::GridGeometry;
+    using Element = typename GridGeometry::GridView::template Codim<0>::Entity;
+    using SolutionVector = Dune::BlockVector<PrimaryVariables>;
+
+    cls.def(pybind11::init([](std::shared_ptr<const Problem> problem,
+                              std::shared_ptr<const GridGeometry> gridGeometry){
+        return std::make_shared<GV>(problem, gridGeometry);
+    }));
+
+    cls.def("init", [](GV& self, const SolutionVector& sol) { return self.init(sol); });
+    cls.def("advanceTimeStep", &GV::advanceTimeStep);
+    cls.def_property_readonly("curGridVolVars", [](GV& self) { return self.curGridVolVars(); });
+    cls.def_property_readonly("gridFluxVarsCache", [](GV& self) { return self.gridFluxVarsCache(); });
+    cls.def_property_readonly("prevGridVolVars", [](GV& self) { return self.prevGridVolVars(); });
+    cls.def_property_readonly("gridGeometry", &GV::gridGeometry);
+
+    cls.def("updateAfterGridAdaption", [](GV& self, const SolutionVector& sol)
+            { return self.updateAfterGridAdaption(sol); }
+    );
+
+    cls.def("resetTimeStep", [](GV& self, const SolutionVector& sol)
+            { return self.resetTimeStep(sol); }
+    );
+
+    cls.def("update", [](GV& self, const SolutionVector& sol,
+                         const bool forceFluxCacheUpdate = false)
+            { return self.update(sol, forceFluxCacheUpdate); }
+    );
+
+    using ElementSolution = std::decay_t<decltype(elementSolution(std::declval<Element>(),
+                                                                  std::declval<SolutionVector>(),
+                                                                  std::declval<GridGeometry>()))>;
+    Impl::registerElementSolution<ElementSolution>(scope);
+}
+
+} // namespace Dumux::Python
+
+#endif
diff --git a/python/dumux/discretization/__init__.py b/python/dumux/discretization/__init__.py
index 238240b2ac..5c0e8b4298 100644
--- a/python/dumux/discretization/__init__.py
+++ b/python/dumux/discretization/__init__.py
@@ -3,7 +3,7 @@ from dune.common.hashit import hashIt
 
 # construct a GridGeometry from a gridView
 # the grid geometry is JIT compiled
-def GridGeometry(gridView, discMethod="cctpfa"):
+def GridGeometry(*, gridView, discMethod="cctpfa"):
     includes = gridView._includes + ["dumux/python/discretization/gridgeometry.hh"]
 
     if discMethod == "cctpfa":
@@ -20,3 +20,29 @@ def GridGeometry(gridView, discMethod="cctpfa"):
     generator = SimpleGenerator("GridGeometry", "Dumux::Python")
     module = generator.load(includes, typeName, moduleName, options=[holderType])
     return module.GridGeometry(gridView)
+
+
+# construct GridVariables
+# the grid variables is JIT compiled
+def GridVariables(*, problem, model):
+    includes = [
+        "dumux/discretization/fvgridvariables.hh",
+        "dumux/python/discretization/gridvariables.hh",
+    ]
+    GG = "Dumux::GetPropType<{}, Dumux::Properties::GridGeometry>".format(model.getTypeTag())
+    GVV = "Dumux::GetPropType<{}, Dumux::Properties::GridVolumeVariables>".format(
+        model.getTypeTag()
+    )
+    GFC = "Dumux::GetPropType<{}, Dumux::Properties::GridFluxVariablesCache>".format(
+        model.getTypeTag()
+    )
+    typeName = "Dumux::FVGridVariables<{}, {}, {}>".format(GG, GVV, GFC)
+
+    moduleName = "gridvariables_" + hashIt(typeName)
+    holderType = "std::shared_ptr<{}>".format(typeName)
+    generator = SimpleGenerator("GridVariables", "Dumux::Python")
+    module = generator.load(
+        includes, typeName, moduleName, options=[holderType], preamble=model.getProperties()
+    )
+    module.GridVariables._model = property(lambda self: model)
+    return module.GridVariables(problem, problem.gridGeometry())
-- 
GitLab