Small question about writing dot product in UFL

Hi, I’m trying to write a flux term

\mathbf{S} = \boldsymbol{a}\nabla u + u\boldsymbol{c}

where

\begin{align} \boldsymbol a = \begin{bmatrix} \frac{A_3^2z^2}{2} & 0 & \frac{A_3^2xz}{2} \\ 0 &\frac12\bigg(A_1^2+A_2^2+A_3^2\frac{z^2}{x^2}\bigg) & 0 \\ \frac{A_3^2xz}{2} & 0 & \frac{A_3^2x^2}{2} \end{bmatrix}, \quad \boldsymbol c = \begin{bmatrix} -A_4x \\ -A_5 \\ A_4z \end{bmatrix}. \end{align}

with these "A" terms constant. In Python I have

a = np.array([[0.5*A_3**2*x[2]**2,0,0.5*A_3**2*x[0]*x[2]],
[0,0.5*(A_1**2+A_2**2+A_3**2*(x[2]/x[0])**2),0],
[0.5*A_3**2*x[0]*x[2],0,0.5*A_3**2*x[0]**2]])

c = np.array([-0.5*A_3**2*x[0]+(A_3**2/2-A_4)*x[0],
-A_5,
-0.5*A_3**2*x[2]+(A_3**2/2+A_4)*x[2]])

a_grad_u = dot(as_matrix(a),grad(u))
S = a_grad_u + dot(u,c)

but the dot(c,u) term returns an error

raise UFLValueError("Invalid type conversion: %s can not be converted"
ufl.log.UFLValueError: Invalid type conversion: [Sum(Product(FloatValue(-0.08000000000000002), Indexed(SpatialCoordinate(Mesh(VectorElement(FiniteElement('Lagrange', tetrahedron, 1), dim=3), 0)), MultiIndex((FixedIndex(0),)))), Product(FloatValue(-0.52), Indexed(SpatialCoordinate(Mesh(VectorElement(FiniteElement('Lagrange', tetrahedron, 1), dim=3), 0)), MultiIndex((FixedIndex(0),)))))
 -0.7
 Sum(Product(FloatValue(-0.08000000000000002), Indexed(SpatialCoordinate(Mesh(VectorElement(FiniteElement('Lagrange', tetrahedron, 1), dim=3), 0)), MultiIndex((FixedIndex(2),)))), Product(FloatValue(0.6799999999999999), Indexed(SpatialCoordinate(Mesh(VectorElement(FiniteElement('Lagrange', tetrahedron, 1), dim=3), 0)), MultiIndex((FixedIndex(2),)))))] can not be converted to any UFL type.

So how do I write this part correctly? Thanks in advance.

What is u ? If it’s a vector function, then grad(u) would be a second order tensor and so would dot(as_matrix(a), grad(u)). On the other hand dot(u, c) would be a scalar. Also you need not use numpy arrays, you can directly pass lists to as_matrix and as_vector, namely

a = as_matrix([[0.5*A_3**2*x[2]**2,0,0.5*A_3**2*x[0]*x[2]],
[0,0.5*(A_1**2+A_2**2+A_3**2*(x[2]/x[0])**2),0],
[0.5*A_3**2*x[0]*x[2],0,0.5*A_3**2*x[0]**2]])

c = as_vector([-0.5*A_3**2*x[0]+(A_3**2/2-A_4)*x[0],
-A_5,
-0.5*A_3**2*x[2]+(A_3**2/2+A_4)*x[2]])

If u is a scalar function (from your previous post) then you don’t need a dot product between c and u, it’s simply c*u

1 Like