# How to use same vector-valued mathematical expressions with both ufl and numpy?

**URL:** <https://fenicsproject.discourse.group/t/how-to-use-same-vector-valued-mathematical-expressions-with-both-ufl-and-numpy/14058>\
**Category:** General\
**Tags:** dolfinx\
**Created:** [March 28, 2024, 9:03pm UTC](https://fenicsproject.discourse.group/t/how-to-use-same-vector-valued-mathematical-expressions-with-both-ufl-and-numpy/14058 "2024-03-28T21:03:19Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![August](https://avatars.discourse-cdn.com/v4/letter/a/d26b3c/32.png) [@August](https://fenicsproject.discourse.group/u/August)\
**Post date:** [March 28, 2024, 9:03pm UTC](https://fenicsproject.discourse.group/t/how-to-use-same-vector-valued-mathematical-expressions-with-both-ufl-and-numpy/14058/1 "2024-03-28T21:03:20Z")

</div>

Hi all,

I’m using this kind of technique to avoid having to write an expression both in `ufl` (eg for generating the exact right hand side `f`) and `numpy` (eg for pointwise evaluations):

```auto
import dolfinx
import ufl
from mpi4py import MPI
import numpy as np

mesh = dolfinx.mesh.create_unit_square(MPI.COMM_WORLD, 5, 5)

def u_exact(m):
    return lambda x: m.sin(m.pi * x[0]) * m.sin(m.pi * x[1])

x = ufl.SpatialCoordinate(mesh)
f = ufl.div(ufl.grad(u_exact(ufl)(x)))
pts = np.array([[0.5, 0.1], [0.1, 0.9]])
u0 = u_exact(np)(pts)

```

What I cannot get to work is how to do this if `u_exact` is a vector-valued function. I’m trying to be clever with mixing `np.stack` and `ufl.as_vector` but without success. Is there an example somewhere I can look at?

Thanks!

---

<div class="post-metadata">

**Author:** ![francesco-ballarin](https://avatars.discourse-cdn.com/v4/letter/f/f05b48/32.png) [@francesco-ballarin](https://fenicsproject.discourse.group/u/francesco-ballarin)\
**Post date:** [March 29, 2024, 6:33am UTC](https://fenicsproject.discourse.group/t/how-to-use-same-vector-valued-mathematical-expressions-with-both-ufl-and-numpy/14058/2 "2024-03-29T06:33:25Z")

</div>

For legacy dolfin there used to be [GitHub - MiroK/ulfy: Traslate UFL to SymPy to Expression](https://github.com/MiroK/ulfy) (ufl ↔ sympy, but then from sympy one could use `sympy.lambdify` to numpy). I am not aware of similar projects for dolfinx.

---

<div class="post-metadata">

**Author:** ![bleyerj](https://yyz2.discourse-cdn.com/free1/user_avatar/fenicsproject.discourse.group/bleyerj/32/6020_2.png) [@bleyerj](https://fenicsproject.discourse.group/u/bleyerj)\
**Post date:** [March 29, 2024, 10:15am UTC](https://fenicsproject.discourse.group/t/how-to-use-same-vector-valued-mathematical-expressions-with-both-ufl-and-numpy/14058/3 "2024-03-29T10:15:34Z")

</div>

The `fem.Expression` mechanism would be a solution if your points are defined via the same coordinates on the reference element. I am not sure if something is similar with points defined by their global coordinates

---

<div class="post-metadata">

**Author:** ![bleyerj](https://yyz2.discourse-cdn.com/free1/user_avatar/fenicsproject.discourse.group/bleyerj/32/6020_2.png) [@bleyerj](https://fenicsproject.discourse.group/u/bleyerj)\
**Post date:** [March 29, 2024, 10:19am UTC](https://fenicsproject.discourse.group/t/how-to-use-same-vector-valued-mathematical-expressions-with-both-ufl-and-numpy/14058/4 "2024-03-29T10:19:41Z")

</div>

Maybe this ?

> [@Evaluating Finite Element Function](https://fenicsproject.discourse.group/t/evaluating-finite-element-function/13462/10):
>
> The points have the wrong shape (single point, the function expects multiple points): from mpi4py import MPI import numpy as np from dolfinx import mesh from dolfinx import fem from dolfinx.fem import FunctionSpace from dolfinx import default\_scalar\_type import ufl from dolfinx.fem.petsc import LinearProblem from dolfinx import geometry domain = mesh.create\_unit\_square(MPI.COMM\_WORLD, 8, 8, mesh.CellType.quadrilateral) V = FunctionSpace(domain, ("Lagrange", 1)) uD = fem.Function(V)…

---

<div class="post-metadata">

**Author:** ![dokken](https://yyz2.discourse-cdn.com/free1/user_avatar/fenicsproject.discourse.group/dokken/32/1560_2.png) [@dokken](https://fenicsproject.discourse.group/u/dokken)\
**Post date:** [March 29, 2024, 9:38pm UTC](https://fenicsproject.discourse.group/t/how-to-use-same-vector-valued-mathematical-expressions-with-both-ufl-and-numpy/14058/5 "2024-03-29T21:38:06Z")

</div>

For point evaluation, you need to specify what cell the point is in, as specified in: [Implementation — FEniCSx tutorial](https://jsdokken.com/dolfinx-tutorial/chapter1/membrane_code.html#making-curve-plots-throughout-the-domain)

One can of course go through `dolfinx.fem.Expression` for more advanced code, such as shown in: [Evaluation of UFL expression at mesh points - #2 by dokken](https://fenicsproject.discourse.group/t/evaluation-of-ufl-expression-at-mesh-points/7368/2) and subsequent posts.

Other similar resources:

> [@Point Sources (Redux)](https://fenicsproject.discourse.group/t/point-sources-redux/13496/6):
>
> Following my post above, with a minor adaptations, a point source can be implemented as follows: # Create a point source for Poisson problem # Author: Jørgen S. Dokken # SPDX-License-Identifier: MIT from mpi4py import MPI from petsc4py import PETSc import dolfinx import dolfinx.fem.petsc import numpy as np import ufl def compute\_cell\_contributions(V, points): # Determine what process owns a point and what cells it lies within mesh = V.mesh \_, \_, owning\_points, cells = dolfinx.cp…

> [@Evaluate\_basis\_all in dolfinx](https://fenicsproject.discourse.group/t/evaluate-basis-all-in-dolfinx/3968/11):
>
> The DOLFINx way to do this would be to: Figure out which cell the point x is in (using dolfinx.compute\_colliding\_cells, as done in: [Implementation — FEniCSx tutorial](https://jorgensd.github.io/dolfinx-tutorial/chapter1/membrane_code.html#making-curve-plots-throughout-the-domain)) Pull these coordinates back to the reference element, using mesh.geometry.cmap.pull\_back ([dolfinx/fem.cpp at 48ece0087588f5f274a36aec223abb129fa59e8e · FEniCS/dolfinx · GitHub](https://github.com/FEniCS/dolfinx/blob/48ece0087588f5f274a36aec223abb129fa59e8e/python/dolfinx/wrappers/fem.cpp#L1094)) Use basix.FiniteElement(element\_of choice).tabulate(1, X\_ref) to tabulate at the reference points. An example of the last step can be found in: [asimov-cu…](https://github.com/Wells-Group/asimov-custom-assemblers/blob/main/python/dolfinx_cuas/custom_assembler.py#L138-L140)
