From 1c52f16470a4a4466defe20e65c6f90d7690ad3e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Carsten=20Gr=C3=A4ser?= <graeser@math.fau.de>
Date: Fri, 7 Mar 2025 09:32:13 +0100
Subject: [PATCH] [examples][bugfix] Only use AdolC if it is available

---
 examples/biharmonic.cc      | 30 +++++++++++++++++++++---------
 examples/poisson-hermite.cc | 26 ++++++++++++++++++++++----
 2 files changed, 43 insertions(+), 13 deletions(-)

diff --git a/examples/biharmonic.cc b/examples/biharmonic.cc
index bb122c7e..78f159b6 100644
--- a/examples/biharmonic.cc
+++ b/examples/biharmonic.cc
@@ -32,7 +32,9 @@
 #include <dune/grid/io/file/vtk/subsamplingvtkwriter.hh>
 #endif
 
+#ifdef HAVE_ADOLC
 #include <dune/fufem/functions/adolcfunction.hh>
+#endif
 #include <dune/fufem/parallel/elementcoloring.hh>
 #include <dune/fufem/boundarypatch.hh>
 #include <dune/fufem/functiontools/boundarydofs.hh>
@@ -187,36 +189,46 @@ int main (int argc, char *argv[]) try
 
   auto pi = std::acos(-1.0);
 
+  using Domain = Dune::FieldVector<double, 2>;
+  using Range = double;
+  using DerivativeRange = Dune::FieldVector<double, 2>;
+  using SignatureTag = Dune::Functions::SignatureTag<Range(Domain)>;
+
 //  auto exactSol = [pi](const auto& x) { return std::pow(std::sin(pi*x[0]), 2.)*std::pow(std::sin(pi*x[1]), 2.); };
 //  auto rightHandSide = [exactSol,pi] (const auto& x) {
 //    return std::pow(pi, 4.)*(8.-24.*std::pow(std::sin(pi*x[0]), 2.)-24.*std::pow(std::sin(pi*x[1]), 2.) + 64*exactSol(x));
 //  };
-//  auto dirichletValuesC0 = [pi](const auto& x){
+//  auto dirichletFunctionValues = [pi](const auto& x){
 //    return 0.0;
 //  };
+//  auto dirichletValues = Dune::Fufem::makeAdolCFunction(SignatureTag(), dirichletFunctionValues);
 
 //  auto exactSol = [&](const auto& x) { return 16*x[0]*(x[0]-1)*x[1]*(x[1]-1); };
 //  auto rightHandSide = [] (const auto& x) { return 8*16;};
-//  auto dirichletValuesC0 = [&](const auto& x){
+//  auto dirichletFunctionValues = [&](const auto& x){
 //    return exactSol(x);
 //  };
+//  auto dirichletValues = Dune::Fufem::makeAdolCFunction(SignatureTag(), dirichletFunctionValues);
 
 //  auto rightHandSide = [] (const auto& x) { return 10;};
-//  auto dirichletValuesC0 = [pi](const auto& x){
+//  auto dirichletFunctionValues = [pi](const auto& x){
 //    using std::sin;
 //    return sin(2*pi*x[0]);
 //  };
+//  auto dirichletValues = Dune::Fufem::makeAdolCFunction(SignatureTag(), dirichletFunctionValues);
 
   auto rightHandSide = [] (const auto& x) {
     return 500;
   };
-  auto dirichletValuesC0 = [pi](const auto& x){
-    return 0.0;
-  };
 
-  // Make Dirichlet data differentiable, since this is required by local interpolation
-  using SignatureTag = Dune::Functions::SignatureTag<double(Dune::FieldVector<double,2>)>;
-  auto dirichletValues = Dune::Fufem::makeAdolCFunction(SignatureTag(), dirichletValuesC0);
+  auto dirichletFunctionValues = [](auto x) { return Range(); };
+#ifdef HAVE_ADOLC
+  auto dirichletValues = Dune::Fufem::makeAdolCFunction(SignatureTag(), dirichletFunctionValues);
+#else
+  auto dirichletDerivativeValues = [](auto x) { return DerivativeRange(); };
+  auto dirichletValues = Dune::Functions::makeDifferentiableFunctionFromCallables(SignatureTag(),
+    dirichletFunctionValues, dirichletDerivativeValues);
+#endif
 
   // Disable parallel assembly for UGGrid before 2.10
 #if DUNE_VERSION_GT(DUNE_FUNCTIONS, 2, 9)
diff --git a/examples/poisson-hermite.cc b/examples/poisson-hermite.cc
index af9ef637..c86bda27 100644
--- a/examples/poisson-hermite.cc
+++ b/examples/poisson-hermite.cc
@@ -33,7 +33,9 @@
 #endif
 
 #include <dune/fufem/logger.hh>
+#ifdef HAVE_ADOLC
 #include <dune/fufem/functions/adolcfunction.hh>
+#endif
 #include <dune/fufem/parallel/elementcoloring.hh>
 #include <dune/fufem/boundarypatch.hh>
 #include <dune/fufem/functiontools/boundarydofs.hh>
@@ -68,7 +70,8 @@ int main (int argc, char *argv[]) try
   //   Generate the grid
   ///////////////////////////////////
 
-  auto grid = Dune::StructuredGridFactory<Dune::UGGrid<2>>::createSimplexGrid({0,0}, {1, 1}, {2, 2});
+  constexpr auto dim = 2;
+  auto grid = Dune::StructuredGridFactory<Dune::UGGrid<dim>>::createSimplexGrid({0,0}, {1, 1}, {2, 2});
 
   log("Grid created");
 
@@ -112,16 +115,31 @@ int main (int argc, char *argv[]) try
   auto dirichletPatch = BoundaryPatch(basis.gridView());
   dirichletPatch.insertFacesByProperty([&](auto&& intersection) { return dirichletIndicatorFunction(intersection.geometry().center()); });
 
+  using Domain = Dune::FieldVector<double, dim>;
+  using Range = double;
+  using DerivativeRange = Dune::FieldVector<double, dim>;
+  using SignatureTag = Dune::Functions::SignatureTag<Range(Domain)>;
+
   auto rightHandSide = [] (const auto& x) { return 10;};
   auto pi = std::acos(-1.0);
-  auto dirichletValuesC0 = [pi](const auto& x){
+  auto dirichletFunctionValues = [pi](const auto& x){
     using std::sin;
     return sin(2*pi*x[0]);
   };
 
   // Make Dirichlet data differentiable, since this is required by local interpolation
-  using SignatureTag = Dune::Functions::SignatureTag<double(Dune::FieldVector<double,2>)>;
-  auto dirichletValues = Dune::Fufem::makeAdolCFunction(SignatureTag(), dirichletValuesC0);
+  // Notice that, depite the fact that we have essential constraints for function values
+  // only, the derivative values do matter, because we also have to constrain tangential DOFs.
+#ifdef HAVE_ADOLC
+  auto dirichletValues = Dune::Fufem::makeAdolCFunction(SignatureTag(), dirichletFunctionValues);
+#else
+  auto dirichletDerivativeValues = [pi](auto x) {
+    using std::cos;
+    return DerivativeRange({2.*pi*cos(2.*pi*x[0]), 0.0});
+  };
+  auto dirichletValues = Dune::Functions::makeDifferentiableFunctionFromCallables(SignatureTag(),
+    dirichletFunctionValues, dirichletDerivativeValues);
+#endif
 
   // Disable parallel assembly for UGGrid before 2.10
 #if DUNE_VERSION_GT(DUNE_FUNCTIONS, 2, 9)
-- 
GitLab