From 549877a827143b3dd6260b8dced526a7db6f94a7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ren=C3=A9=20He=C3=9F?= <rene.hess@iwr.uni-heidelberg.de>
Date: Tue, 20 Sep 2016 10:30:40 +0200
Subject: [PATCH] Create numerical nonlinear jacobian apply methods

---
 python/dune/perftool/pdelab/localoperator.py | 36 +++++++++++++-------
 1 file changed, 23 insertions(+), 13 deletions(-)

diff --git a/python/dune/perftool/pdelab/localoperator.py b/python/dune/perftool/pdelab/localoperator.py
index 2795d330..592e606b 100644
--- a/python/dune/perftool/pdelab/localoperator.py
+++ b/python/dune/perftool/pdelab/localoperator.py
@@ -433,33 +433,43 @@ def generate_localoperator_kernels(formdata, data):
 
                 # Maybe add numerical differentiation
                 if get_option("numerical_jacobian"):
+                    # Include headers for numerical methods
                     include_file("dune/pdelab/localoperator/defaultimp.hh", filetag="operatorfile")
 
+                    # Numerical jacobian base class
                     _, loptype = class_type_from_cache("operator")
                     which = ufl_measure_to_pdelab_measure(measure)
-
-                    # Numerical jacobian methods
                     base_class("Dune::PDELab::NumericalJacobian{}<{}>".format(which, loptype), classtag="operator")
 
-                    # Add the initializer list for that base class
+                    # Numerical jacobian initializer list
                     ini = name_initree_member()
                     ini_constructor = name_initree_constructor_param()
-
-                    # Numerical jacobian methods
                     initializer_list("Dune::PDELab::NumericalJacobian{}<{}>".format(which, loptype),
                                      ["{}.get<double>(\"numerical_epsilon.{}\", 1e-9)".format(ini_constructor, ini, which.lower())],
                                      classtag="operator",
                                      )
 
+                    # In the case of matrix free operator evaluation we need jacobian apply methods
                     if get_option("matrix_free"):
-                        # Numeical jacobian apply base class
-                        base_class("Dune::PDELab::NumericalJacobianApply{}<{}>".format(which, loptype), classtag="operator")
-
-                        # Numerical jacobian apply initializer list
-                        initializer_list("Dune::PDELab::NumericalJacobianApply{}<{}>".format(which, loptype),
-                                         ["{}.get<double>(\"numerical_epsilon.{}\", 1e-9)".format(ini_constructor, ini, which.lower())],
-                                         classtag="operator",
-                                         )
+                        from dune.perftool.pdelab.driver import is_linear
+                        if is_linear(form):
+                            # Numeical jacobian apply base class
+                            base_class("Dune::PDELab::NumericalJacobianApply{}<{}>".format(which, loptype), classtag="operator")
+
+                            # Numerical jacobian apply initializer list
+                            initializer_list("Dune::PDELab::NumericalJacobianApply{}<{}>".format(which, loptype),
+                                             ["{}.get<double>(\"numerical_epsilon.{}\", 1e-9)".format(ini_constructor, ini, which.lower())],
+                                              classtag="operator",
+                                             )
+                        else:
+                            # Numerical nonlinear jacobian apply base class
+                            base_class("Dune::PDELab::NumericalNonlinearJacobianApply{}<{}>".format(which, loptype), classtag="operator")
+
+                            # Numerical nonlinear jacobian apply initializer list
+                            initializer_list("Dune::PDELab::NumericalNonlinearJacobianApply{}<{}>".format(which, loptype),
+                                             ["{}.get<double>(\"numerical_epsilon.{}\", 1e-9)".format(ini_constructor, ini, which.lower())],
+                                              classtag="operator",
+                                             )
 
                 operator_kernels[(measure, 'residual')] = kernel
 
-- 
GitLab