signature for overloaded MathFunction

Issue #83 invalid
Chaffra Affouda created an issue

Hi,

I am trying to implement an overloaded MathFunction like below. The function works with my modified version of ufl. The problem is that when I use it in a NonlinearProblem the JIT compiles it every time which makes me think something is wrong with the signature. What would be the proper way of generating a signature for this?

class AbsApproximation(MathFunction):

#    form_compiler_parameters = {
#                                'include_dirs': include_dirs,
#                                'system_headers': system_headers,
#                                'libraries': libraries,
#                                }

    def __new__(cls, x0, argument, n=0):
        if isinstance(argument, (ScalarValue, Zero)):
            return FloatValue(abs_approximation_evaluate(x0,float(argument), n))
        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)
        return abs_approximation_evaluate(self._x0, a, self._n)


    def __init__(self, x0, n, argument):
        x0 = float(x0)
        self._x0 = x0
        str_x0 = str(x0)

        self._n = n

        if n == 0:
            MathFunction.__init__(self, 'semifem::abs_approximation_'+str_x0,
                                  argument)
        elif n == 1:
            MathFunction.__init__(self, 'semifem::abs_derivative_approximation_'+str_x0,
                                  argument)
        elif n == 2:
            MathFunction.__init__(self, 'semifem::abs_secend_derivative_approximation_'+str_x0,
                                  argument)
        else:
            raise NotImplementedError("derivative %d not implemented for AbsApproximation."% n)


        self._argument = argument


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

    def _ufl_signature_data_(self):
        return self._name #self._ufl_typecode_

    def _ufl_compute_hash_(self):
        "Compute a hash code for this expression. Used by sets and dicts."
        val = hash((self._ufl_typecode_,self._name) + tuple(hash(o) for o in self.ufl_operands))
        print "abs_hash = ", val
        return val

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

    def format(self,v):
        x0 = str(self._x0)
        #print "_order = ", self._order

        print self.cname()

        if self._n == 0:
            return "semifem::abs_approximation("+v+","+x0+")"
        elif self._n == 1:
            return "semifem::abs_derivative_approximation("+v+","+x0+")"
        elif self._n == 2:
            return "semifem::abs_second_derivative_approximation("+v+","+x0+")"
        else:
            raise NotImplementedError

Comments (2)

  1. Log in to comment