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

Merge branch 'feature/custom-functions' into 'master'

Implement possibility of functions that provide their own visitor

See merge request dominic/dune-perftool!234
parents 140ab36a aa6ffb8c
No related branches found
No related tags found
No related merge requests found
...@@ -343,6 +343,22 @@ class UFL2LoopyVisitor(ModifiedTerminalTracker): ...@@ -343,6 +343,22 @@ 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
# #
......
...@@ -67,6 +67,12 @@ dune_add_formcompiler_system_test(UFLFILE poisson_dg_tensor.ufl ...@@ -67,6 +67,12 @@ dune_add_formcompiler_system_test(UFLFILE poisson_dg_tensor.ufl
INIFILE poisson_dg_tensor.mini INIFILE poisson_dg_tensor.mini
) )
# 12. Poisson Test Case with a custom function
dune_add_formcompiler_system_test(UFLFILE poisson_customfunction.ufl
BASENAME poisson_customfunction
INIFILE poisson_customfunction.mini
)
# the reference vtk file # the reference vtk file
add_executable(poisson_dg_ref reference_main.cc) add_executable(poisson_dg_ref reference_main.cc)
set_target_properties(poisson_dg_ref PROPERTIES EXCLUDE_FROM_ALL 1) set_target_properties(poisson_dg_ref PROPERTIES EXCLUDE_FROM_ALL 1)
__name = poisson_customfunction_{__exec_suffix}
__exec_suffix = numdiff, symdiff | expand num
lowerleft = 0.0 0.0
upperright = 1.0 1.0
elements = 32 32
elementType = simplical
[wrapper.vtkcompare]
name = {__name}
reference = poisson_ref
extension = vtu
[formcompiler]
compare_l2errorsquared = 1e-7
[formcompiler.r]
numerical_jacobian = 1, 0 | expand num
import ufl
cell = triangle
x = SpatialCoordinate(cell)
class SquareFct(ufl.classes.MathFunction):
def __init__(self, arg):
ufl.classes.MathFunction.__init__(self, 'square', arg)
def _ufl_expr_reconstruct_(self, *operands):
return SquareFct(*operands)
def derivative(self):
return 2 * self.ufl_operands[0]
def visit(self, visitor):
op = visitor.call(self.ufl_operands[0])
return op * op
c = SquareFct(0.5-x[0]) + SquareFct(0.5-x[1])
g = exp(-1.*c)
f = 4*(1.-c)*g
V = FiniteElement("CG", cell, 1)
u = TrialFunction(V)
v = TestFunction(V)
r = (inner(grad(u), grad(v)) - f*v)*dx
exact_solution = g
interpolate_expression = g
is_dirichlet = 1
\ No newline at end of file
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