From 366e029cdde1eb1369819146819d5e8b7f658429 Mon Sep 17 00:00:00 2001
From: Kilian Weishaupt <kilian.weishaupt@iws.uni-stuttgart.de>
Date: Tue, 8 Jun 2021 17:36:05 +0200
Subject: [PATCH] [python] Add FVAssembler

---
 dumux/python/CMakeLists.txt          |  1 +
 dumux/python/assembly/CMakeLists.txt |  3 ++
 dumux/python/assembly/fvassembler.hh | 77 ++++++++++++++++++++++++++++
 python/dumux/CMakeLists.txt          |  1 +
 python/dumux/assembly/CMakeLists.txt |  3 ++
 python/dumux/assembly/__init__.py    | 31 +++++++++++
 6 files changed, 116 insertions(+)
 create mode 100644 dumux/python/assembly/CMakeLists.txt
 create mode 100644 dumux/python/assembly/fvassembler.hh
 create mode 100644 python/dumux/assembly/CMakeLists.txt
 create mode 100644 python/dumux/assembly/__init__.py

diff --git a/dumux/python/CMakeLists.txt b/dumux/python/CMakeLists.txt
index 4f95771a66..82890da7ca 100644
--- a/dumux/python/CMakeLists.txt
+++ b/dumux/python/CMakeLists.txt
@@ -1,2 +1,3 @@
+add_subdirectory(assembly)
 add_subdirectory(common)
 add_subdirectory(discretization)
diff --git a/dumux/python/assembly/CMakeLists.txt b/dumux/python/assembly/CMakeLists.txt
new file mode 100644
index 0000000000..9e57d351c1
--- /dev/null
+++ b/dumux/python/assembly/CMakeLists.txt
@@ -0,0 +1,3 @@
+file(GLOB DUMUX_PYTHON_ASSEMBLY_HEADERS *.hh *.inc)
+install(FILES ${DUMUX_PYTHON_ASSEMBLY_HEADERS}
+        DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dumux/python/assembly)
diff --git a/dumux/python/assembly/fvassembler.hh b/dumux/python/assembly/fvassembler.hh
new file mode 100644
index 0000000000..5359b88e3a
--- /dev/null
+++ b/dumux/python/assembly/fvassembler.hh
@@ -0,0 +1,77 @@
+// -*- 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_COMMON_FVASSEMBLER_HH
+#define DUMUX_PYTHON_COMMON_FVASSEMBLER_HH
+
+#include <dune/python/pybind11/pybind11.h>
+#include <dune/python/pybind11/stl.h>
+
+namespace Dumux::Python {
+
+// Python wrapper for the FVAssembler C++ class
+template<class FVAssembler, class... options>
+void registerFVAssembler(pybind11::handle scope, pybind11::class_<FVAssembler, options...> cls)
+{
+    using pybind11::operator""_a;
+
+    using Problem = typename FVAssembler::Problem;
+    using GridGeometry = typename FVAssembler::GridGeometry;
+    using GridVariables = typename FVAssembler::GridVariables;
+    using SolutionVector = typename FVAssembler::ResidualType;
+
+    static_assert(std::is_same_v<GridGeometry, typename Problem::GridGeometry>);
+    cls.def(pybind11::init([](std::shared_ptr<const Problem> problem,
+                              std::shared_ptr<const GridGeometry> gridGeometry,
+                              std::shared_ptr<GridVariables> gridVariables){
+        return std::make_shared<FVAssembler>(problem, gridGeometry, gridVariables);
+    }));
+
+    // TODO assembler with time loop
+
+    cls.def_property_readonly("numDofs", &FVAssembler::numDofs);
+    cls.def_property_readonly("problem", &FVAssembler::problem);
+    cls.def_property_readonly("gridGeometry", &FVAssembler::gridGeometry);
+    cls.def_property_readonly("gridView", &FVAssembler::gridView);
+    cls.def_property_readonly("jacobian", &FVAssembler::jacobian);
+    cls.def_property_readonly("residual", &FVAssembler::residual);
+    cls.def_property_readonly("prevSol", &FVAssembler::prevSol);
+    cls.def_property_readonly("isStationaryProblem", &FVAssembler::isStationaryProblem);
+    cls.def_property_readonly("gridVariables", [](FVAssembler& self) { return self.gridVariables(); });
+
+    cls.def("updateGridVariables", [](FVAssembler& self, const SolutionVector& curSol) {
+        self.updateGridVariables(curSol);
+    });
+
+    cls.def("assembleResidual", [](FVAssembler& self, const SolutionVector& curSol) {
+        self.assembleResidual(curSol);
+    });
+
+    cls.def("assembleJacobianAndResidual", [](FVAssembler& self, const SolutionVector& curSol) {
+        self.assembleJacobianAndResidual(curSol);
+    });
+}
+
+} // end namespace Dumux::Python
+
+#endif
diff --git a/python/dumux/CMakeLists.txt b/python/dumux/CMakeLists.txt
index e11f39eed6..55e5571499 100644
--- a/python/dumux/CMakeLists.txt
+++ b/python/dumux/CMakeLists.txt
@@ -1,3 +1,4 @@
+add_subdirectory(assembly)
 add_subdirectory(common)
 add_subdirectory(discretization)
 
diff --git a/python/dumux/assembly/CMakeLists.txt b/python/dumux/assembly/CMakeLists.txt
new file mode 100644
index 0000000000..aba7cb7775
--- /dev/null
+++ b/python/dumux/assembly/CMakeLists.txt
@@ -0,0 +1,3 @@
+add_python_targets(assembly
+  __init__
+)
diff --git a/python/dumux/assembly/__init__.py b/python/dumux/assembly/__init__.py
new file mode 100644
index 0000000000..b09a7f4776
--- /dev/null
+++ b/python/dumux/assembly/__init__.py
@@ -0,0 +1,31 @@
+from dune.generator.generator import SimpleGenerator
+from dune.common.hashit import hashIt
+
+
+def FVAssembler(*, problem, gridVariables, model, diffMethod="numeric", isImplicit=True):
+
+    TypeTag = model.getTypeTag()
+
+    if diffMethod == "numeric":
+        dm = "Dumux::DiffMethod::numeric"
+    elif diffMethod == "analytic":
+        dm = "Dumux::DiffMethod::analytic"
+    else:
+        raise ValueError(f"Unknown diffMethod {diffMethod}")
+
+    assemblerType = f"Dumux::FVAssembler<{TypeTag}, {dm}, {int(isImplicit)}>"
+    includes = (
+        problem._includes + problem.gridGeometry()._includes + ["dumux/assembly/fvassembler.hh"]
+    )
+    includes += ["dumux/python/assembly/fvassembler.hh"]
+
+    moduleName = "fvassembler_" + hashIt(assemblerType)
+    generator = SimpleGenerator("FVAssembler", "Dumux::Python")
+    module = generator.load(
+        includes,
+        assemblerType,
+        moduleName,
+        holder="std::shared_ptr",
+        preamble=model.getProperties(),
+    )
+    return module.FVAssembler(problem, problem.gridGeometry(), gridVariables)
-- 
GitLab