This is a read only copy of the old FEniCS QA forum. Please visit the new QA forum to ask questions

User-defined expression with value_shape determined at run time

+2 votes

I am trying to define a subclass of Expression whose value_shape is determined at run time. Here is an example:

from dolfin import *
import numpy
class MyFunction(Expression):
    tensor_shape = None
    def __init__(self, tensor_shape):
        self.tensor_shape = tensor_shape
    def eval(self, value, x):
        value[:] = numpy.zeros(self.tensor_shape, dtype = numpy.float_)
    def value_shape(self):
        return self.tensor_shape
f = MyFunction((1, 1, ))

This fails with "TypeError: object of type 'NoneType' has no len()" because in FEniCS Expression subclass implementation, value_shape() is called before init is called. I am wondering if it is possible to get around this. Thanks.

asked May 3, 2014 by lzlarryli FEniCS Novice (820 points)

I just found that value_shape() is called by FEniCS only for automatically assigning an element. Assigning one oneself seems to get around it:

from dolfin import *
import numpy
class MyFunction(Expression):
    tensor_shape = None
    def __init__(self, tensor_shape, mesh):
        self.tensor_shape = tensor_shape
        self._ufl_element = TensorFunctionSpace(mesh, "DG", 0, shape = tensor_shape).ufl_element()
    def eval(self, value, x):
        value[:] = numpy.zeros(self.tensor_shape, dtype = numpy.float_)
f = MyFunction((1, 1, ), UnitSquareMesh(1, 1))

Somehow, this looks evil. I am still wondering if there is a better way.

1 Answer

+2 votes
 
Best answer

You could use the element keyword in constructing the Expression at runtime, like this:

W = TensorFunctionSpace(mesh, "CG", 1)
V = VectorFunctionSpace(mesh, "CG", 1)
S = FunctionSpace(mesh, "CG", 1)

class MyExpression(Expression):
    def eval(self, values, x):
        values[:] = numpy.zeros(self.value_size())

my1 = MyExpression(element=W.ufl_element())
my2 = MyExpression(element=V.ufl_element())
my3 = MyExpression(element=S.ufl_element())
answered May 4, 2014 by mikael-mortensen FEniCS Expert (29,340 points)
selected May 5, 2014 by lzlarryli

Thank you very much. This solves my problem.

...