User-defined expression for tensor coefficient

Hi all,

I would like to solve a diffusion equation where the coefficient in the bilinear form is a matrix. Since I have a complicated expression for that, I define a class for this coefficient which inherits from UserExpression. My question is now how to access and assign the values of the matrix-valued coefficient in this class in the eval function, because values[i,j] or values[i][j] does not work and I could not find examples for it.

Here below is a simple example, where I use the identity tensor and the eval function is accessing wrongly the values

class Tensor_Coefficient(UserExpression):
def init(self,**kwargs):
super().init(**kwargs)
def eval(self,values,x):
values[0][0] = 1.
values[0][1] = 0.
values[1][0] = 0.
values[1][1] = 1.
def value_shape(self):
return(2,2)

The array that is input into eval is a 1D array, where the first 2 entries are the first row in the tensor, the next 2 are the next row etc. I’ve made a minimal 2D example to illustrate this:


from dolfin import *
import numpy as np
mesh = UnitSquareMesh(1,1)
V = VectorFunctionSpace(mesh, "CG", 1)
unp = np.array([1,2,3,4])
u = as_tensor(unp.reshape((2,2)).tolist())

class Tensor_Coeff(UserExpression):
    def init(self, **kwargs):
        super().init(**kwargs)
    def eval(self, values, x):
        values[0] = 0
        values[1] = 1
        values[2] = 2
        values[3] = 3
        #print("LOCAL tensor\n", values.reshape(self.value_shape()))
    def value_shape(self):
        return (2,2)

expr = Tensor_Coeff()
for i in range(2):
    for j in range(2):
        print("i", i,"j", j, "assembled",
              assemble(u[i,j]*expr[i,j]*dx(domain=mesh)),
              "exact",(2*i+j)*unp[2*i+j])

5 Likes