Skip to content
Snippets Groups Projects
Commit d4581f21 authored by Dominic Kempf's avatar Dominic Kempf
Browse files

[!278] Enable extendability of the visitor for custom UFL nodes

Merge branch 'feature/allow-custom-ufl-types' into 'master'

ref:dominic/dune-perftool We do want code bloat in dune-perftool for the
specific needs of a given application. We therefore allow custom UFL nodes to
procide their own visitor implementation. This was done previously for the
very specific case of a MathFunction node, but it can be done with any node.

See merge request [dominic/dune-perftool!278]

  [dominic/dune-perftool!278]: gitlab.dune-project.org/dominic/dune-perftool/merge_requests/278
parents 7dde9013 42b3964e
No related branches found
No related tags found
No related merge requests found
...@@ -77,7 +77,16 @@ class UFL2LoopyVisitor(ModifiedTerminalTracker): ...@@ -77,7 +77,16 @@ class UFL2LoopyVisitor(ModifiedTerminalTracker):
return self.call(o) return self.call(o)
call = MultiFunction.__call__ def call(self, o):
# Allow downstream projects to provide custom nodes that provide their own visiting
# implementation. To do so, inherit from the UFL node which is closest to what you need
# and provide it with the following:
# * a _ufl_expr_reconstruct_ method to avoid preprocessing discarding the node
# * a visit method taking the visitor as the only argument
if hasattr(o, "visit"):
return o.visit(self)
else:
return MultiFunction.__call__(self, o)
# #
# Form argument/coefficients handlers: # Form argument/coefficients handlers:
...@@ -343,22 +352,6 @@ class UFL2LoopyVisitor(ModifiedTerminalTracker): ...@@ -343,22 +352,6 @@ class UFL2LoopyVisitor(ModifiedTerminalTracker):
def min_value(self, o): def min_value(self, o):
return self._minmax_impl(min, "min", tuple(self.call(op) for op in o.ufl_operands)) return self._minmax_impl(min, "min", tuple(self.call(op) for op in o.ufl_operands))
def math_function(self, o):
# MathFunction is a base class for unary functions. We use this to provide
# custom functions. Such a custom functions inherits from it and defines the
# following methods:
# * visit: This function is called from here to delegate the visiting process
# to the user code. The only argument is this visitor instance.
# * derivative: It is called from UFL AD code to determine the derivative.
# Upstream documentation indicates that FEniCS allows the same
# (ab)use of the MathFunction node.
# Note that if the __init__ method of your function differs from MathFunction,
# you also need to implement the method _ufl_expr_reconstruct_
if hasattr(o, "visit"):
return o.visit(self)
else:
raise NotImplementedError("Function {} is not known to dune-perftool.".format(o._name))
# #
# Handler for conditionals, use pymbolic base implementation # Handler for conditionals, use pymbolic base implementation
# #
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment