Hi kamensky, thanks for your reply. I’ve started by defining functions for the spherical curl, divergence and gradient, as you suggested, but I don’t know how to return a UFL type instead of a list or numpy array. As a consequence, I can’t compute dot products between a vector function and its curl, for example. Here’s a mwe:
import ufl
from dolfinx import mesh, fem
from mpi4py import MPI
dim = 3 # dimension of the OP
domain = mesh.create_unit_cube(MPI.COMM_WORLD,10,10,10)
x = ufl.SpatialCoordinate(domain)
element = ufl.VectorElement("CG", domain.ufl_cell(), 1, dim)
V = fem.FunctionSpace(domain, element) # space of vector functions with dim components
m = ufl.TrialFunction(V) # dim-dimensional vector OP
def curl_sph(A, x):
xr, xq, xf = x; jr, jq, jf = 0, 1, 2
Ar, Aq, Af = A
curl_r = (ufl.Dx(Af*ufl.sin(xq),jq)-ufl.Dx(Aq,jf))/(xr*ufl.sin(xq))
curl_q = (ufl.Dx(Ar,jf)/ufl.sin(xq)-ufl.Dx(xr*Af,jr))/xr
curl_f = (ufl.Dx(xr*Aq,jr)-ufl.Dx(Ar,jq))/xr
return [curl_r, curl_q, curl_f]
#ufl.dot([1,0,0],[0,1,0])
ufl.dot(m,curl_sph(m,x))
---------------------------------------------------------------------------
UFLValueError Traceback (most recent call last)
Input In [1], in <cell line: 23>()
20 return [curl_r, curl_q, curl_f]
22 #ufl.dot([1,0,0],[0,1,0])
---> 23 ufl.dot(m,curl_sph(m,x))
File /usr/local/lib/python3.10/dist-packages/ufl/operators.py:173, in dot(a, b)
171 "UFL operator: Take the dot product of *a* and *b*. This won't take the complex conjugate of the second argument."
172 a = as_ufl(a)
--> 173 b = as_ufl(b)
174 if a.ufl_shape == () and b.ufl_shape == ():
175 return a * b
File /usr/local/lib/python3.10/dist-packages/ufl/constantvalue.py:437, in as_ufl(expression)
435 return IntValue(expression)
436 else:
--> 437 raise UFLValueError("Invalid type conversion: %s can not be converted"
438 " to any UFL type." % str(expression))
UFLValueError: Invalid type conversion: [Division(Sum(Indexed(Grad(Product(Indexed(Argument(FunctionSpace(Mesh(VectorElement(FiniteElement('Lagrange', tetrahedron, 1), dim=3), 0), VectorElement(FiniteElement('Lagrange', tetrahedron, 1), dim=3)), 1, None), MultiIndex((FixedIndex(2),))), Sin(Indexed(SpatialCoordinate(Mesh(VectorElement(FiniteElement('Lagrange', tetrahedron, 1), dim=3), 0)), MultiIndex((FixedIndex(1),)))))), MultiIndex((FixedIndex(1),))), Product(IntValue(-1), Indexed(Grad(Indexed(Argument(FunctionSpace(Mesh(VectorElement(FiniteElement('Lagrange', tetrahedron, 1), dim=3), 0), VectorElement(FiniteElement('Lagrange', tetrahedron, 1), dim=3)), 1, None), MultiIndex((FixedIndex(1),)))), MultiIndex((FixedIndex(2),))))), Product(Indexed(SpatialCoordinate(Mesh(VectorElement(FiniteElement('Lagrange', tetrahedron, 1), dim=3), 0)), MultiIndex((FixedIndex(0),))), Sin(Indexed(SpatialCoordinate(Mesh(VectorElement(FiniteElement('Lagrange', tetrahedron, 1), dim=3), 0)), MultiIndex((FixedIndex(1),)))))), Division(Sum(Product(IntValue(-1), Indexed(Grad(Product(Indexed(SpatialCoordinate(Mesh(VectorElement(FiniteElement('Lagrange', tetrahedron, 1), dim=3), 0)), MultiIndex((FixedIndex(0),))), Indexed(Argument(FunctionSpace(Mesh(VectorElement(FiniteElement('Lagrange', tetrahedron, 1), dim=3), 0), VectorElement(FiniteElement('Lagrange', tetrahedron, 1), dim=3)), 1, None), MultiIndex((FixedIndex(2),))))), MultiIndex((FixedIndex(0),)))), Division(Indexed(Grad(Indexed(Argument(FunctionSpace(Mesh(VectorElement(FiniteElement('Lagrange', tetrahedron, 1), dim=3), 0), VectorElement(FiniteElement('Lagrange', tetrahedron, 1), dim=3)), 1, None), MultiIndex((FixedIndex(0),)))), MultiIndex((FixedIndex(2),))), Sin(Indexed(SpatialCoordinate(Mesh(VectorElement(FiniteElement('Lagrange', tetrahedron, 1), dim=3), 0)), MultiIndex((FixedIndex(1),)))))), Indexed(SpatialCoordinate(Mesh(VectorElement(FiniteElement('Lagrange', tetrahedron, 1), dim=3), 0)), MultiIndex((FixedIndex(0),)))), Division(Sum(Indexed(Grad(Product(Indexed(SpatialCoordinate(Mesh(VectorElement(FiniteElement('Lagrange', tetrahedron, 1), dim=3), 0)), MultiIndex((FixedIndex(0),))), Indexed(Argument(FunctionSpace(Mesh(VectorElement(FiniteElement('Lagrange', tetrahedron, 1), dim=3), 0), VectorElement(FiniteElement('Lagrange', tetrahedron, 1), dim=3)), 1, None), MultiIndex((FixedIndex(1),))))), MultiIndex((FixedIndex(0),))), Product(IntValue(-1), Indexed(Grad(Indexed(Argument(FunctionSpace(Mesh(VectorElement(FiniteElement('Lagrange', tetrahedron, 1), dim=3), 0), VectorElement(FiniteElement('Lagrange', tetrahedron, 1), dim=3)), 1, None), MultiIndex((FixedIndex(0),)))), MultiIndex((FixedIndex(1),))))), Indexed(SpatialCoordinate(Mesh(VectorElement(FiniteElement('Lagrange', tetrahedron, 1), dim=3), 0)), MultiIndex((FixedIndex(0),))))] can not be converted to any UFL type.
In fact, this extremely minimal example raises the same error:
import ufl
ufl.dot([1,0,0],[0,1,0])
---------------------------------------------------------------------------
UFLValueError Traceback (most recent call last)
Input In [1], in <cell line: 3>()
1 import ufl
----> 3 ufl.dot([1,0,0],[0,1,0])
File /usr/local/lib/python3.10/dist-packages/ufl/operators.py:172, in dot(a, b)
170 def dot(a, b):
171 "UFL operator: Take the dot product of *a* and *b*. This won't take the complex conjugate of the second argument."
--> 172 a = as_ufl(a)
173 b = as_ufl(b)
174 if a.ufl_shape == () and b.ufl_shape == ():
File /usr/local/lib/python3.10/dist-packages/ufl/constantvalue.py:437, in as_ufl(expression)
435 return IntValue(expression)
436 else:
--> 437 raise UFLValueError("Invalid type conversion: %s can not be converted"
438 " to any UFL type." % str(expression))
UFLValueError: Invalid type conversion: [1, 0, 0] can not be converted to any UFL type.
How can I return something compatible with ufl.dot?