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

Implement possibility of functions that provide their own visitor

This will be needed to replace nonlinearities in Richards code
with a cubic spline evaluation without bloating dune-perftool with
the implementation details of such procedure.

Also provides a test, that defines a custom square function.
parent 140ab36a
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