Create generic nonlinear operator in UFL

Issue #84 new
Chaffra Affouda created an issue

I asked for this on the fenics qa but I am asking again here to see if this can be implemented.

I'd like to create a generic UFL operator by inheriting from ufl.MathFunction. It's an approach I've used before and it works.

The problem here is in the format function that I use to generate c++ code for that operator. I'd like to be able to call the "map_function" which is a dolfin::GenericFunction into the code generated by ffc.

How to generate the right call_to_map_function string below? Is it even possible?

def nonlinear_function_evaluate(map_function,n, x):
        return map_function(x,n)
    class NonlinearFunction(MathFunction):

        def __new__(cls, map_function, n, argument):
            if isinstance(argument, (ScalarValue, Zero)):
                return FloatValue(nonlinear_function_evaluate(map_function,
                                                          n,
                                                          float(argument)
                                                          )
                              )
            return MathFunction.__new__(cls)


        def evaluate(self, x, mapping, component, index_values, derivatives=()):
            #print x, mapping, component, index_values    
            a = self._argument.evaluate(x, mapping, component, index_values)
            map_function = self._map_function
            n = self._n
            return nonlinear_function_evaluate(map_function, n, a)


        def __init__(self, map_function, n, argument):

            self._map_function = map_function;
            self._n = n

            MathFunction.__init__(self, map_function.name()+'eval_derivatives_'+str(n),
                                  argument)

            self._argument = argument


        def _ufl_expr_reconstruct_(self, argument):
            "Return a new object of the same type with new operands."
            return self.__class__(self._map_function, self._n , argument)

        def derivative(self, ):
            """Used in ufl.algorithms.forward_ad"""
            return self.__class__(self._map_function, self._n+1, self._argument)

        def format(self,v):
            map_function = self._map_function.name()

            return "call_to_map_function("+v+")"

Comments (7)

  1. Log in to comment